public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support
@ 2019-08-17  0:15 Kubacki, Michael A
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
                   ` (37 more replies)
  0 siblings, 38 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

This patch series adds support for Intel Coffee Lake and Intel Whiskey Lake
products.

The following are a comprehensive set of packages to build a functional firmware.
Currently source code is only provided for the Intel Whiskey Lake U Reference
Validation Platform (RVP). This code is intended to provide sample code that will
enable additional board ports.

 - EDK II core
   - Package(s): Various
   - Repository: https://github.com/tianocore/edk2
 - Intel FSP:
   - Package(s): CoffeeLakeFspBinPkg
   - Repository: https://github.com/IntelFsp/FSP
 - Silicon binaries:
   - Package(s): Silicon/Intel/CoffeeLakeFspBinPkg
   - Repository: https://github.com/tianocore/edk2-non-osi
 - Silicon source:
   - Package(s): Silicon/Intel/CoffeelakeSiliconPkg
   - Repository: https://github.com/tianocore/edk2-platforms
 - Board source:
   - Package(s): Platform/Intel/WhiskeylakeOpenBoardPkg
   - Repository: https://github.com/tianocore/edk2-platforms

For build instructions and a brief background on EDK II Minimum Platform,
please reference:
https://github.com/tianocore/edk2-platforms/blob/master/Platform/Intel/Readme.md

For a more comprehensive explanation of EDK II Minimum Platform, please
reference the draft specification at:
https://edk2-docs.gitbooks.io/edk-ii-minimum-platform-specification/

Some TianoCore BZ cleanup bugs will be filed after the package is pushed.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>

Michael Kubacki (37):
  CoffeelakeSiliconPkg: Add package and Include headers
  CoffeelakeSiliconPkg/Cpu: Add Include headers
  CoffeelakeSiliconPkg/Me: Add Include headers
  CoffeelakeSiliconPkg/Pch: Add include headers
  CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers
  CoffeelakeSiliconPkg/Pch: Add Library include headers
  CoffeelakeSiliconPkg/Pch: Add PPI and Protocol include headers
  CoffeelakeSiliconPkg/Pch: Add Register include headers
  CoffeelakeSiliconPkg/Pch: Add Private include headers
  CoffeelakeSiliconPkg/Pch: Add Private/Library include headers
  CoffeelakeSiliconPkg/Pch: Add Private/Protocol include headers
  CoffeelakeSiliconPkg/SampleCode: Add Include headers
  CoffeelakeSiliconPkg/SystemAgent: Add Include headers
  CoffeelakeSiliconPkg: Add package common library instances
  CoffeelakeSiliconPkg/Cpu: Add library instances
  CoffeelakeSiliconPkg/Me: Add library instances
  CoffeelakeSiliconPkg/Pch: Add Base library instances
  CoffeelakeSiliconPkg/Pch: Add DXE library instances
  CoffeelakeSiliconPkg/Pch: Add PEI library instances
  CoffeelakeSiliconPkg/Pch: Add SMM library instances
  CoffeelakeSiliconPkg/Pch: Add Base library instances
  CoffeelakeSiliconPkg/Pch: Add DXE private library instances
  CoffeelakeSiliconPkg/Pch: Add PEI private library instances
  CoffeelakeSiliconPkg/Pch: Add SMM private library instances
  CoffeelakeSiliconPkg/SystemAgent: Add library instances
  CoffeelakeSiliconPkg/Pch: Add modules
  CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher
  CoffeelakeSiliconPkg/SystemAgent: Add modules
  CoffeelakeSiliconPkg: Add package DSC files
  Maintainers.txt: Add CoffeelakeSiliconPkg maintainers
  WhiskeylakeOpenBoardPkg: Add package and headers
  WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers
  WhiskeylakeOpenBoardPkg: Add library instances
  WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
  WhiskeylakeOpenBoardPkg: Add modules
  WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
  Add WhiskeylakeOpenBoardPkg to global build config and documentation

 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec                                                                      |  565 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec                                                                                 |  714 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc                                                      |  385 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc                                           |  154 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc                                                |  128 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc                                                   |  245 ++
 Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc                                                                  |  215 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc                                                                      |  130 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc                                                                        |   69 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc                                                                              |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc                                                                           |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc                                                                              |   21 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc                                                                           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf                                       |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf                                                      |  706 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf                                                    |   71 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf                                                    |   62 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf                              |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf                           |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf                              |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf                        |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf                                                   |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf                                               |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf                                                   |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf                        |  161 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf      |  139 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf        |   97 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf                                             |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf                                   |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf                                     |   67 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf                                           |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf                              |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf                                  |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf                              |  272 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf                                                |  176 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf                                   |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf         |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf                   |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf                        |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf                  |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf                       |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf                        |  116 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf                  |  202 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf                   |  296 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf                     |   94 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf           |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf                               |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf                                           |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf                                     |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf                           |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf                                         |   29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf                                     |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf                                               |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf                                       |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf                                           |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf                                          |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf                                                 |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf                                              |   44 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf                                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf                                                 |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf                                           |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf                                       |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf                         |   52 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf                                 |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf                                         |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf                 |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf                                   |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf                                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf                                   |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf                                |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf                               |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf                                     |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf                                     |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf                        |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf                   |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf                         |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf                                           |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf                                      |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf                                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf                                           |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf                                        |   86 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf                                             |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf                                       |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf                                                       |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf                     |   26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf                           |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf                     |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf                  |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf                         |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf                                         |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf                |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf                             |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf                       |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf               |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf            |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf                  |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf               |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf                        |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf                               |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf                                 |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf                                 |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf                                                         |   99 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf                                                      |   77 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf                                                            |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf                                             |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf                                                  |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf                                                                 |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf                                                   |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                                                  |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf                                     |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf                                     |   74 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf                                                      |  116 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf                                                   |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h                                                      |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h                                |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h                                        |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h                                      |  131 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h                                |   21 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h                                        |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h                                  |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h                                           |  261 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h                                               |   31 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h                                 |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h                            |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h                                    |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h                                          |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h                                            |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h                                                   |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h                                                  |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h                                      |   84 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h                            |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h                            |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h                                              |  180 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h                          |  234 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h                 |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h                  |   28 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h                   |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h                          |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h                             |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h                                                       |  118 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h                                                             |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h                                                                      |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h                                                      |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h                                                                | 1766 ++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h                                                              |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h                                                                  |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h                                               |   75 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h                                                |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h                                               |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h                                             |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h                                                |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h                                                    |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h                                                |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h                                                     |  123 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h                                                     |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h                                                        |   34 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h                                                      |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h                                             |  141 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h                                                    |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h                                                     |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h                                                           |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h                                                     |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h                                                                    |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h                                                             |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h                                                      |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h                                                                       |  144 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h                                                                     |  157 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h                                         | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h                                 |   91 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h                                 |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h                                    |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h                                     |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h                                       |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h                                     |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h                                     |   22 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h                                |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h                                 |   14 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h                                |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h                                 |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h                                 |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h                                                   |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h                                               |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h                                               |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h                                               |   52 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h                                                  |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h                                                |   56 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h                                           |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h                                          |  131 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h                                              |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h                                         |  105 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h                                                |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h                                           |   12 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h                                      |   18 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h                                   |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h                            |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h                               |  225 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h                              |  284 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h                        |   59 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h                               | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h                      |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h                |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h                |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h                                                       |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h                                        |  106 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h                                           |  141 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h                                                |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h                                         |  179 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h                                        |   78 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h                                          |  149 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h                                                   |   66 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h                                                                   |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h                                                               |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h                                                               |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h                                                             |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h                                                                |  100 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h                                                                     |  261 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h                                                       |   90 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h                                                      |  118 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h                                                        |   84 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h                                                            |  123 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h                                                  |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h                                         |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h                                  |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h                                                                     |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h                                                            |   89 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h                                                           |  291 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h                                                            |  157 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h                                                          |   64 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h                                                                |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h                                                    |  123 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h                                                        |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h                                                             |  110 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h                                                             |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h                                                                  |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h                                                                        |  319 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h                                                                    |   29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h                                                     |   26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h                                                      |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h                                                       |   60 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h                                                                |   55 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h                                                                     |   19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h                                                                  |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h                                                            |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h                                               |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h                                                      |  124 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h                                                       |   59 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h                                                       |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h                                                                    |  172 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h                                                                  |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h                                                                     |   19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h                                                            |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h                                            |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h                                                      |   69 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h                                                       |   56 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h                                                       |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h                                                      |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h                                           |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h                                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h                                                   |  178 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h                                                      |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h                                                  |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h                                                  |   66 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h                                                 |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h                                                    |   68 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h                                                       |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h                                                       |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h                                                  |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h                                                       |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h                                                      |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h                                                |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h                                               |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h                                                    |  429 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h                                                        |  311 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h                                                      |  230 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h                                                       |   63 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h                                                  |   96 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h                                                 |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h                                                     |   52 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h                                                   |  139 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h                                                  |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h                                                                  |  135 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h                                                                  |  326 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h                                                                |  381 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h                                                               |  340 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h                                                                |  241 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h                                                               |  200 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h                                                         |   27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h                                                             |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h                                                     |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h                                                           |  265 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h                                                             |  788 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h                                                       |  166 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h                                                            |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h                                                 |  371 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h                                                          |  141 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h                                                           |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h                                                          |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h                                                          |  407 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h                                                        |  105 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h                                                           |  226 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h                                                           |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h                                                        |  114 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h                                                         |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h                                                     |  116 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h                                                      |  240 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h                                                  |  111 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h                                                    |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h                                                     |  121 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h                                                              |  207 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h                                                             |   76 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h                                                           |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h                                                   |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h                                                              |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h                                                                   |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h                                                                      |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h                                                                  |   80 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h                                                                   |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h                                                     |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h                                                             |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h                                                       |   59 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h                                                        |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h                                                    |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h                                                                |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h                                                                     |   27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h                                                                     |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h                                                      |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h                                               |  134 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h                                              |   97 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h                                           |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h                                              | 1061 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h                                          |  288 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h                                                   |  344 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h                                                   |   56 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h                                            |  100 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h                                     |  371 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h                                            |  578 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h                                           |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h                                             |  366 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h                                                |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h                                               |  706 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h                                          |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h                                            |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h                                                        |  273 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h                                                     |  115 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h                                                             |   92 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h                                                       |  269 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h                                                           |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h                                                 |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h                                                 |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h                                                  |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h                                                   |  186 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h                                                 |  136 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h                                                      |   68 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h                                                 |  146 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h                                                 |  132 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h                                                          |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h                                                           |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h                                                     |  134 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h                                                |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h                                         |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h                                                  |  152 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h                                                           |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h                                                                |  295 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h                                                                |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h                                                            |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h                                                         |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h                                                         |  122 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h                                                       |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h                                                       |   62 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h                                                         |   90 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h                                                        |  273 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h                                                     |  694 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h                                                         |  204 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h                                                        |  170 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h                                                         |   79 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h                                                        |  103 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h                                                         |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h                                                         |  360 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h                                                      |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h                                                        |  116 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h                                                        |  484 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h                                                         |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h                                                         |  670 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h                                                      |   72 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h                                                         |  104 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h                                                      |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h                                                        |   77 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h                                                        |  668 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h                                                         |   52 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h                                                      |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h                                                    |  232 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h                                                 |  138 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h                                                       |  151 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h                                                         |  295 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h                                                  |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h                                                    |  134 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h                                                |  117 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h                                       |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h                              |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h                                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h                |  477 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h                                         |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h        |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h                  |  490 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h                        |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h                                                                 |  223 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h                                                              |  187 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h                                                         |  228 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h                                                         | 1031 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h                                                     |  342 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h                                                  |  157 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h                                                 |  105 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h                                              |  132 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h                                               |   82 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h                            |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h                                | 1513 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h                           |  118 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h                                      |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h                                   |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h                              |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h                                  |   80 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h                                           |  137 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h                                          |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h                                    |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h                                                        |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h                                               |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h                                       |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h                                       |   96 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h                                 |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h                                         |   46 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h                                            |  534 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h                                         |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h                                           |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h                                      |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h                                           |  135 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h                                           |   60 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h                                     |  354 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h                                         |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h                                   |  103 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h                                |   63 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h                                          |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h                                               |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h                                                   |   77 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h                                              |   60 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h                                              |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h                                               |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h                                                          |  259 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h                                     |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h                                        |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h                                   |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h                                           |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h                                        |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h                                          |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h                                                 |   89 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h                                                |  151 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h                                          |   63 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h                                                  |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h                                                |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h                                                    |  132 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h                                                   |   66 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h                                                  |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h                                           |  214 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h                                                  |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h                                                  |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h                                                  |   64 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h                                                            |  106 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h                                                 |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h                                                     |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h                                                      |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h                                                              |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h                                   |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h                            |   21 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h                                       |  323 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h                                |  230 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h                                  | 1567 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h                                    |  203 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h                                    | 1167 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h                                      |  237 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h                                             |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h                                                     |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h                                                  |  193 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h                                                   |   91 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h                                                      |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h                                                           |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h                                                        |  139 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h                                           |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h                                                              |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h                                               |  162 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c                                                      |   96 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c                                                      |  290 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c                                                      |  353 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c                                |  148 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c                             |  316 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c                                |  206 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c                          |  567 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c                                                     |  228 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c                                                 |  211 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c                                              | 1609 +++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c                                                     | 1765 ++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c                       |  461 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c                        |  121 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c                         |   77 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c                       |  736 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c                          |  223 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c                        |  848 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c                  |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c                        |   95 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c              |  100 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c               |  124 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c                  |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c            |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c                   |   85 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c             |   87 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c             |  163 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c                         |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c                    |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c               |   79 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c                       |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c                       |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c                                                   |  394 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c                                               |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c                                     |  310 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c                                       |  132 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c                                             |  115 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c                                |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c                                 |  105 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c                                |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c                                 |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c                                       |   65 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c                                 |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c                                     |  114 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c                                |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c                          |  108 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c                                 |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c                           |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c                                |  523 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c                          |  113 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c                                 |  242 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c                           |  221 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c                                 |  168 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c                                                   |  612 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c                                               |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c                                               |  174 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c                                               |   55 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c                                                  |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c                                                |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c                                           |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c                                             |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c           |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c   |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c                     |  156 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c                          |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c                    |   82 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c                        |  170 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c                |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c                                      |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c                                  |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c                            |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c                          |  398 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c                           |  282 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c                         |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c                          |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c                    |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c                     |   83 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c                       |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c               |  432 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c                |  636 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c                  |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c                       |  299 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c             |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c       |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c             |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c       |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c              |   27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c                                 |   90 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c                                              |  293 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c                                        |  108 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c                                             |  434 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c                                       |  160 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c                                  |  415 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c                                           |  146 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c                                       |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c                                                 |  403 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c                                         |  126 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c                                             |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c                                            |   78 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c                                                   |  214 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c                                             |  122 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c                                                    |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c                                                |  251 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c                                       |  153 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c                                                   |  993 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c                                             |  218 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c                                         |  310 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c                           |  323 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c                                            |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c                                                   |  553 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c                                                    | 2710 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c                                                  |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c                                              |  234 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c                            | 1136 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c                                              |  505 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c                                                |   82 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c                                              |  127 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c                                              |  272 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c                                        |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c                                           |  386 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c                                          |  183 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c                                                |  279 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c                                                |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c                                    |  270 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c                                      |  516 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c                                   |  181 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c                     |  372 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c                                          |  242 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c                                                      |  330 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c                                                    |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c                                                 |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c                                                 |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c                                                     |  130 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c                                             |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c                                        |  307 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c                                              |  778 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c                                             |  739 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c                                          |  169 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c                                       |  318 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c                                                     |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c                                         |  257 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c                                                            |  217 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c                       |  108 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c                                       | 1081 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c                       |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c                 |  125 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c                    |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c                              |   20 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c                                        |  333 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c                                              |  886 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c                                       |  439 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c                                |  166 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c                        | 1304 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c                     | 2275 +++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c                              |  752 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c                           |  225 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c                                         |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c                                        |  569 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c                                  |   79 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c                             |  221 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c        | 2407 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c                          |  542 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c                       |  338 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c                             |   92 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c                                | 1033 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c                          |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c                             |  360 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c                          |  194 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c                                 |  356 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c                              |   68 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c                                   |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c                                         |  196 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c                                   |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c                                                                 |  451 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c                                                             |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c                                                              |  323 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c                                                                 |  554 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c                                                              |  382 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c                                                              |   85 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c                                                                 |   89 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c                                                             |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c                                                          |  156 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c                                                     |  156 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c                                                              |  179 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c                                                             |  298 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c                                                              |  436 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c                                                             |   69 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c                                                         | 1264 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c                                                 | 2452 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c                                                     |  911 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c                                                     | 1595 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c                                                      |  254 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c                                                  |  358 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c                                            |  675 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c                                              |   83 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c                                                       |  385 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c                                                       |  229 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c                                                      |  231 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c                                                 |  764 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c                                              |  399 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c                                                                      |  310 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c                                       |  473 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c                            |  128 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c                                       |  745 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c                                       |  656 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c                                 |  284 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c                                        |  559 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c                                                     |  157 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c                                                  |  570 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c                                                   |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c                                                      |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c                                                           |  496 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c                                                           |  179 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c                                                        |  122 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c                                                              |  717 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c                                               |  356 +++
 Maintainers.txt                                                                                                              |   12 +-
 Platform/Intel/Readme.md                                                                                                     |   44 +-
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl                                                     |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL                                                       |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl                                                    |  516 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl                                                    |  309 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl                                                   |   76 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl                                               |  405 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl                                                       | 1877 ++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm                 |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm                     |  361 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm                        |   72 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl                                                            |  112 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni                                             |   15 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg                                                      |   33 +
 Platform/Intel/build.cfg                                                                                                     |    4 +-
 Readme.md                                                                                                                    |    1 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc                                                     |  250 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl                                                        |  794 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl                                                    | 1666 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl                                              |  472 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl                                                 |  369 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl                                              |  129 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl                                                |  296 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl                                              |  262 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl                                                     |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                                                      |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl                                                   |  147 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                                                  |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S                                  |  114 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm                                |  126 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm                               |  118 +
 749 files changed, 139608 insertions(+), 17 deletions(-)
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm

-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
                   ` (36 subsequent siblings)
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Create the CoffeelakeSiliconPkg to provide an initial package for
silicon initialization code for Coffee Lake (CFL) and Whiskey Lake
(WHL) generation products.

* Major areas of functionality are categorized into CPU, Management
  Engine (ME), 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: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec                              | 714 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h                  |  53 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h         |  89 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h        | 291 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h         | 157 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h       |  64 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h             |  28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h | 123 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h     |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h          | 110 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h          |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h               |  34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h                     | 319 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h                 |  29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h  |  26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h   |  71 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h    |  60 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h             |  55 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h                  |  19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h               |  65 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h         |  23 +
 21 files changed, 2410 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
new file mode 100644
index 0000000000..fa8c11e93d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
@@ -0,0 +1,714 @@
+## @file
+# Component description file for the Silicon Reference Code.
+#
+# Copyright (c) 2019 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]
+  Include
+  SampleCode/Include
+  SampleCode/MdeModulePkg/Include
+  SampleCode/IntelFrameworkPkg/Include
+  #
+  # SystemAgent
+  #
+  SystemAgent/Include
+  SystemAgent/MemoryInit/Include
+  SystemAgent/AcpiTables
+  #
+  # Cpu
+  #
+  Cpu/Include
+  #
+  # Me
+  #
+  Me/Include
+  #
+  # Pch
+  #
+  Pch/Include
+
+[Guids.common.Private]
+  #
+  # PCH
+  #
+  gPchDeviceTableHobGuid       = { 0xb3e123d0, 0x7a1e, 0x4db4, { 0xaf, 0x66, 0xbe, 0xd4, 0x1e, 0x9c, 0x66, 0x38 }}
+  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 }}
+
+[Guids]
+##
+## 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}}
+
+##
+## IntelFrameworkPkg
+##
+gEfiSmmPeiSmramMemoryReserveGuid =  {0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d}}
+
+##
+## Common
+##
+## Include/ConfigBlock/SiConfig.h
+gSiConfigGuid = {0x4ed6d282, 0x22f3, 0x4fe1, {0xa6, 0x61, 0x6, 0x1a, 0x97, 0x38, 0x59, 0xd8 }}
+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}}
+
+##
+## System Agent
+##
+gSaAcpiTableStorageGuid  =  {0x3c0ed5e2, 0x91ea, 0x4b94, { 0x82, 0xd, 0x9d, 0xaf, 0x9a, 0x3b, 0xb4, 0xa2}}
+gSaDataHobGuid  =  {0xe07d0bda, 0xbf90, 0x46a9, { 0xb0, 0x0e, 0xb2, 0xc4, 0x4a, 0x0e, 0xd6, 0xd0}}
+gSaConfigHobGuid  = {0x762fa2e6, 0xea3b, 0x41c8, { 0x8c, 0x52, 0x63, 0x76, 0x6d, 0x70, 0x39, 0xe0}}
+gSaPegHobGuid  = {0x440ab2e5, 0xa3ea, 0x466f, { 0x84, 0x96, 0xdf, 0xb1, 0x3b, 0x75, 0x29, 0x95}}
+gSgAcpiTableStorageGuid  =  {0x8de8964f, 0x2939, 0x4b49, { 0xa3, 0x48, 0xf6, 0xb2, 0xb2, 0xde, 0x4a, 0x42}}
+gSaSsdtAcpiTableStorageGuid  =  {0xca89914d, 0x2317, 0x452e, { 0xb2, 0x45, 0x36, 0xc6, 0xfb, 0x77, 0xa9, 0xc6}}
+gPegSsdtAcpiTableStorageGuid  =  {0xE05B8635, 0xE5C0, 0x4D88, { 0xB6, 0x29, 0x19, 0xD6, 0xA2, 0xC6, 0xE9, 0x2E}}
+gSgAcpiTablePchStorageGuid  =  {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}}
+gSaPciePeiPreMemConfigGuid  =  { 0x81baf3c9, 0xf295, 0x4572, { 0x8b, 0x21, 0x79, 0x3f, 0xa3, 0x1b, 0xa5, 0xdb}}
+gSaPciePeiConfigGuid  =  { 0xdaa929a9, 0x5ec9, 0x486a, { 0xb0, 0xf7, 0x82, 0x3a, 0x55, 0xc7, 0xb5, 0xb3}}
+gGraphicsPeiPreMemConfigGuid  =  { 0x0319c56b, 0xc43a, 0x42f1, { 0x80, 0xbe, 0xca, 0x5b, 0xd1, 0xd5, 0xc9, 0x28}}
+gGraphicsPeiConfigGuid  =  { 0x04249ac0, 0x0088, 0x439f, { 0xa7, 0x4e, 0xa7, 0x04, 0x2a, 0x06, 0x2f, 0x5d}}
+gSwitchableGraphicsConfigGuid  =  { 0xc7956998, 0xc065, 0x46c4, { 0x8e, 0x2f, 0x58, 0x2b, 0x67, 0xeb, 0xbe, 0x2f}}
+gCpuTraceHubConfigGuid =  { 0xf2e17477, 0x93f3, 0x430d, { 0x9e, 0x08, 0x3c, 0xcc, 0x6e, 0x2f, 0x6c, 0x4b}}
+gMemoryConfigGuid  =  { 0x26cf084c, 0xc9db, 0x41bb, { 0x92, 0xc6, 0xd1, 0x97, 0xb8, 0xa1, 0xe4, 0xbf}}
+gMemoryConfigNoCrcGuid  =  { 0xc56c73d0, 0x1cdb, 0x4c0c, { 0xa9, 0x57, 0xea, 0x62, 0xa9, 0xe6, 0xf5, 0x0c}}
+gIpuPreMemConfigGuid  =  { 0x830a222b, 0x3ff5, 0x432e, { 0x9d, 0xd5, 0x4e, 0xe3, 0xfc, 0xa2, 0xaa, 0xa2}}
+gGnaConfigGuid  =  { 0x53e0ef18, 0xb8a8, 0x4795, { 0xa6, 0x6d, 0xe4, 0x77, 0x2c, 0xc3, 0xae, 0x82}}
+gVtdConfigGuid  =  { 0x03e5cf63, 0xbebb, 0x4041, { 0xb7, 0xe7, 0xbf, 0x54, 0x61, 0x20, 0xf1, 0xc5}}
+gGraphicsDxeConfigGuid  =  {0x34d93161, 0xf78e, 0x4915, {0xad, 0xc4, 0xdb, 0x67, 0x16, 0x42, 0x39, 0x24}}
+gMiscDxeConfigGuid  =  {0x7ce5f5ef, 0x4ef1, 0x4f9f, {0x8e, 0x29, 0x5f, 0xf4, 0x5f, 0x2f, 0xd8, 0xaf}}
+gPcieDxeConfigGuid  =  {0x1ed2d6f1, 0xa9d2, 0x476e, {0x8e, 0x74, 0xad, 0xd9, 0x5b, 0x5,  0x10, 0x82}}
+gMemoryDxeConfigGuid  =  {0xa5c7dda8, 0x686b, 0x404f, {0x86, 0x40, 0xf8, 0x2,  0xd,  0x84, 0x4c, 0x94}}
+gVbiosDxeConfigGuid  =  {0x8df0f30a, 0x8156, 0x4897, {0xa2, 0x18, 0x1f, 0xd3, 0x91, 0xbc, 0x46, 0x26}}
+gSaOverclockingPreMemConfigGuid  =  { 0x09ecc29d, 0xdbbe, 0x49fb, { 0xa6, 0x49, 0x4b, 0xf6, 0x40, 0xe2, 0xeb, 0xd6}}
+gFspReservedMemoryResourceHobTsegGuid  =  { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}}
+
+## 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}}
+
+## 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 }}
+
+##
+## 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}}
+gHtBistHobGuid  =  {0xbe644001, 0xe7d4, 0x48b1, {0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7}}
+gCpuInitDataHobGuid  =  {0x266e31cc, 0x13c5, 0x4807, {0xb9, 0xdc, 0x39, 0xa6, 0xba, 0x88, 0xff, 0x1a}}
+gEpcBiosDataGuid  =  {0xc60aa7f6, 0xe8d6, 0x4956, {0x8b, 0xa1, 0xfe, 0x26, 0x29, 0x8f, 0x5e, 0x87}}
+gCpuSecurityPreMemConfigGuid = {0xfd5c346, 0x8260, 0x4067, {0x94, 0x69, 0xcf, 0x91, 0x68, 0xa3, 0x42, 0x90}}
+gCpuConfigLibPreMemConfigGuid = {0xfc1c0ec2, 0xc6b4, 0x4f05, {0xbb, 0x85, 0xc8, 0x0, 0x8d, 0x5b, 0x4a, 0xb7}}
+gCpuSgxConfigGuid = {0xc30bc5ac, 0x828a, 0x45ae, {0x83, 0x1b, 0x8e, 0xb, 0x73, 0x9a, 0xb2, 0xf2}}
+gCpuTestConfigGuid = {0xd4dba957, 0xd9c, 0x4af2, {0x9d, 0x40, 0x35, 0xa8, 0x44, 0xe4, 0x93, 0xad}}
+gCpuConfigGuid = {0x48c3aac9, 0xd66c, 0x42e4, {0x9b, 0x1d, 0x39, 0x4, 0x5f, 0x46, 0x53, 0x41}}
+gCpuOverclockingPreMemConfigGuid = {0x396223b6, 0x6088, 0x44e7, {0x99, 0xcb, 0xfa, 0x8b, 0x99, 0x3d, 0xed, 0x4c}}
+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}}
+gCpuPowerMgmtTestConfigGuid = {0x5161ed3d, 0x90bf, 0x436f, {0xb8, 0x33, 0xd7, 0x17, 0x89, 0xb3, 0x48, 0xc1}}
+
+##
+## Me
+##
+gMePeiPreMemConfigGuid  =  {0x67ed113b, 0xd4ab, 0x43f5, {0x9c, 0x3c, 0x35, 0x44, 0x15, 0xaa, 0x47, 0x5c}}
+gMePeiConfigGuid  =  {0x9bad5628, 0x657b, 0x48e3, {0xb1, 0x11, 0xc3, 0xb9, 0xeb, 0xea, 0xee, 0x17}}
+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}}
+
+##
+## 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 = {0x8c7ee32c, 0x0870, 0x4bfa, {0x84, 0x79, 0x5b, 0xa5, 0x67, 0xc4, 0xae, 0x5b}}
+
+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}}
+gTraceHubPreMemConfigGuid  =  {0xC26AC3F6, 0xDAD0, 0x4E91, {0xB6, 0xD6, 0xD8, 0x51, 0x6F, 0x8F, 0x9B, 0x7B}}
+gPchTraceHubPreMemConfigGuid  = {0x8456c11, 0xdb85, 0x4914, {0x8d, 0x1a, 0xe5, 0xac, 0x64, 0x37, 0xe8, 0x96}}
+gPcieRpPreMemConfigGuid  =  {0x8377AB38, 0xF8B0, 0x476A, { 0x9C, 0xA1, 0x68, 0xEA, 0x78, 0x57, 0xD8, 0x2A}}
+gHpetPreMemConfigGuid  =  {0x7C75C0F1, 0xA20F, 0x42EB, {0x83, 0xDE, 0xE8, 0x58, 0xAB, 0x81, 0xC5, 0xDC}}
+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}}
+gHsioPreMemConfigGuid  =  {0xbc9e5787, 0x3ddb, 0x4916, {0x8c, 0xcc, 0x82, 0xb8, 0x9, 0x43, 0xe2, 0xf0}} #deprecated
+
+gPchGeneralConfigGuid  =  {0x6ED94C8C, 0x25F7, 0x4686, {0xB2, 0x46, 0xCA, 0x4D, 0xE2, 0x95, 0x4B, 0x5D}}
+gPcieRpConfigGuid  =  {0x0A53B507, 0x988B, 0x475C, {0xBF, 0x76, 0x33, 0xDE, 0x10, 0x6D, 0x94, 0x84}}
+gSataConfigGuid  =  {0xF5F87B4F, 0xCC3C, 0x408D, {0x89, 0xE3, 0x61, 0xC5, 0x9C, 0x54, 0x07, 0xC4}}
+gIoApicConfigGuid  =  {0x2873D0F1, 0x00F6, 0x40AB, {0xAC, 0x36, 0x9A, 0x68, 0xBA, 0x87, 0x3E, 0x6C}}
+gCio2ConfigGuid  =  {0xFBC4C192, 0x789D, 0x4038, {0x90, 0xE1, 0x5E, 0x6D, 0xFD, 0x52, 0xAF, 0x8A}}
+gDmiConfigGuid  =  {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}}
+gLanConfigGuid  =  {0x4B2DE99E, 0x7517, 0x4D04, {0x8C, 0x02, 0xF1, 0x1A, 0x59, 0x2B, 0x14, 0x2F}}
+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}}
+gPort61ConfigGuid  =  {0x59913475, 0x1960, 0x4099, {0x80, 0xEC, 0xAF, 0xC7, 0xCF, 0x5F, 0x9F, 0xAC}}
+gScsConfigGuid  =  {0xF4DE6D52, 0xB5C9, 0x48C0, {0xA0, 0x4A, 0x68, 0x54, 0x20, 0x94, 0x05, 0xD0}}
+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}}
+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}}
+
+##
+## 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 }}
+gTpmDeviceInstanceTpm20PttGuid        =  {0x72cd3a7b, 0xfea5, 0x4f5e, {0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}}
+gTpmDeviceInstanceTpm20PttPtpGuid     =  {0x93d66f66, 0x55da, 0x4f03, {0x9b, 0x5f, 0x32, 0xcf, 0x9e, 0x54, 0x3b, 0x3a}}
+gEfiTrEEPhysicalPresenceGuid          =  {0xf24643c2, 0xc622, 0x494e, {0x8a, 0x0d, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b}}
+gTcoWdtHobGuid                        = { 0x3e405418, 0x0d8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x08, 0x41, 0x46, 0x8d }}
+
+##
+## Pre-Memory 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}}
+
+##
+## Post-Memory 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}}
+
+[Protocols.common.Private]
+  #
+  # SA
+  #
+  gSaIotrapSmiProtocolGuid        = { 0x1861e089, 0xcaa3, 0x473e, { 0x84, 0x32, 0xdc, 0x1f, 0x94, 0xc6, 0xc1, 0xa6 }}
+
+  #
+  # CPU
+  #
+  gPchPcieIoTrapProtocolGuid      = { 0xd66a1cf,  0x79ad, 0x494b, { 0x97, 0x8b, 0xb2, 0x59, 0x81, 0x68, 0x93, 0x34 }}
+
+[Protocols]
+##
+## IntelFrameworkPkg
+##
+gEfiLegacyBiosProtocolGuid  =  {0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d}}
+gEfiLegacyInterruptProtocolGuid  =  {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}}
+gEfiDataHubProtocolGuid  =  {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}
+
+##
+## MdeModulePkg
+##
+gEfiSmmVariableProtocolGuid  =  {0xed32d533, 0x99e6, 0x4209, {0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7}}
+
+##
+## 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}}
+gGopComponentName2ProtocolGuid  =  {0x651b7ebd, 0xce13, 0x41d0, {0x82, 0xe5, 0xa0, 0x63, 0xab, 0xbe, 0x9b, 0xb6}}
+gGopOverrideProtocolGuid        =  {0x4a89a16e, 0x67b8, 0x4429, {0x8c, 0x47, 0x43, 0x67, 0x90, 0xf2, 0xf2, 0x69}}
+
+##
+## AcpiTables
+##
+gEfiGlobalNvsAreaProtocolGuid  =  {0x074e1e48, 0x8132, 0x47a1, {0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc}}
+
+##
+## Cpu
+##
+gCpuInfoProtocolGuid  =  {0xe223cf65, 0xf6ce, 0x4122, {0xb3, 0xaf, 0x4b, 0xd1, 0x8a, 0xff, 0x40, 0xa1}}
+gCpuNvsAreaProtocolGuid  =  {0xb9cf3f43, 0xbe3e, 0x4e45, {0xa0, 0xbe, 0x1a, 0x4, 0x89, 0xdf, 0x1a, 0xc9}}
+gDxeCpuPolicyProtocolGuid  =  {0x8282b977, 0x22f9, 0x4134, {0x99, 0x43, 0x7b, 0xcc, 0x5f, 0x40, 0x33, 0x52}}
+
+##
+## Me
+##
+gDxeMePolicyGuid                 = {0xa0b5dc52, 0x4f34, 0x3990, {0xd4, 0x91, 0x10, 0x8b, 0xe8, 0xba, 0x75, 0x42}}
+
+##
+## PCH
+##
+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}}
+gPchResetCallbackProtocolGuid  =  {0x3a3300ab, 0xc929, 0x487d, {0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0}}
+gPchNvsAreaProtocolGuid  =  {0x2e058b2b, 0xedc1, 0x4431, {0x87, 0xd9, 0xc6, 0xc4, 0xea, 0x10, 0x2b, 0xe3}}
+gPchEmmcTuningProtocolGuid  =  {0x10fe7e3b, 0xdbe5, 0x4cfa, {0x90, 0x25, 0x40, 0x02, 0xcf, 0xdd, 0xbb, 0x89}}
+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}}
+gPchSraProtocolGuid = {0x7AE12E27, 0x5087, 0x46C8, {0xBF, 0xF0, 0x83, 0x9C, 0x53, 0x7B, 0x25, 0xEB}}
+
+##
+## 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 }}
+
+[Ppis.common.Private]
+
+[Ppis]
+##
+## MdeModulePkg
+##
+gPeiCapsulePpiGuid  =  {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d}}
+gPeiSmmAccessPpiGuid  =  {0x268f33a9, 0xcccd, 0x48be, {0x88, 0x17, 0x86, 0x05, 0x3a, 0xc3, 0x2e, 0xd6}}
+gPeiSmmControlPpiGuid  =  {0x61c68702, 0x4d7e, 0x4f43, {0x8d, 0xef, 0xa7, 0x43, 0x05, 0xce, 0x74, 0xc5}}
+
+##
+## SecurityPkg
+##
+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}}
+
+##
+## 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}}
+
+##
+## Cpu
+##
+gPeiCachePpiGuid  =  {0x09be4bc2, 0x790e, 0x4dea, {0x8b, 0xdc, 0x38, 0x05, 0x16, 0x98, 0x39, 0x44}}
+
+##
+## Me
+##
+gMeDidSentPpiGuid = {0x45dc3106, 0xef67, 0x4c71, {0xb0, 0xf0, 0x97, 0x15, 0x9c, 0x7d, 0xbb, 0x7c}}
+
+##
+## 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}}
+gPchResetCallbackPpiGuid  =  {0x17865dc0, 0x0b8b, 0x4da8, {0x8b, 0x42, 0x7c, 0x46, 0xb8, 0x5c, 0xca, 0x4d}}
+
+[LibraryClasses]
+##
+## Common
+##
+AslUpdateLib|Include/Library/AslUpdateLib.h
+SiPolicyLib|Include/Library/SiPolicyLib.h
+UsbLib|Include/Library/UsbLib.h
+UsbInitLib|Include/Private/Library/UsbInitLib.h
+
+##
+## CPU
+##
+CpuMailboxLib|Cpu/Include/Library/CpuMailboxLib.h
+CpuPlatformLib|Cpu/Include/Library/CpuPlatformLib.h
+CpuPolicyLib|Cpu/Include/Library/CpuPolicyLib.h
+
+##
+## Me
+##
+PeiMePolicyLib|Me/Include/Library/PeiMePolicyLib.h
+
+##
+## Pch
+##
+GpioLib|Pch/Include/Library/GpioLib.h
+GpioLib|Pch/Include/Library/GpioNativeLib.h
+PchCycleDecodingLib|Pch/Include/Library/PchCycleDecodingLib.h
+PchEspiLib|Pch/Include/Library/PchEspiLib.h
+PchGbeLib|Pch/Include/Library/PchGbeLib.h
+GbeMdiLib|Pch/Include/Library/GbeMdiLib.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
+PchPmcLib|Pch/Include/Library/PchPmcLib.h
+PchPolicyLib|Pch/Include/Library/PchPolicyLib.h
+PchSbiAccessLib|Pch/Include/Library/PchSbiAccessLib.h
+PchSerialIoLib|Pch/Include/Library/PchSerialIoLib.h
+PchSerialIoUartLib|Pch/Include/Library/PchSerialIoUartLib.h
+SecPchLib|Pch/Include/Library/SecPchLib.h
+PchTraceHubLib|Pch/Include/Private/Library/PchTraceHubLib.h
+PchSmmControlLib|Pch/IncludePrivate/Library/PchSmmControlLib.h
+PchWdtCommonLib|Pch/Include/Library/PchWdtCommonLib.h
+OcWdtLib|Pch/Include/Library/OcWdtLib.h
+PchResetLib|Pch/Include/Library/PchResetLib.h
+DxePchPolicyLib|Pch/Include/Library/DxePchPolicyLib.h
+GpioNameBufferLib|Pch/IncludePrivate/Library/GpioNameBufferLib.h
+
+##
+## Sa
+##
+DxeSaPolicyLib|SystemAgent/Include/Library/DxeSaPolicyLib.h
+PeiSaPolicyLib|SystemAgent/Include/Library/PeiSaPolicyLib.h
+SaPlatformLib|SystemAgent/Include/Library/SaPlatformLib.h
+
+##
+## Memory
+##
+
+[PcdsFixedAtBuild]
+## From MdeModulePkg.dec
+## 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.PcdFlashMicrocodeFvBase|0xFFE60000|UINT32|0x30000004
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize|0x000A0000|UINT32|0x30000005
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|0x00660000|UINT32|0x30000006
+
+##
+## 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
+
+gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi|0x55|UINT8|0x0010005
+gSiPkgTokenSpaceGuid.PcdHwpSmi|0x27|UINT8|0x40000001
+gSiPkgTokenSpaceGuid.PcdItbmSmi|0x29|UINT8|0x40000002
+
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioBase|0x0000004000000000|UINT64|0x40000003
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioSize|0x0000004000000000|UINT64|0x40000004
+
+[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
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+## Maximun number of performance log entries during PEI phase.
+gSiPkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|40|UINT8|0x0001002f
+## This value is used to set the base address of MCH
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress|0xFED10000|UINT64|0x00010030
+## This value is used to set the base address of PCH devices
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress|0x0000EFA0|UINT16|0x00010031
+gSiPkgTokenSpaceGuid.PcdTcoBaseAddress|0x0400|UINT16|0x00010034
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress|0x1800|UINT16|0x00010035
+
+## 32KB window
+gSiPkgTokenSpaceGuid.PcdMchMmioSize|0x8000|UINT32|0x50000000
+
+## 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
+
+##
+## Default 8MB TSEG
+##
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000|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
+##
+
+##Major:To represent code generation
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionMajor   |0x07|UINT8|0x00010049
+
+##Revision:Weekly build number
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionRevision|0x57|UINT8|0x00010051
+
+##Build[7:4]:Daily build number.
+##Build[3:0]:Patch build number.
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionBuild   |0x40|UINT8|0x00010052
+
+
+##
+## 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.PcdHpetBaseAddress    |0xFED00000|UINT32|0x00010057
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress  |0xFED00000|UINT32|0x00010060
+##
+## This PCD specifies the base address of the IO APIC.
+## The acceptable values are 0xFECxx000.
+##
+#gSiPkgTokenSpaceGuid.PcdIoApicBaseAddress  |0xFEC00000|UINT32|0x00010058
+##
+## Regbar Base Address
+##
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress|0xFC000000|UINT32|0x00010059
+
+## 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
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+##
+## SerialIo Uart Configuration
+##
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable |0      |UINT8 |0x00100001 # 0:Disable, 1:Enable and Initialize, 2:Enable without Initializing
+gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber      |2      |UINT8 |0x00100002
+gSiPkgTokenSpaceGuid.PcdSerialIoUartInputClock  |1843200|UINT32|0x00100003
+gSiPkgTokenSpaceGuid.PcdSerialIoUart0PinMuxing  |0      |UINT8 |0x00100009 # 0: default pins, 1: pins muxed with CNV_BRI/RGI
+##
+## PCI Express MMIO region length
+## Valid settings: 0x10000000/256MB, 0x8000000/128MB, 0x4000000/64MB
+##
+gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000|UINT32|0x0010004
+
+## Indidates if SMM Save State saved in MSRs.
+#  if enabled, SMM Save State will use the MSRs instead of the memory.<BR><BR>
+#   TRUE  - SMM Save State will use the MSRs.<BR>
+#   FALSE - SMM Save State will use the memory.<BR>
+# @Prompt SMM Save State uses MSRs.
+gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable|FALSE|BOOLEAN|0x20000001
+[PcdsDynamic]
+
+## Indidates if SMM Delay feature is supported.<BR><BR>
+#   TRUE  - SMM Delay feature is supported.<BR>
+#   FALSE - SMM Delay feature is not supported.<BR>
+# @Prompt SMM Delay feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication|TRUE|BOOLEAN|0x0010009
+
+## Indidates if SMM Block feature is supported.<BR><BR>
+#   TRUE  - SMM Block feature is supported.<BR>
+#   FALSE - SMM Block feature is not supported.<BR>
+# @Prompt SMM Block feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication|TRUE|BOOLEAN|0x001000A
+
+## Indidates if SMM Enable/Disable feature is supported.<BR><BR>
+#   TRUE  - SMM Enable/Disable feature is supported.<BR>
+#   FALSE - SMM Enable/Disable feature is not supported.<BR>
+# @Prompt SMM Enable/Disable feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication|TRUE|BOOLEAN|0x001000B
+
+## 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|TRUE|BOOLEAN|0x001000C
+
+## 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
+
+[PcdsFeatureFlag]
+##
+## Those PCDs are used to control build process.
+##
+gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE|BOOLEAN|0xF0000001
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |FALSE|BOOLEAN|0xF0000002
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE|BOOLEAN|0xF0000004
+gSiPkgTokenSpaceGuid.PcdSiCsmEnable                  |FALSE|BOOLEAN|0xF0000005
+gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE |BOOLEAN|0xF0000006
+gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE |BOOLEAN|0xF0000008
+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.PcdSmbiosEnable                 |TRUE |BOOLEAN|0xF0000014
+gSiPkgTokenSpaceGuid.PcdS3Enable                     |TRUE |BOOLEAN|0xF0000015
+gSiPkgTokenSpaceGuid.PcdOverclockEnable              |FALSE|BOOLEAN|0xF0000016
+gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable       |FALSE|BOOLEAN|0xF0000017
+gSiPkgTokenSpaceGuid.PcdIgdEnable                    |TRUE |BOOLEAN|0xF000001A
+gSiPkgTokenSpaceGuid.PcdPegEnable                    |TRUE |BOOLEAN|0xF000001B
+gSiPkgTokenSpaceGuid.PcdSaDmiEnable                  |TRUE |BOOLEAN|0xF000001C
+gSiPkgTokenSpaceGuid.PcdIpuEnable                    |TRUE |BOOLEAN|0xF000001D
+gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE |BOOLEAN|0xF000001E
+gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE |BOOLEAN|0xF000001F
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE |BOOLEAN|0xF0000020
+gSiPkgTokenSpaceGuid.PcdBdatEnable                   |FALSE|BOOLEAN|0xF0000023
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE |BOOLEAN|0xF0000024
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE |BOOLEAN|0xF0000025
+gSiPkgTokenSpaceGuid.PcdCflCpuEnable                 |FALSE|BOOLEAN|0xF0000027
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |FALSE|BOOLEAN|0xF0000029
+gSiPkgTokenSpaceGuid.PcdMinTreeEnable                |FALSE|BOOLEAN|0xF000002A  # To separate modules used in mininal source tree and advanced features
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |FALSE|BOOLEAN|0xF0000033
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE|BOOLEAN|0xF0000034
+
+gSiPkgTokenSpaceGuid.PcdEdk2MasterEnable             |FALSE|BOOLEAN|0xF0000035
+gSiPkgTokenSpaceGuid.PcdPpamEnable                   |TRUE |BOOLEAN|0xF0000036
+
+#This PCD is used to enable WDT for debug purposes in OverClocking.
+gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug          |FALSE|BOOLEAN|0xF0000037
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
new file mode 100644
index 0000000000..d0e3d94418
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
new file mode 100644
index 0000000000..27b5a9440e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
@@ -0,0 +1,89 @@
+/** @file
+  Si Config Block
+
+  Copyright (c) 2019 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  3
+
+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
+  <b>Revision 3</b>
+  - Deprecated SkipPostBootSai
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Offset 0 - 27 Config Block Header
+  //
+  // Platform specific common policies that used by several silicon components.
+  //
+  UINT32 CsmFlag          :  1;  ///< Offset 44 BIT0: CSM status flag.
+  /**
+    @deprecated since revision 3
+  **/
+  UINT32 SkipPostBootSai  :  1;
+  UINT32 RsvdBits         : 30;  ///< Reserved
+  UINT32 *SsidTablePtr;          // Offset 48
+  UINT16 NumberOfSsidTableEntry; // Offset 52
+  UINT16 Reserved;               // Offset 54
+  /**
+    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
+} SI_CONFIG;
+
+#pragma pack (pop)
+
+#define DEFAULT_SSVID    0x8086
+#define DEFAULT_SSDID    0x7270
+#define 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 {
+      UINT64  Register:12;
+      UINT64  Function:3;
+      UINT64  Device:5;
+      UINT64  Bus:8;
+      UINT64  Reserved1:4;
+      UINT64  Segment:16;
+      UINT64  Reserved2:16;
+    } Bits;
+    UINT64    SegBusDevFuncRegister;
+  } Address;
+  SVID_SID_VALUE SvidSidValue;
+  UINT32 Reserved;
+} SVID_SID_INIT_ENTRY;
+
+#endif // _SI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
new file mode 100644
index 0000000000..8b51e2d47a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
@@ -0,0 +1,291 @@
+/** @file
+  Common USB policy shared between PCH and CPU
+  Contains general features settings for xHCI and xDCI
+
+  Copyright (c) 2019 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 3
+extern EFI_GUID gUsbConfigGuid;
+
+#define MAX_USB2_PORTS  16
+#define MAX_USB3_PORTS  10
+
+#pragma pack (push,1)
+
+#define PCH_USB_OC_PINS_MAX  8  ///< Maximal possible number of USB Over Current pins
+
+///
+/// Overcurrent pins, the values match the setting of EDS, please refer to EDS for more details
+///
+typedef enum {
+  UsbOverCurrentPin0 = 0,
+  UsbOverCurrentPin1,
+  UsbOverCurrentPin2,
+  UsbOverCurrentPin3,
+  UsbOverCurrentPin4,
+  UsbOverCurrentPin5,
+  UsbOverCurrentPin6,
+  UsbOverCurrentPin7,
+  UsbOverCurrentPinMax,
+  UsbOverCurrentPinSkip = 0xFF
+} USB_OVERCURRENT_PIN;
+
+/**
+  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;
+} USB20_AFE;
+
+/**
+  This structure configures per USB2 port physical settings.
+  It allows to setup the port location and port length, and configures the port strength accordingly.
+**/
+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 (see: USB_OVERCURRENT_PIN).
+  **/
+  UINT32     OverCurrentPin     :  8;
+  UINT32     Enable             :  1;     ///< 0: Disable; <b>1: Enable</b>.
+  UINT32     RsvdBits0          : 23;     ///< Reserved bits
+  /**
+    Changing this policy values from default ones may require disabling USB2 PHY Sus Well Power Gating
+    through Usb2PhySusPgEnable on PCH-LP
+  **/
+  USB20_AFE  Afe;                         ///< USB2 AFE settings
+} USB20_PORT_CONFIG;
+
+/**
+  This structure describes whether the USB3 Port N is enabled by platform modules.
+**/
+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 (see: USB_OVERCURRENT_PIN).
+  **/
+  UINT32  OverCurrentPin            :  8;
+
+  /**
+    USB 3.0 TX Output Downscale Amplitude Adjustment (orate01margin)
+    HSIO_TX_DWORD8[21:16]
+    <b>Default = 00h</b>
+  **/
+  UINT32  HsioTxDownscaleAmp        :  8;
+  /**
+    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)
+  **/
+  UINT32  HsioTxDeEmph              :  8;
+
+  UINT32  Enable                    :  1; ///< 0: Disable; <b>1: Enable</b>.
+  UINT32  HsioTxDeEmphEnable        :  1; ///< Enable the write to USB 3.0 TX Output -3.5dB De-Emphasis Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioTxDownscaleAmpEnable  :  1; ///< Enable the write to USB 3.0 TX Output Downscale Amplitude Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                 :  5; ///< Reserved bits
+} USB30_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;
+
+//
+// Below defines are for proper UPD construction and values syncing between UPD and policy
+//
+#define B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN      BIT0  ///< Enable the write to Signed Magnatude number added to the CTLE code bit
+#define B_XHCI_HSIO_FILTER_SELECT_N_EN            BIT1  ///< Enable the write to LFPS filter select for n
+#define B_XHCI_HSIO_FILTER_SELECT_P_EN            BIT2  ///< Enable the write to LFPS filter select for p
+#define B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN    BIT3  ///< Enable the write to olfpscfgpullupdwnres
+#define N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG     3
+#define N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES   0
+#define N_XHCI_UPD_HSIO_FILTER_SELECT_P           0
+#define N_XHCI_UPD_HSIO_FILTER_SELECT_N           4
+
+typedef struct {
+  /**
+    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>
+  **/
+  UINT32  HsioCtrlAdaptOffsetCfg      :  5;
+  /**
+    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>
+  **/
+  UINT32  HsioFilterSelN              :  3;
+  /**
+    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>
+  **/
+  UINT32  HsioFilterSelP              :  3;
+  /**
+    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>
+  **/
+  UINT32  HsioOlfpsCfgPullUpDwnRes    :  3;
+
+  UINT32  HsioCtrlAdaptOffsetCfgEnable    :  1; ///< Enable the write to Signed Magnatude number added to the CTLE code, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioFilterSelNEnable            :  1; ///< Enable the write to LFPS filter select for n, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioFilterSelPEnable            :  1; ///< Enable the write to LFPS filter select for p, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioOlfpsCfgPullUpDwnResEnable  :  1; ///< Enable the write to olfpscfgpullupdwnres, <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                       : 14; ///< Reserved bits
+} USB30_HSIO_RX_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>:
+  - Added Usb2PhySusPgEnable - for enabling/disabling USB2 PHY SUS Well Power Gating
+  <b>Revision 3</b>:
+    Added HSIO Rx tuning policy options structure USB30_HSIO_RX_CONFIG
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
+  /**
+    This policy setting controls state of Compliance Mode enabling.
+    Compliance Mode can be enabled for testing through this option but defualt setting is Disabled.
+    <b>0:Disable</b>, 1: Enable
+  **/
+  UINT32                  EnableComplianceMode         :  1;
+  /**
+    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;
+  /**
+    <b>(Test)</b>
+    This policy option enables USB2 PHY SUS Well Power Gating functionality.
+    Please note this is ignored on PCH H
+    <b>0: disable USB2 PHY SUS Well Power Gating</b>
+    1: enable USB2 PHY SUS Well Power Gating
+  **/
+  UINT32                  Usb2PhySusPgEnable           :  1;
+  UINT32                  RsvdBits0                    : 27;     ///< Reserved bits
+  /**
+    These members describe whether the USB2 Port N of PCH is enabled by platform modules.
+  **/
+  USB20_PORT_CONFIG       PortUsb20[MAX_USB2_PORTS];
+  /**
+    These members describe whether the USB3 Port N of PCH is enabled by platform modules.
+  **/
+  USB30_PORT_CONFIG       PortUsb30[MAX_USB3_PORTS];
+  /**
+    This member describes whether or not the xDCI controller should be enabled.
+  **/
+  XDCI_CONFIG             XdciConfig;
+  /**
+    This member describes policy options for RX signal tuning in ModPHY
+  **/
+  USB30_HSIO_RX_CONFIG    PortUsb30HsioRx[MAX_USB3_PORTS];
+} USB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _USB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..39baa6c03a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,157 @@
+/** @file
+  ASL dynamic update library definitions.
+  This library provides dymanic update to various ASL structures.
+  There may be different libraries for different environments (PEI, BS, RT, SMM).
+  Make sure you meet the requirements for the library (protocol dependencies, use
+  restrictions, etc).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ASL_UPDATE_LIB_H_
+#define _ASL_UPDATE_LIB_H_
+
+//
+// Include files
+//
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+//
+// AML parsing definitions
+//
+#define AML_RESRC_TEMP_END_TAG  0x0079
+
+//
+// ASL PSS package structure layout
+//
+#pragma pack (1)
+typedef struct {
+  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
+  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
+  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
+  UINT8     DwordPrefix1;     // 0Ch
+  UINT32    CoreFrequency;    // 00h
+  UINT8     DwordPrefix2;     // 0Ch
+  UINT32    Power;            // 00h
+  UINT8     DwordPrefix3;     // 0Ch
+  UINT32    TransLatency;     // 00h
+  UINT8     DwordPrefix4;     // 0Ch
+  UINT32    BmLatency;        // 00h
+  UINT8     DwordPrefix5;     // 0Ch
+  UINT32    Control;          // 00h
+  UINT8     DwordPrefix6;     // 0Ch
+  UINT32    Status;           // 00h
+} PSS_PACKAGE_LAYOUT;
+#pragma pack()
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  );
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature               The signature of Operation Region that we want to update.
+  @param[in] Buffer                     source of data to be written over original aml
+  @param[in] Length                     length of data to be overwritten
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode(
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  );
+
+/**
+  This procedure will update the name of ASL Method
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateMethodAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI table using the .
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+  Matches are determined by finding the table with ACPI table that has
+  a matching signature and version.
+
+  @param[in] Signature                  Pointer to an ASCII string containing the Signature to match
+  @param[in, out] Table                 Updated with a pointer to the table
+  @param[in, out] Handle                AcpiSupport protocol table handle for the table found
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI SSDT table.
+  The table is located by searching for a matching OEM Table ID field.
+  Partial match searches are supported via the TableIdSize parameter.
+
+  @param[in] TableId                    Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize                Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                        will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table                 Updated with a pointer to the table
+  @param[in, out] Handle                AcpiSupport protocol table handle for the table found
+  @param[in, out] Version               See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer                     Pointer to buffer to checksum
+  @param[in] Size                       Number of bytes to checksum
+  @param[in] ChecksumOffset             Offset to place the checksum result in
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
new file mode 100644
index 0000000000..9a3bf373a6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
@@ -0,0 +1,64 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
new file mode 100644
index 0000000000..858f8ac5e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
@@ -0,0 +1,28 @@
+/** @file
+  Get Pci Express address library implementation.
+
+  Copyright (c) 2019 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
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+);
+
+#endif // _PEI_DXE_SMM_MM_PCI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
new file mode 100644
index 0000000000..c6eb70f6e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Header file for PEI SiPolicyUpdate Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_UPDATE_LIB_H_
+#define _PEI_SI_POLICY_UPDATE_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  This function performs Silicon PEI Policy initialization.
+
+  @param[in, out] SiPolicy The Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS      The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicy (
+  IN OUT SI_POLICY_PPI *SiPolicy
+  );
+
+/**
+  This function performs CPU PEI Policy initialization in Post-memory.
+
+  @param[in, out] SiPolicyPpi     The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+  IN OUT  SI_POLICY_PPI *SiPolicyPpi
+  );
+
+/**
+  This function performs SI PEI Policy initialization.
+
+  @param[in, out] SiPolicyPpi     The SA Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicy (
+  IN OUT   SI_POLICY_PPI  *SiPolicyPpi
+  );
+
+
+/**
+This function performs SA PEI Policy initialization for PreMem.
+
+@param[in, out] SiPreMemPolicyPpi   The SI PreMem Policy PPI instance
+
+@retval EFI_SUCCESS             Update complete.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyPreMem (
+IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicyPpi
+);
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicy (
+  IN OUT  SI_POLICY_PPI         *SiPolicy
+  );
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPreMemPolicy  The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
+  );
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPolicy       The SI Policy PPI instance
+
+  @retval EFI_SUCCESS            Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicy (
+  IN OUT  SI_POLICY_PPI         *SiPolicy
+  );
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPreMemPolicy The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS            Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
new file mode 100644
index 0000000000..fd8582b981
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
@@ -0,0 +1,58 @@
+/** @file
+  Prototype of the SiConfigBlockLib library.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
new file mode 100644
index 0000000000..5633e2892c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
@@ -0,0 +1,110 @@
+/** @file
+  Prototype of the SiPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_LIB_H_
+#define _SI_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole SI_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi          The RC PREMEM Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi          The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPrintPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  );
+
+/**
+  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreatePreMemConfigBlocks (
+  OUT  SI_PREMEM_POLICY_PPI         **SiPreMemPolicyPpi
+  );
+
+/**
+  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreateConfigBlocks (
+  OUT  SI_POLICY_PPI         **SiPolicyPpi
+  );
+
+/**
+  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPreMemPolicyPpi   The pointer to Silicon PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiPreMemInstallPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  SiInstallPolicyPpi installs SiPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiInstallPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  );
+
+/**
+  Print out all silicon policy information.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval none
+**/
+VOID
+DumpSiPolicy (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  );
+
+#endif // _SI_PREMEM_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
new file mode 100644
index 0000000000..cab5342c54
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for a library to install StallPpi.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _STALL_PPI_LIB_H_
+#define _STALL_PPI_LIB_H_
+
+/**
+  This function is to install StallPpi
+
+  @retval  EFI_SUCCESS if Ppi is installed successfully.
+**/
+EFI_STATUS
+EFIAPI
+InstallStallPpi(
+  VOID
+  );
+#endif //_STALL_PPI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
new file mode 100644
index 0000000000..a7cd305c62
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Header file of available functions in general USB Library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB_LIB_H_
+#define _USB_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+
+/*
+  Disables requested ports through Port Disable Override register programming
+
+  @param[in]  XhciMmioBase        xHCI Memory BAR0 address
+  @param[in]  Usb2DisabledPorts   Disabled ports bitmask with a bit for each USB2 port
+                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
+  @param[in]  Usb3DisabledPorts   Disabled ports bitmask with a bit for each USB3 port
+                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
+
+  @retval EFI_SUCCESS             Programming ended successfully and no errors occured
+          EFI_ACCESS_DENIED       Port Disable Override register was locked and write
+                                  didn't go through. Platform may require restart to unlock.
+*/
+EFI_STATUS
+UsbDisablePorts (
+  IN  UINTN   XhciMmioBase,
+  IN  UINT32  Usb2DisabledPorts,
+  IN  UINT32  Usb3DisabledPorts
+  );
+
+#endif // _USB_LIB_H
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
new file mode 100644
index 0000000000..86bed53c6f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
@@ -0,0 +1,319 @@
+/** @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) 2019 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_PI_OFFSET                           0x09
+#define R_PCI_SCC_OFFSET                          0x0A
+#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
+#define B_PCI_BRIDGE_BNUM_PBN                     0x000000FF ///< Primary Bus Number
+#define B_PCI_BRIDGE_BNUM_SBBN_SCBN               (B_PCI_BRIDGE_BNUM_SBBN | B_PCI_BRIDGE_BNUM_SCBN)
+
+#define R_PCI_BRIDGE_IOBL                         0x1C ///< I/O Base and Limit Register
+
+#define R_PCI_BRIDGE_MBL                          0x20 ///< Memory Base and Limit Register
+#define B_PCI_BRIDGE_MBL_ML                       0xFFF00000 ///< Memory Limit
+#define B_PCI_BRIDGE_MBL_MB                       0x0000FFF0 ///< Memory Base
+
+#define R_PCI_BRIDGE_PMBL                         0x24 ///< Prefetchable Memory Base and Limit Register
+#define B_PCI_BRIDGE_PMBL_PML                     0xFFF00000 ///< Prefetchable Memory Limit
+#define B_PCI_BRIDGE_PMBL_I64L                    0x000F0000 ///< 64-bit Indicator
+#define B_PCI_BRIDGE_PMBL_PMB                     0x0000FFF0 ///< Prefetchable Memory Base
+#define B_PCI_BRIDGE_PMBL_I64B                    0x0000000F ///< 64-bit Indicator
+
+#define R_PCI_BRIDGE_PMBU32                       0x28 ///< Prefetchable Memory Base Upper 32-Bit Register
+#define B_PCI_BRIDGE_PMBU32                       0xFFFFFFFF
+
+#define R_PCI_BRIDGE_PMLU32                       0x2C ///< Prefetchable Memory Limit Upper 32-Bit Register
+#define B_PCI_BRIDGE_PMLU32                       0xFFFFFFFF
+
+//
+// PCIE capabilities register
+//
+#define R_PCIE_CAP_ID_OFFSET                      0x00 ///< Capability ID
+#define R_PCIE_CAP_NEXT_PRT_OFFSET                0x01 ///< Next Capability Capability ID Pointer
+
+//
+// PCI Express Capability List Register (CAPID:10h)
+//
+#define R_PCIE_XCAP_OFFSET                        0x02 ///< PCI Express Capabilities Register (Offset 02h)
+#define S_PCIE_XCAP                               2
+#define B_PCIE_XCAP_SI                            BIT8 ///< Slot Implemented
+#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 S_PCIE_DCAP                               4
+#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 B_PCIE_DCTL_URE                           BIT3 ///< Unsupported Request Reporting Enable
+#define B_PCIE_DCTL_FEE                           BIT2 ///< Fatal Error Reporting Enable
+#define B_PCIE_DCTL_NFE                           BIT1 ///< Non-Fatal Error Reporting Enable
+#define B_PCIE_DCTL_CEE                           BIT0 ///< Correctable Error Reporting Enable
+
+#define R_PCIE_DSTS_OFFSET                        0x0A ///< Device Status Register (Offset 0Ah)
+#define B_PCIE_DSTS_TDP                           BIT5 ///< Transactions Pending
+#define B_PCIE_DSTS_APD                           BIT4 ///< AUX Power Detected
+#define B_PCIE_DSTS_URD                           BIT3 ///< Unsupported Request Detected
+#define B_PCIE_DSTS_FED                           BIT2 ///< Fatal Error Detected
+#define B_PCIE_DSTS_NFED                          BIT1 ///< Non-Fatal Error Detected
+#define B_PCIE_DSTS_CED                           BIT0 ///< Correctable Error Detected
+
+#define R_PCIE_LCAP_OFFSET                        0x0C ///< Link Capabilities Register (Offset 0Ch)
+#define B_PCIE_LCAP_ASPMOC                        BIT22 ///< ASPM Optionality Compliance
+#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                          (BIT11 | BIT10) ///< Active State Power Management (ASPM) Support
+#define B_PCIE_LCAP_APMS_L0S                      BIT10
+#define B_PCIE_LCAP_APMS_L1                       BIT11
+#define N_PCIE_LCAP_APMS                          10
+#define B_PCIE_LCAP_MLW                           0x000003F0 ///< Maximum Link Width
+#define N_PCIE_LCAP_MLW                           4
+#define B_PCIE_LCAP_MLS                           (BIT3 | BIT2 | BIT1 | BIT0) ///< Max Link Speed
+#define V_PCIE_LCAP_MLS_GEN3                      3
+
+#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_ES                            BIT7 ///< Extended Synch
+#define B_PCIE_LCTL_CCC                           BIT6 ///< Common Clock Configuration
+#define B_PCIE_LCTL_RL                            BIT5 ///< Retrain Link
+#define B_PCIE_LCTL_LD                            BIT4 ///< Link Disable
+#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 V_PCIE_LSTS_NLW_1                         0x0010
+#define V_PCIE_LSTS_NLW_2                         0x0020
+#define V_PCIE_LSTS_NLW_4                         0x0040
+#define B_PCIE_LSTS_CLS                           0x000F ///< Current Link Speed
+#define V_PCIE_LSTS_CLS_GEN1                      1
+#define V_PCIE_LSTS_CLS_GEN2                      2
+#define V_PCIE_LSTS_CLS_GEN3                      3
+
+#define R_PCIE_SLCAP_OFFSET                       0x14 ///< Slot Capabilities Register (Offset 14h)
+#define S_PCIE_SLCAP                              4
+#define B_PCIE_SLCAP_PSN                          0xFFF80000 ///< Physical Slot Number
+#define B_PCIE_SLCAP_SLS                          0x00018000 ///< Slot Power Limit Scale
+#define B_PCIE_SLCAP_SLV                          0x00007F80 ///< Slot Power Limit Value
+#define B_PCIE_SLCAP_HPC                          BIT6 ///< Hot-Plug Capable
+#define B_PCIE_SLCAP_HPS                          BIT5 ///< Hot-Plug Surprise
+
+#define R_PCIE_SLCTL_OFFSET                       0x18 ///< Slot Control Register (Offset 18h)
+#define S_PCIE_SLCTL                              2
+#define B_PCIE_SLCTL_HPE                          BIT5 ///< Hot Plug Interrupt Enable
+#define B_PCIE_SLCTL_PDE                          BIT3 ///< Presence Detect Changed Enable
+
+#define R_PCIE_SLSTS_OFFSET                       0x1A ///< Slot Status Register (Offset 1Ah)
+#define S_PCIE_SLSTS                              2
+#define B_PCIE_SLSTS_PDS                          BIT6 ///< Presence Detect State
+#define B_PCIE_SLSTS_PDC                          BIT3 ///< Presence Detect Changed
+
+#define R_PCIE_RCTL_OFFSET                        0x1C ///< Root Control Register (Offset 1Ch)
+#define S_PCIE_RCTL                               2
+#define B_PCIE_RCTL_PIE                           BIT3 ///< PME Interrupt Enable
+#define B_PCIE_RCTL_SFE                           BIT2 ///< System Error on Fatal Error Enable
+#define B_PCIE_RCTL_SNE                           BIT1 ///< System Error on Non-Fatal Error Enable
+#define B_PCIE_RCTL_SCE                           BIT0 ///< System Error on Correctable Error Enable
+
+#define R_PCIE_RSTS_OFFSET                        0x20 ///< Root Status Register (Offset 20h)
+#define S_PCIE_RSTS                               4
+
+#define R_PCIE_DCAP2_OFFSET                       0x24 ///< Device Capabilities 2 Register (Offset 24h)
+#define B_PCIE_DCAP2_OBFFS                        (BIT19 | BIT18) ///< OBFF Supported
+#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_OBFFEN                       (BIT14 | BIT13) ///< OBFF Enable
+#define N_PCIE_DCTL2_OBFFEN                       13
+#define V_PCIE_DCTL2_OBFFEN_DIS                   0 ///< Disabled
+#define V_PCIE_DCTL2_OBFFEN_WAKE                  3 ///< Enabled using WAKE# signaling
+#define B_PCIE_DCTL2_LTREN                        BIT10 ///< LTR Mechanism Enable
+#define B_PCIE_DCTL2_CTD                          BIT4 ///< Completion Timeout Disable
+#define B_PCIE_DCTL2_CTV                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Completion Timeout Value
+#define V_PCIE_DCTL2_CTV_DEFAULT                  0x0
+#define V_PCIE_DCTL2_CTV_40MS_50MS                0x5
+#define V_PCIE_DCTL2_CTV_160MS_170MS              0x6
+#define V_PCIE_DCTL2_CTV_400MS_500MS              0x9
+#define V_PCIE_DCTL2_CTV_1P6S_1P7S                0xA
+
+#define R_PCIE_LCTL2_OFFSET                       0x30 ///< Link Control 2 Register (Offset 30h)
+#define B_PCIE_LCTL2_SD                           BIT6 ///< Selectable de-emphasis (0 = -6dB, 1 = -3.5dB)
+#define B_PCIE_LCTL2_TLS                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Target Link Speed
+#define V_PCIE_LCTL2_TLS_GEN1                     1
+#define V_PCIE_LCTL2_TLS_GEN2                     2
+#define V_PCIE_LCTL2_TLS_GEN3                     3
+
+#define R_PCIE_LSTS2_OFFSET                       0x32 ///< Link Status 2 Register (Offset 32h)
+#define B_PCIE_LSTS2_LER                          BIT5 ///< Link Equalization Request
+#define B_PCIE_LSTS2_EQP3S                        BIT4 ///< Equalization Phase 3 Successful
+#define B_PCIE_LSTS2_EQP2S                        BIT3 ///< Equalization Phase 2 Successful
+#define B_PCIE_LSTS2_EQP1S                        BIT2 ///< Equalization Phase 1 Successful
+#define B_PCIE_LSTS2_EC                           BIT1 ///< Equalization Complete
+#define B_PCIE_LSTS2_CDL                          BIT0 ///< Current De-emphasis Level
+
+//
+// PCI Power Management Capability (CAPID:01h)
+//
+#define R_PCIE_PMC_OFFSET                         0x02 ///< Power Management Capabilities Register
+#define S_PCIE_PMC                                2
+#define B_PCIE_PMC_PMES                           (BIT15 | BIT14 | BIT13 | BIT12 | BIT11) ///< PME Support
+#define B_PCIE_PMC_PMEC                           BIT3 ///< PME Clock
+
+#define R_PCIE_PMCS_OFFST                         0x04 ///< Power Management Status/Control Register
+#define S_PCIE_PMCS                               4
+#define B_PCIE_PMCS_BPCE                          BIT23 ///< Bus Power/Clock Control Enable
+#define B_PCIE_PMCS_B23S                          BIT22 ///< B2/B3 Support
+#define B_PCIE_PMCS_PMES                          BIT15 ///< PME_Status
+#define B_PCIE_PMCS_PMEE                          BIT8 ///< PME Enable
+#define B_PCIE_PMCS_NSR                           BIT3 ///< No Soft Reset
+#define B_PCIE_PMCS_PS                            (BIT1 | BIT0) ///< Power State
+#define V_PCIE_PMCS_PS_D0                         0
+#define V_PCIE_PMCS_PS_D3H                        3
+
+//
+// PCIE Extension Capability Register
+//
+#define B_PCIE_EXCAP_NCO                          0xFFF00000 ///< Next Capability Offset
+#define N_PCIE_EXCAP_NCO                          20
+#define V_PCIE_EXCAP_NCO_LISTEND                  0
+#define B_PCIE_EXCAP_CV                           0x000F0000 ///< Capability Version
+#define N_PCIE_EXCAP_CV                           16
+#define B_PCIE_EXCAP_CID                          0x0000FFFF ///< Capability ID
+
+//
+// Advanced Error Reporting Capability (CAPID:0001h)
+//
+#define V_PCIE_EX_AEC_CID                         0x0001 ///< Capability ID
+#define R_PCIE_EX_UEM_OFFSET                      0x08 ///< Uncorrectable Error Mask Register
+#define B_PCIE_EX_UEM_CT                          BIT14 ///< Completion Timeout Mask
+#define B_PCIE_EX_UEM_UC                          BIT16 ///< Unexpected Completion
+
+//
+// ACS Extended Capability (CAPID:000Dh)
+//
+#define V_PCIE_EX_ACS_CID                         0x000D ///< Capability ID
+#define R_PCIE_EX_ACSCAPR_OFFSET                  0x04 ///< ACS Capability Register
+//#define R_PCIE_EX_ACSCTLR_OFFSET                  0x08 ///< ACS Control Register (NOTE: register size in PCIE spce is not match the PCH register size)
+
+
+//
+// Latency Tolerance Reporting Extended Capability Registers (CAPID:0018h)
+//
+#define R_PCH_PCIE_LTRECH_CID                     0x0018
+#define R_PCH_PCIE_LTRECH_MSLR_OFFSET             0x04
+#define N_PCH_PCIE_LTRECH_MSLR_VALUE              0
+#define N_PCH_PCIE_LTRECH_MSLR_SCALE              10
+#define R_PCH_PCIE_LTRECH_MNSLR_OFFSET            0x06
+#define N_PCH_PCIE_LTRECH_MNSLR_VALUE             0
+#define N_PCH_PCIE_LTRECH_MNSLR_SCALE             10
+//
+// Secondary PCI Express Extended Capability Header (CAPID:0019h)
+//
+#define V_PCIE_EX_SPE_CID                         0x0019 ///< Capability ID
+#define R_PCIE_EX_LCTL3_OFFSET                    0x04 ///< Link Control 3 Register
+#define B_PCIE_EX_LCTL3_PE                        BIT0 ///< Perform Equalization
+#define R_PCIE_EX_LES_OFFSET                      0x08 ///< Lane Error Status
+#define R_PCIE_EX_L01EC_OFFSET                    0x0C ///< Lane 0 and Lan 1 Equalization Control Register (Offset 0Ch)
+#define B_PCIE_EX_L01EC_UPL1TP                    0x0F000000 ///< Upstream Port Lane 1 Transmitter Preset
+#define N_PCIE_EX_L01EC_UPL1TP                    24
+#define B_PCIE_EX_L01EC_DPL1TP                    0x000F0000 ///< Downstream Port Lane 1 Transmitter Preset
+#define N_PCIE_EX_L01EC_DPL1TP                    16
+#define B_PCIE_EX_L01EC_UPL0TP                    0x00000F00 ///< Upstream Port Transmitter Preset
+#define N_PCIE_EX_L01EC_UPL0TP                    8
+#define B_PCIE_EX_L01EC_DPL0TP                    0x0000000F ///< Downstream Port Transmitter Preset
+#define N_PCIE_EX_L01EC_DPL0TP                    0
+
+#define R_PCIE_EX_L23EC_OFFSET                    0x10 ///< Lane 2 and Lane 3 Equalization Control Register (Offset 10h)
+#define B_PCIE_EX_L23EC_UPL3TP                    0x0F000000 ///< Upstream Port Lane 3 Transmitter Preset
+#define N_PCIE_EX_L23EC_UPL3TP                    24
+#define B_PCIE_EX_L23EC_DPL3TP                    0x000F0000 ///< Downstream Port Lane 3 Transmitter Preset
+#define N_PCIE_EX_L23EC_DPL3TP                    16
+#define B_PCIE_EX_L23EC_UPL2TP                    0x00000F00 ///< Upstream Port Lane 2 Transmitter Preset
+#define N_PCIE_EX_L23EC_UPL2TP                    8
+#define B_PCIE_EX_L23EC_DPL2TP                    0x0000000F ///< Downstream Port Lane 2 Transmitter Preset
+#define N_PCIE_EX_L23EC_DPL2TP                    0
+
+
+//
+// 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  V_PCIE_EX_L1SCAP_PTPOS_2us               0
+#define  V_PCIE_EX_L1SCAP_PTPOS_10us              1
+#define  V_PCIE_EX_L1SCAP_PTPOS_100us             2
+#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 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
+
+//
+// Base Address Offset
+//
+#define R_BASE_ADDRESS_OFFSET_0                   0x0010 ///< Base Address Register 0
+#define R_BASE_ADDRESS_OFFSET_1                   0x0014 ///< Base Address Register 1
+#define R_BASE_ADDRESS_OFFSET_2                   0x0018 ///< Base Address Register 2
+#define R_BASE_ADDRESS_OFFSET_3                   0x001C ///< Base Address Register 3
+#define R_BASE_ADDRESS_OFFSET_4                   0x0020 ///< Base Address Register 4
+#define R_BASE_ADDRESS_OFFSET_5                   0x0024 ///< Base Address Register 5
+#define B_PCI_BAR_MEMORY_TYPE_MASK                (BIT1 | BIT2)
+#define B_PCI_BAR_MEMORY_TYPE_64                  BIT2
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
new file mode 100644
index 0000000000..ac270e24fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
@@ -0,0 +1,29 @@
+/** @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) 2019 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 <PchAccess.h>
+#include <PchPolicyCommon.h>
+#include <PchPreMemPolicyCommon.h>
+#include <SaPolicyCommon.h>
+#include <CpuPolicyCommon.h>
+
+extern EFI_GUID gSiPreMemPolicyPpiGuid;
+extern EFI_GUID gSiPolicyPpiGuid;
+
+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/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
new file mode 100644
index 0000000000..fe676f8519
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
@@ -0,0 +1,26 @@
+/** @file
+  PCIe Initialization Library header file
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_INIT_LIB_H_
+#define _PCIE_INIT_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/GpioLib.h>
+#include <SaRegs.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
new file mode 100644
index 0000000000..f05cf0fdea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for USB initialization library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB_INIT_LIB_H_
+#define _USB_INIT_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Common entry point for PCH and CPU xDCI controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XdciPciMmBase       xDCI PCI config space address
+**/
+VOID
+XdciConfigure (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Common entry point for PCH and CPU xHCI controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciMmBase       xHCI PCI config space address
+**/
+VOID
+XhciConfigure (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Configure xHCI after initialization
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciMmBase       XHCI PCI CFG Base Address
+**/
+VOID
+XhciConfigureAfterInit (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Locks xHCI configuration by setting the proper lock bits in controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciBase         xHCI PCI config space address
+**/
+VOID
+XhciLockConfiguration (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciBase
+  );
+
+/**
+  Tune the USB 2.0 high-speed signals quality.
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+**/
+VOID
+Usb2AfeProgramming (
+  IN  USB_CONFIG      *UsbConfig
+  );
+#endif // _USB_INIT_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
new file mode 100644
index 0000000000..671e94b3bc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
@@ -0,0 +1,60 @@
+/** @file
+  Protocol used for specifying platform related Silicon information and policy setting.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_PROTOCOL_H_
+#define _SI_POLICY_PROTOCOL_H_
+
+#include <IndustryStandard/Hsti.h>
+
+//
+// DXE_SI_POLICY_PROTOCOL revisions
+//
+#define DXE_SI_POLICY_PROTOCOL_REVISION 2
+
+extern EFI_GUID gDxeSiPolicyProtocolGuid;
+
+#pragma pack (push,1)
+
+/**
+  The protocol allows the platform code to publish a set of configuration information that the
+  Silicon drivers will use to configure the processor in the DXE phase.
+  This Policy Protocol needs to be initialized for Silicon configuration.
+  @note The Protocol has to be published before processor DXE drivers are dispatched.
+**/
+typedef struct {
+  /**
+  This member specifies the revision of the Si Policy protocol. This field is used to indicate backward
+  compatible changes to the protocol. Any such changes to this protocol will result in an update in the revision number.
+
+  <b>Revision 1</b>:
+   - Initial version
+  <b>Revision 2</b>:
+   - Added SmbiosOemTypeFirmwareVersionInfo to determines the SMBIOS OEM type
+  **/
+  UINT8                          Revision;
+  /**
+    SmbiosOemTypeFirmwareVersionInfo 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.
+  **/
+  UINT8                          SmbiosOemTypeFirmwareVersionInfo;
+  UINT8                          ReservedByte[6];  ///< Reserved bytes, align to multiple 8.
+  /**
+    This member describes a pointer to Hsti results from previous boot. In order to mitigate the large performance cost
+    of performing all of the platform security tests on each boot, we can save the results across boots and retrieve
+    and point this policy to them prior to the launch of HstiSiliconDxe. Logic should be implemented to not populate this
+    upon major platform changes (i.e changes to setup option or platform hw)to ensure that results accurately reflect the
+    configuration of the platform.
+  **/
+  ADAPTER_INFO_PLATFORM_SECURITY *Hsti;    ///< This is a pointer to Hsti results from previous boot
+  UINTN                          HstiSize; ///< Size of results, if setting Hsti policy to point to previous results
+} DXE_SI_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
new file mode 100644
index 0000000000..58a185c8fd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
@@ -0,0 +1,55 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _REGS_USB_H_
+#define _REGS_USB_H_
+
+//
+// USB3 (XHCI) related definitions
+// @todo: Add CPU PCI defs for xHCI
+//
+#define PCI_BUS_NUMBER_PCH_XHCI             0
+#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
+#endif // _REGS_USB_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
new file mode 100644
index 0000000000..b5aeccbe5d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
@@ -0,0 +1,19 @@
+/** @file
+  Silicon Config HOB is used for gathering platform
+  related Intel silicon information and config setting.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
new file mode 100644
index 0000000000..da16aad257
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
@@ -0,0 +1,65 @@
+/** @file
+  Intel reference code configuration policies.
+
+  Copyright (c) 2019 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/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;
+/*
+  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;
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
new file mode 100644
index 0000000000..7e056a25af
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
@@ -0,0 +1,23 @@
+/** @file
+ Common configurations for CPU and PCH trace hub
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TRACE_HUB_COMMON_CONFIG_H_
+#define _TRACE_HUB_COMMON_CONFIG_H_
+
+///
+/// The TRACE_HUB_ENABLE_MODE describes the desired TraceHub mode of operation
+///
+typedef enum {
+  TraceHubModeDisabled       = 0,       ///< TraceHub Disabled
+  TraceHubModeTargetDebugger = 1,       ///< TraceHub Target Debugger mode, debug on target device itself, config to PCI mode
+  TraceHubModeHostDebugger   = 2,       ///< TraceHub Host Debugger mode, debugged by host with cable attached, config to ACPI mode
+  TraceHubModeMax
+} TRACE_HUB_ENABLE_MODE;
+
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add Include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
                   ` (35 subsequent siblings)
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds header files common to CPU modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h                |  45 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h | 106 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h    | 141 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h         |  54 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h  | 179 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h |  78 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h   | 149 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h            |  66 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h                            |  16 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h                        | 113 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h                        |  88 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h                      |  23 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h                         | 100 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h                              | 261 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h                |  90 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h               | 118 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h                 |  84 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h                     | 123 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h           |  50 ++++
 19 files changed, 1884 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
new file mode 100644
index 0000000000..47a98131d0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
@@ -0,0 +1,45 @@
+/** @file
+  CPU Config Block.
+
+  Copyright (c) 2019 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>:
+  - Deprecate and move SkipMpInit to CpuConfigLibPreMemConfig.
+  <b>Revision 3</b>:
+  - Move DebugInterfaceEnable from CPU_TEST_CONFIG.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    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;
+  UINT32 SkipMpInit               : 1;            ///< @deprecated since revision 2. For Fsp only, Silicon Initialization will skip MP Initialization (including BSP) if enabled. For non-FSP, this should always be 0.
+  UINT32 DebugInterfaceEnable     : 1;            ///< Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+  UINT32 RsvdBits                 : 28;           ///< Reserved for future use
+  EFI_PHYSICAL_ADDRESS MicrocodePatchAddress;     ///< Pointer to microcode patch that is suitable for this processor.
+} CPU_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
new file mode 100644
index 0000000000..ce965a7510
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
@@ -0,0 +1,106 @@
+/** @file
+  CPU Security PreMemory Config Block.
+
+  Copyright (c) 2019 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 5
+
+extern EFI_GUID gCpuConfigLibPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Config Library PreMemory Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Update for JTAG Power Gate comment.
+  <b>Revision 3</b>:
+  - Add PeciSxReset and PeciC10Reset
+  <b>Revision 4</b>:
+  - Add SkipMpInit
+  <b>Revision 5</b>:
+  - Add DpSscMarginEnable
+**/
+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.
+   - <b>1: Maximum non-turbo performance</b>.
+   - 2: Turbo performance.
+  @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;
+  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;
+  /**
+    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>0: Disable</b> for CNL, and <b>1: Enable</b> for all other CPU's
+    - 0: Disable
+    - 1: Enable
+  **/
+  UINT32 PeciC10Reset               : 1;
+  /**
+    For Fsp only, Silicon Initialization will skip MP Initialization
+    (including BSP) if enabled. For non-FSP, this should always be 0.
+    - <b>0: Disable</b>
+    - 1: Enable
+  **/
+  UINT32 SkipMpInit                 : 1;
+  /**
+    Enable DisplayPort SSC range reduction
+    @note This should only be used on systems that exceeds allowed SSC modulation range as defined in VESA's spec.
+    - <b>0: Disable</b>
+    - 1: Enable
+  **/
+  UINT32 DpSscMarginEnable          : 1;
+  UINT32 RsvdBits                   : 17;
+  /**
+    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;
+  UINT8  Reserved[3];                    ///< Reserved for alignment
+} CPU_CONFIG_LIB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
new file mode 100644
index 0000000000..a0b8a208e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
@@ -0,0 +1,141 @@
+/** @file
+  CPU Overclocking Config Block.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
+#define _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
+
+#define CPU_OVERCLOCKING_CONFIG_REVISION 4
+
+extern EFI_GUID gCpuOverclockingPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Overclocking Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>
+  - Deprecate RingMinOcRatio
+  <b>Revision 3</b>
+  - Change RingDownBin default to 'Enabled'
+  <b>Revision 4</b>
+  - Add TvbRatioClipping, TvbVoltageOptimization
+
+**/
+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.; <b>0: Disable</b>; 1: Enable (Lock).
+  /**
+  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 RsvdBits             :  10;              ///< 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-255. Max range varies by CPU sku.
+  **/
+  UINT8  CoreMaxOcRatio;
+  /**
+  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;
+  /**
+  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-255. Max range varies by CPU sku.
+  **/
+  UINT8  RingMaxOcRatio;
+  /**
+  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;
+  UINT8  RingMinOcRatio;                          ///< Deprecated since rev 2. Minimum ring ratio override. <b>0: Hardware defaults.</b> Range: 0-83.
+  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.
+  /**
+  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 RsvdBits1              :  6;
+  /**
+  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 0 to 63.
+  **/
+  UINT8  TjMaxOffset;
+} CPU_OVERCLOCKING_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_OVERCLOCKING_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
new file mode 100644
index 0000000000..e45f335ff9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
@@ -0,0 +1,54 @@
+/** @file
+  CPU PID Config Block.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
new file mode 100644
index 0000000000..2ad474b7e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
@@ -0,0 +1,179 @@
+/** @file
+  CPU Power Management Basic Config Block.
+
+  Copyright (c) 2019 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 2
+
+extern EFI_GUID gCpuPowerMgmtBasicConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Power Management Basic Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added MinRingRatioLimit
+  - Added MaxRingRatioLimit
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+  Sets the boot frequency starting from reset vector.
+   - 0: Maximum battery performance.
+   - <b>1: Maximum non-turbo performance</b>.
+   - 2: Turbo performance.
+  @note If Turbo is selected BIOS will start in max non-turbo mode and switch to Turbo mode.
+  **/
+  UINT32 BootFrequency                  : 2;
+  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; <b>0: Disabled</b>; 1: Enabled (Lock).
+  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 RsvdBits                       : 9;      ///< 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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>15</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.
+  0: Disable; <b>1: Enable;</b>
+  **/
+  UINT8  EnableItbm                     : 1;
+  /**
+  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;
+  UINT8  ReservedBits1                  : 6;      ///< 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.
+  Default: <b>0 - AUTO</b>, auto will program 28 seconds.
+  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;
+} CPU_POWER_MGMT_BASIC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_BASIC_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
new file mode 100644
index 0000000000..7eb91fa3ee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
@@ -0,0 +1,78 @@
+/** @file
+  CPU Power Managment Custom Config Block.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
new file mode 100644
index 0000000000..cb9b20249f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
@@ -0,0 +1,149 @@
+/** @file
+  CPU Power Management Test Config Block.
+
+  Copyright (c) 2019 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 3
+
+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,
+  PpmIrmPairFixedPriority,
+  PpmIrmPairRoundRobin,
+  PpmIrmPairHashVector,
+  PpmIrmNoChange
+} PPM_IRM_SETTING;
+
+/**
+  CPU Power Management Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Update PkgCStateDemotion and PkgCStateUnDemotion to be Disable.
+  <b>Revision 3</b>:
+  - Add  CstateLatencyControl0TimeUnit for CFL only
+  - Add  CstateLatencyControl0Irtl for CFL only
+**/
+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 AutoThermalReporting          : 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. [Cannonlake Y] 0: Disable; <b>1: Enable</b> [CoffeeLake] <b>Disable</b>; 1: Enable
+  UINT32 PkgCStateUnDemotion           : 1;        ///<              Enable or Disable Package Cstate UnDemotion.  0: [Cannonlake Y] 0: Disable; <b>1: Enable</b> [CoffeeLake] <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;        ///<              Configuration for boot TDP selection; <b>0: TDP Nominal</b>; 1: TDP Down; 2: TDP Up.
+  UINT16 CstateLatencyControl1Irtl;                ///< Offset 32-33 Interrupt Response Time Limit of LatencyContol1 MSR 0x60B[9:0].
+  UINT16 CstateLatencyControl2Irtl;                ///< Offset 34-35 Interrupt Response Time Limit of LatencyContol2 MSR 0x60C[9:0].
+  UINT16 CstateLatencyControl3Irtl;                ///< Offset 36-37 Interrupt Response Time Limit of LatencyContol3 MSR 0x633[9:0].
+  UINT16 CstateLatencyControl4Irtl;                ///< Offset 38-39 Interrupt Response Time Limit of LatencyContol4 MSR 0x634[9:0].
+  UINT16 CstateLatencyControl5Irtl;                ///< Offset 40-41 Interrupt Response Time Limit of LatencyContol5 MSR 0x635[9:0].
+  UINT16 CstateLatencyControl0Irtl;                ///< Offset 42-43 Interrupt Response Time Limit of LatencyContol1 MSR 0x60A[9:0].
+  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 CstateLatencyControl0TimeUnit; ///< Offset 45    TimeUnit for Latency Control0 MSR 0x60A[12:10]; (CFL)2: 1024ns
+  C_STATE_TIME_UNIT CstateLatencyControl1TimeUnit; ///< Offset 46    TimeUnit for Latency Control1 MSR 0x60B[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl2TimeUnit; ///< Offset 47    TimeUnit for Latency Control2 MSR 0x60C[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl3TimeUnit; ///< Offset 48    TimeUnit for Latency Control3 MSR 0x633[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl4TimeUnit; ///< Offset 49    TimeUnit for Latency Control4 MSR 0x634[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl5TimeUnit; ///< Offset 50    TimeUnit for Latency Control5 MSR 0x635[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  /**
+  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.
+   - 1: Round robin.
+   - 2: Hash vector.
+   - 4: PAIR with fixed priority.
+   - 5: PAIR with round robin.
+   - 6: PAIR with hash vector.
+   - 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
new file mode 100644
index 0000000000..b94eb5e263
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
@@ -0,0 +1,66 @@
+/** @file
+  CPU Test Config Block.
+
+  Copyright (c) 2019 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 4
+
+extern EFI_GUID gCpuTestConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Fixed RsvdBits incorrect value.
+  <b>Revision 3</b>:
+  - Added CpuWakeUpTimer
+  <b>Revision 4</b>:
+  - Deprecate and move DebugInterfaceEnable to CPU_CONFIG.
+**/
+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                DebugInterfaceEnable            : 1;     ///< @deprecated Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+  UINT32                DebugInterfaceLockEnable        : 1;     ///< Lock or Unlock debug interface features; 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.
+  /**
+    This policy should be used to enable or disable Voltage Optimization feature.
+    Recommended defaults:
+     Enable  - For Mobile SKUs(U/Y)
+     Disable - Rest of all SKUs other than Mobile.
+  **/
+  UINT32                VoltageOptimization             : 1;
+  UINT32                CpuWakeUpTimer                  : 1;      ///< Enable or Disable long CPU wake up timer. 0: Disabled (8s); <b>1: Enabled (180s)</b>.
+  UINT32                RsvdBits                        : 21;     ///< 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;
+} CPU_TEST_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_TEST_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
new file mode 100644
index 0000000000..48fdbdd012
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
@@ -0,0 +1,16 @@
+/** @file
+  Macros to simplify and abstract the interface to CPU configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPUACCESS_H_
+#define _CPUACCESS_H_
+
+#include "CpuRegs.h"
+#include "CpuDataStruct.h"
+#include "CpuPowerMgmt.h"
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
new file mode 100644
index 0000000000..2382e60dca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
@@ -0,0 +1,113 @@
+/** @file
+  This file declares various data structures used in CPU reference code.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_DATA_STRUCT_H
+#define _CPU_DATA_STRUCT_H
+
+//
+// The reason for changing the state of the processor Only applies to Disabling processors.
+// In future, we can add add/remove support
+//
+#define CPU_CAUSE_NOT_DISABLED      0x0000
+#define CPU_CAUSE_INTERNAL_ERROR    0x0001
+#define CPU_CAUSE_THERMAL_ERROR     0x0002
+#define CPU_CAUSE_SELFTEST_FAILURE  0x0004
+#define CPU_CAUSE_PREBOOT_TIMEOUT   0x0008
+#define CPU_CAUSE_FAILED_TO_START   0x0010
+#define CPU_CAUSE_CONFIG_ERROR      0x0020
+#define CPU_CAUSE_USER_SELECTION    0x0080
+#define CPU_CAUSE_BY_ASSOCIATION    0x0100
+#define CPU_CAUSE_UNSPECIFIED       0x8000
+
+typedef UINT32 CPU_STATE_CHANGE_CAUSE;
+
+///
+/// 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;
+
+///
+/// Structure to describe microcode header
+///
+typedef struct {
+  UINT32 HeaderVersion;  ///< Version number of the update header.
+  UINT32 UpdateRevision; ///< Unique version number for the update.
+  UINT32 Date;           ///< Date of the update creation.
+  UINT32 ProcessorId;    ///< Signature of the processor that requires this update.
+  UINT32 Checksum;       ///< Checksum of update data and header.
+  UINT32 LoaderRevision; ///< Version number of the microcode loader program.
+  UINT32 ProcessorFlags; ///< Lower 4 bits denoting platform type information.
+  UINT32 DataSize;       ///< Size of encoded data in bytes.
+  UINT32 TotalSize;      ///< Total size of microcode update in bytes.
+  UINT8  Reserved[12];   ///< Reserved bits.
+} CPU_MICROCODE_HEADER;
+
+///
+/// Structure to describe the extended signature table header of the microcode update
+///
+typedef struct {
+  UINT32 ExtendedSignatureCount; ///< Number of extended signature structures.
+  UINT32 ExtendedTableChecksum;  ///< Checksum of update extended processor signature table.
+  UINT8  Reserved[12];           ///< Reserved bits.
+} CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+///
+/// Structure to describe the data of the extended table of the microcode update
+///
+typedef struct {
+  UINT32 ProcessorSignature; ///< Extended signature of the processor that requires this update
+  UINT32 ProcessorFlag;      ///< Lower 4 bits denoting platform type information
+  UINT32 ProcessorChecksum;  ///< checksum of each of the extended update
+} CPU_MICROCODE_EXTENDED_TABLE;
+
+#pragma pack(1)
+///
+/// MSR_REGISTER definition as a Union of QWORDS, DWORDS and BYTES
+///
+typedef union _MSR_REGISTER {
+  UINT64  Qword;       ///< MSR value in 64 bit QWORD.
+
+  ///
+  /// MSR value represented in two DWORDS
+  ///
+  struct {
+    UINT32  Low;       ///< Lower DWORD of the 64 bit MSR value.
+    UINT32  High;      ///< Higher DWORD of the 64 bit MSR value.
+  } Dwords;
+
+  ///
+  /// MSR value represented in eight bytes.
+  ///
+  struct {
+    UINT8 FirstByte;   ///< First byte of the 64 bit MSR value.
+    UINT8 SecondByte;  ///< Second byte of the 64 bit MSR value.
+    UINT8 ThirdByte;   ///< Third byte of the 64 bit MSR value.
+    UINT8 FouthByte;   ///< Fourth byte of the 64 bit MSR value.
+    UINT8 FifthByte;   ///< Fifth byte of the 64 bit MSR value.
+    UINT8 SixthByte;   ///< Sixth byte of the 64 bit MSR value.
+    UINT8 SeventhByte; ///< Seventh byte of the 64 bit MSR value.
+    UINT8 EighthByte;  ///< Eigth byte of the 64 bit MSR value.
+  } Bytes;
+} MSR_REGISTER;
+
+///
+/// Store BIST data for BSP.
+///
+typedef struct {
+  UINT32 ApicId;    ///< APIC ID
+  UINT32 Health;    ///< BIST result
+} BIST_HOB_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
new file mode 100644
index 0000000000..4862d62975
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
@@ -0,0 +1,88 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define CPU NVS Area operation region.
+  //
+
+#ifndef _CPU_NVS_AREA_DEF_H_
+#define _CPU_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT8    Revision;                                ///< Offset 0       CPU GlobalNvs Revision
+  UINT32   PpmFlags;                                ///< Offset 1       PPM Flags Values
+  UINT8    Reserved0[1];                            ///< Offset 5:5
+  UINT8    AutoCriticalTripPoint;                   ///< Offset 6       Auto Critical Trip Point
+  UINT8    AutoPassiveTripPoint;                    ///< Offset 7       Auto Passive Trip Point
+  UINT8    AutoActiveTripPoint;                     ///< Offset 8       Auto Active Trip Point
+  UINT32   Cpuid;                                   ///< Offset 9       CPUID
+  UINT8    ConfigurablePpc;                         ///< Offset 13      Boot Mode vlues for _PPC
+  UINT8    CtdpLevelsSupported;                     ///< Offset 14      ConfigTdp Number Of Levels
+  UINT8    ConfigTdpBootModeIndex;                  ///< Offset 15      CTDP Boot Mode Index
+  UINT16   CtdpPowerLimit1[3];                      ///< Offset 16      CTDP Level 0 Power Limit1
+                                                    ///< Offset 18      CTDP Level 1 Power Limit1
+                                                    ///< Offset 20      CTDP Level 2 Power Limit1
+  UINT16   CtdpPowerLimit2[3];                      ///< Offset 22      CTDP Level 0 Power Limit2
+                                                    ///< Offset 24      CTDP Level 1 Power Limit2
+                                                    ///< Offset 26      CTDP Level 2 Power Limit2
+  UINT8    CtdpPowerLimitWindow[3];                 ///< Offset 28      CTDP Level 0 Power Limit1 Time Window
+                                                    ///< Offset 29      CTDP Level 1 Power Limit1 Time Window
+                                                    ///< Offset 30      CTDP Level 2 Power Limit1 Time Window
+  UINT8    CtdpCtc[3];                              ///< Offset 31      CTDP Level 0 CTC
+                                                    ///< Offset 32      CTDP Level 1 CTC
+                                                    ///< Offset 33      CTDP Level 2 CTC
+  UINT8    CtdpTar[3];                              ///< Offset 34      CTDP Level 0 TAR
+                                                    ///< Offset 35      CTDP Level 1 TAR
+                                                    ///< Offset 36      CTDP Level 2 TAR
+  UINT8    CtdpPpc[3];                              ///< Offset 37      CTDP Level 0 PPC
+                                                    ///< Offset 38      CTDP Level 1 PPC
+                                                    ///< Offset 39      CTDP Level 2 PPC
+  UINT8    Reserved1[1];                            ///< Offset 40:40
+  UINT8    C6MwaitValue;                            ///< Offset 41      Mwait Hint value for C6
+  UINT8    C7MwaitValue;                            ///< Offset 42      Mwait Hint value for C7/C7s
+  UINT8    CDMwaitValue;                            ///< Offset 43      Mwait Hint value for C7/C8/C9/C10
+  UINT8    Reserved2[2];                            ///< Offset 44:45
+  UINT16   C6Latency;                               ///< Offset 46      Latency Value for C6
+  UINT16   C7Latency;                               ///< Offset 48      Latency Value for C7/C7S
+  UINT16   CDLatency;                               ///< Offset 50      Latency Value for C8/C9/C10
+  UINT16   CDIOLevel;                               ///< Offset 52      IO LVL value for C8/C9/C10
+  UINT16   CDPowerValue;                            ///< Offset 54      Power value for C8/C9/C10
+  UINT8    MiscPowerManagementFlags;                ///< Offset 56      MiscPowerManagementFlags
+  UINT8    EnableDigitalThermalSensor;              ///< Offset 57      Digital Thermal Sensor Enable
+  UINT8    BspDigitalThermalSensorTemperature;      ///< Offset 58      Digital Thermal Sensor 1 Readingn for BSP
+  UINT8    ApDigitalThermalSensorTemperature;       ///< Offset 59      Digital Thermal Sensor 2 Reading for AP1
+  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 60      DTS SMI Function Call via DTS IO Trap
+  UINT8    PackageDTSTemperature;                   ///< Offset 61      Package Temperature
+  UINT8    IsPackageTempMSRAvailable;               ///< Offset 62      Package Temperature MSR available
+  UINT8    Ap2DigitalThermalSensorTemperature;      ///< Offset 63      Digital Thermal Sensor 3 Reading for AP2
+  UINT8    Ap3DigitalThermalSensorTemperature;      ///< Offset 64      Digital Thermal Sensor 4 Reading for AP3
+  UINT64   BiosGuardMemAddress;                     ///< Offset 65      BIOS Guard Memory Address for Tool Interface
+  UINT8    BiosGuardMemSize;                        ///< Offset 73      BIOS Guard Memory Size for Tool Interface
+  UINT16   BiosGuardIoTrapAddress;                  ///< Offset 74      BIOS Guard IoTrap Address for Tool Interface
+  UINT16   BiosGuardIoTrapLength;                   ///< Offset 76      BIOS Guard IoTrap Length for Tool Interface
+  UINT16   DtsIoTrapAddress;                        ///< Offset 78      DTS IO trap Address
+  UINT8    DtsIoTrapLength;                         ///< Offset 80      DTS IO trap Length
+  UINT8    DtsAcpiEnable;                           ///< Offset 81      DTS is in ACPI Mode Enabled
+  UINT8    SgxStatus;                               ///< Offset 82      SGX Status
+  UINT64   EpcBaseAddress;                          ///< Offset 83      EPC Base Address
+  UINT64   EpcLength;                               ///< Offset 91      EPC Length
+  UINT8    HwpVersion;                              ///< Offset 99      HWP Version
+  UINT8    HwpInterruptStatus;                      ///< Offset 100     HWP Interrupt Status
+  UINT8    DtsInterruptStatus;                      ///< Offset 101     DTS Interrupt Status
+  UINT8    HwpSmi;                                  ///< Offset 102     SMI to setup HWP LVT tables
+  UINT8    LowestMaxPerf;                           ///< Offset 103     Max ratio of the slowest core.
+  UINT8    EnableItbm;                              ///< Offset 104     Enable/Disable Intel Turbo Boost Max Technology 3.0.
+  UINT8    EnableItbmDriver;                        ///< Offset 105     Enable/Disable Intel Turbo Boost Max Technology 3.0 Driver.
+  UINT8    ItbmInterruptStatus;                     ///< Offset 106     Intel Turbo Boost Max Technology 3.0 interrupt status.
+  UINT8    ItbmSmi;                                 ///< Offset 107     SMI to resume periodic SMM for Intel Turbo Boost Max Technology 3.0.
+  UINT8    OcBins;                                  ///< Offset 108     Indicates bins of Oc support. MSR 194h FLEX_RATIO Bits (19:17)
+  UINT8    C3MwaitValue;                            ///< Offset 109     Mwait Hint value for C3 (CFL only)
+  UINT16   C3Latency;                               ///< Offset 110     Latency Value for C3 (CFL only)
+} CPU_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
new file mode 100644
index 0000000000..a9abd426f9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
@@ -0,0 +1,23 @@
+/** @file
+  CPU Policy structure definition which will contain several config blocks during runtime.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_COMMON_H_
+#define _CPU_POLICY_COMMON_H_
+
+#include "CpuPowerMgmt.h"
+#include <ConfigBlock.h>
+#include <ConfigBlock/CpuOverclockingConfig.h>
+#include <ConfigBlock/CpuConfig.h>
+#include <ConfigBlock/CpuPidTestConfig.h>
+#include <ConfigBlock/CpuPowerMgmtBasicConfig.h>
+#include <ConfigBlock/CpuPowerMgmtCustomConfig.h>
+#include <ConfigBlock/CpuPowerMgmtTestConfig.h>
+#include <ConfigBlock/CpuTestConfig.h>
+#include <ConfigBlock/CpuConfigLibPreMemConfig.h>
+
+#endif // _CPU_POLICY_COMMON_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
new file mode 100644
index 0000000000..af1f70b34f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
@@ -0,0 +1,100 @@
+/** @file
+  This file contains define definitions specific to processor
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POWER_MGMT_DEFINITIONS_H_
+#define _POWER_MGMT_DEFINITIONS_H_
+
+#define CSTATE_SUPPORTED          0x1
+#define ENHANCED_CSTATE_SUPPORTED 0x2
+#define C6_C7_SHORT_LATENCY_SUPPORTED 0x01
+#define C6_C7_LONG_LATENCY_SUPPORTED  0x02
+#define C7s_SHORT_LATENCY_SUPPORTED   0x03
+#define C7s_LONG_LATENCY_SUPPORTED    0x04
+//
+// Voltage offset definitions
+//
+#define OC_LIB_OFFSET_ADAPTIVE  0
+#define OC_LIB_OFFSET_OVERRIDE  1
+//
+// Platform Power Management Flags Bit Definitions:
+//   These defines are also used in CPU0CST.ASL to check platform configuration
+//   and build C-state table accordingly.
+//
+#define PPM_EIST                BIT0   ///< Enhanced Intel Speed Step Technology.
+#define PPM_C1                  BIT1   ///< C1 enabled, supported.
+#define PPM_C1E                 BIT2   ///< C1E enabled.
+#define PPM_C3                  BIT3   ///< C3 enabled, supported.
+#define PPM_C6                  BIT4   ///< C6 enabled, supported.
+#define PPM_C7                  BIT5   ///< C7 enabled, supported.
+#define PPM_C7S                 BIT6   ///< C7S enabled, supported
+#define PPM_TM                  BIT7   ///< Adaptive Thermal Monitor.
+#define PPM_TURBO               BIT8   ///< Long duration turbo mode
+#define PPM_CMP                 BIT9   ///< CMP.
+#define PPM_TSTATES             BIT10  ///< CPU throttling states
+#define PPM_MWAIT_EXT           BIT11  ///< MONITIOR/MWAIT Extensions supported.
+#define PPM_EEPST               BIT12  ///< Energy efficient P-State Feature enabled
+#define PPM_TSTATE_FINE_GRAINED BIT13  ///< Fine grained CPU Throttling states
+#define PPM_CD                  BIT14  ///< Deep Cstate - C8/C9/C10
+#define PPM_TIMED_MWAIT         BIT15  ///< Timed Mwait support
+#define C6_LONG_LATENCY_ENABLE  BIT16  ///< 1=C6 Long and Short,0=C6 Short only
+#define C7_LONG_LATENCY_ENABLE  BIT17  ///< 1=C7 Long and Short,0=C7 Short only
+#define C7s_LONG_LATENCY_ENABLE BIT18  ///< 1=C7s Long and Short,0=C7s Short only
+#define PPM_C8                  BIT19  ///< 1= C8 enabled/supported
+#define PPM_C9                  BIT20  ///< 1= C9 enabled/supported
+#define PPM_C10                 BIT21  ///< 1= C10 enabled/supported
+#define PPM_HWP                 BIT22  ///< 1= HWP enabled/supported
+#define PPM_HWP_LVT             BIT23  ///< 1= HWP LVT enabled/supported
+#define PPM_OC_UNLOCKED         BIT24  ///< 1= Overclocking fully unlocked
+
+#define PPM_C_STATES            0x7A    ///< PPM_C1 + PPM_C3 + PPM_C6 + PPM_C7 + PPM_C7S
+#define C3_LATENCY              0x4E
+#define C6_C7_SHORT_LATENCY     0x76
+#define C6_C7_LONG_LATENCY      0x94
+#define C8_LATENCY              0xFA
+#define C9_LATENCY              0x14C
+#define C10_LATENCY             0x3F2
+
+//
+// The following definitions are based on assumed location for the  ACPI
+// Base Address.  Modify as necessary base on platform-specific requirements.
+//
+#define PCH_ACPI_PBLK 0x1810
+#define PCH_ACPI_LV2  0x1814
+#define PCH_ACPI_LV3  0x1815
+#define PCH_ACPI_LV4  0x1816
+#define PCH_ACPI_LV6  0x1818
+#define PCH_ACPI_LV5  0x1817
+#define PCH_ACPI_LV7  0x1819
+
+//
+// C-State Latency (us) and Power (mW) for C1
+//
+#define C1_LATENCY                        1
+#define C1_POWER                          0x3E8
+#define C3_POWER                          0x1F4
+#define C6_POWER                          0x15E
+#define C7_POWER                          0xC8
+#define C8_POWER                          0xC8
+#define C9_POWER                          0xC8
+#define C10_POWER                         0xC8
+
+
+#define PID_DOMAIN_KP                     0
+#define PID_DOMAIN_KI                     1
+#define PID_DOMAIN_KD                     2
+#define MAILBOX_PARAM_1_OFFSET            8
+
+///
+///  VR Domain Definitions
+///
+#define CPU_VR_DOMAIN_SA           0x0
+#define CPU_VR_DOMAIN_IA           0x1
+#define CPU_VR_DOMAIN_RING         0x2
+#define CPU_VR_DOMAIN_GT           0x3
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
new file mode 100644
index 0000000000..68f2c019e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
@@ -0,0 +1,261 @@
+/** @file
+  Register names for CPU registers
+
+  <b>Conventions</b>
+  - Definitions beginning with "MSR_" are MSRs
+  - 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_REGS_H_
+#define _CPU_REGS_H_
+
+#define MSR_CORE_THREAD_COUNT                                         0x00000035
+#define B_THREAD_COUNT_MASK                                           0xFFFF
+#define MSR_SPCL_CHIPSET_USAGE_ADDR                                   0x000001FE
+///
+/// Arch-specific MSR defines in SDM
+/// @{
+
+#define MSR_PLATFORM_INFO                                             0x000000CE
+#define N_PLATFORM_INFO_MIN_RATIO                                     40
+#define B_PLATFORM_INFO_RATIO_MASK                                    0xFF
+#define N_PLATFORM_INFO_MAX_RATIO                                     8
+#define B_MSR_PLATFORM_INFO_BIOSGUARD_AVAIL                           BIT35
+#define N_MSR_PLATFORM_INFO_CONFIG_TDP_NUM_LEVELS_OFFSET              33
+#define V_CONFIG_TDP_NUM_LEVELS_MASK                                  (BIT34 | BIT33)
+#define B_PLATFORM_INFO_TDC_TDP_LIMIT                                 BIT29
+#define N_PLATFORM_INFO_RATIO_LIMIT                                   28
+#define B_PLATFORM_INFO_RATIO_LIMIT                                   BIT28
+#define B_PLATFORM_INFO_SAMPLE_PART                                   BIT27
+#define B_PLATFORM_INFO_SMM_SAVE_CONTROL                              BIT16
+#define N_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET                    30
+#define B_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET                    BIT30
+#define B_PLATFORM_INFO_TIMED_MWAIT_SUPPORTED                         BIT37
+#define B_PLATFORM_INFO_EDRAM_EN                                      BIT57
+
+//
+// MSR_BROADWELL_PKG_CST_CONFIG_CONTROL: related defines
+//
+#define B_TIMED_MWAIT_ENABLE                                          BIT31 ///< @todo Remove when bitfield definition is available.
+#define V_CSTATE_LIMIT_C1                                             0x01
+#define V_CSTATE_LIMIT_C3                                             0x02
+#define V_CSTATE_LIMIT_C6                                             0x03
+#define V_CSTATE_LIMIT_C7                                             0x04
+#define V_CSTATE_LIMIT_C7S                                            0x05
+#define V_CSTATE_LIMIT_C8                                             0x06
+#define V_CSTATE_LIMIT_C9                                             0x07
+#define V_CSTATE_LIMIT_C10                                            0x08
+
+#define MSR_PMG_IO_CAPTURE_BASE                                       0x000000E4
+#define B_MSR_PMG_CST_RANGE                                           (BIT18 | BIT17 | BIT16)
+#define V_IO_CAPT_LVL2                                                (0x0 << 16)   ///< C3
+#define V_IO_CAPT_LVL3                                                (0x1 << 16)   ///< C6
+#define V_IO_CAPT_LVL4                                                (0x2 << 16)   ///< C7
+#define V_IO_CAPT_LVL5                                                (0x3 << 16)   ///< C8
+#define V_IO_CAPT_LVL6                                                (0x4 << 16)   ///< C9
+#define V_IO_CAPT_LVL7                                                (0x5 << 16)   ///< C10
+#define V_IO_CAPT_LVL2_BASE_ADDR_MASK                                 0xFFFF
+
+#define MSR_TEMPERATURE_TARGET                                        0x000001A2
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LOCK                      BIT31
+#define N_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LIMIT                     24
+#define V_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_OFFSET_MASK           0x3F
+#define N_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_OFFSET    (16)
+#define B_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_MASK      (0xFF << 16)
+#define N_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET               8
+#define B_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET               (0xFF << 8)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_TIME_WINDOW               (0x7F)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_MASK                      0xFF
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_CLAMP_BIT                 BIT7
+
+
+#define MSR_TURBO_RATIO_LIMIT                                         0x000001AD
+#define N_MSR_TURBO_RATIO_LIMIT_1C                                    0
+#define B_MSR_TURBO_RATIO_LIMIT_1C                                    (0xFF << 0)
+#define N_MSR_TURBO_RATIO_LIMIT_2C                                    8
+#define B_MSR_TURBO_RATIO_LIMIT_2C                                    (0xFF << 8)
+#define N_MSR_TURBO_RATIO_LIMIT_3C                                    16
+#define B_MSR_TURBO_RATIO_LIMIT_3C                                    (0xFF << 16)
+#define N_MSR_TURBO_RATIO_LIMIT_4C                                    24
+#define B_MSR_TURBO_RATIO_LIMIT_4C                                    (0xFF << 24)
+#define N_MSR_TURBO_RATIO_LIMIT_5C                                    32
+#define B_MSR_TURBO_RATIO_LIMIT_5C                                    (0xFF << 32)
+#define N_MSR_TURBO_RATIO_LIMIT_6C                                    40
+#define B_MSR_TURBO_RATIO_LIMIT_6C                                    (0xFF << 40)
+#define N_MSR_TURBO_RATIO_LIMIT_7C                                    48
+#define B_MSR_TURBO_RATIO_LIMIT_7C                                    (0xFF << 48)
+#define N_MSR_TURBO_RATIO_LIMIT_8C                                    56
+#define B_MSR_TURBO_RATIO_LIMIT_8C                                    (0xFF << 56)
+
+#define MSR_IA32_FEATURE_CONFIG                                       0x0000013C
+#define B_IA32_FEATURE_CONFIG_AES_DIS                                 BIT1
+#define B_IA32_FEATURE_CONFIG_LOCK                                    BIT0
+
+//
+// MSRs for SMM State Save Register
+//
+#define MSR_SMM_MCA_CAP                                               0x0000017D
+#define B_TARGETED_SMI                                                BIT56
+#define N_TARGETED_SMI                                                56
+#define B_SMM_CPU_SVRSTR                                              BIT57
+#define N_SMM_CPU_SVRSTR                                              57
+#define B_SMM_CODE_ACCESS_CHK                                         BIT58
+#define N_SMM_CODE_ACCESS_CHK                                         58
+#define B_LONG_FLOW_INDICATION                                        BIT59
+#define N_LONG_FLOW_INDICATION                                        59
+#define MSR_SMM_FEATURE_CONTROL                                       0x000004E0
+#define B_SMM_FEATURE_CONTROL_LOCK                                    BIT0
+#define B_SMM_CPU_SAVE_EN                                             BIT1
+#define B_SMM_CODE_CHK_EN                                             BIT2
+
+/// @}
+
+
+///
+/// Bit defines for MSRs defined in UefiCpuPkg/Include/Register/ArchitecturalMsr.h.
+/// @{
+
+//
+// Number of fixed MTRRs
+//
+#define V_FIXED_MTRR_NUMBER                                           11
+
+//
+// Number of variable MTRRs
+//
+#define V_MAXIMUM_VARIABLE_MTRR_NUMBER                                10
+
+//
+// Bit defines for MSR_IA32_MTRR_DEF_TYPE
+//
+#define B_CACHE_MTRR_VALID                                            BIT11
+#define B_CACHE_FIXED_MTRR_VALID                                      BIT10
+
+//
+// Bit defines for MSR_IA32_DEBUG_INTERFACE
+//
+#define B_DEBUG_INTERFACE_ENABLE                                      BIT0
+#define B_DEBUG_INTERFACE_LOCK                                        BIT30
+#define B_DEBUG_INTERFACE_DEBUG_STATUS                                BIT31
+
+/// @}
+
+///
+/// Other defines
+///
+#ifndef TRIGGER_MODE_EDGE
+#define TRIGGER_MODE_EDGE             0x00
+#endif
+#ifndef TRIGGER_MODE_LEVEL
+#define TRIGGER_MODE_LEVEL            0x01
+#endif
+
+#ifndef CPU_FEATURE_DISABLE
+#define CPU_FEATURE_DISABLE  0
+#endif
+#ifndef CPU_FEATURE_ENABLE
+#define CPU_FEATURE_ENABLE   1
+#endif
+
+#define CACHE_UNCACHEABLE               0
+#define CACHE_WRITECOMBINING            1
+#define CACHE_WRITETHROUGH              4
+#define CACHE_WRITEPROTECTED            5
+#define CACHE_WRITEBACK                 6
+
+
+//
+// Processor Definitions
+//
+#define CPUID_FULL_STEPPING                      0x0000000F
+#define CPUID_FULL_FAMILY_MODEL                  0x0FFF0FF0
+#define CPUID_FULL_FAMILY_MODEL_STEPPING         0x0FFF0FFF
+#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX 0x000806E0
+#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO 0x000906E0
+#define CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO 0x00060670
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND 1000
+#endif
+
+#define BITS(x) (1 << (x))
+
+/**
+Notes :
+  1.  Bit position always starts at 0.
+  2.  Following macros are applicable only for Word aligned integers.
+**/
+#define BIT(Pos, Value)               (1 << (Pos) & (Value))
+#define BITRANGE(From, Width, Value)  (((Value) >> (From)) & ((1 << (Width)) - 1))
+
+///
+/// Enums for CPU Family IDs
+///
+typedef enum {
+  EnumCpuCflUltUlx    = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
+  EnumCpuCflDtHalo    = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO,
+  EnumCpuCnlDtHalo    = CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO,
+  EnumCpuMax          = CPUID_FULL_FAMILY_MODEL
+} CPU_FAMILY;
+
+///
+/// Enums for CPU Stepping IDs
+///
+typedef enum {
+  ///
+  /// Coffeelake ULX/ULT Steppings
+  ///
+  EnumKblH0         = 9,
+  EnumCflD0         = 0xA,
+
+  /// Whiskey Lake ULT Steppings
+  EnumCflW0         = 0xB,
+  EnumCflV0         = 0xC,
+
+  EnumCflMaxUltUlxStep = EnumCflV0,
+
+  ///
+  /// Coffeelake DT/Halo Steppings
+  ///
+  EnumCflU0         = 0xA,
+  EnumCflB0         = 0xB,
+  EnumCflP0         = 0xC,
+  EnumCflR0         = 0xD,
+  EnumCflMaxDtHaloStep = EnumCflR0,
+
+  ///
+  /// Max Stepping
+  ///
+  EnumCpuSteppingMax  = CPUID_FULL_STEPPING
+} CPU_STEPPING;
+
+///
+/// Enums for CPU SKU IDs
+///
+typedef enum {
+  EnumCpuUlt        = 0,
+  EnumCpuTrad,
+  EnumCpuUlx,
+  EnumCpuHalo,
+  EnumCpuUnknown
+} CPU_SKU;
+
+///
+/// Enums for CPU Generation
+///
+typedef enum {
+  EnumCflCpu  = 0,
+  EnumCpuUnknownGeneration = 255
+} CPU_GENERATION;
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
new file mode 100644
index 0000000000..79dff36783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
@@ -0,0 +1,90 @@
+/** @file
+  Header file for Cpu Mailbox Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_MAILBOX_LIB_H_
+#define _CPU_MAILBOX_LIB_H_
+
+//
+//  Mailbox Related Definitions
+//
+
+/**
+  Generic Mailbox function for mailbox write commands. This function will
+  poll the mailbox interface for control, issue the write request, poll
+  for completion, and verify the write was succussful.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[in]  MailboxData     Overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status values are:
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  IN UINT32  MailboxData,
+  OUT UINT32 *MailboxStatus
+  );
+
+/**
+  Generic Mailbox function for mailbox read commands. This function will write
+  the read request from MailboxType, and populate the read results in the MailboxDataPtr.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status are
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  OUT UINT32 *MailboxDataPtr,
+  OUT UINT32 *MailboxStatus
+  );
+
+/**
+  Poll the run/busy bit of the mailbox until available or timeout expires.
+
+  @param[in]  MailboxType
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_TIMEOUT           Command timeout.
+**/
+EFI_STATUS
+EFIAPI
+PollMailboxReady (
+  IN UINT32 MailboxType
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
new file mode 100644
index 0000000000..a2dc83efb5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
@@ -0,0 +1,118 @@
+/** @file
+  Header file for CpuPlatform Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PLATFORM_LIB_H_
+#define _CPU_PLATFORM_LIB_H_
+
+#include <CpuRegs.h>
+#include <CpuDataStruct.h>
+#include <CpuPowerMgmt.h>
+
+/**
+  Check CPU Type of the platform
+
+  @retval CPU_FAMILY              CPU type
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+  VOID
+  );
+
+/**
+  Return Cpu stepping type
+
+  @retval CPU_STEPPING                   Cpu stepping type
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+  VOID
+  );
+
+/**
+  Return CPU Sku
+
+  @retval UINT8              CPU Sku
+**/
+UINT8
+EFIAPI
+GetCpuSku (
+  VOID
+  );
+
+/**
+  Returns the processor microcode revision of the processor installed in the system.
+
+  @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+  VOID
+  );
+
+/**
+  Check if this microcode is correct one for processor
+
+  @param[in] Cpuid               - processor CPUID
+  @param[in] MicrocodeEntryPoint - entry point of microcode
+  @param[in] Revision            - revision of microcode
+
+  @retval CorrectMicrocode if this microcode is correct
+**/
+BOOLEAN
+CheckMicrocode (
+  IN UINT32               Cpuid,
+  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+  IN UINT32               *Revision
+  );
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval True if SGX supported or FALSE if not
+**/
+BOOLEAN
+IsSgxSupported (
+  VOID
+  );
+
+/**
+  Get processor generation
+
+  @retval CPU_GENERATION  Returns the executing thread's processor generation.
+**/
+CPU_GENERATION
+GetCpuGeneration (
+  VOID
+  );
+
+/**
+  Check if Disable CPU Debug (DCD) bit is set from FIT CPU Debugging [Disabled].
+  If it is set, CPU probe mode is disabled.
+
+  @retval TRUE    DCD is set
+  @retval FALSE   DCD is clear
+**/
+BOOLEAN
+IsCpuDebugDisabled (
+  VOID
+  );
+
+/**
+  Is Whiskey Lake CPU.
+
+  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
+  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
+**/
+BOOLEAN
+IsWhlCpu (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
new file mode 100644
index 0000000000..88f4353e91
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
@@ -0,0 +1,84 @@
+/** @file
+  Prototype of the CpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_LIB_H_
+#define _CPU_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole CPU related config blocks of SI_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi             The Si PreMem Policy PPI instance
+**/
+VOID
+CpuPreMemPrintPolicy (
+IN  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+);
+
+/**
+  Get CPU PREMEM config block table total size.
+
+  @retval Size of CPU PREMEM config block table
+**/
+UINT16
+EFIAPI
+CpuGetPreMemConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  Print whole CPU config blocks of SiPolicyPpi and serial out.
+
+  @param[in] SiPolicyPpi             The SI Policy PPI instance
+**/
+VOID
+CpuPrintPolicy (
+  IN  SI_POLICY_PPI                 *SiPolicyPpi
+  );
+
+/**
+  Get CPU config block table total size.
+
+  @retval Size of CPU config block table
+**/
+UINT16
+EFIAPI
+CpuGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  CpuAddConfigBlocks add all Cpu config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_CPU_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
new file mode 100644
index 0000000000..67f88ce987
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
@@ -0,0 +1,123 @@
+/** @file
+  Protocol used to report CPU information
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_INFO_H_
+#define _CPU_INFO_H_
+
+#include <CpuDataStruct.h>
+
+typedef struct _CPU_INFO_PROTOCOL CPU_INFO_PROTOCOL;
+
+
+extern EFI_GUID gCpuInfoProtocolGuid;
+
+//
+// DXE_CPU_INFO_PROTOCOL revisions
+//
+#define CPU_INFO_PROTOCOL_REVISION 1
+
+//
+// Processor feature definitions.
+//
+#define TXT_SUPPORT        BIT0
+#define VMX_SUPPORT        BIT1
+#define XD_SUPPORT         BIT2
+#define DCA_SUPPORT        BIT3
+#define X2APIC_SUPPORT     BIT4
+#define AES_SUPPORT        BIT5
+#define HT_SUPPORT         BIT6
+#define DEBUG_SUPPORT      BIT7
+#define DEBUG_LOCK_SUPPORT BIT8
+#define PROC_TRACE_SUPPORT BIT9
+#define HDC_SUPPORT        BIT10
+
+
+#pragma pack(1)
+///
+/// Cache descriptor information
+///
+typedef struct {
+  UINT8   Desc;                                    ///< Cache Descriptor
+  UINT8   Level;                                   ///< Cache Level
+  UINT8   Type;                                    ///< Cache Type. 0: Data, 1: Instruction, 3: Unified
+  UINT32  Size;                                    ///< Cache Size.
+  UINT16  Associativity;                           ///< Cache Ways of Associativity.
+} CACHE_DESCRIPTOR_INFO;
+
+///
+/// Processor information
+///
+typedef struct {
+  UINT32                CpuSignature;               ///< Processor signature and version information.
+  UINT64                Features;                   ///< Features availability in the CPU based on reading ECX after doing Asmcpuid(EAX=1).
+  CHAR8                 *BrandString;               ///< Processor Brand String.
+  UINT8                 NumSupportedCores;          ///< Total Number of Supported Cores in CPU Package. If Dual core, 2 cores.
+  UINT8                 NumSupportedThreadsPerCore; ///< Number of Supported Threads per Core.
+  UINT8                 NumCores;                   ///< Number of Enabled or Active Cores.
+  UINT8                 NumHts;                     ///< Number of Enabled Threads per Core. This will be 1 or 2.
+  UINT32                IntendedFreq;               ///< Maximum non turbo ratio in MHz
+  UINT32                ActualFreq;                 ///< Actual frequency in MHz
+  UINT32                Voltage;                    ///< Current operating voltage.
+  CACHE_DESCRIPTOR_INFO *CacheInfo;                 ///< Cache descriptor information.
+  UINT8                 MaxCacheSupported;          ///< Maximum cache supported.
+  UINT8                 SmmbaseSwSmiNumber;         ///< Software SMI Number from Smbase. @Note: This is unused.
+  UINT16                NumberOfPStates;            ///< Number of P-States.
+} CPU_INFO;
+
+///
+/// This HOB is data structure representing two different address location in SMRAM to hold SMRAM CPU DATA.
+///
+typedef struct {
+  EFI_PHYSICAL_ADDRESS LockBoxData;  ///< First location (address) of SMRAM CPU DATA.
+  EFI_PHYSICAL_ADDRESS SmramCpuData; ///< Second location (Address) of SMRAM CPU DATA.
+  UINT64               LockBoxSize;  ///< Size of SMRAM CPU DATA.
+} SMRAM_CPU_INFO;
+
+///
+/// SGX Information
+///
+typedef struct {
+  UINT64  SgxSinitNvsData;  ///< Sinit SE SVN Version saved and passed back in next boot
+} SGX_INFO;
+
+#pragma pack()
+
+///
+/// This protocol provides information about the common features available in this CPU.
+///
+struct _CPU_INFO_PROTOCOL {
+  /**
+  Revision for the protocol structure.
+  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>:
+   -  Initial version
+  **/
+  UINT8  Revision;
+  /**
+  CPU Supported Feature.
+   - BIT0:  If set then processor supports TXT.
+   - BIT1:  If set then processor supports virtual mode extensions.
+   - BIT2:  If set then processor supports execute disable bit.
+   - BIT3:  If set then processor supports DCA.
+   - BIT4:  If set then processor supports X2APIC.
+   - BIT5:  If set then processor supports Advanced Encryption Standard.
+   - BIT6:  If set then processor supports hyperthreading.
+   - BIT7:  If set then processor supports debug interface.
+   - BIT8:  If set then processor supports debug interface lock.
+   - BIT9:  If set then processor supports processor trace.
+   - BIT10: If Set then processor supports supports HDC.
+  **/
+  UINT64         CpuCommonFeatures;
+  CPU_INFO       *CpuInfo;      ///< Processor Basic Information
+  SMRAM_CPU_INFO *SmramCpuInfo; ///< SMRAM CPU Information
+  SGX_INFO       *SgxInfo;      ///< SGX Information
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
new file mode 100644
index 0000000000..ed056025b7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
@@ -0,0 +1,50 @@
+/** @file
+  Protocol used for specifying platform related CPU information and policy setting.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_PROTOCOL_H_
+#define _CPU_POLICY_PROTOCOL_H_
+
+//
+// DXE_CPU_POLICY_PROTOCOL revisions
+//
+#define DXE_CPU_POLICY_PROTOCOL_REVISION 1
+
+extern EFI_GUID gDxeCpuPolicyProtocolGuid;
+
+#pragma pack (push,1)
+
+/**
+  The protocol allows the platform code to publish a set of configuration information that the
+  CPU drivers will use to configure the processor in the DXE phase.
+  This Policy Protocol needs to be initialized for CPU configuration.
+  @note The Protocol has to be published before processor DXE drivers are dispatched.
+**/
+typedef struct {
+  /**
+  This member specifies the revision of the Cpu Policy protocol. This field is used to indicate backward
+  compatible changes to the protocol. Any such changes to this protocol will result in an update in the revision number.
+
+  <b>Revision 1</b>:
+   - Initial version
+  **/
+  /**
+  Policies to obtain CPU temperature.
+   - <b>0: ACPI thermal management uses EC reported temperature values</b>.
+   - 1: ACPI thermal management uses DTS SMM mechanism to obtain CPU temperature values.
+   - 2: ACPI Thermal Management uses EC reported temperature values and DTS SMM is used to handle Out of Spec condition.
+  **/
+  UINT32                         EnableDts           : 2;
+  UINT32                         RsvdBit             : 30;  ///< Reserved bits, align to multiple 32;
+
+  UINT8                          Revision;                  ///< Current revision of policy.
+  UINT8                          ReservedByte[3];           ///< Reserved bytes, align to multiple 8.
+} DXE_CPU_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add Include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
                   ` (34 subsequent siblings)
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds header files common to ME modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h | 124 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h  |  59 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h  |  87 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h               | 172 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h             |  17 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h                |  19 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h       |  41 +++++
 7 files changed, 519 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
new file mode 100644
index 0000000000..102fb43bd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
@@ -0,0 +1,124 @@
+/** @file
+  ME config block for PEI phase
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ME_PEI_CONFIG_H_
+#define _ME_PEI_CONFIG_H_
+
+#include <ConfigBlock.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>:
+  - Change DidInitStat bit width.
+**/
+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>(Test)</b> 0: Disable; <b>1: Enable</b> - Enable/Disable to send DID message.
+  /**
+    <b>(Test)</b>
+    <b>0: Set to 0 to enable retry mechanism for HECI APIs</b>
+       1: Set to 1 will disable retry mechanism for HECI APIs
+  **/
+  UINT32 DisableHeciRetry                 : 1;
+  /**
+    <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 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 2
+extern EFI_GUID gMePeiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME Pei Post-Memory Configuration Structure.
+
+  <b>Revision 1:</b>
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add MctpBroadcastCycle test setting.
+**/
+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.
+  /**
+    HECI3 state from Mbp for reference in S3 path only
+    <b>0: Disabled</b>; 1: Enabled
+  **/
+  UINT32 Heci3Enabled                     : 1;
+  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 RsvdBits                         : 25;  ///< Reserved for future use & Config block alignment
+} ME_PEI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ME_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
new file mode 100644
index 0000000000..46f7f86021
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
@@ -0,0 +1,59 @@
+/** @file
+  Prototype of the DxeMePolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_ME_POLICY_LIB_H_
+#define _DXE_ME_POLICY_LIB_H_
+
+#include <Protocol/MePolicy.h>
+
+/**
+  This function prints the ME DXE phase policy.
+
+  @param[in] DxeMePolicy - ME DXE Policy protocol
+**/
+VOID
+MePrintPolicyProtocol (
+  IN  ME_POLICY_PROTOCOL             *DxeMePolicy
+  );
+
+/**
+  MeCreatePolicyDefaults creates the default setting of ME Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+MeCreatePolicyDefaults (
+  IN OUT  ME_POLICY_PROTOCOL            **DxeMePolicy
+  );
+
+/**
+  MeInstallPolicyProtocol installs ME 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] DxeMePolicy                The pointer to ME Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+MeInstallPolicyProtocol (
+  IN  EFI_HANDLE                    ImageHandle,
+  IN  ME_POLICY_PROTOCOL            *DxeMePolicy
+  );
+
+#endif // _DXE_ME_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
new file mode 100644
index 0000000000..5db4714346
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
@@ -0,0 +1,87 @@
+/** @file
+  Prototype of the MePolicyLibPei library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_ME_POLICY_LIB_H_
+#define _PEI_ME_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  );
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi              The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  );
+
+/**
+  Get Me config block table total size.
+
+  @retval     Size of Me config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get ME config block table total size.
+
+  @retval      Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSizePreMem (
+  VOID
+  );
+
+/**
+  MeAddConfigBlocksPreMem add all ME config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add ME config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  MeAddConfigBlocks add all ME config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add ME config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_ME_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
new file mode 100644
index 0000000000..f29f9bc8bd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
@@ -0,0 +1,172 @@
+/** @file
+  Chipset definition for ME Devices.
+
+  Conventions:
+
+  - 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
+  - Registers / bits that are different between PCH generations are denoted by
+    "_ME_[generation_name]_" in register/bit names.
+  - Registers / bits that are specific to PCH-H denoted by "PCH_H_" in register/bit names.
+    Registers / bits that are specific to PCH-LP denoted by "PCH_LP_" in register/bit names.
+    e.g., "_ME_PCH_H_", "_ME_PCH_LP_"
+    Registers / bits names without _PCH_H_ or _PCH_LP_ apply for both H and 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 "_ME_" without [generation_name] inserted.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ME_CHIPSET_H_
+#define _ME_CHIPSET_H_
+
+#define ME_SEGMENT            0
+#define ME_BUS                0
+#define ME_DEVICE_NUMBER      22
+#define HECI_MIN_FUNC         0
+#define HECI_MAX_FUNC         5
+
+#define HECI_FUNCTION_NUMBER  0x00
+#define HECI2_FUNCTION_NUMBER 0x01
+#define IDER_FUNCTION_NUMBER  0x02
+#define SOL_FUNCTION_NUMBER   0x03
+#define HECI3_FUNCTION_NUMBER 0x04
+#define HECI4_FUNCTION_NUMBER 0x05
+
+#define IDER_BUS_NUMBER       ME_BUS
+#define IDER_DEVICE_NUMBER    ME_DEVICE_NUMBER
+#define SOL_BUS_NUMBER        ME_BUS
+#define SOL_DEVICE_NUMBER     ME_DEVICE_NUMBER
+
+ ///
+/// Convert to HECI# defined in BWG from Fun#
+///
+#define HECI_NAME_MAP(a) ((a < 2) ? (a + 1) : (a - 1))
+
+///
+/// ME-related Chipset Definition
+///
+#define HeciEnable()    MeDeviceControl (HECI1, Enabled);
+#define Heci2Enable()   MeDeviceControl (HECI2, Enabled);
+#define Heci3Enable()   MeDeviceControl (HECI3, Enabled);
+#define Heci4Enable()   MeDeviceControl (HECI4, Enabled);
+#define IderEnable()    MeDeviceControl (IDER, Enabled);
+#define SolEnable()     MeDeviceControl (SOL, Enabled);
+
+#define HeciDisable()   MeDeviceControl (HECI1, Disabled);
+#define Heci2Disable()  MeDeviceControl (HECI2, Disabled);
+#define Heci3Disable()  MeDeviceControl (HECI3, Disabled);
+#define IderDisable()   MeDeviceControl (IDER, Disabled);
+#define SolDisable()    MeDeviceControl (SOL, Disabled);
+
+#define DisableAllMeDevices() \
+  HeciDisable (); \
+  Heci2Disable (); \
+  Heci3Disable (); \
+  IderDisable (); \
+  SolDisable ();
+
+///
+/// HECI Device Id Definitions
+///
+ #define IS_PCH_H_HECI_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_H_HECI_DEVICE_ID) \
+     )
+
+ #define IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_LP_HECI_DEVICE_ID) \
+     )
+
+ #define IS_HECI_DEVICE_ID(DeviceId) \
+     ( \
+       IS_PCH_H_HECI_DEVICE_ID(DeviceId) || \
+       IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
+     )
+
+///
+/// HECI2 Device Id Definitions
+///
+#define IS_PCH_H_HECI2_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_H_HECI2_DEVICE_ID) \
+     )
+
+#define IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_LP_HECI2_DEVICE_ID) \
+     )
+
+#define IS_HECI2_DEVICE_ID(DeviceId) \
+     ( \
+       IS_PCH_H_HECI2_DEVICE_ID(DeviceId) || \
+       IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
+     )
+
+///
+/// HECI3 Device Id Definitions
+///
+#define IS_PCH_H_HECI3_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_HECI3_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_HECI3_DEVICE_ID) \
+    )
+
+#define IS_HECI3_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_HECI3_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
+    )
+
+///
+/// HECI4 Device Id Definitions
+///
+#define IS_PCH_H_HECI4_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_HECI4_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_HECI4_DEVICE_ID) \
+    )
+
+#define IS_HECI4_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_HECI4_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
+    )
+
+///
+/// SoL Device Id Definitions
+///
+#define IS_PCH_H_SOL_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_SOL_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_SOL_DEVICE_ID) \
+    )
+
+#define IS_PCH_SOL_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SOL_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
new file mode 100644
index 0000000000..a24973ce32
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
@@ -0,0 +1,17 @@
+/** @file
+  This file contains definitions of ME Policy HOB.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ME_POLICY_HOB_H_
+#define _ME_POLICY_HOB_H_
+
+#include <MePolicyCommon.h>
+
+extern EFI_GUID gMePolicyHobGuid;
+extern EFI_GUID gMePreMemPolicyHobGuid;
+
+#endif // _ME_POLICY_HOB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
new file mode 100644
index 0000000000..2d8ef1cf7a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
@@ -0,0 +1,19 @@
+/** @file
+  MKHI Messages
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MKHI_MSGS_H
+#define _MKHI_MSGS_H
+
+///
+/// End of Post
+///
+#define EOP_DISABLED    0
+#define EOP_SEND_IN_PEI 1
+#define EOP_SEND_IN_DXE 2
+
+#endif // _MKHI_MSGS_H
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
new file mode 100644
index 0000000000..518041cb58
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
@@ -0,0 +1,41 @@
+/** @file
+  Interface definition details between ME and platform drivers during DXE phase.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ME_POLICY_H_
+#define _ME_POLICY_H_
+
+#include <ConfigBlock.h>
+
+/**
+  ME Policy Protocol.
+  All ME Policy Protocol change history listed here.
+
+**/
+#define ME_POLICY_PROTOCOL_REVISION  1
+
+extern EFI_GUID gDxeMePolicyGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME policy provided by platform for DXE phase
+  This protocol provides an interface to get Intel ME Configuration information
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _ME_POLICY_PROTOCOL {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+} ME_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif // _ME_POLICY_H_
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (2 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
                   ` (33 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds Pch/Include headers.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h               | 135 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h               | 326 +++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h             | 381 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h            | 340 +++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h             | 241 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h            | 200 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h                |  54 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h                   |  38 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h               |  80 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h                |  53 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h  |  47 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h          |  47 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h    |  59 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h     |  53 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h |  23 ++
 15 files changed, 2077 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
new file mode 100644
index 0000000000..91222fd54d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
@@ -0,0 +1,135 @@
+/** @file
+  Header file for DxePchHdaNhltLib - NHLT structure definitions.
+
+  Copyright (c) 2019 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
+#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_DEVICE_TYPE
+{
+  HdaNhltDeviceBt   = 0,
+  HdaNhltDeviceDmic = 1,
+  HdaNhltDeviceI2s  = 4,
+  HdaNhltDeviceInvalid
+};
+
+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_HDA_NHLT_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
new file mode 100644
index 0000000000..babbf1ce3a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
@@ -0,0 +1,326 @@
+/** @file
+  Header file for GpioConfig structure used by GPIO library.
+
+  Copyright (c) 2019 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;
+
+
+///
+/// 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 {
+  GpioPadModeGpio     = 0x1,
+  GpioPadModeNative1  = 0x3,
+  GpioPadModeNative2  = 0x5,
+  GpioPadModeNative3  = 0x7,
+  GpioPadModeNative4  = 0x9,
+  GpioPadModeNative5  = 0xB
+} 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
+} 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/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
new file mode 100644
index 0000000000..524328d3e3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
@@ -0,0 +1,381 @@
+/** @file
+  GPIO pins,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_CNL_H_H_
+#define _GPIO_PINS_CNL_H_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_CNL_H_CHIPSET_ID       0x3
+
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_CNL_H_GROUP_GPP_A  0x0300
+#define GPIO_CNL_H_GROUP_GPP_B  0x0301
+#define GPIO_CNL_H_GROUP_GPP_C  0x0302
+#define GPIO_CNL_H_GROUP_GPP_D  0x0303
+#define GPIO_CNL_H_GROUP_GPP_E  0x0304
+#define GPIO_CNL_H_GROUP_GPP_F  0x0305
+#define GPIO_CNL_H_GROUP_GPP_G  0x0306
+#define GPIO_CNL_H_GROUP_GPP_H  0x0307
+#define GPIO_CNL_H_GROUP_GPP_I  0x0308
+#define GPIO_CNL_H_GROUP_GPP_J  0x0309
+#define GPIO_CNL_H_GROUP_GPP_K  0x030A
+#define GPIO_CNL_H_GROUP_GPD    0x030B
+#define GPIO_CNL_H_GROUP_VGPIO  0x030C
+#define GPIO_CNL_H_GROUP_SPI    0x030D
+#define GPIO_CNL_H_GROUP_AZA    0x030E
+#define GPIO_CNL_H_GROUP_CPU    0x030F
+#define GPIO_CNL_H_GROUP_JTAG   0x0310
+
+///
+/// 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_CNL_H_GPP_A0               0x03000000
+#define GPIO_CNL_H_GPP_A1               0x03000001
+#define GPIO_CNL_H_GPP_A2               0x03000002
+#define GPIO_CNL_H_GPP_A3               0x03000003
+#define GPIO_CNL_H_GPP_A4               0x03000004
+#define GPIO_CNL_H_GPP_A5               0x03000005
+#define GPIO_CNL_H_GPP_A6               0x03000006
+#define GPIO_CNL_H_GPP_A7               0x03000007
+#define GPIO_CNL_H_GPP_A8               0x03000008
+#define GPIO_CNL_H_GPP_A9               0x03000009
+#define GPIO_CNL_H_GPP_A10              0x0300000A
+#define GPIO_CNL_H_GPP_A11              0x0300000B
+#define GPIO_CNL_H_GPP_A12              0x0300000C
+#define GPIO_CNL_H_GPP_A13              0x0300000D
+#define GPIO_CNL_H_GPP_A14              0x0300000E
+#define GPIO_CNL_H_GPP_A15              0x0300000F
+#define GPIO_CNL_H_GPP_A16              0x03000010
+#define GPIO_CNL_H_GPP_A17              0x03000011
+#define GPIO_CNL_H_GPP_A18              0x03000012
+#define GPIO_CNL_H_GPP_A19              0x03000013
+#define GPIO_CNL_H_GPP_A20              0x03000014
+#define GPIO_CNL_H_GPP_A21              0x03000015
+#define GPIO_CNL_H_GPP_A22              0x03000016
+#define GPIO_CNL_H_GPP_A23              0x03000017
+#define GPIO_CNL_H_ESPI_CLK_LOOPBK      0x03000018
+
+#define GPIO_CNL_H_GPP_B0               0x03010000
+#define GPIO_CNL_H_GPP_B1               0x03010001
+#define GPIO_CNL_H_GPP_B2               0x03010002
+#define GPIO_CNL_H_GPP_B3               0x03010003
+#define GPIO_CNL_H_GPP_B4               0x03010004
+#define GPIO_CNL_H_GPP_B5               0x03010005
+#define GPIO_CNL_H_GPP_B6               0x03010006
+#define GPIO_CNL_H_GPP_B7               0x03010007
+#define GPIO_CNL_H_GPP_B8               0x03010008
+#define GPIO_CNL_H_GPP_B9               0x03010009
+#define GPIO_CNL_H_GPP_B10              0x0301000A
+#define GPIO_CNL_H_GPP_B11              0x0301000B
+#define GPIO_CNL_H_GPP_B12              0x0301000C
+#define GPIO_CNL_H_GPP_B13              0x0301000D
+#define GPIO_CNL_H_GPP_B14              0x0301000E
+#define GPIO_CNL_H_GPP_B15              0x0301000F
+#define GPIO_CNL_H_GPP_B16              0x03010010
+#define GPIO_CNL_H_GPP_B17              0x03010011
+#define GPIO_CNL_H_GPP_B18              0x03010012
+#define GPIO_CNL_H_GPP_B19              0x03010013
+#define GPIO_CNL_H_GPP_B20              0x03010014
+#define GPIO_CNL_H_GPP_B21              0x03010015
+#define GPIO_CNL_H_GPP_B22              0x03010016
+#define GPIO_CNL_H_GPP_B23              0x03010017
+#define GPIO_CNL_H_GSPI0_CLK_LOOPBK     0x03010018
+#define GPIO_CNL_H_GSPI1_CLK_LOOPBK     0x03010019
+
+#define GPIO_CNL_H_GPP_C0               0x03020000
+#define GPIO_CNL_H_GPP_C1               0x03020001
+#define GPIO_CNL_H_GPP_C2               0x03020002
+#define GPIO_CNL_H_GPP_C3               0x03020003
+#define GPIO_CNL_H_GPP_C4               0x03020004
+#define GPIO_CNL_H_GPP_C5               0x03020005
+#define GPIO_CNL_H_GPP_C6               0x03020006
+#define GPIO_CNL_H_GPP_C7               0x03020007
+#define GPIO_CNL_H_GPP_C8               0x03020008
+#define GPIO_CNL_H_GPP_C9               0x03020009
+#define GPIO_CNL_H_GPP_C10              0x0302000A
+#define GPIO_CNL_H_GPP_C11              0x0302000B
+#define GPIO_CNL_H_GPP_C12              0x0302000C
+#define GPIO_CNL_H_GPP_C13              0x0302000D
+#define GPIO_CNL_H_GPP_C14              0x0302000E
+#define GPIO_CNL_H_GPP_C15              0x0302000F
+#define GPIO_CNL_H_GPP_C16              0x03020010
+#define GPIO_CNL_H_GPP_C17              0x03020011
+#define GPIO_CNL_H_GPP_C18              0x03020012
+#define GPIO_CNL_H_GPP_C19              0x03020013
+#define GPIO_CNL_H_GPP_C20              0x03020014
+#define GPIO_CNL_H_GPP_C21              0x03020015
+#define GPIO_CNL_H_GPP_C22              0x03020016
+#define GPIO_CNL_H_GPP_C23              0x03020017
+
+#define GPIO_CNL_H_GPP_D0               0x03030000
+#define GPIO_CNL_H_GPP_D1               0x03030001
+#define GPIO_CNL_H_GPP_D2               0x03030002
+#define GPIO_CNL_H_GPP_D3               0x03030003
+#define GPIO_CNL_H_GPP_D4               0x03030004
+#define GPIO_CNL_H_GPP_D5               0x03030005
+#define GPIO_CNL_H_GPP_D6               0x03030006
+#define GPIO_CNL_H_GPP_D7               0x03030007
+#define GPIO_CNL_H_GPP_D8               0x03030008
+#define GPIO_CNL_H_GPP_D9               0x03030009
+#define GPIO_CNL_H_GPP_D10              0x0303000A
+#define GPIO_CNL_H_GPP_D11              0x0303000B
+#define GPIO_CNL_H_GPP_D12              0x0303000C
+#define GPIO_CNL_H_GPP_D13              0x0303000D
+#define GPIO_CNL_H_GPP_D14              0x0303000E
+#define GPIO_CNL_H_GPP_D15              0x0303000F
+#define GPIO_CNL_H_GPP_D16              0x03030010
+#define GPIO_CNL_H_GPP_D17              0x03030011
+#define GPIO_CNL_H_GPP_D18              0x03030012
+#define GPIO_CNL_H_GPP_D19              0x03030013
+#define GPIO_CNL_H_GPP_D20              0x03030014
+#define GPIO_CNL_H_GPP_D21              0x03030015
+#define GPIO_CNL_H_GPP_D22              0x03030016
+#define GPIO_CNL_H_GPP_D23              0x03030017
+
+#define GPIO_CNL_H_GPP_E0               0x03040000
+#define GPIO_CNL_H_GPP_E1               0x03040001
+#define GPIO_CNL_H_GPP_E2               0x03040002
+#define GPIO_CNL_H_GPP_E3               0x03040003
+#define GPIO_CNL_H_GPP_E4               0x03040004
+#define GPIO_CNL_H_GPP_E5               0x03040005
+#define GPIO_CNL_H_GPP_E6               0x03040006
+#define GPIO_CNL_H_GPP_E7               0x03040007
+#define GPIO_CNL_H_GPP_E8               0x03040008
+#define GPIO_CNL_H_GPP_E9               0x03040009
+#define GPIO_CNL_H_GPP_E10              0x0304000A
+#define GPIO_CNL_H_GPP_E11              0x0304000B
+#define GPIO_CNL_H_GPP_E12              0x0304000C
+
+#define GPIO_CNL_H_GPP_F0               0x03050000
+#define GPIO_CNL_H_GPP_F1               0x03050001
+#define GPIO_CNL_H_GPP_F2               0x03050002
+#define GPIO_CNL_H_GPP_F3               0x03050003
+#define GPIO_CNL_H_GPP_F4               0x03050004
+#define GPIO_CNL_H_GPP_F5               0x03050005
+#define GPIO_CNL_H_GPP_F6               0x03050006
+#define GPIO_CNL_H_GPP_F7               0x03050007
+#define GPIO_CNL_H_GPP_F8               0x03050008
+#define GPIO_CNL_H_GPP_F9               0x03050009
+#define GPIO_CNL_H_GPP_F10              0x0305000A
+#define GPIO_CNL_H_GPP_F11              0x0305000B
+#define GPIO_CNL_H_GPP_F12              0x0305000C
+#define GPIO_CNL_H_GPP_F13              0x0305000D
+#define GPIO_CNL_H_GPP_F14              0x0305000E
+#define GPIO_CNL_H_GPP_F15              0x0305000F
+#define GPIO_CNL_H_GPP_F16              0x03050010
+#define GPIO_CNL_H_GPP_F17              0x03050011
+#define GPIO_CNL_H_GPP_F18              0x03050012
+#define GPIO_CNL_H_GPP_F19              0x03050013
+#define GPIO_CNL_H_GPP_F20              0x03050014
+#define GPIO_CNL_H_GPP_F21              0x03050015
+#define GPIO_CNL_H_GPP_F22              0x03050016
+#define GPIO_CNL_H_GPP_F23              0x03050017
+
+#define GPIO_CNL_H_GPP_G0               0x03060000
+#define GPIO_CNL_H_GPP_G1               0x03060001
+#define GPIO_CNL_H_GPP_G2               0x03060002
+#define GPIO_CNL_H_GPP_G3               0x03060003
+#define GPIO_CNL_H_GPP_G4               0x03060004
+#define GPIO_CNL_H_GPP_G5               0x03060005
+#define GPIO_CNL_H_GPP_G6               0x03060006
+#define GPIO_CNL_H_GPP_G7               0x03060007
+
+#define GPIO_CNL_H_GPP_H0               0x03070000
+#define GPIO_CNL_H_GPP_H1               0x03070001
+#define GPIO_CNL_H_GPP_H2               0x03070002
+#define GPIO_CNL_H_GPP_H3               0x03070003
+#define GPIO_CNL_H_GPP_H4               0x03070004
+#define GPIO_CNL_H_GPP_H5               0x03070005
+#define GPIO_CNL_H_GPP_H6               0x03070006
+#define GPIO_CNL_H_GPP_H7               0x03070007
+#define GPIO_CNL_H_GPP_H8               0x03070008
+#define GPIO_CNL_H_GPP_H9               0x03070009
+#define GPIO_CNL_H_GPP_H10              0x0307000A
+#define GPIO_CNL_H_GPP_H11              0x0307000B
+#define GPIO_CNL_H_GPP_H12              0x0307000C
+#define GPIO_CNL_H_GPP_H13              0x0307000D
+#define GPIO_CNL_H_GPP_H14              0x0307000E
+#define GPIO_CNL_H_GPP_H15              0x0307000F
+#define GPIO_CNL_H_GPP_H16              0x03070010
+#define GPIO_CNL_H_GPP_H17              0x03070011
+#define GPIO_CNL_H_GPP_H18              0x03070012
+#define GPIO_CNL_H_GPP_H19              0x03070013
+#define GPIO_CNL_H_GPP_H20              0x03070014
+#define GPIO_CNL_H_GPP_H21              0x03070015
+#define GPIO_CNL_H_GPP_H22              0x03070016
+#define GPIO_CNL_H_GPP_H23              0x03070017
+
+#define GPIO_CNL_H_GPP_I0               0x03080000
+#define GPIO_CNL_H_GPP_I1               0x03080001
+#define GPIO_CNL_H_GPP_I2               0x03080002
+#define GPIO_CNL_H_GPP_I3               0x03080003
+#define GPIO_CNL_H_GPP_I4               0x03080004
+#define GPIO_CNL_H_GPP_I5               0x03080005
+#define GPIO_CNL_H_GPP_I6               0x03080006
+#define GPIO_CNL_H_GPP_I7               0x03080007
+#define GPIO_CNL_H_GPP_I8               0x03080008
+#define GPIO_CNL_H_GPP_I9               0x03080009
+#define GPIO_CNL_H_GPP_I10              0x0308000A
+#define GPIO_CNL_H_GPP_I11              0x0308000B
+#define GPIO_CNL_H_GPP_I12              0x0308000C
+#define GPIO_CNL_H_GPP_I13              0x0308000D
+#define GPIO_CNL_H_GPP_I14              0x0308000E
+#define GPIO_CNL_H_SYS_PWROK            0x0308000F
+#define GPIO_CNL_H_SYS_RESETB           0x03080010
+#define GPIO_CNL_H_MLK_RSTB             0x03080011
+
+#define GPIO_CNL_H_GPP_J0               0x03090000
+#define GPIO_CNL_H_GPP_J1               0x03090001
+#define GPIO_CNL_H_GPP_J2               0x03090002
+#define GPIO_CNL_H_GPP_J3               0x03090003
+#define GPIO_CNL_H_GPP_J4               0x03090004
+#define GPIO_CNL_H_GPP_J5               0x03090005
+#define GPIO_CNL_H_GPP_J6               0x03090006
+#define GPIO_CNL_H_GPP_J7               0x03090007
+#define GPIO_CNL_H_GPP_J8               0x03090008
+#define GPIO_CNL_H_GPP_J9               0x03090009
+#define GPIO_CNL_H_GPP_J10              0x0309000A
+#define GPIO_CNL_H_GPP_J11              0x0309000B
+
+#define GPIO_CNL_H_GPP_K0               0x030A0000
+#define GPIO_CNL_H_GPP_K1               0x030A0001
+#define GPIO_CNL_H_GPP_K2               0x030A0002
+#define GPIO_CNL_H_GPP_K3               0x030A0003
+#define GPIO_CNL_H_GPP_K4               0x030A0004
+#define GPIO_CNL_H_GPP_K5               0x030A0005
+#define GPIO_CNL_H_GPP_K6               0x030A0006
+#define GPIO_CNL_H_GPP_K7               0x030A0007
+#define GPIO_CNL_H_GPP_K8               0x030A0008
+#define GPIO_CNL_H_GPP_K9               0x030A0009
+#define GPIO_CNL_H_GPP_K10              0x030A000A
+#define GPIO_CNL_H_GPP_K11              0x030A000B
+#define GPIO_CNL_H_GPP_K12              0x030A000C
+#define GPIO_CNL_H_GPP_K13              0x030A000D
+#define GPIO_CNL_H_GPP_K14              0x030A000E
+#define GPIO_CNL_H_GPP_K15              0x030A000F
+#define GPIO_CNL_H_GPP_K16              0x030A0010
+#define GPIO_CNL_H_GPP_K17              0x030A0011
+#define GPIO_CNL_H_GPP_K18              0x030A0012
+#define GPIO_CNL_H_GPP_K19              0x030A0013
+#define GPIO_CNL_H_GPP_K20              0x030A0014
+#define GPIO_CNL_H_GPP_K21              0x030A0015
+#define GPIO_CNL_H_GPP_K22              0x030A0016
+#define GPIO_CNL_H_GPP_K23              0x030A0017
+
+#define GPIO_CNL_H_GPD0                 0x030B0000
+#define GPIO_CNL_H_GPD1                 0x030B0001
+#define GPIO_CNL_H_GPD2                 0x030B0002
+#define GPIO_CNL_H_GPD3                 0x030B0003
+#define GPIO_CNL_H_GPD4                 0x030B0004
+#define GPIO_CNL_H_GPD5                 0x030B0005
+#define GPIO_CNL_H_GPD6                 0x030B0006
+#define GPIO_CNL_H_GPD7                 0x030B0007
+#define GPIO_CNL_H_GPD8                 0x030B0008
+#define GPIO_CNL_H_GPD9                 0x030B0009
+#define GPIO_CNL_H_GPD10                0x030B000A
+#define GPIO_CNL_H_GPD11                0x030B000B
+#define GPIO_CNL_H_SLP_LANB             0x030B000C
+#define GPIO_CNL_H_SLP_SUSB             0x030B000D
+#define GPIO_CNL_H_SLP_WAKEB            0x030B000E
+#define GPIO_CNL_H_SLP_DRAM_RESETB      0x030B000F
+
+#define GPIO_CNL_H_VGPIO0               0x030C0000
+#define GPIO_CNL_H_VGPIO1               0x030C0001
+#define GPIO_CNL_H_VGPIO2               0x030C0002
+#define GPIO_CNL_H_VGPIO3               0x030C0003
+#define GPIO_CNL_H_VGPIO4               0x030C0004
+#define GPIO_CNL_H_VGPIO5               0x030C0005
+#define GPIO_CNL_H_VGPIO6               0x030C0006
+#define GPIO_CNL_H_VGPIO7               0x030C0007
+#define GPIO_CNL_H_VGPIO8               0x030C0008
+#define GPIO_CNL_H_VGPIO9               0x030C0009
+#define GPIO_CNL_H_VGPIO10              0x030C000A
+#define GPIO_CNL_H_VGPIO11              0x030C000B
+#define GPIO_CNL_H_VGPIO12              0x030C000C
+#define GPIO_CNL_H_VGPIO13              0x030C000D
+#define GPIO_CNL_H_VGPIO14              0x030C000E
+#define GPIO_CNL_H_VGPIO15              0x030C000F
+#define GPIO_CNL_H_VGPIO16              0x030C0010
+#define GPIO_CNL_H_VGPIO17              0x030C0011
+#define GPIO_CNL_H_VGPIO18              0x030C0012
+#define GPIO_CNL_H_VGPIO19              0x030C0013
+#define GPIO_CNL_H_VGPIO20              0x030C0014
+#define GPIO_CNL_H_VGPIO21              0x030C0015
+#define GPIO_CNL_H_VGPIO22              0x030C0016
+#define GPIO_CNL_H_VGPIO23              0x030C0017
+#define GPIO_CNL_H_VGPIO24              0x030C0018
+#define GPIO_CNL_H_VGPIO25              0x030C0019
+#define GPIO_CNL_H_VGPIO26              0x030C001A
+#define GPIO_CNL_H_VGPIO27              0x030C001B
+#define GPIO_CNL_H_VGPIO28              0x030C001C
+#define GPIO_CNL_H_VGPIO29              0x030C001D
+#define GPIO_CNL_H_VGPIO30              0x030C001E
+#define GPIO_CNL_H_VGPIO31              0x030C001F
+#define GPIO_CNL_H_VGPIO32              0x030C0020
+#define GPIO_CNL_H_VGPIO33              0x030C0021
+#define GPIO_CNL_H_VGPIO34              0x030C0022
+#define GPIO_CNL_H_VGPIO35              0x030C0023
+#define GPIO_CNL_H_VGPIO36              0x030C0024
+#define GPIO_CNL_H_VGPIO37              0x030C0025
+#define GPIO_CNL_H_VGPIO38              0x030C0026
+#define GPIO_CNL_H_VGPIO39              0x030C0027
+
+#define GPIO_CNL_H_SPI0_IO_2            0x030D0000
+#define GPIO_CNL_H_SPI0_IO_3            0x030D0001
+#define GPIO_CNL_H_SPI0_MOSI_IO_0       0x030D0002
+#define GPIO_CNL_H_SPI0_MOSI_IO_1       0x030D0003
+#define GPIO_CNL_H_SPI0_TPM_CSB         0x030D0004
+#define GPIO_CNL_H_SPI0_FLASH_0_CSB     0x030D0005
+#define GPIO_CNL_H_SPI0_FLASH_1_CSB     0x030D0006
+#define GPIO_CNL_H_SPI0_CLK             0x030D0007
+#define GPIO_CNL_H_SPI0_CLK_LOOPBK      0x030D0008
+
+#define GPIO_CNL_H_HDA_BCLK             0x030E0000
+#define GPIO_CNL_H_HDA_RSTB             0x030E0001
+#define GPIO_CNL_H_HDA_SYNC             0x030E0002
+#define GPIO_CNL_H_HDA_SDO              0x030E0003
+#define GPIO_CNL_H_HDA_SDI_0            0x030E0004
+#define GPIO_CNL_H_HDA_SDI_1            0x030E0005
+#define GPIO_CNL_H_SSP1_SFRM            0x030E0006
+#define GPIO_CNL_H_SSP1_TXD             0x030E0007
+
+#define GPIO_CNL_H_HDACPU_SDI           0x030F0000
+#define GPIO_CNL_H_HDACPU_SDO           0x030F0001
+#define GPIO_CNL_H_HDACPU_SCLK          0x030F0002
+#define GPIO_CNL_H_PM_SYNC              0x030F0003
+#define GPIO_CNL_H_PECI                 0x030F0004
+#define GPIO_CNL_H_CPUPWRGD             0x030F0005
+#define GPIO_CNL_H_THRMTRIPB            0x030F0006
+#define GPIO_CNL_H_PLTRST_CPUB          0x030F0007
+#define GPIO_CNL_H_PM_DOWN              0x030F0008
+#define GPIO_CNL_H_TRIGGER_IN           0x030F0009
+#define GPIO_CNL_H_TRIGGER_OUT          0x030F000A
+
+#define GPIO_CNL_H_JTAG_TDO             0x03100000
+#define GPIO_CNL_H_JTAGX                0x03100001
+#define GPIO_CNL_H_PRDYB                0x03100002
+#define GPIO_CNL_H_PREQB                0x03100003
+#define GPIO_CNL_H_CPU_TRSTB            0x03100004
+#define GPIO_CNL_H_JTAG_TDI             0x03100005
+#define GPIO_CNL_H_JTAG_TMS             0x03100006
+#define GPIO_CNL_H_JTAG_TCK             0x03100007
+#define GPIO_CNL_H_ITP_PMODE            0x03100008
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
new file mode 100644
index 0000000000..9ce5875ca5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
@@ -0,0 +1,340 @@
+/** @file
+  GPIO pins,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_CNL_LP_H_
+#define _GPIO_PINS_CNL_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_CNL_LP_CHIPSET_ID      0x4
+
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_CNL_LP_GROUP_GPP_A  0x0400
+#define GPIO_CNL_LP_GROUP_GPP_B  0x0401
+#define GPIO_CNL_LP_GROUP_GPP_C  0x0402
+#define GPIO_CNL_LP_GROUP_GPP_D  0x0403
+#define GPIO_CNL_LP_GROUP_GPP_E  0x0404
+#define GPIO_CNL_LP_GROUP_GPP_F  0x0405
+#define GPIO_CNL_LP_GROUP_GPP_G  0x0406
+#define GPIO_CNL_LP_GROUP_GPP_H  0x0407
+#define GPIO_CNL_LP_GROUP_GPD    0x0408
+#define GPIO_CNL_LP_GROUP_VGPIO  0x0409
+#define GPIO_CNL_LP_GROUP_SPI    0x040A
+#define GPIO_CNL_LP_GROUP_AZA    0x040B
+#define GPIO_CNL_LP_GROUP_CPU    0x040C
+#define GPIO_CNL_LP_GROUP_JTAG   0x040D
+#define GPIO_CNL_LP_GROUP_HVMOS  0x040E
+
+///
+/// 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_CNL_LP_GPP_A0               0x04000000
+#define GPIO_CNL_LP_GPP_A1               0x04000001
+#define GPIO_CNL_LP_GPP_A2               0x04000002
+#define GPIO_CNL_LP_GPP_A3               0x04000003
+#define GPIO_CNL_LP_GPP_A4               0x04000004
+#define GPIO_CNL_LP_GPP_A5               0x04000005
+#define GPIO_CNL_LP_GPP_A6               0x04000006
+#define GPIO_CNL_LP_GPP_A7               0x04000007
+#define GPIO_CNL_LP_GPP_A8               0x04000008
+#define GPIO_CNL_LP_GPP_A9               0x04000009
+#define GPIO_CNL_LP_GPP_A10              0x0400000A
+#define GPIO_CNL_LP_GPP_A11              0x0400000B
+#define GPIO_CNL_LP_GPP_A12              0x0400000C
+#define GPIO_CNL_LP_GPP_A13              0x0400000D
+#define GPIO_CNL_LP_GPP_A14              0x0400000E
+#define GPIO_CNL_LP_GPP_A15              0x0400000F
+#define GPIO_CNL_LP_GPP_A16              0x04000010
+#define GPIO_CNL_LP_GPP_A17              0x04000011
+#define GPIO_CNL_LP_GPP_A18              0x04000012
+#define GPIO_CNL_LP_GPP_A19              0x04000013
+#define GPIO_CNL_LP_GPP_A20              0x04000014
+#define GPIO_CNL_LP_GPP_A21              0x04000015
+#define GPIO_CNL_LP_GPP_A22              0x04000016
+#define GPIO_CNL_LP_GPP_A23              0x04000017
+#define GPIO_CNL_LP_ESPI_CLK_LOOPBK      0x04000018
+
+#define GPIO_CNL_LP_GPP_B0               0x04010000
+#define GPIO_CNL_LP_GPP_B1               0x04010001
+#define GPIO_CNL_LP_GPP_B2               0x04010002
+#define GPIO_CNL_LP_GPP_B3               0x04010003
+#define GPIO_CNL_LP_GPP_B4               0x04010004
+#define GPIO_CNL_LP_GPP_B5               0x04010005
+#define GPIO_CNL_LP_GPP_B6               0x04010006
+#define GPIO_CNL_LP_GPP_B7               0x04010007
+#define GPIO_CNL_LP_GPP_B8               0x04010008
+#define GPIO_CNL_LP_GPP_B9               0x04010009
+#define GPIO_CNL_LP_GPP_B10              0x0401000A
+#define GPIO_CNL_LP_GPP_B11              0x0401000B
+#define GPIO_CNL_LP_GPP_B12              0x0401000C
+#define GPIO_CNL_LP_GPP_B13              0x0401000D
+#define GPIO_CNL_LP_GPP_B14              0x0401000E
+#define GPIO_CNL_LP_GPP_B15              0x0401000F
+#define GPIO_CNL_LP_GPP_B16              0x04010010
+#define GPIO_CNL_LP_GPP_B17              0x04010011
+#define GPIO_CNL_LP_GPP_B18              0x04010012
+#define GPIO_CNL_LP_GPP_B19              0x04010013
+#define GPIO_CNL_LP_GPP_B20              0x04010014
+#define GPIO_CNL_LP_GPP_B21              0x04010015
+#define GPIO_CNL_LP_GPP_B22              0x04010016
+#define GPIO_CNL_LP_GPP_B23              0x04010017
+#define GPIO_CNL_LP_GSPI0_CLK_LOOPBK     0x04010018
+#define GPIO_CNL_LP_GSPI1_CLK_LOOPBK     0x04010019
+
+#define GPIO_CNL_LP_GPP_C0               0x04020000
+#define GPIO_CNL_LP_GPP_C1               0x04020001
+#define GPIO_CNL_LP_GPP_C2               0x04020002
+#define GPIO_CNL_LP_GPP_C3               0x04020003
+#define GPIO_CNL_LP_GPP_C4               0x04020004
+#define GPIO_CNL_LP_GPP_C5               0x04020005
+#define GPIO_CNL_LP_GPP_C6               0x04020006
+#define GPIO_CNL_LP_GPP_C7               0x04020007
+#define GPIO_CNL_LP_GPP_C8               0x04020008
+#define GPIO_CNL_LP_GPP_C9               0x04020009
+#define GPIO_CNL_LP_GPP_C10              0x0402000A
+#define GPIO_CNL_LP_GPP_C11              0x0402000B
+#define GPIO_CNL_LP_GPP_C12              0x0402000C
+#define GPIO_CNL_LP_GPP_C13              0x0402000D
+#define GPIO_CNL_LP_GPP_C14              0x0402000E
+#define GPIO_CNL_LP_GPP_C15              0x0402000F
+#define GPIO_CNL_LP_GPP_C16              0x04020010
+#define GPIO_CNL_LP_GPP_C17              0x04020011
+#define GPIO_CNL_LP_GPP_C18              0x04020012
+#define GPIO_CNL_LP_GPP_C19              0x04020013
+#define GPIO_CNL_LP_GPP_C20              0x04020014
+#define GPIO_CNL_LP_GPP_C21              0x04020015
+#define GPIO_CNL_LP_GPP_C22              0x04020016
+#define GPIO_CNL_LP_GPP_C23              0x04020017
+
+#define GPIO_CNL_LP_GPP_D0               0x04030000
+#define GPIO_CNL_LP_GPP_D1               0x04030001
+#define GPIO_CNL_LP_GPP_D2               0x04030002
+#define GPIO_CNL_LP_GPP_D3               0x04030003
+#define GPIO_CNL_LP_GPP_D4               0x04030004
+#define GPIO_CNL_LP_GPP_D5               0x04030005
+#define GPIO_CNL_LP_GPP_D6               0x04030006
+#define GPIO_CNL_LP_GPP_D7               0x04030007
+#define GPIO_CNL_LP_GPP_D8               0x04030008
+#define GPIO_CNL_LP_GPP_D9               0x04030009
+#define GPIO_CNL_LP_GPP_D10              0x0403000A
+#define GPIO_CNL_LP_GPP_D11              0x0403000B
+#define GPIO_CNL_LP_GPP_D12              0x0403000C
+#define GPIO_CNL_LP_GPP_D13              0x0403000D
+#define GPIO_CNL_LP_GPP_D14              0x0403000E
+#define GPIO_CNL_LP_GPP_D15              0x0403000F
+#define GPIO_CNL_LP_GPP_D16              0x04030010
+#define GPIO_CNL_LP_GPP_D17              0x04030011
+#define GPIO_CNL_LP_GPP_D18              0x04030012
+#define GPIO_CNL_LP_GPP_D19              0x04030013
+#define GPIO_CNL_LP_GPP_D20              0x04030014
+#define GPIO_CNL_LP_GPP_D21              0x04030015
+#define GPIO_CNL_LP_GPP_D22              0x04030016
+#define GPIO_CNL_LP_GPP_D23              0x04030017
+
+#define GPIO_CNL_LP_GPP_E0               0x04040000
+#define GPIO_CNL_LP_GPP_E1               0x04040001
+#define GPIO_CNL_LP_GPP_E2               0x04040002
+#define GPIO_CNL_LP_GPP_E3               0x04040003
+#define GPIO_CNL_LP_GPP_E4               0x04040004
+#define GPIO_CNL_LP_GPP_E5               0x04040005
+#define GPIO_CNL_LP_GPP_E6               0x04040006
+#define GPIO_CNL_LP_GPP_E7               0x04040007
+#define GPIO_CNL_LP_GPP_E8               0x04040008
+#define GPIO_CNL_LP_GPP_E9               0x04040009
+#define GPIO_CNL_LP_GPP_E10              0x0404000A
+#define GPIO_CNL_LP_GPP_E11              0x0404000B
+#define GPIO_CNL_LP_GPP_E12              0x0404000C
+#define GPIO_CNL_LP_GPP_E13              0x0404000D
+#define GPIO_CNL_LP_GPP_E14              0x0404000E
+#define GPIO_CNL_LP_GPP_E15              0x0404000F
+#define GPIO_CNL_LP_GPP_E16              0x04040010
+#define GPIO_CNL_LP_GPP_E17              0x04040011
+#define GPIO_CNL_LP_GPP_E18              0x04040012
+#define GPIO_CNL_LP_GPP_E19              0x04040013
+#define GPIO_CNL_LP_GPP_E20              0x04040014
+#define GPIO_CNL_LP_GPP_E21              0x04040015
+#define GPIO_CNL_LP_GPP_E22              0x04040016
+#define GPIO_CNL_LP_GPP_E23              0x04040017
+
+#define GPIO_CNL_LP_GPP_F0               0x04050000
+#define GPIO_CNL_LP_GPP_F1               0x04050001
+#define GPIO_CNL_LP_GPP_F2               0x04050002
+#define GPIO_CNL_LP_GPP_F3               0x04050003
+#define GPIO_CNL_LP_GPP_F4               0x04050004
+#define GPIO_CNL_LP_GPP_F5               0x04050005
+#define GPIO_CNL_LP_GPP_F6               0x04050006
+#define GPIO_CNL_LP_GPP_F7               0x04050007
+#define GPIO_CNL_LP_GPP_F8               0x04050008
+#define GPIO_CNL_LP_GPP_F9               0x04050009
+#define GPIO_CNL_LP_GPP_F10              0x0405000A
+#define GPIO_CNL_LP_GPP_F11              0x0405000B
+#define GPIO_CNL_LP_GPP_F12              0x0405000C
+#define GPIO_CNL_LP_GPP_F13              0x0405000D
+#define GPIO_CNL_LP_GPP_F14              0x0405000E
+#define GPIO_CNL_LP_GPP_F15              0x0405000F
+#define GPIO_CNL_LP_GPP_F16              0x04050010
+#define GPIO_CNL_LP_GPP_F17              0x04050011
+#define GPIO_CNL_LP_GPP_F18              0x04050012
+#define GPIO_CNL_LP_GPP_F19              0x04050013
+#define GPIO_CNL_LP_GPP_F20              0x04050014
+#define GPIO_CNL_LP_GPP_F21              0x04050015
+#define GPIO_CNL_LP_GPP_F22              0x04050016
+#define GPIO_CNL_LP_GPP_F23              0x04050017
+
+#define GPIO_CNL_LP_GPP_G0               0x04060000
+#define GPIO_CNL_LP_GPP_G1               0x04060001
+#define GPIO_CNL_LP_GPP_G2               0x04060002
+#define GPIO_CNL_LP_GPP_G3               0x04060003
+#define GPIO_CNL_LP_GPP_G4               0x04060004
+#define GPIO_CNL_LP_GPP_G5               0x04060005
+#define GPIO_CNL_LP_GPP_G6               0x04060006
+#define GPIO_CNL_LP_GPP_G7               0x04060007
+
+#define GPIO_CNL_LP_GPP_H0               0x04070000
+#define GPIO_CNL_LP_GPP_H1               0x04070001
+#define GPIO_CNL_LP_GPP_H2               0x04070002
+#define GPIO_CNL_LP_GPP_H3               0x04070003
+#define GPIO_CNL_LP_GPP_H4               0x04070004
+#define GPIO_CNL_LP_GPP_H5               0x04070005
+#define GPIO_CNL_LP_GPP_H6               0x04070006
+#define GPIO_CNL_LP_GPP_H7               0x04070007
+#define GPIO_CNL_LP_GPP_H8               0x04070008
+#define GPIO_CNL_LP_GPP_H9               0x04070009
+#define GPIO_CNL_LP_GPP_H10              0x0407000A
+#define GPIO_CNL_LP_GPP_H11              0x0407000B
+#define GPIO_CNL_LP_GPP_H12              0x0407000C
+#define GPIO_CNL_LP_GPP_H13              0x0407000D
+#define GPIO_CNL_LP_GPP_H14              0x0407000E
+#define GPIO_CNL_LP_GPP_H15              0x0407000F
+#define GPIO_CNL_LP_GPP_H16              0x04070010
+#define GPIO_CNL_LP_GPP_H17              0x04070011
+#define GPIO_CNL_LP_GPP_H18              0x04070012
+#define GPIO_CNL_LP_GPP_H19              0x04070013
+#define GPIO_CNL_LP_GPP_H20              0x04070014
+#define GPIO_CNL_LP_GPP_H21              0x04070015
+#define GPIO_CNL_LP_GPP_H22              0x04070016
+#define GPIO_CNL_LP_GPP_H23              0x04070017
+
+#define GPIO_CNL_LP_GPD0                 0x04080000
+#define GPIO_CNL_LP_GPD1                 0x04080001
+#define GPIO_CNL_LP_GPD2                 0x04080002
+#define GPIO_CNL_LP_GPD3                 0x04080003
+#define GPIO_CNL_LP_GPD4                 0x04080004
+#define GPIO_CNL_LP_GPD5                 0x04080005
+#define GPIO_CNL_LP_GPD6                 0x04080006
+#define GPIO_CNL_LP_GPD7                 0x04080007
+#define GPIO_CNL_LP_GPD8                 0x04080008
+#define GPIO_CNL_LP_GPD9                 0x04080009
+#define GPIO_CNL_LP_GPD10                0x0408000A
+#define GPIO_CNL_LP_GPD11                0x0408000B
+#define GPIO_CNL_LP_SLP_LANB             0x0408000C
+#define GPIO_CNL_LP_SLP_SUSB             0x0408000D
+#define GPIO_CNL_LP_SLP_WAKEB            0x0408000E
+#define GPIO_CNL_LP_SLP_DRAM_RESETB      0x0408000F
+
+#define GPIO_CNL_LP_VGPIO0               0x04090000
+#define GPIO_CNL_LP_VGPIO1               0x04090001
+#define GPIO_CNL_LP_VGPIO2               0x04090002
+#define GPIO_CNL_LP_VGPIO3               0x04090003
+#define GPIO_CNL_LP_VGPIO4               0x04090004
+#define GPIO_CNL_LP_VGPIO5               0x04090005
+#define GPIO_CNL_LP_VGPIO6               0x04090006
+#define GPIO_CNL_LP_VGPIO7               0x04090007
+#define GPIO_CNL_LP_VGPIO8               0x04090008
+#define GPIO_CNL_LP_VGPIO9               0x04090009
+#define GPIO_CNL_LP_VGPIO10              0x0409000A
+#define GPIO_CNL_LP_VGPIO11              0x0409000B
+#define GPIO_CNL_LP_VGPIO12              0x0409000C
+#define GPIO_CNL_LP_VGPIO13              0x0409000D
+#define GPIO_CNL_LP_VGPIO14              0x0409000E
+#define GPIO_CNL_LP_VGPIO15              0x0409000F
+#define GPIO_CNL_LP_VGPIO16              0x04090010
+#define GPIO_CNL_LP_VGPIO17              0x04090011
+#define GPIO_CNL_LP_VGPIO18              0x04090012
+#define GPIO_CNL_LP_VGPIO19              0x04090013
+#define GPIO_CNL_LP_VGPIO20              0x04090014
+#define GPIO_CNL_LP_VGPIO21              0x04090015
+#define GPIO_CNL_LP_VGPIO22              0x04090016
+#define GPIO_CNL_LP_VGPIO23              0x04090017
+#define GPIO_CNL_LP_VGPIO24              0x04090018
+#define GPIO_CNL_LP_VGPIO25              0x04090019
+#define GPIO_CNL_LP_VGPIO26              0x0409001A
+#define GPIO_CNL_LP_VGPIO27              0x0409001B
+#define GPIO_CNL_LP_VGPIO28              0x0409001C
+#define GPIO_CNL_LP_VGPIO29              0x0409001D
+#define GPIO_CNL_LP_VGPIO30              0x0409001E
+#define GPIO_CNL_LP_VGPIO31              0x0409001F
+#define GPIO_CNL_LP_VGPIO32              0x04090020
+#define GPIO_CNL_LP_VGPIO33              0x04090021
+#define GPIO_CNL_LP_VGPIO34              0x04090022
+#define GPIO_CNL_LP_VGPIO35              0x04090023
+#define GPIO_CNL_LP_VGPIO36              0x04090024
+#define GPIO_CNL_LP_VGPIO37              0x04090025
+#define GPIO_CNL_LP_VGPIO38              0x04090026
+#define GPIO_CNL_LP_VGPIO39              0x04090027
+
+#define GPIO_CNL_LP_SPI0_IO_2            0x040A0000
+#define GPIO_CNL_LP_SPI0_IO_3            0x040A0001
+#define GPIO_CNL_LP_SPI0_MOSI_IO_0       0x040A0002
+#define GPIO_CNL_LP_SPI0_MOSI_IO_1       0x040A0003
+#define GPIO_CNL_LP_SPI0_TPM_CSB         0x040A0004
+#define GPIO_CNL_LP_SPI0_FLASH_0_CSB     0x040A0005
+#define GPIO_CNL_LP_SPI0_FLASH_1_CSB     0x040A0006
+#define GPIO_CNL_LP_SPI0_CLK             0x040A0007
+#define GPIO_CNL_LP_SPI0_CLK_LOOPBK      0x040A0008
+
+#define GPIO_CNL_LP_HDA_BCLK             0x040B0000
+#define GPIO_CNL_LP_HDA_RSTB             0x040B0001
+#define GPIO_CNL_LP_HDA_SYNC             0x040B0002
+#define GPIO_CNL_LP_HDA_SDO              0x040B0003
+#define GPIO_CNL_LP_HDA_SDI_0            0x040B0004
+#define GPIO_CNL_LP_HDA_SDI_1            0x040B0005
+#define GPIO_CNL_LP_SSP1_SFRM            0x040B0006
+#define GPIO_CNL_LP_SSP1_TXD             0x040B0007
+
+#define GPIO_CNL_LP_HDACPU_SDI           0x040C0000
+#define GPIO_CNL_LP_HDACPU_SDO           0x040C0001
+#define GPIO_CNL_LP_HDACPU_SCLK          0x040C0002
+#define GPIO_CNL_LP_PM_SYNC              0x040C0003
+#define GPIO_CNL_LP_PECI                 0x040C0004
+#define GPIO_CNL_LP_CPUPWRGD             0x040C0005
+#define GPIO_CNL_LP_THRMTRIPB            0x040C0006
+#define GPIO_CNL_LP_PLTRST_CPUB          0x040C0007
+#define GPIO_CNL_LP_PM_DOWN              0x040C0008
+#define GPIO_CNL_LP_TRIGGER_IN           0x040C0009
+#define GPIO_CNL_LP_TRIGGER_OUT          0x040C000A
+
+#define GPIO_CNL_LP_JTAG_TDO             0x040D0000
+#define GPIO_CNL_LP_JTAGX                0x040D0001
+#define GPIO_CNL_LP_PRDYB                0x040D0002
+#define GPIO_CNL_LP_PREQB                0x040D0003
+#define GPIO_CNL_LP_CPU_TRSTB            0x040D0004
+#define GPIO_CNL_LP_JTAG_TDI             0x040D0005
+#define GPIO_CNL_LP_JTAG_TMS             0x040D0006
+#define GPIO_CNL_LP_JTAG_TCK             0x040D0007
+#define GPIO_CNL_LP_ITP_PMODE            0x040D0008
+
+#define GPIO_CNL_LP_HVMOS_L_BKLTEN       0x040E0000
+#define GPIO_CNL_LP_HVMOS_L_BKLTCTL      0x040E0001
+#define GPIO_CNL_LP_HVMOS_L_VDDEN        0x040E0002
+#define GPIO_CNL_LP_HVMOS_SYS_PWROK      0x040E0003
+#define GPIO_CNL_LP_HVMOS_SYS_RESETB     0x040E0004
+#define GPIO_CNL_LP_HVMOS_MLK_RSTB       0x040E0005
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
new file mode 100644
index 0000000000..d3aad4172f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
@@ -0,0 +1,241 @@
+/** @file
+  GPIO pins
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_SKL_H_H_
+#define _GPIO_PINS_SKL_H_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
+///
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_SKL_H_GROUP_GPP_A  0x0100
+#define GPIO_SKL_H_GROUP_GPP_B  0x0101
+#define GPIO_SKL_H_GROUP_GPP_C  0x0102
+#define GPIO_SKL_H_GROUP_GPP_D  0x0103
+#define GPIO_SKL_H_GROUP_GPP_E  0x0104
+#define GPIO_SKL_H_GROUP_GPP_F  0x0105
+#define GPIO_SKL_H_GROUP_GPP_G  0x0106
+#define GPIO_SKL_H_GROUP_GPP_H  0x0107
+#define GPIO_SKL_H_GROUP_GPP_I  0x0108
+#define GPIO_SKL_H_GROUP_GPD    0x0109
+
+///
+/// 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_SKL_H_GPP_A0       0x01000000
+#define GPIO_SKL_H_GPP_A1       0x01000001
+#define GPIO_SKL_H_GPP_A2       0x01000002
+#define GPIO_SKL_H_GPP_A3       0x01000003
+#define GPIO_SKL_H_GPP_A4       0x01000004
+#define GPIO_SKL_H_GPP_A5       0x01000005
+#define GPIO_SKL_H_GPP_A6       0x01000006
+#define GPIO_SKL_H_GPP_A7       0x01000007
+#define GPIO_SKL_H_GPP_A8       0x01000008
+#define GPIO_SKL_H_GPP_A9       0x01000009
+#define GPIO_SKL_H_GPP_A10      0x0100000A
+#define GPIO_SKL_H_GPP_A11      0x0100000B
+#define GPIO_SKL_H_GPP_A12      0x0100000C
+#define GPIO_SKL_H_GPP_A13      0x0100000D
+#define GPIO_SKL_H_GPP_A14      0x0100000E
+#define GPIO_SKL_H_GPP_A15      0x0100000F
+#define GPIO_SKL_H_GPP_A16      0x01000010
+#define GPIO_SKL_H_GPP_A17      0x01000011
+#define GPIO_SKL_H_GPP_A18      0x01000012
+#define GPIO_SKL_H_GPP_A19      0x01000013
+#define GPIO_SKL_H_GPP_A20      0x01000014
+#define GPIO_SKL_H_GPP_A21      0x01000015
+#define GPIO_SKL_H_GPP_A22      0x01000016
+#define GPIO_SKL_H_GPP_A23      0x01000017
+#define GPIO_SKL_H_GPP_B0       0x01010000
+#define GPIO_SKL_H_GPP_B1       0x01010001
+#define GPIO_SKL_H_GPP_B2       0x01010002
+#define GPIO_SKL_H_GPP_B3       0x01010003
+#define GPIO_SKL_H_GPP_B4       0x01010004
+#define GPIO_SKL_H_GPP_B5       0x01010005
+#define GPIO_SKL_H_GPP_B6       0x01010006
+#define GPIO_SKL_H_GPP_B7       0x01010007
+#define GPIO_SKL_H_GPP_B8       0x01010008
+#define GPIO_SKL_H_GPP_B9       0x01010009
+#define GPIO_SKL_H_GPP_B10      0x0101000A
+#define GPIO_SKL_H_GPP_B11      0x0101000B
+#define GPIO_SKL_H_GPP_B12      0x0101000C
+#define GPIO_SKL_H_GPP_B13      0x0101000D
+#define GPIO_SKL_H_GPP_B14      0x0101000E
+#define GPIO_SKL_H_GPP_B15      0x0101000F
+#define GPIO_SKL_H_GPP_B16      0x01010010
+#define GPIO_SKL_H_GPP_B17      0x01010011
+#define GPIO_SKL_H_GPP_B18      0x01010012
+#define GPIO_SKL_H_GPP_B19      0x01010013
+#define GPIO_SKL_H_GPP_B20      0x01010014
+#define GPIO_SKL_H_GPP_B21      0x01010015
+#define GPIO_SKL_H_GPP_B22      0x01010016
+#define GPIO_SKL_H_GPP_B23      0x01010017
+#define GPIO_SKL_H_GPP_C0       0x01020000
+#define GPIO_SKL_H_GPP_C1       0x01020001
+#define GPIO_SKL_H_GPP_C2       0x01020002
+#define GPIO_SKL_H_GPP_C3       0x01020003
+#define GPIO_SKL_H_GPP_C4       0x01020004
+#define GPIO_SKL_H_GPP_C5       0x01020005
+#define GPIO_SKL_H_GPP_C6       0x01020006
+#define GPIO_SKL_H_GPP_C7       0x01020007
+#define GPIO_SKL_H_GPP_C8       0x01020008
+#define GPIO_SKL_H_GPP_C9       0x01020009
+#define GPIO_SKL_H_GPP_C10      0x0102000A
+#define GPIO_SKL_H_GPP_C11      0x0102000B
+#define GPIO_SKL_H_GPP_C12      0x0102000C
+#define GPIO_SKL_H_GPP_C13      0x0102000D
+#define GPIO_SKL_H_GPP_C14      0x0102000E
+#define GPIO_SKL_H_GPP_C15      0x0102000F
+#define GPIO_SKL_H_GPP_C16      0x01020010
+#define GPIO_SKL_H_GPP_C17      0x01020011
+#define GPIO_SKL_H_GPP_C18      0x01020012
+#define GPIO_SKL_H_GPP_C19      0x01020013
+#define GPIO_SKL_H_GPP_C20      0x01020014
+#define GPIO_SKL_H_GPP_C21      0x01020015
+#define GPIO_SKL_H_GPP_C22      0x01020016
+#define GPIO_SKL_H_GPP_C23      0x01020017
+#define GPIO_SKL_H_GPP_D0       0x01030000
+#define GPIO_SKL_H_GPP_D1       0x01030001
+#define GPIO_SKL_H_GPP_D2       0x01030002
+#define GPIO_SKL_H_GPP_D3       0x01030003
+#define GPIO_SKL_H_GPP_D4       0x01030004
+#define GPIO_SKL_H_GPP_D5       0x01030005
+#define GPIO_SKL_H_GPP_D6       0x01030006
+#define GPIO_SKL_H_GPP_D7       0x01030007
+#define GPIO_SKL_H_GPP_D8       0x01030008
+#define GPIO_SKL_H_GPP_D9       0x01030009
+#define GPIO_SKL_H_GPP_D10      0x0103000A
+#define GPIO_SKL_H_GPP_D11      0x0103000B
+#define GPIO_SKL_H_GPP_D12      0x0103000C
+#define GPIO_SKL_H_GPP_D13      0x0103000D
+#define GPIO_SKL_H_GPP_D14      0x0103000E
+#define GPIO_SKL_H_GPP_D15      0x0103000F
+#define GPIO_SKL_H_GPP_D16      0x01030010
+#define GPIO_SKL_H_GPP_D17      0x01030011
+#define GPIO_SKL_H_GPP_D18      0x01030012
+#define GPIO_SKL_H_GPP_D19      0x01030013
+#define GPIO_SKL_H_GPP_D20      0x01030014
+#define GPIO_SKL_H_GPP_D21      0x01030015
+#define GPIO_SKL_H_GPP_D22      0x01030016
+#define GPIO_SKL_H_GPP_D23      0x01030017
+#define GPIO_SKL_H_GPP_E0       0x01040000
+#define GPIO_SKL_H_GPP_E1       0x01040001
+#define GPIO_SKL_H_GPP_E2       0x01040002
+#define GPIO_SKL_H_GPP_E3       0x01040003
+#define GPIO_SKL_H_GPP_E4       0x01040004
+#define GPIO_SKL_H_GPP_E5       0x01040005
+#define GPIO_SKL_H_GPP_E6       0x01040006
+#define GPIO_SKL_H_GPP_E7       0x01040007
+#define GPIO_SKL_H_GPP_E8       0x01040008
+#define GPIO_SKL_H_GPP_E9       0x01040009
+#define GPIO_SKL_H_GPP_E10      0x0104000A
+#define GPIO_SKL_H_GPP_E11      0x0104000B
+#define GPIO_SKL_H_GPP_E12      0x0104000C
+#define GPIO_SKL_H_GPP_F0       0x01050000
+#define GPIO_SKL_H_GPP_F1       0x01050001
+#define GPIO_SKL_H_GPP_F2       0x01050002
+#define GPIO_SKL_H_GPP_F3       0x01050003
+#define GPIO_SKL_H_GPP_F4       0x01050004
+#define GPIO_SKL_H_GPP_F5       0x01050005
+#define GPIO_SKL_H_GPP_F6       0x01050006
+#define GPIO_SKL_H_GPP_F7       0x01050007
+#define GPIO_SKL_H_GPP_F8       0x01050008
+#define GPIO_SKL_H_GPP_F9       0x01050009
+#define GPIO_SKL_H_GPP_F10      0x0105000A
+#define GPIO_SKL_H_GPP_F11      0x0105000B
+#define GPIO_SKL_H_GPP_F12      0x0105000C
+#define GPIO_SKL_H_GPP_F13      0x0105000D
+#define GPIO_SKL_H_GPP_F14      0x0105000E
+#define GPIO_SKL_H_GPP_F15      0x0105000F
+#define GPIO_SKL_H_GPP_F16      0x01050010
+#define GPIO_SKL_H_GPP_F17      0x01050011
+#define GPIO_SKL_H_GPP_F18      0x01050012
+#define GPIO_SKL_H_GPP_F19      0x01050013
+#define GPIO_SKL_H_GPP_F20      0x01050014
+#define GPIO_SKL_H_GPP_F21      0x01050015
+#define GPIO_SKL_H_GPP_F22      0x01050016
+#define GPIO_SKL_H_GPP_F23      0x01050017
+#define GPIO_SKL_H_GPP_G0       0x01060000
+#define GPIO_SKL_H_GPP_G1       0x01060001
+#define GPIO_SKL_H_GPP_G2       0x01060002
+#define GPIO_SKL_H_GPP_G3       0x01060003
+#define GPIO_SKL_H_GPP_G4       0x01060004
+#define GPIO_SKL_H_GPP_G5       0x01060005
+#define GPIO_SKL_H_GPP_G6       0x01060006
+#define GPIO_SKL_H_GPP_G7       0x01060007
+#define GPIO_SKL_H_GPP_G8       0x01060008
+#define GPIO_SKL_H_GPP_G9       0x01060009
+#define GPIO_SKL_H_GPP_G10      0x0106000A
+#define GPIO_SKL_H_GPP_G11      0x0106000B
+#define GPIO_SKL_H_GPP_G12      0x0106000C
+#define GPIO_SKL_H_GPP_G13      0x0106000D
+#define GPIO_SKL_H_GPP_G14      0x0106000E
+#define GPIO_SKL_H_GPP_G15      0x0106000F
+#define GPIO_SKL_H_GPP_G16      0x01060010
+#define GPIO_SKL_H_GPP_G17      0x01060011
+#define GPIO_SKL_H_GPP_G18      0x01060012
+#define GPIO_SKL_H_GPP_G19      0x01060013
+#define GPIO_SKL_H_GPP_G20      0x01060014
+#define GPIO_SKL_H_GPP_G21      0x01060015
+#define GPIO_SKL_H_GPP_G22      0x01060016
+#define GPIO_SKL_H_GPP_G23      0x01060017
+#define GPIO_SKL_H_GPP_H0       0x01070000
+#define GPIO_SKL_H_GPP_H1       0x01070001
+#define GPIO_SKL_H_GPP_H2       0x01070002
+#define GPIO_SKL_H_GPP_H3       0x01070003
+#define GPIO_SKL_H_GPP_H4       0x01070004
+#define GPIO_SKL_H_GPP_H5       0x01070005
+#define GPIO_SKL_H_GPP_H6       0x01070006
+#define GPIO_SKL_H_GPP_H7       0x01070007
+#define GPIO_SKL_H_GPP_H8       0x01070008
+#define GPIO_SKL_H_GPP_H9       0x01070009
+#define GPIO_SKL_H_GPP_H10      0x0107000A
+#define GPIO_SKL_H_GPP_H11      0x0107000B
+#define GPIO_SKL_H_GPP_H12      0x0107000C
+#define GPIO_SKL_H_GPP_H13      0x0107000D
+#define GPIO_SKL_H_GPP_H14      0x0107000E
+#define GPIO_SKL_H_GPP_H15      0x0107000F
+#define GPIO_SKL_H_GPP_H16      0x01070010
+#define GPIO_SKL_H_GPP_H17      0x01070011
+#define GPIO_SKL_H_GPP_H18      0x01070012
+#define GPIO_SKL_H_GPP_H19      0x01070013
+#define GPIO_SKL_H_GPP_H20      0x01070014
+#define GPIO_SKL_H_GPP_H21      0x01070015
+#define GPIO_SKL_H_GPP_H22      0x01070016
+#define GPIO_SKL_H_GPP_H23      0x01070017
+#define GPIO_SKL_H_GPP_I0       0x01080000
+#define GPIO_SKL_H_GPP_I1       0x01080001
+#define GPIO_SKL_H_GPP_I2       0x01080002
+#define GPIO_SKL_H_GPP_I3       0x01080003
+#define GPIO_SKL_H_GPP_I4       0x01080004
+#define GPIO_SKL_H_GPP_I5       0x01080005
+#define GPIO_SKL_H_GPP_I6       0x01080006
+#define GPIO_SKL_H_GPP_I7       0x01080007
+#define GPIO_SKL_H_GPP_I8       0x01080008
+#define GPIO_SKL_H_GPP_I9       0x01080009
+#define GPIO_SKL_H_GPP_I10      0x0108000A
+#define GPIO_SKL_H_GPD0         0x01090000
+#define GPIO_SKL_H_GPD1         0x01090001
+#define GPIO_SKL_H_GPD2         0x01090002
+#define GPIO_SKL_H_GPD3         0x01090003
+#define GPIO_SKL_H_GPD4         0x01090004
+#define GPIO_SKL_H_GPD5         0x01090005
+#define GPIO_SKL_H_GPD6         0x01090006
+#define GPIO_SKL_H_GPD7         0x01090007
+#define GPIO_SKL_H_GPD8         0x01090008
+#define GPIO_SKL_H_GPD9         0x01090009
+#define GPIO_SKL_H_GPD10        0x0109000A
+#define GPIO_SKL_H_GPD11        0x0109000B
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
new file mode 100644
index 0000000000..8d430afd14
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
@@ -0,0 +1,200 @@
+/** @file
+  GPIO pins
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_SKL_LP_H_
+#define _GPIO_PINS_SKL_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
+///
+
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_SKL_LP_GROUP_GPP_A  0x0200
+#define GPIO_SKL_LP_GROUP_GPP_B  0x0201
+#define GPIO_SKL_LP_GROUP_GPP_C  0x0202
+#define GPIO_SKL_LP_GROUP_GPP_D  0x0203
+#define GPIO_SKL_LP_GROUP_GPP_E  0x0204
+#define GPIO_SKL_LP_GROUP_GPP_F  0x0205
+#define GPIO_SKL_LP_GROUP_GPP_G  0x0206
+#define GPIO_SKL_LP_GROUP_GPD    0x0207
+
+///
+/// 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_SKL_LP_GPP_A0      0x02000000
+#define GPIO_SKL_LP_GPP_A1      0x02000001
+#define GPIO_SKL_LP_GPP_A2      0x02000002
+#define GPIO_SKL_LP_GPP_A3      0x02000003
+#define GPIO_SKL_LP_GPP_A4      0x02000004
+#define GPIO_SKL_LP_GPP_A5      0x02000005
+#define GPIO_SKL_LP_GPP_A6      0x02000006
+#define GPIO_SKL_LP_GPP_A7      0x02000007
+#define GPIO_SKL_LP_GPP_A8      0x02000008
+#define GPIO_SKL_LP_GPP_A9      0x02000009
+#define GPIO_SKL_LP_GPP_A10     0x0200000A
+#define GPIO_SKL_LP_GPP_A11     0x0200000B
+#define GPIO_SKL_LP_GPP_A12     0x0200000C
+#define GPIO_SKL_LP_GPP_A13     0x0200000D
+#define GPIO_SKL_LP_GPP_A14     0x0200000E
+#define GPIO_SKL_LP_GPP_A15     0x0200000F
+#define GPIO_SKL_LP_GPP_A16     0x02000010
+#define GPIO_SKL_LP_GPP_A17     0x02000011
+#define GPIO_SKL_LP_GPP_A18     0x02000012
+#define GPIO_SKL_LP_GPP_A19     0x02000013
+#define GPIO_SKL_LP_GPP_A20     0x02000014
+#define GPIO_SKL_LP_GPP_A21     0x02000015
+#define GPIO_SKL_LP_GPP_A22     0x02000016
+#define GPIO_SKL_LP_GPP_A23     0x02000017
+#define GPIO_SKL_LP_GPP_B0      0x02010000
+#define GPIO_SKL_LP_GPP_B1      0x02010001
+#define GPIO_SKL_LP_GPP_B2      0x02010002
+#define GPIO_SKL_LP_GPP_B3      0x02010003
+#define GPIO_SKL_LP_GPP_B4      0x02010004
+#define GPIO_SKL_LP_GPP_B5      0x02010005
+#define GPIO_SKL_LP_GPP_B6      0x02010006
+#define GPIO_SKL_LP_GPP_B7      0x02010007
+#define GPIO_SKL_LP_GPP_B8      0x02010008
+#define GPIO_SKL_LP_GPP_B9      0x02010009
+#define GPIO_SKL_LP_GPP_B10     0x0201000A
+#define GPIO_SKL_LP_GPP_B11     0x0201000B
+#define GPIO_SKL_LP_GPP_B12     0x0201000C
+#define GPIO_SKL_LP_GPP_B13     0x0201000D
+#define GPIO_SKL_LP_GPP_B14     0x0201000E
+#define GPIO_SKL_LP_GPP_B15     0x0201000F
+#define GPIO_SKL_LP_GPP_B16     0x02010010
+#define GPIO_SKL_LP_GPP_B17     0x02010011
+#define GPIO_SKL_LP_GPP_B18     0x02010012
+#define GPIO_SKL_LP_GPP_B19     0x02010013
+#define GPIO_SKL_LP_GPP_B20     0x02010014
+#define GPIO_SKL_LP_GPP_B21     0x02010015
+#define GPIO_SKL_LP_GPP_B22     0x02010016
+#define GPIO_SKL_LP_GPP_B23     0x02010017
+#define GPIO_SKL_LP_GPP_C0      0x02020000
+#define GPIO_SKL_LP_GPP_C1      0x02020001
+#define GPIO_SKL_LP_GPP_C2      0x02020002
+#define GPIO_SKL_LP_GPP_C3      0x02020003
+#define GPIO_SKL_LP_GPP_C4      0x02020004
+#define GPIO_SKL_LP_GPP_C5      0x02020005
+#define GPIO_SKL_LP_GPP_C6      0x02020006
+#define GPIO_SKL_LP_GPP_C7      0x02020007
+#define GPIO_SKL_LP_GPP_C8      0x02020008
+#define GPIO_SKL_LP_GPP_C9      0x02020009
+#define GPIO_SKL_LP_GPP_C10     0x0202000A
+#define GPIO_SKL_LP_GPP_C11     0x0202000B
+#define GPIO_SKL_LP_GPP_C12     0x0202000C
+#define GPIO_SKL_LP_GPP_C13     0x0202000D
+#define GPIO_SKL_LP_GPP_C14     0x0202000E
+#define GPIO_SKL_LP_GPP_C15     0x0202000F
+#define GPIO_SKL_LP_GPP_C16     0x02020010
+#define GPIO_SKL_LP_GPP_C17     0x02020011
+#define GPIO_SKL_LP_GPP_C18     0x02020012
+#define GPIO_SKL_LP_GPP_C19     0x02020013
+#define GPIO_SKL_LP_GPP_C20     0x02020014
+#define GPIO_SKL_LP_GPP_C21     0x02020015
+#define GPIO_SKL_LP_GPP_C22     0x02020016
+#define GPIO_SKL_LP_GPP_C23     0x02020017
+#define GPIO_SKL_LP_GPP_D0      0x02030000
+#define GPIO_SKL_LP_GPP_D1      0x02030001
+#define GPIO_SKL_LP_GPP_D2      0x02030002
+#define GPIO_SKL_LP_GPP_D3      0x02030003
+#define GPIO_SKL_LP_GPP_D4      0x02030004
+#define GPIO_SKL_LP_GPP_D5      0x02030005
+#define GPIO_SKL_LP_GPP_D6      0x02030006
+#define GPIO_SKL_LP_GPP_D7      0x02030007
+#define GPIO_SKL_LP_GPP_D8      0x02030008
+#define GPIO_SKL_LP_GPP_D9      0x02030009
+#define GPIO_SKL_LP_GPP_D10     0x0203000A
+#define GPIO_SKL_LP_GPP_D11     0x0203000B
+#define GPIO_SKL_LP_GPP_D12     0x0203000C
+#define GPIO_SKL_LP_GPP_D13     0x0203000D
+#define GPIO_SKL_LP_GPP_D14     0x0203000E
+#define GPIO_SKL_LP_GPP_D15     0x0203000F
+#define GPIO_SKL_LP_GPP_D16     0x02030010
+#define GPIO_SKL_LP_GPP_D17     0x02030011
+#define GPIO_SKL_LP_GPP_D18     0x02030012
+#define GPIO_SKL_LP_GPP_D19     0x02030013
+#define GPIO_SKL_LP_GPP_D20     0x02030014
+#define GPIO_SKL_LP_GPP_D21     0x02030015
+#define GPIO_SKL_LP_GPP_D22     0x02030016
+#define GPIO_SKL_LP_GPP_D23     0x02030017
+#define GPIO_SKL_LP_GPP_E0      0x02040000
+#define GPIO_SKL_LP_GPP_E1      0x02040001
+#define GPIO_SKL_LP_GPP_E2      0x02040002
+#define GPIO_SKL_LP_GPP_E3      0x02040003
+#define GPIO_SKL_LP_GPP_E4      0x02040004
+#define GPIO_SKL_LP_GPP_E5      0x02040005
+#define GPIO_SKL_LP_GPP_E6      0x02040006
+#define GPIO_SKL_LP_GPP_E7      0x02040007
+#define GPIO_SKL_LP_GPP_E8      0x02040008
+#define GPIO_SKL_LP_GPP_E9      0x02040009
+#define GPIO_SKL_LP_GPP_E10     0x0204000A
+#define GPIO_SKL_LP_GPP_E11     0x0204000B
+#define GPIO_SKL_LP_GPP_E12     0x0204000C
+#define GPIO_SKL_LP_GPP_E13     0x0204000D
+#define GPIO_SKL_LP_GPP_E14     0x0204000E
+#define GPIO_SKL_LP_GPP_E15     0x0204000F
+#define GPIO_SKL_LP_GPP_E16     0x02040010
+#define GPIO_SKL_LP_GPP_E17     0x02040011
+#define GPIO_SKL_LP_GPP_E18     0x02040012
+#define GPIO_SKL_LP_GPP_E19     0x02040013
+#define GPIO_SKL_LP_GPP_E20     0x02040014
+#define GPIO_SKL_LP_GPP_E21     0x02040015
+#define GPIO_SKL_LP_GPP_E22     0x02040016
+#define GPIO_SKL_LP_GPP_E23     0x02040017
+#define GPIO_SKL_LP_GPP_F0      0x02050000
+#define GPIO_SKL_LP_GPP_F1      0x02050001
+#define GPIO_SKL_LP_GPP_F2      0x02050002
+#define GPIO_SKL_LP_GPP_F3      0x02050003
+#define GPIO_SKL_LP_GPP_F4      0x02050004
+#define GPIO_SKL_LP_GPP_F5      0x02050005
+#define GPIO_SKL_LP_GPP_F6      0x02050006
+#define GPIO_SKL_LP_GPP_F7      0x02050007
+#define GPIO_SKL_LP_GPP_F8      0x02050008
+#define GPIO_SKL_LP_GPP_F9      0x02050009
+#define GPIO_SKL_LP_GPP_F10     0x0205000A
+#define GPIO_SKL_LP_GPP_F11     0x0205000B
+#define GPIO_SKL_LP_GPP_F12     0x0205000C
+#define GPIO_SKL_LP_GPP_F13     0x0205000D
+#define GPIO_SKL_LP_GPP_F14     0x0205000E
+#define GPIO_SKL_LP_GPP_F15     0x0205000F
+#define GPIO_SKL_LP_GPP_F16     0x02050010
+#define GPIO_SKL_LP_GPP_F17     0x02050011
+#define GPIO_SKL_LP_GPP_F18     0x02050012
+#define GPIO_SKL_LP_GPP_F19     0x02050013
+#define GPIO_SKL_LP_GPP_F20     0x02050014
+#define GPIO_SKL_LP_GPP_F21     0x02050015
+#define GPIO_SKL_LP_GPP_F22     0x02050016
+#define GPIO_SKL_LP_GPP_F23     0x02050017
+#define GPIO_SKL_LP_GPP_G0      0x02060000
+#define GPIO_SKL_LP_GPP_G1      0x02060001
+#define GPIO_SKL_LP_GPP_G2      0x02060002
+#define GPIO_SKL_LP_GPP_G3      0x02060003
+#define GPIO_SKL_LP_GPP_G4      0x02060004
+#define GPIO_SKL_LP_GPP_G5      0x02060005
+#define GPIO_SKL_LP_GPP_G6      0x02060006
+#define GPIO_SKL_LP_GPP_G7      0x02060007
+#define GPIO_SKL_LP_GPD0        0x02070000
+#define GPIO_SKL_LP_GPD1        0x02070001
+#define GPIO_SKL_LP_GPD2        0x02070002
+#define GPIO_SKL_LP_GPD3        0x02070003
+#define GPIO_SKL_LP_GPD4        0x02070004
+#define GPIO_SKL_LP_GPD5        0x02070005
+#define GPIO_SKL_LP_GPD6        0x02070006
+#define GPIO_SKL_LP_GPD7        0x02070007
+#define GPIO_SKL_LP_GPD8        0x02070008
+#define GPIO_SKL_LP_GPD9        0x02070009
+#define GPIO_SKL_LP_GPD10       0x0207000A
+#define GPIO_SKL_LP_GPD11       0x0207000B
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
new file mode 100644
index 0000000000..6730b3baf9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
@@ -0,0 +1,54 @@
+/** @file
+  Macros that simplify accessing PCH devices's PCI registers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_ACCESS_H_
+#define _PCH_ACCESS_H_
+
+#include "PchLimits.h"
+#include "PchReservedResources.h"
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_SECOND
+#define STALL_ONE_SECOND 1000000
+#endif
+
+//
+// Include device register definitions
+//
+#include "PcieRegs.h"
+#include "Register/PchRegs.h"
+#include "Register/PchRegsPcr.h"
+#include "Register/PchRegsP2sb.h"
+#include "Register/PchRegsHda.h"
+#include "Register/PchRegsHsio.h"
+#include "Register/PchRegsLan.h"
+#include "Register/PchRegsLpc.h"
+#include "Register/PchRegsPmc.h"
+#include "Register/PchRegsPcie.h"
+#include "Register/PchRegsSata.h"
+#include "Register/PchRegsSmbus.h"
+#include "Register/PchRegsSpi.h"
+#include <Register/RegsUsb.h>
+#include "Register/PchRegsGpio.h"
+#include "Register/PchRegsThermalCnl.h"
+#include "Register/PchRegsGpioCnl.h"
+#include "Register/PchRegsSerialIoCnl.h"
+#include "Register/PchRegsSerialIo.h"
+#include "Register/PchRegsTraceHub.h"
+#include "Register/PchRegsScsCnl.h"
+#include "Register/PchRegsIsh.h"
+#include "Register/PchRegsDmi.h"
+#include "Register/PchRegsItss.h"
+#include "Register/PchRegsPsth.h"
+#include "Register/PchRegsFia.h"
+#include "Register/PchRegsDci.h"
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
new file mode 100644
index 0000000000..3b8e5147db
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for HD Audio configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_H_
+#define _PCH_HDA_H_
+
+
+enum PCH_HDAUDIO_DMIC_TYPE {
+  PchHdaDmicDisabled = 0,
+  PchHdaDmic2chArray = 1,
+  PchHdaDmic4chArray = 2,
+  PchHdaDmic1chArray = 3
+};
+
+typedef enum {
+  PchHdaLinkFreq6MHz  = 0,
+  PchHdaLinkFreq12MHz = 1,
+  PchHdaLinkFreq24MHz = 2,
+  PchHdaLinkFreq48MHz = 3,
+  PchHdaLinkFreq96MHz = 4,
+  PchHdaLinkFreqInvalid
+} PCH_HDAUDIO_LINK_FREQUENCY;
+
+typedef enum  {
+  PchHdaIDispMode2T  = 0,
+  PchHdaIDispMode1T  = 1,
+  PchHdaIDispMode4T  = 2,
+  PchHdaIDispMode8T  = 3,
+  PchHdaIDispMode16T = 4,
+  PchHdaIDispTModeInvalid
+} PCH_HDAUDIO_IDISP_TMODE;
+
+#endif // _PCH_HDA_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
new file mode 100644
index 0000000000..743dd84b2b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
@@ -0,0 +1,80 @@
+/** @file
+  This file contains definitions of PCH Info HOB.
+
+  Copyright (c) 2019 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  2
+
+#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>:
+  - Added LaneReversal Field
+**/
+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];
+
+  /**
+    GbE over PCIe port number when GbE is enabled
+    >0 - Root port number (1-based)
+    0  - GbE over PCIe disabled
+    This information needs to be passed through HOB as FIA registers
+    are not accessible with POSTBOOT_SAI
+  **/
+  UINT8        GbePciePortNumber;
+  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;
+  /**
+    This member specifies if lane reversal is enabled on the specific
+    Pcie Root port controller.
+  **/
+  UINT8        PcieControllerLaneReversal[6];
+} PCH_INFO_HOB;
+
+#pragma pack (pop)
+
+#endif // _PCH_INFO_HOB_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
new file mode 100644
index 0000000000..929f9f02d4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
@@ -0,0 +1,53 @@
+/** @file
+  Build time limits of PCH resources.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_LIMITS_H_
+#define _PCH_LIMITS_H_
+
+//
+// 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
+
+//
+// USB limits
+//
+#define PCH_MAX_USB2_PORTS                  16
+#define PCH_MAX_USB3_PORTS                  10
+
+//
+// SerialIo limits
+//
+#define PCH_MAX_SERIALIO_CONTROLLERS         12
+#define PCH_MAX_SERIALIO_I2C_CONTROLLERS      6
+#define PCH_MAX_SERIALIO_SPI_CONTROLLERS      3
+#define PCH_MAX_SERIALIO_UART_CONTROLLERS     3
+
+//
+// Number of eSPI slaves
+//
+#define PCH_MAX_ESPI_SLAVES                  2
+
+#endif // _PCH_LIMITS_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
new file mode 100644
index 0000000000..1097e58332
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
@@ -0,0 +1,47 @@
+/** @file
+  Definitions required to create PcieStorageInfoHob
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIE_STORAGE_DETECT_HOB_
+#define _PCH_PCIE_STORAGE_DETECT_HOB_
+
+#include "PchLimits.h"
+
+#define PCIE_STORAGE_INFO_HOB_REVISION              1
+
+extern EFI_GUID gPchPcieStorageDetectHobGuid;
+
+typedef enum {
+  RstLinkWidthX1 = 1,
+  RstLinkWidthX2 = 2,
+  RstLinkWidthX4 = 4
+} RST_LINK_WIDTH;
+
+//
+//  Stores information about connected PCIe storage devices used later by BIOS setup and RST remapping
+//
+#pragma pack(1)
+typedef struct {
+  UINT8  Revision;
+
+  //
+  // Stores the number of root ports occupied by a connected storage device, values from RST_LINK_WIDTH are supported
+  //
+  UINT8  PcieStorageLinkWidth[PCH_MAX_PCIE_ROOT_PORTS];
+
+  //
+  // Programming interface value for a given device, 0x02 - NVMe or RAID, 0x1 - AHCI storage, 0x0 - no device connected
+  //
+  UINT8  PcieStorageProgrammingInterface[PCH_MAX_PCIE_ROOT_PORTS];
+
+  //
+  // Stores information about cycle router number under a given PCIe controller
+  //
+  UINT8  RstCycleRouterMap[PCH_MAX_PCIE_CONTROLLERS];
+} PCIE_STORAGE_INFO_HOB;
+#pragma pack()
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
new file mode 100644
index 0000000000..213ca91d2d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
@@ -0,0 +1,47 @@
+/** @file
+  PCH configuration based on PCH policy
+
+  Copyright (c) 2019 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 <ConfigBlock/UsbConfig.h>
+
+#include "PchLimits.h"
+#include "ConfigBlock/PchGeneralConfig.h"
+#include "ConfigBlock/PcieRpConfig.h"
+#include "ConfigBlock/SataConfig.h"
+#include "ConfigBlock/IoApicConfig.h"
+#include "ConfigBlock/DmiConfig.h"
+#include "ConfigBlock/FlashProtectionConfig.h"
+#include "ConfigBlock/HdAudioConfig.h"
+#include "ConfigBlock/InterruptConfig.h"
+#include "ConfigBlock/IshConfig.h"
+#include "ConfigBlock/LanConfig.h"
+#include "ConfigBlock/LockDownConfig.h"
+#include "ConfigBlock/P2sbConfig.h"
+#include "ConfigBlock/PmConfig.h"
+#include "ConfigBlock/ScsConfig.h"
+#include "ConfigBlock/SerialIoConfig.h"
+#include "ConfigBlock/SerialIrqConfig.h"
+#include "ConfigBlock/ThermalConfig.h"
+#include "ConfigBlock/EspiConfig.h"
+#include "ConfigBlock/CnviConfig.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/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
new file mode 100644
index 0000000000..37b2301770
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
@@ -0,0 +1,59 @@
+/** @file
+  PCH configuration based on PCH policy
+
+  Copyright (c) 2019 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 "ConfigBlock/DciConfig.h"
+#include "ConfigBlock/WatchDogConfig.h"
+#include "ConfigBlock/PchTraceHubConfig.h"
+#include "ConfigBlock/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/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
new file mode 100644
index 0000000000..f5106ffebb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
@@ -0,0 +1,53 @@
+/** @file
+  PCH preserved MMIO resource definitions.
+
+  Copyright (c) 2019 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                      |
+  | 88 KB       | 0xFE020000  | 0xFE035FFF  | SerialIo BAR in ACPI mode     |
+  | 488 KB      | 0xFE036000  | 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     ///< 28MB
+#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         0x00016000     ///< 88KB
+#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_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
new file mode 100644
index 0000000000..8e1495d16f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
@@ -0,0 +1,23 @@
+/** @file
+  PCH Reset Platform Specific definitions.
+
+  Copyright (c) 2019 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_
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (3 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
                   ` (32 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds header files to Pch/Include/ConfigBlock.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h            |  69 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h             |  56 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h             |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h            |  40 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h |  54 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h         |  39 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h         | 178 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h            |  57 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h        |  58 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h        |  66 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h       |  58 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h          |  68 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h             |  57 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h             |  35 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h        |  70 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h             |  34 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h            |  49 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h      |  71 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h     |  36 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h          | 429 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h              | 311 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h            | 230 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h             |  63 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h        |  96 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h       |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h           |  52 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h         | 139 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h        |  33 ++
 28 files changed, 2534 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
new file mode 100644
index 0000000000..35fa125ba3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
@@ -0,0 +1,69 @@
+/** @file
+  CNVI policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gCnviConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CNVi Mode options
+**/
+typedef enum {
+  CnviModeDisabled = 0,
+  CnviModeAuto
+} CNVI_MODE;
+
+/**
+  CNVi MfUart1 connection options
+**/
+typedef enum {
+  CnviMfUart1Ish = 0,
+  CnviMfUart1SerialIo,
+  CnviBtUart1ExtPads,
+  CnviBtUart1NotConnected
+} CNVI_MFUART1_TYPE;
+
+
+/**
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Remove BtInterface and BtUartType.
+
+**/
+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;
+  /**
+    <b>(Test)</b> This option configures Uart type which connects to MfUart1
+    For production configuration ISH is the default, for tests SerialIO Uart0 or external pads can be used
+    Use CNVI_MFUART1_TYPE enum for selection
+    <b>CnviMfUart1Ish = MfUart1 over ISH Uart0</b>,
+    CnviMfUart1SerialIo = MfUart1 over SerialIO Uart2,
+    CnviBtUart1ExtPads = MfUart1 over exteranl pads,
+    CnviBtUart1NotConnected = MfUart1 not connected
+  **/
+  UINT32 MfUart1Type           :  2;
+  UINT32 RsvdBits              : 29;
+} PCH_CNVI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CNVI_CONFIG_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
new file mode 100644
index 0000000000..791546bdfe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
@@ -0,0 +1,56 @@
+/** @file
+  Dci policy
+
+  Copyright (c) 2019 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 1
+extern EFI_GUID gDciPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  ProbeTypeDisabled   = 0x0,
+  ProbeTypeDciOobDbc  = 0x1,
+  ProbeTypeDciOob     = 0x2,
+  ProbeTypeUsb3Dbc    = 0x3,
+  ProbeTypeXdp3       = 0x4,
+  ProbeTypeUsb2Dbc    = 0x5,
+  ProbeTypeMax
+} PLATFORM_DEBUG_CONSENT_PROBE_TYPE;
+
+/**
+  The PCH_DCI_PREMEM_CONFIG block describes policies related to Direct Connection Interface (DCI)
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    Platform Debug Consent
+    As a master switch to enable platform debug capability and relevant settings with specified probe type.
+    Note: DCI OOB (aka BSSB) uses CCA probe; [DCI OOB+DbC] and [USB2 DbC] have the same setting.
+    Refer to definition of PLATFORM_DEBUG_CONSENT_PROBE_TYPE
+    <b>0:Disabled</b>; 1:DCI OOB+DbC; 2:DCI OOB; 3:USB3 DbC; 4:XDP3/MIPI60 5:USB2 DbC;
+  **/
+  UINT32    PlatformDebugConsent  :  3;
+  /**
+    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>
+  **/
+  UINT32    DciUsb3TypecUfpDbg    :  2;
+  UINT32    RsvdBits              : 27;       ///< Reserved bits
+} PCH_DCI_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _DCI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
new file mode 100644
index 0000000000..03f83d9bf8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
@@ -0,0 +1,43 @@
+/** @file
+  DMI policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DMI_CONFIG_H_
+#define _DMI_CONFIG_H_
+
+#define DMI_CONFIG_REVISION 3
+extern EFI_GUID gDmiConfigGuid;
+
+
+#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>:
+  - Deprecate DmiAspm and add DmiAspmCtrl
+  <b>Revision 3</b>
+  - Added policy to enable/disable Central Write Buffer feature
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    @deprecated since revision 2
+  **/
+
+  UINT32     DmiAspm           :  1;
+  UINT32     PwrOptEnable      :  1;    ///< <b>0: Disable</b>; 1: Enable DMI Power Optimizer on PCH side.
+  UINT32     DmiAspmCtrl       :  8;    ///< ASPM configuration (PCH_PCIE_ASPM_CONTROL) on the PCH side of the DMI/OPI Link. Default is <b>PchPcieAspmAutoConfig</b>
+  UINT32     CwbEnable         :  1;    ///< <b>0: Disable</b>; Central Write Buffer feature configurable and disabled by default
+  UINT32     Rsvdbits          : 21;    ///< Reserved bits
+} PCH_DMI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _DMI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
new file mode 100644
index 0000000000..5de9b73397
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
@@ -0,0 +1,40 @@
+/** @file
+  Espi policy
+
+  Copyright (c) 2019 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 1
+extern EFI_GUID gEspiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to ESPI.
+**/
+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;
+  UINT32    RsvdBits              : 30;     ///< Reserved bits
+} PCH_ESPI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ESPI_CONFIG_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
new file mode 100644
index 0000000000..2a6c19de7e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
@@ -0,0 +1,54 @@
+/** @file
+  FlashProtection policy
+
+  Copyright (c) 2019 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
+
+/**
+  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 {
+  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;
+
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  PROTECTED_RANGE       ProtectRange[PCH_FLASH_PROTECTED_RANGES];
+} PCH_FLASH_PROTECTION_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _FLASH_PROTECTION_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
new file mode 100644
index 0000000000..2b32a21f54
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
@@ -0,0 +1,39 @@
+/** @file
+  GPIO device policy
+
+  Copyright (c) 2019 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
+
+} PCH_GPIO_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_GPIO_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
new file mode 100644
index 0000000000..a810d4f1fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
@@ -0,0 +1,178 @@
+/** @file
+  HDAUDIO policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _HDAUDIO_CONFIG_H_
+#define _HDAUDIO_CONFIG_H_
+
+#include <PchHda.h>
+
+#define HDAUDIO_PREMEM_CONFIG_REVISION 1
+#define HDAUDIO_CONFIG_REVISION 2
+#define HDAUDIO_DXE_CONFIG_REVISION 2
+
+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 (PCH_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.
+} PCH_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  {
+  PCH_HDA_VERB_TABLE_HEADER  Header;
+  UINT32 Data[];
+} HDAUDIO_VERB_TABLE;
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+/**
+  This structure contains the policies which are related to HD Audio device (cAVS).
+
+  <b>Revision 1:</b>
+  - Inital version.
+  <b>Revision 2:</b>
+  - Move DspEndpointDmic, DspEndpointBluetooth, DspEndpointI2s and DspFeatureMask to PCH_HDAUDIO_DXE_CONFIG
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1: Enable</b>
+  UINT32  Pme                   :  1;    ///< Azalia wake-on-ring, <b>0: Disable</b>; 1: Enable
+  UINT32  VcType                :  1;    ///< Virtual Channel Type Select: <b>0: VC0</b>, 1: VC1
+  UINT32  HdAudioLinkFrequency  :  4;    ///< HDA-Link frequency (PCH_HDAUDIO_LINK_FREQUENCY enum): <b>2: 24MHz</b>, 1: 12MHz, 0: 6MHz
+  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
+  /**
+    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  IDispCodecDisconnect  :  1;    ///< iDisplay Audio Codec disconnection, <b>0: Not disconnected, enumerable</b>; 1: Disconnected SDI, not enumerable
+  UINT32  CodecSxWakeCapability :  1;    ///< Capability to detect wake initiated by a codec in Sx (eg by modem codec), <b>0: Disable</b>; 1: Enable
+  /**
+    Audio Link Mode configuration bitmask.
+    Allows to configure enablement of the following interfaces: HDA-Link, DMIC, SSP, SoundWire.
+  **/
+  UINT32  AudioLinkHda          :  1;    ///< HDA-Link enablement: 0: Disable; <b>1: Enable</b>. Muxed with SSP0/SSP1/SNDW1
+  UINT32  AudioLinkDmic0        :  1;    ///< DMIC0 link enablement: 0: Disable; <b>1: Enable</b>. Muxed with SNDW4
+  UINT32  AudioLinkDmic1        :  1;    ///< DMIC1 link enablement: 0: Disable; <b>1: Enable</b>. Muxed with SNDW3
+  UINT32  AudioLinkSsp0         :  1;    ///< I2S/SSP0 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with HDA SDI0
+  UINT32  AudioLinkSsp1         :  1;    ///< I2S/SSP1 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with HDA SDI1/SNDW2
+  /**
+    I2S/SSP2 link enablement: <b>0: Disable</b>; 1: Enable.
+    @note Since the I2S/SSP2 pin set contains pads which are also used for CNVi purpose, enabling AudioLinkSsp2
+    is exclusive with CNVi is present.
+  **/
+  UINT32  AudioLinkSsp2         :  1;
+  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
+  /**
+    Soundwire Clock Buffer GPIO RCOMP adjustments based on bus topology:
+    <b>0: non-ACT</b> - 50 Ohm driver impedance when bus topology does not have the external AC termination;
+       1: ACT - 8 Ohm driver impedance when bus topology has the external AC termination.
+  **/
+  UINT32  SndwBufferRcomp       :  1;
+  UINT32  RsvdBits0             :  4;    ///< Reserved bits 0
+  UINT16  ResetWaitTimer;               ///< <b>(Test)</b> The delay timer after Azalia reset, the value is number of microseconds. Default is <b>600</b>.
+  UINT8   Rsvd0;                        ///< Reserved bytes, align to multiple 4
+  /**
+    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;
+  /**
+    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;
+} PCH_HDAUDIO_CONFIG;
+
+/**
+  This structure contains the premem 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  Enable                : 1;     ///< Intel HD Audio (Azalia) enablement: 0: Disable, <b>1: Enable</b>
+  UINT32  RsvdBits              : 31;    ///< Reserved bits 0
+} PCH_HDAUDIO_PREMEM_CONFIG;
+
+/**
+  This structure contains the DXE policies which are related to HD Audio device (cAVS).
+
+  <b>Revision 1:</b>
+  - Inital version.
+  <b>Revision 2:</b>
+  - Add NhltDefaultFlow option for disabling NHLT flow from Si code.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  /**
+    AudioDSP/iSST endpoints configuration exposed via NHLT ACPI table:
+  **/
+  UINT32  DspEndpointDmic       :  2;    ///< DMIC Select (PCH_HDAUDIO_DMIC_TYPE enum): 0: Disable; 1: 2ch array; <b>2: 4ch array</b>; 3: 1ch array
+  UINT32  DspEndpointBluetooth  :  1;    ///< Bluetooth enablement: <b>0: Disable</b>; 1: Enable
+  UINT32  DspEndpointI2s        :  1;    ///< I2S enablement: <b>0: Disable</b>; 1: Enable
+  UINT32  NhltDefaultFlow       :  1;    ///< Default Nhlt flow: 0: Disable, <b>1: Enable</b>
+  UINT32  RsvdBits1             : 27;    ///< Reserved bits 1
+  /**
+    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;
+} PCH_HDAUDIO_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HDAUDIO_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
new file mode 100644
index 0000000000..8c3186153c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
@@ -0,0 +1,57 @@
+/** @file
+  HSIO policy
+
+  Copyright (c) 2019 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
+#define HSIO_CONFIG_REVISION 1
+extern EFI_GUID gHsioPreMemConfigGuid; //@deprecated
+extern EFI_GUID gHsioConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_HSIO_PREMEM_CONFIG block provides HSIO message related settings. //@deprecated
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header //@deprecated
+
+  /**
+  <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 //@deprecated
+  **/
+  UINT32    ChipsetInitMessage :  1;
+  /**
+  <b>(Test)</b>
+  <b>0- Disable</b>
+  1- Enable When enabled, this is used to bypass the reset after ChipsetInit HECI message. //@deprecated
+  **/
+  UINT32    BypassPhySyncReset :  1;
+  UINT32    RsvdBits           : 30;
+} 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
new file mode 100644
index 0000000000..93131ea07a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
@@ -0,0 +1,58 @@
+/** @file
+  HSIO pcie policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _HSIO_PCIE_CONFIG_H_
+#define _HSIO_PCIE_CONFIG_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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
new file mode 100644
index 0000000000..a79542d657
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
@@ -0,0 +1,66 @@
+/** @file
+  Hsio Sata policy
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h
new file mode 100644
index 0000000000..788931b83d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h
@@ -0,0 +1,58 @@
+/** @file
+  Interrupt policy
+
+  Copyright (c) 2019 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  64       ///< Number of all PCH devices
+#define PCH_MAX_PXRC_CONFIG              8        ///< Number of PXRC registers in ITSS
+
+///
+/// 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                        PxRcConfig[PCH_MAX_PXRC_CONFIG];                 ///< Array which stores interrupt routing for 8259 controller
+  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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
new file mode 100644
index 0000000000..ce1d8f746d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
@@ -0,0 +1,68 @@
+/** @file
+  IoApic policy
+
+  Copyright (c) 2019 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 2
+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.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add Enable8254ClockGatingOnS3.
+
+**/
+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 PmcSet8254ClockGateState (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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
new file mode 100644
index 0000000000..d03ef377ce
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
@@ -0,0 +1,57 @@
+/** @file
+  ISH policy
+
+  Copyright (c) 2019 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)
+
+///
+/// The PCH_ISH_CONFIG block describes Integrated Sensor Hub device.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;     ///< Config Block Header
+  UINT32    SpiGpioAssign   :  1;   ///< ISH SPI GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    Uart0GpioAssign :  1;   ///< ISH UART0 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    Uart1GpioAssign :  1;   ///< ISH UART1 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    I2c0GpioAssign  :  1;   ///< ISH I2C0 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    I2c1GpioAssign  :  1;   ///< ISH I2C1 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    I2c2GpioAssign  :  1;   ///< ISH I2C2 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    Gp0GpioAssign   :  1;   ///< ISH GP_0 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp1GpioAssign   :  1;   ///< ISH GP_1 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp2GpioAssign   :  1;   ///< ISH GP_2 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp3GpioAssign   :  1;   ///< ISH GP_3 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp4GpioAssign   :  1;   ///< ISH GP_4 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp5GpioAssign   :  1;   ///< ISH GP_5 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp6GpioAssign   :  1;   ///< ISH GP_6 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp7GpioAssign   :  1;   ///< ISH GP_7 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    PdtUnlock       :  1;   ///< ISH PDT Unlock Msg: <b>0: False</b> 1: True
+  UINT32    RsvdBits0       : 17;   ///< Reserved Bits
+} PCH_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
+} PCH_ISH_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ISH_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
new file mode 100644
index 0000000000..6bf34f8fe7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
@@ -0,0 +1,35 @@
+/** @file
+  Lan policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _LAN_CONFIG_H_
+#define _LAN_CONFIG_H_
+
+#define LAN_CONFIG_REVISION 1
+extern EFI_GUID gLanConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  PCH intergrated LAN controller configuration settings.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Config Block Header
+  /**
+    Determines if enable PCH internal LAN, 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 register, 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
+} PCH_LAN_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LAN_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
new file mode 100644
index 0000000000..a3a08c3cf6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
@@ -0,0 +1,70 @@
+/** @file
+  Lock down policy
+
+  Copyright (c) 2019 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 RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the upper
+    and lower 128-byte bank of RTC RAM. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  RtcMemoryLock  :  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;
+  /**
+    <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      : 27;             ///< Reserved bits
+} PCH_LOCK_DOWN_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LOCK_DOWN_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
new file mode 100644
index 0000000000..6ee9fe2d75
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
@@ -0,0 +1,34 @@
+/** @file
+  Lpc policy
+
+  Copyright (c) 2019 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;
+  UINT32    RsvdBits                    : 31;     ///< Reserved bits
+} PCH_LPC_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LPC_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
new file mode 100644
index 0000000000..5e1971cb9c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
@@ -0,0 +1,49 @@
+/** @file
+  P2sb policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gP2sbConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to P2SB device.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Deprecate SbiUnlock policy.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    @deprecated from REVISION 2.
+    <b>(Test)</b>
+    This unlock the SBI lock bit to allow SBI after post time.
+    For CFL: <b>0: Lock SBI</b>; 1: Unlock SBI.
+    NOTE: Do not change this policy "SbiUnlock" unless its necessary.
+  **/
+  UINT32    SbiUnlock         :  1;
+  /**
+    <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          : 30;    ///< Reserved bits
+} PCH_P2SB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _P2SB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
new file mode 100644
index 0000000000..67f9a121ca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
@@ -0,0 +1,71 @@
+/** @file
+  PCH General policy
+
+  Copyright (c) 2019 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 3
+#define PCH_GENERAL_PREMEM_CONFIG_REVISION 1
+
+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 postmem general config block.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Remove SubSystemVendorId and SubSystemId.
+  <b>Revision 3</b>:
+  - Add LegacyIoLowLatency support.
+**/
+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 premem general config block.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+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    RsvdBits0       : 31;       ///< Reserved bits
+} PCH_GENERAL_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_GENERAL_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h
new file mode 100644
index 0000000000..36527a5af3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h
@@ -0,0 +1,36 @@
+/** @file
+  PCH Trace Hub policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_TRACEHUB_CONFIG_H_
+#define _PCH_TRACEHUB_CONFIG_H_
+
+#define PCH_TRACEHUB_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gPchTraceHubPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+///
+/// The PCH_TRACE_HUB_CONFIG block describes TraceHub settings for PCH.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  UINT32  EnableMode         :  2;       ///< <b>0 = Disable</b>; 1 = Target Debugger mode; 2 = Host Debugger mode
+  /**
+  Pch Trace hub memory buffer region size policy.
+  The avaliable memory size options are: <b>0:0MB (none)</b>, 1:1MB, 2:8MB, 3:64MB, 4:128MB, 5:256MB, 6:512MB.
+  Refer to TRACE_BUFFER_SIZE in TraceHubCommon.h for supported settings.
+  Note : Limitation of total buffer size (CPU + PCH) is 512MB.
+  **/
+  UINT32  MemReg0Size        :  8;
+  UINT32  MemReg1Size        :  8;
+  UINT32  RsvdBits0          : 14;       ///< Reserved bits
+} PCH_TRACE_HUB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _TRACEHUB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
new file mode 100644
index 0000000000..7d23fcd15f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
@@ -0,0 +1,429 @@
+/** @file
+  Pcie root port policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIE_CONFIG_H_
+#define _PCH_PCIE_CONFIG_H_
+
+#include <PchLimits.h>
+
+#define PCIE_RP_CONFIG_REVISION 3
+#define PCIE_RP_PREMEM_CONFIG_REVISION 1
+
+extern EFI_GUID gPcieRpConfigGuid;
+extern EFI_GUID gPcieRpPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+#define PCH_PCIE_SWEQ_COEFFS_MAX    5
+
+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;
+
+enum PCH_PCIE_SPEED {
+  PchPcieAuto,
+  PchPcieGen1,
+  PchPcieGen2,
+  PchPcieGen3
+};
+
+///
+/// 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
+};
+
+enum PCH_PCIE_COMPLETION_TIMEOUT {
+  PchPcieCompletionTO_Default,
+  PchPcieCompletionTO_50_100us,
+  PchPcieCompletionTO_1_10ms,
+  PchPcieCompletionTO_16_55ms,
+  PchPcieCompletionTO_65_210ms,
+  PchPcieCompletionTO_260_900ms,
+  PchPcieCompletionTO_1_3P5s,
+  PchPcieCompletionTO_4_13s,
+  PchPcieCompletionTO_17_64s,
+  PchPcieCompletionTO_Disabled
+};
+
+typedef enum {
+  PchPcieEqDefault      = 0,  ///< @deprecated since revision 3. Behaves as PchPcieEqHardware.
+  PchPcieEqHardware     = 1,  ///< Hardware equalization
+  PchPcieEqStaticCoeff  = 4   ///< Fixed equalization (requires Coefficient settings per lane)
+} PCH_PCIE_EQ_METHOD;
+
+/**
+  Represent lane specific PCIe Gen3 equalization parameters.
+**/
+typedef struct {
+  UINT8   Cm;                 ///< Coefficient C-1
+  UINT8   Cp;                 ///< Coefficient C+1
+  UINT8   Rsvd0[2];           ///< Reserved bytes
+} PCH_PCIE_EQ_LANE_PARAM, PCH_PCIE_EQ_PARAM;
+
+
+/**
+  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 {
+  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  ExtSync                         :  1;   ///< Indicate whether the extended synch is enabled. <b>0: Disable</b>; 1: Enable.
+  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>.
+  UINT32  RsvdBits0                       : 11;   ///< Reserved bits.
+  /**
+    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;
+  //
+  // 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 PCH_PCIE_MAX_PAYLOAD
+    Changes Max Payload Size Supported field in Device Capabilities of the root port.
+  **/
+  UINT32  MaxPayload                      :  2;
+  UINT32  RsvdBits1                       :  1;   ///< Reserved fields for future expansion w/o protocol change
+  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  RsvdBits3                       :  1;   ///< Placeholder for deleted field
+  /**
+    Determines each PCIE Port speed capability.
+    <b>0: Auto</b>; 1: Gen1; 2: Gen2; 3: Gen3 (see: PCH_PCIE_SPEED)
+  **/
+  UINT8   PcieSpeed;
+  /**
+    PCIe Gen3 Equalization Phase 3 Method (see PCH_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: PCH_PCIE_COMPLETION_TIMEOUT). Default is <b>PchPcieCompletionTO_Default</b>.
+  /**
+    The PCH pin assigned to device PERST# signal if available, zero otherwise.
+    This entry is used mainly in Gen3 software equalization flow. It is necessary for some devices
+    (mainly some graphic adapters) to successfully complete the software equalization flow.
+    See also DeviceResetPadActiveHigh
+  **/
+  UINT32  RsvdBytes0[2];                          ///< Reserved bytes
+  //
+  // Power Management
+  //
+  UINT8   Aspm;                                   ///< The ASPM configuration of the root port (see: PCH_PCIE_ASPM_CONTROL). Default is <b>PchPcieAspmAutoConfig</b> for CNP-LP B1 it is limited to <b>PchPcieAspmL1</b>.
+  UINT8   L1Substates;                            ///< The L1 Substates configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL). Default is <b>PchPcieL1SubstatesL1_1_2</b>.
+  UINT8   LtrEnable;                              ///< Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+  UINT8   LtrConfigLock;                          ///< <b>0: Disable</b>; 1: Enable.
+  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.
+  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>.
+  //
+  // Gen3 Equalization settings
+  //
+  UINT32  Uptp                :  4;               ///< <b>(Test)</b> Upstream Port Transmitter Preset used during Gen3 Link Equalization. Used for all lanes.  Default is <b>5</b>.
+  UINT32  Dptp                :  4;               ///< <b>(Test)</b> Downstream Port Transmiter Preset used during Gen3 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  /**
+    <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
+  **/
+  UINT32  ForceLtrOverride                :  1;
+  UINT32  EnableCpm                       :  1;               ///< Enables Clock Power Management; even if disabled, CLKREQ# signal can still be controlled by L1 PM substates mechanism
+  UINT32  PtmEnabled                      :  1;               ///< Enables PTM capability
+  UINT32  PcieRootPortGen2PllL1CgDisable  :  1;               ///< Disables Gen2PLL shutdown and L1 state controller power gating
+  UINT32  RsvdBits2                       :  6;               ///< Reserved Bits
+  /**
+    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;
+  UINT16  RsvdBytes1[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>:
+  - Init version
+  <b>Revision 2</b>:
+  - Add policy PcieRootPortGen2PllL1CgDisable in PCH_PCIE_ROOT_PORT_CONFIG.
+  <b>Revision 3</b>:
+  - Deleted all items related to PCIe Gen3 software equalization:
+      DeviceResetPad, DeviceResetPadActiveHigh policies and two values from PCH_PCIE_EQ_METHOD enum used for Gen3EqPh3Method field
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  ///
+  /// These members describe the configuration of each PCH PCIe root port.
+  ///
+  PCH_PCIE_ROOT_PORT_CONFIG         RootPort[PCH_MAX_PCIE_ROOT_PORTS];
+  ///
+  /// Configuration of PCIe source clocks
+  ///
+  PCH_PCIE_CLOCK                    PcieClock[PCH_MAX_PCIE_CLOCKS];
+  ///
+  /// 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).
+  ///
+  PCH_PCIE_EQ_LANE_PARAM            EqPh3LaneParam[PCH_MAX_PCIE_ROOT_PORTS];
+  ///
+  /// List of coefficients used during equalization (applicable to both software and hardware EQ)
+  ///
+  PCH_PCIE_EQ_PARAM                 SwEqCoeffList[PCH_PCIE_SWEQ_COEFFS_MAX];
+  PCH_PCIE_EQ_PARAM                 Rsvd0[3];
+  ///
+  /// <b>(Test)</b> This member describes whether PCIE root port Port 8xh Decode is enabled. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  EnablePort8xhDecode              :  1;
+  ///
+  /// <b>(Test)</b> The Index of PCIe Port that is selected for Port8xh Decode (0 Based)
+  ///
+  UINT32  PchPciePort8xhDecodePortIndex    :  5;
+  ///
+  /// 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  DisableRootPortClockGating       :  1;
+  ///
+  /// This member describes whether Peer Memory Writes are enabled on the platform. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  EnablePeerMemoryWrite            :  1;
+  /**
+    Compliance Test Mode shall be enabled when using Compliance Load Board.
+    <b>0: Disable</b>, 1: Enable
+  **/
+  UINT32  ComplianceTestMode               :  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;
+
+  UINT32  RsvdBits0                        : 22;
+  /**
+    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:
+    PCH_PCIE_DEVICE_OVERRIDE *PcieDeviceOverrideTablePtr;
+  **/
+  UINT32  PcieDeviceOverrideTablePtr;
+
+} PCH_PCIE_CONFIG;
+
+/**
+  The PCH_PCIE_RP_PREMEM_CONFIG block describes early configuration of the PCH PCI Express controllers
+  <b>Revision 1</b>:
+  - Init version
+  - Add RpEnable in premem phase.
+**/
+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;
+  UINT16                PcieImrSize;                           ///< PCIe IMR size in megabytes
+  UINT8                 PcieImrEnabled;                        ///< PCIe IMR. <b>0: Disable</b>; 1: Enable.
+  UINT8                 ImrRpSelection;                        ///< Index of PCIe root port that is selected for IMR (0 based)
+} PCH_PCIE_RP_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_PCIE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
new file mode 100644
index 0000000000..8748db5e1a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
@@ -0,0 +1,311 @@
+/** @file
+  Power Management policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PM_CONFIG_H_
+#define _PM_CONFIG_H_
+
+#define PM_CONFIG_REVISION 5
+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,
+} 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,
+  S0ixDisQAuto,
+  S0ixDisQMax,
+} S0IX_DISQ_PROBE_TYPE;
+
+typedef enum {
+  SlpS0OverrideDisabled  = 0x0,
+  SlpS0OverrideEnabled   = 0x1,
+  SlpS0OverrideAuto      = 0x2,
+  SlpS0OverrideMax
+} SLP_S0_OVERRIDE;
+
+/**
+  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>:
+  - Add PsOnEnable and PowerButtonDebounce.
+  <b>Revision 3</b>:
+  - Add CpuC10GatePinEnable in PCH_PM_CONFIG.
+  <b>Revision 4</b>:
+  - Add PmcDbgMsgEn.
+  - Removed PmcReadDisable in PCH_PM_CONFIG.
+  <b>Revision 5</b>:
+  - Add ModPhySusPgEnable
+  <b>Revision 6</b>:
+  - Add SlpS0WithGbeSupport
+**/
+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. 0: Disable; <b>1: Enable</b>
+  **/
+  UINT32                  LpcClockRun          :  1;         /// 0: Disable; <b>1: Enable</b>
+  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;
+  /**
+    Indicates whether SLP_S0# is to be asserted when PCH reaches idle state.
+    When set to one SLP_S0# will be asserted in idle state.
+    When set to zero SLP_S0# will not toggle and is always drivern high.
+    0:Disable, <b>1:Enable</b>
+
+    If a platform is using SLP_S0 to lower PCH voltage the below policy must be disabled.
+  **/
+  UINT32                  SlpS0Enable                  :  1;
+  /**
+    SLP_S0 Voltage Margining Runtime Control.
+    PCH VCCPRIM_CORE Voltage Margining is under ACPI control. Software in runtime
+    may change VCCPRIM_CORE supply voltage based on conditions like HDAudio power state
+    after SLP_S0# assertion. Enable VM runtime control requires ACPI VMON method
+    which will allow configuring VCCPRIM_CORE supply voltage. If this configuration is used
+    ACPI VMON method needs to be provided as it is not implemented in RC.
+    This setting is dependent on PMIC/VR type used on the platform.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  SlpS0VmRuntimeControl        :  1;
+  /**
+    SLP_S0 0.70V Voltage Margining Support.
+    Indicates whether SLP_S0# Voltage Margining supports setting PCH VCCPRIM_CORE down to 0.70V.
+    This setting is dependent on PMIC/VR type used on the platform.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  SlpS0Vm070VSupport           :  1;
+  /**
+    SLP_S0 0.75V Voltage Margining Support.
+    Indicates whether SLP_S0# Voltage Margining supports setting PCH VCCPRIM_CORE down to 0.75V.
+    This setting is dependent on PMIC/VR type used on the platform.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  SlpS0Vm075VSupport           :  1;
+  /**
+    Decide if SLP_S0# needs to be overriden (de-asserted) when system is in debug mode. This is available since CNP-B0.
+    Select 'Auto', it will be auto-configured according to probe type. Select 'Enabled' will disable SLP_S0# assertion whereas 'Disabled' will enable SLP_S0# assertion when debug is enabled.
+    This policy should keep 'Auto', other options are intended for advanced configuration only.
+    please refer to SLP_S0_OVERRIDE
+    0: Disable; 1: Enable; <b>2:Auto</b>
+  **/
+  UINT32                  SlpS0Override                :  2;
+  /**
+    SLP_S0# disqualify for debug prode
+    used to configure power management setting per debug probe to be disqualified from S0ix.
+    Reminder: USB3 DbC supports S0 only. DCI OOB (aka BSSB) uses CCA probe
+    Select 'Auto', it will be auto-configured according to probe type. 'No Change' will keep PMC default settings. Or select the desired debug probe type for S0ix Override settings.\nReminder: USB3 DbC supports S0 only. DCI OOB (aka BSSB) uses CCA probe.
+    Note: This policy should keep 'Auto', other options are intended for advanced configuration only.
+    please refer to S0IX_DISQ_PROBE_TYPE
+    0: No Probe; 1: DCI OOB; 2: USB2 DbC; <b>3:Auto</b>
+  **/
+  UINT32                  SlpS0DisQForDebug            :  3;
+  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;
+  /**
+    Enable/Disable SLP_S0 with GBE Support. This policy is ignored when GbE is not present.
+    0: Disable; <b>1: Enable</b>.
+    Default is 0 when paired with WHL V0 stepping CPU and 1 for all other CPUs.
+  **/
+  UINT32                  SlpS0WithGbeSupport          :  1;
+
+  UINT32                  RsvdBits1                    :  5;
+  /*
+    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;
+  UINT8                   Rsvd0[2];                             ///< Reserved bytes
+
+} PCH_PM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
new file mode 100644
index 0000000000..ce1013b05e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
@@ -0,0 +1,230 @@
+/** @file
+  Sata policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gSataConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum  {
+  PchSataModeAhci,
+  PchSataModeRaid,
+  PchSataModeMax
+} PCH_SATA_MODE;
+
+typedef enum {
+  PchSataOromDelay2sec,
+  PchSataOromDelay4sec,
+  PchSataOromDelay6sec,
+  PchSataOromDelay8sec
+} PCH_SATA_OROM_DELAY;
+
+typedef enum {
+  PchSataSpeedDefault,
+  PchSataSpeedGen1,
+  PchSataSpeedGen2,
+  PchSataSpeedGen3
+} PCH_SATA_SPEED;
+
+typedef enum {
+  PchSataRstMsix,
+  PchSataRstMsi,
+  PchSataRstLegacy
+} PCH_SATA_RST_INTERRUPT;
+
+typedef enum {
+  PchSataRaidClient,
+  PchSataRaidAlternate,
+  PchSataRaidServer
+} PCH_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  RsvdBits0        :  9;                  ///< Reserved fields for future expansion w/o protocol change
+} PCH_SATA_PORT_CONFIG;
+
+/**
+  Rapid Storage Technology settings.
+**/
+typedef struct {
+  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  : PCH_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
+  /**
+    This option allows to configure SATA controller device ID while in RAID mode.
+    Refer to PCH_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
+  **/
+  UINT32  RaidDeviceId       :  2;
+  /**
+    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>
+  **/
+  UINT32  SataRstInterrupt   :  2;
+  UINT32  RsvdBits0          : 13;         ///< Reserved Bits
+} PCH_SATA_RST_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;
+
+/**
+  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, the assignments are as below:
+    i.)   RST PCIe Storage Cycle Router 2 -> RP5 - RP8
+    ii.)  RST PCIe Storage Cycle Router 3 -> RP9 - RP12
+
+    i.)   RST PCIe Storage Cycle Router 1 -> RP9  - RP12
+    ii.)  RST PCIe Storage Cycle Router 2 -> RP13 - RP16
+    iii.) RST PCIe Storage Cycle Router 3 -> RP17 - RP20
+  **/
+  UINT32   RstPcieStoragePort     :  5;
+  UINT32   RsvdBits0              :  2; ///< Reserved bit
+  /**
+    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   RsvdBits1              : 16; ///< Reserved bits
+
+  UINT32   Rsvd0[2];                    ///< Reserved bytes
+} PCH_RST_PCIE_STORAGE_CONFIG;
+
+/**
+  The PCH_SATA_CONFIG block describes the expected configuration of the SATA controllers.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add CpuAttachedStorage in PCH_SATA_RST_CONFIG.
+**/
+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>.
+  ///
+  UINT32                        Enable          :  1;
+  UINT32                        TestMode        :  1;       ///< <b>(Test)</b> <b>0: Disable</b>; 1: Allow entrance to the PCH SATA test modes
+  UINT32                        SalpSupport     :  1;       ///< 0: Disable; <b>1: Enable</b> Aggressive Link Power Management
+  UINT32                        PwrOptEnable    :  1;       ///< 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
+  **/
+  UINT32                        EsataSpeedLimit :  1;
+  UINT32                        LedEnable       :  1;       ///< SATA LED indicates SATA controller activity. 0: Disable; <b>1: Enable</b> SATA LED.
+  UINT32                        RsvdBits0       : 26;       ///< Reserved bits
+
+  /**
+    Determines the system will be configured to which SATA mode (PCH_SATA_MODE). Default is <b>PchSataModeAhci</b>.
+  **/
+  PCH_SATA_MODE                 SataMode;
+  /**
+    Indicates the maximum speed the SATA controller can support
+    <b>0h: PchSataSpeedDefault</b>; 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2); 3h: 6 Gb/s (Gen 1)
+  **/
+  PCH_SATA_SPEED                SpeedLimit;
+  /**
+    This member configures the features, property, and capability for each SATA port.
+  **/
+  PCH_SATA_PORT_CONFIG          PortSettings[PCH_MAX_SATA_PORTS];
+  PCH_SATA_RST_CONFIG           Rst;                        ///< Setting applicable to Rapid Storage Technology
+  /**
+    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
+  **/
+  PCH_RST_PCIE_STORAGE_CONFIG   RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
+  /**
+    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;
+} PCH_SATA_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SATA_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
new file mode 100644
index 0000000000..1e91143b93
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
@@ -0,0 +1,63 @@
+/** @file
+  Scs policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SCS_CONFIG_H_
+#define _SCS_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define SCS_CONFIG_REVISION 2
+extern EFI_GUID gScsConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  DriverStrength33Ohm = 0,
+  DriverStrength40Ohm,
+  DriverStrength50Ohm
+} PCH_SCS_EMMC_DRIVER_STRENGTH;
+
+/**
+  The PCH_SCS_CONFIG block describes Storage and Communication Subsystem (SCS) settings for PCH.
+
+  <b>Revision 1</b>:
+  - Initial version
+  <b>Revision 2</b>:
+  - Add policy SdCardPowerEnableActiveHigh
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+
+  UINT32    ScsEmmcEnabled                :  2;   ///< Determine if eMMC is enabled - 0: Disabled, <b>1: Enabled</b>.
+  UINT32    ScsEmmcHs400Enabled           :  1;   ///< Determine eMMC HS400 Mode if ScsEmmcEnabled - <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    ScsEmmcHs400TuningRequired    :  1;
+  UINT32    ScsEmmcHs400DllDataValid      :  1;   ///< Set if HS400 Tuning Data Valid
+  UINT32    ScsEmmcHs400RxStrobeDll1      :  7;   ///< Rx Strobe Delay Control - Rx Strobe Delay DLL 1 (HS400 Mode)
+  UINT32    ScsEmmcHs400TxDataDll         :  7;   ///< Tx Data Delay Control 1 - Tx Data Delay (HS400 Mode)
+  UINT32    ScsEmmcHs400DriverStrength    :  3;   ///< I/O driver strength: 0 - 33 Ohm, <b>1 - 40 Ohm</b>, 2 - 50 Ohm
+  /**
+    Sd Card Controler 0: Disable; <b>1: Enable</b>.
+    For Desktop sku, the SD Card Controller POR should be disabled. <b> 0:Disable </b>.
+  **/
+  UINT32    ScsSdcardEnabled              :  1;
+  UINT32    ScsUfsEnabled                 :  1;   ///< Determine if Ufs is enabled 0: Disabled 1: Enabled
+  UINT32    SdCardPowerEnableActiveHigh   :  1;   ///< Determine SD_PWREN# polarity 0: Active low, <b>1: Active high</b>
+  UINT32    RsvdBits                      :  7;
+  UINT32    Rsvd0;                                ///< Reserved bytes
+} PCH_SCS_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SCS_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
new file mode 100644
index 0000000000..73dfd17c47
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
@@ -0,0 +1,96 @@
+/** @file
+  Serial IO policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gSerialIoConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_SERIAL_IO_CONFIG block provides the configurations to set the Serial IO controllers
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add I2cPadsTermination
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                             ///< Config Block Header
+  /**
+       0: Disabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - Device will be disabled in PSF
+          - !important! If given device is Function 0 and not all other LPSS functions on given device
+                        are disabled, then 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: Pci</b>;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be enabled in PSF
+          - Only Bar 0 will be enabled
+       2: Acpi;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+    @note Intel does not provide Windows SerialIo drivers for this mode
+       3: Hidden;
+          Designated for Kernel Debug and Legacy UART configuartion, might also be used for IO Expander on I2C
+          - Device is placed in D0
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+          - !important! In this mode UART will work in 16550 Legacy 8BIT Mode, it's resources will be assigned to mother board through ACPI (PNP0C02)
+    @note Considering the PcdSerialIoUartDebugEnable and PcdSerialIoUartNumber for all SerialIo UARTx,
+          the PCD is more meaningful to represent the board design. It means, if PcdSerialIoUartDebugEnable is not 0,
+          the board is designed to use the SerialIo UART for debug message and the PcdSerialIoUartNumber is dedicated
+          to be Debug UART usage. Therefore, it should grayout the option from setup menu since no other options
+          available for this UART controller on this board, and also override the policy default accordingly.
+          While PcdSerialIoUartDebugEnable is 0, then it's allowed to configure the UART controller by policy.
+  **/
+  UINT8  DevMode[PCH_MAX_SERIALIO_CONTROLLERS];
+  UINT8  SpiCsPolarity[PCH_MAX_SERIALIO_SPI_CONTROLLERS];   ///< Selects SPI ChipSelect signal polarity, <b>0=active low</b>.
+  UINT8  UartHwFlowCtrl[PCH_MAX_SERIALIO_UART_CONTROLLERS]; ///< Enables UART hardware flow control, CTS and RTS lines, <b>0:disabled</b>, 1:enabled
+  /**
+    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  I2cPadsTermination[PCH_MAX_SERIALIO_I2C_CONTROLLERS];
+  /**
+    UART device for debug purpose. 0:UART0, 1: UART1, <b>2:UART2</b>
+    @note If CNVi solution is on the platform and UART0 is selected as BT Core interface,
+          UART0 cannot be used for debug purpose.
+  **/
+  UINT32 DebugUartNumber           :  2;
+  UINT32 EnableDebugUartAfterPost  :  1;                    ///< Enable debug UART controller after post. 0: diabled, <b>1: enabled</b>
+  /**
+    <b>0: default pins</b>; 1: pins muxed with CNV_BRI/RGI
+    UART0 can be configured to use two different sets of pins:
+    This setting gives flexibility to use UART0 functionality on other pins when
+    default ones are used for a different purpose.
+    @note Since the second pin set contains pads which are also used for CNVi purpose, setting Uart0PinMuxing
+    is exclusive with CNVi being enabled.
+  **/
+  UINT32 Uart0PinMuxing            :  1;
+  UINT32 RsvdBits0                 : 28;
+} PCH_SERIAL_IO_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SERIAL_IO_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
new file mode 100644
index 0000000000..7ccfe65428
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
@@ -0,0 +1,43 @@
+/** @file
+  Serial IRQ policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SERIAL_IRQ_CONFIG_H_
+#define _SERIAL_IRQ_CONFIG_H_
+
+#define SERIAL_IRQ_CONFIG_REVISION 1
+extern EFI_GUID gSerialIrqConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  PchQuietMode,
+  PchContinuousMode
+} PCH_SIRQ_MODE;
+///
+/// Refer to PCH EDS for the details of Start Frame Pulse Width in Continuous and Quiet mode
+///
+typedef enum {
+  PchSfpw4Clk,
+  PchSfpw6Clk,
+  PchSfpw8Clk
+} PCH_START_FRAME_PULSE;
+
+///
+/// The PCH_LPC_SIRQ_CONFIG block describes the expected configuration of the PCH for Serial IRQ.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT32                SirqEnable      :  1;     ///< Determines if enable Serial IRQ. 0: Disable; <b>1: Enable</b>.
+  UINT32                SirqMode        :  2;     ///< Serial IRQ Mode Select. Refer to PCH_SIRQ_MODE for each value. <b>0: quiet mode</b> 1: continuous mode.
+  UINT32                StartFramePulse :  3;     ///< Start Frame Pulse Width. Refer to PCH_START_FRAME_PULSE for each value. Default is <b>PchSfpw4Clk</b>.
+  UINT32                RsvdBits0       : 26;     ///< Reserved bits
+} PCH_LPC_SIRQ_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SERIAL_IRQ_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
new file mode 100644
index 0000000000..d96cf9f6cd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
@@ -0,0 +1,52 @@
+/** @file
+  Smbus policy
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
new file mode 100644
index 0000000000..d3ea563f95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
@@ -0,0 +1,139 @@
+/** @file
+  Thermal policy
+
+  Copyright (c) 2019 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;
+
+/**
+  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
+  **/
+  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 PCH_THERMAL_CONFIG block describes the expected configuration of the PCH for Thermal.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    This locks down "SMI Enable on Alert Thermal Sensor Trip". 0: Disabled, 1: <b>Enabled</b>.
+  **/
+  UINT32  TsmicLock               :  1;
+  UINT32  PchHotEnable            :  1; ///< Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: <b>Disabled<b>, 1: Enabled.
+  UINT32  RsvdBits0               : 30;
+  /**
+    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;
+  /**
+    This field decides the temperature, default is <b>0x154</b>.
+    The recommendation is the same as Cat Trip point.
+  **/
+  UINT16                    PchHotLevel;
+  UINT8                     Rsvd0[6];
+} PCH_THERMAL_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _THERMAL_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h
new file mode 100644
index 0000000000..78e4497d90
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  WatchDog policy
+
+  Copyright (c) 2019 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_
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (4 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
                   ` (31 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds the following header files:
 * Pch/Include/library

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h         |  27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h             |  24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h     |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h           | 265 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h             | 788 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h       | 166 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h            |  33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h | 371 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h          | 141 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h           |  36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h          | 109 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h          | 407 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h        | 105 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h           | 226 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h           |  45 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h        | 114 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h         |  24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h     | 116 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h      | 240 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h  | 111 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h    |  23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h     | 121 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h              | 207 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h             |  76 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h           |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h   |  98 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h              |  23 +
 27 files changed, 3976 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
new file mode 100644
index 0000000000..ee77334ecb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
@@ -0,0 +1,27 @@
+/** @file
+  Header file for BiosLockLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BIOSLOCK_LIB_H_
+#define _BIOSLOCK_LIB_H_
+
+/**
+  Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable In SMM.STS).
+  When this is set, attempts to write the WPD (Write Protect Disable) bit in PCH
+  will cause a SMI which will allow the BIOS to verify that the write is from a valid source.
+
+  Bios should always enable LockDownConfig.BiosLock policy to set Bios Lock bit in FRC.
+  If capsule udpate is enabled, it's expected to not do BiosLock by setting BiosLock policy disable
+  so it can udpate BIOS region.
+  After flash update, it should utilize this lib to do BiosLock for security.
+**/
+VOID
+BiosLockEnable (
+  VOID
+  );
+
+#endif // _BIOSLOCK_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
new file mode 100644
index 0000000000..f406e0d929
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
@@ -0,0 +1,24 @@
+/** @file
+  Header file for CnviLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CNVI_LIB_H_
+#define _CNVI_LIB_H_
+
+/**
+  Check if CNVi is present.
+
+  @retval TRUE                    CNVi is enabled
+  @retval FALSE                   CNVi is disabled
+
+**/
+BOOLEAN
+CnviIsPresent (
+  VOID
+  );
+
+#endif // _CNVI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
new file mode 100644
index 0000000000..4d1ed91f7e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
@@ -0,0 +1,58 @@
+/** @file
+  Prototype of the DxePchPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_POLICY_LIB_H_
+#define _DXE_PCH_POLICY_LIB_H_
+
+#include <Protocol/PchPolicy.h>
+
+/**
+  This function prints the DXE phase policy.
+
+  @param[in] PchPolicy    - PCH DXE Policy protocol
+**/
+VOID
+PchPrintPolicyProtocol (
+  IN  PCH_POLICY_PROTOCOL         *PchPolicy
+  );
+
+/**
+  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 Policy 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      **PchPolicy
+  );
+
+/**
+  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] PchPolicy                  The pointer to PCH 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
+  );
+
+#endif // _DXE_PCH_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
new file mode 100644
index 0000000000..a6ce032eba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
@@ -0,0 +1,265 @@
+/** @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_H_", "_PCH_LP_"
+    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GBE_MDI_LIB_H_
+#define _GBE_MDI_LIB_H_
+
+//
+//
+//      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)
+#define MDI_REG_SHIFT(x)                              (x << 16)
+#define R_PHY_MDI_PHY_REG_DATA_READ_WRITE             0x00120000
+// LAN PHY MDI registers and bits
+//
+
+//
+// Page 769 Port Control Registers
+// 6020h (769 * 32)
+//
+#define PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS        769
+
+//
+//  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/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
new file mode 100644
index 0000000000..25def24fca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
@@ -0,0 +1,788 @@
+/** @file
+  Header file for GpioLib.
+  All function in this library is available for PEI, DXE, and SMM
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_LIB_H_
+#define _GPIO_LIB_H_
+
+#include <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 Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetHostSwOwnershipForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *HostSwRegVal
+  );
+
+/**
+  This procedure will get GPIO Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioSetHostSwOwnershipForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       HostSwRegVal
+  );
+
+/**
+  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 set 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 GpioSetGroupDwToGpeDwX()
+
+  @param[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  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
+GpioSetGroupToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2
+  );
+
+/**
+  This procedure will set 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[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupDwForGpeDw0    DW of pins to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  GroupDwForGpeDw1    DW of pins to be mapped to GPE_DW1
+  @param[in]  GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
+  @param[in]  GroupDwForGpeDw2    DW of pins to be mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetGroupDwToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN UINT32                    GroupDwForGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN UINT32                    GroupDwForGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2,
+  IN 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] Data                GPE STS data
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiGpeSts (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32*                  Data
+  );
+
+/**
+  This procedure is used to lock all GPIO pads except the ones
+  which were requested during their configuration to be left unlocked.
+  This function must be called before BIOS_DONE - before POSTBOOT_SAI is enabled.
+    FSP - call this function from wrapper before transition to FSP-S
+    UEFI/EDK - call this function before EndOfPei event
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioLockPads (
+  VOID
+  );
+
+/**
+  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
+  );
+
+#endif // _GPIO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
new file mode 100644
index 0000000000..9956c60dd5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
@@ -0,0 +1,166 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_NATIVE_LIB_H_
+#define _GPIO_NATIVE_LIB_H_
+
+#include <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
+  );
+
+/**
+  This function checks if SATA GP pin is enabled
+
+  @param[in]  SataCtrlIndex       SATA Controller Index
+  @param[in]  SataPort            SATA port number
+
+  @retval TRUE                    SATA GPx is enabled (pad is in required native mode)
+          FALSE                   SATA GPx is not enabled
+**/
+BOOLEAN
+GpioIsSataGpEnabled (
+  IN  UINT32          SataCtrlIndex,
+  IN  UINTN           SataPort
+  );
+
+#endif // _GPIO_NATIVE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
new file mode 100644
index 0000000000..6ef0d08774
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
@@ -0,0 +1,33 @@
+/** @file
+  Header file for OC WDT Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _OC_WDT_LIB_H_
+#define _OC_WDT_LIB_H_
+
+/**
+  Check for unexpected reset.
+  If there was an unexpected reset, enforces WDT expiration.
+  Stops watchdog.
+**/
+VOID
+OcWdtResetCheck (
+  VOID
+  );
+
+/**
+  This function install WDT PPI
+
+  @retval EFI_STATUS  Results of the installation of the WDT PPI
+**/
+EFI_STATUS
+EFIAPI
+OcWdtInit (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
new file mode 100644
index 0000000000..7b6c82d390
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
@@ -0,0 +1,371 @@
+/** @file
+  Header file for PchCycleDecodingLib.
+
+  Copyright (c) 2019 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_
+
+/**
+  Set PCH TCO base address.
+  This cycle decoding is allowed to set when DMIC.SRL is 0.
+  Programming steps:
+  1. set Smbus PCI offset 54h [8] to enable TCO base address.
+  2. program Smbus PCI offset 50h [15:5] to TCO base address.
+  3. set Smbus PCI offset 54h [8] to enable TCO base address.
+  4. program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [Smbus PCI offset 50h[15:5], 1].
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchTcoBaseSet (
+  IN  UINT16                            Address
+  );
+
+/**
+  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
+#define PCH_H_ESPI_GEN_IO_RANGE_MAX     PCH_LPC_GEN_IO_RANGE_MAX  // @deprecated. Keep it here for backward compatibility.
+
+///
+/// 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 eSPI CS1# generic IO range decoding.
+  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 eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enable.
+  2. Program eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @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               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeSet (
+  IN  UINT16                            Address,
+  IN  UINTN                             Length
+  );
+
+/**
+  Get PCH LPC/eSPI generic IO range list.
+  This function returns a list of base address, length, and enable for all LPC/eSPI generic IO range registers.
+
+  @param[out] LpcGenIoRangeList         Return all LPC/eSPI generic IO range register status.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchLpcGenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *LpcGenIoRangeList
+  );
+
+/**
+  Get PCH eSPI CS1# generic IO range list.
+  This function returns a list of base address, length, and enable for all eSPI CS1# generic IO range registers.
+
+  @param[out] GenIoRangeList            eSPI generic IO range registers.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
+  );
+
+/**
+  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
+  );
+
+/**
+  @deprecated. Keep this for backward compatibility.
+  It's replaced by PchEspiCs1MemRangeSet.
+**/
+EFI_STATUS
+PchEspiMemRange2Set (
+  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
+  );
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port.
+  System BIOS is likely to do this very soon after reset before PCI bus enumeration, it must ensure that
+  the IO Base Address field (PCIe:1Ch[7:4]) contains a value greater than the IO Limit field (PCIe:1Ch[15:12])
+  before setting the IOSE bit. Otherwise the bridge will positively decode IO range 000h - FFFh by its default
+  IO range values.
+  This cycle decoding is allowed to set when DMIC.SRL is 0.
+  Programming steps:
+  1. Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest ID of RP.
+  2. Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'. Use byte write on GCS+1 and leave the BILD bit which is RWO.
+  3. Program IOSE bit of PCIE:Reg04h[0] to '1'  for PCH to send such IO cycles to PCIe bus for subtractive decoding.
+
+  @param[in] RpPhyNumber                PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoPort80DecodeSet (
+  IN  UINTN                             RpPhyNumber
+  );
+
+/**
+  Get IO APIC registers base address.
+
+  @param[out] IoApicBase                Buffer of IO APIC register 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/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
new file mode 100644
index 0000000000..c1d3c50ead
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
@@ -0,0 +1,141 @@
+/** @file
+  Header file for PchEspiLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_ESPI_LIB_H_
+#define _PCH_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 // _PEI_DXE_SMM_PCH_ESPI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
new file mode 100644
index 0000000000..2a4dc986f4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
@@ -0,0 +1,36 @@
+/** @file
+  Header file for PchGbeLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_GBE_LIB_H_
+#define _PCH_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
+PchIsGbeRegionValid (
+  VOID
+  );
+
+
+/**
+  Check whether LAN controller is enabled in the platform.
+
+  @retval TRUE                    GbE is enabled
+  @retval FALSE                   GbE is disabled
+**/
+BOOLEAN
+PchIsGbePresent (
+  VOID
+  );
+
+#endif // _PCH_GBE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
new file mode 100644
index 0000000000..4f93f44120
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
@@ -0,0 +1,109 @@
+/** @file
+  Header file for PchHsioLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HSIO_LIB_H_
+#define _PCH_HSIO_LIB_H_
+
+/**
+  Represents HSIO lane
+**/
+typedef struct {
+  UINT8        Index; ///< Lane index
+  UINT8        Pid;   ///< Sideband ID
+  UINT16       Base;  ///< Sideband base address
+} HSIO_LANE;
+
+/**
+  The function returns the Port Id and lane owner for the specified lane
+
+  @param[in]  PhyMode             Phymode that needs to be checked
+  @param[out] Pid                 Common Lane End Point ID
+  @param[out] LaneOwner           Lane Owner
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid lane number
+**/
+EFI_STATUS
+EFIAPI
+PchGetLaneInfo (
+  IN  UINT32                            LaneNum,
+  OUT UINT8                             *PortId,
+  OUT UINT8                             *LaneOwner
+  );
+
+/**
+  Get HSIO lane representation needed to perform any operation on the lane.
+
+  @param[in]  LaneIndex  Number of the HSIO lane
+  @param[out] HsioLane   HSIO lane representation
+**/
+VOID
+HsioGetLane (
+  IN   UINT8       LaneIndex,
+  OUT  HSIO_LANE   *HsioLane
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  PcieLaneIndex             PCIE Root Port Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetPcieLaneNum (
+  UINT32              PcieLaneIndex,
+  UINT8               *LaneNum
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  SataLaneIndex             Sata Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetSataLaneNum (
+  UINT32              SataLaneIndex,
+  UINT8               *LaneNum
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  Usb3LaneIndex             USB3 Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetUsb3LaneNum (
+  UINT32              Usb3LaneIndex,
+  UINT8               *LaneNum
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[out] LaneNum                   GBE Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetGbeLaneNum (
+  UINT8               *LaneNum
+  );
+
+#endif // _PCH_HSIO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
new file mode 100644
index 0000000000..94a8204fa5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
@@ -0,0 +1,407 @@
+/** @file
+  Header file for PchInfoLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INFO_LIB_H_
+#define _PCH_INFO_LIB_H_
+
+#include <PchHda.h>
+
+typedef UINT8 PCH_STEPPING;
+#define PCH_A0                0x00
+#define PCH_A1                0x01
+#define PCH_B0                0x10
+#define PCH_B1                0x11
+#define PCH_C0                0x20
+#define PCH_C1                0x21
+#define PCH_D0                0x30
+#define PCH_D1                0x31
+#define PCH_STEPPING_MAX      0xFF
+
+typedef UINT8 PCH_SERIES;
+#define PCH_H                   1
+#define PCH_LP                  2
+#define PCH_SERVER              0x80
+#define PCH_UNKNOWN_SERIES      0xFF
+
+typedef UINT8 PCH_GENERATION;
+#define CNL_PCH                 3
+#define CDF_PCH                 0x80
+#define PCH_UNKNOWN_GENERATION  0xFF
+
+typedef enum {
+  RstUnsupported  = 0,
+  RstPremium,
+  RstOptane,
+  RstMaxMode
+} RST_MODE;
+
+/**
+  Return LPC Device Id
+
+  @retval PCH_LPC_DEVICE_ID         PCH Lpc Device ID
+**/
+UINT16
+PchGetLpcDid (
+  VOID
+  );
+
+/**
+  Return Pch stepping type
+
+  @retval PCH_STEPPING            Pch stepping type
+**/
+PCH_STEPPING
+PchStepping (
+  VOID
+  );
+
+/**
+  Determine if PCH is supported
+
+  @retval TRUE                    PCH is supported
+  @retval FALSE                   PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+  VOID
+  );
+
+/**
+  Return Pch Series
+
+  @retval PCH_SERIES                Pch Series
+**/
+PCH_SERIES
+PchSeries (
+  VOID
+  );
+
+/**
+  Check if this is PCH LP series
+
+  @retval TRUE                It's PCH LP series
+  @retval FALSE               It's not PCH LP series
+**/
+BOOLEAN
+IsPchLp (
+  VOID
+  );
+
+/**
+  Check if this is PCH H series
+
+  @retval TRUE                It's PCH H series
+  @retval FALSE               It's not PCH H series
+**/
+BOOLEAN
+IsPchH (
+  VOID
+  );
+
+/**
+  Check if this is Server PCH
+
+  @retval TRUE                It's a Server PCH
+  @retval FALSE               It's not a Server PCH
+**/
+BOOLEAN
+IsPchServer (
+  VOID
+  );
+
+/**
+  Return Pch Generation
+
+  @retval PCH_GENERATION            Pch Generation
+**/
+PCH_GENERATION
+PchGeneration (
+  VOID
+  );
+
+/**
+  Check if this is CDF PCH generation
+
+  @retval TRUE                It's CDF PCH
+  @retval FALSE               It's not CDF PCH
+**/
+BOOLEAN
+IsCdfPch (
+  VOID
+  );
+
+/**
+  @retval TRUE                It's CNL PCH
+  @retval FALSE               It's not CNL PCH
+**/
+BOOLEAN
+IsCnlPch (
+  VOID
+  );
+
+/**
+  Check if this is Server SKU
+
+  @retval TRUE                It's PCH Server SKU
+  @retval FALSE               It's not PCH Server SKU
+**/
+BOOLEAN
+IsPchServerSku (
+  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 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 Maximum Usb3 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb3PortNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Serial IO controllers number
+
+  @retval Pch Maximum Serial IO controllers number
+**/
+UINT8
+GetPchMaxSerialIoControllersNum (
+  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
+  );
+
+#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 (
+  );
+
+/**
+  Get PCH Sku ASCII string
+  The return string is zero terminated.
+
+  @retval Static ASCII string of PCH Sku
+**/
+CHAR8*
+PchGetSkuStr (
+  VOID
+  );
+
+/**
+  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 UFS controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchUfsSupported  (
+  VOID
+  );
+
+/**
+  Gets the maximum number of UFS controller supported by this chipset.
+
+  @return Number of supported UFS controllers
+**/
+UINT8
+PchGetMaxUfsNum (
+  VOID
+  );
+
+/**
+  Get RST mode supported by the silicon
+
+  @retval RST_MODE    RST mode supported by silicon
+**/
+RST_MODE
+PchGetSupportedRstMode (
+  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 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 PCH_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
+  );
+
+#endif // _PCH_INFO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
new file mode 100644
index 0000000000..7c26f6939e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
@@ -0,0 +1,105 @@
+/** @file
+  Header file for PchPcieRpLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIERP_LIB_H_
+#define _PCH_PCIERP_LIB_H_
+
+#define RST_PCIE_STORAGE_CR_1                       0
+#define RST_PCIE_STORAGE_CR_2                       1
+#define RST_PCIE_STORAGE_CR_3                       2
+#define RST_PCIE_STORAGE_CR_INVALID                 99
+
+typedef struct {
+  UINT8 DevNum;
+  UINT8 Pid;
+  UINT8 RpNumBase;
+} PCH_PCIE_CONTROLLER_INFO;
+
+/**
+  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
+  );
+
+/**
+  Check the RST PCIe Storage Cycle Router number according to the root port number and PCH type
+
+  @param[in] RootPortNum  Root Port Number
+
+  @return  The RST PCIe Storage Cycle Router Number
+**/
+UINT8
+RstGetCycleRouterNumber (
+  IN  UINT32                   RootPortNum
+  );
+
+#endif // _PCH_PCIERP_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
new file mode 100644
index 0000000000..2d57087c6b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
@@ -0,0 +1,226 @@
+/** @file
+  Header file for PchPcrLib.
+
+  Copyright (c) 2019 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 base address (defined in PchReservedResources.h)
+///
+//#define PCH_PCR_BASE_ADDRESS            0xFD000000
+//#define PCH_PCR_MMIO_SIZE               0x01000000
+/**
+  Definition for PCR address
+  The PCR address is used to the PCR MMIO programming
+**/
+#define PCH_PCR_ADDRESS(Pid, Offset)    (PCH_PCR_BASE_ADDRESS | ((UINT8)(Pid) << 16) | (UINT16)(Offset))
+
+/**
+  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
+  );
+
+#endif // _PCH_PCR_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
new file mode 100644
index 0000000000..36a0adb56f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
@@ -0,0 +1,45 @@
+/** @file
+  Header file for PchPmcLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PMC_LIB_H_
+#define _PCH_PMC_LIB_H_
+
+typedef enum {
+  WarmBoot          = 1,
+  ColdBoot,
+  PwrFlr,
+  PwrFlrSys,
+  PwrFlrPch,
+  PchPmStatusMax
+} PCH_PM_STATUS;
+
+/**
+  Query PCH to determine the Pm Status
+
+  @param[in] PmStatus - The Pch Pm Status to be probed
+
+  @retval Status TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+  PCH_PM_STATUS PmStatus
+  );
+
+/**
+  Funtion to check if Battery lost or CMOS cleared.
+
+  @reval TRUE  Battery is always present.
+  @reval FALSE CMOS is cleared.
+**/
+BOOLEAN
+EFIAPI
+PchIsRtcBatteryGood (
+  VOID
+  );
+
+#endif // _PCH_PMC_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
new file mode 100644
index 0000000000..acd7a16e48
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
@@ -0,0 +1,114 @@
+/** @file
+  Prototype of the PeiPchPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_LIB_H_
+#define _PEI_PCH_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole PCH_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi       The RC PREMEM Policy PPI instance
+**/
+VOID
+EFIAPI
+PchPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi               The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+PchPrintPolicyPpi (
+  IN  SI_POLICY_PPI           *SiPolicyPpi
+  );
+
+/**
+  Get PCH PREMEM config block table total size.
+
+  @retval                               Size of PCH PREMEM config block table
+**/
+UINT16
+EFIAPI
+PchGetPreMemConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get PCH config block table total size.
+
+  @retval                               Size of PCH config block table
+**/
+UINT16
+EFIAPI
+PchGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  PchAddPreMemConfigBlocks add all PCH config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  PchAddConfigBlocks add all PCH config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  Get Sata Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     SataConfig          Pointer to Sata Config Policy
+**/
+PCH_SATA_CONFIG *
+GetPchSataConfig (
+  IN SI_POLICY_PPI      *SiPolicy,
+  IN UINT32             SataCtrlIndex
+  );
+
+/**
+  Get Hsio Sata Pre Mem Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Pointer to Hsio Sata Pre Mem Config Policy
+**/
+PCH_HSIO_SATA_PREMEM_CONFIG *
+GetPchHsioSataPreMemConfig (
+  IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy,
+  IN UINT32               SataCtrlIndex
+  );
+
+#endif // _PEI_PCH_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
new file mode 100644
index 0000000000..ca2da4cfc1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
@@ -0,0 +1,24 @@
+/** @file
+  Header file for PCH RESET Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RESET_LIB_H_
+#define _PCH_RESET_LIB_H_
+
+/**
+  Initialize PCH Reset APIs
+
+  @retval EFI_SUCCESS             APIs are installed successfully
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
+**/
+EFI_STATUS
+EFIAPI
+PchInitializeReset (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
new file mode 100644
index 0000000000..779aac2d2a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
@@ -0,0 +1,116 @@
+/** @file
+  Header file for PchSbiAccessLib.
+
+  Copyright (c) 2019 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
+EFIAPI
+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
+EFIAPI
+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/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
new file mode 100644
index 0000000000..4962c67a7c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
@@ -0,0 +1,240 @@
+/** @file
+  Header file for PCH Serial IO Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SERIAL_IO_LIB_H_
+#define _PCH_SERIAL_IO_LIB_H_
+
+typedef enum {
+  PchSerialIoIndexI2C0,
+  PchSerialIoIndexI2C1,
+  PchSerialIoIndexI2C2,
+  PchSerialIoIndexI2C3,
+  PchSerialIoIndexI2C4,
+  PchSerialIoIndexI2C5,
+  PchSerialIoIndexSpi0,
+  PchSerialIoIndexSpi1,
+  PchSerialIoIndexSpi2,
+  PchSerialIoIndexUart0,
+  PchSerialIoIndexUart1,
+  PchSerialIoIndexUart2,
+  PchSerialIoIndexMax
+} PCH_SERIAL_IO_CONTROLLER;
+
+typedef enum {
+  PchSerialIoDisabled,
+  PchSerialIoPci,
+  PchSerialIoAcpi,
+  PchSerialIoHidden
+} PCH_SERIAL_IO_MODE;
+
+typedef enum  {
+  SERIAL_IO_UNKNOWN = 0,
+  SERIAL_IO_I2C,
+  SERIAL_IO_SPI,
+  SERIAL_IO_UART
+} PCH_SERIAL_IO_CONTROLLER_TYPE;
+
+enum PCH_LP_SERIAL_IO_CS_POLARITY {
+  PchSerialIoCsActiveLow = 0,
+  PchSerialIoCsActiveHigh = 1
+};
+enum PCH_LP_SERIAL_IO_HW_FLOW_CTRL {
+  PchSerialIoHwFlowCtrlDisabled = 0,
+  PchSerialIoHwFlowControlEnabled = 1
+};
+
+#define SERIALIO_HID_LENGTH 8 // including null terminator
+#define SERIALIO_UID_LENGTH 1
+#define SERIALIO_CID_LENGTH 1
+#define SERIALIO_TOTAL_ID_LENGTH SERIALIO_HID_LENGTH+SERIALIO_UID_LENGTH+SERIALIO_CID_LENGTH
+
+/**
+  Returns index of the last i2c controller
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            Index of I2C controller
+**/
+PCH_SERIAL_IO_CONTROLLER
+GetMaxI2cNumber (
+  VOID
+  );
+
+/**
+  Returns string with AcpiHID assigned to selected SerialIo controller
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            pointer to 8-byte string
+**/
+CHAR8*
+GetSerialIoAcpiHid (
+  IN PCH_SERIAL_IO_CONTROLLER Number
+  );
+
+/**
+  Checks if given Serial IO Controller Function equals 0
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               TRUE if SerialIO Function is equal to 0
+                                        FALSE if Function is higher then 0
+**/
+BOOLEAN
+IsSerialIoFunctionZero (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  );
+
+/**
+  Checks if Device with given PciDeviceId is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  PciDevId  Device ID
+  @param[out] Number    Number of SerialIo controller
+
+  @retval TRUE          Yes it is a SerialIo controller
+  @retval FALSE         No it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoPciDevId (
+  IN  UINT16                    PciDevId,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  );
+
+/**
+  Checks if Device with given AcpiHID string is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  AcpiHid   String
+  @param[out] Number    Number of SerialIo controller
+
+  @retval TRUE          yes it is a SerialIo controller
+  @retval FALSE         no it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoAcpiHid (
+  IN CHAR8                      *AcpiHid,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  );
+
+/**
+  Configures Serial IO Controller
+
+  @param[in] Controller    Serial IO controller number
+  @param[in] DeviceMode    Device operation mode
+  @param[in] PsfDisable    Disable device at PSF level
+
+  @retval None
+**/
+VOID
+ConfigureSerialIoController (
+  IN PCH_SERIAL_IO_CONTROLLER Controller,
+  IN PCH_SERIAL_IO_MODE       DeviceMode,
+  IN BOOLEAN                  PsfDisable
+  );
+
+/**
+  Returns Serial IO Controller Type I2C, SPI or UART
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            I2C, SPI or UART
+  @retval            UNKNOWN - in case if undefined controller
+**/
+PCH_SERIAL_IO_CONTROLLER_TYPE
+GetSerialIoControllerType (
+  IN PCH_SERIAL_IO_CONTROLLER  Controller
+  );
+
+/**
+  Finds PCI Device Number of SerialIo devices.
+  SerialIo devices' BDF is configurable
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo device number
+**/
+UINT8
+GetSerialIoDeviceNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  );
+
+/**
+  Finds PCI Function Number of SerialIo devices.
+  SerialIo devices' BDF is configurable
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo funciton number
+**/
+UINT8
+GetSerialIoFunctionNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  );
+
+/**
+  Finds BAR values of SerialIo devices.
+  SerialIo devices can be configured to not appear on PCI so traditional method of reading BAR might not work.
+
+  @param[in] SerialIoDevice             Serial IO device
+  @param[in] BarNumber                  0=BAR0, 1=BAR1
+
+  @retval                               SerialIo Bar value
+**/
+UINTN
+FindSerialIoBar (
+  IN PCH_SERIAL_IO_CONTROLLER           SerialIoDevice,
+  IN UINT8                              BarNumber
+  );
+
+/**
+  Checks if given device corresponds to any of LPSS Devices
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval                               TRUE if SerialIO Device/Function Number is equal to any of LPSS devices
+                                        FALSE Device/Function is not in Serial IO scope
+**/
+BOOLEAN
+IsSerialIoDevice (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  );
+
+/**
+  Checks if given Serial IO Controller is enabled or not
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval TRUE                          TRUE if given serial io device is enabled.
+  @retval FALSE                         FALSE if given serial io device is disabled.
+**/
+BOOLEAN
+IsSerialIoDeviceEnabled (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  );
+
+/**
+  Gets Pci Config control offset
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval    CfgCtrAddr                 Offset of Pci config control
+                                        0 if Device and Function do not correspond to Serial IO
+**/
+UINT16
+GetSerialIoConfigControlOffset (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  );
+
+#endif // _PEI_DXE_SMM_PCH_SERIAL_IO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
new file mode 100644
index 0000000000..f97051e97c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
@@ -0,0 +1,111 @@
+/** @file
+  Header file for PCH Serial IO UART Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SERIAL_IO_UART_LIB_H_
+#define _PCH_SERIAL_IO_UART_LIB_H_
+
+typedef enum {
+  AccessMode8bit,
+  AccessMode32bit
+} UART_ACCESS_MODE;
+
+/**
+  Returns UART's currently active access mode, 8 or 32 bit
+
+  @param[in]  MmioBase    Base address of UART MMIO space
+
+  @retval     AccessMode8bit
+  @retval     AccessMode32bit
+**/
+UART_ACCESS_MODE
+DetectAccessMode (
+  IN UINTN  MmioBase
+  );
+
+/**
+  Initialize selected SerialIo UART.
+
+  @param[in]  UartNumber           Selects Serial IO UART device (0-2)
+  @param[in]  FifoEnable           When TRUE, enables 64-byte FIFOs.
+  @param[in]  BaudRate             Baud rate.
+  @param[in]  LineControl          Data length, parity, stop bits.
+  @param[in]  HardwareFlowControl  Automated hardware flow control. If TRUE, hardware automatically checks CTS when sending data, and sets RTS when receiving data.
+**/
+VOID
+EFIAPI
+PchSerialIoUartInit (
+  IN UINT8   UartNumber,
+  IN BOOLEAN FifoEnable,
+  IN UINT32  BaudRate,
+  IN UINT8   LineControl,
+  IN BOOLEAN HardwareFlowControl
+  );
+
+
+/**
+  Write data to serial device.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param[in]  UartNumber       Selects Serial IO UART device (0-2)
+  @param[in]  Buffer           Point of data buffer which need to be writed.
+  @param[in]  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval                  Actual number of bytes writed to serial device.
+**/
+UINTN
+EFIAPI
+PchSerialIoUartOut (
+  IN UINT8  UartNumber,
+  IN UINT8  *Buffer,
+  IN UINTN  NumberOfBytes
+);
+
+/*
+  Read data from serial device and save the datas in buffer.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param[in]   UartNumber           Selects Serial IO UART device (0-2)
+  @param[out]  Buffer               Point of data buffer which need to be writed.
+  @param[in]   NumberOfBytes        Number of output bytes which are cached in Buffer.
+  @param[in]   WaitUntilBufferFull  When TRUE, function waits until whole buffer is filled. When FALSE, function returns as soon as no new characters are available.
+
+  @retval                      Actual number of bytes raed from serial device.
+
+**/
+UINTN
+EFIAPI
+PchSerialIoUartIn (
+  IN  UINT8     UartNumber,
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes,
+  IN  BOOLEAN   WaitUntilBufferFull
+);
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @param[in]  UartNumber       Selects Serial IO UART device (0-2)
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+PchSerialIoUartPoll (
+  IN  UINT8     UartNumber
+  );
+
+
+#endif // _PEI_DXE_SMM_PCH_SERIAL_IO_UART_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
new file mode 100644
index 0000000000..34b9867c34
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for SMM Control PEI Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SMM_CONTROL_LIB_H_
+#define _PCH_SMM_CONTROL_LIB_H_
+
+/**
+  This function install PEI SMM Control PPI
+
+  @retval EFI_STATUS  Results of the installation of the SMM Control PPI
+**/
+EFI_STATUS
+EFIAPI
+PchSmmControlInit (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
new file mode 100644
index 0000000000..69b9c1cdb7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
@@ -0,0 +1,121 @@
+/** @file
+  Library that contains common parts of WdtPei and WdtDxe. Not a standalone module.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_WDT_COMMON_LIB_H_
+#define _PCH_WDT_COMMON_LIB_H_
+
+extern UINT8    mAllowExpectedReset;
+
+/**
+  Reads LPC bridge to get Watchdog Timer address
+
+
+  @retval UINT32                  Watchdog's address
+**/
+UINT32
+WdtGetAddress (
+  VOID
+  );
+
+/**
+  Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+  causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+  function was called too.
+
+  @param[in] TimeoutValue         Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+  @retval EFI_SUCCESS             if everything's OK
+  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
+**/
+EFI_STATUS
+EFIAPI
+WdtReloadAndStart (
+  IN  UINT32  TimeoutValue
+  );
+
+/**
+  Disables WDT timer.
+
+
+**/
+VOID
+EFIAPI
+WdtDisable (
+  VOID
+  );
+
+/**
+  Returns WDT failure status.
+
+
+  @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE   If there was WDT expiration or unexpected reset
+  @retval V_PCH_OC_WDT_CTL_STATUS_OK        Otherwise
+**/
+UINT8
+EFIAPI
+WdtCheckStatus (
+  VOID
+  );
+
+/**
+  Normally, each reboot performed while watchdog runs is considered a failure.
+  This function allows platform to perform expected reboots with WDT running,
+  without being interpreted as failures.
+  In DXE phase, it is enough to call this function any time before reset.
+  In PEI phase, between calling this function and performing reset, ReloadAndStart()
+  must not be called.
+
+
+**/
+VOID
+EFIAPI
+WdtAllowKnownReset (
+  VOID
+  );
+
+/**
+  Returns information if WDT coverage for the duration of BIOS execution
+  was requested by an OS application
+
+
+  @retval TRUE                    if WDT was requested
+  @retval FALSE                   if WDT was not requested
+**/
+UINT8
+EFIAPI
+IsWdtRequired (
+  VOID
+  );
+
+/**
+  Returns WDT enabled/disabled status.
+
+
+  @retval TRUE                    if WDT is enabled
+  @retval FALSE                   if WDT is disabled
+**/
+UINT8
+EFIAPI
+IsWdtEnabled (
+  VOID
+  );
+
+/**
+  Returns WDT locked status.
+
+
+  @retval TRUE                    if WDT is locked
+  @retval FALSE                   if WDT is unlocked
+**/
+UINT8
+EFIAPI
+IsWdtLocked (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
new file mode 100644
index 0000000000..f1a2600216
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
@@ -0,0 +1,207 @@
+/** @file
+  Header file for PmcLib.
+
+  Copyright (c) 2019 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 {
+  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;
+
+#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 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 RTC 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
+  );
+
+/**
+  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 checks if SMI Lock is set
+
+  @retval SMI Lock state
+**/
+BOOLEAN
+PmcIsSmiLockSet (
+  VOID
+  );
+
+/**
+  Check global SMI enable is set
+
+  @retval TRUE  Global SMI enable is set
+          FALSE Global SMI enable is not set
+**/
+BOOLEAN
+PmcIsGblSmiEn (
+  VOID
+  );
+
+#endif // _PMC_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
new file mode 100644
index 0000000000..047d543009
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
@@ -0,0 +1,76 @@
+/** @file
+  Header file for PchSataLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SATA_LIB_H_
+#define _PCH_SATA_LIB_H_
+
+#define SATA_1_CONTROLLER_INDEX             0
+#define SATA_2_CONTROLLER_INDEX             1
+#define SATA_3_CONTROLLER_INDEX             2
+
+/**
+  Get Pch Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval Pch Maximum Sata Port Number
+**/
+UINT8
+GetPchMaxSataPortNum (
+  IN UINT32     SataCtrlIndex
+  );
+
+/**
+  Gets Maximum Sata Controller Number
+
+  @param[in] None
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+GetPchMaxSataControllerNum (
+  VOID
+  );
+
+/**
+  Gets SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+GetSataPcieDeviceNum (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Gets SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+GetSataPcieFunctionNum (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Gets SATA controller PCIe config space base address
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe config space base address
+**/
+UINT64
+GetSataRegBase (
+  IN UINT32 SataCtrlIndex
+  );
+
+#endif // _PCH_SATA_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
new file mode 100644
index 0000000000..53283597e7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for SEC PCH Lib.
+  All function in this library is available for SEC
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SEC_PCH_LIB_H_
+#define _SEC_PCH_LIB_H_
+
+/**
+  This function do the PCH cycle decoding initialization.
+**/
+VOID
+EFIAPI
+EarlyCycleDecoding (
+  VOID
+  );
+
+#endif // _SEC_PCH_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..53c11bb59a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
@@ -0,0 +1,98 @@
+/** @file
+  The header file includes the common header files, defines
+  internal structure and functions used by SpiFlashCommonLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SPI_FLASH_COMMON_LIB_H__
+#define __SPI_FLASH_COMMON_LIB_H__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define SECTOR_SIZE_4KB   0x1000      // Common 4kBytes sector size
+/**
+  Enable block protection on the Serial Flash device.
+
+  @retval     EFI_SUCCESS       Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+  VOID
+  );
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      Address       The starting physical address of the read.
+  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
+                                of bytes actually read.
+  @param[out]     Buffer        The destination data buffer for the read.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN                        Address,
+  IN OUT UINT32                       *NumBytes,
+     OUT UINT8                        *Buffer
+  );
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      Address         The starting physical address of the write.
+  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
+                                  the actual number of bytes written.
+  @param[in]      Buffer          The source data buffer for the write.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN                      Address,
+  IN OUT UINT32                     *NumBytes,
+  IN     UINT8                      *Buffer
+  );
+
+/**
+  Erase the block starting at Address.
+
+  @param[in]  Address         The starting physical address of the block to be erased.
+                              This library assume that caller garantee that the PAddress
+                              is at the starting address of this block.
+  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
+                              On output, the actual number of bytes erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN    UINTN                     Address,
+  IN    UINTN                     *NumBytes
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
new file mode 100644
index 0000000000..e56f3139d7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for Spi Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SPI_LIB_H_
+#define _SPI_LIB_H_
+
+/**
+  This function Initial SPI services
+
+  @retval EFI_STATUS  Results of the installation of the SPI services
+**/
+EFI_STATUS
+EFIAPI
+SpiServiceInit (
+  VOID
+  );
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (5 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
                   ` (30 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

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

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h                        |  42 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h                             |  27 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h                             |  28 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h           | 186 ++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h         | 136 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h              |  68 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h         | 146 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h         | 132 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h                  |  42 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h                   |  42 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h             | 134 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h        |  67 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h |  67 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h          | 152 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h                   |  15 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h                        | 295 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h                        | 113 ++++++++
 17 files changed, 1692 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
new file mode 100644
index 0000000000..840a2355f1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
@@ -0,0 +1,42 @@
+/** @file
+  PCH Reset PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RESET_PPI_H_
+#define _PCH_RESET_PPI_H_
+
+//
+// Member functions
+//
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+
+  @retval EFI_SUCCESS             The callback function has been done successfully
+  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback ppi. Or, none of
+                                  callback ppi is installed.
+  @retval Others                  Do not do any reset from PCH
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET_CALLBACK) (
+  IN  EFI_RESET_TYPE    ResetType,
+  IN  EFI_GUID          *ResetTypeGuid
+  );
+
+/**
+  This ppi is used to execute PCH Reset from the host controller.
+  If drivers need to run their callback function right before issuing the PCH Reset,
+  they can install PCH Reset Callback PPI before PCH Reset PEI driver to achieve that.
+**/
+typedef struct {
+  PCH_RESET_CALLBACK  ResetCallback;
+} PCH_RESET_CALLBACK_PPI;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
new file mode 100644
index 0000000000..d3ff152742
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
@@ -0,0 +1,27 @@
+/** @file
+  This file defines the PCH SPI PPI which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_PPI_H_
+#define _PCH_SPI_PPI_H_
+
+#include <Protocol/Spi.h>
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID           gPchSpiPpiGuid;
+
+/**
+  Reuse the PCH_SPI_PROTOCOL definitions
+  This is possible becaues the PPI implementation does not rely on a PeiService pointer,
+  as it uses EDKII Glue Lib to do IO accesses
+**/
+typedef PCH_SPI_PROTOCOL PCH_SPI_PPI;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
new file mode 100644
index 0000000000..59a9f0f251
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
@@ -0,0 +1,28 @@
+/** @file
+  Watchdog Timer PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_WDT_H_
+#define _PEI_WDT_H_
+
+#include <Protocol/Wdt.h>
+//
+// MRC takes a lot of time to execute in debug mode
+//
+#define WDT_TIMEOUT_BETWEEN_PEI_DXE 60
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID       gWdtPpiGuid;
+
+///
+/// Reuse WDT_PROTOCOL definition
+///
+typedef WDT_PROTOCOL  WDT_PPI;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
new file mode 100644
index 0000000000..4f14065bd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
@@ -0,0 +1,186 @@
+/** @file
+  PCH IO TrapEx Dispatch Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
new file mode 100644
index 0000000000..f3e788a2e1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
@@ -0,0 +1,136 @@
+/** @file
+  APIs of PCH ACPI SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
new file mode 100644
index 0000000000..45fae6e2d5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
@@ -0,0 +1,68 @@
+/** @file
+  PCH eMMC HS400 Tuning Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_EMMC_TUNING_PROTOCOL_H_
+#define _PCH_EMMC_TUNING_PROTOCOL_H_
+
+#define PCH_EMMC_TUNING_PROTOCOL_REVISION 1
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID  gPchEmmcTuningProtocolGuid;
+
+//
+// Forward declaration for PCH_EMMC_TUNING_PROTOCOL
+//
+typedef struct _PCH_EMMC_TUNING_PROTOCOL PCH_EMMC_TUNING_PROTOCOL;
+
+/**
+  This structure decribes the required Emmc info for HS400 tuning
+**/
+typedef struct {
+  EFI_HANDLE                PartitionHandle;    ///< eMMC partition handle for block read/write
+  EFI_LBA                   Lba;                ///< Logical Block Address for HS400 Tuning block read/write
+  UINT32                    RelativeDevAddress; ///< Device system address, dynamically assigned by the host during initialization.
+  UINT8                     HS200BusWidth;      ///< The value to be programmed for BUS_WIDTH[183] byte
+} EMMC_INFO;
+
+///
+/// This structure describes the return value after HS400 tuning
+///
+typedef struct {
+  UINT8       Hs400DataValid;     ///< Set if Hs400 Tuning Data is valid after tuning
+  UINT8       Hs400RxStrobe1Dll;  ///< Rx Strobe Delay Control - Rx Strobe Delay DLL 1 (HS400 Mode)
+  UINT8       Hs400TxDataDll;     ///< Tx Data Delay Control 1 - Tx Data Delay (HS400 Mode)
+} EMMC_TUNING_DATA;
+
+///
+/// EMMC HS400 TUNING INTERFACE
+///
+typedef EFI_STATUS (EFIAPI *EMMC_TUNE) (
+  IN   PCH_EMMC_TUNING_PROTOCOL         *This,              ///< This pointer to PCH_EMMC_TUNING_PROTOCOL
+  /**
+    Revision parameter is used to verify the layout of EMMC_INFO and TUNINGDATA.
+    If the revision is not matched, means the revision of EMMC_INFO and TUNINGDATA is not matched.
+    And function will return immediately.
+  **/
+  IN   UINT8                            Revision,
+  IN   EMMC_INFO                        *EmmcInfo,          ///< Pointer to EMMC_INFO
+  OUT  EMMC_TUNING_DATA                 *EmmcTuningData     ///< Pointer to EMMC_TUNING_DATA
+);
+
+/**
+  PCH EMMC TUNING PROTOCOL INTERFACE
+  Platform code uses this protocol to configure Emmc Hs400 mode, by passing the EMMC_INFO information.
+  PCH will setting EMMC controller based on EMMC_INFO and return EMMC_TUNING_DATA to platform code.
+  Platform should keep values of EMMC_TUNING_DATA and uses to configure EMMC through policies, to
+  prevent from doing EMMC tuning every boot.
+**/
+struct _PCH_EMMC_TUNING_PROTOCOL {
+  EMMC_TUNE  EmmcTune;  ///< Emmc Hs400 Tuning Interface
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
new file mode 100644
index 0000000000..9a180b4285
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
@@ -0,0 +1,146 @@
+/** @file
+  SmmEspiDispatch Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
new file mode 100644
index 0000000000..c5e8bc3f28
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
@@ -0,0 +1,132 @@
+/** @file
+  APIs of PCH PCIE SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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;
+
+//
+// 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 to PCH PCIE Root Port 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
new file mode 100644
index 0000000000..ff35b43b61
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
@@ -0,0 +1,42 @@
+/** @file
+  Interface definition details between Pch and platform drivers during DXE phase.
+
+  Copyright (c) 2019 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 <Private/PchConfigHob.h>
+#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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
new file mode 100644
index 0000000000..4c49d082fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
@@ -0,0 +1,42 @@
+/** @file
+  PCH Reset Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RESET_PROTOCOL_H_
+#define _PCH_RESET_PROTOCOL_H_
+
+//
+// Member functions
+//
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+
+  @retval EFI_SUCCESS             The callback function has been done successfully
+  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback protocol. Or, none of
+                                  callback protocol is installed.
+  @retval Others                  Do not do any reset from PCH
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET_CALLBACK) (
+  IN  EFI_RESET_TYPE    ResetType,
+  IN  EFI_GUID          *ResetTypeGuid
+  );
+
+/**
+  This protocol is used to execute PCH Reset from the host controller.
+  If drivers need to run their callback function right before issuing the PCH Reset,
+  they can install PCH Reset Callback Protocol before PCH Reset DXE driver to achieve that.
+**/
+typedef struct {
+  PCH_RESET_CALLBACK  ResetCallback;
+} PCH_RESET_CALLBACK_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
new file mode 100644
index 0000000000..6fdfed1de7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
@@ -0,0 +1,134 @@
+/** @file
+  APIs of PCH SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
new file mode 100644
index 0000000000..73386a570e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
@@ -0,0 +1,67 @@
+/** @file
+  PCH SMM IO Trap Control Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
new file mode 100644
index 0000000000..06ddc3e1cd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
@@ -0,0 +1,67 @@
+/** @file
+  PCH SMM Periodic Timer Control Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
new file mode 100644
index 0000000000..d397712092
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
@@ -0,0 +1,152 @@
+/** @file
+  APIs of PCH TCO SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
new file mode 100644
index 0000000000..ece65cd729
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
@@ -0,0 +1,15 @@
+/** @file
+  SmmSmbus Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __EFI_SMM_SMBUS_PROTOCOL_H__
+#define __EFI_SMM_SMBUS_PROTOCOL_H__
+
+extern EFI_GUID               gEfiSmmSmbusProtocolGuid;
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..22df7fe351
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
@@ -0,0 +1,295 @@
+/** @file
+  This file defines the PCH SPI Protocol which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 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,
+  FlashRegionEC = 8,
+  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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
new file mode 100644
index 0000000000..67554e526f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
@@ -0,0 +1,113 @@
+/** @file
+  Watchdog Timer protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_WDT_H_
+#define _DXE_WDT_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID               gWdtProtocolGuid;
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _WDT_PROTOCOL  WDT_PROTOCOL;
+
+/**
+  Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+  causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+  function was called too.
+
+  @param[in] TimeoutValue         Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+  @retval EFI_SUCCESS             if everything's OK
+  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WDT_RELOAD_AND_START) (
+  UINT32 TimeoutValue
+  );
+
+/**
+  Returns WDT failure status.
+
+  @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE   If there was WDT expiration or unexpected reset
+  @retval V_PCH_OC_WDT_CTL_STATUS_OK        Otherwise
+**/
+typedef
+UINT8
+(EFIAPI *WDT_CHECK_STATUS) (
+  VOID
+  );
+
+/**
+  Returns information if WDT coverage for the duration of BIOS execution
+  was requested by an OS application.
+
+  @retval TRUE                    if WDT was requested
+  @retval FALSE                   if WDT was not requested
+**/
+typedef
+UINT8
+(EFIAPI *IS_WDT_REQUIRED) (
+  VOID
+  );
+
+/**
+  Returns WDT enabled/disabled status.
+
+  @retval TRUE                    if WDT is enabled
+  @retval FALSE                   if WDT is disabled
+**/
+typedef
+UINT8
+(EFIAPI *IS_WDT_ENABLED) (
+  VOID
+  );
+
+/**
+  Disables WDT timer.
+**/
+typedef
+VOID
+(EFIAPI *WDT_DISABLE) (
+  VOID
+  );
+
+/**
+  Normally, each reboot performed while watchdog runs is considered a failure.
+  This function allows platform to perform expected reboots with WDT running,
+  without being interpreted as failures.
+  In DXE phase, it is enough to call this function any time before reset.
+  In PEI phase, between calling this function and performing reset, ReloadAndStart()
+  must not be called.
+**/
+typedef
+VOID
+(EFIAPI *WDT_ALLOW_KNOWN_RESET) (
+  VOID
+  );
+
+/**
+  These protocols and PPI allow a platform module to perform watch dog timer operations
+  through the Intel PCH LPC Host Controller Interface. The WDT protocol and WDT PPI
+  implement the Intel (R) Watch Dog timer for DXE, and PEI environments, respectively.
+  WDT_PROTOCOL referenced hereafter represents both WDT_PROTOCOL and WDT_PPI, as they
+  share the identical data structure.
+**/
+struct _WDT_PROTOCOL {
+  WDT_RELOAD_AND_START  ReloadAndStart;   ///< Reloads WDT with new timeout value and starts it.
+  WDT_CHECK_STATUS      CheckStatus;      ///< Returns WDT failure status.
+  WDT_DISABLE           Disable;          ///< Disables WDT timer.
+  WDT_ALLOW_KNOWN_RESET AllowKnownReset;  ///< Perform expected reboots with WDT running, without being interpreted as failures.
+  IS_WDT_REQUIRED       IsWdtRequired;    ///< Returns information if WDT coverage for the duration of BIOS execution was requested by an OS application.
+  IS_WDT_ENABLED        IsWdtEnabled;     ///< Returns WDT enabled/disabled status.
+};
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (6 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
                   ` (29 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds the following header files:
 * Pch/Include/Register

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h            |  54 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h         |  57 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h         | 122 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h       |  54 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h       |  62 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h         |  90 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h        | 273 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h     | 694 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h         | 204 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h        | 170 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h         |  79 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h        | 103 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h         |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h         | 360 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h      |  61 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h        | 116 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h        | 484 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h         |  73 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h         | 670 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h      |  72 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h         | 104 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h      | 113 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h        |  77 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h        | 668 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h         |  52 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h      |  48 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h    | 232 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h | 138 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h       | 151 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h         | 295 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h  |  49 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h    | 134 ++++
 32 files changed, 5917 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
new file mode 100644
index 0000000000..10fcb316fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
@@ -0,0 +1,54 @@
+/** @file
+  Generic register definitions for 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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
+
+//
+// Default Vendor ID and Subsystem ID
+//
+#define V_PCH_INTEL_VENDOR_ID   0x8086      ///< Default Intel PCH Vendor ID
+#define V_PCH_DEFAULT_SID       0x7270      ///< Default Intel PCH Subsystem ID
+#define V_PCH_DEFAULT_SVID_SID  (V_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID << 16))   ///< Default INTEL PCH Vendor ID and Subsystem ID
+
+#endif //_PCH_REGS_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
new file mode 100644
index 0000000000..47dd73215e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
@@ -0,0 +1,57 @@
+/** @file
+  Register names for PCH DCI 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DCI_H_
+#define _PCH_REGS_DCI_H_
+
+//
+// DCI PCR Registers
+//
+
+#define R_DCI_PCR_ECTRL                       0x04            ///< DCI Control Register
+
+#define B_DCI_PCR_ECTRL_HDCIEN_LOCK           BIT0            ///< Host DCI Enable Lock
+#define B_DCI_PCR_ECTRL_HDCIEN                BIT4            ///< Host DCI Enable
+
+#define R_DCI_PCR_ECKPWRCTL                   0x08            ///< DCI Power Control
+// CNP-A0 (DCI Gen2) and backwards
+#define R_DCI_PCR_PCE                         0x30            ///< DCI Power Control Enable Register
+#define B_DCI_PCR_PCE_HAE                     BIT5            ///< Hardware Autonomous Enable
+#define B_DCI_PCR_PCE_D3HE                    BIT2            ///< D3-Hot Enable
+#define B_DCI_PCR_PCE_I3E                     BIT1            ///< I3 Enable
+#define B_DCI_PCR_PCE_PMCRE                   BIT0            ///< PMC Request Enable
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
new file mode 100644
index 0000000000..44f708dd92
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
@@ -0,0 +1,122 @@
+/** @file
+  Register names for DMI and OP-DMI
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DMI_H_
+#define _PCH_REGS_DMI_H_
+
+//
+// DMI Chipset Configuration Registers (PID:DMI)
+//
+
+//
+// VC Configuration (Common)
+//
+#define B_PCH_DMI_PCR_V0CTL_EN               BIT31
+#define B_PCH_DMI_PCR_V0CTL_ID               (7 << 24)                   ///< Bit[26:24]
+#define N_PCH_DMI_PCR_V0CTL_ID               24
+#define V_PCH_DMI_PCR_V0CTL_ETVM_MASK        0xFC00
+#define V_PCH_DMI_PCR_V0CTL_TVM_MASK         0x7E
+#define B_PCH_DMI_PCR_V0STS_NP               BIT1
+#define B_PCH_DMI_PCR_V1CTL_EN               BIT31
+#define B_PCH_DMI_PCR_V1CTL_ID               (0x0F << 24)                ///< Bit[27:24]
+#define N_PCH_DMI_PCR_V1CTL_ID               24
+#define V_PCH_DMI_PCR_V1CTL_ETVM_MASK        0xFC00
+#define V_PCH_DMI_PCR_V1CTL_TVM_MASK         0xFE
+#define B_PCH_DMI_PCR_V1STS_NP               BIT1
+
+
+//
+// DMI Source Decode PCRs (Common)
+//
+#define R_PCH_DMI_PCR_PCIEPAR1E         0x2700                ///< PCIE Port IOxAPIC Range 1 Enable
+#define R_PCH_DMI_PCR_PCIEPAR2E         0x2704                ///< PCIE Port IOxAPIC Range 2 Enable
+#define R_PCH_DMI_PCR_PCIEPAR3E         0x2708                ///< PCIE Port IOxAPIC Range 3 Enable
+#define R_PCH_DMI_PCR_PCIEPAR4E         0x270C                ///< PCIE Port IOxAPIC Range 4 Enable
+#define R_PCH_DMI_PCR_PCIEPAR1DID       0x2710                ///< PCIE Port IOxAPIC Range 1 Destination ID
+#define R_PCH_DMI_PCR_PCIEPAR2DID       0x2714                ///< PCIE Port IOxAPIC Range 2 Destination ID
+#define R_PCH_DMI_PCR_PCIEPAR3DID       0x2718                ///< PCIE Port IOxAPIC Range 3 Destination ID
+#define R_PCH_DMI_PCR_PCIEPAR4DID       0x271C                ///< PCIE Port IOxAPIC Range 4 Destination ID
+#define R_PCH_DMI_PCR_P2SBIOR           0x2720                ///< P2SB IO Range
+#define R_PCH_DMI_PCR_TTTBARB           0x2724                ///< Thermal Throttling BIOS Assigned Thermal Base Address
+#define R_PCH_DMI_PCR_TTTBARBH          0x2728                ///< Thermal Throttling BIOS Assigned Thermal Base High Address
+#define R_PCH_DMI_PCR_LPCLGIR1          0x2730                ///< LPC Generic I/O Range 1
+#define R_PCH_DMI_PCR_LPCLGIR2          0x2734                ///< LPC Generic I/O Range 2
+#define R_PCH_DMI_PCR_LPCLGIR3          0x2738                ///< LPC Generic I/O Range 3
+#define R_PCH_DMI_PCR_LPCLGIR4          0x273C                ///< LPC Generic I/O Range 4
+#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_RPRDID            0xFFFF0000            ///< RPR Destination ID
+#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_IOT2              0x2758                ///< I/O Trap Register 2
+#define R_PCH_DMI_PCR_IOT3              0x2760                ///< I/O Trap Register 3
+#define R_PCH_DMI_PCR_IOT4              0x2768                ///< I/O Trap Register 4
+#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
+#define R_PCH_DMI_PCR_GPMR2             0x2784                ///< General Purpose Memory Range 2
+#define R_PCH_DMI_PCR_GPMR2DID          0x2788                ///< General Purpose Memory Range 2 Destination ID
+#define R_PCH_DMI_PCR_GPMR3             0x278C                ///< General Purpose Memory Range 3
+#define R_PCH_DMI_PCR_GPMR3DID          0x2790                ///< General Purpose Memory Range 3 Destination ID
+#define R_PCH_DMI_PCR_GPIOR1            0x2794                ///< General Purpose I/O Range 1
+#define R_PCH_DMI_PCR_GPIOR1DID         0x2798                ///< General Purpose I/O Range 1 Destination ID
+#define R_PCH_DMI_PCR_GPIOR2            0x279C                ///< General Purpose I/O Range 2
+#define R_PCH_DMI_PCR_GPIOR2DID         0x27A0                ///< General Purpose I/O Range 2 Destination ID
+#define R_PCH_DMI_PCR_GPIOR3            0x27A4                ///< General Purpose I/O Range 3
+#define R_PCH_DMI_PCR_GPIOR3DID         0x27A8                ///< General Purpose I/O Range 3 Destination ID
+
+//
+// Opi PHY registers
+//
+#define R_PCH_OPIPHY_PCR_0110           0x0110
+#define R_PCH_OPIPHY_PCR_0118           0x0118
+#define R_PCH_OPIPHY_PCR_011C           0x011C
+#define R_PCH_OPIPHY_PCR_0354           0x0354
+#define R_PCH_OPIPHY_PCR_B104           0xB104
+#define R_PCH_OPIPHY_PCR_B10C           0xB10C
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
new file mode 100644
index 0000000000..36c0054d63
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
@@ -0,0 +1,54 @@
+/** @file
+  Register names for DMI SIP14
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DMI14_H_
+#define _PCH_REGS_DMI14_H_
+
+//
+// DMI Chipset Configuration Registers (PID:DMI)
+//
+
+//
+// DMI Control
+//
+#define R_PCH_DMI14_PCR_DMIC                   0x2234                              ///< DMI Control
+#define B_PCH_DMI14_PCR_DMIC_SRL               BIT31                               ///< Secured register lock
+#define B_PCH_DMI14_PCR_DMIC_DMICGEN           (BIT4 | BIT3 | BIT2 | BIT1 | BIT0)  ///< DMI Clock Gate Enable
+
+#define R_PCH_DMI14_PCR_2314                   0x2314
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
new file mode 100644
index 0000000000..c885fdd34d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
@@ -0,0 +1,62 @@
+/** @file
+  Register names for DMI and OP-DMI
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DMI15_H_
+#define _PCH_REGS_DMI15_H_
+
+#define R_PCH_DMI15_PCR_MPC                 0x20D8                       ///< Miscellaneous Port Configuration
+#define B_PCH_DMI15_PCR_MPC_SRL             BIT23                        ///< Secured register lock
+#define R_PCH_DMI15_PCR_V0CTL               0x2284                       ///< Virtual channel 0 resource control
+#define R_PCH_DMI15_PCR_V0STS               0x228A                       ///< Virtual channel 0 status
+
+#define R_PCH_DMI15_PCR_V1CTL               0x2290                       ///< Virtual channel 1 resource control
+#define R_PCH_DMI15_PCR_V1STS               0x2296                       ///< Virtual channel 1 status
+
+#define R_PCH_DMI15_PCR_VMCTL               0x22B0                       ///< ME Virtual Channel (VCm) resource control
+
+#define R_PCH_DMI15_PCR_UPHWAWC             0x249C                       ///< Upstream Port HW Autonomous Width Control
+#define B_PCH_DMI15_PCR_UPHWAWC_TS3TW       (BIT15 | BIT14 | BIT13)      ///< Thermal Sensor 3 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS3TW       13                           ///< Thermal Sensor 3 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TS2TW       (BIT12 | BIT11 | BIT10)      ///< Thermal Sensor 2 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS2TW       10                           ///< Thermal Sensor 2 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TS1TW       (BIT9 | BIT8 | BIT7)         ///< Thermal Sensor 1 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS1TW       7                            ///< Thermal Sensor 1 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TS0TW       (BIT6 | BIT5 | BIT4)         ///< Thermal Sensor 0 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS0TW       4                            ///< Thermal Sensor 0 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TSAWEN      BIT0                         ///< Thermal Sensor Autonomous Width Enable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
new file mode 100644
index 0000000000..837fdc5609
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
@@ -0,0 +1,90 @@
+/** @file
+  Register definition for FIA 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_FIA_H_
+#define _PCH_REGS_FIA_H_
+
+
+//
+// Private chipset register (Memory space) offset definition
+// The PCR register defines is used for PCR MMIO programming and PCH SBI programming as well.
+//
+
+//
+// PCH FIA lane owner encoding
+//
+#define V_PCH_FIA_PCR_LANE_OWN_PCIEDMI                    0x0
+#define V_PCH_FIA_PCR_LANE_OWN_USB3                       0x1
+#define V_PCH_FIA_PCR_LANE_OWN_SATA                       0x2
+#define V_PCH_FIA_PCR_LANE_OWN_GBE                        0x3
+#define V_PCH_FIA_PCR_LANE_OWN_MOBEXP                     0x4
+#define V_PCH_FIA_PCR_LANE_OWN_SSIC                       0x5
+#define V_PCH_FIA_PCR_LANE_OWN_CSI3                       0x6
+#define V_PCH_FIA_PCR_LANE_OWN_UFS                        0x7
+
+#define B_PCH_FIA_PCR_L0O                                 (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L1O                                 (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L2O                                 (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L3O                                 (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L4O                                 (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L5O                                 (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_FIA_PCR_L6O                                 (BIT27 | BIT26 | BIT25 | BIT24)
+#define B_PCH_FIA_PCR_L7O                                 (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_FIA_PCR_L8O                                 (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L9O                                 (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L10O                                (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L11O                                (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L12O                                (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L13O                                (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_FIA_PCR_L14O                                (BIT27 | BIT26 | BIT25 | BIT24)
+#define B_PCH_FIA_PCR_L15O                                (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_FIA_PCR_L16O                                (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L17O                                (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L18O                                (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L19O                                (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L20O                                (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L21O                                (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_FIA_PCR_L22O                                (BIT27 | BIT26 | BIT25 | BIT24)
+#define B_PCH_FIA_PCR_L23O                                (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_FIA_PCR_L24O                                (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L25O                                (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L26O                                (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L27O                                (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L28O                                (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L29O                                (BIT23 | BIT22 | BIT21 | BIT20)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
new file mode 100644
index 0000000000..3f614ba002
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
@@ -0,0 +1,273 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_GPIO_H_
+#define _PCH_REGS_GPIO_H_
+
+//
+// GPIO Common Private Configuration Registers
+//
+#define R_GPIO_PCR_REV_ID               0x00
+#define R_GPIO_PCR_CAP_LIST             0x04
+#define R_GPIO_PCR_FAMBAR               0x08
+#define R_GPIO_PCR_PADBAR               0x0C
+#define B_GPIO_PCR_PADBAR               0x0000FFFF
+#define R_GPIO_PCR_MISCCFG              0x10
+#define B_GPIO_PCR_MISCCFG_IRQ_ROUTE    0xFF000000
+#define N_GPIO_PCR_MISCCFG_IRQ_ROUTE    24
+#define B_GPIO_PCR_MISCCFG_GPE0_DW2     (BIT19 | BIT18 | BIT17 | BIT16)
+#define N_GPIO_PCR_MISCCFG_GPE0_DW2     16
+#define B_GPIO_PCR_MISCCFG_GPE0_DW1     (BIT15 | BIT14 | BIT13 | BIT12)
+#define N_GPIO_PCR_MISCCFG_GPE0_DW1     12
+#define B_GPIO_PCR_MISCCFG_GPE0_DW0     (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_GPIO_PCR_MISCCFG_GPE0_DW0     8
+#define B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN    BIT5
+#define B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN  BIT4
+#define B_GPIO_PCR_MISCCFG_GPRTCDLCGEN     BIT3
+#define B_GPIO_PCR_MISCCFG_GPDPCGEN     BIT1
+#define B_GPIO_PCR_MISCCFG_GPDLCGEN     BIT0
+
+//
+// GPIO SerialBlink/PWM registers
+//
+#define R_GPIO_PCR_CAP_LIST_1_PWM         0x0200
+#define R_GPIO_PCR_PWMC                   0x0204
+#define R_GPIO_PCR_CAP_LIST_2_SER_BLINK   0x0208
+#define R_GPIO_PCR_GP_SER_BLINK           0x020C
+#define B_GPIO_PCR_GP_SER_BLINK           0x1F
+#define R_GPIO_PCR_GP_SER_CMDSTS          0x0210
+#define B_GPIO_PCR_GP_SER_CMDSTS_DLS      (BIT23 | BIT22)
+#define N_GPIO_PCR_GP_SER_CMDSTS_DLS      22
+#define B_GPIO_PCR_GP_SER_CMDSTS_DRS      0x003F0000
+#define N_GPIO_PCR_GP_SER_CMDSTS_DRS      16
+#define B_GPIO_PCR_GP_SER_CMDSTS_BUSY     BIT8
+#define B_GPIO_PCR_GP_SER_CMDSTS_GO       BIT0
+#define R_GPIO_PCR_GP_SER_DATA            0x0210
+
+//
+// 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 Pad State Select
+#define B_GPIO_PCR_RX_PAD_STATE         BIT29
+#define N_GPIO_PCR_RX_PAD_STATE         29
+#define V_GPIO_PCR_RX_PAD_STATE_RAW     0x00
+#define V_GPIO_PCR_RX_PAD_STATE_INT     0x01
+
+//RX Raw Overrride to 1
+#define B_GPIO_PCR_RX_RAW1              BIT28
+#define N_GPIO_PCR_RX_RAW1              28
+#define V_GPIO_PCR_RX_RAW1_DIS          0x00
+#define V_GPIO_PCR_RX_RAW1_EN           0x01
+
+//RX Level/Edge Configuration
+#define B_GPIO_PCR_RX_LVL_EDG           (BIT26 | BIT25)
+#define N_GPIO_PCR_RX_LVL_EDG           25
+#define V_GPIO_PCR_RX_LVL_EDG_LVL       0x00
+#define V_GPIO_PCR_RX_LVL_EDG_EDG       0x01
+#define V_GPIO_PCR_RX_LVL_EDG_0         0x02
+#define V_GPIO_PCR_RX_LVL_EDG_RIS_FAL   0x03
+
+//RX Invert
+#define B_GPIO_PCR_RXINV                BIT23
+#define N_GPIO_PCR_RXINV                23
+#define V_GPIO_PCR_RXINV_NO             0x00
+#define V_GPIO_PCR_RXINV_YES            0x01
+
+//GPIO Input Route IOxAPIC
+#define B_GPIO_PCR_RX_APIC_ROUTE        BIT20
+#define N_GPIO_PCR_RX_APIC_ROUTE        20
+#define V_GPIO_PCR_RX_APIC_ROUTE_DIS    0x00
+#define V_GPIO_PCR_RX_APIC_ROUTE_EN     0x01
+
+//GPIO Input Route SCI
+#define B_GPIO_PCR_RX_SCI_ROUTE         BIT19
+#define N_GPIO_PCR_RX_SCI_ROUTE         19
+#define V_GPIO_PCR_RX_SCI_ROUTE_DIS     0x00
+#define V_GPIO_PCR_RX_SCI_ROUTE_EN      0x01
+
+//GPIO Input Route SMI
+#define B_GPIO_PCR_RX_SMI_ROUTE         BIT18
+#define N_GPIO_PCR_RX_SMI_ROUTE         18
+#define V_GPIO_PCR_RX_SMI_ROUTE_DIS     0x00
+#define V_GPIO_PCR_RX_SMI_ROUTE_EN      0x01
+
+//GPIO Input Route NMI
+#define B_GPIO_PCR_RX_NMI_ROUTE         BIT17
+#define N_GPIO_PCR_RX_NMI_ROUTE         17
+#define V_GPIO_PCR_RX_NMI_ROUTE_DIS     0x00
+#define V_GPIO_PCR_RX_NMI_ROUTE_EN      0x01
+
+//GPIO Pad Mode
+#define B_GPIO_PCR_PAD_MODE             (BIT12 | BIT11 | BIT10)
+#define N_GPIO_PCR_PAD_MODE             10
+#define V_GPIO_PCR_PAD_MODE_GPIO        0
+#define V_GPIO_PCR_PAD_MODE_NAT_1       1
+#define V_GPIO_PCR_PAD_MODE_NAT_2       2
+#define V_GPIO_PCR_PAD_MODE_NAT_3       3
+#define V_GPIO_PCR_PAD_MODE_NAT_4       4 // SPT-H only
+
+//GPIO RX Disable
+#define B_GPIO_PCR_RXDIS                BIT9
+#define N_GPIO_PCR_RXDIS                9
+#define V_GPIO_PCR_RXDIS_EN             0x00
+#define V_GPIO_PCR_RXDIS_DIS            0x01
+
+//GPIO TX Disable
+#define B_GPIO_PCR_TXDIS                BIT8
+#define N_GPIO_PCR_TXDIS                8
+#define V_GPIO_PCR_TXDIS_EN             0x00
+#define V_GPIO_PCR_TXDIS_DIS            0x01
+
+//GPIO RX State
+#define B_GPIO_PCR_RX_STATE             BIT1
+#define N_GPIO_PCR_RX_STATE             1
+#define V_GPIO_PCR_RX_STATE_LOW         0x00
+#define V_GPIO_PCR_RX_STATE_HIGH        0x01
+
+//GPIO TX State
+#define B_GPIO_PCR_TX_STATE             BIT0
+#define N_GPIO_PCR_TX_STATE             0
+#define V_GPIO_PCR_TX_STATE_LOW         0x00
+#define V_GPIO_PCR_TX_STATE_HIGH        0x01
+
+//
+// Pad Configuration Register DW1
+//
+
+//Padtol
+#define B_GPIO_PCR_PADTOL               BIT25
+#define N_GPIO_PCR_PADTOL               25
+#define V_GPIO_PCR_PADTOL_NONE          0x00
+#define V_GPIO_PCR_PADTOL_CLEAR         0x00
+#define V_GPIO_PCR_PADTOL_SET           0x01
+
+//Termination
+#define B_GPIO_PCR_TERM                (BIT13 | BIT12 | BIT11 | BIT10)
+#define N_GPIO_PCR_TERM                 10
+#define V_GPIO_PCR_TERM_WPD_NONE        0x00
+#define V_GPIO_PCR_TERM_WPD_5K          0x02
+#define V_GPIO_PCR_TERM_WPD_20K         0x04
+#define V_GPIO_PCR_TERM_WPU_NONE        0x08
+#define V_GPIO_PCR_TERM_WPU_1K          0x09
+#define V_GPIO_PCR_TERM_WPU_2K          0x0B
+#define V_GPIO_PCR_TERM_WPU_5K          0x0A
+#define V_GPIO_PCR_TERM_WPU_20K         0x0C
+#define V_GPIO_PCR_TERM_WPU_1K_2K       0x0D
+#define V_GPIO_PCR_TERM_NATIVE          0x0F
+
+//Interrupt number
+#define B_GPIO_PCR_INTSEL               0x7F
+#define N_GPIO_PCR_INTSEL               0
+
+//
+//Debounce
+#define B_GPIO_PCR_DEBOUNCE             (BIT4 | BIT3 | BIT2 | BIT1)
+#define N_GPIO_PCR_DEBOUNCE              1
+
+//Debounce Enable
+#define B_GPIO_PCR_DEBEN                 BIT0
+#define N_GPIO_PCR_DEBEN                 0
+
+//
+// Ownership
+//
+#define V_GPIO_PCR_OWN_GPIO             0x01
+#define V_GPIO_PCR_OWN_ACPI             0x00
+
+//
+// GPE
+//
+#define V_GPIO_PCR_GPE_EN               0x01
+#define V_GPIO_PCR_GPE_DIS              0x00
+//
+// SMI
+//
+#define V_GPIO_PCR_SMI_EN               0x01
+#define V_GPIO_PCR_SMI_DIS              0x00
+//
+// NMI
+//
+#define V_GPIO_PCR_NMI_EN               0x01
+#define V_GPIO_PCR_NMI_DIS              0x00
+
+//
+// GPIO native features pins data
+//
+#define PCH_GPIO_HDA_LINK_NUMBER_OF_PINS     6
+#define PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS     2
+#define PCH_GPIO_HDA_SSP_NUMBER_OF_PINS      4
+#define PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS     2
+#define PCH_GPIO_SMBUS_NUMBER_OF_PINS        2
+#define PCH_GPIO_CPU_GP_NUMBER_OF_PINS       4
+#define PCH_GPIO_EDP_NUMBER_OF_PINS          4
+#define PCH_GPIO_DDSP_HPD_NUMBER_OF_PINS     4
+#define PCH_GPIO_DDP_NUMBER_OF_INTERFACES    4
+#define PCH_GPIO_DDP_NUMBER_OF_PINS          2
+#define PCH_GPIO_CNVI_UART_NUMBER_OF_PINS    4
+#define PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS     4
+#define PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS 4
+
+
+///
+/// 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_EN                4
+#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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
new file mode 100644
index 0000000000..140c758730
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
@@ -0,0 +1,694 @@
+/** @file
+  Register names for 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_GPIO_CNL_H_
+#define _PCH_REGS_GPIO_CNL_H_
+
+//
+// PCH-LP GPIO
+//
+#define CNL_PCH_LP_GPIO_GROUP_MAX             15
+
+#define CNL_PCH_LP_GPIO_GPP_A_PAD_MAX         25
+#define CNL_PCH_LP_GPIO_GPP_B_PAD_MAX         26
+#define CNL_PCH_LP_GPIO_GPP_C_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_D_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_E_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_F_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_G_PAD_MAX         8
+#define CNL_PCH_LP_GPIO_GPP_H_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPD_PAD_MAX           16
+#define CNL_PCH_LP_GPIO_VGPIO_PAD_MAX         40
+#define CNL_PCH_LP_GPIO_SPI_PAD_MAX           9
+#define CNL_PCH_LP_GPIO_AZA_PAD_MAX           8
+#define CNL_PCH_LP_GPIO_CPU_PAD_MAX           11
+#define CNL_PCH_LP_GPIO_JTAG_PAD_MAX          9
+#define CNL_PCH_LP_GPIO_HVMOS_PAD_MAX         6
+
+//
+// PCH-H GPIO
+//
+#define CNL_PCH_H_GPIO_GROUP_MAX              17
+
+#define CNL_PCH_H_GPIO_GPP_A_PAD_MAX          25
+#define CNL_PCH_H_GPIO_GPP_B_PAD_MAX          26
+#define CNL_PCH_H_GPIO_GPP_C_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_D_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_E_PAD_MAX          13
+#define CNL_PCH_H_GPIO_GPP_F_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_G_PAD_MAX          8
+#define CNL_PCH_H_GPIO_GPP_H_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_I_PAD_MAX          18
+#define CNL_PCH_H_GPIO_GPP_J_PAD_MAX          12
+#define CNL_PCH_H_GPIO_GPP_K_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPD_PAD_MAX            16
+#define CNL_PCH_H_GPIO_VGPIO_PAD_MAX          40
+#define CNL_PCH_H_GPIO_SPI_PAD_MAX            9
+#define CNL_PCH_H_GPIO_AZA_PAD_MAX            8
+#define CNL_PCH_H_GPIO_CPU_PAD_MAX            11
+#define CNL_PCH_H_GPIO_JTAG_PAD_MAX           9
+
+//
+// PCH-LP GPIO registers
+//
+//
+// GPIO Community Common Private Configuration Registers
+//
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A     0x0
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B     0x1
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C     0xC
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D     0x4
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E     0xD
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F     0x5
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G     0x2
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H     0x6
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD       0x9
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO     0x7
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI       0x3
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA       0xA
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_CPU       0xB
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG      0xE
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_HVMOS     0xF
+
+//
+// GPIO Community 0 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN        0x20
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN        0x30
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN        0x40
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN          0x44
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK     0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX   0x84
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK     0x88
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX   0x8C
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK     0x90
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX   0x94
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK       0x98
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX     0x9C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN     0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN     0xB4
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN     0xB8
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN       0xBC
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS         0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS         0x0104
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS         0x0108
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS           0x010C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE         0x0120
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE         0x0124
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE         0x0128
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE           0x012C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS    0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS    0x0144
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS    0x0148
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS      0x014C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN     0x0160
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN     0x0164
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN     0x0168
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN       0x016C
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_SMI_STS        0x0180  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS        0x0184
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_SMI_STS        0x0188  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_SMI_STS          0x018C  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_SMI_EN         0x01A0  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN         0x01A4
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_SMI_EN         0x01A8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_SMI_EN           0x01AC  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_NMI_STS        0x01C0  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS        0x01C4
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_NMI_STS        0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_NMI_STS          0x01CC  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_NMI_EN         0x01E0  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN         0x01E4
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_NMI_EN         0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_NMI_EN           0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET  0x600
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET  0x790
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET  0x930
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET    0x9B0
+
+//
+// GPIO Community 1 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN        0x20
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN        0x30
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN        0x3C
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN        0x48
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK     0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX   0x84
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK     0x88
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX   0x8C
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK     0x90
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX   0x94
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK   0x98
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX 0x9C
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_1_PADCFGLOCK   0xA0
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_1_PADCFGLOCKTX 0xA4
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN     0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN     0xB4
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN     0xB8
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN     0xBC
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS         0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS         0x0104
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS         0x0108
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS         0x010C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE         0x0120
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE         0x0124
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE         0x0128
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE         0x012C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS    0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS    0x0144
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS    0x0148
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS    0x014C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN     0x0160
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN     0x0164
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN     0x0168
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN     0x016C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS        0x0180
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_SMI_STS        0x0184  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_SMI_STS        0x0188  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_SMI_STS        0x018C  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN         0x01A0
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_SMI_EN         0x01A4  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_SMI_EN         0x01A8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_SMI_EN         0x01AC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS        0x01C0
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_NMI_STS        0x01C4  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_NMI_STS        0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_NMI_STS        0x01CC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN         0x01E0
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_NMI_EN         0x01E4  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_NMI_EN         0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_NMI_EN         0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET  0x600
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET  0x790
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET  0x910
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET  0xA90
+
+//
+// GPIO Community 2 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN          0x20
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK       0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX     0x84
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN       0xB0
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS           0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE           0x0120
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS      0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN       0x0160
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_SMI_STS        0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_SMI_EN         0x01A0  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_NMI_STS        0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_NMI_EN         0x01E0  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET    0x600
+
+//
+// GPIO Community 3 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN          0x20
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN          0x24
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK       0x80
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX     0x84
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK       0x88
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX     0x8C
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN       0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN       0xB4
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS           0x0100
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_IS           0x0104  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE           0x0120
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_IE           0x0124  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS      0x0140
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_GPE_STS      0x0144  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN       0x0160
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_GPE_EN       0x0164  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_SMI_STS          0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_SMI_STS          0x0184  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_SMI_EN           0x01A0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_SMI_EN           0x01A4  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_NMI_STS          0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_NMI_STS          0x01C4  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_NMI_EN           0x01E0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_NMI_EN           0x01E4  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET    0x600
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET    0x680
+
+//
+// GPIO Community 4 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN        0x20
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN        0x2C
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN         0x38
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN        0x40
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK     0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX   0x84
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK     0x88
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX   0x8C
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK      0x90
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK     0x98
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX   0x9C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN     0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN     0xB4
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN      0xB8
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN     0xBC
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS         0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS         0x0104
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_IS          0x0108  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS         0x010C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE         0x0120
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE         0x0124
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_IE          0x0128  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE         0x012C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS    0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS    0x0144
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_GPE_STS     0x0148  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS    0x014C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN     0x0160
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN     0x0164
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_GPE_EN      0x0168  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN     0x016C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS        0x0180
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS        0x0184
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_SMI_STS         0x0188  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_SMI_STS        0x018C  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN         0x01A0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN         0x01A4
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_SMI_EN          0x01A8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_SMI_EN         0x01AC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS        0x01C0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS        0x01C4
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_NMI_STS         0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_NMI_STS        0x01CC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN         0x01E0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN         0x01E4
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_NMI_EN          0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_NMI_EN         0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET  0x600
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET  0x780
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET   0x900
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET  0x990
+
+//
+// PCH-H GPIO registers
+//
+//
+// GPIO Community Common Private Configuration Registers
+//
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A      0x0
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B      0x1
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C      0x2
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D      0x3
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E      0x6
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F      0x7
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G      0x4
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H      0x8
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K      0x9
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I      0xA
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J      0xB
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD        0x5
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO      0xD
+
+//
+// GPIO Community 0 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN         0x20
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN         0x30
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK      0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX    0x84
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK      0x88
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX    0x8C
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN      0xC0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN      0xC4
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS          0x0100
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS          0x0104
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE          0x0120
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE          0x0124
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS     0x0140
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS     0x0144
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN      0x0160
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN      0x0164
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_SMI_STS         0x0180  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS         0x0184
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_SMI_EN          0x01A0  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN          0x01A4
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_NMI_STS         0x01C0  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS         0x01C4
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_NMI_EN          0x01E0  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN          0x01E4
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET   0x600
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET   0x790
+
+//
+// GPIO Community 1 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN         0x20
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN         0x2C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN         0x38
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN           0x3C
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN         0x40
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK      0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX    0x84
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK      0x88
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX    0x8C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK      0x90
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK        0x98
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX      0x9C
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK    0xA0
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX  0xA4
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_1_PADCFGLOCK    0xA8
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_1_PADCFGLOCKTX  0xAC
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN      0xC0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN      0xC4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN      0xC8
+#define R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN        0xCC
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN      0xD0
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS          0x0100
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS          0x0104
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS          0x0108
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_IS            0x010C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS          0x0110
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE          0x0120
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE          0x0124
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE          0x0128
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_IE            0x012C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE          0x0130
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS     0x0140
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS     0x0144
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS     0x0148
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_GPE_STS       0x014C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS     0x0150
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN      0x0160
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN      0x0164
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN      0x0168
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_GPE_EN        0x016C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN      0x0170
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS         0x0180
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS         0x0184
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS         0x0188
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_SMI_STS           0x018C  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_SMI_STS         0x0190  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN          0x01A0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN          0x01A4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN          0x01A8
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_SMI_EN            0x01AC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_SMI_EN          0x01B0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS         0x01C0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS         0x01C4
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_G_NMI_STS         0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_NMI_STS           0x01CC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_NMI_STS         0x01D0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN          0x01E0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN          0x01E4
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_G_NMI_EN          0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_NMI_EN            0x01EC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_NMI_EN          0x01F0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET   0x600
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET   0x780
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET   0x900
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET     0x980
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET   0xA00
+
+//
+// GPIO Community 2 Private Configuration Registers
+//
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN           0x20
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK        0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX      0x84
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN        0xB0
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS            0x0100
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE            0x0120
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS       0x0140
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN        0x0160
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_SMI_STS         0x0180  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_SMI_EN          0x01A0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_NMI_STS         0x01C0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_NMI_EN          0x01E0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET     0x600
+
+//
+// GPIO Community 3 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN         0x20
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN         0x2C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN         0x38
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN         0x40
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN           0x4C
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK      0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX    0x84
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK      0x88
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX    0x8C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK      0x90
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK      0x98
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX    0x9C
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK        0xA0
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX      0xA4
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN      0xC0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN      0xC4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN      0xC8
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN      0xCC
+#define R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN        0xD0
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS          0x0100
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS          0x0104
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS          0x0108
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS          0x010C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_IS            0x0110  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE          0x0120
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE          0x0124
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE          0x0128
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE          0x012C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_IE            0x0130  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS     0x0140
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS     0x0144
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS     0x0148
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS     0x014C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_GPE_STS       0x0150  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN      0x0160
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN      0x0164
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN      0x0168
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN      0x016C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_GPE_EN        0x0170  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_SMI_STS         0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_SMI_STS         0x0184  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS         0x0188
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_SMI_STS         0x018C  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_SMI_STS           0x0190  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_SMI_EN          0x01A0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_SMI_EN          0x01A4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN          0x01A8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_SMI_EN          0x01AC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_SMI_EN            0x01B0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_NMI_STS         0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_NMI_STS         0x01C4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS         0x01C8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_NMI_STS         0x01CC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_NMI_STS           0x01D0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_NMI_EN          0x01E0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_NMI_EN          0x01E4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN          0x01E8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_NMI_EN          0x01EC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_NMI_EN            0x01F0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET   0x600
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET   0x780
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET   0x900
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET   0x9D0
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET     0xB50
+
+//
+// GPIO Community 4 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN           0x20
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN          0x28
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN         0x30
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN         0x3C
+
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK        0x80
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX      0x84
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK       0x88
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX     0x8C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK      0x90
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK      0x98
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX    0x9C
+
+#define R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN        0xC0
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN       0xC4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN      0xC8
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN      0xCC
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_IS            0x0100  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_IS           0x0104  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS          0x0108
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS          0x010C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_IE            0x0120  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_IE           0x0124  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE          0x0128
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE          0x012C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_GPE_STS       0x0140  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_GPE_STS      0x0144  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS     0x0148
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS     0x014C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_GPE_EN        0x0160  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_GPE_EN       0x0164  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN      0x0168
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN      0x016C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_SMI_STS           0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_SMI_STS          0x0184  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS         0x0188
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_SMI_STS         0x018C  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_SMI_EN            0x01A0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_SMI_EN           0x01A4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN          0x01A8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_SMI_EN          0x01AC  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_NMI_STS           0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_NMI_STS          0x01C4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS         0x01C8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_NMI_STS         0x01CC  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_NMI_EN            0x01E0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_NMI_EN           0x01E4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN          0x01E8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_NMI_EN          0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET     0x600
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET    0x6B0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET   0x740
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET   0x860
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
new file mode 100644
index 0000000000..bc099d9662
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
@@ -0,0 +1,204 @@
+/** @file
+  Register names for PCH 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_HDA_H_
+#define _PCH_REGS_HDA_H_
+
+//
+// HD-A Controller Registers (D31:F3)
+//
+// PCI Configuration Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_HDA               31
+#define PCI_FUNCTION_NUMBER_PCH_HDA             3
+
+#define R_HDA_CFG_PI                            0x09
+#define V_HDA_CFG_PI_ADSP_UAA                   0x80
+#define R_HDA_CFG_SCC                           0x0A
+#define V_HDA_CFG_SCC_ADSP                      0x01
+#define R_HDA_CFG_HDALBA                        0x10
+#define B_HDA_CFG_HDALBA_LBA                    0xFFFFC000
+#define V_HDA_CFG_HDBAR_SIZE                    (1 << 14)
+#define R_HDA_CFG_HDAUBA                        0x14
+#define B_HDA_CFG_HDAUBA_UBA                    0xFFFFFFFF
+#define R_HDA_CFG_CGCTL                         0x48
+#define B_HDA_CFG_CGCTL_RSMTCGE                 BIT18
+#define B_HDA_CFG_CGCTL_MISCBDCGE               BIT6
+#define R_HDA_CFG_PC                            0x52
+#define V_HDA_CFG_PC_PMES                       0x18
+#define N_HDA_CFG_PC_PMES                       11
+#define R_HDA_CFG_PCS                           0x54
+#define B_HDA_CFG_PCS_PMEE                      BIT8
+#define B_HDA_CFG_PCS_PS                        (BIT1 | BIT0)
+#define R_HDA_CFG_MMC                           0x62
+#define B_HDA_CFG_MMC_ME                        BIT0
+#define R_HDA_CFG_DEVC                          0x78
+#define B_HDA_CFG_DEVC_NSNPEN                   BIT11
+#define R_HDA_CFG_SEM1                          0xC0
+#define B_HDA_CFG_SEM1_LFLCS                    BIT24
+#define B_HDA_CFG_SEM1_BLKC3DIS                 BIT17
+#define B_HDA_CFG_SEM1_TMODE                    BIT12
+#define B_HDA_CFG_SEM1_FIFORDYSEL               (BIT10 | BIT9)
+#define R_HDA_CFG_SEM2                          0xC4
+#define B_HDA_CFG_SEM2_BSMT                     (BIT27 | BIT26)
+#define V_HDA_CFG_SEM2_BSMT                     0x1
+#define N_HDA_CFG_SEM2_BSMT                     26
+#define B_HDA_CFG_SEM2_VC0SNR                   BIT24
+#define B_HDA_CFG_SEM2_DUM                      BIT23
+#define R_HDA_CFG_SEM3L                         0xC8
+#define B_HDA_CFG_SEM3L_ISL1EXT2                (BIT21 | BIT20)
+#define V_HDA_CFG_SEM3L_ISL1EXT2                0x2
+#define N_HDA_CFG_SEM3L_ISL1EXT2                20
+#define R_HDA_CFG_SEM4L                         0xD0
+#define B_HDA_CFG_SEM4L_OSL1EXT2                (BIT21 | BIT20)
+#define V_HDA_CFG_SEM4L_OSL1EXT2                0x3
+#define N_HDA_CFG_SEM4L_OSL1EXT2                20
+
+//
+// Memory Space Registers
+//
+//
+// Resides in 'HD Audio Global Registers' (0000h)
+//
+#define R_HDA_MEM_GCAP                        0x00
+#define R_HDA_MEM_GCTL                        0x08
+#define B_HDA_MEM_GCTL_CRST                   BIT0
+
+#define R_HDA_MEM_OUTPAY                      0x04
+#define R_HDA_MEM_INPAY                       0x06
+#define V_HDA_MEM_INPAY_DEFAULT               0x1C
+
+#define R_HDA_MEM_WAKEEN                      0x0C
+#define B_HDA_MEM_WAKEEN_SDI_3                BIT3
+#define B_HDA_MEM_WAKEEN_SDI_2                BIT2
+#define B_HDA_MEM_WAKEEN_SDI_1                BIT1
+#define B_HDA_MEM_WAKEEN_SDI_0                BIT0
+
+#define R_HDA_MEM_WAKESTS                     0x0E
+#define B_HDA_MEM_WAKESTS_SDIN3               BIT3
+#define B_HDA_MEM_WAKESTS_SDIN2               BIT2
+#define B_HDA_MEM_WAKESTS_SDIN1               BIT1
+#define B_HDA_MEM_WAKESTS_SDIN0               BIT0
+
+//
+// Resides in 'HD Audio Controller Registers' (0030h)
+//
+#define R_HDA_MEM_IC                          0x60
+#define R_HDA_MEM_IR                          0x64
+#define R_HDA_MEM_ICS                         0x68
+#define B_HDA_MEM_ICS_IRV                     BIT1
+#define B_HDA_MEM_ICS_ICB                     BIT0
+
+//
+// Resides in 'HD Audio Processing Pipe Capability Structure' (0800h)
+//
+#define R_HDA_MEM_PPC                         0x0800 // Processing Pipe Capability Structure (Memory Space, offset 0800h)
+#define R_HDA_MEM_PPCTL                       (R_HDA_MEM_PPC + 0x04)
+#define B_HDA_MEM_PPCTL_GPROCEN               BIT30
+
+//
+// Resides in 'HD Audio Multiple Links Capability Structure' (0C00h)
+//
+#define HDA_HDALINK_INDEX                     0
+#define HDA_IDISPLINK_INDEX                   1
+
+#define R_HDA_MEM_MLC                         0x0C00 // Multiple Links Capability Structure (Memory Space, offset 0C00h)
+#define R_HDA_MEM_LCTLX(x)                    (R_HDA_MEM_MLC + (0x40 + (0x40 * (x)) + 0x04)) // x - Link index: 0 - HDA Link, 1 - iDisp Link
+#define B_HDA_MEM_LCTLX_CPA                   BIT23
+#define B_HDA_MEM_LCTLX_SPA                   BIT16
+#define N_HDA_MEM_LCTLX_SCF                   0
+#define V_HDA_MEM_LCTLX_SCF_6MHZ              0x0
+#define V_HDA_MEM_LCTLX_SCF_12MHZ             0x1
+#define V_HDA_MEM_LCTLX_SCF_24MHZ             0x2
+#define V_HDA_MEM_LCTLX_SCF_48MHZ             0x3
+#define V_HDA_MEM_LCTLX_SCF_96MHZ             0x4
+
+//
+// Resides in 'HD Audio Vendor Specific Registers' (1000h)
+//
+#define R_HDA_MEM_LTRC                        0x1048
+#define V_HDA_MEM_LTRC_GB                     0x29
+#define N_HDA_MEM_LTRC_GB                     0
+#define R_HDA_MEM_PCE                         0x104B
+#define B_HDA_MEM_PCE_D3HE                    BIT2
+
+//
+// Private Configuration Space Registers
+//
+//
+// Resides in IOSF & Fabric Configuration Registers (000h)
+//
+#define R_HDA_PCR_TTCCFG                    0xE4
+#define B_HDA_PCR_TTCCFG_HCDT               BIT1
+
+//
+// Resides in PCI & Codec Configuration Registers (500h)
+//
+#define R_HDA_PCR_PCICDCCFG                 0x500 // PCI & Codec Configuration Registers (PCR, offset 500h)
+#define B_HDA_PCR_PCICDCCFG_ACPIIN          0x0000FF00
+#define N_HDA_PCR_PCICDCCFG_ACPIIN          8
+#define R_HDA_PCR_FNCFG                     (R_HDA_PCR_PCICDCCFG + 0x30)
+#define B_HDA_PCR_FNCFG_PGD                 BIT5
+#define B_HDA_PCR_FNCFG_BCLD                BIT4
+#define B_HDA_PCR_FNCFG_CGD                 BIT3
+#define B_HDA_PCR_FNCFG_ADSPD               BIT2
+#define B_HDA_PCR_FNCFG_HDASD               BIT0
+#define R_HDA_PCR_CDCCFG                    (R_HDA_PCR_PCICDCCFG + 0x34)
+#define B_HDA_PCR_CDCCFG_DIS_SDIN2          BIT2
+
+//
+// Resides in Power Management & EBB Configuration Registers (600h)
+//
+#define R_HDA_PCR_PWRMANCFG                 0x600 // Power Management & EBB Configuration Registers (PCR, offset 600h)
+#define R_HDA_PCR_APLLP0                    (R_HDA_PCR_PWRMANCFG + 0x10)
+#define V_HDA_PCR_APLLP0                    0xFC1E0000
+#define R_HDA_PCR_APLLP1                    (R_HDA_PCR_PWRMANCFG + 0x14)
+#define V_HDA_PCR_APLLP1                    0x00003F00
+#define R_HDA_PCR_APLLP2                    (R_HDA_PCR_PWRMANCFG + 0x18)
+#define V_HDA_PCR_APLLP2                    0x0000011D
+#define R_HDA_PCR_IOBCTL                    (R_HDA_PCR_PWRMANCFG + 0x1C)
+#define B_HDA_PCR_IOBCTL_OSEL               (BIT9 | BIT8)
+#define V_HDA_PCR_IOBCTL_OSEL_HDALINK       0
+#define V_HDA_PCR_IOBCTL_OSEL_HDALINK_I2S   1
+#define V_HDA_PCR_IOBCTL_OSEL_I2S           3
+#define N_HDA_PCR_IOBCTL_OSEL               8
+#define B_HDA_PCR_IOBCTL_VSEL               BIT1
+#define R_HDA_PCR_PTDC                      (R_HDA_PCR_PWRMANCFG + 0x28)
+#define B_HDA_PCR_PTDC_SRMIW                (BIT6 | BIT5 | BIT4)
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
new file mode 100644
index 0000000000..0cd69eb299
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
@@ -0,0 +1,170 @@
+/** @file
+  Register definition for HSIO
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_HSIO_H_
+#define _PCH_REGS_HSIO_H_
+
+#define B_HSIO_PCR_ACCESS_TYPE                          (BIT15 | BIT14)
+#define N_HSIO_PCR_ACCESS_TYPE                          14
+#define V_HSIO_PCR_ACCESS_TYPE_BDCAST                   (BIT15 | BIT14)
+#define V_HSIO_PCR_ACCESS_TYPE_MULCAST                  BIT15
+#define B_HSIO_PCR_LANE_GROUP_NO                        (BIT13 | BIT12 | BIT11 | BIT10 | BIT9)
+#define B_HSIO_PCR_FUNCTION_NO                          (BIT8  | BIT7)
+#define N_HSIO_PCR_FUNCTION_NO                          7
+#define B_HSIO_PCR_REG_OFFSET                           (BIT6  | BIT5  | BIT4  | BIT3  | BIT2  | BIT1  | BIT0)
+
+#define V_HSIO_PCR_ACCESS_TYPE_BCAST                    0x03
+#define V_HSIO_PCR_ACCESS_TYPE_MCAST                    0x02
+#define V_HSIO_PCR_ACCESS_TYPE_UCAST                    0x00
+
+#define V_HSIO_PCR_LANE_GROUP_NO_CMN_LANE               0x00
+
+#define V_HSIO_PCR_FUNCTION_NO_PCS                      0x00
+#define V_HSIO_PCR_FUNCTION_NO_TX                       0x01
+#define V_HSIO_PCR_FUNCTION_NO_RX                       0x02
+
+#define V_HSIO_PCR_FUNCTION_NO_CMNDIG                   0x00
+#define V_HSIO_PCR_FUNCTION_NO_CMNANA                   0x01
+#define V_HSIO_PCR_FUNCTION_NO_PLL                      0x02
+
+#define R_HSIO_PCR_PCS_DWORD4                           0x10
+
+#define R_HSIO_PCR_PCS_DWORD8                           0x20
+#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_PTR_INIT_4_0     0x1F000000
+#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_LOWATER_4_0      0x001F0000
+#define N_HSIO_PCR_PCS_DWORD8_CRI_RXEB_LOWATER_4_0      16
+#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_HIWATER_4_0      0x00001F00
+#define N_HSIO_PCR_PCS_DWORD8_CRI_RXEB_HIWATER_4_0      8
+
+#define R_HSIO_PCR_PCS_DWORD9                           0x24
+#define B_HSIO_PCR_PCS_DWORD9_REG_ENABLE_PWR_GATING     BIT29
+
+#define R_HSIO_PCR_RX_DWORD8                            0x220
+#define B_HSIO_PCR_RX_DWORD8_ICFGDFETAP3_EN             BIT10
+
+#define R_HSIO_PCR_RX_DWORD9                            0x224
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP4_OVERRIDE_EN     BIT24
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP3_OVERRIDE_EN     BIT26
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP2_OVERRIDE_EN     BIT28
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP1_OVERRIDE_EN     BIT30
+
+#define R_HSIO_PCR_RX_DWORD12                           0x230
+#define B_HSIO_PCR_RX_DWORD12_O_CFGEWMARGINSEL          BIT14
+
+#define R_HSIO_PCR_RX_DWORD20                               0x250
+#define B_HSIO_PCR_RX_DWORD20_ICFGCTLEDATATAP_FULLRATE_5_0  (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
+#define N_HSIO_PCR_RX_DWORD20_ICFGCTLEDATATAP_FULLRATE_5_0  24
+
+#define R_HSIO_PCR_RX_DWORD21                               0x254
+#define B_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_QUATRATE_5_0  (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_QUATRATE_5_0  8
+#define B_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_HALFRATE_5_0  (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define N_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_HALFRATE_5_0  0
+
+#define R_HSIO_PCR_RX_DWORD23                               0x25C
+#define B_HSIO_PCR_RX_DWORD23_ICFGVGABLWTAP_OVERRIDE_EN     BIT2
+#define B_HSIO_PCR_RX_DWORD23_CFGVGATAP_ADAPT_OVERRIDE_EN   BIT4
+
+#define R_HSIO_PCR_RX_DWORD25                            0x264
+#define B_HSIO_PCR_RX_DWORD25_RX_TAP_CFG_CTRL            BIT3
+#define B_HSIO_PCR_RX_DWORD25_CTLE_ADAPT_OFFSET_CFG_4_0  0x1F0000
+#define N_HSIO_PCR_RX_DWORD25_CTLE_ADAPT_OFFSET_CFG_4_0  16
+
+#define R_HSIO_PCR_RX_DWORD26                           0x268
+#define B_HSIO_PCR_RX_DWORD26_SATA_EQ_DIS               BIT16
+
+#define R_HSIO_PCR_RX_DWORD34                           0x288
+#define B_HSIO_PCR_RX_DWORD34_MM_PH_OFC_SCALE_2_0       (BIT14 | BIT13 | BIT12)
+#define N_HSIO_PCR_RX_DWORD34_MM_PH_OFC_SCALE_2_0       12
+
+#define R_HSIO_PCR_RX_DWORD44                           0x2B0
+#define B_HSIO_PCR_RX_DWORD44_0_DFE_DATASUMCAL0_7_0     0xFF0000
+#define N_HSIO_PCR_RX_DWORD44_0_DFE_DATASUMCAL0_7_0     16
+
+#define R_HSIO_PCR_RX_DWORD56                           0x2E0
+#define B_HSIO_PCR_RX_DWORD56_ICFGPIDACCFGVALID         BIT16
+
+#define R_HSIO_PCR_RX_DWORD57                           0x2E4
+#define B_HSIO_PCR_RX_DWORD57_JIM_COURSE                BIT30
+#define B_HSIO_PCR_RX_DWORD57_JIM_ENABLE                BIT29
+#define B_HSIO_PCR_RX_DWORD57_JIMMODE                   BIT28
+#define B_HSIO_PCR_RX_DWORD57_JIMNUMCYCLES_3_0          0x0F000000
+#define N_HSIO_PCR_RX_DWORD57_JIMNUMCYCLES_3_0          24
+#define B_HSIO_PCR_RX_DWORD57_ICFGMARGINEN              BIT0
+
+#define R_HSIO_PCR_RX_DWORD59                           0x2EC
+#define R_HSIO_PCR_RX_DWORD60                           0x2F0
+
+#define R_HSIO_PCR_TX_DWORD5                            0x154
+#define B_HSIO_PCR_TX_DWORD5_OW2TAPGEN2DEEMPH3P5_5_0    (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_TX_DWORD5_OW2TAPGEN2DEEMPH3P5_5_0    16
+#define B_HSIO_PCR_TX_DWORD5_OW2TAPGEN1DEEMPH3P5_5_0    (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_TX_DWORD5_OW2TAPGEN1DEEMPH3P5_5_0    8
+
+#define R_HSIO_PCR_TX_DWORD6                            0x158
+#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN3DEEMPH6P0_5_0    (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_TX_DWORD6_OW2TAPGEN3DEEMPH6P0_5_0    16
+#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN2DEEMPH6P0_5_0    (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_TX_DWORD6_OW2TAPGEN2DEEMPH6P0_5_0    8
+#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN1DEEMPH6P0_5_0    (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#define R_HSIO_PCR_TX_DWORD8                            0x160
+#define B_HSIO_PCR_TX_DWORD8_ORATE10MARGIN_5_0          (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
+#define N_HSIO_PCR_TX_DWORD8_ORATE10MARGIN_5_0          24
+#define B_HSIO_PCR_TX_DWORD8_ORATE01MARGIN_5_0          (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_TX_DWORD8_ORATE01MARGIN_5_0          16
+#define B_HSIO_PCR_TX_DWORD8_ORATE00MARGIN_5_0          (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_TX_DWORD8_ORATE00MARGIN_5_0          8
+
+#define R_HSIO_PCR_TX_DWORD19                           0x18C
+
+#define R_HSIO_PCR_CLANE0_CMN_ANA_DWORD2                0x80C8
+#define B_HSIO_PCR_CLANE0_CMN_ANA_DWORD2_O_DTPLL1_lC_PLLEN_H_OVRDEN                BIT5
+#define B_HSIO_PCR_CLANE0_CMN_ANA_DWORD2_O_DTPLL1_lC_FULLCALRESET_L_OVERDEN        BIT3
+
+#define R_HSIO_PCR_PLL_SSC_DWORD2                       0x8188
+#define B_HSIO_PCR_PLL_SSC_DWORD2_SSCSTEPSIZE_7_0       (BIT23 | BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_PLL_SSC_DWORD2_SSCSTEPSIZE_7_0       16
+#define B_HSIO_PCR_PLL_SSC_DWORD2_SSCSEN                BIT10
+#define N_HSIO_PCR_PLL_SSC_DWORD2_SSCSEN                10
+
+#define R_HSIO_PCR_PLL_SSC_DWORD3                       0x818C
+#define B_HSIO_PCR_PLL_SSC_DWORD3_SSC_PROPAGATE         BIT0
+
+
+#endif //_PCH_REGS_HSIO_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
new file mode 100644
index 0000000000..5b4e23c43f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
@@ -0,0 +1,79 @@
+/** @file
+  Register names for PCH Integrated Sensor Hub (ISH3.0)
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_ISH_H_
+#define _PCH_REGS_ISH_H_
+
+//
+// ISH Controller Registers
+//
+// D19:F0
+#define PCI_DEVICE_NUMBER_PCH_ISH             19
+#define PCI_FUNCTION_NUMBER_PCH_ISH           0
+
+// PCI Configuration Space Registers
+#define R_ISH_CFG_BAR0_LOW                    0x10
+#define R_ISH_CFG_BAR0_HIGH                   0x14
+#define V_ISH_CFG_BAR0_SIZE                   0x100000
+#define N_ISH_CFG_BAR0_ALIGNMENT              20
+#define R_ISH_CFG_BAR1_LOW                    0x18
+#define R_ISH_CFG_BAR1_HIGH                   0x1C
+#define V_ISH_CFG_BAR1_SIZE                   0x1000
+#define N_ISH_CFG_BAR1_ALIGNMENT              12
+
+//
+// ISH Private Configuration Space Registers (IOSF2OCP)
+// (PID:ISH)
+//
+#define R_ISH_PCR_PMCTL                   0x1D0                         ///< Power Management
+#define R_ISH_PCR_PCICFGCTRL              0x200                         ///< PCI Configuration Control
+#define B_ISH_PCR_PCICFGCTR_PCI_IRQ       0x0FF00000                    ///< PCI IRQ number
+#define N_ISH_PCR_PCICFGCTR_PCI_IRQ       20
+#define B_ISH_PCR_PCICFGCTR_ACPI_IRQ      0x000FF000                    ///< ACPI IRQ number
+#define N_ISH_PCR_PCICFGCTR_ACPI_IRQ      12
+#define B_ISH_PCR_PCICFGCTR_IPIN1         (BIT11 | BIT10 | BIT9 | BIT8) ///< Interrupt Pin
+#define N_ISH_PCR_PCICFGCTR_IPIN1         8
+#define B_ISH_PCR_PCICFGCTRL_BAR1DIS      BIT7                          ///< BAR1 Disable
+
+//
+// Number of pins used by ISH controllers
+//
+#define PCH_ISH_PINS_PER_I2C_CONTROLLER               2
+#define PCH_ISH_PINS_PER_UART_CONTROLLER              4
+#define PCH_ISH_PINS_PER_SPI_CONTROLLER               4
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
new file mode 100644
index 0000000000..8d7c3f9015
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
@@ -0,0 +1,103 @@
+/** @file
+  Register names for ITSS
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_ITSS_H_
+#define _PCH_REGS_ITSS_H_
+
+//
+// ITSS PCRs (PID:ITSS)
+//
+#define R_ITSS_PCR_PIRQA_ROUT             0x3100          ///< PIRQA Routing Control register
+#define R_ITSS_PCR_PIRQB_ROUT             0x3101          ///< PIRQB Routing Control register
+#define R_ITSS_PCR_PIRQC_ROUT             0x3102          ///< PIRQC Routing Control register
+#define R_ITSS_PCR_PIRQD_ROUT             0x3103          ///< PIRQD Routing Control register
+#define R_ITSS_PCR_PIRQE_ROUT             0x3104          ///< PIRQE Routing Control register
+#define R_ITSS_PCR_PIRQF_ROUT             0x3105          ///< PIRQF Routing Control register
+#define R_ITSS_PCR_PIRQG_ROUT             0x3106          ///< PIRQG Routing Control register
+#define R_ITSS_PCR_PIRQH_ROUT             0x3107          ///< PIRQH Routing Control register
+#define B_ITSS_PCR_PIRQX_ROUT_REN         0x80            ///< Interrupt Routing Enable
+#define B_ITSS_PCR_PIRQX_ROUT_IR          0x0F            ///< IRQ Routng
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_3       0x03            ///< Route PIRQx to IRQ3
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_4       0x04            ///< Route PIRQx to IRQ4
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_5       0x05            ///< Route PIRQx to IRQ5
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_6       0x06            ///< Route PIRQx to IRQ6
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_7       0x07            ///< Route PIRQx to IRQ7
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_9       0x09            ///< Route PIRQx to IRQ9
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_10      0x0A            ///< Route PIRQx to IRQ10
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_11      0x0B            ///< Route PIRQx to IRQ11
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_12      0x0C            ///< Route PIRQx to IRQ12
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_14      0x0E            ///< Route PIRQx to IRQ14
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_15      0x0F            ///< Route PIRQx to IRQ15
+
+#define R_ITSS_PCR_PIR0                   0x3140          ///< PCI Interrupt Route 0
+#define R_ITSS_PCR_PIR1                   0x3142          ///< PCI Interrupt Route 1
+#define R_ITSS_PCR_PIR2                   0x3144          ///< PCI Interrupt Route 2
+#define R_ITSS_PCR_PIR3                   0x3146          ///< PCI Interrupt Route 3
+#define R_ITSS_PCR_PIR4                   0x3148          ///< PCI Interrupt Route 4
+#define R_ITSS_PCR_PIR5                   0x314A          ///< PCI Interrupt Route 5
+#define R_ITSS_PCR_PIR6                   0x314C          ///< PCI Interrupt Route 6
+#define R_ITSS_PCR_PIR7                   0x314E          ///< PCI Interrupt Route 7
+#define R_ITSS_PCR_PIR8                   0x3150          ///< PCI Interrupt Route 8
+#define R_ITSS_PCR_PIR9                   0x3152          ///< PCI Interrupt Route 9
+#define R_ITSS_PCR_PIR10                  0x3154          ///< PCI Interrupt Route 10
+#define R_ITSS_PCR_PIR11                  0x3156          ///< PCI Interrupt Route 11
+#define R_ITSS_PCR_PIR12                  0x3158          ///< PCI Interrupt Route 12
+
+#define R_ITSS_PCR_GIC                    0x31FC          ///< General Interrupt Control
+#define B_ITSS_PCR_GIC_MAX_IRQ_24         BIT9            ///< Max IRQ entry size, 1 = 24 entry size, 0 = 120 entry size
+#define B_ITSS_PCR_GIC_AME                BIT17           ///< Alternate Access Mode Enable
+#define B_ITSS_PCR_GIC_SPS                BIT16           ///< Shutdown Policy Select
+#define R_ITSS_PCR_IPC0                   0x3200          ///< Interrupt Polarity Control 0
+#define R_ITSS_PCR_IPC1                   0x3204          ///< Interrupt Polarity Control 1
+#define R_ITSS_PCR_IPC2                   0x3208          ///< Interrupt Polarity Control 2
+#define R_ITSS_PCR_IPC3                   0x320C          ///< Interrupt Polarity Control 3
+#define R_ITSS_PCR_ITSSPRC                0x3300          ///< ITSS Power Reduction Control
+#define B_ITSS_PCR_ITSSPRC_PGCBDCGE       BIT4            ///< PGCB Dynamic Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_HPETDCGE       BIT3            ///< HPET Dynamic Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_8254CGE        BIT2            ///< 8254 Static Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_IOSFICGE       BIT1            ///< IOSF-Sideband Interface Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_ITSSCGE        BIT0            ///< ITSS Clock Gate Enable
+#define R_ITSS_PCR_NMI                    0x3330          ///< NMI Control
+#define N_ITSS_PCR_NMI_NMI2SMI_STS        3               ///< NMI2SMI Status
+#define N_ITSS_PCR_NMI_NMI2SMI_EN         2               ///< NMI2SMI Enable
+#define B_ITSS_PCR_NMI_NMI2SMI_EN         BIT2            ///< NMI2SMI Enable
+#define B_ITSS_PCR_NMI_NMI_NOW_STS        BIT1            ///< NMI_NOW_STS
+#define B_ITSS_PCR_NMI_NMI_NOW            BIT0            ///< NMI_NOW
+#define R_ITSS_PCR_MMC                    0x3334          ///< Master Message Control
+#define B_ITSS_PCR_MMC_MSTRMSG_EN         BIT0            ///< Master Message Enable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
new file mode 100644
index 0000000000..f649873f67
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
@@ -0,0 +1,58 @@
+/** @file
+  Register names for PCH LAN 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_LAN_H_
+#define _PCH_REGS_LAN_H_
+
+//
+// Gigabit LAN Controller configuration registers (D31:F6)
+//
+#define PCI_DEVICE_NUMBER_PCH_LAN     31
+#define PCI_FUNCTION_NUMBER_PCH_LAN   6
+
+#define R_LAN_CFG_MBARA               0x10
+#define N_LAN_CFG_MBARA_ALIGN         17
+#define R_LAN_CFG_PMCS                0xCC
+#define B_LAN_CFG_PMCS_PS             (BIT1 | BIT0)
+#define V_LAN_CFG_PMCS_PS0            0x00
+#define R_LAN_MEM_CSR_RAL                  0x5400
+#define R_LAN_MEM_CSR_RAH                  0x5404
+#define B_LAN_MEM_CSR_RAH_RAH              0x0000FFFF
+#define R_LAN_MEM_CSR_WUC                  0x5800
+#define B_LAN_MEM_CSR_WUC_APME             BIT0
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
new file mode 100644
index 0000000000..34fc3c4dd2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
@@ -0,0 +1,360 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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 (D31:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_LPC       31
+#define PCI_FUNCTION_NUMBER_PCH_LPC     0
+
+#define V_LPC_CFG_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID
+
+
+#define R_LPC_CFG_SERIRQ_CNT                      0x64
+#define B_LPC_CFG_SERIRQ_CNT_SIRQEN               BIT7
+#define B_LPC_CFG_SERIRQ_CNT_SIRQMD               BIT6
+#define B_LPC_CFG_SERIRQ_CNT_SIRQSZ               (BIT5 | BIT4 | BIT3 | BIT2)
+#define N_LPC_CFG_SERIRQ_CNT_SIRQSZ               2
+#define B_LPC_CFG_SERIRQ_CNT_SFPW                 (BIT1 | BIT0)
+#define N_LPC_CFG_SERIRQ_CNT_SFPW                 0
+#define V_LPC_CFG_SERIRQ_CNT_SFPW_4CLK            0x00
+#define V_LPC_CFG_SERIRQ_CNT_SFPW_6CLK            0x01
+#define V_LPC_CFG_SERIRQ_CNT_SFPW_8CLK            0x02
+
+#define R_LPC_CFG_IOD                             0x80
+#define B_LPC_CFG_IOD_FDD                         BIT12
+#define N_LPC_CFG_IOD_FDD                         12
+#define V_LPC_CFG_IOD_FDD_3F0                     0
+#define V_LPC_CFG_IOD_FDD_370                     1
+#define B_LPC_CFG_IOD_LPT                         (BIT9 | BIT8)
+#define N_LPC_CFG_IOD_LPT                         8
+#define V_LPC_CFG_IOD_LPT_378                     0
+#define V_LPC_CFG_IOD_LPT_278                     1
+#define V_LPC_CFG_IOD_LPT_3BC                     2
+#define B_LPC_CFG_IOD_COMB                        (BIT6 | BIT5 |BIT4)
+#define N_LPC_CFG_IOD_COMB                        4
+#define V_LPC_CFG_IOD_COMB_3F8                    0
+#define V_LPC_CFG_IOD_COMB_2F8                    1
+#define V_LPC_CFG_IOD_COMB_220                    2
+#define V_LPC_CFG_IOD_COMB_228                    3
+#define V_LPC_CFG_IOD_COMB_238                    4
+#define V_LPC_CFG_IOD_COMB_2E8                    5
+#define V_LPC_CFG_IOD_COMB_338                    6
+#define V_LPC_CFG_IOD_COMB_3E8                    7
+#define B_LPC_CFG_IOD_COMA                        (BIT2 | BIT1 | BIT0)
+#define N_LPC_CFG_IOD_COMA                        0
+#define V_LPC_CFG_IOD_COMA_3F8                    0
+#define V_LPC_CFG_IOD_COMA_2F8                    1
+#define V_LPC_CFG_IOD_COMA_220                    2
+#define V_LPC_CFG_IOD_COMA_228                    3
+#define V_LPC_CFG_IOD_COMA_238                    4
+#define V_LPC_CFG_IOD_COMA_2E8                    5
+#define V_LPC_CFG_IOD_COMA_338                    6
+#define V_LPC_CFG_IOD_COMA_3E8                    7
+#define R_LPC_CFG_IOE                             0x82
+#define B_LPC_CFG_IOE_ME2                         BIT13           ///< Microcontroller Enable #2, Enables decoding of I/O locations 4Eh and 4Fh to LPC
+#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_ME1                         BIT11           ///< Microcontroller Enable #1, Enables decoding of I/O locations 62h and 66h 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_HGE                         BIT9            ///< High Gameport Enable, Enables decoding of the I/O locations 208h to 20Fh to LPC.
+#define B_LPC_CFG_IOE_LGE                         BIT8            ///< Low Gameport Enable, Enables decoding of the I/O locations 200h to 207h to LPC.
+#define B_LPC_CFG_IOE_FDE                         BIT3            ///< Floppy Drive Enable, Enables decoding of the FDD range to LPC. Range is selected by LIOD.FDE
+#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_GEN1_DEC                        0x84
+#define R_LPC_CFG_GEN2_DEC                        0x88
+#define R_LPC_CFG_GEN3_DEC                        0x8C
+#define R_LPC_CFG_GEN4_DEC                        0x90
+#define B_LPC_CFG_GENX_DEC_IODRA                  0x00FC0000
+#define B_LPC_CFG_GENX_DEC_IOBAR                  0x0000FFFC
+#define B_LPC_CFG_GENX_DEC_EN                     0x00000001
+#define R_LPC_CFG_ULKMC                           0x94
+#define B_LPC_CFG_ULKMC_SMIBYENDPS                BIT15
+#define B_LPC_CFG_ULKMC_TRAPBY64W                 BIT11
+#define B_LPC_CFG_ULKMC_TRAPBY64R                 BIT10
+#define B_LPC_CFG_ULKMC_TRAPBY60W                 BIT9
+#define B_LPC_CFG_ULKMC_TRAPBY60R                 BIT8
+#define B_LPC_CFG_ULKMC_SMIATENDPS                BIT7
+#define B_LPC_CFG_ULKMC_PSTATE                    BIT6
+#define B_LPC_CFG_ULKMC_A20PASSEN                 BIT5
+#define B_LPC_CFG_ULKMC_USBSMIEN                  BIT4
+#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_CS1IORE_DPCS1RE                BIT14
+#define R_ESPI_CFG_CS1GIR1                        0xA4
+#define R_ESPI_CFG_CS1GMR1                        0xA8
+
+#define R_LPC_CFG_FWH_BIOS_SEL                    0xD0
+#define B_LPC_CFG_FWH_BIOS_SEL_F8                 0xF0000000
+#define B_LPC_CFG_FWH_BIOS_SEL_F0                 0x0F000000
+#define B_LPC_CFG_FWH_BIOS_SEL_E8                 0x00F00000
+#define B_LPC_CFG_FWH_BIOS_SEL_E0                 0x000F0000
+#define B_LPC_CFG_FWH_BIOS_SEL_D8                 0x0000F000
+#define B_LPC_CFG_FWH_BIOS_SEL_D0                 0x00000F00
+#define B_LPC_CFG_FWH_BIOS_SEL_C8                 0x000000F0
+#define B_LPC_CFG_FWH_BIOS_SEL_C0                 0x0000000F
+#define R_LPC_CFG_FWH_BIOS_SEL2                   0xD4
+#define B_LPC_CFG_FWH_BIOS_SEL2_70                0xF000
+#define B_LPC_CFG_FWH_BIOS_SEL2_60                0x0F00
+#define B_LPC_CFG_FWH_BIOS_SEL2_50                0x00F0
+#define B_LPC_CFG_FWH_BIOS_SEL2_40                0x000F
+#define R_LPC_CFG_BDE                             0xD8                          ///< BIOS decode enable
+#define B_LPC_CFG_BDE_F8                          BIT15
+#define B_LPC_CFG_BDE_F0                          BIT14
+#define B_LPC_CFG_BDE_E8                          BIT13
+#define B_LPC_CFG_BDE_E0                          BIT12
+#define B_LPC_CFG_BDE_D8                          BIT11
+#define B_LPC_CFG_BDE_D0                          BIT10
+#define B_LPC_CFG_BDE_C8                          BIT9
+#define B_LPC_CFG_BDE_C0                          BIT8
+#define B_LPC_CFG_BDE_LEG_F                       BIT7
+#define B_LPC_CFG_BDE_LEG_E                       BIT6
+#define B_LPC_CFG_BDE_70                          BIT3
+#define B_LPC_CFG_BDE_60                          BIT2
+#define B_LPC_CFG_BDE_50                          BIT1
+#define B_LPC_CFG_BDE_40                          BIT0
+#define R_LPC_CFG_PCC                             0xE0
+#define B_LPC_CFG_PCC_CLKRUN_EN                   BIT0
+
+#define B_LPC_CFG_FVEC0_USB_PORT_CAP              (BIT11 | BIT10)
+#define V_LPC_CFG_FVEC0_USB_14_PORT               0x00000000
+#define V_LPC_CFG_FVEC0_USB_12_PORT               0x00000400
+#define V_LPC_CFG_FVEC0_USB_10_PORT               0x00000800
+#define B_LPC_CFG_FVEC0_SATA_RAID_CAP             BIT7
+#define B_LPC_CFG_FVEC0_SATA_PORT23_CAP           BIT6
+#define B_LPC_CFG_FVEC0_SATA_PORT1_6GB_CAP        BIT3
+#define B_LPC_CFG_FVEC0_SATA_PORT0_6GB_CAP        BIT2
+#define B_LPC_CFG_FVEC0_PCI_CAP                   BIT1
+#define R_LPC_CFG_FVEC1                           0x01
+#define B_LPC_CFG_FVEC1_USB_R_CAP                 BIT22
+#define R_LPC_CFG_FVEC2                           0x02
+#define V_LPC_CFG_FVEC2_PCIE_PORT78_CAP           0x00200000
+#define V_LPC_CFG_FVEC2_PCH_IG_SUPPORT_CAP        0x00020000 ///< PCH Integrated Graphics Support Capability
+#define R_LPC_CFG_FVEC3                           0x03
+#define B_LPC_CFG_FVEC3_DCMI_CAP                  BIT13      ///< Data Center Manageability Interface (DCMI) Capability
+#define B_LPC_CFG_FVEC3_NM_CAP                    BIT12      ///< Node Manager Capability
+
+#define R_LPC_CFG_MDAP                            0xC0
+#define B_LPC_CFG_MDAP_POLICY_EN                  BIT31
+#define B_LPC_CFG_MDAP_PDMA_EN                    BIT30
+#define B_LPC_CFG_MDAP_VALUE                      0x0001FFFF
+
+//
+// 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 B_LPC_CFG_BC_BILD                         BIT7            ///< BIOS Interface Lock-Down
+#define B_LPC_CFG_BC_BBS                          BIT6            ///< Boot BIOS strap
+#define N_LPC_CFG_BC_BBS                          6
+#define V_LPC_CFG_BC_BBS_SPI                      0               ///< Boot BIOS strapped to SPI
+#define V_LPC_CFG_BC_BBS_LPC                      1               ///< Boot BIOS strapped to LPC
+#define B_LPC_CFG_BC_EISS                         BIT5            ///< Enable InSMM.STS
+#define B_LPC_CFG_BC_TS                           BIT4            ///< Top Swap
+#define B_LPC_CFG_BC_LE                           BIT1            ///< Lock Enable
+#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 N_ESPI_CFG_PCBC_BWRE                      11              ///< BIOS Write Report Enable bit position
+#define B_ESPI_CFG_PCBC_BWRS                      BIT10           ///< BIOS Write Report Status
+#define N_ESPI_CFG_PCBC_BWRS                      10              ///< BIOS Write Report Status bit position
+#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 R_ESPI_SLAVE_CHA_0_CAP_AND_CONF           0x10            ///< Channel 0 Capabilities and Configurations
+#define B_ESPI_SLAVE_BME                          BIT2            ///< Bus Master Enable
+
+//
+// Processor interface registers
+//
+#define R_PCH_IO_NMI_SC                              0x61
+#define B_PCH_IO_NMI_SC_SERR_NMI_STS                 BIT7
+#define B_PCH_IO_NMI_SC_IOCHK_NMI_STS                BIT6
+#define B_PCH_IO_NMI_SC_TMR2_OUT_STS                 BIT5
+#define B_PCH_IO_NMI_SC_REF_TOGGLE                   BIT4
+#define B_PCH_IO_NMI_SC_IOCHK_NMI_EN                 BIT3
+#define B_PCH_IO_NMI_SC_PCI_SERR_EN                  BIT2
+#define B_PCH_IO_NMI_SC_SPKR_DAT_EN                  BIT1
+#define B_PCH_IO_NMI_SC_TIM_CNT2_EN                  BIT0
+#define R_PCH_IO_NMI_EN                              0x70
+#define B_PCH_IO_NMI_EN_NMI_EN                       BIT7
+
+//
+// Reset Generator I/O Port
+//
+#define R_PCH_IO_RST_CNT                             0xCF9
+#define B_PCH_IO_RST_CNT_FULL_RST                    BIT3
+#define B_PCH_IO_RST_CNT_RST_CPU                     BIT2
+#define B_PCH_IO_RST_CNT_SYS_RST                     BIT1
+#define V_PCH_IO_RST_CNT_FULLRESET                   0x0E
+#define V_PCH_IO_RST_CNT_HARDRESET                   0x06
+#define V_PCH_IO_RST_CNT_SOFTRESET                   0x04
+#define V_PCH_IO_RST_CNT_HARDSTARTSTATE              0x02
+#define V_PCH_IO_RST_CNT_SOFTSTARTSTATE              0x00
+
+//
+// RTC register
+//
+#define R_RTC_IO_INDEX                           0x70
+#define R_RTC_IO_TARGET                          0x71
+#define R_RTC_IO_EXT_INDEX                       0x72
+#define R_RTC_IO_EXT_TARGET                      0x73
+#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_EXT_TARGET_ALT                  0x77
+#define R_RTC_IO_REGA                            0x0A
+#define B_RTC_IO_REGA_UIP                        BIT7
+#define R_RTC_IO_REGB                            0x0B
+#define B_RTC_IO_REGB_SET                        0x80
+#define B_RTC_IO_REGB_PIE                        0x40
+#define B_RTC_IO_REGB_AIE                        0x20
+#define B_RTC_IO_REGB_UIE                        0x10
+#define B_RTC_IO_REGB_DM                         0x04
+#define B_RTC_IO_REGB_HOURFORM                   0x02
+#define R_RTC_IO_REGC                            0x0C
+#define R_RTC_IO_REGD                            0x0D
+
+//
+// Private Configuration Register
+// RTC PCRs (PID:RTC)
+//
+#define R_RTC_PCR_CONF                        0x3400               ///< RTC Configuration register
+#define B_RTC_PCR_CONF_BILD                   BIT31                ///< BIOS Interface Lock-Down
+#define B_RTC_PCR_CONF_HPM_HW_DIS             BIT6                 ///< RTC High Power Mode HW Disable
+#define B_RTC_PCR_CONF_UCMOS_LOCK             BIT4                 ///< Upper 128 Byte Lock
+#define B_RTC_PCR_CONF_LCMOS_LOCK             BIT3                 ///< Lower 128 Byte Lock
+#define B_RTC_PCR_CONF_UCMOS_EN               BIT2                 ///< Upper CMOS bank enable
+#define R_RTC_PCR_BUC                         0x3414               ///< Backed Up Control
+#define B_RTC_PCR_BUC_DSO                     BIT4                 ///< Daylight Savings Override
+#define B_RTC_PCR_BUC_TS                      BIT0                 ///< Top Swap
+#define R_RTC_PCR_RTCDCG                      0x3418               ///< RTC Dynamic Clock Gating Control
+#define R_RTC_PCR_RTCDCG_RTCPGCBDCGEN         BIT2                 ///< pgcb_clk (12Mhz) Dynamic Clock Gate Enable
+#define R_RTC_PCR_RTCDCG_RTCPCICLKDCGEN       BIT1                 ///< ipciclk_clk (24 MHz) Dynamic Clock Gate Enable
+#define R_RTC_PCR_RTCDCG_RTCROSIDEDCGEN       BIT0                 ///< rosc_side_clk (120 MHz) Dynamic Clock Gate Enable
+#define R_RTC_PCR_PG1_CP_LO                   0x3428
+#define R_RTC_PCR_PG1_AC_LO                   0x3438
+#define R_RTC_PCR_3F00                        0x3F00
+#define R_RTC_PCR_UIPSMI                      0x3F04               ///< RTC Update In Progress SMI Control
+
+//
+// LPC PCR Registers
+//
+#define R_LPC_PCR_HVMTCTL                     0x3410
+#define R_LPC_PCR_GCFD                        0x3418
+#define B_LPC_PCR_GCFD_SRVR_CLKRUN_EN         BIT2                 ///< Enables the CLKRUN# logic to stop the PCI clocks
+#define R_LPC_PCR_PRC                         0x341C
+#define R_LPC_PCR_PCT                         0x3420
+#define R_LPC_PCR_SCT                         0x3424
+#define R_LPC_PCR_LPCCT                       0x3428
+#define R_LPC_PCR_ULTOR                       0x3500
+
+//
+// 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 V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_RD    0                       ///< Slave Configuration register read from address SCRA[11:0]
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_WR    1                       ///< Slave Configuration register write to address SCRA[11:0]
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_STS   2                       ///< Slave Status register read
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_RS    3                       ///< In-Band reset
+#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_PCERR_SLV1                 0x4024          ///< Peripheral Channel Error for Slave 1
+#define R_ESPI_PCR_VWERR_SLV0                 0x4030          ///< Virtual Wire Channel Error for Slave 0
+#define R_ESPI_PCR_VWERR_SLV1                 0x4034          ///< Virtual Wire Channel Error for Slave 1
+#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 R_ESPI_PCR_SOFTSTRAPS_CS1_EN          BIT12           ///< CS1# Enable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
new file mode 100644
index 0000000000..74789a87ce
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
@@ -0,0 +1,61 @@
+/** @file
+  Register names for PCH LPC/eSPI device
+
+  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_H_", "_PCH_LP_"
+    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_LPC_CNL_H_
+#define _PCH_REGS_LPC_CNL_H_
+
+#define V_LPC_CFG_DID_CNL_H                       0xA300
+#define V_LPC_CFG_DID_CNL_LP                      0x9D80
+
+//
+// PCH-LP Device IDs
+//
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU   0x9D80          ///< PCH LP Mobile
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0           0x9D81          ///< PCH LP Mobile (U)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1           0x9D82          ///< PCH LP Mobile Locked
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2           0x9D83          ///< PCH LP Mobile (Y)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3           0x9D84          ///< PCH LP Mobile (U)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4           0x9D85          ///< PCH LP Mobile (U)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5           0x9D86          ///< PCH LP Mobile (Y)
+
+//
+// PCH-H Desktop LPC Device IDs
+//
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU        0xA300          ///< LPC/eSPI Controller
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU        0xA303          ///< PCH H Mobile H310
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU        0xA304          ///< PCH H Mobile H370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU        0xA305          ///< PCH H Mobile Z390
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU        0xA306          ///< PCH H Mobile Q370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU        0xA309          ///< PCH H Mobile C246
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU        0xA30A          ///< PCH H Mobile C242
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU        0xA30B          ///< PCH H Mobile X399
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU        0xA30C          ///< PCH H Mobile QM370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU        0xA30D          ///< PCH H Mobile HM370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU        0xA30E          ///< PCH H Mobile CM246
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
new file mode 100644
index 0000000000..db6a8c4e95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
@@ -0,0 +1,116 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_P2SB_H_
+#define _PCH_REGS_P2SB_H_
+
+//
+// PCI to P2SB Bridge Registers (D31:F1)
+//
+#define PCI_DEVICE_NUMBER_PCH_P2SB                 31
+#define PCI_FUNCTION_NUMBER_PCH_P2SB               1
+
+#define V_P2SB_CFG_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID
+#define R_P2SB_CFG_SBREG_BAR                       0x10
+#define B_P2SB_CFG_SBREG_RBA                       0xFF000000
+#define R_P2SB_CFG_SBREG_BARH                      0x14
+#define B_P2SB_CFG_SBREG_RBAH                      0xFFFFFFFF
+#define R_P2SB_CFG_VBDF                            0x50
+#define B_P2SB_CFG_VBDF_BUS                        0xFF00
+#define B_P2SB_CFG_VBDF_DEV                        0x00F8
+#define B_P2SB_CFG_VBDF_FUNC                       0x0007
+#define R_P2SB_CFG_ESMBDF                          0x52
+#define B_P2SB_CFG_ESMBDF_BUS                      0xFF00
+#define B_P2SB_CFG_ESMBDF_DEV                      0x00F8
+#define B_P2SB_CFG_ESMBDF_FUNC                     0x0007
+#define R_P2SB_CFG_RCFG                            0x54
+#define B_P2SB_CFG_RCFG_RPRID                      0x0000FF00
+#define B_P2SB_CFG_RCFG_RSE                        BIT0
+#define R_P2SB_CFG_HPTC                            0x60
+#define B_P2SB_CFG_HPTC_AE                         BIT7
+#define B_P2SB_CFG_HPTC_AS                         0x0003
+#define N_HPET_ADDR_ASEL                           12
+#define R_P2SB_CFG_IOAC                            0x64
+#define B_P2SB_CFG_IOAC_AE                         BIT8
+#define B_P2SB_CFG_IOAC_ASEL                       0x00FF
+#define N_IO_APIC_ASEL                             12
+#define R_IO_APIC_INDEX_OFFSET                     0x00
+#define R_IO_APIC_DATA_OFFSET                      0x10
+#define R_IO_APIC_EOI_OFFSET                       0x40
+#define R_P2SB_CFG_IBDF                            0x6C
+#define B_P2SB_CFG_IBDF_BUS                        0xFF00
+#define B_P2SB_CFG_IBDF_DEV                        0x00F8
+#define B_P2SB_CFG_IBDF_FUNC                       0x0007
+#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 B_P2SB_CFG_SBIADDR_DESTID                  0xFF000000
+#define B_P2SB_CFG_SBIADDR_RS                      0x000F0000
+#define B_P2SB_CFG_SBIADDR_OFFSET                  0x0000FFFF
+#define R_P2SB_CFG_SBIDATA                         0xD4
+#define B_P2SB_CFG_SBIDATA_DATA                    0xFFFFFFFF
+#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 B_P2SB_CFG_SBIRID_FBE                      0xF000
+#define B_P2SB_CFG_SBIRID_BAR                      0x0700
+#define B_P2SB_CFG_SBIRID_FID                      0x00FF
+#define R_P2SB_CFG_SBIEXTADDR                      0xDC
+#define B_P2SB_CFG_SBIEXTADDR_ADDR                 0xFFFFFFFF
+
+//
+// Others
+//
+#define R_P2SB_CFG_E0                              0xE0
+#define R_P2SB_CFG_E4                              0xE4
+#define R_P2SB_CFG_E8                              0xE8
+#define R_P2SB_CFG_EA                              0xEA
+#define R_P2SB_CFG_F4                              0xF4
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
new file mode 100644
index 0000000000..af19b93e2d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
@@ -0,0 +1,484 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PCIE_H_
+#define _PCH_REGS_PCIE_H_
+
+//
+// Number of PCIe ports per PCIe controller
+//
+#define PCH_PCIE_CONTROLLER_PORTS                 4u
+
+//
+// PCH PCI Express Root Ports (D28:F0..7, D29:F0..7, D27:F0..7)
+//
+#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1       28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2       29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3       27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS     28
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1  0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2  1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3  2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4  3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5  4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6  5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7  6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8  7
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9  0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10 1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11 2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12 3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_13 4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_14 5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_15 6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_16 7
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_17 0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_18 1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_19 2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_20 3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_21 4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_22 5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_23 6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_24 7
+
+#define V_PCH_PCIE_CFG_VENDOR_ID                  V_PCH_INTEL_VENDOR_ID
+
+
+#define R_PCH_PCIE_CFG_CLIST                          0x40
+#define R_PCH_PCIE_CFG_XCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_XCAP_OFFSET)
+#define R_PCH_PCIE_CFG_DCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCAP_OFFSET)
+#define R_PCH_PCIE_CFG_DCTL                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCTL_OFFSET)
+#define R_PCH_PCIE_CFG_DSTS                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_DSTS_OFFSET)
+#define R_PCH_PCIE_CFG_LCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_LCAP_OFFSET)
+#define B_PCH_PCIE_CFG_LCAP_PN                        0xFF000000
+#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_SLCTL                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_SLCTL_OFFSET)
+#define R_PCH_PCIE_CFG_SLSTS                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_SLSTS_OFFSET)
+#define R_PCH_PCIE_CFG_RCTL                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_RCTL_OFFSET)
+#define R_PCH_PCIE_CFG_RSTS                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_RSTS_OFFSET)
+#define R_PCH_PCIE_CFG_DCAP2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCAP2_OFFSET)
+#define R_PCH_PCIE_CFG_DCTL2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCTL2_OFFSET)
+#define R_PCH_PCIE_CFG_LCTL2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_LCTL2_OFFSET)
+#define R_PCH_PCIE_CFG_LSTS2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_LSTS2_OFFSET)
+
+#define R_PCH_PCIE_CFG_MID                            0x80
+#define S_PCH_PCIE_CFG_MID                            2
+#define R_PCH_PCIE_CFG_MC                             0x82
+#define S_PCH_PCIE_CFG_MC                             2
+#define R_PCH_PCIE_CFG_MA                             0x84
+#define S_PCH_PCIE_CFG_MA                             4
+#define R_PCH_PCIE_CFG_MD                             0x88
+#define S_PCH_PCIE_CFG_MD                             2
+
+#define R_PCH_PCIE_CFG_SVCAP                          0x90
+#define S_PCH_PCIE_CFG_SVCAP                          2
+#define R_PCH_PCIE_CFG_SVID                           0x94
+#define S_PCH_PCIE_CFG_SVID                           4
+
+#define R_PCH_PCIE_CFG_PMCAP                          0xA0
+#define R_PCH_PCIE_CFG_PMCS                           (R_PCH_PCIE_CFG_PMCAP + R_PCIE_PMCS_OFFST)
+
+#define R_PCH_PCIE_CFG_CCFG                           0xD0
+#define B_PCH_PCIE_CFG_CCFG_UNRS                      (BIT6 | BIT5 | BIT4)
+#define N_PCH_PCIE_CFG_CCFG_UNRS                      4
+
+#define R_PCH_PCIE_CFG_MPC2                           0xD4
+#define S_PCH_PCIE_CFG_MPC2                           4
+#define B_PCH_PCIE_CFG_MPC2_PTNFAE                    BIT12
+#define B_PCH_PCIE_CFG_MPC2_LSTP                      BIT6
+#define B_PCH_PCIE_CFG_MPC2_IEIME                     BIT5
+#define B_PCH_PCIE_CFG_MPC2_ASPMCOEN                  BIT4
+#define B_PCH_PCIE_CFG_MPC2_ASPMCO                    (BIT3 | BIT2)
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_DISABLED           0
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L0S                (1 << 2)
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L1                 (2 << 2)
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L0S_L1             (3 << 2)
+#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_HPCE                       BIT30
+#define B_PCH_PCIE_CFG_MPC_MMBNCE                     BIT27
+#define B_PCH_PCIE_CFG_MPC_P8XDE                      BIT26
+#define B_PCH_PCIE_CFG_MPC_IRRCE                      BIT25
+#define B_PCH_PCIE_CFG_MPC_SRL                        BIT23
+#define B_PCH_PCIE_CFG_MPC_UCEL                       (BIT20 | BIT19 | BIT18)
+#define N_PCH_PCIE_CFG_MPC_UCEL                       18
+#define B_PCH_PCIE_CFG_MPC_CCEL                       (BIT17 | BIT16 | BIT15)
+#define N_PCH_PCIE_CFG_MPC_CCEL                       15
+#define B_PCH_PCIE_CFG_MPC_PCIESD                     (BIT14 | BIT13)
+#define N_PCH_PCIE_CFG_MPC_PCIESD                     13
+#define V_PCH_PCIE_CFG_MPC_PCIESD_GEN1                1
+#define V_PCH_PCIE_CFG_MPC_PCIESD_GEN2                2
+#define B_PCH_PCIE_CFG_MPC_MCTPSE                     BIT3
+#define B_PCH_PCIE_CFG_MPC_HPME                       BIT1
+#define N_PCH_PCIE_CFG_MPC_HPME                       1
+#define B_PCH_PCIE_CFG_MPC_PMME                       BIT0
+
+#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
+
+#define R_PCH_PCIE_CFG_RPDCGEN                        0xE1
+#define S_PCH_PCIE_CFG_RPDCGEN                        1
+#define B_PCH_PCIE_CFG_RPDCGEN_RPSCGEN                BIT7
+#define B_PCH_PCIE_CFG_RPDCGEN_PTOCGE                 BIT6
+#define B_PCH_PCIE_CFG_RPDCGEN_LCLKREQEN              BIT5
+#define B_PCH_PCIE_CFG_RPDCGEN_BBCLKREQEN             BIT4
+#define B_PCH_PCIE_CFG_RPDCGEN_SRDBCGEN               BIT2
+#define B_PCH_PCIE_CFG_RPDCGEN_RPDLCGEN               BIT1
+#define B_PCH_PCIE_CFG_RPDCGEN_RPDBCGEN               BIT0
+
+
+#define R_PCH_PCIE_CFG_PWRCTL                         0xE8
+#define B_PCH_PCIE_CFG_PWRCTL_LTSSMRTC                BIT20
+#define B_PCH_PCIE_CFG_PWRCTL_WPDMPGEP                BIT17
+#define B_PCH_PCIE_CFG_PWRCTL_DBUPI                   BIT15
+#define B_PCH_PCIE_CFG_PWRCTL_TXSWING                 BIT13
+#define B_PCH_PCIE_CFG_PWRCTL_RPL1SQPOL               BIT1
+#define B_PCH_PCIE_CFG_PWRCTL_RPDTSQPOL               BIT0
+
+#define R_PCH_PCIE_CFG_DC                             0xEC
+#define B_PCH_PCIE_CFG_DC_PCIBEM                      BIT2
+
+#define R_PCH_PCIE_CFG_PHYCTL2                        0xF5
+#define B_PCH_PCIE_CFG_PHYCTL2_TDFT                   (BIT7 | BIT6)
+#define B_PCH_PCIE_CFG_PHYCTL2_TXCFGCHGWAIT           (BIT5 | BIT4)
+#define N_PCH_PCIE_CFG_PHYCTL2_TXCFGCHGWAIT           4
+#define B_PCH_PCIE_CFG_PHYCTL2_PXPG3PLLOFFEN          BIT1
+#define B_PCH_PCIE_CFG_PHYCTL2_PXPG2PLLOFFEN          BIT0
+
+#define R_PCH_PCIE_CFG_IOSFSBCS                       0xF7
+#define B_PCH_PCIE_CFG_IOSFSBCS_SCPTCGE               BIT6
+#define B_PCH_PCIE_CFG_IOSFSBCS_SIID                  (BIT3 | BIT2)
+
+#define R_PCH_PCIE_CFG_STRPFUSECFG                    0xFC
+#define B_PCH_PCIE_CFG_STRPFUSECFG_PXIP               (BIT27 | BIT26 | BIT25 | BIT24)
+#define N_PCH_PCIE_CFG_STRPFUSECFG_PXIP               24
+#define B_PCH_PCIE_CFG_STRPFUSECFG_RPC                (BIT15 | BIT14)
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_1_1_1_1        0
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_2_1_1          1
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_2_2            2
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_4              3
+#define N_PCH_PCIE_CFG_STRPFUSECFG_RPC                14
+#define B_PCH_PCIE_CFG_STRPFUSECFG_MODPHYIOPMDIS      BIT9
+#define B_PCH_PCIE_CFG_STRPFUSECFG_PLLSHTDWNDIS       BIT8
+#define B_PCH_PCIE_CFG_STRPFUSECFG_STPGATEDIS         BIT7
+#define B_PCH_PCIE_CFG_STRPFUSECFG_ASPMDIS            BIT6
+#define B_PCH_PCIE_CFG_STRPFUSECFG_LDCGDIS            BIT5
+#define B_PCH_PCIE_CFG_STRPFUSECFG_LTCGDIS            BIT4
+#define B_PCH_PCIE_CFG_STRPFUSECFG_CDCGDIS            BIT3
+#define B_PCH_PCIE_CFG_STRPFUSECFG_DESKTOPMOB         BIT2
+
+//
+//PCI Express Extended Capability Registers
+//
+
+#define R_PCH_PCIE_CFG_EXCAP_OFFSET                   0x100
+
+#define R_PCH_PCIE_CFG_EX_AECH                        0x100 ///< Advanced Error Reporting Capability Header
+#define V_PCH_PCIE_CFG_EX_AEC_CV                      0x1
+#define R_PCH_PCIE_CFG_EX_UEM                         (R_PCH_PCIE_CFG_EX_AECH + R_PCIE_EX_UEM_OFFSET) // Uncorrectable Error Mask
+
+#define R_PCH_PCIE_CFG_EX_CES                         0x110 ///< Correctable Error Status
+#define B_PCH_PCIE_CFG_EX_CES_BD                      BIT7  ///< Bad DLLP Status
+#define B_PCH_PCIE_CFG_EX_CES_BT                      BIT6  ///< Bad TLP Status
+#define B_PCH_PCIE_CFG_EX_CES_RE                      BIT0  ///< Receiver Error Status
+
+
+//CES.RE, CES.BT, CES.BD
+
+#define R_PCH_PCIE_CFG_EX_ACSECH                      0x140 ///< ACS Extended Capability Header
+#define V_PCH_PCIE_CFG_EX_ACS_CV                      0x1
+#define R_PCH_PCIE_CFG_EX_ACSCAPR                     (R_PCH_PCIE_CFG_EX_ACSECH + R_PCIE_EX_ACSCAPR_OFFSET)
+
+#define R_PCH_PCIE_CFG_EX_L1SECH                      0x200 ///< L1 Sub-States Extended Capability Header
+#define V_PCH_PCIE_CFG_EX_L1S_CV                      0x1
+#define R_PCH_PCIE_CFG_EX_L1SCAP                      (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCAP_OFFSET)
+#define R_PCH_PCIE_CFG_EX_L1SCTL1                     (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCTL1_OFFSET)
+#define R_PCH_PCIE_CFG_EX_L1SCTL2                     (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCTL2_OFFSET)
+
+#define R_PCH_PCIE_CFG_EX_SPEECH                      0x220 ///< Secondary PCI Express Extended Capability Header
+#define V_PCH_PCIE_CFG_EX_SPEECH_CV                   0x1
+#define R_PCH_PCIE_CFG_EX_LCTL3                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LCTL3_OFFSET)
+#define R_PCH_PCIE_CFG_EX_LES                         (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LES_OFFSET)
+#define R_PCH_PCIE_CFG_EX_LECTL                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L01EC_OFFSET)
+#define B_PCH_PCIE_CFG_EX_LECTL_UPTPH                 (BIT14 | BIT13 | BIT12)
+#define N_PCH_PCIE_CFG_EX_LECTL_UPTPH                 12
+#define B_PCH_PCIE_CFG_EX_LECTL_UPTP                  0x0F00
+#define N_PCH_PCIE_CFG_EX_LECTL_UPTP                  8
+#define B_PCH_PCIE_CFG_EX_LECTL_DPTPH                 (BIT6 | BIT5 | BIT4)
+#define N_PCH_PCIE_CFG_EX_LECTL_DPTPH                 4
+#define B_PCH_PCIE_CFG_EX_LECTL_DPTP                  0x000F
+#define N_PCH_PCIE_CFG_EX_LECTL_DPTP                  0
+
+#define R_PCH_PCIE_CFG_EX_L01EC                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L01EC_OFFSET)
+#define R_PCH_PCIE_CFG_EX_L23EC                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L23EC_OFFSET)
+
+#define R_PCH_PCIE_CFG_PCIERTP1                       0x300
+#define R_PCH_PCIE_CFG_PCIERTP2                       0x304
+#define R_PCH_PCIE_CFG_PCIENFTS                       0x314
+#define R_PCH_PCIE_CFG_PCIEL0SC                       0x318
+
+#define R_PCH_PCIE_CFG_PCIECFG2                       0x320
+#define B_PCH_PCIE_CFG_PCIECFG2_LBWSSTE               BIT30
+#define B_PCH_PCIE_CFG_PCIECFG2_RLLG3R                BIT27
+#define B_PCH_PCIE_CFG_PCIECFG2_CROAOV                BIT24
+#define B_PCH_PCIE_CFG_PCIECFG2_CROAOE                BIT23
+#define B_PCH_PCIE_CFG_PCIECFG2_CRSREN                BIT22
+#define B_PCH_PCIE_CFG_PCIECFG2_PMET                  (BIT21 | BIT20)
+#define V_PCH_PCIE_CFG_PCIECFG2_PMET                  1
+#define N_PCH_PCIE_CFG_PCIECFG2_PMET                  20
+
+#define R_PCH_PCIE_CFG_PCIEDBG                        0x324
+#define B_PCH_PCIE_CFG_PCIEDBG_LBWSSTE                BIT30
+#define B_PCH_PCIE_CFG_PCIEDBG_USSP                   (BIT27 | BIT26)
+#define B_PCH_PCIE_CFG_PCIEDBG_LGCLKSQEXITDBTIMERS    (BIT25 | BIT24)
+#define B_PCH_PCIE_CFG_PCIEDBG_CTONFAE                BIT14
+#define B_PCH_PCIE_CFG_PCIEDBG_SQOL0                  BIT7
+#define B_PCH_PCIE_CFG_PCIEDBG_SPCE                   BIT5
+#define B_PCH_PCIE_CFG_PCIEDBG_LR                     BIT4
+
+#define R_PCH_PCIE_CFG_PCIESTS1                              0x328
+#define B_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE                    0xFF000000
+#define N_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE                    24
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DETRDY             0x01
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DETRDYECINP1CG     0x0E
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_L0                 0x33
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DISWAIT            0x5E
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DISWAITPG          0x60
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_RECOVERYSPEEDREADY 0x6C
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_RECOVERYLNK2DETECT 0x6F
+
+
+#define B_PCH_PCIE_CFG_PCIESTS1_LNKSTAT               (BIT22 | BIT21 | BIT20 | BIT19)
+#define N_PCH_PCIE_CFG_PCIESTS1_LNKSTAT               19
+#define V_PCH_PCIE_CFG_PCIESTS1_LNKSTAT_L0            0x7
+
+#define R_PCH_PCIE_CFG_PCIESTS2                       0x32C
+#define B_PCH_PCIE_CFG_PCIESTS2_P4PNCCWSSCMES         BIT31
+#define B_PCH_PCIE_CFG_PCIESTS2_P3PNCCWSSCMES         BIT30
+#define B_PCH_PCIE_CFG_PCIESTS2_P2PNCCWSSCMES         BIT29
+#define B_PCH_PCIE_CFG_PCIESTS2_P1PNCCWSSCMES         BIT28
+#define B_PCH_PCIE_CFG_PCIESTS2_CLRE                  0x0000F000
+#define N_PCH_PCIE_CFG_PCIESTS2_CLRE                  12
+
+#define R_PCH_PCIE_CFG_PCIEALC                        0x338
+#define B_PCH_PCIE_CFG_PCIEALC_ITLRCLD                BIT29
+#define B_PCH_PCIE_CFG_PCIEALC_ILLRCLD                BIT28
+#define B_PCH_PCIE_CFG_PCIEALC_BLKDQDA                BIT26
+
+
+#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_PHYCTL4                        0x408
+#define B_PCH_PCIE_CFG_PHYCTL4_SQDIS                  BIT27
+
+#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_PCIEPMECTL2                    0x424
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_PHYCLPGE           BIT11
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_FDCPGE             BIT8
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_DETSCPGE           BIT7
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_L23RDYSCPGE        BIT6
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_DISSCPGE           BIT5
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_L1SCPGE            BIT4
+
+#define R_PCH_PCIE_CFG_PCE                            0x428
+#define B_PCH_PCIE_CFG_PCE_HAE                        BIT5
+#define B_PCH_PCIE_CFG_PCE_PMCRE                      BIT0
+
+#define R_PCH_PCIE_CFG_EQCFG1                         0x450
+#define S_PCH_PCIE_CFG_EQCFG1                         4
+#define B_PCH_PCIE_CFG_EQCFG1_REC                     0xFF000000
+#define N_PCH_PCIE_CFG_EQCFG1_REC                     24
+#define B_PCH_PCIE_CFG_EQCFG1_REIFECE                 BIT23
+#define N_PCH_PCIE_CFG_EQCFG1_LERSMIE                 21
+#define B_PCH_PCIE_CFG_EQCFG1_LEP23B                  BIT18
+#define B_PCH_PCIE_CFG_EQCFG1_LEP3B                   BIT17
+#define B_PCH_PCIE_CFG_EQCFG1_RTLEPCEB                BIT16
+#define B_PCH_PCIE_CFG_EQCFG1_RTPCOE                  BIT15
+#define B_PCH_PCIE_CFG_EQCFG1_HPCMQE                  BIT13
+#define B_PCH_PCIE_CFG_EQCFG1_HAED                    BIT12
+#define B_PCH_PCIE_CFG_EQCFG1_EQTS2IRRC               BIT7
+#define B_PCH_PCIE_CFG_EQCFG1_TUPP                    BIT1
+
+#define R_PCH_PCIE_CFG_RTPCL1                         0x454
+#define B_PCH_PCIE_CFG_RTPCL1_PCM                     BIT31
+#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL2PL4             0x3F000000
+#define B_PCH_PCIE_CFG_RTPCL1_RTPOSTCL1PL3            0xFC0000
+#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL1PL2             0x3F000
+#define B_PCH_PCIE_CFG_RTPCL1_RTPOSTCL0PL1            0xFC0
+#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL0PL0             0x3F
+
+#define R_PCH_PCIE_CFG_RTPCL2                         0x458
+#define B_PCH_PCIE_CFG_RTPCL2_RTPOSTCL3PL             0x3F000
+#define B_PCH_PCIE_CFG_RTPCL2_RTPRECL3PL6             0xFC0
+#define B_PCH_PCIE_CFG_RTPCL2_RTPOSTCL2PL5            0x3F
+
+#define R_PCH_PCIE_CFG_RTPCL3                         0x45C
+#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL7                0x3F000000
+#define B_PCH_PCIE_CFG_RTPCL3_RTPOSTCL6               0xFC0000
+#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL6                0x3F000
+#define B_PCH_PCIE_CFG_RTPCL3_RTPOSTCL5               0xFC0
+#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL5PL10            0x3F
+
+#define R_PCH_PCIE_CFG_RTPCL4                         0x460
+#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL9               0x3F000000
+#define B_PCH_PCIE_CFG_RTPCL4_RTPRECL9                0xFC0000
+#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL8               0x3F000
+#define B_PCH_PCIE_CFG_RTPCL4_RTPRECL8                0xFC0
+#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL7               0x3F
+
+#define R_PCH_PCIE_CFG_FOMS                           0x464
+#define B_PCH_PCIE_CFG_FOMS_I                         (BIT30 | BIT29)
+#define N_PCH_PCIE_CFG_FOMS_I                         29
+#define B_PCH_PCIE_CFG_FOMS_LN                        0x1F000000
+#define N_PCH_PCIE_CFG_FOMS_LN                        24
+#define B_PCH_PCIE_CFG_FOMS_FOMSV                     0x00FFFFFF
+#define B_PCH_PCIE_CFG_FOMS_FOMSV0                    0x000000FF
+#define N_PCH_PCIE_CFG_FOMS_FOMSV0                    0
+#define B_PCH_PCIE_CFG_FOMS_FOMSV1                    0x0000FF00
+#define N_PCH_PCIE_CFG_FOMS_FOMSV1                    8
+#define B_PCH_PCIE_CFG_FOMS_FOMSV2                    0x00FF0000
+#define N_PCH_PCIE_CFG_FOMS_FOMSV2                    16
+
+#define R_PCH_PCIE_CFG_HAEQ                           0x468
+#define B_PCH_PCIE_CFG_HAEQ_HAPCCPI                   (BIT31 | BIT30 | BIT29 | BIT28)
+#define N_PCH_PCIE_CFG_HAEQ_HAPCCPI                   28
+#define B_PCH_PCIE_CFG_HAEQ_MACFOMC                   BIT19
+
+#define R_PCH_PCIE_CFG_LTCO1                          0x470
+#define B_PCH_PCIE_CFG_LTCO1_L1TCOE                   BIT25
+#define B_PCH_PCIE_CFG_LTCO1_L0TCOE                   BIT24
+#define B_PCH_PCIE_CFG_LTCO1_L1TPOSTCO                0xFC0000
+#define N_PCH_PCIE_CFG_LTCO1_L1TPOSTCO                18
+#define B_PCH_PCIE_CFG_LTCO1_L1TPRECO                 0x3F000
+#define N_PCH_PCIE_CFG_LTCO1_L1TPRECO                 12
+#define B_PCH_PCIE_CFG_LTCO1_L0TPOSTCO                0xFC0
+#define N_PCH_PCIE_CFG_LTCO1_L0TPOSTCO                6
+#define B_PCH_PCIE_CFG_LTCO1_L0TPRECO                 0x3F
+#define N_PCH_PCIE_CFG_LTCO1_L0TPRECO                 0
+
+#define R_PCH_PCIE_CFG_LTCO2                          0x474
+#define B_PCH_PCIE_CFG_LTCO2_L3TCOE                   BIT25
+#define B_PCH_PCIE_CFG_LTCO2_L2TCOE                   BIT24
+#define B_PCH_PCIE_CFG_LTCO2_L3TPOSTCO                0xFC0000
+#define B_PCH_PCIE_CFG_LTCO2_L3TPRECO                 0x3F000
+#define B_PCH_PCIE_CFG_LTCO2_L2TPOSTCO                0xFC0
+#define B_PCH_PCIE_CFG_LTCO2_L2TPRECO                 0x3F
+
+#define R_PCH_PCIE_CFG_G3L0SCTL                       0x478
+#define B_PCH_PCIE_CFG_G3L0SCTL_G3UCNFTS              0x0000FF00
+#define B_PCH_PCIE_CFG_G3L0SCTL_G3CCNFTS              0x000000FF
+
+#define R_PCH_PCIE_CFG_EQCFG2                         0x47C
+#define B_PCH_PCIE_CFG_EQCFG2_NTIC                    0xFF000000
+#define B_PCH_PCIE_CFG_EQCFG2_EMD                     BIT23
+#define B_PCH_PCIE_CFG_EQCFG2_NTSS                    (BIT22 | BIT21 | BIT20)
+#define B_PCH_PCIE_CFG_EQCFG2_PCET                    (BIT19 | BIT18 | BIT17 | BIT16)
+#define N_PCH_PCIE_CFG_EQCFG2_PCET                    16
+#define B_PCH_PCIE_CFG_EQCFG2_HAPCSB                  (BIT15 | BIT14 | BIT13 | BIT12)
+#define N_PCH_PCIE_CFG_EQCFG2_HAPCSB                  12
+#define B_PCH_PCIE_CFG_EQCFG2_NTEME                   BIT11
+#define B_PCH_PCIE_CFG_EQCFG2_MPEME                   BIT10
+#define B_PCH_PCIE_CFG_EQCFG2_REWMETM                 (BIT9 | BIT8)
+#define B_PCH_PCIE_CFG_EQCFG2_REWMET                  0xFF
+
+#define R_PCH_PCIE_CFG_MM                             0x480
+#define B_PCH_PCIE_CFG_MM_MSST                        0xFFFFFF00
+#define N_PCH_PCIE_CFG_MM_MSST                        8
+#define B_PCH_PCIE_CFG_MM_MSS                         0xFF
+
+//
+// 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 B_SPX_PCR_PCD_RP1CH                   BIT3                    ///< Port 1 config hide
+#define B_SPX_PCR_PCD_RP2FN                   (BIT6 | BIT5 | BIT4)    ///< Port 2 Function Number
+#define B_SPX_PCR_PCD_RP2CH                   BIT7                    ///< Port 2 config hide
+#define B_SPX_PCR_PCD_RP3FN                   (BIT10 | BIT9 | BIT8)   ///< Port 3 Function Number
+#define B_SPX_PCR_PCD_RP3CH                   BIT11                   ///< Port 3 config hide
+#define B_SPX_PCR_PCD_RP4FN                   (BIT14 | BIT13 | BIT12) ///< Port 4 Function Number
+#define B_SPX_PCR_PCD_RP4CH                   BIT15                   ///< Port 4 config hide
+#define S_SPX_PCR_PCD_RP_FIELD                4                       ///< 4 bits for each RP FN
+#define B_SPX_PCR_PCD_P1D                     BIT16                   ///< Port 1 disable
+#define B_SPX_PCR_PCD_P2D                     BIT17                   ///< Port 2 disable
+#define B_SPX_PCR_PCD_P3D                     BIT18                   ///< Port 3 disable
+#define B_SPX_PCR_PCD_P4D                     BIT19                   ///< Port 4 disable
+#define B_SPX_PCR_PCD_SRL                     BIT31                   ///< Secured Register Lock
+
+#define R_SPX_PCR_PCIEHBP                     0x0004                  ///< PCI Express high-speed bypass
+#define B_SPX_PCR_PCIEHBP_PCIEHBPME           BIT0                    ///< PCIe HBP mode enable
+#define B_SPX_PCR_PCIEHBP_PCIEGMO             (BIT2 | BIT1)           ///< PCIe gen mode override
+#define B_SPX_PCR_PCIEHBP_PCIETIL0O           BIT3                    ///< PCIe transmitter-in-L0 override
+#define B_SPX_PCR_PCIEHBP_PCIERIL0O           BIT4                    ///< PCIe receiver-in-L0 override
+#define B_SPX_PCR_PCIEHBP_PCIELRO             BIT5                    ///< PCIe link recovery override
+#define B_SPX_PCR_PCIEHBP_PCIELDO             BIT6                    ///< PCIe link down override
+#define B_SPX_PCR_PCIEHBP_PCIESSM             BIT7                    ///< PCIe SKP suppression mode
+#define B_SPX_PCR_PCIEHBP_PCIESST             BIT8                    ///< PCIe suppress SKP transmission
+#define B_SPX_PCR_PCIEHBP_PCIEHBPPS           (BIT13 | BIT12)         ///< PCIe HBP port select
+#define B_SPX_PCR_PCIEHBP_CRCSEL              (BIT15 | BIT14)         ///< CRC select
+#define B_SPX_PCR_PCIEHBP_PCIEHBPCRC          0xFFFF0000              ///< PCIe HBP CRC
+
+//
+// ICC PCR (PID: ICC)
+//
+#define R_ICC_PCR_TMCSRCCLK                   0x1000                  ///< Timing Control SRC Clock Register
+#define R_ICC_PCR_TMCSRCCLK2                  0x1004                  ///< Timing Control SRC Clock Register 2
+#define R_ICC_PCR_MSKCKRQ                     0x100C                  ///< Mask Control CLKREQ
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
new file mode 100644
index 0000000000..ed1668300a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
@@ -0,0 +1,73 @@
+/** @file
+  Register names for PCH private chipset 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
+  - 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_H_", "_PCH_LP_"
+    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 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_OPIPHY     0xAC
+#define PID_MODPHY0    0xAB
+#define PID_MODPHY1    0xAA
+#define PID_USB2       0xCA
+#define PID_DMI        0x88
+#define PID_PSTH       0x89
+#define PID_DSP        0xD7
+#define PID_ESPISPI    0x72
+#define PID_FIA        0xCF
+#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_SERIALIO   0xCB
+#define PID_LPC        0xC7
+#define PID_SMB        0xC6
+#define PID_ITSS       0xC4
+#define PID_RTC_HOST   0xC3
+#define PID_PSF6       0x7F
+#define PID_PSF7       0x7E
+#define PID_PSF8       0x7D
+#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_CSME12     0x9C
+
+#define PID_CSME0      0x90
+#define PID_CSME_PSF   0x8F
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
new file mode 100644
index 0000000000..dcecc633a1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
@@ -0,0 +1,670 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PMC_H_
+#define _PCH_REGS_PMC_H_
+
+//
+// PMC Registers (D31:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_PMC                31
+#define PCI_FUNCTION_NUMBER_PCH_PMC              2
+
+#define R_PMC_CFG_BASE                           0x10
+#define B_PMC_CFG_PWRM_BASE_MASK                 0xFFFF0000                    ///< PWRM must be 64KB alignment to align the source decode.
+
+//
+// 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_BM                     BIT4
+#define B_ACPI_IO_PM1_STS_TMROF                  BIT0
+#define N_ACPI_IO_PM1_STS_WAK                    15
+#define N_ACPI_IO_PM1_STS_PCIEXP_WAKE_STS        14
+#define N_ACPI_IO_PM1_STS_PRBTNOR                11
+#define N_ACPI_IO_PM1_STS_RTC                    10
+#define N_ACPI_IO_PM1_STS_PWRBTN                 8
+#define N_ACPI_IO_PM1_STS_GBL                    5
+#define N_ACPI_IO_PM1_STS_BM                     4
+#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_RTC                     BIT10
+#define B_ACPI_IO_PM1_EN_PWRBTN                  BIT8
+#define B_ACPI_IO_PM1_EN_GBL                     BIT5
+#define B_ACPI_IO_PM1_EN_TMROF                   BIT0
+#define N_ACPI_IO_PM1_EN_RTC                     10
+#define N_ACPI_IO_PM1_EN_PWRBTN                  8
+#define N_ACPI_IO_PM1_EN_GBL                     5
+#define N_ACPI_IO_PM1_EN_TMROF                   0
+
+#define R_ACPI_IO_PM1_CNT                        0x04
+#define S_ACPI_IO_PM1_CNT                        4
+#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_GBL_RLS                BIT2
+#define B_ACPI_IO_PM1_CNT_BM_RLD                 BIT1
+#define B_ACPI_IO_PM1_CNT_SCI_EN                 BIT0
+
+#define R_ACPI_IO_PM1_TMR                        0x08
+#define V_ACPI_IO_PM1_TMR_FREQUENCY              3579545
+#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_USB3                  BIT31
+#define B_ACPI_IO_SMI_EN_GPIO_UNLOCK_SMI              BIT27
+#define B_ACPI_IO_SMI_EN_LEGACY_USB2                  BIT17
+#define B_ACPI_IO_SMI_EN_PERIODIC                     BIT14
+#define B_ACPI_IO_SMI_EN_TCO                          BIT13
+#define B_ACPI_IO_SMI_EN_MCSMI                        BIT11
+#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_ON_SLP_EN                    BIT4
+#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_GPIO_UNLOCK                  27
+#define N_ACPI_IO_SMI_EN_INTEL_USB2                   18
+#define N_ACPI_IO_SMI_EN_LEGACY_USB2                  17
+#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_BIOS_RLS                     7
+#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 N_ACPI_IO_SMI_EN_BIOS                         2
+#define N_ACPI_IO_SMI_EN_EOS                          1
+#define N_ACPI_IO_SMI_EN_GBL_SMI                      0
+
+#define R_ACPI_IO_SMI_STS                             0x34
+#define S_ACPI_IO_SMI_STS                             4
+#define B_ACPI_IO_SMI_STS_LEGACY_USB3                 BIT31
+#define B_ACPI_IO_SMI_STS_GPIO_UNLOCK                 BIT27
+#define B_ACPI_IO_SMI_STS_SPI                         BIT26
+#define B_ACPI_IO_SMI_STS_MONITOR                     BIT21
+#define B_ACPI_IO_SMI_STS_PCI_EXP                     BIT20
+#define B_ACPI_IO_SMI_STS_PATCH                       BIT19
+#define B_ACPI_IO_SMI_STS_INTEL_USB2                  BIT18
+#define B_ACPI_IO_SMI_STS_LEGACY_USB2                 BIT17
+#define B_ACPI_IO_SMI_STS_SMBUS                       BIT16
+#define B_ACPI_IO_SMI_STS_SERIRQ                      BIT15
+#define B_ACPI_IO_SMI_STS_PERIODIC                    BIT14
+#define B_ACPI_IO_SMI_STS_TCO                         BIT13
+#define B_ACPI_IO_SMI_STS_DEVMON                      BIT12
+#define B_ACPI_IO_SMI_STS_MCSMI                       BIT11
+#define B_ACPI_IO_SMI_STS_GPIO_SMI                    BIT10
+#define B_ACPI_IO_SMI_STS_GPE0                        BIT9
+#define B_ACPI_IO_SMI_STS_PM1_STS_REG                 BIT8
+#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_LEGACY_USB                  BIT3
+#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_GPIO_UNLOCK                 27
+#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_PATCH                       19
+#define N_ACPI_IO_SMI_STS_INTEL_USB2                  18
+#define N_ACPI_IO_SMI_STS_LEGACY_USB2                 17
+#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_DEVMON                      12
+#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 N_ACPI_IO_SMI_STS_BIOS                        2
+
+#define R_ACPI_IO_GPE_CNTL                            0x40
+#define B_ACPI_IO_GPE_CNTL_SWGPE_CTRL                 BIT17
+
+#define R_ACPI_IO_DEVACT_STS                          0x44
+#define S_ACPI_IO_DEVACT_STS                          2
+#define B_ACPI_IO_DEVACT_STS_MASK                     0x13E1
+#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 B_ACPI_IO_DEVACT_STS_D0_TRP                   BIT0
+#define N_ACPI_IO_DEVACT_STS_KBC                      12
+#define N_ACPI_IO_DEVACT_STS_PIRQDH                   9
+#define N_ACPI_IO_DEVACT_STS_PIRQCG                   8
+#define N_ACPI_IO_DEVACT_STS_PIRQBF                   7
+#define N_ACPI_IO_DEVACT_STS_PIRQAE                   6
+
+#define R_ACPI_IO_PM2_CNT                             0x50
+#define B_ACPI_IO_PM2_CNT_ARB_DIS                     BIT0
+
+#define R_ACPI_IO_OC_WDT_CTL                          0x54
+#define B_ACPI_IO_OC_WDT_CTL_RLD                      BIT31
+#define B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS              BIT25
+#define B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS           BIT24
+#define B_ACPI_IO_OC_WDT_CTL_FORCE_ALL                BIT15
+#define B_ACPI_IO_OC_WDT_CTL_EN                       BIT14
+#define B_ACPI_IO_OC_WDT_CTL_ICCSURV                  BIT13
+#define B_ACPI_IO_OC_WDT_CTL_LCK                      BIT12
+#define B_ACPI_IO_OC_WDT_CTL_TOV_MASK                 0x3FF
+#define B_ACPI_IO_OC_WDT_CTL_FAILURE_STS              BIT23
+#define B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS           BIT22
+#define B_ACPI_IO_OC_WDT_CTL_AFTER_POST               0x3F0000
+#define V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE           1
+#define V_ACPI_IO_OC_WDT_CTL_STATUS_OK                0
+
+#define R_ACPI_IO_GPE0_STS_31_0                    0x60
+#define R_ACPI_IO_GPE0_STS_63_32                   0x64
+#define R_ACPI_IO_GPE0_STS_95_64                   0x68
+#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_GPIO_TIER_2      BIT15
+#define B_ACPI_IO_GPE0_STS_127_96_PME_B0           BIT13
+#define B_ACPI_IO_GPE0_STS_127_96_ME_SCI           BIT12
+#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_PCI_EXP          BIT9
+#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_TC0SCI           BIT6
+#define B_ACPI_IO_GPE0_STS_127_96_SWGPE            BIT2
+#define B_ACPI_IO_GPE0_STS_127_96_HOT_PLUG         BIT1
+#define N_ACPI_IO_GPE0_STS_127_96_PME_B0           13
+#define N_ACPI_IO_GPE0_STS_127_96_PME              11
+#define N_ACPI_IO_GPE0_STS_127_96_BATLOW           10
+#define N_ACPI_IO_GPE0_STS_127_96_PCI_EXP          9
+#define N_ACPI_IO_GPE0_STS_127_96_RI               8
+#define N_ACPI_IO_GPE0_STS_127_96_SMB_WAK          7
+#define N_ACPI_IO_GPE0_STS_127_96_TC0SCI           6
+#define N_ACPI_IO_GPE0_STS_127_96_SWGPE            2
+#define N_ACPI_IO_GPE0_STS_127_96_HOT_PLUG         1
+
+#define R_ACPI_IO_GPE0_EN_31_0                     0x70
+#define R_ACPI_IO_GPE0_EN_63_32                    0x74
+#define R_ACPI_IO_GPE0_EN_95_64                    0x78
+#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_USB_CON_DSX_EN    BIT17
+#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_PCI_EXP           BIT9
+#define B_ACPI_IO_GPE0_EN_127_96_RI                BIT8
+#define B_ACPI_IO_GPE0_EN_127_96_TC0SCI            BIT6
+#define B_ACPI_IO_GPE0_EN_127_96_SWGPE             BIT2
+#define B_ACPI_IO_GPE0_EN_127_96_HOT_PLUG          BIT1
+#define N_ACPI_IO_GPE0_EN_127_96_PME_B0            13
+#define N_ACPI_IO_GPE0_EN_127_96_USB3              12
+#define N_ACPI_IO_GPE0_EN_127_96_PME               11
+#define N_ACPI_IO_GPE0_EN_127_96_BATLOW            10
+#define N_ACPI_IO_GPE0_EN_127_96_PCI_EXP           9
+#define N_ACPI_IO_GPE0_EN_127_96_RI                8
+#define N_ACPI_IO_GPE0_EN_127_96_TC0SCI            6
+#define N_ACPI_IO_GPE0_EN_127_96_SWGPE             2
+#define N_ACPI_IO_GPE0_EN_127_96_HOT_PLUG          1
+
+
+//
+// TCO register I/O map
+//
+#define R_TCO_IO_RLD                                 0x0
+#define R_TCO_IO_DAT_IN                              0x2
+#define R_TCO_IO_DAT_OUT                             0x3
+#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 R_TCO_IO_TCO2_STS                            0x06
+#define S_TCO_IO_TCO2_STS                            2
+#define B_TCO_IO_TCO2_STS_SMLINK_SLV_SMI             BIT4
+#define B_TCO_IO_TCO2_STS_BAD_BIOS                   BIT3
+#define B_TCO_IO_TCO2_STS_BOOT                       BIT2
+#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 B_TCO_IO_TCO1_CNT_TMR_HLT                    BIT11
+#define B_TCO_IO_TCO1_CNT_NR_MSUS                    BIT0  //NO_REBOOT
+
+#define R_TCO_IO_TCO2_CNT                            0x0A
+#define S_TCO_IO_TCO2_CNT                            2
+#define B_TCO_IO_TCO2_CNT_OS_POLICY                  0x0030
+#define B_TCO_IO_TCO2_CNT_GPI11_ALERT_DISABLE        0x0008
+#define B_TCO_IO_TCO2_CNT_INTRD_SEL                  0x0006
+#define N_TCO_IO_TCO2_CNT_INTRD_SEL                  2
+
+#define R_TCO_IO_MESSAGE1                            0x0C
+#define R_TCO_IO_MESSAGE2                            0x0D
+#define R_TCO_IO_TWDS                                0x0E           ///< TCO_WDSTATUS register.
+#define R_TCO_IO_LE                                  0x10           ///< LEGACY_ELIM register
+#define B_TCO_IO_LE_IRQ12_CAUSE                      BIT1
+#define B_TCO_IO_LE_IRQ1_CAUSE                       BIT0
+#define R_TCO_IO_TMR                                 0x12
+
+//
+// PWRM Registers for IPC interface
+//
+#define R_PMC_PWRM_IPC_CMD                                  0x00                        ///< IPC command
+#define N_PMC_PWRM_IPC_CMD_CMD_ID                           12                          ///< IPC command.cmd.ID
+#define N_PMC_PWRM_IPC_CMD_SIZE                             16                          ///< IPC command.size
+#define B_PMC_PWRM_IPC_CMD_SIZE_MASK                        0x00FF0000                  ///< IPC command.size mask Bits[23:16]
+#define N_PMC_PWRM_IPC_CMD_COMMAND                          0                           ///< IPC command.cmd.Command
+#define B_PMC_PWRM_IPC_CMD_COMMAND_MASK                     0x000000FF                  ///< IPC command.size mask Bits[07:00]
+#define V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL                 0xA1                        ///< IPC commmand to control S0ix policies RCOMP
+#define V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE                0xA4                        ///< IPC commmand to control NPK Power State
+#define V_PMC_PWRM_IPC_CMD_COMMAND_PROXY                    0xAA                        ///< Proxy access to SOC registers
+#define V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ                   0                        ///< Read command
+#define V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE                  1                        ///< Write command
+#define V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI                     2                        ///< parameter to access NMI control register
+#define R_PMC_PWRM_IPC_STS                                  0x04                        ///< IPC Status
+#define B_PMC_PWRM_IPC_STS_BUSY                             BIT0                        ///< IPC Status Busy Bit
+#define B_PMC_PWRM_IPC_STS_ERROR                            BIT1                        ///< IPC Status Error Bit
+#define N_PMC_PWRM_IPC_STS_ERR_CODE                         BIT16                       ///< IPC Status Error status
+#define B_PMC_PWRM_IPC_STS_ERR_CODE_MASK                    0x00FF0000                  ///< IPC Status Error status mask[23:16]
+#define R_PMC_PWRM_IPC_SPTR                                 0x08                        ///< IPC Source Pointer
+#define R_PMC_PWRM_IPC_DPTR                                 0x0C                        ///< IPC Destination Pointer
+#define R_PMC_PWRM_IPC_WBUF0                                0x80                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_WBUF1                                0x84                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_WBUF2                                0x88                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_WBUF3                                0x8C                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_RBUF0                                0x90                        ///< IPC Read Buffer
+#define R_PMC_PWRM_IPC_RBUF1                                0x94                        ///< IPC Read Buffer
+#define R_PMC_PWRM_IPC_RBUF2                                0x98                        ///< IPC Read Buffer
+#define R_PMC_PWRM_IPC_RBUF3                                0x9C                        ///< IPC Read Buffer
+//
+// PWRM Registers
+//
+#define R_PMC_PWRM_GEN_PMCON_A                              0x1020
+#define B_PMC_PWRM_GEN_PMCON_A_DC_PP_DIS                    BIT30
+#define B_PMC_PWRM_GEN_PMCON_A_DSX_PP_DIS                   BIT29
+#define B_PMC_PWRM_GEN_PMCON_A_AG3_PP_EN                    BIT28
+#define B_PMC_PWRM_GEN_PMCON_A_SX_PP_EN                     BIT27
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_ICLK_PLL               BIT26
+#define B_PMC_PWRM_GEN_PMCON_A_MPHY_CRICLK_GATE_OVR         BIT25
+#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_OPI_PLL_SD_INC0        BIT22
+#define B_PMC_PWRM_GEN_PMCON_A_MEM_SR                       BIT21
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_SPXB_CG_INC0           BIT20
+#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_ALLOW_L1LOW_OPI_ON           BIT17
+#define B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR                  BIT16
+#define B_PMC_PWRM_GEN_PMCON_A_PME_B0_S5_DIS                BIT15
+#define B_PMC_PWRM_GEN_PMCON_A_PWR_FLR                      BIT14
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_L1LOW_BCLKREQ_ON       BIT13
+#define B_PMC_PWRM_GEN_PMCON_A_DISABLE_SX_STRETCH           BIT12
+#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_SLP_S4_ASE                   BIT3
+#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_WOL_EN_OVRD                  BIT13
+#define B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN              BIT10
+#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 B_PMC_PWRM_CRID_RID_SEL                             (BIT0 | BIT1)    ///< RID Select
+#define V_PMC_PWRM_CRID_RID_SEL_REVISIONID                  0
+#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          ///< this is PWRM register
+#define B_PMC_PWRM_ETR3_CF9LOCK                             BIT31           ///< CF9h Lockdown
+#define B_PMC_PWRM_ETR3_LATCH_EVENTS_C10_EXIT               BIT30
+#define B_PMC_PWRM_ETR3_USB_CACHE_DIS                       BIT21
+#define B_PMC_PWRM_ETR3_CF9GR                               BIT20           ///< CF9h Global Reset
+#define B_PMC_PWRM_ETR3_SKIP_HOST_RST_HS                    BIT19
+#define B_PMC_PWRM_ETR3_CWORWRE                             BIT18
+#define B_PMC_PWRM_THROT_1_VR_ALERT                         BIT0
+
+#define R_PMC_PWRM_SSML                                     0x104C           ///< Set Strap Msg Lock
+#define B_PMC_PWRM_SSML_SSL                                 BIT0             ///< Set_Strap Lock
+#define R_PMC_PWRM_SSMC                                     0x1050           ///< Set Strap Msg Control
+#define B_PMC_PWRM_SSMC_SSMS                                BIT0             ///< Set_Strap Mux Select
+#define R_PMC_PWRM_SSMD                                     0x1054           ///< Set Strap Msg Data
+
+#define R_PMC_PWRM_MODPHY_PM_CFG5                           0x10D0
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2            BIT26
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_DMI             BIT25
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E3              BIT24
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E2              BIT23
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E1              BIT22
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E0              BIT21
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D3              BIT20
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D2              BIT19
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D1              BIT18
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0              BIT17
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS             BIT16    ///< UFS ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI            BIT15    ///< xDCI ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI            BIT14    ///< xHCI ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE             BIT13    ///< GbE ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA            BIT12    ///< SATA ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C3              BIT11
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C2              BIT10
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C1              BIT9
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C0              BIT8
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B3              BIT7
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B2              BIT6
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B1              BIT5
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B0              BIT4
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A3              BIT3
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A2              BIT2
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A1              BIT1
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0              BIT0
+#define R_PMC_PWRM_WADT_AC                                  0x1800
+#define R_PMC_PWRM_PRSTS                                    0x1810                      ///< Power and Reset Status
+#define B_PMC_PWRM_PRSTS_VE_WD_TMR_STS                      BIT7                        ///< VE Watchdog Timer Status
+#define B_PMC_PWRM_PRSTS_WOL_OVR_WK_STS                     BIT5
+#define B_PMC_PWRM_PRSTS_FIELD_1                            BIT4
+#define B_PMC_PWRM_PRSTS_ME_WAKE_STS                        BIT0
+
+#define R_PMC_PWRM_1814                                     0x1814
+#define R_PMC_PWRM_CFG                                      0x1818                      ///< Power Management Configuration
+#define B_PMC_PWRM_CFG_ALLOW_24_OSC_SD                      BIT29                       ///< Allow 24MHz Crystal Oscillator Shutdown
+#define B_PMC_PWRM_CFG_DBG_MODE_LOCK                        BIT27                       ///< Debug Mode Lock
+#define B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG                   BIT25                       ///< Allow USB2 Core Power Gating
+#define B_PMC_PWRM_CFG_ER_LOCK                              BIT24                       ///< Energy Reporting Lock
+#define B_PMC_PWRM_CFG_EN_PMC_UNC_ERR                       BIT23                       ///< Enable Global Reset on Uncorrectable Parity Error on PMC SRAM Interface
+#define B_PMC_PWRM_CFG_PMCREAD_DISABLE                      BIT22                       ///< Disable Reads to PMC
+#define B_PMC_PWRM_CFG_RTC_DS_WAKE_DIS                      BIT21                       ///< RTC Wake from Deep S4/S5 Disable
+#define B_PMC_PWRM_CFG_SSMAW_MASK                           (BIT19 | BIT18)             ///< SLP_SUS# Min Assertion Width
+#define V_PMC_PWRM_CFG_SSMAW_4S                             (BIT19 | BIT18)             ///< 4 seconds
+#define V_PMC_PWRM_CFG_SSMAW_1S                             BIT19                       ///< 1 second
+#define V_PMC_PWRM_CFG_SSMAW_0_5S                           BIT18                       ///< 0.5 second (500ms)
+#define V_PMC_PWRM_CFG_SSMAW_0S                             0                           ///< 0 second
+#define B_PMC_PWRM_CFG_SAMAW_MASK                           (BIT17 | BIT16)             ///< SLP_A# Min Assertion Width
+#define V_PMC_PWRM_CFG_SAMAW_2S                             (BIT17 | BIT16)             ///< 2 seconds
+#define V_PMC_PWRM_CFG_SAMAW_98ms                           BIT17                       ///< 98ms
+#define V_PMC_PWRM_CFG_SAMAW_4S                             BIT16                       ///< 4 seconds
+#define V_PMC_PWRM_CFG_SAMAW_0S                             0                           ///< 0 second
+#define B_PMC_PWRM_CFG_RPCD_MASK                            (BIT9 | BIT8)               ///< Reset Power Cycle Duration
+#define V_PMC_PWRM_CFG_RPCD_1S                              (BIT9 | BIT8)               ///< 1-2 seconds
+#define V_PMC_PWRM_CFG_RPCD_2S                              BIT9                        ///< 2-3 seconds
+#define V_PMC_PWRM_CFG_RPCD_3S                              BIT8                        ///< 3-4 seconds
+#define V_PMC_PWRM_CFG_RPCD_4S                              0                           ///< 4-5 seconds (Default)
+#define B_PMC_PWRM_CFG_COCS                                 BIT5                        ///< CPU OC Strap
+#define B_PMC_PWRM_CFG_ER_EN                                BIT2                        ///< Energy Reporting Enable
+#define B_PMC_PWRM_CFG_TIMING_TPCH25                        (BIT1 | BIT0)               ///< tPCH25 timing
+
+#define R_PMC_PWRM_S3_PWRGATE_POL                           0x1828                      ///< S3 Power Gating Policies
+#define B_PMC_PWRM_S3_PWRGATE_POL_S3DC_GATE_SUS             BIT1                        ///< Deep S3 Enable in DC Mode
+#define B_PMC_PWRM_S3_PWRGATE_POL_S3AC_GATE_SUS             BIT0                        ///< Deep S3 Enable in AC Mode
+
+#define R_PMC_PWRM_S4_PWRGATE_POL                           0x182C                      ///< Deep S4 Power Policies
+#define B_PMC_PWRM_S4_PWRGATE_POL_S4DC_GATE_SUS             BIT1                        ///< Deep S4 Enable in DC Mode
+#define B_PMC_PWRM_S4_PWRGATE_POL_S4AC_GATE_SUS             BIT0                        ///< Deep S4 Enable in AC Mode
+
+#define R_PMC_PWRM_S5_PWRGATE_POL                           0x1830                      ///< Deep S5 Power Policies
+#define B_PMC_PWRM_S5_PWRGATE_POL_S5DC_GATE_SUS             BIT15                       ///< Deep S5 Enable in DC Mode
+#define B_PMC_PWRM_S5_PWRGATE_POL_S5AC_GATE_SUS             BIT14                       ///< Deep S5 Enable in AC Mode
+
+#define R_PMC_PWRM_DSX_CFG                                  0x1834                      ///< Deep SX Configuration
+#define B_PMC_PWRM_DSX_CFG_WAKE_PIN_DSX_EN                  BIT2                        ///< WAKE# Pin DeepSx Enable
+#define B_PMC_PWRM_DSX_CFG_ACPRES_PD_DSX_DIS                BIT1                        ///< AC_PRESENT pin pulldown in DeepSx disable
+#define B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN                      BIT0                        ///< LAN_WAKE Pin DeepSx Enable
+
+#define R_PMC_PWRM_CFG2                                     0x183C                      ///< Power Management Configuration Reg 2
+#define B_PMC_PWRM_CFG2_PBOP                                (BIT31 | BIT30 | BIT29)     ///< Power Button Override Period (PBOP)
+#define N_PMC_PWRM_CFG2_PBOP                                29                          ///< Power Button Override Period (PBOP)
+#define B_PMC_PWRM_CFG2_PB_DIS                              BIT28                       ///< Power Button Native Mode Disable (PB_DIS)
+#define B_PMC_PWRM_CFG2_EN_DBG_MSG                          BIT27                       ///< Enable PMC Debug Messages
+#define B_PMC_PWRM_CFG2_DRAM_RESET_CTL                      BIT26                       ///< DRAM RESET# control
+#define N_PMC_PWRM_CFG2_DRAM_RESET_CTL                      26
+
+#define R_PMC_PWRM_EN_SN_SLOW_RING                          0x1848                      ///< Enable Snoop Request to SLOW_RING
+#define R_PMC_PWRM_EN_SN_SLOW_RING2                         0x184C                      ///< Enable Snoop Request to SLOW_RING 2nd Reg
+#define R_PMC_PWRM_EN_SN_SA                                 0x1850                      ///< Enable Snoop Request to SA
+#define R_PMC_PWRM_EN_SN_SA2                                0x1854                      ///< Enable Snoop Request to SA 2nd Reg
+#define R_PMC_PWRM_EN_SN_SLOW_RING_CF                       0x1858                      ///< Enable Snoop Request to SLOW_RING_CF
+#define R_PMC_PWRM_EN_NS_SA                                 0x1868                      ///< Enable Non-Snoop Request to SA
+#define R_PMC_PWRM_EN_CW_SLOW_RING                          0x1880                      ///< Enable Clock Wake to SLOW_RING
+#define R_PMC_PWRM_EN_CW_SLOW_RING2                         0x1884                      ///< Enable Clock Wake to SLOW_RING 2nd Reg
+#define R_PMC_PWRM_EN_CW_SA                                 0x1888                      ///< Enable Clock Wake to SA
+#define R_PMC_PWRM_EN_CW_SA2                                0x188C                      ///< Enable Clock Wake to SA 2nd Reg
+#define R_PMC_PWRM_EN_CW_SLOW_RING_CF                       0x1898                      ///< Enable Clock Wake to SLOW_RING_CF
+#define R_PMC_PWRM_EN_PA_SLOW_RING                          0x18A8                      ///< Enable Pegged Active to SLOW_RING
+#define R_PMC_PWRM_EN_PA_SLOW_RING2                         0x18AC                      ///< Enable Pegged Active to SLOW_RING 2nd Reg
+#define R_PMC_PWRM_EN_PA_SA                                 0x18B0                      ///< Enable Pegged Active to SA
+#define R_PMC_PWRM_EN_PA_SA2                                0x18B4                      ///< Enable Pegged Active to SA 2nd Reg
+#define R_PMC_PWRM_EN_MISC_EVENT                            0x18C0                      ///< Enable Misc PM_SYNC Events
+#define R_PMC_PWRM_PMSYNC_TPR_CONFIG                        0x18C4
+#define B_PMC_PWRM_PMSYNC_TPR_CONFIG_LOCK                   BIT31
+#define B_PMC_PWRM_PMSYNC_PCH2CPU_TT_EN                     BIT26
+#define B_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE                  (BIT25 | BIT24)
+#define N_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE                  24
+#define V_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE_1                1
+#define B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK                      BIT15                       ///< PM_SYNC Configuration Lock
+#define B_PMC_PWRM_PMSYNC_GPIO_D_SEL                        BIT11
+#define B_PMC_PWRM_PMSYNC_GPIO_C_SEL                        BIT10
+
+#define R_PMC_PWRM_PM_SYNC_STATE_HYS                        0x18D0                      ///< PM_SYNC State Hysteresis
+#define R_PMC_PWRM_PM_SYNC_MODE                             0x18D4                      ///< PM_SYNC Pin Mode
+
+#define R_PMC_PWRM_CFG3                                     0x18E0                      ///< Power Management Configuration Reg 3
+#define B_PMC_PWRM_CFG3_HOST_WLAN_PP_EN                     BIT17                       ///< Host Wireless LAN Phy Power Enable
+#define B_PMC_PWRM_CFG3_DSX_WLAN_PP_EN                      BIT16                       ///< Deep-Sx WLAN Phy Power Enable
+
+#define R_PMC_PWRM_PM_DOWN_PPB_CFG                          0x18E4                      ///< PM_DOWN PCH_POWER_BUDGET CONFIGURATION
+
+#define R_PMC_PWRM_CFG4                                     0x18E8                      ///< Power Management Configuration Reg 4
+#define B_PMC_PWRM_CFG4_U2_PHY_PG_EN                        BIT30                       ///< USB2 PHY SUS Well Power Gating Enable
+#define B_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR                   (0x000001FF)                ///< CPU I/O VR Ramp Duration, [8:0]
+#define N_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR                   0
+#define V_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR_70US              0x007
+#define V_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR_240US             0x018
+
+#define R_PMC_PWRM_CPU_EPOC                                 0x18EC
+
+#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_CS_SD_CTL1                               0x1BE8            ///< Clock Source Shutdown Control Reg 1
+#define B_PMC_PWRM_CS_SD_CTL1_CS5_CTL_CFG                   (BIT22 | BIT21 | BIT20)    ///< Clock Source 5 Control Configuration
+#define N_PMC_PWRM_CS_SD_CTL1_CS5_CTL_CFG                   20
+#define B_PMC_PWRM_CS_SD_CTL1_CS1_CTL_CFG                   (BIT2 | BIT1 | BIT0)       ///< Clock Source 1 Control Configuration
+#define N_PMC_PWRM_CS_SD_CTL1_CS1_CTL_CFG                   0
+
+#define R_PMC_PWRM_CS_SD_CTL2                               0x1BEC ///< Clock Source Shutdown Control Reg 2
+
+#define R_PMC_PWRM_HSWPGCR1                                 0x1DD0
+#define B_PMC_PWRM_SW_PG_CTRL_LOCK                          BIT31
+#define B_PMC_PWRM_NPK_VNN_SW_PG_CTRL                       BIT0
+
+#define R_PMC_PWRM_1E00                                     0x1E00
+#define R_PMC_PWRM_1E04                                     0x1E04
+
+#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_CNVI_FDIS_PMC           BIT1   ///< CNVi Function Disable (PMC Version) (CNVI_FDIS_PMC)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK              BIT31 ///< Static Function Disable Lock (ST_FDIS_LK)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_CAM_FDIS_PMC            BIT6  ///< Camera Function Disable (PMC Version) (CAM_FDIS_PMC)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC            BIT5  ///< SH Function Disable (PMC Version) (ISH_FDIS_PMC)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC            BIT0  ///< GBE Function Disable (PMC Version) (GBE_FDIS_PMC)
+
+#define R_PMC_PWRM_ST_PG_FDIS_PMC_2                         0x1E24 ///< Static Function Disable Control Register 2
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI2_FDIS_PMC BIT11 ///< SerialIo Controller GSPI Device 2 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI1_FDIS_PMC BIT10 ///< SerialIo Controller GSPI Device 1 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI0_FDIS_PMC BIT9  ///< SerialIo Controller GSPI Device 0 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART2_FDIS_PMC BIT8  ///< SerialIo Controller UART Device 2 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART1_FDIS_PMC BIT7  ///< SerialIo Controller UART Device 1 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART0_FDIS_PMC BIT6  ///< SerialIo Controller UART Device 0 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C5_FDIS_PMC  BIT5  ///< SerialIo Controller I2C Device 5 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C4_FDIS_PMC  BIT4  ///< SerialIo Controller I2C Device 4 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C3_FDIS_PMC  BIT3  ///< SerialIo Controller I2C Device 3 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C2_FDIS_PMC  BIT2  ///< SerialIo Controller I2C Device 2 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C1_FDIS_PMC  BIT1  ///< SerialIo Controller I2C Device 1 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C0_FDIS_PMC  BIT0  ///< SerialIo Controller I2C Device 0 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO                0xFFF  ///< SerialIo Devices Disable Mask
+
+#define R_PMC_PWRM_NST_PG_FDIS_1                            0x1E28
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F3_FDIS_PMC     BIT31  ///< PCIe Controller F Port 3 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F2_FDIS_PMC     BIT30  ///< PCIe Controller F Port 2 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F1_FDIS_PMC     BIT29  ///< PCIe Controller F Port 1 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC     BIT28  ///< PCIe Controller F Port 0 Function Disable
+#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC     BIT29  ///< SD Card Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC      BIT27  ///< SD Card Function Disable
+#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC       BIT28  ///< eMMC Function Disable
+#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC        BIT27  ///< UFS Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC              BIT26  ///< XDCI Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_SMBUS_FDIS_PMC             BIT25  ///< Smbus Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC              BIT23  ///< ADSP Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC              BIT22  ///< SATA Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E3_FDIS_PMC     BIT21  ///< PCIe Controller E Port 3 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E2_FDIS_PMC     BIT20  ///< PCIe Controller E Port 2 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E1_FDIS_PMC     BIT19  ///< PCIe Controller E Port 1 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E0_FDIS_PMC     BIT18  ///< PCIe Controller E Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D3_FDIS_PMC           BIT17  ///< PCIe Controller D Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D2_FDIS_PMC           BIT16  ///< PCIe Controller D Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D1_FDIS_PMC           BIT15  ///< PCIe Controller D Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D0_FDIS_PMC           BIT14  ///< PCIe Controller D Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C3_FDIS_PMC           BIT13  ///< PCIe Controller C Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C2_FDIS_PMC           BIT12  ///< PCIe Controller C Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C1_FDIS_PMC           BIT11  ///< PCIe Controller C Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C0_FDIS_PMC           BIT10  ///< PCIe Controller C Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B3_FDIS_PMC           BIT9   ///< PCIe Controller B Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B2_FDIS_PMC           BIT8   ///< PCIe Controller B Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B1_FDIS_PMC           BIT7   ///< PCIe Controller B Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B0_FDIS_PMC           BIT6   ///< PCIe Controller B Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A3_FDIS_PMC           BIT5   ///< PCIe Controller A Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A2_FDIS_PMC           BIT4   ///< PCIe Controller A Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A1_FDIS_PMC           BIT3   ///< PCIe Controller A Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC           BIT2   ///< PCIe Controller A Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC              BIT0   ///< XHCI Function Disable
+
+#define R_PMC_PWRM_FUSE_DIS_RD_2                            0x1E44 ///< Fuse Disable Read 2 Register
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SPC_SS_DIS                 BIT25 ///< SPC Fuse Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SPB_SS_DIS                 BIT24 ///< SPB Fuse Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SPA_SS_DIS                 BIT23 ///< SPA Fuse Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_PSTH_FUSE_SS_DIS           BIT21 ///< PSTH Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_DMI_FUSE_SS_DIS            BIT20 ///< DMI Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS            BIT19 ///< OTG Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_XHCI_SS_DIS                BIT18 ///< XHCI Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_FIA_FUSE_SS_DIS            BIT17 ///< FIA Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_DSP_FUSE_SS_DIS            BIT16 ///< DSP Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS           BIT15 ///< SATA Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_ICC_FUSE_SS_DIS            BIT14 ///< ICC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_LPC_FUSE_SS_DIS            BIT13 ///< LPC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_RTC_FUSE_SS_DIS            BIT12 ///< RTC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_P2S_FUSE_SS_DIS            BIT11 ///< P2S Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_TRSB_FUSE_SS_DIS           BIT10 ///< TRSB Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SMB_FUSE_SS_DIS            BIT9  ///< SMB Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_ITSS_FUSE_SS_DIS           BIT8  ///< ITSS Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_UFSX2_FUSE_SS_DIS          BIT7   ///< UFSX2 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS       BIT6  ///< SerialIo Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_EMMC_FUSE_SS_DIS           BIT5   ///< EMMC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_CNVI_FUSE_SS_DIS           BIT4   ///< CNVi Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_P2D_FUSE_SS_DIS            BIT3  ///< P2D Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SDX_FUSE_SS_DIS            BIT2   ///< SD Conroller Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS            BIT1  ///< ISH Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS            BIT0  ///< GBE Fuse or Soft Strap Disable
+
+#define R_PMC_PWRM_FUSE_DIS_RD_3                            0x1E48 ///< Static PG Fuse and Soft Strap Disable Read Register 3
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA3_FUSE_SS_DIS         BIT3  ///< PNCRA3 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA2_FUSE_SS_DIS         BIT2  ///< PNCRA2 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA1_FUSE_SS_DIS         BIT1  ///< PNCRA1 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA_FUSE_SS_DIS          BIT0  ///< PNCRA Fuse or Soft Strap Disable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
new file mode 100644
index 0000000000..bd0c2574f2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
@@ -0,0 +1,72 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PMC_CNL_H_
+#define _PCH_REGS_PMC_CNL_H_
+
+//
+// PWRM Registers
+//
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A                        0x0
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B                        0x1
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C                        0xD
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D                        0x4
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E                        0xE
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F                        0x5
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G                        0x2
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H                        0x6
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD                          0xA
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO                        0x7
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI                          0x3
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA                          0xB
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG                         0xF
+
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A                         0x0
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B                         0x1
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C                         0x2
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D                         0x3
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E                         0xA
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F                         0xB
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G                         0x4
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H                         0x9
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I                         0xC
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J                         0xD
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K                         0x8
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD                           0x7
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO                         0x5
+
+#endif // _PCH_REGS_PMC_CNL_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
new file mode 100644
index 0000000000..5c4d583904
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
@@ -0,0 +1,104 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PSF_H_
+#define _PCH_REGS_PSF_H_
+
+//
+// Private chipset register (Memory space) offset definition
+// The PCR register defines is used for PCR MMIO programming and PCH SBI programming as well.
+//
+
+//
+// PSFx segment registers
+//
+#define R_PCH_PSF_PCR_GLOBAL_CONFIG                     0x4000                  ///< PSF Segment Global Configuration Register
+#define B_PCH_PSF_PCR_ROOTSPACE_CONFIG_RSX_ENADDRP2P    BIT1
+#define B_PCH_PSF_PCR_ROOTSPACE_CONFIG_RSX_VTDEN        BIT0
+
+#define S_PCH_PSFX_PCR_DEV_GNTCNT_RELOAD_DGCR                4
+#define S_PCH_PSFX_PCR_TARGET_GNTCNT_RELOAD                  4
+#define B_PCH_PSFX_PCR_DEV_GNTCNT_RELOAD_DGCR_GNT_CNT_RELOAD 0x1F
+#define B_PCH_PSFX_PCR_TARGET_GNTCNT_RELOAD_GNT_CNT_RELOAD   0x1F
+
+#define N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC          1
+#define B_PCH_PSFX_PCR_MC_CONTROL_MCASTX_MULTCEN        BIT0
+
+//
+// PSFx PCRs definitions
+//
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR0                     0                       ///< PCI BAR0
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR1                     0x04                    ///< PCI BAR1
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR2                     0x08                    ///< PCI BAR2
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR3                     0x0C                    ///< PCI BAR3
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR4                     0x10                    ///< PCI BAR4
+#define R_PCH_PSFX_PCR_T0_SHDW_PCIEN                    0x1C                    ///< PCI configuration space enable bits
+#define N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS            16
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR0DIS            BIT16                   ///< Disable BAR0
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR1DIS            BIT17                   ///< Disable BAR1
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR2DIS            BIT18                   ///< Disable BAR2
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR3DIS            BIT19                   ///< Disable BAR3
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR4DIS            BIT20                   ///< Disable BAR4
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR5DIS            BIT21                   ///< Disable BAR5
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS             BIT8                    ///< Function disable
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_MEMEN              BIT1                    ///< Memory decoding enable
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN               BIT0                    ///< IO decoding enable
+#define R_PCH_PSFX_PCR_T0_SHDW_PMCSR                    0x20                    ///< PCI power management configuration
+#define B_PCH_PSFX_PCR_T0_SHDW_PMCSR_PWRST              (BIT1 | BIT0)           ///< Power status
+#define R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS                  0x38                    ///< PCI configuration disable
+#define B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS           BIT0                    ///< config disable
+
+#define R_PCH_PSFX_PCR_T1_SHDW_PCIEN                    0x3C                    ///< PCI configuration space enable bits
+#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_FUNDIS             BIT8                    ///< Function disable
+#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_MEMEN              BIT1                    ///< Memory decoding enable
+#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_IOEN               BIT0                    ///< IO decoding enable
+
+#define B_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_DEVICE    0x01F0                 ///< device number
+#define N_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_DEVICE    4
+#define B_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_FUNCTION  (BIT3 | BIT2 | BIT1)   ///< function number
+#define N_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_FUNCTION  1
+
+#define B_PCH_PSFX_PCR_TARGET_CHANNELID                 0xFF
+#define B_PCH_PSFX_PCR_TARGET_PORTID                    0x7F00
+#define N_PCH_PSFX_PCR_TARGET_PORTID                    8
+#define B_PCH_PSFX_PCR_TARGET_PORTGROUPID               BIT15
+#define N_PCH_PSFX_PCR_TARGET_PORTGROUPID               15
+#define B_PCH_PSFX_PCR_TARGET_PSFID                     0xFF0000
+#define N_PCH_PSFX_PCR_TARGET_PSFID                     16
+#define B_PCH_PSFX_PCR_TARGET_CHANMAP                   BIT31
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
new file mode 100644
index 0000000000..9a5e536f18
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
@@ -0,0 +1,113 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PSF_CNL_H_
+#define _PCH_REGS_PSF_CNL_H_
+
+//PSF 1 Multicast Message Configuration
+#define R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI                 0x404C      ///< Multicast Control Register
+#define R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI              0x4064      ///< Destination ID
+#define R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI                  0x403C      ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI               0x4054      ///< Destination ID
+
+//
+// PSF3 PCRs (PID:PSF3)
+//
+// PSF3 PCH-LP Specific Base Address
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE         0x0100                  ///< D18F6 PSF base address (SerialIo: SPI2)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_ISH_REG_BASE          0x0200                  ///< D19F0 PSF base address (ISH)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_CNVI_REG_BASE         0x0400                  ///< D20F3 PSF base address (CNVi)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SDCARD_REG_BASE       0x0500                  ///< D20F5 PSF base address (SCC: SDCard)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE         0x0600                  ///< D21F0 PSF base address (SerialIo: I2C0)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE         0x0700                  ///< D21F1 PSF base address (SerialIo: I2C1)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE         0x0800                  ///< D21F2 PSF base address (SerialIo: I2C2)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE         0x0900                  ///< D21F3 PSF base address (SerialIo: I2C3)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE         0x0A00                  ///< D25F0 PSF base address (SerialIo: I2C4)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE         0x0B00                  ///< D25F1 PSF base address (SerialIo: I2C5)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE        0x0C00                  ///< D25F2 PSF base address (SerialIo: UART2)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE        0x0D00                  ///< D30F0 PSF base address (SerialIo: UART0)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE        0x0E00                  ///< D30F1 PSF base address (SerialIo: UART1)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE         0x0F00                  ///< D30F2 PSF base address (SerialIo: SPI0)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE         0x1000                  ///< D30F3 PSF base address (SerialIo: SPI1)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_LPC_REG_BASE          0x1100                  ///< D31F0 PSF base address (LPC)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_P2SB_REG_BASE         0x1300                  ///< D31F1 PSF base address (P2SB)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE          0x1400                  ///< D31F2 PSF base address (PMC)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_AUD_REG_BASE          0x1500                  ///< D31F3 PSF base address (HDA, ADSP)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SMBUS_REG_BASE        0x1600                  ///< D31F4 PSF base address (SMBUS)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI_SPI_REG_BASE      0x1700                  ///< D31F5 PSF base address (SPI SPI)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_GBE_REG_BASE          0x1800                  ///< D31F6 PSF base address (GBE)
+// PSF3 PCH-H Specific Base Address
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE          0x0100                  ///< D18F6 PSF base address (SerialIo: SPI2)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_ISH_REG_BASE           0x0180                  ///< D19F0 PSF base address (ISH)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_CNVI_REG_BASE          0x0280                  ///< D20F3 PSF base address (CNVi)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SDCARD_REG_BASE        0x0300                  ///< D20F5 PSF base address (SCC: SDCard)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE          0x0380                  ///< D21F0 PSF base address (SerialIo: I2C0)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE          0x0400                  ///< D21F1 PSF base address (SerialIo: I2C1)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE          0x0480                  ///< D21F2 PSF base address (SerialIo: I2C2)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE          0x0500                  ///< D21F3 PSF base address (SerialIo: I2C3)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE         0x0580                  ///< D25F2 PSF base address (SerialIo: UART2)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE         0x0600                  ///< D30F0 PSF base address (SerialIo: UART0)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE         0x0680                  ///< D30F1 PSF base address (SerialIo: UART1)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE          0x0700                  ///< D30F2 PSF base address (SerialIo: SPI0)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE          0x0780                  ///< D30F3 PSF base address (SerialIo: SPI1)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_LPC_REG_BASE           0x0800                  ///< D31F0 PSF base address (LPC)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_P2SB_REG_BASE          0x0900                  ///< D31F1 PSF base address (P2SB)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE           0x0980                  ///< D31F2 PSF base address (PMC)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_AUD_REG_BASE           0x0A00                  ///< D31F3 PSF base address (HDA, ADSP)H
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SMBUS_REG_BASE         0x0A80                  ///< D31F4 PSF base address (SMBUS)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI_SPI_REG_BASE       0x0B00                  ///< D31F5 PSF base address (SPI SPI)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_GBE_REG_BASE           0x0B80                  ///< D31F6 PSF base address (GBE)
+
+// Other PSF3 PCRs definition
+#define R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI        0x4058                  ///< Multicast Control Register  // LP&H
+#define R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI     0x4064                  ///< Destination ID  // LP&H
+
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI              0x4030          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI           0x4048          ///< Destination ID
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1        0x403C          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1     0x4070          ///< Destination ID
+
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI              0x4030          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI           0x4048          ///< Destination ID
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1        0x403C          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1     0x4070          ///< Destination ID
+
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI              0x4030          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI           0x4048          ///< Destination ID
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1        0x403C          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1     0x4070          ///< Destination ID
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
new file mode 100644
index 0000000000..d6030ed10d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
@@ -0,0 +1,77 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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 register (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 B_PSTH_PCR_PSTHIOSFSTCGE    BIT1                  ///< PSTH IOSF sideband trunk clock gating enable
+#define B_PSTH_PCR_PSTHDCGE         BIT0                  ///< PSTH dynamic clock gating enable
+#define R_PSTH_PCR_TRPST            0x1E00                ///< Trap status register
+#define B_PSTH_PCR_TRPST_CTSS       0x0000000F            ///< Cycle Trap SMI# Status mask
+#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 B_PSTH_PCR_TRPD_IOD         0x00000000FFFFFFFF    ///< Trap cycle I/O 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 B_PSTH_PCR_TRPREG_BEM       0x000000F000000000    ///< Byte enable mask
+#define N_PSTH_PCR_TRPREG_BE        32
+#define B_PSTH_PCR_TRPREG_BE        0x0000000F00000000    ///< Byte enable
+#define B_PSTH_PCR_TRPREG_AM        0x0000000000FC0000    ///< IO Address mask
+#define B_PSTH_PCR_TRPREG_AD        0x000000000000FFFC    ///< IO Address
+#define B_PSTH_PCR_TRPREG_TSE       BIT0                  ///< Trap and SMI# Enable
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
new file mode 100644
index 0000000000..d98ce39df6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
@@ -0,0 +1,668 @@
+/** @file
+  Register names for PCH 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SATA_H_
+#define _PCH_REGS_SATA_H_
+
+//
+//  SATA Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SATA          23
+#define PCI_FUNCTION_NUMBER_PCH_SATA        0
+
+#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_1    7
+#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1  0
+
+#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_2    8
+#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2  0
+
+#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_3    14
+#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3  0
+
+//
+//  PCH-LP SATA Device ID's
+//
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_AHCI         0x9DD3  ///< SATA Controller (AHCI) - Mobile
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID         0x9DD5  ///< SATA Controller (RAID 0/1/5/10) - NOT premium - Mobile
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_PREM    0x9DD7  ///< SATA Controller (RAID 0/1/5/10) - premium - Mobile
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_IBC     0x282A  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible - Mobile
+
+//
+//  PCH-H SATA Device ID's
+//
+#define V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_ALTDIS   0x2822  ///< SATA Controller (RAID 0/1/5/10) - premium - Alternate ID
+#define V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_RSTE     0x2826  ///< SATA Controller (RAID 0/1/5/10) - RSTe of Server SKU
+
+//
+//  PCH-H SATA Device ID's
+//
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_AHCI         0xA352  ///< SATA Controller (AHCI) Desktop/Server
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_AHCI        0xA353  ///< SATA Controller (AHCI) Mobile Halo
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID         0xA354  ///< SATA Controller (RAID 0/1/5/10) - NOT premium Desktop/Server
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID        0xA355  ///< SATA Controller (RAID 0/1/5/10) - NOT premium Mobile Halo
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_PREM    0xA356  ///< SATA Controller (RAID 0/1/5/10) - premium Desktop/Server
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID_PREM   0xA357  ///< SATA Controller (RAID 0/1/5/10) - premium Mobile Halo
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_OP_AHCI      0xA35E  ///< SATA Controller (AHCI) Optane Caching - Desktop
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC     0x2822  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_RST 0x2826  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible (RSTe)
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_2   0x282A  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible (Alternate)
+
+
+//
+//  SATA Controller common Registers
+//
+#define V_SATA_CFG_SUB_CLASS_CODE_AHCI      0x06
+#define V_SATA_CFG_SUB_CLASS_CODE_RAID      0x04
+#define R_SATA_CFG_AHCI_BAR                 0x24
+#define B_SATA_CFG_AHCI_BAR_BA              0xFFFFF800
+#define V_SATA_CFG_AHCI_BAR_LENGTH          0x800
+#define N_SATA_CFG_AHCI_BAR_ALIGNMENT       11
+#define V_SATA_CFG_AHCI_BAR_LENGTH_512K     0x80000
+#define N_SATA_CFG_AHCI_BAR_ALIGNMENT_512K  19
+#define B_SATA_CFG_AHCI_BAR_PF              BIT3
+#define B_SATA_CFG_AHCI_BAR_TP              (BIT2 | BIT1)
+#define B_SATA_CFG_AHCI_BAR_RTE             BIT0
+#define R_SATA_CFG_PID                      0x70
+#define B_SATA_CFG_PID_NEXT                 0xFF00
+#define V_SATA_CFG_PID_NEXT_0               0xB000
+#define V_SATA_CFG_PID_NEXT_1               0xA800
+#define B_SATA_CFG_PID_CID                  0x00FF
+#define R_SATA_CFG_PC                       0x72
+#define S_SATA_CFG_PC                       2
+#define B_SATA_CFG_PC_PME                   (BIT15 | BIT14 | BIT13 | BIT12 | BIT11)
+#define V_SATA_CFG_PC_PME_0                 0x0000
+#define V_SATA_CFG_PC_PME_1                 0x4000
+#define B_SATA_CFG_PC_D2_SUP                BIT10
+#define B_SATA_CFG_PC_D1_SUP                BIT9
+#define B_SATA_CFG_PC_AUX_CUR               (BIT8 | BIT7 | BIT6)
+#define B_SATA_CFG_PC_DSI                   BIT5
+#define B_SATA_CFG_PC_PME_CLK               BIT3
+#define B_SATA_CFG_PC_VER                   (BIT2 | BIT1 | BIT0)
+#define R_SATA_CFG_PMCS                     0x74
+#define B_SATA_CFG_PMCS_PMES                BIT15
+#define B_SATA_CFG_PMCS_PMEE                BIT8
+#define B_SATA_CFG_PMCS_NSFRST              BIT3
+#define V_SATA_CFG_PMCS_NSFRST_1            0x01
+#define V_SATA_CFG_PMCS_NSFRST_0            0x00
+#define B_SATA_CFG_PMCS_PS                  (BIT1 | BIT0)
+#define V_SATA_CFG_PMCS_PS_3                0x03
+#define V_SATA_CFG_PMCS_PS_0                0x00
+#define R_SATA_CFG_MID                      0x80
+#define B_SATA_CFG_MID_NEXT                 0xFF00
+#define B_SATA_CFG_MID_CID                  0x00FF
+#define R_SATA_CFG_MC                       0x82
+#define B_SATA_CFG_MC_C64                   BIT7
+#define B_SATA_CFG_MC_MME                   (BIT6 | BIT5 | BIT4)
+#define V_SATA_CFG_MC_MME_4                 0x04
+#define V_SATA_CFG_MC_MME_2                 0x02
+#define V_SATA_CFG_MC_MME_1                 0x01
+#define V_SATA_CFG_MC_MME_0                 0x00
+#define B_SATA_CFG_MC_MMC                   (BIT3 | BIT2 | BIT1)
+#define V_SATA_CFG_MC_MMC_4                 0x04
+#define V_SATA_CFG_MC_MMC_0                 0x00
+#define B_SATA_CFG_MC_MSIE                  BIT0
+#define V_SATA_CFG_MC_MSIE_1                0x01
+#define V_SATA_CFG_MC_MSIE_0                0x00
+#define R_SATA_CFG_MA                       0x84
+#define B_SATA_CFG_MA                       0xFFFFFFFC
+#define R_SATA_CFG_MD                       0x88
+#define B_SATA_CFG_MD_MSIMD                 0xFFFF
+
+#define R_SATA_CFG_MAP                      0x90
+#define B_SATA_CFG_MAP_PCD                  0xFF
+#define N_SATA_CFG_MAP_SPD                  16
+#define B_SATA_CFG_MAP_SPD7                 BIT23
+#define B_SATA_CFG_MAP_SPD6                 BIT22
+#define B_SATA_CFG_MAP_SPD5                 BIT21
+#define B_SATA_CFG_MAP_SPD4                 BIT20
+#define B_SATA_CFG_MAP_SPD3                 BIT19
+#define B_SATA_CFG_MAP_SPD2                 BIT18
+#define B_SATA_CFG_MAP_SPD1                 BIT17
+#define B_SATA_CFG_MAP_SPD0                 BIT16
+#define B_SATA_CFG_MAP_PORT7_PCD            BIT7
+#define B_SATA_CFG_MAP_PORT6_PCD            BIT6
+#define B_SATA_CFG_MAP_PORT5_PCD            BIT5
+#define B_SATA_CFG_MAP_PORT4_PCD            BIT4
+#define B_SATA_CFG_MAP_PORT3_PCD            BIT3
+#define B_SATA_CFG_MAP_PORT2_PCD            BIT2
+#define B_SATA_CFG_MAP_PORT1_PCD            BIT1
+#define B_SATA_CFG_MAP_PORT0_PCD            BIT0
+#define R_SATA_CFG_PCS                      0x94
+#define B_SATA_CFG_PCS_P7P                  BIT23
+#define B_SATA_CFG_PCS_P6P                  BIT22
+#define B_SATA_CFG_PCS_P5P                  BIT21
+#define B_SATA_CFG_PCS_P4P                  BIT20
+#define B_SATA_CFG_PCS_P3P                  BIT19
+#define B_SATA_CFG_PCS_P2P                  BIT18
+#define B_SATA_CFG_PCS_P1P                  BIT17
+#define B_SATA_CFG_PCS_P0P                  BIT16
+#define B_SATA_CFG_PCS_P7E                  BIT7
+#define B_SATA_CFG_PCS_P6E                  BIT6
+#define B_SATA_CFG_PCS_P5E                  BIT5
+#define B_SATA_CFG_PCS_P4E                  BIT4
+#define B_SATA_CFG_PCS_P3E                  BIT3
+#define B_SATA_CFG_PCS_P2E                  BIT2
+#define B_SATA_CFG_PCS_P1E                  BIT1
+#define B_SATA_CFG_PCS_P0E                  BIT0
+#define R_SATA_CFG_SATAGC                   0x9C
+#define B_SATA_CFG_SATAGC_SMS_MASK          BIT16
+#define N_SATA_CFG_SATAGC_SMS_MASK          16
+#define V_SATA_CFG_SATAGC_SMS_AHCI          0x0
+#define V_SATA_CFG_SATAGC_SMS_RAID          0x1
+#define B_SATA_CFG_SATAGC_AIE               BIT7
+#define B_SATA_CFG_SATAGC_AIES              BIT6
+#define B_SATA_CFG_SATAGC_MSS               (BIT4 | BIT3)
+#define V_SATA_CFG_SATAGC_MSS_8K            0x2
+#define N_SATA_CFG_SATAGC_MSS               3
+#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
+
+#define R_SATA_CFG_SIRI                     0xA0
+#define R_SATA_CFG_STRD                     0xA4
+#define R_SATA_CFG_SIR_0C                   0x0C
+#define R_SATA_CFG_SIR_50                   0x50
+#define R_SATA_CFG_SIR_54                   0x54
+#define R_SATA_CFG_SIR_58                   0x58
+#define R_SATA_CFG_SIR_5C                   0x5C
+#define R_SATA_CFG_SIR_60                   0x60
+#define R_SATA_CFG_SIR_64                   0x64
+#define R_SATA_CFG_SIR_68                   0x68
+#define R_SATA_CFG_SIR_6C                   0x6C
+#define R_SATA_CFG_SIR_70                   0x70
+#define R_SATA_CFG_SIR_80                   0x80
+#define R_SATA_CFG_SIR_84                   0x84
+#define R_SATA_CFG_SIR_8C                   0x8C
+#define R_SATA_CFG_SIR_90                   0x90
+#define R_SATA_CFG_SIR_98                   0x98
+#define R_SATA_CFG_SIR_9C                   0x9C
+#define R_SATA_CFG_SIR_A0                   0xA0
+#define R_SATA_CFG_SIR_A4                   0xA4
+#define R_SATA_CFG_SIR_A8                   0xA8
+#define R_SATA_CFG_SIR_C8                   0xC8
+#define R_SATA_CFG_SIR_CC                   0xCC
+#define R_SATA_CFG_SIR_D0                   0xD0
+#define R_SATA_CFG_SIR_D4                   0xD4
+#define B_SATA_CFG_STRD_DTA                 0xFFFFFFFF
+#define R_SATA_CFG_CR0                      0xA8
+#define B_SATA_CFG_CR0_MAJREV               0x00F00000
+#define B_SATA_CFG_CR0_MINREV               0x000F0000
+#define B_SATA_CFG_CR0_NEXT                 0x0000FF00
+#define B_SATA_CFG_CR0_CAP                  0x000000FF
+#define R_SATA_CFG_CR1                      0xAC
+#define B_SATA_CFG_CR1_BAROFST              0xFFF0
+#define B_SATA_CFG_CR1_BARLOC               0x000F
+#define R_SATA_CFG_FLR_CID                  0xB0
+#define B_SATA_CFG_FLR_CID_NEXT             0xFF00
+#define B_SATA_CFG_FLR_CID                  0x00FF
+#define V_SATA_CFG_FLR_CID_1                0x0009
+#define V_SATA_CFG_FLR_CID_0                0x0013
+#define R_SATA_CFG_FLR_CLV                  0xB2
+#define B_SATA_CFG_FLR_CLV_FLRC_FLRCSSEL_0  BIT9
+#define B_SATA_CFG_FLR_CLV_TXPC_FLRCSSEL_0  BIT8
+#define B_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL_0 0x00FF
+#define B_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL_1 0x00FF
+#define V_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL   0x0006
+#define R_SATA_CFG_FLRC                     0xB4
+#define B_SATA_CFG_FLRC_TXP                 BIT8
+#define B_SATA_CFG_FLRC_INITFLR             BIT0
+#define R_SATA_CFG_SP                       0xC0
+#define B_SATA_CFG_SP                       0xFFFFFFFF
+#define R_SATA_CFG_MXID                     0xD0
+#define N_SATA_CFG_MXID_NEXT                8
+
+#define R_SATA_CFG_BFCS                     0xE0
+#define B_SATA_CFG_BFCS_P7BFI               BIT17
+#define B_SATA_CFG_BFCS_P6BFI               BIT16
+#define B_SATA_CFG_BFCS_P5BFI               BIT15
+#define B_SATA_CFG_BFCS_P4BFI               BIT14
+#define B_SATA_CFG_BFCS_P3BFI               BIT13
+#define B_SATA_CFG_BFCS_P2BFI               BIT12
+#define B_SATA_CFG_BFCS_P2BFS               BIT11
+#define B_SATA_CFG_BFCS_P2BFF               BIT10
+#define B_SATA_CFG_BFCS_P1BFI               BIT9
+#define B_SATA_CFG_BFCS_P0BFI               BIT8
+#define B_SATA_CFG_BFCS_BIST_FIS_T          BIT7
+#define B_SATA_CFG_BFCS_BIST_FIS_A          BIT6
+#define B_SATA_CFG_BFCS_BIST_FIS_S          BIT5
+#define B_SATA_CFG_BFCS_BIST_FIS_L          BIT4
+#define B_SATA_CFG_BFCS_BIST_FIS_F          BIT3
+#define B_SATA_CFG_BFCS_BIST_FIS_P          BIT2
+#define R_SATA_CFG_BFTD1                    0xE4
+#define B_SATA_CFG_BFTD1                    0xFFFFFFFF
+#define R_SATA_CFG_BFTD2                    0xE8
+#define B_SATA_CFG_BFTD2                    0xFFFFFFFF
+
+#define R_SATA_CFG_VS_CAP                   0xA4
+#define B_SATA_CFG_VS_CAP_NRMBE             BIT0                            ///< NVM Remap Memory BAR Enable
+#define B_SATA_CFG_VS_CAP_MSL               0x1FFE                          ///< Memory Space Limit
+#define N_SATA_CFG_VS_CAP_MSL               1
+#define V_SATA_CFG_VS_CAP_MSL               0x1EF                           ///< Memory Space Limit Field Value
+#define B_SATA_CFG_VS_CAP_NRMO              0xFFF0000                       ///< NVM Remapped Memory Offset
+#define N_SATA_CFG_VS_CAP_NRMO              16
+#define V_SATA_CFG_VS_CAP_NRMO              0x10                            ///< NVM Remapped Memory Offset Field Value
+
+//
+// RST PCIe Storage Remapping Registers
+//
+#define R_SATA_CFG_RST_PCIE_STORAGE_RCR                 0x800                           ///< Remap Capability Register
+#define B_SATA_CFG_RST_PCIE_STORAGE_RCR_NRS             (BIT2|BIT1|BIT0)                ///< Number of Remapping Supported
+#define B_SATA_CFG_RST_PCIE_STORAGE_RCR_NRS_CR1         BIT0                            ///< Number of Remapping Supported (RST PCIe Storage Cycle Router #1)
+#define R_SATA_CFG_RST_PCIE_STORAGE_SPR                 0x80C                           ///< Scratch Pad Register
+#define R_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC             0x880                           ///< CR#1 Device Class Code
+#define N_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_SCC         8
+#define N_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_BCC         16
+#define B_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_DT          BIT31                           ///< Device Type
+#define V_SATA_CFG_RST_PCIE_STORAGE_REMAP_CONFIG_CR     0x80                            ///< Remapped Configuration for RST PCIe Storage Cycle Router #n
+#define V_SATA_CFG_RST_PCIE_STORAGE_REMAP_RP_OFFSET     0x100                           ///< Remapped Root Port Offset Value
+#define R_SATA_CFG_RST_PCIE_STORAGE_CCFG                0x1D0                           ///< Port Configuration Register
+//
+// AHCI BAR Area related Registers
+//
+#define R_SATA_MEM_AHCI_CAP                 0x0
+#define B_SATA_MEM_AHCI_CAP_S64A            BIT31
+#define B_SATA_MEM_AHCI_CAP_SCQA            BIT30
+#define B_SATA_MEM_AHCI_CAP_SSNTF           BIT29
+#define B_SATA_MEM_AHCI_CAP_SMPS            BIT28 ///< Supports Interlock Switch
+#define B_SATA_MEM_AHCI_CAP_SSS             BIT27 ///< Supports Stagger Spin-up
+#define B_SATA_MEM_AHCI_CAP_SALP            BIT26
+#define B_SATA_MEM_AHCI_CAP_SAL             BIT25
+#define B_SATA_MEM_AHCI_CAP_SCLO            BIT24 ///< Supports Command List Override
+#define B_SATA_MEM_AHCI_CAP_ISS_MASK        (BIT23 | BIT22 | BIT21 | BIT20)
+#define N_SATA_MEM_AHCI_CAP_ISS             20    ///< Interface Speed Support
+#define V_SATA_MEM_AHCI_CAP_ISS_1_5_G       0x01
+#define V_SATA_MEM_AHCI_CAP_ISS_3_0_G       0x02
+#define V_SATA_MEM_AHCI_CAP_ISS_6_0_G       0x03
+#define B_SATA_MEM_AHCI_CAP_SNZO            BIT19
+#define B_SATA_MEM_AHCI_CAP_SAM             BIT18
+#define B_SATA_MEM_AHCI_CAP_SPM             BIT17 ///< Supports Port Multiplier
+#define B_SATA_MEM_AHCI_CAP_PMD             BIT15 ///< PIO Multiple DRQ Block
+#define B_SATA_MEM_AHCI_CAP_SSC             BIT14
+#define B_SATA_MEM_AHCI_CAP_PSC             BIT13
+#define B_SATA_MEM_AHCI_CAP_NCS             0x1F00
+#define B_SATA_MEM_AHCI_CAP_CCCS            BIT7
+#define B_SATA_MEM_AHCI_CAP_EMS             BIT6
+#define B_SATA_MEM_AHCI_CAP_SXS             BIT5  ///< External SATA is supported
+#define B_SATA_MEM_AHCI_CAP_NPS             0x001F
+
+#define R_SATA_MEM_AHCI_GHC                 0x04
+#define B_SATA_MEM_AHCI_GHC_AE              BIT31
+#define B_SATA_MEM_AHCI_GHC_MRSM            BIT2
+#define B_SATA_MEM_AHCI_GHC_IE              BIT1
+#define B_SATA_MEM_AHCI_GHC_HR              BIT0
+
+#define R_SATA_MEM_AHCI_IS                  0x08
+#define B_SATA_MEM_AHCI_IS_PORT7            BIT7
+#define B_SATA_MEM_AHCI_IS_PORT6            BIT6
+#define B_SATA_MEM_AHCI_IS_PORT5            BIT5
+#define B_SATA_MEM_AHCI_IS_PORT4            BIT4
+#define B_SATA_MEM_AHCI_IS_PORT3            BIT3
+#define B_SATA_MEM_AHCI_IS_PORT2            BIT2
+#define B_SATA_MEM_AHCI_IS_PORT1            BIT1
+#define B_SATA_MEM_AHCI_IS_PORT0            BIT0
+#define R_SATA_MEM_AHCI_PI                  0x0C
+#define B_SATA_MEM_AHCI_PI_PORT_MASK        0xFF
+#define B_SATA_MEM_PORT7_IMPLEMENTED        BIT7
+#define B_SATA_MEM_PORT6_IMPLEMENTED        BIT6
+#define B_SATA_MEM_PORT5_IMPLEMENTED        BIT5
+#define B_SATA_MEM_PORT4_IMPLEMENTED        BIT4
+#define B_SATA_MEM_PORT3_IMPLEMENTED        BIT3
+#define B_SATA_MEM_PORT2_IMPLEMENTED        BIT2
+#define B_SATA_MEM_PORT1_IMPLEMENTED        BIT1
+#define B_SATA_MEM_PORT0_IMPLEMENTED        BIT0
+#define R_SATA_MEM_AHCI_VS                  0x10
+#define B_SATA_MEM_AHCI_VS_MJR              0xFFFF0000
+#define B_SATA_MEM_AHCI_VS_MNR              0x0000FFFF
+#define R_SATA_MEM_AHCI_EM_LOC              0x1C
+#define B_SATA_MEM_AHCI_EM_LOC_OFST         0xFFFF0000
+#define B_SATA_MEM_AHCI_EM_LOC_SZ           0x0000FFFF
+#define R_SATA_MEM_AHCI_EM_CTRL             0x20
+#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_ALHD   BIT26
+#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_XMT    BIT25
+#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_SMB    BIT24
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SGPIO  BIT19
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SES2   BIT18
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SAFTE  BIT17
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_LED    BIT16
+#define B_SATA_MEM_AHCI_EM_CTRL_RST         BIT9
+#define B_SATA_MEM_AHCI_EM_CTRL_CTL_TM      BIT8
+#define B_SATA_MEM_AHCI_EM_CTRL_STS_MR      BIT0
+#define R_SATA_MEM_AHCI_CAP2                0x24
+#define B_SATA_MEM_AHCI_CAP2_DESO           BIT5
+#define B_SATA_MEM_AHCI_CAP2_SADM           BIT4
+#define B_SATA_MEM_AHCI_CAP2_SDS            BIT3
+#define B_SATA_MEM_AHCI_CAP2_APST           BIT2  ///< Automatic Partial to Slumber Transitions
+#define R_SATA_MEM_AHCI_VSP                 0xA0
+#define B_SATA_MEM_AHCI_VSP_SLPD            BIT0
+#define R_SATA_MEM_AHCI_SFM                 0xC8  ///< RST Feature Capabilities
+#define B_SATA_MEM_AHCI_SFM_LEGACY          BIT12
+#define B_SATA_MEM_AHCI_SFM_OUD             (BIT11 | BIT10)
+#define N_SATA_MEM_AHCI_SFM_OUD             10
+#define B_SATA_MEM_AHCI_SFM_SEREQ           BIT9
+#define B_SATA_MEM_AHCI_SFM_IROES           BIT8
+#define B_SATA_MEM_AHCI_SFM_LEDL            BIT7
+#define B_SATA_MEM_AHCI_SFM_HDDLK           BIT6
+#define B_SATA_MEM_AHCI_SFM_IRSTOROM        BIT5
+#define B_SATA_MEM_AHCI_SFM_RSTE            BIT4
+#define B_SATA_MEM_AHCI_SFM_R5E             BIT3
+#define B_SATA_MEM_AHCI_SFM_R10E            BIT2
+#define B_SATA_MEM_AHCI_SFM_R1E             BIT1
+#define B_SATA_MEM_AHCI_SFM_R0E             BIT0
+#define B_SATA_MEM_AHCI_SFM_LOWBYTES        0x1FF
+#define R_SATA_MEM_AHCI_P0CLB               0x100
+#define R_SATA_MEM_AHCI_P1CLB               0x180
+#define R_SATA_MEM_AHCI_P2CLB               0x200
+#define R_SATA_MEM_AHCI_P3CLB               0x280
+#define R_SATA_MEM_AHCI_P4CLB               0x300
+#define R_SATA_MEM_AHCI_P5CLB               0x380
+#define R_SATA_MEM_AHCI_P6CLB               0x400
+#define R_SATA_MEM_AHCI_P7CLB               0x480
+#define B_SATA_MEM_AHCI_PXCLB               0xFFFFFC00
+#define R_SATA_MEM_AHCI_P0CLBU              0x104
+#define R_SATA_MEM_AHCI_P1CLBU              0x184
+#define R_SATA_MEM_AHCI_P2CLBU              0x204
+#define R_SATA_MEM_AHCI_P3CLBU              0x284
+#define R_SATA_MEM_AHCI_P4CLBU              0x304
+#define R_SATA_MEM_AHCI_P5CLBU              0x384
+#define R_SATA_MEM_AHCI_P6CLBU              0x404
+#define R_SATA_MEM_AHCI_P7CLBU              0x484
+#define B_SATA_MEM_AHCI_PXCLBU              0xFFFFFFFF
+#define R_SATA_MEM_AHCI_P0FB                0x108
+#define R_SATA_MEM_AHCI_P1FB                0x188
+#define R_SATA_MEM_AHCI_P2FB                0x208
+#define R_SATA_MEM_AHCI_P3FB                0x288
+#define R_SATA_MEM_AHCI_P4FB                0x308
+#define R_SATA_MEM_AHCI_P5FB                0x388
+#define R_SATA_MEM_AHCI_P6FB                0x408
+#define R_SATA_MEM_AHCI_P7FB                0x488
+#define B_SATA_MEM_AHCI_PXFB                0xFFFFFF00
+#define R_SATA_MEM_AHCI_P0FBU               0x10C
+#define R_SATA_MEM_AHCI_P1FBU               0x18C
+#define R_SATA_MEM_AHCI_P2FBU               0x20C
+#define R_SATA_MEM_AHCI_P3FBU               0x28C
+#define R_SATA_MEM_AHCI_P4FBU               0x30C
+#define R_SATA_MEM_AHCI_P5FBU               0x38C
+#define R_SATA_MEM_AHCI_P6FBU               0x40C
+#define R_SATA_MEM_AHCI_P7FBU               0x48C
+#define B_SATA_MEM_AHCI_PXFBU               0xFFFFFFFF
+#define R_SATA_MEM_AHCI_P0IS                0x110
+#define R_SATA_MEM_AHCI_P1IS                0x190
+#define R_SATA_MEM_AHCI_P2IS                0x210
+#define R_SATA_MEM_AHCI_P3IS                0x290
+#define R_SATA_MEM_AHCI_P4IS                0x310
+#define R_SATA_MEM_AHCI_P5IS                0x390
+#define R_SATA_MEM_AHCI_P6IS                0x410
+#define R_SATA_MEM_AHCI_P7IS                0x490
+#define B_SATA_MEM_AHCI_PXIS_CPDS           BIT31
+#define B_SATA_MEM_AHCI_PXIS_TFES           BIT30
+#define B_SATA_MEM_AHCI_PXIS_HBFS           BIT29
+#define B_SATA_MEM_AHCI_PXIS_HBDS           BIT28
+#define B_SATA_MEM_AHCI_PXIS_IFS            BIT27
+#define B_SATA_MEM_AHCI_PXIS_INFS           BIT26
+#define B_SATA_MEM_AHCI_PXIS_OFS            BIT24
+#define B_SATA_MEM_AHCI_PXIS_IPMS           BIT23
+#define B_SATA_MEM_AHCI_PXIS_PRCS           BIT22
+#define B_SATA_MEM_AHCI_PXIS_DIS            BIT7
+#define B_SATA_MEM_AHCI_PXIS_PCS            BIT6
+#define B_SATA_MEM_AHCI_PXIS_DPS            BIT5
+#define B_SATA_MEM_AHCI_PXIS_UFS            BIT4
+#define B_SATA_MEM_AHCI_PXIS_SDBS           BIT3
+#define B_SATA_MEM_AHCI_PXIS_DSS            BIT2
+#define B_SATA_MEM_AHCI_PXIS_PSS            BIT1
+#define B_SATA_MEM_AHCI_PXIS_DHRS           BIT0
+#define R_SATA_MEM_AHCI_P0IE                0x114
+#define R_SATA_MEM_AHCI_P1IE                0x194
+#define R_SATA_MEM_AHCI_P2IE                0x214
+#define R_SATA_MEM_AHCI_P3IE                0x294
+#define R_SATA_MEM_AHCI_P4IE                0x314
+#define R_SATA_MEM_AHCI_P5IE                0x394
+#define R_SATA_MEM_AHCI_P6IE                0x414
+#define R_SATA_MEM_AHCI_P7IE                0x494
+#define B_SATA_MEM_AHCI_PXIE_CPDE           BIT31
+#define B_SATA_MEM_AHCI_PXIE_TFEE           BIT30
+#define B_SATA_MEM_AHCI_PXIE_HBFE           BIT29
+#define B_SATA_MEM_AHCI_PXIE_HBDE           BIT28
+#define B_SATA_MEM_AHCI_PXIE_IFE            BIT27
+#define B_SATA_MEM_AHCI_PXIE_INFE           BIT26
+#define B_SATA_MEM_AHCI_PXIE_OFE            BIT24
+#define B_SATA_MEM_AHCI_PXIE_IPME           BIT23
+#define B_SATA_MEM_AHCI_PXIE_PRCE           BIT22
+#define B_SATA_MEM_AHCI_PXIE_DIE            BIT7
+#define B_SATA_MEM_AHCI_PXIE_PCE            BIT6
+#define B_SATA_MEM_AHCI_PXIE_DPE            BIT5
+#define B_SATA_MEM_AHCI_PXIE_UFIE           BIT4
+#define B_SATA_MEM_AHCI_PXIE_SDBE           BIT3
+#define B_SATA_MEM_AHCI_PXIE_DSE            BIT2
+#define B_SATA_MEM_AHCI_PXIE_PSE            BIT1
+#define B_SATA_MEM_AHCI_PXIE_DHRE           BIT0
+#define R_SATA_MEM_AHCI_P0CMD               0x118
+#define R_SATA_MEM_AHCI_P1CMD               0x198
+#define R_SATA_MEM_AHCI_P2CMD               0x218
+#define R_SATA_MEM_AHCI_P3CMD               0x298
+#define R_SATA_MEM_AHCI_P4CMD               0x318
+#define R_SATA_MEM_AHCI_P5CMD               0x398
+#define R_SATA_MEM_AHCI_P6CMD               0x418
+#define R_SATA_MEM_AHCI_P7CMD               0x498
+#define B_SATA_MEM_AHCI_PxCMD_ESP           BIT21 ///< Used with an external SATA device
+#define B_SATA_MEM_AHCI_PxCMD_MPSP          BIT19 ///< Mechanical Switch Attached to Port
+#define B_SATA_MEM_AHCI_PxCMD_HPCP          BIT18 ///< Hotplug capable
+#define B_SATA_MEM_AHCI_PxCMD_CR            BIT15
+#define B_SATA_MEM_AHCI_PxCMD_FR            BIT14
+#define B_SATA_MEM_AHCI_PxCMD_ISS           BIT13
+#define B_SATA_MEM_AHCI_PxCMD_CCS           0x00001F00
+#define B_SATA_MEM_AHCI_PxCMD_FRE           BIT4
+#define B_SATA_MEM_AHCI_PxCMD_CLO           BIT3
+#define B_SATA_MEM_AHCI_PxCMD_POD           BIT2
+#define B_SATA_MEM_AHCI_PxCMD_SUD           BIT1
+#define B_SATA_MEM_AHCI_PxCMD_ST            BIT0
+#define R_SATA_MEM_AHCI_P0TFD               0x120
+#define R_SATA_MEM_AHCI_P1TFD               0x1A0
+#define R_SATA_MEM_AHCI_P2TFD               0x220
+#define R_SATA_MEM_AHCI_P3TFD               0x2A0
+#define R_SATA_MEM_AHCI_P4TFD               0x320
+#define R_SATA_MEM_AHCI_P5TFD               0x3A0
+#define R_SATA_MEM_AHCI_P6TFD               0x420
+#define B_SATA_MEM_AHCI_PXTFD_ERR           0x0000FF00
+#define B_SATA_MEM_AHCI_PXTFD_STS           0x000000FF
+#define R_SATA_MEM_AHCI_P0SIG               0x124
+#define R_SATA_MEM_AHCI_P1SIG               0x1A4
+#define R_SATA_MEM_AHCI_P2SIG               0x224
+#define R_SATA_MEM_AHCI_P3SIG               0x2A4
+#define R_SATA_MEM_AHCI_P4SIG               0x324
+#define R_SATA_MEM_AHCI_P5SIG               0x3A4
+#define R_SATA_MEM_AHCI_P6SIG               0x424
+#define B_SATA_MEM_AHCI_PXSIG_LBA_HR        0xFF000000
+#define B_SATA_MEM_AHCI_PXSIG_LBA_MR        0x00FF0000
+#define B_SATA_MEM_AHCI_PXSIG_LBA_LR        0x0000FF00
+#define B_SATA_MEM_AHCI_PXSIG_SCR           0x000000FF
+#define R_SATA_MEM_AHCI_P0SSTS              0x128
+#define R_SATA_MEM_AHCI_P1SSTS              0x1A8
+#define R_SATA_MEM_AHCI_P2SSTS              0x228
+#define R_SATA_MEM_AHCI_P3SSTS              0x2A8
+#define R_SATA_MEM_AHCI_P4SSTS              0x328
+#define R_SATA_MEM_AHCI_P5SSTS              0x3A8
+#define R_SATA_MEM_AHCI_P6SSTS              0x428
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_0        0x00000000
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_1        0x00000100
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_2        0x00000200
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_6        0x00000600
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_0        0x00000000
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_1        0x00000010
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_2        0x00000020
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_3        0x00000030
+#define B_SATA_MEM_AHCI_PXSSTS_DET_0        0x00000000
+#define B_SATA_MEM_AHCI_PXSSTS_DET_1        0x00000001
+#define B_SATA_MEM_AHCI_PXSSTS_DET_3        0x00000003
+#define B_SATA_MEM_AHCI_PXSSTS_DET_4        0x00000004
+#define R_SATA_MEM_AHCI_P0SCTL              0x12C
+#define R_SATA_MEM_AHCI_P1SCTL              0x1AC
+#define R_SATA_MEM_AHCI_P2SCTL              0x22C
+#define R_SATA_MEM_AHCI_P3SCTL              0x2AC
+#define R_SATA_MEM_AHCI_P4SCTL              0x32C
+#define R_SATA_MEM_AHCI_P5SCTL              0x3AC
+#define R_SATA_MEM_AHCI_P6SCTL              0x42C
+#define B_SATA_MEM_AHCI_PXSCTL_IPM          0x00000F00
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_0        0x00000000
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_1        0x00000100
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_2        0x00000200
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_3        0x00000300
+#define B_SATA_MEM_AHCI_PXSCTL_SPD          0x000000F0
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_0        0x00000000
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_1        0x00000010
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_2        0x00000020
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_3        0x00000030
+#define B_SATA_MEM_AHCI_PXSCTL_DET          0x0000000F
+#define V_SATA_MEM_AHCI_PXSCTL_DET_0        0x00000000
+#define V_SATA_MEM_AHCI_PXSCTL_DET_1        0x00000001
+#define V_SATA_MEM_AHCI_PXSCTL_DET_4        0x00000004
+#define R_SATA_MEM_AHCI_P0SERR              0x130
+#define R_SATA_MEM_AHCI_P1SERR              0x1B0
+#define R_SATA_MEM_AHCI_P2SERR              0x230
+#define R_SATA_MEM_AHCI_P3SERR              0x2B0
+#define R_SATA_MEM_AHCI_P4SERR              0x330
+#define R_SATA_MEM_AHCI_P5SERR              0x3B0
+#define R_SATA_MEM_AHCI_P6SERR              0x430
+#define B_SATA_MEM_AHCI_PXSERR_EXCHG        BIT26
+#define B_SATA_MEM_AHCI_PXSERR_UN_FIS_TYPE  BIT25
+#define B_SATA_MEM_AHCI_PXSERR_TRSTE_24     BIT24
+#define B_SATA_MEM_AHCI_PXSERR_TRSTE_23     BIT23
+#define B_SATA_MEM_AHCI_PXSERR_HANDSHAKE    BIT22
+#define B_SATA_MEM_AHCI_PXSERR_CRC_ERROR    BIT21
+#define B_SATA_MEM_AHCI_PXSERR_10B8B_DECERR BIT19
+#define B_SATA_MEM_AHCI_PXSERR_COMM_WAKE    BIT18
+#define B_SATA_MEM_AHCI_PXSERR_PHY_ERROR    BIT17
+#define B_SATA_MEM_AHCI_PXSERR_PHY_RDY_CHG  BIT16
+#define B_SATA_MEM_AHCI_PXSERR_INTRNAL_ERR  BIT11
+#define B_SATA_MEM_AHCI_PXSERR_PROTOCOL_ERR BIT10
+#define B_SATA_MEM_AHCI_PXSERR_PCDIE        BIT9
+#define B_SATA_MEM_AHCI_PXSERR_TDIE         BIT8
+#define B_SATA_MEM_AHCI_PXSERR_RCE          BIT1
+#define B_SATA_MEM_AHCI_PXSERR_RDIE         BIT0
+#define R_SATA_MEM_AHCI_P0SACT              0x134
+#define R_SATA_MEM_AHCI_P1SACT              0x1B4
+#define R_SATA_MEM_AHCI_P2SACT              0x234
+#define R_SATA_MEM_AHCI_P3SACT              0x2B4
+#define R_SATA_MEM_AHCI_P4SACT              0x334
+#define R_SATA_MEM_AHCI_P5SACT              0x3B4
+#define R_SATA_MEM_AHCI_P6SACT              0x434
+#define B_SATA_MEM_AHCI_PXSACT_DS           0xFFFFFFFF
+#define R_SATA_MEM_AHCI_P0CI                0x138
+#define R_SATA_MEM_AHCI_P1CI                0x1B8
+#define R_SATA_MEM_AHCI_P2CI                0x238
+#define R_SATA_MEM_AHCI_P3CI                0x2B8
+#define R_SATA_MEM_AHCI_P4CI                0x338
+#define R_SATA_MEM_AHCI_P5CI                0x3B8
+#define R_SATA_MEM_AHCI_P6CI                0x438
+#define B_SATA_MEM_AHCI_PXCI                0xFFFFFFFF
+
+//
+//  SATA AHCI Device ID macros
+//
+#define IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_AHCI) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_AHCI) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_OP_AHCI) \
+    )
+
+#define IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_AHCI) \
+    )
+
+#define IS_PCH_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) \
+    )
+
+//
+//  SATA RAID Device ID macros
+//
+#define IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_PREM) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID_PREM) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_RST) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_2) || \
+      (DeviceId == V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_ALTDIS) || \
+      (DeviceId == V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_RSTE) \
+    )
+
+#define IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID) || \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_PREM) || \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_IBC) \
+    )
+
+#define IS_PCH_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
+    )
+
+//
+//  Combined SATA IDE/AHCI/RAID Device ID macros
+//
+#define IS_PCH_H_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) || \
+      IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) \
+    )
+
+#define IS_PCH_LP_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
+    )
+#define IS_PCH_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_DEVICE_ID(DeviceId) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
new file mode 100644
index 0000000000..00e7881408
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
@@ -0,0 +1,52 @@
+/** @file
+  Register names for PCH Storage and Communication Subsystem
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SCS_H_
+#define _PCH_REGS_SCS_H_
+
+//
+// SCS Devices proprietary PCI Config Space Registers
+//
+#define R_SCS_CFG_PCS                     0x84                          ///< PME Control Status
+#define B_SCS_CFG_PCS_PMESTS              BIT15                         ///< PME Status
+#define B_SCS_CFG_PCS_PMEEN               BIT8                          ///< PME Enable
+#define B_SCS_CFG_PCS_NSS                 BIT3                          ///< No Soft Reset
+#define B_SCS_CFG_PCS_PS                  (BIT1 | BIT0)                 ///< Power State
+#define B_SCS_CFG_PCS_PS_D3HOT            (BIT1 | BIT0)                 ///< Power State: D3Hot State
+#define R_SCS_CFG_PG_CONFIG               0xA2                          ///< PG Config
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
new file mode 100644
index 0000000000..c18e1ef38c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
@@ -0,0 +1,48 @@
+/** @file
+  Project specific SCS register definitions.
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SCS_CNL_H_
+#define _PCH_REGS_SCS_CNL_H_
+
+//
+//  SCS SDCARD Controller PCI config
+//
+#define PCI_DEVICE_NUMBER_PCH_CNL_SCS_SDCARD      20
+#define PCI_FUNCTION_NUMBER_PCH_CNL_SCS_SDCARD    5
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
new file mode 100644
index 0000000000..449335b073
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
@@ -0,0 +1,232 @@
+/** @file
+  Register names for PCH 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SERIAL_IO_
+#define _PCH_REGS_SERIAL_IO_
+
+//
+// Serial IO Controllers General PCI Configuration Registers
+// registers accessed using PciD21FxRegBase + offset
+//
+#define R_SERIAL_IO_CFG_BAR0_LOW                        0x10
+#define B_SERIAL_IO_CFG_BAR0_LOW_BAR                    0xFFFFF000
+#define R_SERIAL_IO_CFG_BAR0_HIGH                       0x14
+#define R_SERIAL_IO_CFG_BAR1_LOW                        0x18
+#define B_SERIAL_IO_CFG_BAR1_LOW_BAR                    0xFFFFF000
+#define R_SERIAL_IO_CFG_BAR1_HIGH                       0x1C
+#define V_SERIAL_IO_CFG_BAR_SIZE                        (4 * 1024)
+#define N_SERIAL_IO_CFG_BAR_ALIGNMENT                   12
+
+#define R_SERIAL_IO_CFG_PME_CTRL_STS                    0x84
+#define B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST             (BIT1| BIT0)
+
+#define R_SERIAL_IO_CFG_D0I3MAXDEVPG                    0xA0
+#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_PMCRE              BIT16
+#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_I3E                BIT17
+#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_PGE                BIT18
+
+#define R_SERIAL_IO_CFG_INTERRUPTREG                    0x3C
+#define B_SERIAL_IO_CFG_INTERRUPTREG_INTLINE            0x000000FF
+
+//
+// Serial IO Controllers MMIO Registers
+// registers accessed : BAR0 + offset
+//
+#define R_SERIAL_IO_MEM_SSCR1                           0x4
+#define B_SERIAL_IO_MEM_SSCR1_IFS                       BIT16
+
+#define R_SERIAL_IO_MEM_PPR_CLK                         0x200
+#define B_SERIAL_IO_MEM_PPR_CLK_EN                      BIT0
+#define B_SERIAL_IO_MEM_PPR_CLK_UPDATE                  BIT31
+#define V_SERIAL_IO_MEM_PPR_CLK_M_DIV                   0x30
+#define V_SERIAL_IO_MEM_PPR_CLK_N_DIV                   0xC35
+
+#define R_SERIAL_IO_MEM_PPR_RESETS                      0x204
+#define B_SERIAL_IO_MEM_PPR_RESETS_FUNC                 BIT0
+#define B_SERIAL_IO_MEM_PPR_RESETS_APB                  BIT1
+#define B_SERIAL_IO_MEM_PPR_RESETS_IDMA                 BIT2
+
+#define R_SERIAL_IO_MEM_ACTIVE_LTR                      0x210
+#define R_SERIAL_IO_MEM_IDLE_LTR                        0x214
+#define B_SERIAL_IO_MEM_LTR_SNOOP_VALUE                 0x000003FF
+#define B_SERIAL_IO_MEM_LTR_SNOOP_SCALE                 0x00001C00
+#define B_SERIAL_IO_MEM_LTR_SNOOP_REQUIREMENT           BIT15
+
+#define R_SERIAL_IO_MEM_SPI_CS_CONTROL                  0x224
+#define B_SERIAL_IO_MEM_SPI_CS_CONTROL_STATE            BIT1
+#define B_SERIAL_IO_MEM_SPI_CS_CONTROL_MODE             BIT0
+
+#define R_SERIAL_IO_MEM_REMAP_ADR_LOW                   0x240
+#define R_SERIAL_IO_MEM_REMAP_ADR_HIGH                  0x244
+
+#define R_SERIAL_IO_MEM_I2C_SDA_HOLD                    0x7C
+#define V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE              0x002C002C
+
+//
+// I2C Controller
+// Registers accessed through BAR0 + offset
+//
+#define    R_IC_CON                            0x00 // I2c Control
+#define    B_IC_MASTER_MODE                    BIT0
+#define    B_IC_RESTART_EN                     BIT5
+#define    B_IC_SLAVE_DISABLE                  BIT6
+#define    V_IC_SPEED_STANDARD                 0x02
+#define    V_IC_SPEED_FAST                     0x04
+#define    V_IC_SPEED_HIGH                     0x06
+
+#define    R_IC_TAR                            0x04 // I2c Target Address
+#define    B_IC_TAR_10BITADDR_MASTER           BIT12
+
+#define    R_IC_DATA_CMD                       0x10  // I2c Rx/Tx Data Buffer and Command
+#define    B_IC_CMD_READ                       BIT8    // 1 = read, 0 = write
+#define    B_IC_CMD_STOP                       BIT9    // 1 = STOP
+#define    B_IC_CMD_RESTART                    BIT10   // 1 = IC_RESTART_EN
+#define    V_IC_WRITE_CMD_MASK                 0xFF
+
+#define    R_IC_SS_SCL_HCNT                    0x14 // Standard Speed I2c Clock SCL High Count
+#define    R_IC_SS_SCL_LCNT                    0x18 // Standard Speed I2c Clock SCL Low Count
+#define    R_IC_FS_SCL_HCNT                    0x1C // Full Speed I2c Clock SCL High Count
+#define    R_IC_FS_SCL_LCNT                    0x20 // Full Speed I2c Clock SCL Low Count
+#define    R_IC_HS_SCL_HCNT                    0x24 // High Speed I2c Clock SCL High Count
+#define    R_IC_HS_SCL_LCNT                    0x28 // High Speed I2c Clock SCL Low Count
+#define    R_IC_INTR_STAT                      0x2C // I2c Inetrrupt Status
+#define    R_IC_INTR_MASK                      0x30 // I2c Interrupt Mask
+#define    B_IC_INTR_GEN_CALL                  BIT11  // General call received
+#define    B_IC_INTR_START_DET                 BIT10
+#define    B_IC_INTR_STOP_DET                  BIT9
+#define    B_IC_INTR_ACTIVITY                  BIT8
+#define    B_IC_INTR_TX_ABRT                   BIT6   // Set on NACK
+#define    B_IC_INTR_TX_EMPTY                  BIT4
+#define    B_IC_INTR_TX_OVER                   BIT3
+#define    B_IC_INTR_RX_FULL                   BIT2   // Data bytes in RX FIFO over threshold
+#define    B_IC_INTR_RX_OVER                   BIT1
+#define    B_IC_INTR_RX_UNDER                  BIT0
+#define    R_IC_RAW_INTR_STAT                ( 0x34) // I2c Raw Interrupt Status
+#define    R_IC_RX_TL                        ( 0x38) // I2c Receive FIFO Threshold
+#define    R_IC_TX_TL                        ( 0x3C) // I2c Transmit FIFO Threshold
+#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual Interrupts
+#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER Interrupt
+#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
+#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
+#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
+#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
+#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
+#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
+#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
+#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET interrupt
+#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
+#define    R_IC_ENABLE                       ( 0x6C) // I2c Enable
+
+#define    R_IC_STATUS                         0x70  // I2c Status
+#define    B_IC_STATUS_RFF                     BIT4   // RX FIFO is completely full
+#define    B_IC_STATUS_RFNE                    BIT3   // RX FIFO is not empty
+#define    B_IC_STATUS_TFE                     BIT2   // TX FIFO is completely empty
+#define    B_IC_STATUS_TFNF                    BIT1   // TX FIFO is not full
+#define    B_IC_STATUS_ACTIVITY                BIT0   // Controller Activity Status.
+
+#define    R_IC_TXFL R                       ( 0x74) // Transmit FIFO Level Register
+#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
+#define    R_IC_SDA_HOLD                     ( 0x7C)
+#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2c Transmit Abort Status Register
+#define    B_IC_TX_ABRT_7B_ADDR_NACK          BIT0 // NACK on 7-bit address
+
+#define    R_IC_SDA_SETUP                    ( 0x94) // I2c SDA Setup Register
+#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2c ACK General Call Register
+#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2c Enable Status Register
+#define    B_IC_EN                            BIT0   // I2c enable status
+
+#define    R_IC_CLK_GATE                     ( 0xC0)
+#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter Register
+#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
+#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
+
+//
+// Bridge Private Configuration Registers
+// accessed only through SB messaging. SB access = SerialIo IOSF2OCP Bridge Port ID + offset
+//
+#define R_SERIAL_IO_PCR_PMCTL                        0x1D0
+#define V_SERIAL_IO_PCR_PMCTL_PWR_GATING             0x3F
+
+#define R_SERIAL_IO_PCR_PCICFGCTRLx                 0x200
+#define V_SERIAL_IO_PCR_PCICFGCTRL_N_OFFS           0x04
+#define R_SERIAL_IO_PCR_PCICFGCTRL1                 0x200 //I2C0
+#define R_SERIAL_IO_PCR_PCICFGCTRL2                 0x204 //I2C1
+#define R_SERIAL_IO_PCR_PCICFGCTRL3                 0x208 //I2C2
+#define R_SERIAL_IO_PCR_PCICFGCTRL4                 0x20C //I2C3
+#define R_SERIAL_IO_PCR_PCICFGCTRL5                 0x210 //I2C4
+#define R_SERIAL_IO_PCR_PCICFGCTRL6                 0x214 //I2C5
+#define R_SERIAL_IO_PCR_PCICFGCTRL9                 0x218 //UA00
+#define R_SERIAL_IO_PCR_PCICFGCTRL10                0x21C //UA01
+#define R_SERIAL_IO_PCR_PCICFGCTRL11                0x220 //UA02
+#define R_SERIAL_IO_PCR_PCICFGCTRL13                0x224 //SPI0
+#define R_SERIAL_IO_PCR_PCICFGCTRL14                0x228 //SPI1
+
+#define B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS      BIT0
+#define B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN     BIT1
+#define B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS         BIT7
+#define B_SERIAL_IO_PCR_PCICFGCTRL_INT_PIN          (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_SERIAL_IO_PCR_PCICFGCTRL_INT_PIN          8
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTA             0x01
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTB             0x02
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTC             0x03
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTD             0x04
+#define B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_IRQ         0x000FF000
+#define N_SERIAL_IO_PCR_PCICFGCTRL_ACPI_IRQ         12
+#define B_SERIAL_IO_PCR_PCICFGCTRL_PCI_IRQ          0x0FF00000
+#define N_SERIAL_IO_PCR_PCICFGCTRL_PCI_IRQ          20
+
+#define R_SERIAL_IO_PCR_GPPRVRW2                            0x604
+#define B_SERIAL_IO_PCR_GPPRVRW2_PGCB_FRC_CLK_CP_EN         BIT1
+#define B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CG_EN         BIT5
+#define B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CLKREQ_CTL_EN BIT11
+#define V_SERIAL_IO_PCR_GPPRVRW2_CLK_GATING                 (B_SERIAL_IO_PCR_GPPRVRW2_PGCB_FRC_CLK_CP_EN | B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CG_EN | B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CLKREQ_CTL_EN)
+
+
+#define R_SERIAL_IO_PCR_GPPRVRW7                    0x618
+#define B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN BIT0
+#define B_SERIAL_IO_PCR_GPPRVRW7_UART1_BYTE_ADDR_EN BIT1
+#define B_SERIAL_IO_PCR_GPPRVRW7_UART2_BYTE_ADDR_EN BIT2
+
+//
+// Number of pins used by SerialIo controllers
+//
+#define PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER               2
+#define PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER              4
+#define PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL 2
+#define PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER               4
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
new file mode 100644
index 0000000000..62b859dc99
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
@@ -0,0 +1,138 @@
+/** @file
+  Device IDs for PCH Serial IO Controllers for 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SERIAL_IO_CNL_
+#define _PCH_REGS_SERIAL_IO_CNL_
+
+//
+//  Serial IO I2C0 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0          0
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID       0x9DE8
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID        0xA368
+
+//
+//  Serial IO I2C1 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1          1
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID       0x9DE9
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID        0xA369
+
+//
+//  Serial IO I2C2 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2          2
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID       0x9DEA
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID        0xA36A
+
+//
+//  Serial IO I2C3 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3          3
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID       0x9DEB
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID        0xA36B
+
+//
+//  Serial IO I2C4 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4            25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4          0
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID       0x9DC5
+
+//
+//  Serial IO I2C5 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5            25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5          1
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID       0x9DC6
+
+//
+//  Serial IO SPI0 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0            30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0          2
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID       0x9DAA
+#define V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID        0xA32A
+
+//
+//  Serial IO SPI1 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1            30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1          3
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID       0x9DAB
+#define V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID        0xA32B
+
+//
+//  Serial IO UART0 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0           30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0         0
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID      0x9DA8
+#define V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID       0xA328
+
+//
+//  Serial IO UART1 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1           30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1         1
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID      0x9DA9
+#define V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID       0xA329
+
+//
+//  Serial IO UART2 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2           25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2         2
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID      0x9DC7
+#define V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID       0xA347
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
new file mode 100644
index 0000000000..e571a6a127
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
@@ -0,0 +1,151 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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 (D31:F4)
+//
+#define PCI_DEVICE_NUMBER_PCH_SMBUS           31
+#define PCI_FUNCTION_NUMBER_PCH_SMBUS         4
+#define R_SMBUS_CFG_BASE                      0x20
+#define V_SMBUS_CFG_BASE_SIZE                 (1 << 5)
+#define B_SMBUS_CFG_BASE_BAR                  0x0000FFE0
+#define R_SMBUS_CFG_HOSTC                     0x40
+#define B_SMBUS_CFG_HOSTC_SPDWD               BIT4
+#define B_SMBUS_CFG_HOSTC_SSRESET             BIT3
+#define B_SMBUS_CFG_HOSTC_I2C_EN              BIT2
+#define B_SMBUS_CFG_HOSTC_SMI_EN              BIT1
+#define B_SMBUS_CFG_HOSTC_HST_EN              BIT0
+#define R_SMBUS_CFG_TCOBASE                   0x50
+#define B_SMBUS_CFG_TCOBASE_BAR               0x0000FFE0
+#define R_SMBUS_CFG_TCOCTL                    0x54
+#define B_SMBUS_CFG_TCOCTL_TCO_BASE_EN        BIT8
+#define B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK      BIT0
+#define R_SMBUS_CFG_64                        0x64
+#define R_SMBUS_CFG_80                        0x80
+
+//
+// SMBus I/O Registers
+//
+#define R_SMBUS_IO_HSTS                  0x00  ///< Host Status Register R/W
+#define B_SMBUS_IO_HBSY                  0x01
+#define B_SMBUS_IO_INTR                  0x02
+#define B_SMBUS_IO_DERR                  0x04
+#define B_SMBUS_IO_BERR                  0x08
+#define B_SMBUS_IO_FAIL                  0x10
+#define B_SMBUS_IO_SMBALERT_STS          0x20
+#define B_SMBUS_IO_IUS                   0x40
+#define B_SMBUS_IO_BYTE_DONE_STS         0x80
+#define B_SMBUS_IO_ERROR                 (B_SMBUS_IO_DERR | B_SMBUS_IO_BERR | B_SMBUS_IO_FAIL)
+#define B_SMBUS_IO_HSTS_ALL              0xFF
+#define R_SMBUS_IO_HCTL                  0x02  ///< Host Control Register R/W
+#define B_SMBUS_IO_INTREN                0x01
+#define B_SMBUS_IO_KILL                  0x02
+#define B_SMBUS_IO_SMB_CMD               0x1C
+#define V_SMBUS_IO_SMB_CMD_QUICK         0x00
+#define V_SMBUS_IO_SMB_CMD_BYTE          0x04
+#define V_SMBUS_IO_SMB_CMD_BYTE_DATA     0x08
+#define V_SMBUS_IO_SMB_CMD_WORD_DATA     0x0C
+#define V_SMBUS_IO_SMB_CMD_PROCESS_CALL  0x10
+#define V_SMBUS_IO_SMB_CMD_BLOCK         0x14
+#define V_SMBUS_IO_SMB_CMD_IIC_READ      0x18
+#define V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS 0x1C
+#define B_SMBUS_IO_LAST_BYTE             0x20
+#define B_SMBUS_IO_START                 0x40
+#define B_SMBUS_IO_PEC_EN                0x80
+#define R_SMBUS_IO_HCMD                  0x03  ///< Host Command Register R/W
+#define R_SMBUS_IO_TSA                   0x04  ///< Transmit Slave Address Register R/W
+#define B_SMBUS_IO_RW_SEL                0x01
+#define B_SMBUS_IO_READ                  0x01  // RW
+#define B_SMBUS_IO_WRITE                 0x00  // RW
+#define B_SMBUS_IO_ADDRESS               0xFE
+#define R_SMBUS_IO_HD0                   0x05  ///< Data 0 Register R/W
+#define R_SMBUS_IO_HD1                   0x06  ///< Data 1 Register R/W
+#define R_SMBUS_IO_HBD                   0x07  ///< Host Block Data Register R/W
+#define R_SMBUS_IO_PEC                   0x08  ///< Packet Error Check Data Register R/W
+#define R_SMBUS_IO_RSA                   0x09  ///< Receive Slave Address Register R/W
+#define B_SMBUS_IO_SLAVE_ADDR            0x7F
+#define R_SMBUS_IO_SD                    0x0A  ///< Receive Slave Data Register R/W
+#define R_SMBUS_IO_AUXS                  0x0C  ///< Auxiliary Status Register R/WC
+#define B_SMBUS_IO_CRCE                  0x01
+#define B_SMBUS_IO_STCO                  0x02  ///< SMBus TCO Mode
+#define R_SMBUS_IO_AUXC                  0x0D  ///< Auxiliary Control Register R/W
+#define B_SMBUS_IO_AAC                   0x01
+#define B_SMBUS_IO_E32B                  0x02
+#define R_SMBUS_IO_SMLC                  0x0E  ///< SMLINK Pin Control Register R/W
+#define B_SMBUS_IO_SMLINK0_CUR_STS       0x01
+#define B_SMBUS_IO_SMLINK1_CUR_STS       0x02
+#define B_SMBUS_IO_SMLINK_CLK_CTL        0x04
+#define R_SMBUS_IO_SMBC                  0x0F  ///< SMBus Pin Control Register R/W
+#define B_SMBUS_IO_SMBCLK_CUR_STS        0x01
+#define B_SMBUS_IO_SMBDATA_CUR_STS       0x02
+#define B_SMBUS_IO_SMBCLK_CTL            0x04
+#define R_SMBUS_IO_SSTS                  0x10  ///< Slave Status Register R/WC
+#define B_SMBUS_IO_HOST_NOTIFY_STS       0x01
+#define R_SMBUS_IO_SCMD                  0x11  ///< Slave Command Register R/W
+#define B_SMBUS_IO_HOST_NOTIFY_INTREN    0x01
+#define B_SMBUS_IO_HOST_NOTIFY_WKEN      0x02
+#define B_SMBUS_IO_SMBALERT_DIS          0x04
+#define R_SMBUS_IO_NDA                   0x14  ///< Notify Device Address Register RO
+#define B_SMBUS_IO_DEVICE_ADDRESS        0xFE
+#define R_SMBUS_IO_NDLB                  0x16  ///< Notify Data Low Byte Register RO
+#define R_SMBUS_IO_NDHB                  0x17  ///< Notify Data High Byte Register RO
+
+//
+// SMBus Private Config Registers
+// (PID:SMB)
+//
+#define R_SMBUS_PCR_TCOCFG                0x00                        ///< TCO Configuration register
+#define B_SMBUS_PCR_TCOCFG_IE             BIT7                        ///< TCO IRQ Enable
+#define B_SMBUS_PCR_TCOCFG_IS             (BIT2 | BIT1 | BIT0)        ///< TCO IRQ Select
+#define V_SMBUS_PCR_TCOCFG_IRQ_9          0x00
+#define V_SMBUS_PCR_TCOCFG_IRQ_10         0x01
+#define V_SMBUS_PCR_TCOCFG_IRQ_11         0x02
+#define V_SMBUS_PCR_TCOCFG_IRQ_20         0x04                        ///< only if APIC enabled
+#define V_SMBUS_PCR_TCOCFG_IRQ_21         0x05                        ///< only if APIC enabled
+#define V_SMBUS_PCR_TCOCFG_IRQ_22         0x06                        ///< only if APIC enabled
+#define V_SMBUS_PCR_TCOCFG_IRQ_23         0x07                        ///< only if APIC enabled
+#define R_SMBUS_PCR_SMBTM                 0x04                        ///< SMBus Test Mode
+#define B_SMBUS_PCR_SMBTM_SMBCT           BIT1                        ///< SMBus Counter
+#define B_SMBUS_PCR_SMBTM_SMBDG           BIT0                        ///< SMBus Deglitch
+#define R_SMBUS_PCR_SCTM                  0x08                        ///< Short Counter Test Mode
+#define B_SMBUS_PCR_SCTM_SSU              BIT31                       ///< Simulation Speed-Up
+#define R_SMBUS_PCR_GC                    0x0C                        ///< General Control
+#define B_SMBUS_PCR_GC_FD                 BIT0                        ///< Function Disable
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
new file mode 100644
index 0000000000..013603ca25
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
@@ -0,0 +1,295 @@
+/** @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
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SPI_H_
+#define _PCH_REGS_SPI_H_
+
+//
+// SPI Registers (D31:F5)
+//
+
+#define PCI_DEVICE_NUMBER_PCH_SPI           31
+#define PCI_FUNCTION_NUMBER_PCH_SPI         5
+
+#define R_SPI_CFG_BAR0                      0x10
+#define B_SPI_CFG_BAR0_MASK                 0x0FFF
+
+#define R_SPI_CFG_BDE                       0xD8
+#define B_SPI_CFG_BDE_F8                    0x8000
+#define B_SPI_CFG_BDE_F0                    0x4000
+#define B_SPI_CFG_BDE_E8                    0x2000
+#define B_SPI_CFG_BDE_E0                    0x1000
+#define B_SPI_CFG_BDE_D8                    0x0800
+#define B_SPI_CFG_BDE_D0                    0x0400
+#define B_SPI_CFG_BDE_C8                    0x0200
+#define B_SPI_CFG_BDE_C0                    0x0100
+#define B_SPI_CFG_BDE_LEG_F                 0x0080
+#define B_SPI_CFG_BDE_LEG_E                 0x0040
+#define B_SPI_CFG_BDE_70                    0x0008
+#define B_SPI_CFG_BDE_60                    0x0004
+#define B_SPI_CFG_BDE_50                    0x0002
+#define B_SPI_CFG_BDE_40                    0x0001
+
+#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 B_SPI_CFG_BC_OSFH                   BIT9            ///< OS Function Hide
+#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 V_SPI_CFG_BC_BBS_LPC                1               ///< Boot BIOS strapped to LPC
+#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_EN_CACHE_EN   0x02            ///< Prefetching and Caching enabled
+#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS 0x01            ///< No prefetching and no caching
+#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_EN  0x00            ///< No prefetching, but caching enabled
+#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_BFPR                      0x00                          ///< BIOS Flash Primary Region Register(32bits), which is RO and contains the same value from FREG1
+#define B_SPI_MEM_BFPR_PRL                  0x7FFF0000                    ///< BIOS Flash Primary Region Limit mask
+#define N_SPI_MEM_BFPR_PRL                  16                            ///< BIOS Flash Primary Region Limit bit position
+#define B_SPI_MEM_BFPR_PRB                  0x00007FFF                    ///< BIOS Flash Primary Region Base mask
+#define N_SPI_MEM_BFPR_PRB                  0                             ///< BIOS Flash Primary Region Base bit position
+#define R_SPI_MEM_HSFSC                     0x04                          ///< Hardware Sequencing Flash Status and Control Register(32bits)
+#define B_SPI_MEM_HSFSC_FSMIE               BIT31                         ///< Flash SPI SMI# Enable
+#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_PRR34_LOCKDN        BIT12                         ///< PRR3 PRR4 Lock-Down
+#define B_SPI_MEM_HSFSC_WRSDIS              BIT11                         ///< Write Status Disable
+#define B_SPI_MEM_HSFSC_SAF_CE              BIT8                          ///< SAF ctype error
+#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_SAF_LE              BIT6                          ///< SAF link error
+#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_FDATA01                   0x14                          ///< SPI Data 01
+#define R_SPI_MEM_FDATA02                   0x18                          ///< SPI Data 02
+#define R_SPI_MEM_FDATA03                   0x1C                          ///< SPI Data 03
+#define R_SPI_MEM_FDATA04                   0x20                          ///< SPI Data 04
+#define R_SPI_MEM_FDATA05                   0x24                          ///< SPI Data 05
+#define R_SPI_MEM_FDATA06                   0x28                          ///< SPI Data 06
+#define R_SPI_MEM_FDATA07                   0x2C                          ///< SPI Data 07
+#define R_SPI_MEM_FDATA08                   0x30                          ///< SPI Data 08
+#define R_SPI_MEM_FDATA09                   0x34                          ///< SPI Data 09
+#define R_SPI_MEM_FDATA10                   0x38                          ///< SPI Data 10
+#define R_SPI_MEM_FDATA11                   0x3C                          ///< SPI Data 11
+#define R_SPI_MEM_FDATA12                   0x40                          ///< SPI Data 12
+#define R_SPI_MEM_FDATA13                   0x44                          ///< SPI Data 13
+#define R_SPI_MEM_FDATA14                   0x48                          ///< SPI Data 14
+#define R_SPI_MEM_FDATA15                   0x4C                          ///< SPI Data 15
+#define R_SPI_MEM_FRAP                      0x50                          ///< Flash Region Access Permisions 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_FREG1_BIOS                0x58                          ///< Flash Region 1(BIOS)(32bits)
+#define R_SPI_MEM_FREG2_ME                  0x5C                          ///< Flash Region 2(ME)(32bits)
+#define R_SPI_MEM_FREG3_GBE                 0x60                          ///< Flash Region 3(GbE)(32bits)
+#define R_SPI_MEM_FREG4_PLATFORM_DATA       0x64                          ///< Flash Region 4(Platform Data)(32bits)
+#define R_SPI_MEM_FREG5_DER                 0x68                          ///< Flash Region 5(Device Expansion Region)(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 R_SPI_MEM_PR1                       0x88                          ///< Protected Region 1 Register
+#define R_SPI_MEM_PR2                       0x8C                          ///< Protected Region 2 Register
+#define R_SPI_MEM_PR3                       0x90                          ///< Protected Region 3 Register
+#define R_SPI_MEM_PR4                       0x94                          ///< Protected Region 4 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_SFRAP                     0xB0                          ///< Secondary Flash Regions Access Permisions Register
+#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_REGN            0x2000                        ///< Region
+#define V_SPI_MEM_FDOC_FDSS_MSTR            0x3000                        ///< Master
+#define V_SPI_MEM_FDOC_FDSS_PCHS            0x4000                        ///< PCH soft straps
+#define V_SPI_MEM_FDOC_FDSS_SFDP            0x5000                        ///< SFDP Parameter Table
+#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 B_SPI_MEM_SFDPX_VSCCX_EO_4K         BIT28                         ///< 4k Erase valid (EO_4k_valid)
+#define B_SPI_MEM_SFDPX_VSCCX_RPMC          BIT27                         ///< RPMC Supported
+#define B_SPI_MEM_SFDPX_VSCCX_DPD           BIT26                         ///< Deep Powerdown Supported
+#define B_SPI_MEM_SFDPX_VSCCX_SUSRES        BIT25                         ///< Suspend/Resume Supported
+#define B_SPI_MEM_SFDPX_VSCCX_SOFTRES       BIT24                         ///< Soft Reset Supported
+#define B_SPI_MEM_SFDPX_VSCCX_64k_EO_MASK   0x00FF0000                    ///< 64k Erase Opcode (EO_64k)
+#define B_SPI_MEM_SFDPX_VSCCX_4k_EO_MASK    0x0000FF00                    ///< 4k Erase Opcode (EO_4k)
+#define B_SPI_MEM_SFDPX_VSCCX_QER           (BIT7 | BIT6 | BIT5)          ///< Quad Enable Requirements
+#define B_SPI_MEM_SFDPX_VSCCX_WEWS          BIT4                          ///< Write Enable on Write Status
+#define B_SPI_MEM_SFDPX_VSCCX_WSR           BIT3                          ///< Write Status Required
+#define B_SPI_MEM_SFDPX_VSCCX_WG_64B        BIT2                          ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
+#define R_SPI_MEM_SFDP1_VSCC1               0xC8                          ///< Vendor Specific Component Capabilities Register(32 bits)
+#define R_SPI_MEM_PINTX                     0xCC                          ///< Parameter Table Index
+#define N_SPI_MEM_PINTX_SPT                 14
+#define V_SPI_MEM_PINTX_SPT_CPT0            0x0                           ///< Component 0 Property Parameter Table
+#define V_SPI_MEM_PINTX_SPT_CPT1            0x1                           ///< Component 1 Property Parameter Table
+#define N_SPI_MEM_PINTX_HORD                12
+#define V_SPI_MEM_PINTX_HORD_SFDP           0x0                           ///< SFDP Header
+#define V_SPI_MEM_PINTX_HORD_PT             0x1                           ///< Parameter Table Header
+#define V_SPI_MEM_PINTX_HORD_DATA           0x2                           ///< Data
+#define R_SPI_MEM_PTDATA                    0xD0                          ///< Parameter Table Data
+#define R_SPI_MEM_SBRS                      0xD4                          ///< SPI Bus Requester Status
+
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_SPI_FLASH_FDBAR_FLVALSIG            0x00                          ///< Flash Valid Signature
+#define V_SPI_FLASH_FDBAR_FLVALSIG            0x0FF0A55A
+#define R_SPI_FLASH_FDBAR_FLASH_MAP0          0x04
+#define B_SPI_FLASH_FDBAR_FCBA                0x000000FF                    ///< Flash Component Base Address
+#define B_SPI_FLASH_FDBAR_NC                  0x00000300                    ///< Number Of Components
+#define N_SPI_FLASH_FDBAR_NC                  8                             ///< Number Of Components
+#define V_SPI_FLASH_FDBAR_NC_1                0x00000000
+#define V_SPI_FLASH_FDBAR_NC_2                0x00000100
+#define B_SPI_FLASH_FDBAR_FRBA                0x00FF0000                    ///< Flash Region Base Address
+#define B_SPI_FLASH_FDBAR_NR                  0x07000000                    ///< Number Of Regions
+#define R_SPI_FLASH_FDBAR_FLASH_MAP1          0x08
+#define B_SPI_FLASH_FDBAR_FMBA                0x000000FF                    ///< Flash Master Base Address
+#define B_SPI_FLASH_FDBAR_NM                  0x00000700                    ///< Number Of Masters
+#define B_SPI_FLASH_FDBAR_FPSBA               0x00FF0000                    ///< PCH Strap Base Address, [23:16] represents [11:4]
+#define N_SPI_FLASH_FDBAR_FPSBA               16                            ///< PCH Strap base Address bit position
+#define N_SPI_FLASH_FDBAR_FPSBA_REPR          4                             ///< PCH Strap base Address bit represents position
+#define B_SPI_FLASH_FDBAR_PCHSL               0xFF000000                    ///< PCH Strap Length, [31:24] represents number of Dwords
+#define N_SPI_FLASH_FDBAR_PCHSL               24                            ///< PCH Strap Length bit position
+#define R_SPI_FLASH_FDBAR_FLASH_MAP2          0x0C
+#define B_SPI_FLASH_FDBAR_FCPUSBA             0x000000FF                    ///< CPU Strap Base Address, [7:0] represents [11:4]
+#define N_SPI_FLASH_FDBAR_FCPUSBA             0                             ///< CPU Strap Base Address bit position
+#define N_SPI_FLASH_FDBAR_FCPUSBA_REPR        4                             ///< CPU Strap Base Address bit represents position
+#define B_SPI_FLASH_FDBAR_CPUSL               0x0000FF00                    ///< CPU Strap Length, [15:8] represents number of Dwords
+#define N_SPI_FLASH_FDBAR_CPUSL               8                             ///< CPU Strap Length bit position
+//
+// Flash Component Base Address (FCBA) from Flash Region 0
+//
+#define R_SPI_FLASH_FCBA_FLCOMP               0x00                          ///< Flash Components Register
+#define B_SPI_FLASH_FLCOMP_RIDS_FREQ          (BIT29 | BIT28 | BIT27)       ///< Read ID and Read Status Clock Frequency
+#define B_SPI_FLASH_FLCOMP_WE_FREQ            (BIT26 | BIT25 | BIT24)       ///< Write and Erase Clock Frequency
+#define B_SPI_FLASH_FLCOMP_FRCF_FREQ          (BIT23 | BIT22 | BIT21)       ///< Fast Read Clock Frequency
+#define B_SPI_FLASH_FLCOMP_FR_SUP             BIT20                         ///< Fast Read Support.
+#define B_SPI_FLASH_FLCOMP_RC_FREQ            (BIT19 | BIT18 | BIT17)       ///< Read Clock Frequency.
+#define V_SPI_FLASH_FLCOMP_FREQ_48MHZ         0x02
+#define V_SPI_FLASH_FLCOMP_FREQ_30MHZ         0x04
+#define V_SPI_FLASH_FLCOMP_FREQ_17MHZ         0x06
+#define B_SPI_FLASH_FLCOMP_COMP1_MASK         0xF0                          ///< Flash Component 1 Size MASK
+#define N_SPI_FLASH_FLCOMP_COMP1              4                             ///< Flash Component 1 Size bit position
+#define B_SPI_FLASH_FLCOMP_COMP0_MASK         0x0F                          ///< Flash Component 0 Size MASK
+#define V_SPI_FLASH_FLCOMP_COMP_512KB         0x80000
+//
+// Descriptor Upper Map Section from Flash Region 0
+//
+#define R_SPI_FLASH_UMAP1                     0xEFC                         ///< Flash Upper Map 1
+#define B_SPI_FLASH_UMAP1_VTBA                0x000000FF                    ///< VSCC Table Base Address
+#define B_SPI_FLASH_UMAP1_VTL                 0x0000FF00                    ///< VSCC Table Length
+
+//
+// SPI Private Configuration Space Registers
+//
+#define R_SPI_PCR_CLK_CTL               0xC004
+#define R_SPI_PCR_PWR_CTL               0xC008
+#define R_SPI_PCR_ESPI_SOFTSTRAPS       0xC210
+#define B_SPI_PCR_ESPI_SLAVE            BIT12
+
+//
+// MMP0
+//
+#define R_PCH_SPI_STRP_MMP0                 0xC4    ///< MMP0 Soft strap offset
+#define B_PCH_SPI_STRP_MMP0                 0x10    ///< MMP0 Soft strap bit
+
+
+#define R_PCH_SPI_STRP_SFDP                 0xF0    ///< PCH Soft Strap SFDP
+#define B_PCH_SPI_STRP_SFDP_QIORE           BIT3    ///< Quad IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_QORE            BIT2    ///< Quad Output Read Enable
+#define B_PCH_SPI_STRP_SFDP_DIORE           BIT1    ///< Dual IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_DORE            BIT0    ///< Dual Output Read Enable
+
+//
+// Descriptor Record 0
+//
+#define R_PCH_SPI_STRP_DSCR_0               0x00    ///< PCH Soft Strap 0
+#define B_PCH_SPI_STRP_DSCR_0_PTT_SUPP      BIT22   ///< PTT Supported
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h
new file mode 100644
index 0000000000..fb93a62364
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h
@@ -0,0 +1,49 @@
+/** @file
+  Register names for PCH Thermal 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
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_THERMAL_H_
+#define _PCH_REGS_THERMAL_H_
+
+//
+//  Thermal Device Registers (D18:0)
+//
+#define PCI_DEVICE_NUMBER_PCH_THERMAL   18
+#define PCI_FUNCTION_NUMBER_PCH_THERMAL 0
+#define R_THERMAL_CFG_MEM_TBAR              0x10
+#define B_THERMAL_CFG_MEM_TBAR_MASK         0xFFFFF000
+#define R_THERMAL_CFG_MEM_TBARH             0x14
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
new file mode 100644
index 0000000000..21f9839546
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
@@ -0,0 +1,134 @@
+/** @file
+  Register names for PCH TraceHub 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
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_TRACE_HUB_H_
+#define _PCH_REGS_TRACE_HUB_H_
+
+//
+// TraceHub Registers (D31:F7)
+//
+#define PCI_DEVICE_NUMBER_PCH_TRACE_HUB               31
+#define PCI_FUNCTION_NUMBER_PCH_TRACE_HUB             7
+
+#define R_TRACE_HUB_CFG_CSR_MTB_LBAR                  0x10
+#define B_TRACE_HUB_CFG_CSR_MTB_RBAL                  0xFFF00000
+#define R_TRACE_HUB_CFG_CSR_MTB_UBAR                  0x14
+#define B_TRACE_HUB_CFG_CSR_MTB_RBAU                  0xFFFFFFFF
+#define R_TRACE_HUB_CFG_SW_LBAR                       0x18
+#define R_TRACE_HUB_CFG_SW_UBAR                       0x1C
+#define B_TRACE_HUB_CFG_SW_RBAU                       0xFFFFFFFF
+#define R_TRACE_HUB_CFG_RTIT_LBAR                     0x20
+#define B_TRACE_HUB_CFG_RTIT_RBAL                     0xFFFFFF00
+#define R_TRACE_HUB_CFG_RTIT_UBAR                     0x24
+#define B_TRACE_HUB_CFG_RTIT_RBAU                     0xFFFFFFFF
+#define R_TRACE_HUB_CFG_MSICID                        0x40
+#define R_TRACE_HUB_CFG_MSINCP                        0x41
+#define R_TRACE_HUB_CFG_MSIMC                         0x42
+#define R_TRACE_HUB_CFG_MSILMA                        0x44
+#define R_TRACE_HUB_CFG_MSIUMA                        0x48
+#define R_TRACE_HUB_CFG_MSIMD                         0x4C
+#define B_TRACE_HUB_CFG_FW_RBAU                       0xFFFFFFFF
+#define R_TRACE_HUB_CFG_DSC                           0x80
+#define B_TRACE_HUB_CFG_BYP                           BIT0 //< TraceHub Bypass
+#define R_TRACE_HUB_CFG_DSS                           0x81
+#define R_TRACE_HUB_CFG_ISTOT                         0x84
+#define R_TRACE_HUB_CFG_ICTOT                         0x88
+#define R_TRACE_HUB_CFG_IPAD                          0x8C
+#define R_TRACE_HUB_CFG_DSD                           0x90
+
+//
+// Offsets from CSR_MTB_BAR
+//
+#define R_TRACE_HUB_MEM_MTB_GTHOPT0                   0x00
+#define B_TRACE_HUB_MEM_MTB_GTHOPT0_P0FLUSH           BIT7
+#define B_TRACE_HUB_MEM_MTB_GTHOPT0_P1FLUSH           BIT15
+#define V_TRACE_HUB_MEM_MTB_SWDEST_PTI                0x0A
+#define V_TRACE_HUB_MEM_MTB_SWDEST_MEMEXI             0x08
+#define V_TRACE_HUB_MEM_MTB_SWDEST_DISABLE            0x00
+#define R_TRACE_HUB_MEM_MTB_SWDEST_1                  0x0C
+#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_1              0x0000000F
+#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_2              0x000000F0
+#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_3              0x00000F00
+#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_1              0x0000F000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_2              0x000F0000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_3              0x00F00000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_AUDIO              0x0F000000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_PMC                0xF0000000
+#define R_TRACE_HUB_MEM_MTB_SWDEST_2                  0x10
+#define B_TRACE_HUB_MEM_MTB_SWDEST_FTH                0x0000000F
+#define R_TRACE_HUB_MEM_MTB_SWDEST_3                  0x14
+#define B_TRACE_HUB_MEM_MTB_SWDEST_MAESTRO            0x00000F00
+#define B_TRACE_HUB_MEM_MTB_SWDEST_MIPICAM            0x0F000000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_AET                0xF0000000
+#define R_TRACE_HUB_MEM_MTB_SWDEST_4                  0x18
+#define R_TRACE_HUB_MEM_MTB_MSC0CTL                   0xA0100
+#define R_TRACE_HUB_MEM_MTB_MSC1CTL                   0xA0200
+#define V_TRACE_HUB_MEM_MTB_MSCNMODE_DCI              0x2
+#define V_TRACE_HUB_MEM_MTB_MSCNMODE_DEBUG            0x3
+#define B_TRACE_HUB_MEM_MTB_MSCNLEN                   (BIT10 | BIT9 | BIT8)
+#define B_TRACE_HUB_MEM_MTB_MSCNMODE                  (BIT5 | BIT4)
+#define N_TRACE_HUB_MEM_MTB_MSCNMODE                  0x4
+#define B_TRACE_HUB_MEM_MTB_MSCN_RD_HDR_OVRD          BIT2
+#define B_TRACE_HUB_MEM_MTB_WRAPENN                   BIT1
+#define B_TRACE_HUB_MEM_MTB_MSCNEN                    BIT0
+#define R_TRACE_HUB_MEM_MTB_GTHSTAT                   0xD4
+#define R_TRACE_HUB_MEM_MTB_SCR2                      0xD8
+#define B_TRACE_HUB_MEM_MTB_SCR2_FCD                  BIT0
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF2              BIT2
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF3              BIT3
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF4              BIT4
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF5              BIT5
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF6              BIT6
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF7              BIT7
+#define R_TRACE_HUB_MEM_MTB_MSC0BAR                   0xA0108
+#define R_TRACE_HUB_MEM_MTB_MSC0SIZE                  0xA010C
+#define R_TRACE_HUB_MEM_MTB_MSC1BAR                   0xA0208
+#define R_TRACE_HUB_MEM_MTB_MSC1SIZE                  0xA020C
+#define R_TRACE_HUB_MEM_MTB_STREAMCFG1                0xA1000
+#define R_TRACE_HUB_MEM_MTB_SCR                       0xC8
+#define R_TRACE_HUB_MEM_MTB_GTH_FREQ                  0xCC
+#define V_TRACE_HUB_MEM_MTB_SCR                       0x00130000
+#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0           0xE0
+#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD1           0xE4
+#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD10          0xE40
+#define R_TRACE_HUB_MEM_MTB_CTPGCS                    0x1C14
+#define B_TRACE_HUB_MEM_MTB_CTPEN                     BIT0
+#define V_TRACE_HUB_MEM_MTB_CHLCNT                    0x80
+#define R_TRACE_HUB_MEM_CSR_MTB_TSUCTRL               0x2000
+#define B_TRACE_HUB_MEM_CSR_MTB_TSUCTRL_CTCRESYNC     BIT0
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (7 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
                   ` (28 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds the following header files:
 * Pch/Include/Private

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h     |  16 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h       | 273 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h    | 115 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h            |  92 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h      | 269 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h          |  58 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h |  25 ++
 7 files changed, 848 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
new file mode 100644
index 0000000000..6c9d10e928
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
@@ -0,0 +1,16 @@
+/** @file
+    CnlPchLp Dx HSIO Header File
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CNL_PCH_LP_HSIO_DX_H_
+#define _CNL_PCH_LP_HSIO_DX_H_
+
+#define CNL_PCH_LP_HSIO_VER_DX   0x7
+
+
+extern UINT8                      CnlPchLpChipsetInitTable_Dx[5072];
+extern UINT8                      CnlPchLpChipsetInitTable_eDBC_Dx[4612];
+#endif //_CNL_PCH_LP_HSIO_DX_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
new file mode 100644
index 0000000000..5569da670d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
@@ -0,0 +1,273 @@
+/** @file
+  The GUID definition for PchConfigHob
+
+  Copyright (c) 2019 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 <ConfigBlock/SmbusConfig.h>
+#include <ConfigBlock/InterruptConfig.h>
+#include <ConfigBlock/PcieRpConfig.h>
+#include <ConfigBlock/SataConfig.h>
+#include <ConfigBlock/FlashProtectionConfig.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];
+  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 describes interrupt settings for PCH HOB.
+///
+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
+  UINT8                        PxRcConfig[PCH_MAX_PXRC_CONFIG];                 ///< PCI interrupt routing for 8259 PIC controller
+} INTERRUPT_HOB;
+
+///
+/// The CNVI_HOB block describes CNVi device.
+///
+typedef struct {
+  UINT32 Mode                      :  1;         ///< 0: Disabled, <b>1: Auto</b>
+  UINT32 RsvdBits0                 : 31;
+} CNVI_HOB;
+
+/**
+  The SERIAL_IO block provides the configurations to set the Serial IO controllers
+**/
+typedef struct {
+  /**
+       0: Disabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - Device will be disabled in PSF
+          - !important! If given device is Function 0 and not all other LPSS functions on given device
+                        are disabled, then 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: Pci</b>;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be enabled in PSF
+          - Only Bar 0 will be enabled
+       2: Acpi;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+    @note Intel does not provide Windows SerialIo drivers for this mode
+       3: Hidden;
+          Designated for Kernel Debug and Legacy UART configuartion, might also be used for IO Expander on I2C
+          - Device is placed in D0
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+          - !important! In this mode UART will work in 16550 Legacy 8BIT Mode, it's resources will be assigned to mother board through ACPI (PNP0C02)
+    @note Considering the PcdSerialIoUartDebugEnable and PcdSerialIoUartNumber for all SerialIo UARTx,
+          the PCD is more meaningful to represent the board design. It means, if PcdSerialIoUartDebugEnable is not 0,
+          the board is designed to use the SerialIo UART for debug message and the PcdSerialIoUartNumber is dedicated
+          to be Debug UART usage. Therefore, it should grayout the option from setup menu since no other options
+          available for this UART controller on this board, and also override the policy default accordingly.
+          While PcdSerialIoUartDebugEnable is 0, then it's allowed to configure the UART controller by policy.
+  **/
+  UINT8  DevMode[PCH_MAX_SERIALIO_CONTROLLERS];
+  UINT32 DebugUartNumber           :  2;                    ///< UART number for debug purpose. 0:UART0, 1: UART1, <b>2:UART2</b>
+  UINT32 EnableDebugUartAfterPost  :  1;                    ///< Enable debug UART controller after post. 0: disabled, <b>1: enabled</b>
+  UINT32 RsvdBits0                 : 29;
+} SERIAL_IO_HOB;
+
+
+///
+/// The PCH_PCIE_CONFIG 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];
+  /**
+    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;
+} PCIERP_HOB;
+
+typedef struct {
+  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1: Enable</b>
+  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  RsvdBits0             : 26;    ///< Reserved bits
+} HDAUDIO_HOB;
+
+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];
+  /**
+    This member describes the details of implementation of Intel RST for PCIe Storage remapping (Intel RST Driver is required)
+  **/
+  PCH_RST_PCIE_STORAGE_CONFIG   RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
+} SATA_HOB;
+
+///
+/// The SCS_HOB block describes Storage and Communication Subsystem (SCS) settings for PCH.
+///
+typedef struct {
+  UINT32  ScsEmmcEnabled                      :  2;  ///< Determine if eMMC is enabled - 0: Disabled, <b>1: Enabled</b>.
+  UINT32  ScsEmmcHs400Enabled                 :  1;  ///< Determine eMMC HS400 Mode if ScsEmmcEnabled - <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  ScsEmmcHs400TuningRequired          :  1;
+  UINT32  ScsEmmcHs400DllDataValid            :  1;  ///< Set if HS400 Tuning Data Valid
+  UINT32  ScsEmmcHs400DriverStrength          :  3;  ///< I/O driver strength: <b>0 - 33 Ohm</b>, 1 - 40 Ohm, 2 - 50 Ohm
+  UINT32  ScsSdPowerEnableActiveHigh          :  1;  ///< Sd PWREN# active high
+  UINT32  ScsSdCardEnabled                    :  1;  ///< Sd card enabled
+  UINT32  RsvdBits                            : 22;
+} SCS_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 RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the upper
+    and lower 128-byte bank of RTC RAM. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  RtcMemoryLock   :  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        : 28;
+} 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                  SlpS0VmRuntimeControl        :  1;     /// < SLP_S0 Voltage Margining Runtime Control. <b>0: Disable</b>; 1: Enable.
+  UINT32                  SlpS0Vm070VSupport           :  1;     /// < SLP_S0 0.70V Voltage Margining Support. <b>0: Disable</b>; 1: Enable.
+  UINT32                  SlpS0Vm075VSupport           :  1;     /// < SLP_S0 0.75V Voltage Margining Support. <b>0: Disable</b>; 1: Enable.
+  UINT32                  PsOnEnable                   :  1;     /// < Indicates if PS_ON support has been enabled, <b>0: Disable</b>; 1: Enable.
+  UINT32                  RsvdBits1                    : 28;
+} PM_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 bytes
+} PCH_TRACEHUB_HOB;
+
+/**
+  PCH eSPI HOB settings.
+**/
+typedef struct {
+  UINT32  BmeMasterSlaveEnabled :  1; // <b>0 = BME disable</b>; 1 = BME enable
+  UINT32  RsvdBits              : 31;
+} PCH_ESPI_HOB;
+
+
+///
+/// Pch Config Hob
+///
+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
+  SCS_HOB            Scs;                ///< Scs HOB definition
+  CNVI_HOB           Cnvi;               ///< Cnvi 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
+  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
+
+} PCH_CONFIG_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
new file mode 100644
index 0000000000..faaff9f497
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
@@ -0,0 +1,115 @@
+/** @file
+  Header file for PchHdaLib Endpoint descriptors.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_ENDPOINTS_H_
+#define _PCH_HDA_ENDPOINTS_H_
+
+#include <Private/Library/DxePchHdaNhlt.h>
+
+typedef enum {
+  HdaDmicX1       = 0,
+  HdaDmicX2,
+  HdaDmicX4,
+  HdaBtRender,
+  HdaBtCapture,
+  HdaI2sRender1,
+  HdaI2sRender2,
+  HdaI2sCapture,
+  HdaEndpointMax
+} NHLT_ENDPOINT;
+
+typedef struct {
+  NHLT_ENDPOINT EndpointType;
+  UINT32        EndpointFormatsBitmask;
+  UINT32        EndpointDevicesBitmask;
+  BOOLEAN       Enable;
+} PCH_HDA_NHLT_ENDPOINTS;
+
+#define PCH_HDA_NHLT_TABLE_SIZE 0x2000
+
+// Format bitmask
+#define B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT                BIT0
+#define B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT                BIT1
+#define B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT                BIT2
+#define B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT                BIT3
+#define B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT                BIT4
+#define B_HDA_BT_NARROWBAND_FORMAT                       BIT5
+#define B_HDA_BT_WIDEBAND_FORMAT                         BIT6
+#define B_HDA_BT_A2DP_FORMAT                             BIT7
+#define B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT   BIT8
+#define B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT  BIT9
+#define V_HDA_FORMAT_MAX                                 10
+
+// Formats
+extern CONST WAVEFORMATEXTENSIBLE Ch1_48kHz16bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz16bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz24bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz32bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch4_48kHz16bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch4_48kHz32bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE NarrowbandFormat;
+extern CONST WAVEFORMATEXTENSIBLE WidebandFormat;
+extern CONST WAVEFORMATEXTENSIBLE A2dpFormat;
+
+// Format Config
+extern CONST UINT32 DmicStereo16BitFormatConfig[];
+extern CONST UINT32 DmicStereo16BitFormatConfigSize;
+extern CONST UINT32 DmicStereo32BitFormatConfig[];
+extern CONST UINT32 DmicStereo32BitFormatConfigSize;
+extern CONST UINT32 DmicQuad16BitFormatConfig[];
+extern CONST UINT32 DmicQuad16BitFormatConfigSize;
+extern CONST UINT32 DmicQuad32BitFormatConfig[];
+extern CONST UINT32 DmicQuad32BitFormatConfigSize;
+extern CONST UINT32 DmicMono16BitFormatConfig[];
+extern CONST UINT32 DmicMono16BitFormatConfigSize;
+
+extern CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfig[];
+extern CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfigSize;
+extern CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfig[];
+extern CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
+extern CONST UINT32 BtFormatConfig[];
+extern CONST UINT32 BtFormatConfigSize;
+
+// Endpoints
+extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX1;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX2;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX4;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointBtRender;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointBtCapture;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointI2sRender;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointI2sCapture;
+
+// Endpoint Config
+extern CONST UINT8  DmicX1Config[];
+extern CONST UINT32 DmicX1ConfigSize;
+extern CONST UINT8  DmicX2Config[];
+extern CONST UINT32 DmicX2ConfigSize;
+extern CONST UINT8  DmicX4Config[];
+extern CONST UINT32 DmicX4ConfigSize;
+extern CONST UINT8  BtConfig[];
+extern CONST UINT32 BtConfigSize;
+extern CONST UINT8  I2sRender1Config[];
+extern CONST UINT32 I2sRender1ConfigSize;
+extern CONST UINT8  I2sRender2Config[];
+extern CONST UINT32 I2sRender2ConfigSize;
+extern CONST UINT8  I2sCaptureConfig[];
+extern CONST UINT32 I2sCaptureConfigSize;
+
+// Device Info bitmask
+#define B_HDA_I2S_RENDER_DEVICE_INFO  BIT0
+#define B_HDA_I2S_CAPTURE_DEVICE_INFO BIT1
+
+// Device Info
+extern CONST DEVICE_INFO I2sRenderDeviceInfo;
+extern CONST DEVICE_INFO I2sCaptureDeviceInfo;
+
+// Oed Configuration
+extern CONST UINT32 NhltConfiguration[];
+extern CONST UINT32 NhltConfigurationSize;
+
+#endif // _PCH_HDA_ENDPOINTS_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
new file mode 100644
index 0000000000..860ed89f0d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
@@ -0,0 +1,92 @@
+/** @file
+  Header file with all common HSIO information
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HSIO_H_
+#define _PCH_HSIO_H_
+
+#define PCH_LANE_OWN_COMMON                      0x10
+#define PCH_LANE_BDCAST                          0x11
+#define PCH_HSIO_LANE_GROUP_NO                   0x09
+#define PCH_HSIO_LANE_GROUP_COMMON_LANE          0x00
+#define PCH_HSIO_LANE_GROUP_PCIE                 0x01
+#define PCH_HSIO_LANE_GROUP_DMI                  0x02
+#define PCH_HSIO_LANE_GROUP_GBE                  0x03
+#define PCH_HSIO_LANE_GROUP_USB3                 0x04
+#define PCH_HSIO_LANE_GROUP_SATA                 0x05
+#define PCH_HSIO_LANE_GROUP_SSIC                 0x06
+
+
+/**
+  PCH HSIO ChipsetInit Version Information
+**/
+typedef struct {
+  UINT16 BaseCrc;
+  UINT16 SusCrc;
+  UINT16 OemCrc;
+  UINT8  Version;
+  UINT8  Product;
+  UINT8  MetalLayer : 4;
+  UINT8  BaseLayer : 4;
+  UINT8  OemVersion;
+  UINT16 DebugMode : 1;
+  UINT16 OemCrcValid : 1;
+  UINT16 SusCrcValid : 1;
+  UINT16 BaseCrcValid : 1;
+  UINT16 Reserved : 12;
+} PCH_HSIO_VER_INFO;
+
+#define PMC_DATA_CMD_SIZE   ((12/sizeof(UINT16))-1)
+#define PMC_DATA_DELAY_CMD_SIZE ((4/sizeof(UINT16))-1)
+
+#define RECORD_OFFSET(X, Y)  ((X << 4) | Y)
+/**
+  PCH HSIO ChipsetInit Command Field
+**/
+typedef struct {
+  UINT8 Command : 3;
+  UINT8 Size : 5;
+  UINT8 Pid;
+  UINT8 OpCode; //PrivateControlWrite
+  UINT8 Bar; //0
+  UINT8 Fbe; //First Byte Enable  : 0x0F
+  UINT8 Fid; //0
+  UINT16 Offset;
+  UINT32 Value;
+} PCH_HSIO_CMD_FIELD;
+
+/**
+PCH HSIO Delay XRAM Data
+**/
+typedef struct {
+  UINT8 Command : 3;
+  UINT8 Size : 5;
+  UINT8 DelayPeriod; //(00h = 1us, 01h = 10us, 02h = 100us, ..., 07h = 10s; others reserved)
+  UINT8 DelayCount; //(0 - 255); total delay = Delay period * Delay count
+  UINT8 Padding;
+} PCH_HSIO_DELAY_CMD_FIELD;
+
+typedef enum {
+  Delay1us = 0x0,
+  Delay10us,
+  Delay100us,
+  Delay1ms,
+  Delay10ms,
+  Delay100ms,
+  Delay1s,
+  Delay10s
+} PCH_HSIO_DELAY;
+
+/**
+PCH PCIE PLL SSC Data
+**/
+#define MAX_PCIE_PLL_SSC_PERCENT  20
+
+#include <Private/CnlPchLpHsioDx.h>
+
+#endif //_PCH_HSIO_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
new file mode 100644
index 0000000000..4617a01c0b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
@@ -0,0 +1,269 @@
+/** @file
+  Copyright (c) 2019 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[24];                           ///< 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
+  UINT64   NHLA;                                    ///< Offset 102     HD-Audio NHLT ACPI address
+  UINT32   NHLL;                                    ///< Offset 110     HD-Audio NHLT ACPI length
+  UINT32   ADFM;                                    ///< Offset 114     HD-Audio DSP Feature Mask
+  UINT8    SWQ0;                                    ///< Offset 118     HD-Audio SoundWire Link #1 quirk mask
+  UINT8    SWQ1;                                    ///< Offset 119     HD-Audio SoundWire Link #2 quirk mask
+  UINT8    SWQ2;                                    ///< Offset 120     HD-Audio SoundWire Link #3 quirk mask
+  UINT8    SWQ3;                                    ///< Offset 121     HD-Audio SoundWire Link #4 quirk mask
+  UINT32   DSPM;                                    ///< Offset 122     HD-Audio DSP Stolen Memory Base Address
+  UINT32   SBRG;                                    ///< Offset 126     SBREG_BAR
+  UINT8    GEI0;                                    ///< Offset 130     GPIO GroupIndex mapped to GPE_DW0
+  UINT8    GEI1;                                    ///< Offset 131     GPIO GroupIndex mapped to GPE_DW1
+  UINT8    GEI2;                                    ///< Offset 132     GPIO GroupIndex mapped to GPE_DW2
+  UINT8    GED0;                                    ///< Offset 133     GPIO DW part of group mapped to GPE_DW0
+  UINT8    GED1;                                    ///< Offset 134     GPIO DW part of group mapped to GPE_DW1
+  UINT8    GED2;                                    ///< Offset 135     GPIO DW part of group mapped to GPE_DW2
+  UINT16   PcieLtrMaxSnoopLatency[24];              ///< Offset 136     PCIE LTR max snoop Latency 1
+                                                    ///< Offset 138     PCIE LTR max snoop Latency 2
+                                                    ///< Offset 140     PCIE LTR max snoop Latency 3
+                                                    ///< Offset 142     PCIE LTR max snoop Latency 4
+                                                    ///< Offset 144     PCIE LTR max snoop Latency 5
+                                                    ///< Offset 146     PCIE LTR max snoop Latency 6
+                                                    ///< Offset 148     PCIE LTR max snoop Latency 7
+                                                    ///< Offset 150     PCIE LTR max snoop Latency 8
+                                                    ///< Offset 152     PCIE LTR max snoop Latency 9
+                                                    ///< Offset 154     PCIE LTR max snoop Latency 10
+                                                    ///< Offset 156     PCIE LTR max snoop Latency 11
+                                                    ///< Offset 158     PCIE LTR max snoop Latency 12
+                                                    ///< Offset 160     PCIE LTR max snoop Latency 13
+                                                    ///< Offset 162     PCIE LTR max snoop Latency 14
+                                                    ///< Offset 164     PCIE LTR max snoop Latency 15
+                                                    ///< Offset 166     PCIE LTR max snoop Latency 16
+                                                    ///< Offset 168     PCIE LTR max snoop Latency 17
+                                                    ///< Offset 170     PCIE LTR max snoop Latency 18
+                                                    ///< Offset 172     PCIE LTR max snoop Latency 19
+                                                    ///< Offset 174     PCIE LTR max snoop Latency 20
+                                                    ///< Offset 176     PCIE LTR max snoop Latency 21
+                                                    ///< Offset 178     PCIE LTR max snoop Latency 22
+                                                    ///< Offset 180     PCIE LTR max snoop Latency 23
+                                                    ///< Offset 182     PCIE LTR max snoop Latency 24
+  UINT16   PcieLtrMaxNoSnoopLatency[24];            ///< Offset 184     PCIE LTR max no snoop Latency 1
+                                                    ///< Offset 186     PCIE LTR max no snoop Latency 2
+                                                    ///< Offset 188     PCIE LTR max no snoop Latency 3
+                                                    ///< Offset 190     PCIE LTR max no snoop Latency 4
+                                                    ///< Offset 192     PCIE LTR max no snoop Latency 5
+                                                    ///< Offset 194     PCIE LTR max no snoop Latency 6
+                                                    ///< Offset 196     PCIE LTR max no snoop Latency 7
+                                                    ///< Offset 198     PCIE LTR max no snoop Latency 8
+                                                    ///< Offset 200     PCIE LTR max no snoop Latency 9
+                                                    ///< Offset 202     PCIE LTR max no snoop Latency 10
+                                                    ///< Offset 204     PCIE LTR max no snoop Latency 11
+                                                    ///< Offset 206     PCIE LTR max no snoop Latency 12
+                                                    ///< Offset 208     PCIE LTR max no snoop Latency 13
+                                                    ///< Offset 210     PCIE LTR max no snoop Latency 14
+                                                    ///< Offset 212     PCIE LTR max no snoop Latency 15
+                                                    ///< Offset 214     PCIE LTR max no snoop Latency 16
+                                                    ///< Offset 216     PCIE LTR max no snoop Latency 17
+                                                    ///< Offset 218     PCIE LTR max no snoop Latency 18
+                                                    ///< Offset 220     PCIE LTR max no snoop Latency 19
+                                                    ///< Offset 222     PCIE LTR max no snoop Latency 20
+                                                    ///< Offset 224     PCIE LTR max no snoop Latency 21
+                                                    ///< Offset 226     PCIE LTR max no snoop Latency 22
+                                                    ///< Offset 228     PCIE LTR max no snoop Latency 23
+                                                    ///< Offset 230     PCIE LTR max no snoop Latency 24
+  UINT8    XHPC;                                    ///< Offset 232     Number of HighSpeed ports implemented in XHCI controller
+  UINT8    XRPC;                                    ///< Offset 233     Number of USBR ports implemented in XHCI controller
+  UINT8    XSPC;                                    ///< Offset 234     Number of SuperSpeed ports implemented in XHCI controller
+  UINT8    XSPA;                                    ///< Offset 235     Address of 1st SuperSpeed port
+  UINT32   HPTB;                                    ///< Offset 236     HPET base address
+  UINT8    HPTE;                                    ///< Offset 240     HPET enable
+  //SerialIo block
+  UINT8    SMD[12];                                 ///< Offset 241     SerialIo controller 0 mode
+                                                    ///< Offset 242     SerialIo controller 1 mode
+                                                    ///< Offset 243     SerialIo controller 2 mode
+                                                    ///< Offset 244     SerialIo controller 3 mode
+                                                    ///< Offset 245     SerialIo controller 4 mode
+                                                    ///< Offset 246     SerialIo controller 5 mode
+                                                    ///< Offset 247     SerialIo controller 6 mode
+                                                    ///< Offset 248     SerialIo controller 7 mode
+                                                    ///< Offset 249     SerialIo controller 8 mode
+                                                    ///< Offset 250     SerialIo controller 9 mode
+                                                    ///< Offset 251     SerialIo controller A mode
+                                                    ///< Offset 252     SerialIo controller B mode
+  UINT8    SIR[12];                                 ///< Offset 253     SerialIo controller 0 irq number
+                                                    ///< Offset 254     SerialIo controller 1 irq number
+                                                    ///< Offset 255     SerialIo controller 2 irq number
+                                                    ///< Offset 256     SerialIo controller 3 irq number
+                                                    ///< Offset 257     SerialIo controller 4 irq number
+                                                    ///< Offset 258     SerialIo controller 5 irq number
+                                                    ///< Offset 259     SerialIo controller 6 irq number
+                                                    ///< Offset 260     SerialIo controller 7 irq number
+                                                    ///< Offset 261     SerialIo controller 8 irq number
+                                                    ///< Offset 262     SerialIo controller 9 irq number
+                                                    ///< Offset 263     SerialIo controller A irq number
+                                                    ///< Offset 264     SerialIo controller B irq number
+  UINT64   SB0[12];                                 ///< Offset 265     SerialIo controller 0 BAR0
+                                                    ///< Offset 273     SerialIo controller 1 BAR0
+                                                    ///< Offset 281     SerialIo controller 2 BAR0
+                                                    ///< Offset 289     SerialIo controller 3 BAR0
+                                                    ///< Offset 297     SerialIo controller 4 BAR0
+                                                    ///< Offset 305     SerialIo controller 5 BAR0
+                                                    ///< Offset 313     SerialIo controller 6 BAR0
+                                                    ///< Offset 321     SerialIo controller 7 BAR0
+                                                    ///< Offset 329     SerialIo controller 8 BAR0
+                                                    ///< Offset 337     SerialIo controller 9 BAR0
+                                                    ///< Offset 345     SerialIo controller A BAR0
+                                                    ///< Offset 353     SerialIo controller B BAR0
+  UINT64   SB1[12];                                 ///< Offset 361     SerialIo controller 0 BAR1
+                                                    ///< Offset 369     SerialIo controller 1 BAR1
+                                                    ///< Offset 377     SerialIo controller 2 BAR1
+                                                    ///< Offset 385     SerialIo controller 3 BAR1
+                                                    ///< Offset 393     SerialIo controller 4 BAR1
+                                                    ///< Offset 401     SerialIo controller 5 BAR1
+                                                    ///< Offset 409     SerialIo controller 6 BAR1
+                                                    ///< Offset 417     SerialIo controller 7 BAR1
+                                                    ///< Offset 425     SerialIo controller 8 BAR1
+                                                    ///< Offset 433     SerialIo controller 9 BAR1
+                                                    ///< Offset 441     SerialIo controller A BAR1
+                                                    ///< Offset 449     SerialIo controller B BAR1
+  //end of SerialIo block
+  UINT8    SGIR;                                    ///< Offset 457     GPIO IRQ
+  UINT8    GPHD;                                    ///< Offset 458     Hide GPIO ACPI device
+  UINT8    RstPcieStorageInterfaceType[3];          ///< Offset 459     RST PCIe Storage Cycle Router#1 Interface Type
+                                                    ///< Offset 460     RST PCIe Storage Cycle Router#2 Interface Type
+                                                    ///< Offset 461     RST PCIe Storage Cycle Router#3 Interface Type
+  UINT8    RstPcieStoragePmCapPtr[3];               ///< Offset 462     RST PCIe Storage Cycle Router#1 Power Management Capability Pointer
+                                                    ///< Offset 463     RST PCIe Storage Cycle Router#2 Power Management Capability Pointer
+                                                    ///< Offset 464     RST PCIe Storage Cycle Router#3 Power Management Capability Pointer
+  UINT8    RstPcieStoragePcieCapPtr[3];             ///< Offset 465     RST PCIe Storage Cycle Router#1 PCIe Capabilities Pointer
+                                                    ///< Offset 466     RST PCIe Storage Cycle Router#2 PCIe Capabilities Pointer
+                                                    ///< Offset 467     RST PCIe Storage Cycle Router#3 PCIe Capabilities Pointer
+  UINT16   RstPcieStorageL1ssCapPtr[3];             ///< Offset 468     RST PCIe Storage Cycle Router#1 L1SS Capability Pointer
+                                                    ///< Offset 470     RST PCIe Storage Cycle Router#2 L1SS Capability Pointer
+                                                    ///< Offset 472     RST PCIe Storage Cycle Router#3 L1SS Capability Pointer
+  UINT8    RstPcieStorageEpL1ssControl2[3];         ///< Offset 474     RST PCIe Storage Cycle Router#1 Endpoint L1SS Control Data2
+                                                    ///< Offset 475     RST PCIe Storage Cycle Router#2 Endpoint L1SS Control Data2
+                                                    ///< Offset 476     RST PCIe Storage Cycle Router#3 Endpoint L1SS Control Data2
+  UINT32   RstPcieStorageEpL1ssControl1[3];         ///< Offset 477     RST PCIe Storage Cycle Router#1 Endpoint L1SS Control Data1
+                                                    ///< Offset 481     RST PCIe Storage Cycle Router#2 Endpoint L1SS Control Data1
+                                                    ///< Offset 485     RST PCIe Storage Cycle Router#3 Endpoint L1SS Control Data1
+  UINT16   RstPcieStorageLtrCapPtr[3];              ///< Offset 489     RST PCIe Storage Cycle Router#1 LTR Capability Pointer
+                                                    ///< Offset 491     RST PCIe Storage Cycle Router#2 LTR Capability Pointer
+                                                    ///< Offset 493     RST PCIe Storage Cycle Router#3 LTR Capability Pointer
+  UINT32   RstPcieStorageEpLtrData[3];              ///< Offset 495     RST PCIe Storage Cycle Router#1 Endpoint LTR Data
+                                                    ///< Offset 499     RST PCIe Storage Cycle Router#2 Endpoint LTR Data
+                                                    ///< Offset 503     RST PCIe Storage Cycle Router#3 Endpoint LTR Data
+  UINT16   RstPcieStorageEpLctlData16[3];           ///< Offset 507     RST PCIe Storage Cycle Router#1 Endpoint LCTL Data
+                                                    ///< Offset 509     RST PCIe Storage Cycle Router#2 Endpoint LCTL Data
+                                                    ///< Offset 511     RST PCIe Storage Cycle Router#3 Endpoint LCTL Data
+  UINT16   RstPcieStorageEpDctlData16[3];           ///< Offset 513     RST PCIe Storage Cycle Router#1 Endpoint DCTL Data
+                                                    ///< Offset 515     RST PCIe Storage Cycle Router#2 Endpoint DCTL Data
+                                                    ///< Offset 517     RST PCIe Storage Cycle Router#3 Endpoint DCTL Data
+  UINT16   RstPcieStorageEpDctl2Data16[3];          ///< Offset 519     RST PCIe Storage Cycle Router#1 Endpoint DCTL2 Data
+                                                    ///< Offset 521     RST PCIe Storage Cycle Router#2 Endpoint DCTL2 Data
+                                                    ///< Offset 523     RST PCIe Storage Cycle Router#3 Endpoint DCTL2 Data
+  UINT16   RstPcieStorageRpDctl2Data16[3];          ///< Offset 525     RST PCIe Storage Cycle Router#1 RootPort DCTL2 Data
+                                                    ///< Offset 527     RST PCIe Storage Cycle Router#2 RootPort DCTL2 Data
+                                                    ///< Offset 529     RST PCIe Storage Cycle Router#3 RootPort DCTL2 Data
+  UINT32   RstPcieStorageUniqueTableBar[3];         ///< Offset 531     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR
+                                                    ///< Offset 535     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X Table BAR
+                                                    ///< Offset 539     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X Table BAR
+  UINT32   RstPcieStorageUniqueTableBarValue[3];    ///< Offset 543     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR value
+                                                    ///< Offset 547     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X Table BAR value
+                                                    ///< Offset 551     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X Table BAR value
+  UINT32   RstPcieStorageUniquePbaBar[3];           ///< Offset 555     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR
+                                                    ///< Offset 559     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X PBA BAR
+                                                    ///< Offset 563     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X PBA BAR
+  UINT32   RstPcieStorageUniquePbaBarValue[3];      ///< Offset 567     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR value
+                                                    ///< Offset 571     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X PBA BAR value
+                                                    ///< Offset 575     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X PBA BAR value
+  UINT32   RstPcieStorageRootPortNum[3];            ///< Offset 579     RST PCIe Storage Cycle Router#1 Root Port number
+                                                    ///< Offset 583     RST PCIe Storage Cycle Router#2 Root Port number
+                                                    ///< Offset 587     RST PCIe Storage Cycle Router#3 Root Port number
+  UINT8    EMH4;                                    ///< Offset 591     eMMC HS400 mode enabled
+  UINT8    EMDS;                                    ///< Offset 592     eMMC Driver Strength
+  UINT8    CpuSku;                                  ///< Offset 593     CPU SKU
+  UINT16   IoTrapAddress[4];                        ///< Offset 594
+  UINT8    IoTrapStatus[4];                         ///< Offset 602
+  UINT16   PMBS;                                    ///< Offset 606     ACPI IO BASE address
+  UINT32   PWRM;                                    ///< Offset 608     PWRM MEM BASE address
+  // Cnvi specific
+  UINT8    CnviMode;                                ///< Offset 612     CNVi mode
+  UINT32   RmrrCsmeBaseAddress;                     ///< Offset 613     RMRR CSME Base Address
+  //Voltage Margining
+  UINT8    SlpS0VmRuntimeControl;                   ///< Offset 617     SLP_S0 Voltage Margining Runtime Control
+  UINT8    SlpS0Vm070VSupport;                      ///< Offset 618     SLP_S0 0.70V Voltage Margining Support
+  UINT8    SlpS0Vm075VSupport;                      ///< Offset 619     SLP_S0 0.75V Voltage Margining Support
+  // PCH Trace Hub
+  UINT8    PchTraceHubMode;                         ///< Offset 620     PCH Trace Hub Mode
+  // PCH PS_ON support
+  UINT8    PsOnEnable;                              ///< Offset 621     PCH PS_ON enable
+  UINT32   TempRsvdMemBase;                         ///< Offset 622     Reserved memory base address for Temp MBAR
+  //
+  // These are for PchApciTablesSelfTest use
+  //
+  UINT8    LtrEnable[24];                           ///< Offset 626     Latency Tolerance Reporting Enable
+                                                    ///< Offset 627     Latency Tolerance Reporting Enable
+                                                    ///< Offset 628     Latency Tolerance Reporting Enable
+                                                    ///< Offset 629     Latency Tolerance Reporting Enable
+                                                    ///< Offset 630     Latency Tolerance Reporting Enable
+                                                    ///< Offset 631     Latency Tolerance Reporting Enable
+                                                    ///< Offset 632     Latency Tolerance Reporting Enable
+                                                    ///< Offset 633     Latency Tolerance Reporting Enable
+                                                    ///< Offset 634     Latency Tolerance Reporting Enable
+                                                    ///< Offset 635     Latency Tolerance Reporting Enable
+                                                    ///< Offset 636     Latency Tolerance Reporting Enable
+                                                    ///< Offset 637     Latency Tolerance Reporting Enable
+                                                    ///< Offset 638     Latency Tolerance Reporting Enable
+                                                    ///< Offset 639     Latency Tolerance Reporting Enable
+                                                    ///< Offset 640     Latency Tolerance Reporting Enable
+                                                    ///< Offset 641     Latency Tolerance Reporting Enable
+                                                    ///< Offset 642     Latency Tolerance Reporting Enable
+                                                    ///< Offset 643     Latency Tolerance Reporting Enable
+                                                    ///< Offset 644     Latency Tolerance Reporting Enable
+                                                    ///< Offset 645     Latency Tolerance Reporting Enable
+                                                    ///< Offset 646     Latency Tolerance Reporting Enable
+                                                    ///< Offset 647     Latency Tolerance Reporting Enable
+                                                    ///< Offset 648     Latency Tolerance Reporting Enable
+                                                    ///< Offset 649     Latency Tolerance Reporting Enable
+  UINT8    GBES;                                    ///< Offset 650     GbE Support
+  UINT8    SataPortPresence;                        ///< Offset 651     Holds information from SATA PCS register about SATA ports which recieved COMINIT from connected devices.
+  UINT8    SdPowerEnableActiveHigh;                 ///< Offset 652     SD PWREN# active high indication
+  UINT8    EmmcEnabled;                             ///< Offset 653     Set to indicate that eMMC is enabled
+  UINT8    SdCardEnabled;                           ///< Offset 654     Set to indicate that SD card is enabled
+} PCH_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
new file mode 100644
index 0000000000..94a5e0fad2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
@@ -0,0 +1,58 @@
+/** @file
+  Definitions required to create RstHob
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h
new file mode 100644
index 0000000000..7a92a509b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h
@@ -0,0 +1,25 @@
+/** @file
+  This file contains definitions of Si Schedule Reset HOB.
+
+  Copyright (c) 2019 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_
+
+#include <PchResetPlatformSpecific.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.16.2.windows.1


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

* [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (8 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
                   ` (27 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds the following header files:
 * Pch/Include/Private/Library

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h           |  134 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h          |   97 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h       |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h          | 1061 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h      |  288 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h               |  344 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h               |   56 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h        |  100 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h |  371 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h        |  578 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h       |   98 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h         |  366 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h            |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h           |  706 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h      |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h        |   28 +
 16 files changed, 4325 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h
new file mode 100644
index 0000000000..9d8e34eb0d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h
@@ -0,0 +1,134 @@
+/** @file
+  Header file for DxePchHdaLib - NHLT structure definitions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_HDA_NHLT_H_
+#define _DXE_PCH_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_DEVICE_TYPE
+{
+  HdaNhltDeviceBt   = 0,
+  HdaNhltDeviceDmic = 1,
+  HdaNhltDeviceI2s  = 4,
+  HdaNhltDeviceInvalid
+};
+
+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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h
new file mode 100644
index 0000000000..9e0658331f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h
@@ -0,0 +1,97 @@
+/** @file
+  Header file for GPIO Helpers Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_HELPERS_LIB_H_
+#define _GPIO_HELPERS_LIB_H_
+
+#include <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
+  );
+#endif // _GPIO_HELPERS_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h
new file mode 100644
index 0000000000..a6ab42e4d5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h
@@ -0,0 +1,25 @@
+/** @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) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h
new file mode 100644
index 0000000000..245618ff6d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h
@@ -0,0 +1,1061 @@
+/** @file
+  Header file for GpioPrivateLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PRIVATE_LIB_H_
+#define _GPIO_PRIVATE_LIB_H_
+
+#include <GpioConfig.h>
+#include <Library/PchPcrLib.h>
+
+//
+// Structure for native pin data
+//
+typedef struct {
+  GPIO_PAD       Pad;
+  GPIO_PAD_MODE  Mode;
+} GPIO_PAD_NATIVE_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
+
+//
+// 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
+
+/**
+  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
+  );
+
+/**
+  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 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;
+  UINT8       GpioGpeDwxVal;
+} 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 set 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
+GpioSetPadMode (
+  IN GPIO_PAD                GpioPad,
+  IN GPIO_PAD_MODE           PadModeValue
+  );
+
+/**
+  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 sets SerialIo I2C controller pins into native mode
+
+  @param[in]  SerialIoI2cControllerNumber   I2C controller
+  @param[in]  GpioTermination               GPIO termination type
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoI2c (
+  IN  UINT32                  SerialIoI2cControllerNumber,
+  IN  GPIO_ELECTRICAL_CONFIG  GpioTermination
+  );
+
+/**
+  This function sets SerialIo UART controller pins into native mode
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoUart (
+  IN  UINT32            SerialIoUartControllerNumber,
+  IN  BOOLEAN           HardwareFlowControl,
+  IN  UINT32            PinMuxing
+  );
+
+/**
+  This function sets SerialIo SPI controller pins into native mode
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoSpi (
+  IN  UINT32            SerialIoSpiControllerNumber
+  );
+
+/**
+  This function sets ISH I2C controller pins into native mode
+
+  @param[in]  IshI2cControllerNumber   I2C controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshI2c (
+  IN  UINT32            IshI2cControllerNumber
+  );
+
+/**
+  This function sets ISH UART controller pins into native mode
+
+  @param[in]  IshUartControllerNumber   UART controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshUart (
+  IN  UINT32            IshUartControllerNumber
+  );
+
+/**
+  This function sets ISH SPI controller pins into native mode
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshSpi (
+  IN  UINT32            IshSpiControllerNumber
+  );
+
+/**
+  This function sets ISH GP pin into native mode
+
+  @param[in]  IshGpPinNumber   ISH GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshGpPin (
+  IN  UINT32            IshGpPinNumber
+  );
+
+/**
+  This function sets SCS SD card controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCard (
+  VOID
+  );
+
+/**
+  This function enables SCS SD Card controller card detect pin
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCardDetect (
+  VOID
+  );
+
+/**
+  This function sets SCS eMMC controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsEmmc (
+  VOID
+  );
+
+/**
+  This function sets HDA Link pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaLink (
+  VOID
+  );
+
+/**
+  This function sets HDA DMIC pins into native mode
+
+  @param[in]  DmicNumber   DMIC number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaDmic (
+  IN  UINT32            DmicNumber
+  );
+
+/**
+  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]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSspMasterClock (
+  VOID
+  );
+
+/**
+  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 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 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 sets SATA DevSlp pins into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataDevSlpPin (
+  IN  UINT32  SataCtrlIndex,
+  IN  UINTN   SataPort
+  );
+
+/**
+  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]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataLed (
+  VOID
+  );
+
+/**
+  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
+  );
+
+//
+// DDSP_HPD pins
+//
+typedef enum {
+  GpioDdspHpd0 = 0x00,
+  GpioDdspHpd1 = 0x01,
+  GpioDdspHpd2 = 0x02,
+  GpioDdspHpd3 = 0x03,
+  GpioDdspHpd4 = 0x04,
+  GpioDdspHpdA = 0x10,
+  GpioDdspHpdB = 0x11,
+  GpioDdspHpdC = 0x12
+} GPIO_DDSP_HPD;
+
+/**
+  This function sets DDSP_HPDx pin into native mode
+
+  @param[in]  DdspHpdPin     DDSP_HPDx pin
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpHotPlugDetect (
+  IN GPIO_DDSP_HPD  DdspHpdPin
+  );
+
+/**
+  This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode for eDP Panel
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableEdpPins (
+  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
+  );
+
+/**
+  This function configures GPIO connection between CNVi and CRF
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviCrfConnection (
+  VOID
+  );
+
+/**
+  This function enables CNVi RF Reset pin
+**/
+VOID
+GpioEnableCnviRfResetPin (
+  VOID
+  );
+
+/**
+  This function enables CNVi MODEM CLKREQ pin
+**/
+VOID
+GpioEnableCnviModemClkReqPin (
+  VOID
+  );
+
+/**
+  CNVi Bluetooth UART connection options
+**/
+typedef enum {
+  GpioCnviBtUartNotConnected,
+  GpioCnviBtUartToSerialIoUart0,
+  GpioCnviBtUartToIshUart0,
+  GpioCnviBtUartToExternalPads
+} VGPIO_CNVI_BT_UART_CONNECTION_TYPE;
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth UART
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtUartConnection (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType
+  );
+
+/**
+  CNVi Bluetooth I2S connection options
+**/
+typedef enum {
+  GpioCnviBtI2sNotConnected,
+  GpioCnviBtI2sToSsp0,
+  GpioCnviBtI2sToSsp1,
+  GpioCnviBtI2sToSsp2,
+  GpioCnviBtI2sToExternalPads
+} VGPIO_CNVI_BT_I2S_CONNECTION_TYPE;
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth I2S
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtI2sConnection (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType
+  );
+
+/**
+  CNVi MultiFunction UART connection options
+**/
+typedef enum {
+  GpioCnviMfUart1NotConnected,
+  GpioCnviMfUart1ToSerialIoUart2,
+  GpioCnviMfUart1ToIshUart0,
+  GpioCnviMfUart1ToExternalPads
+} VGPIO_CNVI_MF_UART1_CONNECTION_TYPE;
+
+/**
+  This function configures virtual GPIO connection for CNVi MFUART1
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviMfUart1Connection (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType
+  );
+
+
+/**
+  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
+  );
+
+/**
+  CNVi Bluetooth UART connection options
+**/
+typedef enum {
+  GpioCnviBtIfUart = 0,
+  GpioCnviBtIfUsb,
+} VGPIO_CNVI_BT_INTERFACE;
+
+/**
+  This function sets CNVi Bluetooth main host interface
+
+  @param[in] BtInterface          CNVi BT Interface Select value
+                                  GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviBtInterface (
+  IN  VGPIO_CNVI_BT_INTERFACE  BtInterface
+  );
+
+/**
+  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
+  );
+
+/**
+  CNVi WiFi mode
+**/
+typedef enum {
+  GpioCnviWiFiEnabled,
+  GpioCnviWiFiAuto
+} VGPIO_CNVI_WIFI_MODE;
+
+/**
+  This function sets CNVi WiFi mode
+
+  @param[in] Value                CNVi WiFi Mode value
+                                  GpioCnviWiFiAuto: WiFi is automatically enabled/disabled by WiFi core
+                                  GpioCnviWiFiEnabled: WiFi is enabled regardless of WiFi core decision
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviWifiMode (
+  IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
+  );
+
+/**
+  This function enables IMGU CLKOUT native pin
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableImguClkOut (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  Configure LPC GPIO
+**/
+VOID
+LpcConfigureGpio (
+  VOID
+  );
+
+#endif // _GPIO_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h
new file mode 100644
index 0000000000..a4bd42f420
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h
@@ -0,0 +1,288 @@
+/** @file
+ Implement the I2C port control.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _I2C_MASTER_COMMON_LIB_H_
+#define _I2C_MASTER_COMMON_LIB_H_
+
+///
+/// Each I2C port instance uses an I2C_MASTER_CONTEXT structure
+/// to maintain its context.
+///
+typedef struct {
+  EFI_I2C_CONTROLLER_CAPABILITIES Capabilities;
+  //
+  // I2C master's mmio addresses cached to speed up operation
+  //
+  UINTN                           MmioAddress;
+  UINTN                           ConfigAddress;
+  //
+  // copy of all pointers and data provided in StartRequest call
+  // if transfer didn't finish in one go, those will be needed to continue it
+  //
+  EFI_I2C_REQUEST_PACKET          *Request;
+  //
+  // Internal copy of Transfer status, to be returned from StartRequest()
+  //
+  EFI_STATUS                      TransferStatus;
+  //
+  // Index (Operation:Postition in Buffer) of next operation to be performed
+  // Write is for both R/W operations as both need to be put in fifo
+  // Read is for Read only, for filling buffer with data retrieved from bus
+  //
+  UINTN                           WriteOp;
+  UINTN                           WritePos;
+  UINTN                           ReadOp;
+  UINTN                           ReadPos;
+  BOOLEAN                         TransferInProgress;
+} I2C_MASTER_CONTEXT;
+
+/**
+  Prepare I2c controller for use: enable its mmio range, put in D0, get out of reset
+  Verifies I2C Line SDA and SCL states
+
+  @param[in] Context - driver context
+
+  @retval EFI_SUCCESS         Controller prepared
+  @retval EFI_DEVICE_ERROR    SCL and/or SDA lines are not pulled up
+**/
+EFI_STATUS
+PrepareController (
+  I2C_MASTER_CONTEXT  *Context
+  );
+
+/**
+  Determine the state of the I2C controller
+
+  @param[in] Context - driver context
+
+  @retval TRUE              The I2C controller is active
+  @retval FALSE             The I2C controller is idle
+**/
+BOOLEAN
+IsHardwareActive (
+  I2C_MASTER_CONTEXT  *Context
+  );
+
+/**
+  Updates WriteOperation and WritePosition, two variables that determine
+  which part of Request is being committed to I2C bus.
+  This iterates over both Read and Write operations from a request, because
+  things that need to be written to WriteFifo are both I2c bus writes
+  and I2c bus reads (the command to perform bus read needs to be put into Write Fifo)
+
+  @param[in] Context - driver context
+**/
+VOID
+UpdateWritePosition (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  FindReadOp checks if current Operation is of Read type. If so, returns.
+  If not, increases ReadOp until it finds one or goes beyond Request's OperationCount
+
+  @param[in] Context - driver context
+**/
+VOID
+FindReadOp (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Updates ReadOperation and ReadPosition, two variables that determine
+  which part of Request is being filled with data incoming from I2C reads.
+  This iterates only over Read operations from a request.
+
+  @param[in] Context - driver context
+**/
+VOID
+UpdateReadPosition (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  ValidateRequest checks if Request is valid and can be started
+
+  @param[in] Context            driver context
+  @param[in] RequestPacket      content of I2C request package
+
+  @retval EFI_SUCCESS           Request is valid and can be started
+  @retval EFI_ALREADY_STARTED   The controller is busy with another transfer
+  @retval EFI_BAD_BUFFER_SIZE   Transfer size too big
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL, invalid Operation flags
+  @retval EFI_UNSUPPORTED       10bit I2C address or "ping" operation attempted (0-byte transfer, address byte not followed by any data)
+**/
+EFI_STATUS
+ValidateRequest (
+  I2C_MASTER_CONTEXT           *Context,
+  CONST EFI_I2C_REQUEST_PACKET *RequestPacket
+  );
+
+/**
+  IsLastFromRequest checks if WritePos and WriteOp point to the last byte of the request
+
+  @param[in] Context - driver context
+**/
+BOOLEAN
+IsLastFromRequest (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  IsLastFromRequest checks if WritePos and WriteOp point to the first byte of an operation
+
+  @param[in] Context - driver context
+
+  @retval Boolean
+**/
+BOOLEAN
+IsFirstFromOperation (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  InitializeTransfer checks if HW is ready to accept new transfer.
+  If so, sets up slave address
+
+  @param[in] Context - driver context
+
+  @retval Status
+**/
+EFI_STATUS
+InitializeTransfer (
+  I2C_MASTER_CONTEXT           *Context,
+  UINTN                        SlaveAddress,
+  CONST EFI_I2C_REQUEST_PACKET *RequestPacket
+  );
+
+/**
+  WriteFifo writes to I2c controller's transmit Fifo. Data written to Fifo could be
+  - data bytes to be written to an I2C slave
+  - read requests that trigger I2C bus reads
+  First transfer from each operation adds Restart bit which triggers Restart condition on bus
+  Last transfer from the whole Request adds Stop bit which triggers Stop condtion on bus
+  Driver keeps track of which parts of Request were already committed to hardware using
+  pointer consisting of WritePosition and WriteOperation variables. This pointer is updated
+  every time data byte/read request is committed to FIFO
+  WriteFifo executes while there's anything more to write and the write fifo isn't full
+
+  @param[in] Context - driver context
+**/
+VOID
+WriteFifo (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  ReadFifo reads from I2c controller's receive Fifo. It contains data retrieved
+  from slave device as a result of executing read transfers, which were
+  triggered by putting read requests into Write Fifo. Retrieved data is copied into buffers
+  pointed to by Request structure.
+  Driver keeps track where to copy incoming data using pointer consisting of
+  ReadPosition and ReadOperation variables. This pointer is updated
+  every time data was retrieved from hardware
+  ReadFifo executes while there's data available and receive buffers were not filled
+
+  @param[in] Context - driver context
+**/
+VOID
+ReadFifo (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  CheckErrors checks if there were any transfer errors.
+
+  @param[in] Context - driver context
+**/
+VOID
+CheckErrors (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Transfer is finished when all requested operations were placed in fifo,
+  all read requests were filled and hardware is inactive
+  The last part is necessary for write-only transfers where after
+  placing all writes in fifo sw needs to wait until they flush down the bus
+
+  @param[in] Context - driver context
+
+  @retval Boolean
+**/
+BOOLEAN
+IsTransferFinished (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Clean up Hw activity and errors
+  Return status to Request's submitter and signal the event that tells
+  it that the request is complete
+  Clear up Sw context to allow new request to start
+
+  @param[in] Context - driver context
+**/
+VOID
+FinishTransfer (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  PerformTransfer. For synchronous transfer this function is called in a loop
+  and for asynchronous transfers, as a timer callback. It writes data and/or
+  read requests to hadrware, copies read data to destination buffers. When
+  transfer completes, it cleans up Sw context and Hw registers in preparation
+  for new transfer
+
+  @param[in] Context - driver context
+**/
+VOID
+PerformTransfer (
+  IN I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Set the I2C controller bus clock frequency.
+
+  This routine must be called at or below TPL_NOTIFY.
+
+  The software and controller do a best case effort of using the specified
+  frequency for the I2C bus.  If the frequency does not match exactly then
+  the controller will use lower frequency for the I2C to avoid exceeding
+  the operating conditions for any of the I2C devices on the bus.
+  For example if 400 KHz was specified and the controller's divide network
+  only supports 402 KHz or 398 KHz then the controller would be set to 398
+  KHz.
+
+  @param[in] MmioAddress    Address of I2C controller
+  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
+
+  @retval EFI_SUCCESS       The bus frequency was set successfully.
+  @retval EFI_UNSUPPORTED   The controller does not support this frequency.
+**/
+
+EFI_STATUS
+FrequencySet (
+  IN UINTN     MmioAddress,
+  IN OUT UINTN *BusClockHertz
+  );
+
+/**
+  Reset the I2C controller
+
+  @param[in] MmioAddress    Address of I2C controller
+
+  @retval Status
+**/
+EFI_STATUS
+I2cReset (
+  IN UINTN     MmioAddress
+  );
+
+#endif // _I2C_MASTER_COMMON_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
new file mode 100644
index 0000000000..d17b65c598
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
@@ -0,0 +1,344 @@
+/** @file
+  Header file for PchDmiLib.
+
+  Copyright (c) 2019 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
+  );
+
+/**
+  Set ACPI base address decoding in DMI
+
+  @param[in] Address                    Address for ACPI base.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetAcpiBase (
+  IN  UINT16                            Address
+  );
+
+/**
+  Set PWRM base address decoding in DMI
+
+  @param[in] Address                    Address for PWRM base.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetPwrmBase (
+  IN  UINT32                            Address
+  );
+
+/**
+  Set PCH TCO base address decoding in DMI
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetTcoBase (
+  IN  UINT16                            Address
+  );
+
+/**
+  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
+  );
+
+/**
+  Clear PCH LPC/eSPI generic IO range decoding in DMI
+
+  @param[in] RangeIndex                 Index of chosen range
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearLpcGenIoRange (
+  IN  UINTN                             RangeIndex
+  );
+
+/**
+  Clear PCH eSPI CS1# generic IO range decoding in DMI
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearEspiCs1GenIoRange (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port in DMI
+
+  @param[in] RpNumber                   PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchDmiSetIoPort80Decode (
+  IN  UINTN                             RpNumber
+  );
+
+/**
+  Set DMI thermal throttling to recommended configuration
+**/
+VOID
+PchDmiSetRecommendedThermalThrottling (
+  VOID
+  );
+
+//
+// Thermal Sensor Target Width structure
+// Look at DMI_THERMAL_SENSOR_TARGET_WIDTH for possible values
+//
+typedef struct {
+  UINT32  ThermalSensor0TargetWidth :3;
+  UINT32  ThermalSensor1TargetWidth :3;
+  UINT32  ThermalSensor2TargetWidth :3;
+  UINT32  ThermalSensor3TargetWidth :3;
+  UINT32  Rsvd                      :20;
+} DMI_THERMAL_THROTTLING;
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmiSetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  );
+
+/**
+  Determines where to send the reserved page registers
+  Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Port
+  with the destination ID specified in GCS.RPRDID using DMI source decode.
+**/
+VOID
+PchDmiSetReservedPageRegToPcieRootPort (
+  VOID
+  );
+
+/**
+  Determines where to send the reserved page registers
+  DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cycles hitting these ranges will
+  end up in P2SB which will then forward the cycle to LPC or eSPI through IOSF Sideband.
+**/
+VOID
+PchDmiSetReservedPageRegToLpc (
+  VOID
+  );
+
+/**
+  uCode Patch Region Enable (UPRE). Enables memory access targeting the uCode patch region (0xFEF00000 to 0xFEFFFFFF)
+  to be forwarded to SPI Flash. This can only be set if the boot flash is on SPI.
+**/
+VOID
+PchDmiEnableUCodePatchRegion (
+  VOID
+  );
+
+/**
+  Enable PCIe Relaxed Order
+**/
+VOID
+PchDmiEnablePcieRelaxedOrder (
+  VOID
+  );
+
+/**
+  This function will switch SAI value to be driven to IOSF Primary Fabric
+  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
+  To be used when PCH is paired with CFL CPU.
+**/
+VOID
+PchDmiEnablePostBootSai (
+  VOID
+  );
+
+/**
+  This function will do necessary configuration after platform
+  should have switched to POSTBOOT_SAI. It needs to be called even if
+  POSTBOOT_SAI was not set.
+**/
+VOID
+PchDmiConfigAfterPostBootSai (
+  VOID
+  );
+
+/**
+  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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
new file mode 100644
index 0000000000..e53ed881df
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
@@ -0,0 +1,56 @@
+/** @file
+  This library provides PCH HD Audio functions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_LIB_H_
+#define _PCH_HDA_LIB_H_
+
+#include <Private/Library/DxePchHdaNhlt.h>
+#include <Private/PchHdaEndpoints.h>
+
+/**
+  Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload Engine Driver) Configuration Table).
+
+  @param[in] *NhltAcpiTable    The NHLT table to print
+**/
+VOID
+NhltAcpiTableDump(
+  IN NHLT_ACPI_TABLE           *NhltTable
+  );
+
+/**
+  Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
+
+  @param[in][out] *NhltTable            NHLT table for which header will be created
+  @param[in]      NhltTableSize         Size of NHLT table
+
+  @retval None
+**/
+VOID
+NhltAcpiHeaderConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable,
+  IN UINT32                     NhltTableSize
+  );
+
+/**
+  Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
+
+  @param[in]      *EndpointTable List of endpoints for NHLT
+  @param[in][out] **NhltTable    NHLT table to be created
+  @param[in][out] *NhltTableSize Size of created NHLT table
+
+  @retval EFI_SUCCESS            NHLT created successfully
+  @retval EFI_BAD_BUFFER_SIZE    Not enough resources to allocate NHLT
+**/
+EFI_STATUS
+NhltConstructor(
+  IN PCH_HDA_NHLT_ENDPOINTS    *EndpointTable,
+  IN OUT NHLT_ACPI_TABLE       **NhltTable,
+  IN OUT UINT32                *NhltTableSize
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h
new file mode 100644
index 0000000000..6d71504772
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h
@@ -0,0 +1,100 @@
+/** @file
+  Header file for PCH Init Common Lib
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_COMMON_LIB_H_
+#define _PCH_INIT_COMMON_LIB_H_
+
+#include <Library/PchPcrLib.h>
+
+/**
+  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] RpPort             Root Port Number
+
+  @retval PCH_SBI_PID    Returns PID for SBI Access
+**/
+PCH_SBI_PID
+GetRpSbiPid (
+  IN  UINTN  RpPort
+  );
+
+/**
+  Calculate root port device number based on physical port index.
+
+  @param[in]  RpIndex              Root port index (0-based).
+
+  @retval     Root port device number.
+**/
+UINT32
+PchGetPcieRpDevice (
+  IN  UINT32   RpIndex
+  );
+
+/**
+  This function reads Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[out] *Data32             Value of Config register
+
+  @retval EFI_SUCCESS             SBI Read successful.
+**/
+EFI_STATUS
+PchSbiRpPciRead32 (
+  IN    UINT32  RpIndex,
+  IN    UINT32  Offset,
+  OUT   UINT32  *Data32
+  );
+
+/**
+  This function And then Or Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[in]  Data32And           Value of Config register to be And-ed
+  @param[in]  Data32AOr           Value of Config register to be Or-ed
+
+  @retval EFI_SUCCESS             SBI Read and Write successful.
+**/
+EFI_STATUS
+PchSbiRpPciAndThenOr32 (
+  IN  UINT32  RpIndex,
+  IN  UINT32  Offset,
+  IN  UINT32  Data32And,
+  IN  UINT32  Data32Or
+  );
+
+/**
+  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
+PrintRegisters (
+  IN  UINTN        PrintMmioBase,
+  IN  UINT32       PrintSize,
+  IN  UINT32       OffsetFromBase
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h
new file mode 100644
index 0000000000..b0e4eb64c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h
@@ -0,0 +1,371 @@
+/** @file
+  Header file for PCH PCI Express helpers library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIB_H_
+#define _PCH_PCI_EXPRESS_HELPERS_LIB_H_
+
+#include <PchPolicyCommon.h>
+
+typedef enum {
+  TpoScale2us,
+  TpoScale10us,
+  TpoScale100us,
+  TpoScaleMax
+} T_PO_SCALE;
+
+typedef struct {
+  UINT32     Value;
+  T_PO_SCALE Scale;
+} T_POWER_ON;
+
+//
+// Function prototypes
+//
+
+/**
+  Get PCIe port number for enabled port.
+  @param[in] RpBase    Root Port pci segment base address
+  @return 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
+  );
+
+/**
+  Translate PCIe Port/Lane pair to 0-based PCIe lane number.
+
+  @param[in] RpIndex    Root Port index
+  @param[in] RpLane     Root Port Lane (0-3)
+
+  @retval PCIe lane number (0-based)
+**/
+UINT32
+PchPciePhysicalLane (
+  UINT32 RpIndex,
+  UINT32 RpLane
+  );
+
+/**
+  Checks if lane reversal is enabled on a given root port
+
+  @param[in] RpIndex  Root port index (0-based)
+
+  @retval TRUE if lane reversal is enbabled, FALSE otherwise
+**/
+BOOLEAN
+IsPcieLaneReversalEnabled (
+  IN     UINT32  RpIndex
+  );
+
+/**
+  Calculates the index of the first port on the same controller.
+
+  @param[in] RpIndex     Root Port Number (0-based)
+
+  @retval Index of the first port on the first controller.
+**/
+UINT32
+PchGetPcieFirstPortIndex (
+  IN     UINT32  RpIndex
+  );
+
+/*
+  Returns Tpower_on capability of device
+
+  @param[in] DeviceBase       device's PCI segment base address
+  @param[in] L1ssCapOffset    offset to L1substates capability in device's extended config space
+
+  @retval                     structure containing Tpoweron scale and value
+*/
+T_POWER_ON
+GetTpoCapability (
+  UINT64 DeviceBase,
+  UINT32 L1ssCapOffset
+  );
+
+/*
+  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
+  );
+
+/**
+  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
+
+  @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] 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
+*/
+VOID
+RetrainLink (
+  UINT64  Base,
+  UINT8   PcieCapOffset,
+  BOOLEAN WaitUntilDone
+  );
+
+/*
+  Checks if device at given address exists
+
+  @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
+  );
+
+/*
+  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
+  );
+
+/*
+  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] 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,
+  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
+  UINT32                    AspmOverrideTableSize,
+  PCH_PCIE_DEVICE_OVERRIDE  *AspmOverrideTable
+  );
+
+/**
+  Get current PCIe link speed.
+
+  @param[in] RpBase    Root Port base address
+  @return Link speed
+**/
+UINT32
+GetLinkSpeed (
+  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
+GetMaxLinkSpeed (
+  UINT64 RpBase
+  );
+
+/**
+  PCIe controller configuration.
+**/
+typedef enum {
+  Pcie4x1      = 0,
+  Pcie1x2_2x1  = 1,
+  Pcie2x2      = 2,
+  Pcie1x4      = 3
+} PCIE_CONTROLLER_CONFIG;
+
+#endif // _PEI_DXE_SMM_PCH_PCI_EXPRESS_HELPERS_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h
new file mode 100644
index 0000000000..9e68615717
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h
@@ -0,0 +1,578 @@
+/** @file
+  Header file for PchPsfPrivateLib.
+
+  Copyright (c) 2019 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/PchRegsPcr.h>
+
+//
+// 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
+  );
+
+/**
+  Return PSF_PORT for SerialIO I2C device
+
+  @param[in] I2cNum  Serial IO I2C device (I2C0, I2C1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO I2C device
+**/
+PSF_PORT
+PsfSerialIoI2cPort (
+  IN UINT32  I2cNum
+  );
+
+/**
+  Return PSF_PORT for SerialIO SPI device
+
+  @param[in] SpiNum  Serial IO SPI device (SPI0, SPI1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO SPI device
+**/
+PSF_PORT
+PsfSerialIoSpiPort (
+  IN UINT32  SpiNum
+  );
+
+/**
+  Return PSF_PORT for SerialIO UART device
+
+  @param[in] UartNum  Serial IO UART device (UART0, UART1, ....)
+
+  @retval  PsfPort    PSF PORT structure for SerialIO UART device
+**/
+PSF_PORT
+PsfSerialIoUartPort (
+  IN UINT32  UartNum
+  );
+
+/**
+  This procedure will set BARx value for TraceHub ACPI device at PSF level
+
+  @param[in] BarNum          BAR Number (0:BAR0, 1:BAR1)
+  @param[in] BarValue        32bit BAR value
+**/
+VOID
+PsfSetTraceHubAcpiDeviceBarValue (
+  IN UINT8   BarNum,
+  IN UINT32  BarValue
+  );
+
+/**
+  This procedure will enable MSE for TraceHub ACPI device at PSF level
+**/
+VOID
+PsfEnableTraceHubAcpiDeviceMemorySpace (
+  VOID
+  );
+
+/**
+  Enable HECI device at PSF level
+
+  @param[in] HeciDevice       HECIx Device (HECI1-4)
+**/
+VOID
+PsfEnableHeciDevice (
+  IN UINT8      HeciDevice
+  );
+
+/**
+  Disable HECI device at PSF level
+
+  @param[in] HeciDevice       HECIx Device (HECI1-4)
+**/
+VOID
+PsfDisableHeciDevice (
+  IN UINT8      HeciDevice
+  );
+
+/**
+  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 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 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
+  );
+
+typedef enum {
+  PsfPcieCtrl4x1,
+  PsfPcieCtrl1x2_2x1,
+  PsfPcieCtrl2x2,
+  PsfPcieCtrl1x4
+} 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
+  );
+
+/**
+  Program PSF EOI Multicast configuration for ITSS
+**/
+VOID
+PsfConfigurEoiForItss (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  Configure PSF power management.
+  Must be called after all PSF configuration is completed.
+**/
+VOID
+PsfConfigurePowerManagement (
+  VOID
+  );
+
+/**
+  Enable VTd support in PSF.
+**/
+VOID
+PchPsfEnableVtd (
+  VOID
+  );
+
+/**
+  Disable PSF address-based peer-to-peer decoding.
+**/
+VOID
+PchPsfDisableP2pDecoding (
+  VOID
+  );
+
+/**
+  Perform registers programming required for
+  Management Component Transport Protocol Broadcast Cycle.
+
+  Agent Destination Addresses are being programmed only when adequate
+  PCIe root port controllers are function enabled.
+
+  Function sets CSME PMT as a message broadcaster and programs the targets
+  of the message in registers only if adequate PCIe root port controllers
+  are function enabled. Conditionally, if the CPU PEG exist and is function
+  enabled, DMI is also a target.
+**/
+VOID
+PsfConfigureMctpCycle (
+  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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h
new file mode 100644
index 0000000000..313b13060f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h
@@ -0,0 +1,98 @@
+/** @file
+  PCH Smbus Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SMBUS_COMMON_LIB_H
+#define _PCH_SMBUS_COMMON_LIB_H
+
+//
+// Definitions
+//
+#define SMBUS_NUM_RESERVED          38      ///< Number of device addresses that are reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP           0xC2 >> 1
+#define SMBUS_DATA_PREPARE_TO_ARP   0x01
+#define SMBUS_DATA_RESET_DEVICE     0x02
+#define SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define SMBUS_DATA_ASSIGN_ADDRESS   0x04
+#define SMBUS_GET_UDID_LENGTH       17      ///< 16 byte UDID + 1 byte address
+//
+// Private data and functions
+//
+
+#define PCH_SMBUS_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('p', 's', 'm', 'b')
+
+/**
+  This function provides a standard way to read PCH Smbus IO registers.
+
+  @param[in] Offset               Register offset from Smbus base IO address.
+
+  @retval UINT8                   Returns data read from IO.
+**/
+UINT8
+SmbusIoRead (
+  IN      UINT8           Offset
+  );
+
+/**
+  This function provides a standard way to write PCH Smbus IO registers.
+
+  @param[in] Offset               Register offset from Smbus base IO address.
+  @param[in] Data                 Data to write to register.
+
+**/
+VOID
+SmbusIoWrite (
+  IN      UINT8           Offset,
+  IN      UINT8           Data
+  );
+
+/**
+  This function provides a standard way to execute Smbus protocols
+  as defined in the SMBus Specification. The data can either be of
+  the Length byte, word, or a block of data. The resulting transaction will be
+  either the SMBus Slave Device accepts this transaction or this function
+  returns with an error
+
+  @param[in] SlaveAddress         Smbus Slave device the command is directed at
+  @param[in] Command              Slave Device dependent
+  @param[in] Operation            Which SMBus protocol will be used
+  @param[in] PecCheck             Defines if Packet Error Code Checking is to be used
+  @param[in, out] Length          How many bytes to read. Must be 0 <= Length <= 32 depending on Operation
+                                  It will contain the actual number of bytes read/written.
+  @param[in, out] Buffer          Contain the data read/written.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @exception EFI_UNSUPPORTED      The operation is unsupported.
+
+  @retval EFI_INVALID_PARAMETER   Length or Buffer is NULL for any operation besides
+                                  quick read or quick write.
+  @retval EFI_TIMEOUT             The transaction did not complete within an internally
+                                  specified timeout period, or the controller is not
+                                  available for use.
+  @retval EFI_DEVICE_ERROR        There was an Smbus error (NACK) during the operation.
+                                  This could indicate the slave device is not present
+                                  or is in a hung condition.
+**/
+EFI_STATUS
+SmbusExec (
+  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN      EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN      EFI_SMBUS_OPERATION       Operation,
+  IN      BOOLEAN                   PecCheck,
+  IN OUT  UINTN                     *Length,
+  IN OUT  VOID                      *Buffer
+  );
+
+/**
+  This function initializes the Smbus Registers.
+
+**/
+VOID
+InitializeSmbusRegisters (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..0a973a77a3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h
@@ -0,0 +1,366 @@
+/** @file
+  Header file for the PCH SPI Common Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_COMMON_LIB_H_
+#define _PCH_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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h
new file mode 100644
index 0000000000..301ec3dd48
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h
@@ -0,0 +1,25 @@
+/** @file
+  This file contains PEI DMI methods
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_DMI_LIB_H_
+#define _PEI_PCH_DMI_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+//
+// Data structure definitions
+//
+typedef enum {
+  DmiVcTypeVc0,
+  DmiVcTypeVc1,
+  DmiVcTypeVcm,
+  DmiVcTypeMax
+} PCH_DMI_VC_TYPE;
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h
new file mode 100644
index 0000000000..44e7567e0f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h
@@ -0,0 +1,706 @@
+/** @file
+  Header file for private PmcLib.
+
+  Copyright (c) 2019 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/PchRegsPmc.h>
+
+/**
+  Send PMC IPC1 Normal Read/Write command
+
+  @param[in]  Command           Command to be issued to PMC IPC 1 interface
+  @param[in]  SubCmdId          SUB_CMD_ID for provided Command
+  @param[in]  CmdSize           Total size in byte to be sent via PMC IPC 1 interface
+  @param[in]  WriteBufPtr       Pointer to Structure of 4 DWORDs to be issued to PMC IPC 1 interface
+  @param[out] ReadBufPtr        Pointer to Structure of 4 DWORDs to be filled by PMC IPC 1 interface
+
+  @retval EFI_SUCCESS             Command was executed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid command size
+  @retval EFI_DEVICE_ERROR        IPC command failed with an error
+  @retval EFI_TIMEOUT             IPC command did not complete after 1s
+**/
+EFI_STATUS
+PmcSendCommand (
+  IN  UINT8                    Command,
+  IN  UINT8                    SubCmdId,
+  IN  UINT8                    CmdSize,
+  IN  PMC_IPC_COMMAND_BUFFER   *WriteBufPtr,
+  OUT PMC_IPC_COMMAND_BUFFER   *ReadBufPtr
+  );
+
+/**
+  Set PCH ACPI base address.
+  The Address should not be 0 and should be 256 bytes alignment, and it is IO space, so must not exceed 0xFFFF.
+
+  @param[in] Address                    Address for ACPI base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PmcSetAcpiBase (
+  IN  UINT16                            Address
+  );
+
+/**
+  Set PCH PWRM base address.
+  Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for PWRMBASE
+
+  @param[in] Address                    Address for PWRM base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PmcSetPwrmBase (
+  IN  UINT32                            Address
+  );
+
+/**
+  This function checks if function disable (static and non-static power gating)
+  configuration is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsFunctionDisableConfigLocked (
+  VOID
+  );
+
+/**
+  This function locks static power gating configuration with S3 Boot Script programming
+**/
+VOID
+PmcLockFunctionDisableConfigWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function checks if ISH is function disabled
+  by static power gating
+
+  @retval ISH device state
+**/
+BOOLEAN
+PmcIsIshFunctionDisabled (
+  VOID
+  );
+
+/**
+  This function checks if ISH device is supported (not disabled by fuse)
+
+  @retval ISH support state
+**/
+BOOLEAN
+PmcIsIshSupported (
+  VOID
+  );
+
+/**
+  This function disables ISH device by static power gating
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableIsh (
+  VOID
+  );
+
+/**
+  This function enables ISH device by disabling static power gating
+**/
+VOID
+PmcEnableIsh (
+  VOID
+  );
+
+/**
+  This function enables GBE ModPHY SPD gating.
+**/
+VOID
+PmcGbeModPhyPowerGating (
+  VOID
+  );
+
+/**
+  This function checks if GbE is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsGbeFunctionDisabled (
+  VOID
+  );
+
+/**
+  This function disables GbE device by static power gating
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableGbe (
+  VOID
+  );
+
+/**
+  This function enables GbE device by disabling static power gating
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableGbe (
+  VOID
+  );
+
+/**
+  This function checks if GbE device is supported (not disabled by fuse)
+
+  @retval GbE support state
+**/
+BOOLEAN
+PmcIsGbeSupported (
+  VOID
+  );
+
+/**
+  This function enables all SerailIo devices
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableSerialIo (
+  VOID
+  );
+
+/**
+  This function disables (static power gating) all SerailIo devices.
+  For SerialIo controllers they can be power gated only if all of them are to be disabled.
+  They cannot be statically power gated separately.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableSerialIo (
+  VOID
+  );
+
+/**
+  This function checks if all SerialIo devices are statically disabled (static power gating)
+
+  @retval SerialIo disable state
+**/
+BOOLEAN
+PmcIsSerialIoStaticallyDisabled (
+  VOID
+  );
+
+/**
+  This function checks if SerialIo device is supported (not disabled by fuse)
+
+  @retval SerialIo support state
+**/
+BOOLEAN
+PmcIsSerialIoSupported (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) HDA device
+**/
+VOID
+PmcDisableHda (
+  VOID
+  );
+
+/**
+  This function checks if Cnvi device is supported (not disabled by fuse)
+
+  @retval Cnvi support state
+**/
+BOOLEAN
+PmcIsCnviSupported (
+  VOID
+  );
+
+/**
+  This function checks if CNVi is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsCnviFunctionDisabled (
+  VOID
+  );
+
+/**
+  This function enables CNVi device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableCnvi (
+  VOID
+  );
+
+/**
+  This function disables CNVi device by static power gating
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableCnvi (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) PCIe Root Port
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+**/
+VOID
+PmcDisablePcieRootPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  This function disables (non-static power gating) SATA
+
+  @param[in]  SataCtrlIndex     SATA controller index
+**/
+VOID
+PmcDisableSata (
+  IN UINT32     SataCtrlIndex
+  );
+
+/**
+  This function checks if SATA device is supported (not disabled by fuse)
+
+  @param[in] SataCtrlIndex SATA controller index
+
+  @retval SATA support state
+**/
+BOOLEAN
+PmcIsSataSupported (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  This function gets NMI regsiter.
+
+  @retval  NMI register setting
+**/
+UINT32
+PmcGetNmiControl (
+  VOID
+  );
+
+/**
+  This function sets the NMI register
+
+  @param[in]  NmiRegister    The whole NMI register
+**/
+VOID
+PmcSetNmiControl (
+  UINT32   NmiRegister
+  );
+
+/**
+  This function disables (non-static power gating) xHCI
+**/
+VOID
+PmcDisableXhci (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) XDCI
+**/
+VOID
+PmcDisableXdci (
+  VOID
+  );
+
+/**
+  This function checks if XDCI device is supported (not disabled by fuse)
+
+  @retval XDCI support state
+**/
+BOOLEAN
+PmcIsXdciSupported (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) SCS eMMC controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsEmmc (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) SCS SD Card controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsSdCard (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) SCS UFS controller and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in] UfsNum     SCS UFS Device
+**/
+VOID
+PmcDisableScsUfs (
+  IN UINT32   UfsNum
+  );
+
+/**
+  This function checks if SCS eMMC device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsEmmcSupported (
+  VOID
+  );
+
+/**
+  This function checks if SCS SD Card device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsSdCardSupported (
+  VOID
+  );
+
+/**
+  This function checks if SCS UFS device is supported (not disabled by fuse)
+
+  @param[in] UfsNum     SCS UFS Device
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsUfsSupported (
+  IN UINT32   UfsNum
+  );
+
+
+/**
+  This function locks HOST SW power gating control
+**/
+VOID
+PmcLockHostSwPgCtrl (
+  VOID
+  );
+
+/**
+  This function checks if HOST SW Power Gating Control is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsHostSwPgCtrlLocked (
+  VOID
+  );
+
+/**
+  This function disables Trace Hub by enabling power gating
+**/
+VOID
+PmcDisableTraceHub (
+  VOID
+  );
+
+/**
+  This function enables Trace Hub by disabling power gating
+**/
+VOID
+PmcEnableTraceHub (
+  VOID
+  );
+
+/**
+  This function checks if LAN wake from DeepSx is enabled
+
+  @retval Lan Wake state
+**/
+BOOLEAN
+PmcIsLanDeepSxWakeEnabled (
+  VOID
+  );
+
+/**
+  This function locks down PMC (DebugModeLock)
+**/
+VOID
+PmcLockWithS3BootScript (
+  VOID
+  );
+
+/**
+  Checks if conditions for proper USB2 PHY AFE programming are met
+**/
+VOID
+PmcUsb2CorePhyPowerGatingDisable (
+  VOID
+  );
+
+/**
+  This function reads CPU Early Power-on Configuration (EPOC)
+
+  @retval CPU EPOC value
+**/
+UINT32
+PmcGetCpuEpoc (
+  VOID
+  );
+
+/**
+  This function sets CPU Early Power-on Configuration (EPOC)
+
+  @param[in] CpuEpocValue      CPU EPOC value
+**/
+VOID
+PmcSetCpuEpoc (
+  IN UINT32     CpuEpocValue
+  );
+
+/**
+  This function sets DRAM_RESET# Control Pin value
+
+  @param[in] DramResetVal      0: Pin output is low
+                               1: Pin output is tri-stated
+**/
+VOID
+PmcSetDramResetCtlState (
+  IN UINT32     DramResetVal
+  );
+
+/**
+  This function enables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh
+**/
+VOID
+PmcEnableCf9GlobalReset (
+  VOID
+  );
+
+/**
+  This function disables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh.
+**/
+VOID
+PmcDisableCf9GlobalReset (
+  VOID
+  );
+
+/**
+  This 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
+PmcDisableCf9GlobalResetWithLock (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  This function disables CF9 reset without Resume Well reset.
+  Cf9 0x6/0xE reset will also reset resume well logic.
+**/
+VOID
+PmcDisableCf9ResetWithoutResumeWell (
+  VOID
+  );
+
+/**
+  This function locks PMC Set Strap Message interface with S3 Boot Script programming
+**/
+VOID
+PmcLockSetStrapMsgInterfaceWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function clears RTC Power Failure status (RTC_PWR_FLR)
+**/
+VOID
+PmcClearRtcPowerFailureStatus (
+  VOID
+  );
+
+/**
+  This function enables PCI Express* PME events
+**/
+VOID
+PmcEnablePciExpressPmeEvents (
+  VOID
+  );
+
+/**
+  This function sets SLP_SX Stretching Policy and adds
+  lock setting to S3 Boot Script
+**/
+VOID
+PmcLockSlpSxStretchingPolicyWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function sets SMI Lock with S3 Boot Script programming
+**/
+VOID
+PmcLockSmiWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function sets eSPI SMI Lock
+**/
+VOID
+PmcLockEspiSmi (
+  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
+  );
+
+/**
+  This function sets 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
+PmcSetGpioGpe (
+  IN UINT32    GpeDw0Value,
+  IN UINT32    GpeDw1Value,
+  IN UINT32    GpeDw2Value
+  );
+
+/**
+  This function checks if SCI interrupt is enabled
+
+  @retval SCI Enable state
+**/
+BOOLEAN
+PmcIsSciEnabled (
+  VOID
+  );
+
+/**
+  This function triggers Software GPE
+**/
+VOID
+PmcTriggerSwGpe (
+  VOID
+  );
+
+/**
+  Disable SLP_S0# assertion when system is in debug mode
+**/
+VOID
+PmcDisableSlpS0AssertionInDebugMode (
+  VOID
+  );
+
+/**
+  Enable SLP_S0# assertion even when system is in debug mode
+**/
+VOID
+PmcEnableSlpS0AssertionInDebugMode (
+  VOID
+  );
+
+#endif // _PMC_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h
new file mode 100644
index 0000000000..af5734b74b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h
@@ -0,0 +1,48 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h
new file mode 100644
index 0000000000..f074e0073a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h
@@ -0,0 +1,28 @@
+/** @file
+  Header file for private PCH SMM Lib.
+
+  Copyright (c) 2019 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_
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (9 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:10   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
                   ` (26 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds the following header files:
 * Pch/Include/Private/Protocol

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h | 31 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h | 37 ++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h
new file mode 100644
index 0000000000..75003c82ad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h
@@ -0,0 +1,31 @@
+/** @file
+  This file defines the PCH NVS Area Protocol.
+
+  Copyright (c) 2019 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 <Private/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/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h
new file mode 100644
index 0000000000..2cd6b85d29
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h
@@ -0,0 +1,37 @@
+/** @file
+  This file defines the PCH PCIE IoTrap Protocol.
+
+  Copyright (c) 2019 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 {
+  PciePmTrap,
+  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
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (10 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
                   ` (25 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds header files common to silicon Sample Code.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h                     |   82 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h  |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h      | 1513 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h |  118 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h            |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h         |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h    |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h        |   80 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h                 |  137 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h                |   87 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h          |   33 +
 11 files changed, 2213 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h
new file mode 100644
index 0000000000..829d1190fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h
@@ -0,0 +1,82 @@
+/** @file
+  Prototype of SEC Platform hook library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef  _SEC_PLATFORM_LIB_H_
+#define  _SEC_PLATFORM_LIB_H_
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+
+/**
+  A developer supplied function to perform platform specific operations.
+
+  It's a developer supplied function to perform any operations appropriate to a
+  given platform. It's invoked just before passing control to PEI core by SEC
+  core. Platform developer may modify the SecCoreData passed to PEI Core.
+  It returns a platform specific PPI list that platform wishes to pass to PEI core.
+  The Generic SEC core module will merge this list to join the final list passed to
+  PEI core.
+
+  @param  SecCoreData           The same parameter as passing to PEI core. It
+                                could be overridden by this function.
+
+  @return The platform specific PPI list to be passed to PEI core or
+          NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
+  );
+
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param  PeiServices               Pointer to the PEI Services Table.
+  @param  StructureSize             Pointer to the variable describing size of the input buffer.
+  @param  PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  );
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval     EFI_SUCCESS  The data was successfully returned.
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  );
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h
new file mode 100644
index 0000000000..862a7c8aea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h
@@ -0,0 +1,51 @@
+/** @file
+  Definition of GUIDed HOB for reserving SMRAM regions.
+
+  This file defines:
+  * the GUID used to identify the GUID HOB for reserving SMRAM regions.
+  * the data structure of SMRAM descriptor to describe SMRAM candidate regions
+  * values of state of SMRAM candidate regions
+  * the GUID specific data structure of HOB for reserving SMRAM regions.
+  This GUIDed HOB can be used to convey the existence of the T-SEG reservation and H-SEG usage
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_
+#define _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_
+
+#define EFI_SMM_PEI_SMRAM_MEMORY_RESERVE \
+  { \
+    0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d } \
+  }
+
+/**
+* GUID specific data structure of HOB for reserving SMRAM regions.
+*
+* Inconsistent with specification here:
+* EFI_HOB_SMRAM_DESCRIPTOR_BLOCK has been changed to EFI_SMRAM_HOB_DESCRIPTOR_BLOCK.
+* This inconsistency is kept in code in order for backward compatibility.
+**/
+typedef struct {
+  ///
+  /// Designates the number of possible regions in the system
+  /// that can be usable for SMRAM.
+  ///
+  /// Inconsistent with specification here:
+  /// In Framework SMM CIS 0.91 specification, it defines the field type as UINTN.
+  /// However, HOBs are supposed to be CPU neutral, so UINT32 should be used instead.
+  ///
+  UINT32                NumberOfSmmReservedRegions;
+  ///
+  /// Used throughout this protocol to describe the candidate
+  /// regions for SMRAM that are supported by this platform.
+  ///
+  EFI_SMRAM_DESCRIPTOR  Descriptor[1];
+} EFI_SMRAM_HOB_DESCRIPTOR_BLOCK;
+
+extern EFI_GUID gEfiSmmPeiSmramMemoryReserveGuid;
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h
new file mode 100644
index 0000000000..6ba23381b0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h
@@ -0,0 +1,1513 @@
+/** @file
+  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage
+  under EFI and Legacy OS boot.  This file also includes all the related
+  COMPATIBILIY16 structures and defintions.
+
+  Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow
+  well known naming conventions.
+
+  Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode
+  environment. Reverse thunk is the code that does the opposite.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _EFI_LEGACY_BIOS_H_
+#define _EFI_LEGACY_BIOS_H_
+
+///
+///
+///
+#pragma pack(1)
+
+typedef UINT8                       SERIAL_MODE;
+typedef UINT8                       PARALLEL_MODE;
+
+#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$')
+
+///
+/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx
+/// physical address range. It is located on a 16-byte boundary and provides the physical address of the
+/// entry point for the Compatibility16 functions. These functions provide the platform-specific
+/// information that is required by the generic EfiCompatibility code. The functions are invoked via
+/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical
+/// entry point.
+///
+typedef struct {
+  ///
+  /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte
+  /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32.
+  ///
+  UINT32                            Signature;
+
+  ///
+  /// The value required such that byte checksum of TableLength equals zero.
+  ///
+  UINT8                             TableChecksum;
+
+  ///
+  /// The length of this table.
+  ///
+  UINT8                             TableLength;
+
+  ///
+  /// The major EFI revision for which this table was generated.
+  ///
+  UINT8                             EfiMajorRevision;
+
+  ///
+  /// The minor EFI revision for which this table was generated.
+  ///
+  UINT8                             EfiMinorRevision;
+
+  ///
+  /// The major revision of this table.
+  ///
+  UINT8                             TableMajorRevision;
+
+  ///
+  /// The minor revision of this table.
+  ///
+  UINT8                             TableMinorRevision;
+
+  ///
+  /// Reserved for future usage.
+  ///
+  UINT16                            Reserved;
+
+  ///
+  /// The segment of the entry point within the traditional BIOS for Compatibility16 functions.
+  ///
+  UINT16                            Compatibility16CallSegment;
+
+  ///
+  /// The offset of the entry point within the traditional BIOS for Compatibility16 functions.
+  ///
+  UINT16                            Compatibility16CallOffset;
+
+  ///
+  /// The segment of the entry point within the traditional BIOS for EfiCompatibility
+  /// to invoke the PnP installation check.
+  ///
+  UINT16                            PnPInstallationCheckSegment;
+
+  ///
+  /// The Offset of the entry point within the traditional BIOS for EfiCompatibility
+  /// to invoke the PnP installation check.
+  ///
+  UINT16                            PnPInstallationCheckOffset;
+
+  ///
+  /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform
+  ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS).
+  ///
+  UINT32                            EfiSystemTable;
+
+  ///
+  /// The address of an OEM-provided identifier string. The string is null terminated.
+  ///
+  UINT32                            OemIdStringPointer;
+
+  ///
+  /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional
+  /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size
+  /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI
+  /// RSD PTR with either the ACPI 1.0b or 2.0 values.
+  ///
+  UINT32                            AcpiRsdPtrPointer;
+
+  ///
+  /// The OEM revision number. Usage is undefined but provided for OEM module usage.
+  ///
+  UINT16                            OemRevision;
+
+  ///
+  /// The 32-bit physical address where INT15 E820 data is stored within the traditional
+  /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the
+  /// data to the indicated area.
+  ///
+  UINT32                            E820Pointer;
+
+  ///
+  /// The length of the E820 data and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            E820Length;
+
+  ///
+  /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS.
+  /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and
+  /// copy the data to the indicated area.
+  ///
+  UINT32                            IrqRoutingTablePointer;
+
+  ///
+  /// The length of the $PIR table and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            IrqRoutingTableLength;
+
+  ///
+  /// The 32-bit physical address where the MP table is stored in the traditional BIOS.
+  /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data
+  /// to the indicated area.
+  ///
+  UINT32                            MpTablePtr;
+
+  ///
+  /// The length of the MP table and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            MpTableLength;
+
+  ///
+  /// The segment of the OEM-specific INT table/code.
+  ///
+  UINT16                            OemIntSegment;
+
+  ///
+  /// The offset of the OEM-specific INT table/code.
+  ///
+  UINT16                            OemIntOffset;
+
+  ///
+  /// The segment of the OEM-specific 32-bit table/code.
+  ///
+  UINT16                            Oem32Segment;
+
+  ///
+  /// The offset of the OEM-specific 32-bit table/code.
+  ///
+  UINT16                            Oem32Offset;
+
+  ///
+  /// The segment of the OEM-specific 16-bit table/code.
+  ///
+  UINT16                            Oem16Segment;
+
+  ///
+  /// The offset of the OEM-specific 16-bit table/code.
+  ///
+  UINT16                            Oem16Offset;
+
+  ///
+  /// The segment of the TPM binary passed to 16-bit CSM.
+  ///
+  UINT16                            TpmSegment;
+
+  ///
+  /// The offset of the TPM binary passed to 16-bit CSM.
+  ///
+  UINT16                            TpmOffset;
+
+  ///
+  /// A pointer to a string identifying the independent BIOS vendor.
+  ///
+  UINT32                            IbvPointer;
+
+  ///
+  /// This field is NULL for all systems not supporting PCI Express. This field is the base
+  /// value of the start of the PCI Express memory-mapped configuration registers and
+  /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function
+  /// Compatibility16InitializeYourself().
+  /// Compatibility16InitializeYourself() is defined in Compatability16
+  /// Functions.
+  ///
+  UINT32                            PciExpressBase;
+
+  ///
+  /// Maximum PCI bus number assigned.
+  ///
+  UINT8                             LastPciBus;
+
+  ///
+  /// Start Address of Upper Memory Area (UMA) to be set as Read/Write. If
+  /// UmaAddress is a valid address in the shadow RAM, it also indicates that the region
+  /// from 0xC0000 to (UmaAddress - 1) can be used for Option ROM.
+  ///
+  UINT32                            UmaAddress;
+
+  ///
+  /// Upper Memory Area size in bytes to be set as Read/Write. If zero, no UMA region
+  /// will be set as Read/Write (i.e. all Shadow RAM is set as Read-Only).
+  ///
+  UINT32                            UmaSize;
+
+  ///
+  /// Start Address of high memory that can be used for permanent allocation. If zero,
+  /// high memory is not available for permanent allocation.
+  ///
+  UINT32                            HiPermanentMemoryAddress;
+
+  ///
+  /// Size of high memory that can be used for permanent allocation in bytes. If zero,
+  /// high memory is not available for permanent allocation.
+  ///
+  UINT32                            HiPermanentMemorySize;
+} EFI_COMPATIBILITY16_TABLE;
+
+///
+/// Functions provided by the CSM binary which communicate between the EfiCompatibility
+/// and Compatability16 code.
+///
+/// Inconsistent with the specification here:
+/// The member's name started with "Compatibility16" [defined in Intel Framework
+/// Compatibility Support Module Specification / 0.97 version]
+/// has been changed to "Legacy16" since keeping backward compatible.
+///
+typedef enum {
+  ///
+  /// Causes the Compatibility16 code to do any internal initialization required.
+  /// Input:
+  ///   AX = Compatibility16InitializeYourself
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE
+  /// Return:
+  ///   AX = Return Status codes
+  ///
+  Legacy16InitializeYourself    = 0x0000,
+
+  ///
+  /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence.
+  /// Input:
+  ///   AX = Compatibility16UpdateBbs
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
+  /// Return:
+  ///   AX = Returned status codes
+  ///
+  Legacy16UpdateBbs             = 0x0001,
+
+  ///
+  /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16
+  /// code is read/write.
+  /// Input:
+  ///   AX = Compatibility16PrepareToBoot
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure
+  /// Return:
+  ///   AX = Returned status codes
+  ///
+  Legacy16PrepareToBoot         = 0x0002,
+
+  ///
+  /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only.
+  /// Input:
+  ///   AX = Compatibility16Boot
+  /// Output:
+  ///   AX = Returned status codes
+  ///
+  Legacy16Boot                  = 0x0003,
+
+  ///
+  /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is
+  /// stored in CMOS and is the priority number of the last attempted boot device.
+  /// Input:
+  ///   AX = Compatibility16RetrieveLastBootDevice
+  /// Output:
+  ///   AX = Returned status codes
+  ///   BX = Priority number of the boot device.
+  ///
+  Legacy16RetrieveLastBootDevice = 0x0004,
+
+  ///
+  /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM.
+  /// Input:
+  ///   AX = Compatibility16DispatchOprom
+  ///   ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE
+  /// Output:
+  ///   AX = Returned status codes
+  ///   BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant.
+  ///
+  Legacy16DispatchOprom         = 0x0005,
+
+  ///
+  /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address
+  /// of that region.
+  /// Input:
+  ///   AX = Compatibility16GetTableAddress
+  ///   BX = Allocation region
+  ///       00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.
+  ///       Bit 0 = 1 Allocate from 0xF0000 64 KB block
+  ///       Bit 1 = 1 Allocate from 0xE0000 64 KB block
+  ///   CX = Requested length in bytes.
+  ///   DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment.
+  /// Output:
+  ///   AX = Returned status codes
+  ///   DS:BX = Address of the region
+  ///
+  Legacy16GetTableAddress       = 0x0006,
+
+  ///
+  /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state.
+  /// Input:
+  ///   AX = Compatibility16SetKeyboardLeds
+  ///   CL = LED status.
+  ///     Bit 0  Scroll Lock 0 = Off
+  ///     Bit 1  NumLock
+  ///     Bit 2  Caps Lock
+  /// Output:
+  ///     AX = Returned status codes
+  ///
+  Legacy16SetKeyboardLeds       = 0x0007,
+
+  ///
+  /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that
+  /// do not have an OpROM associated with them. An example is SATA.
+  /// Input:
+  ///   AX = Compatibility16InstallPciHandler
+  ///   ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure
+  /// Output:
+  ///   AX = Returned status codes
+  ///
+  Legacy16InstallPciHandler     = 0x0008
+} EFI_COMPATIBILITY_FUNCTIONS;
+
+
+///
+/// EFI_DISPATCH_OPROM_TABLE
+///
+typedef struct {
+  UINT16  PnPInstallationCheckSegment;  ///< A pointer to the PnpInstallationCheck data structure.
+  UINT16  PnPInstallationCheckOffset;   ///< A pointer to the PnpInstallationCheck data structure.
+  UINT16  OpromSegment;                 ///< The segment where the OpROM was placed. Offset is assumed to be 3.
+  UINT8   PciBus;                       ///< The PCI bus.
+  UINT8   PciDeviceFunction;            ///< The PCI device * 0x08 | PCI function.
+  UINT8   NumberBbsEntries;             ///< The number of valid BBS table entries upon entry and exit. The IBV code may
+                                        ///< increase this number, if BBS-compliant devices also hook INTs in order to force the
+                                        ///< OpROM BIOS Setup to be executed.
+  UINT32  BbsTablePointer;              ///< A pointer to the BBS table.
+  UINT16  RuntimeSegment;               ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this
+                                        ///< means that the relocation of this run time code is not supported.
+                                        ///< Inconsistent with specification here:
+                                        ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version]
+                                        ///< has been changed to "RuntimeSegment" since keeping backward compatible.
+
+} EFI_DISPATCH_OPROM_TABLE;
+
+///
+/// EFI_TO_COMPATIBILITY16_INIT_TABLE
+///
+typedef struct {
+  ///
+  /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF.
+  ///
+  UINT32                            BiosLessThan1MB;
+
+  ///
+  /// The starting address of the high memory block.
+  ///
+  UINT32                            HiPmmMemory;
+
+  ///
+  /// The length of high memory block.
+  ///
+  UINT32                            HiPmmMemorySizeInBytes;
+
+  ///
+  /// The segment of the reverse thunk call code.
+  ///
+  UINT16                            ReverseThunkCallSegment;
+
+  ///
+  /// The offset of the reverse thunk call code.
+  ///
+  UINT16                            ReverseThunkCallOffset;
+
+  ///
+  /// The number of E820 entries copied to the Compatibility16 BIOS.
+  ///
+  UINT32                            NumberE820Entries;
+
+  ///
+  /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory.
+  ///
+  UINT32                            OsMemoryAbove1Mb;
+
+  ///
+  /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM.
+  ///
+  UINT32                            ThunkStart;
+
+  ///
+  /// The size of the thunk code.
+  ///
+  UINT32                            ThunkSizeInBytes;
+
+  ///
+  /// Starting address of memory under 1 MB.
+  ///
+  UINT32                            LowPmmMemory;
+
+  ///
+  /// The length of low Memory block.
+  ///
+  UINT32                            LowPmmMemorySizeInBytes;
+} EFI_TO_COMPATIBILITY16_INIT_TABLE;
+
+///
+/// DEVICE_PRODUCER_SERIAL.
+///
+typedef struct {
+  UINT16                            Address;    ///< I/O address assigned to the serial port.
+  UINT8                             Irq;        ///< IRQ assigned to the serial port.
+  SERIAL_MODE                       Mode;       ///< Mode of serial port. Values are defined below.
+} DEVICE_PRODUCER_SERIAL;
+
+///
+/// DEVICE_PRODUCER_SERIAL's modes.
+///@{
+#define DEVICE_SERIAL_MODE_NORMAL               0x00
+#define DEVICE_SERIAL_MODE_IRDA                 0x01
+#define DEVICE_SERIAL_MODE_ASK_IR               0x02
+#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00
+#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10
+///@)
+
+///
+/// DEVICE_PRODUCER_PARALLEL.
+///
+typedef struct {
+  UINT16                            Address;  ///< I/O address assigned to the parallel port.
+  UINT8                             Irq;      ///< IRQ assigned to the parallel port.
+  UINT8                             Dma;      ///< DMA assigned to the parallel port.
+  PARALLEL_MODE                     Mode;     ///< Mode of the parallel port. Values are defined below.
+} DEVICE_PRODUCER_PARALLEL;
+
+///
+/// DEVICE_PRODUCER_PARALLEL's modes.
+///@{
+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00
+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01
+#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02
+#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03
+///@}
+
+///
+/// DEVICE_PRODUCER_FLOPPY
+///
+typedef struct {
+  UINT16                            Address;          ///< I/O address assigned to the floppy.
+  UINT8                             Irq;              ///< IRQ assigned to the floppy.
+  UINT8                             Dma;              ///< DMA assigned to the floppy.
+  UINT8                             NumberOfFloppy;   ///< Number of floppies in the system.
+} DEVICE_PRODUCER_FLOPPY;
+
+///
+/// LEGACY_DEVICE_FLAGS
+///
+typedef struct {
+  UINT32                            A20Kybd : 1;      ///< A20 controller by keyboard controller.
+  UINT32                            A20Port90 : 1;    ///< A20 controlled by port 0x92.
+  UINT32                            Reserved : 30;    ///< Reserved for future usage.
+} LEGACY_DEVICE_FLAGS;
+
+///
+/// DEVICE_PRODUCER_DATA_HEADER
+///
+typedef struct {
+  DEVICE_PRODUCER_SERIAL            Serial[4];      ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below.
+  DEVICE_PRODUCER_PARALLEL          Parallel[3];    ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below.
+  DEVICE_PRODUCER_FLOPPY            Floppy;         ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below.
+  UINT8                             MousePresent;   ///< Flag to indicate if mouse is present.
+  LEGACY_DEVICE_FLAGS               Flags;          ///< Miscellaneous Boolean state information passed to CSM.
+} DEVICE_PRODUCER_DATA_HEADER;
+
+///
+/// ATAPI_IDENTIFY
+///
+typedef struct {
+  UINT16                            Raw[256];     ///< Raw data from the IDE IdentifyDrive command.
+} ATAPI_IDENTIFY;
+
+///
+/// HDD_INFO
+///
+typedef struct {
+  ///
+  /// Status of IDE device. Values are defined below. There is one HDD_INFO structure
+  /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index
+  /// 1 is slave.
+  ///
+  UINT16                            Status;
+
+  ///
+  /// PCI bus of IDE controller.
+  ///
+  UINT32                            Bus;
+
+  ///
+  /// PCI device of IDE controller.
+  ///
+  UINT32                            Device;
+
+  ///
+  /// PCI function of IDE controller.
+  ///
+  UINT32                            Function;
+
+  ///
+  /// Command ports base address.
+  ///
+  UINT16                            CommandBaseAddress;
+
+  ///
+  /// Control ports base address.
+  ///
+  UINT16                            ControlBaseAddress;
+
+  ///
+  /// Bus master address.
+  ///
+  UINT16                            BusMasterAddress;
+
+  UINT8                             HddIrq;
+
+  ///
+  /// Data that identifies the drive data; one per possible attached drive.
+  ///
+  ATAPI_IDENTIFY                    IdentifyDrive[2];
+} HDD_INFO;
+
+///
+/// HDD_INFO status bits
+///
+#define HDD_PRIMARY               0x01
+#define HDD_SECONDARY             0x02
+#define HDD_MASTER_ATAPI_CDROM    0x04
+#define HDD_SLAVE_ATAPI_CDROM     0x08
+#define HDD_MASTER_IDE            0x20
+#define HDD_SLAVE_IDE             0x40
+#define HDD_MASTER_ATAPI_ZIPDISK  0x10
+#define HDD_SLAVE_ATAPI_ZIPDISK   0x80
+
+///
+/// BBS_STATUS_FLAGS;\.
+///
+typedef struct {
+  UINT16                            OldPosition : 4;    ///< Prior priority.
+  UINT16                            Reserved1 : 4;      ///< Reserved for future use.
+  UINT16                            Enabled : 1;        ///< If 0, ignore this entry.
+  UINT16                            Failed : 1;         ///< 0 = Not known if boot failure occurred.
+                                                        ///< 1 = Boot attempted failed.
+
+  ///
+  /// State of media present.
+  ///   00 = No bootable media is present in the device.
+  ///   01 = Unknown if a bootable media present.
+  ///   10 = Media is present and appears bootable.
+  ///   11 = Reserved.
+  ///
+  UINT16                            MediaPresent : 2;
+  UINT16                            Reserved2 : 4;      ///< Reserved for future use.
+} BBS_STATUS_FLAGS;
+
+///
+/// BBS_TABLE, device type values & boot priority values.
+///
+typedef struct {
+  ///
+  /// The boot priority for this boot device. Values are defined below.
+  ///
+  UINT16                            BootPriority;
+
+  ///
+  /// The PCI bus for this boot device.
+  ///
+  UINT32                            Bus;
+
+  ///
+  /// The PCI device for this boot device.
+  ///
+  UINT32                            Device;
+
+  ///
+  /// The PCI function for the boot device.
+  ///
+  UINT32                            Function;
+
+  ///
+  /// The PCI class for this boot device.
+  ///
+  UINT8                             Class;
+
+  ///
+  /// The PCI Subclass for this boot device.
+  ///
+  UINT8                             SubClass;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
+  ///
+  UINT16                            MfgStringOffset;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
+  ///
+  UINT16                            MfgStringSegment;
+
+  ///
+  /// BBS device type. BBS device types are defined below.
+  ///
+  UINT16                            DeviceType;
+
+  ///
+  /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below.
+  ///
+  BBS_STATUS_FLAGS                  StatusFlags;
+
+  ///
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
+  /// BCV devices.
+  ///
+  UINT16                            BootHandlerOffset;
+
+  ///
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
+  /// BCV devices.
+  ///
+  UINT16                            BootHandlerSegment;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing this device.
+  ///
+  UINT16                            DescStringOffset;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing this device.
+  ///
+  UINT16                            DescStringSegment;
+
+  ///
+  /// Reserved.
+  ///
+  UINT32                            InitPerReserved;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq13Handler;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq18Handler;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq19Handler;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq40Handler;
+  UINT8                             AssignedDriveNumber;
+  UINT32                            AdditionalIrq41Handler;
+  UINT32                            AdditionalIrq46Handler;
+  UINT32                            IBV1;
+  UINT32                            IBV2;
+} BBS_TABLE;
+
+///
+/// BBS device type values
+///@{
+#define BBS_FLOPPY              0x01
+#define BBS_HARDDISK            0x02
+#define BBS_CDROM               0x03
+#define BBS_PCMCIA              0x04
+#define BBS_USB                 0x05
+#define BBS_EMBED_NETWORK       0x06
+#define BBS_BEV_DEVICE          0x80
+#define BBS_UNKNOWN             0xff
+///@}
+
+///
+/// BBS boot priority values
+///@{
+#define BBS_DO_NOT_BOOT_FROM    0xFFFC
+#define BBS_LOWEST_PRIORITY     0xFFFD
+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE
+#define BBS_IGNORE_ENTRY        0xFFFF
+///@}
+
+///
+/// SMM_ATTRIBUTES
+///
+typedef struct {
+  ///
+  /// Access mechanism used to generate the soft SMI. Defined types are below. The other
+  /// values are reserved for future usage.
+  ///
+  UINT16                            Type : 3;
+
+  ///
+  /// The size of "port" in bits. Defined values are below.
+  ///
+  UINT16                            PortGranularity : 3;
+
+  ///
+  /// The size of data in bits. Defined values are below.
+  ///
+  UINT16                            DataGranularity : 3;
+
+  ///
+  /// Reserved for future use.
+  ///
+  UINT16                            Reserved : 7;
+} SMM_ATTRIBUTES;
+
+///
+/// SMM_ATTRIBUTES type values.
+///@{
+#define STANDARD_IO       0x00
+#define STANDARD_MEMORY   0x01
+///@}
+
+///
+/// SMM_ATTRIBUTES port size constants.
+///@{
+#define PORT_SIZE_8       0x00
+#define PORT_SIZE_16      0x01
+#define PORT_SIZE_32      0x02
+#define PORT_SIZE_64      0x03
+///@}
+
+///
+/// SMM_ATTRIBUTES data size constants.
+///@{
+#define DATA_SIZE_8       0x00
+#define DATA_SIZE_16      0x01
+#define DATA_SIZE_32      0x02
+#define DATA_SIZE_64      0x03
+///@}
+
+///
+/// SMM_FUNCTION & relating constants.
+///
+typedef struct {
+  UINT16                            Function : 15;
+  UINT16                            Owner : 1;
+} SMM_FUNCTION;
+
+///
+/// SMM_FUNCTION Function constants.
+///@{
+#define INT15_D042        0x0000
+#define GET_USB_BOOT_INFO 0x0001
+#define DMI_PNP_50_57     0x0002
+///@}
+
+///
+/// SMM_FUNCTION Owner constants.
+///@{
+#define STANDARD_OWNER    0x0
+#define OEM_OWNER         0x1
+///@}
+
+///
+/// This structure assumes both port and data sizes are 1. SmmAttribute must be
+/// properly to reflect that assumption.
+///
+typedef struct {
+  ///
+  /// Describes the access mechanism, SmmPort, and SmmData sizes. Type
+  /// SMM_ATTRIBUTES is defined below.
+  ///
+  SMM_ATTRIBUTES                    SmmAttributes;
+
+  ///
+  /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below.
+  ///
+  SMM_FUNCTION                      SmmFunction;
+
+  ///
+  /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
+  ///
+  UINT8                             SmmPort;
+
+  ///
+  /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
+  ///
+  UINT8                             SmmData;
+} SMM_ENTRY;
+
+///
+/// SMM_TABLE
+///
+typedef struct {
+  UINT16                            NumSmmEntries;    ///< Number of entries represented by SmmEntry.
+  SMM_ENTRY                         SmmEntry;         ///< One entry per function. Type SMM_ENTRY is defined below.
+} SMM_TABLE;
+
+///
+/// UDC_ATTRIBUTES
+///
+typedef struct {
+  ///
+  /// This bit set indicates that the ServiceAreaData is valid.
+  ///
+  UINT8                             DirectoryServiceValidity : 1;
+
+  ///
+  /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if
+  /// DirectoryServiceValidity is 0.
+  ///
+  UINT8                             RabcaUsedFlag : 1;
+
+  ///
+  /// This bit set indicates to execute hard disk diagnostics.
+  ///
+  UINT8                             ExecuteHddDiagnosticsFlag : 1;
+
+  ///
+  /// Reserved for future use. Set to 0.
+  ///
+  UINT8                             Reserved : 5;
+} UDC_ATTRIBUTES;
+
+///
+/// UD_TABLE
+///
+typedef struct {
+  ///
+  /// This field contains the bit-mapped attributes of the PARTIES information. Type
+  /// UDC_ATTRIBUTES is defined below.
+  ///
+  UDC_ATTRIBUTES                    Attributes;
+
+  ///
+  /// This field contains the zero-based device on which the selected
+  /// ServiceDataArea is present. It is 0 for master and 1 for the slave device.
+  ///
+  UINT8                             DeviceNumber;
+
+  ///
+  /// This field contains the zero-based index into the BbsTable for the parent device.
+  /// This index allows the user to reference the parent device information such as PCI
+  /// bus, device function.
+  ///
+  UINT8                             BbsTableEntryNumberForParentDevice;
+
+  ///
+  /// This field contains the zero-based index into the BbsTable for the boot entry.
+  ///
+  UINT8                             BbsTableEntryNumberForBoot;
+
+  ///
+  /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry.
+  ///
+  UINT8                             BbsTableEntryNumberForHddDiag;
+
+  ///
+  /// The raw Beer data.
+  ///
+  UINT8                             BeerData[128];
+
+  ///
+  /// The raw data of selected service area.
+  ///
+  UINT8                             ServiceAreaData[64];
+} UD_TABLE;
+
+#define EFI_TO_LEGACY_MAJOR_VERSION 0x02
+#define EFI_TO_LEGACY_MINOR_VERSION 0x00
+#define MAX_IDE_CONTROLLER          8
+
+///
+/// EFI_TO_COMPATIBILITY16_BOOT_TABLE
+///
+typedef struct {
+  UINT16                            MajorVersion;                 ///< The EfiCompatibility major version number.
+  UINT16                            MinorVersion;                 ///< The EfiCompatibility minor version number.
+  UINT32                            AcpiTable;                    ///< The location of the RSDT ACPI table. < 4G range.
+  UINT32                            SmbiosTable;                  ///< The location of the SMBIOS table in EFI memory. < 4G range.
+  UINT32                            SmbiosTableLength;
+  //
+  // Legacy SIO state
+  //
+  DEVICE_PRODUCER_DATA_HEADER       SioData;                      ///< Standard traditional device information.
+  UINT16                            DevicePathType;               ///< The default boot type.
+  UINT16                            PciIrqMask;                   ///< Mask of which IRQs have been assigned to PCI.
+  UINT32                            NumberE820Entries;            ///< Number of E820 entries. The number can change from the
+                                                                  ///< Compatibility16InitializeYourself() function.
+  //
+  // Controller & Drive Identify[2] per controller information
+  //
+  HDD_INFO                          HddInfo[MAX_IDE_CONTROLLER];  ///< Hard disk drive information, including raw Identify Drive data.
+  UINT32                            NumberBbsEntries;             ///< Number of entries in the BBS table
+  UINT32                            BbsTable;                     ///< A pointer to the BBS table. Type BBS_TABLE is defined below.
+  UINT32                            SmmTable;                     ///< A pointer to the SMM table. Type SMM_TABLE is defined below.
+  UINT32                            OsMemoryAbove1Mb;             ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can
+                                                                  ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more
+                                                                  ///< memory may have been discovered.
+  UINT32                            UnconventionalDeviceTable;    ///< Information to boot off an unconventional device like a PARTIES partition. Type
+                                                                  ///< UD_TABLE is defined below.
+} EFI_TO_COMPATIBILITY16_BOOT_TABLE;
+
+///
+/// EFI_LEGACY_INSTALL_PCI_HANDLER
+///
+typedef struct {
+  UINT8                             PciBus;             ///< The PCI bus of the device.
+  UINT8                             PciDeviceFun;       ///< The PCI device in bits 7:3 and function in bits 2:0.
+  UINT8                             PciSegment;         ///< The PCI segment of the device.
+  UINT8                             PciClass;           ///< The PCI class code of the device.
+  UINT8                             PciSubclass;        ///< The PCI subclass code of the device.
+  UINT8                             PciInterface;       ///< The PCI interface code of the device.
+  //
+  // Primary section
+  //
+  UINT8                             PrimaryIrq;         ///< The primary device IRQ.
+  UINT8                             PrimaryReserved;    ///< Reserved.
+  UINT16                            PrimaryControl;     ///< The primary device control I/O base.
+  UINT16                            PrimaryBase;        ///< The primary device I/O base.
+  UINT16                            PrimaryBusMaster;   ///< The primary device bus master I/O base.
+  //
+  // Secondary Section
+  //
+  UINT8                             SecondaryIrq;       ///< The secondary device IRQ.
+  UINT8                             SecondaryReserved;  ///< Reserved.
+  UINT16                            SecondaryControl;   ///< The secondary device control I/O base.
+  UINT16                            SecondaryBase;      ///< The secondary device I/O base.
+  UINT16                            SecondaryBusMaster; ///< The secondary device bus master I/O base.
+} EFI_LEGACY_INSTALL_PCI_HANDLER;
+
+//
+// Restore default pack value
+//
+#pragma pack()
+
+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \
+  { \
+    0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \
+  }
+
+typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL;
+
+///
+/// Flags returned by CheckPciRom().
+///
+#define NO_ROM            0x00
+#define ROM_FOUND         0x01
+#define VALID_LEGACY_ROM  0x02
+#define ROM_WITH_CONFIG   0x04     ///< Not defined in the Framework CSM Specification.
+
+///
+/// The following macros do not appear in the Framework CSM Specification and
+/// are kept for backward compatibility only.  They convert 32-bit address (_Adr)
+/// to Segment:Offset 16-bit form.
+///
+///@{
+#define EFI_SEGMENT(_Adr)     (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)
+#define EFI_OFFSET(_Adr)      (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)
+///@}
+
+#define CARRY_FLAG            0x01
+
+///
+/// EFI_EFLAGS_REG
+///
+typedef struct {
+  UINT32 CF:1;
+  UINT32 Reserved1:1;
+  UINT32 PF:1;
+  UINT32 Reserved2:1;
+  UINT32 AF:1;
+  UINT32 Reserved3:1;
+  UINT32 ZF:1;
+  UINT32 SF:1;
+  UINT32 TF:1;
+  UINT32 IF:1;
+  UINT32 DF:1;
+  UINT32 OF:1;
+  UINT32 IOPL:2;
+  UINT32 NT:1;
+  UINT32 Reserved4:2;
+  UINT32 VM:1;
+  UINT32 Reserved5:14;
+} EFI_EFLAGS_REG;
+
+///
+/// EFI_DWORD_REGS
+///
+typedef struct {
+    UINT32           EAX;
+    UINT32           EBX;
+    UINT32           ECX;
+    UINT32           EDX;
+    UINT32           ESI;
+    UINT32           EDI;
+    EFI_EFLAGS_REG   EFlags;
+    UINT16           ES;
+    UINT16           CS;
+    UINT16           SS;
+    UINT16           DS;
+    UINT16           FS;
+    UINT16           GS;
+    UINT32           EBP;
+    UINT32           ESP;
+} EFI_DWORD_REGS;
+
+///
+/// EFI_FLAGS_REG
+///
+typedef struct {
+  UINT16     CF:1;
+  UINT16     Reserved1:1;
+  UINT16     PF:1;
+  UINT16     Reserved2:1;
+  UINT16     AF:1;
+  UINT16     Reserved3:1;
+  UINT16     ZF:1;
+  UINT16     SF:1;
+  UINT16     TF:1;
+  UINT16     IF:1;
+  UINT16     DF:1;
+  UINT16     OF:1;
+  UINT16     IOPL:2;
+  UINT16     NT:1;
+  UINT16     Reserved4:1;
+} EFI_FLAGS_REG;
+
+///
+/// EFI_WORD_REGS
+///
+typedef struct {
+    UINT16           AX;
+    UINT16           ReservedAX;
+    UINT16           BX;
+    UINT16           ReservedBX;
+    UINT16           CX;
+    UINT16           ReservedCX;
+    UINT16           DX;
+    UINT16           ReservedDX;
+    UINT16           SI;
+    UINT16           ReservedSI;
+    UINT16           DI;
+    UINT16           ReservedDI;
+    EFI_FLAGS_REG    Flags;
+    UINT16           ReservedFlags;
+    UINT16           ES;
+    UINT16           CS;
+    UINT16           SS;
+    UINT16           DS;
+    UINT16           FS;
+    UINT16           GS;
+    UINT16           BP;
+    UINT16           ReservedBP;
+    UINT16           SP;
+    UINT16           ReservedSP;
+} EFI_WORD_REGS;
+
+///
+/// EFI_BYTE_REGS
+///
+typedef struct {
+    UINT8   AL, AH;
+    UINT16  ReservedAX;
+    UINT8   BL, BH;
+    UINT16  ReservedBX;
+    UINT8   CL, CH;
+    UINT16  ReservedCX;
+    UINT8   DL, DH;
+    UINT16  ReservedDX;
+} EFI_BYTE_REGS;
+
+///
+/// EFI_IA32_REGISTER_SET
+///
+typedef union {
+  EFI_DWORD_REGS  E;
+  EFI_WORD_REGS   X;
+  EFI_BYTE_REGS   H;
+} EFI_IA32_REGISTER_SET;
+
+/**
+  Thunk to 16-bit real mode and execute a software interrupt with a vector
+  of BiosInt. Regs will contain the 16-bit register context on entry and
+  exit.
+
+  @param[in]     This      The protocol instance pointer.
+  @param[in]     BiosInt   The processor interrupt vector to invoke.
+  @param[in,out] Reg       Register contexted passed into (and returned) from thunk to
+                           16-bit mode.
+
+  @retval TRUE                Thunk completed with no BIOS errors in the target code. See Regs for status.
+  @retval FALSE                  There was a BIOS error in the target code.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_LEGACY_BIOS_INT86)(
+  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN     UINT8                     BiosInt,
+  IN OUT EFI_IA32_REGISTER_SET     *Regs
+  );
+
+/**
+  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the
+  16-bit register context on entry and exit. Arguments can be passed on
+  the Stack argument
+
+  @param[in] This        The protocol instance pointer.
+  @param[in] Segment     The segemnt of 16-bit mode call.
+  @param[in] Offset      The offset of 16-bit mdoe call.
+  @param[in] Reg         Register contexted passed into (and returned) from thunk to
+                         16-bit mode.
+  @param[in] Stack       The caller allocated stack used to pass arguments.
+  @param[in] StackSize   The size of Stack in bytes.
+
+  @retval FALSE                 Thunk completed with no BIOS errors in the target code.                                See Regs for status.  @retval TRUE                  There was a BIOS error in the target code.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_LEGACY_BIOS_FARCALL86)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UINT16                    Segment,
+  IN UINT16                    Offset,
+  IN EFI_IA32_REGISTER_SET     *Regs,
+  IN VOID                      *Stack,
+  IN UINTN                     StackSize
+  );
+
+/**
+  Test to see if a legacy PCI ROM exists for this device. Optionally return
+  the Legacy ROM instance for this PCI device.
+
+  @param[in]  This        The protocol instance pointer.
+  @param[in]  PciHandle   The PCI PC-AT OPROM from this devices ROM BAR will be loaded
+  @param[out] RomImage    Return the legacy PCI ROM for this device.
+  @param[out] RomSize     The size of ROM Image.
+  @param[out] Flags       Indicates if ROM found and if PC-AT. Multiple bits can be set as follows:
+                            - 00 = No ROM.
+                            - 01 = ROM Found.
+                            - 02 = ROM is a valid legacy ROM.
+
+  @retval EFI_SUCCESS       The Legacy Option ROM available for this device
+  @retval EFI_UNSUPPORTED   The Legacy Option ROM is not supported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN  EFI_HANDLE                PciHandle,
+  OUT VOID                      **RomImage, OPTIONAL
+  OUT UINTN                     *RomSize, OPTIONAL
+  OUT UINTN                     *Flags
+  );
+
+/**
+  Load a legacy PC-AT OPROM on the PciHandle device. Return information
+  about how many disks were added by the OPROM and the shadow address and
+  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:
+
+  @param[in]  This               The protocol instance pointer.
+  @param[in]  PciHandle          The PCI PC-AT OPROM from this devices ROM BAR will be loaded.
+                                 This value is NULL if RomImage is non-NULL. This is the normal
+                                 case.
+  @param[in]  RomImage           A PCI PC-AT ROM image. This argument is non-NULL if there is
+                                 no hardware associated with the ROM and thus no PciHandle,
+                                 otherwise is must be NULL.
+                                 Example is PXE base code.
+  @param[out] Flags              The type of ROM discovered. Multiple bits can be set, as follows:
+                                   - 00 = No ROM.
+                                   - 01 = ROM found.
+                                   - 02 = ROM is a valid legacy ROM.
+  @param[out] DiskStart          The disk number of first device hooked by the ROM. If DiskStart
+                                 is the same as DiskEnd no disked were hooked.
+  @param[out] DiskEnd            disk number of the last device hooked by the ROM.
+  @param[out] RomShadowAddress   Shadow address of PC-AT ROM.
+  @param[out] RomShadowSize      Size of RomShadowAddress in bytes.
+
+  @retval EFI_SUCCESS             Thunk completed, see Regs for status.
+  @retval EFI_INVALID_PARAMETER   PciHandle not found
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN  EFI_HANDLE                PciHandle,
+  IN  VOID                      **RomImage,
+  OUT UINTN                     *Flags,
+  OUT UINT8                     *DiskStart, OPTIONAL
+  OUT UINT8                     *DiskEnd, OPTIONAL
+  OUT VOID                      **RomShadowAddress, OPTIONAL
+  OUT UINT32                    *ShadowedRomSize OPTIONAL
+  );
+
+/**
+  This function attempts to traditionally boot the specified BootOption. If the EFI context has
+  been compromised, this function will not return. This procedure is not used for loading an EFI-aware
+  OS off a traditional device. The following actions occur:
+  - Get EFI SMBIOS data structures, convert them to a traditional format, and copy to
+    Compatibility16.
+  - Get a pointer to ACPI data structures and copy the Compatibility16 RSD PTR to F0000 block.
+  - Find the traditional SMI handler from a firmware volume and register the traditional SMI
+    handler with the EFI SMI handler.
+  - Build onboard IDE information and pass this information to the Compatibility16 code.
+  - Make sure all PCI Interrupt Line registers are programmed to match 8259.
+  - Reconfigure SIO devices from EFI mode (polled) into traditional mode (interrupt driven).
+  - Shadow all PCI ROMs.
+  - Set up BDA and EBDA standard areas before the legacy boot.
+  - Construct the Compatibility16 boot memory map and pass it to the Compatibility16 code.
+  - Invoke the Compatibility16 table function Compatibility16PrepareToBoot(). This
+    invocation causes a thunk into the Compatibility16 code, which sets all appropriate internal
+    data structures. The boot device list is a parameter.
+  - Invoke the Compatibility16 Table function Compatibility16Boot(). This invocation
+    causes a thunk into the Compatibility16 code, which does an INT19.
+  - If the Compatibility16Boot() function returns, then the boot failed in a graceful
+    manner--meaning that the EFI code is still valid. An ungraceful boot failure causes a reset because the state
+    of EFI code is unknown.
+
+  @param[in] This             The protocol instance pointer.
+  @param[in] BootOption       The EFI Device Path from BootXXXX variable.
+  @param[in] LoadOptionSize   The size of LoadOption in size.
+  @param[in] LoadOption       LThe oadOption from BootXXXX variable.
+
+  @retval EFI_DEVICE_ERROR      Failed to boot from any boot device and memory is uncorrupted.                                Note: This function normally does not returns. It will either boot the                                OS or reset the system if memory has been "corrupted" by loading                                a boot sector and passing control to it.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_BOOT)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN BBS_BBS_DEVICE_PATH       *BootOption,
+  IN UINT32                    LoadOptionsSize,
+  IN VOID                      *LoadOptions
+  );
+
+/**
+  This function takes the Leds input parameter and sets/resets the BDA accordingly.
+  Leds is also passed to Compatibility16 code, in case any special processing is required.
+  This function is normally called from EFI Setup drivers that handle user-selectable
+  keyboard options such as boot with NUM LOCK on/off. This function does not
+  touch the keyboard or keyboard LEDs but only the BDA.
+
+  @param[in] This   The protocol instance pointer.
+  @param[in] Leds   The status of current Scroll, Num & Cap lock LEDS:
+                      - Bit 0 is Scroll Lock 0 = Not locked.
+                      - Bit 1 is Num Lock.
+                      - Bit 2 is Caps Lock.
+
+  @retval EFI_SUCCESS   The BDA was updated successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UINT8                     Leds
+  );
+
+/**
+  Retrieve legacy BBS info and assign boot priority.
+
+  @param[in]     This       The protocol instance pointer.
+  @param[out]    HddCount   The number of HDD_INFO structures.
+  @param[out]    HddInfo    Onboard IDE controller information.
+  @param[out]    BbsCount   The number of BBS_TABLE structures.
+  @param[in,out] BbsTable   Points to List of BBS_TABLE.
+
+  @retval EFI_SUCCESS   Tables were returned.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO)(
+  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,
+  OUT    UINT16                    *HddCount,
+  OUT    HDD_INFO                  **HddInfo,
+  OUT    UINT16                    *BbsCount,
+  IN OUT BBS_TABLE                 **BbsTable
+  );
+
+/**
+  Assign drive number to legacy HDD drives prior to booting an EFI
+  aware OS so the OS can access drives without an EFI driver.
+
+  @param[in]  This       The protocol instance pointer.
+  @param[out] BbsCount   The number of BBS_TABLE structures
+  @param[out] BbsTable   List of BBS entries
+
+  @retval EFI_SUCCESS   Drive numbers assigned.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  OUT UINT16                    *BbsCount,
+  OUT BBS_TABLE                 **BbsTable
+  );
+
+/**
+  To boot from an unconventional device like parties and/or execute
+  HDD diagnostics.
+
+  @param[in]  This              The protocol instance pointer.
+  @param[in]  Attributes        How to interpret the other input parameters.
+  @param[in]  BbsEntry          The 0-based index into the BbsTable for the parent
+                                device.
+  @param[in]  BeerData          A pointer to the 128 bytes of ram BEER data.
+  @param[in]  ServiceAreaData   A pointer to the 64 bytes of raw Service Area data. The
+                                caller must provide a pointer to the specific Service
+                                Area and not the start all Service Areas.
+
+  @retval EFI_INVALID_PARAMETER   If error. Does NOT return if no error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UDC_ATTRIBUTES            Attributes,
+  IN UINTN                     BbsEntry,
+  IN VOID                      *BeerData,
+  IN VOID                      *ServiceAreaData
+  );
+
+/**
+  Shadow all legacy16 OPROMs that haven't been shadowed.
+  Warning: Use this with caution. This routine disconnects all EFI
+  drivers. If used externally, then  the caller must re-connect EFI
+  drivers.
+
+  @param[in]  This   The protocol instance pointer.
+
+  @retval EFI_SUCCESS   OPROMs were shadowed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This
+  );
+
+/**
+  Get a region from the LegacyBios for S3 usage.
+
+  @param[in]  This                  The protocol instance pointer.
+  @param[in]  LegacyMemorySize      The size of required region.
+  @param[in]  Region                The region to use.
+                                    00 = Either 0xE0000 or 0xF0000 block.
+                                      - Bit0 = 1 0xF0000 block.
+                                      - Bit1 = 1 0xE0000 block.
+  @param[in]  Alignment             Address alignment. Bit mapped. The first non-zero
+                                    bit from right is alignment.
+  @param[out] LegacyMemoryAddress   The Region Assigned
+
+  @retval EFI_SUCCESS           The Region was assigned.
+  @retval EFI_ACCESS_DENIED     The function was previously invoked.
+  @retval Other                 The Region was not assigned.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN  UINTN                     LegacyMemorySize,
+  IN  UINTN                     Region,
+  IN  UINTN                     Alignment,
+  OUT VOID                      **LegacyMemoryAddress
+  );
+
+/**
+  Get a region from the LegacyBios for Tiano usage. Can only be invoked once.
+
+  @param[in]  This                        The protocol instance pointer.
+  @param[in]  LegacyMemorySize            The size of data to copy.
+  @param[in]  LegacyMemoryAddress         The Legacy Region destination address.
+                                          Note: must be in region assigned by
+                                          LegacyBiosGetLegacyRegion.
+  @param[in]  LegacyMemorySourceAddress   The source of the data to copy.
+
+  @retval EFI_SUCCESS           The Region assigned.
+  @retval EFI_ACCESS_DENIED     Destination was outside an assigned region.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UINTN                     LegacyMemorySize,
+  IN VOID                      *LegacyMemoryAddress,
+  IN VOID                      *LegacyMemorySourceAddress
+  );
+
+///
+/// Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot()
+/// member function allows the BDS to support booting a traditional OS.
+/// EFI thunks drivers that make EFI bindings for BIOS INT services use
+/// all the other member functions.
+///
+struct _EFI_LEGACY_BIOS_PROTOCOL {
+  ///
+  /// Performs traditional software INT. See the Int86() function description.
+  ///
+  EFI_LEGACY_BIOS_INT86                       Int86;
+
+  ///
+  /// Performs a far call into Compatibility16 or traditional OpROM code.
+  ///
+  EFI_LEGACY_BIOS_FARCALL86                   FarCall86;
+
+  ///
+  /// Checks if a traditional OpROM exists for this device.
+  ///
+  EFI_LEGACY_BIOS_CHECK_ROM                   CheckPciRom;
+
+  ///
+  /// Loads a traditional OpROM in traditional OpROM address space.
+  ///
+  EFI_LEGACY_BIOS_INSTALL_ROM                 InstallPciRom;
+
+  ///
+  /// Boots a traditional OS.
+  ///
+  EFI_LEGACY_BIOS_BOOT                        LegacyBoot;
+
+  ///
+  /// Updates BDA to reflect the current EFI keyboard LED status.
+  ///
+  EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS  UpdateKeyboardLedStatus;
+
+  ///
+  /// Allows an external agent, such as BIOS Setup, to get the BBS data.
+  ///
+  EFI_LEGACY_BIOS_GET_BBS_INFO                GetBbsInfo;
+
+  ///
+  /// Causes all legacy OpROMs to be shadowed.
+  ///
+  EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS    ShadowAllLegacyOproms;
+
+  ///
+  /// Performs all actions prior to boot. Used when booting an EFI-aware OS
+  /// rather than a legacy OS.
+  ///
+  EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI         PrepareToBootEfi;
+
+  ///
+  /// Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block.
+  ///
+  EFI_LEGACY_BIOS_GET_LEGACY_REGION           GetLegacyRegion;
+
+  ///
+  /// Allows EFI to copy data to the area specified by GetLegacyRegion.
+  ///
+  EFI_LEGACY_BIOS_COPY_LEGACY_REGION          CopyLegacyRegion;
+
+  ///
+  /// Allows the user to boot off an unconventional device such as a PARTIES partition.
+  ///
+  EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE  BootUnconventionalDevice;
+};
+
+extern EFI_GUID gEfiLegacyBiosProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h
new file mode 100644
index 0000000000..1d776793d2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h
@@ -0,0 +1,118 @@
+/** @file
+  This protocol abstracts the PIRQ programming from the generic EFI Compatibility Support Modules (CSMs).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _EFI_LEGACY_INTERRUPT_H_
+#define _EFI_LEGACY_INTERRUPT_H_
+
+
+#define EFI_LEGACY_INTERRUPT_PROTOCOL_GUID \
+  { \
+    0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe } \
+  }
+
+typedef struct _EFI_LEGACY_INTERRUPT_PROTOCOL EFI_LEGACY_INTERRUPT_PROTOCOL;
+
+/**
+  Get the number of PIRQs this hardware supports.
+
+  @param  This                  The protocol instance pointer.
+  @param  NumberPirsq           The number of PIRQs that are supported.
+
+  @retval EFI_SUCCESS           The number of PIRQs was returned successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,
+  OUT UINT8                                   *NumberPirqs
+  );
+
+/**
+  Gets the PCI location associated with this protocol.
+
+  @param  This                  The Protocol instance pointer.
+  @param  Bus                   The PCI Bus.
+  @param  Device                The PCI Device.
+  @param  Function              The PCI Function.
+
+  @retval EFI_SUCCESS           The Bus, Device, and Function were returned successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_GET_LOCATION)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,
+  OUT UINT8                                   *Bus,
+  OUT UINT8                                   *Device,
+  OUT UINT8                                   *Function
+  );
+
+/**
+  Read the PIRQ register and return the data
+
+  @param  This                  The protocol instance pointer.
+  @param  PirqNumber            The PIRQ register to read.
+  @param  PirqData              The data read.
+
+  @retval EFI_SUCCESS           The data was read.
+  @retval EFI_INVALID_PARAMETER Invalid PIRQ number.
+  @retval EFI_DEVICE_ERROR      Operation was unsuccessful
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_READ_PIRQ)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,
+  IN  UINT8                                  PirqNumber,
+  OUT UINT8                                  *PirqData
+  );
+
+/**
+  Write the specified PIRQ register with the given data.
+
+  @param  This                  The protocol instance pointer.
+  @param  PirqNumber            A PIRQ register to read.
+  @param  PirqData              The data to write.
+
+  @retval EFI_SUCCESS           The PIRQ was programmed.
+  @retval EFI_INVALID_PARAMETER Invalid PIRQ number.
+  @retval EFI_DEVICE_ERROR      Operation was unsuccessful
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_WRITE_PIRQ)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,
+  IN  UINT8                                  PirqNumber,
+  IN UINT8                                   PirqData
+  );
+
+struct _EFI_LEGACY_INTERRUPT_PROTOCOL {
+  ///
+  ///   Gets the number of PIRQs supported.
+  ///
+  EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS GetNumberPirqs;
+
+  ///
+  /// Gets the PCI bus, device, and function that is associated with this protocol.
+  ///
+  EFI_LEGACY_INTERRUPT_GET_LOCATION     GetLocation;
+
+  ///
+  /// Reads the indicated PIRQ register.
+  ///
+  EFI_LEGACY_INTERRUPT_READ_PIRQ        ReadPirq;
+
+  ///
+  /// Writes to the indicated PIRQ register.
+  ///
+  EFI_LEGACY_INTERRUPT_WRITE_PIRQ       WritePirq;
+};
+
+extern EFI_GUID gEfiLegacyInterruptProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h
new file mode 100644
index 0000000000..c1d1fc89ec
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h
@@ -0,0 +1,65 @@
+/** @file
+  Definitions for data structures used in S3 resume.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_S3_DATA_H_
+#define _ACPI_S3_DATA_H_
+
+#include <Library/BaseLib.h>
+
+#define SMM_S3_RESUME_SMM_32 SIGNATURE_64 ('S','M','M','S','3','_','3','2')
+#define SMM_S3_RESUME_SMM_64 SIGNATURE_64 ('S','M','M','S','3','_','6','4')
+
+#pragma pack(1)
+
+typedef struct {
+  UINT64                Signature;
+  EFI_PHYSICAL_ADDRESS  SmmS3ResumeEntryPoint;
+  EFI_PHYSICAL_ADDRESS  SmmS3StackBase;
+  UINT64                SmmS3StackSize;
+  UINT64                SmmS3Cr0;
+  UINT64                SmmS3Cr3;
+  UINT64                SmmS3Cr4;
+  UINT16                ReturnCs;
+  EFI_PHYSICAL_ADDRESS  ReturnEntryPoint;
+  EFI_PHYSICAL_ADDRESS  ReturnContext1;
+  EFI_PHYSICAL_ADDRESS  ReturnContext2;
+  EFI_PHYSICAL_ADDRESS  ReturnStackPointer;
+  EFI_PHYSICAL_ADDRESS  Smst;
+} SMM_S3_RESUME_STATE;
+
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS  AcpiFacsTable;
+  EFI_PHYSICAL_ADDRESS  IdtrProfile;
+  EFI_PHYSICAL_ADDRESS  S3NvsPageTableAddress;
+  EFI_PHYSICAL_ADDRESS  BootScriptStackBase;
+  UINT64                BootScriptStackSize;
+  EFI_PHYSICAL_ADDRESS  S3DebugBufferAddress;
+} ACPI_S3_CONTEXT;
+
+typedef struct {
+  UINT16                ReturnCs;
+  UINT64                ReturnStatus;
+  EFI_PHYSICAL_ADDRESS  ReturnEntryPoint;
+  EFI_PHYSICAL_ADDRESS  ReturnStackPointer;
+  EFI_PHYSICAL_ADDRESS  AsmTransferControl;
+  IA32_DESCRIPTOR       Idtr;
+} PEI_S3_RESUME_STATE;
+
+#pragma pack()
+
+#define EFI_ACPI_S3_CONTEXT_GUID \
+  { \
+    0xef98d3a, 0x3e33, 0x497a, {0xa4, 0x1, 0x77, 0xbe, 0x3e, 0xb7, 0x4f, 0x38} \
+  }
+
+extern EFI_GUID gEfiAcpiS3ContextGuid;
+
+extern EFI_GUID gEfiAcpiVariableGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h
new file mode 100644
index 0000000000..c770101b38
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h
@@ -0,0 +1,17 @@
+/** @file
+  This GUID can be installed to the device handle to specify that the device is the console-out device.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __CONSOLE_OUT_DEVICE_H__
+#define __CONSOLE_OUT_DEVICE_H__
+
+#define EFI_CONSOLE_OUT_DEVICE_GUID    \
+    { 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+extern EFI_GUID gEfiConsoleOutDeviceGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
new file mode 100644
index 0000000000..bf4b3cdeca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
@@ -0,0 +1,30 @@
+/** @file
+  This file defines:
+  * Memory Type Information GUID for HOB and Variable.
+  * Memory Type Information Variable Name.
+  * Memory Type Information GUID HOB data structure.
+
+  The memory type information HOB and variable can
+  be used to store the information for each memory type in Variable or HOB.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __MEMORY_TYPE_INFORMATION_GUID_H__
+#define __MEMORY_TYPE_INFORMATION_GUID_H__
+
+#define EFI_MEMORY_TYPE_INFORMATION_GUID \
+  { 0x4c19049f,0x4137,0x4dd3, { 0x9c,0x10,0x8b,0x97,0xa8,0x3f,0xfd,0xfa } }
+
+#define EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME L"MemoryTypeInformation"
+
+extern EFI_GUID gEfiMemoryTypeInformationGuid;
+
+typedef struct {
+  UINT32  Type;             ///< EFI memory type defined in UEFI specification.
+  UINT32  NumberOfPages;    ///< The pages of this type memory.
+} EFI_MEMORY_TYPE_INFORMATION;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h
new file mode 100644
index 0000000000..754865943e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h
@@ -0,0 +1,80 @@
+/** @file
+  System reset Library Services.  This library class defines a set of
+  methods that reset the whole system.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h
new file mode 100644
index 0000000000..565d35b654
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h
@@ -0,0 +1,137 @@
+/** @file
+  EFI SMM Access PPI definition.
+
+  This PPI is used to control the visibility of the SMRAM on the platform.
+  It abstracts the location and characteristics of SMRAM.  The expectation is
+  that the north bridge or memory controller would publish this PPI.
+
+  The principal functionality found in the memory controller includes the following:
+  - Exposing the SMRAM to all non-SMM agents, or the "open" state
+  - Shrouding the SMRAM to all but the SMM agents, or the "closed" state
+  - Preserving the system integrity, or "locking" the SMRAM, such that the settings cannot be
+    perturbed by either boot service or runtime agents
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_PPI_H_
+#define _SMM_ACCESS_PPI_H_
+
+#define PEI_SMM_ACCESS_PPI_GUID \
+  { 0x268f33a9, 0xcccd, 0x48be, { 0x88, 0x17, 0x86, 0x5, 0x3a, 0xc3, 0x2e, 0xd6 }}
+
+typedef struct _PEI_SMM_ACCESS_PPI  PEI_SMM_ACCESS_PPI;
+
+/**
+  Opens the SMRAM area to be accessible by a PEIM driver.
+
+  This function "opens" SMRAM so that it is visible while not inside of SMM. The function should
+  return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. The function
+  should return EFI_DEVICE_ERROR if the SMRAM configuration is locked.
+
+  @param  PeiServices            General purpose services available to every PEIM.
+  @param  This                   The pointer to the SMM Access Interface.
+  @param  DescriptorIndex        The region of SMRAM to Open.
+
+  @retval EFI_SUCCESS            The region was successfully opened.
+  @retval EFI_DEVICE_ERROR       The region could not be opened because locked by chipset.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_OPEN)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  );
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function "closes" SMRAM so that it is not visible while outside of SMM. The function should
+  return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM.
+
+  @param  PeiServices              General purpose services available to every PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS              The region was successfully closed.
+  @retval EFI_DEVICE_ERROR         The region could not be closed because locked by chipset.
+  @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CLOSE)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  );
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function prohibits access to the SMRAM region.  This function is usually implemented such
+  that it is a write-once operation.
+
+  @param  PeiServices              General purpose services available to every PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS            The region was successfully locked.
+  @retval EFI_DEVICE_ERROR       The region could not be locked because at least
+                                 one range is still open.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_LOCK)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  );
+
+/**
+  Queries the memory controller for the possible regions that will support SMRAM.
+
+  @param  PeiServices           General purpose services available to every PEIM.
+  @param This                   The pointer to the SmmAccessPpi Interface.
+  @param SmramMapSize           The pointer to the variable containing size of the
+                                buffer to contain the description information.
+  @param SmramMap               The buffer containing the data describing the Smram
+                                region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CAPABILITIES)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  );
+
+///
+///  EFI SMM Access PPI is used to control the visibility of the SMRAM on the platform.
+///  It abstracts the location and characteristics of SMRAM.  The expectation is
+///  that the north bridge or memory controller would publish this PPI.
+///
+struct _PEI_SMM_ACCESS_PPI {
+  PEI_SMM_OPEN          Open;
+  PEI_SMM_CLOSE         Close;
+  PEI_SMM_LOCK          Lock;
+  PEI_SMM_CAPABILITIES  GetCapabilities;
+  BOOLEAN               LockState;
+  BOOLEAN               OpenState;
+};
+
+extern EFI_GUID gPeiSmmAccessPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h
new file mode 100644
index 0000000000..e982c00bf4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h
@@ -0,0 +1,87 @@
+/** @file
+  EFI SMM Control PPI definition.
+
+  This PPI is used to initiate SMI/PMI activations. This protocol could be published by either:
+  - A processor driver to abstract the SMI/PMI IPI
+  - The driver that abstracts the ASIC that is supporting the APM port, such as the ICH in an
+  Intel chipset
+  Because of the possibility of performing SMI or PMI IPI transactions, the ability to generate this
+  event from a platform chipset agent is an optional capability for both IA-32 and Itanium-based
+  systems.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_CONTROL_PPI_H_
+#define _SMM_CONTROL_PPI_H_
+
+#define PEI_SMM_CONTROL_PPI_GUID \
+  { 0x61c68702, 0x4d7e, 0x4f43, 0x8d, 0xef, 0xa7, 0x43, 0x5, 0xce, 0x74, 0xc5 }
+
+typedef struct _PEI_SMM_CONTROL_PPI  PEI_SMM_CONTROL_PPI;
+
+/**
+  Invokes SMI activation from either the preboot or runtime environment.
+
+  @param  PeiServices           General purpose services available to every PEIM.
+  @param  This                  The PEI_SMM_CONTROL_PPI instance.
+  @param  ArgumentBuffer        The optional sized data to pass into the protocol activation.
+  @param  ArgumentBufferSize    The optional size of the data.
+  @param  Periodic              An optional mechanism to periodically repeat activation.
+  @param  ActivationInterval    An optional parameter to repeat at this period one
+                                time or, if the Periodic Boolean is set, periodically.
+
+  @retval EFI_SUCCESS           The SMI/PMI has been engendered.
+  @retval EFI_DEVICE_ERROR      The timing is unsupported.
+  @retval EFI_INVALID_PARAMETER The activation period is unsupported.
+  @retval EFI_NOT_STARTED       The SMM base service has not been initialized.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_ACTIVATE) (
+  IN EFI_PEI_SERVICES                                **PeiServices,
+  IN PEI_SMM_CONTROL_PPI                             * This,
+  IN OUT INT8                                        *ArgumentBuffer OPTIONAL,
+  IN OUT UINTN                                       *ArgumentBufferSize OPTIONAL,
+  IN BOOLEAN                                         Periodic OPTIONAL,
+  IN UINTN                                           ActivationInterval OPTIONAL
+  );
+
+/**
+  Clears any system state that was created in response to the Active call.
+
+  @param  PeiServices           General purpose services available to every PEIM.
+  @param  This                  The PEI_SMM_CONTROL_PPI instance.
+  @param  Periodic              Optional parameter to repeat at this period one
+                                time or, if the Periodic Boolean is set, periodically.
+
+  @retval EFI_SUCCESS           The SMI/PMI has been engendered.
+  @retval EFI_DEVICE_ERROR      The source could not be cleared.
+  @retval EFI_INVALID_PARAMETER The service did not support the Periodic input argument.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_DEACTIVATE) (
+  IN EFI_PEI_SERVICES                      **PeiServices,
+  IN PEI_SMM_CONTROL_PPI                   * This,
+  IN BOOLEAN                               Periodic OPTIONAL
+  );
+
+///
+///  PEI SMM Control PPI is used to initiate SMI/PMI activations. This protocol could be published by either:
+///  - A processor driver to abstract the SMI/PMI IPI
+///  - The driver that abstracts the ASIC that is supporting the APM port, such as the ICH in an
+///  Intel chipset
+///
+struct _PEI_SMM_CONTROL_PPI {
+  PEI_SMM_ACTIVATE    Trigger;
+  PEI_SMM_DEACTIVATE  Clear;
+};
+
+extern EFI_GUID gPeiSmmControlPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h
new file mode 100644
index 0000000000..4aaa715d77
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h
@@ -0,0 +1,33 @@
+/** @file
+  EFI SMM Variable Protocol is related to EDK II-specific implementation of variables
+  and intended for use as a means to store data in the EFI SMM environment.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SMM_VARIABLE_H__
+#define __SMM_VARIABLE_H__
+
+#define EFI_SMM_VARIABLE_PROTOCOL_GUID \
+  { \
+    0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 } \
+  }
+
+typedef struct _EFI_SMM_VARIABLE_PROTOCOL  EFI_SMM_VARIABLE_PROTOCOL;
+
+///
+/// EFI SMM Variable Protocol is intended for use as a means
+/// to store data in the EFI SMM environment.
+///
+struct _EFI_SMM_VARIABLE_PROTOCOL {
+  EFI_GET_VARIABLE            SmmGetVariable;
+  EFI_GET_NEXT_VARIABLE_NAME  SmmGetNextVariableName;
+  EFI_SET_VARIABLE            SmmSetVariable;
+  EFI_QUERY_VARIABLE_INFO     SmmQueryVariableInfo;
+};
+
+extern EFI_GUID gEfiSmmVariableProtocolGuid;
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: Add Include headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (11 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
                   ` (24 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds header files common to System Agent (SA) modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h                |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h        |  53 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h        |  96 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h  |  70 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h          |  46 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h             | 534 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h          |  61 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h            |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h       |  51 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h            | 135 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h            |  60 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h      | 354 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h          |  61 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h    | 103 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h |  63 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h           |  39 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h                |  42 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h                    |  77 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h               |  60 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h               |  87 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h                |  88 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h                           | 259 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h      |  15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h         |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h    |  23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h            |  70 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h         |  36 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h           |  31 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h                  |  89 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h                 | 151 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h           |  63 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h                   |  73 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h                 |  24 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h                     | 132 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h                    |  66 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h                   |  32 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h            | 214 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h                   |  50 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h                   |  37 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h                   |  64 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h                             | 106 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h                  |  23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h                      |  25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h                       |  51 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h                               |  32 ++
 45 files changed, 3845 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h
new file mode 100644
index 0000000000..020a4aeab5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  Policy definition for GNA Config Block
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h
new file mode 100644
index 0000000000..cc337a83f3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h
@@ -0,0 +1,53 @@
+/** @file
+  Graphics DXE Policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_DXE_CONFIG_H_
+#define _GRAPHICS_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define GRAPHICS_DXE_CONFIG_REVISION 2
+
+#define MAX_BCLM_ENTRIES    20
+
+/**
+  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.
+  <b>Revision 2</b>:
+  - Adding BCLM[MAX_BCLM_ENTRIES]
+**/
+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_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h
new file mode 100644
index 0000000000..276289ae81
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h
@@ -0,0 +1,96 @@
+/** @file
+  Policy definition for Internal Graphics Config Block (PostMem)
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_PEI_CONFIG_H_
+#define _GRAPHICS_PEI_CONFIG_H_
+#pragma pack(push, 1)
+
+#define GRAPHICS_PEI_CONFIG_REVISION 4
+#define DDI_DEVICE_NUMBER 4
+
+//
+// DDI defines
+//
+typedef enum {
+  DdiDisable       = 0x00,
+  DdiDdcEnable     = 0x01,
+  DdiTbtLsxEnable  = 0x02,
+} DDI_DDC_TBT_VAL;
+
+typedef enum {
+  DdiHpdDisable  = 0x00,
+  DdiHpdEnable   = 0x01,
+} DDI_HPD_VAL;
+
+typedef enum {
+  DdiPortADisabled = 0x00,
+  DdiPortAEdp      = 0x01,
+  DdiPortAMipiDsi  = 0x02,
+} DDI_PORTA_SETTINGS;
+/**
+  This structure configures the Native GPIOs for DDI port per VBT settings.
+**/
+typedef struct {
+  UINT8 DdiPortEdp;    /// The setting of eDP port, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortBHpd;   /// The HPD setting of DDI Port B, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortCHpd;   /// The HPD setting of DDI Port C, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortDHpd;   /// The HPD setting of DDI Port D, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortFHpd;   /// The HPD setting of DDI Port F, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortBDdc;   /// The DDC setting of DDI Port B, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortCDdc;   /// The DDC setting of DDI Port C, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortDDdc;   /// The DDC setting of DDI Port D, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortFDdc;   /// The DDC setting of DDI Port F, this settings must match VBT's settings. <b>0- Disable</b>, 1- Enable
+  UINT8 Rsvd[3];       ///< Reserved for 4 bytes alignment
+} DDI_CONFIGURATION;
+
+/**
+  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>:
+  - Added SkipS3CdClockInit.
+  <b>Revision 3</b>:
+  - Added DeltaT12PowerCycleDelay, BltBufferAddress, BltBufferSize.
+  <b>Revision 4</b>:
+  - Deprecated DeltaT12PowerCycleDelay.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config Block Header
+  UINT32                RenderStandby     : 1;    ///< Offset 28:0 :<b>(Test)</b> This field is used to enable or disable RC6 (Render Standby): 0=FALSE, <b>1=TRUE</b>
+  UINT32                PmSupport         : 1;    ///< Offset 28:1 :<b>(Test)</b> IGD PM Support TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
+  UINT32                PavpEnable        : 1;    ///< Offset 28:2 :IGD PAVP TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
+  /**
+    Offset 28:3
+    CdClock Frequency select\n
+    CFL\n
+    0   = 337.5 Mhz, 1 = 450 Mhz,\n
+    2   = 540 Mhz,<b> 3 = 675 Mhz</b>,\n
+
+  **/
+  UINT32                CdClock            : 3;
+  UINT32                PeiGraphicsPeimInit: 1;   ///< Offset 28:6 : This policy is used to enable/disable Intel Gfx PEIM.<b>0- Disable</b>, 1- Enable
+  UINT32                CdynmaxClampEnable : 1;   ///< Offset 28:7 : This policy is used to enable/disable CDynmax Clamping Feature (CCF) <b>1- Enable</b>, 0- Disable
+  UINT32                GtFreqMax          : 8;   ///< Offset 28:8 : <b>(Test)</b> Max GT frequency limited by user in multiples of 50MHz: Default value which indicates normal frequency is <b>0xFF</b>
+  UINT32                DisableTurboGt     : 1;   ///< Offset 28:9 : This policy is used to enable/disable DisableTurboGt <b>0- Disable</b>, 1- Enable
+  UINT32                RsvdBits0          : 15;  ///< Offser 28:15 :Reserved for future use
+  VOID*                 LogoPtr;                  ///< Offset 32 Address of Intel Gfx PEIM Logo to be displayed
+  UINT32                LogoSize;                 ///< Offset 36 Intel Gfx PEIM Logo Size
+  VOID*                 GraphicsConfigPtr;        ///< Offset 40 Address of the Graphics Configuration Table
+  DDI_CONFIGURATION     DdiConfiguration;         ///< Offset 44 DDI configuration, need to match with VBT settings.
+  UINT32                SkipS3CdClockInit  : 1;   ///< Offset 56 SKip full CD clock initialization being done during S3 resume.<b>0- Disable<\b>, 1- Enable
+  UINT32                ReservedBits       : 31;  ///< Offset 56: 1 : Reserved for future use.
+  UINT16                DeltaT12PowerCycleDelay;  ///< Offset 60 @deprecated Power Cycle Delay required for eDP as per VESA standard.<b>0 - 0 ms<\b>, 0xFFFF - Auto calculate to max 500 ms
+  UINT8                 Reserved[2];              ///< Offset 62 Reserved for future use.
+  VOID*                 BltBufferAddress;         ///< Offset 64 Address of Blt buffer for PEIM Logo use
+  UINT32                BltBufferSize;            ///< Offset 68 The size for Blt Buffer, calculating by PixelWidth * PixelHeight * 4 bytes (the size of EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+} GRAPHICS_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _GRAPHICS_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h
new file mode 100644
index 0000000000..4986fdab60
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h
@@ -0,0 +1,70 @@
+/** @file
+  Policy definition for Internal Graphics Config Block (PreMem)
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_PEI_PREMEM_CONFIG_H_
+#define _GRAPHICS_PEI_PREMEM_CONFIG_H_
+#pragma pack(push, 1)
+
+#define GRAPHICS_PEI_PREMEM_CONFIG_REVISION 2
+
+
+/**
+  This Configuration block is to configure GT related PreMem data/variables.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added DeltaT12PowerCycleDelayPreMem.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28:0
+    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
+  **/
+  UINT32                PrimaryDisplay    : 3;
+  /**
+    Offset 28:3
+    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.
+  **/
+  UINT32                InternalGraphics  : 2;
+  /**
+    Offset 28:5
+    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>
+  **/
+  UINT32                IgdDvmt50PreAlloc : 8;
+  UINT32                PanelPowerEnable  : 1;          ///< Offset 28:13 :<b>(Test)</b> Control for enabling/disabling VDD force bit (Required only for early enabling of eDP panel): 0=FALSE, <b>1=TRUE</b>
+  UINT32                ApertureSize      : 7;          ///< Offser 28:14 :Graphics aperture size (256MB is the recommended size as per BWG) : 0=128MB, <b>1=256MB</b>, 3=512MB, 7=1024MB, 15=2048MB.
+  UINT32                GtPsmiSupport     : 1;          ///< Offser 28:21 :PSMI support On/Off: <b>0=FALSE</b>, 1=TRUE
+  UINT32                PsmiRegionSize    : 3;          ///< Offser 28:22 :Psmi region size: <b>0=32MB</b>, 1=288MB, 2=544MB, 3=800MB, 4=1056MB
+  UINT32                RsvdBits0         : 7;          ///< Offser 28:25 :Reserved for future use
+  UINT32                GttMmAdr;                       ///< Offset 32 Temp Address of System Agent GTTMMADR : Default is <b>0xCF000000< / b>
+  UINT16                GttSize;                        ///< Offset 36 Selection of iGFX GTT Memory size: 1=2MB, 2=4MB, <b>3=8MB</b>
+  UINT8                 Rsvd1[2];                       ///< Offset 38 Reserved for DWORD alignment
+  UINT32                GmAdr;                          ///< Offset 40 Temp Address of System Agent GMADR : Default is <b>0xD0000000< / b>
+  UINT16                DeltaT12PowerCycleDelayPreMem;  ///< Offset 44 Power Cycle Delay required for eDP as per VESA standard.<b>0 - 0 ms<\b>, 0xFFFF - Auto calculate to max 500 ms
+  UINT8                 Reserved[2];                    ///< Offset 46 Reserved for future use.
+} GRAPHICS_PEI_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _GRAPHICS_PEI_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h
new file mode 100644
index 0000000000..79025d16fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h
@@ -0,0 +1,46 @@
+/** @file
+  IPU policy definitions (PreMem)
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPU_CONFIG_PREMEM_H_
+#define _IPU_CONFIG_PREMEM_H_
+
+#pragma pack(push, 1)
+
+#define IPU_PREMEM_CONFIG_REVISION 1
+
+#define SA_IMR_IPU_CAMERA   0
+#define SA_IMR_IPU_GEN      1
+
+/**
+ IPU PreMem configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;           ///< Offset  0-27 Config Block Header
+  /**
+  Offset 28:0 :
+  <b>(Test)</b> It enables the SA IPU Device if supported and not fused off.
+  If FALSE, all other policies in this config block will be ignored.
+  <b>1=TRUE</b>;
+  0=FALSE.
+  **/
+  UINT32    SaIpuEnable:1;
+  /**
+  Offset 28:1 :
+  <b>(Test)</b> It configure the IPU IMR to IPU Camera or IPU Gen when IPU is enabled.
+  If FALSE, all other policies in this config block will be ignored.
+  <b>0=IPU Camera</b>;
+  1=IPU Gen
+  **/
+  UINT32    SaIpuImrConfiguration:1;
+  UINT32    RsvdBits0:30;                     /// Offset 28:2 :Reserved for future use.
+} IPU_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _IPU_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h
new file mode 100644
index 0000000000..8374ff5f68
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h
@@ -0,0 +1,534 @@
+/** @file
+  Policy definition of Memory Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MEMORY_CONFIG_H_
+#define _MEMORY_CONFIG_H_
+
+#include <SaRegs.h>
+
+#pragma pack(push, 1)
+
+#define SA_MRC_ITERATION_MAX      (6)
+#define SA_MRC_MAX_RCOMP          (3)
+#define SA_MRC_MAX_RCOMP_TARGETS  (5)
+
+#define MEMORY_CONFIG_REVISION 3
+
+///
+/// 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;
+
+typedef struct {
+  UINT8 SpdData[SA_MC_MAX_CHANNELS][SA_MC_MAX_SLOTS][SA_MC_MAX_SPD_SIZE];
+//Next Field Offset 2048
+} SPD_DATA_BUFFER;
+
+typedef struct {
+  UINT8 DqByteMap[SA_MC_MAX_CHANNELS][SA_MRC_ITERATION_MAX][2];
+//Next Field Offset 24
+} SA_MEMORY_DQ_MAPPING;
+
+typedef struct {
+  UINT8 DqsMapCpu2Dram[SA_MC_MAX_CHANNELS][SA_MC_MAX_BYTES_NO_ECC];
+//Next Field Offset 16
+} SA_MEMORY_DQS_MAPPING;
+
+typedef struct {
+  UINT16  RcompResistor[SA_MRC_MAX_RCOMP];       ///< Offset 0: Reference RCOMP resistors on motherboard
+  UINT16  RcompTarget[SA_MRC_MAX_RCOMP_TARGETS]; ///< Offset 6: RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+//Next Field Offset 16
+} SA_MEMORY_RCOMP;
+
+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);
+typedef UINT16     (EFIAPI * SA_IO_READ_16)              (UINTN IoAddress);
+typedef UINT32     (EFIAPI * SA_IO_READ_32)              (UINTN IoAddress);
+typedef UINT8      (EFIAPI * SA_IO_WRITE_8)              (UINTN IoAddress, UINT8 Value);
+typedef UINT16     (EFIAPI * SA_IO_WRITE_16)             (UINTN IoAddress, UINT16 Value);
+typedef UINT32     (EFIAPI * SA_IO_WRITE_32)             (UINTN IoAddress, UINT32 Value);
+typedef UINT8      (EFIAPI * SA_MMIO_READ_8)             (UINTN Address);
+typedef UINT16     (EFIAPI * SA_MMIO_READ_16)            (UINTN Address);
+typedef UINT32     (EFIAPI * SA_MMIO_READ_32)            (UINTN Address);
+typedef UINT64     (EFIAPI * SA_MMIO_READ_64)            (UINTN Address);
+typedef UINT8      (EFIAPI * SA_MMIO_WRITE_8)            (UINTN Address, UINT8 Value);
+typedef UINT16     (EFIAPI * SA_MMIO_WRITE_16)           (UINTN Address, UINT16 Value);
+typedef UINT32     (EFIAPI * SA_MMIO_WRITE_32)           (UINTN Address, UINT32 Value);
+typedef UINT64     (EFIAPI * SA_MMIO_WRITE_64)           (UINTN Address, UINT64 Value);
+typedef UINT8      (EFIAPI * SA_SMBUS_READ_8)            (UINTN Address, RETURN_STATUS *Status);
+typedef UINT16     (EFIAPI * SA_SMBUS_READ_16)           (UINTN Address, RETURN_STATUS *Status);
+typedef UINT8      (EFIAPI * SA_SMBUS_WRITE_8)           (UINTN Address, UINT8 Value, RETURN_STATUS *Status);
+typedef UINT16     (EFIAPI * SA_SMBUS_WRITE_16)          (UINTN Address, UINT16 Value, RETURN_STATUS *Status);
+typedef UINT32     (EFIAPI * SA_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef UINT32     (EFIAPI * SA_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef VOID       (EFIAPI * SA_GET_RTC_TIME)            (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
+typedef UINT64     (EFIAPI * SA_GET_CPU_TIME)            (VOID *GlobalData);
+typedef VOID *     (EFIAPI * SA_MEMORY_COPY)             (VOID *Destination, CONST VOID *Source, UINTN NumBytes);
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_BYTE)         (VOID *Buffer, UINTN NumBytes, UINT8 Value);
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_WORD)         (VOID *Buffer, UINTN NumWords, UINT16 Value);
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_DWORD)        (VOID *Buffer, UINTN NumDwords, UINT32 Value);
+typedef UINT64     (EFIAPI * SA_LEFT_SHIFT_64)           (UINT64 Data, UINTN NumBits);
+typedef UINT64     (EFIAPI * SA_RIGHT_SHIFT_64)          (UINT64 Data, UINTN NumBits);
+typedef UINT64     (EFIAPI * SA_MULT_U64_U32)            (UINT64 Multiplicand, UINT32 Multiplier);
+typedef UINT64     (EFIAPI * SA_DIV_U64_U64)             (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);
+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);
+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);
+typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_READ)        (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);
+typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_WRITE)       (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);
+typedef UINT32     (EFIAPI * SA_GET_MEMORY_VDD)          (VOID *GlobalData, UINT32 DefaultVdd);
+typedef UINT32     (EFIAPI * SA_SET_MEMORY_VDD)          (VOID *GlobalData, UINT32 DefaultVdd, UINT32 Value);
+typedef UINT32     (EFIAPI * SA_CHECKPOINT)              (VOID *GlobalData, UINT32 CheckPoint, VOID *Scratch);
+typedef VOID       (EFIAPI * SA_DEBUG_HOOK)              (VOID *GlobalData, UINT16 DisplayDebugNumber);
+typedef UINT8      (EFIAPI * SA_CHANNEL_EXIST)           (VOID *Outputs, UINT8 Channel);
+typedef INT32      (EFIAPI * SA_PRINTF)                  (VOID *Debug, UINT32 Level, char *Format, ...);
+typedef VOID       (EFIAPI * SA_DEBUG_PRINT)             (VOID *String);
+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);
+typedef UINT8      (EFIAPI * SA_SIGN_EXTEND)             (UINT8 Value, UINT8 OldMsb, UINT8 NewMsb);
+typedef VOID       (EFIAPI * SA_SHIFT_PI_COMMAND_TRAIN)  (VOID *GlobalData, UINT8 Channel, UINT8 Iteration, UINT8 RankMask, UINT8 GroupMask, INT32 NewValue, UINT8 UpdateHost);
+typedef VOID       (EFIAPI * SA_UPDATE_VREF)             (VOID *GlobalData, UINT8 Channel, UINT8 RankMask, UINT16 DeviceMask, UINT8 VrefType, INT32 Offset, BOOLEAN UpdateMrcData, BOOLEAN PDAmode, BOOLEAN SkipWait);
+typedef UINT8      (EFIAPI * SA_GET_RTC_CMOS)            (UINT8 Location);
+typedef UINT64     (EFIAPI * SA_MSR_READ_64)             (UINT32 Location);
+typedef UINT64     (EFIAPI * SA_MSR_WRITE_64)            (UINT32 Location, UINT64 Data);
+typedef UINT32     (EFIAPI * SA_THERMAL_OVERRIDES)       (VOID *GlobalData);
+typedef VOID       (EFIAPI * SA_MRC_RETURN_FROM_SMC)     (VOID *GlobalData, UINT32 MrcStatus);
+typedef VOID       (EFIAPI * SA_MRC_DRAM_RESET)          (UINT32 PciEBaseAddress, UINT32 ResetValue);
+typedef VOID       (EFIAPI * SA_SET_LOCK_PRMRR)          (UINT32 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_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>:
+ - Removed GearType.
+ - Added Lp4DqsOscEn, RMTLoopCount, EnBER, DualDimmPerChannelBoardType.
+ <b>Revision 3</b>:
+ - Removed EvLoader, EvLoaderDelay.
+**/
+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 DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  RemapEnable:1;                  ///<  - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+  UINT32  ScramblerSupport:1;             ///<  - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor: 0=Disable, <b>1=Enable</b>
+  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set option: 0=Set A, <b>1=Set B</b>
+  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bit 7-8 Reserved
+  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+  UINT32  Ddr4DdpSharedClock:1;           ///<  - Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  UINT32  SharedZqPin:1;                  ///<  - Select if ZQ pin is shared between Rank ranks.  For CFL, this option only works for DDR4.  the option works for LPDDR4 and DDR4. <b>0=Not shared</b>, 1=Shared
+  // Thermal Management
+  UINT32  ThermalManagement:1;            ///<  - <CFL> Memory Thermal Management Support: <b>0=Disable</b>, 1=Enable.
+  UINT32  PeciInjectedTemp:1;             ///<  - <CFL> Enable/Disable memory temperatures to be injected to the processor via PECI: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnBoard:1;            ///<  - <CFL> Enable/Disable routing TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnDimm:1;             ///<  - <CFL> Enable/Disable routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  VirtualTempSensor:1;            ///<  - <CFL> Enable/Disable Virtual Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
+  UINT32  Lp4DqsOscEn :1;                 ///<  - <CNL> LpDdrDqDqsReTraining - DqDqsReTraining Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DualDimmPerChannelBoardType:1;  ///<  - <CFL> DualDimmPerChannelBoardType - Option to indicate if the Memory Design for the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>, 1=Dual DIMM Design
+  UINT32  ReservedBits1:13;
+  /**
+   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[SA_MC_MAX_CHANNELS]; ///< Offset 68
+  /**
+   Selects the ratio to multiply the reference clock by for the DDR frequency\n
+   When RefClk is 133MHz\n
+   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are invalid\n
+   When RefClk is 100MHz\n
+   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are invalid\n
+  **/
+  UINT8   Ratio;                  ///< Offset 70
+  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+  /**
+     - 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 76 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   EnergyScaleFact;        ///< Offset 77 Energy Scale Factor. 0=Minimal, 7=Maximum, <b>4=Default</b>
+  BOOLEAN PerBankRefresh;         ///< <CNL> Offset 78 Enables and Disables the per bank refresh.  This only impacts memory technologies that support PBR: LPDDR3, LPDDR4.  FALSE=Disabled, <b>TRUE=Enabled</b>
+  UINT8   McLock;                 ///< <CFL> Offset 79 Enable/Disable memory configuration register locking: 0=Disable, <b>1=Enable</b>.
+  // Training Algorithms 1
+  UINT32 ECT:1;                   ///< Offset 80 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;                   ///<  - 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;            ///<  - 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;                ///<  - 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;                 ///<  - 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;                  ///<  - 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;               ///<  - 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;               ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;              ///<  - 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;              ///<  - 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;               ///<  - 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;                 ///<  - 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;                ///<  - 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;                 ///<  - 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;                 ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;                 ///<  - 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;                   ///<  - 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;                   ///<  - 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;                   ///<  - 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;                   ///<  - Enable/Disable Rank Margin Tool function: <b>0=Disable</b>, 1=Enable.
+  UINT32 MEMTST:1;                ///<  - Enable/Disable Memory Test function: <b>0=Disable</b>, 1=Enable.
+  UINT32 ALIASCHK:1;              ///<  - Enable/Disable DIMM SPD Alias Check: 0=Disable, <b>1=Enable</b>
+  UINT32 RCVENC1D:1;              ///<  - 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;                   ///<  - 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;               ///<  - 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
+  UINT32  CMDSR    : 1;           ///< <CFL> Offset 84 - Enable/Disable CMD Slew Rate Training: 0=Disable, <b>1=Enable</b>.
+  UINT32  CMDDSEQ  : 1;           ///< <CFL>  - Enable/Disable CMD Drive Strength and Tx Equalization: 0=Disable, <b>1=Enable</b>.
+  UINT32  CMDNORM  : 1;           ///< <CFL>  - Enable/Disable CMD Normalization: 0=Disable, <b>1=Enable</b>.
+  UINT32  EWRDSEQ  : 1;           ///< <CFL>  - Enable/Disable Early DQ Write Drive Strength and Equalization Training: 0=Disable, <b>1=Enable</b>.
+  UINT32  RDVC1D   : 1;           ///< <CNL>  - Enable/Disable Read Voltage Centering 1D
+  UINT32  TXTCO    : 1;           ///< <CNL>  - Enable/Disable Write TCO Comp Training
+  UINT32  CLKTCO   : 1;           ///< <CNL>  - Enable/Disable Clock TCO Comp Training
+  UINT32  ReservedBits2 :25;
+
+  UINT32  OddRatioMode:1;             ///< Offset 88 If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcTimeMeasure:1;           ///<  - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcFastBoot:1;              ///<  - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+  UINT32  DqPinsInterleaved:1;        ///<  - Interleaving mode of DQ/DQS pins for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
+  UINT32  RankInterleave:1;           ///<  - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  EnhancedInterleave:1;       ///<  - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  WeaklockEn:1;               ///<  - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  CmdTriStateDis:1;           ///<  - CMD Tri-State Support: <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if Command RTT is not present on the platform.
+  UINT32  MemoryTrace:1;              ///<  - Memory Trace to second DDR channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  ChHashEnable:1;             ///<  - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  EnableExtts:1;              ///<  - Enable Extts: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableCltm:1;               ///<  - Enable Closed Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableOltm:1;               ///<  - Enable Open Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnablePwrDn:1;              ///<  - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  EnablePwrDnLpddr:1;         ///<  - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  LockPTMregs:1;              ///<  - Lock PCU Thermal Management registers: 0=Disable, <b>1=Enable</b>
+  UINT32  UserPowerWeightsEn:1;       ///<  - Allows user to explicitly set power weight, scale factor, and channel power floor values: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Lock:1;             ///<  - Lock DDR_RAPL_LIMIT register: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Ena:1;              ///<  - Enable Power Limit 2: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim1Ena:1;              ///<  - Enable Power Limit 1: <b>0=Disable</b>, 1=Enable
+  UINT32  SrefCfgEna:1;               ///<  - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeatLpddr:1;    ///<  - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeat:1;         ///<  - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+  UINT32  AutoSelfRefreshSupport:1;   ///<  - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+  UINT32  ExtTemperatureSupport:1;    ///<  - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+  UINT32  MobilePlatform:1;           ///<  - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+  UINT32  Force1Dpc:1;                ///<  - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+  UINT32  ForceSingleRank:1;          ///<  - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+  UINT32  RhPrevention:1;             ///<  - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+  UINT32  VttTermination:1;           ///<  - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+  UINT32  VttCompForVsshi:1;          ///<  - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+  UINT32  ExitOnFailure:1;            ///<  - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+
+  UINT32  VddSettleWaitTime;      ///< Offset 92 Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+  UINT16  FreqSaGvLow;            ///< Offset 96 SA GV: 0 is Auto/default, otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333, 1400, 1600, 1800, 1867.
+  UINT16  SrefCfgIdleTmr;         ///< Offset 98 Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+  UINT8   RhActProbability;       ///< Offset 100 Activation probability for Hardware RHP
+  UINT8   SmramMask;              ///< Offset 101 Reserved memory ranges for SMRAM
+  UINT16  Vc1ReadMeterThreshold;  ///< <CFL> Offset 102 VC1 Read Meter Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum, <b>0x118=Default</b>
+  UINT32  Vc1ReadMeterTimeWindow; ///< <CFL> Offset 104 VC1 Read Meter Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
+  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es): <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
+
+  UINT16  ChHashMask;             ///< Offset 140 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 142 Memory Frequency setting: 3=1067, 5=1333, 7=1600, 9=1867, 11=2133, 13=2400, <b>15=2667</b>
+  UINT8   RaplLim2WindX;          ///< Offset 144 Power Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8   RaplLim2WindY;          ///< Offset 145 Power Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8   RaplLim1WindX;          ///< Offset 146 Power Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
+  UINT8   RaplLim1WindY;          ///< Offset 147 Power Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
+  UINT16  RaplLim2Pwr;            ///< Offset 148  Power Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
+  UINT16  RaplLim1Pwr;            ///< Offset 150  Power Limit 1: <b>0=Minimal</b>, 16383=Maximum
+  UINT8   WarmThresholdCh0Dimm0;  ///< Offset 152 Warm Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmThresholdCh0Dimm1;  ///< Offset 153 Warm Threshold (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmThresholdCh1Dimm0;  ///< Offset 154 Warm Threshold (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmThresholdCh1Dimm1;  ///< Offset 155 Warm Threshold (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh0Dimm0;   ///< Offset 156 Hot Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh0Dimm1;   ///< Offset 157 Hot Threshold (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh1Dimm0;   ///< Offset 158 Hot Threshold (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh1Dimm1;   ///< Offset 159 Hot Threshold (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh0Dimm0;     ///< Offset 160 Warm Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh0Dimm1;     ///< Offset 161 Warm Budget (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh1Dimm0;     ///< Offset 162 Warm Budget (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh1Dimm1;     ///< Offset 163 Warm Budget (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh0Dimm0;      ///< Offset 164 Hot Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh0Dimm1;      ///< Offset 165 Hot Budget (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh1Dimm0;      ///< Offset 166 Hot Budget (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh1Dimm1;      ///< Offset 167 Hot Budget (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   IdleEnergyCh0Dimm0;     ///< Offset 168 Idle Energy (Channel 0, Dimm 0): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   IdleEnergyCh0Dimm1;     ///< Offset 169 Idle Energy (Channel 0, Dimm 1): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   IdleEnergyCh1Dimm0;     ///< Offset 170 Idle Energy (Channel 1, Dimm 0): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   IdleEnergyCh1Dimm1;     ///< Offset 171 Idle Energy (Channel 1, Dimm 1): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   PdEnergyCh0Dimm0;       ///< Offset 172 Power Down Energy (Channel 0, Dimm 0): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   PdEnergyCh0Dimm1;       ///< Offset 173 Power Down Energy (Channel 0, Dimm 1): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   PdEnergyCh1Dimm0;       ///< Offset 174 Power Down Energy (Channel 1, Dimm 0): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   PdEnergyCh1Dimm1;       ///< Offset 175 Power Down Energy (Channel 1, Dimm 1): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   ActEnergyCh0Dimm0;      ///< Offset 176 Activation Energy (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   ActEnergyCh0Dimm1;      ///< Offset 177 Activation Energy (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   ActEnergyCh1Dimm0;      ///< Offset 178 Activation Energy (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   ActEnergyCh1Dimm1;      ///< Offset 179 Activation Energy (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   RdEnergyCh0Dimm0;       ///< Offset 180 Read Energy (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   RdEnergyCh0Dimm1;       ///< Offset 181 Read Energy (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   RdEnergyCh1Dimm0;       ///< Offset 182 Read Energy (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   RdEnergyCh1Dimm1;       ///< Offset 183 Read Energy (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   WrEnergyCh0Dimm0;       ///< Offset 184 Write Energy (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>221=Default</b>
+  UINT8   WrEnergyCh0Dimm1;       ///< Offset 185 Write Energy (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>221=Default</b>
+  UINT8   WrEnergyCh1Dimm0;       ///< Offset 186 Write Energy (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>221=Default</b>
+  UINT8   WrEnergyCh1Dimm1;       ///< Offset 187 Write Energy (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>221=Default</b>
+
+
+  UINT8   MaxRttWr;               ///< Offset 188 Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+  UINT8   ThrtCkeMinTmr;          ///< Offset 189 Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
+  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
+  UINT8   BerEnable;              ///< Offset 191 BER Enable and # of Addresses passed in: <b>0=Minimal</b>, 8=Maximum
+  UINT8   CkeRankMapping;         ///< Offset 192 Bits [7:4] - Channel 1, bits [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes to.
+  UINT8   StrongWkLeaker;         ///< Offset 193 Strong Weak Leaker: 1=Minimal, <b>7=Maximum</b>
+  UINT8   CaVrefConfig;           ///< Offset 194 0=VREF_CA goes to both CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A, VREF_DQ_B to CH_B</b>
+  UINT8   SaGv;                   ///< Offset 195 SA GV: 0=Disabled; 1=FixedLow; CFL: 2=FixedHigh, CNL: 2=FixedMid; <b>CFL: 3=Enabled</b> CNL: 3=FixedHigh; <b>CNL: 4=Enabled</b>
+  UINT8   RaplPwrFlCh1;           ///< Offset 196 Power Channel 1 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   RaplPwrFlCh0;           ///< Offset 197 Power Channel 0 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   NModeSupport;           ///< Offset 198 Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+  UINT8   RefClk;                 ///< Offset 199 Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+  UINT8   EnCmdRate;              ///< Offset 200 CMD Rate Enable: 0=Disable, 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7 CMDs
+  UINT8   Refresh2X;              ///< Offset 201 Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+  UINT8   EpgEnable;              ///< Offset 202 Enable Energy Performance Gain.
+  UINT8   RhSolution;             ///< Offset 203 Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  UINT8   UserThresholdEnable;    ///< Offset 204 Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   UserBudgetEnable;       ///< Offset 205 Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodTcritMax;           ///< Offset 206 TSOD Tcrit Maximum Value  to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
+
+  UINT8   TsodEventMode;          ///< Offset 207 Flag to Enable Event Mode Interruption in TSOD Configuration Register, 0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventPolarity;      ///< Offset 208 Event Signal Polarity in TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
+  UINT8   TsodCriticalEventOnly;  ///< Offset 209 Critical Trigger Only in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventOutputControl; ///< Offset 210 Event Output Control in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 Alarm Windows Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodCriticaltripLockBit;///< Offset 212 Critical Trip Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodShutdownMode;       ///< Offset 213 Shutdown Mode TSOD Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
+  UINT8   TsodThigMax;            ///< Offset 214 Thigh Max Value In the  for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodManualEnable;       ///< Offset 215 Flag to manually select the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   DllBwEn0;               ///< Offset 216 DllBwEn value for 1067
+  UINT8   DllBwEn1;               ///< Offset 217 DllBwEn value for 1333
+  UINT8   DllBwEn2;               ///< Offset 218 DllBwEn value for 1600
+  UINT8   DllBwEn3;               ///< Offset 219 DllBwEn value for 1867 and up
+  UINT8   RetrainOnFastFail;      ///< Offset 220 Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 Force OLTM or 2X Refresh when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
+  UINT8   PowerDownMode;          ///< Offset 222 CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+  UINT8   PwdwnIdleCounter;       ///< Offset 223 CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal, 0xFF=Maximum, <b>0x99=Default</b>
+  UINT8   CmdRanksTerminated;     ///< <CNL> Offset 225 LPDDR4: Bitmask of ranks that have CA bus terminated. <b>0x01=Default, Rank0 is terminating and Rank1 is non-terminating</b>
+  UINT8   GdxcEnable;             ///< <CFL> Offset 226 GDXC  MOT enable
+  UINT8   GdxcIotSize;            ///< <CFL> Offset 227 IOT size in multiples of 8MEG
+  UINT8   GdxcMotSize;            ///< <CFL> Offset 228 MOT size in multiples of 8MEG
+  UINT8   RMTLoopCount;           ///< Offset 229 Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+  UINT16  FreqSaGvMid;            ///< Offset 230 SA GV: 0 is Auto/default, otherwise holds the frequency value expressed as an integer: <b>0=Default</b>, 1600, 1800, 1867, 2000, 2133, etc.
+
+  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  TrainTrace:1;                 ///< Offset 232 Bit 1: Trained state tracing debug. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  SafeMode:1;                   ///< Offset 232 Bit 2: Define if safe mode is enabled for MC/IO
+  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is enabled for Rank Margin Tool
+  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4: Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
+  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Force MRC training on warm boot : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
+
+  // TurnAround Timing
+  UINT8   tRd2RdSG;               ///< Offset 236 - Read-to-Read   Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2RdDG;               ///< Offset 237 - Read-to-Read   Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tRd2RdDR;               ///< Offset 238 - Read-to-Read   Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2RdDD;               ///< Offset 239 - Read-to-Read   Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2WrSG;               ///< Offset 240 - Read-to-Write  Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2WrDG;               ///< Offset 241 - Read-to-Write  Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tRd2WrDR;               ///< Offset 242 - Read-to-Write  Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2WrDD;               ///< Offset 243 - Read-to-Write  Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2RdSG;               ///< Offset 244 - Write-to-Read  Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 86=Maximum.
+  UINT8   tWr2RdDG;               ///< Offset 245 - Write-to-Read  Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tWr2RdDR;               ///< Offset 246 - Write-to-Read  Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2RdDD;               ///< Offset 247 - Write-to-Read  Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2WrSG;               ///< Offset 248 - Write-to-Write Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2WrDG;               ///< Offset 249 - Write-to-Write Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tWr2WrDR;               ///< Offset 250 - Write-to-Write Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2WrDD;               ///< Offset 251 - Write-to-Write Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT16  tRRD_L;                 ///< <CFL> Offset 252 - User defined DDR4 Memory Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tRRD_S;                 ///< <CFL> Offset 254 - User defined DDR4 Memory Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR_L;                 ///< <CFL> Offset 266 - User defined DDR4 Memory Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tWTR_S;                 ///< <CFL> Offset 268 - User defined DDR4 Memory Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+
+} MEMORY_CONFIGURATION;
+
+/// Memory Configuration
+/// The contents of this structure are not CRC'd by the MRC for option change detection.
+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 200  Function calls into the MRC.
+  SPD_DATA_BUFFER          *SpdData;            ///< Offset 236  Memory SPD data, will be used by the MRC when SPD SmBus address is zero.
+  SA_MEMORY_DQ_MAPPING     *DqByteMap;          ///< Offset 240  LPDDR3 DQ byte mapping to CMD/CTL/CLK, from the CPU side.
+  SA_MEMORY_DQS_MAPPING    *DqsMap;             ///< Offset 244  LPDDR3 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 260  Ask MRC to clear memory content: <b>FALSE=Do not Clear Memory</b>; TRUE=Clear Memory
+  UINT32                   MemTestOnWarmBoot:1; ///< Offset 260  Run Base Memory Test On WarmBoot:  0=Disabled, <b>1=Enabled</b>
+  UINT32                   ReservedBits5:30;
+  /**
+   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 264
+  UINT8   Reserved11[3];                        ///< Offset 265  Reserved
+} MEMORY_CONFIG_NO_CRC;
+#pragma pack(pop)
+
+#endif // _MEMORY_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
new file mode 100644
index 0000000000..9f01c172f2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
@@ -0,0 +1,61 @@
+/** @file
+  Memory DXE Policy definitions
+
+  Copyright (c) 2019 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
+
+/**
+  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.
+**/
+typedef struct {
+  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;
+  UINT8                 MrcTimeMeasure;   ///< Offset 38: MRC execution time measurement: <b>0=Disable</b>, 1=Enable
+  UINT8                 MrcFastBoot;      ///< Offset 39: Fast boot: 0=Disable, <b>1=Enable</b>
+} MEMORY_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _MEMORY_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h
new file mode 100644
index 0000000000..7a8894a5c0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  MISC DXE policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MISC_DXE_CONFIG_H_
+#define _MISC_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define MISC_DXE_CONFIG_REVISION 2
+
+/**
+  This data structure includes miscellaneous configuration variables such SA thermal device
+  control. The data elements should be initialized by a Platform Module.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2:</b>
+  - Added RmrrCsmeBaseAddress fields.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                    ///< Offset 0-27 Config Block Header
+  EFI_PHYSICAL_ADDRESS  *RmrrUsbBaseAddress;       ///< Offset 28 The field is used to describe the platform USB Reserved memory for Intel VT-d support. Platform code should provide this information for Intel VT-d DXE driver use
+  UINT32                EnableAbove4GBMmio : 1;    ///< Offset 29:0 Enable/disable above 4GB MMIO resource support: <b>0=Disable</b>, 1=Enable
+  UINT32                RsvdBits0          : 31;   ///< Offset 29:1 Reserved bits.
+  EFI_PHYSICAL_ADDRESS  *RmrrCsmeBaseAddress;      ///< The field is used to describe the CSME Reserved memory.
+} MISC_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _MISC_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h
new file mode 100644
index 0000000000..b623f14c15
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h
@@ -0,0 +1,51 @@
+/** @file
+  Policy definition for System Agent overclocking Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _OVERCLOCKING_PREMEM_CONFIG__H_
+#define _OVERCLOCKING_PREMEM_CONFIG__H_
+#pragma pack(push, 1)
+
+#define SA_OVERCLOCKING_CONFIG_REVISION 2
+
+/**
+ Defines the overclocking configuration parameters for System Agent.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add GT unslice support.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;    ///< Offset 0-27 Config Block Header
+  /**
+  Offset 28:0 :
+  Enable disable of SA overclocking mailbox commands.
+  If disabled, or if PcdSaOcEnable is disabled, all other policies in this config block are ignored.
+  <b>0=Disable</b>,
+  1=Enable
+  **/
+  UINT32  OcSupport             : 1;
+  UINT32  GtVoltageMode         : 1;    ///< Offset 28:1 :Specifies whether GT voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>, 1=Override
+  UINT32  RealtimeMemoryTiming  : 1;    ///< Offset 28:2 :Enable/Disable the message sent to the CPU to allow realtime memory timing changes after MRC_DONE. <b>0=Disable</b>, 1=Enable
+  UINT32  GtusVoltageMode       : 1;    ///< Offset 28:3 :Specifies whether GT unslice voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>, 1=Override
+  UINT32  RsvdBits0             : 28;   ///< Offset 28:4 - 31 :Reserved for future use
+  UINT8   GtMaxOcRatio;                 ///< Offset 32 Maximum GT turbo ratio override: 0=Minimal, 255=Maximum, <b>0=AUTO</b>
+  UINT8   Rsvd0;                        ///< Offset 33 Reserved for DWORD alignment
+  INT16   GtVoltageOffset;              ///< Offset 34 The voltage offset applied to GT slice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>, 1000=Maximum
+  UINT16  GtVoltageOverride;            ///< Offset 36 The GT voltage override which is applied to the entire range of GT frequencies <b>0=Default</b>
+  UINT16  GtExtraTurboVoltage;          ///< Offset 38 The adaptive voltage applied during turbo frequencies. Valid range from 0 to 2000mV: <b>0=Minimal</b>, 2000=Maximum
+  INT16   SaVoltageOffset;              ///< Offset 40 The voltage offset applied to the SA. Valid range from -1000mv to 1000mv: <b>0=Default</b>
+  INT16   GtusVoltageOffset;            ///< Offset 42 The voltage offset applied to GT unslice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>, 1000=Maximum
+  UINT16  GtusVoltageOverride;          ///< Offset 44 The GT unslice voltage override which is applied to the entire range of GT frequencies: <b>0=Default</b>
+  UINT16  GtusExtraTurboVoltage;        ///< Offset 46 The adaptive voltage applied during turbo frequencies. Valid range from 0 to 2000mV: <b>0=Default</b>
+  UINT8   GtusMaxOcRatio;               ///< Offset 48 Maximum GTus turbo ratio override: 0=Minimal, 6=Maximum, <b>0=AUTO</b>
+  UINT8   Rsvd1[3];                     ///< Offset 49-51 Reserved for DWORD alignment
+} OVERCLOCKING_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _OVERCLOCKING_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
new file mode 100644
index 0000000000..f0b9670f64
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
@@ -0,0 +1,135 @@
+/** @file
+  PCIE DXE policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_DXE_CONFIG_H_
+#define _PCIE_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define PCIE_DXE_CONFIG_REVISION 1
+
+///
+/// Device List for special ASPM override
+///
+typedef struct {
+  UINT16  VendorId;         ///< Offset 0 PCI Configuration space offset 0
+  UINT16  DeviceId;         ///< Offset 2 PCI Configuration space offset 2
+  UINT8   RevId;            ///< Offset 4 PCI Configuration space offset 8; 0xFF means all steppings
+  UINT8   RootApmcMask;     ///< Offset 5 Root ASPM override bit mask <b>0=No override</b>
+  UINT8   EndpointApmcMask; ///< Offset 6 Endpoint ASPM override bit mask <b>0=No override</b>
+  UINT8   Rsvd;             ///< Offset 7 Reserved
+} PCIE_ASPM_OVERRIDE_LIST;
+
+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
+} SA_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.
+**/
+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: This field is used to describe the PEG L0s advanced control
+  0=ASPM L0s disabled, 1=ASPM L0s enabled on RP, 2=ASPM L0s enabled on EP, <b>3=ASPM L0s enabled on both RP and EP</b>
+**/
+  UINT8                    PegAspmL0s[SA_PEG_MAX_FUN];
+/**
+  Offset 36: 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];
+/**
+  Offset 40: This field is used as a pointer to the ASPM device override table, default points to an\n
+  existing table mPcieAspmDevsOverride\n
+  Refer to DxeSaPolicyLib.c for the usage.
+  Note:  This exclusion list helps avoid potential system hangs.
+**/
+  PCIE_ASPM_OVERRIDE_LIST  *PcieAspmDevsOverride;
+/**
+  Offset 48: This field is used as a pointer to the LTR device override table, default points to an existing
+  table mPcieLtrDevsOverride.\n
+  Refer to DxeSaPolicyLib.c for the usage.
+**/
+  PCIE_LTR_DEV_INFO        *PcieLtrDevsOverride;
+  SA_PCIE_PWR_OPT          PegPwrOpt[SA_PEG_MAX_FUN];     ///< Offset 60: This field is used to describe the PCIe LTR/OBFF relevant settings
+  UINT8                    Rsvd1[3];                      /// Reserved for future use
+} PCIE_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h
new file mode 100644
index 0000000000..7899504865
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h
@@ -0,0 +1,60 @@
+/** @file
+  Policy definition for PCIe Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_PEI_CONFIG_H_
+#define _PCIE_PEI_CONFIG_H_
+
+#include <Library/GpioLib.h>
+#include <SaAccess.h>
+
+#pragma pack(push, 1)
+
+#define SA_PCIE_PEI_CONFIG_REVISION 1
+
+/**
+ PCI Express and DMI controller configuration - PostMem\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 Extended Sync Control
+  - <b>Disabled</b> (0x0)  : Disable DMI Extended Sync (Default)
+  - Enabled         (0x1)  : Enable DMI Extended Sync
+  **/
+  UINT32                 DmiExtSync                      :  1;
+  /**
+    Offset 28:1
+   <b>(Test)</b>DMI IOT Control
+  - <b>Disabled</b> (0x0)  : Disable DMI IOT (Default)
+  - Enabled         (0x1)  : Enable DMI IOT
+  **/
+  UINT32                 DmiIot                          :  1;
+  UINT32                 RsvdBits1                       :  30;       ///< Offset 28:2-31 :Reserved for future use.
+  UINT8                  DmiAspm;                                     ///< Offset 32 This field is used to describe the ASPM control for DMI: <b>3=PcieAspmL0sL1</b>, 2=PcieAspmL1, 1=PcieAspmL0s, 0=PcieAspmDisabled.
+  UINT8                  Rsvd1[3];                                    ///< Offset 33 to 35
+  UINT8                  PegDeEmphasis[SA_PEG_MAX_FUN];               ///< Offset 36 This field is used to describe the DeEmphasis control for PEG (-6 dB and -3.5 dB are the options)SA_PEG_MAX_FUN = 3 for CFL and SA_PEG_MAX_FUN = 4 for CNL, offsets are adjusted accordingly
+  UINT8                  PegMaxPayload[SA_PEG_MAX_FUN];               ///< <b>(Test)</b> Offset 39/40 This field is used to describe the PEG Max Pay Load Size (0xFF: Auto, 0:128B, 1:256B)
+  /**
+   PCIe Slot Power Capabilities. SlotPowerLimitValue in combination with SlotPowerLimitScale specifies the upper limit on power supplied by slot.
+  **/
+  UINT8                  PegSlotPowerLimitValue[SA_PEG_MAX_FUN];      ///< Offset 42/44 8 bit value
+  UINT8                  PegSlotPowerLimitScale[SA_PEG_MAX_FUN];      ///< Offset 45/48 2 bit value: <b>00 = 1.0x</b>, 01 = 0.1x, 10 = 0.01x and 11 = 0.001x
+  /**
+   Offset 48/52
+   PCIe Physical Slot Number (13 bit value). Indicates the physical slot number attached to the port.
+  **/
+  UINT16                 PegPhysicalSlotNumber[SA_PEG_MAX_FUN];
+  UINT8                  Rsvd2[2];
+} PCIE_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h
new file mode 100644
index 0000000000..a53bf3c7bd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h
@@ -0,0 +1,354 @@
+/** @file
+  Policy definition for PCIe Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_PEI_PREMEM_CONFIG_H_
+#define _PCIE_PEI_PREMEM_CONFIG_H_
+
+#include <Library/GpioLib.h>
+#include <SaAccess.h>
+
+#pragma pack(push, 1)
+
+#define SA_PCIE_PEI_PREMEM_CONFIG_REVISION 3
+
+///
+/// SA GPIO Data Structure
+///
+typedef struct {
+  GPIO_PAD      GpioPad;        ///< Offset 0: GPIO Pad
+  UINT8         Value;          ///< Offset 4: GPIO Value
+  UINT8         Rsvd0[3];       ///< Offset 5: Reserved for 4 bytes alignment
+  UINT32        Active  :1;     ///< Offset 8: 0=Active Low; 1=Active High
+  UINT32        RsvdBits0:31;
+} SA_GPIO_INFO_PCIE;
+
+///
+/// SA Board PEG GPIO Info
+///
+typedef struct {
+  SA_GPIO_INFO_PCIE  SaPeg0ResetGpio;    ///< Offset 0:  PEG0 PERST# GPIO assigned, must be a PCH GPIO pin
+  SA_GPIO_INFO_PCIE  SaPeg3ResetGpio;    ///< Offset 12: PEG3 PERST# GPIO assigned, must be a PCH GPIO pin
+  BOOLEAN            GpioSupport;        ///< Offset 24: 1=Supported; 0=Not Supported
+  UINT8              Rsvd0[3];           ///< Offset 25: Reserved for 4 bytes alignment
+} PEG_GPIO_DATA;
+
+
+/**
+ 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.
+  <b>Revision 2</b>:
+  - Change PegGen3RxCtleOverride of PCIE_PEI_PREMEM_CONFIG from one bit to UINT8
+  - Change DmiGen3RxCtlePeaking default to 0
+  <b>Revision 3</b>:
+  - Added PEG IMR support
+  - Added UINT8 PegImrEnable
+  - Added UINT16 PegImrSize
+  - Added UINT8 ImrRpSelection
+**/
+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;
+
+  /**
+   Offset 28:8 to 28:15 :
+   <b>(Test)</b> PEG Enable Control
+  - Disabled    (0x0)  : Disable PEG Port
+  - Enabled     (0x1)  : Enable PEG Port (If Silicon SKU permits it)
+  - <b>Auto</b> (0x2)  : If an endpoint is present, enable the PEG Port, Disable otherwise (Default)
+  **/
+  UINT32                 Peg0Enable                      :  2;        ///< Enable/Disable PEG 0:1:0 Root Port
+  UINT32                 Peg1Enable                      :  2;        ///< <b>(Test)</b> Enable/Disable PEG 0:1:1 Root Port
+  UINT32                 Peg2Enable                      :  2;        ///< <b>(Test)</b> Enable/Disable PEG 0:1:2 Root Port
+  UINT32                 Peg3Enable                      :  2;        ///< <b>(Test)</b> Enable/Disable PEG 0:6:0 Root Port.
+
+  /**
+   Offset 28:16 :
+   <b>(Test)</b> PCIe 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                 Peg0MaxLinkSpeed                :  2;        ///< PCIe Link Speed Control for PEG 0:1:0 Root Port.
+  UINT32                 Peg1MaxLinkSpeed                :  2;        ///< <b>(Test)</b> PCIe Link Speed Control for PEG 0:1:1 Root Port.
+  UINT32                 Peg2MaxLinkSpeed                :  2;        ///< <b>(Test)</b> PCIe Link Speed Control for PEG 0:1:2 Root Port.
+  UINT32                 Peg3MaxLinkSpeed                :  2;        ///< <b>(Test)</b> PCIe Link Speed Control for PEG 0:6:0 Root Port.
+  UINT32                 RsvdBits0                       :  8;        ///< Offset 28:24 :Reserved for future use
+
+  /**
+   Offset 32:0 :
+   <b>(Test)</b> PCIe Link Width Control
+  - <b>Auto</b> (0x0)  : Maximum possible Link width (Default)
+  - X1          (0x1)  : Limit Link to X1 Width
+  - X2          (0x2)  : Limit Link to X2 Width
+  - X4          (0x3)  : Limit Link to X4 Width
+  - X8          (0x4)  : Limit Link to X8 Width
+  **/
+  UINT32                 Peg0MaxLinkWidth                :  3;        ///< PCIe Link Width Control for PEG 0:1:0 Root Port.
+  UINT32                 Peg1MaxLinkWidth                :  3;        ///< <b>(Test)</b> PCIe Link Width Control for PEG 0:1:1 Root Port.
+  UINT32                 Peg2MaxLinkWidth                :  3;        ///< <b>(Test)</b> PCIe Link Width Control for PEG 0:1:2 Root Port.
+  UINT32                 Peg3MaxLinkWidth                :  3;        ///< <b>(Test)</b> PCIe Link Width Control for PEG 0:6:0 Root Port.
+  /**
+    Offset 32:12 to 32:15 :
+    Power down unused lanes on the PEG Root Port.
+  - Disabled     (0x0) : No power saving.
+  - <b>Auto</b>  (0x1) : Bios will power down unused lanes based on the max possible link width
+  **/
+  UINT32                 Peg0PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:1:0 Root Port.
+  UINT32                 Peg1PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:1:1 Root Port.
+  UINT32                 Peg2PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:1:2 Root Port.
+  UINT32                 Peg3PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:6:0 Root Port.
+
+  /**
+   Offset 32:16 to 32:23 :
+   <b>(Test)</b> PCIe 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                 Peg0Gen3EqPh2Enable             :  2;        ///< Phase2 EQ enable on the PEG 0:1:0 Root Port.
+  UINT32                 Peg1Gen3EqPh2Enable             :  2;        ///< <b>(Test)</b> Phase2 EQ enable on the PEG 0:1:1 Root Port.
+  UINT32                 Peg2Gen3EqPh2Enable             :  2;        ///< <b>(Test)</b> Phase2 EQ enable on the PEG 0:1:2 Root Port.
+  UINT32                 Peg3Gen3EqPh2Enable             :  2;        ///< <b>(Test)</b> Phase2 EQ enable on the PEG 0:6:0 Root Port.
+  UINT32                 RsvdBits1                       :  8;        ///< Offset 32:24 :Reserved for future use
+  /**
+   Offset 36:0 to 36:11 :
+   <b>(Test)</b> Select the method for performing Phase3 of Gen3 Equalization.
+  - <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 PegGen3EndPointPreset array for Phase1 AND Phase3 (Instead of just Phase1)
+  - Disabled    (0x4)  : Bypass Equalization Phase 3
+  **/
+  UINT32                 Peg0Gen3EqPh3Method             :  3;        ///< Phase3 EQ method on the PEG 0:1:0 Root Port.
+  UINT32                 Peg1Gen3EqPh3Method             :  3;        ///< <b>(Test)</b> Phase3 EQ method on the PEG 0:1:1 Root Port.
+  UINT32                 Peg2Gen3EqPh3Method             :  3;        ///< <b>(Test)</b> Phase3 EQ method on the PEG 0:1:2 Root Port.
+  UINT32                 Peg3Gen3EqPh3Method             :  3;        ///< <b>(Test)</b> Phase3 EQ method on the PEG 0:6:0 Root Port.
+  /**
+   Offset 36:12 :
+   <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;
+  /**
+   Offset 36:13 :
+   <b>(Test)</b> Always Attempt Gen3 Software Equalization
+
+   When enabled, Gen3 Software Equalization will be executed every boot.  When disabled, it will be only executed if the CPU
+   or EP is changed, otherwise it is skipped and the previous EQ value will be re-used.
+
+   This setting will only have an effect if Software Equalization is enabled and OEM Platform Code implements
+   save/restore of the PegDataPtr data (see below).  If PegDataPtr is not saved/restored RC forces this to be enabled.
+
+  - <b>Disabled</b> (0x0)  : Reuse EQ settings saved/restored from NVRAM whenever possible (Default)
+  - Enabled         (0x1)  : Re-test and generate new EQ values every boot, not recommended
+  **/
+  UINT32                 Gen3SwEqAlwaysAttempt           :  1;
+  /**
+   Offset 36:14 to 36:16 :
+   <b>(Test)</b> Select number of TxEq presets to test in the PCIe/DMI Software Equalization Algorithm
+  - P7,P3,P5,P8 (0x0)  : Test Presets 7, 3, 5, and 8
+  - P0-P9       (0x1)  : Test Presets 0-9
+  - <b>Auto</b> (0x2)  : Use the current default method (Default)
+  Auto will test Presets 7, 3, 5, and 8.  It is possible for this default to change over time;
+  using "Auto" will ensure Reference Code always uses the latest default settings.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  **/
+  UINT32                 Gen3SwEqNumberOfPresets         :  3;
+  /**
+   Offset 36:17 to 36:18:
+   <b>(Test)</b> Offset 36 Enable use of the Voltage Offset and Centering Test in the PCIe Software Equalization Algorithm
+  - Disabled     (0x0) : Disable VOC Test
+  - Enabled      (0x1) : Enable VOC Test
+  - <b>Auto</b>  (0x2) : Use the current default (Default)
+  **/
+  UINT32                 Gen3SwEqEnableVocTest           :  2;
+  /**
+    Offset 36:19 :
+    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;
+  /**
+   Offset 36:20 :
+   <b>(Test)</b> PCIe Rx Compliance Testing Mode
+  - <b>Disabled</b> (0x0) : Normal Operation             - Disable PCIe Rx Compliance testing (Default)
+  - Enabled         (0x1) : PCIe Rx Compliance Test Mode - PEG controller is in Rx Compliance Testing Mode; it should only be set when doing PCIe compliance testing
+  **/
+  UINT32                 PegRxCemTestingMode             :  1;
+
+  /**
+    Offset 36:21 to 36:24 :
+    <b>(Test)</b> PCIe Rx Compliance Loopback Lane
+
+    When PegRxCemTestingMode is Enabled, the specificied Lane (0 - 15) will be
+    used for RxCEMLoopback.
+
+    Default is Lane 0.
+  **/
+  UINT32                 PegRxCemLoopbackLane            :  4;
+  /**
+   Offset 36:25 to 36:28 :
+   <b>(Test)</b> Generate PCIe BDAT Margin Table. Set this policy to enable the generation and addition of PCIe margin data to the BDAT table.
+  - <b>Disabled</b> (0x0) : Normal Operation          - Disable PCIe BDAT margin data generation (Default)
+  - PortData        (0x1) : Port Data                 - Generate PCIe BDAT margin data
+  **/
+  UINT32                 PegGenerateBdatMarginTable      :  4;
+   /**
+   Offset 36:29 :
+   <b>(Test)</b> PCIe Non-Protocol Awareness for Rx Compliance Testing
+  - <b>Disabled</b> (0x0) : Normal Operation                - Disable non-protocol awareness (Default)
+  - Enabled         (0x1) : Non-Protocol Awareness Enabled  - Enable non-protocol awareness for compliance testing
+  **/
+  UINT32                 PegRxCemNonProtocolAwareness    :  1;
+   /**
+   Offset 36:30 :
+   <b>(Test)</b> PCIe Disable Spread Spectrum Clocking. This feature should be TRUE only for compliance testing
+  - <b>False</b>          (0x0) : Normal Operation                 - SSC enabled  (Default)
+  - True                  (0x1) : Disable SSC                      - Disable SSC for compliance testing
+  **/
+  UINT32                 PegDisableSpreadSpectrumClocking :  1;
+
+  UINT32                 RsvdBits2                        :  1;
+
+  UINT8                  DmiGen3RootPortPreset[SA_DMI_MAX_LANE];      ///< Offset 40 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 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 48 Hint value per lane for the DMI Gen3 End Point. Range: 0-6, 2 is default for each lane
+  /**
+   Offset 52 :
+   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 0.
+  **/
+
+  UINT8                  DmiGen3RxCtlePeaking[SA_DMI_MAX_BUNDLE];
+
+  UINT8                  PegGen3RootPortPreset[SA_PEG_MAX_LANE];      ///< Offset 54 <b>(Test)</b> Used for programming PEG Gen3 preset values per lane. Range: 0-9, 8 is default for each lane
+  UINT8                  PegGen3EndPointPreset[SA_PEG_MAX_LANE];      ///< Offset 70 <b>(Test)</b> Used for programming PEG Gen3 preset values per lane. Range: 0-9, 7 is default for each lane
+  UINT8                  PegGen3EndPointHint[SA_PEG_MAX_LANE];        ///< Offset 86 <b>(Test)</b> Hint value per lane for the PEG Gen3 End Point. Range: 0-6, 2 is default for each lane
+  /**
+   Offset 102:
+   PCIe 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                  PegGen3RxCtlePeaking[SA_PEG_MAX_BUNDLE];
+  /**
+  Offset 110:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 1000.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  @note An attack on this policy could result in an apparent hang,
+    but the system will eventually boot.  This variable should be protected.
+  **/
+  UINT16                 Gen3SwEqJitterDwellTime;
+  /**
+   Offset 112:
+   This is a memory data pointer for saved preset search results. The reference code will store
+   the Gen3 Preset Search results in the SaPegHob. In order to skip the Gen3
+   preset search on boots where the PEG card configuration has not changed since the previous boot,
+   platform code can save the contents of the SaPegHob in DXE (When it present and for size reported by Header.HobLength)
+   and provide a pointer to a restored copy of that data. Default value is NULL, which results in a full
+   preset search every boot.
+
+   @note An attack on this policy could prevent the PCIe display from working until a boot when
+   PegDataPtr is NULL or Gen3SwEqAlwaysAttempt is enabled.  The variable used to save the
+   preset search results should be protected in a way that it can only be modified by the
+   platform manufacturer.
+  **/
+  VOID                   *PegDataPtr;
+  /**
+  Offset 116:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 1.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  **/
+  UINT16                 Gen3SwEqJitterErrorTarget;
+
+  /**
+  Offset 118:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 10000.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  @note An attack on this policy could result in an apparent hang,
+    but the system will eventually boot.  This variable should be protected.
+  **/
+  UINT16                 Gen3SwEqVocDwellTime;
+
+  /**
+  Offset 120:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 2.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  **/
+  UINT16                 Gen3SwEqVocErrorTarget;
+  /**
+  Offset 122:
+    PCIe Hot Plug Enable/Disable. It has 2 policies.
+  - Disabled (0x0)     : No hotplug.
+  - Enabled (0x1)      : Bios assist hotplug.
+  **/
+  UINT8                  PegRootPortHPE[SA_PEG_MAX_FUN];
+  UINT8                  DmiDeEmphasis;                               ///< Offset 125 This field is used to describe the DeEmphasis control for DMI (-6 dB and -3.5 dB are the options)
+  UINT8                  Rsvd0[2];                                    ///< Offset 126
+  /**
+   Offset 128:
+   This contains the PCIe PERST# GPIO information.  This structure is required
+   for PCIe Gen3 operation. The reference code will use the information in this structure in
+   order to reset PCIe Gen3 devices during equalization, if necessary.  Refer to the Platform
+   Developer's Guide (PDG) for additional details.
+  **/
+  PEG_GPIO_DATA          PegGpioData;
+
+   /**
+   Offset 156
+   <b>(Test)</b> PCIe Override RxCTLE. This feature should only be true to disable RxCTLE adaptive behavior for compliance testing
+  - <b>False</b>          (0x0) : Normal Operation                 - RxCTLE adaptive behavior enabled  (Default)
+  - True                  (0x1) : Override RxCTLE                  - Disable RxCTLE adaptive behavior to keep the configured RxCTLE peak values unmodified
+  From CFL onwards, modularity is introduced to this setup option so that the RxCTLE adaptive behavior could be controlled at the controller level.
+  Making this variable a UINT8 to accomodate the values of all controllers as bit definition
+  **/
+  UINT8                 PegGen3RxCtleOverride;
+  UINT8                 Reserved1;
+  UINT16                Reserved2;
+
+} PCIE_PEI_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_PEI_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
new file mode 100644
index 0000000000..12648b836b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
@@ -0,0 +1,61 @@
+/** @file
+  Policy details for miscellaneous configuration in System Agent
+
+  Copyright (c) 2019 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)
+
+#ifndef SA_MC_MAX_SOCKETS
+#define SA_MC_MAX_SOCKETS 4
+#endif
+
+#define SA_MISC_PEI_CONFIG_REVISION 1
+
+///
+/// Subsystem Vendor ID / Subsystem ID
+///
+typedef struct _SA_DEFAULT_SVID_SID{
+  UINT16         SubSystemVendorId;
+  UINT16         SubSystemId;
+} SA_DEFAULT_SVID_SID;
+
+/**
+  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
+  /**
+  Offset 28:0
+  This policy is used to control enable or disable System Agent Thermal device (0,4,0).
+  The default value is <b>1: TRUE</b> for WHL, and <b>0: FALSE</b> for all other CPU's
+  **/
+  UINT32  Device4Enable:1;
+  /**
+  Offset 28:1
+  <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.
+  **/
+  UINT32  ChapDeviceEnable:1;
+  /**
+  Offset 28:2
+  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  CridEnable:1;
+  UINT32  SkipPamLock:1;                     ///< Offset 28:3 :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.
+  UINT32  EdramTestMode:2;                   ///< Offset 28:4 :EDRAM Test Mode. For EDRAM stepping - 0- EDRAM SW Disable, 1- EDRAM SW Enable, <b> 2- EDRAM HW Mode</b>
+  UINT32  RsvdBits0          :26;            ///< Offset 28:7 :Reserved for future use
+} SA_MISC_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _SA_MISC_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
new file mode 100644
index 0000000000..2c831404ef
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
@@ -0,0 +1,103 @@
+/** @file
+  Policy details for miscellaneous configuration in System Agent
+
+  Copyright (c) 2019 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 SA_MC_MAX_SOCKETS
+#define SA_MC_MAX_SOCKETS 4
+#endif
+
+#define SA_MISC_PEI_PREMEM_CONFIG_REVISION 3
+
+/**
+  This configuration block is to configure SA Miscellaneous variables during PEI Pre-Mem phase like programming
+  different System Agent BARs, TsegSize, IedSize, MmioSize required etc.
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - add BdatTestType, default is RMT
+  <b>Revision 3</b>:
+  - Remove SgSubSystemId.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+  UINT8   SpdAddressTable[SA_MC_MAX_SOCKETS];///< Offset 28 Memory DIMMs' SPD address for reading SPD data. <b>example: SpdAddressTable[0]=0xA2(C0D0), SpdAddressTable[1]=0xA0(C0D1), SpdAddressTable[2]=0xA2(C1D0), SpdAddressTable[3]=0xA0(C1D1)</b>
+  VOID    *S3DataPtr;                        ///< Offset 32 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  MchBar;                            ///< Offset 36 Address of System Agent MCHBAR: <b>0xFED10000</b>
+  UINT32  DmiBar;                            ///< Offset 40 Address of System Agent DMIBAR: <b>0xFED18000</b>
+  UINT32  EpBar;                             ///< Offset 44 Address of System Agent EPBAR: <b>0xFED19000</b>
+  UINT32  SmbusBar;                          ///< Offset 48 Address of System Agent SMBUS BAR: <b>0xEFA0</b>
+  UINT32  GdxcBar;                           ///< Offset 52 Address of System Agent GDXCBAR: <b>0xFED84000</b>
+  /**
+    Offset 56 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;
+  UINT32  EdramBar;                          ///< Offset 60 Address of System Agent EDRAMBAR: <b>0xFED80000</b>
+  /**
+    Offset 64
+    <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>
+  **/
+  UINT32  IedSize;
+  UINT8   UserBd;                            ///< Offset 68 <b>0=Mobile/Mobile Halo</b>, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile Halo, 7=UP Server
+  UINT8   SgMode;                            ///< Offset 69 SgMode: <b>0=Disabled</b>, 1=SG Muxed, 2=SG Muxless, 3=PEG
+  UINT16  SgDelayAfterPwrEn;                 ///< Offset 70 Dgpu Delay after Power enable using Setup option: 0=Minimal, 1000=Maximum, <b>300=300 microseconds</b>
+  UINT16  SgDelayAfterHoldReset;             ///< Offset 72 Dgpu Delay after Hold Reset using Setup option: 0=Minimal, 1000=Maximum, <b>100=100 microseconds</b>
+  UINT32  SkipExtGfxScan:1;                  ///< <b>(Test)</b> OFfset 74: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 74:1 :This field enables the generation of the BIOS DATA ACPI Tables: <b>0=FALSE</b>, 1=TRUE.
+  UINT32  TxtImplemented:1;                  ///< OFfset 74: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 74: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.  If the primary graphics device only implements legacy VBIOS, then the
+   LegacyOnlyVgaOpRomDetected field in the SA_DATA_HOB will be set to 1.
+
+   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 74:4 :Reserved for future use
+  UINT8   LockPTMregs;                       ///< <b>(Test)</b> Offset 78 Lock PCU Thermal Management registers: 0=FALSE, <b>1=TRUE</b>
+  UINT8   BdatTestType;                      ///< Offset 79 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   Rsvd1[4];                          ///< Offset 80 Reserved for future use
+  /**
+    Offset 84 :
+    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.
+  **/
+  UINT16  MmioSize;
+  INT16   MmioSizeAdjustment;                ///< Offset 86 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>
+  UINT64  AcpiReservedMemoryBase;            ///< Offset 88 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 96 Total system memory length from previous boot, this is required for S3 resume. Originally it is retrieved from AcpiVariableCompatibility variable.
+  UINT32  AcpiReservedMemorySize;            ///< Offset 104 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 108 Temporary address to MMIO map OpROMs during VGA scanning.  Used for ScanExtGfxForLegacyOpRom feature.  MUST BE 16MB ALIGNED!
+  UINT32  OpRomScanTempMmioLimit;            ///< <b>(Test)</b> Offset 112 Limit address for OpROM MMIO range.  Used for ScanExtGfxForLegacyOpRom feature. (OpROMScanTempMmioLimit - OpRomScanTempMmioBar) MUST BE >= 16MB!
+
+  // 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/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h
new file mode 100644
index 0000000000..cc6179a61c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h
@@ -0,0 +1,63 @@
+/** @file
+  Switchable Graphics policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SWITCHABLE_GRAPHICS_CONFIG_H_
+#define _SWITCHABLE_GRAPHICS_CONFIG_H_
+
+#define SWITCHABLE_GRAPHICS_CONFIG_REVISION 1
+
+#define GP_ENABLE   1
+#define GP_DISABLE  0
+
+#pragma pack(push, 1)
+///
+/// GPIO Support
+///
+typedef enum {
+  NotSupported = 0,
+  PchGpio,
+  I2CGpio,
+} GPIO_SUPPORT;
+
+///
+/// SA 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
+} SA_GPIO_INFO;
+
+/**
+ SA PCIE RTD3 GPIO Data Structure
+**/
+typedef struct {
+  SA_GPIO_INFO  HoldRst;      ///< Offset 0 This field contain PCIe HLD RESET GPIO value and level information
+  SA_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
+} SA_PCIE_RTD3_GPIO;
+
+/**
+  This Configuration block configures SA PCI Express 0/1/2 RTD3 GPIOs & Root Port.
+  Swithable Gfx/Hybrid Gfx uses the same GPIOs & Root port as PCI Express 0/1/2 RTD3.
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER Header;             ///< Offset 0-27 Config Block Header
+  SA_PCIE_RTD3_GPIO   SaRtd3Pcie0Gpio;    ///< Offset 28 RTD3 GPIOs used for PCIe0
+  SA_PCIE_RTD3_GPIO   SaRtd3Pcie1Gpio;    ///< Offset 52 RTD3 GPIOs used for PCIe1
+  SA_PCIE_RTD3_GPIO   SaRtd3Pcie2Gpio;    ///< Offset 76 RTD3 GPIOs used for PCIe2
+  UINT8               RootPortIndex;      ///< Offset 124 Root Port Index number used for SG
+  UINT8               Rsvd0[3];           ///< Offset 125 Reserved for DWORD Alignment
+} SWITCHABLE_GRAPHICS_CONFIG;
+#pragma pack(pop)
+#endif // _SWITCHABLE_GRAPHICS_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h
new file mode 100644
index 0000000000..690ad8630a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h
@@ -0,0 +1,39 @@
+/** @file
+  VBIOS DXE policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VBIOS_DXE_CONFIG_H_
+#define _VBIOS_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define VBIOS_DXE_CONFIG_REVISION 1
+
+/**
+  This data structure includes Switchable Graphics VBIOS configuration.
+  If Switchable Graphics/Hybrid Gfaphics feature is not supported, all the policies in this configuration block can 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
+  UINT8                 LoadVbios    : 1;    ///< Offset 28:0 :This field is used to describe if the dGPU VBIOS needs to be loaded: <b>0=Not load</b>, 1=Load
+  UINT8                 ExecuteVbios : 1;    ///< Offset 28:1 :This field is used to describe if the dGPU VBIOS need to be executed: <b>0=Not execute</b>, 1=Execute
+/**
+  Offset 28:2 :
+  This field is used to identify the source location of dGPU VBIOS\n
+  <b>1 = secondary display device VBIOS Source is PCI Card</b>\n
+  0 = secondary display device VBIOS Source is FW Volume\n
+**/
+  UINT8                 VbiosSource  : 1;
+  UINT8                 RsvdBits0    : 5;    ///< Offset 28:3 Reserved for future use
+  UINT8                 Rsvd[3];             ///< Offset 29 : Reserved for DWORD alignment
+} VBIOS_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _VBIOS_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h
new file mode 100644
index 0000000000..adde1f836b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h
@@ -0,0 +1,42 @@
+/** @file
+  VT-d policy definitions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VTD_CONFIG_H_
+#define _VTD_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define VTD_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.
+  <b>Revision 2</b>:
+  - Add DMA_CONTROL_GUARANTEE bit in the DMAR table
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;                      ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28:0 :
+    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.
+  **/
+  UINT32        VtdDisable               : 1;
+  UINT32        X2ApicOptOut             : 1;       ///< Offset 28:1 :This field is used to enable the X2APIC_OPT_OUT bit in the DMAR table. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT32        DmaControlGuarantee      : 1;       ///< Offset 28:2 :This field is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT32        RsvdBits0                : 29;      ///< Offset 28:3 :Reserved bits for future use
+  UINT32        BaseAddress[SA_VTD_ENGINE_NUMBER];  ///< Offset 32: This field is used to describe the base addresses for VT-d function: <b>BaseAddress[0]=0xFED90000, BaseAddress[1]=0xFED92000, BaseAddress[2]=0xFED91000 </b>
+} VTD_CONFIG;
+#pragma pack(pop)
+
+#endif   //  _VTD_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h
new file mode 100644
index 0000000000..a1d88cb5a2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h
@@ -0,0 +1,77 @@
+/** @file
+  This code defines ACPI DMA Remapping table related definitions.
+  See the System Agent BIOS specification for definition of the table.
+
+  Copyright (c) 2019 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>
+
+#pragma pack(1)
+///
+/// DMAR table signature
+///
+#define EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE   0x52414D44  ///< "DMAR"
+#define EFI_ACPI_DMAR_TABLE_REVISION        1
+#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];    // CSME
+} EFI_ACPI_RMRR_CSME_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_USB_STRUC       RmrrUsb;
+  EFI_ACPI_RMRR_IGD_STRUC       RmrrIgd;
+  EFI_ACPI_RMRR_CSME_STRUC      RmrrCsme;
+} EFI_ACPI_DMAR_TABLE;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h
new file mode 100644
index 0000000000..663b0f2202
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h
@@ -0,0 +1,60 @@
+/** @file
+  Prototype of the DxeSaPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_LIB_H_
+#define _DXE_SA_POLICY_LIB_H_
+
+#include <Protocol/SaPolicy.h>
+
+/**
+  This function prints the DXE phase policy.
+
+  @param[in] SaPolicy    - SA DXE Policy protocol
+**/
+VOID
+SaPrintPolicyProtocol (
+  IN  SA_POLICY_PROTOCOL         *SaPolicy
+  )
+;
+
+/**
+  CreateSaDxeConfigBlocks generates the config blocksg 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 Policy 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
+);
+
+/**
+  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
+  )
+;
+
+#endif // _DXE_SA_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h
new file mode 100644
index 0000000000..c29d67a305
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h
@@ -0,0 +1,87 @@
+/** @file
+  Prototype of the PeiSaPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_LIB_H_
+#define _PEI_SA_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI instance
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  );
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi              The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  );
+
+/**
+  Get SA config block table total size.
+
+  @retval     Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get SA config block table total size.
+
+  @retval      Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSizePreMem (
+  VOID
+  );
+
+/**
+  SaAddConfigBlocksPreMem add all SA config blocks.
+
+  @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
+SaAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  SaAddConfigBlocks add all SA config blocks.
+
+  @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
+SaAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
new file mode 100644
index 0000000000..a1289abe81
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
@@ -0,0 +1,88 @@
+/** @file
+  Header file for SaPlatformLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PLATFORM_LIB_H_
+#define _SA_PLATFORM_LIB_H_
+
+#include <SaAccess.h>
+#include <CpuAccess.h>
+
+/**
+  Determine if PCH Link is DMI/OPI
+
+  @param[in] CpuModel             CPU model
+
+  @retval TRUE                    DMI
+  @retval FALSE                   OPI
+**/
+BOOLEAN
+IsPchLinkDmi (
+  IN CPU_FAMILY  CpuModel
+  );
+
+/**
+  Returns the number of DMI lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiLanes (
+  );
+
+
+/**
+  Returns the number of DMI bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiBundles (
+  );
+
+
+/**
+  Returns the function numbers for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegFuncs (
+  );
+
+
+/**
+  Returns the number of DMI lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegLanes (
+  );
+
+
+/**
+  Returns the number of DMI bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegBundles (
+  );
+
+/**
+  Checks if PEG port is present
+
+  @retval TRUE     PEG is presented
+  @retval FALSE    PEG is not presented
+**/
+BOOLEAN
+IsPegPresent (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
new file mode 100644
index 0000000000..da285bbcba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
@@ -0,0 +1,259 @@
+/** @file
+  This file contains definitions required for creation of
+  Memory S3 Save data, Memory Info data and Memory Platform
+  data hobs.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MEM_INFO_HOB_H_
+#define _MEM_INFO_HOB_H_
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+
+#pragma pack (push, 1)
+
+extern EFI_GUID gSiMemoryS3DataGuid;
+extern EFI_GUID gSiMemoryInfoDataGuid;
+extern EFI_GUID gSiMemoryPlatformDataGuid;
+
+#define MAX_NODE        1
+#define MAX_CH          2
+#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 MrcChannelSts enum in MRC
+//
+#ifndef CHANNEL_NOT_PRESENT
+#define CHANNEL_NOT_PRESENT     0  // There is no channel present on the controller.
+#endif
+#ifndef CHANNEL_DISABLED
+#define CHANNEL_DISABLED     1  // There is a channel present but it is disabled.
+#endif
+#ifndef CHANNEL_PRESENT
+#define CHANNEL_PRESENT     2  // There is a channel present and it is enabled.
+#endif
+
+//
+// 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 bmCold
+#define bmCold 0            // Cold boot
+#endif
+#ifndef bmWarm
+#define bmWarm 1            // Warm boot
+#endif
+#ifndef bmS3
+#define bmS3   2            // S3 resume
+#endif
+#ifndef bmFast
+#define bmFast 3            // Fast boot
+#endif
+
+//
+// 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_UNKNOWN
+#define MRC_DDR_TYPE_UNKNOWN  3
+#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;
+
+typedef struct {
+  UINT8 SG;         ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;         ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;         ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;         ///< Number of tCK cycles between transactions when switching between DIMMs.
+} MRC_TA_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.
+} 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.
+  MRC_TA_TIMING    tRd2Rd;                  ///< Read-to-Read   Turn Around Timings
+  MRC_TA_TIMING    tRd2Wr;                  ///< Read-to-Write  Turn Around Timings
+  MRC_TA_TIMING    tWr2Rd;                  ///< Write-to-Read  Turn Around Timings
+  MRC_TA_TIMING    tWr2Wr;                  ///< Write-to-Write Turn Around Timings
+} 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.
+  MRC_TA_TIMING    tRd2Rd;                   ///< Deprecated and moved to CHANNEL_INFO. Read-to-Read   Turn Around Timings
+  MRC_TA_TIMING    tRd2Wr;                   ///< Deprecated and moved to CHANNEL_INFO. Read-to-Write  Turn Around Timings
+  MRC_TA_TIMING    tWr2Rd;                   ///< Deprecated and moved to CHANNEL_INFO. Write-to-Read  Turn Around Timings
+  MRC_TA_TIMING    tWr2Wr;                   ///< Deprecated and moved to CHANNEL_INFO. Write-to-Write Turn Around Timings
+} CONTROLLER_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;
+  UINT32            PrmrrBase;
+  UINT32            GttBase;
+  UINT32            MmioSize;
+  UINT32            PciEBaseAddress;
+  UINT32            GdxcIotBase;
+  UINT32            GdxcIotSize;
+  UINT32            GdxcMotBase;
+  UINT32            GdxcMotSize;
+} 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/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h
new file mode 100644
index 0000000000..ff7cfa838f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h
@@ -0,0 +1,15 @@
+/** @file
+  Graphics header file
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_INIT_H_
+#define _GRAPHICS_INIT_H_
+
+#include <SaPolicyCommon.h>
+#include <Ppi/SiPolicy.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h
new file mode 100644
index 0000000000..497c860824
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h
@@ -0,0 +1,33 @@
+/** @file
+  This code supports a private implementation of the Legacy Region protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _LEGACY_REGION_H_
+#define _LEGACY_REGION_H_
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/LegacyRegion2.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/Cpu.h>
+#include <IndustryStandard/Pci22.h>
+#include <SaAccess.h>
+
+/**
+  Install Driver to produce Legacy Region protocol.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS - Legacy Region protocol installed
+  @retval Other       - No protocol installed, unload driver.
+**/
+EFI_STATUS
+LegacyRegionInstall (
+  IN EFI_HANDLE           ImageHandle
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h
new file mode 100644
index 0000000000..8bf46528ab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for North TraceHub Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _NORTH_TRACEHUB_LIB_H_
+#define _NORTH_TRACEHUB_LIB_H_
+
+#include <SaPolicyCommon.h>
+#include <SaAccess.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/MtrrLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h
new file mode 100644
index 0000000000..19dd634a35
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h
@@ -0,0 +1,70 @@
+/** @file
+  Defines and prototypes for the System Agent PCIe library module
+  This library is expected to share between DXE and SMM drivers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PCIE_LIB_H_
+#define _SA_PCIE_LIB_H_
+
+#include <Library/S3BootScriptLib.h>
+#include <Protocol/SaPolicy.h>
+
+#define MAX_SUPPORTED_ROOT_BRIDGE_NUMBER  3
+#define MAX_SUPPORTED_DEVICE_NUMBER       192
+
+/**
+  Enumerate all end point devices connected to root bridge ports and record their MMIO base address
+
+  @exception EFI_UNSUPPORTED      PCIe capability structure not found
+  @retval    EFI_SUCCESS          All done successfully
+**/
+EFI_STATUS
+EnumerateAllPcieDevices (
+  VOID
+  );
+
+/**
+  Sets Common Clock, TCx-VC0 mapping, and Max Payload for PCIe
+**/
+VOID
+SaPcieConfigBeforeOpRom (
+  VOID
+  );
+
+/**
+  This function does all SA ASPM initialization
+**/
+VOID
+SaAspm (
+  VOID
+  );
+
+/**
+  This function checks PEG end point device for extended tag capability and enables them if they are.
+**/
+VOID
+EnableExtendedTag (
+  VOID
+  );
+
+/**
+  This function handles SA S3 resume
+**/
+VOID
+SaS3Resume (
+  VOID
+  );
+
+/**
+  Wrapper function for all SA S3 resume tasks which can be a callback function.
+**/
+VOID
+SaS3ResumeCallback (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h
new file mode 100644
index 0000000000..2c765b09b8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h
@@ -0,0 +1,36 @@
+/** @file
+  This file defines the SA Iotrap SMI Protocol to provide the
+  I/O address for registered Iotrap SMI.
+
+  Copyright (c) 2019 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;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h
new file mode 100644
index 0000000000..1bae2d95e5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h
@@ -0,0 +1,31 @@
+/** @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) 2019 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 <Private/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/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h
new file mode 100644
index 0000000000..f1b72488ca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h
@@ -0,0 +1,89 @@
+/** @file
+  The GUID definition for SaConfigHob
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_CONFIG_HOB_H_
+#define _SA_CONFIG_HOB_H_
+
+#include <SaAccess.h>
+#include <Base.h>
+
+extern EFI_GUID gSaConfigHobGuid;
+
+#pragma pack (push,1)
+///
+#define DPR_DIRECTORY_MAX               2         ///< 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;
+
+///
+/// The data elements should be initialized by a Platform Module.
+/// The data structure is for VT-d driver initialization
+///
+typedef struct {
+  BOOLEAN               VtdDisable;                        ///< 1 = Avoids programming Vtd bars, Vtd overrides and DMAR table
+  UINT32                BaseAddress[SA_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               InterruptRemappingSupport;         ///< This field is used to indicate Interrupt Remapping supported or not
+} SA_VTD_CONFIGURATION_HOB;
+
+///
+/// SA GPIO Data Structure
+///
+typedef struct {
+  UINT8   ExpanderNo; ///< =Expander No For I2C based GPIO
+  UINT32  GpioNo;     ///< GPIO pad
+  BOOLEAN Active;     ///< 0=Active Low; 1=Active High
+} SA_GPIO;
+
+///
+/// SA PCIE RTD3 GPIO Data Structure
+///
+typedef struct {
+  UINT8              GpioSupport;      ///< 0=Not Supported; 1=PCH based; 2=I2C Based
+  SA_GPIO            HoldRst;          ///< Offset 8 This field contain PCIe HLD RESET GPIO value and level information
+  SA_GPIO            PwrEnable;        ///< This field contain PCIe PWR Enable GPIO value and level information
+  UINT32             WakeGpioNo;       ///< This field contain PCIe RTD3 Device Wake GPIO number
+} PCIE_RTD3_GPIO;
+
+///
+/// SG Info HOB
+///
+typedef struct {
+  SG_MODE           SgMode;
+  UINT8             RootPortIndex;
+  PCIE_RTD3_GPIO    Rtd3Pcie0Gpio;
+  PCIE_RTD3_GPIO    Rtd3Pcie1Gpio;
+  PCIE_RTD3_GPIO    Rtd3Pcie2Gpio;
+  UINT16            DelayAfterPwrEn;
+  UINT16            DelayAfterHoldReset;
+} SA_RTD3;
+
+///
+/// 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
+  BOOLEAN                  InitPcieAspmAfterOprom;                   ///< 1=initialize PCIe ASPM after Oprom; 0=before (This will be set basing on policy)
+  SA_RTD3                  SaRtd3;                                   ///< SG Info HOB
+  UINT8                    ApertureSize;                             ///< Aperture size value
+  UINT8                    IpuAcpiMode;                              ///< IPU ACPI mode: 0=Disabled, 1=IGFX Child device, 2=ACPI device
+  SA_VTD_CONFIGURATION_HOB VtdData;                                  ///< VT-d Data HOB
+  BOOLEAN                  CridEnable;                               ///< This field inidicates if CRID is enabled or disabled (to support Intel(R) SIPP)
+  BOOLEAN                  SkipPamLock;                              ///< 0=All PAM registers will be locked in System Agent code, 1=Do not lock PAM registers in System Agent code.
+  UINT8                    PowerDownUnusedBundles[SA_PEG_MAX_FUN];   ///< PCIe power down unused bundles support
+  UINT8                    PegMaxPayload[SA_PEG_MAX_FUN];            ///< PEG Max Pay Load Size (0xFF: Auto, 0:128B, 1:256B)
+} SA_CONFIG_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h
new file mode 100644
index 0000000000..095942d483
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h
@@ -0,0 +1,151 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define SA NVS Area operatino 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    SgMode;                                  ///< Offset 136     SG Mode (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
+  UINT8    SgFeatureList;                           ///< Offset 137     SG 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
+  UINT16   DelayAfterPwrEn;                         ///< Offset 177     Delay after power enable for PCIe
+  UINT16   DelayAfterHoldReset;                     ///< Offset 179     Delay after Hold Reset for PCIe
+  UINT8    Pcie0EpCapOffset;                        ///< Offset 181     PCIe0 Endpoint Capability Structure Offset
+  UINT32   XPcieCfgBaseAddress;                     ///< Offset 182     Any Device's PCIe Config Space Base Address
+  UINT16   GpioBaseAddress;                         ///< Offset 186     GPIO Base Address
+  UINT32   NvIgOpRegionAddress;                     ///< Offset 188     NVIG opregion address
+  UINT32   NvHmOpRegionAddress;                     ///< Offset 192     NVHM opregion address
+  UINT32   ApXmOpRegionAddress;                     ///< Offset 196     AMDA opregion address
+  UINT8    Peg0LtrEnable;                           ///< Offset 200     Latency Tolerance Reporting Enable
+  UINT8    Peg0ObffEnable;                          ///< Offset 201     Optimized Buffer Flush and Fill
+  UINT8    Peg1LtrEnable;                           ///< Offset 202     Latency Tolerance Reporting Enable
+  UINT8    Peg1ObffEnable;                          ///< Offset 203     Optimized Buffer Flush and Fill
+  UINT8    Peg2LtrEnable;                           ///< Offset 204     Latency Tolerance Reporting Enable
+  UINT8    Peg2ObffEnable;                          ///< Offset 205     Optimized Buffer Flush and Fill
+  UINT8    Peg3LtrEnable;                           ///< Offset 206     Latency Tolerance Reporting Enable
+  UINT8    Peg3ObffEnable;                          ///< Offset 207     Optimized Buffer Flush and Fill
+  UINT16   PegLtrMaxSnoopLatency;                   ///< Offset 208     SA Peg Latency Tolerance Reporting Max Snoop Latency
+  UINT16   PegLtrMaxNoSnoopLatency;                 ///< Offset 210     SA Peg Latency Tolerance Reporting Max No Snoop Latency
+  UINT8    Peg0PowerDownUnusedBundles;              ///< Offset 212     Peg0 Unused Bundle Control
+  UINT8    Peg1PowerDownUnusedBundles;              ///< Offset 213     Peg1 Unused Bundle Control
+  UINT8    Peg2PowerDownUnusedBundles;              ///< Offset 214     Peg2 Unused Bundle Control
+  UINT8    Peg3PowerDownUnusedBundles;              ///< Offset 215     Peg3 Unused Bundle Control
+  UINT8    PackageCstateLimit;                      ///< Offset 216     The lowest C-state for the package
+  UINT8    PwrDnBundlesGlobalEnable;                ///< Offset 217     Pegx Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
+  UINT64   Mmio64Base;                              ///< Offset 218     Base of above 4GB MMIO resource
+  UINT64   Mmio64Length;                            ///< Offset 226     Length of above 4GB MMIO resource
+  UINT32   CpuIdInfo;                               ///< Offset 234     CPU ID info to get Family Id or Stepping
+  UINT8    Pcie1EpCapOffset;                        ///< Offset 238     PCIe1 Endpoint Capability Structure Offset
+  UINT8    Pcie2EpCapOffset;                        ///< Offset 239     PCIe2 Endpoint Capability Structure Offset
+  UINT8    Pcie0SecBusNum;                          ///< Offset 240     PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie1SecBusNum;                          ///< Offset 241     PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie2SecBusNum;                          ///< Offset 242     PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT32   Mmio32Base;                              ///< Offset 243     Base of below 4GB MMIO resource
+  UINT32   Mmio32Length;                            ///< Offset 247     Length of below 4GB MMIO resource
+  UINT32   Pcie0WakeGpioNo;                         ///< Offset 251     PCIe0 RTD3 Device Wake GPIO Number
+  UINT32   Pcie1WakeGpioNo;                         ///< Offset 255     PCIe1 RTD3 Device Wake GPIO Number
+  UINT32   Pcie2WakeGpioNo;                         ///< Offset 259     PCIe2 RTD3 Device Wake GPIO Number
+  UINT8    VtdDisable;                              ///< Offset 263     VT-d Enable/Disable
+  UINT32   VtdBaseAddress1;                         ///< Offset 264     VT-d Base Address 1
+  UINT32   VtdBaseAddress2;                         ///< Offset 268     VT-d Base Address 2
+  UINT32   VtdBaseAddress3;                         ///< Offset 272     VT-d Base Address 3
+  UINT16   VtdEngine1Vid;                           ///< Offset 276     VT-d Engine#1 Vendor ID
+  UINT16   VtdEngine2Vid;                           ///< Offset 278     VT-d Engine#2 Vendor ID
+  UINT8    Pcie3SecBusNum;                          ///< Offset 280     PCIe3 Secondary Bus Number (PCIe3 Endpoint Bus Number)
+  UINT8    Pcie3GpioSupport;                        ///< Offset 281     PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  UINT8    Pcie3HoldRstExpanderNo;                  ///< Offset 282     PCIe3 HLD RST IO Expander Number
+  UINT32   Pcie3HoldRstGpioNo;                      ///< Offset 283     PCIe3 HLD RST GPIO Number
+  UINT8    Pcie3HoldRstActiveInfo;                  ///< Offset 287     PCIe3 HLD RST GPIO Active Information
+  UINT8    Pcie3PwrEnExpanderNo;                    ///< Offset 288     PCIe3 PWR Enable IO Expander Number
+  UINT32   Pcie3PwrEnGpioNo;                        ///< Offset 289     PCIe3 PWR Enable GPIO Number
+  UINT8    Pcie3PwrEnActiveInfo;                    ///< Offset 293     PCIe3 PWR Enable GPIO Active Information
+  UINT32   Pcie3WakeGpioNo;                         ///< Offset 294     PCIe3 RTD3 Device Wake GPIO Number
+  UINT8    Pcie3EpCapOffset;                        ///< Offset 298     PCIe3 Endpoint Capability Structure Offset
+  UINT8    RootPortIndex;                           ///< Offset 299     RootPort Number
+  UINT32   RootPortAddress;                         ///< Offset 300     RootPortAddress
+  UINT8    Reserved0[196];                          ///< Offset 304:499
+} SYSTEM_AGENT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h
new file mode 100644
index 0000000000..a9db25404f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h
@@ -0,0 +1,63 @@
+/** @file
+  Protocol to retrieve the GOP driver version
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h
new file mode 100644
index 0000000000..866f60b9c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h
@@ -0,0 +1,73 @@
+/** @file
+  Interface definition for GopPolicy Protocol.
+
+  Copyright (c) 2019 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 gIntelGraphicsVbtGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h
new file mode 100644
index 0000000000..ef2edfe122
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h
@@ -0,0 +1,24 @@
+/** @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) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
new file mode 100644
index 0000000000..031e55b9b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
@@ -0,0 +1,132 @@
+/** @file
+  This protocol provides the memory information data, such as
+  total physical memory size, memory frequency, memory size
+  of each dimm and rank.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MEM_INFO_PROTOCOL_H_
+#define _MEM_INFO_PROTOCOL_H_
+
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gMemInfoProtocolGuid;
+
+//
+// Protocol definitions
+//
+#define NODE_NUM  1
+#define CH_NUM    2
+#define DIMM_NUM  2
+#define RANK_NUM  2
+#define SLOT_NUM  (CH_NUM * DIMM_NUM)
+#define PROFILE_NUM 4 // number of memory profiles supported
+#define XMP_PROFILE_NUM 2 // number of XMP profiles supported
+
+//
+// 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_UNKNOWN
+#define MRC_DDR_TYPE_UNKNOWN  3
+#endif
+
+//
+// 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
+
+#pragma pack(1)
+///
+/// Memory timing Structure
+///
+typedef struct {
+  UINT32 tCK;     ///< Offset 0 Memory cycle time, in femtoseconds.
+  UINT16 NMode;   ///< Offset 4 Number of tCK cycles for the channel DIMM's command rate mode.
+  UINT16 tCL;     ///< Offset 6 Number of tCK cycles for the channel DIMM's CAS latency.
+  UINT16 tCWL;    ///< Offset 8 Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
+  UINT16 tFAW;    ///< Offset 10 Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
+  UINT16 tRAS;    ///< Offset 12 Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
+  UINT16 tRCDtRP; ///< Offset 14 Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time
+  UINT16 tREFI;   ///< Offset 16 Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
+  UINT16 tRFC;    ///< Offset 18 Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRPab;   ///< Offset 20 Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
+  UINT16 tRRD;    ///< Offset 22 Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
+  UINT16 tRTP;    ///< Offset 24 Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
+  UINT16 tWR;     ///< Offset 26 Number of tCK cycles for the channel DIMM's minimum write recovery time.
+  UINT16 tWTR;    ///< Offset 28 Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
+  UINT16 tRRD_L;  ///< Offset 30 Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
+  UINT16 tRRD_S;  ///< Offset 32 Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
+  UINT16 tWTR_L;  ///< Offset 34 Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
+  UINT16 tWTR_S;  ///< Offset 36 Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
+  UINT8  Rsvd[2]; ///< Offset 38
+} MEMORY_TIMING;
+
+typedef struct {
+  UINT8 SG;       ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;       ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;       ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;       ///< Number of tCK cycles between transactions when switching between DIMMs
+} TURNAROUND_TIMING;
+
+// @todo use the MemInfoHob data instead of duplicate structure.
+///
+/// Memory information Data Structure
+///
+typedef struct {
+  MEMORY_TIMING Timing[PROFILE_NUM];                   ///< Offset 0 Timming information for the DIMM
+  UINT32  memSize;                                     ///< Offset 128 Total physical memory size
+  UINT16  ddrFreq;                                     ///< Offset 132 DDR Current Frequency
+  UINT16  ddrFreqMax;                                  ///< Offset 134 DDR Maximum Frequency
+  UINT16  dimmSize[NODE_NUM * CH_NUM * DIMM_NUM];      ///< Offset 136 Size of each DIMM
+  UINT16  VddVoltage[PROFILE_NUM];                     ///< Offset 144 The voltage setting for the DIMM
+  UINT8   DimmStatus[NODE_NUM * CH_NUM * DIMM_NUM];    ///< Offset 152 The enumeration value from MrcDimmSts
+  UINT8   RankInDimm[NODE_NUM * CH_NUM * DIMM_NUM];    ///< Offset 156 No. of ranks in a dimm
+  UINT8   *DimmsSpdData[NODE_NUM * CH_NUM * DIMM_NUM]; ///< Offset 160 SPD data of each DIMM
+  UINT8   RefClk;                                      ///< Offset 192 Reference Clock
+  UINT8   Ratio;                                       ///< Offset 193 Clock Multiplier
+  BOOLEAN EccSupport;                                  ///< Offset 194 ECC supported or not
+  UINT8   Profile;                                     ///< Offset 195 Currently running memory profile
+  UINT8   XmpProfileEnable;                            ///< Offset 196: 0 = no XMP DIMMs in system
+  UINT8   DdrType;                                     ///< Offset 197: Current DDR type, see DDR_TYPE_xxx defines above
+  UINT8   Reserved[2];                                 ///< Offset 198 Reserved bytes for future use
+  UINT32  DefaultXmptCK[XMP_PROFILE_NUM];              ///< Offset 200 The Default XMP tCK values read from SPD.
+  TURNAROUND_TIMING tRd2Rd[CH_NUM];                    ///< Read-to-Read   Turn Around Timings
+  TURNAROUND_TIMING tRd2Wr[CH_NUM];                    ///< Read-to-Write  Turn Around Timings
+  TURNAROUND_TIMING tWr2Rd[CH_NUM];                    ///< Write-to-Read  Turn Around Timings
+  TURNAROUND_TIMING tWr2Wr[CH_NUM];                    ///< Write-to-Write Turn Around Timings
+} MEMORY_INFO_DATA;
+#pragma pack()
+
+///
+/// Memory information Protocol definition
+///
+typedef struct {
+  MEMORY_INFO_DATA  MemInfoData; ///< Memory Information Data Structure
+} MEM_INFO_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
new file mode 100644
index 0000000000..7b68f3072b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
@@ -0,0 +1,66 @@
+/** @file
+  Interface definition details between System Agent and platform drivers during DXE phase.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_H_
+#define _SA_POLICY_H_
+
+#include <SaAccess.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/GraphicsDxeConfig.h>
+#include <ConfigBlock/MemoryDxeConfig.h>
+#include <ConfigBlock/MiscDxeConfig.h>
+#include <ConfigBlock/PcieDxeConfig.h>
+#include <ConfigBlock/VbiosDxeConfig.h>
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gSaPolicyProtocolGuid;
+extern EFI_GUID gGraphicsDxeConfigGuid;
+extern EFI_GUID gMiscDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gVbiosDxeConfigGuid;
+
+/**
+  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 SA_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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h
new file mode 100644
index 0000000000..6f3541e3e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h
@@ -0,0 +1,32 @@
+/** @file
+  Register names for GNA 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_GNA_H_
+#define _SA_REGS_GNA_H_
+
+//
+// Device 8 Equates
+//
+#define SA_GNA_BUS_NUM    0x00
+#define SA_GNA_DEV_NUM    0x08
+#define SA_GNA_FUN_NUM    0x00
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h
new file mode 100644
index 0000000000..2cc0e5be68
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h
@@ -0,0 +1,214 @@
+/** @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) 2019 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_
+
+//
+// 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
+
+///
+/// Maximum number of SDRAM channels supported by the memory controller
+///
+#define SA_MC_MAX_CHANNELS 2
+
+///
+/// Maximum number of DIMM sockets supported by each channel
+///
+#define SA_MC_MAX_SLOTS 2
+
+///
+/// Maximum number of sides supported per DIMM
+///
+#define SA_MC_MAX_SIDES 2
+
+///
+/// Maximum number of DIMM sockets supported by the memory controller
+///
+#define SA_MC_MAX_SOCKETS (SA_MC_MAX_CHANNELS * SA_MC_MAX_SLOTS)
+
+///
+/// Maximum number of rows supported by the memory controller
+///
+#define SA_MC_MAX_RANKS (SA_MC_MAX_SOCKETS * SA_MC_MAX_SIDES)
+
+///
+/// Maximum number of rows supported by the memory controller
+///
+#define SA_MC_MAX_ROWS (SA_MC_MAX_SIDES * SA_MC_MAX_SOCKETS)
+
+///
+/// Maximum memory supported by the memory controller
+/// 4 GB in terms of KB
+///
+#define SA_MC_MAX_MEM_CAPACITY (4 * 1024 * 1024)
+
+///
+/// Define the maximum number of data bytes on a system with no ECC memory support.
+///
+#define SA_MC_MAX_BYTES_NO_ECC (8)
+
+///
+/// Define the maximum number of SPD data bytes on a DIMM.
+///
+#define SA_MC_MAX_SPD_SIZE (512)
+//
+// Maximum DMI lanes and bundles supported (x8 and 4 lanes)
+//
+#define SA_DMI_MAX_LANE                      0x04
+#define SA_DMI_MAX_BUNDLE                    0x02
+
+#define SA_DMI_CFL_MAX_LANE                  0x04
+#define SA_DMI_CFL_MAX_BUNDLE                0x02
+//
+// KabyLake CPU Mobile SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_MB_ULT_1 0x5904   ///< Kabylake Ult (OPI) (2+1F/1.5F/2F/3/3E) Mobile SA DID
+//
+// KabyLake CPU Halo SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_HALO_2   0x5910   ///< Kabylake Halo (4+2/4E/3FE) SA DID
+//
+// KabyLake CPU Desktop SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_DT_2     0x591F   ///< Kabylake Desktop (4+1.5F/2/4) SA DID
+//
+// KabyLake CPU Server SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_SVR_2    0x5918   ///< Kabylake Server (4+1/2/4E) SA DID
+
+//
+// CoffeeLake CPU Mobile SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_ULT_1        0x3ED0   ///< CoffeeLake Mobile (CFL-U 4+3e) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_2        0x3ECC   ///< CoffeeLake Mobile (CFL-U 2+3e) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_3        0x3E34   ///< CoffeeLake Mobile (CFL-U 4+(1 or 2)) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_4        0x3E35   ///< CoffeeLake Mobile (CFL-U 2+(1 or 2)) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_6        0x3ECC   ///< CoffeeLake Mobile (CFL-U 2+3e) SA DID
+
+//
+// CoffeeLake CPU Desktop SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_DT_1         0x3EC2   ///< CoffeeLake Desktop (6+2) SA DID
+#define V_SA_DEVICE_ID_CFL_DT_2         0x3E1F   ///< CoffeeLake Desktop (4+2) SA DID
+#define V_SA_DEVICE_ID_CFL_DT_3         0x3E0F   ///< CoffeeLake Desktop (2+2) SA DID
+#define V_SA_DEVICE_ID_CFL_DT_4         0x3E30   ///< CoffeeLake Desktop (8+2) SA DID
+
+//
+// CoffeeLake CPU Halo SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_HALO_1       0x3EC4   ///< CoffeeLake Halo (6+2) SA DID
+#define V_SA_DEVICE_ID_CFL_HALO_2       0x3E10   ///< CoffeeLake Halo (4+2) SA DID
+#define V_SA_DEVICE_ID_CFL_HALO_3       0x3E20   ///< CoffeeLake Halo (8+2) SA DID
+
+//
+// CoffeeLake CPU WS SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_WS_1         0x3EC6   ///< CoffeeLake WorkStation (6+2) SA DID
+#define V_SA_DEVICE_ID_CFL_WS_2         0x3E18   ///< CoffeeLake WrokStation (4+2) SA DID
+#define V_SA_DEVICE_ID_CFL_WS_3         0x3E31   ///< CoffeeLake WrokStation (8+2) SA DID
+
+//
+// CPU Server SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_SVR_1        0x3ECA   ///< CoffeeLake Server (6+0) SA DID
+#define V_SA_DEVICE_ID_CFL_SVR_2        0x3E32   ///< CoffeeLake Server (8+0) SA DID
+#define V_SA_DEVICE_ID_CFL_SVR_3        0x3E33   ///< CoffeeLake Server (4+0) SA DID
+/**
+ <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)
+#define N_SA_GGC_GMS_OFFSET  (0x8)
+#define B_SA_GGC_GMS_MASK    (0xff00)
+#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)
+#define B_SA_DEVEN_D2EN_MASK     (0x10)
+/**
+ Description:
+  This is the base address for the PCI Express configuration space.  This window of addresses contains the 4KB of configuration space for each PCI Express device that can potentially be part of the PCI Express Hierarchy associated with the Uncore.  There is no actual physical memory within this window of up to 256MB that can be addressed.  The actual size of this range is determined by a field in this register.
+  Each PCI Express Hierarchy requires a PCI Express BASE register.  The Uncore supports one PCI Express Hierarchy.  The region reserved by this register does not alias to any PCI2.3 compliant memory mapped space.  For example, the range reserved for MCHBAR is outside of PCIEXBAR space.
+  On reset, this register is disabled and must be enabled by writing a 1 to the enable field in this register.  This base address shall be assigned on a boundary consistent with the number of buses (defined by the length field in this register), above TOLUD and still within 39-bit addressable memory space.
+  The PCI Express Base Address cannot be less than the maximum address written to the Top of physical memory register (TOLUD).  Software must guarantee that these ranges do not overlap with known ranges located above TOLUD.
+  Software must ensure that the sum of the length of the enhanced configuration region + TOLUD + any other known ranges reserved above TOLUD is not greater than the 39-bit addessable limit of 512GB.  In general, system implementation and the number of PCI/PCI Express/PCI-X buses supported in the hierarchy will dictate the length of the region.
+  All the bits in this register are locked in LT mode.
+**/
+#define R_SA_PCIEXBAR  (0x60)
+
+/**
+ Description:
+ - This register controls the read, write and shadowing attributes of the BIOS range from F_0000h to F_FFFFh.  The Uncore allows programmable memory attributes on 13 legacy memory segments of various sizes in the 768KB to 1MB address range.  Seven Programmable Attribute Map (PAM) registers are used to support these features.  Cacheability of these areas is controlled via the MTRR register in the core.
+ - Two bits are used to specify memory attributes for each memory segment.  These bits apply to host accesses to the PAM areas.  These attributes are:
+ - RE - Read Enable.  When RE=1, the host read accesses to the corresponding memory segment are claimed by the Uncore and directed to main memory.  Conversely, when RE=0, the host read accesses are directed to DMI.
+ - WE - Write Enable.  When WE=1, the host write accesses to the corresponding memory segment are claimed by the Uncore and directed to main memory.  Conversely, when WE=0, the host read accesses are directed to DMI.
+ - The RE and WE attributes permit a memory segment to be Read Only, Write Only, Read/Write or Disabled.  For example, if a memory segment has RE=1 and WE=0, the segment is Read Only.
+**/
+#define R_SA_PAM0  (0x80)
+
+///
+/// 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)
+#define B_SA_SMRAMC_D_LCK_MASK     (0x10)
+#define B_SA_SMRAMC_D_CLS_MASK     (0x20)
+#define B_SA_SMRAMC_D_OPEN_MASK    (0x40)
+///
+/// Description:
+///  This register contains the Top of low memory address.
+///
+#define R_SA_TOLUD (0xbc)
+#define R_SA_MC_CAPID0_A_OFFSET    0xE4
+//
+// MCHBAR IO Register Offset Equates
+//
+#define R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET          0x5DA8
+
+#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)
+///
+/// Vt-d Engine base address.
+///
+#define R_SA_MCHBAR_VTD1_OFFSET                 0x5400  ///< HW UNIT1 for IGD
+#define R_SA_MCHBAR_VTD3_OFFSET      0x5410  ///< HW UNIT3 for all other - PEG, USB, SATA etc
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h
new file mode 100644
index 0000000000..f8b794a9fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h
@@ -0,0 +1,50 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_IGD_H_
+#define _SA_REGS_IGD_H_
+
+///
+/// Device 2 Register Equates
+///
+//
+// The following equates must be reviewed and revised when the specification is ready.
+//
+#define SA_IGD_BUS           0x00
+#define SA_IGD_DEV           0x02
+#define SA_IGD_FUN_0         0x00
+#define SA_IGD_DEV_FUN       (SA_IGD_DEV << 3)
+#define SA_IGD_BUS_DEV_FUN   (SA_MC_BUS << 8) + SA_IGD_DEV_FUN
+
+#define V_SA_IGD_VID         0x8086
+#define SA_GT_APERTURE_SIZE_256MB    1      ///< 256MB is the recommanded GT Aperture Size as per BWG.
+
+#define V_SA_PCI_DEV_2_GT2_CFL_ULT_1_ID   0x3EA0 ///< Dev2 CFL-U GT2
+#define V_SA_PCI_DEV_2_GT1_CFL_ULT_1_ID   0x3EA1 ///< Dev2 CFL-U GT1
+#define R_SA_IGD_VID               0x00
+#define R_SA_IGD_DID               0x02
+#define R_SA_IGD_CMD               0x04
+
+#define R_SA_IGD_SWSCI_OFFSET      0x00E8
+#define R_SA_IGD_ASLS_OFFSET       0x00FC  ///< ASL Storage
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h
new file mode 100644
index 0000000000..b26c79ec95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h
@@ -0,0 +1,37 @@
+/** @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
+  - 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_IPU_H_
+#define _SA_REGS_IPU_H_
+
+//
+// Device 5 Equates
+//
+#define SA_IPU_BUS_NUM    0x00
+#define SA_IPU_DEV_NUM    0x05
+#define SA_IPU_FUN_NUM    0x00
+
+//
+// GPIO native features pins data
+//
+#define SA_GPIO_IMGUCLK_NUMBER_OF_PINS     2
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h
new file mode 100644
index 0000000000..b7e9416fc6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h
@@ -0,0 +1,64 @@
+/** @file
+  Register names for PEG 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_PEG_H_
+#define _SA_REGS_PEG_H_
+//
+// Device 1 Memory Mapped IO Register Offset Equates
+//
+#define SA_PEG_BUS_NUM     0x00
+#define SA_PEG_DEV_NUM     0x01
+#define SA_PEG0_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG0_FUN_NUM    0x00
+#define SA_PEG1_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG1_FUN_NUM    0x01
+#define SA_PEG2_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG2_FUN_NUM    0x02
+//
+// Temporary Device & Function Number used for Switchable Graphics DGPU
+//
+#define SA_TEMP_DGPU_DEV   0x00
+#define SA_TEMP_DGPU_FUN   0x00
+
+//
+// SA PCI Express* Port configuration
+//
+#define SA_PEG_MAX_FUN     0x03
+#define SA_PEG_MAX_LANE    0x10
+#define SA_PEG_MAX_BUNDLE  0x08
+
+//
+// Silicon and SKU- specific MAX defines
+//
+#define SA_PEG_CNL_H_MAX_FUN           SA_PEG_MAX_FUN      // CNL-H- SKU supports 4 controllers with 20 PEG lanes and 10 bundles
+#define SA_PEG_CNL_H_MAX_LANE          SA_PEG_MAX_LANE
+#define SA_PEG_CNL_H_MAX_BUNDLE        SA_PEG_MAX_BUNDLE
+#define SA_PEG_NON_CNL_H_MAX_FUN       0x03                // All non-CNL-H- SKU supports 3 controllers with 16 PEG lanes and 8 bundles
+#define SA_PEG_NON_CNL_H_MAX_LANE      0x10
+#define SA_PEG_NON_CNL_H_MAX_BUNDLE    0x08
+
+
+
+#define R_SA_PEG_VID_OFFSET            0x00  ///< Vendor ID
+#define R_SA_PEG_DID_OFFSET            0x02  ///< Device ID
+#define R_SA_PEG_SS_OFFSET             0x8C  ///< Subsystem ID
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
new file mode 100644
index 0000000000..b98f1732ba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
@@ -0,0 +1,106 @@
+/** @file
+  Macros to simplify and abstract the interface to PCI configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SAACCESS_H_
+#define _SAACCESS_H_
+
+#include "SaRegs.h"
+#include "SaCommonDefinitions.h"
+
+///
+/// SystemAgent Base Address definition
+///
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND  1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND  1000
+#endif
+
+//
+// SA Segement Number
+//
+#define SA_SEG_NUM         0x00
+
+#define V_SA_DEVICE_ID_INVALID 0xFFFF
+
+
+///
+/// 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
+} SA_PCIE_ASPM_CONFIG;
+
+///
+/// SgMode settings
+///
+typedef enum {
+  SgModeDisabled = 0,
+  SgModeReserved,
+  SgModeMuxless,
+  SgModeDgpu,
+  SgModeMax
+} SG_MODE;
+
+//
+// Macros that judge which type a device ID belongs to
+//
+#define IS_SA_DEVICE_ID_MOBILE(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_MB_ULT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_3) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_4) \
+    )
+
+///
+/// Device IDs that are Desktop specific B0:D0:F0
+///
+#define IS_SA_DEVICE_ID_DESKTOP(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_DT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_3) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_4) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_WS_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_WS_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_WS_3) \
+    )
+
+///
+/// Device IDS that are Server specific B0:D0:F0
+///
+#define IS_SA_DEVICE_ID_SERVER(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_SVR_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_3) \
+    )
+
+///
+/// Device IDs that are Halo specific B0:D0:F0
+///
+#define IS_SA_DEVICE_ID_HALO(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_HALO_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_3) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_IOT_1) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h
new file mode 100644
index 0000000000..ab9224e573
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h
@@ -0,0 +1,23 @@
+/** @file
+  This header file provides common definitions just for System Agent using to avoid including extra module's file.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_COMMON_DEFINITIONS_H_
+#define _SA_COMMON_DEFINITIONS_H_
+
+#define ERROR_BY_16     (0xEE15)
+#define ERROR_NOT_BY_16 (0xED15)
+
+#define MAX_PCIE_ASPM_OVERRIDE       500
+#define MAX_PCIE_LTR_OVERRIDE        500
+
+#define DISABLED  0
+#define ENABLED   1
+
+#define SA_VTD_ENGINE_NUMBER        3
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
new file mode 100644
index 0000000000..87aa105df2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
@@ -0,0 +1,25 @@
+/** @file
+  Header file for the PCI Express library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PCI_EXPRESS_LIB_H_
+#define _SA_PCI_EXPRESS_LIB_H_
+
+
+/**
+  Gets the base address of PCI Express.
+
+  This internal functions retrieves PCI Express Base Address.
+
+  @return The base address of PCI Express.
+**/
+VOID*
+GetPciExpressBaseAddress (
+  VOID
+);
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
new file mode 100644
index 0000000000..086c60bfed
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
@@ -0,0 +1,51 @@
+/** @file
+  Main System Agent Policy structure definition which will contain several config blocks during runtime.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_COMMON_H_
+#define _SA_POLICY_COMMON_H_
+
+#include <Uefi.h>
+#include <Library/SmbusLib.h>
+#include <SaAccess.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/SwitchableGraphicsConfig.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <ConfigBlock/GraphicsPeiPreMemConfig.h>
+#include <ConfigBlock/PciePeiPreMemConfig.h>
+#include <ConfigBlock/IpuPreMemConfig.h>
+#include <ConfigBlock/SaMiscPeiPreMemConfig.h>
+#include <ConfigBlock/GnaConfig.h>
+#include <ConfigBlock/GraphicsPeiConfig.h>
+#include <ConfigBlock/SaMiscPeiConfig.h>
+#include <ConfigBlock/OverClockingConfig.h>
+#include <ConfigBlock/VtdConfig.h>
+#include <ConfigBlock/PciePeiConfig.h>
+
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gSiPolicyPpiGuid;
+extern EFI_GUID gSaMiscPeiConfigGuid;
+extern EFI_GUID gGraphicsPeiConfigGuid;
+extern EFI_GUID gSaPciePeiConfigGuid;
+extern EFI_GUID gGnaConfigGuid;
+extern EFI_GUID gVtdConfigGuid;
+extern EFI_GUID gSaOverclockingPreMemConfigGuid;
+extern EFI_GUID gSiPreMemPolicyPpiGuid;
+extern EFI_GUID gSaMiscPeiPreMemConfigGuid;
+extern EFI_GUID gSaPciePeiPreMemConfigGuid;
+extern EFI_GUID gGraphicsPeiPreMemConfigGuid;
+extern EFI_GUID gIpuPreMemConfigGuid;
+extern EFI_GUID gSwitchableGraphicsConfigGuid;
+extern EFI_GUID gCpuTraceHubConfigGuid;
+extern EFI_GUID gMemoryConfigGuid;
+extern EFI_GUID gMemoryConfigNoCrcGuid;
+
+#endif // _SA_POLICY_COMMON_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
new file mode 100644
index 0000000000..593b907d2a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
@@ -0,0 +1,32 @@
+/** @file
+  Register names for System Agent (SA) registers
+  <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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_H_
+#define _SA_REGS_H_
+
+#include <Register/SaRegsHostBridge.h>
+#include <Register/SaRegsIgd.h>
+#include <Register/SaRegsPeg.h>
+#include <Register/SaRegsIpu.h>
+#include <Register/SaRegsGna.h>
+
+#endif
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (12 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
                   ` (23 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds package-level library class instances.

* BaseConfigBlockLib - Library functions for config block management.
* BaseSiConfigBlockLib - Library functions for managing component
  config blocks.
* DxeAslUpdateLib - Services to update ACPI tables.
* PeiDxeSmmMmPciLib - Services to manage PCI Express addresses.
* PeiStallPpiLib - Installs an instance of EFI_PEI_STALL_PPI.
* PeiSiPolicyLib - Installs an instance of the Silicon Policy PPI.
  Prints the Silicon Policy PPI values when DEBUG prints are enabled.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf     |  29 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf           |  40 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf   |  30 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf       |  35 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf      |  31 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf             |  51 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h           |  35 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c       | 146 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c   |  87 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c             | 403 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c     | 126 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c         |  32 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c        |  78 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c               | 214 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c         | 122 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c                |  36 ++
 17 files changed, 1528 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
new file mode 100644
index 0000000000..a7def2481d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
@@ -0,0 +1,29 @@
+## @file
+# Component INF file for the BaseConfigBlock library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseConfigBlockLib
+FILE_GUID = 1EC07EA8-7808-4e06-9D79-309AE331D2D5
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = ConfigBlockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+BaseConfigBlockLib.c
+
+[LibraryClasses]
+DebugLib
+BaseMemoryLib
+MemoryAllocationLib
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
new file mode 100644
index 0000000000..b04dc3cfa4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for the BaseSiConfigBlockLib library.
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseSiConfigBlockLib.c
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
new file mode 100644
index 0000000000..658caccb43
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Provides services to update ASL tables.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeAslUpdateLib
+FILE_GUID = 8621697D-4E3A-4bf2-ADB0-3E2FF06559CA
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = AslUpdateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PcdLib
+BaseMemoryLib
+UefiLib
+MemoryAllocationLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeAslUpdateLib.c
+
+
+[Protocols]
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiAcpiSdtProtocolGuid ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
new file mode 100644
index 0000000000..ae78a8e8f9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
@@ -0,0 +1,30 @@
+## @file
+# Provides services to update ASL tables.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeAslUpdateLibNull
+FILE_GUID = C7A3725F-6146-4FAB-B2EF-B4CED222DA52
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = AslUpdateLib
+
+
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeAslUpdateLibNull.c
+
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
new file mode 100644
index 0000000000..fdf376bc70
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the PeiDxeSmmMmPciLib
+#
+# Copyright (c) 2019 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
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+PeiDxeSmmMmPciLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
new file mode 100644
index 0000000000..2e07a90406
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Library description file for Stall Ppi installation
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiStallPpiLib
+FILE_GUID = 73E3DD0E-B2C1-4429-B0B8-F8C2BD64F8CE
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = StallPpiLib
+
+[Sources]
+PeiStallPpiLib.c
+
+[LibraryClasses]
+BaseLib
+DebugLib
+TimerLib
+PeiServicesLib
+
+[Packages]
+MdePkg/MdePkg.dec
+
+[Ppis]
+gEfiPeiStallPpiGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
new file mode 100644
index 0000000000..c5945c3129
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for the PeiSiPolicyLib library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSiPolicyLib
+FILE_GUID = 97584FAE-9299-4202-9889-2D339E4BFA5B
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = SiPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+CpuPolicyLib
+PchPolicyLib
+PeiSaPolicyLib
+PeiMePolicyLib
+PcdLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiSiPolicyLib.c
+PeiSiPolicyLibrary.h
+SiPrintPolicy.c
+PeiSiPolicyLibPreMem.c
+
+
+[Guids]
+gSiConfigGuid        ## CONSUMES
+
+
+[Ppis]
+gSiPolicyPpiGuid       ## PRODUCES
+gSiPreMemPolicyPpiGuid ## PRODUCES
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
new file mode 100644
index 0000000000..cb6b14fdd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
@@ -0,0 +1,35 @@
+/** @file
+  Header file for the PeiSiPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_LIBRARY_H_
+#define _PEI_SI_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/PchPolicyLib.h>
+#include <Library/PeiMePolicyLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <PchAccess.h>
+#include <Library/CpuPolicyLib.h>
+
+#define TEMP_MEM_BASE_ADDRESS 0xFE600000
+#define TEMP_IO_BASE_ADDRESS  0xD000
+
+//
+// IO/MMIO resource limits
+//
+#define TEMP_MEM_SIZE         V_PCH_XDCI_MEM_LENGTH
+#define TEMP_IO_SIZE          0x10
+
+#endif // _PEI_SI_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c
new file mode 100644
index 0000000000..369dab97ee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c
@@ -0,0 +1,146 @@
+/** @file
+  Library functions for Config Block management.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.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
+  )
+{
+  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
+  UINT32                    ConfigBlkTblHdrSize;
+
+  ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
+
+  if (TotalSize <= (ConfigBlkTblHdrSize + sizeof (CONFIG_BLOCK_HEADER))) {
+    DEBUG ((DEBUG_ERROR, "Invalid Parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)AllocateZeroPool (TotalSize);
+  if (ConfigBlkTblAddrPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Could not allocate memory.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ConfigBlkTblAddrPtr->NumberOfBlocks = 0;
+  ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength = TotalSize;
+  ConfigBlkTblAddrPtr->AvailableSize = TotalSize - ConfigBlkTblHdrSize;
+
+  *ConfigBlockTableAddress = (VOID *)ConfigBlkTblAddrPtr;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  CONFIG_BLOCK              *TempConfigBlk;
+  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
+  CONFIG_BLOCK              *ConfigBlkAddrPtr;
+  UINT16                    ConfigBlkSize;
+
+  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)ConfigBlockTableAddress;
+  ConfigBlkAddrPtr = (CONFIG_BLOCK *)(*ConfigBlockAddress);
+  ConfigBlkSize = ConfigBlkAddrPtr->Header.GuidHob.Header.HobLength;
+  DEBUG ((DEBUG_INFO, "Config Block GUID: %g / Config Block Size: 0x%x bytes\n", &(ConfigBlkAddrPtr->Header.GuidHob.Name), ConfigBlkSize));
+  if ((ConfigBlkSize % 4) != 0) {
+    DEBUG ((DEBUG_ERROR, "Config Block must be multiples of 4 bytes\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  if (ConfigBlkTblAddrPtr->AvailableSize < ConfigBlkSize) {
+    DEBUG ((DEBUG_ERROR, "Config Block Table is full and cannot add new Config Block.\n"));
+    DEBUG ((DEBUG_ERROR, "Available Config Block Size: 0x%x bytes / Requested Config Block Size: 0x%x bytes\n", ConfigBlkTblAddrPtr->AvailableSize, ConfigBlkSize));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr + (UINTN)(ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength - ConfigBlkTblAddrPtr->AvailableSize));
+  CopyMem (&TempConfigBlk->Header, &ConfigBlkAddrPtr->Header, sizeof(CONFIG_BLOCK_HEADER));
+
+  ConfigBlkTblAddrPtr->NumberOfBlocks++;
+  ConfigBlkTblAddrPtr->AvailableSize = ConfigBlkTblAddrPtr->AvailableSize - ConfigBlkSize;
+
+  *ConfigBlockAddress = (VOID *) TempConfigBlk;
+  DEBUG ((DEBUG_INFO, "Config Block Address: 0x%x / Available Config Block Size: 0x%x bytes\n", (UINT32)(UINTN)*ConfigBlockAddress, ConfigBlkTblAddrPtr->AvailableSize));
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  UINT16                    OffsetIndex;
+  CONFIG_BLOCK              *TempConfigBlk;
+  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
+  UINT32                    ConfigBlkTblHdrSize;
+  UINT32                    ConfigBlkOffset;
+  UINT16                    NumOfBlocks;
+
+  ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
+  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)ConfigBlockTableAddress;
+  NumOfBlocks = ConfigBlkTblAddrPtr->NumberOfBlocks;
+
+  ConfigBlkOffset = 0;
+  for (OffsetIndex = 0; OffsetIndex < NumOfBlocks; OffsetIndex++) {
+    if ((ConfigBlkTblHdrSize + ConfigBlkOffset) > (ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength)) {
+      break;
+    }
+    TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr + (UINTN)ConfigBlkTblHdrSize + (UINTN)ConfigBlkOffset);
+    if (CompareGuid (&(TempConfigBlk->Header.GuidHob.Name), ConfigBlockGuid)) {
+      *ConfigBlockAddress = (VOID *)TempConfigBlk;
+      return EFI_SUCCESS;
+    }
+    ConfigBlkOffset = ConfigBlkOffset + TempConfigBlk->Header.GuidHob.Header.HobLength;
+  }
+  DEBUG ((DEBUG_ERROR, "Could not find the config block.\n"));
+  return EFI_NOT_FOUND;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
new file mode 100644
index 0000000000..16a14b3245
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
@@ -0,0 +1,87 @@
+/** @file
+  This file is BaseSiConfigBlockLib library is used to add config blocks
+  to config block header.
+
+  Copyright (c) 2019 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++) {
+    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/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
new file mode 100644
index 0000000000..04cf66fd2f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
@@ -0,0 +1,403 @@
+/** @file
+  Boot service DXE ASL update library implementation.
+
+  These functions in this file can be called during DXE and cannot be called during runtime
+  or in SMM which should use a RT or SMM library.
+
+  This library uses the ACPI Support protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/AslUpdateLib.h>
+
+//
+// Function implemenations
+//
+static EFI_ACPI_SDT_PROTOCOL      *mAcpiSdt = NULL;
+static EFI_ACPI_TABLE_PROTOCOL    *mAcpiTable = NULL;
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  ///
+  /// Locate ACPI tables
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **) &mAcpiSdt);
+  ASSERT_EFI_ERROR (Status);
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateNameAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER *Table;
+  UINT8                       *CurrPtr;
+  UINT32                      *Signature;
+  UINT8                       *DsdtPointer;
+  UINTN                       Handle;
+  UINT8                       DataSize;
+
+  if (mAcpiTable == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiTable == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+
+  ///
+  /// Locate table with matching ID
+  ///
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+             (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+             &Handle
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ///
+  /// Point to the beginning of the DSDT table
+  ///
+  CurrPtr = (UINT8 *) Table;
+  if (CurrPtr == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Loop through the ASL looking for values that we must fix up.
+  ///
+  for (DsdtPointer = CurrPtr; DsdtPointer < (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+    ///
+    /// Get a pointer to compare for signature
+    ///
+    Signature = (UINT32 *) DsdtPointer;
+    ///
+    /// Check if this is the Device Object signature we are looking for
+    ///
+    if ((*Signature) == AslSignature) {
+      ///
+      /// Look for Name Encoding
+      ///
+      if (*(DsdtPointer-1) == AML_NAME_OP) {
+        ///
+        /// Check if size of new and old data is the same
+        ///
+        DataSize = *(DsdtPointer+4);
+        if ((Length == 1 && DataSize == 0xA) ||
+            (Length == 2 && DataSize == 0xB) ||
+            (Length == 4 && DataSize == 0xC)) {
+          CopyMem (DsdtPointer+5, Buffer, Length);
+        } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+          CopyMem (DsdtPointer+4, Buffer, Length);
+        } else {
+          FreePool (Table);
+          return EFI_BAD_BUFFER_SIZE;
+        }
+        Status = mAcpiTable->UninstallAcpiTable (
+                               mAcpiTable,
+                               Handle
+                               );
+        Handle = 0;
+        Status = mAcpiTable->InstallAcpiTable (
+                               mAcpiTable,
+                               Table,
+                               Table->Length,
+                               &Handle
+                               );
+        FreePool (Table);
+        return Status;
+      }
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This procedure will update the name of ASL Method
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateMethodAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER *Table;
+  UINT8                       *CurrPtr;
+  UINT32                      *Signature;
+  UINT8                       *DsdtPointer;
+  UINTN                       Handle;
+
+  if (mAcpiTable == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiTable == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+
+  ///
+  /// Locate table with matching ID
+  ///
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+             (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+             &Handle
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ///
+  /// Point to the beginning of the DSDT table
+  ///
+  CurrPtr = (UINT8 *) Table;
+  if (CurrPtr == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Loop through the ASL looking for values that we must fix up.
+  ///
+  for (DsdtPointer = CurrPtr; DsdtPointer < (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+    ///
+    /// Get a pointer to compare for signature
+    ///
+    Signature = (UINT32 *) DsdtPointer;
+    ///
+    /// Check if this is the Device Object signature we are looking for
+    ///
+    if ((*Signature) == AslSignature) {
+      ///
+      /// Look for Name Encoding
+      ///
+      if ((*(DsdtPointer-3) == AML_METHOD_OP)
+         || (*(DsdtPointer-2) == AML_METHOD_OP)
+         )
+      {
+        CopyMem (DsdtPointer, Buffer, Length);
+        Status = mAcpiTable->UninstallAcpiTable (
+                               mAcpiTable,
+                               Handle
+                               );
+        Handle = 0;
+        Status = mAcpiTable->InstallAcpiTable (
+                               mAcpiTable,
+                               Table,
+                               Table->Length,
+                               &Handle
+                               );
+        FreePool (Table);
+        return Status;
+      }
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI table.
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+
+  @param[in] Signature           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in, out] Table          - Updated with a pointer to the table
+  @param[in, out] Handle         - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  EFI_STATUS                  Status;
+  INTN                        Index;
+  EFI_ACPI_TABLE_VERSION      Version;
+  EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+  if (mAcpiSdt == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiSdt == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+
+  ///
+  /// Locate table with matching ID
+  ///
+  Version = 0;
+  Index = 0;
+  do {
+    Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+    if (Status == EFI_NOT_FOUND) {
+      break;
+    }
+    ASSERT_EFI_ERROR (Status);
+    Index++;
+  } while (OrgTable->Signature != Signature);
+
+  if (Status != EFI_NOT_FOUND) {
+    *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
+    ASSERT (*Table);
+  }
+
+  ///
+  /// If we found the table, there will be no error.
+  ///
+  return Status;
+}
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
+
+  @param[in] TableId           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize       - Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                 will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table        - Updated with a pointer to the table
+  @param[in, out] Handle       - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  EFI_STATUS                  Status;
+  INTN                        Index;
+  EFI_ACPI_TABLE_VERSION      Version;
+  EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+  if (mAcpiSdt == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiSdt == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+  ///
+  /// Locate table with matching ID
+  ///
+  Version = 0;
+  Index = 0;
+  do {
+    Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+    if (Status == EFI_NOT_FOUND) {
+      break;
+    }
+    ASSERT_EFI_ERROR (Status);
+    Index++;
+  } while (CompareMem (&(OrgTable->OemTableId), TableId, TableIdSize));
+
+  if (Status != EFI_NOT_FOUND) {
+    *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
+    ASSERT (*Table);
+  }
+
+  ///
+  /// If we found the table, there will be no error.
+  ///
+  return Status;
+}
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer          Pointer to buffer to checksum
+  @param[in] Size            Number of bytes to checksum
+  @param[in] ChecksumOffset  Offset to place the checksum result in
+
+  @retval EFI_SUCCESS        The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  )
+{
+  UINT8 Sum;
+  UINT8 *Ptr;
+
+  Sum = 0;
+  ///
+  /// Initialize pointer
+  ///
+  Ptr = Buffer;
+
+  ///
+  /// set checksum to 0 first
+  ///
+  Ptr[ChecksumOffset] = 0;
+
+  ///
+  /// add all content of buffer
+  ///
+  while (Size--) {
+    Sum = (UINT8) (Sum + (*Ptr++));
+  }
+  ///
+  /// set checksum
+  ///
+  Ptr                 = Buffer;
+  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c
new file mode 100644
index 0000000000..a7ce92b7c3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c
@@ -0,0 +1,126 @@
+/** @file
+  Boot service DXE ASL update library implementation.
+
+  These functions in this file can be called during DXE and cannot be called during runtime
+  or in SMM which should use a RT or SMM library.
+
+  This library uses the ACPI Support protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/AslUpdateLib.h>
+
+//
+// Function implemenations
+//
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI table.
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+
+  @param[in] Signature           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in, out] Table          - Updated with a pointer to the table
+  @param[in, out] Handle         - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
+
+  @param[in] TableId           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize       - Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                 will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table        - Updated with a pointer to the table
+  @param[in, out] Handle       - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer          Pointer to buffer to checksum
+  @param[in] Size            Number of bytes to checksum
+  @param[in] ChecksumOffset  Offset to place the checksum result in
+
+  @retval EFI_SUCCESS        The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
new file mode 100644
index 0000000000..5085f29d6d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
@@ -0,0 +1,32 @@
+/** @file
+  This file contains routines that get PCI Express Address
+
+  Copyright (c) 2019 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
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+  )
+{
+  ASSERT ((Bus <= 0xFF) && (Device <= 0x1F) && (Function <= 0x7));
+
+  return ((UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c
new file mode 100644
index 0000000000..d462aef407
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c
@@ -0,0 +1,78 @@
+/** @file
+  Library to install StallPpi.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Ppi/Stall.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PeiServicesLib.h>
+
+#define PEI_STALL_RESOLUTION   1
+
+/**
+  This function provides a blocking stall for reset at least the given number of microseconds
+  stipulated in the final argument.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  this Pointer to the local data for the interface.
+  @param  Microseconds number of microseconds for which to stall.
+
+  @retval  EFI_SUCCESS the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  );
+
+
+EFI_PEI_STALL_PPI   mStallPpi = {
+  PEI_STALL_RESOLUTION,
+  Stall
+};
+
+EFI_PEI_PPI_DESCRIPTOR    mPeiInstallStallPpi = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiStallPpiGuid,
+  &mStallPpi
+};
+
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  )
+{
+  MicroSecondDelay (Microseconds);
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will install the StallPpi.
+
+  @retval EFI_SUCCESS if StallPpi is installed successfully.
+**/
+EFI_STATUS
+EFIAPI
+InstallStallPpi (
+  VOID
+  )
+{
+  EFI_STATUS   Status;
+
+  DEBUG((DEBUG_INFO, "Installing StallPpi \n"));
+
+  Status = PeiServicesInstallPpi (&mPeiInstallStallPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
new file mode 100644
index 0000000000..de8d9745d3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
@@ -0,0 +1,214 @@
+/** @file
+  This file is PeiSiPolicyLib library creates default settings of RC
+  Policy and installs RC Policy PPI.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyLibrary.h"
+#include <Library/PcdLib.h>
+
+/**
+  Get Si config block table total size.
+
+  @retval                               Size of PCH config block table
+**/
+UINT16
+EFIAPI
+SiGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return (UINT16) sizeof (SI_CONFIG);
+}
+
+EFI_STATUS
+EFIAPI
+LoadSiConfigBlockDefault (
+  IN VOID *ConfigBlockPointer
+  )
+{
+  SI_CONFIG                         *SiConfig;
+
+  SiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Name = %g\n", &SiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SiConfig->Header.GuidHob.Header.HobLength));
+
+  SiConfig->Header.Revision = SI_CONFIG_REVISION;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SiAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  VOID                 *ConfigBlockPointer;
+  EFI_STATUS           Status;
+  CONFIG_BLOCK_HEADER  SiBlock;
+
+  //
+  // Initalize SiBlock
+  //
+  CopyMem (&(SiBlock.GuidHob.Name), &gSiConfigGuid, sizeof (EFI_GUID));
+  SiBlock.GuidHob.Header.HobLength = sizeof (SI_CONFIG);
+  SiBlock.Revision                 = SI_CONFIG_REVISION;
+  //
+  // Initialize ConfigBlockPointer
+  //
+  ConfigBlockPointer = (VOID *)&SiBlock;
+  //
+  // Add config block fro SiBlock
+  //
+  DEBUG ((DEBUG_INFO, "gSiConfigGuid = %g\n", &gSiConfigGuid));
+  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Name = %g\n", &(SiBlock.GuidHob.Name)));
+  Status = AddConfigBlock (ConfigBlockTableAddress, (VOID *) &ConfigBlockPointer);
+  ASSERT_EFI_ERROR (Status);
+
+  LoadSiConfigBlockDefault ((VOID *) ConfigBlockPointer);
+
+  return Status;
+}
+
+/**
+  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreateConfigBlocks (
+  OUT  SI_POLICY_PPI **SiPolicyPpi
+  )
+{
+  UINT16        TotalBlockSize;
+  EFI_STATUS    Status;
+  SI_POLICY_PPI *SiPolicy;
+  UINT16        RequiredSize;
+
+  SiPolicy = NULL;
+  //
+  // TotalBlockSize = Si, Pch, ME, SA and CPU config block size.
+  //
+  TotalBlockSize = SiGetConfigBlockTotalSize () +
+                   PchGetConfigBlockTotalSize () +
+                   MeGetConfigBlockTotalSize () +
+                   SaGetConfigBlockTotalSize () +
+                   CpuGetConfigBlockTotalSize ();
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *) &SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // General initialization
+  //
+  SiPolicy->TableHeader.Header.Revision = SI_POLICY_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status = SiAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = PchAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = MeAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = SaAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = CpuAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *SiPolicyPpi = SiPolicy;
+  return Status;
+}
+
+/**
+  Print out all silicon policy information.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval none
+**/
+VOID
+DumpSiPolicy (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  )
+{
+  //
+  // Print SI config blocks and serial out.
+  //
+  SiPrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print PCH config blocks and serial out.
+  //
+  PchPrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print ME config blocks and serial out.
+  //
+  MePrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print SA config blocks and serial out.
+  //
+  SaPrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print CPU config block and serial out.
+  //
+  CpuPrintPolicy (SiPolicyPpi);
+}
+
+/**
+  SiInstallPolicyPpi installs SiPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiInstallPolicyPpi (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  )
+{
+  EFI_STATUS             Status;
+  EFI_PEI_PPI_DESCRIPTOR *SiPolicyPpiDesc;
+  SI_CONFIG              *SiConfig;
+
+  SiPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  if (SiPolicyPpiDesc == NULL) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SiPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  SiPolicyPpiDesc->Guid  = &gSiPolicyPpiGuid;
+  SiPolicyPpiDesc->Ppi   = SiPolicyPpi;
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "Dump Silicon Policy update by Platform...\n"));
+  DumpSiPolicy (SiPolicyPpi);
+
+  //
+  // Install Silicon Policy PPI
+  //
+  Status = PeiServicesInstallPpi (SiPolicyPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c
new file mode 100644
index 0000000000..499f895e8e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c
@@ -0,0 +1,122 @@
+/** @file
+  This file is PeiSiPolicyLib library creates default settings of RC
+  Policy and installs RC Policy PPI.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyLibrary.h"
+#include <Base.h>
+
+/**
+  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon PREMEM Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreatePreMemConfigBlocks (
+  OUT  SI_PREMEM_POLICY_PPI **SiPreMemPolicyPpi
+  )
+{
+  UINT16               TotalBlockSize;
+  EFI_STATUS           Status;
+  SI_PREMEM_POLICY_PPI *SiPreMemPolicy;
+  UINT16               RequiredSize;
+
+  SiPreMemPolicy = NULL;
+  //
+  // TotalBlockSize = Pch , SA, ME and CPU config block size.
+  //
+  TotalBlockSize = PchGetPreMemConfigBlockTotalSize () +
+                   MeGetConfigBlockTotalSizePreMem () +
+                   SaGetConfigBlockTotalSizePreMem () +
+                   CpuGetPreMemConfigBlockTotalSize ();
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // General initialization
+  //
+  SiPreMemPolicy->TableHeader.Header.Revision = SI_PREMEM_POLICY_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status = PchAddPreMemConfigBlocks ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = MeAddConfigBlocksPreMem ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = SaAddConfigBlocksPreMem ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = CpuAddPreMemConfigBlocks ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *SiPreMemPolicyPpi = SiPreMemPolicy;
+  return Status;
+}
+
+/**
+  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPreMemPolicyPpi   The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiPreMemInstallPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  )
+{
+  EFI_STATUS             Status;
+  EFI_PEI_PPI_DESCRIPTOR *SiPolicyPreMemPpiDesc;
+
+  SiPolicyPreMemPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  if (SiPolicyPreMemPpiDesc == NULL) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SiPolicyPreMemPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  SiPolicyPreMemPpiDesc->Guid  = &gSiPreMemPolicyPpiGuid;
+  SiPolicyPreMemPpiDesc->Ppi   = SiPolicyPreMemPpi;
+
+  //
+  // Print whole PCH_POLICY_PPI and serial out.
+  //
+  PchPreMemPrintPolicyPpi (SiPolicyPreMemPpi);
+  //
+  // Print ME config blocks and serial out.
+  //
+  MePrintPolicyPpiPreMem (SiPolicyPreMemPpi);
+  //
+  // Print whole SI_POLICY_PPI and serial out.
+  //
+  SaPrintPolicyPpiPreMem (SiPolicyPreMemPpi);
+  //
+  // Print whole CPU of SI_PREMEM_POLICY_PPI and serial out.
+  //
+  CpuPreMemPrintPolicy (SiPolicyPreMemPpi);
+  //
+  // Install Silicon Policy PPI
+  //
+  Status = PeiServicesInstallPpi (SiPolicyPreMemPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
new file mode 100644
index 0000000000..cf7e1b2308
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
@@ -0,0 +1,36 @@
+/** @file
+  This file is PeiSiPolicyLib library for printing Policy settings.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyLibrary.h"
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPrintPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  SI_CONFIG     *SiConfig;
+  EFI_STATUS    Status;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ Silicon Print Policy Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " CsmFlag= %x\n", SiConfig->CsmFlag));
+  DEBUG ((DEBUG_INFO, " TraceHubMemBase = 0x%08x\n", SiConfig->TraceHubMemBase));
+
+  DEBUG ((DEBUG_INFO, "------------------------ Silicon Print Policy End --------------------------\n"));
+  DEBUG_CODE_END ();
+}
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (13 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
                   ` (22 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds CPU library class instances.

* BaseCpuMailboxLibNull - Generic CPU mailbox interaction services.
* PeiCpuPolicyLib - CPU policy configuration services.
* PeiCpuPolicyLibPreMem - CPU policy pre-memory configuration services.
* PeiDxeSmmCpuPlatformLib - CPU platform services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf     |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf                 |  65 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf           |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf |  39 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h               |  30 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h        |  28 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c       |  90 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c                    | 293 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c              | 108 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c                   | 434 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c             | 160 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c        | 415 +++++++++++++++++++
 12 files changed, 1727 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
new file mode 100644
index 0000000000..4fcfca4670
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
@@ -0,0 +1,22 @@
+## @file
+# Component description file for Cpu Mailbox Null Lib
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseCpuMailboxLibNull
+FILE_GUID = 74F470BC-1769-4732-B9C0-EE9AB0B12411
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuMailboxLib
+
+[Packages]
+MdePkg/MdePkg.dec
+
+[Sources]
+BaseCpuMailboxLibNull.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
new file mode 100644
index 0000000000..c986e35360
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Component description file for the PeiCpuPolicyLib library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiCpuPolicyLib
+FILE_GUID = 5baafc8f-25c6-4d19-b141-585757509372
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = CpuPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+PciSegmentLib
+SaPlatformLib
+SiConfigBlockLib
+PostCodeLib
+PcdLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiCpuPolicyLib.c
+PeiCpuPolicyLibrary.h
+CpuPrintPolicy.c
+PeiCpuPolicyLibPreMem.c
+CpuPrintPolicyPreMem.c
+
+[Ppis]
+gSiPolicyPpiGuid                    ## CONSUMES
+gSiPreMemPolicyPpiGuid              ## CONSUMES
+
+[FixedPcd]
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+
+[Pcd]
+gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode  ## Produces
+
+[Guids]
+gCpuConfigGuid                      ## PRODUCES
+gCpuSgxConfigGuid                   ## PRODUCES
+gCpuPowerMgmtBasicConfigGuid        ## PRODUCES
+gCpuPowerMgmtCustomConfigGuid       ## PRODUCES
+gCpuTestConfigGuid                  ## PRODUCES
+gCpuPidTestConfigGuid               ## PRODUCES
+gCpuPowerMgmtTestConfigGuid         ## PRODUCES
+gCpuConfigLibPreMemConfigGuid       ## PRODUCES
+gCpuSecurityPreMemConfigGuid        ## PRODUCES
+gCpuOverclockingPreMemConfigGuid    ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
new file mode 100644
index 0000000000..52dc989f74
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiCpuPolicyLibPreMem library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiCpuPolicyLibPreMem
+FILE_GUID = 5F4C2CF1-9DFE-4D99-9318-98FD31C8517D
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = CpuPolicyLibPreMem
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+SiConfigBlockLib
+PostCodeLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiCpuPolicyLib.c
+PeiCpuPolicyLibrary.h
+CpuPrintPolicy.c
+
+[Ppis]
+gSiPreMemPolicyPpiGuid         ## CONSUMES
+
+[Guids]
+gCpuSecurityPreMemConfigGuid      ## PRODUCES
+gCpuOverclockingPreMemConfigGuid  ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
new file mode 100644
index 0000000000..0a56e42817
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for CPU Platform Lib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmCpuPlatformLib
+FILE_GUID = 11647130-6AA4-41A4-A3A8-5FA296ABD977
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuPlatformLib
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+DebugLib
+IoLib
+PcdLib
+CpuLib
+TimerLib
+SynchronizationLib
+PciSegmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+CpuPlatformLibrary.h
+CpuPlatformLibrary.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
new file mode 100644
index 0000000000..6e993053fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
@@ -0,0 +1,30 @@
+/** @file
+  Header file for the PeiCpuPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_LIBRARY_H_
+#define _PEI_CPU_POLICY_LIBRARY_H_
+
+#include <PiPei.h>
+#include <CpuAccess.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/CpuPolicyLib.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/Cpuid.h>
+#include <Library/PcdLib.h>
+
+#define MAX_MICROCODE_PATCH_SIZE 0x20000
+
+#endif // _PEI_CPU_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
new file mode 100644
index 0000000000..0b780acd22
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
@@ -0,0 +1,28 @@
+/** @file
+  Header file for Cpu Platform Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SynchronizationLib.h>
+
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <CpuAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
new file mode 100644
index 0000000000..2af11ce8d0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
@@ -0,0 +1,90 @@
+/** @file
+  Mailbox Library.
+
+  Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+
+/**
+  Generic Mailbox function for mailbox write commands. This function will
+  poll the mailbox interface for control, issue the write request, poll
+  for completion, and verify the write was successful.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[in]  MailboxData     Overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status values are:
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval    EFI_SUCCESS           Command succeeded.
+  @retval    EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+  @retval    EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  IN UINT32  MailboxData,
+  OUT UINT32 *MailboxStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Generic Mailbox function for mailbox read commands. This function will write
+  the read request from MailboxType, and populate the read results in the MailboxDataPtr.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status are
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_SUCCESS           Command succeeded.
+  @retval EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+  @retval EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  OUT UINT32 *MailboxDataPtr,
+  OUT UINT32 *MailboxStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Poll the run/busy bit of the mailbox until available or timeout expires.
+
+  @param[in]  MailboxType
+
+  @retval EFI_SUCCESS           Command succeeded.
+  @retval EFI_TIMEOUT           Command timeout.
+**/
+EFI_STATUS
+EFIAPI
+PollMailboxReady (
+  IN UINT32 MailboxType
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
new file mode 100644
index 0000000000..38cf383e8d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
@@ -0,0 +1,293 @@
+/** @file
+  This file is PeiCpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/PcdLib.h>
+
+/**
+  Print CPU_CONFIG and serial out.
+
+  @param[in] CpuConfig   Pointer to a CPU_CONFIG
+**/
+VOID
+CpuConfigPrint (
+  IN CONST CPU_CONFIG   *CpuConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ CPU Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_CONFIG : AesEnable : 0x%x\n", CpuConfig->AesEnable));
+  DEBUG ((DEBUG_INFO, " CPU_CONFIG : MicrocodePatchAddress : 0x%x\n", CpuConfig->MicrocodePatchAddress));
+  DEBUG ((DEBUG_INFO, " CPU_CONFIG : DebugInterfaceEnable : 0x%X\n", CpuConfig->DebugInterfaceEnable));
+}
+
+/**
+  Print CPU_POWER_MGMT_BASIC_CONFIG and serial out.
+
+  @param[in] CpuPowerMgmtBasicConfig   Pointer to a CPU_POWER_MGMT_BASIC_CONFIG
+**/
+VOID
+CpuPowerMgmtBasicConfigPrint (
+  IN CONST CPU_POWER_MGMT_BASIC_CONFIG   *CpuPowerMgmtBasicConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Basic Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG : OneCoreRatioLimit : 0x%X , TwoCoreRatioLimit = 0x%X , ThreeCoreRatioLimit = 0x%X , FourCoreRatioLimit = 0x%X, FiveCoreRatioLimit = 0x%X, SixCoreRatioLimit = 0x%X, SevenCoreRatioLimit = 0x%X, EightCoreRatioLimit = 0x%X \n",  CpuPowerMgmtBasicConfig->OneCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->TwoCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->FourCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->FiveCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->SixCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->SevenCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->EightCoreRatioLimit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: Hwp : 0x%x\n", CpuPowerMgmtBasicConfig->Hwp));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: SkipSetBootPState : 0x%x\n", CpuPowerMgmtBasicConfig->SkipSetBootPState));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HdcControl : 0x%X\n", CpuPowerMgmtBasicConfig->HdcControl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: (Intel Turbo Boost Max Technology 3.0)EnableItbm : 0x%X\n", CpuPowerMgmtBasicConfig->EnableItbm));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: EnableItbmDriver : 0x%X\n", CpuPowerMgmtBasicConfig->EnableItbmDriver));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit2 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboPowerLimitLock : 0x%x\n", CpuPowerMgmtBasicConfig->TurboPowerLimitLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3DutyCycle : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Lock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit4Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4Lock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetClamp : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetClamp));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetLock : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboMode : 0x%x\n", CpuPowerMgmtBasicConfig->TurboMode));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccActivationOffset : 0x%X\n", CpuPowerMgmtBasicConfig->TccActivationOffset));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit1 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit2Power : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2Power));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit4 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit1Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1Time));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Time));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetTimeWindowForRatl : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HwpInterruptControl : 0x%x\n", CpuPowerMgmtBasicConfig->HwpInterruptControl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: MinRingRatioLimit : 0x%x\n", CpuPowerMgmtBasicConfig->MinRingRatioLimit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: MaxRingRatioLimit : 0x%x\n", CpuPowerMgmtBasicConfig->MaxRingRatioLimit));
+}
+
+/**
+  Print CPU_POWER_MGMT_CUSTOM_CONFIG and serial out.
+
+  @param[in] CpuPowerMgmtCustomConfig   Pointer to a CPU_POWER_MGMT_CUSTOM_CONFIG
+**/
+VOID
+CpuPowerMgmtCustomConfigPrint (
+  IN CONST CPU_POWER_MGMT_CUSTOM_CONFIG   *CpuPowerMgmtCustomConfig
+  )
+{
+  UINT32 Index = 0;
+  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Custom Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "\n CustomRatioTable... \n"));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidNumber : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidCpuid : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidMaxRatio : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio));
+  for (Index = 0; Index < MAX_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: StateRatio[%d] : 0x%x\n", Index, CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index]));
+  }
+  for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: StateRatioMax16[%d] : 0x%x\n", Index, CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index]));
+  }
+  for (Index = 0; Index < MAX_CUSTOM_CTDP_ENTRIES; Index++) {
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit1 : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit1)
+            );
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit2 : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit2)
+            );
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit1Time : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit1Time)
+            );
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomTurboActivationRatio : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomTurboActivationRatio)
+            );
+  }
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: ConfigTdpLock : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: ConfigTdpBios : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpBios));
+}
+
+/**
+  Print CPU_TEST_CONFIG and serial out.
+
+  @param[in] CpuTestConfig   Pointer to a CPU_TEST_CONFIG
+**/
+VOID
+CpuTestConfigPrint (
+  IN CONST CPU_TEST_CONFIG   *CpuTestConfig
+  )
+{
+  UINT8 PcdCpuApLoopMode;
+
+  PcdCpuApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+
+  DEBUG ((DEBUG_INFO, "------------------ CPU Test Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcStreamerPrefetcher : 0x%X\n", CpuTestConfig->MlcStreamerPrefetcher));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcSpatialPrefetcher : 0x%X\n", CpuTestConfig->MlcSpatialPrefetcher));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MonitorMwaitEnable : 0x%X\n", CpuTestConfig->MonitorMwaitEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MachineCheckEnable : 0x%X\n", CpuTestConfig->MachineCheckEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: DebugInterfaceLockEnable : 0x%X\n", CpuTestConfig->DebugInterfaceLockEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceOutputScheme : 0x%X\n", CpuTestConfig->ProcessorTraceOutputScheme));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceEnable : 0x%X\n", CpuTestConfig->ProcessorTraceEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemBase : 0x%llX\n", CpuTestConfig->ProcessorTraceMemBase));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemLength : 0x%X\n", CpuTestConfig->ProcessorTraceMemLength));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ThreeStrikeCounterDisable : 0x%X\n", CpuTestConfig->ThreeStrikeCounterDisable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: VoltageOptimization : 0x%X\n", CpuTestConfig->VoltageOptimization));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: CpuWakeUpTimer : 0x%X\n", CpuTestConfig->CpuWakeUpTimer));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: PcdCpuApLoopMode: 0x%X\n", PcdCpuApLoopMode));
+}
+
+/**
+  Print CPU_PID_TEST_CONFIG and serial out.
+
+  @param[in] CpuPidTestConfig   Pointer to a CPU_PID_TEST_CONFIG
+**/
+VOID
+CpuPidTestConfigPrint (
+  IN CONST CPU_PID_TEST_CONFIG   *CpuPidTestConfig
+  )
+{
+  UINT32 Index = 0;
+  DEBUG ((DEBUG_INFO, "------------------ CPU PID Test Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PidTuning : 0x%X\n", Index,  CpuPidTestConfig->PidTuning));
+  if ( CpuPidTestConfig->PidTuning == 1) {
+    for (Index = PID_DOMAIN_KP; Index <= PID_DOMAIN_KD; Index++) {
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : Ratl[%X] : 0x%X\n", Index,  CpuPidTestConfig->Ratl[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr0[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr0[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr1[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr1[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr2[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr2[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr3[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr3[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl1Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl1MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl2Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl2MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl1Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl1MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl2Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl2MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl1Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl1MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl2Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl2MmioPcs[Index]));
+    }
+  }
+}
+
+/**
+  Print CPU_POWER_MGMT_TEST_CONFIG and serial out.
+
+  @param[in] CpuPowerMgmtTestConfig   Pointer to a CPU_POWER_MGMT_TEST_CONFIG
+**/
+VOID
+CpuPowerMgmtTestConfigPrint (
+  IN CONST CPU_POWER_MGMT_TEST_CONFIG   *CpuPowerMgmtTestConfig
+  )
+{
+  CPU_GENERATION CpuGeneration;
+  CpuGeneration = GetCpuGeneration();
+  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Test Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Eist : 0x%x\n", CpuPowerMgmtTestConfig->Eist));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: EnergyEfficientPState : 0x%x\n", CpuPowerMgmtTestConfig->EnergyEfficientPState));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: EnergyEfficientTurbo : 0x%x\n", CpuPowerMgmtTestConfig->EnergyEfficientTurbo));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TStates : 0x%x\n", CpuPowerMgmtTestConfig->TStates));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: BiProcHot : 0x%x\n", CpuPowerMgmtTestConfig->BiProcHot));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: DisableProcHotOut : 0x%x\n", CpuPowerMgmtTestConfig->DisableProcHotOut));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotResponse : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotResponse));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: DisableVrThermalAlert : 0x%x\n", CpuPowerMgmtTestConfig->DisableVrThermalAlert));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: AutoThermalReporting : 0x%x\n", CpuPowerMgmtTestConfig->AutoThermalReporting));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ThermalMonitor : 0x%x\n", CpuPowerMgmtTestConfig->ThermalMonitor));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Cx : 0x%x\n", CpuPowerMgmtTestConfig->Cx));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PmgCstCfgCtrlLock : 0x%x\n", CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1e : 0x%x\n", CpuPowerMgmtTestConfig->C1e));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1Autodemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1AutoDemotion));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1Undemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1UnDemotion));
+  if(CpuGeneration == EnumCflCpu){
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C3AutoDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3AutoDemotion));
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C3UnDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3UnDemotion));
+  }
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCState Demotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateDemotion));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCstateUndemotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateUnDemotion));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CStatePreWake : 0x%x\n", CpuPowerMgmtTestConfig->CStatePreWake));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TimedMwait : 0x%x\n", CpuPowerMgmtTestConfig->TimedMwait));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstCfgCtrIoMwaitRedirection : 0x%x\n", CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotLock : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ConfigTdpLevel : 0x%x\n", CpuPowerMgmtTestConfig->ConfigTdpLevel));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: RaceToHalt  : 0x%x\n",  CpuPowerMgmtTestConfig->RaceToHalt));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl0Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl0TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl1Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl2Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl3Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl4Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl5Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCStateLimit : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateLimit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl1TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl2TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl3TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl4TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl5TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CustomPowerUnit : 0x%x\n", CpuPowerMgmtTestConfig->CustomPowerUnit));
+  DEBUG ((DEBUG_INFO, " PpmIrmSetting : 0x%x\n", CpuPowerMgmtTestConfig->PpmIrmSetting));
+}
+/**
+  Print whole CPU config blocks of SI_POLICY_PPI and serial out in PostMem.
+
+  @param[in] SiPolicyPpi The SI Policy PPI instance
+**/
+VOID
+CpuPrintPolicy (
+  IN  SI_POLICY_PPI       *SiPolicyPpi
+  )
+{
+DEBUG_CODE_BEGIN();
+  EFI_STATUS                       Status;
+  CPU_CONFIG                       *CpuConfig;
+  CPU_POWER_MGMT_BASIC_CONFIG      *CpuPowerMgmtBasicConfig;
+  CPU_POWER_MGMT_CUSTOM_CONFIG     *CpuPowerMgmtCustomConfig;
+  CPU_TEST_CONFIG                  *CpuTestConfig;
+  CPU_PID_TEST_CONFIG              *CpuPidTestConfig;
+  CPU_POWER_MGMT_TEST_CONFIG       *CpuPowerMgmtTestConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *) &CpuPowerMgmtCustomConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID *) &CpuTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPidTestConfigGuid, (VOID *) &CpuPidTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print Begin in PostMem----------------- \n"));
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPolicyPpi->TableHeader.Header.Revision));
+
+  CpuConfigPrint(CpuConfig);
+  CpuPowerMgmtBasicConfigPrint(CpuPowerMgmtBasicConfig);
+  CpuPowerMgmtCustomConfigPrint(CpuPowerMgmtCustomConfig);
+  CpuTestConfigPrint(CpuTestConfig);
+  CpuPidTestConfigPrint(CpuPidTestConfig);
+  CpuPowerMgmtTestConfigPrint(CpuPowerMgmtTestConfig);
+  DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print End in PostMem ----------------- \n\n"));
+DEBUG_CODE_END();
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
new file mode 100644
index 0000000000..0bcb34c99c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
@@ -0,0 +1,108 @@
+/** @file
+  This file is PeiCpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/ConfigBlockLib.h>
+
+/**
+  Print CPU_CONFIG_LIB_PREMEM_CONFIG and serial out.
+
+  @param[in] CpuConfigLibPreMemConfig     Pointer to a CPU_CONFIG_LIB_PREMEM_CONFIG
+
+**/
+VOID
+CpuConfigLibPreMemConfigPrint (
+  IN CONST CPU_CONFIG_LIB_PREMEM_CONFIG        *CpuConfigLibPreMemConfig
+  )
+{
+  CPU_GENERATION CpuGeneration;
+  CpuGeneration = GetCpuGeneration();
+  DEBUG ((DEBUG_INFO, "------------------ CPU Config Lib PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : HyperThreading = 0x%x\n", CpuConfigLibPreMemConfig->HyperThreading));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BootFrequency = 0x%x\n", CpuConfigLibPreMemConfig->BootFrequency));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : ActiveCoreCount = 0x%x\n", CpuConfigLibPreMemConfig->ActiveCoreCount));
+  if(CpuGeneration == EnumCflCpu){
+    DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : FClkFrequency = 0x%x\n", CpuConfigLibPreMemConfig->FClkFrequency));
+  }
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : JtagC10PowerGateDisable = 0x%x\n", CpuConfigLibPreMemConfig->JtagC10PowerGateDisable));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BistOnReset = 0x%x\n", CpuConfigLibPreMemConfig->BistOnReset));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : VmxEnable = 0x%x\n", CpuConfigLibPreMemConfig->VmxEnable));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : CpuRatio = 0x%x\n", CpuConfigLibPreMemConfig->CpuRatio));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciSxReset = 0x%x\n", CpuConfigLibPreMemConfig->PeciSxReset));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciC10Reset = 0x%x\n", CpuConfigLibPreMemConfig->PeciC10Reset));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : SkipMpInit = 0x%x\n", CpuConfigLibPreMemConfig->SkipMpInit));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : DpSscMarginEnable = 0x%x\n", CpuConfigLibPreMemConfig->DpSscMarginEnable));
+}
+
+/**
+  Print CPU_OVERCLOCKING_PREMEM_CONFIG and serial out.
+
+  @param[in] CpuOverClockingConfig   Pointer to a CPU_OVERCLOCKING_CONFIG
+**/
+VOID
+CpuOverClockingPreMemConfigPrint (
+  IN CONST CPU_OVERCLOCKING_PREMEM_CONFIG   *CpuOverClockingPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ CPU OverClocking Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcSupport : 0x%X\n", CpuOverClockingPreMemConfig->OcSupport));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcLock : 0x%X\n", CpuOverClockingPreMemConfig->OcLock));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageMode : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageMode));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreMaxOcRatio  : 0x%X\n", CpuOverClockingPreMemConfig->CoreMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageOverride : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageOverride));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageAdaptive : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageAdaptive));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageMode : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageMode));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageOverride : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageOverride));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageAdaptive : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageAdaptive));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingMaxOcRatio  : 0x%X\n", CpuOverClockingPreMemConfig->RingMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingDownBin     : 0x%X\n", CpuOverClockingPreMemConfig->RingDownBin));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: Avx2RatioOffset : 0x%X\n", CpuOverClockingPreMemConfig->Avx2RatioOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: Avx3RatioOffset : 0x%X\n", CpuOverClockingPreMemConfig->Avx3RatioOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: BclkAdaptiveVoltage  : 0x%X\n", CpuOverClockingPreMemConfig->BclkAdaptiveVoltage));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CorePllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->CorePllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: GtPllVoltageOffset   : 0x%X\n", CpuOverClockingPreMemConfig->GtPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingPllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->RingPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: SaPllVoltageOffset   : 0x%X\n", CpuOverClockingPreMemConfig->SaPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: McPllVoltageOffset   : 0x%X\n", CpuOverClockingPreMemConfig->McPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TjMaxOffset          : 0x%X\n", CpuOverClockingPreMemConfig->TjMaxOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TvbRatioClipping     : 0x%X\n", CpuOverClockingPreMemConfig->TvbRatioClipping));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TvbVoltageOptimization : 0x%X\n", CpuOverClockingPreMemConfig->TvbVoltageOptimization));
+}
+
+
+/**
+  Print whole CPU Config blocks of SI_PREMEM_POLICY_PPI and serial out in PreMem.
+
+  @param[in] SiPreMemPolicyPpi The SI Pre-Mem Policy PPI instance
+**/
+VOID
+CpuPreMemPrintPolicy (
+  IN  SI_PREMEM_POLICY_PPI       *SiPreMemPolicyPpi
+  )
+{
+DEBUG_CODE_BEGIN();
+  EFI_STATUS                      Status;
+  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverclockingPreMemConfig;
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print Begin in PreMem -----------------\n"));
+
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPreMemPolicyPpi->TableHeader.Header.Revision));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverclockingPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  CpuConfigLibPreMemConfigPrint(CpuConfigLibPreMemConfig);
+  CpuOverClockingPreMemConfigPrint(CpuOverclockingPreMemConfig);
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print End -----------------\n\n"));
+DEBUG_CODE_END();
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
new file mode 100644
index 0000000000..181b72fec5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
@@ -0,0 +1,434 @@
+/** @file
+  This file is PeiCpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <SaAccess.h>
+#include <CpuAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/PcdLib.h>
+
+#ifndef FSP_FLAG
+/**
+  Get the next microcode patch pointer.
+
+  @param[in, out] MicrocodeData - Input is a pointer to the last microcode patch address found,
+                                  and output points to the next patch address found.
+
+  @retval EFI_SUCCESS           - Patch found.
+  @retval EFI_NOT_FOUND         - Patch not found.
+**/
+EFI_STATUS
+EFIAPI
+RetrieveMicrocode (
+  IN OUT CPU_MICROCODE_HEADER **MicrocodeData
+  )
+{
+  UINTN                MicrocodeStart;
+  UINTN                MicrocodeEnd;
+  UINTN                TotalSize;
+
+  if ((FixedPcdGet32 (PcdFlashMicrocodeFvBase) == 0) || (FixedPcdGet32 (PcdFlashMicrocodeFvSize) == 0)) {
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Microcode binary in SEC
+  ///
+  MicrocodeStart = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) +
+          ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase))->HeaderLength +
+          sizeof (EFI_FFS_FILE_HEADER);
+
+  MicrocodeEnd = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) + (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvSize);
+
+  if (*MicrocodeData == NULL) {
+    *MicrocodeData = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodeStart;
+  } else {
+    if (*MicrocodeData < (CPU_MICROCODE_HEADER *) (UINTN) MicrocodeStart) {
+      DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData < MicrocodeStart \n"));
+      return EFI_NOT_FOUND;
+    }
+
+    TotalSize = (UINTN) ((*MicrocodeData)->TotalSize);
+    if (TotalSize == 0) {
+      TotalSize = 2048;
+    }
+
+    *MicrocodeData = (CPU_MICROCODE_HEADER *) ((UINTN)*MicrocodeData + TotalSize);
+    if (*MicrocodeData >= (CPU_MICROCODE_HEADER *) (UINTN) (MicrocodeEnd) || (*MicrocodeData)->TotalSize == (UINT32) -1) {
+      DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData >= MicrocodeEnd \n"));
+      return EFI_NOT_FOUND;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Get the microcode patch pointer.
+
+  @retval EFI_PHYSICAL_ADDRESS - Address of the microcode patch, or NULL if not found.
+**/
+EFI_PHYSICAL_ADDRESS
+PlatformCpuLocateMicrocodePatch (
+  VOID
+  )
+{
+  EFI_STATUS           Status;
+  CPU_MICROCODE_HEADER *MicrocodeData;
+  EFI_CPUID_REGISTER   Cpuid;
+  UINT32               UcodeRevision;
+  UINTN                MicrocodeBufferSize;
+  VOID                 *MicrocodeBuffer = NULL;
+
+  AsmCpuid (
+    CPUID_VERSION_INFO,
+    &Cpuid.RegEax,
+    &Cpuid.RegEbx,
+    &Cpuid.RegEcx,
+    &Cpuid.RegEdx
+    );
+
+  UcodeRevision = GetCpuUcodeRevision ();
+  MicrocodeData = NULL;
+  while (TRUE) {
+    ///
+    /// Find the next patch address
+    ///
+    Status = RetrieveMicrocode (&MicrocodeData);
+    DEBUG ((DEBUG_INFO, "MicrocodeData = %x\n", MicrocodeData));
+
+    if (Status != EFI_SUCCESS) {
+      break;
+    } else if (CheckMicrocode (Cpuid.RegEax, MicrocodeData, &UcodeRevision)) {
+      break;
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+  }
+
+  ///
+  /// Check that microcode patch size is <= 128K max size,
+  /// then copy the patch from FV to temp buffer for faster access.
+  ///
+  MicrocodeBufferSize = (UINTN) MicrocodeData->TotalSize;
+
+  if (MicrocodeBufferSize <= MAX_MICROCODE_PATCH_SIZE) {
+    MicrocodeBuffer = AllocatePages (EFI_SIZE_TO_PAGES (MicrocodeBufferSize));
+    if (MicrocodeBuffer != NULL) {
+      DEBUG(( DEBUG_INFO, "Copying Microcode to temp buffer.\n"));
+      CopyMem (MicrocodeBuffer, MicrocodeData, MicrocodeBufferSize);
+
+      return (EFI_PHYSICAL_ADDRESS) (UINTN) MicrocodeBuffer;
+    } else {
+      DEBUG(( DEBUG_ERROR, "Failed to allocate enough memory for Microcode Patch.\n"));
+    }
+  } else {
+    DEBUG(( DEBUG_ERROR, "Microcode patch size is greater than max allowed size of 128K.\n"));
+  }
+  return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+}
+#endif
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_CONFIG  *CpuConfig;
+  CpuConfig  = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Name = %g\n", &CpuConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU configuration
+  ********************************/
+  CpuConfig->AesEnable             = CPU_FEATURE_ENABLE;
+#ifndef FSP_FLAG
+  CpuConfig->MicrocodePatchAddress = PlatformCpuLocateMicrocodePatch ();
+#endif //FSP_FLAG
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuSgxConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+
+  /********************************
+    CPU SGX configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtBasicConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_POWER_MGMT_BASIC_CONFIG  *CpuPowerMgmtBasicConfig;
+  CPU_SKU      CpuSku;
+  MSR_REGISTER TempMsr;
+
+  CpuPowerMgmtBasicConfig = ConfigBlockPointer;
+  CpuSku                  = GetCpuSku();
+
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtBasicConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtBasicConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Power Management Basic configuration
+  ********************************/
+  CpuPowerMgmtBasicConfig->Hwp                          = TRUE;
+  CpuPowerMgmtBasicConfig->HdcControl                   = TRUE;
+  CpuPowerMgmtBasicConfig->PowerLimit2                  = TRUE;
+  CpuPowerMgmtBasicConfig->PowerLimit3Lock              = TRUE;
+  CpuPowerMgmtBasicConfig->TccOffsetLock                = FALSE;
+  CpuPowerMgmtBasicConfig->EnableItbm                   = TRUE;
+  CpuPowerMgmtBasicConfig->EnableItbmDriver             = FALSE;
+
+  ///
+  /// Initialize RATL (Runtime Average Temperature Limit) Config for ULX.
+  ///
+  if (CpuSku == EnumCpuUlx) {
+    CpuPowerMgmtBasicConfig->TccActivationOffset        = 15;
+    CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl = 5000; // 5 sec
+    CpuPowerMgmtBasicConfig->TccOffsetClamp             = CPU_FEATURE_ENABLE;
+  }
+  CpuPowerMgmtBasicConfig->TurboMode                    = TRUE;
+
+  TempMsr.Qword = AsmReadMsr64 (MSR_TURBO_RATIO_LIMIT);
+  CpuPowerMgmtBasicConfig->OneCoreRatioLimit = TempMsr.Bytes.FirstByte;
+  CpuPowerMgmtBasicConfig->TwoCoreRatioLimit = TempMsr.Bytes.SecondByte;
+  CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit = TempMsr.Bytes.ThirdByte;
+  CpuPowerMgmtBasicConfig->FourCoreRatioLimit = TempMsr.Bytes.FouthByte;
+  CpuPowerMgmtBasicConfig->FiveCoreRatioLimit = TempMsr.Bytes.FifthByte;
+  CpuPowerMgmtBasicConfig->SixCoreRatioLimit = TempMsr.Bytes.SixthByte;
+  CpuPowerMgmtBasicConfig->SevenCoreRatioLimit = TempMsr.Bytes.SeventhByte;
+  CpuPowerMgmtBasicConfig->EightCoreRatioLimit = TempMsr.Bytes.EighthByte;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtCustomConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_POWER_MGMT_CUSTOM_CONFIG  *CpuPowerMgmtCustomConfig;
+  CpuPowerMgmtCustomConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtCustomConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtCustomConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Power Management Custom configuration
+  ********************************/
+  CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid = (UINT16) ((GetCpuFamily() | GetCpuStepping()) & (0x0FFF));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuTestConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_TEST_CONFIG  *CpuTestConfig;
+  CPU_SKU          CpuSku;
+  CpuTestConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Name = %g\n", &CpuTestConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuTestConfig->Header.GuidHob.Header.HobLength));
+
+  CpuSku = GetCpuSku();
+  /********************************
+    CPU Test configuration
+  ********************************/
+
+  CpuTestConfig->MlcStreamerPrefetcher    = CPU_FEATURE_ENABLE;
+  CpuTestConfig->MlcSpatialPrefetcher     = CPU_FEATURE_ENABLE;
+  CpuTestConfig->MonitorMwaitEnable       = CPU_FEATURE_ENABLE;
+  CpuTestConfig->MachineCheckEnable       = CPU_FEATURE_ENABLE;
+  CpuTestConfig->DebugInterfaceLockEnable = CPU_FEATURE_ENABLE;
+
+  if ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt)){
+    /**
+    This policy should be used to enable or disable Voltage Optimization feature. Recommended defaults:
+     Enable  - For Mobile SKUs(U/Y)
+     Disable - Rest of all SKUs other than Mobile.
+    **/
+    CpuTestConfig->VoltageOptimization      = CPU_FEATURE_ENABLE;
+  }
+  else {
+    CpuTestConfig->VoltageOptimization      = CPU_FEATURE_DISABLE;
+  }
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPidTestConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_PID_TEST_CONFIG  *CpuPidTestConfig;
+  CpuPidTestConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Name = %g\n", &CpuPidTestConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPidTestConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU PID Test configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtTestConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_POWER_MGMT_TEST_CONFIG  *CpuPowerMgmtTestConfig;
+  CPU_GENERATION              CpuGeneration;
+  UINT16                      CpuDid;
+
+  CpuPowerMgmtTestConfig = ConfigBlockPointer;
+  CpuDid    = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtTestConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtTestConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Power Management Test configuration
+  ********************************/
+  CpuPowerMgmtTestConfig->Eist                          = TRUE;
+  CpuPowerMgmtTestConfig->EnergyEfficientPState         = TRUE;
+  CpuPowerMgmtTestConfig->EnergyEfficientTurbo          = TRUE;
+  if ((CpuDid == V_SA_DEVICE_ID_CFL_DT_1) || (CpuDid == V_SA_DEVICE_ID_CFL_DT_2)
+     || (CpuDid == V_SA_DEVICE_ID_CFL_DT_3) || (CpuDid == V_SA_DEVICE_ID_CFL_DT_4)) {
+    ///
+    /// CFL-S 6+2, CFL S 8+2, CFl S 4+2, CFL S 2+2
+    ///
+    CpuPowerMgmtTestConfig->EnergyEfficientTurbo      = FALSE;
+  }
+  CpuPowerMgmtTestConfig->BiProcHot                     = TRUE;
+  CpuPowerMgmtTestConfig->DisableProcHotOut             = TRUE;
+  CpuPowerMgmtTestConfig->AutoThermalReporting          = TRUE;
+  CpuPowerMgmtTestConfig->ThermalMonitor                = TRUE;
+  CpuPowerMgmtTestConfig->Cx                            = TRUE;
+  CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock             = TRUE;
+  CpuPowerMgmtTestConfig->C1e                           = TRUE;
+  CpuPowerMgmtTestConfig->C1AutoDemotion                = TRUE;
+  CpuPowerMgmtTestConfig->C1UnDemotion                  = TRUE;
+  CpuGeneration = GetCpuGeneration();
+  if(CpuGeneration == EnumCflCpu){
+    CpuPowerMgmtTestConfig->C3AutoDemotion                = TRUE;
+    CpuPowerMgmtTestConfig->C3UnDemotion                  = TRUE;
+  }
+
+  CpuPowerMgmtTestConfig->CStatePreWake                 = TRUE;
+  CpuPowerMgmtTestConfig->RaceToHalt                    = TRUE;
+  CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl     = C3_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl     = C6_C7_SHORT_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl     = C6_C7_LONG_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl     = C8_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl     = C9_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl     = C10_LATENCY;
+
+  CpuPowerMgmtTestConfig->PkgCStateLimit                = PkgAuto;
+  CpuPowerMgmtTestConfig->CustomPowerUnit               = PowerUnit125MilliWatts;
+  CpuPowerMgmtTestConfig->PpmIrmSetting                 = PpmIrmPairFixedPriority;
+}
+
+static COMPONENT_BLOCK_ENTRY  mCpuIpBlocks [] = {
+  {&gCpuConfigGuid,                     sizeof (CPU_CONFIG),                         CPU_CONFIG_REVISION,                        LoadCpuConfigDefault},
+  {&gCpuPowerMgmtBasicConfigGuid,       sizeof (CPU_POWER_MGMT_BASIC_CONFIG),        CPU_POWER_MGMT_BASIC_CONFIG_REVISION,       LoadCpuPowerMgmtBasicConfigDefault},
+  {&gCpuPowerMgmtCustomConfigGuid,      sizeof (CPU_POWER_MGMT_CUSTOM_CONFIG),       CPU_POWER_MGMT_CUSTOM_CONFIG_REVISION,      LoadCpuPowerMgmtCustomConfigDefault},
+  {&gCpuTestConfigGuid,                 sizeof (CPU_TEST_CONFIG),                    CPU_TEST_CONFIG_REVISION,                   LoadCpuTestConfigDefault},
+  {&gCpuPidTestConfigGuid,              sizeof (CPU_PID_TEST_CONFIG),                CPU_PID_TEST_CONFIG_REVISION,               LoadCpuPidTestConfigDefault},
+  {&gCpuPowerMgmtTestConfigGuid,        sizeof (CPU_POWER_MGMT_TEST_CONFIG),         CPU_POWER_MGMT_TEST_CONFIG_REVISION,        LoadCpuPowerMgmtTestConfigDefault},
+};
+
+/**
+  Get CPU config block table total size.
+
+  @retval Size of CPU config block table
+**/
+UINT16
+EFIAPI
+CpuGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  CpuAddConfigBlocks add all Cpu config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS Status;
+  DEBUG((DEBUG_INFO, "CPU Post-Mem Entry \n"));
+  PostCode (0xC00);
+
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  DEBUG ((DEBUG_INFO, "CpuAddConfigBlocks Done \n"));
+  PostCode (0xC09);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
new file mode 100644
index 0000000000..7d45e10236
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
@@ -0,0 +1,160 @@
+/** @file
+  This file is PeiCpuPolicyLibPreMem library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/SaPlatformLib.h>
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuSecurityPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuConfigLibPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_GENERATION  CpuGeneration;
+  CPU_CONFIG_LIB_PREMEM_CONFIG  *CpuConfigLibPreMemConfig;
+  CPU_FAMILY      CpuFamily;
+  CPU_SKU         CpuSku;
+  BOOLEAN         PegDisabled;
+  UINT64          MchBar;
+  UINT64          SaPciBase;
+
+  CpuConfigLibPreMemConfig = ConfigBlockPointer;
+  CpuFamily  = GetCpuFamily();
+  CpuSku     = GetCpuSku();
+
+  DEBUG ((DEBUG_INFO, "CpuConfigLibPreMemConfig->Header.GuidHob.Name = %g\n", &CpuConfigLibPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Config Lib PreMem configuration
+  ********************************/
+  CpuConfigLibPreMemConfig->HyperThreading          = CPU_FEATURE_ENABLE;
+  CpuConfigLibPreMemConfig->BootFrequency           = 1;    // Maximum non-turbo Performance
+  CpuConfigLibPreMemConfig->ActiveCoreCount         = 0;    // All cores active
+  CpuConfigLibPreMemConfig->JtagC10PowerGateDisable = CPU_FEATURE_DISABLE;
+  CpuConfigLibPreMemConfig->BistOnReset             = CPU_FEATURE_DISABLE;
+  CpuConfigLibPreMemConfig->VmxEnable               = CPU_FEATURE_ENABLE;
+  CpuConfigLibPreMemConfig->CpuRatio = (RShiftU64 (AsmReadMsr64 (MSR_PLATFORM_INFO), N_PLATFORM_INFO_MAX_RATIO) & B_PLATFORM_INFO_RATIO_MASK);
+
+  CpuGeneration = GetCpuGeneration();
+  if(CpuGeneration == EnumCflCpu){
+    ///
+    /// FCLK Frequency
+    ///
+
+    SaPciBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, 0);
+    PciSegmentReadBuffer (SaPciBase + R_SA_MCHBAR, sizeof (MchBar), &MchBar);
+    MchBar &= ((UINT64) ~BIT0);
+    if (IsPchLinkDmi (CpuFamily) && (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF)) {
+      PegDisabled = MmioRead32 ((UINTN) MchBar + R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET) & BIT3;
+    } else {
+      PegDisabled = 1;
+    }
+
+    ///
+    /// DT/Halo FCLK = 1GHz
+    /// Ulx/Ult FCLK = 800MHz
+    ///
+    if (((CpuSku == EnumCpuHalo) && (!PegDisabled)) || (CpuSku == EnumCpuTrad)) {
+      CpuConfigLibPreMemConfig->FClkFrequency = 1;  // 1Ghz
+    }
+    else {
+      CpuConfigLibPreMemConfig->FClkFrequency = 0;  // 800MHz
+    }
+    ///
+    /// Disable Peci Reset on C10 exit on CFL based CPU's
+    /// Setting to 1 will activate the message that disables peci reset.
+    ///
+    CpuConfigLibPreMemConfig->PeciC10Reset = 1;
+  }
+}
+
+/**
+  Load Overclocking pre-mem Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuOverclockingPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverclockingPreMemConfig;
+  CpuOverclockingPreMemConfig = ConfigBlockPointer;
+
+  /********************************
+    CPU Overclocking PreMem configuration
+  ********************************/
+  DEBUG ((DEBUG_INFO, "CpuOverclockingPreMemConfig->Header.GuidHob.Name = %g\n", &CpuOverclockingPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY  mCpuIpBlocksPreMem [] = {
+  {&gCpuConfigLibPreMemConfigGuid,    sizeof (CPU_CONFIG_LIB_PREMEM_CONFIG),    CPU_CONFIG_LIB_PREMEM_CONFIG_REVISION,  LoadCpuConfigLibPreMemConfigDefault},
+  {&gCpuOverclockingPreMemConfigGuid, sizeof (CPU_OVERCLOCKING_PREMEM_CONFIG),  CPU_OVERCLOCKING_CONFIG_REVISION,       LoadCpuOverclockingPreMemConfigDefault},
+};
+
+/**
+  Get CPU PREMEM config block table total size.
+
+  @retval Size of CPU PREMEM config block table
+**/
+UINT16
+EFIAPI
+CpuGetPreMemConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS Status;
+  DEBUG((DEBUG_INFO, "CPU Pre-Mem Entry \n"));
+  PostCode (0xC00);
+
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+  DEBUG((DEBUG_INFO, "CpuAddPreMemConfigBlocks Done \n"));
+  PostCode (0xC0F);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
new file mode 100644
index 0000000000..18f2028fa9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
@@ -0,0 +1,415 @@
+/** @file
+  CPU Platform Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "CpuPlatformLibrary.h"
+#include <SaAccess.h>
+#include <MeChipset.h>
+
+#define SKIP_MICROCODE_CHECKSUM_CHECK 1
+#define C6DRAM_ENABLE 1
+#define C6DRAM_DISABLE 0
+
+/**
+  Return CPU Family ID
+
+  @retval CPU_FAMILY              CPU Family ID
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER Cpuid;
+  ///
+  /// Read the CPUID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  return ((CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL));
+}
+
+/**
+  Return Cpu stepping type
+
+  @retval UINT8                   Cpu stepping type
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER Cpuid;
+  ///
+  /// Read the CPUID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  return ((CPU_STEPPING) (Cpuid.RegEax & CPUID_FULL_STEPPING));
+}
+
+/**
+  Return CPU Sku
+
+  @retval UINT8              CPU Sku
+**/
+UINT8
+EFIAPI
+GetCpuSku (
+  VOID
+  )
+{
+  UINT8              CpuType;
+  UINT16             CpuDid;
+  UINT32             CpuFamilyModel;
+  EFI_CPUID_REGISTER Cpuid;
+  BOOLEAN            SkuFound;
+
+  SkuFound  = TRUE;
+  CpuType   = EnumCpuUnknown;
+
+  ///
+  /// Read the CPUID & DID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  CpuFamilyModel = Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL;
+  CpuDid = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+
+  switch (CpuFamilyModel) {
+    case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX:
+      switch (CpuDid) {
+        case V_SA_DEVICE_ID_KBL_MB_ULT_1:    // KBL ULT OPI
+        case V_SA_DEVICE_ID_CFL_ULT_1:       // CFL ULT
+        case V_SA_DEVICE_ID_CFL_ULT_2:       // CFL ULT
+        case V_SA_DEVICE_ID_CFL_ULT_3:       // CFL ULT
+        case V_SA_DEVICE_ID_CFL_ULT_4:       // CFL ULT
+          CpuType = EnumCpuUlt;
+          break;
+
+        default:
+          SkuFound = FALSE;
+          break;
+      }
+      break;
+
+    case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO:
+      switch (CpuDid) {
+
+        case V_SA_DEVICE_ID_KBL_DT_2:      // DT
+        case V_SA_DEVICE_ID_KBL_SVR_2:     // Server
+        case V_SA_DEVICE_ID_CFL_DT_1:      // DT
+        case V_SA_DEVICE_ID_CFL_DT_2:      // DT
+        case V_SA_DEVICE_ID_CFL_DT_3:      // DT
+        case V_SA_DEVICE_ID_CFL_DT_4:      // DT
+        case V_SA_DEVICE_ID_CFL_WS_1:      // WorkStation
+        case V_SA_DEVICE_ID_CFL_WS_2:      // Workstation
+        case V_SA_DEVICE_ID_CFL_WS_3:      // Workstation
+        case V_SA_DEVICE_ID_CFL_SVR_1:     // Server
+        case V_SA_DEVICE_ID_CFL_SVR_2:     // Server
+        case V_SA_DEVICE_ID_CFL_SVR_3:     // Server
+          CpuType = EnumCpuTrad;
+          break;
+
+        case V_SA_DEVICE_ID_KBL_HALO_2:    // Halo
+        case V_SA_DEVICE_ID_CFL_HALO_1:    // Halo
+        case V_SA_DEVICE_ID_CFL_HALO_2:    // Halo
+        case V_SA_DEVICE_ID_CFL_HALO_3:    // Halo
+          CpuType = EnumCpuHalo;
+          break;
+
+        default:
+          SkuFound = FALSE;
+          break;
+      }
+      break;
+
+    default:
+      SkuFound = FALSE;
+      break;
+  }
+#ifdef CFL_SIMICS
+  CpuType = EnumCpuTrad;
+#else
+  if (!SkuFound) {
+    DEBUG ((DEBUG_ERROR, "Unsupported CPU SKU, Device ID: 0x%02X, CPUID: 0x%08X!\n", CpuDid, CpuFamilyModel));
+    ASSERT (FALSE);
+  }
+#endif
+
+  return CpuType;
+}
+
+/**
+  Returns the processor microcode revision of the processor installed in the system.
+
+  @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+  VOID
+  )
+{
+  AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
+  return (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+/**
+  Verify the DWORD type checksum
+
+  @param[in] ChecksumAddr  - The start address to be checkumed
+  @param[in] ChecksumLen   - The length of data to be checksumed
+
+  @retval EFI_SUCCESS           - Checksum correct
+  @retval EFI_CRC_ERROR         - Checksum incorrect
+**/
+EFI_STATUS
+Checksum32Verify (
+  IN UINT32 *ChecksumAddr,
+  IN UINT32 ChecksumLen
+  )
+{
+#if SKIP_MICROCODE_CHECKSUM_CHECK
+  return EFI_SUCCESS;
+#else
+  UINT32 Checksum;
+  UINT32 Index;
+
+  Checksum = 0;
+
+  for (Index = 0; Index < ChecksumLen; Index++) {
+    Checksum += ChecksumAddr[Index];
+  }
+
+  return (Checksum == 0) ? EFI_SUCCESS : EFI_CRC_ERROR;
+#endif
+}
+
+/**
+  This function checks the MCU revision to decide if BIOS needs to load
+  microcode.
+
+  @param[in] MicrocodePointer - Microcode in memory
+  @param[in] Revision         - Current CPU microcode revision
+
+  @retval EFI_SUCCESS - BIOS needs to load microcode
+  @retval EFI_ABORTED - Don't need to update microcode
+**/
+EFI_STATUS
+CheckMcuRevision (
+  IN CPU_MICROCODE_HEADER *MicrocodePointer,
+  IN UINT32               Revision
+  )
+{
+  EFI_STATUS Status;
+  Status = EFI_ABORTED;
+
+  if ((MicrocodePointer->UpdateRevision & 0x80000000) ||
+      (MicrocodePointer->UpdateRevision > Revision) ||
+      (Revision == 0)) {
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+/**
+  Check if this microcode is correct one for processor
+
+  @param[in] Cpuid               - processor CPUID
+  @param[in] MicrocodeEntryPoint - entry point of microcode
+  @param[in] Revision            - revision of microcode
+
+  @retval CorrectMicrocode if this microcode is correct
+**/
+BOOLEAN
+CheckMicrocode (
+  IN UINT32               Cpuid,
+  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+  IN UINT32               *Revision
+  )
+{
+  EFI_STATUS                          Status;
+  UINT8                               ExtendedIndex;
+  MSR_IA32_PLATFORM_ID_REGISTER       Msr;
+  UINT32                              ExtendedTableLength;
+  UINT32                              ExtendedTableCount;
+  BOOLEAN                             CorrectMicrocode;
+  CPU_MICROCODE_EXTENDED_TABLE        *ExtendedTable;
+  CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+
+  Status              = EFI_NOT_FOUND;
+  ExtendedTableLength = 0;
+  CorrectMicrocode    = FALSE;
+
+  if (MicrocodeEntryPoint == NULL) {
+    return FALSE;
+  }
+
+  Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+
+  ///
+  /// Check if the microcode is for the Cpu and the version is newer
+  /// and the update can be processed on the platform
+  ///
+  if ((MicrocodeEntryPoint->HeaderVersion == 0x00000001) &&
+      !EFI_ERROR (CheckMcuRevision (MicrocodeEntryPoint, *Revision))
+      ) {
+    if ((MicrocodeEntryPoint->ProcessorId == Cpuid) && (MicrocodeEntryPoint->ProcessorFlags & (1 << (UINT8) Msr.Bits.PlatformId))) {
+      if (MicrocodeEntryPoint->DataSize == 0) {
+        Status = Checksum32Verify ((UINT32 *) MicrocodeEntryPoint, 2048 / sizeof (UINT32));
+      } else {
+        Status = Checksum32Verify (
+                   (UINT32 *) MicrocodeEntryPoint,
+                   (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)) / sizeof (UINT32)
+                   );
+      }
+
+      if (!EFI_ERROR (Status)) {
+        CorrectMicrocode = TRUE;
+      }
+    } else if ((MicrocodeEntryPoint->DataSize != 0)) {
+      ///
+      /// Check the  Extended Signature if the entended signature exist
+      /// Only the data size != 0 the extended signature may exist
+      ///
+      ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
+      if (ExtendedTableLength != 0) {
+        ///
+        /// Extended Table exist, check if the CPU in support list
+        ///
+        ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + 48);
+        ///
+        /// Calulate Extended Checksum
+        ///
+        if ((ExtendedTableLength % 4) == 0) {
+          Status = Checksum32Verify ((UINT32 *) ExtendedTableHeader, ExtendedTableLength / sizeof (UINT32));
+          if (!EFI_ERROR (Status)) {
+            ///
+            /// Checksum correct
+            ///
+            ExtendedTableCount  = ExtendedTableHeader->ExtendedSignatureCount;
+            ExtendedTable       = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
+            for (ExtendedIndex = 0; ExtendedIndex < ExtendedTableCount; ExtendedIndex++) {
+              ///
+              /// Verify Header
+              ///
+              if ((ExtendedTable->ProcessorSignature == Cpuid) && (ExtendedTable->ProcessorFlag & (1 << (UINT8) Msr.Bits.PlatformId))) {
+                Status = Checksum32Verify (
+                           (UINT32 *) ExtendedTable,
+                           sizeof (CPU_MICROCODE_EXTENDED_TABLE) / sizeof (UINT32)
+                           );
+                if (!EFI_ERROR (Status)) {
+                  ///
+                  /// Find one
+                  ///
+                  CorrectMicrocode = TRUE;
+                  break;
+                }
+              }
+
+              ExtendedTable++;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return CorrectMicrocode;
+}
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval TRUE  if SGX supported
+  @retval FALSE if SGX is not supported
+**/
+BOOLEAN
+IsSgxSupported (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER CpuidRegs;
+
+  //
+  // Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
+  //
+  AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.RegEdx);
+
+  ///
+  /// SGX feature is supported with CPUID.(EAX=7,ECX=0):EBX[2]=1
+  /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
+  ///
+  if (((CpuidRegs.RegEbx & BIT2)) && (AsmReadMsr64 (MSR_IA32_MTRRCAP) & BIT12)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Get processor generation
+
+  @retval CPU_GENERATION  Returns the executing thread's processor generation.
+**/
+CPU_GENERATION
+GetCpuGeneration (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER Cpuid;
+  CPU_FAMILY         CpuFamilyModel;
+  CPU_GENERATION     CpuGeneration;
+
+  CpuGeneration = EnumCflCpu;
+  ///
+  /// Read the CPUID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  CpuFamilyModel = (CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL);
+
+  switch (CpuFamilyModel) {
+    case EnumCpuCflUltUlx:
+    case EnumCpuCflDtHalo:
+      CpuGeneration = EnumCflCpu;
+      break;
+
+    default:
+      CpuGeneration = EnumCpuUnknownGeneration;
+      ASSERT (FALSE);
+      break;
+  }
+
+  return CpuGeneration;
+}
+
+/**
+  Is Whiskey Lake CPU.
+
+  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
+  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
+**/
+BOOLEAN
+IsWhlCpu (
+  VOID
+  )
+{
+  CPU_FAMILY    CpuFamily;
+  CPU_STEPPING  CpuStepping;
+
+  CpuFamily   = GetCpuFamily ();
+  CpuStepping = GetCpuStepping ();
+
+  //
+  // Check if it is Whiskey Lake CPU
+  //
+  if ((CpuFamily == EnumCpuCflUltUlx) && ((CpuStepping == EnumCflW0) || (CpuStepping == EnumCflV0))) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: Add library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (14 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
                   ` (21 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds ME library class instances.

* PeiMePolicyLib - PEI ME policy configuration services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf   |  44 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h |  25 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c     | 251 ++++++++++++++++++++
 3 files changed, 320 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf
new file mode 100644
index 0000000000..85a227f950
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for the PeiMePolicyLib libbrary.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiMePolicyLib
+FILE_GUID = 2655FA94-4559-F393-B0B1-85A8E79C1532
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiMePolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiMePolicyLib.c
+PeiMePolicyLibrary.h
+
+
+[Ppis]
+gSiPolicyPpiGuid       ## PRODUCES
+gSiPreMemPolicyPpiGuid ## PRODUCES
+
+
+[Guids]
+gMePeiPreMemConfigGuid
+gMePeiConfigGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h
new file mode 100644
index 0000000000..3ac6a639e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h
@@ -0,0 +1,25 @@
+/** @file
+  Header file for the PeiMePolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_ME_POLICY_LIBRARY_H_
+#define _PEI_ME_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiMePolicyLib.h>
+#include <ConfigBlock.h>
+#include <ConfigBlock/MePeiConfig.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <MkhiMsgs.h>
+
+#endif // _PEI_ME_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c
new file mode 100644
index 0000000000..6f3d70b841
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c
@@ -0,0 +1,251 @@
+/** @file
+  This file is PeiMePolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiMePolicyLibrary.h"
+
+/**
+  Load default settings for ME config block in pre-mem phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiPreMemDefault (
+  IN VOID                           *ConfigBlockPointer
+  );
+
+/**
+  Load default settings for ME config block in PEI phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiDefault (
+  IN VOID                           *ConfigBlockPointer
+  );
+
+STATIC COMPONENT_BLOCK_ENTRY  mMeCompontBlockPreMemBlocks [] = {
+  {&gMePeiPreMemConfigGuid, sizeof (ME_PEI_PREMEM_CONFIG),  ME_PEI_PREMEM_CONFIG_REVISION,  LoadMePeiPreMemDefault}
+};
+
+STATIC COMPONENT_BLOCK_ENTRY  mMeCompontBlockBlocks [] = {
+  {&gMePeiConfigGuid,       sizeof (ME_PEI_CONFIG),         ME_PEI_CONFIG_REVISION,         LoadMePeiDefault}
+};
+
+/**
+  Load default settings for ME config block in pre-mem phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiPreMemDefault (
+  IN VOID                           *ConfigBlockPointer
+  )
+{
+  ME_PEI_PREMEM_CONFIG *MePeiPreMemConfig;
+  MePeiPreMemConfig = ConfigBlockPointer;
+
+  MePeiPreMemConfig->HeciTimeouts                  = 1;
+
+  MePeiPreMemConfig->Heci1BarAddress               = 0xFED1A000;
+  MePeiPreMemConfig->Heci2BarAddress               = 0xFED1B000;
+  MePeiPreMemConfig->Heci3BarAddress               = 0xFED1C000;
+
+  //
+  // Test policies
+  //
+  MePeiPreMemConfig->SendDidMsg                    = 1;
+
+  MePeiPreMemConfig->KtDeviceEnable                = 1;
+}
+
+/**
+  Load default settings for ME config block in PEI phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiDefault (
+  IN VOID                           *ConfigBlockPointer
+  )
+{
+  ME_PEI_CONFIG *MePeiConfig;
+  MePeiConfig = ConfigBlockPointer;
+
+  MePeiConfig->EndOfPostMessage     = EOP_SEND_IN_DXE;
+  MePeiConfig->MeUnconfigOnRtcClear = 1;
+}
+
+/**
+  Dump values of ME config block in pre-mem phase.
+
+  @param[in] MePeiPreMemConfig                     The pointer to the config block
+**/
+VOID
+EFIAPI
+PrintMePeiPreMemConfig (
+  IN ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "------------------------ ME_PEI_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision                  : 0x%x\n", MePeiPreMemConfig->Header.Revision));
+  ASSERT (MePeiPreMemConfig->Header.Revision == ME_PEI_PREMEM_CONFIG_REVISION);
+
+  DEBUG ((DEBUG_INFO, " HeciTimeouts              : 0x%x\n", MePeiPreMemConfig->HeciTimeouts));
+  DEBUG ((DEBUG_INFO, " DidInitStat               : 0x%x\n", MePeiPreMemConfig->DidInitStat));
+  DEBUG ((DEBUG_INFO, " DisableCpuReplacedPolling : 0x%x\n", MePeiPreMemConfig->DisableCpuReplacedPolling));
+  DEBUG ((DEBUG_INFO, " SendDidMsg                : 0x%x\n", MePeiPreMemConfig->SendDidMsg));
+  DEBUG ((DEBUG_INFO, " DisableHeciRetry          : 0x%x\n", MePeiPreMemConfig->DisableHeciRetry));
+  DEBUG ((DEBUG_INFO, " DisableMessageCheck       : 0x%x\n", MePeiPreMemConfig->DisableMessageCheck));
+  DEBUG ((DEBUG_INFO, " SkipMbpHob                : 0x%x\n", MePeiPreMemConfig->SkipMbpHob));
+  DEBUG ((DEBUG_INFO, " HeciCommunication2        : 0x%x\n", MePeiPreMemConfig->HeciCommunication2));
+  DEBUG ((DEBUG_INFO, " KtDeviceEnable            : 0x%x\n", MePeiPreMemConfig->KtDeviceEnable));
+  DEBUG ((DEBUG_INFO, " Heci1BarAddress           : 0x%x\n", MePeiPreMemConfig->Heci1BarAddress));
+  DEBUG ((DEBUG_INFO, " Heci2BarAddress           : 0x%x\n", MePeiPreMemConfig->Heci2BarAddress));
+  DEBUG ((DEBUG_INFO, " Heci3BarAddress           : 0x%x\n", MePeiPreMemConfig->Heci3BarAddress));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Dump values of ME config block in PEI phase.
+
+  @param[in] MePeiConfig                    The pointer to the config block
+**/
+VOID
+EFIAPI
+PrintMePeiConfig (
+  IN ME_PEI_CONFIG              *MePeiConfig
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "------------------------ ME_PEI_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision                  : 0x%x\n", MePeiConfig->Header.Revision));
+  ASSERT (MePeiConfig->Header.Revision == ME_PEI_CONFIG_REVISION);
+
+  DEBUG ((DEBUG_INFO, " MctpBroadcastCycle        : 0x%x\n", MePeiConfig->MctpBroadcastCycle));
+  DEBUG ((DEBUG_INFO, " EndOfPostMessage          : 0x%x\n", MePeiConfig->EndOfPostMessage));
+  DEBUG ((DEBUG_INFO, " Heci3Enabled              : 0x%x\n", MePeiConfig->Heci3Enabled));
+  DEBUG ((DEBUG_INFO, " DisableD0I3SettingForHeci : 0x%x\n", MePeiConfig->DisableD0I3SettingForHeci));
+  DEBUG ((DEBUG_INFO, " MeUnconfigOnRtcClear      : 0x%x\n", MePeiConfig->MeUnconfigOnRtcClear));
+
+  DEBUG_CODE_END ();
+}
+
+/**
+  Print PEI ME config block
+
+  @param[in] SiPolicyPpiPreMem The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPpiPreMem
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                        Status;
+  ME_PEI_PREMEM_CONFIG              *MePeiPreMemConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpiPreMem, &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Pre-Mem Print Begin -----------------\n"));
+  PrintMePeiPreMemConfig (MePeiPreMemConfig);
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Pre-Mem Print End -------------------\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Print PEI ME config block
+
+  @param[in] SiPolicyPpi The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpi (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                        Status;
+  ME_PEI_CONFIG                     *MePeiConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Print Begin -----------------\n"));
+  PrintMePeiConfig (MePeiConfig);
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Print End -------------------\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Get ME config block table total size.
+
+  @retval        Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSizePreMem (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mMeCompontBlockPreMemBlocks[0], sizeof (mMeCompontBlockPreMemBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  Get ME config block table total size.
+
+  @retval        Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mMeCompontBlockBlocks[0], sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  MeAddConfigBlocksPreMem add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "Me AddConfigBlocks. TotalBlockCount = 0x%x\n",  sizeof (mMeCompontBlockPreMemBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mMeCompontBlockPreMemBlocks[0], sizeof (mMeCompontBlockPreMemBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  MeAddConfigBlocks add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "ME AddConfigBlocks. TotalBlockCount = 0x%x\n",  sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mMeCompontBlockBlocks[0], sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (15 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
                   ` (20 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH Base library class instances.

* BaseResetSystemLib
* BaseSmbusLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf |  38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf             |  39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c   | 153 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c               | 993 ++++++++++++++++++++
 4 files changed, 1223 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
new file mode 100644
index 0000000000..8d68f2dd83
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 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
+DebugLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseResetSystemLib.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
new file mode 100644
index 0000000000..f3388a2624
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for PCH Smbus Library.
+#
+# SMBUS Library that layers on top of the I/O Library to directly
+# access a standard SMBUS host controller.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSmbusLib
+FILE_GUID = 5C4D0430-F81B-42D3-BB88-4A6CD2796FF8
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SmbusLib
+CONSTRUCTOR = BaseSmbusLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+BaseLib
+DebugLib
+IoLib
+PciSegmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+BaseSmbusLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
new file mode 100644
index 0000000000..a603f5e794
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
@@ -0,0 +1,153 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 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 <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.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
+  )
+{
+  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/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c
new file mode 100644
index 0000000000..3d6386d433
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c
@@ -0,0 +1,993 @@
+/** @file
+  PCH SMBUS library implementation built upon I/O library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/SmbusLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSmbus.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mSmbusIoBase = 0;
+
+/**
+  Gets Io port base address of Smbus Host Controller.
+
+  @retval The Io port base address of Smbus host controller.
+
+**/
+UINT16
+InternalGetSmbusIoPortBaseAddress (
+  VOID
+  )
+{
+  UINT64    SmbusPciBase;
+  UINT16    IoPortBaseAddress;
+
+  if (mSmbusIoBase != 0) {
+    return mSmbusIoBase;
+  }
+
+  SmbusPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                   0
+                   );
+  IoPortBaseAddress = (UINT16) PciSegmentRead32 (SmbusPciBase + R_SMBUS_CFG_BASE);
+
+  //
+  // Make sure that the IO port base address has been properly set.
+  //
+  if ((IoPortBaseAddress == 0) || (IoPortBaseAddress == 0xFFFF)) {
+    ASSERT (FALSE);
+    return 0;
+  }
+
+  IoPortBaseAddress &= B_SMBUS_CFG_BASE_BAR;
+  mSmbusIoBase = IoPortBaseAddress;
+
+  return IoPortBaseAddress;
+}
+
+
+/**
+  Acquires the ownership of SMBUS.
+
+  This internal function reads the host state register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;
+  Otherwise, it performs some basic initializations and returns
+  RETURN_SUCCESS.
+
+  @param[in]  IoPortBaseAddress The Io port base address of Smbus Host controller.
+
+  @retval     RETURN_SUCCESS    The SMBUS command was executed successfully.
+  @retval     RETURN_TIMEOUT    A timeout occurred while executing the SMBUS command.
+
+**/
+RETURN_STATUS
+InternalSmBusAcquire (
+  IN UINT16                   IoPortBaseAddress
+  )
+{
+  UINT8   HostStatus;
+
+  HostStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);
+  if ((HostStatus & B_SMBUS_IO_IUS) != 0) {
+    return RETURN_TIMEOUT;
+  } else if ((HostStatus & B_SMBUS_IO_HBSY) != 0) {
+    //
+    // Clear host status register and exit.
+    //
+    IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_HSTS_ALL);
+    return RETURN_TIMEOUT;
+  }
+  //
+  // Clear out any odd status information (Will Not Clear In Use).
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, HostStatus);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Starts the SMBUS transaction and waits until the end.
+
+  This internal function start the SMBUS transaction and waits until the transaction
+  of SMBUS is over by polling the INTR bit of Host status register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;
+  Otherwise, it performs some basic initializations and returns
+  RETURN_SUCCESS.
+
+  @param[in]  IoPortBaseAddress   The Io port base address of Smbus Host controller.
+  @param[in]  HostControl         The Host control command to start SMBUS transaction.
+
+  @retval     RETURN_SUCCESS      The SMBUS command was executed successfully.
+  @retval     RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).
+  @retval     RETURN_DEVICE_ERROR The request was not completed because a failure reflected
+                                  in the Host Status Register bit.  Device errors are
+                                  a result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+
+**/
+RETURN_STATUS
+InternalSmBusStart (
+  IN  UINT16                  IoPortBaseAddress,
+  IN  UINT8                   HostControl
+  )
+{
+  UINT8   HostStatus;
+  UINT8   AuxiliaryStatus;
+
+  //
+  // Set Host Control Register (Initiate Operation, Interrupt disabled).
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCTL, (UINT8)(HostControl + B_SMBUS_IO_START));
+
+  do {
+    //
+    // Poll INTR bit of Host Status Register.
+    //
+    HostStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);
+  } while ((HostStatus & (B_SMBUS_IO_INTR | B_SMBUS_IO_ERROR | B_SMBUS_IO_BYTE_DONE_STS)) == 0);
+
+  if ((HostStatus & B_SMBUS_IO_ERROR) == 0) {
+    return RETURN_SUCCESS;
+  }
+  //
+  // Clear error bits of Host Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_ERROR);
+  //
+  // Read Auxiliary Status Register to judge CRC error.
+  //
+  AuxiliaryStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_AUXS);
+  if ((AuxiliaryStatus & B_SMBUS_IO_CRCE) != 0) {
+    return RETURN_CRC_ERROR;
+  }
+
+  return RETURN_DEVICE_ERROR;
+}
+
+/**
+  Executes an SMBUS quick, byte or word command.
+
+  This internal function executes an SMBUS quick, byte or word commond.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+
+  @param[in]  HostControl     The value of Host Control Register to set.
+  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                              SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value           The byte/word write to the SMBUS.
+  @param[out] Status          Return status for the executed command.
+                              This is an optional parameter and may be NULL.
+
+  @retval The byte/word read from the SMBUS.
+
+**/
+UINT16
+InternalSmBusNonBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT16                    Value,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINT16                        IoPortBaseAddress;
+  UINT8                         AuxiliaryControl;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  //
+  // Try to acquire the ownership of SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+  //
+  // Set the appropriate Host Control Register and auxiliary Control Register.
+  //
+  AuxiliaryControl = 0;
+  if (SMBUS_LIB_PEC (SmBusAddress)) {
+    AuxiliaryControl |= B_SMBUS_IO_AAC;
+  }
+  //
+  // Set Host Commond Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));
+  //
+  // Write value to Host Data 0 and Host Data 1 Registers.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) Value);
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD1, (UINT8) (Value >> 8));
+  //
+  // Set Auxiliary Control Regiester.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl);
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress);
+  //
+  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
+  //
+  // Read value from Host Data 0 and Host Data 1 Registers.
+  //
+  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD1) << 8);
+  Value = (UINT16)(Value | IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD0));
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_HSTS_ALL);
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE);
+
+Done:
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return Value;
+}
+
+/**
+  Executes an SMBUS quick read command.
+
+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickRead (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if (SMBUS_LIB_PEC (SmBusAddress)           ||
+    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return;
+  }
+
+  InternalSmBusNonBlock (
+    V_SMBUS_IO_SMB_CMD_QUICK,
+    SmBusAddress | B_SMBUS_IO_READ,
+    0,
+    Status
+    );
+}
+
+/**
+  Executes an SMBUS quick write command.
+
+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickWrite (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if (SMBUS_LIB_PEC (SmBusAddress)           ||
+    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return;
+  }
+
+  InternalSmBusNonBlock (
+    V_SMBUS_IO_SMB_CMD_QUICK,
+    SmBusAddress | B_SMBUS_IO_WRITE,
+    0,
+    Status
+    );
+}
+
+/**
+  Executes an SMBUS receive byte command.
+
+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  The byte received from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The byte received from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReceiveByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE,
+                   SmBusAddress | B_SMBUS_IO_READ,
+                   0,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS send byte command.
+
+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
+  The byte specified by Value is sent.
+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 8-bit value to send.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusSendByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE,
+                   SmBusAddress | B_SMBUS_IO_WRITE,
+                   Value,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS read data byte command.
+
+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 8-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                              SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status          Return status for the executed command.
+                              This is an optional parameter and may be NULL.
+
+  @retval The byte read from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReadDataByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE_DATA,
+                   SmBusAddress | B_SMBUS_IO_READ,
+                   0,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS write data byte command.
+
+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
+  The 8-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 8-bit value to write.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusWriteDataByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE_DATA,
+                   SmBusAddress | B_SMBUS_IO_WRITE,
+                   Value,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS read data word command.
+
+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The byte read from the SMBUS.
+
+**/
+UINT16
+EFIAPI
+SmBusReadDataWord (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusNonBlock (
+           V_SMBUS_IO_SMB_CMD_WORD_DATA,
+           SmBusAddress | B_SMBUS_IO_READ,
+           0,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS write data word command.
+
+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 16-bit value to write.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+SmBusWriteDataWord (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusNonBlock (
+           V_SMBUS_IO_SMB_CMD_WORD_DATA,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           Value,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS process call command.
+
+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value returned by the process call command is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 16-bit value to write.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The 16-bit value returned by the process call command.
+
+**/
+UINT16
+EFIAPI
+SmBusProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusNonBlock (
+           V_SMBUS_IO_SMB_CMD_PROCESS_CALL,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           Value,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS block command.
+
+  Executes an SMBUS block read, block write and block write-block read command
+  on the SMBUS device specified by SmBusAddress.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+
+  @param[in]  HostControl     The value of Host Control Register to set.
+  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                              SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.
+  @param[out] ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.
+  @param[out] Status          Return status for the executed command.
+                              This is an optional parameter and may be NULL.
+
+  @retval The number of bytes read from the SMBUS.
+
+**/
+UINTN
+InternalSmBusBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT8                     *WriteBuffer,
+  OUT UINT8                     *ReadBuffer,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINTN                         Index;
+  UINTN                         BytesCount;
+  UINT16                        IoPortBaseAddress;
+  UINT8                         AuxiliaryControl;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
+
+  //
+  // Try to acquire the ownership of SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+  //
+  // Set the appropriate Host Control Register and auxiliary Control Register.
+  //
+  AuxiliaryControl = B_SMBUS_IO_E32B;
+  if (SMBUS_LIB_PEC (SmBusAddress)) {
+    AuxiliaryControl |= B_SMBUS_IO_AAC;
+  }
+  //
+  // Set Host Command Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));
+  //
+  // Set Auxiliary Control Regiester.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl);
+  //
+  // Clear byte pointer of 32-byte buffer.
+  //
+  IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HCTL);
+
+  if (WriteBuffer != NULL) {
+    //
+    // Write the number of block to Host Block Data Byte Register.
+    //
+    IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) BytesCount);
+    //
+    // Write data block to Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HBD, WriteBuffer[Index]);
+    }
+  }
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress);
+  //
+  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
+  if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  if (ReadBuffer != NULL) {
+    //
+    // Read the number of block from host block data byte register.
+    //
+    BytesCount = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD0);
+    //
+    // Write data block from Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      ReadBuffer[Index] = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HBD);
+    }
+  }
+
+Done:
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_HSTS_ALL);
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE);
+
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return BytesCount;
+}
+
+/**
+  Executes an SMBUS read block command.
+
+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Buffer        Pointer to the buffer to store the bytes read from the SMBUS.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The number of bytes read.
+
+**/
+UINTN
+EFIAPI
+SmBusReadBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((Buffer == NULL)                         ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusBlock (
+           V_SMBUS_IO_SMB_CMD_BLOCK,
+           SmBusAddress | B_SMBUS_IO_READ,
+           NULL,
+           Buffer,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS write block command.
+
+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from Buffer.
+  The number of bytes written is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Buffer        Pointer to the buffer to store the bytes read from the SMBUS.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusWriteBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((Buffer == NULL)                         ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusBlock (
+           V_SMBUS_IO_SMB_CMD_BLOCK,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           Buffer,
+           NULL,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS block process call command.
+
+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If WriteBuffer is NULL, then ASSERT().
+  If ReadBuffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  WriteBuffer   Pointer to the buffer of bytes to write to the SMBUS.
+  @param[out] ReadBuffer    Pointer to the buffer of bytes to read from the SMBUS.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusBlockProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  VOID           *WriteBuffer,
+  OUT VOID           *ReadBuffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (WriteBuffer != NULL);
+  ASSERT (ReadBuffer  != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((WriteBuffer == NULL)                    ||
+      (ReadBuffer  == NULL)                    ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))
+  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusBlock (
+           V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           WriteBuffer,
+           ReadBuffer,
+           Status
+           );
+}
+
+/**
+  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.
+**/
+RETURN_STATUS
+EFIAPI
+BaseSmbusLibConstructor (
+  VOID
+  )
+{
+  UINT64    SmbusPciBase;
+  UINT16    IoPortBaseAddress;
+
+  //
+  // Init mSmbusIoBase variable.
+  //
+  SmbusPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                   0
+                   );
+  IoPortBaseAddress = (UINT16) PciSegmentRead32 (SmbusPciBase + R_SMBUS_CFG_BASE);
+
+  if ((IoPortBaseAddress != 0) && (IoPortBaseAddress != 0xFFFF)) {
+    mSmbusIoBase = IoPortBaseAddress & B_SMBUS_CFG_BASE_BAR;
+  }
+
+  return RETURN_SUCCESS;
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (16 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
                   ` (19 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH DXE library class instances.

* DxePchPolicyLib
* DxeResetSystemLib
* DxeRuntimeResetSystemLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf                   |  41 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf               |  49 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf |  52 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c                     | 218 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c                 | 310 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c   | 323 ++++++++++++++++++++
 6 files changed, 993 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
new file mode 100644
index 0000000000..8845ab796c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Component description file for the PeiPchPolicy library.
+#
+# Copyright (c) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxePchPolicyLib.c
+
+
+[Guids]
+gHdAudioDxeConfigGuid
+gGpioDxeConfigGuid
+
+[Protocols]
+gPchPolicyProtocolGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf
new file mode 100644
index 0000000000..0bb2d6e247
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeResetSystemLib
+FILE_GUID = 239383BC-499E-4DC5-8CDC-F85AF27B1BC4
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+CONSTRUCTOR = DxeResetSystemLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+TimerLib
+BaseMemoryLib
+UefiBootServicesTableLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeResetSystemLib.c
+
+
+[Protocols]
+gPchResetCallbackProtocolGuid ## CONSUMES
+
+
+[Guids]
+gPchGlobalResetGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
new file mode 100644
index 0000000000..a1777293ab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
@@ -0,0 +1,52 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeRuntimeResetSystemLib
+FILE_GUID = 1026813A-E46F-43D1-B709-FF1F996F2E72
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_RUNTIME_DRIVER
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+CONSTRUCTOR = DxeRuntimeResetSystemLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+TimerLib
+BaseMemoryLib
+UefiRuntimeLib
+DxeServicesTableLib
+UefiBootServicesTableLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeRuntimeResetSystemLib.c
+
+
+[Protocols]
+gPchResetCallbackProtocolGuid ## CONSUMES
+
+
+[Guids]
+gPchGlobalResetGuid
+gEfiEventVirtualAddressChangeGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
new file mode 100644
index 0000000000..62c8a91eb9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
@@ -0,0 +1,218 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+  Copyright (c) 2019 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 <ConfigBlock/HdAudioConfig.h>
+#include <ConfigBlock/GpioDevConfig.h>
+
+/**
+  Load DXE Config block default for HD Audio
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHdAudioDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_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));
+
+  HdAudioDxeConfig->DspEndpointDmic = PchHdaDmic4chArray;
+  HdAudioDxeConfig->NhltDefaultFlow = TRUE;
+}
+
+/**
+  Load DXE Config block default for GPIO
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadGpioDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_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;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchDxeIpBlocks [] = {
+  {&gHdAudioDxeConfigGuid, sizeof (PCH_HDAUDIO_DXE_CONFIG), HDAUDIO_DXE_CONFIG_REVISION, LoadHdAudioDxeConfigDefault},
+  {&gGpioDxeConfigGuid, sizeof (PCH_GPIO_DXE_CONFIG), GPIO_DXE_CONFIG_REVISION, LoadGpioDxeConfigDefault}
+};
+
+/**
+  Print PCH_HDAUDIO_DXE_CONFIG.
+
+  @param[in] HdaDxeConfig         Pointer to a PCH_HDAUDIO_DXE_CONFIG that provides the HD Audio settings
+**/
+VOID
+PchPrintHdAudioDxeConfig (
+  IN CONST PCH_HDAUDIO_DXE_CONFIG   *HdaDxeConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio DXE Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " DSP Endpoint: DMIC : %d\n", HdaDxeConfig->DspEndpointDmic));
+  DEBUG ((DEBUG_INFO, " DSP Endpoint: I2S  : %d\n", HdaDxeConfig->DspEndpointI2s));
+  DEBUG ((DEBUG_INFO, " DSP Endpoint: BT   : %d\n", HdaDxeConfig->DspEndpointBluetooth));
+  DEBUG ((DEBUG_INFO, " DSP Feature Mask   : 0x%x\n", HdaDxeConfig->DspFeatureMask));
+  DEBUG ((DEBUG_INFO, " Nhlt Default Flow  : %d\n", HdaDxeConfig->NhltDefaultFlow));
+}
+
+/**
+  Print PCH_GPIO_DXE_CONFIG.
+
+  @param[in] GpioDxeConfig         Pointer to a PCH_GPIO_DXE_CONFIG that provides the GPIO settings
+**/
+VOID
+PchPrintGpioDxeConfig (
+  IN CONST PCH_GPIO_DXE_CONFIG   *GpioDxeConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH GPIO DXE Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n", GpioDxeConfig->HideGpioAcpiDevice));
+}
+
+/**
+  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;
+  PCH_HDAUDIO_DXE_CONFIG     *HdaDxeConfig;
+  PCH_GPIO_DXE_CONFIG        *GpioDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdaDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (VOID *)&GpioDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %x\n", PchPolicy->TableHeader.Header.Revision));
+
+  PchPrintHdAudioDxeConfig (HdaDxeConfig);
+  PchPrintGpioDxeConfig (GpioDxeConfig);
+
+  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));
+
+  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);
+
+  //
+  // 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/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c
new file mode 100644
index 0000000000..fd3c280605
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c
@@ -0,0 +1,310 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Protocol/PchReset.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32           mDxeResetSystemPwrmBase;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mDxeResetSystemABase;
+
+/**
+  Dump reset message for debug build readability
+**/
+VOID
+DumpResetMessage (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINTN       Index;
+  //
+  // ******************************
+  // **    SYSTEM REBOOT !!!     **
+  // ******************************
+  //
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+**/
+VOID
+EFIAPI
+PchResetCallback (
+  IN  EFI_RESET_TYPE          ResetType,
+  IN  EFI_GUID                *ResetTypeGuid
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       NumHandles;
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       Index;
+  PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
+
+  ///
+  /// Retrieve all instances of Pch Reset Callback protocol
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gPchResetCallbackProtocolGuid,
+                  NULL,
+                  &NumHandles,
+                  &HandleBuffer
+                  );
+
+  if (EFI_ERROR (Status)) {
+    ///
+    /// Those drivers that need to install Pch Reset Callback protocol have the responsibility
+    /// to make sure themselves execute before Pch Reset Runtime driver.
+    ///
+    if (Status == EFI_NOT_FOUND) {
+      DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback protocol is installed.\n"));
+    }
+    return;
+  }
+
+  for (Index = 0; Index < NumHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gPchResetCallbackProtocolGuid,
+                    (VOID **) &PchResetCallback
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    if (!EFI_ERROR (Status)) {
+      PchResetCallback->ResetCallback (ResetType, ResetTypeGuid);
+    }
+  }
+}
+
+/**
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetCold, NULL);
+
+  DumpResetMessage ();
+
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetWarm, NULL);
+
+  DumpResetMessage ();
+  //
+  // In case there are pending capsules to process, need to flush the cache.
+  //
+  AsmWbinvd ();
+
+  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
+  )
+{
+  UINT32         Data32;
+
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetShutdown, NULL);
+
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+  ///
+  IoWrite32 (mDxeResetSystemABase + 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 (mDxeResetSystemABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state
+  ///
+  Data32 = IoRead32 (mDxeResetSystemABase + 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 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  DumpResetMessage ();
+
+  IoWrite32 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  return;
+}
+
+/**
+  Internal function to execute the required HECI command for GlobalReset,
+  if failed will use PCH Reest.
+
+**/
+STATIC
+VOID
+PchGlobalReset (
+  VOID
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
+
+  //
+  // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
+  //
+  MmioOr32 (
+    mDxeResetSystemPwrmBase + R_PMC_PWRM_ETR3,
+    (UINT32) B_PMC_PWRM_ETR3_CF9GR
+    );
+
+  DumpResetMessage ();
+
+  //
+  // ME Global Reset should fail after EOP is sent. Go to use PCH Reset.
+  //
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
+}
+
+/**
+  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
+  )
+{
+  EFI_GUID            *GuidPtr;
+
+  if (ResetData == NULL) {
+    DEBUG ((DEBUG_ERROR, "[DxeResetSystemLib] ResetData is not available.\n"));
+    return;
+  }
+  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID));
+  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
+    PchGlobalReset();
+  } else {
+    return;
+  }
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library DXE instance.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+**/
+EFI_STATUS
+EFIAPI
+DxeResetSystemLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  mDxeResetSystemABase    = PmcGetAcpiBase ();
+  mDxeResetSystemPwrmBase = PmcGetPwrmBase ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c
new file mode 100644
index 0000000000..a39e171804
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c
@@ -0,0 +1,323 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Protocol/PchReset.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32           mDxeRuntimeResetSystemPwrmBase;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mDxeRuntimeResetSystemABase;
+
+/**
+  Dump reset message for debug build readability
+**/
+VOID
+DumpResetMessage (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINTN       Index;
+  //
+  // ******************************
+  // **    SYSTEM REBOOT !!!     **
+  // ******************************
+  //
+  if (!EfiAtRuntime ()) {
+    for (Index = 0; Index < 30; Index++) {
+      DEBUG ((DEBUG_INFO, "*"));
+    }
+    DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
+    for (Index = 0; Index < 30; Index++) {
+      DEBUG ((DEBUG_INFO, "*"));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  DEBUG_CODE_END ();
+}
+
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+**/
+VOID
+EFIAPI
+PchResetCallback (
+  IN  EFI_RESET_TYPE          ResetType,
+  IN  EFI_GUID                *ResetTypeGuid
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       NumHandles;
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       Index;
+  PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
+
+  if (!EfiAtRuntime ()) {
+    ///
+    /// Retrieve all instances of Pch Reset Callback protocol
+    ///
+    Status = gBS->LocateHandleBuffer (
+                    ByProtocol,
+                    &gPchResetCallbackProtocolGuid,
+                    NULL,
+                    &NumHandles,
+                    &HandleBuffer
+                    );
+    if (EFI_ERROR (Status)) {
+      ///
+      /// Those drivers that need to install Pch Reset Callback protocol have the responsibility
+      /// to make sure themselves execute before Pch Reset Runtime driver.
+      ///
+      if (Status == EFI_NOT_FOUND) {
+        DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback protocol is installed.\n"));
+      }
+      return;
+    }
+
+    for (Index = 0; Index < NumHandles; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gPchResetCallbackProtocolGuid,
+                      (VOID **) &PchResetCallback
+                      );
+      ASSERT_EFI_ERROR (Status);
+
+      if (!EFI_ERROR (Status)) {
+        PchResetCallback->ResetCallback (ResetType, ResetTypeGuid);
+      }
+    }
+  }
+}
+
+/**
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetCold, NULL);
+
+  DumpResetMessage ();
+
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetWarm, NULL);
+
+  DumpResetMessage ();
+  //
+  // In case there are pending capsules to process, need to flush the cache.
+  //
+  AsmWbinvd ();
+
+  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
+  )
+{
+  UINT32         Data32;
+
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetShutdown, NULL);
+
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+  ///
+  IoWrite32 (mDxeRuntimeResetSystemABase + 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 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state
+  ///
+  Data32 = IoRead32 (mDxeRuntimeResetSystemABase + 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 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  DumpResetMessage ();
+
+  IoWrite32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  return;
+}
+
+/**
+  Internal function to execute the required HECI command for GlobalReset,
+  if failed will use PCH Reest.
+
+**/
+STATIC
+VOID
+PchGlobalReset (
+  VOID
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
+
+  DumpResetMessage ();
+
+  //
+  // Let ME do global reset if Me Fw is available
+  //
+  if (!EfiAtRuntime ()) {
+    //
+    // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
+    //
+    MmioOr32 (
+      mDxeRuntimeResetSystemPwrmBase + R_PMC_PWRM_ETR3,
+      (UINT32) B_PMC_PWRM_ETR3_CF9GR
+      );
+  }
+
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
+}
+
+/**
+  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
+  )
+{
+  EFI_GUID            *GuidPtr;
+
+  if (ResetData == NULL) {
+    if (!EfiAtRuntime ()) {
+      DEBUG ((DEBUG_ERROR, "[DxeRuntimeResetSystemLib] ResetData is not available.\n"));
+    }
+    return;
+  }
+  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID));
+  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
+    PchGlobalReset ();
+  } else {
+    return;
+  }
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library instance.
+
+  The PMC PCI configuration and PWRM space memory ranges are converted into EFI_RUNTIME_XXX
+  in PciHostBridgeEntryPoint
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+**/
+EFI_STATUS
+EFIAPI
+DxeRuntimeResetSystemLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  mDxeRuntimeResetSystemABase    = PmcGetAcpiBase ();
+  mDxeRuntimeResetSystemPwrmBase = PmcGetPwrmBase ();
+
+  return EFI_SUCCESS;
+}
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (17 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
                   ` (18 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH PEI library class instances. These libraries may also be
compatible in other boot phases as indicated by the library type.

* PeiDxeSmmBiosLockLib
* PeiDxeSmmGpioLib
* PeiDxeSmmPchCycleDecodingLib
* PeiDxeSmmPchDmiWithS3Lib
* PeiDxeSmmPchEspiLib
* PeiDxeSmmPchGbeLib
* PeiDxeSmmPchHsioLib
* PeiDxeSmmPchInfoLib
* PeiDxeSmmPchPcieRpLib
* PeiDxeSmmPchPcrLib
* PeiDxeSmmPchPmcLib
* PeiDxeSmmPchSbiAccessLib
* PeiDxeSmmPchSerialIoLib
* PeiDxeSmmPchSerialIoUartLib
* PeiDxeSmmPchWdtCommonLib
* PeiDxeSmmPmcLib
* PeiDxeSmmSataLib
* PeiOcWdtLib
* PeiOcWdtLibNull
* PeiPchPolicyLib
* PeiPchResetLib
* PeiResetSystemLib
* PeiSpiLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf                 |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf                         |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf                   |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf                   |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf                |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf               |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf                     |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf                     |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf        |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf   |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf         |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf                           |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf                      |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf                           |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf                        |   86 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf                             |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf                       |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf                                       |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h                                |  117 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h                       |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h              |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c                            |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c                                   |  553 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c                                    | 2710 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c                                  |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c                              |  234 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c            | 1136 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c                              |  505 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c                                |   82 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c                              |  127 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c                              |  272 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c                        |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c                           |  386 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c                          |  183 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c                                |  279 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c                                |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c                    |  270 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c                      |  516 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c                   |  181 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c     |  372 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c                          |  242 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c                                      |  330 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c                                    |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c                                 |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c                                 |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c                                     |  130 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c                             |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c                        |  307 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c                              |  778 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c                             |  739 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c                          |  169 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c                       |  318 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c                                     |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c                         |  257 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c                                            |  217 ++
 60 files changed, 13130 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
new file mode 100644
index 0000000000..6db81f6cf3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
@@ -0,0 +1,40 @@
+## @file
+# BIOS LOCK library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmBiosLockLib
+FILE_GUID = 64EBA6B1-CC36-4C2E-A0F5-D90199432E6C
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = BiosLockLib
+
+
+[LibraryClasses]
+BaseLib
+DebugLib
+PcdLib
+PciSegmentLib
+S3BootScriptLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BiosLockLib.c
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
new file mode 100644
index 0000000000..00d06591fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the PeiDxeSmmGpioLib
+#
+# Copyright (c) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+GpioLib.c
+GpioLibrary.h
+GpioNativeLib.c
+GpioInit.c
+GpioNames.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
new file mode 100644
index 0000000000..2a53f42004
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/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) 2019 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
+PchEspiLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[Sources]
+PchCycleDecodingLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress          ## CONSUMES
+gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress        ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
new file mode 100644
index 0000000000..a775210984
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for the PeiDxeSmmPchEspiLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchEspiLib
+FILE_GUID = 7F25F990-7989-4413-B414-1EDE557E9389
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchEspiLib
+#
+# 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchEspiLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
new file mode 100644
index 0000000000..a685104249
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
@@ -0,0 +1,38 @@
+## @file
+# PCH Gbe Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchGbeLib
+FILE_GUID = FC022ED0-6EB3-43E1-A740-0BA27CBBD010
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchGbeLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+PchCycleDecodingLib
+PmcPrivateLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchGbeLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
new file mode 100644
index 0000000000..7c67e0fa20
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
@@ -0,0 +1,37 @@
+## @file
+# PCH HSIO Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchHsioLib
+FILE_GUID = 6B2D3D0D-9A04-4E7C-AE84-1C2EF2E00E2E
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchHsioLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+MmPciLib
+PchInfoLib
+PchPcrLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchHsioLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf
new file mode 100644
index 0000000000..b9781de810
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf
@@ -0,0 +1,42 @@
+## @file
+# PCH information library for PCH.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchInfoLibCnl
+FILE_GUID = 455CD363-0E78-46B7-8DD3-634003F1614F
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchInfoLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PrintLib
+PciSegmentLib
+PchPcrLib
+PmcPrivateLib
+PcdLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchInfoLib.c
+PchInfoLibClient.c
+PchInfoLibCnl.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
new file mode 100644
index 0000000000..b1ee095423
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
@@ -0,0 +1,37 @@
+## @file
+# PCH 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) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPcieRpLib
+FILE_GUID = B4129C2C-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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcieRpLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
new file mode 100644
index 0000000000..0244e1c0c8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/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) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcrLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
new file mode 100644
index 0000000000..3b1f1e467b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
@@ -0,0 +1,36 @@
+## @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) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPmcLib
+FILE_GUID = 9D60C364-5086-41E3-BC9D-C62AB7233DBF
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPmcLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+MmPciLib
+PchCycleDecodingLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPmcLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
new file mode 100644
index 0000000000..ceb109168b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
@@ -0,0 +1,35 @@
+## @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) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSbiAccessLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
new file mode 100644
index 0000000000..3bfada0b22
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for PEI/DXE/SMM PCH Serial IO Lib.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSerialIoLibCnl
+FILE_GUID = 613A22A2-5736-40f8-909B-DF10EA389C72
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchSerialIoLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PcdLib
+PciSegmentLib
+GpioPrivateLib
+PchPcrLib
+PchSerialIoUartLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSerialIoLib.c
+PchSerialIoLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
new file mode 100644
index 0000000000..1becfc7a96
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for PCH Serial IO UART Lib.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSerialIoUartLib
+FILE_GUID = 55463A54-FD0D-4e8e-8D57-D54FAAEFDC2F
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchSerialIoUartLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PchSerialIoLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiDxeSmmPchSerialIoUartLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
new file mode 100644
index 0000000000..8a01a749bf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
@@ -0,0 +1,31 @@
+## @file
+#  Component description file for the PchWdtCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiDxeSmmPchWdtCommonLib
+  FILE_GUID                      = 171F78D2-0A52-4692-8830-AB693791EA23
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchWdtCommonLib
+
+[Sources]
+  WdtCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PmcLib
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug           ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
new file mode 100644
index 0000000000..78e212eeb0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
@@ -0,0 +1,43 @@
+## @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) 2019 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
+PmcPrivateLib
+BaseMemoryLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+
+
+[Sources]
+PmcLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf
new file mode 100644
index 0000000000..128b348b3d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf
@@ -0,0 +1,32 @@
+## @file
+# PEI/DXE/SMM PCH SATA library for Cannon Lake PCH.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSataLibCnl
+FILE_GUID = 5163ECE3-5372-47E1-B057-2282E753DD55
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SataLib
+
+[LibraryClasses]
+BaseLib
+PciSegmentLib
+PchInfoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+SataLib.c
+SataLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
new file mode 100644
index 0000000000..37d0c80ea4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component Description File for OcWdt Support.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiOcWdtLib
+FILE_GUID = D5207C23-3632-4078-A671-3B5C364B2BDB
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = OcWdtLib
+
+
+[LibraryClasses]
+IoLib
+DebugLib
+PeiServicesLib
+PchWdtCommonLib
+PmcLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiOcWdtLib.c
+
+
+[Ppis]
+gWdtPpiGuid  ## PRODUCES
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug           ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
new file mode 100644
index 0000000000..68ff41ef7f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
@@ -0,0 +1,24 @@
+## @file
+# Component Description File for OcWdt Support.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiOcWdtLib
+FILE_GUID = DB65B36B-E276-4A2b-AB20-61764889E483
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = OcWdtLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+
+
+[Sources]
+PeiOcWdtLibNull.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
new file mode 100644
index 0000000000..49e63cfc51
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
@@ -0,0 +1,86 @@
+## @file
+# Component description file for the PeiPchPolicy libbrary.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiPchPolicyLibCnl
+FILE_GUID = BB1AC992-B2CA-4744-84B7-915C185576C5
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PchPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PcdLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+PchInfoLib
+ConfigBlockLib
+SiConfigBlockLib
+SataLib
+PchPcieRpLib
+CpuPlatformLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable
+gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber
+
+
+[Sources]
+PeiPchPolicyLib.c
+PeiPchPolicyLibCnl.c
+PeiPchPolicyLibrary.h
+PeiPchPreMemPolicyLib.c
+PchPrintPolicy.c
+PchPreMemPrintPolicy.c
+
+[Guids]
+gPchGeneralConfigGuid              ## CONSUMES
+gPcieRpConfigGuid                  ## CONSUMES
+gSataConfigGuid                    ## CONSUMES
+gIoApicConfigGuid                  ## CONSUMES
+gDmiConfigGuid                     ## CONSUMES
+gFlashProtectionConfigGuid         ## CONSUMES
+gHdAudioConfigGuid                 ## CONSUMES
+gInterruptConfigGuid               ## CONSUMES
+gIshConfigGuid                     ## CONSUMES
+gLanConfigGuid                     ## CONSUMES
+gLockDownConfigGuid                ## CONSUMES
+gP2sbConfigGuid                    ## CONSUMES
+gPmConfigGuid                      ## CONSUMES
+gScsConfigGuid                     ## CONSUMES
+gSerialIoConfigGuid                ## CONSUMES
+gSerialIrqConfigGuid               ## CONSUMES
+gThermalConfigGuid                 ## CONSUMES
+gUsbConfigGuid                     ## CONSUMES
+gEspiConfigGuid                    ## CONSUMES
+gCnviConfigGuid                    ## CONSUMES
+gHsioConfigGuid                    ## CONSUMES
+gPchGeneralPreMemConfigGuid        ## COMSUMES
+gDciPreMemConfigGuid               ## CONSUMES
+gWatchDogPreMemConfigGuid          ## CONSUMES
+gPchTraceHubPreMemConfigGuid       ## CONSUMES
+gSmbusPreMemConfigGuid             ## CONSUMES
+gLpcPreMemConfigGuid               ## CONSUMES
+gHsioPciePreMemConfigGuid          ## CONSUMES
+gHsioSataPreMemConfigGuid          ## CONSUMES
+gPcieRpPreMemConfigGuid            ## CONSUMES
+gHdAudioPreMemConfigGuid           ## CONSUMES
+gIshPreMemConfigGuid               ## CONSUMES
+
+[Ppis]
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
new file mode 100644
index 0000000000..41e339a2e8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Component description file for PCH Reset Lib Pei Phase
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiPchResetLib
+FILE_GUID = DB91FFF0-5B99-4A88-9EC8-183A2106DCA2
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PchResetLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+DebugLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+ResetSystemLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchReset.c
+
+[Ppis]
+gEfiPeiReset2PpiGuid ## PRODUCES
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
new file mode 100644
index 0000000000..f8f8bf1b66
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiResetSystemLib
+FILE_GUID = D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+DebugLib
+BaseMemoryLib
+PeiServicesLib
+PmcLib
+PmcPrivateLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiResetSystemLib.c
+
+
+[Ppis]
+gMeDidSentPpiGuid ## CONSUMES
+gPchResetCallbackPpiGuid ## CONSUMES
+
+
+[Guids]
+gPchGlobalResetGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
new file mode 100644
index 0000000000..fb2fad78d3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for PCH Reset Lib Pei Phase
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSpiLib
+FILE_GUID = 4998447D-7948-448F-AB75-96E24E18FF23
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = SpiLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+DebugLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+PciSegmentLib
+PchSpiCommonLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSpi.c
+
+
+[Ppis]
+gPchSpiPpiGuid ## PRODUCES
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h
new file mode 100644
index 0000000000..7a480b6cad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h
@@ -0,0 +1,117 @@
+/** @file
+  Header file for GPIO Lib implementation.
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/GpioHelpersLib.h>
+#include <Register/PchRegsGpio.h>
+
+// BIT15-0  - pad number
+// BIT31-16 - group info
+//   BIT23- 16 - group index
+//   BIT31- 24 - chipset ID
+#define PAD_INFO_MASK          0x0000FFFF
+#define GROUP_INFO_POSITION    16
+#define GROUP_INFO_MASK        0xFFFF0000
+#define GROUP_INDEX_MASK       0x00FF0000
+#define UNIQUE_ID_MASK         0xFF000000
+#define UNIQUE_ID_POSITION     24
+
+#define GPIO_PAD_DEF(Group,Pad)               (UINT32)(((Group) << 16) + (Pad))
+#define GPIO_GROUP_DEF(Index,ChipsetId)       ((Index) | ((ChipsetId) << 8))
+#define GPIO_GET_GROUP_INDEX(Group)           ((Group) & 0xFF)
+#define GPIO_GET_GROUP_FROM_PAD(Pad)          ((Pad) >> 16)
+#define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad)    GPIO_GET_GROUP_INDEX (((Pad) >> 16))
+#define GPIO_GET_PAD_NUMBER(Pad)              ((Pad) & 0xFFFF)
+#define GPIO_GET_CHIPSET_ID(Pad)              ((Pad) >> 24)
+
+#define GPIO_GET_PAD_POSITION(PadNumber)      ((PadNumber) % 32)
+#define GPIO_GET_DW_NUM(PadNumber)            ((PadNumber) / 32u)
+
+//
+// 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
+**/
+VOID
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  );
+
+/**
+  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_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
new file mode 100644
index 0000000000..79e03fef44
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
@@ -0,0 +1,45 @@
+/** @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) 2019 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;
+};
+
+extern struct PCH_SKU_STRING mSkuStrs[];
+
+/**
+  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
+  );
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h
new file mode 100644
index 0000000000..17e4bb863a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h
@@ -0,0 +1,16 @@
+/** @file
+  Header file for PchSerialIoLibInternal.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SERIAL_IO_LIB_INTERNAL_H_
+#define _PCH_SERIAL_IO_LIB_INTERNAL_H_
+
+typedef struct {
+  UINT8  DevNum;
+  UINT8  FuncNum;
+} SERIAL_IO_BDF_NUMBERS;
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h
new file mode 100644
index 0000000000..abd7e63365
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h
@@ -0,0 +1,35 @@
+/** @file
+  Header file for the PeiPchPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_LIBRARY_H_
+#define _PEI_PCH_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchPolicyLib.h>
+
+/**
+  Adds interrupt configuration for device
+
+  @param[in/out] InterruptConfig         Pointer to interrupt config
+**/
+VOID
+LoadDeviceInterruptConfig (
+  IN OUT  PCH_INTERRUPT_CONFIG  *InterruptConfig
+  );
+
+#endif // _PEI_PCH_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c
new file mode 100644
index 0000000000..20c024e893
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c
@@ -0,0 +1,98 @@
+/** @file
+  Bios Lock library.
+
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+
+/**
+  Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable In SMM.STS).
+  When this is set, attempts to write the WPD (Write Protect Disable) bit in PCH
+  will cause a SMI which will allow the BIOS to verify that the write is from a valid source.
+
+  Bios should always enable LockDownConfig.BiosLock policy to set Bios Lock bit in FRC.
+  If capsule udpate is enabled, it's expected to not do BiosLock by setting BiosLock policy disable
+  so it can udpate BIOS region.
+  After flash update, it should utilize this lib to do BiosLock for security.
+**/
+VOID
+BiosLockEnable (
+  VOID
+  )
+{
+  UINT64  LpcBaseAddress;
+  UINT64  SpiBaseAddress;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+  SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+
+  ///
+  /// 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.
+  ///
+  PciSegmentOr8 (SpiBaseAddress + R_SPI_CFG_BC, B_SPI_CFG_BC_EISS | B_SPI_CFG_BC_LE);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC,
+    1,
+    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC)
+    );
+  PciSegmentOr8 (LpcBaseAddress + R_LPC_CFG_BC, B_LPC_CFG_BC_EISS | B_LPC_CFG_BC_LE);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    PcdGet64 (PcdPciExpressBaseAddress) + LpcBaseAddress + R_LPC_CFG_BC,
+    1,
+    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + LpcBaseAddress + R_LPC_CFG_BC)
+    );
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
new file mode 100644
index 0000000000..76eb3a9b81
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
@@ -0,0 +1,553 @@
+/** @file
+  This file contains routines for GPIO initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GpioLibrary.h"
+#include <Register/PchRegsPcr.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.
+//
+// For Cannonlake only vGPIO group has >32 pads but those pads
+// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be 1
+//
+#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.
+**/
+STATIC
+VOID
+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
+          );
+      }
+    }
+
+  }
+}
+
+/**
+  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);
+  GpioClearAllGpioInterrupts ();
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
new file mode 100644
index 0000000000..0be50f75df
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
@@ -0,0 +1,2710 @@
+/** @file
+  This file contains routines for GPIO
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GpioLibrary.h"
+#include <Register/PchRegsPcr.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
+**/
+STATIC
+VOID
+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) {
+    *ReadVal = 0;
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // 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));
+}
+
+/**
+  This function determines if the group is SMI capable.
+
+  @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                    The function completed successfully
+  @retval FALSE                   Setting SMI for a group is not supported
+**/
+STATIC
+BOOLEAN
+GpioIsSmiSupportedByGroupDw (
+  IN GPIO_GROUP             Group,
+  IN UINT32                 Dw
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  This function determines if the group is NMI capable.
+
+  @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                    The function completed successfully
+  @retval FALSE                   Setting NMI for a group is not supported
+**/
+STATIC
+BOOLEAN
+GpioIsNmiSupportedByGroupDw (
+  IN GPIO_GROUP             Group,
+  IN UINT32                 Dw
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  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
+**/
+STATIC
+VOID
+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;
+  EFI_STATUS             Status;
+
+  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;
+  }
+
+  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
+        //
+        Status = GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+        if (EFI_ERROR (Status)) {
+          ASSERT (FALSE);
+          return;
+        }
+      } 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
+    //
+    Status = GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+    if (EFI_ERROR (Status)) {
+      ASSERT (FALSE);
+      return;
+    }
+  }
+}
+
+/**
+  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;
+
+  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;
+
+  Status = PchSbiExecutionEx (
+             GpioGroupInfo[GroupIndex].Community,
+             RegOffset,
+             GpioLockUnlock,
+             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  GppPadRstCfgToGpioResetConfigMap[] = {
+                              GpioResumeReset,
+                              GpioHostDeepReset,
+                              GpioPlatformReset};
+  static GPIO_RESET_CONFIG  GpdPadRstCfgToGpioResetConfigMap[] = {
+                              GpioDswReset,
+                              GpioHostDeepReset,
+                              GpioPlatformReset,
+                              GpioResumeReset};
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+
+  if (GpioIsDswGroup (Group) && PadRstCfg < 4) {
+    return GpdPadRstCfgToGpioResetConfigMap[PadRstCfg];
+  } else if (PadRstCfg < 3) {
+    return GppPadRstCfgToGpioResetConfigMap[PadRstCfg];
+  } else {
+    ASSERT (FALSE);
+    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) | 0x1;
+
+  //
+  // Read PADCFGLOCKTX register
+  //
+  GpioReadReg (
+    GpioPadLockOutputRegister,
+    Group,
+    GPIO_GET_DW_NUM (PadNumber),
+    &RegVal
+    );
+
+  //
+  // Get Pad Configuration Lock Tx state
+  //
+  GpioData->LockConfig |= ((!((RegVal >> PadBitPosition) & 0x1)) << 2) | 0x1;
+
+  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
+**/
+VOID
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  )
+{
+  UINT32               PadRstCfg;
+  EFI_STATUS           Status;
+
+  //
+  // Configure Reset Type (PadRstCfg)
+  // Reset configuration depends on group type.
+  // This field requires support for new and deprecated settings.
+  //
+  Status = GpioPadRstCfgFromResetConfig (
+             GpioPad,
+             GpioConfig->PowerConfig,
+             &PadRstCfg
+             );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  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);
+}
+
+/**
+  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;
+
+  Status = EFI_SUCCESS;
+  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;
+
+  if (GpioIsNmiSupportedByGroupDw (Group, DwNum)) {
+    GpioWriteReg (
+      GpioNmiEnableRegister,
+      Group,
+      DwNum,
+      ~GpiNmiEnRegMask,
+      GpiNmiEnReg
+      );
+  } else {
+    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 EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Update value to be programmed in GPI_SMI_EN register
+  //
+  GpiSmiEnRegMask = (GpioData->InterruptConfig & 0x1) << PadBitPosition;
+  GpiSmiEnReg = ((GpioData->InterruptConfig & GpioIntSmi) >> 2) << PadBitPosition;
+
+  if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) {
+    GpioWriteReg (
+      GpioSmiEnableRegister,
+      Group,
+      DwNum,
+      ~GpiSmiEnRegMask,
+      GpiSmiEnReg
+      );
+  } else {
+    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 EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // 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;
+  BOOLEAN     IsNmiSupported;
+  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;
+    }
+
+    IsNmiSupported = GpioIsNmiSupportedByGroupDw (
+                       GpioGetGroupFromGpioPad (GpioPad),
+                       GPIO_GET_DW_NUM (PadNumber)
+                       );
+    if (IsNmiSupported) {
+      GpioWriteReg (
+        GpioNmiEnableRegister,
+        GpioGetGroupFromGpioPad (GpioPad),
+        GPIO_GET_DW_NUM (PadNumber),
+        ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+        NmiEnable << GPIO_GET_PAD_POSITION (PadNumber)
+        );
+    } else {
+      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 (FALSE);
+      }
+    }
+  }
+
+  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;
+  EFI_STATUS  Status;
+
+  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.
+    //
+    Status = GpioPadRstCfgFromResetConfig (
+               GpioPad,
+               Value,
+               &PadRstCfg
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    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 Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetHostSwOwnershipForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *HostSwRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioReadReg (
+    GpioHostOwnershipRegister,
+    Group,
+    DwNum,
+    HostSwRegVal
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioSetHostSwOwnershipForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       HostSwRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioWriteReg (
+    GpioHostOwnershipRegister,
+    Group,
+    DwNum,
+    0,
+    HostSwRegVal
+    );
+  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);
+
+  GpioWriteReg (
+    GpioHostOwnershipRegister,
+    GpioGetGroupFromGpioPad (GpioPad),
+    GPIO_GET_DW_NUM (PadNumber),
+    (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+    PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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;
+  }
+
+  GpioReadReg (
+    GpioPadConfigLockRegister,
+    Group,
+    DwNum,
+    PadCfgLockRegVal
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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;
+  }
+
+  GpioReadReg (
+    GpioPadLockOutputRegister,
+    Group,
+    DwNum,
+    PadCfgLockTxRegVal
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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 set 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 GpioSetGroupDwToGpeDwX()
+
+  @param[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  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
+GpioSetGroupToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2
+  )
+{
+  return GpioSetGroupDwToGpeDwX (
+           GroupToGpeDw0,
+           0,
+           GroupToGpeDw1,
+           0,
+           GroupToGpeDw2,
+           0
+           );
+}
+
+/**
+  This procedure will set 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[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupDwForGpeDw0    DW of pins to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  GroupDwForGpeDw1    DW of pins to be mapped to GPE_DW1
+  @param[in]  GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
+  @param[in]  GroupDwForGpeDw2    DW of pins to be mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetGroupDwToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN UINT32                    GroupDwForGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN UINT32                    GroupDwForGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2,
+  IN UINT32                    GroupDwForGpeDw2
+  )
+{
+  UINT32                     Data32Or;
+  UINT32                     Data32And;
+  PCH_SBI_PID                *GpioComSbiIds;
+  UINT32                     NoOfGpioComs;
+  UINT32                     GpioComIndex;
+  UINT32                     GpioGpeDwx[3];
+  UINT32                     PmcGpeDwx[3];
+  GPIO_GROUP                 GroupToGpeDwX[3];
+  UINT32                     GroupDwForGpeDwX[3];
+  UINT8                      GpeDwXIndex;
+  UINT32                     Index;
+  GPIO_GROUP_TO_GPE_MAPPING  *GpioGpeMap;
+  UINT32                     GpioGpeMapLength;
+
+  ZeroMem (GpioGpeDwx, sizeof (GpioGpeDwx));
+  ZeroMem (PmcGpeDwx, sizeof (PmcGpeDwx));
+  //
+  // Check if each group number is unique
+  //
+  if ((GroupToGpeDw0 == GroupToGpeDw1) ||
+      (GroupToGpeDw0 == GroupToGpeDw2) ||
+      (GroupToGpeDw1 == GroupToGpeDw2)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GroupToGpeDwX[0] = GroupToGpeDw0;
+  GroupDwForGpeDwX[0] = GroupDwForGpeDw0;
+  GroupToGpeDwX[1] = GroupToGpeDw1;
+  GroupDwForGpeDwX[1] = GroupDwForGpeDw1;
+  GroupToGpeDwX[2] = GroupToGpeDw2;
+  GroupDwForGpeDwX[2] = GroupDwForGpeDw2;
+
+  GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength);
+
+  for (GpeDwXIndex = 0; GpeDwXIndex < 3; GpeDwXIndex++) {
+    for (Index = 0; Index < GpioGpeMapLength; Index++) {
+
+      if ((GpioGpeMap[Index].Group == GroupToGpeDwX[GpeDwXIndex]) &&
+          (GpioGpeMap[Index].GroupDw == GroupDwForGpeDwX[GpeDwXIndex])) {
+        PmcGpeDwx[GpeDwXIndex] = GpioGpeMap[Index].PmcGpeDwxVal;
+        GpioGpeDwx[GpeDwXIndex] = GpioGpeMap[Index].GpioGpeDwxVal;
+        break;
+      }
+    }
+
+    if (Index == GpioGpeMapLength) {
+      ASSERT (FALSE);
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Program GPE configuration in PMC register
+  //
+  PmcSetGpioGpe (
+    PmcGpeDwx[0],
+    PmcGpeDwx[1],
+    PmcGpeDwx[2]
+    );
+
+  //
+  // Program GPE configuration in GPIO registers
+  //
+  Data32And = (UINT32) ~(B_GPIO_PCR_MISCCFG_GPE0_DW2 | B_GPIO_PCR_MISCCFG_GPE0_DW1 | B_GPIO_PCR_MISCCFG_GPE0_DW0);
+  Data32Or = (UINT32) ((GpioGpeDwx[2] << N_GPIO_PCR_MISCCFG_GPE0_DW2) |
+                       (GpioGpeDwx[1] << N_GPIO_PCR_MISCCFG_GPE0_DW1) |
+                       (GpioGpeDwx[0] << N_GPIO_PCR_MISCCFG_GPE0_DW0));
+
+  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
+
+  //
+  // Program MISCCFG register for each community
+  //
+  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) {
+    MmioAndThenOr32 (
+      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], R_GPIO_PCR_MISCCFG),
+      Data32And,
+      Data32Or
+      );
+  }
+
+  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;
+  EFI_STATUS           Status;
+
+  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
+  //
+  Status = GpioGetGroupDwToGpeDwX (
+             &GroupToGpeDwX[0], &GroupDw[0],
+             &GroupToGpeDwX[1], &GroupDw[1],
+             &GroupToGpeDwX[2], &GroupDw[2]
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // 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'
+  //
+  GpioWriteReg (
+    GpioSmiStatusRegister,
+    Group,
+    DwNum,
+    0u,
+    (UINT32) (BIT0 << PadBitPosition)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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++) {
+      if (GpioIsSmiSupportedByGroupDw(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++) {
+      if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) {
+        SmiEnRegVal = 0;
+        //
+        // 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;
+  EFI_STATUS           Status;
+
+  Status = GpioGetGpeNumber (GpioPad, &Data32);
+  if (EFI_ERROR (Status)) {
+    DEBUG (( DEBUG_ERROR, "GpioCheckFor2Tier: Failed to get GPE number. Status: %r\n", Status ));
+    return FALSE;
+  }
+
+  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'
+  //
+  GpioWriteReg (
+    GpioGpeStatusRegister,
+    Group,
+    DwNum,
+    0u,
+    (UINT32) (BIT0 << PadBitPosition)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to read GPE STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] Data                GPE STS data
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiGpeSts (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *Data
+  )
+{
+  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
+    );
+
+  *Data = (GpeStsRegVal >> PadBitPosition) & 0x1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to lock all GPIO pads except the ones
+  which were requested during their configuration to be left unlocked.
+  This function must be called before BIOS_DONE - before POSTBOOT_SAI is enabled.
+    FSP - call this function from wrapper before transition to FSP-S
+    UEFI/EDK - call this function before EndOfPei event
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioLockPads (
+  VOID
+  )
+{
+  UINT32         DwNum;
+  GPIO_GROUP     Group;
+  GPIO_GROUP     GroupMin;
+  GPIO_GROUP     GroupMax;
+  UINT32         UnlockedPads;
+  EFI_STATUS     Status;
+
+  GroupMin = GpioGetLowestGroup ();
+  GroupMax = GpioGetHighestGroup ();
+
+  for (Group = GroupMin; Group <= GroupMax; Group++) {
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
+
+      UnlockedPads = GpioGetGroupDwUnlockPadConfigMask (GpioGetGroupIndexFromGroup (Group), DwNum);
+
+      Status = GpioLockPadCfgForGroupDw (Group, DwNum, (UINT32)~UnlockedPads);
+      if (EFI_ERROR (Status)) {
+        ASSERT (FALSE);
+        return Status;
+      }
+
+      UnlockedPads = GpioGetGroupDwUnlockOutputMask (GpioGetGroupIndexFromGroup (Group), DwNum);
+
+      Status = GpioLockPadCfgTxForGroupDw (Group, DwNum, (UINT32)~UnlockedPads);
+      if (EFI_ERROR (Status)) {
+        ASSERT (FALSE);
+        return Status;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c
new file mode 100644
index 0000000000..ec33d06156
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c
@@ -0,0 +1,87 @@
+/** @file
+  This file contains GPIO name library implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
new file mode 100644
index 0000000000..9b71cb1d95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
@@ -0,0 +1,234 @@
+/** @file
+  This file contains routines for GPIO native and chipset specific usage
+
+  Copyright (c) 2019 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
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_PAD_DEF (Group,PadNumber);
+  } else {
+    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);
+}
+
+/**
+  This function checks if SATA GP pin is enabled
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval TRUE                    SATA GPx is enabled (pad is in required native mode)
+          FALSE                   SATA GPx is not enabled
+**/
+BOOLEAN
+GpioIsSataGpEnabled (
+  IN  UINT32          SataCtrlIndex,
+  IN  UINTN           SataPort
+  )
+{
+  EFI_STATUS                Status;
+  GPIO_PAD_NATIVE_FUNCTION  SataGpGpio;
+  GPIO_PAD_MODE             GpioMode;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  GpioGetSataGpPin (
+    SataCtrlIndex,
+    SataPort,
+    &SataGpGpio
+    );
+
+  Status =  GpioGetPadMode (SataGpGpio.Pad, &GpioMode);
+  if ((EFI_ERROR (Status)) || (GpioMode != SataGpGpio.Mode)) {
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
new file mode 100644
index 0000000000..24afbbf712
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
@@ -0,0 +1,1136 @@
+/** @file
+  PCH cycle deocding configuration and query library.
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PchEspiLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsSmbus.h>
+
+typedef enum {
+  SlaveLpcEspiCS0,
+  SlaveEspiCS1,
+  SlaveId_Max
+} SLAVE_ID_INDEX;
+
+/**
+  Set PCH TCO base address.
+  This cycle decoding is required also on DMI side
+  Programming steps:
+  1. set Smbus PCI offset 54h [8] to enable TCO base address.
+  2. program Smbus PCI offset 50h [15:5] to TCO base address.
+  3. set Smbus PCI offset 54h [8] to enable TCO base address.
+  4. program "TCO Base Address" in DMI
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchTcoBaseSet (
+  IN  UINT16                            Address
+  )
+{
+  UINT64                                SmbusBase;
+  EFI_STATUS                            Status;
+
+  if ((Address & ~B_SMBUS_CFG_TCOBASE_BAR) != 0) {
+    DEBUG ((DEBUG_ERROR, "PchTcoBaseSet Error. Invalid Address: %x.\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PchDmiSetTcoBase (Address);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  SmbusBase = PCI_SEGMENT_LIB_ADDRESS (
+                DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                DEFAULT_PCI_BUS_NUMBER_PCH,
+                PCI_DEVICE_NUMBER_PCH_SMBUS,
+                PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                0
+                );
+  if (PciSegmentRead16 (SmbusBase) == 0xFFFF) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Verify TCO base is not locked.
+  //
+  if ((PciSegmentRead8 (SmbusBase + R_SMBUS_CFG_TCOCTL) & B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK) != 0) {
+    ASSERT (FALSE);
+    return EFI_DEVICE_ERROR;
+  }
+  //
+  // Disable TCO in SMBUS Device first before changing base address.
+  // Byte access to not touch the TCO_BASE_LOCK bit
+  //
+  PciSegmentAnd8 (
+    SmbusBase + R_SMBUS_CFG_TCOCTL + 1,
+    (UINT8) ~(B_SMBUS_CFG_TCOCTL_TCO_BASE_EN >> 8)
+    );
+  //
+  // Program TCO in SMBUS Device
+  //
+  PciSegmentAndThenOr16 (
+    SmbusBase + R_SMBUS_CFG_TCOBASE,
+    (UINT16) (~B_SMBUS_CFG_TCOBASE_BAR),
+    Address
+    );
+  //
+  // Enable TCO in SMBUS Device and lock TCO BASE
+  //
+  PciSegmentOr16 (
+    SmbusBase + R_SMBUS_CFG_TCOCTL,
+    B_SMBUS_CFG_TCOCTL_TCO_BASE_EN | B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK
+    );
+
+  return Status;
+}
+
+/**
+  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;
+}
+
+/**
+  Returns PCH LPC device PCI base address.
+
+  @retval                   PCH LPC PCI base address.
+**/
+STATIC
+UINT64
+LpcPciBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           PCI_DEVICE_NUMBER_PCH_LPC,
+           PCI_FUNCTION_NUMBER_PCH_LPC,
+           0
+           );
+}
+
+/**
+  Function checks if passed Generic LPC IO Address and Length meets requirements.
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @param[in] Length                     Length of generic IO range.
+
+  @retval TRUE                          Passed IO range meets requirements
+  @retval FALSE                         Passed IO range does not meets requirements.
+**/
+STATIC
+BOOLEAN
+IsLpcIoRangeValid (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length
+  )
+{
+  UINT32            Index;
+  UINT32            NumRanges;
+
+  STATIC struct EXCEPT_RANGE {
+    UINT8 Start;
+    UINT8 Length;
+  } ExceptRanges[] = { {0x00, 0x20}, {0x44, 0x08}, {0x54, 0x0C}, {0x68, 0x08}, {0x80, 0x10}, {0xC0, 0x40} };
+
+  NumRanges = ARRAY_SIZE (ExceptRanges);
+  //
+  // For generic IO range, the base address must align to 4 and less than 0xFFFF,
+  // the length must be power of 2 and less than or equal to 256, and the address must be length aligned.
+  // 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
+  //
+  if (((Length & (Length - 1)) != 0)  ||
+      ((Address & (UINT16) ~B_LPC_CFG_GENX_DEC_IOBAR) != 0) ||
+      (Length > 256)) {
+    return FALSE;
+  }
+  if (Address < 0x100) {
+    for (Index = 0; Index < NumRanges; Index++) {
+      if ((Address >= ExceptRanges[Index].Start) &&
+          ((Address + Length) <= ((UINTN) ExceptRanges[Index].Start + (UINTN) ExceptRanges[Index].Length))) {
+        break;
+      }
+    }
+    if (Index >= NumRanges) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+  Function checks if passed Generic LPC IO Range is already in Gen IO Range list
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] GenIoRangeList             Pointer to Generic IO Ranges List
+
+  @retval TRUE                          Passed IO range alredy covered
+  @retval FALSE                         Passed IO range NOT covered
+**/
+STATIC
+BOOLEAN
+IsRangeInList (
+  IN  UINT32                      Address,
+  IN  UINT32                      Length,
+  IN  PCH_LPC_GEN_IO_RANGE_LIST   *GenIoRangeList
+  )
+{
+  UINT32                                CurrentBaseAddr;
+  UINT32                                CurrentLength;
+  UINT32                                Index;
+
+  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
+    CurrentBaseAddr = GenIoRangeList->Range[Index].BaseAddr;
+    CurrentLength   = GenIoRangeList->Range[Index].Length;
+    if (GenIoRangeList->Range[Index].Enable == 0) {
+      continue;
+    }
+    if ((Address >= CurrentBaseAddr) && ((Address + Length) <= (CurrentBaseAddr + CurrentLength))) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Function checks if passed Generic LPC IO Range overlaps with existing range
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] GenIoRangeList             Pointer to Generic IO Ranges List
+
+  @retval TRUE                          Passed LPC IO range overlaps with existing range
+  @retval FALSE                         Passed LPC IO range NOT overlaps
+**/
+STATIC
+BOOLEAN
+FindOverlappingGenIoRange (
+  IN  UINT32                          Address,
+  IN  UINT32                          Length,
+  IN  PCH_LPC_GEN_IO_RANGE_LIST       *GenIoRangeList
+  )
+{
+  UINT32                              Index;
+  UINT32                              CurrentBaseAddr;
+  UINT32                              CurrentLength;
+
+  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
+    CurrentBaseAddr = GenIoRangeList->Range[Index].BaseAddr;
+    CurrentLength = GenIoRangeList->Range[Index].Length;
+    if (GenIoRangeList->Range[Index].Enable == 0) {
+      continue;
+    }
+
+    if ((Address >= CurrentBaseAddr) &&
+        (Address <= (CurrentBaseAddr + CurrentLength))) {
+      return TRUE;
+    } else if (((Address + Length) >= CurrentBaseAddr) &&
+              ((Address + Length) <= (CurrentBaseAddr + CurrentLength))) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Function look for empty Generic IO range register.
+  If found return range index.
+
+  @param[in]      GenIoRangeList        Pointer to Generic IO Ranges List
+  @param[in]      ListLength            Length of passed list
+  @param[out]     RangeIndex            Generic IO Range Index
+
+  @retval TRUE                          Empty range found
+  @retval FALSE                         NOT found empty range
+**/
+STATIC
+BOOLEAN
+FindEmptyGenIoRange (
+  IN  PCH_LPC_GEN_IO_RANGE_LIST   *GenIoRangeList,
+  IN  UINT32                      ListLength,
+  OUT UINT32                      *RangeIndex
+  )
+{
+  UINT32                          Index;
+
+  for (Index = 0; Index < ListLength; Index++) {
+    if (GenIoRangeList->Range[Index].Enable == 0) {
+      *RangeIndex = Index;
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Get PCH LPC/eSPI and eSPI CS1# generic IO range list.
+  This function returns a list of base address, length, and enable for all LPC/eSPI or eSPI CS1# generic IO range registers.
+
+  @param[in]  RangeIndex                Slave ID (refer to SLAVE_ID_INDEX)
+  @param[out] GenIoRangeList            LPC/eSPI or eSPI CS1# generic IO range registers.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+LpcEspiGenIoRangeGetHelper (
+  IN  SLAVE_ID_INDEX                    SlaveId,
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
+  )
+{
+  UINT32                                Index;
+  UINT64                                LpcBase;
+  UINT32                                Data32;
+  UINT32                                GenIoReg;
+
+  if ((GenIoRangeList == NULL) || (SlaveId >= SlaveId_Max)) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  LpcBase = LpcPciBase ();
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenIoReg = R_ESPI_CFG_CS1GIR1;
+  } else {
+    GenIoReg = R_LPC_CFG_GEN1_DEC;
+  }
+
+  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
+    if ((SlaveId == SlaveEspiCS1) &&
+        (Index > 0)) {
+      // For eSPI CS1# we have only one range. Reset remaining entries to zero.
+      GenIoRangeList->Range[Index].BaseAddr = 0;
+      GenIoRangeList->Range[Index].Enable = 0;
+      GenIoRangeList->Range[Index].Length = 0;
+      continue;
+    }
+    Data32 = PciSegmentRead32 (LpcBase + GenIoReg + Index * 4);
+    GenIoRangeList->Range[Index].BaseAddr = Data32 & B_LPC_CFG_GENX_DEC_IOBAR;
+    GenIoRangeList->Range[Index].Length   = ((Data32 & B_LPC_CFG_GENX_DEC_IODRA) >> 16) + 4;
+    GenIoRangeList->Range[Index].Enable   = Data32 & B_LPC_CFG_GENX_DEC_EN;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Function checks if passed Generic LPC IO Range colliding
+  with range alredy defined for other eSPI chiselect (CS)
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] SlaveId                    Slave ID (refer to SLAVE_ID_INDEX)
+
+  @retval TRUE                          Passed IO range conflicting
+  @retval FALSE                         There is no conflict
+**/
+STATIC
+BOOLEAN
+IsRangeColliding (
+  IN  UINT32                      Address,
+  IN  UINT32                      Length,
+  IN  SLAVE_ID_INDEX              SlaveId
+  )
+{
+  EFI_STATUS                      Status;
+  PCH_LPC_GEN_IO_RANGE_LIST       GenIoRangeList;
+
+  if (SlaveId == SlaveEspiCS1) {
+    Status  = LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0, &GenIoRangeList);
+    if (!EFI_ERROR (Status)) {
+      if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) ||
+          IsRangeInList (Address, Length, &GenIoRangeList)) {
+        return TRUE;
+      }
+    }
+  } else {
+    Status  = LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, &GenIoRangeList);
+    if (!EFI_ERROR (Status)) {
+      if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) ||
+          IsRangeInList (Address, Length, &GenIoRangeList)) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS                            Status;
+  PCH_LPC_GEN_IO_RANGE_LIST             GenIoRangeList;
+  UINT32                                RangeIndex;
+  UINT32                                Data32;
+  UINT32                                GenIoReg;
+  UINT32                                ListLength;
+
+  //
+  // Check if pasesed Address and Length meets all requirements
+  //
+  if(!IsLpcIoRangeValid (Address, Length) || (SlaveId >= SlaveId_Max)) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Read current Generic IO configuration
+  //
+  Status  = LpcEspiGenIoRangeGetHelper (SlaveId, &GenIoRangeList);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Check if passed Generic IO range is already covered in current configuration
+  //
+  if (IsRangeInList (Address, Length, &GenIoRangeList)) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Check if passed Generic IO range conflicting with other eSPI CS decoding
+  //
+  if (IsRangeColliding (Address, Length, SlaveId)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenIoReg = R_ESPI_CFG_CS1GIR1;
+    ListLength = ESPI_CS1_GEN_IO_RANGE_MAX;
+  } else {
+    GenIoReg = R_LPC_CFG_GEN1_DEC;
+    ListLength = PCH_LPC_GEN_IO_RANGE_MAX;
+  }
+
+  RangeIndex = ListLength;
+  //
+  // Check if there is an empty Generic IO range register
+  //
+  if (FindEmptyGenIoRange (&GenIoRangeList, ListLength, &RangeIndex) == FALSE) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Program decoding in DMI and LPC/eSPI registers
+  //
+  if (SlaveId == SlaveEspiCS1) {
+    ASSERT (RangeIndex == 0);
+    Status = PchDmiSetEspiCs1GenIoRange (Address, Length);
+  } else {
+    Status = PchDmiSetLpcGenIoRange (Address, Length, RangeIndex);
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Program LPC/eSPI generic IO range register accordingly.
+  //
+  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
+  Data32 |= (UINT32) Address;
+  Data32 |= B_LPC_CFG_GENX_DEC_EN;
+
+  //
+  // Program LPC/eSPI PCI Offset 84h ~ 93h (LPC, eSPI CS0#) or A4h (eSPI CS1#) of Mask, Address, and Enable.
+  //
+  PciSegmentWrite32 (
+    LpcPciBase () + GenIoReg + RangeIndex * 4,
+    Data32
+    );
+
+  return Status;
+}
+
+/**
+  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 eSPI CS1# generic IO range decoding.
+
+  Steps of programming generic IO range:
+  1. Program eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enable.
+  2. Program eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @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               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeSet (
+  IN  UINT16                            Address,
+  IN  UINTN                             Length
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiGenIoRangeSetHelper ((UINT32)Address, (UINT32)Length, SlaveEspiCS1);
+}
+
+/**
+  Get PCH LPC/eSPI generic IO range list.
+  This function returns a list of base address, length, and enable for all LPC/eSPI generic IO range registers.
+
+  @param[out] LpcGenIoRangeList         Return all LPC/eSPI generic IO range register status.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchLpcGenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *LpcGenIoRangeList
+  )
+{
+  return LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0, LpcGenIoRangeList);
+}
+
+/**
+  Get PCH eSPI CS1# generic IO range list.
+  This function returns a list of base address, length, and enable for all eSPI CS1# generic IO range registers.
+
+  @param[out] GenIoRangeList            eSPI generic IO range registers.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, GenIoRangeList);
+}
+
+/**
+  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.
+**/
+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, "PchLpcEspiMemRangeSet Error. Invalid Address: %x or invalid SlaveId\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  LpcBase = LpcPciBase ();
+
+  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);
+}
+
+/**
+  @deprecated. Keep this for backward compatibility.
+  It's replaced by PchEspiCs1MemRangeSet.
+**/
+EFI_STATUS
+PchEspiMemRange2Set (
+  IN  UINT32                            Address
+  )
+{
+  return PchEspiCs1MemRangeSet (Address);
+}
+
+/**
+  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
+**/
+EFI_STATUS
+LpcEspiMemRangeGetHelper (
+  IN  SLAVE_ID_INDEX                    SlaveId,
+  OUT UINT32                            *Address
+  )
+{
+  UINT32                                GenMemReg;
+
+  if ((Address == NULL) || (SlaveId >= SlaveId_Max)) {
+    DEBUG ((DEBUG_ERROR, "PchLpcEspiMemRangeGet Error. Invalid pointer or SlaveId.\n"));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenMemReg = R_ESPI_CFG_CS1GMR1;
+  } else {
+    GenMemReg = R_LPC_CFG_LGMR;
+  }
+  *Address = PciSegmentRead32 (LpcPciBase () + 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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+    //
+    // Read SPI CFG cycle before write SPI CFG cycle
+    PciSegmentRead16 (BaseAddr + R_SPI_CFG_BDE);
+    //
+    // If SPI, Program SPI offset D8h to BiosDecodeEnable.
+    //
+    PciSegmentWrite16 (BaseAddr + R_SPI_CFG_BDE, BiosDecodeEnable);
+  } else {
+    BaseAddr = LpcPciBase ();
+    //
+    // 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  = LpcPciBase ();
+
+  //
+  // 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 = LpcPciBase ();
+
+  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);
+}
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port.
+  System BIOS is likely to do this very soon after reset before PCI bus enumeration.
+  This cycle decoding is allowed to set when DMI is unlocked
+
+  @param[in] RpNumber                PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoPort80DecodeSet (
+  IN  UINTN                             RpNumber
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PchDmiSetIoPort80Decode (RpNumber);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Get IO APIC registers base address.
+
+  @param[out] IoApicBase                Buffer of IO APIC register address
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoApicBaseGet (
+  OUT UINT32                            *IoApicBase
+  )
+{
+  *IoApicBase = PcdGet32 (PcdIoApicBaseAddress);
+  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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c
new file mode 100644
index 0000000000..1bbecc71ed
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c
@@ -0,0 +1,505 @@
+/** @file
+  This file contains routines for eSPI
+
+  Copyright (c) 2019 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/PchEspiLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/TimerLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsPcr.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 (IsPchH () && ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAPS) & R_ESPI_PCR_SOFTSTRAPS_CS1_EN) != 0));
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Data32;
+  UINT8       SupportedChannels;
+
+  Status = PchEspiSlaveGetConfig (SlaveId, R_ESPI_SLAVE_GENCAP, &Data32);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  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 a PCH_H
+  //
+  if ((SlaveId == 1) && (IsPchLp ())) {
+    DEBUG ((DEBUG_ERROR, "eSPI Slave ID of 1 is only available on PCH_H \n"));
+    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);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = 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;
+  EFI_STATUS  Status;
+
+  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) {
+    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    if ((Data32 & B_ESPI_SLAVE_BME) != 0) {
+      Data32 &= ~(B_ESPI_SLAVE_BME);
+      Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+      SlaveBmeSet = TRUE;
+    }
+  }
+
+  // Disable channel
+  Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Data32 &= ~(B_ESPI_SLAVE_CHACAP_CHEN);
+  Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  // Enable channel
+  Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Data32 |= B_ESPI_SLAVE_CHACAP_CHEN;
+  Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  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)) {
+    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    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) {
+    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    Data32 |= B_ESPI_SLAVE_BME;
+    Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c
new file mode 100644
index 0000000000..652a47ebaf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c
@@ -0,0 +1,82 @@
+/** @file
+  PCH Gbe Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.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
+PchIsGbeRegionValid (
+  VOID
+  )
+{
+  UINT32  SpiBar;
+  SpiBar = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
+                               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                               DEFAULT_PCI_BUS_NUMBER_PCH,
+                               PCI_DEVICE_NUMBER_PCH_SPI,
+                               PCI_FUNCTION_NUMBER_PCH_SPI,
+                               R_SPI_CFG_BAR0)) & ~B_SPI_CFG_BAR0_MASK;
+  ASSERT (SpiBar != 0);
+  if (MmioRead32 (SpiBar + R_SPI_MEM_FREG3_GBE) != B_SPI_MEM_FREGX_BASE_MASK) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/**
+  Check whether LAN controller is enabled in the platform.
+
+  @retval TRUE                    GbE is enabled
+  @retval FALSE                   GbE is disabled
+**/
+BOOLEAN
+PchIsGbePresent (
+  VOID
+  )
+{
+  //
+  // Check PCH Support
+  //
+  if (!PchIsGbeSupported ()) {
+    return FALSE;
+  }
+  //
+  // Check PMC strap/fuse
+  //
+  if (!PmcIsGbeSupported ()) {
+    return FALSE;
+  }
+  //
+  // Check GbE NVM
+  //
+  if (PchIsGbeRegionValid () == FALSE) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c
new file mode 100644
index 0000000000..2be8e8ed49
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c
@@ -0,0 +1,127 @@
+/** @file
+  PCH HSIO Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <PchAccess.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchHsioLib.h>
+
+/**
+  The function returns the Port Id and lane owner for the specified lane
+
+  @param[in]  PhyMode             Phymode that needs to be checked
+  @param[out] PortId              Common Lane End Point ID
+  @param[out] LaneOwner           Lane Owner
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid lane number
+**/
+EFI_STATUS
+EFIAPI
+PchGetLaneInfo (
+  IN  UINT32                            LaneNum,
+  OUT UINT8                             *PortId,
+  OUT UINT8                             *LaneOwner
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[out] LaneNum                   GBE Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetGbeLaneNum (
+  UINT8               *LaneNum
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  Usb3LaneIndex             USB3 Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetUsb3LaneNum (
+  UINT32              Usb3LaneIndex,
+  UINT8               *LaneNum
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  SataLaneIndex             Sata Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetSataLaneNum (
+  UINT32              SataLaneIndex,
+  UINT8               *LaneNum
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  PcieLaneIndex             PCIE Root Port Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetPcieLaneNum (
+  UINT32              PcieLaneIndex,
+  UINT8               *LaneNum
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get HSIO lane representation needed to perform any operation on the lane.
+
+  @param[in]  LaneIndex  Number of the HSIO lane
+  @param[out] HsioLane   HSIO lane representation
+**/
+VOID
+HsioGetLane (
+  IN   UINT8       LaneIndex,
+  OUT  HSIO_LANE   *HsioLane
+  )
+{
+
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
new file mode 100644
index 0000000000..7c3ade49b6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
@@ -0,0 +1,272 @@
+/** @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) 2019 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 <Register/PchRegsPcie.h>
+#include <IndustryStandard/Pci30.h>
+
+/**
+  Return LPC Device Id
+
+  @retval PCH_LPC_DEVICE_ID         PCH Lpc Device ID
+**/
+UINT16
+PchGetLpcDid (
+  VOID
+  )
+{
+  UINT64  LpcBaseAddress;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+
+  return PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
+}
+
+/**
+  Return Pch Series
+
+  @retval PCH_SERIES            Pch Series
+**/
+PCH_SERIES
+PchSeries (
+  VOID
+  )
+{
+  PCH_SERIES        PchSer;
+  static PCH_SERIES PchSeries = PCH_UNKNOWN_SERIES;
+
+  if (PchSeries != PCH_UNKNOWN_SERIES) {
+    return PchSeries;
+  }
+
+  PchSer = PchSeriesFromLpcDid (PchGetLpcDid ());
+
+  PchSeries = PchSer;
+
+  return PchSer;
+}
+
+/**
+  Return Pch stepping type
+
+  @retval PCH_STEPPING            Pch stepping type
+**/
+PCH_STEPPING
+PchStepping (
+  VOID
+  )
+{
+  UINT8                RevId;
+  UINT64               LpcBaseAddress;
+  static PCH_STEPPING  PchStepping = PCH_STEPPING_MAX;
+
+  if (PchStepping != PCH_STEPPING_MAX) {
+    return PchStepping;
+  }
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+  RevId = PciSegmentRead8 (LpcBaseAddress + PCI_REVISION_ID_OFFSET);
+
+  PchStepping = RevId;
+
+  return RevId;
+}
+
+/**
+  Determine if PCH is supported
+
+  @retval TRUE                    PCH is supported
+  @retval FALSE                   PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+  VOID
+  )
+{
+  UINT16         LpcDeviceId;
+  UINT16         LpcVendorId;
+  UINT64         LpcBaseAddress;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+
+  LpcDeviceId = PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
+  LpcVendorId = PciSegmentRead16 (LpcBaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  ///
+  /// Verify that this is a supported chipset
+  ///
+  if ((LpcVendorId == V_LPC_CFG_VENDOR_ID) && (PchSeries () != PCH_UNKNOWN_SERIES)) {
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_ERROR, "PCH code doesn't support the LpcDeviceId: 0x%04x!\n", LpcDeviceId));
+    return FALSE;
+  }
+}
+
+/**
+  Check if this is PCH LP series
+
+  @retval TRUE                It's PCH LP series
+  @retval FALSE               It's not PCH LP series
+**/
+BOOLEAN
+IsPchLp (
+  VOID
+  )
+{
+  return (PchSeries () == PCH_LP);
+}
+
+/**
+  Check if this is PCH H series
+
+  @retval TRUE                It's PCH H series
+  @retval FALSE               It's not PCH H series
+**/
+BOOLEAN
+IsPchH (
+  VOID
+  )
+{
+  return (PchSeries () == PCH_H);
+}
+
+/**
+  Check if this is CDF PCH generation
+
+  @retval TRUE                It's CDF PCH
+  @retval FALSE               It's not CDF PCH
+**/
+BOOLEAN
+IsCdfPch (
+  VOID
+  )
+{
+  return (PchGeneration () == CDF_PCH);
+}
+
+/**
+  Check if this is PCH generation
+
+  @retval TRUE                It's CNL PCH
+  @retval FALSE               It's not CNL PCH
+**/
+BOOLEAN
+IsCnlPch (
+  VOID
+  )
+{
+  return (PchGeneration () == CNL_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;
+  }
+
+  AsciiSPrint (Buffer, BufferSize, "%c%c", 'A' + (PchStep >> 4), '0' + (PchStep & 0xF));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get PCH Sku ASCII string
+  The return string is zero terminated.
+
+  @retval Static ASCII string of PCH Sku
+**/
+CHAR8*
+PchGetSkuStr (
+  VOID
+  )
+{
+  UINTN          Index;
+  UINT16         LpcDid;
+
+  LpcDid = PchGetLpcDid ();
+
+  for (Index = 0; mSkuStrs[Index].Id != 0xFFFF; Index++) {
+    if (LpcDid == mSkuStrs[Index].Id) {
+      return mSkuStrs[Index].String;
+    }
+  }
+
+  return "Undefined SKU";
+}
+
+/**
+  Get Pch Maximum Pcie Controller Number
+
+  @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPcieControllerNum (
+  VOID
+  )
+{
+  return GetPchMaxPciePortNum () / PCH_PCIE_CONTROLLER_PORTS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c
new file mode 100644
index 0000000000..7b09a2dbb9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c
@@ -0,0 +1,87 @@
+/** @file
+  Common Pch information library for Client PCH silicon.
+
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+
+/**
+  Get Pch Maximum Pcie Clock Number
+
+  @retval Pch Maximum Pcie Clock Number
+**/
+UINT8
+GetPchMaxPcieClockNum (
+  VOID
+  )
+{
+  if (IsPchH ()) {
+    return 16;
+  } else {
+    return 6;
+  }
+}
+
+/**
+  Get Pch Maximum Serial IO controllers number
+
+  @retval Pch Maximum Serial IO controllers number
+**/
+UINT8
+GetPchMaxSerialIoControllersNum (
+  VOID
+  )
+{
+  return 12;
+}
+
+/**
+  Get Pch Maximum Serial IO I2C controllers number
+
+  @retval Pch Maximum Serial IO I2C controllers number
+**/
+UINT8
+GetPchMaxSerialIoI2cControllersNum (
+  VOID
+  )
+{
+  if (IsPchH ()) {
+    return 4;
+  } else {
+    return 6;
+  }
+}
+
+/**
+  Get Pch Maximum Serial IO SPI controllers number
+
+  @retval Pch Maximum Serial IO SPI controllers number
+**/
+UINT8
+GetPchMaxSerialIoSpiControllersNum (
+  VOID
+  )
+{
+  return 3;
+}
+
+/**
+  Get Pch Maximum Serial IO UART controllers number
+
+  @retval Pch Maximum Serial IO UART controllers number
+**/
+UINT8
+GetPchMaxSerialIoUartControllersNum (
+  VOID
+  )
+{
+  return 3;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c
new file mode 100644
index 0000000000..431b1470c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c
@@ -0,0 +1,386 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsLpcCnl.h>
+#include "PchInfoLibPrivate.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegsLpc.h>
+
+/**
+  Determine Pch Series based on Device Id
+
+  @param[in] LpcDeviceId      Lpc Device Id
+
+  @retval PCH_SERIES          Pch Series
+**/
+PCH_SERIES
+PchSeriesFromLpcDid (
+  IN UINT16 LpcDeviceId
+  )
+{
+  switch (LpcDeviceId & B_LPC_CFG_DID) {
+
+    case V_LPC_CFG_DID_CNL_H:
+      return PCH_H;
+
+    case V_LPC_CFG_DID_CNL_LP:
+      return PCH_LP;
+
+    default:
+      return PCH_UNKNOWN_SERIES;
+  }
+}
+
+/**
+  Return Pch Generation
+
+  @retval PCH_GENERATION            Pch Generation
+**/
+PCH_GENERATION
+PchGeneration (
+  VOID
+  )
+{
+  return CNL_PCH;
+}
+
+/**
+  Check if this is Server PCH
+
+  @retval TRUE                It's a Server PCH
+  @retval FALSE               It's not a Server PCH
+**/
+BOOLEAN
+IsPchServer (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Get RST mode supported by the silicon
+
+  @retval RST_MODE    RST mode supported by silicon
+**/
+RST_MODE
+PchGetSupportedRstMode (
+  VOID
+  )
+{
+  switch (PchGetLpcDid ()) {
+
+    case V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4:
+    case V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU:
+      return RstUnsupported;
+      break;
+
+    default:
+      return RstPremium;
+      break;
+  }
+}
+
+/**
+  Check if this is Server SKU
+
+  @retval TRUE                It's PCH Server SKU
+  @retval FALSE               It's not PCH Server SKU
+**/
+BOOLEAN
+IsPchServerSku (
+  VOID
+  )
+{
+  UINT16 LpcDid;
+
+  LpcDid = PchGetLpcDid ();
+
+  if (LpcDid == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Get PCH series ASCII string.
+
+  @retval PCH Series string
+**/
+CHAR8*
+PchGetSeriesStr (
+  VOID
+  )
+{
+  switch (PchSeries ()) {
+
+    case PCH_LP:
+      return "CNL PCH-LP";
+
+    case PCH_H:
+      return "CNL PCH-H";
+
+    default:
+      return NULL;
+  }
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+struct PCH_SKU_STRING mSkuStrs[] = {
+  //
+  // PCH LP Mobile LPC Device IDs
+  //
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU, "Super SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0, "(U) Super SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1, "Super SKU (locked)"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2, "(Y) Premium SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3, "(U) Premium  SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4, "(U) Base/Mainstream SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5, "(Y) Super SKU"},
+  //
+  // PCH H LPC Device IDs
+  //
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU, "CNL PCH-H SKU A300"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU, "H310"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU, "H370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU, "Z390"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU, "Q370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU, "C246"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU, "C242"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU, "X399"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU, "QM370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU, "HM370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU, "CM246"},
+  {0xFFFF, NULL}
+};
+
+/**
+  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;
+}
+
+/**
+  Get Pch Maximum Pcie Root Port Number
+
+  @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPciePortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 16;
+  } else {
+    return 24;
+  }
+}
+
+/**
+  Get Pch Usb2 Maximum Physical Port Number
+
+  @retval Pch Usb2 Maximum Physical Port Number
+**/
+UINT8
+GetPchUsb2MaxPhysicalPortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 10;
+  } else {
+    return 14;
+  }
+}
+
+/**
+  Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb2PortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 12;
+  } else {
+    return 16;
+  }
+}
+
+/**
+  Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb3PortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 6;
+  } else {
+    return 10;
+  }
+}
+
+/**
+  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 PCH_HDAUDIO_IDISP_TMODE Tmode
+  )
+{
+  //
+  // iDisplay Audio Link T-mode support per PCH Generation/Series:
+  // 1. 1T  - CNP-LP
+  // 2. 2T  - CNP-LP/H (default)
+  //
+  switch (Tmode) {
+    case PchHdaIDispMode1T:
+      return IsPchLp ();
+    case PchHdaIDispMode2T:
+      return TRUE;
+    case PchHdaIDispMode4T:
+    case PchHdaIDispMode8T:
+    case PchHdaIDispMode16T:
+    default:
+      return FALSE;
+  }
+}
+
+/**
+  Gets the maximum number of UFS controller supported by this chipset.
+
+  @return Number of supported UFS controllers
+**/
+UINT8
+PchGetMaxUfsNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/**
+  Check if this chipset supports eMMC controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchEmmcSupported (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Check if this chipset supports SD controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchSdCardSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Check if this chipset supports UFS controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchUfsSupported (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  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 IsPchH ();
+}
+
+/**
+  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 !IsPchH ();
+}
+
+/**
+  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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
new file mode 100644
index 0000000000..9997c3612b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
@@ -0,0 +1,183 @@
+/** @file
+  PCH 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) 2019 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 <Register/PchRegsPcie.h>
+#include <Register/PchRegsPcr.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[] = {
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPA,  0 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPB,  4 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPC,  8 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPD, 12 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPE, 16 }, // PCH-H only
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPF, 20 }  // PCH-H only
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 mPchPcieControllerInfoSize = sizeof (mPchPcieControllerInfo) / sizeof (mPchPcieControllerInfo[0]);
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchLpRstPcieStorageSupportedPort[] = {
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP1..RP4
+  RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,         // RP5..RP8
+  RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,         // RP9..RP12
+  RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3          // RP13..RP16
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchHRstPcieStorageSupportedPort[] = {
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP1..RP4
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP5..RP8
+  RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,         // RP9..RP12
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP13..RP16
+  RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,         // RP17..RP20
+  RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2          // RP21..RP24
+};
+
+/**
+  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;
+}
+
+/**
+  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
+  )
+{
+  UINTN       RpDevice;
+  UINTN       RpFunction;
+
+  GetPchPcieRpDevFun (RpIndex, &RpDevice, &RpFunction);
+
+  return PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+}
+
+/**
+  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 ();
+}
+
+/**
+  Check the RST PCIe Storage Cycle Router number according to the root port number and PCH type
+
+  @param[in] RootPortNum  Root Port Number
+
+  @return  The RST PCIe Storage Cycle Router Number
+**/
+UINT8
+RstGetCycleRouterNumber (
+  IN  UINT32                   RootPortNum
+  )
+{
+  if (IsPchLp ()) {
+    if (RootPortNum < ARRAY_SIZE (mPchLpRstPcieStorageSupportedPort)) {
+      return mPchLpRstPcieStorageSupportedPort[RootPortNum];
+    }
+  } else if (IsPchH ()) {
+    if (RootPortNum < ARRAY_SIZE (mPchHRstPcieStorageSupportedPort)) {
+      return mPchHRstPcieStorageSupportedPort[RootPortNum];
+    }
+  }
+  return RST_PCIE_STORAGE_CR_INVALID;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
new file mode 100644
index 0000000000..6f70733fe7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
@@ -0,0 +1,279 @@
+/** @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) 2019 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 <Register/PchRegsPcr.h>
+
+#ifndef MDEPKG_NDEBUG
+/**
+  Checks if the offset is valid for a given memory access width
+
+  @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 (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFF)) {
+    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);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c
new file mode 100644
index 0000000000..2654a76983
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c
@@ -0,0 +1,101 @@
+/** @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) 2019 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/MmPciLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPmcLib.h>
+
+/**
+  Query PCH to determine the Pm Status
+  NOTE:
+  It's matter when did platform code use this library, since some status could be cleared by write one clear.
+  Therefore this funciton is not always return the same result in one boot.
+  It's suggested that platform code read this status in the beginning of post.
+  For the ColdBoot case, this function only returns one case of the cold boot. Some cold boot case might
+  depends on the power cycle scenario and should check with different condtion.
+
+  @param[in] PmStatus - The Pch Pm Status to be probed
+
+  @retval Return TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+  PCH_PM_STATUS PmStatus
+  )
+{
+  UINTN  PmcRegBase;
+  UINT32 GblRst0;
+
+  PmcRegBase = MmPciBase (
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_PMC,
+                 PCI_FUNCTION_NUMBER_PCH_PMC
+                 );
+
+  switch (PmStatus) {
+    case WarmBoot:
+      break;
+
+    case PwrFlr:
+      break;
+
+    case PwrFlrSys:
+      if (GblRst0 & BIT12) {
+        return TRUE;
+      }
+      break;
+
+    case PwrFlrPch:
+      if (GblRst0 & BIT11) {
+        return TRUE;
+      }
+      break;
+
+    case ColdBoot:
+      break;
+
+    default:
+      break;
+  }
+
+  return FALSE;
+}
+
+/**
+  Funtion to check if Battery lost or CMOS cleared.
+
+  @reval TRUE  Battery is always present.
+  @reval FALSE CMOS is cleared.
+**/
+BOOLEAN
+EFIAPI
+PchIsRtcBatteryGood (
+  VOID
+  )
+{
+  UINTN    PmcBaseAddress;
+
+  //
+  // Check if the CMOS battery is present
+  // Checks RTC_PWR_STS bit in the GEN_PMCON_3 register
+  //
+  PmcBaseAddress = MmPciBase (
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_PMC,
+                     PCI_FUNCTION_NUMBER_PCH_PMC
+                     );
+  return FALSE;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
new file mode 100644
index 0000000000..43690e2409
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
@@ -0,0 +1,270 @@
+/** @file
+  PCH SBI access library.
+
+  Copyright (c) 2019 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 <Register/PchRegs.h>
+#include <Register/PchRegsP2sb.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
+EFIAPI
+PchSbiExecution (
+  IN     PCH_SBI_PID                    Pid,
+  IN     UINT64                         Offset,
+  IN     PCH_SBI_OPCODE                 Opcode,
+  IN     BOOLEAN                        Posted,
+  IN OUT UINT32                         *Data32,
+  OUT    UINT8                          *Response
+  )
+{
+  //
+  // Check address valid
+  //
+  if (((UINT32) Offset & 0x3) != 0) {
+    //
+    // Warning message for the address not DWORD alignment.
+    //
+    DEBUG ((DEBUG_INFO, "PchSbiExecution: Address is not DWORD aligned.\n"));
+  }
+
+  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
+EFIAPI
+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 = PCI_SEGMENT_LIB_ADDRESS (
+               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+               DEFAULT_PCI_BUS_NUMBER_PCH,
+               PCI_DEVICE_NUMBER_PCH_P2SB,
+               PCI_FUNCTION_NUMBER_PCH_P2SB,
+               0
+               );
+  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 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 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 {
+      return EFI_DEVICE_ERROR;
+    }
+  }
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c
new file mode 100644
index 0000000000..0e79d83a12
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c
@@ -0,0 +1,516 @@
+/** @file
+  PCH Serial IO Lib implementation.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <SaAccess.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchSerialIoUartLib.h>
+#include <Include/PcieRegs.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsSerialIo.h>
+
+#define PCIEX_BAR_ADDR_MASK  0x0000007FFC000000
+
+typedef struct {
+  UINT32 Bar0;
+  UINT32 Bar1;
+} SERIAL_IO_CONTROLLER_DESCRIPTOR;
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR mSerialIoAcpiAddress [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  {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},
+  {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}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchSerialIoPciCfgCtrAddr [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  R_SERIAL_IO_PCR_PCICFGCTRL1,
+  R_SERIAL_IO_PCR_PCICFGCTRL2,
+  R_SERIAL_IO_PCR_PCICFGCTRL3,
+  R_SERIAL_IO_PCR_PCICFGCTRL4,
+  R_SERIAL_IO_PCR_PCICFGCTRL5,
+  R_SERIAL_IO_PCR_PCICFGCTRL6,
+  R_SERIAL_IO_PCR_PCICFGCTRL13,
+  R_SERIAL_IO_PCR_PCICFGCTRL14,
+  R_SERIAL_IO_PCR_PCICFGCTRL9,
+  R_SERIAL_IO_PCR_PCICFGCTRL10,
+  R_SERIAL_IO_PCR_PCICFGCTRL11
+};
+
+/**
+  Returns Serial IO Controller Type  I2C, SPI or UART
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            I2C, SPI or UART
+  @retval            UNKNOWN - in case if undefined controller
+**/
+PCH_SERIAL_IO_CONTROLLER_TYPE
+GetSerialIoControllerType (
+  IN PCH_SERIAL_IO_CONTROLLER  Controller
+  )
+{
+  if (Controller >= PchSerialIoIndexI2C0 && Controller <= GetMaxI2cNumber ()) {
+    return SERIAL_IO_I2C;
+  } else if (Controller >= PchSerialIoIndexSpi0 && Controller < (PchSerialIoIndexSpi0 + GetPchMaxSerialIoSpiControllersNum ())) {
+    return SERIAL_IO_SPI;
+  } else if (Controller >= PchSerialIoIndexUart0 && Controller <= PchSerialIoIndexUart2) {
+    return SERIAL_IO_UART;
+  }
+  return SERIAL_IO_UNKNOWN;
+}
+
+/**
+  Checks if given Serial IO Controller Function equals 0
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               TRUE if SerialIO Function is equal to 0
+                                        FALSE if Function is higher then 0
+**/
+BOOLEAN
+IsSerialIoFunctionZero (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  )
+{
+  if (GetSerialIoFunctionNumber (SerialIoNumber) > 0) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Checks if given Serial IO Controller is enabled or not
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval TRUE                          TRUE if given serial io device is enabled.
+  @retval FALSE                         FALSE if given serial io device is disabled.
+**/
+BOOLEAN
+IsSerialIoDeviceEnabled (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  )
+{
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, DeviceNumber, FunctionNumber, PCI_DEVICE_ID_OFFSET)) != 0xFFFF) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Checks if given device corresponds to any of LPSS Devices
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval                               TRUE if SerialIO Device/Function Number is equal to any of LPSS devices
+                                        FALSE Device/Function is not in Serial IO scope
+**/
+BOOLEAN
+IsSerialIoDevice (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER  Controller;
+  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
+
+  ControllerMax = GetPchMaxSerialIoControllersNum ();
+
+  for (Controller = 0; Controller < ControllerMax; Controller++) {
+    if ((DeviceNumber == GetSerialIoDeviceNumber (Controller)) &&
+        (FunctionNumber == GetSerialIoFunctionNumber (Controller))) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Gets Pci Config control offset
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval    CfgCtrAddr                 Offset of Pci config control
+                                        0 if Device and Function do not correspond to Serial IO
+**/
+UINT16
+GetSerialIoConfigControlOffset (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER  Controller;
+  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
+
+  ControllerMax = GetPchMaxSerialIoControllersNum ();
+
+  for (Controller = 0; Controller < ControllerMax; Controller++) {
+    if ((DeviceNumber == GetSerialIoDeviceNumber (Controller)) &&
+        (FunctionNumber == GetSerialIoFunctionNumber (Controller))) {
+      return mPchSerialIoPciCfgCtrAddr[Controller];
+    }
+  }
+
+  return 0;
+}
+
+/**
+  Checks if Device with given AcpiHid string is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  AcpiHid                   String
+  @param[out] Number                    Number of SerialIo controller
+
+  @retval TRUE                          yes it is a SerialIo controller
+  @retval FALSE                         no it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoAcpiHid (
+  IN CHAR8                      *AcpiHid,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Controller;
+  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
+
+  ControllerMax = GetPchMaxSerialIoControllersNum ();
+
+  for (Controller = 0; Controller < ControllerMax; Controller++) {
+    if (!AsciiStrCmp ((const CHAR8 *) AcpiHid, GetSerialIoAcpiHid(Controller))) {
+      *Number = Controller;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Finds BAR values of SerialIo devices.
+  SerialIo devices can be configured to not appear on PCI so traditional method of reading BAR might not work.
+  If the SerialIo device is in PCI mode, a request for BAR1 will return its PCI CFG space instead
+
+  @param[in] SerialIoDevice             Serial IO device
+  @param[in] BarNumber                  0=BAR0, 1=BAR1
+
+  @retval                               SerialIo Bar value
+**/
+UINTN
+FindSerialIoBar (
+  IN PCH_SERIAL_IO_CONTROLLER           SerialIoDevice,
+  IN UINT8                              BarNumber
+  )
+{
+  UINT64   Bar;
+  UINT64   PcieBase;
+  UINT64   PciSegBase;
+  UINT16   VenId;
+  UINT32   Device;
+  UINT32   Function;
+
+  Device   = GetSerialIoDeviceNumber (SerialIoDevice);
+  Function = GetSerialIoFunctionNumber (SerialIoDevice);
+
+  PcieBase = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_PCIEXBAR)); // S0:B0:D0:F0:R60
+  PcieBase = (PcieBase & PCIEX_BAR_ADDR_MASK) + LShiftU64 (DEFAULT_PCI_BUS_NUMBER_PCH, 20) + LShiftU64 (Device, 15) + LShiftU64 (Function, 12);
+
+  PciSegBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 Device,
+                 Function,
+                 0
+                 );
+
+  VenId = PciSegmentRead16 (PciSegBase + PCI_VENDOR_ID_OFFSET) & 0xFFFF;
+  if (VenId == V_PCH_INTEL_VENDOR_ID) {
+    if (BarNumber == 1) {
+      return ((UINTN) PcieBase);
+    }
+    Bar = PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET);
+    // For 64-Bit Memory Space BARs ((BAR[x] & 0xFFFFFFF0) + ((BAR[x+1] & 0xFFFFFFFF) << 32)
+    if ((Bar & B_PCI_BAR_MEMORY_TYPE_MASK) == B_PCI_BAR_MEMORY_TYPE_64) {
+      Bar = (Bar & 0xFFFFF000) + (UINTN) ((UINT64) LShiftU64 ((PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET + 4) & 0xFFFFFFFF), 32));
+      return (UINTN) Bar;
+    }
+    return (UINTN) (Bar & 0xFFFFF000);
+  }
+  //PCI mode failed? Try hardcoded addresses from ACPI
+  if (BarNumber == 0) {
+    Bar = mSerialIoAcpiAddress[SerialIoDevice].Bar0;
+  } else {
+    Bar = mSerialIoAcpiAddress[SerialIoDevice].Bar1;
+  }
+  return (UINTN) Bar;
+}
+
+/**
+  Get PSF_PORT for a given Serial IO Controller
+
+  @param[in] Controller    Serial IO controller number
+**/
+STATIC
+PSF_PORT
+SerialIoPsfPort (
+  IN PCH_SERIAL_IO_CONTROLLER Controller
+  )
+{
+  switch (GetSerialIoControllerType (Controller)) {
+    case SERIAL_IO_I2C:
+      return PsfSerialIoI2cPort (Controller - PchSerialIoIndexI2C0);
+    case SERIAL_IO_SPI:
+      return PsfSerialIoSpiPort (Controller - PchSerialIoIndexSpi0);
+    case SERIAL_IO_UART:
+      return PsfSerialIoUartPort (Controller - PchSerialIoIndexUart0);
+    case SERIAL_IO_UNKNOWN:
+    default:
+      return (PSF_PORT){0};
+  }
+}
+
+/**
+  Configures Serial IO Controller
+
+  @param[in] Controller    Serial IO controller number
+  @param[in] DeviceMode    Device operation mode
+  @param[in] PsfDisable    Disable device at PSF level
+
+  @retval None
+**/
+VOID
+ConfigureSerialIoController (
+  IN PCH_SERIAL_IO_CONTROLLER Controller,
+  IN PCH_SERIAL_IO_MODE       DeviceMode,
+  IN BOOLEAN                  PsfDisable
+  )
+{
+  UINT64          PciCfgBase;
+  UINT32          Data32And;
+  UINT32          Data32Or;
+  UINT16          *SerialIoPciCfgCtrAddr;
+  UINT8           Uart8BitLoop;
+
+/*
+  Please do not add DEBUG message here because this routine is configuring SerialIoUart.
+  Printing DEBUG message before SerialIoUart initialization may cause system hang (in Debug build).
+*/
+
+  //
+  // This is to prevent from overflow of array access.
+  //
+  if (Controller >= PCH_MAX_SERIALIO_CONTROLLERS) {
+    return;
+  }
+
+  if (GetSerialIoControllerType (Controller) == SERIAL_IO_UNKNOWN) {
+    return;
+  }
+
+  PciCfgBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 GetSerialIoDeviceNumber (Controller),
+                 GetSerialIoFunctionNumber (Controller),
+                 0
+                 );
+  //
+  // Do not modify a device that has already been disabled/hidden
+  //
+  if (PciSegmentRead16 (PciCfgBase + PCI_VENDOR_ID_OFFSET) != V_PCH_INTEL_VENDOR_ID) {
+    return;
+  }
+
+  ///
+  /// Step 0. set Bit 16,17,18.
+  ///
+  PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_D0I3MAXDEVPG, BIT18 | BIT17 | BIT16);
+
+  SerialIoPciCfgCtrAddr = mPchSerialIoPciCfgCtrAddr;
+
+  switch (DeviceMode) {
+    case PchSerialIoDisabled:
+      ///
+      /// Step 1. Put device in D3
+      /// Step 2. Function Disable in PSF
+      ///
+      PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0);
+
+      if (PsfDisable) {
+        PsfDisableDevice (SerialIoPsfPort (Controller));
+      }
+      break;
+    case PchSerialIoAcpi:
+    case PchSerialIoHidden:
+      ///
+      /// reenable BAR1 in case it was disabled earlier
+      /// Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS),
+        0
+        );
+      PsfEnableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2);
+      ///
+      /// Step 1. Assign BAR0
+      /// Step 2. Assign BAR1
+      ///
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,  mSerialIoAcpiAddress[Controller].Bar0);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_LOW,  mSerialIoAcpiAddress[Controller].Bar1);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_HIGH, 0x0);
+      ///
+      /// Step 3. Set Memory space Enable
+      ///
+      PciSegmentOr32 (PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+      ///
+      /// Step 4. Disable device's PciCfg and enable ACPI interrupts
+      ///         Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        ~0u,
+        (B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS | B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN)
+        );
+      ///
+      /// Step 5. Disable device's PciCfg in PSF
+      ///
+      PsfHideDevice (SerialIoPsfPort (Controller));
+      ///
+      /// get controller out of reset
+      ///
+      MmioOr32 (
+        mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_RESETS,
+        B_SERIAL_IO_MEM_PPR_RESETS_FUNC | B_SERIAL_IO_MEM_PPR_RESETS_APB | B_SERIAL_IO_MEM_PPR_RESETS_IDMA
+        );
+      break;
+    case PchSerialIoPci:
+      //
+      //  Check If device is already initialized
+      //
+      if (PciSegmentRead32 (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFF000) {
+        return;
+      }
+      ///
+      /// reenable PciCfg in case it was disabled earlier
+      /// Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS | B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN),
+        0
+        );
+      PsfUnhideDevice (SerialIoPsfPort (Controller));
+      ///
+      /// Disable Bar1
+      /// Disable Bar1 in PSF
+      /// Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        ~0u,
+        B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS
+        );
+      PsfDisableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2);
+
+      //
+      // Assign BAR0 and Set Memory space Enable
+      //
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,  mSerialIoAcpiAddress[Controller].Bar0);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
+      PciSegmentOr32    (PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+      ///
+      /// get controller out of reset
+      ///
+      MmioOr32 (
+        mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_RESETS,
+        B_SERIAL_IO_MEM_PPR_RESETS_FUNC | B_SERIAL_IO_MEM_PPR_RESETS_APB | B_SERIAL_IO_MEM_PPR_RESETS_IDMA
+        );
+      break;
+    default:
+      return;
+  }
+
+  ///
+  /// Step X. Program clock dividers for UARTs
+  /// Step Y. Enable Byte addressing for UARTs in legacy mode
+  ///
+  if ((Controller >= PchSerialIoIndexUart0 && Controller <= PchSerialIoIndexUart2) && (DeviceMode != PchSerialIoDisabled)) {
+    MmioWrite32 (mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_CLK,
+      (B_SERIAL_IO_MEM_PPR_CLK_UPDATE | (V_SERIAL_IO_MEM_PPR_CLK_N_DIV << 16) |
+       (V_SERIAL_IO_MEM_PPR_CLK_M_DIV << 1) | B_SERIAL_IO_MEM_PPR_CLK_EN )
+      );
+
+    Data32And = (UINT32) (~(B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << (Controller - PchSerialIoIndexUart0)));
+    Data32Or = 0x0;
+    if (DeviceMode == PchSerialIoHidden) {
+      Data32Or = (B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << (Controller - PchSerialIoIndexUart0));
+    }
+    PchPcrAndThenOr32 (PID_SERIALIO, R_SERIAL_IO_PCR_GPPRVRW7,Data32And,Data32Or);
+    //
+    // Dummy read after setting any of GPPRVRW7.
+    // Required for UART 16550 8-bit Legacy mode to become active
+    //
+    MmioRead32 (mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_CLK);
+    //
+    // Loop until Uart has successfuly moved to 8 bit mode
+    //
+    if (DeviceMode == PchSerialIoHidden) {
+      Uart8BitLoop = 10;
+      while (Uart8BitLoop > 0) {
+        if (DetectAccessMode (mSerialIoAcpiAddress[Controller].Bar0) == AccessMode8bit) {
+          return;
+        }
+        Uart8BitLoop--;
+      }
+    }
+  }
+
+  ///
+  /// Step Z. Program I2C SDA hold registers
+  ///
+  if (Controller >= PchSerialIoIndexI2C0 && Controller <= GetMaxI2cNumber ()) {
+    if (DeviceMode != PchSerialIoDisabled) {
+      MmioOr32 (mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_I2C_SDA_HOLD, V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE);
+    }
+  }
+
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c
new file mode 100644
index 0000000000..28ccd626af
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c
@@ -0,0 +1,181 @@
+/** @file
+  PCH Serial IO Lib implementation Cannon Lake specific.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <IndustryStandard/Pci30.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+
+#include <PchLimits.h>
+#include <Register/PchRegsSerialIoCnl.h>
+#include "PchSerialIoLibInternal.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mCnlAcpiHid[PCH_MAX_SERIALIO_CONTROLLERS][SERIALIO_HID_LENGTH] =
+{
+  "INT34B2",
+  "INT34B3",
+  "INT34B4",
+  "INT34B5",
+  "INT34B6",
+  "INT34B7",
+  "INT34B0",
+  "INT34B1",
+  "INT34BC",
+  "INT34B8",
+  "INT34B9",
+  "INT34BA"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchLpSerialIoId [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchHSerialIoId [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID,
+                                         0,
+                                         0,
+  V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_BDF_NUMBERS mSerialIoBdf [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2}
+};
+
+
+/**
+  Returns index of the last i2c controller
+
+  @param[in] Number                     Number of SerialIo controller
+
+  @retval                               Index of I2C controller
+**/
+PCH_SERIAL_IO_CONTROLLER
+GetMaxI2cNumber (
+  VOID
+  )
+{
+  if (IsPchH ()) {
+    return PchSerialIoIndexI2C3;
+  } else {
+    return PchSerialIoIndexI2C5;
+  }
+}
+
+/**
+  Checks if Device with given PciDeviceId is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  PciDevId                  Device ID
+  @param[out] Number                    Number of SerialIo controller
+
+  @retval TRUE                          Yes it is a SerialIo controller
+  @retval FALSE                         No it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoPciDevId (
+  IN  UINT16                    PciDevId,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Controller;
+
+  for (Controller = 0; Controller < GetPchMaxSerialIoControllersNum (); Controller++) {
+    if ((IsPchLp () && (PciDevId == mCnlPchLpSerialIoId[Controller])) ||
+        (IsPchH () && (PciDevId == mCnlPchHSerialIoId[Controller])))
+    {
+      *Number = Controller;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Finds PCI Device Number of SerialIo devices.
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo device number
+**/
+UINT8
+GetSerialIoDeviceNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  )
+{
+  return mSerialIoBdf[SerialIoNumber].DevNum;
+}
+
+/**
+  Finds PCI Function Number of SerialIo devices.
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo funciton number
+**/
+UINT8
+GetSerialIoFunctionNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  )
+{
+  return mSerialIoBdf[SerialIoNumber].FuncNum;
+}
+
+/**
+  Returns string with AcpiHid assigned to selected SerialIo controller
+
+  @param[in] Number                     Number of SerialIo controller
+
+  @retval                               pointer to 8-byte string
+**/
+CHAR8*
+GetSerialIoAcpiHid (
+  IN PCH_SERIAL_IO_CONTROLLER Number
+  )
+{
+  return mCnlAcpiHid[Number];
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c
new file mode 100644
index 0000000000..621a473cfa
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c
@@ -0,0 +1,372 @@
+/** @file
+  PCH Serial IO UART Lib implementation.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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/PchPcrLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchSerialIoUartLib.h>
+#include <IndustryStandard/Pci30.h>
+
+#define MAX_BAUD_RATE      115200
+
+#define R_PCH_SERIAL_IO_8BIT_UART_RXBUF      0x00
+#define R_PCH_SERIAL_IO_8BIT_UART_TXBUF      0x00
+#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW   0x00
+#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH  0x01
+#define R_PCH_SERIAL_IO_8BIT_UART_FCR        0x02
+#define R_PCH_SERIAL_IO_8BIT_UART_IIR        0x02
+#define R_PCH_SERIAL_IO_8BIT_UART_LCR        0x03
+#define R_PCH_SERIAL_IO_8BIT_UART_MCR        0x04
+#define R_PCH_SERIAL_IO_8BIT_UART_LSR        0x05
+#define R_PCH_SERIAL_IO_8BIT_UART_USR        0x1F
+#define R_PCH_SERIAL_IO_32BIT_UART_CTR       0xFC //Component Type Register contains identification code
+#define UART_COMPONENT_IDENTIFICATION_CODE   0x44570110
+
+#define B_PCH_SERIAL_IO_UART_IIR_FIFOSE   BIT7|BIT6
+#define B_PCH_SERIAL_IO_UART_LSR_RXDA     BIT0
+#define B_PCH_SERIAL_IO_UART_LSR_BI       BIT4
+#define B_PCH_SERIAL_IO_UART_LSR_TXRDY    BIT5
+#define B_PCH_SERIAL_IO_UART_LCR_DLAB     BIT7
+#define B_PCH_SERIAL_IO_UART_FCR_FCR      BIT0
+#define B_PCH_SERIAL_IO_UART_MCR_RTS      BIT1
+#define B_PCH_SERIAL_IO_UART_MCR_AFCE     BIT5
+#define B_PCH_SERIAL_IO_UART_USR_TFNF     BIT1
+
+/**
+  Returns UART's currently active access mode, 8 or 32 bit
+
+  @param[in]  MmioBase    Base address of UART MMIO space
+
+  @retval     AccessMode8bit
+  @retval     AccessMode32bit
+**/
+UART_ACCESS_MODE
+DetectAccessMode (
+  IN UINTN  MmioBase
+  )
+{
+  if (MmioRead32 (MmioBase + R_PCH_SERIAL_IO_32BIT_UART_CTR) == UART_COMPONENT_IDENTIFICATION_CODE) {
+    return AccessMode32bit;
+  } else {
+    return AccessMode8bit;
+  }
+}
+
+
+/**
+  Register access helper. Depending on SerialIO UART mode,
+  its registers are aligned to 1 or 4 bytes and have 8 or 32bit size
+
+  @param[in]  AccessMode     Selects between 8bit access to 1-byte aligned registers or 32bit access to 4-byte algined
+  @param[in]  BaseAddress    Base address of UART MMIO space
+  @param[in]  Offset         Register offset in 8bit mode
+  @param[in]  Data           Data to be written
+**/
+STATIC
+VOID
+WriteRegister (
+  IN UART_ACCESS_MODE AccessMode,
+  IN UINTN            BaseAddress,
+  IN UINTN            Offset,
+  IN UINT8            Data
+  )
+{
+  if (AccessMode == AccessMode32bit) {
+    MmioWrite32 (BaseAddress + 4*Offset, Data);
+  } else {
+    MmioWrite8 (BaseAddress + Offset, Data);
+  }
+}
+
+/**
+  Register access helper. Depending on SerialIO UART mode,
+  its registers are aligned to 1 or 4 bytes and have 8 or 32bit size
+
+  @param[in]  AccessMode     Selects between 8bit access to 1-byte aligned registers or 32bit access to 4-byte algined
+  @param[in]  BaseAddress    Base address of UART MMIO space
+  @param[in]  Offset         Register offset in 8bit mode
+  @retval                    retrieved register value, always 8bit regardless of access mode
+**/
+STATIC
+UINT8
+ReadRegister (
+  IN UART_ACCESS_MODE AccessMode,
+  IN UINTN            BaseAddress,
+  IN UINTN            Offset
+  )
+{
+  if (AccessMode == AccessMode32bit) {
+    return (UINT8) (0xFF & MmioRead32 (BaseAddress + 4*Offset));
+  } else {
+    return MmioRead8 (BaseAddress + Offset);
+  }
+}
+
+/**
+  SerialIo UART in PCI mode will become unavailable when PCI enumerator
+  disables its memory space. This function re-enables it
+
+  @param[in]  UartNumber           Selects Serial IO UART device (0-2)
+**/
+STATIC
+VOID
+EnablePciMse (
+  IN UINT8  UartNumber
+  )
+{
+  UINTN  CfgSpace;
+
+  CfgSpace = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 1);
+  if (MmioRead16 (CfgSpace + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+  if ((MmioRead16 (CfgSpace + PCI_COMMAND_OFFSET) & EFI_PCI_COMMAND_MEMORY_SPACE) != EFI_PCI_COMMAND_MEMORY_SPACE) {
+    if ((MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFF000) != 0x0 &&
+        (MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFF000) != 0xFFFFF000 ) {
+      MmioOr8 (CfgSpace + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+    }
+  }
+}
+
+/**
+  Initialize selected SerialIo UART.
+  This init function MUST be used prior any SerialIo UART functions to init serial io controller if platform is going use serialio UART as debug output.
+
+  @param  UartNumber           Selects Serial IO UART device (0-2)
+  @param  FifoEnable           When TRUE, enables 64-byte FIFOs.
+  @param  BaudRate             Baud rate.
+  @param  LineControl          Data length, parity, stop bits.
+  @param  HardwareFlowControl  Automated hardware flow control. If TRUE, hardware automatically checks CTS when sending data, and sets RTS when receiving data.
+**/
+VOID
+EFIAPI
+PchSerialIoUartInit (
+  UINT8            UartNumber,
+  BOOLEAN          FifoEnable,
+  UINT32           BaudRate,
+  UINT8            LineControl,
+  BOOLEAN          HardwareFlowControl
+  )
+{
+  UINTN            Base;
+  UINTN            Divisor;
+  UART_ACCESS_MODE AccessMode;
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    //
+    // Base is not programmed, skip it.
+    //
+    return;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  Divisor = MAX_BAUD_RATE / BaudRate;
+
+  //
+  // Configure baud rate
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR, B_PCH_SERIAL_IO_UART_LCR_DLAB);
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
+  //
+  //  Configure Line control and switch back to bank 0
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR, LineControl & 0x1F);
+  //
+  // Enable and reset FIFOs
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_FCR, FifoEnable?B_PCH_SERIAL_IO_UART_FCR_FCR:0 );
+  //
+  // Put Modem Control Register(MCR) into its reset state of 0x00.
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_MCR, B_PCH_SERIAL_IO_UART_MCR_RTS | (HardwareFlowControl?B_PCH_SERIAL_IO_UART_MCR_AFCE:0));
+}
+
+/**
+  Write data to serial device.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param  UartNumber       Selects Serial IO UART device (0-2)
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval                  Actual number of bytes writed to serial device.
+**/
+UINTN
+EFIAPI
+PchSerialIoUartOut (
+  IN UINT8            UartNumber,
+  IN UINT8            *Buffer,
+  IN UINTN            NumberOfBytes
+  )
+{
+  UINTN            BytesLeft;
+  UINTN            Base;
+  UART_ACCESS_MODE AccessMode;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  //
+  // Sanity checks to avoid infinite loop when trying to print through uninitialized UART
+  //
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    return 0;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) == 0xFF) {
+    return 0;
+  }
+
+  BytesLeft = NumberOfBytes;
+
+  while (BytesLeft != 0) {
+    //
+    // Write data while there's room in TXFIFO. If HW Flow Control was enabled, it happens automatically on hardware level.
+    //
+    if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) & B_PCH_SERIAL_IO_UART_USR_TFNF) {
+      WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_TXBUF, *Buffer);
+      Buffer++;
+      BytesLeft--;
+    }
+  }
+
+  return NumberOfBytes;
+}
+
+/*
+  Read data from serial device and save the datas in buffer.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param  UartNumber           Selects Serial IO UART device (0-2)
+  @param  Buffer               Point of data buffer which need to be writed.
+  @param  NumberOfBytes        Number of output bytes which are cached in Buffer.
+  @param  WaitUntilBufferFull  When TRUE, function waits until whole buffer is filled. When FALSE, function returns as soon as no new characters are available.
+
+  @retval                      Actual number of bytes raed to serial device.
+
+**/
+UINTN
+EFIAPI
+PchSerialIoUartIn (
+  IN  UINT8            UartNumber,
+  OUT UINT8            *Buffer,
+  IN  UINTN            NumberOfBytes,
+  IN  BOOLEAN          WaitUntilBufferFull
+  )
+{
+  UINTN            BytesReceived;
+  UINTN            Base;
+  UART_ACCESS_MODE AccessMode;
+  UINT8            Lsr;
+  UINT8            Byte;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  //
+  // Sanity checks to avoid infinite loop when trying to print through uninitialized UART
+  //
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    return 0;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  BytesReceived = 0;
+
+  while (BytesReceived != NumberOfBytes) {
+    //
+    // Read the line status register
+    //
+    Lsr = ReadRegister(AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LSR);
+
+    //
+    // If there is data in the RX buffer, read it.
+    //
+    if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_RXDA) != 0) {
+      Byte = ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_RXBUF);
+      //
+      // Check if the break interrupt bit is set. If set, the byte read from the
+      // RX buffer is invalid and should be ignored. If not set, copy the byte into
+      // the receive buffer.
+      //
+      if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_BI) == 0) {
+        *Buffer = Byte;
+        Buffer++;
+        BytesReceived++;
+      }
+    } else {
+      if (!WaitUntilBufferFull) {
+        //
+        // If there's no data and function shouldn't wait, exit early
+        //
+        return BytesReceived;
+      }
+    }
+  }
+  return BytesReceived;
+}
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+
+  Polls a serial device to see if there is any data waiting to be read.
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @param  UartNumber       Selects Serial IO UART device (0-2)
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+PchSerialIoUartPoll (
+  IN  UINT8            UartNumber
+  )
+{
+  UINTN Base;
+  UART_ACCESS_MODE AccessMode;
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  //
+  // Sanity checks to avoid infinite loop when trying to print through uninitialized UART
+  //
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    return 0;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  //
+  // Read the serial port status
+  //
+  if ((ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LSR) & B_PCH_SERIAL_IO_UART_LSR_RXDA) != 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c
new file mode 100644
index 0000000000..679dcae0ab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c
@@ -0,0 +1,242 @@
+/** @file
+  Library that contains common parts of WdtPei and WdtDxe. Not a standalone module.
+
+  Copyright (c) 2019 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/PmcLib.h>
+#include <Register/PchRegsPmc.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8     mAllowExpectedReset = 0;
+
+/**
+  Reads LPC bridge to get Watchdog Timer address
+
+
+  @retval UINT32                  Watchdog's address
+**/
+UINT32
+WdtGetAddress (
+  VOID
+  )
+{
+  return PmcGetAcpiBase () + R_ACPI_IO_OC_WDT_CTL;
+}
+
+/**
+  Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+  causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+  function was called too.
+
+  @param[in] TimeoutValue         Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+  @retval EFI_SUCCESS             if everything's OK
+  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
+**/
+EFI_STATUS
+EFIAPI
+WdtReloadAndStart (
+  IN  UINT32  TimeoutValue
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "\n(Wdt) ReloadAndStartTimer(%d)\n", TimeoutValue));
+
+  if ((TimeoutValue > B_ACPI_IO_OC_WDT_CTL_TOV_MASK) || (TimeoutValue == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Readback = IoRead32 (WdtGetAddress ());
+  Readback |= (B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_ICCSURV);
+  if (mAllowExpectedReset == 0) {
+    Readback |= B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS;
+  }
+
+  if (PcdGetBool (PcdOcEnableWdtforDebug) == FALSE) {
+    ///
+    /// WDT will not be turned on. This is to prevent platform reboots triggered
+    /// by WDT expiration, which can be expected when processor is halted for debugging
+    ///
+    Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+    DEBUG ((DEBUG_INFO, "(Wdt) Wdt disabled in Debug BIOS\n"));
+  }
+
+  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
+  Readback |= ((TimeoutValue - 1) & B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
+  IoWrite32 (WdtGetAddress (), Readback);
+  Readback |= B_ACPI_IO_OC_WDT_CTL_RLD;
+  IoWrite32 (WdtGetAddress (), Readback);
+  return EFI_SUCCESS;
+}
+
+/**
+  Disables WDT timer.
+
+
+**/
+VOID
+EFIAPI
+WdtDisable (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) DisableTimer\n"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+  IoWrite32 (WdtGetAddress (), Readback);
+}
+
+/**
+  Returns WDT failure status.
+
+
+  @retval V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE   If there was WDT expiration or unexpected reset
+  @retval V_ACPI_IO_OC_WDT_CTL_STATUS_OK        Otherwise
+**/
+UINT8
+EFIAPI
+WdtCheckStatus (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) CheckTimerStatus\n"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+  DEBUG ((DEBUG_INFO, "(Wdt) Readback = (%x)\n", Readback));
+
+  if (Readback & B_ACPI_IO_OC_WDT_CTL_FAILURE_STS) {
+    DEBUG ((DEBUG_INFO, "(Wdt) Status = FAILURE\n"));
+    return V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE;
+  } else {
+    return V_ACPI_IO_OC_WDT_CTL_STATUS_OK;
+  }
+}
+
+/**
+  Normally, each reboot performed while watchdog runs is considered a failure.
+  This function allows platform to perform expected reboots with WDT running,
+  without being interpreted as failures.
+  In DXE phase, it is enough to call this function any time before reset.
+  In PEI phase, between calling this function and performing reset, ReloadAndStart()
+  must not be called.
+
+
+**/
+VOID
+EFIAPI
+WdtAllowKnownReset (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) AllowKnownReset\n"));
+
+  mAllowExpectedReset = 1;
+
+  Readback  = IoRead32 (WdtGetAddress ());
+  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL);
+  IoWrite32 (WdtGetAddress (), Readback);
+}
+
+/**
+  Returns information if WDT coverage for the duration of BIOS execution
+  was requested by an OS application
+
+
+  @retval TRUE                    if WDT was requested
+  @retval FALSE                   if WDT was not requested
+**/
+UINT8
+EFIAPI
+IsWdtRequired (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtRequired"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+
+  if ((Readback & B_ACPI_IO_OC_WDT_CTL_AFTER_POST) != 0) {
+    DEBUG ((DEBUG_INFO, " - yes\n"));
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_INFO, " - no\n"));
+    return FALSE;
+  }
+
+}
+
+/**
+  Returns WDT enabled/disabled status.
+
+
+  @retval TRUE                    if WDT is enabled
+  @retval FALSE                   if WDT is disabled
+**/
+UINT8
+EFIAPI
+IsWdtEnabled (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtEnabled"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+
+  if ((Readback & B_ACPI_IO_OC_WDT_CTL_EN) != 0) {
+    DEBUG ((DEBUG_INFO, " - yes\n"));
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_INFO, " - no\n"));
+    return FALSE;
+  }
+
+}
+
+/**
+  Returns WDT locked status.
+
+
+  @retval TRUE                    if WDT is locked
+  @retval FALSE                   if WDT is unlocked
+**/
+UINT8
+EFIAPI
+IsWdtLocked (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtLocked"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+
+  if ((Readback & B_ACPI_IO_OC_WDT_CTL_LCK) != 0) {
+    DEBUG ((DEBUG_INFO, " - yes\n"));
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_INFO, " - no\n"));
+    return FALSE;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
new file mode 100644
index 0000000000..8e026b3ab6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
@@ -0,0 +1,330 @@
+/** @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) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegsPmc.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);
+}
+
+/**
+  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 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 RTC 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_B) & 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 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);
+}
+
+/**
+  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);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
new file mode 100644
index 0000000000..05557931c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
@@ -0,0 +1,41 @@
+/** @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) 2019 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>
+/**
+  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
+GetSataRegBase (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           GetSataPcieDeviceNum (SataCtrlIndex),
+           GetSataPcieFunctionNum (SataCtrlIndex),
+           0
+           );
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c
new file mode 100644
index 0000000000..5cec818dd6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c
@@ -0,0 +1,101 @@
+/** @file
+  Pch SATA library for CedarFork SouthCluster.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PchInfoLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsSata.h>
+#include <Library/SataLib.h>
+
+/**
+  Get Maximum Sata Controller Number
+
+  @param[in] None
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+GetPchMaxSataControllerNum (
+  VOID
+  )
+{
+  return 3;
+}
+
+/**
+  Get Pch Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval Pch Maximum Sata Port Number
+**/
+UINT8
+GetPchMaxSataPortNum (
+  IN UINT8      SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return 8;
+}
+
+/**
+  Get SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+GetSataPcieDeviceNum (
+  IN UINT8  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_1;
+  } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_2;
+  } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_3;
+  } else {
+    ASSERT (FALSE);
+    return 0;
+  }
+}
+
+/**
+  Get SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+GetSataPcieFunctionNum (
+  IN UINT8  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1;
+  } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2;
+  } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3;
+  } else {
+    ASSERT (FALSE);
+    return 0;
+  }
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c
new file mode 100644
index 0000000000..0eca692a74
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c
@@ -0,0 +1,88 @@
+/** @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) 2019 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/PchRegsSata.h>
+#include <Library/SataLib.h>
+
+/**
+  Get Maximum Sata Controller Number
+
+  @param[in] None
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+GetPchMaxSataControllerNum (
+  VOID
+  )
+{
+  return 1;
+}
+
+/**
+  Get Pch Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval Pch Maximum Sata Port Number
+**/
+UINT8
+GetPchMaxSataPortNum (
+  IN UINT32      SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  if (IsPchLp ()) {
+    return 3;
+  } else {
+    return 8;
+  }
+}
+
+/**
+  Get SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+GetSataPcieDeviceNum (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return PCI_DEVICE_NUMBER_PCH_SATA;
+}
+
+/**
+  Get SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+GetSataPcieFunctionNum (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return PCI_FUNCTION_NUMBER_PCH_SATA;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
new file mode 100644
index 0000000000..22f6fb215f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
@@ -0,0 +1,130 @@
+/** @file
+  The PEI Library Implements OcWdt Support.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/Wdt.h>
+#include <Library/PchWdtCommonLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/IoLib.h>
+#include <Register/PchRegsPmc.h>
+
+static WDT_PPI mWdtPpi = {
+  WdtReloadAndStart,
+  WdtCheckStatus,
+  WdtDisable,
+  WdtAllowKnownReset,
+  IsWdtRequired,
+  IsWdtEnabled
+};
+
+static EFI_PEI_PPI_DESCRIPTOR  mInstallWdtPpi = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gWdtPpiGuid,
+  &mWdtPpi
+};
+
+/**
+  Reads PCH registers to check if platform wakes from S3/S4
+
+  @retval TRUE                    if platfrom wakes from S3/S4
+  @retval FALSE                   otherwise
+**/
+BOOLEAN
+IsWakeFromS3S4 (
+  VOID
+  )
+{
+  PMC_SLEEP_STATE  SleepType;
+
+  SleepType = PmcGetSleepTypeAfterWake ();
+  if ((SleepType == PmcS3SleepState) || (SleepType == PmcS4SleepState)) {
+    return TRUE;
+  }
+
+  return FALSE;
+
+}
+
+/**
+  Check for unexpected reset.
+  If there was an unexpected reset, enforces WDT expiration.
+**/
+VOID
+OcWdtResetCheck (
+  VOID
+  )
+{
+  UINT32      Readback;
+
+  Readback = IoRead32 (WdtGetAddress ());
+  DEBUG ((DEBUG_INFO, "(WDT) OcWdtResetCheck()\n"));
+
+  ///
+  /// If there was a WDT expiration, set Failure Status and clear timeout status bits
+  /// Timeout status bits are cleared by writing '1'
+  ///
+  if (Readback & (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS)) {
+    DEBUG ((DEBUG_ERROR, "(WDT) Expiration detected.\n", Readback));
+    Readback |= B_ACPI_IO_OC_WDT_CTL_FAILURE_STS;
+    Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
+    Readback &= ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+  } else {
+    ///
+    /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
+    /// clear unexpected reset status and enforce expiration. This is to inform Firmware
+    /// which has no access to unexpected reset status bit, that something went wrong.
+    ///
+    if ((Readback & B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS) && !IsWakeFromS3S4()) {
+      if (PcdGetBool (PcdOcEnableWdtforDebug)) {
+        DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected and ignored.\n"));
+        Readback &= ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS | B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+        Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
+      } else {
+        DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected. Enforcing Wdt expiration.\n"));
+        WdtReloadAndStart (1);
+        ///
+        /// wait for reboot caused by WDT expiration
+        ///
+        CpuDeadLoop ();
+      }
+    } else {
+      ///
+      /// No WDT expiration and no unexpected reset - clear Failure status
+      ///
+      DEBUG ((DEBUG_INFO, "(WDT) Status OK.\n", Readback));
+      Readback &= ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS);
+      Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
+    }
+  }
+
+  IoWrite32 (WdtGetAddress (), Readback);
+
+  return;
+}
+
+/**
+  This function install WDT PPI
+
+  @retval EFI_STATUS  Results of the installation of the WDT PPI
+**/
+EFI_STATUS
+EFIAPI
+OcWdtInit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PeiServicesInstallPpi (&mInstallWdtPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c
new file mode 100644
index 0000000000..182218ffcf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c
@@ -0,0 +1,23 @@
+/** @file
+  The Null PEI Library Implements OcWdt Support.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+
+/**
+  This function install WDT PPI
+
+  @retval EFI_STATUS  Results of the installation of the WDT PPI
+**/
+EFI_STATUS
+EFIAPI
+OcWdtInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c
new file mode 100644
index 0000000000..bd1e2711da
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c
@@ -0,0 +1,307 @@
+/** @file
+  Print whole PCH_PREMEM_POLICY_PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+
+/**
+  Print PCH_GENERAL_PREMEM_CONFIG and serial out.
+
+  @param[in] PchGeneralPreMemConfig     Pointer to a PCH_GENERAL_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintGeneralPreMemConfig (
+  IN CONST PCH_GENERAL_PREMEM_CONFIG    *PchGeneralPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH General PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Port80Route= %x\n", PchGeneralPreMemConfig->Port80Route));
+}
+
+/**
+  Print PCH_DCI_PREMEM_CONFIG and serial out.
+
+  @param[in] DciPreMemConfig            Pointer to a PCH_DCI_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintDciPreMemConfig (
+  IN CONST PCH_DCI_PREMEM_CONFIG        *DciPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH DCI PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "PlatformDebugConsent = %x\n", DciPreMemConfig->PlatformDebugConsent));
+  DEBUG ((DEBUG_INFO, "DciUsb3TypecUfpDbg = %x\n", DciPreMemConfig->DciUsb3TypecUfpDbg));
+}
+
+/**
+  Print PCH_WDT_PREMEM_CONFIG and serial out.
+
+  @param[in] WdtPreMemConfig            Pointer to a PCH_WDT_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintWdtPreMemConfig (
+  IN CONST PCH_WDT_PREMEM_CONFIG               *WdtPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH WDT PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "DisableAndLock= %x\n", WdtPreMemConfig->DisableAndLock));
+}
+
+/**
+  Print PCH_TRACE_HUB_CONFIG and serial out.
+
+  @param[in] TraceHubConfig             Pointer to a PCH_TRACE_HUB_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintTraceHubPreMemConfig (
+  IN CONST PCH_TRACE_HUB_PREMEM_CONFIG         *PchTraceHubPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH TraceHub PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "EnableMode= %x\n", PchTraceHubPreMemConfig->EnableMode));
+  DEBUG ((DEBUG_INFO, "MemReg0Size= %x\n", PchTraceHubPreMemConfig->MemReg0Size));
+  DEBUG ((DEBUG_INFO, "MemReg1Size= %x\n", PchTraceHubPreMemConfig->MemReg1Size));
+}
+
+/**
+  Print PCH_SMBUS_CONFIG and serial out.
+
+  @param[in] SmbusConfig         Pointer to a PCH_SMBUS_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSmbusPreMemConfig (
+  IN CONST PCH_SMBUS_PREMEM_CONFIG    *SmbusPreMemConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH SMBUS PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", SmbusPreMemConfig->Enable));
+  DEBUG ((DEBUG_INFO, " ArpEnable= %x\n", SmbusPreMemConfig->ArpEnable));
+  DEBUG ((DEBUG_INFO, " DynamicPowerGating= %x\n", SmbusPreMemConfig->DynamicPowerGating));
+  DEBUG ((DEBUG_INFO, " SpdWriteDisable= %x\n", SmbusPreMemConfig->SpdWriteDisable));
+  DEBUG ((DEBUG_INFO, " SmbAlertEnable= %x\n", SmbusPreMemConfig->SmbAlertEnable));
+  DEBUG ((DEBUG_INFO, " SmbusIoBase= %x\n", SmbusPreMemConfig->SmbusIoBase));
+  DEBUG ((DEBUG_INFO, " NumRsvdSmbusAddresses= %x\n", SmbusPreMemConfig->NumRsvdSmbusAddresses));
+  DEBUG ((DEBUG_INFO, " RsvdSmbusAddressTable= {"));
+  for (Index = 0; Index < SmbusPreMemConfig->NumRsvdSmbusAddresses; ++Index) {
+    DEBUG ((DEBUG_INFO, " %02xh", SmbusPreMemConfig->RsvdSmbusAddressTable[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " }\n"));
+}
+
+/**
+  Print PCH_LPC_PREMEM_CONFIG and serial out.
+
+  @param[in] LpcPreMemConfig                  Pointer to a PCH_LPC_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintLpcPreMemConfig (
+  IN CONST PCH_LPC_PREMEM_CONFIG              *LpcPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH LPC PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "EnhancePort8xhDecoding= %x\n", LpcPreMemConfig->EnhancePort8xhDecoding));
+}
+
+/**
+  Print PCH_HSIO_PCIE_PREMEM_CONFIG and serial out.
+
+  @param[in] HsioPciePreMemConfig     Pointer to a PCH_HSIO_PCIE_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintHsioPciePreMemConfig (
+  IN CONST PCH_HSIO_PCIE_PREMEM_CONFIG *HsioPciePreMemConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ HSIO PCIE PreMem Config ------------------\n"));
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtleEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtle= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DownscaleAmpEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DownscaleAmp= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DownscaleAmpEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DownscaleAmp= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen3DownscaleAmpEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen3DownscaleAmp= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmphEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmph= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5Enable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0Enable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0));
+  }
+}
+
+/**
+  Print PCH_HSIO_SATA_PREMEM_CONFIG and serial out.
+
+  @param[in] SataCtrlIndex            SATA controller index
+  @param[in] HsioSataPreMemConfig     Pointer to a PCH_HSIO_SATA_PREMEM_CONFIG that provides the platform setting
+**/
+VOID
+PchPrintHsioSataPreMemConfig (
+  IN UINT8                             SataCtrlIndex,
+  IN CONST PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "---------------- HSIO SATA PreMem Config for controller %d ----------------\n", SataCtrlIndex));
+  for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen1EqBoostMagEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen1EqBoostMag= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen2EqBoostMagEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen2EqBoostMag= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen3EqBoostMagEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen3EqBoostMag= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DownscaleAmpEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DownscaleAmp= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DownscaleAmpEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DownscaleAmp= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DownscaleAmpEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DownscaleAmp= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmphEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmph= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmphEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmph= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmphEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmph= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph));
+  }
+}
+
+/**
+  Print PCH_PCIE_RP_PREMEM_CONFIG and serial out.
+
+  @param[in] PcieRpPreMemConfig        Pointer to a PCH_PCIE_RP_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintPcieRpPreMemConfig (
+  IN CONST PCH_PCIE_RP_PREMEM_CONFIG    *PcieRpPreMemConfig
+  )
+{
+  UINT32 Index;
+  DEBUG ((DEBUG_INFO, "------------------ PCH PCIe RP PreMem Config ------------------\n"));
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " Port[%d] RpEnabled= %x\n", Index, (PcieRpPreMemConfig->RpEnabledMask & (UINT32) (1 << Index)) != 0 ));
+  }
+  DEBUG ((DEBUG_INFO, " PcieImrEnabled= %x\n", PcieRpPreMemConfig->PcieImrEnabled));
+  DEBUG ((DEBUG_INFO, " PcieImrSize= %d MB\n", PcieRpPreMemConfig->PcieImrSize));
+  DEBUG ((DEBUG_INFO, " ImrRpSelection= %d\n", PcieRpPreMemConfig->ImrRpSelection));
+}
+
+/**
+  Print PCH_HDAUDIO_PREMEM_CONFIG and serial out.
+
+  @param[in] LpcPreMemConfig                  Pointer to a PCH_HDAUDIO_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintHdAudioPreMemConfig (
+  IN CONST PCH_HDAUDIO_PREMEM_CONFIG *HdaPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ HD Audio PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", HdaPreMemConfig->Enable));
+}
+
+/**
+  Print PCH_ISH_PREMEM_CONFIG  and serial out.
+
+  @param[in] IshPreMemConfig                  Pointer to a PCH_ISH_PREMEM_CONFIG  that provides the platform setting
+
+**/
+VOID
+PchPrintIshPreMemConfig (
+  IN CONST PCH_ISH_PREMEM_CONFIG *IshPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ ISH PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", IshPreMemConfig->Enable));
+}
+
+
+/**
+  Print whole PCH_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi    The RC PREMEM Policy PPI instance
+
+**/
+VOID
+EFIAPI
+PchPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI     *SiPreMemPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                      Status;
+  PCH_GENERAL_PREMEM_CONFIG       *PchGeneralPreMemConfig;
+  PCH_DCI_PREMEM_CONFIG           *DciPreMemConfig;
+  PCH_WDT_PREMEM_CONFIG           *WdtPreMemConfig;
+  PCH_TRACE_HUB_PREMEM_CONFIG     *PchTraceHubPreMemConfig;
+  PCH_SMBUS_PREMEM_CONFIG         *SmbusPreMemConfig;
+  PCH_LPC_PREMEM_CONFIG           *LpcPreMemConfig;
+  PCH_HSIO_PCIE_PREMEM_CONFIG     *HsioPciePreMemConfig;
+  PCH_HSIO_SATA_PREMEM_CONFIG     *HsioSataPreMemConfig;
+  PCH_PCIE_RP_PREMEM_CONFIG       *PcieRpPreMemConfig;
+  PCH_HDAUDIO_PREMEM_CONFIG       *HdaPreMemConfig;
+  PCH_ISH_PREMEM_CONFIG           *IshPreMemConfig;
+  UINT8                           SataCtrlIndex;
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPreMemPolicyPpi->TableHeader.Header.Revision));
+
+  PchPrintGeneralPreMemConfig (PchGeneralPreMemConfig);
+  PchPrintDciPreMemConfig (DciPreMemConfig);
+  PchPrintWdtPreMemConfig (WdtPreMemConfig);
+  PchPrintTraceHubPreMemConfig (PchTraceHubPreMemConfig);
+  PchPrintSmbusPreMemConfig (SmbusPreMemConfig);
+  PchPrintLpcPreMemConfig (LpcPreMemConfig);
+  PchPrintHsioPciePreMemConfig (HsioPciePreMemConfig);
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++) {
+    HsioSataPreMemConfig = GetPchHsioSataPreMemConfig (SiPreMemPolicyPpi, SataCtrlIndex);
+    PchPrintHsioSataPreMemConfig (SataCtrlIndex, HsioSataPreMemConfig);
+  }
+  PchPrintPcieRpPreMemConfig (PcieRpPreMemConfig);
+  PchPrintHdAudioPreMemConfig (HdaPreMemConfig);
+  PchPrintIshPreMemConfig (IshPreMemConfig);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy End --------------------------\n"));
+  DEBUG_CODE_END ();
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c
new file mode 100644
index 0000000000..d9005b50ef
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c
@@ -0,0 +1,778 @@
+/** @file
+  Print whole PCH_POLICY_PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Private/PchHsio.h>
+
+/**
+  Print USB_CONFIG and serial out.
+
+  @param[in] UsbConfig         Pointer to a USB_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintUsbConfig (
+  IN CONST USB_CONFIG     *UsbConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH USB Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " EnableComplianceMode           = %x\n", UsbConfig->EnableComplianceMode));
+  DEBUG ((DEBUG_INFO, " PdoProgramming                 = %x\n", UsbConfig->PdoProgramming));
+  DEBUG ((DEBUG_INFO, " OverCurrentEnable              = %x\n", UsbConfig->OverCurrentEnable));
+  DEBUG ((DEBUG_INFO, " XhciOcLock                     = %x\n", UsbConfig->XhciOcLock));
+  DEBUG ((DEBUG_INFO, " Usb2PhySusPgEnable             = %x\n", UsbConfig->Usb2PhySusPgEnable));
+
+  for (Index = 0; Index < GetPchUsb2MaxPhysicalPortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Enabled        = %x\n", Index, UsbConfig->PortUsb20[Index].Enable));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].OverCurrentPin = OC%x\n", Index, UsbConfig->PortUsb20[Index].OverCurrentPin));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Petxiset   = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Petxiset));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Txiset     = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Txiset));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Predeemp   = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Predeemp));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Pehalfbit  = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Pehalfbit));
+  }
+
+  for (Index = 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d] Enabled                  = %x\n", Index, UsbConfig->PortUsb30[Index].Enable));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].OverCurrentPin           = OC%x\n", Index, UsbConfig->PortUsb30[Index].OverCurrentPin));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmphEnable       = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmph             = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDeEmph));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmpEnable = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmp       = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp));
+
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfgEnable    = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfg          = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelNEnable            = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelN                  = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelPEnable            = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelP                  = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnResEnable  = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnRes        = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes));
+  }
+
+  DEBUG ((DEBUG_INFO, " XdciConfig.Enable= %x\n", UsbConfig->XdciConfig.Enable));
+
+}
+
+/**
+  Print PCH_PCIE_CONFIG and serial out.
+
+  @param[in] PcieConfig         Pointer to a PCH_PCIE_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintPcieConfig (
+  IN CONST PCH_PCIE_CONFIG      *PcieConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH PCIE Config ------------------\n"));
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HotPlug= %x\n", Index, PcieConfig->RootPort[Index].HotPlug));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PmSci= %x\n", Index, PcieConfig->RootPort[Index].PmSci));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] ExtSync= %x\n", Index, PcieConfig->RootPort[Index].ExtSync));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] ClkReqDetect= %x\n", Index, PcieConfig->RootPort[Index].ClkReqDetect));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] UnsupportedRequestReport= %x\n", Index, PcieConfig->RootPort[Index].UnsupportedRequestReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] FatalErrorReport= %x\n", Index, PcieConfig->RootPort[Index].FatalErrorReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NoFatalErrorReport= %x\n", Index, PcieConfig->RootPort[Index].NoFatalErrorReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] CorrectableErrorReport= %x\n", Index, PcieConfig->RootPort[Index].CorrectableErrorReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnFatalError= %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnFatalError));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnNonFatalError= %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnNonFatalError));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnCorrectableError= %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnCorrectableError));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] MaxPayload= %x\n", Index, PcieConfig->RootPort[Index].MaxPayload));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotImplemented= %x\n", Index, PcieConfig->RootPort[Index].SlotImplemented));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] AcsEnabled= %x\n", Index, PcieConfig->RootPort[Index].AcsEnabled));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PtmEnabled= %x\n", Index, PcieConfig->RootPort[Index].PtmEnabled));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] AdvancedErrorReporting= %x\n", Index, PcieConfig->RootPort[Index].AdvancedErrorReporting));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] TransmitterHalfSwing= %x\n", Index, PcieConfig->RootPort[Index].TransmitterHalfSwing));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PcieSpeed= %x\n", Index, PcieConfig->RootPort[Index].PcieSpeed));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Gen3EqPh3Method= %x\n", Index, PcieConfig->RootPort[Index].Gen3EqPh3Method));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PhysicalSlotNumber= %x\n", Index, PcieConfig->RootPort[Index].PhysicalSlotNumber));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] CompletionTimeout= %x\n", Index, PcieConfig->RootPort[Index].CompletionTimeout));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Aspm= %x\n", Index, PcieConfig->RootPort[Index].Aspm));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] L1Substates= %x\n", Index, PcieConfig->RootPort[Index].L1Substates));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrEnable= %x\n", Index, PcieConfig->RootPort[Index].LtrEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrConfigLock= %x\n", Index, PcieConfig->RootPort[Index].LtrConfigLock));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxSnoopLatency= %x\n", Index, PcieConfig->RootPort[Index].LtrMaxSnoopLatency));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxNoSnoopLatency= %x\n", Index, PcieConfig->RootPort[Index].LtrMaxNoSnoopLatency));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMode= %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMode));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMultiplier= %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMultiplier));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideValue= %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideValue));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideMode= %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMode));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideMultiplier= %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideValue= %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideValue));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] ForceLtrOverride= %x\n", Index, PcieConfig->RootPort[Index].ForceLtrOverride));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] DetectTimeoutMs= %x\n", Index, PcieConfig->RootPort[Index].DetectTimeoutMs));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitScale= %x\n", Index, PcieConfig->RootPort[Index].SlotPowerLimitScale));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitValue= %x\n", Index, PcieConfig->RootPort[Index].SlotPowerLimitValue));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Uptp= %x\n", Index, PcieConfig->RootPort[Index].Uptp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Dptp= %x\n", Index, PcieConfig->RootPort[Index].Dptp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] EnableCpm= %x\n", Index, PcieConfig->RootPort[Index].EnableCpm));
+
+  }
+  for (Index = 0; Index < GetPchMaxPcieClockNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " Clock[%d] Usage= %x\n", Index, PcieConfig->PcieClock[Index].Usage));
+    DEBUG ((DEBUG_INFO, " Clock[%d] ClkReq= %x\n", Index, PcieConfig->PcieClock[Index].ClkReq));
+  }
+  for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index++) {
+    DEBUG ((DEBUG_INFO, " SwEqCoeffCm[%d] = %x\n", Index, PcieConfig->SwEqCoeffList[Index].Cm));
+    DEBUG ((DEBUG_INFO, " SwEqCoeffCp[%d] = %x\n", Index, PcieConfig->SwEqCoeffList[Index].Cp));
+  }
+  DEBUG ((DEBUG_INFO, " EnablePort8xhDecode= %x\n", PcieConfig->EnablePort8xhDecode));
+  DEBUG ((DEBUG_INFO, " PchPciePort8xhDecodePortIndex= %x\n", PcieConfig->PchPciePort8xhDecodePortIndex));
+  DEBUG ((DEBUG_INFO, " DisableRootPortClockGating= %x\n", PcieConfig->DisableRootPortClockGating));
+  DEBUG ((DEBUG_INFO, " EnablePeerMemoryWrite= %x\n", PcieConfig->EnablePeerMemoryWrite));
+  DEBUG ((DEBUG_INFO, " ComplianceTestMode= %x\n", PcieConfig->ComplianceTestMode));
+  DEBUG ((DEBUG_INFO, " RpFunctionSwap= %x\n", PcieConfig->RpFunctionSwap));
+  DEBUG ((DEBUG_INFO, " PcieDeviceOverrideTablePtr= %x\n", PcieConfig->PcieDeviceOverrideTablePtr));
+}
+
+/**
+  Print PCH_SATA_CONFIG and serial out.
+
+  @param[in]  SataCtrlIndex     SATA controller index
+  @param[in]  SataConfig        Pointer to a PCH_SATA_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSataConfig (
+  IN UINT32                     SataCtrlIndex,
+  IN CONST PCH_SATA_CONFIG      *SataConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "--------------- PCH SATA Config for controller %d -----------\n", SataCtrlIndex));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", SataConfig->Enable));
+  DEBUG ((DEBUG_INFO, " SataMode= %x\n", SataConfig->SataMode));
+
+  for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] Enabled= %x\n", Index, SataConfig->PortSettings[Index].Enable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HotPlug= %x\n", Index, SataConfig->PortSettings[Index].HotPlug));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] InterlockSw= %x\n", Index, SataConfig->PortSettings[Index].InterlockSw));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] External= %x\n", Index, SataConfig->PortSettings[Index].External));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] SpinUp= %x\n", Index, SataConfig->PortSettings[Index].SpinUp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] SolidStateDrive= %x\n", Index, SataConfig->PortSettings[Index].SolidStateDrive));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] DevSlp= %x\n", Index, SataConfig->PortSettings[Index].DevSlp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] EnableDitoConfig= %x\n", Index, SataConfig->PortSettings[Index].EnableDitoConfig));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] DmVal= %x\n", Index, SataConfig->PortSettings[Index].DmVal));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] DitoVal= %x\n", Index, SataConfig->PortSettings[Index].DitoVal));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] ZpOdd= %x\n", Index, SataConfig->PortSettings[Index].ZpOdd));
+  }
+
+  DEBUG ((DEBUG_INFO, " RaidDeviceId= %x\n", SataConfig->Rst.RaidDeviceId));
+  DEBUG ((DEBUG_INFO, " Sata interrupt mode =  %x\n", SataConfig->Rst.SataRstInterrupt));
+  DEBUG ((DEBUG_INFO, " Raid0= %x\n", SataConfig->Rst.Raid0));
+  DEBUG ((DEBUG_INFO, " Raid1= %x\n", SataConfig->Rst.Raid1));
+  DEBUG ((DEBUG_INFO, " Raid10= %x\n", SataConfig->Rst.Raid10));
+  DEBUG ((DEBUG_INFO, " Raid5= %x\n", SataConfig->Rst.Raid5));
+  DEBUG ((DEBUG_INFO, " Irrt= %x\n", SataConfig->Rst.Irrt));
+  DEBUG ((DEBUG_INFO, " OromUiBanner= %x\n", SataConfig->Rst.OromUiBanner));
+  DEBUG ((DEBUG_INFO, " OromUiDelay= %x\n", SataConfig->Rst.OromUiDelay));
+  DEBUG ((DEBUG_INFO, " HddUnlock= %x\n", SataConfig->Rst.HddUnlock));
+  DEBUG ((DEBUG_INFO, " LedLocate= %x\n", SataConfig->Rst.LedLocate));
+  DEBUG ((DEBUG_INFO, " IrrtOnly= %x\n", SataConfig->Rst.IrrtOnly));
+  DEBUG ((DEBUG_INFO, " SmartStorage= %x\n", SataConfig->Rst.SmartStorage));
+  DEBUG ((DEBUG_INFO, " LegacyOrom= %x\n", SataConfig->Rst.LegacyOrom));
+  DEBUG ((DEBUG_INFO, " OptaneMemory= %x\n", SataConfig->Rst.OptaneMemory));
+  DEBUG ((DEBUG_INFO, " CpuAttachedStorage= %x\n", SataConfig->Rst.CpuAttachedStorage));
+
+  DEBUG ((DEBUG_INFO, " SpeedSupport= %x\n", SataConfig->SpeedLimit));
+  DEBUG ((DEBUG_INFO, " EsataSpeedLimit= %x\n", SataConfig->EsataSpeedLimit));
+  DEBUG ((DEBUG_INFO, " LedEnable= %x\n", SataConfig->LedEnable));
+  DEBUG ((DEBUG_INFO, " TestMode= %x\n", SataConfig->TestMode));
+  DEBUG ((DEBUG_INFO, " SalpSupport= %x\n", SataConfig->SalpSupport));
+  DEBUG ((DEBUG_INFO, " PwrOptEnable= %x\n", SataConfig->PwrOptEnable));
+
+  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].Enable                  = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].Enable));
+    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].RstPcieStoragePort      = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort));
+    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].DeviceResetDelay        = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay));
+  }
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T1M %x\n", SataConfig->ThermalThrottling.P0T1M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T2M %x\n", SataConfig->ThermalThrottling.P0T2M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T3M %x\n", SataConfig->ThermalThrottling.P0T3M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDisp %x\n", SataConfig->ThermalThrottling.P0TDisp));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0Tinact %x\n", SataConfig->ThermalThrottling.P0Tinact));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDispFinit %x\n", SataConfig->ThermalThrottling.P0TDispFinit));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T1M %x\n", SataConfig->ThermalThrottling.P1T1M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T2M %x\n", SataConfig->ThermalThrottling.P1T2M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T3M %x\n", SataConfig->ThermalThrottling.P1T3M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDisp %x\n", SataConfig->ThermalThrottling.P1TDisp));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1Tinact %x\n", SataConfig->ThermalThrottling.P1Tinact));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDispFinit %x\n", SataConfig->ThermalThrottling.P1TDispFinit));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling SuggestedSetting %x\n", SataConfig->ThermalThrottling.SuggestedSetting));
+}
+
+/**
+  Print PCH_IOAPIC_CONFIG and serial out.
+
+  @param[in] IoApicConfig         Pointer to a PCH_IOAPIC_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintIoApicConfig (
+  IN CONST PCH_IOAPIC_CONFIG   *IoApicConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH IOAPIC Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " IoApicEntry24_119= %x\n", IoApicConfig->IoApicEntry24_119));
+  DEBUG ((DEBUG_INFO, " Enable8254ClockGating= %x\n", IoApicConfig->Enable8254ClockGating));
+  DEBUG ((DEBUG_INFO, " Enable8254ClockGatingOnS3= %x\n", IoApicConfig->Enable8254ClockGatingOnS3));
+  DEBUG ((DEBUG_INFO, " IoApicId= %x\n", IoApicConfig->IoApicId));
+}
+
+/**
+  Print PCH_LOCK_DOWN_CONFIG and serial out.
+
+  @param[in] LockDownConfig         Pointer to a PCH_LOCK_DOWN_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintLockDownConfig (
+  IN CONST PCH_LOCK_DOWN_CONFIG   *LockDownConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH Lock Down Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " GlobalSmi= %x\n", LockDownConfig->GlobalSmi));
+  DEBUG ((DEBUG_INFO, " BiosInterface= %x\n", LockDownConfig->BiosInterface));
+  DEBUG ((DEBUG_INFO, " RtcMemoryLock= %x\n", LockDownConfig->RtcMemoryLock));
+  DEBUG ((DEBUG_INFO, " BiosLock= %x\n", LockDownConfig->BiosLock));
+  DEBUG ((DEBUG_INFO, " UnlockGpioPads= %x\n", LockDownConfig->UnlockGpioPads));
+}
+
+/**
+  Print PCH_HDAUDIO_CONFIG and serial out.
+
+  @param[in] HdaConfig         Pointer to a PCH_HDAUDIO_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintHdAudioConfig (
+  IN CONST PCH_HDAUDIO_CONFIG   *HdaConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " DSP Enable               = %x\n", HdaConfig->DspEnable));
+  DEBUG ((DEBUG_INFO, " DSP UAA Compliance       = %x\n", HdaConfig->DspUaaCompliance));
+  DEBUG ((DEBUG_INFO, " iDisp Codec Disconnect   = %x\n", HdaConfig->IDispCodecDisconnect));
+  DEBUG ((DEBUG_INFO, " Pme                      = %x\n", HdaConfig->Pme));
+  DEBUG ((DEBUG_INFO, " Codec Sx Wake Capability = %x\n", HdaConfig->CodecSxWakeCapability));
+  DEBUG ((DEBUG_INFO, " VC Type                  = %x\n", HdaConfig->VcType));
+  DEBUG ((DEBUG_INFO, " HD-A Link Frequency      = %x\n", HdaConfig->HdAudioLinkFrequency));
+  DEBUG ((DEBUG_INFO, " iDisp Link Frequency     = %x\n", HdaConfig->IDispLinkFrequency));
+  DEBUG ((DEBUG_INFO, " iDisp Link T-Mode        = %x\n", HdaConfig->IDispLinkTmode));
+  DEBUG ((DEBUG_INFO, " Audio Link: HDA Link     = %x\n", HdaConfig->AudioLinkHda));
+  DEBUG ((DEBUG_INFO, " Audio Link: DMIC#0       = %x\n", HdaConfig->AudioLinkDmic0));
+  DEBUG ((DEBUG_INFO, " Audio Link: DMIC#1       = %x\n", HdaConfig->AudioLinkDmic1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SSP#0        = %x\n", HdaConfig->AudioLinkSsp0));
+  DEBUG ((DEBUG_INFO, " Audio Link: SSP#1        = %x\n", HdaConfig->AudioLinkSsp1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SSP#2        = %x\n", HdaConfig->AudioLinkSsp1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#1  = %x\n", HdaConfig->AudioLinkSndw1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#2  = %x\n", HdaConfig->AudioLinkSndw2));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#3  = %x\n", HdaConfig->AudioLinkSndw3));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#4  = %x\n", HdaConfig->AudioLinkSndw4));
+  DEBUG ((DEBUG_INFO, " SoundWire Buffer RCOMP   = %x\n", HdaConfig->SndwBufferRcomp));
+  DEBUG ((DEBUG_INFO, " ResetWaitTimer           = %x\n", HdaConfig->ResetWaitTimer));
+  DEBUG ((DEBUG_INFO, " VerbTableEntryNum        = %x\n", HdaConfig->VerbTableEntryNum));
+  DEBUG ((DEBUG_INFO, " VerbTablePtr             = %x\n", HdaConfig->VerbTablePtr));
+}
+
+/**
+  Print PCH_PM_CONFIG and serial out.
+
+  @param[in] PmConfig         Pointer to a PCH_PM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintPmConfig (
+  IN CONST PCH_PM_CONFIG   *PmConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH PM Config ------------------\n"));
+
+  DEBUG ((DEBUG_INFO, " WakeConfig PmeB0S5Dis               = %x\n", PmConfig->WakeConfig.PmeB0S5Dis));
+  DEBUG ((DEBUG_INFO, " WakeConfig WolEnableOverride        = %x\n", PmConfig->WakeConfig.WolEnableOverride));
+  DEBUG ((DEBUG_INFO, " WakeConfig LanWakeFromDeepSx        = %x\n", PmConfig->WakeConfig.LanWakeFromDeepSx));
+  DEBUG ((DEBUG_INFO, " WakeConfig PcieWakeFromDeepSx       = %x\n", PmConfig->WakeConfig.PcieWakeFromDeepSx));
+  DEBUG ((DEBUG_INFO, " WakeConfig WoWlanEnable             = %x\n", PmConfig->WakeConfig.WoWlanEnable));
+  DEBUG ((DEBUG_INFO, " WakeConfig WoWlanDeepSxEnable       = %x\n", PmConfig->WakeConfig.WoWlanDeepSxEnable));
+
+  DEBUG ((DEBUG_INFO, " PchDeepSxPol                        = %x\n", PmConfig->PchDeepSxPol));
+  DEBUG ((DEBUG_INFO, " PchSlpS3MinAssert                   = %x\n", PmConfig->PchSlpS3MinAssert));
+  DEBUG ((DEBUG_INFO, " PchSlpS4MinAssert                   = %x\n", PmConfig->PchSlpS4MinAssert));
+  DEBUG ((DEBUG_INFO, " PchSlpSusMinAssert                  = %x\n", PmConfig->PchSlpSusMinAssert));
+  DEBUG ((DEBUG_INFO, " PchSlpAMinAssert                    = %x\n", PmConfig->PchSlpAMinAssert));
+  DEBUG ((DEBUG_INFO, " LpcClockRun                         = %x\n", PmConfig->LpcClockRun));
+  DEBUG ((DEBUG_INFO, " SlpStrchSusUp                       = %x\n", PmConfig->SlpStrchSusUp));
+  DEBUG ((DEBUG_INFO, " SlpLanLowDc                         = %x\n", PmConfig->SlpLanLowDc));
+  DEBUG ((DEBUG_INFO, " PwrBtnOverridePeriod                = %x\n", PmConfig->PwrBtnOverridePeriod));
+  DEBUG ((DEBUG_INFO, " DisableEnergyReport                 = %x\n", PmConfig->DisableEnergyReport));
+  DEBUG ((DEBUG_INFO, " DisableDsxAcPresentPulldown         = %x\n", PmConfig->DisableDsxAcPresentPulldown));
+  DEBUG ((DEBUG_INFO, " PchPwrCycDur                        = %x\n", PmConfig->PchPwrCycDur));
+  DEBUG ((DEBUG_INFO, " PciePllSsc                          = %x\n", PmConfig->PciePllSsc));
+  DEBUG ((DEBUG_INFO, " DisableNativePowerButton            = %x\n", PmConfig->DisableNativePowerButton));
+  DEBUG ((DEBUG_INFO, " SlpS0Enabled                        = %x\n", PmConfig->SlpS0Enable));
+  DEBUG ((DEBUG_INFO, " MeWakeSts                           = %x\n", PmConfig->MeWakeSts));
+  DEBUG ((DEBUG_INFO, " WolOvrWkSts                         = %x\n", PmConfig->WolOvrWkSts));
+  DEBUG ((DEBUG_INFO, " EnableTcoTimer                      = %x\n", PmConfig->EnableTcoTimer));
+  DEBUG ((DEBUG_INFO, " VrAlert                             = %x\n", PmConfig->VrAlert));
+  DEBUG ((DEBUG_INFO, " PowerButtonDebounce                 = %x\n", PmConfig->PowerButtonDebounce));
+  DEBUG ((DEBUG_INFO, " SlpS0VmRuntimeControl               = %x\n", PmConfig->SlpS0VmRuntimeControl));
+  DEBUG ((DEBUG_INFO, " SlpS0Vm070VSupport                  = %x\n", PmConfig->SlpS0Vm070VSupport));
+  DEBUG ((DEBUG_INFO, " SlpS0Vm075VSupport                  = %x\n", PmConfig->SlpS0Vm075VSupport));
+  DEBUG ((DEBUG_INFO, " SlpS0Override                       = %x\n", PmConfig->SlpS0Override));
+  DEBUG ((DEBUG_INFO, " SlpS0DisQForDebug                   = %x\n", PmConfig->SlpS0DisQForDebug));
+  DEBUG ((DEBUG_INFO, " PsOnEnable                          = %x\n", PmConfig->PsOnEnable));
+  DEBUG ((DEBUG_INFO, " CpuC10GatePinEnable                 = %x\n", PmConfig->CpuC10GatePinEnable));
+  DEBUG ((DEBUG_INFO, " PmcDbgMsgEn                         = %x\n", PmConfig->PmcDbgMsgEn));
+  DEBUG ((DEBUG_INFO, " ModPhySusPgEnable                   = %x\n", PmConfig->ModPhySusPgEnable));
+  DEBUG ((DEBUG_INFO, " SlpS0WithGbeSupport                 = %x\n", PmConfig->SlpS0WithGbeSupport));
+}
+
+/**
+  Print PCH_DMI_CONFIG and serial out.
+
+  @param[in] DmiConfig         Pointer to a PCH_DMI_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintDmiConfig (
+  IN CONST PCH_DMI_CONFIG   *DmiConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH DMI Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " PwrOptEnable= %x\n", DmiConfig->PwrOptEnable));
+  DEBUG ((DEBUG_INFO, " DmiAspmCtrl= %x\n", DmiConfig->DmiAspmCtrl));
+}
+/**
+  Print PCH_LPC_SIRQ_CONFIG and serial out.
+
+  @param[in] SerialIrqConfig         Pointer to a PCH_LPC_SIRQ_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSerialIrqConfig (
+  IN CONST PCH_LPC_SIRQ_CONFIG   *SerialIrqConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH LPC SIRQ Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " SirqEnable= %x\n", SerialIrqConfig->SirqEnable));
+  DEBUG ((DEBUG_INFO, " SirqMode= %x\n", SerialIrqConfig->SirqMode));
+  DEBUG ((DEBUG_INFO, " StartFramePulse= %x\n", SerialIrqConfig->StartFramePulse));
+}
+/**
+  Print PCH_THERMAL_CONFIG and serial out.
+
+  @param[in] ThermalConfig         Pointer to a PCH_THERMAL_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintThermalConfig (
+  IN CONST PCH_THERMAL_CONFIG   *ThermalConfig
+  )
+{
+  UINTN Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH Thermal Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " TsmicLock= %x\n", ThermalConfig->TsmicLock));
+  DEBUG ((DEBUG_INFO, " TTLevels T0Level %x centigrade degree\n", ThermalConfig->TTLevels.T0Level));
+  DEBUG ((DEBUG_INFO, " TTLevels T1Level %x centigrade degree\n", ThermalConfig->TTLevels.T1Level));
+  DEBUG ((DEBUG_INFO, " TTLevels T2Level %x centigrade degree\n", ThermalConfig->TTLevels.T2Level));
+  DEBUG ((DEBUG_INFO, " TTLevels TTEnable %x\n", ThermalConfig->TTLevels.TTEnable));
+  DEBUG ((DEBUG_INFO, " TTLevels TTState13Enable %x\n", ThermalConfig->TTLevels.TTState13Enable));
+  DEBUG ((DEBUG_INFO, " TTLevels TTLock %x\n", ThermalConfig->TTLevels.TTLock));
+  DEBUG ((DEBUG_INFO, " TTLevels SuggestedSetting %x\n", ThermalConfig->TTLevels.SuggestedSetting));
+  DEBUG ((DEBUG_INFO, " TTLevels PchCrossThrottling %x\n", ThermalConfig->TTLevels.PchCrossThrottling));
+
+  DEBUG ((DEBUG_INFO, " DmiHaAWC DmiTsawEn %x\n", ThermalConfig->DmiHaAWC.DmiTsawEn));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS0TW %x\n", ThermalConfig->DmiHaAWC.TS0TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS1TW %x\n", ThermalConfig->DmiHaAWC.TS1TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS2TW %x\n", ThermalConfig->DmiHaAWC.TS2TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS3TW %x\n", ThermalConfig->DmiHaAWC.TS3TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC SuggestedSetting %x\n", ThermalConfig->DmiHaAWC.SuggestedSetting));
+
+  DEBUG ((DEBUG_INFO, " MemoryThrottling Enable= %x\n", ThermalConfig->MemoryThrottling.Enable));
+  for (Index = 0; Index < MaxTsGpioPin; Index++) {
+    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting PmsyncEnable= %x\n", ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PmsyncEnable));
+    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting C0TransmitEnable= %x\n", ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].C0TransmitEnable));
+    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting PinSelection= %x\n", ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PinSelection));
+  }
+  DEBUG ((DEBUG_INFO, " PchHotEnable = %x\n", ThermalConfig->PchHotEnable));
+  DEBUG ((DEBUG_INFO, " PchHotLevel = %x\n", ThermalConfig->PchHotLevel));
+}
+
+/**
+  Print PCH_GENERAL_CONFIG and serial out.
+
+  @param[in] PchGeneralConfig   Pointer to a PCH_GENERAL_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintGeneralConfig (
+  IN CONST PCH_GENERAL_CONFIG   *PchGeneralConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH General Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Crid= %x\n", PchGeneralConfig->Crid));
+  DEBUG ((DEBUG_INFO, " LegacyIoLowLatency = %x\n", PchGeneralConfig->LegacyIoLowLatency));
+}
+
+/**
+  Print PCH_LAN_CONFIG and serial out.
+
+  @param[in] LanConfig         Pointer to a PCH_LAN_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintLanConfig (
+  IN CONST PCH_LAN_CONFIG   *LanConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH LAN Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", LanConfig->Enable));
+  DEBUG ((DEBUG_INFO, " LtrEnable= %x\n", LanConfig->LtrEnable));
+}
+
+/**
+  Print PCH_SERIAL_IO_CONFIG and serial out.
+
+  @param[in] SerialIoConfig         Pointer to a PCH_SERIAL_IO_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSerialIoConfig (
+  IN CONST PCH_SERIAL_IO_CONFIG   *SerialIoConfig
+  )
+{
+  UINTN Index;
+#ifndef MDEPKG_NDEBUG
+  static UINT8 DeviceName[PCH_MAX_SERIALIO_CONTROLLERS][5] = {"I2C0","I2C1","I2C2","I2C3","I2C4","I2C5","SPI0","SPI1","SPI2","UA00","UA01","UA02"};
+#endif
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH Serial IO Config ------------------\n"));
+  DEBUG_CODE_BEGIN ();
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " SerialIoController %a: Mode 0x%x\n", DeviceName[Index], SerialIoConfig->DevMode[Index]));
+  }
+  DEBUG_CODE_END ();
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " SpiCsPolarity[%d] = 0x%x\n", Index, SerialIoConfig->SpiCsPolarity[Index]));
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " UartHwFlowCtrl[%d] = 0x%x\n", Index, SerialIoConfig->UartHwFlowCtrl[Index]));
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index ++) {
+    DEBUG ((DEBUG_INFO, " I2cPadsTermination[%d] = 0x%x\n", Index, SerialIoConfig->I2cPadsTermination[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " DebugUartNumber = 0x%x\n", SerialIoConfig->DebugUartNumber));
+  DEBUG ((DEBUG_INFO, " EnableDebugUartAfterPost = 0x%x\n", SerialIoConfig->EnableDebugUartAfterPost));
+  DEBUG ((DEBUG_INFO, " Uart0PinMuxing = 0x%x\n", SerialIoConfig->Uart0PinMuxing));
+}
+
+/**
+  Print PCH_INTERRUPT_CONFIG and serial out
+
+  @param[in] InterruptConfig        Pointer to Interrupt Configuration structure
+
+**/
+VOID
+PchPrintInterruptConfig (
+  IN CONST PCH_INTERRUPT_CONFIG     *InterruptConfig
+  )
+{
+  UINTN Index;
+  //
+  // Print interrupt information
+  //
+  DEBUG ((DEBUG_INFO, "------------------ PCH Interrupt Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Interrupt assignment:\n"));
+  DEBUG ((DEBUG_INFO, "  Dxx:Fx INTx IRQ\n"));
+  for (Index = 0; Index < InterruptConfig->NumOfDevIntConfig; Index++) {
+    DEBUG ((DEBUG_INFO, "  D%02d:F%d    %d %03d\n",
+            InterruptConfig->DevIntConfig[Index].Device,
+            InterruptConfig->DevIntConfig[Index].Function,
+            InterruptConfig->DevIntConfig[Index].IntX,
+            InterruptConfig->DevIntConfig[Index].Irq));
+  }
+  DEBUG ((DEBUG_INFO, " Legacy PIC interrupt routing:\n"));
+  DEBUG ((DEBUG_INFO, "  PIRQx    IRQx\n"));
+  for (Index = 0; Index < PCH_MAX_PXRC_CONFIG; Index++) {
+    DEBUG ((DEBUG_INFO, "  PIRQ%c -> IRQ%d\n", Index + 65, InterruptConfig->PxRcConfig[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " Other interrupt configuration:\n"));
+  DEBUG ((DEBUG_INFO, "  GpioIrqRoute= %d\n", InterruptConfig->GpioIrqRoute));
+  DEBUG ((DEBUG_INFO, "  SciIrqSelect= %d\n", InterruptConfig->SciIrqSelect));
+  DEBUG ((DEBUG_INFO, "  TcoIrqEnable= %d\n", InterruptConfig->TcoIrqEnable));
+  DEBUG ((DEBUG_INFO, "  TcoIrqSelect= %d\n", InterruptConfig->TcoIrqSelect));
+}
+
+/**
+  Print PCH_SCS_CONFIG and serial out.
+
+  @param[in] ScsConfig         Pointer to a PCH_SCS_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintScsConfig (
+  IN CONST PCH_SCS_CONFIG   *ScsConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH SCS Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " ScsEmmcEnabled = %x\n", ScsConfig->ScsEmmcEnabled));
+  DEBUG ((DEBUG_INFO, " ScsSdcardEnabled = %x\n", ScsConfig->ScsSdcardEnabled));
+  DEBUG ((DEBUG_INFO, " SdCardPowerEnableActiveHigh = %x\n", ScsConfig->SdCardPowerEnableActiveHigh));
+  DEBUG ((DEBUG_INFO, " ScsUfsEnabled = %x\n", ScsConfig->ScsUfsEnabled));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400Enabled = %x\n", ScsConfig->ScsEmmcHs400Enabled));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400TuningRequired = %x\n", ScsConfig->ScsEmmcHs400TuningRequired));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400DllDataValid = %x\n", ScsConfig->ScsEmmcHs400DllDataValid));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400RxStrobeDll1 = %x\n", ScsConfig->ScsEmmcHs400RxStrobeDll1));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400TxDataDll = %x\n", ScsConfig->ScsEmmcHs400TxDataDll));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400DriverStrength = %x\n", ScsConfig->ScsEmmcHs400DriverStrength));
+}
+
+/**
+  Print PCH_ISH_CONFIG and serial out.
+
+  @param[in] IshConfig         Pointer to a PCH_ISH_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintIshConfig (
+  IN CONST PCH_ISH_CONFIG   *IshConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH ISH Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " SPI GPIO Assigned   = %x\n", IshConfig->SpiGpioAssign));
+  DEBUG ((DEBUG_INFO, " UART0 GPIO Assigned = %x\n", IshConfig->Uart0GpioAssign));
+  DEBUG ((DEBUG_INFO, " UART1 GPIO Assigned = %x\n", IshConfig->Uart1GpioAssign));
+  DEBUG ((DEBUG_INFO, " I2C0 GPIO Assigned  = %x\n", IshConfig->I2c0GpioAssign));
+  DEBUG ((DEBUG_INFO, " I2C1 GPIO Assigned  = %x\n", IshConfig->I2c1GpioAssign));
+  DEBUG ((DEBUG_INFO, " I2C2 GPIO Assigned  = %x\n", IshConfig->I2c2GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_0 GPIO Assigned  = %x\n", IshConfig->Gp0GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_1 GPIO Assigned  = %x\n", IshConfig->Gp1GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_2 GPIO Assigned  = %x\n", IshConfig->Gp2GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_3 GPIO Assigned  = %x\n", IshConfig->Gp3GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_4 GPIO Assigned  = %x\n", IshConfig->Gp4GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_5 GPIO Assigned  = %x\n", IshConfig->Gp5GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_6 GPIO Assigned  = %x\n", IshConfig->Gp6GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_7 GPIO Assigned  = %x\n", IshConfig->Gp7GpioAssign));
+}
+
+/**
+  Print PCH_FLASH_PROTECTION_CONFIG and serial out.
+
+  @param[in] FlashProtectConfig  Pointer to a PCH_FLASH_PROTECTION_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintFlashProtectionConfig (
+  IN CONST PCH_FLASH_PROTECTION_CONFIG   *FlashProtectConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH Flash Protection Config ------------------\n"));
+  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; ++Index) {
+    DEBUG ((DEBUG_INFO, " WriteProtectionEnable[%d] = %x\n", Index, FlashProtectConfig->ProtectRange[Index].WriteProtectionEnable));
+    DEBUG ((DEBUG_INFO, " ReadProtectionEnable[%d]  = %x\n", Index, FlashProtectConfig->ProtectRange[Index].ReadProtectionEnable));
+    DEBUG ((DEBUG_INFO, " ProtectedRangeLimit[%d]   = %x\n", Index, FlashProtectConfig->ProtectRange[Index].ProtectedRangeLimit));
+    DEBUG ((DEBUG_INFO, " ProtectedRangeBase[%d]    = %x\n", Index, FlashProtectConfig->ProtectRange[Index].ProtectedRangeBase));
+  }
+}
+
+/**
+  Print PCH_P2SB_CONFIG and serial out.
+
+  @param[in] P2sbConfig                 Pointer to a PCH_P2SB_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintP2sbConfig (
+  IN CONST PCH_P2SB_CONFIG              *P2sbConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH P2SB Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "SbAccessUnlock= %x\n", P2sbConfig->SbAccessUnlock));
+}
+
+/**
+  Print PCH_ESPI_CONFIG.
+
+  @param[in] EspiConfig         Pointer to a PCH_ESPI_CONFIG that provides the eSPI setting
+
+**/
+VOID
+PchPrintEspiConfig (
+  IN CONST PCH_ESPI_CONFIG   *EspiConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH eSPI Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " LGMR Enable %x\n", EspiConfig->LgmrEnable));
+  DEBUG ((DEBUG_INFO, " BME for Master and Slave Enabled %x\n", EspiConfig->BmeMasterSlaveEnabled));
+}
+
+/**
+  Print PCH_CNVI_CONFIG.
+
+  @param[in] CnviConfig         Pointer to a PCH_CNVI_CONFIG that provides the CNVi settings
+
+**/
+VOID
+PchPrintCnviConfig (
+  IN CONST PCH_CNVI_CONFIG   *CnviConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH CNVi Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "CNVi Mode = %x\n", CnviConfig->Mode));
+  DEBUG ((DEBUG_INFO, "CNVi MfUart1 type = %x\n", CnviConfig->MfUart1Type));
+}
+
+/**
+  Print PCH_HSIO_CONFIG.
+
+  @param[in] HsioConfig         Pointer to a PCH_HSIO_CONFIG that provides the eSPI setting
+
+**/
+VOID
+PchPrintHsioConfig (
+  IN CONST PCH_HSIO_CONFIG   *HsioConfig
+  )
+{
+  PCH_HSIO_VER_INFO             *BiosChipsetInitVerInfoPtr;
+  DEBUG ((DEBUG_INFO, "------------------ PCH HSIO Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " ChipsetInit Binary Pointer            = %x\n", HsioConfig->ChipsetInitBinPtr));
+  DEBUG ((DEBUG_INFO, " ChipsetInit Binary Length             = %x\n", HsioConfig->ChipsetInitBinLen));
+  BiosChipsetInitVerInfoPtr = (PCH_HSIO_VER_INFO *) HsioConfig->ChipsetInitBinPtr;
+  if (HsioConfig->ChipsetInitBinPtr && HsioConfig->ChipsetInitBinLen) {
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC           = %x\n", BiosChipsetInitVerInfoPtr->BaseCrc));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC            = %x\n", BiosChipsetInitVerInfoPtr->OemCrc));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC            = %x\n", BiosChipsetInitVerInfoPtr->SusCrc));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Version            = %x\n", BiosChipsetInitVerInfoPtr->Version));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Product            = %x\n", BiosChipsetInitVerInfoPtr->Product));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Metal Layer        = %x\n", BiosChipsetInitVerInfoPtr->MetalLayer));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base Layer         = %x\n", BiosChipsetInitVerInfoPtr->BaseLayer));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM Version        = %x\n", BiosChipsetInitVerInfoPtr->OemVersion));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Debug Mode         = %x\n", BiosChipsetInitVerInfoPtr->DebugMode));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC Valid      = %x\n", BiosChipsetInitVerInfoPtr->OemCrcValid));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC Valid      = %x\n", BiosChipsetInitVerInfoPtr->SusCrcValid));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC Valid     = %x\n", BiosChipsetInitVerInfoPtr->BaseCrcValid));
+  }
+}
+
+/**
+  Print whole PCH config blocks and serial out.
+
+  @param[in] SiPolicyPpi    The RC Policy PPI instance
+
+**/
+VOID
+EFIAPI
+PchPrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  )
+{
+DEBUG_CODE_BEGIN();
+  EFI_STATUS                      Status;
+  PCH_GENERAL_CONFIG              *PchGeneralConfig;
+  PCH_PCIE_CONFIG                 *PcieRpConfig;
+  PCH_SATA_CONFIG                 *SataConfig;
+  PCH_IOAPIC_CONFIG               *IoApicConfig;
+  PCH_DMI_CONFIG                  *DmiConfig;
+  PCH_FLASH_PROTECTION_CONFIG     *FlashProtectionConfig;
+  PCH_HDAUDIO_CONFIG              *HdAudioConfig;
+  PCH_INTERRUPT_CONFIG            *InterruptConfig;
+  PCH_ISH_CONFIG                  *IshConfig;
+  PCH_LAN_CONFIG                  *LanConfig;
+  PCH_P2SB_CONFIG                 *P2sbConfig;
+  PCH_LOCK_DOWN_CONFIG            *LockDownConfig;
+  PCH_PM_CONFIG                   *PmConfig;
+  PCH_SCS_CONFIG                  *ScsConfig;
+  PCH_SERIAL_IO_CONFIG            *SerialIoConfig;
+  PCH_LPC_SIRQ_CONFIG             *SerialIrqConfig;
+  PCH_THERMAL_CONFIG              *ThermalConfig;
+  USB_CONFIG                      *UsbConfig;
+  PCH_ESPI_CONFIG                 *EspiConfig;
+  PCH_CNVI_CONFIG                 *CnviConfig;
+  PCH_HSIO_CONFIG                 *HsioConfig;
+  UINT32                          SataCtrlIndex;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gDmiConfigGuid, (VOID *) &DmiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHdAudioConfigGuid, (VOID *) &HdAudioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gIshConfigGuid, (VOID *) &IshConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gLanConfigGuid, (VOID *) &LanConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gP2sbConfigGuid, (VOID *) &P2sbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gScsConfigGuid, (VOID *) &ScsConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIoConfigGuid, (VOID *) &SerialIoConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIrqConfigGuid, (VOID *) &SerialIrqConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gThermalConfigGuid, (VOID *) &ThermalConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gUsbConfigGuid, (VOID *) &UsbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gEspiConfigGuid, (VOID *) &EspiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCnviConfigGuid, (VOID *) &CnviConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHsioConfigGuid, (VOID *) &HsioConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print Policy Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPolicyPpi->TableHeader.Header.Revision));
+
+  PchPrintGeneralConfig (PchGeneralConfig);
+  PchPrintPcieConfig (PcieRpConfig);
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++) {
+    SataConfig = GetPchSataConfig (SiPolicyPpi, SataCtrlIndex);
+    PchPrintSataConfig (SataCtrlIndex, SataConfig);
+  }
+  PchPrintUsbConfig (UsbConfig);
+  PchPrintIoApicConfig (IoApicConfig);
+  PchPrintHdAudioConfig (HdAudioConfig);
+  PchPrintLanConfig (LanConfig);
+  PchPrintLockDownConfig (LockDownConfig);
+  PchPrintThermalConfig (ThermalConfig);
+  PchPrintPmConfig (PmConfig);
+  PchPrintDmiConfig (DmiConfig);
+  PchPrintSerialIrqConfig (SerialIrqConfig);
+  PchPrintSerialIoConfig (SerialIoConfig);
+  PchPrintInterruptConfig (InterruptConfig);
+  PchPrintScsConfig (ScsConfig);
+  PchPrintIshConfig (IshConfig);
+  PchPrintFlashProtectionConfig (FlashProtectionConfig);
+  PchPrintP2sbConfig (P2sbConfig);
+  PchPrintEspiConfig (EspiConfig);
+  PchPrintCnviConfig (CnviConfig);
+  PchPrintHsioConfig (HsioConfig);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print Platform Protocol End --------------------------\n"));
+DEBUG_CODE_END();
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c
new file mode 100644
index 0000000000..2a1da20667
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c
@@ -0,0 +1,739 @@
+/** @file
+  This file is PeiPchPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/PchRegsLpcCnl.h>
+
+/**
+  mPxRcConfig[] table contains data for 8259 routing (how PIRQx is mapped to IRQy).
+  This information is used by systems which choose to use legacy PIC
+  interrupt controller. Only IRQ3-7,9-12,14,15 are valid. Values from this table
+  will be programmed into ITSS.PxRC registers.
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPxRcConfig[] = {
+  11,  // PARC: PIRQA -> IRQ11
+  10,  // PBRC: PIRQB -> IRQ10
+  11,  // PCRC: PIRQC -> IRQ11
+  11,  // PDRC: PIRQD -> IRQ11
+  11,  // PERC: PIRQE -> IRQ11
+  11,  // PFRC: PIRQF -> IRQ11
+  11,  // PGRC: PIRQG -> IRQ11
+  11   // PHRC: PIRQH -> IRQ11
+};
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchGeneralConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_GENERAL_CONFIG  *PchGeneralConfig;
+  PchGeneralConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PchGeneralConfig->Header.GuidHob.Name = %g\n", &PchGeneralConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PchGeneralConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PchGeneralConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    PCH general configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPcieRpConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN            Index;
+  PCH_PCIE_CONFIG  *PcieRpConfig;
+
+  PcieRpConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpConfig->Header.GuidHob.Name = %g\n", &PcieRpConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieRpConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    PCI Express related settings
+  ********************************/
+  PcieRpConfig->RpFunctionSwap = TRUE;
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    PcieRpConfig->RootPort[Index].Aspm                   = PchPcieAspmAutoConfig;
+    PcieRpConfig->RootPort[Index].PmSci                  = TRUE;
+    PcieRpConfig->RootPort[Index].AcsEnabled             = TRUE;
+    PcieRpConfig->RootPort[Index].PtmEnabled             = TRUE;
+    PcieRpConfig->RootPort[Index].DpcEnabled             = TRUE;
+    PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled = TRUE;
+    PcieRpConfig->RootPort[Index].MaxPayload             = PchPcieMaxPayload256;
+    PcieRpConfig->RootPort[Index].SlotImplemented        = TRUE;
+    PcieRpConfig->RootPort[Index].PhysicalSlotNumber     = (UINT8) Index;
+    PcieRpConfig->RootPort[Index].L1Substates            = PchPcieL1SubstatesL1_1_2;
+    PcieRpConfig->RootPort[Index].EnableCpm              = TRUE;
+    PcieRpConfig->RootPort[Index].Gen3EqPh3Method        = PchPcieEqHardware;
+
+    //
+    // PCIe LTR Configuration.
+    //
+    PcieRpConfig->RootPort[Index].LtrEnable             = TRUE;
+
+    PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency               = 0x1003;
+    PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency             = 0x1003;
+
+    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode           = 2;
+    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier     = 2;
+    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue          = 60;
+    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode        = 2;
+    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier  = 2;
+    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue       = 60;
+
+    PcieRpConfig->RootPort[Index].Uptp                               = 5;
+    PcieRpConfig->RootPort[Index].Dptp                               = 7;
+
+    PcieRpConfig->EqPh3LaneParam[Index].Cm                           = 6;
+    PcieRpConfig->EqPh3LaneParam[Index].Cp                           = 2;
+  }
+
+  PcieRpConfig->SwEqCoeffList[0].Cm = 4;
+  PcieRpConfig->SwEqCoeffList[0].Cp = 8;
+  PcieRpConfig->SwEqCoeffList[1].Cm = 6;
+  PcieRpConfig->SwEqCoeffList[1].Cp = 2;
+  PcieRpConfig->SwEqCoeffList[2].Cm = 8;
+  PcieRpConfig->SwEqCoeffList[2].Cp = 6;
+  PcieRpConfig->SwEqCoeffList[3].Cm = 10;
+  PcieRpConfig->SwEqCoeffList[3].Cp = 8;
+  PcieRpConfig->SwEqCoeffList[4].Cm = 12;
+  PcieRpConfig->SwEqCoeffList[4].Cp = 2;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSataConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN            PortIndex;
+  UINTN            Index;
+  UINT32           SataCtrlIndex;
+  PCH_SATA_CONFIG  *SataConfig;
+
+  SataConfig = (PCH_SATA_CONFIG *)ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Name = %g\n", &SataConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SataConfig->Header.GuidHob.Header.HobLength));
+
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++, SataConfig++) {
+    /********************************
+      SATA related settings
+    ********************************/
+    SataConfig->Enable               = TRUE;
+    SataConfig->SalpSupport          = TRUE;
+    SataConfig->SataMode             = PchSataModeAhci;
+
+    for (PortIndex = 0; PortIndex < GetPchMaxSataPortNum (SataCtrlIndex); PortIndex++) {
+      SataConfig->PortSettings[PortIndex].Enable           = TRUE;
+      SataConfig->PortSettings[PortIndex].DmVal            = 15;
+      SataConfig->PortSettings[PortIndex].DitoVal          = 625;
+    }
+
+    SataConfig->Rst.Raid0              = TRUE;
+    SataConfig->Rst.Raid1              = TRUE;
+    SataConfig->Rst.Raid10             = TRUE;
+    SataConfig->Rst.Raid5              = TRUE;
+    SataConfig->Rst.Irrt               = TRUE;
+    SataConfig->Rst.OromUiBanner       = TRUE;
+    SataConfig->Rst.OromUiDelay        = PchSataOromDelay2sec;
+    SataConfig->Rst.HddUnlock          = TRUE;
+    SataConfig->Rst.LedLocate          = TRUE;
+    SataConfig->Rst.IrrtOnly           = TRUE;
+    SataConfig->Rst.SmartStorage       = TRUE;
+    SataConfig->Rst.OptaneMemory       = TRUE;
+    SataConfig->Rst.CpuAttachedStorage = TRUE;
+
+    for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+      SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay             = 100;
+    }
+
+    SataConfig->PwrOptEnable     = TRUE;
+    SataConfig->ThermalThrottling.SuggestedSetting = TRUE;
+  }
+}
+
+/**
+  Get Sata Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     SataConfig          Pointer to Sata Config Policy
+**/
+PCH_SATA_CONFIG *
+GetPchSataConfig (
+  IN SI_POLICY_PPI      *SiPolicy,
+  IN UINT32             SataCtrlIndex
+  )
+{
+  PCH_SATA_CONFIG     *SataConfig;
+  EFI_STATUS          Status;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *) &SataConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  SataConfig += SataCtrlIndex;
+
+  return SataConfig;
+}
+
+/**
+  Load Config block default
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadIoApicConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_IOAPIC_CONFIG  *IoApicConfig;
+  IoApicConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Name = %g\n", &IoApicConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Header.HobLength = 0x%x\n", IoApicConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Io Apic configuration
+  ********************************/
+  IoApicConfig->IoApicId                   = 0x02;
+  IoApicConfig->IoApicEntry24_119          = TRUE;
+  IoApicConfig->Enable8254ClockGating      = TRUE;
+  IoApicConfig->Enable8254ClockGatingOnS3  = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadDmiConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_DMI_CONFIG  *DmiConfig;
+  DmiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Name = %g\n", &DmiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", DmiConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    DMI related settings
+  ********************************/
+  DmiConfig->DmiAspmCtrl = PchPcieAspmAutoConfig;
+}
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadFlashProtectionConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_FLASH_PROTECTION_CONFIG  *FlashProtectionConfig;
+  FlashProtectionConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "FlashProtectionConfig->Header.GuidHob.Name = %g\n", &FlashProtectionConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "FlashProtectionConfig->Header.GuidHob.Header.HobLength = 0x%x\n", FlashProtectionConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHdAudioConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HDAUDIO_CONFIG  *HdAudioConfig;
+  HdAudioConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HdAudioConfig->Header.GuidHob.Name = %g\n", &HdAudioConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HdAudioConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HdAudioConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    HD-Audio configuration
+  ********************************/
+  HdAudioConfig->DspEnable            = TRUE;
+  HdAudioConfig->HdAudioLinkFrequency = PchHdaLinkFreq24MHz;
+  HdAudioConfig->IDispLinkFrequency   = PchHdaLinkFreq96MHz;
+  HdAudioConfig->IDispLinkTmode       = PchHdaIDispMode2T;
+  HdAudioConfig->ResetWaitTimer       = 600; // Must be at least 521us (25 frames)
+  HdAudioConfig->AudioLinkHda         = TRUE;
+  HdAudioConfig->AudioLinkDmic0       = TRUE;
+  HdAudioConfig->AudioLinkDmic1       = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadInterruptConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_INTERRUPT_CONFIG  *InterruptConfig;
+  InterruptConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "InterruptConfig->Header.GuidHob.Name = %g\n", &InterruptConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "InterruptConfig->Header.GuidHob.Header.HobLength = 0x%x\n", InterruptConfig->Header.GuidHob.Header.HobLength));
+
+  LoadDeviceInterruptConfig (InterruptConfig);
+
+  ASSERT ((sizeof (mPxRcConfig) / sizeof (UINT8)) <= PCH_MAX_PXRC_CONFIG);
+  CopyMem (
+    InterruptConfig->PxRcConfig,
+    mPxRcConfig,
+    sizeof (mPxRcConfig)
+    );
+
+  InterruptConfig->GpioIrqRoute = 14;
+  InterruptConfig->SciIrqSelect = 9;
+  InterruptConfig->TcoIrqSelect = 9;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadIshConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_ISH_CONFIG  *IshConfig;
+  IshConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Name = %g\n", &IshConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Header.HobLength = 0x%x\n", IshConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadLanConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LAN_CONFIG  *LanConfig;
+  UINT16          LpcDid;
+
+  LanConfig = ConfigBlockPointer;
+  LpcDid    = PchGetLpcDid ();
+
+  DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Name = %g\n", &LanConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Header.HobLength = 0x%x\n", LanConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Lan configuration
+  ********************************/
+  LanConfig->Enable = TRUE;
+  LanConfig->LtrEnable = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadLockDownConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LOCK_DOWN_CONFIG  *LockDownConfig;
+  LockDownConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "LockDownConfig->Header.GuidHob.Name = %g\n", &LockDownConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "LockDownConfig->Header.GuidHob.Header.HobLength = 0x%x\n", LockDownConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Lockdown configuration
+  ********************************/
+  LockDownConfig->GlobalSmi       = TRUE;
+  LockDownConfig->BiosInterface   = TRUE;
+  LockDownConfig->RtcMemoryLock   = TRUE;
+  LockDownConfig->BiosLock        = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadP2sbConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_P2SB_CONFIG  *P2sbConfig;
+  P2sbConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Name = %g\n", &P2sbConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Header.HobLength = 0x%x\n", P2sbConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPmConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_PM_CONFIG  *PmConfig;
+  PmConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Name = %g\n", &PmConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PmConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    MiscPm Configuration
+  ********************************/
+  PmConfig->MeWakeSts                            = TRUE;
+  PmConfig->WolOvrWkSts                          = TRUE;
+
+  PmConfig->WakeConfig.WolEnableOverride         = TRUE;
+  PmConfig->WakeConfig.LanWakeFromDeepSx         = TRUE;
+
+  PmConfig->PchSlpS3MinAssert                    = PchSlpS350ms;
+  PmConfig->PchSlpS4MinAssert                    = PchSlpS41s;
+  PmConfig->PchSlpSusMinAssert                   = PchSlpSus4s;
+  PmConfig->PchSlpAMinAssert                     = PchSlpA2s;
+
+  PmConfig->SlpLanLowDc                          = TRUE;
+  PmConfig->PciePllSsc                           = 0xFF;
+  PmConfig->LpcClockRun                          = TRUE;
+  PmConfig->SlpS0Enable                          = TRUE;
+  PmConfig->CpuC10GatePinEnable                  = TRUE;
+  if (IsWhlCpu () && (GetCpuStepping () == EnumCflV0)) {
+    PmConfig->SlpS0WithGbeSupport                  = FALSE;
+  } else {
+    PmConfig->SlpS0WithGbeSupport                  = TRUE;
+  }
+
+  if (IsPchLp ()) {
+    PmConfig->ModPhySusPgEnable                  = TRUE;
+  }
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadScsConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_SCS_CONFIG  *ScsConfig;
+  ScsConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Name = %g\n", &ScsConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Header.HobLength = 0x%x\n", ScsConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    SCS Configuration
+  ********************************/
+  ScsConfig->ScsEmmcEnabled   = IsPchLp () ? TRUE : FALSE; // eMMC present on PCH-LP only
+  ScsConfig->ScsEmmcHs400DriverStrength = DriverStrength40Ohm;
+  //Enable Sd Card controller for Non-Desktop sku platforms
+  if (GetCpuSku () != EnumCpuTrad) {
+    ScsConfig->ScsSdcardEnabled = TRUE;
+  }
+  ScsConfig->SdCardPowerEnableActiveHigh = TRUE;
+  ScsConfig->ScsUfsEnabled    = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSerialIoConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN                 Index;
+  PCH_SERIAL_IO_CONFIG  *SerialIoConfig;
+  SerialIoConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SerialIoConfig->Header.GuidHob.Name = %g\n", &SerialIoConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SerialIoConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SerialIoConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    SerialIo Configuration
+  ********************************/
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    SerialIoConfig->DevMode[Index]         = PchSerialIoPci;
+  }
+  SerialIoConfig->DebugUartNumber          = PcdGet8 (PcdSerialIoUartNumber);
+}
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSerialIrqConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LPC_SIRQ_CONFIG  *SerialIrqConfig;
+  SerialIrqConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SerialIrqConfig->Header.GuidHob.Name = %g\n", &SerialIrqConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SerialIrqConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SerialIrqConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Serial IRQ Configuration
+  ********************************/
+  SerialIrqConfig->SirqEnable       = TRUE;
+  SerialIrqConfig->SirqMode         = PchQuietMode;
+  SerialIrqConfig->StartFramePulse  = PchSfpw4Clk;
+}
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadThermalConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_THERMAL_CONFIG  *ThermalConfig;
+  ThermalConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "ThermalConfig->Header.GuidHob.Name = %g\n", &ThermalConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "ThermalConfig->Header.GuidHob.Header.HobLength = 0x%x\n", ThermalConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Thermal configuration.
+  ********************************/
+  ThermalConfig->TsmicLock                   = TRUE;
+  ThermalConfig->PchHotLevel                 = 0x154;
+  ThermalConfig->TTLevels.SuggestedSetting   = TRUE;
+  ThermalConfig->TTLevels.PchCrossThrottling = TRUE;
+  ThermalConfig->DmiHaAWC.SuggestedSetting   = TRUE;
+
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].PmsyncEnable     = TRUE;
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].C0TransmitEnable = TRUE;
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].PmsyncEnable     = TRUE;
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].C0TransmitEnable = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadUsbConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN           PortIndex;
+  USB_CONFIG      *UsbConfig;
+  UsbConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Name = %g\n", &UsbConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Header.HobLength = 0x%x\n", UsbConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    USB related configuration
+  ********************************/
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++) {
+    UsbConfig->PortUsb20[PortIndex].Enable  = TRUE;
+  }
+
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+    UsbConfig->PortUsb30[PortIndex].Enable  = TRUE;
+  }
+
+  //
+  // BIOS should program PDO in PEI phase by default
+  //
+  UsbConfig->PdoProgramming = TRUE;
+
+  //
+  // Default values of USB2 AFE settings.
+  //
+  UsbConfig->Usb2PhySusPgEnable = TRUE;
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++) {
+    UsbConfig->PortUsb20[PortIndex].Afe.Petxiset  = 3;
+    UsbConfig->PortUsb20[PortIndex].Afe.Txiset    = 2;
+    UsbConfig->PortUsb20[PortIndex].Afe.Predeemp  = 1;
+    UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit = 1;
+  }
+
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+    UsbConfig->PortUsb30HsioRx[PortIndex].HsioOlfpsCfgPullUpDwnRes = 3;
+  }
+
+  UsbConfig->XhciOcLock = TRUE;
+
+  //
+  // xDCI configuration
+  //
+  UsbConfig->XdciConfig.Enable = FALSE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadEspiConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_ESPI_CONFIG  *EspiConfig;
+  EspiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Name = %g\n", &EspiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", EspiConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Espi configuration.
+  ********************************/
+  EspiConfig->BmeMasterSlaveEnabled = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCnviConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_CNVI_CONFIG  *CnviConfig;
+  CnviConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Name = %g\n", &CnviConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CnviConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Cnvi configuration.
+  ********************************/
+  CnviConfig->Mode = CnviModeAuto; // Automatic detection
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHsioConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HSIO_CONFIG  *HsioConfig;
+  HsioConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Name = %g\n", &HsioConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HsioConfig->Header.GuidHob.Header.HobLength));
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchIpBlocks [] = {
+  {&gPchGeneralConfigGuid,       sizeof (PCH_GENERAL_CONFIG),           PCH_GENERAL_CONFIG_REVISION,       LoadPchGeneralConfigDefault},
+  {&gPcieRpConfigGuid,           sizeof (PCH_PCIE_CONFIG),              PCIE_RP_CONFIG_REVISION,           LoadPcieRpConfigDefault},
+  {&gSataConfigGuid,             sizeof (PCH_SATA_CONFIG),              SATA_CONFIG_REVISION,              LoadSataConfigDefault},
+  {&gIoApicConfigGuid,           sizeof (PCH_IOAPIC_CONFIG),            IOAPIC_CONFIG_REVISION,            LoadIoApicConfigDefault},
+  {&gDmiConfigGuid,              sizeof (PCH_DMI_CONFIG),               DMI_CONFIG_REVISION,               LoadDmiConfigDefault},
+  {&gFlashProtectionConfigGuid,  sizeof (PCH_FLASH_PROTECTION_CONFIG),  FLASH_PROTECTION_CONFIG_REVISION,  LoadFlashProtectionConfigDefault},
+  {&gHdAudioConfigGuid,          sizeof (PCH_HDAUDIO_CONFIG),           HDAUDIO_CONFIG_REVISION,           LoadHdAudioConfigDefault},
+  {&gInterruptConfigGuid,        sizeof (PCH_INTERRUPT_CONFIG),         INTERRUPT_CONFIG_REVISION,         LoadInterruptConfigDefault},
+  {&gIshConfigGuid,              sizeof (PCH_ISH_CONFIG),               ISH_CONFIG_REVISION,               LoadIshConfigDefault},
+  {&gLanConfigGuid,              sizeof (PCH_LAN_CONFIG),               LAN_CONFIG_REVISION,               LoadLanConfigDefault},
+  {&gLockDownConfigGuid,         sizeof (PCH_LOCK_DOWN_CONFIG),         LOCK_DOWN_CONFIG_REVISION,         LoadLockDownConfigDefault},
+  {&gP2sbConfigGuid,             sizeof (PCH_P2SB_CONFIG),              P2SB_CONFIG_REVISION,              LoadP2sbConfigDefault},
+  {&gPmConfigGuid,               sizeof (PCH_PM_CONFIG),                PM_CONFIG_REVISION,                LoadPmConfigDefault},
+  {&gScsConfigGuid,              sizeof (PCH_SCS_CONFIG),               SCS_CONFIG_REVISION,               LoadScsConfigDefault},
+  {&gSerialIoConfigGuid,         sizeof (PCH_SERIAL_IO_CONFIG),         SERIAL_IO_CONFIG_REVISION,         LoadSerialIoConfigDefault},
+  {&gSerialIrqConfigGuid,        sizeof (PCH_LPC_SIRQ_CONFIG),          SERIAL_IRQ_CONFIG_REVISION,        LoadSerialIrqConfigDefault},
+  {&gThermalConfigGuid,          sizeof (PCH_THERMAL_CONFIG),           THERMAL_CONFIG_REVISION,           LoadThermalConfigDefault},
+  {&gUsbConfigGuid,              sizeof (USB_CONFIG),                   USB_CONFIG_REVISION,               LoadUsbConfigDefault},
+  {&gEspiConfigGuid,             sizeof (PCH_ESPI_CONFIG),              ESPI_CONFIG_REVISION,              LoadEspiConfigDefault},
+  {&gCnviConfigGuid,             sizeof (PCH_CNVI_CONFIG),              CNVI_CONFIG_REVISION,              LoadCnviConfigDefault},
+  {&gHsioConfigGuid,             sizeof (PCH_HSIO_CONFIG),              HSIO_CONFIG_REVISION,              LoadHsioConfigDefault},
+};
+
+/**
+  Get PCH config block table total size.
+
+  @retval                               Size of PCH config block table
+**/
+UINT16
+EFIAPI
+PchGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mPchIpBlocks[0], sizeof (mPchIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  PchAddConfigBlocks add all PCH config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "PCH AddConfigBlocks\n"));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mPchIpBlocks[0], sizeof (mPchIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c
new file mode 100644
index 0000000000..d19692ff2c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c
@@ -0,0 +1,169 @@
+/** @file
+  This file is PeiPchPolicy library Cannon Lake specific.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+
+/**
+  mDevIntConfig[] table contains data on INTx and IRQ for each device.
+  IRQ value for devices which use ITSS INTx->PIRQx mapping need to be set in a way
+  that for each multifunctional Dxx:Fy same interrupt pins must map to the same IRQ.
+  Those IRQ values will be used to update ITSS.PIRx register.
+  In APIC relationship between PIRQs and IRQs is:
+  PIRQA -> IRQ16
+  PIRQB -> IRQ17
+  PIRQC -> IRQ18
+  PIRQD -> IRQ19
+  PIRQE -> IRQ20
+  PIRQF -> IRQ21
+  PIRQG -> IRQ22
+  PIRQH -> IRQ23
+
+  Devices which use INTx->PIRQy mapping are: cAVS(in PCI mode), SMBus, GbE, TraceHub, PCIe,
+  SATA, HECI, IDE-R, KT Redirection, xHCI, Thermal Subsystem, Camera IO Host Controller
+
+  PCI Express Root Ports mapping should be programmed only with values as in below table (D27/28/29)
+  otherwise _PRT methods in ACPI for RootPorts would require additional patching as
+  PCIe Endpoint Device Interrupt is further subjected to INTx to PIRQy Mapping
+
+  Configured IRQ values are not used if an OS chooses to be in PIC instead of APIC mode
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG mDevIntConfig[] = {
+//  {31, 0, PchNoInt, 0}, // LPC/eSPI Interface, doesn't use interrupts
+//  {31, 1, PchNoInt, 0}, // P2SB, doesn't use interrupts
+//  {31, 2, PchNoInt, 0}, // PMC , doesn't use interrupts
+  {31, 3, PchIntA, 16}, // cAVS(Audio, Voice, Speach), INTA is default, programmed in PciCfgSpace 3Dh
+  {31, 4, PchIntA, 16}, // SMBus Controller, no default value, programmed in PciCfgSpace 3Dh
+//  {31, 5, PchNoInt, 0}, // SPI , doesn't use interrupts
+  {31, 7, PchIntA, 16}, // TraceHub, INTA is default, RO register
+  {30, 0, PchIntA, 20}, // SerialIo: UART #0, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[7]
+  {30, 1, PchIntB, 21}, // SerialIo: UART #1, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[8]
+  {30, 2, PchIntC, 22}, // SerialIo: SPI #0, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[10]
+  {30, 3, PchIntD, 23}, // SerialIo: SPI #1, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[11]
+  {28, 0, PchIntA, 16}, // PCI Express Port 1, INT is default, programmed in PciCfgSpace + FCh
+  {28, 1, PchIntB, 17}, // PCI Express Port 2, INT is default, programmed in PciCfgSpace + FCh
+  {28, 2, PchIntC, 18}, // PCI Express Port 3, INT is default, programmed in PciCfgSpace + FCh
+  {28, 3, PchIntD, 19}, // PCI Express Port 4, INT is default, programmed in PciCfgSpace + FCh
+  {28, 4, PchIntA, 16}, // PCI Express Port 5, INT is default, programmed in PciCfgSpace + FCh
+  {28, 5, PchIntB, 17}, // PCI Express Port 6, INT is default, programmed in PciCfgSpace + FCh
+  {28, 6, PchIntC, 18}, // PCI Express Port 7, INT is default, programmed in PciCfgSpace + FCh
+  {28, 7, PchIntD, 19}, // PCI Express Port 8, INT is default, programmed in PciCfgSpace + FCh
+  {25, 2, PchIntC, 34}, // SerialIo UART Controller #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[9]
+//  {24, 0, 0, 0}, // Reserved (used by RST PCIe Storage Cycle Router)
+  {23, 0, PchIntA, 16}, // SATA Controller, INTA is default, programmed in PciCfgSpace + 3Dh
+  {22, 0, PchIntA, 16}, // CSME: HECI #1
+  {22, 1, PchIntB, 17}, // CSME: HECI #2
+  {22, 4, PchIntA, 16}, // CSME: HECI #3
+//  {22, 7, PchNoInt, 0}, // CSME: WLAN
+  {21, 0, PchIntA, 16}, // SerialIo I2C Controller #0, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[1]
+  {21, 1, PchIntB, 17}, // SerialIo I2C Controller #1, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[2]
+  {21, 2, PchIntC, 18}, // SerialIo I2C Controller #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[3]
+  {21, 3, PchIntD, 19}, // SerialIo I2C Controller #3, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[4]
+  {20, 0, PchIntA, 16}, // USB 3.0 xHCI Controller, no default value, programmed in PciCfgSpace 3Dh
+  {20, 1, PchIntB, 17}, // USB Device Controller (OTG)
+  //{20, 2, PchNoInt, 0}, // Shared SRAM, no interrupts
+  {20, 3, PchIntA, 16}, // CNVi WiFir
+//  {20, 4, 0, 0}, // TraceHub Phantom (ACPI) Function
+  {20, 5, PchIntD, 19}, // SCS: SDCard
+//  {18, 0, PchNoInt, 0}, // CSME: KVMcc,  doesn't use interrupts
+//  {18, 1, PchNoInt, 0}, // CSME: Clink,  doesn't use interrupts
+//  {18, 2, PchNoInt, 0}, // CSME: PMT,  doesn't use interrupts
+//  {18, 3, 0, 0}, // CSME: CSE UMA
+//  {18, 4, 0, 0}  // CSME: fTPM DMA
+  {18, 5, PchIntA, 16}  // SCS: UFS
+};
+
+//
+// mCnlPchLpOnlyDevIntConfig[] table contains data on INTx and IRQ for devices that exist on PCH-LP
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG mPchLpOnlyDevIntConfig[] = {
+  {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed in PciCfgSpace 3Dh
+  {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programmed in PciCfgSpace + FCh
+  {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programmed in PciCfgSpace + FCh
+  {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programmed in PciCfgSpace + FCh
+  {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programmed in PciCfgSpace + FCh
+  {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programmed in PciCfgSpace + FCh
+  {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programmed in PciCfgSpace + FCh
+  {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programmed in PciCfgSpace + FCh
+  {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programmed in PciCfgSpace + FCh
+  {26, 0, PchIntA, 16}, // SCS: eMMC
+  {25, 0, PchIntA, 32}, // SerialIo I2C Controller #4, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[5]
+  {25, 1, PchIntB, 33}, // SerialIo I2C Controller #5, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[6]
+  {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R)
+  {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection
+  {19, 0, PchIntA, 20}, // Integrated Sensor Hub
+  {18, 0, PchIntA, 16}, // Thermal Subsystem
+  {18, 6, PchIntB, 24}  // SerialIo: SPI #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[12]
+};
+
+//
+// mPchHOnlyDevIntConfig[] table contains data on INTx and IRQ for devices that exist on PCH-H
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG mPchHOnlyDevIntConfig[] = {
+  {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed in PciCfgSpace 3Dh
+  {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programmed in PciCfgSpace + FCh
+  {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programmed in PciCfgSpace + FCh
+  {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programmed in PciCfgSpace + FCh
+  {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programmed in PciCfgSpace + FCh
+  {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programmed in PciCfgSpace + FCh
+  {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programmed in PciCfgSpace + FCh
+  {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programmed in PciCfgSpace + FCh
+  {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programmed in PciCfgSpace + FCh
+  {27, 0, PchIntA, 16}, // PCI Express Port 17, INT is default, programmed in PciCfgSpace + FCh
+  {27, 1, PchIntB, 17}, // PCI Express Port 18, INT is default, programmed in PciCfgSpace + FCh
+  {27, 2, PchIntC, 18}, // PCI Express Port 19, INT is default, programmed in PciCfgSpace + FCh
+  {27, 3, PchIntD, 19}, // PCI Express Port 20, INT is default, programmed in PciCfgSpace + FCh
+  {27, 4, PchIntA, 16}, // PCI Express Port 21
+  {27, 5, PchIntB, 17}, // PCI Express Port 22
+  {27, 6, PchIntC, 18}, // PCI Express Port 23
+  {27, 7, PchIntD, 19}, // PCI Express Port 24
+  {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R)
+  {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection
+  {19, 0, PchIntA, 20}, // Integrated Sensor Hub
+  {18, 0, PchIntA, 16}, // Thermal Subsystem
+  {18, 6, PchIntB, 24}  // SerialIo: SPI #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[12]
+};
+
+/**
+  Adds interrupt configuration for device
+
+  @param[in/out] InterruptConfig         Pointer to interrupt config
+**/
+VOID
+LoadDeviceInterruptConfig (
+  IN OUT  PCH_INTERRUPT_CONFIG  *InterruptConfig
+  )
+{
+  UINT8                 IntConfigTableEntries;
+
+  IntConfigTableEntries = ARRAY_SIZE (mDevIntConfig);
+  ASSERT (IntConfigTableEntries <= PCH_MAX_DEVICE_INTERRUPT_CONFIG);
+  InterruptConfig->NumOfDevIntConfig = IntConfigTableEntries;
+  CopyMem (
+    InterruptConfig->DevIntConfig,
+    mDevIntConfig,
+    sizeof (mDevIntConfig)
+    );
+
+  if (IsPchLp ()) {
+    CopyMem (
+      &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]),
+      mPchLpOnlyDevIntConfig,
+      sizeof (mPchLpOnlyDevIntConfig)
+      );
+    InterruptConfig->NumOfDevIntConfig += ARRAY_SIZE (mPchLpOnlyDevIntConfig);
+  } else if (IsPchH ()) {
+    CopyMem (
+      &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]),
+      mPchHOnlyDevIntConfig,
+      sizeof (mPchHOnlyDevIntConfig)
+      );
+    InterruptConfig->NumOfDevIntConfig += ARRAY_SIZE (mPchHOnlyDevIntConfig);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c
new file mode 100644
index 0000000000..dfab5d29c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c
@@ -0,0 +1,318 @@
+/** @file
+  This file is PeiPchPreMemPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Library/CpuPlatformLib.h>
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchGeneralPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_GENERAL_PREMEM_CONFIG  *PchGeneralPreMemConfig;
+  PchGeneralPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PchGeneralPreMemConfig->Header.GuidHob.Name = %g\n", &PchGeneralPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    PCH general premem configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadDciPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_DCI_PREMEM_CONFIG  *DciPreMemConfig;
+  DciPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "DciPreMemConfig->Header.GuidHob.Name = %g\n", &DciPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "DciPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", DciPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    DCI Configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadWatchDogPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_WDT_PREMEM_CONFIG       *WdtPreMemConfig;
+  WdtPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "WdtPreMemConfig->Header.GuidHob.Name = %g\n", &WdtPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "WdtPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", WdtPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchTraceHubPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_TRACE_HUB_PREMEM_CONFIG  *PchTraceHubPreMemConfig;
+  PchTraceHubPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PchTraceHubPreMemConfig->Header.GuidHob.Name = %g\n", &PchTraceHubPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusRsvdAddresses[] = {
+  0xA0,
+  0xA2,
+  0xA4,
+  0xA6
+};
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSmbusPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_SMBUS_PREMEM_CONFIG  *SmbusPreMemConfig;
+  SmbusPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SmbusPreMemConfig->Header.GuidHob.Name = %g\n", &SmbusPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SmbusPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SmbusPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    SMBus configuration
+  ********************************/
+  SmbusPreMemConfig->Enable                = TRUE;
+  SmbusPreMemConfig->DynamicPowerGating    = TRUE;
+  SmbusPreMemConfig->SpdWriteDisable       = TRUE;
+  SmbusPreMemConfig->SmbusIoBase           = PcdGet16 (PcdSmbusBaseAddress);
+  ASSERT (sizeof (mSmbusRsvdAddresses) <= PCH_MAX_SMBUS_RESERVED_ADDRESS);
+  SmbusPreMemConfig->NumRsvdSmbusAddresses = sizeof (mSmbusRsvdAddresses);
+  CopyMem (
+    SmbusPreMemConfig->RsvdSmbusAddressTable,
+    mSmbusRsvdAddresses,
+    sizeof (mSmbusRsvdAddresses)
+    );
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadLpcPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LPC_PREMEM_CONFIG  *LpcPreMemConfig;
+  LpcPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "LpcPreMemConfig->Header.GuidHob.Name = %g\n", &LpcPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "LpcPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", LpcPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    LPC Configuration
+  ********************************/
+  LpcPreMemConfig->EnhancePort8xhDecoding     = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHsioPciePreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HSIO_PCIE_PREMEM_CONFIG  *HsioPciePreMemConfig;
+  HsioPciePreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HsioPciePreMemConfig->Header.GuidHob.Name = %g\n", &HsioPciePreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HsioPciePreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HsioPciePreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHsioSataPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HSIO_SATA_PREMEM_CONFIG  *HsioSataPreMemConfig;
+  HsioSataPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HsioSataPreMemConfig->Header.GuidHob.Name = %g\n", &HsioSataPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HsioSataPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HsioSataPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Get Hsio Sata Pre Mem Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Pointer to Hsio Sata Pre Mem Config Policy
+**/
+PCH_HSIO_SATA_PREMEM_CONFIG *
+GetPchHsioSataPreMemConfig (
+  IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy,
+  IN UINT32               SataCtrlIndex
+  )
+{
+  PCH_HSIO_SATA_PREMEM_CONFIG     *HsioSataPreMemConfig;
+  EFI_STATUS                      Status;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  HsioSataPreMemConfig += SataCtrlIndex;
+
+  return HsioSataPreMemConfig;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPcieRpPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_PCIE_RP_PREMEM_CONFIG  *PcieRpPreMemConfig;
+  UINT32                     RpIndex;
+
+  PcieRpPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name = %g\n", &PcieRpPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieRpPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  for (RpIndex = 0; RpIndex < GetPchMaxPciePortNum (); RpIndex ++) {
+    PcieRpPreMemConfig->RpEnabledMask |= (UINT32) (1 << RpIndex);
+  }
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHdAudioPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HDAUDIO_PREMEM_CONFIG  *HdaPreMemConfig;
+  HdaPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name = %g\n", &HdaPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HdaPreMemConfig->Header.GuidHob.Header.HobLength));
+  HdaPreMemConfig->Enable = 1;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadIshPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_ISH_PREMEM_CONFIG  *IshPreMemConfig;
+  IshPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name = %g\n", &IshPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", IshPreMemConfig->Header.GuidHob.Header.HobLength));
+  //Enable ISH controller for Non-Desktop sku platforms
+  if (GetCpuSku () != EnumCpuTrad) {
+    IshPreMemConfig->Enable = TRUE;
+  }
+}
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchIpBlocksPreMem [] = {
+  {&gPchGeneralPreMemConfigGuid,     sizeof (PCH_GENERAL_PREMEM_CONFIG),    PCH_GENERAL_PREMEM_CONFIG_REVISION,        LoadPchGeneralPreMemConfigDefault},
+  {&gDciPreMemConfigGuid,            sizeof (PCH_DCI_PREMEM_CONFIG),        DCI_PREMEM_CONFIG_REVISION,                LoadDciPreMemConfigDefault},
+  {&gWatchDogPreMemConfigGuid,       sizeof (PCH_WDT_PREMEM_CONFIG),        WATCH_DOG_PREMEM_CONFIG_REVISION,          LoadWatchDogPreMemConfigDefault},
+  {&gPchTraceHubPreMemConfigGuid,    sizeof (PCH_TRACE_HUB_PREMEM_CONFIG),  PCH_TRACEHUB_PREMEM_CONFIG_REVISION,       LoadPchTraceHubPreMemConfigDefault},
+  {&gSmbusPreMemConfigGuid,          sizeof (PCH_SMBUS_PREMEM_CONFIG),      SMBUS_PREMEM_CONFIG_REVISION,              LoadSmbusPreMemConfigDefault},
+  {&gLpcPreMemConfigGuid,            sizeof (PCH_LPC_PREMEM_CONFIG),        LPC_PREMEM_CONFIG_REVISION,                LoadLpcPreMemConfigDefault},
+  {&gHsioPciePreMemConfigGuid,       sizeof (PCH_HSIO_PCIE_PREMEM_CONFIG),  HSIO_PCIE_PREMEM_CONFIG_REVISION,          LoadHsioPciePreMemConfigDefault},
+  {&gHsioSataPreMemConfigGuid,       sizeof (PCH_HSIO_SATA_PREMEM_CONFIG),  HSIO_SATA_PREMEM_CONFIG_REVISION,          LoadHsioSataPreMemConfigDefault},
+  {&gPcieRpPreMemConfigGuid,         sizeof (PCH_PCIE_RP_PREMEM_CONFIG),    PCIE_RP_PREMEM_CONFIG_REVISION,            LoadPcieRpPreMemConfigDefault},
+  {&gHdAudioPreMemConfigGuid,        sizeof (PCH_HDAUDIO_PREMEM_CONFIG),    HDAUDIO_PREMEM_CONFIG_REVISION,            LoadHdAudioPreMemConfigDefault},
+  {&gIshPreMemConfigGuid,            sizeof (PCH_ISH_PREMEM_CONFIG),        ISH_PREMEM_CONFIG_REVISION,                LoadIshPreMemConfigDefault},
+};
+
+/**
+  Get PCH PREMEM config block table total size.
+
+  @retval                               Size of PCH PREMEM config block table
+**/
+UINT16
+EFIAPI
+PchGetPreMemConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mPchIpBlocksPreMem[0], sizeof (mPchIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  PchAddPreMemConfigBlocks add all PCH PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "PCH AddPreMemConfigBlocks\n"));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mPchIpBlocksPreMem[0], sizeof (mPchIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
new file mode 100644
index 0000000000..2210344462
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
@@ -0,0 +1,109 @@
+/** @file
+  PCH RESET PEIM DRIVER.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/Reset2.h>
+#include <Ppi/PchReset.h>
+#include <Library/PchResetLib.h>
+#include <Library/ResetSystemLib.h>
+
+
+/**
+  Resets the entire platform.
+
+  @param[in] ResetType            UEFI defined reset type.
+  @param[in] ResetStatus          The status code for the reset.
+  @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
+ResetSystem (
+  IN EFI_RESET_TYPE     ResetType,
+  IN EFI_STATUS         ResetStatus,
+  IN UINTN              DataSize,
+  IN VOID               *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+  case EfiResetWarm:
+    ResetWarm ();
+    break;
+
+  case EfiResetCold:
+    ResetCold ();
+    break;
+
+  case EfiResetShutdown:
+    ResetShutdown ();
+    return;
+
+  case EfiResetPlatformSpecific:
+    ResetPlatformSpecific (DataSize, ResetData);
+    return;
+
+  default:
+    return;
+  }
+
+  //
+  // Given we should have reset getting here would be bad
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop();
+}
+
+/**
+  Initialize PCH Reset APIs
+
+  @retval EFI_SUCCESS             APIs are installed successfully
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
+**/
+EFI_STATUS
+EFIAPI
+PchInitializeReset (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  EFI_PEI_RESET2_PPI        *EfiPeiReset2Ppi;
+  EFI_PEI_PPI_DESCRIPTOR    *EfiPeiReset2Descriptor;
+
+  DEBUG ((DEBUG_INFO, "PchInitializeReset() Start\n"));
+
+
+  EfiPeiReset2Descriptor = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  EfiPeiReset2Ppi = (EFI_PEI_RESET2_PPI *) AllocateZeroPool (sizeof (EFI_PEI_RESET2_PPI));
+  if ((EfiPeiReset2Descriptor == NULL) ||
+      (EfiPeiReset2Ppi == NULL)) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  ///
+  /// Initialize the EFI Reset2 ppi instance
+  ///
+  EfiPeiReset2Ppi->ResetSystem  = ResetSystem;
+
+  EfiPeiReset2Descriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  EfiPeiReset2Descriptor->Guid  = &gEfiPeiReset2PpiGuid;
+  EfiPeiReset2Descriptor->Ppi   = EfiPeiReset2Ppi;
+
+  Status = PeiServicesInstallPpi (EfiPeiReset2Descriptor);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "PchInitializeReset() End\n"));
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c
new file mode 100644
index 0000000000..58f2d86103
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c
@@ -0,0 +1,257 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchResetLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Ppi/PchReset.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.h>
+
+/**
+  Dump reset message for debug build readability
+**/
+VOID
+DumpResetMessage (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINTN       Index;
+  //
+  // ******************************
+  // **    SYSTEM REBOOT !!!     **
+  // ******************************
+  //
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG_CODE_END ();
+}
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+**/
+VOID
+PchResetCallback (
+  IN  EFI_RESET_TYPE      ResetType,
+  IN  EFI_GUID            *ResetTypeGuid
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   Instance;
+  PCH_RESET_CALLBACK_PPI  *PchResetCallbackPpi;
+
+  Instance = 0;
+  do {
+    Status = PeiServicesLocatePpi (
+               &gPchResetCallbackPpiGuid,
+               Instance,
+               NULL,
+               (VOID **) &PchResetCallbackPpi
+               );
+
+    switch (Status) {
+      case EFI_SUCCESS:
+        PchResetCallbackPpi->ResetCallback (ResetType, ResetTypeGuid);
+        break;
+      case EFI_NOT_FOUND:
+        break;
+      default:
+        ASSERT_EFI_ERROR (Status);
+        break;
+    }
+    ++Instance;
+  } while (Status == EFI_SUCCESS);
+}
+
+/**
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetCold, NULL);
+  DumpResetMessage ();
+
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetWarm, NULL);
+  DumpResetMessage ();
+
+  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;
+
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetShutdown, NULL);
+
+  ABase = PmcGetAcpiBase ();
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+  ///
+  IoWrite32 ((UINTN) (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 ((UINTN) (ABase + R_ACPI_IO_PM1_STS), B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state
+  ///
+  Data32 = IoRead32 ((UINTN) (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 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  DumpResetMessage ();
+
+  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32);
+
+  return;
+}
+
+/**
+  Internal function to execute the required HECI command for GlobalReset,
+  if failed will use PCH Reest.
+
+**/
+STATIC
+VOID
+PchGlobalReset (
+  VOID
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
+
+  //
+  // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
+  //
+  PmcEnableCf9GlobalReset ();
+
+  DumpResetMessage ();
+
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
+}
+
+/**
+  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
+  )
+{
+  EFI_GUID            *GuidPtr;
+
+  if (ResetData == NULL) {
+    DEBUG ((DEBUG_ERROR, "[PeiResetSystemLib] ResetData is not available.\n"));
+    return;
+  }
+  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID));
+  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
+    PchGlobalReset();
+  } else {
+    return;
+  }
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
new file mode 100644
index 0000000000..1a5db7f24a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
@@ -0,0 +1,217 @@
+/** @file
+  PCH SPI PEI Library implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Ppi/Spi.h>
+#include <Private/Library/PchSpiCommonLib.h>
+#include <PchReservedResources.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+
+typedef struct {
+  EFI_PEI_PPI_DESCRIPTOR  PpiDescriptor;
+  SPI_INSTANCE            SpiInstance;
+} PEI_SPI_INSTANCE;
+
+/**
+  PCI Enumeratuion is not done till later in DXE
+  Initlialize SPI BAR0 to a default value till enumeration is done
+  also enable memory space decoding for SPI
+
+**/
+VOID
+InitSpiBar0 (
+  VOID
+  )
+{
+  UINT64       PchSpiBase;
+  PchSpiBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  PciSegmentAnd8 (PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+  PciSegmentWrite32 (PchSpiBase + R_SPI_CFG_BAR0, PCH_SPI_BASE_ADDRESS);
+  PciSegmentOr8 (PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+}
+
+/**
+  This function Initial SPI services
+
+  @retval EFI_STATUS  Results of the installation of the SPI services
+**/
+EFI_STATUS
+EFIAPI
+SpiServiceInit (
+  VOID
+  )
+{
+  EFI_STATUS        Status;
+  PEI_SPI_INSTANCE  *PeiSpiInstance;
+  SPI_INSTANCE      *SpiInstance;
+  PCH_SPI_PPI       *SpiPpi;
+
+  Status = PeiServicesLocatePpi (
+             &gPchSpiPpiGuid,
+             0,
+             NULL,
+             (VOID **)&SpiPpi
+             );
+
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_INFO, "SpiServiceInit() Start\n"));
+
+    //
+    // PCI Enumeratuion is not done till later in DXE
+    // Initlialize SPI BAR0 to a default value till enumeration is done
+    // also enable memory space decoding for SPI
+    //
+    InitSpiBar0 ();
+
+    PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof (PEI_SPI_INSTANCE));
+    if (NULL == PeiSpiInstance) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    SpiInstance = &(PeiSpiInstance->SpiInstance);
+    SpiProtocolConstructor (SpiInstance);
+
+    PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+    PeiSpiInstance->PpiDescriptor.Guid = &gPchSpiPpiGuid;
+    PeiSpiInstance->PpiDescriptor.Ppi = &(SpiInstance->SpiProtocol);
+
+    ///
+    /// Install the SPI PPI
+    ///
+    DEBUG ((DEBUG_INFO, "SPI PPI Installed\n"));
+    Status = PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor);
+    ASSERT_EFI_ERROR (Status);
+
+    DEBUG ((DEBUG_INFO, "SpiServiceInit() End\n"));
+  }
+  else {
+    DEBUG ((DEBUG_INFO, "SPI PPI already installed\n"));
+  }
+  return Status;
+}
+
+/**
+  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
+  )
+{
+  return PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
+}
+
+/**
+  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 = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & B_SPI_CFG_BC_EISS) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  ///
+  /// Enable the access to the BIOS space for both read and write cycles
+  ///
+  PciSegmentOr8 (
+    SpiBaseAddress + R_SPI_CFG_BC,
+    B_SPI_CFG_BC_WPD
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+  VOID
+  )
+{
+  UINT64           SpiBaseAddress;
+
+  SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  ///
+  /// Disable the access to the BIOS space for write cycles
+  ///
+  PciSegmentAnd8 (
+    SpiBaseAddress + R_SPI_CFG_BC,
+    (UINT8) (~B_SPI_CFG_BC_WPD)
+    );
+}
+
+/**
+  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
+  )
+{
+  return TRUE;
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (18 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
                   ` (17 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH SMM library class instances.

* SmmSpiFlashCommonLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf |  51 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c         | 196 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c   |  54 ++++++
 3 files changed, 301 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
new file mode 100644
index 0000000000..abc919867c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,51 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmSpiFlashCommonLib
+  FILE_GUID                      = 9632D96E-E849-4217-9217-DC500B8AAE47
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  LIBRARY_CLASS                  = SpiFlashCommonLib|DXE_SMM_DRIVER
+  CONSTRUCTOR                    = SmmSpiFlashCommonLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+  PciLib
+  IoLib
+  MemoryAllocationLib
+  BaseLib
+  UefiLib
+  SmmServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  MmPciLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress  ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdBiosSize         ## CONSUMES
+
+[Sources]
+  SpiFlashCommonSmmLib.c
+  SpiFlashCommon.c
+
+[Protocols]
+  gPchSmmSpiProtocolGuid                        ## CONSUMES
+
+[Depex.X64.DXE_SMM_DRIVER]
+  gPchSmmSpiProtocolGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
new file mode 100644
index 0000000000..53711db632
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
@@ -0,0 +1,196 @@
+/** @file
+  Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
+  for module use.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <PchAccess.h>
+#include <Library/MmPciLib.h>
+#include <Protocol/Spi.h>
+
+
+PCH_SPI_PROTOCOL       *mSpiProtocol;
+
+//
+// FlashAreaBaseAddress and Size for boottime and runtime usage.
+//
+UINTN mFlashAreaBaseAddress = 0;
+UINTN mFlashAreaSize        = 0;
+
+/**
+  Enable block protection on the Serial Flash device.
+
+  @retval     EFI_SUCCESS       Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      Address       The starting physical address of the read.
+  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
+                                of bytes actually read.
+  @param[out]     Buffer        The destination data buffer for the read.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN                        Address,
+  IN OUT UINT32                       *NumBytes,
+     OUT UINT8                        *Buffer
+  )
+{
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // This function is implemented specifically for those platforms
+  // at which the SPI device is memory mapped for read. So this
+  // function just do a memory copy for Spi Flash Read.
+  //
+  CopyMem (Buffer, (VOID *) Address, *NumBytes);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      Address         The starting physical address of the write.
+  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
+                                  the actual number of bytes written.
+  @param[in]      Buffer          The source data buffer for the write.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN                      Address,
+  IN OUT UINT32                     *NumBytes,
+  IN     UINT8                      *Buffer
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Offset;
+  UINT32                    Length;
+  UINT32                    RemainingBytes;
+
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ASSERT (Address >= mFlashAreaBaseAddress);
+
+  Offset = Address - mFlashAreaBaseAddress;
+
+  ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+
+  while (RemainingBytes > 0) {
+    if (RemainingBytes > SECTOR_SIZE_4KB) {
+      Length = SECTOR_SIZE_4KB;
+    } else {
+      Length = RemainingBytes;
+    }
+    Status = mSpiProtocol->FlashWrite (
+                             mSpiProtocol,
+                             FlashRegionBios,
+                             (UINT32) Offset,
+                             Length,
+                             Buffer
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    RemainingBytes -= Length;
+    Offset += Length;
+    Buffer += Length;
+  }
+
+  //
+  // Actual number of bytes written
+  //
+  *NumBytes -= RemainingBytes;
+
+  return Status;
+}
+
+/**
+  Erase the block starting at Address.
+
+  @param[in]  Address         The starting physical address of the block to be erased.
+                              This library assume that caller garantee that the PAddress
+                              is at the starting address of this block.
+  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
+                              On output, the actual number of bytes erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN    UINTN                     Address,
+  IN    UINTN                     *NumBytes
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Offset;
+  UINTN               RemainingBytes;
+
+  ASSERT (NumBytes != NULL);
+  if (NumBytes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ASSERT (Address >= mFlashAreaBaseAddress);
+
+  Offset = Address - mFlashAreaBaseAddress;
+
+  ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0);
+  ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+
+  Status = mSpiProtocol->FlashErase (
+                           mSpiProtocol,
+                           FlashRegionBios,
+                           (UINT32) Offset,
+                           (UINT32) RemainingBytes
+                           );
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
new file mode 100644
index 0000000000..43c0218d85
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
@@ -0,0 +1,54 @@
+/** @file
+  SMM Library instance of SPI Flash Common Library Class
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/Spi.h>
+
+extern PCH_SPI_PROTOCOL   *mSpiProtocol;
+
+extern UINTN mFlashAreaBaseAddress;
+extern UINTN mFlashAreaSize;
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library
+  instance.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+**/
+EFI_STATUS
+EFIAPI
+SmmSpiFlashCommonLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  mFlashAreaBaseAddress = (UINTN)PcdGet32 (PcdBiosAreaBaseAddress);
+  mFlashAreaSize        = (UINTN)PcdGet32 (PcdBiosSize);
+
+  //
+  // Locate the SMM SPI protocol.
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gPchSmmSpiProtocolGuid,
+                    NULL,
+                    (VOID **) &mSpiProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (19 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
                   ` (16 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds Pch/Library/Private Base library class instances.

* BaseGpioHelpersLibNull
* BasePchSpiCommonlib
* BaseSiScheduleResetLib
* BaseSiScheduleResetLibFsp

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf     |   26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf           |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf     |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf  |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c       |  108 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c                       | 1081 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c       |   70 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c |  125 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c    |   61 ++
 9 files changed, 1579 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
new file mode 100644
index 0000000000..5502af824f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
@@ -0,0 +1,26 @@
+## @file
+# Component description file for the NULL GpioHelpersLib
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseGpioHelpersLibNull.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
new file mode 100644
index 0000000000..ea23e628c8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,28 @@
+## @file
+#  Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BasePchSpiCommonLib
+  FILE_GUID                      = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchSpiCommonLib
+
+[Sources]
+  SpiCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PmcLib
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
new file mode 100644
index 0000000000..de7f6eeb73
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for Si Reset Schedule Library.
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Guids]
+gSiScheduleResetHobGuid
+gPchConfigHobGuid
+
+[Sources]
+BaseSiScheduleResetLibCommon.c
+BaseSiScheduleResetLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf
new file mode 100644
index 0000000000..c8fe9e6079
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for Si Reset Schedule Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSiScheduleResetLibFsp
+FILE_GUID = 1478D005-8DEC-4A6E-9619-309C6A7F313A
+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
+PeiServicesTablePointerLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Guids]
+gSiScheduleResetHobGuid
+gPchConfigHobGuid
+
+[Sources]
+BaseSiScheduleResetLibCommon.c
+BaseSiScheduleResetLibFsp.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
new file mode 100644
index 0000000000..46390eeca1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
@@ -0,0 +1,108 @@
+/** @file
+  This file contains NULL implementation for GPIO Helpers Lib
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c
new file mode 100644
index 0000000000..bc84a4f27f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c
@@ -0,0 +1,1081 @@
+/** @file
+  PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPmc.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;
+
+  //
+  // 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 = PCI_SEGMENT_LIB_ADDRESS (
+                              DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                              DEFAULT_PCI_BUS_NUMBER_PCH,
+                              PCI_DEVICE_NUMBER_PCH_SPI,
+                              PCI_FUNCTION_NUMBER_PCH_SPI,
+                              0
+                              );
+
+  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_SPI_FLASH_FDBAR_FLASH_MAP0)
+    );
+
+  //
+  // Copy Zero based Number Of Components
+  //
+  SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16 (PchSpiBar0 + R_SPI_MEM_FDOD) & B_SPI_FLASH_FDBAR_NC) >> N_SPI_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_SPI_FLASH_FCBA_FLCOMP)
+    );
+
+  //
+  // Copy Component 0 Density
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  if (SpiInstance->NumberOfComponents > 0) {
+    SpiInstance->Component1StartAddr = V_SPI_FLASH_FLCOMP_COMP_512KB <<
+      (Data32 & B_SPI_FLASH_FLCOMP_COMP0_MASK);
+    DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n", SpiInstance->Component1StartAddr));
+    SpiInstance->TotalFlashSize = SpiInstance->Component1StartAddr +
+      (V_SPI_FLASH_FLCOMP_COMP_512KB <<
+      ((Data32 & B_SPI_FLASH_FLCOMP_COMP1_MASK) >>
+      N_SPI_FLASH_FLCOMP_COMP1));
+  } else {
+    SpiInstance->TotalFlashSize = V_SPI_FLASH_FLCOMP_COMP_512KB <<
+      (Data32 & B_SPI_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_SPI_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_SPI_FLASH_FDBAR_FPSBA)
+                                             >> N_SPI_FLASH_FDBAR_FPSBA)
+                                            << N_SPI_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_SPI_FLASH_FDBAR_PCHSL)
+                                         >> N_SPI_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_SPI_FLASH_FDBAR_FLASH_MAP2)
+    );
+  //
+  // Align FPSBA with address bits for the PCH Strap portion of flash descriptor
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  SpiInstance->CpuStrapBaseAddr = (UINT16) (((Data32 & B_SPI_FLASH_FDBAR_FCPUSBA)
+                                             >> N_SPI_FLASH_FDBAR_FCPUSBA)
+                                            << N_SPI_FLASH_FDBAR_FCPUSBA_REPR);
+  DEBUG ((DEBUG_INFO, "CpuStrapBaseAddr : %0x\n", SpiInstance->CpuStrapBaseAddr));
+  ASSERT (SpiInstance->CpuStrapBaseAddr != 0);
+  //
+  // CPU Strap Length, [15:8] represents number of Dwords
+  //
+  SpiInstance->CpuStrapSize = (UINT16) (((Data32 & B_SPI_FLASH_FDBAR_CPUSL)
+                                         >> N_SPI_FLASH_FDBAR_CPUSL)
+                                        * sizeof (UINT32));
+  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 (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.
+**/
+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;
+
+  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.
+**/
+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;
+
+  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.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // 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.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // 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/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
new file mode 100644
index 0000000000..dfc49d9bf6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
@@ -0,0 +1,70 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 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 <Private/Library/SiScheduleResetLib.h>
+#include <Private/SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+SI_SCHEDULE_RESET_HOB *
+SiScheduleGetResetData (
+  VOID
+  );
+
+/**
+  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/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c
new file mode 100644
index 0000000000..e1d783b2e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c
@@ -0,0 +1,125 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Library/HobLib.h>
+#include <Private/SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c
new file mode 100644
index 0000000000..15ac61a21b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c
@@ -0,0 +1,61 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/HobLib.h>
+#include <Private/Library/SiScheduleResetLib.h>
+#include <Private/SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+SI_SCHEDULE_RESET_HOB *
+SiScheduleGetResetData (
+  VOID
+  );
+
+/**
+  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));
+  if (SiScheduleResetHob->ResetType == EfiResetPlatformSpecific) {
+    DataSize = sizeof (PCH_RESET_DATA);
+    (*GetPeiServicesTablePointer ())->ResetSystem2 (SiScheduleResetHob->ResetType, EFI_SUCCESS, DataSize, &SiScheduleResetHob->ResetData);
+  } else {
+    (*GetPeiServicesTablePointer ())->ResetSystem2 (SiScheduleResetHob->ResetType, EFI_SUCCESS, 0, NULL);
+  }
+  //
+  // Code should never reach here
+  //
+  ASSERT (FALSE);
+  return TRUE;
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (20 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
                   ` (15 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH DXE private library class instances.

* DxeGpioNameBufferLib
* DxePchHdaLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf |  32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf                 |  43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c      |  20 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c                | 333 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c                      | 886 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c               | 439 ++++++++++
 6 files changed, 1753 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
new file mode 100644
index 0000000000..0dc8f9749d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
@@ -0,0 +1,32 @@
+## @file
+# Component description file for the DxeGpioMemLib
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+GpioNameBufferDxe.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
new file mode 100644
index 0000000000..a8a3f60b53
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component information file for PCH HD Audio Library
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxePchHdaLib
+FILE_GUID = DA915B7F-EE08-4C1D-B3D0-DE7C52AB155A
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchHdaLib
+
+
+[LibraryClasses]
+BaseLib
+DebugLib
+MemoryAllocationLib
+BaseMemoryLib
+PchInfoLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+
+[Sources]
+PchHdaLib.c
+PchHdaEndpoints.c
+PchHdaNhltConfig.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c
new file mode 100644
index 0000000000..af53387faf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c
@@ -0,0 +1,20 @@
+/** @file
+  This file contains implementation of the GpioMemLib for DXE phase
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Private/Library/GpioNameBufferLib.h>
+
+STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];
+
+CHAR8*
+GpioGetStaticNameBuffer (
+  VOID
+  )
+{
+  return mGpioNameBuffer;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c
new file mode 100644
index 0000000000..ea04512501
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c
@@ -0,0 +1,333 @@
+/** @file
+  This file contains HD Audio NHLT Endpoints definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Private/PchHdaEndpoints.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch1_48kHz16bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    1,
+    48000,
+    96000,
+    2,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_MONO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch2_48kHz16bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    192000,
+    4,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch2_48kHz24bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {24},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch2_48kHz32bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {32},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch4_48kHz16bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    4,
+    48000,
+    384000,
+    8,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_QUAD,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch4_48kHz32bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    4,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {32},
+  KSAUDIO_SPEAKER_QUAD,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE NarrowbandFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    1,
+    8000,
+    16000,
+    2,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_MONO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE WidebandFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    1,
+    16000,
+    32000,
+    2,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_MONO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE A2dpFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {24},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointDmicX1 = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkDmic,   // LinkType
+  0,                 // InstanceId
+  0x8086,            // HwVendorId
+  0xae20,            // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceDmic, // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointDmicX2 = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkDmic,   // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae20,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceDmic, // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointDmicX4 = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkDmic,   // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae20,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceDmic, // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointBtRender = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae30,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceBt,   // DeviceType
+  0,                 // Direction
+  2,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointBtCapture = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae30,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceBt,   // DeviceType
+  1,                 // Direction
+  2,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointI2sRender = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  1,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae34,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceI2s,  // DeviceType
+  0,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointI2sCapture = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  1,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae34,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceI2s,  // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX1Config[] =
+{
+  0x00, // VirtualSlot
+  0x00, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX1ConfigSize = sizeof (DmicX1Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX2Config[] =
+{
+  0x00, // VirtualSlot
+  0x01, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
+  0x0A  // ArrayType
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX2ConfigSize = sizeof (DmicX2Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX4Config[] =
+{
+  0x00, // VirtualSlot
+  0x01, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
+  0x0D  // ArrayType
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX4ConfigSize = sizeof (DmicX4Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  BtConfig[] = {0};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 BtConfigSize = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sRender1Config[] = {0};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRender1ConfigSize = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sRender2Config[] = {0x01};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRender2ConfigSize = sizeof (I2sRender2Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sCaptureConfig[] = {0};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sCaptureConfigSize = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST DEVICE_INFO I2sRenderDeviceInfo =
+{
+  "INT34C2", // DeviceId
+  0x00,      // DeviceInstanceId
+  0x01       // DevicePortId
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST DEVICE_INFO I2sCaptureDeviceInfo =
+{
+  "INT34C2", // DeviceId
+  0x00,      // DeviceInstanceId
+  0x01       // DevicePortId
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 NhltConfiguration[] = { 0xEFBEADDE };
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 NhltConfigurationSize = sizeof (NhltConfiguration);
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c
new file mode 100644
index 0000000000..a87509de1b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c
@@ -0,0 +1,886 @@
+/** @file
+  PCH HD Audio Library implementation.
+
+  Copyright (c) 2019 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 <Private/Library/PchHdaLib.h>
+#include <Library/PchInfoLib.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               i;
+  ENDPOINT_DESCRIPTOR *Endpoint;
+  Endpoint = (ENDPOINT_DESCRIPTOR*) (NhltTable->EndpointDescriptors);
+
+  if (EndpointIndex > NhltTable->EndpointCount) {
+    return NULL;
+  }
+
+  for (i = 0; i < EndpointIndex; i++) {
+    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          i;
+  UINT32         Length;
+  FORMATS_CONFIG *FormatsConfig;
+  FORMAT_CONFIG  *Format;
+
+  Length = 0;
+  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
+  Format = FormatsConfig->FormatsConfiguration;
+
+  if (FormatIndex > FormatsConfig->FormatsCount) {
+    return NULL;
+  }
+
+  for (i = 0; i < FormatIndex; i++) {
+    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) {
+    return NULL;
+  }
+
+  if (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 i;
+
+  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 (i = 0; i < (  Format->FormatConfiguration.CapabilitiesSize ) ; i++) {
+    if (i % 16 == 0) {
+      DEBUG ((DEBUG_VERBOSE, "\n"));
+    }
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Format->FormatConfiguration.Capabilities[i]));
+  }
+  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 i;
+  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 (i = 0; i < (Endpoint->EndpointConfig.CapabilitiesSize ) ; i++) {
+    if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Endpoint->EndpointConfig.Capabilities[i]));
+  }
+
+  FormatsConfigs = GetNhltEndpointFormatsConfig (Endpoint);
+
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, " Endpoint->FormatsConfig.FormatsCount = %d\n", FormatsConfigs->FormatsCount));
+  for (i = 0; i < FormatsConfigs->FormatsCount; i++) {
+    Format = GetNhltEndpointFormat (Endpoint, i);
+    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 (i = 0; i < DevicesInfo->DeviceInfoCount; i++) {
+      DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, i);
+      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 i;
+
+  DEBUG ((DEBUG_INFO, "-------------------------- OED CONFIGURATION -------------------------\n"));
+  DEBUG ((DEBUG_INFO, " OedConfig->CapabilitiesSize = %d B\n", OedConfig->CapabilitiesSize));
+  DEBUG ((DEBUG_VERBOSE, " OedConfig->Capabilities:"));
+  for (i = 0; i < (OedConfig->CapabilitiesSize) ; i++) {
+    if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", OedConfig->Capabilities[i]));
+  }
+
+  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 i;
+
+  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 (i = 0; i < NhltTable->EndpointCount; i++) {
+    NhltEndpointDump (GetNhltEndpoint (NhltTable, i));
+  }
+
+  NhltOedConfigDump (GetNhltOedConfig (NhltTable));
+  DEBUG ((DEBUG_INFO, "----------------------------------------------------------------------\n"));
+
+  DEBUG_CODE_END ();
+}
+
+/**
+  Constructs FORMATS_CONFIGS structure based on given formats list.
+
+  @param[in][out] *Endpoint     Endpoint for which format structures are created
+  @param[in]      FormatBitmask Bitmask of formats supported for given endpoint
+
+  @retval                       Size of created FORMATS_CONFIGS structure
+**/
+UINT32
+NhltFormatsConstructor (
+  IN OUT ENDPOINT_DESCRIPTOR    *Endpoint,
+  IN CONST UINT32               FormatsBitmask
+  )
+{
+  FORMATS_CONFIG *FormatsConfig;
+  FORMAT_CONFIG  *Format;
+  UINT8          FormatIndex;
+  UINT32         FormatsConfigLength;
+
+  DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() Start, FormatsBitmask = 0x%08x\n", FormatsBitmask));
+
+  FormatsConfig = NULL;
+  FormatIndex = 0;
+  FormatsConfigLength = 0;
+
+  if (!FormatsBitmask) {
+    DEBUG ((DEBUG_WARN, "No supported format found!\n"));
+    return 0;
+  }
+
+  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
+  FormatsConfig->FormatsCount = 0;
+
+  if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+      Format->FormatConfiguration.CapabilitiesSize = DmicStereo16BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicStereo16BitFormatConfig, DmicStereo16BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz32bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = DmicStereo32BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicStereo32BitFormatConfig, DmicStereo32BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch4_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+      Format->FormatConfiguration.CapabilitiesSize = DmicQuad16BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicQuad16BitFormatConfig, DmicQuad16BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch4_48kHz32bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = DmicQuad32BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicQuad32BitFormatConfig, DmicQuad32BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch1_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = DmicMono16BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicMono16BitFormatConfig, DmicMono16BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_BT_NARROWBAND_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_NARROWBAND_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &NarrowbandFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_BT_WIDEBAND_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_WIDEBAND_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &WidebandFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_BT_A2DP_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_A2DP_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &A2dpFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = I2sRtk274Render4ch48kHz24bitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, I2sRtk274Render4ch48kHz24bitFormatConfig, I2sRtk274Render4ch48kHz24bitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, I2sRtk274Capture4ch48kHz24bitFormatConfig, I2sRtk274Capture4ch48kHz24bitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() End, FormatsCount = %d, FormatsConfigLength = %d B\n", FormatsConfig->FormatsCount, FormatsConfigLength));
+  return FormatsConfigLength;
+}
+
+/**
+  Constructs DEVICES_INFO structure based on given device info list.
+
+  @param[in][out] *Endpoint      Endpoint for which device info structures are created
+  @param[in]      DevicesBitmask Bitmask of devices supported for given endpoint
+
+  @retval                        Size of created DEVICES_INFO structure
+**/
+UINT32
+NhltDevicesInfoConstructor (
+  IN OUT   ENDPOINT_DESCRIPTOR  *Endpoint,
+  IN CONST UINT32               DevicesBitmask
+  )
+{
+  DEVICES_INFO  *DevicesInfo;
+  DEVICE_INFO   *DeviceInfo;
+  UINT8         DeviceIndex;
+  UINT32        DevicesInfoLength;
+
+  DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() Start, DevicesBitmask = 0x%08x\n", DevicesBitmask));
+
+  DevicesInfo = NULL;
+  DeviceIndex = 0;
+  DevicesInfoLength = 0;
+
+  if (!DevicesBitmask) {
+    return 0;
+  }
+
+  DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
+  if (DevicesInfo == NULL) {
+    return 0;
+  }
+  DevicesInfo->DeviceInfoCount = 0;
+
+  if (DevicesBitmask & B_HDA_I2S_RENDER_DEVICE_INFO) {
+    DEBUG ((DEBUG_INFO, "DeviceInfo: B_HDA_I2S_RENDER_DEVICE_INFO\n"));
+
+    DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
+    if (DeviceInfo != NULL) {
+      CopyMem (DeviceInfo, &I2sRenderDeviceInfo, sizeof (DEVICE_INFO));
+      DevicesInfo->DeviceInfoCount++;
+    }
+  } else if (DevicesBitmask & B_HDA_I2S_CAPTURE_DEVICE_INFO) {
+    DEBUG ((DEBUG_INFO, "DeviceInfo: B_HDA_I2S_CAPTURE_DEVICE_INFO\n"));
+
+    DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
+    if (DeviceInfo != NULL) {
+      CopyMem (DeviceInfo, &I2sCaptureDeviceInfo, sizeof (DEVICE_INFO));
+      DevicesInfo->DeviceInfoCount++;
+    }
+  }
+
+  DevicesInfoLength = DevicesInfo->DeviceInfoCount * sizeof (DEVICE_INFO);
+
+  DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() End, DevicesCount = %d, DevicesInfoLength = %d B\n", DevicesInfo->DeviceInfoCount, DevicesInfoLength));
+  return DevicesInfoLength;
+}
+
+/**
+  Constructs NHLT_ENDPOINT structure based on given endpoint type.
+
+  @param[in][out] *NhltTable              NHLT table for which endpoint is created
+  @param[in]      EndpointType            Type of endpoint to be created
+  @param[in]      EndpointFormatsBitmask  Bitmask of formats supported by endpoint
+  @param[in]      EndpointDevicesBitmask  Bitmask of device info for endpoint
+  @param[in]      EndpointIndex           Endpoint index in NHLT table
+
+  @retval                       Size of created NHLT_ENDPOINT structure
+**/
+UINT32
+NhltEndpointConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable,
+  IN NHLT_ENDPOINT              EndpointType,
+  IN UINT32                     EndpointFormatsBitmask,
+  IN UINT32                     EndpointDevicesBitmask,
+  IN UINT8                      EndpointIndex
+  )
+{
+
+  ENDPOINT_DESCRIPTOR *Endpoint;
+  SPECIFIC_CONFIG     *EndpointConfig;
+  CONST UINT8         *EndpointConfigBuffer;
+  UINT32              EndpointConfigBufferSize;
+  UINT32              EndpointDescriptorLength;
+
+  DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() Start, EndpointIndex = %d\n", EndpointIndex));
+
+  EndpointDescriptorLength = 0;
+  Endpoint = GetNhltEndpoint (NhltTable, EndpointIndex);
+  if (Endpoint == NULL) {
+    return 0;
+  }
+  EndpointDescriptorLength = sizeof (ENDPOINT_DESCRIPTOR)
+    - sizeof (SPECIFIC_CONFIG)
+    - sizeof (FORMAT_CONFIG)
+    - sizeof (DEVICE_INFO);
+
+  switch (EndpointType) {
+    case HdaDmicX1:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX1\n"));
+      CopyMem (Endpoint, &HdaEndpointDmicX1, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = DmicX1Config;
+      EndpointConfigBufferSize = DmicX1ConfigSize;
+      break;
+    case HdaDmicX2:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX2\n"));
+      CopyMem (Endpoint, &HdaEndpointDmicX2, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = DmicX2Config;
+      EndpointConfigBufferSize = DmicX2ConfigSize;
+      break;
+    case HdaDmicX4:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX4\n"));
+      CopyMem (Endpoint, &HdaEndpointDmicX4, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = DmicX4Config;
+      EndpointConfigBufferSize = DmicX4ConfigSize;
+      break;
+    case HdaBtRender:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaBtRender\n"));
+      CopyMem (Endpoint, &HdaEndpointBtRender, sizeof (ENDPOINT_DESCRIPTOR));
+      if (IsPchH ()) {
+        Endpoint->VirtualBusId = 0;
+      }
+
+      EndpointConfigBuffer = BtConfig;
+      EndpointConfigBufferSize = BtConfigSize;
+      break;
+    case HdaBtCapture:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaBtCapture\n"));
+      CopyMem (Endpoint, &HdaEndpointBtCapture, sizeof (ENDPOINT_DESCRIPTOR));
+      if (IsPchH ()) {
+        Endpoint->VirtualBusId = 0;
+      }
+
+      EndpointConfigBuffer = BtConfig;
+      EndpointConfigBufferSize = BtConfigSize;
+      break;
+    case HdaI2sRender1:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender1\n"));
+      CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = I2sRender1Config;
+      EndpointConfigBufferSize = I2sRender1ConfigSize;
+      break;
+    case HdaI2sRender2:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender2\n"));
+      CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = I2sRender2Config;
+      EndpointConfigBufferSize = I2sRender2ConfigSize;
+      break;
+    case HdaI2sCapture:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sCapture\n"));
+      CopyMem (Endpoint, &HdaEndpointI2sCapture, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = I2sCaptureConfig;
+      EndpointConfigBufferSize = I2sCaptureConfigSize;
+      break;
+    default:
+      DEBUG ((DEBUG_WARN, "Unknown endpoint!\n"));
+      return 0;
+  }
+
+  EndpointConfig = GetNhltEndpointDeviceCapabilities (Endpoint);
+  EndpointConfig->CapabilitiesSize = EndpointConfigBufferSize;
+  CopyMem (EndpointConfig->Capabilities, EndpointConfigBuffer, EndpointConfig->CapabilitiesSize);
+  EndpointDescriptorLength += sizeof (*EndpointConfig)
+    - sizeof (EndpointConfig->Capabilities)
+    + EndpointConfig->CapabilitiesSize;
+
+  EndpointDescriptorLength += NhltFormatsConstructor (Endpoint, EndpointFormatsBitmask);
+  EndpointDescriptorLength += NhltDevicesInfoConstructor (Endpoint, EndpointDevicesBitmask);
+
+  Endpoint->EndpointDescriptorLength = EndpointDescriptorLength;
+
+  DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() End, EndpointDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
+  return Endpoint->EndpointDescriptorLength;
+}
+
+/**
+  Constructs SPECIFIC_CONFIG structure for OED configuration.
+
+  @param[in][out] *NhltTable    NHLT table for which OED config is created
+
+  @retval                       Size of created SPECIFIC_CONFIG structure
+**/
+UINT32
+NhltOedConfigConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable
+  )
+{
+  SPECIFIC_CONFIG *OedConfig;
+  UINT32          OedConfigLength;
+
+  OedConfigLength = 0;
+  OedConfig = GetNhltOedConfig (NhltTable);
+
+  OedConfig->CapabilitiesSize = NhltConfigurationSize;
+  CopyMem (OedConfig->Capabilities, (UINT8*) NhltConfiguration, NhltConfigurationSize);
+
+  OedConfigLength = sizeof (*OedConfig)
+    - sizeof (OedConfig->Capabilities)
+    + OedConfig->CapabilitiesSize;
+
+  return OedConfigLength;
+}
+
+/**
+  Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
+
+  @param[in]      *EndpointTable List of endpoints for NHLT
+  @param[in][out] **NhltTable    NHLT table to be created
+  @param[in][out] *NhltTableSize Size of created NHLT table
+
+  @retval EFI_SUCCESS            NHLT created successfully
+  @retval EFI_BAD_BUFFER_SIZE    Not enough resources to allocate NHLT
+**/
+EFI_STATUS
+NhltConstructor (
+  IN PCH_HDA_NHLT_ENDPOINTS     *EndpointTable,
+  IN OUT NHLT_ACPI_TABLE        **NhltTable,
+  IN OUT UINT32                 *NhltTableSize
+  )
+{
+  EFI_STATUS Status;
+  UINT8  Index;
+  UINT32 TableSize;
+  UINT32 EndpointDescriptorsLength;
+  UINT32 OedConfigLength;
+  NHLT_ACPI_TABLE *Table;
+
+
+  Status = EFI_SUCCESS;
+  TableSize = PCH_HDA_NHLT_TABLE_SIZE;
+  EndpointDescriptorsLength = 0;
+  OedConfigLength = 0;
+
+  Table = AllocateZeroPool (TableSize);
+
+  if (Table == NULL) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  Table->EndpointCount = 0;
+
+  for (Index = 0; Index < HdaEndpointMax; Index++) {
+    if (EndpointTable[Index].Enable == TRUE) {
+      EndpointDescriptorsLength += NhltEndpointConstructor (Table,
+                                     EndpointTable[Index].EndpointType,
+                                     EndpointTable[Index].EndpointFormatsBitmask,
+                                     EndpointTable[Index].EndpointDevicesBitmask,
+                                     Table->EndpointCount++);
+    }
+  }
+  DEBUG ((DEBUG_INFO, "NhltConstructor: EndpointCount = %d, All EndpointDescriptorsLength = %d B\n", Table->EndpointCount, EndpointDescriptorsLength));
+
+  OedConfigLength = NhltOedConfigConstructor (Table);
+  DEBUG ((DEBUG_INFO, "NhltConstructor: OedConfigLength = %d B\n", OedConfigLength));
+
+  TableSize = EndpointDescriptorsLength + OedConfigLength;
+
+  *NhltTableSize = TableSize;
+  *NhltTable = Table;
+
+  return Status;
+}
+
+/**
+  Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
+
+  @param[in][out] *NhltTable            NHLT table for which header will be created
+  @param[in]      NhltTableSize         Size of NHLT table
+
+  @retval None
+**/
+VOID
+NhltAcpiHeaderConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable,
+  IN UINT32                     NhltTableSize
+  )
+{
+  DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor() Start\n"));
+
+  // Header
+  NhltTable->Header.Signature = NHLT_ACPI_TABLE_SIGNATURE;
+  NhltTable->Header.Length = (UINT32) (NhltTableSize + sizeof (NHLT_ACPI_TABLE) - sizeof (ENDPOINT_DESCRIPTOR) - sizeof (SPECIFIC_CONFIG));
+  NhltTable->Header.Revision = 0x0;
+  NhltTable->Header.Checksum = 0x0;
+
+  CopyMem (NhltTable->Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (NhltTable->Header.OemId));
+  NhltTable->Header.OemTableId      = PcdGet64 (PcdAcpiDefaultOemTableId);
+  NhltTable->Header.OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
+  NhltTable->Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
+  NhltTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor(), NhltAcpiTable->Header.Length = %d B\n", NhltTable->Header.Length));
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c
new file mode 100644
index 0000000000..301b1f8d10
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c
@@ -0,0 +1,439 @@
+/** @file
+  This file contains HD Audio NHLT Configuration BLOBs
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// CFL NHLT Configuration BLOBs
+//
+
+//
+// DMIC Configuration BLOBs
+//
+// DMIC Config 2 channels, 16 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicStereo16BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x00300003,
+  0x00300003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicStereo16BitFormatConfigSize = sizeof (DmicStereo16BitFormatConfig);
+
+// DMIC Config 2 channels, 32 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicStereo32BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x00380003,
+  0x00380003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicStereo32BitFormatConfigSize = sizeof (DmicStereo32BitFormatConfig);
+
+// DMIC Config 4 channels, 16 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicQuad16BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x00320003,
+  0x00320003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicQuad16BitFormatConfigSize = sizeof (DmicQuad16BitFormatConfig);
+
+// DMIC Config 4 channels, 32 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicQuad32BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x003A0003,
+  0x003A0003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicQuad32BitFormatConfigSize = sizeof (DmicQuad32BitFormatConfig);
+
+
+// DMIC Config 1 channel, 16 bits
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicMono16BitFormatConfig[] =
+{
+  0x00000000,
+  0xfffffff0,0xfffffff0,0xfffffff0,0xfffffff0,
+  3,
+  3,
+  0x00300003,
+  0x00300003,
+  0x3,
+  0x0, 0x09001303, 0x0, 0x0301, 0, 0, 0, 0,
+  0x10, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x10, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x0, 0x09001303, 0x0, 0x0301, 0, 0, 0, 0,
+  0x10, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x10, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicMono16BitFormatConfigSize = sizeof (DmicMono16BitFormatConfig);
+
+//
+// I2S/SSP Configuration BLOBs
+// Audio Format and Configuration details
+//
+// Frequency: 48kHz, PCM resolution: 24 bits
+// TDM slots: 4
+// Codec: Realtek ALC274, mode: slave
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfig[]  = {0x0, 0xffffff10, 0xffffff32, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0x83d00437, 0xc0700000, 0x0, 0x02010004, 0xf, 0xf, 0x4002, 0x4, 0x7070f00, 0x20, 0x00000001, 0x00000fff};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfigSize = sizeof (I2sRtk274Render4ch48kHz24bitFormatConfig);
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfig[]  = {0x0, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0x83d00437, 0xc0700000, 0x0, 0x02010004, 0xf, 0xf, 0x4002, 0x4, 0x7070f00, 0x20, 0x00000001, 0x00000fff};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfigSize = sizeof (I2sRtk274Capture4ch48kHz24bitFormatConfig);
+
+//
+// BlueTooth Configuration BLOBs
+//
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 BtFormatConfig[] =
+{
+  0x0, 0xfffffff0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+  0x0, 0x80c0003f, 0xd3400000, 0x0, 0x02000005, 0x01, 0x01, 0x4002,
+  0x0, 0x07020000, 0x0, 0x01, 0x0
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 BtFormatConfigSize = sizeof (BtFormatConfig);
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI private library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (21 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
                   ` (14 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH PEI private library class instances. These library instances
may be compatible with other boot phases as indicated by the library type.

* PeiDxeSmmGpioPrivateLibCnl
* PeiDxeSmmPchDmiLib
* PeiDxeSmmPchDmiWithS3Lib
* PeiDxeSmmPchInitCommonLib
* PeiDxeSmmPchPciExpressHelpersLib
* PeiDxeSmmPchPsfPrivateLibCnl
* PeiDxeSmmPmcPrivateLibCnl
* PeiDxeSmmPmcPrivateLibWithS3
* PeiGpioHelpersLib
* PeiGpioNameBufferLib
* PeiPmcPrivateLibCnl

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf                |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf                             |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf                       |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf               |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf            |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf                  |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf               |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf                        |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf                               |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h                |  477 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h                                         |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h        |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h                  |  490 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h                        |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c                                |  166 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c                        | 1304 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c                     | 2275 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c                              |  752 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c                           |  225 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c                                         |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c                                        |  569 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c                                  |   79 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c                             |  221 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c        | 2407 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c                          |  542 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c                       |  338 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c                             |   92 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c                                | 1033 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c                          |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c                             |  360 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c                          |  194 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c                                 |  356 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c                              |   68 +
 37 files changed, 12919 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
new file mode 100644
index 0000000000..318b54a99c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
@@ -0,0 +1,45 @@
+## @file
+#  Component description file for the PeiDxeSmmGpioPrivateLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmGpioPrivateLibCnl
+FILE_GUID                      = E078A734-BEA0-47CF-A476-3742316D01FC
+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
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  GpioPrivateLib.c
+  GpioNativePrivateLib.c
+  GpioPrivateLibCnl.c
+  GpioNativePrivateLibCnl.c
+  GpioNamesCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
new file mode 100644
index 0000000000..b36fc15901
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
@@ -0,0 +1,40 @@
+## @file
+#  Component description file for the PeiDxeSmmPchDmiLib
+#
+# Copyright (c) 2019 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
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchDmiLib.c
+  PchDmi14.c
+  PchDmi15.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
new file mode 100644
index 0000000000..1eda7cdba8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
@@ -0,0 +1,40 @@
+## @file
+#  Component description file for the PeiDxeSmmPchDmiWithS3Lib
+#
+# Copyright (c) 2019 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
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchDmiWithS3Lib.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
new file mode 100644
index 0000000000..d81c428a1c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
@@ -0,0 +1,34 @@
+## @file
+#  Component description file for the PchInitCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiDxeSmmPchInitCommonLib
+  FILE_GUID                      = E9C4FE04-8A79-43FA-B3E0-603359C31B43
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchInitCommonLib
+
+[Sources]
+  PchInitCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PciSegmentLib
+  PchCycleDecodingLib
+  PchPcieRpLib
+  PchSbiAccessLib
+  PchInfoLib
+  SataLib
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
new file mode 100644
index 0000000000..16b1c019b8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for the PeiDxeSmmPchPciExpressHelpersLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPciExpressHelpersLib
+FILE_GUID = 07E3F76D-6D26-419d-9053-58696A15B519
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPciExpressHelpersLib
+#
+# 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
+PchInitCommonLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPciExpressHelpersLibrary.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
new file mode 100644
index 0000000000..0ed9f30dcc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
@@ -0,0 +1,41 @@
+## @file
+#  PEI/DXE/SMM PCH PSF Private Lib for Cannon Lake PCH
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmPchPsfPrivateLibCnl
+FILE_GUID                      = 7A6C18CA-0353-433E-885D-DD68BFAD38BE
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = PchPsfPrivateLib
+#
+# 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
+  SaPlatformLib
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchPsfPrivateLib.c
+  PchPsfPrivateLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
new file mode 100644
index 0000000000..adb154dd14
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
@@ -0,0 +1,48 @@
+## @file
+# PEI/DXE/SMM PCH PMC Private Lib for Cannon Lake PCH.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPmcPrivateLibCnl
+FILE_GUID = A1CB52AD-4FAB-4214-94A0-323E3BE4E934
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PmcPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+TimerLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+PmcLib
+PchPsfPrivateLib
+PchDmiLib
+SataLib
+BaseMemoryLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+
+
+[Sources]
+PmcPrivateLib.c
+PmcPrivateLibClient.c
+PmcPrivateLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
new file mode 100644
index 0000000000..cd1380dc43
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
@@ -0,0 +1,39 @@
+## @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) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PmcPrivateLibWithS3.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf
new file mode 100644
index 0000000000..ab3645c61d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf
@@ -0,0 +1,40 @@
+## @file
+# PEI PCH PMC Private Lib for Cannon Lake PCH.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiPmcPrivateLibCnl
+FILE_GUID = 1DD4EA23-12F2-4F05-93AF-535476106D8C
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiPmcPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+IoLib
+DebugLib
+PeiServicesLib
+PciSegmentLib
+ConfigBlockLib
+PchInfoLib
+PchPcrLib
+PmcLib
+PmcPrivateLib
+PchEspiLib
+GpioPrivateLib
+PeiItssLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiPmcPrivateLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
new file mode 100644
index 0000000000..b6f786d80b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for the PeiGpioHelpersLib
+#
+# Copyright (c) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiGpioHelpersLib.c
+
+
+[Guids]
+gGpioLibUnlockHobGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
new file mode 100644
index 0000000000..3619a2e6a7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the PeiGpioMemLib
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+GpioNameBufferPei.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
new file mode 100644
index 0000000000..e081027c40
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
@@ -0,0 +1,477 @@
+/** @file
+  Header file for GPIO Private Lib Internal functions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
+#define _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
+
+#include <Private/Library/GpioPrivateLib.h>
+
+#define GPIO_PAD_NONE 0
+
+/**
+  This function provides SerialIo I2C controller pins
+
+  @param[in]  SerialIoI2cControllerNumber    I2C controller
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoI2cPins (
+  IN  UINT32                      SerialIoI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SerialIo UART controller pins
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoUartPins (
+  IN  UINT32                      SerialIoUartControllerNumber,
+  IN  BOOLEAN                     HardwareFlowControl,
+  IN  UINT32                      PinMuxing,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides SerialIo SPI controller pins
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @param[out] NativePinsTable               Table with pins
+  @param[out] NoOfNativePins                Number of pins
+**/
+VOID
+GpioGetSerialIoSpiPins (
+  IN  UINT32                      SerialIoSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides ISH GP pin data
+
+  @param[in]  IshGpPinNumber        ISH GP pin number
+
+  @param[out] NativePin             ISH GP pin
+**/
+VOID
+GpioGetIshGpPin (
+  IN  UINT32                      IshGpPinNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  );
+
+/**
+  This function provides ISH UART controller pins
+
+  @param[in]  IshUartControllerNumber   ISH UART controller
+
+  @param[out] NativePinsTable           Table with pins
+**/
+VOID
+GpioGetIshUartPins (
+  IN  UINT32                      IshUartControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides ISH I2C controller pins
+
+  @param[in]  IshI2cControllerNumber   ISH I2C controller
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetIshI2cPins (
+  IN  UINT32                      IshI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides ISH SPI controller pins
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins           Number of pins
+**/
+VOID
+GpioGetIshSpiPins (
+  IN  UINT32                      IshSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides SCS SD CARD controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsSdCardPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides SCS SD CARD detect pin
+
+  @retval GpioPin             SD CARD Detect pin
+**/
+GPIO_PAD
+GpioGetScsSdCardDetectPin (
+  VOID
+  );
+
+/**
+  This function provides SCS eMMC controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsEmmcPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides HD Audio Link pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetHdAudioLinkPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides DMIC interface pins
+
+  @param[in]  DmicNumber               DMIC interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaDmicPins (
+  IN  UINT32                      DmicNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SSP/I2S interface pins
+
+  @param[in]  SspInterfaceNumber       SSP/I2S interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSspPins (
+  IN  UINT32                      SspInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SNDW interface pins
+
+  @param[in]  SndwInterfaceNumber      SNDWx interface number
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSndwPins (
+  IN  UINT32                      SndwInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SMBUS interface pins
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetSmbusPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SATA DevSlp pin data
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+  @param[out] NativePin           SATA DevSlp pin
+**/
+VOID
+GpioGetSataDevSlpPin (
+  IN  UINT32                    SataCtrlIndex,
+  IN  UINTN                     SataPort,
+  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
+  );
+
+/**
+  This function provides PCIe CLKREQ pin data
+
+  @param[in]  ClkreqIndex        CLKREQ# number
+  @param[out] NativePin          Native pin data
+**/
+VOID
+GpioGetPcieClkReqPin (
+  IN  UINT32                      ClkreqIndex,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  );
+
+/**
+  This function provides eDP pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetEdpPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides DDPx interface pins
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetDdpPins (
+  IN  GPIO_DDP                    DdpInterface,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides CNVi BT UART pins
+
+  @param[in]  ConnectionType           CNVi BT UART connection type
+  @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
+  @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
+  @param[out] VUartForCnviBtPad        Table with vUART0 pads
+  @param[out] VUartForCnviBtPadMode    vUART0 pad mode
+**/
+VOID
+GpioGetCnviBtUartPins (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                            **VCnviBtUartPad,
+  OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
+  OUT GPIO_PAD                            **VUartForCnviBtPad,
+  OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
+  );
+
+/**
+  This function provides CNVi BT UART external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtUartExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi BT I2S pins
+
+  @param[in]  ConnectionType          CNVi BT I2S connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
+  @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
+  @param[out] VSspForCnviBtPad        Table with vSSP2 pads
+  @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
+**/
+VOID
+GpioGetCnviBtI2sPins (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviBtI2sPad,
+  OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
+  OUT GPIO_PAD                 **VSspForCnviBtPad,
+  OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
+  );
+
+/**
+  This function provides CNVi BT I2S external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtI2sExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi MFUART1 pins
+
+  @param[in]  ConnectionType          CNVi MFUART1 connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
+  @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
+  @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
+  @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
+**/
+VOID
+GpioGetCnviMfUart1Pins (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
+  OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
+  );
+
+/**
+  This function provides CNVi MFUART1 external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviMfUart1ExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi Bluetooth Enable pad
+
+  @retval GpioPad           CNVi Bluetooth Enable pad
+**/
+GPIO_PAD
+GpioGetCnviBtEnablePin (
+  VOID
+  );
+
+/**
+  This function provides CNVi BRI RGI GPIO pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnvBriRgiPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi MFUART2 external pins
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnvMfUart2ExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi BT interface select pin
+
+  @retval GpioPad          GPIO pad for CNVi BT interface select
+**/
+GPIO_PAD
+GpioGetCnviBtIfSelectPin (
+  VOID
+  );
+
+/**
+  This function provides CNVi BT Charging pin
+
+  @retval GpioPad          GPIO pad for CNVi BT Charging select
+**/
+GPIO_PAD
+GpioGetCnviBtChargingPin (
+  VOID
+  );
+
+/**
+  This function provides CNVi A4WP pin
+
+  @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
+**/
+VOID
+GpioGetCnviA4WpPin (
+  OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
+  );
+
+/**
+  This function provides CNVi BT host wake int pin
+
+  @retval GpioPad          GPIO pad BT host wake int
+**/
+GPIO_PAD
+GpioGetCnviBtHostWakeIntPin (
+  VOID
+  );
+
+/**
+  This function provides IMGCLKOUT pins
+
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins            Number of pins
+**/
+VOID
+GpioGetImgClkOutPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
+  OUT UINT32                   *NoOfNativePins
+  );
+
+/**
+  This function provides PWRBTN pin
+
+  @retval GpioPad          PWRTBTN pin
+**/
+GPIO_PAD
+GpioGetPwrBtnPin (
+  VOID
+  );
+
+/**
+  This procedure enables debounce feature on a selected pad configured in input mode
+  Debounce time can be specified in microseconds. GPIO HW supports only certain values
+  according to below formula:
+   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 GPIO HW, function will round down
+  to closest supported
+
+  @param[in] GpioPad              GPIO pad
+  @param[in, out] DebounceTime    Debounce Time in microseconds
+                                  If Debounce Time = 0, Debouncer feature will be disabled
+                                  Function will set DebounceTime argument to rounded supported value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad or unsupported DebounceDuration value
+  @retval EFI_UNSUPPORTED         GpioPad is not owned by host
+**/
+EFI_STATUS
+GpioSetDebounceTimer (
+  IN GPIO_PAD                  GpioPad,
+  IN OUT UINT32                *DebounceTime
+  );
+
+/**
+  This function provides LPC pin
+
+  @retval GpioPad          LPC pin
+**/
+GPIO_PAD
+GpioGetLpcPin (
+  VOID
+  );
+
+#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h
new file mode 100644
index 0000000000..1d50c04b0f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h
@@ -0,0 +1,70 @@
+/** @file
+  Internal header file for PCH DMI library for SIP14
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PCH_DMI_14_H__
+#define __PCH_DMI_14_H__
+
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/PeiPchDmiLib.h>
+
+/**
+  This function checks if DMI SIP14 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi14Locked (
+  VOID
+  );
+
+/**
+  Enable PCIe Relaxed Order for DMI SIP14
+**/
+VOID
+PchDmi14EnablePcieRelaxedOrder (
+  VOID
+  );
+
+/**
+  This function will switch SAI value to be driven to IOSF Primary Fabric
+  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
+  To be used when PCH is paired with CFL CPU.
+**/
+VOID
+PchDmi14EnablePostBootSai (
+  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
+  );
+
+/**
+  Get PCH DMI SIP14 Virtual Channel Control and Status registers
+
+  @param[in]  Vc                   The virtual channel number for programing
+  @param[out] DmiVcCtlAddress      DMI Virtual Channel Control register address
+  @param[out] DmiVcStsAddress      DMI Virtual Channel Status register address
+**/
+VOID
+PchDmi14VcRegs (
+  IN   PCH_DMI_VC_TYPE  Vc,
+  OUT  UINT16           *DmiVcCtlAddress,
+  OUT  UINT16           *DmiVcStsAddress
+  );
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h
new file mode 100644
index 0000000000..744a96fe14
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h
@@ -0,0 +1,113 @@
+/** @file
+  Internal header file for PCH DMI library for SIP15
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PCH_DMI_15_H__
+#define __PCH_DMI_15_H__
+
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/PeiPchDmiLib.h>
+
+/**
+  This function checks if DMI SIP15 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi15Locked (
+  VOID
+  );
+
+/**
+  Set DMI thermal throttling to recommended configuration.
+  It's intended only for P-DMI SIP15.
+**/
+VOID
+PchDmi15SetRecommendedThermalThrottling (
+  VOID
+  );
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+  It's intended only for P-DMI SIP15.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmi15SetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  );
+
+/**
+  Enable PCIe Relaxed Order for DMI SIP15
+**/
+VOID
+PchDmi15EnablePcieRelaxedOrder (
+  VOID
+  );
+
+/**
+  This function will switch SAI value to be driven to IOSF Primary Fabric
+  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
+  To be used when PCH is paired with CFL CPU.
+**/
+VOID
+PchDmi15EnablePostBootSai (
+  VOID
+  );
+
+/**
+  This function will do necessary configuration after platform
+  should have switched to POSTBOOT_SAI. It needs to be called even if
+  POSTBOOT_SAI was not set.
+**/
+VOID
+PchDmi15ConfigAfterPostBootSai (
+  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
+PchDmi15SrlRegData (
+  OUT UINT16  *SrlRegOffset,
+  OUT UINT32  *SrlRegMask
+  );
+
+/**
+  Get PCH DMI SIP15 Virtual Channel Control and Status registers
+
+  @param[in]  Vc                   The virtual channel number for programing
+  @param[out] DmiVcCtlAddress      DMI Virtual Channel Control register address
+  @param[out] DmiVcStsAddress      DMI Virtual Channel Status register address
+**/
+VOID
+PchDmi15VcRegs (
+  IN   PCH_DMI_VC_TYPE  Vc,
+  OUT  UINT16           *DmiVcCtlAddress,
+  OUT  UINT16           *DmiVcStsAddress
+  );
+
+/**
+  The function sets the Target Link Speed to GEN 3 in P-DMI SIP15.
+
+  @param[in] TargetLinkSpeed        Target Link Speed
+                                    2: GEN2
+                                    3: GEN3
+**/
+VOID
+PchDmi15SetTargetLinkSpeed (
+  IN  UINT8                 TargetLinkSpeed
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
new file mode 100644
index 0000000000..b14f24b18f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
@@ -0,0 +1,42 @@
+/** @file
+  Header file for PCH Pci Express helps library implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
+#define _PCH_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 <Private/Library/PchPciExpressHelpersLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <Private/Library/PchInitCommonLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegsPcie.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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h
new file mode 100644
index 0000000000..f633df0411
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h
@@ -0,0 +1,490 @@
+/** @file
+  This file contains internal header for PSF lib usage
+
+  Copyright (c) 2019 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 <Private/Library/PchPsfPrivateLib.h>
+#include <Register/PchRegsPcr.h>
+
+#define PSF_PORT_NULL ((PSF_PORT){0,0})
+#define PSF_IS_PORT_NULL(PsfPort) ((PsfPort.PsfPid == 0) && (PsfPort.RegBase == 0))
+
+/**
+  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
+  );
+
+/**
+  Return PSF_PORT for HECI device
+
+  @param[in] HeciDevice      HECIx Device (HECI1-4)
+
+  @retval    PsfPort         PSF PORT structure for HECI device
+**/
+PSF_PORT
+PsfHeciPort (
+  IN UINT8      HeciDevice
+  );
+
+/**
+  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 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
+
+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
+  );
+
+/**
+  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
+  );
+
+/**
+  P2SB PSF port Destination ID (psf_id:port_group_id:port_id:channel_id)
+
+  @retval P2SB Destination ID
+**/
+PSF_PORT_DEST_ID
+PsfP2sbDestinationId (
+  VOID
+  );
+
+/**
+  DMI PSF port Destination ID (psf_id:port_group_id:port_id:channel_id)
+
+  @retval DMI Destination ID
+**/
+PSF_PORT_DEST_ID
+PsfDmiDestinationId (
+  VOID
+  );
+
+/**
+  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
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h
new file mode 100644
index 0000000000..c08d1cf10d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h
@@ -0,0 +1,47 @@
+/** @file
+  Internal header file for PMC Private library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PMC_PRIVATE_LIB_INTERNAL_H_
+#define _PMC_PRIVATE_LIB_INTERNAL_H_
+
+/**
+  Check if MODPHY SUS PG is supported
+
+  @retval  Status of MODPHY SUS PG support
+**/
+BOOLEAN
+PmcIsModPhySusPgSupported (
+  VOID
+  );
+
+/**
+  This function is part of PMC init and configures which clock wake signals should
+  set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent up to the CPU/PCH
+**/
+VOID
+PmcInitClockWakeEnable (
+  VOID
+  );
+
+/**
+  This function configures PWRMBASE + 0x1E00 register
+**/
+VOID
+PmcConfigureRegPwrm1E00 (
+  VOID
+  );
+
+/**
+  This function configures Misc PM_SYNC events settings
+**/
+VOID
+PmcConfigurePmSyncEventsSettings (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c
new file mode 100644
index 0000000000..5a4876bfeb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c
@@ -0,0 +1,166 @@
+/** @file
+  This file contains GPIO name library implementation
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+
+STATIC CONST CHAR8*  mGpioGppaNames[] = {
+  "ESPI_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGppbNames[] = {
+  "GSPI0_CLK_LOOPBK",
+  "GSPI1_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGpdNames[] = {
+  "SLP_LANB",
+  "SLP_SUSB",
+  "SLP_WAKEB",
+  "SLP_DRAM_RESETB"
+};
+
+STATIC CONST CHAR8*  mGpioGppiNames[] = {
+  "SYS_PWROK",
+  "SYS_RESETB",
+  "MLK_RSTB"
+};
+
+STATIC CONST CHAR8*  mGpioSpiNames[] = {
+  "SPI0_IO_2",
+  "SPI0_IO_3",
+  "SPI0_MOSI_IO_0",
+  "SPI0_MOSI_IO_1",
+  "SPI0_TPM_CSB",
+  "SPI0_FLASH_0_CSB",
+  "SPI0_FLASH_1_CSB",
+  "SPI0_CLK",
+  "SPI0_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioAzaNames[] = {
+  "HDA_BCLK",
+  "HDA_RSTB",
+  "HDA_SYNC",
+  "HDA_SDO",
+  "HDA_SDI_0",
+  "HDA_SDI_1",
+  "SSP1_SFRM",
+  "SSP1_TXD"
+};
+
+STATIC CONST CHAR8*  mGpioJtagNames[] = {
+  "JTAG_TDO",
+  "JTAGX",
+  "PRDYB",
+  "PREQB",
+  "CPU_TRSTB",
+  "JTAG_TDI",
+  "JTAG_TMS",
+  "JTAG_TCK",
+  "ITP_PMODE"
+};
+
+STATIC CONST CHAR8*  mGpioHvmosNames[] = {
+  "HVMOS_L_BKLTEN",
+  "HVMOS_L_BKLCTL",
+  "HVMOS_L_VDDEN",
+  "HVMOS_SYS_PWROK",
+  "HVMOS_SYS_RESETB",
+  "HVMOS_MLK_RSTB"
+};
+
+STATIC CONST CHAR8*  mGpioCpuNames[] = {
+  "HDACPU_SDI",
+  "HDACPU_SDO",
+  "HDACPU_SCLK",
+  "PM_SYNC",
+  "PECI",
+  "CPUPWRGD",
+  "THRMTRIPB",
+  "PLTRST_CPUB",
+  "PM_DOWN",
+  "TRIGGER_IN",
+  "TRIGGER_OUT"
+};
+
+STATIC CONST GPIO_GROUP_NAME_INFO  mPchLpGroupDescriptors[] = {
+  GPIO_GROUP_NAME("GPP_A", GPIO_CNL_LP_ESPI_CLK_LOOPBK, mGpioGppaNames),
+  GPIO_GROUP_NAME("GPP_B", GPIO_CNL_LP_GSPI0_CLK_LOOPBK, mGpioGppbNames),
+  GPIO_GROUP_NAME_BASIC("GPP_C"),
+  GPIO_GROUP_NAME_BASIC("GPP_D"),
+  GPIO_GROUP_NAME_BASIC("GPP_E"),
+  GPIO_GROUP_NAME_BASIC("GPP_F"),
+  GPIO_GROUP_NAME_BASIC("GPP_G"),
+  GPIO_GROUP_NAME_BASIC("GPP_H"),
+  GPIO_GROUP_NAME("GPD", GPIO_CNL_LP_SLP_LANB, mGpioGpdNames),
+  GPIO_GROUP_NAME_BASIC("VGPIO"),
+  GPIO_GROUP_NAME("SPI", GPIO_CNL_LP_SPI0_IO_2, mGpioSpiNames),
+  GPIO_GROUP_NAME("AZA", GPIO_CNL_LP_HDA_BCLK, mGpioAzaNames),
+  GPIO_GROUP_NAME("CPU", GPIO_CNL_LP_HDACPU_SDI, mGpioCpuNames),
+  GPIO_GROUP_NAME("JTAG", GPIO_CNL_LP_JTAG_TDO, mGpioJtagNames),
+  GPIO_GROUP_NAME("HVMOS", GPIO_CNL_LP_HVMOS_L_BKLTEN, mGpioHvmosNames)
+};
+
+STATIC CONST GPIO_GROUP_NAME_INFO  mPchHGroupDescriptors[] = {
+  GPIO_GROUP_NAME("GPP_A", GPIO_CNL_H_ESPI_CLK_LOOPBK, mGpioGppaNames),
+  GPIO_GROUP_NAME("GPP_B", GPIO_CNL_H_GSPI0_CLK_LOOPBK, mGpioGppbNames),
+  GPIO_GROUP_NAME_BASIC("GPP_C"),
+  GPIO_GROUP_NAME_BASIC("GPP_D"),
+  GPIO_GROUP_NAME_BASIC("GPP_E"),
+  GPIO_GROUP_NAME_BASIC("GPP_F"),
+  GPIO_GROUP_NAME_BASIC("GPP_G"),
+  GPIO_GROUP_NAME_BASIC("GPP_H"),
+  GPIO_GROUP_NAME("GPP_I", GPIO_CNL_H_SYS_PWROK, mGpioGppiNames),
+  GPIO_GROUP_NAME_BASIC("GPP_J"),
+  GPIO_GROUP_NAME_BASIC("GPP_K"),
+  GPIO_GROUP_NAME("GPD", GPIO_CNL_H_SLP_LANB, mGpioGpdNames),
+  GPIO_GROUP_NAME_BASIC("VGPIO"),
+  GPIO_GROUP_NAME("SPI", GPIO_CNL_H_SPI0_IO_2, mGpioSpiNames),
+  GPIO_GROUP_NAME("AZA", GPIO_CNL_H_HDA_BCLK, mGpioAzaNames),
+  GPIO_GROUP_NAME("CPU", GPIO_CNL_H_HDACPU_SDI, mGpioCpuNames),
+  GPIO_GROUP_NAME("JTAG", GPIO_CNL_H_JTAG_TDO, mGpioJtagNames),
+};
+
+/**
+  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 (IsPchLp ()) {
+    if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) {
+      return &mPchLpGroupDescriptors[GroupIndex];
+    } else {
+      ASSERT (FALSE);
+      return NULL;
+    }
+  } else {
+    if (GroupIndex < ARRAY_SIZE (mPchHGroupDescriptors)) {
+      return &mPchHGroupDescriptors[GroupIndex];
+    } else {
+      ASSERT (FALSE);
+      return NULL;
+    }
+  }
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c
new file mode 100644
index 0000000000..affecf9ec0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c
@@ -0,0 +1,1304 @@
+/** @file
+  This file contains routines for GPIO native and chipset specific purpose
+  used by Reference Code only.
+
+  Copyright (c) 2019 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/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <SaAccess.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include "GpioNativePrivateLibInternal.h"
+#include <Register/PchRegsGpio.h>
+#include <Register/PchRegsSerialIo.h>
+#include <Register/PchRegsIsh.h>
+
+/**
+  This function sets SerialIo I2C controller pins into native mode
+
+  @param[in]  SerialIoI2cControllerNumber   I2C controller
+  @param[in]  GpioTermination               GPIO termination type
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoI2c (
+  IN  UINT32                  SerialIoI2cControllerNumber,
+  IN  GPIO_ELECTRICAL_CONFIG  GpioTermination
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
+  GPIO_CONFIG              GpioConfig;
+
+  GpioGetSerialIoI2cPins (
+    SerialIoI2cControllerNumber,
+    &I2cGpio
+    );
+
+  if (I2cGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
+  GpioConfig.ElectricalConfig = GpioTermination;
+
+  for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index++) {
+    GpioConfig.PadMode          = I2cGpio[Index].Mode;
+
+    Status = GpioSetPadConfig(I2cGpio[Index].Pad, &GpioConfig);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SerialIo UART controller pins into native mode
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoUart (
+  IN  UINT32            SerialIoUartControllerNumber,
+  IN  BOOLEAN           HardwareFlowControl,
+  IN  UINT32            PinMuxing
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  UINT32                   PinsUsed;
+  GPIO_PAD_NATIVE_FUNCTION *UartGpio;
+
+  GpioGetSerialIoUartPins (
+    SerialIoUartControllerNumber,
+    HardwareFlowControl,
+    PinMuxing,
+    &UartGpio,
+    &PinsUsed
+    );
+
+  if (UartGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PinsUsed; Index++) {
+    Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+    GpioSetInputInversion (UartGpio[Index].Pad, 0);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SerialIo SPI controller pins into native mode
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoSpi (
+  IN  UINT32            SerialIoSpiControllerNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
+  UINT32                   NumOfSpiPins;
+
+  GpioGetSerialIoSpiPins (
+    SerialIoSpiControllerNumber,
+    &SpiGpio,
+    &NumOfSpiPins
+    );
+
+  if (SpiGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfSpiPins; Index++) {
+    Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+    GpioSetInputInversion (SpiGpio[Index].Pad, 0);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH I2C controller pins into native mode
+
+  @param[in]  IshI2cControllerNumber   I2C controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshI2c (
+  IN  UINT32            IshI2cControllerNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
+
+  GpioGetIshI2cPins (
+    IshI2cControllerNumber,
+    &I2cGpio
+    );
+
+  if (I2cGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_ISH_PINS_PER_I2C_CONTROLLER; Index++) {
+    Status = GpioSetPadMode (I2cGpio[Index].Pad, I2cGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH UART controller pins into native mode
+
+  @param[in]  IshUartControllerNumber   UART controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshUart (
+  IN  UINT32            IshUartControllerNumber
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *UartGpio;
+
+  GpioGetIshUartPins (
+    IshUartControllerNumber,
+    &UartGpio
+    );
+
+  if (UartGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_ISH_PINS_PER_UART_CONTROLLER; Index++) {
+    Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH SPI controller pins into native mode
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshSpi (
+  IN  UINT32            IshSpiControllerNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
+  UINT32                   NumOfSpiPins;
+
+  GpioGetIshSpiPins (
+    IshSpiControllerNumber,
+    &SpiGpio,
+    &NumOfSpiPins
+    );
+
+  if (SpiGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfSpiPins; Index++) {
+    Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH GP pin into native mode
+
+  @param[in]  IshGpPinNumber   ISH GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshGpPin (
+  IN  UINT32            IshGpPinNumber
+  )
+{
+  EFI_STATUS               Status;
+  GPIO_PAD_NATIVE_FUNCTION IshGp;
+
+  GpioGetIshGpPin (
+    IshGpPinNumber,
+    &IshGp
+    );
+
+  Status = GpioSetPadMode (IshGp.Pad, IshGp.Mode);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SCS SD card controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCard (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *SdCardGpio;
+  UINT32                    NumOfSdCardPins;
+  GPIO_CONFIG               PwrEnConfig;
+
+  GpioGetScsSdCardPins (
+    &SdCardGpio,
+    &NumOfSdCardPins
+    );
+
+  if (SdCardGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // We need to leave the PWREN#
+  // GPIO pad unlocked since it is controlled at runtime
+  // by ACPI code. It is a work around for our SD card
+  // controller not respecting PWREN# invertion settings
+  // during D3. Since this pad will be in GPIO mode when
+  // SD controller is in D3 we need to set correct pad config.
+  //
+  GpioUnlockPadCfg (SdCardGpio[0].Pad);
+  GpioGetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
+  PwrEnConfig.PadMode = SdCardGpio[0].Mode;
+  PwrEnConfig.Direction = GpioDirOut;
+  PwrEnConfig.HostSoftPadOwn = GpioHostOwnAcpi;
+  PwrEnConfig.InterruptConfig = GpioIntDis;
+  PwrEnConfig.PowerConfig = GpioHostDeepReset;
+  PwrEnConfig.LockConfig = GpioPadUnlock;
+  GpioSetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
+
+  for (Index = 1; Index < NumOfSdCardPins; Index++) {
+    Status = GpioSetPadMode (SdCardGpio[Index].Pad, SdCardGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // SD Card Pins GPP_G0 - G4 require Native Termination
+    // Index in mPch[Lp/H]ScsSdCardGpio (depends on mPch[Lp/H]ScsSdCardGpio internal organization):
+    // GPP_G0 = 1
+    // GPP_G4 = 5
+    //
+    if (Index >= 1 && Index <= 5) {
+      Status = GpioSetPadElectricalConfig (SdCardGpio[Index].Pad, GpioTermNative);
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function enables SCS Sd Card controller card detect pin
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCardDetect (
+  VOID
+  )
+{
+  GPIO_CONFIG   PadConfig;
+  GPIO_PAD      GpioPad;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  ///
+  /// vSD3_CD_B line is driven by GPPC_G_5_SD3_CDB
+  /// and is used for interrupt for card detect event.
+  /// GPPC_G_5_SD3_CDB cannot be used for interrupt because this pin
+  /// is in native mode.
+  ///
+  GpioPad = GpioGetScsSdCardDetectPin ();
+  PadConfig.PadMode         = GpioPadModeGpio;
+  PadConfig.Direction       = GpioDirIn;
+  PadConfig.HostSoftPadOwn  = GpioHostOwnGpio;
+  PadConfig.InterruptConfig = GpioIntBothEdge;
+  PadConfig.PowerConfig     = GpioHostDeepReset;
+
+  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode.
+  GpioUnlockPadCfg (GpioPad);
+
+  return GpioSetPadConfig (GpioPad, &PadConfig);
+}
+
+/**
+  This function sets SCS eMMC controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsEmmc (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *EmmcGpio;
+  UINT32                    NumOfEmmcPins;
+
+  GpioGetScsEmmcPins (
+    &EmmcGpio,
+    &NumOfEmmcPins
+    );
+
+  if (EmmcGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfEmmcPins; Index++) {
+    Status = GpioSetPadMode (EmmcGpio[Index].Pad, EmmcGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA Link pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaLink (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *HdaLinkGpio;
+  UINT32                    NumOfHdaLinkPins;
+
+  GpioGetHdAudioLinkPins (
+    &HdaLinkGpio,
+    &NumOfHdaLinkPins
+    );
+
+  if (HdaLinkGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfHdaLinkPins; Index++) {
+    Status = GpioSetPadMode (HdaLinkGpio[Index].Pad, HdaLinkGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA DMIC pins into native mode
+
+  @param[in]  DmicNumber   DMIC number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaDmic (
+  IN  UINT32            DmicNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *DmicGpio;
+
+  GpioGetHdaDmicPins (
+    DmicNumber,
+    &DmicGpio
+    );
+
+  if (DmicGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (DmicGpio[Index].Pad, DmicGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA SSP interface pins into native mode
+
+  @param[in]  SspInterfaceNumber   SSPx interface number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSsp (
+  IN  UINT32            SspInterfaceNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SspGpio;
+
+  GpioGetHdaSspPins (
+    SspInterfaceNumber,
+    &SspGpio
+    );
+
+  if (SspGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_HDA_SSP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (SspGpio[Index].Pad, SspGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA SoundWire interface pins into native mode
+
+  @param[in]  SndwInterfaceNumber   SNDWx interface number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSndw (
+  IN  UINT32            SndwInterfaceNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SndwGpio;
+
+  GpioGetHdaSndwPins (
+    SndwInterfaceNumber,
+    &SndwGpio
+    );
+
+  if (SndwGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (SndwGpio[Index].Pad, SndwGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SMBUS controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSmbus (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SmbusGpio;
+
+  GpioGetSmbusPins (&SmbusGpio);
+
+  if (SmbusGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_SMBUS_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (SmbusGpio[Index].Pad, SmbusGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SATA DevSlp pins into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataDevSlpPin (
+  IN  UINT32  SataCtrlIndex,
+  IN  UINTN   SataPort
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  DevSlpGpio;
+
+  GpioGetSataDevSlpPin (
+    SataCtrlIndex,
+    SataPort,
+    &DevSlpGpio
+    );
+
+  GpioSetPadResetConfig (DevSlpGpio.Pad, GpioResumeReset);
+
+  return GpioSetPadMode (DevSlpGpio.Pad, DevSlpGpio.Mode);
+}
+
+/**
+  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
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  DevSlpNativePad;
+  GPIO_PAD_MODE             GpioMode;
+  EFI_STATUS                Status;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  GpioGetSataDevSlpPin (
+    SataCtrlIndex,
+    SataPort,
+    &DevSlpNativePad
+    );
+
+  Status = GpioGetPadMode (DevSlpNativePad.Pad, &GpioMode);
+
+  if (EFI_ERROR (Status) || (GpioMode != DevSlpNativePad.Mode)) {
+    if (DevSlpPad != NULL) {
+      *DevSlpPad = GPIO_PAD_NONE;
+    }
+    return FALSE;
+  } else {
+    if (DevSlpPad != NULL) {
+      *DevSlpPad = DevSlpNativePad.Pad;
+    }
+    return TRUE;
+  }
+}
+
+/**
+  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
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  SataGpGpio;
+
+  GpioGetSataGpPin (
+    SataCtrlIndex,
+    SataPort,
+    &SataGpGpio
+    );
+
+  DEBUG_CODE_BEGIN ();
+  GPIO_PAD_MODE  PadMode;
+  GpioGetPadMode (SataGpGpio.Pad, &PadMode);
+  if (PadMode == GpioPadModeNative1) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Cannot enable SATAGP%d, %a already used for SATAXPCIE_%d\n",
+        SataPort,
+        GpioName (SataGpGpio.Pad),
+        SataPort));
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  DEBUG_CODE_END ();
+
+  return GpioSetPadMode (SataGpGpio.Pad, SataGpGpio.Mode);
+}
+
+/**
+  Returns a pad for given CLKREQ# index.
+
+  @param[in]  ClkreqIndex       CLKREQ# number
+
+  @return CLKREQ# pad.
+**/
+GPIO_PAD
+GpioGetClkreqPad (
+  IN     UINT32   ClkreqIndex
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  ClkReqGpio;
+
+  GpioGetPcieClkReqPin (
+    ClkreqIndex,
+    &ClkReqGpio
+    );
+
+  return ClkReqGpio.Pad;
+}
+
+/**
+  Enables CLKREQ# pad in native mode.
+
+  @param[in]  ClkreqIndex       CLKREQ# number
+
+  @return none
+**/
+VOID
+GpioEnableClkreq (
+  IN     UINT32   ClkreqIndex
+  )
+{
+  GPIO_CONFIG               PadConfig;
+  GPIO_PAD_NATIVE_FUNCTION  ClkReqGpio;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  GpioGetPcieClkReqPin (
+    ClkreqIndex,
+    &ClkReqGpio
+    );
+
+  PadConfig.PadMode      = ClkReqGpio.Mode;
+  PadConfig.Direction    = GpioDirNone;
+  PadConfig.PowerConfig  = GpioHostDeepReset;
+  DEBUG ((DEBUG_INFO, "Enabling CLKREQ%d\n", ClkreqIndex));
+  GpioSetPadConfig (ClkReqGpio.Pad, &PadConfig);
+}
+
+
+/**
+  This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode for eDP Panel
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableEdpPins (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD_NATIVE_FUNCTION *EdpPins;
+  UINT32                   EdpPinsNumber;
+
+  GpioGetEdpPins (
+    &EdpPins,
+    &EdpPinsNumber
+    );
+
+  if (EdpPins == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure HPD, VDD and BKLT Pins for eDP panel
+  //
+  for (Index = 0; Index < EdpPinsNumber; Index++) {
+    Status = GpioSetPadMode (EdpPins[Index].Pad, EdpPins[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets DDP pins into native mode
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpInterface (
+  IN  GPIO_DDP            DdpInterface
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *DdpGpio;
+
+  GpioGetDdpPins (
+    DdpInterface,
+    &DdpGpio
+    );
+
+  if (DdpGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_DDP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (DdpGpio[Index].Pad, DdpGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures GPIO connection between CNVi and CRF
+  @param[in]  None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviCrfConnection (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD_NATIVE_FUNCTION *CnviBriRgiExternalPad;
+
+  GpioGetCnvBriRgiPins (&CnviBriRgiExternalPad);
+
+  if (CnviBriRgiExternalPad == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi BRI and RGI buses for high speed communication with CRF
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (CnviBriRgiExternalPad[Index].Pad, CnviBriRgiExternalPad[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth UART
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtUartConnection (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD                 *VCnviBtUartPad;
+  GPIO_PAD_MODE            VCnviBtUartPadMode;
+  GPIO_PAD                 *VUartForCnviBtPad;
+  GPIO_PAD_MODE            VUartForCnviBtPadMode;
+  GPIO_PAD_NATIVE_FUNCTION *CnviBtUartExternalPad;
+
+  GpioGetCnviBtUartPins (
+    ConnectionType,
+    &VCnviBtUartPad,
+    &VCnviBtUartPadMode,
+    &VUartForCnviBtPad,
+    &VUartForCnviBtPadMode
+    );
+
+  if ((VCnviBtUartPad == NULL) ||
+      (VUartForCnviBtPad == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi Bluetooth UART for certain connection
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VCnviBtUartPad[Index], VCnviBtUartPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable virtual connection for UART for Bluetooth
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VUartForCnviBtPad[Index], VUartForCnviBtPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable CNVi BT UART on external pads
+  //
+  if (ConnectionType == GpioCnviBtUartToExternalPads) {
+
+    GpioGetCnviBtUartExternalPins (&CnviBtUartExternalPad);
+
+    if (CnviBtUartExternalPad == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+      Status = GpioSetPadMode (CnviBtUartExternalPad[Index].Pad, CnviBtUartExternalPad[Index].Mode);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return EFI_UNSUPPORTED;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth I2S
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtI2sConnection (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD                 *VCnviBtI2sPad;
+  GPIO_PAD_MODE            VCnviBtI2sPadMode;
+  GPIO_PAD                 *VSspForCnviBtPad;
+  GPIO_PAD_MODE            VSspForCnviBtPadMode;
+  GPIO_PAD_NATIVE_FUNCTION *CnviBtI2sExternalPad;
+
+  GpioGetCnviBtI2sPins (
+    ConnectionType,
+    &VCnviBtI2sPad,
+    &VCnviBtI2sPadMode,
+    &VSspForCnviBtPad,
+    &VSspForCnviBtPadMode
+    );
+
+  if ((VCnviBtI2sPad == NULL) ||
+      (VSspForCnviBtPad == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi Bluetooth I2S for certain connection
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VCnviBtI2sPad[Index], VCnviBtI2sPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable virtual connection for SSP for Bluetooth
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VSspForCnviBtPad[Index], VSspForCnviBtPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable CNV BT I2S on external pads
+  //
+  if (ConnectionType == (VGPIO_CNVI_BT_I2S_CONNECTION_TYPE) GpioCnviBtI2sToExternalPads) {
+
+    GpioGetCnviBtI2sExternalPins (&CnviBtI2sExternalPad);
+
+    if (CnviBtI2sExternalPad == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
+      Status = GpioSetPadMode (CnviBtI2sExternalPad[Index].Pad, CnviBtI2sExternalPad[Index].Mode);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return EFI_UNSUPPORTED;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures virtual GPIO connection for CNVi MFUART1
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviMfUart1Connection (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD                 *VCnviMfUart1Pad;
+  GPIO_PAD_MODE            VCnviMfUart1PadMode;
+  GPIO_PAD                 *VUartForCnviMfUart1Pad;
+  GPIO_PAD_MODE            VUartForCnviMfUart1PadMode;
+  GPIO_PAD_NATIVE_FUNCTION *CnviMfUart1ExternalPad;
+
+  GpioGetCnviMfUart1Pins (
+    ConnectionType,
+    &VCnviMfUart1Pad,
+    &VCnviMfUart1PadMode,
+    &VUartForCnviMfUart1Pad,
+    &VUartForCnviMfUart1PadMode
+    );
+
+  if ((VCnviMfUart1Pad == NULL) ||
+      (VUartForCnviMfUart1Pad == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi MFUART1 for certain connection
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VCnviMfUart1Pad[Index], VCnviMfUart1PadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable virtual connection for MFUART1
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VUartForCnviMfUart1Pad[Index], VUartForCnviMfUart1PadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable CNV MFUART1 on external pads
+  //
+  if (ConnectionType == GpioCnviMfUart1ToExternalPads) {
+
+    GpioGetCnviMfUart1ExternalPins (&CnviMfUart1ExternalPad);
+
+    if (CnviMfUart1ExternalPad == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+      Status = GpioSetPadMode (CnviMfUart1ExternalPad[Index].Pad, CnviMfUart1ExternalPad[Index].Mode);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return EFI_UNSUPPORTED;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_PAD    CnviBtEnPad;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode        = GpioPadModeGpio;
+  PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
+  PadConfig.Direction      = GpioDirOut;
+  if (Value == 1) {
+    PadConfig.OutputState  = GpioOutHigh;
+  } else {
+    PadConfig.OutputState  = GpioOutLow;
+  }
+  CnviBtEnPad = GpioGetCnviBtEnablePin ();
+
+  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode and it is GPO
+  GpioUnlockPadCfg (CnviBtEnPad);
+  GpioUnlockPadCfgTx (CnviBtEnPad);
+  Status = GpioSetPadConfig (CnviBtEnPad, &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  This function sets CNVi Bluetooth main host interface
+
+  @param[in] BtInterface          CNVi BT Interface Select value
+                                  GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviBtInterface (
+  IN  VGPIO_CNVI_BT_INTERFACE  BtInterface
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode        = GpioPadModeGpio;
+  PadConfig.Direction      = GpioDirOut;
+  if (BtInterface == GpioCnviBtIfUsb) {
+    PadConfig.OutputState  = GpioOutHigh;
+  } else {
+    PadConfig.OutputState  = GpioOutLow;
+  }
+
+  Status = GpioSetPadConfig (GpioGetCnviBtIfSelectPin (), &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS                Status;
+  GPIO_CONFIG               CnviBtChargingPadConfig;
+  GPIO_PAD_NATIVE_FUNCTION  A4WpPad;
+
+  ZeroMem (&CnviBtChargingPadConfig, sizeof (CnviBtChargingPadConfig));
+
+  CnviBtChargingPadConfig.PadMode        = GpioPadModeGpio;
+  CnviBtChargingPadConfig.Direction      = GpioDirOut;
+
+  if (BtWirelessCharging == 1) {
+    CnviBtChargingPadConfig.OutputState  = GpioOutHigh;
+
+    GpioGetCnviA4WpPin (&A4WpPad);
+
+    Status = GpioSetPadMode (A4WpPad.Pad, A4WpPad.Mode);
+    ASSERT_EFI_ERROR (Status);
+
+  } else {
+    CnviBtChargingPadConfig.OutputState  = GpioOutLow;
+  }
+
+  Status = GpioSetPadConfig (GpioGetCnviBtChargingPin (), &CnviBtChargingPadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function enables and configures CNVi Bluetooth Host wake-up interrupt
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtHostWakeInt (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_PAD    CnviBtHostWakeIntPad;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode = GpioPadModeGpio;
+  PadConfig.Direction = GpioDirIn;
+  PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
+  PadConfig.InterruptConfig = GpioIntEdge;
+  PadConfig.PowerConfig  = GpioHostDeepReset;
+  CnviBtHostWakeIntPad = GpioGetCnviBtHostWakeIntPin ();
+
+  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode.
+  GpioUnlockPadCfg (CnviBtHostWakeIntPad);
+  Status = GpioSetPadConfig (CnviBtHostWakeIntPad, &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function enables IMGU CLKOUT native pin
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableImguClkOut (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *ImguClkOutGpio;
+  UINT32                    NoOfNativePins;
+
+  GpioGetImgClkOutPins (
+    &ImguClkOutGpio,
+    &NoOfNativePins
+    );
+
+  if (ImguClkOutGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NoOfNativePins; Index++) {
+    Status = GpioSetPadMode (ImguClkOutGpio[Index].Pad, ImguClkOutGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  GpioSetDebounceTimer (GpioGetPwrBtnPin (), &DebounceTime);
+}
+
+/**
+  Configure LPC GPIO
+**/
+VOID
+LpcConfigureGpio (
+  VOID
+  )
+{
+  GPIO_PAD      GpioPad;
+  GpioPad = GpioGetLpcPin();
+
+  if (GpioPad == 0) {
+    return;
+  } else {
+    GpioSetPadElectricalConfig (GpioPad, GpioTermWpu20K);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c
new file mode 100644
index 0000000000..4cff00c27b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c
@@ -0,0 +1,2275 @@
+/** @file
+  This file contains specific GPIO information
+
+  Copyright (c) 2019 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 <SaAccess.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Register/PchRegsGpio.h>
+#include <Register/PchRegsGpioCnl.h>
+#include <Register/PchRegsSerialIo.h>
+#include <Register/PchRegsIsh.h>
+#include <Register/PchRegsScs.h>
+#include <Register/PchRegsLpcCnl.h>
+
+#include "GpioNativePrivateLibInternal.h"
+
+//
+// I2C controller pins
+// I2C[controller number][pin: SDA/SCL]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
+{
+  {{GPIO_CNL_LP_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C17, GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C19, GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H4,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H5 , GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H6,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H7 , GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H8,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H9 , GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H10, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H11, GpioPadModeNative1}}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION  mPchHI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
+{
+  {{GPIO_CNL_H_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C17, GpioPadModeNative1}}, // I2C0
+  {{GPIO_CNL_H_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C19, GpioPadModeNative1}}, // I2C1
+  {{GPIO_CNL_H_GPP_D13, GpioPadModeNative3}, {GPIO_CNL_H_GPP_D14, GpioPadModeNative3}}, // I2C2
+  {{GPIO_CNL_H_GPP_D4,  GpioPadModeNative2}, {GPIO_CNL_H_GPP_D23, GpioPadModeNative2}}  // I2C3
+};
+
+
+/**
+  This function provides SerialIo I2C controller pins
+
+  @param[in]  SerialIoI2cControllerNumber    I2C controller
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoI2cPins (
+  IN  UINT32                      SerialIoI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchLpI2cGpio)) {
+      *NativePinsTable = mPchLpI2cGpio[SerialIoI2cControllerNumber];
+      return;
+    }
+  } else {
+    if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchHI2cGpio)) {
+      *NativePinsTable = mPchHI2cGpio[SerialIoI2cControllerNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+//
+// UART controller pins
+// UART[controller number][pin: RXD/TXD/RTSB/CTSB]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
+{
+  { // UART0
+    {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C10, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C11, GpioPadModeNative1}
+  },
+  { // UART1
+    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative1}
+  },
+  { // UART2
+    {GPIO_CNL_LP_GPP_C20, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C21, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C22, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C23, GpioPadModeNative1},
+  },
+  { // UART0 (2nd pin set)
+    {GPIO_CNL_LP_GPP_F5, GpioPadModeNative2},
+    {GPIO_CNL_LP_GPP_F6, GpioPadModeNative2},
+    {GPIO_CNL_LP_GPP_F4, GpioPadModeNative2},
+    {GPIO_CNL_LP_GPP_F7, GpioPadModeNative2}
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
+{
+  { // UART0
+    {GPIO_CNL_H_GPP_C8,  GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C9,  GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C10, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C11, GpioPadModeNative1}
+  },
+  { // UART1
+    {GPIO_CNL_H_GPP_C12, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C13, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C14, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C15, GpioPadModeNative1}
+  },
+  { // UART2
+    {GPIO_CNL_H_GPP_C20, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C21, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C22, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C23, GpioPadModeNative1}
+  },
+  { // UART0 (2nd pin set)
+    {GPIO_CNL_H_GPP_J5, GpioPadModeNative2},
+    {GPIO_CNL_H_GPP_J6, GpioPadModeNative2},
+    {GPIO_CNL_H_GPP_J4, GpioPadModeNative2},
+    {GPIO_CNL_H_GPP_J7, GpioPadModeNative2}
+  }
+};
+
+/**
+  This function provides SerialIo UART controller pins
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+   @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoUartPins (
+  IN  UINT32                      SerialIoUartControllerNumber,
+  IN  BOOLEAN                     HardwareFlowControl,
+  IN  UINT32                      PinMuxing,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  UINTN                    UartGpioIndex;
+
+  UartGpioIndex = SerialIoUartControllerNumber;
+
+  if ((SerialIoUartControllerNumber == 0) && (PinMuxing == 1)) {
+    // Last record is for UART0 second pin set
+    if (IsPchLp ()) {
+      UartGpioIndex = ARRAY_SIZE (mPchLpUartGpio) - 1;
+    } else {
+      UartGpioIndex = ARRAY_SIZE (mPchHUartGpio) - 1;
+    }
+  }
+
+  if (HardwareFlowControl) {
+    *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER;
+  } else {
+    *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL;
+  }
+
+  if (IsPchLp ()) {
+    if (UartGpioIndex < ARRAY_SIZE (mPchLpUartGpio)) {
+      *NativePinsTable = mPchLpUartGpio[UartGpioIndex];
+      return;
+    }
+  } else {
+    if (UartGpioIndex < ARRAY_SIZE (mPchHUartGpio)) {
+      *NativePinsTable = mPchHUartGpio[UartGpioIndex];
+      return;
+    }
+  }
+
+  *NativePinsTable = NULL;
+  *NoOfNativePins = 0;
+  ASSERT (FALSE);
+}
+
+//
+// SPI controller pins
+// SPI[controller number][pin: CSB/CLK/MISO/MOSI]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
+{
+  { // SPI0
+    {GPIO_CNL_LP_GPP_B15, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B16, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B17, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B18, GpioPadModeNative1}
+  },
+  { // SPI1
+    {GPIO_CNL_LP_GPP_B19, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B20, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B21, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B22, GpioPadModeNative1}
+  },
+  { // SPI2
+    {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative3},
+    {GPIO_CNL_LP_GPP_D10, GpioPadModeNative3},
+    {GPIO_CNL_LP_GPP_D11, GpioPadModeNative3},
+    {GPIO_CNL_LP_GPP_D12, GpioPadModeNative3}
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
+{
+  { // SPI0
+    {GPIO_CNL_H_GPP_B15, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B16, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B17, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B18, GpioPadModeNative1}
+  },
+  { // SPI1
+    {GPIO_CNL_H_GPP_B19, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B20, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B21, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B22, GpioPadModeNative1}
+  },
+  { // SPI2
+    {GPIO_CNL_H_GPP_D9,  GpioPadModeNative3},
+    {GPIO_CNL_H_GPP_D10, GpioPadModeNative3},
+    {GPIO_CNL_H_GPP_D11, GpioPadModeNative3},
+    {GPIO_CNL_H_GPP_D12, GpioPadModeNative3}
+  }
+};
+
+/**
+  This function provides SerialIo SPI controller pins
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @param[out] NativePinsTable               Table with pins
+  @param[out] NoOfNativePins                Number of pins
+**/
+VOID
+GpioGetSerialIoSpiPins (
+  IN  UINT32                      SerialIoSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchLpSpiGpio)) {
+      *NativePinsTable = mPchLpSpiGpio[SerialIoSpiControllerNumber];
+      *NoOfNativePins =  ARRAY_SIZE (mPchLpSpiGpio[SerialIoSpiControllerNumber]);
+      return;
+    }
+  } else {
+    if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchHSpiGpio)) {
+      *NativePinsTable = mPchHSpiGpio[SerialIoSpiControllerNumber];
+      *NoOfNativePins =  ARRAY_SIZE (mPchHSpiGpio[SerialIoSpiControllerNumber]);
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  *NoOfNativePins = 0;
+  ASSERT (FALSE);
+}
+
+//
+// ISH GP pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshGPGpio[] =
+{
+  {GPIO_CNL_LP_GPP_A18, GpioPadModeNative1},// ISH_GP_0
+  {GPIO_CNL_LP_GPP_A19, GpioPadModeNative1},// ISH_GP_1
+  {GPIO_CNL_LP_GPP_A20, GpioPadModeNative1},// ISH_GP_2
+  {GPIO_CNL_LP_GPP_A21, GpioPadModeNative1},// ISH_GP_3
+  {GPIO_CNL_LP_GPP_A22, GpioPadModeNative1},// ISH_GP_4
+  {GPIO_CNL_LP_GPP_A23, GpioPadModeNative1},// ISH_GP_5
+  {GPIO_CNL_LP_GPP_A12, GpioPadModeNative2},// ISH_GP_6
+  {GPIO_CNL_LP_GPP_A17, GpioPadModeNative2} // ISH_GP_7
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshGPGpio[] =
+{
+  {GPIO_CNL_H_GPP_A18, GpioPadModeNative1},// ISH_GP_0
+  {GPIO_CNL_H_GPP_A19, GpioPadModeNative1},// ISH_GP_1
+  {GPIO_CNL_H_GPP_A20, GpioPadModeNative1},// ISH_GP_2
+  {GPIO_CNL_H_GPP_A21, GpioPadModeNative1},// ISH_GP_3
+  {GPIO_CNL_H_GPP_A22, GpioPadModeNative1},// ISH_GP_4
+  {GPIO_CNL_H_GPP_A23, GpioPadModeNative1},// ISH_GP_5
+  {GPIO_CNL_H_GPP_A12, GpioPadModeNative2},// ISH_GP_6
+  {GPIO_CNL_H_GPP_A17, GpioPadModeNative2} // ISH_GP_7
+};
+
+/**
+  This function provides ISH GP pin data
+
+  @param[in]  IshGpPinNumber        ISH GP pin number
+  @param[out] NativePin             ISH GP pin
+**/
+VOID
+GpioGetIshGpPin (
+  IN  UINT32                      IshGpPinNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  )
+{
+  if (IsPchLp ()) {
+    if (IshGpPinNumber < ARRAY_SIZE (mPchLpIshGPGpio)) {
+      *NativePin = mPchLpIshGPGpio[IshGpPinNumber];
+      return;
+    }
+  } else {
+    if (IshGpPinNumber < ARRAY_SIZE (mPchHIshGPGpio)) {
+      *NativePin = mPchHIshGPGpio[IshGpPinNumber];
+      return;
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// ISH UART controller pins
+// ISH UART[controller number][pin: RXD/TXD/RTSB/CTSB]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
+{
+  { // UART0
+    {GPIO_CNL_LP_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
+    {GPIO_CNL_LP_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
+    {GPIO_CNL_LP_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
+    {GPIO_CNL_LP_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
+  },
+  { // UART1
+    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
+    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
+    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTSB
+    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTSB
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
+{
+  { // UART0
+    {GPIO_CNL_H_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
+    {GPIO_CNL_H_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
+    {GPIO_CNL_H_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
+    {GPIO_CNL_H_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
+  },
+  { // UART1
+    {GPIO_CNL_H_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
+    {GPIO_CNL_H_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
+    {GPIO_CNL_H_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTS
+    {GPIO_CNL_H_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTS
+  }
+};
+
+/**
+  This function provides ISH UART controller pins
+
+  @param[in]  IshUartControllerNumber   ISH UART controller
+
+  @param[out] NativePinsTable           Table with pins
+**/
+VOID
+GpioGetIshUartPins (
+  IN  UINT32                      IshUartControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (IshUartControllerNumber < ARRAY_SIZE (mPchLpIshUartGpio)) {
+      *NativePinsTable = mPchLpIshUartGpio[IshUartControllerNumber];
+      return;
+    }
+  } else {
+    if (IshUartControllerNumber < ARRAY_SIZE (mPchHIshUartGpio)) {
+      *NativePinsTable = mPchHIshUartGpio[IshUartControllerNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// ISH I2C controller pins
+// ISH I2C[controller number][pin: SDA/SCL]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
+{
+  { // I2C0
+    {GPIO_CNL_LP_GPP_D5,  GpioPadModeNative1},// ISH_I2C0_SDA
+    {GPIO_CNL_LP_GPP_D6,  GpioPadModeNative1} // ISH_I2C0_SCL
+  },
+  { // I2C1
+    {GPIO_CNL_LP_GPP_D7,  GpioPadModeNative1},// ISH_I2C1_SDA
+    {GPIO_CNL_LP_GPP_D8,  GpioPadModeNative1} // ISH_I2C1_SCL
+  },
+  { // I2C2
+    {GPIO_CNL_LP_GPP_H10, GpioPadModeNative2},// ISH_I2C2_SDA
+    {GPIO_CNL_LP_GPP_H11, GpioPadModeNative2} // ISH_I2C2_SCL
+  },
+  { // I2C3
+    {GPIO_CNL_LP_GPP_H4,  GpioPadModeNative2},// ISH_I2C3_SDA
+    {GPIO_CNL_LP_GPP_H5,  GpioPadModeNative2} // ISH_I2C3_SCL
+  },
+  { // I2C4
+    {GPIO_CNL_LP_GPP_H6,  GpioPadModeNative2},// ISH_I2C4_SDA
+    {GPIO_CNL_LP_GPP_H7,  GpioPadModeNative2} // ISH_I2C4_SCL
+  },
+  { // I2C5
+    {GPIO_CNL_LP_GPP_H8,  GpioPadModeNative2},// ISH_I2C5_SDA
+    {GPIO_CNL_LP_GPP_H9,  GpioPadModeNative2} // ISH_I2C5_SCL
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
+{
+  { // I2C0
+    {GPIO_CNL_H_GPP_H19, GpioPadModeNative1},// ISH_I2C0_SDA
+    {GPIO_CNL_H_GPP_H20, GpioPadModeNative1} // ISH_I2C0_SCL
+  },
+  { // I2C1
+    {GPIO_CNL_H_GPP_H21, GpioPadModeNative1},// ISH_I2C1_SDA
+    {GPIO_CNL_H_GPP_H22, GpioPadModeNative1} // ISH_I2C1_SCL
+  },
+  { // I2C2
+    {GPIO_CNL_H_GPP_D4,  GpioPadModeNative1},// ISH_I2C2_SDA
+    {GPIO_CNL_H_GPP_D23, GpioPadModeNative1} // ISH_I2C2_SCL
+  }
+};
+
+/**
+  This function provides ISH I2C controller pins
+
+  @param[in]  IshI2cControllerNumber   ISH I2C controller
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetIshI2cPins (
+  IN  UINT32                      IshI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (IshI2cControllerNumber < ARRAY_SIZE (mPchLpIshI2cGpio)) {
+      *NativePinsTable = mPchLpIshI2cGpio[IshI2cControllerNumber];
+      return;
+    }
+  } else {
+    if (IshI2cControllerNumber < ARRAY_SIZE (mPchHIshI2cGpio)) {
+      *NativePinsTable = mPchHIshI2cGpio[IshI2cControllerNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// ISH SPI controller pins
+// ISH SPI[pin: CSB/CLK/MISO/MOSI]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
+{
+  {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
+  {GPIO_CNL_LP_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
+  {GPIO_CNL_LP_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
+  {GPIO_CNL_LP_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
+{
+  {GPIO_CNL_H_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
+  {GPIO_CNL_H_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
+  {GPIO_CNL_H_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
+  {GPIO_CNL_H_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
+};
+
+/**
+  This function provides ISH SPI controller pins
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins           Number of pins
+**/
+VOID
+GpioGetIshSpiPins (
+  IN  UINT32                      IshSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    if (IshSpiControllerNumber < ARRAY_SIZE (mPchLpIshSpiGpio)) {
+      *NativePinsTable = mPchLpIshSpiGpio;
+      *NoOfNativePins = ARRAY_SIZE (mPchLpIshSpiGpio);
+      return;
+    }
+  } else {
+    if (IshSpiControllerNumber < ARRAY_SIZE (mPchHIshSpiGpio)) {
+      *NativePinsTable = mPchHIshSpiGpio;
+      *NoOfNativePins = ARRAY_SIZE (mPchHIshSpiGpio);
+      return;
+    }
+  }
+
+  *NoOfNativePins = 0;
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO pins for SD controller
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpScsSdCardGpio[9] =
+{
+  {GPIO_CNL_LP_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
+  {GPIO_CNL_LP_GPP_G0,  GpioPadModeNative1},// SD_CMD
+  {GPIO_CNL_LP_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
+  {GPIO_CNL_LP_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
+  {GPIO_CNL_LP_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
+  {GPIO_CNL_LP_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
+  {GPIO_CNL_LP_GPP_G5,  GpioPadModeNative1},// SD_CDB
+  {GPIO_CNL_LP_GPP_G6,  GpioPadModeNative1},// SD_CLK
+  {GPIO_CNL_LP_GPP_G7,  GpioPadModeNative1} // SD_WP
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHScsSdCardGpio[9] =
+{
+  {GPIO_CNL_H_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
+  {GPIO_CNL_H_GPP_G0,  GpioPadModeNative1},// SD_CMD
+  {GPIO_CNL_H_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
+  {GPIO_CNL_H_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
+  {GPIO_CNL_H_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
+  {GPIO_CNL_H_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
+  {GPIO_CNL_H_GPP_G5,  GpioPadModeNative1},// SD_CDB
+  {GPIO_CNL_H_GPP_G6,  GpioPadModeNative1},// SD_CLK
+  {GPIO_CNL_H_GPP_G7,  GpioPadModeNative1} // SD_WP
+};
+
+/**
+  This function provides SCS SD CARD controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsSdCardPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpScsSdCardGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpScsSdCardGpio);
+  } else {
+    *NativePinsTable = mPchHScsSdCardGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchHScsSdCardGpio);
+  }
+}
+
+/**
+  This function provides SCS SD CARD detect pin
+
+  @retval GpioPin             SD CARD Detect pin
+**/
+GPIO_PAD
+GpioGetScsSdCardDetectPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO39;
+  } else {
+    return GPIO_CNL_H_VGPIO6;
+  }
+}
+
+//
+// GPIO pins for eMMC controller
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpScsEmmcGpio[12] =
+{
+  {GPIO_CNL_LP_GPP_F11, GpioPadModeNative1},// EMMC_CMD
+  {GPIO_CNL_LP_GPP_F12, GpioPadModeNative1},// EMMC_DATA_0
+  {GPIO_CNL_LP_GPP_F13, GpioPadModeNative1},// EMMC_DATA_1
+  {GPIO_CNL_LP_GPP_F14, GpioPadModeNative1},// EMMC_DATA_2
+  {GPIO_CNL_LP_GPP_F15, GpioPadModeNative1},// EMMC_DATA_3
+  {GPIO_CNL_LP_GPP_F16, GpioPadModeNative1},// EMMC_DATA_4
+  {GPIO_CNL_LP_GPP_F17, GpioPadModeNative1},// EMMC_DATA_5
+  {GPIO_CNL_LP_GPP_F18, GpioPadModeNative1},// EMMC_DATA_6
+  {GPIO_CNL_LP_GPP_F19, GpioPadModeNative1},// EMMC_DATA_7
+  {GPIO_CNL_LP_GPP_F20, GpioPadModeNative1},// EMMC_RCLK
+  {GPIO_CNL_LP_GPP_F21, GpioPadModeNative1},// EMMC_CLK
+  {GPIO_CNL_LP_GPP_F22, GpioPadModeNative1} // EMMC_RESETB
+};
+
+/**
+  This function provides SCS eMMC controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsEmmcPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpScsEmmcGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpScsEmmcGpio);
+  } else {
+    ASSERT (FALSE);
+    return;
+  }
+}
+
+//
+// GPIO pins for HD Audio Link [pin: BCLK/RSTB/SYNC/SDO/SDIx]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
+  {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
+  {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
+  {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
+  {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
+  {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
+  {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
+  {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
+  {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
+  {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
+  {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
+};
+
+/**
+  This function provides HD Audio Link pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetHdAudioLinkPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpHdaLinkGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpHdaLinkGpio);
+  } else {
+    *NativePinsTable = mPchHHdaLinkGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchHHdaLinkGpio);
+  }
+}
+
+//
+// GPIO pins for HD Audio DMIC [DMIC number][pin: CLK/DATA]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
+{
+  { // DMIC0
+    {GPIO_CNL_LP_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
+    {GPIO_CNL_LP_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
+  },
+  { // DMIC1
+    {GPIO_CNL_LP_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
+    {GPIO_CNL_LP_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
+{
+  { // DMIC0
+    {GPIO_CNL_H_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
+    {GPIO_CNL_H_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
+  },
+  { // DMIC1
+    {GPIO_CNL_H_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
+    {GPIO_CNL_H_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
+  }
+};
+
+/**
+  This function provides DMIC interface pins
+
+  @param[in]  DmicNumber               DMIC interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaDmicPins (
+  IN  UINT32                      DmicNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (DmicNumber < ARRAY_SIZE (mPchLpHdaDmicGpio)) {
+      *NativePinsTable = mPchLpHdaDmicGpio[DmicNumber];
+      return;
+    }
+  } else {
+    if (DmicNumber < ARRAY_SIZE (mPchHHdaDmicGpio)) {
+      *NativePinsTable = mPchHHdaDmicGpio[DmicNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO pins for HD Audio SSPx/I2Sx interface [SSP number][pin: SCLK/SFRM/TXD/RXD]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
+{
+  { // SSP0/I2S0
+    {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
+    {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
+    {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
+    {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
+  },
+  { // SSP1/I2S1
+    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
+    {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
+    {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
+    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
+  },
+  { // SSP2/I2S2
+    {GPIO_CNL_LP_GPP_H0, GpioPadModeNative1},// SSP2_SCLK
+    {GPIO_CNL_LP_GPP_H1, GpioPadModeNative1},// SSP2_SFRM
+    {GPIO_CNL_LP_GPP_H2, GpioPadModeNative1},// SSP2_TXD
+    {GPIO_CNL_LP_GPP_H3, GpioPadModeNative1} // SSP2_RXD
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
+{
+  { // SSP0/I2S0
+    {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
+    {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
+    {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
+    {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
+  },
+  { // SSP1/I2S1
+    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
+    {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
+    {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
+    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
+  },
+  { // SSP2/I2S2
+    {GPIO_CNL_H_GPP_D5, GpioPadModeNative1}, // SSP2_SFRM
+    {GPIO_CNL_H_GPP_D6, GpioPadModeNative1}, // SSP2_TXD
+    {GPIO_CNL_H_GPP_D7, GpioPadModeNative1}, // SSP2_RXD
+    {GPIO_CNL_H_GPP_D8, GpioPadModeNative1}  // SSP2_SCLK
+  }
+};
+
+/**
+  This function provides SSP/I2S interface pins
+
+  @param[in]  SspInterfaceNumber       SSP/I2S interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSspPins (
+  IN  UINT32                      SspInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (SspInterfaceNumber < ARRAY_SIZE (mPchLpHdaSspInterfaceGpio)) {
+      *NativePinsTable = mPchLpHdaSspInterfaceGpio[SspInterfaceNumber];
+      return;
+    }
+  } else {
+    if (SspInterfaceNumber < ARRAY_SIZE (mPchHHdaSspInterfaceGpio)) {
+      *NativePinsTable = mPchHHdaSspInterfaceGpio[SspInterfaceNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO Pin for HD Audio SSP_MCLK/I2S_MCLK
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSspMasterClockGpio = {GPIO_CNL_LP_GPP_D23, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSspMasterClockGpio = {GPIO_CNL_H_GPP_B11, GpioPadModeNative1};
+
+/**
+  This function sets HDA SSP Master Clock into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSspMasterClock (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GpioSetPadMode (mPchLpHdaSspMasterClockGpio.Pad, mPchLpHdaSspMasterClockGpio.Mode);
+  } else {
+    return GpioSetPadMode (mPchHHdaSspMasterClockGpio.Pad, mPchHHdaSspMasterClockGpio.Mode);
+  }
+}
+
+//
+// GPIO pins for HD Audio SoundWire interface [SNDW number][pin: CLK/DATA]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
+{
+  { // SNDW1
+    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
+    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
+  },
+  { // SNDW2
+    {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
+    {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
+  },
+  { // SNDW3
+    {GPIO_CNL_LP_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
+    {GPIO_CNL_LP_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
+  },
+  { // SNDW4
+    {GPIO_CNL_LP_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
+    {GPIO_CNL_LP_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
+{
+  { // SNDW1
+    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
+    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
+  },
+  { // SNDW2
+    {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
+    {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
+  },
+  { // SNDW3
+    {GPIO_CNL_H_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
+    {GPIO_CNL_H_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
+  },
+  { // SNDW4
+    {GPIO_CNL_H_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
+    {GPIO_CNL_H_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
+  }
+};
+
+/**
+  This function provides SNDW interface pins
+
+  @param[in]  SndwInterfaceNumber      SNDWx interface number
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSndwPins (
+  IN  UINT32                      SndwInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (SndwInterfaceNumber < ARRAY_SIZE (mPchLpHdaSndwGpio)) {
+      *NativePinsTable = mPchLpHdaSndwGpio[SndwInterfaceNumber];
+      return;
+    }
+  } else {
+    if (SndwInterfaceNumber < ARRAY_SIZE (mPchHHdaSndwGpio)) {
+      *NativePinsTable = mPchHHdaSndwGpio[SndwInterfaceNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO pins for SMBUS
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_C0, GpioPadModeNative1},// SMB_CLK
+  {GPIO_CNL_LP_GPP_C1, GpioPadModeNative1} // SMB_DATA
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_C0, GpioPadModeNative1}, // SMB_CLK
+  {GPIO_CNL_H_GPP_C1, GpioPadModeNative1}  // SMB_DATA
+};
+
+/**
+  This function provides SMBUS interface pins
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetSmbusPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpSmbusGpio;
+  } else {
+    *NativePinsTable = mPchHSmbusGpio;
+  }
+}
+
+//
+// SMBUS Alert pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSmbusAlertGpio = {GPIO_CNL_LP_GPP_C2,  GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSmbusAlertGpio = {GPIO_CNL_H_GPP_C2,  GpioPadModeNative1};
+
+/**
+  This function sets SMBUS ALERT pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSmbusAlert (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION SmbusAlertGpio;
+
+  if (IsPchLp ()) {
+    SmbusAlertGpio = mPchLpSmbusAlertGpio;
+  } else {
+    SmbusAlertGpio = mPchHSmbusAlertGpio;
+  }
+
+  return GpioSetPadMode (SmbusAlertGpio.Pad, SmbusAlertGpio.Mode);
+}
+
+//
+// SATADevSlpPin to GPIO pin mapping
+// SATA_DEVSLP_x -> GPIO pin y
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataDevSlpPinToGpioMap[] =
+{
+  {GPIO_CNL_LP_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_E6, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataDevSlpPinToGpioMap[] =
+{
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F8, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F9, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata1DevSlpPinToGpioMap[] =
+{
+/// @todo SERVER- update for SATA 1
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata2DevSlpPinToGpioMap[] =
+{
+/// @todo SERVER- update for SATA 2
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata3DevSlpPinToGpioMap[] =
+{
+/// @todo SERVER- update for SATA 3
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
+};
+
+/**
+  This function provides SATA DevSlp pin data
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+  @param[out] NativePin           SATA DevSlp pin
+**/
+VOID
+GpioGetSataDevSlpPin (
+  IN  UINT32                    SataCtrlIndex,
+  IN  UINTN                     SataPort,
+  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
+  )
+{
+  if (IsCdfPch ()) {
+    if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata1DevSlpPinToGpioMap)) {
+        *NativePin = mCdfPchSata1DevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata2DevSlpPinToGpioMap)) {
+        *NativePin = mCdfPchSata2DevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata3DevSlpPinToGpioMap)) {
+        *NativePin = mCdfPchSata3DevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    }
+  } else {
+    if (IsPchLp ()) {
+      if (SataPort < ARRAY_SIZE (mPchLpSataDevSlpPinToGpioMap)) {
+        *NativePin = mPchLpSataDevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    } else {
+      if (SataPort < ARRAY_SIZE (mPchHSataDevSlpPinToGpioMap)) {
+        *NativePin = mPchHSataDevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// SATA reset port to GPIO pin mapping
+// SATAGP_x -> GPIO pin y
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataGpToGpioMap[] =
+{
+  {GPIO_CNL_LP_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_LP_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_LP_GPP_E2, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataGpToGpioMap[]  =
+{
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F3, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F4, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata1GpToGpioMap[]  =
+{
+/// @todo SERVER- update for SATA 1
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata2GpToGpioMap[]  =
+{
+/// @todo SERVER- update for SATA 2
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata3GpToGpioMap[]  =
+{
+/// @todo SERVER- update for SATA 3
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
+};
+
+/**
+  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
+  )
+{
+  if (IsCdfPch ()) {
+    if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata1GpToGpioMap)) {
+        *NativePin = mCdfPchSata1GpToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata2GpToGpioMap)) {
+        *NativePin = mCdfPchSata2GpToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata3GpToGpioMap)) {
+        *NativePin = mCdfPchSata3GpToGpioMap[SataPort];
+        return;
+      }
+    }
+  } else {
+    if (IsPchLp ()) {
+      if (SataPort < ARRAY_SIZE (mPchLpSataGpToGpioMap)) {
+        *NativePin = mPchLpSataGpToGpioMap[SataPort];
+        return;
+      }
+    } else {
+      if (SataPort < ARRAY_SIZE (mPchHSataGpToGpioMap)) {
+        *NativePin = mPchHSataGpToGpioMap[SataPort];
+        return;
+      }
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// SATA LED pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataLedGpio = {GPIO_CNL_LP_GPP_E8, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataLedGpio = {GPIO_CNL_H_GPP_E8, GpioPadModeNative1};
+
+/**
+  This function sets SATA LED pin into native mode. SATA LED indicates
+  SATA controller activity
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataLed (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  SataLedGpio;
+
+  if (IsPchLp ()) {
+    SataLedGpio = mPchLpSataLedGpio;
+  } else {
+    SataLedGpio = mPchHSataLedGpio;
+  }
+
+  return GpioSetPadMode (SataLedGpio.Pad, SataLedGpio.Mode);
+}
+
+//
+// USB2 OC pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpUsbOcGpioPins[] =
+{
+  {GPIO_CNL_LP_GPP_E9,  GpioPadModeNative1},// USB_OC_0
+  {GPIO_CNL_LP_GPP_E10, GpioPadModeNative1},// USB_OC_1
+  {GPIO_CNL_LP_GPP_E11, GpioPadModeNative1},// USB_OC_2
+  {GPIO_CNL_LP_GPP_E12, GpioPadModeNative1} // USB_OC_3
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHUsbOcGpioPins[] =
+{
+  {GPIO_CNL_H_GPP_E9,  GpioPadModeNative1},// USB_OC_0
+  {GPIO_CNL_H_GPP_E10, GpioPadModeNative1},// USB_OC_1
+  {GPIO_CNL_H_GPP_E11, GpioPadModeNative1},// USB_OC_2
+  {GPIO_CNL_H_GPP_E12, GpioPadModeNative1},// USB_OC_3
+  {GPIO_CNL_H_GPP_F15, GpioPadModeNative1},// USB_OC_4
+  {GPIO_CNL_H_GPP_F16, GpioPadModeNative1},// USB_OC_5
+  {GPIO_CNL_H_GPP_F17, GpioPadModeNative1},// USB_OC_6
+  {GPIO_CNL_H_GPP_F18, GpioPadModeNative1} // USB_OC_7
+};
+
+/**
+  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
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  OcGpio;
+
+  if (IsPchLp ()) {
+    if (OcPinNumber >= ARRAY_SIZE (mPchLpUsbOcGpioPins)) {
+      ASSERT(FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    OcGpio = mPchLpUsbOcGpioPins[OcPinNumber];
+  } else {
+    if (OcPinNumber >= ARRAY_SIZE (mPchHUsbOcGpioPins)) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    OcGpio = mPchHUsbOcGpioPins[OcPinNumber];
+  }
+
+  return GpioSetPadMode (OcGpio.Pad, OcGpio.Mode);
+}
+
+//
+// GPIO pin for PCIE SCRCLKREQB
+// SCRCLKREQB_x -> GPIO pin y
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpPcieSrcClkReqbPinToGpioMap[] =
+{
+  {GPIO_CNL_LP_GPP_B5,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B6,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B7,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B8,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B9,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B10, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHPcieSrcClkReqbPinToGpioMap[]  =
+{
+  {GPIO_CNL_H_GPP_B5,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B6,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B7,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B8,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B9,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B10, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H0,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H1,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H2,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H3,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H4,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H5,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H6,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H7,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H8,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H9,  GpioPadModeNative1}
+};
+
+/**
+  This function provides PCIe CLKREQ pin data
+
+  @param[in]  ClkreqIndex        CLKREQ# number
+  @param[out] NativePin          Native pin data
+**/
+VOID
+GpioGetPcieClkReqPin (
+  IN  UINT32                      ClkreqIndex,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  )
+{
+  if (IsPchLp ()) {
+    if (ClkreqIndex < ARRAY_SIZE (mPchLpPcieSrcClkReqbPinToGpioMap)) {
+      *NativePin = mPchLpPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
+      return;
+    }
+  } else {
+    if (ClkreqIndex < ARRAY_SIZE (mPchHPcieSrcClkReqbPinToGpioMap)) {
+      *NativePin = mPchHPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
+      return;
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// PCHHOTB pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpPchHotbPin = {GPIO_CNL_LP_GPP_B23,  GpioPadModeNative2};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHPchHotbPin = {GPIO_CNL_H_GPP_B23,  GpioPadModeNative2};
+
+/**
+  This function sets PCHHOT pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnablePchHot (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION PchHotbPin;
+
+  if (IsPchLp ()) {
+    PchHotbPin = mPchLpPchHotbPin;
+  } else {
+    PchHotbPin = mPchHPchHotbPin;
+  }
+
+  return GpioSetPadMode (PchHotbPin.Pad, PchHotbPin.Mode);
+}
+
+//
+// VRALERTB pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpVrAlertbPin = {GPIO_CNL_LP_GPP_B2, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHVrAlertbPin = {GPIO_CNL_H_GPP_B2, GpioPadModeNative1};
+
+//
+// CPU_C10_GATE pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCpuC10GatePin = {GPIO_CNL_LP_GPP_H18, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCpuC10GatePin = {GPIO_CNL_H_GPP_J1, GpioPadModeNative2};
+
+/**
+  This function sets VRALERTB pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableVrAlert (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  VrAlertGpio;
+
+  if (IsPchLp ()) {
+    VrAlertGpio = mPchLpVrAlertbPin;
+  } else {
+    VrAlertGpio = mPchHVrAlertbPin;
+  }
+
+  return GpioSetPadMode (VrAlertGpio.Pad, VrAlertGpio.Mode);
+}
+
+/**
+This function sets CPU C10 Gate pins into native mode
+
+@retval Status
+**/
+EFI_STATUS
+GpioEnableCpuC10GatePin (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  CpuC10GateGpio;
+
+  if (IsPchLp ()) {
+    CpuC10GateGpio = mPchLpCpuC10GatePin;
+  } else {
+    CpuC10GateGpio = mPchHCpuC10GatePin;
+  }
+
+  return GpioSetPadMode (CpuC10GateGpio.Pad, CpuC10GateGpio.Mode);
+}
+
+//
+// CPU GP pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
+  {GPIO_CNL_LP_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
+  {GPIO_CNL_LP_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
+  {GPIO_CNL_LP_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
+};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
+  {GPIO_CNL_H_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
+  {GPIO_CNL_H_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
+  {GPIO_CNL_H_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
+};
+
+/**
+  This function sets CPU GP pins into native mode
+
+  @param[in]  CpuGpPinNum               CPU GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableCpuGpPin (
+  IN  UINT32                            CpuGpPinNum
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION CpuGpPin;
+
+  if (IsPchLp ()) {
+    if (CpuGpPinNum >= ARRAY_SIZE (mPchLpCpuGpPinMap)) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    CpuGpPin = mPchLpCpuGpPinMap[CpuGpPinNum];
+  } else {
+    if (CpuGpPinNum >= ARRAY_SIZE (mPchHCpuGpPinMap)) {
+      ASSERT(FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    CpuGpPin = mPchHCpuGpPinMap[CpuGpPinNum];
+  }
+
+  return GpioSetPadMode (CpuGpPin.Pad, CpuGpPin.Mode);
+}
+
+//
+// DDSP_HPD pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpDdspHpdPins[] =
+{
+  {GPIO_CNL_LP_GPP_E13, GpioPadModeNative1},// DDSP_HPD_0
+  {GPIO_CNL_LP_GPP_E14, GpioPadModeNative1},// DDSP_HPD_1
+  {GPIO_CNL_LP_GPP_E15, GpioPadModeNative1},// DDSP_HPD_2
+  {GPIO_CNL_LP_GPP_E16, GpioPadModeNative1} // DDSP_HPD_3
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHDdspHpdPins[] =
+{
+  {GPIO_CNL_H_GPP_I0, GpioPadModeNative1},// DDSP_HPD_0
+  {GPIO_CNL_H_GPP_I1, GpioPadModeNative1},// DDSP_HPD_1
+  {GPIO_CNL_H_GPP_I2, GpioPadModeNative1},// DDSP_HPD_2
+  {GPIO_CNL_H_GPP_I3, GpioPadModeNative1} // DDSP_HPD_3
+};
+
+/**
+  This function sets DDSP_HPDx pin into native mode
+
+  @param[in]  DdspHpdPin     DDSP_HPDx pin
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpHotPlugDetect (
+  IN GPIO_DDSP_HPD  DdspHpdPin
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  DdspHpdGpio;
+  UINT32                    DdspHpdPinIndex;
+
+  if (DdspHpdPin > GpioDdspHpd3) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DdspHpdPinIndex = DdspHpdPin - GpioDdspHpd0;
+
+  if (IsPchLp ()) {
+    if (DdspHpdPinIndex >= ARRAY_SIZE (mPchLpDdspHpdPins)) {
+      goto Error;
+    }
+    DdspHpdGpio = mPchLpDdspHpdPins[DdspHpdPinIndex];
+  } else {
+    if (DdspHpdPinIndex >= ARRAY_SIZE (mPchHDdspHpdPins)) {
+      goto Error;
+    }
+    DdspHpdGpio = mPchHDdspHpdPins[DdspHpdPinIndex];
+  }
+
+  return GpioSetPadMode (DdspHpdGpio.Pad, DdspHpdGpio.Mode);
+Error:
+  ASSERT (FALSE);
+  return EFI_UNSUPPORTED;
+}
+
+//
+// EDP HPD, VDD and BKLT pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_E17,         GpioPadModeNative1},// EDP_HPD
+  {GPIO_CNL_LP_HVMOS_L_VDDEN,   GpioPadModeNative1},// VDDEN
+  {GPIO_CNL_LP_HVMOS_L_BKLTEN,  GpioPadModeNative1},// BKLTEN
+  {GPIO_CNL_LP_HVMOS_L_BKLTCTL, GpioPadModeNative1} // BKLTCTL
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_I4,  GpioPadModeNative1},// EDP_HPD
+  {GPIO_CNL_H_GPP_F19, GpioPadModeNative1},// VDDEN
+  {GPIO_CNL_H_GPP_F20, GpioPadModeNative1},// BKLTEN
+  {GPIO_CNL_H_GPP_F21, GpioPadModeNative1} // BKLTCTL
+};
+
+/**
+  This function provides eDP pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetEdpPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpEdpPins;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpEdpPins);
+  } else {
+    *NativePinsTable = mPchHEdpPins;
+    *NoOfNativePins = ARRAY_SIZE (mPchHEdpPins);
+  }
+}
+
+//
+// DDPB/C/D/F  CTRLCLK and CTRLDATA pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GPIO_DDP_NUMBER_OF_PINS] =
+{
+  {// DDPB
+    {GPIO_CNL_LP_GPP_E18, GpioPadModeNative1},// DDPB_CTRLCLK
+    {GPIO_CNL_LP_GPP_E19, GpioPadModeNative1} // DDPB_CTRLDATA
+  },
+  {// DDPC
+    {GPIO_CNL_LP_GPP_E20, GpioPadModeNative1},// DDPC_CTRLCLK
+    {GPIO_CNL_LP_GPP_E21, GpioPadModeNative1} // DDPC_CTRLDATA
+  },
+  {// DDPD
+    {GPIO_CNL_LP_GPP_E22, GpioPadModeNative1},// DDPD_CTRLCLK
+    {GPIO_CNL_LP_GPP_E23, GpioPadModeNative1} // DDPD_CTRLDATA
+  },
+  {// DDPF
+    {GPIO_CNL_LP_GPP_H16, GpioPadModeNative1},// DDPF_CTRLCLK
+    {GPIO_CNL_LP_GPP_H17, GpioPadModeNative1} // DDPF_CTRLDATA
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GPIO_DDP_NUMBER_OF_PINS] =
+{
+  {// DDPB
+    {GPIO_CNL_H_GPP_I5,  GpioPadModeNative1}, // DDPB_CTRLCLK
+    {GPIO_CNL_H_GPP_I6,  GpioPadModeNative1}, // DDPB_CTRLDATA
+  },
+  {// DDPC
+    {GPIO_CNL_H_GPP_I7,  GpioPadModeNative1}, // DDPC_CTRLCLK
+    {GPIO_CNL_H_GPP_I8,  GpioPadModeNative1}, // DDPC_CTRLDATA
+  },
+  {// DDPD
+    {GPIO_CNL_H_GPP_I9,  GpioPadModeNative1}, // DDPD_CTRLCLK
+    {GPIO_CNL_H_GPP_I10, GpioPadModeNative1}, // DDPD_CTRLDATA
+  },
+  {// DDPF
+    {GPIO_CNL_H_GPP_F22, GpioPadModeNative1}, // DDPF_CTRLCLK
+    {GPIO_CNL_H_GPP_F23, GpioPadModeNative1}, // DDPF_CTRLDATA
+  }
+};
+
+/**
+  This function provides DDPx interface pins
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetDdpPins (
+  IN  GPIO_DDP                    DdpInterface,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  UINT32  DdpInterfaceIndex;
+
+  switch (DdpInterface) {
+    case GpioDdpB:
+    case GpioDdpC:
+    case GpioDdpD:
+      DdpInterfaceIndex = DdpInterface - GpioDdpB;
+      break;
+    case GpioDdpF:
+      DdpInterfaceIndex = 3;
+      break;
+    default:
+      goto Error;
+  }
+
+  if (IsPchLp ()) {
+    if (DdpInterfaceIndex < ARRAY_SIZE (mPchLpDdpInterfacePins)) {
+      *NativePinsTable = mPchLpDdpInterfacePins[DdpInterfaceIndex];
+      return;
+    }
+  } else {
+    if (DdpInterfaceIndex < ARRAY_SIZE (mPchHDdpInterfacePins)) {
+      *NativePinsTable = mPchHDdpInterfacePins[DdpInterfaceIndex];
+      return;
+    }
+  }
+Error:
+  *NativePinsTable = NULL;
+  ASSERT(FALSE);
+}
+
+/**
+  This function enables CNVi RF Reset pin
+**/
+VOID
+GpioEnableCnviRfResetPin (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  GPIO_PAD        GpioPad;
+  GPIO_PAD_MODE   PadMode;
+
+  if (IsPchLp ()) {
+    GpioPad = GPIO_CNL_LP_GPP_H1;
+    PadMode = GpioPadModeNative3;
+  } else {
+    GpioPad = GPIO_CNL_H_GPP_D5;
+    PadMode = GpioPadModeNative3;
+  }
+
+  Status = GpioSetPadMode (GpioPad, PadMode);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function enables CNVi MODEM CLKREQ pin
+**/
+VOID
+GpioEnableCnviModemClkReqPin (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  GPIO_PAD        GpioPad;
+  GPIO_PAD_MODE   PadMode;
+
+  if (IsPchLp ()) {
+    GpioPad = GPIO_CNL_LP_GPP_H2;
+    PadMode = GpioPadModeNative3;
+  } else {
+    GpioPad = GPIO_CNL_H_GPP_D6;
+    PadMode = GpioPadModeNative3;
+  }
+
+  Status = GpioSetPadMode (GpioPad, PadMode);
+  ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+  This function provides CNVi BT interface select pin
+
+  @retval GpioPad          GPIO pad for CNVi BT interface select
+**/
+GPIO_PAD
+GpioGetCnviBtIfSelectPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO5;
+  } else {
+    return GPIO_CNL_H_VGPIO7;
+  }
+}
+
+/**
+  This function provides CNVi BT Charging pin
+
+  @retval GpioPad          GPIO pad for CNVi BT Charging select
+**/
+GPIO_PAD
+GpioGetCnviBtChargingPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO3;
+  } else {
+    return GPIO_CNL_H_VGPIO3;
+  }
+}
+
+/**
+  This function provides CNVi A4WP pin
+
+  @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
+**/
+VOID
+GpioGetCnviA4WpPin (
+  OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
+  )
+{
+  GpioNativePad->Mode = GpioPadModeNative1;
+  if (IsPchLp ()) {
+    GpioNativePad->Pad = GPIO_CNL_LP_GPP_F23;
+  } else {
+    GpioNativePad->Pad = GPIO_CNL_H_GPP_J11;
+  }
+}
+
+/**
+  This function provides CNVi BT host wake int pin
+
+  @retval GpioPad          GPIO pad BT host wake int
+**/
+GPIO_PAD
+GpioGetCnviBtHostWakeIntPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO4;
+  } else {
+    return GPIO_CNL_H_VGPIO4;
+  }
+}
+
+//
+// CNVi Bluetooth UART pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO6, // vCNV_BT_UART_TXD
+  GPIO_CNL_LP_VGPIO7, // vCNV_BT_UART_RXD
+  GPIO_CNL_LP_VGPIO8, // vCNV_BT_UART_CTS_B
+  GPIO_CNL_LP_VGPIO9  // vCNV_BT_UART_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO8, // vCNV_BT_UART_TXD
+  GPIO_CNL_H_VGPIO9, // vCNV_BT_UART_RXD
+  GPIO_CNL_H_VGPIO10,// vCNV_BT_UART_CTS_B
+  GPIO_CNL_H_VGPIO11 // vCNV_BT_UART_RTS_B
+};
+
+//
+// vUART for Bluetooth
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO18, // vUART0_TXD
+  GPIO_CNL_LP_VGPIO19, // vUART0_RXD
+  GPIO_CNL_LP_VGPIO20, // vUART0_CTS_B
+  GPIO_CNL_LP_VGPIO21  // vUART0_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO20, // vUART0_TXD
+  GPIO_CNL_H_VGPIO21, // vUART0_RXD
+  GPIO_CNL_H_VGPIO22, // vUART0_CTS_B
+  GPIO_CNL_H_VGPIO23  // vUART0_RTS_B
+};
+
+/**
+  This function provides CNVi BT UART pins
+
+  @param[in]  ConnectionType           CNVi BT UART connection type
+  @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
+  @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
+  @param[out] VUartForCnviBtPad        Table with vUART0 pads
+  @param[out] VUartForCnviBtPadMode    vUART0 pad mode
+**/
+VOID
+GpioGetCnviBtUartPins (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                            **VCnviBtUartPad,
+  OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
+  OUT GPIO_PAD                            **VUartForCnviBtPad,
+  OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
+  )
+{
+  if (IsPchLp ()) {
+    *VCnviBtUartPad = mPchLpVCnviBtUartGpioPad;
+    *VUartForCnviBtPad = mPchLpVUartForCnviBtGpioPad;
+  } else {
+    *VCnviBtUartPad = mPchHVCnviBtUartGpioPad;
+    *VUartForCnviBtPad = mPchHVUartForCnviBtGpioPad;
+  }
+
+  switch (ConnectionType) {
+    case GpioCnviBtUartToSerialIoUart0:
+      *VCnviBtUartPadMode = GpioPadModeNative1;
+      *VUartForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtUartToIshUart0:
+      *VCnviBtUartPadMode = GpioPadModeNative2;
+      *VUartForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtUartNotConnected:
+    case GpioCnviBtUartToExternalPads:
+      *VCnviBtUartPadMode = GpioPadModeGpio;
+      *VUartForCnviBtPadMode = GpioPadModeGpio;
+      break;
+    default:
+      ASSERT (FALSE);
+      return;
+  }
+}
+
+//
+// CNVi Bluetooth UART external pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
+  {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
+  {GPIO_CNL_LP_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
+  {GPIO_CNL_LP_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
+  {GPIO_CNL_H_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
+  {GPIO_CNL_H_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
+  {GPIO_CNL_H_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
+};
+
+/**
+  This function provides CNVi BT UART external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtUartExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviBtUartExternalPads;
+  } else {
+    *NativePinsTable = mPchHCnviBtUartExternalPads;
+  }
+}
+
+//
+// CNVi Bluetooth I2S pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO30, // vCNV_BT_I2S_BCLK
+  GPIO_CNL_LP_VGPIO31, // vCNV_BT_I2S_WS_SYNC
+  GPIO_CNL_LP_VGPIO32, // vCNV_BT_I2S_SDO
+  GPIO_CNL_LP_VGPIO33  // vCNV_BT_I2S_SDI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO32, // vCNV_BT_I2S_BCLK
+  GPIO_CNL_H_VGPIO33, // vCNV_BT_I2S_WS_SYNC
+  GPIO_CNL_H_VGPIO34, // vCNV_BT_I2S_SDO
+  GPIO_CNL_H_VGPIO35  // vCNV_BT_I2S_SDI
+};
+
+//
+// vSSP for Bluetooth
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO34, // vSSP2_SCLK
+  GPIO_CNL_LP_VGPIO35, // vSSP2_SFRM
+  GPIO_CNL_LP_VGPIO36, // vSSP2_TXD
+  GPIO_CNL_LP_VGPIO37  // vSSP2_RXD
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO36, // vSSP2_SCLK
+  GPIO_CNL_H_VGPIO37, // vSSP2_SFRM
+  GPIO_CNL_H_VGPIO38, // vSSP2_TXD
+  GPIO_CNL_H_VGPIO39  // vSSP2_RXD
+};
+
+/**
+  This function provides CNVi BT I2S pins
+
+  @param[in]  ConnectionType          CNVi BT I2S connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
+  @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
+  @param[out] VSspForCnviBtPad        Table with vSSP2 pads
+  @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
+**/
+VOID
+GpioGetCnviBtI2sPins (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviBtI2sPad,
+  OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
+  OUT GPIO_PAD                 **VSspForCnviBtPad,
+  OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
+  )
+{
+  if (IsPchLp ()) {
+    *VCnviBtI2sPad = mPchLpVCnviBtI2sGpioPad;
+    *VSspForCnviBtPad = mPchLpVSspForCnviBtGpioPad;
+  } else {
+    *VCnviBtI2sPad = mPchHVCnviBtI2sGpioPad;
+    *VSspForCnviBtPad = mPchHVSspForCnviBtGpioPad;
+  }
+
+  switch (ConnectionType) {
+    case GpioCnviBtI2sToSsp0:
+      *VCnviBtI2sPadMode = GpioPadModeNative1;
+      *VSspForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtI2sToSsp1:
+      *VCnviBtI2sPadMode = GpioPadModeNative2;
+      *VSspForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtI2sToSsp2:
+      *VCnviBtI2sPadMode = GpioPadModeNative3;
+      *VSspForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtI2sNotConnected:
+    case GpioCnviBtI2sToExternalPads:
+      *VCnviBtI2sPadMode = GpioPadModeGpio;
+      *VSspForCnviBtPadMode = GpioPadModeGpio;
+      break;
+    default:
+      ASSERT (FALSE);
+      return;
+  }
+}
+
+//
+// CNVi Bluetooth I2S external pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_H0, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
+  {GPIO_CNL_LP_GPP_H1, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
+  {GPIO_CNL_LP_GPP_H2, GpioPadModeNative2}, // CNV_BT_I2S_SDI
+  {GPIO_CNL_LP_GPP_H3, GpioPadModeNative2}  // CNV_BT_I2S_SDO
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_D8, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
+  {GPIO_CNL_H_GPP_D5, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
+  {GPIO_CNL_H_GPP_D6, GpioPadModeNative2}, // CNV_BT_I2S_SDI
+  {GPIO_CNL_H_GPP_D7, GpioPadModeNative2}  // CNV_BT_I2S_SDO
+};
+
+/**
+  This function provides CNVi BT I2S external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtI2sExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviBtI2sExternalPads;
+  } else {
+    *NativePinsTable = mPchHCnviBtI2sExternalPads;
+  }
+}
+
+//
+// CNVi MFUART1 pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO10, // vCNV_MFUART1_TXD
+  GPIO_CNL_LP_VGPIO11, // vCNV_MFUART1_RXD
+  GPIO_CNL_LP_VGPIO12, // vCNV_MFUART1_CTS_B
+  GPIO_CNL_LP_VGPIO13  // vCNV_MFUART1_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO12, // vCNV_MFUART1_TXD
+  GPIO_CNL_H_VGPIO13, // vCNV_MFUART1_RXD
+  GPIO_CNL_H_VGPIO14, // vCNV_MFUART1_CTS_B
+  GPIO_CNL_H_VGPIO15  // vCNV_MFUART1_RTS_B
+};
+
+//
+// vUART for MFUART1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO22, // vISH_UART0_TXD
+  GPIO_CNL_LP_VGPIO23, // vISH_UART0_RXD
+  GPIO_CNL_LP_VGPIO24, // vISH_UART0_CTS_B
+  GPIO_CNL_LP_VGPIO25  // vISH_UART0_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO24, // vISH_UART0_TXD
+  GPIO_CNL_H_VGPIO25, // vISH_UART0_RXD
+  GPIO_CNL_H_VGPIO26, // vISH_UART0_CTS_B
+  GPIO_CNL_H_VGPIO27  // vISH_UART0_RTS_B
+};
+
+/**
+  This function provides CNVi MFUART1 pins
+
+  @param[in]  ConnectionType          CNVi MFUART1 connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
+  @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
+  @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
+  @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
+**/
+VOID
+GpioGetCnviMfUart1Pins (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
+  OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
+  )
+{
+  if (IsPchLp ()) {
+    *VCnviMfUart1Pad = mPchLpVCnviMfUart1GpioPad;
+    *VUartForCnviMfUart1Pad = mPchLpVUartForCnviMfUart1GpioPad;
+  } else {
+    *VCnviMfUart1Pad = mPchHVCnviMfUart1GpioPad;
+    *VUartForCnviMfUart1Pad = mPchHVUartForCnviMfUart1GpioPad;
+  }
+
+  switch (ConnectionType) {
+    case GpioCnviMfUart1ToSerialIoUart2:
+      *VCnviMfUart1PadMode = GpioPadModeNative2;
+      *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviMfUart1ToIshUart0:
+      *VCnviMfUart1PadMode = GpioPadModeNative1;
+      *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviMfUart1NotConnected:
+    case GpioCnviMfUart1ToExternalPads:
+      *VCnviMfUart1PadMode = GpioPadModeGpio;
+      *VUartForCnviMfUart1PadMode = GpioPadModeGpio;
+      break;
+    default:
+      ASSERT (FALSE);
+      return;
+  }
+}
+
+//
+// CNVi MFUART1 external pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
+  {GPIO_CNL_LP_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
+  {GPIO_CNL_LP_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
+  {GPIO_CNL_LP_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
+  {GPIO_CNL_H_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
+  {GPIO_CNL_H_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
+  {GPIO_CNL_H_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
+};
+
+/**
+  This function provides CNVi MFUART1 external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviMfUart1ExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviMfUart1ExternalPads;
+  } else {
+    *NativePinsTable = mPchHCnviMfUart1ExternalPads;
+  }
+}
+
+/**
+  This function provides CNVi Bluetooth Enable pad
+
+  @retval GpioPad           CNVi Bluetooth Enable pad
+**/
+GPIO_PAD
+GpioGetCnviBtEnablePin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO0;
+  } else {
+    return GPIO_CNL_H_VGPIO0;
+  }
+}
+
+//
+// CNVi BRI (Bluetooth Radio Interface) and RGI (Radio Generic Interface) buses from Pulsar to CRF (Companion RF)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_F4, GpioPadModeNative1}, // CNV_BRI_DT
+  {GPIO_CNL_LP_GPP_F5, GpioPadModeNative1}, // CNV_BRI_RSP
+  {GPIO_CNL_LP_GPP_F6, GpioPadModeNative1}, // CNV_RGI_DT
+  {GPIO_CNL_LP_GPP_F7, GpioPadModeNative1}  // CNV_RGI_RSP
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_J4, GpioPadModeNative1}, // CNV_BRI_DT
+  {GPIO_CNL_H_GPP_J5, GpioPadModeNative1}, // CNV_BRI_RSP
+  {GPIO_CNL_H_GPP_J6, GpioPadModeNative1}, // CNV_RGI_DT
+  {GPIO_CNL_H_GPP_J7, GpioPadModeNative1}  // CNV_RGI_RSP
+};
+
+/**
+  This function provides CNVi BRI RGI GPIO pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnvBriRgiPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviBriRgiGpioPad;
+  } else {
+    *NativePinsTable = mPchHCnviBriRgiGpioPad;
+  }
+}
+
+
+/**
+  This function sets CNVi WiFi mode
+
+  @param[in] Value                CNVi WiFi Mode value
+                                  GpioCnviWiFiAuto: WiFi is automatically enabled/disabled by WiFi core
+                                  GpioCnviWiFiEnabled: WiFi is enabled regardless of WiFi core decision
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviWifiMode (
+  IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_PAD    CnviWifiModePad;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode = GpioPadModeGpio;
+  PadConfig.Direction = GpioDirOut;
+  if (WiFiMode == GpioCnviWiFiEnabled) {
+    PadConfig.OutputState = GpioOutHigh;
+  } else {
+    PadConfig.OutputState = GpioOutLow;
+  }
+
+  if (IsPchLp ()) {
+    CnviWifiModePad = GPIO_CNL_LP_VGPIO2;
+  } else {
+    CnviWifiModePad = GPIO_CNL_H_VGPIO2;
+  }
+
+  Status = GpioSetPadConfig (CnviWifiModePad, &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_D4,  GpioPadModeNative1}, // IMGCLKOUT_0
+  {GPIO_CNL_LP_GPP_H20, GpioPadModeNative1}, // IMGCLKOUT_1
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_K22, GpioPadModeNative1}, // IMGCLKOUT_0
+  {GPIO_CNL_H_GPP_K23, GpioPadModeNative1}, // IMGCLKOUT_1
+};
+
+/**
+  This function provides IMGCLKOUT pins
+
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins            Number of pins
+**/
+VOID
+GpioGetImgClkOutPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
+  OUT UINT32                   *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpImguClkOutGpioPad;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpImguClkOutGpioPad);
+  } else {
+    *NativePinsTable = mPchHImguClkOutGpioPad;
+    *NoOfNativePins = ARRAY_SIZE (mPchHImguClkOutGpioPad);
+  }
+}
+
+/**
+  This function provides PWRBTN pin
+
+  @retval GpioPad          PWRTBTN pin
+**/
+GPIO_PAD
+GpioGetPwrBtnPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_GPD3;
+  } else {
+    return GPIO_CNL_H_GPD3;
+  }
+}
+
+/**
+  This function provides LPC pin
+
+  @retval GpioPad          LPC pin
+**/
+GPIO_PAD
+GpioGetLpcPin (
+  VOID
+  )
+{
+  if (PchGetLpcDid () == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU) {
+    return GPIO_CNL_H_GPP_A8;
+  } else {
+    return 0;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
new file mode 100644
index 0000000000..2cf11c6da2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
@@ -0,0 +1,752 @@
+/** @file
+  This file contains GPIO routines for RC usage
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h>
+#include <Private/Library/GpioNameBufferLib.h>
+#include <Register/PchRegsPcr.h>
+
+#include "GpioNativePrivateLibInternal.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 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
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  //
+  // Check if group argument exceeds GPIO GROUP INFO array
+  //
+  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *RegVal = MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, Offset));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  //
+  // Check if group argument exceeds GPIO GROUP INFO array
+  //
+  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MmioWrite32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, Offset), RegVal);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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 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
+  )
+{
+  UINT32       Data32And;
+  UINT32       Data32Or;
+  PCH_SBI_PID  *GpioComSbiIds;
+  UINT32       NoOfGpioComs;
+  UINT32       GpioComIndex;
+
+  Data32And = (UINT32)~(B_GPIO_PCR_MISCCFG_IRQ_ROUTE);
+  Data32Or  = (UINT32)Irq << N_GPIO_PCR_MISCCFG_IRQ_ROUTE;
+
+  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
+
+  //
+  // Program MISCCFG register for each community
+  //
+  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) {
+    MmioAndThenOr32 (
+      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], R_GPIO_PCR_MISCCFG),
+      Data32And,
+      Data32Or
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  return GpioGroupInfo[GroupIndex].Community;
+}
+
+/**
+  This procedure will return PadCfg address from GpioPad
+
+  @param[in] GpioPad            GpioPad
+
+  @retval GpioPadCfgAddress     PadCfg Address of GpioPad
+**/
+UINT32
+GpioGetGpioPadCfgAddressFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  )
+{
+  UINT32                 PadCfgRegAddress;
+  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
+  //
+  PadCfgRegAddress = GpioGroupInfo[GroupIndex].PadCfgOffset + S_GPIO_PCR_PADCFG * PadNumber;
+
+  return PadCfgRegAddress;
+}
+
+
+/**
+  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;
+
+  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
+  //
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  if (PadNumber >= GpioGroupInfo[GpioGetGroupIndexFromGpioPad (GpioPad)].PadPerGroup) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for this group\n", PadNumber));
+    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[out] 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;
+
+  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;
+}
+
+/**
+  The function performs GPIO Power Management programming.
+**/
+VOID
+GpioConfigurePm (
+  VOID
+  )
+{
+  UINT32       Data32Or;
+  UINT32       Data32And;
+  PCH_SBI_PID  *GpioComSbiIds;
+  UINT32       NoOfGpioComs;
+  UINT32       GpioComIndex;
+
+  Data32And = (UINT32)~0,
+  //
+  // Enable MISCCFG.GPSIDEDPCGEn, MISCCFG.GPRCOMPCDLCGEn, MISCCFG.GPRTCDLCGEn,
+  // MISCCFG.GPDLCGEn and MISCCFG.GPDPCGEn for GPIO communities
+  //
+  Data32Or = (B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN |
+              B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN |
+              B_GPIO_PCR_MISCCFG_GPRTCDLCGEN |
+              B_GPIO_PCR_MISCCFG_GPDLCGEN |
+              B_GPIO_PCR_MISCCFG_GPDPCGEN);
+
+  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
+
+  //
+  // Configure Clock Gating in each community
+  //
+  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) {
+    MmioAndThenOr32 (
+      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], R_GPIO_PCR_MISCCFG),
+      Data32And,
+      Data32Or
+      );
+  }
+}
+
+/**
+  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
+  )
+{
+  UINT32         DwNum;
+  UINT32         GroupIndex;
+  UINT32         NumberOfGroups;
+  GPIO_GROUP     Group;
+  UINT32         LockValue;
+  EFI_STATUS     Status;
+
+  NumberOfGroups = GpioGetNumberOfGroups ();
+
+  for (GroupIndex = 0; GroupIndex < NumberOfGroups; GroupIndex++) {
+    Group = GpioGetGroupFromGroupIndex (GroupIndex);
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
+
+      GpioGetPadCfgLockForGroupDw (Group, DwNum, &LockValue);
+
+      if (LockValue) {
+        Status = GpioUnlockPadCfgForGroupDw (Group, DwNum, ~0u);
+        ASSERT_EFI_ERROR (Status);
+      }
+
+      GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &LockValue);
+
+      if (LockValue) {
+        Status = GpioUnlockPadCfgTxForGroupDw (Group, DwNum, ~0u);
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+}
+
+/**
+  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);
+}
+
+
+//
+// For GPIO debounce feature glitch filter clock is used
+// which is driven by RTC clock with f = 32kHz (T = 31.25us)
+//
+#define GPIO_DEB_CLK_PERIOD_IN_NS  31250
+
+/**
+  This procedure enables debounce feature on a selected pad configured in input mode
+  Debounce time can be specified in microseconds. GPIO HW supports only certain values
+  according to below formula:
+   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 GPIO HW, function will round down
+  to closest supported
+
+  @param[in] GpioPad              GPIO pad
+  @param[in, out] DebounceTime    Debounce Time in microseconds
+                                  If Debounce Time = 0, Debouncer feature will be disabled
+                                  Function will set DebounceTime argument to rounded supported value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad or unsupported DebounceDuration value
+  @retval EFI_UNSUPPORTED         GpioPad is not owned by host
+**/
+EFI_STATUS
+GpioSetDebounceTimer (
+  IN GPIO_PAD                  GpioPad,
+  IN OUT UINT32                *DebounceTime
+  )
+{
+  UINT32   DebounceEnable;
+  UINT32   DebounceValue;
+  UINT32   InRangeDebounceTime;
+  UINT32   SupportedDebounceTime;
+  UINT32   Temp;
+  BOOLEAN  SupportedValue;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (*DebounceTime > 1024000) {
+    InRangeDebounceTime = 1024000;
+    SupportedValue = FALSE;
+  } else if ((*DebounceTime < 250) && (*DebounceTime > 0)) {
+    InRangeDebounceTime = 0;
+    SupportedValue = FALSE;
+  } else {
+    InRangeDebounceTime = *DebounceTime;
+    SupportedValue = TRUE;
+  }
+
+  //
+  // DebounceValue = log2 (InRangeDebounceTime * f_deb_clk)
+  //
+  DebounceValue = 0;
+  Temp = InRangeDebounceTime * 1000 / GPIO_DEB_CLK_PERIOD_IN_NS;
+
+  //
+  // Check if any rounding occurred
+  //
+  if (InRangeDebounceTime != (Temp * GPIO_DEB_CLK_PERIOD_IN_NS / 1000)) {
+    SupportedValue = FALSE;
+  }
+
+  //
+  // Check if value is power of 2
+  //
+  if ((Temp != 0) && ((Temp & (Temp - 1)) != 0)) {
+    SupportedValue = FALSE;
+  }
+
+  //
+  // DebounceValue = log2 (Temp)
+  //
+  while (Temp > 1) {
+    Temp >>= 1;
+    DebounceValue++;
+  }
+
+  if (DebounceValue > 0) {
+    DebounceEnable = B_GPIO_PCR_DEBEN;
+    SupportedDebounceTime = (1 << DebounceValue) * GPIO_DEB_CLK_PERIOD_IN_NS / 1000;
+  } else {
+    DebounceEnable = 0;
+    SupportedDebounceTime = 0;
+  }
+
+  GpioWritePadCfgReg (
+    GpioPad,
+    2,
+    (UINT32)~(B_GPIO_PCR_DEBOUNCE | B_GPIO_PCR_DEBEN),
+    (DebounceValue << N_GPIO_PCR_DEBOUNCE) | DebounceEnable
+    );
+
+  if (!SupportedValue) {
+    DEBUG ((DEBUG_WARN, "GPIO WARNING: %a %dus debounce time rounded down to %dus\n",
+            GpioName (GpioPad),
+            *DebounceTime,
+            SupportedDebounceTime));
+  }
+
+  *DebounceTime = SupportedDebounceTime;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c
new file mode 100644
index 0000000000..a6d260f4ad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c
@@ -0,0 +1,225 @@
+/** @file
+  This file contains specific GPIO information
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <Register/PchRegsGpioCnl.h>
+#include <Register/PchRegsPmcCnl.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <GpioConfig.h>
+#include <Register/PchRegsPcr.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] = {
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS, R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_A_PAD_MAX}, //CNL PCH-LP GPP_A
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_B_PAD_MAX}, //CNL PCH-LP GPP_B
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_C_PAD_MAX}, //CNL PCH-LP GPP_C
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_D_PAD_MAX}, //CNL PCH-LP GPP_D
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_E_PAD_MAX}, //CNL PCH-LP GPP_E
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS, R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_F_PAD_MAX}, //CNL PCH-LP GPP_F
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_G_PAD_MAX}, //CNL PCH-LP GPP_G
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS, R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_H_PAD_MAX}, //CNL PCH-LP GPP_H
+  {PID_GPIOCOM2, R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN,   R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS,   R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE,   R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS,   R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_GPD_PAD_MAX},   //CNL PCH-LP GPD
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK, R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX, R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET, CNL_PCH_LP_GPIO_VGPIO_PAD_MAX}, //CNL PCH-LP vGPIO
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_SPI_PAD_MAX},   //CNL PCH-LP SPI
+  {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_AZA_PAD_MAX},   //CNL PCH-LP AZA
+  {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN,   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,           R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_CPU_PAD_MAX},   //CNL PCH-LP CPU
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN,  R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN,  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,           R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK,    R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX,    R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET,  CNL_PCH_LP_GPIO_JTAG_PAD_MAX},  //CNL PCH-LP JTAG
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET, CNL_PCH_LP_GPIO_HVMOS_PAD_MAX}  //CNL PCH-LP HVMOS
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchHGpioGroupInfo[] = {
+  {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_A_PAD_MAX}, //CNL PCH-H GPP_A
+  {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_B_PAD_MAX}, //CNL PCH-H GPP_B
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_C_PAD_MAX}, //CNL PCH-H GPP_C
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_D_PAD_MAX}, //CNL PCH-H GPP_D
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_E_PAD_MAX}, //CNL PCH-H GPP_E
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_F_PAD_MAX}, //CNL PCH-H GPP_F
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_G_PAD_MAX}, //CNL PCH-H GPP_G
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_H_PAD_MAX}, //CNL PCH-H GPP_H
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_I_PAD_MAX}, //CNL PCH-H GPP_I
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_J_PAD_MAX}, //CNL PCH-H GPP_J
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_K_PAD_MAX}, //CNL PCH-H GPP_K
+  {PID_GPIOCOM2, R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET,   CNL_PCH_H_GPIO_GPD_PAD_MAX},   //CNL PCH-H GPD
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK, R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX, R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET, CNL_PCH_H_GPIO_VGPIO_PAD_MAX}, //CNL PCH-H vGPIO
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN,   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,          R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET,   CNL_PCH_H_GPIO_SPI_PAD_MAX},   //CNL PCH-H SPI
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN,   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,          R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET,   CNL_PCH_H_GPIO_AZA_PAD_MAX},   //CNL PCH-H AZA
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN,   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,          R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET,   CNL_PCH_H_GPIO_CPU_PAD_MAX},   //CNL PCH-H CPU
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN,  R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN,  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,          R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK,    R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX,    R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET,  CNL_PCH_H_GPIO_JTAG_PAD_MAX}   //CNL PCH-H JTAG
+};
+
+/**
+  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
+  )
+{
+  if (IsPchLp ()) {
+    *GpioGroupInfoTableLength = ARRAY_SIZE (mPchLpGpioGroupInfo);
+    return mPchLpGpioGroupInfo;
+  } else {
+    *GpioGroupInfoTableLength = ARRAY_SIZE (mPchHGpioGroupInfo);
+    return mPchHGpioGroupInfo;
+  }
+}
+
+/**
+  Get GPIO Chipset ID specific to PCH generation and series
+**/
+UINT32
+GpioGetThisChipsetId (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_CHIPSET_ID;
+  } else {
+    return GPIO_CNL_H_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_CNL_LP_GROUP_GPD) || (Group == GPIO_CNL_H_GROUP_GPD)) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  This procedure will perform special handling of GPP_A_12.
+
+  @param[in]  None
+
+  @retval None
+**/
+VOID
+GpioA12SpecialHandling (
+  VOID
+  )
+{
+  GPIO_PAD_OWN         PadOwnVal;
+  GPIO_PAD             GpioPad;
+
+  //
+  // PCH BWG 16.6. GPP_A_12 Special Handling
+  //
+  if (IsPchLp ()) {
+    GpioPad = GPIO_CNL_LP_GPP_A12;
+  } else {
+    GpioPad = GPIO_CNL_H_GPP_A12;
+  }
+  GpioGetPadOwnership (GpioPad, &PadOwnVal);
+
+  //
+  // If the pad is host-own, BIOS has to always lock this pad after being initialized
+  //
+  if (PadOwnVal == GpioPadOwnHost) {
+    //
+    // Set PadCfgLock for GPP_A_12
+    //
+    GpioLockPadCfg (GpioPad);
+  }
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SBI_PID mGpioComSbiIds[] =
+{
+  PID_GPIOCOM0, PID_GPIOCOM1, PID_GPIOCOM2, PID_GPIOCOM3, PID_GPIOCOM4
+};
+
+/**
+  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
+  )
+{
+  *GpioComSbiIds = mGpioComSbiIds;
+  return ARRAY_SIZE (mGpioComSbiIds);
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING mPchLpGpioGroupToGpeMapping[] = {
+  {GPIO_CNL_LP_GROUP_GPP_A,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A},
+  {GPIO_CNL_LP_GROUP_GPP_B,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B},
+  {GPIO_CNL_LP_GROUP_GPP_C,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C},
+  {GPIO_CNL_LP_GROUP_GPP_D,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D},
+  {GPIO_CNL_LP_GROUP_GPP_E,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E},
+  {GPIO_CNL_LP_GROUP_GPP_F,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F},
+  {GPIO_CNL_LP_GROUP_GPP_G,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G},
+  {GPIO_CNL_LP_GROUP_GPP_H,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H},
+  {GPIO_CNL_LP_GROUP_GPD,    0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD,   V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD},
+  {GPIO_CNL_LP_GROUP_VGPIO , 0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO},
+  {GPIO_CNL_LP_GROUP_SPI,    0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI,   V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI},
+  {GPIO_CNL_LP_GROUP_AZA,    0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA,   V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA},
+  {GPIO_CNL_LP_GROUP_JTAG,   0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG,  V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING mPchHGpioGroupToGpeMapping[] = {
+  {GPIO_CNL_H_GROUP_GPP_A,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A},
+  {GPIO_CNL_H_GROUP_GPP_B,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B},
+  {GPIO_CNL_H_GROUP_GPP_C,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C},
+  {GPIO_CNL_H_GROUP_GPP_D,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D},
+  {GPIO_CNL_H_GROUP_GPP_E,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E},
+  {GPIO_CNL_H_GROUP_GPP_F,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F},
+  {GPIO_CNL_H_GROUP_GPP_G,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G},
+  {GPIO_CNL_H_GROUP_GPP_H,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H},
+  {GPIO_CNL_H_GROUP_GPP_I,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I},
+  {GPIO_CNL_H_GROUP_GPP_J,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J},
+  {GPIO_CNL_H_GROUP_GPP_K,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K},
+  {GPIO_CNL_H_GROUP_GPD,    0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD,   V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD},
+  {GPIO_CNL_H_GROUP_VGPIO,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO}
+};
+
+/**
+  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
+  )
+{
+  if (IsPchLp ()) {
+    *GpioGroupToGpeMapping = mPchLpGpioGroupToGpeMapping;
+    *GpioGroupToGpeMappingLength = ARRAY_SIZE (mPchLpGpioGroupToGpeMapping);
+  } else {
+    *GpioGroupToGpeMapping = mPchHGpioGroupToGpeMapping;
+    *GpioGroupToGpeMappingLength = ARRAY_SIZE (mPchHGpioGroupToGpeMapping);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c
new file mode 100644
index 0000000000..2f9b6a7e6f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c
@@ -0,0 +1,67 @@
+/** @file
+  This file contains functions for PCH DMI SIP14
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsDmi.h>
+#include <Register/PchRegsDmi14.h>
+#include <Register/PchRegsPcr.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);
+}
+
+/**
+  Enable PCIe Relaxed Order for DMI SIP14
+**/
+VOID
+PchDmi14EnablePcieRelaxedOrder (
+  VOID
+  )
+{
+  //
+  // Enable Forced Relaxed Ordering to always allow downstream completions to pass posted writes.
+  // Set Completion Relaxed Ordering Attribute Override Value
+  // and Completion Relaxed Ordering Attribute Override Enable
+  //
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI14_PCR_2314, ~0u, (BIT31 | BIT7));
+}
+
+/**
+ 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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c
new file mode 100644
index 0000000000..c711b3de39
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c
@@ -0,0 +1,113 @@
+/** @file
+  This file contains functions for PCH DMI SIP15
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsDmi.h>
+#include <Register/PchRegsDmi15.h>
+#include <Register/PchRegsPcr.h>
+
+/**
+  This function checks if DMI SIP15 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi15Locked (
+  VOID
+  )
+{
+  return ((PchPcrRead32 (PID_DMI, R_PCH_DMI15_PCR_MPC) & B_PCH_DMI15_PCR_MPC_SRL) != 0);
+}
+
+/**
+  Set DMI thermal throttling to recommended configuration.
+  It's intended only for P-DMI SIP15.
+**/
+VOID
+PchDmi15SetRecommendedThermalThrottling (
+  VOID
+  )
+{
+  UINT32  Data32And;
+  UINT32  Data32Or;
+  ///
+  /// DMI recommended Thermal Sensor Target Width
+  /// is the HW default configuration:
+  ///  - Thermal Sensor 3 Target Width: 0 (x1)
+  ///  - Thermal Sensor 2 Target Width: 1 (x2)
+  ///  - Thermal Sensor 1 Target Width: 2 (x4)
+  ///  - Thermal Sensor 0 Target Width: 3 (x8)
+  /// Enable Thermal Sensor Autonomous Width
+  ///
+  Data32And = (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW | B_PCH_DMI15_PCR_UPHWAWC_TS2TW |
+                        B_PCH_DMI15_PCR_UPHWAWC_TS1TW | B_PCH_DMI15_PCR_UPHWAWC_TS0TW);
+  Data32Or  = (0 << N_PCH_DMI15_PCR_UPHWAWC_TS3TW) |
+              (1 << N_PCH_DMI15_PCR_UPHWAWC_TS2TW) |
+              (2 << N_PCH_DMI15_PCR_UPHWAWC_TS1TW) |
+              (3 << N_PCH_DMI15_PCR_UPHWAWC_TS0TW) |
+              B_PCH_DMI15_PCR_UPHWAWC_TSAWEN;
+
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC, Data32And, Data32Or);
+}
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+  It's intended only for P-DMI SIP15.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmi15SetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  )
+{
+  UINT32  Data32And;
+  UINT32  Data32Or;
+
+  ///
+  /// DMI Throttling action
+  ///
+  Data32And = (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW | B_PCH_DMI15_PCR_UPHWAWC_TS2TW |
+                        B_PCH_DMI15_PCR_UPHWAWC_TS1TW | B_PCH_DMI15_PCR_UPHWAWC_TS0TW);
+  Data32Or  = (DmiThermalThrottling.ThermalSensor3TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS3TW) |
+              (DmiThermalThrottling.ThermalSensor2TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS2TW) |
+              (DmiThermalThrottling.ThermalSensor1TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS1TW) |
+              (DmiThermalThrottling.ThermalSensor0TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS0TW) |
+              B_PCH_DMI15_PCR_UPHWAWC_TSAWEN;
+
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC, Data32And, Data32Or);
+}
+
+
+/**
+ Secure Register Lock data
+
+ @param[out] SrlRegOffset        Register offset holding Secure Register Lock setting
+ @param[out] SrlRegMask          Mask for Secure Register Lock setting
+**/
+VOID
+PchDmi15SrlRegData (
+  OUT UINT16  *SrlRegOffset,
+  OUT UINT32  *SrlRegMask
+  )
+{
+  *SrlRegMask = B_PCH_DMI15_PCR_MPC_SRL;
+  *SrlRegOffset = R_PCH_DMI15_PCR_MPC;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c
new file mode 100644
index 0000000000..f1b2867659
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c
@@ -0,0 +1,569 @@
+/** @file
+  PCH DMI library.
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsDmi.h>
+
+#include "PchDmi14.h"
+#include "PchDmi15.h"
+
+/**
+  This function checks if DMI Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmiLocked (
+  VOID
+  )
+{
+  if (IsPchWithPdmi ()) {
+    return IsPchDmi15Locked ();
+  } else {
+    return IsPchDmi14Locked ();
+  }
+}
+
+/**
+  Backward DMI library API compatibility
+  ACPI base address programming is done in PSF
+
+  @param[in] Address                    Address for ACPI base.
+
+  @retval EFI_UNSUPPORTED               NOT supported programming.
+**/
+EFI_STATUS
+PchDmiSetAcpiBase (
+  IN  UINT16                            Address
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Backward DMI library API compatibility
+  PWRMBASE is a standard BAR and doesn't require
+  additional DMI base decoding programming
+
+  @param[in] Address                    Address for PWRM base.
+
+  @retval EFI_UNSUPPORTED               NOT supported programming.
+**/
+EFI_STATUS
+PchDmiSetPwrmBase (
+  IN  UINT32                            Address
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Set PCH TCO base address decoding in DMI
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetTcoBase (
+  IN  UINT16                            Address
+  )
+{
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [SMBUS PCI offset 50h[15:5], 1].
+  //
+  PchPcrWrite16 (
+    PID_DMI, R_PCH_DMI_PCR_TCOBASE,
+    (Address | BIT1)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  UINT32                                Data32;
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
+  Data32 |= (UINT32) Address;
+  Data32 |= B_LPC_CFG_GENX_DEC_EN;
+  //
+  // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the same value programmed in LPC/eSPI PCI Offset 84h~93h.
+  //
+  PchPcrWrite32 (
+    PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4),
+    Data32
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  UINT32                                Data32;
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
+  Data32 |= (UINT32) Address;
+  Data32 |= B_LPC_CFG_GENX_DEC_EN;
+  //
+  // Program eSPI Generic IO Range #, PCR[DMI] + 27BCh to the same value programmed in eSPI PCI Offset A4h.
+  //
+  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, Data32);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear PCH LPC/eSPI generic IO range decoding in DMI
+
+  @param[in] RangeIndex                 Index of chosen range
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearLpcGenIoRange (
+  IN  UINTN                             RangeIndex
+  )
+{
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the same value programmed in LPC/eSPI PCI Offset 84h~93h.
+  //
+  PchPcrWrite32 (
+    PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4),
+    0
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear PCH eSPI CS1# generic IO range decoding in DMI
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearEspiCs1GenIoRange (
+  VOID
+  )
+{
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Program LPC Generic IO Range #, PCR[DMI] + 27BCh to the same value programmed in eSPI PCI Offset A4h.
+  //
+  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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, "PchDmiSetLpcMemRange Error. DMI is locked.\n"));
+    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, "PchLpcMemRange2Set Error. DMI is locked.\n"));
+    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;
+}
+
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port in DMI
+
+  @param[in] RpNumber                   PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchDmiSetIoPort80Decode (
+  IN  UINTN                             RpNumber
+  )
+{
+  UINT16            DmiRpDestinationId;
+  PSF_PORT_DEST_ID  PsfRpDestinationId;
+
+  if (IsPchDmiLocked ()) {
+    DEBUG ((DEBUG_ERROR, "PchIoPort80DecodeSet Error. DMI is locked.\n"));
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  ///
+  /// IO port 80h is typically used by decoder/LED hardware for debug purposes.
+  /// By default PCH will forward IO port 80h cycles to LPC bus. The Reserved Page Route (RPR) bit
+  /// of General Control and Status register, located at PCR[DMI] + 274Ch[11] , allows software to
+  /// re-direct IO port 80h cycles to PCIe bus so that a target (for example, a debug card) on
+  /// PCIe bus can receive and claim these cycles.
+  /// The "RPR Destination ID", PCR[DMI] + 274Ch[31:16] need to be set accordingly to point
+  /// to the root port that decode this range. Reading from Port 80h may not return valid values
+  /// if the POST-card itself do not shadow the writes. Unlike LPC, PCIe does not shadow the Port 80 writes.
+  ///
+  PsfRpDestinationId = PsfPcieDestinationId ((UINT32)RpNumber);
+
+  DmiRpDestinationId = (UINT16)((0x2 << 12) |
+                                (PsfRpDestinationId.Fields.PsfId << 8) |
+                                (PsfRpDestinationId.Fields.PortGroupId << 7) |
+                                (PsfRpDestinationId.Fields.PortId << 3) |
+                                 PsfRpDestinationId.Fields.ChannelId);
+
+  //
+  // Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest ID of RP.
+  //
+  PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_GCS + 2, DmiRpDestinationId);
+  //
+  // Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'.
+  // Use byte write on GCS+1 and leave the BILD bit which is RWO.
+  //
+  PchPcrAndThenOr8 (PID_DMI, R_PCH_DMI_PCR_GCS + 1, 0xFF, (B_PCH_DMI_PCR_RPR >> 8));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set DMI thermal throttling to recommended configuration.
+  It's intended only for P-DMI.
+**/
+VOID
+PchDmiSetRecommendedThermalThrottling (
+  VOID
+  )
+{
+  if (IsPchWithPdmi ()) {
+    PchDmi15SetRecommendedThermalThrottling ();
+  }
+}
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+  It's intended only for P-DMI.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmiSetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  )
+{
+  if (IsPchWithPdmi ()) {
+    PchDmi15SetCustomThermalThrottling (DmiThermalThrottling);
+  }
+}
+
+/**
+  Determines where to send the reserved page registers
+  Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Port
+  with the destination ID specified in GCS.RPRDID using DMI source decode.
+**/
+VOID
+PchDmiSetReservedPageRegToPcieRootPort (
+  VOID
+  )
+{
+  PchPcrAndThenOr8 (
+    PID_DMI, R_PCH_DMI_PCR_GCS + 1,
+    (UINT8) ~0,
+    (UINT8) (B_PCH_DMI_PCR_RPR >> 8)
+    );
+}
+
+/**
+  Determines where to send the reserved page registers
+  DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cycles hitting these ranges will
+  end up in P2SB which will then forward the cycle to LPC or eSPI through IOSF Sideband.
+**/
+VOID
+PchDmiSetReservedPageRegToLpc (
+  VOID
+  )
+{
+  PchPcrAndThenOr8 (
+    PID_DMI, R_PCH_DMI_PCR_GCS + 1,
+    (UINT8) (~(B_PCH_DMI_PCR_RPR >> 8)),
+    0
+    );
+}
+
+/**
+  uCode Patch Region Enable (UPRE). Enables memory access targeting the uCode patch region (0xFEF00000 to 0xFEFFFFFF)
+  to be forwarded to SPI Flash. This can only be set if the boot flash is on SPI.
+**/
+VOID
+PchDmiEnableUCodePatchRegion (
+  VOID
+  )
+{
+  ///
+  /// Setup "uCode Patch Region Enable", PCR [DMI] + 2748h[0] to '0b'
+  ///
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI_PCR_UCPR, (UINT32) ~B_PCH_DMI_PCR_UCPR_UPRE, 0);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
new file mode 100644
index 0000000000..9778c9a252
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
@@ -0,0 +1,79 @@
+/** @file
+  PCH DMI library with S3 boot script support.
+
+  Copyright (c) 2019 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/PchRegsPcr.h>
+#include <Register/PchRegsDmi.h>
+
+#include "PchDmi14.h"
+#include "PchDmi15.h"
+
+/**
+  Configure PCH DMI Lock
+**/
+VOID
+PchDmiSetLockWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  Data32Or;
+  UINT32  Data32And;
+  UINT16  Address;
+
+  Data32And = 0xFFFFFFFF;
+  if (IsPchWithPdmi ()) {
+    PchDmi15SrlRegData (&Address, &Data32Or);
+  } else {
+    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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c
new file mode 100644
index 0000000000..14bd51ec43
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c
@@ -0,0 +1,221 @@
+/** @file
+  Pch common library for PCH INIT PEI/DXE/SMM modules
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PchPolicyCommon.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/PchRegsPcie.h>
+
+extern CONST PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[];
+extern CONST UINT32 mPchPcieControllerInfoSize;
+
+#define PORT_PLS_TIMEOUT 100    ///< 100 * 10 us = 1ms timeout for USB3 PortSC PLS polling
+
+/**
+  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 < mPchPcieControllerInfoSize);
+  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));
+}
+
+/**
+  Calculate root port device number based on physical port index.
+
+  @param[in]  RpIndex              Root port index (0-based).
+
+  @retval     Root port device number.
+**/
+UINT32
+PchGetPcieRpDevice (
+  IN  UINT32   RpIndex
+  )
+{
+  UINTN ControllerIndex;
+  ControllerIndex = RpIndex / PCH_PCIE_CONTROLLER_PORTS;
+  ASSERT (ControllerIndex < mPchPcieControllerInfoSize);
+  return mPchPcieControllerInfo[ControllerIndex].DevNum;
+}
+
+/**
+  This function reads Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[out] *Data32             Value of Config register
+
+  @retval EFI_SUCCESS             SBI Read successful.
+**/
+EFI_STATUS
+PchSbiRpPciRead32 (
+  IN    UINT32  RpIndex,
+  IN    UINT32  Offset,
+  OUT   UINT32  *Data32
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        RpDevice;
+  UINT8         Response;
+  UINT16        Fid;
+
+  RpDevice = PchGetPcieRpDevice (RpIndex);
+  Fid = (UINT16) ((RpDevice << 3) | (RpIndex % 4 ));
+  Status = PchSbiExecutionEx (
+             GetRpSbiPid (RpIndex),
+             Offset,
+             PciConfigRead,
+             FALSE,
+             0xF,
+             0,
+             Fid,
+             Data32,
+             &Response
+             );
+  if (Status != EFI_SUCCESS) {
+    DEBUG((DEBUG_ERROR,"Sideband Read Failed of RpIndex %d Offset 0x%x. Device = %d Fid = 0x%x\n",RpIndex, Offset, RpDevice, Fid));
+    ASSERT (FALSE);
+  }
+  return Status;
+}
+
+/**
+  This function And then Or Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[in]  Data32And           Value of Config register to be And-ed
+  @param[in]  Data32AOr           Value of Config register to be Or-ed
+
+  @retval EFI_SUCCESS             SBI Read and Write successful.
+**/
+EFI_STATUS
+PchSbiRpPciAndThenOr32 (
+  IN  UINT32  RpIndex,
+  IN  UINT32  Offset,
+  IN  UINT32  Data32And,
+  IN  UINT32  Data32Or
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      RpDevice;
+  UINT32      Data32;
+  UINT8       Response;
+  UINT16      Fid;
+
+  RpDevice = PchGetPcieRpDevice (RpIndex);
+  Status = PchSbiRpPciRead32 (RpIndex, Offset, &Data32);
+  if (Status == EFI_SUCCESS) {
+    Data32 &= Data32And;
+    Data32 |= Data32Or;
+    Fid = (UINT16) ((RpDevice << 3) | (RpIndex % 4 ));
+    Status = PchSbiExecutionEx (
+               GetRpSbiPid (RpIndex),
+               Offset,
+               PciConfigWrite,
+               FALSE,
+               0xF,
+               0,
+               Fid,
+               &Data32,
+               &Response
+               );
+    if (Status != EFI_SUCCESS) {
+      DEBUG((DEBUG_ERROR,"Sideband Write Failed of RpIndex %d Offset 0x%x. Device = %d Fid = 0x%x\n",RpIndex, Offset, RpDevice, Fid));
+      ASSERT (FALSE);
+    }
+  } else {
+    ASSERT (FALSE);
+  }
+  return Status;
+}
+
+/**
+  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
+PrintRegisters (
+  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
+PrintPciRegisters (
+  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"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
new file mode 100644
index 0000000000..dcb43285b7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
@@ -0,0 +1,2407 @@
+/** @file
+  This file contains routines that support PCI Express initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchPciExpressHelpersLibrary.h"
+#include <Library/BaseMemoryLib.h>
+
+#define ASPM_L1_NO_LIMIT 0xFF
+#define ASPM_L0s_NO_LIMIT 0x7
+
+#define LINK_RETRAIN_WAIT_TIME 1000 // microseconds
+//
+// This structure conveniently keeps segment:bus:device:function coordinates of a PCIe device
+// in a single variable. PcieCap is offset to PCI Express capabilities. Having it cached together
+// with coordinates is an optimization feature, because code in this file uses it a lot
+//
+typedef struct {
+  UINT32 Seg     : 8;
+  UINT32 Bus     : 8;
+  UINT32 Dev     : 5;
+  UINT32 Func    : 3;
+  UINT32 PcieCap : 8;
+} SBDF;
+
+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;
+
+typedef struct {
+  UINT32 MaxSnoopLatencyValue         : 10;
+  UINT32 MaxSnoopLatencyScale         : 3;
+  UINT32 MaxNoSnoopLatencyValue       : 10;
+  UINT32 MaxNoSnoopLatencyScale       : 3;
+} LTR_LIMIT;
+
+#define MSLV_BIT_OFFSET   0
+#define MSLS_BIT_OFFSET  10
+#define MNSLV_BIT_OFFSET 13
+#define MNSLS_BIT_OFFSET 23
+
+
+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);
+}
+
+/**
+  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;
+}
+
+/**
+  Translate PCIe Port/Lane pair to 0-based PCIe lane number.
+
+  @param[in] RpIndex    Root Port index
+  @param[in] RpLane     Root Port Lane (0-3)
+
+  @retval PCIe lane number (0-based)
+**/
+UINT32
+PchPciePhysicalLane (
+  UINT32 RpIndex,
+  UINT32 RpLane
+  )
+{
+  UINT32  ControllerIndex;
+  UINT32  ControllerLane;
+
+  ASSERT (RpIndex < GetPchMaxPciePortNum ());
+  ASSERT (((RpIndex % 4) + RpLane) < 4);
+
+  ControllerIndex = (RpIndex / 4);
+  ControllerLane  = (RpIndex % 4) + RpLane;
+  if (IsPcieLaneReversalEnabled (RpIndex)) {
+    ControllerLane = 3 - ControllerLane;
+  }
+  return (ControllerIndex * 4) + ControllerLane;
+}
+
+/**
+  Checks if lane reversal is enabled on a given root port
+
+  @param[in] RpIndex  Root port index (0-based)
+
+  @retval TRUE if lane reversal is enbabled, FALSE otherwise
+**/
+BOOLEAN
+IsPcieLaneReversalEnabled (
+  IN     UINT32  RpIndex
+  )
+{
+  UINT32  Data32;
+  PchSbiRpPciRead32 (PchGetPcieFirstPortIndex (RpIndex), R_PCH_PCIE_CFG_PCIEDBG, &Data32);
+  return !! (Data32 & B_PCH_PCIE_CFG_PCIEDBG_LR);
+}
+
+/**
+  Calculates the index of the first port on the same controller.
+
+  @param[in] RpIndex     Root Port Number (0-based)
+
+  @retval Index of the first port on the first controller.
+**/
+UINT32
+PchGetPcieFirstPortIndex (
+  IN     UINT32  RpIndex
+  )
+{
+  UINT32  ControllerIndex;
+
+  ControllerIndex = RpIndex / PCH_PCIE_CONTROLLER_PORTS;
+  return ControllerIndex * PCH_PCIE_CONTROLLER_PORTS;
+}
+
+/*
+  Returns Tpower_on capability of device
+
+  @param[in] DeviceBase       device's PCI segment base address
+  @param[in] L1ssCapOffset    offset to L1substates capability in device's extended config space
+
+  @retval                     structure containing Tpoweron scale and value
+*/
+T_POWER_ON
+GetTpoCapability (
+  UINT64 DeviceBase,
+  UINT32 L1ssCapOffset
+  )
+{
+  T_POWER_ON Tpo;
+  UINT32     L1ssCapabilities;
+
+  L1ssCapabilities = PciSegmentRead32 (DeviceBase + L1ssCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+  Tpo.Scale = (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTPOS) >> N_PCIE_EX_L1SCAP_PTPOS;
+  Tpo.Value = (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTV) >> N_PCIE_EX_L1SCAP_PTV;
+  return Tpo;
+}
+
+/*
+  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);
+}
+
+/**
+  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
+          ///
+          DEBUG ((DEBUG_INFO,"CapId %x,%x->%02x\n", ((UINT32)(DeviceBase&0xFFFFF000)>>12), CapId, CapHeaderOffset));
+          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;
+
+  DEBUG ((DEBUG_INFO,"PcieFindCapId () SBDF %0x: %0x: %0x :%0x, CapId = %0x \n", Segment, Bus, Device, Function, CapId));
+  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_PCH_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);
+}
+
+/**
+  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
+**/
+STATIC
+BOOLEAN
+PcieIsPhyLanePgEnabled (
+  IN     UINT64  RpBase
+  )
+{
+  UINT32 Data32;
+  Data32 = PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL);
+  return (Data32 & B_PCH_PCIE_CFG_PCIEPMECTL_DLSULPPGE) != 0;
+}
+
+/**
+  Get current PCIe link speed.
+
+  @param[in] RpBase    Root Port base address
+  @retval Link speed
+**/
+UINT32
+GetLinkSpeed (
+  UINT64  RpBase
+  )
+{
+  return PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_LSTS) & B_PCIE_LSTS_CLS;
+}
+
+/**
+  Get max PCIe link speed supported by the root port.
+
+  @param[in] RpBase    Root Port base address
+  @retval Max link speed
+**/
+UINT32
+GetMaxLinkSpeed (
+  UINT64 RpBase
+  )
+{
+  return PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) & B_PCIE_LCAP_MLS;
+}
+
+/**
+  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);
+}
+
+/**
+  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
+**/
+STATIC
+BOOLEAN
+IsLtrCapable (
+  SBDF Sbdf
+  )
+{
+  if (Sbdf.PcieCap == 0) {
+    return FALSE;
+  }
+  return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCAP2_OFFSET) & B_PCIE_DCAP2_LTRMS);
+}
+
+/**
+  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);
+}
+
+/**
+  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;
+}
+
+/**
+  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;
+  }
+}
+
+/**
+  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;
+}
+
+/**
+  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
+**/
+STATIC
+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};
+
+  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;
+  }
+  Result.ForceOverride = FALSE;
+  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
+**/
+STATIC
+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;
+}
+
+/**
+  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_PCH_PCIE_LTRECH_CID);
+  if (LtrCapOffset == 0) {
+    return;
+  }
+  Data16 = (UINT16)((Ltr.MaxSnoopLatencyValue << N_PCH_PCIE_LTRECH_MSLR_VALUE) | (Ltr.MaxSnoopLatencyScale << N_PCH_PCIE_LTRECH_MSLR_SCALE));
+  PciSegmentWrite16(Base + LtrCapOffset + R_PCH_PCIE_LTRECH_MSLR_OFFSET, Data16);
+
+  Data16 = (UINT16)((Ltr.MaxNoSnoopLatencyValue << N_PCH_PCIE_LTRECH_MNSLR_VALUE) | (Ltr.MaxNoSnoopLatencyScale << N_PCH_PCIE_LTRECH_MNSLR_SCALE));
+  PciSegmentWrite16(Base + LtrCapOffset + R_PCH_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
+**/
+STATIC
+BOOLEAN
+FindNextPcieChild (
+  IN     PCI_DEV_TYPE ParentDevType,
+  IN OUT SBDF   *Sbdf
+  )
+{
+  while ( FindNextLegalSbdf (ParentDevType, Sbdf)) {
+    if (IsPcieDevice (Sbdf)) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Checks device's Slot Clock Configuration
+
+  @param[in] Base            device's base address
+
+  @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] 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] Sbdf           Device's Segment:Bus:Device:Function coordinates
+  @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));
+  }
+}
+
+/**
+  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] Base            device's base address
+**/
+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 == 0xFF)) {
+      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) {
+    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
+  )
+{
+  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);
+  }
+  ///
+  ///  Set L1.2 LTR threshold to 80us (value = 0x50, scale = 0x2 = 1024ns), in accordance to BWG
+  ///  BUG BUG BUG  It shouldn't be hardcoded, it should consider Tpoweron, otherwise we risk situation where
+  ///  BUG BUG BUG  threshold is lower than Tpo, and every L1 entry turns into L1.2 entry with no possibility
+  ///  BUG BUG BUG  to exit before LTR elapses, because exit can take no less than Tpo
+  ///
+  Ctrl1Register |= (0x50 << N_PCIE_EX_L1SCTL1_L12LTRTLV);
+  Ctrl1Register |= (2 << N_PCIE_EX_L1SCTL1_L12LTRTLSV);
+
+  Ctrl2Register |= (L1ss.TpoScale);
+  Ctrl2Register |= (L1ss.TpoValue << N_PCIE_EX_L1SCTL2_POWT);
+
+  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
+  //
+  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;
+
+  DEBUG ((DEBUG_INFO, "RecursiveL1ssConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  Base = SbdfToBase (Sbdf);
+  //
+  // 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);
+        SetL1ss (ChildSbdf, CombinedCaps, Override);
+      }
+    }
+  }
+  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);
+}
+
+/**
+  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
+**/
+STATIC
+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 rootport packet split.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] Mps                            maximum packet size
+**/
+STATIC
+VOID
+ConfigureRpPacketSplit (
+  SBDF   RpSbdf,
+  UINT8  Mps
+  )
+{
+  UINT64 RpBase;
+
+  RpBase = SbdfToBase (RpSbdf);
+  PciSegmentAndThenOr32 (RpBase + R_PCH_PCIE_CFG_CCFG, (UINT32) ~(B_PCH_PCIE_CFG_CCFG_UNRS), Mps << N_PCH_PCIE_CFG_CCFG_UNRS);
+}
+
+/**
+  Configures LTR override in rootport's proprietary registers.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] RpConfig                       rootport configuration
+  @param[in] TreeLtr                        combination of LTR override values from all devices under this rootport
+**/
+STATIC
+VOID
+ConfigureRpLtrOverride (
+  SBDF                      RpSbdf,
+  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
+  OVERRIDE_TABLE            *AspmOverride
+  )
+{
+  UINT64       RpBase;
+  UINT32       OvrEn;
+  UINT32       OvrVal;
+  LTR_OVERRIDE TreeLtr;
+
+  OvrEn = 0;
+  OvrVal = 0;
+  RpBase = SbdfToBase (RpSbdf);
+  //
+  // 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
+  //
+
+  TreeLtr = RecursiveLtrOverrideCheck (RpSbdf, AspmOverride);
+
+  if (RpConfig->ForceLtrOverride || TreeLtr.ForceOverride) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_FORCE_OVERRIDE;
+  }
+  if (RpConfig->LtrConfigLock == TRUE) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LOCK;
+  }
+
+  if (RpConfig->SnoopLatencyOverrideMode == 1) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN;
+    OvrVal |= RpConfig->SnoopLatencyOverrideValue;
+    OvrVal |= RpConfig->SnoopLatencyOverrideMultiplier << 10;
+    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRSROVR;
+  } else if (RpConfig->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 (RpConfig->NonSnoopLatencyOverrideMode == 1) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN;
+    OvrVal |= RpConfig->NonSnoopLatencyOverrideValue << 16;
+    OvrVal |= RpConfig->NonSnoopLatencyOverrideMultiplier << 26;
+    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRNSROVR;
+  } else if (RpConfig->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 %x:%x Val %x En %x\n", RpSbdf.Dev, RpSbdf.Func, 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] 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] IoApicPresent  TRUE if there's IoAPIC behind this rootprot
+**/
+VOID
+ConfigureEoiForwarding (
+  UINT8    RpSegment,
+  UINT8    RpBus,
+  UINT8    RpDevice,
+  UINT8    RpFunction,
+  BOOLEAN  IoApicPresent
+  )
+{
+  UINT64 RpBase;
+  UINT32 RpIndex;
+
+  RpBase = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  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
+    /// accordingly to PCH 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 rootport
+
+  @param[in] RpSbdf   segment:bus:device:function coordinates of rootport
+**/
+STATIC
+VOID
+L1ssProprietaryConfiguration (
+  SBDF RpSbdf
+  )
+{
+  BOOLEAN ClkreqSupported;
+  BOOLEAN L1ssEnabled;
+  UINT16  PcieCapOffset;
+  UINT32  Data32;
+  BOOLEAN L1LowSupported;
+  UINT64  RpBase;
+
+  RpBase = SbdfToBase (RpSbdf);
+  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 && IsLtrCapable (RpSbdf) && !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 L1LOW)
+    ///
+    PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, B_PCH_PCIE_CFG_PCIEPMECTL_L1FSOE);
+  }
+}
+
+/**
+  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
+  )
+{
+  UINT8      Mps;
+  BOOLEAN    IoApicPresent;
+  UINT64     RpBase;
+  SBDF       RpSbdf;
+  SBDF_TABLE BridgeCleanupList;
+
+  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);
+  ConfigureRpPacketSplit (RpSbdf, Mps);
+  IoApicPresent = RecursiveIoApicCheck (RpSbdf);
+  ConfigureEoiForwarding (RpSegment, RpBus, RpDevice, RpFunction, IoApicPresent);
+  RecursiveCccConfiguration (RpSbdf, TRUE);
+
+  ClearBusFromTable (&BridgeCleanupList);
+}
+
+/**
+  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] AspmOverrideTableSize    size of override array
+  @param[in] AspmOverrideTable        array of device that need exceptions in configuration
+  @param[in] PerformAspmConfiguration enables/disables ASPM programming
+**/
+VOID
+RootportDownstreamPmConfiguration (
+  UINT8                     RpSegment,
+  UINT8                     RpBus,
+  UINT8                     RpDevice,
+  UINT8                     RpFunction,
+  UINT8                     BusMin,
+  UINT8                     BusMax,
+  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
+  UINT32                    AspmOverrideTableSize,
+  PCH_PCIE_DEVICE_OVERRIDE  *AspmOverrideTable
+  )
+{
+  LTR_LIMIT      PolicyLtr;
+  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 = (RpConfig->LtrMaxNoSnoopLatency & 0x1c00) >> 10;
+  PolicyLtr.MaxNoSnoopLatencyValue = RpConfig->LtrMaxNoSnoopLatency & 0x3FF;
+  PolicyLtr.MaxSnoopLatencyScale   = (RpConfig->LtrMaxSnoopLatency & 0x1c00) >> 10;
+  PolicyLtr.MaxSnoopLatencyValue   = RpConfig->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);
+  ConfigureRpLtrOverride (RpSbdf, RpConfig, &PmOverrideTable);
+  if (RpConfig->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 (RpSbdf);
+  RecursiveAspmConfiguration (RpSbdf, 0, &PmOverrideTable);
+  ClearBusFromTable (&BridgeCleanupList);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c
new file mode 100644
index 0000000000..f2d20c625a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c
@@ -0,0 +1,542 @@
+/** @file
+  This file contains PSF routines for RC usage
+
+  Copyright (c) 2019 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/SaPlatformLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsPsf.h>
+#include <Register/PchRegsPcie.h>
+#include "PchPsfPrivateLibInternal.h"
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~0u,
+    B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  // If there is PCI access right after the PSF hide device, the device might
+  // still be accessible since the PSF cycle is not completed yet, and causes
+  // the race condition between sideband and primary cycles.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS,
+    ~0u,
+    B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS,
+    (UINT32) ~(B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS),
+    0
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // BAR0-5 supported
+  //
+  ASSERT (BarDisMask < BIT6);
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~0u,
+    BarDisMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // BAR0-5 supported
+  //
+  ASSERT (BarEnMask < BIT6);
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    (UINT32)~(BarEnMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS),
+    0
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~(UINT32)(B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN),
+    0
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~0u,
+    B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN
+    );
+}
+
+/**
+  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
+  )
+{
+  ASSERT (BarNum < 6);
+
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0 + BarNum * 0x4,
+    0,
+    BarValue
+    );
+}
+
+/**
+  Hide PMC device at PSF level
+**/
+VOID
+PsfHidePmcDevice (
+  VOID
+  )
+{
+  PsfHideDevice (PsfPmcPort ());
+}
+
+/**
+  Set PMC ABASE value in PSF
+
+  @param[in] Address     Address for ACPI base address.
+**/
+VOID
+PsfSetPmcAbase (
+  IN  UINT16       Address
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort = PsfPmcPort ();
+
+  ASSERT (PchPcrRead32 (PsfPort.PsfPid, PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR4) != 0xFFFFFFFF);
+
+  //
+  // Disable IOSpace before changing the address
+  //
+  PsfDisableDeviceIoSpace (PsfPort);
+
+  //
+  // Program ABASE in PSF PMC space BAR4
+  //
+  PsfSetDeviceBarValue (PsfPort, 4, Address);
+
+  //
+  // Enable IOSpace
+  //
+  PsfEnableDeviceIoSpace (PsfPort);
+}
+
+/**
+  Get PMC ABASE value from PSF
+
+  @retval Address     Address for ACPI base.
+**/
+UINT16
+PsfGetPmcAbase (
+  VOID
+  )
+{
+  UINT16    Address;
+  PSF_PORT  PsfPort;
+
+  PsfPort = PsfPmcPort ();
+  //
+  // Read ABASE from PSF PMC space BAR4
+  //
+  Address = PchPcrRead16 (
+              PsfPort.PsfPid,
+              PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR4
+              );
+
+  ASSERT (Address != 0xFFFF);
+
+  return Address;
+}
+
+/**
+  Get PMC PWRMBASE value from PSF
+
+  @retval Address     Address for PWRM base.
+**/
+UINT32
+PsfGetPmcPwrmBase (
+  VOID
+  )
+{
+  UINT32    Address;
+  PSF_PORT  PsfPort;
+
+  PsfPort = PsfPmcPort ();
+  //
+  // Read PWRMBASE from PSF PMC space BAR0
+  //
+  Address = PchPcrRead32 (
+              PsfPort.PsfPid,
+              PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0
+              );
+
+  ASSERT (Address != 0xFFFFFFFF);
+
+  return Address;
+}
+
+/**
+  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 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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c
new file mode 100644
index 0000000000..d1c87a9e84
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c
@@ -0,0 +1,338 @@
+/** @file
+  This file contains internal PSF routines for PCH PSF lib usage
+
+  Copyright (c) 2019 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 <Register/PchRegsPsfCnl.h>
+#include <Register/PchRegsPcie.h>
+#include "PchPsfPrivateLibInternal.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoI2cPsfRegs[] =
+{
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoI2cPsfRegs[] =
+{
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE
+};
+
+/**
+  Return PSF_PORT for SerialIO I2C device
+
+  @param[in] I2cNum  Serial IO I2C device (I2C0, I2C1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO I2C device
+**/
+PSF_PORT
+PsfSerialIoI2cPort (
+  IN UINT32  I2cNum
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    if (I2cNum < ARRAY_SIZE(mPchLpSerialIoI2cPsfRegs)) {
+      PsfPort.RegBase = mPchLpSerialIoI2cPsfRegs[I2cNum];
+      return PsfPort;
+    }
+  } else {
+    if (I2cNum < ARRAY_SIZE(mPchHSerialIoI2cPsfRegs)) {
+      PsfPort.RegBase = mPchHSerialIoI2cPsfRegs[I2cNum];
+      return PsfPort;
+    }
+  }
+
+  ASSERT(FALSE);
+  return PSF_PORT_NULL;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoSpiPsfRegs[] =
+{
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoSpiPsfRegs[] =
+{
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
+};
+
+/**
+  Return PSF_PORT for SerialIO SPI device
+
+  @param[in] SpiNum  Serial IO SPI device (SPI0, SPI1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO SPI device
+**/
+PSF_PORT
+PsfSerialIoSpiPort (
+  IN UINT32  SpiNum
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    if (SpiNum < ARRAY_SIZE(mPchLpSerialIoSpiPsfRegs)) {
+      PsfPort.RegBase = mPchLpSerialIoSpiPsfRegs[SpiNum];
+      return PsfPort;
+    }
+  } else {
+    if (SpiNum < ARRAY_SIZE(mPchHSerialIoSpiPsfRegs)) {
+      PsfPort.RegBase = mPchHSerialIoSpiPsfRegs[SpiNum];
+      return PsfPort;
+    }
+  }
+
+  ASSERT(FALSE);
+  return PSF_PORT_NULL;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoUartPsfRegs[] =
+{
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoUartPsfRegs[] =
+{
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE
+};
+
+/**
+  Return PSF_PORT for SerialIO UART device
+
+  @param[in] UartNum  Serial IO UART device (UART0, UART1, ....)
+
+  @retval  PsfPort    PSF PORT structure for SerialIO UART device
+**/
+PSF_PORT
+PsfSerialIoUartPort (
+  IN UINT32  UartNum
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    if (UartNum < ARRAY_SIZE(mPchLpSerialIoUartPsfRegs)) {
+      PsfPort.RegBase = mPchLpSerialIoUartPsfRegs[UartNum];
+      return PsfPort;
+    }
+  } else {
+    if (UartNum < ARRAY_SIZE(mPchHSerialIoUartPsfRegs)) {
+      PsfPort.RegBase = mPchHSerialIoUartPsfRegs[UartNum];
+      return PsfPort;
+    }
+  }
+
+  ASSERT(FALSE);
+  return PSF_PORT_NULL;
+}
+
+/**
+  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:
+      if (IsPchLp ()) {
+        *EoiTargetBase = R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 17;
+      } else {
+        *EoiTargetBase = R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 7;
+      }
+      break;
+
+    case 3:
+      *EoiTargetBase = R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+      *EoiControlBase = R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+      MaxTargets = 1;
+      break;
+
+    case 6:
+      if (IsPchH ()) {
+        *EoiTargetBase = R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 8;
+      }
+      break;
+
+    case 7:
+      if (IsPchH ()) {
+        *EoiTargetBase = R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 8;
+      }
+      break;
+
+    case 8:
+      if (IsPchH ()) {
+        *EoiTargetBase = R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 8;
+      }
+      break;
+  }
+  return MaxTargets;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchLpRpDestId[] =
+{
+  {0x18000}, {0x18001}, {0x18002}, {0x18003}, // SPA: PSF1, PortID = 0
+  {0x18200}, {0x18201}, {0x18202}, {0x18203}, // SPB: PSF1, PortID = 2
+  {0x18400}, {0x18401}, {0x18402}, {0x18403}, // SPC: PSF1, PortID = 4
+  {0x18600}, {0x18601}, {0x18602}, {0x18603}  // SPD: PSF1, PortID = 6
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchHRpDestId[] =
+{
+  {0x68000}, {0x68001}, {0x68002}, {0x68003}, // SPA: PSF6, PortID = 0
+  {0x88000}, {0x88001}, {0x88002}, {0x88003}, // SPB: PSF8, PortID = 0
+  {0x68100}, {0x68101}, {0x68102}, {0x68103}, // SPC: PSF6, PortID = 1
+  {0x78000}, {0x78001}, {0x78002}, {0x78003}, // SPD: PSF7, PortID = 0
+  {0x78100}, {0x78101}, {0x78102}, {0x78103}, // SPE: PSF7, PortID = 1
+  {0x88100}, {0x88101}, {0x88102}, {0x88103}  // SPF: PSF8, PortID = 1
+};
+
+/**
+  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 (IsPchLp ()) {
+    if (RpIndex < ARRAY_SIZE(PchLpRpDestId)) {
+      return PchLpRpDestId[RpIndex];
+    }
+  } else {
+    if (RpIndex < ARRAY_SIZE(PchHRpDestId)) {
+      return PchHRpDestId[RpIndex];
+    }
+  }
+  ASSERT (FALSE);
+  return (PSF_PORT_DEST_ID){0};
+}
+
+
+/**
+  Return PSF_PORT for PMC device
+
+  @retval    PsfPort         PSF PORT structure for PMC device
+**/
+PSF_PORT
+PsfPmcPort (
+  VOID
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    PsfPort.RegBase = R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
+  } else {
+    PsfPort.RegBase = R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
+  }
+  return PsfPort;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchLpPsfTable[] =
+{
+  {1, PID_PSF1},
+  {2, PID_PSF2},
+  {3, PID_PSF3},
+  {4, PID_PSF4},
+  {5, PID_CSME_PSF}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchHPsfTable[]  =
+{
+  {1, PID_PSF1},
+  {2, PID_PSF2},
+  {3, PID_PSF3},
+  {4, PID_PSF4},
+  {5, PID_CSME_PSF},
+  {6, PID_PSF6},
+  {7, PID_PSF7},
+  {8, PID_PSF8}
+};
+
+/**
+  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
+  )
+{
+  if (IsPchLp ()) {
+    *PsfTable = mPchLpPsfTable;
+    *PsfTableLength = ARRAY_SIZE(mPchLpPsfTable);
+  } else {
+    *PsfTable = mPchHPsfTable;
+    *PsfTableLength = ARRAY_SIZE(mPchHPsfTable);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c
new file mode 100644
index 0000000000..f88febfa48
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c
@@ -0,0 +1,92 @@
+/** @file
+  PCH private PEI PMC Library for all PCH generations.
+
+  Copyright (c) 2019 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/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchEspiLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsClk.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLan.h>
+#include "PmcPrivateLibInternal.h"
+
+/**
+  Check if PCH PM Timer enabled based on platform policy
+
+  @retval TRUE       PCH PM Timer is enabled.
+  @retval FALSE      PCH PM Timer is disabled.
+**/
+BOOLEAN
+PmcIsPchPmTimerEnabled (
+  VOID
+  )
+{
+  BOOLEAN           PchPmTimerEnabled;
+  EFI_STATUS        Status;
+  SI_POLICY_PPI     *SiPolicy;
+  PCH_PM_CONFIG     *PmConfig;
+
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **)&SiPolicy
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  PchPmTimerEnabled = TRUE;
+  if (!PmConfig->EnableTcoTimer) {
+    PchPmTimerEnabled = FALSE;
+  }
+
+  DEBUG ((DEBUG_INFO, "PmcIsPchPmTimerEnabled () = %x\n", PchPmTimerEnabled));
+
+  return PchPmTimerEnabled;
+}
+
+/**
+  Lock down PMC settings
+
+  @param[in] SiPolicy   The SI Policy PPI instance
+**/
+VOID
+PmcLockSettings (
+  IN  SI_POLICY_PPI     *SiPolicy
+  )
+{
+
+  UINT32         PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  ///
+  /// Set PWRMBASE Offset 0x1048 [24]
+  ///
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ETR3, BIT24);
+
+  ///
+  /// PM_SYNC_LOCK
+  /// Set PWRMBASE Offset 0x18C8 [15]
+  ///
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_PMSYNC_MISC_CFG, B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK);
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
new file mode 100644
index 0000000000..a6ccf4b96b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
@@ -0,0 +1,1033 @@
+/** @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) 2019 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/TimerLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsItss.h>
+#include <IndustryStandard/Pci30.h>
+
+#include "PmcPrivateLibInternal.h"
+
+/**
+  Send PMC IPC1 Normal Read/Write command
+
+  @param[in]  Command           Command to be issued to PMC IPC 1 interface
+  @param[in]  SubCmdId          SUB_CMD_ID for provided Command
+  @param[in]  CmdSize           Total size in byte to be sent via PMC IPC 1 interface
+  @param[in]  WriteBufPtr       Pointer to Structure of 4 DWORDs to be issued to PMC IPC 1 interface
+  @param[out] ReadBufPtr        Pointer to Structure of 4 DWORDs to be filled by PMC IPC 1 interface
+
+  @retval EFI_SUCCESS             Command was executed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid command size
+  @retval EFI_DEVICE_ERROR        IPC command failed with an error
+  @retval EFI_TIMEOUT             IPC command did not complete after 1s
+**/
+EFI_STATUS
+PmcSendCommand (
+  IN  UINT8                    Command,
+  IN  UINT8                    SubCmdId,
+  IN  UINT8                    CmdSize,
+  IN  PMC_IPC_COMMAND_BUFFER   *WriteBufPtr,
+  OUT PMC_IPC_COMMAND_BUFFER   *ReadBufPtr
+  )
+{
+  EFI_STATUS             Status;
+  UINT32                 PchPwrmBase;
+  UINT32                 IpcSts;
+  UINTN                  Timeout;
+
+  DEBUG ((DEBUG_INFO, "PmcSendCommand(): IPC_COMMAND=0x%02X, IPC_SUB_CMD = 0x%02X, IPC_SIZE=0x%02X \n", Command, SubCmdId, CmdSize));
+  DEBUG ((DEBUG_INFO, "WBUF0=0x%08X, WBUF1=0x%08X, WBUF2=0x%08X, WBUF3=0x%08X \n", WriteBufPtr->Buf0, WriteBufPtr->Buf1, WriteBufPtr->Buf2, WriteBufPtr->Buf3));
+
+  if (CmdSize > 16) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Program the Write Buffer 0 with the Data that needs to be written to PMC
+  //
+  PchPwrmBase = PmcGetPwrmBase ();
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF0), WriteBufPtr->Buf0);
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF1), WriteBufPtr->Buf1);
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF2), WriteBufPtr->Buf2);
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF3), WriteBufPtr->Buf3);
+  //
+  // Program the command register with command and size
+  //
+  MmioWrite32 (
+    PchPwrmBase + R_PMC_PWRM_IPC_CMD,
+    (UINT32) ((CmdSize << N_PMC_PWRM_IPC_CMD_SIZE) |
+      (SubCmdId << N_PMC_PWRM_IPC_CMD_CMD_ID) |
+      (Command << N_PMC_PWRM_IPC_CMD_COMMAND))
+    );
+
+  //
+  // Read the IPC_STS register to get BUSY or Error status
+  //
+  Timeout = 0;
+  Status = EFI_SUCCESS;
+  while (TRUE) {
+    IpcSts = MmioRead32 (PchPwrmBase + R_PMC_PWRM_IPC_STS);
+    if ((IpcSts & B_PMC_PWRM_IPC_STS_BUSY) == 0) {
+      break;
+    }
+
+    if (Timeout > (1000 * 100)) {
+      Status = EFI_TIMEOUT;
+      break;
+    }
+    MicroSecondDelay (10);
+    Timeout++;
+  }
+
+  if ((IpcSts & B_PMC_PWRM_IPC_STS_ERROR) != 0) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "PmcSendCommand() Error: IPC_STS=0x%08X\n", IpcSts));
+    return Status;
+  }
+
+  if (ReadBufPtr != NULL) {
+    //
+    // Fill the  ReadBuffer contents with the Data that needs to be read from PMC
+    //
+    ReadBufPtr->Buf0 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF0);
+    ReadBufPtr->Buf1 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF1);
+    ReadBufPtr->Buf2 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF2);
+    ReadBufPtr->Buf3 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF3);
+
+    DEBUG ((DEBUG_INFO, "RBUF0=0x%08X, RBUF1=0x%08X, RBUF2=0x%08X, RBUF3=0x%08X \n", ReadBufPtr->Buf0, ReadBufPtr->Buf1, ReadBufPtr->Buf2, ReadBufPtr->Buf3));
+  }
+
+  return Status;
+}
+
+/**
+  This function checks if SCI interrupt is enabled
+
+  @retval SCI Enable state
+**/
+BOOLEAN
+PmcIsSciEnabled (
+  VOID
+  )
+{
+  return ((IoRead8 (PmcGetAcpiBase () + R_ACPI_IO_PM1_CNT) & B_ACPI_IO_PM1_CNT_SCI_EN) != 0);
+}
+
+/**
+  This function triggers Software GPE
+**/
+VOID
+PmcTriggerSwGpe (
+  VOID
+  )
+{
+  IoOr32 (PmcGetAcpiBase () + R_ACPI_IO_GPE_CNTL, B_ACPI_IO_GPE_CNTL_SWGPE_CTRL);
+}
+
+/**
+  Set PCH ACPI base address.
+  The Address should not be 0 and should be 256 bytes aligned. It is IO space, so must not exceed 0xFFFF.
+  Only address matching PcdAcpiBaseAddress is the acceptable value for ACPI IO Base
+
+  @param[in] Address                    Address for ACPI base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PmcSetAcpiBase (
+  IN  UINT16                            Address
+  )
+{
+
+  if (Address != PcdGet16 (PcdAcpiBaseAddress)) {
+    DEBUG ((DEBUG_ERROR, "PmcSetAcpiBase Error. Invalid Address: %x.\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PsfSetPmcAbase (Address);
+  return EFI_SUCCESS;
+}
+
+/**
+  Set PCH PWRM base address.
+  Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for PWRMBASE
+
+  @param[in] Address                    Address for PWRM base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PmcSetPwrmBase (
+  IN  UINT32                            Address
+  )
+{
+  UINT64                                PmcBase;
+
+  if (Address != PCH_PWRM_BASE_ADDRESS) {
+    DEBUG ((DEBUG_ERROR, "PmcSetPwrmBase Error. Invalid Address: %x.\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PmcBase      = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_PMC,
+                   PCI_FUNCTION_NUMBER_PCH_PMC,
+                   0
+                   );
+  if (PciSegmentRead16 (PmcBase) == 0xFFFF) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Disable PWRMBASE in PMC Device first before changing PWRM base address.
+  //
+  PciSegmentAnd16 (
+    PmcBase + PCI_COMMAND_OFFSET,
+    (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE
+    );
+
+  //
+  // Program PWRMBASE in PMC Device
+  //
+  PciSegmentAndThenOr32 (
+    PmcBase + R_PMC_CFG_BASE,
+    (UINT32) (~B_PMC_CFG_PWRM_BASE_MASK),
+    Address
+    );
+
+  //
+  // Enable PWRMBASE in PMC Device
+  //
+  PciSegmentOr16 (
+    PmcBase + PCI_COMMAND_OFFSET,
+    EFI_PCI_COMMAND_MEMORY_SPACE
+    );
+  return EFI_SUCCESS;
+}
+
+/**
+  This function checks if function disable (static and non-static power gating)
+  configuration is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsFunctionDisableConfigLocked (
+  VOID
+  )
+{
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK) != 0);
+}
+
+/**
+  Check if MODPHY SUS PG is supported
+
+  @retval  Status of MODPHY SUS PG support
+**/
+BOOLEAN
+PmcIsModPhySusPgSupported (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    //
+    // MPHY SUS PG supported on PCH-LP only:
+    //
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  This function checks if ISH is function disabled
+  by static power gating
+
+  @retval ISH device state
+**/
+BOOLEAN
+PmcIsIshFunctionDisabled (
+  VOID
+  )
+{
+  //
+  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
+  //
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1)) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC) != 0);
+}
+
+/**
+  This function checks if ISH device is supported (not disabled by fuse)
+
+  @retval ISH support state
+**/
+BOOLEAN
+PmcIsIshSupported (
+  VOID
+  )
+{
+  //
+  // Get fuse info from PWRMBASE + FUSE_DIS_RD_2
+  //
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_FUSE_DIS_RD_2)) & B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function disables ISH device by static power gating.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableIsh (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] = 1b to statically disable ISH Controller
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC);
+}
+
+/**
+  This function enables ISH device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableIsh (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] = 0b to enable ISH controller
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) (~B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC));
+}
+
+/**
+  This function checks if GbE is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsGbeFunctionDisabled (
+  VOID
+  )
+{
+  //
+  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
+  //
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1)) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC) != 0);
+}
+
+/**
+  This function disables GbE device by static power gating and enables ModPHY SPD gating (PCH-LP only).
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableGbe (
+  VOID
+  )
+{
+  UINT32 PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] = 1b to statically disable GbE Controller
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[13] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    PmcGbeModPhyPowerGating ();
+  }
+}
+
+/**
+  This function enables GbE device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableGbe (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] = 0b to enable GbE controller
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC);
+}
+
+/**
+  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 disables (non-static power gating) HDA device
+**/
+VOID
+PmcDisableHda (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC);
+}
+
+/**
+  This function checks if Cnvi device is supported (not disabled by fuse)
+
+  @retval Cnvi support state
+**/
+BOOLEAN
+PmcIsCnviSupported (
+  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_CNVI_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if CNVi is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsCnviFunctionDisabled (
+  VOID
+  )
+{
+  //
+  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC) != 0);
+}
+
+/**
+  This function enables CNVi device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableCnvi (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1 to enable CNVi controller
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC);
+}
+
+/**
+  This function disables CNVi device by static power gating.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableCnvi (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC);
+}
+
+/**
+  This function disables (non-static power gating) PCIe Root Port and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+**/
+VOID
+PmcDisablePcieRootPort (
+  IN UINT32  RpIndex
+  )
+{
+  UINT32   NstPgFdis1Mask;
+  UINT32   PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+  //
+  // Set PchPwrmBase + NST_PG_FDIS_1 to function disable PCIE port in PMC
+  //
+  if (IsPchH () && RpIndex >= 20) {
+    NstPgFdis1Mask = B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC << (RpIndex % 20);
+  } else {
+    NstPgFdis1Mask = B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC << RpIndex;
+  }
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, NstPgFdis1Mask);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[26:0] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    if (RpIndex <= 11) {
+      MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0 << RpIndex);
+    } else {
+      MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0 << (RpIndex - 12));
+    }
+  }
+}
+
+/**
+  This function disables (non-static power gating) xHCI and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableXhci (
+  VOID
+  )
+{
+  UINT32   PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 [0] = 1b
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[14] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI);
+  }
+}
+
+/**
+  This function disables (non-static power gating) XDCI and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableXdci (
+  VOID
+  )
+{
+  UINT32 PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 [26] = 1b to disable XDCI Controller in PMC
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[15] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI);
+  }
+}
+
+/**
+  This function checks if XDCI device is supported (not disabled by fuse)
+
+  @retval XDCI support state
+**/
+BOOLEAN
+PmcIsXdciSupported (
+  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_OTG_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function locks HOST SW power gating control
+**/
+VOID
+PmcLockHostSwPgCtrl (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1, B_PMC_PWRM_SW_PG_CTRL_LOCK);
+}
+
+/**
+  This function checks if HOST SW Power Gating Control is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsHostSwPgCtrlLocked (
+  VOID
+  )
+{
+  //
+  // Get lock info from PWRMBASE + HSWPGCR1
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1) & B_PMC_PWRM_SW_PG_CTRL_LOCK) != 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);
+}
+
+/**
+  Disables USB2 Core PHY PowerGating during power on for Chipsetinit table update
+**/
+VOID
+PmcUsb2CorePhyPowerGatingDisable (
+  VOID
+  )
+{
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_CFG, (UINT32) ~B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG);
+}
+
+
+/**
+  This function reads CPU Early Power-on Configuration (EPOC)
+
+  @retval CPU EPOC value
+**/
+UINT32
+PmcGetCpuEpoc (
+  VOID
+  )
+{
+  return MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC);
+}
+
+/**
+  This function sets CPU Early Power-on Configuration (EPOC)
+
+  @param[in] CpuEpocValue      CPU EPOC value
+**/
+VOID
+PmcSetCpuEpoc (
+  IN UINT32     CpuEpocValue
+  )
+{
+  MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC, CpuEpocValue);
+}
+
+/**
+  This function sets DRAM_RESET# Control Pin value
+
+  @param[in] DramResetVal      0: Pin output is low
+                               1: Pin output is tri-stated
+**/
+VOID
+PmcSetDramResetCtlState (
+  IN UINT32     DramResetVal
+  )
+{
+  ASSERT (DramResetVal < 2);
+
+  MmioAndThenOr32 (
+    PmcGetPwrmBase () + R_PMC_PWRM_CFG2,
+    (UINT32)~B_PMC_PWRM_CFG2_DRAM_RESET_CTL,
+    DramResetVal << N_PMC_PWRM_CFG2_DRAM_RESET_CTL
+    );
+}
+
+/**
+  This function enables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh
+**/
+VOID
+PmcEnableCf9GlobalReset (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) (B_PMC_PWRM_ETR3_CF9GR));
+}
+
+/**
+  This function disables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh.
+**/
+VOID
+PmcDisableCf9GlobalReset (
+  VOID
+  )
+{
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) ~B_PMC_PWRM_ETR3_CF9GR);
+}
+
+/**
+  This 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
+PmcDisableCf9GlobalResetWithLock (
+  VOID
+  )
+{
+  MmioAndThenOr32 (
+    PmcGetPwrmBase () + R_PMC_PWRM_ETR3,
+    (UINT32) ~B_PMC_PWRM_ETR3_CF9GR,
+    (UINT32) B_PMC_PWRM_ETR3_CF9LOCK
+    );
+}
+
+/**
+  This function disables CF9 reset without Resume Well reset.
+  Cf9 0x6/0xE reset will also reset resume well logic.
+**/
+VOID
+PmcDisableCf9ResetWithoutResumeWell (
+  VOID
+  )
+{
+
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) ~B_PMC_PWRM_ETR3_CWORWRE);
+}
+
+/**
+  This function clears RTC Power Failure status (RTC_PWR_FLR)
+**/
+VOID
+PmcClearRtcPowerFailureStatus (
+  VOID
+  )
+{
+  //
+  // Set B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS to 0 to clear it.
+  //
+  MmioAnd8 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B), (UINT8) (~B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS));
+}
+
+/**
+  This function enables PCI Express* PME events
+**/
+VOID
+PmcEnablePciExpressPmeEvents (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B, B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN);
+}
+
+/**
+  This function sets eSPI SMI Lock
+**/
+VOID
+PmcLockEspiSmi (
+  VOID
+  )
+{
+  MmioAndThenOr8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1,
+    (UINT8) ~((B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS) >> 8),
+    B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK >> 8
+    );
+}
+
+/**
+  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);
+}
+
+/**
+  This function sets 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
+PmcSetGpioGpe (
+  IN UINT32    GpeDw0Value,
+  IN UINT32    GpeDw1Value,
+  IN UINT32    GpeDw2Value
+  )
+{
+  UINT32               Data32Or;
+  UINT32               Data32And;
+
+  //
+  // Program GPIO_CFG register
+  //
+  Data32And = (UINT32) ~(B_PMC_PWRM_GPIO_CFG_GPE0_DW2 | B_PMC_PWRM_GPIO_CFG_GPE0_DW1 | B_PMC_PWRM_GPIO_CFG_GPE0_DW0);
+  Data32Or  = (UINT32) ((GpeDw2Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW2) |
+                        (GpeDw1Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW1) |
+                        (GpeDw0Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW0));
+
+  MmioAndThenOr32 (
+    (PmcGetPwrmBase () + R_PMC_PWRM_GPIO_CFG),
+    Data32And,
+    Data32Or
+    );
+}
+
+/**
+  Disable SLP_S0# assertion when system is in debug mode
+**/
+VOID
+PmcDisableSlpS0AssertionInDebugMode (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Enable SLP_S0# assertion even when system is in debug mode
+**/
+VOID
+PmcEnableSlpS0AssertionInDebugMode (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Wbuf.Buf0 = 1;
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function gets NMI regsiter.
+
+  @retval  NMI register setting
+**/
+UINT32
+PmcGetNmiControl (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+  PMC_IPC_COMMAND_BUFFER    Rbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+  ZeroMem (&Rbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+  //
+  // WBUF0 = 2 for NMI delivery control and status register (entire register PCR[ITSS] 0x3330)
+  //
+  Wbuf.Buf0 = V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI;
+  Status = PmcSendCommand (
+             V_PMC_PWRM_IPC_CMD_COMMAND_PROXY,
+             V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ,
+             4,
+             &Wbuf,
+             &Rbuf
+             );
+  ASSERT_EFI_ERROR (Status);
+  return Rbuf.Buf0;
+}
+
+/**
+  This function sets the NMI register
+
+  @param[in]  NmiRegister    The whole NMI register
+**/
+VOID
+PmcSetNmiControl (
+  UINT32   NmiRegister
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+  //
+  // WBUF0 = 2 for NMI delivery control and status register (entire register PCR[ITSS] 0x3330)
+  //
+  Wbuf.Buf0 = V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI;
+  Wbuf.Buf1 = NmiRegister;
+  Status = PmcSendCommand (
+             V_PMC_PWRM_IPC_CMD_COMMAND_PROXY,
+             V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE,
+             8,
+             &Wbuf,
+             NULL
+             );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function enables GBE ModPHY SPD gating.
+**/
+VOID
+PmcGbeModPhyPowerGating (
+  VOID
+  )
+{
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set B_PCH_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE ModPHY SPD RT Request
+    //
+    MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c
new file mode 100644
index 0000000000..2411a2be23
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c
@@ -0,0 +1,73 @@
+/** @file
+  PCH PMC Private Library implementation for Cannon Lake PCH.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPmc.h>
+
+#include "PmcPrivateLibInternal.h"
+
+/**
+  This function disables (non-static power gating) SATA and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in]  SataCtrlIndex     SATA controller index
+**/
+VOID
+PmcDisableSata (
+  IN UINT32     SataCtrlIndex
+  )
+{
+  UINT32 PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 [22] = 1b to disable SATA Controller in PMC
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // MPHY SUS PG supported on PCH-LP only:
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[12] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA);
+  }
+}
+
+/**
+  This function checks if SATA device is supported (not disabled by fuse)
+
+  @param[in] SataCtrlIndex SATA controller index
+
+  @retval SATA support state
+**/
+BOOLEAN
+PmcIsSataSupported (
+  UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  //
+  // 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_SATA_FUSE_SS_DIS) == 0);
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c
new file mode 100644
index 0000000000..847be42937
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c
@@ -0,0 +1,360 @@
+/** @file
+  PCH PMC Private Library implementation for Cannon Lake PCH.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPmc.h>
+
+#include "PmcPrivateLibInternal.h"
+
+/**
+  This function disables Trace Hub by enabling power gating
+**/
+VOID
+PmcDisableTraceHub (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Wbuf.Buf0 = BIT0;
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function enables Trace Hub by disabling power gating
+**/
+VOID
+PmcEnableTraceHub (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Wbuf.Buf0 = BIT1;
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function is part of PMC init and configures which clock wake signals should
+  set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent up to the CPU/PCH
+**/
+VOID
+PmcInitClockWakeEnable (
+  VOID
+  )
+{
+  UINT32                    PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    ///
+    /// PWRMBASE + 0x1880 = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING, 0x0);
+  } else {
+    ///
+    /// PWRMBASE + 0x1880 = 0x2F8FBB01
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING, 0x2F8FBB01);
+  }
+
+  if (IsPchLp ()) {
+    if (PchStepping () < PCH_B0) {
+      ///
+      /// PWRMBASE + 0x1884 = 0x0
+      ///
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, 0x0);
+    } else {
+      ///
+      /// PWRMBASE + 0x1884
+      ///  PCH-LP: 0x0280C7E1
+      ///
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, 0x0280C7E1);
+    }
+  } else {
+    ///
+    /// PWRMBASE + 0x1884
+    ///  PCH-H:  0x0280D7E1
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, 0x0280D7E1);
+  }
+
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    ///
+    /// PWRMBASE + 0x1888 = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x0);
+    ///
+    /// PWRMBASE + 0x188C = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0);
+  } else {
+    ///
+    /// PWRMBASE + 0x1888 = 0x2F8FAB01
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x2F8FAB01);
+
+    ///
+    /// PWRMBASE + 0x188C
+    ///  PCH-LP: 0x0280C7E1
+    ///  PCH-H:  0x0280D7E1
+    ///
+    if (IsPchLp ()) {
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0280C7E1);
+    } else {
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0280D7E1);
+    }
+  }
+
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    ///
+    /// PWRMBASE + 0x1898 = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF, 0x0);
+  } else {
+    ///
+    /// PWRMBASE + 0x1898 = 0x00018000
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF, 0x00018000);
+  }
+}
+
+/**
+  This function configures PWRMBASE + 0x1E00 register
+**/
+VOID
+PmcConfigureRegPwrm1E00 (
+  VOID
+  )
+{
+  ///
+  /// PWRMBASE + 0x1E00[31,30] = 1,1
+  /// PWRMBASE + 0x1E00[29] = 0
+  /// PWRMBASE + 0x1E00[10:6] = 0
+  /// PWRMBASE + 0x1E00[3:0] = 2
+  ///
+  MmioAndThenOr32 (
+    PmcGetPwrmBase () + R_PMC_PWRM_1E00,
+    (UINT32) ~(BIT29 | (0x1F << 6) | 0xF),
+    BIT31 | BIT30 | 2
+    );
+}
+
+/**
+  This function configures Misc PM_SYNC events settings
+**/
+VOID
+PmcConfigurePmSyncEventsSettings (
+  VOID
+  )
+{
+  ///
+  /// PWRMBASE + 0x18C0 = 0x00000A20
+  ///
+  MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_EN_MISC_EVENT, 0x00000A20);
+}
+
+/**
+  This function enables all SerailIo devices.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableSerialIo (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_2
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2, (UINT32)~B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
+}
+
+/**
+  This function disables (static power gating) all SerailIo devices.
+  For SerialIo controllers they can be power gated only if all of them are to be disabled.
+  They cannot be statically power gated separately.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableSerialIo (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_2
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2, B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
+}
+
+/**
+  This function checks if all SerialIo devices are statically disabled (static power gating)
+
+  @retval SerialIo disable state
+**/
+BOOLEAN
+PmcIsSerialIoStaticallyDisabled (
+  VOID
+  )
+{
+  //
+  // Check if all SerialIo controllers are statically disabled in PMC
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2) & B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO) == B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
+}
+
+/**
+  This function checks if SerialIo device is supported (not disabled by fuse)
+
+  @retval SerialIo support state
+**/
+BOOLEAN
+PmcIsSerialIoSupported (
+  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_SERIALIO_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function disables (non-static power gating) SCS eMMC controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsEmmc (
+  VOID
+  )
+{
+  ASSERT (IsPchLp ());
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC);
+}
+
+/**
+  This function disables (non-static power gating) SCS SD Card controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsSdCard (
+  VOID
+  )
+{
+  UINT32        ScsDevicePgMask;
+
+  if (IsPchLp ()) {
+    ScsDevicePgMask = B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC;
+  } else {
+    ScsDevicePgMask = B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC;
+  }
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, ScsDevicePgMask);
+}
+
+/**
+  This function disables (non-static power gating) SCS UFS controller and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in] UfsNum     SCS UFS Device
+**/
+VOID
+PmcDisableScsUfs (
+  IN UINT32   UfsNum
+  )
+{
+  UINT32        PchPwrmBase;
+
+  ASSERT ((UfsNum == 0) && IsPchLp ());
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[16] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2);
+  }
+}
+
+/**
+  This function checks if SCS eMMC device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsEmmcSupported (
+  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_EMMC_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if SCS SD Card device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsSdCardSupported (
+  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_SDX_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if SCS UFS device is supported (not disabled by fuse)
+
+  @param[in] UfsNum     SCS UFS Device
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsUfsSupported (
+  IN UINT32   UfsNum
+  )
+{
+  //
+  // 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_UFSX2_FUSE_SS_DIS) == 0);
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
new file mode 100644
index 0000000000..bbe944da5c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
@@ -0,0 +1,194 @@
+/** @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) 2019 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 <Private/Library/PmcPrivateLib.h>
+
+/**
+  This function locks down PMC (DebugModeLock)
+**/
+VOID
+PmcLockWithS3BootScript (
+  VOID
+  )
+{
+
+  UINT32 PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRM_CFG[27] prior to OS.
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_CFG, B_PMC_PWRM_CFG_DBG_MODE_LOCK);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (PchPwrmBase + R_PMC_PWRM_CFG),
+    1,
+    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_CFG)
+    );
+
+}
+
+/**
+  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 SLP_SX Stretching Policy and adds
+  lock setting to S3 Boot Script
+**/
+VOID
+PmcLockSlpSxStretchingPolicyWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr8 (
+    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2),
+    (UINT8) ((B_PMC_PWRM_GEN_PMCON_B_SLPSX_STR_POL_LOCK) >> 16)
+    );
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2),
+    1,
+    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2)
+    );
+}
+
+/**
+  This function sets SMI Lock with S3 Boot Script programming
+**/
+VOID
+PmcLockSmiWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr8 ((PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B),
+    1,
+    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B)
+    );
+}
+
+/**
+  This function locks static power gating configuration with S3 Boot Script programming
+**/
+VOID
+PmcLockFunctionDisableConfigWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) (B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK));
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1),
+    1,
+    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1)
+    );
+}
+
+/**
+  This function locks PMC Set Strap Message interface with S3 Boot Script programming
+**/
+VOID
+PmcLockSetStrapMsgInterfaceWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr32 ((UINTN) (PchPwrmBase + R_PMC_PWRM_SSML), B_PMC_PWRM_SSML_SSL);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML),
+    1,
+    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML)
+    );
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c
new file mode 100644
index 0000000000..9c722bce07
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c
@@ -0,0 +1,356 @@
+/** @file
+  This file contains routines for PEI GPIO Helpers Lib
+
+  Copyright (c) 2019 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 <Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h>
+#include <Private/Library/GpioHelpersLib.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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c
new file mode 100644
index 0000000000..1b05378799
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c
@@ -0,0 +1,68 @@
+/** @file
+  This file contains GpioMemLib implementation for PEI phase
+
+  Copyright (c) 2019 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 <Private/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 ();
+  }
+}
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM private library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (22 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
                   ` (13 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds PCH SMM private library class instances.

* SmmPchPrivateLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf | 32 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c   | 58 ++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf
new file mode 100644
index 0000000000..5cbad21fa5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf
@@ -0,0 +1,32 @@
+## @file
+#  PCH SMM private lib.
+#
+# Copyright (c) 2019 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
+CpuPlatformLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmPchPrivateLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c
new file mode 100644
index 0000000000..85a3086874
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c
@@ -0,0 +1,58 @@
+/** @file
+  PCH SMM private lib.
+
+  Copyright (c) 2019 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/CpuPlatformLib.h>
+#include <CpuRegs.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_ADDR, 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_ADDR, Data32 & (UINT32) (~BIT0));
+  ///
+  /// Read FED30880h back to ensure the setting went through.
+  ///
+  Data32 = MmioRead32 (0xFED30880);
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (23 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
                   ` (12 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds System Agent (SA) library class instances.

* DxeSaPolicyLib - DXE SA policy configuration services.
* PeiDxeSmmSaPlatformLib - SA platform generation services.
* PeiSaPolicyLib - PEI SA policy configuration services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf                 |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf |  38 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf                 |  74 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h               |  37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h        |  21 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h                   | 323 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h               |  39 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c                   | 473 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c        | 128 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c                   | 745 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c                   | 656 +++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c             | 284 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c                    | 559 +++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S              | 114 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm            | 126 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm           | 118 ++++
 16 files changed, 3778 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
new file mode 100644
index 0000000000..8a5092e199
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+# Copyright (c) 2019 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
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeSaPolicyLib.c
+DxeSaPolicyLibrary.h
+
+[Guids]
+gGraphicsDxeConfigGuid
+gMiscDxeConfigGuid
+gPcieDxeConfigGuid
+gMemoryDxeConfigGuid
+gVbiosDxeConfigGuid
+
+[Protocols]
+gSaPolicyProtocolGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
new file mode 100644
index 0000000000..ffc4043e7a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for SA Platform Lib
+#
+# Copyright (c) 2019 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
+CpuPlatformLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Sources]
+SaPlatformLibrary.h
+SaPlatformLibrary.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
new file mode 100644
index 0000000000..22d0f0c945
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
@@ -0,0 +1,74 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSaPolicyLib
+FILE_GUID = d7022865-ef1b-449d-8c3f-ac36488c408b
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiSaPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+CpuMailboxLib
+SiConfigBlockLib
+RngLib
+PmcPrivateLib
+GpioLib
+PchInfoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdTsegSize
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress
+gSiPkgTokenSpaceGuid.PcdIpuEnable                   ## CONSUMES
+
+[Sources]
+PeiSaPolicyLib.c
+PeiSaPolicyLibrary.h
+MrcOemPlatform.c
+MrcOemPlatform.h
+SaPrintPolicy.c
+PeiSaPolicyLibSample.c
+
+[Sources.IA32]
+Ia32/MrcOemPlatform.nasm
+Ia32/MrcOemPlatform.S
+
+[Ppis]
+gSiPreMemPolicyPpiGuid        ## CONSUMES
+gSiPolicyPpiGuid              ## CONSUMES
+
+[Guids]
+gSaMiscPeiPreMemConfigGuid    ## PRODUCES
+gSaMiscPeiConfigGuid          ## PRODUCES
+gSaPciePeiPreMemConfigGuid    ## PRODUCES
+gSaPciePeiConfigGuid          ## PRODUCES
+gGraphicsPeiPreMemConfigGuid  ## CONSUMES
+gGraphicsPeiConfigGuid        ## CONSUMES
+gSwitchableGraphicsConfigGuid ## PRODUCES
+gCpuTraceHubConfigGuid        ## PRODUCES
+gMemoryConfigGuid             ## PRODUCES
+gMemoryConfigNoCrcGuid        ## PRODUCES
+gIpuPreMemConfigGuid          ## PRODUCES
+gGnaConfigGuid                ## PRODUCES
+gVtdConfigGuid                ## PRODUCES
+gSaOverclockingPreMemConfigGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
new file mode 100644
index 0000000000..449b67798c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the DxeSaPolicy library.
+
+  Copyright (c) 2019 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 <Base.h>
+#include <ConfigBlock.h>
+#include <Library/HobLib.h>
+#include <MkhiMsgs.h>
+
+#include <Protocol/SaPolicy.h>
+
+#define WORD_FIELD_VALID_BIT  BIT15
+///
+/// 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/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
new file mode 100644
index 0000000000..07d4c6e666
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for SA Platform Lib implementation.
+
+  Copyright (c) 2019 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 <SaAccess.h>
+#include <CpuAccess.h>
+#include <Library/SaPlatformLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
new file mode 100644
index 0000000000..61a6e2a691
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
@@ -0,0 +1,323 @@
+/** @file
+  This file contains functions that read the SPD data for each DIMM slot over
+  the SMBus interface.
+  This file is SampleCode for Intel SA PEI Policy initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyLibrary.h"
+#include "MrcInterface.h"
+
+#define RTC_INDEX_REGISTER        (0x70)
+#define RTC_TARGET_REGISTER       (0x71)
+
+#define RTC_INDEX_MASK            (0x7F)
+#define RTC_BANK_SIZE             (0x80)
+
+#define RTC_SECONDS               (0x00)
+#define RTC_MINUTES               (0x02)
+#define RTC_HOURS                 (0x04)
+#define RTC_DAY_OF_MONTH          (0x07)
+#define RTC_MONTH                 (0x08)
+#define RTC_YEAR                  (0x09)
+#define CMOS_REGA                 (0x0A)
+#define CMOS_REGB                 (0x0B)
+#define CMOS_REGC                 (0x0C)
+#define CMOS_REGD                 (0x0D)
+
+#define RTC_UPDATE_IN_PROGRESS    (0x80)
+#define RTC_HOLD                  (0x80)
+#define RTC_MODE_24HOUR           (0x02)
+#define RTC_CLOCK_DIVIDER         (0x20)
+#define RTC_RATE_SELECT           (0x06)
+
+#define BCD2BINARY(A)             (((((A) >> 4) & 0xF) * 10) + ((A) & 0xF))
+#define CENTURY_OFFSET            (2000)
+
+/**
+  Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+  The SPD data locations read is controlled by the current boot mode.
+
+  @param[in] BootMode           - The current MRC boot mode.
+  @param[in] Address            - SPD SmBus address offset.
+  @param[in] Buffer             - Buffer that contains the data read from the SPD.
+  @param[in] SpdDdr3Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr3TableSize   - Size of SpdDdr3Table in bytes.
+  @param[in] SpdDdr4Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr4TableSize   - Size of SpdDdr4Table in bytes.
+  @param[in] SpdLpddrTable      - Indicates which SPD bytes to read.
+  @param[in] SpdLpddrTableSize  - Size of SpdLpddrTable in bytes.
+
+  @retval TRUE if the read is successful, otherwise FALSE on error.
+**/
+BOOLEAN
+GetSpdData (
+  IN SPD_BOOT_MODE BootMode,
+  IN UINT8         Address,
+  IN OUT   UINT8   *Buffer,
+  IN UINT8         *SpdDdr3Table,
+  IN UINT32        SpdDdr3TableSize,
+  IN UINT8         *SpdDdr4Table,
+  IN UINT32        SpdDdr4TableSize,
+  IN UINT8         *SpdLpddrTable,
+  IN UINT32        SpdLpddrTableSize
+  );
+
+/**
+  Output a string to the debug stream/device.
+
+  @param[in] String     - The string to output.
+**/
+VOID
+SaDebugPrint (
+  VOID   *String
+  );
+
+/**
+  Calculate the PCI device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+  @retval The PCI device address.
+**/
+UINT32
+GetPciDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  );
+
+/**
+  Calculate the PCIE device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+   The PCIE device address.
+
+  @retval The PCIe device address
+**/
+UINT32
+GetPcieDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  );
+
+/**
+  Read specific RTC/CMOS RAM
+
+  @param[in] Location        Point to RTC/CMOS RAM offset for read
+
+  @retval The data of specific location in RTC/CMOS RAM.
+**/
+UINT8
+PeiRtcRead (
+  IN const UINT8 Location
+  );
+
+/**
+  Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
+  Since RTC time is stored in BCD, convert each value to binary.
+
+  @param[out] Seconds       - The current second (0-59).
+  @param[out] Minutes       - The current minute (0-59).
+  @param[out] Hours         - The current hour (0-23).
+  @param[out] DayOfMonth    - The current day of the month (1-31).
+  @param[out] Month         - The current month (1-12).
+  @param[out] Year          - The current year (2000-2099).
+**/
+VOID
+GetRtcTime (
+  OUT UINT8  *const Seconds,
+  OUT UINT8  *const Minutes,
+  OUT UINT8  *const Hours,
+  OUT UINT8  *const DayOfMonth,
+  OUT UINT8  *const Month,
+  OUT UINT16 *const Year
+  );
+
+/**
+  Gets CPU current time.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+
+  @retval The current CPU time in milliseconds.
+**/
+UINT64
+GetCpuTime (
+  IN VOID     *GlobalData
+  );
+
+/**
+  Sets the specified number of memory words, a word at a time, at the
+  specified destination.
+
+  @param[in, out] Dest     - Destination pointer.
+  @param[in]      NumWords - The number of dwords to set.
+  @param[in]      Value    - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemWord (
+  IN OUT VOID     *Dest,
+  IN UINTN        NumWords,
+  IN const UINT16 Value
+  );
+
+/**
+  Sets the specified number of memory dwords, a dword at a time, at the
+  specified destination.
+
+  @param[in, out] Dest      - Destination pointer.
+  @param[in]      NumDwords - The number of dwords to set.
+  @param[in]      Value     - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemDword (
+  IN OUT VOID     *Dest,
+  IN UINT32       NumDwords,
+  IN const UINT32 Value
+  );
+
+/**
+  Read 64 bits from the Memory Mapped I/O space.
+  Use MMX instruction for atomic access, because some MC registers have side effect.
+
+  @param[in] Address - Memory mapped I/O address.
+**/
+UINT64
+SaMmioRead64 (
+  IN  UINTN Address
+  );
+
+/**
+  Write 64 bits to the Memory Mapped I/O space.
+  Use MMX instruction for atomic access, because some MC registers have side effect.
+
+  @param[in] Address - Memory mapped I/O address.
+  @param[in] Value   - The value to write.
+**/
+UINT64
+SaMmioWrite64 (
+  IN UINTN Address,
+  IN UINT64 Value
+  );
+
+/**
+  Intel Silicon View Technology check point interface based on IO port reading
+
+  @param CheckPoint        Check point AH value.
+                           AH = 0x10:  End of MRC State
+                           AH = 0x20:  End of DXE State
+                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD)
+
+  @param PortReading       IO port reading address used for breakpoints
+**/
+VOID
+EFIAPI
+IsvtCheckPoint (
+  IN UINT32          CheckPoint,
+  IN UINT32          PortReading
+  );
+
+/**
+  Gets the current memory voltage (VDD).
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+
+  @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
+**/
+UINT32
+GetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd
+  );
+
+/**
+  Sets the memory voltage (VDD) to the specified value.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+  @param[in] Voltage    - The new memory voltage to set.
+
+  @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
+**/
+UINT32
+SetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd,
+  IN UINT32   Voltage
+  );
+
+/**
+  Check point that is called at various points in the MRC.
+
+  @param[in] GlobalData - MRC global data.
+  @param[in] Command    - OEM command.
+  @param[in] Pointer    - Command specific data.
+
+  @retval MrcStatus value.
+**/
+UINT32
+CheckPoint (
+  VOID   *GlobalData,
+  UINT32 Command,
+  VOID   *Pointer
+  );
+
+/**
+  Typically used to display to the I/O port 80h.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] DisplayDebugNumber - the number to display on port 80.
+
+  @retval Nothing.
+**/
+VOID
+DebugHook (
+  VOID          *GlobalData,
+  UINT16        DisplayDebugNumber
+  );
+
+/**
+  Hook to take any action after returning from MrcStartMemoryConfiguration()
+  and prior to taking any action regarding MrcStatus.  Pre-populated with issuing
+  Intel Silicon View Technology (ISVT) checkpoint 0x01.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] MrcStatus          - Mrc status variable
+**/
+VOID
+ReturnFromSmc (
+  VOID          *GlobalData,
+  UINT32        MrcStatus
+  );
+
+/**
+  Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+
+  @param[in] PciEBaseAddress  - PCI express base address.
+  @param[in] ResetValue       - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
+**/
+VOID
+SaDramReset (
+  IN UINT32 PciEBaseAddress,
+  IN UINT32 ResetValue
+  );
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
new file mode 100644
index 0000000000..124ca6a57f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
@@ -0,0 +1,39 @@
+/** @file
+  Header file for the PeiSaPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_LIBRARY_H_
+#define _PEI_SA_POLICY_LIBRARY_H_
+
+#include <CpuRegs.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/SiConfigBlockLib.h>
+
+/**
+  SaLoadSamplePolicyPreMem - Load some policy default for reference board.
+
+  @param[in] ConfigBlockTableAddress    The pointer for SA config blocks
+
+**/
+VOID
+SaLoadSamplePolicyPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+#endif // _PEI_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
new file mode 100644
index 0000000000..0e8d518fe7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
@@ -0,0 +1,473 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeSaPolicyLibrary.h"
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_ASPM_OVERRIDE_LIST mPcieAspmDevsOverride[] = {
+  {0x8086, 0x108b, 0xff, 2, 2},           ///< Tekoa w/o iAMT
+  {0x8086, 0x108c, 0x00, 0, 0},           ///< Tekoa A2
+  {0x8086, 0x108c, 0xff, 2, 2},           ///< Tekoa others
+  {0x8086, 0x109a, 0xff, 2, 2},           ///< Vidalia
+  {0x8086, 0x4222, 0xff, 2, 3},           ///< 3945ABG
+  {0x8086, 0x4227, 0xff, 2, 3},           ///< 3945ABG
+  {0x8086, 0x4228, 0xff, 2, 3},           ///< 3945ABG
+  ///
+  /// Place structures for known bad OEM/IHV devices here
+  ///
+  {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}  ///< End of table
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_LTR_DEV_INFO mPcieLtrDevsOverride[] = {
+  ///
+  /// Place holder for PCIe devices with correct LTR requirements
+  ///
+  {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}  ///< End of table
+};
+
+extern EFI_GUID gGraphicsDxeConfigGuid;
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gMiscDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+extern EFI_GUID gVbiosDxeConfigGuid;
+
+/**
+  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;
+  GRAPHICS_DXE_CONFIG         *GraphicsDxeConfig;
+  PCIE_DXE_CONFIG             *PcieDxeConfig;
+  MISC_DXE_CONFIG             *MiscDxeConfig;
+  MEMORY_DXE_CONFIG           *MemoryDxeConfig;
+  VBIOS_DXE_CONFIG            *VbiosDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gVbiosDxeConfigGuid, (VOID *)&VbiosDxeConfig);
+  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] :", SA_MC_MAX_SOCKETS));
+  for (i = 0; i < SA_MC_MAX_SOCKETS; 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, "------------------------ SA_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, " PegAspmL0s[%d] :", SA_PEG_MAX_FUN));
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspmL0s[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"));
+
+  if (PcieDxeConfig->PcieAspmDevsOverride != NULL) {
+    DEBUG ((DEBUG_INFO, "------------------------ PCIE_ASPM_OVERRIDE_LIST -----------------\n"));
+    DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId RootApmcMask EndpointApmcMask\n"));
+    i = 0;
+    while ((PcieDxeConfig->PcieAspmDevsOverride[i].VendorId != SA_PCIE_DEV_END_OF_TABLE) &&
+           (i < MAX_PCIE_ASPM_OVERRIDE)) {
+      DEBUG ((DEBUG_INFO, " %04x     %04x     %02x    %01x            %01x\n",
+              PcieDxeConfig->PcieAspmDevsOverride[i].VendorId,
+              PcieDxeConfig->PcieAspmDevsOverride[i].DeviceId,
+              PcieDxeConfig->PcieAspmDevsOverride[i].RevId,
+              PcieDxeConfig->PcieAspmDevsOverride[i].RootApmcMask,
+              PcieDxeConfig->PcieAspmDevsOverride[i].EndpointApmcMask));
+      i++;
+    }
+    DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE -----------------------\n"));
+  }
+  if (PcieDxeConfig->PcieLtrDevsOverride != NULL) {
+    DEBUG ((DEBUG_INFO, "------------------------ PCIE_LTR_DEV_INFO -----------------\n"));
+    DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId SnoopLatency NonSnoopLatency\n"));
+    i = 0;
+    while ((PcieDxeConfig->PcieLtrDevsOverride[i].VendorId != SA_PCIE_DEV_END_OF_TABLE) &&
+           (i < MAX_PCIE_LTR_OVERRIDE)) {
+      DEBUG ((DEBUG_INFO, " %04x     %04x     %02x    %01x            %01x\n",
+              PcieDxeConfig->PcieLtrDevsOverride[i].VendorId,
+              PcieDxeConfig->PcieLtrDevsOverride[i].DeviceId,
+              PcieDxeConfig->PcieLtrDevsOverride[i].RevId,
+              PcieDxeConfig->PcieLtrDevsOverride[i].SnoopLatency,
+              PcieDxeConfig->PcieLtrDevsOverride[i].NonSnoopLatency));
+      i++;
+    }
+    DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE ----------------------\n"));
+  }
+
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrEnable            : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrEnable));
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxSnoopLatency   : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrMaxSnoopLatency));
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].ObffEnable           : %x\n", i, PcieDxeConfig->PegPwrOpt[i].ObffEnable));
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxNoSnoopLatency : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrMaxNoSnoopLatency));
+  }
+
+
+  if (VbiosDxeConfig != NULL) {
+    DEBUG ((DEBUG_INFO, "------------------------ SA_SG_VBIOS_CONFIGURATION -----------------\n"));
+    DEBUG ((DEBUG_INFO, " LoadVbios    : %x\n", VbiosDxeConfig->LoadVbios));
+    DEBUG ((DEBUG_INFO, " ExecuteVbios : %x\n", VbiosDxeConfig->ExecuteVbios));
+    DEBUG ((DEBUG_INFO, " VbiosSource  : %x\n", VbiosDxeConfig->VbiosSource));
+  }
+
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_CONFIGURATION -----------------\n"));
+  DEBUG ((DEBUG_INFO, " EnableAbove4GBMmio : %x\n", MiscDxeConfig->EnableAbove4GBMmio));
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+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%
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadPcieDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  UINT8                  pegFn;
+  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 (pegFn = 0; pegFn < SA_PEG_MAX_FUN; pegFn++) {
+    PcieDxeConfig->PegAspm[pegFn]       = PcieAspmAutoConfig;
+    PcieDxeConfig->PegAspmL0s[pegFn]    = 0;
+  }
+
+  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;
+  }
+
+  PcieDxeConfig->PcieAspmDevsOverride = mPcieAspmDevsOverride;
+  PcieDxeConfig->PcieLtrDevsOverride = mPcieLtrDevsOverride;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadMiscDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  MISC_DXE_CONFIG        *MiscDxeConfig;
+
+  MiscDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Name = %g\n", &MiscDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// RMRR Base and Limit Address for USB
+  ///
+  MiscDxeConfig->RmrrUsbBaseAddress = AllocateZeroPool (sizeof (EFI_PHYSICAL_ADDRESS) * 2);
+  ASSERT (MiscDxeConfig->RmrrUsbBaseAddress != NULL);
+  if (MiscDxeConfig->RmrrUsbBaseAddress != NULL) {
+    ///
+    /// BIOS must update USB RMRR base address
+    ///
+    MiscDxeConfig->RmrrUsbBaseAddress[0] = 0;
+    MiscDxeConfig->RmrrUsbBaseAddress[1] = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+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;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadVbiosDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  VBIOS_DXE_CONFIG        *VbiosDxeConfig;
+
+  VbiosDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Name = %g\n", &VbiosDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", VbiosDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// Initialize the SG VBIOS DXE Policies
+  ///
+  ///
+  /// 1 = secondary display device VBIOS Source is PCI Card
+  /// 0 = secondary display device VBIOS Source is FW Volume
+  ///
+  VbiosDxeConfig->VbiosSource = 1;
+  return EFI_SUCCESS;
+}
+
+/**
+  LoadSaDxeConfigBlockDefault - Initialize default settings for each SA Config block
+
+  @param[in] ConfigBlockPointer         The buffer pointer that will be initialized as specific config block
+  @param[in] BlockId                    Request to initialize defaults of specified config block by given Block ID
+
+  @retval EFI_SUCCESS                   The given buffer has contained the defaults of requested config block
+  @retval EFI_NOT_FOUND                 Block ID is not defined so no default Config block will be initialized
+**/
+EFI_STATUS
+EFIAPI
+LoadSaDxeConfigBlockDefault (
+  IN   VOID          *ConfigBlockPointer,
+  IN   EFI_GUID      BlockGuid
+  )
+{
+  if (CompareGuid (&BlockGuid, &gGraphicsDxeConfigGuid)) {
+    LoadIgdDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gMiscDxeConfigGuid)) {
+    LoadMiscDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gPcieDxeConfigGuid)) {
+    LoadPcieDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gMemoryDxeConfigGuid)) {
+    LoadMemoryDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gVbiosDxeConfigGuid)) {
+    LoadVbiosDxeDefault (ConfigBlockPointer);
+  } else {
+    return EFI_NOT_FOUND;
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  CreateSaDxeConfigBlocks generates the config blocksg 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;
+  UINT16                            TotalBlockCount;
+  UINT16                            BlockCount;
+  VOID                              *ConfigBlockPointer;
+  EFI_STATUS                        Status;
+  SA_POLICY_PROTOCOL                *SaInitPolicy;
+  UINT16                            RequiredSize;
+  STATIC CONFIG_BLOCK_HEADER        SaDxeIpBlocks [] = {
+       {{{0, sizeof (GRAPHICS_DXE_CONFIG),    0},  {0}},     GRAPHICS_DXE_CONFIG_REVISION,           0, {0, 0}},
+       {{{0, sizeof (MEMORY_DXE_CONFIG), 0},  {0}},     MEMORY_DXE_CONFIG_REVISION,        0, {0, 0}},
+       {{{0, sizeof (MISC_DXE_CONFIG),   0},  {0}},     MISC_DXE_CONFIG_REVISION,          0, {0, 0}},
+       {{{0, sizeof (PCIE_DXE_CONFIG),   0},  {0}},     PCIE_DXE_CONFIG_REVISION,          0, {0, 0}},
+       {{{0, sizeof (VBIOS_DXE_CONFIG),  0},  {0}},     VBIOS_DXE_CONFIG_REVISION,         0, {0, 0}}
+  };
+
+  SaInitPolicy = NULL;
+  TotalBlockCount = sizeof (SaDxeIpBlocks) / sizeof (CONFIG_BLOCK_HEADER);
+  DEBUG ((DEBUG_INFO, "TotalBlockCount = 0x%x\n", TotalBlockCount));
+
+  TotalBlockSize = 0;
+  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
+    TotalBlockSize += (UINT32) SaDxeIpBlocks[BlockCount].GuidHob.Header.HobLength;
+    DEBUG ((DEBUG_INFO, "TotalBlockSize after adding  Block[0x%x]= 0x%x\n", BlockCount, TotalBlockSize));
+  }
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Initalize SklSaIpBlocks table GUID
+  //
+  CopyMem (&SaDxeIpBlocks[0].GuidHob.Name,  &gGraphicsDxeConfigGuid, sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[1].GuidHob.Name,  &gMemoryDxeConfigGuid,   sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[2].GuidHob.Name,  &gMiscDxeConfigGuid,     sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[3].GuidHob.Name,  &gPcieDxeConfigGuid,     sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[4].GuidHob.Name,  &gVbiosDxeConfigGuid,    sizeof (EFI_GUID));
+
+  //
+  // Initialize Policy Revision
+  //
+  SaInitPolicy->TableHeader.Header.Revision = SA_POLICY_PROTOCOL_REVISION;
+  //
+  // Initialize ConfigBlockPointer to NULL
+  //
+  ConfigBlockPointer = NULL;
+  //
+  // Loop to identify each config block from SaDxeIpBlocks[] Table and add each of them
+  //
+  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
+    ConfigBlockPointer = (VOID *)&SaDxeIpBlocks[BlockCount];
+    Status = AddConfigBlock ((VOID *) SaInitPolicy, (VOID *)&ConfigBlockPointer);
+    ASSERT_EFI_ERROR (Status);
+    LoadSaDxeConfigBlockDefault ((VOID *) ConfigBlockPointer, SaDxeIpBlocks[BlockCount].GuidHob.Name);
+  }
+  //
+  // Assignment for returning SaPolicy config block base address
+  //
+  *SaPolicy = SaInitPolicy;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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);
+
+  ///
+  /// 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/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
new file mode 100644
index 0000000000..fc6e469ae3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
@@ -0,0 +1,128 @@
+/** @file
+  SA Platform Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaPlatformLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <SaRegs.h>
+#include <Library/CpuPlatformLib.h>
+
+/**
+  Determine if PCH Link is DMI/OPI
+
+  @param[in] CpuModel             CPU model
+
+  @retval TRUE                    DMI
+  @retval FALSE                   OPI
+**/
+BOOLEAN
+IsPchLinkDmi (
+  IN CPU_FAMILY  CpuModel
+  )
+{
+  if ((CpuModel == EnumCpuCflDtHalo) || (CpuModel == EnumCpuCnlDtHalo)) {
+    return TRUE; // DMI
+  }
+  return FALSE;  // OPI
+}
+
+
+/**
+  Returns the number of DMI lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiLanes (
+  )
+{
+    return SA_DMI_CFL_MAX_LANE;
+}
+
+
+/**
+  Returns the number of DMI bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiBundles (
+  )
+{
+    return SA_DMI_CFL_MAX_BUNDLE;
+}
+
+
+/**
+  Returns the function numbers for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegFuncs (
+  )
+{
+  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
+    return SA_PEG_CNL_H_MAX_FUN;
+  } else {
+    return SA_PEG_NON_CNL_H_MAX_FUN;
+  }
+}
+
+
+/**
+  Returns the number of PEG lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegLanes (
+  )
+{
+  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
+    return SA_PEG_CNL_H_MAX_LANE;
+  } else {
+    return SA_PEG_NON_CNL_H_MAX_LANE;
+  }
+}
+
+
+/**
+  Returns the number of PEG bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegBundles (
+  )
+{
+  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
+    return  SA_PEG_CNL_H_MAX_BUNDLE;
+  } else {
+    return  SA_PEG_NON_CNL_H_MAX_BUNDLE;
+  }
+}
+
+/**
+  Checks if PEG port is present
+
+  @retval TRUE     PEG is presented
+  @retval FALSE    PEG is not presented
+**/
+BOOLEAN
+IsPegPresent (
+  VOID
+  )
+{
+  UINT64  PegBaseAddress;
+
+  PegBaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, 0, 0);
+  if (PciSegmentRead16 (PegBaseAddress) != 0xFFFF) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
new file mode 100644
index 0000000000..b7aec77842
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
@@ -0,0 +1,745 @@
+/** @file
+  This file is SampleCode for Intel SA PEI Policy initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "MrcOemPlatform.h"
+#include <Library/CpuPlatformLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmbusLib.h>
+#include <PchAccess.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+
+#pragma pack (push, 1)
+typedef union {
+  struct {
+    UINT32                         : 8;
+    UINT32 MAX_NON_TURBO_LIM_RATIO : 8;
+    UINT32                         : 16;
+    UINT32                         : 32;
+  } Bits;
+  UINT64 Data;
+  UINT32 Data32[2];
+  UINT16 Data16[4];
+  UINT8  Data8[8];
+} PCU_CR_PLATFORM_INFO_STRUCT;
+
+#pragma pack (pop)
+
+#define SA_SYSTEM_BCLK                (100)
+#define PCU_CR_PLATFORM_INFO          (0xCE)
+#define MRC_POST_CODE_LOW_BYTE_ADDR   (0x48)
+#define MRC_POST_CODE_HIGH_BYTE_ADDR  (0x49)
+#define MAX_SPD_PAGE_COUNT            (2)
+#define MAX_SPD_PAGE_SIZE             (256)
+#define MAX_SPD_DDR3_SIZE             (MAX_SPD_PAGE_SIZE * 1)
+#define MAX_SPD_DDR4_SIZE             (MAX_SPD_PAGE_SIZE * 2)
+#define MAX_SPD_SIZE                  (MAX_SPD_PAGE_SIZE * MAX_SPD_PAGE_COUNT)
+#define SPD_PAGE_ADDRESS_0            (0x6C)
+#define SPD_PAGE_ADDRESS_1            (0x6E)
+#define SPD_DDR3_XMP_OFFSET           (176)
+#define SPD_DDR4_XMP_OFFSET           (384)
+#define SPD_DDR3_SDRAM_TYPE_OFFSET    (0x02)
+#define SPD_DDR3_SDRAM_TYPE_NUMBER    (0x0B)
+#define SPD_DDR4_SDRAM_TYPE_NUMBER    (0x0C)
+#define SPD_LPDDR3_SDRAM_TYPE_NUMBER  (0x0F)
+#define SPD_LPDDR4_SDRAM_TYPE_NUMBER  (0x10)
+#define SPD_LPDDR4X_SDRAM_TYPE_NUMBER (0x11)
+#define ISVT_END_OF_MRC_STATE         (0x10)
+
+/**
+  Read the SPD data over the SMBus, at the specified SPD address, starting at
+  the specified starting offset and read the given amount of data.
+
+  @param[in] SpdAddress  - SPD SMBUS address
+  @param[in, out] Buffer - Buffer to store the data.
+  @param[in] Start       - Starting SPD offset
+  @param[in] Size        - The number of bytes of data to read and also the size of the buffer.
+  @param[in, out] Page   - The final page that is being pointed to.
+
+  @retval RETURN_SUCCESS if the read is successful, otherwise error status.
+**/
+static
+RETURN_STATUS
+DoSpdRead (
+  IN     const UINT8  SpdAddress,
+  IN OUT UINT8        *const Buffer,
+  IN     const UINT16 Start,
+  IN           UINT16 Size,
+  IN OUT UINT8        *const Page
+  )
+{
+  RETURN_STATUS EfiStatus;
+  BOOLEAN       PageUpdate;
+  UINT16        Count;
+  UINT16        Index;
+
+  EfiStatus = RETURN_DEVICE_ERROR;
+  if ((Buffer != NULL) && (Start < MAX_SPD_SIZE) && ((Start + Size) < MAX_SPD_SIZE)) {
+    Count = 0;
+    PageUpdate = FALSE;
+    while (Size--) {
+      Index = Start + Count;
+      if ((Index / MAX_SPD_PAGE_SIZE) != *Page) {
+        *Page = (UINT8) (Index / MAX_SPD_PAGE_SIZE);
+        PageUpdate = TRUE;
+      }
+      Index %= MAX_SPD_PAGE_SIZE;
+      if (PageUpdate == TRUE) {
+        PageUpdate = FALSE;
+        SmBusWriteDataByte ((*Page == 0) ? SPD_PAGE_ADDRESS_0 : SPD_PAGE_ADDRESS_1, 0, &EfiStatus);
+      }
+      Buffer[Count] = SmBusReadDataByte (SpdAddress | ((UINT32) Index << 8), &EfiStatus);
+      if (RETURN_SUCCESS != EfiStatus) {
+        Buffer[Count] = 0;
+        break;
+      }
+      Count++;
+    }
+    EfiStatus = RETURN_SUCCESS;
+  }
+  return (EfiStatus);
+}
+
+/**
+  See if there is valid XMP SPD data.
+
+  @param[in] Debug    - Mrc debug structure.
+  @param[in, out] Spd - Mrc SPD structure.
+  @param[in] XmpStart - The current offset in the SPD.
+
+  @retval TRUE if valid, FALSE in not.
+**/
+static
+BOOLEAN
+VerifyXmp (
+  IN OUT MrcSpd *const Spd,
+  IN const UINT16 XmpStart
+  )
+{
+  SPD_EXTREME_MEMORY_PROFILE_HEADER      *Header1;
+  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0  *Header2;
+  BOOLEAN                                 Xmp;
+
+  Xmp = FALSE;
+
+  switch (((UINT8 *) Spd) [2]) {
+    case SPD_DDR3_SDRAM_TYPE_NUMBER:
+      Header1 = &Spd->Ddr3.Xmp.Header;
+      if (XmpStart == ((UINT32) (Header1) - (UINT32) Spd)) {
+        Xmp = TRUE;
+        if ((Header1->XmpRevision.Data & 0xFE) == 0x12) {
+          return (TRUE);
+        } else {
+          Header1->XmpId            = 0;
+          Header1->XmpOrgConf.Data  = 0;
+          Header1->XmpRevision.Data = 0;
+        }
+      }
+      break;
+    case SPD_DDR4_SDRAM_TYPE_NUMBER:
+      Header2 = &Spd->Ddr4.EndUser.Xmp.Header;
+      if (XmpStart == ((UINT32) (Header2) - (UINT32) Spd)) {
+        Xmp = TRUE;
+        if ((Header2->XmpRevision.Data) == 0x20) {
+          return (TRUE);
+        } else {
+          Header2->XmpId            = 0;
+          Header2->XmpOrgConf.Data  = 0;
+          Header2->XmpRevision.Data = 0;
+        }
+      }
+      break;
+    case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
+    case SPD_LPDDR4_SDRAM_TYPE_NUMBER:
+    case SPD_LPDDR4X_SDRAM_TYPE_NUMBER:
+      return (TRUE);
+    default:
+      return (FALSE);
+  }
+  if (!Xmp) {
+    return (TRUE);
+  }
+  return (FALSE);
+}
+
+/**
+  Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+  The SPD data locations read is controlled by the current boot mode.
+
+  @param[in] BootMode           - The current MRC boot mode.
+  @param[in] Address            - SPD SmBus address offset.
+  @param[in] Buffer             - Buffer that contains the data read from the SPD.
+  @param[in] SpdDdr3Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr3TableSize   - Size of SpdDdr3Table in bytes.
+  @param[in] SpdDdr4Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr4TableSize   - Size of SpdDdr4Table in bytes.
+  @param[in] SpdLpddrTable      - Indicates which SPD bytes to read.
+  @param[in] SpdLpddrTableSize  - Size of SpdLpddrTable in bytes.
+
+  @retval TRUE if the read is successful, otherwise FALSE on error.
+**/
+BOOLEAN
+GetSpdData (
+  IN SPD_BOOT_MODE BootMode,
+  IN UINT8         Address,
+  IN OUT   UINT8   *Buffer,
+  IN UINT8         *SpdDdr3Table,
+  IN UINT32        SpdDdr3TableSize,
+  IN UINT8         *SpdDdr4Table,
+  IN UINT32        SpdDdr4TableSize,
+  IN UINT8         *SpdLpddrTable,
+  IN UINT32        SpdLpddrTableSize
+  )
+{
+  const SPD_OFFSET_TABLE *Tbl;
+  const SPD_OFFSET_TABLE *TableSelect;
+  RETURN_STATUS          Status;
+  UINT32                 Byte;
+  UINT32                 Stop;
+  UINT8                  Page;
+
+  Page   = (UINT8) (~0);
+  Status = DoSpdRead (Address, &Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET], 2, 1, &Page);
+  if (RETURN_SUCCESS == Status) {
+    switch (Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET]) {
+      case SPD_DDR3_SDRAM_TYPE_NUMBER:
+      default:
+        TableSelect = (SPD_OFFSET_TABLE *) SpdDdr3Table;
+        Stop = (SpdDdr3TableSize / sizeof (SPD_OFFSET_TABLE));
+        break;
+      case SPD_DDR4_SDRAM_TYPE_NUMBER:
+        TableSelect = (SPD_OFFSET_TABLE *) SpdDdr4Table;
+        Stop = (SpdDdr4TableSize / sizeof (SPD_OFFSET_TABLE));
+        break;
+      case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
+      case SPD_LPDDR4_SDRAM_TYPE_NUMBER:
+      case SPD_LPDDR4X_SDRAM_TYPE_NUMBER:
+        TableSelect = (SPD_OFFSET_TABLE *) SpdLpddrTable;
+        Stop = (SpdLpddrTableSize / sizeof (SPD_OFFSET_TABLE));
+        break;
+    }
+    for (Byte = 0; (RETURN_SUCCESS == Status) && (Byte < Stop); Byte++) {
+      Tbl = &TableSelect[Byte];
+      if ((1 << BootMode) & Tbl->BootMode) {
+        Status = DoSpdRead (Address, &Buffer[Tbl->Start], Tbl->Start, Tbl->End - Tbl->Start + 1, &Page);
+        if (Status == RETURN_SUCCESS) {
+          if (SpdCold == BootMode) {
+            if (FALSE == VerifyXmp ((MrcSpd *) Buffer, Tbl->Start)) {
+              break;
+            }
+          }
+        } else {
+          break;
+        }
+      }
+    }
+  }
+
+  return ((RETURN_SUCCESS == Status) ? TRUE : FALSE);
+}
+
+//
+// This is from MdeModulePkg\Include\Guid\StatusCodeDataTypeDebug.h
+// Might need to be adjusted for a particular BIOS core
+//
+#ifndef EFI_STATUS_CODE_DATA_MAX_SIZE
+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
+#endif
+
+/**
+  Output a string to the debug stream/device.
+  If there is a '%' sign in the string, convert it to '%%', so that DEBUG() macro will print it properly.
+
+  @param[in] String     - The string to output.
+
+  @retval Nothing.
+**/
+VOID
+SaDebugPrint (
+  VOID   *String
+  )
+{
+  CHAR8   Str[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  CHAR8   *InputStr;
+  CHAR8   *OutputStr;
+  UINT32  i;
+
+  InputStr = (CHAR8 *) String;
+  OutputStr = Str;
+  i = 0;
+  while (*InputStr != 0) {
+    if (i < (EFI_STATUS_CODE_DATA_MAX_SIZE - 2)) {
+      *OutputStr++ = *InputStr;
+      i++;
+      if (*InputStr++ == '%') {
+        *OutputStr++ = '%';
+        i++;
+      }
+    }
+  }
+  *OutputStr = 0;  // Terminating NULL
+  DEBUG ((DEBUG_INFO, Str));
+  return;
+}
+
+/**
+  Calculate the PCI device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+  @retval The PCI device address.
+**/
+UINT32
+GetPciDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  )
+{
+  return (
+    ((UINT32) ((Bus)      & 0xFF) << 16) |
+    ((UINT32) ((Device)   & 0x1F) << 11) |
+    ((UINT32) ((Function) & 0x07) << 8)  |
+    ((UINT32) ((Offset)   & 0xFF) << 0)  |
+    (1UL << 31));
+}
+
+/**
+  Calculate the PCIE device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+   The PCIE device address.
+
+  @retval The PCIe device address
+**/
+UINT32
+GetPcieDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  )
+{
+  return (
+    ((UINT32) Bus << 20) +
+    ((UINT32) Device << 15) +
+    ((UINT32) Function << 12) +
+    ((UINT32) Offset << 0));
+}
+
+/**
+  Read specific RTC/CMOS RAM
+
+  @param[in] Location        Point to RTC/CMOS RAM offset for read
+
+  @retval The data of specific location in RTC/CMOS RAM.
+**/
+UINT8
+PeiRtcRead (
+  IN const UINT8 Location
+  )
+{
+  UINT8  RtcIndexPort;
+  UINT8  RtcDataPort;
+
+  //
+  // CMOS access registers (using alternative access not to handle NMI bit)
+  //
+  if (Location < RTC_BANK_SIZE) {
+    //
+    // First bank
+    //
+    RtcIndexPort  = R_RTC_IO_INDEX_ALT;
+    RtcDataPort   = R_RTC_IO_TARGET_ALT;
+  } else {
+    //
+    // Second bank
+    //
+    RtcIndexPort  = R_RTC_IO_EXT_INDEX_ALT;
+    RtcDataPort   = R_RTC_IO_EXT_TARGET_ALT;
+  }
+
+  IoWrite8 (RtcIndexPort, Location & RTC_INDEX_MASK);
+  return IoRead8 (RtcDataPort);
+}
+
+/**
+  Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
+  Since RTC time is stored in BCD, convert each value to binary.
+
+  @param[out] Seconds       - The current second (0-59).
+  @param[out] Minutes       - The current minute (0-59).
+  @param[out] Hours         - The current hour (0-23).
+  @param[out] DayOfMonth    - The current day of the month (1-31).
+  @param[out] Month         - The current month (1-12).
+  @param[out] Year          - The current year (2000-2099).
+
+  @retval Nothing.
+**/
+VOID
+GetRtcTime (
+  OUT UINT8  *const Seconds,
+  OUT UINT8  *const Minutes,
+  OUT UINT8  *const Hours,
+  OUT UINT8  *const DayOfMonth,
+  OUT UINT8  *const Month,
+  OUT UINT16 *const Year
+  )
+{
+  UINT32 Timeout;
+
+  //
+  // Wait until RTC "update in progress" bit goes low.
+  //
+  Timeout = 0x0FFFFF;
+  do {
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
+    if ((IoRead8 (RTC_TARGET_REGISTER) & RTC_UPDATE_IN_PROGRESS) != RTC_UPDATE_IN_PROGRESS) {
+      break;
+    }
+  } while (--Timeout > 0);
+
+  if (0 == Timeout) {
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
+    IoWrite8 (RTC_TARGET_REGISTER, RTC_HOLD | RTC_MODE_24HOUR);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
+    IoWrite8 (RTC_TARGET_REGISTER, RTC_CLOCK_DIVIDER | RTC_RATE_SELECT);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGC);
+    IoRead8 (RTC_TARGET_REGISTER);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGD);
+    IoRead8 (RTC_TARGET_REGISTER);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
+    IoWrite8 (RTC_TARGET_REGISTER, RTC_MODE_24HOUR);
+  }
+  //
+  // Read seconds
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_SECONDS);
+  *Seconds = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read minutes
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_MINUTES);
+  *Minutes = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read hours
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_HOURS);
+  *Hours = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read day of month
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_DAY_OF_MONTH);
+  *DayOfMonth = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read month
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_MONTH);
+  *Month = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read year and add current century.
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_YEAR);
+  *Year = IoRead8 (RTC_TARGET_REGISTER);
+
+  *Seconds    = BCD2BINARY (*Seconds);
+  *Minutes    = BCD2BINARY (*Minutes);
+  *Hours      = BCD2BINARY (*Hours);
+  *DayOfMonth = BCD2BINARY (*DayOfMonth);
+  *Month      = BCD2BINARY (*Month);
+  *Year       = BCD2BINARY (*Year) + CENTURY_OFFSET;
+}
+
+/**
+  Gets CPU current time.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+
+  @retval The current CPU time in milliseconds.
+**/
+UINT64
+GetCpuTime (
+  IN VOID         *GlobalData
+  )
+{
+  MrcParameters               *MrcData;
+  MrcInput                    *Inputs;
+  PCU_CR_PLATFORM_INFO_STRUCT Msr;
+  UINT32                      TimeBase;
+
+  MrcData   = (MrcParameters *) GlobalData;
+  Inputs    = &MrcData->Inputs;
+
+  Msr.Data = AsmReadMsr64 (PCU_CR_PLATFORM_INFO);
+  TimeBase = (Inputs->BClkFrequency / 1000) * Msr.Bits.MAX_NON_TURBO_LIM_RATIO; //In Millisec
+  return ((TimeBase == 0) ? 0 : DivU64x32 (AsmReadTsc (), TimeBase));
+}
+
+/**
+  Sets the specified number of memory words, a word at a time, at the
+  specified destination.
+
+  @param[in, out] Dest     - Destination pointer.
+  @param[in]      NumWords - The number of dwords to set.
+  @param[in]      Value    - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemWord (
+  IN OUT VOID     *Dest,
+  IN UINTN        NumWords,
+  IN const UINT16 Value
+  )
+{
+  UINT16 *Buffer;
+
+  Buffer = (UINT16 *) Dest;
+  while (0 != NumWords--) {
+    *Buffer++ = Value;
+  }
+
+  return (Dest);
+}
+
+/**
+  Sets the specified number of memory dwords, a dword at a time, at the
+  specified destination.
+
+  @param[in, out] Dest      - Destination pointer.
+  @param[in]      NumDwords - The number of dwords to set.
+  @param[in]      Value     - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemDword (
+  IN OUT VOID     *Dest,
+  IN UINT32       NumDwords,
+  IN const UINT32 Value
+  )
+{
+  UINT32 *Buffer;
+
+  Buffer = (UINT32 *) Dest;
+  while (0 != NumDwords--) {
+    *Buffer++ = Value;
+  }
+
+  return (Dest);
+}
+
+
+/**
+  Gets the current memory voltage (VDD).
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+
+  @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
+**/
+UINT32
+GetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd
+  )
+{
+  UINT32          CurrentVoltage;
+
+  CurrentVoltage = DefaultVdd;
+
+  return CurrentVoltage;
+}
+
+/**
+  Sets the memory voltage (VDD) to the specified value.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+  @param[in] Voltage    - The new memory voltage to set.
+
+  @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
+**/
+UINT32
+SetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd,
+  IN UINT32   Voltage
+  )
+{
+
+  return Voltage;
+}
+
+/**
+  This function is used by the OEM to do a dedicated task during the MRC.
+
+  @param[in] GlobalData        - include all the MRC data
+  @param[in] OemStatusCommand  - A command that indicates the task to perform.
+  @param[in] Pointer           - general ptr for general use.
+
+  @retval The status of the task.
+**/
+MrcStatus
+CheckPoint (
+  IN VOID                *GlobalData,
+  IN MrcOemStatusCommand OemStatusCommand,
+  IN VOID                *Pointer
+  )
+{
+  MrcParameters                *MrcData;
+  MrcInput                     *Inputs;
+  MrcStatus                    Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+  MEMORY_CONFIG_NO_CRC         *MemConfigNoCrc;
+  EFI_STATUS                   Status1;
+
+  //
+  // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform data
+  //
+  Status1 = PeiServicesLocatePpi (
+              &gSiPreMemPolicyPpiGuid,
+              0,
+              NULL,
+              (VOID **) &SiPreMemPolicyPpi
+              );
+  ASSERT_EFI_ERROR (Status1);
+
+  Status1 = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR (Status1);
+  MrcData             = (MrcParameters *) GlobalData;
+  Inputs              = &MrcData->Inputs;
+  SiPreMemPolicyPpi = (SI_PREMEM_POLICY_PPI *) Inputs->SiPreMemPolicyPpi;
+  Status              = mrcSuccess;
+
+  switch (OemStatusCommand) {
+    default:
+      break;
+  }
+
+  return (Status);
+}
+
+/**
+  Typically used to display to the I/O port 80h.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] DisplayDebugNumber - the number to display on port 80.
+
+  @retval Nothing.
+**/
+VOID
+DebugHook (
+  IN VOID       *GlobalData,
+  UINT16        DisplayDebugNumber
+  )
+{
+  MrcParameters                *MrcData;
+  MrcOutput                    *Outputs;
+  MrcDebug                     *Debug;
+  EFI_STATUS                   Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+  SA_MISC_PEI_PREMEM_CONFIG    *MiscPeiPreMemConfig;
+
+  MrcData = (MrcParameters *) GlobalData;
+  Outputs = &MrcData->Outputs;
+  Debug   = &Outputs->Debug;
+
+  Debug->PostCode[MRC_POST_CODE] = DisplayDebugNumber;
+  IoWrite16 (0x80, DisplayDebugNumber);
+  DEBUG ((DEBUG_INFO, "Post Code: %04Xh\n", DisplayDebugNumber));
+
+  //
+  // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform data
+  //
+  Status = PeiServicesLocatePpi (&gSiPreMemPolicyPpiGuid, 0, NULL, (VOID **) &SiPreMemPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+  if (Status == EFI_SUCCESS) {
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+    if (Status == EFI_SUCCESS) {
+      //
+      // Put the Port80 code also here:
+      // #define BIOS_POST_CODE_PCU_CNL_REG          (0x00005824)
+      //
+      MmioWrite16 (MiscPeiPreMemConfig->MchBar + 0x5824, DisplayDebugNumber);
+    }
+  }
+  return;
+}
+
+/**
+  Hook to take any action after returning from MrcStartMemoryConfiguration()
+  and prior to taking any action regarding MrcStatus.  Pre-populated with issuing
+  Intel Silicon View Technology (ISVT) checkpoint 0x10.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] MrcStatus          - Mrc status variable
+**/
+void
+ReturnFromSmc (
+  IN VOID         *GlobalData,
+  IN UINT32       MrcStatus
+  )
+{
+  MrcInput        *Inputs;
+  MrcParameters   *MrcData;
+  UINT32          CheckPoint;
+  UINT32          PortReading;
+
+  MrcData   = (MrcParameters *) GlobalData;
+  Inputs    = &MrcData->Inputs;
+
+  DEBUG ((DEBUG_INFO, "Returned From MrcStartMemoryConfiguration(). MrcStatus = %08Xh\n", MrcStatus));
+
+  //
+  // Intel Silicon View Technology (ISVT) IO Reading port with EAX = 0x10 for End of MRC
+  //
+  CheckPoint = ISVT_END_OF_MRC_STATE;
+  PortReading = (UINT32) Inputs->IsvtIoPort;
+  IsvtCheckPoint (CheckPoint, PortReading);
+
+  return;
+}
+
+/**
+  Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+
+  @param[in] PciEBaseAddress  - PCI express base address.
+  @param[in] ResetValue       - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
+**/
+VOID
+SaDramReset (
+  IN UINT32 PciEBaseAddress,
+  IN UINT32 ResetValue
+  )
+{
+  PmcSetDramResetCtlState (ResetValue);
+
+  return;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
new file mode 100644
index 0000000000..2ac3543f93
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
@@ -0,0 +1,656 @@
+/** @file
+  This file provides services for PEI policy default initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyLibrary.h"
+#include <Library/GpioLib.h>
+#include <Library/CpuPlatformLib.h>
+#include "MrcInterface.h"
+#include <Library/PchInfoLib.h>
+
+#define DEFAULT_OPTION_ROM_TEMP_BAR            0x80000000
+#define DEFAULT_OPTION_ROM_TEMP_MEM_LIMIT      0xC0000000
+//
+// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
+//
+#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)    // 80MB + 256MB
+
+//
+// Function call to Load defaults for Individial IP Blocks
+//
+VOID
+LoadSaMiscPeiPreMemDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  SA_MISC_PEI_PREMEM_CONFIG            *MiscPeiPreMemConfig;
+
+  MiscPeiPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Name = %g\n", &MiscPeiPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Policy initialization commented out here is because it's the same with default 0 and no need to re-do again.
+  //
+  MiscPeiPreMemConfig->LockPTMregs                      = 1;
+
+  //
+  // Initialize the Platform Configuration
+  //
+  MiscPeiPreMemConfig->MchBar              = 0xFED10000;
+  MiscPeiPreMemConfig->DmiBar              = 0xFED18000;
+  MiscPeiPreMemConfig->EpBar               = 0xFED19000;
+  MiscPeiPreMemConfig->EdramBar            = 0xFED80000;
+  MiscPeiPreMemConfig->SmbusBar            = 0xEFA0;
+  MiscPeiPreMemConfig->TsegSize            = PcdGet32 (PcdTsegSize);
+  MiscPeiPreMemConfig->GdxcBar             = 0xFED84000;
+
+  //
+  // Initialize the Switchable Graphics Default Configuration
+  //
+  MiscPeiPreMemConfig->SgDelayAfterHoldReset = 100; //100ms
+  MiscPeiPreMemConfig->SgDelayAfterPwrEn     = 300; //300ms
+
+  ///
+  /// Initialize the DataPtr for S3 resume
+  ///
+  MiscPeiPreMemConfig->S3DataPtr = NULL;
+  MiscPeiPreMemConfig->OpRomScanTempMmioBar      = DEFAULT_OPTION_ROM_TEMP_BAR;
+  MiscPeiPreMemConfig->OpRomScanTempMmioLimit    = DEFAULT_OPTION_ROM_TEMP_MEM_LIMIT;
+}
+
+VOID
+LoadSaMiscPeiDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  SA_MISC_PEI_CONFIG        *MiscPeiConfig;
+
+  MiscPeiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "MiscPeiConfig->Header.GuidHob.Name = %g\n", &MiscPeiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MiscPeiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscPeiConfig->Header.GuidHob.Header.HobLength));
+
+  ///
+  /// EDRAM H/W Mode by default (0- EDRAM SW Disable, 1- EDRAM SW Enable, 2- EDRAM HW Mode)
+  ///
+  MiscPeiConfig->EdramTestMode = 2;
+
+  if (IsWhlCpu()) {
+    MiscPeiConfig->Device4Enable = 1;
+  }
+}
+
+VOID
+LoadVtdDefault (
+  IN VOID   *ConfigBlockPointer
+  )
+{
+  VTD_CONFIG   *Vtd;
+
+  Vtd = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Name = %g\n", &Vtd->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Header.HobLength = 0x%x\n", Vtd->Header.GuidHob.Header.HobLength));
+
+  //
+  // Initialize the Vtd Configuration
+  //
+  Vtd->VtdDisable      = 0;
+  Vtd->BaseAddress[0]  = 0xFED90000;
+  Vtd->BaseAddress[1]  = 0xFED92000;
+  Vtd->BaseAddress[2]  = 0xFED91000;
+}
+
+VOID
+LoadIpuPreMemDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  IPU_PREMEM_CONFIG      *IpuPreMemPolicy;
+
+  IpuPreMemPolicy = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "IpuPreMemPolicy->Header.GuidHob.Name = %g\n", &IpuPreMemPolicy->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "IpuPreMemPolicy->Header.GuidHob.Header.HobLength = 0x%x\n", IpuPreMemPolicy->Header.GuidHob.Header.HobLength));
+
+}
+
+VOID
+LoadPciePeiPreMemDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  UINT8                  Index;
+  PCIE_PEI_PREMEM_CONFIG *PciePeiPreMemConfig;
+
+  PciePeiPreMemConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "PciePeiPreMemConfig->Header.GuidHob.Name = %g\n", &PciePeiPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PciePeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PciePeiPreMemConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Initialize the PciExpress Configuration
+  //
+  PciePeiPreMemConfig->DmiGen3EqPh2Enable             = 2;
+  PciePeiPreMemConfig->DmiGen3ProgramStaticEq         = 1;
+  PciePeiPreMemConfig->Peg0Enable                     = 2;
+  PciePeiPreMemConfig->Peg1Enable                     = 2;
+  PciePeiPreMemConfig->Peg2Enable                     = 2;
+  PciePeiPreMemConfig->Peg3Enable                     = 2;
+  PciePeiPreMemConfig->Peg0PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg1PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg2PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg3PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg0Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->Peg1Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->Peg2Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->Peg3Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->PegGen3ProgramStaticEq         = 1;
+  PciePeiPreMemConfig->Gen3SwEqNumberOfPresets        = 2;
+  PciePeiPreMemConfig->Gen3SwEqEnableVocTest          = 2;
+
+  if (IsCnlPch() && IsPchH() && (PchStepping() == PCH_A0)) {
+    PciePeiPreMemConfig->DmiMaxLinkSpeed = 1;
+  }
+
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    PciePeiPreMemConfig->DmiGen3RootPortPreset[Index] = 4;
+    PciePeiPreMemConfig->DmiGen3EndPointPreset[Index] = 7;
+    PciePeiPreMemConfig->DmiGen3EndPointHint[Index]   = 2;
+  }
+  for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
+    ///
+    /// Gen3 RxCTLE peaking default is 0 for DMI
+    ///
+    PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index]  = 0;
+  }
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    PciePeiPreMemConfig->PegGen3RootPortPreset[Index] = 7;
+    PciePeiPreMemConfig->PegGen3EndPointPreset[Index] = 7;
+    PciePeiPreMemConfig->PegGen3EndPointHint[Index]   = 2;
+  }
+  PciePeiPreMemConfig->DmiDeEmphasis = 1;
+  ///
+  /// Gen3 Software Equalization Jitter Dwell Time:               1 msec
+  /// Gen3 Software Equalization Jitter Error Target:             1
+  /// Gen3 Software Equalization VOC    Dwell Time:               10 msec
+  /// Gen3 Software Equalization VOC    Error Target:             2
+  ///
+  PciePeiPreMemConfig->Gen3SwEqJitterDwellTime        = 3 * STALL_ONE_MILLI_SECOND;
+  PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget      = 2;
+  PciePeiPreMemConfig->Gen3SwEqVocDwellTime           = 10 * STALL_ONE_MILLI_SECOND;
+  PciePeiPreMemConfig->Gen3SwEqVocErrorTarget         = 2;
+
+  /**
+  Parameters for PCIe Gen3 device reset
+  @note Refer to the Platform Design Guide (PDG) for additional information about this GPIO.
+  **/
+  PciePeiPreMemConfig->PegGpioData.GpioSupport        = FALSE;
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad = 0;
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active  = FALSE;
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad = 0;
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active  = FALSE;
+}
+
+VOID
+LoadPciePeiDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  UINT8                Index;
+  PCIE_PEI_CONFIG      *PciePeiConfig;
+
+  PciePeiConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "PciePeiConfig->Header.GuidHob.Name = %g\n", &PciePeiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PciePeiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PciePeiConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Initialize the PciExpress Configuration
+  //
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PciePeiConfig->PegDeEmphasis[Index] = 1;
+    PciePeiConfig->PegMaxPayload[Index] = 0xFF;
+  }
+  ///
+  /// Slot Power Limit Value:   75 W
+  /// Slot Power Limit Scale:   1.0x
+  /// Physical Slot Number:     Peg Index + 1 (1,2,3)
+  ///
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PciePeiConfig->PegSlotPowerLimitValue[Index] = 75;
+    PciePeiConfig->PegPhysicalSlotNumber[Index] =  Index + 1;
+  }
+
+}
+
+VOID
+LoadGraphichsPeiPreMemDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  GRAPHICS_PEI_PREMEM_CONFIG                         *GtPreMemConfig;
+
+  GtPreMemConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GtPreMemConfig->Header.GuidHob.Name = %g\n", &GtPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GtPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GtPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  ///
+  /// Initialize Graphics Pre-Mem Configurations.
+  ///
+  GtPreMemConfig->GmAdr               = 0xD0000000;
+  GtPreMemConfig->GttMmAdr            = 0xCF000000;
+  GtPreMemConfig->GttSize             = 3;
+  GtPreMemConfig->IgdDvmt50PreAlloc   = 1;
+  GtPreMemConfig->InternalGraphics    = 2;
+  GtPreMemConfig->PrimaryDisplay      = 3;
+  GtPreMemConfig->ApertureSize        = SA_GT_APERTURE_SIZE_256MB;
+  GtPreMemConfig->PanelPowerEnable    = 1;
+}
+
+VOID
+LoadGraphichsPeiDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  GRAPHICS_PEI_CONFIG                         *GtConfig;
+
+  GtConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Name = %g\n", &GtConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GtConfig->Header.GuidHob.Header.HobLength));
+
+  //
+  // Initialize the Graphics configuration
+  //
+  GtConfig->RenderStandby       = 1;
+  GtConfig->PavpEnable          = 1;
+  GtConfig->PmSupport           = 1;
+  GtConfig->CdynmaxClampEnable  = 1;
+  GtConfig->GtFreqMax           = 0xFF;
+  //
+  // Initialize the default VBT settings
+  //
+  GtConfig->DdiConfiguration.DdiPortEdp  = 1;
+  GtConfig->DdiConfiguration.DdiPortBHpd = 1;
+  GtConfig->DdiConfiguration.DdiPortCHpd = 1;
+  GtConfig->DdiConfiguration.DdiPortDHpd = 1;
+  GtConfig->DdiConfiguration.DdiPortFHpd = 0;
+  GtConfig->DdiConfiguration.DdiPortBDdc = 1;
+  GtConfig->DdiConfiguration.DdiPortCDdc = 1;
+  GtConfig->DdiConfiguration.DdiPortDDdc = 1;
+  GtConfig->DdiConfiguration.DdiPortFDdc = 0;
+
+  ///
+  /// Initialize the CdClock to 675 Mhz
+  ///
+  GtConfig->CdClock             = 3;
+}
+
+VOID
+LoadSwitchableGraphichsDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  SWITCHABLE_GRAPHICS_CONFIG        *SgConfig;
+  SgConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "SgConfig->Header.GuidHob.Name = %g\n", &SgConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SgConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SgConfig->Header.GuidHob.Header.HobLength));
+  SgConfig->SaRtd3Pcie0Gpio.GpioSupport    = NotSupported;
+  SgConfig->SaRtd3Pcie1Gpio.GpioSupport    = NotSupported;
+  SgConfig->SaRtd3Pcie2Gpio.GpioSupport    = NotSupported;
+}
+
+VOID
+LoadMemConfigNoCrcDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+
+  MEMORY_CONFIG_NO_CRC                    *MemConfigNoCrc;
+
+  MemConfigNoCrc = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Name = %g\n", &MemConfigNoCrc->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Header.HobLength = 0x%x\n", MemConfigNoCrc->Header.GuidHob.Header.HobLength));
+  //
+  // Allocating memory space for pointer structures inside MemConfigNoCrc
+  //
+  MemConfigNoCrc->SpdData = (SPD_DATA_BUFFER *) AllocateZeroPool (sizeof (SPD_DATA_BUFFER));
+  ASSERT (MemConfigNoCrc->SpdData != NULL);
+  if (MemConfigNoCrc->SpdData == NULL) {
+    return;
+  }
+
+  MemConfigNoCrc->DqByteMap = (SA_MEMORY_DQ_MAPPING *) AllocateZeroPool (sizeof (SA_MEMORY_DQ_MAPPING));
+  ASSERT (MemConfigNoCrc->DqByteMap != NULL);
+  if (MemConfigNoCrc->DqByteMap == NULL) {
+    return;
+  }
+
+  MemConfigNoCrc->DqsMap = (SA_MEMORY_DQS_MAPPING *) AllocateZeroPool (sizeof (SA_MEMORY_DQS_MAPPING));
+  ASSERT (MemConfigNoCrc->DqsMap != NULL);
+  if (MemConfigNoCrc->DqsMap == NULL) {
+    return;
+  }
+
+  MemConfigNoCrc->RcompData = (SA_MEMORY_RCOMP *) AllocateZeroPool (sizeof (SA_MEMORY_RCOMP));
+  ASSERT (MemConfigNoCrc->RcompData != NULL);
+  if (MemConfigNoCrc->RcompData == NULL) {
+    return;
+  }
+
+  //
+  // Set PlatformMemory Size
+  //
+
+  MemConfigNoCrc->PlatformMemorySize = PEI_MIN_MEMORY_SIZE;
+
+  MemConfigNoCrc->SerialDebugLevel  = 3;  //< Enable MRC debug message
+
+  MemConfigNoCrc->MemTestOnWarmBoot = 1;  //< Enable to run BaseMemoryTest on warm boot by default
+
+}
+
+VOID
+LoadGnaDefault (
+  IN VOID *ConfigBlockPointer
+  )
+{
+  GNA_CONFIG                        *GnaConfig;
+  GnaConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GnaConfig->Header.GuidHob.Name = %g\n", &GnaConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GnaConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GnaConfig->Header.GuidHob.Header.HobLength));
+  GnaConfig->GnaEnable    = TRUE;
+}
+
+VOID
+LoadMemConfigDefault (
+  IN VOID *ConfigBlockPointer
+  )
+{
+  MEMORY_CONFIGURATION                    *MemConfig;
+  CPU_FAMILY                              CpuFamily;
+  UINT16                                  DeviceId;
+
+  CPU_SKU                                 CpuSku;
+  CpuSku = GetCpuSku ();
+  CpuFamily   = GetCpuFamily ();
+  DeviceId    = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_DEVICE_ID));
+
+  MemConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Name = %g\n", &MemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Initialize the Memory Configuration
+  //
+  MemConfig->EnBER              = 1;
+  MemConfig->EccSupport         = 1;
+  MemConfig->ScramblerSupport   = 1;
+  MemConfig->PowerDownMode      = 0xFF;
+  MemConfig->RankInterleave     = TRUE;
+  MemConfig->EnhancedInterleave = TRUE;
+  MemConfig->EnCmdRate          = 3;
+  MemConfig->AutoSelfRefreshSupport = TRUE;
+  MemConfig->ExtTemperatureSupport  = TRUE;
+  MemConfig->WeaklockEn = 1;
+  MemConfig->Ddr4MixedUDimm2DpcLimit = 1;
+
+  MemConfig->DualDimmPerChannelBoardType = (CpuFamily == EnumCpuCflDtHalo) ? TRUE : FALSE;
+
+  //
+  // Channel Hash Configuration
+  //
+  MemConfig->ChHashEnable         = TRUE;
+  MemConfig->ChHashMask           = 0;
+  MemConfig->ChHashInterleaveBit  = 2;
+  MemConfig->PerBankRefresh       = TRUE;
+  //
+  // Options for Thermal settings
+  //
+  MemConfig->EnablePwrDn            = 1;
+  MemConfig->EnablePwrDnLpddr       = 1;
+  MemConfig->DdrThermalSensor       = 1;
+
+  MemConfig->EnergyScaleFact        = 4;
+  MemConfig->IdleEnergyCh0Dimm0     = 0xA;
+  MemConfig->IdleEnergyCh0Dimm1     = 0xA;
+  MemConfig->IdleEnergyCh1Dimm0     = 0xA;
+  MemConfig->IdleEnergyCh1Dimm1     = 0xA;
+  MemConfig->PdEnergyCh0Dimm0       = 0x6;
+  MemConfig->PdEnergyCh0Dimm1       = 0x6;
+  MemConfig->PdEnergyCh1Dimm0       = 0x6;
+  MemConfig->PdEnergyCh1Dimm1       = 0x6;
+  MemConfig->ActEnergyCh0Dimm0      = 0xAC;
+  MemConfig->ActEnergyCh0Dimm1      = 0xAC;
+  MemConfig->ActEnergyCh1Dimm0      = 0xAC;
+  MemConfig->ActEnergyCh1Dimm1      = 0xAC;
+  MemConfig->RdEnergyCh0Dimm0       = 0xD4;
+  MemConfig->RdEnergyCh0Dimm1       = 0xD4;
+  MemConfig->RdEnergyCh1Dimm0       = 0xD4;
+  MemConfig->RdEnergyCh1Dimm1       = 0xD4;
+  MemConfig->WrEnergyCh0Dimm0       = 0xDD;
+  MemConfig->WrEnergyCh0Dimm1       = 0xDD;
+  MemConfig->WrEnergyCh1Dimm0       = 0xDD;
+  MemConfig->WrEnergyCh1Dimm1       = 0xDD;
+  MemConfig->WarmThresholdCh0Dimm0  = 0xFF;
+  MemConfig->WarmThresholdCh0Dimm1  = 0xFF;
+  MemConfig->WarmThresholdCh1Dimm0  = 0xFF;
+  MemConfig->WarmThresholdCh1Dimm1  = 0xFF;
+  MemConfig->HotThresholdCh0Dimm0   = 0xFF;
+  MemConfig->HotThresholdCh0Dimm1   = 0xFF;
+  MemConfig->HotThresholdCh1Dimm0   = 0xFF;
+  MemConfig->HotThresholdCh1Dimm1   = 0xFF;
+  MemConfig->WarmBudgetCh0Dimm0     = 0xFF;
+  MemConfig->WarmBudgetCh0Dimm1     = 0xFF;
+  MemConfig->WarmBudgetCh1Dimm0     = 0xFF;
+  MemConfig->WarmBudgetCh1Dimm1     = 0xFF;
+  MemConfig->HotBudgetCh0Dimm0      = 0xFF;
+  MemConfig->HotBudgetCh0Dimm1      = 0xFF;
+  MemConfig->HotBudgetCh1Dimm0      = 0xFF;
+  MemConfig->HotBudgetCh1Dimm1      = 0xFF;
+
+  MemConfig->SrefCfgEna             = 1;
+  MemConfig->SrefCfgIdleTmr         = 0x200;
+  MemConfig->ThrtCkeMinTmr          = 0x30;
+  MemConfig->ThrtCkeMinDefeatLpddr  = 1;
+  MemConfig->ThrtCkeMinTmrLpddr     = 0x40;
+
+  MemConfig->RaplLim2WindX = 1;
+  MemConfig->RaplLim2WindY = 1;
+  MemConfig->RaplLim2Pwr   = 0xDE;
+
+  //
+  // CA Vref routing: board-dependent
+  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
+  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
+  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
+  //
+  //MemConfig->CaVrefConfig = 0;
+  MemConfig->VttTermination     = ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt));
+  MemConfig->VttCompForVsshi    = 0;
+
+#ifdef UP_SERVER_FLAG
+  MemConfig->TsodTcritmax = 0x69;
+  MemConfig->TsodThigMax  = 0x5D;
+#endif
+
+
+  //
+  // MRC training steps
+  //
+  MemConfig->ECT                  = 1;
+  MemConfig->ERDMPRTC2D           = 1;
+  MemConfig->SOT                  = 1;
+  MemConfig->RDMPRT               = 1;
+  MemConfig->RCVET                = 1;
+  MemConfig->JWRL                 = 1;
+  MemConfig->EWRTC2D              = 1;
+  MemConfig->ERDTC2D              = 1;
+  MemConfig->WRTC1D               = 1;
+  MemConfig->WRVC1D               = 1;
+  MemConfig->RDTC1D               = 1;
+  MemConfig->DIMMODTT             = 1;
+  MemConfig->DIMMRONT             = 1;
+  MemConfig->WRSRT                = 1;
+  MemConfig->RDODTT               = 1;
+  MemConfig->RDAPT                = 1;
+  MemConfig->WRTC2D               = 1;
+  MemConfig->RDTC2D               = 1;
+  MemConfig->CMDVC                = 1;
+  MemConfig->WRVC2D               = 1;
+  MemConfig->RDVC2D               = 1;
+  MemConfig->LCT                  = 1;
+  MemConfig->RTL                  = 1;
+  MemConfig->TAT                  = 1;
+  MemConfig->ALIASCHK             = 1;
+  MemConfig->RCVENC1D             = 1;
+  MemConfig->RMC                  = 1;
+  MemConfig->CMDSR                = 1;
+  MemConfig->CMDDSEQ              = 1;
+  MemConfig->CMDNORM              = 1;
+  MemConfig->EWRDSEQ              = 1;
+  MemConfig->McLock               = TRUE;
+  MemConfig->GdxcIotSize          = 4;
+  MemConfig->GdxcMotSize          = 12;
+  MemConfig->RDEQT                = 1;
+
+  MemConfig->MrcFastBoot          = TRUE;
+  MemConfig->MrcTrainOnWarm       = FALSE;
+  MemConfig->RemapEnable          = TRUE;
+  MemConfig->BClkFrequency        = 100 * 1000 * 1000;
+
+#ifdef EMBEDDED_FLAG
+  MemConfig->Force1Dpc = TRUE;
+#endif
+  MemConfig->Vc1ReadMeter           = TRUE;
+  MemConfig->Vc1ReadMeterTimeWindow = 0x320;
+  MemConfig->Vc1ReadMeterThreshold  = 0x118;
+  MemConfig->StrongWkLeaker         = 7;
+
+  MemConfig->MobilePlatform     = (IS_SA_DEVICE_ID_MOBILE (DeviceId)) ? TRUE : FALSE;
+  MemConfig->PciIndex           = 0xCF8;
+  MemConfig->PciData            = 0xCFC;
+  MemConfig->CkeRankMapping     = 0xAA;
+
+  // This only affects ULX/ULT; otherwise SA GV is disabled.
+  // CFL SA GV: 0 - Disabled, 1 - FixedLow, 2 - FixedHigh, 3 - Enabled
+  MemConfig->SaGv             = 3;
+  MemConfig->SimicsFlag       = 0;
+
+  MemConfig->Idd3n              = 26;
+  MemConfig->Idd3p              = 11;
+
+  MemConfig->RhPrevention       = TRUE;         // Row Hammer prevention.
+  MemConfig->RhSolution         = HardwareRhp;  // Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  MemConfig->RhActProbability   = OneIn2To11;    // Activation probability for Hardware RHP
+
+  MemConfig->LpddrMemWriteLatencySet = 1;  // Enable LPDDR3 WL Set B if supported by DRAM
+
+  MemConfig->DllBwEn1 = 1;
+  MemConfig->DllBwEn2 = 2;
+  MemConfig->DllBwEn3 = 2;
+
+  MemConfig->RetrainOnFastFail  = 1; //  Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, 1 = Enabled
+  MemConfig->Lp4DqsOscEn        = 1;
+  MemConfig->IsvtIoPort         = 0x99;
+}
+
+
+VOID
+LoadOverClockConfigDefault (
+  IN VOID   *ConfigBlockPointer
+  )
+{
+  OVERCLOCKING_PREMEM_CONFIG    *OcPreMemConfig;
+  OcPreMemConfig = (OVERCLOCKING_PREMEM_CONFIG *)ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "OcPreMemConfig->Header.GuidHob.Name = %g\n", &OcPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "OcPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", OcPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY  mSaIpBlocksPreMem [] = {
+  {&gSaMiscPeiPreMemConfigGuid,       sizeof (SA_MISC_PEI_PREMEM_CONFIG),  SA_MISC_PEI_PREMEM_CONFIG_REVISION,  LoadSaMiscPeiPreMemDefault},
+  {&gSaPciePeiPreMemConfigGuid,       sizeof (PCIE_PEI_PREMEM_CONFIG),     SA_PCIE_PEI_PREMEM_CONFIG_REVISION,  LoadPciePeiPreMemDefault},
+  {&gGraphicsPeiPreMemConfigGuid,     sizeof (GRAPHICS_PEI_PREMEM_CONFIG), GRAPHICS_PEI_PREMEM_CONFIG_REVISION, LoadGraphichsPeiPreMemDefault},
+  {&gSwitchableGraphicsConfigGuid,    sizeof (SWITCHABLE_GRAPHICS_CONFIG), SWITCHABLE_GRAPHICS_CONFIG_REVISION, LoadSwitchableGraphichsDefault},
+  {&gMemoryConfigGuid,                sizeof (MEMORY_CONFIGURATION),       MEMORY_CONFIG_REVISION,              LoadMemConfigDefault},
+  {&gMemoryConfigNoCrcGuid,           sizeof (MEMORY_CONFIG_NO_CRC),       MEMORY_CONFIG_REVISION,              LoadMemConfigNoCrcDefault},
+  {&gSaOverclockingPreMemConfigGuid,  sizeof (OVERCLOCKING_PREMEM_CONFIG), SA_OVERCLOCKING_CONFIG_REVISION,     LoadOverClockConfigDefault},
+  {&gVtdConfigGuid,                   sizeof (VTD_CONFIG),                 VTD_CONFIG_REVISION,                 LoadVtdDefault},
+  {&gIpuPreMemConfigGuid,             sizeof (IPU_PREMEM_CONFIG),          IPU_PREMEM_CONFIG_REVISION,          LoadIpuPreMemDefault}
+};
+
+static COMPONENT_BLOCK_ENTRY  mSaIpBlocks [] = {
+  {&gSaMiscPeiConfigGuid,       sizeof (SA_MISC_PEI_CONFIG),   SA_MISC_PEI_CONFIG_REVISION,      LoadSaMiscPeiDefault},
+  {&gSaPciePeiConfigGuid,       sizeof (PCIE_PEI_CONFIG),      SA_PCIE_PEI_CONFIG_REVISION,      LoadPciePeiDefault},
+  {&gGraphicsPeiConfigGuid,     sizeof (GRAPHICS_PEI_CONFIG),  GRAPHICS_PEI_CONFIG_REVISION,     LoadGraphichsPeiDefault},
+  {&gGnaConfigGuid,             sizeof (GNA_CONFIG),           GNA_CONFIG_REVISION,              LoadGnaDefault}
+};
+
+/**
+  Get SA config block table total size.
+
+  @retval     Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  Get SA config block table total size.
+
+  @retval      Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSizePreMem (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  SaAddConfigBlocksPreMem add all SA config blocks.
+
+  @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
+SaAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n",  sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY)));
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+  if (Status == EFI_SUCCESS) {
+    SaLoadSamplePolicyPreMem (ConfigBlockTableAddress);
+  }
+  return Status;
+}
+
+/**
+  SaAddConfigBlocks add all SA config blocks.
+
+  @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
+SaAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n",  sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
new file mode 100644
index 0000000000..463e75702d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
@@ -0,0 +1,284 @@
+/** @file
+  This file provides services for Sample PEI policy default initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <SaPolicyCommon.h>
+#include "PeiSaPolicyLibrary.h"
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "MrcOemPlatform.h"
+#include <Library/GpioLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/RngLib.h>
+#include <Library/CpuMailboxLib.h>
+
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapSkl[2][6][2] = {
+  // Channel 0:
+  {
+    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  },
+  // Channel 1:
+  {
+    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  }
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqsMapCpu2DramSklRvp[2][8] = {
+  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
+  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
+};
+
+//
+// Reference RCOMP resistors on motherboard
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 mRcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 mRcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
+
+/**
+  Hynix H9CCNNN8JTMLAR-NTM_178b_DDP LPDDR3, 4Gb die (128Mx32), x32
+  or Elpida  EDF8132A1MC-GD-F
+  or Samsung K4E8E304EB-EGCE
+  1600, 12-15-15-34
+  2 rank per channel, 2 SDRAMs per rank, 4x4Gb = 2GB total per channel
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSkylakeRvp3Spd[] = {
+  0x24,                                 ///< 0   Number of Serial PD Bytes Written / SPD Device Size
+  0x20,                                 ///< 1   SPD Revision
+  0x0F,                                 ///< 2   DRAM Device Type
+  0x0E,                                 ///< 3   Module Type
+  0x14,                                 ///< 4   SDRAM Density and Banks: 8 Banks, 4 Gb SDRAM density
+  0x11,                                 ///< 5   SDRAM Addressing: 14 Rows, 10 Columns
+  0x90,                                 ///< 6   SDRAM Package Type: Non-Monolithic, DDP, 1 Channel per package
+  0x00,                                 ///< 7   SDRAM Optional Features
+  0x00,                                 ///< 8   SDRAM Thermal and Refresh Options
+  0x00,                                 ///< 9   Other SDRAM Optional Features
+  0x00,                                 ///< 10  Reserved - must be coded as 0x00
+  0x03,                                 ///< 11  Module Nominal Voltage, VDD
+  0x0B,                                 ///< 12  Module Organization, SDRAM width: 32 bits, 2 Ranks
+  0x03,                                 ///< 13  Module Memory Bus Width: 1 Channel, 64 bits channel width
+  0x00,                                 ///< 14  Module Thermal Sensor
+  0x00,                                 ///< 15  Extended Module Type
+  0x00,                                 ///< 16  Reserved - must be coded as 0x00
+  0x00,                                 ///< 17  Timebases
+  0x0A,                                 ///< 18  SDRAM Minimum Cycle Time (tCKmin)
+  0xFF,                                 ///< 19  SDRAM Minimum Cycle Time (tCKmax)
+  0x54,                                 ///< 20  CAS Latencies Supported, First Byte (tCk): 12 10 8
+  0x00,                                 ///< 21  CAS Latencies Supported, Second Byte
+  0x00,                                 ///< 22  CAS Latencies Supported, Third Byte
+  0x00,                                 ///< 23  CAS Latencies Supported, Fourth Byte
+  0x78,                                 ///< 24  Minimum CAS Latency Time (tAAmin)
+  0x00,                                 ///< 25  Read and Write Latency Set Options
+  0x90,                                 ///< 26  Minimum RAS# to CAS# Delay Time (tRCDmin)
+  0xA8,                                 ///< 27  Minimum Row Precharge Delay Time for all banks (tRPab)
+  0x90,                                 ///< 28  Minimum Row Precharge Delay Time per bank (tRPpb)
+  0x10,                                 ///< 29  Minimum Refresh Recovery Delay Time for all banks (tRFCab), Least Significant Byte
+  0x04,                                 ///< 30  Minimum Refresh Recovery Delay Time for all banks (tRFCab), Most Significant Byte
+  0xE0,                                 ///< 31  Minimum Refresh Recovery Delay Time for per bank (tRFCpb), Least Significant Byte
+  0x01,                                 ///< 32  Minimum Refresh Recovery Delay Time for per bank (tRFCpb), Most Significant Byte
+  0, 0, 0, 0, 0, 0, 0,                  ///< 33 - 39
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 40 - 49
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 50 - 59
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 60 - 69 Connector to SDRAM Bit Mapping
+  0, 0, 0, 0, 0, 0, 0, 0,               ///< 70 - 77 Connector to SDRAM Bit Mapping
+  0, 0,                                 ///< 78 - 79
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 80 - 89
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 90 - 99
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 100 - 109
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 110 - 119
+  0x00,                                 ///< 120 Fine Offset for Minimum Row Precharge Delay Time per bank (tRPpb)
+  0x00,                                 ///< 121 Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+  0x00,                                 ///< 122 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  0x00,                                 ///< 123 Fine Offset for Minimum CAS Latency Time (tAAmin)
+  0x7F,                                 ///< 124 Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+  0x00,                                 ///< 125 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  0x00,                                 ///< 126 CRC A
+  0x00,                                 ///< 127 CRC B
+  0, 0,                                 ///< 128 - 129
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 130 - 139
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 140 - 149
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 150 - 159
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 160 - 169
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 170 - 179
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 180 - 189
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 190 - 199
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 200 - 209
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 210 - 219
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 220 - 229
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 230 - 239
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 240 - 249
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 250 - 259
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 260 - 269
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 270 - 279
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 280 - 289
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 290 - 299
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 300 - 309
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 310 - 319
+  0x00,                                 ///< 320 Module Manufacturer ID Code, Least Significant Byte
+  0x00,                                 ///< 321 Module Manufacturer ID Code, Most Significant Byte
+  0x00,                                 ///< 322 Module Manufacturing Location
+  0x00,                                 ///< 323 Module Manufacturing Date Year
+  0x00,                                 ///< 324 Module Manufacturing Date Week
+  0x55,                                 ///< 325 Module Serial Number A
+  0x00,                                 ///< 326 Module Serial Number B
+  0x00,                                 ///< 327 Module Serial Number C
+  0x00,                                 ///< 328 Module Serial Number D
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 329 - 333 Module Part Number: Unused bytes coded as ASCII Blanks (0x20)
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 334 - 338 Module Part Number
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 339 - 343 Module Part Number
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 344 - 348 Module Part Number
+  0x00,                                 ///< 349 Module Revision Code
+  0x00,                                 ///< 350 DRAM Manufacturer ID Code, Least Significant Byte
+  0x00,                                 ///< 351 DRAM Manufacturer ID Code, Most Significant Byte
+  0x00,                                 ///< 352 DRAM Stepping
+  0, 0, 0, 0, 0, 0, 0,                  ///< 353 - 359
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 360 - 369
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 370 - 379
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 380 - 389
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 390 - 399
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 400 - 409
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 410 - 419
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 420 - 429
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 430 - 439
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 440 - 449
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 450 - 459
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 460 - 469
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 470 - 479
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 480 - 489
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 490 - 499
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 500 - 509
+  0, 0                                  ///< 510 - 511
+};
+
+#define SaIoRead8    IoRead8
+#define SaIoRead16   IoRead16
+#define SaIoRead32   IoRead32
+#define SaIoWrite8   IoWrite8
+#define SaIoWrite16  IoWrite16
+#define SaIoWrite32  IoWrite32
+#define SaCopyMem    CopyMem
+#define SaSetMem     SetMem
+#define SaLShiftU64  LShiftU64
+#define SaRShiftU64  RShiftU64
+#define SaMultU64x32 MultU64x32
+
+/**
+  SaLoadSamplePolicyPreMem - Load some policy default for reference board.
+
+  @param[in] ConfigBlockTableAddress    The pointer for SA config blocks
+
+**/
+VOID
+SaLoadSamplePolicyPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  SA_FUNCTION_CALLS     *MemCall;
+  EFI_STATUS            Status;
+  MEMORY_CONFIG_NO_CRC  *MemConfigNoCrc;
+  CPU_FAMILY            CpuFamilyId;
+  UINT8                 *DqByteMap;
+  BOOLEAN               KblCpu;
+
+  MemConfigNoCrc = NULL;
+  Status = GetConfigBlock (ConfigBlockTableAddress, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR (Status);
+
+  if (MemConfigNoCrc == NULL) {
+    return;
+  }
+  CpuFamilyId = GetCpuFamily ();
+  KblCpu = ((CpuFamilyId == EnumCpuCflUltUlx) || (CpuFamilyId == EnumCpuCflDtHalo));
+
+  DEBUG ((DEBUG_INFO, "Applying Sample policy defaults for RVP3\n"));
+  MemCall                       = &MemConfigNoCrc->SaCall;
+  MemCall->IoRead8              = &SaIoRead8;
+  MemCall->IoRead16             = &SaIoRead16;
+  MemCall->IoRead32             = &SaIoRead32;
+  MemCall->IoWrite8             = &SaIoWrite8;
+  MemCall->IoWrite16            = &SaIoWrite16;
+  MemCall->IoWrite32            = &SaIoWrite32;
+  MemCall->MmioRead8            = &MmioRead8;
+  MemCall->MmioRead16           = &MmioRead16;
+  MemCall->MmioRead32           = &MmioRead32;
+  MemCall->MmioRead64           = &SaMmioRead64;
+  MemCall->MmioWrite8           = &MmioWrite8;
+  MemCall->MmioWrite16          = &MmioWrite16;
+  MemCall->MmioWrite32          = &MmioWrite32;
+  MemCall->MmioWrite64          = &SaMmioWrite64;
+  MemCall->SmbusRead8           = &SmBusReadDataByte;
+  MemCall->SmbusRead16          = &SmBusReadDataWord;
+  MemCall->SmbusWrite8          = &SmBusWriteDataByte;
+  MemCall->SmbusWrite16         = &SmBusWriteDataWord;
+  MemCall->GetPciDeviceAddress  = &GetPciDeviceAddress;
+  MemCall->GetPcieDeviceAddress = &GetPcieDeviceAddress;
+  MemCall->GetRtcTime           = &GetRtcTime;
+  MemCall->GetCpuTime           = &GetCpuTime;
+  MemCall->CopyMem              = &SaCopyMem;
+  MemCall->SetMem               = &SaSetMem;
+  MemCall->SetMemWord           = &SetMemWord;
+  MemCall->SetMemDword          = &SetMemDword;
+  MemCall->LeftShift64          = &SaLShiftU64;
+  MemCall->RightShift64         = &SaRShiftU64;
+  MemCall->MultU64x32           = &SaMultU64x32;
+  MemCall->DivU64x64            = &DivU64x64Remainder;
+  MemCall->GetSpdData           = &GetSpdData;
+  MemCall->GetRandomNumber      = &GetRandomNumber32;
+  MemCall->CpuMailboxRead       = &MailboxRead;
+  MemCall->CpuMailboxWrite      = &MailboxWrite;
+  MemCall->GetMemoryVdd         = &GetMemoryVdd;
+  MemCall->SetMemoryVdd         = &SetMemoryVdd;
+  MemCall->CheckPoint           = &CheckPoint;
+  MemCall->DebugHook            = &DebugHook;
+  MemCall->DebugPrint           = &SaDebugPrint;
+  MemCall->GetRtcCmos           = &PeiRtcRead;
+  MemCall->ReadMsr64            = &AsmReadMsr64;
+  MemCall->WriteMsr64           = &AsmWriteMsr64;
+  MemCall->MrcReturnFromSmc     = &ReturnFromSmc;
+  MemCall->MrcDramReset         = &SaDramReset;
+
+  //
+  // RCOMP resistors and target values: board-dependent
+  //
+  if (KblCpu) {
+    CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompResistor, mRcompResistorSklRvp1, sizeof (mRcompResistorSklRvp1));
+    CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompTarget,   mRcompTargetSklRvp1,   sizeof (mRcompTargetSklRvp1));
+  }
+
+  CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[0][0], mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
+  CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[1][0], mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
+
+  DqByteMap = (UINT8 *) mDqByteMapSkl;
+
+  CopyMem ((VOID *) MemConfigNoCrc->DqByteMap, DqByteMap, sizeof (UINT8) * SA_MC_MAX_CHANNELS * SA_MRC_ITERATION_MAX * 2);
+  CopyMem ((VOID *) MemConfigNoCrc->DqsMap, mDqsMapCpu2DramSklRvp, sizeof (UINT8) * SA_MC_MAX_CHANNELS * SA_MC_MAX_BYTES_NO_ECC);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
new file mode 100644
index 0000000000..ce3ef52733
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
@@ -0,0 +1,559 @@
+/** @file
+  This file provides service for PEI phase policy printing
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyLibrary.h"
+#include <Library/GpioNativeLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi - Instance of SI_PREMEM_POLICY_PPI
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  INTN                                  Index;
+  INTN                                  Index2;
+  EFI_STATUS                            Status;
+  SA_MISC_PEI_PREMEM_CONFIG             *MiscPeiPreMemConfig;
+  GRAPHICS_PEI_PREMEM_CONFIG            *GtPreMemConfig;
+  MEMORY_CONFIGURATION                  *MemConfig;
+  PCIE_PEI_PREMEM_CONFIG                *PciePeiPreMemConfig;
+  SWITCHABLE_GRAPHICS_CONFIG            *SgConfig;
+  MEMORY_CONFIG_NO_CRC                  *MemConfigNoCrc;
+  VTD_CONFIG                            *Vtd;
+  OVERCLOCKING_PREMEM_CONFIG            *OcPreMemConfig;
+  IPU_PREMEM_CONFIG                     *IpuPreMemPolicy;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gVtdConfigGuid, (VOID *) &Vtd);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSwitchableGraphicsConfigGuid, (VOID *) &SgConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", SiPolicyPreMemPpi->TableHeader.Header.Revision));
+  ASSERT (SiPolicyPreMemPpi->TableHeader.Header.Revision == SI_PREMEM_POLICY_REVISION);
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_PREMEM_CONFIG  -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", MiscPeiPreMemConfig->Header.Revision));
+  ASSERT (MiscPeiPreMemConfig->Header.Revision == SA_MISC_PEI_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", SA_MC_MAX_SOCKETS));
+  for (Index = 0; Index < SA_MC_MAX_SOCKETS; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", MiscPeiPreMemConfig->SpdAddressTable[Index]));
+  }
+
+  DEBUG ((DEBUG_INFO, "\n MchBar : 0x%x\n", MiscPeiPreMemConfig->MchBar));
+  DEBUG ((DEBUG_INFO, " DmiBar : 0x%x\n", MiscPeiPreMemConfig->DmiBar));
+  DEBUG ((DEBUG_INFO, " EpBar : 0x%x\n", MiscPeiPreMemConfig->EpBar));
+  DEBUG ((DEBUG_INFO, " SmbusBar : 0x%x\n", MiscPeiPreMemConfig->SmbusBar));
+  DEBUG ((DEBUG_INFO, " GdxcBar : 0x%x\n", MiscPeiPreMemConfig->GdxcBar));
+  DEBUG ((DEBUG_INFO, " TsegSize : 0x%x\n", MiscPeiPreMemConfig->TsegSize));
+  DEBUG ((DEBUG_INFO, " UserBd : 0x%x\n", MiscPeiPreMemConfig->UserBd));
+  DEBUG ((DEBUG_INFO, " EdramBar : 0x%x\n", MiscPeiPreMemConfig->EdramBar));
+  DEBUG ((DEBUG_INFO, " MmioSize : %d MB\n", MiscPeiPreMemConfig->MmioSize));
+  DEBUG ((DEBUG_INFO, " MmioSizeAdjustment : %d MB\n", MiscPeiPreMemConfig->MmioSizeAdjustment));
+  DEBUG ((DEBUG_INFO, " SkipExtGfxScan: 0x%x\n", MiscPeiPreMemConfig->SkipExtGfxScan));
+  DEBUG ((DEBUG_INFO, " S3DataPtr : 0x%x\n", MiscPeiPreMemConfig->S3DataPtr));
+  DEBUG ((DEBUG_INFO, "------------------------ SG_DELAY_OPTIMIZATION_DATA -----------------\n"));
+  DEBUG ((DEBUG_INFO, " SaRtd3.SgDelayAfterHoldReset : 0x%x\n", MiscPeiPreMemConfig->SgDelayAfterHoldReset));
+  DEBUG ((DEBUG_INFO, " SaRtd3.SgDelayAfterPwrEn     : 0x%x\n", MiscPeiPreMemConfig->SgDelayAfterPwrEn));
+
+  DEBUG ((DEBUG_INFO, " ScanExtGfxForLegacyOpRom : 0x%x\n", MiscPeiPreMemConfig->ScanExtGfxForLegacyOpRom));
+  DEBUG ((DEBUG_INFO, " AcpiReservedMemoryBase : 0x%x\n", MiscPeiPreMemConfig->AcpiReservedMemoryBase));
+  DEBUG ((DEBUG_INFO, " AcpiReservedMemorySize : 0x%x\n", MiscPeiPreMemConfig->AcpiReservedMemorySize));
+  DEBUG ((DEBUG_INFO, " SystemMemoryLength : 0x%x\n", MiscPeiPreMemConfig->SystemMemoryLength));
+  DEBUG ((DEBUG_INFO, " OpRomScanTempMmioBar : 0x%x\n", MiscPeiPreMemConfig->OpRomScanTempMmioBar));
+  DEBUG ((DEBUG_INFO, " OpRomScanTempMmioLimit : 0x%x\n", MiscPeiPreMemConfig->OpRomScanTempMmioLimit));
+
+  DEBUG ((DEBUG_INFO, "------------------------ GRAPHICS_PEI_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", GtPreMemConfig->Header.Revision));
+  ASSERT (GtPreMemConfig->Header.Revision == GRAPHICS_PEI_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " PanelPowerEnable : 0x%x\n", GtPreMemConfig->PanelPowerEnable));
+  DEBUG ((DEBUG_INFO, " GttSize : %d MB\n", GtPreMemConfig->GttSize));
+  DEBUG ((DEBUG_INFO, " IgdDvmt50PreAlloc : 0x%x\n", GtPreMemConfig->IgdDvmt50PreAlloc));
+  DEBUG ((DEBUG_INFO, " InternalGraphics : 0x%x\n", GtPreMemConfig->InternalGraphics));
+  DEBUG ((DEBUG_INFO, " PrimaryDisplay : 0x%x\n", GtPreMemConfig->PrimaryDisplay));
+  DEBUG ((DEBUG_INFO, " ApertureSize : 0x%x\n", GtPreMemConfig->ApertureSize));
+  DEBUG ((DEBUG_INFO, " GtPsmiSupport : 0x%x\n", GtPreMemConfig->GtPsmiSupport));
+  DEBUG ((DEBUG_INFO, " PsmiRegionSize : 0x%x\n", GtPreMemConfig->PsmiRegionSize));
+  DEBUG ((DEBUG_INFO, " GttMmAdr : 0x%x\n", GtPreMemConfig->GttMmAdr));
+  DEBUG ((DEBUG_INFO, " GmAdr : 0x%x\n", GtPreMemConfig->GmAdr));
+  DEBUG ((DEBUG_INFO, " DeltaT12PowerCycleDelayPreMem : 0x%x\n", GtPreMemConfig->DeltaT12PowerCycleDelayPreMem));
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCIE_PEI_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", PciePeiPreMemConfig->Header.Revision));
+  ASSERT (PciePeiPreMemConfig->Header.Revision == SA_PCIE_PEI_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " DmiMaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->DmiMaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " DmiGen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->DmiGen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " DmiGen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->DmiGen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " DmiGen3ProgramStaticEq : 0x%x\n", PciePeiPreMemConfig->DmiGen3ProgramStaticEq));
+  DEBUG ((DEBUG_INFO, " Peg0Enable : 0x%x\n", PciePeiPreMemConfig->Peg0Enable));
+  DEBUG ((DEBUG_INFO, " Peg1Enable : 0x%x\n", PciePeiPreMemConfig->Peg1Enable));
+  DEBUG ((DEBUG_INFO, " Peg2Enable : 0x%x\n", PciePeiPreMemConfig->Peg2Enable));
+  DEBUG ((DEBUG_INFO, " Peg3Enable : 0x%x\n", PciePeiPreMemConfig->Peg3Enable));
+  DEBUG ((DEBUG_INFO, " Peg0MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg0MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg1MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg1MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg2MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg2MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg3MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg3MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg0MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg0MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg1MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg1MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg2MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg2MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg3MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg3MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg0PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg0PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg1PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg1PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg2PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg2PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg3PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg3PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg0Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg0Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg1Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg1Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg2Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg2Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg3Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg3Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg0Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg0Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " Peg1Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg1Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " Peg2Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg2Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " Peg3Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg3Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " PegGen3ProgramStaticEq : 0x%x\n", PciePeiPreMemConfig->PegGen3ProgramStaticEq));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqAlwaysAttempt : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqAlwaysAttempt));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqNumberOfPresets : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqNumberOfPresets));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqEnableVocTest : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqEnableVocTest));
+  DEBUG ((DEBUG_INFO, " InitPcieAspmAfterOprom : 0x%x\n", PciePeiPreMemConfig->InitPcieAspmAfterOprom));
+  DEBUG ((DEBUG_INFO, " PegRxCemTestingMode : 0x%x\n", PciePeiPreMemConfig->PegRxCemTestingMode));
+  DEBUG ((DEBUG_INFO, " PegRxCemLoopbackLane : 0x%x\n", PciePeiPreMemConfig->PegRxCemLoopbackLane));
+  DEBUG ((DEBUG_INFO, " PegRxCemNonProtocolAwareness : 0x%x\n", PciePeiPreMemConfig->PegRxCemNonProtocolAwareness));
+  DEBUG ((DEBUG_INFO, " PegDisableSpreadSpectrumClocking : 0x%x\n", PciePeiPreMemConfig->PegDisableSpreadSpectrumClocking));
+  DEBUG ((DEBUG_INFO, " PegGenerateBdatMarginTable : 0x%x\n", PciePeiPreMemConfig->PegGenerateBdatMarginTable));
+  DEBUG ((DEBUG_INFO, " DmiGen3RootPortPreset[%d] :", SA_DMI_MAX_LANE));
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3RootPortPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n DmiGen3EndPointPreset[%d] :", SA_DMI_MAX_LANE));
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3EndPointPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n DmiGen3EndPointHint[%d] :", SA_DMI_MAX_LANE));
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3EndPointHint[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n DmiGen3RxCtlePeaking[%d] :", SA_DMI_MAX_BUNDLE));
+  for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3RootPortPreset[%d] :", SA_PEG_MAX_LANE));
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3RootPortPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegRootPortHPE[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegRootPortHPE[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3EndPointPreset[%d] :", SA_PEG_MAX_LANE));
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3EndPointPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3EndPointHint[%d] :", SA_PEG_MAX_LANE));
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3EndPointHint[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3RxCtlePeaking[%d] :", SA_PEG_MAX_BUNDLE));
+  for (Index = 0; Index < SA_PEG_MAX_BUNDLE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3RxCtlePeaking[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3RxCtleOverride : 0x%x\n", PciePeiPreMemConfig->PegGen3RxCtleOverride));
+  DEBUG ((DEBUG_INFO, " DmiDeEmphasis : 0x%x\n", PciePeiPreMemConfig->DmiDeEmphasis));
+  DEBUG ((DEBUG_INFO, "\n Gen3SwEqJitterDwellTime : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqJitterDwellTime));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqJitterErrorTarget : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqVocDwellTime : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqVocDwellTime));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqVocErrorTarget : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqVocErrorTarget));
+  DEBUG ((DEBUG_INFO, " PegDataPtr : %p\n", PciePeiPreMemConfig->PegDataPtr));
+  DEBUG ((DEBUG_INFO, " PegGpioData->GpioSupport : 0x%x\n", PciePeiPreMemConfig->PegGpioData.GpioSupport));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg0ResetGpio.GpioPad Group:%d, PadNumber:%d\n", GpioGetGroupIndexFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad), GpioGetPadNumberFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad)));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg0ResetGpio.Active : 0x%x\n", PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg3ResetGpio.GpioPad Group:%d, PadNumber:%d\n", GpioGetGroupIndexFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad), GpioGetPadNumberFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad)));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg3ResetGpio.Active : 0x%x\n", PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active));
+
+  DEBUG ((DEBUG_INFO, "------------------------ VTD_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", Vtd->Header.Revision));
+  ASSERT (Vtd->Header.Revision == VTD_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " VtdDisable : 0x%x\n", Vtd->VtdDisable));
+  DEBUG ((DEBUG_INFO, " X2ApicOptOut : 0x%x\n", Vtd->X2ApicOptOut));
+  DEBUG ((DEBUG_INFO, " VtdBaseAddress[%d] :", SA_VTD_ENGINE_NUMBER));
+  for (Index = 0; Index < SA_VTD_ENGINE_NUMBER; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", Vtd->BaseAddress[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, "------------------------ SWITCHABLE_GRAPHICS_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", SgConfig->Header.Revision));
+  ASSERT (SgConfig->Header.Revision == SWITCHABLE_GRAPHICS_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " SgConfig->SaRtd3Pcie0Gpio.GpioSupport : 0x%x\n", SgConfig->SaRtd3Pcie0Gpio.GpioSupport));
+
+  DEBUG ((DEBUG_INFO, "------------------------ IPU_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", IpuPreMemPolicy->Header.Revision));
+  ASSERT (IpuPreMemPolicy->Header.Revision == IPU_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " SaIpuEnable : 0x%x\n", IpuPreMemPolicy->SaIpuEnable));
+  DEBUG ((DEBUG_INFO, " SaIpuImrConfiguration : 0x%x\n", IpuPreMemPolicy->SaIpuImrConfiguration));
+
+  DEBUG ((DEBUG_INFO, "------------------------ MEMORY_CONFIG ------------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Guid                   : %g\n", &MemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, " Revision               : %d\n",   MemConfig->Header.Revision));
+  ASSERT (MemConfig->Header.Revision == MEMORY_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " Size                   : 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
+  DEBUG ((DEBUG_INFO, " HobBufferSize          : 0x%x\n", MemConfig->HobBufferSize));
+  DEBUG ((DEBUG_INFO, " EccSupport             : 0x%x\n", MemConfig->EccSupport));
+  DEBUG ((DEBUG_INFO, " DdrFreqLimit           : %d\n",   MemConfig->DdrFreqLimit));
+  DEBUG ((DEBUG_INFO, " SpdProfileSelected     : 0x%x\n", MemConfig->SpdProfileSelected));
+  DEBUG ((DEBUG_INFO, " tCL                    : 0x%x\n", MemConfig->tCL));
+  DEBUG ((DEBUG_INFO, " tRCDtRP                : 0x%x\n", MemConfig->tRCDtRP));
+  DEBUG ((DEBUG_INFO, " tRAS                   : 0x%x\n", MemConfig->tRAS));
+  DEBUG ((DEBUG_INFO, " tWR                    : 0x%x\n", MemConfig->tWR));
+  DEBUG ((DEBUG_INFO, " tRFC                   : 0x%x\n", MemConfig->tRFC));
+  DEBUG ((DEBUG_INFO, " tRRD                   : 0x%x\n", MemConfig->tRRD));
+  DEBUG ((DEBUG_INFO, " tWTR                   : 0x%x\n", MemConfig->tWTR));
+  DEBUG ((DEBUG_INFO, " tRTP                   : 0x%x\n", MemConfig->tRTP));
+  DEBUG ((DEBUG_INFO, " tFAW                   : 0x%x\n", MemConfig->tFAW));
+  DEBUG ((DEBUG_INFO, " tCWL                   : 0x%x\n", MemConfig->tCWL));
+  DEBUG ((DEBUG_INFO, " tREFI                  : 0x%x\n", MemConfig->tREFI));
+  DEBUG ((DEBUG_INFO, " NModeSupport           : 0x%x\n", MemConfig->NModeSupport));
+  DEBUG ((DEBUG_INFO, " VddVoltage             : %d\n", MemConfig->VddVoltage));
+
+  DEBUG ((DEBUG_INFO, " DisableDimmChannel[%d] :", SA_MC_MAX_CHANNELS));
+  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", MemConfig->DisableDimmChannel[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n RemapEnable            : 0x%x\n", MemConfig->RemapEnable));
+  DEBUG ((DEBUG_INFO, " ScramblerSupport       : 0x%x\n", MemConfig->ScramblerSupport));
+  DEBUG ((DEBUG_INFO, " SerialDebug            : 0x%x\n", MemConfigNoCrc->SerialDebugLevel));
+  DEBUG ((DEBUG_INFO, " ProbelessTrace      : 0x%x\n", MemConfig->ProbelessTrace));
+  DEBUG ((DEBUG_INFO, " ECT                    : 0x%x\n", MemConfig->ECT));
+  DEBUG ((DEBUG_INFO, " SOT                    : 0x%x\n", MemConfig->SOT));
+  DEBUG ((DEBUG_INFO, " ERDMPRTC2D             : 0x%x\n", MemConfig->ERDMPRTC2D));
+  DEBUG ((DEBUG_INFO, " RDMPRT                 : 0x%x\n", MemConfig->RDMPRT));
+  DEBUG ((DEBUG_INFO, " RCVET                  : 0x%x\n", MemConfig->RCVET));
+  DEBUG ((DEBUG_INFO, " JWRL                   : 0x%x\n", MemConfig->JWRL));
+  DEBUG ((DEBUG_INFO, " EWRTC2D                : 0x%x\n", MemConfig->EWRTC2D));
+  DEBUG ((DEBUG_INFO, " ERDTC2D                : 0x%x\n", MemConfig->ERDTC2D));
+  DEBUG ((DEBUG_INFO, " WRTC1D                 : 0x%x\n", MemConfig->WRTC1D));
+  DEBUG ((DEBUG_INFO, " WRVC1D                 : 0x%x\n", MemConfig->WRVC1D));
+  DEBUG ((DEBUG_INFO, " RDTC1D                 : 0x%x\n", MemConfig->RDTC1D));
+  DEBUG ((DEBUG_INFO, " DIMMODTT               : 0x%x\n", MemConfig->DIMMODTT));
+  DEBUG ((DEBUG_INFO, " DIMMRONT               : 0x%x\n", MemConfig->DIMMRONT));
+  DEBUG ((DEBUG_INFO, " WRDSEQT                : 0x%x\n", MemConfig->WRDSEQT));
+  DEBUG ((DEBUG_INFO, " WRSRT                  : 0x%x\n", MemConfig->WRSRT));
+  DEBUG ((DEBUG_INFO, " RDODTT                 : 0x%x\n", MemConfig->RDODTT));
+  DEBUG ((DEBUG_INFO, " RDEQT                  : 0x%x\n", MemConfig->RDEQT));
+  DEBUG ((DEBUG_INFO, " RDAPT                  : 0x%x\n", MemConfig->RDAPT));
+  DEBUG ((DEBUG_INFO, " WRTC2D                 : 0x%x\n", MemConfig->WRTC2D));
+  DEBUG ((DEBUG_INFO, " RDTC2D                 : 0x%x\n", MemConfig->RDTC2D));
+  DEBUG ((DEBUG_INFO, " WRVC2D                 : 0x%x\n", MemConfig->WRVC2D));
+  DEBUG ((DEBUG_INFO, " RDVC2D                 : 0x%x\n", MemConfig->RDVC2D));
+  DEBUG ((DEBUG_INFO, " CMDVC                  : 0x%x\n", MemConfig->CMDVC));
+  DEBUG ((DEBUG_INFO, " LCT                    : 0x%x\n", MemConfig->LCT));
+  DEBUG ((DEBUG_INFO, " RTL                    : 0x%x\n", MemConfig->RTL));
+  DEBUG ((DEBUG_INFO, " TAT                    : 0x%x\n", MemConfig->TAT));
+  DEBUG ((DEBUG_INFO, " RMT                    : 0x%x\n", MemConfig->RMT));
+  DEBUG ((DEBUG_INFO, " MEMTST                 : 0x%x\n", MemConfig->MEMTST));
+  DEBUG ((DEBUG_INFO, " ALIASCHK               : 0x%x\n", MemConfig->ALIASCHK));
+  DEBUG ((DEBUG_INFO, " RCVENC1D               : 0x%x\n", MemConfig->RCVENC1D));
+  DEBUG ((DEBUG_INFO, " RMC                    : 0x%x\n", MemConfig->RMC));
+  DEBUG ((DEBUG_INFO, " WRDSUDT                : 0x%x\n", MemConfig->WRDSUDT));
+
+  DEBUG ((DEBUG_INFO, " VddSettleWaitTime      : 0x%x\n", MemConfig->VddSettleWaitTime));
+  DEBUG ((DEBUG_INFO, " RefClk                 : 0x%x\n", MemConfig->RefClk));
+  DEBUG ((DEBUG_INFO, " Ratio                  : 0x%x\n", MemConfig->Ratio));
+  DEBUG ((DEBUG_INFO, " OddRatioMode           : 0x%x\n", MemConfig->OddRatioMode));
+  DEBUG ((DEBUG_INFO, " MrcTimeMeasure         : 0x%x\n", MemConfig->MrcTimeMeasure));
+  DEBUG ((DEBUG_INFO, " MrcFastBoot            : 0x%x\n", MemConfig->MrcFastBoot));
+  DEBUG ((DEBUG_INFO, " DqPinsInterleaved      : 0x%x\n", MemConfig->DqPinsInterleaved));
+  DEBUG ((DEBUG_INFO, " MrcSafeConfig          : 0x%x\n", MemConfig->MrcSafeConfig));
+  DEBUG ((DEBUG_INFO, " SafeMode               : 0x%x\n", MemConfig->SafeMode));
+  DEBUG ((DEBUG_INFO, " Lp4DqsOscEn            : 0x%x\n", MemConfig->Lp4DqsOscEn));
+  DEBUG ((DEBUG_INFO, " EnBER                  : 0x%x\n", MemConfig->EnBER));
+  DEBUG ((DEBUG_INFO, " Ddr4MixedUDimm2DpcLimit: 0x%x\n", MemConfig->Ddr4MixedUDimm2DpcLimit));
+  DEBUG ((DEBUG_INFO, " PowerDownMode          : 0x%x\n", MemConfig->PowerDownMode));
+  DEBUG ((DEBUG_INFO, " PwdwnIdleCounter       : 0x%x\n", MemConfig->PwdwnIdleCounter));
+  DEBUG ((DEBUG_INFO, " RankInterleave         : 0x%x\n", MemConfig->RankInterleave));
+  DEBUG ((DEBUG_INFO, " EnhancedInterleave     : 0x%x\n", MemConfig->EnhancedInterleave));
+  DEBUG ((DEBUG_INFO, " WeaklockEn             : 0x%x\n", MemConfig->WeaklockEn));
+  DEBUG ((DEBUG_INFO, " EnCmdRate              : 0x%x\n", MemConfig->EnCmdRate));
+  DEBUG ((DEBUG_INFO, " CmdTriStateDis         : 0x%x\n", MemConfig->CmdTriStateDis));
+  DEBUG ((DEBUG_INFO, " BClkFrequency          : 0x%x\n", MemConfig->BClkFrequency));
+  DEBUG ((DEBUG_INFO, " MemoryTrace            : 0x%x\n", MemConfig->MemoryTrace));
+  DEBUG ((DEBUG_INFO, " ChHashEnable           : 0x%x\n", MemConfig->ChHashEnable));
+  DEBUG ((DEBUG_INFO, " ChHashMask             : 0x%x\n", MemConfig->ChHashMask));
+  DEBUG ((DEBUG_INFO, " ChHashInterleaveBit    : 0x%x\n", MemConfig->ChHashInterleaveBit));
+  DEBUG ((DEBUG_INFO, " PerBankRefresh         : 0x%x\n", MemConfig->PerBankRefresh));
+  DEBUG ((DEBUG_INFO, " EnableExtts            : 0x%x\n", MemConfig->EnableExtts));
+  DEBUG ((DEBUG_INFO, " EnableCltm             : 0x%x\n", MemConfig->EnableCltm));
+  DEBUG ((DEBUG_INFO, " EnableOltm             : 0x%x\n", MemConfig->EnableOltm));
+  DEBUG ((DEBUG_INFO, " EnablePwrDn            : 0x%x\n", MemConfig->EnablePwrDn));
+  DEBUG ((DEBUG_INFO, " EnablePwrDnLpddr       : 0x%x\n", MemConfig->EnablePwrDnLpddr));
+  DEBUG ((DEBUG_INFO, " Refresh2X              : 0x%x\n", MemConfig->Refresh2X));
+  DEBUG ((DEBUG_INFO, " DdrThermalSensor       : 0x%x\n", MemConfig->DdrThermalSensor));
+  DEBUG ((DEBUG_INFO, " LockPTMregs            : 0x%x\n", MemConfig->LockPTMregs));
+  DEBUG ((DEBUG_INFO, " UserPowerWeightsEn     : 0x%x\n", MemConfig->UserPowerWeightsEn));
+  DEBUG ((DEBUG_INFO, " EnergyScaleFact        : 0x%x\n", MemConfig->EnergyScaleFact));
+  DEBUG ((DEBUG_INFO, " RaplPwrFlCh1           : 0x%x\n", MemConfig->RaplPwrFlCh1));
+  DEBUG ((DEBUG_INFO, " RaplPwrFlCh0           : 0x%x\n", MemConfig->RaplPwrFlCh0));
+  DEBUG ((DEBUG_INFO, " RaplLim2Lock           : 0x%x\n", MemConfig->RaplLim2Lock));
+  DEBUG ((DEBUG_INFO, " RaplLim2WindX          : 0x%x\n", MemConfig->RaplLim2WindX));
+  DEBUG ((DEBUG_INFO, " RaplLim2WindY          : 0x%x\n", MemConfig->RaplLim2WindY));
+  DEBUG ((DEBUG_INFO, " RaplLim2Ena            : 0x%x\n", MemConfig->RaplLim2Ena));
+  DEBUG ((DEBUG_INFO, " RaplLim2Pwr            : 0x%x\n", MemConfig->RaplLim2Pwr));
+  DEBUG ((DEBUG_INFO, " RaplLim1WindX          : 0x%x\n", MemConfig->RaplLim1WindX));
+  DEBUG ((DEBUG_INFO, " RaplLim1WindY          : 0x%x\n", MemConfig->RaplLim1WindY));
+  DEBUG ((DEBUG_INFO, " RaplLim1Ena            : 0x%x\n", MemConfig->RaplLim1Ena));
+  DEBUG ((DEBUG_INFO, " RaplLim1Pwr            : 0x%x\n", MemConfig->RaplLim1Pwr));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm0  : 0x%x\n", MemConfig->WarmThresholdCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm1  : 0x%x\n", MemConfig->WarmThresholdCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm0  : 0x%x\n", MemConfig->WarmThresholdCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm1  : 0x%x\n", MemConfig->WarmThresholdCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm0   : 0x%x\n", MemConfig->HotThresholdCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm1   : 0x%x\n", MemConfig->HotThresholdCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm0   : 0x%x\n", MemConfig->HotThresholdCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm1   : 0x%x\n", MemConfig->HotThresholdCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm0     : 0x%x\n", MemConfig->WarmBudgetCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm1     : 0x%x\n", MemConfig->WarmBudgetCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm0     : 0x%x\n", MemConfig->WarmBudgetCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm1     : 0x%x\n", MemConfig->WarmBudgetCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm0      : 0x%x\n", MemConfig->HotBudgetCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm1      : 0x%x\n", MemConfig->HotBudgetCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm0      : 0x%x\n", MemConfig->HotBudgetCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm1      : 0x%x\n", MemConfig->HotBudgetCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm0     : 0x%x\n", MemConfig->IdleEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm1     : 0x%x\n", MemConfig->IdleEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm0     : 0x%x\n", MemConfig->IdleEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm1     : 0x%x\n", MemConfig->IdleEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm0       : 0x%x\n", MemConfig->PdEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm1       : 0x%x\n", MemConfig->PdEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm0       : 0x%x\n", MemConfig->PdEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm1       : 0x%x\n", MemConfig->PdEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm0      : 0x%x\n", MemConfig->ActEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm1      : 0x%x\n", MemConfig->ActEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm0      : 0x%x\n", MemConfig->ActEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm1      : 0x%x\n", MemConfig->ActEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm0       : 0x%x\n", MemConfig->RdEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm1       : 0x%x\n", MemConfig->RdEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm0       : 0x%x\n", MemConfig->RdEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm1       : 0x%x\n", MemConfig->RdEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm0       : 0x%x\n", MemConfig->WrEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm1       : 0x%x\n", MemConfig->WrEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm0       : 0x%x\n", MemConfig->WrEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm1       : 0x%x\n", MemConfig->WrEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " SrefCfgEna             : 0x%x\n", MemConfig->SrefCfgEna));
+  DEBUG ((DEBUG_INFO, " SrefCfgIdleTmr         : 0x%x\n", MemConfig->SrefCfgIdleTmr));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeat       : 0x%x\n", MemConfig->ThrtCkeMinDefeat));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinTmr          : 0x%x\n", MemConfig->ThrtCkeMinTmr));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeatLpddr  : 0x%x\n", MemConfig->ThrtCkeMinDefeatLpddr));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinTmrLpddr     : 0x%x\n", MemConfig->ThrtCkeMinTmrLpddr));
+  DEBUG ((DEBUG_INFO, " AutoSelfRefreshSupport : 0x%x\n", MemConfig->AutoSelfRefreshSupport));
+  DEBUG ((DEBUG_INFO, " ExtTemperatureSupport  : 0x%x\n", MemConfig->ExtTemperatureSupport));
+  DEBUG ((DEBUG_INFO, " MaxRttWr               : 0x%x\n", MemConfig->MaxRttWr));
+  DEBUG ((DEBUG_INFO, " MobilePlatform         : 0x%x\n", MemConfig->MobilePlatform));
+  DEBUG ((DEBUG_INFO, " Force1Dpc              : 0x%x\n", MemConfig->Force1Dpc));
+
+
+  DEBUG ((DEBUG_INFO, " ForceSingleRank        : 0x%x\n", MemConfig->ForceSingleRank));
+  DEBUG ((DEBUG_INFO, " PciIndex               : 0x%x\n", MemConfig->PciIndex));
+  DEBUG ((DEBUG_INFO, " PciData                : 0x%x\n", MemConfig->PciData));
+  DEBUG ((DEBUG_INFO, " CkeRankMapping         : 0x%x\n", MemConfig->CkeRankMapping));
+  DEBUG ((DEBUG_INFO, " RhPrevention           : 0x%x\n", MemConfig->RhPrevention));
+  DEBUG ((DEBUG_INFO, " RhSolution             : 0x%x\n", MemConfig->RhSolution));
+  DEBUG ((DEBUG_INFO, " RhActProbability       : 0x%x\n", MemConfig->RhActProbability));
+  DEBUG ((DEBUG_INFO, " VttTermination         : 0x%x\n", MemConfig->VttTermination));
+  DEBUG ((DEBUG_INFO, " VttCompForVsshi        : 0x%x\n", MemConfig->VttCompForVsshi));
+  DEBUG ((DEBUG_INFO, " BerEnable              : 0x%x\n", MemConfig->BerEnable));
+  for (Index = 0; Index < 4; Index++) {
+    DEBUG ((DEBUG_INFO, " BerAddress[%d]      : 0x%x\n",Index , MemConfig->BerAddress[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " CleanMemory            : 0x%x\n", MemConfigNoCrc->CleanMemory));
+  DEBUG ((DEBUG_INFO, " MemTestOnWarmBoot      : 0x%x\n", MemConfigNoCrc->MemTestOnWarmBoot));
+  DEBUG ((DEBUG_INFO, " ExitOnFailure          : 0x%x\n", MemConfig->ExitOnFailure));
+  DEBUG ((DEBUG_INFO, " Vc1ReadMeter           : 0x%x\n", MemConfig->Vc1ReadMeter));
+  DEBUG ((DEBUG_INFO, " SaGv                   : 0x%x\n", MemConfig->SaGv));
+  DEBUG ((DEBUG_INFO, " FreqSaGvLow            : 0x%x\n FreqSaGvMid            : 0x%x\n",
+          MemConfig->FreqSaGvLow, MemConfig->FreqSaGvMid));
+  DEBUG ((DEBUG_INFO, " StrongWkLeaker         : 0x%x\n", MemConfig->StrongWkLeaker));
+  DEBUG ((DEBUG_INFO, " CaVrefConfig           : 0x%x\n", MemConfig->CaVrefConfig));
+  DEBUG ((DEBUG_INFO, " SimicsFlag             : 0x%x\n", MemConfig->SimicsFlag));
+  DEBUG ((DEBUG_INFO, " PlatformMemorySize     : 0x%x\n", MemConfigNoCrc->PlatformMemorySize));
+  DEBUG ((DEBUG_INFO, " SmramMask              : 0x%x\n", MemConfig->SmramMask));
+  DEBUG ((DEBUG_INFO, " DllBwEn0: %d\n DllBwEn1: %d\n DllBwEn2: %d\n DllBwEn3: %d\n",
+          MemConfig->DllBwEn0, MemConfig->DllBwEn1, MemConfig->DllBwEn2, MemConfig->DllBwEn3));
+  DEBUG ((DEBUG_INFO, " RetrainOnFastFail: %d\n ForceOltmOrRefresh2x: %d\n",
+          MemConfig->RetrainOnFastFail, MemConfig->ForceOltmOrRefresh2x));
+  DEBUG ((DEBUG_INFO, " RmtPerTask: %u\n TrainTrace: %u\n", MemConfig->RmtPerTask, MemConfig->TrainTrace));
+  DEBUG ((DEBUG_INFO, " tRd2RdSG               : 0x%x\n tRd2RdDG               : 0x%x\n", MemConfig->tRd2RdSG, MemConfig->tRd2RdDG));
+  DEBUG ((DEBUG_INFO, " tRd2RdDR               : 0x%x\n tRd2RdDD               : 0x%x\n", MemConfig->tRd2RdDR, MemConfig->tRd2RdDD));
+  DEBUG ((DEBUG_INFO, " tRd2WrSG               : 0x%x\n tRd2WrDG               : 0x%x\n", MemConfig->tRd2WrSG, MemConfig->tRd2WrDG));
+  DEBUG ((DEBUG_INFO, " tRd2WrDR               : 0x%x\n tRd2WrDD               : 0x%x\n", MemConfig->tRd2WrDR, MemConfig->tRd2WrDD));
+  DEBUG ((DEBUG_INFO, " tWr2RdSG               : 0x%x\n tWr2RdDG               : 0x%x\n", MemConfig->tWr2RdSG, MemConfig->tWr2RdDG));
+  DEBUG ((DEBUG_INFO, " tWr2RdDR               : 0x%x\n tWr2RdDD               : 0x%x\n", MemConfig->tWr2RdDR, MemConfig->tWr2RdDD));
+  DEBUG ((DEBUG_INFO, " tWr2WrSG               : 0x%x\n tWr2WrDG               : 0x%x\n", MemConfig->tWr2WrSG, MemConfig->tWr2WrDG));
+  DEBUG ((DEBUG_INFO, " tWr2WrDR               : 0x%x\n tWr2WrDD               : 0x%x\n", MemConfig->tWr2WrDR, MemConfig->tWr2WrDD));
+  DEBUG ((DEBUG_INFO, "------------------------ OVERCLOCKING_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", OcPreMemConfig->Header.Revision));
+  ASSERT (OcPreMemConfig->Header.Revision == SA_OVERCLOCKING_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " OcSupport : 0x%x\n", OcPreMemConfig->OcSupport));
+  DEBUG ((DEBUG_INFO, " GtMaxOcRatio : 0x%x\n", OcPreMemConfig->GtMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " GtVoltageMode : 0x%x\n", OcPreMemConfig->GtVoltageMode));
+  DEBUG ((DEBUG_INFO, " GtVoltageOffset : 0x%x\n", OcPreMemConfig->GtVoltageOffset));
+  DEBUG ((DEBUG_INFO, " GtVoltageOverride : 0x%x\n", OcPreMemConfig->GtVoltageOverride));
+  DEBUG ((DEBUG_INFO, " GtExtraTurboVoltage : 0x%x\n", OcPreMemConfig->GtExtraTurboVoltage));
+  DEBUG ((DEBUG_INFO, " SaVoltageOffset : 0x%x\n", OcPreMemConfig->SaVoltageOffset));
+  DEBUG ((DEBUG_INFO, " GtusMaxOcRatio : 0x%x\n", OcPreMemConfig->GtusMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " GtusVoltageMode : 0x%x\n", OcPreMemConfig->GtusVoltageMode));
+  DEBUG ((DEBUG_INFO, " GtusVoltageOffset : 0x%x\n", OcPreMemConfig->GtusVoltageOffset));
+  DEBUG ((DEBUG_INFO, " GtusVoltageOverride : 0x%x\n", OcPreMemConfig->GtusVoltageOverride));
+  DEBUG ((DEBUG_INFO, " GtusExtraTurboVoltage : 0x%x\n", OcPreMemConfig->GtusExtraTurboVoltage));
+  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+    DEBUG ((DEBUG_INFO, " DqByteMapCh%d        : ", Index));
+    for (Index2 = 0; Index2 < SA_MRC_ITERATION_MAX; Index2++) {
+      DEBUG ((DEBUG_INFO, "0x%02x ", MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][0]));
+      DEBUG ((DEBUG_INFO, "0x%02x ", MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][1]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+    DEBUG ((DEBUG_INFO, " DqsMapCpu2DramCh%d   : ", Index));
+    for (Index2 = 0; Index2 < SA_MC_MAX_BYTES_NO_ECC; Index2++) {
+      DEBUG ((DEBUG_INFO, "%d ", MemConfigNoCrc->DqsMap->DqsMapCpu2Dram[Index][Index2]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print END -----------------\n"));
+  DEBUG_CODE_END ();
+  return;
+}
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi - Instance of SI_POLICY_PPI
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  INTN                                  Index;
+  EFI_STATUS                            Status;
+  GRAPHICS_PEI_CONFIG                   *GtConfig;
+  PCIE_PEI_CONFIG                       *PciePeiConfig;
+  SA_MISC_PEI_CONFIG                    *MiscPeiConfig;
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *) &GtConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID *) &PciePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid, (VOID *) &MiscPeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", SiPolicyPpi->TableHeader.Header.Revision));
+  ASSERT (SiPolicyPpi->TableHeader.Header.Revision == SI_POLICY_REVISION);
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_CONFIG  -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", MiscPeiConfig->Header.Revision));
+  ASSERT (MiscPeiConfig->Header.Revision == SA_MISC_PEI_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " ChapDeviceEnable : 0x%x\n", MiscPeiConfig->ChapDeviceEnable));
+  DEBUG ((DEBUG_INFO, " Device4Enable : 0x%x\n", MiscPeiConfig->Device4Enable));
+  DEBUG ((DEBUG_INFO, " CridEnable : 0x%x\n", MiscPeiConfig->CridEnable));
+  DEBUG ((DEBUG_INFO, " SkipPamLock : 0x%x\n", MiscPeiConfig->SkipPamLock));
+  DEBUG ((DEBUG_INFO, " EdramTestMode : 0x%x\n", MiscPeiConfig->EdramTestMode));
+
+  DEBUG ((DEBUG_INFO, "------------------------ GRAPHICS_PEI_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", GtConfig->Header.Revision));
+  ASSERT (GtConfig->Header.Revision == GRAPHICS_PEI_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " RenderStandby : 0x%x\n", GtConfig->RenderStandby));
+  DEBUG ((DEBUG_INFO, " PmSupport : 0x%x\n", GtConfig->PmSupport));
+  DEBUG ((DEBUG_INFO, " PavpEnable : 0x%x\n", GtConfig->PavpEnable));
+  DEBUG ((DEBUG_INFO, " CdClock : 0x%x\n", GtConfig->CdClock));
+  DEBUG ((DEBUG_INFO, " PeiGraphicsPeimInit : 0x%x\n", GtConfig->PeiGraphicsPeimInit));
+  DEBUG ((DEBUG_INFO, " LogoPtr : 0x%x\n", GtConfig->LogoPtr));
+  DEBUG ((DEBUG_INFO, " LogoSize : 0x%x\n", GtConfig->LogoSize));
+  DEBUG ((DEBUG_INFO, " BltBufferAddress : 0x%x\n", GtConfig->BltBufferAddress));
+  DEBUG ((DEBUG_INFO, " BltBufferSize : 0x%x\n", GtConfig->BltBufferSize));
+  DEBUG ((DEBUG_INFO, " GraphicsConfigPtr : 0x%x\n", GtConfig->GraphicsConfigPtr));
+  DEBUG ((DEBUG_INFO, " CdynmaxClampEnable : 0x%x\n", GtConfig->CdynmaxClampEnable));
+  DEBUG ((DEBUG_INFO, " GtFreqMax : 0x%x\n", GtConfig->GtFreqMax));
+  DEBUG ((DEBUG_INFO, " DisableTurboGt : 0x%x\n", GtConfig->DisableTurboGt));
+  DEBUG ((DEBUG_INFO, " DdiPortEdp  : 0x%x\n", GtConfig->DdiConfiguration.DdiPortEdp));
+  DEBUG ((DEBUG_INFO, " DdiPortBHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortBHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortCHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortCHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortDHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortDHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortFHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortFHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortBDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortBDdc));
+  DEBUG ((DEBUG_INFO, " DdiPortCDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortCDdc));
+  DEBUG ((DEBUG_INFO, " DdiPortDDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortDDdc));
+  DEBUG ((DEBUG_INFO, " DdiPortFDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortFDdc));
+  DEBUG ((DEBUG_INFO, " SkipS3CdClockInit : 0x%x\n", GtConfig->SkipS3CdClockInit));
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCIE_PEI_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", PciePeiConfig->Header.Revision));
+  ASSERT (PciePeiConfig->Header.Revision == SA_PCIE_PEI_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " DmiExtSync : 0x%x\n", PciePeiConfig->DmiExtSync));
+  DEBUG ((DEBUG_INFO, " DmiIot : 0x%x\n", PciePeiConfig->DmiIot));
+  DEBUG ((DEBUG_INFO, " DmiAspm : 0x%x\n", PciePeiConfig->DmiAspm));
+  DEBUG ((DEBUG_INFO, "\n PegSlotPowerLimitValue[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegSlotPowerLimitValue[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegSlotPowerLimitScale[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegSlotPowerLimitScale[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegPhysicalSlotNumber[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegPhysicalSlotNumber[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegDeEmphasis[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegDeEmphasis[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegMaxPayload[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegMaxPayload[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print END -----------------\n"));
+  DEBUG_CODE_END ();
+  return;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
new file mode 100644
index 0000000000..97b58c460f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
@@ -0,0 +1,114 @@
+## @file
+//
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+//-----------------------------------------------------------------------------
+//
+//  Section:     SaMmioRead64
+//
+//  Description: Read 64 bits from the Memory Mapped I/O space.
+//  Use MMX instruction for atomic access, because some MC registers have side effect.
+//
+//  @param[in] Address - Memory mapped I/O address.
+//
+//-----------------------------------------------------------------------------
+//UINT64
+//SaMmioRead64 (
+//  IN  UINTN Address
+//  )
+
+ASM_GLOBAL ASM_PFX(SaMmioRead64)
+ASM_PFX(SaMmioRead64):
+   subl    $16, %esp
+   movq    %mm0, (%esp)       //Save mm0 on stack
+   movl    20(%esp), %edx     //edx = Address
+   movq    (%edx), %mm0       //mm0 = [Address]
+   movq    %mm0, 8(%esp)      //Store mm0 on Stack
+   movq    (%esp), %mm0       //Restore mm0
+   emms
+   movl    8(%esp), %eax      //eax = [Address][31:0]
+   movl    12(%esp), %edx     //edx = [Address][64:32]
+   addl    $16, %esp
+   ret
+
+//-----------------------------------------------------------------------------
+//
+//  Section:     SaMmioWrite64
+//
+//  Description: Write 64 bits to the Memory Mapped I/O space.
+//  Use MMX instruction for atomic access, because some MC registers have side effect.
+//
+//  @param[in] Address - Memory mapped I/O address.
+//  @param[in] Value   - The value to write.
+//
+//-----------------------------------------------------------------------------
+
+//UINT64
+//SaMmioWrite64 (
+//  IN UINTN Address,
+//  IN UINT64 Value
+//  )
+
+ASM_GLOBAL ASM_PFX(SaMmioWrite64)
+ASM_PFX(SaMmioWrite64):
+   subl    $8, %esp
+   movq    %mm0, (%esp)       //Save mm0 on Stack
+   movl    12(%esp), %edx     //edx = Address
+   movq    16(%esp), %mm0     //mm0 = Value
+   movq    %mm0, (%edx)       //[Address] = Value
+   movq    (%esp), %mm0       //Restore mm0
+   emms
+   movl     16(%esp), %eax    //eax = Value[31:0]
+   movl     20(%esp), %edx    //edx = Value[64:32]
+   addl     $8, %esp
+   ret
+
+//-----------------------------------------------------------------------------
+//  Intel Silicon View Technology check point interface based on IO port reading
+//
+//  @param CheckPoint        Check point AH value.
+//                           AH = 0x10:  End of MRC State
+//                           AH = 0x20:  End of DXE State
+//                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+//                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD);
+//
+//  @param PortReading       IO port reading address used for breakpoints
+//-----------------------------------------------------------------------------
+
+//VOID
+//EFIAPI
+//IsvtCheckPoint (
+//  IN UINT32          CheckPoint,
+//  IN UINT32          PortReading
+//  )
+
+ASM_GLOBAL ASM_PFX(IsvtCheckPoint)
+ASM_PFX(IsvtCheckPoint):
+   pushl    %eax
+   pushl    %edx
+
+   // Stack layout at this point:
+   //-------------
+   // PortReading     ESP + 16
+   //-------------
+   // CheckPoint      ESP + 12
+   //-------------
+   // EIP             ESP + 8
+   //-------------
+   // EAX             ESP + 4
+   //-------------
+   // EDX         <-- ESP
+   //-------------
+
+   mov      12(%esp), %ah    // CheckPoint
+   mov      16(%esp), %dx    // PortReading
+   in       %dx, %al         // signal debugger
+
+   popl     %edx
+   popl     %eax
+   ret
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
new file mode 100644
index 0000000000..288fe7a2fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
@@ -0,0 +1,126 @@
+; @file
+;  This file provides assembly 64-bit atomic reads/writes required for memory initialization.
+;
+; Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+.686p
+.xmm
+.model small, c
+
+.CODE
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioRead64
+;
+;  Description: Read 64 bits from the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioRead64 (
+;  IN  UINTN Address
+;  )
+
+SaMmioRead64    PROC    NEAR    PUBLIC
+   sub     esp, 16
+   movq    [esp], mm0         ;Save mm0 on stack
+   mov     edx,  [esp + 20]   ;edx = Address
+   movq    mm0, [edx]         ;mm0 = [Address]
+   movq    [esp + 8], mm0     ;Store mm0 on Stack
+   movq    mm0, [esp]         ;Restore mm0
+   emms
+   mov     eax, [esp + 8]     ;eax = [Address][31:0]
+   mov     edx, [esp + 12]    ;edx = [Address][64:32]
+   add     esp, 16
+   ret
+SaMmioRead64    ENDP
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioWrite64
+;
+;  Description: Write 64 bits to the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;  @param[in] Value   - The value to write.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioWrite64 (
+;  IN UINTN Address,
+;  IN UINT64 Value
+;  )
+
+SaMmioWrite64    PROC    NEAR    PUBLIC
+   sub     esp, 8
+   movq    [esp], mm0          ;Save mm0 on Stack
+   mov     edx, [esp + 12]     ;edx = Address
+   movq    mm0, [esp + 16]     ;mm0 = Value
+   movq    [edx], mm0          ;[Address] = Value
+   movq    mm0, [esp]          ;Restore mm0
+   emms
+   mov     eax, [esp + 16]     ;eax = Value[31:0]
+   mov     edx, [esp + 20]     ;edx = Value[64:32]
+   add     esp, 8
+   ret
+SaMmioWrite64    ENDP
+
+
+;-----------------------------------------------------------------------------
+;  Intel Silicon View Technology check point interface based on IO port reading
+;
+;  @param CheckPoint        Check point AH value.
+;                           AH = 0x10:  End of MRC State
+;                           AH = 0x20:  End of DXE State
+;                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+;                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD);
+;
+;  @param PortReading       IO port reading address used for breakpoints
+;-----------------------------------------------------------------------------
+
+;VOID
+;EFIAPI
+;IsvtCheckPoint (
+;  IN UINT32          CheckPoint,
+;  IN UINT32          PortReading
+;  )
+
+IsvtCheckPoint    PROC    NEAR    PUBLIC
+   push eax
+   push edx
+
+   ; Stack layout at this point:
+   ;-------------
+   ; PortReading     ESP + 16
+   ;-------------
+   ; CheckPoint      ESP + 12
+   ;-------------
+   ; EIP             ESP + 8
+   ;-------------
+   ; EAX             ESP + 4
+   ;-------------
+   ; EDX         <-- ESP
+   ;-------------
+
+   mov  ah, BYTE PTR [esp + 12]      ; CheckPoint
+   mov  dx, WORD PTR [esp + 16]      ; PortReading
+   in   al, dx                       ; signal debugger
+
+   pop  edx
+   pop  eax
+   ret
+IsvtCheckPoint    ENDP
+
+
+end
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm
new file mode 100644
index 0000000000..da7ef004ad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm
@@ -0,0 +1,118 @@
+; @file
+;  This file provides assembly 64-bit atomic reads/writes required for memory initialization.
+;
+; Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioRead64
+;
+;  Description: Read 64 bits from the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioRead64 (
+;  IN  UINTN Address
+;  )
+
+global ASM_PFX(SaMmioRead64)
+ASM_PFX(SaMmioRead64):
+   sub     esp, 16
+   movq    [esp], mm0         ;Save mm0 on stack
+   mov     edx,  [esp + 20]   ;edx = Address
+   movq    mm0, [edx]         ;mm0 = [Address]
+   movq    [esp + 8], mm0     ;Store mm0 on Stack
+   movq    mm0, [esp]         ;Restore mm0
+   emms
+   mov     eax, [esp + 8]     ;eax = [Address][31:0]
+   mov     edx, [esp + 12]    ;edx = [Address][64:32]
+   add     esp, 16
+   ret
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioWrite64
+;
+;  Description: Write 64 bits to the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;  @param[in] Value   - The value to write.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioWrite64 (
+;  IN UINTN Address,
+;  IN UINT64 Value
+;  )
+
+global ASM_PFX(SaMmioWrite64)
+ASM_PFX(SaMmioWrite64):
+   sub     esp, 8
+   movq    [esp], mm0          ;Save mm0 on Stack
+   mov     edx, [esp + 12]     ;edx = Address
+   movq    mm0, [esp + 16]     ;mm0 = Value
+   movq    [edx], mm0          ;[Address] = Value
+   movq    mm0, [esp]          ;Restore mm0
+   emms
+   mov     eax, [esp + 16]     ;eax = Value[31:0]
+   mov     edx, [esp + 20]     ;edx = Value[64:32]
+   add     esp, 8
+   ret
+
+;-----------------------------------------------------------------------------
+;  Intel Silicon View Technology check point interface based on IO port reading
+;
+;  @param CheckPoint        Check point AH value.
+;                           AH = 0x10:  End of MRC State
+;                           AH = 0x20:  End of DXE State
+;                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+;                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD);
+;
+;  @param PortReading       IO port reading address used for breakpoints
+;-----------------------------------------------------------------------------
+
+;VOID
+;EFIAPI
+;IsvtCheckPoint (
+;  IN UINT32          CheckPoint,
+;  IN UINT32          PortReading
+;  )
+
+global ASM_PFX(IsvtCheckPoint)
+ASM_PFX(IsvtCheckPoint):
+   push eax
+   push edx
+
+   ; Stack layout at this point:
+   ;-------------
+   ; PortReading     ESP + 16
+   ;-------------
+   ; CheckPoint      ESP + 12
+   ;-------------
+   ; EIP             ESP + 8
+   ;-------------
+   ; EAX             ESP + 4
+   ;-------------
+   ; EDX         <-- ESP
+   ;-------------
+
+   mov  ah, BYTE [esp + 12]      ; CheckPoint
+   mov  dx, WORD [esp + 16]      ; PortReading
+   in   al, dx                   ; signal debugger
+
+   pop  edx
+   pop  eax
+   ret
+
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (24 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
                   ` (11 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

* PchInitDxeCnl - Generic DXE PCH initialization.
* PchInitDxeFspCnl - Generic DXE PCH FSP initialization.
* PchInitSmm - Generic SMM PCH initialization.
* SmmControl - Produces an instance of EFI_SMM_CONTROL2_PROTOCOL.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf            |  99 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf         |  77 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf               | 101 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf     |  54 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf                    |  45 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h                    | 223 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h                 | 187 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h | 132 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c                    | 451 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c                |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c                 | 323 ++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c                    | 554 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c                 | 382 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c                 |  85 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c                    |  89 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c                |  57 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c             | 156 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c        | 156 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c                 | 179 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c                | 298 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c                 | 436 +++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c                |  69 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c | 399 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c                         | 310 +++++++++++
 24 files changed, 4895 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
new file mode 100644
index 0000000000..5e0cf06cb6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
@@ -0,0 +1,99 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE823
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = PchInitEntryPointDxe
+
+
+[LibraryClasses]
+S3BootScriptLib
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PchPciExpressHelpersLib
+UefiBootServicesTableLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+UefiLib
+DxeServicesTableLib
+UefiDriverEntryPoint
+UefiRuntimeServicesTableLib
+AslUpdateLib
+CpuPlatformLib
+GpioLib
+PchSerialIoLib
+PchHdaLib
+PchInitCommonLib
+ConfigBlockLib
+PmcLib
+PmcPrivateLib
+PmcPrivateLibWithS3
+SataLib
+PchDmiWithS3Lib
+PchGbeLib
+SiScheduleResetLib
+BiosLockLib
+DxeSaPolicyLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+
+
+[Sources]
+PchInitDxe.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+PchSerialIoDxe.c
+PchHdaAcpi.c
+PchCnviAcpi.c
+PchAcpi.c
+
+[Protocols]
+gPchNvsAreaProtocolGuid ## PRODUCES
+gPchEmmcTuningProtocolGuid ## PRODUCES
+gEfiPciIoProtocolGuid ## CONSUMES
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiBlockIoProtocolGuid ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## CONSUMES
+gPchPolicyProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gEfiAcpiTableGuid
+gSiConfigHobGuid                 ## CONSUMES
+gPchConfigHobGuid                ## CONSUMES
+gPchRstHobGuid                   ## CONSUMES
+gHdAudioDxeConfigGuid            ## CONSUMES
+gGpioDxeConfigGuid               ## 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/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
new file mode 100644
index 0000000000..528cfd0296
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
@@ -0,0 +1,77 @@
+## @file
+#  Component description file for Pch Initialization driver for FSP package
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = PchInitDxe
+FILE_GUID            = 5AA5031E-4CB6-43D4-B219-FE50FF5D116C
+MODULE_TYPE          = PEIM
+VERSION_STRING       = 1.0
+ENTRY_POINT          = PchInitEntryPointFsp
+
+
+[LibraryClasses]
+PeimEntryPoint
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PchPciExpressHelpersLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+GpioLib
+PchSerialIoLib
+PchInitCommonLib
+S3BootScriptLib  # NULL library
+ConfigBlockLib
+PmcLib
+PmcPrivateLib
+PmcPrivateLibWithS3
+UsbInitLib
+PchDmiWithS3Lib
+PchGbeLib
+SiScheduleResetLib
+BiosLockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Sources]
+PchInitFsp.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+
+
+[Protocols]
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEventReadyToBootGuid
+gSiConfigHobGuid                 ## CONSUMES
+gPchConfigHobGuid                ## CONSUMES
+
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
new file mode 100644
index 0000000000..308da65385
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
@@ -0,0 +1,101 @@
+## @file
+# Component description file for PchInitSmm driver
+#
+# Copyright (c) 2019 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
+PchPciExpressHelpersLib
+SmmServicesTableLib
+PciSegmentLib
+HobLib
+GpioLib
+GpioPrivateLib
+ReportStatusCodeLib
+DevicePathLib
+PmcLib
+PchPcieRpLib
+PchInfoLib
+TimerLib
+ConfigBlockLib
+PmcPrivateLib
+SataLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemSize
+
+
+[Sources]
+PchInitSmm.c
+PchPcieSmm.c
+PchLanSxSmm.c
+PchInitSmm.h
+PchBiosWriteProtect.c
+PchSpiAsync.c
+
+
+[Protocols]
+gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES
+gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
+gPchSmmIoTrapControlGuid ## CONSUMES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+gPchNvsAreaProtocolGuid ## CONSUMES
+gPchPcieSmiDispatchProtocolGuid ## CONSUMES
+gPchTcoSmiDispatchProtocolGuid ## CONSUMES
+gPchSmiDispatchProtocolGuid ## CONSUMES
+gPchEspiSmiDispatchProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## PRODUCES
+
+
+[Guids]
+gSiConfigHobGuid             ## CONSUMES
+gPchConfigHobGuid            ## CONSUMES
+gPchDeviceTableHobGuid
+
+
+[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 # This is for SmmServicesTableLib
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000000..ff712f8635
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,54 @@
+## @file
+# Component description file for SmmControl module
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmControlDriver.h
+SmmControlDriver.c
+
+
+[Protocols]
+gEfiSmmControl2ProtocolGuid ## PRODUCES
+
+
+[Guids]
+gEfiEventVirtualAddressChangeGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
new file mode 100644
index 0000000000..77bd3ad72b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchSpiSmm
+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
+PchSpiCommonLib
+SmmPchPrivateLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSpi.c
+
+
+[Protocols]
+gPchSmmSpiProtocolGuid ## PRODUCES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+
+[Depex]
+gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
+gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
new file mode 100644
index 0000000000..b84c574a2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
@@ -0,0 +1,223 @@
+/** @file
+  Header file for PCH Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_DXE_H_
+#define _PCH_INIT_DXE_H_
+
+#include <Protocol/PchEmmcTuning.h>
+#include <SiConfigHob.h>
+#include <Private/PchConfigHob.h>
+#include <Private/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
+//
+/**
+  Initialize the PCH device according to the PCH Policy HOB
+  and install PCH info instance.
+
+**/
+VOID
+InitializePchDevice (
+  VOID
+  );
+
+/**
+  Common PchInit Module Entry Point
+**/
+VOID
+PchInitEntryPointCommon (
+  VOID
+  );
+
+/**
+  Common PCH initialization on PCI enumeration complete.
+**/
+VOID
+PchOnPciEnumCompleteCommon (
+  VOID
+  );
+
+/**
+  Configures Serial IO Controllers
+
+**/
+EFI_STATUS
+ConfigureSerialIoAtBoot (
+  VOID
+  );
+
+/**
+  Creates device handles for SerialIo devices in ACPI mode
+
+**/
+VOID
+CreateSerialIoHandles (
+  VOID
+  );
+
+/**
+  Mark memory used by SerialIo devices in ACPI mode as allocated
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+AllocateSerialIoMemory (
+  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
+  );
+
+/**
+  Update ASL definitions for SerialIo devices.
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+  VOID
+  );
+
+/**
+  Initialize PCIE SRC clocks in ICC subsystem
+
+  @param[in] GbePortNumber        Number of PCIE rootport assigned to GbE adapter
+
+**/
+VOID
+ConfigurePchPcieClocks (
+  IN UINTN                        GbePortNumber
+  );
+
+/**
+  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
+  );
+
+/**
+  Configure eMMC in HS400 Mode
+
+  @param[in] This                         A pointer to PCH_EMMC_TUNING_PROTOCOL structure
+  @param[in] Revision                     Revision parameter used to verify the layout of EMMC_INFO and TUNINGDATA.
+  @param[in] EmmcInfo                     A pointer to EMMC_INFO structure
+  @param[out] EmmcTuningData              A pointer to EMMC_TUNING_DATA structure
+
+  @retval EFI_SUCCESS                     The function completed successfully
+  @retval EFI_NOT_FOUND                   The item was not found
+  @retval EFI_OUT_OF_RESOURCES            The request could not be completed due to a lack of resources.
+  @retval EFI_INVALID_PARAMETER           A parameter was incorrect.
+  @retval EFI_DEVICE_ERROR                Hardware Error
+  @retval EFI_NO_MEDIA                    No media
+  @retval EFI_MEDIA_CHANGED               Media Change
+  @retval EFI_BAD_BUFFER_SIZE             Buffer size is bad
+  @retval EFI_CRC_ERROR                   Command or Data CRC Error
+**/
+EFI_STATUS
+EFIAPI
+ConfigureEmmcHs400Mode (
+  IN  PCH_EMMC_TUNING_PROTOCOL          *This,
+  IN  UINT8                             Revision,
+  IN  EMMC_INFO                         *EmmcInfo,
+  OUT EMMC_TUNING_DATA                  *EmmcTuningData
+  );
+
+/**
+  Get eMMC PCI cfg space address
+
+  @return UINT64  PCI base address
+**/
+UINT64
+ScsGetEmmcBaseAddress (
+  VOID
+  );
+
+/**
+  Perform the remaining configuration on PCH SATA to perform device detection,
+  then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+  @retval None
+**/
+VOID
+ConfigurePchSataOnEndOfDxe (
+  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
+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
+  );
+
+/**
+  Initialize PCH Nvs Area opeartion region.
+
+**/
+VOID
+PatchPchNvsAreaAddress (
+  VOID
+  );
+
+#endif // _PCH_INIT_DXE_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
new file mode 100644
index 0000000000..693c5d3f50
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
@@ -0,0 +1,187 @@
+/** @file
+  Header file for PCH Init SMM Handler
+
+  Copyright (c) 2019 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/PchEspiLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Private/Library/PchPciExpressHelpersLib.h>
+#include <Protocol/PchPcieSmiDispatch.h>
+#include <Protocol/PchTcoSmiDispatch.h>
+#include <Protocol/PchSmiDispatch.h>
+#include <Protocol/PchEspiSmiDispatch.h>
+#include <Protocol/PchSmmIoTrapControl.h>
+#include <Private/Protocol/PchNvsArea.h>
+#include <Private/Protocol/PcieIoTrap.h>
+#include <SiConfigHob.h>
+#include <Private/PchConfigHob.h>
+#include <Private/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
+  );
+
+/**
+  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
+  );
+
+/**
+  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/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000000..08e64fa5a7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,132 @@
+/** @file
+  Header file for SMM Control Driver.
+
+  Copyright (c) 2019 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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
new file mode 100644
index 0000000000..bcbdb12dc3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
@@ -0,0 +1,451 @@
+/** @file
+  This is the driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 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 <IndustryStandard/Pci.h>
+
+#include "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/GpioDevConfig.h>
+#include <ConfigBlock/ScsConfig.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchGbeLib.h>
+#include <Private/PchRstHob.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SataLib.h>
+#include <Register/PchRegsSata.h>
+#include <TraceHubCommonConfig.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegsTraceHub.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA_PROTOCOL    mPchNvsAreaProtocol;
+
+/**
+  Retrieve interrupt information about a PCH device from policy
+
+  @param[in] Device                     PCI device number
+
+  @retval PCH_DEVICE_INTERRUPT_CONFIG   structure with device's interrupt information
+**/
+PCH_DEVICE_INTERRUPT_CONFIG
+GetInterruptPolicy (
+  IN PCH_SERIAL_IO_CONTROLLER  Device
+  )
+{
+  PCH_DEVICE_INTERRUPT_CONFIG EmptyRecord;
+  UINT8                       DevNum;
+  UINT8                       FuncNum;
+  UINT8                       Index;
+
+  ZeroMem (&EmptyRecord, sizeof (PCH_DEVICE_INTERRUPT_CONFIG));
+  DevNum  = GetSerialIoDeviceNumber (Device);
+  FuncNum = GetSerialIoFunctionNumber (Device);
+
+  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.
+
+  @retval EFI_SUCCESS                   The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Index;
+
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    mPchNvsAreaProtocol.Area->SMD[Index] = mPchConfigHob->SerialIo.DevMode[Index];
+    mPchNvsAreaProtocol.Area->SIR[Index] = (GetInterruptPolicy (Index)).Irq;
+    mPchNvsAreaProtocol.Area->SB0[Index] = (UINT32) FindSerialIoBar (Index, 0);
+    mPchNvsAreaProtocol.Area->SB1[Index] = (UINT32) FindSerialIoBar (Index, 1);
+  }
+  if (IsPchH ()) {
+    mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C4] = PchSerialIoDisabled;
+    mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C5] = PchSerialIoDisabled;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Update NVS Area after RST PCIe Storage Remapping and before Boot
+**/
+VOID
+PchUpdateNvsAreaAfterRemapping (
+  VOID
+  )
+{
+  UINTN                 Index;
+  VOID                  *Hob;
+  PCH_RST_HOB           *RstHob;
+
+  Hob = GetFirstGuidHob (&gPchRstHobGuid);
+  if (Hob == NULL) {
+    DEBUG (( DEBUG_INFO , "PchUpdateNvsAreaAfterRemapping: cannot fetch RstHob" ));
+    return;
+  }
+
+  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;
+  }
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS  Status;
+
+  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 ();
+
+  //
+  // Update Pch Nvs Area
+  //
+  Status = PchUpdateNvsArea ();
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  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
+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 ();
+
+  //
+  // 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 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;
+  PCH_GPIO_DXE_CONFIG   *GpioDxeConfig;
+
+  ///
+  /// 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++) {
+    Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFun);
+    ASSERT_EFI_ERROR (Status);
+
+    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].LtrMaxSnoopLatency;
+    mPchNvsAreaProtocol.Area->PcieLtrMaxNoSnoopLatency[Index] = mPchConfigHob->PcieRp.RootPort[Index].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 PMC ACPIBASE and PWRMBASE
+  //
+  mPchNvsAreaProtocol.Area->PMBS = PmcGetAcpiBase ();
+
+  mPchNvsAreaProtocol.Area->PWRM = PmcGetPwrmBase ();
+
+  //
+  // 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
+  //
+  // Update eMMC HS400 mode enablement
+  //
+  mPchNvsAreaProtocol.Area->EMH4 = (UINT8) mPchConfigHob->Scs.ScsEmmcHs400Enabled;
+  mPchNvsAreaProtocol.Area->EmmcEnabled = (UINT8) mPchConfigHob->Scs.ScsEmmcEnabled;
+
+  //
+  // Update eMMC Driver Strength
+  // Per eMMC 5.01 JEDEC Specification (JESD84-B50.1, Table 186)
+  // Nominal Impedance - Driver Type Values:
+  // 50 Ohm              0x0
+  // 33 Ohm              0x1
+  // 40 Ohm              0x4
+  //
+  switch (mPchConfigHob->Scs.ScsEmmcHs400DriverStrength) {
+    case DriverStrength33Ohm:
+      mPchNvsAreaProtocol.Area->EMDS = 0x1;
+      break;
+    case DriverStrength40Ohm:
+      mPchNvsAreaProtocol.Area->EMDS = 0x4;
+      break;
+    case DriverStrength50Ohm:
+    default:
+      mPchNvsAreaProtocol.Area->EMDS = 0x0;
+  }
+
+  mPchNvsAreaProtocol.Area->SdPowerEnableActiveHigh = (UINT8) mPchConfigHob->Scs.ScsSdPowerEnableActiveHigh;
+  mPchNvsAreaProtocol.Area->SdCardEnabled           = (UINT8) mPchConfigHob->Scs.ScsSdCardEnabled;
+
+  //
+  // SATA configuration.
+  //
+  if (PciSegmentRead16 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+    mPchNvsAreaProtocol.Area->SataPortPresence = 0;
+  } else {
+    mPchNvsAreaProtocol.Area->SataPortPresence = PciSegmentRead8 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + R_SATA_CFG_PCS + 2);
+  }
+
+  //
+  // CPU SKU
+  //
+  mPchNvsAreaProtocol.Area->CpuSku = GetCpuSku ();
+
+  mPchNvsAreaProtocol.Area->SlpS0VmRuntimeControl = (UINT8)mPchConfigHob->Pm.SlpS0VmRuntimeControl;
+  mPchNvsAreaProtocol.Area->SlpS0Vm070VSupport    = (UINT8)mPchConfigHob->Pm.SlpS0Vm070VSupport;
+  mPchNvsAreaProtocol.Area->SlpS0Vm075VSupport    = (UINT8)mPchConfigHob->Pm.SlpS0Vm075VSupport;
+  mPchNvsAreaProtocol.Area->PsOnEnable            = (UINT8)mPchConfigHob->Pm.PsOnEnable;
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    mPchNvsAreaProtocol.Area->LtrEnable[Index]  = (UINT8)mPchConfigHob->PcieRp.RootPort[Index].LtrEnable;
+  }
+
+  mPchNvsAreaProtocol.Area->GBES = PchIsGbePresent ();
+
+  //
+  // Update PCH Trace Hub Mode
+  //
+  mPchNvsAreaProtocol.Area->PchTraceHubMode     = (UINT8) mPchConfigHob->PchTraceHub.PchTraceHubMode;
+  //
+  // if SCRPD0[24] is set, force TH to be host debugger mode.
+  //
+  if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS) != 0xFFFFFFFF) {
+    if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS + R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0) & BIT24) {
+      mPchNvsAreaProtocol.Area->PchTraceHubMode = TraceHubModeHostDebugger;
+    }
+  }
+
+  //
+  // Update TWMB, Temp memory base address
+  //
+  mPchNvsAreaProtocol.Area->TempRsvdMemBase = (UINT32) PcdGet32 (PcdSiliconInitTempMemBaseAddr);
+
+  return Status;
+}
+
+/**
+  Initialize PCH Nvs Area opeartion region.
+
+**/
+VOID
+PatchPchNvsAreaAddress (
+  VOID
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Address;
+  UINT16                                Length;
+
+  Status = InitializeAslUpdateLib ();
+  ASSERT_EFI_ERROR (Status);
+
+  Address = (UINT32) (UINTN) mPchNvsAreaProtocol.Area;
+  Length  = (UINT16) sizeof (PCH_NVS_AREA);
+  DEBUG ((DEBUG_INFO, "PatchPchNvsAreaAddress: PCH NVS Address %x Length %x\n", Address, Length));
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','B'), &Address, sizeof (Address));
+  ASSERT_EFI_ERROR (Status);
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','L'), &Length, sizeof (Length));
+  ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
new file mode 100644
index 0000000000..4e38db1027
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
@@ -0,0 +1,33 @@
+/** @file
+  Initializes PCH CNVi device ACPI data.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include "PchInit.h"
+#include <Library/DxeSaPolicyLib.h>
+
+/**
+  Update ASL definitions for CNVi device.
+
+  @retval EFI_SUCCESS         The function completed successfully
+**/
+EFI_STATUS
+UpdateCnviAcpiData (
+  VOID
+  )
+{
+
+  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() Start\n"));
+
+  mPchNvsAreaProtocol.Area->CnviMode = (UINT8) mPchConfigHob->Cnvi.Mode;
+
+  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
new file mode 100644
index 0000000000..57f2e1dca0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
@@ -0,0 +1,323 @@
+/** @file
+  Initializes the PCH HD Audio ACPI Tables.
+
+  Copyright (c) 2019 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 "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/HdAudioConfig.h>
+#include <Private/PchConfigHob.h>
+#include <Library/PchInfoLib.h>
+#include <Private/Library/PchHdaLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsHda.h>
+
+PCH_HDA_NHLT_ENDPOINTS mPchHdaNhltEndpoints[HdaEndpointMax] =
+{
+  {HdaDmicX1,     B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT,                                              0, FALSE},
+  {HdaDmicX2,     (B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT),        0, FALSE},
+  {HdaDmicX4,     (B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT),        0, FALSE},
+  {HdaBtRender,   (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT | B_HDA_BT_A2DP_FORMAT), 0, FALSE},
+  {HdaBtCapture,  (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT),                        0, FALSE},
+  {HdaI2sRender1, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO,      FALSE},
+  {HdaI2sRender2, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO,      FALSE},
+  {HdaI2sCapture, B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_CAPTURE_DEVICE_INFO,    FALSE}
+};
+
+#define DSP_FW_STOLEN_MEMORY_SIZE 0x400000 //4MB
+/**
+  Allocates 4MB of memory for DSP FW usage.
+
+  @retval EFI_PHYSICAL_ADDRESS  Allocated memory address
+**/
+EFI_PHYSICAL_ADDRESS
+AllocateAudioDspStolenMemory (
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PHYSICAL_ADDRESS DspStolenMemBaseAddress;
+
+  DspStolenMemBaseAddress = 0;
+
+  DEBUG ((DEBUG_INFO, "AllocateAudioDspStolenMemory()\n"));
+
+  //
+  // Reserve memory to store Acpi Debug data.
+  //
+  DspStolenMemBaseAddress = 0xFFFFFFFF;
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  EfiReservedMemoryType,
+                  EFI_SIZE_TO_PAGES (DSP_FW_STOLEN_MEMORY_SIZE),
+                  &DspStolenMemBaseAddress
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  ZeroMem ((VOID *) (UINTN) DspStolenMemBaseAddress, DSP_FW_STOLEN_MEMORY_SIZE);
+
+  mPchNvsAreaProtocol.Area->DSPM = (UINT32) DspStolenMemBaseAddress;
+  DEBUG ((DEBUG_INFO, "mPchNvsAreaProtocol.Area->DSPM = 0x%016x\n", mPchNvsAreaProtocol.Area->DSPM));
+
+  return DspStolenMemBaseAddress;
+}
+
+/**
+  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->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) {
+      break;
+    }
+  }
+
+  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;
+}
+
+/**
+  Constructs and installs NHLT table.
+
+  @retval EFI_SUCCESS       ACPI Table installed successfully
+  @retval EFI_UNSUPPORTED   ACPI Table protocol not found
+**/
+EFI_STATUS
+PublishNhltAcpiTable (
+  VOID
+  )
+{
+  UINTN                                     AcpiTableKey;
+  EFI_ACPI_TABLE_PROTOCOL                   *AcpiTable;
+  NHLT_ACPI_TABLE                           *NhltTable;
+  UINT32                                    TableLength;
+  EFI_STATUS                                Status;
+
+  AcpiTable = NULL;
+  NhltTable = NULL;
+  AcpiTableKey = 0;
+
+  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n"));
+
+  //
+  // Locate ACPI support protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+  if ( EFI_ERROR (Status) || AcpiTable == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  NhltConstructor (mPchHdaNhltEndpoints, &NhltTable, &TableLength);
+  NhltAcpiHeaderConstructor (NhltTable, TableLength);
+
+  Status = AcpiTable->InstallAcpiTable (AcpiTable, NhltTable, NhltTable->Header.Length, &AcpiTableKey);
+
+  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n"));
+  return Status;
+}
+
+/**
+  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 PCH_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->NHLA = NhltAcpiTableAddress;
+  mPchNvsAreaProtocol.Area->NHLL = NhltAcpiTableLength;
+  mPchNvsAreaProtocol.Area->ADFM = HdAudioDxeConfig->DspFeatureMask;
+  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;
+}
+
+/**
+  Initialize and publish NHLT (Non-HDA Link Table), update NVS variables.
+
+  @param[in]                *HdAudioConfigHob
+  @param[in]                *HdAudioDxeConfig
+
+  @retval EFI_SUCCESS    The function completed successfully
+**/
+EFI_STATUS
+SetHdaAcpiTable (
+  IN CONST HDAUDIO_HOB            *HdAudioConfigHob,
+  IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
+  )
+{
+  NHLT_ACPI_TABLE     *NhltTable;
+  EFI_STATUS          Status;
+  NhltTable = NULL;
+
+  Status = EFI_SUCCESS;
+
+  if (HdAudioDxeConfig->NhltDefaultFlow == TRUE) {
+    switch (HdAudioDxeConfig->DspEndpointDmic) {
+      case PchHdaDmic1chArray:
+        mPchHdaNhltEndpoints[HdaDmicX1].Enable   = TRUE;
+        break;
+      case PchHdaDmic2chArray:
+        mPchHdaNhltEndpoints[HdaDmicX2].Enable   = TRUE;
+        break;
+      case PchHdaDmic4chArray:
+        mPchHdaNhltEndpoints[HdaDmicX4].Enable   = TRUE;
+        break;
+      case PchHdaDmicDisabled:
+      default:
+        mPchHdaNhltEndpoints[HdaDmicX2].Enable   = FALSE;
+        mPchHdaNhltEndpoints[HdaDmicX4].Enable   = FALSE;
+    }
+
+    if (HdAudioDxeConfig->DspEndpointBluetooth) {
+      mPchHdaNhltEndpoints[HdaBtRender].Enable   = TRUE;
+      mPchHdaNhltEndpoints[HdaBtCapture].Enable  = TRUE;
+    }
+
+    if (HdAudioDxeConfig->DspEndpointI2s) {
+      mPchHdaNhltEndpoints[HdaI2sRender1].Enable = TRUE;
+      mPchHdaNhltEndpoints[HdaI2sRender2].Enable = TRUE;
+      mPchHdaNhltEndpoints[HdaI2sCapture].Enable = TRUE;
+    }
+
+    Status    = PublishNhltAcpiTable ();
+  }
+  NhltTable = LocateNhltAcpiTable ();
+  if (NhltTable == NULL) {
+    return EFI_LOAD_ERROR;
+  }
+
+  UpdateHdaAcpiData ((UINT64) (UINTN) NhltTable, (UINT32) (NhltTable->Header.Length), HdAudioConfigHob, HdAudioDxeConfig);
+
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    AllocateAudioDspStolenMemory ();
+  }
+
+  DEBUG_CODE ( NhltAcpiTableDump (NhltTable); );
+  return Status;
+}
+
+/**
+  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;
+  PCH_HDAUDIO_DXE_CONFIG        *HdAudioDxeConfig;
+
+
+  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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_HDA,
+                 PCI_FUNCTION_NUMBER_PCH_HDA,
+                 0
+                 );
+
+  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;
+  }
+
+  Status = SetHdaAcpiTable (HdAudioConfigHob, HdAudioDxeConfig);
+
+  DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", Status));
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
new file mode 100644
index 0000000000..55f1e086fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
@@ -0,0 +1,554 @@
+/** @file
+  This is the Common driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/SiScheduleResetLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/BiosLockLib.h>
+#include <Library/PchPcrLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsPmc.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB           *mPchConfigHob;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA       *mSiConfigHobData;
+
+//
+// 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);
+
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  ASSERT (HobPtr.Guid != NULL);
+  mSiConfigHobData = (SI_CONFIG_HOB_DATA *) 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   = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      PCI_DEVICE_NUMBER_PCH_SPI,
+                      PCI_FUNCTION_NUMBER_PCH_SPI,
+                      0
+                      );
+
+  //
+  // Check for SPI controller presence before programming
+  //
+  if (PciSegmentRead32 (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);
+
+  //
+  // 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)
+    );
+}
+
+/**
+  Process all the lock downs
+**/
+VOID
+ProcessAllLocks (
+  VOID
+  )
+{
+  UINT8         Data8;
+  UINT16        Data16And;
+  UINT16        Data16Or;
+  UINT32        Data32And;
+  UINT32        Data32Or;
+  UINT64        PciLpcRegBase;
+  UINT16        TcoBase;
+  UINT64        PciSpiRegBase;
+
+  PciLpcRegBase   = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      PCI_DEVICE_NUMBER_PCH_LPC,
+                      PCI_FUNCTION_NUMBER_PCH_LPC,
+                      0
+                      );
+  PciSpiRegBase   = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      PCI_DEVICE_NUMBER_PCH_SPI,
+                      PCI_FUNCTION_NUMBER_PCH_SPI,
+                      0
+                      );
+
+  PchTcoBaseGet (&TcoBase);
+
+  //
+  // Lock function disable (ST and NST PG) register fields.
+  //
+  PmcLockFunctionDisableConfigWithS3BootScript ();
+
+  ///
+  /// PCH BWG Additional PCH DMI and OP-DMI Programming Steps
+  /// Lock DMI.
+  ///
+    PchDmiSetLockWithS3BootScript ();
+
+  //
+  // Lock SPI register before boot.
+  //
+  LockSpiConfiguration ();
+
+  ///
+  /// Additional Power Management Programming
+  /// Step 3
+  /// Lock configuration after stretch and ACPI base programming completed.
+  ///
+  PmcLockSlpSxStretchingPolicyWithS3BootScript ();
+
+  //
+  // Set BiosLock.
+  //
+  if (mPchConfigHob->LockDown.BiosLock == TRUE) {
+    BiosLockEnable ();
+  }
+
+  ///
+  /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+  /// 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]).
+  /// 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 (mPchConfigHob->LockDown.BiosInterface == TRUE) {
+    //
+    // LPC
+    //
+    PciSegmentOr8 ((UINT64) (PciLpcRegBase + R_LPC_CFG_BC), (UINT32) B_LPC_CFG_BC_BILD);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC)
+      );
+
+    //
+    // Reads back for posted write to take effect
+    //
+    Data8 = PciSegmentRead8 ((UINTN) (PciLpcRegBase + R_LPC_CFG_BC));
+    S3BootScriptSaveMemPoll  (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC,
+      &Data8,  // BitMask
+      &Data8,  // BitValue
+      1,       // Duration
+      1        // LoopTimes
+      );
+
+    //
+    // SPI
+    //
+    PciSegmentOr8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC), (UINT32) B_SPI_CFG_BC_BILD);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC)
+      );
+
+    //
+    // Reads back for posted write to take effect
+    //
+    Data8 = PciSegmentRead8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC));
+    S3BootScriptSaveMemPoll  (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
+      &Data8,     // BitMask
+      &Data8,     // BitValue
+      1,          // Duration
+      1           // LoopTimes
+      );
+
+    ///
+    /// Set BIOS interface Lock-Down
+    ///
+    PchDmiSetBiosLockDownWithS3BootScript ();
+  }
+
+  ///
+  /// PCH BIOS Spec on using RTC RAM
+  /// Regardless of BUC.TS being updated or not, BIOS must set RC.BILD bit PCR[RTC] + 3400h[31] before exit
+  /// For Data integrity protection, set RTC Memory locks (Upper 128 Byte Lock and
+  /// Lower 128 Byte Lock) at PCR[RTC] + 3400h[4] and PCR[RTC] + 3400h[3].
+  /// Note once locked bytes 0x38 - 0x3F in each of the Upper and Lower Byte blocks, respectively,
+  /// cannot be unlocked until next reset.
+  ///
+  Data32And = 0xFFFFFFFF;
+  Data32Or = 0x0;
+
+  if (mPchConfigHob->LockDown.BiosInterface == TRUE) {
+    Data32Or  = B_RTC_PCR_CONF_BILD;
+  }
+  if (mPchConfigHob->LockDown.RtcMemoryLock == TRUE) {
+    Data32Or |= (B_RTC_PCR_CONF_UCMOS_LOCK | B_RTC_PCR_CONF_LCMOS_LOCK);
+  }
+  PchPcrAndThenOr32 (
+    PID_RTC_HOST, R_RTC_PCR_CONF,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_RTC_HOST, R_RTC_PCR_CONF,
+    &Data32Or,
+    &Data32And
+    );
+
+  ///
+  ///  Remove access to RTC PCRs
+  ///
+  Data32And = (UINT32)~(BIT0);
+  Data32Or  = 0;
+  PchPcrAndThenOr32 (
+    PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
+    &Data32Or,
+    &Data32And
+    );
+  PchPcrAndThenOr32 (
+    PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
+    &Data32Or,
+    &Data32And
+    );
+
+  //
+  // Lock Down TCO
+  //
+  Data16And = 0xFFFF;
+  Data16Or  = B_TCO_IO_TCO1_CNT_LOCK;
+  IoOr16 (TcoBase + R_TCO_IO_TCO1_CNT, Data16Or);
+  S3BootScriptSaveIoReadWrite (
+    S3BootScriptWidthUint16,
+    (UINTN) (TcoBase + R_TCO_IO_TCO1_CNT),
+    &Data16Or,  // Data to be ORed
+    &Data16And  // Data to be ANDed
+    );
+
+  ///
+  /// PCH BIOS Spec Section 5.15.1 Additional Chipset Initialization
+  /// Step 1
+  /// Lock PMC Set Strap Message Interface
+  ///
+  PmcLockSetStrapMsgInterfaceWithS3BootScript ();
+  //
+  // Lock Down PMC
+  //
+  PmcLockWithS3BootScript ();
+}
+
+/**
+  Set eSPI BME bit
+**/
+VOID
+ConfigureEspiBme (
+  VOID
+  )
+{
+  UINT64 EspiPciBase;
+
+  EspiPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPC,
+                  PCI_FUNCTION_NUMBER_PCH_LPC,
+                  0
+                  );
+
+  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);
+  }
+}
+
+/**
+  Common PCH initialization before Boot Sript Table is closed
+
+**/
+VOID
+PchOnPciEnumCompleteCommon (
+  VOID
+  )
+{
+  UINT32                                    Data32Or;
+  UINT32                                    Data32And;
+  BOOLEAN                                   ResetStatus;
+
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() Start\n"));
+
+  if (SiScheduleResetIsRequired ()) {
+    ResetStatus = SiScheduleResetPerformReset ();
+    ASSERT (!ResetStatus);
+  }
+
+  ProcessAllLocks ();
+
+  //
+  // Perform remaining configuration for PCH SATA on End of DXE
+  //
+  ConfigurePchSataOnEndOfDxe ();
+  //
+  // PSTHCTL (0xD00h[2]) = 1, PSTH IOSF Primary Trunk Clock Gating Enable (PSTHIOSFPTCGE)
+  //
+  Data32And = 0xFFFFFFFF;
+  Data32Or =  B_PSTH_PCR_PSTHIOSFPTCGE;
+  PchPcrAndThenOr32 (PID_PSTH, R_PSTH_PCR_PSTHCTL, Data32And, Data32Or);
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_PSTH, R_PSTH_PCR_PSTHCTL,
+    &Data32Or,
+    &Data32And
+    );
+
+  //
+  // Set eSPI BME after PCI enumeration
+  //
+  ConfigureEspiBme ();
+
+  ///
+  /// Clear Global Reset Status, Power Failure and Host Reset Status bits
+  ///
+  PmcClearGlobalResetStatus ();
+  PmcClearPowerFailureStatus ();
+  PmcClearHostResetStatus ();
+
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
new file mode 100644
index 0000000000..b106c849e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
@@ -0,0 +1,382 @@
+/** @file
+  This is the Uefi driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 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 <Private/Protocol/PcieIoTrap.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchPciExpressHelpersLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcie.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsThermalCnl.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 = PciePmTrap;
+    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;
+  UINT64              ThermalPciBase;
+
+  ///
+  /// 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);
+
+  //
+  // Enable Thermal MSE
+  //
+  ThermalPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_THERMAL,
+                     PCI_FUNCTION_NUMBER_PCH_THERMAL,
+                     0
+                     );
+  if (PciSegmentRead16 (ThermalPciBase + PCI_VENDOR_ID_OFFSET) != 0xFFFF) {
+    if (((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBAR) & B_THERMAL_CFG_MEM_TBAR_MASK) != 0) ||
+        ((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBARH) != 0))) {
+      PciSegmentOr8 (ThermalPciBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+    }
+  }
+
+  ReconfigurePciePowerManagementForS3 ();
+  ProcessSmiLocks ();
+#ifndef FSP_WRAPPER_FLAG
+  PchOnPciEnumCompleteCommon ();
+#endif
+  ConfigureSerialIoAtS3Resume ();
+}
+
+/**
+  Register callback functions for PCH DXE.
+**/
+VOID
+PchRegisterNotifications (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   LegacyBootEvent;
+  EFI_EVENT   ExitBootServicesEvent;
+  VOID        *Registration;
+
+  ///
+  /// Create PCI Enumeration Completed callback for PCH
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    PchOnPciEnumComplete,
+    NULL,
+    &Registration
+    );
+
+  //
+  // 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);
+}
+
+/**
+  Initialize the PCH device according to the PCH Policy HOB
+  and install PCH info instance.
+**/
+VOID
+InitializePchDevice (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "InitializePchDevice() Start\n"));
+
+  DEBUG ((DEBUG_INFO, "InitializePchDevice() End\n"));
+}
+/**
+  <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 ();
+
+  InitializePchDevice ();
+
+  Status = PchAcpiInit (ImageHandle);
+
+  CreateSerialIoHandles ();
+
+  PchRegisterNotifications ();
+
+  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, PciePmTrap);
+  } else {
+    ASSERT (FALSE);
+  }
+
+  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() End\n"));
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
new file mode 100644
index 0000000000..15fe4628fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
@@ -0,0 +1,85 @@
+/** @file
+  This is the FSP driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include "PchInit.h"
+
+EFI_STATUS
+EFIAPI
+PchOnPciEnumCompleteFsp (
+  IN  EFI_PEI_SERVICES            **PeiServices,
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN  VOID                        *Ppi
+  );
+
+STATIC
+EFI_PEI_NOTIFY_DESCRIPTOR  mPchOnPciEnumCompleteNotifyList[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK  | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    PchOnPciEnumCompleteFsp
+  }
+};
+
+/**
+  <b>FSP PchInit Module Entry Point for FSP</b>\n
+
+  @param[in] FileHandle      PEIM's file handle
+  @param[in] PeiServices     An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPointFsp (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() Start\n"));
+
+  PchInitEntryPointCommon ();
+
+  Status = PeiServicesNotifyPpi (mPchOnPciEnumCompleteNotifyList);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() End\n"));
+
+  return Status;
+}
+
+/**
+  Fsp PCH initialization on PCI enumeration complete
+
+  @param[in]  PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  @param[in]  NotifyDescriptor  Address of the notification descriptor data structure.
+  @param[in]  Ppi               Address of the PPI that was installed.
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchOnPciEnumCompleteFsp (
+  IN  EFI_PEI_SERVICES            **PeiServices,
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN  VOID                        *Ppi
+  )
+{
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() Start\n"));
+
+  PchOnPciEnumCompleteCommon ();
+
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() End\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
new file mode 100644
index 0000000000..6e30280fa7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
@@ -0,0 +1,89 @@
+/** @file
+  Perform related functions for PCH Sata in DXE phase
+
+  Copyright (c) 2019 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 <Register/PchRegsSata.h>
+
+/**
+  Perform the remaining configuration on PCH SATA to perform device detection,
+  then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+  @retval None
+**/
+VOID
+ConfigurePchSataOnEndOfDxe (
+  VOID
+  )
+{
+  UINT64        PciSataRegBase;
+  UINT16        SataPortsEnabled;
+  UINT32        DwordReg;
+  UINTN         Index;
+  UINT32        SataCtrlIndex;
+
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); 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    = GetSataRegBase (SataCtrlIndex);
+    SataPortsEnabled  = 0;
+
+    DwordReg = PciSegmentRead32 (PciSataRegBase + R_SATA_CFG_PCS);
+    for (Index = 0; Index < GetPchMaxSataPortNum (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 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_MAP,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + 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 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_PCS,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + 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 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC)
+      );
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
new file mode 100644
index 0000000000..d0f4b4fa56
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
@@ -0,0 +1,57 @@
+/** @file
+  Initializes Serial IO Controllers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include "PchInit.h"
+#include <Library/PchSerialIoLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsSerialIo.h>
+
+/**
+  Puts all SerialIo controllers (except UARTs in debug mode) in D3
+  Clears MemoryEnable for all PCI-mode controllers
+**/
+EFI_STATUS
+ConfigureSerialIoAtBoot (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Index;
+  UINTN                    PciCfgBase;
+
+  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
+      if (IsSerialIoFunctionZero (Index)) {
+        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
+          PciCfgBase = FindSerialIoBar (Index,1);
+          MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
+        }
+      }
+      continue;
+    }
+    if ((Index >= PchSerialIoIndexUart0) &&
+        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
+        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
+      continue;
+    }
+    PciCfgBase = FindSerialIoBar (Index,1);
+    MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
+    MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
+      MmioAnd32 (PciCfgBase + PCI_COMMAND_OFFSET, (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) );
+      if (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0)) {
+        continue;
+      }
+      MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, 0);
+      MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
new file mode 100644
index 0000000000..5563d82076
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
@@ -0,0 +1,156 @@
+/** @file
+  Initializes Serial IO Controllers.
+
+  Copyright (c) 2019 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/S3BootScriptLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+
+#include "PchInit.h"
+#include <Library/PchSerialIoLib.h>
+#include <Library/DevicePathLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsSerialIo.h>
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH          RootPort;
+  ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
+  CHAR8                         HidString[8];
+  CHAR8                         UidString;
+  CHAR8                         CidString;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} SERIALIO_DEVICE_PATH;
+
+#define gPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof(ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
+#define gAcpiDev {{ACPI_DEVICE_PATH,ACPI_EXTENDED_DP,{(UINT8)(sizeof(ACPI_EXTENDED_HID_DEVICE_PATH)+SERIALIO_TOTAL_ID_LENGTH),0}},0,0,0}
+#define gEndEntire {END_DEVICE_PATH_TYPE,END_ENTIRE_DEVICE_PATH_SUBTYPE,{END_DEVICE_PATH_LENGTH,0}}
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_DEVICE_PATH gSerialIoPath = {
+  gPciRootBridge,
+  gAcpiDev,
+  "\0\0\0\0\0\0\0",
+  '\0',
+  '\0',
+  gEndEntire
+};
+
+/**
+Mark memory used by SerialIo devices in ACPI mode as allocated
+
+@retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+AllocateSerialIoMemory (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER i;
+  UINT8                    BarNumber;
+  UINTN                    Bar;
+  EFI_STATUS               Status;
+
+  for (i=0; i<PchSerialIoIndexMax; i++) {
+    if (mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoHidden ||
+        mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoAcpi) {
+      for (BarNumber = 0; BarNumber<=1; BarNumber++) {
+        Bar = FindSerialIoBar (i,BarNumber);
+        Status = gDS->AddMemorySpace (
+                        EfiGcdMemoryTypeReserved,
+                        Bar,
+                        V_SERIAL_IO_CFG_BAR_SIZE,
+                        0
+                        );
+        ASSERT_EFI_ERROR (Status);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        Status = gDS->AllocateMemorySpace (
+                        EfiGcdAllocateAddress,
+                        EfiGcdMemoryTypeReserved,
+                        N_SERIAL_IO_CFG_BAR_ALIGNMENT,
+                        V_SERIAL_IO_CFG_BAR_SIZE,
+                        &Bar,
+                        mImageHandle,
+                        NULL
+                        );
+        ASSERT_EFI_ERROR (Status);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+VOID
+CreateSerialIoHandles (
+  VOID
+  )
+{
+  EFI_HANDLE NewHandle;
+  EFI_DEVICE_PATH_PROTOCOL *NewPath;
+  UINT32 Controller;
+
+  for (Controller = 0; Controller < PchSerialIoIndexMax; Controller++) {
+    if (mPchConfigHob->SerialIo.DevMode[Controller] == PchSerialIoAcpi) {
+      NewHandle = NULL;
+      CopyMem (gSerialIoPath.HidString, GetSerialIoAcpiHid (Controller), SERIALIO_HID_LENGTH);
+      NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&gSerialIoPath);
+      gBS->InstallMultipleProtocolInterfaces (
+             &NewHandle,
+             &gEfiDevicePathProtocolGuid,
+             NewPath,
+             NULL );
+    }
+  }
+}
+
+/**
+  Puts all SerialIo controllers (except UARTs in debug mode) in D3.
+  Clears MemoryEnable for all PCI-mode controllers on S3 resume
+**/
+VOID
+ConfigureSerialIoAtS3Resume (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Index;
+  UINTN                    PciCfgBase;
+  UINT32                   Data32;
+
+  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
+      if (IsSerialIoFunctionZero (Index)) {
+        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
+          PciCfgBase = FindSerialIoBar (Index,1);
+          Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+          Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
+          S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
+        }
+      }
+      continue;
+    }
+    if ((Index >= PchSerialIoIndexUart0) &&
+        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
+        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
+      continue;
+    }
+    PciCfgBase = FindSerialIoBar (Index,1);
+    Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+    Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
+    S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
+      Data32 = MmioRead32 (PciCfgBase + PCI_COMMAND_OFFSET);
+      Data32 &= (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
+      S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + PCI_COMMAND_OFFSET, 1, &Data32);
+    }
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
new file mode 100644
index 0000000000..7fe1567c9f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
@@ -0,0 +1,156 @@
+/** @file
+  PCH BIOS Write Protect Driver.
+
+  Copyright (c) 2019 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/PchRegsSpi.h>
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_TCO_SMI_DISPATCH_PROTOCOL     *mPchTcoSmiDispatchProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64                            mSpiRegBase;
+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
+  )
+{
+  //
+  // Disable BIOSWE bit to protect BIOS
+  //
+  PciSegmentAnd8 ((UINTN) (mSpiRegBase + R_SPI_CFG_BC), (UINT8) ~B_SPI_CFG_BC_WPD);
+}
+
+/**
+  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;
+  }
+
+  mSpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_SPI,
+                  PCI_FUNCTION_NUMBER_PCH_SPI,
+                  0
+                  );
+
+  mLpcRegBase = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_LPC,
+                   PCI_FUNCTION_NUMBER_PCH_LPC,
+                   0
+                   );
+
+  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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
new file mode 100644
index 0000000000..e9f4c91ed4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
@@ -0,0 +1,179 @@
+/** @file
+  PCH Init Smm module for PCH specific SMI handlers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/RegsUsb.h>
+#include <Register/PchRegsSmbus.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;
+
+//
+// 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;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA                        *mSiConfigHobData;
+
+//
+// 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 = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                   0
+                   );
+
+  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);
+}
+
+/**
+  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);
+
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  ASSERT (HobPtr.Guid != NULL);
+  mSiConfigHobData = (SI_CONFIG_HOB_DATA *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  mAcpiBaseAddr = PmcGetAcpiBase ();
+
+  AllocateReservedMmio ();
+
+  Status = InitializePchPcieSmm (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InstallPchBiosWriteProtect (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InstallPchSpiAsyncSmiHandler ();
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
new file mode 100644
index 0000000000..4a2d1f9cea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
@@ -0,0 +1,298 @@
+/** @file
+  PCH LAN Sx handler implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/TimerLib.h>
+#include "PchInitSmm.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Library/GbeMdiLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLan.h>
+
+/**
+  Checks if Lan is Enabled or Disabled
+
+  @retval  BOOLEAN    TRUE if device is enabled, FALSE otherwise.
+**/
+BOOLEAN
+IsGbeEnabled (
+  VOID
+  )
+{
+  UINT64  GbePciBase;
+
+  GbePciBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_LAN,
+                 PCI_FUNCTION_NUMBER_PCH_LAN,
+                 0
+                 );
+
+  if (PciSegmentRead32 (GbePciBase) != 0xFFFFFFFF) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+/**
+  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_LAN_MEM_CSR_RAL);
+  RAH0 = MmioRead32 (GbeBar + R_LAN_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_LAN_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_LAN_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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_LAN,
+                 PCI_FUNCTION_NUMBER_PCH_LAN,
+                 0
+                 );
+
+  if (PciSegmentRead16 (LanRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+
+  //
+  // Check if GbE device is in D0
+  //
+  if ((PciSegmentRead16 (LanRegBase + R_LAN_CFG_PMCS) & B_LAN_CFG_PMCS_PS) != V_LAN_CFG_PMCS_PS0) {
+    return;
+  }
+
+  ASSERT (mResvMmioSize >= (1 << N_LAN_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_LAN_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_LAN_MEM_CSR_WUC) & B_LAN_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_LAN_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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
new file mode 100644
index 0000000000..eac2e1c3ec
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
@@ -0,0 +1,436 @@
+/** @file
+  PCH Pcie SMM Driver Entry
+
+  Copyright (c) 2019 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/PchRegsPcie.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                     mPciePmTrapExecuted = 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
+**/
+STATIC
+VOID
+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;
+  }
+  //
+  // 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;
+      }
+    }
+    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
+      );
+    RootportDownstreamPmConfiguration (
+      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      RpDevice,
+      RpFunction,
+      mTempRootPortBusNumMin,
+      mTempRootPortBusNumMax,
+      &mPcieRootPortConfig[PortIndex],
+      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);
+    }
+  }
+}
+
+/**
+  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;
+  UINTN                                     RpDevice;
+  UINTN                                     RpFunction;
+
+  MaxPciePortNum                   = GetPchMaxPciePortNum ();
+
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+    RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+
+    if (PciSegmentRead16 (RpBase) != 0xFFFF) {
+      RootportDownstreamPmConfiguration (
+        DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+        DEFAULT_PCI_BUS_NUMBER_PCH,
+        (UINT8)RpDevice,
+        (UINT8)RpFunction,
+        mTempRootPortBusNumMin,
+        mTempRootPortBusNumMax,
+        &mPcieRootPortConfig[PortIndex],
+        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 == PciePmTrap) {
+    if (mPciePmTrapExecuted == FALSE) {
+      PchPciePmIoTrapSmiCallback ();
+      mPciePmTrapExecuted = 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
+  )
+{
+  mPciePmTrapExecuted = 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;
+  UINTN                                 RpDevice;
+  UINTN                                 RpFunction;
+  EFI_HANDLE                            PcieHandle;
+  PCH_PCIE_SMI_DISPATCH_PROTOCOL        *PchPcieSmiDispatchProtocol;
+  EFI_HOB_GUID_TYPE*                    Hob;
+  UINT32                                DevTableSize;
+  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;
+
+  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)
+    );
+
+  mDevAspmOverride                  = NULL;
+  mNumOfDevAspmOverride             = 0;
+
+  Hob = GetFirstGuidHob (&gPchDeviceTableHobGuid);
+  if (Hob != NULL) {
+    DevTableSize = GET_GUID_HOB_DATA_SIZE (Hob);
+    ASSERT ((DevTableSize % sizeof (PCH_PCIE_DEVICE_OVERRIDE)) == 0);
+    mNumOfDevAspmOverride = DevTableSize / sizeof (PCH_PCIE_DEVICE_OVERRIDE);
+    DEBUG ((DEBUG_INFO, "Found PcieDeviceTable HOB (%d entries)\n", mNumOfDevAspmOverride));
+    Status = gSmst->SmmAllocatePool (
+                      EfiRuntimeServicesData,
+                      DevTableSize,
+                      (VOID **) &mDevAspmOverride
+                      );
+    CopyMem (mDevAspmOverride, GET_GUID_HOB_DATA (Hob), DevTableSize);
+  }
+
+  //
+  // Throught all PCIE root port function and register the SMI Handler for enabled ports.
+  //
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+    RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (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_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;
+      S3BootScriptSaveMemReadWrite (
+        S3BootScriptWidthUint32,
+        PcdGet64 (PcdPciExpressBaseAddress) + 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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
new file mode 100644
index 0000000000..3c843616e4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
@@ -0,0 +1,69 @@
+/** @file
+  PCH SPI Async SMI handler.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..d843de3ad8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,399 @@
+/** @file
+  This is the driver that publishes the SMM Control Protocol.
+
+  Copyright (c) 2019 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/PchRegsSpi.h>
+#include <Register/PchRegsPmc.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_EVENT,
+     "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_EVENT,
+     "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_EVENT,
+     "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_EVENT,
+     "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_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)
+      );
+    //
+    // Disable WADT_EN by default can avoid the WADT SMI during POST time when the WADT_STS is set as a wake source.
+    // BIOS disable WADT_EN and keep WADT_STS into OS so OS can be aware of the wake source.
+    //
+    IoAnd32 ((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/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000000..458d137e4f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
@@ -0,0 +1,310 @@
+/** @file
+  PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
+#include <Private/Library/SmmPchPrivateLib.h>
+#include <PchReservedResources.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.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 = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  // 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 = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  ///
+  /// 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;
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (25 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
                   ` (10 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Adds the PchSmiDispatcher module. Dispatches PCH SMIs to appropriate
SMI handlers registered in various SMM modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf  |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h              |  228 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h              | 1031 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h          |  342 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h       |  157 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h      |  105 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c              | 1264 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c      | 2452 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c          |  911 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c          | 1595 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c           |  254 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c       |  358 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c |  675 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c   |   83 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c            |  385 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c            |  229 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c           |  231 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c      |  764 ++++++
 18 files changed, 11173 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
new file mode 100644
index 0000000000..38d5dbeebf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
@@ -0,0 +1,109 @@
+## @file
+# Component description file for the Pch SMI Dispatch Handlers module
+#
+# Copyright (c) 2019 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
+PchEspiLib
+S3BootScriptLib
+ConfigBlockLib
+PmcPrivateLib
+PmcLib
+SmiHandlerProfileLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+# 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
+
+
+[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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
new file mode 100644
index 0000000000..9d6a459ff3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
@@ -0,0 +1,228 @@
+/** @file
+  Defines and prototypes for the IoTrap SMM driver
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
new file mode 100644
index 0000000000..1906e32b5a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
@@ -0,0 +1,1031 @@
+/** @file
+  Prototypes and defines for the PCH SMM Dispatcher.
+
+  Copyright (c) 2019 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/PchEspiLib.h>
+#include <Private/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 \
+  }
+
+///
+/// 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_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 union {
+  UINTN ElapsedTime;
+} 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 CONST 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
new file mode 100644
index 0000000000..193eed6bac
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
@@ -0,0 +1,342 @@
+/** @file
+  eSPI SMI Dispatch header
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
new file mode 100644
index 0000000000..24e0975025
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
@@ -0,0 +1,157 @@
+/** @file
+  Helper functions for PCH SMM
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
new file mode 100644
index 0000000000..ba7ad42c9d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
@@ -0,0 +1,105 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2019 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.
+**/
+VOID
+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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
new file mode 100644
index 0000000000..ddab2fc378
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
@@ -0,0 +1,1264 @@
+/** @file
+  Main implementation source file for the Io Trap SMM driver
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Private/Protocol/PchNvsArea.h>
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsDmi.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), NULL, 0);
+  }
+  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 (&gEfiSmmIoTrapDispatch2ProtocolGuid, RecordToDelete->IoTrapCallback, NULL, 0);
+  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), NULL, 0);
+  }
+  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, NULL, 0);
+  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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
new file mode 100644
index 0000000000..2b70008fee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
@@ -0,0 +1,2452 @@
+/** @file
+  This function handle the register/unregister of PCH specific SMI events.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Library/SmiHandlerProfileLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPcie.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsItss.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,
+  {
+    {
+      {
+        PCR_ADDR_TYPE,
+        {PCH_PCR_ADDRESS (PID_ITSS, R_ITSS_PCR_NMI)}
+      },
+      4,
+      N_ITSS_PCR_NMI_NMI2SMI_EN
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        PCR_ADDR_TYPE,
+        {PCH_PCR_ADDRESS (PID_ITSS, R_ITSS_PCR_NMI)}
+      },
+      4,
+      N_ITSS_PCR_NMI_NMI2SMI_STS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  Enable the Nmi2Smi source
+**/
+VOID
+PchNmi2SmiEnableSource (
+  VOID
+  )
+{
+  //
+  // The PCR[ITSS].NMI register can only be accessed with BOOT_SAI and SMM_SAI.
+  // Since in CFL there is no SMM_SAI it needs PMC assistance to access this register.
+  //
+  UINT32  ItssNmi;
+  ItssNmi = PmcGetNmiControl ();
+  PmcSetNmiControl (ItssNmi | B_ITSS_PCR_NMI_NMI2SMI_EN);
+}
+
+/**
+  Clear the NMI status bit after the SMI handling is done
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+**/
+VOID
+EFIAPI
+PchNmi2SmiClearSource (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  )
+{
+  // No need to clear NMI2SMI_STS since it's cleared when NMI source is cleared.
+  // Clear TCO status only.
+  PchSmmClearSource (&mDescSrcTcoSts);
+}
+
+/**
+  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);
+    //
+    // Since the NMI2SMI status and enable bit are at the same register,
+    // it needs separate function to handle the source enable and clear.
+    //
+    Record->ClearSource = PchNmi2SmiClearSource;
+    PchNmi2SmiEnableSource ();
+    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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  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);
+}
+
+/**
+  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.
+    //
+    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.
+    //
+    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 == PCI_DEVICE_NUMBER_PCH_SPI) &&
+      (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc == PCI_FUNCTION_NUMBER_PCH_SPI) &&
+      (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 == PCI_DEVICE_NUMBER_PCH_LPC) &&
+             (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc == PCI_FUNCTION_NUMBER_PCH_LPC) &&
+             (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                   Indicate the RP index (0-based)
+  @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;
+
+  //
+  // 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;
+  }
+
+  GetPchPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+  //
+  // Patch the RP device number and function number of srcdesc.
+  //
+  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)) {
+    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  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                   Indicate the RP index (0-based)
+  @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;
+
+  //
+  // 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;
+  }
+
+  GetPchPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+  //
+  // Patch the RP device number and function number of srcdesc.
+  //
+  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)) {
+    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  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                   Indicate the RP index (0-based)
+  @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;
+
+  //
+  // 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;
+  }
+
+  GetPchPcieRpDevFun (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)) {
+    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid, (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
+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, NULL, 0);
+  }
+  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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  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;
+  SpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  PciSegmentAndThenOr32 (
+    SpiRegBase + R_SPI_CFG_BC,
+    (UINT32) ~B_SPI_CFG_BC_SYNC_SS,
+    B_SPI_CFG_BC_ASE_BWP
+    );
+
+  //
+  // 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 == PCI_DEVICE_NUMBER_PCH_SPI) &&
+      (Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Fnc == PCI_FUNCTION_NUMBER_PCH_SPI) &&
+      (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 = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SPI,
+                   PCI_FUNCTION_NUMBER_PCH_SPI,
+                   0
+                   );
+    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;
+      GetPchPcieRpNumber (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]);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gEfiSmmIoTrapDispatch2ProtocolGuid, (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] 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
+  )
+{
+  DATABASE_RECORD                   *RecordToDelete;
+  EFI_STATUS                        Status;
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (&gEfiSmmIoTrapDispatch2ProtocolGuid, RecordToDelete->Callback, NULL, 0);
+  }
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
new file mode 100644
index 0000000000..9c36103396
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
@@ -0,0 +1,911 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2019 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/PchRegsGpio.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsLpc.h>
+
+//
+// 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 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;
+
+  //
+  // 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, NULL, 0);
+  }
+  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.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_EN_127_96) & B_ACPI_IO_GPE0_EN_127_96_WADT) &&
+        (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 {
+                  //
+                  // 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
new file mode 100644
index 0000000000..9eb61947a3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
@@ -0,0 +1,1595 @@
+/** @file
+  eSPI SMI implementation
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmEspi.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Library/PchEspiLib.h>
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsLpc.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 = PCI_SEGMENT_LIB_ADDRESS (
+                         DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                         DEFAULT_PCI_BUS_NUMBER_PCH,
+                         PCI_DEVICE_NUMBER_PCH_LPC,
+                         PCI_FUNCTION_NUMBER_PCH_LPC,
+                         0
+                         );
+      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.
+  //
+  PmcLockEspiSmi ();
+  //
+  // 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;
+    default:
+      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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
new file mode 100644
index 0000000000..43277f0938
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
@@ -0,0 +1,254 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Gpi dispatch protocol.
+
+  Copyright (c) 2019 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/PchRegsGpio.h>
+#include <Register/PchRegsPmc.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 CONST 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), (void *)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, NULL, 0);
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
new file mode 100644
index 0000000000..f6413921eb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
@@ -0,0 +1,358 @@
+/** @file
+  Helper functions for PCH SMM dispatcher.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsItss.h>
+#include <Private/Library/PmcPrivateLib.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;
+    }
+  }
+
+  //
+  // Special handling for NMI bit since it requires PMC IPC command.
+  // Do w/a here instead of in ReadBitDesc to reduce the PMC IPC command usage.
+  //
+  // The PCR[ITSS].NMI register can only be accessed with BOOT_SAI and SMM_SAI.
+  // Since in CFL there is no SMM_SAI it needs PMC assistance to access this register.
+  //
+  if ((Src->En[0].Reg.Data.Pcr.Fields.Pid == PID_ITSS) &&
+      (Src->En[0].Reg.Data.Pcr.Fields.Offset == R_ITSS_PCR_NMI))
+  {
+    UINT32  ItssNmi;
+    ItssNmi = PmcGetNmiControl ();
+    if ((ItssNmi & (BIT0 << Src->En[0].Bit)) &&
+        (ItssNmi & (BIT0 << Src->Sts[0].Bit)))
+    {
+      return TRUE;
+    } else {
+      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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
new file mode 100644
index 0000000000..9a5ae464e0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
@@ -0,0 +1,675 @@
+/** @file
+  File to contain all the hardware specific stuff for the Periodical Timer dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Protocol/PchSmmPeriodicTimerControl.h>
+#include <Private/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.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) {
+      ///
+      /// 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;
+
+  if (SmiTickInterval == NULL) {
+    ASSERT(FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  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;
+  TIMER_INTERVAL                        *TimerInterval;
+
+  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  TimerInterval = NULL;
+  TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+  if (TimerInterval == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PchSmmDisableSource (&mTimerSourceDesc[TimerInterval->AssociatedTimer]);
+  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;
+  TIMER_INTERVAL                        *TimerInterval;
+
+  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  TimerInterval = NULL;
+  TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+  if (TimerInterval == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PchSmmEnableSource (&mTimerSourceDesc[TimerInterval->AssociatedTimer]);
+  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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
new file mode 100644
index 0000000000..17898b899b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
@@ -0,0 +1,83 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Power Button dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PchSmmHelpers.h>
+#include <Private/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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
new file mode 100644
index 0000000000..35ecfe5238
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
@@ -0,0 +1,385 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Sw dispatch protocol.
+
+  Copyright (c) 2019 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/PchRegsPmc.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++) {
+      Status = SmiInputValueDuplicateCheck (Index);
+      if (!EFI_ERROR (Status)) {
+        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;
+  }
+
+  Status = SmiInputValueDuplicateCheck (DispatchContext->SwSmiInputValue);
+  if (EFI_ERROR (Status)) {
+    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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
new file mode 100644
index 0000000000..52bb906315
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
@@ -0,0 +1,229 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsPcie.h>
+
+#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 = PchPcieBase (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 ();
+
+  ///
+  /// Flush cache into memory before we go to sleep. It is necessary for S3 sleep
+  /// because we may update memory in SMM Sx sleep handlers -- the updates are in cache now
+  ///
+  AsmWbinvd ();
+
+  ///
+  /// 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);
+
+    ///
+    /// Flush cache into memory before we go 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
new file mode 100644
index 0000000000..061dbe4300
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
@@ -0,0 +1,231 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm USB dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/RegsUsb.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
new file mode 100644
index 0000000000..4ac00b831f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
@@ -0,0 +1,764 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPmc.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.
+**/
+VOID
+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 &= (UINT32)~(B_ACPI_IO_GPE0_STS_127_96_WADT);
+
+    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);
+}
+
+/**
+  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;
+  }
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (26 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
                   ` (9 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

* SaAcpiTables - SA (DMAR) ACPI tables.
* SaSsdt - SA SSDT ACPI tables.
* SaInitDxe - Generic DXE SA initialization.
* SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf                    |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                   |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf                       |  116 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf                    |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h                         |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h |  230 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h   | 1567 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h     |  203 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h     | 1167 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h       |  237 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h              |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h                      |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h                   |  193 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h                    |   91 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h                       |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h                            |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h                         |  139 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h            |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h                               |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h                |  162 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c                      |  157 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c                   |  570 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c                    |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c                       |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c                            |  496 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c                            |  179 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c                         |  122 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c                               |  717 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c                |  356 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc                      |  250 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl                         |  794 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl                     | 1666 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl               |  472 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl                  |  369 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl               |  129 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl                 |  296 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl               |  262 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl                      |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                       |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl                    |  147 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                   |   22 +
 41 files changed, 11970 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
new file mode 100644
index 0000000000..56ddc2957f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
@@ -0,0 +1,50 @@
+## @file
+#  Component description file for the ACPI tables
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SaAcpiTables
+FILE_GUID            = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  Dmar/Dmar.aslc
+  Dmar/Dmar.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
new file mode 100644
index 0000000000..3588565aac
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
@@ -0,0 +1,49 @@
+## @file
+#  Component description file for the ACPI tables
+#
+# Copyright (c) 2019 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
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
new file mode 100644
index 0000000000..9937fc60e5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
@@ -0,0 +1,116 @@
+## @file
+# Component description file for SystemAgent Initialization driver
+#
+# Copyright (c) 2019 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
+TimerLib
+PciCf8Lib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+IoLib
+S3BootScriptLib
+PmcLib
+PchCycleDecodingLib
+PchInfoLib
+GpioLib
+ConfigBlockLib
+SaPlatformLib
+PchPcieRpLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
+
+[Sources]
+SaInitDxe.h
+SaInitDxe.c
+SaInit.h
+SaInit.c
+VTd.c
+VTd.h
+IgdOpRegionInit.h
+IgdOpRegionInit.c
+GraphicsInit.h
+GraphicsInit.c
+PciExpressInit.h
+PciExpressInit.c
+PcieComplex.c
+PcieComplex.h
+SaAcpi.c
+
+[Protocols]
+gEfiAcpiTableProtocolGuid              ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## PRODUCES
+gSaPolicyProtocolGuid                  ## CONSUMES
+gEfiCpuArchProtocolGuid                ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
+gEfiPciIoProtocolGuid                  ## CONSUMES
+gIgdOpRegionProtocolGuid               ## PRODUCES
+gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
+gEfiLegacyBiosProtocolGuid             ## CONSUMES
+gGopComponentName2ProtocolGuid         ## CONSUMES
+gSaIotrapSmiProtocolGuid               ## CONSUMES
+
+[Guids]
+gSaConfigHobGuid
+gSgAcpiTablePchStorageGuid
+gSaAcpiTableStorageGuid
+gSgAcpiTableStorageGuid
+gSaSsdtAcpiTableStorageGuid
+gPegSsdtAcpiTableStorageGuid
+gEfiEndOfDxeEventGroupGuid
+gSiConfigHobGuid        ## CONSUMES
+gMiscDxeConfigGuid
+gGraphicsDxeConfigGuid
+gMemoryDxeConfigGuid
+gPcieDxeConfigGuid
+gVbiosDxeConfigGuid
+gPchInfoHobGuid
+
+[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/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
new file mode 100644
index 0000000000..9356781c9e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the SmmAccess module
+#
+# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmAccess
+FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SmmAccessDriverEntryPoint
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+BaseLib
+BaseMemoryLib
+DebugLib
+HobLib
+PciLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmAccessDriver.h
+SmmAccessDriver.c
+
+
+[Protocols]
+gEfiSmmAccess2ProtocolGuid       ## PRODUCES
+
+
+[Guids]
+gEfiSmmPeiSmramMemoryReserveGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
new file mode 100644
index 0000000000..4339256bba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
@@ -0,0 +1,25 @@
+/** @file
+  This file describes the contents of the ACPI DMA address Remapping
+  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_DMAR_H_
+#define _SA_DMAR_H_
+
+///
+/// Include standard ACPI table definitions
+///
+#include <IndustryStandard/Acpi30.h>
+#include <DmaRemappingTable.h>
+
+#pragma pack(1)
+
+#define EFI_ACPI_DMAR_OEM_TABLE_ID    0x20202020324B4445  ///< "EDK2    "
+#define EFI_ACPI_DMAR_OEM_CREATOR_ID  0x4C544E49  ///< "INTL"
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
new file mode 100644
index 0000000000..54cb69066d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
@@ -0,0 +1,230 @@
+/** @file
+  This file contains the definitions common to the MRC API and other APIs.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcCommonTypes_h_
+#define _MrcCommonTypes_h_
+
+#define INT32_MIN                       (0x80000000)
+#ifndef INT32_MAX  //INT32_MAX->Already defined
+#define INT32_MAX                       (0x7FFFFFFF)
+#endif
+#define INT16_MIN                       (0x8000)
+#define INT16_MAX                       (0x7FFF)
+
+///
+/// System boot mode.
+///
+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.
+} MrcBootMode;
+
+///
+/// DIMM memory package
+/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
+/// Note that DDR4 have different encoding for some module types
+///
+typedef enum {
+  RDimmMemoryPackage          = 1,
+  UDimmMemoryPackage          = 2,
+  SoDimmMemoryPackage         = 3,
+  MicroDimmMemoryPackageDdr3  = 4,
+  LrDimmMemoryPackageDdr4     = 4,
+  MiniRDimmMemoryPackage      = 5,
+  MiniUDimmMemoryPackage      = 6,
+  MiniCDimmMemoryPackage      = 7,
+  LpDimmMemoryPackage         = 7,
+  SoUDimmEccMemoryPackageDdr3 = 8,
+  SoRDimmEccMemoryPackageDdr4 = 8,
+  SoRDimmEccMemoryPackageDdr3 = 9,
+  SoUDimmEccMemoryPackageDdr4 = 9,
+  SoCDimmEccMemoryPackage     = 10,
+  LrDimmMemoryPackage         = 11,
+  SoDimm16bMemoryPackage      = 12,
+  SoDimm32bMemoryPackage      = 13,
+  NonDimmMemoryPackage        = 14,
+  MemoryPackageMax,                       ///< MEMORY_PACKAGE enumeration maximum value.
+  MemoryPackageDelim = INT32_MAX          ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MEMORY_PACKAGE;
+
+///
+/// Memory training I/O levels.
+///
+typedef enum {
+  DdrLevel   = 0,                         ///< Refers to frontside of DIMM
+  LrbufLevel = 1,                         ///< Refers to data level at backside of LRDIMM or AEP buffer
+  RegALevel  = 2,                         ///< Refers to cmd level at backside of register - side A
+  RegBLevel  = 3,                         ///< Refers to cmd level at backside of register - side B
+  GsmLtMax,                               ///< GSM_LT enumeration maximum value.
+  GsmLtDelim = INT32_MAX                  ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_LT;
+
+///
+/// Memory training margin group selectors.
+///
+typedef enum {
+  RecEnDelay       = 0,                   ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+  RxDqsDelay       = 1,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+  RxDqDelay        = 2,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQ byte/nibble/bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+  RxDqsPDelay      = 3,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "even" chunks later in time relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxDqsNDelay      = 4,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "odd" chunks later in time relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxVref           = 5,                   ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+  RxEq             = 6,                   ///< RX CTLE setting indicating a set of possible resistances, capacitance, current steering, etc. values, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  RxDqBitDelay     = 7,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQ bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+  RxVoc            = 8,                   ///< Monotonic increment (Sense Amp setting), where the positive increment moves the byte/nibble/bitlane's effective switching point to a lower Vref value.
+  RxOdt            = 9,                   ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  RxOdtUp          = 10,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  RxOdtDn          = 11,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  DramDrvStr       = 12,                  ///< Drive strength setting resistance setting within a set of possible resistances (or currents), which may be a different set of values per product. Indexed by integer values.
+  McOdtDelay       = 13,                  ///<
+  McOdtDuration    = 14,                  ///<
+  SenseAmpDelay    = 15,                  ///< This may be used to indicate CmdToDiffAmpEn for SoC's.
+  SenseAmpDuration = 16,                  ///<
+  RoundTripDelay   = 17,                  ///< This may be used to indicate CmdToRdDataValid for SoC's.
+  RxDqsBitDelay    = 18,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS within the bitlane later in time relative to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of the eye).
+  RxDqDqsDelay     = 19,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS per strobe later in time relative to the RX DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye. The difference between this parameter and RxDqsDelay is that both the DQ and DQS timings may be moved in order to increase the total range of DQDQS timings.
+  WrLvlDelay       = 20,                  ///< Linear delay (PI ticks), where the positive increment moves both the TX DQS and TX DQ signals later in time relative to all other bus signals.
+  TxDqsDelay       = 21,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+  TxDqDelay        = 22,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+  TxVref           = 23,                  ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane TX Vref to a higher voltage. (Assuming this will abstract away from the range specifics for DDR4, for example.)
+  TxEq             = 24,                  ///< TX EQ setting indicating a set of possible equalization levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  TxDqBitDelay     = 25,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ bitlane later in time relative to all other bus signals.
+  TxRon            = 26,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxRonUp          = 27,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxRonDn          = 28,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxSlewRate       = 29,                  ///< Monotonic increment, where the positive increment moves the byte/nibble/bitlane's effective slew rate to a higher slope.
+  TxImode          = 30,                  ///< TX I-Mode Boost setting indicating a set of possible current boost levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  WrOdt            = 31,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  NomOdt           = 32,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  ParkOdt          = 33,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxTco            = 34,                  ///<
+  RxCtleR          = 36,                  ///<
+  RxCtleC          = 37,                  ///<
+  RxDqsPBitDelay   = 38,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "even" chunks later in time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxDqsNBitDelay   = 39,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "odd" chunks later in time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  CmdAll           = 40,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_ALL category later in time relative to all other signals on the bus.
+  CmdGrp0          = 41,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP0 category later in time relative to all other signals on the bus.
+  CmdGrp1          = 42,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP1 category later in time relative to all other signals on the bus.
+  CmdGrp2          = 43,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP2 category later in time relative to all other signals on the bus.
+  CtlAll           = 44,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_ALL category later in time relative to all other signals on the bus.
+  CtlGrp0          = 45,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP0 category later in time relative to all other signals on the bus.
+  CtlGrp1          = 46,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP1 category later in time relative to all other signals on the bus.
+  CtlGrp2          = 47,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP2 category later in time relative to all other signals on the bus.
+  CtlGrp3          = 48,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP3 category later in time relative to all other signals on the bus.
+  CtlGrp4          = 49,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP4 category later in time relative to all other signals on the bus.
+  CtlGrp5          = 50,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP5 category later in time relative to all other signals on the bus.
+  CmdCtlAll        = 51,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_CTL_ALL category later in time relative to all other signals on the bus.
+  CkAll            = 52,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CK_ALL category later in time relative to all other signals on the bus.
+  CmdVref          = 53,                  ///< Linear increment (Vref ticks), where the positive increment moves the CMD Vref to a higher voltage.
+  AlertVref        = 54,                  ///< Linear increment (Vref ticks), where the positive increment moves the ALERT Vref to a higher voltage.
+  CmdRon           = 55,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+
+  EridDelay        = 60,                  ///< Linear delay (PI ticks), where the positive increment moves the ERID signals later in time relative to the internal sampling clock (i.e.closing the gap between ERID and internal sampling clock in the setup side of the eye). This group is applicable for DDRT DIMMs.
+  EridVref         = 61,                  ///< Linear increment (Vref ticks), where the positive increment moves the ERID Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  ErrorVref        = 62,                  ///< Linear increment (Vref ticks), where the positive increment moves the ERROR Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  ReqVref          = 63,                  ///< Linear increment (Vref ticks), where the positive increment moves the REQ Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  RecEnOffset      = 64,                  ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+  RxDqsOffset      = 65,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+  RxVrefOffset     = 66,                  ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+  TxDqsOffset      = 67,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+  TxDqOffset       = 68,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+  GsmGtMax,                               ///< SSA_GSM_GT enumeration maximum value.
+  GsmGtDelim = INT32_MAX                  ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_GT;
+
+typedef enum {
+  SigRasN   = 0,
+  SigCasN   = 1,
+  SigWeN    = 2,
+  SigBa0    = 3,
+  SigBa1    = 4,
+  SigBa2    = 5,
+  SigA0     = 6,
+  SigA1     = 7,
+  SigA2     = 8,
+  SigA3     = 9,
+  SigA4     = 10,
+  SigA5     = 11,
+  SigA6     = 12,
+  SigA7     = 13,
+  SigA8     = 14,
+  SigA9     = 15,
+  SigA10    = 16,
+  SigA11    = 17,
+  SigA12    = 18,
+  SigA13    = 19,
+  SigA14    = 20,
+  SigA15    = 21,
+  SigA16    = 22,
+  SigA17    = 23,
+  SigCs0N   = 24,
+  SigCs1N   = 25,
+  SigCs2N   = 26,
+  SigCs3N   = 27,
+  SigCs4N   = 28,
+  SigCs5N   = 29,
+  SigCs6N   = 30,
+  SigCs7N   = 31,
+  SigCs8N   = 32,
+  SigCs9N   = 33,
+  SigCke0   = 34,
+  SigCke1   = 35,
+  SigCke2   = 36,
+  SigCke3   = 37,
+  SigCke4   = 38,
+  SigCke5   = 39,
+  SigOdt0   = 40,     //could also be used for CA-ODT for LP4
+  SigOdt1   = 41,     //could also be used for CA-ODT for LP4
+  SigOdt2   = 42,
+  SigOdt3   = 43,
+  SigOdt4   = 44,
+  SigOdt5   = 45,
+  SigPar    = 46,
+  SigAlertN = 47,
+  SigBg0    = 48,
+  SigBg1    = 49,
+  SigActN   = 50,
+  SigCid0   = 51,
+  SigCid1   = 52,
+  SigCid2   = 53,
+  SigCk0    = 54,
+  SigCk1    = 55,
+  SigCk2    = 56,
+  SigCk3    = 57,
+  SigCk4    = 58,
+  SigCk5    = 59,
+  SigGnt0   = 60,
+  SigGnt1   = 61,
+  SigErid00 = 62,
+  SigErid01 = 63,
+  SigErid10 = 64,
+  SigErid11 = 65,
+  SigErr0   = 66,
+  SigErr1   = 67,
+  SigCa00   = 68,    // First instantiation of the CA bus for a given channel
+  SigCa01   = 69,
+  SigCa02   = 70,
+  SigCa03   = 71,
+  SigCa04   = 72,
+  SigCa05   = 73,
+  SigCa10   = 74,    // Second instantiation of the CA bus for a given channel
+  SigCa11   = 75,
+  SigCa12   = 76,
+  SigCa13   = 77,
+  SigCa14   = 78,
+  SigCa15   = 79,
+  GsmCsnMax,
+  GsmCsnDelim = INT32_MAX
+} GSM_CSN;
+
+
+#endif // _MrcCommonTypes_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
new file mode 100644
index 0000000000..635906cc2b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
@@ -0,0 +1,1567 @@
+/** @file
+  This file includes all the data structures that the MRC considers "global data".
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcInterface_h_
+#define _MrcInterface_h_
+
+#define MAX_CPU_SOCKETS          (1)       ///< The maximum number of CPUs per system.
+#define MAX_CONTROLLERS          (1)       ///< The maximum number of memory controllers per CPU socket.
+#define MAX_CHANNEL              (2)       ///< The maximum number of channels per memory controller.
+#define MAX_DIMMS_IN_CHANNEL     (2)       ///< The maximum number of DIMMs per channel.
+#define MAX_RANK_IN_DIMM         (2)       ///< The maximum number of ranks per DIMM.
+#define MAX_RANK_IN_CHANNEL      (MAX_DIMMS_IN_CHANNEL * MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
+#define MAX_SDRAM_IN_DIMM        (9)       ///< The maximum number of SDRAMs per DIMM when ECC is enabled.
+#define MAX_MR_IN_DIMM           (7)       ///< Maximum number of mode registers in a DIMM.
+#define MAX_DEVICES_IN_DDR4      (8)       ///< The maximum number of SDRAMs per DDR4 DIMM.
+#define MAX_BITS                 (8)       ///< BITS per byte.
+#define MAX_STROBE               (18)      ///< Number of strobe groups.
+#define MAX_DQ                   (72)      ///< Number of Dq bits used by the rank.
+#define CHAR_BITS                (8)       ///< Number of bits in a char.
+#define PSMI_SIZE_MB             (64)      ///< Define the max size of PSMI needed in MB
+#define BCLK_DEFAULT             (100 * 1000 * 1000) ///< BCLK default value, in Hertz.
+#define MAX_COMMAND_GROUPS       (2)
+#define MAX_EDGES                (2) ///< Maximum number of edges.
+#define SUPPORT_DDR3             SUPPORT   ///< SUPPORT means that DDR3 is supported by the MRC.
+#define ULT_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define TRAD_SUPPORT_LPDDR3      /*UN*/SUPPORT ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define BDW_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define JEDEC_SUPPORT_LPDDR      SUPPORT   ///< SUPPORT means that JEDEC SPD Spec for LPDDR3 is supported by the MRC.
+#define SUPPORT_DDR4             SUPPORT   ///< SUPPORT means that DDR4 is supported by the MRC.
+#define SUPPORT_LPDDR3           (ULT_SUPPORT_LPDDR3 || TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 || JEDEC_SUPPORT_LPDDR)
+#define MRC_ALL_DDR_SUPPORTED    ((SUPPORT_DDR4 == SUPPORT) && ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
+#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) || (SUPPORT_LPDDR3 == SUPPORT))
+#define SPD3_MANUF_START       117         ///< The starting point for the SPD manufacturing data.
+#define SPD3_MANUF_END         127         ///< The ending point for the SPD manufacturing data.
+#if (SUPPORT_DDR4 == SUPPORT)
+#define SPD4_MANUF_START       320         ///< The starting point for the SPD manufacturing data.
+#define SPD4_MANUF_END         328         ///< The ending point for the SPD manufacturing data.
+#endif
+#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
+#define SPDLP_MANUF_START      320         ///< The starting point for the SPD manufacturing data.
+#define SPDLP_MANUF_END        328         ///< The ending point for the SPD manufacturing data.
+#endif
+#include "MrcSpdData.h"
+#include "MrcRmtData.h"
+#include "MrcCommonTypes.h"
+#pragma pack (push, 1)
+
+
+///
+//////////////////////////////////////////////////////////////////////////////////////
+///                           OEM platform  routines and types                      //
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// define the oem check points the OEM can define more point and locate them in the code.
+///
+typedef enum {
+  OemFastBootPermitted,     ///<  before fast boot.
+  OemRestoreNonTraining,
+  OemPrintInputParameters,  ///<  before printing input parameters
+  OemSpdProcessingRun,      ///<  before spd processing code
+  OemSetOverridePreSpd,     ///<  before set overrides pre spd
+  OemSetOverride,           ///<  before set overrides
+  OemMcCapability,          ///<  before MC capability
+  OemMcInitRun,             ///<  before mc init code
+  OemMcMemoryMap,           ///<  before memory map
+  OemMcResetRun,            ///<  before jedec reset
+  OemPreTraining,           ///<  before the training.
+  OemMcTrainingRun,         ///<  before training code
+  OemEarlyCommandTraining,  ///<  before Early Command training
+  OemJedecInitLpddr3,       ///<  before Jedec Init Lpddr3
+  OemSenseAmpTraining,      ///<  before Sense Amp Training
+  OemReadMprTraining,       ///<  before Read MPR Training
+  OemReceiveEnable,         ///<  before Read Leveling
+  OemJedecWriteLeveling,    ///<  before Jedec Write Leveling
+  OemLpddrLatencySetB,      ///<  before LPDDR Latency Set B
+  OemWriteDqDqs,            ///<  before Write Timing Centering
+  OemWriteVoltage,          ///<  before Write Voltage Centering
+  OemEarlyWriteDqDqs2D,     ///<  before Early Write Timing Centering 2D
+  OemEarlyWrDsEq,           ///<  before Early Write Drive Strength / Equalization
+  OemEarlyReadDqDqs2D,      ///<  before Early Read Timing Centering 2D
+  OemEarlyReadMprDqDqs2D,   ///<  before Early MPR Read Timing Centering 2D
+  OemReadDqDqs,             ///<  before Read Timing Centering
+  OemDdr4Map,               ///<  before DDR4 PDA Mapping
+  OemDimmRonTraining,       ///<  before DIMM Ron Training
+  OemDimmODTTraining,       ///<  before DIMM ODT Training
+  OemWriteDriveStrengthEq,  ///<  before Write Drive Strength/Equalization 2D Training
+  OemWriteDriveUpDn,        ///<  before Write Drive Strength Up/Dn 2D Training
+  OemWriteSlewRate,         ///<  before Write Slew Rate Training
+  OemReadODTTraining,       ///<  before Read ODT algorithm.
+  OemReadEQTraining,        ///<  before Read Equalization Training
+  OemReadAmplifierPower,    ///<  before Read Amplifier Power
+  OemOptimizeComp,          ///<  before Comp Optimization Training
+  OemPowerSavingMeter,      ///<  before PowerSavingMeter step
+  OemWriteDqDqs2D,          ///<  before Write Timing Centering 2D
+  OemReadDqDqs2D,           ///<  before Read Timing Centering 2D
+  OemCmdVoltCenterPreLct,   ///<  before Command Voltage Centering that runs pre-LCT
+  OemCmdSlewRate,           ///<  before CMD Slew Rate
+  OemCmdVoltCentering,      ///<  before Command Voltage Centering
+  OemCmdDriveStrengthEq,    ///<  before Command Drive Strength Equalization
+  OemWriteVoltCentering2D,  ///<  before Write Voltage Centering 2D
+  OemReadVoltCentering2D,   ///<  before Read Voltage Centering 2D
+  OemLateCommandTraining,   ///<  before Late Command training
+  OemCmdNormalization,      ///<  before CMD Normalization
+  OemRoundTripLatency,      ///<  before Round Trip Latency Traiing
+  OemTurnAroundTimes,       ///<  before Turn Aorund Times.
+  OemRcvEnCentering1D,      ///<  before Receive Enable Centring
+  OemSaveMCValues,          ///<  before saving memory controller values
+  OemRmt,                   ///<  before RMT crosser tool.
+  OemMemTest,               ///<  before Memory testing
+  OemRestoreTraining,       ///<  before Restoring Training Values
+  OemJedecResetDdr4Fast,    ///<  before JEDEC reset for DDR4 in Fast flow
+  OemSelfRefreshExit,       ///<  before Self Refresh Exit
+  OemNormalMode,            ///<  before Normal Mode on non-cold boots.
+  OemThermalConfig,         ///<  set Thermal config values.
+  OemTxtAliasCheck,         ///<  before TxT Alias Check Call.
+  OemAliasCheck,            ///<  before alias checking on cold boots.
+  OemHwMemInit,
+
+  OemPostTraining,          ///<  after the training.
+  OemForceOltm,             ///<  before MrcForceOltm
+  OemMrcActivate,           ///<  before MrcActivate call.
+  OemMrcRhPrevention,       ///<  before MrcRhPrevention
+  OemSaGvSwitch,            ///<  before SA GV switch
+  OemEngPerfGain,           ///<  before Energy Performance Gain.
+  OemMrcDone,               ///<  call to MrcOemCheckPoint when MRC was done.
+  OemFrequencySet,          ///<  do operation before frequency set.
+  OemFrequencySetDone,      ///<  do operation after frequency set.
+  OemStartMemoryConfiguration,
+  OemBeforeNormalMode,      ///<  call to MrcOemCheckPoint before normal mode is enalbed
+  OemAfterNormalMode,       ///<  call to MrcOemCheckPoint after normal mode is enalbed
+  OemMrcFillBdat,
+  OemRetrainMarginCheck,
+  OemRmtPerBit,             ///< before Rank Margin Tool Per-Bit.
+  OemUpdateSaveMCValues,    ///< before Updating memory controller values.
+  ///
+  ///*********************************************************************************
+  ///
+  OemNumOfCommands          ///<  Should always be last in the list!
+} MrcOemStatusCommand;
+
+typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with 0 and increment by one each time MRC library is called.
+#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 << ((sizeof (MrcIteration) * 8) - 1)) - 1))
+
+#define MAX_RCOMP         (3)
+#define MAX_RCOMP_TARGETS (5)
+
+///
+/// Thermal Options
+///
+typedef struct {
+  UINT8  RaplLim2WindX;                                    ///< Offset 110  - Power Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8  RaplLim2WindY;                                    ///< Offset 111  - Power Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8  RaplLim1WindX;                                    ///< Offset 112  - Power Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
+  UINT8  RaplLim1WindY;                                    ///< Offset 113  - Power Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
+  UINT16 RaplLim2Pwr;                                      ///< Offset 114  - Power Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
+  UINT16 RaplLim1Pwr;                                      ///< Offset 116  - Power Limit 1: <b>0=Minimal</b>, 16383=Maximum
+  UINT8  WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 118  - Warm Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];  ///< Offset 122  - Hot Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];    ///< Offset 126  - Warm Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];     ///< Offset 130  - Hot Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+} ThermalMngmtEn;
+
+
+typedef struct {
+  UINT8      GdxcEnable;   ///< GDXC  MOT enable
+  UINT8      GdxcIotSize;  ///< IOT size in multiples of 8MEG
+  UINT8      GdxcMotSize;  ///< MOT size in multiples of 8MEG
+} MrcGdxc;
+
+typedef struct {
+  UINT32 ECT : 1;        ///< BIT0 - Early Command Training
+  UINT32 SOT : 1;        ///< BIT1 - Sense Amp Offset Training
+  UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
+  UINT32 RDMPRT : 1;     ///< BIT3 - Read MPR Training
+  UINT32 RCVET : 1;      ///< BIT4 - Read Leveling Training (RcvEn)
+  UINT32 JWRL : 1;       ///< BIT5 - Jedec Write Leveling
+  UINT32 EWRTC2D : 1;    ///< BIT6 - Early Write Time Centering 2D
+  UINT32 ERDTC2D : 1;    ///< BIT7  - Early Read Time Centering 2D
+  UINT32 WRTC1D : 1;     ///< BIT8 - Write Timing Centering 1D
+  UINT32 WRVC1D : 1;     ///< BIT9 - Write Voltage Centering 1D
+  UINT32 RDTC1D : 1;     ///< BIT10 - Read Timing Centering 1D
+  UINT32 DIMMODTT : 1;   ///< BIT11 - Dimm ODT Training
+  UINT32 DIMMRONT : 1;   ///< BIT12 - Dimm Ron Training
+  UINT32 WRDSEQT : 1;    ///< BIT13 - Write Drive Strength / Equalization Training 2D
+  UINT32 WRSRT : 1;      ///< BIT14 - Write Slew Rate Training
+  UINT32 RDODTT : 1;     ///< BIT15 - Read ODT Training
+  UINT32 RDEQT : 1;      ///< BIT16 - Read Equalization Training
+  UINT32 RDAPT : 1;      ///< BIT17 - Read Amplifier Power Training
+  UINT32 WRTC2D : 1;     ///< BIT18 - Write Timing Centering 2D
+  UINT32 RDTC2D : 1;     ///< BIT19 - Read Timing Centering 2D
+  UINT32 WRVC2D : 1;     ///< BIT20 - Write Voltage Centering 2D
+  UINT32 RDVC2D : 1;     ///< BIT21 - Read Voltage Centering 2D
+  UINT32 CMDVC : 1;      ///< BIT22 - Command Voltage Centering
+  UINT32 LCT : 1;        ///< BIT23 - Late Command Training
+  UINT32 RTL : 1;        ///< BIT24 - Round Trip latency
+  UINT32 TAT : 1;        ///< BIT25 - Turn Around Timing
+  UINT32 RMT : 1;        ///< BIT26 - RMT Tool
+  UINT32 MEMTST : 1;     ///< BIT27 - Memory Test
+  UINT32 ALIASCHK: 1;    ///< BIT28 - SPD Alias Check
+  UINT32 RCVENC1D: 1;    ///< BIT29 - Receive Enable Centering 1D
+  UINT32 RMC : 1;        ///< BIT30 - Retrain Margin Check
+  UINT32 WRDSUDT : 1;    ///< BIT31 - Write Drive Strength Up/Dn independently
+} TrainingStepsEn;
+
+typedef struct {
+  UINT32 CMDSR    : 1;   ///< BIT0  - CMD Slew Rate Training
+  UINT32 CMDDSEQ  : 1;   ///< BIT1  - CMD Drive Strength and Tx Equalization
+  UINT32 CMDNORM  : 1;   ///< BIT2  - CMD Normalization
+  UINT32 EWRDSEQ  : 1;   ///< BIT3  - Early DQ Write Drive Strength and Equalization Training
+  UINT32 TeRsv4   : 1;   ///< BIT4 - Reserved
+  UINT32 TeRsv5   : 1;   ///< BIT5 - Reserved
+  UINT32 TeRsv6   : 1;   ///< BIT6 - Reserved
+  UINT32 RsvdBits :25;
+} TrainingStepsEn2;
+
+///
+/// Defines whether the MRC is executing in full or mini BIOS mode.
+///
+typedef enum {
+  MrcModeFull,   ///< Select full BIOS MRC execution.
+  MrcModeMini,   ///< Select mini BIOS MRC execution.
+  MrcModeMaximum ///< Delimiter.
+} MrcMode;
+
+typedef enum {
+  MrcTmPower,
+  MrcTmMargin,
+  MrcTmMax
+} TrainingModeType;
+
+typedef enum {
+  LastRxV,
+  LastRxT,
+  LastTxV,
+  LastTxT,
+  LastRcvEna,
+  LastWrLevel,
+  LastCmdT,
+  LastCmdV,
+  MAX_RESULT_TYPE
+} MrcMarginResult;
+
+typedef enum {
+  MSG_LEVEL_NEVER,
+  MSG_LEVEL_ERROR,
+  MSG_LEVEL_WARNING,
+  MSG_LEVEL_NOTE,
+  MSG_LEVEL_EVENT,
+  MSG_LEVEL_ALGO,
+  MSG_LEVEL_MMIO,
+  MSG_LEVEL_CSV,
+  MSG_LEVEL_TIME,
+  MSG_LEVEL_ALL = MRC_INT32_MAX
+} MrcDebugMsgLevel;
+
+///
+/// Define the frequencies that may be possible in the memory controller.
+/// Note that not all these values may be supported.
+///
+#define fNoInit     (0)
+#define f800        (800)
+#define f1000       (1000)
+#define f1100       (1100)
+#define f1067       (1067)
+#define f1200       (1200)
+#define f1300       (1300)
+#define f1333       (1333)
+#define f1400       (1400)
+#define f1467       (1467)
+#define f1500       (1500)
+#define f1600       (1600)
+#define f1700       (1700)
+#define f1733       (1733)
+#define f1800       (1800)
+#define f1867       (1867)
+#define f1900       (1900)
+#define f2000       (2000)
+#define f2100       (2100)
+#define f2133       (2133)
+#define f2200       (2200)
+#define f2267       (2267)
+#define f2300       (2300)
+#define f2400       (2400)
+#define f2500       (2500)
+#define f2533       (2533)
+#define f2600       (2600)
+#define f2667       (2667)
+#define f2700       (2700)
+#define f2800       (2800)
+#define f2900       (2900)
+#define f2933       (2933)
+#define f3000       (3000)
+#define f3067       (3067)
+#define f3100       (3100)
+#define f3200       (3200)
+#define f3333       (3333)
+#define f3467       (3467)
+#define f3600       (3600)
+#define f3733       (3733)
+#define f3867       (3867)
+#define f4000       (4000)
+#define f4133       (4133)
+#define fInvalid    (0x7FFFFFFF)
+typedef UINT32 MrcFrequency;
+
+//
+// Max supported frequency in OC mode
+// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
+// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
+//
+#define MAX_FREQ_OC_133   f4133
+#define MAX_FREQ_OC_100   f3100
+
+//
+// tCK value in femtoseconds for various frequencies
+// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
+//
+#define MRC_DDR_800_TCK_MIN      2500000
+#define MRC_DDR_1000_TCK_MIN     2000000
+#define MRC_DDR_1067_TCK_MIN     1875000
+#define MRC_DDR_1100_TCK_MIN     1818182
+#define MRC_DDR_1200_TCK_MIN     1666667
+#define MRC_DDR_1300_TCK_MIN     1538462
+#define MRC_DDR_1333_TCK_MIN     1500000
+#define MRC_DDR_1400_TCK_MIN     1428571
+#define MRC_DDR_1467_TCK_MIN     1363636
+#define MRC_DDR_1500_TCK_MIN     1333333
+#define MRC_DDR_1600_TCK_MIN     1250000
+#define MRC_DDR_1700_TCK_MIN     1176471
+#define MRC_DDR_1733_TCK_MIN     1153846
+#define MRC_DDR_1800_TCK_MIN     1111111
+#define MRC_DDR_1867_TCK_MIN     1071429
+#define MRC_DDR_1900_TCK_MIN     1052632
+#define MRC_DDR_2000_TCK_MIN     1000000
+#define MRC_DDR_2100_TCK_MIN     952381
+#define MRC_DDR_2133_TCK_MIN     938000
+#define MRC_DDR_2200_TCK_MIN     909091
+#define MRC_DDR_2267_TCK_MIN     882353
+#define MRC_DDR_2300_TCK_MIN     869565
+#define MRC_DDR_2400_TCK_MIN     833333
+#define MRC_DDR_2500_TCK_MIN     800000
+#define MRC_DDR_2533_TCK_MIN     789474
+#define MRC_DDR_2600_TCK_MIN     769231
+#define MRC_DDR_2667_TCK_MIN     750000
+#define MRC_DDR_2700_TCK_MIN     740741
+#define MRC_DDR_2800_TCK_MIN     714286
+#define MRC_DDR_2900_TCK_MIN     689655
+#define MRC_DDR_2933_TCK_MIN     681818
+#define MRC_DDR_3000_TCK_MIN     666667
+#define MRC_DDR_3067_TCK_MIN     652174
+#define MRC_DDR_3100_TCK_MIN     645161
+#define MRC_DDR_3200_TCK_MIN     625000
+#define MRC_DDR_3333_TCK_MIN     600000
+#define MRC_DDR_3467_TCK_MIN     576923
+#define MRC_DDR_3600_TCK_MIN     555556
+#define MRC_DDR_3733_TCK_MIN     535714
+#define MRC_DDR_3867_TCK_MIN     517241
+#define MRC_DDR_4000_TCK_MIN     500000
+#define MRC_DDR_4133_TCK_MIN     483871
+
+///
+/// Define the memory nominal voltage (VDD).
+/// Note that not all these values may be supported.
+///
+typedef enum {
+  VDD_INVALID,
+  VDD_1_00    = 1000,
+  VDD_1_05    = 1050,
+  VDD_1_10    = 1100,
+  VDD_1_15    = 1150,
+  VDD_1_20    = 1200,
+  VDD_1_25    = 1250,
+  VDD_1_30    = 1300,
+  VDD_1_35    = 1350,
+  VDD_1_40    = 1400,
+  VDD_1_45    = 1450,
+  VDD_1_50    = 1500,
+  VDD_1_55    = 1550,
+  VDD_1_60    = 1600,
+  VDD_1_65    = 1650,
+  VDD_1_70    = 1700,
+  VDD_1_75    = 1750,
+  VDD_1_80    = 1800,
+  VDD_1_85    = 1850,
+  VDD_1_90    = 1900,
+  VDD_1_95    = 1950,
+  VDD_2_00    = 2000,
+  VDD_2_05    = 2050,
+  VDD_2_10    = 2100,
+  VDD_2_15    = 2150,
+  VDD_2_20    = 2200,
+  VDD_2_25    = 2250,
+  VDD_2_30    = 2300,
+  VDD_2_35    = 2350,
+  VDD_2_40    = 2400,
+  VDD_2_45    = 2450,
+  VDD_2_50    = 2500,
+  VDD_2_55    = 2550,
+  VDD_2_60    = 2600,
+  VDD_2_65    = 2650,
+  VDD_2_70    = 2700,
+  VDD_2_75    = 2750,
+  VDD_2_80    = 2800,
+  VDD_2_85    = 2850,
+  VDD_2_90    = 2900,
+  VDD_2_95    = 2950,
+  VDD_MAXIMUM = 0x7FFFFFFF
+} MrcVddSelect;
+
+///
+/// SA GV points
+///
+typedef enum {
+  MrcSaGvPointLow,
+  MrcSaGvPointHigh,
+} MrcSaGvPoint;
+
+///
+/// SA GV modes
+///  Disabled:  SA GV Disabled, run all MRC tasks
+///  FixedLow:  SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_LOW
+///  FixedHigh: SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_HIGH
+///  Enabled:   SA GV Enabled
+///
+typedef enum {
+  MrcSaGvDisabled,
+  MrcSaGvFixedLow,
+  MrcSaGvFixedHigh,
+  MrcSaGvEnabled,
+} MrcSaGv;
+
+///
+/// DIMM SPD Security Status
+///
+typedef enum {
+  MrcSpdStatusGood,      ///< Memory is in a secure state.
+  MrcSpdStatusAliased,   ///< Memory is aliased.
+  MrcSpdStatusLast       ///< Must be last in the list
+} MrcSpdStatus;
+
+///
+/// Define the virtual channel.
+///
+typedef enum {
+  vcL,  ///< Virtual channel L
+  vcS,  ///< Virtual channel S
+} MrcVirtualChannel;
+
+///
+/// Define the board types.
+///
+typedef enum {
+  btCRBMB,    ///< 0 - CRB Mobile
+  btCRBDT,    ///< 1 - CRB Desktop
+  btUser1,    ///< 2 - SV Karkom
+  btUser2,    ///< 3 - SV desktop
+  btUser3,    ///< 4 - SV miniDVP
+  btUser4,    ///< 5 - Ult
+  btCRBEMB,   ///< 6 - CRB Embedded
+  btUpServer, ///< 7 - Up Server
+  btUnknown,  ///< 8 - Unknown
+  btMaximum   ///< Delimiter
+} MrcBoardType;
+
+///
+/// Define the CPU family/model.
+///
+typedef enum {
+  cmCFL_ULX_ULT   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,  ///< Coffeelake ULT/ULX
+  cmCFL_DT_HALO   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO   ///< Coffeelake DT/Halo
+} MrcCpuModel;
+
+///
+/// Define the CPU Tick/Tock.
+///
+typedef enum {
+  cfCfl    = 0,  ///< Coffeelake
+  cfMax
+} MrcCpuFamily;
+
+///
+/// Define the CPU stepping number.
+///
+typedef enum {
+  ///
+  /// Coffeelake ULX/ULT
+  ///
+  csKblH0         = EnumKblH0,
+  csCflD0         = EnumCflD0,
+  csCflW0         = EnumCflW0,
+  csCflV0         = EnumCflV0,
+  csCflUlxUltLast = csCflV0,
+
+  ///
+  /// Coffeelake DT/Halo
+  ///
+  csCflU0         = EnumCflU0,
+  csCflB0         = EnumCflB0,
+  csCflP0         = EnumCflP0,
+  csCflR0         = EnumCflR0,
+  csCflDtHaloLast = csCflR0,
+} MrcCpuStepping;
+
+typedef enum {
+  CONTROLLER_NOT_PRESENT, ///< There is no controller present in the system.
+  CONTROLLER_DISABLED,    ///< There is a controller present but it is disabled.
+  CONTROLLER_PRESENT,     ///< There is a controller present and it is enabled.
+  MAX_CONTROLLER_STATUS   ///< Delimiter
+} MrcControllerSts;
+
+typedef enum {
+  CHANNEL_NOT_PRESENT,    ///< There is no channel present on the controller.
+  CHANNEL_DISABLED,       ///< There is a channel present but it is disabled.
+  CHANNEL_PRESENT,        ///< There is a channel present and it is enabled.
+  MAX_CHANNEL_STATUS      ///< Delimiter
+} MrcChannelSts;
+
+typedef enum {
+  DIMM_ENABLED,           ///< DIMM/rank Pair is enabled, presence will be detected.
+  DIMM_DISABLED,          ///< DIMM/rank Pair is disabled, regardless of presence.
+  DIMM_PRESENT,           ///< There is a DIMM present in the slot/rank pair and it will be used.
+  DIMM_NOT_PRESENT,       ///< There is no DIMM present in the slot/rank pair.
+  MAX_DIMM_STATUS         ///< Delimiter
+} MrcDimmSts;
+
+typedef enum {
+  STD_PROFILE,            ///< Standard DIMM profile select.
+  USER_PROFILE,           ///< User specifies various override values.
+  XMP_PROFILE1,           ///< XMP enthusiast settings select (XMP profile #1).
+  XMP_PROFILE2,           ///< XMP extreme settings select (XMP profile #2).
+  MAX_PROFILE             ///< Delimiter
+} MrcProfile;
+
+#define XMP_PROFILES_ENABLE   (0x3)
+#define XMP1_PROFILE_ENABLE   (0x1)
+#define XMP2_PROFILE_ENABLE   (0x2)
+
+typedef enum {
+  MRC_REF_CLOCK_133,      ///< 133MHz reference clock
+  MRC_REF_CLOCK_100,      ///< 100MHz reference clock
+  MRC_REF_CLOCK_MAXIMUM   ///< Delimiter
+} MrcRefClkSelect;        ///< This value times the MrcClockRatio determines the MrcFrequency.
+
+typedef enum {
+  MRC_FREQ_INVALID       = 0,
+  MRC_FREQ_133           = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
+  MRC_FREQ_100           = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
+  MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit 2
+  MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit 3
+  MRC_FREQ_MAX                                              // Delimiter
+} MrcFreqFlag;
+
+typedef UINT32 MrcBClkRef;   ///< Base clock, in Hertz, Default is 100MHz or leave at zero for default.
+
+//
+// This encoding matches CFL SC_GS_CFG.DRAM_technology and MAD_INTER_CHANNEL.DDR_TYPE registers
+//
+typedef enum {
+  MRC_DDR_TYPE_DDR4     = 0,
+  MRC_DDR_TYPE_DDR3     = 1,
+  MRC_DDR_TYPE_LPDDR3   = 2,
+  MRC_DDR_TYPE_UNKNOWN  = 3,
+  MAX_MRC_DDR_TYPE        ///< Delimiter
+} MrcDdrType;
+
+typedef enum {
+  MrcIterationClock,
+  MrcIterationCmdN,
+  MrcIterationCmdS,
+  MrcIterationCke,
+  MrcIterationCtl,
+  MrcIterationCmdV,
+  MrcIterationMax
+} MrcIterationType;
+
+typedef enum {
+  UpmLimit,
+  PowerLimit,
+  RetrainLimit,
+  MarginLimitMax
+} MRC_MARGIN_LIMIT_TYPE;
+
+
+typedef enum {
+  HardwareRhp,
+  Refresh2x
+} MrcRhpType;
+
+typedef enum {
+  OneIn2To1 = 1,
+  OneIn2To2,
+  OneIn2To3,
+  OneIn2To4,
+  OneIn2To5,
+  OneIn2To6,
+  OneIn2To7,
+  OneIn2To8,
+  OneIn2To9,
+  OneIn2To10,
+  OneIn2To11,
+  OneIn2To12,
+  OneIn2To13,
+  OneIn2To14,
+  OneIn2To15
+} MrcRhProbType;
+
+typedef enum {
+  MRC_POST_CODE,
+  MRC_POST_CODE_WRITE,
+  MRC_POST_CODE_READ,
+  MRC_POST_CODE_MAX
+} MrcDebugPostCode;
+
+typedef struct {
+  UINT32 MrcData;
+  UINT32 Stream;
+  UINT32 Start;
+  UINT32 End;
+  UINT32 Current;
+  int Level;
+  UINT16 PostCode[MRC_POST_CODE_MAX];
+  UINT32 TopStackAddr;     ///< Initial stack address.
+  UINT32 LowestStackAddr;  ///< Track the lowest stack address used through MrcPrintfVaList()
+} MrcDebug;
+
+typedef UINT16 MrcPostCode;
+typedef UINT8  MrcClockRatio;  ///< This value times the MrcRefClkSelect determines the MrcFrequency.
+typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data memory, in MBytes.
+typedef UINT32 MrcGfxGttSize;  ///< The size of the graphics translation table, in MBytes.
+
+
+///
+/// This data structure contains all the "DDR power saving data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  BOOLEAN    BaseFlag;      ///< Indicates if the base line of power was already calculated.
+  UINT16     BaseSavingRd;  ///< Indicates the base line of power consume by the ddr on read.
+  UINT16     BaseSavingWr;  ///< Indicates the base line of power consume by the ddr on write.
+  UINT16     BaseSavingCmd; ///< Indicates the base line of power consume by the ddr on command.
+  UINT16     MrcSavingRd;   ///< Indicates the power consume by the ddr on read at the end of MRC.
+  UINT16     MrcSavingWr;   ///< Indicates the power consume by the ddr on write at the end of MRC.
+  UINT16     MrcSavingCmd;  ///< Indicates the power consume by the ddr on command at the end of MRC.
+} MrcOdtPowerSaving;
+
+///
+/// The memory controller capabilities.
+///
+typedef union {
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} MrcCapabilityIdA;
+
+typedef union {
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} MrcCapabilityIdB;
+
+typedef union {
+  UINT64 Data;
+  struct {
+    MrcCapabilityIdA A;
+    MrcCapabilityIdB B;
+  } Data32;
+} MrcCapabilityId;
+
+///
+/// MRC version description.
+///
+typedef struct {
+  UINT8  Major;  ///< Major version number
+  UINT8  Minor;  ///< Minor version number
+  UINT8  Rev;    ///< Revision number
+  UINT8  Build;  ///< Build number
+} MrcVersion;
+
+///
+/// Memory map configuration information.
+///
+typedef struct {
+  UINT32     TomMinusMe;
+  UINT32     ToludBase;
+  UINT32     BdsmBase;
+  UINT32     GttBase;
+  UINT32     GraphicsControlRegister;
+  UINT32     TsegBase;
+  BOOLEAN    ReclaimEnable;
+  UINT32     RemapBase;
+  UINT32     RemapLimit;
+  UINT32     TouudBase;
+  UINT32     TotalPhysicalMemorySize;
+  UINT32     MeStolenBase;
+  UINT32     MeStolenSize;
+  UINT32     GdxcMotBase;
+  UINT32     GdxcMotSize;
+  UINT32     GdxcIotBase;
+  UINT32     GdxcIotSize;
+  UINT32     DprSize;
+  UINT32     PttStolenBase;
+  UINT32     PrmrrBase;
+  UINT32     LowestBase;
+} MrcMemoryMap;
+
+///
+/// Real time clock information.
+///
+typedef struct {
+  UINT8  Seconds;    ///< Seconds, 0-59
+  UINT8  Minutes;    ///< Minutes, 0-59
+  UINT8  Hours;      ///< Hours, 0-23
+  UINT8  DayOfMonth; ///< Day of the month, 1-31
+  UINT8  Month;      ///< Month of the year, 1-12
+  UINT16 Year;       ///< Year, 0-65535
+} MrcBaseTime;
+
+///
+/// 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.
+} MrcTiming;
+
+typedef struct {
+  UINT8 SG;       ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;       ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;       ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;       ///< Number of tCK cycles between transactions when switching between DIMMs
+} MrcTurnaroundTimes;
+
+typedef struct {
+  INT32 Mtb;    ///< Medium time base.
+  INT32 Ftb;    ///< Fine time base.
+} MrcTimeBase;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the timing eye.
+  UINT8  Center; ///< The center of the timing eye.
+  UINT8  Right;  ///< The right side of the timing eye.
+} MrcDqTimeMargin;
+
+typedef struct {
+  UINT8  High;   ///< The high side of the Vref eye.
+  UINT8  Center; ///< The center of the Vref eye.
+  UINT8  Low;    ///< The low side of the Vref eye.
+} MrcDqVrefMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the command eye.
+  UINT8  Right;  ///< The right side of the command eye.
+  UINT8  High;   ///< The high side of the command eye.
+  UINT8  Low;    ///< The low side of the command eye.
+} MrcCommandMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the receive enable eye.
+  UINT8  Right;  ///< The right side of the receive enableeye.
+} MrcRecvEnMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the write leveling eye.
+  UINT8  Right;  ///< The right side of the write leveling eye.
+} MrcWrLevelMargin;
+
+typedef struct {
+  UINT8     SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///< Each valid bit maps to SPD byte.
+  UINT8     MrcSpdString[3]; ///< The SPD data start marker. This must be located at the start of the SPD data structure. It includes this string plus the following flag.
+  union {
+    struct {
+      UINT8   DimmNumber    : 4; ///< SPD zero based DIMM number.
+      UINT8   ChannelNumber : 3; ///< SPD zero based channel number.
+      UINT8   MdSocket      : 1; ///< 0 = memory down, 1 = socketed.
+    } Bit;
+    UINT8 Data;
+  } Flag;
+  MrcSpd Data;            ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+} MrcSpdData;
+
+typedef UINT8        (*MRC_IO_READ_8)               (UINT32 IoAddress);
+typedef UINT16       (*MRC_IO_READ_16)              (UINT32 IoAddress);
+typedef UINT32       (*MRC_IO_READ_32)              (UINT32 IoAddress);
+typedef void         (*MRC_IO_WRITE_8)              (UINT32 IoAddress, UINT8 Value);
+typedef void         (*MRC_IO_WRITE_16)             (UINT32 IoAddress, UINT16 Value);
+typedef void         (*MRC_IO_WRITE_32)             (UINT32 IoAddress, UINT32 Value);
+typedef UINT8        (*MRC_MMIO_READ_8)             (UINT32 Address);
+typedef UINT16       (*MRC_MMIO_READ_16)            (UINT32 Address);
+typedef UINT32       (*MRC_MMIO_READ_32)            (UINT32 Address);
+typedef UINT64       (*MRC_MMIO_READ_64)            (UINT32 Address);
+typedef UINT8        (*MRC_MMIO_WRITE_8)            (UINT32 Address, UINT8 Value);
+typedef UINT16       (*MRC_MMIO_WRITE_16)           (UINT32 Address, UINT16 Value);
+typedef UINT32       (*MRC_MMIO_WRITE_32)           (UINT32 Address, UINT32 Value);
+typedef UINT64       (*MRC_MMIO_WRITE_64)           (UINT32 Address, UINT64 Value);
+typedef UINT8        (*MRC_SMBUS_READ_8)            (UINT32 Address, UINT32 *Status);
+typedef UINT16       (*MRC_SMBUS_READ_16)           (UINT32 Address, UINT32 *Status);
+typedef UINT8        (*MRC_SMBUS_WRITE_8)           (UINT32 Address, UINT8 Value, UINT32 *Status);
+typedef UINT16       (*MRC_SMBUS_WRITE_16)          (UINT32 Address, UINT16 Value, UINT32 *Status);
+typedef UINT32       (*MRC_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef UINT32       (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef void         (*MRC_GET_RTC_TIME)            (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
+typedef UINT64       (*MRC_GET_CPU_TIME)            (void *MrcData);
+typedef void *       (*MRC_MEMORY_COPY)             (UINT8 *Destination, UINT8 *Source, UINT32 NumBytes);
+typedef void *       (*MRC_MEMORY_SET_BYTE)         (UINT8 *Destination, UINT32 NumBytes, UINT8 Value);
+typedef void *       (*MRC_MEMORY_SET_WORD)         (UINT16 *Destination, UINT32 NumWords, UINT16 Value);
+typedef void *       (*MRC_MEMORY_SET_DWORD)        (UINT32 *Destination, UINT32 NumDwords, UINT32 Value);
+typedef UINT64       (*MRC_LEFT_SHIFT_64)           (UINT64 Data, UINT32 NumBits);
+typedef UINT64       (*MRC_RIGHT_SHIFT_64)          (UINT64 Data, UINT32 NumBits);
+typedef UINT64       (*MRC_MULT_U64_U32)            (UINT64 Multiplicand, UINT32 Multiplier);
+typedef UINT64       (*MRC_DIV_U64_U64)             (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);
+typedef BOOLEAN      (*MRC_GET_SPD_DATA)            (UINT8 BootMode, UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize, UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32 LpddrTableSize);
+typedef BOOLEAN      (*MRC_GET_RANDOM_NUMBER)       (UINT32 *Rand);
+typedef UINT32       (*MRC_CPU_MAILBOX_READ)        (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);
+typedef UINT32       (*MRC_CPU_MAILBOX_WRITE)       (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);
+typedef UINT32       (*MRC_GET_MEMORY_VDD)          (void *MrcData, UINT32 DefaultVdd);
+typedef UINT32       (*MRC_SET_MEMORY_VDD)          (void *MrcData, UINT32 DefaultVdd, UINT32 Value);
+typedef UINT32       (*MRC_CHECKPOINT)              (void *MrcData, UINT32 CheckPoint, void *Scratch);
+typedef void         (*MRC_DEBUG_HOOK)              (void *GlobalData, UINT16 DisplayDebugNumber);
+typedef void         (*MRC_PRINT_STRING)            (void *String);
+typedef UINT8        (*MRC_GET_RTC_CMOS)            (UINT8 Location);
+typedef UINT64       (*MRC_MSR_READ_64)             (UINT32 Location);
+typedef UINT64       (*MRC_MSR_WRITE_64)            (UINT32 Location, UINT64 Data);
+typedef void         (*MRC_RETURN_FROM_SMC)         (void *GlobalData, UINT32 MrcStatus);
+typedef void         (*MRC_DRAM_RESET)              (UINT32 PciEBaseAddress, UINT32 ResetValue);
+typedef void         (*MRC_SET_LOCK_PRMRR)          (UINT32 PrmrrBase, UINT32 PrmrrSize);
+typedef void         (*MRC_TXT_ACHECK)              (void);
+
+///
+/// Function calls that are called external to the MRC.
+///   This structure needs to be aligned with SA_FUNCTION_CALLS.  All functions that are
+///   not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
+///
+typedef struct {
+  MRC_IO_READ_8               MrcIoRead8;
+  MRC_IO_READ_16              MrcIoRead16;
+  MRC_IO_READ_32              MrcIoRead32;
+  MRC_IO_WRITE_8              MrcIoWrite8;
+  MRC_IO_WRITE_16             MrcIoWrite16;
+  MRC_IO_WRITE_32             MrcIoWrite32;
+  MRC_MMIO_READ_8             MrcMmioRead8;
+  MRC_MMIO_READ_16            MrcMmioRead16;
+  MRC_MMIO_READ_32            MrcMmioRead32;
+  MRC_MMIO_READ_64            MrcMmioRead64;
+  MRC_MMIO_WRITE_8            MrcMmioWrite8;
+  MRC_MMIO_WRITE_16           MrcMmioWrite16;
+  MRC_MMIO_WRITE_32           MrcMmioWrite32;
+  MRC_MMIO_WRITE_64           MrcMmioWrite64;
+  MRC_SMBUS_READ_8            MrcSmbusRead8;
+  MRC_SMBUS_READ_16           MrcSmbusRead16;
+  MRC_SMBUS_WRITE_8           MrcSmbusWrite8;
+  MRC_SMBUS_WRITE_16          MrcSmbusWrite16;
+  MRC_GET_PCI_DEVICE_ADDRESS  MrcGetPciDeviceAddress;
+  MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
+  MRC_GET_RTC_TIME            MrcGetRtcTime;
+  MRC_GET_CPU_TIME            MrcGetCpuTime;
+  MRC_MEMORY_COPY             MrcCopyMem;
+  MRC_MEMORY_SET_BYTE         MrcSetMem;
+  MRC_MEMORY_SET_WORD         MrcSetMemWord;
+  MRC_MEMORY_SET_DWORD        MrcSetMemDword;
+  MRC_LEFT_SHIFT_64           MrcLeftShift64;
+  MRC_RIGHT_SHIFT_64          MrcRightShift64;
+  MRC_MULT_U64_U32            MrcMultU64x32;
+  MRC_DIV_U64_U64             MrcDivU64x64;
+  MRC_GET_SPD_DATA            MrcGetSpdData;
+  MRC_GET_RANDOM_NUMBER       MrcGetRandomNumber;
+  MRC_CPU_MAILBOX_READ        MrcCpuMailboxRead;
+  MRC_CPU_MAILBOX_WRITE       MrcCpuMailboxWrite;
+  MRC_GET_MEMORY_VDD          MrcGetMemoryVdd;
+  MRC_SET_MEMORY_VDD          MrcSetMemoryVdd;
+  MRC_CHECKPOINT              MrcCheckpoint;
+  MRC_DEBUG_HOOK              MrcDebugHook;
+  MRC_PRINT_STRING            MrcPrintString;
+  MRC_GET_RTC_CMOS            MrcRtcCmos;
+  MRC_MSR_READ_64             MrcReadMsr64;
+  MRC_MSR_WRITE_64            MrcWriteMsr64;
+  MRC_RETURN_FROM_SMC         MrcReturnFromSmc;
+  MRC_DRAM_RESET              MrcDramReset;
+  MRC_SET_LOCK_PRMRR          MrcSetLockPrmrr;
+  MRC_TXT_ACHECK              MrcTxtAcheck;
+} MRC_FUNCTION;
+
+///
+///*****************************************
+/// Output related "global data" structures.
+///*****************************************
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+} MrcSdramOut;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+//MrcSdramOut     Sdram[MAX_SDRAM_IN_DIMM];         ///< The following are SDRAM level definitions.
+  UINT16             MR[MAX_MR_IN_DIMM];            ///< DRAM mode register value.
+  UINT16             MR11;                          ///< LPDDR3 ODT MR
+  UINT8              Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0] for per-DRAM VrefDQ (PDA)
+#if (SUPPORT_DDR4 == SUPPORT)
+  UINT8              Device[MAX_SDRAM_IN_DIMM];     ///< Which Bytes are tied to which Device where BIT0 set means Byte 0
+#endif //SUPPORT_DDR4
+} MrcRankOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+  MrcDimmSts     Status;                    ///< See MrcDimmSts for the definition of this field.
+  MrcTiming      Timing[MAX_PROFILE];       ///< The DIMMs timing values.
+  MrcVddSelect   VddVoltage[MAX_PROFILE];   ///< The voltage (VDD) setting for this DIMM, per profile.
+  BOOLEAN        EccSupport;                ///< TRUE if ECC is enabled and supported on this DIMM.
+  BOOLEAN        IgnoreNonEccDimm;          ///< TRUE if a DIMM without ECC capability should be ignored.
+  BOOLEAN        AddressMirrored;           ///< TRUE if the DIMM is address mirrored.
+  BOOLEAN        SelfRefreshTemp;           ///< TRUE if the DIMM supports self refresh extended operating temperature range (SRT).
+  BOOLEAN        AutoSelfRefresh;           ///< TRUE if the DIMM supports automatic self refresh (ASR).
+  BOOLEAN        PartialSelfRefresh;        ///< TRUE if the DIMM supports Partial Array Self Refresh (PASR).
+  BOOLEAN        OnDieThermalSensor;        ///< TRUE if the DIMM supports On-die Thermal Sensor (ODTS) Readout.
+  BOOLEAN        ExtendedTemperRange;       ///< TRUE if the DIMM supports Extended Temperature Range (ETR).
+  BOOLEAN        ExtendedTemperRefresh;     ///< TRUE if the DIMM supports 1x Extended Temperature Refresh rate, FALSE = 2x.
+  MrcDdrType     DdrType;                   ///< DDR type: DDR3 or LPDDR3
+  MEMORY_PACKAGE ModuleType;                ///< Module type: UDIMM, SO-DIMM, etc.
+  UINT32         SdramCount;                ///< The number of SDRAM components on a DIMM.
+  UINT32         DimmCapacity;              ///< DIMM size in MBytes.
+  UINT32         RowSize;                   ///< The DIMMs row address size.
+  UINT16         ColumnSize;                ///< The DIMMs column address size.
+  UINT16         Crc;                       ///< Calculated CRC16 of the DIMM's provided SPD. Can be used to detect DIMM change.
+  UINT8          RankInDimm;                ///< The number of ranks in this DIMM.
+  UINT8          Banks;                     ///< Number of banks the DIMM contains.
+  UINT8          BankGroups;                ///< Number of bank groups the DIMM contains.
+  UINT8          PrimaryBusWidth;           ///< DIMM primary bus width.
+  UINT8          SdramWidth;                ///< DIMM SDRAM width.
+  UINT8          SdramWidthIndex;           ///< DIMM SDRAM width index (0 = x4, 1 = x8, 2 = x16, 3 = x32).
+  UINT8          DensityIndex;              ///< Total SDRAM capacity index (0 = 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
+  UINT8          tMAC;                      ///< Maximum Activate Count for pTRR.
+  UINT8          ReferenceRawCard;          ///< Indicates which JEDEC reference design raw card was used as the basis for the module assembly.
+  UINT8          ReferenceRawCardRevision;  ///< Indicates which JEDEC reference design raw card revision.
+  UINT8          XmpSupport;                ///< Indicates if XMP profiles are supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
+  UINT8          XmpRevision;               ///< Indicates the XMP revision of this DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
+  MrcFrequency   Speed;                     ///< Max DIMM speed in the current profile - needed for SMBIOS.
+  MrcRankOut     Rank[MAX_RANK_IN_DIMM];    ///< The following are rank level definitions.
+} MrcDimmOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+  MrcChannelSts       Status;                                                       ///< Indicates whether this channel should be used.
+  MrcVirtualChannel   VirtualChannel;                                               ///< define the virtual channel type A or B.
+  MrcTiming           Timing[MAX_PROFILE];                                          ///< The channel timing values.
+  MrcTimeBase         TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE];                  ///< Medium and fine timebases for each DIMM in the channel and each memory profile.
+  UINT32              Capacity;                                                     ///< Amount of memory in this channel, in MBytes.
+  UINT32              DimmCount;                                                    ///< Number of valid DIMMs that exist in the channel.
+  UINT32              DataOffsetTrain[MAX_SDRAM_IN_DIMM];                           ///< DataOffsetTrain CR
+  UINT32              DataCompOffset[MAX_SDRAM_IN_DIMM];                            ///< DataCompOffset CR
+  UINT32              CkeCmdPiCode[MAX_COMMAND_GROUPS];                             ///< CKE  CmdPiCode CR, per group
+  UINT32              CmdsCmdPiCode[MAX_COMMAND_GROUPS];                            ///< CmdS CmdPiCode CR, per group
+  UINT32              CmdnCmdPiCode[MAX_COMMAND_GROUPS];                            ///< CmdN CmdPiCode CR, per group
+  UINT16              TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///< TxDQS PI Code
+  UINT16              TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< TxDQ Pi Code
+  UINT16              RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///< RcvEn PI Code
+  UINT16              WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];              ///< WlDelay PI Code
+  UINT8               ClkPiCode[MAX_RANK_IN_CHANNEL];                               ///< Clk Pi Code
+  UINT8               CtlPiCode[MAX_RANK_IN_CHANNEL];                               ///< Ctl Pi Code
+  UINT8               CkePiCode[MAX_RANK_IN_CHANNEL];                               ///< Ctl Pi Code
+  UINT8               TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< TxEq setting
+  MrcCommandMargin    Command[MAX_RANK_IN_CHANNEL];                                 ///< Cmd setting
+  MrcDqTimeMargin     RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];     ///< Rx PerBit Pi Code
+  MrcDqTimeMargin     TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];     ///< Tx PerBit Pi Code
+  MrcDqVrefMargin     RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+  MrcDqVrefMargin     TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+  MrcRecvEnMargin     ReceiveEnable[MAX_RANK_IN_CHANNEL];                           ///< Receive enable per rank
+  MrcWrLevelMargin    WriteLevel[MAX_RANK_IN_CHANNEL];                              ///< Write leveling per rank
+  UINT8               IoLatency[MAX_RANK_IN_CHANNEL];                               ///< IOLatency
+  UINT8               RTLatency[MAX_RANK_IN_CHANNEL];                               ///< RoundTripLatency
+  UINT32              RTIoComp;                                                     ///< RoundTrip IO Compensation of the Channel
+  UINT8               RxVref[MAX_SDRAM_IN_DIMM];                                    ///< RX Vref in steps of 7.9 mv
+  UINT8               RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< RxEQ Setting
+  UINT8               RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///< RxDQSP PI Code
+  UINT8               RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///< RxDQSN PI Code
+  UINT8               ValidRankBitMask;                                             ///< Bit map of the populated ranks per channel
+  UINT8               ValidCkeBitMask;                                              ///< Bit map of the used CKE pins per channel
+  MrcDimmOut          Dimm[MAX_DIMMS_IN_CHANNEL];                                   ///< DIMM specific output variables.
+  MrcTurnaroundTimes  tRd2Rd;                                                       ///< The system's minimal delay timings for Read  command followed by Read  command.
+  MrcTurnaroundTimes  tRd2Wr;                                                       ///< The system's minimal delay timings for Read  command followed by Write command.
+  MrcTurnaroundTimes  tWr2Rd;                                                       ///< The system's minimal delay timings for Write command followed by Read  command.
+  MrcTurnaroundTimes  tWr2Wr;                                                       ///< The system's minimal delay timings for Write command followed by Write command.
+} MrcChannelOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  MrcControllerSts 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.
+  MrcChannelOut    Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerOut;
+
+///
+///********************************************
+/// Saved data related "global data" structures.
+///********************************************
+///
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are DIMM level definitions.
+///
+typedef struct {
+  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.
+} MrcDimmSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are channel level definitions.
+///
+typedef struct {
+  MrcChannelSts Status;                               ///< Indicates whether this channel should be used.
+  UINT32        DimmCount;                            ///< Number of valid DIMMs that exist in the channel.
+  UINT8         ValidRankBitMask;                     ///< Bit map of the populated ranks per channel
+  MrcTiming     Timing[MAX_PROFILE];                  ///< The channel timing values.
+  MrcDimmOut    Dimm[MAX_DIMMS_IN_CHANNEL];           ///< Save the DIMM output characteristics.
+  MrcDimmSave   DimmSave[MAX_DIMMS_IN_CHANNEL];       ///< Save SPD information needed for SMBIOS structure creation.
+} MrcChannelSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are controller level definitions.
+///
+typedef struct {
+  MrcControllerSts  Status;               ///< Indicates whether this controller should be used.
+  UINT8             ChannelCount;         ///< Number of valid channels that exist on the controller.
+  MrcChannelSave    Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcContSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are system level definitions.
+///
+typedef struct {
+  UINT32 Crc;                  ///< The CRC-32 of the data in this structure.
+} MrcSaveHeader;
+
+//
+// ------- IMPORTANT NOTE --------
+// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in MrcSaveRestore.c.
+// Update this define whenever you add/remove registers from this table.
+//
+#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (common)
+#define MRC_REGISTER_COUNT_SAGV   (1528 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (per SA GV point)
+
+typedef struct {
+  MrcCapabilityId McCapId;                                   ///< The memory controller's capabilities.
+  UINT32          RegSaveCommon[MRC_REGISTER_COUNT_COMMON];  ///< The MC registers that are common to both SA GV points
+  UINT32          RegSaveLow[MRC_REGISTER_COUNT_SAGV];       ///< The MC registers for the Low SA GV point
+  UINT32          RegSaveHigh[MRC_REGISTER_COUNT_SAGV];      ///< The MC registers for the High SA GV point, or for SA GV Disabled case
+  UINT32          MeStolenSize;                              ///< The managebility engine memory size, in Mbyte units.
+  MrcCpuStepping  CpuStepping;                               ///< The last cold boot happended with this CPU stepping.
+  MrcCpuModel     CpuModel;                                  ///< The last cold boot happended with this CPU model.
+  MrcCpuFamily    CpuFamily;                                 ///< CPU is Coffeelake
+  MrcVersion      Version;                                   ///< The last cold boot happended with this MRC version.
+  UINT32          SaMemCfgCrc;                               ///< The CRC32 of the system agent memory configuration structure.
+  MrcContSave     Controller[MAX_CONTROLLERS];               ///< The following are controller level definitions.
+  MrcFrequency    FreqMax;                                   ///< The system's requested maximum frequency.
+  MrcFrequency    Frequency;                                 ///< The system's common memory controller frequency.
+  UINT32          MemoryClock;                               ///< The system's common memory controller clock, in femtoseconds.
+  BOOLEAN         OddRatioModeLow;                           ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV Low point.
+  BOOLEAN         OddRatioModeHigh;                          ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV High point, or SAGV disabled / fixed high / fixed low
+  MrcRefClkSelect RefClk;                                    ///< The memory controller is going to use this reference clock.
+  MrcClockRatio   Ratio;                                     ///< Request for this memory controller to use this clock ratio.
+  MrcVddSelect    VddVoltage[MAX_PROFILE];                   ///< The voltage (VDD) setting for all DIMMs in the system, per profile.
+  BOOLEAN         EccSupport;                                ///< TRUE if ECC is enabled and supported on this controller.
+  MrcDdrType      DdrType;                                   ///< DDR type: DDR3, DDR4, or LPDDR3
+  UINT32          DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The Default XMP tCK values read from SPD.
+  UINT8           XmpProfileEnable;                          ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  BOOLEAN         BinnedLpddrDevices;                        ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+  BOOLEAN         TCRSensitiveHynixDDR4;                     ///< TCR sensitive Hynix DDR4 in the system
+  BOOLEAN         TCRSensitiveMicronDDR4;                    ///< TCR sensitive Micron DDR4 in the system
+  BOOLEAN         LpddrEctDone;                       ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+  UINT8           BerEnable;                          ///< BER Enable (and # of Addresses)
+  UINT64          BerAddress[4];                      ///< BER Addresses
+  BOOLEAN         DmfcLimitedBoard;                   ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+  BOOLEAN         DmfcLimited;                        ///< Indicates if the system has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
+  BOOLEAN         MixedUDimmConfig2Dpc;               ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+  BOOLEAN         ExtendedDdrOverclock;               ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+} MrcSaveData;
+
+typedef struct {
+  UINT32              Size;                        ///< The size of this structure, in bytes. Must be the first entry in this structure.
+  MrcDebug            Debug;                       ///< MRC debug related variables used for serial output and debugging purposes.
+  MrcVersion          Version;                     ///< The memory reference code version.
+  MrcFrequency        FreqMax;                     ///< The requested maximum valid frequency.
+  MrcFrequency        Frequency;                   ///< The system's common memory controller frequency.
+  UINT32              MemoryClockMax;              ///< The system's common memory controller maximum clock, in femtoseconds.
+  UINT32              MemoryClock;                 ///< The system's common memory controller clock, in femtoseconds.
+  MrcRefClkSelect     RefClk;                      ///< The memory controller is going to use this reference clock.
+  MrcClockRatio       Ratio;                       ///< Request for this memory controller to use this clock ratio.
+  MrcMemoryMap        MemoryMapData;               ///< The system's memory map data.
+  MrcGfxDataSize      GraphicsStolenSize;          ///< Graphics Data Stolen Memory size in MB
+  MrcGfxGttSize       GraphicsGttSize;             ///< GTT graphics stolen memory size in MB
+  MrcVddSelect        VddVoltage[MAX_PROFILE];     ///< The currently running voltage (VDD) setting for all DIMMs in the system, per profile.
+  MrcGdxc             Gdxc;                        ///< GDXC enable and size.
+  BOOLEAN             VddVoltageDone;              ///< To determine if VddVoltageDone update has been done already
+  BOOLEAN             EccSupport;                  ///< TRUE if ECC is enabled and supported on this controller.
+  BOOLEAN             EnDumRd;                     ///< Enable/Disable Logic Analyzer
+  BOOLEAN             RestoreMRs;                  ///< Enable/Disable restoring
+  BOOLEAN             LpddrEctDone;                ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+  BOOLEAN             LpddrWLUpdated;              ///< Set to TRUE once LPDDR WL Memory Set has been updated
+  BOOLEAN             JedecInitDone;               ///< Set to TRUE once JEDEC Init on LPDDR/DDR4 is done
+  UINT32              DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1];            ///< The Default XMP tCK values read from SPD.
+  UINT8               XmpProfileEnable;            ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  BOOLEAN             Capable100;                  ///< The MC is capable of 100 reference clock (0 = no, 1 = yes).
+  BOOLEAN             AutoSelfRefresh;             ///< Indicates ASR is supported for all the DIMMS for 2xRefresh
+  MrcDdrType          DdrType;                     ///< Current memory type: DDR3, DDR4, or LPDDR3
+  MrcSpdStatus        SpdSecurityStatus;           ///< Status variable to inform BIOS that memory contains an alias.
+  UINT32              MrcTotalChannelLimit;        ///< The maximum allowed memory size per channel, in MBytes.
+  UINT8               SdramCount;                  ///< The number of SDRAM components on a DIMM.
+  UINT16              Qclkps;                      ///< Qclk period in pS
+  UINT8               DQPat;                       ///< Global Variables storing the current DQPat REUT Test
+  INT8                DQPatLC;                     ///< Global Variables storing the current DQPat Loopcount
+  UINT16              NumCL;                       ///< Global Variables storing the current number of Cachelines
+  UINT8               ValidRankMask;               ///< Rank bit map - includes both channels
+  UINT8               ValidChBitMask;              ///< Channel bit map of the populated channels
+  BOOLEAN             UpmPwrRetrainFlag;           ///< A flag that indicates if training with higher UPM/PWR limits.
+  UINT32              MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin measurement.
+  BOOLEAN             MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
+  MrcOdtPowerSaving   OdtPowerSavingData;          ///< ODT power savings data.
+  BOOLEAN             TxDIMMVref[MAX_CHANNEL];     ///< Whether Write DIMM Vref is enabled based on Channel
+  UINT32              MchBarWriteCount;            ///< The number of MMIO writes performed during MRC execution.
+  UINT32              MchBarReadCount;             ///< The number of MMIO reads performed during MRC execution.
+  UINT8               BerEnable;                   ///< BER Enable (and # of Addresses)
+  UINT64              BerAddress[4];               ///< BER Addresses
+  UINT8               CmdVLoop;                    ///< Keeps track of the # of CmdV training step runned
+  UINT8               CmdVLoopStatus;              ///< Keeps the last status of the CmdV training step
+  UINT8               tMAC;                        ///< Maximum Activate Count for pTRR.
+  UINT8               LpddrMemWriteLatencySet;     ///< 0 = Set A (WL), 1 = Set B (WL) if supported
+  BOOLEAN             Ddr4PdaEnable;               ///< Current status of PDA - if true all the Mr6 operations need to use PDA mode.
+  BOOLEAN             BinnedLpddrDevices;          ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+  MrcControllerOut    Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+  BOOLEAN             TCRSensitiveHynixDDR4;       ///< TCR sensitive Hynix DDR4 in the system
+  BOOLEAN             TCRSensitiveMicronDDR4;      ///< TCR sensitive Micron DDR4 in the system
+  BOOLEAN             OddRatioMode;                ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz
+  BOOLEAN             LpddrDramOdt;                ///< Indicates if LPDDR DRAM ODT is used - Only used for 2133+
+  BOOLEAN             ExtendedDdrOverclock;        ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+  BOOLEAN             DmfcLimitedBoard;            ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+  BOOLEAN             DmfcLimited;                 ///< Indicates if the system has DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
+  BOOLEAN             MixedUDimmConfig2Dpc;        ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+#ifdef BDAT_SUPPORT
+  union {
+    MRC_BDAT_SCHEMA_LIST_HOB *Pointer;             ///< Pointer to the BDAT schema list.
+    UINT64                   Data;
+  } BdatSchemasHob;
+  union {
+    BDAT_MEMORY_DATA_HOB *Pointer;                 ///< Pointer to the BDAT memory data HOB.
+    UINT64               Data;
+  } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
+  UINT8               Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
+#endif
+
+#ifdef UP_SERVER_FLAG
+  UINT8              ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];                        ///< TSOD Thermal Offset
+#endif
+} MrcOutput;
+
+///
+///****************************************
+/// Input related "global data" structures.
+///****************************************
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+  UINT8  Placeholder;  ///< TODO: Is there anything that needs to go in here?
+} MrcSdramIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+  MrcSdramIn  Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are SDRAM level definitions.
+} MrcRankIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+  MrcDimmSts  Status;                 ///< Indicates whether this DIMM should be used.
+  MrcSpdData  Spd;                    ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+  MrcTiming   Timing;                 ///< The DIMMs requested timing overrides.
+  UINT8       SpdAddress;             ///< The SMBus address for the DIMM's SPD data.
+//MrcRankIn   Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level definitions.
+} MrcDimmIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+  MrcChannelSts Status;                        ///< Indicates whether this channel should be used.
+  UINT32        DimmCount;                     ///< The maximum number of DIMMs on this channel.
+  MrcDimmIn     Dimm[MAX_DIMMS_IN_CHANNEL];    ///< The following are DIMM level definitions.
+  UINT8         DqsMapCpu2Dram[8];             ///< Mapping from CPU DQS pins to SDRAM DQS pins
+  UINT8         DqMapCpu2Dram[8][MAX_BITS];    ///< Mapping from CPU DQ pins to SDRAM DQ pins
+  UINT8         DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side), per group
+                                               ///< DQByteMap[0] - ClkDQByteMap:
+                                               ///<   If clock is per rank, program to [0xFF, 0xFF]
+                                               ///<   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+                                               ///<   If clock is shared by 2 ranks but does not go to all bytes,
+                                               ///<           Entry[i] defines which DQ bytes Group i services
+                                               ///< DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+                                               ///< DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+                                               ///< DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+                                               ///<                For DDR, DQByteMap[3:1] = [0xFF, 0]
+                                               ///< DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+                                               ///<                               Variable only exists to make the code easier to use
+                                               ///< DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+                                               ///<                               Variable only exists to make the code easier to use
+} MrcChannelIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  MrcControllerSts  Status;               ///< Indicates whether this controller should be used.
+  UINT8             ChannelCount;         ///< Number of valid channels that are requested on the controller.
+  MrcChannelIn      Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerIn;
+
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are system level definitions. All memory controllers in the system are set to these values.
+typedef struct {
+  // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
+  // Alignment of this block must be maintained and field offsets must match.
+  UINT8   Header[28];             ///< 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
+  UINT8   MemoryProfile;          ///< 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 MemoryProfile is UserDefined (CUSTOM PROFILE)
+  UINT16  tCL;                    ///< Offset 32 User defined Memory Timing tCL value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 31=Maximum.
+  UINT16  tRCDtRP;                ///< Offset 34 User defined Memory Timing tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tRAS;                   ///< Offset 36 User defined Memory Timing tRAS value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 64=Maximum.
+  UINT16  tWR;                    ///< Offset 38 User defined Memory Timing tWR value,   valid when MemoryProfile 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 MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 1023=Maximum.
+  UINT16  tRRD;                   ///< Offset 42 User defined Memory Timing tRRD value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR;                   ///< Offset 44 User defined Memory Timing tWTR value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tRTP;                   ///< Offset 46 User defined Memory Timing tRTP value,  valid when MemoryProfile 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 MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tCWL;                   ///< Offset 50 User defined Memory Timing tCWL value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 20=Maximum.
+  UINT16  tREFI;                  ///< Offset 52 User defined Memory Timing tREFI value, valid when MemoryProfile 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 DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  RemapEnable:1;                  ///<  - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+  UINT32  ScramblerEnable:1;              ///<  - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor: 0=Disable, <b>1=Enable</b>
+  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set option: 0=Set A, <b>1=Set B</b>
+  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bits 7-8 Reserved
+  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+  UINT32  Ddr4DdpSharedClock:1;           ///<  - New Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  UINT32  Ddr4DdpSharedZq:1;              ///<  - Select if ZQ pin is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  // Thermal Management
+  UINT32  ThermalManagement:1;            ///<  - Memory Thermal Management Support: <b>0=Disable</b>, 1=Enable.
+  UINT32  PeciInjectedTemp:1;             ///<  - Enable/Disable memory temperatures to be injected to the processor via PECI: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnBoard:1;            ///<  - Enable/Disable routing TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnDimm:1;             ///<  - Enable/Disable routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  VirtualTempSensor:1;            ///<  - Enable/Disable Virtual Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
+  UINT32  Lp4DqsOscEn:1;                  ///<  - DqDqsReTraining support: 0=Disable, <b>1=Enable</b>
+  UINT32  DualDimmPerChannelBoardType:1;  ///<  - DualDimmPerChannelBoardType: Option to indicate if the Memory Design for the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>, 1=Dual DIMM Design
+  UINT32  ReservedBits1:13;
+  /**
+   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[MAX_CHANNEL];  ///< Offset 68
+  /**
+   Selects the ratio to multiply the reference clock by for the DDR frequency\n
+   When RefClk is 133MHz\n
+   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are invalid\n
+   When RefClk is 100MHz\n
+   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are invalid\n
+  **/
+  UINT8   Ratio;                  ///< Offset 70
+  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+  /**
+     - Channel Hash Enable.\n
+    NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at 4 and BIT9 at 8\n
+    0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
+  **/
+  UINT8   ChHashInterleaveBit;    ///< Offset 76
+  UINT8   EnergyScaleFact;        ///< Offset 77 - Energy Scale Factor. 0=Minimal, 7=Maximum, <b>4=Default</b>
+  UINT8   Reserved0;              ///< Offset 78 - Reserved for future use.
+  UINT8   McLock;                 ///< Offset 79 - Enable/Disable memory configuration register locking: 0=Disable, <b>1=Enable</b>.
+  // Training Algorithms
+  TrainingStepsEn TrainingEnables;    ///< Offset 80 - Options to Enable individual training steps
+  TrainingStepsEn2 TrainingEnables2;  ///< Offset 84 - Options to Enable individual training steps
+
+  UINT32  OddRatioMode:1;             ///< Offset 88 - If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcTimeMeasure:1;           ///< - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcFastBoot:1;              ///< - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+  UINT32  DqPinsInterleaved:1;        ///< - Interleaving mode of DQ/DQS pins for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
+  UINT32  RankInterleave:1;           ///< - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  EnhancedInterleave:1;       ///< - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  WeaklockEn:1;               ///< - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  CmdTriStateDis:1;           ///< - CMD Tri-State Support: <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if Command RTT is not present on the platform.
+  UINT32  MemoryTrace:1;              ///< - Memory Trace to second DDR channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  ChHashEnable:1;             ///< - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  EnableExtts:1;              ///< - Enable Extts: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableCltm:1;               ///< - Enable Closed Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableOltm:1;               ///< - Enable Open Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnablePwrDn:1;              ///< - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  EnablePwrDnLpddr:1;         ///< - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  LockPTMregs:1;              ///< - Lock PCU Thermal Management registers: 0=Disable, <b>1=Enable</b>
+  UINT32  UserPowerWeightsEn:1;       ///< - Allows user to explicitly set power weight, scale factor, and channel power floor values: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Lock:1;             ///< - Lock DDR_RAPL_LIMIT register: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Ena:1;              ///< - Enable Power Limit 2: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim1Ena:1;              ///< - Enable Power Limit 1: <b>0=Disable</b>, 1=Enable
+  UINT32  SrefCfgEna:1;               ///< - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeatLpddr:1;    ///< - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeat:1;         ///< - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+  UINT32  AutoSelfRefreshSupport:1;   ///< - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+  UINT32  ExtTemperatureSupport:1;    ///< - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+  UINT32  MobilePlatform:1;           ///< - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+  UINT32  Force1Dpc:1;                ///< - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+  UINT32  ForceSingleRank:1;          ///< - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+  UINT32  RhPrevention:1;             ///< - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+  UINT32  VttTermination:1;           ///< - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+  UINT32  VttCompForVsshi:1;          ///< - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+  UINT32  ExitOnFailure:1;            ///< - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+
+  UINT32  VddSettleWaitTime;      ///< Offset 92 - Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+  UINT16  FreqSaGvLow;            ///< Offset 96 - SA GV: 0 is Auto/default, otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333, 1400, 1600, 1800, 1867.
+  UINT16  SrefCfgIdleTmr;         ///< Offset 98 - Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+  UINT8   RhActProbability;       ///< Offset 100 - Activation probability for Hardware RHP
+  UINT8   SmramMask;              ///< Offset 101 - Reserved memory ranges for SMRAM
+  UINT16  Vc1ReadMeterThreshold;  ///< Offset 102 - VC1 Read Meter Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum, <b>0x118=Default</b>
+  UINT32  Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
+  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es): <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
+
+  UINT16  ChHashMask;             ///< Offset 140 - 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 142 - Memory Frequency Limit: <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see MrcFrequency in MrcInterface.h
+  ThermalMngmtEn  ThermalEnables; ///< Offset 144 - 187
+
+  UINT8   MaxRttWr;               ///< Offset 188 - Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+  UINT8   ThrtCkeMinTmr;          ///< Offset 189 - Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
+  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 - Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
+  UINT8   BerEnable;              ///< Offset 191 - BER Enable and # of Addresses passed in: <b>0=Minimal</b>, 8=Maximum
+  UINT8   CkeRankMapping;         ///< Offset 192 - Bits [7:4] - Channel 1, bits [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes to.
+  UINT8   StrongWkLeaker;         ///< Offset 193 - Strong Weak Leaker: 1=Minimal, <b>7=Maximum</b>
+  UINT8   CaVrefConfig;           ///< Offset 194 - 0=VREF_CA goes to both CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A, VREF_DQ_B to CH_B</b>
+  UINT8   SaGv;                   ///< Offset 195 - SA GV: <b>0=Disabled</b>, 1=FixedLow, 2=FixedHigh, 3=Enabled
+  UINT8   RaplPwrFlCh1;           ///< Offset 196 - Power Channel 1 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   RaplPwrFlCh0;           ///< Offset 197 - Power Channel 0 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   NModeSupport;           ///< Offset 198 - Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+  UINT8   RefClk;                 ///< Offset 199 - Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+  UINT8   EnCmdRate;              ///< Offset 200 - CMD Rate Enable: 0=Disable, 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7 CMDs
+  UINT8   Refresh2X;              ///< Offset 201 - Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+  UINT8   EpgEnable;              ///< Offset 202 - Enable Energy Performance Gain.
+  UINT8   RhSolution;             ///< Offset 203 - Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  UINT8   UserThresholdEnable;    ///< Offset 204 - Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   UserBudgetEnable;       ///< Offset 205 - Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodTcritMax;           ///< Offset 206 - TSOD Tcrit Maximum Value  to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
+
+  UINT8   TsodEventMode;          ///< Offset 207 - Flag to Enable Event Mode Interruption in TSOD Configuration Register, 0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventPolarity;      ///< Offset 208 - Event Signal Polarity in TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
+  UINT8   TsodCriticalEventOnly;  ///< Offset 209 - Critical Trigger Only in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventOutputControl; ///< Offset 210 - Event Output Control in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodShutdownMode;       ///< Offset 213 - Shutdown Mode TSOD Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
+  UINT8   TsodThigMax;            ///< Offset 214 - Thigh Max Value In the  for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodManualEnable;       ///< Offset 215 - Flag to manually select the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   DllBwEn0;               ///< Offset 216 - DllBwEn value for 1067
+  UINT8   DllBwEn1;               ///< Offset 217 - DllBwEn value for 1333
+  UINT8   DllBwEn2;               ///< Offset 218 - DllBwEn value for 1600
+  UINT8   DllBwEn3;               ///< Offset 219 - DllBwEn value for 1867 and up
+  UINT8   RetrainOnFastFail;      ///< Offset 220 - Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 - Force OLTM or 2X Refresh when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
+  UINT8   PowerDownMode;          ///< Offset 222 - CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+  UINT8   PwdwnIdleCounter;       ///< Offset 223 - CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal, 0xFF=Maximum, <b>0x99=Default</b>
+  UINT8   Reserved3;              ///< Offset 225 -  ConfigBlock size must be a multiple of DWORDs
+  MrcGdxc Gdxc;                   ///< Offset 226 - 228 - GDXC enable and size.
+  UINT8   RMTLoopCount;           ///< Offset 229 - Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+  UINT8   Reserved4[2];           ///< Offset 230 - 231 Reserved for DWORD alignment.
+  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232Bit1Rsvd:2;             ///< Offset 232 Bit 1-2: Reserved
+  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is enabled for Rank Margin Tool
+  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4: Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
+  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Enalbes MRC trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
+  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
+
+  //
+  // TurnAround Timing
+  //
+  MrcTurnaroundTimes tRd2Rd;      ///< Offset 236 - User-defined overrides for Read-to-Read   Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tRd2Wr;      ///< Offset 240 - User-defined overrides for Read-to-Write  Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tWr2Rd;      ///< Offset 244 - User-defined overrides for Write-to-Read  Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tWr2Wr;      ///< Offset 248 - User-defined overrides for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
+  UINT16  tRRD_L;                 ///< Offset 252 - User defined DDR4 Memory Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tRRD_S;                 ///< Offset 254 - User defined DDR4 Memory Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR_L;                 ///< Offset 266 - User defined DDR4 Memory Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tWTR_S;                 ///< Offset 268 - User defined DDR4 Memory Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+
+  //
+  // End of synchronization to the SA MEMORY_CONFIGURATION structure.
+  //
+  MrcFrequency     FreqMax;                     ///< The requested maximum valid frequency.
+  MrcBoardType     BoardType;                   ///< Define the board type (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
+  MrcCpuStepping   CpuStepping;                 ///< Define the CPU stepping.
+  MrcCpuModel      CpuModel;                    ///< Define the CPU model.
+  MrcCpuFamily     CpuFamily;                   ///< CPU is Coffeelake
+  MrcGfxDataSize   GraphicsStolenSize;          ///< Graphics Data Stolen Memory size in MB
+  MrcGfxGttSize    GraphicsGttSize;             ///< GTT graphics stolen memory size in MB
+  MrcBaseTime      BaseTime;                    ///< RTC base time.
+  MrcIteration     Iteration;                   ///< Number of iterations thru the MRC core call table.
+  MrcMode          MrcMode;                     ///< The control for full or MiniBIOS MRC.
+  MrcBootMode      BootMode;                    ///< The requested memory controller boot mode.
+  BOOLEAN          TxtFlag;                     ///< Trusted eXecution Technology flag.
+  BOOLEAN          SetRxDqs32;                  ///< Set DQS Delay to 32 control.
+  BOOLEAN          GfxIsVersatileAcceleration;  ///< iGFX engines are in Versatile Acceleration
+  BOOLEAN          DDR4MAP;                     ///< DDR4 PDA Mapping training control.
+  POINTER_STRUCT   SaMemCfgAddress;             ///< Starting address of the input parameters to CRC.
+  UINT32           SaMemCfgSize;                ///< The size of the input parameters to CRC.
+  UINT32           PciEBaseAddress;             ///< define the PciE base address.
+  UINT32           MchBarBaseAddress;           ///< define the MCH bar base address.
+  UINT32           SmbusBaseAddress;            ///< This field defines the smbus base address.
+  UINT32           GdxcBaseAddress;             ///< This field defines the GDXC base address.
+  UINT32           HpetBaseAddress;             ///< This field defines the hpet base address.
+  UINT32           MeStolenSize;                ///< define the size that the ME need in MB.
+  UINT32           MmioSize;                    ///< define the MMIO size in MB.
+  UINT32           TsegSize;                    ///< TSEG size that require by the system in MB.
+  UINT32           IedSize;                     ///< IED size that require by the system in MB.
+  UINT32           DprSize;                     ///< DPR size required by system in MB.
+  UINT32           PrmrrSize;                   ///< Prmrr size required by the system in MB.
+  POINTER_STRUCT   SerialBuffer;                ///< Pointer to the start of the serial buffer.
+  UINT32           SerialBufferSize;            ///< The size of the serial buffer, in bytes.
+  UINT32           DebugStream;                 ///< The debug port pointer.
+  INT32            DebugLevel;                  ///< Indicates the level of debug messaging.
+  UINT16           VccIomV;                     ///< VccIO logic voltage in mV.
+  MrcControllerIn  Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+  UINT32           HeapBase;                    ///< Starting address of the heap space.
+  UINT32           HeapSize;                    ///< Size of the heap space, in bytes.
+  UINT32           MrcStackTop;                 ///< Top of the stack at the beginning of MRC, for stack usage calculations.
+  BOOLEAN          BdatEnable;                  ///< Option to enable output of training results into BDAT.
+  UINT8            BdatTestType;                ///< When BdatEnable is set to TRUE, this option selects the type of training results data which will be populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
+  BOOLEAN          LpddrDramOdt;                ///< TRUE if LPDDR DRAM ODT is used - depends on board design
+  BOOLEAN          Ddr3DramOdt;                 ///< TRUE if DDR3  DRAM ODT is used - depends on board design
+  BOOLEAN          Ddr4DramOdt;                 ///< TRUE if DDR4  DRAM ODT is used - depends on board design
+  BOOLEAN          EnableVrefPwrDn;             ///< Setting this limits VrefGen to be off only during CKEPowerDown
+  BOOLEAN          TxEqDis;                     ///< Disable TX Equalization
+  BOOLEAN          EnVttOdt;                    ///< Enable VTT Termination for Data ODT
+  UINT32           CpuidModel;                  ///< Unique CPU identifier.
+  UINT8            CpuidStepping;               ///< Revision of the CPU.
+  UINT8            CpuidSku;                    ///< SKU of the CPU.
+  UINT32           SiPreMemPolicyPpi;
+  TrainingModeType PowerTrainingMode;           ///< 0 - Power Training. 1 - Margin Training.
+  union {
+    MRC_FUNCTION  *Func;                        ///< External to MRC function pointers
+    UINT64        Data;
+  } Call;
+  UINT16          RcompResistor[MAX_RCOMP];     ///< Reference RCOMP resistors on motherboard
+  UINT16          RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+  UINT32          CleanMemory:1;                ///< TRUE to request a memory clean
+  UINT32          OcSupport:1;                  ///< TRUE if Overclocking is enabled in BIOS
+  UINT32          RsvdBits5:30;
+  /**
+   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;
+} MrcInput;
+
+typedef struct {
+  UINT32        Size;   ///< The size of this structure, in bytes. Must be the first entry in this structure.
+  MrcSaveHeader Header; ///< The header portion of the MRC saved data.
+  MrcSaveData   Data;   ///< The data portion of the MRC saved data.
+} MrcSave;
+
+typedef struct {
+  // Global variables that will be copied to the HOB follow.
+  UINT8        MrcDataString[4]; ///< Beginning of global data marker, starts with "MRC". Must be the first entry in this structure.
+  UINT32       MrcDataSize;      ///< The size of the MRC global data area, in bytes. Must be the second entry in this structure.
+  MrcSave      Save;             ///< System specific save variables.
+  MrcInput     Inputs;           ///< System specific input variables.
+  MrcOutput    Outputs;          ///< System specific output variables.
+
+  // Global variables that will remain internal to the MRC library follow.
+  union {
+    void   *Internal; ///< System specific output variables that remain internal to the library.
+    UINT64 Data;
+  } IntOutputs;
+} MrcParameters;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
new file mode 100644
index 0000000000..9dd9b096ba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
@@ -0,0 +1,203 @@
+/** @file
+  Copies the memory related timing and configuration information into the
+  Compatible BIOS data (BDAT) table.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcRmtData_h_
+#define _MrcRmtData_h_
+
+#include "MrcTypes.h"
+
+#define VDD_1_350             1350                      ///< VDD in millivolts
+#define VDD_1_500             1500                      ///< VDD in millivolts
+#define PI_STEP_BASE          2048                      ///< Magic number from spec
+#define PI_STEP_INTERVAL      128                       ///< tCK is split into this amount of intervals
+#define PI_STEP               ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
+#define VREF_STEP_BASE        100                       ///< Magic number from spec
+#define TX_VREF_STEP          7800                      ///< TX Vref step in microvolts
+#define TX_VREF(VDD)          (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define RX_VREF_STEP          8000                      ///< TX Vref step in microvolts
+#define RX_VREF(VDD)          (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define CA_VREF_STEP          8000                      ///< TX Vref step in microvolts
+#define CA_VREF(VDD)          (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+
+#define MAX_SPD_RMT           512                       ///< The maximum amount of data, in bytes, in an SPD structure.
+#define RMT_PRIMARY_VERSION   4                         ///< The BDAT structure that is currently supported.
+#define RMT_SECONDARY_VERSION 0                         ///< The BDAT structure that is currently supported.
+#define MAX_MODE_REGISTER     7                         ///< Number of mode registers
+#define MAX_DRAM_DEVICE       9                         ///< Maximum number of memory devices
+#define MAX_2D_EYE_TYPE       2                         ///< Maximum number of supported Margin 2D Eye Types
+#define MAX_2D_EYE_OFFSETS    7                         ///< Number of 2D Eye Offsets
+
+//
+// Warning: Bdat4.h has its own copy of this #define
+// make sure to change it in both places
+//
+#define MAX_SCHEMA_LIST_LENGTH (10)
+
+
+#ifdef BDAT_SUPPORT
+/*
+  BSSA result Memory Schema GUID
+  {8F4E928-0F5F-46D4-8410-479FDA279DB6}
+*/
+extern EFI_GUID gSsaBiosResultsGuid;
+/*
+  RMT Results Metadata GUID
+  {02CB1552-D659-4232-B51F-CAB1E11FCA87}
+*/
+extern EFI_GUID gRmtResultMetadataGuid;
+/*
+  RMT Results Columns GUID
+  {0E60A1EB-331F-42A1-9DE7-453E84761154}
+*/
+extern EFI_GUID gRmtResultColumnsGuid;
+
+/*
+Margin2D Results Metadata GUID
+{48265582-8E49-4AC7-AA06-E1B9A74C9716}
+*/
+extern EFI_GUID gMargin2DResultMetadataGuid;
+/*
+Margin2D Results Columns GUID
+{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
+*/
+extern EFI_GUID gMargin2DResultColumnsGuid;
+
+#endif
+/*
+ GUID for Schema List HOB
+ This is private GUID used by MemoryInit internally.
+ {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
+*/
+extern EFI_GUID gMrcSchemaListHobGuid;
+
+#pragma pack(push, 1)
+
+
+///
+/// SSA results buffer header.
+///
+typedef struct {
+  UINT32  Revision;
+  BOOLEAN TransferMode;
+  struct {
+    UINT32   Reserved;
+    UINT32   MetadataSize;
+    EFI_GUID MetadataType;
+  } MdBlock;
+  struct {
+    UINT32   Reserved;
+    EFI_GUID ResultType;
+    UINT32   ResultElementSize;
+    INT32    ResultCapacity;
+    INT32    ResultElementCount;
+  } RsBlock;
+} RESULTS_DATA_HDR;
+
+// start auto-generated by the BSSA CCK sourced from the result xml files.
+typedef enum {
+  DisableScrambler = 0,
+  EnableScrambler = 1,
+  DontTouchScrambler = 2,
+  SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
+} SCRAMBLER_OVERRIDE_MODE;
+
+typedef struct _RMT_RESULT_METADATA {
+  BOOLEAN EnableCtlAllMargin;
+  UINT16 SinglesBurstLength;
+  UINT32 SinglesLoopCount;
+  UINT16 TurnaroundsBurstLength;
+  UINT32 TurnaroundsLoopCount;
+  SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
+  UINT8 PiStepUnit[2];
+  UINT16 RxVrefStepUnit[2];
+  UINT16 TxVrefStepUnit[2][2];
+  UINT16 CmdVrefStepUnit[2][2];
+  UINT8 MajorVer;
+  UINT8 MinorVer;
+  UINT8 RevVer;
+  UINT32 BuildVer;
+  UINT16 ResultEleCount;
+} RMT_RESULT_METADATA;
+
+
+typedef struct _RMT_RESULT_ROW_HEADER {
+  UINT32 ResultType : 5;
+  UINT32 Socket : 3;
+  UINT32 Controller : 2;
+  UINT32 Channel : 3;
+  UINT32 DimmA : 1;
+  UINT32 RankA : 3;
+  UINT32 DimmB : 1;
+  UINT32 RankB : 3;
+  UINT32 Lane : 8;
+  UINT32 IoLevel : 1;
+  UINT32 Reserved : 2;
+} RMT_RESULT_ROW_HEADER;
+
+typedef struct _RMT_RESULT_COLUMNS {
+  RMT_RESULT_ROW_HEADER Header;
+  UINT8 Margin[4][2];
+} RMT_RESULT_COLUMNS;
+
+// end of auto-generated by the BSSA CCK sourced from the result xml files.
+
+typedef struct _BASE_RMT_RESULT {
+  RESULTS_DATA_HDR              ResultsHeader;
+  RMT_RESULT_METADATA           Metadata;
+  RMT_RESULT_COLUMNS            Rows[1];
+} BASE_RMT_RESULT;
+
+
+typedef struct {
+  UINT32                      Data1;
+  UINT16                      Data2;
+  UINT16                      Data3;
+  UINT8                       Data4[8];
+} BDAT_EFI_GUID;
+
+typedef struct {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} BDAT_HOB_GENERIC_HEADER;
+
+typedef struct {
+  BDAT_HOB_GENERIC_HEADER  Header;
+  BDAT_EFI_GUID            Name;
+  ///
+  /// Guid specific data goes here
+  ///
+} BDAT_HOB_GUID_TYPE;
+
+typedef struct {
+  BDAT_EFI_GUID               SchemaId;                         ///< The GUID uniquely identifies the format of the data contained within the structure.
+  UINT32                      DataSize;                         ///< The total size of the memory block, including both the header as well as the schema specific data.
+  UINT16                      Crc16;                            ///< Crc16 is computed in the same manner as the field in the BDAT_HEADER_STRUCTURE.
+} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
+
+typedef struct {
+  MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader;                ///< The schema header.
+  BASE_RMT_RESULT          RMT_RESULTS_WITH_META_COLUMNS;
+} BDAT_MEMORY_DATA_STRUCTURE;
+
+typedef struct {
+  BDAT_HOB_GUID_TYPE          HobGuidType;
+  BDAT_MEMORY_DATA_STRUCTURE  MemorySchema;
+} BDAT_MEMORY_DATA_HOB;
+
+#pragma pack (pop)
+
+typedef struct {
+  BDAT_HOB_GUID_TYPE          HobGuidType;
+  UINT16                      SchemaHobCount;
+  UINT16                      Reserved;
+  BDAT_EFI_GUID               SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
+} MRC_BDAT_SCHEMA_LIST_HOB;
+
+#endif //_MrcRmtData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
new file mode 100644
index 0000000000..45de5084c0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
@@ -0,0 +1,1167 @@
+/** @file
+  SPD data format header file.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcSpdData_h_
+#define _MrcSpdData_h_
+#pragma pack (push, 1)
+
+#include "MrcTypes.h"
+
+#define MAX_XMP_PROFILES  (2)
+#define SPD3_MANUF_SIZE   (SPD3_MANUF_END - SPD3_MANUF_START + 1)   ///< The size of the SPD manufacturing data.
+#define SPD4_MANUF_SIZE   (SPD4_MANUF_END - SPD4_MANUF_START + 1)   ///< The size of the SPD manufacturing data.
+#define SPDLP_MANUF_SIZE  (SPDLP_MANUF_END - SPDLP_MANUF_START + 1) ///< The size of the SPD manufacturing data
+
+typedef union {
+  struct {
+    UINT8  BytesUsed                           :  4; ///< Bits 3:0
+    UINT8  BytesTotal                          :  3; ///< Bits 6:4
+    UINT8  CrcCoverage                         :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_DEVICE_DESCRIPTION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Minor                               :  4; ///< Bits 3:0
+    UINT8  Major                               :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_REVISION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Type                                :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_DRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ModuleType                          :  4; ///< Bits 3:0
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  3; ///< Bits 6:4
+    UINT8                                      :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ColumnAddress                       :  3; ///< Bits 2:0
+    UINT8  RowAddress                          :  3; ///< Bits 5:3
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_ADDRESSING_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_50                     :  1; ///< Bits 0:0
+    UINT8  OperationAt1_35                     :  1; ///< Bits 1:1
+    UINT8  OperationAt1_25                     :  1; ///< Bits 2:2
+    UINT8                                      :  5; ///< Bits 7:3
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SdramDeviceWidth                    :  3; ///< Bits 2:0
+    UINT8  RankCount                           :  3; ///< Bits 5:3
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_ORGANIZATION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  PrimaryBusWidth                     :  3; ///< Bits 2:0
+    UINT8  BusWidthExtension                   :  2; ///< Bits 4:3
+    UINT8                                      :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Divisor                             :  4; ///< Bits 3:0
+    UINT8  Dividend                            :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_FINE_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Dividend                            :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Divisor                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
+
+typedef struct {
+  SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium Timebase (MTB) Dividend
+  SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT  Divisor;  ///< Medium Timebase (MTB) Divisor
+} SPD_MEDIUM_TIMEBASE;
+
+typedef union {
+  struct {
+    UINT8  tCKmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TCK_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 CL4                                 :  1; ///< Bits 0:0
+    UINT16 CL5                                 :  1; ///< Bits 1:1
+    UINT16 CL6                                 :  1; ///< Bits 2:2
+    UINT16 CL7                                 :  1; ///< Bits 3:3
+    UINT16 CL8                                 :  1; ///< Bits 4:4
+    UINT16 CL9                                 :  1; ///< Bits 5:5
+    UINT16 CL10                                :  1; ///< Bits 6:6
+    UINT16 CL11                                :  1; ///< Bits 7:7
+    UINT16 CL12                                :  1; ///< Bits 8:8
+    UINT16 CL13                                :  1; ///< Bits 9:9
+    UINT16 CL14                                :  1; ///< Bits 10:10
+    UINT16 CL15                                :  1; ///< Bits 11:11
+    UINT16 CL16                                :  1; ///< Bits 12:12
+    UINT16 CL17                                :  1; ///< Bits 13:13
+    UINT16 CL18                                :  1; ///< Bits 14:14
+    UINT16                                     :  1; ///< Bits 15:15
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tAAmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TAA_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tWRmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TWR_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRCDmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRCD_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRRDmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRRD_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPab                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_AB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPabFine                            :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_AB_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPpb                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_PB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPpbFine                            :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_PB_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16  tRFCab                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_AB_MTB_STRUCT;
+
+typedef union {
+struct {
+    UINT16  tRFCpb                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_PB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRASminUpper                        :  4; ///< Bits 3:0
+    UINT8  tRCminUpper                         :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_TRAS_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRASmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRAS_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRCmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 tRFCmin                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tWTRmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TWTR_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRTPmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRTP_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tFAWminUpper                        :  4; ///< Bits 3:0
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tFAWmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TFAW_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCWLmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TCWL_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  NMode                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_SYSTEM_COMMAND_RATE_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 tREFImin                            :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TREFI_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  RZQ6                                :  1; ///< Bits 0:0
+    UINT8  RZQ7                                :  1; ///< Bits 1:1
+    UINT8                                      :  5; ///< Bits 6:2
+    UINT8  DllOff                              :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ExtendedTemperatureRange            :  1; ///< Bits 0:0
+    UINT8  ExtendedTemperatureRefreshRate      :  1; ///< Bits 1:1
+    UINT8  AutoSelfRefresh                     :  1; ///< Bits 2:2
+    UINT8  OnDieThermalSensor                  :  1; ///< Bits 3:3
+    UINT8                                      :  3; ///< Bits 6:4
+    UINT8  PartialArraySelfRefresh             :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ThermalSensorAccuracy               :  7; ///< Bits 6:0
+    UINT8  ThermalSensorPresence               :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_THERMAL_SENSOR_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  NonStandardDeviceDescription        :  7; ///< Bits 6:0
+    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TCK_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tAAminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TAA_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRCDminFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRCD_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRCminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRC_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tMACencoding                        :  4; ///< Bits 3:0
+    UINT8  tMAWencoding                        :  2; ///< Bits 5:4
+    UINT8  Reserved                            :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_PTRR_SUPPORT_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRRDminFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRRD_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_REFERENCE_RAW_CARD;
+
+typedef union {
+  struct {
+    UINT8  MappingRank1                        :  1; ///< Bits 0:0
+    UINT8                                      :  7; ///< Bits 7:1
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_ADDRESS_MAPPING;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8                                      :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_REFERENCE_RAW_CARD;
+
+typedef union {
+  struct {
+    UINT8  RegisterCount                       :  2; ///< Bits 1:0
+    UINT8  DramRowCount                        :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_ATTRIBUTES;
+
+typedef union {
+  struct {
+    UINT16 ContinuationCount                   :  7; ///< Bits 6:0
+    UINT16 ContinuationParity                  :  1; ///< Bits 7:7
+    UINT16 LastNonZeroByte                     :  8; ///< Bits 15:8
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_MANUFACTURER_ID_CODE;
+
+typedef struct {
+  UINT8  Year;                                 ///< Year represented in BCD (00h = 2000)
+  UINT8  Week;                                 ///< Year represented in BCD (47h = week 47)
+} SPD_MANUFACTURING_DATE;
+
+typedef union {
+  UINT32 Data;
+  UINT16 SerialNumber16[2];
+  UINT8  SerialNumber8[4];
+} SPD_MANUFACTURER_SERIAL_NUMBER;
+
+typedef struct {
+  UINT8 Location;                              ///< Module Manufacturing Location
+} SPD_MANUFACTURING_LOCATION;
+
+typedef struct {
+  SPD_MANUFACTURER_ID_CODE            IdCode;                   ///< Module Manufacturer ID Code
+  SPD_MANUFACTURING_LOCATION          Location;                 ///< Module Manufacturing Location
+  SPD_MANUFACTURING_DATE              Date;                     ///< Module Manufacturing Year, in BCD (range: 2000-2255)
+  SPD_MANUFACTURER_SERIAL_NUMBER      SerialNumber;             ///< Module Serial Number
+} SPD_UNIQUE_MODULE_ID;
+
+typedef union {
+  UINT16 Crc[1];
+  UINT8  Data8[2];
+} SPD_CYCLIC_REDUNDANCY_CODE;
+
+typedef union {
+  struct {
+    UINT8  ProfileEnable1                :  1;                     ///< Bits 0:0
+    UINT8  ProfileEnable2                :  1;                     ///< Bits 1:1
+    UINT8  ProfileConfig1                :  2;                     ///< Bits 3:2
+    UINT8  ProfileConfig2                :  2;                     ///< Bits 5:4
+    UINT8                                :  2;                     ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_XMP_ORG_CONFIG;
+
+typedef struct {
+  UINT16                              XmpId;                    ///< 176-177 XMP Identification String
+  SPD_XMP_ORG_CONFIG                  XmpOrgConf;               ///< 178 XMP Organization & Configuration
+  SPD_REVISION_STRUCT                 XmpRevision;              ///< 179 XMP Revision
+  SPD_MEDIUM_TIMEBASE                 MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase (MTB)
+  SPD_FINE_TIMEBASE_STRUCT            FineTimeBase;             ///< 184 Fine Timebase (FTB) Dividend / Divisor
+} SPD_EXTREME_MEMORY_PROFILE_HEADER;
+
+typedef union {
+  struct {
+    UINT8  Decimal : 5;
+    UINT8  Integer : 2;
+    UINT8          : 1;
+  } Bits;
+  UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Decimal : 7;
+    UINT8  Integer : 1;
+  } Bits;
+  UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
+
+typedef union {
+  struct {
+    UINT8  Fine                                :  2; ///< Bits 1:0
+    UINT8  Medium                              :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD4_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT32 CL7                                 :  1; ///< Bits 0:0
+    UINT32 CL8                                 :  1; ///< Bits 1:1
+    UINT32 CL9                                 :  1; ///< Bits 2:2
+    UINT32 CL10                                :  1; ///< Bits 3:3
+    UINT32 CL11                                :  1; ///< Bits 4:4
+    UINT32 CL12                                :  1; ///< Bits 5:5
+    UINT32 CL13                                :  1; ///< Bits 6:6
+    UINT32 CL14                                :  1; ///< Bits 7:7
+    UINT32 CL15                                :  1; ///< Bits 8:8
+    UINT32 CL16                                :  1; ///< Bits 9:9
+    UINT32 CL17                                :  1; ///< Bits 10:10
+    UINT32 CL18                                :  1; ///< Bits 11:11
+    UINT32 CL19                                :  1; ///< Bits 12:12
+    UINT32 CL20                                :  1; ///< Bits 13:13
+    UINT32 CL21                                :  1; ///< Bits 14:14
+    UINT32 CL22                                :  1; ///< Bits 15:15
+    UINT32 CL23                                :  1; ///< Bits 16:16
+    UINT32 CL24                                :  1; ///< Bits 17:17
+    UINT32                                     :  14; ///< Bits 31:18
+  } Bits;
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef struct {
+  SPD_VDD_VOLTAGE_LEVEL_STRUCT        Vdd;                      ///< 185, 220 XMP Module VDD Voltage Level
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 186, 221 XMP SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 187, 222 XMP Minimum CAS Latency Time (tAAmin)
+  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
+  SPD_TCWL_MIN_MTB_STRUCT             tCWLmin;                  ///< 190, 225 XMP Minimum CAS Write Latency Time (tCWLmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 191, 226 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 192, 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 193, 228 XMP Minimum Write Recovery Time (tWRmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 194, 229 XMP Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 195, 230 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 196, 231 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TREFI_MIN_MTB_STRUCT            tREFImin;                 ///< 197-198, 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 199-200, 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least Significant Byte
+  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 201, 236 XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 202, 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 203, 238 XMP Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 204, 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 205, 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
+  UINT8                               Reserved1[207 - 206 + 1]; ///< 206-207, 241-242 XMP Reserved
+  SPD_SYSTEM_COMMAND_RATE_STRUCT      SystemCmdRate;            ///< 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
+  SPD_AUTO_SELF_REFRESH_PERF_STRUCT   AsrPerf;                  ///< 209, 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6 impact)
+  UINT8                               VoltageLevel;             ///< 210, 245 XMP Memory Controller Voltage Level
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 211, 246 XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 212, 247 XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 213, 248 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 214, 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 215, 250 XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  UINT8                               Reserved2[218 - 216 + 1]; ///< 216-218, 251-253 XMP Reserved
+  UINT8                               VendorPersonality;        ///< 219, 254 XMP Vendor Personality
+} SPD_EXTREME_MEMORY_PROFILE_DATA;
+
+typedef struct {
+  SPD_EXTREME_MEMORY_PROFILE_HEADER   Header;                   ///< 176-184 XMP header
+  SPD_EXTREME_MEMORY_PROFILE_DATA     Data[MAX_XMP_PROFILES];   ///< 185-254 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE;
+
+typedef struct {
+  UINT16                              XmpId;                        ///< 384-385 XMP Identification String
+  SPD_XMP_ORG_CONFIG                  XmpOrgConf;                   ///< 386 XMP Organization & Configuration
+  SPD_REVISION_STRUCT                 XmpRevision;                  ///< 387 XMP Revision
+  SPD4_TIMEBASE_STRUCT                TimeBase[MAX_XMP_PROFILES];   ///< 388-389 Medium and Fine Timebase
+  UINT8                               Reserved[392 - 390 + 1];     ///< 390-392 Reserved
+} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
+
+typedef struct {
+  SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0    Vdd;                      ///< 393, 440 XMP Module VDD Voltage Level
+  UINT8                               Reserved1[395 - 394 + 1]; ///< 394-395, 441-442 XMP Reserved
+  SPD_TCK_MIN_MTB_STRUCT              tCKAVGmin;                ///< 396, 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
+  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///< 397-400, 444-447 XMP CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 401, 448 XMP Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 402, 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 403, 450 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 404, 451 XMP Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 405, 452 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 406, 453 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 407-408, 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 409-410, 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 411-412, 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 413, 460 Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 414, 461 Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 415, 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 416, 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+  UINT8                               Reserved2[424 - 417 + 1]; ///< 417-424, 464-471 XMP Reserved
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 425, 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 426, 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 427, 474 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 428, 475 Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 429, 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 430, 477 Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TCK_MIN_FTB_STRUCT              tCKAVGminFine;            ///< 431, 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
+  UINT8                               Reserved3[439 - 432 + 1]; ///< 432-439, 479-486 XMP Reserved
+} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
+
+typedef struct {
+  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0      Header;                   ///< 384-392 XMP header
+  SPD_EXTREME_MEMORY_PROFILE_DATA_2_0        Data[MAX_XMP_PROFILES];   ///< 393-486 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE_2_0;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0   Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                 Revision;                 ///< 1   SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2   DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3   Module Type
+  SPD_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;     ///< 4   SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5   SDRAM Addressing
+  SPD_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;     ///< 6   Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///< 7   Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;     ///< 8   Module Memory Bus Width
+  SPD_FINE_TIMEBASE_STRUCT            FineTimebase;             ///< 9   Fine Timebase (FTB) Dividend / Divisor
+  SPD_MEDIUM_TIMEBASE                 MediumTimebase;           ///< 10-11 Medium Timebase (MTB) Dividend
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 12  SDRAM Minimum Cycle Time (tCKmin)
+  UINT8                               Reserved1;                ///< 13  Reserved
+  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 14-15 CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 16  Minimum CAS Latency Time (tAAmin)
+  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 17  Minimum Write Recovery Time (tWRmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 18  Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 19  Minimum Row Active to Row Active Delay Time (tRRDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 20  Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 21  Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 22  Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 23  Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 24-25  Minimum Refresh Recovery Delay Time (tRFCmin)
+  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 26  Minimum Internal Write to Read Command Delay Time (tWTRmin)
+  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 27  Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 28  Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 29  Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_SDRAM_OPTIONAL_FEATURES_STRUCT  SdramOptionalFeatures;    ///< 30  SDRAM Optional Features
+  SPD_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions; ///< 31  SDRAMThermalAndRefreshOptions
+  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;      ///< 32  Module Thermal Sensor
+  SPD_SDRAM_DEVICE_TYPE_STRUCT        SdramDeviceType;          ///< 33  SDRAM Device Type
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 34  Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 35  Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 36  Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 37  Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 38  Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_AB_MTB_STRUCT               tRPab;                    ///< 39  Minimum Row Precharge Delay Time for all banks (tRPab)
+  SPD_TRP_AB_FTB_STRUCT               tRPabFine;                ///< 40  Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 41 - pTRR support with TMAC value
+  UINT8                               Reserved3[59 - 42 + 1];   ///< 42 - 59 Reserved
+} SPD_GENERAL_SECTION;
+
+typedef struct {
+  SPD_UNBUF_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;      ///< 60 Module Nominal Height
+  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 61 Module Maximum Thickness
+  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 62 Reference Raw Card Used
+  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;   ///< 63 Address Mapping from Edge Connector to DRAM
+  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
+} SPD_MODULE_UNBUFFERED;
+
+typedef struct {
+  SPD_RDIMM_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;      ///< 60 Module Nominal Height
+  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 61 Module Maximum Thickness
+  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 62 Reference Raw Card Used
+  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///< 63 DIMM Module Attributes
+  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
+} SPD_MODULE_REGISTERED;
+
+typedef union {
+  SPD_MODULE_UNBUFFERED               Unbuffered;
+  SPD_MODULE_REGISTERED               Registered;
+} SPD_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                          ModulePartNumber[145 - 128 + 1];        ///< 128-145 Module Part Number
+} SPD_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                          ModuleRevisionCode[147 - 146 + 1];      ///< 146-147 Module Revision Code
+} SPD_MODULE_REVISION_CODE;
+
+typedef struct {
+  UINT8                          ManufactureSpecificData[175 - 150 + 1]; ///< 150-175 Manufacturer's Specific Data
+} SPD_MANUFACTURE_SPECIFIC;
+
+///
+/// DDR3 Serial Presence Detect structure
+///
+typedef struct {
+  SPD_GENERAL_SECTION         General;                                ///< 0-59 General Section
+  SPD_MODULE_SPECIFIC         Module;                                 ///< 60-116 Module-Specific Section
+  SPD_UNIQUE_MODULE_ID        ModuleId;                               ///< 117-125 Unique Module ID
+  SPD_CYCLIC_REDUNDANCY_CODE  Crc;                                    ///< 126-127 Cyclical Redundancy Code (CRC)
+  SPD_MODULE_PART_NUMBER      ModulePartNumber;                       ///< 128-145 Module Part Number
+  SPD_MODULE_REVISION_CODE    ModuleRevisionCode;                     ///< 146-147 Module Revision Code
+  SPD_MANUFACTURER_ID_CODE    DramIdCode;                             ///< 148-149 Dram Manufacturer ID Code
+  SPD_MANUFACTURE_SPECIFIC    ManufactureSpecificData;                ///< 150-175 Manufacturer's Specific Data
+  SPD_EXTREME_MEMORY_PROFILE  Xmp;                                    ///< 176-254 Intel(r) Extreme Memory Profile support
+  UINT8                       Reserved;                               ///< 255 Reserved
+} MrcSpdDdr3;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  2; ///< Bits 5:4
+    UINT8  BankGroup                           :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SignalLoading                       :  2; ///< Bits 1:0
+    UINT8                                      :  2; ///< Bits 3:2
+    UINT8  DieCount                            :  3; ///< Bits 6:4
+    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
+    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
+    UINT8                                      :  6; ///< Bits 7:2
+  } Bits;
+  UINT8  Data;
+} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCKmax                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD4_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKmaxFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD4_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0       Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                 Revision;                 ///< 1       SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2       DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3       Module Type
+  SPD4_SDRAM_DENSITY_BANKS_STRUCT     SdramDensityAndBanks;     ///< 4       SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5       SDRAM Addressing
+  SPD4_SDRAM_DEVICE_TYPE_STRUCT       SdramDeviceType;          ///< 6       SDRAM Device Type
+  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 7       pTRR support with TMAC value
+  SPD4_SDRAM_THERMAL_REFRESH_STRUCT   ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
+  UINT8                               Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
+  SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT  ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///< 12      Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
+  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;      ///< 14      Module Thermal Sensor
+  UINT8                               Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
+  SPD4_TIMEBASE_STRUCT                Timebase;                 ///< 17      Timebases
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 18      SDRAM Minimum Cycle Time (tCKmin)
+  SPD4_TCK_MAX_MTB_STRUCT             tCKmax;                   ///< 19      SDRAM Maximum Cycle Time (tCKmax)
+  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///< 20-23   CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 24      Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 25      Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 26      Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 27      Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 28      Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 29      Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 30-31   Minimum Refresh Recovery Delay Time (tRFC1min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 32-33   Minimum Refresh Recovery Delay Time (tRFC2min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 34-35   Minimum Refresh Recovery Delay Time (tRFC4min)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 36      Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 37      Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 38      Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 39      Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+  UINT8                               Reserved2[117 - 40 + 1];  ///< 40-117  Reserved
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 118     Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 119     Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 120     Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 121     Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 123     Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD4_TCK_MAX_FTB_STRUCT             tCKmaxFine;               ///< 124     Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 125     Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD4_BASE_SECTION;
+
+typedef struct {
+  SPD4_UNBUF_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;   ///< 131     Address Mapping from Edge Connector to DRAM
+  UINT8                               Reserved[253 - 132 + 1];  ///< 132-253 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_UNBUFFERED;
+
+typedef struct {
+  SPD4_RDIMM_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///< 131     DIMM Module Attributes
+  UINT8                               Reserved[253 - 132 + 1];  ///< 253-132 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_REGISTERED;
+
+typedef union {
+  SPD4_MODULE_UNBUFFERED              Unbuffered;               ///< 128-255 Unbuffered Memory Module Types
+  SPD4_MODULE_REGISTERED              Registered;               ///< 128-255 Registered Memory Module Types
+} SPD4_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                               ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD4_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                               ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD4_MANUFACTURE_SPECIFIC;
+
+typedef UINT8                         SPD4_MODULE_REVISION_CODE;///< 349     Module Revision Code
+typedef UINT8                         SPD4_DRAM_STEPPING;       ///< 352     Dram Stepping
+
+typedef struct {
+  SPD_UNIQUE_MODULE_ID                ModuleId;                 ///< 320-328 Unique Module ID
+  SPD4_MODULE_PART_NUMBER             ModulePartNumber;         ///< 329-348 Module Part Number
+  SPD4_MODULE_REVISION_CODE           ModuleRevisionCode;       ///< 349     Module Revision Code
+  SPD_MANUFACTURER_ID_CODE            DramIdCode;               ///< 350-351 Dram Manufacturer ID Code
+  SPD4_DRAM_STEPPING                  DramStepping;             ///< 352     Dram Stepping
+  SPD4_MANUFACTURE_SPECIFIC           ManufactureSpecificData;  ///< 353-381 Manufacturer's Specific Data
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 382-383 Cyclical Redundancy Code (CRC)
+} SPD4_MANUFACTURING_DATA;
+
+typedef union {
+  SPD_EXTREME_MEMORY_PROFILE_2_0      Xmp;                      ///< 384-463 Intel(r) Extreme Memory Profile support
+  UINT8                               Reserved0[511 - 384 + 1]; ///< 384-511 Unbuffered Memory Module Types
+} SPD4_END_USER_SECTION;
+
+///
+/// DDR4 Serial Presence Detect structure
+///
+typedef struct {
+  SPD4_BASE_SECTION                   Base;                     ///< 0-127   Base Configuration and DRAM Parameters
+  SPD4_MODULE_SPECIFIC                Module;                   ///< 128-255 Module-Specific Section
+  UINT8                               Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+  SPD4_MANUFACTURING_DATA             ManufactureInfo;          ///< 320-383 Manufacturing Information
+  SPD4_END_USER_SECTION               EndUser;                  ///< 384-511 End User Programmable
+} MrcSpdDdr4;
+
+typedef union {
+  struct {
+    UINT8  Fine                                :  2; ///< Bits 1:0
+    UINT8  Medium                              :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT32 CL3                                 :  1;  ///< Bits 0:0
+    UINT32 CL6                                 :  1;  ///< Bits 1:1
+    UINT32 CL8                                 :  1;  ///< Bits 2:2
+    UINT32 CL9                                 :  1;  ///< Bits 3:3
+    UINT32 CL10                                :  1;  ///< Bits 4:4
+    UINT32 CL11                                :  1;  ///< Bits 5:5
+    UINT32 CL12                                :  1;  ///< Bits 6:6
+    UINT32 CL14                                :  1;  ///< Bits 7:7
+    UINT32 CL16                                :  1;  ///< Bits 8:8
+    UINT32                                     :  1;  ///< Bits 9:9
+    UINT32 CL20                                :  1;  ///< Bits 10:10
+    UINT32 CL22                                :  1;  ///< Bits 11:11
+    UINT32 CL24                                :  1;  ///< Bits 12:12
+    UINT32                                     :  1;  ///< Bits 13:13
+    UINT32 CL28                                :  1;  ///< Bits 14:14
+    UINT32                                     :  1;  ///< Bits 15:15
+    UINT32 CL32                                :  1;  ///< Bits 16:16
+    UINT32                                     :  1;  ///< Bits 17:17
+    UINT32 CL36                                :  1;  ///< Bits 18:18
+    UINT32                                     :  1;  ///< Bits 19:19
+    UINT32 CL40                                :  1;  ///< Bits 20:20
+    UINT32                                     :  11; ///< Bits 31:21
+  } Bits;
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  2; ///< Bits 5:4
+    UINT8  BankGroup                           :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SignalLoading                       :  2; ///< Bits 1:0
+    UINT8  ChannelsPerDie                      :  2; ///< Bits 3:2
+    UINT8  DieCount                            :  3; ///< Bits 6:4
+    UINT8  SdramPackageType                    :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
+    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
+    UINT8  OperationAt1_10                     :  1; ///< Bits 2:2
+    UINT8  EndurantAt1_10                      :  1; ///< Bits 3:3
+    UINT8  OperationAtTBD2V                    :  1; ///< Bits 4:4
+    UINT8  EndurantAtTBD2V                     :  1; ///< Bits 5:5
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCKmax                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ReadLatencyMode                     :  2; ///< Bits 1:0
+    UINT8  WriteLatencySet                     :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKmaxFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT             Description;              ///< 0       Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                       Revision;                 ///< 1       SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT               DramDeviceType;           ///< 2       DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT                    ModuleType;               ///< 3       Module Type
+  SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;     ///< 4       SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT               SdramAddressing;          ///< 5       SDRAM Addressing
+  SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT       SdramPackageType;         ///< 6       SDRAM Package Type
+  SPD_PTRR_SUPPORT_STRUCT                   pTRRsupport;              ///< 7       pTRR support with TMAC value - SDRAM Optional Features
+  SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
+  UINT8                                     Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
+  SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT            ModuleOrganization;       ///< 12      Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT        ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
+  SPD_MODULE_THERMAL_SENSOR_STRUCT          ModuleThermalSensor;      ///< 14      Module Thermal Sensor
+  UINT8                                     Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
+  SPD_LPDDR_TIMEBASE_STRUCT                 Timebase;                 ///< 17      Timebases
+  SPD_TCK_MIN_MTB_STRUCT                    tCKmin;                   ///< 18      SDRAM Minimum Cycle Time (tCKmin)
+  SPD_LPDDR_TCK_MAX_MTB_STRUCT              tCKmax;                   ///< 19      SDRAM Maximum Cycle Time (tCKmax)
+  SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 20-23   CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT                    tAAmin;                   ///< 24      Minimum CAS Latency Time (tAAmin)
+  SPD_LPDDR_RW_LATENCY_OPTION_STRUCT        LatencySetOptions;        ///< 25      Read and Write Latency Set Options
+  SPD_TRCD_MIN_MTB_STRUCT                   tRCDmin;                  ///< 26      Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_AB_MTB_STRUCT                     tRPab;                    ///< 27      Minimum Row Precharge Delay Time (tRPab), all banks
+  SPD_TRP_PB_MTB_STRUCT                     tRPpb;                    ///< 28      Minimum Row Precharge Delay Time (tRPpb), per bank
+  SPD_TRFC_AB_MTB_STRUCT                    tRFCab;                   ///< 29-30   Minimum Refresh Recovery Delay Time (tRFCab), all banks
+  SPD_TRFC_PB_MTB_STRUCT                    tRFCpb;                   ///< 31-32   Minimum Refresh Recovery Delay Time (tRFCpb), per bank
+  UINT8                                     Reserved2[119 - 33 + 1];  ///< 33-119  Reserved
+  SPD_TRP_PB_FTB_STRUCT                     tRPpbFine;                ///< 120     Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
+  SPD_TRP_AB_FTB_STRUCT                     tRPabFine;                ///< 121     Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
+  SPD_TRCD_MIN_FTB_STRUCT                   tRCDminFine;              ///< 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT                    tAAminFine;               ///< 123     Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_LPDDR_TCK_MAX_FTB_STRUCT              tCKmaxFine;               ///< 124     Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
+  SPD_TCK_MIN_FTB_STRUCT                    tCKminFine;               ///< 125     Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_CYCLIC_REDUNDANCY_CODE                Crc;                      ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_BASE_SECTION;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8 Data;
+} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_REFERENCE_RAW_CARD;
+
+typedef struct {
+  SPD_LPDDR_MODULE_NOMINAL_HEIGHT         ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_LPDDR_MODULE_MAXIMUM_THICKNESS      ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_LPDDR_REFERENCE_RAW_CARD            ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  UINT8                                   Reserved[253 - 131 + 1];  ///< 131-253 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE              Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_MODULE_LPDIMM;
+
+typedef union {
+  SPD_LPDDR_MODULE_LPDIMM                 LpDimm;                   ///< 128-255 Unbuffered Memory Module Types
+} SPD_LPDDR_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                                   ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD_LPDDR_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                                   ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD_LPDDR_MANUFACTURE_SPECIFIC;
+
+typedef UINT8                             SPD_LPDDR_MODULE_REVISION_CODE;///< 349     Module Revision Code
+typedef UINT8                             SPD_LPDDR_DRAM_STEPPING;       ///< 352     Dram Stepping
+
+typedef struct {
+  SPD_UNIQUE_MODULE_ID                    ModuleId;                 ///< 320-328 Unique Module ID
+  SPD_LPDDR_MODULE_PART_NUMBER            ModulePartNumber;         ///< 329-348 Module Part Number
+  SPD_LPDDR_MODULE_REVISION_CODE          ModuleRevisionCode;       ///< 349     Module Revision Code
+  SPD_MANUFACTURER_ID_CODE                DramIdCode;               ///< 350-351 Dram Manufacturer ID Code
+  SPD_LPDDR_DRAM_STEPPING                 DramStepping;             ///< 352     Dram Stepping
+  SPD_LPDDR_MANUFACTURE_SPECIFIC          ManufactureSpecificData;  ///< 353-381 Manufacturer's Specific Data
+  UINT8                                   Reserved[383 - 382 + 1];  ///< 382-383 Reserved
+} SPD_LPDDR_MANUFACTURING_DATA;
+
+typedef union {
+  UINT8                                   Reserved0[511 - 384 + 1]; ///< 384-511 End User Programmable
+} SPD_LPDDR_END_USER_SECTION;
+
+typedef struct {
+  SPD_LPDDR_BASE_SECTION                  Base;                     ///< 0-127   Base Configuration and DRAM Parameters
+  SPD_LPDDR_MODULE_SPECIFIC               Module;                   ///< 128-255 Module-Specific Section
+  UINT8                                   Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+  SPD_LPDDR_MANUFACTURING_DATA            ManufactureInfo;          ///< 320-383 Manufacturing Information
+  SPD_LPDDR_END_USER_SECTION              EndUser;                  ///< 384-511 End User Programmable
+} MrcSpdLpDdr;
+
+typedef union {
+  MrcSpdDdr3  Ddr3;
+  MrcSpdDdr4  Ddr4;
+  MrcSpdLpDdr Lpddr;
+} MrcSpd;
+
+#ifndef MAX_SPD_SAVE
+#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
+                      sizeof (SPD_MANUFACTURING_LOCATION) + \
+                      sizeof (SPD_MANUFACTURING_DATE) + \
+                      sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
+                      sizeof (SPD4_MODULE_PART_NUMBER))
+#endif
+
+#pragma pack (pop)
+#endif // _MrcSpdData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
new file mode 100644
index 0000000000..b267315f36
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
@@ -0,0 +1,237 @@
+/** @file
+  Include the the general MRC types
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MRC_TYPES_H
+#define _MRC_TYPES_H
+
+#ifdef MRC_MINIBIOS_BUILD
+#include "MrcMiniBiosEfiDefs.h"
+#else
+#include <Base.h>
+#endif // MRC_MINIBIOS_BUILD
+
+//
+// Data Types
+//
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+typedef union {
+  struct {
+    INT32  Low;
+    INT32  High;
+  } Data32;
+  INT64 Data;
+} INT64_STRUCT;
+
+typedef union {
+  VOID    *Ptr;
+  UINTN   DataN;
+  UINT64  Data64;
+} POINTER_STRUCT;
+
+#define UNSUPPORT 0
+#define SUPPORT   1
+
+typedef enum {
+  mrcSuccess,
+  mrcFail,
+  mrcWrongInputParameter,
+  mrcCasError,
+  mrcTimingError,
+  mrcSenseAmpErr,
+  mrcReadMPRErr,
+  mrcReadLevelingError,
+  mrcWriteLevelingError,
+  mrcDataTimeCentering1DErr,
+  mrcWriteVoltage2DError,
+  mrcReadVoltage2DError,
+  mrcMiscTrainingError,
+  mrcWrError,
+  mrcDimmNotSupport,
+  mrcChannelNotSupport,
+  mrcPiSettingError,
+  mrcDqsPiSettingError,
+  mrcDeviceBusy,
+  mrcFrequencyChange,
+  mrcReutSequenceError,
+  mrcCrcError,
+  mrcFrequencyError,
+  mrcDimmNotExist,
+  mrcColdBootRequired,
+  mrcRoundTripLatencyError,
+  mrcMixedDimmSystem,
+  mrcAliasDetected,
+  mrcRetrain,
+  mrcRtpError,
+  mrcUnsupportedTechnology,
+  mrcMappingError,
+  mrcSocketNotSupported,
+  mrcControllerNotSupported,
+  mrcRankNotSupported,
+  mrcTurnAroundTripError
+} MrcStatus;
+
+//
+// general  macros
+//
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(x)  (((x) < 0) ? (-(x)) : (x))
+#endif
+
+//
+// Make sure x is inside the range of [a..b]
+//
+#ifndef RANGE
+#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
+#endif
+
+#ifndef DIVIDECEIL
+#define DIVIDECEIL(a, b)   (((a) + (b) - 1) / (b))
+#endif
+
+#ifndef DIVIDEROUND
+#define DIVIDEROUND(a, b)  (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2) / (b))
+#endif
+
+#ifndef DIVIDEFLOOR
+#define DIVIDEFLOOR(a, b)  ((a) / (b))
+#endif
+
+//
+// Number of elements in a 1D array
+//
+#ifndef ARRAY_COUNT
+#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
+#endif
+
+//
+//  use for ignore parames
+//
+// #define MRC_IGNORE_PARAM(x) ((x) = (x))
+//
+#if _MSC_EXTENSIONS
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning (disable : 4214)
+//
+// Unreferenced formal parameter - We are object oriented, so we pass parameters even
+//  if we don't need them.
+//
+#pragma warning (disable : 4100)
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
+//
+#pragma warning(disable : 4127)
+//
+// The given function was selected for inline expansion, but the compiler did not perform the inlining.
+//
+#pragma warning(disable : 4710)
+
+#endif // _MSC_EXTENSIONS
+#define MRC_BIT0          0x00000001
+#define MRC_BIT1          0x00000002
+#define MRC_BIT2          0x00000004
+#define MRC_BIT3          0x00000008
+#define MRC_BIT4          0x00000010
+#define MRC_BIT5          0x00000020
+#define MRC_BIT6          0x00000040
+#define MRC_BIT7          0x00000080
+#define MRC_BIT8          0x00000100
+#define MRC_BIT9          0x00000200
+#define MRC_BIT10         0x00000400
+#define MRC_BIT11         0x00000800
+#define MRC_BIT12         0x00001000
+#define MRC_BIT13         0x00002000
+#define MRC_BIT14         0x00004000
+#define MRC_BIT15         0x00008000
+#define MRC_BIT16         0x00010000
+#define MRC_BIT17         0x00020000
+#define MRC_BIT18         0x00040000
+#define MRC_BIT19         0x00080000
+#define MRC_BIT20         0x00100000
+#define MRC_BIT21         0x00200000
+#define MRC_BIT22         0x00400000
+#define MRC_BIT23         0x00800000
+#define MRC_BIT24         0x01000000
+#define MRC_BIT25         0x02000000
+#define MRC_BIT26         0x04000000
+#define MRC_BIT27         0x08000000
+#define MRC_BIT28         0x10000000
+#define MRC_BIT29         0x20000000
+#define MRC_BIT30         0x40000000
+#define MRC_BIT31         0x80000000
+#define MRC_BIT32        0x100000000ULL
+#define MRC_BIT33        0x200000000ULL
+#define MRC_BIT34        0x400000000ULL
+#define MRC_BIT35        0x800000000ULL
+#define MRC_BIT36       0x1000000000ULL
+#define MRC_BIT37       0x2000000000ULL
+#define MRC_BIT38       0x4000000000ULL
+#define MRC_BIT39       0x8000000000ULL
+#define MRC_BIT40      0x10000000000ULL
+#define MRC_BIT41      0x20000000000ULL
+#define MRC_BIT42      0x40000000000ULL
+#define MRC_BIT43      0x80000000000ULL
+#define MRC_BIT44     0x100000000000ULL
+#define MRC_BIT45     0x200000000000ULL
+#define MRC_BIT46     0x400000000000ULL
+#define MRC_BIT47     0x800000000000ULL
+#define MRC_BIT48    0x1000000000000ULL
+#define MRC_BIT49    0x2000000000000ULL
+#define MRC_BIT50    0x4000000000000ULL
+#define MRC_BIT51    0x8000000000000ULL
+#define MRC_BIT52   0x10000000000000ULL
+#define MRC_BIT53   0x20000000000000ULL
+#define MRC_BIT54   0x40000000000000ULL
+#define MRC_BIT55   0x80000000000000ULL
+#define MRC_BIT56  0x100000000000000ULL
+#define MRC_BIT57  0x200000000000000ULL
+#define MRC_BIT58  0x400000000000000ULL
+#define MRC_BIT59  0x800000000000000ULL
+#define MRC_BIT60 0x1000000000000000ULL
+#define MRC_BIT61 0x2000000000000000ULL
+#define MRC_BIT62 0x4000000000000000ULL
+#define MRC_BIT63 0x8000000000000000ULL
+
+#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
+
+#ifndef ASM
+#define ASM __asm
+#endif
+
+///
+/// Type Max/Min Values
+///
+#define MRC_INT32_MAX   (0x7FFFFFFF)
+#define MRC_INT32_MIN   (0x80000000)
+#define MRC_INT64_MAX   (0x7FFFFFFFFFFFFFFFLL)
+#define MRC_INT64_MIN   (0x8000000000000000LL)
+#define MRC_UINT32_MAX  (0xFFFFFFFF)
+#define MRC_UINT64_MAX  (0xFFFFFFFFFFFFFFFFULL)
+#define MRC_UINT_MIN    (0x0)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
new file mode 100644
index 0000000000..d444e937d6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
@@ -0,0 +1,15 @@
+/** @file
+  This file includes all the data structures that the MRC considers "global data".
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _UNIFIED_MrcInterface_h_
+#define _UNIFIED_MrcInterface_h_
+
+#include "Coffeelake/MrcInterface.h"
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
new file mode 100644
index 0000000000..82d798b783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
@@ -0,0 +1,50 @@
+/** @file
+  Header file for initialization of GT PowerManagement
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_INIT_H_
+#define _GRAPHICS_INIT_H_
+
+#include <Library/DxeServicesTableLib.h>
+#include <Guid/DxeServices.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Library/PciSegmentLib.h>
+#include <SaAccess.h>
+#include <Protocol/SaPolicy.h>
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <PchAccess.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
new file mode 100644
index 0000000000..0e95db3d02
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
@@ -0,0 +1,193 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IGD_OPREGION_INIT_H_
+#define _IGD_OPREGION_INIT_H_
+
+///
+/// Statements that include other header files.
+///
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <SaAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <CpuRegs.h>
+#include <SaInit.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <SiConfigHob.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/SaPolicy.h>
+
+
+#include <Private/Protocol/SaNvsArea.h>
+
+///
+/// Driver Produced Protocol Prototypes
+///
+#include <Protocol/IgdOpRegion.h>
+
+///
+///
+/// OpRegion (Miscellaneous) defines.
+///
+/// OpRegion Header defines.
+///
+typedef UINT16  STRING_REF;
+#define HEADER_SIGNATURE            "IntelGraphicsMem"
+#define HEADER_SIZE                 0x2000
+#define HEADER_OPREGION_VER         0x0200
+#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 BLC_ENABLE            BIT1
+#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
+///
+#pragma pack(1)
+typedef struct {
+  UINT16  Signature;  /// 0xAA55
+  UINT8   Size512;
+  UINT8   Reserved[21];
+  UINT16  PcirOffset;
+  UINT16  VbtOffset;
+} INTEL_VBIOS_OPTION_ROM_HEADER;
+#pragma pack()
+
+#pragma pack(1)
+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;
+#pragma pack()
+
+#pragma pack(1)
+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()
+///
+/// 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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
new file mode 100644
index 0000000000..34a2809f80
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
@@ -0,0 +1,91 @@
+/** @file
+  Header file for PciExpress Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+
+#include <Library/HobLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/Msr.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Private/SaConfigHob.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/Protocol/SaNvsArea.h>
+
+#define GEN1      1
+#define GEN2      2
+
+///
+/// Function prototypes
+///
+/**
+  PCI Express Dxe Initialization.
+  Run before PCI Bus Init, where assignment of Bus, Memory,
+    and I/O Resources are assigned.
+
+  @param[in] SaPolicy    -     SA DXE Policy protocol
+
+  @retval EFI_SUCCESS        - Pci Express successfully started and ready to be used
+  @exception EFI_UNSUPPORTED - Pci Express can't be initialized
+**/
+EFI_STATUS
+PciExpressInit (
+  IN SA_POLICY_PROTOCOL *SaPolicy
+  );
+
+/**
+  Find the Offset to a given 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 fo
+
+  @retval 0       - CAPID not found
+  @retval Other   - CAPID found, Offset of desired CAPID
+**/
+UINT32
+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
+
+  @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
+**/
+UINT32
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
new file mode 100644
index 0000000000..73af27e9d7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
@@ -0,0 +1,23 @@
+/** @file
+  This is header file for SA PCIE Root Complex initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+  VOID
+  );
+
+/**
+  This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Save/restore has done
+  @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+  VOID
+  );
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
new file mode 100644
index 0000000000..d7e2423ffd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for SA Common Initialization Driver.
+
+  Copyright (c) 2019 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 <CpuRegs.h>
+#include <SaAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/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
+  );
+
+/**
+  Common function locks the PAM register as part of the SA Security requirements.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+SaPamLock (
+  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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
new file mode 100644
index 0000000000..1991fd82c4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
@@ -0,0 +1,139 @@
+/** @file
+  Header file for SA Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
+#define _SA_INITIALIZATION_DXE_DRIVER_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include "VTd.h"
+#include "PcieComplex.h"
+#include "IgdOpRegionInit.h"
+#include <Private/Library/LegacyRegion.h>
+#include "GraphicsInit.h"
+#include "PciExpressInit.h"
+#include "SwitchableGraphicsInit.h"
+#include <Library/CpuPlatformLib.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/SaPolicy.h>
+
+extern EFI_GUID gSaAcpiTableStorageGuid;
+extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
+extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
+
+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 SA 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.
+
+  @retval EFI_SUCCESS   - Always.
+
+**/
+VOID
+EFIAPI
+SaPciEnumCompleteCallback (
+  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
+  );
+
+/**
+  This function locks the PAM register as part of the SA Security requirements.
+
+  @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 EFI_SUCCESS   - Always.
+**/
+VOID
+EFIAPI
+SaPamLockDxe (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
new file mode 100644
index 0000000000..2b1b4c5880
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
@@ -0,0 +1,17 @@
+/** @file
+  Header file for the SwitchableGraphics Dxe driver.
+  This driver loads SwitchableGraphics ACPI tables.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
+#define _SWITCHABLE_GRAPHICS_DXE_H_
+
+
+#include <Protocol/FirmwareVolume2.h>
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
new file mode 100644
index 0000000000..c4bc47f7fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
@@ -0,0 +1,53 @@
+/** @file
+  This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VT_D_H_
+#define _VT_D_H_
+
+///
+/// Include files
+///
+#include <DmaRemappingTable.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Uefi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/PchConfigHob.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <IndustryStandard/Pci22.h>
+
+
+#define VTD_ECAP_REG  0x10
+#define IR            BIT3
+
+/**
+  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
+  );
+
+/**
+  PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..02c74c0672
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
@@ -0,0 +1,162 @@
+/** @file
+  Header file for SMM Access Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H_
+#define _SMM_ACCESS_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <Guid/SmramMemoryReserve.h>
+#include <Protocol/SmmAccess2.h>
+#include <IndustryStandard/Pci22.h>
+#include <SaAccess.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a')
+
+///
+/// Private data
+///
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle;
+  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
+
+  ///
+  /// Local Data for SMM Access interface goes here
+  ///
+  UINTN                           NumberRegions;
+  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+  CR (a, \
+      SMM_ACCESS_PRIVATE_DATA, \
+      SmmAccess, \
+      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+      )
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+/**
+  <b>SMM Access Driver Entry Point</b>
+  This driver installs an SMM Access Protocol
+  - <b>Introduction</b> \n
+    This module publishes the SMM access protocol.  The protocol is used by the SMM Base driver to access the SMRAM region when the processor is not in SMM.
+    The SMM Base driver uses the services provided by the SMM access protocol to open SMRAM during post and copy the SMM handler.
+    SMM access protocol is also used to close the SMRAM region once the copying is done.
+    Finally, the SMM access protocol provides services to "Lock" the SMRAM region.
+    Please refer the SMM Protocols section in the attached SMM CIS Specification version 0.9 for further details.
+    This driver is required if SMM is supported. Proper configuration of SMM registers is recommended even if SMM is not supported.
+
+  - @result
+    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System Management Mode Core Interface Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>Porting Recommendations</b> \n
+    No modification of this module is recommended.  Any modification should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL protocol definition.
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS     - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED - Protocol was not installed
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by
+                            chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  );
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                          one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                            buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                            region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                   *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
new file mode 100644
index 0000000000..5daa2367e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
@@ -0,0 +1,157 @@
+/** @file
+  DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GraphicsInit.h"
+#include "SaInit.h"
+#include <Protocol/LegacyBios.h>
+#include <Protocol/GopComponentName2.h>
+#include <SiConfigHob.h>
+
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64                        mGttMmAdr;
+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_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  EFI_STATUS                Status;
+  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
+  EFI_PEI_HOB_POINTERS      HobPtr;
+  SI_CONFIG_HOB_DATA        *SiConfigHobData;
+
+  ///
+  /// Get the platform setup policy.
+  ///
+  DriverVersion = NULL;
+  LegacyBios = NULL;
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  if (SiConfigHobData->CsmFlag == 1) {
+    Status = gBS->LocateProtocol (
+                    &gEfiLegacyBiosProtocolGuid,
+                    NULL,
+                    (VOID **) &LegacyBios
+                    );
+  }
+
+  if (LegacyBios == NULL) {
+    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;
+
+  mGttMmAdr               = 0;
+  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);
+
+  ///
+  /// Update IGD SA Global NVS
+  ///
+  DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
+
+  mSaNvsAreaProtocol.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) {
+    mSaNvsAreaProtocol.Area->IgdState = 1;
+  } else {
+    mSaNvsAreaProtocol.Area->IgdState = 0;
+  }
+
+  mSaNvsAreaProtocol.Area->BrightnessPercentage         = 100;
+  mSaNvsAreaProtocol.Area->IgdBootType                  = GraphicsDxeConfig->IgdBootType;
+  mSaNvsAreaProtocol.Area->IgdPanelType                 = GraphicsDxeConfig->IgdPanelType;
+  mSaNvsAreaProtocol.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.
+  ///
+  mSaNvsAreaProtocol.Area->IgdDvmtMemSize               = GraphicsDxeConfig->IgdDvmtMemSize;
+  mSaNvsAreaProtocol.Area->IgdFunc1Enable               = 0;
+  mSaNvsAreaProtocol.Area->IgdHpllVco                   = MmioRead8 (mMchBarBase.Data + 0xC0F) & 0x07;
+  mSaNvsAreaProtocol.Area->IgdSciSmiMode                = 0;
+  mSaNvsAreaProtocol.Area->GfxTurboIMON                 = GraphicsDxeConfig->GfxTurboIMON;
+
+  mSaNvsAreaProtocol.Area->EdpValid                     = 0;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
new file mode 100644
index 0000000000..6ec0691074
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
@@ -0,0 +1,570 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "IgdOpRegionInit.h"
+
+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;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &mSaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &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_PCIR_STRUCTURE    *PcirBlockPtr;
+  UINT32                        PcirBlockAddress;
+  UINT16                        PciVenderId;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
+  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
+  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;
+  EFI_STATUS                    Status;
+  VBIOS_VBT_STRUCTURE           *VbtFileBuffer;
+  UINTN                         Index;
+  UINT8                         LegacyVbtFound;
+  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
+  EFI_PEI_HOB_POINTERS          HobPtr;
+  SI_CONFIG_HOB_DATA            *SiConfigHobData;
+
+  VbtFileBuffer = NULL;
+  LegacyVbtFound = 1;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &mSaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  LegacyBios = NULL;
+  VBiosPtr = NULL;
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+  if (SiConfigHobData->CsmFlag == 1) {
+    Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+
+    if (LegacyBios) {
+      VBiosPtr      = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN) (VBIOS_LOCATION_PRIMARY);
+      PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
+      PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN) (PcirBlockAddress);
+      PciVenderId   = PcirBlockPtr->VendorId;
+      ///
+      /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
+      /// the integrated Intel video BIOS (must be uncompressed).
+      ///
+      if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+        GetIntegratedIntelVBiosPtr (&VBiosPtr);
+        if (VBiosPtr != NULL) {
+          ///
+          /// Video BIOS found.
+          ///
+          PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->PcirOffset);
+          PciVenderId   = PcirBlockPtr->VendorId;
+
+          if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+            ///
+            /// Intel video BIOS not found.
+            ///
+            VBiosVbtPtr = NULL;
+            LegacyVbtFound = 0;
+          }
+        }
+      }
+    }
+  }
+  if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
+    ///
+    /// No Video BIOS found, 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"));
+      for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
+      }
+      Index = (Index+1)*2;
+      CopyMem (mIgdOpRegion.OpRegion->Header.DVER, GraphicsDxeConfig->GopVersion, Index);
+      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;
+
+  ///
+  /// 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);
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
+  /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
+  /// area structure.
+  ///
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
+  ASSERT_EFI_ERROR (Status);
+
+  SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE), 0);
+  SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN) (mIgdOpRegion.OpRegion);
+
+  ///
+  /// If IGD is disabled return
+  ///
+  IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 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, 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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
new file mode 100644
index 0000000000..bbdf0d0fab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
@@ -0,0 +1,171 @@
+/** @file
+  This driver does SA PCI Express ACPI table initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL   mSaNvsAreaProtocol;
+extern SA_CONFIG_HOB                    *mSaConfigHob;
+
+/**
+  PCI Express Dxe Initialization.
+  Run before PCI Bus Init, where assignment of Bus, Memory,
+    and I/O Resources are assigned.
+
+  @param[in] SaPolicy     -     SA DXE Policy protocol
+
+  @retval EFI_SUCCESS     - Pci Express successfully started and ready to be used
+**/
+EFI_STATUS
+PciExpressInit (
+  IN SA_POLICY_PROTOCOL *SaPolicy
+  )
+{
+  EFI_STATUS                                    Status;
+  PCIE_DXE_CONFIG                               *PcieDxeConfig;
+  MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
+  mSaNvsAreaProtocol.Area->PackageCstateLimit  = (UINT8) Msr.Bits.Limit;
+
+  mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable  = 0;
+
+  if (mSaConfigHob != NULL) {
+    mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[0];
+    mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[1];
+    mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[2];
+    if (SA_PEG_MAX_FUN > 3) {
+      mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[3];
+    }
+  }
+  ///
+  /// LTR/OBFF
+  ///
+  mSaNvsAreaProtocol.Area->Peg0LtrEnable                = PcieDxeConfig->PegPwrOpt[0].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg0ObffEnable               = PcieDxeConfig->PegPwrOpt[0].ObffEnable;
+  mSaNvsAreaProtocol.Area->Peg1LtrEnable                = PcieDxeConfig->PegPwrOpt[1].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg1ObffEnable               = PcieDxeConfig->PegPwrOpt[1].ObffEnable;
+  mSaNvsAreaProtocol.Area->Peg2LtrEnable                = PcieDxeConfig->PegPwrOpt[2].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg2ObffEnable               = PcieDxeConfig->PegPwrOpt[2].ObffEnable;
+  mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency        = LTR_MAX_SNOOP_LATENCY_VALUE;
+  mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency      = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+**/
+UINT32
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  )
+{
+  UINT64 DeviceBaseAddress;
+  UINT8  CapHeader;
+
+  ///
+  /// Always start at Offset 0x34
+  ///
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  CapHeader         = PciSegmentRead8 (DeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+  if (CapHeader == 0xFF) {
+    return 0;
+  }
+
+  while (CapHeader != 0) {
+    ///
+    /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
+    ///
+    CapHeader &= ~(BIT1 + BIT0);
+    ///
+    /// Search for desired CapID
+    ///
+    if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
+      return CapHeader;
+    }
+
+    CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
+  }
+
+  return 0;
+}
+
+/**
+  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
+**/
+UINT32
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+
+  ///
+  /// Start to search at Offset 0x100
+  /// Get Capability Header
+  ///
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  CapHeaderId     = 0;
+  CapHeaderOffset = 0x100;
+
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    ///
+    /// Search for desired CapID
+    ///
+    CapHeaderId = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+
+    CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 2) >> 4);
+  }
+
+  return 0;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
new file mode 100644
index 0000000000..1dc37334ae
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
@@ -0,0 +1,171 @@
+/** @file
+  This file will perform SA PCIE Root Complex initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+#include <Private/Library/SaPcieLib.h>
+#include "PcieComplex.h"
+#include <Private/Protocol/SaIotrapSmi.h>
+#include "SaInit.h"
+
+///
+/// Global variables
+///
+UINT16                                 mSaIotrapSmiAddress;
+extern SA_CONFIG_HOB                   *mSaConfigHob;
+
+///
+/// Functions
+///
+/**
+    This function gets registered as a callback to perform all SA late initialization
+
+    @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
+SaLateInitSmiCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                 Status;
+  SA_IOTRAP_SMI_PROTOCOL     *SaIotrapSmiProtocol;
+
+  if (mSaIotrapSmiAddress == 0) {
+    //
+    // Use global variable instead of protocol data since it maybe tampered in unsecure environment
+    // Get IOTrap address when first time this routine calling (gEfiPciEnumerationCompleteProtocolGuid callback)
+    //
+    SaIotrapSmiProtocol = NULL;
+    Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **) &SaIotrapSmiProtocol);
+    ASSERT_EFI_ERROR (Status);
+    if (SaIotrapSmiProtocol != NULL) {
+      mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
+    }
+  }
+
+  ASSERT (mSaIotrapSmiAddress != 0);
+  if (mSaIotrapSmiAddress != 0) {
+    //
+    // Generate IOTRAP SMI immediately
+    //
+    DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n", mSaIotrapSmiAddress));
+    IoWrite8 (mSaIotrapSmiAddress, 0);
+  }
+  if (Event != NULL) {
+    gBS->CloseEvent (Event);
+  }
+  return;
+}
+
+/**
+  This function performs Peg initialization before EndOfDxe.
+  @note This function will be executed as gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA DXE/SMM drivers have been dispatched.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+  VOID
+  )
+{
+  EFI_EVENT                       ReadyToBoot;
+  EFI_STATUS                      Status;
+  BOOLEAN                         AspmHasBeenHandled;
+
+  DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
+  AspmHasBeenHandled = FALSE;
+  ///
+  /// SMM mode ASPM handling
+  /// Check if supported and enabled
+  ///
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+    ///
+    /// Do the Phase 1 SMI callback
+    /// This will enumerate PCIe downstream devices
+    ///
+    SaLateInitSmiCallback (NULL, NULL);
+
+    if (mSaIotrapSmiAddress != 0) {
+      ///
+      /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
+      /// This will handle PEG ASPM programming after OROM execution
+      /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
+      ///       to initialize rest of PCIe settings prior to OPROM
+      ///
+      Status = EfiCreateEventReadyToBootEx (
+                 TPL_NOTIFY,
+                 (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
+                 NULL,
+                 &ReadyToBoot
+                 );
+      ASSERT_EFI_ERROR (Status);
+      AspmHasBeenHandled = TRUE;
+    }
+  }
+
+  ///
+  /// DXE mode ASPM handling
+  /// Check if SMM mode already taken care all things
+  /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
+  ///
+  if (AspmHasBeenHandled == FALSE) {
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Save/restore has done
+  @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+  VOID
+  )
+{
+  BOOLEAN                         SaveRestoreHasBeenHandled;
+  UINT8                           SmiData;
+
+  SaveRestoreHasBeenHandled = FALSE;
+
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+    ///
+    /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and security lock
+    ///
+    SaLateInitSmiCallback (NULL, NULL);
+
+    if (mSaIotrapSmiAddress != 0) {
+      ///
+      /// Store IOTRAP SMI address into Boot Script save table
+      /// This is required to trigger this IOTRAP during S3 resume to restore all settings
+      ///
+      SmiData = 0;
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) mSaIotrapSmiAddress,
+        1,
+        &SmiData
+        );
+      SaveRestoreHasBeenHandled = TRUE;
+    }
+  }
+
+  ///
+  /// Check if SMM mode already taken care this task
+  ///
+  if (SaveRestoreHasBeenHandled == TRUE) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
new file mode 100644
index 0000000000..d5a63785b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
@@ -0,0 +1,496 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Private/Protocol/SaNvsArea.h>
+#include <Library/PchInfoLib.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;
+
+/**
+  Initialize System Agent SSDT ACPI tables
+
+  @retval EFI_SUCCESS    ACPI tables are initialized successfully
+  @retval EFI_NOT_FOUND  ACPI tables not found
+**/
+EFI_STATUS
+InitializeSaSsdtAcpiTables (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         NumberOfHandles;
+  EFI_FV_FILETYPE               FileType;
+  UINT32                        FvStatus;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINTN                         Size;
+  UINTN                         i;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  INTN                          Instance;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINTN                         AcpiTableKey;
+  UINT8                         *CurrPtr;
+  UINT8                         *EndPtr;
+  UINT32                        *Signature;
+  EFI_ACPI_DESCRIPTION_HEADER   *SaAcpiTable;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+
+  FwVol       = NULL;
+  SaAcpiTable = NULL;
+
+  ///
+  /// Locate ACPI Table protocol
+  ///
+  DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// 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,
+                      &gSaSsdtAcpiTableStorageGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (Status == EFI_SUCCESS) {
+      break;
+    }
+  }
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol != NULL);
+  if (FwVol == NULL) {
+    DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
+    return EFI_NOT_FOUND;
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  /// Read tables from the storage file.
+  ///
+  Instance      = 0;
+  CurrentTable  = NULL;
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gSaSsdtAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// Check the table ID to modify the table
+      ///
+      if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
+        SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+        ///
+        /// Locate the SSDT package
+        ///
+        CurrPtr = (UINT8 *) SaAcpiTable;
+        EndPtr  = CurrPtr + SaAcpiTable->Length;
+
+        for (; CurrPtr <= EndPtr; CurrPtr++) {
+          Signature = (UINT32 *) (CurrPtr + 3);
+          if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
+            ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) == 0xFFFF0000);
+            ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55);
+            ///
+            /// SA Global NVS Area address
+            ///
+            *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN) mSaNvsAreaProtocol.Area;
+            ///
+            /// SA Global NVS Area size
+            ///
+            *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) =
+              sizeof (SYSTEM_AGENT_NVS_AREA);
+
+            AcpiTableKey = 0;
+            Status = AcpiTable->InstallAcpiTable (
+                                  AcpiTable,
+                                  SaAcpiTable,
+                                  SaAcpiTable->Length,
+                                  &AcpiTableKey
+                                  );
+            ASSERT_EFI_ERROR (Status);
+            return EFI_SUCCESS;
+          }
+        }
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  return Status;
+
+}
+
+/**
+  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 SwitchableGraphics 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, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 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, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 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;
+  CPU_FAMILY                CpuFamilyId;
+  EFI_EVENT                 EndOfDxeEvent;
+
+  CpuFamilyId = GetCpuFamily();
+  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 (PcdPciExpressBaseAddress));
+  mSaNvsAreaProtocol.Area->CpuIdInfo            = CpuidRegs.RegEax;
+  if (mSaConfigHob != NULL) {
+    mSaNvsAreaProtocol.Area->IpuAcpiMode = mSaConfigHob->IpuAcpiMode;
+  }
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaNvsAreaProtocolGuid,
+                  &mSaNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// PciExpress Dxe Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
+  PciExpressInit (mSaPolicy);
+
+  ///
+  /// GtPostInit Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
+
+  GraphicsInit (ImageHandle, mSaPolicy);
+
+  /// 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 = InitializeSaSsdtAcpiTables ();
+
+  ///
+  /// Install PEG SSDT table only if PEG port is present
+  ///
+  if (IsPchLinkDmi (CpuFamilyId)) {
+    if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
+      Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid, SIGNATURE_64 ('P','e','g','S','s','d','t',0));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
new file mode 100644
index 0000000000..40bb107ad0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
@@ -0,0 +1,179 @@
+/** @file
+  This is the Common driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInit.h"
+#include <Library/PciSegmentLib.h>
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+//
+// Declare I/O Ports used to perform PCI Confguration Cycles
+//
+#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8
+#define PCI_CONFIGURATION_DATA_PORT     0xCFC
+
+/**
+  Convert a PCI Library address to PCI CF8 formatted address.
+
+  Declare macro to convert PCI Library address to PCI CF8 formatted address.
+  Bit fields of PCI Library and CF8 formatted address is as follows:
+  PCI Library formatted address    CF8 Formatted Address
+ =============================    ======================
+    Bits 00..11  Register           Bits 00..07  Register
+    Bits 12..14  Function           Bits 08..10  Function
+    Bits 15..19  Device             Bits 11..15  Device
+    Bits 20..27  Bus                Bits 16..23  Bus
+    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)
+                                    Bits 31..31  Must be 1
+
+  @param  A The address to convert.
+
+  @retval The coverted address.
+
+**/
+#define PCI_TO_CF8_ADDRESS(A) \
+  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
+
+///
+/// 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 SaPcieInitPolicy().
+*/
+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
+  )
+{
+  ///
+  /// Get SaConfigHob HOB
+  ///
+  mSaConfigHob              = NULL;
+  mSaConfigHob              = (SA_CONFIG_HOB *) GetFirstGuidHob (&gSaConfigHobGuid);
+  if (mSaConfigHob != NULL) {
+    mSkipPamLock = mSaConfigHob->SkipPamLock;
+  }
+
+  return;
+}
+
+
+
+/**
+  Common function locks the PAM register as part of the SA Security requirements.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+
+VOID
+SaPamLock (
+  VOID
+  )
+{
+  UINT64 BaseAddress;
+  UINT32 Data32Or;
+
+  if (mSkipPamLock == FALSE) {
+    //
+    // Lock PAM by PAM Lock Bit
+    //
+    BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
+    Data32Or    = BIT0;
+    DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
+    PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
+  }
+}
+
+/**
+  This function does SA security lock
+**/
+VOID
+SaSecurityLock (
+  VOID
+  )
+{
+  UINT8           Index;
+  UINT32          RegOffset;
+  UINT32          Data32Or;
+  UINT32          Data32;
+  UINT8           Data8;
+
+  ///
+  /// 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++) {
+    RegOffset   = mSaSecurityRegisters[Index].Offset;
+    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);
+      Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+      Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint32,
+        (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
+        1,
+        &Data32
+        );
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) (PCI_CONFIGURATION_DATA_PORT),
+        1,
+        &Data8
+        );
+    }
+  }
+}
+
+/**
+  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 (PcdPciExpressBaseAddress);
+    }
+  }
+  SaSecurityLock ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
new file mode 100644
index 0000000000..d646e60618
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
@@ -0,0 +1,122 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <MemInfoHob.h>
+
+///
+/// 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;
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
+
+  SaInitEntryPoint ();
+
+  Status = SaAcpiInit (ImageHandle);
+
+  ///
+  /// Create PCI Enumeration Completed callback for SA
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    SaPciEnumCompleteCallback,
+    NULL,
+    &Registration
+    );
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform SA 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
+SaPciEnumCompleteCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+  VOID                *ProtocolPointer;
+
+  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback 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);
+
+  Status = PegInitBeforeEndOfDxe ();
+  if (EFI_SUCCESS != Status) {
+    DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error, Status = %r \n", Status));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  SaSaveRestore ();
+  SaSecurityInit ();
+  UpdateDmarPciEnumCompleteCallback ();
+
+  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
+  return;
+}
+
+/**
+  This function locks the PAM register as part of the SA Security requirements.
+
+  @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
+SaPamLockDxe (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
+
+  SaPamLock ();
+
+  DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
new file mode 100644
index 0000000000..acbf6b7aab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
@@ -0,0 +1,717 @@
+/** @file
+  This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include "VTd.h"
+#include <CpuRegs.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <PchInfoHob.h>
+#include <PchAccess.h>
+
+
+extern SA_CONFIG_HOB                                          *mSaConfigHob;
+
+/**
+  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}, {0x1400, 0x80}, {0x1401, 0x80}, {0x1607, 0x8F}};
+
+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 < sizeof (mDevEnMap) / 4; 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 (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 (PcdIoApicBaseAddress);
+  ///
+  /// Get current IO APIC ID
+  ///
+  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
+  IoApicId = MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_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) {
+      NeedRemove = FALSE;
+    }
+    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;
+  UINTN               MchBar;
+  UINT16              IgdMode;
+  UINT16              GttMode;
+  UINT32              IgdMemSize;
+  UINT32              GttMemSize;
+  EFI_STATUS          Status;
+  MISC_DXE_CONFIG     *MiscDxeConfig;
+
+  IgdMemSize  = 0;
+  GttMemSize  = 0;
+  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
+  ///
+  if (mInterruptRemappingSupport) {
+    DmarTable->DmarHeader.Flags |= BIT0;
+  }
+
+  if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
+    DmarTable->DmarHeader.Flags |= BIT1;
+  } else {
+    DmarTable->DmarHeader.Flags &= 0xFD;
+  }
+
+  ///
+  /// 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);
+  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+  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);
+  }
+
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   = (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) - IgdMemSize - GttMemSize;
+  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));
+
+  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress   = MiscDxeConfig->RmrrUsbBaseAddress[0];
+  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress  = MiscDxeConfig->RmrrUsbBaseAddress[1];
+
+  ///
+  /// Convert to 4KB alignment.
+  ///
+  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress != 0x0) {
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress  &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress += 0x1000-1;
+  }
+
+  DEBUG ((DEBUG_INFO, "RMRR Base  address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress == 0) {
+    DEBUG ((DEBUG_WARN, "WARNING:  RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
+  }
+
+  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress   = MiscDxeConfig->RmrrCsmeBaseAddress[0];
+  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress  = MiscDxeConfig->RmrrCsmeBaseAddress[1];
+  DEBUG ((DEBUG_INFO, "RMRR Base  address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
+  ///
+  /// Update DRHD structures of DmarTable
+  ///
+  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+
+  DEBUG ((DEBUG_INFO, "VTD base address1 %x\n", DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
+  DEBUG ((DEBUG_INFO, "VTD base address3 %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);
+
+  ///
+  /// Update RMRR structures of temp DMAR table
+  ///
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
+
+  ///
+  /// 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.RmrrUsb.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb, TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  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;
+  }
+  if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme, TempDmarTable.RmrrCsme.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);
+}
+
+/**
+  PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+  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, "UpdateDmarPciEnumCompleteCallback \n"));
+
+
+  ///
+  /// Fix DMAR Table always created, skip install when disabled
+  ///
+  if ((mSaConfigHob->VtdData.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
+      ///
+      switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
+
+        case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
+          VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+          DmarTableUpdate (VtdAcpiTable, &Version);
+          break;
+
+        default:
+          break;
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      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;
+  UINTN                           MchBar;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+
+  mInterruptRemappingSupport  = FALSE;
+  mSaConfigHob       = NULL;
+  mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
+  if (mSaConfigHob != NULL) {
+    mInterruptRemappingSupport  = mSaConfigHob->VtdData.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, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
+  mSaPolicy        = SaPolicy;
+  MchBar           = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+
+  if (mSaConfigHob != NULL) {
+    SaNvsAreaProtocol->Area->VtdDisable = mSaConfigHob->VtdData.VtdDisable;
+  }
+  SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+  SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+  SaNvsAreaProtocol->Area->VtdEngine1Vid = PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  if (mSaConfigHob != NULL) {
+    if ((mSaConfigHob->VtdData.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/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..08fd9266c6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
@@ -0,0 +1,356 @@
+/** @file
+  This is the driver that publishes the SMM Access Protocol
+  instance for System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SmmAccessDriver.h"
+
+static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
+
+
+/**
+  This is the standard EFI driver point that
+  installs an SMM Access Protocol
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS           - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED    - Protocol was not installed
+  @retval EFI_NOT_FOUND         - Protocol can't be found.
+  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  EFI_PEI_HOB_POINTERS            *Hob;
+
+  ///
+  /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+  ///
+  /// Initialize Global variables
+  ///
+  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
+
+  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+  mSmmAccess.Handle           = NULL;
+
+  ///
+  /// Get Hob list
+  ///
+  Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
+
+  ///
+  /// Alloc space for mSmmAccess.SmramDesc
+  ///
+  mSmmAccess.SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR));
+  if (mSmmAccess.SmramDesc == NULL) {
+    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
+
+  ///
+  /// Use the HOB to publish SMRAM capabilities
+  ///
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock->Descriptor[Index].CpuStart;
+    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock->Descriptor[Index].RegionState;
+  }
+
+  mSmmAccess.NumberRegions              = Index;
+  mSmmAccess.SmmAccess.Open             = Open;
+  mSmmAccess.SmmAccess.Close            = Close;
+  mSmmAccess.SmmAccess.Lock             = Lock;
+  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
+  mSmmAccess.SmmAccess.LockState        = FALSE;
+  mSmmAccess.SmmAccess.OpenState        = FALSE;
+
+  ///
+  /// Install our protocol interfaces on the device's handle
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mSmmAccess.Handle,
+                  &gEfiSmmAccess2ProtocolGuid,
+                  &mSmmAccess.SmmAccess,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned %r\n", Status));
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  ///
+  /// BEGIN CHIPSET SPECIFIC CODE
+  ///
+  ///
+  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+  ///
+  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+  SmramControl = PciRead8 (Address);
+  ///
+  ///  Is SMRAM locked?
+  ///
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      ///
+      /// Cannot Open a locked region
+      ///
+      SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+  ///
+  /// Open SMRAM region
+  ///
+  SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
+  SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
+
+  PciWrite8 (Address, SmramControl);
+  ///
+  /// END CHIPSET SPECIFIC CODE
+  ///
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_OPEN;
+  }
+  SmmAccess->SmmAccess.OpenState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  BOOLEAN                 OpenState;
+  UINT8                   Index;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      continue;
+    }
+
+    ///
+    /// BEGIN CHIPSET SPECIFIC CODE
+    ///
+    ///
+    /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+    ///
+    Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+    SmramControl = PciRead8 (Address);
+    ///
+    ///  Is SMRAM locked?
+    ///
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      ///
+      /// Cannot Close a locked region
+      ///
+      SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+    ///
+    /// Close SMRAM region
+    ///
+    SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
+
+    PciWrite8 (Address, SmramControl);
+    ///
+    /// END CHIPSET SPECIFIC CODE
+    ///
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~EFI_SMRAM_OPEN;
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  }
+
+  ///
+  /// Find out if any regions are still open
+  ///
+  OpenState = FALSE;
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                                  one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (SmmAccess->SmmAccess.OpenState) {
+    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n"));
+    return EFI_DEVICE_ERROR;
+  }
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+  }
+  SmmAccess->SmmAccess.LockState = TRUE;
+
+  ///
+  /// BEGIN CHIPSET SPECIFIC CODE
+  ///
+  ///
+  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+  ///
+  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+  SmramControl = PciRead8 (Address);
+  ///
+  /// Lock the SMRAM
+  ///
+  SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
+
+  PciWrite8 (Address, SmramControl);
+  ///
+  /// END CHIPSET SPECIFIC CODE
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                                     buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                                     region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  EFI_STATUS              Status;
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   NecessaryBufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+  if (*SmramMapSize < NecessaryBufferSize) {
+    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+    Status = EFI_SUCCESS;
+  }
+
+  *SmramMapSize = NecessaryBufferSize;
+
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
new file mode 100644
index 0000000000..c864a0ca8f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
@@ -0,0 +1,250 @@
+/** @file
+  This file describes the contents of the ACPI DMA address Remapping
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Dmar.h"
+#include <Register/PchRegsP2sb.h>
+
+EFI_ACPI_DMAR_TABLE DmarTable = {
+  //
+  // EFI_ACPI_DMAR_HEADER
+  //
+  {
+    //
+    // EFI_ACPI_DESCRIPTION_HEADER
+    //
+    {
+      EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
+      sizeof (EFI_ACPI_DMAR_TABLE),
+      EFI_ACPI_DMAR_TABLE_REVISION,
+
+      //
+      // Checksum will be updated at runtime
+      //
+      0x00,
+
+      //
+      // It is expected that these values will be programmed at runtime
+      //
+      { 'I', 'N', 'T', 'E', 'L', ' ' },
+      EFI_ACPI_DMAR_OEM_TABLE_ID,
+      0x1,
+      EFI_ACPI_DMAR_OEM_CREATOR_ID,
+      1
+    },
+
+    //
+    // DMAR table specific entries below:
+    //
+
+    //
+    // 39-bit addressing Host Address Width
+    //
+    38,
+
+    //
+    // Flags
+    //
+    0,
+
+    //
+    // Reserved fields
+    //
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+  },
+
+  //
+  // First DRHD structure, VT-d Engine #1
+  //
+  {
+    //
+    // EFI_ACPI_DMAR_DRHD_HEADER
+    //
+    {
+      {0,                                         // Type = 0 (DRHD)
+      sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)},     // Length of structure
+      0,                                          // Flag - Do not include all
+      0,                                          // Reserved fields
+      0,                                          // Segment
+      0                                           // Base address of DMA-remapping hardware - Updated at boot time
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                     // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),  // Length
+        0,                                      // Segment number
+        0,                                      // Reserved
+        0},                                     // Start bus number
+        {2, 0}                                  // PCI path
+      }
+    }
+  },
+
+  //
+  //Third DRHD structure VT-d Engine# 3
+  //
+  {
+    //
+    // EFI_ACPI_DMAR_DRHD_HEADER
+    //
+    {
+      {0,                                        // Type = 0 (DRHD)
+      sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)},    // Length of strucure.
+      1,                                         // Flag - Include all
+      0,                                         // Reserved
+      0,                                         // Segment Number
+      0                                          // Base address of DMA-remapping hardware.
+    },
+    {
+      //
+      // Device Scopes
+      //
+      {
+        {3,                                          // Type=IO APIC
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
+        0,                                           // Reserved
+        2,                                           // Enumeration ID
+        V_P2SB_CFG_IBDF_BUS},                        // Start bus number
+        {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC}  // PCI path
+      },
+      //
+      // Device Scopes
+      //
+      {
+        {4,                                          // Type=HPET
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
+        0,                                           // Reserved
+        0,                                           // Enumeration ID
+        V_P2SB_CFG_HBDF_BUS},                        // Start bus number
+        {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC}  // PCI path
+      }
+    }
+  },
+  //RMRR structure for USB devices.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {
+        0x1,                                     // Type 1 - RMRR structure
+        sizeof(EFI_ACPI_RMRR_USB_STRUC)          // Length
+      },
+      { 0x00, 0x00 },                            // Reserved
+      0x0000,                                    // Segment Num
+      0x00000000000E0000,                        // RMRR Base address - Updated in runtime.
+      0x00000000000EFFFF                         // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                    // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                     // Reserved
+        0,                                     // Enum ID
+        0},                                    // Start bus number
+        {20, 0}                                // PCI path
+      },
+      {
+        {1,                                    // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                     // Reserved
+        0,                                     // Enum ID
+        0},                                    // Start bus number
+        {20, 1}                                // PCI path
+      }
+    }
+  },
+
+  //RMRR structure for IGD device.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {1,                                       // Type 1 - RMRR structure
+      sizeof (EFI_ACPI_RMRR_IGD_STRUC)},        // Length
+      {0x0000},                                 // Reserved
+      0x0000,                                   // Segment Num
+      0x0000000000000000,                       // RMRR Base address - Updated in runtime.
+      0x0000000000000000                        // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                   // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                    // Reserved
+        0,                                    // Enum ID
+        0},                                   // Start bus number
+        {2, 0}                                // PCI path
+      }
+    }
+  },
+
+  // RMRR structure for WiAMT DMA access.
+  // Keep this device in end of RMRR queue.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {1,                                       // Type 1 - RMRR structure
+      sizeof (EFI_ACPI_RMRR_CSME_STRUC)},       // Length
+      {0x0000},                                 // Reserved
+      0x0000,                                   // Segment Num
+      0x0000000000000000,                       // RMRR Base address - Updated in runtime.
+      0x0000000000000000                        // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                   // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                    // Reserved
+        0,                                    // Enum ID
+        0},                                   // Start bus number
+        {22, 7}                               // PCI path
+      }
+    }
+  }
+};
+
+//
+// Dummy function required for build tools
+//
+#if defined (__GNUC__)
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&DmarTable;
+}
+#else
+int
+main (
+  VOID
+  )
+{
+  return 0;
+}
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
new file mode 100644
index 0000000000..b431a77f05
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
@@ -0,0 +1,794 @@
+/** @file
+  This file contains the SystemAgent PCI Configuration space
+  definition.
+  It defines various System Agent PCI Configuration Space registers
+  which will be used to dynamically produce all resources in the Host Bus.
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(M64B)
+External(M64L)
+External(M32B)
+External(M32L)
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x40),   // EPBAR (0:0:0:40)
+  EPEN, 1,        // Enable
+      , 11,
+  EPBR, 20,       // EPBAR [31:12]
+
+  Offset(0x48),   // MCHBAR (0:0:0:48)
+  MHEN, 1,        // Enable
+      , 14,
+  MHBR, 17,       // MCHBAR [31:15]
+
+  Offset(0x50),   // GGC (0:0:0:50)
+  GCLK, 1,        // GGCLCK
+
+  Offset(0x54),   // DEVEN (0:0:0:54)
+  D0EN, 1,        // DEV0 Enable
+  D1F2, 1,        // DEV1 FUN2 Enable
+  D1F1, 1,        // DEV1 FUN1 Enable
+  D1F0, 1,        // DEV1 FUN0 Enable
+
+  Offset(0x60),   // PCIEXBAR (0:0:0:60)
+  PXEN, 1,        // Enable
+  PXSZ, 2,        // PCI Express Size
+      , 23,
+  PXBR, 6,        // PCI Express BAR [31:26]
+
+  Offset(0x68),   // DMIBAR (0:0:0:68)
+  DIEN, 1,        // Enable
+      , 11,
+  DIBR, 20,       // DMIBAR [31:12]
+
+  Offset(0x70),   // MESEG_BASE (0:0:0:70)
+      , 20,
+  MEBR, 12,       // MESEG_BASE [31:20]
+
+  Offset(0x80),   // PAM0 Register (0:0:0:80)
+  PMLK, 1,        // PAM Lock bit.
+      , 3,
+  PM0H, 2,        // PAM 0, High Nibble
+      , 2,
+
+  Offset(0x81),   // PAM1 Register (0:0:0:81)
+  PM1L, 2,        // PAM1, Low  Nibble
+      , 2,
+  PM1H, 2,        // PAM1, High Nibble
+      , 2,
+
+  Offset(0x82),   // PAM2 Register (0:0:0:82)
+  PM2L, 2,        // PAM2, Low  Nibble
+      , 2,
+  PM2H, 2,        // PAM2, High Nibble
+      , 2,
+
+  Offset(0x83),   // PAM3 Register (0:0:0:83)
+  PM3L, 2,        // PAM3, Low  Nibble
+      , 2,
+  PM3H, 2,        // PAM3, High Nibble
+      , 2,
+
+  Offset(0x84),   // PAM4 Register (0:0:0:84)
+  PM4L, 2,        // PAM4, Low  Nibble
+      , 2,
+  PM4H, 2,        // PAM4, High Nibble
+      , 2,
+
+  Offset(0x85),   // PAM5 Register (0:0:0:85)
+  PM5L, 2,        // PAM5, Low  Nibble
+      , 2,
+  PM5H, 2,        // PAM5, High Nibble
+      , 2,
+
+  Offset(0x86),   // PAM6 Register (0:0:0:86)
+  PM6L, 2,        // PAM6, Low  Nibble
+      , 2,
+  PM6H, 2,        // PAM6, High Nibble
+      , 2,
+
+  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
+      , 20,
+  TUUD, 19,       // TOUUD [38:20]
+
+  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
+      , 20,
+  TLUD, 12,       // TOLUD [31:20]
+
+  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
+      , 7,
+  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus.  This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+  //
+  // Bus Number Allocation: Bus 0 to 0xFF
+  //
+  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+    0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+  //
+  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+  //
+  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+  //
+  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+  //
+  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+  //
+  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+  //
+  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+  //
+  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+  //
+  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+  //
+  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+  //
+  // BIOS Area ( 0xF0000 - 0xFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+//  //
+//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+//  //
+//  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+  //
+  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+  //
+  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+  // (This is dummy range for OS compatibility, will patch it in _CRS)
+  //
+  QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+  //
+  // SA reserved resources
+  //
+  Device(SRRE) {
+    Name(_HID,EISAID("PNP0C02")) // motherboard resource
+    Name(_UID,"SARESV")
+    Method(_STA,0,Serialized) // device present and decodes its resources, but not to be displayed in OSPM
+    {
+      If(LGreaterEqual(TLUD, 0x404)) {
+        Return (3)
+      } Else {
+        Return (0)
+      }
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+      Name(BUF0,ResourceTemplate(){
+        //
+        // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this memory range
+        //
+        Memory32Fixed(ReadOnly,0x40000000,0x400000)
+      })
+      If(LGreaterEqual(TLUD, 0x404)) {
+        Return (BUF0)
+      } Else {
+        Return (Buffer(){})
+      }
+    }
+  }
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+  if(LEqual(EP_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+  }
+  Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+  if(LEqual(MH_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+  }
+  Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+  if(LEqual(PC_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+  }
+  Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+  if(LEqual(PC_L,0)) {
+    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+  }
+  Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+  if(LEqual(DM_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+  }
+  Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+  //
+  // Fix up Max Bus Number and Length
+  //
+  Store(\_SB.PCI0.GPCL(),Local0)
+  CreateWordField(BUF0, ^PB00._MAX, PBMX)
+  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+  CreateWordField(BUF0, ^PB00._LEN, PBLN)
+  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+  //
+  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+  //
+  If(PM1L)  // \_SB.PCI0
+  {
+    // PAMx != 0.  Set length = 0.
+
+    CreateDwordField(BUF0, ^C000._LEN,C0LN)
+    Store(Zero,C0LN)
+  }
+
+  If(LEqual(PM1L,1))
+  {
+    CreateBitField(BUF0, ^C000._RW,C0RW)
+    Store(Zero,C0RW)
+  }
+
+  If(PM1H)
+  {
+    CreateDwordField(BUF0, ^C400._LEN,C4LN)
+    Store(Zero,C4LN)
+  }
+
+  If(LEqual(PM1H,1))
+  {
+    CreateBitField(BUF0, ^C400._RW,C4RW)
+    Store(Zero,C4RW)
+  }
+
+  If(PM2L)
+  {
+    CreateDwordField(BUF0, ^C800._LEN,C8LN)
+    Store(Zero,C8LN)
+  }
+
+  If(LEqual(PM2L,1))
+  {
+    CreateBitField(BUF0, ^C800._RW,C8RW)
+    Store(Zero,C8RW)
+  }
+
+  If(PM2H)
+  {
+    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+    Store(Zero,CCLN)
+  }
+
+  If(LEqual(PM2H,1))
+  {
+    CreateBitField(BUF0, ^CC00._RW,CCRW)
+    Store(Zero,CCRW)
+  }
+
+  If(PM3L)
+  {
+    CreateDwordField(BUF0, ^D000._LEN,D0LN)
+    Store(Zero,D0LN)
+  }
+
+  If(LEqual(PM3L,1))
+  {
+    CreateBitField(BUF0, ^D000._RW,D0RW)
+    Store(Zero,D0RW)
+  }
+
+  If(PM3H)
+  {
+    CreateDwordField(BUF0, ^D400._LEN,D4LN)
+    Store(Zero,D4LN)
+  }
+
+  If(LEqual(PM3H,1))
+  {
+    CreateBitField(BUF0, ^D400._RW,D4RW)
+    Store(Zero,D4RW)
+  }
+
+  If(PM4L)
+  {
+    CreateDwordField(BUF0, ^D800._LEN,D8LN)
+    Store(Zero,D8LN)
+  }
+
+  If(LEqual(PM4L,1))
+  {
+    CreateBitField(BUF0, ^D800._RW,D8RW)
+    Store(Zero,D8RW)
+  }
+
+  If(PM4H)
+  {
+    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+    Store(Zero,DCLN)
+  }
+
+  If(LEqual(PM4H,1))
+  {
+    CreateBitField(BUF0, ^DC00._RW,DCRW)
+    Store(Zero,DCRW)
+  }
+
+  If(PM5L)
+  {
+    CreateDwordField(BUF0, ^E000._LEN,E0LN)
+    Store(Zero,E0LN)
+  }
+
+  If(LEqual(PM5L,1))
+  {
+    CreateBitField(BUF0, ^E000._RW,E0RW)
+    Store(Zero,E0RW)
+  }
+
+  If(PM5H)
+  {
+    CreateDwordField(BUF0, ^E400._LEN,E4LN)
+    Store(Zero,E4LN)
+  }
+
+  If(LEqual(PM5H,1))
+  {
+    CreateBitField(BUF0, ^E400._RW,E4RW)
+    Store(Zero,E4RW)
+  }
+
+  If(PM6L)
+  {
+    CreateDwordField(BUF0, ^E800._LEN,E8LN)
+    Store(Zero,E8LN)
+  }
+
+  If(LEqual(PM6L,1))
+  {
+    CreateBitField(BUF0, ^E800._RW,E8RW)
+    Store(Zero,E8RW)
+  }
+
+  If(PM6H)
+  {
+    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+    Store(Zero,ECLN)
+  }
+
+  If(LEqual(PM6H,1))
+  {
+    CreateBitField(BUF0, ^EC00._RW,ECRW)
+    Store(Zero,ECRW)
+  }
+
+  If(PM0H)
+  {
+    CreateDwordField(BUF0, ^F000._LEN,F0LN)
+    Store(Zero,F0LN)
+  }
+
+  If(LEqual(PM0H,1))
+  {
+    CreateBitField(BUF0, ^F000._RW,F0RW)
+    Store(Zero,F0RW)
+  }
+
+  // Enable the 1MB region between 15-16MB if HENA = 1.
+  //
+  // If( MCHC.HENA)
+  // {
+  // CreateDwordField(BUF0, HOLE._LEN,H0LN)
+  // Store(0x100000,H0LN)
+  // }
+
+  //
+  // Create pointers to Memory Sizing values.
+  //
+  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+  //
+  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+  // TOM, so shift these bits into the correct position and fix up
+  // the Memory Region available to PCI.
+  //
+  Store (M32L, M1LN)
+  Store (M32B, M1MN)
+  Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+  //
+  // Create pointers to Memory Sizing values.
+  // Patch PM02 range basing on memory size and OS type
+  //
+  If (LEqual(M64L, 0)) {
+    CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+    //
+    // Set resource length to 0
+    //
+    Store (0, MSLN)
+  }
+  Else {
+    CreateQwordField(BUF0, ^PM02._LEN,M2LN)
+    CreateQwordField(BUF0, ^PM02._MIN,M2MN)
+    CreateQwordField(BUF0, ^PM02._MAX,M2MX)
+    //
+    // Set 64bit MMIO resource Base and Length
+    //
+    Store (M64L, M2LN)
+    Store (M64B, M2MN)
+    Subtract (Add (M2MN, M2LN), 1, M2MX)
+  }
+  Return(BUF0)
+}
+
+//
+//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
+//
+Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
+          0xf7, 0x1f,
+          0x1c, 0x40,
+          0x96, 0x57,
+          0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
+
+
+Name(SUPP,0)  // PCI _OSC Support Field value
+Name(CTRL,0)  // PCI _OSC Control Field value
+Name(XCNT, 0) // Variable used in _OSC for counting
+
+Method(_OSC,4,Serialized)
+{
+  //
+  // Check for proper UUID
+  // Save the capabilities buffer
+  //
+  Store(Arg3,Local0)
+
+  //
+  // Create DWord-adressable fields from the Capabilties Buffer
+  //
+  CreateDWordField(Local0,0,CDW1)
+  CreateDWordField(Local0,4,CDW2)
+  CreateDWordField(Local0,8,CDW3)
+
+
+  //
+  // Check for proper UUID
+  //
+  If(LEqual(Arg0,GUID))
+  {
+    // Save Capabilities DWord2 & 3
+    Store(CDW2,SUPP)
+    Store(CDW3,CTRL)
+
+    //
+    // You can clear bits in CTRL here if you don't want OS to take
+    // control
+    //
+    If(LNot(NEXP))
+    {
+      And(CTRL, 0xFFFFFFF8, CTRL)       // disable Native hot plug, PME
+    }
+
+    If(LEqual(TBTS, 1)) {
+      // \_OSC disallow only Advanced Error Reporting control
+      And(CTRL, 0xFFFFFFF7, CTRL)
+    }
+
+    If(Not(And(CDW1,1)))  // Query flag clear?
+    { // Disable GPEs for features granted native control.
+      If(And(CTRL,0x01))
+      {
+        NHPG()
+      }
+      If(And(CTRL,0x04))  // PME control granted?
+      {
+        NPME()
+      }
+    }
+
+    If(LNotEqual(Arg1,One))
+    {
+      //
+      // Unknown revision
+      //
+      Or(CDW1,0x08,CDW1)
+    }
+
+    If(LNotEqual(CDW3,CTRL))
+    {
+      //
+      // Capabilities bits were masked
+      //
+      Or(CDW1,0x10,CDW1)
+    }
+    //
+    // Update DWORD3 in the buffer
+    //
+    Store(CTRL,CDW3)
+    Store(CTRL,OSCC)
+    Return(Local0)
+  } Else {
+    Or(CDW1,4,CDW1)   // Unrecognized UUID
+    Return(Local0)
+  }
+} // End _OSC
+
+//
+// Added code for Dual IRQ support. Two set of ACPI IRQ tables were generated.
+// Code has been added to select the appropriate IRQ table by checking the CPUID.
+//
+Scope(\_SB.PCI0)
+{
+  Method(AR00) {
+    Return(\_SB.AR00)
+  }
+
+  Method(PD00) {
+    Return(\_SB.PD00)
+  }
+
+  Method(AR02) {
+    Return(\_SB.AR02)
+  }
+
+  Method(PD02) {
+    Return(\_SB.PD02)
+  }
+
+  Method(AR04) {
+    Return(\_SB.AR04)
+  }
+
+  Method(PD04) {
+    Return(\_SB.PD04)
+  }
+
+  Method(AR05) {
+    Return(\_SB.AR05)
+  }
+
+  Method(PD05) {
+    Return(\_SB.PD05)
+  }
+
+  Method(AR06) {
+    Return(\_SB.AR06)
+  }
+
+  Method(PD06) {
+    Return(\_SB.PD06)
+  }
+
+  Method(AR07) {
+    Return(\_SB.AR07)
+  }
+
+  Method(PD07) {
+    Return(\_SB.PD07)
+  }
+
+  Method(AR08) {
+    Return(\_SB.AR08)
+  }
+
+  Method(PD08) {
+    Return(\_SB.PD08)
+  }
+
+  Method(AR09) {
+    Return(\_SB.AR09)
+  }
+
+  Method(PD09) {
+    Return(\_SB.PD09)
+  }
+
+  Method(AR0A) {
+    Return(\_SB.AR0A)
+  }
+
+  Method(PD0A) {
+    Return(\_SB.PD0A)
+  }
+
+  Method(AR0B) {
+    Return(\_SB.AR0B)
+  }
+
+  Method(PD0B) {
+    Return(\_SB.PD0B)
+  }
+
+  //
+  // Add device scope definition for System Agent
+  // P.E.G. Root Port D1F0
+  //
+  Device(PEG0) {
+    Name(_ADR, 0x00010000)
+    Device(PEGP) { // P.E.G. Port Slot x16
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // P.E.G. Root Port D1F1
+  //
+  Device(PEG1) {
+    Name(_ADR, 0x00010001)
+    Device(PEGP) { // P.E.G. Port Slot x8
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // P.E.G. Root Port D1F2
+  //
+  Device(PEG2) {
+    Name(_ADR, 0x00010002)
+    Device(PEGP) { // P.E.G. Port Slot x4
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // I.G.D
+  //
+  Device(GFX0) {
+    Name(_ADR, 0x00020000)
+  }
+  //
+  // SA Thermal Device
+  //
+  Device(B0D4) {
+    Method(_DSM,4,serialized){if(PCIC(Arg0)) { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
+    Name(_ADR, 0x00040000)
+  }
+  //
+  // Device IPU0 is the IPU PCI device
+  //
+  Device(IPU0) {
+    Name(_ADR, 0x00050000)
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
new file mode 100644
index 0000000000..e7a797c973
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
@@ -0,0 +1,1666 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+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)
+
+Name(TMP1,Package() {0xFFFFFFFF})
+Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF})
+Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
+Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF})
+Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF})
+
+// 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)
+{
+  If (LEqual(IPTP,1)) {
+    //
+    // Increment number of devices if IPU is enabled
+    //
+    Store(1, NDID)
+  } Else {
+    Store(0, 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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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(SGMD,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))
+    {
+      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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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.PCI0.GFX0.AINT(1, Arg0)
+      Store(Arg0,BRTL)  // Store Brightness Level.
+    }
+  }
+
+  //
+  // Brightness Query Current level.
+  //
+  Method (_BQC,0)
+  {
+    Return(BRTL)
+  }
+}
+
+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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
new file mode 100644
index 0000000000..7edbe45e2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
@@ -0,0 +1,472 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/************************************************************************;
+;* 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.PCI0.GFX0, Arg1)
+  }
+
+  If(CondRefOf(HNOT))
+  {
+    HNOT(Arg0)  //Notification handler for Switchable graphics
+  }
+  Else
+  {
+    Notify(\_SB.PCI0.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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
new file mode 100644
index 0000000000..e7b3c92cda
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
@@ -0,0 +1,369 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// _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
+    //
+    //
+    // 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 (0x1E7FF)   // bit 11 and 12 is not supported
+        }
+      }
+
+      //
+      // 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
new file mode 100644
index 0000000000..26e560a358
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
@@ -0,0 +1,129 @@
+/** @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) 2019 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
new file mode 100644
index 0000000000..a26cbdb00c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
@@ -0,0 +1,296 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//  Define an OperationRegion to cover the GMCH PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+//
+Scope(\_SB.PCI0)
+{
+  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
+  //
+  // 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.PCI0.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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
new file mode 100644
index 0000000000..0167d922ff
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
@@ -0,0 +1,262 @@
+/** @file
+  This file contains the system BIOS call back functionality for the
+  OpRegion/Software SCI mechanism.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
new file mode 100644
index 0000000000..e4e47ddf1e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
@@ -0,0 +1,87 @@
+/** @file
+  This file contains the device definition of the System Agent
+  ACPI reference code.
+  Currently defines the device objects for the
+  System Agent IPU device
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
+//
+Scope (\_SB.PCI0.GFX0)
+{
+  Device(IPUA) // IPU AVStream virtual device name
+  {
+    /*
+      The identifier for this device (Same as in
+      _DOD above). This is required so GFX driver can
+      associate a matching device ID for the AVStream
+      driver and provide it to PnP (this device ID
+      should appear in the INF file of the AVStream
+      driver).
+    */
+    Name(_ADR, 0x00003480)
+    /*
+      The following is a technique that may be used (per OEM needs) to prevent
+      the load of the camera device in one of the following cases:
+      - Camera device is fused out
+      - If the platform setup requires that in a secured boot the camera device
+      should not be enabled
+    */
+    Method (_STA, 0, NotSerialized) {
+      If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as GFX0 child
+        Return (0xF)
+      } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0 child
+        Return (0x0)
+      }
+    }
+  } // End SKC0
+} // end I.G.D
+
+Scope(\_SB.PCI0.IPU0)
+{
+//----------------------------------------------------------------------------------------
+//  Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM Method
+//
+//  Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj, IntObj, PkgObj})
+//  Arguments:
+//  Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
+//  Arg1: Integer Revision Level (Current revision is 0)
+//  Arg2: Integer Function Index
+//                0x1 - return UINT 32bit LTR values
+//                0x2 - return UINT 32bit Fill Time
+//
+//-----------------------------------------------------------------------------------------
+Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
+    If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
+    {
+      // Function 0 : Query Function
+      If (LEqual(Arg2, 0))
+      {
+        // Revision 0
+        If (LEqual(Arg1, 0)) // The current revision is 0
+        {
+          Return(Buffer() { 0x07 }) // There are 2 function defined other than Query.
+        } Else {
+          Return(0) // Revision mismatch
+        }
+      }
+      // Function 1 : Return UINT 32bit LTR values
+      If(LEqual(Arg2, 1))
+      {
+        Return(0x64503C19)
+      }
+      // Function 2 : Return UINT 32bit Fill Time
+      If(LEqual(Arg2, 2))
+      {
+        Return(0xFFF0783C)
+      }
+    }
+
+    Return(0) // Function number or GUID mismatch but normal return.
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
new file mode 100644
index 0000000000..4817968240
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
@@ -0,0 +1,31 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.PCI0, DeviceObj)
+External(\_SB.PCI0.GFX0, DeviceObj)
+External(\_SB.PCI0.IPU0, DeviceObj)
+External(\_SB.PCI0.B0D3, DeviceObj)
+External(\_SB.PCI0.PCIC, MethodObj)
+External(\_SB.PCI0.PCID, MethodObj)
+
+
+///
+/// I.G.D
+///
+Scope (\_SB.PCI0.GFX0)
+{
+  include("Igfx.asl")
+} // end I.G.D
+
+///
+/// IPU Device
+///
+include("Ipu.asl")
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
new file mode 100644
index 0000000000..09d36ade53
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
@@ -0,0 +1,147 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define SA NVS Area operatino region.
+  //
+
+
+
+  OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
+  Field(SANV,AnyAcc,Lock,Preserve)
+  {  Offset(0),      ASLB, 32, // Offset(0),     IGD OpRegion base address
+  Offset(4),      IMON, 8,  // Offset(4),     IMON Current Value
+  Offset(5),      IGDS, 8,  // Offset(5),     IGD State (Primary Display = 1)
+  Offset(6),      IBTT, 8,  // Offset(6),     IGD Boot Display Device
+  Offset(7),      IPAT, 8,  // Offset(7),     IGD Panel Type CMOS option
+  Offset(8),      IPSC, 8,  // Offset(8),     IGD Panel Scaling
+  Offset(9),      IBIA, 8,  // Offset(9),     IGD BIA Configuration
+  Offset(10),     ISSC, 8,  // Offset(10),    IGD SSC Configuration
+  Offset(11),     IDMS, 8,  // Offset(11),    IGD DVMT Memory Size
+  Offset(12),     IF1E, 8,  // Offset(12),    IGD Function 1 Enable
+  Offset(13),     HVCO, 8,  // Offset(13),    HPLL VCO
+  Offset(14),     GSMI, 8,  // Offset(14),    GMCH SMI/SCI mode (0=SCI)
+  Offset(15),     PAVP, 8,  // Offset(15),    IGD PAVP data
+  Offset(16),     CADL, 8,  // Offset(16),    Current Attached Device List
+  Offset(17),     CSTE, 16, // Offset(17),    Current Display State
+  Offset(19),     NSTE, 16, // Offset(19),    Next Display State
+  Offset(21),     NDID, 8,  // Offset(21),    Number of Valid Device IDs
+  Offset(22),     DID1, 32, // Offset(22),    Device ID 1
+  Offset(26),     DID2, 32, // Offset(26),    Device ID 2
+  Offset(30),     DID3, 32, // Offset(30),    Device ID 3
+  Offset(34),     DID4, 32, // Offset(34),    Device ID 4
+  Offset(38),     DID5, 32, // Offset(38),    Device ID 5
+  Offset(42),     DID6, 32, // Offset(42),    Device ID 6
+  Offset(46),     DID7, 32, // Offset(46),    Device ID 7
+  Offset(50),     DID8, 32, // Offset(50),    Device ID 8
+  Offset(54),     DID9, 32, // Offset(54),    Device ID 9
+  Offset(58),     DIDA, 32, // Offset(58),    Device ID 10
+  Offset(62),     DIDB, 32, // Offset(62),    Device ID 11
+  Offset(66),     DIDC, 32, // Offset(66),    Device ID 12
+  Offset(70),     DIDD, 32, // Offset(70),    Device ID 13
+  Offset(74),     DIDE, 32, // Offset(74),    Device ID 14
+  Offset(78),     DIDF, 32, // Offset(78),    Device ID 15
+  Offset(82),     DIDX, 32, // Offset(82),    Device ID for eDP device
+  Offset(86),     NXD1, 32, // Offset(86),    Next state DID1 for _DGS
+  Offset(90),     NXD2, 32, // Offset(90),    Next state DID2 for _DGS
+  Offset(94),     NXD3, 32, // Offset(94),    Next state DID3 for _DGS
+  Offset(98),     NXD4, 32, // Offset(98),    Next state DID4 for _DGS
+  Offset(102),    NXD5, 32, // Offset(102),   Next state DID5 for _DGS
+  Offset(106),    NXD6, 32, // Offset(106),   Next state DID6 for _DGS
+  Offset(110),    NXD7, 32, // Offset(110),   Next state DID7 for _DGS
+  Offset(114),    NXD8, 32, // Offset(114),   Next state DID8 for _DGS
+  Offset(118),    NXDX, 32, // Offset(118),   Next state DID for eDP
+  Offset(122),    LIDS, 8,  // Offset(122),   Lid State (Lid Open = 1)
+  Offset(123),    KSV0, 32, // Offset(123),   First four bytes of AKSV (manufacturing mode)
+  Offset(127),    KSV1, 8,  // Offset(127),   Fifth byte of AKSV (manufacturing mode)
+  Offset(128),    BRTL, 8,  // Offset(128),   Brightness Level Percentage
+  Offset(129),    ALSE, 8,  // Offset(129),   Ambient Light Sensor Enable
+  Offset(130),    ALAF, 8,  // Offset(130),   Ambient Light Adjusment Factor
+  Offset(131),    LLOW, 8,  // Offset(131),   LUX Low Value
+  Offset(132),    LHIH, 8,  // Offset(132),   LUX High Value
+  Offset(133),    ALFP, 8,  // Offset(133),   Active LFP
+  Offset(134),    IPTP, 8,  // Offset(134),   IPU ACPI device type (0=Disabled, 1=AVStream virtual device as child of GFX)
+  Offset(135),    EDPV, 8,  // Offset(135),   Check for eDP display device
+  Offset(136),    SGMD, 8,  // Offset(136),   SG Mode (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
+  Offset(137),    SGFL, 8,  // Offset(137),   SG Feature List
+  Offset(138),    SGGP, 8,  // Offset(138),   PCIe0 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(139),    HRE0, 8,  // Offset(139),   PCIe0 HLD RST IO Expander Number
+  Offset(140),    HRG0, 32, // Offset(140),   PCIe0 HLD RST GPIO Number
+  Offset(144),    HRA0, 8,  // Offset(144),   PCIe0 HLD RST GPIO Active Information
+  Offset(145),    PWE0, 8,  // Offset(145),   PCIe0 PWR Enable IO Expander Number
+  Offset(146),    PWG0, 32, // Offset(146),   PCIe0 PWR Enable GPIO Number
+  Offset(150),    PWA0, 8,  // Offset(150),   PCIe0 PWR Enable GPIO Active Information
+  Offset(151),    P1GP, 8,  // Offset(151),   PCIe1 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(152),    HRE1, 8,  // Offset(152),   PCIe1 HLD RST IO Expander Number
+  Offset(153),    HRG1, 32, // Offset(153),   PCIe1 HLD RST GPIO Number
+  Offset(157),    HRA1, 8,  // Offset(157),   PCIe1 HLD RST GPIO Active Information
+  Offset(158),    PWE1, 8,  // Offset(158),   PCIe1 PWR Enable IO Expander Number
+  Offset(159),    PWG1, 32, // Offset(159),   PCIe1 PWR Enable GPIO Number
+  Offset(163),    PWA1, 8,  // Offset(163),   PCIe1 PWR Enable GPIO Active Information
+  Offset(164),    P2GP, 8,  // Offset(164),   PCIe2 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(165),    HRE2, 8,  // Offset(165),   PCIe2 HLD RST IO Expander Number
+  Offset(166),    HRG2, 32, // Offset(166),   PCIe2 HLD RST GPIO Number
+  Offset(170),    HRA2, 8,  // Offset(170),   PCIe2 HLD RST GPIO Active Information
+  Offset(171),    PWE2, 8,  // Offset(171),   PCIe2 PWR Enable IO Expander Number
+  Offset(172),    PWG2, 32, // Offset(172),   PCIe2 PWR Enable GPIO Number
+  Offset(176),    PWA2, 8,  // Offset(176),   PCIe2 PWR Enable GPIO Active Information
+  Offset(177),    DLPW, 16, // Offset(177),   Delay after power enable for PCIe
+  Offset(179),    DLHR, 16, // Offset(179),   Delay after Hold Reset for PCIe
+  Offset(181),    EECP, 8,  // Offset(181),   PCIe0 Endpoint Capability Structure Offset
+  Offset(182),    XBAS, 32, // Offset(182),   Any Device's PCIe Config Space Base Address
+  Offset(186),    GBAS, 16, // Offset(186),   GPIO Base Address
+  Offset(188),    NVGA, 32, // Offset(188),   NVIG opregion address
+  Offset(192),    NVHA, 32, // Offset(192),   NVHM opregion address
+  Offset(196),    AMDA, 32, // Offset(196),   AMDA opregion address
+  Offset(200),    LTRX, 8,  // Offset(200),   Latency Tolerance Reporting Enable
+  Offset(201),    OBFX, 8,  // Offset(201),   Optimized Buffer Flush and Fill
+  Offset(202),    LTRY, 8,  // Offset(202),   Latency Tolerance Reporting Enable
+  Offset(203),    OBFY, 8,  // Offset(203),   Optimized Buffer Flush and Fill
+  Offset(204),    LTRZ, 8,  // Offset(204),   Latency Tolerance Reporting Enable
+  Offset(205),    OBFZ, 8,  // Offset(205),   Optimized Buffer Flush and Fill
+  Offset(206),    LTRW, 8,  // Offset(206),   Latency Tolerance Reporting Enable
+  Offset(207),    OBFA, 8,  // Offset(207),   Optimized Buffer Flush and Fill
+  Offset(208),    SMSL, 16, // Offset(208),   SA Peg Latency Tolerance Reporting Max Snoop Latency
+  Offset(210),    SNSL, 16, // Offset(210),   SA Peg Latency Tolerance Reporting Max No Snoop Latency
+  Offset(212),    P0UB, 8,  // Offset(212),   Peg0 Unused Bundle Control
+  Offset(213),    P1UB, 8,  // Offset(213),   Peg1 Unused Bundle Control
+  Offset(214),    P2UB, 8,  // Offset(214),   Peg2 Unused Bundle Control
+  Offset(215),    P3UB, 8,  // Offset(215),   Peg3 Unused Bundle Control
+  Offset(216),    PCSL, 8,  // Offset(216),   The lowest C-state for the package
+  Offset(217),    PBGE, 8,  // Offset(217),   Pegx Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
+  Offset(218),    M64B, 64, // Offset(218),   Base of above 4GB MMIO resource
+  Offset(226),    M64L, 64, // Offset(226),   Length of above 4GB MMIO resource
+  Offset(234),    CPEX, 32, // Offset(234),   CPU ID info to get Family Id or Stepping
+  Offset(238),    EEC1, 8,  // Offset(238),   PCIe1 Endpoint Capability Structure Offset
+  Offset(239),    EEC2, 8,  // Offset(239),   PCIe2 Endpoint Capability Structure Offset
+  Offset(240),    SBN0, 8,  // Offset(240),   PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(241),    SBN1, 8,  // Offset(241),   PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(242),    SBN2, 8,  // Offset(242),   PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(243),    M32B, 32, // Offset(243),   Base of below 4GB MMIO resource
+  Offset(247),    M32L, 32, // Offset(247),   Length of below 4GB MMIO resource
+  Offset(251),    P0WK, 32, // Offset(251),   PCIe0 RTD3 Device Wake GPIO Number
+  Offset(255),    P1WK, 32, // Offset(255),   PCIe1 RTD3 Device Wake GPIO Number
+  Offset(259),    P2WK, 32, // Offset(259),   PCIe2 RTD3 Device Wake GPIO Number
+  Offset(263),    VTDS, 8,  // Offset(263),   VT-d Enable/Disable
+  Offset(264),    VTB1, 32, // Offset(264),   VT-d Base Address 1
+  Offset(268),    VTB2, 32, // Offset(268),   VT-d Base Address 2
+  Offset(272),    VTB3, 32, // Offset(272),   VT-d Base Address 3
+  Offset(276),    VE1V, 16, // Offset(276),   VT-d Engine#1 Vendor ID
+  Offset(278),    VE2V, 16, // Offset(278),   VT-d Engine#2 Vendor ID
+  Offset(280),    SBN3, 8,  // Offset(280),   PCIe3 Secondary Bus Number (PCIe3 Endpoint Bus Number)
+  Offset(281),    P3GP, 8,  // Offset(281),   PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(282),    HRE3, 8,  // Offset(282),   PCIe3 HLD RST IO Expander Number
+  Offset(283),    HRG3, 32, // Offset(283),   PCIe3 HLD RST GPIO Number
+  Offset(287),    HRA3, 8,  // Offset(287),   PCIe3 HLD RST GPIO Active Information
+  Offset(288),    PWE3, 8,  // Offset(288),   PCIe3 PWR Enable IO Expander Number
+  Offset(289),    PWG3, 32, // Offset(289),   PCIe3 PWR Enable GPIO Number
+  Offset(293),    PWA3, 8,  // Offset(293),   PCIe3 PWR Enable GPIO Active Information
+  Offset(294),    P3WK, 32, // Offset(294),   PCIe3 RTD3 Device Wake GPIO Number
+  Offset(298),    EEC3, 8,  // Offset(298),   PCIe3 Endpoint Capability Structure Offset
+  Offset(299),    RPIN, 8,  // Offset(299),   RootPort Number
+  Offset(300),    RPBA, 32, // Offset(300),   RootPortAddress
+  Offset (500),             // Offset(304) : Offset(499), Reserved bytes
+  }
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
new file mode 100644
index 0000000000..0db354901d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
@@ -0,0 +1,22 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+  "SaSsdt.aml",
+  "SSDT",
+  0x02,
+  "SaSsdt",
+  "SaSsdt ",
+  0x3000
+  )
+{
+  include ("SaNvs.asl")
+  include ("Sa.asl")
+}
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (27 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
                   ` (8 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney, Ankit Sinha

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

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc | 215 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc     | 130 ++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc       |  69 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc             |  33 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc          |  37 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc             |  21 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc          |  44 ++++
 7 files changed, 549 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
new file mode 100644
index 0000000000..37c77d8f63
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
@@ -0,0 +1,215 @@
+## @file
+#  Component description file for the Coffee Lake silicon package DSC file.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[PcdsFeatureFlag]
+gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |TRUE
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE
+gSiPkgTokenSpaceGuid.PcdSiCsmEnable                  |FALSE
+gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE
+gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE
+gSiPkgTokenSpaceGuid.PcdAcpiEnable                   |FALSE
+gSiPkgTokenSpaceGuid.PcdSourceDebugEnable            |FALSE
+gSiPkgTokenSpaceGuid.PcdPpmEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable        |FALSE
+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.PcdIpuEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE
+gSiPkgTokenSpaceGuid.PcdCflCpuEnable                 |FALSE
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |TRUE
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |TRUE
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE
+
+[PcdsFixedAtBuild.common]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress       |0xE0000000
+gSiPkgTokenSpaceGuid.PcdTemporaryPciExpressRegionLength |0x10000000
+
+  gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin        |10
+  gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax        |18
+
+[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 = CoffeelakeSiliconPkg
+  PLATFORM_GUID = A45CA44C-AB04-4932-A77C-5A7179F66A22
+  PLATFORM_VERSION = 0.4
+  DSC_SPECIFICATION = 0x00010005
+  OUTPUT_DIRECTORY = Build/CoffeelakeSiliconPkg
+  SUPPORTED_ARCHITECTURES = IA32|X64
+  BUILD_TARGETS = DEBUG|RELEASE
+  SKUID_IDENTIFIER = DEFAULT
+
+  DEFINE   PLATFORM_SI_PACKAGE        = CoffeelakeSiliconPkg
+
+  #
+  # 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|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.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
+  SmiHandlerProfileLib|Edk2/MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.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
+  PostCodeLib|MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  MtrrLib|ClientSiliconPkg/Override/UefiCpuPkg/Library/MtrrLib/MtrrLib.inf  # CSPO-0012: RoyalParkOverrideContent
+  RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+
+#####################################################################################################
+
+#
+# Silicon Init Common Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
+ConfigBlockLib|ClientSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
+PchTraceHubInitLib|ClientSiliconPkg/Library/BasePchTraceHubInitLib/BasePchTraceHubInitLib.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
+
+#####################################################################################################################################
+
+#
+# Silicon Init Pei Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
+
+[LibraryClasses.IA32.SEC]
+
+[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
+  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
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
new file mode 100644
index 0000000000..b6d2058669
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
@@ -0,0 +1,130 @@
+## @file
+# Silicon build option configuration file.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[BuildOptions]
+# Define Build Options both for EDK and EDKII drivers.
+
+# SA
+!if gSiPkgTokenSpaceGuid.PcdPttEnable == TRUE
+  DEFINE PTT_BUILD_OPTION = -DPTT_FLAG=1
+!else
+  DEFINE PTT_BUILD_OPTION =
+!endif
+
+#
+# System Agent
+#
+!if gSiPkgTokenSpaceGuid.PcdSgEnable == TRUE
+  DEFINE DSC_SG_BUILD_OPTIONS = -DSG_SUPPORT=1
+!else
+  DEFINE DSC_SG_BUILD_OPTIONS =
+!endif
+
+!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 =
+
+!if gSiPkgTokenSpaceGuid.PcdCflCpuEnable == TRUE
+  DEFINE CPU_FLAGS = -DCPU_CFL
+!else
+  DEFINE CPU_FLAGS =
+!endif
+
+
+DEFINE DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(BDAT_BUILD_OPTION) $(PTT_BUILD_OPTION) $(DEBUG_BUILD_OPTIONS)
+DEFINE DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(DSC_SG_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(CPU_FLAGS) $(HSLE_BUILD_OPTIONS) $(RELEASE_CATALOG_BUILD_OPTIONS) $(DSC_TXT_BUILD_OPTIONS)
+
+!if gSiPkgTokenSpaceGuid.PcdSourceDebugEnable == TRUE
+  *_*_X64_GENFW_FLAGS = --keepexceptiontable
+!endif
+
+[BuildOptions.Common.EDKII]
+
+#
+# For IA32 Global Build Flag
+#
+       *_*_IA32_PP_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_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
+#
+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
+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_PP_FLAGS       = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_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
+#
+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
+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/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
new file mode 100644
index 0000000000..2df08c6d01
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
@@ -0,0 +1,69 @@
+## @file
+#  Component description file for the Coffee Lake silicon package both PEI and DXE libraries DSC file.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Set PCH generation according PCD.
+# The DEFINE will be used to select PCH library INF file corresponding to PCH generation
+#
+DEFINE  PCH = Cnl
+
+#
+# Cpu
+#
+ CpuPlatformLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
+ CpuMailboxLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
+
+#
+# Me
+#
+
+#
+# Pch
+#
+ PchCycleDecodingLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
+ PchGbeLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
+ PchInfoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLib$(PCH).inf
+ SataLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLib$(PCH).inf
+ PchPcieRpLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
+ PchPcrLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
+ PmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
+
+ PchSbiAccessLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
+ GpioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
+!if gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable == TRUE
+ PchSerialIoUartLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
+!else
+ PchSerialIoUartLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BasePchSerialIoUartLibNull/BasePchSerialIoUartLibNull.inf
+!endif
+ PchSerialIoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
+ PchEspiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
+ PchWdtCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
+ SmbusLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
+ BiosLockLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
+ #private
+ PchPciExpressHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
+ PchInitCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
+ PchSpiCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
+ GpioPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
+ PchPsfPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLib$(PCH).inf
+ PmcPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
+ PmcPrivateLibWithS3|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
+ PchDmiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
+ PchDmiWithS3Lib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
+ SiScheduleResetLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
+
+#
+# SA
+#
+ SaPlatformLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
+
+#
+# Memory
+#
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
new file mode 100644
index 0000000000..07677ece1a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
@@ -0,0 +1,33 @@
+## @file
+#  Component description file for the Coffee Lake silicon package DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Common
+#
+
+#
+# Pch
+#
+  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
+  $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
+
+  $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
+
+  $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
+  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
+
+#
+# SystemAgent
+#
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
+
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
+!endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
new file mode 100644
index 0000000000..214de06d58
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
@@ -0,0 +1,37 @@
+## @file
+#  Component description file for the Coffee Lake silicon package DXE libraries.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Silicon Init Dxe Library
+#
+
+#
+# Common
+#
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+ AslUpdateLib|$(PLATFORM_SI_PACKAGE)/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
+!else
+ AslUpdateLib|$(PLATFORM_SI_PACKAGE)/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
+!endif
+ SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
+
+#
+# Pch
+#
+ PchHdaLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf
+ DxePchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
+ GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
+ GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
+ SmmPchPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf
+
+#
+# SystemAgent
+#
+ DxeSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
new file mode 100644
index 0000000000..f30c7e0ae1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
@@ -0,0 +1,21 @@
+## @file
+#  Component description file for theCoffee Lake silicon package PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Common
+#
+
+#
+# SystemAgent
+#
+
+#
+# Cpu
+#
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
new file mode 100644
index 0000000000..6e244a6ded
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
@@ -0,0 +1,44 @@
+## @file
+#  Component description file for the Coffee Lake silicon package PEI libraries.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Silicon Init Pei Library
+#
+ SiPolicyLib|$(PLATFORM_SI_PACKAGE)/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
+ SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
+ StallPpiLib|$(PLATFORM_SI_PACKAGE)/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
+
+#
+# Pch
+#
+ PchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
+!if gSiPkgTokenSpaceGuid.PcdOcWdtEnable == TRUE
+ OcWdtLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
+!else
+ OcWdtLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
+!endif
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
+ PchResetLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
+ SpiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiSpiLib/PeiSpiLib.inf
+ GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
+ GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
+
+#
+# Me
+#
+ PeiMePolicyLib|$(PLATFORM_SI_PACKAGE)/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf
+
+#
+# SA
+#
+  PeiSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
+#
+# Cpu
+#
+ CpuPolicyLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (28 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
                   ` (7 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Liming Gao,
	Michael D Kinney

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

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Maintainers.txt | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Maintainers.txt b/Maintainers.txt
index 876ae5612a..bc8cbd6458 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -125,9 +125,14 @@ Silicon/Intel/Vlv2DeviceRefCodePkg
 M: Zailiang Sun <zailiang.sun@intel.com>
 M: Yi Qian <yi.qian@intel.com>
 
+Silicon/Intel/CoffeelakeSiliconPkg
+M: Chasel Chiu <chasel.chiu@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
+M: Sai Chaganty <rangasai.v.chaganty@intel.com>
+
 Silicon/Intel/KabylakeSiliconPkg
 M: Chasel Chiu <chasel.chiu@intel.com>
-M: Michael A Kubacki <michael.a.kubacki@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
 M: Sai Chaganty <rangasai.v.chaganty@intel.com>
 
 Silicon/Intel/LewisburgPkg
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (29 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
                   ` (6 subsequent siblings)
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

Create the WhiskeylakeOpenBoardPkg to provide board support code. The
package may support Coffee Lake (CFL) and Whiskey Lake (WHL) boards. The
package serves as a board support package in the EDK II Minimum Platform
design. Silicon support for this package is provided in CoffeeLakeFspBinPkg
in the FSP repository and CoffeelakeSiliconPkg in the edk2-platforms
repository.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec                                           |  565 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h     |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h             |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h           |  131 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h     |   21 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h             |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h       |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h                |  261 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h                    |   31 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h      |  130 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h         |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h               |  137 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h                 |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h                        |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h                       |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h           |   84 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h                            |  118 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h                                  |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h                                           |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h                           |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h                                     | 1766 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h                                   |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h                                       |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h                    |   75 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h                     |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h                    |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h                  |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h                     |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h                         |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h                     |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h                          |  123 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h                          |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h                             |   34 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h                           |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h                  |  141 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h                         |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h                          |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h                                |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h                          |  106 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h                                         |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h                                  |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h                           |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h                                            |  144 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h                                          |  157 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl                                 |  112 ++
 46 files changed, 5288 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
new file mode 100644
index 0000000000..9d56f0e841
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
@@ -0,0 +1,565 @@
+## @file
+# Module describe the entire platform configuration.
+#
+# The DEC files are used by the utilities that parse DSC and
+# INF files to generate AutoGen.c and AutoGen.h files
+# for the build infrastructure.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+
+[Defines]
+DEC_SPECIFICATION = 0x00010017
+PACKAGE_NAME = OpenBoardPkg
+PACKAGE_VERSION = 0.1
+PACKAGE_GUID = 0A8BA6E8-C8AC-4AC1-87AC-52772FA6AE5E
+
+[Includes]
+Include
+WhiskeylakeURvp\Include
+Features\Tbt\Include
+
+[Guids]
+
+gBoardModuleTokenSpaceGuid            =  {0x72d1fff7, 0xa42a, 0x4219, {0xb9, 0x95, 0x5a, 0x67, 0x53, 0x6e, 0xa4, 0x2a}}
+
+gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+
+gTbtInfoHobGuid                       =  {0x74a81eaa, 0x033c, 0x4783, {0xbe, 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}}
+
+gPlatformModuleTokenSpaceGuid         =  {0x69d13bf0, 0xaf91, 0x4d96, {0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0}}
+
+gMeInfoSetupGuid                      =  {0x78259433, 0x7b6d, 0x4db3, {0x9a, 0xe8, 0x36, 0xc4, 0xc2, 0xc3, 0xa1, 0x7d}}
+gRealModeFileGuid                     =  {0xdf84ed23, 0x5d53, 0x423f, {0xaa, 0x81, 0x0f, 0x0e, 0x6f, 0x55, 0xc6, 0x9b}}
+gVirtualKeyboardDriverImageGuid       =  {0xe4735aac, 0x9c27, 0x493f, {0x86, 0xea, 0x9e, 0xff, 0x43, 0xd7, 0xad, 0xcd}}
+gPegConfigVariableGuid                =  {0xb414caf8, 0x8225, 0x4d6f, {0xb9, 0x18, 0xcd, 0xe5, 0xcb, 0x84, 0xcf, 0x0b}}
+gSaSetupVariableGuid                  =  {0x72c5e28c, 0x7783, 0x43a1, {0x87, 0x67, 0xfa, 0xd7, 0x3f, 0xcc, 0xaf, 0xa4}}
+gMeSetupVariableGuid                  =  {0x5432122d, 0xd034, 0x49d2, {0xa6, 0xde, 0x65, 0xa8, 0x29, 0xeb, 0x4c, 0x74}}
+gCpuSetupVariableGuid                 =  {0xb08f97ff, 0xe6e8, 0x4193, {0xa9, 0x97, 0x5e, 0x9e, 0x9b, 0xa,  0xdb, 0x32}}
+gCpuSmmGuid                           =  {0x90d93e09, 0x4e91, 0x4b3d, {0x8c, 0x77, 0xc8, 0x2f, 0xf1, 0xe,  0x3c, 0x81}}
+gPchSetupVariableGuid                 =  {0x4570b7f1, 0xade8, 0x4943, {0x8d, 0xc3, 0x40, 0x64, 0x72, 0x84, 0x23, 0x84}}
+gSiSetupVariableGuid                  =  {0xAAF8E719, 0x48F8, 0x4099, {0xA6, 0xF7, 0x64, 0x5F, 0xBD, 0x69, 0x4C, 0x3D}}
+gDebugConfigVariableGuid              =  {0xDE0A5E74, 0x4E3E, 0x3D96, {0xA4, 0x40, 0x2C, 0x96, 0xEC, 0xBD, 0x3C, 0x97}}
+gDebugConfigHobGuid                   =  {0x2f6a6bb7, 0x9dc7, 0x4bf6, {0x94, 0x04, 0x22, 0x70, 0xc0, 0xe3, 0xbe, 0x2f}}
+gChassisIntrudeDetHobGuid             =  {0xdea43de2, 0x756b, 0x4b3b, {0x75, 0x1c, 0xad, 0xeb, 0x8d, 0xff, 0x56, 0xa3}}
+
+gGpioCheckConflictHobGuid             =  {0x5603f872, 0xefac, 0x40ae, {0xb9, 0x7e, 0x13, 0xb2, 0xf8, 0x07, 0x80, 0x21}}
+
+gAttemptUsbFirstHotkeyInfoHobGuid     =  {0x38b8e214, 0x1468, 0x4bb7, {0x95, 0xb1, 0x74, 0x59, 0x1e, 0x4c, 0x6e, 0x1d}}
+gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+##
+## ChipsetInitBinary
+##
+gCnlPchLpChipsetInitTableDxGuid          =  {0xc9505bc0, 0xaa3d, 0x4056, {0x99, 0x95, 0x87, 0x0c, 0x8d, 0xe8, 0x59, 0x4e}}
+
+
+[Protocols]
+gTbtNvsAreaProtocolGuid               =  {0x4d6a54d1, 0xcd56, 0x47f3, {0x93, 0x6e, 0x7e, 0x51, 0xd9, 0x31, 0x15, 0x4f}}
+gDxeTbtPolicyProtocolGuid             =  {0x196bf9e3, 0x20d7, 0x4b7b, {0x89, 0xf9, 0x31, 0xc2, 0x72, 0x08, 0xc9, 0xb9}}
+
+[Ppis]
+gPeiTbtPolicyPpiGuid                  =  {0xd7e7e1e6, 0xcbec, 0x4f5f, {0xae, 0xd3, 0xfd, 0xc0, 0xa8, 0xb0, 0x7e, 0x25}}
+gPeiTbtPolicyBoardInitDonePpiGuid     =  {0x970f9c60, 0x8547, 0x49d7, { 0xa4, 0xb, 0x1e, 0xc4, 0xbc, 0x4e, 0xe8, 0x9b}}
+
+[LibraryClasses]
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+
+[PcdsFixedAtBuild]
+
+gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange|0x0010|UINT16|0x10001004
+gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding|0x3c03|UINT16|0x10001005
+
+gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress|0xFED18000|UINT64|0x90000003
+gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize|0x1000|UINT32|0x90000004
+gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress|0xFED19000|UINT64|0x90000005
+gPlatformModuleTokenSpaceGuid.PcdEpMmioSize|0x1000|UINT32|0x90000006
+gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress|0xFED84000|UINT64|0x90000007
+gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize|0x1000|UINT32|0x90000008
+gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress|0xFED80000|UINT64|0x90000009
+gPlatformModuleTokenSpaceGuid.PcdEdramMmioSize|0x4000|UINT32|0x9000000A
+gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress|0xFEE00000|UINT64|0x9000000B
+gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize|0x1000|UINT32|0x9000000C
+gPlatformModuleTokenSpaceGuid.PcdApicIoAddress|0xFEC00000|UINT64|0x9000000D
+gPlatformModuleTokenSpaceGuid.PcdApicIoMmioSize|0x1000|UINT32|0x9000000E
+gPlatformModuleTokenSpaceGuid.PcdGttMmAddress|0xCF000000|UINT64|0x9000000F
+gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress|0xD0000000|UINT64|0x90000010
+gPlatformModuleTokenSpaceGuid.PcdAcpiEnableSwSmi|0xF0|UINT8|0x90000012
+gPlatformModuleTokenSpaceGuid.PcdAcpiDisableSwSmi|0xF1|UINT8|0x90000013
+gPlatformModuleTokenSpaceGuid.PcdPcieDockBridgeResourcePatchSmi|0x4D|UINT8|0x90000014
+gPlatformModuleTokenSpaceGuid.PcdCmosFastBootDefaultValue|0x01|UINT8|0x90000016
+gPlatformModuleTokenSpaceGuid.PcdCmosDebugPrintErrorLevelDefaultValue|0x80000046|UINT32|0x90000017
+gPlatformModuleTokenSpaceGuid.PcdOverClockingInterfaceSwSmi|0x72|UINT8|0x90000019
+gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort|0x2F|UINT16|0x9000001A
+gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort|0x2E|UINT16|0x9000001B
+gPlatformModuleTokenSpaceGuid.PcdApicIoIdPch|0x02|UINT8|0x9000001E
+gPlatformModuleTokenSpaceGuid.PcdRuntimeUpdateFvHeaderLength|0x48|UINT8|0x90000020
+gPlatformModuleTokenSpaceGuid.PcdEcExtraIoBase|0x6A0|UINT16|0x20000505
+gPlatformModuleTokenSpaceGuid.PcdFspTemporaryRamSize|0x1000|UINT32|0x10001003
+
+gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition|0x01|UINT8|0x90000015
+gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort|0x4e|UINT16|0x90000018
+gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort|0x164E|UINT16|0x9000001C
+gBoardModuleTokenSpaceGuid.PcdSioBaseAddress|0x0680|UINT16|0x9000001D
+gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort|0x4f|UINT16|0x9000001F
+gBoardModuleTokenSpaceGuid.PcdLpcSioIndexDefaultPort|0x164E|UINT16|0x90000021
+gBoardModuleTokenSpaceGuid.PcdLpcSioDataDefaultPort|0x164F|UINT16|0x90000022
+
+[PcdsDynamic]
+# Board GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable|0|UINT32|0x00000040
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize|0|UINT16|0x00000041
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2|0|UINT32|0x00000042
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size|0|UINT16|0x00000043
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem|0|UINT32|0x000000113
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize|0|UINT16|0x000000114
+
+# Board Expander GPIO Table
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable|0|UINT32|0x00000044
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize|0|UINT16|0x00000045
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2|0|UINT32|0x00000046
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size|0|UINT16|0x00000047
+
+# TouchPanel & SDHC CD GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel|0|UINT32|0x00000048
+
+# PCH-LP HSIO PTSS Table
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1|0|UINT32|0x0000004A
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2|0|UINT32|0x0000004B
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size|0|UINT16|0x0000004C
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size|0|UINT16|0x0000004D
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1|0|UINT32|0x0000004E
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2|0|UINT32|0x0000004F
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size|0|UINT16|0x00000050
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size|0|UINT16|0x00000051
+
+# PCH-H HSIO PTSS Table
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1|0|UINT32|0x00000052
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2|0|UINT32|0x00000053
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size|0|UINT16|0x00000054
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size|0|UINT16|0x00000055
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1|0|UINT32|0x00000056
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2|0|UINT32|0x00000057
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size|0|UINT16|0x00000058
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size|0|UINT16|0x00000059
+
+# HDA Verb Table
+gBoardModuleTokenSpaceGuid.PcdHdaVerbTable|0|UINT32|0x0000005A
+gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2|0|UINT32|0x0000005B
+gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable|0|UINT32|0x0000005C
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1|0|UINT32|0x0000005D
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2|0|UINT32|0x0000005E
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3|0|UINT32|0x0000005F
+gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable|0|UINT32|0x00000060
+
+# SA Misc Configuration
+gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd|0|UINT8|0x00000066
+gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment|0|UINT16|0x00000067
+gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit|0|UINT16|0x00000101
+
+# DRAM Configuration
+gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor|0|UINT32|0x00000068
+gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget|0|UINT32|0x00000069
+gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap|0|UINT32|0x0000006A
+gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize|0|UINT16|0x0000006B
+gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram|0|UINT32|0x0000006C
+gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize|0|UINT16|0x0000006D
+gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl|FALSE|BOOLEAN|0x0000006E
+gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved|FALSE|BOOLEAN|0x0000006F
+gBoardModuleTokenSpaceGuid.PcdMrcSpdData|0|UINT32|0x00000070
+gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize|0|UINT16|0x00000071
+
+# PEG RESET GPIO
+gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl|FALSE|BOOLEAN|0x00000072
+gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort|FALSE|BOOLEAN|0x00000073
+gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo|0|UINT32|0x00000079
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo|0|UINT8|0x0000007A
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo|0|UINT32|0x0000007B
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive|FALSE|BOOLEAN|0x0000007C
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo|0|UINT8|0x0000007D
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo|0|UINT32|0x0000007E
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive|FALSE|BOOLEAN|0x0000007F
+
+# SPD Address Table
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0|0|UINT8|0x00000099
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1|0|UINT8|0x0000009A
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2|0|UINT8|0x0000009B
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3|0|UINT8|0x0000009C
+
+# CA Vref Configuration
+gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig|0|UINT8|0x0000009D
+
+# USB 2.0 Port AFE
+gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe|0|UINT32|0x000000BF
+gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe|0|UINT32|0x000000C0
+gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe|0|UINT32|0x000000C1
+gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe|0|UINT32|0x000000C2
+gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe|0|UINT32|0x000000C3
+gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe|0|UINT32|0x000000C4
+gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe|0|UINT32|0x000000C5
+gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe|0|UINT32|0x000000C6
+gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe|0|UINT32|0x000000C7
+gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe|0|UINT32|0x000000C8
+gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe|0|UINT32|0x000000C9
+gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe|0|UINT32|0x000000CA
+gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe|0|UINT32|0x000000CB
+gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe|0|UINT32|0x000000CC
+gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe|0|UINT32|0x000000CD
+gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe|0|UINT32|0x000000CE
+
+# USB 2.0 Port Over Current Pin
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0|0|UINT8|0x000000CF
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1|0|UINT8|0x000000D0
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2|0|UINT8|0x000000D1
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3|0|UINT8|0x000000D2
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4|0|UINT8|0x000000D3
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5|0|UINT8|0x000000D4
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6|0|UINT8|0x000000D5
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7|0|UINT8|0x000000D6
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8|0|UINT8|0x000000D7
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9|0|UINT8|0x000000D8
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10|0|UINT8|0x000000D9
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11|0|UINT8|0x000000DA
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12|0|UINT8|0x000000DB
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13|0|UINT8|0x000000DC
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14|0|UINT8|0x000000DD
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15|0|UINT8|0x000000DE
+
+# USB 3.0 Port Over Current Pin
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0|0|UINT8|0x000000DF
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1|0|UINT8|0x000000E0
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2|0|UINT8|0x000000E1
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3|0|UINT8|0x000000E2
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4|0|UINT8|0x000000E3
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5|0|UINT8|0x000000E4
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6|0|UINT8|0x000000E5
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7|0|UINT8|0x000000E6
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8|0|UINT8|0x000000E7
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9|0|UINT8|0x000000E8
+
+# Misc
+gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent|FALSE|BOOLEAN|0x000000EC
+
+# TBT
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel |0|BOOLEAN|0x000000F3
+gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad |0|UINT32|0x000000F4
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad |0|UINT32|0x000000F5
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport |0|UINT8|0x000000FA
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI |0|UINT8|0x000000FB
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify |0|UINT8|0x000000FC
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq|0|UINT8|0x000000FD
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm |0|UINT8|0x000000FE
+gBoardModuleTokenSpaceGuid.PcdDTbtLtr | 0 | UINT8| 0x00000116
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch |0|UINT8|0x000000FF
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt |0|UINT8|0x00000100
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq |0|UINT8|0x0000010A
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax |0|UINT8|0x00000107
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd |0|UINT16|0x00000108
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax |0|UINT8|0x00000109
+
+# UCMC GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable|0|UINT32|0x000000111
+gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize|0|UINT16|0x000000112
+
+gBoardModuleTokenSpaceGuid.PcdAcpiSleepState|1|UINT8|0x40000002
+gBoardModuleTokenSpaceGuid.PcdAcpiHibernate|1|UINT8|0x40000003
+gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle|0|UINT8|0x40000004
+gBoardModuleTokenSpaceGuid.PcdPciExpNative|0|UINT8|0x40000005
+gBoardModuleTokenSpaceGuid.PcdNativeAspmEnable|1|UINT8|0x40000006
+gBoardModuleTokenSpaceGuid.PcdPs2KbMsEnable|0|UINT8|0x40000009
+gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints|1|UINT8|0x4000000A
+gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints|0|UINT8|0x4000000B
+gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints|1|UINT8|0x4000000C
+
+# 0: Type-C
+# 1: Stacked-Jack
+gBoardModuleTokenSpaceGuid.PcdAudioConnector|0|UINT8|0x40000012
+
+gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress|0|UINT64|0x40000013
+
+# gIntelPeiGraphicsVbtGuid =  {0x4ad46122, 0xffeb, 0x4a52, {0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}}
+gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid|{0x22, 0x61, 0xd4, 0x4a, 0xeb, 0xff, 0x52, 0x4a, 0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}|VOID*|0x40000014
+#==============================================================
+#
+# The PCD which indicates the Memory Slot Population.
+#
+gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType|FALSE|BOOLEAN|0x00101027
+gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate|0|UINT64|0x00000010
+
+# Board GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem|0|UINT32|0x001000115
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize|0|UINT16|0x001000116
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem|0|UINT32|0x001000117
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize|0|UINT16|0x001000118
+gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio|0x0|UINT32|0x0010020C
+gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity|0x0|UINT8|0x0010022E
+gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio|0x0|UINT32|0x0010022F
+gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio|0x0|UINT32|0x00100230
+gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable|FALSE|BOOLEAN|0x00100231
+gBoardModuleTokenSpaceGuid.PcdWlanWakeGpio|0x0|UINT32|0x00100234
+gBoardModuleTokenSpaceGuid.PcdWlanRootPortNumber|0x0|UINT8|0x00100235
+gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround|FALSE|BOOLEAN|0x00100236
+
+# UCMC GPIO Table
+gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable|0|UINT32|0x00100033
+gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize|0|UINT16|0x00100034
+
+# PEG RESET GPIO
+gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad|0|UINT32|0x00000074
+gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive|FALSE|BOOLEAN|0x00000075
+gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad|0|UINT32|0x00000105
+gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive|FALSE|BOOLEAN|0x00000106
+
+# PCIE RTD3 GPIO
+gBoardModuleTokenSpaceGuid.PcdRootPortDev|0xFF|UINT8|0x00000076
+gBoardModuleTokenSpaceGuid.PcdRootPortFunc|0xFF|UINT8|0x00000077
+gBoardModuleTokenSpaceGuid.PcdRootPortIndex|0xFF|UINT8|0x00000104
+gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport|0|UINT8|0x00000078
+
+gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport|0|UINT8|0x00000080
+gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo|0|UINT32|0x00000081
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo|0|UINT8|0x00000082
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo|0|UINT32|0x00000083
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive|FALSE|BOOLEAN|0x00000084
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo|0|UINT8|0x00000085
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo|0|UINT32|0x00000086
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive|FALSE|BOOLEAN|0x00000087
+
+gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport|0|UINT8|0x00000088
+gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo|0|UINT32|0x00000089
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo|0|UINT8|0x0000008A
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo|0|UINT32|0x0000008B
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive|FALSE|BOOLEAN|0x0000008C
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo|0|UINT8|0x0000008D
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo|0|UINT32|0x0000008E
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive|FALSE|BOOLEAN|0x0000008F
+gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport|0|UINT8|0x00000130
+gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo|0|UINT32|0x00000131
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo|0|UINT8|0x00000132
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo|0|UINT32|0x00000133
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive|FALSE|BOOLEAN|0x00000134
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo|0|UINT8|0x00000135
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo|0|UINT32|0x00000136
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive|FALSE|BOOLEAN|0x00000137
+
+# Root Port Clock Info
+gBoardModuleTokenSpaceGuid.PcdPcieClock0|0|UINT64|0x0000009E
+gBoardModuleTokenSpaceGuid.PcdPcieClock1|0|UINT64|0x0000009F
+gBoardModuleTokenSpaceGuid.PcdPcieClock2|0|UINT64|0x000000A0
+gBoardModuleTokenSpaceGuid.PcdPcieClock3|0|UINT64|0x000000A1
+gBoardModuleTokenSpaceGuid.PcdPcieClock4|0|UINT64|0x000000A2
+gBoardModuleTokenSpaceGuid.PcdPcieClock5|0|UINT64|0x000000A3
+gBoardModuleTokenSpaceGuid.PcdPcieClock6|0|UINT64|0x000000A4
+gBoardModuleTokenSpaceGuid.PcdPcieClock7|0|UINT64|0x000000A5
+gBoardModuleTokenSpaceGuid.PcdPcieClock8|0|UINT64|0x000000A6
+gBoardModuleTokenSpaceGuid.PcdPcieClock9|0|UINT64|0x000000A7
+gBoardModuleTokenSpaceGuid.PcdPcieClock10|0|UINT64|0x000000A8
+gBoardModuleTokenSpaceGuid.PcdPcieClock11|0|UINT64|0x000000A9
+gBoardModuleTokenSpaceGuid.PcdPcieClock12|0|UINT64|0x000000AA
+gBoardModuleTokenSpaceGuid.PcdPcieClock13|0|UINT64|0x000000AB
+gBoardModuleTokenSpaceGuid.PcdPcieClock14|0|UINT64|0x000000AC
+gBoardModuleTokenSpaceGuid.PcdPcieClock15|0|UINT64|0x000000AD
+
+# GPIO Group Tier
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0|0|UINT32|0x000000E9
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1|0|UINT32|0x000000EA
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2|0|UINT32|0x000000EB
+
+# Board related PCH PmConfig
+gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl|FALSE|BOOLEAN|0x000000F6
+gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport|FALSE|BOOLEAN|0x000000F7
+gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport|FALSE|BOOLEAN|0x000000F8
+
+# Misc
+gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent|FALSE|BOOLEAN|0x000000ED
+gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable|FALSE|BOOLEAN|0x000000EE
+gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent|FALSE|BOOLEAN|0x000000EF
+gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio|0|UINT64|0x000000F0
+gBoardModuleTokenSpaceGuid.PcdMobileDramPresent|FALSE|BOOLEAN|0x000000F1
+gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable|FALSE|BOOLEAN|0x000000F2
+gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable|FALSE|BOOLEAN|0x000000F9
+#gBoardModuleTokenSpaceGuid.PcdxxxNotInUse|FALSE|BOOLEAN|0x000000FC
+
+#PlatformInfoPcd
+gBoardModuleTokenSpaceGuid.PcdEnableVoltageMargining|FALSE|BOOLEAN|0x00101000
+gBoardModuleTokenSpaceGuid.PcdGfxCrbDetect|FALSE|BOOLEAN|0x00101001
+gBoardModuleTokenSpaceGuid.PcdHsioBoardPresent|FALSE|BOOLEAN|0x00101002
+gBoardModuleTokenSpaceGuid.PcdHsioBoardType|0x0|UINT8|0x00101003
+gBoardModuleTokenSpaceGuid.PcdWakeupType|0x0|UINT8|0x00101004
+gBoardModuleTokenSpaceGuid.PcdMfgMode|FALSE|BOOLEAN|0x00101005
+gBoardModuleTokenSpaceGuid.PcdBoardName|L"0123456789ABCDEF0123456789ABCDEF"|VOID*|0x00101007
+gBoardModuleTokenSpaceGuid.PcdEcMajorRevision|0x0|UINT8|0x00101008
+gBoardModuleTokenSpaceGuid.PcdEcMinorRevision|0x0|UINT8|0x00101009
+gBoardModuleTokenSpaceGuid.PcdBiosVersion|L"0123456789012345678901234567890123456789"|VOID*|0x0010100E
+gBoardModuleTokenSpaceGuid.PcdReleaseDate|L"01234567890123456789"|VOID*|0x0010100F
+gBoardModuleTokenSpaceGuid.PcdReleaseTime|L"01234567890123456789"|VOID*|0x00101010
+gBoardModuleTokenSpaceGuid.PcdPlatformGeneration|0x0|UINT8|0x00101011
+gBoardModuleTokenSpaceGuid.PcdSpdPresent|FALSE|BOOLEAN|0x00101012
+gBoardModuleTokenSpaceGuid.PcdDockAttached|FALSE|BOOLEAN|0x00101013
+gBoardModuleTokenSpaceGuid.PcdPlatformType|0x0|UINT8|0x00101014
+gBoardModuleTokenSpaceGuid.PcdPlatformFlavor|0x0|UINT8|0x00101015
+gBoardModuleTokenSpaceGuid.PcdBoardRev|0x0|UINT8|0x00101016
+gBoardModuleTokenSpaceGuid.PcdBoardBomId|0x0|UINT8|0x00101017
+gBoardModuleTokenSpaceGuid.PcdBoardId|0x0|UINT8|0x00101018
+gBoardModuleTokenSpaceGuid.PcdBoardType|0x0|UINT8|0x00101019
+gBoardModuleTokenSpaceGuid.PcdEcPresent|FALSE|BOOLEAN|0x0010101A
+
+# PCH Misc Configuration
+gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable|FALSE|BOOLEAN|0x00000061
+gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable|FALSE|BOOLEAN|0x00000065
+gBoardModuleTokenSpaceGuid.PcdSmbiosFabBoardName|0|UINT64|0x00000102
+gBoardModuleTokenSpaceGuid.PcdSmbiosMainSlotEntry|0|UINT64|0x00000103
+gBoardModuleTokenSpaceGuid.PcdUsbcEcPdNegotiation|FALSE|BOOLEAN|0x00000110
+
+# Control PCD to dump default silicon policy
+gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy|FALSE|BOOLEAN|0x00010064
+
+# Pch SerialIo I2c Pads Termination
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm|0x1|UINT8|0x00000020
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm|0x1|UINT8|0x00000021
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm|0x1|UINT8|0x00000022
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm|0x1|UINT8|0x00000023
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm|0x1|UINT8|0x00000030
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm|0x1|UINT8|0x00000031
+#
+# The PCD which holds the pointer of Smbios Platform Info table
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosPlatformInfo|0|UINT64|0x0010101B
+#
+# The PCD which used to enable / disable the code to use RVP Smbios Board Info
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfoEnable|FALSE|BOOLEAN|0x0010101C
+#
+# The PCD which holds the pointer of RVP Smbios Board Info
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfo|0|UINT64|0x0010101D
+#
+# CoEngineering Custom Defaults PCD
+#
+gBoardModuleTokenSpaceGuid.PcdCoEngEnableCustomDefaults|0x0|UINT8|0x00100227
+#
+# The PCD which is defined to enable/disable the SMBus Alert function.
+#
+gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable|FALSE|BOOLEAN|0x0010101E
+#
+# The PCD which is defined to enable/disable the SATA LED function.
+#
+gBoardModuleTokenSpaceGuid.PcdSataLedEnable|FALSE|BOOLEAN|0x0010101F
+#
+# The PCD which is defined to enable/disable the VR Alert function.
+#
+gBoardModuleTokenSpaceGuid.PcdVrAlertEnable|FALSE|BOOLEAN|0x00101020
+#
+# The PCD which is defined to enable/disable the PCH thermal hot threshold function.
+#
+gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable|FALSE|BOOLEAN|0x00101021
+#
+# The PCD which is defined to enable/disable the memory thermal sensor GPIO C/D function.
+#
+gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEnable|TRUE|BOOLEAN|0x00101022
+gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEnable|TRUE|BOOLEAN|0x00101023
+#
+# The PCD defines the I2C bus number to which PSS chip connected.
+#
+gBoardModuleTokenSpaceGuid.PcdPssReadSN|FALSE|BOOLEAN|0x00101024
+gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber|0x04|UINT8|0x00101025
+gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress|0x6E|UINT8|0x00101026
+#
+# The PCD defines the USB port number to which BLE connected.
+#
+gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber                     |0x0|UINT8|0x00101028
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support                    |0x00|UINT8|0x00100113
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support                    |0x00|UINT8|0x00100114
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support                    |0x00|UINT8|0x00100115
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support                    |0x00|UINT8|0x00100116
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support                    |0x00|UINT8|0x00100117
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support                    |0x00|UINT8|0x00100118
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport         |FALSE|BOOLEAN|0x00100119
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport       |FALSE|BOOLEAN|0x0010011A
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport       |FALSE|BOOLEAN|0x0010011B
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport     |FALSE|BOOLEAN|0x0010011C
+gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport               |FALSE|BOOLEAN|0x0010011D
+gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport                |FALSE|BOOLEAN|0x0010011F
+gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin                 |0x00|UINT32|0x00100120
+gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport           |FALSE|BOOLEAN|0x00100121
+gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport           |FALSE|BOOLEAN|0x00100122
+gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature                  |FALSE|BOOLEAN|0x00100123
+gBoardModuleTokenSpaceGuid.PcdBatteryPresent                       |0x0|UINT8|0x00100124
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport|FALSE|BOOLEAN|0x00100212
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess|FALSE|BOOLEAN|0x00100213
+gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature|0x0|UINT64|0x00100204
+gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile|0x0|UINT8|0x00100205
+gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio|0x0|UINT32|0x00100209
+gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio|0x0|UINT32|0x0010020A
+gBoardModuleTokenSpaceGuid.PcdGnssResetGpio|0x0|UINT32|0x0010020B
+gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio|0x0|UINT32|0x0010020F
+gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio|0x0|UINT32|0x00100210
+
+gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio                   |0x0|UINT32|0x00100126
+gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber              |0x0|UINT8|0x00100127
+gBoardModuleTokenSpaceGuid.PcdEcSmiGpio|0x0|UINT32|0x00100200
+gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio                   |0x0|UINT32|0x00100125
+gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad|0x0|UINT32|0x00100201
+gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck|FALSE|BOOLEAN|0x00100202
+gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride|FALSE|BOOLEAN|0x00100203
+gBoardModuleTokenSpaceGuid.PcdDDISelection|0x0|UINT8|0x00100215
+gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio|0x0|UINT64|0x00100217
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1|0x00|UINT8|0x00100039
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch|0x00|UINT8|0x0010003A
+gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties|0x00|UINT8|0x0010003B
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2|0x00|UINT8|0x0010003C
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch|0x00|UINT8|0x0010003D
+gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties|0x00|UINT8|0x0010003E
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3|0x00|UINT8|0x0010003F
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch|0x00|UINT8|0x00100040
+gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties|0x00|UINT8|0x00100041
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4|0x00|UINT8|0x00100042
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch|0x00|UINT8|0x00100043
+gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties|0x00|UINT8|0x00100044
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5|0x00|UINT8|0x00100045
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch|0x00|UINT8|0x00100046
+gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties|0x00|UINT8|0x00100047
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6|0x00|UINT8|0x00100048
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch|0x00|UINT8|0x00100049
+gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties|0x00|UINT8|0x0010004A
+gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed                     |0x0|UINT8|0x00100128
+gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed                     |0x0|UINT8|0x00100129
+gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed                     |0x0|UINT8|0x0010012A
+gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed                     |0x0|UINT8|0x0010012B
+
+# Super IO Pcd
+gPlatformModuleTokenSpaceGuid.PcdH8S2113Present|TRUE|BOOLEAN|0xF0000100
+gPlatformModuleTokenSpaceGuid.PcdNat87393Present|TRUE|BOOLEAN|0xF0000104
+gPlatformModuleTokenSpaceGuid.PcdNct677FPresent|TRUE|BOOLEAN|0xF0000105
+gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport               |FALSE|BOOLEAN|0x00100112
+gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin                     |0x00|UINT32|0x00100111
+gBoardModuleTokenSpaceGuid.PcdRealBattery1Control                  |0x00|UINT8|0x00100103
+gBoardModuleTokenSpaceGuid.PcdRealBattery2Control                  |0x00|UINT8|0x00100104
+
+gBoardModuleTokenSpaceGuid.PcdDimmPopulationError|FALSE|BOOLEAN|0x00100221
+gBoardModuleTokenSpaceGuid.PcdBtIrqGpio|0x0|UINT32|0x0010020E
+gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio|0x0|UINT32|0x0010020D
+gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable|FALSE|BOOLEAN|0x0010022C
+gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported|0x00|UINT8|0x0010004B
+gBoardModuleTokenSpaceGuid.PcdMipiCamSensor                        |FALSE|BOOLEAN|0x00100105
+gBoardModuleTokenSpaceGuid.PcdH8S2113SIO                           |FALSE|BOOLEAN|0x0010010A
+gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM                          |FALSE|BOOLEAN|0x00100107
+gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO                          |FALSE|BOOLEAN|0x00100108
+gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON                        |FALSE|BOOLEAN|0x00100109
+
+[PcdsDynamicEx]
+
+[PcdsDynamic, PcdsDynamicEx]
+
+[PcdsPatchableInModule]
+
+[PcdsFeatureFlag]
+gBoardModuleTokenSpaceGuid.PcdIntelGopEnable      |TRUE|BOOLEAN|0xF0000062
+gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport   |TRUE|BOOLEAN|0xF0000000
+gBoardModuleTokenSpaceGuid.PcdTbtEnable           |FALSE|BOOLEAN|0x000000115
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
new file mode 100644
index 0000000000..4aae18cac4
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Header file for the DxeCheckIommuSupport library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+#define _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
+/**
+  Detect ME FW and Board Type and return the result via IommuSkuCheck.
+
+  IommuSkuCheck
+  BIT0: Indicate system has a Corporate CSME firmware
+  BIT1: Indicate BIOS is running on a WHL RVP
+  BIT2: Indicate BIOS is running on a CFL-H RVP
+  BIT3: Indicate BIOS is running on a CFL-S 8+2 RVP
+
+  @retval Return 0 means not support, otherwise value is defined by IommuSkuCheck
+**/
+UINT8
+DetectMeAndBoard (
+  VOID
+  );
+
+/**
+  DxeCheckIommuSupport
+
+  Only WHL/CFL-H/CFL-S 8+2 Crop SKUs support Iommu.
+  This function will save sku information to PcdIommuSkuCheck.
+  BIOS will use PcdIommuSkuCheck and other factors to set PcdVTdPolicyPropertyMask on the next boot in PEI phase
+
+  This function might perform a system reset.
+**/
+EFI_STATUS
+EFIAPI
+DxeCheckIommuSupport (
+  VOID
+  );
+#endif // _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
new file mode 100644
index 0000000000..167cc8af83
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
@@ -0,0 +1,49 @@
+/** @file
+  Prototype of the DxeTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_LIB_H_
+#define _DXE_TBT_POLICY_LIB_H_
+
+
+/**
+  Install TBT Policy.
+
+  @param[in] ImageHandle                Image handle of this driver.
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+  IN  EFI_HANDLE                    ImageHandle
+  );
+
+/**
+  Update Tbt Policy Callback.
+
+  @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
+UpdateTbtPolicyCallback (
+  VOID
+  );
+
+/**
+  Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+  VOID
+  );
+#endif // _DXE_TBT_POLICY_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
new file mode 100644
index 0000000000..17337ceb0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
@@ -0,0 +1,131 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_SECURITY_LIB_H_
+#define _TBT_SECURITY_LIB_H_
+
+#include <Protocol/Tcg2Protocol.h>
+#include <Protocol/AcpiTable.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi.h>
+#include <SetupVariable.h>
+#include <OemSetup.h>
+#include <DmaRemappingTable.h>
+#include <PcieRegs.h>
+#include <Tcg2ConfigNvData.h>
+#include <TbtPolicyCommonDefinition.h>
+#include <Library/TbtCommonLib.h>
+
+#define TBT_SECURITY_EVENT_STRING                 "DMA Protection Disabled"
+#define TBT_SECURITY_EVENT_STRING_LEN             (sizeof (TBT_SECURITY_EVENT_STRING) - 1)
+
+#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING      "Security Level is Downgraded to 0"
+#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING_LEN  (sizeof (TBT_SECURITY_LEVEL_DOWNGRADED_STRING) - 1)
+
+#define GET_TBT_SECURITY_MODE    0
+#define SET_TBT_SECURITY_MODE    1
+
+typedef struct {
+  UINT8       EnableVtd;
+  BOOLEAN     SLDowngrade;
+} PCR7_DATA;
+
+/**
+  TBT Security ExtendPCR7 CallBackFunction
+  If the firmware/BIOS has an option to enable and disable DMA protections via a VT-d switch in BIOS options, then the shipping configuration must be with VT-d protection enabled.
+  On every boot where VT-d/DMA protection is disabled, or will be disabled, or configured to a lower security state, and a platform has a TPM enabled, then the platform SHALL extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA.
+  The event string SHALL be "DMA Protection Disabled". The platform firmware MUST log this measurement in the event log using the string "DMA Protection Disabled" for the Event Data.
+  Measure and log launch of TBT Security, and extend the measurement result into a specific PCR.
+  Extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA. The event string SHALL be "DMA Protection Disabled". The platform firmware MUST log this measurement in the event log using the string "DMA Protection Disabled" for the Event Data.
+
+  @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
+ExtendPCR7CallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  TBT Security DisableBme CallBackFunction
+
+  BIOS will disable BME and tear down the Thunderbolt DMAR tables at ExitBootServices
+  in order to hand off security of TBT hierarchies to the OS.
+  The BIOS is expected to either: Disable BME from power on till the OS starts configuring the devices and enabling BME Enable BME only for devices that can be protected by VT-d in preboot environment,
+  but disable BME and tear down any Thunderbolt DMAR tables at ExitBootServices()
+
+  @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
+TbtDisableBmeCallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  TBT Security SetDmarOptIn CallBackFunction
+
+  A new security feature will be supported to protect against Physical DMA attacks over Thunderbolt connects.
+  In order to do this, they need a new flag added to the DMAR tables that a DMA is only permitted into RMRR at ExitBootServices().  With this flag available, OS can then Bug Check if any DMA is requested outside of the RMRR before OS supported device drivers are started.
+  ReadyToBoot callback routine to update DMAR BIT2
+  Bit definition: DMA_CONTROL_GUARANTEE
+  If Set, the platform supports blocking all DMA outside of the regions defined in the RMRR structures from ExitBootServices() until OS supported device drivers are started.
+
+  @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
+SetDmarOptInCallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+/**
+  The function install DisableBme protocol for TBT Shell validation
+**/
+VOID
+InstallDisableBmeProtocol (
+  VOID
+  );
+
+/**
+  Get or set Thunderbolt(TM) security mode
+
+  @param[in]  DelayTime           - The delay time after do ForcePwr
+  @param[in]  SecurityMode        - TBT Security Level
+  @param[in]  Gpio3ForcePwrEn     - Force GPIO to power on or not
+  @param[in]  DTbtController      - Enable/Disable DTbtController
+  @param[in]  MaxControllerNumber - Number of contorller
+  @param[in]  Action              - 0 = get, 1 = set
+
+  @retval                         - Return security level
+**/
+UINT8
+EFIAPI
+GetSetSecurityMode (
+  IN UINTN                       DelayTime,
+  IN UINT8                       SecurityMode,
+  IN UINT8                       Gpio3ForcePwrEn,
+  IN UINT8                       *DTbtController,
+  IN UINT8                       MaxControllerNumber,
+  IN UINT8                       Action
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
new file mode 100644
index 0000000000..9afb36f011
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for the PeiCheckIommuSupport library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+#define _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
+/**
+  Check Iommu Ability base on SKU type, CSME FW type, Vtd and setup options.
+**/
+VOID
+PeiCheckIommuSupport (
+  VOID
+  );
+
+#endif // _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
new file mode 100644
index 0000000000..45bd8f38ed
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Prototype of the PeiTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_LIB_H_
+#define _PEI_TBT_POLICY_LIB_H_
+
+/**
+  Install Tbt Policy
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+  VOID
+  );
+
+/**
+  Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicyCallback (
+  VOID
+  );
+
+/**
+  Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+  VOID
+  );
+#endif // _DXE_TBT_POLICY_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
new file mode 100644
index 0000000000..44ae01a3f7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
@@ -0,0 +1,61 @@
+/** @file
+  PEI TBT Task Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_TBT_TASK_DISPATCH_LIB_H__
+#define __PEI_TBT_TASK_DISPATCH_LIB_H__
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+
+typedef
+EFI_STATUS
+(EFIAPI *TBT_TASK) (
+  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+typedef enum {
+  TBT_NULL,                ///< All policy flags turned off.
+  TBT_NORMAL   = (1 << 0), ///< Execute TBT function on cold reset.
+  TBT_S3       = (1 << 1), ///< Execute TBT function on S3 exit.
+  TBT_S4       = (1 << 2), ///< Execute TBT function on S4 exit.
+  TBT_ALL      = MAX_UINTN ///< Execute TBT function always.
+} TBT_BOOT_MODE;
+
+typedef struct {
+  TBT_TASK      TbtTask;         ///< Ptr to function to execute, with parameter list.
+  TBT_BOOT_MODE TbtBootModeFlag; ///< Call table base on TbtBootModeFlag
+  CHAR8         *String;         ///< Output string describing this task.
+} TBT_CALL_TABLE_ENTRY;
+
+/**
+  Covert the current EFI_BOOT_MODE to TBT_BOOT_MODE
+**/
+TBT_BOOT_MODE
+TbtGetBootMode (
+  VOID
+);
+
+/**
+  TbtTaskDistpach: Dispatch the TBT tasks according to TBT_CALL_TABLE_ENTRY
+
+  @param[in] TBT_CALL_TABLE_ENTRY   TbtCallTable
+
+**/
+VOID
+TbtTaskDistpach (
+  IN TBT_CALL_TABLE_ENTRY *TbtCallTable
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
new file mode 100644
index 0000000000..3e9e7c4b76
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
@@ -0,0 +1,261 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_COMMON_LIB_H_
+#define _TBT_COMMON_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+
+#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_RP     0 // @todo : Update when once finalized
+#define DEFAULT_PCI_BUS_NUMBER_ITBT_RP         0
+#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_RP      0x07
+
+#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_DMA0   0
+#define DEFAULT_PCI_BUS_NUMBER_ITBT_DMA0       0
+#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_DMA0    0x0D
+#define DEFAULT_PCI_FUNCTION_NUMBER_ITBT_DMA0  0x02
+
+#define DTBT_CONTROLLER                   0x00
+#define DTBT_TYPE_PCH                     0x01
+#define DTBT_TYPE_PEG                     0x02
+#define ITBT_CONTROLLER                   0x80
+#define TBT2PCIE_ITBT_R                   0xEC
+#define PCIE2TBT_ITBT_R                   0xF0
+#define TBT2PCIE_DTBT_R                   0x548
+#define PCIE2TBT_DTBT_R                   0x54C
+
+#define INVALID_RP_CONTROLLER_TYPE        0xFF
+
+//
+//  Thunderbolt FW OS capability
+//
+#define NO_OS_NATIVE_SUPPORT    0
+#define OS_NATIVE_SUPPORT_ONLY  1
+#define OS_NATIVE_SUPPORT_RTD3  2
+
+#define ITBT_SAVE_STATE_OFFSET  BIT4 // Bits 4-7 is for ITBT (HIA0/1/2/Reserved)
+#define DTBT_SAVE_STATE_OFFSET  BIT0 // Bits 0-3 is for DTBT (only bit 0 is in use)
+/**
+Get Tbt2Pcie Register Offset
+
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@retval     Register  Register Variable
+**/
+
+#define GET_TBT2PCIE_REGISTER_ADDRESS(Type, Segment, Bus, Device, Function, RegisterAddress) \
+  if (Type == ITBT_CONTROLLER) { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_ITBT_R); \
+  } else { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_DTBT_R); \
+  }
+
+/**
+Get Pcie2Tbt Register Offset
+
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@retval     Register  Register Variable
+**/
+
+#define GET_PCIE2TBT_REGISTER_ADDRESS(Type, Segment, Bus, Device, Function, RegisterAddress) \
+  if (Type == ITBT_CONTROLLER) { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_ITBT_R); \
+  } else { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_DTBT_R); \
+  }
+
+#define PCIE2TBT_VLD_B                    BIT0
+#define TBT2PCIE_DON_R                    BIT0
+#define TBT_MAIL_BOX_DELAY                (100*1000)
+#define TBT_5S_TIMEOUT                    50
+#define TBT_1S_TIMEOUT                    10
+#define TBT_3S_TIMEOUT                    30
+
+#define PCIE2TBT_GO2SX                    (0x02 << 1)
+#define PCIE2TBT_GO2SX_NO_WAKE            (0x03 << 1)
+#define PCIE2TBT_SX_EXIT_TBT_CONNECTED    (0x04 << 1)
+#define PCIE2TBT_SX_EXIT_NO_TBT_CONNECTED (0x05 << 1)
+#define PCIE2TBT_OS_UP                    (0x06 << 1)
+#define PCIE2TBT_SET_SECURITY_LEVEL       (0x08 << 1)
+#define PCIE2TBT_GET_SECURITY_LEVEL       (0x09 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_ENTER       (0x10 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_EXIT        (0x11 << 1)
+#define PCIE2TBT_BOOT_ON                  (0x18 << 1)
+#define PCIE2TBT_BOOT_OFF                 (0x19 << 1)
+#define PCIE2TBT_USB_ON                   (0x19 << 1)
+#define PCIE2TBT_GET_ENUMERATION_METHOD   (0x1A << 1)
+#define PCIE2TBT_SET_ENUMERATION_METHOD   (0x1B << 1)
+#define PCIE2TBT_POWER_CYCLE              (0x1C << 1)
+#define PCIE2TBT_PREBOOTACL               (0x1E << 1)
+#define CONNECT_TOPOLOGY_COMMAND          (0x1F << 1)
+
+#define RESET_HR_BIT                      BIT0
+#define ENUMERATE_HR_BIT                  BIT1
+#ifndef AUTO
+#define AUTO                              0x0
+#endif
+
+//
+//Thunder Bolt Device IDs
+//
+
+//
+// Alpine Ridge HR device IDs
+//
+#define AR_HR_2C  0x1576
+#define AR_HR_4C  0x1578
+#define AR_XHC    0x15B5
+#define AR_XHC_4C 0x15B6
+#define AR_HR_LP  0x15C0
+//
+// Alpine Ridge C0 HR device IDs
+//
+#define AR_HR_C0_2C  0x15DA
+#define AR_HR_C0_4C  0x15D3
+//
+// Titan Ridge HR device IDs
+//
+#define TR_HR_2C  0x15E7
+#define TR_HR_4C  0x15EA
+//
+//End of Thunderbolt(TM) Device IDs
+//
+
+typedef struct _DEV_ID {
+  UINT8 Segment;
+  UINT8 Bus;
+  UINT8 Dev;
+  UINT8 Fun;
+} DEV_ID;
+
+//@todo Seems to only be used by Platform/TBT/Smm/TbtSmm.inf
+//@todo should refactor this to only be present in that driver
+//@todo also definitions like this should never be in a .h file anyway
+//@todo this is a quick hack to get things compiling for now
+#ifdef __GNUC__
+#pragma GCC diagnostic warning "-Wunused-variable"
+#endif
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in]  GpioNumber
+@param[in]  Value
+**/
+VOID
+ForceDtbtPower(
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+);
+
+/**
+  Get Security Level.
+  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
+  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  );
+
+/**
+  Set Security Level.
+  @param[in]  Data      Security State
+  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
+  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+  IN    UINT8                   Data,
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  );
+
+/**
+Execute TBT Mail Box Command
+
+@param[in]  Command   TBT Command
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+  IN    UINT8                   Command,
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT32                  Timeout
+);
+/**
+  Check connected TBT controller is supported or not by DeviceID
+
+  @param[in]  DeviceID              DeviceID of of TBT controller
+
+
+  @retval     TRUE                  Valid DeviceID
+  @retval     FALSE                 Invalid DeviceID
+**/
+
+BOOLEAN
+IsTbtHostRouter (
+  IN    UINT16  DeviceID
+  );
+
+/**
+  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun(
+  IN  BOOLEAN Type,
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFunc
+  );
+
+/**
+  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
+  @param[in]  TimeOut                   Time out with 100 ms garnularity
+  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to Clear/Set)
+  @param[out] *Tbt2PcieValue Function   Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion (
+  IN  UINT64   CommandOffsetAddress,
+  IN  UINT32   TimeOut,
+  IN  BOOLEAN  Tbt2PcieDone,
+  OUT UINT32   *Tbt2PcieValue
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
new file mode 100644
index 0000000000..17d8a62f66
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
@@ -0,0 +1,31 @@
+/** @file
+TBT PEI Policy
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_H_
+#define _PEI_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define PEI_TBT_POLICY_REVISION 1
+
+/**
+ TBT PEI configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _PEI_TBT_POLICY {
+  DTBT_COMMON_CONFIG     DTbtCommonConfig;                                  ///< dTbt Common Configuration
+  DTBT_CONTROLLER_CONFIG DTbtControllerConfig [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
+} PEI_TBT_POLICY;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
new file mode 100644
index 0000000000..bb30c2c0ec
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
@@ -0,0 +1,130 @@
+/** @file
+  PEI DTBT Init Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_DTBT_INIT_LIB_H__
+#define __PEI_DTBT_INIT_LIB_H__
+
+#include <Private/Library/PeiTbtCommonInitLib.h>
+#include <Library/PeiTbtTaskDispatchLib.h>
+
+extern TBT_CALL_TABLE_ENTRY DTbtCallTable[];
+
+/**
+  Get Thunderbolt(TM) (TBT) PEI Policy Data.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtGetPeiTbtPolicyData (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Toggle related GPIO pin for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtToggleGPIO (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  set tPCH25 Timing to 10 ms for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Do ForcePower for DTBT Controller
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Clear VGA Registers for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "Boot On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "USB On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "Sx Exit".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
new file mode 100644
index 0000000000..0ed13fd300
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
@@ -0,0 +1,51 @@
+/** @file
+  PEI TBT Common Init Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_TBT_COMMON_INIT_LIB_H__
+#define __PEI_TBT_COMMON_INIT_LIB_H__
+
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiTbtTaskDispatchLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TbtCommonLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PmcLib.h>
+#include <PlatformNvRamHookLib.h>
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN  UINT8        ControllerType,
+IN  UINT8        Controller
+);
+
+VOID
+TbtSetSxMode(
+IN    BOOLEAN                 Type,
+IN    UINT8                   Bus,
+IN    UINT8                   Device,
+IN    UINT8                   Function,
+IN    UINT8                   TbtBootOn
+);
+
+VOID
+TbtClearVgaRegisters(
+IN    UINTN                   Segment,
+IN    UINTN                   Bus,
+IN    UINTN                   Device,
+IN    UINTN                   Function
+);
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
new file mode 100644
index 0000000000..1948c252f0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
@@ -0,0 +1,36 @@
+/** @file
+  Definitions for DisableBmeProtocol
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DISABLE_TBT_BME_PROTOCOL_H_
+#define _DISABLE_TBT_BME_PROTOCOL_H_
+
+typedef struct EFI_DISABLE_BME_PROTOCOL EFI_DISABLE_TBT_BME_PROTOCOL;
+
+/**
+  This is for disable TBT BME bit under shell environment
+
+  @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.
+**/
+typedef
+VOID
+(EFIAPI *DISABLE_BUS_MASTER_ENABLE) (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+struct EFI_DISABLE_BME_PROTOCOL {
+  DISABLE_BUS_MASTER_ENABLE DisableBme;
+};
+
+extern EFI_GUID gDxeDisableTbtBmeProtocolGuid;
+
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
new file mode 100644
index 0000000000..437f6a8401
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
@@ -0,0 +1,137 @@
+/** @file
+TBT DXE Policy
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_H_
+#define _DXE_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define DXE_TBT_POLICY_REVISION 1
+
+//
+// TBT Common Data Structure
+//
+typedef struct _TBT_COMMON_CONFIG{
+  /**
+    TBT Security Level
+    <b>0: SL0 No Security</b>, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+  **/
+  UINT32   SecurityMode      : 3;
+  /**
+    BIOS W/A for Hot plug of 12V USB devices cause electrical noise on PCH GPIOs
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Gpio5Filter       : 1;
+  /**
+     WA for TR A0 OS_UP Command, it is only needed for TR A0 stepping
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TrA0OsupWa        : 1;
+  /**
+    Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtWakeupSupport  : 1;
+  /**
+    SMI TBT enumeration
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtHotSMI         : 1;
+  /**
+    Notify PCIe RP after Hot-Plug/Hot-Unplug occurred.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtHotNotify      : 1;
+  /**
+    CLK REQ for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtSetClkReq      : 1;
+  /**
+    ASPM setting for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: L0s, 2: L1, 3: L0sL1
+  **/
+  UINT32   TbtAspm           : 2;
+  /**
+    L1 SubState for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: L1.1, 2: L1.1 & L1.2
+  **/
+  UINT32   TbtL1SubStates    : 2;
+  /**
+    LTR for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtLtr            : 1;
+  /**
+    PTM for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtPtm            : 1;
+  /**
+    TBT Dynamic AC/DC L1.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtAcDcSwitch     : 1;
+  /**
+    TBT RTD3 Support.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Rtd3Tbt           : 1;
+  /**
+    TBT ClkReq for RTD3 Flow.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Rtd3TbtClkReq     : 1;
+  /**
+    TBT Win10support for Tbt FW execution mode.
+    <b>0: Disabled</b>, 1: Native, 2: Native + RTD3
+  **/
+  UINT32   Win10Support      : 2;
+  /**
+    TbtVtdBaseSecurity
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtVtdBaseSecurity: 1;
+  /**
+    Control Iommu behavior in pre-boot
+    <b>0: Disabled Iommu</b>, 1: Enable Iommu, Disable exception list, 2: Enable Iommu, Enable exception list
+  **/
+  UINT32   ControlIommu      : 3;
+  UINT32   Rsvd0             : 8; ///< Reserved bits
+  UINT16   Rtd3TbtClkReqDelay;
+  UINT16   Rtd3TbtOffDelay;
+} TBT_COMMON_CONFIG;
+
+//
+// dTBT Resource Data Structure
+//
+typedef struct _DTBT_RESOURCE_CONFIG{
+  UINT8  DTbtPcieExtraBusRsvd;     ///< Preserve Bus resource for PCIe RP that connect to dTBT Host Router
+  UINT16 DTbtPcieMemRsvd;          ///< Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  DTbtPcieMemAddrRngMax;    ///< Alignment of Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+  UINT16 DTbtPciePMemRsvd;         ///< Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  DTbtPciePMemAddrRngMax;   ///< Alignment of Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  Reserved[1];      ///< Reserved for DWORD alignment
+} DTBT_RESOURCE_CONFIG;
+
+/**
+ TBT DXE configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _DXE_TBT_POLICY_PROTOCOL {
+  TBT_COMMON_CONFIG      TbtCommonConfig;                                  ///< Tbt Common Information
+  DTBT_RESOURCE_CONFIG   DTbtResourceConfig[MAX_DTBT_CONTROLLER_NUMBER];   ///< dTbt Resource Configuration
+} DXE_TBT_POLICY_PROTOCOL;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
new file mode 100644
index 0000000000..e6654b4094
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
@@ -0,0 +1,50 @@
+/** @file
+  This file defines the TBT NVS Area Protocol.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_NVS_AREA_H_
+#define _TBT_NVS_AREA_H_
+
+//
+// Platform NVS Area definition
+//
+#include <TbtNvsAreaDef.h>
+
+//
+// Includes
+//
+#define TBT_NVS_DEVICE_ENABLE 1
+#define TBT_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL TBT_NVS_AREA_PROTOCOL;
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gTbtNvsAreaProtocolGuid;
+
+/**
+ Making any TBT_NVS_AREA 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.\n
+  <b>Revision 2</b>:   - Adding TBT NVS AREA Revision, Deprecated DTbtControllerEn0, DTbtControllerEn1.\n
+**/
+#define TBT_NVS_AREA_REVISION       2
+
+//
+// Platform NVS Area Protocol
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL {
+  TBT_NVS_AREA     *Area;
+} TBT_NVS_AREA_PROTOCOL;
+
+#endif // _TBT_NVS_AREA_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
new file mode 100644
index 0000000000..bd5e577fbe
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
@@ -0,0 +1,23 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_INFO_GUID_H_
+#define _TBT_INFO_GUID_H_
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(1)
+//
+// TBT Info HOB
+//
+typedef struct _TBT_INFO_HOB {
+  EFI_HOB_GUID_TYPE      EfiHobGuidType;
+  DTBT_COMMON_CONFIG     DTbtCommonConfig;                                  ///< dTbt Common Configuration
+  DTBT_CONTROLLER_CONFIG DTbtControllerConfig [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
+} TBT_INFO_HOB;
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
new file mode 100644
index 0000000000..21e17b4609
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
@@ -0,0 +1,68 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define TBT NVS Area operation region.
+  //
+
+#ifndef _TBT_NVS_AREA_DEF_H_
+#define _TBT_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT8    ThunderboltSmiFunction;                  ///< Offset 0       Thunderbolt(TM) SMI Function Number
+  UINT8    ThunderboltHotSmi;                       ///< Offset 1       SMI on Hot Plug for TBT devices
+  UINT8    TbtWin10Support;                         ///< Offset 2       TbtWin10Support
+  UINT8    TbtGpioFilter;                           ///< Offset 3       Gpio filter to detect USB Hotplug event
+  UINT8    ThunderboltHotNotify;                    ///< Offset 4       Notify on Hot Plug for TBT devices
+  UINT8    TbtSelector;                             ///< Offset 5       Thunderbolt(TM) Root port selector
+  UINT8    WAKFinished;                             ///< Offset 6       WAK Finished
+  UINT8    DiscreteTbtSupport;                      ///< Offset 7       Thunderbolt(TM) support
+  UINT8    TbtAcpiRemovalSupport;                   ///< Offset 8       TbtAcpiRemovalSupport
+  UINT32   TbtFrcPwrEn;                             ///< Offset 9       TbtFrcPwrEn
+  UINT32   TbtFrcPwrGpioNo0;                        ///< Offset 13      TbtFrcPwrGpioNo
+  UINT8    TbtFrcPwrGpioLevel0;                     ///< Offset 17      TbtFrcPwrGpioLevel
+  UINT32   TbtCioPlugEventGpioNo0;                  ///< Offset 18      TbtCioPlugEventGpioNo
+  UINT32   TbtPcieRstGpioNo0;                       ///< Offset 22      TbtPcieRstGpioNo
+  UINT8    TbtPcieRstGpioLevel0;                    ///< Offset 26      TbtPcieRstGpioLevel
+  UINT8    CurrentDiscreteTbtRootPort;              ///< Offset 27      Current Port that has plug event
+  UINT8    RootportSelected0;                       ///< Offset 28      Root port Selected by the User
+  UINT8    RootportSelected0Type;                   ///< Offset 29      Root port Type
+  UINT8    RootportSelected1;                       ///< Offset 30      Root port Selected by the User
+  UINT8    RootportSelected1Type;                   ///< Offset 31      Root port Type
+  UINT8    RootportEnabled0;                        ///< Offset 32      Root port Enabled by the User
+  UINT8    RootportEnabled1;                        ///< Offset 33      Root port Enabled by the User
+  UINT32   TbtFrcPwrGpioNo1;                        ///< Offset 34      TbtFrcPwrGpioNo
+  UINT8    TbtFrcPwrGpioLevel1;                     ///< Offset 38      TbtFrcPwrGpioLevel
+  UINT32   TbtCioPlugEventGpioNo1;                  ///< Offset 39      TbtCioPlugEventGpioNo
+  UINT32   TbtPcieRstGpioNo1;                       ///< Offset 43      TbtPcieRstGpioNo
+  UINT8    TbtPcieRstGpioLevel1;                    ///< Offset 47      TbtPcieRstGpioLevel
+  UINT8    TBtCommonGpioSupport;                    ///< Offset 48      Set if Single GPIO is used for Multi/Different Controller Hot plug support
+  UINT8    CurrentDiscreteTbtRootPortType;          ///< Offset 49      Root Port type for which SCI Triggered
+  UINT8    TrOsup;                                  ///< Offset 50      Titan Ridge Osup command
+  UINT8    TbtAcDcSwitch;                           ///< Offset 51      TBT Dynamic AcDc L1
+  UINT8    DTbtControllerEn0;                       ///< Offset 52      DTbtController0 is enabled or not.  @deprecated since revision 2
+  UINT8    DTbtControllerEn1;                       ///< Offset 53      DTbtController1 is enabled or not.  @deprecated since revision 2
+  UINT8    TbtAspm;                                 ///< Offset 54      ASPM setting for all the PCIe device in TBT daisy chain.
+  UINT8    TbtL1SubStates;                          ///< Offset 55      L1 SubState for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtSetClkReq;                            ///< Offset 56      CLK REQ for all the PCIe device in TBT daisy chain.
+  UINT8    TbtLtr;                                  ///< Offset 57      LTR for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtPtm;                                  ///< Offset 58      PTM for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtWakeupSupport;                        ///< Offset 59      Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+  UINT16   Rtd3TbtOffDelay;                         ///< Offset 60      Rtd3TbtOffDelay TBT RTD3 Off Delay
+  UINT8    TbtSxWakeSwitchLogicEnable;              ///< Offset 62      TbtSxWakeSwitchLogicEnable Set True if TBT_WAKE_N will be routed to PCH WakeB at Sx entry point. HW logic is required.
+  UINT8    Rtd3TbtSupport;                          ///< Offset 63      Enable Rtd3 support for TBT. Corresponding to Rtd3Tbt in Setup.
+  UINT8    Rtd3TbtClkReq;                           ///< Offset 64      Enable TBT RTD3 CLKREQ mask.
+  UINT16   Rtd3TbtClkReqDelay;                      ///< Offset 65      TBT RTD3 CLKREQ mask delay.
+  //
+  // Revision Field:
+  //
+  UINT8    TbtRevision;                             ///< Offset 67      Revison of TbtNvsArea
+} TBT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
new file mode 100644
index 0000000000..7771fc7a95
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
@@ -0,0 +1,84 @@
+/** @file
+TBT Policy Common definition.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_POLICY_COMMON_H_
+#define _TBT_POLICY_COMMON_H_
+
+#include <Library/GpioLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#define MAX_DTBT_CONTROLLER_NUMBER 2
+
+#define TYPE_PCIE           0x01
+#define TYPE_PEG            0x02
+
+#pragma pack(push, 1)
+
+//
+// dTBT Force Power GPIO Data Structure
+//
+typedef struct _DTBT_FORCE_POWER_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_FORCE_POWER_GPIO_CONFIG;
+
+//
+// dTBT CIO Plug Event GPIO Data Structure
+//
+typedef struct _DTBT_CIO_PLUG_EVENT_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  UINT32         AcpiGpeSignature;        ///< AcpiPlatform driver will change the XTBT method to the _Lxx or _Exx that we assign in this item.
+  BOOLEAN        AcpiGpeSignaturePorting; ///< 0 = No porting required(for 2-tier GPI GPE event architecture), 1 = Porting required(for 1-tier GPI GPE event architecture)
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_CIO_PLUG_EVENT_GPIO_CONFIG;
+
+//
+// dTBT PCIE Reset GPIO Data Structure
+//
+typedef struct _DTBT_PCIE_RESET_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_PCIE_RESET_GPIO_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_CONTROLLER_CONFIG {
+  UINT8                           DTbtControllerEn; ///< Enable/Disable DTbtController.
+  UINT8                           Type;             ///< 01-Pcie RP, 02- PEG,Reserved. <Specific according to Board Design>
+  UINT8                           PcieRpNumber;     ///< RP Number/ PEG Port (0,1,2) that connecet to dTBT controller. <Specific according to Board Design>
+  DTBT_FORCE_POWER_GPIO_CONFIG    ForcePwrGpio;     ///< The GPIO pin that can force dTBT Power On. <Specific according to Board Design>
+  DTBT_CIO_PLUG_EVENT_GPIO_CONFIG CioPlugEventGpio; ///< The GPIO pin that can generate Hot-Plug event. <Specific according to Board Design>
+  DTBT_PCIE_RESET_GPIO_CONFIG     PcieRstGpio;      ///< The GPIO pin that is use to perform Reset when platform enters to Sx, it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO <Specific according to Board Design>
+  GPIO_PAD                        PdResetGpioPad;   ///< PD HRESET GPIO Pad Number
+  GPIO_PAD                        PdSxEntryGpioPad; ///< PD SX Entry GPIO Pad Number
+  GPIO_PAD                        PdSxAckGpioPad;   ///< PD SX Ack GPIO Pad Number
+  UINT8                           Reserved[1];      ///< Reserved for DWORD alignment
+} DTBT_CONTROLLER_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_COMMON_CONFIG {
+  UINT8            TbtBootOn;                    ///< Send BootOn Mailbox command when TbtBootOn is enabled.
+  UINT8            TbtUsbOn;                     ///< Send UsbOn Mailbox command when TbtBootOn is enabled.
+  UINT8            Gpio3ForcePwr;                ///< Force GPIO to power on or not
+  UINT16           Gpio3ForcePwrDly;             ///< The delay time after do ForcePwr
+  BOOLEAN          DTbtSharedGpioConfiguration;  ///< Multiple DTBT controllers share the same GPIO pin <Specific according to Board Design>
+  BOOLEAN          PcieRstSupport;               ///< 0 = Not Support, 1 = Supported. it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO
+  UINT8            SecurityMode;                 ///< 0: SL0 No Security, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+  UINT8            ControlIommu;                 ///< Control Iommu behavior in pre-boot, 0: Disabled Iommu, 1: Enable Iommu, Disable exception list, 2: Enable Iommu, Enable exception list
+  UINT8            Reserved[3];                  ///< Reserved for DWORD alignment
+} DTBT_COMMON_CONFIG;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
new file mode 100644
index 0000000000..d8021e8c22
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
@@ -0,0 +1,118 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  // Define a Global region of ACPI NVS Region that may be used for any
+  // type of implementation.  The starting offset and size will be fixed
+  // up by the System BIOS during POST.  Note that the Size must be a word
+  // in size to be fixed up correctly.
+
+
+#ifndef _GLOBAL_NVS_AREA_DEF_H_
+#define _GLOBAL_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  //
+  // Miscellaneous Dynamic Registers:
+  //
+  UINT16   OperatingSystem;                         ///< Offset 0       Operating System
+  UINT8    SmiFunction;                             ///< Offset 2       SMI Function Call (ASL to SMI via I/O Trap)
+  UINT32   Port80DebugValue;                        ///< Offset 3       Port 80 Debug Port Value
+  UINT8    PowerState;                              ///< Offset 7       Power State (AC Mode = 1)
+  //
+  // Thermal Policy Registers:
+  //
+  UINT8    EnableDigitalThermalSensor;              ///< Offset 8       Digital Thermal Sensor Enable
+  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 9       DTS SMI Function Call
+  //
+  // CPU Identification Registers:
+  //
+  UINT8    ApicEnable;                              ///< Offset 10      APIC Enabled by SBIOS (APIC Enabled = 1)
+  UINT8    ThreadCount;                             ///< Offset 11      Number of Enabled Threads
+  //
+  // PCIe Hot Plug
+  //
+  UINT8    PcieOSCControl;                          ///< Offset 12      PCIE OSC Control
+  UINT8    NativePCIESupport;                       ///< Offset 13      Native PCIE Setup Value
+  //
+  // Global Variables
+  //
+  UINT8    DisplaySupportFlag;                      ///< Offset 14      _DOS Display Support Flag.
+  UINT8    InterruptModeFlag;                       ///< Offset 15      Global IOAPIC/8259 Interrupt Mode Flag.
+  UINT8    L01Counter;                              ///< Offset 16      Global L01 Counter.
+  UINT8    LtrEnable[24];                           ///< Offset 17      Latency Tolerance Reporting Enable
+                                                    ///< Offset 18      Latency Tolerance Reporting Enable
+                                                    ///< Offset 19      Latency Tolerance Reporting Enable
+                                                    ///< Offset 20      Latency Tolerance Reporting Enable
+                                                    ///< Offset 21      Latency Tolerance Reporting Enable
+                                                    ///< Offset 22      Latency Tolerance Reporting Enable
+                                                    ///< Offset 23      Latency Tolerance Reporting Enable
+                                                    ///< Offset 24      Latency Tolerance Reporting Enable
+                                                    ///< Offset 25      Latency Tolerance Reporting Enable
+                                                    ///< Offset 26      Latency Tolerance Reporting Enable
+                                                    ///< Offset 27      Latency Tolerance Reporting Enable
+                                                    ///< Offset 28      Latency Tolerance Reporting Enable
+                                                    ///< Offset 29      Latency Tolerance Reporting Enable
+                                                    ///< Offset 30      Latency Tolerance Reporting Enable
+                                                    ///< Offset 31      Latency Tolerance Reporting Enable
+                                                    ///< Offset 32      Latency Tolerance Reporting Enable
+                                                    ///< Offset 33      Latency Tolerance Reporting Enable
+                                                    ///< Offset 34      Latency Tolerance Reporting Enable
+                                                    ///< Offset 35      Latency Tolerance Reporting Enable
+                                                    ///< Offset 36      Latency Tolerance Reporting Enable
+                                                    ///< Offset 37      Latency Tolerance Reporting Enable
+                                                    ///< Offset 38      Latency Tolerance Reporting Enable
+                                                    ///< Offset 39      Latency Tolerance Reporting Enable
+                                                    ///< Offset 40      Latency Tolerance Reporting Enable
+  UINT8    ObffEnable[24];                          ///< Offset 41      Optimized Buffer Flush and Fill
+                                                    ///< Offset 42      Optimized Buffer Flush and Fill
+                                                    ///< Offset 43      Optimized Buffer Flush and Fill
+                                                    ///< Offset 44      Optimized Buffer Flush and Fill
+                                                    ///< Offset 45      Optimized Buffer Flush and Fill
+                                                    ///< Offset 46      Optimized Buffer Flush and Fill
+                                                    ///< Offset 47      Optimized Buffer Flush and Fill
+                                                    ///< Offset 48      Optimized Buffer Flush and Fill
+                                                    ///< Offset 49      Optimized Buffer Flush and Fill
+                                                    ///< Offset 50      Optimized Buffer Flush and Fill
+                                                    ///< Offset 51      Optimized Buffer Flush and Fill
+                                                    ///< Offset 52      Optimized Buffer Flush and Fill
+                                                    ///< Offset 53      Optimized Buffer Flush and Fill
+                                                    ///< Offset 54      Optimized Buffer Flush and Fill
+                                                    ///< Offset 55      Optimized Buffer Flush and Fill
+                                                    ///< Offset 56      Optimized Buffer Flush and Fill
+                                                    ///< Offset 57      Optimized Buffer Flush and Fill
+                                                    ///< Offset 58      Optimized Buffer Flush and Fill
+                                                    ///< Offset 59      Optimized Buffer Flush and Fill
+                                                    ///< Offset 60      Optimized Buffer Flush and Fill
+                                                    ///< Offset 61      Optimized Buffer Flush and Fill
+                                                    ///< Offset 62      Optimized Buffer Flush and Fill
+                                                    ///< Offset 63      Optimized Buffer Flush and Fill
+                                                    ///< Offset 64      Optimized Buffer Flush and Fill
+  UINT8    Rtd3Support;                             ///< Offset 65      Runtime D3 support.
+  UINT8    LowPowerS0Idle;                          ///< Offset 66      Low Power S0 Idle Enable
+  UINT8    VirtualGpioButtonSxBitmask;              ///< Offset 67      Virtual GPIO button Notify Sleep State Change
+  UINT8    PstateCapping;                           ///< Offset 68      P-state Capping
+  UINT8    Ps2MouseEnable;                          ///< Offset 69      Ps2 Mouse Enable
+  UINT8    Ps2KbMsEnable;                           ///< Offset 70      Ps2 Keyboard and Mouse Enable
+  //
+  // Driver Mode
+  //
+  UINT32   GpioIrqRoute;                            ///< Offset 71      GPIO IRQ
+  UINT8    PL1LimitCS;                              ///< Offset 75      set PL1 limit when entering CS
+  UINT16   PL1LimitCSValue;                         ///< Offset 76      PL1 limit value
+  UINT8    TenSecondPowerButtonEnable;              ///< Offset 78      10sec Power button support
+  UINT8    PciDelayOptimizationEcr;                 ///< Offset 79      Pci Delay Optimization Ecr
+  UINT8    TbtSupport;                              ///< Offset 80      Thunderbolt(TM) support
+  UINT8    TbtNativeOsHotPlug;                      ///< Offset 81      TbtNativeOsHotPlug
+  UINT8    TbtSelector;                             ///< Offset 82      Thunderbolt(TM) Root port selector
+  UINT8    TbtSelector1;                            ///< Offset 83      Thunderbolt(TM) Root port selector
+} EFI_GLOBAL_NVS_AREA;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
new file mode 100644
index 0000000000..bbdeb71da5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ATTEMPT_USB_FIRST_H_
+#define _ATTEMPT_USB_FIRST_H_
+
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_HOTKEY_INFO {
+  UINT8 RevisonId;         // Structure Revision ID
+  UINT8 HotkeyTriggered;   // Hot key status
+} ATTEMPT_USB_FIRST_HOTKEY_INFO;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_VARIABLE {
+  UINT8 UsbBootPrior;
+} ATTEMPT_USB_FIRST_VARIABLE;
+#pragma pack()
+
+//
+// Volatile variable definition for Attempt USB first features
+//
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_RUNTIME_VARIABLE {
+  UINT8 RevisonId;        // Structure Revision ID
+  UINT8 UsbFirstEnable;   // Attempt USB First is enabled or not
+} ATTEMPT_USB_FIRST_RUNTIME_VARIABLE;
+#pragma pack()
+
+//
+// Volatile variable definition for third party Default Enabling via UEFI Variable.
+//
+#pragma pack(1)
+typedef struct _ENABLE_CUSTOM_DEFAULTS{
+  UINT32 EnableCustomDefaults;
+} ENABLE_CUSTOM_DEFAULTS;
+#pragma pack()
+
+#define COENG_DEFAULTS_UNKNOWN   0
+#define COENG_DEFAULTS_SUPPORTED 1
+#define COENG_DEFAULTS_VAR_EXITS 2
+#define COENG_DEFAULTS_VAR_SET   4
+#define COENG_DEFAULTS_AVAILABLE (COENG_DEFAULTS_SUPPORTED | COENG_DEFAULTS_VAR_EXITS |COENG_DEFAULTS_VAR_SET)
+
+extern EFI_GUID gAttemptUsbFirstHotkeyInfoHobGuid;
+extern EFI_GUID gAttemptUsbFirstRuntimeVarInfoGuid;
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
new file mode 100644
index 0000000000..17ccd56373
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
@@ -0,0 +1,57 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPUSMM_H_
+#define _CPUSMM_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CPUSMM_GUID { 0x90d93e09, 0x4e91, 0x4b3d, { 0x8c, 0x77, 0xc8, 0x2f, 0xf1, 0xe, 0x3c, 0x81 }}
+#define CPUSMM_SETUP_NAME             L"CpuSmm"
+
+#pragma pack(1)
+typedef struct {
+  UINT8     CpuSmmMsrSaveStateEnable;
+  UINT8     CpuSmmCodeAccessCheckEnable;
+  UINT8     CpuSmmUseDelayIndication;
+  UINT8     CpuSmmUseBlockIndication;
+  UINT8     CpuSmmUseSmmEnableIndication;
+  UINT8     CpuSmmProcTraceEnable;
+} CPU_SMM;
+#pragma pack()
+
+#ifndef OFFSET_OF
+#ifdef __GNUC__
+#if __GNUC__ >= 4
+#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
+#endif
+#endif
+#endif
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+#define VERIFY_OFFSET(TYPE, Field, Offset) extern UINT8 _VerifyOffset##TYPE##Field[(OFFSET_OF(TYPE, Field) == Offset) / (OFFSET_OF(TYPE, Field) == Offset)]
+
+//
+// If TpmSupport/MorStae isn't in this offset, build failure (0 size array or divided by 0) will be generated.
+// Platform DSC file maps the two field to HII PCD so the offset value is critical.
+//
+VERIFY_OFFSET (CPU_SMM, CpuSmmMsrSaveStateEnable, 0x0);
+VERIFY_OFFSET (CPU_SMM, CpuSmmCodeAccessCheckEnable, 0x1);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseDelayIndication, 0x2);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseBlockIndication, 0x3);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseSmmEnableIndication, 0x4);
+VERIFY_OFFSET (CPU_SMM, CpuSmmProcTraceEnable, 0x5);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
new file mode 100644
index 0000000000..b7202a6b4a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
@@ -0,0 +1,20 @@
+/** @file
+  This header file provides definitions of firmware configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _FIRMWARE_CONFIGURATION_H_
+#define _FIRMWARE_CONFIGURATION_H_
+
+typedef enum {
+  FwConfigDefault = 0,
+  FwConfigProduction,
+  FwConfigTest,
+  FwConfigMax
+} FW_CONFIG;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
new file mode 100644
index 0000000000..ed63b28adf
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
@@ -0,0 +1,1766 @@
+/** @file
+Header file for GOP Configuration Library
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GOP_CONFIG_LIB_H_
+#define _GOP_CONFIG_LIB_H_
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#pragma pack(1)
+#define GOP_CONFIG_VBT_REVISION 0xC1
+
+#define ChildStruct_MAX                       8         ///< Maximum number of child structures in VBT
+#define CompressionStruct_MAX                 2         ///< Maximum number of compression parameter structures in VBT.
+#define NO_DEVICE                             0x00      ///< Defines a null display class.
+#define DISPLAY_PORT_ONLY                     0x68C6    ///< Defines a display class of Integrated Display Port Only
+#define DISPLAY_PORT_HDMI_DVI_COMPATIBLE      0x60D6    ///< Defines a display class of Integrated DisplayPort with HDMI/DVI Compatible
+#define DISPLAY_PORT_DVI_COMPATIBLE           0x68D6    ///< Defines a display class of Integrated DisplayPort with DVI Compatible
+#define HDMI_DVI                              0x60D2    ///< Defines a display class of Integrated HDMI/DVI
+#define DVI_ONLY                              0x68D2    ///< Defines a display class of Integrated DVI Only
+#define MIPI_ONLY                             0x1400
+#define eDP_ONLY                              0x1806    ///< Defines a display class of eDP only
+#define AUX_CHANNEL_A                         0x40
+#define AUX_CHANNEL_B                         0x10
+#define AUX_CHANNEL_C                         0x20
+#define AUX_CHANNEL_D                         0x30
+#define NO_PORT                               0x00      ///< Defines a output port NA
+#define HDMI_B                                0x01      ///< Defines a output port HDMI-B
+#define HDMI_C                                0x02      ///< Defines a output port HDMI-C
+#define HDMI_D                                0x03      ///< Defines a output port HDMI-D
+#define HDMI_F                                0x0E      ///< Defines a output port HDMI-D
+#define DISPLAY_PORT_A                        0x0A      ///< Defines a output port DisplayPort A
+#define DISPLAY_PORT_B                        0x07      ///< Defines a output port DisplayPort B
+#define DISPLAY_PORT_C                        0x08      ///< Defines a output port DisplayPort C
+#define DISPLAY_PORT_D                        0x09      ///< Defines a output port DisplayPort D
+#define DISPLAY_PORT_E                        0x0B      ///< Defines a output port DisplayPort E
+#define DISPLAY_PORT_F                        0x0D      ///< Defines a output port DisplayPort F
+#define PORT_MIPI_A                           0x15      ///< Mipi Port A
+#define PORT_MIPI_C                           0x17      ///< Mipi Port C
+
+typedef struct {
+  UINT16  Dclk;                         // DClk in 10 KHz
+  UINT8   HActive;                      // HActive [7:0]
+  UINT8   HBlank;                       // HBlank [7:0]
+  UINT8   HA_HB_UpperNibble;            // Upper nibble = HActive [11:8]
+  UINT8   VActive;                      // VActive [7:0]
+  UINT8   VBlank;                       // VBlank [7:0]
+  UINT8   VA_VB_UpperNibble;            // Upper nibble = VActive [11:8]
+  UINT8   HSyncOffset;                  // HSync offset from blank start LSB
+  UINT8   HPulseWidth;                  // HSync Pulse Width, LSB
+  UINT8   VsyncOffset_VpulseWidth_LSB;  // Bits 7:4 = VSync offset [3:0]
+  UINT8   HSO_HSPW_V_High;              // Bits 7:6 = HSync Offset [9:8]
+  UINT8   HorImageSize;                 // Horizontal Image Size
+  UINT8   VerImageSize;                 // Vertical Image Size
+  UINT8   HIS_VIS_High;                 // UpperLmtH_V Upper limits of H. and V. image size
+  UINT8   HBorder;                      // Horizontal Border
+  UINT8   VBorder;                      // Vertical Border
+  UINT8   Flags;                        // Flags
+} DTD_STRUCTURE;                        // 18 Bytes
+
+typedef struct {
+  UINT16  XRes;
+  UINT16  YRes;
+  UINT32  SerialNo;
+  UINT8   Week;
+  UINT8   Year;
+} PID_DATA;                             // 10 Bytes
+
+//
+// VBT Header
+//
+/**
+  This structure defines the VBT Header.
+**/
+typedef struct {
+  UINT8   Product_String[20]; ///< "$VBT_Cannonlake" is the product string
+  UINT16  Version_Num;        ///< Defines the VBT Header version number.
+  UINT16  Header_Size;        ///< Defines the size of VBT Header.
+  UINT16  Table_Size;         ///< Defines the size of complete VBT.
+  UINT8   Checksum;           ///< Defines the checksum of entire VBT
+  UINT8   Reserved1;          ///< Reserved field 1 of 1 byte.
+  UINT32  Bios_Data_Offset;   ///< Defines the offset of VBT Data block.
+  UINT32  Aim_Data_Offset[4]; ///< 4 reserved pointers to VBT data blocks.
+} VBT_HEADER;
+
+/**
+  This structure defines the VBT BIOS Data Block Header
+**/
+typedef struct {
+  UINT8   BDB_Signature[16];  ///< Defines the Bios Data Block signature "BIOS_DATA_BLOCK".
+  UINT16  BDB_Version;        ///< Defines the VBT (data) version.
+  UINT16  BDB_Header_Size;    ///< Defines the size of VBT Bios data block header.
+  UINT16  BDB_Size;           ///< Defines the size of Bios data block.
+} VBT_BIOS_DATA_HEADER;
+
+/**
+  This structure defines the BMP Signon Message and Copyright Message Structure
+**/
+typedef struct {
+  UINT8   BlockId;            ///< Defines Block ID : 254
+  UINT16  BlockSize;          ///< Defines the size of BMP Signon block.
+
+  UINT16  Bmp_BIOS_Size;      ///< Defines the BIOS size 32k/48k/64k.
+  UINT8   BIOS_Type;          ///< Defines the type of BIOS desktop or mobile.
+  UINT8   RelStatus;          ///< Defines the release status of the current GOP driver.
+  UINT8   BIOS_HW;            ///< Defines the Hardware i.e. Cannonlake.
+  UINT8   INT_HW;             ///< Defines the integrated hardware supported eDP/HDMI/DP.
+  UINT8   Build_Number[4];    ///< Defines the build number string.
+  UINT8   SignOn[155];        ///< Defines the sign on message.
+  UINT8   CopyRight[61];      ///< Defines the copyright message.
+} BMP_STRUCTURE_SIGNON;
+
+/**
+  This structure defines the BMP General Bits
+**/
+typedef struct {
+  UINT16  bmp_BIOS_CS;          ///< Defines the start of BIOS code segment
+  UINT8   bmp_DOS_Boot_Mode;    ///< Defines the mode number to set when DOS is boot
+  UINT8   bmp_BW_Percent;       ///< Set percentage of total memory BW
+  UINT8   bmp_Popup_Mem_Size;   ///< Default Popup memory size in KB
+  UINT8   bmp_Resize_PCI_BIOS;  ///< BIOS size granularity in 0.5 KB
+  UINT8   Switch_CRT_To_DDC2;   ///< Obsolete field: Is the CRT already switched to DDC2
+  UINT8   bmp_Allow_Config;     ///< Bit 1 : 1, Enable aspect ratio for DOS
+                                ///< Bit 0 : 1, Allow boot to DVI even if it is not attached.
+} BMPGEN;
+
+/**
+  This structure defines Block 254 (BMP structure)
+**/
+typedef struct {
+  BMP_STRUCTURE_SIGNON    bmp_Signon_Message;   ///< Instance of signon and copyright message structure
+  BMPGEN                  bmp_General_Bytes;    ///< Instance of BMP General Bits structure.
+} BLOCK254_BMP_Structure;
+
+/**
+  This structure defines Block 1 (General Bytes Definitions)
+**/
+typedef struct {
+  UINT8   BlockId;        ///< Defines the Block ID (1)
+  UINT16  BlockSize;      ///< Defines the size of General bytes definition block.
+
+  /**
+  BMP General Bit Definitions 1\n
+  Bit 7 = DVO A color flip bit
+    = 0, No DVO A color flip
+    = 1, Flip DVO A color
+  Bits 6:4 = Clear screen (CLS) after Signon
+      = 000, No CLS
+      = 001, 0.5 sec pause and then CLS
+      = 010, 1.0 sec pause and then CLS
+      = 011, 1.5 sec pause and then CLS
+      = 100, 2.0 sec pause and then CLS
+      = 101, 2.5 sec pause and then CLS
+      = 110, 3.0 sec pause and then CLS
+      = 111, 3.5 sec pause and then CLS
+  Bit 3 = 1  Enable Display Signon
+  Bit 2 = 1  Enable Flex-aim Support
+  Bits 1:0 = Flat panel fitting enabling
+      = 00, Centering
+      = 01, Reserved
+      = 10, Aspect scaling
+      = 11, Fullscreen
+  **/
+  union {
+    UINT8  Value;
+    struct {
+      UINT8 PanelFitterEnabling:2;
+      UINT8 FlexAimSupportEnable:1;
+      UINT8 DisplaySignonEnable:1;
+      UINT8 ClearScreenTime:3;
+      UINT8 DvoAColorFlipEnable:1;
+    } Bits;
+  } bmp_Bits_1;
+
+  /**
+  BMP General Bit Definitions\n
+  Bit 7 = Hot plug support
+    = 0, Hot plug disabled
+    = 1, Hot plug enabled
+  Bit 6 = Dynamic CD clock feature
+    = 0, Dynamic CD clock feature is disabled
+    = 1, Dynamic CD clock feature is enabled
+  Bit 5 = Underscan support for VGA timings
+  Bit 4 = Disable SSC in Dual Display Twin Mode. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, No
+    = 1, Yes
+  Bit 3 = LFP power state on override by 5f64h,08h
+    = 0, No Override
+    = 1, Override
+  Bit 2 = Internal LVDS SSC frequency. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, 96/120MHz
+    = 1, 100MHz
+  Bit 1 = internal LVDS SSC (Spread Spectrum Clock) (This field is obsolete now. Kept for VBIOS only.)
+    = 0, Disabled
+    = 1, Enabled
+  Bit 0 = KvmrSessionEnable.
+    = 0, Disabled
+    = 1, Enabled
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 KvmrSessionEnable:1;
+      UINT8 Reserved_1:5;
+      UINT8 DynamicCdClockEnable:1;
+      UINT8 HotPlugEnable:1;
+    } Bits;
+  } bmp_Bits_2;
+
+  /**
+  BMP General Bit Definitions 3\n
+  Bit 7 = Ignore strap status
+      = 0 Do not ignore
+      = 1 Ignore
+  Bit 6 = Panel Timing algorithm
+      = 0 Preferred timings
+      = 1 Best fit timings
+  Bit 5 Copy iLFP DTD to SDVO LVDS DTD
+      = 0 Don't copy DTD
+      = 1 Copy DTD to
+  Bit 4 = VBIOS normal/extd. DT mode
+      = 0 Normal mode
+      = 1 DUAL mode
+  Bit 3 = FDI RX Polarity
+      = 0 Normal
+      = 1 Inverted
+  Bit 2 = Enable 180 Degree Rotation
+      = 0  Disable
+      = 1  Enable
+  Bit 1 = Single DVI-I connector for CRT and DVI display: Obsolete field
+      = 0 Disabled
+      = 1 Enabled
+  Bit 0 = Smooth Vision
+      = 0  Disabled
+      = 1  Enabled
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 Reserved1:1;
+      UINT8 SingleDviiCrtConnector:1;
+      UINT8 Enable180DegRotation:1;
+      UINT8 FdiRxPolarity:1;
+      UINT8 Reserved2:4;
+    } Bits;
+  } bmp_Bits_3;
+
+  UINT8   Reserved;     ///< Reserved field. It was Legacy_Monitor_Detect in previous platforms.
+
+  /**
+  Integrated display device support\n
+  Bits 7:6 = Reserved
+  Bit 5 = DP SSC Dongle Enable/Disable
+  Bit 4 = DP SSC Frequency. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, 96 MHz
+    = 1, 100 MHz
+  Bit 3 = DP SSC Enable
+    = 0, Disable
+    = 1, Enable
+  Bit 2 = Integrated EFP support
+    = 0, Disable
+    = 1, Enable
+  Bit 1 = Integrated TV support. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, Disable
+    = 1, Enable
+  Bit 0 = Integrated CRT support: Obsolete field
+    = 0, Disable
+    = 1, Enable
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 CrtSupported:1;
+      UINT8 TvSupported:1;
+      UINT8 EfpSupported:1;
+      UINT8 DpSscEnable:1;
+      UINT8 DpSscFrequency:1;
+      UINT8 DpDongleSscEnable:1;
+      UINT8 Reserved1:2;
+    } Bits;
+  } Int_Displays_Support;
+} VBT_GENERAL1_INFO;
+
+/**
+  This defines the Structure of PRD Boot Table Entry
+**/
+typedef struct {
+  UINT8 AttachBits;     ///< Bitmap representing the displays attached currently.
+  UINT8 BootDev_PipeA;  ///< Bitmap representing the display to boot on Pipe A.
+  UINT8 BootDev_PipeB;  ///< Bitmap representing the display to boot on Pipe B.
+} PRD_TABLE;
+
+/**
+  This defines the structure of Block 254 (PRD Boot Table/Child Device List)
+**/
+typedef struct {
+  UINT8     BlockId;    ///< Defines the Block ID (254)
+  UINT16    BlockSize;  ///< Defines the size of Block 254
+
+  PRD_TABLE PRDTable[16];                     ///< Defines the Child device list for enumerating child handles.
+  UINT16    PRD_Boot_Table_Number_Of_Entries; ///< Number of entries in child device list.
+} PRD_BOOT_TABLE;
+
+/**
+  This defines the Structure for a CHILD_STRUCT (used for all the displays).
+**/
+typedef struct {
+  UINT16  DeviceHandle;         ///< Unique ID indicating the group of display device (LFP/EFP1/EFP2/EFP3/EFP4).
+  UINT16  DeviceClass;          ///< Indicates the class of display device.
+  UINT8   I2CSpeed;             ///< Defines the I2C speed to be used for I2C transaction.
+  /**
+  Defines the DP on board redriver configuration.
+  BIT[7]    : Reserved
+  BIT[6]    : Is On Board DP Redriver Present
+          0 : No
+          1 : Yes
+  BIT[5:3]  : On Board Redriver VSwing Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+     Others : Reserved
+  BIT[2:0]  : On Board Redriver PreEmph Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+  Others    : Reserved
+  **/
+  union{
+  UINT8 Value;
+  struct {
+    UINT8 OnBoardPreEmphLevel:3;
+    UINT8 OnBoardVSwingLevel:3;
+    UINT8 OnBoardRedriverPresent:1;
+    UINT8 Reserved:1;
+    } Bits;
+  } DpOnBoardRedriver;
+
+  /**
+  Defines the DP on dock redriver configuration.
+  BIT[7]    : Reserved
+  BIT[6]    : Is On Dock DP Redriver Present
+          0 : No
+          1 : Yes
+  BIT[5:3]  : On Dock Redriver VSwing Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+     Others : Reserved
+  BIT[2:0]  : On Dock Redriver PreEmph Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+  Others    : Reserved
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 OnDockPreEmphLevel:3;
+    UINT8 OnDockVSwingLevel:3;
+    UINT8 OnDockRedriverPresent:1;
+    UINT8 Reserved:1;
+    } Bits;
+  } DpOnDockRedriver;
+
+  /**
+
+  Defines the HDMI level shifter configuration.
+  BIT[7:5]  : Hdmi Maximum data rate
+  BIT[4:0]  : Hdmi Level shifter value
+
+  **/
+  union{
+  UINT8 Value;
+  struct {
+    UINT8 HdmiLevelShifterValue:5;
+    UINT8 HdmiMaxDataRateBits:3;
+    } Bits;
+  } HdmiLevelShifterConfig;
+
+  UINT16  EFPDTDBufferPointer;  ///< Pointer to the DTD timing to be used in case of edidless EFP.
+
+  /**
+  Defines the first set of flags.
+  BIT[7-4]  : Reserved
+  BIT[3]    : Dual pipe ganged display support
+          0 : Display uses a single pipe/port
+          1 : Display uses two distinct pipes/ports.
+  BIT[2]    : Compression Method Select
+          0 : Compression using picture parameter set (PPS)
+          1 : Compression using Capability parameter set (CPS)
+  BIT[1]    : Compression enable/disable for this display.
+          0 : Disabled
+          1 : Enabled
+  BIT[0]    : EDID less EFP Enable
+          0 : Enable support for EDID less EFP.
+          1 : Disable support for EDID less EFP.
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 EdidlessEfpEnable:1;
+    UINT8 CompressionEnable:1;
+    UINT8 CompressionMethod:1;
+    UINT8 IsDualPortEnabled:1;
+    UINT8 Reserved:4;
+    } Bits;
+  } Flags0;
+
+  /**
+  Defines the compression index field for the display.
+  BITS[7-4]  : Reserved
+  BITS[3-0]  : Compression Structure index in the block 55.
+        0x0  : Index 0 in block 55
+        0x1  : Index 1 in block 55
+        0xF  : Not Applicable.
+      Others : Reserved
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 IndexInBlock55:4;
+    UINT8 Reserved:4;
+    } Bits;
+  } CompressionStructureIndex;
+
+  UINT8   SlaveDdiPort;         ///< The DVO port number of slave DDI to be used in case Flags0[3] = 1.
+
+  UINT8   Reserved_1;           ///< Reserved and might be used in other platforms.
+  UINT16  AddInOffset;          ///< Obsolete field.
+  UINT8   DVOPort;              ///< Specifies the port number of the display device represented in the device class.
+  UINT8   I2CBus;               ///< Specifies the GMBUS or I2C pin pair for add in card.
+  UINT8   SlaveAddr;            ///< Specifies the I2C address of the add in card.
+  UINT8   DDCBus;               ///< Specifies the GMBUS pin pair for EDID read.
+  UINT16  TimingInfoPtr;        ///< Pointer to the buffer where VBIOS stores the EDID of device.
+  UINT8   DVOCfg;               ///< Obsolete field.
+
+  /**
+  Flags 1\n
+  Bits 7:5  : Reserved
+  Bit 4     : HPD Sense Invert
+          0 : Invert not required (default)
+          1 : Invert required
+  Bit 3     : IBoost feature enable/disable.
+          0 : IBoost feature is disabled.
+          1 : IBoost feature is enabled.
+  Bit 2     : Hdmi 2.0 Motherboard Downsuppotred options
+          0 : Motherboard Down chip not supported
+          1 : Motherboard Down Chip Supported on the Board
+  Bit 1     : Lane Reversal feature.
+          0 : Disable
+          1 : Enable
+  Bit 0     : DP/HDMI routed to dock.
+          0 : Disable
+          1 : Enable
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 DockablePort:1;
+    UINT8 EnableLaneReversal:1;
+    UINT8 OnBoardLsPconDonglePresent:1;
+    UINT8 IBoostEnable:1;
+    UINT8 IsHpdInverted:1;
+    UINT8 Reserved:3;
+    } Bits;
+  } Flags_1;
+
+  UINT8   Compatibility;        ///< Compatibility is used in VBIOS only. It was used before device class was defined.
+  UINT8   AUX_Channel;          ///< Specifies the aux channel to be used for display port devices.
+  UINT8   Dongle_Detect;        ///< Indicates whether dongle detect is enabled or not.
+  UINT8   Capabilities;         ///< Bits 1-0 indicate pipe capabilities whether display can be used on one pipe or both the pipes.
+  UINT8   DVOWiring;            ///< Obsolete field.
+  UINT8   MipiBridgeType;       ///< MIPI bridge type
+  UINT16  DeviceClassExtension; ///< Obsolete.
+  UINT8   DVOFunction;          ///< Obsolete.
+
+  /**
+  Flags 2
+  Bits 7:4  : DP Port trace length from silicon to output port on the board
+          0 : Default RVP length
+          1 : Short trace length
+          2 : Long trace length
+  Bits 3:2  : Reserved
+  Bit 1     : Indicates whether this port is Thunderbolt port or not.
+          0 : No
+          1 : Yes
+  Bit 0     : DP 2 lane RCR# 1024829: USB type C to enable 2 lane DP display
+          0 : Disable
+          1 : Enable
+  **/
+  union {
+    UINT8   Value;
+    struct {
+      UINT8   UsbTypeCDongleEnabled:1;  ///< Indicates whether this port is USB type C.
+      UINT8   IsThunderboltPort:1;      ///< Indicates whether this port is Thunderbolt. (ICL+)
+      UINT8   Reserved:2;               ///< Reserved for future use.
+      UINT8   DpPortTraceLength:4;      ///< Dp port trace length from silicon to port.
+    } Bits;
+  } Flags_2;
+  UINT8   DP2XGpioIndex;        ///< GPIO index number for the USB type C.
+  UINT16  DP2XGpioNumber;       ///< GPIO number for USB type C.
+
+  /**
+  IBoost magnitude field.
+  Bits 7:4  : DP Boost magnitude
+          0 : 1
+          1 : 3
+          2 : 7
+     Others : Reserved for WHL.
+  Bits 3:0  : HDMI Boost magnitude
+          0 : 1
+          1 : 3
+          2 : 7
+  Others : Reserved.
+  **/
+  union {
+    UINT8   Value;
+    struct {
+      UINT8   DpEdpBoostMagnitude:4;
+      UINT8   HdmiBoostMagnitude:4;
+    } Bits;
+  } BoostMagnitude;
+} CHILD_STRUCT;
+
+/**
+  This structure defines Block 2 (General Bytes Definitions)
+**/
+typedef struct {
+  UINT8         BlockId;          ///< Defines the Block ID : 2.
+  UINT16        BlockSize;        ///< Defines the size of VBT General Info 2 Block.
+
+  UINT8         bmp_CRT_DDC_GMBUS_Pin;  ///< Obsolete field: Selects the CRT DDC GMBUS pin pair.
+  UINT8         bmp_DPMS_Bits;          ///< BMP DPMS Bit Definitions.
+  UINT16        bmp_Boot_Dev_Bits;      ///< BMP Boot Device Bit Definitions.
+  UINT8         SizeChild_Struct;       ///< Size of the ChildStruc structure.
+
+  CHILD_STRUCT  Child_Struct[ChildStruct_MAX];  ///< This array defines all the supported child structures.
+} VBT_GENERAL2_INFO;
+
+/**
+  This defines the structure of Block 3 (Original Display Toggle List)
+**/
+typedef struct {
+  UINT8   BlockId;                ///< Defines the Block ID : 3
+  UINT16  BlockSize;              ///< Defines the size of Original Display Toggle List Block
+  UINT8   bmp_Display_Detect;     ///< Display must be attached or not
+} BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST;
+
+/**
+  This defines structure of a pointer table.
+**/
+typedef struct {
+  UINT16  Offset;       ///< Defines the offset of the table from start of BIOS Data block.
+  UINT16  Size;         ///< Defines the size of an entry of the table.
+} BMP_TABLE_PTR;
+
+/**
+  This structure defines Block 252 (SBIOS Hooks and BMP Table Pointers).
+**/
+typedef struct {
+  UINT8           BlockId;          ///< Defines the Block ID : 252.
+  UINT16          BlockSize;        ///< Defines the size of SBIOS Hooks block.
+  UINT8           SbiosHooks[18];   ///< This array defines a series of SBIOS hooks. Each entry represents one hook.
+  BMP_TABLE_PTR   BmpTablePtr[26];  ///< This array defines pointers to all the important tables in the VBT.
+} BLOCK252_SBIOS_Hook;
+
+/**
+  This defines the structure of MMIO boot table entry
+**/
+typedef struct {
+  UINT32  Register;   ///< Defines the MMIO offset of the register.
+  UINT32  Value;      ///< Defines the default value of the register.
+} MMIO_BOOT_TABLE;
+
+/**
+  This structure defines Block 6 (MMIO Register Block)
+**/
+typedef struct {
+  UINT8           BlockId;              ///< Defines the Block ID : 6
+  UINT16          BlockSize;            ///< Defines the size of MMIO Register Table block.
+  UINT16          RegTableId;           ///< Defines the ID for MMIO register table (0xFFFC).
+  UINT8           AccessFlag;           ///< Defines the flag for data access size (02 for 4 byte read/write).
+  MMIO_BOOT_TABLE MMIOBootTable[14];    ///< Array containing the MMIO register table.
+  UINT16          TableEnd;             ///< Special value describing End of table (0xFFFF).
+} BLOCK06_MMIO_REG_TABLE;
+
+/**
+  This structure defines Block 7 (IO SW Flag Register Table)
+**/
+typedef struct {
+  UINT8   BlockId;          ///< Defines Block ID (7).
+  UINT16  BlockSize;        ///< Defines the size of IO SW Flag register table block.
+  UINT16  RegTableId;       ///< Defines the ID for IO SW Flag register table (0xFFFE).
+  UINT8   GRIndexRegLsb;    ///< Defines the read/write size. Value is 0xCE meaning 1 byte without mask.
+  UINT8   IOSWFlagReg;      ///< Defines the offset for the IO SW Flag register.
+  UINT8   Value;            ///< Defines the data/value for the register.
+  UINT16  TableEnd;         ///< Special value describing the end of table (0xFFFF).
+} BLOCK07_IOSWFLAG_REG_TABLE;
+
+/**
+  This structure defines the entry of SWF table.
+**/
+typedef struct {
+  UINT32  Register;   ///< Defines the MMIO offset of the SWF register.
+  UINT32  Value;      ///< Defines the default value for the SWF register.
+} SWF_TABLE;
+
+/**
+  This defines the structure of Block 8 (MMIO SW Flag Block).
+**/
+typedef struct {
+  UINT8     BlockId;      ///< Defines the Block ID : 8.
+  UINT16    BlockSize;    ///< Defines the size of MMIO SWF register table block.
+  UINT16    RegTableId;   ///< Defines the ID for MMIO SWF register table (0xFFFC).
+  UINT8     AccessFlag;   ///< Defines the data access size. Value is 0x02 meaning 4 bytes read/write.
+  SWF_TABLE SWFTable[7];  ///< Array containing the MMIO SWF register table.
+  UINT16    TableEnd;     ///< Special value describing end of table (0xFFFF).
+} BLOCK08_MMIOSWFLAG_REG_TABLE;
+
+/**
+  This structure defines the PSR feature table entry.
+**/
+typedef struct {
+  UINT8   SRD_Enables;        ///< Defines PSR features such as full link enable/disable and whether aux is required to wake up.
+  UINT8   SRD_WaitTimes;      ///< Defines lines to wait before link standby and idle frames to wait before SRD enable.
+  UINT16  SRD_TP1_WakeupTime; ///< TP 1 wake up time in multiples of 100.
+  UINT16  SRD_TP2_WakeupTime; ///< TP2/TP3 wake up time in multiples of 100
+} PSR_FEATURE_TABLE;
+
+/**
+  This defines the structure of Block 9 (PSR Features Block)
+**/
+typedef struct {
+  UINT8             BlockId;              ///< Defines the block ID : 9
+  UINT16            BlockSize;            ///< Defines the size of PSR Feature block.
+  PSR_FEATURE_TABLE PSRFeatureTable[16];  ///< Array containing the PSR Feature table.
+} BLOCK09_PSR_FEATURE;
+
+/**
+  This structure defines an entry of Mode Removal table.
+**/
+typedef struct {
+  UINT16  XRes;         ///< X resolution of the mode.
+  UINT16  YRes;         ///< Y resolution of the mode.
+  UINT8   Bpp;          ///< Bits per pixel of the mode.
+  UINT16  RRate;        ///< Refresh rate of the mode.
+  UINT8   RFlags;       ///< Flags specifying display type and functional area where the mode is to be removed.
+  UINT16  PanelFlags;   ///< Applicable to LFP only. Indicates which LFP panels the mode is to be removed.
+} MODE_REMOVAL_TABLE_ENTRY;
+
+/**
+  This defines the structure of Block 10 (Mode Removal Block)
+**/
+typedef struct {
+  UINT8                     BlockId;              ///< Defines the Block ID : 10.
+  UINT16                    BlockSize;            ///< Defines the size of Mode Removal table block.
+  UINT8                     EntrySize;            ///< Defines the size of one entry of mode removal table.
+  MODE_REMOVAL_TABLE_ENTRY  ModeRemovalTable[20]; ///< Array containing the mode removal table.
+  UINT16                    Terminator;           ///< Special value indicating end of mode removal table (0xFFFF).
+} BLOCK10_MODE_REMOVAL_TABLE;
+
+/**
+  This defines the structure of Block 12 (Driver Features Data Block)
+**/
+typedef struct {
+  UINT8   BlockId;                  ///< Defines the unique Block ID : 12
+  UINT16  BlockSize;                ///< Defines the size of Driver features block.
+
+  /**
+  This field defines the various driver related bits:\n
+  Bit 7 = Use 00000110h ID for Primary LFP
+        = 0, No
+        = 1, Yes
+  Bit 6 = Enable/Disable Sprite in Clone Mode
+        = 0, Disable
+        = 1, Enable
+  Bit 5 = Driver INT 15h hook
+        = 0, Disable
+        = 1, Enable
+  Bit 4 = Dual View Zoom
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = Hot Plug DVO
+        = 0, Disable
+        = 1, Enable
+  Bit 2 = Allow display switching when in Full Screen DOS.
+        = 0, Block Display Switching
+        = 1, Allow Display Switching
+  Bit 1 = Block display switching when DVD active
+        = 0, No Block Display Switching
+        = 1, Block Display Switching
+  Bit 0 = Boot device algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  **/
+  UINT8   bmp_Driver_Bits;
+  UINT16  bmp_Driver_Boot_Mode_X;   ///< X resolution of driver boot mode.
+  UINT16  bmp_Driver_Boot_Mode_Y;   ///< Y resolution of driver boot mode.
+  UINT8   bmp_Driver_Boot_Mode_BPP; ///< Bits per pixel of driver boot mode.
+  UINT8   bmp_Driver_Boot_Mode_RR;  ///< Refresh rate of driver boot mode.
+
+  /**
+  This field defines the extended driver bits 1.\n
+  Bits [15:14] = Integrated HDMI configuration
+              = 00b,  No Integrated HDMI
+              = 01b,  Port-B Only
+              = 10b,  Port-C Only
+              = 11b,  Both Port-B and Port-C
+  Bits 13 = TV Hotplug
+  Bits [12:11]  = LFP configuration
+                = 00b,  No LVDS
+                = 01b,  Integrated LVDS
+                = 10b,  SDVO LVDS
+                = 11b,  eDP
+  Bit 10 = Obsolete field: CRT hotplug
+          = 0, Disabled
+          = 1, Enabled (Default)
+  Bit 9 = SDVO device power down
+        = 0, Disabled (Default)
+        = 1, Enabled
+  Bit 8 = Preserve Aspect Ratio
+        = 0, Disabled (Default)
+        = 1, Enabled
+  Bit 7 = Display "Maintain Aspect Scaling" via CUI
+        = 0, No
+        = 1, Yes (Default)
+  Bit 6 = Sprite Display Assignment when Overlay is Active in Clone Mode:
+        = 0, Secondary
+        = 1, Primary
+  Bit 5 = Default Power Scheme user interface
+        = 0, CUI
+        = 1, 3rd Party Application
+  Bit 4 = NT 4.0 Dual Display Clone Support
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = Default Render Clock Frequency
+        = 0, High Frequency
+        = 1, Low Frequency
+  Bit 2 = Dual-Frequency Graphics Technology
+        = 0, No
+        = 1, Yes
+  Bit 1 = Selective Mode Pruning
+        = 0, No
+        = 1, Yes
+  Bit 0 = Enable LFP as primary
+        = 0, Disable
+        = 1, Enable
+**/
+  UINT16  bmp_Ext_Driver_Bits;
+
+  /**
+  This defines the driver flags related to CUI Hot key.\n
+  Bits [7:3] - Reserved
+  Bit 2 = Display Subsystem Enable/Disable
+        = 0, Enable (default Value)
+        = 1, Disable
+  Bit 1 = Embedded Platform
+        = 0, False
+        = 1, True
+  Bit 0 = Define CUI HotK Displays Statically
+        = 0, No
+        = 1, Yes
+  **/
+  UINT8   bmp_Display_Detect_CUIHotK;
+
+  UINT16  bmp_Legacy_CRT_Max_X;         ///< Obsolete field: Defines the legacy CRT X resolution for driver boot mode.
+  UINT16  bmp_Legacy_CRT_Max_Y;         ///< Obsolete field: Defines the legacy CRT Y resolution for driver boot mode.
+  UINT8   bmp_Legacy_CRT_Max_RR;        ///< Obsolete field: Defines the legacy CRT refresh rate for driver boot mode.
+
+  /**
+  This field defines the extended driver bits 2.\n
+  Bits [7:1] - Reserved
+  Bit 0 = Enable Internal Source Termination for HDMI
+        = 0, External Termination
+        = 1, Internal Termination
+  **/
+  UINT8   bmp_Ext2_Driver_Bits;
+
+  UINT8   bmp_VBT_Customization_Version;  ///< Defines the customized VBT version number.
+
+  /**
+  This field defines all the driver feature flags.\n
+  Bit 15 = PC Features Field's Validity
+         = 0, Invalid
+         = 1, Valid
+  Bit 14 = Hpd_wake - HPD events are routed to display driver when system is in S0ix/DC9
+         = 0, Disable
+         = 1, Enable
+  Bit 13 = Assertive Display Technology (ADT)
+         = 0, Disable
+         = 1, Enable
+  Bit 12 = Dynamic Media Refresh Rate Switching (DMRRS)
+         = 0, Disable
+         = 1, Enable
+  Bit 11 = Dynamic Frames Per Second (DFPS)
+         = 0, Disable
+         = 1, Enable
+  Bit 10 = Intermediate Pixel Storage (IPS)
+         = 0, Disable
+         = 1, Enable
+  Bit 9 = Panel Self Refresh (PSR)
+        = 0, Disable
+        = 1, Enable
+  Bit 8 = Intel Turbo Boost Technology
+        = 0, Disable
+        = 1, Enable
+  Bit 7 = Graphics Power Modulation Technology (GPMT)
+        = 0, Disable
+        = 1, Enable
+  Bit 6 = Graphics Render Standby (RS)
+        = 0, Disable
+        = 1, Enable
+  Bit 5 = Intel Display Refresh Rate Switching (DRRS)
+        = 0, Disable
+        = 1, Enable
+  Bit 4 = Intel Automatic Display Brightness (ADB)
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = DxgkDDI Backlight Control (DxgkDdiBLC)
+        = 0, Disable
+        = 1, Enable
+  Bit 2 = Intel Display Power Saving Technology (DPST)
+        = 0, Disable
+        = 1, Enable
+  Bit 1 = Intel Smart 2D Display Technology (S2DDT)
+        = 0, Disable
+        = 1, Enable
+  Bit 0 = Intel Rapid Memory Power Management (RMPM)
+        = 0, Disable
+        = 1, Enable
+  **/
+  UINT16  bmp_Driver_Feature_Flags;
+} BLOCK12_DRIVER_FEATURES;
+
+/**
+  This defines the structure of Block 13 (Driver Persistence Options)
+**/
+typedef struct {
+  UINT8   BlockId;                ///< Defines the unique Block ID : 13
+  UINT16  BlockSize;              ///< Defines the size of Driver Persistence options block.
+
+  /**
+  Defines the various persistence options.\n
+  Bits [15:10] - Reserved
+  Bit 9 = Docking Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 8 = DVO Hot Plug Persistence on Mode
+  Bit 7 = EDID Persistence on Mode
+  Bit 6 = Hot Key Persistence on Mode
+        = 0, No
+        = 1, Yes
+  Bit 5 = Hot Key Persistence on RestorePipe
+        = 0, No
+        = 1, Yes
+  Bit 4 = Hot Key Persistence on RefreshRate
+        = 0, No
+        = 1, Yes
+  Bit 3 = Hot Key Persistence on MDS/Twin
+        = 0, No
+        = 1, Yes
+  Bit 2 = Power Management Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 1 = Lid Switch Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 0 = Hot Key Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  **/
+  UINT16  PersistenceAlgorithm;
+
+  UINT8   PersistMaxconfig;       ///< Maximum mode persistence configurations (10-200)
+} BLOCK13_DRIVER_PERSISTENCE;
+
+/**
+  This defines the structure of Block 17 (SV Bits)
+**/
+typedef struct {
+  UINT8   BlockId;      ///< Defnies the unique Block ID : 17
+  UINT16  BlockSize;    ///< Defines the size of SV Bits block.
+
+  /**
+  Bits [7:4] = Reserved
+    Bit3  = Allow VBlank/VblankScanline timeout hang
+          = 0, Disable
+          = 1, Enable
+    Bit2  = Special GMBus support
+          = 0, Disable
+          = 1, Enable
+    Bit1  = Skip program pipe timings when set VGA modes
+          = 0, Setmode skip DVO Update
+          = 1, Setmode updates DVO
+    Bit0  = Disable VGA fast arbiter
+          = 0, Enabled
+          = 1, Disabled
+  **/
+  UINT8   SvBits1;
+  UINT8   SvBits2;      ///< Reserved for future use.
+  UINT8   SvBits3;      ///< Reserved for future use.
+  UINT8   SvBits4;      ///< Reserved for future use.
+  UINT8   SvBits5;      ///< Reserved for future use.
+  UINT8   SvBits6;      ///< Reserved for future use.
+  UINT8   SvBits7;      ///< Reserved for future use.
+  UINT8   SvBits8;      ///< Reserved for future use.
+} BLOCK17_SV_BITS;
+
+/**
+  This defines the structure of Block 18 (Driver Rotation)
+**/
+typedef struct {
+  UINT8   BlockId;                    ///< Defines the unique Block ID : 18
+  UINT16  BlockSize;                  ///< Defines the size of Driver Rotation block.
+  UINT8   RotationFeatureSupport;     ///< Rotation feature support field used by driver.
+  UINT8   Reserved1;                  ///< Reserved for future use.
+  UINT16  Reserved2;                  ///< Reserved for future use.
+  UINT32  Reserved3;                  ///< Reserved for future use.
+  UINT32  Reserved4;                  ///< Reserved for future use.
+} BLOCK18_DRIVER_ROTATION;
+
+/**
+  This structure defines an entry of OEM mode table.
+**/
+typedef struct {
+  /**
+  Mode Flags:
+    Bits[7:3] = Reserved
+    Bit 2 = Enable/disable this OEM mode in GOP driver.
+    Bit 1 = Enable/disable this mode in Driver
+    Bit 0 = Enable/disable this mode in VBIOS
+  **/
+  UINT8   ModeFlags;
+
+  /**
+  Display Device Flags:
+    Bit 7 = LFP2
+    Bit 6 = EFP2
+    Bit 5 = EFP3
+    Bit 4 = EFP4
+    Bit 3 = LFP
+    Bit 2 = EFP
+    Bit 1 = Rsvd
+    Bit 0 = Rsvd
+  **/
+  UINT8   DisplayFlags;
+  UINT16  XRes;         ///< Defines the X resolution of the mode.
+  UINT16  YRes;         ///< Defines the Y resolution of the mode.
+
+  /**
+  Defines the bits per pixel of the mode.
+    Bit 7:3 = Reserved
+    Bit 2 = 32 BPP
+    Bit 1 = 16 BPP
+    Bit 0 = 8 BPP
+  **/
+  UINT8   Bpp;
+  UINT8   RRate;        ///< Defines the refresh rate of the mode.
+  DTD_STRUCTURE Dtd;    ///< Defines the 18 byte timing config for the mode.
+} OEM_MODE_ENTRY;
+
+/**
+  This defines the structure of Block 20 (OEM Mode Customization Block)
+**/
+typedef struct {
+  UINT8           BlockId;          ///< Defines the unique block ID : 20
+  UINT16          BlockSize;        ///< Defines the size of OEM customization block.
+  UINT8           NumOfEntry;       ///< Defines the number of entries in OEM Mode table.
+  UINT8           EntrySize;        ///< Defines the size of one entry of OEM Mode table.
+  OEM_MODE_ENTRY  OemModeTable[6];  ///< Array defining the OEM mode table.
+} BLOCK20_OEM_CUSTOMIZATION;
+
+/**
+  This defines the structure of Block 26 (TV options)
+**/
+typedef struct {
+  UINT8   BlockId;                  ///< Defines the unique Block ID : 26
+  UINT16  BlockSize;                ///< Defines the size of TV Options block.
+
+  /**
+  Defines the TV options:
+    Bit 15  = D-Conector Support
+            = 0, Disable
+            = 1, Enable
+    Bit 14 = Add 1776x1000 when 1080i is selected and add 1184x666 when 720p is selected
+            = 0, Disable
+            = 1, Enable
+    Bit 13:12 Underscan/overscan for HDTV via DVI
+            = 00b, Enable Underscan and Overscan modes (Default)
+            = 01b, Enable only overscan modes
+            = 10b, Enable only underscan modes
+    Bits 11:2 = Reserved
+    Bit 1:0 = Underscan/overscan for HDTV via Component (YPrPb)
+            = 00b, Enable Underscan and Overscan modes (Default)
+            = 01b, Enable only overscan modes
+            = 10b, Enable only underscan modes
+  **/
+  UINT16  bmp_TV_Options_1;
+} BLOCK26_TV_OPTIONS;
+
+/**
+  This structure defines the eDP panel power sequencing parameters.
+**/
+typedef struct {
+  UINT16  T3;         ///< Panel Power-Up Delay.
+  UINT16  T8;         ///< Panel Power-On to backlight Enable Delay.
+  UINT16  T9;         ///< Backlight-Off to Power-Down Delay.
+  UINT16  T10;        ///< Power-Down Delay.
+  UINT16  T12;        ///< Power Cycle Delay.
+} EDP_PWR_SEQ;
+
+/**
+  This structure defines the PWM<-->Backlight delays for a single eDP panel.
+**/
+typedef struct {
+  UINT16  PwmOnToBacklightEnableDelay;      ///< PWM on to backight enable delay.
+  UINT16  BacklightDisableToPwmOffDelay;    ///< Backlight disable to PWM off delay.
+} EDP_PWM_BACKLIGHT_DELAYS;
+
+/**
+  This defines FLT parameters for a single eDP panel.
+  Bits[15:12] : VSwing level
+            0 : 0.4V (default)
+            1 : 0.6V
+            2 : 0.8V
+            3 : 1.2V
+       Others : Reserved
+  Bits[11:8]  : Pre-emphasis level
+            0 : no pre-emphasis (default)
+            1 : 3.5dB
+            2 : 6dB
+            3 : 9.5dB
+       Others : Reserved
+  Bits[7:4]   : Lane count (port width)
+            0 : x1 mode (default)
+            1 : x2 mode
+            2 : Reserved
+            3 : x4 mode
+       Others : Reserved
+  Bits[3:0]   : data rate
+            0 : 1.62 Gbps
+            1 : 2.7 Gbps
+            2 : 5.4 Gbps
+       Others : Reserved
+**/
+typedef union {
+  UINT16 Value;
+  struct {
+    UINT16 DataRate:4;
+    UINT16 LaneCount:4;
+    UINT16 PreEmphasisLevel:4;
+    UINT16 VSwingLevel:4;
+  } Bits;
+} EDP_FAST_LINK_TRAINING_PARAMS;
+
+/**
+  This defines Full link training parameters for a single eDP panel.
+  Bits[7:4] : VSwing level
+          0 : 0.4V (default)
+          1 : 0.6V
+          2 : 0.8V
+          3 : 1.2V
+     Others : Reserved
+  Bits[3:0] : Pre-emphasis level
+          0 : no pre-emphasis (default)
+          1 : 3.5dB
+          2 : 6dB
+          3 : 9.5dB
+     Others : Reserved
+**/
+typedef union {
+  UINT8   Value;
+  struct {
+    UINT8   PreEmphasisLevel:4;
+    UINT8   VSwingLevel:4;
+  } Bits;
+} EDP_FULL_LINK_TRAINING_PARAMS;
+
+/**
+  This defines the structure of Apical Parameters for a single eDP panel.
+**/
+typedef struct {
+  UINT32      PanelOui;             ///< Apical IP specific field for Panel OUI
+  UINT32      DPCDBaseAddress;      ///< Apical IP specific field for DPCD Base address
+  UINT32      DPCDIrdidixControl0;  ///< Apical IP specific field for DPCD Idridix Control 0
+  UINT32      DPCDOptionSelect;     ///< Apical IP specific field for DPCD option select
+  UINT32      DPCDBacklight;        ///< Apical IP specific field for DPCD backlight
+  UINT32      AmbientLight;         ///< Apical IP specific field for Ambient light
+  UINT32      BacklightScale;       ///< Apical IP specific field for backlight scale
+} EDP_APICAL_PARAMS;
+
+/**
+  This defines the structure of Block 27 (eDP Display Block)
+**/
+typedef struct {
+  UINT8       BlockId;            ///< Defines the unique Block ID : 27
+  UINT16      BlockSize;          ///< Defines the size of eDP display VBT block.
+
+  EDP_PWR_SEQ eDP_PWR_SEQ[16];    ///< Array defining the panel power sequencing for all 16 eDP panels.
+
+  /**
+  Defines the panel color depth in bits per pixel. 2 Bits for each Panel.
+    Bits[1:0] Panel color depth for Panel #1
+      = 00, 18bpp
+      = 01, 24bpp
+      = 10, 30bpp
+      = 11, 36bpp
+  **/
+  UINT32      eDP_Panel_Color_Depth;
+
+  /**
+    Array containing the FLT parameters of 16 eDP panels.
+  **/
+  EDP_FAST_LINK_TRAINING_PARAMS      eDP_Fast_Link_Training_Params[16];
+
+  /**
+  This field defines the eDP sDRRS MSA Timing Delay for all 16 eDP panels. 2 Bits for Each Panel.
+  Bits[1:0] for Panel #1
+    = 00, Line 1
+    = 01, Line 2
+    = 10, Line 3
+    = 11, Line 4
+  **/
+  UINT32      eDP_sDRRS_MSA_Delay;
+
+  /**
+  Defines the S3D feature enable/disable for all 16 eDP panels. 1 Bit for Each Panel.
+  Bits[0] for Panel #1
+    = 0, S3D disabled for this panel
+    = 1, S3D enabled for this panel
+  **/
+  UINT16      eDP_S3D_Feature;
+
+  /**
+  Defines the T3 optimization enable/disable for all 16 panels. 1 Bit for each panel.
+  Bits[0] = Panel #1
+    = 0, T3 optimization disabled for this panel
+    = 1, T3 optimization enabled for this panel
+  **/
+  UINT16      eDP_T3_Optmization;
+
+  /**
+  Defines the Edp vswing and pre-emphasis for all 16 panels. 4 Bits for Each Panel
+  Bits[3:0] = Panel #1
+    = 0, Use table 1 for this panel.
+    = 1, Use table 2 for this panel.
+  **/
+  UINT64       VswingPreEmphasisTableNum;
+
+  /**
+  Defines the Edp fast link training support on all 16 panels. 1 Bit for Each Panel
+  Bits[0] = Panel #1
+    = 0, FastLinkTraining feature is disabled for this panel
+    = 1, FastLinkTraining feature is enabled for this panel
+  **/
+  UINT16     EdpFastLinkTrainingSupportOnPanel;
+
+  /**
+  Defines whether the Set power state at DPCD 600h is to be done in eDP enable/disable sequence.
+  Bits[0] = Panel #1
+    = 0, Set power state at DPCD 600h feature is disabled for this panel
+    = 1, Set power state at DPCD 600h feature is enabled for this panel
+  **/
+  UINT16     SetPowerStateAtDPCD600h; //This is not used currently
+
+  /**
+    Array defining the PWM <--> Backlight related delays for 16 panels.
+  **/
+  EDP_PWM_BACKLIGHT_DELAYS eDP_Pwm_BackLight_Delays[16];
+
+  /**
+  Defines the Edp full link training support on all 16 panels. 1 Bit for Each Panel.
+  \verbatim
+  Bits[0] : Panel #1
+        0 : Initial vswing and pre-emphasis levels are not provided for Full link training
+        1 : Initial vswing and pre-emphasis levels are provided for Full link training
+  Bits 1 to 15 are for panel # 2 to 16.
+  \endverbatim
+  **/
+  UINT16     InitialFullLinkTrainingParamsProvidedInVbt;
+
+  /**
+    Array containing the initial Vswing and Pre-emphasis parameters for Full link training.
+  **/
+  EDP_FULL_LINK_TRAINING_PARAMS    eDP_Full_Link_Training_Params[16];
+
+  /**
+  Defines the Edp Apical assertive display IP support on all 16 panels. 1 Bit for Each Panel.
+  Bit 0   : Panel #1
+        0 : Apical assertive display IP is disabled for this panel.
+        1 : Apical assertive display IP is enabled for this panel.
+  Bits 1 to 15 are for panel # 2 to 16.
+  **/
+  UINT16                           IsApicalAssertiveDisplayIpEnable;
+
+  /**
+    Array containing the Apical parameters for all 16 panels
+  **/
+  EDP_APICAL_PARAMS                eDP_Apcial_Params[16];
+} BLOCK27_EDP_FEATURES;
+
+/**
+  This defines the structure of Block 28 (Edidless EFP support DTD timings)
+**/
+typedef struct {
+  UINT8                 BlockId;                    ///< Defines the unique Block ID : 28
+  UINT16                BlockSize;                  ///< Defines the size of Edidless EFP support block.
+  DTD_STRUCTURE         Edidless_EFP_DTD_Struc[4];  ///< Array defining the DTD timing for 3 EFP devices.
+} BLOCK28_EDIDLESS_EFP;
+
+/**
+This defines the structure of toggle list entry.
+**/
+typedef struct {
+  /**
+  Defines the display device selection for toggling
+  Bit 15 = EFP4.3 (Reserved for WHL)
+  Bit 14 = EFP3.3
+  Bit 13 = EFP2.3
+  Bit 12 = EFP1.3
+  Bit 11 = EFP4.2 (Reserved for WHL)
+  Bit 10 = EFP3.2
+  Bit 9  = EFP2.2
+  Bit 8  = EFP1.2
+  Bit 7  = LFP2
+  Bit 6  = EFP2
+  Bit 5  = EFP3
+  Bit 4  = EFP4
+  Bit 3  = LFP
+  Bit 2  = EFP
+  Bit 1  = TV
+  Bit 0  = CRT
+  **/
+  UINT16  DisplayDevice;
+} CNL_TOGGLE_LIST_ENTRY;
+
+/**
+  This defines the structure of Block 31 (Toggle Lists for Cannonlake)
+**/
+typedef struct {
+  UINT8                   BlockId;              ///< Defines the unique Block ID : 31
+  UINT16                  BlockSize;            ///< Defines the size of Toggle List Block.
+  UINT16                  NumOfEntry1;          ///< Defines the number of entries in toggle list 1.
+  UINT8                   EntrySize1;           ///< Defines the size of toggle list entry present in list 1.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList1Entry[16]; ///< Array defining the toggle list 1.
+  UINT16                  NumOfEntry2;          ///< Defines the number of entries in toggle list 2.
+  UINT8                   EntrySize2;           ///< Defines the size of toggle list entry present in list 2.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList2Entry[8];  ///< Array defining the toggle list 2.
+  UINT16                  NumOfEntry3;          ///< Defines the number of entries in toggle list 3.
+  UINT8                   EntrySize3;           ///< Defines the size of toggle list entry present in list 3.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList3Entry[8];  ///< Array defining the toggle list 3.
+  UINT16                  NumOfEntry4;          ///< Defines the number of entries in toggle list 4.
+  UINT8                   EntrySize4;           ///< Defines the size of toggle list entry present in list 4.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList4Entry[8];  ///< Array defining the toggle list 4.
+} BLOCK31_TOGGLE_LIST;
+
+/**
+  This defines the structure of Display device removal configuration entry.
+**/
+typedef struct {
+  /**
+  Defines the display device configuration to be removed.
+  Bit 15 = EFP4.3 (Reserved for WHL)
+  Bit 14 = EFP3.3
+  Bit 13 = EFP2.3
+  Bit 12 = EFP1.3
+  Bit 11 = EFP4.2 (Reserved for WHL)
+  Bit 10 = EFP3.2
+  Bit 9  = EFP2.2
+  Bit 8  = EFP1.2
+  Bit 7  = LFP2
+  Bit 6  = EFP2
+  Bit 5  = EFP3
+  Bit 4  = EFP4
+  Bit 3  = LFP
+  Bit 2  = EFP
+  Bit 1  = TV
+  Bit 0  = CRT
+  **/
+  UINT16  DisplayDeviceConfiguration;
+} CNL_DISPLAY_CONFIGURATION_ENTRY;
+
+/**
+  This defines the structure of Block 32 (Display removal configuration Block)
+**/
+typedef struct {
+  UINT8                                BlockId;       ///< Defines the unique Block ID = 32
+  UINT16                               BlockSize;     ///< Defines the size of Display removal configuration block.
+  UINT8                                NumOfEntry;    ///< Defines the number of entries in display removal configuraion table.
+  UINT8                                EntrySize;     ///< Defines the size of 1 entry in display removal configuration table.
+  CNL_DISPLAY_CONFIGURATION_ENTRY      RemoveDisplayConfiguration[15];    ///< Array defining the display removal configuration table.
+}BLOCK32_DISPLAY_CONFIGURATION_REMOVAL;
+
+/**
+  This defines the Local Flat panel basic details such as resolution and the various registers.
+**/
+typedef struct {
+  UINT16  XRes;                   ///< X resolution of the panel.
+  UINT16  YRes;                   ///< Y resolution of the panel.
+  UINT32  LVDSDigDisReg;          ///< MMIO offset of LFP digital display port register.
+  UINT32  LVDSDigDisVal;          ///< Value of LFP digital display port register.
+  UINT32  OnSeqDelayReg;          ///< MMIO offset of Panel power on sequencing delay register.
+  UINT32  OnSeqDelayVal;          ///< Value of Panel power on sequencing delay register.
+  UINT32  OffSeqDelayReg;         ///< MMIO offset of Panel power off sequencing delay register.
+  UINT32  OffSeqDelayVal;         ///< Value of Panel power off sequencing delay register.
+  UINT32  CycleDelay_RefDivReg;   ///< MMIO offset of Panel power cycle delay and reference divider register.
+  UINT32  CycleDelay_RefDivVal;   ///< Value of Panel power cycle delay and reference divider register.
+  UINT16  Terminate;              ///< Special value 0xFFFF indicating end of data.
+} FP_DATA;
+
+/**
+  This defines the structure consisting of all details for a single Local Flat panel.
+**/
+typedef struct {
+  FP_DATA       FP_Data;      ///< Instance of ::FP_DATA structure.
+  DTD_STRUCTURE DTD_Data;     ///< Instance of ::DTD_STRUCTURE which contains the DTD timings for the panel.
+  PID_DATA      PID_Data;     ///< Instance of ::PID_DATA structure which contains panel related information used by driver.
+} LVDS_FP_TABLE;
+
+/**
+  This structure defines all the details regarding Backlight control for LFP.
+**/
+typedef struct {
+  /**
+  Defines the backlight features for the panel.
+  Bits 7:6  = GMBus Speed:
+            = 00, 100 KHz
+            = 01, 50 KHz
+            = 10, 400 KHz
+            = 11, 1 MHz
+  Bits 5:3  = Inverter GPIO Pins
+            = 0, None
+            = 1, I2C GPIO pins
+            = 2, Analog CRT DDC pins
+            = 3, DVI/LVDS DDC GPIO pins
+            = 5, sDVO I2C GPIO pins
+  Bit 2     = Inverter Polarity (i2c & PWM)
+            = 0, Normal (0 = Minimum brightness)
+            = 1, Inverted (0 = Maximum brightness)
+  Bits 1:0  = BLC Inverter Type
+            = 00, None/External
+            = 01, i2c
+            = 10, PWM
+            = 11, Reserved
+  **/
+  UINT8   BLC_Ftr;
+
+  UINT16  PWM_Freq;       ///< PWM inverter frequency in KHz
+  UINT8   Min_Brightness; ///< Minimum brightness in the range 0-255
+  UINT8   I2C_Add;        ///< I2C Inverter Slave Address
+  UINT8   I2C_Command;    ///< I2C Inverter command code
+} BLC;
+
+/**
+  This defines the structure of Block 40 (LFP Features)
+**/
+typedef struct {
+  UINT8   BlockId;          ///< Defines the unique Block ID : 40
+  UINT16  BlockSize;        ///< Defines the size of LFP Features block.
+
+  UINT8   bmp_Panel_type;   ///< Defines the panel type of LFP.
+  UINT8   Skip1;            ///< Obsoleted.
+
+  /**
+  Capabilities byte:
+  Bit 15:7  = SW Workaround bits
+  Bit 6     = Panel EDID support
+            = 0, Disable
+            = 1, Enable
+  Bit 5     = Pixel dithering
+            = 0, Disable
+            = 1, Enable
+  Bit 4     = Panel Fitting ratio calc.
+            = 0 - Manual
+            = 1 - Automatic
+  Bit 3     = Panel Fitting Graphics mode
+            = 0, Bilinear
+            = 1, Enhanced
+  Bit 2     = Panel Fitting Text mode
+            = 0, Bilinear
+            = 1, Enhanced
+  Bit 1:0   = Panel Fitting Support
+            = 00, No panel fitting
+            = 01, Text panel fitting
+            = 10, GFX panel fitting
+            = 11, Text+GFX panel fitting
+  **/
+  UINT16  bmp_LVDS_Capabilities;
+
+  /**
+  Defines the channel type of LFP. 2 Bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Automatic (algorithm)
+    = 01, Single Channel
+    = 10, Dual Channel
+    = 11, Reserved
+  **/
+  UINT32  INT_LVDS_Panel_Channel_Bits;
+
+  UINT16  Enable_SSC_Bit;         ///< LVDS Spread Spectrum Clock
+  UINT16  SSC_Freq_Bit;           ///< LVDS Spread Spectrum Clock Frequency
+  UINT16  Disable_SSC_DDT_Bit;    ///< Disable SSC in Dual Display Twin
+
+  /**
+  Defines the panel color depth. 1 Bits for each Panel.
+  Bits[0] for Panel #01
+    = 0, 18bpp
+    = 1, 24bpp
+  **/
+  UINT16  INT_Panel_Color_Depth;
+
+  /**
+  Defines the Panel type. 2 Bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Static DRRS
+    = 01, D2PO
+    = 10, Seamless
+    = 11, Reserved
+  **/
+  UINT32  DPS_Panel_Type_Bits;
+
+  /**
+  Defines the type of backlight control for the LFP. 2 bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Default
+    = 01, CCFL backlight
+    = 10, LED backlight
+    = 11, Reserved
+  **/
+  UINT32  BLT_Control_Type_Bits;
+  /**
+  Defines the LFP power enable flag in S0 state for all 16 panels. 1 Bit for Each Panel.
+  Bits[0] : Panel #1
+        0 : Do not keep LCDVCC on during S0 state.
+        1 : Keep LCDVCC on during S0 state.
+  Bits 1 to 15 are for panel # 2 to 16.
+  **/
+  UINT16     LcdvccOnDuringS0State;
+} BLOCK40_LVDS_FEATURES;
+
+/**
+  This structure defines the second type of BMP table pointers.
+  This is used to store pointers to LFP Flat panel data, DTD and PID information.
+**/
+typedef struct {
+  UINT16  Offset;       ///< Offset of the table.
+  UINT8   Size;         ///< Size of the table.
+} BMP_TABLE_TYPE2_PTR;
+
+/**
+  This structure defines a set of 3 pointers for LFP display.
+  These pointers point to FP data, DTD and PID information respectively.
+**/
+typedef struct {
+  BMP_TABLE_TYPE2_PTR   FpTablePtr;   ///< Pointer to FP Data of the LFP panel.
+  BMP_TABLE_TYPE2_PTR   DtdTablePtr;  ///< Pointer to DTD of the LFP panel.
+  BMP_TABLE_TYPE2_PTR   PidTablePtr;  ///< Pointer to the PID data of the LFP panel.
+} LFP_TABLE_POINTERS;
+
+/**
+  This defines the structure of Block 41 (LFP Table Pointers for FPDATA, DTD and PID)
+**/
+typedef struct {
+  UINT8               BlockId;                  ///< Defines the unique Block ID:41
+  UINT16              BlockSize;                ///< Defines the size of LFP Table Pointer Block.
+  UINT8               NumOfEntries;             ///< Defines the number of entries in the Table.
+  LFP_TABLE_POINTERS  LfpTablePointers[16];     ///< Array of ::LFP_TABLE_POINTERS for all 16 panels.
+  UINT16              LfpPanelNameTableOffset;  ///< Offset of LFP panel names table.
+  UINT8               LfpPanelNameLength;       ///< Length of a single LFP panel's name.
+} BLOCK41_LFP_TABLE_POINTERS;
+
+/**
+  This defines the structure of Block 42 (Complete LFP Panel Information)
+**/
+typedef struct {
+  UINT8         BlockId;                ///< Defines the unique block ID : 42
+  UINT16        BlockSize;              ///< Defines the size of Complete LFP panel information for all 16 panels.
+  LVDS_FP_TABLE LVDS_FP_Table[16];      ///< Array of ::LVDS_FP_TABLE containing data of 16 panels.
+  UINT8         LFP_PANEL_NAMES[16][13];///< Array defining the panel names for all 16 panels.
+
+  /**
+  1 Bit for Each Panel
+  Bit0  = Scaling feature for panel 1.
+        = 0, Scaling feature is disabled for this panel.
+        = 1, Scaling feature is enabled for this panel.
+  **/
+  UINT16        EnableScaling; //This is not used currently
+
+  /**
+    Array defining DRRS minimum refresh rate. 1 Byte for Each Panel.
+  **/
+  UINT8         Seamless_DRRS_Min_RR[16];
+
+  /**
+    Array defining Pixel Overlap Count. 1 Byte for Each Panel.
+  **/
+  UINT8         PixelOverlapCount[16];
+} BLOCK42_LVDS_PANEL_INFO;
+
+typedef union {
+  /**
+  Backlight control parameters.\n
+  Bits 7:4  : PWM Controller Selection
+          0 : Controller 0
+          1 : Controller 1
+          2 : Controller 2
+          3 : Controller 3
+     Others : Reserved.
+  Bits 3:0  : PWM Source Selection
+          0 : PMIC PWM
+          1 : LPSS PWM
+          2 : DISPLAY PWM
+          3 : CABC PWM
+     Others : Reserved.
+  **/
+  UINT8 Value;
+  struct {
+    UINT8 PwmSourceSelection:4;
+    UINT8 PwmControllerSelection:4;
+  } Bits;
+} BKLT_CTRL_PARAMS;
+
+/**
+  This defines the structure of Block 43 (LFP Brightness Control)
+**/
+typedef struct {
+  UINT8             BlockId;                ///< Defines the unique Block ID : 43
+  UINT16            BlockSize;              ///< Defines the size of Brightness control block.
+
+  UINT8             SIZE_BLCStruc;          ///< Defines the size of single entry in Backlight control table for LFP.
+  BLC               BLC_Struct[16];         ///< Array defining the backlight control for 16 LFP panels.
+  UINT8             Post_Brightness[16];    ///< Array defining the initial brightness for all 16 panels.
+  BKLT_CTRL_PARAMS  Brightness_Control[16]; ///< Array defining the brightness control method for all 16 panels
+} BLOCK43_LVDS_BLC;
+
+/**
+  This defines the structure of Block 44 (LFP Power Conservation Features)
+**/
+typedef struct {
+  UINT8   BlockId;        ///< Defines the unique block ID : 44
+  UINT16  BlockSize;      ///< Defines the size of LFP Power Conservation Features block.
+  union {
+  /**
+  Bit[7]        : ALS Enable/Disable
+               0 - Disable
+               1 - Enable
+  Bit[6]        : Display LACE support
+               0 - Not supported
+               1 - Supported
+  Bit[5]        : Default Display LACE enabled status
+               0 - Disabled
+               1 - Enabled
+  Bit[4]        : Reserved
+  Bit[3:1]      : Power conservation preference level.
+                 4 is default in a range of 1 to 6.
+  Bit[0]        : Reserved
+  **/
+    UINT8  Value;
+    struct {
+      UINT8 Reserved:1;
+      UINT8 PwrConservation:3;
+      UINT8 Reserved_1:1;
+      UINT8 DefalutDisplayLaceEnable:1;
+      UINT8 DisplayLaceSupport:1;
+      UINT8 AlsEnable:1;
+    } Bits;
+  } LfpFeatureBits;
+
+  UINT16  AlsData[10];    ///< Defines the main ALS data.
+
+  union {
+  /**
+  Bit[7:3]      : Reserved
+  Bit[2:0]      : Aggressiveness Level Profile.
+            000 - Minimum
+            001 - Moderate
+            010 - High
+  **/
+    UINT8  Value;
+    struct {
+      UINT8 AggressionProfileLevel:3;
+      UINT8 Reserved:5;
+    } Bits;
+  } LaceAggressivenessProfile; ///< Defines the LACE Aggressiveness Profile
+} BLOCK44_ALS;
+
+/**
+  This defines the structure of Black Frame Insertion table entry.
+**/
+typedef struct {
+  /**
+  BFI Features\n
+  Bit[7-2]  : Reserved\n
+  Bit[1]    : Enable Brightness control in CUI\n
+  Bit[0]    : Enable BFI in driver
+  **/
+  UINT8         EnableBits;
+  UINT8         BrightnessNonBFI;   ///< Brightness percentage in non BFI mode
+} BFI;
+
+/**
+  This defines the structure of Block 45 (Black Frame insertion Support for LFP)
+**/
+typedef struct {
+  UINT8              BlockId;         ///< Defines the unique Block ID : 45
+  UINT16             BlockSize;       ///< Defines the size of Black frame insertion support block.
+  UINT8              SIZE_BFIStruc;   ///< Defines the size of 1 entry of black frame data.
+  BFI                BFI_Struct[16];  ///< Array defining the data of black frame insertion for all 16 panels.
+} BLOCK45_BFI_SUPPORT;
+
+/**
+  This structure defines the chromaticity information for a single LFP panel.
+**/
+typedef struct {
+  /**
+  Defines the chromaticity feature enable bits
+  Bits 7:2  = Reserved
+  Bit 1     = Override EDID values for chromaticity if enabled, Instead Use VBT values
+            = 0, Disable, Use the EDID values
+            = 1, Enable, Use the values from the VBT
+  Bit 0     = Enable chromaticity feature. EDID values will be used when this feature is enabled.
+            = 0, Disable
+            = 1, Enable
+  **/
+  UINT8        EnableBits;
+
+  UINT8        Red_Green_1;   ///< Red/green chormaticity coordinates at EDID offset 19h
+  UINT8        Blue_White_1;  ///< Blue/white chromatiity coordinates at EDID offset 1Ah
+  UINT8        Red_X1;        ///< Red x coordinate at EDID offset 1Bh
+  UINT8        Red_Y1;        ///< Red x coordinate at EDID offset 1Ch
+  UINT8        Green_X1;      ///< Green x coordinate at EDID offset 1Dh
+  UINT8        Green_Y1;      ///< Green x coordinate at EDID offset 1Eh
+  UINT8        Blue_X1;       ///< Blue x coordinate at EDID offset 1Fh
+  UINT8        Blue_Y1;       ///< Blue x coordinate at EDID offset 20h
+  UINT8        White_X1;      ///< White x coordinate at EDID offset 21h
+  UINT8        White_Y1;      ///< White x coordinate at EDID offset 22h
+} CHROMATICITY;
+
+/**
+  This structure defines the Luminance information for a single LFP panel.
+**/
+typedef struct {
+  /**
+  Defines the chromaticity feature enable bits
+  Bits 7:2  : Reserved
+  Bit 1     : Enable Gamma feature.
+            : if enabled, use gamma values from this block.
+          0 : Disable
+          1 : Enable
+  Bit 0     : Enable Luminance feature.
+            : if enabled, use values from this block.
+          0 : Disable
+          1 : Enable
+  **/
+  UINT8        EnableBits;
+  /**
+    Luminance info (refer DisplayID 2.0)
+    2 byte value, encoded in IEEE 754 half-precision binary floating point format
+  **/
+  UINT16      MinLuminance;           ///< Native minimum luminance
+  UINT16      MaxFullFrameLuminance;  ///< Native maximum luminance (Full Frame)
+  UINT16      MaxLuminance;           ///< Native Maximum Luminance (1% Rectangular Coverage)
+  /**
+    Gamma EOTF
+    Gamma values range from 00h through FFh which will come from VBT.
+    Value shall define the gamma range, from 1.00 to 3.54.
+    Field Value = (Gamma (value from VBT) + 100) / 100
+
+    FFh = No gamma information shall be provided
+  **/
+  UINT8 Gamma;
+
+}LUMINANCE_AND_GAMMA;
+
+/**
+  This defines the structure of Block 46 (Chromaticity Support)
+**/
+typedef struct {
+  UINT8              BlockId;                 ///< Defines the unique Block ID : 46
+  UINT16             BlockSize;               ///< Defines the size of Chromaticity Block.
+  CHROMATICITY       Chromaticity_Struct[16]; ///< Defines the chromaticity information for all 16 panels.
+  LUMINANCE_AND_GAMMA  Luminance_Gamma_Struct[16];    ///< Defines the lumianance information for all 16 panels.
+} BLOCK46_CHROMATICITY_SUPPORT;
+
+/**
+  This defines the structure of Block 51 (Fixed Mode Set)
+**/
+typedef struct{
+  UINT8       BlockId;        ///< Defines the unique block ID : 51.
+  UINT16      BlockSize;      ///< Defines the size of Fixed mode set feature block.
+  UINT8       FeatureEnable;  ///< Whether the fixed mode set feature is enabled/disabled.
+  UINT32      XRes;           ///< X resolution of the fixed mode.
+  UINT32      YRes;           ///< Y resolution of the fixed mode.
+} BLOCK51_FIXED_MODE_SET;
+
+/**
+  This defines the Complete VBT Structure for generation purpose
+**/
+typedef struct {
+  VBT_HEADER                                VbtHeader;
+  VBT_BIOS_DATA_HEADER                      VbtBdbHeader;
+  BLOCK254_BMP_Structure                    Block254BMPStructure;
+  VBT_GENERAL1_INFO                         VbtGen1Info;
+  PRD_BOOT_TABLE                            PrdBootTable;
+  VBT_GENERAL2_INFO                         VbtGen2Info;
+  BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST      Block03OriginalDisplayToggleList;
+  BLOCK252_SBIOS_Hook                       Block252SbiosHook;
+  BLOCK06_MMIO_REG_TABLE                    Block06MmioRegTable;
+  BLOCK07_IOSWFLAG_REG_TABLE                Block07IoswflagRegTable;
+  BLOCK08_MMIOSWFLAG_REG_TABLE              Block08MmioswflagRegTable;
+  BLOCK09_PSR_FEATURE                       Block09PsrFeature;
+  BLOCK10_MODE_REMOVAL_TABLE                Block10ModeRemovalTable;
+  BLOCK12_DRIVER_FEATURES                   Block12DriverFeatures;
+  BLOCK13_DRIVER_PERSISTENCE                Block13DriverPersistence;
+  BLOCK17_SV_BITS                           Block17SvBits;
+  BLOCK18_DRIVER_ROTATION                   Block18DriverRotation;
+  BLOCK20_OEM_CUSTOMIZATION                 Block20OemCustomization;
+  BLOCK26_TV_OPTIONS                        Block26TVOptions;
+  BLOCK27_EDP_FEATURES                      Block27EDPFeatures;
+  BLOCK28_EDIDLESS_EFP                      Block28EdidlessEFP;
+  BLOCK31_TOGGLE_LIST                       Block31ToggleList;
+  BLOCK32_DISPLAY_CONFIGURATION_REMOVAL     Block32DisplayConfigurationRemoval;
+  BLOCK40_LVDS_FEATURES                     Block40LVDSFeatures;
+  BLOCK41_LFP_TABLE_POINTERS                Block41LfpTablePointers;
+  BLOCK42_LVDS_PANEL_INFO                   Block42LvdsPanelInfo;
+  BLOCK43_LVDS_BLC                          Block43LVDSBlc;
+  BLOCK44_ALS                               Block44Als;
+  BLOCK46_CHROMATICITY_SUPPORT              Block46ChromaticitySupport;
+  BLOCK51_FIXED_MODE_SET                    Block51FixedModeSet;
+} VBT_TABLE_DATA;
+
+#pragma pack()
+
+/**
+  This function will update the VBT checksum.
+
+  @param[in out] VbtPtr - Pointer to VBT table
+
+  @retval none
+**/
+VOID
+UpdateVbtChecksum(
+  VBT_TABLE_DATA *VbtPtr
+);
+
+/**
+  This function will update the VBT.
+
+  @param[in] VbtPtr - Pointer to VBT Table
+
+  @retval none
+**/
+VOID
+UpdateGopVbt (
+  IN  VBT_TABLE_DATA    *VbtPtr
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
new file mode 100644
index 0000000000..5bf2527963
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __TCO_WDT_HOB_H__
+#define __TCO_WDT_HOB_H__
+
+#define TCO_WDT_HOB_GUID \
+  { \
+    0x3e405418, 0xd8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x8, 0x41, 0x46, 0x8d } \
+  }
+
+#ifndef _PEI_HOB_H_
+#ifndef __HOB__H__
+#ifndef __PI_HOB_H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+  EFI_HOB_GENERIC_HEADER  Header;
+  EFI_GUID                Name;
+  //
+  // Guid specific data goes here
+  //
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+#endif
+
+typedef struct {
+  EFI_HOB_GUID_TYPE Header;
+  UINT8             TcoRebootHappened;
+} TCO_WDT_HOB;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
new file mode 100644
index 0000000000..671e3c5cde
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
@@ -0,0 +1,68 @@
+/** @file
+  GPIO definition table for WhiskeylakeURvp
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IO_EXPANDER_H_
+#define _IO_EXPANDER_H_
+
+typedef struct {
+  UINT32 IoExpanderNumber   : 1;  // IO Expander Number (0/1)
+  UINT32 GpioPinNumber      : 5;  // GPIO Pin Number (0 to 23)
+  UINT32 GpioDirection      : 1;  // GPIO Pin Direction (Input/Output)
+  UINT32 GpioLevel          : 1;  // GPIO Pin Output Level (High/Low)
+  UINT32 GpioInversion     : 1;  // GPIO Pin Inversion (Enabled/Disabled)
+  UINT32 Reserved           : 23; // Reserved
+} IO_EXPANDER_GPIO_CONFIG;
+
+//WHL PCH LP GPIO Expander Number
+#define IO_EXPANDER_0            0
+#define IO_EXPANDER_1            1
+
+//WHL PCH LP GPIO Pin Mapping
+#define IO_EXPANDER_GPIO_0        0   // P00
+#define IO_EXPANDER_GPIO_1        1   // P01
+#define IO_EXPANDER_GPIO_2        2   // P02
+#define IO_EXPANDER_GPIO_3        3   // P03
+#define IO_EXPANDER_GPIO_4        4   // P04
+#define IO_EXPANDER_GPIO_5        5   // P05
+#define IO_EXPANDER_GPIO_6        6   // P06
+#define IO_EXPANDER_GPIO_7        7   // P07
+#define IO_EXPANDER_GPIO_8        8   // P10
+#define IO_EXPANDER_GPIO_9        9   // P11
+#define IO_EXPANDER_GPIO_10       10  // P12
+#define IO_EXPANDER_GPIO_11       11  // P13
+#define IO_EXPANDER_GPIO_12       12  // P14
+#define IO_EXPANDER_GPIO_13       13  // P15
+#define IO_EXPANDER_GPIO_14       14  // P16
+#define IO_EXPANDER_GPIO_15       15  // P17
+#define IO_EXPANDER_GPIO_16       16  // P20
+#define IO_EXPANDER_GPIO_17       17  // P21
+#define IO_EXPANDER_GPIO_18       18  // P22
+#define IO_EXPANDER_GPIO_19       19  // P23
+#define IO_EXPANDER_GPIO_20       20  // P24
+#define IO_EXPANDER_GPIO_21       21  // P25
+#define IO_EXPANDER_GPIO_22       22  // P26
+#define IO_EXPANDER_GPIO_23       23  // P27
+
+//WHL PCH LP GPIO Expander GPIO Direction
+#define IO_EXPANDER_GPIO_OUTPUT   0
+#define IO_EXPANDER_GPIO_INPUT    1
+
+//WHL PCH LP GPIO Expaner GPIO Output Level
+#define IO_EXPANDER_GPO_LEVEL_LOW    0
+#define IO_EXPANDER_GPO_LEVEL_HIGH   1
+
+//WHL PCH LP GPIO Expaner GPIO Inversion Status
+#define IO_EXPANDER_GPI_INV_DISABLED  0
+#define IO_EXPANDER_GPI_INV_ENABLED   1
+#define IO_EXPANDER_GPIO_RESERVED     0x00
+
+//GPIO Table Terminator
+#define END_OF_GPIO_TABLE 0xFFFFFFFF
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
new file mode 100644
index 0000000000..5d5fba47ad
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
@@ -0,0 +1,75 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_CPU_POLICY_UPDATE_LIB_H_
+#define _DXE_CPU_POLICY_UPDATE_LIB_H_
+
+#include <PiDxe.h>
+#include <PchAccess.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CpuPolicyProtocol.h>
+
+/**
+
+  This function prints the CPU DXE phase policy.
+
+  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
+
+**/
+VOID
+CpuDxePrintPolicyProtocol (
+  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  );
+
+/**
+
+Routine Description:
+
+  This function updates Dxe Cpu Policy Protocol
+
+Arguments:
+
+  @param[in] DxeCpuPolicy                 The Cpu Policy protocol instance
+
+Returns:
+
+  @retval EFI_SUCCESS                     Initialization complete.
+  @retval 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
+UpdateDxeSiCpuPolicy (
+  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  );
+
+/**
+
+  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
new file mode 100644
index 0000000000..9b960159ba
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
@@ -0,0 +1,27 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_ME_POLICY_UPDATE_LIB_H_
+#define _DXE_ME_POLICY_UPDATE_LIB_H_
+
+/**
+  Update the ME Policy Library
+
+  @param[in] DxeMePolicy                The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   Initialization complete.
+  @retval 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
+UpdateDxeMePolicy (
+  IN OUT  ME_POLICY_PROTOCOL      *DxeMePolicy
+  );
+
+#endif // _DXE_ME_POLICY_UPDATE_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
new file mode 100644
index 0000000000..84db68e65c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_POLICY_UPDATE_LIB_H_
+#define _DXE_PCH_POLICY_UPDATE_LIB_H_
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] PchPolicy               The pointer to get PCH Policy protocol instance
+
+  @retval EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxePchPolicy (
+  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
new file mode 100644
index 0000000000..3bb941235c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
@@ -0,0 +1,30 @@
+/** @file
+  Header file for the DxePolicyBoardConfig Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_POLICY_BOARD_CONFIG_LIB_H_
+#define _DXE_POLICY_BOARD_CONFIG_LIB_H_
+
+#include <Protocol/MePolicy.h>
+#include <Protocol/SaPolicy.h>
+
+/**
+  This function performs DXE SA Policy update by board configuration.
+
+  @param[in, out] DxeSaPolicy     DXE SA Policy
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicyBoardConfig (
+  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
new file mode 100644
index 0000000000..4279c0c6f1
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_UPDATE_LIB_H_
+#define _DXE_SA_POLICY_UPDATE_LIB_H_
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] SaPolicy               The pointer to get SA Policy protocol instance
+
+  @retval EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicy (
+  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
new file mode 100644
index 0000000000..4709179ac6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
@@ -0,0 +1,29 @@
+/** @file
+  Function prototype of FspPolicyInitLib.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _FSP_POLICY_INIT_LIB_H_
+#define _FSP_POLICY_INIT_LIB_H_
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+  IN FSPM_UPD           *FspmUpdDataPtr
+  );
+
+VOID
+EFIAPI
+FspPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+#endif // _FSP_POLICY_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
new file mode 100644
index 0000000000..ba73cad63b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
@@ -0,0 +1,46 @@
+/** @file
+  Header file for check Gpio PadMode conflict.
+
+
+  Copyright (c) 2019, 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 <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 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 UINT16                    GpioTableCount
+  );
+
+#endif // _GPIO_CHECK_CONFLICT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
new file mode 100644
index 0000000000..40ea4abc3d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_EXPANDER_LIB_H_
+#define _GPIO_EXPANDER_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <PchAccess.h>
+#include <Library/PchSerialIoLib.h>
+
+/**
+  Set the Direction value for the given Expander Gpio pin.
+
+  This function is to Set the direction value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+**/
+VOID
+GpioExpSetDirection (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Direction
+  );
+/**
+  Set the input value for the given Expander Gpio pin.
+
+  This function is to get the input value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetPolarity  (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Polarity
+  );
+/**
+  Set the Output value for the given Expander Gpio pin.
+
+  This function is to Set the Output value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetOutput    (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  );
+/**
+  Returns the data from register value giving in the input.
+
+  This function is to get the data from the Expander
+  Registers by following the I2C Protocol communication
+
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+
+  @retval     UINT8      Value returned from the register
+**/
+UINT8
+GpioExpGetInput     (
+  IN UINT8 Expander,
+  IN UINT8 Pin
+  );
+
+/**
+  Configures all registers of a single IO Expander in one go.
+
+  @param[in]  Expander    Expander number (0/1)
+  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc. 0=output, 1=input
+  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0, etc. 0=normal, 1=inversion
+  @param[in]  Output      Bit-encoded output state, ignores polarity, only applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
+
+**/
+VOID
+GpioExpBulkConfig (
+  IN UINT8  Expander,
+  IN UINT32 Direction,
+  IN UINT32 Polarity,
+  IN UINT32 Output
+  );
+
+/**
+  Returns the Controller on which GPIO expander is present.
+
+  This function returns the Controller value
+
+  @param[out] Controller              Pointer to a Controller value on
+                                      which I2C expander is configured.
+
+  @retval     EFI_SUCCESS              non.
+**/
+EFI_STATUS
+GpioExpGetController (
+  OUT UINT8 *Controller
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
new file mode 100644
index 0000000000..f08c88f114
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
@@ -0,0 +1,48 @@
+/** @file
+
+  Header file for the Intel HD Audio Verb Table library.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _HDA_VERB_TABLE_LIB_H_
+#define _HDA_VERB_TABLE_LIB_H_
+
+#include <ConfigBlock/HdAudioConfig.h>
+#include <Library/BaseLib.h>
+
+enum HDAUDIO_CODEC_SELECT {
+  PchHdaCodecPlatformOnboard = 0,
+  PchHdaCodecExternalKit     = 1
+};
+
+/**
+  Add verb table function.
+  This function update the verb table number and verb table ptr of policy.
+
+  @param[in]  HdAudioConfig            HD Audio config block
+  @param[out] VerbTableEntryNum        Number of verb table entries
+  @param[out] HdaVerbTablePtr          Pointer to the verb table
+**/
+VOID
+AddPlatformVerbTables (
+  IN   UINT8              CodecType,
+  OUT  UINT8              *VerbTableEntryNum,
+  OUT  UINT32             *HdaVerbTablePtr
+  );
+
+/**
+  HDA VerbTable init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+HdaVerbTableInit(
+  IN UINT16 BoardId
+  );
+
+#endif
\ No newline at end of file
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
new file mode 100644
index 0000000000..cec045091b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _I2C_ACCESS_LIB_H_
+#define _I2C_ACCESS_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <PchAccess.h>
+#include <Library/PchSerialIoLib.h>
+
+#define WAIT_1_SECOND            1600000000 //1.6 * 10^9
+
+EFI_STATUS
+I2cWriteRead (
+  IN UINTN  MmioBase,
+  IN UINT8  SlaveAddress,
+  IN UINT8  WriteLength,
+  IN UINT8  *WriteBuffer,
+  IN UINT8  ReadLength,
+  IN UINT8  *ReadBuffer,
+  IN UINT64  TimeBudget
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
new file mode 100644
index 0000000000..d65586dbb9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PLATFORM_LIB_H_
+#define _PEI_PLATFORM_LIB_H_
+
+
+
+#define PEI_DEVICE_DISABLED 0
+#define PEI_DEVICE_ENABLED  1
+
+typedef struct {
+  UINT8   Register;
+  UINT32  Value;
+} PCH_GPIO_DEV;
+
+//
+// GPIO Initialization Data Structure
+//
+typedef struct{
+  PCH_GPIO_DEV Use_Sel;
+  PCH_GPIO_DEV Use_Sel2;
+  PCH_GPIO_DEV Use_Sel3;
+  PCH_GPIO_DEV Io_Sel;
+  PCH_GPIO_DEV Io_Sel2;
+  PCH_GPIO_DEV Io_Sel3;
+  PCH_GPIO_DEV Lvl;
+  PCH_GPIO_DEV Lvl2;
+  PCH_GPIO_DEV Lvl3;
+  PCH_GPIO_DEV Inv;
+  PCH_GPIO_DEV Blink;
+  PCH_GPIO_DEV Rst_Sel;
+  PCH_GPIO_DEV Rst_Sel2;
+} GPIO_INIT_STRUCT;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
new file mode 100644
index 0000000000..fe947482dc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
@@ -0,0 +1,141 @@
+/** @file
+  Header file for the PeiPolicyBoardConfig Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_BOARD_CONFIG_LIB_H_
+#define _PEI_POLICY_BOARD_CONFIG_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  This function performs PEI CPU Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI ME Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI PCH Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI SA Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI CPU Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI ME Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI PCH Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI SA Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI SI Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
new file mode 100644
index 0000000000..15db1f1fbc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for the PolicyInitPei Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POLICY_INIT_PEI_LIB_H_
+#define _POLICY_INIT_PEI_LIB_H_
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that depends
+                                     on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInitPreMem (
+  IN UINT8                     FirmwareConfiguration
+  );
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in] PeiServices            General purpose services available to every PEIM.
+  @param[in] FirmwareConfiguration  It uses to skip specific policy init that depends
+                                    on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInit (
+//  IN CONST EFI_PEI_SERVICES    **PeiServices,
+  IN UINT8                     FirmwareConfiguration
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
new file mode 100644
index 0000000000..f0da2db968
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Function prototype of PlatformInitLib.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_INIT_LIB_H_
+#define _PLATFORM_INIT_LIB_H_
+
+VOID
+PlatformLateInit (
+  VOID
+  );
+
+VOID
+InitSerialPort (
+  VOID
+  );
+
+#endif // _PLATFORM_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
new file mode 100644
index 0000000000..8bf7deaa0c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PCH_HSIO_PTSSTABLES_H_
+#define PCH_HSIO_PTSSTABLES_H_
+
+#include <PchAccess.h>
+
+///
+/// SATA PTSS Topology Types
+///
+typedef enum {
+  PchSataTopoUnknown = 0x00,
+  PchSataTopoIsata,
+  PchSataTopoDirectConnect,
+  PchSataTopoFlex,
+  PchSataTopoM2
+} PCH_SATA_TOPOLOGY;
+
+///
+/// PCIe PTSS Topology Types
+///
+typedef enum {
+  PchPcieTopoUnknown = 0x00,
+  PchPcieTopox1,
+  PchPcieTopox4,
+  PchPcieTopoSataE,
+  PchPcieTopoM2
+} PCH_PCIE_TOPOLOGY;
+
+///
+/// The PCH_SBI_PTSS_HSIO_TABLE block describes HSIO PTSS settings for PCH.
+///
+typedef struct {
+  UINT8       LaneNum;
+  UINT8       PhyMode;
+  UINT16      Offset;
+  UINT32      Value;
+  UINT32      BitMask;
+} PCH_SBI_PTSS_HSIO_TABLE;
+
+typedef struct {
+  PCH_SBI_PTSS_HSIO_TABLE   PtssTable;
+  UINT16                    Topology;
+} HSIO_PTSS_TABLES;
+
+#endif // PCH_HSIO_PTSSTABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
new file mode 100644
index 0000000000..395d08779c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
@@ -0,0 +1,106 @@
+/** @file
+  PCIe Device Override Table
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCIE_DEVICE_OVERRIDE_TABLE_H_
+#define _PCIE_DEVICE_OVERRIDE_TABLE_H_
+
+#include <ConfigBlock/PcieRpconfig.h>
+#include <IndustryStandard/Pci22.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 },
+
+  //
+  // End of Table
+  //
+  { 0 }
+};
+
+#endif
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
new file mode 100644
index 0000000000..ea96227e3d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
@@ -0,0 +1,33 @@
+/** @file
+  This header file provides platform specific definitions used
+  by other modules for platform specific initialization.
+  This is not suitable for consumption by ASL or VRF files.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//#include "CommonDefinitions.h"
+#include "PchAccess.h"
+#include "SaAccess.h"
+
+//
+// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
+//
+#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)   // 80MB + 256MB
+#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (10 * 0x800000 + 0x10000000)   // 80MB + 256MB
+
+#define FLASH_BLOCK_SIZE  0x10000
+
+#define CPU_EXTERNAL_CLOCK_FREQ  0x64
+#define CPU_FREQUENCY_MODE_100  0x64
+#define FREQUENCY_RESOLUTION_3182  0xc6e
+#define NDIVIDER_BASE_VALUE  0x19d
+#define MDIVIDER_VALUE_13  0xd
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
new file mode 100644
index 0000000000..3545b2a05c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
@@ -0,0 +1,29 @@
+/** @file
+Defines Platform BoardIds
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_BOARD_ID_H_
+#define _PLATFORM_BOARD_ID_H_
+
+#define FlavorUnknown                       0x0
+#define FlavorMobile                        0x1
+#define FlavorDesktop                       0x2
+#define FlavorWorkstation                   0x3
+#define FlavorUpServer                      0x4
+#define FlavorEmbedded                      0x5
+#define FlavorPlatformMax                   0x6
+
+#define TypeUnknown                         0x0
+#define TypeTrad                            0x1
+#define TypeUltUlx                          0x2
+
+#define BoardIdWhiskeyLakeRvp               0x60
+
+#define BoardIdUnknown1                     0xffff
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
new file mode 100644
index 0000000000..b64cfff9a2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
@@ -0,0 +1,47 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GLOBAL_NVS_AREA_H_
+#define _GLOBAL_NVS_AREA_H_
+
+//
+// Includes
+//
+#define GLOBAL_NVS_DEVICE_ENABLE 1
+#define GLOBAL_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+//
+// Global NVS Area Protocol GUID
+//
+#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
+{ 0x74e1e48, 0x8132, 0x47a1, 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc }
+
+#define GLOBAL_NVS_AREA_REVISION       16
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
+
+//
+// Global NVS Area definition
+//
+#include <Acpi/GlobalNvsAreaDef.h>
+
+//
+// Global NVS Area Protocol
+//
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
+  EFI_GLOBAL_NVS_AREA     *Area;
+} EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
new file mode 100644
index 0000000000..6dd6795a52
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
@@ -0,0 +1,144 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SETUP__H__
+#define __SETUP__H__
+
+#ifndef MDEPKG_NDEBUG
+#define DEBUG_INTERFACE_FORM_ENABLE
+#endif // MDEPKG_NDEBUG
+//
+// Form class guid for the forms those will be showed on first front page.
+//
+#define FRONT_PAGE_GUID        { 0xe58809f8, 0xfbc1, 0x48e2, { 0x88, 0x3a, 0xa3, 0xf, 0xdc, 0x4b, 0x44, 0x1e } }
+//
+// Form class guid for the forms those will be showed on boot maintenance manager menu.
+//
+#define BOOT_MAINTENANCE_GUID  { 0xb2dedc91, 0xd59f, 0x48d2, { 0x89, 0x8a, 0x12, 0x49, 0xc, 0x74, 0xa4, 0xe0 } }
+
+// VFR common Definitions
+#define INVENTORY(Name,Value) \
+    text \
+      help  = STRING_TOKEN(STR_EMPTY), \
+      text  = Name, \
+      text  = Value, \
+      flags = 0, \
+      key   = 0;
+
+#define SUBTITLE(Text) subtitle text = Text;
+#define SEPARATOR SUBTITLE(STRING_TOKEN(STR_EMPTY))
+
+#define INTERACTIVE_TEXT(HelpToken, CaptionToken, ValueToken, Key)\
+  grayoutif TRUE;\
+    oneof varid        = SETUP_DATA.InteractiveText,\
+      questionid       = Key,\
+      prompt           = CaptionToken,\
+      help             = HelpToken,\
+      option text      = ValueToken, value = 0, flags = INTERACTIVE | DEFAULT;\
+      refresh interval = 1 \
+    endoneof;\
+  endif;
+
+#define SUPPRESS_GRAYOUT_ENDIF endif; endif;
+#define DEFAULT_FLAG
+
+#define SYSTEM_ACCESS_KEY_ID            0xF000
+//
+// System Access defintions.
+//
+#define SYSTEM_ACCESS_GUID \
+ { 0xE770BB69, 0xBCB4, 0x4D04, { 0x9E, 0x97, 0x23, 0xFF, 0x94, 0x56, 0xFE, 0xAC }}
+
+#define SYSTEM_PASSWORD_ADMIN 0
+#define SYSTEM_PASSWORD_USER  1
+#define ADMIN_PW_CLEAR        0
+#define ADMIN_PW_SET          1
+
+
+typedef struct _SYSTEM_ACCESS
+{
+  //
+  // Passwords
+  //
+  UINT8       Access;
+} SYSTEM_ACCESS;
+
+//
+// Record the password status.
+//
+typedef struct {
+  UINT8   AdminName;
+  UINT8   UserName;
+} EFI_PASSWORD_STATUS;
+
+//
+// Config Data
+//
+typedef struct {
+  UINT8 SerialDebug;
+  UINT8 SerialDebugBaudRate;
+  UINT8 RamDebugInterface;
+  UINT8 UartDebugInterface;
+  UINT8 Usb3DebugInterface;
+  UINT8 SerialIoDebugInterface;
+  UINT8 TraceHubDebugInterface;
+} DEBUG_CONFIG_DATA;
+
+//
+// Config Data Hob
+//
+#define DEBUG_CONFIG_DATA_HOB DEBUG_CONFIG_DATA
+
+//
+// Secure Boot Data
+//
+typedef struct{
+  UINT8   SecureBoot;
+} SECURE_BOOT_VARIABLE;
+
+#pragma pack()
+
+//
+// Varstore statement
+// Setup is EfiVarStore that is related to EFI variable with attribute 0x07
+// (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
+//
+#define SETUP_DATA_VARSTORE\
+    efivarstore SETUP_DATA, varid = 1,\
+        attribute = 0x7, name = Setup, guid = SETUP_GUID;
+#define SA_SETUP_VARSTORE\
+    efivarstore SA_SETUP, varid = 2,\
+        attribute = 0x7, name = SaSetup, guid = SA_SETUP_GUID;
+#define CPU_SETUP_VARSTORE\
+    efivarstore CPU_SETUP, varid = 3,\
+        attribute = 0x7, name = CpuSetup, guid = CPU_SETUP_GUID;
+#define ME_SETUP_VARSTORE\
+    efivarstore ME_SETUP, varid = 4,\
+        attribute = 0x7, name = MeSetup, guid = ME_SETUP_GUID;
+#define PCH_SETUP_VARSTORE\
+    efivarstore PCH_SETUP, varid = 5,\
+        attribute = 0x7, name = PchSetup, guid = PCH_SETUP_GUID;
+#define SI_SETUP_VARSTORE\
+    efivarstore SI_SETUP, varid = 6,\
+        attribute = 0x7, name = SiSetup, guid = SI_SETUP_GUID;
+#ifdef DEBUG_INTERFACE_FORM_ENABLE
+#define DEBUG_CONFIG_DATA_ID            0xF001
+#define DEBUG_CONFIG_DATA_VARSTORE\
+    efivarstore DEBUG_CONFIG_DATA, varid = DEBUG_CONFIG_DATA_ID,\
+        attribute = 0x7, name = DebugConfigData, guid = DEBUG_CONFIG_GUID;
+#endif // DEBUG_INTERFACE_FORM_ENABLE
+#define SYSTEM_ACCESS_VARSTORE\
+    varstore SYSTEM_ACCESS, varid = SYSTEM_ACCESS_KEY_ID,\
+        name = SystemAccess, guid = SYSTEM_ACCESS_GUID;
+#define SYSTEM_PASSWORD_VARSTORE\
+    varstore EFI_PASSWORD_STATUS,\
+        name = PasswordStatus, guid = SYSTEM_ACCESS_GUID;
+
+#define BOOT_FLOW_CONDITION_RECOVERY   2
+#define BOOT_FLOW_CONDITION_FIRST_BOOT 4
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
new file mode 100644
index 0000000000..4ce85de5bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
@@ -0,0 +1,157 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_REG_H_
+#define _SIO_REG_H_
+
+#define REG_LOGICAL_DEVICE        0x07
+#define ACTIVATE                  0x30
+
+#define BASE_ADDRESS_HIGH0        0x60
+#define BASE_ADDRESS_LOW0         0x61
+#define BASE_ADDRESS_HIGH1        0x62
+#define BASE_ADDRESS_LOW1         0x63
+#define BASE_ADDRESS_HIGH2        0x64
+#define BASE_ADDRESS_LOW2         0x65
+#define BASE_ADDRESS_HIGH3        0x66
+#define BASE_ADDRESS_LOW3         0x67
+#define PRIMARY_INTERRUPT_SELECT  0x70
+#define WAKEUP_ON_IRQ_EN          0x70
+#define INTERRUPT_TYPE            0x71
+#define DMA_CHANNEL_SELECT0       0x74
+#define DMA_CHANNEL_SELECT1       0x75
+
+
+
+//
+//Port address for PILOT - III
+//
+#define PILOTIII_CHIP_ID         0x03
+#define PILOTIII_SIO_INDEX_PORT  0x04E
+#define PILOTIII_SIO_DATA_PORT   (PILOTIII_SIO_INDEX_PORT+1)
+
+#define PILOTIII_UNLOCK      0x5A
+#define PILOTIII_LOCK        0xA5
+
+//
+// logical device in PILOT-III
+//
+#define PILOTIII_SIO_PSR     0x00
+#define PILOTIII_SIO_COM2    0x01
+#define PILOTIII_SIO_COM1    0x02
+#define PILOTIII_SIO_SWCP    0x03
+#define PILOTIII_SIO_GPIO    0x04
+#define PILOTIII_SIO_WDT     0x05
+#define PILOTIII_SIO_KCS3    0x08
+#define PILOTIII_SIO_KCS4    0x09
+#define PILOTIII_SIO_KCS5    0x0A
+#define PILOTIII_SIO_BT      0x0B
+#define PILOTIII_SIO_SMIC    0x0C
+#define PILOTIII_SIO_MAILBOX 0x0D
+#define PILOTIII_SIO_RTC     0x0E
+#define PILOTIII_SIO_SPI     0x0F
+#define PILOTIII_SIO_TAP     0x10
+//
+// Regisgers for Pilot-III
+//
+#define PILOTIII_CHIP_ID_REG               0x20
+#define PILOTIII_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
+#define PILOTIII_ACTIVATE                  ACTIVATE
+#define PILOTIII_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
+#define PILOTIII_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
+#define PILOTIII_BASE_ADDRESS_HIGH1        BASE_ADDRESS_HIGH1
+#define PILOTIII_BASE_ADDRESS_LOW1         BASE_ADDRESS_LOW1
+#define PILOTIII_PRIMARY_INTERRUPT_SELECT  PRIMARY_INTERRUPT_SELECT
+
+//
+// Port address for PC8374
+//
+#define PC8374_SIO_INDEX_PORT  0x02E
+#define PC8374_SIO_DATA_PORT   (PC8374_SIO_INDEX_PORT+1)
+
+//
+// Logical device in PC8374
+//
+#define PC8374_SIO_FLOPPY  0x00
+#define PC8374_SIO_PARA    0x01
+#define PC8374_SIO_COM2    0x02
+#define PC8374_SIO_COM1    0x03
+#define PC8374_SIO_MOUSE   0x05
+#define PC8374_SIO_KYBD    0x06
+#define PC8374_SIO_GPIO    0x07
+
+//
+// Registers specific for PC8374
+//
+#define PC8374_CLOCK_SELECT  0x2D
+#define PC8374_CLOCK_CONFIG  0x29
+
+//
+// Registers for PC8374
+//
+#define PC8374_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
+#define PC8374_ACTIVATE                  ACTIVATE
+#define PC8374_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
+#define PC8374_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
+#define PC8374_PRIMARY_INTERRUPT_SELECT  PRIMARY_INTERRUPT_SELECT
+#define PC8374_DMA_CHANNEL_SELECT        DMA_CHANNEL_SELECT0
+
+#define PC87427_SERVERIO_CNF2           0x22
+
+
+//
+// Pilot III Mailbox Data Register definitions
+//
+#define MBDAT00_OFFSET                  0x00
+#define MBDAT01_OFFSET                  0x01
+#define MBDAT02_OFFSET                  0x02
+#define MBDAT03_OFFSET                  0x03
+#define MBDAT04_OFFSET                  0x04
+#define MBDAT05_OFFSET                  0x05
+#define MBDAT06_OFFSET                  0x06
+#define MBDAT07_OFFSET                  0x07
+#define MBDAT08_OFFSET                  0x08
+#define MBDAT09_OFFSET                  0x09
+#define MBDAT10_OFFSET                  0x0A
+#define MBDAT11_OFFSET                  0x0B
+#define MBDAT12_OFFSET                  0x0C
+#define MBDAT13_OFFSET                  0x0D
+#define MBDAT14_OFFSET                  0x0E
+#define MBDAT15_OFFSET                  0x0F
+#define MBST0_OFFSET                    0x10
+#define MBST1_OFFSET                    0x11
+#define MBBINT_OFFSET                   0x12
+
+//
+// Mailbox Bit definitions...
+//
+#define   MBBINT_MBBIST_BIT               0x80
+// If both are there, use the default one
+//
+#define  W83527_EXIST     BIT2
+#define  PC8374_EXIST     BIT1
+#define  PILOTIII_EXIST   BIT0
+#define  DEFAULT_SIO      PILOTIII_EXIST
+#define  DEFAULT_KDB      PC8374_EXIST
+
+#define IPMI_DEFAULT_SMM_IO_BASE           0xca2
+//
+// For Pilot III
+//
+
+#define PILOTIII_SWC_BASE_ADDRESS          0xA00
+#define PILOTIII_PM1b_EVT_BLK_BASE_ADDRESS 0x0A80
+#define PILOTIII_PM1b_CNT_BLK_BASE_ADDRESS 0x0A84
+#define PILOTIII_GPE1_BLK_BASE_ADDRESS     0x0A86
+#define PILOTIII_KCS3_DATA_BASE_ADDRESS    0x0CA4
+#define PILOTIII_KCS3_CMD_BASE_ADDRESS     0x0CA5
+#define PILOTIII_KCS4_DATA_BASE_ADDRESS    0x0CA2
+#define PILOTIII_KCS4_CMD_BASE_ADDRESS     0x0CA3
+#define PILOTIII_MAILBOX_BASE_ADDRESS      0x0600
+#define PILOTIII_MAILBOX_MASK              0xFFE0
+#define BMC_KCS_BASE_ADDRESS               0x0CA0
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
new file mode 100644
index 0000000000..af753e1dce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
@@ -0,0 +1,112 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  // Define a Global region of ACPI NVS Region that may be used for any
+  // type of implementation.  The starting offset and size will be fixed
+  // up by the System BIOS during POST.  Note that the Size must be a word
+  // in size to be fixed up correctly.
+
+  OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55)
+  Field(GNVS,AnyAcc,Lock,Preserve)
+  {
+  //
+  // Miscellaneous Dynamic Registers:
+  //
+  Offset(0),      OSYS, 16, // Offset(0),     Operating System
+  Offset(2),      SMIF, 8,  // Offset(2),     SMI Function Call (ASL to SMI via I/O Trap)
+  Offset(3),      P80D, 32, // Offset(3),     Port 80 Debug Port Value
+  Offset(7),      PWRS, 8,  // Offset(7),     Power State (AC Mode = 1)
+  //
+  // Thermal Policy Registers:
+  //
+  Offset(8),      DTSE, 8,  // Offset(8),    Digital Thermal Sensor Enable
+  Offset(9),      DTSF, 8,  // Offset(9),    DTS SMI Function Call
+  //
+  // CPU Identification Registers:
+  //
+  Offset(10),     APIC, 8,  // Offset(10),    APIC Enabled by SBIOS (APIC Enabled = 1)
+  Offset(11),     TCNT, 8,  // Offset(11),    Number of Enabled Threads
+  //
+  // PCIe Hot Plug
+  //
+  Offset(12),     OSCC, 8,  // Offset(12),    PCIE OSC Control
+  Offset(13),     NEXP, 8,  // Offset(13),    Native PCIE Setup Value
+  //
+  // Global Variables
+  //
+  Offset(14),     DSEN, 8,  // Offset(14),    _DOS Display Support Flag.
+  Offset(15),     GPIC, 8,  // Offset(15),    Global IOAPIC/8259 Interrupt Mode Flag.
+  Offset(16),     L01C, 8,  // Offset(16),    Global L01 Counter.
+  Offset(17),     LTR1, 8,  // Offset(17),    Latency Tolerance Reporting Enable
+  Offset(18),     LTR2, 8,  // Offset(18),    Latency Tolerance Reporting Enable
+  Offset(19),     LTR3, 8,  // Offset(19),    Latency Tolerance Reporting Enable
+  Offset(20),     LTR4, 8,  // Offset(20),    Latency Tolerance Reporting Enable
+  Offset(21),     LTR5, 8,  // Offset(21),    Latency Tolerance Reporting Enable
+  Offset(22),     LTR6, 8,  // Offset(22),    Latency Tolerance Reporting Enable
+  Offset(23),     LTR7, 8,  // Offset(23),    Latency Tolerance Reporting Enable
+  Offset(24),     LTR8, 8,  // Offset(24),    Latency Tolerance Reporting Enable
+  Offset(25),     LTR9, 8,  // Offset(25),    Latency Tolerance Reporting Enable
+  Offset(26),     LTRA, 8,  // Offset(26),    Latency Tolerance Reporting Enable
+  Offset(27),     LTRB, 8,  // Offset(27),    Latency Tolerance Reporting Enable
+  Offset(28),     LTRC, 8,  // Offset(28),    Latency Tolerance Reporting Enable
+  Offset(29),     LTRD, 8,  // Offset(29),    Latency Tolerance Reporting Enable
+  Offset(30),     LTRE, 8,  // Offset(30),    Latency Tolerance Reporting Enable
+  Offset(31),     LTRF, 8,  // Offset(31),    Latency Tolerance Reporting Enable
+  Offset(32),     LTRG, 8,  // Offset(32),    Latency Tolerance Reporting Enable
+  Offset(33),     LTRH, 8,  // Offset(33),    Latency Tolerance Reporting Enable
+  Offset(34),     LTRI, 8,  // Offset(34),    Latency Tolerance Reporting Enable
+  Offset(35),     LTRJ, 8,  // Offset(35),    Latency Tolerance Reporting Enable
+  Offset(36),     LTRK, 8,  // Offset(36),    Latency Tolerance Reporting Enable
+  Offset(37),     LTRL, 8,  // Offset(37),    Latency Tolerance Reporting Enable
+  Offset(38),     LTRM, 8,  // Offset(38),    Latency Tolerance Reporting Enable
+  Offset(39),     LTRN, 8,  // Offset(39),    Latency Tolerance Reporting Enable
+  Offset(40),     LTRO, 8,  // Offset(40),    Latency Tolerance Reporting Enable
+  Offset(41),     OBF1, 8,  // Offset(41),    Optimized Buffer Flush and Fill
+  Offset(42),     OBF2, 8,  // Offset(42),    Optimized Buffer Flush and Fill
+  Offset(43),     OBF3, 8,  // Offset(43),    Optimized Buffer Flush and Fill
+  Offset(44),     OBF4, 8,  // Offset(44),    Optimized Buffer Flush and Fill
+  Offset(45),     OBF5, 8,  // Offset(45),    Optimized Buffer Flush and Fill
+  Offset(46),     OBF6, 8,  // Offset(46),    Optimized Buffer Flush and Fill
+  Offset(47),     OBF7, 8,  // Offset(47),    Optimized Buffer Flush and Fill
+  Offset(48),     OBF8, 8,  // Offset(48),    Optimized Buffer Flush and Fill
+  Offset(49),     OBF9, 8,  // Offset(49),    Optimized Buffer Flush and Fill
+  Offset(50),     OBFA, 8,  // Offset(50),    Optimized Buffer Flush and Fill
+  Offset(51),     OBFB, 8,  // Offset(51),    Optimized Buffer Flush and Fill
+  Offset(52),     OBFC, 8,  // Offset(52),    Optimized Buffer Flush and Fill
+  Offset(53),     OBFD, 8,  // Offset(53),    Optimized Buffer Flush and Fill
+  Offset(54),     OBFE, 8,  // Offset(54),    Optimized Buffer Flush and Fill
+  Offset(55),     OBFF, 8,  // Offset(55),    Optimized Buffer Flush and Fill
+  Offset(56),     OBFG, 8,  // Offset(56),    Optimized Buffer Flush and Fill
+  Offset(57),     OBFH, 8,  // Offset(57),    Optimized Buffer Flush and Fill
+  Offset(58),     OBFI, 8,  // Offset(58),    Optimized Buffer Flush and Fill
+  Offset(59),     OBFJ, 8,  // Offset(59),    Optimized Buffer Flush and Fill
+  Offset(60),     OBFK, 8,  // Offset(60),    Optimized Buffer Flush and Fill
+  Offset(61),     OBFL, 8,  // Offset(61),    Optimized Buffer Flush and Fill
+  Offset(62),     OBFM, 8,  // Offset(62),    Optimized Buffer Flush and Fill
+  Offset(63),     OBFN, 8,  // Offset(63),    Optimized Buffer Flush and Fill
+  Offset(64),     OBFO, 8,  // Offset(64),    Optimized Buffer Flush and Fill
+  Offset(65),     RTD3, 8,  // Offset(65),    Runtime D3 support.
+  Offset(66),     S0ID, 8,  // Offset(66),    Low Power S0 Idle Enable
+  Offset(67),     GBSX, 8,  // Offset(67),    Virtual GPIO button Notify Sleep State Change
+  Offset(68),     PSCP, 8,  // Offset(68),    P-state Capping
+  Offset(69),     P2ME, 8,  // Offset(69),    Ps2 Mouse Enable
+  Offset(70),     P2MK, 8,  // Offset(70),    Ps2 Keyboard and Mouse Enable
+  //
+  // Driver Mode
+  //
+  Offset(71),     GIRQ, 32, // Offset(71),    GPIO IRQ
+  Offset(75),     PLCS, 8,  // Offset(75),    set PL1 limit when entering CS
+  Offset(76),     PLVL, 16, // Offset(76),    PL1 limit value
+  Offset(78),     PB1E, 8,  // Offset(78),    10sec Power button support
+  Offset(79),     ECR1, 8,  // Offset(79),    Pci Delay Optimization Ecr
+  Offset(80),     TBTS, 8,  // Offset(80),    Thunderbolt(TM) support
+  Offset(81),     TNAT, 8,  // Offset(81),    TbtNativeOsHotPlug
+  Offset(82),     TBSE, 8,  // Offset(82),    Thunderbolt(TM) Root port selector
+  Offset(83),     TBS1, 8,  // Offset(83),    Thunderbolt(TM) Root port selector
+  }
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (30 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
                   ` (5 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

Header files for the WhiskeylakeURvp board instance.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h  | 131 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h      |  40 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h | 105 ++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h        |  44 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h   |  12 ++
 5 files changed, 332 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h
new file mode 100644
index 0000000000..bd849b9ee2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h
@@ -0,0 +1,131 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PLATFORM_HOOK_LIB_H_
+#define _PEI_PLATFORM_HOOK_LIB_H_
+
+#include <PlatformInfo.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/GpioLib.h>
+
+
+//EC Command to provide one byte of debug indication
+#define BSSB_DEBUG_INDICATION 0xAE
+/**
+  Configure EC for specific devices
+
+  @param[in] PchLan       - The PchLan of PCH_SETUP variable.
+  @param[in] BootMode     - The current boot mode.
+**/
+VOID
+EcInit (
+  IN UINT8                PchLan,
+  IN EFI_BOOT_MODE        BootMode
+  );
+
+/**
+  Checks if Premium PMIC present
+
+  @retval  TRUE  if present
+  @retval  FALSE it discrete/other PMIC
+**/
+BOOLEAN
+IsPremiumPmicPresent (
+  VOID
+  );
+
+/**
+  Pmic Programming to supprort LPAL Feature
+
+  @retval     NONE
+**/
+VOID
+PremiumPmicDisableSlpS0Voltage (
+  VOID
+  );
+
+/**
+Pmic Programming to supprort LPAL Feature
+  @retval     NONE
+**/
+VOID
+PremiumPmicEnableSlpS0Voltage(
+  VOID
+  );
+
+/**
+  Do platform specific programming pre-memory. For example, EC init, Chipset programming
+
+  @retval  Status
+**/
+EFI_STATUS
+PlatformSpecificInitPreMem (
+  VOID
+  );
+
+/**
+  Do platform specific programming post-memory.
+
+  @retval  Status
+**/
+EFI_STATUS
+PlatformSpecificInit (
+  VOID
+  );
+
+/**
+  Configure GPIO and SIO Before Memory is ready.
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInitPreMem (
+  VOID
+  );
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInit (
+  VOID
+  );
+
+/**
+Voltage Margining Routine
+
+@retval  EFI_SUCCESS   Operation success
+**/
+EFI_STATUS
+VoltageMarginingRoutine(
+  VOID
+  );
+
+/**
+  Detect recovery mode
+
+  @retval  EFI_SUCCESS       System in Recovery Mode
+  @retval  EFI_UNSUPPORTED   System doesn't support Recovery Mode
+  @retval  EFI_NOT_FOUND     System is not in Recovery Mode
+**/
+EFI_STATUS
+IsRecoveryMode (
+  VOID
+  );
+
+/**
+  Early board Configuration before Memory is ready.
+
+  @retval  EFI_SUCCESS  Operation success.
+**/
+EFI_STATUS
+BoardInitEarlyPreMem (
+  VOID
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h
new file mode 100644
index 0000000000..d65586dbb9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PLATFORM_LIB_H_
+#define _PEI_PLATFORM_LIB_H_
+
+
+
+#define PEI_DEVICE_DISABLED 0
+#define PEI_DEVICE_ENABLED  1
+
+typedef struct {
+  UINT8   Register;
+  UINT32  Value;
+} PCH_GPIO_DEV;
+
+//
+// GPIO Initialization Data Structure
+//
+typedef struct{
+  PCH_GPIO_DEV Use_Sel;
+  PCH_GPIO_DEV Use_Sel2;
+  PCH_GPIO_DEV Use_Sel3;
+  PCH_GPIO_DEV Io_Sel;
+  PCH_GPIO_DEV Io_Sel2;
+  PCH_GPIO_DEV Io_Sel3;
+  PCH_GPIO_DEV Lvl;
+  PCH_GPIO_DEV Lvl2;
+  PCH_GPIO_DEV Lvl3;
+  PCH_GPIO_DEV Inv;
+  PCH_GPIO_DEV Blink;
+  PCH_GPIO_DEV Rst_Sel;
+  PCH_GPIO_DEV Rst_Sel2;
+} GPIO_INIT_STRUCT;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h
new file mode 100644
index 0000000000..44b4059f8e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h
@@ -0,0 +1,105 @@
+/** @file
+  Header file for Platform Boards Configurations.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_BOARD_CONFIG_H
+#define _PLATFORM_BOARD_CONFIG_H
+
+#include <ConfigBlock.h>
+#include <PchPolicyCommon.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <GpioConfig.h>
+#include <TbtBoardInfo.h>
+
+#define IS_ALIGNED(addr, size) (((addr) & (size - 1)) ? 0 : 1)
+#define ALIGN16(size)          (IS_ALIGNED(size, 16) ? size : ((size + 16) & 0xFFF0))
+
+#define BOARD_CONFIG_BLOCK_PEI_PREMEM_VERSION  0x00000001
+#define BOARD_CONFIG_BLOCK_PEI_POSTMEM_VERSION 0x00000001
+#define BOARD_CONFIG_BLOCK_DXE_VERSION 0x00000001
+#define BOARD_NO_BATTERY_SUPPORT 0
+#define BOARD_REAL_BATTERY_SUPPORTED BIT0
+#define BOARD_VIRTUAL_BATTERY_SUPPORTED BIT1
+
+#pragma pack(1)
+
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+} BOARD_CONFIG_BLOCK;
+
+typedef struct {
+  UINT8 GpioSupport;
+  UINT32 WakeGpioNo;
+  UINT8 HoldRstExpanderNo;
+  UINT32 HoldRstGpioNo;
+  BOOLEAN HoldRstActive;
+  UINT8 PwrEnableExpanderNo;
+  UINT32 PwrEnableGpioNo;
+  BOOLEAN PwrEnableActive;
+} SWITCH_GRAPHIC_GPIO;
+
+typedef struct {
+  UINT8 ClkReqNumber : 4;
+  UINT8 ClkReqSupported : 1;
+  UINT8 DeviceResetPadActiveHigh : 1;
+  UINT32 DeviceResetPad;
+} ROOT_PORT_CLK_INFO;
+
+typedef struct {
+  UINT8 Section;
+  UINT8 Pin;
+} EXPANDER_GPIO_CONFIG;
+
+typedef enum {
+  BoardGpioTypePch,
+  BoardGpioTypeExpander,
+  BoardGpioTypeNotSupported = 0xFF
+} BOARD_GPIO_TYPE;
+
+typedef struct {
+  UINT8 Type;
+  UINT8 Reserved[3];  // alignment for COMMON_GPIO_CONFIG
+  union {
+    UINT32 Pin;
+    EXPANDER_GPIO_CONFIG Expander;
+  } u;
+} BOARD_GPIO_CONFIG;
+
+// Do not change the encoding. It must correspond with PCH_PCIE_CLOCK_USAGE from PCH RC.
+#define NOT_USED     0xFF
+#define FREE_RUNNING 0x80
+#define LAN_CLOCK    0x70
+#define PCIE_PEG     0x40
+#define PCIE_PCH     0x00
+
+typedef struct {
+  UINT32 ClockUsage;
+  UINT32 ClkReqSupported;
+} PCIE_CLOCK_CONFIG;
+
+typedef union {
+  UINT64 Blob;
+  BOARD_GPIO_CONFIG  BoardGpioConfig;
+  ROOT_PORT_CLK_INFO Info;
+  PCIE_CLOCK_CONFIG  PcieClock;
+} PCD64_BLOB;
+
+typedef union {
+  UINT32        Blob;
+  USB20_AFE     Info;
+} PCD32_BLOB;
+
+#ifndef IO_EXPANDER_DISABLED
+#define IO_EXPANDER_DISABLED      0xFF
+#endif
+
+#define SPD_DATA_SIZE 512
+
+#pragma pack()
+
+#endif // _PLATFORM_BOARD_CONFIG_H
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h
new file mode 100644
index 0000000000..0e0b6c4f6c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h
@@ -0,0 +1,44 @@
+/** @file
+  GUID used for Platform Info Data entries in the HOB list.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_INFO_H_
+#define _PLATFORM_INFO_H_
+
+#pragma pack(1)
+
+///
+/// PCH_GPIO_PAD is equivalent to GPIO_PAD which is defined in GpioConfig.h
+///
+typedef UINT32 PCH_GPIO_PAD; //Copied from GpioConfig.h (need to change it based on include)
+
+typedef struct {
+UINT8    Expander;
+UINT8    Pin;
+UINT16   Reserved; // Reserved for future use
+} IO_EXPANDER_PAD;
+
+typedef union {
+PCH_GPIO_PAD       PchGpio;
+IO_EXPANDER_PAD    IoExpGpio;
+} GPIO_PAD_CONFIG;
+
+typedef struct {
+UINT8                GpioType;    // 0: Disabled (no GPIO support), 1: PCH, 2: I/O Expander
+UINT8                Reserved[3]; // Reserved for future use
+GPIO_PAD_CONFIG      GpioData;
+} PACKED_GPIO_CONFIG;
+
+typedef union {
+PACKED_GPIO_CONFIG    PackedGpio;
+UINT64                Data64;
+} COMMON_GPIO_CONFIG;
+
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h
new file mode 100644
index 0000000000..7d44acccc1
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h
@@ -0,0 +1,12 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _WHISKEYLAKE_ERB_ID_H_
+#define _WHISKEYLAKE_ERB_ID_H_
+
+#define BoardIdWhiskeyLakeRvp          0x60
+#endif // _WHISKEYLAKE_RVP3_ID_H_
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (31 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
@ 2019-08-17  0:15 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
                   ` (4 subsequent siblings)
  37 siblings, 2 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:15 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

Common package library instances.

* BaseAcpiTimerLib - Support for ACPI timer services.
* BaseGpioExpanderLib - Support for the TCA6424 IO expander.
* DxePolicyUpdateLib - Policy update in DXE.
* DxeTbtPolicyLib - DXE Thunderbolt policy initialization.
* PeiDTbtInitLib - PEI discrete Thunderbolt initialization services.
* PeiFspPolicyInitLib - PEI Intel FSP policy initialization.
* PeiI2cAccessLib - Provides I2C read and write services.
* PeiPolicyInitLib - Policy initialization in PEI.
* PeiPolicyUpdateLib - Policy update in PEI.
* PeiSiliconPolicyUpdateLibFsp - PEI FSP silicon policy initialization.
* PeiTbtPolicyLib - PEI Thunderbolt policy initialization.
* SecFspWrapperPlatformSecLib - FSP wrapper PlatformSecLib instance.
* TbtCommonLib - Common Thunderbolt services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf                         |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf                      |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf                         |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf                   |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf                   |  161 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf |  139 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf   |   97 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf                                        |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf                              |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf                                |   67 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf                                      |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf                         |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf                             |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf                         |  272 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h                       |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h                       |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h                     |  234 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h            |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h             |   28 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h              |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h                     |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h                        |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h                                    | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h                            |   91 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h                            |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h                               |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h                                |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h                                  |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h                                |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h                                |   22 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h                           |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h                            |   14 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h                           |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h                            |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h                            |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c                           |  148 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c                        |  316 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c                           |  206 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c                     |  567 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c                  |  461 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c                   |  121 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c                    |   77 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c                  |  736 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c                     |  223 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c                   |  848 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c             |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c                   |   95 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c         |  100 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c          |  124 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c             |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c       |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c              |   85 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c        |   87 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c        |  163 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c                    |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c               |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c          |   79 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c                  |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c                  |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c                                          |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c                                |  310 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c                                  |  132 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c                                        |  115 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c                           |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c                            |  105 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c                           |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c                            |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c                                  |   65 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c                            |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c                                |  114 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c                           |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c                     |  108 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c                            |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c                      |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c                           |  523 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c                     |  113 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c                            |  242 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c                      |  221 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c                            |  168 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm            |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm                |  361 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm                   |   72 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni                                        |   15 +
 83 files changed, 13144 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
new file mode 100644
index 0000000000..0d2a6cceeb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for Tbt functionality
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeTbtPolicyLib
+FILE_GUID = 28ABF346-4E52-4BD3-b1FF-63BA7563C9D4
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+HobLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+[Sources]
+DxeTbtPolicyLib.c
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gTbtInfoHobGuid
+
+[Protocols]
+gDxeTbtPolicyProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
new file mode 100644
index 0000000000..f2330b5b71
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
@@ -0,0 +1,60 @@
+## @file
+# Component information file for Tbt common library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtCommonLib
+  FILE_GUID                      = 5F03614E-CB56-40B1-9989-A09E25BBA294
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = TbtCommonLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+  DebugLib
+  PchPcieRpLib
+  PciSegmentLib
+  TimerLib
+  BaseLib
+  GpioLib
+  GpioExpanderLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode           ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport       ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI              ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify           ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq           ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm                ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch          ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt                ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq          ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax  ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd       ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber
+
+[Sources]
+  TbtCommonLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
new file mode 100644
index 0000000000..b74e641e16
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for Tbt policy
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiTbtPolicyLib
+FILE_GUID = 4A95FDBB-2535-49eb-9A79-D56D24257106
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+DebugLib
+PostCodeLib
+HobLib
+GpioLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad    ## CONSUMES
+
+[Sources]
+PeiTbtPolicyLib.c
+
+[Guids]
+gTbtInfoHobGuid
+
+[Ppis]
+gEfiPeiReadOnlyVariable2PpiGuid
+gPeiTbtPolicyPpiGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
new file mode 100644
index 0000000000..8e0dbe73ce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for PEI DTBT Init library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiDTbtInitLib
+  FILE_GUID                      = 06768A8D-8152-403f-83C1-59584FD2B438
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiDTbtInitLib
+
+[LibraryClasses]
+  PeiServicesLib
+  DebugLib
+  PcdLib
+  TbtCommonLib
+  PciSegmentLib
+  PeiTbtPolicyLib
+  PchPmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Ppis]
+  gPeiTbtPolicyPpiGuid                          ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  #gClientCommonModuleTokenSpaceGuid.PcdTbtSupport    ## PRODUCES
+
+[Sources]
+  PeiDTbtInitLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
new file mode 100644
index 0000000000..bd39cd60b7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
@@ -0,0 +1,161 @@
+## @file
+# Library functions for Fsp Policy Initialization Library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiFspPolicyInitLib
+  FILE_GUID                      = 2CB87D67-D1A4-4CD3-8CD7-91A1FA1DF6E0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyInitLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  PeiFspPolicyInitLib.c
+  PeiFspSiPolicyInitLib.c
+  PeiFspPchPolicyInitLib.c
+  PeiFspCpuPolicyInitLib.c
+  PeiFspMePolicyInitLib.c
+  PeiFspSaPolicyInitLib.c
+  PeiFspSecurityPolicyInitLib.c
+  PeiFspMiscUpdInitLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  CoffeeLakeFspBinPkg/CoffeeLakeFspBinPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  PeiServicesLib
+  SmbusLib
+  ConfigBlockLib
+  PcdLib
+  MemoryAllocationLib
+  PchInfoLib
+  SpiLib
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdTsegSize
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize          ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize           ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize         ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode                   ## CONSUMES
+
+[Ppis]
+  gSiPolicyPpiGuid                        ## CONSUMES
+  gSiPreMemPolicyPpiGuid                  ## CONSUMES
+  gEfiSecPlatformInformation2PpiGuid      ## CONSUMES
+  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
+
+[Guids]
+  gPchTraceHubPreMemConfigGuid            ## CONSUMES
+  gSmbusPreMemConfigGuid                  ## CONSUMES
+  gDciPreMemConfigGuid                    ## CONSUMES
+  gPcieRpPreMemConfigGuid                 ## CONSUMES
+  gHdAudioPreMemConfigGuid                ## CONSUMES
+  gIshPreMemConfigGuid                    ## CONSUMES
+  gHsioPciePreMemConfigGuid               ## CONSUMES
+  gHsioSataPreMemConfigGuid               ## CONSUMES
+  gLpcPreMemConfigGuid                    ## CONSUMES
+  gPchGeneralPreMemConfigGuid             ## CONSUMES
+  gWatchDogPreMemConfigGuid               ## CONSUMES
+  gLanConfigGuid                          ## CONSUMES
+  gPcieRpConfigGuid                       ## CONSUMES
+  gSataConfigGuid                         ## CONSUMES
+  gHdAudioConfigGuid                      ## CONSUMES
+  gScsConfigGuid                          ## CONSUMES
+  gIshConfigGuid                          ## CONSUMES
+  gSataConfigGuid                         ## CONSUMES
+  gUsbConfigGuid                          ## CONSUMES
+  gSerialIoConfigGuid                     ## CONSUMES
+  gInterruptConfigGuid                    ## CONSUMES
+  gLockDownConfigGuid                     ## CONSUMES
+  gSaMiscPeiPreMemConfigGuid              ## PRODUCES
+  gSaMiscPeiConfigGuid                    ## PRODUCES
+  gMemoryConfigGuid                       ## CONSUMES
+  gMemoryConfigNoCrcGuid                  ## CONSUMES
+  gSwitchableGraphicsConfigGuid           ## CONSUMES
+  gGraphicsPeiPreMemConfigGuid            ## CONSUMES
+  gSaPciePeiPreMemConfigGuid              ## CONSUMES
+  gSaMiscPeiConfigGuid                    ## CONSUMES
+  gSaPciePeiConfigGuid                    ## CONSUMES
+  gGraphicsPeiConfigGuid                  ## CONSUMES
+  gCpuTraceHubConfigGuid                  ## CONSUMES
+  gIpuPreMemConfigGuid                    ## CONSUMES
+  gCnviConfigGuid                         ## CONSUMES
+  gHsioConfigGuid                         ## CONSUMES
+  gEspiConfigGuid                         ## CONSUMES
+  gGnaConfigGuid                          ## CONSUMES
+  gVtdConfigGuid                          ## CONSUMES
+  gSaOverclockingPreMemConfigGuid         ## CONSUMES
+  gMePeiPreMemConfigGuid                  ## CONSUMES
+  gMePeiConfigGuid                        ## CONSUMES
+  gDmiConfigGuid                          ## CONSUMES
+  gFlashProtectionConfigGuid              ## CONSUMES
+  gIoApicConfigGuid                       ## CONSUMES
+  gPmConfigGuid                           ## CONSUMES
+  gP2sbConfigGuid                         ## CONSUMES
+  gPchGeneralConfigGuid                   ## CONSUMES
+  gSerialIrqConfigGuid                    ## CONSUMES
+  gThermalConfigGuid                      ## CONSUMES
+  gCpuSecurityPreMemConfigGuid            ## CONSUMES
+  gCpuConfigGuid                          ## CONSUMES
+  gCpuOverclockingPreMemConfigGuid        ## CONSUMES
+  gCpuConfigLibPreMemConfigGuid           ## CONSUMES
+  gCpuPowerMgmtBasicConfigGuid            ## CONSUMES
+  gCpuPowerMgmtCustomConfigGuid           ## CONSUMES
+  gCpuTestConfigGuid                      ## CONSUMES
+  gCpuPidTestConfigGuid                   ## CONSUMES
+  gCpuPowerMgmtTestConfigGuid             ## CONSUMES
+  gFspNonVolatileStorageHobGuid           ## CONSUMES
+  gSmramCpuDataHeaderGuid                 ## CONSUMES
+  gFspReservedMemoryResourceHobTsegGuid   ## CONSUMES
+  gSiConfigGuid                           ## CONSUMES
+  gDebugConfigHobGuid                     ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
new file mode 100644
index 0000000000..994cf93e33
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
@@ -0,0 +1,139 @@
+## @file
+#  Provide FSP wrapper platform related function.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconPolicyUpdateLibFsp
+  FILE_GUID                      = 4E83003B-49A9-459E-AAA6-1CA3C6D04FB2
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyUpdateLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  PeiFspPolicyUpdateLib.c
+  PeiPchPolicyUpdatePreMem.c
+  PeiPchPolicyUpdate.c
+  PeiSaPolicyUpdatePreMem.c
+  PeiSaPolicyUpdate.c
+  PeiFspMiscUpdUpdateLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  CoffeeLakeFspBinPkg/CoffeeLakeFspBinPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses.IA32]
+  FspWrapperApiLib
+  OcWdtLib
+  PchResetLib
+  FspWrapperPlatformLib
+  BaseMemoryLib
+  CpuPlatformLib
+  DebugLib
+  HdaVerbTableLib
+  HobLib
+  IoLib
+  PcdLib
+  PostCodeLib
+  SmbusLib
+  ConfigBlockLib
+  PeiSaPolicyLib
+  PchGbeLib
+  PchInfoLib
+  PchHsioLib
+  PchPcieRpLib
+  MemoryAllocationLib
+  DebugPrintErrorLevelLib
+  SiPolicyLib
+  PchGbeLib
+  TimerLib
+  GpioLib
+  PeiLib
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable        ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber             ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size
+
+  gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+[Guids]
+  gFspNonVolatileStorageHobGuid                 ## CONSUMES
+  gTianoLogoGuid                                ## CONSUMES
+  gEfiMemoryOverwriteControlDataGuid
+
+[Depex]
+  gEdkiiVTdInfoPpiGuid
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
new file mode 100644
index 0000000000..06489a6336
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
@@ -0,0 +1,97 @@
+## @file
+#  Provide FSP wrapper platform sec related function.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecFspWrapperPlatformSecLib
+  FILE_GUID                      = 4E1C4F95-90EA-47de-9ACC-B8920189A1F5
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSecLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  FspWrapperPlatformSecLib.c
+  SecRamInitData.c
+  SecPlatformInformation.c
+  SecGetPerformance.c
+  SecTempRamDone.c
+  PlatformInit.c
+
+[Sources.IA32]
+  Ia32/SecEntry.nasm
+  Ia32/PeiCoreEntry.nasm
+  Ia32/Stack.nasm
+  Ia32/Fsp.h
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  LocalApicLib
+  SerialPortLib
+  FspWrapperPlatformLib
+  FspWrapperApiLib
+  BoardInitLib
+  SecBoardInitLib
+  TestPointCheckLib
+  IoLib
+
+[Ppis]
+  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
+  gPeiSecPerformancePpiGuid               ## CONSUMES
+  gTopOfTemporaryRamPpiGuid               ## PRODUCES
+  gEfiPeiFirmwareVolumeInfoPpiGuid        ## PRODUCES
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize               ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress                  ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize                  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdSecSerialPortDebugEnable        ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
+
+[FixedPcd]
+  gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress         ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize      ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset             ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress            ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize               ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
new file mode 100644
index 0000000000..e7eef24906
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
@@ -0,0 +1,54 @@
+## @file
+#  Base ACPI Timer Library
+#
+#  Provides basic timer support using the ACPI timer hardware.  The performance
+#  counter features are provided by the processors time stamp counter.
+#
+#  Note: The implementation uses the lower 24-bits of the ACPI timer and
+#  is compatible with both 24-bit and 32-bit ACPI timers.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseAcpiTimerLib
+  FILE_GUID                      = 564DE85F-049E-4481-BF7A-CA04D2788CF9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib|SEC PEI_CORE PEIM
+  CONSTRUCTOR                    = AcpiTimerLibConstructor
+  MODULE_UNI_FILE                = BaseAcpiTimerLib.uni
+
+[Sources]
+  AcpiTimerLib.c
+  BaseAcpiTimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec      ## OVERRIDE
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  PciLib
+  IoLib
+  DebugLib
+
+[Pcd]
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber             ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber          ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber        ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset  ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask            ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset     ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress          ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset               ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask      ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
new file mode 100644
index 0000000000..ef5ede18cc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Library producing Gpio Expander functionality.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BaseGpioExpanderLib
+  FILE_GUID                      = D10AE2A4-782E-427E-92FB-BB74505ED329
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = GpioExpanderLib
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  TimerLib
+  PchSerialIoLib
+  I2cAccessLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioExpanderLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
new file mode 100644
index 0000000000..3c017577b6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
@@ -0,0 +1,67 @@
+## @file
+#  PEI Intel HD Audio Verb Table library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiHdaVerbTableLib
+  FILE_GUID                      = 821486A2-CF3B-4D24-BC45-AFE40D9737EB
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = HdaVerbTableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  PeiHdaVerbTableLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PcdLib
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdHdaVerbTable                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable    ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
new file mode 100644
index 0000000000..887cbf84f8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
@@ -0,0 +1,39 @@
+## @file
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiI2cAccessLib
+  FILE_GUID                      = 72CD3A7B-FEA5-4F5E-9165-4DD12187BB13
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = PeiI2cAccessLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiI2cAccessLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
new file mode 100644
index 0000000000..16653f38bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
@@ -0,0 +1,58 @@
+## @file
+#  Component description file for DXE DxePolicyUpdateLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxePolicyUpdateLib
+  FILE_GUID                      = 690B3786-D215-4ABB-9EF2-7A80128560E0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  DxeMePolicyUpdate.c
+  DxeSaPolicyUpdate.c
+  DxePchPolicyUpdate.c
+  DxeCpuPolicyUpdate.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseLib
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  IoLib
+  CpuPlatformLib
+  HobLib
+  ConfigBlockLib
+  PciSegmentLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+
+[Guids]
+  gEfiGlobalVariableGuid                        ## CONSUMES
+  gEfiEndOfDxeEventGroupGuid                    ## CONSUMES
+  gMeInfoSetupGuid                              ## PRODUCES
+  gMePolicyHobGuid                              ## CONSUMES
+  gCpuSetupVariableGuid                         ## CONSUMES
+  gPchSetupVariableGuid                         ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
new file mode 100644
index 0000000000..293abf1904
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
@@ -0,0 +1,61 @@
+## @file
+# Component description file for PeiPolicyInit library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyInitLib
+  FILE_GUID                      = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyInitLib
+
+[LibraryClasses]
+  BaseMemoryLib
+  BaseLib
+  CpuPlatformLib
+  DebugLib
+  DebugPrintErrorLevelLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  PeiServicesLib
+  PeiPolicyBoardConfigLib
+  PeiPolicyUpdateLib
+  PostCodeLib
+  SmbusLib
+  ConfigBlockLib
+  SiPolicyLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy ## CONSUMES
+
+
+[Sources]
+  PeiPolicyInitPreMem.c
+  PeiPolicyInit.c
+  PeiPolicyInit.h
+  PeiCpuPolicyInit.h
+  PeiMePolicyInit.h
+  PeiSaPolicyInit.c
+  PeiSaPolicyInit.h
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+  gSiPreMemPolicyPpiGuid                        ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
new file mode 100644
index 0000000000..3095a7333e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
@@ -0,0 +1,272 @@
+## @file
+# Module Information file for PEI PolicyUpdateLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyUpdateLib
+  FILE_GUID                      = 6EA9585C-3C15-47DA-9FFC-25E9E4EA4D0C
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyUpdateLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+  HobLib
+  BaseCryptLib
+  CpuPlatformLib
+  IoLib
+  PeiSaPolicyLib
+  ConfigBlockLib
+  PchGbeLib
+  PchInfoLib
+  PchPcieRpLib
+  HdaVerbTableLib
+  MemoryAllocationLib
+  PeiServicesTablePointerLib
+  PcdLib
+  Tpm2CommandLib
+  Tpm12CommandLib
+  Tpm2DeviceLib
+  Tpm12DeviceLib
+  PmcLib
+  SataLib
+  PchInfoLib
+  PciSegmentLib
+  SiPolicyLib
+  PeiServicesLib
+  SpiLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdTsegSize                             ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize          ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdMchBaseAddress             ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable    ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber         ## CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGttMmAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit       ## CONSUMES
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize                 ## CONSUMES
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## CONSUMES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive            ## CONSUMES
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex                  ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive           ## CONSUMES
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3            ## CONSUMES
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent              ## CONSUMES
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15                    ## CONSUMES
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe                 ## CONSUMES
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15      ## CONSUMES
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9       ## CONSUMES
+
+  # Pch SerialIo I2c Pads Termination
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdEcPresent
+
+  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSataLedEnable                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdVrAlertEnable                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEnable  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEnable  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid   ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber           ## CONSUMES
+
+[FixedPcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiAcpiReclaimMemorySize  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiAcpiNvsMemorySize      ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize     ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize       ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize       ## CONSUMES
+
+[Sources]
+  PeiPchPolicyUpdatePreMem.c
+  PeiPchPolicyUpdate.c
+  PeiCpuPolicyUpdatePreMem.c
+  PeiCpuPolicyUpdate.c
+  PeiMePolicyUpdatePreMem.c
+  PeiMePolicyUpdate.c
+  PeiSaPolicyUpdate.c
+  PeiSaPolicyUpdatePreMem.c
+  PeiSiPolicyUpdate.c
+
+[Ppis]
+  gWdtPpiGuid                                   ## CONSUMES
+  gPchSpiPpiGuid                                ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+  gSiPreMemPolicyPpiGuid                        ## CONSUMES
+  gPeiTbtPolicyPpiGuid                          ## CONSUMES
+
+[Guids]
+  gTianoLogoGuid                                ## CONSUMES
+  gSiConfigGuid                                 ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
new file mode 100644
index 0000000000..a88385f36f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
@@ -0,0 +1,25 @@
+/** @file
+  Header file for the DxeTBTPolicy library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_LIBRARY_H_
+#define _DXE_TBT_POLICY_LIBRARY_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+//#include <SetupVariable.h>
+#include <Guid/EventGroup.h>
+
+#endif // _DXE_TBT_POLICY_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
new file mode 100644
index 0000000000..462bf780e3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
@@ -0,0 +1,19 @@
+/** @file
+  Header file for the PeiTBTPolicy library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_LIBRARY_H_
+#define _PEI_TBT_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#endif // _PEI_TBT_POLICY_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
new file mode 100644
index 0000000000..52f9fbed8b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
@@ -0,0 +1,234 @@
+/** @file
+  Internal header file for Fsp Policy Initialization Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_FSP_POLICY_INIT_LIB_H_
+#define _PEI_FSP_POLICY_INIT_LIB_H_
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+#include <Setup.h>
+
+/**
+  Performs FSP SI PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP SI PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+/**
+  Performs FSP PCH PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInit (
+  IN OUT FSPS_UPD     *FspsUpd
+  );
+
+/**
+  Performs FSP CPU PEI Policy initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+Performs FSP Security PEI Policy initialization.
+
+@param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+@retval          EFI_SUCCESS         FSP UPD Data is updated.
+@retval          EFI_NOT_FOUND       Fail to locate required PPI.
+@retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInitPreMem(
+IN OUT FSPM_UPD    *FspmUpd
+);
+
+/**
+  Performs FSP ME PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP ME PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInit (
+  IN OUT FSPS_UPD     *FspsUpd
+  );
+
+/**
+  Performs FSP SA PEI Policy initialization in pre-memory.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP SA PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+/**
+  Performs FSP CPU PEI Policy post memory initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+/**
+Performs FSP Security PEI Policy post memory initialization.
+
+@param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+@retval          EFI_SUCCESS         FSP UPD Data is updated.
+@retval          EFI_NOT_FOUND       Fail to locate required PPI.
+@retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInit(
+IN OUT FSPS_UPD    *FspsUpd
+);
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32               *Size
+  );
+
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+#endif // _PEI_FSP_POLICY_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
new file mode 100644
index 0000000000..a0c8f2dae7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_MISC_POLICY_UPDATE_H_
+#define _PEI_MISC_POLICY_UPDATE_H_
+
+#include <FspmUpd.h>
+
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+#endif
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h
new file mode 100644
index 0000000000..1ff16e2f32
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h
@@ -0,0 +1,28 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_UPDATE_H_
+#define _PEI_PCH_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/MmPciLib.h>
+#include <Library/ConfigBlockLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..9b8c28c469
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h
@@ -0,0 +1,30 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_UPDATE_H_
+#define _PEI_SA_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <SaPolicyCommon.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include "PeiPchPolicyUpdate.h"
+#include <Library/PcdLib.h>
+#include <CpuAccess.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+extern EFI_GUID gTianoLogoGuid;
+
+#endif
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
new file mode 100644
index 0000000000..e7b5ed952b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __FSPT_CORE_UPD_H__
+#define __FSPT_CORE_UPD_H__
+
+#pragma pack(1)
+
+/** Fsp T Core UPD
+**/
+typedef struct {
+
+/** Offset 0x0020
+**/
+  UINT32                      MicrocodeRegionBase;
+
+/** Offset 0x0024
+**/
+  UINT32                      MicrocodeRegionSize;
+
+/** Offset 0x0028
+**/
+  UINT32                      CodeRegionBase;
+
+/** Offset 0x002C
+**/
+  UINT32                      CodeRegionSize;
+
+/** Offset 0x0030
+**/
+  UINT8                       Reserved[16];
+} FSPT_CORE_UPD;
+
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
new file mode 100644
index 0000000000..1c88285a1d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
@@ -0,0 +1,43 @@
+/** @file
+  Fsp related definitions
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __FSP_H__
+#define __FSP_H__
+
+//
+// Fv Header
+//
+#define FVH_SIGINATURE_OFFSET         0x28
+#define FVH_SIGINATURE_VALID_VALUE    0x4856465F  // valid signature:_FVH
+#define FVH_HEADER_LENGTH_OFFSET      0x30
+#define FVH_EXTHEADER_OFFSET_OFFSET   0x34
+#define FVH_EXTHEADER_SIZE_OFFSET     0x10
+
+//
+// Ffs Header
+//
+#define FSP_HEADER_GUID_DWORD1        0x912740BE
+#define FSP_HEADER_GUID_DWORD2        0x47342284
+#define FSP_HEADER_GUID_DWORD3        0xB08471B9
+#define FSP_HEADER_GUID_DWORD4        0x0C3F3527
+#define FFS_HEADER_SIZE_VALUE         0x18
+
+//
+// Section Header
+//
+#define SECTION_HEADER_TYPE_OFFSET    0x03
+#define RAW_SECTION_HEADER_SIZE_VALUE 0x04
+
+//
+// Fsp Header
+//
+#define FSP_HEADER_IMAGEBASE_OFFSET     0x1C
+#define FSP_HEADER_TEMPRAMINIT_OFFSET   0x30
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h
new file mode 100644
index 0000000000..0d26e8ad7a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h
@@ -0,0 +1,3014 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_VERB_TABLES_H_
+#define _PCH_HDA_VERB_TABLES_H_
+
+#include <Ppi/SiPolicy.h>
+
+HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: CFL Display Audio Codec
+  //  Revision ID = 0xFF
+  //  Codec Vendor: 0x8086280B
+  //
+  0x8086, 0x280B,
+  0xFF, 0xFF,
+  //
+  // Display Audio Verb Table
+  //
+  // For GEN9, the Vendor Node ID is 08h
+  // Port to be exposed to the inbox driver in the vanilla mode: PORT C - BIT[7:6] = 01b
+  0x00878140,
+  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
+  0x00571C10,
+  0x00571D00,
+  0x00571E56,
+  0x00571F18,
+  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
+  0x00671C20,
+  0x00671D00,
+  0x00671E56,
+  0x00671F18,
+  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
+  0x00771C30,
+  0x00771D00,
+  0x00771E56,
+  0x00771F18,
+  // Disable the third converter and third Pin (NID 08h)
+  0x00878140
+);
+
+//
+//codecs verb tables
+//
+HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40622005
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D20,
+  0x01D71E62,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B,
+
+
+  //Widget node 0X20 for ALC1305   20160603 update
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+  //
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204800F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02044848,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050000,
+  0x02043330,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050000,
+  0x02043333,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x020402EC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02044909,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x020440B0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040047,
+  0x02050028,
+  0x02040C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040048,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040049,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004A,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040001,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024
+); // HdaVerbTableAlc700
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC701)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0701
+  //
+  0x10EC, 0x0701,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC701
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40610041
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC1124
+  0x00172024,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C41,
+  0x01D71D00,
+  0x01D71E61,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B
+); // HdaVerbTableAlc701
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC274)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0274
+  //
+  0x10EC, 0x0274,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC274
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
+  //The number of verb command block : 16
+
+  //    NID 0x12 : 0x40000000
+  //    NID 0x13 : 0x411111F0
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x411111F0
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11020
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40451B05
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211010
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //,DA Codec Subsystem ID  : 0x10EC10F6
+  0x001720F6,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371CF0,
+  0x01371D11,
+  0x01371E11,
+  0x01371F41,
+  //Pin widget 0x14 - NPC
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S_OUT2
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S_OUT1
+  0x01771CF0,
+  0x01771D11,
+  0x01771E11,
+  0x01771F41,
+  //Pin widget 0x18 - I2S_IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C20,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D1B,
+  0x01D71E45,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C10,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205006F,
+  0x02042C0B,
+  //Widget node 0x20 - 1 :
+  0x02050035,
+  0x02048968,
+  0x05B50001,
+  0x05B48540,
+  //Widget node 0x20 - 2 :
+  0x05850000,
+  0x05843888,
+  0x05850000,
+  0x05843888,
+  //Widget node 0x20 - 3 :
+  0x0205004A,
+  0x0204201B,
+  0x0205004A,
+  0x0204201B
+); //HdaVerbTableAlc274
+
+//
+// CFL S Audio Codec
+//
+STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) CFL S RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x90A60130
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x03011010
+  //    NID 0x17 : 0x90170120
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A1103E
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x03A11040
+  //    NID 0x1D : 0x40600001
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x0421102F
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC112C
+  0x0017202C,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C30,
+  0x01271D01,
+  0x01271EA6,
+  0x01271F90,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671C10,
+  0x01671D10,
+  0x01671E01,
+  0x01671F03,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C20,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C3E,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71C40,
+  0x01B71D10,
+  0x01B71EA1,
+  0x01B71F03,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C01,
+  0x01D71D00,
+  0x01D71E60,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C2F,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
+  0x0205006B,
+  0x02044260,
+  0x0205006B,
+  0x02044260,
+  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent control
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 4   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+
+  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove ALC1305 EQ setting
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x02042213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+);
+
+
+//
+// WHL codecs verb tables
+//
+HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) WHL RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table for WHL PCH boards
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x02A19040
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40638029
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x02211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271CF0,
+  0x01271D11,
+  0x01271E11,
+  0x01271F41,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C40,
+  0x01971D90,
+  0x01971EA1,
+  0x01971F02,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C29,
+  0x01D71D80,
+  0x01D71E63,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F02,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+
+  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass DAC02 DRE(NID5B bit14)
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+
+  //Widget node 0x20 -2:
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+
+  //Widget node 0x20 - 3   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+
+  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x0204E213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204422E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+); // WhlHdaVerbTableAlc700
+
+#endif // _PCH_HDA_VERB_TABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h
new file mode 100644
index 0000000000..8cbcace075
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h
@@ -0,0 +1,91 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_ME_POLICY_UPDATE_H_
+#define _DXE_ME_POLICY_UPDATE_H_
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Guid/EventGroup.h>
+#include <IndustryStandard/Acpi10.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/MePolicy.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/MePeiConfig.h>
+
+#define PLATFORM_BOOT_TABLE_PTR_TYPE   0x1001
+#define PLATFORM_BOOT_RECORD_TYPE      0x1022
+//
+// Timeout values based on HPET
+//
+#define HECI_MSG_DELAY                 2000000  ///< show warning msg and stay for 2 seconds.
+#define CONVERSION_MULTIPLIER          1000000  ///< msec to nanosec multiplier
+#define PLATFORM_BOOT_TABLE_SIGNATURE  SIGNATURE_32 ('P', 'B', 'P', 'T')
+
+//
+// Platform Boot Performance Table Record
+//
+
+typedef struct {
+  UINT16 Type;
+  UINT8  Length;
+  UINT8  Revision;
+  UINT32 Reserved;
+  UINT64 TimestampDelta1;
+  UINT64 TimestampDelta2;
+  UINT64 TimestampDelta3;
+} PLATFORM_BOOT_TABLE_RECORD;
+
+//
+// Platform boot Performance Table
+//
+
+typedef struct {
+  EFI_ACPI_COMMON_HEADER     Header;
+  PLATFORM_BOOT_TABLE_RECORD PlatformBoot;
+} PLATFORM_BOOT_PERFORMANCE_TABLE;
+
+/**
+  Update ME Policy while MePlatformProtocol is installed.
+
+  @param[in] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromMeSetup (
+  IN ME_POLICY_PROTOCOL           *MePolicyInstance
+  );
+
+/**
+  Update ME Policy if Setup variable exists.
+
+  @param[in, out] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromSetup (
+  IN OUT ME_POLICY_PROTOCOL     *MePolicyInstance
+  );
+
+/**
+  Functions performs HECI exchange with FW to update MePolicy settings.
+
+  @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
+UpdateMeSetupCallback (
+  IN  EFI_EVENT                       Event,
+  IN  VOID                            *Context
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
new file mode 100644
index 0000000000..4521d83567
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_UPDATE_H_
+#define _DXE_SA_POLICY_UPDATE_H_
+
+#include <PiDxe.h>
+#include <CpuRegs.h>
+#include <PchAccess.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
new file mode 100644
index 0000000000..25c5213c2d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the PeiCpuPolicyInit.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_INIT_H_
+#define _PEI_CPU_POLICY_INIT_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+
+/**
+  This function performs CPU PEI Policy initialization in PreMem.
+
+  @param[in, out] SiPreMemPolicyPpi  The Si Pre-Mem Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h
new file mode 100644
index 0000000000..7f3fde9fd8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for the PeiMePolicyInit
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_ME_POLICY_INIT_H_
+#define _PEI_ME_POLICY_INIT_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiMePolicyLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+
+#endif // _PEI_ME_POLICY_INIT_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h
new file mode 100644
index 0000000000..9c18f85735
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for the PolicyInitPei PEIM.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_INIT_H_
+#define _PEI_POLICY_INIT_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "PeiCpuPolicyInit.h"
+#include "PeiMePolicyInit.h"
+#include "PeiSaPolicyInit.h"
+#include "PeiSiPolicyInit.h"
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
new file mode 100644
index 0000000000..83b18bf533
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
@@ -0,0 +1,58 @@
+/** @file
+  Header file for the SaPolicyInitPei PEIM.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_INIT_PEI_H_
+#define _SA_POLICY_INIT_PEI_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Ppi/SiPolicy.h>
+#include <SaPolicyCommon.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+#include <Library/TimerLib.h>
+#include <Library/GpioLib.h>
+
+//
+// Functions
+//
+/**
+PCIe GPIO Write
+
+@param[in] Gpio        - GPIO Number
+@param[in] Active      - GPIO Active Information; High/Low
+@param[in] Level       - Write GPIO value (0/1)
+
+**/
+VOID
+PcieGpioWrite(
+IN       UINT32                       Gpio,
+IN       BOOLEAN                      Active,
+IN       BOOLEAN                      Level
+);
+
+/**
+PcieCardResetWorkAround performs PCIe Card reset on root port
+
+@param[in out] SiPreMemPolicyPpi       - SI_PREMEM_POLICY_PPI
+
+@retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+PcieCardResetWorkAround(
+IN OUT   SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
new file mode 100644
index 0000000000..1a28f426d6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for the PeiSiPolicyInit
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_INIT_PEI_H_
+#define _SI_POLICY_INIT_PEI_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+
+#endif // _SI_POLICY_INIT_PEI_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
new file mode 100644
index 0000000000..254e58edb7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
@@ -0,0 +1,32 @@
+/** @file
+  Header file for PEI CpuPolicyUpdate.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_UPDATE_H_
+#define _PEI_CPU_POLICY_UPDATE_H_
+
+#include <PiPei.h>
+#include <Ppi/SiPolicy.h>
+#include <Ppi/Wdt.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <PlatformBoardId.h>
+#include <PchAccess.h>
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <CpuAccess.h>
+#include <Ppi/MasterBootMode.h>
+#include <Library/PeiServicesLib.h>
+#include "PeiPchPolicyUpdate.h"
+#include <Library/CpuPlatformLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h
new file mode 100644
index 0000000000..37cd373c78
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h
@@ -0,0 +1,14 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_ME_POLICY_UPDATE_H_
+#define _PEI_ME_POLICY_UPDATE_H_
+
+#include <Library/DebugLib.h>
+#include <Ppi/SiPolicy.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h
new file mode 100644
index 0000000000..5a69852801
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_UPDATE_H_
+#define _PEI_PCH_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PiPei.h>
+#include <PlatformBoardId.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+#include <PlatformBoardConfig.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..8cf24ed24d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
@@ -0,0 +1,53 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_UPDATE_H_
+#define _PEI_SA_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PlatformBoardId.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Ppi/Wdt.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include "PeiPchPolicyUpdate.h"
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <CpuAccess.h>
+
+#define WDT_TIMEOUT 60
+
+// BClk Frequency Limitations (in Hz)
+#define BCLK_MAX                538000000
+#define BCLK_100                100000000
+#define BCLK_GRANULARITY        1000000
+#define BCLK_100_KHZ            100000
+
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32               *Size
+  );
+
+#endif
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
new file mode 100644
index 0000000000..38ea081166
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
@@ -0,0 +1,19 @@
+/** @file
+   Header file for PEI SiPolicyUpdate.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_UPDATE_H_
+#define _PEI_SI_POLICY_UPDATE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
new file mode 100644
index 0000000000..c185cda4ce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
@@ -0,0 +1,148 @@
+/** @file
+  This file is DxeTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <DxeTbtPolicyLibrary.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+
+
+/**
+  Update Tbt Policy Callback
+**/
+
+VOID
+EFIAPI
+UpdateTbtPolicyCallback (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  DXE_TBT_POLICY_PROTOCOL        *DxeTbtConfig;
+
+  DxeTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+  DEBUG ((DEBUG_INFO, "UpdateTbtPolicyCallback\n"));
+
+  Status = gBS->LocateProtocol (
+                  &gDxeTbtPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &DxeTbtConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+  } else {
+
+  }
+
+  return;
+}
+
+/**
+  Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+  VOID
+  )
+{
+  EFI_STATUS                       Status;
+  UINT8                            Index;
+  DXE_TBT_POLICY_PROTOCOL          *DxeTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtPrintDxePolicyConfig Start\n"));
+
+  DxeTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+  Status = gBS->LocateProtocol (
+                  &gDxeTbtPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &DxeTbtConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Print DTBT Policy
+  //
+  DEBUG ((DEBUG_ERROR, " ========================= DXE TBT POLICY ========================= \n"));
+  for (Index = 0; Index < MAX_DTBT_CONTROLLER_NUMBER; Index++) {
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieExtraBusRsvd = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieExtraBusRsvd));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieMemRsvd = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieMemRsvd));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieMemAddrRngMax = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieMemAddrRngMax));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPciePMemRsvd = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPciePMemRsvd));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPciePMemAddrRngMax = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPciePMemAddrRngMax));
+  }
+
+  //
+  // Print TBT Common Policy
+  //
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAspm = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAspm));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtL1SubStates = %x\n", DxeTbtConfig->TbtCommonConfig.TbtL1SubStates));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotNotify = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotNotify));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotSMI = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotSMI));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtLtr = %x\n", DxeTbtConfig->TbtCommonConfig.TbtLtr));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtPtm = %x\n", DxeTbtConfig->TbtCommonConfig.TbtPtm));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtSetClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.TbtSetClkReq));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = %x\n", DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.SecurityMode = %x\n", DxeTbtConfig->TbtCommonConfig.SecurityMode));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Gpio5Filter = %x\n", DxeTbtConfig->TbtCommonConfig.Gpio5Filter));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TrA0OsupWa = %x\n", DxeTbtConfig->TbtCommonConfig.TrA0OsupWa));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3Tbt = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3Tbt));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Win10Support = %x\n", DxeTbtConfig->TbtCommonConfig.Win10Support));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtVtdBaseSecurity = %x\n", DxeTbtConfig->TbtCommonConfig.TbtVtdBaseSecurity));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.ControlIommu = %x\n", DxeTbtConfig->TbtCommonConfig.ControlIommu));
+  return;
+}
+
+/**
+  Install Tbt Policy
+
+  @param[in] ImageHandle                Image handle of this driver.
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+  IN  EFI_HANDLE                    ImageHandle
+  )
+{
+  EFI_STATUS                    Status;
+  DXE_TBT_POLICY_PROTOCOL       *DxeTbtPolicy;
+
+  DEBUG ((DEBUG_INFO, "Install DXE TBT Policy\n"));
+
+  DxeTbtPolicy = NULL;
+  //Alloc memory for DxeTbtPolicy
+  DxeTbtPolicy = (DXE_TBT_POLICY_PROTOCOL *) AllocateZeroPool (sizeof (DXE_TBT_POLICY_PROTOCOL));
+  if (DxeTbtPolicy == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = gBS->InstallProtocolInterface (
+                  &ImageHandle,
+                  &gDxeTbtPolicyProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  DxeTbtPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install Tbt Secure Boot List protocol failed\n"));
+  }
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
new file mode 100644
index 0000000000..690c9acf95
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
@@ -0,0 +1,316 @@
+/** @file
+  PeiTbtInit library implementition with empty functions.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+
+
+/**
+  Selects the proper TBT Root port to assign resources
+  based on the user input value
+
+  @param[in]  SetupData          Pointer to Setup data
+
+  @retval     TbtSelectorChosen  Rootport number.
+**/
+VOID
+GetRootporttoSetResourcesforTbt (
+  IN UINTN                              RpIndex,
+  OUT UINT8                             *RsvdExtraBusNum,
+  OUT UINT16                            *RsvdPcieMegaMem,
+  OUT UINT8                             *PcieMemAddrRngMax,
+  OUT UINT16                            *RsvdPciePMegaMem,
+  OUT UINT8                             *PciePMemAddrRngMax,
+  OUT BOOLEAN                           *SetResourceforTbt
+  )
+{
+  UINTN TbtRpNumber;
+  TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber);
+
+    if (RpIndex == (TbtRpNumber - 1)) {
+        *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
+        *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd);
+        *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
+        *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd);
+        *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
+        *SetResourceforTbt = TRUE;
+      }
+      else {
+        *SetResourceforTbt = FALSE;
+      }
+  }
+
+/**
+  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
+  @param[in]  TimeOut                   Time out with 100 ms garnularity
+  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to Clear/Set)
+  @param[out] *Tbt2PcieValue Function   Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion(
+  IN  UINT64   CommandOffsetAddress,
+  IN  UINT32   TimeOut,
+  IN  BOOLEAN  Tbt2PcieDone,
+  OUT UINT32   *Tbt2PcieValue
+  )
+{
+  BOOLEAN ReturnFlag;
+  UINT32  Tbt2PcieCheck;
+
+  ReturnFlag = FALSE;
+  while (TimeOut-- > 0) {
+    *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress);
+
+    if (0xFFFFFFFF == *Tbt2PcieValue ) {
+      //
+      // Device is not here return now
+      //
+      ReturnFlag     = FALSE;
+      break;
+    }
+
+    if(Tbt2PcieDone) {
+      Tbt2PcieCheck  =  *Tbt2PcieValue & TBT2PCIE_DON_R;
+    } else {
+      Tbt2PcieCheck  = !(*Tbt2PcieValue & TBT2PCIE_DON_R);
+    }
+
+    if (Tbt2PcieCheck) {
+      ReturnFlag     = TRUE;
+      break;
+    }
+
+    MicroSecondDelay(TBT_MAIL_BOX_DELAY);
+  }
+  return ReturnFlag;
+}
+/**
+  Get Security Level.
+  @param[in]  Bus       Bus number Host Router (DTBT)
+  @param[in]  Device    Device number for Host Router (DTBT)
+  @param[in]  Function  Function number for  Host Router (DTBT)
+  @param[in]  Command   Command for  Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  )
+{
+  UINT64       Pcie2Tbt;
+  UINT64       Tbt2Pcie;
+  UINT32       RegisterValue;
+  UINT8        ReturnFlag;
+
+  ReturnFlag           = 0xFF;
+
+  DEBUG ((DEBUG_INFO, "GetSecLevel() \n"));
+
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+  PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+  if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue)) {
+    ReturnFlag     = (UINT8) (0xFF & (RegisterValue >> 8));
+  }
+
+  PciSegmentWrite32 (Pcie2Tbt, 0);
+
+  InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+  DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag));
+
+  return ReturnFlag;
+}
+
+/**
+  Set Security Level.
+  @param[in]  Data      Security State
+  @param[in]  Bus       Bus number for Host Router (DTBT)
+  @param[in]  Device    Device number for Host Router (DTBT)
+  @param[in]  Function  Function number for Host Router (DTBT)
+  @param[in]  Command   Command for  Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+  IN    UINT8                   Data,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  )
+{
+  UINT64       Pcie2Tbt;
+  UINT64       Tbt2Pcie;
+  UINT32       RegisterValue;
+  BOOLEAN      ReturnFlag;
+
+  ReturnFlag   = FALSE;
+
+  DEBUG ((DEBUG_INFO, "SetSecLevel() \n"));
+
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+  PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B);
+
+  ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+  DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue));
+  PciSegmentWrite32 (Pcie2Tbt, 0);
+
+  InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+  DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag));
+  return ReturnFlag;
+}
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in]  GpioNumber
+@param[in]  Value
+**/
+VOID
+ForceDtbtPower(
+  IN  UINT8          GpioAccessType,
+  IN  UINT8          Expander,
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+)
+{
+  if (GpioAccessType == 0x01) {
+    // PCH
+    GpioSetOutputValue (GpioNumber, (UINT32)Value);
+  } else if (GpioAccessType == 0x02) {
+    // IoExpander {TCA6424A}
+    GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value);
+  }
+}
+
+/**
+Execute TBT Mail Box Command
+
+@param[in]  Command   TBT Command
+@param[in]  Bus       Bus number for  Host Router (DTBT)
+@param[in]  Device    Device number for  Host Router (DTBT)
+@param[in]  Function  Function number for  Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+   IN    UINT8                   Command,
+   IN    UINT8                   Bus,
+   IN    UINT8                   Device,
+   IN    UINT8                   Function,
+   IN    UINT32                  Timeout
+)
+{
+   UINT64      Pcie2Tbt;
+   UINT64      Tbt2Pcie;
+   UINT32      RegisterValue;
+   BOOLEAN     ReturnFlag;
+
+   GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+   GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+   PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+   ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+   PciSegmentWrite32(Pcie2Tbt, 0);
+
+   return ReturnFlag;
+}
+/**
+  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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 If Invalid Root Port Number or TYPE is Passed
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun (
+  IN  BOOLEAN Type,
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFunc
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 TbtRpDev;
+  UINTN                 TbtRpFunc;
+
+  Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if valid input found.
+  //
+  // PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be
+  // with device number 0x1 and Function number 0,1 and 2 respectively.
+  //
+  if (Type == DTBT_TYPE_PEG)
+  {
+    //
+    //  PEG Rootport
+    //
+    if (RpNumber <= 2) {
+      *RpDev  =   0x01;
+      *RpFunc =   RpNumber;
+      Status  =   EFI_SUCCESS;
+    }
+  }
+  if (Type == DTBT_TYPE_PCH)
+  {
+    //
+    //  PCH Rootport
+    //
+    if (RpNumber <= 23) {
+      Status  = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc);
+      *RpDev  = TbtRpDev;
+      *RpFunc = TbtRpFunc;
+    }
+  }
+
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+BOOLEAN
+IsTbtHostRouter (
+  IN    UINT16  DeviceID
+  )
+{
+  switch (DeviceID) {
+  case AR_HR_2C:
+  case AR_HR_4C:
+  case AR_HR_LP:
+  case AR_HR_C0_2C:
+  case AR_HR_C0_4C:
+  case TR_HR_2C:
+  case TR_HR_4C:
+    return TRUE;
+  }
+
+  return FALSE;
+} // IsTbtHostRouter
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
new file mode 100644
index 0000000000..ffd8416660
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
@@ -0,0 +1,206 @@
+/** @file
+  This file is PeiTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/PeiServicesLib.h>
+#include <Library/GpioLib.h>
+#include <PiPei.h>
+#include <PeiTbtPolicyLibrary.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Base.h>
+#include <GpioConfig.h>
+
+/**
+  Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicy (
+  VOID
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *VariableServices;
+  PEI_TBT_POLICY                   *PeiTbtConfig;
+
+  PeiTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiTbtPolicy \n"));
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,
+             0,
+             NULL,
+             (VOID **) &VariableServices
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update DTBT Policy
+  //
+  PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn = PcdGet8 (PcdDTbtControllerEn);
+  if (PcdGet8 (PcdDTbtControllerType) == TYPE_PEG)
+  {
+    PeiTbtConfig-> DTbtControllerConfig.Type = (UINT8) TYPE_PEG;
+    PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = 1; // PEG RP 1 (Function no. 0)
+  }
+  else {
+    PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = PcdGet8 (PcdDTbtPcieRpNumber);
+    PeiTbtConfig-> DTbtControllerConfig.Type = PcdGet8 (PcdDTbtControllerType);
+  }
+  PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = (GPIO_PAD) PcdGet32 (PcdDTbtCioPlugEventGpioPad);
+  if (GpioCheckFor2Tier(PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad)) {
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 0;
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+  }
+  else {
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 1;
+    //
+    // Update Signature based on platform GPIO.
+    //
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+  }
+  PeiTbtConfig->DTbtCommonConfig.TbtBootOn = PcdGet8 (PcdDTbtBootOn);
+  PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = PcdGet8 (PcdDTbtUsbOn);
+  PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = PcdGet8 (PcdDTbtGpio3ForcePwr);
+  PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = PcdGet16 (PcdDTbtGpio3ForcePwrDly);
+
+  return;
+}
+
+/**
+  Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                       Status;
+  PEI_TBT_POLICY                   *PeiTbtConfig;
+
+  PeiTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+  DEBUG ((DEBUG_INFO, "TbtPrintPolicyConfig Start\n"));
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Print DTBT Policy
+  //
+  DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", PEI_TBT_POLICY_REVISION));
+  DEBUG ((DEBUG_INFO, "------------------------ PEI_TBT_CONFIG  -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", PEI_TBT_POLICY_REVISION));
+
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.DTbtControllerEn = %x\n", PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.Type = %x\n", PeiTbtConfig-> DTbtControllerConfig.Type));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRpNumber = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting));
+
+
+  //
+  // Print DTBT Common Policy
+  //
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtBootOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtBootOn));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtUsbOn));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration = %x\n", PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.PcieRstSupport = %x\n", PeiTbtConfig->DTbtCommonConfig.PcieRstSupport));
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+/**
+  Install Tbt Policy
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_PEI_PPI_DESCRIPTOR        *PeiTbtPolicyPpiDesc;
+  PEI_TBT_POLICY                *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "Install PEI TBT Policy\n"));
+
+  PeiTbtConfig = NULL;
+
+  //
+  // Allocate memory for PeiTbtPolicyPpiDesc
+  //
+  PeiTbtPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  ASSERT (PeiTbtPolicyPpiDesc != NULL);
+  if (PeiTbtPolicyPpiDesc == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Allocate memory and initialize all default to zero for PeiTbtPolicy
+  //
+  PeiTbtConfig = (PEI_TBT_POLICY *) AllocateZeroPool (sizeof (PEI_TBT_POLICY));
+  ASSERT (PeiTbtConfig != NULL);
+  if (PeiTbtConfig == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize PPI
+  //
+  PeiTbtPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  PeiTbtPolicyPpiDesc->Guid = &gPeiTbtPolicyPpiGuid;
+  PeiTbtPolicyPpiDesc->Ppi = PeiTbtConfig;
+
+  Status = PeiServicesInstallPpi (PeiTbtPolicyPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install PEI TBT Policy failed\n"));
+  }
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
new file mode 100644
index 0000000000..f33ddebdb3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
@@ -0,0 +1,567 @@
+/** @file
+  Thunderbolt(TM) Pei Library
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GpioExpanderLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+#include <Base.h>
+#include <Library/TbtCommonLib.h>
+#include <TbtBoardInfo.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Library/PchPmcLib.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+
+/**
+Is host router (For dTBT) or End Point (For iTBT) present before sleep
+
+@param[in] ControllerType - DTBT_CONTROLLER or ITBT_CONTROLLER
+@param[in] Controller     - Controller begin offset of CMOS
+
+@Retval     TRUE      There is a TBT HostRouter presented before sleep
+@Retval     FALSE     There is no TBT HostRouter presented before sleep
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN  UINT8        ControllerType,
+IN  UINT8        Controller
+)
+{
+  UINT8 SavedState;
+
+  SavedState = (UINT8)GetTbtHostRouterStatus();
+  if (ControllerType == DTBT_CONTROLLER){
+    return ((SavedState & (DTBT_SAVE_STATE_OFFSET << Controller)) == (DTBT_SAVE_STATE_OFFSET << Controller));
+  } else {
+    if (ControllerType == ITBT_CONTROLLER) {
+      return ((SavedState & (ITBT_SAVE_STATE_OFFSET << Controller)) == (ITBT_SAVE_STATE_OFFSET << Controller));
+    }
+  }
+  return 0;
+}
+**/
+
+/**
+Execute TBT PCIE2TBT_SX_EXIT_TBT_CONNECTED Mail Box Command for S4 mode with PreBootAclEnable
+
+@param[in]  Bus       Bus number for Host Router (DTBT)
+@param[in]  Device    Device number for Host Router (DTBT)
+@param[in]  Function  Function number for Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(
+   IN    UINT8                   Bus,
+   IN    UINT8                   Device,
+   IN    UINT8                   Function,
+   IN    UINT32                  Timeout
+)
+{
+  UINT64      Pcie2Tbt;
+  UINT64      Tbt2Pcie;
+  UINT32      RegisterValue;
+  BOOLEAN     ReturnFlag;
+  UINT32      Command;
+
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+// If PreBootAcl is Enable, we need to enable DATA bit while sending SX EXIT MAIL BOX Command
+  Command = (1 << 8) | PCIE2TBT_SX_EXIT_TBT_CONNECTED;
+  PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+  ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+  PciSegmentWrite32(Pcie2Tbt, 0);
+
+  return ReturnFlag;
+}
+
+/**
+Set the Sleep Mode if the HR is up.
+@param[in]  Bus       Bus number for Host Router (DTBT)
+@param[in]  Device    Device number for Host Router (DTBT)
+@param[in]  Function  Function number for Host Router (DTBT)
+**/
+VOID
+TbtSetSxMode(
+IN    UINT8                   Bus,
+IN    UINT8                   Device,
+IN    UINT8                   Function,
+IN    UINT8                   TbtBootOn
+)
+{
+  UINT64                          TbtUsDevId;
+  UINT64                          Tbt2Pcie;
+  UINT32                          RegVal;
+  UINT32                          MaxLoopCount;
+  UINTN                           Delay;
+  UINT8                           RetCode;
+  EFI_BOOT_MODE                   BootMode;
+  EFI_STATUS                      Status;
+
+  TbtUsDevId = PCI_SEGMENT_LIB_ADDRESS(0, Bus, Device, Function, 0);
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+
+  MaxLoopCount = TBT_5S_TIMEOUT;  // Wait 5 sec
+  Delay = 100 * 1000;
+  RetCode = 0x62;
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  if ((BootMode == BOOT_ON_S4_RESUME) && (TbtBootOn == 2)) {
+    MaxLoopCount = TBT_3S_TIMEOUT;
+    if (!TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(Bus, Device, Function, MaxLoopCount)) {
+      //
+      // Nothing to wait, HR is not responsive
+      //
+      return;
+    }
+  }
+  else {
+    if (!TbtSetPcie2TbtCommand(PCIE2TBT_SX_EXIT_TBT_CONNECTED, Bus, Device, Function, MaxLoopCount)) {
+      //
+      // Nothing to wait, HR is not responsive
+      //
+      return;
+    }
+  }
+
+  DEBUG((DEBUG_INFO, "Wait for Dev ID != 0xFF\n"));
+
+  while (MaxLoopCount-- > 0) {
+    //
+    // Check what HR still here
+    //
+    RegVal = PciSegmentRead32(Tbt2Pcie);
+    if (0xFFFFFFFF == RegVal) {
+      RetCode = 0x6F;
+      break;
+    }
+    //
+    // Check completion of TBT link
+    //
+    RegVal = PciSegmentRead32(TbtUsDevId);
+    if (0xFFFFFFFF != RegVal) {
+      RetCode = 0x61;
+      break;
+    }
+
+    MicroSecondDelay(Delay);
+  }
+
+  DEBUG((DEBUG_INFO, "Return code = 0x%x\n", RetCode));
+}
+/**
+  set tPCH25 Timing to 10 ms for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  DEBUG ((DEBUG_INFO, "DTbtSetTPch25Timing call Inside\n"));
+  UINT32                PchPwrmBase;
+
+  //
+  //During boot, reboot and wake  tPCH25 Timing should be set to 10 ms
+  //
+  MmioOr32 (
+    (UINTN) (PchPwrmBase + R_PCH_PWRM_CFG),
+    (BIT0 | BIT1)
+    );
+
+  DEBUG((DEBUG_INFO, "DTbtSetTPch25Timing call Return\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Do ForcePower for DTBT Controller
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+
+  DEBUG ((DEBUG_INFO, "DTbtForcePower call Inside\n"));
+
+      if (PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr) {
+        DEBUG((DEBUG_INFO, "ForcePwrGpio.GpioPad = %x \n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+        ForceDtbtPower(PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioAccessType,PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.Expander, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel);
+        DEBUG((DEBUG_INFO, "ForceDtbtPower asserted \n"));
+        MicroSecondDelay(PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly * 1000);
+        DEBUG((DEBUG_INFO, "Delay after ForceDtbtPower = 0x%x ms \n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+      }
+
+  DEBUG ((DEBUG_INFO, "DTbtForcePower call Return\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear VGA Registers for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  UINTN      RpDev;
+  UINTN      RpFunc;
+  EFI_STATUS Status;
+  UINT64     BridngeBaseAddress;
+  UINT16     Data16;
+
+  DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Inside\n"));
+
+  Status = EFI_SUCCESS;
+
+  Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+  ASSERT_EFI_ERROR(Status);
+  //
+  // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+  // Host router resides should be cleaned
+  //
+
+  BridngeBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0, (UINT32)RpDev, (UINT32)RpFunc, 0);
+  Data16 = PciSegmentRead16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET);
+  Data16 &= (~(EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16));
+  PciSegmentWrite16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET, Data16);
+
+  DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Return\n"));
+  return Status;
+}
+
+/**
+  Exectue Mail box command "Boot On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn(
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  EFI_STATUS Status;
+  UINT32     OrgBusNumberConfiguration;
+  UINTN      RpDev;
+  UINTN      RpFunc;
+
+  DEBUG((DEBUG_INFO, "DTbtBootOn call Inside\n"));
+
+  Status = EFI_SUCCESS;
+
+      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+      ASSERT_EFI_ERROR(Status);
+      OrgBusNumberConfiguration = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+      //
+      // Set Sec/Sub buses to 0xF0
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+      //
+      //When Thunderbolt(TM) boot [TbtBootOn] is enabled in bios setup we need to do the below:
+      //Bios should send "Boot On" message through PCIE2TBT register
+      //The Boot On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+      //once the Boot On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+      //next step from BIOS is enumeration using SMI
+      //
+
+      if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+        //
+        // Exectue Mail box command "Boot On / Pre-Boot ACL"
+        //
+        //Command may be executed only during boot/reboot and not during Sx exit flow
+        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 1) {
+          if (!TbtSetPcie2TbtCommand(PCIE2TBT_BOOT_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+            //
+            // Nothing to wait, HR is not responsive
+            //
+            DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Boot On message sent failed \n"));
+          }
+        }
+        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2) {
+          if (!TbtSetPcie2TbtCommand(PCIE2TBT_PREBOOTACL, 0xF0, 0, 0, TBT_3S_TIMEOUT)) {
+            //
+            // Nothing to wait, HR is not responsive
+            //
+            DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Pre-Boot ACL message sent failed \n"));
+          }
+        }
+      }
+      //
+      // Reset Sec/Sub buses to original value
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+  DEBUG((DEBUG_INFO, "DTbtBootOn call Return\n"));
+  return Status;
+}
+
+/**
+  Exectue Mail box command "USB On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn(
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  EFI_STATUS                      Status;
+  UINTN                           RpDev;
+  UINTN                           RpFunc;
+  UINT32                          OrgBusNumberConfiguration;
+  UINT64                          TbtBaseAddress;
+  UINT32                          MaxWaitIter;
+  UINT32                          RegVal;
+  EFI_BOOT_MODE                   BootMode;
+
+  DEBUG((DEBUG_INFO, "DTbtUsbOn call Inside\n"));
+
+  Status = EFI_SUCCESS;
+
+      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+      ASSERT_EFI_ERROR(Status);
+      OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+      //
+      // Set Sec/Sub buses to 0xF0
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+      //
+      //When Thunderbolt(TM) Usb boot [TbtUsbOn] is enabled in bios setup we need to do the below:
+      //Bios should send "Usb On" message through PCIE2TBT register
+      //The Usb On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+      //once the Usb On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+      //next step from BIOS is enumeration using SMI
+      //
+      if (PeiTbtConfig->DTbtCommonConfig.TbtUsbOn) {
+        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+          MaxWaitIter = 50;   // Wait 5 sec
+          TbtBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0xF0, 0, 0, 0);
+          //
+          // Driver clears the PCIe2TBT Valid bit to support two consicutive mailbox commands
+          //
+          PciSegmentWrite32(TbtBaseAddress + PCIE2TBT_DTBT_R, 0);
+          DEBUG((DEBUG_INFO, "TbtBaseAddress + PCIE2TBT_DTBT_R = 0x%lx \n", TbtBaseAddress + PCIE2TBT_DTBT_R));
+          while (MaxWaitIter-- > 0) {
+            RegVal = PciSegmentRead32(TbtBaseAddress + TBT2PCIE_DTBT_R);
+            if (0xFFFFFFFF == RegVal) {
+              //
+              // Device is not here return now
+              //
+              DEBUG((DEBUG_INFO, "TBT device is not present \n"));
+              break;
+            }
+
+            if (!(RegVal & TBT2PCIE_DON_R)) {
+              break;
+            }
+            MicroSecondDelay(100 * 1000);
+          }
+        }
+
+        Status = PeiServicesGetBootMode(&BootMode);
+        ASSERT_EFI_ERROR(Status);
+
+        //
+        // Exectue Mail box command "Usb On"
+        //
+        //Command may be executed only during boot/reboot and not during S3 exit flow
+        //In case of S4 Exit send USB ON cmd only if Host Router was inactive/not present during S4 entry
+        if ((BootMode == BOOT_ON_S4_RESUME) ) {
+          // USB_ON cmd not required
+        } else {
+          if (!TbtSetPcie2TbtCommand(PCIE2TBT_USB_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+            //
+            // Nothing to wait, HR is not responsive
+            //
+            DEBUG((DEBUG_INFO, "<TbtPei> TbtBootSupport - Usb On message sent failed \n"));
+          }
+        }
+      }
+      //
+      // Reset Sec/Sub buses to original value
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+  DEBUG((DEBUG_INFO, "DTbtUsbOn call return\n"));
+  return Status;
+}
+
+/**
+  Exectue Mail box command "Sx Exit".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow(
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  EFI_STATUS                      Status;
+  UINT32                          OrgBusNumberConfiguration;
+  UINTN                           RpDev;
+  UINTN                           RpFunc;
+  UINT32                          Count;
+
+  DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Inside\n"));
+
+  Status = EFI_SUCCESS;
+  Count = 0;
+
+      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+      ASSERT_EFI_ERROR(Status);
+      OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+      //
+      // Set Sec/Sub buses to 0xF0
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+      if ( (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2)) {
+        //
+        // WA: When system with TBT 3.1 device, resume SX system need to wait device ready. In document that maximum time out should be 500ms.
+        //
+        while (PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS(0, 0xf0, 0x0, 0x0, 0x08)) == 0xffffffff) { //End Device will be with Device Number 0x0, Function Number 0x0.
+          MicroSecondDelay(STALL_ONE_MICRO_SECOND * 1000); // 1000usec
+          Count++;
+          if (Count > 10000) { //Allowing Max Delay of 10 sec for CFL-S board.
+          break;
+          }
+        }
+
+        //
+        // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+        // attached devices), BIOS should:
+        // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+        // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+        // 3. Continue regular wake flow.
+        //
+        //
+        // Exectue Mail box command and perform "wait for fast link bring-up" loop
+        //
+        TbtSetSxMode(0xF0, 0, 0, PeiTbtConfig->DTbtCommonConfig.TbtBootOn);
+      }
+      //
+      // Reset Sec/Sub buses to original value
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+  DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Return\n"));
+  return Status;
+}
+
+
+/**
+  Initialize Thunderbolt(TM)
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+EFI_STATUS
+EFIAPI
+TbtInit (
+  VOID
+  )
+{
+  EFI_STATUS            Status;
+  PEI_TBT_POLICY             *PeiTbtConfig;
+
+  //
+  // Get the TBT Policy
+  //
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Exectue Mail box command "Boot On"
+  //
+  Status = DTbtBootOn (PeiTbtConfig);
+  //
+  // Exectue Mail box command "Usb On"
+  //
+  Status = DTbtUsbOn (PeiTbtConfig);
+  //
+  //During boot, reboot and wake  (bits [1:0]) of PCH PM_CFG register should be
+  //set to 11b - 10 ms (default value is 0b - 10 us)
+  //
+  Status = DTbtSetTPch25Timing (PeiTbtConfig);
+  //
+  // Configure Tbt Force Power
+  //
+  Status = DTbtForcePower (PeiTbtConfig);
+  //
+  // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+  // Host router resides should be cleaned
+  //
+  Status = DTbtClearVgaRegisters (PeiTbtConfig);
+  //
+  // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+  // attached devices), BIOS should:
+  // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+  // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+  // 3. Continue regular wake flow.
+  //
+  Status = DTbtSxExitFlow (PeiTbtConfig);
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
new file mode 100644
index 0000000000..f38901f2ae
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
@@ -0,0 +1,461 @@
+/** @file
+  Implementation of Fsp CPU Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <Ppi/SecPlatformInformation2.h>
+
+#include <CpuAccess.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PcdLib.h>
+#include <FspEas.h>
+
+/**
+  Performs FSP CPU PEI Policy initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                      Status;
+  SI_PREMEM_POLICY_PPI            *SiPreMemPolicyPpi;
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverClockingPreMemConfig;
+  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy Pre-Mem Start\n"));
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  SiPreMemPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverClockingPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  ///
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy Pre-Mem End\n"));
+
+  //
+  // Overclocking PreMem policies
+  //
+  FspmUpd->FspmConfig.OcSupport               = (UINT8) CpuOverClockingPreMemConfig->OcSupport;
+  FspmUpd->FspmConfig.OcLock                  = (UINT8) CpuOverClockingPreMemConfig->OcLock;
+  FspmUpd->FspmConfig.CoreMaxOcRatio          = (UINT8) CpuOverClockingPreMemConfig->CoreMaxOcRatio;
+  FspmUpd->FspmConfig.CoreVoltageMode         = (UINT8) CpuOverClockingPreMemConfig->CoreVoltageMode;
+  FspmUpd->FspmConfig.CoreVoltageOverride     = (UINT16) CpuOverClockingPreMemConfig->CoreVoltageOverride;
+  FspmUpd->FspmConfig.CoreVoltageAdaptive     = (UINT16) CpuOverClockingPreMemConfig->CoreVoltageAdaptive;
+  FspmUpd->FspmConfig.CoreVoltageOffset       = (UINT16) CpuOverClockingPreMemConfig->CoreVoltageOffset;
+  FspmUpd->FspmConfig.CorePllVoltageOffset    = (UINT8) CpuOverClockingPreMemConfig->CorePllVoltageOffset;
+  FspmUpd->FspmConfig.RingMaxOcRatio          = (UINT8) CpuOverClockingPreMemConfig->RingMaxOcRatio;
+  FspmUpd->FspmConfig.RingVoltageOverride     = (UINT16) CpuOverClockingPreMemConfig->RingVoltageOverride;
+  FspmUpd->FspmConfig.RingVoltageAdaptive     = (UINT16) CpuOverClockingPreMemConfig->RingVoltageAdaptive;
+  FspmUpd->FspmConfig.RingVoltageOffset       = (UINT16) CpuOverClockingPreMemConfig->RingVoltageOffset;
+  FspmUpd->FspmConfig.RingPllVoltageOffset    = (UINT8) CpuOverClockingPreMemConfig->RingPllVoltageOffset;
+  FspmUpd->FspmConfig.GtPllVoltageOffset      = (UINT8) CpuOverClockingPreMemConfig->GtPllVoltageOffset;
+  FspmUpd->FspmConfig.RingPllVoltageOffset    = (UINT8) CpuOverClockingPreMemConfig->RingPllVoltageOffset;
+  FspmUpd->FspmConfig.SaPllVoltageOffset      = (UINT8) CpuOverClockingPreMemConfig->SaPllVoltageOffset;
+  FspmUpd->FspmConfig.McPllVoltageOffset      = (UINT8) CpuOverClockingPreMemConfig->McPllVoltageOffset;
+  FspmUpd->FspmConfig.RingDownBin             = (UINT8) CpuOverClockingPreMemConfig->RingDownBin;
+  FspmUpd->FspmConfig.RingVoltageMode         = (UINT8) CpuOverClockingPreMemConfig->RingVoltageMode;
+  FspmUpd->FspmConfig.Avx2RatioOffset         = (UINT8) CpuOverClockingPreMemConfig->Avx2RatioOffset;
+  FspmUpd->FspmConfig.Avx3RatioOffset         = (UINT8) CpuOverClockingPreMemConfig->Avx3RatioOffset;
+  FspmUpd->FspmConfig.BclkAdaptiveVoltage     = (UINT8) CpuOverClockingPreMemConfig->BclkAdaptiveVoltage;
+  FspmUpd->FspmConfig.TjMaxOffset             = (UINT8) CpuOverClockingPreMemConfig->TjMaxOffset;
+  FspmUpd->FspmConfig.TvbRatioClipping        = (UINT8) CpuOverClockingPreMemConfig->TvbRatioClipping;
+  FspmUpd->FspmConfig.TvbVoltageOptimization  = (UINT8) CpuOverClockingPreMemConfig->TvbVoltageOptimization;
+
+  //
+  //  Cpu Config Lib policies
+  //
+  FspmUpd->FspmConfig.HyperThreading            = (UINT8) CpuConfigLibPreMemConfig->HyperThreading;
+  FspmUpd->FspmConfig.BootFrequency             = (UINT8) CpuConfigLibPreMemConfig->BootFrequency;
+  FspmUpd->FspmConfig.ActiveCoreCount           = (UINT8) CpuConfigLibPreMemConfig->ActiveCoreCount;
+  FspmUpd->FspmConfig.JtagC10PowerGateDisable   = (UINT8) CpuConfigLibPreMemConfig->JtagC10PowerGateDisable;
+  FspmUpd->FspmConfig.FClkFrequency             = (UINT8) CpuConfigLibPreMemConfig->FClkFrequency;
+  FspmUpd->FspmConfig.BistOnReset               = (UINT8) CpuConfigLibPreMemConfig->BistOnReset;
+  FspmUpd->FspmConfig.VmxEnable                 = (UINT8) CpuConfigLibPreMemConfig->VmxEnable;
+  FspmUpd->FspmConfig.CpuRatio                  = (UINT8) CpuConfigLibPreMemConfig->CpuRatio;
+  FspmUpd->FspmConfig.PeciSxReset               = (UINT8) CpuConfigLibPreMemConfig->PeciSxReset;
+  FspmUpd->FspmConfig.PeciC10Reset              = (UINT8) CpuConfigLibPreMemConfig->PeciC10Reset;
+  FspmUpd->FspmConfig.SkipMpInit                = (UINT8) CpuConfigLibPreMemConfig->SkipMpInit;
+  FspmUpd->FspmConfig.DpSscMarginEnable         = (UINT8) CpuConfigLibPreMemConfig->DpSscMarginEnable;
+
+  //
+  // DisableMtrrProgram <1> Disable Mtrrs program. <0> Program Mtrrs in FSP
+  //
+  FspmUpd->FspmConfig.DisableMtrrProgram        = (UINT8) 0;
+
+  return EFI_SUCCESS;
+}
+
+/**
+ This routine is used to get Sec Platform Information Record2 Pointer.
+
+ @param[in] PeiServices    Pointer to the PEI services table
+
+ @retval GetSecPlatformInformation2 - The pointer of Sec Platform Information Record2 Pointer.
+ **/
+
+EFI_SEC_PLATFORM_INFORMATION_RECORD2 * GetSecPlatformInformation2(
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  EFI_SEC_PLATFORM_INFORMATION2_PPI    *SecPlatformInformation2Ppi;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2 = NULL;
+  UINT64                               InformationSize;
+  EFI_STATUS Status;
+
+  //
+  // Get BIST information from Sec Platform Information2 Ppi firstly
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiSecPlatformInformation2PpiGuid,   // GUID
+             0,                                     // Instance
+             NULL,                                  // EFI_PEI_PPI_DESCRIPTOR
+             (VOID ** ) &SecPlatformInformation2Ppi // PPI
+             );
+
+  DEBUG((DEBUG_INFO, "LocatePpi SecPlatformInformationPpi2 Status - %x\n", Status));
+  if (EFI_ERROR(Status)) {
+    return NULL;
+  }
+
+  InformationSize = 0;
+
+  Status = SecPlatformInformation2Ppi->PlatformInformation2 (
+                                         (CONST EFI_PEI_SERVICES  **) PeiServices,
+                                         &InformationSize,
+                                         SecPlatformInformation2
+                                         );
+
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return NULL;
+  }
+
+  SecPlatformInformation2 = AllocatePool((UINTN)InformationSize);
+  ASSERT (SecPlatformInformation2 != NULL);
+  if (SecPlatformInformation2 == NULL) {
+    return NULL;
+  }
+
+  //
+  // Retrieve BIST data from SecPlatform2
+  //
+  Status = SecPlatformInformation2Ppi->PlatformInformation2 (
+                                         PeiServices,
+                                         &InformationSize,
+                                         SecPlatformInformation2
+                                         );
+  DEBUG((DEBUG_INFO, "SecPlatformInformation2Ppi->PlatformInformation2 Status - %x\n", Status));
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  return SecPlatformInformation2;
+}
+
+/**
+ This routine is used to get Sec Platform Information Record Pointer.
+
+ @param[in] PeiServices    Pointer to the PEI services table
+
+ @retval GetSecPlatformInformation2 - The pointer of Sec Platform Information Record Pointer.
+ **/
+EFI_SEC_PLATFORM_INFORMATION_RECORD2 * GetSecPlatformInformationInfoInFormat2(
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  EFI_SEC_PLATFORM_INFORMATION_PPI     *SecPlatformInformationPpi;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD  *SecPlatformInformation = NULL;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
+  UINT64                               InformationSize;
+  EFI_STATUS                           Status;
+
+  //
+  // Get BIST information from Sec Platform Information
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiSecPlatformInformationPpiGuid,    // GUID
+             0,                                     // Instance
+             NULL,                                  // EFI_PEI_PPI_DESCRIPTOR
+             (VOID ** ) &SecPlatformInformationPpi  // PPI
+             );
+
+  DEBUG((DEBUG_INFO, "LocatePpi SecPlatformInformationPpi Status - %x\n", Status));
+  if (EFI_ERROR(Status)) {
+    return NULL;
+  }
+
+  InformationSize = 0;
+  Status = SecPlatformInformationPpi->PlatformInformation (
+                                        (CONST EFI_PEI_SERVICES  **) PeiServices,
+                                        &InformationSize,
+                                        SecPlatformInformation
+                                        );
+
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return NULL;
+  }
+
+  SecPlatformInformation = AllocatePool((UINTN)InformationSize);
+  ASSERT (SecPlatformInformation != NULL);
+  if (SecPlatformInformation == NULL) {
+    return NULL;
+  }
+
+  //
+  // Retrieve BIST data from SecPlatform
+  //
+  Status = SecPlatformInformationPpi->PlatformInformation (
+                                        PeiServices,
+                                        &InformationSize,
+                                        SecPlatformInformation
+                                        );
+  DEBUG((DEBUG_INFO, "FSP  SecPlatformInformation2Ppi->PlatformInformation Status - %x\n", Status));
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  SecPlatformInformation2 = AllocatePool(sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2));
+  ASSERT (SecPlatformInformation2 != NULL);
+  if (SecPlatformInformation2 == NULL) {
+    return NULL;
+  }
+
+  SecPlatformInformation2->NumberOfCpus = 1;
+  SecPlatformInformation2->CpuInstance[0].CpuLocation = 0;
+  SecPlatformInformation2->CpuInstance[0].InfoRecord.x64HealthFlags.Uint32 = SecPlatformInformation->x64HealthFlags.Uint32;
+
+  FreePool(SecPlatformInformation);
+
+  return SecPlatformInformation2;
+}
+
+
+/**
+ Performs FSP CPU PEI Policy post memory initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                           Status;
+  SI_POLICY_PPI                        *SiPolicyPpi;
+  CPU_CONFIG                           *CpuConfig;
+  CPU_POWER_MGMT_BASIC_CONFIG          *CpuPowerMgmtBasicConfig;
+  CPU_POWER_MGMT_CUSTOM_CONFIG         *CpuPowerMgmtCustomConfig;
+  CPU_TEST_CONFIG                      *CpuTestConfig;
+  CPU_POWER_MGMT_TEST_CONFIG           *CpuPowerMgmtTestConfig;
+  UINTN                                Index;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
+  EFI_PEI_SERVICES                     **PeiServices;
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy\n"));
+  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
+  //
+  // Locate gSiPolicyPpiGuid
+  //
+  SiPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *) &CpuPowerMgmtCustomConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID *) &CpuTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
+  ASSERT_EFI_ERROR (Status);
+  ///
+  ///Production RC Policies
+  ///
+
+  FspsUpd->FspsConfig.AesEnable                 = (UINT8) CpuConfig->AesEnable;
+  FspsUpd->FspsConfig.DebugInterfaceEnable      = (UINT8) CpuConfig->DebugInterfaceEnable;
+
+  FspsUpd->FspsConfig.TurboMode                 = (UINT8) CpuPowerMgmtBasicConfig->TurboMode;
+
+  ///
+  /// Test RC Policies
+  ///
+  FspsUpd->FspsTestConfig.MlcStreamerPrefetcher      = (UINT8) CpuTestConfig->MlcStreamerPrefetcher;
+  FspsUpd->FspsTestConfig.MlcSpatialPrefetcher       = (UINT8) CpuTestConfig->MlcSpatialPrefetcher;
+  FspsUpd->FspsTestConfig.MonitorMwaitEnable         = (UINT8) CpuTestConfig->MonitorMwaitEnable;
+  FspsUpd->FspsTestConfig.DebugInterfaceLockEnable   = (UINT8) CpuTestConfig->DebugInterfaceLockEnable;
+  FspsUpd->FspsTestConfig.ApIdleManner               = PcdGet8 (PcdCpuApLoopMode);
+  FspsUpd->FspsTestConfig.ProcessorTraceOutputScheme = (UINT8) CpuTestConfig->ProcessorTraceOutputScheme;
+  FspsUpd->FspsTestConfig.ProcessorTraceEnable       = (UINT8) CpuTestConfig->ProcessorTraceEnable;
+  FspsUpd->FspsTestConfig.ProcessorTraceMemBase      = CpuTestConfig->ProcessorTraceMemBase;
+  FspsUpd->FspsTestConfig.ProcessorTraceMemLength    = (UINT32) CpuTestConfig->ProcessorTraceMemLength;
+  FspsUpd->FspsTestConfig.VoltageOptimization        = (UINT8) CpuTestConfig->VoltageOptimization;
+  FspsUpd->FspsTestConfig.ThreeStrikeCounterDisable  = (UINT8) CpuTestConfig->ThreeStrikeCounterDisable;
+  FspsUpd->FspsTestConfig.MachineCheckEnable         = (UINT8) CpuTestConfig->MachineCheckEnable;
+  FspsUpd->FspsTestConfig.CpuWakeUpTimer             = (UINT8) CpuTestConfig->CpuWakeUpTimer;
+
+  FspsUpd->FspsTestConfig.OneCoreRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->OneCoreRatioLimit;
+  FspsUpd->FspsTestConfig.TwoCoreRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->TwoCoreRatioLimit;
+  FspsUpd->FspsTestConfig.ThreeCoreRatioLimit        = (UINT8) CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit;
+  FspsUpd->FspsTestConfig.FourCoreRatioLimit         = (UINT8) CpuPowerMgmtBasicConfig->FourCoreRatioLimit;
+  FspsUpd->FspsTestConfig.FiveCoreRatioLimit         = (UINT8) CpuPowerMgmtBasicConfig->FiveCoreRatioLimit;
+  FspsUpd->FspsTestConfig.SixCoreRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->SixCoreRatioLimit;
+  FspsUpd->FspsTestConfig.SevenCoreRatioLimit        = (UINT8) CpuPowerMgmtBasicConfig->SevenCoreRatioLimit;
+  FspsUpd->FspsTestConfig.EightCoreRatioLimit        = (UINT8) CpuPowerMgmtBasicConfig->EightCoreRatioLimit;
+  FspsUpd->FspsTestConfig.Hwp                        = (UINT8) CpuPowerMgmtBasicConfig->Hwp;
+  FspsUpd->FspsTestConfig.HdcControl                 = (UINT8) CpuPowerMgmtBasicConfig->HdcControl;
+  FspsUpd->FspsTestConfig.PowerLimit1Time            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit1Time;
+  FspsUpd->FspsTestConfig.PowerLimit2                = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit2;
+  FspsUpd->FspsTestConfig.TurboPowerLimitLock        = (UINT8) CpuPowerMgmtBasicConfig->TurboPowerLimitLock;
+  FspsUpd->FspsTestConfig.PowerLimit3Time            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit3Time;
+  FspsUpd->FspsTestConfig.PowerLimit3DutyCycle       = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle;
+  FspsUpd->FspsTestConfig.PowerLimit3Lock            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit3Lock;
+  FspsUpd->FspsTestConfig.PowerLimit4Lock            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit4Lock;
+  FspsUpd->FspsTestConfig.TccActivationOffset        = (UINT8) CpuPowerMgmtBasicConfig->TccActivationOffset;
+  FspsUpd->FspsTestConfig.TccOffsetClamp             = (UINT8) CpuPowerMgmtBasicConfig->TccOffsetClamp;
+  FspsUpd->FspsTestConfig.TccOffsetLock              = (UINT8) CpuPowerMgmtBasicConfig->TccOffsetLock;
+  FspsUpd->FspsTestConfig.PowerLimit1                = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.PowerLimit2Power           = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit2Power * 125);
+  FspsUpd->FspsTestConfig.PowerLimit3                = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit3 * 125);
+  FspsUpd->FspsTestConfig.PowerLimit4                = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit4 * 125);
+  FspsUpd->FspsTestConfig.TccOffsetTimeWindowForRatl = (UINT32) CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl;
+  FspsUpd->FspsTestConfig.HwpInterruptControl        = (UINT8) CpuPowerMgmtBasicConfig->HwpInterruptControl;
+  FspsUpd->FspsTestConfig.EnableItbm                 = (UINT8) CpuPowerMgmtBasicConfig->EnableItbm;
+  FspsUpd->FspsTestConfig.EnableItbmDriver           = (UINT8) CpuPowerMgmtBasicConfig->EnableItbmDriver;
+  FspsUpd->FspsTestConfig.MinRingRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->MinRingRatioLimit;
+  FspsUpd->FspsTestConfig.MaxRingRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->MaxRingRatioLimit;
+  FspsUpd->FspsTestConfig.NumberOfEntries             = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries;
+  FspsUpd->FspsTestConfig.Custom1PowerLimit1Time      = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimit1Time;
+  FspsUpd->FspsTestConfig.Custom2PowerLimit1Time      = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimit1Time;
+  FspsUpd->FspsTestConfig.Custom3PowerLimit1Time      = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimit1Time;
+  FspsUpd->FspsTestConfig.Custom1TurboActivationRatio = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomTurboActivationRatio;
+  FspsUpd->FspsTestConfig.Custom2TurboActivationRatio = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomTurboActivationRatio;
+  FspsUpd->FspsTestConfig.Custom3TurboActivationRatio = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomTurboActivationRatio;
+  FspsUpd->FspsTestConfig.ConfigTdpLock               = (UINT8) CpuPowerMgmtCustomConfig->ConfigTdpLock;
+  FspsUpd->FspsTestConfig.ConfigTdpBios               = (UINT8) CpuPowerMgmtCustomConfig->ConfigTdpBios;
+  FspsUpd->FspsTestConfig.MaxRatio                    = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio;
+  for (Index = 0; Index < CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries; Index++) {
+    FspsUpd->FspsTestConfig.StateRatio[Index]         = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index];
+  }
+  for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+    FspsUpd->FspsTestConfig.StateRatioMax16[Index]    = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index];
+  }
+  FspsUpd->FspsTestConfig.Custom1PowerLimit1          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.Custom1PowerLimit2          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimit2 * 125);
+  FspsUpd->FspsTestConfig.Custom2PowerLimit1          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.Custom2PowerLimit2          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimit2 * 125);
+  FspsUpd->FspsTestConfig.Custom3PowerLimit1          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.Custom3PowerLimit2          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimit2 * 125);
+
+  FspsUpd->FspsTestConfig.Eist                          = (UINT8) CpuPowerMgmtTestConfig->Eist;
+  FspsUpd->FspsTestConfig.EnergyEfficientPState         = (UINT8) CpuPowerMgmtTestConfig->EnergyEfficientPState;
+  FspsUpd->FspsTestConfig.EnergyEfficientTurbo          = (UINT8) CpuPowerMgmtTestConfig->EnergyEfficientTurbo;
+  FspsUpd->FspsTestConfig.TStates                       = (UINT8) CpuPowerMgmtTestConfig->TStates;
+  FspsUpd->FspsTestConfig.BiProcHot                     = (UINT8) CpuPowerMgmtTestConfig->BiProcHot;
+  FspsUpd->FspsTestConfig.DisableProcHotOut             = (UINT8) CpuPowerMgmtTestConfig->DisableProcHotOut;
+  FspsUpd->FspsTestConfig.ProcHotResponse               = (UINT8) CpuPowerMgmtTestConfig->ProcHotResponse;
+  FspsUpd->FspsTestConfig.DisableVrThermalAlert         = (UINT8) CpuPowerMgmtTestConfig->DisableVrThermalAlert;
+  FspsUpd->FspsTestConfig.AutoThermalReporting          = (UINT8) CpuPowerMgmtTestConfig->AutoThermalReporting;
+  FspsUpd->FspsTestConfig.ThermalMonitor                = (UINT8) CpuPowerMgmtTestConfig->ThermalMonitor;
+  FspsUpd->FspsTestConfig.Cx                            = (UINT8) CpuPowerMgmtTestConfig->Cx;
+  FspsUpd->FspsTestConfig.PmgCstCfgCtrlLock             = (UINT8) CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock;
+  FspsUpd->FspsTestConfig.C1e                           = (UINT8) CpuPowerMgmtTestConfig->C1e;
+  FspsUpd->FspsTestConfig.C1StateAutoDemotion           = (UINT8) CpuPowerMgmtTestConfig->C1AutoDemotion;
+  FspsUpd->FspsTestConfig.C1StateUnDemotion             = (UINT8) CpuPowerMgmtTestConfig->C1UnDemotion;
+  FspsUpd->FspsTestConfig.C3StateAutoDemotion           = (UINT8) CpuPowerMgmtTestConfig->C3AutoDemotion;
+  FspsUpd->FspsTestConfig.C3StateUnDemotion             = (UINT8) CpuPowerMgmtTestConfig->C3UnDemotion;
+  FspsUpd->FspsTestConfig.CstateLatencyControl0TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl0Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl;
+  FspsUpd->FspsTestConfig.PkgCStateDemotion             = (UINT8) CpuPowerMgmtTestConfig->PkgCStateDemotion;
+  FspsUpd->FspsTestConfig.PkgCStateUnDemotion           = (UINT8) CpuPowerMgmtTestConfig->PkgCStateUnDemotion;
+  FspsUpd->FspsTestConfig.CStatePreWake                 = (UINT8) CpuPowerMgmtTestConfig->CStatePreWake;
+  FspsUpd->FspsTestConfig.TimedMwait                    = (UINT8) CpuPowerMgmtTestConfig->TimedMwait;
+  FspsUpd->FspsTestConfig.CstCfgCtrIoMwaitRedirection   = (UINT8) CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection;
+  FspsUpd->FspsTestConfig.PkgCStateLimit                = (UINT8) CpuPowerMgmtTestConfig->PkgCStateLimit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl1TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl2TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl3TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl4TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl5TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit;
+  FspsUpd->FspsTestConfig.PpmIrmSetting                 = (UINT8) CpuPowerMgmtTestConfig->PpmIrmSetting;
+  FspsUpd->FspsTestConfig.ProcHotLock                   = (UINT8) CpuPowerMgmtTestConfig->ProcHotLock;
+  FspsUpd->FspsTestConfig.RaceToHalt                    = (UINT8) CpuPowerMgmtTestConfig->RaceToHalt;
+  FspsUpd->FspsTestConfig.ConfigTdpLevel                = (UINT8) CpuPowerMgmtTestConfig->ConfigTdpLevel;
+  FspsUpd->FspsTestConfig.CstateLatencyControl1Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl2Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl3Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl4Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl5Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl;
+
+  //
+  // Get BIST information from Sec Platform Information
+  //
+  SecPlatformInformation2 = GetSecPlatformInformation2 (PeiServices);
+  if (SecPlatformInformation2 == NULL) {
+    SecPlatformInformation2 = GetSecPlatformInformationInfoInFormat2 (PeiServices);
+  }
+
+  ASSERT (SecPlatformInformation2 != NULL);
+
+  if (SecPlatformInformation2 != NULL) {
+    FspsUpd->FspsConfig.CpuBistData = (UINT32)SecPlatformInformation2;
+    DEBUG((DEBUG_INFO, "SecPlatformInformation NumberOfCpus - %x\n", SecPlatformInformation2->NumberOfCpus));
+    DEBUG ((DEBUG_INFO, "SecPlatformInformation BIST - %x\n", SecPlatformInformation2->CpuInstance[0].InfoRecord.x64HealthFlags.Uint32));
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c
new file mode 100644
index 0000000000..97d9842aff
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c
@@ -0,0 +1,121 @@
+/** @file
+  Implementation of Fsp Me Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <ConfigBlock/MePeiConfig.h>
+#include <Ppi/SiPolicy.h>
+
+/**
+  Performs FSP ME PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_PREMEM_POLICY_PPI      *SiPreMemPolicy;
+  ME_PEI_PREMEM_CONFIG      *MePeiPreMemConfig;
+
+  DEBUG ((DEBUG_INFO, "PeiFspMePolicyInitPreMem\n"));
+
+  //
+  // Locate gSiPreMemPolicyPpi
+  //
+  SiPreMemPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  FspmUpd->FspmConfig.HeciTimeouts                      = (UINT8)  MePeiPreMemConfig->HeciTimeouts;
+  //
+  // Test policies
+  //
+  FspmUpd->FspmTestConfig.DidInitStat                   = (UINT8) MePeiPreMemConfig->DidInitStat;
+  FspmUpd->FspmTestConfig.DisableCpuReplacedPolling     = (UINT8) MePeiPreMemConfig->DisableCpuReplacedPolling;
+  FspmUpd->FspmTestConfig.SendDidMsg                    = (UINT8) MePeiPreMemConfig->SendDidMsg;
+  FspmUpd->FspmTestConfig.DisableHeciRetry              = (UINT8) MePeiPreMemConfig->DisableHeciRetry;
+  FspmUpd->FspmTestConfig.DisableMessageCheck           = (UINT8) MePeiPreMemConfig->DisableMessageCheck;
+  FspmUpd->FspmTestConfig.SkipMbpHob                    = (UINT8) MePeiPreMemConfig->SkipMbpHob;
+
+  FspmUpd->FspmTestConfig.HeciCommunication2            = (UINT8) MePeiPreMemConfig->HeciCommunication2;
+  FspmUpd->FspmTestConfig.KtDeviceEnable                = (UINT8) MePeiPreMemConfig->KtDeviceEnable;
+
+  FspmUpd->FspmConfig.Heci1BarAddress                   = MePeiPreMemConfig->Heci1BarAddress;
+  FspmUpd->FspmConfig.Heci2BarAddress                   = MePeiPreMemConfig->Heci2BarAddress;
+  FspmUpd->FspmConfig.Heci3BarAddress                   = MePeiPreMemConfig->Heci3BarAddress;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP ME PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_POLICY_PPI             *SiPolicyPpi;
+  ME_PEI_CONFIG             *MePeiConfig;
+
+  DEBUG ((DEBUG_INFO, "PeiFspMePolicyInit \n"));
+  //
+  // Locate gSiPolicyPpiGuid
+  //
+  SiPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  FspsUpd->FspsConfig.Heci3Enabled                  = (UINT8) MePeiConfig->Heci3Enabled;
+  FspsUpd->FspsConfig.MeUnconfigOnRtcClear          = (UINT8) MePeiConfig->MeUnconfigOnRtcClear;
+
+  //
+  // Test policies
+  //
+  FspsUpd->FspsTestConfig.MctpBroadcastCycle        = (UINT8) MePeiConfig->MctpBroadcastCycle;
+  FspsUpd->FspsTestConfig.EndOfPostMessage          = (UINT8) MePeiConfig->EndOfPostMessage;
+  FspsUpd->FspsTestConfig.DisableD0I3SettingForHeci = (UINT8) MePeiConfig->DisableD0I3SettingForHeci;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c
new file mode 100644
index 0000000000..9545e3df0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c
@@ -0,0 +1,77 @@
+/** @file
+  Implementation of Fsp Misc UPD Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+
+#define STATUS_CODE_USE_RAM        BIT0
+#define STATUS_CODE_USE_ISA_SERIAL BIT1
+#define STATUS_CODE_USE_USB        BIT2
+#define STATUS_CODE_USE_USB3       BIT3
+#define STATUS_CODE_USE_SERIALIO   BIT4
+#define STATUS_CODE_USE_TRACEHUB   BIT5
+#define STATUS_CODE_CMOS_INVALID   BIT6
+#define STATUS_CODE_CMOS_VALID     BIT7
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_PEI_HOB_POINTERS              Hob;
+  DEBUG_CONFIG_DATA_HOB             *DebugConfigData;
+  UINT8                             DebugInterfaces;
+
+  FspmUpd->FspmArchUpd.StackBase = (VOID *)(UINTN)(PcdGet32(PcdTemporaryRamBase) + PcdGet32(PcdTemporaryRamSize) - (PcdGet32(PcdFspTemporaryRamSize) + PcdGet32(PcdFspReservedBufferSize)));
+  FspmUpd->FspmArchUpd.StackSize = PcdGet32(PcdFspTemporaryRamSize);
+
+  Status = PeiServicesGetBootMode (&(FspmUpd->FspmArchUpd.BootMode));
+  if (EFI_ERROR (Status)) {
+    FspmUpd->FspmArchUpd.BootMode = BOOT_WITH_FULL_CONFIGURATION;
+  }
+
+  FspmUpd->FspmArchUpd.BootLoaderTolumSize = 0x0;
+
+  //
+  // Initialize DebugConfigData
+  //
+  DebugInterfaces = 0x00;
+  Hob.Guid = GetFirstGuidHob (&gDebugConfigHobGuid);
+  if (Hob.Guid != NULL) {
+    DebugConfigData = (DEBUG_CONFIG_DATA_HOB *) GET_GUID_HOB_DATA (Hob.Guid);
+    if (DebugConfigData != NULL) {
+      // Debug Interfaces
+      if (DebugConfigData->RamDebugInterface)      { DebugInterfaces |= STATUS_CODE_USE_RAM; }
+      if (DebugConfigData->UartDebugInterface)     { DebugInterfaces |= STATUS_CODE_USE_ISA_SERIAL; }
+      if (DebugConfigData->Usb3DebugInterface)     { DebugInterfaces |= STATUS_CODE_USE_USB3; }
+      if (DebugConfigData->SerialIoDebugInterface) { DebugInterfaces |= STATUS_CODE_USE_SERIALIO; }
+      if (DebugConfigData->TraceHubDebugInterface) { DebugInterfaces |= STATUS_CODE_USE_TRACEHUB; }
+      FspmUpd->FspmConfig.PcdDebugInterfaceFlags  = DebugInterfaces;
+      // Serial debug message baud rate
+      FspmUpd->FspmConfig.PcdSerialDebugBaudRate  = DebugConfigData->SerialDebugBaudRate;
+      //Serial debug message level
+      FspmUpd->FspmConfig.PcdSerialDebugLevel     = DebugConfigData->SerialDebug;
+    }
+  }
+  DEBUG ((DEBUG_INFO, "FspmConfig.PcdDebugInterfaceFlags is 0x%X\n", FspmUpd->FspmConfig.PcdDebugInterfaceFlags));
+  DEBUG ((DEBUG_INFO, "FspmUpd->FspmConfig.PcdSerialDebugBaudRate is 0x%X\n", FspmUpd->FspmConfig.PcdSerialDebugBaudRate));
+  DEBUG ((DEBUG_INFO, "FspmUpd->FspmConfig.PcdSerialDebugLevel is 0x%X\n", FspmUpd->FspmConfig.PcdSerialDebugLevel));
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c
new file mode 100644
index 0000000000..e2022929cd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c
@@ -0,0 +1,736 @@
+/** @file
+  Implementation of Fsp PCH Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PchInfoLib.h>
+
+/**
+  Performs FSP PCH PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                       Status;
+  UINTN                            Index;
+  UINTN                            MaxPcieRootPorts;
+  SI_PREMEM_POLICY_PPI             *SiPreMemPolicy;
+  PCH_TRACE_HUB_PREMEM_CONFIG      *PchTraceHubPreMemConfig;
+  PCH_SMBUS_PREMEM_CONFIG          *SmbusPreMemConfig;
+  PCH_DCI_PREMEM_CONFIG            *DciPreMemConfig;
+  PCH_HSIO_PCIE_PREMEM_CONFIG      *HsioPciePreMemConfig;
+  PCH_HSIO_SATA_PREMEM_CONFIG      *HsioSataPreMemConfig;
+  PCH_PCIE_RP_PREMEM_CONFIG        *PcieRpPreMemConfig;
+  PCH_LPC_PREMEM_CONFIG            *LpcPreMemConfig;
+  PCH_GENERAL_PREMEM_CONFIG        *PchGeneralPreMemConfig;
+  PCH_WDT_PREMEM_CONFIG            *WdtPreMemConfig;
+  PCH_HDAUDIO_PREMEM_CONFIG        *HdaPreMemConfig;
+  PCH_ISH_PREMEM_CONFIG            *IshPreMemConfig;
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP UpdatePeiPchPolicyPreMem\n"));
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "FspmUpd = 0x%x\n", FspmUpd));
+  //
+  // Locate PchPreMemPolicyPpi
+  //
+  SiPreMemPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ UpdatePeiPchPolicyPreMem\n"));
+  //
+  // Update PCIE RP policies
+  //
+//  MaxPcieRootPorts = 16;
+
+  MaxPcieRootPorts = GetPchMaxPciePortNum ();
+//  MaxPcieRootPorts = 16;
+  FspmUpd->FspmConfig.PcieRpEnableMask = PcieRpPreMemConfig->RpEnabledMask & ((1 << MaxPcieRootPorts) - 1);
+  FspmUpd->FspmConfig.PcieImrEnabled = PcieRpPreMemConfig->PcieImrEnabled;
+  FspmUpd->FspmConfig.PcieImrSize = PcieRpPreMemConfig->PcieImrSize;
+  FspmUpd->FspmConfig.ImrRpSelection = PcieRpPreMemConfig->ImrRpSelection;
+  //
+  // Update TraceHub policies
+  //
+  FspmUpd->FspmConfig.PchTraceHubMode = (UINT8) PchTraceHubPreMemConfig->EnableMode;
+  FspmUpd->FspmConfig.PchTraceHubMemReg0Size = (UINT8) PchTraceHubPreMemConfig->MemReg0Size;
+  FspmUpd->FspmConfig.PchTraceHubMemReg1Size = (UINT8) PchTraceHubPreMemConfig->MemReg1Size;
+
+  //
+  // Update Smbus policies
+  //
+  FspmUpd->FspmConfig.SmbusEnable = (UINT8)SmbusPreMemConfig->Enable;
+  FspmUpd->FspmConfig.SmbusArpEnable = (UINT8)SmbusPreMemConfig->ArpEnable;
+  FspmUpd->FspmTestConfig.SmbusDynamicPowerGating = (UINT8)SmbusPreMemConfig->DynamicPowerGating;
+  FspmUpd->FspmTestConfig.SmbusSpdWriteDisable = (UINT8)SmbusPreMemConfig->SpdWriteDisable;
+  FspmUpd->FspmConfig.PchSmbAlertEnable = (UINT8)SmbusPreMemConfig->SmbAlertEnable;
+  FspmUpd->FspmConfig.PchSmbusIoBase = (UINT16)SmbusPreMemConfig->SmbusIoBase;
+  FspmUpd->FspmConfig.PchNumRsvdSmbusAddresses = (UINT8)SmbusPreMemConfig->NumRsvdSmbusAddresses;
+  FspmUpd->FspmConfig.RsvdSmbusAddressTablePtr = (UINT32)SmbusPreMemConfig->RsvdSmbusAddressTable;
+
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ1 UpdatePeiPchPolicyPreMem\n"));
+  //
+  // Update Dci policies
+  //
+  FspmUpd->FspmConfig.PlatformDebugConsent = (UINT8)DciPreMemConfig->PlatformDebugConsent;
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ11 UpdatePeiPchPolicyPreMem\n"));
+  FspmUpd->FspmConfig.DciUsb3TypecUfpDbg = (UINT8)DciPreMemConfig->DciUsb3TypecUfpDbg;
+  //
+  // Update HSIO PCIE policies
+  //
+  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
+    FspmUpd->FspmConfig.PchPcieHsioRxSetCtleEnable[Index]           = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable;
+    FspmUpd->FspmConfig.PchPcieHsioRxSetCtle[Index]                 = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DownscaleAmpEnable[Index]  = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DownscaleAmp[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DownscaleAmpEnable[Index]  = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DownscaleAmp[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen3DownscaleAmpEnable[Index]  = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen3DownscaleAmp[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DeEmphEnable[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DeEmph[Index]              = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph3p5Enable[Index]     = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph3p5[Index]           = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph6p0Enable[Index]     = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph6p0[Index]           = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0;
+  }
+
+  //
+  // Update HSIO SATA policies
+  //
+  for (Index = 0; Index < PCH_MAX_SATA_PORTS; Index ++) {
+    FspmUpd->FspmConfig.PchSataHsioRxGen1EqBoostMagEnable[Index]    = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEnable;
+    FspmUpd->FspmConfig.PchSataHsioRxGen1EqBoostMag[Index]          = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag;
+    FspmUpd->FspmConfig.PchSataHsioRxGen2EqBoostMagEnable[Index]    = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEnable;
+    FspmUpd->FspmConfig.PchSataHsioRxGen2EqBoostMag[Index]          = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag;
+    FspmUpd->FspmConfig.PchSataHsioRxGen3EqBoostMagEnable[Index]    = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEnable;
+    FspmUpd->FspmConfig.PchSataHsioRxGen3EqBoostMag[Index]          = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DownscaleAmpEnable[Index]  = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DownscaleAmp[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DownscaleAmpEnable[Index]  = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DownscaleAmp[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DownscaleAmpEnable[Index]  = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DownscaleAmp[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DeEmphEnable[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DeEmph[Index]              = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DeEmphEnable[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DeEmph[Index]              = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DeEmphEnable[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DeEmph[Index]              = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph;
+  }
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ2 UpdatePeiPchPolicyPreMem\n"));
+  // Update LPC policies
+  //
+  FspmUpd->FspmConfig.PchLpcEnhancePort8xhDecoding = (UINT8)LpcPreMemConfig->EnhancePort8xhDecoding;
+
+  //
+  // Update Pch General Premem policies
+  //
+  FspmUpd->FspmConfig.PchPort80Route = (UINT8)PchGeneralPreMemConfig->Port80Route;
+
+  //
+  // Update Wdt policies
+  //
+  FspmUpd->FspmTestConfig.WdtDisableAndLock = (UINT8)WdtPreMemConfig->DisableAndLock;
+
+  //
+  // HdAudioConfig
+  //
+  FspmUpd->FspmConfig.PchHdaEnable = (UINT8)HdaPreMemConfig->Enable;
+
+  //
+  // IshConfig
+  //
+  FspmUpd->FspmConfig.PchIshEnable = (UINT8)IshPreMemConfig->Enable;
+
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ3 UpdatePeiPchPolicyPreMem\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                   Status;
+  UINTN                        Index;
+  UINTN                        MaxPcieRootPorts;
+  UINT8                        Data8;
+  SI_POLICY_PPI                *SiPolicy;
+  PCH_LAN_CONFIG               *LanConfig;
+  PCH_HDAUDIO_CONFIG           *HdAudioConfig;
+  PCH_SCS_CONFIG               *ScsConfig;
+  PCH_ISH_CONFIG               *IshConfig;
+  PCH_SATA_CONFIG              *SataConfig;
+  USB_CONFIG                   *UsbConfig;
+  PCH_SERIAL_IO_CONFIG         *SerialIoConfig;
+  PCH_INTERRUPT_CONFIG         *InterruptConfig;
+  PCH_LOCK_DOWN_CONFIG         *LockDownConfig;
+  PCH_CNVI_CONFIG              *CnviConfig;
+  PCH_HSIO_CONFIG              *HsioConfig;
+  PCH_ESPI_CONFIG              *EspiConfig;
+  PCH_PCIE_CONFIG              *PcieRpConfig;
+  PCH_DMI_CONFIG               *DmiConfig;
+  PCH_FLASH_PROTECTION_CONFIG  *FlashProtectionConfig;
+  PCH_IOAPIC_CONFIG            *IoApicConfig;
+  PCH_P2SB_CONFIG              *P2sbConfig;
+  PCH_GENERAL_CONFIG           *PchGeneralConfig;
+  PCH_PM_CONFIG                *PmConfig;
+  PCH_LPC_SIRQ_CONFIG          *PchSerialIrqConfig;
+  PCH_THERMAL_CONFIG           *PchThermalConfig;
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP UpdatePeiPchPolicy\n"));
+  //
+  // Locate SiPolicyPpi
+  //
+  SiPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLanConfigGuid, (VOID *) &LanConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gHdAudioConfigGuid, (VOID *) &HdAudioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gScsConfigGuid, (VOID *) &ScsConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIshConfigGuid, (VOID *) &IshConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *) &SataConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gUsbConfigGuid, (VOID *) &UsbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIoConfigGuid, (VOID *) &SerialIoConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gDmiConfigGuid, (VOID *) &DmiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gP2sbConfigGuid, (VOID *) &P2sbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIrqConfigGuid, (VOID *) &PchSerialIrqConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gThermalConfigGuid, (VOID *) &PchThermalConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gCnviConfigGuid, (VOID *) &CnviConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gHsioConfigGuid, (VOID *) &HsioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gEspiConfigGuid, (VOID *) &EspiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update LAN policies
+  //
+  FspsUpd->FspsConfig.PchLanEnable          = (UINT8)LanConfig->Enable;
+  FspsUpd->FspsConfig.PchLanLtrEnable       = (UINT8)LanConfig->LtrEnable;
+
+  //
+  // Update HDA policies
+  //
+  FspsUpd->FspsConfig.PchHdaDspEnable             = (UINT8)HdAudioConfig->DspEnable;
+  FspsUpd->FspsConfig.PchHdaPme                   = (UINT8)HdAudioConfig->Pme;
+  FspsUpd->FspsConfig.PchHdaVcType                = (UINT8)HdAudioConfig->VcType;
+  FspsUpd->FspsConfig.PchHdaLinkFrequency         = (UINT8)HdAudioConfig->HdAudioLinkFrequency;
+  FspsUpd->FspsConfig.PchHdaIDispLinkFrequency    = (UINT8)HdAudioConfig->IDispLinkFrequency;
+  FspsUpd->FspsConfig.PchHdaIDispLinkTmode        = (UINT8)HdAudioConfig->IDispLinkTmode;
+  FspsUpd->FspsConfig.PchHdaDspUaaCompliance      = (UINT8)HdAudioConfig->DspUaaCompliance;
+  FspsUpd->FspsConfig.PchHdaIDispCodecDisconnect  = (UINT8)HdAudioConfig->IDispCodecDisconnect;
+  FspsUpd->FspsConfig.PchHdaCodecSxWakeCapability = (UINT8)HdAudioConfig->CodecSxWakeCapability;
+  FspsUpd->FspsTestConfig.PchHdaResetWaitTimer    = (UINT16)HdAudioConfig->ResetWaitTimer;
+  FspsUpd->FspsConfig.PchHdaVerbTableEntryNum     = HdAudioConfig->VerbTableEntryNum;
+  FspsUpd->FspsConfig.PchHdaVerbTablePtr          = HdAudioConfig->VerbTablePtr;
+  FspsUpd->FspsConfig.PchHdaAudioLinkHda          = (UINT8)HdAudioConfig->AudioLinkHda;
+  FspsUpd->FspsConfig.PchHdaAudioLinkDmic0        = (UINT8)HdAudioConfig->AudioLinkDmic0;
+  FspsUpd->FspsConfig.PchHdaAudioLinkDmic1        = (UINT8)HdAudioConfig->AudioLinkDmic1;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSsp0         = (UINT8)HdAudioConfig->AudioLinkSsp0;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSsp1         = (UINT8)HdAudioConfig->AudioLinkSsp1;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSsp2         = (UINT8)HdAudioConfig->AudioLinkSsp2;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw1        = (UINT8)HdAudioConfig->AudioLinkSndw1;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw2        = (UINT8)HdAudioConfig->AudioLinkSndw2;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw3        = (UINT8)HdAudioConfig->AudioLinkSndw3;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw4        = (UINT8)HdAudioConfig->AudioLinkSndw4;
+  FspsUpd->FspsConfig.PchHdaSndwBufferRcomp       = (UINT8)HdAudioConfig->SndwBufferRcomp;
+
+  //
+  // Update SCS policies
+  //
+  FspsUpd->FspsConfig.ScsEmmcEnabled = (UINT8)ScsConfig->ScsEmmcEnabled;
+  FspsUpd->FspsConfig.ScsEmmcHs400Enabled = (UINT8)ScsConfig->ScsEmmcHs400Enabled;
+  FspsUpd->FspsConfig.ScsSdCardEnabled = (UINT8)ScsConfig->ScsSdcardEnabled;
+  FspsUpd->FspsConfig.SdCardPowerEnableActiveHigh = (UINT8)ScsConfig->SdCardPowerEnableActiveHigh;
+#ifdef CFL_SIMICS
+  FspsUpd->FspsConfig.ScsUfsEnabled    = 0;
+#else
+  FspsUpd->FspsConfig.ScsUfsEnabled    = (UINT8)ScsConfig->ScsUfsEnabled;
+#endif
+  FspsUpd->FspsConfig.PchScsEmmcHs400TuningRequired = (UINT8)ScsConfig->ScsEmmcHs400TuningRequired;
+  FspsUpd->FspsConfig.PchScsEmmcHs400DllDataValid   = (UINT8)ScsConfig->ScsEmmcHs400DllDataValid;
+  FspsUpd->FspsConfig.PchScsEmmcHs400RxStrobeDll1   = (UINT8)ScsConfig->ScsEmmcHs400RxStrobeDll1;
+  FspsUpd->FspsConfig.PchScsEmmcHs400TxDataDll      = (UINT8)ScsConfig->ScsEmmcHs400TxDataDll;
+  FspsUpd->FspsConfig.PchScsEmmcHs400DriverStrength = (UINT8)ScsConfig->ScsEmmcHs400DriverStrength;
+
+  //
+  // Update ISH policies
+  //
+  FspsUpd->FspsConfig.PchIshSpiGpioAssign   = (UINT8)IshConfig->SpiGpioAssign;
+  FspsUpd->FspsConfig.PchIshUart0GpioAssign = (UINT8)IshConfig->Uart0GpioAssign;
+  FspsUpd->FspsConfig.PchIshUart1GpioAssign = (UINT8)IshConfig->Uart1GpioAssign;
+  FspsUpd->FspsConfig.PchIshI2c0GpioAssign  = (UINT8)IshConfig->I2c0GpioAssign;
+  FspsUpd->FspsConfig.PchIshI2c1GpioAssign  = (UINT8)IshConfig->I2c1GpioAssign;
+  FspsUpd->FspsConfig.PchIshI2c2GpioAssign  = (UINT8)IshConfig->I2c2GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp0GpioAssign   = (UINT8)IshConfig->Gp0GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp1GpioAssign   = (UINT8)IshConfig->Gp1GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp2GpioAssign   = (UINT8)IshConfig->Gp2GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp3GpioAssign   = (UINT8)IshConfig->Gp3GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp4GpioAssign   = (UINT8)IshConfig->Gp4GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp5GpioAssign   = (UINT8)IshConfig->Gp5GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp6GpioAssign   = (UINT8)IshConfig->Gp6GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp7GpioAssign   = (UINT8)IshConfig->Gp7GpioAssign;
+  FspsUpd->FspsConfig.PchIshPdtUnlock       = (UINT8)IshConfig->PdtUnlock;
+
+  //
+  // Update PCIE RP RootPort policies
+  //
+  MaxPcieRootPorts = GetPchMaxPciePortNum ();
+  FspsUpd->FspsConfig.PcieRpDpcMask = 0;
+  FspsUpd->FspsConfig.PcieRpDpcExtensionsMask = 0;
+  FspsUpd->FspsConfig.PcieRpPtmMask = 0;
+  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
+    FspsUpd->FspsConfig.PcieRpHotPlug[Index] = (UINT8)PcieRpConfig->RootPort[Index].HotPlug;
+    FspsUpd->FspsConfig.PcieRpSlotImplemented[Index] = (UINT8)PcieRpConfig->RootPort[Index].SlotImplemented;
+    FspsUpd->FspsConfig.PcieRpPmSci[Index] = (UINT8)PcieRpConfig->RootPort[Index].PmSci;
+    FspsUpd->FspsConfig.PcieRpExtSync[Index] = (UINT8)PcieRpConfig->RootPort[Index].ExtSync;
+    FspsUpd->FspsConfig.PcieRpTransmitterHalfSwing[Index] = (UINT8)PcieRpConfig->RootPort[Index].TransmitterHalfSwing;
+    FspsUpd->FspsConfig.PcieRpClkReqDetect[Index] = (UINT8)PcieRpConfig->RootPort[Index].ClkReqDetect;
+    FspsUpd->FspsConfig.PcieRpAdvancedErrorReporting[Index] = (UINT8)PcieRpConfig->RootPort[Index].AdvancedErrorReporting;
+    FspsUpd->FspsConfig.PcieRpUnsupportedRequestReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].UnsupportedRequestReport;
+    FspsUpd->FspsConfig.PcieRpFatalErrorReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].FatalErrorReport;
+    FspsUpd->FspsConfig.PcieRpNoFatalErrorReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].NoFatalErrorReport;
+    FspsUpd->FspsConfig.PcieRpCorrectableErrorReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].CorrectableErrorReport;
+    FspsUpd->FspsConfig.PcieRpSystemErrorOnFatalError[Index] = (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnFatalError;
+    FspsUpd->FspsConfig.PcieRpSystemErrorOnNonFatalError[Index] = (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnNonFatalError;
+    FspsUpd->FspsConfig.PcieRpSystemErrorOnCorrectableError[Index] = (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnCorrectableError;
+    FspsUpd->FspsConfig.PcieRpMaxPayload[Index] = (UINT8)PcieRpConfig->RootPort[Index].MaxPayload;
+    if (PcieRpConfig->RootPort[Index].DpcEnabled) {
+      FspsUpd->FspsConfig.PcieRpDpcMask |= (BIT0<<Index);
+    }
+    if (PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled) {
+      FspsUpd->FspsConfig.PcieRpDpcExtensionsMask |= (BIT0<<Index);
+    }
+    if (PcieRpConfig->RootPort[Index].PtmEnabled) {
+      FspsUpd->FspsConfig.PcieRpPtmMask |= (BIT0<<Index);
+    }
+    FspsUpd->FspsConfig.PcieRpPcieSpeed[Index] = (UINT8)PcieRpConfig->RootPort[Index].PcieSpeed;
+    FspsUpd->FspsConfig.PcieRpGen3EqPh3Method[Index] = (UINT8)PcieRpConfig->RootPort[Index].Gen3EqPh3Method;
+    FspsUpd->FspsConfig.PcieRpPhysicalSlotNumber[Index] = (UINT8)PcieRpConfig->RootPort[Index].PhysicalSlotNumber;
+    FspsUpd->FspsConfig.PcieRpCompletionTimeout[Index] = (UINT8)PcieRpConfig->RootPort[Index].CompletionTimeout;
+    FspsUpd->FspsConfig.PcieRpAspm[Index] = (UINT8)PcieRpConfig->RootPort[Index].Aspm;
+    FspsUpd->FspsConfig.PcieRpL1Substates[Index] = (UINT8)PcieRpConfig->RootPort[Index].L1Substates;
+    FspsUpd->FspsConfig.PcieRpLtrEnable[Index] = (UINT8)PcieRpConfig->RootPort[Index].LtrEnable;
+    FspsUpd->FspsConfig.PcieRpLtrConfigLock[Index] = (UINT8)PcieRpConfig->RootPort[Index].LtrConfigLock;
+    FspsUpd->FspsConfig.PcieRpAcsEnabled[Index] = (UINT8)PcieRpConfig->RootPort[Index].AcsEnabled;
+    FspsUpd->FspsConfig.PcieRpDetectTimeoutMs[Index] = (UINT16)PcieRpConfig->RootPort[Index].DetectTimeoutMs;
+    FspsUpd->FspsConfig.PcieRootPortGen2PllL1CgDisable[Index] = (UINT8)PcieRpConfig->RootPort[Index].PcieRootPortGen2PllL1CgDisable;
+
+    FspsUpd->FspsTestConfig.PcieRpLtrMaxSnoopLatency[Index] = (UINT16)PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency;
+    FspsUpd->FspsTestConfig.PcieRpLtrMaxNoSnoopLatency[Index] = (UINT16)PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency;
+
+    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideMode[Index] = (UINT8)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode;
+    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideMultiplier[Index] = (UINT8)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier;
+    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideValue[Index] = (UINT16)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue;
+
+    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideMode[Index] = (UINT8)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode;
+    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideMultiplier[Index] = (UINT8)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier;
+    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideValue[Index] = (UINT16)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue;
+
+    FspsUpd->FspsTestConfig.PcieRpSlotPowerLimitScale[Index] = (UINT8)PcieRpConfig->RootPort[Index].SlotPowerLimitScale;
+    FspsUpd->FspsTestConfig.PcieRpSlotPowerLimitValue[Index] = (UINT16)PcieRpConfig->RootPort[Index].SlotPowerLimitValue;
+    FspsUpd->FspsTestConfig.PcieRpUptp[Index] = (UINT8)PcieRpConfig->RootPort[Index].Uptp;
+    FspsUpd->FspsTestConfig.PcieRpDptp[Index] = (UINT8)PcieRpConfig->RootPort[Index].Dptp;
+
+  }
+  for (Index = 0; Index < GetPchMaxPcieClockNum (); Index ++) {
+    FspsUpd->FspsConfig.PcieClkSrcUsage[Index] = PcieRpConfig->PcieClock[Index].Usage;
+    FspsUpd->FspsConfig.PcieClkSrcClkReq[Index] = PcieRpConfig->PcieClock[Index].ClkReq;
+  }
+
+  //
+  // Update PCIE RP EqPh3LaneParam policies
+  //
+  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
+    FspsUpd->FspsConfig.PcieEqPh3LaneParamCm[Index] = (UINT8)PcieRpConfig->EqPh3LaneParam[Index].Cm;
+    FspsUpd->FspsConfig.PcieEqPh3LaneParamCp[Index] = (UINT8)PcieRpConfig->EqPh3LaneParam[Index].Cp;
+  }
+
+  //
+  // Update PCIE RP SwEqCoeffList policies
+  //
+  for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index ++) {
+    FspsUpd->FspsConfig.PcieSwEqCoeffListCm[Index] = (UINT8)PcieRpConfig->SwEqCoeffList[Index].Cm;
+    FspsUpd->FspsConfig.PcieSwEqCoeffListCp[Index] = (UINT8)PcieRpConfig->SwEqCoeffList[Index].Cp;
+  }
+
+  //
+  // Update PCIE RP policies
+  //
+  FspsUpd->FspsTestConfig.PcieEnablePort8xhDecode        = (UINT8)PcieRpConfig->EnablePort8xhDecode;
+  FspsUpd->FspsTestConfig.PchPciePort8xhDecodePortIndex  = (UINT8)PcieRpConfig->PchPciePort8xhDecodePortIndex;
+  FspsUpd->FspsConfig.PcieDisableRootPortClockGating = (UINT8)PcieRpConfig->DisableRootPortClockGating;
+  FspsUpd->FspsConfig.PcieEnablePeerMemoryWrite      = (UINT8)PcieRpConfig->EnablePeerMemoryWrite;
+  FspsUpd->FspsConfig.PcieComplianceTestMode         = (UINT8)PcieRpConfig->ComplianceTestMode;
+  FspsUpd->FspsConfig.PcieRpFunctionSwap             = (UINT8)PcieRpConfig->RpFunctionSwap;
+  FspsUpd->FspsConfig.PchPcieDeviceOverrideTablePtr  = PcieRpConfig->PcieDeviceOverrideTablePtr;
+
+  //
+  // Update Sata Policies
+  //
+  FspsUpd->FspsConfig.SataEnable                     = (UINT8)SataConfig->Enable;
+  FspsUpd->FspsTestConfig.SataTestMode               = (UINT8)SataConfig->TestMode;
+  FspsUpd->FspsConfig.SataSalpSupport                = (UINT8)SataConfig->SalpSupport;
+  FspsUpd->FspsConfig.SataPwrOptEnable = (UINT8)SataConfig->PwrOptEnable;
+  FspsUpd->FspsConfig.EsataSpeedLimit  = (UINT8)SataConfig->EsataSpeedLimit;
+  FspsUpd->FspsConfig.SataLedEnable    = (UINT8)SataConfig->LedEnable;
+  FspsUpd->FspsConfig.SataMode         = (UINT8)SataConfig->SataMode;
+  FspsUpd->FspsConfig.SataSpeedLimit   = (UINT8)SataConfig->SpeedLimit;
+
+  for (Index = 0; Index < PCH_MAX_SATA_PORTS; Index++) {
+    FspsUpd->FspsConfig.SataPortsEnable[Index] = (UINT8)SataConfig->PortSettings[Index].Enable;
+    FspsUpd->FspsConfig.SataPortsHotPlug[Index]     = (UINT8)SataConfig->PortSettings[Index].HotPlug;
+    FspsUpd->FspsConfig.SataPortsInterlockSw[Index] = (UINT8)SataConfig->PortSettings[Index].InterlockSw;
+    FspsUpd->FspsConfig.SataPortsExternal[Index]    = (UINT8)SataConfig->PortSettings[Index].External;
+    FspsUpd->FspsConfig.SataPortsSpinUp[Index]      = (UINT8)SataConfig->PortSettings[Index].SpinUp;
+    FspsUpd->FspsConfig.SataPortsSolidStateDrive[Index]  = (UINT8)SataConfig->PortSettings[Index].SolidStateDrive;
+    FspsUpd->FspsConfig.SataPortsDevSlp[Index] = (UINT8)SataConfig->PortSettings[Index].DevSlp;
+    FspsUpd->FspsConfig.SataPortsEnableDitoConfig[Index] = (UINT8)SataConfig->PortSettings[Index].EnableDitoConfig;
+    FspsUpd->FspsConfig.SataPortsDmVal[Index]       = (UINT8)SataConfig->PortSettings[Index].DmVal;
+    FspsUpd->FspsConfig.SataPortsDitoVal[Index]     = (UINT16)SataConfig->PortSettings[Index].DitoVal;
+    FspsUpd->FspsConfig.SataPortsZpOdd[Index]       = (UINT8)SataConfig->PortSettings[Index].ZpOdd;
+  }
+
+  FspsUpd->FspsConfig.SataRstRaidDeviceId            = (UINT8)SataConfig->Rst.RaidDeviceId;
+  FspsUpd->FspsConfig.SataRstInterrupt               = (UINT8)SataConfig->Rst.SataRstInterrupt;
+  FspsUpd->FspsConfig.SataRstRaid0                   = (UINT8)SataConfig->Rst.Raid0;
+  FspsUpd->FspsConfig.SataRstRaid1                   = (UINT8)SataConfig->Rst.Raid1;
+  FspsUpd->FspsConfig.SataRstRaid10                  = (UINT8)SataConfig->Rst.Raid10;
+  FspsUpd->FspsConfig.SataRstRaid5                   = (UINT8)SataConfig->Rst.Raid5;
+  FspsUpd->FspsConfig.SataRstIrrt                    = (UINT8)SataConfig->Rst.Irrt;
+  FspsUpd->FspsConfig.SataRstOromUiBanner            = (UINT8)SataConfig->Rst.OromUiBanner;
+  FspsUpd->FspsConfig.SataRstOromUiDelay             = (UINT8)SataConfig->Rst.OromUiDelay;
+  FspsUpd->FspsConfig.SataRstHddUnlock               = (UINT8)SataConfig->Rst.HddUnlock;
+  FspsUpd->FspsConfig.SataRstLedLocate               = (UINT8)SataConfig->Rst.LedLocate;
+  FspsUpd->FspsConfig.SataRstIrrtOnly                = (UINT8)SataConfig->Rst.IrrtOnly;
+  FspsUpd->FspsConfig.SataRstSmartStorage            = (UINT8)SataConfig->Rst.SmartStorage;
+  FspsUpd->FspsConfig.SataRstOptaneMemory            = (UINT8)SataConfig->Rst.OptaneMemory;
+  FspsUpd->FspsConfig.SataRstLegacyOrom              = (UINT8)SataConfig->Rst.LegacyOrom;
+  FspsUpd->FspsConfig.SataRstCpuAttachedStorage      = (UINT8)SataConfig->Rst.CpuAttachedStorage;
+
+  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+    FspsUpd->FspsConfig.SataRstPcieEnable[Index]           = (UINT8)SataConfig->RstPcieStorageRemap[Index].Enable;
+    FspsUpd->FspsConfig.SataRstPcieStoragePort[Index]      = (UINT8)SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort;
+    FspsUpd->FspsConfig.SataRstPcieDeviceResetDelay[Index] = (UINT8)SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay;
+  }
+
+  FspsUpd->FspsConfig.SataP0T1M            = (UINT8)SataConfig->ThermalThrottling.P0T1M;
+  FspsUpd->FspsConfig.SataP0T2M            = (UINT8)SataConfig->ThermalThrottling.P0T2M;
+  FspsUpd->FspsConfig.SataP0T3M            = (UINT8)SataConfig->ThermalThrottling.P0T3M;
+  FspsUpd->FspsConfig.SataP0TDisp          = (UINT8)SataConfig->ThermalThrottling.P0TDisp;
+  FspsUpd->FspsConfig.SataP1T1M            = (UINT8)SataConfig->ThermalThrottling.P1T1M;
+  FspsUpd->FspsConfig.SataP1T2M            = (UINT8)SataConfig->ThermalThrottling.P1T2M;
+  FspsUpd->FspsConfig.SataP1T3M            = (UINT8)SataConfig->ThermalThrottling.P1T3M;
+  FspsUpd->FspsConfig.SataP1TDisp          = (UINT8)SataConfig->ThermalThrottling.P1TDisp;
+  FspsUpd->FspsConfig.SataP0Tinact         = (UINT8)SataConfig->ThermalThrottling.P0Tinact;
+  FspsUpd->FspsConfig.SataP0TDispFinit     = (UINT8)SataConfig->ThermalThrottling.P0TDispFinit;
+  FspsUpd->FspsConfig.SataP1Tinact         = (UINT8)SataConfig->ThermalThrottling.P1Tinact;
+  FspsUpd->FspsConfig.SataP1TDispFinit     = (UINT8)SataConfig->ThermalThrottling.P1TDispFinit;
+  FspsUpd->FspsConfig.SataThermalSuggestedSetting = (UINT8)SataConfig->ThermalThrottling.SuggestedSetting;
+
+  //
+  // Update USB policies
+  //
+  FspsUpd->FspsConfig.PchEnableComplianceMode           = (UINT8)UsbConfig->EnableComplianceMode;
+  FspsUpd->FspsConfig.UsbPdoProgramming                 = (UINT8)UsbConfig->PdoProgramming;
+  FspsUpd->FspsConfig.PchUsbOverCurrentEnable           = (UINT8)UsbConfig->OverCurrentEnable;
+  FspsUpd->FspsConfig.PchUsb2PhySusPgEnable             = (UINT8)UsbConfig->Usb2PhySusPgEnable;
+  FspsUpd->FspsTestConfig.PchXhciOcLock                 = (UINT8)UsbConfig->XhciOcLock;
+  for (Index = 0; Index < PCH_MAX_USB2_PORTS; Index++) {
+    FspsUpd->FspsConfig.PortUsb20Enable[Index]  = (UINT8)UsbConfig->PortUsb20[Index].Enable;
+    FspsUpd->FspsConfig.Usb2OverCurrentPin[Index] = (UINT8)UsbConfig->PortUsb20[Index].OverCurrentPin;
+    FspsUpd->FspsConfig.Usb2AfePetxiset[Index]  = (UINT8)UsbConfig->PortUsb20[Index].Afe.Petxiset;
+    FspsUpd->FspsConfig.Usb2AfeTxiset[Index]    = (UINT8)UsbConfig->PortUsb20[Index].Afe.Txiset;
+    FspsUpd->FspsConfig.Usb2AfePredeemp[Index]  = (UINT8)UsbConfig->PortUsb20[Index].Afe.Predeemp;
+    FspsUpd->FspsConfig.Usb2AfePehalfbit[Index] = (UINT8)UsbConfig->PortUsb20[Index].Afe.Pehalfbit;
+  }
+  for (Index = 0; Index < PCH_MAX_USB3_PORTS; Index++) {
+    FspsUpd->FspsConfig.PortUsb30Enable[Index]              = (UINT8)UsbConfig->PortUsb30[Index].Enable;
+    FspsUpd->FspsConfig.Usb3OverCurrentPin[Index]           = (UINT8)UsbConfig->PortUsb30[Index].OverCurrentPin;
+    FspsUpd->FspsConfig.Usb3HsioTxDeEmphEnable[Index]       = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable;
+    FspsUpd->FspsConfig.Usb3HsioTxDeEmph[Index]             = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDeEmph;
+    FspsUpd->FspsConfig.Usb3HsioTxDownscaleAmpEnable[Index] = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable;
+    FspsUpd->FspsConfig.Usb3HsioTxDownscaleAmp[Index]       = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp;
+
+    Data8 = 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable ? B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN : 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable ? B_XHCI_HSIO_FILTER_SELECT_N_EN : 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable ? B_XHCI_HSIO_FILTER_SELECT_P_EN : 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable ? B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN : 0;
+    FspsUpd->FspsConfig.PchUsbHsioRxTuningEnable[Index] = Data8;
+
+    Data8 = ((UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg & 0x1F) << N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG) |
+            ((UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes & 0x7) << N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES);
+    FspsUpd->FspsConfig.PchUsbHsioRxTuningParameters[Index] = Data8;
+
+    Data8 = ((UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN & 0x7) << N_XHCI_UPD_HSIO_FILTER_SELECT_N) |
+            ((UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP & 0x7) << N_XHCI_UPD_HSIO_FILTER_SELECT_P);
+    FspsUpd->FspsConfig.PchUsbHsioFilterSel[Index] = Data8;
+  }
+
+  FspsUpd->FspsConfig.XdciEnable     = (UINT8)UsbConfig->XdciConfig.Enable;
+
+  //
+  // Update SerialIo policies
+  //
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    FspsUpd->FspsConfig.SerialIoDevMode[Index] = SerialIoConfig->DevMode[Index];
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    FspsUpd->FspsConfig.SerialIoSpiCsPolarity[Index] = SerialIoConfig->SpiCsPolarity[Index];
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    FspsUpd->FspsConfig.SerialIoUartHwFlowCtrl[Index] = SerialIoConfig->UartHwFlowCtrl[Index];
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    FspsUpd->FspsConfig.PchSerialIoI2cPadsTermination[Index] = SerialIoConfig->I2cPadsTermination[Index];
+  }
+
+  FspsUpd->FspsConfig.SerialIoDebugUartNumber          = (UINT8)SerialIoConfig->DebugUartNumber;
+  FspsUpd->FspsConfig.SerialIoEnableDebugUartAfterPost = (UINT8)SerialIoConfig->EnableDebugUartAfterPost;
+  FspsUpd->FspsConfig.SerialIoUart0PinMuxing           = (UINT8)SerialIoConfig->Uart0PinMuxing;
+
+  //
+  // Update Interrupt policies
+  //
+  FspsUpd->FspsConfig.DevIntConfigPtr = (UINT32)InterruptConfig->DevIntConfig;
+  FspsUpd->FspsConfig.NumOfDevIntConfig = InterruptConfig->NumOfDevIntConfig;
+  for (Index = 0; Index < PCH_MAX_PXRC_CONFIG; Index ++) {
+    FspsUpd->FspsConfig.PxRcConfig[Index] = (UINT8)InterruptConfig->PxRcConfig[Index];
+  }
+  FspsUpd->FspsConfig.GpioIrqRoute = (UINT8)InterruptConfig->GpioIrqRoute;
+  FspsUpd->FspsConfig.SciIrqSelect = (UINT8)InterruptConfig->SciIrqSelect;
+  FspsUpd->FspsConfig.TcoIrqSelect = (UINT8)InterruptConfig->TcoIrqSelect;
+  FspsUpd->FspsConfig.TcoIrqEnable = (UINT8)InterruptConfig->TcoIrqEnable;
+
+  //
+  // Update LockDown policies
+  //
+  FspsUpd->FspsTestConfig.PchLockDownGlobalSmi     = (UINT8)LockDownConfig->GlobalSmi;
+  FspsUpd->FspsTestConfig.PchLockDownBiosInterface = (UINT8)LockDownConfig->BiosInterface;
+  FspsUpd->FspsConfig.PchLockDownBiosLock          = (UINT8)LockDownConfig->BiosLock;
+  FspsUpd->FspsConfig.PchLockDownRtcMemoryLock     = (UINT8)LockDownConfig->RtcMemoryLock;
+  FspsUpd->FspsTestConfig.PchUnlockGpioPads        = (UINT8)LockDownConfig->UnlockGpioPads;
+
+  //
+  // Update Dmi policies
+  //
+  FspsUpd->FspsConfig.PchPwrOptEnable = (UINT8)DmiConfig->PwrOptEnable;
+  FspsUpd->FspsConfig.PchDmiAspmCtrl = (UINT8)DmiConfig->DmiAspmCtrl;
+
+  //
+  // Update Flash Protection policies
+  //
+  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; Index ++) {
+    FspsUpd->FspsConfig.PchWriteProtectionEnable[Index] = (UINT8)FlashProtectionConfig->ProtectRange[Index].WriteProtectionEnable;
+    FspsUpd->FspsConfig.PchReadProtectionEnable[Index]  = (UINT8)FlashProtectionConfig->ProtectRange[Index].ReadProtectionEnable;
+    FspsUpd->FspsConfig.PchProtectedRangeLimit[Index]  = (UINT16)FlashProtectionConfig->ProtectRange[Index].ProtectedRangeLimit;
+    FspsUpd->FspsConfig.PchProtectedRangeBase[Index]   = (UINT16)FlashProtectionConfig->ProtectRange[Index].ProtectedRangeBase;
+  }
+
+  //
+  // Update IO Apic policies
+  //
+  FspsUpd->FspsConfig.PchIoApicEntry24_119       = (UINT8)IoApicConfig->IoApicEntry24_119;
+  FspsUpd->FspsConfig.Enable8254ClockGating      = (UINT8)IoApicConfig->Enable8254ClockGating;
+  FspsUpd->FspsConfig.Enable8254ClockGatingOnS3  = (UINT8)IoApicConfig->Enable8254ClockGatingOnS3;
+  FspsUpd->FspsConfig.PchIoApicId                = (UINT8)IoApicConfig->IoApicId;
+
+  //
+  // Update P2sb policies
+  //
+  FspsUpd->FspsTestConfig.PchSbAccessUnlock  = (UINT8)P2sbConfig->SbAccessUnlock;
+
+  //
+  // Update Pch General policies
+  //
+  FspsUpd->FspsConfig.PchCrid               = (UINT8)PchGeneralConfig->Crid;
+  FspsUpd->FspsConfig.PchLegacyIoLowLatency = (UINT8)PchGeneralConfig->LegacyIoLowLatency;
+
+  //
+  // Update Pm policies
+  //
+  FspsUpd->FspsConfig.PchPmPmeB0S5Dis         = (UINT8)PmConfig->WakeConfig.PmeB0S5Dis;
+  FspsUpd->FspsConfig.PchPmWolEnableOverride  = (UINT8)PmConfig->WakeConfig.WolEnableOverride;
+  FspsUpd->FspsConfig.PchPmPcieWakeFromDeepSx = (UINT8)PmConfig->WakeConfig.PcieWakeFromDeepSx;
+  FspsUpd->FspsConfig.PchPmWoWlanEnable       = (UINT8)PmConfig->WakeConfig.WoWlanEnable;
+  FspsUpd->FspsConfig.PchPmWoWlanDeepSxEnable = (UINT8)PmConfig->WakeConfig.WoWlanDeepSxEnable;
+  FspsUpd->FspsConfig.PchPmLanWakeFromDeepSx  = (UINT8)PmConfig->WakeConfig.LanWakeFromDeepSx;
+
+  FspsUpd->FspsConfig.PchPmDeepSxPol          = (UINT8)PmConfig->PchDeepSxPol;
+  FspsUpd->FspsConfig.PchPmSlpS3MinAssert     = (UINT8)PmConfig->PchSlpS3MinAssert;
+  FspsUpd->FspsConfig.PchPmSlpS4MinAssert     = (UINT8)PmConfig->PchSlpS4MinAssert;
+  FspsUpd->FspsConfig.PchPmSlpSusMinAssert    = (UINT8)PmConfig->PchSlpSusMinAssert;
+  FspsUpd->FspsConfig.PchPmSlpAMinAssert      = (UINT8)PmConfig->PchSlpAMinAssert;
+  FspsUpd->FspsConfig.PchPmLpcClockRun        = (UINT8)PmConfig->LpcClockRun;
+  FspsUpd->FspsConfig.PchPmSlpStrchSusUp      = (UINT8)PmConfig->SlpStrchSusUp;
+  FspsUpd->FspsConfig.PchPmSlpLanLowDc        = (UINT8)PmConfig->SlpLanLowDc;
+  FspsUpd->FspsConfig.PchPmPwrBtnOverridePeriod = (UINT8)PmConfig->PwrBtnOverridePeriod;
+  FspsUpd->FspsTestConfig.PchPmDisableEnergyReport  = (UINT8)PmConfig->DisableEnergyReport;
+  FspsUpd->FspsConfig.PchPmDisableDsxAcPresentPulldown = (UINT8)PmConfig->DisableDsxAcPresentPulldown;
+  FspsUpd->FspsConfig.PchPmDisableNativePowerButton    = (UINT8)PmConfig->DisableNativePowerButton;
+  FspsUpd->FspsConfig.PmcPowerButtonDebounce  = PmConfig->PowerButtonDebounce;
+  FspsUpd->FspsConfig.PchPmSlpS0Enable        = (UINT8)PmConfig->SlpS0Enable;
+  FspsUpd->FspsConfig.PchPmMeWakeSts          = (UINT8)PmConfig->MeWakeSts;
+  FspsUpd->FspsConfig.PchPmWolOvrWkSts        = (UINT8)PmConfig->WolOvrWkSts;
+  FspsUpd->FspsConfig.EnableTcoTimer          = (UINT8)PmConfig->EnableTcoTimer;
+  FspsUpd->FspsConfig.PchPmVrAlert            = (UINT8)PmConfig->VrAlert;
+  FspsUpd->FspsConfig.PchPmPwrCycDur          = (UINT8)PmConfig->PchPwrCycDur;
+  FspsUpd->FspsConfig.PchPmPciePllSsc         = (UINT8)PmConfig->PciePllSsc;
+  FspsUpd->FspsConfig.PchPmSlpS0VmRuntimeControl = (UINT8)PmConfig->SlpS0VmRuntimeControl;
+  FspsUpd->FspsConfig.PchPmSlpS0Vm070VSupport   = (UINT8)PmConfig->SlpS0Vm070VSupport;
+  FspsUpd->FspsConfig.PchPmSlpS0Vm075VSupport   = (UINT8)PmConfig->SlpS0Vm075VSupport;
+  FspsUpd->FspsConfig.SlpS0Override             = (UINT8)PmConfig->SlpS0Override;
+  FspsUpd->FspsConfig.SlpS0DisQForDebug         = (UINT8)PmConfig->SlpS0DisQForDebug;
+  FspsUpd->FspsConfig.PmcDbgMsgEn               = (UINT8)PmConfig->PmcDbgMsgEn;
+  FspsUpd->FspsConfig.PsOnEnable                = (UINT8)PmConfig->PsOnEnable;
+  FspsUpd->FspsConfig.PmcCpuC10GatePinEnable    = (UINT8)PmConfig->CpuC10GatePinEnable;
+  FspsUpd->FspsConfig.PmcModPhySusPgEnable      = (UINT8)PmConfig->ModPhySusPgEnable;
+  FspsUpd->FspsConfig.SlpS0WithGbeSupport       = (UINT8)PmConfig->SlpS0WithGbeSupport;
+  //
+  // Update Pch Serial IRQ policies
+  //
+  FspsUpd->FspsConfig.PchSirqEnable       = (UINT8)PchSerialIrqConfig->SirqEnable;
+  FspsUpd->FspsConfig.PchSirqMode         = (UINT8)PchSerialIrqConfig->SirqMode;
+  FspsUpd->FspsConfig.PchStartFramePulse  = (UINT8)PchSerialIrqConfig->StartFramePulse;
+  //
+  // Update Pch Thermal policies
+  //
+  FspsUpd->FspsConfig.PchTsmicLock        = (UINT8)PchThermalConfig->TsmicLock;
+  FspsUpd->FspsConfig.PchHotEnable        = (UINT8)PchThermalConfig->PchHotEnable;
+
+  FspsUpd->FspsConfig.PchT0Level          = (UINT16)PchThermalConfig->TTLevels.T0Level;
+  FspsUpd->FspsConfig.PchT1Level          = (UINT16)PchThermalConfig->TTLevels.T1Level;
+  FspsUpd->FspsConfig.PchT2Level          = (UINT16)PchThermalConfig->TTLevels.T2Level;
+  FspsUpd->FspsConfig.PchTTEnable         = (UINT8)PchThermalConfig->TTLevels.TTEnable;
+  FspsUpd->FspsConfig.PchTTState13Enable  = (UINT8)PchThermalConfig->TTLevels.TTState13Enable;
+  FspsUpd->FspsConfig.PchTTLock           = (UINT8)PchThermalConfig->TTLevels.TTLock;
+  FspsUpd->FspsConfig.TTSuggestedSetting  = (UINT8)PchThermalConfig->TTLevels.SuggestedSetting;
+  FspsUpd->FspsConfig.TTCrossThrottling   = (UINT8)PchThermalConfig->TTLevels.PchCrossThrottling;
+
+  FspsUpd->FspsConfig.PchDmiTsawEn        = (UINT8)PchThermalConfig->DmiHaAWC.DmiTsawEn;
+  FspsUpd->FspsConfig.DmiSuggestedSetting = (UINT8)PchThermalConfig->DmiHaAWC.SuggestedSetting;
+  FspsUpd->FspsConfig.DmiTS0TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS0TW;
+  FspsUpd->FspsConfig.DmiTS1TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS1TW;
+  FspsUpd->FspsConfig.DmiTS2TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS2TW;
+  FspsUpd->FspsConfig.DmiTS3TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS3TW;
+
+  FspsUpd->FspsConfig.PchMemoryThrottlingEnable    = (UINT8)PchThermalConfig->MemoryThrottling.Enable;
+  FspsUpd->FspsConfig.PchMemoryPmsyncEnable[0]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].PmsyncEnable;
+  FspsUpd->FspsConfig.PchMemoryPmsyncEnable[1]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].PmsyncEnable;
+  FspsUpd->FspsConfig.PchMemoryC0TransmitEnable[0] = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].C0TransmitEnable;
+  FspsUpd->FspsConfig.PchMemoryC0TransmitEnable[1] = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].C0TransmitEnable;
+  FspsUpd->FspsConfig.PchMemoryPinSelection[0]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].PinSelection;
+  FspsUpd->FspsConfig.PchMemoryPinSelection[1]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].PinSelection;
+
+  FspsUpd->FspsConfig.PchTemperatureHotLevel = (UINT16)PchThermalConfig->PchHotLevel;
+
+  //
+  // Update Pch CNVi policies
+  //
+  FspsUpd->FspsConfig.PchCnviMode        = (UINT8)CnviConfig->Mode;
+  FspsUpd->FspsConfig.PchCnviMfUart1Type = (UINT8)CnviConfig->MfUart1Type;
+
+  //
+  // Update Pch HSIO policies
+  //
+  FspsUpd->FspsConfig.ChipsetInitBinPtr = HsioConfig->ChipsetInitBinPtr;
+  FspsUpd->FspsConfig.ChipsetInitBinLen = HsioConfig->ChipsetInitBinLen;
+
+  //
+  // Update Pch Espi policies
+  //
+  FspsUpd->FspsConfig.PchEspiLgmrEnable = (UINT8)EspiConfig->LgmrEnable;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c
new file mode 100644
index 0000000000..ce34325781
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c
@@ -0,0 +1,223 @@
+/** @file
+  Instance of Fsp Policy Initialization Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Library/SpiLib.h>
+
+VOID
+EFIAPI
+FspPolicyInitPreMem(
+  IN FSPM_UPD           *FspmUpdDataPtr
+);
+
+VOID *
+EFIAPI
+SiliconPolicyInitPreMem(
+  IN OUT VOID    *FspmUpd
+)
+{
+  FspPolicyInitPreMem((FSPM_UPD *)FspmUpd);
+  return FspmUpd;
+}
+
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePreMem(
+  IN VOID *FspmUpd
+)
+{
+  EFI_STATUS         Status;
+
+  Status = SpiServiceInit();
+  ASSERT_EFI_ERROR(Status);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Performs FSP PEI Policy Pre-memory initialization.
+
+  @param[in] FspmUpdDataPtr       Pointer to FSPM UPD data.
+**/
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+  IN FSPM_UPD           *FspmUpdDataPtr
+  )
+{
+  EFI_STATUS            Status;
+
+  //
+  // SI Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSiPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // PCH Pei Fsp Policy Initialization
+  //
+  Status = PeiFspPchPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - PCH Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Cpu Pei Fsp Policy Initialization
+  //
+  Status = PeiFspCpuPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Security Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSecurityPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - Security Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // ME Pei Fsp Policy Initialization
+  //
+  Status = PeiFspMePolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - ME Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // SystemAgent Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSaPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Other Upd Initialization
+  //
+  Status = PeiFspMiscUpdInitPreMem (FspmUpdDataPtr);
+
+}
+
+/**
+  Performs FSP PEI Policy initialization.
+
+  @param[in][out] FspsUpd  Pointer UPD data region
+
+**/
+VOID
+EFIAPI
+FspPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS            Status;
+
+  //
+  // SI Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSiPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy iInitialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // PCH Pei Fsp Policy Initialization
+  //
+  Status = PeiFspPchPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - PCH Pei Fsp Policy iInitialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // ME Pei Fsp Policy Initialization
+  //
+  Status = PeiFspMePolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - ME Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // SystemAgent Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSaPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Cpu Pei Fsp Policy Initialization
+  //
+  Status = PeiFspCpuPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Security Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSecurityPolicyInit(FspsUpd);
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "ERROR - Security Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+}
+
+/**
+Performs silicon post-mem policy initialization.
+
+The meaning of Policy is defined by silicon code.
+It could be the raw data, a handle, a PPI, etc.
+
+The returned data must be used as input data for SiliconPolicyDonePostMem(),
+and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
+
+1) In FSP path, the input Policy should be FspsUpd.
+Value of FspsUpd has been initialized by FSP binary default value.
+Only a subset of FspsUpd needs to be updated for different silicon sku.
+The return data is same FspsUpd.
+
+2) In non-FSP path, the input policy could be NULL.
+The return data is the initialized policy.
+
+@param[in, out] Policy       Pointer to policy.
+
+@return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPostMem(
+  IN OUT VOID    *FspsUpd
+)
+{
+  FspPolicyInit((FSPS_UPD *)FspsUpd);
+  return FspsUpd;
+}
+
+/*
+The silicon post-mem policy is finalized.
+Silicon code can do initialization based upon the policy data.
+
+The input Policy must be returned by SiliconPolicyInitPostMem().
+
+@param[in] Policy       Pointer to policy.
+
+@retval EFI_SUCCESS The policy is handled consumed by silicon code.
+*/
+EFI_STATUS
+EFIAPI
+SiliconPolicyDonePostMem(
+  IN OUT VOID    *FspsUpd
+)
+{
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
new file mode 100644
index 0000000000..0bfc379386
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
@@ -0,0 +1,848 @@
+/** @file
+  Implementation of Fsp SA Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <PchAccess.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Core/Pei/PeiMain.h>
+
+#define MAX_SPD_PAGE_COUNT           (2)
+#define MAX_SPD_PAGE_SIZE            (256)
+#define MAX_SPD_SIZE                 (MAX_SPD_PAGE_SIZE * MAX_SPD_PAGE_COUNT)
+#define SPD_PAGE_ADDRESS_0           (0x6C)
+#define SPD_PAGE_ADDRESS_1           (0x6E)
+#define SPD_DDR3_SDRAM_TYPE_OFFSET   (0x02)
+#define SPD_DDR3_SDRAM_TYPE_NUMBER   (0x0B)
+#define SPD_DDR4_SDRAM_TYPE_NUMBER   (0x0C)
+#define SPD_LPDDR3_SDRAM_TYPE_NUMBER (0xF1)
+#define SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER (0x0F)
+#define XMP_ID_STRING                (0x4A0C)
+#define SPD3_MANUF_START             (117)
+#define SPD3_MANUF_END               (127)
+#define SPD4_MANUF_START             (320)
+#define SPD4_MANUF_END               (328)
+#define SPDLP_MANUF_START            (320)
+#define SPDLP_MANUF_END              (328)
+
+GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdDdr3Table[] = {
+  {   0,               1,             (1 << SpdCold),},
+  {   2,               2,             (1 << SpdCold) | (1 << SpdFast),},
+  {   3,              41,             (1 << SpdCold),},
+  {  60,              63,             (1 << SpdCold),},
+  { SPD3_MANUF_START, SPD3_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
+  { 128,             145,             (1 << SpdCold),},
+  {  39,              59,             (1 << SpdCold),},
+  {  64,             125,             (1 << SpdCold),},
+  { 176,             179,             (1 << SpdCold),},
+  { 180,             184,             (1 << SpdCold),},
+  { 185,             215,             (1 << SpdCold),},
+  { 220,             250,             (1 << SpdCold),},
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdDdr4Table[] = {
+  {   0,               1,             (1 << SpdCold),},
+  {   2,               2,             (1 << SpdCold) | (1 << SpdFast),},
+  {   3,              40,             (1 << SpdCold),},
+  { 117,             131,             (1 << SpdCold),},
+  { SPD4_MANUF_START, SPD4_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
+  { 329,             348,             (1 << SpdCold),},
+  {  32,             119,             (1 << SpdCold),},
+  { 126,             255,             (1 << SpdCold),},
+  { 349,             383,             (1 << SpdCold),},
+  { 384,             387,             (1 << SpdCold),},
+  { 388,             389,             (1 << SpdCold),},
+  { 393,             431,             (1 << SpdCold),},
+  { 440,             478,             (1 << SpdCold),},
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdLpddrTable[] = {
+  {   0,               1,               (1 << SpdCold),},
+  {   2,               2,               (1 << SpdCold) | (1 << SpdFast),},
+  {   3,              32,               (1 << SpdCold),},
+  { 120,             130,               (1 << SpdCold),},
+  { SPDLP_MANUF_START, SPDLP_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
+  { 329,             348,               (1 << SpdCold),},
+  {  31,             121,               (1 << SpdCold),},
+  { 126,             255,               (1 << SpdCold),},
+  { 349,             383,               (1 << SpdCold),},
+  { 384,             387,               (1 << SpdCold),},
+  { 388,             389,               (1 << SpdCold),},
+  { 393,             431,               (1 << SpdCold),},
+  { 440,             478,               (1 << SpdCold),},
+};
+
+
+/**
+  Update Spd Data
+
+  @param[in][out] FspmUpd              Pointer to FSP UPD Data.
+  @param[in]      MemConfigNoCrc       Pointer to Mem Config No Crc.
+  @param[in]      MiscPeiPreMemConfig  Pointer to Misc Config.
+
+  @retval         EFI_SUCCESS          The function completes successfully
+  @retval         Other                The function fail
+**/
+VOID
+EFIAPI
+InternalUpdateSpdInfo (
+  IN OUT FSPM_UPD               *FspmUpd,
+  IN MEMORY_CONFIG_NO_CRC       *MemConfigNoCrc,
+  IN SA_MISC_PEI_PREMEM_CONFIG  *MiscPeiPreMemConfig
+  )
+{
+
+  DEBUG ((DEBUG_INFO, "Updating UPD:Memory Spd Pointers...\n"));
+  if ((FspmUpd == NULL) || (MemConfigNoCrc == NULL) || (MiscPeiPreMemConfig == NULL)) {
+    DEBUG ((DEBUG_ERROR, "EFI_INVALID_PARAMETER.\n"));
+    DEBUG ((DEBUG_ERROR, "Fail to access SPD from SiPolicyPpi\n"));
+    return;
+  }
+
+  //
+  // Update MemorySpdPtrXX if SpdAddressTable is zero
+  //
+  if (MiscPeiPreMemConfig->SpdAddressTable[0] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr00 = (UINT32)MemConfigNoCrc->SpdData->SpdData;
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[0] = MiscPeiPreMemConfig->SpdAddressTable[0];
+  }
+
+  if (MiscPeiPreMemConfig->SpdAddressTable[1] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr01 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (1 * SA_MC_MAX_SPD_SIZE);
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[1] = MiscPeiPreMemConfig->SpdAddressTable[1];
+  }
+
+  if (MiscPeiPreMemConfig->SpdAddressTable[2] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr10 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (2 * SA_MC_MAX_SPD_SIZE);
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[2] = MiscPeiPreMemConfig->SpdAddressTable[2];
+  }
+
+  if (MiscPeiPreMemConfig->SpdAddressTable[3] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr11 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (3 * SA_MC_MAX_SPD_SIZE);
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[3] = MiscPeiPreMemConfig->SpdAddressTable[3];
+  }
+
+  DEBUG ((DEBUG_INFO, "UPD:MemorySpdPtr Updated\n"));
+}
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32               *Size
+  )
+{
+  EFI_STATUS  Status;
+  EFI_PEI_FIRMWARE_VOLUME_PPI          *FvPpi;
+  EFI_FV_FILE_INFO                     FvFileInfo;
+  PEI_CORE_INSTANCE                    *PrivateData;
+  UINTN                                CurrentFv;
+  PEI_CORE_FV_HANDLE                   *CoreFvHandle;
+  EFI_PEI_FILE_HANDLE                  VbtFileHandle;
+  EFI_GUID                             *VbtGuid;
+  EFI_COMMON_SECTION_HEADER            *Section;
+  CONST EFI_PEI_SERVICES               **PeiServices;
+
+  PeiServices = GetPeiServicesTablePointer ();
+
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+  Status = PeiServicesLocatePpi (
+            &gEfiFirmwareFileSystem2Guid,
+            0,
+            NULL,
+            (VOID **) &FvPpi
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  CurrentFv = PrivateData->CurrentPeimFvCount;
+  CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+  Status = FvPpi->FindFileByName (FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+  if (!EFI_ERROR(Status) && VbtFileHandle != NULL) {
+
+  DEBUG ((DEBUG_INFO, "Find SectionByType \n"));
+
+    Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **) &VbtGuid);
+    if (!EFI_ERROR (Status)) {
+
+    DEBUG ((DEBUG_INFO, "GetFileInfo \n"));
+
+      Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo);
+      Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
+
+      if (IS_SECTION2 (Section)) {
+        ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
+        *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+      } else {
+        *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP SA PEI Policy initialization in pre-memory.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                  Status;
+  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
+  MEMORY_CONFIGURATION        *MemConfig;
+  MEMORY_CONFIG_NO_CRC        *MemConfigNoCrc;
+  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
+  PCIE_PEI_PREMEM_CONFIG      *PciePeiPreMemConfig;
+  SWITCHABLE_GRAPHICS_CONFIG  *SgGpioData;
+  GRAPHICS_PEI_PREMEM_CONFIG  *GtPreMemConfig;
+  OVERCLOCKING_PREMEM_CONFIG  *OcPreMemConfig;
+  VTD_CONFIG                  *Vtd;
+  IPU_PREMEM_CONFIG           *IpuPreMemPolicy;
+  UINT8                       Index;
+  VOID                        *Buffer;
+
+  SiPreMemPolicyPpi   = NULL;
+  MiscPeiPreMemConfig = NULL;
+  MemConfig           = NULL;
+  MemConfigNoCrc      = NULL;
+  PciePeiPreMemConfig = NULL;
+  SgGpioData          = NULL;
+  GtPreMemConfig      = NULL;
+  OcPreMemConfig      = NULL;
+  Vtd                 = NULL;
+  IpuPreMemPolicy     = NULL;
+
+
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  Status = PeiServicesLocatePpi(
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+  if ((Status == EFI_SUCCESS) && (SiPreMemPolicyPpi != NULL)) {
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *) &SgGpioData);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gVtdConfigGuid, (VOID *) &Vtd);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Byte Map and DQS Byte Swizzling Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh0, Buffer, 12);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh1, (UINT8*) Buffer + 12, 12);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh0, Buffer, 8);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh1, (UINT8*) Buffer + 8, 8);
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Pins Interleaved,Rcomp Resistor & Rcomp Target Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompResistor, Buffer, 6);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompTarget, Buffer, 10);
+  }
+
+  //
+  // Update UPD:MemorySpdPtrXX and SpdAddressTable
+  //
+  InternalUpdateSpdInfo (FspmUpd, MemConfigNoCrc, MiscPeiPreMemConfig);
+
+  //
+  // Update UPD:MemorySpdDataLen
+  //
+  FspmUpd->FspmConfig.MemorySpdDataLen = SA_MC_MAX_SPD_SIZE;
+
+  if (MemConfigNoCrc != NULL) {
+    //
+    // Update UPD:PlatformMemorySize
+    //
+    //
+    // @todo: This value is used since #183932. Revisit.
+    //
+    FspmUpd->FspmConfig.PlatformMemorySize  = MemConfigNoCrc->PlatformMemorySize;
+    FspmUpd->FspmConfig.CleanMemory         = (UINT8) MemConfigNoCrc->CleanMemory;
+    FspmUpd->FspmConfig.MemTestOnWarmBoot   = (UINT8) MemConfigNoCrc->MemTestOnWarmBoot;
+  }
+
+  if (MemConfig != NULL) {
+    //
+    // Update UPD:DqPinsInterleaved
+    //
+    FspmUpd->FspmConfig.DqPinsInterleaved     = (UINT8) MemConfig->DqPinsInterleaved;
+
+    FspmUpd->FspmConfig.ProbelessTrace        = MemConfig->ProbelessTrace;
+    FspmUpd->FspmConfig.GdxcIotSize           = MemConfig->GdxcIotSize;
+    FspmUpd->FspmConfig.GdxcMotSize           = MemConfig->GdxcMotSize;
+    FspmUpd->FspmConfig.DualDimmPerChannelBoardType =(UINT8) MemConfig->DualDimmPerChannelBoardType;
+    FspmUpd->FspmConfig.Ddr4MixedUDimm2DpcLimit     =(UINT8) MemConfig->Ddr4MixedUDimm2DpcLimit;
+    //
+    // Update UPD:CaVrefConfig
+    //
+    FspmUpd->FspmConfig.CaVrefConfig          = MemConfig->CaVrefConfig;
+    FspmUpd->FspmConfig.SaGv                  = MemConfig->SaGv;
+    FspmUpd->FspmConfig.FreqSaGvLow           = MemConfig->FreqSaGvLow;
+    FspmUpd->FspmConfig.FreqSaGvMid           = MemConfig->FreqSaGvMid;
+    FspmUpd->FspmConfig.RMT                   = (UINT8) MemConfig->RMT;
+    FspmUpd->FspmConfig.DdrFreqLimit          = MemConfig->DdrFreqLimit;
+
+    FspmUpd->FspmConfig.SpdProfileSelected    = MemConfig->SpdProfileSelected;
+    FspmUpd->FspmConfig.VddVoltage            = MemConfig->VddVoltage;
+    FspmUpd->FspmConfig.RefClk                = MemConfig->RefClk;
+    FspmUpd->FspmConfig.Ratio                 = MemConfig->Ratio;
+    FspmUpd->FspmConfig.OddRatioMode          = (UINT8) MemConfig->OddRatioMode;
+    FspmUpd->FspmConfig.tCL                   = (UINT8) MemConfig->tCL;
+    FspmUpd->FspmConfig.tCWL                  = (UINT8) MemConfig->tCWL;
+    FspmUpd->FspmConfig.tFAW                  = MemConfig->tFAW;
+    FspmUpd->FspmConfig.tRAS                  = MemConfig->tRAS;
+    FspmUpd->FspmConfig.tRCDtRP               = (UINT8) MemConfig->tRCDtRP;
+    FspmUpd->FspmConfig.tREFI                 = MemConfig->tREFI;
+    FspmUpd->FspmConfig.tRFC                  = MemConfig->tRFC;
+    FspmUpd->FspmConfig.tRRD                  = (UINT8) MemConfig->tRRD;
+    FspmUpd->FspmConfig.tRTP                  = (UINT8) MemConfig->tRTP;
+    FspmUpd->FspmConfig.tWR                   = (UINT8) MemConfig->tWR;
+    FspmUpd->FspmConfig.tWTR                  = (UINT8) MemConfig->tWTR;
+    FspmUpd->FspmConfig.NModeSupport          = MemConfig->NModeSupport;
+    FspmUpd->FspmConfig.DllBwEn0              = MemConfig->DllBwEn0;
+    FspmUpd->FspmConfig.DllBwEn1              = MemConfig->DllBwEn1;
+    FspmUpd->FspmConfig.DllBwEn2              = MemConfig->DllBwEn2;
+    FspmUpd->FspmConfig.DllBwEn3              = MemConfig->DllBwEn3;
+    FspmUpd->FspmConfig.MrcSafeConfig         = (UINT8) MemConfig->MrcSafeConfig; // Typecasting as MrcSafeConfig is of UINT32 in MEMORY_CONFIGURATION
+    FspmUpd->FspmConfig.LpDdrDqDqsReTraining  = (UINT8) MemConfig->Lp4DqsOscEn;
+    FspmUpd->FspmConfig.RmtPerTask            = (UINT8) MemConfig->RmtPerTask;
+    FspmUpd->FspmConfig.TrainTrace            = (UINT8) MemConfig->TrainTrace;
+    FspmUpd->FspmConfig.ScramblerSupport      = (UINT8) MemConfig->ScramblerSupport;
+    FspmUpd->FspmConfig.SafeMode              = (UINT8) MemConfig->SafeMode;
+
+    //
+    // Update UPD:SmramMask and DisableDimmChannel
+    //
+    FspmUpd->FspmConfig.SmramMask               = MemConfig->SmramMask;
+    FspmUpd->FspmConfig.DisableDimmChannel0     = MemConfig->DisableDimmChannel[0];
+    FspmUpd->FspmConfig.DisableDimmChannel1     = MemConfig->DisableDimmChannel[1];
+    FspmUpd->FspmConfig.HobBufferSize           = MemConfig->HobBufferSize;
+
+    FspmUpd->FspmConfig.ECT                     = (UINT8) MemConfig->ECT;
+    FspmUpd->FspmConfig.SOT                     = (UINT8) MemConfig->SOT;
+    FspmUpd->FspmConfig.ERDMPRTC2D              = (UINT8) MemConfig->ERDMPRTC2D;
+    FspmUpd->FspmConfig.RDMPRT                  = (UINT8) MemConfig->RDMPRT;
+    FspmUpd->FspmConfig.RCVET                   = (UINT8) MemConfig->RCVET;
+    FspmUpd->FspmConfig.JWRL                    = (UINT8) MemConfig->JWRL;
+    FspmUpd->FspmConfig.EWRTC2D                 = (UINT8) MemConfig->EWRTC2D;
+    FspmUpd->FspmConfig.ERDTC2D                 = (UINT8) MemConfig->ERDTC2D;
+    FspmUpd->FspmConfig.WRTC1D                  = (UINT8) MemConfig->WRTC1D;
+    FspmUpd->FspmConfig.WRVC1D                  = (UINT8) MemConfig->WRVC1D;
+    FspmUpd->FspmConfig.RDTC1D                  = (UINT8) MemConfig->RDTC1D;
+    FspmUpd->FspmConfig.DIMMODTT                = (UINT8) MemConfig->DIMMODTT;
+    FspmUpd->FspmConfig.DIMMRONT                = (UINT8) MemConfig->DIMMRONT;
+    FspmUpd->FspmConfig.WRSRT                   = (UINT8) MemConfig->WRSRT;
+    FspmUpd->FspmConfig.RDODTT                  = (UINT8) MemConfig->RDODTT;
+    FspmUpd->FspmConfig.RDEQT                   = (UINT8) MemConfig->RDEQT;
+    FspmUpd->FspmConfig.RDAPT                   = (UINT8) MemConfig->RDAPT;
+    FspmUpd->FspmConfig.WRTC2D                  = (UINT8) MemConfig->WRTC2D;
+    FspmUpd->FspmConfig.RDTC2D                  = (UINT8) MemConfig->RDTC2D;
+    FspmUpd->FspmConfig.WRVC2D                  = (UINT8) MemConfig->WRVC2D;
+    FspmUpd->FspmConfig.RDVC2D                  = (UINT8) MemConfig->RDVC2D;
+    FspmUpd->FspmConfig.CMDVC                   = (UINT8) MemConfig->CMDVC;
+    FspmUpd->FspmConfig.LCT                     = (UINT8) MemConfig->LCT;
+    FspmUpd->FspmConfig.RTL                     = (UINT8) MemConfig->RTL;
+    FspmUpd->FspmConfig.TAT                     = (UINT8) MemConfig->TAT;
+    FspmUpd->FspmConfig.RCVENC1D                = (UINT8) MemConfig->RCVENC1D;
+    FspmUpd->FspmConfig.RMT                     = (UINT8) MemConfig->RMT;
+    FspmUpd->FspmConfig.MEMTST                  = (UINT8) MemConfig->MEMTST;
+    FspmUpd->FspmConfig.ALIASCHK                = (UINT8) MemConfig->ALIASCHK;
+    FspmUpd->FspmConfig.RMC                     = (UINT8) MemConfig->RMC;
+    FspmUpd->FspmConfig.WRDSUDT                 = (UINT8) MemConfig->WRDSUDT;
+    FspmUpd->FspmConfig.EnBER                   = (UINT8) MemConfig->EnBER;
+    FspmUpd->FspmConfig.EccSupport              = (UINT8) MemConfig->EccSupport;
+    FspmUpd->FspmConfig.RemapEnable             = (UINT8) MemConfig->RemapEnable;
+    FspmUpd->FspmConfig.ScramblerSupport        = (UINT8) MemConfig->ScramblerSupport;
+    FspmUpd->FspmConfig.MrcFastBoot             = (UINT8) MemConfig->MrcFastBoot;
+    FspmUpd->FspmConfig.RankInterleave          = (UINT8) MemConfig->RankInterleave;
+    FspmUpd->FspmConfig.EnhancedInterleave      = (UINT8) MemConfig->EnhancedInterleave;
+    FspmUpd->FspmConfig.MemoryTrace             = (UINT8) MemConfig->MemoryTrace;
+    FspmUpd->FspmConfig.ChHashEnable            = (UINT8) MemConfig->ChHashEnable;
+    FspmUpd->FspmConfig.EnableExtts             = (UINT8) MemConfig->EnableExtts;
+    FspmUpd->FspmConfig.EnableCltm              = (UINT8) MemConfig->EnableCltm;
+    FspmUpd->FspmConfig.EnableOltm              = (UINT8) MemConfig->EnableOltm;
+    FspmUpd->FspmConfig.EnablePwrDn             = (UINT8) MemConfig->EnablePwrDn;
+    FspmUpd->FspmConfig.EnablePwrDnLpddr        = (UINT8) MemConfig->EnablePwrDnLpddr;
+    FspmUpd->FspmConfig.UserPowerWeightsEn      = (UINT8) MemConfig->UserPowerWeightsEn;
+    FspmUpd->FspmConfig.RaplLim2Lock            = (UINT8) MemConfig->RaplLim2Lock;
+    FspmUpd->FspmConfig.RaplLim2Ena             = (UINT8) MemConfig->RaplLim2Ena;
+    FspmUpd->FspmConfig.RaplLim1Ena             = (UINT8) MemConfig->RaplLim1Ena;
+    FspmUpd->FspmConfig.SrefCfgEna              = (UINT8) MemConfig->SrefCfgEna;
+    FspmUpd->FspmConfig.ThrtCkeMinDefeatLpddr   = (UINT8) MemConfig->ThrtCkeMinDefeatLpddr;
+    FspmUpd->FspmConfig.ThrtCkeMinDefeat        = (UINT8) MemConfig->ThrtCkeMinDefeat;
+    FspmUpd->FspmConfig.RhPrevention            = (UINT8) MemConfig->RhPrevention;
+    FspmUpd->FspmConfig.ExitOnFailure           = (UINT8) MemConfig->ExitOnFailure;
+    FspmUpd->FspmConfig.DdrThermalSensor        = (UINT8) MemConfig->DdrThermalSensor;
+    FspmUpd->FspmConfig.Ddr4DdpSharedClock      = (UINT8) MemConfig->Ddr4DdpSharedClock;
+    FspmUpd->FspmConfig.Ddr4DdpSharedZq         = (UINT8) MemConfig->SharedZqPin;
+    FspmUpd->FspmConfig.BClkFrequency           = MemConfig->BClkFrequency;
+    FspmUpd->FspmConfig.ChHashInterleaveBit     = MemConfig->ChHashInterleaveBit;
+    FspmUpd->FspmConfig.ChHashMask              = MemConfig->ChHashMask;
+    FspmUpd->FspmConfig.EnergyScaleFact         = MemConfig->EnergyScaleFact;
+    FspmUpd->FspmConfig.Idd3n                   = MemConfig->Idd3n;
+    FspmUpd->FspmConfig.Idd3p                   = MemConfig->Idd3p;
+    FspmUpd->FspmConfig.CMDSR                   = (UINT8) MemConfig->CMDSR;
+    FspmUpd->FspmConfig.CMDDSEQ                 = (UINT8) MemConfig->CMDDSEQ;
+    FspmUpd->FspmConfig.CMDNORM                 = (UINT8) MemConfig->CMDNORM;
+    FspmUpd->FspmConfig.EWRDSEQ                 = (UINT8) MemConfig->EWRDSEQ;
+    FspmUpd->FspmConfig.FreqSaGvLow             = MemConfig->FreqSaGvLow;
+    FspmUpd->FspmConfig.RhActProbability        = MemConfig->RhActProbability;
+    FspmUpd->FspmConfig.RaplLim2WindX           = MemConfig->RaplLim2WindX;
+    FspmUpd->FspmConfig.RaplLim2WindY           = MemConfig->RaplLim2WindY;
+    FspmUpd->FspmConfig.RaplLim1WindX           = MemConfig->RaplLim1WindX;
+    FspmUpd->FspmConfig.RaplLim1WindY           = MemConfig->RaplLim1WindY;
+    FspmUpd->FspmConfig.RaplLim2Pwr             = MemConfig->RaplLim2Pwr;
+    FspmUpd->FspmConfig.RaplLim1Pwr             = MemConfig->RaplLim1Pwr;
+    FspmUpd->FspmConfig.WarmThresholdCh0Dimm0   = MemConfig->WarmThresholdCh0Dimm0;
+    FspmUpd->FspmConfig.WarmThresholdCh0Dimm1   = MemConfig->WarmThresholdCh0Dimm1;
+    FspmUpd->FspmConfig.WarmThresholdCh1Dimm0   = MemConfig->WarmThresholdCh1Dimm0;
+    FspmUpd->FspmConfig.WarmThresholdCh1Dimm1   = MemConfig->WarmThresholdCh1Dimm1;
+    FspmUpd->FspmConfig.HotThresholdCh0Dimm0    = MemConfig->HotThresholdCh0Dimm0;
+    FspmUpd->FspmConfig.HotThresholdCh0Dimm1    = MemConfig->HotThresholdCh0Dimm1;
+    FspmUpd->FspmConfig.HotThresholdCh1Dimm0    = MemConfig->HotThresholdCh1Dimm0;
+    FspmUpd->FspmConfig.HotThresholdCh1Dimm1    = MemConfig->HotThresholdCh1Dimm1;
+    FspmUpd->FspmConfig.WarmBudgetCh0Dimm0      = MemConfig->WarmBudgetCh0Dimm0;
+    FspmUpd->FspmConfig.WarmBudgetCh0Dimm1      = MemConfig->WarmBudgetCh0Dimm1;
+    FspmUpd->FspmConfig.WarmBudgetCh1Dimm0      = MemConfig->WarmBudgetCh1Dimm0;
+    FspmUpd->FspmConfig.WarmBudgetCh1Dimm1      = MemConfig->WarmBudgetCh1Dimm1;
+    FspmUpd->FspmConfig.HotBudgetCh0Dimm0       = MemConfig->HotBudgetCh0Dimm0;
+    FspmUpd->FspmConfig.HotBudgetCh0Dimm1       = MemConfig->HotBudgetCh0Dimm1;
+    FspmUpd->FspmConfig.HotBudgetCh1Dimm0       = MemConfig->HotBudgetCh1Dimm0;
+    FspmUpd->FspmConfig.HotBudgetCh1Dimm1       = MemConfig->HotBudgetCh1Dimm1;
+    FspmUpd->FspmConfig.IdleEnergyCh0Dimm0      = MemConfig->IdleEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.IdleEnergyCh0Dimm1      = MemConfig->IdleEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.IdleEnergyCh1Dimm0      = MemConfig->IdleEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.IdleEnergyCh1Dimm1      = MemConfig->IdleEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.PdEnergyCh0Dimm0        = MemConfig->PdEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.PdEnergyCh0Dimm1        = MemConfig->PdEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.PdEnergyCh1Dimm0        = MemConfig->PdEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.PdEnergyCh1Dimm1        = MemConfig->PdEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.ActEnergyCh0Dimm0       = MemConfig->ActEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.ActEnergyCh0Dimm1       = MemConfig->ActEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.ActEnergyCh1Dimm0       = MemConfig->ActEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.ActEnergyCh1Dimm1       = MemConfig->ActEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.RdEnergyCh0Dimm0        = MemConfig->RdEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.RdEnergyCh0Dimm1        = MemConfig->RdEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.RdEnergyCh1Dimm0        = MemConfig->RdEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.RdEnergyCh1Dimm1        = MemConfig->RdEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.WrEnergyCh0Dimm0        = MemConfig->WrEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.WrEnergyCh0Dimm1        = MemConfig->WrEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.WrEnergyCh1Dimm0        = MemConfig->WrEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.WrEnergyCh1Dimm1        = MemConfig->WrEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.ThrtCkeMinTmr           = MemConfig->ThrtCkeMinTmr;
+    FspmUpd->FspmConfig.CkeRankMapping          = MemConfig->CkeRankMapping;
+    FspmUpd->FspmConfig.CaVrefConfig            = MemConfig->CaVrefConfig;
+    FspmUpd->FspmConfig.RaplPwrFlCh1            = MemConfig->RaplPwrFlCh1;
+    FspmUpd->FspmConfig.RaplPwrFlCh0            = MemConfig->RaplPwrFlCh0;
+    FspmUpd->FspmConfig.EnCmdRate               = MemConfig->EnCmdRate;
+    FspmUpd->FspmConfig.Refresh2X               = MemConfig->Refresh2X;
+    FspmUpd->FspmConfig.EpgEnable               = MemConfig->EpgEnable;
+    FspmUpd->FspmConfig.RhSolution              = MemConfig->RhSolution;
+    FspmUpd->FspmConfig.UserThresholdEnable     = MemConfig->UserThresholdEnable;
+    FspmUpd->FspmConfig.UserBudgetEnable        = MemConfig->UserBudgetEnable;
+    FspmUpd->FspmConfig.TsodTcritMax            = MemConfig->TsodTcritMax;
+    FspmUpd->FspmConfig.TsodEventMode           = MemConfig->TsodEventMode;
+    FspmUpd->FspmConfig.TsodEventPolarity       = MemConfig->TsodEventPolarity;
+    FspmUpd->FspmConfig.TsodCriticalEventOnly   = MemConfig->TsodCriticalEventOnly;
+    FspmUpd->FspmConfig.TsodEventOutputControl  = MemConfig->TsodEventOutputControl;
+    FspmUpd->FspmConfig.TsodAlarmwindowLockBit  = MemConfig->TsodAlarmwindowLockBit;
+    FspmUpd->FspmConfig.TsodCriticaltripLockBit = MemConfig->TsodCriticaltripLockBit;
+    FspmUpd->FspmConfig.TsodShutdownMode        = MemConfig->TsodShutdownMode;
+    FspmUpd->FspmConfig.TsodThigMax             = MemConfig->TsodThigMax;
+    FspmUpd->FspmConfig.TsodManualEnable        = MemConfig->TsodManualEnable;
+    FspmUpd->FspmConfig.IsvtIoPort              = MemConfig->IsvtIoPort;
+    FspmUpd->FspmConfig.ForceOltmOrRefresh2x    = MemConfig->ForceOltmOrRefresh2x;
+    FspmUpd->FspmConfig.PwdwnIdleCounter        = MemConfig->PwdwnIdleCounter;
+    FspmUpd->FspmConfig.CmdRanksTerminated      = MemConfig->CmdRanksTerminated;
+    FspmUpd->FspmConfig.GdxcEnable              = MemConfig->GdxcEnable;
+    FspmUpd->FspmConfig.RMTLoopCount            = MemConfig->RMTLoopCount;
+
+    // DDR4 Memory Timings
+    FspmUpd->FspmTestConfig.tRRD_L = (UINT8) MemConfig->tRRD_L;
+    FspmUpd->FspmTestConfig.tRRD_S = (UINT8) MemConfig->tRRD_S;
+    FspmUpd->FspmTestConfig.tWTR_L = (UINT8) MemConfig->tWTR_L;
+    FspmUpd->FspmTestConfig.tWTR_S = (UINT8) MemConfig->tWTR_S;
+
+    // TurnAround Timing
+    // Read-to-Read
+    FspmUpd->FspmTestConfig.tRd2RdSG = MemConfig->tRd2RdSG;
+    FspmUpd->FspmTestConfig.tRd2RdDG = MemConfig->tRd2RdDG;
+    FspmUpd->FspmTestConfig.tRd2RdDR = MemConfig->tRd2RdDR;
+    FspmUpd->FspmTestConfig.tRd2RdDD = MemConfig->tRd2RdDD;
+    // Write-to-Read
+    FspmUpd->FspmTestConfig.tWr2RdSG = MemConfig->tWr2RdSG;
+    FspmUpd->FspmTestConfig.tWr2RdDG = MemConfig->tWr2RdDG;
+    FspmUpd->FspmTestConfig.tWr2RdDR = MemConfig->tWr2RdDR;
+    FspmUpd->FspmTestConfig.tWr2RdDD = MemConfig->tWr2RdDD;
+    // Write-to-Write
+    FspmUpd->FspmTestConfig.tWr2WrSG = MemConfig->tWr2WrSG;
+    FspmUpd->FspmTestConfig.tWr2WrDG = MemConfig->tWr2WrDG;
+    FspmUpd->FspmTestConfig.tWr2WrDR = MemConfig->tWr2WrDR;
+    FspmUpd->FspmTestConfig.tWr2WrDD = MemConfig->tWr2WrDD;
+    // Read-to-Write
+    FspmUpd->FspmTestConfig.tRd2WrSG = MemConfig->tRd2WrSG;
+    FspmUpd->FspmTestConfig.tRd2WrDG = MemConfig->tRd2WrDG;
+    FspmUpd->FspmTestConfig.tRd2WrDR = MemConfig->tRd2WrDR;
+    FspmUpd->FspmTestConfig.tRd2WrDD = MemConfig->tRd2WrDD;
+  }
+
+  if (MiscPeiPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.IedSize               = MiscPeiPreMemConfig->IedSize;
+    FspmUpd->FspmConfig.UserBd                = MiscPeiPreMemConfig->UserBd;
+    FspmUpd->FspmConfig.SgDelayAfterPwrEn     = MiscPeiPreMemConfig->SgDelayAfterPwrEn;
+    FspmUpd->FspmConfig.SgDelayAfterHoldReset = MiscPeiPreMemConfig->SgDelayAfterHoldReset;
+    FspmUpd->FspmConfig.MmioSize              = MiscPeiPreMemConfig->MmioSize;
+    FspmUpd->FspmConfig.MmioSizeAdjustment    = MiscPeiPreMemConfig->MmioSizeAdjustment;
+    FspmUpd->FspmConfig.TsegSize              = MiscPeiPreMemConfig->TsegSize;
+
+    FspmUpd->FspmTestConfig.SkipExtGfxScan           = (UINT8) MiscPeiPreMemConfig->SkipExtGfxScan;
+    FspmUpd->FspmTestConfig.BdatEnable               = (UINT8) MiscPeiPreMemConfig->BdatEnable;
+    FspmUpd->FspmTestConfig.BdatTestType             = (UINT8) MiscPeiPreMemConfig->BdatTestType;
+    FspmUpd->FspmTestConfig.ScanExtGfxForLegacyOpRom = (UINT8) MiscPeiPreMemConfig->ScanExtGfxForLegacyOpRom;
+    FspmUpd->FspmTestConfig.LockPTMregs              = (UINT8) MiscPeiPreMemConfig->LockPTMregs;
+  }
+
+  if (Vtd != NULL) {
+    FspmUpd->FspmConfig.X2ApicOptOut = (UINT8) Vtd->X2ApicOptOut;
+    FspmUpd->FspmConfig.VtdBaseAddress[0] = Vtd->BaseAddress[0];
+    FspmUpd->FspmConfig.VtdBaseAddress[1] = Vtd->BaseAddress[1];
+    FspmUpd->FspmConfig.VtdBaseAddress[2] = Vtd->BaseAddress[2];
+    FspmUpd->FspmTestConfig.VtdDisable = (UINT8) Vtd->VtdDisable;
+  }
+
+  if (PciePeiPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.DmiGen3ProgramStaticEq = (UINT8) PciePeiPreMemConfig->DmiGen3ProgramStaticEq;
+    FspmUpd->FspmConfig.Peg0Enable = (UINT8) PciePeiPreMemConfig->Peg0Enable;
+    FspmUpd->FspmConfig.Peg1Enable = (UINT8) PciePeiPreMemConfig->Peg1Enable;
+    FspmUpd->FspmConfig.Peg2Enable = (UINT8) PciePeiPreMemConfig->Peg2Enable;
+    FspmUpd->FspmConfig.Peg3Enable = (UINT8) PciePeiPreMemConfig->Peg3Enable;
+    FspmUpd->FspmConfig.Peg0MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg0MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg1MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg1MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg2MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg2MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg3MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg3MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg0MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg0MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg1MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg1MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg2MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg2MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg3MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg3MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg0PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg0PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.Peg1PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg1PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.Peg2PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg2PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.Peg3PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg3PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.InitPcieAspmAfterOprom = (UINT8) PciePeiPreMemConfig->InitPcieAspmAfterOprom;
+    FspmUpd->FspmConfig.PegDisableSpreadSpectrumClocking = (UINT8) PciePeiPreMemConfig->PegDisableSpreadSpectrumClocking;
+    for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+      FspmUpd->FspmConfig.DmiGen3RootPortPreset[Index] = PciePeiPreMemConfig->DmiGen3RootPortPreset[Index];
+      FspmUpd->FspmConfig.DmiGen3EndPointPreset[Index] = PciePeiPreMemConfig->DmiGen3EndPointPreset[Index];
+      FspmUpd->FspmConfig.DmiGen3EndPointHint[Index] = PciePeiPreMemConfig->DmiGen3EndPointHint[Index];
+    }
+    for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
+      FspmUpd->FspmConfig.DmiGen3RxCtlePeaking[Index] = PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index];
+    }
+    for (Index = 0; Index < SA_PEG_MAX_BUNDLE ; Index++) {
+      FspmUpd->FspmConfig.PegGen3RxCtlePeaking[Index] = PciePeiPreMemConfig->PegGen3RxCtlePeaking[Index];
+    }
+    FspmUpd->FspmConfig.PegDataPtr = (UINT32) PciePeiPreMemConfig->PegDataPtr;
+    CopyMem((VOID *)FspmUpd->FspmConfig.PegGpioData, &PciePeiPreMemConfig->PegGpioData, sizeof (PEG_GPIO_DATA));
+    FspmUpd->FspmConfig.DmiDeEmphasis = PciePeiPreMemConfig->DmiDeEmphasis;
+
+    for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+      FspmUpd->FspmConfig.PegRootPortHPE[Index] = PciePeiPreMemConfig->PegRootPortHPE[Index];
+    }
+    FspmUpd->FspmTestConfig.DmiMaxLinkSpeed     = (UINT8) PciePeiPreMemConfig->DmiMaxLinkSpeed;
+    FspmUpd->FspmTestConfig.DmiGen3EqPh2Enable  = (UINT8) PciePeiPreMemConfig->DmiGen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.DmiGen3EqPh3Method  = (UINT8) PciePeiPreMemConfig->DmiGen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg0Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg0Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg1Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg1Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg2Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg2Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg3Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg3Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg0Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg0Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg1Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg1Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg2Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg2Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg3Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg3Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.PegGen3ProgramStaticEq = (UINT8) PciePeiPreMemConfig->PegGen3ProgramStaticEq;
+    FspmUpd->FspmTestConfig.Gen3SwEqAlwaysAttempt = (UINT8) PciePeiPreMemConfig->Gen3SwEqAlwaysAttempt;
+    FspmUpd->FspmTestConfig.Gen3SwEqNumberOfPresets = (UINT8) PciePeiPreMemConfig->Gen3SwEqNumberOfPresets;
+    FspmUpd->FspmTestConfig.Gen3SwEqEnableVocTest = (UINT8) PciePeiPreMemConfig->Gen3SwEqEnableVocTest;
+    FspmUpd->FspmTestConfig.PegRxCemTestingMode = (UINT8) PciePeiPreMemConfig->PegRxCemTestingMode;
+    FspmUpd->FspmTestConfig.PegRxCemLoopbackLane = (UINT8) PciePeiPreMemConfig->PegRxCemLoopbackLane;
+    FspmUpd->FspmTestConfig.PegGenerateBdatMarginTable = (UINT8) PciePeiPreMemConfig->PegGenerateBdatMarginTable;
+    FspmUpd->FspmTestConfig.PegRxCemNonProtocolAwareness = (UINT8) PciePeiPreMemConfig->PegRxCemNonProtocolAwareness;
+    FspmUpd->FspmTestConfig.PegGen3RxCtleOverride = (UINT8) PciePeiPreMemConfig->PegGen3RxCtleOverride;
+    for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+      FspmUpd->FspmTestConfig.PegGen3RootPortPreset[Index] = PciePeiPreMemConfig->PegGen3RootPortPreset[Index];
+      FspmUpd->FspmTestConfig.PegGen3EndPointPreset[Index] = PciePeiPreMemConfig->PegGen3EndPointPreset[Index];
+      FspmUpd->FspmTestConfig.PegGen3EndPointHint[Index] = PciePeiPreMemConfig->PegGen3EndPointHint[Index];
+    }
+    FspmUpd->FspmTestConfig.Gen3SwEqJitterDwellTime = PciePeiPreMemConfig->Gen3SwEqJitterDwellTime;
+    FspmUpd->FspmTestConfig.Gen3SwEqJitterErrorTarget = PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget;
+    FspmUpd->FspmTestConfig.Gen3SwEqVocDwellTime = PciePeiPreMemConfig->Gen3SwEqVocDwellTime;
+    FspmUpd->FspmTestConfig.Gen3SwEqVocErrorTarget = PciePeiPreMemConfig->Gen3SwEqVocErrorTarget;
+  }
+
+  if (GtPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.PrimaryDisplay = (UINT8) GtPreMemConfig->PrimaryDisplay;
+    FspmUpd->FspmConfig.InternalGfx = (UINT8) GtPreMemConfig->InternalGraphics;
+    FspmUpd->FspmConfig.IgdDvmt50PreAlloc = (UINT8) GtPreMemConfig->IgdDvmt50PreAlloc;
+    FspmUpd->FspmConfig.ApertureSize = (UINT8) GtPreMemConfig->ApertureSize;
+    FspmUpd->FspmConfig.GttMmAdr = GtPreMemConfig->GttMmAdr;
+    FspmUpd->FspmConfig.GmAdr = GtPreMemConfig->GmAdr;
+    FspmUpd->FspmConfig.GttSize = GtPreMemConfig->GttSize;
+    FspmUpd->FspmConfig.PsmiRegionSize = (UINT8) GtPreMemConfig->PsmiRegionSize;
+    FspmUpd->FspmConfig.GtPsmiSupport = (UINT8)GtPreMemConfig->GtPsmiSupport;
+    FspmUpd->FspmTestConfig.PanelPowerEnable = (UINT8) GtPreMemConfig->PanelPowerEnable;
+    FspmUpd->FspmTestConfig.DeltaT12PowerCycleDelayPreMem = (UINT16) GtPreMemConfig->DeltaT12PowerCycleDelayPreMem;
+  }
+
+  if (SgGpioData != NULL) {
+    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie0Gpio, &SgGpioData->SaRtd3Pcie0Gpio, sizeof (SA_PCIE_RTD3_GPIO));
+    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie1Gpio, &SgGpioData->SaRtd3Pcie1Gpio, sizeof (SA_PCIE_RTD3_GPIO));
+    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie2Gpio, &SgGpioData->SaRtd3Pcie2Gpio, sizeof (SA_PCIE_RTD3_GPIO));
+    FspmUpd->FspmConfig.RootPortIndex = SgGpioData->RootPortIndex;
+  }
+
+  if (IpuPreMemPolicy != NULL) {
+    FspmUpd->FspmConfig.SaIpuEnable = (UINT8) IpuPreMemPolicy->SaIpuEnable;
+    FspmUpd->FspmConfig.SaIpuImrConfiguration = (UINT8) IpuPreMemPolicy->SaIpuImrConfiguration;
+  }
+
+  if (OcPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.SaOcSupport = (UINT8) OcPreMemConfig->OcSupport;
+    FspmUpd->FspmConfig.RealtimeMemoryTiming = (UINT8) OcPreMemConfig->RealtimeMemoryTiming;
+    FspmUpd->FspmConfig.GtVoltageMode = (UINT8) OcPreMemConfig->GtVoltageMode;
+    FspmUpd->FspmConfig.GtMaxOcRatio = OcPreMemConfig->GtMaxOcRatio;
+    FspmUpd->FspmConfig.GtVoltageOffset = OcPreMemConfig->GtVoltageOffset;
+    FspmUpd->FspmConfig.GtVoltageOverride = OcPreMemConfig->GtVoltageOverride;
+    FspmUpd->FspmConfig.GtExtraTurboVoltage = OcPreMemConfig->GtExtraTurboVoltage;
+    FspmUpd->FspmConfig.SaVoltageOffset = OcPreMemConfig->SaVoltageOffset;
+    FspmUpd->FspmConfig.GtusMaxOcRatio = OcPreMemConfig->GtusMaxOcRatio;
+    FspmUpd->FspmConfig.GtusVoltageMode = (UINT8) OcPreMemConfig->GtusVoltageMode;
+    FspmUpd->FspmConfig.GtusVoltageOffset = OcPreMemConfig->GtusVoltageOffset;
+    FspmUpd->FspmConfig.GtusVoltageOverride = OcPreMemConfig->GtusVoltageOverride;
+    FspmUpd->FspmConfig.GtusExtraTurboVoltage = OcPreMemConfig->GtusExtraTurboVoltage;
+  }
+
+
+
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs FSP SA PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_POLICY_PPI             *SiPolicyPpi;
+  SA_MISC_PEI_CONFIG        *MiscPeiConfig;
+  GRAPHICS_PEI_CONFIG       *GtConfig;
+  PCIE_PEI_CONFIG           *PciePeiConfig;
+  GNA_CONFIG                *GnaConfig;
+  UINT8                     Index;
+  EFI_BOOT_MODE             BootMode;
+
+  MiscPeiConfig = NULL;
+  GtConfig      = NULL;
+  PciePeiConfig = NULL;
+  GnaConfig     = NULL;
+
+  //
+  // @todo This could be cleared up after FSP provides ExitBootServices NotifyPhase.
+  //
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate SiPolicyPpi
+  //
+  SiPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi(
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **)&SiPolicyPpi
+             );
+  if ((Status == EFI_SUCCESS) && (SiPolicyPpi != NULL)) {
+    MiscPeiConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid, (VOID *) &MiscPeiConfig);
+    ASSERT_EFI_ERROR (Status);
+
+    GtConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *) &GtConfig);
+    ASSERT_EFI_ERROR (Status);
+
+    GnaConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGnaConfigGuid, (VOID *) &GnaConfig);
+    ASSERT_EFI_ERROR (Status);
+
+    PciePeiConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID *) &PciePeiConfig);
+    ASSERT_EFI_ERROR (Status);
+
+  }
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Wrapper UpdatePeiSaPolicy\n"));
+
+
+  if (MiscPeiConfig != NULL) {
+    FspsUpd->FspsConfig.Device4Enable = (UINT8) MiscPeiConfig->Device4Enable;
+    FspsUpd->FspsConfig.CridEnable = (UINT8) MiscPeiConfig->CridEnable;
+    FspsUpd->FspsTestConfig.ChapDeviceEnable = (UINT8) MiscPeiConfig->ChapDeviceEnable;
+    FspsUpd->FspsTestConfig.SkipPamLock = (UINT8) MiscPeiConfig->SkipPamLock;
+    FspsUpd->FspsTestConfig.EdramTestMode = (UINT8) MiscPeiConfig->EdramTestMode;
+  }
+
+  if (PciePeiConfig != NULL) {
+    FspsUpd->FspsConfig.DmiAspm = (UINT8) PciePeiConfig->DmiAspm;
+    FspsUpd->FspsTestConfig.DmiExtSync = (UINT8) PciePeiConfig->DmiExtSync;
+    FspsUpd->FspsTestConfig.DmiIot = (UINT8) PciePeiConfig->DmiIot;
+    for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+      FspsUpd->FspsConfig.PegDeEmphasis[Index] = PciePeiConfig->PegDeEmphasis[Index];
+      FspsUpd->FspsConfig.PegSlotPowerLimitValue[Index] = PciePeiConfig->PegSlotPowerLimitValue[Index];
+      FspsUpd->FspsConfig.PegSlotPowerLimitScale[Index] = PciePeiConfig->PegSlotPowerLimitScale[Index];
+      FspsUpd->FspsConfig.PegPhysicalSlotNumber[Index] = PciePeiConfig->PegPhysicalSlotNumber[Index];
+      FspsUpd->FspsTestConfig.PegMaxPayload[Index] = PciePeiConfig->PegMaxPayload[Index];
+    }
+  }
+
+  if (GtConfig != NULL) {
+    FspsUpd->FspsConfig.PavpEnable = (UINT8) GtConfig->PavpEnable;
+    FspsUpd->FspsConfig.CdClock = (UINT8) GtConfig->CdClock;
+    FspsUpd->FspsTestConfig.RenderStandby = (UINT8) GtConfig->RenderStandby;
+    FspsUpd->FspsTestConfig.PmSupport = (UINT8) GtConfig->PmSupport;
+    FspsUpd->FspsTestConfig.CdynmaxClampEnable = (UINT8) GtConfig->CdynmaxClampEnable;
+    FspsUpd->FspsTestConfig.GtFreqMax = (UINT8) GtConfig->GtFreqMax;
+    FspsUpd->FspsTestConfig.DisableTurboGt = (UINT8) GtConfig->DisableTurboGt;
+    FspsUpd->FspsConfig.SkipS3CdClockInit = (UINT8)GtConfig->SkipS3CdClockInit;
+
+    //
+    // For FSP, FspsUpd->FspsConfig.PeiGraphicsPeimInit is always enabled as default.
+    //
+    FspsUpd->FspsConfig.PeiGraphicsPeimInit = (UINT8) GtConfig->PeiGraphicsPeimInit; // SA: InternalOnly: For Internal validation we still need to enable both Enable/Disable Cases
+
+    //
+    // Update UPD: VBT & LogoPtr
+    //
+    if (BootMode == BOOT_ON_S3_RESUME) {
+      FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) NULL;
+    } else {
+      FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) GtConfig->GraphicsConfigPtr;
+    }
+    DEBUG(( DEBUG_INFO, "VbtPtr from GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.GraphicsConfigPtr));
+
+    FspsUpd->FspsConfig.LogoPtr  = (UINT32) GtConfig->LogoPtr;
+    FspsUpd->FspsConfig.LogoSize = GtConfig->LogoSize;
+    DEBUG(( DEBUG_INFO, "LogoPtr from PeiFspSaPolicyInit GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoPtr));
+    DEBUG(( DEBUG_INFO, "LogoSize from PeiFspSaPolicyInit GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoSize));
+
+    FspsUpd->FspsConfig.BltBufferAddress  = (UINT32) GtConfig->BltBufferAddress;
+    FspsUpd->FspsConfig.BltBufferSize     = (UINT32) GtConfig->BltBufferSize;
+
+    //
+    // Update DDI/DDC configuration
+    //
+    FspsUpd->FspsConfig.DdiPortEdp = GtConfig->DdiConfiguration.DdiPortEdp;
+    FspsUpd->FspsConfig.DdiPortBHpd = GtConfig->DdiConfiguration.DdiPortBHpd;
+    FspsUpd->FspsConfig.DdiPortCHpd = GtConfig->DdiConfiguration.DdiPortCHpd;
+    FspsUpd->FspsConfig.DdiPortDHpd = GtConfig->DdiConfiguration.DdiPortDHpd;
+    FspsUpd->FspsConfig.DdiPortFHpd = GtConfig->DdiConfiguration.DdiPortFHpd;
+    FspsUpd->FspsConfig.DdiPortBDdc = GtConfig->DdiConfiguration.DdiPortBDdc;
+    FspsUpd->FspsConfig.DdiPortCDdc = GtConfig->DdiConfiguration.DdiPortCDdc;
+    FspsUpd->FspsConfig.DdiPortDDdc = GtConfig->DdiConfiguration.DdiPortDDdc;
+    FspsUpd->FspsConfig.DdiPortFDdc = GtConfig->DdiConfiguration.DdiPortFDdc;
+
+  }
+
+  if (GnaConfig != NULL) {
+    FspsUpd->FspsConfig.GnaEnable = (UINT8) GnaConfig->GnaEnable;
+#ifdef TESTMENU_FLAG
+#endif // TESTMENU_FLAG
+  }
+
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c
new file mode 100644
index 0000000000..80d20d74a9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c
@@ -0,0 +1,70 @@
+/** @file
+  Implementation of Fsp Security Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SiPolicy.h>
+
+/**
+  Performs FSP Security PEI Policy initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                    Status;
+  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi;
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SecurityPolicy Pre-Mem Start\n"));
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  SiPreMemPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SecurityPolicy Pre-Mem End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP Security PEI Policy post memory initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
new file mode 100644
index 0000000000..98658782aa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
@@ -0,0 +1,95 @@
+/** @file
+  Implementation of Fsp SI Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Ppi/SiPolicy.h>
+
+/**
+  Performs FSP SI PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi;
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  SiPreMemPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP SI PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                   Status;
+  SI_POLICY_PPI                *SiPolicy;
+  SI_CONFIG                    *SiConfig;
+
+  //
+  // Locate SiPolicyPpi
+  //
+  SiPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update SiConfig policies
+  //
+  FspsUpd->FspsConfig.SiCsmFlag                = (UINT8)SiConfig->CsmFlag;
+  FspsUpd->FspsConfig.SiSsidTablePtr           = (UINT32)(UINTN)SiConfig->SsidTablePtr;
+  FspsUpd->FspsConfig.SiNumberOfSsidTableEntry = (UINT16)SiConfig->NumberOfSsidTableEntry;
+  FspsUpd->FspsConfig.TraceHubMemBase          =  SiConfig->TraceHubMemBase;
+
+  return EFI_SUCCESS;
+}
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
new file mode 100644
index 0000000000..a341a58930
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
@@ -0,0 +1,100 @@
+/** @file
+  Implementation of Fsp Misc UPD Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeiLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PeiServicesLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/PciLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <PchAccess.h>
+
+#include "PeiMiscPolicyUpdate.h"
+
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in,out]    FspmUpd                 Pointer to FSPM_UPD Data.
+
+  @retval           EFI_SUCCESS             FSP UPD Data is updated.
+  @retval           EFI_NOT_FOUND           An instance of gEfiPeiReadOnlyVariable2PpiGuid
+                                            could not be located.
+  @retval           EFI_OUT_OF_RESOURCES    Insufficent resources to allocate a memory buffer.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariableServices;
+  UINTN                             VariableSize;
+  VOID                              *MemorySavedData;
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,
+             0,
+             NULL,
+             (VOID **) &VariableServices
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  VariableSize = 0;
+  MemorySavedData = NULL;
+  Status = VariableServices->GetVariable (
+                               VariableServices,
+                               L"MemoryConfig",
+                               &gFspNonVolatileStorageHobGuid,
+                               NULL,
+                               &VariableSize,
+                               MemorySavedData
+                               );
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    MemorySavedData = AllocatePool (VariableSize);
+    if (MemorySavedData == NULL) {
+      ASSERT (MemorySavedData != NULL);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    DEBUG ((DEBUG_INFO, "VariableSize is 0x%x\n", VariableSize));
+    Status = VariableServices->GetVariable (
+                                 VariableServices,
+                                 L"MemoryConfig",
+                                 &gFspNonVolatileStorageHobGuid,
+                                 NULL,
+                                 &VariableSize,
+                                 MemorySavedData
+                                 );
+    if (Status == EFI_SUCCESS) {
+      FspmUpd->FspmArchUpd.NvsBufferPtr = MemorySavedData;
+    } else {
+      DEBUG ((DEBUG_ERROR, "Fail to retrieve Variable:\"MemoryConfig\" gMemoryConfigVariableGuid, Status = %r\n", Status));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+  FspmUpd->FspmArchUpd.NvsBufferPtr = MemorySavedData;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
new file mode 100644
index 0000000000..5119e934a2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
@@ -0,0 +1,124 @@
+/** @file
+  Provide FSP wrapper platform related function.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/SiliconPolicyUpdateLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#include "PeiMiscPolicyUpdate.h"
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyUpdate (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+VOID
+InternalPrintVariableData (
+  IN UINT8   *Data8,
+  IN UINTN   DataSize
+  )
+{
+  UINTN      Index;
+
+  for (Index = 0; Index < DataSize; Index++) {
+    if (Index % 0x10 == 0) {
+      DEBUG ((DEBUG_INFO, "\n%08X:", Index));
+    }
+    DEBUG ((DEBUG_INFO, " %02X", *Data8++));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+/**
+  Performs silicon pre-mem policy update.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+
+  The input Policy must be returned by SiliconPolicyDonePreMem().
+
+  1) In FSP path, the input Policy should be FspmUpd.
+  A platform may use this API to update the FSPM UPD policy initialized
+  by the silicon module or the default UPD data.
+  The output of FSPM UPD data from this API is the final UPD data.
+
+  2) In non-FSP path, the board may use additional way to get
+  the silicon policy data field based upon the input Policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePreMem (
+  IN OUT VOID    *FspmUpd
+  )
+{
+  FSPM_UPD              *FspmUpdDataPtr;
+
+  FspmUpdDataPtr = FspmUpd;
+
+  PeiFspMiscUpdUpdatePreMem (FspmUpdDataPtr);
+  InternalPrintVariableData ((VOID *) FspmUpdDataPtr, sizeof (FSPM_UPD));
+
+  return FspmUpd;
+}
+
+/**
+  Performs silicon post-mem policy update.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+
+  The input Policy must be returned by SiliconPolicyDonePostMem().
+
+  1) In FSP path, the input Policy should be FspsUpd.
+  A platform may use this API to update the FSPS UPD policy initialized
+  by the silicon module or the default UPD data.
+  The output of FSPS UPD data from this API is the final UPD data.
+
+  2) In non-FSP path, the board may use additional way to get
+  the silicon policy data field based upon the input Policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePostMem (
+  IN OUT VOID    *FspsUpd
+  )
+{
+  FSPS_UPD              *FspsUpdDataPtr;
+
+  FspsUpdDataPtr = FspsUpd;
+
+  PeiFspPchPolicyUpdate (FspsUpd);
+  InternalPrintVariableData ((VOID * )FspsUpdDataPtr, sizeof (FSPS_UPD));
+
+  return FspsUpd;
+}
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c
new file mode 100644
index 0000000000..455467dc25
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/PchGbeLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchHsioLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <GpioConfig.h>
+#include <GpioPinsSklH.h>
+#include <Library/DebugLib.h>
+#include <Library/PchGbeLib.h>
+#include <PcieDeviceOverrideTable.h>
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyUpdate (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  FspsUpd->FspsConfig.PchPcieDeviceOverrideTablePtr = (UINT32) mPcieDeviceTable;
+
+  AddPlatformVerbTables (
+    PchHdaCodecPlatformOnboard,
+    &(FspsUpd->FspsConfig.PchHdaVerbTableEntryNum),
+    &(FspsUpd->FspsConfig.PchHdaVerbTablePtr)
+    );
+
+DEBUG_CODE_BEGIN();
+if ((PcdGet8 (PcdSerialIoUartDebugEnable) == 1) &&
+      FspsUpd->FspsConfig.SerialIoDevMode[PchSerialIoIndexUart0 + PcdGet8 (PcdSerialIoUartNumber)] == PchSerialIoDisabled ) {
+    FspsUpd->FspsConfig.SerialIoDevMode[PchSerialIoIndexUart0 + PcdGet8 (PcdSerialIoUartNumber)] = PchSerialIoHidden;
+  }
+DEBUG_CODE_END();
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..cbb818c875
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
@@ -0,0 +1,39 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchHsioLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <PchHsioPtssTables.h>
+#include <Library/DebugLib.h>
+
+/**
+  Performs FSP PCH PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c
new file mode 100644
index 0000000000..2114479030
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c
@@ -0,0 +1,85 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <Guid/MemoryTypeInformation.h>
+#include <Library/HobLib.h>
+#include <PchAccess.h>
+#include <SaAccess.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/PeiLib.h>
+
+/**
+  Performs FSP SA PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyUpdate (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  VOID                            *Buffer;
+  VOID                            *MemBuffer;
+  UINT32                          Size;
+
+  DEBUG((DEBUG_INFO, "\nUpdating SA Policy in Post Mem\n"));
+
+    FspsUpd->FspsConfig.PeiGraphicsPeimInit = 1;
+
+    Size   = 0;
+    Buffer = NULL;
+    PeiGetSectionFromAnyFv (PcdGetPtr (PcdGraphicsVbtGuid), EFI_SECTION_RAW, 0, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_WARN, "Could not locate VBT\n"));
+    } else {
+      MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+      if ((MemBuffer != NULL) && (Buffer != NULL)) {
+        CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+        FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32)(UINTN)MemBuffer;
+      } else {
+        DEBUG((DEBUG_WARN, "Error in locating / copying VBT.\n"));
+        FspsUpd->FspsConfig.GraphicsConfigPtr = 0;
+      }
+    }
+    DEBUG((DEBUG_INFO, "Vbt Pointer from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.GraphicsConfigPtr));
+    DEBUG((DEBUG_INFO, "Vbt Size from PeiGetSectionFromFv is 0x%x\n", Size));
+
+    Size   = 0;
+    Buffer = NULL;
+    PeiGetSectionFromAnyFv (&gTianoLogoGuid, EFI_SECTION_RAW, 0, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_WARN, "Could not locate Logo\n"));
+    } else {
+      MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+      if ((MemBuffer != NULL) && (Buffer != NULL)) {
+        CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+        FspsUpd->FspsConfig.LogoPtr = (UINT32)(UINTN)MemBuffer;
+        FspsUpd->FspsConfig.LogoSize = Size;
+      } else {
+        DEBUG((DEBUG_WARN, "Error in locating / copying LogoPtr.\n"));
+        FspsUpd->FspsConfig.LogoPtr = 0;
+        FspsUpd->FspsConfig.LogoSize = 0;
+      }
+    }
+    DEBUG((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.LogoPtr));
+    DEBUG((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.LogoSize));
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..946182864e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
@@ -0,0 +1,87 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Library/HobLib.h>
+#include <PchAccess.h>
+#include <SaAccess.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklH.h>
+
+
+/**
+  Performs FSP SA PEI Policy initialization in pre-memory.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  VOID                        *Buffer;
+
+  //
+  // If SpdAddressTable are not all 0, it means DIMM slots implemented and
+  // MemorySpdPtr* already updated by reading SPD from DIMM in SiliconPolicyInitPreMem.
+  //
+  // If SpdAddressTable all 0, this is memory down design and hardcoded SpdData
+  // should be applied to MemorySpdPtr*.
+  //
+  if ((PcdGet8 (PcdMrcSpdAddressTable0) == 0) && (PcdGet8 (PcdMrcSpdAddressTable1) == 0)
+      && (PcdGet8 (PcdMrcSpdAddressTable2) == 0) && (PcdGet8 (PcdMrcSpdAddressTable3) == 0)) {
+    DEBUG ((DEBUG_INFO, "Overriding SPD data for down memory.\n"));
+    CopyMem (
+      (VOID *) (UINTN) FspmUpd->FspmConfig.MemorySpdPtr00,
+      (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData),
+      PcdGet16 (PcdMrcSpdDataSize)
+      );
+    CopyMem (
+      (VOID *) (UINTN) FspmUpd->FspmConfig.MemorySpdPtr10,
+      (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData),
+      PcdGet16 (PcdMrcSpdDataSize)
+      );
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Byte Map and DQS Byte Swizzling Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh0, Buffer, 12);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh1, (UINT8*) Buffer + 12, 12);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh0, Buffer, 8);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh1, (UINT8*) Buffer + 8, 8);
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Pins Interleaved,Rcomp Resistor & Rcomp Target Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompResistor, Buffer, 6);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompTarget, Buffer, 10);
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
new file mode 100644
index 0000000000..a767289bc5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
@@ -0,0 +1,163 @@
+/** @file
+  Provide FSP wrapper platform sec related function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/TopOfTemporaryRam.h>
+#include <Guid/FirmwareFileSystem2.h>
+
+#include <Library/LocalApicLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param[in]     PeiServices               Pointer to the PEI Services Table.
+  @param[in,out] StructureSize             Pointer to the variable describing size of the input buffer.
+  @param[out]    PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  );
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval EFI_SUCCESS  The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  );
+
+PEI_SEC_PERFORMANCE_PPI  mSecPerformancePpi = {
+  SecGetPerformance
+};
+
+EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gTopOfTemporaryRamPpiGuid,
+    NULL // To be patched later.
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gPeiSecPerformancePpiGuid,
+    &mSecPerformancePpi
+  },
+};
+
+#define LEGACY_8259_MASK_REGISTER_MASTER                  0x21
+#define LEGACY_8259_MASK_REGISTER_SLAVE                   0xA1
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER  0x4D0
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE   0x4D1
+
+/**
+  Write to mask and edge/level triggered registers of master and slave 8259 PICs.
+
+  @param[in]  Mask       low byte for master PIC mask register,
+                         high byte for slave PIC mask register.
+  @param[in]  EdgeLevel  low byte for master PIC edge/level triggered register,
+                         high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259WriteMask (
+  IN UINT16  Mask,
+  IN UINT16  EdgeLevel
+  )
+{
+  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, (UINT8) Mask);
+  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8) (Mask >> 8));
+  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8) EdgeLevel);
+  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8) (EdgeLevel >> 8));
+}
+
+/**
+  A developer supplied function to perform platform specific operations.
+
+  It's a developer supplied function to perform any operations appropriate to a
+  given platform. It's invoked just before passing control to PEI core by SEC
+  core. Platform developer may modify the SecCoreData passed to PEI Core.
+  It returns a platform specific PPI list that platform wishes to pass to PEI core.
+  The Generic SEC core module will merge this list to join the final list passed to
+  PEI core.
+
+  @param[in,out] SecCoreData           The same parameter as passing to PEI core. It
+                                       could be overridden by this function.
+
+  @return The platform specific PPI list to be passed to PEI core or
+          NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
+  )
+{
+  EFI_PEI_PPI_DESCRIPTOR      *PpiList;
+
+  DEBUG ((DEBUG_INFO, "FSP Wrapper BootFirmwareVolumeBase - 0x%x\n", SecCoreData->BootFirmwareVolumeBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper BootFirmwareVolumeSize - 0x%x\n", SecCoreData->BootFirmwareVolumeSize));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper TemporaryRamBase       - 0x%x\n", SecCoreData->TemporaryRamBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper TemporaryRamSize       - 0x%x\n", SecCoreData->TemporaryRamSize));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper PeiTemporaryRamBase    - 0x%x\n", SecCoreData->PeiTemporaryRamBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper PeiTemporaryRamSize    - 0x%x\n", SecCoreData->PeiTemporaryRamSize));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper StackBase              - 0x%x\n", SecCoreData->StackBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper StackSize              - 0x%x\n", SecCoreData->StackSize));
+
+  InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
+
+  //
+  // Set all 8259 interrupts to edge triggered and disabled
+  //
+  Interrupt8259WriteMask (0xFFFF, 0x0000);
+
+  //
+  // Use middle of Heap as temp buffer, it will be copied by caller.
+  // Do not use Stack, because it will cause wrong calculation on stack by PeiCore
+  //
+  PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize/2);
+  CopyMem (PpiList, mPeiSecPlatformPpi, sizeof(mPeiSecPlatformPpi));
+
+  //
+  // Patch TopOfTemporaryRamPpi
+  //
+  PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize);
+
+  return PpiList;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c
new file mode 100644
index 0000000000..06ca63c19a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c
@@ -0,0 +1,54 @@
+/** @file
+  Provide platform init function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/SecBoardInitLib.h>
+#include <Library/TestPointCheckLib.h>
+#include <Register/PchRegsPmc.h>
+#include <Library/IoLib.h>
+
+/**
+  Platform initialization.
+
+  @param[in] FspHobList   HobList produced by FSP.
+  @param[in] StartOfRange Start of temporary RAM.
+  @param[in] EndOfRange   End of temporary RAM.
+**/
+VOID
+EFIAPI
+PlatformInit (
+  IN VOID                 *FspHobList,
+  IN VOID                 *StartOfRange,
+  IN VOID                 *EndOfRange
+  )
+{
+  ///
+  /// Halt the TCO timer as early as possible
+  ///
+  IoWrite16 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO1_CNT, B_TCO_IO_TCO1_CNT_TMR_HLT);
+
+  //
+  // Platform initialization
+  // Enable Serial port here
+  //
+  if (PcdGetBool(PcdSecSerialPortDebugEnable)) {
+    SerialPortInitialize ();
+  }
+
+  DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in PlatformInit\n"));
+  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
+  DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
+  DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
+
+  BoardAfterTempRamInit ();
+
+  TestPointTempMemoryFunction (StartOfRange, EndOfRange);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c
new file mode 100644
index 0000000000..67bdd232bb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c
@@ -0,0 +1,90 @@
+/** @file
+  Sample to provide SecGetPerformance function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPerformance.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval EFI_SUCCESS  The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  )
+{
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  UINT64      Ticker;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // |--------------| <- TopOfTemporaryRam - BL
+  // |   List Ptr   |
+  // |--------------|
+  // | BL RAM Start |
+  // |--------------|
+  // |  BL RAM End  |
+  // |--------------|
+  // |Number of BSPs|
+  // |--------------|
+  // |     BIST     |
+  // |--------------|
+  // |     ....     |
+  // |--------------|
+  // |  TSC[63:32]  |
+  // |--------------|
+  // |  TSC[31:00]  |
+  // |--------------|
+  //
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  Count             = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));
+  Size              = Count * sizeof (UINT32);
+
+  Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2);
+  Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
new file mode 100644
index 0000000000..e05daa8784
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
@@ -0,0 +1,79 @@
+/** @file
+  Provide SecPlatformInformation function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param[in]     PeiServices               Pointer to the PEI Services Table.
+  @param[in,out] StructureSize             Pointer to the variable describing size of the input buffer.
+  @param[out]    PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  )
+{
+  UINT32      *Bist;
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // The entries of BIST information, together with the number of them,
+  // reside in the bottom of stack, left untouched by normal stack operation.
+  // This routine copies the BIST information to the buffer pointed by
+  // PlatformInformationRecord for output.
+  //
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  Count             = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32)));
+  Size              = Count * sizeof (IA32_HANDOFF_STATUS);
+
+  if ((*StructureSize) < (UINT64) Size) {
+    *StructureSize = Size;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *StructureSize  = Size;
+  Bist            = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);
+
+  CopyMem (PlatformInformationRecord, Bist, Size);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c
new file mode 100644
index 0000000000..04f12a9438
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c
@@ -0,0 +1,37 @@
+/** @file
+  Provide TempRamInitParams data.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/PcdLib.h>
+#include <FspEas.h>
+#include "FsptCoreUpd.h"
+
+typedef struct {
+  FSP_UPD_HEADER    FspUpdHeader;
+  FSPT_CORE_UPD     FsptCoreUpd;
+} FSPT_UPD_CORE_DATA;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA FsptUpdDataPtr = {
+  {
+    0x4450555F54505346,
+    0x00,
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+  },
+  {
+    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicrocodeOffset)),
+    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicrocodeOffset)),
+    0,          // Set CodeRegionBase as 0, so that caching will be 4GB-(CodeRegionSize > LLCSize ? LLCSize : CodeRegionSize) will be used.
+    FixedPcdGet32 (PcdFlashCodeCacheSize),
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+  }
+};
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c
new file mode 100644
index 0000000000..6d65d7d23f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c
@@ -0,0 +1,48 @@
+/** @file
+  Provide SecTemporaryRamDone function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/TemporaryRamDone.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/FspWrapperPlatformLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/BoardInitLib.h>
+
+/**
+This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *TempRamExitParam;
+
+  DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n"));
+
+  Status = BoardInitBeforeTempRamExit ();
+  ASSERT_EFI_ERROR (Status);
+
+  TempRamExitParam = UpdateTempRamExitParam ();
+  Status = CallTempRamExit (TempRamExitParam);
+  DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
+  ASSERT_EFI_ERROR(Status);
+
+  Status = BoardInitAfterTempRamExit ();
+  ASSERT_EFI_ERROR (Status);
+
+  return ;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
new file mode 100644
index 0000000000..7bdb3943e5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
@@ -0,0 +1,48 @@
+/** @file
+  ACPI Timer implements one instance of Timer Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+
+/**
+  Calculate TSC frequency.
+
+  The TSC counting frequency is determined by comparing how far it counts
+  during a 101.4 us period as determined by the ACPI timer.
+  The ACPI timer is used because it counts at a known frequency.
+  The TSC is sampled, followed by waiting 363 counts of the ACPI timer,
+  or 101.4 us. The TSC is then sampled again. The difference multiplied by
+  9861 is the TSC frequency. There will be a small error because of the
+  overhead of reading the ACPI timer. An attempt is made to determine and
+  compensate for this error.
+
+  @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+  VOID
+  );
+
+/**
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+InternalGetPerformanceCounterFrequency (
+  VOID
+  )
+{
+  return InternalCalculateTscFrequency ();
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
new file mode 100644
index 0000000000..8498952888
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
@@ -0,0 +1,310 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/GpioExpanderLib.h>
+#include <Library/I2cAccessLib.h>
+
+//
+// Addresses of registers inside expander
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mInputRegister[3]    = {0x0,0x1,0x2};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mOutputRegister[3]   = {0x4,0x5,0x6};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mConfigRegister[3]   = {0xC,0xD,0xE};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mPolarityRegister[3] = {0x8,0x9,0xA};
+
+#define PCH_SERIAL_IO_I2C4                 4
+#define TCA6424_I2C_ADDRESS 0x22
+#define PINS_PER_REGISTER                  8
+#define GPIO_EXP_PIN_DIRECTION_OUT         1
+#define GPIO_EXP_PIN_DIRECTION_IN          0
+#define GPIO_EXP_PIN_POLARITY_NORMAL       0
+#define GPIO_EXP_PIN_POLARITY_INVERTED     1
+#define GPIO_EXP_SET_OUTPUT                0
+#define GPIO_EXP_SET_DIR                   1
+#define GPIO_EXP_GET_INPUT                 2
+#define GPIO_EXP_SET_POLARITY              3
+#define AUTO_INCREMENT 0x80
+
+/**
+  Returns the Controller on which GPIO expander is present.
+
+  This function returns the Controller value
+
+  @param[out] Controller              Pointer to a Controller value on
+                                      which I2C expander is configured.
+
+  @retval     EFI_SUCCESS              non.
+**/
+EFI_STATUS
+GpioExpGetController (
+  OUT UINT8 *Controller
+  )
+{
+  *Controller = PCH_SERIAL_IO_I2C4;
+  return EFI_SUCCESS;
+}
+
+/**
+  Returns the data from register value giving in the input.
+
+  This function is to get the data from the Expander
+  Registers by following the I2C Protocol communication
+
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+
+  @retval     UINT8      Value returned from the register
+**/
+UINT8
+GpioExpGetRegister (
+  IN UINTN Bar0,
+  IN UINT8 Address,
+  IN UINT8 Register
+  )
+{
+  EFI_STATUS Status;
+  UINT8 WriBuf[1];
+  UINT8 ReBuf[1] = {0};
+
+  WriBuf[0] = Register;
+  Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 1, WriBuf, 1, ReBuf, WAIT_1_SECOND);
+
+  return ReBuf[0];
+}
+/**
+  Set the input register to a give value mentioned in the function.
+
+  This function is to Programm the data value to the Expander
+  Register by following the I2C Protocol communication.
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+  @param[in]  Value      Value to set in the mentioned the register
+**/
+VOID
+GpioExpSetRegister (
+  IN UINTN Bar0,
+  IN UINT8 Address,
+  IN UINT8 Register,
+  IN UINT8 Value
+  )
+{
+  EFI_STATUS Status;
+  UINT8 WriBuf[2];
+
+  WriBuf[0] = Register;
+  WriBuf[1] = Value;
+  Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 2, WriBuf, 0, NULL, WAIT_1_SECOND);
+
+}
+/**
+  Set the input register to a give value mentioned in the function.
+
+  This function is to update the status of the Gpio Expander
+  pin based on the input Operation value of the caller.This
+  function calculates the exact address of the register with
+  the help of the Register Bank
+
+  @param[in]  Controller  SerialIo Controller value
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+  @param[in]  Operation   Type of operation (Setoutput/Setdirection
+                          /Getinput/Setpolarity)
+  @retval     UINT8       Final Value returned from the register
+**/
+UINT8
+GpioExpDecodeRegAccess (
+  IN UINT8 Controller,
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value,
+  IN UINT8 Operation
+  )
+{
+  UINT8* RegisterBank;
+  UINT8 OldValue;
+  UINT8 NewValue;
+  UINT8 RegisterAddress;
+  UINT8 PinNumber;
+  UINT8 ReturnValue = 0;
+
+  DEBUG ((DEBUG_INFO, "GpioExpDecodeRegAccess() %x:%x:%x:%x:%x\n", Controller, Expander, Pin, Value, Operation));
+  ASSERT(Controller<6);
+  ASSERT(Expander<2);
+  ASSERT(Pin<24);
+  ASSERT(Value<2);
+  ASSERT(Operation<4);
+  //
+  // Find the register Address value based on the OPeration
+  //
+  switch(Operation) {
+    case GPIO_EXP_SET_OUTPUT:
+      RegisterBank = mOutputRegister;
+      break;
+    case GPIO_EXP_SET_DIR:
+      RegisterBank = mConfigRegister;
+      break;
+    case GPIO_EXP_GET_INPUT:
+      RegisterBank = mInputRegister;
+      break;
+    case GPIO_EXP_SET_POLARITY:
+      RegisterBank = mPolarityRegister;
+      break;
+    default:
+      ASSERT(FALSE);
+      return 0;
+    }
+  //
+  // Each bit of register represents each Pin
+  // calaulate the register address and Pinnumber(offset with in register)
+  //
+  if (Pin >= 24) {
+    //
+    // Avoid out-of-bound usage of RegisterBank
+    //
+    return 0;
+  }
+
+  RegisterAddress = RegisterBank[(Pin/PINS_PER_REGISTER)];
+  PinNumber = Pin%PINS_PER_REGISTER;
+
+  OldValue = GpioExpGetRegister(FindSerialIoBar(Controller, 0), Expander, RegisterAddress);
+  //
+  // If it to get the data ,just returned otherwise mark the input value and write the register
+  //
+  if (Operation == GPIO_EXP_GET_INPUT) {
+    ReturnValue = 0x1 & (OldValue>>PinNumber);
+  } else {
+    NewValue = OldValue;
+    NewValue &= ~(BIT0<<PinNumber);
+    NewValue |= (Value<<PinNumber);
+    if(NewValue!=OldValue) {
+      GpioExpSetRegister(FindSerialIoBar(Controller, 0), Expander, RegisterAddress, NewValue);
+    }
+  }
+  return ReturnValue;
+}
+/**
+  Set the Output value for the given Expander Gpio pin.
+
+  This function is to Set the Output value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetOutput (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  )
+{
+  UINT8 Controller;
+  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+    GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_OUTPUT);
+  }
+}
+/**
+  Set the Direction value for the given Expander Gpio pin.
+
+  This function is to Set the direction value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+**/
+VOID
+GpioExpSetDirection (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  )
+{
+
+  UINT8 Controller;
+  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+    GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_DIR);
+  }
+}
+
+
+/**
+  Get the input value for the given Expander Gpio pin.
+
+  This function is to get the input value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+
+  @retval     UINT8       Final Value returned from the register
+**/
+UINT8
+GpioExpGetInput (
+  IN UINT8 Expander,
+  IN UINT8 Pin
+  )
+{
+  UINT8 Controller;
+  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+    return GpioExpDecodeRegAccess(Controller,Expander,Pin,0,GPIO_EXP_GET_INPUT);
+  }
+  return 0;
+}
+
+/**
+  Configures all registers of a single IO Expander in one go.
+
+  @param[in]  Expander    Expander number (0/1)
+  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc. 0=output, 1=input
+  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0, etc. 0=normal, 1=inversion
+  @param[in]  Output      Bit-encoded output state, ignores polarity, only applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
+
+**/
+VOID
+GpioExpBulkConfig (
+  IN UINT8  Expander,
+  IN UINT32 Direction,
+  IN UINT32 Polarity,
+  IN UINT32 Output
+  )
+{
+  UINT8 WriteBuf[4];
+  UINT8 Controller;
+
+  GpioExpGetController(&Controller);
+
+  WriteBuf[0] = mOutputRegister[0] + AUTO_INCREMENT;
+  WriteBuf[1] = Output & 0xFF;
+  WriteBuf[2] = (Output>>8) & 0xFF;
+  WriteBuf[3] = (Output>>16) & 0xFF;
+  I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+  WriteBuf[0] = mPolarityRegister[0] + AUTO_INCREMENT;
+  WriteBuf[1] = Polarity & 0xFF;
+  WriteBuf[2] = (Polarity>>8) & 0xFF;
+  WriteBuf[3] = (Polarity>>16) & 0xFF;
+  I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+  WriteBuf[0] = mConfigRegister[0] + AUTO_INCREMENT;
+  WriteBuf[1] = Direction & 0xFF;
+  WriteBuf[2] = (Direction>>8) & 0xFF;
+  WriteBuf[3] = (Direction>>16) & 0xFF;
+  I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c
new file mode 100644
index 0000000000..b8afd791f0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c
@@ -0,0 +1,132 @@
+/** @file
+  This file is SampleCode of the library for Intel HD Audio Verb Table configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <ConfigBlock.h>
+#include <PlatformBoardId.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include "PchHdaVerbTables.h"
+
+/**
+  Add verb table helper function.
+  This function calculates verbtable number and shows verb table information.
+
+  @param[in,out] VerbTableEntryNum      Input current VerbTable number and output the number after adding new table
+  @param[in,out] VerbTableArray         Pointer to array of VerbTable
+  @param[in]     VerbTable              VerbTable which is going to add into array
+**/
+STATIC
+VOID
+InternalAddVerbTable (
+  IN OUT  UINT8                   *VerbTableEntryNum,
+  IN OUT  UINT32                  *VerbTableArray,
+  IN      HDAUDIO_VERB_TABLE      *VerbTable
+  )
+{
+  if (VerbTable == NULL) {
+    DEBUG ((DEBUG_INFO, "InternalAddVerbTable wrong input: VerbTable == NULL\n"));
+    return;
+  }
+
+  VerbTableArray[*VerbTableEntryNum] = (UINT32) VerbTable;
+  *VerbTableEntryNum += 1;
+
+  DEBUG ((DEBUG_INFO,
+    "HDA: Add verb table for vendor = 0x%04X devId = 0x%04X (size = %d DWords)\n",
+    VerbTable->Header.VendorId,
+    VerbTable->Header.DeviceId,
+    VerbTable->Header.DataDwords)
+    );
+}
+
+/**
+  Add verb table function.
+  This function update the verb table number and verb table ptr of policy.
+
+  @param[in]  HdAudioConfig            HD Audio config block
+  @param[out] VerbTableEntryNum        Number of verb table entries
+  @param[out] HdaVerbTablePtr          Pointer to the verb table
+**/
+VOID
+AddPlatformVerbTables (
+  IN   UINT8              CodecType,
+  OUT  UINT8              *VerbTableEntryNum,
+  OUT  UINT32             *HdaVerbTablePtr
+  )
+{
+  UINT8                   VerbTableEntries;
+  UINT32                  VerbTableArray[6];
+  UINT32                  *VerbTablePtr;
+
+  VerbTableEntries = 0;
+
+  InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdDisplayAudioHdaVerbTable));
+
+  if (CodecType == PchHdaCodecPlatformOnboard) {
+    DEBUG ((DEBUG_INFO, "HDA Policy: Onboard codec selected\n"));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdHdaVerbTable));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdHdaVerbTable2));
+  } else {
+    DEBUG ((DEBUG_INFO, "HDA Policy: External codec kit selected\n"));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdCommonHdaVerbTable1));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdCommonHdaVerbTable2));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdCommonHdaVerbTable3));
+  }
+
+  *VerbTableEntryNum = VerbTableEntries;
+
+  VerbTablePtr = (UINT32 *) AllocateZeroPool (sizeof (UINT32) * VerbTableEntries);
+  CopyMem (VerbTablePtr, VerbTableArray, sizeof (UINT32) * VerbTableEntries);
+  *HdaVerbTablePtr = (UINT32) VerbTablePtr;
+}
+
+/**
+  HDA VerbTable init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+HdaVerbTableInit (
+  IN UINT16 BoardId
+  )
+{
+  HDAUDIO_VERB_TABLE *VerbTable;
+  HDAUDIO_VERB_TABLE *VerbTable2;
+
+  VerbTable = NULL;
+  VerbTable2 = NULL;
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      VerbTable = &WhlHdaVerbTableAlc700;
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "HDA: Init default verb tables (Realtek ALC700 and ALC701)\n"));
+      VerbTable = &HdaVerbTableAlc700;
+      VerbTable2 = &HdaVerbTableAlc701;
+      break;
+  }
+
+  PcdSet32S (PcdHdaVerbTable, (UINT32) VerbTable);
+  PcdSet32S (PcdHdaVerbTable2, (UINT32) VerbTable2);
+  PcdSet32S (PcdDisplayAudioHdaVerbTable, (UINT32) &HdaVerbTableDisplayAudio);
+
+  // Codecs - Realtek ALC700, ALC701, ALC274 (external - connected via HDA header)
+  PcdSet32S (PcdCommonHdaVerbTable1, (UINT32) &HdaVerbTableAlc700);
+  PcdSet32S (PcdCommonHdaVerbTable2, (UINT32) &HdaVerbTableAlc701);
+  PcdSet32S (PcdCommonHdaVerbTable3, (UINT32) &HdaVerbTableAlc274);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
new file mode 100644
index 0000000000..70f531daca
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
@@ -0,0 +1,115 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/I2cAccessLib.h>
+
+EFI_STATUS
+I2cWriteRead (
+  IN UINTN  MmioBase,
+  IN UINT8  SlaveAddress,
+  IN UINT8  WriteLength,
+  IN UINT8  *WriteBuffer,
+  IN UINT8  ReadLength,
+  IN UINT8  *ReadBuffer,
+  IN UINT64  TimeBudget
+  //TODO: add Speed parameter
+  )
+{
+  UINT8 ReadsNeeded = ReadLength;
+  UINT64 CutOffTime;
+
+  if ((WriteLength == 0 && ReadLength == 0) ||
+      (WriteLength != 0 && WriteBuffer == NULL) ||
+      (ReadLength != 0 && ReadBuffer == NULL) ) {
+    DEBUG ((DEBUG_ERROR, "I2cWR Invalid Parameters\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Sanity checks to verify the I2C controller is alive
+  // Conveniently, ICON register's values of 0 or FFFFFFFF indicate
+  // I2c controller is out-of-order: either disabled, in D3 or in reset.
+  //
+  if (MmioRead32(MmioBase+R_IC_CON) == 0xFFFFFFFF || MmioRead32(MmioBase+R_IC_CON) == 0x0) {
+    DEBUG ((DEBUG_ERROR, "I2cWR Device Error\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  MmioWrite32(MmioBase+R_IC_ENABLE, 0x0);
+  MmioRead32(MmioBase+0x40);
+  MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
+  MmioWrite32(MmioBase+R_IC_SDA_HOLD, 0x001C001C);
+  //
+  // Set I2C Bus Speed at 400 kHz for GPIO Expander
+  //
+  MmioWrite32(MmioBase + R_IC_FS_SCL_HCNT, 128);
+  MmioWrite32(MmioBase + R_IC_FS_SCL_LCNT, 160);
+  MmioWrite32(MmioBase + R_IC_TAR, SlaveAddress);
+  MmioWrite32(MmioBase + R_IC_CON, B_IC_MASTER_MODE | V_IC_SPEED_FAST | B_IC_RESTART_EN | B_IC_SLAVE_DISABLE );
+  MmioWrite32(MmioBase+R_IC_ENABLE, 0x1);
+  CutOffTime = AsmReadTsc() + TimeBudget;
+
+  while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==0 ) {
+    if (AsmReadTsc() > CutOffTime) {
+      DEBUG ((DEBUG_ERROR, "I2cWR timeout\n"));
+      return EFI_TIMEOUT;
+    }
+  }
+
+  while(1) {
+    if(MmioRead32(MmioBase+R_IC_INTR_STAT) & B_IC_INTR_TX_ABRT) {
+      DEBUG ((DEBUG_ERROR, "I2cWR Transfer aborted, reason = 0x%08x\n",MmioRead32(MmioBase+R_IC_TX_ABRT_SOURCE)));
+      MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
+      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+      return EFI_DEVICE_ERROR;
+    }
+    if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_TFNF) {
+      if (WriteLength > 1) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
+        WriteBuffer++;
+        WriteLength--;
+      } else if (WriteLength==1 && ReadLength != 0) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
+        WriteBuffer++;
+        WriteLength--;
+      } else if (WriteLength==1 && ReadLength == 0) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer | B_IC_CMD_STOP);
+        WriteBuffer++;
+        WriteLength--;
+      } else if (ReadLength > 1) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ);
+        ReadLength--;
+      } else if (ReadLength == 1) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ|B_IC_CMD_STOP);
+        ReadLength--;
+      }
+    }
+
+    if (ReadsNeeded) {
+      if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_RFNE) {
+        *ReadBuffer = (UINT8)MmioRead32(MmioBase+R_IC_DATA_CMD);
+        ReadBuffer++;
+        ReadsNeeded--;
+      }
+    }
+    if (WriteLength==0 && ReadsNeeded==0 && !(MmioRead32(MmioBase+R_IC_STATUS)&B_IC_STATUS_ACTIVITY)) {
+      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+      DEBUG ((DEBUG_INFO, "I2cWR success\n"));
+      return EFI_SUCCESS;
+    }
+    if (AsmReadTsc() > CutOffTime) {
+      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+      DEBUG ((DEBUG_ERROR, "I2cWR wrong ENST value\n"));
+      return EFI_TIMEOUT;
+    }
+
+  }
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c
new file mode 100644
index 0000000000..7b9a32b3f5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c
@@ -0,0 +1,88 @@
+/** @file
+  This file is the library for CPU DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DxeCpuPolicyUpdateLib.h>
+
+/**
+  This function prints the CPU DXE phase policy.
+
+  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
+**/
+VOID
+CpuDxePrintPolicyProtocol (
+  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU Policy (DXE) print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : %x\n", DxeCpuPolicy->Revision));
+  ASSERT (DxeCpuPolicy->Revision == DXE_CPU_POLICY_PROTOCOL_REVISION);
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU_DXE_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, "EnableDts : %x\n", DxeCpuPolicy->EnableDts));
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Get data for CPU policy from setup options.
+
+  @param[in] DxeCpuPolicy              The pointer to get CPU Policy protocol instance
+
+  @retval EFI_SUCCESS                  Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSiCpuPolicy (
+  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
+  )
+{
+  EFI_STATUS            Status;
+
+  ///
+  /// Print CPU DXE Policy
+  ///
+  CpuDxePrintPolicyProtocol(DxeCpuPolicy);
+
+  ///
+  /// Install the DXE_CPU_POLICY_PROTOCOL interface
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gDxeCpuPolicyProtocolGuid,
+                  DxeCpuPolicy,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c
new file mode 100644
index 0000000000..863df3328c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c
@@ -0,0 +1,105 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeMePolicyUpdate.h"
+
+//
+// Record version
+//
+#define RECORD_REVISION_1              0x01
+#define MAX_FW_UPDATE_BIOS_SELECTIONS  2
+
+//
+// Function implementations executed during policy initialization phase
+//
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   Initialization complete.
+  @retval 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
+UpdateDxeMePolicy (
+  IN OUT  ME_POLICY_PROTOCOL            *DxeMePolicy
+  )
+{
+  EFI_STATUS              Status;
+  EFI_EVENT               EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "UpdateDxeMePolicy\n"));
+  UpdateMePolicyFromSetup (DxeMePolicy);
+  UpdateMePolicyFromMeSetup (DxeMePolicy);
+
+  //
+  // Register End of DXE event
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UpdateMeSetupCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+/**
+  Update ME Policy while MePlatformProtocol is installed.
+
+  @param[in] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromMeSetup (
+  IN ME_POLICY_PROTOCOL           *MePolicyInstance
+  )
+{
+
+}
+
+/**
+  Update ME Policy if Setup variable exists.
+
+  @param[in, out] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromSetup (
+  IN OUT ME_POLICY_PROTOCOL     *MePolicyInstance
+  )
+{
+
+}
+
+/**
+  Functions performs HECI exchange with FW to update MePolicy settings.
+
+  @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
+UpdateMeSetupCallback (
+  IN  EFI_EVENT                   Event,
+  IN  VOID                        *Context
+  )
+{
+  gBS->CloseEvent (Event);
+
+  return;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c
new file mode 100644
index 0000000000..7945986aaa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c
@@ -0,0 +1,39 @@
+/** @file
+  This file is the library for PCH DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <PchAccess.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/HdAudioConfig.h>
+
+/**
+  Get data for PCH policy from setup options.
+
+  @param[in] PchPolicy                 The pointer to get PCH Policy protocol instance
+
+  @retval EFI_SUCCESS                  Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxePchPolicy (
+  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
+  )
+{
+  EFI_STATUS              Status;
+  PCH_HDAUDIO_DXE_CONFIG  *HdAudioDxeConfig;
+
+  Status = GetConfigBlock ((VOID *)PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdAudioDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
new file mode 100644
index 0000000000..af4c76bcd0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
@@ -0,0 +1,57 @@
+/** @file
+  This file is the library for SA DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <DxeSaPolicyUpdate.h>
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] SaPolicy                  The pointer to get SA Policy protocol instance
+
+  @retval EFI_SUCCESS                  Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicy (
+  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
+  )
+{
+  EFI_STATUS                Status;
+  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
+  PCIE_DXE_CONFIG           *PcieDxeConfig;
+  MISC_DXE_CONFIG           *MiscDxeConfig;
+  MEMORY_DXE_CONFIG         *MemoryDxeConfig;
+
+  GraphicsDxeConfig = NULL;
+  PcieDxeConfig = NULL;
+  MiscDxeConfig = NULL;
+  MemoryDxeConfig = NULL;
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  PcieDxeConfig->PegAspmL0s[0] = 3;
+  PcieDxeConfig->PegAspmL0s[1] = 3;
+  PcieDxeConfig->PegAspmL0s[2] = 3;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c
new file mode 100644
index 0000000000..93be38a832
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c
@@ -0,0 +1,65 @@
+/** @file
+  This file is SampleCode for Intel PEI Platform Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyInit.h"
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in] PeiServices            General purpose services available to every PEIM.
+  @param[in] FirmwareConfiguration  It uses to skip specific policy init that depends
+                                    on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInit (
+  IN UINT8                     FirmwareConfiguration
+  )
+{
+  EFI_STATUS                   Status;
+  SI_POLICY_PPI                *SiPolicyPpi;
+
+  //
+  // Call SiCreateConfigBlocks to initialize Silicon Policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = SiCreateConfigBlocks (&SiPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return;
+  }
+
+  if (PcdGetBool (PcdDumpDefaultSiliconPolicy)) {
+    DEBUG ((DEBUG_INFO, "Dump Default Silicon Policy...\n"));
+    DumpSiPolicy (SiPolicyPpi);
+  }
+
+  //
+  // Update policy by board configuration
+  //
+  UpdatePeiSiPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiPchPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiSaPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiCpuPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiMePolicyBoardConfig (SiPolicyPpi);
+
+  UpdatePeiSiPolicy(SiPolicyPpi);
+  UpdatePeiPchPolicy(SiPolicyPpi);
+  UpdatePeiSaPolicy(SiPolicyPpi);
+  UpdatePeiCpuPolicy(SiPolicyPpi);
+  UpdatePeiMePolicy(SiPolicyPpi);
+
+  //
+  // Install SiPolicyPpi.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SiInstallPolicyPpi (SiPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
new file mode 100644
index 0000000000..9f8014b72a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode for Intel PEI Platform Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyInit.h"
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that depends
+                                     on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInitPreMem (
+  IN UINT8                     FirmwareConfiguration
+  )
+{
+  EFI_STATUS                   Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in Pre-Memory...\n"));
+  //
+  // Call SiCreatePreMemConfigBlocks to initialize platform policy structure
+  // and get all intel default policy settings.
+  //
+  Status = SiCreatePreMemConfigBlocks (&SiPreMemPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update policy by board configuration
+  //
+  UpdatePeiPchPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+  UpdatePeiMePolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+  UpdatePeiSaPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+  UpdatePeiCpuPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+
+  //
+  // Update and override all platform related and customized settings below.
+  //
+  UpdatePeiPchPolicyPreMem (SiPreMemPolicyPpi);
+  UpdatePeiMePolicyPreMem (SiPreMemPolicyPpi);
+  UpdatePeiSaPolicyPreMem (SiPreMemPolicyPpi);
+  UpdatePeiCpuPolicyPreMem (SiPreMemPolicyPpi);
+
+  //
+  // Install SiPreMemPolicyPpi.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SiPreMemInstallPolicyPpi (SiPreMemPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in Pre-Memory\n"));
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
new file mode 100644
index 0000000000..922bcd135f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
@@ -0,0 +1,114 @@
+/** @file
+  This file is SampleCode for Intel SA PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyInit.h"
+
+
+/**
+  PcieCardResetWorkAround performs PCIe Card reset on root port
+
+  @param[in out] SiPreMemPolicyPpi SI_PREMEM_POLICY_PPI
+
+  @retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+  PcieCardResetWorkAround (
+  IN OUT   SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  SA_MISC_PEI_PREMEM_CONFIG       *MiscPeiPreMemConfig;
+  SWITCHABLE_GRAPHICS_CONFIG      *SgGpioData;
+
+  Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *)&MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *)&SgGpioData);
+  ASSERT_EFI_ERROR(Status);
+
+  if (SgGpioData->SaRtd3Pcie0Gpio.GpioSupport != NotSupported) {
+    ///
+    /// dGPU is present.
+    ///      If PCIe Mode or SG Muxless
+    ///              Power on MXM
+    ///              Configure GPIOs to drive MXM in PCIe mode or SG Muxless
+    ///      else
+    ///              Do Nothing
+    ///
+    if ((MiscPeiPreMemConfig->SgMode == SgModeMuxless) ||
+        (MiscPeiPreMemConfig->SgMode == SgModeDgpu)) {
+      DEBUG((DEBUG_INFO, "Configure GPIOs for driving the dGPU.\n"));
+      ///
+      ///  Drive DGPU HOLD RST Enable to make sure we hold reset
+      ///
+      PcieGpioWrite (
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo,
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active,
+        GP_ENABLE
+        );
+      ///
+      /// wait 100ms
+      ///
+      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) * STALL_ONE_MILLI_SECOND);
+
+      ///
+      /// Drive DGPU PWR EN to Power On MXM
+      ///
+      PcieGpioWrite (
+        SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.GpioNo,
+        SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.Active,
+        GP_ENABLE
+        );
+      ///
+      /// wait 300ms
+      ///
+      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterPwrEn) * STALL_ONE_MILLI_SECOND);
+
+      ///
+      /// Drive DGPU HOLD RST Disabled to remove reset
+      ///
+      PcieGpioWrite (
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo,
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active,
+        GP_DISABLE
+        );
+      ///
+      /// wait 100ms
+      ///
+      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) * STALL_ONE_MILLI_SECOND);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  PCIe GPIO Write
+
+  @param[in] Gpio        - GPIO Number
+  @param[in] Active      - GPIO Active Information; High/Low
+  @param[in] Level       - Write GPIO value (0/1)
+
+**/
+VOID
+PcieGpioWrite (
+  IN  UINT32                Gpio,
+  IN  BOOLEAN               Active,
+  IN  BOOLEAN               Level
+  )
+{
+  EFI_STATUS  Status;
+
+  if (Active == 0) {
+    Level = (~Level) & 0x1;
+  }
+  Status = GpioSetOutputValue(Gpio, (UINT32)Level);
+  if (Status != EFI_SUCCESS) {
+    return;
+  }
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
new file mode 100644
index 0000000000..144480a83d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
@@ -0,0 +1,80 @@
+/** @file
+  CPU PEI Policy Update & initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyUpdate.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CpuPlatformLib.h>
+
+/**
+  This function performs CPU PEI Policy initialization.
+
+  @param[in] SiPolicyPpi           The SI Policy PPI instance
+
+  @retval EFI_SUCCESS              The PPI is installed and initialized.
+  @retval EFI ERRORS               The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES     Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+  IN OUT  SI_POLICY_PPI   *SiPolicyPpi
+  )
+{
+  EFI_STATUS                       Status;
+  CPU_CONFIG                       *CpuConfig;
+  CPU_POWER_MGMT_BASIC_CONFIG      *CpuPowerMgmtBasicConfig;
+  SI_PREMEM_POLICY_PPI             *SiPreMemPolicyPpi;
+  CPU_POWER_MGMT_CUSTOM_CONFIG     *CpuPowerMgmtCustomConfig;
+  CPU_POWER_MGMT_TEST_CONFIG      *CpuPowerMgmtTestConfig;
+  CPU_TEST_CONFIG                 *CpuTestConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *)&CpuPowerMgmtCustomConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuTestConfigGuid, (VOID *)&CpuTestConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = PeiServicesLocatePpi (
+                &gSiPreMemPolicyPpiGuid,
+                0,
+                NULL,
+                (VOID **) &SiPreMemPolicyPpi
+                );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *)&CpuPowerMgmtTestConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Init Power Management Policy Variables
+  //
+  CpuPowerMgmtBasicConfig->HwpInterruptControl = 1;
+  CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio = 0x4;
+  CpuPowerMgmtBasicConfig->OneCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->TwoCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->FourCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->FiveCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->SixCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->SevenCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->EightCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->Hwp = 0x1;
+  CpuTestConfig->CpuWakeUpTimer = 1;
+  CpuPowerMgmtTestConfig->AutoThermalReporting = 0;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..bce02a9c5a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
@@ -0,0 +1,108 @@
+/** @file
+  This file is SampleCode of the library for Intel CPU PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyUpdate.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SpiLib.h>
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval True if SGX supported or FALSE if not
+**/
+BOOLEAN
+IsSgxCapSupported (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER CpuidRegs;
+
+  ///
+  /// Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
+  ///
+  AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.RegEdx);
+
+  ///
+  /// SGX feature is supported only on WHL and later,
+  /// with CPUID.(EAX=7,ECX=0):EBX[2]=1
+  /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
+  ///
+  if ((CpuidRegs.RegEbx & BIT2) && (AsmReadMsr64 (MSR_IA32_MTRRCAP) & BIT12)) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  This function performs CPU PEI Policy initialization in Pre-memory.
+
+  @param[in] SiPreMemPolicyPpi     The SI Pre-Mem Policy PPI instance
+
+  @retval EFI_SUCCESS              The PPI is installed and initialized.
+  @retval EFI ERRORS               The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES     Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_BOOT_MODE                   BootMode;
+  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverClockingPreMemConfig;
+  UINT32                          PchSpiBar0;
+  UINT32                          MaxLogicProcessors;
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverClockingPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiCpuPolicyPreMem Start\n"));
+
+  //
+  // Get current boot mode
+  //
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  SpiServiceInit ();
+
+  PchSpiBar0 = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
+                                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                                   PCI_DEVICE_NUMBER_PCH_SPI,
+                                   PCI_FUNCTION_NUMBER_PCH_SPI,
+                                   R_SPI_CFG_BAR0
+                                   ));
+  PchSpiBar0 &= ~(B_SPI_CFG_BAR0_MASK);
+
+  if (PchSpiBar0 == 0) {
+    DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
+    ASSERT (FALSE);
+  }
+
+  CpuConfigLibPreMemConfig->PeciC10Reset = 0;
+  CpuConfigLibPreMemConfig->CpuRatio = 0;
+  ///
+  /// Set PcdCpuMaxLogicalProcessorNumber to max number of logical processors enabled
+  /// Read MSR_CORE_THREAD_COUNT (0x35) to check the total active Threads
+  ///
+  MaxLogicProcessors = (UINT32) (AsmReadMsr64 (MSR_CORE_THREAD_COUNT) & B_THREAD_COUNT_MASK);
+  DEBUG ((DEBUG_INFO, "MaxLogicProcessors = %d\n", MaxLogicProcessors));
+  PcdSet32S (PcdCpuMaxLogicalProcessorNumber, MaxLogicProcessors);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c
new file mode 100644
index 0000000000..e557f04971
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c
@@ -0,0 +1,49 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiMePolicyUpdate.h"
+#include <ConfigBlock/MePeiConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PmcLib.h>
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPolicyPpi     The pointer to SiPolicyPpi
+
+  @retval EFI_SUCCESS             Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicy (
+  IN OUT SI_POLICY_PPI            *SiPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  ME_PEI_CONFIG                   *MePeiConfig;
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiMePolicy\n"));
+
+  Status = EFI_SUCCESS;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (!PmcIsRtcBatteryGood ()) {
+    //
+    // For non coin battery design, this can be skipped.
+    //
+    MePeiConfig->MeUnconfigOnRtcClear   = 2;
+  }
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c
new file mode 100644
index 0000000000..de9849b807
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c
@@ -0,0 +1,32 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiMePolicyUpdate.h"
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  Update the ME Policy Library
+
+  @param[in] SiPreMemPolicyPpi  The pointer to SiPreMemPolicyPpi
+
+  @retval EFI_SUCCESS           Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicyPreMem (
+  IN OUT SI_PREMEM_POLICY_PPI     *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiMePolicyPreMem\n"));
+
+  Status = EFI_SUCCESS;
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c
new file mode 100644
index 0000000000..3e44c6cc29
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c
@@ -0,0 +1,523 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/PchGbeLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Ppi/Spi.h>
+#include <GpioConfig.h>
+#include <Library/DebugLib.h>
+#include <Library/PchGbeLib.h>
+#include <PlatformBoardConfig.h>
+#include <Library/CnviLib.h>
+#include <Register/PchRegsLpcCnl.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <PcieDeviceOverrideTable.h>
+
+VOID
+UpdatePcieClockInfo (
+  PCH_PCIE_CONFIG  *PcieRpConfig,
+  UINTN            Index,
+  UINT64           Data
+  )
+{
+  PCD64_BLOB Pcd64;
+
+  Pcd64.Blob = Data;
+  DEBUG ((DEBUG_INFO, "UpdatePcieClockInfo ClkIndex %x ClkUsage %x, Supported %x\n", Index, Pcd64.PcieClock.ClockUsage, Pcd64.PcieClock.ClkReqSupported));
+
+  PcieRpConfig->PcieClock[Index].Usage = (UINT8)Pcd64.PcieClock.ClockUsage;
+  if (Pcd64.PcieClock.ClkReqSupported) {
+    PcieRpConfig->PcieClock[Index].ClkReq = (UINT8)Index;
+  } else {
+    PcieRpConfig->PcieClock[Index].ClkReq = 0xFF;
+  }
+}
+
+/**
+  This is helper function for getting I2C Pads Internal Termination settings from Pcd
+
+  @param[in]  Index            I2C Controller Index
+**/
+UINT8
+GetSerialIoI2cPadsTerminationFromPcd (
+  IN UINT8 Index
+)
+{
+  switch (Index) {
+    case 0:
+      return PcdGet8 (PcdPchSerialIoI2c0PadInternalTerm);
+    case 1:
+      return PcdGet8 (PcdPchSerialIoI2c1PadInternalTerm);
+    case 2:
+      return PcdGet8 (PcdPchSerialIoI2c2PadInternalTerm);
+    case 3:
+      return PcdGet8 (PcdPchSerialIoI2c3PadInternalTerm);
+    case 4:
+      return PcdGet8 (PcdPchSerialIoI2c4PadInternalTerm);
+    case 5:
+      return PcdGet8 (PcdPchSerialIoI2c5PadInternalTerm);
+    default:
+      ASSERT (FALSE); // Invalid I2C Controller Index
+  }
+  return 0;
+}
+/**
+  This is a helper function for updating USB Policy according to Blob data
+
+  @param[in]  UsbConfig        Pointer to USB_CONFIG data buffer
+  @param[in]  PortIndex        USB Port index
+  @param[in]  Data32           Blob containing USB2 Afe (PCD32_BLOB) data
+**/
+VOID
+UpdateUsb20AfePolicy (
+  IN USB_CONFIG                 *UsbConfig,
+  IN UINT8                      PortIndex,
+  UINT32                        Data32
+)
+{
+  PCD32_BLOB Pcd32;
+  Pcd32.Blob = Data32;
+
+  if (PortIndex < MAX_USB2_PORTS && Pcd32.Info.Petxiset != 0) {
+    UsbConfig->PortUsb20[PortIndex].Afe.Petxiset     = Pcd32.Info.Petxiset;
+    UsbConfig->PortUsb20[PortIndex].Afe.Txiset       = Pcd32.Info.Txiset;
+    UsbConfig->PortUsb20[PortIndex].Afe.Predeemp     = Pcd32.Info.Predeemp;
+    UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit    = Pcd32.Info.Pehalfbit;
+  }
+}
+
+/**
+  This function updates USB Policy per port OC Pin number
+
+  @param[in]  PchUsbConfig     Pointer to USB_CONFIG data buffer
+  @param[in]  PortIndex        USB Port index
+  @param[in]  Pin              OverCurrent pin number
+**/
+VOID
+UpdateUsb20OverCurrentPolicy (
+  IN USB_CONFIG                 *UsbConfig,
+  IN UINT8                      PortIndex,
+  UINT8                         Pin
+)
+{
+  if (PortIndex < MAX_USB2_PORTS && ((Pin < UsbOverCurrentPinMax) || (Pin == UsbOverCurrentPinSkip))) {
+    UsbConfig->PortUsb20[PortIndex].OverCurrentPin = Pin;
+  } else {
+    if (PortIndex >= MAX_USB2_PORTS) {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb20OverCurrentPolicy: USB2 port number %d is not a valid USB2 port number\n", PortIndex));
+    } else {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb20OverCurrentPolicy: Invalid OverCurrent pin specified USB2 port %d\n", PortIndex));
+    }
+  }
+}
+
+/**
+  This function updates USB Policy per port OC Pin number
+
+  @param[in]  PchUsbConfig     Pointer to USB_CONFIG data buffer
+  @param[in]  PortIndex        USB Port index
+  @param[in]  Pin              OverCurrent pin number
+**/
+VOID
+UpdateUsb30OverCurrentPolicy (
+  IN USB_CONFIG                 *UsbConfig,
+  IN UINT8                      PortIndex,
+  UINT8                         Pin
+)
+{
+  if (PortIndex < MAX_USB3_PORTS && ((Pin < UsbOverCurrentPinMax) || (Pin == UsbOverCurrentPinSkip))) {
+    UsbConfig->PortUsb30[PortIndex].OverCurrentPin = Pin;
+  } else {
+    if (PortIndex >= MAX_USB2_PORTS) {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb30OverCurrentPolicy: USB3 port number %d is not a valid USB3 port number\n", PortIndex));
+    } else {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb30OverCurrentPolicy: Invalid OverCurrent pin specified USB3 port %d\n", PortIndex));
+    }
+  }
+}
+
+/**
+  This function performs PCH USB Platform Policy initialization
+
+  @param[in] PchUsbConfig         Pointer to USB_CONFIG data buffer
+  @param[in] PchSetup             Pointer to PCH_SETUP data buffer
+**/
+VOID
+UpdatePchUsbConfig (
+  IN USB_CONFIG                *UsbConfig
+  )
+{
+  UINTN              PortIndex;
+
+  UsbConfig->OverCurrentEnable = TRUE;
+
+  for (PortIndex = 0; PortIndex < GetPchUsb2MaxPhysicalPortNum (); PortIndex++) {
+      UsbConfig->PortUsb20[PortIndex].Enable = TRUE;
+  }
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+      UsbConfig->PortUsb30[PortIndex].Enable = TRUE;
+  }
+
+  UsbConfig->XdciConfig.Enable = FALSE;
+
+
+  //
+  // USB2 AFE settings.
+  //
+  UpdateUsb20AfePolicy (UsbConfig, 0, PcdGet32 (PcdUsb20Port0Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 1, PcdGet32 (PcdUsb20Port1Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 2, PcdGet32 (PcdUsb20Port2Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 3, PcdGet32 (PcdUsb20Port3Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 4, PcdGet32 (PcdUsb20Port4Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 5, PcdGet32 (PcdUsb20Port5Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 6, PcdGet32 (PcdUsb20Port6Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 7, PcdGet32 (PcdUsb20Port7Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 8, PcdGet32 (PcdUsb20Port8Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 9, PcdGet32 (PcdUsb20Port9Afe));
+  UpdateUsb20AfePolicy (UsbConfig,10, PcdGet32 (PcdUsb20Port10Afe));
+  UpdateUsb20AfePolicy (UsbConfig,11, PcdGet32 (PcdUsb20Port11Afe));
+  UpdateUsb20AfePolicy (UsbConfig,12, PcdGet32 (PcdUsb20Port12Afe));
+  UpdateUsb20AfePolicy (UsbConfig,13, PcdGet32 (PcdUsb20Port13Afe));
+  UpdateUsb20AfePolicy (UsbConfig,14, PcdGet32 (PcdUsb20Port14Afe));
+  UpdateUsb20AfePolicy (UsbConfig,15, PcdGet32 (PcdUsb20Port15Afe));
+
+  //
+  // Platform Board programming per the layout of each port.
+  //
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 0, PcdGet8 (PcdUsb20OverCurrentPinPort0));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 1, PcdGet8 (PcdUsb20OverCurrentPinPort1));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 2, PcdGet8 (PcdUsb20OverCurrentPinPort2));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 3, PcdGet8 (PcdUsb20OverCurrentPinPort3));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 4, PcdGet8 (PcdUsb20OverCurrentPinPort4));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 5, PcdGet8 (PcdUsb20OverCurrentPinPort5));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 6, PcdGet8 (PcdUsb20OverCurrentPinPort6));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 7, PcdGet8 (PcdUsb20OverCurrentPinPort7));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 8, PcdGet8 (PcdUsb20OverCurrentPinPort8));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 9, PcdGet8 (PcdUsb20OverCurrentPinPort9));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,10, PcdGet8 (PcdUsb20OverCurrentPinPort10));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,11, PcdGet8 (PcdUsb20OverCurrentPinPort11));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,12, PcdGet8 (PcdUsb20OverCurrentPinPort12));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,13, PcdGet8 (PcdUsb20OverCurrentPinPort13));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,14, PcdGet8 (PcdUsb20OverCurrentPinPort14));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,15, PcdGet8 (PcdUsb20OverCurrentPinPort15));
+
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 0, PcdGet8 (PcdUsb30OverCurrentPinPort0));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 1, PcdGet8 (PcdUsb30OverCurrentPinPort1));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 2, PcdGet8 (PcdUsb30OverCurrentPinPort2));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 3, PcdGet8 (PcdUsb30OverCurrentPinPort3));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 4, PcdGet8 (PcdUsb30OverCurrentPinPort4));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 5, PcdGet8 (PcdUsb30OverCurrentPinPort5));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 6, PcdGet8 (PcdUsb30OverCurrentPinPort6));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 7, PcdGet8 (PcdUsb30OverCurrentPinPort7));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 8, PcdGet8 (PcdUsb30OverCurrentPinPort8));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 9, PcdGet8 (PcdUsb30OverCurrentPinPort9));
+
+}
+
+/**
+  Return if input ImageGuid belongs to system FMP GUID list.
+
+  @param[in] ImageGuid A pointer to GUID
+
+  @retval TRUE  ImageGuid is in the list of PcdSystemFmpCapsuleImageTypeIdGuid
+  @retval FALSE ImageGuid is not in the list of PcdSystemFmpCapsuleImageTypeIdGuid
+**/
+BOOLEAN
+IsSystemFmpGuid (
+  IN GUID   *ImageGuid
+  )
+{
+  GUID      *Guid;
+  UINTN     Count;
+  UINTN     Index;
+
+  Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
+  Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof (GUID);
+
+  for (Index = 0; Index < Count; Index++, Guid++) {
+    if (CompareGuid (ImageGuid, Guid)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicy (
+  IN OUT      SI_POLICY_PPI     *SiPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT8                           Index;
+  DMI_HW_WIDTH_CONTROL            *DmiHaAWC;
+  UINT16                          LpcDid;
+  PCH_GENERAL_CONFIG              *PchGeneralConfig;
+  PCH_PCIE_CONFIG                 *PcieRpConfig;
+  PCH_SATA_CONFIG                 *SataConfig;
+  PCH_IOAPIC_CONFIG               *IoApicConfig;
+  PCH_DMI_CONFIG                  *DmiConfig;
+  PCH_FLASH_PROTECTION_CONFIG     *FlashProtectionConfig;
+  PCH_HDAUDIO_CONFIG              *HdAudioConfig;
+  PCH_INTERRUPT_CONFIG            *InterruptConfig;
+  PCH_ISH_CONFIG                  *IshConfig;
+  PCH_LAN_CONFIG                  *LanConfig;
+  PCH_LOCK_DOWN_CONFIG            *LockDownConfig;
+  PCH_PM_CONFIG                   *PmConfig;
+  PCH_SCS_CONFIG                  *ScsConfig;
+  PCH_SERIAL_IO_CONFIG            *SerialIoConfig;
+  PCH_LPC_SIRQ_CONFIG             *SerialIrqConfig;
+  PCH_THERMAL_CONFIG              *ThermalConfig;
+  USB_CONFIG                      *UsbConfig;
+  PCH_ESPI_CONFIG                 *EspiConfig;
+  PCH_CNVI_CONFIG                 *CnviConfig;
+  PEI_TBT_POLICY                  *PeiTbtPolicy;
+  SI_PREMEM_POLICY_PPI            *SiPreMemPolicyPpi;
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *) &SataConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gDmiConfigGuid, (VOID *) &DmiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gHdAudioConfigGuid, (VOID *) &HdAudioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIshConfigGuid, (VOID *) &IshConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLanConfigGuid, (VOID *) &LanConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gScsConfigGuid, (VOID *) &ScsConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIoConfigGuid, (VOID *) &SerialIoConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIrqConfigGuid, (VOID *) &SerialIrqConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gThermalConfigGuid, (VOID *) &ThermalConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gUsbConfigGuid, (VOID *) &UsbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gEspiConfigGuid, (VOID *) &EspiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gCnviConfigGuid, (VOID *) &CnviConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesLocatePpi (
+                &gSiPreMemPolicyPpiGuid,
+                0,
+                NULL,
+                (VOID **) &SiPreMemPolicyPpi
+                );
+  ASSERT_EFI_ERROR (Status);
+
+  PeiTbtPolicy = NULL;
+  LpcDid = PchGetLpcDid ();
+
+  DmiConfig->PwrOptEnable = TRUE;
+  PmConfig->PchSlpS3MinAssert = 0;
+  PmConfig->PchSlpS4MinAssert = 0;
+  PmConfig->PchSlpSusMinAssert = 0;
+  PmConfig->PchSlpAMinAssert = 0;
+
+  SataConfig->ThermalThrottling.P1T3M = 3;
+  SataConfig->ThermalThrottling.P1T2M = 2;
+  SataConfig->ThermalThrottling.P1T1M = 1;
+  SataConfig->ThermalThrottling.P0T3M = 3;
+  SataConfig->ThermalThrottling.P0T2M = 2;
+  SataConfig->ThermalThrottling.P0T1M = 1;
+
+  UpdatePcieClockInfo (PcieRpConfig, 0, PcdGet64  (PcdPcieClock0));
+  UpdatePcieClockInfo (PcieRpConfig, 1, PcdGet64  (PcdPcieClock1));
+  UpdatePcieClockInfo (PcieRpConfig, 2, PcdGet64  (PcdPcieClock2));
+  UpdatePcieClockInfo (PcieRpConfig, 3, PcdGet64  (PcdPcieClock3));
+  UpdatePcieClockInfo (PcieRpConfig, 4, PcdGet64  (PcdPcieClock4));
+  UpdatePcieClockInfo (PcieRpConfig, 5, PcdGet64  (PcdPcieClock5));
+  UpdatePcieClockInfo (PcieRpConfig, 6, PcdGet64  (PcdPcieClock6));
+  UpdatePcieClockInfo (PcieRpConfig, 7, PcdGet64  (PcdPcieClock7));
+  UpdatePcieClockInfo (PcieRpConfig, 8, PcdGet64  (PcdPcieClock8));
+  UpdatePcieClockInfo (PcieRpConfig, 9, PcdGet64  (PcdPcieClock9));
+  UpdatePcieClockInfo (PcieRpConfig, 10, PcdGet64 (PcdPcieClock10));
+  UpdatePcieClockInfo (PcieRpConfig, 11, PcdGet64 (PcdPcieClock11));
+  UpdatePcieClockInfo (PcieRpConfig, 12, PcdGet64 (PcdPcieClock12));
+  UpdatePcieClockInfo (PcieRpConfig, 13, PcdGet64 (PcdPcieClock13));
+  UpdatePcieClockInfo (PcieRpConfig, 14, PcdGet64 (PcdPcieClock14));
+  UpdatePcieClockInfo (PcieRpConfig, 15, PcdGet64 (PcdPcieClock15));
+
+  PcieRpConfig->PcieDeviceOverrideTablePtr = (UINT32) mPcieDeviceTable;
+  PcieRpConfig->RootPort[0].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[1].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[2].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[3].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[4].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[5].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[6].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[7].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[8].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[9].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[10].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[11].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[12].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[13].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[14].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[15].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[0].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[1].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[2].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[3].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[4].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[5].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[6].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[7].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[8].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[9].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[10].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[11].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[12].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[13].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[14].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[15].AdvancedErrorReporting = TRUE;
+
+  //
+  // Install HDA Link/iDisplay Codec Verb Table
+  //
+  AddPlatformVerbTables (
+    PchHdaCodecPlatformOnboard,
+    &(HdAudioConfig->VerbTableEntryNum),
+    &(HdAudioConfig->VerbTablePtr)
+    );
+
+  LockDownConfig->BiosLock = FALSE;
+  LockDownConfig->BiosInterface = FALSE;
+
+  //
+  // IOAPIC Config
+  //
+//  IoApicConfig->IoApicEntry24_119     = PchSetup.PchIoApic24119Entries;
+  //
+  // To support SLP_S0, it's required to disable 8254 timer.
+  // Note that CSM may require this option to be disabled for correct operation.
+  // Once 8254 timer disabled, some legacy OPROM and legacy OS will fail while using 8254 timer.
+  // For some OS environment that it needs to set 8254CGE in late state it should
+  // set this policy to FALSE and use PmcSet8254ClockGateState (TRUE) in SMM later.
+  // This is also required during S3 resume.
+  //
+  // The Enable8254ClockGatingOnS3 is only applicable when Enable8254ClockGating is disabled.
+  // If Enable8254ClockGating is enabled, RC will do 8254 CGE programming on S3 as well.
+  // else, RC will do the programming on S3 when Enable8254ClockGatingOnS3 is enabled.
+  // This avoids the SMI requirement for the programming.
+  //
+  // If S0ix is not enabled, then disable 8254CGE for leagcy boot case.
+  //
+  IoApicConfig->Enable8254ClockGating     = FALSE;
+  IoApicConfig->Enable8254ClockGatingOnS3 = FALSE;
+
+  //
+  // SerialIo Config
+  //
+  SerialIoConfig->DevMode[0] = 1;
+  SerialIoConfig->DevMode[1] = 1;
+  SerialIoConfig->DevMode[2] = 0;
+  SerialIoConfig->DevMode[3] = 0;
+  SerialIoConfig->DevMode[4] = 1;
+  SerialIoConfig->DevMode[5] = 0;
+  SerialIoConfig->DevMode[6] = 0;
+  SerialIoConfig->DevMode[7] = 0;
+  SerialIoConfig->DevMode[8] = 0;
+  SerialIoConfig->DevMode[9] = 0;
+  SerialIoConfig->DevMode[10] = 0;
+  SerialIoConfig->DevMode[11] = 3;
+
+  SerialIoConfig->Uart0PinMuxing = 1;
+  SerialIoConfig->SpiCsPolarity[0] = 1;
+  SerialIoConfig->SpiCsPolarity[1] = 0;
+  SerialIoConfig->SpiCsPolarity[2] = 0;
+
+  SerialIoConfig->UartHwFlowCtrl[0] = 1;
+  SerialIoConfig->UartHwFlowCtrl[1] = 1;
+  SerialIoConfig->UartHwFlowCtrl[2] = 1;
+  //
+  // I2C4 and I2C5 don't exist in SPT-H chipset
+  //
+  if (IsPchH ()) {
+    SerialIoConfig->DevMode[PchSerialIoIndexI2C4] = PchSerialIoDisabled;
+    SerialIoConfig->DevMode[PchSerialIoIndexI2C5] = PchSerialIoDisabled;
+  }
+
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    SerialIoConfig->I2cPadsTermination[Index] = GetSerialIoI2cPadsTerminationFromPcd (Index);
+  }
+
+  PmConfig->SlpS0Override                         = 2; //PchSetup.SlpS0Override;
+  PmConfig->SlpS0DisQForDebug                     = 3;  //PchSetup.SlpS0DisQForDebug;
+  PmConfig->SlpS0Vm075VSupport                    = 1; // PcdGetBool(PcdSlpS0Vm075VSupport);
+  PmConfig->CpuC10GatePinEnable                   = 1;
+
+  //
+  // Thermal Config
+  //
+  ThermalConfig->TsmicLock           = TRUE;
+  ThermalConfig->PchHotEnable        = PcdGetBool (PcdPchThermalHotEnable);
+
+  DmiHaAWC = &ThermalConfig->DmiHaAWC;
+  DmiHaAWC->TS3TW = 0;
+  DmiHaAWC->TS2TW = 1;
+  DmiHaAWC->TS1TW = 2;
+  DmiHaAWC->TS0TW = 3;
+  //
+  // Update Pch Usb Config
+  //
+  UpdatePchUsbConfig (
+    UsbConfig
+    );
+
+  ScsConfig->ScsUfsEnabled = 0;
+  ScsConfig->ScsEmmcHs400Enabled = 1;
+  ScsConfig->ScsEmmcHs400TuningRequired = TRUE;
+
+  IshConfig->I2c0GpioAssign = 1;
+  IshConfig->I2c1GpioAssign = 1;
+  IshConfig->Gp0GpioAssign = 1;
+  IshConfig->Gp1GpioAssign = 1;
+  IshConfig->Gp2GpioAssign = 1;
+  IshConfig->Gp3GpioAssign = 1;
+  IshConfig->Gp4GpioAssign = 1;
+  IshConfig->Gp5GpioAssign = 1;
+  IshConfig->Gp6GpioAssign = 1;
+
+  return Status;
+}
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..968df0f55c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c
@@ -0,0 +1,113 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PchPolicyLib.h>
+
+//
+// Sawtooth Peak
+// Single SPD EEPROM at 0xA2 serves both C0D0 and C1D0 (LPDDR is 1DPC only)
+//
+#define DIMM_SMB_SPD_P0C0D0_STP 0xA2
+#define DIMM_SMB_SPD_P0C0D1_STP 0xA0
+#define DIMM_SMB_SPD_P0C1D0_STP 0xA2
+#define DIMM_SMB_SPD_P0C1D1_STP 0xA0
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusSTPRsvdAddresses[] = {
+  DIMM_SMB_SPD_P0C0D0_STP,
+  DIMM_SMB_SPD_P0C0D1_STP,
+  DIMM_SMB_SPD_P0C1D0_STP,
+  DIMM_SMB_SPD_P0C1D1_STP
+};
+
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPreMemPolicy  The SI PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT8                           *SmBusReservedTable;
+  UINT8                           SmBusReservedNum;
+
+  PCH_GENERAL_PREMEM_CONFIG       *PchGeneralPreMemConfig;
+  PCH_TRACE_HUB_PREMEM_CONFIG     *PchTraceHubPreMemConfig;
+  PCH_SMBUS_PREMEM_CONFIG         *SmbusPreMemConfig;
+  PCH_LPC_PREMEM_CONFIG           *LpcPreMemConfig;
+  PCH_WDT_PREMEM_CONFIG           *WatchDogPreMemConfig;
+  PCH_DCI_PREMEM_CONFIG           *DciPreMemConfig;
+  PCH_PCIE_RP_PREMEM_CONFIG       *PcieRpPreMemConfig;
+  PCH_HDAUDIO_PREMEM_CONFIG       *HdaPreMemConfig;
+  PCH_ISH_PREMEM_CONFIG           *IshPreMemConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gWatchDogPreMemConfigGuid, (VOID *) &WatchDogPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DciPreMemConfig->DciUsb3TypecUfpDbg = 2;
+  PchTraceHubPreMemConfig->MemReg0Size = 3;
+  PchTraceHubPreMemConfig->MemReg1Size = 3;
+  //
+  // SMBUS
+  //
+  SmbusPreMemConfig->Enable = TRUE;
+  SmbusPreMemConfig->SmbAlertEnable = PcdGetBool (PcdSmbusAlertEnable);
+  //
+  // SMBUS reserved addresses
+  //
+  SmBusReservedTable = NULL;
+  SmBusReservedNum   = 0;
+  SmbusPreMemConfig->SmbusIoBase = PcdGet16 (PcdSmbusBaseAddress);
+  SmBusReservedTable = mSmbusSTPRsvdAddresses;
+  SmBusReservedNum   = sizeof (mSmbusSTPRsvdAddresses);
+
+  if (SmBusReservedTable != NULL) {
+    SmbusPreMemConfig->NumRsvdSmbusAddresses = SmBusReservedNum;
+    CopyMem (
+      SmbusPreMemConfig->RsvdSmbusAddressTable,
+      SmBusReservedTable,
+      SmBusReservedNum
+      );
+  }
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
new file mode 100644
index 0000000000..c1ac7d890f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
@@ -0,0 +1,242 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <Protocol/GraphicsOutput.h>
+#include <IndustryStandard/Bmp.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Library/HobLib.h>
+#include <Platform.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Core/Pei/PeiMain.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+
+/**
+  UpdatePeiSaPolicy performs SA PEI Policy initialization
+
+  @param[in out] SiPolicyPpi     - SI_POLICY PPI
+
+  @retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+UpdatePeiSaPolicy (
+  IN OUT   SI_POLICY_PPI      *SiPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_GUID                        FileGuid;
+  VOID                            *Buffer;
+  UINT8                           SaDisplayConfigTable[9] = {0};
+  VOID                            *MemBuffer;
+  BMP_IMAGE_HEADER                *BmpHeader;
+  UINT64                          BltBufferSize;
+  UINT32                          Size;
+  GRAPHICS_PEI_CONFIG             *GtConfig;
+  GNA_CONFIG                      *GnaConfig;
+  WDT_PPI                         *gWdtPei;
+  PCIE_PEI_CONFIG                 *PciePeiConfig;
+  SA_MISC_PEI_CONFIG              *MiscPeiConfig;
+  EFI_BOOT_MODE                   BootMode;
+
+  DEBUG((DEBUG_INFO, "\nUpdating SA Policy in Post Mem\n"));
+
+  Size = 0;
+  MemBuffer = NULL;
+  BmpHeader = NULL;
+  BltBufferSize = 0;
+  GtConfig = NULL;
+  GnaConfig = NULL;
+
+  Status = GetConfigBlock((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *)&GtConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPolicyPpi, &gGnaConfigGuid, (VOID *)&GnaConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID *)&PciePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid, (VOID *)&MiscPeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Locate WDT_PPI (ICC WDT PPI)
+  //
+  gWdtPei = NULL;
+  Status = PeiServicesLocatePpi(
+             &gWdtPpiGuid,
+             0,
+             NULL,
+             (VOID **) &gWdtPei
+             );
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  if (!EFI_ERROR (Status)) {
+    Buffer = NULL;
+
+    CopyMem(&FileGuid, PcdGetPtr(PcdIntelGraphicsVbtFileGuid), sizeof(FileGuid));
+    PeiGetSectionFromFv(FileGuid, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_ERROR, "Could not locate VBT\n"));
+    }
+
+    MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+    if ((MemBuffer != NULL) && (Buffer != NULL)) {
+      CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+      GtConfig->GraphicsConfigPtr = MemBuffer;
+    } else {
+      DEBUG((DEBUG_WARN, "Error in locating / copying VBT.\n"));
+      GtConfig->GraphicsConfigPtr = NULL;
+    }
+
+    GtConfig->PeiGraphicsPeimInit = 1;
+
+    DEBUG((DEBUG_INFO, "Vbt Pointer from PeiGetSectionFromFv is 0x%x\n", GtConfig->GraphicsConfigPtr));
+    DEBUG((DEBUG_INFO, "Vbt Size from PeiGetSectionFromFv is 0x%x\n", Size));
+
+    PeiGetSectionFromFv (gTianoLogoGuid, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_WARN, "Could not locate Logo\n"));
+    }
+
+    MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+    if ((MemBuffer != NULL) && (Buffer != NULL)) {
+      CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+      GtConfig->LogoPtr = MemBuffer;
+      GtConfig->LogoSize = Size;
+
+      //
+      // Calculate the BltBuffer needed size.
+      //
+      BmpHeader = (BMP_IMAGE_HEADER *) GtConfig->LogoPtr;
+
+      if (BmpHeader->CharB == 'B' && BmpHeader->CharM == 'M') {
+        BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+        if (BltBufferSize < DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+          BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+          GtConfig->BltBufferSize    = (UINT32) BltBufferSize;
+          GtConfig->BltBufferAddress = (VOID *) AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)GtConfig->BltBufferSize));
+        } else {
+          DEBUG ((DEBUG_ERROR, "Blt Buffer Size overflow.\n"));
+          ASSERT (FALSE);
+        }
+      } else {
+        DEBUG ((DEBUG_ERROR, "Wrong Bmp Image Header.\n"));
+        ASSERT (FALSE);
+      }
+
+    } else {
+      DEBUG((DEBUG_WARN, "Error in locating / copying LogoPtr.\n"));
+      GtConfig->LogoPtr = NULL;
+      GtConfig->LogoSize = 0;
+    }
+
+    DEBUG((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", GtConfig->LogoPtr));
+    DEBUG((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", GtConfig->LogoSize));
+
+    //
+    // Display DDI Initialization ( default Native GPIO as per board during AUTO case)
+    //
+    if (PcdGet32 (PcdSaDisplayConfigTable) != 0) {
+      CopyMem (SaDisplayConfigTable, (VOID *) (UINTN) PcdGet32 (PcdSaDisplayConfigTable), (UINTN)PcdGet16 (PcdSaDisplayConfigTableSize));
+      GtConfig->DdiConfiguration.DdiPortEdp     = SaDisplayConfigTable[0];
+      GtConfig->DdiConfiguration.DdiPortBHpd    = SaDisplayConfigTable[1];
+      GtConfig->DdiConfiguration.DdiPortCHpd    = SaDisplayConfigTable[2];
+      GtConfig->DdiConfiguration.DdiPortDHpd    = SaDisplayConfigTable[3];
+      GtConfig->DdiConfiguration.DdiPortFHpd    = SaDisplayConfigTable[4];
+      GtConfig->DdiConfiguration.DdiPortBDdc    = SaDisplayConfigTable[5];
+      GtConfig->DdiConfiguration.DdiPortCDdc    = SaDisplayConfigTable[6];
+      GtConfig->DdiConfiguration.DdiPortDDdc    = SaDisplayConfigTable[7];
+      GtConfig->DdiConfiguration.DdiPortFDdc    = SaDisplayConfigTable[8];
+    }
+  }
+
+  PciePeiConfig->DmiAspm = 0x3;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32                *Size
+  )
+{
+  EFI_STATUS                           Status;
+  EFI_PEI_FIRMWARE_VOLUME_PPI          *FvPpi;
+  EFI_FV_FILE_INFO                     FvFileInfo;
+  PEI_CORE_INSTANCE                    *PrivateData;
+  UINTN                                CurrentFv;
+  PEI_CORE_FV_HANDLE                   *CoreFvHandle;
+  EFI_PEI_FILE_HANDLE                  VbtFileHandle;
+  EFI_GUID                             *VbtGuid;
+  EFI_COMMON_SECTION_HEADER            *Section;
+  CONST EFI_PEI_SERVICES               **PeiServices;
+
+  PeiServices = GetPeiServicesTablePointer();
+
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+  Status = PeiServicesLocatePpi(
+             &gEfiFirmwareFileSystem2Guid,
+             0,
+             NULL,
+             (VOID **)&FvPpi
+             );
+  ASSERT_EFI_ERROR(Status);
+
+  CurrentFv = PrivateData->CurrentPeimFvCount;
+  CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+  Status = FvPpi->FindFileByName(FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+  if (!EFI_ERROR(Status) && VbtFileHandle != NULL) {
+
+    DEBUG((DEBUG_INFO, "Find SectionByType \n"));
+
+    Status = FvPpi->FindSectionByType(FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **)&VbtGuid);
+    if (!EFI_ERROR(Status)) {
+
+      DEBUG((DEBUG_INFO, "GetFileInfo \n"));
+
+      Status = FvPpi->GetFileInfo(FvPpi, VbtFileHandle, &FvFileInfo);
+      Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
+
+      if (IS_SECTION2(Section)) {
+        ASSERT(SECTION2_SIZE(Section) > 0x00FFFFFF);
+        *Size = SECTION2_SIZE(Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+      } else {
+        *Size = SECTION_SIZE(Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..3dc455ab29
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c
@@ -0,0 +1,221 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <CpuRegs.h>
+#include <Register/Cpuid.h>
+#include <Library/CpuPlatformLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Library/HobLib.h>
+#include <Platform.h>
+#include <PlatformBoardConfig.h>
+#include <Library/SiPolicyLib.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/GpioLib.h>
+
+///
+/// Memory Reserved should be between 125% to 150% of the Current required memory
+/// otherwise BdsMisc.c would do a reset to make it 125% to avoid s4 resume issues.
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+  { EfiACPIReclaimMemory,   FixedPcdGet32 (PcdPlatformEfiAcpiReclaimMemorySize) },  // ASL
+  { EfiACPIMemoryNVS,       FixedPcdGet32 (PcdPlatformEfiAcpiNvsMemorySize) },      // ACPI NVS (including S3 related)
+  { EfiReservedMemoryType,  FixedPcdGet32 (PcdPlatformEfiReservedMemorySize) },     // BIOS Reserved (including S3 related)
+  { EfiRuntimeServicesData, FixedPcdGet32 (PcdPlatformEfiRtDataMemorySize) },       // Runtime Service Data
+  { EfiRuntimeServicesCode, FixedPcdGet32 (PcdPlatformEfiRtCodeMemorySize) },       // Runtime Service Code
+  { EfiMaxMemoryType, 0 }
+};
+
+
+/**
+  UpdatePeiSaPolicyPreMem performs SA PEI Policy initialization
+
+  @param[in out] SiPreMemPolicyPpi - SI_PREMEM_POLICY PPI
+
+  @retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+UpdatePeiSaPolicyPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  SA_MISC_PEI_PREMEM_CONFIG       *MiscPeiPreMemConfig = NULL;
+  MEMORY_CONFIG_NO_CRC            *MemConfigNoCrc = NULL;
+  SA_MEMORY_RCOMP                 *RcompData;
+  WDT_PPI                         *gWdtPei;
+  UINT8                           Index;
+  UINTN                           DataSize;
+  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType + 1];
+  EFI_BOOT_MODE                   BootMode;
+  UINT8                           MorControl;
+  UINT32                          TraceHubTotalMemSize;
+  GRAPHICS_PEI_PREMEM_CONFIG      *GtPreMemConfig = NULL;
+  MEMORY_CONFIGURATION            *MemConfig = NULL;
+  PCIE_PEI_PREMEM_CONFIG          *PciePeiPreMemConfig = NULL;
+  SWITCHABLE_GRAPHICS_CONFIG      *SgGpioData = NULL;
+  IPU_PREMEM_CONFIG               *IpuPreMemPolicy = NULL;
+  OVERCLOCKING_PREMEM_CONFIG      *OcPreMemConfig = NULL;
+  VTD_CONFIG                      *Vtd = NULL;
+  UINT32                          ProcessorTraceTotalMemSize;
+  UINT16                          AdjustedMmioSize;
+  CPU_FAMILY                      CpuFamilyId;
+  CPU_STEPPING                    CpuStepping;
+
+  TraceHubTotalMemSize = 0;
+  ProcessorTraceTotalMemSize = 0;
+  AdjustedMmioSize = PcdGet16 (PcdSaMiscMmioSizeAdjustment);
+  CpuFamilyId = GetCpuFamily();
+  CpuStepping = GetCpuStepping();
+
+  DEBUG((DEBUG_INFO, "Entering Get Config Block function call from UpdatePeiSaPolicyPreMem\n"));
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *) &SgGpioData);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gVtdConfigGuid, (VOID *)&Vtd);
+  ASSERT_EFI_ERROR(Status);
+
+
+  RcompData = MemConfigNoCrc->RcompData;
+
+  //
+  // Locate WDT_PPI (ICC WDT PPI)
+  //
+  gWdtPei = NULL;
+  Status = PeiServicesLocatePpi(
+             &gWdtPpiGuid,
+             0,
+             NULL,
+             (VOID **) &gWdtPei
+             );
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  MiscPeiPreMemConfig->S3DataPtr = NULL;
+  MorControl = 0;
+  MiscPeiPreMemConfig->UserBd = 0; // It's a CRB mobile board by default (btCRBMB)
+
+  PcdSetBoolS (PcdMobileDramPresent, (BOOLEAN) (MemConfig->MobilePlatform));
+  MiscPeiPreMemConfig->SpdAddressTable[0] = PcdGet8 (PcdMrcSpdAddressTable0);
+  MiscPeiPreMemConfig->SpdAddressTable[1] = PcdGet8 (PcdMrcSpdAddressTable1);
+  MiscPeiPreMemConfig->SpdAddressTable[2] = PcdGet8 (PcdMrcSpdAddressTable2);
+  MiscPeiPreMemConfig->SpdAddressTable[3] = PcdGet8 (PcdMrcSpdAddressTable3);
+  MemConfig->CaVrefConfig                 = PcdGet8 (PcdMrcCaVrefConfig);
+  MemConfig->DualDimmPerChannelBoardType  = PcdGetBool (PcdDualDimmPerChannelBoardType);
+  if (PcdGet32 (PcdMrcRcompResistor)) {
+    CopyMem((VOID *)RcompData->RcompResistor, (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor), sizeof (RcompData->RcompResistor));
+  }
+  if (PcdGet32 (PcdMrcRcompTarget)) {
+    CopyMem((VOID *)RcompData->RcompTarget, (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget), sizeof (RcompData->RcompTarget));
+  }
+  if (PcdGet32 (PcdMrcDqByteMap)) {
+    CopyMem((VOID *)MemConfigNoCrc->DqByteMap, (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap), sizeof (UINT8)* SA_MC_MAX_CHANNELS * SA_MRC_ITERATION_MAX * 2);
+  }
+  if (PcdGet32 (PcdMrcDqsMapCpu2Dram)) {
+    CopyMem((VOID *)MemConfigNoCrc->DqsMap, (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram), sizeof (UINT8)* SA_MC_MAX_CHANNELS * SA_MC_MAX_BYTES_NO_ECC);
+  }
+  if (PcdGetBool (PcdMrcDqPinsInterleavedControl)) {
+    MemConfig->DqPinsInterleaved = PcdGetBool (PcdMrcDqPinsInterleaved);
+  }
+  if (PcdGet32 (PcdMrcSpdData)) {
+    CopyMem((VOID *)MemConfigNoCrc->SpdData->SpdData[0][0], (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData), SPD_DATA_SIZE);
+    CopyMem((VOID *)MemConfigNoCrc->SpdData->SpdData[1][0], (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData), SPD_DATA_SIZE);
+  }
+
+  MiscPeiPreMemConfig->MchBar   = (UINTN) PcdGet64 (PcdMchBaseAddress);
+  MiscPeiPreMemConfig->DmiBar   = (UINTN) PcdGet64 (PcdDmiBaseAddress);
+  MiscPeiPreMemConfig->EpBar    = (UINTN) PcdGet64 (PcdEpBaseAddress);
+  MiscPeiPreMemConfig->EdramBar = (UINTN) PcdGet64 (PcdEdramBaseAddress);
+  MiscPeiPreMemConfig->SmbusBar = PcdGet16(PcdSmbusBaseAddress);
+  MiscPeiPreMemConfig->TsegSize = PcdGet32(PcdTsegSize);
+  MiscPeiPreMemConfig->UserBd   = PcdGet8 (PcdSaMiscUserBd);
+  MiscPeiPreMemConfig->MmioSizeAdjustment = PcdGet16 (PcdSaMiscMmioSizeAdjustment);
+  if (PcdGetBool (PcdPegGpioResetControl)) {
+    PciePeiPreMemConfig->PegGpioData.GpioSupport = PcdGetBool (PcdPegGpioResetSupoort);
+  } else {
+
+  }
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad = PcdGet32 (PcdPeg0ResetGpioPad);
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active  = PcdGetBool (PcdPeg0ResetGpioActive);
+
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad = PcdGet32 (PcdPeg3ResetGpioPad);
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active  = PcdGetBool (PcdPeg3ResetGpioActive);
+
+  MemConfig->CkeRankMapping = 0xAA;
+  ///
+  /// Initialize the VTD Configuration
+  ///
+  Vtd->VtdDisable = 0;
+
+  MemConfig->RMT = 1;
+  MemConfig->UserPowerWeightsEn = 0;
+  MemConfig->RaplLim2WindY = 0x0A;
+  MemConfig->ExitOnFailure = 1;
+
+  MemConfigNoCrc->PlatformMemorySize = PEI_MIN_MEMORY_SIZE + TraceHubTotalMemSize + ProcessorTraceTotalMemSize;
+  DataSize = sizeof (mDefaultMemoryTypeInformation);
+  CopyMem(MemoryData, mDefaultMemoryTypeInformation, DataSize);
+
+  if (BootMode != BOOT_IN_RECOVERY_MODE) {
+    for (Index = 0; Index < DataSize / sizeof (EFI_MEMORY_TYPE_INFORMATION); Index++) {
+      MemConfigNoCrc->PlatformMemorySize += MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE;
+    }
+
+    OcPreMemConfig->GtMaxOcRatio = 0;
+    OcPreMemConfig->GtVoltageMode = 0;
+    OcPreMemConfig->GtVoltageOverride = 0;
+    OcPreMemConfig->GtExtraTurboVoltage = 0;
+    OcPreMemConfig->GtVoltageOffset = 0;
+    OcPreMemConfig->SaVoltageOffset = 0;
+    OcPreMemConfig->GtusMaxOcRatio = 0;
+    OcPreMemConfig->GtusVoltageMode = 0;
+    OcPreMemConfig->GtusVoltageOverride = 0;
+    OcPreMemConfig->GtusExtraTurboVoltage = 0;
+    OcPreMemConfig->GtusVoltageOffset = 0;
+
+    ///
+    /// Build the GUID'd HOB for DXE
+    ///
+    BuildGuidDataHob (
+      &gEfiMemoryTypeInformationGuid,
+      MemoryData,
+      DataSize
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
new file mode 100644
index 0000000000..3efbe2ccbd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
@@ -0,0 +1,168 @@
+/** @file
+  This file is SampleCode of the library for Intel Silicon PEI
+  Platform Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyUpdate.h"
+#include <MeChipset.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+STATIC SVID_SID_INIT_ENTRY mCdfSsidTablePtr[] = {
+  //
+  // SA Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    SA_MC_FUN,        SA_MC_DEV,        SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG0_FUN_NUM,  SA_PEG0_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG1_FUN_NUM,  SA_PEG1_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG2_FUN_NUM,  SA_PEG2_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IGD_FUN_0,     SA_IGD_DEV,       SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IPU_FUN_NUM,   SA_IPU_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_GNA_FUN_NUM,   SA_GNA_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  //
+  // PCH Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LPC,               PCI_DEVICE_NUMBER_PCH_LPC,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_P2SB,              PCI_DEVICE_NUMBER_PCH_P2SB,          DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_PMC,               PCI_DEVICE_NUMBER_PCH_PMC,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_HDA,               PCI_DEVICE_NUMBER_PCH_HDA,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1,        PCI_DEVICE_NUMBER_CDF_PCH_SATA_1,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2,        PCI_DEVICE_NUMBER_CDF_PCH_SATA_2,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3,        PCI_DEVICE_NUMBER_CDF_PCH_SATA_3,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SMBUS,             PCI_DEVICE_NUMBER_PCH_SMBUS,         DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SPI,               PCI_DEVICE_NUMBER_PCH_SPI,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_TRACE_HUB,         PCI_DEVICE_NUMBER_PCH_TRACE_HUB,     DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_XHCI,              PCI_DEVICE_NUMBER_PCH_XHCI,          DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_XDCI,              PCI_DEVICE_NUMBER_PCH_XDCI,          DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_THERMAL,           PCI_DEVICE_NUMBER_PCH_THERMAL,       DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+};
+
+STATIC SVID_SID_INIT_ENTRY mSsidTablePtr[] = {
+  //
+  // SA Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    SA_MC_FUN,        SA_MC_DEV,        SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG0_FUN_NUM,  SA_PEG0_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG1_FUN_NUM,  SA_PEG1_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG2_FUN_NUM,  SA_PEG2_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IGD_FUN_0,     SA_IGD_DEV,       SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IPU_FUN_NUM,   SA_IPU_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_GNA_FUN_NUM,   SA_GNA_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  //
+  // PCH Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LPC,     PCI_DEVICE_NUMBER_PCH_LPC,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_P2SB,    PCI_DEVICE_NUMBER_PCH_P2SB,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_PMC,     PCI_DEVICE_NUMBER_PCH_PMC,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_HDA,     PCI_DEVICE_NUMBER_PCH_HDA,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SATA,    PCI_DEVICE_NUMBER_PCH_SATA,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SMBUS,   PCI_DEVICE_NUMBER_PCH_SMBUS,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SPI,     PCI_DEVICE_NUMBER_PCH_SPI,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  //
+  // Skip PCH LAN controller
+  // PCH LAN SVID/SID may be loaded automatically from the NVM Word 0Ch/0Bh upon power up or reset
+  // depending on the "Load Subsystem ID" bit field in NVM word 0Ah
+  //
+  //{{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LAN,     PCI_DEVICE_NUMBER_PCH_LAN,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_TRACE_HUB,       PCI_DEVICE_NUMBER_PCH_TRACE_HUB,        DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0, PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1, PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_CNL_SCS_SDCARD, PCI_DEVICE_NUMBER_PCH_CNL_SCS_SDCARD, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_XHCI,       PCI_DEVICE_NUMBER_PCH_XHCI,       DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_XDCI,       PCI_DEVICE_NUMBER_PCH_XDCI,       DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_THERMAL,    PCI_DEVICE_NUMBER_PCH_THERMAL,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_ISH,               PCI_DEVICE_NUMBER_PCH_ISH,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_13, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_14, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_15, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_16, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_17, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_18, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_19, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_20, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_21, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_22, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_23, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_24, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2, PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  //
+  // ME Device(s)
+  //
+  {{{PCI_SVID_OFFSET,  HECI_FUNCTION_NUMBER,  ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  HECI2_FUNCTION_NUMBER, ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  IDER_FUNCTION_NUMBER,  ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  SOL_FUNCTION_NUMBER,   ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  HECI3_FUNCTION_NUMBER, ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  HECI4_FUNCTION_NUMBER, ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0}
+};
+
+/**
+  This function performs Silicon PEI Policy initialization.
+
+  @param[in] SiPolicy  The Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS  The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicy (
+  IN OUT SI_POLICY_PPI *SiPolicy
+  )
+{
+  EFI_STATUS                         Status;
+  SI_CONFIG                          *SiConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  SiConfig->CsmFlag       = 0;
+
+  if (IsCdfPch ()) {
+    SiConfig->SsidTablePtr = (UINT32*)(UINTN) mCdfSsidTablePtr;
+    SiConfig->NumberOfSsidTableEntry = (sizeof (mCdfSsidTablePtr) / sizeof (SVID_SID_INIT_ENTRY));
+  } else {
+    SiConfig->SsidTablePtr = (UINT32*)(UINTN) mSsidTablePtr;
+    SiConfig->NumberOfSsidTableEntry = (sizeof (mSsidTablePtr) / sizeof (SVID_SID_INIT_ENTRY));
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
new file mode 100644
index 0000000000..5c5b788085
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
@@ -0,0 +1,130 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;  PeiCoreEntry.nasm
+;
+; Abstract:
+;
+;   Find and call SecStartup
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(SecStartup)
+extern ASM_PFX(PlatformInit)
+
+global ASM_PFX(CallPeiCoreEntryPoint)
+ASM_PFX(CallPeiCoreEntryPoint):
+  ;
+  ; Obtain the hob list pointer
+  ;
+  mov     eax, [esp+4]
+  ;
+  ; Obtain the stack information
+  ;   ECX: start of range
+  ;   EDX: end of range
+  ;
+  mov     ecx, [esp+8]
+  mov     edx, [esp+0xC]
+
+  ;
+  ; Platform init
+  ;
+  pushad
+  push edx
+  push ecx
+  push eax
+  call ASM_PFX(PlatformInit)
+  pop  eax
+  pop  eax
+  pop  eax
+  popad
+
+  ;
+  ; Set stack top pointer
+  ;
+  mov     esp, edx
+
+  ;
+  ; Push the hob list pointer
+  ;
+  push    eax
+
+  ;
+  ; Save the value
+  ;   ECX: start of range
+  ;   EDX: end of range
+  ;
+  mov     ebp, esp
+  push    ecx
+  push    edx
+
+  ;
+  ; Push processor count to stack first, then BIST status (AP then BSP)
+  ;
+  mov     eax, 1
+  cpuid
+  shr     ebx, 16
+  and     ebx, 0xFF
+  cmp     bl, 1
+  jae     PushProcessorCount
+
+  ;
+  ; Some processors report 0 logical processors.  Effectively 0 = 1.
+  ; So we fix up the processor count
+  ;
+  inc     ebx
+
+PushProcessorCount:
+  push    ebx
+
+  ;
+  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST
+  ; for all processor threads
+  ;
+  xor     ecx, ecx
+  mov     cl, bl
+PushBist:
+  movd    eax, mm0
+  push    eax
+  loop    PushBist
+
+  ; Save Time-Stamp Counter
+  movd eax, mm5
+  push eax
+
+  movd eax, mm6
+  push eax
+
+  ;
+  ; Pass entry point of the PEI core
+  ;
+  mov     edi, 0xFFFFFFE0
+  push    DWORD [edi]
+
+  ;
+  ; Pass BFV into the PEI Core
+  ;
+  mov     edi, 0xFFFFFFFC
+  push    DWORD [edi]
+
+  ;
+  ; Pass stack size into the PEI Core
+  ;
+  mov     ecx, [ebp - 4]
+  mov     edx, [ebp - 8]
+  push    ecx       ; RamBase
+
+  sub     edx, ecx
+  push    edx       ; RamSize
+
+  ;
+  ; Pass Control into the PEI Core
+  ;
+  call ASM_PFX(SecStartup)
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..7f6d771e41
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
@@ -0,0 +1,361 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+; Module Name:
+;
+;  SecEntry.nasm
+;
+; Abstract:
+;
+;  This is the code that goes from real-mode to protected mode.
+;  It consumes the reset vector, calls TempRamInit API from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+#include "Fsp.h"
+
+SECTION .text
+
+extern   ASM_PFX(CallPeiCoreEntryPoint)
+extern   ASM_PFX(FsptUpdDataPtr)
+extern   ASM_PFX(BoardBeforeTempRamInit)
+; Pcds
+extern   ASM_PFX(PcdGet32 (PcdFspTemporaryRamSize))
+extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    _ModuleEntryPoint
+;
+; Input:        None
+;
+; Output:       None
+;
+; Destroys:     Assume all registers
+;
+; Description:
+;
+;   Transition to non-paged flat-model protected mode from a
+;   hard-coded GDT that provides exactly two descriptors.
+;   This is a bare bones transition to protected mode only
+;   used for a while in PEI and possibly DXE.
+;
+;   After enabling protected mode, a far jump is executed to
+;   transfer to PEI using the newly loaded GDT.
+;
+; Return:       None
+;
+;  MMX Usage:
+;              MM0 = BIST State
+;              MM5 = Save time-stamp counter value high32bit
+;              MM6 = Save time-stamp counter value low32bit.
+;
+;----------------------------------------------------------------------------
+
+BITS 16
+align 4
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  fninit                                ; clear any pending Floating point exceptions
+  ;
+  ; Store the BIST value in mm0
+  ;
+  movd    mm0, eax
+  cli
+
+  ;
+  ; Check INIT# is asserted by port 0xCF9
+  ;
+  mov dx, 0CF9h
+  in  al, dx
+  cmp al, 04h
+  jnz NotWarmStart
+
+
+  ;
+  ; @note Issue warm reset, since if CPU only reset is issued not all MSRs are restored to their defaults
+  ;
+  mov dx, 0CF9h
+  mov al, 06h
+  out dx, al
+
+NotWarmStart:
+  ;
+  ; Save time-stamp counter value
+  ; rdtsc load 64bit time-stamp counter to EDX:EAX
+  ;
+  rdtsc
+  movd    mm5, edx
+  movd    mm6, eax
+
+  ;
+  ; Load the GDT table in GdtDesc
+  ;
+  mov     esi,  GdtDesc
+  DB      66h
+  lgdt    [cs:si]
+
+  ;
+  ; Transition to 16 bit protected mode
+  ;
+  mov     eax, cr0                   ; Get control register 0
+  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)
+  mov     cr0, eax                   ; Activate protected mode
+
+  mov     eax, cr4                   ; Get control register 4
+  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+  mov     cr4, eax
+
+  ;
+  ; Now we're in 16 bit protected mode
+  ; Set up the selectors for 32 bit protected mode entry
+  ;
+  mov     ax, SYS_DATA_SEL
+  mov     ds, ax
+  mov     es, ax
+  mov     fs, ax
+  mov     gs, ax
+  mov     ss, ax
+
+  ;
+  ; Transition to Flat 32 bit protected mode
+  ; The jump to a far pointer causes the transition to 32 bit mode
+  ;
+  mov esi, ProtectedModeEntryLinearAddress
+  jmp   dword far  [cs:si]
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    ProtectedModeEntryPoint
+;
+; Input:        None
+;
+; Output:       None
+;
+; Destroys:     Assume all registers
+;
+; Description:
+;
+; This function handles:
+;   Call two basic APIs from FSP binary
+;   Initializes stack with some early data (BIST, PEI entry, etc)
+;
+; Return:       None
+;
+;----------------------------------------------------------------------------
+
+BITS 32
+align 4
+ProtectedModeEntryPoint:
+  ;
+  ; Early board hooks
+  ;
+  mov     esp, BoardBeforeTempRamInitRet
+  jmp     ASM_PFX(BoardBeforeTempRamInit)
+
+BoardBeforeTempRamInitRet:
+
+  ; Find the fsp info header
+  mov  edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]
+
+  mov  eax, dword [edi + FVH_SIGINATURE_OFFSET]
+  cmp  eax, FVH_SIGINATURE_VALID_VALUE
+  jnz  FspHeaderNotFound
+
+  xor  eax, eax
+  mov  ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]
+  cmp  ax, 0
+  jnz  FspFvExtHeaderExist
+
+  xor  eax, eax
+  mov  ax, word [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header
+  add  edi, eax
+  jmp  FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+  add  edi, eax
+  mov  eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv Header
+  add  edi, eax
+
+  ; Round up to 8 byte alignment
+  mov  eax, edi
+  and  al,  07h
+  jz   FspCheckFfsHeader
+
+  and  edi, 0FFFFFFF8h
+  add  edi, 08h
+
+FspCheckFfsHeader:
+  ; Check the ffs guid
+  mov  eax, dword [edi]
+  cmp  eax, FSP_HEADER_GUID_DWORD1
+  jnz  FspHeaderNotFound
+
+  mov  eax, dword [edi + 4]
+  cmp  eax, FSP_HEADER_GUID_DWORD2
+  jnz  FspHeaderNotFound
+
+  mov  eax, dword [edi + 8]
+  cmp  eax, FSP_HEADER_GUID_DWORD3
+  jnz  FspHeaderNotFound
+
+  mov  eax, dword [edi + 0Ch]
+  cmp  eax, FSP_HEADER_GUID_DWORD4
+  jnz  FspHeaderNotFound
+
+  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header
+
+  ; Check the section type as raw section
+  mov  al, byte [edi + SECTION_HEADER_TYPE_OFFSET]
+  cmp  al, 019h
+  jnz FspHeaderNotFound
+
+  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
+  jmp FspHeaderFound
+
+FspHeaderNotFound:
+  jmp  $
+
+FspHeaderFound:
+  ; Get the fsp TempRamInit Api address
+  mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]
+  add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
+
+  ; Setup the hardcode stack
+  mov esp, TempRamInitStack
+
+  ; Call the fsp TempRamInit Api
+  jmp eax
+
+TempRamInitDone:
+  cmp eax, 8000000Eh      ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.
+  je  CallSecFspInit      ;If microcode not found, don't hang, but continue.
+
+  cmp eax, 0              ;Check if EFI_SUCCESS retuned.
+  jnz FspApiFailed
+
+  ;   ECX: start of range
+  ;   EDX: end of range
+CallSecFspInit:
+  sub     edx, [ASM_PFX(PcdGet32 (PcdFspTemporaryRamSize))] ; TemporaryRam for FSP
+  xor     eax, eax
+  mov     esp, edx
+
+  ; Align the stack at DWORD
+  add  esp,  3
+  and  esp, 0FFFFFFFCh
+
+  push    edx
+  push    ecx
+  push    eax ; zero - no hob list yet
+  call    ASM_PFX(CallPeiCoreEntryPoint)
+
+FspApiFailed:
+  jmp $
+
+align 10h
+TempRamInitStack:
+    DD  TempRamInitDone
+    DD  ASM_PFX(FsptUpdDataPtr); TempRamInitParams
+
+;
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase
+;
+align 16
+global  ASM_PFX(BootGdtTable)
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]
+GDT_BASE:
+ASM_PFX(BootGdtTable):
+                    DD  0
+                    DD  0
+;
+; Linear data segment descriptor
+;
+LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  092h                            ; present, ring 0, data, expand-up, writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  09Bh                            ; present, ring 0, data, expand-up, not-writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+
+;
+; System code segment descriptor
+;
+SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  09Ah                            ; present, ring 0, data, expand-up, writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; Spare segment descriptor
+;
+SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0Eh                             ; Changed from F000 to E000.
+    DB  09Bh                            ; present, ring 0, code, expand-up, writable
+    DB  00h                             ; byte-granular, 16-bit
+    DB  0
+;
+; Spare segment descriptor
+;
+SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]
+    DW  0FFFFh                          ; limit 0xFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable
+    DB  00h                             ; byte-granular, 16-bit
+    DB  0
+
+;
+; Spare segment descriptor
+;
+SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]
+    DW  0                               ; limit 0
+    DW  0                               ; base 0
+    DB  0
+    DB  0                               ; present, ring 0, data, expand-up, writable
+    DB  0                               ; page-granular, 32-bit
+    DB  0
+GDT_SIZE            EQU $ - GDT_BASE    ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc:                                ; GDT descriptor
+    DW  GDT_SIZE - 1                    ; GDT limit
+    DD  GDT_BASE                        ; GDT base address
+
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinear:
+  DD      ProtectedModeEntryPoint  ; Offset of our 32 bit code
+  DW      LINEAR_CODE_SEL
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
new file mode 100644
index 0000000000..47db32d64c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
@@ -0,0 +1,72 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+; Abstract:
+;
+;   Switch the stack from temporary memory to permanent memory.
+;
+;------------------------------------------------------------------------------
+
+    SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; SecSwitchStack (
+;   UINT32   TemporaryMemoryBase,
+;   UINT32   PermanentMemoryBase
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+    ;
+    ; Save three register: eax, ebx, ecx
+    ;
+    push  eax
+    push  ebx
+    push  ecx
+    push  edx
+
+    ;
+    ; !!CAUTION!! this function address's is pushed into stack after
+    ; migration of whole temporary memory, so need save it to permanent
+    ; memory at first!
+    ;
+
+    mov   ebx, [esp + 20]          ; Save the first parameter
+    mov   ecx, [esp + 24]          ; Save the second parameter
+
+    ;
+    ; Save this function's return address into permanent memory at first.
+    ; Then, Fixup the esp point to permanent memory
+    ;
+    mov   eax, esp
+    sub   eax, ebx
+    add   eax, ecx
+    mov   edx, dword [esp]         ; copy pushed register's value to permanent memory
+    mov   dword [eax], edx
+    mov   edx, dword [esp + 4]
+    mov   dword [eax + 4], edx
+    mov   edx, dword [esp + 8]
+    mov   dword [eax + 8], edx
+    mov   edx, dword [esp + 12]
+    mov   dword [eax + 12], edx
+    mov   edx, dword [esp + 16]    ; Update this function's return address into permanent memory
+    mov   dword [eax + 16], edx
+    mov   esp, eax                     ; From now, esp is pointed to permanent memory
+
+    ;
+    ; Fixup the ebp point to permanent memory
+    ;
+    mov   eax, ebp
+    sub   eax, ebx
+    add   eax, ecx
+    mov   ebp, eax                ; From now, ebp is pointed to permanent memory
+
+    pop   edx
+    pop   ecx
+    pop   ebx
+    pop   eax
+    ret
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
new file mode 100644
index 0000000000..33b4be68db
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
@@ -0,0 +1,15 @@
+/** @file
+  Base ACPI Timer Library
+  Provides basic timer support using the ACPI timer hardware.  The performance
+  counter features are provided by the processors time stamp counter.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#string STR_MODULE_ABSTRACT             #language en-US "ACPI Timer Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Provides basic timer support using the ACPI timer hardware."
+
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (32 preceding siblings ...)
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
@ 2019-08-17  0:16 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
                   ` (3 subsequent siblings)
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:16 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

WhiskeylakeURvp library instances.

* BaseFuncLib - Board-specific VBT update routines.
* BaseGpioCheckConflictLib - Identifies GPIO pad conflicts.
* BaseGpioCheckConflictLibNull - NULL library instance.
* BasePlatformHookLib - Serial port initialization support.
* DxePolicyBoardConfigLib - Board-specific silicon policy configuration
  in DXE.
* PeiBoardInitPostMemLib - PEI post-memory board-specific initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiBoardInitPreMemLib - PEI pre-memory board-specific initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiMultiBoardInitPostMemLib - PEI post-memory multi-board initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiMultiBoardInitPreMemLib - PEI pre-memory multi-board initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiPlatformHookLib - PEI board instance-specifc GPIO init.
* PeiPolicyBoardConfigLib - Board instance-specific policy init in PEI.
* SmmBoardAcpiEnableLib - Board instance-specific SMM ACPI enable support.
* SmmMultiBoardAcpiSupportLib - Multi-board ACPI support in SMM.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf                                   |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf         |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf                   |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf                        |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf                  |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf                       |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf                        |  116 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf                  |  202 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf                   |  296 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf                     |   94 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf           |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h                                      |   18 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h                                   |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h                            |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h                               |  225 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h                              |  284 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h                        |   59 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h                               | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h                      |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h                |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h                |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c                                             |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c           |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c   |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c                     |  156 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c                          |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c                    |   82 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c                        |  170 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c                |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c                                      |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c                                  |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c                            |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c                          |  398 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c                           |  282 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c                         |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c                          |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c                    |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c                     |   83 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c                       |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c               |  432 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c                |  636 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c                  |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c                       |  299 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c             |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c       |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c             |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c       |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c              |   27 +
 55 files changed, 8499 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
new file mode 100644
index 0000000000..0ccc73b99f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component information file for Board Functions Library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseBoardFuncInitLib
+  FILE_GUID                      = 7ad17b6c-b9b6-4d88-85c4-7366a2bd12a3
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL|PEIM
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+
+[Packages]
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  Gop.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
new file mode 100644
index 0000000000..5014faf664
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component information file for BaseGpioCheckConflictLib.
+#
+#
+#  Copyright (c) 2019, 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
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLib.c
+
+[Guids]
+  gGpioCheckConflictHobGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
new file mode 100644
index 0000000000..d9b242b3fc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
@@ -0,0 +1,32 @@
+## @file
+# Component information file for BaseGpioCheckConflictLib.
+#
+#
+#  Copyright (c) 2019, 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
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLibNull.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
new file mode 100644
index 0000000000..143bb89c63
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BasePlatformHookLib
+  FILE_GUID                      = E22ADCC6-ED90-4A90-9837-C8E7FF9E963D
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = PlatformHookLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciSegmentLib
+  PchCycleDecodingLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort                 ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort  ## CONSUMES
+
+[FixedPcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding            ## CONSUMES
+
+[Sources]
+  BasePlatformHookLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
new file mode 100644
index 0000000000..8ad32a55dc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmBoardAcpiEnableLib
+  FILE_GUID                      = 549E69AE-D3B3-485B-9C17-AF16E20A58AD
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = BoardAcpiEnableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciLib
+  MmPciLib
+  PchCycleDecodingLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
+
+[Protocols]
+
+[Sources]
+  SmmWhiskeylakeURvpAcpiEnableLib.c
+  SmmSiliconAcpiEnableLib.c
+  SmmBoardAcpiEnableLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
new file mode 100644
index 0000000000..27001c3b7f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmWhiskeylakeURvpMultiBoardAcpiSupportLib
+  FILE_GUID                      = 8929A54E-7ED8-4AB3-BEBB-C0367BDBBFF5
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciLib
+  PmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
+
+[Protocols]
+
+[Sources]
+  SmmWhiskeylakeURvpAcpiEnableLib.c
+  SmmSiliconAcpiEnableLib.c
+  SmmMultiBoardAcpiSupportLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..a8c4869e96
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Component information file for WhiskeylakeURvpInitLib in PEI post memory phase.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiBoardPostMemInitLib
+  FILE_GUID                      = 7fcc3900-d38d-419f-826b-72481e8b5509
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  HdaVerbTableLib
+  MemoryAllocationLib
+  GpioExpanderLib
+  PcdLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPostMemLib.c
+  PeiBoardInitPostMemLib.c
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
+
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
+
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..9361c3df3e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,116 @@
+## @file
+# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiBoardInitPreMemLib
+  FILE_GUID                      = ec3675bc-1470-417d-826e-37378140213d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  PcdLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpDetect.c
+  PeiWhiskeylakeURvpInitPreMemLib.c
+  WhiskeylakeURvpHsioPtssTables.c
+  PeiBoardInitPreMemLib.c
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
+
+  # PCH-LP HSIO PTSS Table
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
+
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..4831735dc5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
@@ -0,0 +1,202 @@
+## @file
+# Component information file for WhiskeylakeURvpInitLib in PEI post memory phase.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitLib
+  FILE_GUID                      = C7D39F17-E5BA-41D9-8DFE-FF9017499280
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = PeiWhiskeylakeURvpMultiBoardInitLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  GpioExpanderLib
+  PcdLib
+  MultiBoardInitSupportLib
+  HdaVerbTableLib
+  PeiPlatformHookLib
+  PeiPolicyInitLib
+  PchInfoLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPostMemLib.c
+  PeiMultiBoardInitPostMemLib.c
+  BoardFunc.c
+  BoardFuncInit.c
+
+[FixedPcd]
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
+
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
+
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
+
+  #===========================================================
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase
+  # Board Init Table List
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # WWAN Full Card Power Off and reset pins
+  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## PRODUCES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## PRODUCES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
+
+  # Pch PmConfig Policy
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
+
+
+  gBoardModuleTokenSpaceGuid.PcdSpdPresent
+  gBoardModuleTokenSpaceGuid.PcdBoardRev
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable
+  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable
+  # TPM interrupt
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
+
+[Guids]
+  gAttemptUsbFirstHotkeyInfoHobGuid             ## CONSUMES
+  gCnlPchLpChipsetInitTableDxGuid               ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..6affc3180e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
@@ -0,0 +1,296 @@
+## @file
+# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitPreMemLib
+  FILE_GUID                      = EA05BD43-136F-45EE-BBBA-27D75817574F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  PcdLib
+  MultiBoardInitSupportLib
+  StallPpiLib
+  PchResetLib
+  PeiPlatformHookLib
+  PlatformHookLib
+  PeiPolicyInitLib
+  OcWdtLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPreMemLib.c
+  WhiskeylakeURvpHsioPtssTables.c
+  PeiMultiBoardInitPreMemLib.c
+  PeiWhiskeylakeURvpDetect.c
+  BoardSaInitPreMemLib.c
+  BoardPchInitPreMemLib.c
+  BoardFuncInitPreMem.c
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid
+  gEfiPeiMemoryDiscoveredPpiGuid                ## CONSUMES
+  gEfiPeiResetPpiGuid                           ## PRODUCES
+
+[Guids]
+  gPchGeneralPreMemConfigGuid      ## CONSUMES
+  gTcoWdtHobGuid                                ## CONSUMES
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
+
+  # PCH-LP HSIO PTSS Table
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  # PCH-H HSIO PTSS Table
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
+
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+
+  #===========================================================
+  # Board Init Table List
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # WWAN Full Card Power Off and reset pins
+  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## PRODUCES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## PRODUCES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
+
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
+
+  # Pch PmConfig Policy
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
+
+
+  gBoardModuleTokenSpaceGuid.PcdSpdPresent
+  gBoardModuleTokenSpaceGuid.PcdBoardRev
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
+  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround    ## PRODUCES
+  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
+
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdMchBaseAddress              ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdMchMmioSize                 ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize        ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpMmioSize         ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize       ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize  ## CONSUMES
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
new file mode 100644
index 0000000000..2c9af5b9a3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Module Information file for DxePolicyBoardConfigLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = DxePolicyBoardConfigLib
+  FILE_GUID                      = 17836E9F-7188-4640-80A3-B4441585FFE9
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  DxeSaPolicyBoardConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseLib
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  HobLib
+  ConfigBlockLib
+
+[Guids]
+  gMemoryDxeConfigGuid                          ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
new file mode 100644
index 0000000000..079fb70ecb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
@@ -0,0 +1,94 @@
+## @file
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPlatformHookLib
+  FILE_GUID                      = AD901798-B0DA-4B20-B90C-283F886E76D0
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPlatformHookLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  IoLib
+  HobLib
+  PcdLib
+  TimerLib
+  PchCycleDecodingLib
+  GpioLib
+  CpuPlatformLib
+  PeiServicesLib
+  ConfigBlockLib
+  PeiSaPolicyLib
+  GpioExpanderLib
+  PmcLib
+  PchPcrLib
+  PciSegmentLib
+  GpioCheckConflictLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel          ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2              ## CONSUMES
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable                ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
+  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround
+
+[Sources]
+  PeiPlatformHooklib.c
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+
+[Guids]
+  gSaDataHobGuid                                ## CONSUMES
+  gEfiGlobalVariableGuid                        ## CONSUMES
+  gGpioCheckConflictHobGuid                     ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
new file mode 100644
index 0000000000..65e66ccb62
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
@@ -0,0 +1,70 @@
+## @file
+# Module Information file for PeiPolicyBoardConfigLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyBoardConfigLib
+  FILE_GUID                      = B1E959E3-9DCA-4D6F-938C-420C3BF5D820
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyBoardConfigLib|PEIM PEI_CORE SEC
+
+[Sources]
+  PeiCpuPolicyBoardConfigPreMem.c
+  PeiCpuPolicyBoardConfig.c
+  PeiMePolicyBoardConfigPreMem.c
+  PeiMePolicyBoardConfig.c
+  PeiPchPolicyBoardConfigPreMem.c
+  PeiPchPolicyBoardConfig.c
+  PeiSaPolicyBoardConfigPreMem.c
+  PeiSaPolicyBoardConfig.c
+  PeiSiPolicyBoardConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  DebugLib
+  HobLib
+  ConfigBlockLib
+  IoLib
+  BaseCryptLib
+  BaseMemoryLib
+
+[Guids]
+  gCpuSecurityPreMemConfigGuid                  ## CONSUMES
+  gMePeiPreMemConfigGuid                        ## CONSUMES
+  gPchGeneralPreMemConfigGuid                   ## CONSUMES
+  gSaMiscPeiPreMemConfigGuid                    ## CONSUMES
+  gCpuConfigGuid                                ## CONSUMES
+  gPchGeneralConfigGuid                         ## CONSUMES
+  gEfiTpmDeviceInstanceTpm20DtpmGuid
+  gEfiTpmDeviceInstanceTpm12Guid
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
+
+[FixedPcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize                             ## CONSUMES
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
new file mode 100644
index 0000000000..eca492e72d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
@@ -0,0 +1,18 @@
+/** @file
+  Header file for Board Hook function intance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BOARD_FUNC_H_
+#define _BOARD_FUNC_H_
+
+EFI_STATUS
+PeiBoardSpecificInitPostMemNull (
+  VOID
+  );
+
+#endif // _BOARD_FUNC_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
new file mode 100644
index 0000000000..5435b4a6e3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
@@ -0,0 +1,20 @@
+/** @file
+ Header file for board Init function for Post Memory Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_BOARD_INIT_LIB_H_
+#define _PEI_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+
+#endif // _PEI_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
new file mode 100644
index 0000000000..41c798a082
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
@@ -0,0 +1,90 @@
+/** @file
+  PEI Boards Configurations for PreMem phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BOARD_SA_CONFIG_PRE_MEM_H_
+#define _BOARD_SA_CONFIG_PRE_MEM_H_
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>               // for MRC Configuration
+#include <ConfigBlock/SwitchableGraphicsConfig.h>   // for PCIE RTD3 GPIO
+#include <GpioPinsCnlLp.h>                          // for GPIO definition
+#include <GpioPinsCnlH.h>
+#include <SaAccess.h>                               // for Root Port number
+#include <PchAccess.h>                              // for Root Port number
+
+//
+// The following section contains board-specific CMD/CTL/CLK and DQ/DQS mapping, needed for LPDDR3/LPDDR4
+//
+
+//
+// DQByteMap[0] - ClkDQByteMap:
+//   If clock is per rank, program to [0xFF, 0xFF]
+//   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+//   If clock is shared by 2 ranks but does not go to all bytes,
+//           Entry[i] defines which DQ bytes Group i services
+// DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+// DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+// DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+//                For DDR, DQByteMap[3:1] = [0xFF, 0]
+// DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+//                               Variable only exists to make the code easier to use
+// DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+//                               Variable only exists to make the code easier to use
+//
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for WHL RVP3, WHL SDS - used by WHL/WHL MRC
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapWhlUDdr4Rvp[2][6][2] = {
+  // Channel 0:
+  {
+    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  },
+  // Channel 1:
+  {
+    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  }
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqsMapCpu2DramWhlUDdr4Rvp[2][8] = {
+  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
+  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 DqsMapCpu2DramWhlUmDvp[2][8] = {
+  { 0, 3, 1, 2, 7, 5, 6, 4 }, // Channel 0
+  { 0, 2, 1, 3, 6, 4, 7, 5 }  // Channel 1
+};
+
+//
+// Reference RCOMP resistors on motherboard
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorCflUDdr4Interposer[SA_MRC_MAX_RCOMP] = { 121, 81, 100 };
+
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetWhlUDdr4Interposer[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 20, 20, 26 };
+
+#endif // _BOARD_SA_CONFIG_PRE_MEM_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
new file mode 100644
index 0000000000..a943d5bd04
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
@@ -0,0 +1,225 @@
+/** @file
+  GPIO definition table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_TABLE_DEFAULT_H_
+#define _GPIO_TABLE_DEFAULT_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+#define END_OF_GPIO_TABLE 0xFFFFFFFF
+
+//
+// CNL U DRR4 Board GPIO table configuration is used as default
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG mGpioTableDefault[] =
+{
+//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,  GPIRoutConfig,  PadRstCfg,  Term,
+  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_0
+  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_1
+  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CSB
+  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
+  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
+  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
+  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //WWAN_WAKE_N
+  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2, GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault, GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
+  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset, GpioTermNone } },  //DGPU_SEL_SLOT1
+  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
+  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPKR_PD_N
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WFCAM_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //ACCEL_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //ALS_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //HALL_SENSOR_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_WAKE
+  //(RC control) {GPIO_CNL_LP_GPP_A23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //SHARED_INT
+  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock } },  //BT_UART_WAKE
+  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock }},  //FORCE_PAD_INT
+  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone , GpioPadConfigUnlock} },  //BT_DISABLE_N
+  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
+  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
+  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
+  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //TCH_PNL_PWR_EN
+  //(CSME Pad) {GPIO_CNL_LP_GPP_B15,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //NFC_DFU
+  { GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
+  { GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock} },  //FPS_RESET_N
+  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},  //TBT_CIO_PWR_EN
+  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
+  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone}},  //EC_SLP_S0_CS_N
+  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
+  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,  GpioTermNone }},  //WIFI_RF_KILL_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
+  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIFI_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermWpu20K } },  //CODEC_INT_N
+  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
+  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone}},  //TBT_FORCE_PWR
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_PWREN_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
+  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
+  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
+  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
+  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL2_RST_N
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SLOT1_WAKE_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //NFC_RST_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,  GpioTermNone }},  //WWAN_PWREN
+  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL_RST_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //NFC_INT_N
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
+  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
+  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
+  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
+  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
+  {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
+  {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
+  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
+  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
+  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
+  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,  GpioTermWpu20K}},  //Reserved for SATA HP val
+  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,  GpioTermNone}},  //EC_SMI_N
+  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
+  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SSD_DEVSLP
+  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //HDD_DEVSLP
+  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL_INT_N
+  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
+  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
+  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
+  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
+  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
+  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
+  //(Not used){GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F0_COEX3
+  {GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},  //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_HDD_PWREN
+  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WF_CLK_EN
+  //(RC control) {GPIO_CNL_LP_GPP_F4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_BRI_DT_UART0_RTSB
+  //(RC control) {GPIO_CNL_LP_GPP_F5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_BRI_RSP_UART0_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_F6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_RGI_DT_UART0_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_F7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_RGI_RSP_UART0_CTSB
+  {GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_MFUART2_RXD
+  {GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_MFUART2_TXD
+
+  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be used at IsRecoveryMode()
+  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone}},  //BIOS_REC
+
+  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
+  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
+  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
+  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
+  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
+  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
+  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
+  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
+  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
+  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_F_23
+  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
+  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
+  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
+  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
+  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
+  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
+  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpd20K }},  //GPP_G_7_SD3_WP
+  //{GPIO_CNL_LP_GPP_H0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_0_SSP2_SCLK
+  //{GPIO_CNL_LP_GPP_H1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_1_SSP2_SFRM
+  //{GPIO_CNL_LP_GPP_H2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_2_SSP2_TXD
+  //{GPIO_CNL_LP_GPP_H3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_3_SSP2_RXD
+  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
+  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_PWREN
+  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_RECOVERY
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IRIS_STROBE
+  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL0
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
+  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_KEY
+  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
+  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
+  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
+  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL1
+  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
+  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H21
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WF_CAM_RST
+  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H23
+  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
+  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //BC_ACOK
+  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
+  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
+  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
+  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SLP_A_N
+  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPD_7
+  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SUS_CLK
+  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
+  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
+  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpd20K }}, // 20K PD for PECI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG mGpioTablePreMemDefault[] =
+{
+  {END_OF_GPIO_TABLE,  {GpioPadModeGpio,    GpioHostOwnGpio, GpioDirNone,  GpioOutDefault, GpioIntDis, GpioDswReset,  GpioTermNone}},//Marking End of Table
+};
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
new file mode 100644
index 0000000000..86b7cb3717
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
@@ -0,0 +1,284 @@
+/** @file
+  GPIO definition table for WhiskeyLake U Ddr4 RVP
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+#define _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4_0[] =
+{
+//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,  GPIRoutConfig,  PadRstCfg,  Term,
+  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_0
+  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_1
+  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CSB
+  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
+  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
+  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //WWAN_WAKE_N
+  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2, GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault, GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
+  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset, GpioTermNone } },  //DGPU_SEL_SLOT1
+  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
+  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPKR_PD_N
+  {GPIO_CNL_LP_GPP_A16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutLow, GpioIntDefault, GpioPlatformReset, GpioTermWpu20K, GpioPadUnlock }},  //WFCAM_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
+  //A18-A23 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_A18,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //ACCEL_INT
+  {GPIO_CNL_LP_GPP_A19,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //ALS_INT
+  {GPIO_CNL_LP_GPP_A20,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
+  {GPIO_CNL_LP_GPP_A21,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //HALL_SENSOR_INT
+  {GPIO_CNL_LP_GPP_A22,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //IVCAM_WAKE
+  {GPIO_CNL_LP_GPP_A23,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //SHARED_INT
+  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermNone, GpioPadUnlock } },  //BT_UART_WAKE
+  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadUnlock }},  //FORCE_PAD_INT
+  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone , GpioOutputStateUnlock} },  //BT_DISABLE_N
+  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
+  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
+  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
+  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //TCH_PNL_PWR_EN
+  //B15 -Unused pin -> Under GPIO table for GPIO Termination - Input sensing disable
+  {GPIO_CNL_LP_GPP_B15, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,  GpioTermNone }},  //Former NFC_DFU
+  {GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
+  {GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock} },  //FPS_RESET_N
+  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},  //TBT_CIO_PWR_EN
+  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
+  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone, GpioPadUnlock }},  //EC_SLP_S0_CS_N
+  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
+  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,  GpioTermNone, GpioOutputStateUnlock }},  //WIFI_RF_KILL_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
+  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIFI_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi , GpioDirIn , GpioOutDefault , GpioIntLevel | GpioIntApic , GpioPlatformReset, GpioTermWpu20K } },  //CODEC_INT_N
+  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
+  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //TBT_FORCE_PWR
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
+  //move to premem phase for early power turn on
+  //  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  //  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_PWREN_N
+  //  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_PWREN_N
+  //  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+
+  //Only clear Reset pins in Post-Mem
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+
+  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
+  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
+  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
+  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
+  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL2_RST_N
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SLOT1_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //Former NFC_RST_N
+  //{GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,  GpioTermNone }},  //WWAN_PWREN
+  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL_RST_N
+  //(Not used) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //Former NFC_INT_N
+  //{GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
+  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
+  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
+  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
+  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
+  //(CSME control) {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
+  //(CSME control) {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
+  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
+  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
+  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
+  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,  GpioTermWpu20K}},  //Reserved for SATA HP val
+  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock}},  //EC_SMI_N
+  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
+  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SSD_DEVSLP
+  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //HDD_DEVSLP
+  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL_INT_N
+  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
+  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
+  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
+  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
+  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
+  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
+   //F0- unused pin-Input Sensing disable F4-F7 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,  GpioTermNone }},  //GPP_F0_COEX3
+  //{GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},  //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K }},  //SATA_HDD_PWREN
+  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K, GpioPadUnlock }},  //WF_CLK_EN
+  {GPIO_CNL_LP_GPP_F4,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_BRI_DT_UART0_RTSB
+  {GPIO_CNL_LP_GPP_F5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_BRI_RSP_UART0_RXD
+  {GPIO_CNL_LP_GPP_F6,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_RGI_DT_UART0_TXD
+  {GPIO_CNL_LP_GPP_F7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_RGI_RSP_UART0_CTSB
+  //{GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_MFUART2_RXD
+  //{GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_MFUART2_TXD
+
+  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be used at IsRecoveryMode()
+  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K}},  //BIOS_REC
+
+  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
+  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
+  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
+  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
+  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
+  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
+  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
+  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
+  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
+  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_F_23
+  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
+  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
+  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
+  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
+  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
+  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
+  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpd20K }},  //GPP_G_7_SD3_WP
+  //H0-H3 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_H0,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_0_SSP2_SCLK
+  {GPIO_CNL_LP_GPP_H1,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_1_SSP2_SFRM
+  {GPIO_CNL_LP_GPP_H2,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_2_SSP2_TXD
+  {GPIO_CNL_LP_GPP_H3,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_3_SSP2_RXD
+  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
+  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_PWREN
+  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_RECOVERY
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IRIS_STROBE
+  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL0
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
+  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_KEY
+  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
+  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
+  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
+  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL1
+  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
+  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H21
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //WF_CAM_RST
+  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H23
+  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
+  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //BC_ACOK
+  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
+  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
+  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
+  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SLP_A_N
+  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPD_7
+  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SUS_CLK
+  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
+  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
+  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpd20K }}, // 20K PD for PECI
+};
+
+static GPIO_INIT_CONFIG mGpioTableCflUDdr4[] = {
+  //                       Pmode,                GPI_IS,             GpioDir,        GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
+  // WiGig start
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioHostDeepReset,  GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,      GpioHostOwnGpio,   GpioDirInInv,    GpioOutHigh, GpioIntLevel | GpioIntSci,    GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_PEWAKE_R_N / WF_CAM_RST on CNL U
+  //WiGig end
+  // Camera start
+  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio,      GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
+  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio,      GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  // Camera end
+  // Touch start
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,      GpioHostOwnGpio,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
+  // Touch end
+  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio,      GpioHostOwnAcpi,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,    GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,      GpioHostOwnAcpi,     GpioDirOut,    GpioOutHigh, GpioIntDis,                   GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio,      GpioHostOwnGpio,      GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock } },  //SPI_TPM_INT_N                                                                                                                                          // Unused start
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermWpu20K }}, //Unused so disabled / WF_CLK_EN on CNL U
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / Not used on CNL U
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}  //Unused so disabled / Not used on CNL U
+  // Unused end
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4[] = {
+  //                       Pmode,                GPI_IS,             GpioDir,        GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
+  // WiGig start
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioHostDeepReset,  GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
+  // WiGig end
+  // Camera start
+  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio, GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
+  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  // Camera end
+  // Touch start
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio, GpioHostOwnGpio,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio, GpioHostOwnAcpi,     GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,  GpioTermNone}},    //SLOT1_RST_N
+  // Touch end
+  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio, GpioHostOwnAcpi,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K,  GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
+  // TBT start
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }},  //TBT_CIO_PWR_EN
+  // TBT end
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio, GpioHostOwnGpio,      GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},         //SPI_TPM_INT_N
+  // Unused start
+  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermWpu20K }}  //Unused so disabled / WF_CLK_EN on CNL U
+  // Unused end
+};
+
+
+#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
new file mode 100644
index 0000000000..01a6599564
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
@@ -0,0 +1,59 @@
+/** @file
+  GPIO definition table for WhiskeyLake U Ddr4 RVP Pre-Memory
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+#define _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4PreMem[] =
+{
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_RST_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_PWREN_N
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlTbtRvpPreMem[] =
+{
+  // do not reset SLOT1 due to TR AIC card cannot be reset in S3/S4 resume.
+  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_RST_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_PWREN_N
+};
+
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOnEarlyPreMem[] =
+{
+  // Turn on WWAN power and de-assert reset pins by default
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioPlatformReset, GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
+  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOffEarlyPreMem[] =
+{
+  // Assert reset pins and then turn off WWAN power
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
+  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioPlatformReset, GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
+};
+
+#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
new file mode 100644
index 0000000000..0d26e8ad7a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
@@ -0,0 +1,3014 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_VERB_TABLES_H_
+#define _PCH_HDA_VERB_TABLES_H_
+
+#include <Ppi/SiPolicy.h>
+
+HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: CFL Display Audio Codec
+  //  Revision ID = 0xFF
+  //  Codec Vendor: 0x8086280B
+  //
+  0x8086, 0x280B,
+  0xFF, 0xFF,
+  //
+  // Display Audio Verb Table
+  //
+  // For GEN9, the Vendor Node ID is 08h
+  // Port to be exposed to the inbox driver in the vanilla mode: PORT C - BIT[7:6] = 01b
+  0x00878140,
+  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
+  0x00571C10,
+  0x00571D00,
+  0x00571E56,
+  0x00571F18,
+  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
+  0x00671C20,
+  0x00671D00,
+  0x00671E56,
+  0x00671F18,
+  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
+  0x00771C30,
+  0x00771D00,
+  0x00771E56,
+  0x00771F18,
+  // Disable the third converter and third Pin (NID 08h)
+  0x00878140
+);
+
+//
+//codecs verb tables
+//
+HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40622005
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D20,
+  0x01D71E62,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B,
+
+
+  //Widget node 0X20 for ALC1305   20160603 update
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+  //
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204800F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02044848,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050000,
+  0x02043330,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050000,
+  0x02043333,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x020402EC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02044909,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x020440B0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040047,
+  0x02050028,
+  0x02040C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040048,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040049,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004A,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040001,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024
+); // HdaVerbTableAlc700
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC701)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0701
+  //
+  0x10EC, 0x0701,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC701
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40610041
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC1124
+  0x00172024,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C41,
+  0x01D71D00,
+  0x01D71E61,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B
+); // HdaVerbTableAlc701
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC274)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0274
+  //
+  0x10EC, 0x0274,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC274
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
+  //The number of verb command block : 16
+
+  //    NID 0x12 : 0x40000000
+  //    NID 0x13 : 0x411111F0
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x411111F0
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11020
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40451B05
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211010
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //,DA Codec Subsystem ID  : 0x10EC10F6
+  0x001720F6,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371CF0,
+  0x01371D11,
+  0x01371E11,
+  0x01371F41,
+  //Pin widget 0x14 - NPC
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S_OUT2
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S_OUT1
+  0x01771CF0,
+  0x01771D11,
+  0x01771E11,
+  0x01771F41,
+  //Pin widget 0x18 - I2S_IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C20,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D1B,
+  0x01D71E45,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C10,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205006F,
+  0x02042C0B,
+  //Widget node 0x20 - 1 :
+  0x02050035,
+  0x02048968,
+  0x05B50001,
+  0x05B48540,
+  //Widget node 0x20 - 2 :
+  0x05850000,
+  0x05843888,
+  0x05850000,
+  0x05843888,
+  //Widget node 0x20 - 3 :
+  0x0205004A,
+  0x0204201B,
+  0x0205004A,
+  0x0204201B
+); //HdaVerbTableAlc274
+
+//
+// CFL S Audio Codec
+//
+STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) CFL S RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x90A60130
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x03011010
+  //    NID 0x17 : 0x90170120
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A1103E
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x03A11040
+  //    NID 0x1D : 0x40600001
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x0421102F
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC112C
+  0x0017202C,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C30,
+  0x01271D01,
+  0x01271EA6,
+  0x01271F90,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671C10,
+  0x01671D10,
+  0x01671E01,
+  0x01671F03,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C20,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C3E,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71C40,
+  0x01B71D10,
+  0x01B71EA1,
+  0x01B71F03,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C01,
+  0x01D71D00,
+  0x01D71E60,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C2F,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
+  0x0205006B,
+  0x02044260,
+  0x0205006B,
+  0x02044260,
+  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent control
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 4   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+
+  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove ALC1305 EQ setting
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x02042213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+);
+
+
+//
+// WHL codecs verb tables
+//
+HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) WHL RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table for WHL PCH boards
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x02A19040
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40638029
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x02211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271CF0,
+  0x01271D11,
+  0x01271E11,
+  0x01271F41,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C40,
+  0x01971D90,
+  0x01971EA1,
+  0x01971F02,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C29,
+  0x01D71D80,
+  0x01D71E63,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F02,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+
+  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass DAC02 DRE(NID5B bit14)
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+
+  //Widget node 0x20 -2:
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+
+  //Widget node 0x20 - 3   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+
+  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x0204E213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204422E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+); // WhlHdaVerbTableAlc700
+
+#endif // _PCH_HDA_VERB_TABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
new file mode 100644
index 0000000000..89c780cc0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
+#define _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Ppi/SiPolicy.h>
+#include <PchHsioPtssTables.h>
+#include <IoExpander.h>
+
+#include <WhiskeylakeURvpId.h>
+
+extern const UINT8 mDqByteMapSklRvp3[2][6][2];
+extern const UINT8 mDqsMapCpu2DramSklRvp3[2][8];
+extern const UINT8 mSkylakeRvp3Spd110[];
+extern const UINT16 mSkylakeRvp3Spd110Size;
+extern HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[];
+extern UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size;
+extern HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[];
+extern UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size;
+
+extern GPIO_INIT_CONFIG mGpioTableLpddr3Rvp3UcmcDevice[];
+extern UINT16 mGpioTableLpddr3Rvp3UcmcDeviceSize;
+
+extern IO_EXPANDER_GPIO_CONFIG mGpioTableIoExpander[];
+extern UINT16 mGpioTableIoExpanderSize;
+extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3Touchpanel;
+extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3[];
+extern UINT16 mGpioTableLpDdr3Rvp3Size;
+
+#endif // _PEI_Whiskeylake_RVP3_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
new file mode 100644
index 0000000000..a6d48e906d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
@@ -0,0 +1,20 @@
+/** @file
+ Header file for DxePolicyBoardConfig library instance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_POLICY_BOARD_CONFIG_H_
+#define _DXE_POLICY_BOARD_CONFIG_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/DxePolicyBoardConfigLib.h>
+
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
new file mode 100644
index 0000000000..03c27f2a41
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
@@ -0,0 +1,23 @@
+/** @file
+ Header file for PeiPolicyBoardConfig library instance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_BOARD_CONFIG_H_
+#define _PEI_POLICY_BOARD_CONFIG_H_
+
+#include <PiPei.h>
+#include <ConfigBlock/MePeiConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
new file mode 100644
index 0000000000..01b3df984a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
@@ -0,0 +1,41 @@
+/** @file
+  Others Board's PCD function hook.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <GopConfigLib.h>
+
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+EFIAPI
+GopVbtSpecificUpdateNull (
+  IN CHILD_STRUCT **ChildStructPtr
+  )
+{
+  return;
+}
+
+//
+// for CFL U DDR4
+//
+VOID
+EFIAPI
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+)
+{
+  ChildStructPtr[1]->DeviceClass = DISPLAY_PORT_ONLY;
+  ChildStructPtr[1]->DVOPort     = DISPLAY_PORT_B;
+  ChildStructPtr[2]->DeviceClass = DISPLAY_PORT_HDMI_DVI_COMPATIBLE;
+  ChildStructPtr[2]->DVOPort     = DISPLAY_PORT_C;
+  ChildStructPtr[2]->AUX_Channel = AUX_CHANNEL_C;
+  ChildStructPtr[3]->DeviceClass = NO_DEVICE;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
new file mode 100644
index 0000000000..7ebf8f8fdc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
@@ -0,0 +1,137 @@
+/** @file
+  Implementation of BaseGpioCheckConflictLib.
+
+
+  Copyright (c) 2019, 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 <Private/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 Hob Check] Can't find Gpio Hob.\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, "[Hob 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 Check] Identified conflict on pad %a\n", GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad)));
+        }
+      }
+      //
+      // 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 UINT16                    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 how big size the Hob Data needs
+      //
+      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 {
+      GpioCheckConflictHobData[GpioIndex].GpioPad = GpioDefinition[Index].GpioPad;
+      GpioCheckConflictHobData[GpioIndex].GpioPadMode = GpioDefinition[Index].GpioConfig.PadMode;
+      GpioIndex++;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n"));
+  return;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
new file mode 100644
index 0000000000..178ce1a124
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
@@ -0,0 +1,37 @@
+/** @file
+  Implementation of BaseGpioCheckConflicLibNull.
+
+
+  Copyright (c) 2019, 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 UINT16                    GpioTableCount
+  )
+{
+  return;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
new file mode 100644
index 0000000000..24c6fa6277
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
@@ -0,0 +1,156 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PlatformHookLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <SystemAgent/Include/SaAccess.h>
+#include <SioRegs.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Register/PchRegsLpc.h>
+#include <PchAccess.h>
+
+#define LPC_SIO_INDEX_DEFAULT_PORT_2              0x2E
+#define LPC_SIO_DATA_DEFAULT_PORT_2               0x2F
+
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_0           0x87
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_1           0x01
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_2           0x55
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_3           0x55
+#define IT8628_EXIT_CONFIG                        0x2
+#define IT8628_CHIPID_BYTE1                       0x86
+#define IT8628_CHIPID_BYTE2                       0x28
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Value;
+} EFI_SIO_TABLE;
+
+//
+// IT8628
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioIt8628TableSerialPort[] = {
+  {0x023, 0x09}, // Clock Selection register
+  {0x007, 0x01}, // Com1 Logical Device Number select
+  {0x061, 0xF8}, // Serial Port 1 Base Address MSB Register
+  {0x060, 0x03}, // Serial Port 1 Base Address LSB Register
+  {0x070, 0x04}, // Serial Port 1 Interrupt Level Select
+  {0x030, 0x01}, // Serial Port 1 Activate
+  {0x007, 0x02}, // Com1 Logical Device Number select
+  {0x061, 0xF8}, // Serial Port 2 Base Address MSB Register
+  {0x060, 0x02}, // Serial Port 2 Base Address MSB Register
+  {0x070, 0x03}, // Serial Port 2 Interrupt Level Select
+  {0x030, 0x01}  // Serial Port 2 Activate
+};
+
+/**
+  Check whether the IT8628 SIO present on LPC. If yes, enable its serial ports
+**/
+STATIC
+VOID
+It8628SioSerialPortInit (
+  VOID
+  )
+{
+  UINT8   ChipId0;
+  UINT8   ChipId1;
+  UINT16  LpcIoDecondeRangeSet;
+  UINT16  LpcIoDecoodeSet;
+  UINT8   Index;
+  UINT64  LpcBaseAddr;
+
+  ChipId0              = 0;
+  ChipId1              = 0;
+  LpcIoDecondeRangeSet = 0;
+  LpcIoDecoodeSet      = 0;
+
+  //
+  // Enable I/O decoding for COM1 (3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh.
+  //
+  LpcBaseAddr = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPC,
+                  PCI_FUNCTION_NUMBER_PCH_LPC,
+                  0
+                  );
+
+  LpcIoDecondeRangeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOD);
+  LpcIoDecoodeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOE);
+  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOD), (LpcIoDecondeRangeSet | ((V_LPC_CFG_IOD_COMB_2F8 << 4) | V_LPC_CFG_IOD_COMA_3F8)));
+  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOE), (LpcIoDecoodeSet | (B_LPC_CFG_IOE_SE | B_LPC_CFG_IOE_CBE | B_LPC_CFG_IOE_CAE|B_LPC_CFG_IOE_KE)));
+
+  //
+  // Enter MB PnP Mode
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_0);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_1);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_2);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_3);
+
+  //
+  // Read Chip Id of SIO IT8628 (registers 0x20 and 0x21)
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x20);
+  ChipId0 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
+
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x21);
+  ChipId1 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
+
+  //
+  // Enable Serial Port 1, Port 2
+  //
+  if ((ChipId0 == IT8628_CHIPID_BYTE1) && (ChipId1 == IT8628_CHIPID_BYTE2)) {
+    for (Index = 0; Index < sizeof (mSioIt8628TableSerialPort) / sizeof (EFI_SIO_TABLE); Index++) {
+      IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Register);
+      IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Value);
+    }
+  }
+
+  //
+  // Exit MB PnP Mode
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
+  IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
+
+  return;
+}
+
+/**
+  Performs platform specific initialization required for the CPU to access
+  the hardware associated with a SerialPortLib instance.  This function does
+  not initialize the serial port hardware itself.  Instead, it initializes
+  hardware devices that are required for the CPU to access the serial port
+  hardware.  This function may be called more than once.
+
+  @retval RETURN_SUCCESS       The platform specific initialization succeeded.
+  @retval RETURN_DEVICE_ERROR  The platform specific initialization could not be completed.
+
+**/
+RETURN_STATUS
+EFIAPI
+PlatformHookSerialPortInitialize (
+  VOID
+  )
+{
+  //
+  // Enable I/O decoding for COM1(3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh, 4Eh/4Fh, 60h/64Fh and 62h/66h.
+  //
+  PchLpcIoDecodeRangesSet (PcdGet16 (PcdLpcIoDecodeRange));
+  PchLpcIoEnableDecodingSet (PcdGet16 (PchLpcIoEnableDecoding));
+
+  // Configure Sio IT8628
+  It8628SioSerialPortInit ();
+
+  return RETURN_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
new file mode 100644
index 0000000000..e7acbda03a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
@@ -0,0 +1,63 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+BoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  SiliconEnableAcpi (EnableSci);
+  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
+}
+
+EFI_STATUS
+EFIAPI
+BoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  SiliconDisableAcpi (DisableSci);
+  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
+}
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
new file mode 100644
index 0000000000..978e367cda
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
@@ -0,0 +1,82 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/MultiBoardAcpiSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  SiliconEnableAcpi (EnableSci);
+  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  SiliconDisableAcpi (DisableSci);
+  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
+}
+
+BOARD_ACPI_ENABLE_FUNC  mWhiskeylakeURvpBoardAcpiEnableFunc = {
+  WhiskeylakeURvpMultiBoardEnableAcpi,
+  WhiskeylakeURvpMultiBoardDisableAcpi,
+};
+
+EFI_STATUS
+EFIAPI
+SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor (
+  VOID
+  )
+{
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    return RegisterBoardAcpiEnableFunc (&mWhiskeylakeURvpBoardAcpiEnableFunc);
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
new file mode 100644
index 0000000000..9daceaa25c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
@@ -0,0 +1,170 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <PchAccess.h>
+#include <Library/MmPciLib.h>
+#include <Library/PmcLib.h>
+
+/**
+  Clear Port 80h
+
+  SMI handler to enable ACPI mode
+
+  Dispatched on reads from APM port with value EFI_ACPI_ENABLE_SW_SMI
+
+  Disables the SW SMI Timer.
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then enabled.
+
+  Clear SLP SMI status
+  Enable SLP SMI
+
+  Disable SW SMI Timer
+
+  Clear all ACPI event status and disable all ACPI events
+
+  Disable PM sources except power button
+  Clear status bits
+
+  Disable GPE0 sources
+  Clear status bits
+
+  Disable GPE1 sources
+  Clear status bits
+
+  Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+
+  Enable SCI
+**/
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+
+  UINT32                              OutputValue;
+  UINT32                              SmiEn;
+  UINT32                              SmiSts;
+  UINT32                              ULKMC;
+  UINTN                               LpcBaseAddress;
+  UINT16                              AcpiBaseAddr;
+  UINT32                              Pm1Cnt;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
+    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    0
+    );
+  //
+  // Get the ACPI Base Address
+  //
+  AcpiBaseAddr = PmcGetAcpiBase();
+  //
+  // BIOS must also ensure that CF9GR is cleared and locked before handing control to the
+  // OS in order to prevent the host from issuing global resets and resetting ME
+  //
+  // EDK2: To match PCCG current BIOS behavior, do not lock CF9 Global Reset
+  // MmioWrite32 (
+  //     PmcBaseAddress + R_PCH_PMC_ETR3),
+  //     PmInit);
+
+  //
+  // Clear Port 80h
+  //
+  IoWrite8 (0x80, 0);
+
+  //
+  // Disable SW SMI Timer and clean the status
+  //
+  SmiEn = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN);
+  SmiEn &= ~(B_ACPI_IO_SMI_EN_LEGACY_USB2 | B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB);
+  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN, SmiEn);
+
+  SmiSts = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS);
+  SmiSts |= B_ACPI_IO_SMI_EN_LEGACY_USB2 | B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB;
+  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS, SmiSts);
+
+  //
+  // Disable port 60/64 SMI trap if they are enabled
+  //
+  ULKMC = MmioRead32 (LpcBaseAddress + R_LPC_CFG_ULKMC) & ~(B_LPC_CFG_ULKMC_60REN | B_LPC_CFG_ULKMC_60WEN | B_LPC_CFG_ULKMC_64REN | B_LPC_CFG_ULKMC_64WEN | B_LPC_CFG_ULKMC_A20PASSEN);
+  MmioWrite32 (LpcBaseAddress + R_LPC_CFG_ULKMC, ULKMC);
+
+  //
+  // Disable PM sources except power button
+  //
+  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_EN, B_ACPI_IO_PM1_EN_PWRBTN);
+
+  //
+  // Clear PM status except Power Button status for RapidStart Resume
+  //
+  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_STS, 0xFEFF);
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+  //
+  IoWrite8 (R_RTC_IO_INDEX_ALT, R_RTC_IO_REGD);
+  IoWrite8 (R_RTC_IO_TARGET_ALT, 0x0);
+
+  //
+  // Write ALT_GPI_SMI_EN to disable GPI1 (SMC_EXTSMI#)
+  //
+  OutputValue = IoRead32 (AcpiBaseAddr + 0x38);
+  OutputValue = OutputValue & ~(1 << (UINTN) PcdGet8 (PcdSmcExtSmiBitPosition));
+  IoWrite32 (AcpiBaseAddr + 0x38, OutputValue);
+
+  //
+  // Enable SCI
+  //
+  if (EnableSci) {
+    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
+    Pm1Cnt |= B_ACPI_IO_PM1_CNT_SCI_EN;
+    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+
+  UINT16                              AcpiBaseAddr;
+  UINT32                              Pm1Cnt;
+
+  //
+  // Get the ACPI Base Address
+  //
+  AcpiBaseAddr = PmcGetAcpiBase();
+  //
+  // Disable SCI
+  //
+  if (DisableSci) {
+    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
+    Pm1Cnt &= ~B_ACPI_IO_PM1_CNT_SCI_EN;
+    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
new file mode 100644
index 0000000000..97a3fae51b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
@@ -0,0 +1,40 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  // enable additional board register
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  // enable additional board register
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
new file mode 100644
index 0000000000..7a2fed9904
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
@@ -0,0 +1,19 @@
+/** @file
+  Board's PCD function hook.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+EFI_STATUS
+PeiBoardSpecificInitPostMemNull (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
new file mode 100644
index 0000000000..5104329825
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
@@ -0,0 +1,27 @@
+/** @file
+  Source code for the board configuration init function in Post Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include "BoardFunc.h"
+
+/**
+  Board's PCD function hook init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardFunctionInit (
+  IN UINT16 BoardId
+)
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
new file mode 100644
index 0000000000..3a42a9bd03
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
@@ -0,0 +1,41 @@
+/** @file
+  Source code for the board configuration init function in Post Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <GopConfigLib.h>
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+GopVbtSpecificUpdateNull(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+//
+// for CFL U DDR4
+//
+VOID
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+/**
+  Board's PCD function hook init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardFunctionInitPreMem (
+  IN UINT16 BoardId
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
new file mode 100644
index 0000000000..458a73f892
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
@@ -0,0 +1,398 @@
+/** @file
+ Source code for the board PCH configuration Pcd init functions for Pre-Mmeory Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <PlatformBoardConfig.h>        // for USB 20 AFE & Root Port Clk Info.
+#include "GpioTableWhlUDdr4PreMem.h"
+#include <Library/BaseMemoryLib.h>
+
+/**
+  Board Root Port Clock Info configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+RootPortClkInfoInit (
+  IN UINT16 BoardId
+  )
+{
+  PCD64_BLOB                      *Clock;
+  UINT32                          Index;
+
+  Clock = AllocateZeroPool (16 * sizeof (PCD64_BLOB));
+  ASSERT (Clock != NULL);
+  if (Clock == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // The default clock assignment will be FREE_RUNNING, which corresponds to PchClockUsageUnspecified
+  // This is safe but power-consuming setting. If Platform code doesn't contain port-clock map for a given board,
+  // the clocks will keep on running anyway, allowing PCIe devices to operate. Downside is that clocks will
+  // continue to draw power. To prevent this, remember to provide port-clock map for every board.
+  //
+  for (Index = 0; Index < 16; Index++) {
+    Clock[Index].PcieClock.ClkReqSupported = TRUE;
+    Clock[Index].PcieClock.ClockUsage = FREE_RUNNING;
+  }
+
+  ///
+  /// Assign ClkReq signal to root port. (Base 0)
+  /// For LP, Set 0 - 5
+  /// For H,  Set 0 - 15
+  /// Note that if GbE is enabled, ClkReq assigned to GbE will not be available for Root Port.
+  ///
+  switch (BoardId) {
+    // CLKREQ
+    case BoardIdWhiskeyLakeRvp:
+      Clock[0].PcieClock.ClockUsage = PCIE_PCH + 1;
+      Clock[1].PcieClock.ClockUsage = PCIE_PCH + 8;
+      Clock[2].PcieClock.ClockUsage = LAN_CLOCK;
+      Clock[3].PcieClock.ClockUsage = PCIE_PCH + 13;
+      Clock[4].PcieClock.ClockUsage = PCIE_PCH + 4;
+      Clock[5].PcieClock.ClockUsage = PCIE_PCH + 14;
+      break;
+
+    default:
+      break;
+  }
+
+  PcdSet64S (PcdPcieClock0,  Clock[ 0].Blob);
+  PcdSet64S (PcdPcieClock1,  Clock[ 1].Blob);
+  PcdSet64S (PcdPcieClock2,  Clock[ 2].Blob);
+  PcdSet64S (PcdPcieClock3,  Clock[ 3].Blob);
+  PcdSet64S (PcdPcieClock4,  Clock[ 4].Blob);
+  PcdSet64S (PcdPcieClock5,  Clock[ 5].Blob);
+  PcdSet64S (PcdPcieClock6,  Clock[ 6].Blob);
+  PcdSet64S (PcdPcieClock7,  Clock[ 7].Blob);
+  PcdSet64S (PcdPcieClock8,  Clock[ 8].Blob);
+  PcdSet64S (PcdPcieClock9,  Clock[ 9].Blob);
+  PcdSet64S (PcdPcieClock10, Clock[10].Blob);
+  PcdSet64S (PcdPcieClock11, Clock[11].Blob);
+  PcdSet64S (PcdPcieClock12, Clock[12].Blob);
+  PcdSet64S (PcdPcieClock13, Clock[13].Blob);
+  PcdSet64S (PcdPcieClock14, Clock[14].Blob);
+  PcdSet64S (PcdPcieClock15, Clock[15].Blob);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board USB related configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+UsbConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  PCD32_BLOB *UsbPort20Afe;
+
+  UsbPort20Afe = AllocateZeroPool (PCH_MAX_USB2_PORTS * sizeof (PCD32_BLOB));
+  ASSERT (UsbPort20Afe != NULL);
+  if (UsbPort20Afe == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // USB2 AFE settings.
+  //
+  UsbPort20Afe[0].Info.Petxiset   = 7;
+  UsbPort20Afe[0].Info.Txiset     = 5;
+  UsbPort20Afe[0].Info.Predeemp   = 3;
+  UsbPort20Afe[0].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[1].Info.Petxiset   = 7;
+  UsbPort20Afe[1].Info.Txiset     = 5;
+  UsbPort20Afe[1].Info.Predeemp   = 3;
+  UsbPort20Afe[1].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[2].Info.Petxiset   = 7;
+  UsbPort20Afe[2].Info.Txiset     = 5;
+  UsbPort20Afe[2].Info.Predeemp   = 3;
+  UsbPort20Afe[2].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[3].Info.Petxiset   = 7;
+  UsbPort20Afe[3].Info.Txiset     = 5;
+  UsbPort20Afe[3].Info.Predeemp   = 3;
+  UsbPort20Afe[3].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[4].Info.Petxiset   = 7;
+  UsbPort20Afe[4].Info.Txiset     = 5;
+  UsbPort20Afe[4].Info.Predeemp   = 3;
+  UsbPort20Afe[4].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[5].Info.Petxiset   = 7;
+  UsbPort20Afe[5].Info.Txiset     = 5;
+  UsbPort20Afe[5].Info.Predeemp   = 3;
+  UsbPort20Afe[5].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[6].Info.Petxiset   = 7;
+  UsbPort20Afe[6].Info.Txiset     = 5;
+  UsbPort20Afe[6].Info.Predeemp   = 3;
+  UsbPort20Afe[6].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[7].Info.Petxiset   = 7;
+  UsbPort20Afe[7].Info.Txiset     = 5;
+  UsbPort20Afe[7].Info.Predeemp   = 3;
+  UsbPort20Afe[7].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[8].Info.Petxiset   = 7;
+  UsbPort20Afe[8].Info.Txiset     = 5;
+  UsbPort20Afe[8].Info.Predeemp   = 3;
+  UsbPort20Afe[8].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[9].Info.Petxiset   = 7;
+  UsbPort20Afe[9].Info.Txiset     = 5;
+  UsbPort20Afe[9].Info.Predeemp   = 3;
+  UsbPort20Afe[9].Info.Pehalfbit  = 0;
+
+  //
+  // USB Port Over Current Pin
+  //
+  PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinMax);
+
+  PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinMax);
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinSkip);
+
+      PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinSkip);
+
+      // USB2.0 AFE settings
+      UsbPort20Afe[0].Info.Petxiset   = 6;
+      UsbPort20Afe[0].Info.Txiset     = 0;
+      UsbPort20Afe[0].Info.Predeemp   = 3;
+      UsbPort20Afe[0].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[1].Info.Petxiset   = 6;
+      UsbPort20Afe[1].Info.Txiset     = 0;
+      UsbPort20Afe[1].Info.Predeemp   = 3;
+      UsbPort20Afe[1].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[2].Info.Petxiset   = 6;
+      UsbPort20Afe[2].Info.Txiset     = 0;
+      UsbPort20Afe[2].Info.Predeemp   = 3;
+      UsbPort20Afe[2].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[3].Info.Petxiset   = 6;
+      UsbPort20Afe[3].Info.Txiset     = 0;
+      UsbPort20Afe[3].Info.Predeemp   = 3;
+      UsbPort20Afe[3].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[4].Info.Petxiset   = 6;
+      UsbPort20Afe[4].Info.Txiset     = 0;
+      UsbPort20Afe[4].Info.Predeemp   = 3;
+      UsbPort20Afe[4].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[5].Info.Petxiset   = 6;
+      UsbPort20Afe[5].Info.Txiset     = 0;
+      UsbPort20Afe[5].Info.Predeemp   = 3;
+      UsbPort20Afe[5].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[6].Info.Petxiset   = 6;
+      UsbPort20Afe[6].Info.Txiset     = 0;
+      UsbPort20Afe[6].Info.Predeemp   = 3;
+      UsbPort20Afe[6].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[7].Info.Petxiset   = 6;
+      UsbPort20Afe[7].Info.Txiset     = 0;
+      UsbPort20Afe[7].Info.Predeemp   = 3;
+      UsbPort20Afe[7].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[8].Info.Petxiset   = 6;
+      UsbPort20Afe[8].Info.Txiset     = 0;
+      UsbPort20Afe[8].Info.Predeemp   = 3;
+      UsbPort20Afe[8].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[9].Info.Petxiset   = 6;
+      UsbPort20Afe[9].Info.Txiset     = 0;
+      UsbPort20Afe[9].Info.Predeemp   = 3;
+      UsbPort20Afe[9].Info.Pehalfbit  = 0;
+      break;
+  }
+
+  //
+  // Save USB2.0 AFE blobs
+  //
+  PcdSet32S (PcdUsb20Port0Afe,  UsbPort20Afe[ 0].Blob);
+  PcdSet32S (PcdUsb20Port1Afe,  UsbPort20Afe[ 1].Blob);
+  PcdSet32S (PcdUsb20Port2Afe,  UsbPort20Afe[ 2].Blob);
+  PcdSet32S (PcdUsb20Port3Afe,  UsbPort20Afe[ 3].Blob);
+  PcdSet32S (PcdUsb20Port4Afe,  UsbPort20Afe[ 4].Blob);
+  PcdSet32S (PcdUsb20Port5Afe,  UsbPort20Afe[ 5].Blob);
+  PcdSet32S (PcdUsb20Port6Afe,  UsbPort20Afe[ 6].Blob);
+  PcdSet32S (PcdUsb20Port7Afe,  UsbPort20Afe[ 7].Blob);
+  PcdSet32S (PcdUsb20Port8Afe,  UsbPort20Afe[ 8].Blob);
+  PcdSet32S (PcdUsb20Port9Afe,  UsbPort20Afe[ 9].Blob);
+  PcdSet32S (PcdUsb20Port10Afe, UsbPort20Afe[10].Blob);
+  PcdSet32S (PcdUsb20Port11Afe, UsbPort20Afe[11].Blob);
+  PcdSet32S (PcdUsb20Port12Afe, UsbPort20Afe[12].Blob);
+  PcdSet32S (PcdUsb20Port13Afe, UsbPort20Afe[13].Blob);
+  PcdSet32S (PcdUsb20Port14Afe, UsbPort20Afe[14].Blob);
+  PcdSet32S (PcdUsb20Port15Afe, UsbPort20Afe[15].Blob);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board GPIO Group Tier configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+GpioGroupTierInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // GPIO Group Tier
+  //
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdGpioGroupToGpeDw0, GPIO_CNL_LP_GROUP_GPP_G);
+      PcdSet32S (PcdGpioGroupToGpeDw1, GPIO_CNL_LP_GROUP_SPI);
+      PcdSet32S (PcdGpioGroupToGpeDw2, GPIO_CNL_LP_GROUP_GPP_E);
+      break;
+
+    default:
+      PcdSet32S (PcdGpioGroupToGpeDw0, 0);
+      PcdSet32S (PcdGpioGroupToGpeDw1, 0);
+      PcdSet32S (PcdGpioGroupToGpeDw2, 0);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  GPIO init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+GpioTablePreMemInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // GPIO Table Init.
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdBoardGpioTablePreMem, (UINTN) mGpioTableWhlUDdr4PreMem);
+      PcdSet16S (PcdBoardGpioTablePreMemSize, sizeof (mGpioTableWhlUDdr4PreMem) / sizeof (GPIO_INIT_CONFIG));
+      PcdSet32S (PcdBoardGpioTableWwanOnEarlyPreMem, (UINTN) mGpioTableWhlUDdr4WwanOnEarlyPreMem);
+      PcdSet16S (PcdBoardGpioTableWwanOnEarlyPreMemSize, sizeof (mGpioTableWhlUDdr4WwanOnEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
+      PcdSet32S (PcdBoardGpioTableWwanOffEarlyPreMem, (UINTN) mGpioTableWhlUDdr4WwanOffEarlyPreMem);
+      PcdSet16S (PcdBoardGpioTableWwanOffEarlyPreMemSize, sizeof (mGpioTableWhlUDdr4WwanOffEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PmConfig init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+PchPmConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update PmCofig policy: output voltage of VCCPRIMCORE RAIL when SLP_S0# is asserted based on board HW design
+  // 1) Discete VR or Non Premium PMIC: 0.75V (PcdSlpS0Vm075VSupport)
+  // 2) Premium PMIC: runtime control for voltage (PcdSlpS0VmRuntimeControl)
+  // Only applys to board with PCH-LP. Board with Discrete PCH doesn't need this setting.
+  //
+  switch (BoardId) {
+    // Discrete VR solution
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm075VSupport, TRUE);
+      break;
+
+    default:
+      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm075VSupport, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
new file mode 100644
index 0000000000..17f12c117d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
@@ -0,0 +1,282 @@
+/** @file
+ Source code for the board SA configuration Pcd init functions in Pre-Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include "BoardSaConfigPreMem.h"
+#include <PlatformBoardConfig.h>
+#include <Library/CpuPlatformLib.h>
+#include "SaPolicyCommon.h"
+
+//
+// Display DDI settings for WHL ERB
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mWhlErbRowDisplayDdiConfig[9] = {
+  DdiPortAEdp,     // DDI Port A Config : DdiPortADisabled = Disabled, DdiPortAEdp = eDP, DdiPortAMipiDsi = MIPI DSI
+  DdiHpdEnable,    // DDI Port B HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdEnable,    // DDI Port C HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdDisable,   // DDI Port D HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdDisable,   // DDI Port F HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiDdcEnable,    // DDI Port B DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDdcEnable,    // DDI Port C DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDdcEnable,    // DDI Port D DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDisable       // DDI Port F DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+};
+
+/**
+  MRC configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaMiscConfigInit (
+  IN UINT16         BoardId
+  )
+{
+  //
+  // UserBd
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // Assign UserBd to 5 which is assigned to MrcInputs->BoardType btUser4 for ULT platforms.
+      // This is required to skip Memory voltage programming based on GPIO's in MRC
+      //
+      PcdSet8S (PcdSaMiscUserBd, 5); // MrcBoardType btUser4 for ULT platform
+      break;
+
+    default:
+      // MiscPeiPreMemConfig.UserBd = 0 by default.
+      break;
+  }
+
+  PcdSet16S (PcdSaDdrFreqLimit, 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board Memory Init related configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+MrcConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  CPU_FAMILY    CpuFamilyId;
+  CPU_STEPPING  CpuStepping;
+
+  CpuFamilyId = GetCpuFamily();
+  CpuStepping = GetCpuStepping();
+
+  if (CpuFamilyId == EnumCpuCflDtHalo) {
+    PcdSetBoolS (PcdDualDimmPerChannelBoardType, TRUE);
+  } else {
+    PcdSetBoolS (PcdDualDimmPerChannelBoardType, FALSE);
+  }
+
+  //
+  // Example policy for DIMM slots implementation boards:
+  // 1. Assign Smbus address of DIMMs and SpdData will be updated later
+  //    by reading from DIMM SPD.
+  // 2. No need to apply hardcoded SpdData buffers here for such board.
+  //
+  //  Whiskey Lake U RVP has removable DIMM slots.
+  //  So assign all Smbus address of DIMMs and leave PcdMrcSpdData set to 0.
+  //   Example:
+  //   PcdMrcSpdData = 0
+  //   PcdMrcSpdDataSize = 0
+  //   PcdMrcSpdAddressTable0 = 0xA0
+  //   PcdMrcSpdAddressTable1 = 0xA2
+  //   PcdMrcSpdAddressTable2 = 0xA4
+  //   PcdMrcSpdAddressTable3 = 0xA6
+  //
+  //  If a board has soldered down memory. It should use the following settings.
+  //   Example:
+  //   PcdMrcSpdAddressTable0 = 0
+  //   PcdMrcSpdAddressTable1 = 0
+  //   PcdMrcSpdAddressTable2 = 0
+  //   PcdMrcSpdAddressTable3 = 0
+  //   PcdMrcSpdData = static data buffer
+  //   PcdMrcSpdDataSize = sizeof (static data buffer)
+  //
+
+  //
+  // SPD Address Table
+  //
+  PcdSet32S (PcdMrcSpdData, 0);
+  PcdSet16S (PcdMrcSpdDataSize, 0);
+  PcdSet8S (PcdMrcSpdAddressTable0, 0xA0);
+  PcdSet8S (PcdMrcSpdAddressTable1, 0xA2);
+  PcdSet8S (PcdMrcSpdAddressTable2, 0xA4);
+  PcdSet8S (PcdMrcSpdAddressTable3, 0xA6);
+
+  //
+  // DRAM SPD Data & related configuration
+  //
+  // Setting the PCD's to default value (WHL RVP3). It will be overriden to board specific settings below.
+  PcdSet32S (PcdMrcDqByteMap, (UINTN) mDqByteMapWhlUDdr4Rvp);
+  PcdSet16S (PcdMrcDqByteMapSize, sizeof (mDqByteMapWhlUDdr4Rvp));
+  PcdSet32S (PcdMrcDqsMapCpu2Dram, (UINTN) mDqsMapCpu2DramWhlUDdr4Rvp);
+  PcdSet16S (PcdMrcDqsMapCpu2DramSize, sizeof (mDqsMapCpu2DramWhlUDdr4Rvp));
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdMrcRcompResistor, (UINTN) RcompResistorCflUDdr4Interposer);
+      PcdSet32S (PcdMrcRcompTarget, (UINTN) RcompTargetWhlUDdr4Interposer);
+      PcdSetBoolS (PcdMrcDqPinsInterleavedControl, TRUE);
+      PcdSetBoolS (PcdMrcDqPinsInterleaved, TRUE);
+      break;
+
+    default:
+      break;
+  }
+
+  //
+  // CA Vref routing: board-dependent
+  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
+  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
+  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdMrcCaVrefConfig, 2); // DDR4 boards
+      break;
+
+    default:
+      PcdSet8S (PcdMrcCaVrefConfig, 0); // All DDR3L/LPDDR3/LPDDR4 boards
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board SA related GPIO configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaGpioConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update board's GPIO for PEG slot reset
+  //
+  PcdSetBoolS (PcdPegGpioResetControl, TRUE);
+  PcdSetBoolS (PcdPegGpioResetSupoort, FALSE);
+  PcdSet32S (PcdPeg0ResetGpioPad, 0);
+  PcdSetBoolS (PcdPeg0ResetGpioActive, FALSE);
+  PcdSet32S (PcdPeg3ResetGpioPad, 0);
+  PcdSetBoolS (PcdPeg3ResetGpioActive, FALSE);
+
+  //
+  // PCIE RTD3 GPIO
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S(PcdRootPortIndex, 4);
+      PcdSet8S (PcdPcie0GpioSupport, PchGpio);
+      PcdSet32S (PcdPcie0WakeGpioNo, 0);
+      PcdSet8S (PcdPcie0HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie0HoldRstGpioNo, GPIO_CNL_LP_GPP_C15);
+      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
+      PcdSet8S (PcdPcie0PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie0PwrEnableGpioNo, GPIO_CNL_LP_GPP_C14);
+      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie1WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie2WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
+      break;
+
+    default:
+      PcdSet8S(PcdRootPortIndex, 0xFF);
+      PcdSet8S  (PcdPcie0GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie0WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie0HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie0HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie0PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie0PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie1WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie2WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  SA Display DDI configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId       An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaDisplayConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update Display DDI Config
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdSaDisplayConfigTable, (UINTN) mWhlErbRowDisplayDdiConfig);
+      PcdSet16S (PcdSaDisplayConfigTableSize, sizeof (mWhlErbRowDisplayDdiConfig));
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..c52d4eceed
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
@@ -0,0 +1,40 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardInitBeforeSiliconInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..1283a4c80a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,106 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  );
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+BoardDetect (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDetect ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDebugInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+  VOID
+  )
+{
+  return WhiskeylakeURvpBoardBootModeDetect ();
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardInitBeforeMemoryInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..965110a5a5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
@@ -0,0 +1,41 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/MultiBoardInitSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  );
+
+BOARD_POST_MEM_INIT_FUNC  mWhiskeylakeURvpBoardInitFunc = {
+  WhiskeylakeURvpBoardInitBeforeSiliconInit,
+  NULL, // BoardInitAfterSiliconInit
+};
+
+EFI_STATUS
+EFIAPI
+PeiWhiskeylakeURvpMultiBoardInitLibConstructor (
+  VOID
+  )
+{
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    return RegisterBoardPostMemInit (&mWhiskeylakeURvpBoardInitFunc);
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..a2a6efe506
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
@@ -0,0 +1,83 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/MultiBoardInitSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDetect (
+  VOID
+  );
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  );
+
+BOARD_DETECT_FUNC  mWhiskeylakeURvpBoardDetectFunc = {
+  WhiskeylakeURvpMultiBoardDetect
+};
+
+BOARD_PRE_MEM_INIT_FUNC  mWhiskeylakeURvpBoardPreMemInitFunc = {
+  WhiskeylakeURvpBoardDebugInit,
+  WhiskeylakeURvpBoardBootModeDetect,
+  WhiskeylakeURvpBoardInitBeforeMemoryInit,
+  NULL, // BoardInitAfterMemoryInit
+  NULL, // BoardInitBeforeTempRamExit
+  NULL, // BoardInitAfterTempRamExit
+};
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDetect (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDetect ();
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    RegisterBoardPreMemInit (&mWhiskeylakeURvpBoardPreMemInitFunc);
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor (
+  VOID
+  )
+{
+  return RegisterBoardDetect (&mWhiskeylakeURvpBoardDetectFunc);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
new file mode 100644
index 0000000000..0adbed7f53
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
@@ -0,0 +1,63 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+
+#include "PeiWhiskeylakeURvpInitLib.h"
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>
+
+BOOLEAN
+WhiskeylakeURvp(
+  VOID
+  )
+{
+  return TRUE;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  )
+{
+  if (LibPcdGetSku () != 0) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((EFI_D_INFO, "WhiskeylakeURvpDetectionCallback\n"));
+
+  if (WhiskeylakeURvp()) {
+    LibPcdSetSku (BoardIdWhiskeyLakeRvp);
+
+    DEBUG ((DEBUG_INFO, "SKU_ID: 0x%x\n", LibPcdGetSku()));
+    ASSERT (LibPcdGetSku() == BoardIdWhiskeyLakeRvp);
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
new file mode 100644
index 0000000000..80b0a97612
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
@@ -0,0 +1,432 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+#include <IoExpander.h>
+#include "PeiWhiskeylakeURvpInitLib.h"
+#include "GpioTableDefault.h"
+#include "GpioTableWhlUDdr4.h"
+#include <AttemptUsbFirst.h>
+#include <PeiPlatformHookLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Library/PchInfoLib.h>
+#include <FirwmareConfigurations.h>
+
+EFI_STATUS
+BoardFunctionInit(
+  IN UINT16 BoardId
+);
+
+/**
+GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardGpioInit(
+  IN UINT16 BoardId
+)
+{
+  //
+  // GPIO Table Init.
+  //
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableWhlUDdr4_0);
+      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableWhlUDdr4_0) / sizeof(GPIO_INIT_CONFIG));
+      PcdSet32S(PcdBoardGpioTable2, (UINTN)mGpioTableWhlUDdr4);
+      PcdSet16S(PcdBoardGpioTable2Size, sizeof(mGpioTableWhlUDdr4) / sizeof(GPIO_INIT_CONFIG));
+      break;
+
+    default:
+      DEBUG((DEBUG_INFO, "For Unknown Board ID..Use Default GPIO Table...\n"));
+      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableDefault);
+      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableDefault) / sizeof(GPIO_INIT_CONFIG));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+Touch panel GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+TouchPanelGpioInit(
+  IN UINT16 BoardId
+)
+{
+  switch (BoardId) {
+    default:
+      PcdSet32S(PcdBoardGpioTableTouchPanel, 0);
+    break;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+Misc. init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInit(
+  IN UINT16 BoardId
+)
+{
+  PcdSetBoolS(PcdDebugUsbUartEnable, FALSE);
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+
+      PcdSetBoolS(PcdMipiCamGpioEnable, TRUE);
+      break;
+
+    default:
+      PcdSetBoolS(PcdMipiCamGpioEnable, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+Security GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardSecurityInit (
+  IN UINT16 BoardId
+)
+{
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+
+      // TPM interrupt connects to GPIO_CNL_H_GPP_A_7
+      PcdSet32S (PcdTpm2CurrentIrqNum, 0x1F);
+      break;
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+WhiskeyLake board configuration init function for PEI post memory phase.
+
+@param[in]  Content  pointer to the buffer contain init information for board init.
+
+@retval EFI_SUCCESS             The function completed successfully.
+@retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+BoardConfigInit(
+  VOID
+)
+{
+  EFI_STATUS  Status;
+  UINT16      BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = BoardGpioInit(BoardId);
+  Status = TouchPanelGpioInit(BoardId);
+  Status = HdaVerbTableInit(BoardId);
+  Status = BoardMiscInit(BoardId);
+  Status = BoardFunctionInit(BoardId);
+  Status = BoardSecurityInit(BoardId);
+
+  return EFI_SUCCESS;
+}
+
+//@todo Review this functionality and if it is required for WHL SDS
+/**
+Create the HOB for hotkey status for 'Attempt USB First' feature
+
+@retval  EFI_SUCCESS  HOB Creating successful.
+@retval  Others       HOB Creating failed.
+**/
+EFI_STATUS
+CreateAttemptUsbFirstHotkeyInfoHob(
+  VOID
+)
+{
+  EFI_STATUS                     Status;
+  ATTEMPT_USB_FIRST_HOTKEY_INFO  AttemptUsbFirstHotkeyInfo;
+
+  Status = EFI_SUCCESS;
+
+  ZeroMem(
+    &AttemptUsbFirstHotkeyInfo,
+    sizeof(AttemptUsbFirstHotkeyInfo)
+  );
+
+  AttemptUsbFirstHotkeyInfo.RevisonId = 0;
+  AttemptUsbFirstHotkeyInfo.HotkeyTriggered = FALSE;
+
+  ///
+  /// Build HOB for Attempt USB First feature
+  ///
+  BuildGuidDataHob(
+    &gAttemptUsbFirstHotkeyInfoHobGuid,
+    &(AttemptUsbFirstHotkeyInfo),
+    sizeof(ATTEMPT_USB_FIRST_HOTKEY_INFO)
+  );
+
+  return Status;
+}
+
+/**
+Search and identify the physical address of a
+file module inside the FW_BINARIES_FV_SIGNED FV
+
+@retval  EFI_SUCCESS  If address has been found
+@retval  Others       If address has not been found
+**/
+EFI_STATUS
+FindModuleInFlash2(
+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
+  IN EFI_GUID                   *GuidPtr,
+  IN OUT UINT32                 *ModulePtr,
+  IN OUT UINT32                 *ModuleSize
+)
+{
+  EFI_FFS_FILE_HEADER        *FfsHeader;
+  EFI_FV_FILE_INFO           FileInfo;
+  EFI_PEI_FILE_HANDLE        FileHandle;
+  EFI_COMMON_SECTION_HEADER  *SectionHeader;
+  VOID                       *FileBuffer;
+  EFI_STATUS                 Status;
+
+  FfsHeader = NULL;
+  FileHandle = NULL;
+  SectionHeader = NULL;
+  FileBuffer = NULL;
+
+  while (TRUE) {
+    //
+    // Locate FV_IMAGE file type in the FW_BINARIES_FV_SIGNED firmware volume
+    //
+    Status = PeiServicesFfsFindNextFile(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, FvHeader, &FileHandle);
+    if (EFI_ERROR(Status)) {
+      // unable to find FV_IMAGE file in this FV
+      break;
+    }
+
+    FfsHeader = (EFI_FFS_FILE_HEADER*)FileHandle;
+    DEBUG((DEBUG_INFO, "FfsHeader 0x%X:\n", FfsHeader));
+    DEBUG((DEBUG_INFO, " Name = 0x%g\n", &FfsHeader->Name));
+    DEBUG((DEBUG_INFO, " Type = 0x%X\n", FfsHeader->Type));
+    if (IS_FFS_FILE2(FfsHeader)) {
+      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE2_SIZE(FfsHeader)));
+    }
+    else {
+      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE_SIZE(FfsHeader)));
+    }
+
+    //
+    // Locate FW_BINARIES_FV FV_IMAGE Section
+    //
+    Status = PeiServicesFfsFindSectionData(EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FileHandle, &FileBuffer);
+    if (EFI_ERROR(Status)) {
+      // continue to search for the next FV_IMAGE file
+      DEBUG((DEBUG_INFO, "FW_BINARIES_FV section not found. Status = %r\n", Status));
+      continue;
+    }
+
+    SectionHeader = (EFI_COMMON_SECTION_HEADER *)FileBuffer;
+    DEBUG((DEBUG_INFO, "GUIDED SectionHeader 0x%X:\n",
+    (UINT32)(UINT8 *)SectionHeader));
+    if (IS_SECTION2(SectionHeader)) {
+      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
+        &((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->SectionDefinitionGuid));
+      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
+        ((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->DataOffset));
+    }
+    else {
+      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
+        &((EFI_GUID_DEFINED_SECTION *)SectionHeader)->SectionDefinitionGuid));
+      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
+        ((EFI_GUID_DEFINED_SECTION *)SectionHeader)->DataOffset));
+    }
+    DEBUG((DEBUG_INFO, " Type      = 0x%X\n", SectionHeader->Type));
+
+    //
+    // Locate Firmware File System file within Firmware Volume
+    //
+    Status = PeiServicesFfsFindFileByName(GuidPtr, FileBuffer, (VOID **)&FfsHeader);
+    if (EFI_ERROR(Status)) {
+      // continue to search for the next FV_IMAGE file
+      DEBUG((DEBUG_INFO, "Module not found. Status = %r\n", Status));
+      continue;
+    }
+
+    *ModulePtr = (UINT32)((UINT8 *)FfsHeader + sizeof(EFI_FFS_FILE_HEADER));
+
+    //
+    // Get File Information
+    //
+    Status = PeiServicesFfsGetFileInfo(FfsHeader, &FileInfo);
+    if (!EFI_ERROR(Status)) {
+      *ModuleSize = (UINT32)FileInfo.BufferSize;
+      DEBUG((DEBUG_INFO, "Module {0x%g} found at = 0x%X, Size = 0x%X\n",
+        &FfsHeader->Name, *ModulePtr, *ModuleSize));
+      return Status;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+Get the ChipsetInit Binary pointer.
+
+@retval EFI_SUCCESS               - ChipsetInit Binary found.
+@retval EFI_NOT_FOUND             - ChipsetInit Binary not found.
+**/
+EFI_STATUS
+UpdateChipsetInitPtr(
+  VOID
+)
+{
+  EFI_STATUS                    Status;
+  PCH_STEPPING                  PchStep;
+  EFI_FIRMWARE_VOLUME_HEADER    *FvHeader;
+  EFI_GUID                      *ChipsetInitBinaryGuidPtr;
+  SI_POLICY_PPI                 *SiPolicyPpi;
+  PCH_HSIO_CONFIG               *HsioConfig;
+  UINT32                        ModuleAddr;
+  UINT32                        ModuleSize;
+
+  ModuleAddr = 0;
+  ModuleSize = 0;
+  PchStep = PchStepping();
+
+  Status = PeiServicesLocatePpi(
+    &gSiPolicyPpiGuid,
+    0,
+    NULL,
+    (VOID **)&SiPolicyPpi
+  );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gHsioConfigGuid, (VOID *)&HsioConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  ChipsetInitBinaryGuidPtr = NULL;
+  if (IsPchLp()) {
+    switch (PchStep) {
+      case PCH_D0:
+      case PCH_D1:
+        ChipsetInitBinaryGuidPtr = &gCnlPchLpChipsetInitTableDxGuid;
+        DEBUG((DEBUG_INFO, "Using CnlPchLpChipsetInitTable_Dx table \n"));
+        break;
+      default:
+        return EFI_NOT_FOUND;
+    }
+  }
+  else {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Locate Firmware Volume header
+  //
+  //	FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)GetFvBinaryBase();
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FixedPcdGet32(PcdFlashFvPostMemoryBase);
+  Status = FindModuleInFlash2(FvHeader, ChipsetInitBinaryGuidPtr, &ModuleAddr, &ModuleSize);
+  //
+  // Get ChipsetInit Binary Pointer
+  //
+  HsioConfig->ChipsetInitBinPtr = ModuleAddr;
+
+  //
+  // Get File Size
+  //
+  HsioConfig->ChipsetInitBinLen = ModuleSize;
+
+  DEBUG((DEBUG_INFO, "ChipsetInit Binary Location: %x\n", HsioConfig->ChipsetInitBinPtr));
+  DEBUG((DEBUG_INFO, "ChipsetInit Binary Size: %x\n", HsioConfig->ChipsetInitBinLen));
+
+  return Status;
+}
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  UINT8                            FwConfig;
+
+  BoardConfigInit();
+  //
+  // Configure GPIO and SIO
+  //
+  Status = BoardInit();
+  ASSERT_EFI_ERROR(Status);
+
+  FwConfig = FwConfigProduction;
+  PeiPolicyInit(FwConfig);
+
+  //
+  // Create USB Boot First hotkey information HOB
+  //
+  CreateAttemptUsbFirstHotkeyInfoHob();
+
+  //
+  // Initializing Platform Specific Programming
+  //
+  Status = PlatformSpecificInit();
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Update ChipsetInitPtr
+  //
+  Status = UpdateChipsetInitPtr();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
new file mode 100644
index 0000000000..519a5be216
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
@@ -0,0 +1,636 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+
+#include "PeiWhiskeylakeURvpInitLib.h"
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Library/PchResetLib.h>
+#include <Register/PchRegsLpc.h>
+#include <Library/StallPpiLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Ppi/Reset.h>
+#include <PlatformBoardConfig.h>
+#include <GpioPinsCnlLp.h>
+#include <Library/PmcLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PeiPlatformHookLib.h>
+#include <FirwmareConfigurations.h>
+#include <Guid/TcoWdtHob.h>
+#include <Library/OcWdtLib.h>
+
+///
+/// Reset Generator I/O Port
+///
+#define RESET_GENERATOR_PORT           0xCF9
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS    BaseAddress;
+  UINT64                  Length;
+} MEMORY_MAP;
+
+//
+// Reference RCOMP resistors on motherboard - for WHL RVP1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
+
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for WHL RVP1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
+
+GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_MAP MmioMap[] = {
+  { FixedPcdGet64(PcdApicLocalAddress), FixedPcdGet32(PcdApicLocalMmioSize) },
+  { FixedPcdGet64(PcdMchBaseAddress), FixedPcdGet32(PcdMchMmioSize) },
+  { FixedPcdGet64(PcdDmiBaseAddress), FixedPcdGet32(PcdDmiMmioSize) },
+  { FixedPcdGet64(PcdEpBaseAddress), FixedPcdGet32(PcdEpMmioSize) },
+  { FixedPcdGet64(PcdGdxcBaseAddress), FixedPcdGet32(PcdGdxcMmioSize) }
+};
+
+EFI_STATUS
+MrcConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+SaGpioConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+  SaMiscConfigInit(
+IN UINT16         BoardId
+);
+
+EFI_STATUS
+  RootPortClkInfoInit(
+IN UINT16 BoardId
+);
+
+EFI_STATUS
+  UsbConfigInit(
+IN UINT16 BoardId
+);
+
+EFI_STATUS
+GpioGroupTierInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+GpioTablePreMemInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+PchPmConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+SaDisplayConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+BoardFunctionInitPreMem(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemCallBack(
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN VOID                        *Ppi
+);
+
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotify(
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN VOID                        *Ppi
+);
+
+EFI_STATUS
+EFIAPI
+PchReset(
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+);
+
+static EFI_PEI_RESET_PPI mResetPpi = {
+  PchReset
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPreMemPpiList[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiResetPpiGuid,
+    &mResetPpi
+  }
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mPreMemNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiReadOnlyVariable2PpiGuid,
+  (EFI_PEIM_NOTIFY_ENTRY_POINT)PlatformInitPreMemCallBack
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mMemDiscoveredNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiMemoryDiscoveredPpiGuid,
+  (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotify
+};
+
+/**
+Board misc init function for PEI pre-memory phase.
+
+@param[in]  BoardId   An unsigned integer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInitPreMem(
+  IN UINT16 BoardId
+)
+{
+  PCD64_BLOB PcdData;
+
+  //
+  // RecoveryMode GPIO
+  //
+  PcdData.Blob = 0;
+  PcdData.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdData.BoardGpioConfig.Type = BoardGpioTypePch;
+      PcdData.BoardGpioConfig.u.Pin = GPIO_CNL_LP_GPP_F10;
+    break;
+
+    default:
+      break;
+  }
+
+  //
+  // Configure WWAN Full Card Power Off and reset pins
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // According to board default settings, GPP_D16 is used to enable/disable modem
+      // power. An alternative way to contol modem power is to toggle FCP_OFF via GPP_D13
+      // but board rework is required.
+      //
+      PcdSet32S(PcdWwanFullCardPowerOffGpio, GPIO_CNL_LP_GPP_D16);
+      PcdSet32S(PcdWwanBbrstGpio, GPIO_CNL_LP_GPP_F1);
+      PcdSet32S(PcdWwanPerstGpio, GPIO_CNL_LP_GPP_E15);
+      PcdSet8S(PcdWwanPerstGpioPolarity, 1);
+      break;
+
+    default:
+      break;
+  }
+
+  PcdSet64S(PcdRecoveryModeGpio, PcdData.Blob);
+
+  //
+  // Pc8374SioKbc Present
+  //
+  PcdSetBoolS(PcdPc8374SioKbcPresent, FALSE);
+
+  return EFI_SUCCESS;
+}
+
+//@todo it should be moved to Si Pkg.
+/**
+Early Platform PCH initialization
+**/
+VOID
+EarlyPlatformPchInit(
+  VOID
+)
+{
+  UINT8        Data8;
+  UINT8        TcoRebootHappened;
+  TCO_WDT_HOB  *TcoWdtHobPtr;
+  EFI_STATUS   Status;
+
+  ///
+  /// Read the Second TO status bit
+  ///
+  Data8 = IoRead8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS);
+  if ((Data8 & B_TCO_IO_TCO2_STS_SECOND_TO) == B_TCO_IO_TCO2_STS_SECOND_TO) {
+    TcoRebootHappened = 1;
+    DEBUG((DEBUG_INFO, "PlatformInitPreMem - TCO Second TO status bit is set. This might be a TCO reboot\n"));
+  }
+  else {
+    TcoRebootHappened = 0;
+  }
+
+  ///
+  /// Create HOB
+  ///
+  Status = PeiServicesCreateHob(EFI_HOB_TYPE_GUID_EXTENSION, sizeof(TCO_WDT_HOB), (VOID **)&TcoWdtHobPtr);
+  if (!EFI_ERROR(Status)) {
+    TcoWdtHobPtr->Header.Name = gTcoWdtHobGuid;
+    TcoWdtHobPtr->TcoRebootHappened = TcoRebootHappened;
+  }
+
+  ///
+  /// Clear the Second TO status bit
+  ///
+  IoWrite8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS, B_TCO_IO_TCO2_STS_SECOND_TO);
+}
+
+/**
+Board init function for PEI pre-memory phase.
+
+@param  Content  pointer to the buffer contain init information for board init.
+
+@retval EFI_SUCCESS             The function completed successfully.
+@retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+BoardConfigInitPreMem(
+  VOID
+)
+{
+  EFI_STATUS Status;
+  UINT16 BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = MrcConfigInit(BoardId);
+  Status = SaGpioConfigInit(BoardId);
+  Status = SaMiscConfigInit(BoardId);
+  Status = RootPortClkInfoInit(BoardId);
+  Status = UsbConfigInit(BoardId);
+  Status = GpioGroupTierInit(BoardId);
+  Status = GpioTablePreMemInit(BoardId);
+  Status = PchPmConfigInit(BoardId);
+  Status = BoardMiscInitPreMem(BoardId);
+  Status = SaDisplayConfigInit(BoardId);
+  Status = BoardFunctionInitPreMem(BoardId);
+
+  return EFI_SUCCESS;
+}
+
+/**
+This function handles PlatformInit task after PeiReadOnlyVariable2 PPI produced
+
+@param[in]  PeiServices   Pointer to PEI Services Table.
+@param[in]  NotifyDesc    Pointer to the descriptor for the Notification event that
+                          caused this function to execute.
+@param[in]  Ppi           Pointer to the PPI data associated with this function.
+
+@retval     EFI_SUCCESS  The function completes successfully
+@retval     others
+**/
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemCallBack(
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+)
+{
+  EFI_STATUS                        Status;
+  UINT16                            ABase;
+  UINT8                             FwConfig;
+  UINT8                             SynchDelay;
+
+  //
+  // Init Board Config Pcd.
+  //
+  BoardConfigInitPreMem();
+
+  DEBUG((DEBUG_ERROR, "Fail to get System Configuration and set the configuration to production mode!\n"));
+  FwConfig = FwConfigProduction;
+  SynchDelay = 0;
+  PcdSetBoolS(PcdPcieWwanEnable, FALSE);
+  PcdSetBoolS(PcdWwanResetWorkaround, FALSE);
+
+  //
+  // Early Board Configuration before memory is ready.
+  //
+  Status = BoardInitEarlyPreMem();
+  ASSERT_EFI_ERROR(Status);
+
+  ///
+  /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
+  /// clear unexpected reset status and enforce expiration. This is to inform Firmware
+  /// which has no access to unexpected reset status bit, that something went wrong.
+  ///
+  OcWdtResetCheck();
+
+  Status = OcWdtInit();
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Initialize Intel PEI Platform Policy
+  //
+  PeiPolicyInitPreMem(FwConfig);
+
+  ///
+  /// Configure GPIO and SIO
+  ///
+  Status = BoardInitPreMem();
+  ASSERT_EFI_ERROR(Status);
+
+  ABase = PmcGetAcpiBase();
+
+  ///
+  /// Clear all pending SMI. On S3 clear power button enable so it will not generate an SMI.
+  ///
+  IoWrite16(ABase + R_ACPI_IO_PM1_EN, 0);
+  IoWrite32(ABase + R_ACPI_IO_GPE0_EN_127_96, 0);
+
+  ///
+  /// Install Pre Memory PPIs
+  ///
+  Status = PeiServicesInstallPpi(&mPreMemPpiList[0]);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
+/**
+Provide hard reset PPI service.
+To generate full hard reset, write 0x0E to PCH RESET_GENERATOR_PORT (0xCF9).
+
+@param[in]  PeiServices       General purpose services available to every PEIM.
+
+@retval     Not return        System reset occured.
+@retval     EFI_DEVICE_ERROR  Device error, could not reset the system.
+**/
+EFI_STATUS
+EFIAPI
+PchReset(
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+)
+{
+  DEBUG((DEBUG_INFO, "Perform Cold Reset\n"));
+  IoWrite8(RESET_GENERATOR_PORT, 0x0E);
+
+  CpuDeadLoop();
+
+  ///
+  /// System reset occured, should never reach at this line.
+  ///
+  ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
+
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+Install Firmware Volume Hob's once there is main memory
+
+@param[in]  PeiServices       General purpose services available to every PEIM.
+@param[in]  NotifyDescriptor  Notify that this module published.
+@param[in]  Ppi               PPI that was installed.
+
+@retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotify(
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+)
+{
+  EFI_STATUS                    Status;
+  EFI_BOOT_MODE                 BootMode;
+  UINTN                         Index;
+  UINT8                         PhysicalAddressBits;
+  UINT32                        RegEax;
+  MEMORY_MAP                    PcieMmioMap;
+
+  Index = 0;
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  AsmCpuid(0x80000000, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= 0x80000008) {
+    AsmCpuid(0x80000008, &RegEax, NULL, NULL, NULL);
+    PhysicalAddressBits = (UINT8)RegEax;
+  }
+  else {
+    PhysicalAddressBits = 36;
+  }
+
+  ///
+  /// Create a CPU hand-off information
+  ///
+  BuildCpuHob(PhysicalAddressBits, 16);
+
+  ///
+  /// Build Memory Mapped IO Resource which is used to build E820 Table in LegacyBios.
+  ///
+  PcieMmioMap.BaseAddress = FixedPcdGet64(PcdPciExpressBaseAddress);
+  PcieMmioMap.Length = PcdGet32(PcdPciExpressRegionLength);
+
+  BuildResourceDescriptorHob(
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    PcieMmioMap.BaseAddress,
+    PcieMmioMap.Length
+  );
+  BuildMemoryAllocationHob(
+    PcieMmioMap.BaseAddress,
+    PcieMmioMap.Length,
+    EfiMemoryMappedIO
+  );
+  for (Index = 0; Index < sizeof(MmioMap) / (sizeof(MEMORY_MAP)); Index++) {
+    BuildResourceDescriptorHob(
+      EFI_RESOURCE_MEMORY_MAPPED_IO,
+      (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+      MmioMap[Index].BaseAddress,
+      MmioMap[Index].Length
+    );
+    BuildMemoryAllocationHob(
+      MmioMap[Index].BaseAddress,
+      MmioMap[Index].Length,
+      EfiMemoryMappedIO
+    );
+  }
+
+  //
+  // Report resource HOB for flash FV
+  //
+  BuildResourceDescriptorHob(
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
+  );
+  BuildMemoryAllocationHob(
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize),
+    EfiMemoryMappedIO
+  );
+
+  BuildFvHob(
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
+  );
+
+  return Status;
+}
+
+
+/**
+  Board configuration init function for PEI pre-memory phase.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpInitPreMem (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  ///
+  /// Install Stall PPI
+  ///
+  Status = InstallStallPpi();
+  ASSERT_EFI_ERROR(Status);
+
+  ///@todo it should be moved to Si Pkg.
+  ///
+  /// Do Early PCH init
+  ///
+  EarlyPlatformPchInit();
+
+  //
+  // Install PCH RESET PPI and EFI RESET2 PeiService
+  //
+  Status = PchInitializeReset();
+  ASSERT_EFI_ERROR(Status);
+
+  ///
+  /// Performing PlatformInitPreMemCallBack after PeiReadOnlyVariable2 PPI produced
+  ///
+  Status = PeiServicesNotifyPpi(&mPreMemNotifyList);
+
+  ///
+  /// After code reorangized, memorycallback will run because the PPI is already
+  /// installed when code run to here, it is supposed that the InstallEfiMemory is
+  /// done before.
+  ///
+  Status = PeiServicesNotifyPpi(&mMemDiscoveredNotifyList);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure GPIO and SIO before memory ready
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpInitPreMem ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  )
+{
+  UINT64                            LpcBaseAddress;
+
+  ///
+  /// LPC I/O Configuration
+  ///
+  PchLpcIoDecodeRangesSet(
+    (V_LPC_CFG_IOD_LPT_378 << N_LPC_CFG_IOD_LPT) |
+    (V_LPC_CFG_IOD_COMB_3E8 << N_LPC_CFG_IOD_COMB) |
+    (V_LPC_CFG_IOD_COMA_3F8 << N_LPC_CFG_IOD_COMA)
+  );
+
+  PchLpcIoEnableDecodingSet(
+    B_LPC_CFG_IOE_ME2 |
+    B_LPC_CFG_IOE_SE |
+    B_LPC_CFG_IOE_ME1 |
+    B_LPC_CFG_IOE_KE |
+    B_LPC_CFG_IOE_HGE |
+    B_LPC_CFG_IOE_LGE |
+    B_LPC_CFG_IOE_FDE |
+    B_LPC_CFG_IOE_PPE |
+    B_LPC_CFG_IOE_CBE |
+    B_LPC_CFG_IOE_CAE
+  );
+
+  ///
+  /// Enable LPC IO decode for EC access
+  ///
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
+    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    0
+  );
+
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
new file mode 100644
index 0000000000..8d8ca835bc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
@@ -0,0 +1,32 @@
+/** @file
+    WhiskeylakeURvp HSIO PTSS H File
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+#define WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+
+#include <PchHsioPtssTables.h>
+
+#ifndef HSIO_PTSS_TABLE_SIZE
+#define HSIO_PTSS_TABLE_SIZE(A) A##_Size = sizeof (A) / sizeof (HSIO_PTSS_TABLES)
+#endif
+
+//BoardId WhiskeylakeURvp
+HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[] = {
+  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0}
+};
+
+UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size = sizeof(PchLpHsioPtss_Cx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
+
+HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[] = {
+  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0},
+};
+
+UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size = sizeof(PchLpHsioPtss_Bx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
+
+#endif // WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
new file mode 100644
index 0000000000..d2c26eb163
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel DXE SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxePolicyBoardConfig.h"
+
+/**
+  This function performs DXE SA Policy update by board configuration.
+
+  @param[in, out] DxeSaPolicy    DXE SA Policy
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicyBoardConfig (
+  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
+  )
+{
+  EFI_STATUS                         Status;
+  MEMORY_DXE_CONFIG                  *MemoryDxeConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in DXE\n"));
+
+  Status = GetConfigBlock ((VOID *)DxeSaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
new file mode 100644
index 0000000000..c495a3a401
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
@@ -0,0 +1,299 @@
+/** @file
+  PEI Library Functions. Initialize GPIOs
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <PeiPlatformHookLib.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <PchAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Library/PchInfoLib.h>
+#include <Library/CnviLib.h>
+#include <SioRegs.h>
+#include <PlatformBoardConfig.h>
+#include <Library/PchPcrLib.h>
+#include <Library/GpioCheckConflictLib.h>
+
+#define SIO_RUNTIME_REG_BASE_ADDRESS                          0x0680
+
+#define RECOVERY_MODE_GPIO_PIN                    0                    // Platform specific @todo use PCD
+
+#define MANUFACTURE_MODE_GPIO_PIN                 0                    // Platform specific @todo use PCD
+
+/**
+  Configures GPIO
+
+  @param[in]  GpioTable       Point to Platform Gpio table
+  @param[in]  GpioTableCount  Number of Gpio table entries
+
+**/
+VOID
+ConfigureGpio (
+  IN GPIO_INIT_CONFIG                 *GpioDefinition,
+  IN UINT16                           GpioTableCount
+  )
+{
+  DEBUG ((DEBUG_INFO, "ConfigureGpio() Start\n"));
+
+
+  CreateGpioCheckConflictHob (GpioDefinition, GpioTableCount);
+
+
+  GpioConfigurePads (GpioTableCount, GpioDefinition);
+
+  DEBUG ((DEBUG_INFO, "ConfigureGpio() End\n"));
+}
+
+/**
+  Configure GPIO group GPE tier.
+
+  @retval     none.
+**/
+VOID
+GpioGroupTierInitHook(
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook Start\n"));
+
+  if (PcdGet32 (PcdGpioGroupToGpeDw0)) {
+    GpioSetGroupToGpeDwX (PcdGet32 (PcdGpioGroupToGpeDw0),
+                          PcdGet32 (PcdGpioGroupToGpeDw1),
+                          PcdGet32 (PcdGpioGroupToGpeDw2));
+  }
+  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook End\n"));
+}
+
+/**
+  Configure single GPIO pad for touchpanel interrupt
+**/
+VOID
+TouchpanelGpioInit (
+  VOID
+  )
+{
+  GPIO_INIT_CONFIG*     TouchpanelPad;
+  GPIO_PAD_OWN          PadOwnVal;
+
+  PadOwnVal = 0;
+  TouchpanelPad = (VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableTouchPanel);
+  if (TouchpanelPad != NULL) {
+    GpioGetPadOwnership (TouchpanelPad->GpioPad, &PadOwnVal);
+    if (PadOwnVal == GpioPadOwnHost) {
+      GpioConfigurePads (1, TouchpanelPad);
+    }
+  }
+}
+
+/**
+  Configure GPIO Before Memory is not ready.
+
+**/
+VOID
+GpioInitPreMem (
+  VOID
+  )
+{
+  if (PcdGet32 (PcdBoardGpioTablePreMem) != 0 && PcdGet16 (PcdBoardGpioTablePreMemSize) != 0) {
+    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTablePreMem), (UINTN) PcdGet16 (PcdBoardGpioTablePreMemSize));
+  }
+}
+
+/**
+  Basic GPIO configuration before memory is ready
+
+**/
+VOID
+GpioInitEarlyPreMem (
+  VOID
+  )
+{
+  GPIO_CONFIG                     BbrstConfig;
+  UINT32                          WwanBbrstGpio;
+
+  WwanBbrstGpio = PcdGet32 (PcdWwanBbrstGpio);
+
+  if (WwanBbrstGpio) {
+    //
+    // BIOS needs to put modem in OFF state for the two scenarios below.
+    // 1. Modem RESET# is not asserted via PLTRST# in the previous sleep state
+    // 2. Modem is disabled via setup option
+    //
+    GpioGetPadConfig (WwanBbrstGpio, &BbrstConfig);
+    if ((PcdGetBool (PcdPcieWwanEnable) == FALSE) ||
+        (PcdGetBool (PcdWwanResetWorkaround) == TRUE &&
+        BbrstConfig.Direction == GpioDirOut &&
+        BbrstConfig.OutputState == GpioOutHigh)) {
+      //
+      // Assert FULL_CARD_POWER_OFF#, RESET# and PERST# GPIOs
+      //
+      if (PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize) != 0) {
+        ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize));
+      }
+      if (PcdGetBool (PcdPcieWwanEnable) == TRUE && PcdGetBool (PcdWwanResetWorkaround) == TRUE) {
+        MicroSecondDelay (1 * 1000); // Delay by 1ms
+      }
+    }
+
+    //
+    // Turn ON modem power and de-assert RESET# and PERST# GPIOs
+    //
+    if (PcdGetBool (PcdPcieWwanEnable) == TRUE) {
+      if (PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize) != 0) {
+        ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize));
+      }
+    }
+  }
+}
+
+/**
+  Configure GPIO
+
+**/
+VOID
+GpioInit (
+  VOID
+  )
+{
+  ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable), (UINTN) PcdGet16 (PcdBoardGpioTableSize));
+
+  if (PcdGet32 (PcdBoardGpioTable2)) {
+    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable2), (UINTN) PcdGet16 (PcdBoardGpioTable2Size));
+  }
+
+  TouchpanelGpioInit();
+
+  //
+  // Lock pads after initializing platform GPIO.
+  // Pads which were requested to be unlocked during configuration
+  // will not be locked.
+  //
+  GpioLockPads ();
+
+  return;
+}
+
+/**
+  Configure Super IO
+
+**/
+VOID
+SioInit (
+  VOID
+  )
+{
+  //
+  // Program and Enable Default Super IO Configuration Port Addresses and range
+  //
+  PchLpcGenIoRangeSet (PcdGet16 (PcdLpcSioConfigDefaultPort) & (~0xF), 0x10);
+
+    PchLpcGenIoRangeSet (SIO_RUNTIME_REG_BASE_ADDRESS  & (~0x7F), 0x10);
+  return;
+}
+
+/**
+  Configure GPIO and SIO before memory ready
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInitPreMem (
+  VOID
+  )
+{
+  //
+  // Obtain Platform Info from HOB.
+  //
+  GpioInitPreMem ();
+  GpioGroupTierInitHook ();
+  SioInit ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInit (
+  VOID
+  )
+{
+
+  GpioInit ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Do platform specific programming post-memory.
+
+  @retval  EFI_SUCCESS       The function completed successfully.
+**/
+
+EFI_STATUS
+PlatformSpecificInit (
+  VOID
+  )
+{
+  GPIO_CONFIG                     GpioConfig;
+
+  if (IsCnlPch ()) {
+
+    //
+    // Tristate unused pins by audio link mode.
+    //
+    ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
+    GpioConfig.PadMode = GpioPadModeGpio;
+    GpioConfig.HostSoftPadOwn = GpioHostOwnGpio;
+    GpioConfig.Direction = GpioDirNone;
+    GpioConfig.OutputState = GpioOutDefault;
+    GpioConfig.InterruptConfig = GpioIntDis;
+    GpioConfig.PowerConfig = GpioPlatformReset;
+    GpioConfig.ElectricalConfig = GpioTermNone;
+
+    GpioSetPadConfig (GPIO_CNL_LP_SSP1_SFRM, &GpioConfig);
+    GpioSetPadConfig (GPIO_CNL_LP_SSP1_TXD, &GpioConfig);
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Early Board Configuration before memory is ready
+
+  @retval  EFI_SUCCESS  Operation success.
+**/
+EFI_STATUS
+BoardInitEarlyPreMem (
+  VOID
+  )
+{
+  GpioInitEarlyPreMem ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
new file mode 100644
index 0000000000..e437814b10
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
@@ -0,0 +1,48 @@
+/** @file
+ Intel PEI CPU Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI CPU Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                  Status;
+  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
+  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
+  CPU_CONFIG                  *CpuConfig;
+
+  DEBUG((DEBUG_INFO, "Updating CPU Policy by board config in Post Mem\n"));
+
+  Status = PeiServicesLocatePpi(
+      &gSiPreMemPolicyPpiGuid,
+      0,
+      NULL,
+      (VOID **)&SiPreMemPolicyPpi
+      );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..3797df0856
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
@@ -0,0 +1,29 @@
+/** @file
+ Intel PEI CPU Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function performs PEI CPU Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
new file mode 100644
index 0000000000..843fe4accd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI ME Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI ME Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  ME_PEI_CONFIG                      *MePeiConfig;
+
+  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..79c93455a6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI ME Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI ME Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
new file mode 100644
index 0000000000..5dbc412879
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI PCH Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI PCH Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  PCH_GENERAL_CONFIG                 *PchGeneralConfig;
+
+  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..1080015029
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI PCH Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI PCH Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  PCH_GENERAL_PREMEM_CONFIG          *PchGeneralPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
new file mode 100644
index 0000000000..d1d964aea7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SA Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  GRAPHICS_PEI_CONFIG                *GtConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *)&GtConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..34fca7fac3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI SA Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SA Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  SA_MISC_PEI_PREMEM_CONFIG          *MiscPeiPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
new file mode 100644
index 0000000000..f5f38910a8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
@@ -0,0 +1,27 @@
+/** @file
+ Intel PEI SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SI Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  return EFI_SUCCESS;
+}
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (33 preceding siblings ...)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
@ 2019-08-17  0:16 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
                   ` (2 subsequent siblings)
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:16 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

Modules shared across board instances.

* BoardAcpiDxe - Performs DXE board ACPI initialization.
* PciHotPlug - Performs PCI-e resource configuration.
* PeiTbtInit - Initializes Thunderbolt policy in PEI.
* PolicyInitDxe - Initializes policy in DXE.
* TbtDxe - Performs Thunderbolt initialization in DXE.
* TbtSmm - Performs Thunderbolt initialization in SMM.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf          |   71 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf          |   62 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf         |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf     |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf         |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf      |  176 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h            |  130 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h    |  180 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h         |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h     |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h     |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h     |   52 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h        |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h      |   56 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c            |   96 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c            |  290 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c            |  353 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c           |  228 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c       |  211 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c    | 1609 +++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c           | 1765 ++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c         |  394 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c         |  612 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c     |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c     |  174 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c     |   55 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c        |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c      |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl           |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL             |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl          |  516 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl          |  309 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl         |   76 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl     |  405 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl             | 1877 ++++++++++++++++++++
 37 files changed, 10365 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
new file mode 100644
index 0000000000..2bbc3cb9e2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
@@ -0,0 +1,71 @@
+## @file
+#  Component information file for AcpiPlatform module
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BoardAcpiDxe
+  FILE_GUID                      = E269E77D-6163-4F5D-8E59-21EAF114D307
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InstallAcpiBoard
+
+[Sources.common]
+  BoardAcpiDxe.c
+  AcpiGnvsInit.c
+  Dsdt/DSDT.ASL
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  HobLib
+  AslUpdateLib
+  BoardAcpiTableLib
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     ## CONSUMES
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gEfiMpServiceProtocolGuid                     ## CONSUMES
+  gEfiGlobalNvsAreaProtocolGuid
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress
+
+  gBoardModuleTokenSpaceGuid.PcdAcpiSleepState
+  gBoardModuleTokenSpaceGuid.PcdAcpiHibernate
+  gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle
+  gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints
+  gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints
+  gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints
+
+[Depex]
+  gEfiAcpiTableProtocolGuid           AND
+  gEfiFirmwareVolume2ProtocolGuid     AND
+  gEfiPciRootBridgeIoProtocolGuid     AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiVariableWriteArchProtocolGuid
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
new file mode 100644
index 0000000000..dd4e41a409
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
@@ -0,0 +1,62 @@
+## @file
+# This module will perform specific PCI-Express devices
+# resource configuration.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PciHotPlug
+  FILE_GUID                      = 3022E512-B94A-4F12-806D-7EF1177899D8
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = PciHotPlug
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DevicePathLib
+  DebugLib
+  UefiLib
+  HobLib
+  PchPcieRpLib
+  ConfigBlockLib
+  TbtCommonLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PciHotPlug.c
+  PciHotPlug.h
+
+[Protocols]
+  gEfiPciHotPlugInitProtocolGuid                ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+
+[Guids]
+  gEfiHobListGuid                               ## CONSUMES
+  gPcieRpConfigGuid                  ## CONSUMES
+
+[Pcd]
+
+[Depex]
+  gDxeTbtPolicyProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
new file mode 100644
index 0000000000..5160bb1dbb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
@@ -0,0 +1,51 @@
+## @file
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtDxe
+  FILE_GUID                      = 19C9762C-3A88-41B0-906F-8C4C2895A887
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = TbtDxeEntryPoint
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  HobLib
+  UefiLib
+  TbtCommonLib
+  DxeTbtPolicyLib
+  AslUpdateLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  TbtDxe.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Depex]
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
new file mode 100644
index 0000000000..07962ffa10
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
@@ -0,0 +1,47 @@
+## @file
+# Component information file for the TBT Init PEI module.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiTbtInit
+  FILE_GUID                      = 90BF2BFB-F998-4cbc-AD72-008D4D047A4B
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = TbtInitEntryPoint
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  HobLib
+  PeiServicesLib
+  PeiTbtPolicyLib
+  PeiDTbtInitLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiTbtInit.c
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Ppis]
+  gEfiEndOfPeiSignalPpiGuid                     ## CONSUMES
+  gPeiTbtPolicyBoardInitDonePpiGuid             ## CONSUMES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
new file mode 100644
index 0000000000..3d4e6ceea0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
@@ -0,0 +1,80 @@
+## @file
+# Component information file for the ThunderBolt Smm module.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtSmm
+  FILE_GUID                      = 5BDCD685-D80A-42E6-9867-A84CCE7F828E
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  PI_SPECIFICATION_VERSION       = 1.10
+  ENTRY_POINT                    = TbtSmmEntryPoint
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  IoLib
+  PciExpressLib
+  HobLib
+  ReportStatusCodeLib
+  PciSegmentLib
+  UefiLib
+  SmmServicesTableLib
+  GpioLib
+  PchInfoLib
+  TbtCommonLib
+  PchPmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+#  gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength      ## CONSUMES
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress       ## CONSUMES
+
+[Sources]
+  TbtSmiHandler.h
+  TbtSmiHandler.c
+  TbtSmm.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gEfiSmmSxDispatch2ProtocolGuid                ## CONSUMES
+  gEfiSmmSwDispatch2ProtocolGuid                ## CONSUMES
+  gEfiSmmVariableProtocolGuid                   ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+
+[Depex]
+  gEfiSmmBase2ProtocolGuid            AND
+  gEfiSmmSxDispatch2ProtocolGuid      AND
+  gEfiSmmSwDispatch2ProtocolGuid      AND
+  gEfiGlobalNvsAreaProtocolGuid       AND
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiSmmVariableProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
new file mode 100644
index 0000000000..65c531a532
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
@@ -0,0 +1,176 @@
+## @file
+# Module Information file for the PolicyInit DXE driver.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PolicyInitDxe
+  FILE_GUID                      = 490D0119-4448-440D-8F5C-F58FB53EE057
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = PolicyInitDxeEntryPoint
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CpuPlatformLib
+  DebugLib
+  DxeServicesTableLib
+  IoLib
+  MemoryAllocationLib
+  DxeSaPolicyLib
+  DxePchPolicyLib
+  PcdLib
+  DxePolicyBoardConfigLib
+  DxePolicyUpdateLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+  ConfigBlockLib
+  DevicePathLib
+  DxeTbtPolicyLib
+  PchPcieRpLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                          ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable
+  gBoardModuleTokenSpaceGuid.PcdPlatformFlavor
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdEcPresent
+  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid
+  gBoardModuleTokenSpaceGuid.PcdTbtEnable
+  gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable                   ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication                  ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
+  gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport
+  gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport
+  gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin
+  gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature
+  gBoardModuleTokenSpaceGuid.PcdBatteryPresent
+
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support
+
+  #
+  # PSS Board Configuration.
+  #
+  gBoardModuleTokenSpaceGuid.PcdPssReadSN
+  gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber
+  gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress
+
+  gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature
+  gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile
+  gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio
+  gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdGnssResetGpio
+  gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio
+
+  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
+  gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber
+  gBoardModuleTokenSpaceGuid.PcdEcSmiGpio
+  gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio
+  gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad
+  gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck
+  gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride
+  gBoardModuleTokenSpaceGuid.PcdDDISelection
+  gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties
+  gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed
+  gPlatformModuleTokenSpaceGuid.PcdH8S2113Present
+  gPlatformModuleTokenSpaceGuid.PcdNat87393Present
+  gPlatformModuleTokenSpaceGuid.PcdNct677FPresent
+  gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport
+  gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin
+  gBoardModuleTokenSpaceGuid.PcdRealBattery1Control
+  gBoardModuleTokenSpaceGuid.PcdRealBattery2Control
+  gBoardModuleTokenSpaceGuid.PcdDimmPopulationError
+  gBoardModuleTokenSpaceGuid.PcdBtIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio
+  gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable
+  gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported
+  gBoardModuleTokenSpaceGuid.PcdMipiCamSensor
+  gBoardModuleTokenSpaceGuid.PcdH8S2113SIO
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON
+  gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable
+  gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate
+
+[Sources]
+  PolicyInitDxe.c
+  SaPolicyInitDxe.c
+  SiliconPolicyInitDxe.c
+  GopPolicyInitDxe.c
+  PchPolicyInitDxe.c
+  CpuPolicyInitDxe.c
+  BoardInitLib.c
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gDxeMePolicyGuid                              ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+  gPchPolicyProtocolGuid                        ## CONSUMES
+  gDxeSiPolicyProtocolGuid                      ## PRODUCES
+  gGopPolicyProtocolGuid                        ## PRODUCES
+  gDxeCpuPolicyProtocolGuid                     ## PRODUCES
+
+[Guids]
+  gCpuSmmGuid                                   ## CONSUMES
+  gSiMemoryInfoDataGuid
+
+[Depex]
+  gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
new file mode 100644
index 0000000000..f57bfb8c26
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
@@ -0,0 +1,130 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCI_HOT_PLUG_H_
+#define _PCI_HOT_PLUG_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <Base.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Acpi10.h>
+#include <Protocol/PciHotPlugInit.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+#include <Protocol/SaPolicy.h>
+
+#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U', 'L', 'P')
+
+#define ACPI \
+  { \
+    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 \
+  }
+
+#define PCI(device, function) \
+  { \
+    { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \
+      (UINTN) function, (UINTN) device \
+  }
+
+#define END \
+  { \
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
+  }
+
+#define LPC(eisaid, function) \
+  { \
+    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid), function \
+  }
+
+typedef struct PCIE_HOT_PLUG_DEVICE_PATH {
+  ACPI_HID_DEVICE_PATH      PciRootBridgeNode;
+  PCI_DEVICE_PATH           PciRootPortNode;
+  EFI_DEVICE_PATH_PROTOCOL  EndDeviceNode;
+} PCIE_HOT_PLUG_DEVICE_PATH;
+
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle; // Handle for protocol this driver installs on
+  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  HotPlugInitProtocol;
+} PCI_HOT_PLUG_INSTANCE;
+
+/**
+  This procedure returns a list of Root Hot Plug controllers that require
+  initialization during boot process
+
+  @param[in]  This      The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[out] HpcCount  The number of Root HPCs returned.
+  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+  @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
+  OUT UINTN                             *PhpcCount,
+  OUT EFI_HPC_LOCATION                  **PhpcList
+  );
+
+/**
+  This procedure Initializes one Root Hot Plug Controller
+  This process may casue initialization of its subordinate buses
+
+  @param[in]  This            The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[in]  HpcDevicePath   The Device Path to the HPC that is being initialized.
+  @param[in]  HpcPciAddress   The address of the Hot Plug Controller function on the PCI bus.
+  @param[in]  Event           The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+  @param[out] HpcState        The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+  @retval   EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
+  IN  UINT64                          PhpcPciAddress,
+  IN  EFI_EVENT                       Event, OPTIONAL
+  OUT EFI_HPC_STATE                   *PhpcState
+  );
+
+/**
+  Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+  @param[in]  This           The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
+  @param[in]  HpcPciAddress  The address of the Hot Plug Controller function on the PCI bus.
+  @param[out] HpcState       The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+  @param[out] Padding        This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+  @param[out] Attribute      Describes how padding is accounted for.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
+  IN  UINT64                          PhpcPciAddress,
+  OUT EFI_HPC_STATE                   *PhpcState,
+  OUT VOID                            **Padding,
+  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
new file mode 100644
index 0000000000..b91b0f14bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
@@ -0,0 +1,180 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_SMI_HANDLER_H_
+#define _TBT_SMI_HANDLER_H_
+
+#include <Library/TbtCommonLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/Pci.h>
+
+#ifdef PROGRESS_CODE
+#undef PROGRESS_CODE
+#endif
+
+#define MAX_TBT_DEPTH         6
+
+#define P2P_BRIDGE            (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define BAR_ALIGN(v, a)       ((((v) - 1) | (a)) + 1)
+
+#define CMD_BUS_MASTER        BIT2
+#define CMD_BM_IO             (CMD_BUS_MASTER | BIT0)
+#define CMD_BM_MEM            (CMD_BUS_MASTER | BIT1)
+#define CMD_BM_MEM_IO         (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DEF_CACHE_LINE_SIZE   0x20
+#define DEF_RES_IO_PER_DEV    4
+#define DEF_RES_MEM_PER_DEV   32
+#define DEF_RES_PMEM_PER_DEV  32
+
+#define DOCK_BUSSES           8
+
+#define DISBL_IO_REG1C        0x01F1
+#define DISBL_MEM32_REG20     0x0000FFF0
+#define DISBL_PMEM_REG24      0x0001FFF1
+
+#define count(x)              (sizeof (x) / sizeof ((x)[0]))
+
+#define PCIE_CAP_ID_SSID_SSVID 0x0D
+#define INVALID_PCI_DEVICE    0xFFFFFFFF
+#define PCI_TBT_VESC_REG2     0x510
+
+typedef struct _PortInfo {
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+  UINT8   BusNumLimit;
+  UINT8   ConfedEP;
+} PORT_INFO;
+
+typedef struct _MEM_REGS {
+  UINT32  Base;
+  UINT32  Limit;
+} MEM_REGS;
+
+typedef struct _PMEM_REGS {
+  UINT64  Base64;
+  UINT64  Limit64;
+} PMEM_REGS;
+
+typedef struct _IO_REGS {
+  UINT16  Base;
+  UINT16  Limit;
+} IO_REGS;
+
+typedef struct _BRDG_RES_CONFIG {
+  UINT8   Cmd;
+  UINT8   Cls;
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+} BRDG_RES_CONFIG;
+
+typedef struct _BRDG_CONFIG {
+  DEV_ID          DevId;
+  UINT8           PBus;
+  UINT8           SBus;
+  UINT8           SubBus;
+  BOOLEAN         IsDSBridge;
+  BRDG_RES_CONFIG Res;
+} BRDG_CONFIG;
+
+enum {
+  HR_US_PORT,
+  HR_DS_PORT0,
+  HR_DS_PORT3,
+  HR_DS_PORT4,
+  HR_DS_PORT5,
+  HR_DS_PORT6,
+  MAX_CFG_PORTS
+};
+
+enum {
+  HR_DS_PORT1   = HR_DS_PORT3
+};
+
+//
+// Alpine Ridge
+//
+enum {
+  AR_DS_PORT1 = HR_DS_PORT3,
+  AR_DS_PORT2,
+  AR_DS_PORT3,
+  AR_DS_PORT4
+};
+
+typedef struct _HR_CONFIG {
+  UINT16  DeviceId;
+  UINT8   HRBus;
+  UINT8   MinDSNumber;
+  UINT8   MaxDSNumber;
+  UINT8   BridgeLoops;
+} HR_CONFIG;
+
+STATIC const BRDG_RES_CONFIG  NOT_IN_USE_BRIDGE = {
+  CMD_BUS_MASTER,
+  0,
+  DISBL_IO_REG1C & 0xFF,
+  DISBL_IO_REG1C >> 8,
+  DISBL_MEM32_REG20 & 0xFFFF,
+  DISBL_MEM32_REG20 >> 16,
+  DISBL_PMEM_REG24 & 0xFFFF,
+  DISBL_PMEM_REG24 >> 16
+};
+
+typedef union _BRDG_CIO_MAP_REG {
+  UINT32  AB_REG;
+  struct {
+    UINT32  NumOfDSPorts : 5;
+    UINT32  CioPortMap : 27;
+  } Bits;
+} BRDG_CIO_MAP_REG;
+
+//
+// Functions
+//
+VOID
+ThunderboltCallback (
+  IN UINT8 Type
+  );
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+  IN UINT8 Type
+  );
+
+VOID
+EndOfThunderboltCallback(
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+);
+
+VOID
+ConfigureTbtAspm(
+  IN UINT8       Type,
+  IN UINT16      Aspm
+);
+
+UINT8
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
new file mode 100644
index 0000000000..ac13acc27d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
@@ -0,0 +1,32 @@
+/** @file
+ Header file for board Init function for DXE Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_BOARD_INIT_LIB_H_
+#define _DXE_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+#include <Register/PchRegs.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Platform.h>
+
+EFI_STATUS
+EFIAPI
+BoardConfigInit (
+   VOID
+  );
+
+#endif // _DXE_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
new file mode 100644
index 0000000000..5d0e2777d8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_INIT_DXE_H_
+#define _CPU_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+#include <Protocol/CpuPolicyProtocol.h>
+#include <Library/DxeCpuPolicyUpdateLib.h>
+
+
+/**
+  Initialize Intel CPU DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @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
+CpuPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
new file mode 100644
index 0000000000..ff975efae0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
@@ -0,0 +1,41 @@
+/** @file
+Header file for the GopPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GOP_POLICY_INIT_DXE_H_
+#define _GOP_POLICY_INIT_DXE_H_
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+#include <Library/PcdLib.h>
+
+/**
+Initialize GOP DXE Policy
+
+@param[in] ImageHandle          Image handle of this driver.
+
+@retval EFI_SUCCESS             Initialization complete.
+@retval 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
+GopPolicyInitDxe(
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
new file mode 100644
index 0000000000..1055fed7c8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
@@ -0,0 +1,52 @@
+/** @file
+  Header file for the PchPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_POLICY_INIT_DXE_H_
+#define _PCH_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <FirwmareConfigurations.h>
+#include <Protocol/PchPolicy.h>
+#include <Library/DxePchPolicyLib.h>
+#include <Library/DxePchPolicyUpdateLib.h>
+
+extern UINT8 mFirmwareConfiguration;
+
+/**
+  <b>PCH DXE Policy Driver Entry Point</b> \n
+  - <b>Introduction</b> \n
+    Pch DXE drivers behavior can be controlled by platform policy without modifying reference code directly.
+    Platform policy Protocol is initialized with default settings in this funciton.
+    This policy Protocol has to be initialized prior to PCH initialization DXE drivers execution.
+
+  - @pre
+    - Runtime variable service should be ready if policy initialization required.
+
+  - @result
+    PCH_POLICY_PROTOCOL will be installed successfully and ready for Pch reference code use.
+
+  - <b>Porting Recommendations</b> \n
+    Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+  @param[in] ImageHandle - Image handle of this driver.
+
+  @retval EFI_SUCCESS           Initialization complete.
+  @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
+PchPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
new file mode 100644
index 0000000000..d2aac9823e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
@@ -0,0 +1,45 @@
+/** @file
+  Header file for the PolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POLICY_INIT_DXE_H_
+#define _POLICY_INIT_DXE_H_
+
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include "SaPolicyInitDxe.h"
+#include "PchPolicyInitDxe.h"
+#include "SiliconPolicyInitDxe.h"
+#include "GopPolicyInitDxe.h"
+#include "CpuPolicyInitDxe.h"
+
+#include <Library/DxeTbtPolicyLib.h>
+/**
+  Initialize DXE Platform Policy
+
+  @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
+PolicyInitDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
new file mode 100644
index 0000000000..0f86711e6a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
@@ -0,0 +1,56 @@
+/** @file
+  Header file for the SaPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_INIT_DXE_H_
+#define _SA_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <FirwmareConfigurations.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/DxeSaPolicyLib.h>
+#include <Library/DxePolicyBoardConfigLib.h>
+#include <Library/DxeSaPolicyUpdateLib.h>
+
+#include <SaAccess.h>
+
+extern UINT8 mFirmwareConfiguration;
+
+/**
+  <b>SA DXE Policy Driver Entry Point</b> \n
+  - <b>Introduction</b> \n
+    System Agent DXE drivers behavior can be controlled by platform policy without modifying reference code directly.
+    Platform policy Protocol is initialized with default settings in this funciton.
+    This policy Protocol has to be initialized prior to System Agent initialization DXE drivers execution.
+
+  - @pre
+    - Runtime variable service should be ready if policy initialization required.
+
+  - @result
+    SA_POLICY_PROTOCOL will be installed successfully and ready for System Agent reference code use.
+
+  - <b>Porting Recommendations</b> \n
+    Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+  @param[in] ImageHandle - Image handle of this driver.
+
+  @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
+SaPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
new file mode 100644
index 0000000000..a2c5f548fa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SILICON_POLICY_INIT_DXE_H_
+#define _SILICON_POLICY_INIT_DXE_H_
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Protocol/SiPolicyProtocol.h>
+
+/**
+  Initilize Intel CPU DXE Policy
+
+  @param[in] ImageHandle             Image handle of this driver.
+
+  @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
+SiliconPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
new file mode 100644
index 0000000000..1ff129c307
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
@@ -0,0 +1,96 @@
+/** @file
+  Acpi Gnvs Init Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <PchAccess.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/MpService.h>
+
+/**
+@brief
+  Global NVS initialize.
+
+  @param[in] GlobalNvs         - Pointer of Global NVS area
+
+  @retval EFI_SUCCESS          - Allocate Global NVS completed.
+  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGnvsInit (
+  IN OUT VOID                   **GlobalNvs
+  )
+{
+  UINTN                         Pages;
+  EFI_PHYSICAL_ADDRESS          Address;
+  EFI_STATUS                    Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GNVS;
+  EFI_MP_SERVICES_PROTOCOL      *MpService;
+  UINTN                         NumberOfCPUs;
+  UINTN                         NumberOfEnabledCPUs;
+
+  Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
+  Address = 0xffffffff; // allocate address below 4G.
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Locate the MP services protocol
+  // Find the MP Protocol. This is an MP platform, so MP protocol must be there.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiMpServiceProtocolGuid,
+                  NULL,
+                  (VOID **) &MpService
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Determine the number of processors
+  //
+  MpService->GetNumberOfProcessors (
+              MpService,
+              &NumberOfCPUs,
+              &NumberOfEnabledCPUs
+              );
+
+  *GlobalNvs = (VOID *) (UINTN) Address;
+  SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
+
+  //
+  // GNVS default value init here...
+  //
+  GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
+
+  GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
+
+  //
+  // Miscellaneous
+  //
+  GNVS->Area->PL1LimitCS = 0;
+  GNVS->Area->PL1LimitCSValue = 4500;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
new file mode 100644
index 0000000000..cb5f328a39
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
@@ -0,0 +1,290 @@
+/** @file
+  ACPI Platform Driver
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/AcpiTable.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL              mGlobalNvsArea;
+
+/**
+@brief
+  Global NVS initialize.
+
+  @param[in] GlobalNvs         - Pointer of Global NVS area
+
+  @retval EFI_SUCCESS          - Allocate Global NVS completed.
+  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGnvsInit (
+  IN OUT VOID                   **GlobalNvs
+  );
+
+//
+// Function implementations
+//
+
+/**
+  Locate the first instance of a protocol.  If the protocol requested is an
+  FV protocol, then it will return the first FV that contains the ACPI table
+  storage file.
+
+  @param[in] Protocol           The protocol to find.
+  @param[in] Instance           Return pointer to the first instance of the protocol.
+  @param[in] Type               TRUE if the desired protocol is a FV protocol.
+
+  @retval EFI_SUCCESS           The function completed successfully.
+  @retval EFI_NOT_FOUND         The protocol could not be located.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
+**/
+EFI_STATUS
+LocateSupportProtocol (
+  IN     EFI_GUID                      *Protocol,
+  IN     EFI_GUID                      *gEfiAcpiMultiTableStorageGuid,
+     OUT VOID                          **Instance,
+  IN     BOOLEAN                       Type
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *HandleBuffer;
+  UINTN                   NumberOfHandles;
+  EFI_FV_FILETYPE         FileType;
+  UINT32                  FvStatus;
+  EFI_FV_FILE_ATTRIBUTES  Attributes;
+  UINTN                   Size;
+  UINTN                   Index;
+
+  //
+  // Locate protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  Protocol,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // Defined errors at this time are not found and out of resources.
+    //
+    return Status;
+  }
+
+  //
+  // Looking 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],
+                    Protocol,
+                    Instance
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    if (!Type) {
+
+      //
+      // Not looking for the FV protocol, so find the first instance of the
+      // protocol.  There should not be any errors because our handle buffer
+      // should always contain at least one or LocateHandleBuffer would have
+      // returned not found.
+      //
+      break;
+    }
+    //
+    // See if it has the ACPI storage file
+    //
+    Size      = 0;
+    FvStatus  = 0;
+    Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile (
+                                                              *Instance,
+                                                              gEfiAcpiMultiTableStorageGuid,
+                                                              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);
+
+  return Status;
+}
+
+EFI_STATUS
+PublishAcpiTablesFromFv (
+  IN EFI_GUID *gEfiAcpiMultiTableStorageGuid
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+  UINTN                         TableHandle;
+  INTN                          Instance;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+
+  Instance      = 0;
+  TableHandle   = 0;
+  CurrentTable  = NULL;
+  FwVol         = NULL;
+
+  //
+  // Find the AcpiSupport protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiMultiTableStorageGuid,
+            (VOID **) &AcpiTable,
+            FALSE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiAcpiMultiTableStorageGuid,
+            (VOID **) &FwVol,
+            TRUE
+            );
+
+  //
+  // Read tables from the storage file.
+  //
+
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      gEfiAcpiMultiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // Add the table
+      //
+      TableHandle = 0;
+
+      Status = AcpiTable->InstallAcpiTable (
+                            AcpiTable,
+                            CurrentTable,
+                            CurrentTable->Length,
+                            &TableHandle
+                            );
+
+
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Increment the instance
+      //
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  //
+  // Finished
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+  ACPI Platform driver installation function.
+
+  @param[in] ImageHandle     Handle for this drivers loaded image protocol.
+  @param[in] SystemTable     EFI system table.
+
+  @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
+EFIAPI
+InstallAcpiBoard (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS   Status;
+  EFI_HANDLE   Handle;
+
+  AcpiGnvsInit((VOID **) &mGlobalNvsArea.Area);
+
+  //
+  // This PCD set must be done before PublishAcpiTablesFromFv.
+  // The PCD data will be used there.
+  //
+  PcdSet64S (PcdAcpiGnvsAddress, (UINT64)(UINTN)mGlobalNvsArea.Area);
+
+  //
+  // Platform ACPI Tables
+  //
+  PublishAcpiTablesFromFv (&gEfiCallerIdGuid);
+
+  //
+  // This protocol publish must be done after PublishAcpiTablesFromFv.
+  // The NVS data is be updated there.
+  //
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  &mGlobalNvsArea,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
new file mode 100644
index 0000000000..2b36475c53
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
@@ -0,0 +1,353 @@
+/** @file
+  Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
+  Devics resource configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "PciHotPlug.h"
+#include <Ppi/SiPolicy.h>
+#include <TbtBoardInfo.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+
+#define PCIE_NUM  (20)
+#define PEG_NUM   (3)
+#define PADDING_BUS (1)
+#define PADDING_NONPREFETCH_MEM (1)
+#define PADDING_PREFETCH_MEM (1)
+#define PADDING_IO (1)
+#define PADDING_NUM (PADDING_BUS + PADDING_NONPREFETCH_MEM + PADDING_PREFETCH_MEM + PADDING_IO)
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HPC_LOCATION          mPcieLocation[PCIE_NUM + PEG_NUM];
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mHpcCount = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_HOT_PLUG_DEVICE_PATH mHotplugPcieDevicePathTemplate = {
+  ACPI,
+  PCI(0xFF, 0xFF), // Dummy Device no & Function no
+  END
+};
+
+/**
+  Entry point for the driver.
+
+  This routine reads the PlatformType GPI on FWH and produces a protocol
+  to be consumed by the chipset driver to effect those settings.
+
+  @param[in]  ImageHandle    An image handle.
+  @param[in]  SystemTable    A pointer to the system table.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+PciHotPlug (
+  IN EFI_HANDLE                   ImageHandle,
+  IN EFI_SYSTEM_TABLE             *SystemTable
+  )
+{
+  EFI_STATUS                       Status;
+  PCI_HOT_PLUG_INSTANCE            *PciHotPlug;
+  UINTN                            Index;
+  UINTN                            RpDev;
+  UINTN                            RpFunc;
+  PCIE_HOT_PLUG_DEVICE_PATH       *HotplugPcieDevicePath;
+  UINT32                           PcieRootPortHpeData = 0;
+
+  DEBUG ((DEBUG_INFO, "PciHotPlug Entry\n"));
+
+  PcieRootPortHpeData = PcdGet32 (PcdPchPcieRootPortHpe);
+  //
+  // PCH Rootports Hotplug device path creation
+  //
+  for (Index = 0; Index < PCIE_NUM; Index++) {
+    if (((PcieRootPortHpeData >> Index) & BIT0) == BIT0) { // Check the Rootport no's hotplug is set
+      Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFunc); // Get the actual device/function no corresponding to the Rootport no provided
+      ASSERT_EFI_ERROR (Status);
+
+      HotplugPcieDevicePath = NULL;
+      HotplugPcieDevicePath = AllocatePool (sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
+      ASSERT (HotplugPcieDevicePath != NULL);
+      if (HotplugPcieDevicePath == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      CopyMem (HotplugPcieDevicePath, &mHotplugPcieDevicePathTemplate, sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
+      HotplugPcieDevicePath->PciRootPortNode.Device = (UINT8) RpDev; // Update real Device no
+      HotplugPcieDevicePath->PciRootPortNode.Function = (UINT8) RpFunc; // Update real Function no
+
+      mPcieLocation[mHpcCount].HpcDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
+      mPcieLocation[mHpcCount].HpbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
+      mHpcCount++;
+
+      DEBUG ((DEBUG_INFO, "(%02d) PciHotPlug (PCH RP#) : Bus 0x00, Device 0x%x, Function 0x%x is added to the Hotplug Device Path list \n", mHpcCount, RpDev, RpFunc));
+    }
+  }
+
+
+  PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE));
+  ASSERT (PciHotPlug != NULL);
+  if (PciHotPlug == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize driver private data.
+  //
+  ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE));
+
+  PciHotPlug->Signature                               = PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE;
+  PciHotPlug->HotPlugInitProtocol.GetRootHpcList      = GetRootHpcList;
+  PciHotPlug->HotPlugInitProtocol.InitializeRootHpc   = InitializeRootHpc;
+  PciHotPlug->HotPlugInitProtocol.GetResourcePadding  = GetResourcePadding;
+
+  Status = gBS->InstallProtocolInterface (
+                  &PciHotPlug->Handle,
+                  &gEfiPciHotPlugInitProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &PciHotPlug->HotPlugInitProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure returns a list of Root Hot Plug controllers that require
+  initialization during boot process
+
+  @param[in]  This      The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[out] HpcCount  The number of Root HPCs returned.
+  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+  @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
+  OUT UINTN                            *HpcCount,
+  OUT EFI_HPC_LOCATION                 **HpcList
+  )
+{
+  *HpcCount = mHpcCount;
+  *HpcList  = mPcieLocation;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure Initializes one Root Hot Plug Controller
+  This process may casue initialization of its subordinate buses
+
+  @param[in]  This            The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[in]  HpcDevicePath   The Device Path to the HPC that is being initialized.
+  @param[in]  HpcPciAddress   The address of the Hot Plug Controller function on the PCI bus.
+  @param[in]  Event           The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+  @param[out] HpcState        The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+  @retval   EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL      *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL            *HpcDevicePath,
+  IN  UINT64                              HpcPciAddress,
+  IN  EFI_EVENT                           Event, OPTIONAL
+  OUT EFI_HPC_STATE                       *HpcState
+  )
+{
+  if (Event) {
+    gBS->SignalEvent (Event);
+  }
+
+  *HpcState = EFI_HPC_STATE_INITIALIZED;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+  @param[in]  This           The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
+  @param[in]  HpcPciAddress  The address of the Hot Plug Controller function on the PCI bus.
+  @param[out] HpcState       The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+  @param[out] Padding        This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+  @param[out] Attribute      Describes how padding is accounted for.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *HpcDevicePath,
+  IN  UINT64                          HpcPciAddress,
+  OUT EFI_HPC_STATE                   *HpcState,
+  OUT VOID                            **Padding,
+  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
+  EFI_STATUS                        Status;
+  UINT8                             RsvdExtraBusNum = 0;
+  UINT16                            RsvdPcieMegaMem = 10;
+  UINT8                             PcieMemAddrRngMax = 0;
+  UINT16                            RsvdPciePMegaMem = 10;
+  UINT8                             PciePMemAddrRngMax = 0;
+  UINT8                             RsvdTbtExtraBusNum = 0;
+  UINT16                            RsvdTbtPcieMegaMem = 10;
+  UINT8                             TbtPcieMemAddrRngMax = 0;
+  UINT16                            RsvdTbtPciePMegaMem = 10;
+  UINT8                             TbtPciePMemAddrRngMax = 0;
+  UINT8                             RsvdPcieKiloIo = 4;
+  BOOLEAN                           SetResourceforTbt = FALSE;
+  UINTN                             RpIndex;
+  UINTN                             RpDev;
+  UINTN                             RpFunc;
+
+DEBUG ((DEBUG_INFO, "GetResourcePadding : Start \n"));
+
+  PaddingResource = AllocatePool (PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  ASSERT (PaddingResource != NULL);
+  if (PaddingResource == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *Padding = (VOID *) PaddingResource;
+
+  RpDev = (UINTN) ((HpcPciAddress >> 16) & 0xFF);
+  RpFunc = (UINTN) ((HpcPciAddress >> 8) & 0xFF);
+
+  // Get the actual Rootport no corresponding to the device/function no provided
+  if (RpDev == SA_PEG_DEV_NUM) {
+    // PEG
+    RpIndex = PCIE_NUM + RpFunc;
+    DEBUG ((DEBUG_INFO, "GetResourcePadding : PEG Rootport no %02d Bus 0x00, Device 0x%x, Function 0x%x \n", (RpIndex-PCIE_NUM), RpDev, RpFunc));
+  } else {
+    // PCH
+    Status = GetPchPcieRpNumber (RpDev, RpFunc, &RpIndex);
+    DEBUG ((DEBUG_INFO, "GetResourcePadding : PCH Rootport no %02d Bus 0x00, Device 0x%x, Function 0x%x \n", RpIndex, RpDev, RpFunc));
+  }
+
+  GetRootporttoSetResourcesforTbt(RpIndex, &RsvdTbtExtraBusNum, &RsvdTbtPcieMegaMem ,&TbtPcieMemAddrRngMax ,&RsvdTbtPciePMegaMem ,&TbtPciePMemAddrRngMax, &SetResourceforTbt);
+    if (SetResourceforTbt) {
+      RsvdExtraBusNum = RsvdTbtExtraBusNum;
+      RsvdPcieMegaMem = RsvdTbtPcieMegaMem;
+      PcieMemAddrRngMax = TbtPcieMemAddrRngMax;
+      RsvdPciePMegaMem = RsvdTbtPciePMegaMem;
+      PciePMemAddrRngMax = TbtPciePMemAddrRngMax;
+    }
+
+  //
+  // Padding for bus
+  //
+  ZeroMem (PaddingResource, PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  *Attributes                   = EfiPaddingPciBus;
+
+  PaddingResource->Desc         = 0x8A;
+  PaddingResource->Len          = 0x2B;
+  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_BUS;
+  PaddingResource->GenFlag      = 0x0;
+  PaddingResource->SpecificFlag = 0;
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrRangeMax = 0;
+  PaddingResource->AddrLen      = RsvdExtraBusNum;
+
+  //
+  // Padding for non-prefetchable memory
+  //
+  PaddingResource++;
+  PaddingResource->Desc                 = 0x8A;
+  PaddingResource->Len                  = 0x2B;
+  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+  PaddingResource->GenFlag              = 0x0;
+    if (SetResourceforTbt) {
+    PaddingResource->AddrSpaceGranularity = 32;
+  } else {
+    PaddingResource->AddrSpaceGranularity = 32;
+  }
+  PaddingResource->SpecificFlag         = 0;
+  //
+  // Pad non-prefetchable
+  //
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
+  if (SetResourceforTbt) {
+    PaddingResource->AddrRangeMax = (1 << PcieMemAddrRngMax) - 1;
+  } else {
+    PaddingResource->AddrRangeMax = 1;
+  }
+
+  //
+  // Padding for prefetchable memory
+  //
+  PaddingResource++;
+  PaddingResource->Desc                 = 0x8A;
+  PaddingResource->Len                  = 0x2B;
+  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+  PaddingResource->GenFlag              = 0x0;
+    if (SetResourceforTbt) {
+    PaddingResource->AddrSpaceGranularity = 32;
+  } else {
+    PaddingResource->AddrSpaceGranularity = 32;
+  }
+  PaddingResource->SpecificFlag         = 06;
+  //
+  // Padding for prefetchable memory
+  //
+  PaddingResource->AddrRangeMin = 0;
+  if (SetResourceforTbt) {
+    PaddingResource->AddrLen      = RsvdPciePMegaMem * 0x100000;
+  } else {
+    PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
+  }
+  //
+  // Pad 16 MB of MEM
+  //
+  if (SetResourceforTbt) {
+    PaddingResource->AddrRangeMax = (1 << PciePMemAddrRngMax) - 1;
+  } else {
+    PaddingResource->AddrRangeMax = 1;
+  }
+  //
+  // Alignment
+  //
+  // Padding for I/O
+  //
+  PaddingResource++;
+  PaddingResource->Desc         = 0x8A;
+  PaddingResource->Len          = 0x2B;
+  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_IO;
+  PaddingResource->GenFlag      = 0x0;
+  PaddingResource->SpecificFlag = 0;
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrLen      = RsvdPcieKiloIo * 0x400;
+  //
+  // Pad 4K of IO
+  //
+  PaddingResource->AddrRangeMax = 1;
+  //
+  // Alignment
+  //
+  // Terminate the entries.
+  //
+  PaddingResource++;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc     = ACPI_END_TAG_DESCRIPTOR;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0;
+
+  *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
new file mode 100644
index 0000000000..c670f23320
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
@@ -0,0 +1,228 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/DxeTbtPolicyLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Protocol/TbtNvsArea.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/PcdLib.h>
+#include <Library/AslUpdateLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL                     mTbtNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB                              *gTbtInfoHob = NULL;
+
+/**
+  TBT NVS Area Initialize
+
+**/
+
+VOID
+TbtNvsAreaInit (
+  IN  VOID              **mTbtNvsAreaPtr
+  )
+{
+  UINTN                         Pages;
+  EFI_PHYSICAL_ADDRESS          Address;
+  EFI_STATUS                    Status;
+  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
+  DXE_TBT_POLICY_PROTOCOL       *DxeTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit Start\n"));
+  Status = gBS->LocateProtocol (
+              &gDxeTbtPolicyProtocolGuid,
+              NULL,
+              (VOID **) &DxeTbtConfig
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  Pages = EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA));
+  Address = 0xffffffff; // allocate address below 4G.
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  ASSERT_EFI_ERROR (Status);
+
+  *mTbtNvsAreaPtr = (VOID *) (UINTN) Address;
+  SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0);
+
+  //
+  // TBTNvsAreaProtocol default value init here
+  //
+  TbtNvsAreaProtocol = (TBT_NVS_AREA_PROTOCOL *) &Address;
+
+  //
+  // Initialize default values
+  //
+  TbtNvsAreaProtocol->Area->WAKFinished             = 0;
+  TbtNvsAreaProtocol->Area->DiscreteTbtSupport      = ((gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1 ) ? TRUE : FALSE);
+  TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport   = 0;
+  TbtNvsAreaProtocol->Area->TbtGpioFilter           = (UINT8) DxeTbtConfig->TbtCommonConfig.Gpio5Filter;
+//  TbtNvsAreaProtocol->Area->TrOsup                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TrA0OsupWa;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrEn             = gTbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr;
+  TbtNvsAreaProtocol->Area->TbtAspm                 = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAspm;
+//  TbtNvsAreaProtocol->Area->TbtL1SubStates          = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtL1SubStates;
+  TbtNvsAreaProtocol->Area->TbtSetClkReq            = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtSetClkReq;
+  TbtNvsAreaProtocol->Area->TbtLtr                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtLtr;
+//  TbtNvsAreaProtocol->Area->TbtPtm                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtPtm;
+  TbtNvsAreaProtocol->Area->TbtWakeupSupport        = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport;
+  TbtNvsAreaProtocol->Area->TbtAcDcSwitch           = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch;
+  TbtNvsAreaProtocol->Area->Rtd3TbtSupport          = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3Tbt;             // TBT RTD3 Enable.
+  TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay         = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay;    // TBT RTD3 Off delay in ms.
+  TbtNvsAreaProtocol->Area->Rtd3TbtClkReq           = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq;       // TBT RTD3 ClkReq Mask Enable.
+  TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay      = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq mask delay in ms.
+  TbtNvsAreaProtocol->Area->TbtWin10Support         = (UINT8) DxeTbtConfig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode
+
+  //
+  // DTBT Controller 1
+  //
+  TbtNvsAreaProtocol->Area->DTbtControllerEn0       = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+  TbtNvsAreaProtocol->Area->RootportSelected0       = gTbtInfoHob-> DTbtControllerConfig.PcieRpNumber;
+  TbtNvsAreaProtocol->Area->RootportSelected0Type   = gTbtInfoHob-> DTbtControllerConfig.Type;
+  TbtNvsAreaProtocol->Area->RootportEnabled0        = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0        = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0     = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+  TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0  = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0       = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0    = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+  TbtNvsAreaProtocol->Area->TBtCommonGpioSupport    = gTbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+
+  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit End\n"));
+}
+
+/**
+  This function gets registered as a callback to patch TBT ASL code
+
+  @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.
+  can we put this also in read me
+**/
+VOID
+EFIAPI
+TbtAcpiEndOfDxeCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Address;
+  UINT16                                Length;
+  UINT32                                Signature;
+
+  Status = InitializeAslUpdateLib ();
+  ASSERT_EFI_ERROR (Status);
+
+  Address = (UINT32) (UINTN) mTbtNvsAreaProtocol.Area;
+  Length  = (UINT16) sizeof (TBT_NVS_AREA);
+  DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x Length %x\n", Address, Length));
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address, sizeof (Address));
+  ASSERT_EFI_ERROR (Status);
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length, sizeof (Length));
+  ASSERT_EFI_ERROR (Status);
+
+  if (gTbtInfoHob != NULL) {
+    if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1) {
+      if (gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting == TRUE) {
+        DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n"));
+        Signature = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+        Status  = UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'), &Signature, sizeof (Signature));
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+
+  return;
+}
+
+/**
+  Initialize Thunderbolt(TM) SSDT ACPI tables
+
+  @retval EFI_SUCCESS    ACPI tables are initialized successfully
+  @retval EFI_NOT_FOUND  ACPI tables not found
+**/
+
+EFI_STATUS
+EFIAPI
+TbtDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              Handle;
+ // EFI_EVENT               EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "TbtDxeEntryPoint \n"));
+
+  //
+  // Get TBT INFO HOB
+  //
+  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+  if (gTbtInfoHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  InstallTbtPolicy (ImageHandle);
+  //
+  // Update DXE TBT Policy
+  //
+  UpdateTbtPolicyCallback ();
+
+  //
+  // Print DXE TBT Policy
+  //
+  TbtPrintDxePolicyConfig ();
+
+  //
+  // Initialize Tbt Nvs Area
+  //
+  TbtNvsAreaInit ((VOID **) &mTbtNvsAreaProtocol.Area);
+
+
+  //
+  // [ACPI] Thunderbolt ACPI table
+  //
+
+
+  Handle = NULL;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gTbtNvsAreaProtocolGuid,
+                  &mTbtNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register an end of DXE event for TBT ACPI to do some patch can be put as description
+  //
+  /**
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  TbtAcpiEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+**/
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
new file mode 100644
index 0000000000..bdd8de0cfd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
@@ -0,0 +1,211 @@
+/** @file
+  Source code file for TBT Init PEI module
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <TbtBoardInfo.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+/*
+/**
+  This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDone
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+
+/**
+  This function pass PEI TBT Policy to Hob at the end of PEI
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+
+EFI_STATUS
+EFIAPI
+PassTbtPolicyToHob (
+VOID
+  )
+{
+  EFI_STATUS            Status;
+  EFI_BOOT_MODE         BootMode;
+  TBT_INFO_HOB          *TbtInfoHob;
+  PEI_TBT_POLICY        *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "PassTbtPolicyToHob\n"));
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+  if (BootMode == BOOT_ON_S3_RESUME ) {
+    return EFI_SUCCESS;
+  }
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Create HOB for TBT Data
+  //
+  Status = PeiServicesCreateHob (
+             EFI_HOB_TYPE_GUID_EXTENSION,
+             sizeof (TBT_INFO_HOB),
+             (VOID **) &TbtInfoHob
+             );
+  DEBUG ((DEBUG_INFO, "TbtInfoHob Created \n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize the TBT INFO HOB data.
+  //
+  TbtInfoHob->EfiHobGuidType.Name = gTbtInfoHobGuid;
+
+  //
+  // Update DTBT Policy
+  //
+  TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn = PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn;
+  TbtInfoHob-> DTbtControllerConfig.Type = PeiTbtConfig-> DTbtControllerConfig.Type;
+  TbtInfoHob-> DTbtControllerConfig.PcieRpNumber = PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber;
+  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting;
+  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+  TbtInfoHob->DTbtCommonConfig.TbtBootOn = PeiTbtConfig->DTbtCommonConfig.TbtBootOn;
+  TbtInfoHob->DTbtCommonConfig.TbtUsbOn = PeiTbtConfig->DTbtCommonConfig.TbtUsbOn;
+  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr;
+  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly;
+  TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration = PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+  TbtInfoHob->DTbtCommonConfig.PcieRstSupport = PeiTbtConfig->DTbtCommonConfig.PcieRstSupport;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function handles TbtInit task at the end of PEI
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+EFI_STATUS
+EFIAPI
+TbtInitEndOfPei (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  BOOLEAN         DTbtExisted;
+  PEI_TBT_POLICY  *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtInitEndOfPei Entry\n"));
+
+  Status       = EFI_SUCCESS;
+  PeiTbtConfig = NULL;
+  DTbtExisted  = FALSE;
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+    if (PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn == 1) {
+      DTbtExisted = TRUE;
+  }
+
+  if (DTbtExisted == TRUE) {
+    //
+    // Call Init function
+    //
+   Status = TbtInit ();
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  TBT Init PEI module entry point
+
+  @param[in]  FileHandle           Not used.
+  @param[in]  PeiServices          General purpose services available to every PEIM.
+
+  @retval     EFI_SUCCESS          The function completes successfully
+  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+EFIAPI
+TbtInitEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS     Status;
+
+  DEBUG ((DEBUG_INFO, "TBT PEI EntryPoint\n"));
+
+  //
+  // Install PEI TBT Policy
+  //
+  Status = InstallPeiTbtPolicy ();
+  ASSERT_EFI_ERROR (Status);
+
+
+  UpdatePeiTbtPolicy ();
+
+  TbtPrintPeiPolicyConfig ();
+  //
+  // Performing PassTbtPolicyToHob and TbtInitEndOfPei
+  //
+  Status = PassTbtPolicyToHob ();
+
+  Status = TbtInitEndOfPei ();
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
new file mode 100644
index 0000000000..a6bdc6ef9f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
@@ -0,0 +1,1609 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "TbtSmiHandler.h"
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SmmVariable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/PciSegmentLib.h>
+#define MEM_PER_SLOT  (DEF_RES_MEM_PER_DEV << 4)
+#define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
+#define IO_PER_SLOT   (DEF_RES_IO_PER_DEV << 2)
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN                 gDeviceBaseAddress;
+//
+//US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG           HrConfigs[MAX_CFG_PORTS];
+
+extern UINT8                      gCurrentDiscreteTbtRootPort;
+extern UINT8                      gCurrentDiscreteTbtRootPortType;
+
+BOOLEAN isLegacyDevice          = FALSE;
+STATIC UINT8 TbtSegment         = 0;
+
+STATIC
+VOID
+PortInfoInit (
+  IN  OUT PORT_INFO *PortInfo
+  )
+{
+  PortInfo->BusNumLimit = 4;
+}
+
+STATIC
+VOID
+UnsetVesc (
+  IN       UINT8     Bus,
+  IN       UINT8     Dev,
+  IN       UINT8     Fun
+  )
+{
+  UINT8 Dbus;
+  UINT32 Data32;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+
+  //
+  // Check for abcence of DS bridge
+  //
+  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+    return;
+  }
+
+  //
+  // Unset vesc_reg2[23] bit (to have an option to access below DS)
+  //
+  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+  Data32 &= 0xFF7FFFFF;
+  PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+  //
+  // Go to Device behind DS
+  //
+  Dbus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
+  //
+  // Check if there is something behind this Downstream Port (Up or Ep)
+  // If there nothing  behind Downstream Port Set vesc_reg2[23] bit -> this will flush all future MemWr
+  //
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus, 0x00, 0x00, 0);
+  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET))
+  {
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+  Data32 |= 0x00800000;
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+  }
+}// Unset_VESC_REG2
+
+STATIC
+UINT16
+MemPerSlot (
+  IN    UINT16 CurrentUsage
+  )
+{
+  if (CurrentUsage == 0) {
+    return 0;
+  }
+
+  if (CurrentUsage <= 16) {
+    return 16;
+  }
+
+  if (CurrentUsage <= 64) {
+    return 64;
+  }
+
+  if (CurrentUsage <= 128) {
+    return 128;
+  }
+
+  if (CurrentUsage <= 256) {
+    return 256;
+  }
+
+  if (CurrentUsage <= 512) {
+    return 512;
+  }
+
+  if (CurrentUsage <= 1024) {
+    return 1024;
+  }
+
+  return CurrentUsage;
+} // MemPerSlot
+
+STATIC
+UINT64
+PMemPerSlot (
+  IN    UINT64 CurrentUsage
+  )
+{
+  if (CurrentUsage == 0) {
+    return 0;
+  }
+
+  if (CurrentUsage <= 1024ULL) {
+    return 1024ULL;
+  }
+
+  if (CurrentUsage <= 4096ULL) {
+    return 4096ULL;
+  }
+
+  return CurrentUsage;
+} // PMemPerSlot
+
+STATIC
+VOID
+SetPhyPortResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      SubBus,
+  IN       INT8       Depth,
+  IN       PORT_INFO  *CurrentPi,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8   Cmd;
+  UINT16  DeltaMem;
+  UINT64  DeltaPMem;
+
+  Cmd               = CMD_BUS_MASTER;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0x00, 0);
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+  DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
+  if (isLegacyDevice) {
+    if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
+      PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
+    }
+  } else {
+    if (DeltaMem < MemPerSlot (DeltaMem)) {
+      PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
+    }
+  }
+
+  if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase - 0x10) <= PortInfo->MemLimit) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), CurrentPi->MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+    PortInfo->MemBase = CurrentPi->MemBase;
+  }
+
+  DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
+  if (isLegacyDevice) {
+    if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
+      PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
+    }
+  } else {
+    if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
+      PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
+    }
+  }
+
+  if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 && (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10) & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10) >> 16));
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+    PortInfo->PMemBase64 = CurrentPi->PMemBase64;
+  }
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetPhyPortResources
+
+STATIC
+UINT32
+SaveSetGetRestoreBar (
+  IN  UINTN  Bar
+  )
+{
+  UINT32  BarReq;
+  UINT32  OrigBar;
+
+  OrigBar = PciSegmentRead32(Bar);     // Save BAR
+  PciSegmentWrite32(Bar, 0xFFFFFFFF);  // Set BAR
+  BarReq = PciSegmentRead32(Bar);      // Get BAR
+  PciSegmentWrite32(Bar, OrigBar);     // Restore BAR
+
+  return BarReq;
+} // SaveSetGetRestoreBar
+
+STATIC
+VOID
+SetIoBar (
+  IN            UINTN    BAR,
+  IN            UINT32   BarReq,
+  IN  OUT       UINT8    *Cmd,
+  IN  OUT       IO_REGS  *IoReg
+  )
+{
+  UINT16  Alignment;
+  UINT16  Size;
+  UINT16  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFC);
+  Size      = Alignment + 1;
+
+  if (IoReg->Base > IoReg->Limit || !Size) {
+    return ;
+
+  }
+
+  NewBase = BAR_ALIGN (IoReg->Base, Alignment);
+  if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
+    return ;
+
+  }
+  PciSegmentWrite16(BAR, NewBase);
+  IoReg->Base = NewBase + Size; // Advance to new position
+  *Cmd      |= CMD_BM_IO; // Set Io Space Enable
+} // SetIoBar
+
+STATIC
+VOID
+SetMemBar (
+  IN            UINTN     BAR,
+  IN            UINT32    BarReq,
+  IN  OUT       UINT8     *Cmd,
+  IN  OUT       MEM_REGS  *MemReg
+  )
+{
+  UINT32  Alignment;
+  UINT32  Size;
+  UINT32  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFFFFF0);
+  Size      = Alignment + 1;
+
+  if (MemReg->Base > MemReg->Limit || !Size) {
+    return ;
+
+  }
+
+  NewBase = BAR_ALIGN (MemReg->Base, Alignment);
+  if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
+    return ;
+
+  }
+
+  PciSegmentWrite32(BAR, NewBase);
+  MemReg->Base = NewBase + Size; // Advance to new position
+  *Cmd       |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetMemBar
+
+STATIC
+VOID
+SetPMem64Bar (
+  IN              UINTN      BAR,
+  IN              BOOLEAN    IsMaxBar,
+  IN              UINT32     BarReq,
+  IN    OUT       UINT8      *Cmd,
+  IN    OUT       PMEM_REGS  *MemReg
+  )
+{
+  UINT32  Alignment;
+  UINT32  Size;
+  UINT64  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFFFFF0);
+  Size      = Alignment + 1;
+
+  if (MemReg->Base64 > MemReg->Limit64 || !Size) {
+    return ;
+  }
+
+  NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
+  if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64) {
+    return ;
+  }
+  PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
+  if (!IsMaxBar) {
+    BAR++;
+    PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
+  }
+  MemReg->Base64 = NewBase + Size; // Advance to new position
+  *Cmd         |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetPMem64Bar
+
+STATIC
+VOID
+SetDevResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      MaxFun,  // PCI_MAX_FUNC for devices, 1 for bridge
+  IN       UINT8      MaxBar,     // PCI_BAR5 for devices, PCI_BAR1 for bridge
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8     Fun;
+  UINT8     Reg;
+  UINT32    BarReq;
+  IO_REGS   Io;
+  MEM_REGS  Mem;
+  PMEM_REGS PMem;
+  UINT8     Cmd;
+
+  Io.Base       = PortInfo->IoBase << 8;
+  Io.Limit      = (PortInfo->IoLimit << 8) | 0xFF;
+  Mem.Base      = PortInfo->MemBase << 16;
+  Mem.Limit     = (PortInfo->MemLimit << 16) | 0xFFFF;
+  PMem.Base64   = PortInfo->PMemBase64 << 16;
+  PMem.Limit64  = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
+
+  for (Fun = 0; Fun < MaxFun; ++Fun) {
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+    Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+
+    }
+
+    for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
+      BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform BAR sizing
+
+      if (BarReq & BIT0) {
+        //
+        // I/O BAR
+        //
+        SetIoBar (
+         (gDeviceBaseAddress + Reg),
+          BarReq,
+          &Cmd,
+          &Io
+          );
+        continue;
+      }
+
+      if (BarReq & BIT3) {
+        //
+        // P-Memory BAR
+        //
+        SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq, &Cmd, &PMem);
+      } else {
+        SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
+      }
+
+      if (BIT2 == (BarReq & (BIT2 | BIT1))) {
+        //
+        // Base address is 64 bits wide
+        //
+        Reg += 4;
+        if (!(BarReq & BIT3)) {
+          //
+          // 64-bit memory bar
+          //
+          PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
+        }
+      }
+    }
+
+    if (Cmd & BIT1) {
+      //
+      // If device uses I/O and MEM mapping use only MEM mepping
+      //
+      Cmd &= ~BIT0;
+    }
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+  }
+  //
+  // Update PortInfo if any changes
+  //
+  if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
+    PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
+  }
+
+  if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
+    PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
+  }
+
+  if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
+    PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
+  }
+} // SetDevResources
+
+STATIC
+VOID
+InitARHRConfigs(
+  IN HR_CONFIG *Hr_Config,
+  IN UINT8 BusNumLimit,
+  IN OUT BRDG_RES_CONFIG* HrResConf
+)
+{
+  UINT8 i,j;
+
+  //
+  // DS port for USB device
+  //
+  HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
+  HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
+  HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
+  HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+  HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+  //
+  // CIO port
+  //
+  HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
+  HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
+  HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
+  HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
+  HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
+
+  switch(Hr_Config->DeviceId)
+  {
+    //
+    // HR with 1 DS and 1 USB
+    //
+    case AR_HR_2C:
+    case AR_HR_LP:
+    case AR_HR_C0_2C:
+    case TR_HR_2C:
+      Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
+      Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
+      Hr_Config->BridgeLoops = 4;
+      break;
+    //
+    // HR with 2 DS and 1 USB
+    //
+    case AR_HR_4C:
+    case TR_HR_4C:
+    case AR_HR_C0_4C:
+      Hr_Config->MinDSNumber = 1;
+      Hr_Config->MaxDSNumber = 4;
+      Hr_Config->BridgeLoops = 6;
+      for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i)
+      {
+        HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+        HrConfigs[j].DevId.Dev = i;
+        HrConfigs[j].DevId.Fun = 0;
+        HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
+        HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
+      }
+    break;
+  }
+}//InitARHRConfigs
+
+
+STATIC
+VOID
+InitCommonHRConfigs (
+  IN       HR_CONFIG        *Hr_Config,
+  IN       UINT8            BusNumLimit,
+  IN  OUT  BRDG_RES_CONFIG  *HrResConf
+  )
+{
+  UINT8 i;
+
+  UINT8 j;
+  for(i = 0; i < count(HrConfigs); ++i) {
+    HrConfigs[i].IsDSBridge = TRUE;
+  }
+  //
+  // US(HRBus:0:0)
+  //
+  HrConfigs[HR_US_PORT].DevId.Bus   = Hr_Config->HRBus;
+  HrConfigs[HR_US_PORT].DevId.Dev   = 0;
+  HrConfigs[HR_US_PORT].DevId.Fun   = 0;
+  HrConfigs[HR_US_PORT].Res         = *HrResConf;
+  HrConfigs[HR_US_PORT].Res.IoBase  = 0xF1;
+  HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
+  HrConfigs[HR_US_PORT].PBus        = HrConfigs[HR_US_PORT].DevId.Bus;
+  HrConfigs[HR_US_PORT].SBus        = HrConfigs[HR_US_PORT].PBus + 1;
+  HrConfigs[HR_US_PORT].SubBus      = BusNumLimit;
+  HrConfigs[HR_US_PORT].IsDSBridge  = FALSE;
+
+  //
+  // HIA resides here
+  //
+  HrConfigs[HR_DS_PORT0].DevId.Bus    = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[HR_DS_PORT0].DevId.Dev    = 0;
+  HrConfigs[HR_DS_PORT0].DevId.Fun    = 0;
+  HrConfigs[HR_DS_PORT0].Res          = NOT_IN_USE_BRIDGE;
+  HrConfigs[HR_DS_PORT0].Res.MemBase  = HrResConf->MemLimit;
+  HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
+  HrResConf->MemLimit                -= 0x10; //This 1 MB chunk will be used by HIA
+  HrConfigs[HR_DS_PORT0].Res.Cmd      = CMD_BM_MEM;
+  HrConfigs[HR_DS_PORT0].Res.Cls      = DEF_CACHE_LINE_SIZE;
+  HrConfigs[HR_DS_PORT0].PBus         = HrConfigs[HR_DS_PORT0].DevId.Bus;
+  HrConfigs[HR_DS_PORT0].SBus         = HrConfigs[HR_DS_PORT0].PBus + 1;
+  HrConfigs[HR_DS_PORT0].SubBus       = HrConfigs[HR_DS_PORT0].PBus + 1;
+
+  switch (Hr_Config->DeviceId) {
+  //
+  // Alpine Ridge
+  //
+  case AR_HR_2C:
+  case AR_HR_C0_2C:
+  case AR_HR_LP:
+  case AR_HR_4C:
+  case AR_HR_C0_4C:
+  //
+  // Titan Ridge
+  //
+  case TR_HR_2C:
+  case TR_HR_4C:
+    InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
+    break;
+
+  default:
+    //
+    // DS(HRBus+2:3-6:0)
+    //
+    Hr_Config->MinDSNumber  = 3;
+    Hr_Config->MaxDSNumber  = 6;
+    Hr_Config->BridgeLoops  = count (HrConfigs);
+
+    for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i) {
+      HrConfigs[j].DevId.Bus  = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+      HrConfigs[j].DevId.Dev  = i;
+      HrConfigs[j].DevId.Fun  = 0;
+      HrConfigs[j].PBus       = HrConfigs[j].DevId.Bus;
+      HrConfigs[j].Res.Cls    = DEF_CACHE_LINE_SIZE;
+    }
+  }
+} // InitCommonHRConfigs
+
+STATIC
+VOID
+InitHRDSPort_Disable (
+  IN       UINT8        id,
+  IN  OUT  BRDG_CONFIG  *BrdgConf
+  )
+{
+  HrConfigs[id].Res     = NOT_IN_USE_BRIDGE;
+  HrConfigs[id].SBus    = BrdgConf->SBus;
+  HrConfigs[id].SubBus  = BrdgConf->SBus;
+
+  BrdgConf->SBus++;
+} // InitHRDSPort_Disable
+
+//AR only
+
+STATIC
+VOID
+InitARDSPort_1Port(
+  IN  OUT  BRDG_CONFIG* BrdgConf
+)
+{
+  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
+  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
+
+  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+  HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
+  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+}//InitARDSPort_1Port
+
+STATIC
+VOID
+InitARDSPort_2Port(
+  IN OUT BRDG_CONFIG* BrdgConf
+)
+{
+  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
+  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
+
+  // Busses are split between ports 1 and 4
+  BusRange /= 2;
+
+  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+  HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
+  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
+  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
+  HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
+  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+
+
+  HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
+  HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
+  HrConfigs[AR_DS_PORT4].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+  HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
+}//InitARDSPort_2Port
+
+
+STATIC
+BOOLEAN
+CheckLimits (
+  IN    BOOLEAN          Is2PortDev,
+  IN    BRDG_RES_CONFIG  *HrResConf,
+  IN    UINT8            BusRange
+  )
+{
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+
+  MemBase     = HrResConf->MemBase & 0xFFF0;
+  MemLimit    = HrResConf->MemLimit & 0xFFF0;
+  PMemBase64  = HrResConf->PMemBase64 & 0xFFF0;
+  PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
+  //
+  // Check memoty alignment
+  //
+  if (MemBase & 0x3FF) {
+    DEBUG((DEBUG_INFO, "M alig\n"));
+    return FALSE;
+  }
+
+  if (PMemBase64 & 0xFFF) {
+    DEBUG((DEBUG_INFO, "PM alig\n"));
+    return FALSE;
+  }
+
+  if (Is2PortDev) {
+    //
+    // Check mem size
+    //
+    if (MemLimit + 0x10 - MemBase < 0x2E00) {
+      DEBUG((DEBUG_INFO, "M size\n"));
+      return FALSE;
+    }
+    //
+    // Check P-mem size
+    //
+    if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
+      DEBUG((DEBUG_INFO, "PM size\n"));
+      return FALSE;
+    }
+    //
+    // Check bus range
+    //
+    if (BusRange < 106) {
+      DEBUG((DEBUG_INFO, "Bus range\n"));
+      return FALSE;
+    }
+  } else {
+    //
+    // Check mem size
+    //
+    if (MemLimit + 0x10 - MemBase < 0x1600) {
+      DEBUG((DEBUG_INFO, "M size\n"));
+      return FALSE;
+    }
+    //
+    // Check P-mem size
+    //
+    if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
+      DEBUG((DEBUG_INFO, "PM size\n"));
+      return FALSE;
+    }
+    //
+    // Check bus range
+    //
+    if (BusRange < 56) {
+      DEBUG((DEBUG_INFO, "Bus range\n"));
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+} // CheckLimits
+
+STATIC
+BOOLEAN
+InitHRResConfigs (
+  IN  OUT HR_CONFIG      *Hr_Config,
+  IN    UINT8            BusNumLimit,
+  IN  OUT BRDG_RES_CONFIG*HrResConf
+  )
+{
+  BRDG_CONFIG  BrdgConf = { { 0 } };
+
+  InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
+  BrdgConf.PBus   = Hr_Config->HRBus + 2;// Take into account busses
+  BrdgConf.SBus   = Hr_Config->HRBus + 3;// for US and DS of HIA
+  BrdgConf.SubBus = BusNumLimit;
+  BrdgConf.Res    = *HrResConf;
+  while (TRUE) {
+    switch (Hr_Config->DeviceId) {
+    case AR_HR_4C:
+    case TR_HR_4C:
+    case AR_HR_C0_4C:
+      //
+      // 2 Port host
+      //
+      if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
+
+
+          InitARDSPort_2Port(&BrdgConf);
+          DEBUG((DEBUG_INFO, "AR2\n"));
+
+        return TRUE;
+      } else {
+       return FALSE;
+      }
+    // AR only
+  case AR_HR_2C: // 1 port host
+  case AR_HR_C0_2C:
+  case AR_HR_LP:
+  case TR_HR_2C:
+    DEBUG((DEBUG_INFO, "AR1\n"));
+    InitARDSPort_1Port(&BrdgConf);
+    return TRUE;
+
+    default:
+      InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
+      return FALSE;
+    }
+  }
+} // InitHRResConfigs
+
+STATIC
+BOOLEAN
+InitializeHostRouter (
+  OUT  HR_CONFIG  *Hr_Config,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8           BusNumLimit;
+  BRDG_RES_CONFIG HrResConf = { 0 };
+  UINT8           i;
+  BOOLEAN         Ret;
+
+  Ret = TRUE;
+
+  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  Hr_Config->HRBus    = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, Hr_Config->HRBus, 0x00, 0x00, 0);
+  Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
+    return FALSE;
+  }
+  TbtSegment = (UINT8)RpSegment;
+
+  HrResConf.Cmd          = CMD_BM_MEM;
+  HrResConf.Cls          = DEF_CACHE_LINE_SIZE;
+  gDeviceBaseAddress      = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  HrResConf.IoBase       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+  HrResConf.IoLimit      = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+  HrResConf.MemBase      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+  HrResConf.MemLimit     = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+  HrResConf.PMemBase64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
+  HrResConf.PMemLimit64  = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
+  HrResConf.PMemBase64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+  HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+  BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+
+  Ret         = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
+
+  for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+    UINT8 Bus;
+    UINT8 Dev;
+    UINT8 Fun;
+    Bus               = HrConfigs[i].DevId.Bus;
+    Dev               = HrConfigs[i].DevId.Dev;
+    Fun               = HrConfigs[i].DevId.Fun;
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, HrConfigs[i].Res.Cls);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64 >> 16));
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), HrConfigs[i].Res.IoBase);
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, HrConfigs[i].Res.Cmd);
+  }
+  if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C || Hr_Config->DeviceId == AR_HR_LP) {
+    for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+      if(HrConfigs[i].IsDSBridge) {
+        UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev, HrConfigs[i].DevId.Fun);
+      }
+    }
+  }
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+  return Ret;
+} // InitializeHostRouter
+STATIC
+UINT8
+ConfigureSlot (
+  IN       UINT8      Bus,
+  IN       UINT8      MAX_DEVICE,
+  IN       INT8       Depth,
+  IN       BOOLEAN    ArPcie,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8      Device;
+  UINT8      SBus;
+  UINT8      UsedBusNumbers;
+  UINT8      RetBusNum;
+  PORT_INFO  CurrentSlot;
+
+  RetBusNum = 0;
+
+  for (Device = 0; Device < MAX_DEVICE; Device++) {
+    //
+    // Continue if device is absent
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, 0x00, 0);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+
+    }
+
+    if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+      SetDevResources (
+        Bus,
+        Device,
+        PCI_MAX_FUNC,
+        PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
+        PortInfo
+        );
+      continue;
+    }
+    //
+    // Else Bridge
+    //
+    CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
+
+    ++RetBusNum; // UP Bridge
+    SBus = Bus + RetBusNum; // DS Bridge
+
+    if (SBus + 1 >= PortInfo->BusNumLimit) {
+      continue;
+
+    }
+
+    SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), PortInfo);
+
+    //
+    // Init UP Bridge to reach DS Bridge
+    //
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+
+  if(ArPcie) {
+    UnsetVesc(Bus, Device, 0x00);
+  }
+
+  UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+  RetBusNum += UsedBusNumbers;
+
+    SetPhyPortResources (
+      Bus,
+      Device,
+      SBus + UsedBusNumbers,
+      Depth,
+      &CurrentSlot,
+      PortInfo
+      );
+  }
+  //
+  // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
+  //
+  return RetBusNum;
+} // ConfigureSlot
+
+STATIC
+VOID
+SetCioPortResources (
+  IN       UINT8     Bus,
+  IN       UINT8     Dev,
+  IN       UINT8     SBus,
+  IN       UINT8     SubBus,
+  IN       PORT_INFO  *portInfoBeforeChange,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8 Cmd;
+  Cmd               = CMD_BUS_MASTER;
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, 0x00, 0);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+  if (PortInfo->IoBase <= PortInfo->IoLimit) {
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), PortInfo->IoBase);
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), PortInfo->IoLimit);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+    Cmd |= CMD_BM_IO;
+  } else {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+  }
+
+  if (PortInfo->MemBase <= PortInfo->MemLimit) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), PortInfo->MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemLimit);
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+  }
+
+  if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+  }
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetCioPortResources
+
+STATIC
+VOID
+SetSlotsAsUnused (
+  IN       UINT8      Bus,
+  IN       UINT8      MaxSlotNum,
+  IN       UINT8      CioSlot,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8 Slot;
+  for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot, 0x00, 0);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+    }
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+    PortInfo->BusNumLimit--;
+  }
+} // SetSlotsAsUnused
+
+STATIC
+UINT16
+FindVendorSpecificHeader(
+  IN  UINT8  Bus
+)
+{
+  PCI_EXP_EXT_HDR   *ExtHdr;
+  UINT32            ExtHdrValue;
+  UINT16            ExtendedRegister;
+
+  ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
+  ExtendedRegister  = 0x100;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  while (ExtendedRegister) {
+    ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress + ExtendedRegister);
+    if (ExtHdr->CapabilityId == 0xFFFF) {
+      return 0x0000; // No Vendor-Specific Extended Capability header
+    }
+
+    if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID == ExtHdr->CapabilityId) {
+      return ExtendedRegister;
+    }
+
+    ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
+  }
+  return 0x0000; // No Vendor-Specific Extended Capability header
+}
+
+STATIC
+UINT8
+FindSsid_SsvidHeader (
+  IN    UINT8  Bus
+  )
+{
+  UINT8 CapHeaderId;
+  UINT8 CapHeaderOffset;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  CapHeaderOffset   = PciSegmentRead8 (gDeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+
+  while (CapHeaderOffset != 0) {
+    CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset);
+
+    if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
+      return CapHeaderOffset;
+    }
+
+    CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset + 1);
+  }
+
+  DEBUG((DEBUG_INFO, "SID0\n"));
+  return 0;
+} // FindSsid_SsvidHeader
+
+STATIC
+BOOLEAN
+GetCioSlotByDevId (
+  IN   UINT8  Bus,
+  OUT  UINT8  *CioSlot,
+  OUT  UINT8  *MaxSlotNum,
+  OUT  BOOLEAN *ArPcie
+  )
+{
+  UINT16            VSECRegister;
+  BRDG_CIO_MAP_REG  BridgMap;
+  UINT32            BitScanRes;
+  UINT16            DevId;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00, 0x00, 0);
+  DevId             = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+
+  //
+  // Init out params in case device is not recognised
+  //
+  *CioSlot    = 4;
+  *MaxSlotNum = 7;
+  *ArPcie     = FALSE;
+
+  switch (DevId) {
+    //
+    // For known device IDs
+    //
+    case 0x1578:
+      *ArPcie = TRUE;
+  }
+
+  switch (DevId) {
+  //
+  // For known device IDs
+  //
+  case 0x1513:
+  case 0x151A:
+  case 0x151B:
+  case 0x1547:
+  case 0x1548:
+    return TRUE; // Just return
+  case 0x1549:
+    return FALSE; // Just return
+  }
+
+  VSECRegister = FindVendorSpecificHeader(Bus);
+  if (!VSECRegister) {
+    return TRUE; // Just return
+  }
+  //
+  // Go to Bridge/CIO map register
+  //
+  VSECRegister += 0x18;
+  BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress + VSECRegister);
+  //
+  // Check for range
+  //
+  if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
+    return TRUE;
+  //
+  // Not a valid register
+  //
+  }
+  //
+  // Set OUT params
+  //
+  *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
+
+#ifdef _MSC_VER
+  if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS bridge which is CIO port
+    return FALSE;
+  }
+#else
+#ifdef __GNUC__
+  if (BridgMap.Bits.CioPortMap == 0) {
+    return FALSE;
+  }
+  BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
+#else
+#error Unsupported Compiler
+#endif
+#endif
+
+  *CioSlot = (UINT8)BitScanRes;
+  return TRUE;
+} // GetCioSlotByDevId
+
+#define TBT_LEGACY_SUB_SYS_ID 0x11112222
+
+STATIC
+BOOLEAN
+IsLegacyDevice (
+  IN    UINT8  Bus
+  )
+{
+  UINT32  Sid;
+  UINT8   SidRegister;
+  UINT16  DevId;
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  DevId             = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  switch (DevId) {
+  //
+  // For known device IDs
+  //
+  case 0x1513:
+  case 0x151A:
+  case 0x151B:
+    DEBUG((DEBUG_INFO, "Legacy "));
+    DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
+    return TRUE;
+    //
+    // Legacy device by Device Id
+    //
+  }
+
+  SidRegister = FindSsid_SsvidHeader(Bus);
+
+  if (!SidRegister) {
+    return TRUE; // May be absent for legacy devices
+  }
+  //
+  // Go to register
+  //
+  SidRegister += 0x4;
+  Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
+  DEBUG((DEBUG_INFO, "SID"));
+  DEBUG((DEBUG_INFO, " = %d\n", Sid));
+
+return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
+} // IsLegacyDevice
+
+STATIC
+VOID
+UnsetVescEp(
+  IN  UINT8     Bus,
+  IN  UINT8     MaxSlotNum
+  )
+{
+  UINT8 i;
+
+  for (i = 0; i <= MaxSlotNum; ++i)
+  {
+    UnsetVesc(Bus, i, 0);
+  }
+}// Unset_VESC_REG2_EP
+
+STATIC
+BOOLEAN
+ConfigureEP (
+  IN       INT8      Depth,
+  IN  OUT  UINT8     *Bus,
+  IN  OUT  PORT_INFO *PortInfo
+  )
+{
+  UINT8      SBus;
+  UINT8      CioSlot;
+  UINT8      MaxSlotNum;
+  BOOLEAN    ArPcie;
+  UINT8      MaxPHYSlots;
+  UINT8      UsedBusNumbers;
+  UINT8      cmd;
+  BOOLEAN    CioSlotPresent;
+  BOOLEAN    Continue;
+  PORT_INFO  PortInfoOrg;
+  UINT8      CioBus;
+
+  CioSlot     = 4;
+  MaxSlotNum  = 7;
+  CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus, 0x00, 0x00, 0);
+  cmd               = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+  // AR ONLY
+  // Endpoint on CIO slot, but not a bridge device
+  if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+    DEBUG((DEBUG_INFO, "UEP\n"));
+    // Check whether EP already configured by examining CMD register
+    if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
+    {
+      DEBUG((DEBUG_INFO, "BMF\n"));
+      return FALSE;
+    }
+    // Configure it as regular PCIe device
+    ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+
+    return FALSE;
+  }
+
+  //
+  // Based on Device ID assign Cio slot and max number of PHY slots to scan
+  //
+  CioSlotPresent  =  GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum, &ArPcie);
+  MaxPHYSlots     = MaxSlotNum;
+  //
+  // Check whether EP already configured by examining CMD register
+  //
+
+  if (cmd & CMD_BUS_MASTER) {
+    //
+    // Yes no need to touch this EP, just move to next one in chain
+    //
+    CioBus = *Bus + 1;
+    if(ArPcie){
+      UnsetVescEp(CioBus, MaxSlotNum);
+    }
+    if (!CioSlotPresent) {
+      //
+      // Cio slot is not present in EP, just return FALSE
+      //
+      DEBUG((DEBUG_INFO, "BMF\n"));
+      return FALSE;
+    }
+    //
+    // Take all resources from Cio slot and return
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus, CioSlot, 0x00, 0);
+    PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+    PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+    PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+    PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+    PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+    PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+    PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+    PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+    PortInfo->PMemLimit64  |= 0xF;
+    //
+    // Jump to next EP
+    //
+    *Bus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    //
+    // Should we continue?
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+    Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+    return Continue;
+  }
+  //
+  // Set is legacy dvice
+  //
+  isLegacyDevice = IsLegacyDevice (*Bus);
+
+  SetCioPortResources (
+    *Bus,
+    0, // Assign all available resources to US port of EP
+    *Bus + 1,
+    PortInfo->BusNumLimit,
+    0,
+    PortInfo
+    );
+
+  SBus = *Bus + 1;// Jump to DS port
+
+  if (CioSlotPresent) {
+    MaxPHYSlots = CioSlot;
+  }
+
+  UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie, PortInfo);
+  if (!CioSlotPresent) {
+    return FALSE;
+    //
+    // Stop resource assignment on this chain
+    //
+  }
+  //
+  // Set rest of slots us unused
+  //
+  SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
+
+  SetCioPortResources (
+    SBus,
+    CioSlot,
+    SBus + UsedBusNumbers + 1,
+    PortInfo->BusNumLimit,
+    &PortInfoOrg,
+    PortInfo
+    );
+  *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
+  if(ArPcie) {
+    UnsetVesc(SBus, CioSlot, 0x00);
+  }
+  if (*Bus > PortInfo->BusNumLimit - 2) {
+    //
+    // In case of bus numbers are exhausted stop enumeration
+    //
+    return FALSE;
+  }
+  //
+  // Check whether we should continue on this chain
+  //
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+  Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  return Continue;
+} // ConfigureEP
+
+STATIC
+VOID
+GetPortResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      Fun,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+  PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+  PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
+  PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
+  PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
+  PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
+  PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+  PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+  PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+  PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+  PortInfo->IoLimit |= 0xF;
+  PortInfo->MemLimit |= 0xF;
+  PortInfo->PMemLimit64 |= 0xF;
+} // GetPortResources
+
+STATIC
+VOID
+ConfigurePort (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      Fun,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  INT8  i;
+  UINT8 USBusNum;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+  USBusNum          = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, USBusNum, 0x00, 0x00, 0);
+  if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+    //
+    // Nothing to do if TBT device is not connected
+    //
+    return ;
+  }
+
+  GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from DS port
+  //
+  // Assign resources to EPs
+  //
+  for (i = 0; i < MAX_TBT_DEPTH; ++i) {
+    PortInfo->ConfedEP++;
+    if (!ConfigureEP (i, &USBusNum, PortInfo)) {
+      return ;
+    }
+  }
+} // ConfigurePort
+
+VOID
+ThunderboltCallback (
+  IN UINT8 Type
+  )
+{
+  PORT_INFO                     PortInfoOrg  = { 0 };
+  HR_CONFIG                     HrConfig  = { 0 };
+  UINT8                         i;
+  UINTN                         Segment = 0;
+  UINTN                         Bus = 0;
+  UINTN                         Device;
+  UINTN                         Function;
+
+  DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
+
+  DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
+  PortInfoInit (&PortInfoOrg);
+  if(Type == DTBT_CONTROLLER) {
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+      return;
+    }
+    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+    DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
+    if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
+      return ;
+    }
+  //
+  // Configure DS ports
+  //
+  for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
+    DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
+    ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
+  }
+
+  DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
+  EndOfThunderboltCallback (Segment, Bus, Device, Function);
+
+  }
+  DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
+} // ThunderboltCallback
+
+VOID
+DisablePCIDevicesAndBridges (
+  IN UINT8 MinBus,
+  IN UINT8 MaxBus
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RegVal;
+  //
+  //  Disable PCI device First, and then Disable PCI Bridge
+  //
+  for (Bus = MaxBus; Bus > MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+          if (Fun == 0) {
+            break;
+
+          }
+
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
+          //
+          // ********     Disable PCI Device   ********
+          // BIT0  I/O Space Enabled    BIT1  Memory Space Enabled
+          // BIT2  Bus Master Enabled   BIT4  Memory Write and Invalidation Enable
+          //
+          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
+        }
+      }
+    }
+  }
+  //
+  // now no more PCI dev on another side of PCI Bridge can safty disable PCI Bridge
+  //
+  for (Bus = MaxBus; Bus > MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+          if (Fun == 0) {
+            break;
+          }
+
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
+          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+        }
+      } // for ( Fun .. )
+    } // for ( Dev ... )
+  } // for ( Bus ... )
+} // DisablePCIDevicesAndBridges
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+  IN UINT8 Type
+  )
+{
+  UINTN         Segment = 0;
+  UINTN         Bus = 0;
+  UINTN         Device;
+  UINTN         Function;
+  UINT8         MinBus;
+  UINT8         MaxBus;
+  UINT16        DeviceId;
+
+  MinBus = 1;
+  if(Type == DTBT_CONTROLLER) {
+    //
+    // for(Dev = 0; Dev < 8; ++Dev)
+    // {
+    // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
+    // gBS->Stall(2000);      // 2msec
+    // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
+    // }
+    // gBS->Stall(200 * 1000);        // 200 msec
+    //
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+      return;
+    }
+    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+    MinBus            = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    MaxBus            = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus, 0x00, 0x00, 0);
+    DeviceId          = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+    if (!(IsTbtHostRouter (DeviceId))) {
+      return;
+    }
+    TbtSegment = (UINT8)Segment;
+    MinBus++;
+    //
+    // @todo : Move this out when we dont have Loop for ITBT
+    //
+    DisablePCIDevicesAndBridges(MinBus, MaxBus);
+
+  }
+} // DisablePCIDevicesAndBridges
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
new file mode 100644
index 0000000000..721438c718
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
@@ -0,0 +1,1765 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Module specific Includes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/TbtNvsArea.h>
+#include <PchAccess.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Guid/HobList.h>
+#include "TbtSmiHandler.h"
+#include <PcieRegs.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Library/PchPmcLib.h>
+#define P2P_BRIDGE                    (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define CMD_BM_MEM_IO                 (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DISBL_IO_REG1C                0x01F1
+#define DISBL_MEM32_REG20             0x0000FFF0
+#define DISBL_PMEM_REG24              0x0001FFF1
+
+#define DOCK_BUSSES                   8
+
+#define PCI_CAPABILITY_ID_PCIEXP      0x10
+#define PCI_CAPBILITY_POINTER_OFFSET  0x34
+
+#define LTR_MAX_SNOOP_LATENCY_VALUE             0x0846    ///< Intel recommended maximum value for Snoop Latency  can we put like this ?
+#define LTR_MAX_NON_SNOOP_LATENCY_VALUE         0x0846    ///< Intel recommended maximum value for Non-Snoop Latency can we put like this ?
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA                *mTbtNvsAreaPtr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gCurrentDiscreteTbtRootPort;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gCurrentDiscreteTbtRootPortType;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                      TbtLtrMaxSnoopLatency;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                      TbtLtrMaxNoSnoopLatency;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gDTbtPcieRstSupport;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB                *gTbtInfoHob = NULL;
+STATIC UINTN                                              mPciExpressBaseAddress;
+STATIC UINT8                TbtSegment        = 0;
+VOID
+GpioWrite (
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+  )
+{
+  GpioSetOutputValue (GpioNumber, (UINT32)Value);
+}
+
+/**
+  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] 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   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+
+  ///
+  /// 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 = 0x100;
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    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;
+}
+
+/**
+  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] 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
+  )
+{
+  UINT8   CapHeaderOffset;
+  UINT8   CapHeaderId;
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+
+  if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) & EFI_PCI_STATUS_CAPABILITY) == 0x00) {
+    ///
+    /// Function has no capability pointer
+    ///
+    return 0;
+  }
+
+  ///
+  /// 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 = 0x14;
+  } else {
+    ///
+    /// Otherwise, start at Offset 0x34
+    ///
+    CapHeaderOffset = 0x34;
+  }
+  ///
+  /// 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) {
+    CapHeaderId = PciSegmentRead8 (DeviceBase + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+    ///
+    /// 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 = PciSegmentRead8 (DeviceBase + CapHeaderOffset + 1) & ((UINT8) ~(BIT0 | BIT1));
+  }
+
+  return 0;
+}
+/**
+  This function configures the L1 Substates.
+  It can be used for Rootport and endpoint devices.
+
+  @param[in] DownstreamPort               Indicates if the device about to be programmed is a downstream port
+  @param[in] DeviceBase                   Device PCI configuration base address
+  @param[in] L1SubstateExtCapOffset       Pointer to L1 Substate Capability Structure
+  @param[in] PortL1SubstateCapSupport     L1 Substate capability setting
+  @param[in] PortCommonModeRestoreTime    Common Mode Restore Time
+  @param[in] PortTpowerOnValue            Tpower_on Power On Wait Time
+  @param[in] PortTpowerOnScale            Tpower-on Scale
+
+  @retval none
+**/
+VOID
+ConfigureL1s (
+  IN UINTN                              DeviceBase,
+  IN UINT16                             L1SubstateExtCapOffset,
+  IN UINT32                             PortL1SubstateCapSupport,
+  IN UINT32                             PortCommonModeRestoreTime,
+  IN UINT32                             PortTpowerOnValue,
+  IN UINT32                             PortTpowerOnScale,
+  IN UINT16                             MaxLevel
+  )
+{
+
+  PciSegmentAndThenOr32 (
+    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+    (UINT32) ~(0xFF00),
+    (UINT32) PortCommonModeRestoreTime << 8
+    );
+
+  PciSegmentAnd32(DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL2_OFFSET, 0xFFFFFF04);
+
+  PciSegmentOr32(DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL2_OFFSET,(UINT32) ((PortTpowerOnValue << N_PCIE_EX_L1SCTL2_POWT) | PortTpowerOnScale));
+
+  PciSegmentAndThenOr32 (
+    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+    (UINT32) ~(0xE3FF0000),
+    (UINT32) (BIT30 | BIT23 | BIT21)
+    );
+
+}
+
+VOID
+RootportL1sSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT16  RootL1SubstateExtCapOffset,
+  IN UINT16  MaxL1Level
+  )
+{
+  UINTN       ComponentABaseAddress;
+  UINTN       ComponentBBaseAddress;
+  UINT8       SecBus;
+  UINT32      PortL1SubstateCapSupport;
+  UINT32      PortCommonModeRestoreTime;
+  UINT32      PortTpowerOnValue;
+  UINT32      PortTpowerOnScale;
+  UINT16      ComponentBL1SubstateExtCapOffset;
+  UINT32      ComponentBL1Substates;
+  UINT32      ComponentBCommonModeRestoreTime;
+  UINT32      ComponentBTpowerOnValue;
+  UINT32      ComponentBTpowerOnScale;
+  UINT32      Data32;
+
+  PortL1SubstateCapSupport  = 0;
+  PortCommonModeRestoreTime = 0;
+  PortTpowerOnValue = 0;
+  PortTpowerOnScale = 0;
+  Data32 = 0;
+
+  ComponentABaseAddress  = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  if (RootL1SubstateExtCapOffset != 0) {
+    Data32 = PciSegmentRead32 (ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+    PortL1SubstateCapSupport  = (Data32) & 0x0F;
+    PortCommonModeRestoreTime = (Data32 >> 8) & 0xFF;
+    PortTpowerOnScale         = (Data32 >> 16) & 0x3;
+    PortTpowerOnValue         = (Data32 >> 19) & 0x1F;
+  } else {
+    MaxL1Level                = 0; // If L1 Substates from Root Port side is disable, then Disable from Device side also.
+  }
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+    ComponentBL1SubstateExtCapOffset = PcieFindExtendedCapId (
+                                  SecBus,
+                                  0,
+                                  0,
+                                  V_PCIE_EX_L1S_CID
+                                  );
+    if (ComponentBL1SubstateExtCapOffset != 0) {
+      ComponentBL1Substates = PciSegmentRead32 (ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+      ComponentBCommonModeRestoreTime = (ComponentBL1Substates >> 8) & 0xFF;
+      ComponentBTpowerOnScale         = (ComponentBL1Substates >> 16) & 0x3;
+      ComponentBTpowerOnValue         = (ComponentBL1Substates >> 19) & 0x1F;
+
+      if (MaxL1Level == 3) {
+        if (Data32 >= ComponentBL1Substates) {
+          if (~(Data32 | BIT2)) {
+            MaxL1Level = 1;
+          }
+        }
+        else {
+          if (~(ComponentBL1Substates | BIT2)) {
+          MaxL1Level = 1;
+        }
+      }
+    }
+
+      if (MaxL1Level == 3) {
+        ConfigureL1s (
+          ComponentABaseAddress,
+          RootL1SubstateExtCapOffset,
+          PortL1SubstateCapSupport,
+          ComponentBCommonModeRestoreTime,
+          ComponentBTpowerOnValue,
+          ComponentBTpowerOnScale,
+          MaxL1Level
+          );
+
+      ConfigureL1s (
+          ComponentBBaseAddress,
+          ComponentBL1SubstateExtCapOffset,
+          ComponentBL1Substates,
+          PortCommonModeRestoreTime,
+          PortTpowerOnValue,
+          PortTpowerOnScale,
+          MaxL1Level
+          );
+      }
+
+      if (MaxL1Level == 1) {
+        PciSegmentOr32 (
+          ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+          (UINT32) (BIT3 | BIT1)
+          );
+
+        PciSegmentOr32 (
+          ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+          (UINT32) (BIT3 | BIT1)
+          );
+      }
+      else {
+        if (RootL1SubstateExtCapOffset != 0) {
+          PciSegmentOr32 (
+            ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT3 | BIT1)
+            );
+
+          PciSegmentOr32 (
+            ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT2 | BIT0)
+            );
+        }
+        if (ComponentBL1SubstateExtCapOffset != 0) {
+          PciSegmentOr32 (
+            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT3 | BIT1)
+           );
+
+          PciSegmentOr32 (
+            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT2 | BIT0)
+            );
+        }
+      }
+    }
+  }
+}
+
+VOID
+MultiFunctionDeviceAspm (
+  IN UINT8   Bus,
+  IN UINT8   Dev
+  )
+{
+  UINT16  LowerAspm;
+  UINT16  AspmVal;
+  UINT8   Fun;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+
+  LowerAspm = 3; // L0s and L1 Supported
+  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+    //
+    // Check for Device availability
+    //
+    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+      // Device not present
+      continue;
+    }
+
+    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+
+    AspmVal = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+    if (LowerAspm > AspmVal) {
+      LowerAspm = AspmVal;
+    }
+  } //Fun
+
+  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+    //
+    // Check for Device availability
+    //
+    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+      //
+      // Device not present
+      //
+      continue;
+    }
+
+    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+
+    PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, LowerAspm);
+  } //Fun
+}
+
+UINT16
+LimitAspmLevel (
+  IN UINT16  SelectedAspm,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  SelectedAspm = SelectedAspm & MaxAspmLevel;
+
+  return SelectedAspm;
+}
+
+UINT16
+FindOptimalAspm (
+  IN UINT16   ComponentAaspm,
+  IN UINT16   ComponentBaspm
+  )
+{
+  UINT16  SelectedAspm;
+
+  SelectedAspm = ComponentAaspm & ComponentBaspm;
+
+  return SelectedAspm;
+}
+
+UINT16
+FindComponentBaspm (
+  IN UINT8   Bus,
+  IN UINT8   MaxBus
+  )
+{
+  UINT8   BusNo;
+  UINT8   DevNo;
+  UINT8   FunNo;
+  UINT64  DevBaseAddress;
+  UINT8   RegVal;
+  UINT8   SecBusNo;
+  UINT16  SelectedAspm; // No ASPM Support
+  UINT8   CapHeaderOffset_B;
+  BOOLEAN AspmFound;
+
+  SelectedAspm  = 0;
+  AspmFound     = FALSE;
+
+  for (BusNo = MaxBus; (BusNo != 0xFF) && (!AspmFound); --BusNo) {
+    for (DevNo = 0; (DevNo <= PCI_MAX_DEVICE) && (!AspmFound); ++DevNo) {
+      for (FunNo = 0; (FunNo <= PCI_MAX_FUNC) && (!AspmFound); ++FunNo) {
+        //
+        // Check for Device availability
+        //
+        DevBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, BusNo, DevNo, FunNo, 0);
+        if (PciSegmentRead16 (DevBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (DevBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if ((RegVal & (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6)) != 0x01) {
+          //
+          // Not a PCI-to-PCI bridges device
+          //
+          continue;
+        }
+
+        SecBusNo = PciSegmentRead8 (DevBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+
+        if (SecBusNo == Bus) {
+          //
+          // This is the Rootbridge for the given 'Bus' device
+          //
+          CapHeaderOffset_B = PcieFindCapId (TbtSegment, BusNo, DevNo, FunNo, 0x10);
+          SelectedAspm      = (PciSegmentRead16 (DevBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+          AspmFound         = TRUE;
+        }
+      } //FunNo
+    } //DevNo
+  } //BusNo
+
+  return (SelectedAspm);
+}
+
+VOID
+NoAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset
+  )
+{
+  UINT64 DeviceBaseAddress;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, 0x00);
+}
+
+VOID
+EndpointAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT8   MaxBus,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
+  SelectedAspm      = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+UpstreamAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT8   MaxBus,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
+  SelectedAspm      = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+DownstreamAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  ComponentABaseAddress;
+  UINT64  ComponentBBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+  UINT8   SecBus;
+  UINT8   CapHeaderOffset_B;
+
+  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+  ComponentBaspm        = 0; // No ASPM Support
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
+    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
+    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+  }
+
+  SelectedAspm = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+RootportAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  ComponentABaseAddress;
+  UINT64  ComponentBBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+  UINT8   SecBus;
+  UINT8   CapHeaderOffset_B;
+
+  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+  ComponentBaspm        = 0; // No ASPM Support
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
+    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
+    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+  }
+
+  SelectedAspm = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+ThunderboltEnableAspmWithoutLtr (
+  IN   UINT16     MaxAspmLevel,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RootBus;
+  UINT8   RootDev;
+  UINT8   RootFun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   RegVal;
+  UINT8   CapHeaderOffset;
+  UINT16  DevicePortType;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+
+  RootBus = (UINT8)RpBus;
+  RootDev = (UINT8)RpDevice;
+  RootFun = (UINT8)RpFunction;
+
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      //
+      // Check for Device availability
+      //
+      DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0, 0);
+      if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+        //
+        // Device not present
+        //
+        continue;
+      }
+
+      RegVal = PciSegmentRead8 (DeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+      if ((RegVal & BIT7) == 0) {
+        //
+        // Not a multi-function device
+        //
+        continue;
+      }
+
+      MultiFunctionDeviceAspm(Bus, Dev);
+    } //Dev
+  } //Bus
+
+
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x002) >> 4) & 0xF;
+        if(PciSegmentRead8 (DeviceBaseAddress + PCI_CLASSCODE_OFFSET) == PCI_CLASS_SERIAL) {
+          MaxAspmLevel = (UINT16) 0x1;
+        }
+
+        switch (DevicePortType) {
+        case 0:
+          //
+          // PCI Express Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 1:
+          //
+          // Legacy PCI Express Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 4:
+          //
+          // Root Port of PCI Express Root Complex
+          //
+          RootportAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLevel);
+          break;
+
+        case 5:
+          //
+          // Upstream Port of PCI Express Switch
+          //
+          UpstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 6:
+          //
+          // Downstream Port of PCI Express Switch
+          //
+          DownstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLevel);
+          break;
+
+        case 7:
+          //
+          // PCI Express to PCI/PCI-X Bridge
+          //
+          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
+          break;
+
+        case 8:
+          //
+          // PCI/PCI-X to PCI Express Bridge
+          //
+          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
+          break;
+
+        case 9:
+          //
+          // Root Complex Integrated Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 10:
+          //
+          // Root Complex Event Collector
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        default:
+          break;
+        }
+        //
+        // switch(DevicePortType)
+        //
+      }
+      //
+      // Fun
+      //
+    }
+    //
+    // Dev
+    //
+  }
+  //
+  // Bus
+  //
+  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun, 0x10);
+  RootportAspmSupport (RootBus, RootDev, RootFun, CapHeaderOffset, MaxAspmLevel);
+}
+
+
+
+VOID
+ThunderboltEnableL1Sub (
+  IN   UINT16     MaxL1Level,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT16  CapHeaderOffsetExtd;
+
+  RpBus   = 0;
+
+  CapHeaderOffsetExtd = PcieFindExtendedCapId ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, V_PCIE_EX_L1S_CID);
+  RootportL1sSupport ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, CapHeaderOffsetExtd, MaxL1Level);
+}
+
+VOID
+ThunderboltDisableAspmWithoutLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RootBus;
+  UINT8   RootDev;
+  UINT8   RootFun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  RootBus = (UINT8)RpBus;
+  RootDev = (UINT8)RpDevice;
+  RootFun = (UINT8)RpFunction;
+
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, 0x00);
+      } //Fun
+    } //Dev
+  } //Bus
+
+  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun, 0x10);
+  NoAspmSupport(RootBus, RootDev, RootFun, CapHeaderOffset);
+}
+
+VOID
+TbtProgramClkReq (
+  IN        UINT8  Bus,
+  IN        UINT8  Device,
+  IN        UINT8  Function,
+  IN        UINT8  ClkReqSetup
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+  UINT16  Data16;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function, 0x10);
+
+  //
+  // Check if CLKREQ# is supported
+  //
+  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x0C) & BIT18) != 0) {
+    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x010);
+
+    if (ClkReqSetup) {
+      Data16 = Data16 | BIT8; // Enable Clock Power Management
+    } else {
+      Data16 =  Data16 & (UINT16)(~BIT8); // Disable Clock Power Management
+    }
+
+    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x010, Data16);
+  }
+}
+VOID
+TbtProgramPtm(
+   IN        UINT8  Bus,
+   IN        UINT8  Device,
+   IN        UINT8  Function,
+   IN        UINT8  PtmSetup,
+   IN        BOOLEAN IsRoot
+)
+{
+   UINT64  DeviceBaseAddress;
+   UINT16  CapHeaderOffset;
+   UINT16  PtmControlRegister;
+   UINT16  PtmCapabilityRegister;
+
+   DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS(TbtSegment, Bus, Device, Function, 0);
+   CapHeaderOffset = PcieFindExtendedCapId(Bus, Device, Function, 0x001F /*V_PCIE_EX_PTM_CID*/);
+   if(CapHeaderOffset != 0) {
+      PtmCapabilityRegister = PciSegmentRead16(DeviceBaseAddress + CapHeaderOffset + 0x04);
+     //
+     // Check if PTM Requester/ Responder capability for the EP/Down stream etc
+     //
+     if ((PtmCapabilityRegister & (BIT1 | BIT0)) != 0) {
+        PtmControlRegister = PciSegmentRead16(DeviceBaseAddress + CapHeaderOffset + 0x08);
+
+        if (PtmSetup) {
+           PtmControlRegister = PtmControlRegister | BIT0; // Enable PTM
+           if(IsRoot) {
+             PtmControlRegister = PtmControlRegister | BIT1; // Enable PTM
+           }
+           PtmControlRegister = PtmControlRegister | (PtmCapabilityRegister & 0xFF00); // Programm Local Clock Granularity
+        } else {
+           PtmControlRegister = PtmControlRegister & (UINT16)(~(BIT0 | BIT1)); // Disable Clock Power Management
+        }
+
+        PciSegmentWrite16(DeviceBaseAddress + CapHeaderOffset + 0x08, PtmControlRegister);
+     }
+   }
+}
+
+VOID
+ConfigureTbtPm (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction,
+  IN   UINT8      Configuration    // 1- Clk Request , 2- PTM ,
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  if ((Configuration != 1) && (Configuration != 2)) {
+    return;
+  }
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MaxBus; Bus >= MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          if (Fun == 0) {
+            //
+            // IF Fun is zero, stop enumerating other functions of the particular bridge
+            //
+            break;
+          }
+          //
+          // otherwise, just skip checking for CLKREQ support
+          //
+          continue;
+        }
+        switch (Configuration) {
+          case 1:
+            TbtProgramClkReq (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtSetClkReq);
+            break;
+          case 2:
+            TbtProgramPtm (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtPtm, FALSE);
+            TbtProgramPtm((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, (UINT8) mTbtNvsAreaPtr->TbtPtm, TRUE);
+            break;
+          default:
+            break;
+        }
+      } //Fun
+    } // Dev
+  } // Bus
+}
+
+/**
+  1) Check LTR support in device capabilities 2 register (bit 11).
+  2) If supported enable LTR in device control 2 register (bit 10).
+
+**/
+VOID
+TbtProgramLtr (
+  IN        UINT8  Bus,
+  IN        UINT8  Device,
+  IN        UINT8  Function,
+  IN        UINT8  LtrSetup
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+  UINT16  Data16;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function, 0x10);
+
+  //
+  // Check if LTR# is supported
+  //
+  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x24) & BIT11) != 0) {
+    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x028);
+
+    if (LtrSetup) {
+      Data16 = Data16 | BIT10; // LTR Mechanism Enable
+    } else {
+      Data16 =  Data16 & (UINT16)(~BIT10); // LTR Mechanism Disable
+    }
+
+    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x028, Data16);
+  }
+}
+
+VOID
+ConfigureLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          if (Fun == 0) {
+            //
+            // IF Fun is zero, stop enumerating other functions of the particular bridge
+            //
+            break;
+          }
+          //
+          // otherwise, just skip checking for LTR support
+          //
+          continue;
+        }
+
+        TbtProgramLtr (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtLtr);
+
+      } //Fun
+    } // Dev
+  } // Bus
+  TbtProgramLtr ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, (UINT8) mTbtNvsAreaPtr->TbtLtr);
+}
+
+/*
+  US ports and endpoints which declare support must also have the LTR capability structure (cap ID 18h).
+  In this structure you need to enter the max snoop latency and max non-snoop latency in accordance with the format specified in the PCIe spec.
+  The latency value itself is platform specific so you'll need to get it from the platform architect or whatever.
+*/
+VOID
+ThunderboltGetLatencyLtr (
+  VOID
+  )
+{
+  PCH_SERIES       PchSeries;
+
+  PchSeries = GetPchSeries ();
+
+  if(gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PEG) {
+  // PEG selector
+  TbtLtrMaxSnoopLatency = LTR_MAX_SNOOP_LATENCY_VALUE;
+  TbtLtrMaxNoSnoopLatency = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+  } else if (gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PCH) {
+  // PCH selector
+
+    if (PchSeries == PchLp) {
+      TbtLtrMaxSnoopLatency = 0x1003;
+      TbtLtrMaxNoSnoopLatency = 0x1003;
+    }
+    if (PchSeries == PchH) {
+      TbtLtrMaxSnoopLatency = 0x0846;
+      TbtLtrMaxNoSnoopLatency = 0x0846;
+    }
+  }
+}
+
+VOID
+SetLatencyLtr (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT16  CapHeaderOffsetExtd,
+  IN UINT16  LtrMaxSnoopLatency,
+  IN UINT16  LtrMaxNoSnoopLatency
+  )
+{
+  UINT64 DeviceBaseAddress;
+  if(CapHeaderOffsetExtd == 0) {
+    return;
+  }
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x004, LtrMaxSnoopLatency);
+  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x006, LtrMaxNoSnoopLatency);
+}
+
+VOID
+ThunderboltSetLatencyLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffsetStd;
+  UINT16  CapHeaderOffsetExtd;
+  UINT16  DevicePortType;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffsetStd = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffsetStd + 0x002) >> 4) & 0xF;
+
+        CapHeaderOffsetExtd = PcieFindExtendedCapId (Bus, Dev, Fun, 0x0018);
+
+        switch (DevicePortType) {
+        case 0:
+          //
+          // PCI Express Endpoint
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 1:
+          //
+          // Legacy PCI Express Endpoint
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 4:
+          //
+          // Root Port of PCI Express Root Complex
+          //
+          // Do-nothing
+          break;
+
+        case 5:
+          //
+          // Upstream Port of PCI Express Switch
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 6:
+          //
+          // Downstream Port of PCI Express Switch
+          //
+          // Do-nothing
+          break;
+
+        case 7:
+          //
+          // PCI Express to PCI/PCI-X Bridge
+          //
+          // Do-nothing
+          break;
+
+        case 8:
+          //
+          // PCI/PCI-X to PCI Express Bridge
+          //
+          // Do-nothing
+          break;
+
+        case 9:
+          //
+          // Root Complex Integrated Endpoint
+          //
+          // Do-nothing
+          break;
+
+        case 10:
+          //
+          // Root Complex Event Collector
+          //
+          // Do-nothing
+          break;
+
+        default:
+          break;
+        }
+        //
+        // switch(DevicePortType)
+        //
+      }
+      //
+      // Fun
+      //
+    }
+    //
+    // Dev
+    //
+  }
+  //
+  // Bus
+  //
+}
+
+static
+VOID
+Stall (
+  UINTN     Usec
+  )
+{
+  UINTN   Index;
+  UINT32  Data32;
+  UINT32  PrevData;
+  UINTN   Counter;
+
+  Counter = (UINTN) ((Usec * 10) / 3);
+  //
+  // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+  // periods, thus attempting to ensure Microseconds of stall time.
+  //
+  if (Counter != 0) {
+
+    PrevData = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_TMR);
+    for (Index = 0; Index < Counter;) {
+      Data32 = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_TMR);
+      if (Data32 < PrevData) {
+        //
+        // Reset if there is a overlap
+        //
+        PrevData = Data32;
+        continue;
+      }
+
+      Index += (Data32 - PrevData);
+      PrevData = Data32;
+    }
+  }
+
+  return ;
+}
+/**
+  Called during Sx entry, initates TbtSetPcie2TbtCommand HandShake to set GO2SX_NO_WAKE
+  for Tbt devices if WakeupSupport is not present.
+
+  @param[in] DispatchHandle         - The unique handle assigned to this handler by SmiHandlerRegister().
+  @param[in] DispatchContext        - 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 successfully.
+**/
+EFI_STATUS
+EFIAPI
+SxDTbtEntryCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer OPTIONAL,
+  IN  UINTN                         *CommBufferSize OPTIONAL
+  )
+{
+  UINT16          DeviceId;
+  UINT8           CableConnected;
+  UINT8           RootportSelected;
+  UINT8           HoustRouteBus;
+  volatile UINT32 *PowerState;
+  UINT32          PowerStatePrev;
+  BOOLEAN         SecSubBusAssigned;
+  UINT64          DeviceBaseAddress;
+  UINT8           CapHeaderOffset;
+  UINTN           RpDev;
+  UINTN           RpFunc;
+  EFI_STATUS      Status;
+  UINT32          Timeout;
+  UINT32          RegisterValue;
+  UINT64          Tbt2Pcie;
+  UINTN           Index;
+  UINT32          TbtCioPlugEventGpioNo;
+  UINT32          TbtFrcPwrGpioNo;
+  UINT8           TbtFrcPwrGpioLevel;
+  UINT32          TbtPcieRstGpioNo;
+  UINT8           TbtPcieRstGpioLevel;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryDispatchContext;
+
+  CableConnected    = 0;
+  HoustRouteBus     = 3;
+  SecSubBusAssigned = FALSE;
+  Timeout = 600;
+  RootportSelected      = 0;
+  TbtCioPlugEventGpioNo = 0;
+  TbtFrcPwrGpioNo       = 0;
+  TbtFrcPwrGpioLevel    = 0;
+  TbtPcieRstGpioNo      = 0;
+  TbtPcieRstGpioLevel   = 0;
+  Index = 0;
+
+  EntryDispatchContext = (EFI_SMM_SX_REGISTER_CONTEXT*) DispatchContext;
+
+//  CableConnected = GetTbtHostRouterStatus ();
+  //SaveTbtHostRouterStatus (CableConnected & 0xF0);
+  //
+  // Get the Power State and Save
+  //
+  if (((mTbtNvsAreaPtr->DTbtControllerEn0 == 0) && (Index == 0)))  {
+
+  RootportSelected      = mTbtNvsAreaPtr->RootportSelected0;
+  TbtCioPlugEventGpioNo = mTbtNvsAreaPtr->TbtCioPlugEventGpioNo0;
+  TbtFrcPwrGpioNo       = mTbtNvsAreaPtr->TbtFrcPwrGpioNo0;
+  TbtFrcPwrGpioLevel    = mTbtNvsAreaPtr->TbtFrcPwrGpioLevel0;
+  TbtPcieRstGpioNo      = mTbtNvsAreaPtr->TbtPcieRstGpioNo0;
+  TbtPcieRstGpioLevel   = mTbtNvsAreaPtr->TbtPcieRstGpioLevel0;
+  }
+
+  Status = GetDTbtRpDevFun (gCurrentDiscreteTbtRootPortType, RootportSelected - 1, &RpDev, &RpFunc);
+  ASSERT_EFI_ERROR (Status);
+  CapHeaderOffset = PcieFindCapId (TbtSegment, 0x00, (UINT8)RpDev, (UINT8)RpFunc, 0x01);
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, 0x00, (UINT32)RpDev, (UINT32)RpFunc, 0);
+  PowerState        = &*((volatile UINT32 *) (mPciExpressBaseAddress + DeviceBaseAddress + CapHeaderOffset + 4)); //PMCSR
+  PowerStatePrev    = *PowerState;
+  *PowerState &= 0xFFFFFFFC;
+
+  HoustRouteBus = PciSegmentRead8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  //
+  // Check the Subordinate bus .If it is Zero ,assign temporary bus to
+  // find the device presence .
+  //
+  if (HoustRouteBus == 0) {
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0xF0);
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0xF0);
+    HoustRouteBus     = 0xF0;
+    SecSubBusAssigned = TRUE;
+  }
+  //
+  // Clear Interrupt capability of TBT CIO Plug Event Pin to make sure no SCI is getting generated,
+  // This GPIO will be reprogrammed while resuming as part of Platform GPIO Programming.
+  //
+  GpioSetPadInterruptConfig (TbtCioPlugEventGpioNo, GpioIntDis);
+  //
+  // Read the TBT Host router DeviceID
+  //
+  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (TbtSegment, HoustRouteBus, 0, 0, PCI_DEVICE_ID_OFFSET));
+
+  //
+  // Check For HostRouter Presence
+  //
+  if (IsTbtHostRouter (DeviceId)) {
+    //    CableConnected = GetTbtHostRouterStatus ();
+    if (!((CableConnected & (DTBT_SAVE_STATE_OFFSET << Index)) == (DTBT_SAVE_STATE_OFFSET << Index))) {
+      CableConnected = CableConnected | (DTBT_SAVE_STATE_OFFSET << Index);
+   //     SaveTbtHostRouterStatus (CableConnected);
+    }
+  }
+
+  //
+  // Check value of Tbt2Pcie reg, if Tbt is not present, bios needs to apply force power prior to sending mailbox command
+  //
+  GET_TBT2PCIE_REGISTER_ADDRESS(TbtSegment, HoustRouteBus, 0x00, 0x00, Tbt2Pcie)
+  RegisterValue = PciSegmentRead32 (Tbt2Pcie);
+  if (0xFFFFFFFF == RegisterValue) {
+
+    GpioWrite (TbtFrcPwrGpioNo,TbtFrcPwrGpioLevel);
+
+    while (Timeout -- > 0) {
+      RegisterValue = PciSegmentRead32 (Tbt2Pcie);
+      if (0xFFFFFFFF != RegisterValue) {
+        break;
+      }
+      Stall(1* (UINTN)1000);
+    }
+    //
+    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox command for AIC.
+    // However BIOS shall not execute go2sx mailbox command on S5/reboot cycle.
+    //
+
+    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type == SxS4))
+    {
+      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
+        //Wake Disabled, GO2SX_NO_WAKE Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      } else {
+        //Wake Enabled, GO2SX Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      }
+    }
+    if (mTbtNvsAreaPtr->TbtFrcPwrEn == 0) {
+      GpioWrite (TbtFrcPwrGpioNo,!(TbtFrcPwrGpioLevel));
+    }
+  } else {
+    //
+    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox command for AIC.
+    // However BIOS shall not execute go2sx mailbox command on S5/reboot cycle.
+    //
+    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type == SxS4))
+    {
+      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
+        //Wake Disabled, GO2SX_NO_WAKE Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      } else {
+        //Wake Enabled, GO2SX Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      }
+    }
+  }
+  *PowerState = PowerStatePrev;
+  //
+  // Restore the bus number in case we assigned temporarily
+  //
+  if (SecSubBusAssigned) {
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0x00);
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0x00);
+  }
+  if (gDTbtPcieRstSupport) {
+    GpioWrite (TbtPcieRstGpioNo,TbtPcieRstGpioLevel);
+  }
+  return EFI_SUCCESS;
+}
+
+VOID
+ThunderboltSwSmiCallback (
+  IN UINT8 Type
+  )
+{
+  UINT8 ThunderboltSmiFunction;
+
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Entry\n"));
+  ThunderboltSmiFunction = mTbtNvsAreaPtr->ThunderboltSmiFunction;
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback. ThunderboltSmiFunction=%d\n", ThunderboltSmiFunction));
+  if (Type == DTBT_CONTROLLER) {
+    gCurrentDiscreteTbtRootPort     = mTbtNvsAreaPtr->CurrentDiscreteTbtRootPort;
+    gCurrentDiscreteTbtRootPortType = mTbtNvsAreaPtr->CurrentDiscreteTbtRootPortType;
+  }
+
+  switch (ThunderboltSmiFunction) {
+  case 21:
+    ThunderboltCallback (Type);
+    break;
+
+  case 22:
+    TbtDisablePCIDevicesAndBridges (Type);
+    break;
+
+  case 23:
+    ConfigureTbtAspm (Type, (UINT16) 0x02);
+    break;
+
+  case 24:
+    ConfigureTbtAspm (Type, (UINT16) 0x01);
+    break;
+
+  default:
+    break;
+  }
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Exit.\n"));
+}
+STATIC
+EFI_STATUS
+EFIAPI
+DiscreteThunderboltSwSmiCallback (
+  IN EFI_HANDLE                     DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer OPTIONAL,
+  IN  UINTN                         *CommBufferSize OPTIONAL
+  )
+{
+  ThunderboltSwSmiCallback(DTBT_CONTROLLER);
+  return EFI_SUCCESS;
+}
+EFI_STATUS
+TbtRegisterHandlers (
+  IN BOOLEAN Type
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         SmiInputValue;
+  EFI_SMM_HANDLER_ENTRY_POINT2   SxHandler;
+  EFI_SMM_HANDLER_ENTRY_POINT2   SwHandler;
+  EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatchProtocol;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+  EFI_SMM_SX_REGISTER_CONTEXT   EntryDispatchContext;
+  EFI_SMM_SW_REGISTER_CONTEXT   SwContext;
+  EFI_HANDLE                    SwDispatchHandle;
+  EFI_HANDLE                    S3DispatchHandle;
+  EFI_HANDLE                    S4DispatchHandle;
+  EFI_HANDLE                    S5DispatchHandle;
+
+  Status = EFI_UNSUPPORTED;
+
+  if(Type == DTBT_CONTROLLER) {
+    SxHandler = SxDTbtEntryCallback;
+    SwHandler = DiscreteThunderboltSwSmiCallback;
+    SmiInputValue = PcdGet8 (PcdSwSmiDTbtEnumerate);
+    gDTbtPcieRstSupport = gTbtInfoHob->DTbtCommonConfig.PcieRstSupport;
+    Status = EFI_SUCCESS;
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SwDispatchHandle        = NULL;
+  S3DispatchHandle        = NULL;
+  S4DispatchHandle        = NULL;
+  S5DispatchHandle        = NULL;
+
+   Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSxDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &SxDispatchProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S3 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS3;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S3DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S4 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS4;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S4DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S5 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS5;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S5DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Locate the SMM SW dispatch protocol
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSwDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &SwDispatch
+                    );
+
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register SWSMI handler
+  //
+  SwContext.SwSmiInputValue = SmiInputValue;
+  Status = SwDispatch->Register (
+                        SwDispatch,
+                        SwHandler,
+                        &SwContext,
+                        &SwDispatchHandle
+                        );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+EFI_STATUS
+InSmmFunction (
+  IN  EFI_HANDLE        ImageHandle,
+  IN  EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                    Status;
+
+  Status = EFI_SUCCESS;
+
+  Status = TbtRegisterHandlers(DTBT_CONTROLLER);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+TbtSmmEntryPoint (
+  IN EFI_HANDLE               ImageHandle,
+  IN EFI_SYSTEM_TABLE         *SystemTable
+  )
+{
+  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
+  EFI_STATUS                    Status;
+
+  DEBUG ((DEBUG_INFO, "TbtSmmEntryPoint\n"));
+
+  mPciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
+  //
+  // Locate Tbt shared data area
+  //
+  Status = gBS->LocateProtocol (&gTbtNvsAreaProtocolGuid, NULL, (VOID **) &TbtNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+  mTbtNvsAreaPtr = TbtNvsAreaProtocol->Area;
+
+  //
+  // Get TBT INFO HOB
+  //
+  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+  if (gTbtInfoHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  return InSmmFunction (ImageHandle, SystemTable);
+}
+
+VOID
+EndOfThunderboltCallback (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  if(mTbtNvsAreaPtr->TbtL1SubStates != 0) {
+    ThunderboltEnableL1Sub (mTbtNvsAreaPtr->TbtL1SubStates, RpSegment, RpBus, RpDevice, RpFunction);
+  }
+  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 1);
+  if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
+    ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  } else { //Aspm enable case
+    ThunderboltEnableAspmWithoutLtr ((UINT16)mTbtNvsAreaPtr->TbtAspm, RpSegment, RpBus, RpDevice, RpFunction);
+  }
+
+  if (mTbtNvsAreaPtr->TbtLtr) {
+    ThunderboltGetLatencyLtr ();
+    ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  }
+  ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 2);
+} // EndOfThunderboltCallback
+
+VOID
+ConfigureTbtAspm (
+  IN UINT8        Type,
+  IN UINT16       Aspm
+  )
+{
+  UINTN                         RpSegment = 0;
+  UINTN                         RpBus = 0;
+  UINTN                         RpDevice;
+  UINTN                         RpFunction;
+
+  if(Type == DTBT_CONTROLLER) {
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      return;
+    }
+    GetDTbtRpDevFun(DTBT_CONTROLLER, gCurrentDiscreteTbtRootPort - 1, &RpDevice, &RpFunction);
+
+    ConfigureTbtPm (RpSegment, RpBus, RpDevice, RpFunction, 1);
+    if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
+      ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunction);
+    } else { //Aspm enable case
+      ThunderboltEnableAspmWithoutLtr ((UINT16) Aspm, RpSegment, RpBus, RpDevice, RpFunction);
+    }
+
+  if (mTbtNvsAreaPtr->TbtLtr) {
+      ThunderboltGetLatencyLtr ();
+      ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
+    }
+    ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  } // EndOfThunderboltCallback
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
new file mode 100644
index 0000000000..ec06eee73f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -0,0 +1,394 @@
+/** @file
+  ACPI Timer implements one instance of Timer Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Acpi.h>
+//
+// OVERRIDE: OverrideBegin
+//
+#include <Register/Cpuid.h>
+//
+// OVERRIDE: OverrideEnd
+//
+
+
+/**
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+InternalGetPerformanceCounterFrequency (
+  VOID
+  );
+
+/**
+  The constructor function enables ACPI IO space.
+
+  If ACPI I/O space not enabled, this function will enable it.
+  It will always return RETURN_SUCCESS.
+
+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+AcpiTimerLibConstructor (
+  VOID
+  )
+{
+  UINTN   Bus;
+  UINTN   Device;
+  UINTN   Function;
+  UINTN   EnableRegister;
+  UINT8   EnableMask;
+
+  //
+  // ASSERT for the invalid PCD values. They must be configured to the real value.
+  //
+  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);
+  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);
+
+  //
+  // If the register offset to the BAR for the ACPI I/O Port Base Address is 0x0000, then
+  // no PCI register programming is required to enable access to the the ACPI registers
+  // specified by PcdAcpiIoPortBaseAddress
+  //
+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {
+    return RETURN_SUCCESS;
+  }
+
+  //
+  // ASSERT for the invalid PCD values. They must be configured to the real value.
+  //
+  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);
+  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);
+  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);
+
+  //
+  // Retrieve the PCD values for the PCI configuration space required to program the ACPI I/O Port Base Address
+  //
+  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);
+  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);
+  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);
+  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);
+  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);
+
+  //
+  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and enable it.
+  //
+  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister)) & EnableMask) != EnableMask) {
+    PciWrite16 (
+      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16 (PcdAcpiIoPciBarRegisterOffset)),
+      PcdGet16 (PcdAcpiIoPortBaseAddress)
+      );
+    PciOr8 (
+      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),
+      EnableMask
+      );
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Internal function to retrieve the ACPI I/O Port Base Address.
+
+  Internal function to retrieve the ACPI I/O Port Base Address.
+
+  @return The 16-bit ACPI I/O Port Base Address.
+
+**/
+UINT16
+InternalAcpiGetAcpiTimerIoPort (
+  VOID
+  )
+{
+  UINT16  Port;
+
+  Port = PcdGet16 (PcdAcpiIoPortBaseAddress);
+
+  //
+  // If the register offset to the BAR for the ACPI I/O Port Base Address is not 0x0000, then
+  // read the PCI register for the ACPI BAR value in case the BAR has been programmed to a
+  // value other than PcdAcpiIoPortBaseAddress
+  //
+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {
+    Port = PciRead16 (PCI_LIB_ADDRESS (
+                        PcdGet8  (PcdAcpiIoPciBusNumber),
+                        PcdGet8  (PcdAcpiIoPciDeviceNumber),
+                        PcdGet8  (PcdAcpiIoPciFunctionNumber),
+                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)
+                        ));
+  }
+
+  return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16 (PcdAcpiPm1TmrOffset);
+}
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+VOID
+InternalAcpiDelay (
+  IN UINT32  Delay
+  )
+{
+  UINT16   Port;
+  UINT32   Ticks;
+  UINT32   Times;
+
+  Port   = InternalAcpiGetAcpiTimerIoPort ();
+  Times  = Delay >> 22;
+  Delay &= BIT22 - 1;
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks = IoBitFieldRead32 (Port, 0, 23) + Delay;
+    Delay = BIT22;
+    //
+    // Wait until time out
+    // Delay >= 2^23 could not be handled by this function
+    // Timer wrap-arounds are handled correctly by this function
+    //
+    while (((Ticks - IoBitFieldRead32 (Port, 0, 23)) & BIT23) == 0) {
+      CpuPause ();
+    }
+  } while (Times-- > 0);
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN UINTN  MicroSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                MicroSeconds,
+                ACPI_TIMER_FREQUENCY
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN UINTN  NanoSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                NanoSeconds,
+                ACPI_TIMER_FREQUENCY
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  Retrieves the current value of a 64-bit free running performance counter. The
+  counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return AsmReadTsc ();
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT UINT64  *StartValue,  OPTIONAL
+  OUT UINT64  *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 0xffffffffffffffffULL;
+  }
+  return InternalGetPerformanceCounterFrequency ();
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN UINT64  Ticks
+  )
+{
+  UINT64  Frequency;
+  UINT64  NanoSeconds;
+  UINT64  Remainder;
+  INTN    Shift;
+  Frequency = GetPerformanceCounterProperties (NULL, NULL);
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
+
+  //
+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
+  // i.e. highest bit set in Remainder should <= 33.
+  //
+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);
+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);
+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);
+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
+
+  return NanoSeconds;
+}
+
+//
+// OVERRIDE: OverrideBegin
+//
+/**
+  Calculate TSC frequency.
+
+  The TSC counting frequency is determined by using CPUID leaf 0x15 that is the preferred
+  method for Skylake and beyond.  Frequency in MHz = Core XTAL frequency * EBX/EAX.
+  In newer flavors of the CPU, core xtal frequency is returned in ECX (or 0 if not
+  supported).  If ECX is 0, 24MHz is assumed.
+  @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+  VOID
+  )
+{
+  UINT64      TscFrequency;
+  UINT64      CoreXtalFrequency;
+  UINT32      RegEax;
+  UINT32      RegEbx;
+  UINT32      RegEcx;
+
+  //
+  // Use CPUID leaf 0x15.
+  // TSC frequency = (Core Xtal Frequency) * EBX/EAX.  EBX returns 0 if not
+  // supported. ECX, if non zero, provides Core Xtal Frequency in hertz
+  // (SDM Dec 2016).
+  //
+  AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL);
+  ASSERT (RegEbx != 0);
+
+  //
+  // If core xtal frequency (ECX) returns 0, it is safe to use 24MHz for post
+  // Skylake client CPU's.
+  //
+  if (RegEcx == 0) {
+    CoreXtalFrequency = 24000000ul;
+  } else {
+    CoreXtalFrequency = (UINT64)RegEcx;
+  }
+
+  //
+  // Calculate frequency.  For integer division, round up/down result
+  // correctly by adding denominator/2 to the numerator prior to division.
+  //
+  TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UINT64)(RegEax >> 1), RegEax);
+
+  return TscFrequency;
+}
+//
+// OVERRIDE: OverrideEnd
+//
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
new file mode 100644
index 0000000000..2bba58eed3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
@@ -0,0 +1,612 @@
+/** @file
+  Source code for the board configuration init function in DXE init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <Library/HobLib.h>
+#include <MemInfoHob.h>
+#include <Library/PchSerialIoLib.h>
+#include <PlatformBoardConfig.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchEspiLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <TbtBoardInfo.h>
+#include <Library/CpuPlatformLib.h>
+#include <GopConfigLib.h>
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+GopVbtSpecificUpdateNull(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+
+//
+// for CFL U DDR4
+//
+VOID
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+
+/**
+  Updates DIMM slots status for Desktop,server and workstation boards
+
+**/
+VOID
+UpdateDimmPopulationConfig(
+  VOID
+  )
+{
+  MEMORY_INFO_DATA_HOB    *MemInfo;
+  UINT8                   Slot0;
+  UINT8                   Slot1;
+  UINT8                   Slot2;
+  UINT8                   Slot3;
+  CONTROLLER_INFO         *ControllerInfo;
+  EFI_HOB_GUID_TYPE       *GuidHob;
+
+  GuidHob = NULL;
+  MemInfo = NULL;
+
+  GuidHob = GetFirstGuidHob (&gSiMemoryInfoDataGuid);
+  ASSERT (GuidHob != NULL);
+  if (GuidHob != NULL) {
+    MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA (GuidHob);
+  }
+  if (MemInfo != NULL) {
+    if (PcdGet8 (PcdPlatformFlavor) == FlavorDesktop ||
+        PcdGet8 (PcdPlatformFlavor) == FlavorUpServer ||
+        PcdGet8 (PcdPlatformFlavor) == FlavorWorkstation) {
+      ControllerInfo = &MemInfo->Controller[0];
+      Slot0 = ControllerInfo->ChannelInfo[0].DimmInfo[0].Status;
+      Slot1 = ControllerInfo->ChannelInfo[0].DimmInfo[1].Status;
+      Slot2 = ControllerInfo->ChannelInfo[1].DimmInfo[0].Status;
+      Slot3 = ControllerInfo->ChannelInfo[1].DimmInfo[1].Status;
+
+      //
+      // Channel 0          Channel 1
+      // Slot0   Slot1      Slot0   Slot1      - Population            AIO board
+      // 0          0          0          0          - Invalid        - Invalid
+      // 0          0          0          1          - Valid          - Invalid
+      // 0          0          1          0          - Invalid        - Valid
+      // 0          0          1          1          - Valid          - Valid
+      // 0          1          0          0          - Valid          - Invalid
+      // 0          1          0          1          - Valid          - Invalid
+      // 0          1          1          0          - Invalid        - Invalid
+      // 0          1          1          1          - Valid          - Invalid
+      // 1          0          0          0          - Invalid        - Valid
+      // 1          0          0          1          - Invalid        - Invalid
+      // 1          0          1          0          - Invalid        - Valid
+      // 1          0          1          1          - Invalid        - Valid
+      // 1          1          0          0          - Valid          - Valid
+      // 1          1          0          1          - Valid          - Invalid
+      // 1          1          1          0          - Invalid        - Valid
+      // 1          1          1          1          - Valid          - Valid
+      //
+
+      if ((Slot0 && (Slot1 == 0)) || (Slot2 && (Slot3 == 0))) {
+        PcdSetBoolS (PcdDimmPopulationError, TRUE);
+      }
+    }
+  }
+}
+
+/**
+  Init Misc Platform Board Config Block.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInit (
+  IN UINT16 BoardId
+  )
+{
+//  PcdSet64S (PcdFuncBoardHookPlatformSetupOverride, (UINT64) (UINTN) BoardHookPlatformSetup);
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdPssReadSN, TRUE);
+      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
+      PcdSet8S (PcdPssI2cBusNumber, 0x04);
+      break;
+    default:
+      PcdSetBoolS (PcdPssReadSN, FALSE);
+      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
+      PcdSet8S (PcdPssI2cBusNumber, 0x04);
+      break;
+  }
+
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init Platform Board Config Block for ACPI platform.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+InitAcpiPlatformPcd (
+  IN UINT16 BoardId
+  )
+{
+  TBT_INFO_HOB  *TbtInfoHob = NULL;
+
+  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+
+  //
+  // Update OEM table ID
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      if ((TbtInfoHob != NULL) && (TbtInfoHob->DTbtControllerConfig[0].DTbtControllerEn == 1)) {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h', 'l', 't', '4'));
+      } else {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h', 'l', 'd', '4'));
+      }
+      break;
+    default:
+      PcdSet64S (PcdXhciAcpiTableSignature, 0);
+      break;
+  }
+
+  //
+  // Modify Preferred_PM_Profile field based on Board SKU's. Default is set to Mobile
+  //
+  PcdSet8S (PcdPreferredPmProfile, EFI_ACPI_2_0_PM_PROFILE_MOBILE);
+
+  //
+  // Assign FingerPrint, Gnss, TouchPanel, Audio related GPIO.
+  //
+  switch(BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdFingerPrintSleepGpio, GPIO_CNL_LP_GPP_B17);
+      PcdSet32S (PcdFingerPrintIrqGpio,   GPIO_CNL_LP_GPP_B16);
+      //
+      // Configure WWAN Reset pin
+      //
+      PcdSet32S (PcdGnssResetGpio,      GPIO_CNL_LP_GPP_F1);
+      PcdSet32S (PcdTouchpanelIrqGpio,  GPIO_CNL_LP_GPP_D10);
+      PcdSet32S (PcdTouchpadIrqGpio,    GPIO_CNL_LP_GPP_B3);
+      PcdSet32S (PcdHdaI2sCodecIrqGpio, GPIO_CNL_LP_GPP_C8);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Configure GPIOs for discrete USB BT module
+  //
+  switch(BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdBtIrqGpio,    GPIO_CNL_LP_GPP_B2);
+      PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Board Specific Init
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS(PcdWhlErbRtd3TableEnable, TRUE);
+      PcdSet8S (PcdHdaI2sCodecI2cBusNumber, 0); // I2S Audio Codec conntected to I2C0
+      PcdSet8S (PcdBleUsbPortNumber, 9);
+      break;
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init Common Platform Board Config Block.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+InitCommonPlatformPcd (
+  IN UINT16 BoardId
+  )
+{
+  PCD64_BLOB Data64;
+  TBT_INFO_HOB  *TbtInfoHob = NULL;
+
+  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+
+
+  //
+  // Enable EC SMI# for SMI
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdEcSmiGpio, GPIO_CNL_LP_GPP_E3);
+      PcdSet32S (PcdEcLowPowerExitGpio, GPIO_CNL_LP_GPP_B23);
+      break;
+  };
+
+  //
+  // HID I2C Interrupt GPIO.
+  //
+  switch (BoardId) {
+    default:
+      // on all supported boards interrupt input is on same GPIO pad. How convenient.
+      PcdSet32S (PcdHidI2cIntPad, GPIO_CNL_LP_GPP_D10);
+      break;
+  }
+
+  //
+  // PS2 KB Specific Init for Sds Serial platform.
+  //
+  if (BoardId == BoardIdWhiskeyLakeRvp) {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE);
+  } else {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck,  FALSE);
+  }
+
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdSpdAddressOverride, FALSE);
+      break;
+  }
+
+  //
+  // DDISelection
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdDDISelection, 1);
+      break;
+    default:
+      PcdSet8S (PcdDDISelection, 0);
+      break;
+  }
+
+  //
+  // GFX Detect
+  //
+  switch (BoardId) {
+    default:
+      // Not all the boards support GFX_CRB_DET. This is not an error.
+      Data64.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
+      break;
+  }
+
+  PcdSet64S (PcdGfxCrbDetectGpio, Data64.Blob);
+
+  //
+  // USB Type-C
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS(PcdUsbTypeCSupport, TRUE);
+      // Discete Ports
+      PcdSet8S(PcdTypeCPortsSupported, 2);
+      // TBT Port 1  mapping and properties [TBT AIC]
+      PcdSet8S(PcdUsbTypeCPort1, 1);
+      PcdSet8S(PcdUsbTypeCPort1Pch, 5);
+      // TBT Port 2  mapping and properties [TBT AIC]
+      PcdSet8S(PcdUsbTypeCPort2, 2);
+      PcdSet8S(PcdUsbTypeCPort2Pch, 7);
+      break;
+    default:
+      PcdSetBoolS (PcdUsbTypeCSupport, FALSE);
+      break;
+  }
+
+  //
+  // Battery Present
+  //
+  switch (BoardId) {
+  default:
+    PcdSet8S (PcdBatteryPresent, BOARD_REAL_BATTERY_SUPPORTED | BOARD_VIRTUAL_BATTERY_SUPPORTED);
+    break;
+  }
+
+  //
+  // TS-on-DIMM temperature
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdTsOnDimmTemperature, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdTsOnDimmTemperature, FALSE);
+      break;
+  }
+  //
+  // Real Battery 1 Control & Real Battery 2 Control
+  //
+  PcdSet8S (PcdRealBattery1Control, 1);
+  PcdSet8S (PcdRealBattery2Control, 2);
+
+  //
+  // Mipi Camera Sensor
+  //
+  PcdSetBoolS (PcdMipiCamSensor, FALSE);
+  //
+  // Mipi Camera Sensor Link Used
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdMipiCam0LinkUsed, 3);
+      PcdSet8S (PcdMipiCam1LinkUsed, 6);
+      PcdSet8S (PcdMipiCam2LinkUsed, 9);
+      PcdSet8S (PcdMipiCam3LinkUsed, 7);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // H8S2113 SIO
+  //
+  switch(BoardId) {
+    default:
+    PcdSetBoolS (PcdH8S2113SIO, FALSE);
+    break;
+  }
+
+
+  //
+  // NCT6776F COM, SIO & HWMON
+  //
+  PcdSetBoolS (PcdNCT6776FCOM, FALSE);
+  PcdSetBoolS (PcdNCT6776FSIO, FALSE);
+  PcdSetBoolS (PcdNCT6776FHWMON, FALSE);
+
+  //
+  // SMC Runtime Sci Pin
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdSmcRuntimeSciPin, (UINT32) GPIO_CNL_LP_GPP_E16);
+      break;
+    default:
+      PcdSet32S (PcdSmcRuntimeSciPin, 0x00);
+      break;
+  }
+
+  //
+  // Convertable Dock Support
+  //
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdConvertableDockSupport, FALSE);
+      break;
+  }
+
+  //
+  // Ec Hotkey F3, F4, F5, F6, F7 and F8 Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdEcHotKeyF3Support, 1);
+      PcdSet8S (PcdEcHotKeyF4Support, 1);
+      PcdSet8S (PcdEcHotKeyF5Support, 1);
+      PcdSet8S (PcdEcHotKeyF6Support, 1);
+      PcdSet8S (PcdEcHotKeyF7Support, 1);
+      PcdSet8S (PcdEcHotKeyF8Support, 1);
+      break;
+    default:
+      PcdSet8S (PcdEcHotKeyF3Support, 0);
+      PcdSet8S (PcdEcHotKeyF4Support, 0);
+      PcdSet8S (PcdEcHotKeyF5Support, 0);
+      PcdSet8S (PcdEcHotKeyF6Support, 0);
+      PcdSet8S (PcdEcHotKeyF7Support, 0);
+      PcdSet8S (PcdEcHotKeyF8Support, 0);
+      break;
+  }
+
+  //
+  // Virtual Button Volume Up & Done Support
+  // Virtual Button Home Button Support
+  // Virtual Button Rotation Lock Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, TRUE);
+      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, TRUE);
+      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
+      break;
+    default:
+      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
+      break;
+  }
+
+  //
+  // Slate Mode Switch Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdSlateModeSwitchSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdSlateModeSwitchSupport, FALSE);
+      break;
+  }
+
+  //
+  // Ac Dc Auto Switch Support
+  //
+  switch (BoardId) {
+  default:
+    PcdSetBoolS (PcdAcDcAutoSwitchSupport, TRUE);
+    break;
+  }
+
+  //
+  // Pm Power Button Gpio Pin
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3);
+      break;
+    default:
+      PcdSet32S (PcdPmPowerButtonGpioPin, 0x00);
+      break;
+  }
+
+  //
+  // Acpi Enable All Button Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // Acpi Hid Driver Button Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // USB Type C EC less
+  //
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdUsbTypeCEcLess, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check if given rootport has device connected and enable wake capability
+
+  @param[in]  RpNum           An unsigned integer represent the root port number.
+
+  @retval                     TRUE if endpoint was connected
+  @retval                     FALSE if no endpoint was detected
+**/
+BOOLEAN
+IsPcieEndPointPresent (
+  IN UINT8 RpNum
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         RpDev;
+  UINTN         RpFun;
+  UINT64        RpBaseAddress;
+
+  Status = GetPchPcieRpDevFun (RpNum, &RpDev, &RpFun);
+  if (!EFI_ERROR (Status)) {
+    //
+    // check if device is present
+    //
+    RpBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      RpDev,
+                      RpFun,
+                      0
+                      );
+
+    if ((PciSegmentRead16 (RpBaseAddress) != 0xFFFF) &&
+        (PciSegmentRead16 (RpBaseAddress + R_PCH_PCIE_CFG_SLSTS) & B_PCIE_SLSTS_PDS)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+
+}
+
+/**
+  Enable Tier2 GPIO Sci wake capability.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+Tier2GpioWakeSupport (
+  IN UINT16 BoardId
+  )
+{
+  BOOLEAN Tier2GpioWakeEnable;
+
+  Tier2GpioWakeEnable = FALSE;
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // Root port #14: M.2 WLAN
+      //
+      if (IsPcieEndPointPresent (13)) {
+        Tier2GpioWakeEnable = TRUE;
+      }
+      break;
+    default:
+      break;
+  }
+  PcdSetBoolS (PcdGpioTier2WakeEnable, Tier2GpioWakeEnable);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board configuration init function for DXE phase.
+
+  @param  Content  pointer to the buffer contain init information for board init.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+BoardConfigInit (
+    VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT16     BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = InitAcpiPlatformPcd (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = InitCommonPlatformPcd (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = BoardMiscInit (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = Tier2GpioWakeSupport (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
new file mode 100644
index 0000000000..eb7c3bbea0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <CpuPolicyInitDxe.h>
+
+DXE_CPU_POLICY_PROTOCOL mCpuPolicyData;
+
+/**
+  Initialize Intel CPU DXE Platform Policy
+
+  @param[in] ImageHandle        Image handle of this driver.
+
+  @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
+CpuPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS                Status;
+
+  ZeroMem(&mCpuPolicyData, sizeof (DXE_CPU_POLICY_PROTOCOL));
+  mCpuPolicyData.Revision                         = DXE_CPU_POLICY_PROTOCOL_REVISION;
+
+  UpdateDxeSiCpuPolicy(&mCpuPolicyData);
+
+  //
+  // Install CpuInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = CpuInstallPolicyProtocol(ImageHandle, &mCpuPolicyData);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
new file mode 100644
index 0000000000..66aab2d198
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
@@ -0,0 +1,174 @@
+/** @file
+  This file initialises and Installs GopPolicy Protocol.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GopPolicyInitDxe.h"
+#include <Protocol/GopPolicy.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL        mGOPPolicy;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32                     mVbtSize = 0;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS       mVbtAddress = 0;
+
+//
+// Function implementations
+//
+
+/**
+
+  @param[out] CurrentLidStatus
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_UNSUPPORTED
+**/
+
+EFI_STATUS
+EFIAPI
+GetPlatformLidStatus (
+  OUT LID_STATUS *CurrentLidStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  @param[out] CurrentDockStatus
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_UNSUPPORTED
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformDockStatus (
+  OUT DOCK_STATUS  CurrentDockStatus
+  )
+{
+    return EFI_UNSUPPORTED;
+}
+
+
+/**
+
+  @param[out] VbtAddress
+  @param[out] VbtSize
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_FOUND
+**/
+EFI_STATUS
+EFIAPI
+GetVbtData (
+  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
+  OUT UINT32               *VbtSize
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         FvProtocolCount;
+  EFI_HANDLE                    *FvHandles;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  UINTN                         Index;
+  UINT32                        AuthenticationStatus;
+  UINT8                         *Buffer;
+  UINTN                         VbtBufferSize;
+
+  Status = EFI_NOT_FOUND;
+  if ( mVbtAddress == 0) {
+    Fv           = NULL;
+    Buffer       = 0;
+    FvHandles    = NULL;
+    Status = gBS->LocateHandleBuffer (
+                    ByProtocol,
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    NULL,
+                    &FvProtocolCount,
+                    &FvHandles
+                    );
+    if (!EFI_ERROR (Status)) {
+      for (Index = 0; Index < FvProtocolCount; Index++) {
+        Status = gBS->HandleProtocol (
+                        FvHandles[Index],
+                        &gEfiFirmwareVolume2ProtocolGuid,
+                        (VOID **) &Fv
+                        );
+        VbtBufferSize = 0;
+        Status = Fv->ReadSection (
+                       Fv,
+                       PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
+                       EFI_SECTION_RAW,
+                       0,
+                       (VOID **) &Buffer,
+                       &VbtBufferSize,
+                       &AuthenticationStatus
+                       );
+        if (!EFI_ERROR (Status)) {
+          *VbtAddress = (EFI_PHYSICAL_ADDRESS)Buffer;
+          *VbtSize = (UINT32)VbtBufferSize;
+          mVbtAddress = *VbtAddress;
+          mVbtSize = *VbtSize;
+          Status = EFI_SUCCESS;
+          break;
+        }
+      }
+    } else {
+      Status = EFI_NOT_FOUND;
+    }
+
+    if (FvHandles != NULL) {
+      FreePool (FvHandles);
+      FvHandles = NULL;
+    }
+  } else {
+    *VbtAddress = mVbtAddress;
+    *VbtSize = mVbtSize;
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+/**
+Initialize GOP DXE Policy
+
+@param[in] ImageHandle          Image handle of this driver.
+
+@retval EFI_SUCCESS             Initialization complete.
+@retval 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
+GopPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Initialize the EFI Driver Library
+  //
+  SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0);
+
+  mGOPPolicy.Revision                = GOP_POLICY_PROTOCOL_REVISION_03;
+  mGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
+  mGOPPolicy.GetVbtData              = GetVbtData;
+  mGOPPolicy.GetPlatformDockStatus   = GetPlatformDockStatus;
+
+  //
+  // Install protocol to allow access to this Policy.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gGopPolicyProtocolGuid,
+                  &mGOPPolicy,
+                  NULL
+                  );
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
new file mode 100644
index 0000000000..2a1604fa13
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
@@ -0,0 +1,55 @@
+/** @file
+  This file is SampleCode for PCH DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchPolicyInitDxe.h"
+
+//
+// Function implementations
+//
+
+/**
+  Initialize PCH DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @retval EFI_SUCCESS             Initialization complete.
+  @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
+PchPolicyInitDxe (
+  IN EFI_HANDLE                   ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+  PCH_POLICY_PROTOCOL      *PchPolicy;
+
+  //
+  // Call CreatePchDxeConfigBlocks to create & initialize platform policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = CreatePchDxeConfigBlocks (&PchPolicy);
+  DEBUG((DEBUG_INFO, "PchPolicy->TableHeader.NumberOfBlocks = 0x%x\n", PchPolicy->TableHeader.NumberOfBlocks));
+  ASSERT_EFI_ERROR (Status);
+
+  if (mFirmwareConfiguration != FwConfigDefault) {
+    UpdateDxePchPolicy (PchPolicy);
+  }
+
+  //
+  // Install PchInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = PchInstallPolicyProtocol (ImageHandle, PchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
new file mode 100644
index 0000000000..ccaa57ce16
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
@@ -0,0 +1,88 @@
+/** @file
+  This file is a wrapper for Platform Policy driver. Get Setup
+  Value to initialize Intel DXE Platform Policy.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PolicyInitDxe.h"
+#include <CpuSmm.h>
+#include "BoardInitLib.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8            mFirmwareConfiguration = 0;
+
+/**
+  Initialize  DXE Platform Policy
+
+  @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
+PolicyInitDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS           Status;
+
+  Status = BoardConfigInit();
+
+  mFirmwareConfiguration = FwConfigProduction;
+  //
+  // SystemAgent Dxe Platform Policy Initialization
+  //
+  Status = SaPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "SystemAgent Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // PCH Dxe Platform Policy Initialization
+  //
+  Status = PchPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "PCH Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Silicon Dxe Platform Policy Initialization
+  //
+  Status = SiliconPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "Silicon Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // CPU DXE Platform Policy Initialization
+  //
+  Status = CpuPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "Cpu Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+
+  if (PcdGetBool(PcdIntelGopEnable)) {
+    //
+    // GOP Dxe Policy Initialization
+    //
+    Status = GopPolicyInitDxe(ImageHandle);
+    DEBUG((DEBUG_INFO, "GOP Dxe Policy Initialization done\n"));
+    ASSERT_EFI_ERROR(Status);
+  }
+  if (PcdGetBool(PcdTbtEnable)) {
+    //
+    // Update TBT Policy
+    //
+    Status = InstallTbtPolicy (ImageHandle);
+    DEBUG ((DEBUG_INFO, "Install Tbt Policy done\n"));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
new file mode 100644
index 0000000000..c0095c09c3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode for SA DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaPolicyInitDxe.h"
+
+
+//
+// Function implementations
+//
+
+/**
+  Initialize SA DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @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
+SaPolicyInitDxe (
+  IN EFI_HANDLE                   ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+  SA_POLICY_PROTOCOL       *SaPolicy;
+
+  //
+  // Call CreateSaDxeConfigBlocks to create & initialize platform policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = CreateSaDxeConfigBlocks(&SaPolicy);
+  DEBUG((DEBUG_INFO, "SaPolicy->TableHeader.NumberOfBlocks = 0x%x\n ", SaPolicy->TableHeader.NumberOfBlocks));
+  ASSERT_EFI_ERROR(Status);
+
+  UpdateDxeSaPolicyBoardConfig (SaPolicy);
+
+  if (mFirmwareConfiguration != FwConfigDefault) {
+
+    UpdateDxeSaPolicy (SaPolicy);
+  }
+
+  //
+  // Install SaInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SaInstallPolicyProtocol (ImageHandle, SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
new file mode 100644
index 0000000000..15adca5cdd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <SiliconPolicyInitDxe.h>
+#include <Library/BaseLib.h>
+
+DXE_SI_POLICY_PROTOCOL mSiPolicyData  = { 0 };
+
+/**
+  Initilize Intel Cpu DXE Platform Policy
+
+  @param[in] ImageHandle        Image handle of this driver.
+
+  @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
+SiliconPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS Status;
+
+  mSiPolicyData.Revision                         = DXE_SI_POLICY_PROTOCOL_REVISION;
+
+  ///
+  /// Install the DXE_SI_POLICY_PROTOCOL interface
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gDxeSiPolicyProtocolGuid,
+                  &mSiPolicyData,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
new file mode 100644
index 0000000000..7e44f5585a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
@@ -0,0 +1,20 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+///////////////////////////////////////////////////////////////////////////////////
+//Values are set like this to have ASL compiler reserve enough space for objects
+///////////////////////////////////////////////////////////////////////////////////
+//
+// Available Sleep states
+//
+Name(SS1,0)
+Name(SS2,0)
+Name(SS3,1)
+Name(SS4,1)
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
new file mode 100644
index 0000000000..dd85f07bd2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
@@ -0,0 +1,37 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformBoardId.h"
+
+DefinitionBlock (
+  "DSDT.aml",
+  "DSDT",
+  0x02, // DSDT revision.
+        // A Revision field value greater than or equal to 2 signifies that integers
+        // declared within the Definition Block are to be evaluated as 64-bit values
+  "INTEL",   // OEM ID (6 byte string)
+  "WHL     ",// OEM table ID  (8 byte string)
+  0x0 // OEM version of DSDT table (4 byte Integer)
+)
+
+// BEGIN OF ASL SCOPE
+{
+  // Miscellaneous services enabled in Project
+  Include ("AMLUPD.asl")
+  Include ("PciTree.asl")
+  Include ("Platform.asl")
+
+  Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state
+  if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})}
+  if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})}
+  if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})}
+  Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state
+
+}// End of ASL File
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
new file mode 100644
index 0000000000..aa302b6e3b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
@@ -0,0 +1,516 @@
+/** @file
+  This file contains the SystemAgent PCI Configuration space
+  definition.
+  It defines various System Agent PCI Configuration Space registers
+  which will be used to dynamically produce all resources in the Host Bus.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x40),   // EPBAR (0:0:0:40)
+  EPEN, 1,        // Enable
+      , 11,
+  EPBR, 20,       // EPBAR [31:12]
+
+  Offset(0x48),   // MCHBAR (0:0:0:48)
+  MHEN, 1,        // Enable
+      , 14,
+  MHBR, 17,       // MCHBAR [31:15]
+
+  Offset(0x50),   // GGC (0:0:0:50)
+  GCLK, 1,        // GGCLCK
+
+  Offset(0x54),   // DEVEN (0:0:0:54)
+  D0EN, 1,        // DEV0 Enable
+  D1F2, 1,        // DEV1 FUN2 Enable
+  D1F1, 1,        // DEV1 FUN1 Enable
+  D1F0, 1,        // DEV1 FUN0 Enable
+
+  Offset(0x60),   // PCIEXBAR (0:0:0:60)
+  PXEN, 1,        // Enable
+  PXSZ, 2,        // PCI Express Size
+      , 23,
+  PXBR, 6,        // PCI Express BAR [31:26]
+
+  Offset(0x68),   // DMIBAR (0:0:0:68)
+  DIEN, 1,        // Enable
+      , 11,
+  DIBR, 20,       // DMIBAR [31:12]
+
+  Offset(0x70),   // MESEG_BASE (0:0:0:70)
+      , 20,
+  MEBR, 12,       // MESEG_BASE [31:20]
+
+  Offset(0x80),   // PAM0 Register (0:0:0:80)
+  PMLK, 1,        // PAM Lock bit.
+      , 3,
+  PM0H, 2,        // PAM 0, High Nibble
+      , 2,
+
+  Offset(0x81),   // PAM1 Register (0:0:0:81)
+  PM1L, 2,        // PAM1, Low  Nibble
+      , 2,
+  PM1H, 2,        // PAM1, High Nibble
+      , 2,
+
+  Offset(0x82),   // PAM2 Register (0:0:0:82)
+  PM2L, 2,        // PAM2, Low  Nibble
+      , 2,
+  PM2H, 2,        // PAM2, High Nibble
+      , 2,
+
+  Offset(0x83),   // PAM3 Register (0:0:0:83)
+  PM3L, 2,        // PAM3, Low  Nibble
+      , 2,
+  PM3H, 2,        // PAM3, High Nibble
+      , 2,
+
+  Offset(0x84),   // PAM4 Register (0:0:0:84)
+  PM4L, 2,        // PAM4, Low  Nibble
+      , 2,
+  PM4H, 2,        // PAM4, High Nibble
+      , 2,
+
+  Offset(0x85),   // PAM5 Register (0:0:0:85)
+  PM5L, 2,        // PAM5, Low  Nibble
+      , 2,
+  PM5H, 2,        // PAM5, High Nibble
+      , 2,
+
+  Offset(0x86),   // PAM6 Register (0:0:0:86)
+  PM6L, 2,        // PAM6, Low  Nibble
+      , 2,
+  PM6H, 2,        // PAM6, High Nibble
+      , 2,
+
+  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
+      , 20,
+  TUUD, 19,       // TOUUD [38:20]
+
+  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
+      , 20,
+  TLUD, 12,       // TOLUD [31:20]
+
+  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
+      , 7,
+  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus.  This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+  //
+  // Bus Number Allocation: Bus 0 to 0xFF
+  //
+  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+    0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+  //
+  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+  //
+  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+  //
+  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+  //
+  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+  //
+  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+  //
+  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+  //
+  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+  //
+  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+  //
+  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+  //
+  // BIOS Area ( 0xF0000 - 0xFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+//  //
+//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+//  //
+//  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+  //
+  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+  //
+  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+  // (This is dummy range for OS compatibility, will patch it in _CRS)
+  //
+  QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+  if(LEqual(EP_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+  }
+  Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+  if(LEqual(MH_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+  }
+  Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+  if(LEqual(PC_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+  }
+  Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+  if(LEqual(PC_L,0)) {
+    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+  }
+  Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+  if(LEqual(DM_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+  }
+  Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+  //
+  // Fix up Max Bus Number and Length
+  //
+  Store(\_SB.PCI0.GPCL(),Local0)
+  CreateWordField(BUF0, ^PB00._MAX, PBMX)
+  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+  CreateWordField(BUF0, ^PB00._LEN, PBLN)
+  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+  //
+  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+  //
+  If(PM1L)  // \_SB.PCI0
+  {
+    // PAMx != 0.  Set length = 0.
+
+    CreateDwordField(BUF0, ^C000._LEN,C0LN)
+    Store(Zero,C0LN)
+  }
+
+  If(LEqual(PM1L,1))
+  {
+    CreateBitField(BUF0, ^C000._RW,C0RW)
+    Store(Zero,C0RW)
+  }
+
+  If(PM1H)
+  {
+    CreateDwordField(BUF0, ^C400._LEN,C4LN)
+    Store(Zero,C4LN)
+  }
+
+  If(LEqual(PM1H,1))
+  {
+    CreateBitField(BUF0, ^C400._RW,C4RW)
+    Store(Zero,C4RW)
+  }
+
+  If(PM2L)
+  {
+    CreateDwordField(BUF0, ^C800._LEN,C8LN)
+    Store(Zero,C8LN)
+  }
+
+  If(LEqual(PM2L,1))
+  {
+    CreateBitField(BUF0, ^C800._RW,C8RW)
+    Store(Zero,C8RW)
+  }
+
+  If(PM2H)
+  {
+    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+    Store(Zero,CCLN)
+  }
+
+  If(LEqual(PM2H,1))
+  {
+    CreateBitField(BUF0, ^CC00._RW,CCRW)
+    Store(Zero,CCRW)
+  }
+
+  If(PM3L)
+  {
+    CreateDwordField(BUF0, ^D000._LEN,D0LN)
+    Store(Zero,D0LN)
+  }
+
+  If(LEqual(PM3L,1))
+  {
+    CreateBitField(BUF0, ^D000._RW,D0RW)
+    Store(Zero,D0RW)
+  }
+
+  If(PM3H)
+  {
+    CreateDwordField(BUF0, ^D400._LEN,D4LN)
+    Store(Zero,D4LN)
+  }
+
+  If(LEqual(PM3H,1))
+  {
+    CreateBitField(BUF0, ^D400._RW,D4RW)
+    Store(Zero,D4RW)
+  }
+
+  If(PM4L)
+  {
+    CreateDwordField(BUF0, ^D800._LEN,D8LN)
+    Store(Zero,D8LN)
+  }
+
+  If(LEqual(PM4L,1))
+  {
+    CreateBitField(BUF0, ^D800._RW,D8RW)
+    Store(Zero,D8RW)
+  }
+
+  If(PM4H)
+  {
+    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+    Store(Zero,DCLN)
+  }
+
+  If(LEqual(PM4H,1))
+  {
+    CreateBitField(BUF0, ^DC00._RW,DCRW)
+    Store(Zero,DCRW)
+  }
+
+  If(PM5L)
+  {
+    CreateDwordField(BUF0, ^E000._LEN,E0LN)
+    Store(Zero,E0LN)
+  }
+
+  If(LEqual(PM5L,1))
+  {
+    CreateBitField(BUF0, ^E000._RW,E0RW)
+    Store(Zero,E0RW)
+  }
+
+  If(PM5H)
+  {
+    CreateDwordField(BUF0, ^E400._LEN,E4LN)
+    Store(Zero,E4LN)
+  }
+
+  If(LEqual(PM5H,1))
+  {
+    CreateBitField(BUF0, ^E400._RW,E4RW)
+    Store(Zero,E4RW)
+  }
+
+  If(PM6L)
+  {
+    CreateDwordField(BUF0, ^E800._LEN,E8LN)
+    Store(Zero,E8LN)
+  }
+
+  If(LEqual(PM6L,1))
+  {
+    CreateBitField(BUF0, ^E800._RW,E8RW)
+    Store(Zero,E8RW)
+  }
+
+  If(PM6H)
+  {
+    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+    Store(Zero,ECLN)
+  }
+
+  If(LEqual(PM6H,1))
+  {
+    CreateBitField(BUF0, ^EC00._RW,ECRW)
+    Store(Zero,ECRW)
+  }
+
+  If(PM0H)
+  {
+    CreateDwordField(BUF0, ^F000._LEN,F0LN)
+    Store(Zero,F0LN)
+  }
+
+  If(LEqual(PM0H,1))
+  {
+    CreateBitField(BUF0, ^F000._RW,F0RW)
+    Store(Zero,F0RW)
+  }
+
+  //
+  // Create pointers to Memory Sizing values.
+  //
+  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+  //
+  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+  // TOM, so shift these bits into the correct position and fix up
+  // the Memory Region available to PCI.
+  //
+  Store (0x50800000, M1LN)
+  Store (0x8F800000, M1MN)
+  Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+  //
+  // Create pointers to Memory Sizing values.
+  // Patch PM02 range basing on memory size and OS type
+  //
+  CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+  //
+  // Set resource length to 0
+  //
+  Store (0, MSLN)
+
+  D8XH (0, 0xC5)
+  D8XH (1, 0xAA)
+
+  Return(BUF0)
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
new file mode 100644
index 0000000000..ff3b0dbe08
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
@@ -0,0 +1,309 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Scope(\_SB) {
+  Name(PD00, Package(){
+// If the setting changed in PCH PxRcConfig policy, platform should also update static assignment here.
+// PCI Bridge
+// D31: cAVS, SMBus, GbE, Nothpeak
+    Package(){0x001FFFFF, 0, 0, 11 },
+    Package(){0x001FFFFF, 1, 0, 10 },
+    Package(){0x001FFFFF, 2, 0, 11 },
+    Package(){0x001FFFFF, 3, 0, 11 },
+// D30: SerialIo and SCS - can't use PIC
+// D29: PCI Express Port 9-16
+    Package(){0x001DFFFF, 0, 0, 11 },
+    Package(){0x001DFFFF, 1, 0, 10 },
+    Package(){0x001DFFFF, 2, 0, 11 },
+    Package(){0x001DFFFF, 3, 0, 11 },
+// D28: PCI Express Port 1-8
+    Package(){0x001CFFFF, 0, 0, 11 },
+    Package(){0x001CFFFF, 1, 0, 10 },
+    Package(){0x001CFFFF, 2, 0, 11 },
+    Package(){0x001CFFFF, 3, 0, 11 },
+// D27: PCI Express Port 17-20
+    Package(){0x001BFFFF, 0, 0, 11 },
+    Package(){0x001BFFFF, 1, 0, 10 },
+    Package(){0x001BFFFF, 2, 0, 11 },
+    Package(){0x001BFFFF, 3, 0, 11 },
+// D25: SerialIo - can't use PIC
+// D23: SATA controller
+    Package(){0x0017FFFF, 0, 0, 11 },
+// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
+    Package(){0x0016FFFF, 0, 0, 11 },
+    Package(){0x0016FFFF, 1, 0, 10 },
+    Package(){0x0016FFFF, 2, 0, 11 },
+    Package(){0x0016FFFF, 3, 0, 11 },
+// D21: SerialIo - can't use PIC
+// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
+// D20: xHCI, OTG, CNVi WiFi, SDcard
+    Package(){0x0014FFFF, 0, 0, 11 },
+    Package(){0x0014FFFF, 1, 0, 10 },
+    Package(){0x0014FFFF, 2, 0, 11 },
+    Package(){0x0014FFFF, 3, 0, 11 },
+// D19: Integrated Sensor Hub - can't use PIC
+// D18: Thermal, UFS, SerialIo SPI2 - can't use PIC
+    Package(){0x0012FFFF, 0, 0, 11 },
+    Package(){0x0012FFFF, 1, 0, 10 },
+    Package(){0x0012FFFF, 2, 0, 11 },
+    Package(){0x0012FFFF, 3, 0, 11 },
+
+// Host Bridge
+// P.E.G. Root Port D1F0
+    Package(){0x0001FFFF, 0, 0, 11 },
+    Package(){0x0001FFFF, 1, 0, 10 },
+    Package(){0x0001FFFF, 2, 0, 11 },
+    Package(){0x0001FFFF, 3, 0, 11 },
+// P.E.G. Root Port D1F1
+// P.E.G. Root Port D1F2
+// SA IGFX Device
+    Package(){0x0002FFFF, 0, 0, 11 },
+// SA Thermal Device
+    Package(){0x0004FFFF, 0, 0, 11 },
+// SA IPU Device
+    Package(){0x0005FFFF, 0, 0, 11 },
+// SA GNA Device
+    Package(){0x0008FFFF, 0, 0, 11 },
+  })
+  Name(AR00, Package(){
+// PCI Bridge
+// D31: cAVS, SMBus, GbE, Nothpeak
+    Package(){0x001FFFFF, 0, 0, 16 },
+    Package(){0x001FFFFF, 1, 0, 17 },
+    Package(){0x001FFFFF, 2, 0, 18 },
+    Package(){0x001FFFFF, 3, 0, 19 },
+// D30: SerialIo and SCS
+    Package(){0x001EFFFF, 0, 0, 20 },
+    Package(){0x001EFFFF, 1, 0, 21 },
+    Package(){0x001EFFFF, 2, 0, 22 },
+    Package(){0x001EFFFF, 3, 0, 23 },
+// D29: PCI Express Port 9-16
+    Package(){0x001DFFFF, 0, 0, 16 },
+    Package(){0x001DFFFF, 1, 0, 17 },
+    Package(){0x001DFFFF, 2, 0, 18 },
+    Package(){0x001DFFFF, 3, 0, 19 },
+// D28: PCI Express Port 1-8
+    Package(){0x001CFFFF, 0, 0, 16 },
+    Package(){0x001CFFFF, 1, 0, 17 },
+    Package(){0x001CFFFF, 2, 0, 18 },
+    Package(){0x001CFFFF, 3, 0, 19 },
+// D27: PCI Express Port 17-20
+    Package(){0x001BFFFF, 0, 0, 16 },
+    Package(){0x001BFFFF, 1, 0, 17 },
+    Package(){0x001BFFFF, 2, 0, 18 },
+    Package(){0x001BFFFF, 3, 0, 19 },
+// D26: eMMC
+    Package(){0x001AFFFF, 0, 0, 16 },
+    Package(){0x001AFFFF, 1, 0, 17 },
+    Package(){0x001AFFFF, 2, 0, 18 },
+    Package(){0x001AFFFF, 3, 0, 19 },
+// D25: SerialIo
+    Package(){0x0019FFFF, 0, 0, 32 },
+    Package(){0x0019FFFF, 1, 0, 33 },
+    Package(){0x0019FFFF, 2, 0, 34 },
+// D23: SATA controller
+    Package(){0x0017FFFF, 0, 0, 16 },
+// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
+    Package(){0x0016FFFF, 0, 0, 16 },
+    Package(){0x0016FFFF, 1, 0, 17 },
+    Package(){0x0016FFFF, 2, 0, 18 },
+    Package(){0x0016FFFF, 3, 0, 19 },
+// D21: SerialIo
+    Package(){0x0015FFFF, 0, 0, 16 },
+    Package(){0x0015FFFF, 1, 0, 17 },
+    Package(){0x0015FFFF, 2, 0, 18 },
+    Package(){0x0015FFFF, 3, 0, 19 },
+// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
+// D20: xHCI, OTG, CNVi WiFi, SDcard
+    Package(){0x0014FFFF, 0, 0, 16 },
+    Package(){0x0014FFFF, 1, 0, 17 },
+    Package(){0x0014FFFF, 2, 0, 18 },
+    Package(){0x0014FFFF, 3, 0, 19 },
+// D19: Integrated Sensor Hub
+    Package(){0x0013FFFF, 0, 0, 20 },
+// D18: Thermal, UFS, SerialIo SPI 2
+    Package(){0x0012FFFF, 0, 0, 16 },
+    Package(){0x0012FFFF, 1, 0, 24 },
+    Package(){0x0012FFFF, 2, 0, 18 },
+    Package(){0x0012FFFF, 3, 0, 19 },
+
+// Host Bridge
+// P.E.G. Root Port D1F0
+    Package(){0x0001FFFF, 0, 0, 16 },
+    Package(){0x0001FFFF, 1, 0, 17 },
+    Package(){0x0001FFFF, 2, 0, 18 },
+    Package(){0x0001FFFF, 3, 0, 19 },
+// P.E.G. Root Port D1F1
+// P.E.G. Root Port D1F2
+// SA IGFX Device
+    Package(){0x0002FFFF, 0, 0, 16 },
+// SA Thermal Device
+    Package(){0x0004FFFF, 0, 0, 16 },
+// SA IPU Device
+    Package(){0x0005FFFF, 0, 0, 16 },
+// SA GNA Device
+    Package(){0x0008FFFF, 0, 0, 16 },
+  })
+  Name(PD04, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR04, Package(){
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD05, Package(){
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR05, Package(){
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD06, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR06, Package(){
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+  Name(PD07, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 10 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR07, Package(){
+    Package(){0x0000FFFF, 0, 0, 19 },
+    Package(){0x0000FFFF, 1, 0, 16 },
+    Package(){0x0000FFFF, 2, 0, 17 },
+    Package(){0x0000FFFF, 3, 0, 18 },
+  })
+  Name(PD08, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR08, Package(){
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD09, Package(){
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR09, Package(){
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD0E, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR0E, Package(){
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+  Name(PD0F, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 10 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR0F, Package(){
+    Package(){0x0000FFFF, 0, 0, 19 },
+    Package(){0x0000FFFF, 1, 0, 16 },
+    Package(){0x0000FFFF, 2, 0, 17 },
+    Package(){0x0000FFFF, 3, 0, 18 },
+  })
+  Name(PD02, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR02, Package(){
+// P.E.G. Port Slot x16
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD0A, Package(){
+// P.E.G. Port Slot x8
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR0A, Package(){
+// P.E.G. Port Slot x8
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD0B, Package(){
+// P.E.G. Port Slot x4
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR0B, Package(){
+// P.E.G. Port Slot x4
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+
+//---------------------------------------------------------------------------
+// Begin PCI tree object scope
+//---------------------------------------------------------------------------
+  Device(PCI0) { // PCI Bridge "Host Bridge"
+    Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2 host hierarchy
+    Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't understand the new HID
+    Name(_SEG, 0)
+    Name(_ADR, 0x00000000)
+    Method(^BN00, 0){ return(0x0000) }  // Returns default Bus number for Peer PCI busses. Name can be overriden with control method placed directly under Device scope
+    Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root PCI Bus
+    Name(_UID, 0x0000)  // Unique Bus ID, optional
+    Method(_PRT,0) {
+      If(PICM) {Return(AR00)} // APIC mode
+      Return (PD00) // PIC Mode
+    } // end _PRT
+
+  Include("HostBus.asl")
+  } // end PCI0 Bridge "Host Bridge"
+} // end _SB scope
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
new file mode 100644
index 0000000000..951c01455f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
@@ -0,0 +1,76 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+// Define Port 80 as an ACPI Operating Region to use for debugging.  Please
+// note that the Intel CRBs have the ability to ouput a Word to
+// Port 80h for debugging purposes, so the model implemented here may not be
+// able to be used on OEM Designs.
+
+OperationRegion(PRT0,SystemIO,0x80,2)
+Field(PRT0,WordAcc,Lock,Preserve)
+{
+  P80B, 16
+}
+
+// Port 80h Update:
+//    Update 2 bytes of Port 80h.
+//
+//  Arguments:
+//    Arg0: 0 = Write Port 80h
+//          1 = Write Port 81h
+//    Arg1: 8-bit Value to write
+//
+//  Return Value:
+//    None
+
+Name(P80T, 0) // temp buffer for P80
+
+Method(D8XH,2,Serialized)
+{
+  If(LEqual(Arg0,0))    // Write Port 80h
+  {
+    Store(Or(And(P80T,0xFF00),Arg1),P80T)
+  }
+  If(LEqual(Arg0,1))    // Write Port 81h
+  {
+    Store(Or(And(P80T,0x00FF),ShiftLeft(Arg1,8)),P80T)
+  }
+  Store(P80T,P80B)
+}
+
+//
+// Define SW SMI port as an ACPI Operating Region to use for generate SW SMI.
+//
+OperationRegion(SPRT,SystemIO, 0xB2,2)
+Field (SPRT, ByteAcc, Lock, Preserve) {
+  SSMP, 8
+}
+
+// The _PIC Control Method is optional for ACPI design.  It allows the
+// OS to inform the ASL code which interrupt controller is being used,
+// the 8259 or APIC.  The reference code in this document will address
+// PCI IRQ Routing and resource allocation for both cases.
+//
+// The values passed into _PIC are:
+//   0 = 8259
+//   1 = IOAPIC
+
+Method(\_PIC,1)
+{
+  Store(Arg0,PICM)
+}
+
+Scope (\)
+{
+  //
+  // Global Name, returns current Interrupt controller mode;
+  // updated from _PIC control method
+  //
+  Name(PICM, 0)
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
new file mode 100644
index 0000000000..38d60d6dbd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
@@ -0,0 +1,405 @@
+/** @file
+  ACPI RTD3 SSDT table for SPT PCIe
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#define PID_ICC                                   0xDC
+#define R_PCH_PCR_ICC_MSKCKRQ                     0x100C                  ///< Mask Control CLKREQ
+
+External(PCRA,MethodObj)
+External(PCRO,MethodObj)
+External(\MMRP, MethodObj)
+External(\MMTB, MethodObj)
+External(\TRDO, IntObj)
+External(\TRD3, IntObj)
+External(\TBPE, IntObj)
+External(\TOFF, IntObj)
+External(\TBSE, IntObj)
+External(\TBOD, IntObj)
+External(\TBRP, IntObj)
+External(\TBHR, IntObj)
+External(\RTBC, IntObj)
+External(\TBCD, IntObj)
+
+Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
+
+Name(WKEN, 0)
+
+  Method(_S0W, 0)
+  {
+  /// This method returns the lowest D-state supported by PCIe root port during S0 state
+
+   ///- PMEs can be generated from D3hot for ULT
+      Return(4)
+
+  /** @defgroup pcie_s0W PCIE _S0W **/
+  } // End _S0W
+
+  Method (_DSD, 0) {
+    Return (
+      Package () {
+        ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
+        Package () {
+          Package (2) {"HotPlugSupportInD3", 1},
+        }
+      }
+    ) // End of Return ()
+  }
+
+    Method(_DSW, 3)
+    {
+    /// This method is used to enable/disable wake from PCIe (WKEN)
+      If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE# from generating runtime PME
+                                    /// Also set 2 to TOFF.
+        Store(0, WKEN)
+        Store (2, TOFF)
+      } Else {  /// If Staying in S0
+        If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
+        { ///- Set PME
+          Store(1, WKEN)
+          Store (1, TOFF)
+        } Else { ///- Disable runtime PME, either because staying in D0 or disabling wake
+          Store(0, WKEN)
+          Store(0, TOFF)
+        }
+      }
+
+    /** @defgroup pcie_dsw PCIE _DSW **/
+    } // End _DSW
+
+
+    PowerResource(PXP, 0, 0)
+    {
+    /// Define the PowerResource for PCIe slot
+    /// Method: _STA(), _ON(), _OFF()
+    /** @defgroup pcie_pxp PCIE Power Resource **/
+
+      Method(_STA, 0)
+      {
+          Return(PSTA())
+      }  /** @defgroup pcie_sta PCIE _STA method **/
+
+      Method(_ON) /// Turn on core power to PCIe Slot
+      {
+        Store(1, TRDO)
+        PON()
+        Store(0, TRDO)
+      } /** @defgroup pcie_on PCIE _ON method **/
+
+      Method(_OFF) /// Turn off core power to PCIe Slot
+      {
+        Store(1, TRD3)
+        POFF()
+        Store(0, TRD3)
+      } // End of Method_OFF
+    } // End PXP
+
+    Method(PSTA, 0)
+    {
+    /// Returns the status of PCIe slot core power
+      // detect power pin status
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) {
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          if(LEqual(\_SB.GGOV(DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // GPIO mode
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // IOEX mode
+      }
+      // detect reset pin status
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) {
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          if(LEqual(\_SB.GGOV(DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // GPIO mode
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2))  { // IOEX mode
+          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // IOEX mode
+      }
+      Return (0)
+    }  /** @defgroup pcie_sta PCIE _STA method **/
+
+    Method (SXEX, 0, Serialized) {
+
+      Store(\MMTB(TBSE), Local7)
+      OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(100, Local1)
+      Store(0x09, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT
+      While (LGreater(Local1, 0)) {
+
+        Store(Subtract(Local1, 1), Local1)
+        Store(TB2P, Local2)
+        If (LEqual(Local2, 0xFFFFFFFF)) { // Device gone
+          Return()
+        }
+        If (And(Local2, 1)) { // Done
+          break
+        }
+        Sleep(5)
+      }
+      Store(0x0, P2TB) // Write 0 to PCIe2TBT
+
+      // Fast Link bring-up flow
+      Store(500, Local1)
+      While (LGreater(Local1, 0)) {
+        Store(Subtract(Local1, 1), Local1)
+        Store(TB2P, Local2)
+        If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
+          Return()
+        }
+        If (LNotEqual(DIVI, 0xFFFFFFFF)) {
+          break
+        }
+        Sleep(10)
+      }
+    } // End of Method(SXEX, 0, Serialized)
+
+    Method(PON) /// Turn on core power to PCIe Slot
+    {
+
+      Store(\MMRP(\TBSE), Local7)
+      OperationRegion(L23P,SystemMemory,Local7,0xE4)
+      Field(L23P,WordAcc, NoLock, Preserve)
+      {
+        Offset(0xA4),// PMCSR
+        PSD0, 2, // PowerState
+        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+        , 2,
+        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
+        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+      }
+
+      Store(\MMTB(\TBSE), Local6)
+      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0xA4),
+        TBPS, 2, // PowerState of TBT
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(0, TOFF)
+      // Check RTD3 power enable, if already ON, no need to execute sx_exit
+      If (TBPE) {
+        Return()
+      }
+
+      Store(0,G2SD)
+      If (\RTBC) {
+        /// de-assert CLK_REQ MSK
+        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+          PCRA(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,Not(DeRefOf(Index(SCLK, 1))))  // And ~SCLK to clear bit
+        }
+        Sleep(\TBCD)
+      }
+
+      /// Turn ON Power for PCIe Slot
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+          Store(1, TBPE)
+          Sleep(PEP0)     /// Sleep for programmable delay
+        }
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+          Store(1, TBPE)
+          Sleep(PEP0)     /// Sleep for programmable delay
+        }
+      }
+
+      /// De-Assert Reset Pin
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+        }
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+        }
+      }
+
+      /// Clear DLSULPPGE, then set L23_Rdy to Detect Transition  (L23R2DT)
+      Store(0, DPGE)
+      Store(1, L2TR)
+      Sleep(16)
+      Store(0, Local0)
+      /// Wait up to 12 ms for transition to Detect
+      While(L2TR) {
+        If(Lgreater(Local0, 4))    // Debug - Wait for 5 ms
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      /// 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(1, DPGE)
+      Store(0, Local0)
+      While(LEqual(LASX,0)) {
+        If(Lgreater(Local0, 8))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(0, LEDM) /// Set PCIEDBG.DMIL1EDM (324[3]) = 0
+
+      // TBT special sleep.
+      Store(PSD0, Local1)
+      Store(0, PSD0)// D0
+      Store(20, Local2) // Poll for TBT, up to 200 ms
+
+      While (LGreater(Local2, 0)) {
+        Store(Subtract(Local2, 1), Local2)
+        Store(TB2P, Local3)
+        If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
+          break
+        }
+        Sleep(10)
+      }
+
+      If (LLessEqual(Local2, 0)) {
+      }
+      SXEX()
+      Store(Local1, PSD0) // Back to Local1
+    } /** @defgroup pcie_on PCIE _ON method **/
+
+    Method(POFF) { /// Turn off core power to PCIe Slot
+      If (LEqual(TOFF, 0)) {
+        Return()
+      }
+      Store(\MMRP(\TBSE), Local7)
+      OperationRegion(L23P, SystemMemory, Local7, 0xE4)
+      Field(L23P,WordAcc, NoLock, Preserve)
+      {
+        Offset(0xA4),// PMCSR
+        PSD0, 2, // PowerState
+        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+        , 2,
+        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
+        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+      }
+
+      Store(\MMTB(TBSE), Local6)
+      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0xA4),
+        TBPS, 2, // PowerState of TBT
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(PSD0, Local1)
+      Store(0, PSD0)// D0
+
+      Store(P2TB, Local3)
+
+      If (Lgreater(TOFF, 1)) {
+        Sleep(10)
+        Store(Local1, PSD0) // Back to Local1
+        Return()
+      }
+      Store(0, TOFF)
+
+      Store(Local1, PSD0) // Back to Local1
+
+      /// Set L23_Rdy Entry Request (L23ER)
+      Store(1, L2TE)
+      Sleep(16)
+      Store(0, Local0)
+      While(L2TE) {
+        If(Lgreater(Local0, 4))    /// Debug - Wait for 5 ms
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(1, LEDM) /// PCIEDBG.DMIL1EDM (324[3]) = 1
+
+      /// Assert Reset Pin
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+        }
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+        }
+      }
+      If (\RTBC) {
+        /// assert CLK_REQ MSK
+        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+          PCRO(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,DeRefOf(Index(SCLK, 1)))    // Or SCLK to set bit
+          Sleep(16)
+        }
+      }
+
+      /// Power OFF for TBT
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+        }
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+        }
+      }
+
+      Store(0, TBPE)
+
+      Store(1, LDIS) /// Set Link Disable
+      Store(0, LDIS) /// Toggle link disable
+
+      /// enable WAKE
+      If (WKEN) {
+        If (LNotEqual(DeRefOf(Index(WAKG, 0)),0)) { // if power gating enabled
+          If (LEqual(DeRefOf(Index(WAKG, 0)),1)) { // GPIO mode
+            \_SB.SGOV(DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+            \_SB.SHPO(DeRefOf(Index(WAKG, 2)), 0) // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+          }
+          If (LEqual(DeRefOf(Index(WAKG, 0)),2))  { // IOEX mode
+            \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG, 1)),DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+          }
+        }
+      }
+      Sleep(\TBOD)
+      /** @defgroup pcie_off PCIE _OFF method **/
+    } // End of Method_OFF
+
+    Name(_PR0, Package(){PXP})
+    Name(_PR3, Package(){PXP})
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
new file mode 100644
index 0000000000..66584c21c5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
@@ -0,0 +1,1877 @@
+/** @file
+ Thunderbolt ACPI methods
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#define DTBT_CONTROLLER                   0x00
+#define DTBT_TYPE_PCH                     0x01
+#define DTBT_TYPE_PEG                     0x02
+#define DTBT_SMI_HANDLER_NUMBER           0xF7
+#define TBT_SMI_ENUMERATION_FUNCTION      21
+#define TBT_SMI_RESET_SWITCH_FUNCTION     22
+#define TBT_SMI_DISABLE_MSI_FUNCTION      23
+#ifndef  BIT29
+#define  BIT29    0x20000000
+#endif
+
+Name(LDLY, 300) //300 ms
+Name (TNVB, 0xFFFF0000)  // TBT NVS Base address
+Name (TNVL, 0xAA55)      // TBT NVS Length
+Include ("Acpi/TbtNvs.asl")
+
+External(\_SB.PCI0.RP02.L23D, MethodObj)
+External(\_SB.PCI0.RP03.L23D, MethodObj)
+External(\_SB.PCI0.RP04.L23D, MethodObj)
+External(\_SB.PCI0.RP05.L23D, MethodObj)
+External(\_SB.PCI0.RP06.L23D, MethodObj)
+External(\_SB.PCI0.RP07.L23D, MethodObj)
+External(\_SB.PCI0.RP08.L23D, MethodObj)
+External(\_SB.PCI0.RP09.L23D, MethodObj)
+External(\_SB.PCI0.RP10.L23D, MethodObj)
+External(\_SB.PCI0.RP11.L23D, MethodObj)
+External(\_SB.PCI0.RP12.L23D, MethodObj)
+External(\_SB.PCI0.RP13.L23D, MethodObj)
+External(\_SB.PCI0.RP14.L23D, MethodObj)
+External(\_SB.PCI0.RP15.L23D, MethodObj)
+External(\_SB.PCI0.RP16.L23D, MethodObj)
+External(\_SB.PCI0.RP17.L23D, MethodObj)
+External(\_SB.PCI0.RP18.L23D, MethodObj)
+External(\_SB.PCI0.RP19.L23D, MethodObj)
+External(\_SB.PCI0.RP20.L23D, MethodObj)
+External(\_SB.PCI0.RP21.L23D, MethodObj)
+External(\_SB.PCI0.RP22.L23D, MethodObj)
+External(\_SB.PCI0.RP23.L23D, MethodObj)
+External(\_SB.PCI0.RP24.L23D, MethodObj)
+
+External(\_SB.PCI0.RP01.DL23, MethodObj)
+External(\_SB.PCI0.RP02.DL23, MethodObj)
+External(\_SB.PCI0.RP03.DL23, MethodObj)
+External(\_SB.PCI0.RP04.DL23, MethodObj)
+External(\_SB.PCI0.RP05.DL23, MethodObj)
+External(\_SB.PCI0.RP06.DL23, MethodObj)
+External(\_SB.PCI0.RP07.DL23, MethodObj)
+External(\_SB.PCI0.RP08.DL23, MethodObj)
+External(\_SB.PCI0.RP09.DL23, MethodObj)
+External(\_SB.PCI0.RP10.DL23, MethodObj)
+External(\_SB.PCI0.RP11.DL23, MethodObj)
+External(\_SB.PCI0.RP12.DL23, MethodObj)
+External(\_SB.PCI0.RP13.DL23, MethodObj)
+External(\_SB.PCI0.RP14.DL23, MethodObj)
+External(\_SB.PCI0.RP15.DL23, MethodObj)
+External(\_SB.PCI0.RP16.DL23, MethodObj)
+External(\_SB.PCI0.RP17.DL23, MethodObj)
+External(\_SB.PCI0.RP18.DL23, MethodObj)
+External(\_SB.PCI0.RP19.DL23, MethodObj)
+External(\_SB.PCI0.RP20.DL23, MethodObj)
+External(\_SB.PCI0.RP21.DL23, MethodObj)
+External(\_SB.PCI0.RP22.DL23, MethodObj)
+External(\_SB.PCI0.RP23.DL23, MethodObj)
+External(\_SB.PCI0.RP24.DL23, MethodObj)
+
+External(\_SB.PCI0.RTEN, MethodObj)
+External(\_SB.PCI0.RTDS, MethodObj)
+External(\_SB.PCI0.RP01.PON, MethodObj)
+External(\_SB.PCI0.RP02.PON, MethodObj)
+External(\_SB.PCI0.RP03.PON, MethodObj)
+External(\_SB.PCI0.RP04.PON, MethodObj)
+External(\_SB.PCI0.RP05.PON, MethodObj)
+External(\_SB.PCI0.RP06.PON, MethodObj)
+External(\_SB.PCI0.RP07.PON, MethodObj)
+External(\_SB.PCI0.RP08.PON, MethodObj)
+External(\_SB.PCI0.RP09.PON, MethodObj)
+External(\_SB.PCI0.RP10.PON, MethodObj)
+External(\_SB.PCI0.RP11.PON, MethodObj)
+External(\_SB.PCI0.RP12.PON, MethodObj)
+External(\_SB.PCI0.RP13.PON, MethodObj)
+External(\_SB.PCI0.RP14.PON, MethodObj)
+External(\_SB.PCI0.RP15.PON, MethodObj)
+External(\_SB.PCI0.RP16.PON, MethodObj)
+External(\_SB.PCI0.RP17.PON, MethodObj)
+External(\_SB.PCI0.RP18.PON, MethodObj)
+External(\_SB.PCI0.RP19.PON, MethodObj)
+External(\_SB.PCI0.RP20.PON, MethodObj)
+External(\_SB.PCI0.RP21.PON, MethodObj)
+External(\_SB.PCI0.RP22.PON, MethodObj)
+External(\_SB.PCI0.RP23.PON, MethodObj)
+External(\_SB.PCI0.RP24.PON, MethodObj)
+External(\_SB.PCI0.PEG0.PG00._ON, MethodObj)
+External(\_SB.PCI0.PEG1.PG01._ON, MethodObj)
+External(\_SB.PCI0.PEG2.PG02._ON, MethodObj)
+
+Name(TRDO, 0) // 1 during TBT RTD3 _ON
+Name(TRD3, 0) // 1 during TBT RTD3 _OFF
+Name(TBPE, 0) // Reflects RTD3_PWR_EN value
+Name(TOFF, 0) // param to TBT _OFF method
+
+  Method (TBON, 0, Serialized) {
+    // TBT On process before entering Sx state.
+    Store(1, TRDO)
+    Switch (ToInteger(\RPS0)) { // TBT Root port Selector
+      Case (1) {
+        If (CondRefOf(\_SB.PCI0.RP01.PON)) {
+          \_SB.PCI0.RP01.PON()
+        }
+      }
+      Case (2) {
+        If (CondRefOf(\_SB.PCI0.RP02.PON)) {
+          \_SB.PCI0.RP02.PON()
+        }
+      }
+      Case (3) {
+        If (CondRefOf(\_SB.PCI0.RP03.PON)) {
+          \_SB.PCI0.RP03.PON()
+        }
+      }
+      Case (4) {
+        If (CondRefOf(\_SB.PCI0.RP04.PON)) {
+          \_SB.PCI0.RP04.PON()
+        }
+      }
+      Case (5) {
+        If (CondRefOf(\_SB.PCI0.RP05.PON)) {
+          \_SB.PCI0.RP05.PON()
+        }
+      }
+      Case (6) {
+        If (CondRefOf(\_SB.PCI0.RP06.PON)) {
+          \_SB.PCI0.RP06.PON()
+        }
+      }
+      Case (7) {
+        If (CondRefOf(\_SB.PCI0.RP07.PON)) {
+          \_SB.PCI0.RP07.PON()
+        }
+      }
+      Case (8) {
+        If (CondRefOf(\_SB.PCI0.RP08.PON)) {
+          \_SB.PCI0.RP08.PON()
+        }
+      }
+      Case (9) {
+        If (CondRefOf(\_SB.PCI0.RP09.PON)) {
+          \_SB.PCI0.RP09.PON()
+        }
+      }
+      Case (10) {
+        If (CondRefOf(\_SB.PCI0.RP10.PON)) {
+          \_SB.PCI0.RP10.PON()
+        }
+      }
+      Case (11) {
+        If (CondRefOf(\_SB.PCI0.RP11.PON)) {
+          \_SB.PCI0.RP11.PON()
+        }
+      }
+      Case (12) {
+        If (CondRefOf(\_SB.PCI0.RP12.PON)) {
+          \_SB.PCI0.RP12.PON()
+        }
+      }
+      Case (13) {
+        If (CondRefOf(\_SB.PCI0.RP13.PON)) {
+          \_SB.PCI0.RP13.PON()
+        }
+      }
+      Case (14) {
+        If (CondRefOf(\_SB.PCI0.RP14.PON)) {
+          \_SB.PCI0.RP14.PON()
+        }
+      }
+      Case (15) {
+        If (CondRefOf(\_SB.PCI0.RP15.PON)) {
+          \_SB.PCI0.RP15.PON()
+        }
+      }
+      Case (16) {
+        If (CondRefOf(\_SB.PCI0.RP16.PON)) {
+          \_SB.PCI0.RP16.PON()
+        }
+      }
+      Case (17) {
+        If (CondRefOf(\_SB.PCI0.RP17.PON)) {
+          \_SB.PCI0.RP17.PON()
+        }
+      }
+      Case (18) {
+        If (CondRefOf(\_SB.PCI0.RP18.PON)) {
+          \_SB.PCI0.RP18.PON()
+        }
+      }
+      Case (19) {
+        If (CondRefOf(\_SB.PCI0.RP19.PON)) {
+          \_SB.PCI0.RP19.PON()
+        }
+      }
+      Case (20) {
+        If (CondRefOf(\_SB.PCI0.RP20.PON)) {
+          \_SB.PCI0.RP20.PON()
+        }
+      }
+      Case (21) {
+        If (CondRefOf(\_SB.PCI0.RP21.PON)) {
+          \_SB.PCI0.RP21.PON()
+        }
+      }
+      Case (22) {
+        If (CondRefOf(\_SB.PCI0.RP22.PON)) {
+          \_SB.PCI0.RP22.PON()
+        }
+      }
+      Case (23) {
+        If (CondRefOf(\_SB.PCI0.RP23.PON)) {
+          \_SB.PCI0.RP23.PON()
+        }
+      }
+      Case (24) {
+        If (CondRefOf(\_SB.PCI0.RP24.PON)) {
+          \_SB.PCI0.RP24.PON()
+        }
+      }
+    }//Switch(ToInteger(RPS0)) // TBT Selector
+    Store(0, TRDO)
+  } // End of TBON
+  //
+  // Name: TBTD
+  // Description: Function to return the TBT RP# device no
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: TBT RP# device no
+  //
+  Method(TBTD,2)
+  {
+    ADBG("TBTD")
+    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (Package () {1, 2, 3, 4, 5, 6, 7, 8})
+        {
+          Store(0x1C, Local0) //Device28-Function0...Function7 = 11100.000...111
+        }
+        Case (Package () {9, 10, 11, 12, 13, 14, 15, 16})
+        {
+          Store(0x1D, Local0) //Device29-Function0...Function7 = 11101.000...111
+        }
+        Case (Package () {17, 18, 19, 20, 21, 22, 23, 24})
+        {
+          Store(0x1B, Local0) //Device27-Function0...Function3 = 11011.000...011
+        }
+      }
+    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (Package () {1, 2, 3})
+        {
+          Store(0x1, Local0) //Device1-Function0...Function2 = 00001.000...010
+        }
+      }
+    } Else {
+      Store(0xFF, Local0)
+    }
+
+    ADBG("Device no")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(TBTD,1)
+
+  //
+  // Name: TBTF
+  // Description: Function to return the TBT RP# function no
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: TBT RP# function no
+  //
+  Method(TBTF,2)
+  {
+    ADBG("TBTF")
+    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (1)
+        {
+          Store(And(\RPA1,0xF), Local0) //Device28-Function0 = 11100.000
+        }
+        Case (2)
+        {
+          Store(And(\RPA2,0xF), Local0) //Device28-Function1 = 11100.001
+        }
+        Case (3)
+        {
+          Store(And(\RPA3,0xF), Local0) //Device28-Function2 = 11100.010
+        }
+        Case (4)
+        {
+          Store(And(\RPA4,0xF), Local0) //Device28-Function3 = 11100.011
+        }
+        Case (5)
+        {
+          Store(And(\RPA5,0xF), Local0) //Device28-Function4 = 11100.100
+        }
+        Case (6)
+        {
+          Store(And(\RPA6,0xF), Local0) //Device28-Function5 = 11100.101
+        }
+        Case (7)
+        {
+          Store(And(\RPA7,0xF), Local0) //Device28-Function6 = 11100.110
+        }
+        Case (8)
+        {
+          Store(And(\RPA8,0xF), Local0) //Device28-Function7 = 11100.111
+        }
+        Case (9)
+        {
+          Store(And(\RPA9,0xF), Local0) //Device29-Function0 = 11101.000
+        }
+        Case (10)
+        {
+          Store(And(\RPAA,0xF), Local0) //Device29-Function1 = 11101.001
+        }
+        Case (11)
+        {
+          Store(And(\RPAB,0xF), Local0) //Device29-Function2 = 11101.010
+        }
+        Case (12)
+        {
+          Store(And(\RPAC,0xF), Local0) //Device29-Function3 = 11101.011
+        }
+        Case (13)
+        {
+          Store(And(\RPAD,0xF), Local0) //Device29-Function4 = 11101.100
+        }
+        Case (14)
+        {
+          Store(And(\RPAE,0xF), Local0) //Device29-Function5 = 11101.101
+        }
+        Case (15)
+        {
+          Store(And(\RPAF,0xF), Local0) //Device29-Function6 = 11101.110
+        }
+        Case (16)
+        {
+          Store(And(\RPAG,0xF), Local0) //Device29-Function7 = 11101.111
+        }
+        Case (17)
+        {
+          Store(And(\RPAH,0xF), Local0) //Device27-Function0 = 11011.000
+        }
+        Case (18)
+        {
+          Store(And(\RPAI,0xF), Local0) //Device27-Function1 = 11011.001
+        }
+        Case (19)
+        {
+          Store(And(\RPAJ,0xF), Local0) //Device27-Function2 = 11011.010
+        }
+        Case (20)
+        {
+          Store(And(\RPAK,0xF), Local0) //Device27-Function3 = 11011.011
+        }
+        Case (21)
+        {
+          Store(And(\RPAL,0xF), Local0) //Device27-Function4 = 11011.100
+        }
+        Case (22)
+        {
+          Store(And(\RPAM,0xF), Local0) //Device27-Function5 = 11011.101
+        }
+        Case (23)
+        {
+          Store(And(\RPAN,0xF), Local0) //Device27-Function6 = 11011.110
+        }
+        Case (24)
+        {
+          Store(And(\RPAO,0xF), Local0) //Device27-Function7 = 11011.111
+        }
+      }
+    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (1)
+        {
+          Store(0x0, Local0) //Device1-Function0 = 00001.000
+        }
+        Case (2)
+        {
+          Store(0x1, Local0) //Device1-Function1 = 00001.001
+        }
+        Case (3)
+        {
+          Store(0x2, Local0) //Device1-Function2 = 00001.010
+        }
+      }
+    } Else {
+      Store(0xFF, Local0)
+    }
+
+    ADBG("Function no")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(TBTF,1)
+
+  //
+  // Name: MMRP
+  // Description: Function to return the Pci base address of TBT rootport
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(MMRP, 2, Serialized)
+  {
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    Return(Local0)
+  } // End of Method(MMRP)
+
+  //
+  // Name: MMRP
+  // Description: Function to return the Pci base address of TBT Up stream port
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+  Method(MMTB, 2, Serialized)
+  {
+    ADBG("MMTB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x19),
+      SBUS, 8
+    }
+    Store(SBUS, Local2)
+    Store(\_SB.PCI0.GPCB(), Local0)
+    Multiply(Local2, 0x100000, Local2)
+    Add(Local2, Local0, Local0) // TBT HR US port
+
+    ADBG("TBT-US-ADR")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(MMTB, 1, Serialized)
+  //
+  // Name: FFTB
+  // Description: Function to  Check for FFFF in TBT PCIe
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: 1 if TBT PCIe space has value FFFF, 0 if not
+  //
+  Method(FFTB, 2, Serialized)
+  {
+    ADBG("FFTB")
+
+    Add(MMTB(Arg0, Arg1), 0x548, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x08)
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      TB2P, 32,
+      P2TB, 32
+    }
+
+    Store(TB2P, Local1)
+
+    If(LEqual(Local1, 0xFFFFFFFF))
+    {
+      ADBG("FFTb 1")
+      Return (1)
+    }
+    Else
+    {
+      ADBG("FFTb 0")
+      Return (0)
+    }
+  } // End of Method(FFTB)
+
+Name(TDMA, 0x80000000) // Address of Thunderbolt(TM) debug memory buffer, fixed up during POST
+
+Scope(\_GPE)
+{
+  //
+  //
+  //OS up Mail Box command execution to host router upstream port each time
+  //exiting from Sx State .Avoids intermediate
+  //PCIe Scan by OS during resorce allocation
+  // Arg0 : PCIe Base address
+  // Arg1 : Controller Type 0x00 : DTBT
+  //Developer notes: Called twice
+  // 1. During OS INIT (booting to OS from S3-S5/Reboot)
+  // 2. Up on Hot plug
+  //
+  Method(OSUP, 2, Serialized)
+  {
+    ADBG("OSUP")
+
+    Add(Arg0, 0x540, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x10)
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      IT2P, 32,
+      IP2T, 32,
+      DT2P, 32,
+      DP2T, 32
+    }
+
+    Store(100, Local1)
+    Store(0x0D, DP2T) // Write OS_Up to PCIe2TBT
+
+    While(LGreater(Local1, 0))
+    {
+      Store(Subtract(Local1, 1), Local1)
+      Store(DT2P, Local2)
+
+      If(LAnd(LEqual(Local2, 0xFFFFFFFF),LEqual(Arg1, DTBT_CONTROLLER)))// Device gone
+      {
+        ADBG("Dev gone")
+        Return(2)
+      }
+      If(And(Local2, 1)) // Done
+      {
+        ADBG("Cmd acknowledged")
+        break
+      }
+      Sleep(50)
+    }
+    If(LEqual(TRWA,1))
+    {
+      Store(0xC, DP2T) // Write OSUP to PCIe2TBT
+    }
+    Else
+    {
+      Store(0x0, DP2T) // Write 0 to PCIe2TBT
+    }
+
+    //Store(0x00, P2TB) // Write 0 to PCIe2TBT
+
+    ADBG("End-of-OSUP")
+
+    Return(1)
+  } // End of Method(OSUP, 1, Serialized)
+
+  //
+  // Check for FFFF in TBT
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TBFF, 2, Serialized)
+  {
+    ADBG("TBFF")
+
+    Store(MMTB(Arg0, Arg1), Local0)
+    OperationRegion (PXVD, SystemMemory, Local0, 0x8)
+    Field (PXVD, DWordAcc, NoLock, Preserve) {
+      VEDI, 32, // Vendor/Device ID
+      CMDR, 32 // CMD register
+    }
+
+    Store(VEDI, Local1)
+
+    If (LEqual(Local1, 0xFFFFFFFF)) {
+      If (LNotEqual(\TWIN, 0)) { // TBT Enumeration is Native mode?
+        If (LEqual(CMDR, 0xFFFFFFFF)) { // Device Gone
+          Return (2)// Notify only
+        }
+        Return (1)// Exit w/o notify
+      } Else {
+        Return (OSUP(Local0, DTBT_CONTROLLER))
+      }
+    } Else
+    {
+      ADBG("Dev Present")
+      Return (0)
+    }
+  } // End of Method(TBFF, 1, Serialized)
+
+  //
+  // Secondary bus of TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TSUB, 2, Serialized)
+  {
+    ADBG("TSUB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    ADBG("ADR")
+    ADBG(Local0)
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x19),
+      SBUS, 8
+    }
+
+    ADBG("Sec Bus")
+    ADBG(SBUS)
+
+    Return(SBUS)
+  } // End of Method(TSUB, 0, Serialized)
+
+  //
+  // Pmem of TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TSUP, 2, Serialized)
+  {
+    ADBG("TSUB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    ADBG("ADR:")
+    ADBG(Local0)
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x30)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      CMDS, 32,
+      Offset(0x19),
+      SBUS, 8,
+      SBU5, 8,
+      Offset(0x1C),
+      SEIO, 32,
+      MMBL, 32,
+      PMBL, 32,
+
+    }
+
+    ADBG("Pmem of TBT RP:")
+    ADBG(PMBL)
+
+    Return(PMBL)
+  } // End of Method(TSUP, 0, Serialized)
+
+  //
+  // Wait for secondary bus in TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(WSUB, 2, Serialized)
+  {
+    ADBG(Concatenate("WSUB=", ToHexString(Arg0)))
+    ADBG(ToHexString(Timer))
+
+    Store(0, Local0)
+    Store(0, Local1)
+    While(1)
+    {
+      Store(TSUP(Arg0, Arg1), Local1)
+      If(LGreater(Local1, 0x1FFF1))
+      {
+        ADBG("WSUB-Finished")
+        Break
+      }
+      Else
+      {
+        Add(Local0, 1, Local0)
+        If(LGreater(Local0, 1000))
+        {
+          Sleep(1000)
+          ADBG("WSUB-Deadlock")
+        }
+        Else
+        {
+          Sleep(16)
+        }
+      }
+    }
+     ADBG(Concatenate("WSUb=", ToHexString(Local1)))
+  } // End of Method(WSUB)
+
+  // Wait for _WAK finished
+  Method(WWAK)
+  {
+    ADBG("WWAK")
+
+    Wait(WFEV, 0xFFFF)
+    Signal(WFEV) // Set it, to enter on next HP
+  } // End of Method(WWAK)
+
+  Method(NTFY, 2, Serialized)
+  {
+    ADBG("NTFY")
+
+    If(LEqual(NOHP,1))
+    {
+      If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+        Switch(ToInteger(Arg0)) // TBT Selector
+        {
+          Case (1)
+          {
+            ADBG("Notify RP01")
+            Notify(\_SB.PCI0.RP01,0)
+          }
+          Case (2)
+          {
+            ADBG("Notify RP02")
+            Notify(\_SB.PCI0.RP02,0)
+          }
+          Case (3)
+          {
+            ADBG("Notify RP03")
+            Notify(\_SB.PCI0.RP03,0)
+          }
+          Case (4)
+          {
+            ADBG("Notify RP04")
+            Notify(\_SB.PCI0.RP04,0)
+          }
+          Case (5)
+          {
+            ADBG("Notify RP05")
+            Notify(\_SB.PCI0.RP05,0)
+          }
+          Case (6)
+          {
+            ADBG("Notify RP06")
+            Notify(\_SB.PCI0.RP06,0)
+          }
+          Case (7)
+          {
+            ADBG("Notify RP07")
+            Notify(\_SB.PCI0.RP07,0)
+          }
+          Case (8)
+          {
+            ADBG("Notify RP08")
+            Notify(\_SB.PCI0.RP08,0)
+          }
+          Case (9)
+          {
+            ADBG("Notify RP09")
+            Notify(\_SB.PCI0.RP09,0)
+          }
+          Case (10)
+          {
+            ADBG("Notify RP10")
+            Notify(\_SB.PCI0.RP10,0)
+          }
+          Case (11)
+          {
+            ADBG("Notify RP11")
+            Notify(\_SB.PCI0.RP11,0)
+          }
+          Case (12)
+          {
+            ADBG("Notify RP12")
+            Notify(\_SB.PCI0.RP12,0)
+          }
+          Case (13)
+          {
+            ADBG("Notify RP13")
+            Notify(\_SB.PCI0.RP13,0)
+          }
+          Case (14)
+          {
+            ADBG("Notify RP14")
+            Notify(\_SB.PCI0.RP14,0)
+          }
+          Case (15)
+          {
+            ADBG("Notify RP15")
+            Notify(\_SB.PCI0.RP15,0)
+          }
+          Case (16)
+          {
+            ADBG("Notify RP16")
+            Notify(\_SB.PCI0.RP16,0)
+          }
+          Case (17)
+          {
+            ADBG("Notify RP17")
+            Notify(\_SB.PCI0.RP17,0)
+          }
+          Case (18)
+          {
+            ADBG("Notify RP18")
+            Notify(\_SB.PCI0.RP18,0)
+          }
+          Case (19)
+          {
+            ADBG("Notify RP19")
+            Notify(\_SB.PCI0.RP19,0)
+          }
+          Case (20)
+          {
+            ADBG("Notify RP20")
+            Notify(\_SB.PCI0.RP20,0)
+          }
+          Case (21)
+          {
+            ADBG("Notify RP21")
+            Notify(\_SB.PCI0.RP21,0)
+          }
+          Case (22)
+          {
+            ADBG("Notify RP22")
+            Notify(\_SB.PCI0.RP22,0)
+          }
+          Case (23)
+          {
+            ADBG("Notify RP23")
+            Notify(\_SB.PCI0.RP23,0)
+          }
+          Case (24)
+          {
+            ADBG("Notify RP24")
+            Notify(\_SB.PCI0.RP24,0)
+          }
+        }//Switch(ToInteger(TBSS)) // TBT Selector
+      } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+        Switch(ToInteger(Arg0))
+        {
+          Case (1)
+          {
+            ADBG("Notify PEG0")
+            Notify(\_SB.PCI0.PEG0,0)
+          }
+          Case (2)
+          {
+            ADBG("Notify PEG1")
+            Notify(\_SB.PCI0.PEG1,0)
+          }
+          Case (3)
+          {
+            ADBG("Notify PEG2")
+            Notify(\_SB.PCI0.PEG2,0)
+          }
+        }
+      }//Switch(ToInteger(TBSS)) // TBT Selector
+    }//If(NOHP())
+    P8XH(0,0xC2)
+    P8XH(1,0xC2)
+  }// End of Method(NTFY)
+
+//
+//  TBT BIOS, GPIO 5 filtering,
+//  Hot plug of 12V USB devices, into TBT host router, cause electrical noise on PCH GPIOs,
+//  This noise cause false hot-plug events, and negatively influence BIOS assisted hot-plug.
+//  WHL-PCH GPIO does not implement Glitch Filter logic (refer to GPIO HAS) on any GPIO pad. Native functions have to implement their own digital glitch-filter logic
+//  if needed. As HW filter was not implemented on WHL PCH, because of that SW workaround should be implemented in BIOS.
+//  Register 0x544(Bios mailbox) bit 0 definition:
+//  if BIOS reads bit as 1, BIOS will clear the bit and continue normal flow, if bit is 0 BIOS will exit from method
+//
+
+  Method(GNIS,2, Serialized)
+  {
+
+    ADBG("GNIS")
+    If(LEqual(GP5F, 0))
+    {
+      ADBG("GNIS_Dis=0")
+      Return(0)
+    }
+    //
+    // BIOS mailbox command for GPIO filter
+    //
+    Add(MMTB(Arg0, Arg1), 0x544, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x08)
+
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      HPFI, 1,
+      Offset(0x4),
+      TB2P, 32
+    }
+    Store(TB2P, Local1)
+    ADBG(Concatenate("TB2P=", ToHexString(Local1)))
+    If(LEqual(Local1, 0xFFFFFFFF)) // Disconnect?
+    {
+      ADBG("GNIS=0")
+      Return(0)
+    }
+    Store(HPFI, Local2)
+    ADBG(Concatenate("HPFI=", ToHexString(Local2)))
+    If(LEqual(Local2, 0x01))
+    {
+      Store(0x00, HPFI)
+      ADBG("GNIS=0")
+      Return(0)
+    }
+    // Any other values treated as a GPIO noise
+    ADBG("GNIS=1")
+    Return(1)
+  }
+
+  Method(CHKP,2, Serialized)
+  {
+    Add(MMTB(Arg0, Arg1), 0x544, Local0)
+    OperationRegion(PXVE,SystemMemory,Local0,0x08)
+
+    Field(PXVE,DWordAcc, NoLock, Preserve)
+    {
+      HPFI, 1,
+      Offset(0x4),
+      TB2P, 32
+    }
+    Store(TB2P, Local1)
+    And(Local1,BIT29,Local1)
+    ADBG(Concatenate("Local1=", ToHexString(Local1)))
+    //ADBG(Concatenate("BIT29=", ToHexString(LAnd(Local1,BIT29))))
+    If(LEqual(Local1, BIT29))
+    {
+      Return(1)
+    }
+    Else
+    {
+      Return(0)
+    }
+  }
+
+  //
+  // Method to Handle enumerate PCIe structure through
+  // SMI for Thunderbolt(TM) devices
+  //
+  Method(XTBT,2, Serialized)
+  {
+    ADBG("XTBT")
+    ADBG("RP :")
+    ADBG(Arg0)
+    Store(Arg0, DTCP) // Root port to enumerate
+    Store(Arg1, DTPT)   // Root port Type
+    If(LEqual(Arg0, RPS0)) {
+      Store (1, Local0)
+    } ElseIf (LEqual(Arg0, RPS1)) {
+      Store (2, Local0)
+    } Else {
+      Store (0, Local0)
+      Return ()
+    }
+
+    If (TRDO) {
+      ADBG("Durng TBT_ON")
+      Return ()
+    }
+
+    If (TRD3) {
+      ADBG("During TBT_OFF")
+      Return ()
+    }
+    WWAK()
+    WSUB(Arg0, Arg1)
+    If(GNIS(Arg0, Arg1))
+    {
+      Return()
+    }
+
+    OperationRegion(SPRT,SystemIO, 0xB2,2)
+    Field (SPRT, ByteAcc, Lock, Preserve)
+    {
+      SSMP, 8
+    }
+
+    ADBG("TBT-HP-Handler")
+
+    Acquire(OSUM, 0xFFFF)
+    Store(TBFF(Arg0, Arg1), Local1)
+    If(LEqual(Local1, 1))// Only HR
+    {
+      Sleep(16)
+      Release(OSUM)
+      ADBG("OS_Up_Received")
+      Return ()
+    }
+    If(LEqual(Local1, 2)) // Disconnect
+    {
+      NTFY(Arg0, Arg1)
+      Sleep(16)
+      Release(OSUM)
+      ADBG("Disconnect")
+      Return ()
+    }
+
+    // HR and EP
+    If(LEqual(SOHP, 1))
+    {
+      // Trigger SMI to enumerate PCIe Structure
+      ADBG("TBT SW SMI")
+      Store(21, TBSF)
+      Store(0xF7, SSMP)
+    }
+    NTFY(Arg0, Arg1)
+    Sleep(16)
+    Release(OSUM)
+
+    ADBG("End-of-XTBT")
+  } // End of Method(XTBT)
+
+  //
+  // Calling Method to Handle enumerate PCIe structure through
+  // SMI for Thunderbolt(TM) devices for Tier 1 GPIOs
+  // Used in Two ways ,
+  // If CIO GPIO(1 Tier) is Different for the Controllers, this will be used as 1 Tier GPIO Handler for 1st controller
+  // If CIO GPIO(1 Tier) is Same for all the controllers, this will be used as 1 Tier GPIO Handler for All the controllers
+  //
+  Method(ATBT)
+  {
+    ADBG("ATBT")
+    //
+    // Calling Method to Handle enumerate PCIe structure through
+    //
+    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
+      If(LEqual(RPN0,1))
+      {
+        XTBT(RPS0, RPT0)
+      }
+    } Else {
+      If(LEqual(RPN0,1))
+      {
+        XTBT(RPS0, RPT0)
+      }
+      ElseIf(LEqual(RPN1,1))
+      {
+        XTBT(RPS1, RPT1)
+      }
+    }
+    ADBG("End-of-ATBT")
+  } // End of Method(ATBT)
+
+  Method(BTBT)
+  {
+    ADBG("BTBT")
+    //
+    // Calling Method to Handle enumerate PCIe structure through
+    //
+    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
+      If(LEqual(RPN1,1))
+      {
+        XTBT(RPS1, RPT1)
+      }
+    }
+    ADBG("End-of-BTBT")
+  } // End of Method(BTBT)
+  //
+  // Method to call OSPU Mail box command
+  // Arg0 : Controller type 0x00 : Discrete 0x80 : Integrated TBT
+  // Arg1 : TBT RP Selector / DMA
+  // Arg2 : TBT Type (PCH or PEG)
+  //
+  Method(TINI, 3, Serialized)
+  {
+    ADBG("TINI")
+    If(Lequal (Arg0, DTBT_CONTROLLER))
+    {
+      //ADBG("DTBT")
+    Store(MMRP(Arg1, Arg2), Local0)
+      OperationRegion(RP_X,SystemMemory,Local0,0x20)
+      Field(RP_X,DWordAcc, NoLock, Preserve)
+      {
+        REG0, 32,
+        REG1, 32,
+        REG2, 32,
+        REG3, 32,
+        REG4, 32,
+        REG5, 32,
+        REG6, 32,
+        REG7, 32
+      }
+      Store(REG6, Local1)
+      Store(0x00F0F000, REG6)
+      Store(MMTB(Arg1, Arg2), Local2)
+      OSUP(Local2, DTBT_CONTROLLER)
+      Store(Local1, REG6)
+    }
+    ADBG("End-of-TINI")
+  }
+
+} // End of Scope (\_GPE)
+
+Scope (\_SB)
+{
+  //
+  // The code needs to be executed for TBT Hotplug Handler event (2-tier GPI GPE event architecture) is presented here
+  //
+  Method(THDR, 3, Serialized)
+  {
+    ADBG("THDR")
+    \_SB.CAGS(Arg0)
+    \_GPE.XTBT(Arg1, Arg2)
+  } // End of Method(THDR, 3, Serialized)
+} // End of Scope(\_SB)
+
+Scope (\_SB)
+{
+  //
+  // Name: CGWR [Combined GPIO Write]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> GpioPad / Expander pin
+  //        Arg1 -> Value
+  // Return: Nothing
+  //
+  Method(CGWR, 2, Serialized)
+  {
+    // PCH
+    If (CondRefOf(\_SB.SGOV))
+    {
+      \_SB.SGOV(Arg0, Arg1)
+    }
+  } // End of Method(CGWR, 4, Serialized)
+
+  //
+  // Name: CGRD [Combined GPIO Read]
+  // Description: Function to read from GPIO
+  // Input: Arg0 -> GpioPad / Expander pin
+  //        Arg1 -> 0: GPO [GPIO TX State]
+  //                1: GPI [GPIO RX State]
+  // Return: Value
+  //
+  Method(CGRD, 2, Serialized)
+  {
+    Store(1, Local0)
+    // PCH
+    If (LEqual(Arg1, 0))
+    {
+      // GPIO TX State
+      If (CondRefOf(\_SB.GGOV))
+      {
+        Store(\_SB.GGOV(Arg0), Local0)
+      }
+    }
+    ElseIf (LEqual(Arg1, 1))
+    {
+      // GPIO RX State
+      If (CondRefOf(\_SB.GGIV))
+      {
+        Store(\_SB.GGIV(Arg0), Local0)
+      }
+    }
+    Return(Local0)
+  } // End of Method(CGRD, 4, Serialized)
+  //
+  // Name: WRGP [GPIO Write]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
+  //        Arg1 -> Value
+  // Return: Nothing
+  //
+  Method(WRGP, 2, Serialized)
+  {
+    Store(Arg0, Local0)
+    Store(Arg0, Local1)
+    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
+    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
+    If (LEqual(And(Local0, 0xFF), 1))
+    {
+      // PCH
+      \_SB.CGWR(Local1, Arg1)
+    }
+  } // End of Method(WRGP, 2, Serialized)
+
+  //
+  // Name: RDGP [GPIO Read]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
+  //        Arg1 -> In case of PCH Gpio Read {GPIO TX(0)/RX(1) State indicator}
+  // Return: Value
+  //
+  Method(RDGP, 2, Serialized)
+  {
+    Store(1, Local7)
+    Store(Arg0, Local0)
+    Store(Arg0, Local1)
+    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
+    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
+    If (LEqual(And(Local0, 0xFF), 1))
+    {
+      // PCH
+      Store(\_SB.CGRD(Local1, Arg1), Local7)
+    }
+    Return(Local7)
+  } // End of Method(RDGP, 2, Serialized)
+
+} // End of Scope(\_SB)
+
+Scope(\_SB)
+{
+  // Asserts/De-asserts TBT force power
+  Method(TBFP, 2)
+  {
+    If(Arg0)
+    {
+      // Implementation dependent way to assert TBT force power
+      If(LEqual(Arg1, 1)) {
+        CGWR(FPG0, FP0L)
+      }
+      Else {
+        CGWR(FPG1, FP1L)
+      }
+    }
+    Else
+    {
+      // Implementation dependent way to de-assert TBT force power
+      If(LEqual(Arg1, 1)) {
+        CGWR(FPG0, LNot(FP0L))
+      }
+      Else {
+        CGWR(FPG1, LNot(FP1L))
+      }
+    }
+  }
+
+  // WMI ACPI device to control TBT force power
+  Device(WMTF)
+  {
+    // pnp0c14 is pnp id assigned to WMI mapper
+    Name(_HID, "PNP0C14")
+    Name(_UID, "TBFP")
+
+    Name(_WDG, Buffer() {
+      // {86CCFD48-205E-4A77-9C48-2021CBEDE341}
+      0x48, 0xFD, 0xCC, 0x86,
+      0x5E, 0x20,
+      0x77, 0x4A,
+      0x9C, 0x48,
+      0x20, 0x21, 0xCB, 0xED, 0xE3, 0x41,
+      84, 70,    // Object Id (TF)
+      1,         // Instance Count
+      0x02       // Flags (WMIACPI_REGFLAG_METHOD)
+    })
+
+    // Set TBT force power
+    // Arg2 is force power value
+    Method(WMTF, 3)
+    {
+      CreateByteField(Arg2,0,FP)
+
+      If(FP)
+      {
+        TBFP(1, 1)
+      }
+      Else
+      {
+        TBFP(0, 1)
+      }
+    }
+  }
+} // End of Scope(\_SB)
+
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 1),LEqual(RPS1, 1))))
+{
+  Scope(\_SB.PCI0.RP01)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP01)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 2),LEqual(RPS1, 2))))
+{
+  Scope(\_SB.PCI0.RP02)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP02)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 3),LEqual(RPS1, 3))))
+{
+  Scope(\_SB.PCI0.RP03)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP03)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 4),LEqual(RPS1, 4))))
+{
+  Scope(\_SB.PCI0.RP04)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP04)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 5),LEqual(RPS1, 5))))
+{
+  Scope(\_SB.PCI0.RP05)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP05)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 6),LEqual(RPS1, 6))))
+{
+  Scope(\_SB.PCI0.RP06)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP06)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 7),LEqual(RPS1, 7))))
+{
+  Scope(\_SB.PCI0.RP07)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP07)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 8),LEqual(RPS1, 8))))
+{
+  Scope(\_SB.PCI0.RP08)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP08)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 9),LEqual(RPS1, 9))))
+{
+  Scope(\_SB.PCI0.RP09)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP09)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 10),LEqual(RPS1, 10))))
+{
+  Scope(\_SB.PCI0.RP10)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP10)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 11),LEqual(RPS1, 11))))
+{
+  Scope(\_SB.PCI0.RP11)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP11)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 12),LEqual(RPS1, 12))))
+{
+  Scope(\_SB.PCI0.RP12)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP12)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 13),LEqual(RPS1, 13))))
+{
+  Scope(\_SB.PCI0.RP13)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP13)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 14),LEqual(RPS1, 14))))
+{
+  Scope(\_SB.PCI0.RP14)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP14)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 15),LEqual(RPS1, 15))))
+{
+  Scope(\_SB.PCI0.RP15)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP15)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 16),LEqual(RPS1, 16))))
+{
+  Scope(\_SB.PCI0.RP16)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP16)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 17),LEqual(RPS1, 17))))
+{
+  Scope(\_SB.PCI0.RP17)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP17)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 18),LEqual(RPS1, 18))))
+{
+  Scope(\_SB.PCI0.RP18)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP18)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 19),LEqual(RPS1, 19))))
+{
+  Scope(\_SB.PCI0.RP19)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP19)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 20),LEqual(RPS1, 20))))
+{
+  Scope(\_SB.PCI0.RP20)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP20)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 21),LEqual(RPS1, 21))))
+{
+  Scope(\_SB.PCI0.PEG0)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG0)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 22),LEqual(RPS1, 22))))
+{
+  Scope(\_SB.PCI0.PEG1)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG1)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 23),LEqual(RPS1, 23))))
+{
+  Scope(\_SB.PCI0.PEG2)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG2)
+}
+
+Scope(\_SB)
+{
+    //
+    // Name: PERB
+    // Description: Function to read a Byte from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Byte data read from PCIE-MMIO
+    //
+    Method(PERB,5,Serialized)
+    {
+      ADBG("PERB")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 1)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 8
+      }
+
+      Return(TEMP)
+    } // End of Method(PERB,5,Serialized)
+
+    //
+    // Name: PEWB
+    // Description: Function to write a Byte into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWB,6,Serialized)
+    {
+      ADBG("PEWB")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 1)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 8
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWB,6,Serialized)
+
+    //
+    // Name: PERW
+    // Description: Function to read a Word from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Word data read from PCIE-MMIO
+    //
+    Method(PERW,5,Serialized)
+    {
+      ADBG("PERW")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 2)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 16
+      }
+
+      Return(TEMP)
+    } // End of Method(PERW,5,Serialized)
+
+    //
+    // Name: PEWW
+    // Description: Function to write a Word into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWW,6,Serialized)
+    {
+      ADBG("PEWW")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 2)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 16
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWW,6,Serialized)
+
+    //
+    // Name: PERD
+    // Description: Function to read a Dword from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Dword data read from PCIE-MMIO
+    //
+    Method(PERD,5,Serialized)
+    {
+      ADBG("PERD")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 4)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 32
+      }
+
+      Return(TEMP)
+    } // End of Method(PERD,5,Serialized)
+
+    //
+    // Name: PEWD
+    // Description: Function to write a Dword into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWD,6,Serialized)
+    {
+      ADBG("PEWD")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 4)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 32
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWD,6,Serialized)
+
+    //
+    // Name: STDC
+    // Description: Function to get Standard Capability Register Offset
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Capability ID
+    // Return: Capability Register Offset data
+    //
+    Method(STDC,5,Serialized)
+    {
+      ADBG("STDC")
+
+      //Check for Referenced device is present or not
+      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x00), Local7) //Vendor ID register
+      If(LEqual(Local7, 0xFFFF))
+      {
+        ADBG("Referenced device is not present")
+        Return(0)
+      }
+
+      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x06), Local0) //Device Status register
+      If (LEqual(And(Local0, 16), 0)) //Bit4 - Capabilities List
+      {
+        //No Capabilities linked list is available
+        ADBG("No Capabilities linked list is available")
+        Return(0)
+      }
+
+      //Local1 is for storing CapabilityID
+      //Local2 is for storing CapabilityPtr
+      Store(PERB(Arg0, Arg1, Arg2, Arg3, 0x34), Local2) //CapabilityPtr
+
+      While(1)
+      {
+        And(Local2, 0xFC, Local2) //Each capability must be DWORD aligned
+
+        If(LEqual(Local2, 0)) //A pointer value of 00h is used to indicate the last capability in the list
+        {
+          ADBG("Capability ID is not found")
+          Return(0)
+        }
+
+        Store(PERB(Arg0, Arg1, Arg2, Arg3, Local2), Local1) //CapabilityID
+
+        If(LEqual(Arg4, Local1)) //CapabilityID match
+        {
+          ADBG("Capability ID is found")
+          ADBG("Capability Offset : ")
+          ADBG(Local2)
+          Return(Local2)
+        }
+        Store(PERB(Arg0, Arg1, Arg2, Arg3, Add(Local2, 1)), Local2) //CapabilityPtr
+        Return(0)
+      }
+    } // End of Method(STDC,5,Serialized)
+
+} // End Scope(\_SB)
+
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (34 preceding siblings ...)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
@ 2019-08-17  0:16 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
  2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:16 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

Adds the DSC and build files necessary to build the
WhiskeylakeURvp board instance.

Key files
=========
* build_config.cfg - Board-specific build configuration file.
* OpenBoardPkg.dsc - The WhiskeylakeURvp board description file.
* OpenBoardPkgConfig.dsc - Used for feature-related PCD
  customization.
* OpenBoardPkgPcd.dsc - Used for other PCD customization.
* OpenBoardPkg.fdf - The WhiskeylakeURvp board flash file.
* FlashMapInclude.fdf - The WhiskeylakeURvp board flash map.
* OpenBoardPkgBuildOption.dsc - Sets build options Based
  on PCD values.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc                | 385 +++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc     | 154 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc          | 128 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc             | 245 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf |  49 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf                | 706 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg                |  33 +
 7 files changed, 1700 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
new file mode 100644
index 0000000000..eea809140c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
@@ -0,0 +1,385 @@
+## @file
+#  Platform description.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  #
+  # Set platform specific package/folder name, same as passed from PREBUILD script.
+  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package build folder
+  # DEFINE only takes effect at R9 DSC and FDF.
+  #
+  DEFINE      PLATFORM_PACKAGE          = MinPlatformPkg
+  DEFINE      PLATFORM_SI_PACKAGE       = CoffeelakeSiliconPkg
+  DEFINE      PLATFORM_SI_BIN_PACKAGE   = CoffeelakeSiliconBinPkg
+  DEFINE      PLATFORM_FSP_BIN_PACKAGE  = CoffeeLakeFspBinPkg
+  DEFINE      PLATFORM_BOARD_PACKAGE    = WhiskeylakeOpenBoardPkg
+  DEFINE      BOARD                     = WhiskeylakeURvp
+  DEFINE      PROJECT                   = $(PLATFORM_BOARD_PACKAGE)/$(BOARD)
+
+  #
+  # Platform On/Off features are defined here
+  #
+  !include OpenBoardPkgConfig.dsc
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                       = $(PLATFORM_PACKAGE)
+  PLATFORM_GUID                       = 84D0F5BD-0EF3-4CC0-9B09-F2D0F2AA5C5E
+  PLATFORM_VERSION                    = 0.1
+  DSC_SPECIFICATION                   = 0x00010005
+  OUTPUT_DIRECTORY                    = Build/$(PROJECT)
+  SUPPORTED_ARCHITECTURES             = IA32|X64
+  BUILD_TARGETS                       = DEBUG|RELEASE
+  SKUID_IDENTIFIER                    = ALL
+
+
+  FLASH_DEFINITION                    = $(PROJECT)/OpenBoardPkg.fdf
+
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
+  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
+
+  #
+  # Default value for OpenBoardPkg.fdf use
+  #
+  DEFINE BIOS_SIZE_OPTION = SIZE_70
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+  0x60|WhiskeylakeURvp
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreCommonLib.dsc
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiLib.dsc
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeLib.dsc
+
+[LibraryClasses.common]
+
+  PeiLib|$(PLATFORM_PACKAGE)/Library/PeiLib/PeiLib.inf
+  ReportFvLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/PeiReportFvLib/PeiReportFvLib.inf
+
+  PciHostBridgeLib|$(PLATFORM_PACKAGE)/Pci/Library/PciHostBridgeLibSimple/PciHostBridgeLibSimple.inf
+  PciSegmentInfoLib|$(PLATFORM_PACKAGE)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
+  PlatformBootManagerLib|$(PLATFORM_PACKAGE)/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf
+  I2cAccessLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
+  GpioExpanderLib|$(PLATFORM_BOARD_PACKAGE)/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
+
+  PlatformHookLib|$(PROJECT)/Library/BasePlatformHookLib/BasePlatformHookLib.inf
+
+  FspWrapperHobProcessLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperHobProcessLib/PeiFspWrapperHobProcessLib.inf
+  PlatformSecLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
+
+  FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
+  FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
+
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf
+  SiliconPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
+
+  ConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/BoardInitLibNull/BoardInitLibNull.inf
+  TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    TbtCommonLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
+  !endif
+  DxeTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
+  PchHsioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
+  MmPciLib|$(PLATFORM_SI_PACKAGE)/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
+  PchPmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
+
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.IA32]
+  #
+  # PEI phase common
+  #
+  SiliconPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/PeiTestPointLib.inf
+  MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  HdaVerbTableLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    PeiTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
+    PeiDTbtInitLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
+  !endif
+
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
+    PeiPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
+    PeiPolicyBoardConfigLib|$(PROJECT)/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
+    PeiPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
+    PeiPlatformHookLib|$(PROJECT)/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
+  !if $(TARGET) == DEBUG
+    GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
+  !else
+    GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
+  !endif
+
+[LibraryClasses.IA32.SEC]
+  TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf
+  SecBoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/SecBoardInitLibNull/SecBoardInitLibNull.inf
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.X64]
+  #
+  # DXE phase common
+  #
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/DxeFspWrapperPlatformLib/DxeFspWrapperPlatformLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/DxeTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/DxeTestPointLib.inf
+  MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
+  MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
+  BoardAcpiTableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
+
+  DxePolicyBoardConfigLib|$(PROJECT)/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
+  DxePolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxeLib.dsc
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  SpiFlashCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SmmTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/SmmTestPointLib.inf
+  MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
+  BoardAcpiEnableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+
+[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
+  ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  !include OpenBoardPkgPcd.dsc
+
+[Components.IA32]
+  #
+  # Common
+  #
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiInclude.dsc
+
+  #
+  # FSP wrapper SEC Core
+  #
+  UefiCpuPkg/SecCore/SecCore.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  #
+  # Silicon
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgPei.dsc
+
+  #
+  # Platform
+  #
+  $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
+      !endif
+      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
+  }
+  IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+      SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
+      !endif
+  }
+  IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
+#to do  $(PLATFORM_PACKAGE)/FspWrapper/FspWrapperPeim/FspWrapperPeim.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+      SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+
+  #
+  # Security
+  #
+
+  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
+  !endif
+
+  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+  IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+  !endif
+
+[Components.X64]
+
+  #
+  # Common
+  #
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeInclude.dsc
+
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # Shell
+  #
+  ShellPkg/Application/Shell/Shell.inf {
+   <PcdsFixedAtBuild>
+     gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+   <LibraryClasses>
+     NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+     ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+     HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+     BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+     ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+     ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  }
+
+  #
+  # Silicon
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxe.dsc
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+    $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+  !endif
+
+  #
+  # Platform
+  #
+  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf{
+    <LibraryClasses>
+      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
+  }
+
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+	  SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
+
+  $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+
+  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
+  $(PLATFORM_PACKAGE)/Test/TestPointDumpApp/TestPointDumpApp.inf
+
+  #
+  # OS Boot
+  #
+  !if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+    $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
+  $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
+  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardAcpiEnableLib|$(PROJECT)/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
+      !endif
+  }
+
+  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
+    <LibraryClasses>
+      !if $(TARGET) == DEBUG
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !endif
+  }
+
+  !endif
+
+  #
+  # Security
+  #
+  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
+
+  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
+  !endif
+
+  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
+
+  #
+  # Other
+  #
+  $(PLATFORM_SI_BIN_PACKAGE)/Microcode/MicrocodeUpdates.inf
+
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
+  !include OpenBoardPkgBuildOption.dsc
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
new file mode 100644
index 0000000000..be1d47c719
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
@@ -0,0 +1,154 @@
+## @file
+# platform build option configuration file.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[BuildOptions]
+# Define Build Options both for EDK and EDKII drivers.
+
+
+  DEFINE DSC_S3_BUILD_OPTIONS =
+
+  DEFINE DSC_CSM_BUILD_OPTIONS =
+
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+  DEFINE DSC_ACPI_BUILD_OPTIONS = -DACPI_SUPPORT=1
+!else
+  DEFINE DSC_ACPI_BUILD_OPTIONS =
+!endif
+
+  DEFINE BIOS_GUARD_BUILD_OPTIONS =
+
+  DEFINE OVERCLOCKING_BUILD_OPTION =
+
+  DEFINE FSP_BINARY_BUILD_OPTIONS =
+
+  DEFINE FSP_WRAPPER_BUILD_OPTIONS = -DFSP_WRAPPER_FLAG
+
+  DEFINE SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS =
+
+  DEFINE RESTRICTED_OPTION =
+
+
+  DEFINE SV_BUILD_OPTIONS =
+
+  DEFINE TEST_MENU_BUILD_OPTION =
+
+!if gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable == FALSE
+  DEFINE OPTIMIZE_DISABLE_OPTIONS = -Od -GL-
+!else
+  DEFINE OPTIMIZE_DISABLE_OPTIONS =
+!endif
+
+  DEFINE UP_SERVER_SUPPORT_BUILD_OPTIONS =
+
+
+  DEFINE TPM_BUILD_OPTION =
+
+  DEFINE TPM2_BUILD_OPTION =
+
+  DEFINE DSC_TBT_BUILD_OPTIONS =
+
+  DEFINE DSC_DCTT_BUILD_OPTIONS =
+
+  DEFINE EMB_BUILD_OPTIONS =
+
+  DEFINE DSC_MEMORY_DOWN_BUILD_OPTIONS = -DMEM_DOWN_FLAG=1
+
+  DEFINE DSC_KBCEMUL_BUILD_OPTIONS =
+
+  DEFINE BOOT_GUARD_BUILD_OPTIONS =
+
+  DEFINE SECURE_BOOT_BUILD_OPTIONS =
+
+  DEFINE USBTYPEC_BUILD_OPTION =
+
+  DEFINE CAPSULE_BUILD_OPTIONS =
+
+  DEFINE PERFORMANCE_BUILD_OPTION =
+
+  DEFINE DEBUGUSEUSB_BUILD_OPTION =
+
+  DEFINE DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION = -DDISABLE_NEW_DEPRECATED_INTERFACES=1
+
+  DEFINE SINITBIN_BUILD_OPTION =
+
+  DEFINE MINTREE_FLAG_BUILD_OPTION = -DMINTREE_FLAG=1
+
+  DEFINE CPUTYPE_BUILD_OPTION = -DCPU_CFL=1
+
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)  $(OVERCLOCKING_BUILD_OPTION) $(PERFORMANCE_BUILD_OPTION) $(EMB_BUILD_OPTIONS) $(BIOS_GUARD_BUILD_OPTIONS) $(DSC_TBT_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(BOOT_GUARD_BUILD_OPTIONS) $(DSC_MEMORY_DOWN_BUILD_OPTIONS) $(DEBUGUSEUSB_BUILD_OPTION) $(DSC_S3_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(FSP_BINARY_BUILD_OPTIONS) $(FSP_WRAPPER_BUILD_OPTIONS) $(SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_KBCEMUL_BUILD_OPTIONS) $(CAPSULE_BUILD_OPTIONS) $(SECURE_BOOT_BUILD_OPTIONS) $(DSC_CSM_BUILD_OPTIONS) $(DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(TPM2_BUILD_OPTION) $(TPM_BUILD_OPTION) $(DSC_DCTT_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS) $(UP_SERVER_SUPPORT_BUILD_OPTIONS) $(USBTYPEC_BUILD_OPTION) $(SINITBIN_BUILD_OPTION) $(MINTREE_FLAG_BUILD_OPTION)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(CPUTYPE_BUILD_OPTION)
+[BuildOptions.Common.EDKII]
+
+#
+# For IA32 Global Build Flag
+#
+       *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+       *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_NASM_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+#
+# For IA32 Specific Build Flag
+#
+GCC:   *_*_IA32_PP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_ASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+MSFT:  *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+
+#
+# For X64 Global Build Flag
+#
+       *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+       *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_NASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+
+#
+# For X64 Specific Build Flag
+#
+GCC:   *_*_X64_PP_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASM_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+MSFT:  *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support MemoryAttribute table
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support NX protection
+[BuildOptions.common.EDKII.DXE_DRIVER, BuildOptions.common.EDKII.DXE_CORE, BuildOptions.common.EDKII.UEFI_DRIVER, BuildOptions.common.EDKII.UEFI_APPLICATION]
+  #MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  #GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
new file mode 100644
index 0000000000..c68fecf50e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
@@ -0,0 +1,128 @@
+## @file
+#  Platform configuration file.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[PcdsFixedAtBuild]
+  #
+  # Please select BootStage here.
+  # Stage 1 - enable debug (system deadloop after debug init)
+  # Stage 2 - mem init (system deadloop after mem init)
+  # Stage 3 - boot to shell only
+  # Stage 4 - boot to OS
+  # Stage 5 - boot to OS with security boot enabled
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4
+
+[PcdsFeatureFlag]
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 1
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 2
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 3
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 4
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 5
+  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
+!endif
+
+  gBoardModuleTokenSpaceGuid.PcdTbtEnable|FALSE
+  #
+  # More fine granularity control below:
+  #
+
+  gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport|TRUE
+
+#
+# TRUE is ENABLE. FALSE is DISABLE.
+#
+#
+# BIOS build switches configuration
+#
+  gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+
+# CPU
+  gSiPkgTokenSpaceGuid.PcdSourceDebugEnable|FALSE
+
+# SA
+  gSiPkgTokenSpaceGuid.PcdIgdEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPegEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSgEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSaDmiEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSaOcEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdVtdEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable|TRUE
+
+# ME
+  gSiPkgTokenSpaceGuid.PcdAtaEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPttEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdJhiEnable|TRUE
+
+  gSiPkgTokenSpaceGuid.PcdAcpiEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdBdatEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSiCsmEnable|FALSE
+  gSiPkgTokenSpaceGuid.PcdTraceHubEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPpmEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdS3Enable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSmbiosEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSmmVariableEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdUseHpetTimer|TRUE                       # TRUE - HPET / FALSE - 8254 timer is used.
+  gSiPkgTokenSpaceGuid.PcdOcWdtEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable|FALSE
+
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdCflCpuEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdIpuEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdGnaEnable|TRUE
+
+#
+# Override some PCDs for specific build requirements.
+#
+  #
+  # Disable USB debug message when Source Level Debug is enabled
+  # because they cannot be enabled at the same time.
+  #
+
+    gSiPkgTokenSpaceGuid.PcdPttEnable|FALSE
+
+  !if $(TARGET) == DEBUG
+    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+  !else
+    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+  !endif
+
+  !if $(TARGET) == DEBUG
+    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE
+  !else
+    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE
+  !endif
+
+    gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
new file mode 100644
index 0000000000..96d65133ae
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
@@ -0,0 +1,245 @@
+## @file
+#  Platform description.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport|TRUE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+!if $(TARGET) == RELEASE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable|TRUE
+
+[PcdsFixedAtBuild.common]
+  gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode|TRUE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|140
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1
+!endif
+
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|2
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|8
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|1
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
+  gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
+  gSiPkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+  gSiPkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF00000
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
+
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize        | 0x00026000
+
+  gSiPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x5000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe|TRUE
+
+#
+# 8MB Default
+#
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000
+
+#
+# 16MB TSEG in Debug build only.
+#
+!if $(TARGET) == DEBUG
+  gSiPkgTokenSpaceGuid.PcdTsegSize|0x1000000
+!endif
+
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber|0x0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber|0x1F
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber|0x2
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x44
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask|0x80
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset|0x00
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress|0x1800
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset|0x08
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask|0xFFFC
+
+  !if $(TARGET) == RELEASE
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x402
+  !else
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x188B
+  !endif
+
+
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize|0x4b
+  !if $(TARGET) == RELEASE
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0x70
+  !else
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0xE0
+  !endif
+
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress|0xFFEAC000
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress|0xFFDC0000
+
+  ## Specifies the size of the microcode Region.
+  # @Prompt Microcode Region size.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0
+
+  ## Specifies timeout value in microseconds for the BSP to detect all APs for the first time.
+  # @Prompt Timeout for the BSP to detect all APs for the first time.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|1000
+
+  ## 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
+
+
+  #
+  # The PCDs are used to control the Windows SMM Security Mitigations Table - Protection Flags
+  #
+  # BIT0: If set, expresses that for all synchronous SMM entries,SMM will validate that input and output buffers lie entirely within the expected fixed memory regions.
+  # BIT1: If set, expresses that for all synchronous SMM entries, SMM will validate that input and output pointers embedded within the fixed communication buffer only refer to address ranges \
+  #       that lie entirely within the expected fixed memory regions.
+  # BIT2: Firmware setting this bit is an indication that it will not allow reconfiguration of system resources via non-architectural mechanisms.
+  # BIT3-31: Reserved
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags|0x07
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 1
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 2
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 3
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x03, 0x05, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 4
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x03, 0x05, 0x1F, 0x00, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 5
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 6
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+[PcdsFixedAtBuild.IA32]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00148
+  gMinPlatformPkgTokenSpaceGuid.PcdPeiPhaseStackTop|0xA0000
+  gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x3800000
+
+[PcdsFixedAtBuild.X64]
+  # Default platform supported RFC 4646 languages: (American) English
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en-US"
+
+
+[PcdsPatchableInModule.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+
+!if $(TARGET) == DEBUG
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable|1
+!endif
+
+[PcdsDynamicHii.X64.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout"
+  gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"Timeout"
+!endif
+
+[PcdsDynamicDefault]
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0xFFD50000
+  # Platform will pre-allocate UPD buffer and pass it to FspWrapper
+  # Those dummy address will be patched before FspWrapper executing
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress|0x0
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress|0x0
+
+  ## Specifies max supported number of Logical Processors.
+  # @Prompt Configure max supported number of Logical Processors
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|16
+
+[PcdsDynamicDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAtaSmartEnable|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE
+  #
+  #  Set video to native resolution as Windows 8 WHCK requirement.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0x0
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum|0x00
+
+[PcdsDynamicDefault.common.DEFAULT]
+
+  # Tbt
+  gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad | 13
+  gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad | 0x02010011
+  gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport | 0x0
+  gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq| 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtAspm | 0x0
+  gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch | 0x0
+
+  gBoardModuleTokenSpaceGuid.PcdRtd3Tbt | 0x1
+  gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax | 26
+  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd | 100
+  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax | 28
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
new file mode 100644
index 0000000000..9209b9e88a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
@@ -0,0 +1,49 @@
+## @file
+#  FDF file of Platform.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+#=================================================================================#
+# 8 M BIOS - for FSP wrapper
+#=================================================================================#
+DEFINE FLASH_BASE                                                   = 0xFF800000  #
+DEFINE FLASH_SIZE                                                   = 0x00800000  #
+DEFINE FLASH_BLOCK_SIZE                                             = 0x00010000  #
+DEFINE FLASH_NUM_BLOCKS                                             = 0x00000080  #
+#=================================================================================#
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageOffset           = 0x00000000  # Flash addr (0xFF800000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize             = 0x00040000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset   = 0x00000000  # Flash addr (0xFF800000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize    = 0x0001E000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset = 0x0001E000  # Flash addr (0xFF81E000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize  = 0x00002000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset   = 0x00020000  # Flash addr (0xFF820000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize    = 0x00020000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset          = 0x00040000  # Flash addr (0xFF840000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            = 0x00060000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset          = 0x000A0000  # Flash addr (0xFF8A0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            = 0x00070000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset            = 0x00110000  # Flash addr (0xFF910000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              = 0x00090000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset          = 0x001A0000  # Flash addr (0xFF9A0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            = 0x00190000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset        = 0x00330000  # Flash addr (0xFFB30000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          = 0x00170000  #
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset                  = 0x004A0000  # Flash addr (0xFFCA0000)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                    = 0x000B0000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset              = 0x00550000  # Flash addr (0xFFD50000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize                = 0x00070000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset              = 0x005C0000  # Flash addr (0xFFDC0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                = 0x000EC000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset              = 0x006AC000  # Flash addr (0xFFEAC000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                = 0x00014000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset         = 0x006C0000  # Flash addr (0xFFEC0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           = 0x00140000  #
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
new file mode 100644
index 0000000000..611078e4b4
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
@@ -0,0 +1,706 @@
+## @file
+#  FDF file of Platform.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+   !include $(PROJECT)/Include/Fdf/FlashMapInclude.fdf
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.WhiskeylakeURvp]
+#
+# FD Tokens, BaseAddress, Size, ErasePolarity, BlockSize, and NumBlocks, cannot be
+# assigned with PCD values. Instead, it uses the definitions for its variety, which
+# are FLASH_BASE, FLASH_SIZE, FLASH_BLOCK_SIZE and FLASH_NUM_BLOCKS.
+#
+BaseAddress   = $(FLASH_BASE) | gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress      #The base address of the FLASH Device.
+Size          = $(FLASH_SIZE) | gSiPkgTokenSpaceGuid.PcdBiosSize             #The size in bytes of the FLASH Device
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCK_SIZE)
+NumBlocks     = $(FLASH_NUM_BLOCKS)
+
+DEFINE SIPKG_DXE_SMM_BIN  = INF
+DEFINE SIPKG_PEI_BIN      = INF
+
+# Set FLASH_REGION_FV_RECOVERY_OFFSET to PcdNemCodeCacheBase, because macro expression is not supported.
+# So, PlatformSecLib uses PcdBiosAreaBaseAddress + PcdNemCodeCacheBase to get the real CodeCache base address.
+SET gSiPkgTokenSpaceGuid.PcdNemCodeCacheBase = $(gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase = $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) + $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase) + 0x60
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize) - 0x60
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) + $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset = 0x60
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase    = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize    = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeOffset  = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress = gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize    = gSiPkgTokenSpaceGuid.PcdBiosSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress    = gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize           = gSiPkgTokenSpaceGuid.PcdBiosSize
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+# Fv Size can be adjusted
+#
+################################################################################
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x40000
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5F, 0x46, 0x56, 0x48, 0xFF, 0xFE, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  #
+  # Be careful on CheckSum field.
+  #
+  0x48, 0x00, 0x32, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 4 Blocks  0x10000 Bytes / Block
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+!if gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable == TRUE
+  #  Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+  #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+  #Size: 0x1E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x1DFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xDF, 0x01, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+FV = FvAdvanced
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+FV = FvSecurity
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+FV = FvOsBoot
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+FV = FvUefiBoot
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+FV = FvPostMemory
+
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase|gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+#Microcode
+FV = FvMicrocode
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+# FSP_S Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_S.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+# FSP_M Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_M.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+# FSP_T Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_T.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+FV = FvPreMemory
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FvMicrocode]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = FALSE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = FALSE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
+  $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/X64/MicrocodeUpdates.bin
+}
+
+[FV.FvPreMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = FC8FE6B5-CD9B-411E-BD8F-31824D0CDE3D
+
+INF  UefiCpuPkg/SecCore/SecCore.inf
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePreMemoryInclude.fdf
+
+INF $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+INF IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+
+[FV.FvPostMemoryUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 7C4DCFC6-AECA-4707-85B9-FD4B2EEA49E7
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePostMemoryInclude.fdf
+
+# Init Board Config PCD
+INF $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+INF IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+
+FILE RAW = C9505BC0-AA3D-4056-9995-870C8DE8594E {
+    $(PLATFORM_SI_BIN_PACKAGE)/ChipsetInit/CnlPchLpChipsetInitTable_Dx.bin
+  }
+!if gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable == TRUE
+FILE FREEFORM =PCD(gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid) {
+  SECTION RAW = $(PLATFORM_FSP_BIN_PACKAGE)/SampleCode/Vbt/Vbt.bin
+  SECTION UI  = "Vbt"
+}
+FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D {
+  SECTION RAW = MdeModulePkg/Logo/Logo.bmp
+}
+!endif # PcdPeiDisplayEnable
+
+
+[FV.FvPostMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 9DFE49DB-8EF0-4D9C-B273-0036144DE917
+
+FILE FV_IMAGE = 244FAAF4-FAE1-4892-8B7D-7EF84CBFA709 {
+      SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+        SECTION FV_IMAGE = FvPostMemoryUncompact
+      }
+}
+
+[FV.FvUefiBootUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreUefiBootInclude.fdf
+INF  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
+
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF  MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+INF  ShellPkg/Application/Shell/Shell.inf
+
+INF  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf
+INF  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf
+INF  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
+
+INF  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
+
+
+[FV.FvUefiBoot]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 0496D33D-EA79-495C-B65D-ABF607184E3B
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvUefiBootUncompact
+       }
+     }
+
+[FV.FvOsBootUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A0F04529-B715-44C6-BCA4-2DEBDD01EEEC
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreOsBootInclude.fdf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+INF  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+INF  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+
+INF  $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
+INF  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf
+
+INF  RuleOverride = DRIVER_ACPITABLE $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
+INF  $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+
+!endif
+
+[FV.FvLateSilicon]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 97F09B89-9E83-4DDC-A3D1-10C4AF539D1E
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
+
+INF  RuleOverride = ACPITABLE $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
+INF  RuleOverride = ACPITABLE $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
+
+!endif
+
+[FV.FvOsBoot]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 13BF8810-75FD-4B1A-91E6-E16C4201F80A
+
+FILE FV_IMAGE = B9020753-84A8-4BB6-947C-CE7D41F5CE39 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvOsBootUncompact
+       }
+     }
+
+FILE FV_IMAGE = D4632741-510C-44E3-BE21-C3D6D7881485 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvLateSilicon
+       }
+     }
+
+[FV.FvSecurityPreMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 9B7FA59D-71C6-4A36-906E-9725EA6ADD5B
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
+
+INF  IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+
+INF  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+
+[FV.FvSecurityPostMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 4199E560-54AE-45E5-91A4-F7BC3804E14A
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPostMemoryInclude.fdf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+INF $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
+!endif
+
+[FV.FvSecurityLate]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = F753FE9A-EEFD-485B-840B-E032D538102C
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityLateInclude.fdf
+INF  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+INF  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
+!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+INF  $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
+!endif
+!endif
+
+[FV.FvSecurity]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 5A9A8B4E-149A-4CB2-BDC7-C8D62DE2C8CF
+
+FILE FV_IMAGE = 757CC075-1428-423D-A73C-22639706C119 {
+       SECTION FV_IMAGE = FvSecurityPreMemory
+     }
+
+FILE FV_IMAGE = 80BB8482-44D5-4BEC-82B5-8D87A933830B {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvSecurityPostMemory
+       }
+     }
+
+FILE FV_IMAGE = C83522D9-80A1-4D95-8C25-3F1370497406 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvSecurityLate
+       }
+     }
+
+[FV.FvAdvancedPreMem]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 6053D78A-457E-4490-A237-31D0FBE2F305
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+!endif
+
+[FV.FvAdvancedPostMem]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = BE3DF86F-E464-44A3-83F7-0D27E6B88C27
+
+[FV.FvAdvancedLate]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 11F6E304-43F9-4B2F-90AB-B8FFEAD6205D
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+!endif
+
+[FV.FvAdvanced]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B23E7388-9953-45C7-9201-0473DDE5487A
+
+FILE FV_IMAGE = 35E7406A-5842-4F2B-BC62-19022C12AF74 {
+       SECTION FV_IMAGE = FvAdvancedPreMem
+     }
+
+FILE FV_IMAGE = F5DCB34F-27EA-48AC-9406-C894F6D587CA {
+       SECTION FV_IMAGE = FvAdvancedPostMem
+     }
+
+FILE FV_IMAGE = 5248467B-B87B-4E74-AC02-398AF4BCB712 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvAdvancedLate
+       }
+     }
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/RuleInclude.fdf
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
new file mode 100644
index 0000000000..1b0619bc1c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
@@ -0,0 +1,33 @@
+# @ build_config.cfg
+# This is the WhiskeylakeURvp board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN =
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = WhiskeylakeOpenBoardPkg
+PROJECT = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp
+BOARD = WhiskeylakeURvp
+FLASH_MAP_FDF = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = CoffeeLakeFspBinPkg
+FSP_PKG_NAME = CoffeelakeSiliconPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
-- 
2.16.2.windows.1


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

* [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (35 preceding siblings ...)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
@ 2019-08-17  0:16 ` Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
                     ` (2 more replies)
  2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit
  37 siblings, 3 replies; 121+ messages in thread
From: Kubacki, Michael A @ 2019-08-17  0:16 UTC (permalink / raw)
  To: devel
  Cc: Sai Chaganty, Chasel Chiu, Liming Gao, Nate DeSimone,
	Michael D Kinney, Ankit Sinha

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

* Adds the WhiskeylakeURvp board as a build option in build.cfg so it
  it is listed as a valid build target.
* Updates relevant Readme.md files to include instructions for
  WhiskeylakeOpenBoardPkg.
* Adds the maintainers for WhiskeylakeOpenBoardPkg to maintainers.txt.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Maintainers.txt          |  5 +++
 Platform/Intel/Readme.md | 44 +++++++++++++-------
 Platform/Intel/build.cfg |  4 +-
 Readme.md                |  1 +
 4 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/Maintainers.txt b/Maintainers.txt
index bc8cbd6458..b16432bf87 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -98,6 +98,11 @@ M: Shifei A Lu <shifei.a.lu@intel.com>
 M: Xiaohu Zhou <bowen.zhou@intel.com>
 M: Isaac W Oram <isaac.w.oram@intel.com>
 
+Platform/Intel/WhiskeylakeOpenBoardPkg
+M: Chasel Chiu <chasel.chiu@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
+M: Nate DeSimone <nathaniel.l.desimone@intel.com>
+
 Platform/Intel/Tools
 M: Bob Feng <bob.c.feng@intel.com>
 M: Liming Gao <liming.gao@intel.com>
diff --git a/Platform/Intel/Readme.md b/Platform/Intel/Readme.md
index 00f42985a2..aaf6ef4d3e 100644
--- a/Platform/Intel/Readme.md
+++ b/Platform/Intel/Readme.md
@@ -53,9 +53,10 @@ A UEFI firmware implementation using MinPlatformPkg is constructed using the fol
 
 
 ## Board Support
+* The `ClevoOpenBoardPkg` contains board implementations for Clevo systems.
 * The `KabylakeOpenBoardPkg` contains board implementations for Kaby Lake systems.
 * The `PurleyOpenBoardPkg` contains board implementations for Purley systems.
-* The `ClevoOpenBoardPkg` contains board implementations for Clevo systems.
+* The `WhiskeylakeOpenBoardPkg` contains board implementations for Whiskey Lake systems.
 
 ## Board Package Organization
 The board package follows the standard EDK II package structure with the following additional elements and guidelines:
@@ -189,7 +190,12 @@ return back to the minimum platform caller.
           |       |        |                |---build_config.cfg: BoardMtOlympus specific
           |       |        |                |                     build settings, environment variables.
           |       |        |                |---build_board.py: Optional board-specific pre-build,
-          |       |        |                |                   build, post-build and clean functions.
+          |       |        |                                    build, post-build and clean functions.
+          |       |        |
+          |       |        |------WhiskeylakeOpenBoardPkg
+          |       |        |        |------WhiskeylakeURvp
+          |       |        |                |---build_config.cfg: WhiskeylakeURvp specific build
+          |       |        |                                      settings environment variables.
           |------FSP
   </pre>
 
@@ -222,19 +228,6 @@ Users can also flash the UEFI firmware image to the highest area of the flash re
 
 ### **Known limitations**
 
-**KabylakeOpenBoardPkg**
-1. This firmware project has only been tested on the Intel KabylakeRvp3 board.
-2. This firmware project has only been tested booting to Microsoft Windows 10 x64 with AHCI mode and Integrated Graphic
-  Device.
-3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
-4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
-5. The build was tested with NASM version 2.11.08.
-
-**PurleyOpenBoardPkg**
-1. This firmware project has only been tested on the Microsoft MtOlympus board.
-2. This firmware project has only been tested booting to Microsoft Windows Server 2016 with NVME on M.2 slot.
-3. This firmware project build has only been tested using the Microsoft Visual Studio 2015 compiler.
-
 **ClevoOpenBoardPkg**
 1. Currently, support is only being added for the N1xxWU series of boards.
 2. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015 compiler.
@@ -244,6 +237,27 @@ Users can also flash the UEFI firmware image to the highest area of the flash re
 6. The firmware project applies to all Clevo supported board configurations but is only being tested on System 76 Galago
   Pro devices.
 
+**KabylakeOpenBoardPkg**
+1. This firmware project has only been tested on the Intel KabylakeRvp3 board.
+2. This firmware project has only been tested booting to Microsoft Windows 10 x64 with AHCI mode and Integrated Graphic
+  Device.
+3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
+4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
+5. The build was tested with NASM version 2.11.08.
+
+**PurleyOpenBoardPkg**
+1. This firmware project has only been tested on the Microsoft MtOlympus board.
+2. This firmware project has only been tested booting to Microsoft Windows Server 2016 with NVME on M.2 slot.
+3. This firmware project build has only been tested using the Microsoft Visual Studio 2015 compiler.
+
+**WhiskeylakeOpenBoardPkg**
+1. This firmware project has only been tested on the Intel WhiskeylakeURvp board.
+2. This firmware project has only been tested booting to Microsoft Windows 10 x64 with AHCI mode and Integrated Graphic
+  Device.
+3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
+4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
+5. The build was tested with NASM version 2.11.08.
+
 ### **Planned Activities**
 * Replace the batch build scripts with cross-platform Python build scripts.
 * Publish a Minimum Platform specification to describe the architecture and interfaces in more detail.
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg
index fc6e4fe824..b6d32ada49 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -51,6 +51,8 @@ NUMBER_OF_PROCESSORS = 0
 
 [PLATFORMS]
 # board_name = path_to_board_build_config.cfg
+BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
-BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+WhiskeylakeURvp = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
+
diff --git a/Readme.md b/Readme.md
index 1befd0b544..e4f211eee6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -228,6 +228,7 @@ they will be documented with the platform.
 * [Clevo](Platform/Intel/ClevoOpenBoardPkg)
 * [Kaby Lake](Platform/Intel/KabylakeOpenBoardPkg)
 * [Purley](Platform/Intel/PurleyOpenBoardPkg)
+* [Whiskey Lake](Platform/Intel/WhiskeylakeOpenBoardPkg)
 
 For more information, see the
 [EDK II Minimum Platform Specification](https://edk2-docs.gitbooks.io/edk-ii-minimum-platform-specification).
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  1:18   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers

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

Create the CoffeelakeSiliconPkg to provide an initial package for
silicon initialization code for Coffee Lake (CFL) and Whiskey Lake
(WHL) generation products.

* Major areas of functionality are categorized into CPU, Management
  Engine (ME), 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: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec                              | 714 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h                  |  53 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h         |  89 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h        | 291 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h         | 157 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h       |  64 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h             |  28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h | 123 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h     |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h          | 110 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h          |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h               |  34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h                     | 319 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h                 |  29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h  |  26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h   |  71 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h    |  60 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h             |  55 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h                  |  19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h               |  65 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h         |  23 +
 21 files changed, 2410 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
new file mode 100644
index 0000000000..fa8c11e93d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
@@ -0,0 +1,714 @@
+## @file
+# Component description file for the Silicon Reference Code.
+#
+# Copyright (c) 2019 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]
+  Include
+  SampleCode/Include
+  SampleCode/MdeModulePkg/Include
+  SampleCode/IntelFrameworkPkg/Include
+  #
+  # SystemAgent
+  #
+  SystemAgent/Include
+  SystemAgent/MemoryInit/Include
+  SystemAgent/AcpiTables
+  #
+  # Cpu
+  #
+  Cpu/Include
+  #
+  # Me
+  #
+  Me/Include
+  #
+  # Pch
+  #
+  Pch/Include
+
+[Guids.common.Private]
+  #
+  # PCH
+  #
+  gPchDeviceTableHobGuid       = { 0xb3e123d0, 0x7a1e, 0x4db4, { 0xaf, 0x66, 0xbe, 0xd4, 0x1e, 0x9c, 0x66, 0x38 }}
+  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 }}
+
+[Guids]
+##
+## 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}}
+
+##
+## IntelFrameworkPkg
+##
+gEfiSmmPeiSmramMemoryReserveGuid =  {0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d}}
+
+##
+## Common
+##
+## Include/ConfigBlock/SiConfig.h
+gSiConfigGuid = {0x4ed6d282, 0x22f3, 0x4fe1, {0xa6, 0x61, 0x6, 0x1a, 0x97, 0x38, 0x59, 0xd8 }}
+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}}
+
+##
+## System Agent
+##
+gSaAcpiTableStorageGuid  =  {0x3c0ed5e2, 0x91ea, 0x4b94, { 0x82, 0xd, 0x9d, 0xaf, 0x9a, 0x3b, 0xb4, 0xa2}}
+gSaDataHobGuid  =  {0xe07d0bda, 0xbf90, 0x46a9, { 0xb0, 0x0e, 0xb2, 0xc4, 0x4a, 0x0e, 0xd6, 0xd0}}
+gSaConfigHobGuid  = {0x762fa2e6, 0xea3b, 0x41c8, { 0x8c, 0x52, 0x63, 0x76, 0x6d, 0x70, 0x39, 0xe0}}
+gSaPegHobGuid  = {0x440ab2e5, 0xa3ea, 0x466f, { 0x84, 0x96, 0xdf, 0xb1, 0x3b, 0x75, 0x29, 0x95}}
+gSgAcpiTableStorageGuid  =  {0x8de8964f, 0x2939, 0x4b49, { 0xa3, 0x48, 0xf6, 0xb2, 0xb2, 0xde, 0x4a, 0x42}}
+gSaSsdtAcpiTableStorageGuid  =  {0xca89914d, 0x2317, 0x452e, { 0xb2, 0x45, 0x36, 0xc6, 0xfb, 0x77, 0xa9, 0xc6}}
+gPegSsdtAcpiTableStorageGuid  =  {0xE05B8635, 0xE5C0, 0x4D88, { 0xB6, 0x29, 0x19, 0xD6, 0xA2, 0xC6, 0xE9, 0x2E}}
+gSgAcpiTablePchStorageGuid  =  {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}}
+gSaPciePeiPreMemConfigGuid  =  { 0x81baf3c9, 0xf295, 0x4572, { 0x8b, 0x21, 0x79, 0x3f, 0xa3, 0x1b, 0xa5, 0xdb}}
+gSaPciePeiConfigGuid  =  { 0xdaa929a9, 0x5ec9, 0x486a, { 0xb0, 0xf7, 0x82, 0x3a, 0x55, 0xc7, 0xb5, 0xb3}}
+gGraphicsPeiPreMemConfigGuid  =  { 0x0319c56b, 0xc43a, 0x42f1, { 0x80, 0xbe, 0xca, 0x5b, 0xd1, 0xd5, 0xc9, 0x28}}
+gGraphicsPeiConfigGuid  =  { 0x04249ac0, 0x0088, 0x439f, { 0xa7, 0x4e, 0xa7, 0x04, 0x2a, 0x06, 0x2f, 0x5d}}
+gSwitchableGraphicsConfigGuid  =  { 0xc7956998, 0xc065, 0x46c4, { 0x8e, 0x2f, 0x58, 0x2b, 0x67, 0xeb, 0xbe, 0x2f}}
+gCpuTraceHubConfigGuid =  { 0xf2e17477, 0x93f3, 0x430d, { 0x9e, 0x08, 0x3c, 0xcc, 0x6e, 0x2f, 0x6c, 0x4b}}
+gMemoryConfigGuid  =  { 0x26cf084c, 0xc9db, 0x41bb, { 0x92, 0xc6, 0xd1, 0x97, 0xb8, 0xa1, 0xe4, 0xbf}}
+gMemoryConfigNoCrcGuid  =  { 0xc56c73d0, 0x1cdb, 0x4c0c, { 0xa9, 0x57, 0xea, 0x62, 0xa9, 0xe6, 0xf5, 0x0c}}
+gIpuPreMemConfigGuid  =  { 0x830a222b, 0x3ff5, 0x432e, { 0x9d, 0xd5, 0x4e, 0xe3, 0xfc, 0xa2, 0xaa, 0xa2}}
+gGnaConfigGuid  =  { 0x53e0ef18, 0xb8a8, 0x4795, { 0xa6, 0x6d, 0xe4, 0x77, 0x2c, 0xc3, 0xae, 0x82}}
+gVtdConfigGuid  =  { 0x03e5cf63, 0xbebb, 0x4041, { 0xb7, 0xe7, 0xbf, 0x54, 0x61, 0x20, 0xf1, 0xc5}}
+gGraphicsDxeConfigGuid  =  {0x34d93161, 0xf78e, 0x4915, {0xad, 0xc4, 0xdb, 0x67, 0x16, 0x42, 0x39, 0x24}}
+gMiscDxeConfigGuid  =  {0x7ce5f5ef, 0x4ef1, 0x4f9f, {0x8e, 0x29, 0x5f, 0xf4, 0x5f, 0x2f, 0xd8, 0xaf}}
+gPcieDxeConfigGuid  =  {0x1ed2d6f1, 0xa9d2, 0x476e, {0x8e, 0x74, 0xad, 0xd9, 0x5b, 0x5,  0x10, 0x82}}
+gMemoryDxeConfigGuid  =  {0xa5c7dda8, 0x686b, 0x404f, {0x86, 0x40, 0xf8, 0x2,  0xd,  0x84, 0x4c, 0x94}}
+gVbiosDxeConfigGuid  =  {0x8df0f30a, 0x8156, 0x4897, {0xa2, 0x18, 0x1f, 0xd3, 0x91, 0xbc, 0x46, 0x26}}
+gSaOverclockingPreMemConfigGuid  =  { 0x09ecc29d, 0xdbbe, 0x49fb, { 0xa6, 0x49, 0x4b, 0xf6, 0x40, 0xe2, 0xeb, 0xd6}}
+gFspReservedMemoryResourceHobTsegGuid  =  { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}}
+
+## 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}}
+
+## 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 }}
+
+##
+## 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}}
+gHtBistHobGuid  =  {0xbe644001, 0xe7d4, 0x48b1, {0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7}}
+gCpuInitDataHobGuid  =  {0x266e31cc, 0x13c5, 0x4807, {0xb9, 0xdc, 0x39, 0xa6, 0xba, 0x88, 0xff, 0x1a}}
+gEpcBiosDataGuid  =  {0xc60aa7f6, 0xe8d6, 0x4956, {0x8b, 0xa1, 0xfe, 0x26, 0x29, 0x8f, 0x5e, 0x87}}
+gCpuSecurityPreMemConfigGuid = {0xfd5c346, 0x8260, 0x4067, {0x94, 0x69, 0xcf, 0x91, 0x68, 0xa3, 0x42, 0x90}}
+gCpuConfigLibPreMemConfigGuid = {0xfc1c0ec2, 0xc6b4, 0x4f05, {0xbb, 0x85, 0xc8, 0x0, 0x8d, 0x5b, 0x4a, 0xb7}}
+gCpuSgxConfigGuid = {0xc30bc5ac, 0x828a, 0x45ae, {0x83, 0x1b, 0x8e, 0xb, 0x73, 0x9a, 0xb2, 0xf2}}
+gCpuTestConfigGuid = {0xd4dba957, 0xd9c, 0x4af2, {0x9d, 0x40, 0x35, 0xa8, 0x44, 0xe4, 0x93, 0xad}}
+gCpuConfigGuid = {0x48c3aac9, 0xd66c, 0x42e4, {0x9b, 0x1d, 0x39, 0x4, 0x5f, 0x46, 0x53, 0x41}}
+gCpuOverclockingPreMemConfigGuid = {0x396223b6, 0x6088, 0x44e7, {0x99, 0xcb, 0xfa, 0x8b, 0x99, 0x3d, 0xed, 0x4c}}
+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}}
+gCpuPowerMgmtTestConfigGuid = {0x5161ed3d, 0x90bf, 0x436f, {0xb8, 0x33, 0xd7, 0x17, 0x89, 0xb3, 0x48, 0xc1}}
+
+##
+## Me
+##
+gMePeiPreMemConfigGuid  =  {0x67ed113b, 0xd4ab, 0x43f5, {0x9c, 0x3c, 0x35, 0x44, 0x15, 0xaa, 0x47, 0x5c}}
+gMePeiConfigGuid  =  {0x9bad5628, 0x657b, 0x48e3, {0xb1, 0x11, 0xc3, 0xb9, 0xeb, 0xea, 0xee, 0x17}}
+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}}
+
+##
+## 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 = {0x8c7ee32c, 0x0870, 0x4bfa, {0x84, 0x79, 0x5b, 0xa5, 0x67, 0xc4, 0xae, 0x5b}}
+
+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}}
+gTraceHubPreMemConfigGuid  =  {0xC26AC3F6, 0xDAD0, 0x4E91, {0xB6, 0xD6, 0xD8, 0x51, 0x6F, 0x8F, 0x9B, 0x7B}}
+gPchTraceHubPreMemConfigGuid  = {0x8456c11, 0xdb85, 0x4914, {0x8d, 0x1a, 0xe5, 0xac, 0x64, 0x37, 0xe8, 0x96}}
+gPcieRpPreMemConfigGuid  =  {0x8377AB38, 0xF8B0, 0x476A, { 0x9C, 0xA1, 0x68, 0xEA, 0x78, 0x57, 0xD8, 0x2A}}
+gHpetPreMemConfigGuid  =  {0x7C75C0F1, 0xA20F, 0x42EB, {0x83, 0xDE, 0xE8, 0x58, 0xAB, 0x81, 0xC5, 0xDC}}
+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}}
+gHsioPreMemConfigGuid  =  {0xbc9e5787, 0x3ddb, 0x4916, {0x8c, 0xcc, 0x82, 0xb8, 0x9, 0x43, 0xe2, 0xf0}} #deprecated
+
+gPchGeneralConfigGuid  =  {0x6ED94C8C, 0x25F7, 0x4686, {0xB2, 0x46, 0xCA, 0x4D, 0xE2, 0x95, 0x4B, 0x5D}}
+gPcieRpConfigGuid  =  {0x0A53B507, 0x988B, 0x475C, {0xBF, 0x76, 0x33, 0xDE, 0x10, 0x6D, 0x94, 0x84}}
+gSataConfigGuid  =  {0xF5F87B4F, 0xCC3C, 0x408D, {0x89, 0xE3, 0x61, 0xC5, 0x9C, 0x54, 0x07, 0xC4}}
+gIoApicConfigGuid  =  {0x2873D0F1, 0x00F6, 0x40AB, {0xAC, 0x36, 0x9A, 0x68, 0xBA, 0x87, 0x3E, 0x6C}}
+gCio2ConfigGuid  =  {0xFBC4C192, 0x789D, 0x4038, {0x90, 0xE1, 0x5E, 0x6D, 0xFD, 0x52, 0xAF, 0x8A}}
+gDmiConfigGuid  =  {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}}
+gLanConfigGuid  =  {0x4B2DE99E, 0x7517, 0x4D04, {0x8C, 0x02, 0xF1, 0x1A, 0x59, 0x2B, 0x14, 0x2F}}
+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}}
+gPort61ConfigGuid  =  {0x59913475, 0x1960, 0x4099, {0x80, 0xEC, 0xAF, 0xC7, 0xCF, 0x5F, 0x9F, 0xAC}}
+gScsConfigGuid  =  {0xF4DE6D52, 0xB5C9, 0x48C0, {0xA0, 0x4A, 0x68, 0x54, 0x20, 0x94, 0x05, 0xD0}}
+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}}
+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}}
+
+##
+## 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 }}
+gTpmDeviceInstanceTpm20PttGuid        =  {0x72cd3a7b, 0xfea5, 0x4f5e, {0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}}
+gTpmDeviceInstanceTpm20PttPtpGuid     =  {0x93d66f66, 0x55da, 0x4f03, {0x9b, 0x5f, 0x32, 0xcf, 0x9e, 0x54, 0x3b, 0x3a}}
+gEfiTrEEPhysicalPresenceGuid          =  {0xf24643c2, 0xc622, 0x494e, {0x8a, 0x0d, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b}}
+gTcoWdtHobGuid                        = { 0x3e405418, 0x0d8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x08, 0x41, 0x46, 0x8d }}
+
+##
+## Pre-Memory 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}}
+
+##
+## Post-Memory 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}}
+
+[Protocols.common.Private]
+  #
+  # SA
+  #
+  gSaIotrapSmiProtocolGuid        = { 0x1861e089, 0xcaa3, 0x473e, { 0x84, 0x32, 0xdc, 0x1f, 0x94, 0xc6, 0xc1, 0xa6 }}
+
+  #
+  # CPU
+  #
+  gPchPcieIoTrapProtocolGuid      = { 0xd66a1cf,  0x79ad, 0x494b, { 0x97, 0x8b, 0xb2, 0x59, 0x81, 0x68, 0x93, 0x34 }}
+
+[Protocols]
+##
+## IntelFrameworkPkg
+##
+gEfiLegacyBiosProtocolGuid  =  {0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d}}
+gEfiLegacyInterruptProtocolGuid  =  {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}}
+gEfiDataHubProtocolGuid  =  {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}
+
+##
+## MdeModulePkg
+##
+gEfiSmmVariableProtocolGuid  =  {0xed32d533, 0x99e6, 0x4209, {0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7}}
+
+##
+## 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}}
+gGopComponentName2ProtocolGuid  =  {0x651b7ebd, 0xce13, 0x41d0, {0x82, 0xe5, 0xa0, 0x63, 0xab, 0xbe, 0x9b, 0xb6}}
+gGopOverrideProtocolGuid        =  {0x4a89a16e, 0x67b8, 0x4429, {0x8c, 0x47, 0x43, 0x67, 0x90, 0xf2, 0xf2, 0x69}}
+
+##
+## AcpiTables
+##
+gEfiGlobalNvsAreaProtocolGuid  =  {0x074e1e48, 0x8132, 0x47a1, {0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc}}
+
+##
+## Cpu
+##
+gCpuInfoProtocolGuid  =  {0xe223cf65, 0xf6ce, 0x4122, {0xb3, 0xaf, 0x4b, 0xd1, 0x8a, 0xff, 0x40, 0xa1}}
+gCpuNvsAreaProtocolGuid  =  {0xb9cf3f43, 0xbe3e, 0x4e45, {0xa0, 0xbe, 0x1a, 0x4, 0x89, 0xdf, 0x1a, 0xc9}}
+gDxeCpuPolicyProtocolGuid  =  {0x8282b977, 0x22f9, 0x4134, {0x99, 0x43, 0x7b, 0xcc, 0x5f, 0x40, 0x33, 0x52}}
+
+##
+## Me
+##
+gDxeMePolicyGuid                 = {0xa0b5dc52, 0x4f34, 0x3990, {0xd4, 0x91, 0x10, 0x8b, 0xe8, 0xba, 0x75, 0x42}}
+
+##
+## PCH
+##
+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}}
+gPchResetCallbackProtocolGuid  =  {0x3a3300ab, 0xc929, 0x487d, {0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0}}
+gPchNvsAreaProtocolGuid  =  {0x2e058b2b, 0xedc1, 0x4431, {0x87, 0xd9, 0xc6, 0xc4, 0xea, 0x10, 0x2b, 0xe3}}
+gPchEmmcTuningProtocolGuid  =  {0x10fe7e3b, 0xdbe5, 0x4cfa, {0x90, 0x25, 0x40, 0x02, 0xcf, 0xdd, 0xbb, 0x89}}
+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}}
+gPchSraProtocolGuid = {0x7AE12E27, 0x5087, 0x46C8, {0xBF, 0xF0, 0x83, 0x9C, 0x53, 0x7B, 0x25, 0xEB}}
+
+##
+## 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 }}
+
+[Ppis.common.Private]
+
+[Ppis]
+##
+## MdeModulePkg
+##
+gPeiCapsulePpiGuid  =  {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d}}
+gPeiSmmAccessPpiGuid  =  {0x268f33a9, 0xcccd, 0x48be, {0x88, 0x17, 0x86, 0x05, 0x3a, 0xc3, 0x2e, 0xd6}}
+gPeiSmmControlPpiGuid  =  {0x61c68702, 0x4d7e, 0x4f43, {0x8d, 0xef, 0xa7, 0x43, 0x05, 0xce, 0x74, 0xc5}}
+
+##
+## SecurityPkg
+##
+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}}
+
+##
+## 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}}
+
+##
+## Cpu
+##
+gPeiCachePpiGuid  =  {0x09be4bc2, 0x790e, 0x4dea, {0x8b, 0xdc, 0x38, 0x05, 0x16, 0x98, 0x39, 0x44}}
+
+##
+## Me
+##
+gMeDidSentPpiGuid = {0x45dc3106, 0xef67, 0x4c71, {0xb0, 0xf0, 0x97, 0x15, 0x9c, 0x7d, 0xbb, 0x7c}}
+
+##
+## 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}}
+gPchResetCallbackPpiGuid  =  {0x17865dc0, 0x0b8b, 0x4da8, {0x8b, 0x42, 0x7c, 0x46, 0xb8, 0x5c, 0xca, 0x4d}}
+
+[LibraryClasses]
+##
+## Common
+##
+AslUpdateLib|Include/Library/AslUpdateLib.h
+SiPolicyLib|Include/Library/SiPolicyLib.h
+UsbLib|Include/Library/UsbLib.h
+UsbInitLib|Include/Private/Library/UsbInitLib.h
+
+##
+## CPU
+##
+CpuMailboxLib|Cpu/Include/Library/CpuMailboxLib.h
+CpuPlatformLib|Cpu/Include/Library/CpuPlatformLib.h
+CpuPolicyLib|Cpu/Include/Library/CpuPolicyLib.h
+
+##
+## Me
+##
+PeiMePolicyLib|Me/Include/Library/PeiMePolicyLib.h
+
+##
+## Pch
+##
+GpioLib|Pch/Include/Library/GpioLib.h
+GpioLib|Pch/Include/Library/GpioNativeLib.h
+PchCycleDecodingLib|Pch/Include/Library/PchCycleDecodingLib.h
+PchEspiLib|Pch/Include/Library/PchEspiLib.h
+PchGbeLib|Pch/Include/Library/PchGbeLib.h
+GbeMdiLib|Pch/Include/Library/GbeMdiLib.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
+PchPmcLib|Pch/Include/Library/PchPmcLib.h
+PchPolicyLib|Pch/Include/Library/PchPolicyLib.h
+PchSbiAccessLib|Pch/Include/Library/PchSbiAccessLib.h
+PchSerialIoLib|Pch/Include/Library/PchSerialIoLib.h
+PchSerialIoUartLib|Pch/Include/Library/PchSerialIoUartLib.h
+SecPchLib|Pch/Include/Library/SecPchLib.h
+PchTraceHubLib|Pch/Include/Private/Library/PchTraceHubLib.h
+PchSmmControlLib|Pch/IncludePrivate/Library/PchSmmControlLib.h
+PchWdtCommonLib|Pch/Include/Library/PchWdtCommonLib.h
+OcWdtLib|Pch/Include/Library/OcWdtLib.h
+PchResetLib|Pch/Include/Library/PchResetLib.h
+DxePchPolicyLib|Pch/Include/Library/DxePchPolicyLib.h
+GpioNameBufferLib|Pch/IncludePrivate/Library/GpioNameBufferLib.h
+
+##
+## Sa
+##
+DxeSaPolicyLib|SystemAgent/Include/Library/DxeSaPolicyLib.h
+PeiSaPolicyLib|SystemAgent/Include/Library/PeiSaPolicyLib.h
+SaPlatformLib|SystemAgent/Include/Library/SaPlatformLib.h
+
+##
+## Memory
+##
+
+[PcdsFixedAtBuild]
+## From MdeModulePkg.dec
+## 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.PcdFlashMicrocodeFvBase|0xFFE60000|UINT32|0x30000004
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize|0x000A0000|UINT32|0x30000005
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|0x00660000|UINT32|0x30000006
+
+##
+## 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
+
+gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi|0x55|UINT8|0x0010005
+gSiPkgTokenSpaceGuid.PcdHwpSmi|0x27|UINT8|0x40000001
+gSiPkgTokenSpaceGuid.PcdItbmSmi|0x29|UINT8|0x40000002
+
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioBase|0x0000004000000000|UINT64|0x40000003
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioSize|0x0000004000000000|UINT64|0x40000004
+
+[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
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+## Maximun number of performance log entries during PEI phase.
+gSiPkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|40|UINT8|0x0001002f
+## This value is used to set the base address of MCH
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress|0xFED10000|UINT64|0x00010030
+## This value is used to set the base address of PCH devices
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress|0x0000EFA0|UINT16|0x00010031
+gSiPkgTokenSpaceGuid.PcdTcoBaseAddress|0x0400|UINT16|0x00010034
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress|0x1800|UINT16|0x00010035
+
+## 32KB window
+gSiPkgTokenSpaceGuid.PcdMchMmioSize|0x8000|UINT32|0x50000000
+
+## 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
+
+##
+## Default 8MB TSEG
+##
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000|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
+##
+
+##Major:To represent code generation
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionMajor   |0x07|UINT8|0x00010049
+
+##Revision:Weekly build number
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionRevision|0x57|UINT8|0x00010051
+
+##Build[7:4]:Daily build number.
+##Build[3:0]:Patch build number.
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionBuild   |0x40|UINT8|0x00010052
+
+
+##
+## 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.PcdHpetBaseAddress    |0xFED00000|UINT32|0x00010057
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress  |0xFED00000|UINT32|0x00010060
+##
+## This PCD specifies the base address of the IO APIC.
+## The acceptable values are 0xFECxx000.
+##
+#gSiPkgTokenSpaceGuid.PcdIoApicBaseAddress  |0xFEC00000|UINT32|0x00010058
+##
+## Regbar Base Address
+##
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress|0xFC000000|UINT32|0x00010059
+
+## 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
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+##
+## SerialIo Uart Configuration
+##
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable |0      |UINT8 |0x00100001 # 0:Disable, 1:Enable and Initialize, 2:Enable without Initializing
+gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber      |2      |UINT8 |0x00100002
+gSiPkgTokenSpaceGuid.PcdSerialIoUartInputClock  |1843200|UINT32|0x00100003
+gSiPkgTokenSpaceGuid.PcdSerialIoUart0PinMuxing  |0      |UINT8 |0x00100009 # 0: default pins, 1: pins muxed with CNV_BRI/RGI
+##
+## PCI Express MMIO region length
+## Valid settings: 0x10000000/256MB, 0x8000000/128MB, 0x4000000/64MB
+##
+gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000|UINT32|0x0010004
+
+## Indidates if SMM Save State saved in MSRs.
+#  if enabled, SMM Save State will use the MSRs instead of the memory.<BR><BR>
+#   TRUE  - SMM Save State will use the MSRs.<BR>
+#   FALSE - SMM Save State will use the memory.<BR>
+# @Prompt SMM Save State uses MSRs.
+gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable|FALSE|BOOLEAN|0x20000001
+[PcdsDynamic]
+
+## Indidates if SMM Delay feature is supported.<BR><BR>
+#   TRUE  - SMM Delay feature is supported.<BR>
+#   FALSE - SMM Delay feature is not supported.<BR>
+# @Prompt SMM Delay feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication|TRUE|BOOLEAN|0x0010009
+
+## Indidates if SMM Block feature is supported.<BR><BR>
+#   TRUE  - SMM Block feature is supported.<BR>
+#   FALSE - SMM Block feature is not supported.<BR>
+# @Prompt SMM Block feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication|TRUE|BOOLEAN|0x001000A
+
+## Indidates if SMM Enable/Disable feature is supported.<BR><BR>
+#   TRUE  - SMM Enable/Disable feature is supported.<BR>
+#   FALSE - SMM Enable/Disable feature is not supported.<BR>
+# @Prompt SMM Enable/Disable feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication|TRUE|BOOLEAN|0x001000B
+
+## 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|TRUE|BOOLEAN|0x001000C
+
+## 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
+
+[PcdsFeatureFlag]
+##
+## Those PCDs are used to control build process.
+##
+gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE|BOOLEAN|0xF0000001
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |FALSE|BOOLEAN|0xF0000002
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE|BOOLEAN|0xF0000004
+gSiPkgTokenSpaceGuid.PcdSiCsmEnable                  |FALSE|BOOLEAN|0xF0000005
+gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE |BOOLEAN|0xF0000006
+gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE |BOOLEAN|0xF0000008
+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.PcdSmbiosEnable                 |TRUE |BOOLEAN|0xF0000014
+gSiPkgTokenSpaceGuid.PcdS3Enable                     |TRUE |BOOLEAN|0xF0000015
+gSiPkgTokenSpaceGuid.PcdOverclockEnable              |FALSE|BOOLEAN|0xF0000016
+gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable       |FALSE|BOOLEAN|0xF0000017
+gSiPkgTokenSpaceGuid.PcdIgdEnable                    |TRUE |BOOLEAN|0xF000001A
+gSiPkgTokenSpaceGuid.PcdPegEnable                    |TRUE |BOOLEAN|0xF000001B
+gSiPkgTokenSpaceGuid.PcdSaDmiEnable                  |TRUE |BOOLEAN|0xF000001C
+gSiPkgTokenSpaceGuid.PcdIpuEnable                    |TRUE |BOOLEAN|0xF000001D
+gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE |BOOLEAN|0xF000001E
+gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE |BOOLEAN|0xF000001F
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE |BOOLEAN|0xF0000020
+gSiPkgTokenSpaceGuid.PcdBdatEnable                   |FALSE|BOOLEAN|0xF0000023
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE |BOOLEAN|0xF0000024
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE |BOOLEAN|0xF0000025
+gSiPkgTokenSpaceGuid.PcdCflCpuEnable                 |FALSE|BOOLEAN|0xF0000027
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |FALSE|BOOLEAN|0xF0000029
+gSiPkgTokenSpaceGuid.PcdMinTreeEnable                |FALSE|BOOLEAN|0xF000002A  # To separate modules used in mininal source tree and advanced features
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |FALSE|BOOLEAN|0xF0000033
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE|BOOLEAN|0xF0000034
+
+gSiPkgTokenSpaceGuid.PcdEdk2MasterEnable             |FALSE|BOOLEAN|0xF0000035
+gSiPkgTokenSpaceGuid.PcdPpamEnable                   |TRUE |BOOLEAN|0xF0000036
+
+#This PCD is used to enable WDT for debug purposes in OverClocking.
+gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug          |FALSE|BOOLEAN|0xF0000037
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
new file mode 100644
index 0000000000..d0e3d94418
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
new file mode 100644
index 0000000000..27b5a9440e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
@@ -0,0 +1,89 @@
+/** @file
+  Si Config Block
+
+  Copyright (c) 2019 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  3
+
+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
+  <b>Revision 3</b>
+  - Deprecated SkipPostBootSai
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Offset 0 - 27 Config Block Header
+  //
+  // Platform specific common policies that used by several silicon components.
+  //
+  UINT32 CsmFlag          :  1;  ///< Offset 44 BIT0: CSM status flag.
+  /**
+    @deprecated since revision 3
+  **/
+  UINT32 SkipPostBootSai  :  1;
+  UINT32 RsvdBits         : 30;  ///< Reserved
+  UINT32 *SsidTablePtr;          // Offset 48
+  UINT16 NumberOfSsidTableEntry; // Offset 52
+  UINT16 Reserved;               // Offset 54
+  /**
+    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
+} SI_CONFIG;
+
+#pragma pack (pop)
+
+#define DEFAULT_SSVID    0x8086
+#define DEFAULT_SSDID    0x7270
+#define 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 {
+      UINT64  Register:12;
+      UINT64  Function:3;
+      UINT64  Device:5;
+      UINT64  Bus:8;
+      UINT64  Reserved1:4;
+      UINT64  Segment:16;
+      UINT64  Reserved2:16;
+    } Bits;
+    UINT64    SegBusDevFuncRegister;
+  } Address;
+  SVID_SID_VALUE SvidSidValue;
+  UINT32 Reserved;
+} SVID_SID_INIT_ENTRY;
+
+#endif // _SI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
new file mode 100644
index 0000000000..8b51e2d47a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
@@ -0,0 +1,291 @@
+/** @file
+  Common USB policy shared between PCH and CPU
+  Contains general features settings for xHCI and xDCI
+
+  Copyright (c) 2019 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 3
+extern EFI_GUID gUsbConfigGuid;
+
+#define MAX_USB2_PORTS  16
+#define MAX_USB3_PORTS  10
+
+#pragma pack (push,1)
+
+#define PCH_USB_OC_PINS_MAX  8  ///< Maximal possible number of USB Over Current pins
+
+///
+/// Overcurrent pins, the values match the setting of EDS, please refer to EDS for more details
+///
+typedef enum {
+  UsbOverCurrentPin0 = 0,
+  UsbOverCurrentPin1,
+  UsbOverCurrentPin2,
+  UsbOverCurrentPin3,
+  UsbOverCurrentPin4,
+  UsbOverCurrentPin5,
+  UsbOverCurrentPin6,
+  UsbOverCurrentPin7,
+  UsbOverCurrentPinMax,
+  UsbOverCurrentPinSkip = 0xFF
+} USB_OVERCURRENT_PIN;
+
+/**
+  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;
+} USB20_AFE;
+
+/**
+  This structure configures per USB2 port physical settings.
+  It allows to setup the port location and port length, and configures the port strength accordingly.
+**/
+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 (see: USB_OVERCURRENT_PIN).
+  **/
+  UINT32     OverCurrentPin     :  8;
+  UINT32     Enable             :  1;     ///< 0: Disable; <b>1: Enable</b>.
+  UINT32     RsvdBits0          : 23;     ///< Reserved bits
+  /**
+    Changing this policy values from default ones may require disabling USB2 PHY Sus Well Power Gating
+    through Usb2PhySusPgEnable on PCH-LP
+  **/
+  USB20_AFE  Afe;                         ///< USB2 AFE settings
+} USB20_PORT_CONFIG;
+
+/**
+  This structure describes whether the USB3 Port N is enabled by platform modules.
+**/
+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 (see: USB_OVERCURRENT_PIN).
+  **/
+  UINT32  OverCurrentPin            :  8;
+
+  /**
+    USB 3.0 TX Output Downscale Amplitude Adjustment (orate01margin)
+    HSIO_TX_DWORD8[21:16]
+    <b>Default = 00h</b>
+  **/
+  UINT32  HsioTxDownscaleAmp        :  8;
+  /**
+    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)
+  **/
+  UINT32  HsioTxDeEmph              :  8;
+
+  UINT32  Enable                    :  1; ///< 0: Disable; <b>1: Enable</b>.
+  UINT32  HsioTxDeEmphEnable        :  1; ///< Enable the write to USB 3.0 TX Output -3.5dB De-Emphasis Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioTxDownscaleAmpEnable  :  1; ///< Enable the write to USB 3.0 TX Output Downscale Amplitude Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                 :  5; ///< Reserved bits
+} USB30_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;
+
+//
+// Below defines are for proper UPD construction and values syncing between UPD and policy
+//
+#define B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN      BIT0  ///< Enable the write to Signed Magnatude number added to the CTLE code bit
+#define B_XHCI_HSIO_FILTER_SELECT_N_EN            BIT1  ///< Enable the write to LFPS filter select for n
+#define B_XHCI_HSIO_FILTER_SELECT_P_EN            BIT2  ///< Enable the write to LFPS filter select for p
+#define B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN    BIT3  ///< Enable the write to olfpscfgpullupdwnres
+#define N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG     3
+#define N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES   0
+#define N_XHCI_UPD_HSIO_FILTER_SELECT_P           0
+#define N_XHCI_UPD_HSIO_FILTER_SELECT_N           4
+
+typedef struct {
+  /**
+    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>
+  **/
+  UINT32  HsioCtrlAdaptOffsetCfg      :  5;
+  /**
+    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>
+  **/
+  UINT32  HsioFilterSelN              :  3;
+  /**
+    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>
+  **/
+  UINT32  HsioFilterSelP              :  3;
+  /**
+    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>
+  **/
+  UINT32  HsioOlfpsCfgPullUpDwnRes    :  3;
+
+  UINT32  HsioCtrlAdaptOffsetCfgEnable    :  1; ///< Enable the write to Signed Magnatude number added to the CTLE code, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioFilterSelNEnable            :  1; ///< Enable the write to LFPS filter select for n, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioFilterSelPEnable            :  1; ///< Enable the write to LFPS filter select for p, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioOlfpsCfgPullUpDwnResEnable  :  1; ///< Enable the write to olfpscfgpullupdwnres, <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                       : 14; ///< Reserved bits
+} USB30_HSIO_RX_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>:
+  - Added Usb2PhySusPgEnable - for enabling/disabling USB2 PHY SUS Well Power Gating
+  <b>Revision 3</b>:
+    Added HSIO Rx tuning policy options structure USB30_HSIO_RX_CONFIG
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
+  /**
+    This policy setting controls state of Compliance Mode enabling.
+    Compliance Mode can be enabled for testing through this option but defualt setting is Disabled.
+    <b>0:Disable</b>, 1: Enable
+  **/
+  UINT32                  EnableComplianceMode         :  1;
+  /**
+    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;
+  /**
+    <b>(Test)</b>
+    This policy option enables USB2 PHY SUS Well Power Gating functionality.
+    Please note this is ignored on PCH H
+    <b>0: disable USB2 PHY SUS Well Power Gating</b>
+    1: enable USB2 PHY SUS Well Power Gating
+  **/
+  UINT32                  Usb2PhySusPgEnable           :  1;
+  UINT32                  RsvdBits0                    : 27;     ///< Reserved bits
+  /**
+    These members describe whether the USB2 Port N of PCH is enabled by platform modules.
+  **/
+  USB20_PORT_CONFIG       PortUsb20[MAX_USB2_PORTS];
+  /**
+    These members describe whether the USB3 Port N of PCH is enabled by platform modules.
+  **/
+  USB30_PORT_CONFIG       PortUsb30[MAX_USB3_PORTS];
+  /**
+    This member describes whether or not the xDCI controller should be enabled.
+  **/
+  XDCI_CONFIG             XdciConfig;
+  /**
+    This member describes policy options for RX signal tuning in ModPHY
+  **/
+  USB30_HSIO_RX_CONFIG    PortUsb30HsioRx[MAX_USB3_PORTS];
+} USB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _USB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..39baa6c03a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,157 @@
+/** @file
+  ASL dynamic update library definitions.
+  This library provides dymanic update to various ASL structures.
+  There may be different libraries for different environments (PEI, BS, RT, SMM).
+  Make sure you meet the requirements for the library (protocol dependencies, use
+  restrictions, etc).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ASL_UPDATE_LIB_H_
+#define _ASL_UPDATE_LIB_H_
+
+//
+// Include files
+//
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+//
+// AML parsing definitions
+//
+#define AML_RESRC_TEMP_END_TAG  0x0079
+
+//
+// ASL PSS package structure layout
+//
+#pragma pack (1)
+typedef struct {
+  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
+  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
+  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
+  UINT8     DwordPrefix1;     // 0Ch
+  UINT32    CoreFrequency;    // 00h
+  UINT8     DwordPrefix2;     // 0Ch
+  UINT32    Power;            // 00h
+  UINT8     DwordPrefix3;     // 0Ch
+  UINT32    TransLatency;     // 00h
+  UINT8     DwordPrefix4;     // 0Ch
+  UINT32    BmLatency;        // 00h
+  UINT8     DwordPrefix5;     // 0Ch
+  UINT32    Control;          // 00h
+  UINT8     DwordPrefix6;     // 0Ch
+  UINT32    Status;           // 00h
+} PSS_PACKAGE_LAYOUT;
+#pragma pack()
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  );
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature               The signature of Operation Region that we want to update.
+  @param[in] Buffer                     source of data to be written over original aml
+  @param[in] Length                     length of data to be overwritten
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode(
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  );
+
+/**
+  This procedure will update the name of ASL Method
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateMethodAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI table using the .
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+  Matches are determined by finding the table with ACPI table that has
+  a matching signature and version.
+
+  @param[in] Signature                  Pointer to an ASCII string containing the Signature to match
+  @param[in, out] Table                 Updated with a pointer to the table
+  @param[in, out] Handle                AcpiSupport protocol table handle for the table found
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI SSDT table.
+  The table is located by searching for a matching OEM Table ID field.
+  Partial match searches are supported via the TableIdSize parameter.
+
+  @param[in] TableId                    Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize                Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                        will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table                 Updated with a pointer to the table
+  @param[in, out] Handle                AcpiSupport protocol table handle for the table found
+  @param[in, out] Version               See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer                     Pointer to buffer to checksum
+  @param[in] Size                       Number of bytes to checksum
+  @param[in] ChecksumOffset             Offset to place the checksum result in
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
new file mode 100644
index 0000000000..9a3bf373a6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
@@ -0,0 +1,64 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
new file mode 100644
index 0000000000..858f8ac5e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
@@ -0,0 +1,28 @@
+/** @file
+  Get Pci Express address library implementation.
+
+  Copyright (c) 2019 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
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+);
+
+#endif // _PEI_DXE_SMM_MM_PCI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
new file mode 100644
index 0000000000..c6eb70f6e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Header file for PEI SiPolicyUpdate Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_UPDATE_LIB_H_
+#define _PEI_SI_POLICY_UPDATE_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  This function performs Silicon PEI Policy initialization.
+
+  @param[in, out] SiPolicy The Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS      The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicy (
+  IN OUT SI_POLICY_PPI *SiPolicy
+  );
+
+/**
+  This function performs CPU PEI Policy initialization in Post-memory.
+
+  @param[in, out] SiPolicyPpi     The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+  IN OUT  SI_POLICY_PPI *SiPolicyPpi
+  );
+
+/**
+  This function performs SI PEI Policy initialization.
+
+  @param[in, out] SiPolicyPpi     The SA Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicy (
+  IN OUT   SI_POLICY_PPI  *SiPolicyPpi
+  );
+
+
+/**
+This function performs SA PEI Policy initialization for PreMem.
+
+@param[in, out] SiPreMemPolicyPpi   The SI PreMem Policy PPI instance
+
+@retval EFI_SUCCESS             Update complete.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyPreMem (
+IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicyPpi
+);
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicy (
+  IN OUT  SI_POLICY_PPI         *SiPolicy
+  );
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPreMemPolicy  The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
+  );
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPolicy       The SI Policy PPI instance
+
+  @retval EFI_SUCCESS            Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicy (
+  IN OUT  SI_POLICY_PPI         *SiPolicy
+  );
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPreMemPolicy The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS            Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
new file mode 100644
index 0000000000..fd8582b981
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
@@ -0,0 +1,58 @@
+/** @file
+  Prototype of the SiConfigBlockLib library.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
new file mode 100644
index 0000000000..5633e2892c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
@@ -0,0 +1,110 @@
+/** @file
+  Prototype of the SiPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_LIB_H_
+#define _SI_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole SI_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi          The RC PREMEM Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi          The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPrintPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  );
+
+/**
+  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreatePreMemConfigBlocks (
+  OUT  SI_PREMEM_POLICY_PPI         **SiPreMemPolicyPpi
+  );
+
+/**
+  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreateConfigBlocks (
+  OUT  SI_POLICY_PPI         **SiPolicyPpi
+  );
+
+/**
+  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPreMemPolicyPpi   The pointer to Silicon PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiPreMemInstallPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  SiInstallPolicyPpi installs SiPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiInstallPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  );
+
+/**
+  Print out all silicon policy information.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval none
+**/
+VOID
+DumpSiPolicy (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  );
+
+#endif // _SI_PREMEM_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
new file mode 100644
index 0000000000..cab5342c54
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for a library to install StallPpi.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _STALL_PPI_LIB_H_
+#define _STALL_PPI_LIB_H_
+
+/**
+  This function is to install StallPpi
+
+  @retval  EFI_SUCCESS if Ppi is installed successfully.
+**/
+EFI_STATUS
+EFIAPI
+InstallStallPpi(
+  VOID
+  );
+#endif //_STALL_PPI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
new file mode 100644
index 0000000000..a7cd305c62
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Header file of available functions in general USB Library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB_LIB_H_
+#define _USB_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+
+/*
+  Disables requested ports through Port Disable Override register programming
+
+  @param[in]  XhciMmioBase        xHCI Memory BAR0 address
+  @param[in]  Usb2DisabledPorts   Disabled ports bitmask with a bit for each USB2 port
+                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
+  @param[in]  Usb3DisabledPorts   Disabled ports bitmask with a bit for each USB3 port
+                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
+
+  @retval EFI_SUCCESS             Programming ended successfully and no errors occured
+          EFI_ACCESS_DENIED       Port Disable Override register was locked and write
+                                  didn't go through. Platform may require restart to unlock.
+*/
+EFI_STATUS
+UsbDisablePorts (
+  IN  UINTN   XhciMmioBase,
+  IN  UINT32  Usb2DisabledPorts,
+  IN  UINT32  Usb3DisabledPorts
+  );
+
+#endif // _USB_LIB_H
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
new file mode 100644
index 0000000000..86bed53c6f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
@@ -0,0 +1,319 @@
+/** @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) 2019 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_PI_OFFSET                           0x09
+#define R_PCI_SCC_OFFSET                          0x0A
+#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
+#define B_PCI_BRIDGE_BNUM_PBN                     0x000000FF ///< Primary Bus Number
+#define B_PCI_BRIDGE_BNUM_SBBN_SCBN               (B_PCI_BRIDGE_BNUM_SBBN | B_PCI_BRIDGE_BNUM_SCBN)
+
+#define R_PCI_BRIDGE_IOBL                         0x1C ///< I/O Base and Limit Register
+
+#define R_PCI_BRIDGE_MBL                          0x20 ///< Memory Base and Limit Register
+#define B_PCI_BRIDGE_MBL_ML                       0xFFF00000 ///< Memory Limit
+#define B_PCI_BRIDGE_MBL_MB                       0x0000FFF0 ///< Memory Base
+
+#define R_PCI_BRIDGE_PMBL                         0x24 ///< Prefetchable Memory Base and Limit Register
+#define B_PCI_BRIDGE_PMBL_PML                     0xFFF00000 ///< Prefetchable Memory Limit
+#define B_PCI_BRIDGE_PMBL_I64L                    0x000F0000 ///< 64-bit Indicator
+#define B_PCI_BRIDGE_PMBL_PMB                     0x0000FFF0 ///< Prefetchable Memory Base
+#define B_PCI_BRIDGE_PMBL_I64B                    0x0000000F ///< 64-bit Indicator
+
+#define R_PCI_BRIDGE_PMBU32                       0x28 ///< Prefetchable Memory Base Upper 32-Bit Register
+#define B_PCI_BRIDGE_PMBU32                       0xFFFFFFFF
+
+#define R_PCI_BRIDGE_PMLU32                       0x2C ///< Prefetchable Memory Limit Upper 32-Bit Register
+#define B_PCI_BRIDGE_PMLU32                       0xFFFFFFFF
+
+//
+// PCIE capabilities register
+//
+#define R_PCIE_CAP_ID_OFFSET                      0x00 ///< Capability ID
+#define R_PCIE_CAP_NEXT_PRT_OFFSET                0x01 ///< Next Capability Capability ID Pointer
+
+//
+// PCI Express Capability List Register (CAPID:10h)
+//
+#define R_PCIE_XCAP_OFFSET                        0x02 ///< PCI Express Capabilities Register (Offset 02h)
+#define S_PCIE_XCAP                               2
+#define B_PCIE_XCAP_SI                            BIT8 ///< Slot Implemented
+#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 S_PCIE_DCAP                               4
+#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 B_PCIE_DCTL_URE                           BIT3 ///< Unsupported Request Reporting Enable
+#define B_PCIE_DCTL_FEE                           BIT2 ///< Fatal Error Reporting Enable
+#define B_PCIE_DCTL_NFE                           BIT1 ///< Non-Fatal Error Reporting Enable
+#define B_PCIE_DCTL_CEE                           BIT0 ///< Correctable Error Reporting Enable
+
+#define R_PCIE_DSTS_OFFSET                        0x0A ///< Device Status Register (Offset 0Ah)
+#define B_PCIE_DSTS_TDP                           BIT5 ///< Transactions Pending
+#define B_PCIE_DSTS_APD                           BIT4 ///< AUX Power Detected
+#define B_PCIE_DSTS_URD                           BIT3 ///< Unsupported Request Detected
+#define B_PCIE_DSTS_FED                           BIT2 ///< Fatal Error Detected
+#define B_PCIE_DSTS_NFED                          BIT1 ///< Non-Fatal Error Detected
+#define B_PCIE_DSTS_CED                           BIT0 ///< Correctable Error Detected
+
+#define R_PCIE_LCAP_OFFSET                        0x0C ///< Link Capabilities Register (Offset 0Ch)
+#define B_PCIE_LCAP_ASPMOC                        BIT22 ///< ASPM Optionality Compliance
+#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                          (BIT11 | BIT10) ///< Active State Power Management (ASPM) Support
+#define B_PCIE_LCAP_APMS_L0S                      BIT10
+#define B_PCIE_LCAP_APMS_L1                       BIT11
+#define N_PCIE_LCAP_APMS                          10
+#define B_PCIE_LCAP_MLW                           0x000003F0 ///< Maximum Link Width
+#define N_PCIE_LCAP_MLW                           4
+#define B_PCIE_LCAP_MLS                           (BIT3 | BIT2 | BIT1 | BIT0) ///< Max Link Speed
+#define V_PCIE_LCAP_MLS_GEN3                      3
+
+#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_ES                            BIT7 ///< Extended Synch
+#define B_PCIE_LCTL_CCC                           BIT6 ///< Common Clock Configuration
+#define B_PCIE_LCTL_RL                            BIT5 ///< Retrain Link
+#define B_PCIE_LCTL_LD                            BIT4 ///< Link Disable
+#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 V_PCIE_LSTS_NLW_1                         0x0010
+#define V_PCIE_LSTS_NLW_2                         0x0020
+#define V_PCIE_LSTS_NLW_4                         0x0040
+#define B_PCIE_LSTS_CLS                           0x000F ///< Current Link Speed
+#define V_PCIE_LSTS_CLS_GEN1                      1
+#define V_PCIE_LSTS_CLS_GEN2                      2
+#define V_PCIE_LSTS_CLS_GEN3                      3
+
+#define R_PCIE_SLCAP_OFFSET                       0x14 ///< Slot Capabilities Register (Offset 14h)
+#define S_PCIE_SLCAP                              4
+#define B_PCIE_SLCAP_PSN                          0xFFF80000 ///< Physical Slot Number
+#define B_PCIE_SLCAP_SLS                          0x00018000 ///< Slot Power Limit Scale
+#define B_PCIE_SLCAP_SLV                          0x00007F80 ///< Slot Power Limit Value
+#define B_PCIE_SLCAP_HPC                          BIT6 ///< Hot-Plug Capable
+#define B_PCIE_SLCAP_HPS                          BIT5 ///< Hot-Plug Surprise
+
+#define R_PCIE_SLCTL_OFFSET                       0x18 ///< Slot Control Register (Offset 18h)
+#define S_PCIE_SLCTL                              2
+#define B_PCIE_SLCTL_HPE                          BIT5 ///< Hot Plug Interrupt Enable
+#define B_PCIE_SLCTL_PDE                          BIT3 ///< Presence Detect Changed Enable
+
+#define R_PCIE_SLSTS_OFFSET                       0x1A ///< Slot Status Register (Offset 1Ah)
+#define S_PCIE_SLSTS                              2
+#define B_PCIE_SLSTS_PDS                          BIT6 ///< Presence Detect State
+#define B_PCIE_SLSTS_PDC                          BIT3 ///< Presence Detect Changed
+
+#define R_PCIE_RCTL_OFFSET                        0x1C ///< Root Control Register (Offset 1Ch)
+#define S_PCIE_RCTL                               2
+#define B_PCIE_RCTL_PIE                           BIT3 ///< PME Interrupt Enable
+#define B_PCIE_RCTL_SFE                           BIT2 ///< System Error on Fatal Error Enable
+#define B_PCIE_RCTL_SNE                           BIT1 ///< System Error on Non-Fatal Error Enable
+#define B_PCIE_RCTL_SCE                           BIT0 ///< System Error on Correctable Error Enable
+
+#define R_PCIE_RSTS_OFFSET                        0x20 ///< Root Status Register (Offset 20h)
+#define S_PCIE_RSTS                               4
+
+#define R_PCIE_DCAP2_OFFSET                       0x24 ///< Device Capabilities 2 Register (Offset 24h)
+#define B_PCIE_DCAP2_OBFFS                        (BIT19 | BIT18) ///< OBFF Supported
+#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_OBFFEN                       (BIT14 | BIT13) ///< OBFF Enable
+#define N_PCIE_DCTL2_OBFFEN                       13
+#define V_PCIE_DCTL2_OBFFEN_DIS                   0 ///< Disabled
+#define V_PCIE_DCTL2_OBFFEN_WAKE                  3 ///< Enabled using WAKE# signaling
+#define B_PCIE_DCTL2_LTREN                        BIT10 ///< LTR Mechanism Enable
+#define B_PCIE_DCTL2_CTD                          BIT4 ///< Completion Timeout Disable
+#define B_PCIE_DCTL2_CTV                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Completion Timeout Value
+#define V_PCIE_DCTL2_CTV_DEFAULT                  0x0
+#define V_PCIE_DCTL2_CTV_40MS_50MS                0x5
+#define V_PCIE_DCTL2_CTV_160MS_170MS              0x6
+#define V_PCIE_DCTL2_CTV_400MS_500MS              0x9
+#define V_PCIE_DCTL2_CTV_1P6S_1P7S                0xA
+
+#define R_PCIE_LCTL2_OFFSET                       0x30 ///< Link Control 2 Register (Offset 30h)
+#define B_PCIE_LCTL2_SD                           BIT6 ///< Selectable de-emphasis (0 = -6dB, 1 = -3.5dB)
+#define B_PCIE_LCTL2_TLS                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Target Link Speed
+#define V_PCIE_LCTL2_TLS_GEN1                     1
+#define V_PCIE_LCTL2_TLS_GEN2                     2
+#define V_PCIE_LCTL2_TLS_GEN3                     3
+
+#define R_PCIE_LSTS2_OFFSET                       0x32 ///< Link Status 2 Register (Offset 32h)
+#define B_PCIE_LSTS2_LER                          BIT5 ///< Link Equalization Request
+#define B_PCIE_LSTS2_EQP3S                        BIT4 ///< Equalization Phase 3 Successful
+#define B_PCIE_LSTS2_EQP2S                        BIT3 ///< Equalization Phase 2 Successful
+#define B_PCIE_LSTS2_EQP1S                        BIT2 ///< Equalization Phase 1 Successful
+#define B_PCIE_LSTS2_EC                           BIT1 ///< Equalization Complete
+#define B_PCIE_LSTS2_CDL                          BIT0 ///< Current De-emphasis Level
+
+//
+// PCI Power Management Capability (CAPID:01h)
+//
+#define R_PCIE_PMC_OFFSET                         0x02 ///< Power Management Capabilities Register
+#define S_PCIE_PMC                                2
+#define B_PCIE_PMC_PMES                           (BIT15 | BIT14 | BIT13 | BIT12 | BIT11) ///< PME Support
+#define B_PCIE_PMC_PMEC                           BIT3 ///< PME Clock
+
+#define R_PCIE_PMCS_OFFST                         0x04 ///< Power Management Status/Control Register
+#define S_PCIE_PMCS                               4
+#define B_PCIE_PMCS_BPCE                          BIT23 ///< Bus Power/Clock Control Enable
+#define B_PCIE_PMCS_B23S                          BIT22 ///< B2/B3 Support
+#define B_PCIE_PMCS_PMES                          BIT15 ///< PME_Status
+#define B_PCIE_PMCS_PMEE                          BIT8 ///< PME Enable
+#define B_PCIE_PMCS_NSR                           BIT3 ///< No Soft Reset
+#define B_PCIE_PMCS_PS                            (BIT1 | BIT0) ///< Power State
+#define V_PCIE_PMCS_PS_D0                         0
+#define V_PCIE_PMCS_PS_D3H                        3
+
+//
+// PCIE Extension Capability Register
+//
+#define B_PCIE_EXCAP_NCO                          0xFFF00000 ///< Next Capability Offset
+#define N_PCIE_EXCAP_NCO                          20
+#define V_PCIE_EXCAP_NCO_LISTEND                  0
+#define B_PCIE_EXCAP_CV                           0x000F0000 ///< Capability Version
+#define N_PCIE_EXCAP_CV                           16
+#define B_PCIE_EXCAP_CID                          0x0000FFFF ///< Capability ID
+
+//
+// Advanced Error Reporting Capability (CAPID:0001h)
+//
+#define V_PCIE_EX_AEC_CID                         0x0001 ///< Capability ID
+#define R_PCIE_EX_UEM_OFFSET                      0x08 ///< Uncorrectable Error Mask Register
+#define B_PCIE_EX_UEM_CT                          BIT14 ///< Completion Timeout Mask
+#define B_PCIE_EX_UEM_UC                          BIT16 ///< Unexpected Completion
+
+//
+// ACS Extended Capability (CAPID:000Dh)
+//
+#define V_PCIE_EX_ACS_CID                         0x000D ///< Capability ID
+#define R_PCIE_EX_ACSCAPR_OFFSET                  0x04 ///< ACS Capability Register
+//#define R_PCIE_EX_ACSCTLR_OFFSET                  0x08 ///< ACS Control Register (NOTE: register size in PCIE spce is not match the PCH register size)
+
+
+//
+// Latency Tolerance Reporting Extended Capability Registers (CAPID:0018h)
+//
+#define R_PCH_PCIE_LTRECH_CID                     0x0018
+#define R_PCH_PCIE_LTRECH_MSLR_OFFSET             0x04
+#define N_PCH_PCIE_LTRECH_MSLR_VALUE              0
+#define N_PCH_PCIE_LTRECH_MSLR_SCALE              10
+#define R_PCH_PCIE_LTRECH_MNSLR_OFFSET            0x06
+#define N_PCH_PCIE_LTRECH_MNSLR_VALUE             0
+#define N_PCH_PCIE_LTRECH_MNSLR_SCALE             10
+//
+// Secondary PCI Express Extended Capability Header (CAPID:0019h)
+//
+#define V_PCIE_EX_SPE_CID                         0x0019 ///< Capability ID
+#define R_PCIE_EX_LCTL3_OFFSET                    0x04 ///< Link Control 3 Register
+#define B_PCIE_EX_LCTL3_PE                        BIT0 ///< Perform Equalization
+#define R_PCIE_EX_LES_OFFSET                      0x08 ///< Lane Error Status
+#define R_PCIE_EX_L01EC_OFFSET                    0x0C ///< Lane 0 and Lan 1 Equalization Control Register (Offset 0Ch)
+#define B_PCIE_EX_L01EC_UPL1TP                    0x0F000000 ///< Upstream Port Lane 1 Transmitter Preset
+#define N_PCIE_EX_L01EC_UPL1TP                    24
+#define B_PCIE_EX_L01EC_DPL1TP                    0x000F0000 ///< Downstream Port Lane 1 Transmitter Preset
+#define N_PCIE_EX_L01EC_DPL1TP                    16
+#define B_PCIE_EX_L01EC_UPL0TP                    0x00000F00 ///< Upstream Port Transmitter Preset
+#define N_PCIE_EX_L01EC_UPL0TP                    8
+#define B_PCIE_EX_L01EC_DPL0TP                    0x0000000F ///< Downstream Port Transmitter Preset
+#define N_PCIE_EX_L01EC_DPL0TP                    0
+
+#define R_PCIE_EX_L23EC_OFFSET                    0x10 ///< Lane 2 and Lane 3 Equalization Control Register (Offset 10h)
+#define B_PCIE_EX_L23EC_UPL3TP                    0x0F000000 ///< Upstream Port Lane 3 Transmitter Preset
+#define N_PCIE_EX_L23EC_UPL3TP                    24
+#define B_PCIE_EX_L23EC_DPL3TP                    0x000F0000 ///< Downstream Port Lane 3 Transmitter Preset
+#define N_PCIE_EX_L23EC_DPL3TP                    16
+#define B_PCIE_EX_L23EC_UPL2TP                    0x00000F00 ///< Upstream Port Lane 2 Transmitter Preset
+#define N_PCIE_EX_L23EC_UPL2TP                    8
+#define B_PCIE_EX_L23EC_DPL2TP                    0x0000000F ///< Downstream Port Lane 2 Transmitter Preset
+#define N_PCIE_EX_L23EC_DPL2TP                    0
+
+
+//
+// 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  V_PCIE_EX_L1SCAP_PTPOS_2us               0
+#define  V_PCIE_EX_L1SCAP_PTPOS_10us              1
+#define  V_PCIE_EX_L1SCAP_PTPOS_100us             2
+#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 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
+
+//
+// Base Address Offset
+//
+#define R_BASE_ADDRESS_OFFSET_0                   0x0010 ///< Base Address Register 0
+#define R_BASE_ADDRESS_OFFSET_1                   0x0014 ///< Base Address Register 1
+#define R_BASE_ADDRESS_OFFSET_2                   0x0018 ///< Base Address Register 2
+#define R_BASE_ADDRESS_OFFSET_3                   0x001C ///< Base Address Register 3
+#define R_BASE_ADDRESS_OFFSET_4                   0x0020 ///< Base Address Register 4
+#define R_BASE_ADDRESS_OFFSET_5                   0x0024 ///< Base Address Register 5
+#define B_PCI_BAR_MEMORY_TYPE_MASK                (BIT1 | BIT2)
+#define B_PCI_BAR_MEMORY_TYPE_64                  BIT2
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
new file mode 100644
index 0000000000..ac270e24fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
@@ -0,0 +1,29 @@
+/** @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) 2019 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 <PchAccess.h>
+#include <PchPolicyCommon.h>
+#include <PchPreMemPolicyCommon.h>
+#include <SaPolicyCommon.h>
+#include <CpuPolicyCommon.h>
+
+extern EFI_GUID gSiPreMemPolicyPpiGuid;
+extern EFI_GUID gSiPolicyPpiGuid;
+
+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/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
new file mode 100644
index 0000000000..fe676f8519
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
@@ -0,0 +1,26 @@
+/** @file
+  PCIe Initialization Library header file
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_INIT_LIB_H_
+#define _PCIE_INIT_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/GpioLib.h>
+#include <SaRegs.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
new file mode 100644
index 0000000000..f05cf0fdea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for USB initialization library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB_INIT_LIB_H_
+#define _USB_INIT_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Common entry point for PCH and CPU xDCI controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XdciPciMmBase       xDCI PCI config space address
+**/
+VOID
+XdciConfigure (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Common entry point for PCH and CPU xHCI controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciMmBase       xHCI PCI config space address
+**/
+VOID
+XhciConfigure (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Configure xHCI after initialization
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciMmBase       XHCI PCI CFG Base Address
+**/
+VOID
+XhciConfigureAfterInit (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Locks xHCI configuration by setting the proper lock bits in controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciBase         xHCI PCI config space address
+**/
+VOID
+XhciLockConfiguration (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciBase
+  );
+
+/**
+  Tune the USB 2.0 high-speed signals quality.
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+**/
+VOID
+Usb2AfeProgramming (
+  IN  USB_CONFIG      *UsbConfig
+  );
+#endif // _USB_INIT_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
new file mode 100644
index 0000000000..671e94b3bc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
@@ -0,0 +1,60 @@
+/** @file
+  Protocol used for specifying platform related Silicon information and policy setting.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_PROTOCOL_H_
+#define _SI_POLICY_PROTOCOL_H_
+
+#include <IndustryStandard/Hsti.h>
+
+//
+// DXE_SI_POLICY_PROTOCOL revisions
+//
+#define DXE_SI_POLICY_PROTOCOL_REVISION 2
+
+extern EFI_GUID gDxeSiPolicyProtocolGuid;
+
+#pragma pack (push,1)
+
+/**
+  The protocol allows the platform code to publish a set of configuration information that the
+  Silicon drivers will use to configure the processor in the DXE phase.
+  This Policy Protocol needs to be initialized for Silicon configuration.
+  @note The Protocol has to be published before processor DXE drivers are dispatched.
+**/
+typedef struct {
+  /**
+  This member specifies the revision of the Si Policy protocol. This field is used to indicate backward
+  compatible changes to the protocol. Any such changes to this protocol will result in an update in the revision number.
+
+  <b>Revision 1</b>:
+   - Initial version
+  <b>Revision 2</b>:
+   - Added SmbiosOemTypeFirmwareVersionInfo to determines the SMBIOS OEM type
+  **/
+  UINT8                          Revision;
+  /**
+    SmbiosOemTypeFirmwareVersionInfo 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.
+  **/
+  UINT8                          SmbiosOemTypeFirmwareVersionInfo;
+  UINT8                          ReservedByte[6];  ///< Reserved bytes, align to multiple 8.
+  /**
+    This member describes a pointer to Hsti results from previous boot. In order to mitigate the large performance cost
+    of performing all of the platform security tests on each boot, we can save the results across boots and retrieve
+    and point this policy to them prior to the launch of HstiSiliconDxe. Logic should be implemented to not populate this
+    upon major platform changes (i.e changes to setup option or platform hw)to ensure that results accurately reflect the
+    configuration of the platform.
+  **/
+  ADAPTER_INFO_PLATFORM_SECURITY *Hsti;    ///< This is a pointer to Hsti results from previous boot
+  UINTN                          HstiSize; ///< Size of results, if setting Hsti policy to point to previous results
+} DXE_SI_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
new file mode 100644
index 0000000000..58a185c8fd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
@@ -0,0 +1,55 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _REGS_USB_H_
+#define _REGS_USB_H_
+
+//
+// USB3 (XHCI) related definitions
+// @todo: Add CPU PCI defs for xHCI
+//
+#define PCI_BUS_NUMBER_PCH_XHCI             0
+#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
+#endif // _REGS_USB_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
new file mode 100644
index 0000000000..b5aeccbe5d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
@@ -0,0 +1,19 @@
+/** @file
+  Silicon Config HOB is used for gathering platform
+  related Intel silicon information and config setting.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
new file mode 100644
index 0000000000..da16aad257
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
@@ -0,0 +1,65 @@
+/** @file
+  Intel reference code configuration policies.
+
+  Copyright (c) 2019 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/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;
+/*
+  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;
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
new file mode 100644
index 0000000000..7e056a25af
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
@@ -0,0 +1,23 @@
+/** @file
+ Common configurations for CPU and PCH trace hub
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TRACE_HUB_COMMON_CONFIG_H_
+#define _TRACE_HUB_COMMON_CONFIG_H_
+
+///
+/// The TRACE_HUB_ENABLE_MODE describes the desired TraceHub mode of operation
+///
+typedef enum {
+  TraceHubModeDisabled       = 0,       ///< TraceHub Disabled
+  TraceHubModeTargetDebugger = 1,       ///< TraceHub Target Debugger mode, debug on target device itself, config to PCI mode
+  TraceHubModeHostDebugger   = 2,       ///< TraceHub Host Debugger mode, debugged by host with cable attached, config to ACPI mode
+  TraceHubModeMax
+} TRACE_HUB_ENABLE_MODE;
+
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers

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

Adds Pch/Include headers.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h               | 135 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h               | 326 +++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h             | 381 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h            | 340 +++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h             | 241 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h            | 200 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h                |  54 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h                   |  38 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h               |  80 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h                |  53 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h  |  47 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h          |  47 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h    |  59 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h     |  53 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h |  23 ++
 15 files changed, 2077 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
new file mode 100644
index 0000000000..91222fd54d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
@@ -0,0 +1,135 @@
+/** @file
+  Header file for DxePchHdaNhltLib - NHLT structure definitions.
+
+  Copyright (c) 2019 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
+#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_DEVICE_TYPE
+{
+  HdaNhltDeviceBt   = 0,
+  HdaNhltDeviceDmic = 1,
+  HdaNhltDeviceI2s  = 4,
+  HdaNhltDeviceInvalid
+};
+
+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_HDA_NHLT_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
new file mode 100644
index 0000000000..babbf1ce3a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
@@ -0,0 +1,326 @@
+/** @file
+  Header file for GpioConfig structure used by GPIO library.
+
+  Copyright (c) 2019 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;
+
+
+///
+/// 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 {
+  GpioPadModeGpio     = 0x1,
+  GpioPadModeNative1  = 0x3,
+  GpioPadModeNative2  = 0x5,
+  GpioPadModeNative3  = 0x7,
+  GpioPadModeNative4  = 0x9,
+  GpioPadModeNative5  = 0xB
+} 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
+} 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/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
new file mode 100644
index 0000000000..524328d3e3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
@@ -0,0 +1,381 @@
+/** @file
+  GPIO pins,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_CNL_H_H_
+#define _GPIO_PINS_CNL_H_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_CNL_H_CHIPSET_ID       0x3
+
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_CNL_H_GROUP_GPP_A  0x0300
+#define GPIO_CNL_H_GROUP_GPP_B  0x0301
+#define GPIO_CNL_H_GROUP_GPP_C  0x0302
+#define GPIO_CNL_H_GROUP_GPP_D  0x0303
+#define GPIO_CNL_H_GROUP_GPP_E  0x0304
+#define GPIO_CNL_H_GROUP_GPP_F  0x0305
+#define GPIO_CNL_H_GROUP_GPP_G  0x0306
+#define GPIO_CNL_H_GROUP_GPP_H  0x0307
+#define GPIO_CNL_H_GROUP_GPP_I  0x0308
+#define GPIO_CNL_H_GROUP_GPP_J  0x0309
+#define GPIO_CNL_H_GROUP_GPP_K  0x030A
+#define GPIO_CNL_H_GROUP_GPD    0x030B
+#define GPIO_CNL_H_GROUP_VGPIO  0x030C
+#define GPIO_CNL_H_GROUP_SPI    0x030D
+#define GPIO_CNL_H_GROUP_AZA    0x030E
+#define GPIO_CNL_H_GROUP_CPU    0x030F
+#define GPIO_CNL_H_GROUP_JTAG   0x0310
+
+///
+/// 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_CNL_H_GPP_A0               0x03000000
+#define GPIO_CNL_H_GPP_A1               0x03000001
+#define GPIO_CNL_H_GPP_A2               0x03000002
+#define GPIO_CNL_H_GPP_A3               0x03000003
+#define GPIO_CNL_H_GPP_A4               0x03000004
+#define GPIO_CNL_H_GPP_A5               0x03000005
+#define GPIO_CNL_H_GPP_A6               0x03000006
+#define GPIO_CNL_H_GPP_A7               0x03000007
+#define GPIO_CNL_H_GPP_A8               0x03000008
+#define GPIO_CNL_H_GPP_A9               0x03000009
+#define GPIO_CNL_H_GPP_A10              0x0300000A
+#define GPIO_CNL_H_GPP_A11              0x0300000B
+#define GPIO_CNL_H_GPP_A12              0x0300000C
+#define GPIO_CNL_H_GPP_A13              0x0300000D
+#define GPIO_CNL_H_GPP_A14              0x0300000E
+#define GPIO_CNL_H_GPP_A15              0x0300000F
+#define GPIO_CNL_H_GPP_A16              0x03000010
+#define GPIO_CNL_H_GPP_A17              0x03000011
+#define GPIO_CNL_H_GPP_A18              0x03000012
+#define GPIO_CNL_H_GPP_A19              0x03000013
+#define GPIO_CNL_H_GPP_A20              0x03000014
+#define GPIO_CNL_H_GPP_A21              0x03000015
+#define GPIO_CNL_H_GPP_A22              0x03000016
+#define GPIO_CNL_H_GPP_A23              0x03000017
+#define GPIO_CNL_H_ESPI_CLK_LOOPBK      0x03000018
+
+#define GPIO_CNL_H_GPP_B0               0x03010000
+#define GPIO_CNL_H_GPP_B1               0x03010001
+#define GPIO_CNL_H_GPP_B2               0x03010002
+#define GPIO_CNL_H_GPP_B3               0x03010003
+#define GPIO_CNL_H_GPP_B4               0x03010004
+#define GPIO_CNL_H_GPP_B5               0x03010005
+#define GPIO_CNL_H_GPP_B6               0x03010006
+#define GPIO_CNL_H_GPP_B7               0x03010007
+#define GPIO_CNL_H_GPP_B8               0x03010008
+#define GPIO_CNL_H_GPP_B9               0x03010009
+#define GPIO_CNL_H_GPP_B10              0x0301000A
+#define GPIO_CNL_H_GPP_B11              0x0301000B
+#define GPIO_CNL_H_GPP_B12              0x0301000C
+#define GPIO_CNL_H_GPP_B13              0x0301000D
+#define GPIO_CNL_H_GPP_B14              0x0301000E
+#define GPIO_CNL_H_GPP_B15              0x0301000F
+#define GPIO_CNL_H_GPP_B16              0x03010010
+#define GPIO_CNL_H_GPP_B17              0x03010011
+#define GPIO_CNL_H_GPP_B18              0x03010012
+#define GPIO_CNL_H_GPP_B19              0x03010013
+#define GPIO_CNL_H_GPP_B20              0x03010014
+#define GPIO_CNL_H_GPP_B21              0x03010015
+#define GPIO_CNL_H_GPP_B22              0x03010016
+#define GPIO_CNL_H_GPP_B23              0x03010017
+#define GPIO_CNL_H_GSPI0_CLK_LOOPBK     0x03010018
+#define GPIO_CNL_H_GSPI1_CLK_LOOPBK     0x03010019
+
+#define GPIO_CNL_H_GPP_C0               0x03020000
+#define GPIO_CNL_H_GPP_C1               0x03020001
+#define GPIO_CNL_H_GPP_C2               0x03020002
+#define GPIO_CNL_H_GPP_C3               0x03020003
+#define GPIO_CNL_H_GPP_C4               0x03020004
+#define GPIO_CNL_H_GPP_C5               0x03020005
+#define GPIO_CNL_H_GPP_C6               0x03020006
+#define GPIO_CNL_H_GPP_C7               0x03020007
+#define GPIO_CNL_H_GPP_C8               0x03020008
+#define GPIO_CNL_H_GPP_C9               0x03020009
+#define GPIO_CNL_H_GPP_C10              0x0302000A
+#define GPIO_CNL_H_GPP_C11              0x0302000B
+#define GPIO_CNL_H_GPP_C12              0x0302000C
+#define GPIO_CNL_H_GPP_C13              0x0302000D
+#define GPIO_CNL_H_GPP_C14              0x0302000E
+#define GPIO_CNL_H_GPP_C15              0x0302000F
+#define GPIO_CNL_H_GPP_C16              0x03020010
+#define GPIO_CNL_H_GPP_C17              0x03020011
+#define GPIO_CNL_H_GPP_C18              0x03020012
+#define GPIO_CNL_H_GPP_C19              0x03020013
+#define GPIO_CNL_H_GPP_C20              0x03020014
+#define GPIO_CNL_H_GPP_C21              0x03020015
+#define GPIO_CNL_H_GPP_C22              0x03020016
+#define GPIO_CNL_H_GPP_C23              0x03020017
+
+#define GPIO_CNL_H_GPP_D0               0x03030000
+#define GPIO_CNL_H_GPP_D1               0x03030001
+#define GPIO_CNL_H_GPP_D2               0x03030002
+#define GPIO_CNL_H_GPP_D3               0x03030003
+#define GPIO_CNL_H_GPP_D4               0x03030004
+#define GPIO_CNL_H_GPP_D5               0x03030005
+#define GPIO_CNL_H_GPP_D6               0x03030006
+#define GPIO_CNL_H_GPP_D7               0x03030007
+#define GPIO_CNL_H_GPP_D8               0x03030008
+#define GPIO_CNL_H_GPP_D9               0x03030009
+#define GPIO_CNL_H_GPP_D10              0x0303000A
+#define GPIO_CNL_H_GPP_D11              0x0303000B
+#define GPIO_CNL_H_GPP_D12              0x0303000C
+#define GPIO_CNL_H_GPP_D13              0x0303000D
+#define GPIO_CNL_H_GPP_D14              0x0303000E
+#define GPIO_CNL_H_GPP_D15              0x0303000F
+#define GPIO_CNL_H_GPP_D16              0x03030010
+#define GPIO_CNL_H_GPP_D17              0x03030011
+#define GPIO_CNL_H_GPP_D18              0x03030012
+#define GPIO_CNL_H_GPP_D19              0x03030013
+#define GPIO_CNL_H_GPP_D20              0x03030014
+#define GPIO_CNL_H_GPP_D21              0x03030015
+#define GPIO_CNL_H_GPP_D22              0x03030016
+#define GPIO_CNL_H_GPP_D23              0x03030017
+
+#define GPIO_CNL_H_GPP_E0               0x03040000
+#define GPIO_CNL_H_GPP_E1               0x03040001
+#define GPIO_CNL_H_GPP_E2               0x03040002
+#define GPIO_CNL_H_GPP_E3               0x03040003
+#define GPIO_CNL_H_GPP_E4               0x03040004
+#define GPIO_CNL_H_GPP_E5               0x03040005
+#define GPIO_CNL_H_GPP_E6               0x03040006
+#define GPIO_CNL_H_GPP_E7               0x03040007
+#define GPIO_CNL_H_GPP_E8               0x03040008
+#define GPIO_CNL_H_GPP_E9               0x03040009
+#define GPIO_CNL_H_GPP_E10              0x0304000A
+#define GPIO_CNL_H_GPP_E11              0x0304000B
+#define GPIO_CNL_H_GPP_E12              0x0304000C
+
+#define GPIO_CNL_H_GPP_F0               0x03050000
+#define GPIO_CNL_H_GPP_F1               0x03050001
+#define GPIO_CNL_H_GPP_F2               0x03050002
+#define GPIO_CNL_H_GPP_F3               0x03050003
+#define GPIO_CNL_H_GPP_F4               0x03050004
+#define GPIO_CNL_H_GPP_F5               0x03050005
+#define GPIO_CNL_H_GPP_F6               0x03050006
+#define GPIO_CNL_H_GPP_F7               0x03050007
+#define GPIO_CNL_H_GPP_F8               0x03050008
+#define GPIO_CNL_H_GPP_F9               0x03050009
+#define GPIO_CNL_H_GPP_F10              0x0305000A
+#define GPIO_CNL_H_GPP_F11              0x0305000B
+#define GPIO_CNL_H_GPP_F12              0x0305000C
+#define GPIO_CNL_H_GPP_F13              0x0305000D
+#define GPIO_CNL_H_GPP_F14              0x0305000E
+#define GPIO_CNL_H_GPP_F15              0x0305000F
+#define GPIO_CNL_H_GPP_F16              0x03050010
+#define GPIO_CNL_H_GPP_F17              0x03050011
+#define GPIO_CNL_H_GPP_F18              0x03050012
+#define GPIO_CNL_H_GPP_F19              0x03050013
+#define GPIO_CNL_H_GPP_F20              0x03050014
+#define GPIO_CNL_H_GPP_F21              0x03050015
+#define GPIO_CNL_H_GPP_F22              0x03050016
+#define GPIO_CNL_H_GPP_F23              0x03050017
+
+#define GPIO_CNL_H_GPP_G0               0x03060000
+#define GPIO_CNL_H_GPP_G1               0x03060001
+#define GPIO_CNL_H_GPP_G2               0x03060002
+#define GPIO_CNL_H_GPP_G3               0x03060003
+#define GPIO_CNL_H_GPP_G4               0x03060004
+#define GPIO_CNL_H_GPP_G5               0x03060005
+#define GPIO_CNL_H_GPP_G6               0x03060006
+#define GPIO_CNL_H_GPP_G7               0x03060007
+
+#define GPIO_CNL_H_GPP_H0               0x03070000
+#define GPIO_CNL_H_GPP_H1               0x03070001
+#define GPIO_CNL_H_GPP_H2               0x03070002
+#define GPIO_CNL_H_GPP_H3               0x03070003
+#define GPIO_CNL_H_GPP_H4               0x03070004
+#define GPIO_CNL_H_GPP_H5               0x03070005
+#define GPIO_CNL_H_GPP_H6               0x03070006
+#define GPIO_CNL_H_GPP_H7               0x03070007
+#define GPIO_CNL_H_GPP_H8               0x03070008
+#define GPIO_CNL_H_GPP_H9               0x03070009
+#define GPIO_CNL_H_GPP_H10              0x0307000A
+#define GPIO_CNL_H_GPP_H11              0x0307000B
+#define GPIO_CNL_H_GPP_H12              0x0307000C
+#define GPIO_CNL_H_GPP_H13              0x0307000D
+#define GPIO_CNL_H_GPP_H14              0x0307000E
+#define GPIO_CNL_H_GPP_H15              0x0307000F
+#define GPIO_CNL_H_GPP_H16              0x03070010
+#define GPIO_CNL_H_GPP_H17              0x03070011
+#define GPIO_CNL_H_GPP_H18              0x03070012
+#define GPIO_CNL_H_GPP_H19              0x03070013
+#define GPIO_CNL_H_GPP_H20              0x03070014
+#define GPIO_CNL_H_GPP_H21              0x03070015
+#define GPIO_CNL_H_GPP_H22              0x03070016
+#define GPIO_CNL_H_GPP_H23              0x03070017
+
+#define GPIO_CNL_H_GPP_I0               0x03080000
+#define GPIO_CNL_H_GPP_I1               0x03080001
+#define GPIO_CNL_H_GPP_I2               0x03080002
+#define GPIO_CNL_H_GPP_I3               0x03080003
+#define GPIO_CNL_H_GPP_I4               0x03080004
+#define GPIO_CNL_H_GPP_I5               0x03080005
+#define GPIO_CNL_H_GPP_I6               0x03080006
+#define GPIO_CNL_H_GPP_I7               0x03080007
+#define GPIO_CNL_H_GPP_I8               0x03080008
+#define GPIO_CNL_H_GPP_I9               0x03080009
+#define GPIO_CNL_H_GPP_I10              0x0308000A
+#define GPIO_CNL_H_GPP_I11              0x0308000B
+#define GPIO_CNL_H_GPP_I12              0x0308000C
+#define GPIO_CNL_H_GPP_I13              0x0308000D
+#define GPIO_CNL_H_GPP_I14              0x0308000E
+#define GPIO_CNL_H_SYS_PWROK            0x0308000F
+#define GPIO_CNL_H_SYS_RESETB           0x03080010
+#define GPIO_CNL_H_MLK_RSTB             0x03080011
+
+#define GPIO_CNL_H_GPP_J0               0x03090000
+#define GPIO_CNL_H_GPP_J1               0x03090001
+#define GPIO_CNL_H_GPP_J2               0x03090002
+#define GPIO_CNL_H_GPP_J3               0x03090003
+#define GPIO_CNL_H_GPP_J4               0x03090004
+#define GPIO_CNL_H_GPP_J5               0x03090005
+#define GPIO_CNL_H_GPP_J6               0x03090006
+#define GPIO_CNL_H_GPP_J7               0x03090007
+#define GPIO_CNL_H_GPP_J8               0x03090008
+#define GPIO_CNL_H_GPP_J9               0x03090009
+#define GPIO_CNL_H_GPP_J10              0x0309000A
+#define GPIO_CNL_H_GPP_J11              0x0309000B
+
+#define GPIO_CNL_H_GPP_K0               0x030A0000
+#define GPIO_CNL_H_GPP_K1               0x030A0001
+#define GPIO_CNL_H_GPP_K2               0x030A0002
+#define GPIO_CNL_H_GPP_K3               0x030A0003
+#define GPIO_CNL_H_GPP_K4               0x030A0004
+#define GPIO_CNL_H_GPP_K5               0x030A0005
+#define GPIO_CNL_H_GPP_K6               0x030A0006
+#define GPIO_CNL_H_GPP_K7               0x030A0007
+#define GPIO_CNL_H_GPP_K8               0x030A0008
+#define GPIO_CNL_H_GPP_K9               0x030A0009
+#define GPIO_CNL_H_GPP_K10              0x030A000A
+#define GPIO_CNL_H_GPP_K11              0x030A000B
+#define GPIO_CNL_H_GPP_K12              0x030A000C
+#define GPIO_CNL_H_GPP_K13              0x030A000D
+#define GPIO_CNL_H_GPP_K14              0x030A000E
+#define GPIO_CNL_H_GPP_K15              0x030A000F
+#define GPIO_CNL_H_GPP_K16              0x030A0010
+#define GPIO_CNL_H_GPP_K17              0x030A0011
+#define GPIO_CNL_H_GPP_K18              0x030A0012
+#define GPIO_CNL_H_GPP_K19              0x030A0013
+#define GPIO_CNL_H_GPP_K20              0x030A0014
+#define GPIO_CNL_H_GPP_K21              0x030A0015
+#define GPIO_CNL_H_GPP_K22              0x030A0016
+#define GPIO_CNL_H_GPP_K23              0x030A0017
+
+#define GPIO_CNL_H_GPD0                 0x030B0000
+#define GPIO_CNL_H_GPD1                 0x030B0001
+#define GPIO_CNL_H_GPD2                 0x030B0002
+#define GPIO_CNL_H_GPD3                 0x030B0003
+#define GPIO_CNL_H_GPD4                 0x030B0004
+#define GPIO_CNL_H_GPD5                 0x030B0005
+#define GPIO_CNL_H_GPD6                 0x030B0006
+#define GPIO_CNL_H_GPD7                 0x030B0007
+#define GPIO_CNL_H_GPD8                 0x030B0008
+#define GPIO_CNL_H_GPD9                 0x030B0009
+#define GPIO_CNL_H_GPD10                0x030B000A
+#define GPIO_CNL_H_GPD11                0x030B000B
+#define GPIO_CNL_H_SLP_LANB             0x030B000C
+#define GPIO_CNL_H_SLP_SUSB             0x030B000D
+#define GPIO_CNL_H_SLP_WAKEB            0x030B000E
+#define GPIO_CNL_H_SLP_DRAM_RESETB      0x030B000F
+
+#define GPIO_CNL_H_VGPIO0               0x030C0000
+#define GPIO_CNL_H_VGPIO1               0x030C0001
+#define GPIO_CNL_H_VGPIO2               0x030C0002
+#define GPIO_CNL_H_VGPIO3               0x030C0003
+#define GPIO_CNL_H_VGPIO4               0x030C0004
+#define GPIO_CNL_H_VGPIO5               0x030C0005
+#define GPIO_CNL_H_VGPIO6               0x030C0006
+#define GPIO_CNL_H_VGPIO7               0x030C0007
+#define GPIO_CNL_H_VGPIO8               0x030C0008
+#define GPIO_CNL_H_VGPIO9               0x030C0009
+#define GPIO_CNL_H_VGPIO10              0x030C000A
+#define GPIO_CNL_H_VGPIO11              0x030C000B
+#define GPIO_CNL_H_VGPIO12              0x030C000C
+#define GPIO_CNL_H_VGPIO13              0x030C000D
+#define GPIO_CNL_H_VGPIO14              0x030C000E
+#define GPIO_CNL_H_VGPIO15              0x030C000F
+#define GPIO_CNL_H_VGPIO16              0x030C0010
+#define GPIO_CNL_H_VGPIO17              0x030C0011
+#define GPIO_CNL_H_VGPIO18              0x030C0012
+#define GPIO_CNL_H_VGPIO19              0x030C0013
+#define GPIO_CNL_H_VGPIO20              0x030C0014
+#define GPIO_CNL_H_VGPIO21              0x030C0015
+#define GPIO_CNL_H_VGPIO22              0x030C0016
+#define GPIO_CNL_H_VGPIO23              0x030C0017
+#define GPIO_CNL_H_VGPIO24              0x030C0018
+#define GPIO_CNL_H_VGPIO25              0x030C0019
+#define GPIO_CNL_H_VGPIO26              0x030C001A
+#define GPIO_CNL_H_VGPIO27              0x030C001B
+#define GPIO_CNL_H_VGPIO28              0x030C001C
+#define GPIO_CNL_H_VGPIO29              0x030C001D
+#define GPIO_CNL_H_VGPIO30              0x030C001E
+#define GPIO_CNL_H_VGPIO31              0x030C001F
+#define GPIO_CNL_H_VGPIO32              0x030C0020
+#define GPIO_CNL_H_VGPIO33              0x030C0021
+#define GPIO_CNL_H_VGPIO34              0x030C0022
+#define GPIO_CNL_H_VGPIO35              0x030C0023
+#define GPIO_CNL_H_VGPIO36              0x030C0024
+#define GPIO_CNL_H_VGPIO37              0x030C0025
+#define GPIO_CNL_H_VGPIO38              0x030C0026
+#define GPIO_CNL_H_VGPIO39              0x030C0027
+
+#define GPIO_CNL_H_SPI0_IO_2            0x030D0000
+#define GPIO_CNL_H_SPI0_IO_3            0x030D0001
+#define GPIO_CNL_H_SPI0_MOSI_IO_0       0x030D0002
+#define GPIO_CNL_H_SPI0_MOSI_IO_1       0x030D0003
+#define GPIO_CNL_H_SPI0_TPM_CSB         0x030D0004
+#define GPIO_CNL_H_SPI0_FLASH_0_CSB     0x030D0005
+#define GPIO_CNL_H_SPI0_FLASH_1_CSB     0x030D0006
+#define GPIO_CNL_H_SPI0_CLK             0x030D0007
+#define GPIO_CNL_H_SPI0_CLK_LOOPBK      0x030D0008
+
+#define GPIO_CNL_H_HDA_BCLK             0x030E0000
+#define GPIO_CNL_H_HDA_RSTB             0x030E0001
+#define GPIO_CNL_H_HDA_SYNC             0x030E0002
+#define GPIO_CNL_H_HDA_SDO              0x030E0003
+#define GPIO_CNL_H_HDA_SDI_0            0x030E0004
+#define GPIO_CNL_H_HDA_SDI_1            0x030E0005
+#define GPIO_CNL_H_SSP1_SFRM            0x030E0006
+#define GPIO_CNL_H_SSP1_TXD             0x030E0007
+
+#define GPIO_CNL_H_HDACPU_SDI           0x030F0000
+#define GPIO_CNL_H_HDACPU_SDO           0x030F0001
+#define GPIO_CNL_H_HDACPU_SCLK          0x030F0002
+#define GPIO_CNL_H_PM_SYNC              0x030F0003
+#define GPIO_CNL_H_PECI                 0x030F0004
+#define GPIO_CNL_H_CPUPWRGD             0x030F0005
+#define GPIO_CNL_H_THRMTRIPB            0x030F0006
+#define GPIO_CNL_H_PLTRST_CPUB          0x030F0007
+#define GPIO_CNL_H_PM_DOWN              0x030F0008
+#define GPIO_CNL_H_TRIGGER_IN           0x030F0009
+#define GPIO_CNL_H_TRIGGER_OUT          0x030F000A
+
+#define GPIO_CNL_H_JTAG_TDO             0x03100000
+#define GPIO_CNL_H_JTAGX                0x03100001
+#define GPIO_CNL_H_PRDYB                0x03100002
+#define GPIO_CNL_H_PREQB                0x03100003
+#define GPIO_CNL_H_CPU_TRSTB            0x03100004
+#define GPIO_CNL_H_JTAG_TDI             0x03100005
+#define GPIO_CNL_H_JTAG_TMS             0x03100006
+#define GPIO_CNL_H_JTAG_TCK             0x03100007
+#define GPIO_CNL_H_ITP_PMODE            0x03100008
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
new file mode 100644
index 0000000000..9ce5875ca5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
@@ -0,0 +1,340 @@
+/** @file
+  GPIO pins,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_CNL_LP_H_
+#define _GPIO_PINS_CNL_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_CNL_LP_CHIPSET_ID      0x4
+
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_CNL_LP_GROUP_GPP_A  0x0400
+#define GPIO_CNL_LP_GROUP_GPP_B  0x0401
+#define GPIO_CNL_LP_GROUP_GPP_C  0x0402
+#define GPIO_CNL_LP_GROUP_GPP_D  0x0403
+#define GPIO_CNL_LP_GROUP_GPP_E  0x0404
+#define GPIO_CNL_LP_GROUP_GPP_F  0x0405
+#define GPIO_CNL_LP_GROUP_GPP_G  0x0406
+#define GPIO_CNL_LP_GROUP_GPP_H  0x0407
+#define GPIO_CNL_LP_GROUP_GPD    0x0408
+#define GPIO_CNL_LP_GROUP_VGPIO  0x0409
+#define GPIO_CNL_LP_GROUP_SPI    0x040A
+#define GPIO_CNL_LP_GROUP_AZA    0x040B
+#define GPIO_CNL_LP_GROUP_CPU    0x040C
+#define GPIO_CNL_LP_GROUP_JTAG   0x040D
+#define GPIO_CNL_LP_GROUP_HVMOS  0x040E
+
+///
+/// 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_CNL_LP_GPP_A0               0x04000000
+#define GPIO_CNL_LP_GPP_A1               0x04000001
+#define GPIO_CNL_LP_GPP_A2               0x04000002
+#define GPIO_CNL_LP_GPP_A3               0x04000003
+#define GPIO_CNL_LP_GPP_A4               0x04000004
+#define GPIO_CNL_LP_GPP_A5               0x04000005
+#define GPIO_CNL_LP_GPP_A6               0x04000006
+#define GPIO_CNL_LP_GPP_A7               0x04000007
+#define GPIO_CNL_LP_GPP_A8               0x04000008
+#define GPIO_CNL_LP_GPP_A9               0x04000009
+#define GPIO_CNL_LP_GPP_A10              0x0400000A
+#define GPIO_CNL_LP_GPP_A11              0x0400000B
+#define GPIO_CNL_LP_GPP_A12              0x0400000C
+#define GPIO_CNL_LP_GPP_A13              0x0400000D
+#define GPIO_CNL_LP_GPP_A14              0x0400000E
+#define GPIO_CNL_LP_GPP_A15              0x0400000F
+#define GPIO_CNL_LP_GPP_A16              0x04000010
+#define GPIO_CNL_LP_GPP_A17              0x04000011
+#define GPIO_CNL_LP_GPP_A18              0x04000012
+#define GPIO_CNL_LP_GPP_A19              0x04000013
+#define GPIO_CNL_LP_GPP_A20              0x04000014
+#define GPIO_CNL_LP_GPP_A21              0x04000015
+#define GPIO_CNL_LP_GPP_A22              0x04000016
+#define GPIO_CNL_LP_GPP_A23              0x04000017
+#define GPIO_CNL_LP_ESPI_CLK_LOOPBK      0x04000018
+
+#define GPIO_CNL_LP_GPP_B0               0x04010000
+#define GPIO_CNL_LP_GPP_B1               0x04010001
+#define GPIO_CNL_LP_GPP_B2               0x04010002
+#define GPIO_CNL_LP_GPP_B3               0x04010003
+#define GPIO_CNL_LP_GPP_B4               0x04010004
+#define GPIO_CNL_LP_GPP_B5               0x04010005
+#define GPIO_CNL_LP_GPP_B6               0x04010006
+#define GPIO_CNL_LP_GPP_B7               0x04010007
+#define GPIO_CNL_LP_GPP_B8               0x04010008
+#define GPIO_CNL_LP_GPP_B9               0x04010009
+#define GPIO_CNL_LP_GPP_B10              0x0401000A
+#define GPIO_CNL_LP_GPP_B11              0x0401000B
+#define GPIO_CNL_LP_GPP_B12              0x0401000C
+#define GPIO_CNL_LP_GPP_B13              0x0401000D
+#define GPIO_CNL_LP_GPP_B14              0x0401000E
+#define GPIO_CNL_LP_GPP_B15              0x0401000F
+#define GPIO_CNL_LP_GPP_B16              0x04010010
+#define GPIO_CNL_LP_GPP_B17              0x04010011
+#define GPIO_CNL_LP_GPP_B18              0x04010012
+#define GPIO_CNL_LP_GPP_B19              0x04010013
+#define GPIO_CNL_LP_GPP_B20              0x04010014
+#define GPIO_CNL_LP_GPP_B21              0x04010015
+#define GPIO_CNL_LP_GPP_B22              0x04010016
+#define GPIO_CNL_LP_GPP_B23              0x04010017
+#define GPIO_CNL_LP_GSPI0_CLK_LOOPBK     0x04010018
+#define GPIO_CNL_LP_GSPI1_CLK_LOOPBK     0x04010019
+
+#define GPIO_CNL_LP_GPP_C0               0x04020000
+#define GPIO_CNL_LP_GPP_C1               0x04020001
+#define GPIO_CNL_LP_GPP_C2               0x04020002
+#define GPIO_CNL_LP_GPP_C3               0x04020003
+#define GPIO_CNL_LP_GPP_C4               0x04020004
+#define GPIO_CNL_LP_GPP_C5               0x04020005
+#define GPIO_CNL_LP_GPP_C6               0x04020006
+#define GPIO_CNL_LP_GPP_C7               0x04020007
+#define GPIO_CNL_LP_GPP_C8               0x04020008
+#define GPIO_CNL_LP_GPP_C9               0x04020009
+#define GPIO_CNL_LP_GPP_C10              0x0402000A
+#define GPIO_CNL_LP_GPP_C11              0x0402000B
+#define GPIO_CNL_LP_GPP_C12              0x0402000C
+#define GPIO_CNL_LP_GPP_C13              0x0402000D
+#define GPIO_CNL_LP_GPP_C14              0x0402000E
+#define GPIO_CNL_LP_GPP_C15              0x0402000F
+#define GPIO_CNL_LP_GPP_C16              0x04020010
+#define GPIO_CNL_LP_GPP_C17              0x04020011
+#define GPIO_CNL_LP_GPP_C18              0x04020012
+#define GPIO_CNL_LP_GPP_C19              0x04020013
+#define GPIO_CNL_LP_GPP_C20              0x04020014
+#define GPIO_CNL_LP_GPP_C21              0x04020015
+#define GPIO_CNL_LP_GPP_C22              0x04020016
+#define GPIO_CNL_LP_GPP_C23              0x04020017
+
+#define GPIO_CNL_LP_GPP_D0               0x04030000
+#define GPIO_CNL_LP_GPP_D1               0x04030001
+#define GPIO_CNL_LP_GPP_D2               0x04030002
+#define GPIO_CNL_LP_GPP_D3               0x04030003
+#define GPIO_CNL_LP_GPP_D4               0x04030004
+#define GPIO_CNL_LP_GPP_D5               0x04030005
+#define GPIO_CNL_LP_GPP_D6               0x04030006
+#define GPIO_CNL_LP_GPP_D7               0x04030007
+#define GPIO_CNL_LP_GPP_D8               0x04030008
+#define GPIO_CNL_LP_GPP_D9               0x04030009
+#define GPIO_CNL_LP_GPP_D10              0x0403000A
+#define GPIO_CNL_LP_GPP_D11              0x0403000B
+#define GPIO_CNL_LP_GPP_D12              0x0403000C
+#define GPIO_CNL_LP_GPP_D13              0x0403000D
+#define GPIO_CNL_LP_GPP_D14              0x0403000E
+#define GPIO_CNL_LP_GPP_D15              0x0403000F
+#define GPIO_CNL_LP_GPP_D16              0x04030010
+#define GPIO_CNL_LP_GPP_D17              0x04030011
+#define GPIO_CNL_LP_GPP_D18              0x04030012
+#define GPIO_CNL_LP_GPP_D19              0x04030013
+#define GPIO_CNL_LP_GPP_D20              0x04030014
+#define GPIO_CNL_LP_GPP_D21              0x04030015
+#define GPIO_CNL_LP_GPP_D22              0x04030016
+#define GPIO_CNL_LP_GPP_D23              0x04030017
+
+#define GPIO_CNL_LP_GPP_E0               0x04040000
+#define GPIO_CNL_LP_GPP_E1               0x04040001
+#define GPIO_CNL_LP_GPP_E2               0x04040002
+#define GPIO_CNL_LP_GPP_E3               0x04040003
+#define GPIO_CNL_LP_GPP_E4               0x04040004
+#define GPIO_CNL_LP_GPP_E5               0x04040005
+#define GPIO_CNL_LP_GPP_E6               0x04040006
+#define GPIO_CNL_LP_GPP_E7               0x04040007
+#define GPIO_CNL_LP_GPP_E8               0x04040008
+#define GPIO_CNL_LP_GPP_E9               0x04040009
+#define GPIO_CNL_LP_GPP_E10              0x0404000A
+#define GPIO_CNL_LP_GPP_E11              0x0404000B
+#define GPIO_CNL_LP_GPP_E12              0x0404000C
+#define GPIO_CNL_LP_GPP_E13              0x0404000D
+#define GPIO_CNL_LP_GPP_E14              0x0404000E
+#define GPIO_CNL_LP_GPP_E15              0x0404000F
+#define GPIO_CNL_LP_GPP_E16              0x04040010
+#define GPIO_CNL_LP_GPP_E17              0x04040011
+#define GPIO_CNL_LP_GPP_E18              0x04040012
+#define GPIO_CNL_LP_GPP_E19              0x04040013
+#define GPIO_CNL_LP_GPP_E20              0x04040014
+#define GPIO_CNL_LP_GPP_E21              0x04040015
+#define GPIO_CNL_LP_GPP_E22              0x04040016
+#define GPIO_CNL_LP_GPP_E23              0x04040017
+
+#define GPIO_CNL_LP_GPP_F0               0x04050000
+#define GPIO_CNL_LP_GPP_F1               0x04050001
+#define GPIO_CNL_LP_GPP_F2               0x04050002
+#define GPIO_CNL_LP_GPP_F3               0x04050003
+#define GPIO_CNL_LP_GPP_F4               0x04050004
+#define GPIO_CNL_LP_GPP_F5               0x04050005
+#define GPIO_CNL_LP_GPP_F6               0x04050006
+#define GPIO_CNL_LP_GPP_F7               0x04050007
+#define GPIO_CNL_LP_GPP_F8               0x04050008
+#define GPIO_CNL_LP_GPP_F9               0x04050009
+#define GPIO_CNL_LP_GPP_F10              0x0405000A
+#define GPIO_CNL_LP_GPP_F11              0x0405000B
+#define GPIO_CNL_LP_GPP_F12              0x0405000C
+#define GPIO_CNL_LP_GPP_F13              0x0405000D
+#define GPIO_CNL_LP_GPP_F14              0x0405000E
+#define GPIO_CNL_LP_GPP_F15              0x0405000F
+#define GPIO_CNL_LP_GPP_F16              0x04050010
+#define GPIO_CNL_LP_GPP_F17              0x04050011
+#define GPIO_CNL_LP_GPP_F18              0x04050012
+#define GPIO_CNL_LP_GPP_F19              0x04050013
+#define GPIO_CNL_LP_GPP_F20              0x04050014
+#define GPIO_CNL_LP_GPP_F21              0x04050015
+#define GPIO_CNL_LP_GPP_F22              0x04050016
+#define GPIO_CNL_LP_GPP_F23              0x04050017
+
+#define GPIO_CNL_LP_GPP_G0               0x04060000
+#define GPIO_CNL_LP_GPP_G1               0x04060001
+#define GPIO_CNL_LP_GPP_G2               0x04060002
+#define GPIO_CNL_LP_GPP_G3               0x04060003
+#define GPIO_CNL_LP_GPP_G4               0x04060004
+#define GPIO_CNL_LP_GPP_G5               0x04060005
+#define GPIO_CNL_LP_GPP_G6               0x04060006
+#define GPIO_CNL_LP_GPP_G7               0x04060007
+
+#define GPIO_CNL_LP_GPP_H0               0x04070000
+#define GPIO_CNL_LP_GPP_H1               0x04070001
+#define GPIO_CNL_LP_GPP_H2               0x04070002
+#define GPIO_CNL_LP_GPP_H3               0x04070003
+#define GPIO_CNL_LP_GPP_H4               0x04070004
+#define GPIO_CNL_LP_GPP_H5               0x04070005
+#define GPIO_CNL_LP_GPP_H6               0x04070006
+#define GPIO_CNL_LP_GPP_H7               0x04070007
+#define GPIO_CNL_LP_GPP_H8               0x04070008
+#define GPIO_CNL_LP_GPP_H9               0x04070009
+#define GPIO_CNL_LP_GPP_H10              0x0407000A
+#define GPIO_CNL_LP_GPP_H11              0x0407000B
+#define GPIO_CNL_LP_GPP_H12              0x0407000C
+#define GPIO_CNL_LP_GPP_H13              0x0407000D
+#define GPIO_CNL_LP_GPP_H14              0x0407000E
+#define GPIO_CNL_LP_GPP_H15              0x0407000F
+#define GPIO_CNL_LP_GPP_H16              0x04070010
+#define GPIO_CNL_LP_GPP_H17              0x04070011
+#define GPIO_CNL_LP_GPP_H18              0x04070012
+#define GPIO_CNL_LP_GPP_H19              0x04070013
+#define GPIO_CNL_LP_GPP_H20              0x04070014
+#define GPIO_CNL_LP_GPP_H21              0x04070015
+#define GPIO_CNL_LP_GPP_H22              0x04070016
+#define GPIO_CNL_LP_GPP_H23              0x04070017
+
+#define GPIO_CNL_LP_GPD0                 0x04080000
+#define GPIO_CNL_LP_GPD1                 0x04080001
+#define GPIO_CNL_LP_GPD2                 0x04080002
+#define GPIO_CNL_LP_GPD3                 0x04080003
+#define GPIO_CNL_LP_GPD4                 0x04080004
+#define GPIO_CNL_LP_GPD5                 0x04080005
+#define GPIO_CNL_LP_GPD6                 0x04080006
+#define GPIO_CNL_LP_GPD7                 0x04080007
+#define GPIO_CNL_LP_GPD8                 0x04080008
+#define GPIO_CNL_LP_GPD9                 0x04080009
+#define GPIO_CNL_LP_GPD10                0x0408000A
+#define GPIO_CNL_LP_GPD11                0x0408000B
+#define GPIO_CNL_LP_SLP_LANB             0x0408000C
+#define GPIO_CNL_LP_SLP_SUSB             0x0408000D
+#define GPIO_CNL_LP_SLP_WAKEB            0x0408000E
+#define GPIO_CNL_LP_SLP_DRAM_RESETB      0x0408000F
+
+#define GPIO_CNL_LP_VGPIO0               0x04090000
+#define GPIO_CNL_LP_VGPIO1               0x04090001
+#define GPIO_CNL_LP_VGPIO2               0x04090002
+#define GPIO_CNL_LP_VGPIO3               0x04090003
+#define GPIO_CNL_LP_VGPIO4               0x04090004
+#define GPIO_CNL_LP_VGPIO5               0x04090005
+#define GPIO_CNL_LP_VGPIO6               0x04090006
+#define GPIO_CNL_LP_VGPIO7               0x04090007
+#define GPIO_CNL_LP_VGPIO8               0x04090008
+#define GPIO_CNL_LP_VGPIO9               0x04090009
+#define GPIO_CNL_LP_VGPIO10              0x0409000A
+#define GPIO_CNL_LP_VGPIO11              0x0409000B
+#define GPIO_CNL_LP_VGPIO12              0x0409000C
+#define GPIO_CNL_LP_VGPIO13              0x0409000D
+#define GPIO_CNL_LP_VGPIO14              0x0409000E
+#define GPIO_CNL_LP_VGPIO15              0x0409000F
+#define GPIO_CNL_LP_VGPIO16              0x04090010
+#define GPIO_CNL_LP_VGPIO17              0x04090011
+#define GPIO_CNL_LP_VGPIO18              0x04090012
+#define GPIO_CNL_LP_VGPIO19              0x04090013
+#define GPIO_CNL_LP_VGPIO20              0x04090014
+#define GPIO_CNL_LP_VGPIO21              0x04090015
+#define GPIO_CNL_LP_VGPIO22              0x04090016
+#define GPIO_CNL_LP_VGPIO23              0x04090017
+#define GPIO_CNL_LP_VGPIO24              0x04090018
+#define GPIO_CNL_LP_VGPIO25              0x04090019
+#define GPIO_CNL_LP_VGPIO26              0x0409001A
+#define GPIO_CNL_LP_VGPIO27              0x0409001B
+#define GPIO_CNL_LP_VGPIO28              0x0409001C
+#define GPIO_CNL_LP_VGPIO29              0x0409001D
+#define GPIO_CNL_LP_VGPIO30              0x0409001E
+#define GPIO_CNL_LP_VGPIO31              0x0409001F
+#define GPIO_CNL_LP_VGPIO32              0x04090020
+#define GPIO_CNL_LP_VGPIO33              0x04090021
+#define GPIO_CNL_LP_VGPIO34              0x04090022
+#define GPIO_CNL_LP_VGPIO35              0x04090023
+#define GPIO_CNL_LP_VGPIO36              0x04090024
+#define GPIO_CNL_LP_VGPIO37              0x04090025
+#define GPIO_CNL_LP_VGPIO38              0x04090026
+#define GPIO_CNL_LP_VGPIO39              0x04090027
+
+#define GPIO_CNL_LP_SPI0_IO_2            0x040A0000
+#define GPIO_CNL_LP_SPI0_IO_3            0x040A0001
+#define GPIO_CNL_LP_SPI0_MOSI_IO_0       0x040A0002
+#define GPIO_CNL_LP_SPI0_MOSI_IO_1       0x040A0003
+#define GPIO_CNL_LP_SPI0_TPM_CSB         0x040A0004
+#define GPIO_CNL_LP_SPI0_FLASH_0_CSB     0x040A0005
+#define GPIO_CNL_LP_SPI0_FLASH_1_CSB     0x040A0006
+#define GPIO_CNL_LP_SPI0_CLK             0x040A0007
+#define GPIO_CNL_LP_SPI0_CLK_LOOPBK      0x040A0008
+
+#define GPIO_CNL_LP_HDA_BCLK             0x040B0000
+#define GPIO_CNL_LP_HDA_RSTB             0x040B0001
+#define GPIO_CNL_LP_HDA_SYNC             0x040B0002
+#define GPIO_CNL_LP_HDA_SDO              0x040B0003
+#define GPIO_CNL_LP_HDA_SDI_0            0x040B0004
+#define GPIO_CNL_LP_HDA_SDI_1            0x040B0005
+#define GPIO_CNL_LP_SSP1_SFRM            0x040B0006
+#define GPIO_CNL_LP_SSP1_TXD             0x040B0007
+
+#define GPIO_CNL_LP_HDACPU_SDI           0x040C0000
+#define GPIO_CNL_LP_HDACPU_SDO           0x040C0001
+#define GPIO_CNL_LP_HDACPU_SCLK          0x040C0002
+#define GPIO_CNL_LP_PM_SYNC              0x040C0003
+#define GPIO_CNL_LP_PECI                 0x040C0004
+#define GPIO_CNL_LP_CPUPWRGD             0x040C0005
+#define GPIO_CNL_LP_THRMTRIPB            0x040C0006
+#define GPIO_CNL_LP_PLTRST_CPUB          0x040C0007
+#define GPIO_CNL_LP_PM_DOWN              0x040C0008
+#define GPIO_CNL_LP_TRIGGER_IN           0x040C0009
+#define GPIO_CNL_LP_TRIGGER_OUT          0x040C000A
+
+#define GPIO_CNL_LP_JTAG_TDO             0x040D0000
+#define GPIO_CNL_LP_JTAGX                0x040D0001
+#define GPIO_CNL_LP_PRDYB                0x040D0002
+#define GPIO_CNL_LP_PREQB                0x040D0003
+#define GPIO_CNL_LP_CPU_TRSTB            0x040D0004
+#define GPIO_CNL_LP_JTAG_TDI             0x040D0005
+#define GPIO_CNL_LP_JTAG_TMS             0x040D0006
+#define GPIO_CNL_LP_JTAG_TCK             0x040D0007
+#define GPIO_CNL_LP_ITP_PMODE            0x040D0008
+
+#define GPIO_CNL_LP_HVMOS_L_BKLTEN       0x040E0000
+#define GPIO_CNL_LP_HVMOS_L_BKLTCTL      0x040E0001
+#define GPIO_CNL_LP_HVMOS_L_VDDEN        0x040E0002
+#define GPIO_CNL_LP_HVMOS_SYS_PWROK      0x040E0003
+#define GPIO_CNL_LP_HVMOS_SYS_RESETB     0x040E0004
+#define GPIO_CNL_LP_HVMOS_MLK_RSTB       0x040E0005
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
new file mode 100644
index 0000000000..d3aad4172f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
@@ -0,0 +1,241 @@
+/** @file
+  GPIO pins
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_SKL_H_H_
+#define _GPIO_PINS_SKL_H_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
+///
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_SKL_H_GROUP_GPP_A  0x0100
+#define GPIO_SKL_H_GROUP_GPP_B  0x0101
+#define GPIO_SKL_H_GROUP_GPP_C  0x0102
+#define GPIO_SKL_H_GROUP_GPP_D  0x0103
+#define GPIO_SKL_H_GROUP_GPP_E  0x0104
+#define GPIO_SKL_H_GROUP_GPP_F  0x0105
+#define GPIO_SKL_H_GROUP_GPP_G  0x0106
+#define GPIO_SKL_H_GROUP_GPP_H  0x0107
+#define GPIO_SKL_H_GROUP_GPP_I  0x0108
+#define GPIO_SKL_H_GROUP_GPD    0x0109
+
+///
+/// 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_SKL_H_GPP_A0       0x01000000
+#define GPIO_SKL_H_GPP_A1       0x01000001
+#define GPIO_SKL_H_GPP_A2       0x01000002
+#define GPIO_SKL_H_GPP_A3       0x01000003
+#define GPIO_SKL_H_GPP_A4       0x01000004
+#define GPIO_SKL_H_GPP_A5       0x01000005
+#define GPIO_SKL_H_GPP_A6       0x01000006
+#define GPIO_SKL_H_GPP_A7       0x01000007
+#define GPIO_SKL_H_GPP_A8       0x01000008
+#define GPIO_SKL_H_GPP_A9       0x01000009
+#define GPIO_SKL_H_GPP_A10      0x0100000A
+#define GPIO_SKL_H_GPP_A11      0x0100000B
+#define GPIO_SKL_H_GPP_A12      0x0100000C
+#define GPIO_SKL_H_GPP_A13      0x0100000D
+#define GPIO_SKL_H_GPP_A14      0x0100000E
+#define GPIO_SKL_H_GPP_A15      0x0100000F
+#define GPIO_SKL_H_GPP_A16      0x01000010
+#define GPIO_SKL_H_GPP_A17      0x01000011
+#define GPIO_SKL_H_GPP_A18      0x01000012
+#define GPIO_SKL_H_GPP_A19      0x01000013
+#define GPIO_SKL_H_GPP_A20      0x01000014
+#define GPIO_SKL_H_GPP_A21      0x01000015
+#define GPIO_SKL_H_GPP_A22      0x01000016
+#define GPIO_SKL_H_GPP_A23      0x01000017
+#define GPIO_SKL_H_GPP_B0       0x01010000
+#define GPIO_SKL_H_GPP_B1       0x01010001
+#define GPIO_SKL_H_GPP_B2       0x01010002
+#define GPIO_SKL_H_GPP_B3       0x01010003
+#define GPIO_SKL_H_GPP_B4       0x01010004
+#define GPIO_SKL_H_GPP_B5       0x01010005
+#define GPIO_SKL_H_GPP_B6       0x01010006
+#define GPIO_SKL_H_GPP_B7       0x01010007
+#define GPIO_SKL_H_GPP_B8       0x01010008
+#define GPIO_SKL_H_GPP_B9       0x01010009
+#define GPIO_SKL_H_GPP_B10      0x0101000A
+#define GPIO_SKL_H_GPP_B11      0x0101000B
+#define GPIO_SKL_H_GPP_B12      0x0101000C
+#define GPIO_SKL_H_GPP_B13      0x0101000D
+#define GPIO_SKL_H_GPP_B14      0x0101000E
+#define GPIO_SKL_H_GPP_B15      0x0101000F
+#define GPIO_SKL_H_GPP_B16      0x01010010
+#define GPIO_SKL_H_GPP_B17      0x01010011
+#define GPIO_SKL_H_GPP_B18      0x01010012
+#define GPIO_SKL_H_GPP_B19      0x01010013
+#define GPIO_SKL_H_GPP_B20      0x01010014
+#define GPIO_SKL_H_GPP_B21      0x01010015
+#define GPIO_SKL_H_GPP_B22      0x01010016
+#define GPIO_SKL_H_GPP_B23      0x01010017
+#define GPIO_SKL_H_GPP_C0       0x01020000
+#define GPIO_SKL_H_GPP_C1       0x01020001
+#define GPIO_SKL_H_GPP_C2       0x01020002
+#define GPIO_SKL_H_GPP_C3       0x01020003
+#define GPIO_SKL_H_GPP_C4       0x01020004
+#define GPIO_SKL_H_GPP_C5       0x01020005
+#define GPIO_SKL_H_GPP_C6       0x01020006
+#define GPIO_SKL_H_GPP_C7       0x01020007
+#define GPIO_SKL_H_GPP_C8       0x01020008
+#define GPIO_SKL_H_GPP_C9       0x01020009
+#define GPIO_SKL_H_GPP_C10      0x0102000A
+#define GPIO_SKL_H_GPP_C11      0x0102000B
+#define GPIO_SKL_H_GPP_C12      0x0102000C
+#define GPIO_SKL_H_GPP_C13      0x0102000D
+#define GPIO_SKL_H_GPP_C14      0x0102000E
+#define GPIO_SKL_H_GPP_C15      0x0102000F
+#define GPIO_SKL_H_GPP_C16      0x01020010
+#define GPIO_SKL_H_GPP_C17      0x01020011
+#define GPIO_SKL_H_GPP_C18      0x01020012
+#define GPIO_SKL_H_GPP_C19      0x01020013
+#define GPIO_SKL_H_GPP_C20      0x01020014
+#define GPIO_SKL_H_GPP_C21      0x01020015
+#define GPIO_SKL_H_GPP_C22      0x01020016
+#define GPIO_SKL_H_GPP_C23      0x01020017
+#define GPIO_SKL_H_GPP_D0       0x01030000
+#define GPIO_SKL_H_GPP_D1       0x01030001
+#define GPIO_SKL_H_GPP_D2       0x01030002
+#define GPIO_SKL_H_GPP_D3       0x01030003
+#define GPIO_SKL_H_GPP_D4       0x01030004
+#define GPIO_SKL_H_GPP_D5       0x01030005
+#define GPIO_SKL_H_GPP_D6       0x01030006
+#define GPIO_SKL_H_GPP_D7       0x01030007
+#define GPIO_SKL_H_GPP_D8       0x01030008
+#define GPIO_SKL_H_GPP_D9       0x01030009
+#define GPIO_SKL_H_GPP_D10      0x0103000A
+#define GPIO_SKL_H_GPP_D11      0x0103000B
+#define GPIO_SKL_H_GPP_D12      0x0103000C
+#define GPIO_SKL_H_GPP_D13      0x0103000D
+#define GPIO_SKL_H_GPP_D14      0x0103000E
+#define GPIO_SKL_H_GPP_D15      0x0103000F
+#define GPIO_SKL_H_GPP_D16      0x01030010
+#define GPIO_SKL_H_GPP_D17      0x01030011
+#define GPIO_SKL_H_GPP_D18      0x01030012
+#define GPIO_SKL_H_GPP_D19      0x01030013
+#define GPIO_SKL_H_GPP_D20      0x01030014
+#define GPIO_SKL_H_GPP_D21      0x01030015
+#define GPIO_SKL_H_GPP_D22      0x01030016
+#define GPIO_SKL_H_GPP_D23      0x01030017
+#define GPIO_SKL_H_GPP_E0       0x01040000
+#define GPIO_SKL_H_GPP_E1       0x01040001
+#define GPIO_SKL_H_GPP_E2       0x01040002
+#define GPIO_SKL_H_GPP_E3       0x01040003
+#define GPIO_SKL_H_GPP_E4       0x01040004
+#define GPIO_SKL_H_GPP_E5       0x01040005
+#define GPIO_SKL_H_GPP_E6       0x01040006
+#define GPIO_SKL_H_GPP_E7       0x01040007
+#define GPIO_SKL_H_GPP_E8       0x01040008
+#define GPIO_SKL_H_GPP_E9       0x01040009
+#define GPIO_SKL_H_GPP_E10      0x0104000A
+#define GPIO_SKL_H_GPP_E11      0x0104000B
+#define GPIO_SKL_H_GPP_E12      0x0104000C
+#define GPIO_SKL_H_GPP_F0       0x01050000
+#define GPIO_SKL_H_GPP_F1       0x01050001
+#define GPIO_SKL_H_GPP_F2       0x01050002
+#define GPIO_SKL_H_GPP_F3       0x01050003
+#define GPIO_SKL_H_GPP_F4       0x01050004
+#define GPIO_SKL_H_GPP_F5       0x01050005
+#define GPIO_SKL_H_GPP_F6       0x01050006
+#define GPIO_SKL_H_GPP_F7       0x01050007
+#define GPIO_SKL_H_GPP_F8       0x01050008
+#define GPIO_SKL_H_GPP_F9       0x01050009
+#define GPIO_SKL_H_GPP_F10      0x0105000A
+#define GPIO_SKL_H_GPP_F11      0x0105000B
+#define GPIO_SKL_H_GPP_F12      0x0105000C
+#define GPIO_SKL_H_GPP_F13      0x0105000D
+#define GPIO_SKL_H_GPP_F14      0x0105000E
+#define GPIO_SKL_H_GPP_F15      0x0105000F
+#define GPIO_SKL_H_GPP_F16      0x01050010
+#define GPIO_SKL_H_GPP_F17      0x01050011
+#define GPIO_SKL_H_GPP_F18      0x01050012
+#define GPIO_SKL_H_GPP_F19      0x01050013
+#define GPIO_SKL_H_GPP_F20      0x01050014
+#define GPIO_SKL_H_GPP_F21      0x01050015
+#define GPIO_SKL_H_GPP_F22      0x01050016
+#define GPIO_SKL_H_GPP_F23      0x01050017
+#define GPIO_SKL_H_GPP_G0       0x01060000
+#define GPIO_SKL_H_GPP_G1       0x01060001
+#define GPIO_SKL_H_GPP_G2       0x01060002
+#define GPIO_SKL_H_GPP_G3       0x01060003
+#define GPIO_SKL_H_GPP_G4       0x01060004
+#define GPIO_SKL_H_GPP_G5       0x01060005
+#define GPIO_SKL_H_GPP_G6       0x01060006
+#define GPIO_SKL_H_GPP_G7       0x01060007
+#define GPIO_SKL_H_GPP_G8       0x01060008
+#define GPIO_SKL_H_GPP_G9       0x01060009
+#define GPIO_SKL_H_GPP_G10      0x0106000A
+#define GPIO_SKL_H_GPP_G11      0x0106000B
+#define GPIO_SKL_H_GPP_G12      0x0106000C
+#define GPIO_SKL_H_GPP_G13      0x0106000D
+#define GPIO_SKL_H_GPP_G14      0x0106000E
+#define GPIO_SKL_H_GPP_G15      0x0106000F
+#define GPIO_SKL_H_GPP_G16      0x01060010
+#define GPIO_SKL_H_GPP_G17      0x01060011
+#define GPIO_SKL_H_GPP_G18      0x01060012
+#define GPIO_SKL_H_GPP_G19      0x01060013
+#define GPIO_SKL_H_GPP_G20      0x01060014
+#define GPIO_SKL_H_GPP_G21      0x01060015
+#define GPIO_SKL_H_GPP_G22      0x01060016
+#define GPIO_SKL_H_GPP_G23      0x01060017
+#define GPIO_SKL_H_GPP_H0       0x01070000
+#define GPIO_SKL_H_GPP_H1       0x01070001
+#define GPIO_SKL_H_GPP_H2       0x01070002
+#define GPIO_SKL_H_GPP_H3       0x01070003
+#define GPIO_SKL_H_GPP_H4       0x01070004
+#define GPIO_SKL_H_GPP_H5       0x01070005
+#define GPIO_SKL_H_GPP_H6       0x01070006
+#define GPIO_SKL_H_GPP_H7       0x01070007
+#define GPIO_SKL_H_GPP_H8       0x01070008
+#define GPIO_SKL_H_GPP_H9       0x01070009
+#define GPIO_SKL_H_GPP_H10      0x0107000A
+#define GPIO_SKL_H_GPP_H11      0x0107000B
+#define GPIO_SKL_H_GPP_H12      0x0107000C
+#define GPIO_SKL_H_GPP_H13      0x0107000D
+#define GPIO_SKL_H_GPP_H14      0x0107000E
+#define GPIO_SKL_H_GPP_H15      0x0107000F
+#define GPIO_SKL_H_GPP_H16      0x01070010
+#define GPIO_SKL_H_GPP_H17      0x01070011
+#define GPIO_SKL_H_GPP_H18      0x01070012
+#define GPIO_SKL_H_GPP_H19      0x01070013
+#define GPIO_SKL_H_GPP_H20      0x01070014
+#define GPIO_SKL_H_GPP_H21      0x01070015
+#define GPIO_SKL_H_GPP_H22      0x01070016
+#define GPIO_SKL_H_GPP_H23      0x01070017
+#define GPIO_SKL_H_GPP_I0       0x01080000
+#define GPIO_SKL_H_GPP_I1       0x01080001
+#define GPIO_SKL_H_GPP_I2       0x01080002
+#define GPIO_SKL_H_GPP_I3       0x01080003
+#define GPIO_SKL_H_GPP_I4       0x01080004
+#define GPIO_SKL_H_GPP_I5       0x01080005
+#define GPIO_SKL_H_GPP_I6       0x01080006
+#define GPIO_SKL_H_GPP_I7       0x01080007
+#define GPIO_SKL_H_GPP_I8       0x01080008
+#define GPIO_SKL_H_GPP_I9       0x01080009
+#define GPIO_SKL_H_GPP_I10      0x0108000A
+#define GPIO_SKL_H_GPD0         0x01090000
+#define GPIO_SKL_H_GPD1         0x01090001
+#define GPIO_SKL_H_GPD2         0x01090002
+#define GPIO_SKL_H_GPD3         0x01090003
+#define GPIO_SKL_H_GPD4         0x01090004
+#define GPIO_SKL_H_GPD5         0x01090005
+#define GPIO_SKL_H_GPD6         0x01090006
+#define GPIO_SKL_H_GPD7         0x01090007
+#define GPIO_SKL_H_GPD8         0x01090008
+#define GPIO_SKL_H_GPD9         0x01090009
+#define GPIO_SKL_H_GPD10        0x0109000A
+#define GPIO_SKL_H_GPD11        0x0109000B
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
new file mode 100644
index 0000000000..8d430afd14
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
@@ -0,0 +1,200 @@
+/** @file
+  GPIO pins
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PINS_SKL_LP_H_
+#define _GPIO_PINS_SKL_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
+///
+
+///
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_SKL_LP_GROUP_GPP_A  0x0200
+#define GPIO_SKL_LP_GROUP_GPP_B  0x0201
+#define GPIO_SKL_LP_GROUP_GPP_C  0x0202
+#define GPIO_SKL_LP_GROUP_GPP_D  0x0203
+#define GPIO_SKL_LP_GROUP_GPP_E  0x0204
+#define GPIO_SKL_LP_GROUP_GPP_F  0x0205
+#define GPIO_SKL_LP_GROUP_GPP_G  0x0206
+#define GPIO_SKL_LP_GROUP_GPD    0x0207
+
+///
+/// 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_SKL_LP_GPP_A0      0x02000000
+#define GPIO_SKL_LP_GPP_A1      0x02000001
+#define GPIO_SKL_LP_GPP_A2      0x02000002
+#define GPIO_SKL_LP_GPP_A3      0x02000003
+#define GPIO_SKL_LP_GPP_A4      0x02000004
+#define GPIO_SKL_LP_GPP_A5      0x02000005
+#define GPIO_SKL_LP_GPP_A6      0x02000006
+#define GPIO_SKL_LP_GPP_A7      0x02000007
+#define GPIO_SKL_LP_GPP_A8      0x02000008
+#define GPIO_SKL_LP_GPP_A9      0x02000009
+#define GPIO_SKL_LP_GPP_A10     0x0200000A
+#define GPIO_SKL_LP_GPP_A11     0x0200000B
+#define GPIO_SKL_LP_GPP_A12     0x0200000C
+#define GPIO_SKL_LP_GPP_A13     0x0200000D
+#define GPIO_SKL_LP_GPP_A14     0x0200000E
+#define GPIO_SKL_LP_GPP_A15     0x0200000F
+#define GPIO_SKL_LP_GPP_A16     0x02000010
+#define GPIO_SKL_LP_GPP_A17     0x02000011
+#define GPIO_SKL_LP_GPP_A18     0x02000012
+#define GPIO_SKL_LP_GPP_A19     0x02000013
+#define GPIO_SKL_LP_GPP_A20     0x02000014
+#define GPIO_SKL_LP_GPP_A21     0x02000015
+#define GPIO_SKL_LP_GPP_A22     0x02000016
+#define GPIO_SKL_LP_GPP_A23     0x02000017
+#define GPIO_SKL_LP_GPP_B0      0x02010000
+#define GPIO_SKL_LP_GPP_B1      0x02010001
+#define GPIO_SKL_LP_GPP_B2      0x02010002
+#define GPIO_SKL_LP_GPP_B3      0x02010003
+#define GPIO_SKL_LP_GPP_B4      0x02010004
+#define GPIO_SKL_LP_GPP_B5      0x02010005
+#define GPIO_SKL_LP_GPP_B6      0x02010006
+#define GPIO_SKL_LP_GPP_B7      0x02010007
+#define GPIO_SKL_LP_GPP_B8      0x02010008
+#define GPIO_SKL_LP_GPP_B9      0x02010009
+#define GPIO_SKL_LP_GPP_B10     0x0201000A
+#define GPIO_SKL_LP_GPP_B11     0x0201000B
+#define GPIO_SKL_LP_GPP_B12     0x0201000C
+#define GPIO_SKL_LP_GPP_B13     0x0201000D
+#define GPIO_SKL_LP_GPP_B14     0x0201000E
+#define GPIO_SKL_LP_GPP_B15     0x0201000F
+#define GPIO_SKL_LP_GPP_B16     0x02010010
+#define GPIO_SKL_LP_GPP_B17     0x02010011
+#define GPIO_SKL_LP_GPP_B18     0x02010012
+#define GPIO_SKL_LP_GPP_B19     0x02010013
+#define GPIO_SKL_LP_GPP_B20     0x02010014
+#define GPIO_SKL_LP_GPP_B21     0x02010015
+#define GPIO_SKL_LP_GPP_B22     0x02010016
+#define GPIO_SKL_LP_GPP_B23     0x02010017
+#define GPIO_SKL_LP_GPP_C0      0x02020000
+#define GPIO_SKL_LP_GPP_C1      0x02020001
+#define GPIO_SKL_LP_GPP_C2      0x02020002
+#define GPIO_SKL_LP_GPP_C3      0x02020003
+#define GPIO_SKL_LP_GPP_C4      0x02020004
+#define GPIO_SKL_LP_GPP_C5      0x02020005
+#define GPIO_SKL_LP_GPP_C6      0x02020006
+#define GPIO_SKL_LP_GPP_C7      0x02020007
+#define GPIO_SKL_LP_GPP_C8      0x02020008
+#define GPIO_SKL_LP_GPP_C9      0x02020009
+#define GPIO_SKL_LP_GPP_C10     0x0202000A
+#define GPIO_SKL_LP_GPP_C11     0x0202000B
+#define GPIO_SKL_LP_GPP_C12     0x0202000C
+#define GPIO_SKL_LP_GPP_C13     0x0202000D
+#define GPIO_SKL_LP_GPP_C14     0x0202000E
+#define GPIO_SKL_LP_GPP_C15     0x0202000F
+#define GPIO_SKL_LP_GPP_C16     0x02020010
+#define GPIO_SKL_LP_GPP_C17     0x02020011
+#define GPIO_SKL_LP_GPP_C18     0x02020012
+#define GPIO_SKL_LP_GPP_C19     0x02020013
+#define GPIO_SKL_LP_GPP_C20     0x02020014
+#define GPIO_SKL_LP_GPP_C21     0x02020015
+#define GPIO_SKL_LP_GPP_C22     0x02020016
+#define GPIO_SKL_LP_GPP_C23     0x02020017
+#define GPIO_SKL_LP_GPP_D0      0x02030000
+#define GPIO_SKL_LP_GPP_D1      0x02030001
+#define GPIO_SKL_LP_GPP_D2      0x02030002
+#define GPIO_SKL_LP_GPP_D3      0x02030003
+#define GPIO_SKL_LP_GPP_D4      0x02030004
+#define GPIO_SKL_LP_GPP_D5      0x02030005
+#define GPIO_SKL_LP_GPP_D6      0x02030006
+#define GPIO_SKL_LP_GPP_D7      0x02030007
+#define GPIO_SKL_LP_GPP_D8      0x02030008
+#define GPIO_SKL_LP_GPP_D9      0x02030009
+#define GPIO_SKL_LP_GPP_D10     0x0203000A
+#define GPIO_SKL_LP_GPP_D11     0x0203000B
+#define GPIO_SKL_LP_GPP_D12     0x0203000C
+#define GPIO_SKL_LP_GPP_D13     0x0203000D
+#define GPIO_SKL_LP_GPP_D14     0x0203000E
+#define GPIO_SKL_LP_GPP_D15     0x0203000F
+#define GPIO_SKL_LP_GPP_D16     0x02030010
+#define GPIO_SKL_LP_GPP_D17     0x02030011
+#define GPIO_SKL_LP_GPP_D18     0x02030012
+#define GPIO_SKL_LP_GPP_D19     0x02030013
+#define GPIO_SKL_LP_GPP_D20     0x02030014
+#define GPIO_SKL_LP_GPP_D21     0x02030015
+#define GPIO_SKL_LP_GPP_D22     0x02030016
+#define GPIO_SKL_LP_GPP_D23     0x02030017
+#define GPIO_SKL_LP_GPP_E0      0x02040000
+#define GPIO_SKL_LP_GPP_E1      0x02040001
+#define GPIO_SKL_LP_GPP_E2      0x02040002
+#define GPIO_SKL_LP_GPP_E3      0x02040003
+#define GPIO_SKL_LP_GPP_E4      0x02040004
+#define GPIO_SKL_LP_GPP_E5      0x02040005
+#define GPIO_SKL_LP_GPP_E6      0x02040006
+#define GPIO_SKL_LP_GPP_E7      0x02040007
+#define GPIO_SKL_LP_GPP_E8      0x02040008
+#define GPIO_SKL_LP_GPP_E9      0x02040009
+#define GPIO_SKL_LP_GPP_E10     0x0204000A
+#define GPIO_SKL_LP_GPP_E11     0x0204000B
+#define GPIO_SKL_LP_GPP_E12     0x0204000C
+#define GPIO_SKL_LP_GPP_E13     0x0204000D
+#define GPIO_SKL_LP_GPP_E14     0x0204000E
+#define GPIO_SKL_LP_GPP_E15     0x0204000F
+#define GPIO_SKL_LP_GPP_E16     0x02040010
+#define GPIO_SKL_LP_GPP_E17     0x02040011
+#define GPIO_SKL_LP_GPP_E18     0x02040012
+#define GPIO_SKL_LP_GPP_E19     0x02040013
+#define GPIO_SKL_LP_GPP_E20     0x02040014
+#define GPIO_SKL_LP_GPP_E21     0x02040015
+#define GPIO_SKL_LP_GPP_E22     0x02040016
+#define GPIO_SKL_LP_GPP_E23     0x02040017
+#define GPIO_SKL_LP_GPP_F0      0x02050000
+#define GPIO_SKL_LP_GPP_F1      0x02050001
+#define GPIO_SKL_LP_GPP_F2      0x02050002
+#define GPIO_SKL_LP_GPP_F3      0x02050003
+#define GPIO_SKL_LP_GPP_F4      0x02050004
+#define GPIO_SKL_LP_GPP_F5      0x02050005
+#define GPIO_SKL_LP_GPP_F6      0x02050006
+#define GPIO_SKL_LP_GPP_F7      0x02050007
+#define GPIO_SKL_LP_GPP_F8      0x02050008
+#define GPIO_SKL_LP_GPP_F9      0x02050009
+#define GPIO_SKL_LP_GPP_F10     0x0205000A
+#define GPIO_SKL_LP_GPP_F11     0x0205000B
+#define GPIO_SKL_LP_GPP_F12     0x0205000C
+#define GPIO_SKL_LP_GPP_F13     0x0205000D
+#define GPIO_SKL_LP_GPP_F14     0x0205000E
+#define GPIO_SKL_LP_GPP_F15     0x0205000F
+#define GPIO_SKL_LP_GPP_F16     0x02050010
+#define GPIO_SKL_LP_GPP_F17     0x02050011
+#define GPIO_SKL_LP_GPP_F18     0x02050012
+#define GPIO_SKL_LP_GPP_F19     0x02050013
+#define GPIO_SKL_LP_GPP_F20     0x02050014
+#define GPIO_SKL_LP_GPP_F21     0x02050015
+#define GPIO_SKL_LP_GPP_F22     0x02050016
+#define GPIO_SKL_LP_GPP_F23     0x02050017
+#define GPIO_SKL_LP_GPP_G0      0x02060000
+#define GPIO_SKL_LP_GPP_G1      0x02060001
+#define GPIO_SKL_LP_GPP_G2      0x02060002
+#define GPIO_SKL_LP_GPP_G3      0x02060003
+#define GPIO_SKL_LP_GPP_G4      0x02060004
+#define GPIO_SKL_LP_GPP_G5      0x02060005
+#define GPIO_SKL_LP_GPP_G6      0x02060006
+#define GPIO_SKL_LP_GPP_G7      0x02060007
+#define GPIO_SKL_LP_GPD0        0x02070000
+#define GPIO_SKL_LP_GPD1        0x02070001
+#define GPIO_SKL_LP_GPD2        0x02070002
+#define GPIO_SKL_LP_GPD3        0x02070003
+#define GPIO_SKL_LP_GPD4        0x02070004
+#define GPIO_SKL_LP_GPD5        0x02070005
+#define GPIO_SKL_LP_GPD6        0x02070006
+#define GPIO_SKL_LP_GPD7        0x02070007
+#define GPIO_SKL_LP_GPD8        0x02070008
+#define GPIO_SKL_LP_GPD9        0x02070009
+#define GPIO_SKL_LP_GPD10       0x0207000A
+#define GPIO_SKL_LP_GPD11       0x0207000B
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
new file mode 100644
index 0000000000..6730b3baf9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
@@ -0,0 +1,54 @@
+/** @file
+  Macros that simplify accessing PCH devices's PCI registers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_ACCESS_H_
+#define _PCH_ACCESS_H_
+
+#include "PchLimits.h"
+#include "PchReservedResources.h"
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_SECOND
+#define STALL_ONE_SECOND 1000000
+#endif
+
+//
+// Include device register definitions
+//
+#include "PcieRegs.h"
+#include "Register/PchRegs.h"
+#include "Register/PchRegsPcr.h"
+#include "Register/PchRegsP2sb.h"
+#include "Register/PchRegsHda.h"
+#include "Register/PchRegsHsio.h"
+#include "Register/PchRegsLan.h"
+#include "Register/PchRegsLpc.h"
+#include "Register/PchRegsPmc.h"
+#include "Register/PchRegsPcie.h"
+#include "Register/PchRegsSata.h"
+#include "Register/PchRegsSmbus.h"
+#include "Register/PchRegsSpi.h"
+#include <Register/RegsUsb.h>
+#include "Register/PchRegsGpio.h"
+#include "Register/PchRegsThermalCnl.h"
+#include "Register/PchRegsGpioCnl.h"
+#include "Register/PchRegsSerialIoCnl.h"
+#include "Register/PchRegsSerialIo.h"
+#include "Register/PchRegsTraceHub.h"
+#include "Register/PchRegsScsCnl.h"
+#include "Register/PchRegsIsh.h"
+#include "Register/PchRegsDmi.h"
+#include "Register/PchRegsItss.h"
+#include "Register/PchRegsPsth.h"
+#include "Register/PchRegsFia.h"
+#include "Register/PchRegsDci.h"
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
new file mode 100644
index 0000000000..3b8e5147db
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for HD Audio configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_H_
+#define _PCH_HDA_H_
+
+
+enum PCH_HDAUDIO_DMIC_TYPE {
+  PchHdaDmicDisabled = 0,
+  PchHdaDmic2chArray = 1,
+  PchHdaDmic4chArray = 2,
+  PchHdaDmic1chArray = 3
+};
+
+typedef enum {
+  PchHdaLinkFreq6MHz  = 0,
+  PchHdaLinkFreq12MHz = 1,
+  PchHdaLinkFreq24MHz = 2,
+  PchHdaLinkFreq48MHz = 3,
+  PchHdaLinkFreq96MHz = 4,
+  PchHdaLinkFreqInvalid
+} PCH_HDAUDIO_LINK_FREQUENCY;
+
+typedef enum  {
+  PchHdaIDispMode2T  = 0,
+  PchHdaIDispMode1T  = 1,
+  PchHdaIDispMode4T  = 2,
+  PchHdaIDispMode8T  = 3,
+  PchHdaIDispMode16T = 4,
+  PchHdaIDispTModeInvalid
+} PCH_HDAUDIO_IDISP_TMODE;
+
+#endif // _PCH_HDA_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
new file mode 100644
index 0000000000..743dd84b2b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
@@ -0,0 +1,80 @@
+/** @file
+  This file contains definitions of PCH Info HOB.
+
+  Copyright (c) 2019 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  2
+
+#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>:
+  - Added LaneReversal Field
+**/
+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];
+
+  /**
+    GbE over PCIe port number when GbE is enabled
+    >0 - Root port number (1-based)
+    0  - GbE over PCIe disabled
+    This information needs to be passed through HOB as FIA registers
+    are not accessible with POSTBOOT_SAI
+  **/
+  UINT8        GbePciePortNumber;
+  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;
+  /**
+    This member specifies if lane reversal is enabled on the specific
+    Pcie Root port controller.
+  **/
+  UINT8        PcieControllerLaneReversal[6];
+} PCH_INFO_HOB;
+
+#pragma pack (pop)
+
+#endif // _PCH_INFO_HOB_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
new file mode 100644
index 0000000000..929f9f02d4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
@@ -0,0 +1,53 @@
+/** @file
+  Build time limits of PCH resources.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_LIMITS_H_
+#define _PCH_LIMITS_H_
+
+//
+// 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
+
+//
+// USB limits
+//
+#define PCH_MAX_USB2_PORTS                  16
+#define PCH_MAX_USB3_PORTS                  10
+
+//
+// SerialIo limits
+//
+#define PCH_MAX_SERIALIO_CONTROLLERS         12
+#define PCH_MAX_SERIALIO_I2C_CONTROLLERS      6
+#define PCH_MAX_SERIALIO_SPI_CONTROLLERS      3
+#define PCH_MAX_SERIALIO_UART_CONTROLLERS     3
+
+//
+// Number of eSPI slaves
+//
+#define PCH_MAX_ESPI_SLAVES                  2
+
+#endif // _PCH_LIMITS_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
new file mode 100644
index 0000000000..1097e58332
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
@@ -0,0 +1,47 @@
+/** @file
+  Definitions required to create PcieStorageInfoHob
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIE_STORAGE_DETECT_HOB_
+#define _PCH_PCIE_STORAGE_DETECT_HOB_
+
+#include "PchLimits.h"
+
+#define PCIE_STORAGE_INFO_HOB_REVISION              1
+
+extern EFI_GUID gPchPcieStorageDetectHobGuid;
+
+typedef enum {
+  RstLinkWidthX1 = 1,
+  RstLinkWidthX2 = 2,
+  RstLinkWidthX4 = 4
+} RST_LINK_WIDTH;
+
+//
+//  Stores information about connected PCIe storage devices used later by BIOS setup and RST remapping
+//
+#pragma pack(1)
+typedef struct {
+  UINT8  Revision;
+
+  //
+  // Stores the number of root ports occupied by a connected storage device, values from RST_LINK_WIDTH are supported
+  //
+  UINT8  PcieStorageLinkWidth[PCH_MAX_PCIE_ROOT_PORTS];
+
+  //
+  // Programming interface value for a given device, 0x02 - NVMe or RAID, 0x1 - AHCI storage, 0x0 - no device connected
+  //
+  UINT8  PcieStorageProgrammingInterface[PCH_MAX_PCIE_ROOT_PORTS];
+
+  //
+  // Stores information about cycle router number under a given PCIe controller
+  //
+  UINT8  RstCycleRouterMap[PCH_MAX_PCIE_CONTROLLERS];
+} PCIE_STORAGE_INFO_HOB;
+#pragma pack()
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
new file mode 100644
index 0000000000..213ca91d2d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
@@ -0,0 +1,47 @@
+/** @file
+  PCH configuration based on PCH policy
+
+  Copyright (c) 2019 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 <ConfigBlock/UsbConfig.h>
+
+#include "PchLimits.h"
+#include "ConfigBlock/PchGeneralConfig.h"
+#include "ConfigBlock/PcieRpConfig.h"
+#include "ConfigBlock/SataConfig.h"
+#include "ConfigBlock/IoApicConfig.h"
+#include "ConfigBlock/DmiConfig.h"
+#include "ConfigBlock/FlashProtectionConfig.h"
+#include "ConfigBlock/HdAudioConfig.h"
+#include "ConfigBlock/InterruptConfig.h"
+#include "ConfigBlock/IshConfig.h"
+#include "ConfigBlock/LanConfig.h"
+#include "ConfigBlock/LockDownConfig.h"
+#include "ConfigBlock/P2sbConfig.h"
+#include "ConfigBlock/PmConfig.h"
+#include "ConfigBlock/ScsConfig.h"
+#include "ConfigBlock/SerialIoConfig.h"
+#include "ConfigBlock/SerialIrqConfig.h"
+#include "ConfigBlock/ThermalConfig.h"
+#include "ConfigBlock/EspiConfig.h"
+#include "ConfigBlock/CnviConfig.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/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
new file mode 100644
index 0000000000..37b2301770
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
@@ -0,0 +1,59 @@
+/** @file
+  PCH configuration based on PCH policy
+
+  Copyright (c) 2019 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 "ConfigBlock/DciConfig.h"
+#include "ConfigBlock/WatchDogConfig.h"
+#include "ConfigBlock/PchTraceHubConfig.h"
+#include "ConfigBlock/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/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
new file mode 100644
index 0000000000..f5106ffebb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
@@ -0,0 +1,53 @@
+/** @file
+  PCH preserved MMIO resource definitions.
+
+  Copyright (c) 2019 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                      |
+  | 88 KB       | 0xFE020000  | 0xFE035FFF  | SerialIo BAR in ACPI mode     |
+  | 488 KB      | 0xFE036000  | 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     ///< 28MB
+#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         0x00016000     ///< 88KB
+#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_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
new file mode 100644
index 0000000000..8e1495d16f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
@@ -0,0 +1,23 @@
+/** @file
+  PCH Reset Platform Specific definitions.
+
+  Copyright (c) 2019 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_
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  7:04   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add Include headers

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

Adds header files common to ME modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h | 124 ++++++++++++++  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h  |  59 +++++++  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h  |  87 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h               | 172 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h             |  17 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h                |  19 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h       |  41 +++++
 7 files changed, 519 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
new file mode 100644
index 0000000000..102fb43bd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiCon
+++ fig.h
@@ -0,0 +1,124 @@
+/** @file
+  ME config block for PEI phase
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_PEI_CONFIG_H_
+#define _ME_PEI_CONFIG_H_
+
+#include <ConfigBlock.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>:
+  - Change DidInitStat bit width.
+**/
+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>(Test)</b> 0: Disable; <b>1: Enable</b> - Enable/Disable to send DID message.
+  /**
+    <b>(Test)</b>
+    <b>0: Set to 0 to enable retry mechanism for HECI APIs</b>
+       1: Set to 1 will disable retry mechanism for HECI APIs
+  **/
+  UINT32 DisableHeciRetry                 : 1;
+  /**
+    <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 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 2
+extern EFI_GUID gMePeiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME Pei Post-Memory Configuration Structure.
+
+  <b>Revision 1:</b>
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add MctpBroadcastCycle test setting.
+**/
+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.
+  /**
+    HECI3 state from Mbp for reference in S3 path only
+    <b>0: Disabled</b>; 1: Enabled
+  **/
+  UINT32 Heci3Enabled                     : 1;
+  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 RsvdBits                         : 25;  ///< Reserved for future use & Config block alignment
+} ME_PEI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ME_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
new file mode 100644
index 0000000000..46f7f86021
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyL
+++ ib.h
@@ -0,0 +1,59 @@
+/** @file
+  Prototype of the DxeMePolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _DXE_ME_POLICY_LIB_H_
+#define _DXE_ME_POLICY_LIB_H_
+
+#include <Protocol/MePolicy.h>
+
+/**
+  This function prints the ME DXE phase policy.
+
+  @param[in] DxeMePolicy - ME DXE Policy protocol **/ VOID 
+MePrintPolicyProtocol (
+  IN  ME_POLICY_PROTOCOL             *DxeMePolicy
+  );
+
+/**
+  MeCreatePolicyDefaults creates the default setting of ME Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+MeCreatePolicyDefaults (
+  IN OUT  ME_POLICY_PROTOCOL            **DxeMePolicy
+  );
+
+/**
+  MeInstallPolicyProtocol installs ME 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] DxeMePolicy                The pointer to ME Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+MeInstallPolicyProtocol (
+  IN  EFI_HANDLE                    ImageHandle,
+  IN  ME_POLICY_PROTOCOL            *DxeMePolicy
+  );
+
+#endif // _DXE_ME_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
new file mode 100644
index 0000000000..5db4714346
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyL
+++ ib.h
@@ -0,0 +1,87 @@
+/** @file
+  Prototype of the MePolicyLibPei library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PEI_ME_POLICY_LIB_H_
+#define _PEI_ME_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  );
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi              The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  );
+
+/**
+  Get Me config block table total size.
+
+  @retval     Size of Me config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get ME config block table total size.
+
+  @retval      Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSizePreMem (
+  VOID
+  );
+
+/**
+  MeAddConfigBlocksPreMem add all ME config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add ME config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  MeAddConfigBlocks add all ME config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add ME config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_ME_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
new file mode 100644
index 0000000000..f29f9bc8bd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
@@ -0,0 +1,172 @@
+/** @file
+  Chipset definition for ME Devices.
+
+  Conventions:
+
+  - 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
+  - Registers / bits that are different between PCH generations are denoted by
+    "_ME_[generation_name]_" in register/bit names.
+  - Registers / bits that are specific to PCH-H denoted by "PCH_H_" in register/bit names.
+    Registers / bits that are specific to PCH-LP denoted by "PCH_LP_" in register/bit names.
+    e.g., "_ME_PCH_H_", "_ME_PCH_LP_"
+    Registers / bits names without _PCH_H_ or _PCH_LP_ apply for both H and 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 "_ME_" without [generation_name] inserted.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_CHIPSET_H_
+#define _ME_CHIPSET_H_
+
+#define ME_SEGMENT            0
+#define ME_BUS                0
+#define ME_DEVICE_NUMBER      22
+#define HECI_MIN_FUNC         0
+#define HECI_MAX_FUNC         5
+
+#define HECI_FUNCTION_NUMBER  0x00
+#define HECI2_FUNCTION_NUMBER 0x01
+#define IDER_FUNCTION_NUMBER  0x02
+#define SOL_FUNCTION_NUMBER   0x03
+#define HECI3_FUNCTION_NUMBER 0x04
+#define HECI4_FUNCTION_NUMBER 0x05
+
+#define IDER_BUS_NUMBER       ME_BUS
+#define IDER_DEVICE_NUMBER    ME_DEVICE_NUMBER
+#define SOL_BUS_NUMBER        ME_BUS
+#define SOL_DEVICE_NUMBER     ME_DEVICE_NUMBER
+
+ ///
+/// Convert to HECI# defined in BWG from Fun# /// #define 
+HECI_NAME_MAP(a) ((a < 2) ? (a + 1) : (a - 1))
+
+///
+/// ME-related Chipset Definition
+///
+#define HeciEnable()    MeDeviceControl (HECI1, Enabled);
+#define Heci2Enable()   MeDeviceControl (HECI2, Enabled);
+#define Heci3Enable()   MeDeviceControl (HECI3, Enabled);
+#define Heci4Enable()   MeDeviceControl (HECI4, Enabled);
+#define IderEnable()    MeDeviceControl (IDER, Enabled);
+#define SolEnable()     MeDeviceControl (SOL, Enabled);
+
+#define HeciDisable()   MeDeviceControl (HECI1, Disabled);
+#define Heci2Disable()  MeDeviceControl (HECI2, Disabled); #define 
+Heci3Disable()  MeDeviceControl (HECI3, Disabled);
+#define IderDisable()   MeDeviceControl (IDER, Disabled);
+#define SolDisable()    MeDeviceControl (SOL, Disabled);
+
+#define DisableAllMeDevices() \
+  HeciDisable (); \
+  Heci2Disable (); \
+  Heci3Disable (); \
+  IderDisable (); \
+  SolDisable ();
+
+///
+/// HECI Device Id Definitions
+///
+ #define IS_PCH_H_HECI_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_H_HECI_DEVICE_ID) \
+     )
+
+ #define IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_LP_HECI_DEVICE_ID) \
+     )
+
+ #define IS_HECI_DEVICE_ID(DeviceId) \
+     ( \
+       IS_PCH_H_HECI_DEVICE_ID(DeviceId) || \
+       IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
+     )
+
+///
+/// HECI2 Device Id Definitions
+///
+#define IS_PCH_H_HECI2_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_H_HECI2_DEVICE_ID) \
+     )
+
+#define IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_LP_HECI2_DEVICE_ID) \
+     )
+
+#define IS_HECI2_DEVICE_ID(DeviceId) \
+     ( \
+       IS_PCH_H_HECI2_DEVICE_ID(DeviceId) || \
+       IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
+     )
+
+///
+/// HECI3 Device Id Definitions
+///
+#define IS_PCH_H_HECI3_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_HECI3_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_HECI3_DEVICE_ID) \
+    )
+
+#define IS_HECI3_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_HECI3_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
+    )
+
+///
+/// HECI4 Device Id Definitions
+///
+#define IS_PCH_H_HECI4_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_HECI4_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_HECI4_DEVICE_ID) \
+    )
+
+#define IS_HECI4_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_HECI4_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
+    )
+
+///
+/// SoL Device Id Definitions
+///
+#define IS_PCH_H_SOL_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_SOL_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_SOL_DEVICE_ID) \
+    )
+
+#define IS_PCH_SOL_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SOL_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
new file mode 100644
index 0000000000..a24973ce32
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
@@ -0,0 +1,17 @@
+/** @file
+  This file contains definitions of ME Policy HOB.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_POLICY_HOB_H_
+#define _ME_POLICY_HOB_H_
+
+#include <MePolicyCommon.h>
+
+extern EFI_GUID gMePolicyHobGuid;
+extern EFI_GUID gMePreMemPolicyHobGuid;
+
+#endif // _ME_POLICY_HOB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
new file mode 100644
index 0000000000..2d8ef1cf7a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
@@ -0,0 +1,19 @@
+/** @file
+  MKHI Messages
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _MKHI_MSGS_H
+#define _MKHI_MSGS_H
+
+///
+/// End of Post
+///
+#define EOP_DISABLED    0
+#define EOP_SEND_IN_PEI 1
+#define EOP_SEND_IN_DXE 2
+
+#endif // _MKHI_MSGS_H
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
new file mode 100644
index 0000000000..518041cb58
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
@@ -0,0 +1,41 @@
+/** @file
+  Interface definition details between ME and platform drivers during DXE phase.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_POLICY_H_
+#define _ME_POLICY_H_
+
+#include <ConfigBlock.h>
+
+/**
+  ME Policy Protocol.
+  All ME Policy Protocol change history listed here.
+
+**/
+#define ME_POLICY_PROTOCOL_REVISION  1
+
+extern EFI_GUID gDxeMePolicyGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME policy provided by platform for DXE phase
+  This protocol provides an interface to get Intel ME Configuration 
+information
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _ME_POLICY_PROTOCOL {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;
+/*
+  Individual Config Block Structures are added here in memory as part 
+of AddConfigBlock() */ } ME_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif // _ME_POLICY_H_
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers

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

Adds header files to Pch/Include/ConfigBlock.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h            |  69 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h             |  56 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h             |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h            |  40 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h |  54 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h         |  39 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h         | 178 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h            |  57 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h        |  58 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h        |  66 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h       |  58 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h          |  68 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h             |  57 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h             |  35 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h        |  70 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h             |  34 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h            |  49 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h      |  71 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h     |  36 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h          | 429 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h              | 311 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h            | 230 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h             |  63 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h        |  96 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h       |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h           |  52 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h         | 139 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h        |  33 ++
 28 files changed, 2534 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
new file mode 100644
index 0000000000..35fa125ba3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
@@ -0,0 +1,69 @@
+/** @file
+  CNVI policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gCnviConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CNVi Mode options
+**/
+typedef enum {
+  CnviModeDisabled = 0,
+  CnviModeAuto
+} CNVI_MODE;
+
+/**
+  CNVi MfUart1 connection options
+**/
+typedef enum {
+  CnviMfUart1Ish = 0,
+  CnviMfUart1SerialIo,
+  CnviBtUart1ExtPads,
+  CnviBtUart1NotConnected
+} CNVI_MFUART1_TYPE;
+
+
+/**
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Remove BtInterface and BtUartType.
+
+**/
+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;
+  /**
+    <b>(Test)</b> This option configures Uart type which connects to MfUart1
+    For production configuration ISH is the default, for tests SerialIO Uart0 or external pads can be used
+    Use CNVI_MFUART1_TYPE enum for selection
+    <b>CnviMfUart1Ish = MfUart1 over ISH Uart0</b>,
+    CnviMfUart1SerialIo = MfUart1 over SerialIO Uart2,
+    CnviBtUart1ExtPads = MfUart1 over exteranl pads,
+    CnviBtUart1NotConnected = MfUart1 not connected
+  **/
+  UINT32 MfUart1Type           :  2;
+  UINT32 RsvdBits              : 29;
+} PCH_CNVI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CNVI_CONFIG_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
new file mode 100644
index 0000000000..791546bdfe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
@@ -0,0 +1,56 @@
+/** @file
+  Dci policy
+
+  Copyright (c) 2019 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 1
+extern EFI_GUID gDciPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  ProbeTypeDisabled   = 0x0,
+  ProbeTypeDciOobDbc  = 0x1,
+  ProbeTypeDciOob     = 0x2,
+  ProbeTypeUsb3Dbc    = 0x3,
+  ProbeTypeXdp3       = 0x4,
+  ProbeTypeUsb2Dbc    = 0x5,
+  ProbeTypeMax
+} PLATFORM_DEBUG_CONSENT_PROBE_TYPE;
+
+/**
+  The PCH_DCI_PREMEM_CONFIG block describes policies related to Direct Connection Interface (DCI)
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    Platform Debug Consent
+    As a master switch to enable platform debug capability and relevant settings with specified probe type.
+    Note: DCI OOB (aka BSSB) uses CCA probe; [DCI OOB+DbC] and [USB2 DbC] have the same setting.
+    Refer to definition of PLATFORM_DEBUG_CONSENT_PROBE_TYPE
+    <b>0:Disabled</b>; 1:DCI OOB+DbC; 2:DCI OOB; 3:USB3 DbC; 4:XDP3/MIPI60 5:USB2 DbC;
+  **/
+  UINT32    PlatformDebugConsent  :  3;
+  /**
+    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>
+  **/
+  UINT32    DciUsb3TypecUfpDbg    :  2;
+  UINT32    RsvdBits              : 27;       ///< Reserved bits
+} PCH_DCI_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _DCI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
new file mode 100644
index 0000000000..03f83d9bf8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
@@ -0,0 +1,43 @@
+/** @file
+  DMI policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DMI_CONFIG_H_
+#define _DMI_CONFIG_H_
+
+#define DMI_CONFIG_REVISION 3
+extern EFI_GUID gDmiConfigGuid;
+
+
+#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>:
+  - Deprecate DmiAspm and add DmiAspmCtrl
+  <b>Revision 3</b>
+  - Added policy to enable/disable Central Write Buffer feature
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    @deprecated since revision 2
+  **/
+
+  UINT32     DmiAspm           :  1;
+  UINT32     PwrOptEnable      :  1;    ///< <b>0: Disable</b>; 1: Enable DMI Power Optimizer on PCH side.
+  UINT32     DmiAspmCtrl       :  8;    ///< ASPM configuration (PCH_PCIE_ASPM_CONTROL) on the PCH side of the DMI/OPI Link. Default is <b>PchPcieAspmAutoConfig</b>
+  UINT32     CwbEnable         :  1;    ///< <b>0: Disable</b>; Central Write Buffer feature configurable and disabled by default
+  UINT32     Rsvdbits          : 21;    ///< Reserved bits
+} PCH_DMI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _DMI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
new file mode 100644
index 0000000000..5de9b73397
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
@@ -0,0 +1,40 @@
+/** @file
+  Espi policy
+
+  Copyright (c) 2019 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 1
+extern EFI_GUID gEspiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to ESPI.
+**/
+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;
+  UINT32    RsvdBits              : 30;     ///< Reserved bits
+} PCH_ESPI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ESPI_CONFIG_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
new file mode 100644
index 0000000000..2a6c19de7e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
@@ -0,0 +1,54 @@
+/** @file
+  FlashProtection policy
+
+  Copyright (c) 2019 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
+
+/**
+  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 {
+  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;
+
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  PROTECTED_RANGE       ProtectRange[PCH_FLASH_PROTECTED_RANGES];
+} PCH_FLASH_PROTECTION_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _FLASH_PROTECTION_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
new file mode 100644
index 0000000000..2b32a21f54
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
@@ -0,0 +1,39 @@
+/** @file
+  GPIO device policy
+
+  Copyright (c) 2019 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
+
+} PCH_GPIO_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_GPIO_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
new file mode 100644
index 0000000000..a810d4f1fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
@@ -0,0 +1,178 @@
+/** @file
+  HDAUDIO policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _HDAUDIO_CONFIG_H_
+#define _HDAUDIO_CONFIG_H_
+
+#include <PchHda.h>
+
+#define HDAUDIO_PREMEM_CONFIG_REVISION 1
+#define HDAUDIO_CONFIG_REVISION 2
+#define HDAUDIO_DXE_CONFIG_REVISION 2
+
+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 (PCH_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.
+} PCH_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  {
+  PCH_HDA_VERB_TABLE_HEADER  Header;
+  UINT32 Data[];
+} HDAUDIO_VERB_TABLE;
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+/**
+  This structure contains the policies which are related to HD Audio device (cAVS).
+
+  <b>Revision 1:</b>
+  - Inital version.
+  <b>Revision 2:</b>
+  - Move DspEndpointDmic, DspEndpointBluetooth, DspEndpointI2s and DspFeatureMask to PCH_HDAUDIO_DXE_CONFIG
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1: Enable</b>
+  UINT32  Pme                   :  1;    ///< Azalia wake-on-ring, <b>0: Disable</b>; 1: Enable
+  UINT32  VcType                :  1;    ///< Virtual Channel Type Select: <b>0: VC0</b>, 1: VC1
+  UINT32  HdAudioLinkFrequency  :  4;    ///< HDA-Link frequency (PCH_HDAUDIO_LINK_FREQUENCY enum): <b>2: 24MHz</b>, 1: 12MHz, 0: 6MHz
+  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
+  /**
+    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  IDispCodecDisconnect  :  1;    ///< iDisplay Audio Codec disconnection, <b>0: Not disconnected, enumerable</b>; 1: Disconnected SDI, not enumerable
+  UINT32  CodecSxWakeCapability :  1;    ///< Capability to detect wake initiated by a codec in Sx (eg by modem codec), <b>0: Disable</b>; 1: Enable
+  /**
+    Audio Link Mode configuration bitmask.
+    Allows to configure enablement of the following interfaces: HDA-Link, DMIC, SSP, SoundWire.
+  **/
+  UINT32  AudioLinkHda          :  1;    ///< HDA-Link enablement: 0: Disable; <b>1: Enable</b>. Muxed with SSP0/SSP1/SNDW1
+  UINT32  AudioLinkDmic0        :  1;    ///< DMIC0 link enablement: 0: Disable; <b>1: Enable</b>. Muxed with SNDW4
+  UINT32  AudioLinkDmic1        :  1;    ///< DMIC1 link enablement: 0: Disable; <b>1: Enable</b>. Muxed with SNDW3
+  UINT32  AudioLinkSsp0         :  1;    ///< I2S/SSP0 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with HDA SDI0
+  UINT32  AudioLinkSsp1         :  1;    ///< I2S/SSP1 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with HDA SDI1/SNDW2
+  /**
+    I2S/SSP2 link enablement: <b>0: Disable</b>; 1: Enable.
+    @note Since the I2S/SSP2 pin set contains pads which are also used for CNVi purpose, enabling AudioLinkSsp2
+    is exclusive with CNVi is present.
+  **/
+  UINT32  AudioLinkSsp2         :  1;
+  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
+  /**
+    Soundwire Clock Buffer GPIO RCOMP adjustments based on bus topology:
+    <b>0: non-ACT</b> - 50 Ohm driver impedance when bus topology does not have the external AC termination;
+       1: ACT - 8 Ohm driver impedance when bus topology has the external AC termination.
+  **/
+  UINT32  SndwBufferRcomp       :  1;
+  UINT32  RsvdBits0             :  4;    ///< Reserved bits 0
+  UINT16  ResetWaitTimer;               ///< <b>(Test)</b> The delay timer after Azalia reset, the value is number of microseconds. Default is <b>600</b>.
+  UINT8   Rsvd0;                        ///< Reserved bytes, align to multiple 4
+  /**
+    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;
+  /**
+    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;
+} PCH_HDAUDIO_CONFIG;
+
+/**
+  This structure contains the premem 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  Enable                : 1;     ///< Intel HD Audio (Azalia) enablement: 0: Disable, <b>1: Enable</b>
+  UINT32  RsvdBits              : 31;    ///< Reserved bits 0
+} PCH_HDAUDIO_PREMEM_CONFIG;
+
+/**
+  This structure contains the DXE policies which are related to HD Audio device (cAVS).
+
+  <b>Revision 1:</b>
+  - Inital version.
+  <b>Revision 2:</b>
+  - Add NhltDefaultFlow option for disabling NHLT flow from Si code.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  /**
+    AudioDSP/iSST endpoints configuration exposed via NHLT ACPI table:
+  **/
+  UINT32  DspEndpointDmic       :  2;    ///< DMIC Select (PCH_HDAUDIO_DMIC_TYPE enum): 0: Disable; 1: 2ch array; <b>2: 4ch array</b>; 3: 1ch array
+  UINT32  DspEndpointBluetooth  :  1;    ///< Bluetooth enablement: <b>0: Disable</b>; 1: Enable
+  UINT32  DspEndpointI2s        :  1;    ///< I2S enablement: <b>0: Disable</b>; 1: Enable
+  UINT32  NhltDefaultFlow       :  1;    ///< Default Nhlt flow: 0: Disable, <b>1: Enable</b>
+  UINT32  RsvdBits1             : 27;    ///< Reserved bits 1
+  /**
+    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;
+} PCH_HDAUDIO_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HDAUDIO_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
new file mode 100644
index 0000000000..8c3186153c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
@@ -0,0 +1,57 @@
+/** @file
+  HSIO policy
+
+  Copyright (c) 2019 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
+#define HSIO_CONFIG_REVISION 1
+extern EFI_GUID gHsioPreMemConfigGuid; //@deprecated
+extern EFI_GUID gHsioConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_HSIO_PREMEM_CONFIG block provides HSIO message related settings. //@deprecated
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header //@deprecated
+
+  /**
+  <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 //@deprecated
+  **/
+  UINT32    ChipsetInitMessage :  1;
+  /**
+  <b>(Test)</b>
+  <b>0- Disable</b>
+  1- Enable When enabled, this is used to bypass the reset after ChipsetInit HECI message. //@deprecated
+  **/
+  UINT32    BypassPhySyncReset :  1;
+  UINT32    RsvdBits           : 30;
+} 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
new file mode 100644
index 0000000000..93131ea07a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
@@ -0,0 +1,58 @@
+/** @file
+  HSIO pcie policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _HSIO_PCIE_CONFIG_H_
+#define _HSIO_PCIE_CONFIG_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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
new file mode 100644
index 0000000000..a79542d657
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
@@ -0,0 +1,66 @@
+/** @file
+  Hsio Sata policy
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h
new file mode 100644
index 0000000000..788931b83d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h
@@ -0,0 +1,58 @@
+/** @file
+  Interrupt policy
+
+  Copyright (c) 2019 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  64       ///< Number of all PCH devices
+#define PCH_MAX_PXRC_CONFIG              8        ///< Number of PXRC registers in ITSS
+
+///
+/// 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                        PxRcConfig[PCH_MAX_PXRC_CONFIG];                 ///< Array which stores interrupt routing for 8259 controller
+  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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
new file mode 100644
index 0000000000..ce1d8f746d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
@@ -0,0 +1,68 @@
+/** @file
+  IoApic policy
+
+  Copyright (c) 2019 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 2
+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.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add Enable8254ClockGatingOnS3.
+
+**/
+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 PmcSet8254ClockGateState (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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
new file mode 100644
index 0000000000..d03ef377ce
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
@@ -0,0 +1,57 @@
+/** @file
+  ISH policy
+
+  Copyright (c) 2019 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)
+
+///
+/// The PCH_ISH_CONFIG block describes Integrated Sensor Hub device.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;     ///< Config Block Header
+  UINT32    SpiGpioAssign   :  1;   ///< ISH SPI GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    Uart0GpioAssign :  1;   ///< ISH UART0 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    Uart1GpioAssign :  1;   ///< ISH UART1 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    I2c0GpioAssign  :  1;   ///< ISH I2C0 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    I2c1GpioAssign  :  1;   ///< ISH I2C1 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    I2c2GpioAssign  :  1;   ///< ISH I2C2 GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32    Gp0GpioAssign   :  1;   ///< ISH GP_0 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp1GpioAssign   :  1;   ///< ISH GP_1 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp2GpioAssign   :  1;   ///< ISH GP_2 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp3GpioAssign   :  1;   ///< ISH GP_3 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp4GpioAssign   :  1;   ///< ISH GP_4 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp5GpioAssign   :  1;   ///< ISH GP_5 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp6GpioAssign   :  1;   ///< ISH GP_6 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    Gp7GpioAssign   :  1;   ///< ISH GP_7 GPIO pin assigned: <b>0: False</b> 1: True
+  UINT32    PdtUnlock       :  1;   ///< ISH PDT Unlock Msg: <b>0: False</b> 1: True
+  UINT32    RsvdBits0       : 17;   ///< Reserved Bits
+} PCH_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
+} PCH_ISH_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ISH_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
new file mode 100644
index 0000000000..6bf34f8fe7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
@@ -0,0 +1,35 @@
+/** @file
+  Lan policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _LAN_CONFIG_H_
+#define _LAN_CONFIG_H_
+
+#define LAN_CONFIG_REVISION 1
+extern EFI_GUID gLanConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  PCH intergrated LAN controller configuration settings.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Config Block Header
+  /**
+    Determines if enable PCH internal LAN, 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 register, 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
+} PCH_LAN_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LAN_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
new file mode 100644
index 0000000000..a3a08c3cf6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
@@ -0,0 +1,70 @@
+/** @file
+  Lock down policy
+
+  Copyright (c) 2019 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 RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the upper
+    and lower 128-byte bank of RTC RAM. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  RtcMemoryLock  :  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;
+  /**
+    <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      : 27;             ///< Reserved bits
+} PCH_LOCK_DOWN_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LOCK_DOWN_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
new file mode 100644
index 0000000000..6ee9fe2d75
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
@@ -0,0 +1,34 @@
+/** @file
+  Lpc policy
+
+  Copyright (c) 2019 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;
+  UINT32    RsvdBits                    : 31;     ///< Reserved bits
+} PCH_LPC_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LPC_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
new file mode 100644
index 0000000000..5e1971cb9c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
@@ -0,0 +1,49 @@
+/** @file
+  P2sb policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gP2sbConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to P2SB device.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Deprecate SbiUnlock policy.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    @deprecated from REVISION 2.
+    <b>(Test)</b>
+    This unlock the SBI lock bit to allow SBI after post time.
+    For CFL: <b>0: Lock SBI</b>; 1: Unlock SBI.
+    NOTE: Do not change this policy "SbiUnlock" unless its necessary.
+  **/
+  UINT32    SbiUnlock         :  1;
+  /**
+    <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          : 30;    ///< Reserved bits
+} PCH_P2SB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _P2SB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
new file mode 100644
index 0000000000..67f9a121ca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
@@ -0,0 +1,71 @@
+/** @file
+  PCH General policy
+
+  Copyright (c) 2019 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 3
+#define PCH_GENERAL_PREMEM_CONFIG_REVISION 1
+
+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 postmem general config block.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Remove SubSystemVendorId and SubSystemId.
+  <b>Revision 3</b>:
+  - Add LegacyIoLowLatency support.
+**/
+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 premem general config block.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+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    RsvdBits0       : 31;       ///< Reserved bits
+} PCH_GENERAL_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_GENERAL_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h
new file mode 100644
index 0000000000..36527a5af3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h
@@ -0,0 +1,36 @@
+/** @file
+  PCH Trace Hub policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_TRACEHUB_CONFIG_H_
+#define _PCH_TRACEHUB_CONFIG_H_
+
+#define PCH_TRACEHUB_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gPchTraceHubPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+///
+/// The PCH_TRACE_HUB_CONFIG block describes TraceHub settings for PCH.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  UINT32  EnableMode         :  2;       ///< <b>0 = Disable</b>; 1 = Target Debugger mode; 2 = Host Debugger mode
+  /**
+  Pch Trace hub memory buffer region size policy.
+  The avaliable memory size options are: <b>0:0MB (none)</b>, 1:1MB, 2:8MB, 3:64MB, 4:128MB, 5:256MB, 6:512MB.
+  Refer to TRACE_BUFFER_SIZE in TraceHubCommon.h for supported settings.
+  Note : Limitation of total buffer size (CPU + PCH) is 512MB.
+  **/
+  UINT32  MemReg0Size        :  8;
+  UINT32  MemReg1Size        :  8;
+  UINT32  RsvdBits0          : 14;       ///< Reserved bits
+} PCH_TRACE_HUB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _TRACEHUB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
new file mode 100644
index 0000000000..7d23fcd15f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
@@ -0,0 +1,429 @@
+/** @file
+  Pcie root port policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIE_CONFIG_H_
+#define _PCH_PCIE_CONFIG_H_
+
+#include <PchLimits.h>
+
+#define PCIE_RP_CONFIG_REVISION 3
+#define PCIE_RP_PREMEM_CONFIG_REVISION 1
+
+extern EFI_GUID gPcieRpConfigGuid;
+extern EFI_GUID gPcieRpPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+#define PCH_PCIE_SWEQ_COEFFS_MAX    5
+
+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;
+
+enum PCH_PCIE_SPEED {
+  PchPcieAuto,
+  PchPcieGen1,
+  PchPcieGen2,
+  PchPcieGen3
+};
+
+///
+/// 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
+};
+
+enum PCH_PCIE_COMPLETION_TIMEOUT {
+  PchPcieCompletionTO_Default,
+  PchPcieCompletionTO_50_100us,
+  PchPcieCompletionTO_1_10ms,
+  PchPcieCompletionTO_16_55ms,
+  PchPcieCompletionTO_65_210ms,
+  PchPcieCompletionTO_260_900ms,
+  PchPcieCompletionTO_1_3P5s,
+  PchPcieCompletionTO_4_13s,
+  PchPcieCompletionTO_17_64s,
+  PchPcieCompletionTO_Disabled
+};
+
+typedef enum {
+  PchPcieEqDefault      = 0,  ///< @deprecated since revision 3. Behaves as PchPcieEqHardware.
+  PchPcieEqHardware     = 1,  ///< Hardware equalization
+  PchPcieEqStaticCoeff  = 4   ///< Fixed equalization (requires Coefficient settings per lane)
+} PCH_PCIE_EQ_METHOD;
+
+/**
+  Represent lane specific PCIe Gen3 equalization parameters.
+**/
+typedef struct {
+  UINT8   Cm;                 ///< Coefficient C-1
+  UINT8   Cp;                 ///< Coefficient C+1
+  UINT8   Rsvd0[2];           ///< Reserved bytes
+} PCH_PCIE_EQ_LANE_PARAM, PCH_PCIE_EQ_PARAM;
+
+
+/**
+  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 {
+  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  ExtSync                         :  1;   ///< Indicate whether the extended synch is enabled. <b>0: Disable</b>; 1: Enable.
+  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>.
+  UINT32  RsvdBits0                       : 11;   ///< Reserved bits.
+  /**
+    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;
+  //
+  // 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 PCH_PCIE_MAX_PAYLOAD
+    Changes Max Payload Size Supported field in Device Capabilities of the root port.
+  **/
+  UINT32  MaxPayload                      :  2;
+  UINT32  RsvdBits1                       :  1;   ///< Reserved fields for future expansion w/o protocol change
+  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  RsvdBits3                       :  1;   ///< Placeholder for deleted field
+  /**
+    Determines each PCIE Port speed capability.
+    <b>0: Auto</b>; 1: Gen1; 2: Gen2; 3: Gen3 (see: PCH_PCIE_SPEED)
+  **/
+  UINT8   PcieSpeed;
+  /**
+    PCIe Gen3 Equalization Phase 3 Method (see PCH_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: PCH_PCIE_COMPLETION_TIMEOUT). Default is <b>PchPcieCompletionTO_Default</b>.
+  /**
+    The PCH pin assigned to device PERST# signal if available, zero otherwise.
+    This entry is used mainly in Gen3 software equalization flow. It is necessary for some devices
+    (mainly some graphic adapters) to successfully complete the software equalization flow.
+    See also DeviceResetPadActiveHigh
+  **/
+  UINT32  RsvdBytes0[2];                          ///< Reserved bytes
+  //
+  // Power Management
+  //
+  UINT8   Aspm;                                   ///< The ASPM configuration of the root port (see: PCH_PCIE_ASPM_CONTROL). Default is <b>PchPcieAspmAutoConfig</b> for CNP-LP B1 it is limited to <b>PchPcieAspmL1</b>.
+  UINT8   L1Substates;                            ///< The L1 Substates configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL). Default is <b>PchPcieL1SubstatesL1_1_2</b>.
+  UINT8   LtrEnable;                              ///< Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+  UINT8   LtrConfigLock;                          ///< <b>0: Disable</b>; 1: Enable.
+  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.
+  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>.
+  //
+  // Gen3 Equalization settings
+  //
+  UINT32  Uptp                :  4;               ///< <b>(Test)</b> Upstream Port Transmitter Preset used during Gen3 Link Equalization. Used for all lanes.  Default is <b>5</b>.
+  UINT32  Dptp                :  4;               ///< <b>(Test)</b> Downstream Port Transmiter Preset used during Gen3 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  /**
+    <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
+  **/
+  UINT32  ForceLtrOverride                :  1;
+  UINT32  EnableCpm                       :  1;               ///< Enables Clock Power Management; even if disabled, CLKREQ# signal can still be controlled by L1 PM substates mechanism
+  UINT32  PtmEnabled                      :  1;               ///< Enables PTM capability
+  UINT32  PcieRootPortGen2PllL1CgDisable  :  1;               ///< Disables Gen2PLL shutdown and L1 state controller power gating
+  UINT32  RsvdBits2                       :  6;               ///< Reserved Bits
+  /**
+    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;
+  UINT16  RsvdBytes1[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>:
+  - Init version
+  <b>Revision 2</b>:
+  - Add policy PcieRootPortGen2PllL1CgDisable in PCH_PCIE_ROOT_PORT_CONFIG.
+  <b>Revision 3</b>:
+  - Deleted all items related to PCIe Gen3 software equalization:
+      DeviceResetPad, DeviceResetPadActiveHigh policies and two values from PCH_PCIE_EQ_METHOD enum used for Gen3EqPh3Method field
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  ///
+  /// These members describe the configuration of each PCH PCIe root port.
+  ///
+  PCH_PCIE_ROOT_PORT_CONFIG         RootPort[PCH_MAX_PCIE_ROOT_PORTS];
+  ///
+  /// Configuration of PCIe source clocks
+  ///
+  PCH_PCIE_CLOCK                    PcieClock[PCH_MAX_PCIE_CLOCKS];
+  ///
+  /// 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).
+  ///
+  PCH_PCIE_EQ_LANE_PARAM            EqPh3LaneParam[PCH_MAX_PCIE_ROOT_PORTS];
+  ///
+  /// List of coefficients used during equalization (applicable to both software and hardware EQ)
+  ///
+  PCH_PCIE_EQ_PARAM                 SwEqCoeffList[PCH_PCIE_SWEQ_COEFFS_MAX];
+  PCH_PCIE_EQ_PARAM                 Rsvd0[3];
+  ///
+  /// <b>(Test)</b> This member describes whether PCIE root port Port 8xh Decode is enabled. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  EnablePort8xhDecode              :  1;
+  ///
+  /// <b>(Test)</b> The Index of PCIe Port that is selected for Port8xh Decode (0 Based)
+  ///
+  UINT32  PchPciePort8xhDecodePortIndex    :  5;
+  ///
+  /// 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  DisableRootPortClockGating       :  1;
+  ///
+  /// This member describes whether Peer Memory Writes are enabled on the platform. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  EnablePeerMemoryWrite            :  1;
+  /**
+    Compliance Test Mode shall be enabled when using Compliance Load Board.
+    <b>0: Disable</b>, 1: Enable
+  **/
+  UINT32  ComplianceTestMode               :  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;
+
+  UINT32  RsvdBits0                        : 22;
+  /**
+    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:
+    PCH_PCIE_DEVICE_OVERRIDE *PcieDeviceOverrideTablePtr;
+  **/
+  UINT32  PcieDeviceOverrideTablePtr;
+
+} PCH_PCIE_CONFIG;
+
+/**
+  The PCH_PCIE_RP_PREMEM_CONFIG block describes early configuration of the PCH PCI Express controllers
+  <b>Revision 1</b>:
+  - Init version
+  - Add RpEnable in premem phase.
+**/
+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;
+  UINT16                PcieImrSize;                           ///< PCIe IMR size in megabytes
+  UINT8                 PcieImrEnabled;                        ///< PCIe IMR. <b>0: Disable</b>; 1: Enable.
+  UINT8                 ImrRpSelection;                        ///< Index of PCIe root port that is selected for IMR (0 based)
+} PCH_PCIE_RP_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_PCIE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
new file mode 100644
index 0000000000..8748db5e1a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
@@ -0,0 +1,311 @@
+/** @file
+  Power Management policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PM_CONFIG_H_
+#define _PM_CONFIG_H_
+
+#define PM_CONFIG_REVISION 5
+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,
+} 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,
+  S0ixDisQAuto,
+  S0ixDisQMax,
+} S0IX_DISQ_PROBE_TYPE;
+
+typedef enum {
+  SlpS0OverrideDisabled  = 0x0,
+  SlpS0OverrideEnabled   = 0x1,
+  SlpS0OverrideAuto      = 0x2,
+  SlpS0OverrideMax
+} SLP_S0_OVERRIDE;
+
+/**
+  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>:
+  - Add PsOnEnable and PowerButtonDebounce.
+  <b>Revision 3</b>:
+  - Add CpuC10GatePinEnable in PCH_PM_CONFIG.
+  <b>Revision 4</b>:
+  - Add PmcDbgMsgEn.
+  - Removed PmcReadDisable in PCH_PM_CONFIG.
+  <b>Revision 5</b>:
+  - Add ModPhySusPgEnable
+  <b>Revision 6</b>:
+  - Add SlpS0WithGbeSupport
+**/
+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. 0: Disable; <b>1: Enable</b>
+  **/
+  UINT32                  LpcClockRun          :  1;         /// 0: Disable; <b>1: Enable</b>
+  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;
+  /**
+    Indicates whether SLP_S0# is to be asserted when PCH reaches idle state.
+    When set to one SLP_S0# will be asserted in idle state.
+    When set to zero SLP_S0# will not toggle and is always drivern high.
+    0:Disable, <b>1:Enable</b>
+
+    If a platform is using SLP_S0 to lower PCH voltage the below policy must be disabled.
+  **/
+  UINT32                  SlpS0Enable                  :  1;
+  /**
+    SLP_S0 Voltage Margining Runtime Control.
+    PCH VCCPRIM_CORE Voltage Margining is under ACPI control. Software in runtime
+    may change VCCPRIM_CORE supply voltage based on conditions like HDAudio power state
+    after SLP_S0# assertion. Enable VM runtime control requires ACPI VMON method
+    which will allow configuring VCCPRIM_CORE supply voltage. If this configuration is used
+    ACPI VMON method needs to be provided as it is not implemented in RC.
+    This setting is dependent on PMIC/VR type used on the platform.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  SlpS0VmRuntimeControl        :  1;
+  /**
+    SLP_S0 0.70V Voltage Margining Support.
+    Indicates whether SLP_S0# Voltage Margining supports setting PCH VCCPRIM_CORE down to 0.70V.
+    This setting is dependent on PMIC/VR type used on the platform.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  SlpS0Vm070VSupport           :  1;
+  /**
+    SLP_S0 0.75V Voltage Margining Support.
+    Indicates whether SLP_S0# Voltage Margining supports setting PCH VCCPRIM_CORE down to 0.75V.
+    This setting is dependent on PMIC/VR type used on the platform.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  SlpS0Vm075VSupport           :  1;
+  /**
+    Decide if SLP_S0# needs to be overriden (de-asserted) when system is in debug mode. This is available since CNP-B0.
+    Select 'Auto', it will be auto-configured according to probe type. Select 'Enabled' will disable SLP_S0# assertion whereas 'Disabled' will enable SLP_S0# assertion when debug is enabled.
+    This policy should keep 'Auto', other options are intended for advanced configuration only.
+    please refer to SLP_S0_OVERRIDE
+    0: Disable; 1: Enable; <b>2:Auto</b>
+  **/
+  UINT32                  SlpS0Override                :  2;
+  /**
+    SLP_S0# disqualify for debug prode
+    used to configure power management setting per debug probe to be disqualified from S0ix.
+    Reminder: USB3 DbC supports S0 only. DCI OOB (aka BSSB) uses CCA probe
+    Select 'Auto', it will be auto-configured according to probe type. 'No Change' will keep PMC default settings. Or select the desired debug probe type for S0ix Override settings.\nReminder: USB3 DbC supports S0 only. DCI OOB (aka BSSB) uses CCA probe.
+    Note: This policy should keep 'Auto', other options are intended for advanced configuration only.
+    please refer to S0IX_DISQ_PROBE_TYPE
+    0: No Probe; 1: DCI OOB; 2: USB2 DbC; <b>3:Auto</b>
+  **/
+  UINT32                  SlpS0DisQForDebug            :  3;
+  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;
+  /**
+    Enable/Disable SLP_S0 with GBE Support. This policy is ignored when GbE is not present.
+    0: Disable; <b>1: Enable</b>.
+    Default is 0 when paired with WHL V0 stepping CPU and 1 for all other CPUs.
+  **/
+  UINT32                  SlpS0WithGbeSupport          :  1;
+
+  UINT32                  RsvdBits1                    :  5;
+  /*
+    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;
+  UINT8                   Rsvd0[2];                             ///< Reserved bytes
+
+} PCH_PM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
new file mode 100644
index 0000000000..ce1013b05e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
@@ -0,0 +1,230 @@
+/** @file
+  Sata policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gSataConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum  {
+  PchSataModeAhci,
+  PchSataModeRaid,
+  PchSataModeMax
+} PCH_SATA_MODE;
+
+typedef enum {
+  PchSataOromDelay2sec,
+  PchSataOromDelay4sec,
+  PchSataOromDelay6sec,
+  PchSataOromDelay8sec
+} PCH_SATA_OROM_DELAY;
+
+typedef enum {
+  PchSataSpeedDefault,
+  PchSataSpeedGen1,
+  PchSataSpeedGen2,
+  PchSataSpeedGen3
+} PCH_SATA_SPEED;
+
+typedef enum {
+  PchSataRstMsix,
+  PchSataRstMsi,
+  PchSataRstLegacy
+} PCH_SATA_RST_INTERRUPT;
+
+typedef enum {
+  PchSataRaidClient,
+  PchSataRaidAlternate,
+  PchSataRaidServer
+} PCH_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  RsvdBits0        :  9;                  ///< Reserved fields for future expansion w/o protocol change
+} PCH_SATA_PORT_CONFIG;
+
+/**
+  Rapid Storage Technology settings.
+**/
+typedef struct {
+  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  : PCH_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
+  /**
+    This option allows to configure SATA controller device ID while in RAID mode.
+    Refer to PCH_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
+  **/
+  UINT32  RaidDeviceId       :  2;
+  /**
+    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>
+  **/
+  UINT32  SataRstInterrupt   :  2;
+  UINT32  RsvdBits0          : 13;         ///< Reserved Bits
+} PCH_SATA_RST_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;
+
+/**
+  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, the assignments are as below:
+    i.)   RST PCIe Storage Cycle Router 2 -> RP5 - RP8
+    ii.)  RST PCIe Storage Cycle Router 3 -> RP9 - RP12
+
+    i.)   RST PCIe Storage Cycle Router 1 -> RP9  - RP12
+    ii.)  RST PCIe Storage Cycle Router 2 -> RP13 - RP16
+    iii.) RST PCIe Storage Cycle Router 3 -> RP17 - RP20
+  **/
+  UINT32   RstPcieStoragePort     :  5;
+  UINT32   RsvdBits0              :  2; ///< Reserved bit
+  /**
+    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   RsvdBits1              : 16; ///< Reserved bits
+
+  UINT32   Rsvd0[2];                    ///< Reserved bytes
+} PCH_RST_PCIE_STORAGE_CONFIG;
+
+/**
+  The PCH_SATA_CONFIG block describes the expected configuration of the SATA controllers.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add CpuAttachedStorage in PCH_SATA_RST_CONFIG.
+**/
+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>.
+  ///
+  UINT32                        Enable          :  1;
+  UINT32                        TestMode        :  1;       ///< <b>(Test)</b> <b>0: Disable</b>; 1: Allow entrance to the PCH SATA test modes
+  UINT32                        SalpSupport     :  1;       ///< 0: Disable; <b>1: Enable</b> Aggressive Link Power Management
+  UINT32                        PwrOptEnable    :  1;       ///< 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
+  **/
+  UINT32                        EsataSpeedLimit :  1;
+  UINT32                        LedEnable       :  1;       ///< SATA LED indicates SATA controller activity. 0: Disable; <b>1: Enable</b> SATA LED.
+  UINT32                        RsvdBits0       : 26;       ///< Reserved bits
+
+  /**
+    Determines the system will be configured to which SATA mode (PCH_SATA_MODE). Default is <b>PchSataModeAhci</b>.
+  **/
+  PCH_SATA_MODE                 SataMode;
+  /**
+    Indicates the maximum speed the SATA controller can support
+    <b>0h: PchSataSpeedDefault</b>; 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2); 3h: 6 Gb/s (Gen 1)
+  **/
+  PCH_SATA_SPEED                SpeedLimit;
+  /**
+    This member configures the features, property, and capability for each SATA port.
+  **/
+  PCH_SATA_PORT_CONFIG          PortSettings[PCH_MAX_SATA_PORTS];
+  PCH_SATA_RST_CONFIG           Rst;                        ///< Setting applicable to Rapid Storage Technology
+  /**
+    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
+  **/
+  PCH_RST_PCIE_STORAGE_CONFIG   RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
+  /**
+    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;
+} PCH_SATA_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SATA_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
new file mode 100644
index 0000000000..1e91143b93
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
@@ -0,0 +1,63 @@
+/** @file
+  Scs policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SCS_CONFIG_H_
+#define _SCS_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define SCS_CONFIG_REVISION 2
+extern EFI_GUID gScsConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  DriverStrength33Ohm = 0,
+  DriverStrength40Ohm,
+  DriverStrength50Ohm
+} PCH_SCS_EMMC_DRIVER_STRENGTH;
+
+/**
+  The PCH_SCS_CONFIG block describes Storage and Communication Subsystem (SCS) settings for PCH.
+
+  <b>Revision 1</b>:
+  - Initial version
+  <b>Revision 2</b>:
+  - Add policy SdCardPowerEnableActiveHigh
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+
+  UINT32    ScsEmmcEnabled                :  2;   ///< Determine if eMMC is enabled - 0: Disabled, <b>1: Enabled</b>.
+  UINT32    ScsEmmcHs400Enabled           :  1;   ///< Determine eMMC HS400 Mode if ScsEmmcEnabled - <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    ScsEmmcHs400TuningRequired    :  1;
+  UINT32    ScsEmmcHs400DllDataValid      :  1;   ///< Set if HS400 Tuning Data Valid
+  UINT32    ScsEmmcHs400RxStrobeDll1      :  7;   ///< Rx Strobe Delay Control - Rx Strobe Delay DLL 1 (HS400 Mode)
+  UINT32    ScsEmmcHs400TxDataDll         :  7;   ///< Tx Data Delay Control 1 - Tx Data Delay (HS400 Mode)
+  UINT32    ScsEmmcHs400DriverStrength    :  3;   ///< I/O driver strength: 0 - 33 Ohm, <b>1 - 40 Ohm</b>, 2 - 50 Ohm
+  /**
+    Sd Card Controler 0: Disable; <b>1: Enable</b>.
+    For Desktop sku, the SD Card Controller POR should be disabled. <b> 0:Disable </b>.
+  **/
+  UINT32    ScsSdcardEnabled              :  1;
+  UINT32    ScsUfsEnabled                 :  1;   ///< Determine if Ufs is enabled 0: Disabled 1: Enabled
+  UINT32    SdCardPowerEnableActiveHigh   :  1;   ///< Determine SD_PWREN# polarity 0: Active low, <b>1: Active high</b>
+  UINT32    RsvdBits                      :  7;
+  UINT32    Rsvd0;                                ///< Reserved bytes
+} PCH_SCS_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SCS_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
new file mode 100644
index 0000000000..73dfd17c47
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
@@ -0,0 +1,96 @@
+/** @file
+  Serial IO policy
+
+  Copyright (c) 2019 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 2
+extern EFI_GUID gSerialIoConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_SERIAL_IO_CONFIG block provides the configurations to set the Serial IO controllers
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add I2cPadsTermination
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                             ///< Config Block Header
+  /**
+       0: Disabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - Device will be disabled in PSF
+          - !important! If given device is Function 0 and not all other LPSS functions on given device
+                        are disabled, then 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: Pci</b>;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be enabled in PSF
+          - Only Bar 0 will be enabled
+       2: Acpi;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+    @note Intel does not provide Windows SerialIo drivers for this mode
+       3: Hidden;
+          Designated for Kernel Debug and Legacy UART configuartion, might also be used for IO Expander on I2C
+          - Device is placed in D0
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+          - !important! In this mode UART will work in 16550 Legacy 8BIT Mode, it's resources will be assigned to mother board through ACPI (PNP0C02)
+    @note Considering the PcdSerialIoUartDebugEnable and PcdSerialIoUartNumber for all SerialIo UARTx,
+          the PCD is more meaningful to represent the board design. It means, if PcdSerialIoUartDebugEnable is not 0,
+          the board is designed to use the SerialIo UART for debug message and the PcdSerialIoUartNumber is dedicated
+          to be Debug UART usage. Therefore, it should grayout the option from setup menu since no other options
+          available for this UART controller on this board, and also override the policy default accordingly.
+          While PcdSerialIoUartDebugEnable is 0, then it's allowed to configure the UART controller by policy.
+  **/
+  UINT8  DevMode[PCH_MAX_SERIALIO_CONTROLLERS];
+  UINT8  SpiCsPolarity[PCH_MAX_SERIALIO_SPI_CONTROLLERS];   ///< Selects SPI ChipSelect signal polarity, <b>0=active low</b>.
+  UINT8  UartHwFlowCtrl[PCH_MAX_SERIALIO_UART_CONTROLLERS]; ///< Enables UART hardware flow control, CTS and RTS lines, <b>0:disabled</b>, 1:enabled
+  /**
+    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  I2cPadsTermination[PCH_MAX_SERIALIO_I2C_CONTROLLERS];
+  /**
+    UART device for debug purpose. 0:UART0, 1: UART1, <b>2:UART2</b>
+    @note If CNVi solution is on the platform and UART0 is selected as BT Core interface,
+          UART0 cannot be used for debug purpose.
+  **/
+  UINT32 DebugUartNumber           :  2;
+  UINT32 EnableDebugUartAfterPost  :  1;                    ///< Enable debug UART controller after post. 0: diabled, <b>1: enabled</b>
+  /**
+    <b>0: default pins</b>; 1: pins muxed with CNV_BRI/RGI
+    UART0 can be configured to use two different sets of pins:
+    This setting gives flexibility to use UART0 functionality on other pins when
+    default ones are used for a different purpose.
+    @note Since the second pin set contains pads which are also used for CNVi purpose, setting Uart0PinMuxing
+    is exclusive with CNVi being enabled.
+  **/
+  UINT32 Uart0PinMuxing            :  1;
+  UINT32 RsvdBits0                 : 28;
+} PCH_SERIAL_IO_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SERIAL_IO_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
new file mode 100644
index 0000000000..7ccfe65428
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
@@ -0,0 +1,43 @@
+/** @file
+  Serial IRQ policy
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SERIAL_IRQ_CONFIG_H_
+#define _SERIAL_IRQ_CONFIG_H_
+
+#define SERIAL_IRQ_CONFIG_REVISION 1
+extern EFI_GUID gSerialIrqConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  PchQuietMode,
+  PchContinuousMode
+} PCH_SIRQ_MODE;
+///
+/// Refer to PCH EDS for the details of Start Frame Pulse Width in Continuous and Quiet mode
+///
+typedef enum {
+  PchSfpw4Clk,
+  PchSfpw6Clk,
+  PchSfpw8Clk
+} PCH_START_FRAME_PULSE;
+
+///
+/// The PCH_LPC_SIRQ_CONFIG block describes the expected configuration of the PCH for Serial IRQ.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT32                SirqEnable      :  1;     ///< Determines if enable Serial IRQ. 0: Disable; <b>1: Enable</b>.
+  UINT32                SirqMode        :  2;     ///< Serial IRQ Mode Select. Refer to PCH_SIRQ_MODE for each value. <b>0: quiet mode</b> 1: continuous mode.
+  UINT32                StartFramePulse :  3;     ///< Start Frame Pulse Width. Refer to PCH_START_FRAME_PULSE for each value. Default is <b>PchSfpw4Clk</b>.
+  UINT32                RsvdBits0       : 26;     ///< Reserved bits
+} PCH_LPC_SIRQ_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SERIAL_IRQ_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
new file mode 100644
index 0000000000..d96cf9f6cd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
@@ -0,0 +1,52 @@
+/** @file
+  Smbus policy
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
new file mode 100644
index 0000000000..d3ea563f95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
@@ -0,0 +1,139 @@
+/** @file
+  Thermal policy
+
+  Copyright (c) 2019 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;
+
+/**
+  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
+  **/
+  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 PCH_THERMAL_CONFIG block describes the expected configuration of the PCH for Thermal.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    This locks down "SMI Enable on Alert Thermal Sensor Trip". 0: Disabled, 1: <b>Enabled</b>.
+  **/
+  UINT32  TsmicLock               :  1;
+  UINT32  PchHotEnable            :  1; ///< Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: <b>Disabled<b>, 1: Enabled.
+  UINT32  RsvdBits0               : 30;
+  /**
+    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;
+  /**
+    This field decides the temperature, default is <b>0x154</b>.
+    The recommendation is the same as Cat Trip point.
+  **/
+  UINT16                    PchHotLevel;
+  UINT8                     Rsvd0[6];
+} PCH_THERMAL_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _THERMAL_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h
new file mode 100644
index 0000000000..78e4497d90
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  WatchDog policy
+
+  Copyright (c) 2019 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_
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  6:58   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add Include headers

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

Adds header files common to CPU modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h                |  45 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h | 106 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h    | 141 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h         |  54 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h  | 179 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h |  78 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h   | 149 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h            |  66 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h                            |  16 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h                        | 113 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h                        |  88 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h                      |  23 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h                         | 100 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h                              | 261 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h                |  90 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h               | 118 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h                 |  84 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h                     | 123 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h           |  50 ++++
 19 files changed, 1884 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
new file mode 100644
index 0000000000..47a98131d0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
@@ -0,0 +1,45 @@
+/** @file
+  CPU Config Block.
+
+  Copyright (c) 2019 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>:
+  - Deprecate and move SkipMpInit to CpuConfigLibPreMemConfig.
+  <b>Revision 3</b>:
+  - Move DebugInterfaceEnable from CPU_TEST_CONFIG.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    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;
+  UINT32 SkipMpInit               : 1;            ///< @deprecated since revision 2. For Fsp only, Silicon Initialization will skip MP Initialization (including BSP) if enabled. For non-FSP, this should always be 0.
+  UINT32 DebugInterfaceEnable     : 1;            ///< Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+  UINT32 RsvdBits                 : 28;           ///< Reserved for future use
+  EFI_PHYSICAL_ADDRESS MicrocodePatchAddress;     ///< Pointer to microcode patch that is suitable for this processor.
+} CPU_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
new file mode 100644
index 0000000000..ce965a7510
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
@@ -0,0 +1,106 @@
+/** @file
+  CPU Security PreMemory Config Block.
+
+  Copyright (c) 2019 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 5
+
+extern EFI_GUID gCpuConfigLibPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Config Library PreMemory Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Update for JTAG Power Gate comment.
+  <b>Revision 3</b>:
+  - Add PeciSxReset and PeciC10Reset
+  <b>Revision 4</b>:
+  - Add SkipMpInit
+  <b>Revision 5</b>:
+  - Add DpSscMarginEnable
+**/
+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.
+   - <b>1: Maximum non-turbo performance</b>.
+   - 2: Turbo performance.
+  @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;
+  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;
+  /**
+    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>0: Disable</b> for CNL, and <b>1: Enable</b> for all other CPU's
+    - 0: Disable
+    - 1: Enable
+  **/
+  UINT32 PeciC10Reset               : 1;
+  /**
+    For Fsp only, Silicon Initialization will skip MP Initialization
+    (including BSP) if enabled. For non-FSP, this should always be 0.
+    - <b>0: Disable</b>
+    - 1: Enable
+  **/
+  UINT32 SkipMpInit                 : 1;
+  /**
+    Enable DisplayPort SSC range reduction
+    @note This should only be used on systems that exceeds allowed SSC modulation range as defined in VESA's spec.
+    - <b>0: Disable</b>
+    - 1: Enable
+  **/
+  UINT32 DpSscMarginEnable          : 1;
+  UINT32 RsvdBits                   : 17;
+  /**
+    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;
+  UINT8  Reserved[3];                    ///< Reserved for alignment
+} CPU_CONFIG_LIB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
new file mode 100644
index 0000000000..a0b8a208e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
@@ -0,0 +1,141 @@
+/** @file
+  CPU Overclocking Config Block.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
+#define _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
+
+#define CPU_OVERCLOCKING_CONFIG_REVISION 4
+
+extern EFI_GUID gCpuOverclockingPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Overclocking Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>
+  - Deprecate RingMinOcRatio
+  <b>Revision 3</b>
+  - Change RingDownBin default to 'Enabled'
+  <b>Revision 4</b>
+  - Add TvbRatioClipping, TvbVoltageOptimization
+
+**/
+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.; <b>0: Disable</b>; 1: Enable (Lock).
+  /**
+  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 RsvdBits             :  10;              ///< 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-255. Max range varies by CPU sku.
+  **/
+  UINT8  CoreMaxOcRatio;
+  /**
+  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;
+  /**
+  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-255. Max range varies by CPU sku.
+  **/
+  UINT8  RingMaxOcRatio;
+  /**
+  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;
+  UINT8  RingMinOcRatio;                          ///< Deprecated since rev 2. Minimum ring ratio override. <b>0: Hardware defaults.</b> Range: 0-83.
+  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.
+  /**
+  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 RsvdBits1              :  6;
+  /**
+  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 0 to 63.
+  **/
+  UINT8  TjMaxOffset;
+} CPU_OVERCLOCKING_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_OVERCLOCKING_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
new file mode 100644
index 0000000000..e45f335ff9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
@@ -0,0 +1,54 @@
+/** @file
+  CPU PID Config Block.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
new file mode 100644
index 0000000000..2ad474b7e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
@@ -0,0 +1,179 @@
+/** @file
+  CPU Power Management Basic Config Block.
+
+  Copyright (c) 2019 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 2
+
+extern EFI_GUID gCpuPowerMgmtBasicConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Power Management Basic Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added MinRingRatioLimit
+  - Added MaxRingRatioLimit
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+  Sets the boot frequency starting from reset vector.
+   - 0: Maximum battery performance.
+   - <b>1: Maximum non-turbo performance</b>.
+   - 2: Turbo performance.
+  @note If Turbo is selected BIOS will start in max non-turbo mode and switch to Turbo mode.
+  **/
+  UINT32 BootFrequency                  : 2;
+  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; <b>0: Disabled</b>; 1: Enabled (Lock).
+  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 RsvdBits                       : 9;      ///< 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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>15</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.
+  0: Disable; <b>1: Enable;</b>
+  **/
+  UINT8  EnableItbm                     : 1;
+  /**
+  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;
+  UINT8  ReservedBits1                  : 6;      ///< 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.
+  Default: <b>0 - AUTO</b>, auto will program 28 seconds.
+  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;
+} CPU_POWER_MGMT_BASIC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_BASIC_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
new file mode 100644
index 0000000000..7eb91fa3ee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
@@ -0,0 +1,78 @@
+/** @file
+  CPU Power Managment Custom Config Block.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
new file mode 100644
index 0000000000..cb9b20249f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
@@ -0,0 +1,149 @@
+/** @file
+  CPU Power Management Test Config Block.
+
+  Copyright (c) 2019 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 3
+
+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,
+  PpmIrmPairFixedPriority,
+  PpmIrmPairRoundRobin,
+  PpmIrmPairHashVector,
+  PpmIrmNoChange
+} PPM_IRM_SETTING;
+
+/**
+  CPU Power Management Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Update PkgCStateDemotion and PkgCStateUnDemotion to be Disable.
+  <b>Revision 3</b>:
+  - Add  CstateLatencyControl0TimeUnit for CFL only
+  - Add  CstateLatencyControl0Irtl for CFL only
+**/
+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 AutoThermalReporting          : 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. [Cannonlake Y] 0: Disable; <b>1: Enable</b> [CoffeeLake] <b>Disable</b>; 1: Enable
+  UINT32 PkgCStateUnDemotion           : 1;        ///<              Enable or Disable Package Cstate UnDemotion.  0: [Cannonlake Y] 0: Disable; <b>1: Enable</b> [CoffeeLake] <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;        ///<              Configuration for boot TDP selection; <b>0: TDP Nominal</b>; 1: TDP Down; 2: TDP Up.
+  UINT16 CstateLatencyControl1Irtl;                ///< Offset 32-33 Interrupt Response Time Limit of LatencyContol1 MSR 0x60B[9:0].
+  UINT16 CstateLatencyControl2Irtl;                ///< Offset 34-35 Interrupt Response Time Limit of LatencyContol2 MSR 0x60C[9:0].
+  UINT16 CstateLatencyControl3Irtl;                ///< Offset 36-37 Interrupt Response Time Limit of LatencyContol3 MSR 0x633[9:0].
+  UINT16 CstateLatencyControl4Irtl;                ///< Offset 38-39 Interrupt Response Time Limit of LatencyContol4 MSR 0x634[9:0].
+  UINT16 CstateLatencyControl5Irtl;                ///< Offset 40-41 Interrupt Response Time Limit of LatencyContol5 MSR 0x635[9:0].
+  UINT16 CstateLatencyControl0Irtl;                ///< Offset 42-43 Interrupt Response Time Limit of LatencyContol1 MSR 0x60A[9:0].
+  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 CstateLatencyControl0TimeUnit; ///< Offset 45    TimeUnit for Latency Control0 MSR 0x60A[12:10]; (CFL)2: 1024ns
+  C_STATE_TIME_UNIT CstateLatencyControl1TimeUnit; ///< Offset 46    TimeUnit for Latency Control1 MSR 0x60B[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl2TimeUnit; ///< Offset 47    TimeUnit for Latency Control2 MSR 0x60C[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl3TimeUnit; ///< Offset 48    TimeUnit for Latency Control3 MSR 0x633[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl4TimeUnit; ///< Offset 49    TimeUnit for Latency Control4 MSR 0x634[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl5TimeUnit; ///< Offset 50    TimeUnit for Latency Control5 MSR 0x635[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  /**
+  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.
+   - 1: Round robin.
+   - 2: Hash vector.
+   - 4: PAIR with fixed priority.
+   - 5: PAIR with round robin.
+   - 6: PAIR with hash vector.
+   - 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
new file mode 100644
index 0000000000..b94eb5e263
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
@@ -0,0 +1,66 @@
+/** @file
+  CPU Test Config Block.
+
+  Copyright (c) 2019 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 4
+
+extern EFI_GUID gCpuTestConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Fixed RsvdBits incorrect value.
+  <b>Revision 3</b>:
+  - Added CpuWakeUpTimer
+  <b>Revision 4</b>:
+  - Deprecate and move DebugInterfaceEnable to CPU_CONFIG.
+**/
+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                DebugInterfaceEnable            : 1;     ///< @deprecated Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+  UINT32                DebugInterfaceLockEnable        : 1;     ///< Lock or Unlock debug interface features; 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.
+  /**
+    This policy should be used to enable or disable Voltage Optimization feature.
+    Recommended defaults:
+     Enable  - For Mobile SKUs(U/Y)
+     Disable - Rest of all SKUs other than Mobile.
+  **/
+  UINT32                VoltageOptimization             : 1;
+  UINT32                CpuWakeUpTimer                  : 1;      ///< Enable or Disable long CPU wake up timer. 0: Disabled (8s); <b>1: Enabled (180s)</b>.
+  UINT32                RsvdBits                        : 21;     ///< 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;
+} CPU_TEST_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_TEST_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
new file mode 100644
index 0000000000..48fdbdd012
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
@@ -0,0 +1,16 @@
+/** @file
+  Macros to simplify and abstract the interface to CPU configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPUACCESS_H_
+#define _CPUACCESS_H_
+
+#include "CpuRegs.h"
+#include "CpuDataStruct.h"
+#include "CpuPowerMgmt.h"
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
new file mode 100644
index 0000000000..2382e60dca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
@@ -0,0 +1,113 @@
+/** @file
+  This file declares various data structures used in CPU reference code.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_DATA_STRUCT_H
+#define _CPU_DATA_STRUCT_H
+
+//
+// The reason for changing the state of the processor Only applies to Disabling processors.
+// In future, we can add add/remove support
+//
+#define CPU_CAUSE_NOT_DISABLED      0x0000
+#define CPU_CAUSE_INTERNAL_ERROR    0x0001
+#define CPU_CAUSE_THERMAL_ERROR     0x0002
+#define CPU_CAUSE_SELFTEST_FAILURE  0x0004
+#define CPU_CAUSE_PREBOOT_TIMEOUT   0x0008
+#define CPU_CAUSE_FAILED_TO_START   0x0010
+#define CPU_CAUSE_CONFIG_ERROR      0x0020
+#define CPU_CAUSE_USER_SELECTION    0x0080
+#define CPU_CAUSE_BY_ASSOCIATION    0x0100
+#define CPU_CAUSE_UNSPECIFIED       0x8000
+
+typedef UINT32 CPU_STATE_CHANGE_CAUSE;
+
+///
+/// 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;
+
+///
+/// Structure to describe microcode header
+///
+typedef struct {
+  UINT32 HeaderVersion;  ///< Version number of the update header.
+  UINT32 UpdateRevision; ///< Unique version number for the update.
+  UINT32 Date;           ///< Date of the update creation.
+  UINT32 ProcessorId;    ///< Signature of the processor that requires this update.
+  UINT32 Checksum;       ///< Checksum of update data and header.
+  UINT32 LoaderRevision; ///< Version number of the microcode loader program.
+  UINT32 ProcessorFlags; ///< Lower 4 bits denoting platform type information.
+  UINT32 DataSize;       ///< Size of encoded data in bytes.
+  UINT32 TotalSize;      ///< Total size of microcode update in bytes.
+  UINT8  Reserved[12];   ///< Reserved bits.
+} CPU_MICROCODE_HEADER;
+
+///
+/// Structure to describe the extended signature table header of the microcode update
+///
+typedef struct {
+  UINT32 ExtendedSignatureCount; ///< Number of extended signature structures.
+  UINT32 ExtendedTableChecksum;  ///< Checksum of update extended processor signature table.
+  UINT8  Reserved[12];           ///< Reserved bits.
+} CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+///
+/// Structure to describe the data of the extended table of the microcode update
+///
+typedef struct {
+  UINT32 ProcessorSignature; ///< Extended signature of the processor that requires this update
+  UINT32 ProcessorFlag;      ///< Lower 4 bits denoting platform type information
+  UINT32 ProcessorChecksum;  ///< checksum of each of the extended update
+} CPU_MICROCODE_EXTENDED_TABLE;
+
+#pragma pack(1)
+///
+/// MSR_REGISTER definition as a Union of QWORDS, DWORDS and BYTES
+///
+typedef union _MSR_REGISTER {
+  UINT64  Qword;       ///< MSR value in 64 bit QWORD.
+
+  ///
+  /// MSR value represented in two DWORDS
+  ///
+  struct {
+    UINT32  Low;       ///< Lower DWORD of the 64 bit MSR value.
+    UINT32  High;      ///< Higher DWORD of the 64 bit MSR value.
+  } Dwords;
+
+  ///
+  /// MSR value represented in eight bytes.
+  ///
+  struct {
+    UINT8 FirstByte;   ///< First byte of the 64 bit MSR value.
+    UINT8 SecondByte;  ///< Second byte of the 64 bit MSR value.
+    UINT8 ThirdByte;   ///< Third byte of the 64 bit MSR value.
+    UINT8 FouthByte;   ///< Fourth byte of the 64 bit MSR value.
+    UINT8 FifthByte;   ///< Fifth byte of the 64 bit MSR value.
+    UINT8 SixthByte;   ///< Sixth byte of the 64 bit MSR value.
+    UINT8 SeventhByte; ///< Seventh byte of the 64 bit MSR value.
+    UINT8 EighthByte;  ///< Eigth byte of the 64 bit MSR value.
+  } Bytes;
+} MSR_REGISTER;
+
+///
+/// Store BIST data for BSP.
+///
+typedef struct {
+  UINT32 ApicId;    ///< APIC ID
+  UINT32 Health;    ///< BIST result
+} BIST_HOB_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
new file mode 100644
index 0000000000..4862d62975
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
@@ -0,0 +1,88 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define CPU NVS Area operation region.
+  //
+
+#ifndef _CPU_NVS_AREA_DEF_H_
+#define _CPU_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT8    Revision;                                ///< Offset 0       CPU GlobalNvs Revision
+  UINT32   PpmFlags;                                ///< Offset 1       PPM Flags Values
+  UINT8    Reserved0[1];                            ///< Offset 5:5
+  UINT8    AutoCriticalTripPoint;                   ///< Offset 6       Auto Critical Trip Point
+  UINT8    AutoPassiveTripPoint;                    ///< Offset 7       Auto Passive Trip Point
+  UINT8    AutoActiveTripPoint;                     ///< Offset 8       Auto Active Trip Point
+  UINT32   Cpuid;                                   ///< Offset 9       CPUID
+  UINT8    ConfigurablePpc;                         ///< Offset 13      Boot Mode vlues for _PPC
+  UINT8    CtdpLevelsSupported;                     ///< Offset 14      ConfigTdp Number Of Levels
+  UINT8    ConfigTdpBootModeIndex;                  ///< Offset 15      CTDP Boot Mode Index
+  UINT16   CtdpPowerLimit1[3];                      ///< Offset 16      CTDP Level 0 Power Limit1
+                                                    ///< Offset 18      CTDP Level 1 Power Limit1
+                                                    ///< Offset 20      CTDP Level 2 Power Limit1
+  UINT16   CtdpPowerLimit2[3];                      ///< Offset 22      CTDP Level 0 Power Limit2
+                                                    ///< Offset 24      CTDP Level 1 Power Limit2
+                                                    ///< Offset 26      CTDP Level 2 Power Limit2
+  UINT8    CtdpPowerLimitWindow[3];                 ///< Offset 28      CTDP Level 0 Power Limit1 Time Window
+                                                    ///< Offset 29      CTDP Level 1 Power Limit1 Time Window
+                                                    ///< Offset 30      CTDP Level 2 Power Limit1 Time Window
+  UINT8    CtdpCtc[3];                              ///< Offset 31      CTDP Level 0 CTC
+                                                    ///< Offset 32      CTDP Level 1 CTC
+                                                    ///< Offset 33      CTDP Level 2 CTC
+  UINT8    CtdpTar[3];                              ///< Offset 34      CTDP Level 0 TAR
+                                                    ///< Offset 35      CTDP Level 1 TAR
+                                                    ///< Offset 36      CTDP Level 2 TAR
+  UINT8    CtdpPpc[3];                              ///< Offset 37      CTDP Level 0 PPC
+                                                    ///< Offset 38      CTDP Level 1 PPC
+                                                    ///< Offset 39      CTDP Level 2 PPC
+  UINT8    Reserved1[1];                            ///< Offset 40:40
+  UINT8    C6MwaitValue;                            ///< Offset 41      Mwait Hint value for C6
+  UINT8    C7MwaitValue;                            ///< Offset 42      Mwait Hint value for C7/C7s
+  UINT8    CDMwaitValue;                            ///< Offset 43      Mwait Hint value for C7/C8/C9/C10
+  UINT8    Reserved2[2];                            ///< Offset 44:45
+  UINT16   C6Latency;                               ///< Offset 46      Latency Value for C6
+  UINT16   C7Latency;                               ///< Offset 48      Latency Value for C7/C7S
+  UINT16   CDLatency;                               ///< Offset 50      Latency Value for C8/C9/C10
+  UINT16   CDIOLevel;                               ///< Offset 52      IO LVL value for C8/C9/C10
+  UINT16   CDPowerValue;                            ///< Offset 54      Power value for C8/C9/C10
+  UINT8    MiscPowerManagementFlags;                ///< Offset 56      MiscPowerManagementFlags
+  UINT8    EnableDigitalThermalSensor;              ///< Offset 57      Digital Thermal Sensor Enable
+  UINT8    BspDigitalThermalSensorTemperature;      ///< Offset 58      Digital Thermal Sensor 1 Readingn for BSP
+  UINT8    ApDigitalThermalSensorTemperature;       ///< Offset 59      Digital Thermal Sensor 2 Reading for AP1
+  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 60      DTS SMI Function Call via DTS IO Trap
+  UINT8    PackageDTSTemperature;                   ///< Offset 61      Package Temperature
+  UINT8    IsPackageTempMSRAvailable;               ///< Offset 62      Package Temperature MSR available
+  UINT8    Ap2DigitalThermalSensorTemperature;      ///< Offset 63      Digital Thermal Sensor 3 Reading for AP2
+  UINT8    Ap3DigitalThermalSensorTemperature;      ///< Offset 64      Digital Thermal Sensor 4 Reading for AP3
+  UINT64   BiosGuardMemAddress;                     ///< Offset 65      BIOS Guard Memory Address for Tool Interface
+  UINT8    BiosGuardMemSize;                        ///< Offset 73      BIOS Guard Memory Size for Tool Interface
+  UINT16   BiosGuardIoTrapAddress;                  ///< Offset 74      BIOS Guard IoTrap Address for Tool Interface
+  UINT16   BiosGuardIoTrapLength;                   ///< Offset 76      BIOS Guard IoTrap Length for Tool Interface
+  UINT16   DtsIoTrapAddress;                        ///< Offset 78      DTS IO trap Address
+  UINT8    DtsIoTrapLength;                         ///< Offset 80      DTS IO trap Length
+  UINT8    DtsAcpiEnable;                           ///< Offset 81      DTS is in ACPI Mode Enabled
+  UINT8    SgxStatus;                               ///< Offset 82      SGX Status
+  UINT64   EpcBaseAddress;                          ///< Offset 83      EPC Base Address
+  UINT64   EpcLength;                               ///< Offset 91      EPC Length
+  UINT8    HwpVersion;                              ///< Offset 99      HWP Version
+  UINT8    HwpInterruptStatus;                      ///< Offset 100     HWP Interrupt Status
+  UINT8    DtsInterruptStatus;                      ///< Offset 101     DTS Interrupt Status
+  UINT8    HwpSmi;                                  ///< Offset 102     SMI to setup HWP LVT tables
+  UINT8    LowestMaxPerf;                           ///< Offset 103     Max ratio of the slowest core.
+  UINT8    EnableItbm;                              ///< Offset 104     Enable/Disable Intel Turbo Boost Max Technology 3.0.
+  UINT8    EnableItbmDriver;                        ///< Offset 105     Enable/Disable Intel Turbo Boost Max Technology 3.0 Driver.
+  UINT8    ItbmInterruptStatus;                     ///< Offset 106     Intel Turbo Boost Max Technology 3.0 interrupt status.
+  UINT8    ItbmSmi;                                 ///< Offset 107     SMI to resume periodic SMM for Intel Turbo Boost Max Technology 3.0.
+  UINT8    OcBins;                                  ///< Offset 108     Indicates bins of Oc support. MSR 194h FLEX_RATIO Bits (19:17)
+  UINT8    C3MwaitValue;                            ///< Offset 109     Mwait Hint value for C3 (CFL only)
+  UINT16   C3Latency;                               ///< Offset 110     Latency Value for C3 (CFL only)
+} CPU_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
new file mode 100644
index 0000000000..a9abd426f9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
@@ -0,0 +1,23 @@
+/** @file
+  CPU Policy structure definition which will contain several config blocks during runtime.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_COMMON_H_
+#define _CPU_POLICY_COMMON_H_
+
+#include "CpuPowerMgmt.h"
+#include <ConfigBlock.h>
+#include <ConfigBlock/CpuOverclockingConfig.h>
+#include <ConfigBlock/CpuConfig.h>
+#include <ConfigBlock/CpuPidTestConfig.h>
+#include <ConfigBlock/CpuPowerMgmtBasicConfig.h>
+#include <ConfigBlock/CpuPowerMgmtCustomConfig.h>
+#include <ConfigBlock/CpuPowerMgmtTestConfig.h>
+#include <ConfigBlock/CpuTestConfig.h>
+#include <ConfigBlock/CpuConfigLibPreMemConfig.h>
+
+#endif // _CPU_POLICY_COMMON_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
new file mode 100644
index 0000000000..af1f70b34f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
@@ -0,0 +1,100 @@
+/** @file
+  This file contains define definitions specific to processor
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POWER_MGMT_DEFINITIONS_H_
+#define _POWER_MGMT_DEFINITIONS_H_
+
+#define CSTATE_SUPPORTED          0x1
+#define ENHANCED_CSTATE_SUPPORTED 0x2
+#define C6_C7_SHORT_LATENCY_SUPPORTED 0x01
+#define C6_C7_LONG_LATENCY_SUPPORTED  0x02
+#define C7s_SHORT_LATENCY_SUPPORTED   0x03
+#define C7s_LONG_LATENCY_SUPPORTED    0x04
+//
+// Voltage offset definitions
+//
+#define OC_LIB_OFFSET_ADAPTIVE  0
+#define OC_LIB_OFFSET_OVERRIDE  1
+//
+// Platform Power Management Flags Bit Definitions:
+//   These defines are also used in CPU0CST.ASL to check platform configuration
+//   and build C-state table accordingly.
+//
+#define PPM_EIST                BIT0   ///< Enhanced Intel Speed Step Technology.
+#define PPM_C1                  BIT1   ///< C1 enabled, supported.
+#define PPM_C1E                 BIT2   ///< C1E enabled.
+#define PPM_C3                  BIT3   ///< C3 enabled, supported.
+#define PPM_C6                  BIT4   ///< C6 enabled, supported.
+#define PPM_C7                  BIT5   ///< C7 enabled, supported.
+#define PPM_C7S                 BIT6   ///< C7S enabled, supported
+#define PPM_TM                  BIT7   ///< Adaptive Thermal Monitor.
+#define PPM_TURBO               BIT8   ///< Long duration turbo mode
+#define PPM_CMP                 BIT9   ///< CMP.
+#define PPM_TSTATES             BIT10  ///< CPU throttling states
+#define PPM_MWAIT_EXT           BIT11  ///< MONITIOR/MWAIT Extensions supported.
+#define PPM_EEPST               BIT12  ///< Energy efficient P-State Feature enabled
+#define PPM_TSTATE_FINE_GRAINED BIT13  ///< Fine grained CPU Throttling states
+#define PPM_CD                  BIT14  ///< Deep Cstate - C8/C9/C10
+#define PPM_TIMED_MWAIT         BIT15  ///< Timed Mwait support
+#define C6_LONG_LATENCY_ENABLE  BIT16  ///< 1=C6 Long and Short,0=C6 Short only
+#define C7_LONG_LATENCY_ENABLE  BIT17  ///< 1=C7 Long and Short,0=C7 Short only
+#define C7s_LONG_LATENCY_ENABLE BIT18  ///< 1=C7s Long and Short,0=C7s Short only
+#define PPM_C8                  BIT19  ///< 1= C8 enabled/supported
+#define PPM_C9                  BIT20  ///< 1= C9 enabled/supported
+#define PPM_C10                 BIT21  ///< 1= C10 enabled/supported
+#define PPM_HWP                 BIT22  ///< 1= HWP enabled/supported
+#define PPM_HWP_LVT             BIT23  ///< 1= HWP LVT enabled/supported
+#define PPM_OC_UNLOCKED         BIT24  ///< 1= Overclocking fully unlocked
+
+#define PPM_C_STATES            0x7A    ///< PPM_C1 + PPM_C3 + PPM_C6 + PPM_C7 + PPM_C7S
+#define C3_LATENCY              0x4E
+#define C6_C7_SHORT_LATENCY     0x76
+#define C6_C7_LONG_LATENCY      0x94
+#define C8_LATENCY              0xFA
+#define C9_LATENCY              0x14C
+#define C10_LATENCY             0x3F2
+
+//
+// The following definitions are based on assumed location for the  ACPI
+// Base Address.  Modify as necessary base on platform-specific requirements.
+//
+#define PCH_ACPI_PBLK 0x1810
+#define PCH_ACPI_LV2  0x1814
+#define PCH_ACPI_LV3  0x1815
+#define PCH_ACPI_LV4  0x1816
+#define PCH_ACPI_LV6  0x1818
+#define PCH_ACPI_LV5  0x1817
+#define PCH_ACPI_LV7  0x1819
+
+//
+// C-State Latency (us) and Power (mW) for C1
+//
+#define C1_LATENCY                        1
+#define C1_POWER                          0x3E8
+#define C3_POWER                          0x1F4
+#define C6_POWER                          0x15E
+#define C7_POWER                          0xC8
+#define C8_POWER                          0xC8
+#define C9_POWER                          0xC8
+#define C10_POWER                         0xC8
+
+
+#define PID_DOMAIN_KP                     0
+#define PID_DOMAIN_KI                     1
+#define PID_DOMAIN_KD                     2
+#define MAILBOX_PARAM_1_OFFSET            8
+
+///
+///  VR Domain Definitions
+///
+#define CPU_VR_DOMAIN_SA           0x0
+#define CPU_VR_DOMAIN_IA           0x1
+#define CPU_VR_DOMAIN_RING         0x2
+#define CPU_VR_DOMAIN_GT           0x3
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
new file mode 100644
index 0000000000..68f2c019e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
@@ -0,0 +1,261 @@
+/** @file
+  Register names for CPU registers
+
+  <b>Conventions</b>
+  - Definitions beginning with "MSR_" are MSRs
+  - 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_REGS_H_
+#define _CPU_REGS_H_
+
+#define MSR_CORE_THREAD_COUNT                                         0x00000035
+#define B_THREAD_COUNT_MASK                                           0xFFFF
+#define MSR_SPCL_CHIPSET_USAGE_ADDR                                   0x000001FE
+///
+/// Arch-specific MSR defines in SDM
+/// @{
+
+#define MSR_PLATFORM_INFO                                             0x000000CE
+#define N_PLATFORM_INFO_MIN_RATIO                                     40
+#define B_PLATFORM_INFO_RATIO_MASK                                    0xFF
+#define N_PLATFORM_INFO_MAX_RATIO                                     8
+#define B_MSR_PLATFORM_INFO_BIOSGUARD_AVAIL                           BIT35
+#define N_MSR_PLATFORM_INFO_CONFIG_TDP_NUM_LEVELS_OFFSET              33
+#define V_CONFIG_TDP_NUM_LEVELS_MASK                                  (BIT34 | BIT33)
+#define B_PLATFORM_INFO_TDC_TDP_LIMIT                                 BIT29
+#define N_PLATFORM_INFO_RATIO_LIMIT                                   28
+#define B_PLATFORM_INFO_RATIO_LIMIT                                   BIT28
+#define B_PLATFORM_INFO_SAMPLE_PART                                   BIT27
+#define B_PLATFORM_INFO_SMM_SAVE_CONTROL                              BIT16
+#define N_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET                    30
+#define B_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET                    BIT30
+#define B_PLATFORM_INFO_TIMED_MWAIT_SUPPORTED                         BIT37
+#define B_PLATFORM_INFO_EDRAM_EN                                      BIT57
+
+//
+// MSR_BROADWELL_PKG_CST_CONFIG_CONTROL: related defines
+//
+#define B_TIMED_MWAIT_ENABLE                                          BIT31 ///< @todo Remove when bitfield definition is available.
+#define V_CSTATE_LIMIT_C1                                             0x01
+#define V_CSTATE_LIMIT_C3                                             0x02
+#define V_CSTATE_LIMIT_C6                                             0x03
+#define V_CSTATE_LIMIT_C7                                             0x04
+#define V_CSTATE_LIMIT_C7S                                            0x05
+#define V_CSTATE_LIMIT_C8                                             0x06
+#define V_CSTATE_LIMIT_C9                                             0x07
+#define V_CSTATE_LIMIT_C10                                            0x08
+
+#define MSR_PMG_IO_CAPTURE_BASE                                       0x000000E4
+#define B_MSR_PMG_CST_RANGE                                           (BIT18 | BIT17 | BIT16)
+#define V_IO_CAPT_LVL2                                                (0x0 << 16)   ///< C3
+#define V_IO_CAPT_LVL3                                                (0x1 << 16)   ///< C6
+#define V_IO_CAPT_LVL4                                                (0x2 << 16)   ///< C7
+#define V_IO_CAPT_LVL5                                                (0x3 << 16)   ///< C8
+#define V_IO_CAPT_LVL6                                                (0x4 << 16)   ///< C9
+#define V_IO_CAPT_LVL7                                                (0x5 << 16)   ///< C10
+#define V_IO_CAPT_LVL2_BASE_ADDR_MASK                                 0xFFFF
+
+#define MSR_TEMPERATURE_TARGET                                        0x000001A2
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LOCK                      BIT31
+#define N_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LIMIT                     24
+#define V_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_OFFSET_MASK           0x3F
+#define N_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_OFFSET    (16)
+#define B_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_MASK      (0xFF << 16)
+#define N_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET               8
+#define B_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET               (0xFF << 8)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_TIME_WINDOW               (0x7F)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_MASK                      0xFF
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_CLAMP_BIT                 BIT7
+
+
+#define MSR_TURBO_RATIO_LIMIT                                         0x000001AD
+#define N_MSR_TURBO_RATIO_LIMIT_1C                                    0
+#define B_MSR_TURBO_RATIO_LIMIT_1C                                    (0xFF << 0)
+#define N_MSR_TURBO_RATIO_LIMIT_2C                                    8
+#define B_MSR_TURBO_RATIO_LIMIT_2C                                    (0xFF << 8)
+#define N_MSR_TURBO_RATIO_LIMIT_3C                                    16
+#define B_MSR_TURBO_RATIO_LIMIT_3C                                    (0xFF << 16)
+#define N_MSR_TURBO_RATIO_LIMIT_4C                                    24
+#define B_MSR_TURBO_RATIO_LIMIT_4C                                    (0xFF << 24)
+#define N_MSR_TURBO_RATIO_LIMIT_5C                                    32
+#define B_MSR_TURBO_RATIO_LIMIT_5C                                    (0xFF << 32)
+#define N_MSR_TURBO_RATIO_LIMIT_6C                                    40
+#define B_MSR_TURBO_RATIO_LIMIT_6C                                    (0xFF << 40)
+#define N_MSR_TURBO_RATIO_LIMIT_7C                                    48
+#define B_MSR_TURBO_RATIO_LIMIT_7C                                    (0xFF << 48)
+#define N_MSR_TURBO_RATIO_LIMIT_8C                                    56
+#define B_MSR_TURBO_RATIO_LIMIT_8C                                    (0xFF << 56)
+
+#define MSR_IA32_FEATURE_CONFIG                                       0x0000013C
+#define B_IA32_FEATURE_CONFIG_AES_DIS                                 BIT1
+#define B_IA32_FEATURE_CONFIG_LOCK                                    BIT0
+
+//
+// MSRs for SMM State Save Register
+//
+#define MSR_SMM_MCA_CAP                                               0x0000017D
+#define B_TARGETED_SMI                                                BIT56
+#define N_TARGETED_SMI                                                56
+#define B_SMM_CPU_SVRSTR                                              BIT57
+#define N_SMM_CPU_SVRSTR                                              57
+#define B_SMM_CODE_ACCESS_CHK                                         BIT58
+#define N_SMM_CODE_ACCESS_CHK                                         58
+#define B_LONG_FLOW_INDICATION                                        BIT59
+#define N_LONG_FLOW_INDICATION                                        59
+#define MSR_SMM_FEATURE_CONTROL                                       0x000004E0
+#define B_SMM_FEATURE_CONTROL_LOCK                                    BIT0
+#define B_SMM_CPU_SAVE_EN                                             BIT1
+#define B_SMM_CODE_CHK_EN                                             BIT2
+
+/// @}
+
+
+///
+/// Bit defines for MSRs defined in UefiCpuPkg/Include/Register/ArchitecturalMsr.h.
+/// @{
+
+//
+// Number of fixed MTRRs
+//
+#define V_FIXED_MTRR_NUMBER                                           11
+
+//
+// Number of variable MTRRs
+//
+#define V_MAXIMUM_VARIABLE_MTRR_NUMBER                                10
+
+//
+// Bit defines for MSR_IA32_MTRR_DEF_TYPE
+//
+#define B_CACHE_MTRR_VALID                                            BIT11
+#define B_CACHE_FIXED_MTRR_VALID                                      BIT10
+
+//
+// Bit defines for MSR_IA32_DEBUG_INTERFACE
+//
+#define B_DEBUG_INTERFACE_ENABLE                                      BIT0
+#define B_DEBUG_INTERFACE_LOCK                                        BIT30
+#define B_DEBUG_INTERFACE_DEBUG_STATUS                                BIT31
+
+/// @}
+
+///
+/// Other defines
+///
+#ifndef TRIGGER_MODE_EDGE
+#define TRIGGER_MODE_EDGE             0x00
+#endif
+#ifndef TRIGGER_MODE_LEVEL
+#define TRIGGER_MODE_LEVEL            0x01
+#endif
+
+#ifndef CPU_FEATURE_DISABLE
+#define CPU_FEATURE_DISABLE  0
+#endif
+#ifndef CPU_FEATURE_ENABLE
+#define CPU_FEATURE_ENABLE   1
+#endif
+
+#define CACHE_UNCACHEABLE               0
+#define CACHE_WRITECOMBINING            1
+#define CACHE_WRITETHROUGH              4
+#define CACHE_WRITEPROTECTED            5
+#define CACHE_WRITEBACK                 6
+
+
+//
+// Processor Definitions
+//
+#define CPUID_FULL_STEPPING                      0x0000000F
+#define CPUID_FULL_FAMILY_MODEL                  0x0FFF0FF0
+#define CPUID_FULL_FAMILY_MODEL_STEPPING         0x0FFF0FFF
+#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX 0x000806E0
+#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO 0x000906E0
+#define CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO 0x00060670
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND 1000
+#endif
+
+#define BITS(x) (1 << (x))
+
+/**
+Notes :
+  1.  Bit position always starts at 0.
+  2.  Following macros are applicable only for Word aligned integers.
+**/
+#define BIT(Pos, Value)               (1 << (Pos) & (Value))
+#define BITRANGE(From, Width, Value)  (((Value) >> (From)) & ((1 << (Width)) - 1))
+
+///
+/// Enums for CPU Family IDs
+///
+typedef enum {
+  EnumCpuCflUltUlx    = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
+  EnumCpuCflDtHalo    = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO,
+  EnumCpuCnlDtHalo    = CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO,
+  EnumCpuMax          = CPUID_FULL_FAMILY_MODEL
+} CPU_FAMILY;
+
+///
+/// Enums for CPU Stepping IDs
+///
+typedef enum {
+  ///
+  /// Coffeelake ULX/ULT Steppings
+  ///
+  EnumKblH0         = 9,
+  EnumCflD0         = 0xA,
+
+  /// Whiskey Lake ULT Steppings
+  EnumCflW0         = 0xB,
+  EnumCflV0         = 0xC,
+
+  EnumCflMaxUltUlxStep = EnumCflV0,
+
+  ///
+  /// Coffeelake DT/Halo Steppings
+  ///
+  EnumCflU0         = 0xA,
+  EnumCflB0         = 0xB,
+  EnumCflP0         = 0xC,
+  EnumCflR0         = 0xD,
+  EnumCflMaxDtHaloStep = EnumCflR0,
+
+  ///
+  /// Max Stepping
+  ///
+  EnumCpuSteppingMax  = CPUID_FULL_STEPPING
+} CPU_STEPPING;
+
+///
+/// Enums for CPU SKU IDs
+///
+typedef enum {
+  EnumCpuUlt        = 0,
+  EnumCpuTrad,
+  EnumCpuUlx,
+  EnumCpuHalo,
+  EnumCpuUnknown
+} CPU_SKU;
+
+///
+/// Enums for CPU Generation
+///
+typedef enum {
+  EnumCflCpu  = 0,
+  EnumCpuUnknownGeneration = 255
+} CPU_GENERATION;
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
new file mode 100644
index 0000000000..79dff36783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
@@ -0,0 +1,90 @@
+/** @file
+  Header file for Cpu Mailbox Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_MAILBOX_LIB_H_
+#define _CPU_MAILBOX_LIB_H_
+
+//
+//  Mailbox Related Definitions
+//
+
+/**
+  Generic Mailbox function for mailbox write commands. This function will
+  poll the mailbox interface for control, issue the write request, poll
+  for completion, and verify the write was succussful.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[in]  MailboxData     Overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status values are:
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  IN UINT32  MailboxData,
+  OUT UINT32 *MailboxStatus
+  );
+
+/**
+  Generic Mailbox function for mailbox read commands. This function will write
+  the read request from MailboxType, and populate the read results in the MailboxDataPtr.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status are
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  OUT UINT32 *MailboxDataPtr,
+  OUT UINT32 *MailboxStatus
+  );
+
+/**
+  Poll the run/busy bit of the mailbox until available or timeout expires.
+
+  @param[in]  MailboxType
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_TIMEOUT           Command timeout.
+**/
+EFI_STATUS
+EFIAPI
+PollMailboxReady (
+  IN UINT32 MailboxType
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
new file mode 100644
index 0000000000..a2dc83efb5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
@@ -0,0 +1,118 @@
+/** @file
+  Header file for CpuPlatform Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PLATFORM_LIB_H_
+#define _CPU_PLATFORM_LIB_H_
+
+#include <CpuRegs.h>
+#include <CpuDataStruct.h>
+#include <CpuPowerMgmt.h>
+
+/**
+  Check CPU Type of the platform
+
+  @retval CPU_FAMILY              CPU type
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+  VOID
+  );
+
+/**
+  Return Cpu stepping type
+
+  @retval CPU_STEPPING                   Cpu stepping type
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+  VOID
+  );
+
+/**
+  Return CPU Sku
+
+  @retval UINT8              CPU Sku
+**/
+UINT8
+EFIAPI
+GetCpuSku (
+  VOID
+  );
+
+/**
+  Returns the processor microcode revision of the processor installed in the system.
+
+  @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+  VOID
+  );
+
+/**
+  Check if this microcode is correct one for processor
+
+  @param[in] Cpuid               - processor CPUID
+  @param[in] MicrocodeEntryPoint - entry point of microcode
+  @param[in] Revision            - revision of microcode
+
+  @retval CorrectMicrocode if this microcode is correct
+**/
+BOOLEAN
+CheckMicrocode (
+  IN UINT32               Cpuid,
+  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+  IN UINT32               *Revision
+  );
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval True if SGX supported or FALSE if not
+**/
+BOOLEAN
+IsSgxSupported (
+  VOID
+  );
+
+/**
+  Get processor generation
+
+  @retval CPU_GENERATION  Returns the executing thread's processor generation.
+**/
+CPU_GENERATION
+GetCpuGeneration (
+  VOID
+  );
+
+/**
+  Check if Disable CPU Debug (DCD) bit is set from FIT CPU Debugging [Disabled].
+  If it is set, CPU probe mode is disabled.
+
+  @retval TRUE    DCD is set
+  @retval FALSE   DCD is clear
+**/
+BOOLEAN
+IsCpuDebugDisabled (
+  VOID
+  );
+
+/**
+  Is Whiskey Lake CPU.
+
+  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
+  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
+**/
+BOOLEAN
+IsWhlCpu (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
new file mode 100644
index 0000000000..88f4353e91
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
@@ -0,0 +1,84 @@
+/** @file
+  Prototype of the CpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_LIB_H_
+#define _CPU_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole CPU related config blocks of SI_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi             The Si PreMem Policy PPI instance
+**/
+VOID
+CpuPreMemPrintPolicy (
+IN  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+);
+
+/**
+  Get CPU PREMEM config block table total size.
+
+  @retval Size of CPU PREMEM config block table
+**/
+UINT16
+EFIAPI
+CpuGetPreMemConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  Print whole CPU config blocks of SiPolicyPpi and serial out.
+
+  @param[in] SiPolicyPpi             The SI Policy PPI instance
+**/
+VOID
+CpuPrintPolicy (
+  IN  SI_POLICY_PPI                 *SiPolicyPpi
+  );
+
+/**
+  Get CPU config block table total size.
+
+  @retval Size of CPU config block table
+**/
+UINT16
+EFIAPI
+CpuGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  CpuAddConfigBlocks add all Cpu config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_CPU_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
new file mode 100644
index 0000000000..67f88ce987
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
@@ -0,0 +1,123 @@
+/** @file
+  Protocol used to report CPU information
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_INFO_H_
+#define _CPU_INFO_H_
+
+#include <CpuDataStruct.h>
+
+typedef struct _CPU_INFO_PROTOCOL CPU_INFO_PROTOCOL;
+
+
+extern EFI_GUID gCpuInfoProtocolGuid;
+
+//
+// DXE_CPU_INFO_PROTOCOL revisions
+//
+#define CPU_INFO_PROTOCOL_REVISION 1
+
+//
+// Processor feature definitions.
+//
+#define TXT_SUPPORT        BIT0
+#define VMX_SUPPORT        BIT1
+#define XD_SUPPORT         BIT2
+#define DCA_SUPPORT        BIT3
+#define X2APIC_SUPPORT     BIT4
+#define AES_SUPPORT        BIT5
+#define HT_SUPPORT         BIT6
+#define DEBUG_SUPPORT      BIT7
+#define DEBUG_LOCK_SUPPORT BIT8
+#define PROC_TRACE_SUPPORT BIT9
+#define HDC_SUPPORT        BIT10
+
+
+#pragma pack(1)
+///
+/// Cache descriptor information
+///
+typedef struct {
+  UINT8   Desc;                                    ///< Cache Descriptor
+  UINT8   Level;                                   ///< Cache Level
+  UINT8   Type;                                    ///< Cache Type. 0: Data, 1: Instruction, 3: Unified
+  UINT32  Size;                                    ///< Cache Size.
+  UINT16  Associativity;                           ///< Cache Ways of Associativity.
+} CACHE_DESCRIPTOR_INFO;
+
+///
+/// Processor information
+///
+typedef struct {
+  UINT32                CpuSignature;               ///< Processor signature and version information.
+  UINT64                Features;                   ///< Features availability in the CPU based on reading ECX after doing Asmcpuid(EAX=1).
+  CHAR8                 *BrandString;               ///< Processor Brand String.
+  UINT8                 NumSupportedCores;          ///< Total Number of Supported Cores in CPU Package. If Dual core, 2 cores.
+  UINT8                 NumSupportedThreadsPerCore; ///< Number of Supported Threads per Core.
+  UINT8                 NumCores;                   ///< Number of Enabled or Active Cores.
+  UINT8                 NumHts;                     ///< Number of Enabled Threads per Core. This will be 1 or 2.
+  UINT32                IntendedFreq;               ///< Maximum non turbo ratio in MHz
+  UINT32                ActualFreq;                 ///< Actual frequency in MHz
+  UINT32                Voltage;                    ///< Current operating voltage.
+  CACHE_DESCRIPTOR_INFO *CacheInfo;                 ///< Cache descriptor information.
+  UINT8                 MaxCacheSupported;          ///< Maximum cache supported.
+  UINT8                 SmmbaseSwSmiNumber;         ///< Software SMI Number from Smbase. @Note: This is unused.
+  UINT16                NumberOfPStates;            ///< Number of P-States.
+} CPU_INFO;
+
+///
+/// This HOB is data structure representing two different address location in SMRAM to hold SMRAM CPU DATA.
+///
+typedef struct {
+  EFI_PHYSICAL_ADDRESS LockBoxData;  ///< First location (address) of SMRAM CPU DATA.
+  EFI_PHYSICAL_ADDRESS SmramCpuData; ///< Second location (Address) of SMRAM CPU DATA.
+  UINT64               LockBoxSize;  ///< Size of SMRAM CPU DATA.
+} SMRAM_CPU_INFO;
+
+///
+/// SGX Information
+///
+typedef struct {
+  UINT64  SgxSinitNvsData;  ///< Sinit SE SVN Version saved and passed back in next boot
+} SGX_INFO;
+
+#pragma pack()
+
+///
+/// This protocol provides information about the common features available in this CPU.
+///
+struct _CPU_INFO_PROTOCOL {
+  /**
+  Revision for the protocol structure.
+  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>:
+   -  Initial version
+  **/
+  UINT8  Revision;
+  /**
+  CPU Supported Feature.
+   - BIT0:  If set then processor supports TXT.
+   - BIT1:  If set then processor supports virtual mode extensions.
+   - BIT2:  If set then processor supports execute disable bit.
+   - BIT3:  If set then processor supports DCA.
+   - BIT4:  If set then processor supports X2APIC.
+   - BIT5:  If set then processor supports Advanced Encryption Standard.
+   - BIT6:  If set then processor supports hyperthreading.
+   - BIT7:  If set then processor supports debug interface.
+   - BIT8:  If set then processor supports debug interface lock.
+   - BIT9:  If set then processor supports processor trace.
+   - BIT10: If Set then processor supports supports HDC.
+  **/
+  UINT64         CpuCommonFeatures;
+  CPU_INFO       *CpuInfo;      ///< Processor Basic Information
+  SMRAM_CPU_INFO *SmramCpuInfo; ///< SMRAM CPU Information
+  SGX_INFO       *SgxInfo;      ///< SGX Information
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
new file mode 100644
index 0000000000..ed056025b7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
@@ -0,0 +1,50 @@
+/** @file
+  Protocol used for specifying platform related CPU information and policy setting.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_PROTOCOL_H_
+#define _CPU_POLICY_PROTOCOL_H_
+
+//
+// DXE_CPU_POLICY_PROTOCOL revisions
+//
+#define DXE_CPU_POLICY_PROTOCOL_REVISION 1
+
+extern EFI_GUID gDxeCpuPolicyProtocolGuid;
+
+#pragma pack (push,1)
+
+/**
+  The protocol allows the platform code to publish a set of configuration information that the
+  CPU drivers will use to configure the processor in the DXE phase.
+  This Policy Protocol needs to be initialized for CPU configuration.
+  @note The Protocol has to be published before processor DXE drivers are dispatched.
+**/
+typedef struct {
+  /**
+  This member specifies the revision of the Cpu Policy protocol. This field is used to indicate backward
+  compatible changes to the protocol. Any such changes to this protocol will result in an update in the revision number.
+
+  <b>Revision 1</b>:
+   - Initial version
+  **/
+  /**
+  Policies to obtain CPU temperature.
+   - <b>0: ACPI thermal management uses EC reported temperature values</b>.
+   - 1: ACPI thermal management uses DTS SMM mechanism to obtain CPU temperature values.
+   - 2: ACPI Thermal Management uses EC reported temperature values and DTS SMM is used to handle Out of Spec condition.
+  **/
+  UINT32                         EnableDts           : 2;
+  UINT32                         RsvdBit             : 30;  ///< Reserved bits, align to multiple 32;
+
+  UINT8                          Revision;                  ///< Current revision of policy.
+  UINT8                          ReservedByte[3];           ///< Reserved bytes, align to multiple 8.
+} DXE_CPU_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers

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

Adds the following header files:
 * Pch/Include/library

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h         |  27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h             |  24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h     |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h           | 265 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h             | 788 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h       | 166 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h            |  33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h | 371 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h          | 141 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h           |  36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h          | 109 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h          | 407 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h        | 105 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h           | 226 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h           |  45 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h        | 114 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h         |  24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h     | 116 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h      | 240 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h  | 111 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h    |  23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h     | 121 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h              | 207 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h             |  76 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h           |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h   |  98 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h              |  23 +
 27 files changed, 3976 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
new file mode 100644
index 0000000000..ee77334ecb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
@@ -0,0 +1,27 @@
+/** @file
+  Header file for BiosLockLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BIOSLOCK_LIB_H_
+#define _BIOSLOCK_LIB_H_
+
+/**
+  Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable In SMM.STS).
+  When this is set, attempts to write the WPD (Write Protect Disable) bit in PCH
+  will cause a SMI which will allow the BIOS to verify that the write is from a valid source.
+
+  Bios should always enable LockDownConfig.BiosLock policy to set Bios Lock bit in FRC.
+  If capsule udpate is enabled, it's expected to not do BiosLock by setting BiosLock policy disable
+  so it can udpate BIOS region.
+  After flash update, it should utilize this lib to do BiosLock for security.
+**/
+VOID
+BiosLockEnable (
+  VOID
+  );
+
+#endif // _BIOSLOCK_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
new file mode 100644
index 0000000000..f406e0d929
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
@@ -0,0 +1,24 @@
+/** @file
+  Header file for CnviLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CNVI_LIB_H_
+#define _CNVI_LIB_H_
+
+/**
+  Check if CNVi is present.
+
+  @retval TRUE                    CNVi is enabled
+  @retval FALSE                   CNVi is disabled
+
+**/
+BOOLEAN
+CnviIsPresent (
+  VOID
+  );
+
+#endif // _CNVI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
new file mode 100644
index 0000000000..4d1ed91f7e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
@@ -0,0 +1,58 @@
+/** @file
+  Prototype of the DxePchPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_POLICY_LIB_H_
+#define _DXE_PCH_POLICY_LIB_H_
+
+#include <Protocol/PchPolicy.h>
+
+/**
+  This function prints the DXE phase policy.
+
+  @param[in] PchPolicy    - PCH DXE Policy protocol
+**/
+VOID
+PchPrintPolicyProtocol (
+  IN  PCH_POLICY_PROTOCOL         *PchPolicy
+  );
+
+/**
+  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 Policy 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      **PchPolicy
+  );
+
+/**
+  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] PchPolicy                  The pointer to PCH 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
+  );
+
+#endif // _DXE_PCH_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
new file mode 100644
index 0000000000..a6ce032eba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
@@ -0,0 +1,265 @@
+/** @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_H_", "_PCH_LP_"
+    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GBE_MDI_LIB_H_
+#define _GBE_MDI_LIB_H_
+
+//
+//
+//      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)
+#define MDI_REG_SHIFT(x)                              (x << 16)
+#define R_PHY_MDI_PHY_REG_DATA_READ_WRITE             0x00120000
+// LAN PHY MDI registers and bits
+//
+
+//
+// Page 769 Port Control Registers
+// 6020h (769 * 32)
+//
+#define PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS        769
+
+//
+//  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/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
new file mode 100644
index 0000000000..25def24fca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
@@ -0,0 +1,788 @@
+/** @file
+  Header file for GpioLib.
+  All function in this library is available for PEI, DXE, and SMM
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_LIB_H_
+#define _GPIO_LIB_H_
+
+#include <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 Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetHostSwOwnershipForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *HostSwRegVal
+  );
+
+/**
+  This procedure will get GPIO Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioSetHostSwOwnershipForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       HostSwRegVal
+  );
+
+/**
+  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 set 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 GpioSetGroupDwToGpeDwX()
+
+  @param[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  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
+GpioSetGroupToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2
+  );
+
+/**
+  This procedure will set 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[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupDwForGpeDw0    DW of pins to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  GroupDwForGpeDw1    DW of pins to be mapped to GPE_DW1
+  @param[in]  GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
+  @param[in]  GroupDwForGpeDw2    DW of pins to be mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetGroupDwToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN UINT32                    GroupDwForGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN UINT32                    GroupDwForGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2,
+  IN 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] Data                GPE STS data
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiGpeSts (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32*                  Data
+  );
+
+/**
+  This procedure is used to lock all GPIO pads except the ones
+  which were requested during their configuration to be left unlocked.
+  This function must be called before BIOS_DONE - before POSTBOOT_SAI is enabled.
+    FSP - call this function from wrapper before transition to FSP-S
+    UEFI/EDK - call this function before EndOfPei event
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioLockPads (
+  VOID
+  );
+
+/**
+  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
+  );
+
+#endif // _GPIO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
new file mode 100644
index 0000000000..9956c60dd5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
@@ -0,0 +1,166 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_NATIVE_LIB_H_
+#define _GPIO_NATIVE_LIB_H_
+
+#include <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
+  );
+
+/**
+  This function checks if SATA GP pin is enabled
+
+  @param[in]  SataCtrlIndex       SATA Controller Index
+  @param[in]  SataPort            SATA port number
+
+  @retval TRUE                    SATA GPx is enabled (pad is in required native mode)
+          FALSE                   SATA GPx is not enabled
+**/
+BOOLEAN
+GpioIsSataGpEnabled (
+  IN  UINT32          SataCtrlIndex,
+  IN  UINTN           SataPort
+  );
+
+#endif // _GPIO_NATIVE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
new file mode 100644
index 0000000000..6ef0d08774
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
@@ -0,0 +1,33 @@
+/** @file
+  Header file for OC WDT Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _OC_WDT_LIB_H_
+#define _OC_WDT_LIB_H_
+
+/**
+  Check for unexpected reset.
+  If there was an unexpected reset, enforces WDT expiration.
+  Stops watchdog.
+**/
+VOID
+OcWdtResetCheck (
+  VOID
+  );
+
+/**
+  This function install WDT PPI
+
+  @retval EFI_STATUS  Results of the installation of the WDT PPI
+**/
+EFI_STATUS
+EFIAPI
+OcWdtInit (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
new file mode 100644
index 0000000000..7b6c82d390
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
@@ -0,0 +1,371 @@
+/** @file
+  Header file for PchCycleDecodingLib.
+
+  Copyright (c) 2019 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_
+
+/**
+  Set PCH TCO base address.
+  This cycle decoding is allowed to set when DMIC.SRL is 0.
+  Programming steps:
+  1. set Smbus PCI offset 54h [8] to enable TCO base address.
+  2. program Smbus PCI offset 50h [15:5] to TCO base address.
+  3. set Smbus PCI offset 54h [8] to enable TCO base address.
+  4. program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [Smbus PCI offset 50h[15:5], 1].
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchTcoBaseSet (
+  IN  UINT16                            Address
+  );
+
+/**
+  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
+#define PCH_H_ESPI_GEN_IO_RANGE_MAX     PCH_LPC_GEN_IO_RANGE_MAX  // @deprecated. Keep it here for backward compatibility.
+
+///
+/// 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 eSPI CS1# generic IO range decoding.
+  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 eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enable.
+  2. Program eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @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               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeSet (
+  IN  UINT16                            Address,
+  IN  UINTN                             Length
+  );
+
+/**
+  Get PCH LPC/eSPI generic IO range list.
+  This function returns a list of base address, length, and enable for all LPC/eSPI generic IO range registers.
+
+  @param[out] LpcGenIoRangeList         Return all LPC/eSPI generic IO range register status.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchLpcGenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *LpcGenIoRangeList
+  );
+
+/**
+  Get PCH eSPI CS1# generic IO range list.
+  This function returns a list of base address, length, and enable for all eSPI CS1# generic IO range registers.
+
+  @param[out] GenIoRangeList            eSPI generic IO range registers.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
+  );
+
+/**
+  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
+  );
+
+/**
+  @deprecated. Keep this for backward compatibility.
+  It's replaced by PchEspiCs1MemRangeSet.
+**/
+EFI_STATUS
+PchEspiMemRange2Set (
+  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
+  );
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port.
+  System BIOS is likely to do this very soon after reset before PCI bus enumeration, it must ensure that
+  the IO Base Address field (PCIe:1Ch[7:4]) contains a value greater than the IO Limit field (PCIe:1Ch[15:12])
+  before setting the IOSE bit. Otherwise the bridge will positively decode IO range 000h - FFFh by its default
+  IO range values.
+  This cycle decoding is allowed to set when DMIC.SRL is 0.
+  Programming steps:
+  1. Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest ID of RP.
+  2. Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'. Use byte write on GCS+1 and leave the BILD bit which is RWO.
+  3. Program IOSE bit of PCIE:Reg04h[0] to '1'  for PCH to send such IO cycles to PCIe bus for subtractive decoding.
+
+  @param[in] RpPhyNumber                PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoPort80DecodeSet (
+  IN  UINTN                             RpPhyNumber
+  );
+
+/**
+  Get IO APIC registers base address.
+
+  @param[out] IoApicBase                Buffer of IO APIC register 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/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
new file mode 100644
index 0000000000..c1d3c50ead
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
@@ -0,0 +1,141 @@
+/** @file
+  Header file for PchEspiLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_ESPI_LIB_H_
+#define _PCH_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 // _PEI_DXE_SMM_PCH_ESPI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
new file mode 100644
index 0000000000..2a4dc986f4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
@@ -0,0 +1,36 @@
+/** @file
+  Header file for PchGbeLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_GBE_LIB_H_
+#define _PCH_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
+PchIsGbeRegionValid (
+  VOID
+  );
+
+
+/**
+  Check whether LAN controller is enabled in the platform.
+
+  @retval TRUE                    GbE is enabled
+  @retval FALSE                   GbE is disabled
+**/
+BOOLEAN
+PchIsGbePresent (
+  VOID
+  );
+
+#endif // _PCH_GBE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
new file mode 100644
index 0000000000..4f93f44120
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
@@ -0,0 +1,109 @@
+/** @file
+  Header file for PchHsioLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HSIO_LIB_H_
+#define _PCH_HSIO_LIB_H_
+
+/**
+  Represents HSIO lane
+**/
+typedef struct {
+  UINT8        Index; ///< Lane index
+  UINT8        Pid;   ///< Sideband ID
+  UINT16       Base;  ///< Sideband base address
+} HSIO_LANE;
+
+/**
+  The function returns the Port Id and lane owner for the specified lane
+
+  @param[in]  PhyMode             Phymode that needs to be checked
+  @param[out] Pid                 Common Lane End Point ID
+  @param[out] LaneOwner           Lane Owner
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid lane number
+**/
+EFI_STATUS
+EFIAPI
+PchGetLaneInfo (
+  IN  UINT32                            LaneNum,
+  OUT UINT8                             *PortId,
+  OUT UINT8                             *LaneOwner
+  );
+
+/**
+  Get HSIO lane representation needed to perform any operation on the lane.
+
+  @param[in]  LaneIndex  Number of the HSIO lane
+  @param[out] HsioLane   HSIO lane representation
+**/
+VOID
+HsioGetLane (
+  IN   UINT8       LaneIndex,
+  OUT  HSIO_LANE   *HsioLane
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  PcieLaneIndex             PCIE Root Port Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetPcieLaneNum (
+  UINT32              PcieLaneIndex,
+  UINT8               *LaneNum
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  SataLaneIndex             Sata Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetSataLaneNum (
+  UINT32              SataLaneIndex,
+  UINT8               *LaneNum
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  Usb3LaneIndex             USB3 Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetUsb3LaneNum (
+  UINT32              Usb3LaneIndex,
+  UINT8               *LaneNum
+  );
+
+/**
+  Determine the lane number of a specified port
+
+  @param[out] LaneNum                   GBE Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetGbeLaneNum (
+  UINT8               *LaneNum
+  );
+
+#endif // _PCH_HSIO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
new file mode 100644
index 0000000000..94a8204fa5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
@@ -0,0 +1,407 @@
+/** @file
+  Header file for PchInfoLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INFO_LIB_H_
+#define _PCH_INFO_LIB_H_
+
+#include <PchHda.h>
+
+typedef UINT8 PCH_STEPPING;
+#define PCH_A0                0x00
+#define PCH_A1                0x01
+#define PCH_B0                0x10
+#define PCH_B1                0x11
+#define PCH_C0                0x20
+#define PCH_C1                0x21
+#define PCH_D0                0x30
+#define PCH_D1                0x31
+#define PCH_STEPPING_MAX      0xFF
+
+typedef UINT8 PCH_SERIES;
+#define PCH_H                   1
+#define PCH_LP                  2
+#define PCH_SERVER              0x80
+#define PCH_UNKNOWN_SERIES      0xFF
+
+typedef UINT8 PCH_GENERATION;
+#define CNL_PCH                 3
+#define CDF_PCH                 0x80
+#define PCH_UNKNOWN_GENERATION  0xFF
+
+typedef enum {
+  RstUnsupported  = 0,
+  RstPremium,
+  RstOptane,
+  RstMaxMode
+} RST_MODE;
+
+/**
+  Return LPC Device Id
+
+  @retval PCH_LPC_DEVICE_ID         PCH Lpc Device ID
+**/
+UINT16
+PchGetLpcDid (
+  VOID
+  );
+
+/**
+  Return Pch stepping type
+
+  @retval PCH_STEPPING            Pch stepping type
+**/
+PCH_STEPPING
+PchStepping (
+  VOID
+  );
+
+/**
+  Determine if PCH is supported
+
+  @retval TRUE                    PCH is supported
+  @retval FALSE                   PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+  VOID
+  );
+
+/**
+  Return Pch Series
+
+  @retval PCH_SERIES                Pch Series
+**/
+PCH_SERIES
+PchSeries (
+  VOID
+  );
+
+/**
+  Check if this is PCH LP series
+
+  @retval TRUE                It's PCH LP series
+  @retval FALSE               It's not PCH LP series
+**/
+BOOLEAN
+IsPchLp (
+  VOID
+  );
+
+/**
+  Check if this is PCH H series
+
+  @retval TRUE                It's PCH H series
+  @retval FALSE               It's not PCH H series
+**/
+BOOLEAN
+IsPchH (
+  VOID
+  );
+
+/**
+  Check if this is Server PCH
+
+  @retval TRUE                It's a Server PCH
+  @retval FALSE               It's not a Server PCH
+**/
+BOOLEAN
+IsPchServer (
+  VOID
+  );
+
+/**
+  Return Pch Generation
+
+  @retval PCH_GENERATION            Pch Generation
+**/
+PCH_GENERATION
+PchGeneration (
+  VOID
+  );
+
+/**
+  Check if this is CDF PCH generation
+
+  @retval TRUE                It's CDF PCH
+  @retval FALSE               It's not CDF PCH
+**/
+BOOLEAN
+IsCdfPch (
+  VOID
+  );
+
+/**
+  @retval TRUE                It's CNL PCH
+  @retval FALSE               It's not CNL PCH
+**/
+BOOLEAN
+IsCnlPch (
+  VOID
+  );
+
+/**
+  Check if this is Server SKU
+
+  @retval TRUE                It's PCH Server SKU
+  @retval FALSE               It's not PCH Server SKU
+**/
+BOOLEAN
+IsPchServerSku (
+  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 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 Maximum Usb3 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb3PortNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Serial IO controllers number
+
+  @retval Pch Maximum Serial IO controllers number
+**/
+UINT8
+GetPchMaxSerialIoControllersNum (
+  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
+  );
+
+#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 (
+  );
+
+/**
+  Get PCH Sku ASCII string
+  The return string is zero terminated.
+
+  @retval Static ASCII string of PCH Sku
+**/
+CHAR8*
+PchGetSkuStr (
+  VOID
+  );
+
+/**
+  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 UFS controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchUfsSupported  (
+  VOID
+  );
+
+/**
+  Gets the maximum number of UFS controller supported by this chipset.
+
+  @return Number of supported UFS controllers
+**/
+UINT8
+PchGetMaxUfsNum (
+  VOID
+  );
+
+/**
+  Get RST mode supported by the silicon
+
+  @retval RST_MODE    RST mode supported by silicon
+**/
+RST_MODE
+PchGetSupportedRstMode (
+  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 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 PCH_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
+  );
+
+#endif // _PCH_INFO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
new file mode 100644
index 0000000000..7c26f6939e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
@@ -0,0 +1,105 @@
+/** @file
+  Header file for PchPcieRpLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIERP_LIB_H_
+#define _PCH_PCIERP_LIB_H_
+
+#define RST_PCIE_STORAGE_CR_1                       0
+#define RST_PCIE_STORAGE_CR_2                       1
+#define RST_PCIE_STORAGE_CR_3                       2
+#define RST_PCIE_STORAGE_CR_INVALID                 99
+
+typedef struct {
+  UINT8 DevNum;
+  UINT8 Pid;
+  UINT8 RpNumBase;
+} PCH_PCIE_CONTROLLER_INFO;
+
+/**
+  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
+  );
+
+/**
+  Check the RST PCIe Storage Cycle Router number according to the root port number and PCH type
+
+  @param[in] RootPortNum  Root Port Number
+
+  @return  The RST PCIe Storage Cycle Router Number
+**/
+UINT8
+RstGetCycleRouterNumber (
+  IN  UINT32                   RootPortNum
+  );
+
+#endif // _PCH_PCIERP_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
new file mode 100644
index 0000000000..2d57087c6b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
@@ -0,0 +1,226 @@
+/** @file
+  Header file for PchPcrLib.
+
+  Copyright (c) 2019 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 base address (defined in PchReservedResources.h)
+///
+//#define PCH_PCR_BASE_ADDRESS            0xFD000000
+//#define PCH_PCR_MMIO_SIZE               0x01000000
+/**
+  Definition for PCR address
+  The PCR address is used to the PCR MMIO programming
+**/
+#define PCH_PCR_ADDRESS(Pid, Offset)    (PCH_PCR_BASE_ADDRESS | ((UINT8)(Pid) << 16) | (UINT16)(Offset))
+
+/**
+  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
+  );
+
+#endif // _PCH_PCR_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
new file mode 100644
index 0000000000..36a0adb56f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
@@ -0,0 +1,45 @@
+/** @file
+  Header file for PchPmcLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PMC_LIB_H_
+#define _PCH_PMC_LIB_H_
+
+typedef enum {
+  WarmBoot          = 1,
+  ColdBoot,
+  PwrFlr,
+  PwrFlrSys,
+  PwrFlrPch,
+  PchPmStatusMax
+} PCH_PM_STATUS;
+
+/**
+  Query PCH to determine the Pm Status
+
+  @param[in] PmStatus - The Pch Pm Status to be probed
+
+  @retval Status TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+  PCH_PM_STATUS PmStatus
+  );
+
+/**
+  Funtion to check if Battery lost or CMOS cleared.
+
+  @reval TRUE  Battery is always present.
+  @reval FALSE CMOS is cleared.
+**/
+BOOLEAN
+EFIAPI
+PchIsRtcBatteryGood (
+  VOID
+  );
+
+#endif // _PCH_PMC_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
new file mode 100644
index 0000000000..acd7a16e48
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
@@ -0,0 +1,114 @@
+/** @file
+  Prototype of the PeiPchPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_LIB_H_
+#define _PEI_PCH_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole PCH_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi       The RC PREMEM Policy PPI instance
+**/
+VOID
+EFIAPI
+PchPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi               The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+PchPrintPolicyPpi (
+  IN  SI_POLICY_PPI           *SiPolicyPpi
+  );
+
+/**
+  Get PCH PREMEM config block table total size.
+
+  @retval                               Size of PCH PREMEM config block table
+**/
+UINT16
+EFIAPI
+PchGetPreMemConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get PCH config block table total size.
+
+  @retval                               Size of PCH config block table
+**/
+UINT16
+EFIAPI
+PchGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  PchAddPreMemConfigBlocks add all PCH config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  PchAddConfigBlocks add all PCH config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  Get Sata Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     SataConfig          Pointer to Sata Config Policy
+**/
+PCH_SATA_CONFIG *
+GetPchSataConfig (
+  IN SI_POLICY_PPI      *SiPolicy,
+  IN UINT32             SataCtrlIndex
+  );
+
+/**
+  Get Hsio Sata Pre Mem Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Pointer to Hsio Sata Pre Mem Config Policy
+**/
+PCH_HSIO_SATA_PREMEM_CONFIG *
+GetPchHsioSataPreMemConfig (
+  IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy,
+  IN UINT32               SataCtrlIndex
+  );
+
+#endif // _PEI_PCH_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
new file mode 100644
index 0000000000..ca2da4cfc1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
@@ -0,0 +1,24 @@
+/** @file
+  Header file for PCH RESET Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RESET_LIB_H_
+#define _PCH_RESET_LIB_H_
+
+/**
+  Initialize PCH Reset APIs
+
+  @retval EFI_SUCCESS             APIs are installed successfully
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
+**/
+EFI_STATUS
+EFIAPI
+PchInitializeReset (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
new file mode 100644
index 0000000000..779aac2d2a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
@@ -0,0 +1,116 @@
+/** @file
+  Header file for PchSbiAccessLib.
+
+  Copyright (c) 2019 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
+EFIAPI
+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
+EFIAPI
+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/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
new file mode 100644
index 0000000000..4962c67a7c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
@@ -0,0 +1,240 @@
+/** @file
+  Header file for PCH Serial IO Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SERIAL_IO_LIB_H_
+#define _PCH_SERIAL_IO_LIB_H_
+
+typedef enum {
+  PchSerialIoIndexI2C0,
+  PchSerialIoIndexI2C1,
+  PchSerialIoIndexI2C2,
+  PchSerialIoIndexI2C3,
+  PchSerialIoIndexI2C4,
+  PchSerialIoIndexI2C5,
+  PchSerialIoIndexSpi0,
+  PchSerialIoIndexSpi1,
+  PchSerialIoIndexSpi2,
+  PchSerialIoIndexUart0,
+  PchSerialIoIndexUart1,
+  PchSerialIoIndexUart2,
+  PchSerialIoIndexMax
+} PCH_SERIAL_IO_CONTROLLER;
+
+typedef enum {
+  PchSerialIoDisabled,
+  PchSerialIoPci,
+  PchSerialIoAcpi,
+  PchSerialIoHidden
+} PCH_SERIAL_IO_MODE;
+
+typedef enum  {
+  SERIAL_IO_UNKNOWN = 0,
+  SERIAL_IO_I2C,
+  SERIAL_IO_SPI,
+  SERIAL_IO_UART
+} PCH_SERIAL_IO_CONTROLLER_TYPE;
+
+enum PCH_LP_SERIAL_IO_CS_POLARITY {
+  PchSerialIoCsActiveLow = 0,
+  PchSerialIoCsActiveHigh = 1
+};
+enum PCH_LP_SERIAL_IO_HW_FLOW_CTRL {
+  PchSerialIoHwFlowCtrlDisabled = 0,
+  PchSerialIoHwFlowControlEnabled = 1
+};
+
+#define SERIALIO_HID_LENGTH 8 // including null terminator
+#define SERIALIO_UID_LENGTH 1
+#define SERIALIO_CID_LENGTH 1
+#define SERIALIO_TOTAL_ID_LENGTH SERIALIO_HID_LENGTH+SERIALIO_UID_LENGTH+SERIALIO_CID_LENGTH
+
+/**
+  Returns index of the last i2c controller
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            Index of I2C controller
+**/
+PCH_SERIAL_IO_CONTROLLER
+GetMaxI2cNumber (
+  VOID
+  );
+
+/**
+  Returns string with AcpiHID assigned to selected SerialIo controller
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            pointer to 8-byte string
+**/
+CHAR8*
+GetSerialIoAcpiHid (
+  IN PCH_SERIAL_IO_CONTROLLER Number
+  );
+
+/**
+  Checks if given Serial IO Controller Function equals 0
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               TRUE if SerialIO Function is equal to 0
+                                        FALSE if Function is higher then 0
+**/
+BOOLEAN
+IsSerialIoFunctionZero (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  );
+
+/**
+  Checks if Device with given PciDeviceId is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  PciDevId  Device ID
+  @param[out] Number    Number of SerialIo controller
+
+  @retval TRUE          Yes it is a SerialIo controller
+  @retval FALSE         No it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoPciDevId (
+  IN  UINT16                    PciDevId,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  );
+
+/**
+  Checks if Device with given AcpiHID string is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  AcpiHid   String
+  @param[out] Number    Number of SerialIo controller
+
+  @retval TRUE          yes it is a SerialIo controller
+  @retval FALSE         no it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoAcpiHid (
+  IN CHAR8                      *AcpiHid,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  );
+
+/**
+  Configures Serial IO Controller
+
+  @param[in] Controller    Serial IO controller number
+  @param[in] DeviceMode    Device operation mode
+  @param[in] PsfDisable    Disable device at PSF level
+
+  @retval None
+**/
+VOID
+ConfigureSerialIoController (
+  IN PCH_SERIAL_IO_CONTROLLER Controller,
+  IN PCH_SERIAL_IO_MODE       DeviceMode,
+  IN BOOLEAN                  PsfDisable
+  );
+
+/**
+  Returns Serial IO Controller Type I2C, SPI or UART
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            I2C, SPI or UART
+  @retval            UNKNOWN - in case if undefined controller
+**/
+PCH_SERIAL_IO_CONTROLLER_TYPE
+GetSerialIoControllerType (
+  IN PCH_SERIAL_IO_CONTROLLER  Controller
+  );
+
+/**
+  Finds PCI Device Number of SerialIo devices.
+  SerialIo devices' BDF is configurable
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo device number
+**/
+UINT8
+GetSerialIoDeviceNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  );
+
+/**
+  Finds PCI Function Number of SerialIo devices.
+  SerialIo devices' BDF is configurable
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo funciton number
+**/
+UINT8
+GetSerialIoFunctionNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  );
+
+/**
+  Finds BAR values of SerialIo devices.
+  SerialIo devices can be configured to not appear on PCI so traditional method of reading BAR might not work.
+
+  @param[in] SerialIoDevice             Serial IO device
+  @param[in] BarNumber                  0=BAR0, 1=BAR1
+
+  @retval                               SerialIo Bar value
+**/
+UINTN
+FindSerialIoBar (
+  IN PCH_SERIAL_IO_CONTROLLER           SerialIoDevice,
+  IN UINT8                              BarNumber
+  );
+
+/**
+  Checks if given device corresponds to any of LPSS Devices
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval                               TRUE if SerialIO Device/Function Number is equal to any of LPSS devices
+                                        FALSE Device/Function is not in Serial IO scope
+**/
+BOOLEAN
+IsSerialIoDevice (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  );
+
+/**
+  Checks if given Serial IO Controller is enabled or not
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval TRUE                          TRUE if given serial io device is enabled.
+  @retval FALSE                         FALSE if given serial io device is disabled.
+**/
+BOOLEAN
+IsSerialIoDeviceEnabled (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  );
+
+/**
+  Gets Pci Config control offset
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval    CfgCtrAddr                 Offset of Pci config control
+                                        0 if Device and Function do not correspond to Serial IO
+**/
+UINT16
+GetSerialIoConfigControlOffset (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  );
+
+#endif // _PEI_DXE_SMM_PCH_SERIAL_IO_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
new file mode 100644
index 0000000000..f97051e97c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
@@ -0,0 +1,111 @@
+/** @file
+  Header file for PCH Serial IO UART Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SERIAL_IO_UART_LIB_H_
+#define _PCH_SERIAL_IO_UART_LIB_H_
+
+typedef enum {
+  AccessMode8bit,
+  AccessMode32bit
+} UART_ACCESS_MODE;
+
+/**
+  Returns UART's currently active access mode, 8 or 32 bit
+
+  @param[in]  MmioBase    Base address of UART MMIO space
+
+  @retval     AccessMode8bit
+  @retval     AccessMode32bit
+**/
+UART_ACCESS_MODE
+DetectAccessMode (
+  IN UINTN  MmioBase
+  );
+
+/**
+  Initialize selected SerialIo UART.
+
+  @param[in]  UartNumber           Selects Serial IO UART device (0-2)
+  @param[in]  FifoEnable           When TRUE, enables 64-byte FIFOs.
+  @param[in]  BaudRate             Baud rate.
+  @param[in]  LineControl          Data length, parity, stop bits.
+  @param[in]  HardwareFlowControl  Automated hardware flow control. If TRUE, hardware automatically checks CTS when sending data, and sets RTS when receiving data.
+**/
+VOID
+EFIAPI
+PchSerialIoUartInit (
+  IN UINT8   UartNumber,
+  IN BOOLEAN FifoEnable,
+  IN UINT32  BaudRate,
+  IN UINT8   LineControl,
+  IN BOOLEAN HardwareFlowControl
+  );
+
+
+/**
+  Write data to serial device.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param[in]  UartNumber       Selects Serial IO UART device (0-2)
+  @param[in]  Buffer           Point of data buffer which need to be writed.
+  @param[in]  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval                  Actual number of bytes writed to serial device.
+**/
+UINTN
+EFIAPI
+PchSerialIoUartOut (
+  IN UINT8  UartNumber,
+  IN UINT8  *Buffer,
+  IN UINTN  NumberOfBytes
+);
+
+/*
+  Read data from serial device and save the datas in buffer.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param[in]   UartNumber           Selects Serial IO UART device (0-2)
+  @param[out]  Buffer               Point of data buffer which need to be writed.
+  @param[in]   NumberOfBytes        Number of output bytes which are cached in Buffer.
+  @param[in]   WaitUntilBufferFull  When TRUE, function waits until whole buffer is filled. When FALSE, function returns as soon as no new characters are available.
+
+  @retval                      Actual number of bytes raed from serial device.
+
+**/
+UINTN
+EFIAPI
+PchSerialIoUartIn (
+  IN  UINT8     UartNumber,
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes,
+  IN  BOOLEAN   WaitUntilBufferFull
+);
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @param[in]  UartNumber       Selects Serial IO UART device (0-2)
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+PchSerialIoUartPoll (
+  IN  UINT8     UartNumber
+  );
+
+
+#endif // _PEI_DXE_SMM_PCH_SERIAL_IO_UART_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
new file mode 100644
index 0000000000..34b9867c34
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for SMM Control PEI Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SMM_CONTROL_LIB_H_
+#define _PCH_SMM_CONTROL_LIB_H_
+
+/**
+  This function install PEI SMM Control PPI
+
+  @retval EFI_STATUS  Results of the installation of the SMM Control PPI
+**/
+EFI_STATUS
+EFIAPI
+PchSmmControlInit (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
new file mode 100644
index 0000000000..69b9c1cdb7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
@@ -0,0 +1,121 @@
+/** @file
+  Library that contains common parts of WdtPei and WdtDxe. Not a standalone module.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_WDT_COMMON_LIB_H_
+#define _PCH_WDT_COMMON_LIB_H_
+
+extern UINT8    mAllowExpectedReset;
+
+/**
+  Reads LPC bridge to get Watchdog Timer address
+
+
+  @retval UINT32                  Watchdog's address
+**/
+UINT32
+WdtGetAddress (
+  VOID
+  );
+
+/**
+  Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+  causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+  function was called too.
+
+  @param[in] TimeoutValue         Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+  @retval EFI_SUCCESS             if everything's OK
+  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
+**/
+EFI_STATUS
+EFIAPI
+WdtReloadAndStart (
+  IN  UINT32  TimeoutValue
+  );
+
+/**
+  Disables WDT timer.
+
+
+**/
+VOID
+EFIAPI
+WdtDisable (
+  VOID
+  );
+
+/**
+  Returns WDT failure status.
+
+
+  @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE   If there was WDT expiration or unexpected reset
+  @retval V_PCH_OC_WDT_CTL_STATUS_OK        Otherwise
+**/
+UINT8
+EFIAPI
+WdtCheckStatus (
+  VOID
+  );
+
+/**
+  Normally, each reboot performed while watchdog runs is considered a failure.
+  This function allows platform to perform expected reboots with WDT running,
+  without being interpreted as failures.
+  In DXE phase, it is enough to call this function any time before reset.
+  In PEI phase, between calling this function and performing reset, ReloadAndStart()
+  must not be called.
+
+
+**/
+VOID
+EFIAPI
+WdtAllowKnownReset (
+  VOID
+  );
+
+/**
+  Returns information if WDT coverage for the duration of BIOS execution
+  was requested by an OS application
+
+
+  @retval TRUE                    if WDT was requested
+  @retval FALSE                   if WDT was not requested
+**/
+UINT8
+EFIAPI
+IsWdtRequired (
+  VOID
+  );
+
+/**
+  Returns WDT enabled/disabled status.
+
+
+  @retval TRUE                    if WDT is enabled
+  @retval FALSE                   if WDT is disabled
+**/
+UINT8
+EFIAPI
+IsWdtEnabled (
+  VOID
+  );
+
+/**
+  Returns WDT locked status.
+
+
+  @retval TRUE                    if WDT is locked
+  @retval FALSE                   if WDT is unlocked
+**/
+UINT8
+EFIAPI
+IsWdtLocked (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
new file mode 100644
index 0000000000..f1a2600216
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
@@ -0,0 +1,207 @@
+/** @file
+  Header file for PmcLib.
+
+  Copyright (c) 2019 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 {
+  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;
+
+#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 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 RTC 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
+  );
+
+/**
+  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 checks if SMI Lock is set
+
+  @retval SMI Lock state
+**/
+BOOLEAN
+PmcIsSmiLockSet (
+  VOID
+  );
+
+/**
+  Check global SMI enable is set
+
+  @retval TRUE  Global SMI enable is set
+          FALSE Global SMI enable is not set
+**/
+BOOLEAN
+PmcIsGblSmiEn (
+  VOID
+  );
+
+#endif // _PMC_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
new file mode 100644
index 0000000000..047d543009
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
@@ -0,0 +1,76 @@
+/** @file
+  Header file for PchSataLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SATA_LIB_H_
+#define _PCH_SATA_LIB_H_
+
+#define SATA_1_CONTROLLER_INDEX             0
+#define SATA_2_CONTROLLER_INDEX             1
+#define SATA_3_CONTROLLER_INDEX             2
+
+/**
+  Get Pch Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval Pch Maximum Sata Port Number
+**/
+UINT8
+GetPchMaxSataPortNum (
+  IN UINT32     SataCtrlIndex
+  );
+
+/**
+  Gets Maximum Sata Controller Number
+
+  @param[in] None
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+GetPchMaxSataControllerNum (
+  VOID
+  );
+
+/**
+  Gets SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+GetSataPcieDeviceNum (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Gets SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+GetSataPcieFunctionNum (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Gets SATA controller PCIe config space base address
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe config space base address
+**/
+UINT64
+GetSataRegBase (
+  IN UINT32 SataCtrlIndex
+  );
+
+#endif // _PCH_SATA_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
new file mode 100644
index 0000000000..53283597e7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for SEC PCH Lib.
+  All function in this library is available for SEC
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SEC_PCH_LIB_H_
+#define _SEC_PCH_LIB_H_
+
+/**
+  This function do the PCH cycle decoding initialization.
+**/
+VOID
+EFIAPI
+EarlyCycleDecoding (
+  VOID
+  );
+
+#endif // _SEC_PCH_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..53c11bb59a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
@@ -0,0 +1,98 @@
+/** @file
+  The header file includes the common header files, defines
+  internal structure and functions used by SpiFlashCommonLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SPI_FLASH_COMMON_LIB_H__
+#define __SPI_FLASH_COMMON_LIB_H__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define SECTOR_SIZE_4KB   0x1000      // Common 4kBytes sector size
+/**
+  Enable block protection on the Serial Flash device.
+
+  @retval     EFI_SUCCESS       Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+  VOID
+  );
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      Address       The starting physical address of the read.
+  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
+                                of bytes actually read.
+  @param[out]     Buffer        The destination data buffer for the read.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN                        Address,
+  IN OUT UINT32                       *NumBytes,
+     OUT UINT8                        *Buffer
+  );
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      Address         The starting physical address of the write.
+  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
+                                  the actual number of bytes written.
+  @param[in]      Buffer          The source data buffer for the write.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN                      Address,
+  IN OUT UINT32                     *NumBytes,
+  IN     UINT8                      *Buffer
+  );
+
+/**
+  Erase the block starting at Address.
+
+  @param[in]  Address         The starting physical address of the block to be erased.
+                              This library assume that caller garantee that the PAddress
+                              is at the starting address of this block.
+  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
+                              On output, the actual number of bytes erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN    UINTN                     Address,
+  IN    UINTN                     *NumBytes
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
new file mode 100644
index 0000000000..e56f3139d7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for Spi Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SPI_LIB_H_
+#define _SPI_LIB_H_
+
+/**
+  This function Initial SPI services
+
+  @retval EFI_STATUS  Results of the installation of the SPI services
+**/
+EFI_STATUS
+EFIAPI
+SpiServiceInit (
+  VOID
+  );
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol include headers

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

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

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h                        |  42 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h                             |  27 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h                             |  28 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h           | 186 ++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h         | 136 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h              |  68 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h         | 146 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h         | 132 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h                  |  42 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h                   |  42 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h             | 134 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h        |  67 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h |  67 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h          | 152 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h                   |  15 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h                        | 295 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h                        | 113 ++++++++
 17 files changed, 1692 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
new file mode 100644
index 0000000000..840a2355f1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
@@ -0,0 +1,42 @@
+/** @file
+  PCH Reset PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RESET_PPI_H_
+#define _PCH_RESET_PPI_H_
+
+//
+// Member functions
+//
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+
+  @retval EFI_SUCCESS             The callback function has been done successfully
+  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback ppi. Or, none of
+                                  callback ppi is installed.
+  @retval Others                  Do not do any reset from PCH
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET_CALLBACK) (
+  IN  EFI_RESET_TYPE    ResetType,
+  IN  EFI_GUID          *ResetTypeGuid
+  );
+
+/**
+  This ppi is used to execute PCH Reset from the host controller.
+  If drivers need to run their callback function right before issuing the PCH Reset,
+  they can install PCH Reset Callback PPI before PCH Reset PEI driver to achieve that.
+**/
+typedef struct {
+  PCH_RESET_CALLBACK  ResetCallback;
+} PCH_RESET_CALLBACK_PPI;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
new file mode 100644
index 0000000000..d3ff152742
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
@@ -0,0 +1,27 @@
+/** @file
+  This file defines the PCH SPI PPI which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_PPI_H_
+#define _PCH_SPI_PPI_H_
+
+#include <Protocol/Spi.h>
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID           gPchSpiPpiGuid;
+
+/**
+  Reuse the PCH_SPI_PROTOCOL definitions
+  This is possible becaues the PPI implementation does not rely on a PeiService pointer,
+  as it uses EDKII Glue Lib to do IO accesses
+**/
+typedef PCH_SPI_PROTOCOL PCH_SPI_PPI;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
new file mode 100644
index 0000000000..59a9f0f251
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
@@ -0,0 +1,28 @@
+/** @file
+  Watchdog Timer PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_WDT_H_
+#define _PEI_WDT_H_
+
+#include <Protocol/Wdt.h>
+//
+// MRC takes a lot of time to execute in debug mode
+//
+#define WDT_TIMEOUT_BETWEEN_PEI_DXE 60
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID       gWdtPpiGuid;
+
+///
+/// Reuse WDT_PROTOCOL definition
+///
+typedef WDT_PROTOCOL  WDT_PPI;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
new file mode 100644
index 0000000000..4f14065bd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
@@ -0,0 +1,186 @@
+/** @file
+  PCH IO TrapEx Dispatch Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
new file mode 100644
index 0000000000..f3e788a2e1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
@@ -0,0 +1,136 @@
+/** @file
+  APIs of PCH ACPI SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
new file mode 100644
index 0000000000..45fae6e2d5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
@@ -0,0 +1,68 @@
+/** @file
+  PCH eMMC HS400 Tuning Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_EMMC_TUNING_PROTOCOL_H_
+#define _PCH_EMMC_TUNING_PROTOCOL_H_
+
+#define PCH_EMMC_TUNING_PROTOCOL_REVISION 1
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID  gPchEmmcTuningProtocolGuid;
+
+//
+// Forward declaration for PCH_EMMC_TUNING_PROTOCOL
+//
+typedef struct _PCH_EMMC_TUNING_PROTOCOL PCH_EMMC_TUNING_PROTOCOL;
+
+/**
+  This structure decribes the required Emmc info for HS400 tuning
+**/
+typedef struct {
+  EFI_HANDLE                PartitionHandle;    ///< eMMC partition handle for block read/write
+  EFI_LBA                   Lba;                ///< Logical Block Address for HS400 Tuning block read/write
+  UINT32                    RelativeDevAddress; ///< Device system address, dynamically assigned by the host during initialization.
+  UINT8                     HS200BusWidth;      ///< The value to be programmed for BUS_WIDTH[183] byte
+} EMMC_INFO;
+
+///
+/// This structure describes the return value after HS400 tuning
+///
+typedef struct {
+  UINT8       Hs400DataValid;     ///< Set if Hs400 Tuning Data is valid after tuning
+  UINT8       Hs400RxStrobe1Dll;  ///< Rx Strobe Delay Control - Rx Strobe Delay DLL 1 (HS400 Mode)
+  UINT8       Hs400TxDataDll;     ///< Tx Data Delay Control 1 - Tx Data Delay (HS400 Mode)
+} EMMC_TUNING_DATA;
+
+///
+/// EMMC HS400 TUNING INTERFACE
+///
+typedef EFI_STATUS (EFIAPI *EMMC_TUNE) (
+  IN   PCH_EMMC_TUNING_PROTOCOL         *This,              ///< This pointer to PCH_EMMC_TUNING_PROTOCOL
+  /**
+    Revision parameter is used to verify the layout of EMMC_INFO and TUNINGDATA.
+    If the revision is not matched, means the revision of EMMC_INFO and TUNINGDATA is not matched.
+    And function will return immediately.
+  **/
+  IN   UINT8                            Revision,
+  IN   EMMC_INFO                        *EmmcInfo,          ///< Pointer to EMMC_INFO
+  OUT  EMMC_TUNING_DATA                 *EmmcTuningData     ///< Pointer to EMMC_TUNING_DATA
+);
+
+/**
+  PCH EMMC TUNING PROTOCOL INTERFACE
+  Platform code uses this protocol to configure Emmc Hs400 mode, by passing the EMMC_INFO information.
+  PCH will setting EMMC controller based on EMMC_INFO and return EMMC_TUNING_DATA to platform code.
+  Platform should keep values of EMMC_TUNING_DATA and uses to configure EMMC through policies, to
+  prevent from doing EMMC tuning every boot.
+**/
+struct _PCH_EMMC_TUNING_PROTOCOL {
+  EMMC_TUNE  EmmcTune;  ///< Emmc Hs400 Tuning Interface
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
new file mode 100644
index 0000000000..9a180b4285
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
@@ -0,0 +1,146 @@
+/** @file
+  SmmEspiDispatch Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
new file mode 100644
index 0000000000..c5e8bc3f28
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
@@ -0,0 +1,132 @@
+/** @file
+  APIs of PCH PCIE SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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;
+
+//
+// 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 to PCH PCIE Root Port 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
new file mode 100644
index 0000000000..ff35b43b61
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
@@ -0,0 +1,42 @@
+/** @file
+  Interface definition details between Pch and platform drivers during DXE phase.
+
+  Copyright (c) 2019 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 <Private/PchConfigHob.h>
+#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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
new file mode 100644
index 0000000000..4c49d082fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
@@ -0,0 +1,42 @@
+/** @file
+  PCH Reset Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RESET_PROTOCOL_H_
+#define _PCH_RESET_PROTOCOL_H_
+
+//
+// Member functions
+//
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+
+  @retval EFI_SUCCESS             The callback function has been done successfully
+  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback protocol. Or, none of
+                                  callback protocol is installed.
+  @retval Others                  Do not do any reset from PCH
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET_CALLBACK) (
+  IN  EFI_RESET_TYPE    ResetType,
+  IN  EFI_GUID          *ResetTypeGuid
+  );
+
+/**
+  This protocol is used to execute PCH Reset from the host controller.
+  If drivers need to run their callback function right before issuing the PCH Reset,
+  they can install PCH Reset Callback Protocol before PCH Reset DXE driver to achieve that.
+**/
+typedef struct {
+  PCH_RESET_CALLBACK  ResetCallback;
+} PCH_RESET_CALLBACK_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
new file mode 100644
index 0000000000..6fdfed1de7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
@@ -0,0 +1,134 @@
+/** @file
+  APIs of PCH SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
new file mode 100644
index 0000000000..73386a570e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
@@ -0,0 +1,67 @@
+/** @file
+  PCH SMM IO Trap Control Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
new file mode 100644
index 0000000000..06ddc3e1cd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
@@ -0,0 +1,67 @@
+/** @file
+  PCH SMM Periodic Timer Control Protocol
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
new file mode 100644
index 0000000000..d397712092
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
@@ -0,0 +1,152 @@
+/** @file
+  APIs of PCH TCO SMI Dispatch Protocol.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
new file mode 100644
index 0000000000..ece65cd729
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
@@ -0,0 +1,15 @@
+/** @file
+  SmmSmbus Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __EFI_SMM_SMBUS_PROTOCOL_H__
+#define __EFI_SMM_SMBUS_PROTOCOL_H__
+
+extern EFI_GUID               gEfiSmmSmbusProtocolGuid;
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..22df7fe351
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
@@ -0,0 +1,295 @@
+/** @file
+  This file defines the PCH SPI Protocol which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 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,
+  FlashRegionEC = 8,
+  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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
new file mode 100644
index 0000000000..67554e526f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
@@ -0,0 +1,113 @@
+/** @file
+  Watchdog Timer protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_WDT_H_
+#define _DXE_WDT_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID               gWdtProtocolGuid;
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _WDT_PROTOCOL  WDT_PROTOCOL;
+
+/**
+  Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+  causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+  function was called too.
+
+  @param[in] TimeoutValue         Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+  @retval EFI_SUCCESS             if everything's OK
+  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WDT_RELOAD_AND_START) (
+  UINT32 TimeoutValue
+  );
+
+/**
+  Returns WDT failure status.
+
+  @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE   If there was WDT expiration or unexpected reset
+  @retval V_PCH_OC_WDT_CTL_STATUS_OK        Otherwise
+**/
+typedef
+UINT8
+(EFIAPI *WDT_CHECK_STATUS) (
+  VOID
+  );
+
+/**
+  Returns information if WDT coverage for the duration of BIOS execution
+  was requested by an OS application.
+
+  @retval TRUE                    if WDT was requested
+  @retval FALSE                   if WDT was not requested
+**/
+typedef
+UINT8
+(EFIAPI *IS_WDT_REQUIRED) (
+  VOID
+  );
+
+/**
+  Returns WDT enabled/disabled status.
+
+  @retval TRUE                    if WDT is enabled
+  @retval FALSE                   if WDT is disabled
+**/
+typedef
+UINT8
+(EFIAPI *IS_WDT_ENABLED) (
+  VOID
+  );
+
+/**
+  Disables WDT timer.
+**/
+typedef
+VOID
+(EFIAPI *WDT_DISABLE) (
+  VOID
+  );
+
+/**
+  Normally, each reboot performed while watchdog runs is considered a failure.
+  This function allows platform to perform expected reboots with WDT running,
+  without being interpreted as failures.
+  In DXE phase, it is enough to call this function any time before reset.
+  In PEI phase, between calling this function and performing reset, ReloadAndStart()
+  must not be called.
+**/
+typedef
+VOID
+(EFIAPI *WDT_ALLOW_KNOWN_RESET) (
+  VOID
+  );
+
+/**
+  These protocols and PPI allow a platform module to perform watch dog timer operations
+  through the Intel PCH LPC Host Controller Interface. The WDT protocol and WDT PPI
+  implement the Intel (R) Watch Dog timer for DXE, and PEI environments, respectively.
+  WDT_PROTOCOL referenced hereafter represents both WDT_PROTOCOL and WDT_PPI, as they
+  share the identical data structure.
+**/
+struct _WDT_PROTOCOL {
+  WDT_RELOAD_AND_START  ReloadAndStart;   ///< Reloads WDT with new timeout value and starts it.
+  WDT_CHECK_STATUS      CheckStatus;      ///< Returns WDT failure status.
+  WDT_DISABLE           Disable;          ///< Disables WDT timer.
+  WDT_ALLOW_KNOWN_RESET AllowKnownReset;  ///< Perform expected reboots with WDT running, without being interpreted as failures.
+  IS_WDT_REQUIRED       IsWdtRequired;    ///< Returns information if WDT coverage for the duration of BIOS execution was requested by an OS application.
+  IS_WDT_ENABLED        IsWdtEnabled;     ///< Returns WDT enabled/disabled status.
+};
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register include headers

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

Adds the following header files:
 * Pch/Include/Register

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h            |  54 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h         |  57 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h         | 122 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h       |  54 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h       |  62 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h         |  90 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h        | 273 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h     | 694 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h         | 204 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h        | 170 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h         |  79 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h        | 103 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h         |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h         | 360 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h      |  61 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h        | 116 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h        | 484 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h         |  73 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h         | 670 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h      |  72 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h         | 104 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h      | 113 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h        |  77 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h        | 668 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h         |  52 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h      |  48 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h    | 232 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h | 138 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h       | 151 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h         | 295 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h  |  49 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h    | 134 ++++
 32 files changed, 5917 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
new file mode 100644
index 0000000000..10fcb316fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
@@ -0,0 +1,54 @@
+/** @file
+  Generic register definitions for 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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
+
+//
+// Default Vendor ID and Subsystem ID
+//
+#define V_PCH_INTEL_VENDOR_ID   0x8086      ///< Default Intel PCH Vendor ID
+#define V_PCH_DEFAULT_SID       0x7270      ///< Default Intel PCH Subsystem ID
+#define V_PCH_DEFAULT_SVID_SID  (V_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID << 16))   ///< Default INTEL PCH Vendor ID and Subsystem ID
+
+#endif //_PCH_REGS_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
new file mode 100644
index 0000000000..47dd73215e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
@@ -0,0 +1,57 @@
+/** @file
+  Register names for PCH DCI 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DCI_H_
+#define _PCH_REGS_DCI_H_
+
+//
+// DCI PCR Registers
+//
+
+#define R_DCI_PCR_ECTRL                       0x04            ///< DCI Control Register
+
+#define B_DCI_PCR_ECTRL_HDCIEN_LOCK           BIT0            ///< Host DCI Enable Lock
+#define B_DCI_PCR_ECTRL_HDCIEN                BIT4            ///< Host DCI Enable
+
+#define R_DCI_PCR_ECKPWRCTL                   0x08            ///< DCI Power Control
+// CNP-A0 (DCI Gen2) and backwards
+#define R_DCI_PCR_PCE                         0x30            ///< DCI Power Control Enable Register
+#define B_DCI_PCR_PCE_HAE                     BIT5            ///< Hardware Autonomous Enable
+#define B_DCI_PCR_PCE_D3HE                    BIT2            ///< D3-Hot Enable
+#define B_DCI_PCR_PCE_I3E                     BIT1            ///< I3 Enable
+#define B_DCI_PCR_PCE_PMCRE                   BIT0            ///< PMC Request Enable
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
new file mode 100644
index 0000000000..44f708dd92
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
@@ -0,0 +1,122 @@
+/** @file
+  Register names for DMI and OP-DMI
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DMI_H_
+#define _PCH_REGS_DMI_H_
+
+//
+// DMI Chipset Configuration Registers (PID:DMI)
+//
+
+//
+// VC Configuration (Common)
+//
+#define B_PCH_DMI_PCR_V0CTL_EN               BIT31
+#define B_PCH_DMI_PCR_V0CTL_ID               (7 << 24)                   ///< Bit[26:24]
+#define N_PCH_DMI_PCR_V0CTL_ID               24
+#define V_PCH_DMI_PCR_V0CTL_ETVM_MASK        0xFC00
+#define V_PCH_DMI_PCR_V0CTL_TVM_MASK         0x7E
+#define B_PCH_DMI_PCR_V0STS_NP               BIT1
+#define B_PCH_DMI_PCR_V1CTL_EN               BIT31
+#define B_PCH_DMI_PCR_V1CTL_ID               (0x0F << 24)                ///< Bit[27:24]
+#define N_PCH_DMI_PCR_V1CTL_ID               24
+#define V_PCH_DMI_PCR_V1CTL_ETVM_MASK        0xFC00
+#define V_PCH_DMI_PCR_V1CTL_TVM_MASK         0xFE
+#define B_PCH_DMI_PCR_V1STS_NP               BIT1
+
+
+//
+// DMI Source Decode PCRs (Common)
+//
+#define R_PCH_DMI_PCR_PCIEPAR1E         0x2700                ///< PCIE Port IOxAPIC Range 1 Enable
+#define R_PCH_DMI_PCR_PCIEPAR2E         0x2704                ///< PCIE Port IOxAPIC Range 2 Enable
+#define R_PCH_DMI_PCR_PCIEPAR3E         0x2708                ///< PCIE Port IOxAPIC Range 3 Enable
+#define R_PCH_DMI_PCR_PCIEPAR4E         0x270C                ///< PCIE Port IOxAPIC Range 4 Enable
+#define R_PCH_DMI_PCR_PCIEPAR1DID       0x2710                ///< PCIE Port IOxAPIC Range 1 Destination ID
+#define R_PCH_DMI_PCR_PCIEPAR2DID       0x2714                ///< PCIE Port IOxAPIC Range 2 Destination ID
+#define R_PCH_DMI_PCR_PCIEPAR3DID       0x2718                ///< PCIE Port IOxAPIC Range 3 Destination ID
+#define R_PCH_DMI_PCR_PCIEPAR4DID       0x271C                ///< PCIE Port IOxAPIC Range 4 Destination ID
+#define R_PCH_DMI_PCR_P2SBIOR           0x2720                ///< P2SB IO Range
+#define R_PCH_DMI_PCR_TTTBARB           0x2724                ///< Thermal Throttling BIOS Assigned Thermal Base Address
+#define R_PCH_DMI_PCR_TTTBARBH          0x2728                ///< Thermal Throttling BIOS Assigned Thermal Base High Address
+#define R_PCH_DMI_PCR_LPCLGIR1          0x2730                ///< LPC Generic I/O Range 1
+#define R_PCH_DMI_PCR_LPCLGIR2          0x2734                ///< LPC Generic I/O Range 2
+#define R_PCH_DMI_PCR_LPCLGIR3          0x2738                ///< LPC Generic I/O Range 3
+#define R_PCH_DMI_PCR_LPCLGIR4          0x273C                ///< LPC Generic I/O Range 4
+#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_RPRDID            0xFFFF0000            ///< RPR Destination ID
+#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_IOT2              0x2758                ///< I/O Trap Register 2
+#define R_PCH_DMI_PCR_IOT3              0x2760                ///< I/O Trap Register 3
+#define R_PCH_DMI_PCR_IOT4              0x2768                ///< I/O Trap Register 4
+#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
+#define R_PCH_DMI_PCR_GPMR2             0x2784                ///< General Purpose Memory Range 2
+#define R_PCH_DMI_PCR_GPMR2DID          0x2788                ///< General Purpose Memory Range 2 Destination ID
+#define R_PCH_DMI_PCR_GPMR3             0x278C                ///< General Purpose Memory Range 3
+#define R_PCH_DMI_PCR_GPMR3DID          0x2790                ///< General Purpose Memory Range 3 Destination ID
+#define R_PCH_DMI_PCR_GPIOR1            0x2794                ///< General Purpose I/O Range 1
+#define R_PCH_DMI_PCR_GPIOR1DID         0x2798                ///< General Purpose I/O Range 1 Destination ID
+#define R_PCH_DMI_PCR_GPIOR2            0x279C                ///< General Purpose I/O Range 2
+#define R_PCH_DMI_PCR_GPIOR2DID         0x27A0                ///< General Purpose I/O Range 2 Destination ID
+#define R_PCH_DMI_PCR_GPIOR3            0x27A4                ///< General Purpose I/O Range 3
+#define R_PCH_DMI_PCR_GPIOR3DID         0x27A8                ///< General Purpose I/O Range 3 Destination ID
+
+//
+// Opi PHY registers
+//
+#define R_PCH_OPIPHY_PCR_0110           0x0110
+#define R_PCH_OPIPHY_PCR_0118           0x0118
+#define R_PCH_OPIPHY_PCR_011C           0x011C
+#define R_PCH_OPIPHY_PCR_0354           0x0354
+#define R_PCH_OPIPHY_PCR_B104           0xB104
+#define R_PCH_OPIPHY_PCR_B10C           0xB10C
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
new file mode 100644
index 0000000000..36c0054d63
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
@@ -0,0 +1,54 @@
+/** @file
+  Register names for DMI SIP14
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DMI14_H_
+#define _PCH_REGS_DMI14_H_
+
+//
+// DMI Chipset Configuration Registers (PID:DMI)
+//
+
+//
+// DMI Control
+//
+#define R_PCH_DMI14_PCR_DMIC                   0x2234                              ///< DMI Control
+#define B_PCH_DMI14_PCR_DMIC_SRL               BIT31                               ///< Secured register lock
+#define B_PCH_DMI14_PCR_DMIC_DMICGEN           (BIT4 | BIT3 | BIT2 | BIT1 | BIT0)  ///< DMI Clock Gate Enable
+
+#define R_PCH_DMI14_PCR_2314                   0x2314
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
new file mode 100644
index 0000000000..c885fdd34d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
@@ -0,0 +1,62 @@
+/** @file
+  Register names for DMI and OP-DMI
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_DMI15_H_
+#define _PCH_REGS_DMI15_H_
+
+#define R_PCH_DMI15_PCR_MPC                 0x20D8                       ///< Miscellaneous Port Configuration
+#define B_PCH_DMI15_PCR_MPC_SRL             BIT23                        ///< Secured register lock
+#define R_PCH_DMI15_PCR_V0CTL               0x2284                       ///< Virtual channel 0 resource control
+#define R_PCH_DMI15_PCR_V0STS               0x228A                       ///< Virtual channel 0 status
+
+#define R_PCH_DMI15_PCR_V1CTL               0x2290                       ///< Virtual channel 1 resource control
+#define R_PCH_DMI15_PCR_V1STS               0x2296                       ///< Virtual channel 1 status
+
+#define R_PCH_DMI15_PCR_VMCTL               0x22B0                       ///< ME Virtual Channel (VCm) resource control
+
+#define R_PCH_DMI15_PCR_UPHWAWC             0x249C                       ///< Upstream Port HW Autonomous Width Control
+#define B_PCH_DMI15_PCR_UPHWAWC_TS3TW       (BIT15 | BIT14 | BIT13)      ///< Thermal Sensor 3 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS3TW       13                           ///< Thermal Sensor 3 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TS2TW       (BIT12 | BIT11 | BIT10)      ///< Thermal Sensor 2 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS2TW       10                           ///< Thermal Sensor 2 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TS1TW       (BIT9 | BIT8 | BIT7)         ///< Thermal Sensor 1 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS1TW       7                            ///< Thermal Sensor 1 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TS0TW       (BIT6 | BIT5 | BIT4)         ///< Thermal Sensor 0 Target Width
+#define N_PCH_DMI15_PCR_UPHWAWC_TS0TW       4                            ///< Thermal Sensor 0 Target Width
+#define B_PCH_DMI15_PCR_UPHWAWC_TSAWEN      BIT0                         ///< Thermal Sensor Autonomous Width Enable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
new file mode 100644
index 0000000000..837fdc5609
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
@@ -0,0 +1,90 @@
+/** @file
+  Register definition for FIA 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_FIA_H_
+#define _PCH_REGS_FIA_H_
+
+
+//
+// Private chipset register (Memory space) offset definition
+// The PCR register defines is used for PCR MMIO programming and PCH SBI programming as well.
+//
+
+//
+// PCH FIA lane owner encoding
+//
+#define V_PCH_FIA_PCR_LANE_OWN_PCIEDMI                    0x0
+#define V_PCH_FIA_PCR_LANE_OWN_USB3                       0x1
+#define V_PCH_FIA_PCR_LANE_OWN_SATA                       0x2
+#define V_PCH_FIA_PCR_LANE_OWN_GBE                        0x3
+#define V_PCH_FIA_PCR_LANE_OWN_MOBEXP                     0x4
+#define V_PCH_FIA_PCR_LANE_OWN_SSIC                       0x5
+#define V_PCH_FIA_PCR_LANE_OWN_CSI3                       0x6
+#define V_PCH_FIA_PCR_LANE_OWN_UFS                        0x7
+
+#define B_PCH_FIA_PCR_L0O                                 (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L1O                                 (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L2O                                 (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L3O                                 (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L4O                                 (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L5O                                 (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_FIA_PCR_L6O                                 (BIT27 | BIT26 | BIT25 | BIT24)
+#define B_PCH_FIA_PCR_L7O                                 (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_FIA_PCR_L8O                                 (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L9O                                 (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L10O                                (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L11O                                (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L12O                                (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L13O                                (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_FIA_PCR_L14O                                (BIT27 | BIT26 | BIT25 | BIT24)
+#define B_PCH_FIA_PCR_L15O                                (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_FIA_PCR_L16O                                (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L17O                                (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L18O                                (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L19O                                (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L20O                                (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L21O                                (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_FIA_PCR_L22O                                (BIT27 | BIT26 | BIT25 | BIT24)
+#define B_PCH_FIA_PCR_L23O                                (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_FIA_PCR_L24O                                (BIT3 | BIT2 | BIT1 | BIT0)
+#define B_PCH_FIA_PCR_L25O                                (BIT7 | BIT6 | BIT5 | BIT4)
+#define B_PCH_FIA_PCR_L26O                                (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_FIA_PCR_L27O                                (BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_FIA_PCR_L28O                                (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_FIA_PCR_L29O                                (BIT23 | BIT22 | BIT21 | BIT20)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
new file mode 100644
index 0000000000..3f614ba002
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
@@ -0,0 +1,273 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_GPIO_H_
+#define _PCH_REGS_GPIO_H_
+
+//
+// GPIO Common Private Configuration Registers
+//
+#define R_GPIO_PCR_REV_ID               0x00
+#define R_GPIO_PCR_CAP_LIST             0x04
+#define R_GPIO_PCR_FAMBAR               0x08
+#define R_GPIO_PCR_PADBAR               0x0C
+#define B_GPIO_PCR_PADBAR               0x0000FFFF
+#define R_GPIO_PCR_MISCCFG              0x10
+#define B_GPIO_PCR_MISCCFG_IRQ_ROUTE    0xFF000000
+#define N_GPIO_PCR_MISCCFG_IRQ_ROUTE    24
+#define B_GPIO_PCR_MISCCFG_GPE0_DW2     (BIT19 | BIT18 | BIT17 | BIT16)
+#define N_GPIO_PCR_MISCCFG_GPE0_DW2     16
+#define B_GPIO_PCR_MISCCFG_GPE0_DW1     (BIT15 | BIT14 | BIT13 | BIT12)
+#define N_GPIO_PCR_MISCCFG_GPE0_DW1     12
+#define B_GPIO_PCR_MISCCFG_GPE0_DW0     (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_GPIO_PCR_MISCCFG_GPE0_DW0     8
+#define B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN    BIT5
+#define B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN  BIT4
+#define B_GPIO_PCR_MISCCFG_GPRTCDLCGEN     BIT3
+#define B_GPIO_PCR_MISCCFG_GPDPCGEN     BIT1
+#define B_GPIO_PCR_MISCCFG_GPDLCGEN     BIT0
+
+//
+// GPIO SerialBlink/PWM registers
+//
+#define R_GPIO_PCR_CAP_LIST_1_PWM         0x0200
+#define R_GPIO_PCR_PWMC                   0x0204
+#define R_GPIO_PCR_CAP_LIST_2_SER_BLINK   0x0208
+#define R_GPIO_PCR_GP_SER_BLINK           0x020C
+#define B_GPIO_PCR_GP_SER_BLINK           0x1F
+#define R_GPIO_PCR_GP_SER_CMDSTS          0x0210
+#define B_GPIO_PCR_GP_SER_CMDSTS_DLS      (BIT23 | BIT22)
+#define N_GPIO_PCR_GP_SER_CMDSTS_DLS      22
+#define B_GPIO_PCR_GP_SER_CMDSTS_DRS      0x003F0000
+#define N_GPIO_PCR_GP_SER_CMDSTS_DRS      16
+#define B_GPIO_PCR_GP_SER_CMDSTS_BUSY     BIT8
+#define B_GPIO_PCR_GP_SER_CMDSTS_GO       BIT0
+#define R_GPIO_PCR_GP_SER_DATA            0x0210
+
+//
+// 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 Pad State Select
+#define B_GPIO_PCR_RX_PAD_STATE         BIT29
+#define N_GPIO_PCR_RX_PAD_STATE         29
+#define V_GPIO_PCR_RX_PAD_STATE_RAW     0x00
+#define V_GPIO_PCR_RX_PAD_STATE_INT     0x01
+
+//RX Raw Overrride to 1
+#define B_GPIO_PCR_RX_RAW1              BIT28
+#define N_GPIO_PCR_RX_RAW1              28
+#define V_GPIO_PCR_RX_RAW1_DIS          0x00
+#define V_GPIO_PCR_RX_RAW1_EN           0x01
+
+//RX Level/Edge Configuration
+#define B_GPIO_PCR_RX_LVL_EDG           (BIT26 | BIT25)
+#define N_GPIO_PCR_RX_LVL_EDG           25
+#define V_GPIO_PCR_RX_LVL_EDG_LVL       0x00
+#define V_GPIO_PCR_RX_LVL_EDG_EDG       0x01
+#define V_GPIO_PCR_RX_LVL_EDG_0         0x02
+#define V_GPIO_PCR_RX_LVL_EDG_RIS_FAL   0x03
+
+//RX Invert
+#define B_GPIO_PCR_RXINV                BIT23
+#define N_GPIO_PCR_RXINV                23
+#define V_GPIO_PCR_RXINV_NO             0x00
+#define V_GPIO_PCR_RXINV_YES            0x01
+
+//GPIO Input Route IOxAPIC
+#define B_GPIO_PCR_RX_APIC_ROUTE        BIT20
+#define N_GPIO_PCR_RX_APIC_ROUTE        20
+#define V_GPIO_PCR_RX_APIC_ROUTE_DIS    0x00
+#define V_GPIO_PCR_RX_APIC_ROUTE_EN     0x01
+
+//GPIO Input Route SCI
+#define B_GPIO_PCR_RX_SCI_ROUTE         BIT19
+#define N_GPIO_PCR_RX_SCI_ROUTE         19
+#define V_GPIO_PCR_RX_SCI_ROUTE_DIS     0x00
+#define V_GPIO_PCR_RX_SCI_ROUTE_EN      0x01
+
+//GPIO Input Route SMI
+#define B_GPIO_PCR_RX_SMI_ROUTE         BIT18
+#define N_GPIO_PCR_RX_SMI_ROUTE         18
+#define V_GPIO_PCR_RX_SMI_ROUTE_DIS     0x00
+#define V_GPIO_PCR_RX_SMI_ROUTE_EN      0x01
+
+//GPIO Input Route NMI
+#define B_GPIO_PCR_RX_NMI_ROUTE         BIT17
+#define N_GPIO_PCR_RX_NMI_ROUTE         17
+#define V_GPIO_PCR_RX_NMI_ROUTE_DIS     0x00
+#define V_GPIO_PCR_RX_NMI_ROUTE_EN      0x01
+
+//GPIO Pad Mode
+#define B_GPIO_PCR_PAD_MODE             (BIT12 | BIT11 | BIT10)
+#define N_GPIO_PCR_PAD_MODE             10
+#define V_GPIO_PCR_PAD_MODE_GPIO        0
+#define V_GPIO_PCR_PAD_MODE_NAT_1       1
+#define V_GPIO_PCR_PAD_MODE_NAT_2       2
+#define V_GPIO_PCR_PAD_MODE_NAT_3       3
+#define V_GPIO_PCR_PAD_MODE_NAT_4       4 // SPT-H only
+
+//GPIO RX Disable
+#define B_GPIO_PCR_RXDIS                BIT9
+#define N_GPIO_PCR_RXDIS                9
+#define V_GPIO_PCR_RXDIS_EN             0x00
+#define V_GPIO_PCR_RXDIS_DIS            0x01
+
+//GPIO TX Disable
+#define B_GPIO_PCR_TXDIS                BIT8
+#define N_GPIO_PCR_TXDIS                8
+#define V_GPIO_PCR_TXDIS_EN             0x00
+#define V_GPIO_PCR_TXDIS_DIS            0x01
+
+//GPIO RX State
+#define B_GPIO_PCR_RX_STATE             BIT1
+#define N_GPIO_PCR_RX_STATE             1
+#define V_GPIO_PCR_RX_STATE_LOW         0x00
+#define V_GPIO_PCR_RX_STATE_HIGH        0x01
+
+//GPIO TX State
+#define B_GPIO_PCR_TX_STATE             BIT0
+#define N_GPIO_PCR_TX_STATE             0
+#define V_GPIO_PCR_TX_STATE_LOW         0x00
+#define V_GPIO_PCR_TX_STATE_HIGH        0x01
+
+//
+// Pad Configuration Register DW1
+//
+
+//Padtol
+#define B_GPIO_PCR_PADTOL               BIT25
+#define N_GPIO_PCR_PADTOL               25
+#define V_GPIO_PCR_PADTOL_NONE          0x00
+#define V_GPIO_PCR_PADTOL_CLEAR         0x00
+#define V_GPIO_PCR_PADTOL_SET           0x01
+
+//Termination
+#define B_GPIO_PCR_TERM                (BIT13 | BIT12 | BIT11 | BIT10)
+#define N_GPIO_PCR_TERM                 10
+#define V_GPIO_PCR_TERM_WPD_NONE        0x00
+#define V_GPIO_PCR_TERM_WPD_5K          0x02
+#define V_GPIO_PCR_TERM_WPD_20K         0x04
+#define V_GPIO_PCR_TERM_WPU_NONE        0x08
+#define V_GPIO_PCR_TERM_WPU_1K          0x09
+#define V_GPIO_PCR_TERM_WPU_2K          0x0B
+#define V_GPIO_PCR_TERM_WPU_5K          0x0A
+#define V_GPIO_PCR_TERM_WPU_20K         0x0C
+#define V_GPIO_PCR_TERM_WPU_1K_2K       0x0D
+#define V_GPIO_PCR_TERM_NATIVE          0x0F
+
+//Interrupt number
+#define B_GPIO_PCR_INTSEL               0x7F
+#define N_GPIO_PCR_INTSEL               0
+
+//
+//Debounce
+#define B_GPIO_PCR_DEBOUNCE             (BIT4 | BIT3 | BIT2 | BIT1)
+#define N_GPIO_PCR_DEBOUNCE              1
+
+//Debounce Enable
+#define B_GPIO_PCR_DEBEN                 BIT0
+#define N_GPIO_PCR_DEBEN                 0
+
+//
+// Ownership
+//
+#define V_GPIO_PCR_OWN_GPIO             0x01
+#define V_GPIO_PCR_OWN_ACPI             0x00
+
+//
+// GPE
+//
+#define V_GPIO_PCR_GPE_EN               0x01
+#define V_GPIO_PCR_GPE_DIS              0x00
+//
+// SMI
+//
+#define V_GPIO_PCR_SMI_EN               0x01
+#define V_GPIO_PCR_SMI_DIS              0x00
+//
+// NMI
+//
+#define V_GPIO_PCR_NMI_EN               0x01
+#define V_GPIO_PCR_NMI_DIS              0x00
+
+//
+// GPIO native features pins data
+//
+#define PCH_GPIO_HDA_LINK_NUMBER_OF_PINS     6
+#define PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS     2
+#define PCH_GPIO_HDA_SSP_NUMBER_OF_PINS      4
+#define PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS     2
+#define PCH_GPIO_SMBUS_NUMBER_OF_PINS        2
+#define PCH_GPIO_CPU_GP_NUMBER_OF_PINS       4
+#define PCH_GPIO_EDP_NUMBER_OF_PINS          4
+#define PCH_GPIO_DDSP_HPD_NUMBER_OF_PINS     4
+#define PCH_GPIO_DDP_NUMBER_OF_INTERFACES    4
+#define PCH_GPIO_DDP_NUMBER_OF_PINS          2
+#define PCH_GPIO_CNVI_UART_NUMBER_OF_PINS    4
+#define PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS     4
+#define PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS 4
+
+
+///
+/// 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_EN                4
+#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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
new file mode 100644
index 0000000000..140c758730
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
@@ -0,0 +1,694 @@
+/** @file
+  Register names for 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_GPIO_CNL_H_
+#define _PCH_REGS_GPIO_CNL_H_
+
+//
+// PCH-LP GPIO
+//
+#define CNL_PCH_LP_GPIO_GROUP_MAX             15
+
+#define CNL_PCH_LP_GPIO_GPP_A_PAD_MAX         25
+#define CNL_PCH_LP_GPIO_GPP_B_PAD_MAX         26
+#define CNL_PCH_LP_GPIO_GPP_C_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_D_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_E_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_F_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPP_G_PAD_MAX         8
+#define CNL_PCH_LP_GPIO_GPP_H_PAD_MAX         24
+#define CNL_PCH_LP_GPIO_GPD_PAD_MAX           16
+#define CNL_PCH_LP_GPIO_VGPIO_PAD_MAX         40
+#define CNL_PCH_LP_GPIO_SPI_PAD_MAX           9
+#define CNL_PCH_LP_GPIO_AZA_PAD_MAX           8
+#define CNL_PCH_LP_GPIO_CPU_PAD_MAX           11
+#define CNL_PCH_LP_GPIO_JTAG_PAD_MAX          9
+#define CNL_PCH_LP_GPIO_HVMOS_PAD_MAX         6
+
+//
+// PCH-H GPIO
+//
+#define CNL_PCH_H_GPIO_GROUP_MAX              17
+
+#define CNL_PCH_H_GPIO_GPP_A_PAD_MAX          25
+#define CNL_PCH_H_GPIO_GPP_B_PAD_MAX          26
+#define CNL_PCH_H_GPIO_GPP_C_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_D_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_E_PAD_MAX          13
+#define CNL_PCH_H_GPIO_GPP_F_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_G_PAD_MAX          8
+#define CNL_PCH_H_GPIO_GPP_H_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPP_I_PAD_MAX          18
+#define CNL_PCH_H_GPIO_GPP_J_PAD_MAX          12
+#define CNL_PCH_H_GPIO_GPP_K_PAD_MAX          24
+#define CNL_PCH_H_GPIO_GPD_PAD_MAX            16
+#define CNL_PCH_H_GPIO_VGPIO_PAD_MAX          40
+#define CNL_PCH_H_GPIO_SPI_PAD_MAX            9
+#define CNL_PCH_H_GPIO_AZA_PAD_MAX            8
+#define CNL_PCH_H_GPIO_CPU_PAD_MAX            11
+#define CNL_PCH_H_GPIO_JTAG_PAD_MAX           9
+
+//
+// PCH-LP GPIO registers
+//
+//
+// GPIO Community Common Private Configuration Registers
+//
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A     0x0
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B     0x1
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C     0xC
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D     0x4
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E     0xD
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F     0x5
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G     0x2
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H     0x6
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD       0x9
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO     0x7
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI       0x3
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA       0xA
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_CPU       0xB
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG      0xE
+#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_HVMOS     0xF
+
+//
+// GPIO Community 0 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN        0x20
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN        0x30
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN        0x40
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN          0x44
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK     0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX   0x84
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK     0x88
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX   0x8C
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK     0x90
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX   0x94
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK       0x98
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX     0x9C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN     0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN     0xB4
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN     0xB8
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN       0xBC
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS         0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS         0x0104
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS         0x0108
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS           0x010C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE         0x0120
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE         0x0124
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE         0x0128
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE           0x012C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS    0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS    0x0144
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS    0x0148
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS      0x014C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN     0x0160
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN     0x0164
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN     0x0168
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN       0x016C
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_SMI_STS        0x0180  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS        0x0184
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_SMI_STS        0x0188  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_SMI_STS          0x018C  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_SMI_EN         0x01A0  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN         0x01A4
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_SMI_EN         0x01A8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_SMI_EN           0x01AC  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_NMI_STS        0x01C0  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS        0x01C4
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_NMI_STS        0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_NMI_STS          0x01CC  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_NMI_EN         0x01E0  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN         0x01E4
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_NMI_EN         0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_SPI_NMI_EN           0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET  0x600
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET  0x790
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET  0x930
+#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET    0x9B0
+
+//
+// GPIO Community 1 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN        0x20
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN        0x30
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN        0x3C
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN        0x48
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK     0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX   0x84
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK     0x88
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX   0x8C
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK     0x90
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX   0x94
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK   0x98
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX 0x9C
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_1_PADCFGLOCK   0xA0
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_1_PADCFGLOCKTX 0xA4
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN     0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN     0xB4
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN     0xB8
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN     0xBC
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS         0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS         0x0104
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS         0x0108
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS         0x010C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE         0x0120
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE         0x0124
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE         0x0128
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE         0x012C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS    0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS    0x0144
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS    0x0148
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS    0x014C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN     0x0160
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN     0x0164
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN     0x0168
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN     0x016C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS        0x0180
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_SMI_STS        0x0184  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_SMI_STS        0x0188  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_SMI_STS        0x018C  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN         0x01A0
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_SMI_EN         0x01A4  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_SMI_EN         0x01A8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_SMI_EN         0x01AC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS        0x01C0
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_NMI_STS        0x01C4  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_NMI_STS        0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_NMI_STS        0x01CC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN         0x01E0
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_NMI_EN         0x01E4  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_NMI_EN         0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_NMI_EN         0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET  0x600
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET  0x790
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET  0x910
+#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET  0xA90
+
+//
+// GPIO Community 2 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN          0x20
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK       0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX     0x84
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN       0xB0
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS           0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE           0x0120
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS      0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN       0x0160
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_SMI_STS        0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_SMI_EN         0x01A0  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_NMI_STS        0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_GPD_NMI_EN         0x01E0  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET    0x600
+
+//
+// GPIO Community 3 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN          0x20
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN          0x24
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK       0x80
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX     0x84
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK       0x88
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX     0x8C
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN       0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN       0xB4
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS           0x0100
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_IS           0x0104  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE           0x0120
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_IE           0x0124  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS      0x0140
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_GPE_STS      0x0144  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN       0x0160
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_GPE_EN       0x0164  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_SMI_STS          0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_SMI_STS          0x0184  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_SMI_EN           0x01A0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_SMI_EN           0x01A4  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_NMI_STS          0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_NMI_STS          0x01C4  // Not supported setting for this group
+
+//#define R_CNL_PCH_LP_GPIO_PCR_AZA_NMI_EN           0x01E0  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_CPU_NMI_EN           0x01E4  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET    0x600
+#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET    0x680
+
+//
+// GPIO Community 4 Private Configuration Registers
+//
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN        0x20
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN        0x2C
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN         0x38
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN        0x40
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK     0x80
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX   0x84
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK     0x88
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX   0x8C
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK      0x90
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK     0x98
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX   0x9C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN     0xB0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN     0xB4
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN      0xB8
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN     0xBC
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS         0x0100
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS         0x0104
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_IS          0x0108  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS         0x010C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE         0x0120
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE         0x0124
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_IE          0x0128  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE         0x012C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS    0x0140
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS    0x0144
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_GPE_STS     0x0148  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS    0x014C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN     0x0160
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN     0x0164
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_GPE_EN      0x0168  // Not supported setting for this group
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN     0x016C
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS        0x0180
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS        0x0184
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_SMI_STS         0x0188  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_SMI_STS        0x018C  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN         0x01A0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN         0x01A4
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_SMI_EN          0x01A8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_SMI_EN         0x01AC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS        0x01C0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS        0x01C4
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_NMI_STS         0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_NMI_STS        0x01CC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN         0x01E0
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN         0x01E4
+//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_NMI_EN          0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_NMI_EN         0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET  0x600
+#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET  0x780
+#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET   0x900
+#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET  0x990
+
+//
+// PCH-H GPIO registers
+//
+//
+// GPIO Community Common Private Configuration Registers
+//
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A      0x0
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B      0x1
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C      0x2
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D      0x3
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E      0x6
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F      0x7
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G      0x4
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H      0x8
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K      0x9
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I      0xA
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J      0xB
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD        0x5
+#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO      0xD
+
+//
+// GPIO Community 0 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN         0x20
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN         0x30
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK      0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX    0x84
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK      0x88
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX    0x8C
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN      0xC0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN      0xC4
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS          0x0100
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS          0x0104
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE          0x0120
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE          0x0124
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS     0x0140
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS     0x0144
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN      0x0160
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN      0x0164
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_SMI_STS         0x0180  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS         0x0184
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_SMI_EN          0x01A0  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN          0x01A4
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_NMI_STS         0x01C0  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS         0x01C4
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_NMI_EN          0x01E0  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN          0x01E4
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET   0x600
+#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET   0x790
+
+//
+// GPIO Community 1 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN         0x20
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN         0x2C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN         0x38
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN           0x3C
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN         0x40
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK      0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX    0x84
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK      0x88
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX    0x8C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK      0x90
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK        0x98
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX      0x9C
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK    0xA0
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX  0xA4
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_1_PADCFGLOCK    0xA8
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_1_PADCFGLOCKTX  0xAC
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN      0xC0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN      0xC4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN      0xC8
+#define R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN        0xCC
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN      0xD0
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS          0x0100
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS          0x0104
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS          0x0108
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_IS            0x010C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS          0x0110
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE          0x0120
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE          0x0124
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE          0x0128
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_IE            0x012C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE          0x0130
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS     0x0140
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS     0x0144
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS     0x0148
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_GPE_STS       0x014C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS     0x0150
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN      0x0160
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN      0x0164
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN      0x0168
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_GPE_EN        0x016C  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN      0x0170
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS         0x0180
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS         0x0184
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS         0x0188
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_SMI_STS           0x018C  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_SMI_STS         0x0190  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN          0x01A0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN          0x01A4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN          0x01A8
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_SMI_EN            0x01AC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_SMI_EN          0x01B0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS         0x01C0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS         0x01C4
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_G_NMI_STS         0x01C8  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_NMI_STS           0x01CC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_NMI_STS         0x01D0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN          0x01E0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN          0x01E4
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_G_NMI_EN          0x01E8  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_AZA_NMI_EN            0x01EC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_NMI_EN          0x01F0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET   0x600
+#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET   0x780
+#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET   0x900
+#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET     0x980
+#define R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET   0xA00
+
+//
+// GPIO Community 2 Private Configuration Registers
+//
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN           0x20
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK        0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX      0x84
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN        0xB0
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS            0x0100
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE            0x0120
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS       0x0140
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN        0x0160
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_SMI_STS         0x0180  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_SMI_EN          0x01A0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_NMI_STS         0x01C0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPD_NMI_EN          0x01E0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET     0x600
+
+//
+// GPIO Community 3 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN         0x20
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN         0x2C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN         0x38
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN         0x40
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN           0x4C
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK      0x80
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX    0x84
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK      0x88
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX    0x8C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK      0x90
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK      0x98
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX    0x9C
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK        0xA0
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX      0xA4
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN      0xC0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN      0xC4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN      0xC8
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN      0xCC
+#define R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN        0xD0
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS          0x0100
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS          0x0104
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS          0x0108
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS          0x010C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_IS            0x0110  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE          0x0120
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE          0x0124
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE          0x0128
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE          0x012C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_IE            0x0130  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS     0x0140
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS     0x0144
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS     0x0148
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS     0x014C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_GPE_STS       0x0150  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN      0x0160
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN      0x0164
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN      0x0168
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN      0x016C
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_GPE_EN        0x0170  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_SMI_STS         0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_SMI_STS         0x0184  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS         0x0188
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_SMI_STS         0x018C  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_SMI_STS           0x0190  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_SMI_EN          0x01A0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_SMI_EN          0x01A4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN          0x01A8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_SMI_EN          0x01AC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_SMI_EN            0x01B0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_NMI_STS         0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_NMI_STS         0x01C4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS         0x01C8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_NMI_STS         0x01CC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_NMI_STS           0x01D0  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_NMI_EN          0x01E0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_NMI_EN          0x01E4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN          0x01E8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_NMI_EN          0x01EC  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_SPI_NMI_EN            0x01F0  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET   0x600
+#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET   0x780
+#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET   0x900
+#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET   0x9D0
+#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET     0xB50
+
+//
+// GPIO Community 4 Private Configuration Registers
+//
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN           0x20
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN          0x28
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN         0x30
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN         0x3C
+
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK        0x80
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX      0x84
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK       0x88
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX     0x8C
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK      0x90
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX    0x94
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK      0x98
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX    0x9C
+
+#define R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN        0xC0
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN       0xC4
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN      0xC8
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN      0xCC
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_IS            0x0100  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_IS           0x0104  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS          0x0108
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS          0x010C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_IE            0x0120  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_IE           0x0124  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE          0x0128
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE          0x012C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_GPE_STS       0x0140  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_GPE_STS      0x0144  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS     0x0148
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS     0x014C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_GPE_EN        0x0160  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_GPE_EN       0x0164  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN      0x0168
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN      0x016C
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_SMI_STS           0x0180  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_SMI_STS          0x0184  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS         0x0188
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_SMI_STS         0x018C  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_SMI_EN            0x01A0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_SMI_EN           0x01A4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN          0x01A8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_SMI_EN          0x01AC  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_NMI_STS           0x01C0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_NMI_STS          0x01C4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS         0x01C8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_NMI_STS         0x01CC  // Not supported setting for this group
+
+//#define R_CNL_PCH_H_GPIO_PCR_CPU_NMI_EN            0x01E0  // Not supported setting for this group
+//#define R_CNL_PCH_H_GPIO_PCR_JTAG_NMI_EN           0x01E4  // Not supported setting for this group
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN          0x01E8
+//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_NMI_EN          0x01EC  // Not supported setting for this group
+
+#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET     0x600
+#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET    0x6B0
+#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET   0x740
+#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET   0x860
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
new file mode 100644
index 0000000000..bc099d9662
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
@@ -0,0 +1,204 @@
+/** @file
+  Register names for PCH 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_HDA_H_
+#define _PCH_REGS_HDA_H_
+
+//
+// HD-A Controller Registers (D31:F3)
+//
+// PCI Configuration Space Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_HDA               31
+#define PCI_FUNCTION_NUMBER_PCH_HDA             3
+
+#define R_HDA_CFG_PI                            0x09
+#define V_HDA_CFG_PI_ADSP_UAA                   0x80
+#define R_HDA_CFG_SCC                           0x0A
+#define V_HDA_CFG_SCC_ADSP                      0x01
+#define R_HDA_CFG_HDALBA                        0x10
+#define B_HDA_CFG_HDALBA_LBA                    0xFFFFC000
+#define V_HDA_CFG_HDBAR_SIZE                    (1 << 14)
+#define R_HDA_CFG_HDAUBA                        0x14
+#define B_HDA_CFG_HDAUBA_UBA                    0xFFFFFFFF
+#define R_HDA_CFG_CGCTL                         0x48
+#define B_HDA_CFG_CGCTL_RSMTCGE                 BIT18
+#define B_HDA_CFG_CGCTL_MISCBDCGE               BIT6
+#define R_HDA_CFG_PC                            0x52
+#define V_HDA_CFG_PC_PMES                       0x18
+#define N_HDA_CFG_PC_PMES                       11
+#define R_HDA_CFG_PCS                           0x54
+#define B_HDA_CFG_PCS_PMEE                      BIT8
+#define B_HDA_CFG_PCS_PS                        (BIT1 | BIT0)
+#define R_HDA_CFG_MMC                           0x62
+#define B_HDA_CFG_MMC_ME                        BIT0
+#define R_HDA_CFG_DEVC                          0x78
+#define B_HDA_CFG_DEVC_NSNPEN                   BIT11
+#define R_HDA_CFG_SEM1                          0xC0
+#define B_HDA_CFG_SEM1_LFLCS                    BIT24
+#define B_HDA_CFG_SEM1_BLKC3DIS                 BIT17
+#define B_HDA_CFG_SEM1_TMODE                    BIT12
+#define B_HDA_CFG_SEM1_FIFORDYSEL               (BIT10 | BIT9)
+#define R_HDA_CFG_SEM2                          0xC4
+#define B_HDA_CFG_SEM2_BSMT                     (BIT27 | BIT26)
+#define V_HDA_CFG_SEM2_BSMT                     0x1
+#define N_HDA_CFG_SEM2_BSMT                     26
+#define B_HDA_CFG_SEM2_VC0SNR                   BIT24
+#define B_HDA_CFG_SEM2_DUM                      BIT23
+#define R_HDA_CFG_SEM3L                         0xC8
+#define B_HDA_CFG_SEM3L_ISL1EXT2                (BIT21 | BIT20)
+#define V_HDA_CFG_SEM3L_ISL1EXT2                0x2
+#define N_HDA_CFG_SEM3L_ISL1EXT2                20
+#define R_HDA_CFG_SEM4L                         0xD0
+#define B_HDA_CFG_SEM4L_OSL1EXT2                (BIT21 | BIT20)
+#define V_HDA_CFG_SEM4L_OSL1EXT2                0x3
+#define N_HDA_CFG_SEM4L_OSL1EXT2                20
+
+//
+// Memory Space Registers
+//
+//
+// Resides in 'HD Audio Global Registers' (0000h)
+//
+#define R_HDA_MEM_GCAP                        0x00
+#define R_HDA_MEM_GCTL                        0x08
+#define B_HDA_MEM_GCTL_CRST                   BIT0
+
+#define R_HDA_MEM_OUTPAY                      0x04
+#define R_HDA_MEM_INPAY                       0x06
+#define V_HDA_MEM_INPAY_DEFAULT               0x1C
+
+#define R_HDA_MEM_WAKEEN                      0x0C
+#define B_HDA_MEM_WAKEEN_SDI_3                BIT3
+#define B_HDA_MEM_WAKEEN_SDI_2                BIT2
+#define B_HDA_MEM_WAKEEN_SDI_1                BIT1
+#define B_HDA_MEM_WAKEEN_SDI_0                BIT0
+
+#define R_HDA_MEM_WAKESTS                     0x0E
+#define B_HDA_MEM_WAKESTS_SDIN3               BIT3
+#define B_HDA_MEM_WAKESTS_SDIN2               BIT2
+#define B_HDA_MEM_WAKESTS_SDIN1               BIT1
+#define B_HDA_MEM_WAKESTS_SDIN0               BIT0
+
+//
+// Resides in 'HD Audio Controller Registers' (0030h)
+//
+#define R_HDA_MEM_IC                          0x60
+#define R_HDA_MEM_IR                          0x64
+#define R_HDA_MEM_ICS                         0x68
+#define B_HDA_MEM_ICS_IRV                     BIT1
+#define B_HDA_MEM_ICS_ICB                     BIT0
+
+//
+// Resides in 'HD Audio Processing Pipe Capability Structure' (0800h)
+//
+#define R_HDA_MEM_PPC                         0x0800 // Processing Pipe Capability Structure (Memory Space, offset 0800h)
+#define R_HDA_MEM_PPCTL                       (R_HDA_MEM_PPC + 0x04)
+#define B_HDA_MEM_PPCTL_GPROCEN               BIT30
+
+//
+// Resides in 'HD Audio Multiple Links Capability Structure' (0C00h)
+//
+#define HDA_HDALINK_INDEX                     0
+#define HDA_IDISPLINK_INDEX                   1
+
+#define R_HDA_MEM_MLC                         0x0C00 // Multiple Links Capability Structure (Memory Space, offset 0C00h)
+#define R_HDA_MEM_LCTLX(x)                    (R_HDA_MEM_MLC + (0x40 + (0x40 * (x)) + 0x04)) // x - Link index: 0 - HDA Link, 1 - iDisp Link
+#define B_HDA_MEM_LCTLX_CPA                   BIT23
+#define B_HDA_MEM_LCTLX_SPA                   BIT16
+#define N_HDA_MEM_LCTLX_SCF                   0
+#define V_HDA_MEM_LCTLX_SCF_6MHZ              0x0
+#define V_HDA_MEM_LCTLX_SCF_12MHZ             0x1
+#define V_HDA_MEM_LCTLX_SCF_24MHZ             0x2
+#define V_HDA_MEM_LCTLX_SCF_48MHZ             0x3
+#define V_HDA_MEM_LCTLX_SCF_96MHZ             0x4
+
+//
+// Resides in 'HD Audio Vendor Specific Registers' (1000h)
+//
+#define R_HDA_MEM_LTRC                        0x1048
+#define V_HDA_MEM_LTRC_GB                     0x29
+#define N_HDA_MEM_LTRC_GB                     0
+#define R_HDA_MEM_PCE                         0x104B
+#define B_HDA_MEM_PCE_D3HE                    BIT2
+
+//
+// Private Configuration Space Registers
+//
+//
+// Resides in IOSF & Fabric Configuration Registers (000h)
+//
+#define R_HDA_PCR_TTCCFG                    0xE4
+#define B_HDA_PCR_TTCCFG_HCDT               BIT1
+
+//
+// Resides in PCI & Codec Configuration Registers (500h)
+//
+#define R_HDA_PCR_PCICDCCFG                 0x500 // PCI & Codec Configuration Registers (PCR, offset 500h)
+#define B_HDA_PCR_PCICDCCFG_ACPIIN          0x0000FF00
+#define N_HDA_PCR_PCICDCCFG_ACPIIN          8
+#define R_HDA_PCR_FNCFG                     (R_HDA_PCR_PCICDCCFG + 0x30)
+#define B_HDA_PCR_FNCFG_PGD                 BIT5
+#define B_HDA_PCR_FNCFG_BCLD                BIT4
+#define B_HDA_PCR_FNCFG_CGD                 BIT3
+#define B_HDA_PCR_FNCFG_ADSPD               BIT2
+#define B_HDA_PCR_FNCFG_HDASD               BIT0
+#define R_HDA_PCR_CDCCFG                    (R_HDA_PCR_PCICDCCFG + 0x34)
+#define B_HDA_PCR_CDCCFG_DIS_SDIN2          BIT2
+
+//
+// Resides in Power Management & EBB Configuration Registers (600h)
+//
+#define R_HDA_PCR_PWRMANCFG                 0x600 // Power Management & EBB Configuration Registers (PCR, offset 600h)
+#define R_HDA_PCR_APLLP0                    (R_HDA_PCR_PWRMANCFG + 0x10)
+#define V_HDA_PCR_APLLP0                    0xFC1E0000
+#define R_HDA_PCR_APLLP1                    (R_HDA_PCR_PWRMANCFG + 0x14)
+#define V_HDA_PCR_APLLP1                    0x00003F00
+#define R_HDA_PCR_APLLP2                    (R_HDA_PCR_PWRMANCFG + 0x18)
+#define V_HDA_PCR_APLLP2                    0x0000011D
+#define R_HDA_PCR_IOBCTL                    (R_HDA_PCR_PWRMANCFG + 0x1C)
+#define B_HDA_PCR_IOBCTL_OSEL               (BIT9 | BIT8)
+#define V_HDA_PCR_IOBCTL_OSEL_HDALINK       0
+#define V_HDA_PCR_IOBCTL_OSEL_HDALINK_I2S   1
+#define V_HDA_PCR_IOBCTL_OSEL_I2S           3
+#define N_HDA_PCR_IOBCTL_OSEL               8
+#define B_HDA_PCR_IOBCTL_VSEL               BIT1
+#define R_HDA_PCR_PTDC                      (R_HDA_PCR_PWRMANCFG + 0x28)
+#define B_HDA_PCR_PTDC_SRMIW                (BIT6 | BIT5 | BIT4)
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
new file mode 100644
index 0000000000..0cd69eb299
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
@@ -0,0 +1,170 @@
+/** @file
+  Register definition for HSIO
+
+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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_HSIO_H_
+#define _PCH_REGS_HSIO_H_
+
+#define B_HSIO_PCR_ACCESS_TYPE                          (BIT15 | BIT14)
+#define N_HSIO_PCR_ACCESS_TYPE                          14
+#define V_HSIO_PCR_ACCESS_TYPE_BDCAST                   (BIT15 | BIT14)
+#define V_HSIO_PCR_ACCESS_TYPE_MULCAST                  BIT15
+#define B_HSIO_PCR_LANE_GROUP_NO                        (BIT13 | BIT12 | BIT11 | BIT10 | BIT9)
+#define B_HSIO_PCR_FUNCTION_NO                          (BIT8  | BIT7)
+#define N_HSIO_PCR_FUNCTION_NO                          7
+#define B_HSIO_PCR_REG_OFFSET                           (BIT6  | BIT5  | BIT4  | BIT3  | BIT2  | BIT1  | BIT0)
+
+#define V_HSIO_PCR_ACCESS_TYPE_BCAST                    0x03
+#define V_HSIO_PCR_ACCESS_TYPE_MCAST                    0x02
+#define V_HSIO_PCR_ACCESS_TYPE_UCAST                    0x00
+
+#define V_HSIO_PCR_LANE_GROUP_NO_CMN_LANE               0x00
+
+#define V_HSIO_PCR_FUNCTION_NO_PCS                      0x00
+#define V_HSIO_PCR_FUNCTION_NO_TX                       0x01
+#define V_HSIO_PCR_FUNCTION_NO_RX                       0x02
+
+#define V_HSIO_PCR_FUNCTION_NO_CMNDIG                   0x00
+#define V_HSIO_PCR_FUNCTION_NO_CMNANA                   0x01
+#define V_HSIO_PCR_FUNCTION_NO_PLL                      0x02
+
+#define R_HSIO_PCR_PCS_DWORD4                           0x10
+
+#define R_HSIO_PCR_PCS_DWORD8                           0x20
+#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_PTR_INIT_4_0     0x1F000000
+#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_LOWATER_4_0      0x001F0000
+#define N_HSIO_PCR_PCS_DWORD8_CRI_RXEB_LOWATER_4_0      16
+#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_HIWATER_4_0      0x00001F00
+#define N_HSIO_PCR_PCS_DWORD8_CRI_RXEB_HIWATER_4_0      8
+
+#define R_HSIO_PCR_PCS_DWORD9                           0x24
+#define B_HSIO_PCR_PCS_DWORD9_REG_ENABLE_PWR_GATING     BIT29
+
+#define R_HSIO_PCR_RX_DWORD8                            0x220
+#define B_HSIO_PCR_RX_DWORD8_ICFGDFETAP3_EN             BIT10
+
+#define R_HSIO_PCR_RX_DWORD9                            0x224
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP4_OVERRIDE_EN     BIT24
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP3_OVERRIDE_EN     BIT26
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP2_OVERRIDE_EN     BIT28
+#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP1_OVERRIDE_EN     BIT30
+
+#define R_HSIO_PCR_RX_DWORD12                           0x230
+#define B_HSIO_PCR_RX_DWORD12_O_CFGEWMARGINSEL          BIT14
+
+#define R_HSIO_PCR_RX_DWORD20                               0x250
+#define B_HSIO_PCR_RX_DWORD20_ICFGCTLEDATATAP_FULLRATE_5_0  (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
+#define N_HSIO_PCR_RX_DWORD20_ICFGCTLEDATATAP_FULLRATE_5_0  24
+
+#define R_HSIO_PCR_RX_DWORD21                               0x254
+#define B_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_QUATRATE_5_0  (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_QUATRATE_5_0  8
+#define B_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_HALFRATE_5_0  (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define N_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_HALFRATE_5_0  0
+
+#define R_HSIO_PCR_RX_DWORD23                               0x25C
+#define B_HSIO_PCR_RX_DWORD23_ICFGVGABLWTAP_OVERRIDE_EN     BIT2
+#define B_HSIO_PCR_RX_DWORD23_CFGVGATAP_ADAPT_OVERRIDE_EN   BIT4
+
+#define R_HSIO_PCR_RX_DWORD25                            0x264
+#define B_HSIO_PCR_RX_DWORD25_RX_TAP_CFG_CTRL            BIT3
+#define B_HSIO_PCR_RX_DWORD25_CTLE_ADAPT_OFFSET_CFG_4_0  0x1F0000
+#define N_HSIO_PCR_RX_DWORD25_CTLE_ADAPT_OFFSET_CFG_4_0  16
+
+#define R_HSIO_PCR_RX_DWORD26                           0x268
+#define B_HSIO_PCR_RX_DWORD26_SATA_EQ_DIS               BIT16
+
+#define R_HSIO_PCR_RX_DWORD34                           0x288
+#define B_HSIO_PCR_RX_DWORD34_MM_PH_OFC_SCALE_2_0       (BIT14 | BIT13 | BIT12)
+#define N_HSIO_PCR_RX_DWORD34_MM_PH_OFC_SCALE_2_0       12
+
+#define R_HSIO_PCR_RX_DWORD44                           0x2B0
+#define B_HSIO_PCR_RX_DWORD44_0_DFE_DATASUMCAL0_7_0     0xFF0000
+#define N_HSIO_PCR_RX_DWORD44_0_DFE_DATASUMCAL0_7_0     16
+
+#define R_HSIO_PCR_RX_DWORD56                           0x2E0
+#define B_HSIO_PCR_RX_DWORD56_ICFGPIDACCFGVALID         BIT16
+
+#define R_HSIO_PCR_RX_DWORD57                           0x2E4
+#define B_HSIO_PCR_RX_DWORD57_JIM_COURSE                BIT30
+#define B_HSIO_PCR_RX_DWORD57_JIM_ENABLE                BIT29
+#define B_HSIO_PCR_RX_DWORD57_JIMMODE                   BIT28
+#define B_HSIO_PCR_RX_DWORD57_JIMNUMCYCLES_3_0          0x0F000000
+#define N_HSIO_PCR_RX_DWORD57_JIMNUMCYCLES_3_0          24
+#define B_HSIO_PCR_RX_DWORD57_ICFGMARGINEN              BIT0
+
+#define R_HSIO_PCR_RX_DWORD59                           0x2EC
+#define R_HSIO_PCR_RX_DWORD60                           0x2F0
+
+#define R_HSIO_PCR_TX_DWORD5                            0x154
+#define B_HSIO_PCR_TX_DWORD5_OW2TAPGEN2DEEMPH3P5_5_0    (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_TX_DWORD5_OW2TAPGEN2DEEMPH3P5_5_0    16
+#define B_HSIO_PCR_TX_DWORD5_OW2TAPGEN1DEEMPH3P5_5_0    (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_TX_DWORD5_OW2TAPGEN1DEEMPH3P5_5_0    8
+
+#define R_HSIO_PCR_TX_DWORD6                            0x158
+#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN3DEEMPH6P0_5_0    (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_TX_DWORD6_OW2TAPGEN3DEEMPH6P0_5_0    16
+#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN2DEEMPH6P0_5_0    (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_TX_DWORD6_OW2TAPGEN2DEEMPH6P0_5_0    8
+#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN1DEEMPH6P0_5_0    (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+
+#define R_HSIO_PCR_TX_DWORD8                            0x160
+#define B_HSIO_PCR_TX_DWORD8_ORATE10MARGIN_5_0          (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
+#define N_HSIO_PCR_TX_DWORD8_ORATE10MARGIN_5_0          24
+#define B_HSIO_PCR_TX_DWORD8_ORATE01MARGIN_5_0          (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_TX_DWORD8_ORATE01MARGIN_5_0          16
+#define B_HSIO_PCR_TX_DWORD8_ORATE00MARGIN_5_0          (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define N_HSIO_PCR_TX_DWORD8_ORATE00MARGIN_5_0          8
+
+#define R_HSIO_PCR_TX_DWORD19                           0x18C
+
+#define R_HSIO_PCR_CLANE0_CMN_ANA_DWORD2                0x80C8
+#define B_HSIO_PCR_CLANE0_CMN_ANA_DWORD2_O_DTPLL1_lC_PLLEN_H_OVRDEN                BIT5
+#define B_HSIO_PCR_CLANE0_CMN_ANA_DWORD2_O_DTPLL1_lC_FULLCALRESET_L_OVERDEN        BIT3
+
+#define R_HSIO_PCR_PLL_SSC_DWORD2                       0x8188
+#define B_HSIO_PCR_PLL_SSC_DWORD2_SSCSTEPSIZE_7_0       (BIT23 | BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define N_HSIO_PCR_PLL_SSC_DWORD2_SSCSTEPSIZE_7_0       16
+#define B_HSIO_PCR_PLL_SSC_DWORD2_SSCSEN                BIT10
+#define N_HSIO_PCR_PLL_SSC_DWORD2_SSCSEN                10
+
+#define R_HSIO_PCR_PLL_SSC_DWORD3                       0x818C
+#define B_HSIO_PCR_PLL_SSC_DWORD3_SSC_PROPAGATE         BIT0
+
+
+#endif //_PCH_REGS_HSIO_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
new file mode 100644
index 0000000000..5b4e23c43f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
@@ -0,0 +1,79 @@
+/** @file
+  Register names for PCH Integrated Sensor Hub (ISH3.0)
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_ISH_H_
+#define _PCH_REGS_ISH_H_
+
+//
+// ISH Controller Registers
+//
+// D19:F0
+#define PCI_DEVICE_NUMBER_PCH_ISH             19
+#define PCI_FUNCTION_NUMBER_PCH_ISH           0
+
+// PCI Configuration Space Registers
+#define R_ISH_CFG_BAR0_LOW                    0x10
+#define R_ISH_CFG_BAR0_HIGH                   0x14
+#define V_ISH_CFG_BAR0_SIZE                   0x100000
+#define N_ISH_CFG_BAR0_ALIGNMENT              20
+#define R_ISH_CFG_BAR1_LOW                    0x18
+#define R_ISH_CFG_BAR1_HIGH                   0x1C
+#define V_ISH_CFG_BAR1_SIZE                   0x1000
+#define N_ISH_CFG_BAR1_ALIGNMENT              12
+
+//
+// ISH Private Configuration Space Registers (IOSF2OCP)
+// (PID:ISH)
+//
+#define R_ISH_PCR_PMCTL                   0x1D0                         ///< Power Management
+#define R_ISH_PCR_PCICFGCTRL              0x200                         ///< PCI Configuration Control
+#define B_ISH_PCR_PCICFGCTR_PCI_IRQ       0x0FF00000                    ///< PCI IRQ number
+#define N_ISH_PCR_PCICFGCTR_PCI_IRQ       20
+#define B_ISH_PCR_PCICFGCTR_ACPI_IRQ      0x000FF000                    ///< ACPI IRQ number
+#define N_ISH_PCR_PCICFGCTR_ACPI_IRQ      12
+#define B_ISH_PCR_PCICFGCTR_IPIN1         (BIT11 | BIT10 | BIT9 | BIT8) ///< Interrupt Pin
+#define N_ISH_PCR_PCICFGCTR_IPIN1         8
+#define B_ISH_PCR_PCICFGCTRL_BAR1DIS      BIT7                          ///< BAR1 Disable
+
+//
+// Number of pins used by ISH controllers
+//
+#define PCH_ISH_PINS_PER_I2C_CONTROLLER               2
+#define PCH_ISH_PINS_PER_UART_CONTROLLER              4
+#define PCH_ISH_PINS_PER_SPI_CONTROLLER               4
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
new file mode 100644
index 0000000000..8d7c3f9015
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
@@ -0,0 +1,103 @@
+/** @file
+  Register names for ITSS
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_ITSS_H_
+#define _PCH_REGS_ITSS_H_
+
+//
+// ITSS PCRs (PID:ITSS)
+//
+#define R_ITSS_PCR_PIRQA_ROUT             0x3100          ///< PIRQA Routing Control register
+#define R_ITSS_PCR_PIRQB_ROUT             0x3101          ///< PIRQB Routing Control register
+#define R_ITSS_PCR_PIRQC_ROUT             0x3102          ///< PIRQC Routing Control register
+#define R_ITSS_PCR_PIRQD_ROUT             0x3103          ///< PIRQD Routing Control register
+#define R_ITSS_PCR_PIRQE_ROUT             0x3104          ///< PIRQE Routing Control register
+#define R_ITSS_PCR_PIRQF_ROUT             0x3105          ///< PIRQF Routing Control register
+#define R_ITSS_PCR_PIRQG_ROUT             0x3106          ///< PIRQG Routing Control register
+#define R_ITSS_PCR_PIRQH_ROUT             0x3107          ///< PIRQH Routing Control register
+#define B_ITSS_PCR_PIRQX_ROUT_REN         0x80            ///< Interrupt Routing Enable
+#define B_ITSS_PCR_PIRQX_ROUT_IR          0x0F            ///< IRQ Routng
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_3       0x03            ///< Route PIRQx to IRQ3
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_4       0x04            ///< Route PIRQx to IRQ4
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_5       0x05            ///< Route PIRQx to IRQ5
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_6       0x06            ///< Route PIRQx to IRQ6
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_7       0x07            ///< Route PIRQx to IRQ7
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_9       0x09            ///< Route PIRQx to IRQ9
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_10      0x0A            ///< Route PIRQx to IRQ10
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_11      0x0B            ///< Route PIRQx to IRQ11
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_12      0x0C            ///< Route PIRQx to IRQ12
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_14      0x0E            ///< Route PIRQx to IRQ14
+#define V_ITSS_PCR_PIRQX_ROUT_IRQ_15      0x0F            ///< Route PIRQx to IRQ15
+
+#define R_ITSS_PCR_PIR0                   0x3140          ///< PCI Interrupt Route 0
+#define R_ITSS_PCR_PIR1                   0x3142          ///< PCI Interrupt Route 1
+#define R_ITSS_PCR_PIR2                   0x3144          ///< PCI Interrupt Route 2
+#define R_ITSS_PCR_PIR3                   0x3146          ///< PCI Interrupt Route 3
+#define R_ITSS_PCR_PIR4                   0x3148          ///< PCI Interrupt Route 4
+#define R_ITSS_PCR_PIR5                   0x314A          ///< PCI Interrupt Route 5
+#define R_ITSS_PCR_PIR6                   0x314C          ///< PCI Interrupt Route 6
+#define R_ITSS_PCR_PIR7                   0x314E          ///< PCI Interrupt Route 7
+#define R_ITSS_PCR_PIR8                   0x3150          ///< PCI Interrupt Route 8
+#define R_ITSS_PCR_PIR9                   0x3152          ///< PCI Interrupt Route 9
+#define R_ITSS_PCR_PIR10                  0x3154          ///< PCI Interrupt Route 10
+#define R_ITSS_PCR_PIR11                  0x3156          ///< PCI Interrupt Route 11
+#define R_ITSS_PCR_PIR12                  0x3158          ///< PCI Interrupt Route 12
+
+#define R_ITSS_PCR_GIC                    0x31FC          ///< General Interrupt Control
+#define B_ITSS_PCR_GIC_MAX_IRQ_24         BIT9            ///< Max IRQ entry size, 1 = 24 entry size, 0 = 120 entry size
+#define B_ITSS_PCR_GIC_AME                BIT17           ///< Alternate Access Mode Enable
+#define B_ITSS_PCR_GIC_SPS                BIT16           ///< Shutdown Policy Select
+#define R_ITSS_PCR_IPC0                   0x3200          ///< Interrupt Polarity Control 0
+#define R_ITSS_PCR_IPC1                   0x3204          ///< Interrupt Polarity Control 1
+#define R_ITSS_PCR_IPC2                   0x3208          ///< Interrupt Polarity Control 2
+#define R_ITSS_PCR_IPC3                   0x320C          ///< Interrupt Polarity Control 3
+#define R_ITSS_PCR_ITSSPRC                0x3300          ///< ITSS Power Reduction Control
+#define B_ITSS_PCR_ITSSPRC_PGCBDCGE       BIT4            ///< PGCB Dynamic Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_HPETDCGE       BIT3            ///< HPET Dynamic Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_8254CGE        BIT2            ///< 8254 Static Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_IOSFICGE       BIT1            ///< IOSF-Sideband Interface Clock Gating Enable
+#define B_ITSS_PCR_ITSSPRC_ITSSCGE        BIT0            ///< ITSS Clock Gate Enable
+#define R_ITSS_PCR_NMI                    0x3330          ///< NMI Control
+#define N_ITSS_PCR_NMI_NMI2SMI_STS        3               ///< NMI2SMI Status
+#define N_ITSS_PCR_NMI_NMI2SMI_EN         2               ///< NMI2SMI Enable
+#define B_ITSS_PCR_NMI_NMI2SMI_EN         BIT2            ///< NMI2SMI Enable
+#define B_ITSS_PCR_NMI_NMI_NOW_STS        BIT1            ///< NMI_NOW_STS
+#define B_ITSS_PCR_NMI_NMI_NOW            BIT0            ///< NMI_NOW
+#define R_ITSS_PCR_MMC                    0x3334          ///< Master Message Control
+#define B_ITSS_PCR_MMC_MSTRMSG_EN         BIT0            ///< Master Message Enable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
new file mode 100644
index 0000000000..f649873f67
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
@@ -0,0 +1,58 @@
+/** @file
+  Register names for PCH LAN 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_LAN_H_
+#define _PCH_REGS_LAN_H_
+
+//
+// Gigabit LAN Controller configuration registers (D31:F6)
+//
+#define PCI_DEVICE_NUMBER_PCH_LAN     31
+#define PCI_FUNCTION_NUMBER_PCH_LAN   6
+
+#define R_LAN_CFG_MBARA               0x10
+#define N_LAN_CFG_MBARA_ALIGN         17
+#define R_LAN_CFG_PMCS                0xCC
+#define B_LAN_CFG_PMCS_PS             (BIT1 | BIT0)
+#define V_LAN_CFG_PMCS_PS0            0x00
+#define R_LAN_MEM_CSR_RAL                  0x5400
+#define R_LAN_MEM_CSR_RAH                  0x5404
+#define B_LAN_MEM_CSR_RAH_RAH              0x0000FFFF
+#define R_LAN_MEM_CSR_WUC                  0x5800
+#define B_LAN_MEM_CSR_WUC_APME             BIT0
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
new file mode 100644
index 0000000000..34fc3c4dd2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
@@ -0,0 +1,360 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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 (D31:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_LPC       31
+#define PCI_FUNCTION_NUMBER_PCH_LPC     0
+
+#define V_LPC_CFG_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID
+
+
+#define R_LPC_CFG_SERIRQ_CNT                      0x64
+#define B_LPC_CFG_SERIRQ_CNT_SIRQEN               BIT7
+#define B_LPC_CFG_SERIRQ_CNT_SIRQMD               BIT6
+#define B_LPC_CFG_SERIRQ_CNT_SIRQSZ               (BIT5 | BIT4 | BIT3 | BIT2)
+#define N_LPC_CFG_SERIRQ_CNT_SIRQSZ               2
+#define B_LPC_CFG_SERIRQ_CNT_SFPW                 (BIT1 | BIT0)
+#define N_LPC_CFG_SERIRQ_CNT_SFPW                 0
+#define V_LPC_CFG_SERIRQ_CNT_SFPW_4CLK            0x00
+#define V_LPC_CFG_SERIRQ_CNT_SFPW_6CLK            0x01
+#define V_LPC_CFG_SERIRQ_CNT_SFPW_8CLK            0x02
+
+#define R_LPC_CFG_IOD                             0x80
+#define B_LPC_CFG_IOD_FDD                         BIT12
+#define N_LPC_CFG_IOD_FDD                         12
+#define V_LPC_CFG_IOD_FDD_3F0                     0
+#define V_LPC_CFG_IOD_FDD_370                     1
+#define B_LPC_CFG_IOD_LPT                         (BIT9 | BIT8)
+#define N_LPC_CFG_IOD_LPT                         8
+#define V_LPC_CFG_IOD_LPT_378                     0
+#define V_LPC_CFG_IOD_LPT_278                     1
+#define V_LPC_CFG_IOD_LPT_3BC                     2
+#define B_LPC_CFG_IOD_COMB                        (BIT6 | BIT5 |BIT4)
+#define N_LPC_CFG_IOD_COMB                        4
+#define V_LPC_CFG_IOD_COMB_3F8                    0
+#define V_LPC_CFG_IOD_COMB_2F8                    1
+#define V_LPC_CFG_IOD_COMB_220                    2
+#define V_LPC_CFG_IOD_COMB_228                    3
+#define V_LPC_CFG_IOD_COMB_238                    4
+#define V_LPC_CFG_IOD_COMB_2E8                    5
+#define V_LPC_CFG_IOD_COMB_338                    6
+#define V_LPC_CFG_IOD_COMB_3E8                    7
+#define B_LPC_CFG_IOD_COMA                        (BIT2 | BIT1 | BIT0)
+#define N_LPC_CFG_IOD_COMA                        0
+#define V_LPC_CFG_IOD_COMA_3F8                    0
+#define V_LPC_CFG_IOD_COMA_2F8                    1
+#define V_LPC_CFG_IOD_COMA_220                    2
+#define V_LPC_CFG_IOD_COMA_228                    3
+#define V_LPC_CFG_IOD_COMA_238                    4
+#define V_LPC_CFG_IOD_COMA_2E8                    5
+#define V_LPC_CFG_IOD_COMA_338                    6
+#define V_LPC_CFG_IOD_COMA_3E8                    7
+#define R_LPC_CFG_IOE                             0x82
+#define B_LPC_CFG_IOE_ME2                         BIT13           ///< Microcontroller Enable #2, Enables decoding of I/O locations 4Eh and 4Fh to LPC
+#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_ME1                         BIT11           ///< Microcontroller Enable #1, Enables decoding of I/O locations 62h and 66h 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_HGE                         BIT9            ///< High Gameport Enable, Enables decoding of the I/O locations 208h to 20Fh to LPC.
+#define B_LPC_CFG_IOE_LGE                         BIT8            ///< Low Gameport Enable, Enables decoding of the I/O locations 200h to 207h to LPC.
+#define B_LPC_CFG_IOE_FDE                         BIT3            ///< Floppy Drive Enable, Enables decoding of the FDD range to LPC. Range is selected by LIOD.FDE
+#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_GEN1_DEC                        0x84
+#define R_LPC_CFG_GEN2_DEC                        0x88
+#define R_LPC_CFG_GEN3_DEC                        0x8C
+#define R_LPC_CFG_GEN4_DEC                        0x90
+#define B_LPC_CFG_GENX_DEC_IODRA                  0x00FC0000
+#define B_LPC_CFG_GENX_DEC_IOBAR                  0x0000FFFC
+#define B_LPC_CFG_GENX_DEC_EN                     0x00000001
+#define R_LPC_CFG_ULKMC                           0x94
+#define B_LPC_CFG_ULKMC_SMIBYENDPS                BIT15
+#define B_LPC_CFG_ULKMC_TRAPBY64W                 BIT11
+#define B_LPC_CFG_ULKMC_TRAPBY64R                 BIT10
+#define B_LPC_CFG_ULKMC_TRAPBY60W                 BIT9
+#define B_LPC_CFG_ULKMC_TRAPBY60R                 BIT8
+#define B_LPC_CFG_ULKMC_SMIATENDPS                BIT7
+#define B_LPC_CFG_ULKMC_PSTATE                    BIT6
+#define B_LPC_CFG_ULKMC_A20PASSEN                 BIT5
+#define B_LPC_CFG_ULKMC_USBSMIEN                  BIT4
+#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_CS1IORE_DPCS1RE                BIT14
+#define R_ESPI_CFG_CS1GIR1                        0xA4
+#define R_ESPI_CFG_CS1GMR1                        0xA8
+
+#define R_LPC_CFG_FWH_BIOS_SEL                    0xD0
+#define B_LPC_CFG_FWH_BIOS_SEL_F8                 0xF0000000
+#define B_LPC_CFG_FWH_BIOS_SEL_F0                 0x0F000000
+#define B_LPC_CFG_FWH_BIOS_SEL_E8                 0x00F00000
+#define B_LPC_CFG_FWH_BIOS_SEL_E0                 0x000F0000
+#define B_LPC_CFG_FWH_BIOS_SEL_D8                 0x0000F000
+#define B_LPC_CFG_FWH_BIOS_SEL_D0                 0x00000F00
+#define B_LPC_CFG_FWH_BIOS_SEL_C8                 0x000000F0
+#define B_LPC_CFG_FWH_BIOS_SEL_C0                 0x0000000F
+#define R_LPC_CFG_FWH_BIOS_SEL2                   0xD4
+#define B_LPC_CFG_FWH_BIOS_SEL2_70                0xF000
+#define B_LPC_CFG_FWH_BIOS_SEL2_60                0x0F00
+#define B_LPC_CFG_FWH_BIOS_SEL2_50                0x00F0
+#define B_LPC_CFG_FWH_BIOS_SEL2_40                0x000F
+#define R_LPC_CFG_BDE                             0xD8                          ///< BIOS decode enable
+#define B_LPC_CFG_BDE_F8                          BIT15
+#define B_LPC_CFG_BDE_F0                          BIT14
+#define B_LPC_CFG_BDE_E8                          BIT13
+#define B_LPC_CFG_BDE_E0                          BIT12
+#define B_LPC_CFG_BDE_D8                          BIT11
+#define B_LPC_CFG_BDE_D0                          BIT10
+#define B_LPC_CFG_BDE_C8                          BIT9
+#define B_LPC_CFG_BDE_C0                          BIT8
+#define B_LPC_CFG_BDE_LEG_F                       BIT7
+#define B_LPC_CFG_BDE_LEG_E                       BIT6
+#define B_LPC_CFG_BDE_70                          BIT3
+#define B_LPC_CFG_BDE_60                          BIT2
+#define B_LPC_CFG_BDE_50                          BIT1
+#define B_LPC_CFG_BDE_40                          BIT0
+#define R_LPC_CFG_PCC                             0xE0
+#define B_LPC_CFG_PCC_CLKRUN_EN                   BIT0
+
+#define B_LPC_CFG_FVEC0_USB_PORT_CAP              (BIT11 | BIT10)
+#define V_LPC_CFG_FVEC0_USB_14_PORT               0x00000000
+#define V_LPC_CFG_FVEC0_USB_12_PORT               0x00000400
+#define V_LPC_CFG_FVEC0_USB_10_PORT               0x00000800
+#define B_LPC_CFG_FVEC0_SATA_RAID_CAP             BIT7
+#define B_LPC_CFG_FVEC0_SATA_PORT23_CAP           BIT6
+#define B_LPC_CFG_FVEC0_SATA_PORT1_6GB_CAP        BIT3
+#define B_LPC_CFG_FVEC0_SATA_PORT0_6GB_CAP        BIT2
+#define B_LPC_CFG_FVEC0_PCI_CAP                   BIT1
+#define R_LPC_CFG_FVEC1                           0x01
+#define B_LPC_CFG_FVEC1_USB_R_CAP                 BIT22
+#define R_LPC_CFG_FVEC2                           0x02
+#define V_LPC_CFG_FVEC2_PCIE_PORT78_CAP           0x00200000
+#define V_LPC_CFG_FVEC2_PCH_IG_SUPPORT_CAP        0x00020000 ///< PCH Integrated Graphics Support Capability
+#define R_LPC_CFG_FVEC3                           0x03
+#define B_LPC_CFG_FVEC3_DCMI_CAP                  BIT13      ///< Data Center Manageability Interface (DCMI) Capability
+#define B_LPC_CFG_FVEC3_NM_CAP                    BIT12      ///< Node Manager Capability
+
+#define R_LPC_CFG_MDAP                            0xC0
+#define B_LPC_CFG_MDAP_POLICY_EN                  BIT31
+#define B_LPC_CFG_MDAP_PDMA_EN                    BIT30
+#define B_LPC_CFG_MDAP_VALUE                      0x0001FFFF
+
+//
+// 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 B_LPC_CFG_BC_BILD                         BIT7            ///< BIOS Interface Lock-Down
+#define B_LPC_CFG_BC_BBS                          BIT6            ///< Boot BIOS strap
+#define N_LPC_CFG_BC_BBS                          6
+#define V_LPC_CFG_BC_BBS_SPI                      0               ///< Boot BIOS strapped to SPI
+#define V_LPC_CFG_BC_BBS_LPC                      1               ///< Boot BIOS strapped to LPC
+#define B_LPC_CFG_BC_EISS                         BIT5            ///< Enable InSMM.STS
+#define B_LPC_CFG_BC_TS                           BIT4            ///< Top Swap
+#define B_LPC_CFG_BC_LE                           BIT1            ///< Lock Enable
+#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 N_ESPI_CFG_PCBC_BWRE                      11              ///< BIOS Write Report Enable bit position
+#define B_ESPI_CFG_PCBC_BWRS                      BIT10           ///< BIOS Write Report Status
+#define N_ESPI_CFG_PCBC_BWRS                      10              ///< BIOS Write Report Status bit position
+#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 R_ESPI_SLAVE_CHA_0_CAP_AND_CONF           0x10            ///< Channel 0 Capabilities and Configurations
+#define B_ESPI_SLAVE_BME                          BIT2            ///< Bus Master Enable
+
+//
+// Processor interface registers
+//
+#define R_PCH_IO_NMI_SC                              0x61
+#define B_PCH_IO_NMI_SC_SERR_NMI_STS                 BIT7
+#define B_PCH_IO_NMI_SC_IOCHK_NMI_STS                BIT6
+#define B_PCH_IO_NMI_SC_TMR2_OUT_STS                 BIT5
+#define B_PCH_IO_NMI_SC_REF_TOGGLE                   BIT4
+#define B_PCH_IO_NMI_SC_IOCHK_NMI_EN                 BIT3
+#define B_PCH_IO_NMI_SC_PCI_SERR_EN                  BIT2
+#define B_PCH_IO_NMI_SC_SPKR_DAT_EN                  BIT1
+#define B_PCH_IO_NMI_SC_TIM_CNT2_EN                  BIT0
+#define R_PCH_IO_NMI_EN                              0x70
+#define B_PCH_IO_NMI_EN_NMI_EN                       BIT7
+
+//
+// Reset Generator I/O Port
+//
+#define R_PCH_IO_RST_CNT                             0xCF9
+#define B_PCH_IO_RST_CNT_FULL_RST                    BIT3
+#define B_PCH_IO_RST_CNT_RST_CPU                     BIT2
+#define B_PCH_IO_RST_CNT_SYS_RST                     BIT1
+#define V_PCH_IO_RST_CNT_FULLRESET                   0x0E
+#define V_PCH_IO_RST_CNT_HARDRESET                   0x06
+#define V_PCH_IO_RST_CNT_SOFTRESET                   0x04
+#define V_PCH_IO_RST_CNT_HARDSTARTSTATE              0x02
+#define V_PCH_IO_RST_CNT_SOFTSTARTSTATE              0x00
+
+//
+// RTC register
+//
+#define R_RTC_IO_INDEX                           0x70
+#define R_RTC_IO_TARGET                          0x71
+#define R_RTC_IO_EXT_INDEX                       0x72
+#define R_RTC_IO_EXT_TARGET                      0x73
+#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_EXT_TARGET_ALT                  0x77
+#define R_RTC_IO_REGA                            0x0A
+#define B_RTC_IO_REGA_UIP                        BIT7
+#define R_RTC_IO_REGB                            0x0B
+#define B_RTC_IO_REGB_SET                        0x80
+#define B_RTC_IO_REGB_PIE                        0x40
+#define B_RTC_IO_REGB_AIE                        0x20
+#define B_RTC_IO_REGB_UIE                        0x10
+#define B_RTC_IO_REGB_DM                         0x04
+#define B_RTC_IO_REGB_HOURFORM                   0x02
+#define R_RTC_IO_REGC                            0x0C
+#define R_RTC_IO_REGD                            0x0D
+
+//
+// Private Configuration Register
+// RTC PCRs (PID:RTC)
+//
+#define R_RTC_PCR_CONF                        0x3400               ///< RTC Configuration register
+#define B_RTC_PCR_CONF_BILD                   BIT31                ///< BIOS Interface Lock-Down
+#define B_RTC_PCR_CONF_HPM_HW_DIS             BIT6                 ///< RTC High Power Mode HW Disable
+#define B_RTC_PCR_CONF_UCMOS_LOCK             BIT4                 ///< Upper 128 Byte Lock
+#define B_RTC_PCR_CONF_LCMOS_LOCK             BIT3                 ///< Lower 128 Byte Lock
+#define B_RTC_PCR_CONF_UCMOS_EN               BIT2                 ///< Upper CMOS bank enable
+#define R_RTC_PCR_BUC                         0x3414               ///< Backed Up Control
+#define B_RTC_PCR_BUC_DSO                     BIT4                 ///< Daylight Savings Override
+#define B_RTC_PCR_BUC_TS                      BIT0                 ///< Top Swap
+#define R_RTC_PCR_RTCDCG                      0x3418               ///< RTC Dynamic Clock Gating Control
+#define R_RTC_PCR_RTCDCG_RTCPGCBDCGEN         BIT2                 ///< pgcb_clk (12Mhz) Dynamic Clock Gate Enable
+#define R_RTC_PCR_RTCDCG_RTCPCICLKDCGEN       BIT1                 ///< ipciclk_clk (24 MHz) Dynamic Clock Gate Enable
+#define R_RTC_PCR_RTCDCG_RTCROSIDEDCGEN       BIT0                 ///< rosc_side_clk (120 MHz) Dynamic Clock Gate Enable
+#define R_RTC_PCR_PG1_CP_LO                   0x3428
+#define R_RTC_PCR_PG1_AC_LO                   0x3438
+#define R_RTC_PCR_3F00                        0x3F00
+#define R_RTC_PCR_UIPSMI                      0x3F04               ///< RTC Update In Progress SMI Control
+
+//
+// LPC PCR Registers
+//
+#define R_LPC_PCR_HVMTCTL                     0x3410
+#define R_LPC_PCR_GCFD                        0x3418
+#define B_LPC_PCR_GCFD_SRVR_CLKRUN_EN         BIT2                 ///< Enables the CLKRUN# logic to stop the PCI clocks
+#define R_LPC_PCR_PRC                         0x341C
+#define R_LPC_PCR_PCT                         0x3420
+#define R_LPC_PCR_SCT                         0x3424
+#define R_LPC_PCR_LPCCT                       0x3428
+#define R_LPC_PCR_ULTOR                       0x3500
+
+//
+// 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 V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_RD    0                       ///< Slave Configuration register read from address SCRA[11:0]
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_WR    1                       ///< Slave Configuration register write to address SCRA[11:0]
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_STS   2                       ///< Slave Status register read
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_RS    3                       ///< In-Band reset
+#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_PCERR_SLV1                 0x4024          ///< Peripheral Channel Error for Slave 1
+#define R_ESPI_PCR_VWERR_SLV0                 0x4030          ///< Virtual Wire Channel Error for Slave 0
+#define R_ESPI_PCR_VWERR_SLV1                 0x4034          ///< Virtual Wire Channel Error for Slave 1
+#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 R_ESPI_PCR_SOFTSTRAPS_CS1_EN          BIT12           ///< CS1# Enable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
new file mode 100644
index 0000000000..74789a87ce
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
@@ -0,0 +1,61 @@
+/** @file
+  Register names for PCH LPC/eSPI device
+
+  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_H_", "_PCH_LP_"
+    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_LPC_CNL_H_
+#define _PCH_REGS_LPC_CNL_H_
+
+#define V_LPC_CFG_DID_CNL_H                       0xA300
+#define V_LPC_CFG_DID_CNL_LP                      0x9D80
+
+//
+// PCH-LP Device IDs
+//
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU   0x9D80          ///< PCH LP Mobile
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0           0x9D81          ///< PCH LP Mobile (U)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1           0x9D82          ///< PCH LP Mobile Locked
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2           0x9D83          ///< PCH LP Mobile (Y)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3           0x9D84          ///< PCH LP Mobile (U)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4           0x9D85          ///< PCH LP Mobile (U)
+#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5           0x9D86          ///< PCH LP Mobile (Y)
+
+//
+// PCH-H Desktop LPC Device IDs
+//
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU        0xA300          ///< LPC/eSPI Controller
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU        0xA303          ///< PCH H Mobile H310
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU        0xA304          ///< PCH H Mobile H370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU        0xA305          ///< PCH H Mobile Z390
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU        0xA306          ///< PCH H Mobile Q370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU        0xA309          ///< PCH H Mobile C246
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU        0xA30A          ///< PCH H Mobile C242
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU        0xA30B          ///< PCH H Mobile X399
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU        0xA30C          ///< PCH H Mobile QM370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU        0xA30D          ///< PCH H Mobile HM370
+#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU        0xA30E          ///< PCH H Mobile CM246
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
new file mode 100644
index 0000000000..db6a8c4e95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
@@ -0,0 +1,116 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_P2SB_H_
+#define _PCH_REGS_P2SB_H_
+
+//
+// PCI to P2SB Bridge Registers (D31:F1)
+//
+#define PCI_DEVICE_NUMBER_PCH_P2SB                 31
+#define PCI_FUNCTION_NUMBER_PCH_P2SB               1
+
+#define V_P2SB_CFG_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID
+#define R_P2SB_CFG_SBREG_BAR                       0x10
+#define B_P2SB_CFG_SBREG_RBA                       0xFF000000
+#define R_P2SB_CFG_SBREG_BARH                      0x14
+#define B_P2SB_CFG_SBREG_RBAH                      0xFFFFFFFF
+#define R_P2SB_CFG_VBDF                            0x50
+#define B_P2SB_CFG_VBDF_BUS                        0xFF00
+#define B_P2SB_CFG_VBDF_DEV                        0x00F8
+#define B_P2SB_CFG_VBDF_FUNC                       0x0007
+#define R_P2SB_CFG_ESMBDF                          0x52
+#define B_P2SB_CFG_ESMBDF_BUS                      0xFF00
+#define B_P2SB_CFG_ESMBDF_DEV                      0x00F8
+#define B_P2SB_CFG_ESMBDF_FUNC                     0x0007
+#define R_P2SB_CFG_RCFG                            0x54
+#define B_P2SB_CFG_RCFG_RPRID                      0x0000FF00
+#define B_P2SB_CFG_RCFG_RSE                        BIT0
+#define R_P2SB_CFG_HPTC                            0x60
+#define B_P2SB_CFG_HPTC_AE                         BIT7
+#define B_P2SB_CFG_HPTC_AS                         0x0003
+#define N_HPET_ADDR_ASEL                           12
+#define R_P2SB_CFG_IOAC                            0x64
+#define B_P2SB_CFG_IOAC_AE                         BIT8
+#define B_P2SB_CFG_IOAC_ASEL                       0x00FF
+#define N_IO_APIC_ASEL                             12
+#define R_IO_APIC_INDEX_OFFSET                     0x00
+#define R_IO_APIC_DATA_OFFSET                      0x10
+#define R_IO_APIC_EOI_OFFSET                       0x40
+#define R_P2SB_CFG_IBDF                            0x6C
+#define B_P2SB_CFG_IBDF_BUS                        0xFF00
+#define B_P2SB_CFG_IBDF_DEV                        0x00F8
+#define B_P2SB_CFG_IBDF_FUNC                       0x0007
+#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 B_P2SB_CFG_SBIADDR_DESTID                  0xFF000000
+#define B_P2SB_CFG_SBIADDR_RS                      0x000F0000
+#define B_P2SB_CFG_SBIADDR_OFFSET                  0x0000FFFF
+#define R_P2SB_CFG_SBIDATA                         0xD4
+#define B_P2SB_CFG_SBIDATA_DATA                    0xFFFFFFFF
+#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 B_P2SB_CFG_SBIRID_FBE                      0xF000
+#define B_P2SB_CFG_SBIRID_BAR                      0x0700
+#define B_P2SB_CFG_SBIRID_FID                      0x00FF
+#define R_P2SB_CFG_SBIEXTADDR                      0xDC
+#define B_P2SB_CFG_SBIEXTADDR_ADDR                 0xFFFFFFFF
+
+//
+// Others
+//
+#define R_P2SB_CFG_E0                              0xE0
+#define R_P2SB_CFG_E4                              0xE4
+#define R_P2SB_CFG_E8                              0xE8
+#define R_P2SB_CFG_EA                              0xEA
+#define R_P2SB_CFG_F4                              0xF4
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
new file mode 100644
index 0000000000..af19b93e2d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
@@ -0,0 +1,484 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PCIE_H_
+#define _PCH_REGS_PCIE_H_
+
+//
+// Number of PCIe ports per PCIe controller
+//
+#define PCH_PCIE_CONTROLLER_PORTS                 4u
+
+//
+// PCH PCI Express Root Ports (D28:F0..7, D29:F0..7, D27:F0..7)
+//
+#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1       28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2       29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3       27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS     28
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1  0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2  1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3  2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4  3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5  4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6  5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7  6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8  7
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9  0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10 1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11 2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12 3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_13 4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_14 5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_15 6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_16 7
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_17 0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_18 1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_19 2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_20 3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_21 4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_22 5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_23 6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_24 7
+
+#define V_PCH_PCIE_CFG_VENDOR_ID                  V_PCH_INTEL_VENDOR_ID
+
+
+#define R_PCH_PCIE_CFG_CLIST                          0x40
+#define R_PCH_PCIE_CFG_XCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_XCAP_OFFSET)
+#define R_PCH_PCIE_CFG_DCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCAP_OFFSET)
+#define R_PCH_PCIE_CFG_DCTL                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCTL_OFFSET)
+#define R_PCH_PCIE_CFG_DSTS                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_DSTS_OFFSET)
+#define R_PCH_PCIE_CFG_LCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_LCAP_OFFSET)
+#define B_PCH_PCIE_CFG_LCAP_PN                        0xFF000000
+#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_SLCTL                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_SLCTL_OFFSET)
+#define R_PCH_PCIE_CFG_SLSTS                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_SLSTS_OFFSET)
+#define R_PCH_PCIE_CFG_RCTL                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_RCTL_OFFSET)
+#define R_PCH_PCIE_CFG_RSTS                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_RSTS_OFFSET)
+#define R_PCH_PCIE_CFG_DCAP2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCAP2_OFFSET)
+#define R_PCH_PCIE_CFG_DCTL2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCTL2_OFFSET)
+#define R_PCH_PCIE_CFG_LCTL2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_LCTL2_OFFSET)
+#define R_PCH_PCIE_CFG_LSTS2                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_LSTS2_OFFSET)
+
+#define R_PCH_PCIE_CFG_MID                            0x80
+#define S_PCH_PCIE_CFG_MID                            2
+#define R_PCH_PCIE_CFG_MC                             0x82
+#define S_PCH_PCIE_CFG_MC                             2
+#define R_PCH_PCIE_CFG_MA                             0x84
+#define S_PCH_PCIE_CFG_MA                             4
+#define R_PCH_PCIE_CFG_MD                             0x88
+#define S_PCH_PCIE_CFG_MD                             2
+
+#define R_PCH_PCIE_CFG_SVCAP                          0x90
+#define S_PCH_PCIE_CFG_SVCAP                          2
+#define R_PCH_PCIE_CFG_SVID                           0x94
+#define S_PCH_PCIE_CFG_SVID                           4
+
+#define R_PCH_PCIE_CFG_PMCAP                          0xA0
+#define R_PCH_PCIE_CFG_PMCS                           (R_PCH_PCIE_CFG_PMCAP + R_PCIE_PMCS_OFFST)
+
+#define R_PCH_PCIE_CFG_CCFG                           0xD0
+#define B_PCH_PCIE_CFG_CCFG_UNRS                      (BIT6 | BIT5 | BIT4)
+#define N_PCH_PCIE_CFG_CCFG_UNRS                      4
+
+#define R_PCH_PCIE_CFG_MPC2                           0xD4
+#define S_PCH_PCIE_CFG_MPC2                           4
+#define B_PCH_PCIE_CFG_MPC2_PTNFAE                    BIT12
+#define B_PCH_PCIE_CFG_MPC2_LSTP                      BIT6
+#define B_PCH_PCIE_CFG_MPC2_IEIME                     BIT5
+#define B_PCH_PCIE_CFG_MPC2_ASPMCOEN                  BIT4
+#define B_PCH_PCIE_CFG_MPC2_ASPMCO                    (BIT3 | BIT2)
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_DISABLED           0
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L0S                (1 << 2)
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L1                 (2 << 2)
+#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L0S_L1             (3 << 2)
+#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_HPCE                       BIT30
+#define B_PCH_PCIE_CFG_MPC_MMBNCE                     BIT27
+#define B_PCH_PCIE_CFG_MPC_P8XDE                      BIT26
+#define B_PCH_PCIE_CFG_MPC_IRRCE                      BIT25
+#define B_PCH_PCIE_CFG_MPC_SRL                        BIT23
+#define B_PCH_PCIE_CFG_MPC_UCEL                       (BIT20 | BIT19 | BIT18)
+#define N_PCH_PCIE_CFG_MPC_UCEL                       18
+#define B_PCH_PCIE_CFG_MPC_CCEL                       (BIT17 | BIT16 | BIT15)
+#define N_PCH_PCIE_CFG_MPC_CCEL                       15
+#define B_PCH_PCIE_CFG_MPC_PCIESD                     (BIT14 | BIT13)
+#define N_PCH_PCIE_CFG_MPC_PCIESD                     13
+#define V_PCH_PCIE_CFG_MPC_PCIESD_GEN1                1
+#define V_PCH_PCIE_CFG_MPC_PCIESD_GEN2                2
+#define B_PCH_PCIE_CFG_MPC_MCTPSE                     BIT3
+#define B_PCH_PCIE_CFG_MPC_HPME                       BIT1
+#define N_PCH_PCIE_CFG_MPC_HPME                       1
+#define B_PCH_PCIE_CFG_MPC_PMME                       BIT0
+
+#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
+
+#define R_PCH_PCIE_CFG_RPDCGEN                        0xE1
+#define S_PCH_PCIE_CFG_RPDCGEN                        1
+#define B_PCH_PCIE_CFG_RPDCGEN_RPSCGEN                BIT7
+#define B_PCH_PCIE_CFG_RPDCGEN_PTOCGE                 BIT6
+#define B_PCH_PCIE_CFG_RPDCGEN_LCLKREQEN              BIT5
+#define B_PCH_PCIE_CFG_RPDCGEN_BBCLKREQEN             BIT4
+#define B_PCH_PCIE_CFG_RPDCGEN_SRDBCGEN               BIT2
+#define B_PCH_PCIE_CFG_RPDCGEN_RPDLCGEN               BIT1
+#define B_PCH_PCIE_CFG_RPDCGEN_RPDBCGEN               BIT0
+
+
+#define R_PCH_PCIE_CFG_PWRCTL                         0xE8
+#define B_PCH_PCIE_CFG_PWRCTL_LTSSMRTC                BIT20
+#define B_PCH_PCIE_CFG_PWRCTL_WPDMPGEP                BIT17
+#define B_PCH_PCIE_CFG_PWRCTL_DBUPI                   BIT15
+#define B_PCH_PCIE_CFG_PWRCTL_TXSWING                 BIT13
+#define B_PCH_PCIE_CFG_PWRCTL_RPL1SQPOL               BIT1
+#define B_PCH_PCIE_CFG_PWRCTL_RPDTSQPOL               BIT0
+
+#define R_PCH_PCIE_CFG_DC                             0xEC
+#define B_PCH_PCIE_CFG_DC_PCIBEM                      BIT2
+
+#define R_PCH_PCIE_CFG_PHYCTL2                        0xF5
+#define B_PCH_PCIE_CFG_PHYCTL2_TDFT                   (BIT7 | BIT6)
+#define B_PCH_PCIE_CFG_PHYCTL2_TXCFGCHGWAIT           (BIT5 | BIT4)
+#define N_PCH_PCIE_CFG_PHYCTL2_TXCFGCHGWAIT           4
+#define B_PCH_PCIE_CFG_PHYCTL2_PXPG3PLLOFFEN          BIT1
+#define B_PCH_PCIE_CFG_PHYCTL2_PXPG2PLLOFFEN          BIT0
+
+#define R_PCH_PCIE_CFG_IOSFSBCS                       0xF7
+#define B_PCH_PCIE_CFG_IOSFSBCS_SCPTCGE               BIT6
+#define B_PCH_PCIE_CFG_IOSFSBCS_SIID                  (BIT3 | BIT2)
+
+#define R_PCH_PCIE_CFG_STRPFUSECFG                    0xFC
+#define B_PCH_PCIE_CFG_STRPFUSECFG_PXIP               (BIT27 | BIT26 | BIT25 | BIT24)
+#define N_PCH_PCIE_CFG_STRPFUSECFG_PXIP               24
+#define B_PCH_PCIE_CFG_STRPFUSECFG_RPC                (BIT15 | BIT14)
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_1_1_1_1        0
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_2_1_1          1
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_2_2            2
+#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_4              3
+#define N_PCH_PCIE_CFG_STRPFUSECFG_RPC                14
+#define B_PCH_PCIE_CFG_STRPFUSECFG_MODPHYIOPMDIS      BIT9
+#define B_PCH_PCIE_CFG_STRPFUSECFG_PLLSHTDWNDIS       BIT8
+#define B_PCH_PCIE_CFG_STRPFUSECFG_STPGATEDIS         BIT7
+#define B_PCH_PCIE_CFG_STRPFUSECFG_ASPMDIS            BIT6
+#define B_PCH_PCIE_CFG_STRPFUSECFG_LDCGDIS            BIT5
+#define B_PCH_PCIE_CFG_STRPFUSECFG_LTCGDIS            BIT4
+#define B_PCH_PCIE_CFG_STRPFUSECFG_CDCGDIS            BIT3
+#define B_PCH_PCIE_CFG_STRPFUSECFG_DESKTOPMOB         BIT2
+
+//
+//PCI Express Extended Capability Registers
+//
+
+#define R_PCH_PCIE_CFG_EXCAP_OFFSET                   0x100
+
+#define R_PCH_PCIE_CFG_EX_AECH                        0x100 ///< Advanced Error Reporting Capability Header
+#define V_PCH_PCIE_CFG_EX_AEC_CV                      0x1
+#define R_PCH_PCIE_CFG_EX_UEM                         (R_PCH_PCIE_CFG_EX_AECH + R_PCIE_EX_UEM_OFFSET) // Uncorrectable Error Mask
+
+#define R_PCH_PCIE_CFG_EX_CES                         0x110 ///< Correctable Error Status
+#define B_PCH_PCIE_CFG_EX_CES_BD                      BIT7  ///< Bad DLLP Status
+#define B_PCH_PCIE_CFG_EX_CES_BT                      BIT6  ///< Bad TLP Status
+#define B_PCH_PCIE_CFG_EX_CES_RE                      BIT0  ///< Receiver Error Status
+
+
+//CES.RE, CES.BT, CES.BD
+
+#define R_PCH_PCIE_CFG_EX_ACSECH                      0x140 ///< ACS Extended Capability Header
+#define V_PCH_PCIE_CFG_EX_ACS_CV                      0x1
+#define R_PCH_PCIE_CFG_EX_ACSCAPR                     (R_PCH_PCIE_CFG_EX_ACSECH + R_PCIE_EX_ACSCAPR_OFFSET)
+
+#define R_PCH_PCIE_CFG_EX_L1SECH                      0x200 ///< L1 Sub-States Extended Capability Header
+#define V_PCH_PCIE_CFG_EX_L1S_CV                      0x1
+#define R_PCH_PCIE_CFG_EX_L1SCAP                      (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCAP_OFFSET)
+#define R_PCH_PCIE_CFG_EX_L1SCTL1                     (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCTL1_OFFSET)
+#define R_PCH_PCIE_CFG_EX_L1SCTL2                     (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCTL2_OFFSET)
+
+#define R_PCH_PCIE_CFG_EX_SPEECH                      0x220 ///< Secondary PCI Express Extended Capability Header
+#define V_PCH_PCIE_CFG_EX_SPEECH_CV                   0x1
+#define R_PCH_PCIE_CFG_EX_LCTL3                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LCTL3_OFFSET)
+#define R_PCH_PCIE_CFG_EX_LES                         (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LES_OFFSET)
+#define R_PCH_PCIE_CFG_EX_LECTL                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L01EC_OFFSET)
+#define B_PCH_PCIE_CFG_EX_LECTL_UPTPH                 (BIT14 | BIT13 | BIT12)
+#define N_PCH_PCIE_CFG_EX_LECTL_UPTPH                 12
+#define B_PCH_PCIE_CFG_EX_LECTL_UPTP                  0x0F00
+#define N_PCH_PCIE_CFG_EX_LECTL_UPTP                  8
+#define B_PCH_PCIE_CFG_EX_LECTL_DPTPH                 (BIT6 | BIT5 | BIT4)
+#define N_PCH_PCIE_CFG_EX_LECTL_DPTPH                 4
+#define B_PCH_PCIE_CFG_EX_LECTL_DPTP                  0x000F
+#define N_PCH_PCIE_CFG_EX_LECTL_DPTP                  0
+
+#define R_PCH_PCIE_CFG_EX_L01EC                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L01EC_OFFSET)
+#define R_PCH_PCIE_CFG_EX_L23EC                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L23EC_OFFSET)
+
+#define R_PCH_PCIE_CFG_PCIERTP1                       0x300
+#define R_PCH_PCIE_CFG_PCIERTP2                       0x304
+#define R_PCH_PCIE_CFG_PCIENFTS                       0x314
+#define R_PCH_PCIE_CFG_PCIEL0SC                       0x318
+
+#define R_PCH_PCIE_CFG_PCIECFG2                       0x320
+#define B_PCH_PCIE_CFG_PCIECFG2_LBWSSTE               BIT30
+#define B_PCH_PCIE_CFG_PCIECFG2_RLLG3R                BIT27
+#define B_PCH_PCIE_CFG_PCIECFG2_CROAOV                BIT24
+#define B_PCH_PCIE_CFG_PCIECFG2_CROAOE                BIT23
+#define B_PCH_PCIE_CFG_PCIECFG2_CRSREN                BIT22
+#define B_PCH_PCIE_CFG_PCIECFG2_PMET                  (BIT21 | BIT20)
+#define V_PCH_PCIE_CFG_PCIECFG2_PMET                  1
+#define N_PCH_PCIE_CFG_PCIECFG2_PMET                  20
+
+#define R_PCH_PCIE_CFG_PCIEDBG                        0x324
+#define B_PCH_PCIE_CFG_PCIEDBG_LBWSSTE                BIT30
+#define B_PCH_PCIE_CFG_PCIEDBG_USSP                   (BIT27 | BIT26)
+#define B_PCH_PCIE_CFG_PCIEDBG_LGCLKSQEXITDBTIMERS    (BIT25 | BIT24)
+#define B_PCH_PCIE_CFG_PCIEDBG_CTONFAE                BIT14
+#define B_PCH_PCIE_CFG_PCIEDBG_SQOL0                  BIT7
+#define B_PCH_PCIE_CFG_PCIEDBG_SPCE                   BIT5
+#define B_PCH_PCIE_CFG_PCIEDBG_LR                     BIT4
+
+#define R_PCH_PCIE_CFG_PCIESTS1                              0x328
+#define B_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE                    0xFF000000
+#define N_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE                    24
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DETRDY             0x01
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DETRDYECINP1CG     0x0E
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_L0                 0x33
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DISWAIT            0x5E
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DISWAITPG          0x60
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_RECOVERYSPEEDREADY 0x6C
+#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_RECOVERYLNK2DETECT 0x6F
+
+
+#define B_PCH_PCIE_CFG_PCIESTS1_LNKSTAT               (BIT22 | BIT21 | BIT20 | BIT19)
+#define N_PCH_PCIE_CFG_PCIESTS1_LNKSTAT               19
+#define V_PCH_PCIE_CFG_PCIESTS1_LNKSTAT_L0            0x7
+
+#define R_PCH_PCIE_CFG_PCIESTS2                       0x32C
+#define B_PCH_PCIE_CFG_PCIESTS2_P4PNCCWSSCMES         BIT31
+#define B_PCH_PCIE_CFG_PCIESTS2_P3PNCCWSSCMES         BIT30
+#define B_PCH_PCIE_CFG_PCIESTS2_P2PNCCWSSCMES         BIT29
+#define B_PCH_PCIE_CFG_PCIESTS2_P1PNCCWSSCMES         BIT28
+#define B_PCH_PCIE_CFG_PCIESTS2_CLRE                  0x0000F000
+#define N_PCH_PCIE_CFG_PCIESTS2_CLRE                  12
+
+#define R_PCH_PCIE_CFG_PCIEALC                        0x338
+#define B_PCH_PCIE_CFG_PCIEALC_ITLRCLD                BIT29
+#define B_PCH_PCIE_CFG_PCIEALC_ILLRCLD                BIT28
+#define B_PCH_PCIE_CFG_PCIEALC_BLKDQDA                BIT26
+
+
+#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_PHYCTL4                        0x408
+#define B_PCH_PCIE_CFG_PHYCTL4_SQDIS                  BIT27
+
+#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_PCIEPMECTL2                    0x424
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_PHYCLPGE           BIT11
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_FDCPGE             BIT8
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_DETSCPGE           BIT7
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_L23RDYSCPGE        BIT6
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_DISSCPGE           BIT5
+#define B_PCH_PCIE_CFG_PCIEPMECTL2_L1SCPGE            BIT4
+
+#define R_PCH_PCIE_CFG_PCE                            0x428
+#define B_PCH_PCIE_CFG_PCE_HAE                        BIT5
+#define B_PCH_PCIE_CFG_PCE_PMCRE                      BIT0
+
+#define R_PCH_PCIE_CFG_EQCFG1                         0x450
+#define S_PCH_PCIE_CFG_EQCFG1                         4
+#define B_PCH_PCIE_CFG_EQCFG1_REC                     0xFF000000
+#define N_PCH_PCIE_CFG_EQCFG1_REC                     24
+#define B_PCH_PCIE_CFG_EQCFG1_REIFECE                 BIT23
+#define N_PCH_PCIE_CFG_EQCFG1_LERSMIE                 21
+#define B_PCH_PCIE_CFG_EQCFG1_LEP23B                  BIT18
+#define B_PCH_PCIE_CFG_EQCFG1_LEP3B                   BIT17
+#define B_PCH_PCIE_CFG_EQCFG1_RTLEPCEB                BIT16
+#define B_PCH_PCIE_CFG_EQCFG1_RTPCOE                  BIT15
+#define B_PCH_PCIE_CFG_EQCFG1_HPCMQE                  BIT13
+#define B_PCH_PCIE_CFG_EQCFG1_HAED                    BIT12
+#define B_PCH_PCIE_CFG_EQCFG1_EQTS2IRRC               BIT7
+#define B_PCH_PCIE_CFG_EQCFG1_TUPP                    BIT1
+
+#define R_PCH_PCIE_CFG_RTPCL1                         0x454
+#define B_PCH_PCIE_CFG_RTPCL1_PCM                     BIT31
+#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL2PL4             0x3F000000
+#define B_PCH_PCIE_CFG_RTPCL1_RTPOSTCL1PL3            0xFC0000
+#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL1PL2             0x3F000
+#define B_PCH_PCIE_CFG_RTPCL1_RTPOSTCL0PL1            0xFC0
+#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL0PL0             0x3F
+
+#define R_PCH_PCIE_CFG_RTPCL2                         0x458
+#define B_PCH_PCIE_CFG_RTPCL2_RTPOSTCL3PL             0x3F000
+#define B_PCH_PCIE_CFG_RTPCL2_RTPRECL3PL6             0xFC0
+#define B_PCH_PCIE_CFG_RTPCL2_RTPOSTCL2PL5            0x3F
+
+#define R_PCH_PCIE_CFG_RTPCL3                         0x45C
+#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL7                0x3F000000
+#define B_PCH_PCIE_CFG_RTPCL3_RTPOSTCL6               0xFC0000
+#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL6                0x3F000
+#define B_PCH_PCIE_CFG_RTPCL3_RTPOSTCL5               0xFC0
+#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL5PL10            0x3F
+
+#define R_PCH_PCIE_CFG_RTPCL4                         0x460
+#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL9               0x3F000000
+#define B_PCH_PCIE_CFG_RTPCL4_RTPRECL9                0xFC0000
+#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL8               0x3F000
+#define B_PCH_PCIE_CFG_RTPCL4_RTPRECL8                0xFC0
+#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL7               0x3F
+
+#define R_PCH_PCIE_CFG_FOMS                           0x464
+#define B_PCH_PCIE_CFG_FOMS_I                         (BIT30 | BIT29)
+#define N_PCH_PCIE_CFG_FOMS_I                         29
+#define B_PCH_PCIE_CFG_FOMS_LN                        0x1F000000
+#define N_PCH_PCIE_CFG_FOMS_LN                        24
+#define B_PCH_PCIE_CFG_FOMS_FOMSV                     0x00FFFFFF
+#define B_PCH_PCIE_CFG_FOMS_FOMSV0                    0x000000FF
+#define N_PCH_PCIE_CFG_FOMS_FOMSV0                    0
+#define B_PCH_PCIE_CFG_FOMS_FOMSV1                    0x0000FF00
+#define N_PCH_PCIE_CFG_FOMS_FOMSV1                    8
+#define B_PCH_PCIE_CFG_FOMS_FOMSV2                    0x00FF0000
+#define N_PCH_PCIE_CFG_FOMS_FOMSV2                    16
+
+#define R_PCH_PCIE_CFG_HAEQ                           0x468
+#define B_PCH_PCIE_CFG_HAEQ_HAPCCPI                   (BIT31 | BIT30 | BIT29 | BIT28)
+#define N_PCH_PCIE_CFG_HAEQ_HAPCCPI                   28
+#define B_PCH_PCIE_CFG_HAEQ_MACFOMC                   BIT19
+
+#define R_PCH_PCIE_CFG_LTCO1                          0x470
+#define B_PCH_PCIE_CFG_LTCO1_L1TCOE                   BIT25
+#define B_PCH_PCIE_CFG_LTCO1_L0TCOE                   BIT24
+#define B_PCH_PCIE_CFG_LTCO1_L1TPOSTCO                0xFC0000
+#define N_PCH_PCIE_CFG_LTCO1_L1TPOSTCO                18
+#define B_PCH_PCIE_CFG_LTCO1_L1TPRECO                 0x3F000
+#define N_PCH_PCIE_CFG_LTCO1_L1TPRECO                 12
+#define B_PCH_PCIE_CFG_LTCO1_L0TPOSTCO                0xFC0
+#define N_PCH_PCIE_CFG_LTCO1_L0TPOSTCO                6
+#define B_PCH_PCIE_CFG_LTCO1_L0TPRECO                 0x3F
+#define N_PCH_PCIE_CFG_LTCO1_L0TPRECO                 0
+
+#define R_PCH_PCIE_CFG_LTCO2                          0x474
+#define B_PCH_PCIE_CFG_LTCO2_L3TCOE                   BIT25
+#define B_PCH_PCIE_CFG_LTCO2_L2TCOE                   BIT24
+#define B_PCH_PCIE_CFG_LTCO2_L3TPOSTCO                0xFC0000
+#define B_PCH_PCIE_CFG_LTCO2_L3TPRECO                 0x3F000
+#define B_PCH_PCIE_CFG_LTCO2_L2TPOSTCO                0xFC0
+#define B_PCH_PCIE_CFG_LTCO2_L2TPRECO                 0x3F
+
+#define R_PCH_PCIE_CFG_G3L0SCTL                       0x478
+#define B_PCH_PCIE_CFG_G3L0SCTL_G3UCNFTS              0x0000FF00
+#define B_PCH_PCIE_CFG_G3L0SCTL_G3CCNFTS              0x000000FF
+
+#define R_PCH_PCIE_CFG_EQCFG2                         0x47C
+#define B_PCH_PCIE_CFG_EQCFG2_NTIC                    0xFF000000
+#define B_PCH_PCIE_CFG_EQCFG2_EMD                     BIT23
+#define B_PCH_PCIE_CFG_EQCFG2_NTSS                    (BIT22 | BIT21 | BIT20)
+#define B_PCH_PCIE_CFG_EQCFG2_PCET                    (BIT19 | BIT18 | BIT17 | BIT16)
+#define N_PCH_PCIE_CFG_EQCFG2_PCET                    16
+#define B_PCH_PCIE_CFG_EQCFG2_HAPCSB                  (BIT15 | BIT14 | BIT13 | BIT12)
+#define N_PCH_PCIE_CFG_EQCFG2_HAPCSB                  12
+#define B_PCH_PCIE_CFG_EQCFG2_NTEME                   BIT11
+#define B_PCH_PCIE_CFG_EQCFG2_MPEME                   BIT10
+#define B_PCH_PCIE_CFG_EQCFG2_REWMETM                 (BIT9 | BIT8)
+#define B_PCH_PCIE_CFG_EQCFG2_REWMET                  0xFF
+
+#define R_PCH_PCIE_CFG_MM                             0x480
+#define B_PCH_PCIE_CFG_MM_MSST                        0xFFFFFF00
+#define N_PCH_PCIE_CFG_MM_MSST                        8
+#define B_PCH_PCIE_CFG_MM_MSS                         0xFF
+
+//
+// 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 B_SPX_PCR_PCD_RP1CH                   BIT3                    ///< Port 1 config hide
+#define B_SPX_PCR_PCD_RP2FN                   (BIT6 | BIT5 | BIT4)    ///< Port 2 Function Number
+#define B_SPX_PCR_PCD_RP2CH                   BIT7                    ///< Port 2 config hide
+#define B_SPX_PCR_PCD_RP3FN                   (BIT10 | BIT9 | BIT8)   ///< Port 3 Function Number
+#define B_SPX_PCR_PCD_RP3CH                   BIT11                   ///< Port 3 config hide
+#define B_SPX_PCR_PCD_RP4FN                   (BIT14 | BIT13 | BIT12) ///< Port 4 Function Number
+#define B_SPX_PCR_PCD_RP4CH                   BIT15                   ///< Port 4 config hide
+#define S_SPX_PCR_PCD_RP_FIELD                4                       ///< 4 bits for each RP FN
+#define B_SPX_PCR_PCD_P1D                     BIT16                   ///< Port 1 disable
+#define B_SPX_PCR_PCD_P2D                     BIT17                   ///< Port 2 disable
+#define B_SPX_PCR_PCD_P3D                     BIT18                   ///< Port 3 disable
+#define B_SPX_PCR_PCD_P4D                     BIT19                   ///< Port 4 disable
+#define B_SPX_PCR_PCD_SRL                     BIT31                   ///< Secured Register Lock
+
+#define R_SPX_PCR_PCIEHBP                     0x0004                  ///< PCI Express high-speed bypass
+#define B_SPX_PCR_PCIEHBP_PCIEHBPME           BIT0                    ///< PCIe HBP mode enable
+#define B_SPX_PCR_PCIEHBP_PCIEGMO             (BIT2 | BIT1)           ///< PCIe gen mode override
+#define B_SPX_PCR_PCIEHBP_PCIETIL0O           BIT3                    ///< PCIe transmitter-in-L0 override
+#define B_SPX_PCR_PCIEHBP_PCIERIL0O           BIT4                    ///< PCIe receiver-in-L0 override
+#define B_SPX_PCR_PCIEHBP_PCIELRO             BIT5                    ///< PCIe link recovery override
+#define B_SPX_PCR_PCIEHBP_PCIELDO             BIT6                    ///< PCIe link down override
+#define B_SPX_PCR_PCIEHBP_PCIESSM             BIT7                    ///< PCIe SKP suppression mode
+#define B_SPX_PCR_PCIEHBP_PCIESST             BIT8                    ///< PCIe suppress SKP transmission
+#define B_SPX_PCR_PCIEHBP_PCIEHBPPS           (BIT13 | BIT12)         ///< PCIe HBP port select
+#define B_SPX_PCR_PCIEHBP_CRCSEL              (BIT15 | BIT14)         ///< CRC select
+#define B_SPX_PCR_PCIEHBP_PCIEHBPCRC          0xFFFF0000              ///< PCIe HBP CRC
+
+//
+// ICC PCR (PID: ICC)
+//
+#define R_ICC_PCR_TMCSRCCLK                   0x1000                  ///< Timing Control SRC Clock Register
+#define R_ICC_PCR_TMCSRCCLK2                  0x1004                  ///< Timing Control SRC Clock Register 2
+#define R_ICC_PCR_MSKCKRQ                     0x100C                  ///< Mask Control CLKREQ
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
new file mode 100644
index 0000000000..ed1668300a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
@@ -0,0 +1,73 @@
+/** @file
+  Register names for PCH private chipset 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
+  - 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_H_", "_PCH_LP_"
+    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 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_OPIPHY     0xAC
+#define PID_MODPHY0    0xAB
+#define PID_MODPHY1    0xAA
+#define PID_USB2       0xCA
+#define PID_DMI        0x88
+#define PID_PSTH       0x89
+#define PID_DSP        0xD7
+#define PID_ESPISPI    0x72
+#define PID_FIA        0xCF
+#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_SERIALIO   0xCB
+#define PID_LPC        0xC7
+#define PID_SMB        0xC6
+#define PID_ITSS       0xC4
+#define PID_RTC_HOST   0xC3
+#define PID_PSF6       0x7F
+#define PID_PSF7       0x7E
+#define PID_PSF8       0x7D
+#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_CSME12     0x9C
+
+#define PID_CSME0      0x90
+#define PID_CSME_PSF   0x8F
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
new file mode 100644
index 0000000000..dcecc633a1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
@@ -0,0 +1,670 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PMC_H_
+#define _PCH_REGS_PMC_H_
+
+//
+// PMC Registers (D31:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_PMC                31
+#define PCI_FUNCTION_NUMBER_PCH_PMC              2
+
+#define R_PMC_CFG_BASE                           0x10
+#define B_PMC_CFG_PWRM_BASE_MASK                 0xFFFF0000                    ///< PWRM must be 64KB alignment to align the source decode.
+
+//
+// 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_BM                     BIT4
+#define B_ACPI_IO_PM1_STS_TMROF                  BIT0
+#define N_ACPI_IO_PM1_STS_WAK                    15
+#define N_ACPI_IO_PM1_STS_PCIEXP_WAKE_STS        14
+#define N_ACPI_IO_PM1_STS_PRBTNOR                11
+#define N_ACPI_IO_PM1_STS_RTC                    10
+#define N_ACPI_IO_PM1_STS_PWRBTN                 8
+#define N_ACPI_IO_PM1_STS_GBL                    5
+#define N_ACPI_IO_PM1_STS_BM                     4
+#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_RTC                     BIT10
+#define B_ACPI_IO_PM1_EN_PWRBTN                  BIT8
+#define B_ACPI_IO_PM1_EN_GBL                     BIT5
+#define B_ACPI_IO_PM1_EN_TMROF                   BIT0
+#define N_ACPI_IO_PM1_EN_RTC                     10
+#define N_ACPI_IO_PM1_EN_PWRBTN                  8
+#define N_ACPI_IO_PM1_EN_GBL                     5
+#define N_ACPI_IO_PM1_EN_TMROF                   0
+
+#define R_ACPI_IO_PM1_CNT                        0x04
+#define S_ACPI_IO_PM1_CNT                        4
+#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_GBL_RLS                BIT2
+#define B_ACPI_IO_PM1_CNT_BM_RLD                 BIT1
+#define B_ACPI_IO_PM1_CNT_SCI_EN                 BIT0
+
+#define R_ACPI_IO_PM1_TMR                        0x08
+#define V_ACPI_IO_PM1_TMR_FREQUENCY              3579545
+#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_USB3                  BIT31
+#define B_ACPI_IO_SMI_EN_GPIO_UNLOCK_SMI              BIT27
+#define B_ACPI_IO_SMI_EN_LEGACY_USB2                  BIT17
+#define B_ACPI_IO_SMI_EN_PERIODIC                     BIT14
+#define B_ACPI_IO_SMI_EN_TCO                          BIT13
+#define B_ACPI_IO_SMI_EN_MCSMI                        BIT11
+#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_ON_SLP_EN                    BIT4
+#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_GPIO_UNLOCK                  27
+#define N_ACPI_IO_SMI_EN_INTEL_USB2                   18
+#define N_ACPI_IO_SMI_EN_LEGACY_USB2                  17
+#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_BIOS_RLS                     7
+#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 N_ACPI_IO_SMI_EN_BIOS                         2
+#define N_ACPI_IO_SMI_EN_EOS                          1
+#define N_ACPI_IO_SMI_EN_GBL_SMI                      0
+
+#define R_ACPI_IO_SMI_STS                             0x34
+#define S_ACPI_IO_SMI_STS                             4
+#define B_ACPI_IO_SMI_STS_LEGACY_USB3                 BIT31
+#define B_ACPI_IO_SMI_STS_GPIO_UNLOCK                 BIT27
+#define B_ACPI_IO_SMI_STS_SPI                         BIT26
+#define B_ACPI_IO_SMI_STS_MONITOR                     BIT21
+#define B_ACPI_IO_SMI_STS_PCI_EXP                     BIT20
+#define B_ACPI_IO_SMI_STS_PATCH                       BIT19
+#define B_ACPI_IO_SMI_STS_INTEL_USB2                  BIT18
+#define B_ACPI_IO_SMI_STS_LEGACY_USB2                 BIT17
+#define B_ACPI_IO_SMI_STS_SMBUS                       BIT16
+#define B_ACPI_IO_SMI_STS_SERIRQ                      BIT15
+#define B_ACPI_IO_SMI_STS_PERIODIC                    BIT14
+#define B_ACPI_IO_SMI_STS_TCO                         BIT13
+#define B_ACPI_IO_SMI_STS_DEVMON                      BIT12
+#define B_ACPI_IO_SMI_STS_MCSMI                       BIT11
+#define B_ACPI_IO_SMI_STS_GPIO_SMI                    BIT10
+#define B_ACPI_IO_SMI_STS_GPE0                        BIT9
+#define B_ACPI_IO_SMI_STS_PM1_STS_REG                 BIT8
+#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_LEGACY_USB                  BIT3
+#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_GPIO_UNLOCK                 27
+#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_PATCH                       19
+#define N_ACPI_IO_SMI_STS_INTEL_USB2                  18
+#define N_ACPI_IO_SMI_STS_LEGACY_USB2                 17
+#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_DEVMON                      12
+#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 N_ACPI_IO_SMI_STS_BIOS                        2
+
+#define R_ACPI_IO_GPE_CNTL                            0x40
+#define B_ACPI_IO_GPE_CNTL_SWGPE_CTRL                 BIT17
+
+#define R_ACPI_IO_DEVACT_STS                          0x44
+#define S_ACPI_IO_DEVACT_STS                          2
+#define B_ACPI_IO_DEVACT_STS_MASK                     0x13E1
+#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 B_ACPI_IO_DEVACT_STS_D0_TRP                   BIT0
+#define N_ACPI_IO_DEVACT_STS_KBC                      12
+#define N_ACPI_IO_DEVACT_STS_PIRQDH                   9
+#define N_ACPI_IO_DEVACT_STS_PIRQCG                   8
+#define N_ACPI_IO_DEVACT_STS_PIRQBF                   7
+#define N_ACPI_IO_DEVACT_STS_PIRQAE                   6
+
+#define R_ACPI_IO_PM2_CNT                             0x50
+#define B_ACPI_IO_PM2_CNT_ARB_DIS                     BIT0
+
+#define R_ACPI_IO_OC_WDT_CTL                          0x54
+#define B_ACPI_IO_OC_WDT_CTL_RLD                      BIT31
+#define B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS              BIT25
+#define B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS           BIT24
+#define B_ACPI_IO_OC_WDT_CTL_FORCE_ALL                BIT15
+#define B_ACPI_IO_OC_WDT_CTL_EN                       BIT14
+#define B_ACPI_IO_OC_WDT_CTL_ICCSURV                  BIT13
+#define B_ACPI_IO_OC_WDT_CTL_LCK                      BIT12
+#define B_ACPI_IO_OC_WDT_CTL_TOV_MASK                 0x3FF
+#define B_ACPI_IO_OC_WDT_CTL_FAILURE_STS              BIT23
+#define B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS           BIT22
+#define B_ACPI_IO_OC_WDT_CTL_AFTER_POST               0x3F0000
+#define V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE           1
+#define V_ACPI_IO_OC_WDT_CTL_STATUS_OK                0
+
+#define R_ACPI_IO_GPE0_STS_31_0                    0x60
+#define R_ACPI_IO_GPE0_STS_63_32                   0x64
+#define R_ACPI_IO_GPE0_STS_95_64                   0x68
+#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_GPIO_TIER_2      BIT15
+#define B_ACPI_IO_GPE0_STS_127_96_PME_B0           BIT13
+#define B_ACPI_IO_GPE0_STS_127_96_ME_SCI           BIT12
+#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_PCI_EXP          BIT9
+#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_TC0SCI           BIT6
+#define B_ACPI_IO_GPE0_STS_127_96_SWGPE            BIT2
+#define B_ACPI_IO_GPE0_STS_127_96_HOT_PLUG         BIT1
+#define N_ACPI_IO_GPE0_STS_127_96_PME_B0           13
+#define N_ACPI_IO_GPE0_STS_127_96_PME              11
+#define N_ACPI_IO_GPE0_STS_127_96_BATLOW           10
+#define N_ACPI_IO_GPE0_STS_127_96_PCI_EXP          9
+#define N_ACPI_IO_GPE0_STS_127_96_RI               8
+#define N_ACPI_IO_GPE0_STS_127_96_SMB_WAK          7
+#define N_ACPI_IO_GPE0_STS_127_96_TC0SCI           6
+#define N_ACPI_IO_GPE0_STS_127_96_SWGPE            2
+#define N_ACPI_IO_GPE0_STS_127_96_HOT_PLUG         1
+
+#define R_ACPI_IO_GPE0_EN_31_0                     0x70
+#define R_ACPI_IO_GPE0_EN_63_32                    0x74
+#define R_ACPI_IO_GPE0_EN_95_64                    0x78
+#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_USB_CON_DSX_EN    BIT17
+#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_PCI_EXP           BIT9
+#define B_ACPI_IO_GPE0_EN_127_96_RI                BIT8
+#define B_ACPI_IO_GPE0_EN_127_96_TC0SCI            BIT6
+#define B_ACPI_IO_GPE0_EN_127_96_SWGPE             BIT2
+#define B_ACPI_IO_GPE0_EN_127_96_HOT_PLUG          BIT1
+#define N_ACPI_IO_GPE0_EN_127_96_PME_B0            13
+#define N_ACPI_IO_GPE0_EN_127_96_USB3              12
+#define N_ACPI_IO_GPE0_EN_127_96_PME               11
+#define N_ACPI_IO_GPE0_EN_127_96_BATLOW            10
+#define N_ACPI_IO_GPE0_EN_127_96_PCI_EXP           9
+#define N_ACPI_IO_GPE0_EN_127_96_RI                8
+#define N_ACPI_IO_GPE0_EN_127_96_TC0SCI            6
+#define N_ACPI_IO_GPE0_EN_127_96_SWGPE             2
+#define N_ACPI_IO_GPE0_EN_127_96_HOT_PLUG          1
+
+
+//
+// TCO register I/O map
+//
+#define R_TCO_IO_RLD                                 0x0
+#define R_TCO_IO_DAT_IN                              0x2
+#define R_TCO_IO_DAT_OUT                             0x3
+#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 R_TCO_IO_TCO2_STS                            0x06
+#define S_TCO_IO_TCO2_STS                            2
+#define B_TCO_IO_TCO2_STS_SMLINK_SLV_SMI             BIT4
+#define B_TCO_IO_TCO2_STS_BAD_BIOS                   BIT3
+#define B_TCO_IO_TCO2_STS_BOOT                       BIT2
+#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 B_TCO_IO_TCO1_CNT_TMR_HLT                    BIT11
+#define B_TCO_IO_TCO1_CNT_NR_MSUS                    BIT0  //NO_REBOOT
+
+#define R_TCO_IO_TCO2_CNT                            0x0A
+#define S_TCO_IO_TCO2_CNT                            2
+#define B_TCO_IO_TCO2_CNT_OS_POLICY                  0x0030
+#define B_TCO_IO_TCO2_CNT_GPI11_ALERT_DISABLE        0x0008
+#define B_TCO_IO_TCO2_CNT_INTRD_SEL                  0x0006
+#define N_TCO_IO_TCO2_CNT_INTRD_SEL                  2
+
+#define R_TCO_IO_MESSAGE1                            0x0C
+#define R_TCO_IO_MESSAGE2                            0x0D
+#define R_TCO_IO_TWDS                                0x0E           ///< TCO_WDSTATUS register.
+#define R_TCO_IO_LE                                  0x10           ///< LEGACY_ELIM register
+#define B_TCO_IO_LE_IRQ12_CAUSE                      BIT1
+#define B_TCO_IO_LE_IRQ1_CAUSE                       BIT0
+#define R_TCO_IO_TMR                                 0x12
+
+//
+// PWRM Registers for IPC interface
+//
+#define R_PMC_PWRM_IPC_CMD                                  0x00                        ///< IPC command
+#define N_PMC_PWRM_IPC_CMD_CMD_ID                           12                          ///< IPC command.cmd.ID
+#define N_PMC_PWRM_IPC_CMD_SIZE                             16                          ///< IPC command.size
+#define B_PMC_PWRM_IPC_CMD_SIZE_MASK                        0x00FF0000                  ///< IPC command.size mask Bits[23:16]
+#define N_PMC_PWRM_IPC_CMD_COMMAND                          0                           ///< IPC command.cmd.Command
+#define B_PMC_PWRM_IPC_CMD_COMMAND_MASK                     0x000000FF                  ///< IPC command.size mask Bits[07:00]
+#define V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL                 0xA1                        ///< IPC commmand to control S0ix policies RCOMP
+#define V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE                0xA4                        ///< IPC commmand to control NPK Power State
+#define V_PMC_PWRM_IPC_CMD_COMMAND_PROXY                    0xAA                        ///< Proxy access to SOC registers
+#define V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ                   0                        ///< Read command
+#define V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE                  1                        ///< Write command
+#define V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI                     2                        ///< parameter to access NMI control register
+#define R_PMC_PWRM_IPC_STS                                  0x04                        ///< IPC Status
+#define B_PMC_PWRM_IPC_STS_BUSY                             BIT0                        ///< IPC Status Busy Bit
+#define B_PMC_PWRM_IPC_STS_ERROR                            BIT1                        ///< IPC Status Error Bit
+#define N_PMC_PWRM_IPC_STS_ERR_CODE                         BIT16                       ///< IPC Status Error status
+#define B_PMC_PWRM_IPC_STS_ERR_CODE_MASK                    0x00FF0000                  ///< IPC Status Error status mask[23:16]
+#define R_PMC_PWRM_IPC_SPTR                                 0x08                        ///< IPC Source Pointer
+#define R_PMC_PWRM_IPC_DPTR                                 0x0C                        ///< IPC Destination Pointer
+#define R_PMC_PWRM_IPC_WBUF0                                0x80                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_WBUF1                                0x84                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_WBUF2                                0x88                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_WBUF3                                0x8C                        ///< IPC Write Buffer
+#define R_PMC_PWRM_IPC_RBUF0                                0x90                        ///< IPC Read Buffer
+#define R_PMC_PWRM_IPC_RBUF1                                0x94                        ///< IPC Read Buffer
+#define R_PMC_PWRM_IPC_RBUF2                                0x98                        ///< IPC Read Buffer
+#define R_PMC_PWRM_IPC_RBUF3                                0x9C                        ///< IPC Read Buffer
+//
+// PWRM Registers
+//
+#define R_PMC_PWRM_GEN_PMCON_A                              0x1020
+#define B_PMC_PWRM_GEN_PMCON_A_DC_PP_DIS                    BIT30
+#define B_PMC_PWRM_GEN_PMCON_A_DSX_PP_DIS                   BIT29
+#define B_PMC_PWRM_GEN_PMCON_A_AG3_PP_EN                    BIT28
+#define B_PMC_PWRM_GEN_PMCON_A_SX_PP_EN                     BIT27
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_ICLK_PLL               BIT26
+#define B_PMC_PWRM_GEN_PMCON_A_MPHY_CRICLK_GATE_OVR         BIT25
+#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_OPI_PLL_SD_INC0        BIT22
+#define B_PMC_PWRM_GEN_PMCON_A_MEM_SR                       BIT21
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_SPXB_CG_INC0           BIT20
+#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_ALLOW_L1LOW_OPI_ON           BIT17
+#define B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR                  BIT16
+#define B_PMC_PWRM_GEN_PMCON_A_PME_B0_S5_DIS                BIT15
+#define B_PMC_PWRM_GEN_PMCON_A_PWR_FLR                      BIT14
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_L1LOW_BCLKREQ_ON       BIT13
+#define B_PMC_PWRM_GEN_PMCON_A_DISABLE_SX_STRETCH           BIT12
+#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_SLP_S4_ASE                   BIT3
+#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_WOL_EN_OVRD                  BIT13
+#define B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN              BIT10
+#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 B_PMC_PWRM_CRID_RID_SEL                             (BIT0 | BIT1)    ///< RID Select
+#define V_PMC_PWRM_CRID_RID_SEL_REVISIONID                  0
+#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          ///< this is PWRM register
+#define B_PMC_PWRM_ETR3_CF9LOCK                             BIT31           ///< CF9h Lockdown
+#define B_PMC_PWRM_ETR3_LATCH_EVENTS_C10_EXIT               BIT30
+#define B_PMC_PWRM_ETR3_USB_CACHE_DIS                       BIT21
+#define B_PMC_PWRM_ETR3_CF9GR                               BIT20           ///< CF9h Global Reset
+#define B_PMC_PWRM_ETR3_SKIP_HOST_RST_HS                    BIT19
+#define B_PMC_PWRM_ETR3_CWORWRE                             BIT18
+#define B_PMC_PWRM_THROT_1_VR_ALERT                         BIT0
+
+#define R_PMC_PWRM_SSML                                     0x104C           ///< Set Strap Msg Lock
+#define B_PMC_PWRM_SSML_SSL                                 BIT0             ///< Set_Strap Lock
+#define R_PMC_PWRM_SSMC                                     0x1050           ///< Set Strap Msg Control
+#define B_PMC_PWRM_SSMC_SSMS                                BIT0             ///< Set_Strap Mux Select
+#define R_PMC_PWRM_SSMD                                     0x1054           ///< Set Strap Msg Data
+
+#define R_PMC_PWRM_MODPHY_PM_CFG5                           0x10D0
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2            BIT26
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_DMI             BIT25
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E3              BIT24
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E2              BIT23
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E1              BIT22
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E0              BIT21
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D3              BIT20
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D2              BIT19
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D1              BIT18
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0              BIT17
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS             BIT16    ///< UFS ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI            BIT15    ///< xDCI ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI            BIT14    ///< xHCI ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE             BIT13    ///< GbE ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA            BIT12    ///< SATA ModPHY SPD RT Request
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C3              BIT11
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C2              BIT10
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C1              BIT9
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C0              BIT8
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B3              BIT7
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B2              BIT6
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B1              BIT5
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B0              BIT4
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A3              BIT3
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A2              BIT2
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A1              BIT1
+#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0              BIT0
+#define R_PMC_PWRM_WADT_AC                                  0x1800
+#define R_PMC_PWRM_PRSTS                                    0x1810                      ///< Power and Reset Status
+#define B_PMC_PWRM_PRSTS_VE_WD_TMR_STS                      BIT7                        ///< VE Watchdog Timer Status
+#define B_PMC_PWRM_PRSTS_WOL_OVR_WK_STS                     BIT5
+#define B_PMC_PWRM_PRSTS_FIELD_1                            BIT4
+#define B_PMC_PWRM_PRSTS_ME_WAKE_STS                        BIT0
+
+#define R_PMC_PWRM_1814                                     0x1814
+#define R_PMC_PWRM_CFG                                      0x1818                      ///< Power Management Configuration
+#define B_PMC_PWRM_CFG_ALLOW_24_OSC_SD                      BIT29                       ///< Allow 24MHz Crystal Oscillator Shutdown
+#define B_PMC_PWRM_CFG_DBG_MODE_LOCK                        BIT27                       ///< Debug Mode Lock
+#define B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG                   BIT25                       ///< Allow USB2 Core Power Gating
+#define B_PMC_PWRM_CFG_ER_LOCK                              BIT24                       ///< Energy Reporting Lock
+#define B_PMC_PWRM_CFG_EN_PMC_UNC_ERR                       BIT23                       ///< Enable Global Reset on Uncorrectable Parity Error on PMC SRAM Interface
+#define B_PMC_PWRM_CFG_PMCREAD_DISABLE                      BIT22                       ///< Disable Reads to PMC
+#define B_PMC_PWRM_CFG_RTC_DS_WAKE_DIS                      BIT21                       ///< RTC Wake from Deep S4/S5 Disable
+#define B_PMC_PWRM_CFG_SSMAW_MASK                           (BIT19 | BIT18)             ///< SLP_SUS# Min Assertion Width
+#define V_PMC_PWRM_CFG_SSMAW_4S                             (BIT19 | BIT18)             ///< 4 seconds
+#define V_PMC_PWRM_CFG_SSMAW_1S                             BIT19                       ///< 1 second
+#define V_PMC_PWRM_CFG_SSMAW_0_5S                           BIT18                       ///< 0.5 second (500ms)
+#define V_PMC_PWRM_CFG_SSMAW_0S                             0                           ///< 0 second
+#define B_PMC_PWRM_CFG_SAMAW_MASK                           (BIT17 | BIT16)             ///< SLP_A# Min Assertion Width
+#define V_PMC_PWRM_CFG_SAMAW_2S                             (BIT17 | BIT16)             ///< 2 seconds
+#define V_PMC_PWRM_CFG_SAMAW_98ms                           BIT17                       ///< 98ms
+#define V_PMC_PWRM_CFG_SAMAW_4S                             BIT16                       ///< 4 seconds
+#define V_PMC_PWRM_CFG_SAMAW_0S                             0                           ///< 0 second
+#define B_PMC_PWRM_CFG_RPCD_MASK                            (BIT9 | BIT8)               ///< Reset Power Cycle Duration
+#define V_PMC_PWRM_CFG_RPCD_1S                              (BIT9 | BIT8)               ///< 1-2 seconds
+#define V_PMC_PWRM_CFG_RPCD_2S                              BIT9                        ///< 2-3 seconds
+#define V_PMC_PWRM_CFG_RPCD_3S                              BIT8                        ///< 3-4 seconds
+#define V_PMC_PWRM_CFG_RPCD_4S                              0                           ///< 4-5 seconds (Default)
+#define B_PMC_PWRM_CFG_COCS                                 BIT5                        ///< CPU OC Strap
+#define B_PMC_PWRM_CFG_ER_EN                                BIT2                        ///< Energy Reporting Enable
+#define B_PMC_PWRM_CFG_TIMING_TPCH25                        (BIT1 | BIT0)               ///< tPCH25 timing
+
+#define R_PMC_PWRM_S3_PWRGATE_POL                           0x1828                      ///< S3 Power Gating Policies
+#define B_PMC_PWRM_S3_PWRGATE_POL_S3DC_GATE_SUS             BIT1                        ///< Deep S3 Enable in DC Mode
+#define B_PMC_PWRM_S3_PWRGATE_POL_S3AC_GATE_SUS             BIT0                        ///< Deep S3 Enable in AC Mode
+
+#define R_PMC_PWRM_S4_PWRGATE_POL                           0x182C                      ///< Deep S4 Power Policies
+#define B_PMC_PWRM_S4_PWRGATE_POL_S4DC_GATE_SUS             BIT1                        ///< Deep S4 Enable in DC Mode
+#define B_PMC_PWRM_S4_PWRGATE_POL_S4AC_GATE_SUS             BIT0                        ///< Deep S4 Enable in AC Mode
+
+#define R_PMC_PWRM_S5_PWRGATE_POL                           0x1830                      ///< Deep S5 Power Policies
+#define B_PMC_PWRM_S5_PWRGATE_POL_S5DC_GATE_SUS             BIT15                       ///< Deep S5 Enable in DC Mode
+#define B_PMC_PWRM_S5_PWRGATE_POL_S5AC_GATE_SUS             BIT14                       ///< Deep S5 Enable in AC Mode
+
+#define R_PMC_PWRM_DSX_CFG                                  0x1834                      ///< Deep SX Configuration
+#define B_PMC_PWRM_DSX_CFG_WAKE_PIN_DSX_EN                  BIT2                        ///< WAKE# Pin DeepSx Enable
+#define B_PMC_PWRM_DSX_CFG_ACPRES_PD_DSX_DIS                BIT1                        ///< AC_PRESENT pin pulldown in DeepSx disable
+#define B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN                      BIT0                        ///< LAN_WAKE Pin DeepSx Enable
+
+#define R_PMC_PWRM_CFG2                                     0x183C                      ///< Power Management Configuration Reg 2
+#define B_PMC_PWRM_CFG2_PBOP                                (BIT31 | BIT30 | BIT29)     ///< Power Button Override Period (PBOP)
+#define N_PMC_PWRM_CFG2_PBOP                                29                          ///< Power Button Override Period (PBOP)
+#define B_PMC_PWRM_CFG2_PB_DIS                              BIT28                       ///< Power Button Native Mode Disable (PB_DIS)
+#define B_PMC_PWRM_CFG2_EN_DBG_MSG                          BIT27                       ///< Enable PMC Debug Messages
+#define B_PMC_PWRM_CFG2_DRAM_RESET_CTL                      BIT26                       ///< DRAM RESET# control
+#define N_PMC_PWRM_CFG2_DRAM_RESET_CTL                      26
+
+#define R_PMC_PWRM_EN_SN_SLOW_RING                          0x1848                      ///< Enable Snoop Request to SLOW_RING
+#define R_PMC_PWRM_EN_SN_SLOW_RING2                         0x184C                      ///< Enable Snoop Request to SLOW_RING 2nd Reg
+#define R_PMC_PWRM_EN_SN_SA                                 0x1850                      ///< Enable Snoop Request to SA
+#define R_PMC_PWRM_EN_SN_SA2                                0x1854                      ///< Enable Snoop Request to SA 2nd Reg
+#define R_PMC_PWRM_EN_SN_SLOW_RING_CF                       0x1858                      ///< Enable Snoop Request to SLOW_RING_CF
+#define R_PMC_PWRM_EN_NS_SA                                 0x1868                      ///< Enable Non-Snoop Request to SA
+#define R_PMC_PWRM_EN_CW_SLOW_RING                          0x1880                      ///< Enable Clock Wake to SLOW_RING
+#define R_PMC_PWRM_EN_CW_SLOW_RING2                         0x1884                      ///< Enable Clock Wake to SLOW_RING 2nd Reg
+#define R_PMC_PWRM_EN_CW_SA                                 0x1888                      ///< Enable Clock Wake to SA
+#define R_PMC_PWRM_EN_CW_SA2                                0x188C                      ///< Enable Clock Wake to SA 2nd Reg
+#define R_PMC_PWRM_EN_CW_SLOW_RING_CF                       0x1898                      ///< Enable Clock Wake to SLOW_RING_CF
+#define R_PMC_PWRM_EN_PA_SLOW_RING                          0x18A8                      ///< Enable Pegged Active to SLOW_RING
+#define R_PMC_PWRM_EN_PA_SLOW_RING2                         0x18AC                      ///< Enable Pegged Active to SLOW_RING 2nd Reg
+#define R_PMC_PWRM_EN_PA_SA                                 0x18B0                      ///< Enable Pegged Active to SA
+#define R_PMC_PWRM_EN_PA_SA2                                0x18B4                      ///< Enable Pegged Active to SA 2nd Reg
+#define R_PMC_PWRM_EN_MISC_EVENT                            0x18C0                      ///< Enable Misc PM_SYNC Events
+#define R_PMC_PWRM_PMSYNC_TPR_CONFIG                        0x18C4
+#define B_PMC_PWRM_PMSYNC_TPR_CONFIG_LOCK                   BIT31
+#define B_PMC_PWRM_PMSYNC_PCH2CPU_TT_EN                     BIT26
+#define B_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE                  (BIT25 | BIT24)
+#define N_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE                  24
+#define V_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE_1                1
+#define B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK                      BIT15                       ///< PM_SYNC Configuration Lock
+#define B_PMC_PWRM_PMSYNC_GPIO_D_SEL                        BIT11
+#define B_PMC_PWRM_PMSYNC_GPIO_C_SEL                        BIT10
+
+#define R_PMC_PWRM_PM_SYNC_STATE_HYS                        0x18D0                      ///< PM_SYNC State Hysteresis
+#define R_PMC_PWRM_PM_SYNC_MODE                             0x18D4                      ///< PM_SYNC Pin Mode
+
+#define R_PMC_PWRM_CFG3                                     0x18E0                      ///< Power Management Configuration Reg 3
+#define B_PMC_PWRM_CFG3_HOST_WLAN_PP_EN                     BIT17                       ///< Host Wireless LAN Phy Power Enable
+#define B_PMC_PWRM_CFG3_DSX_WLAN_PP_EN                      BIT16                       ///< Deep-Sx WLAN Phy Power Enable
+
+#define R_PMC_PWRM_PM_DOWN_PPB_CFG                          0x18E4                      ///< PM_DOWN PCH_POWER_BUDGET CONFIGURATION
+
+#define R_PMC_PWRM_CFG4                                     0x18E8                      ///< Power Management Configuration Reg 4
+#define B_PMC_PWRM_CFG4_U2_PHY_PG_EN                        BIT30                       ///< USB2 PHY SUS Well Power Gating Enable
+#define B_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR                   (0x000001FF)                ///< CPU I/O VR Ramp Duration, [8:0]
+#define N_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR                   0
+#define V_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR_70US              0x007
+#define V_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR_240US             0x018
+
+#define R_PMC_PWRM_CPU_EPOC                                 0x18EC
+
+#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_CS_SD_CTL1                               0x1BE8            ///< Clock Source Shutdown Control Reg 1
+#define B_PMC_PWRM_CS_SD_CTL1_CS5_CTL_CFG                   (BIT22 | BIT21 | BIT20)    ///< Clock Source 5 Control Configuration
+#define N_PMC_PWRM_CS_SD_CTL1_CS5_CTL_CFG                   20
+#define B_PMC_PWRM_CS_SD_CTL1_CS1_CTL_CFG                   (BIT2 | BIT1 | BIT0)       ///< Clock Source 1 Control Configuration
+#define N_PMC_PWRM_CS_SD_CTL1_CS1_CTL_CFG                   0
+
+#define R_PMC_PWRM_CS_SD_CTL2                               0x1BEC ///< Clock Source Shutdown Control Reg 2
+
+#define R_PMC_PWRM_HSWPGCR1                                 0x1DD0
+#define B_PMC_PWRM_SW_PG_CTRL_LOCK                          BIT31
+#define B_PMC_PWRM_NPK_VNN_SW_PG_CTRL                       BIT0
+
+#define R_PMC_PWRM_1E00                                     0x1E00
+#define R_PMC_PWRM_1E04                                     0x1E04
+
+#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_CNVI_FDIS_PMC           BIT1   ///< CNVi Function Disable (PMC Version) (CNVI_FDIS_PMC)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK              BIT31 ///< Static Function Disable Lock (ST_FDIS_LK)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_CAM_FDIS_PMC            BIT6  ///< Camera Function Disable (PMC Version) (CAM_FDIS_PMC)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC            BIT5  ///< SH Function Disable (PMC Version) (ISH_FDIS_PMC)
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC            BIT0  ///< GBE Function Disable (PMC Version) (GBE_FDIS_PMC)
+
+#define R_PMC_PWRM_ST_PG_FDIS_PMC_2                         0x1E24 ///< Static Function Disable Control Register 2
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI2_FDIS_PMC BIT11 ///< SerialIo Controller GSPI Device 2 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI1_FDIS_PMC BIT10 ///< SerialIo Controller GSPI Device 1 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI0_FDIS_PMC BIT9  ///< SerialIo Controller GSPI Device 0 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART2_FDIS_PMC BIT8  ///< SerialIo Controller UART Device 2 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART1_FDIS_PMC BIT7  ///< SerialIo Controller UART Device 1 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART0_FDIS_PMC BIT6  ///< SerialIo Controller UART Device 0 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C5_FDIS_PMC  BIT5  ///< SerialIo Controller I2C Device 5 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C4_FDIS_PMC  BIT4  ///< SerialIo Controller I2C Device 4 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C3_FDIS_PMC  BIT3  ///< SerialIo Controller I2C Device 3 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C2_FDIS_PMC  BIT2  ///< SerialIo Controller I2C Device 2 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C1_FDIS_PMC  BIT1  ///< SerialIo Controller I2C Device 1 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C0_FDIS_PMC  BIT0  ///< SerialIo Controller I2C Device 0 Function Disable
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO                0xFFF  ///< SerialIo Devices Disable Mask
+
+#define R_PMC_PWRM_NST_PG_FDIS_1                            0x1E28
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F3_FDIS_PMC     BIT31  ///< PCIe Controller F Port 3 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F2_FDIS_PMC     BIT30  ///< PCIe Controller F Port 2 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F1_FDIS_PMC     BIT29  ///< PCIe Controller F Port 1 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC     BIT28  ///< PCIe Controller F Port 0 Function Disable
+#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC     BIT29  ///< SD Card Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC      BIT27  ///< SD Card Function Disable
+#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC       BIT28  ///< eMMC Function Disable
+#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC        BIT27  ///< UFS Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC              BIT26  ///< XDCI Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_SMBUS_FDIS_PMC             BIT25  ///< Smbus Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC              BIT23  ///< ADSP Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC              BIT22  ///< SATA Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E3_FDIS_PMC     BIT21  ///< PCIe Controller E Port 3 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E2_FDIS_PMC     BIT20  ///< PCIe Controller E Port 2 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E1_FDIS_PMC     BIT19  ///< PCIe Controller E Port 1 Function Disable
+#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E0_FDIS_PMC     BIT18  ///< PCIe Controller E Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D3_FDIS_PMC           BIT17  ///< PCIe Controller D Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D2_FDIS_PMC           BIT16  ///< PCIe Controller D Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D1_FDIS_PMC           BIT15  ///< PCIe Controller D Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D0_FDIS_PMC           BIT14  ///< PCIe Controller D Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C3_FDIS_PMC           BIT13  ///< PCIe Controller C Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C2_FDIS_PMC           BIT12  ///< PCIe Controller C Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C1_FDIS_PMC           BIT11  ///< PCIe Controller C Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C0_FDIS_PMC           BIT10  ///< PCIe Controller C Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B3_FDIS_PMC           BIT9   ///< PCIe Controller B Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B2_FDIS_PMC           BIT8   ///< PCIe Controller B Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B1_FDIS_PMC           BIT7   ///< PCIe Controller B Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B0_FDIS_PMC           BIT6   ///< PCIe Controller B Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A3_FDIS_PMC           BIT5   ///< PCIe Controller A Port 3 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A2_FDIS_PMC           BIT4   ///< PCIe Controller A Port 2 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A1_FDIS_PMC           BIT3   ///< PCIe Controller A Port 1 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC           BIT2   ///< PCIe Controller A Port 0 Function Disable
+#define B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC              BIT0   ///< XHCI Function Disable
+
+#define R_PMC_PWRM_FUSE_DIS_RD_2                            0x1E44 ///< Fuse Disable Read 2 Register
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SPC_SS_DIS                 BIT25 ///< SPC Fuse Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SPB_SS_DIS                 BIT24 ///< SPB Fuse Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SPA_SS_DIS                 BIT23 ///< SPA Fuse Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_PSTH_FUSE_SS_DIS           BIT21 ///< PSTH Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_DMI_FUSE_SS_DIS            BIT20 ///< DMI Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS            BIT19 ///< OTG Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_XHCI_SS_DIS                BIT18 ///< XHCI Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_FIA_FUSE_SS_DIS            BIT17 ///< FIA Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_DSP_FUSE_SS_DIS            BIT16 ///< DSP Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS           BIT15 ///< SATA Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_ICC_FUSE_SS_DIS            BIT14 ///< ICC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_LPC_FUSE_SS_DIS            BIT13 ///< LPC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_RTC_FUSE_SS_DIS            BIT12 ///< RTC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_P2S_FUSE_SS_DIS            BIT11 ///< P2S Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_TRSB_FUSE_SS_DIS           BIT10 ///< TRSB Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SMB_FUSE_SS_DIS            BIT9  ///< SMB Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_ITSS_FUSE_SS_DIS           BIT8  ///< ITSS Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_UFSX2_FUSE_SS_DIS          BIT7   ///< UFSX2 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS       BIT6  ///< SerialIo Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_EMMC_FUSE_SS_DIS           BIT5   ///< EMMC Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_CNVI_FUSE_SS_DIS           BIT4   ///< CNVi Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_P2D_FUSE_SS_DIS            BIT3  ///< P2D Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_SDX_FUSE_SS_DIS            BIT2   ///< SD Conroller Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS            BIT1  ///< ISH Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS            BIT0  ///< GBE Fuse or Soft Strap Disable
+
+#define R_PMC_PWRM_FUSE_DIS_RD_3                            0x1E48 ///< Static PG Fuse and Soft Strap Disable Read Register 3
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA3_FUSE_SS_DIS         BIT3  ///< PNCRA3 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA2_FUSE_SS_DIS         BIT2  ///< PNCRA2 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA1_FUSE_SS_DIS         BIT1  ///< PNCRA1 Fuse or Soft Strap Disable
+#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA_FUSE_SS_DIS          BIT0  ///< PNCRA Fuse or Soft Strap Disable
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
new file mode 100644
index 0000000000..bd0c2574f2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
@@ -0,0 +1,72 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PMC_CNL_H_
+#define _PCH_REGS_PMC_CNL_H_
+
+//
+// PWRM Registers
+//
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A                        0x0
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B                        0x1
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C                        0xD
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D                        0x4
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E                        0xE
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F                        0x5
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G                        0x2
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H                        0x6
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD                          0xA
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO                        0x7
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI                          0x3
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA                          0xB
+#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG                         0xF
+
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A                         0x0
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B                         0x1
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C                         0x2
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D                         0x3
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E                         0xA
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F                         0xB
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G                         0x4
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H                         0x9
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I                         0xC
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J                         0xD
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K                         0x8
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD                           0x7
+#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO                         0x5
+
+#endif // _PCH_REGS_PMC_CNL_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
new file mode 100644
index 0000000000..5c4d583904
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
@@ -0,0 +1,104 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PSF_H_
+#define _PCH_REGS_PSF_H_
+
+//
+// Private chipset register (Memory space) offset definition
+// The PCR register defines is used for PCR MMIO programming and PCH SBI programming as well.
+//
+
+//
+// PSFx segment registers
+//
+#define R_PCH_PSF_PCR_GLOBAL_CONFIG                     0x4000                  ///< PSF Segment Global Configuration Register
+#define B_PCH_PSF_PCR_ROOTSPACE_CONFIG_RSX_ENADDRP2P    BIT1
+#define B_PCH_PSF_PCR_ROOTSPACE_CONFIG_RSX_VTDEN        BIT0
+
+#define S_PCH_PSFX_PCR_DEV_GNTCNT_RELOAD_DGCR                4
+#define S_PCH_PSFX_PCR_TARGET_GNTCNT_RELOAD                  4
+#define B_PCH_PSFX_PCR_DEV_GNTCNT_RELOAD_DGCR_GNT_CNT_RELOAD 0x1F
+#define B_PCH_PSFX_PCR_TARGET_GNTCNT_RELOAD_GNT_CNT_RELOAD   0x1F
+
+#define N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC          1
+#define B_PCH_PSFX_PCR_MC_CONTROL_MCASTX_MULTCEN        BIT0
+
+//
+// PSFx PCRs definitions
+//
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR0                     0                       ///< PCI BAR0
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR1                     0x04                    ///< PCI BAR1
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR2                     0x08                    ///< PCI BAR2
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR3                     0x0C                    ///< PCI BAR3
+#define R_PCH_PSFX_PCR_T0_SHDW_BAR4                     0x10                    ///< PCI BAR4
+#define R_PCH_PSFX_PCR_T0_SHDW_PCIEN                    0x1C                    ///< PCI configuration space enable bits
+#define N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS            16
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR0DIS            BIT16                   ///< Disable BAR0
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR1DIS            BIT17                   ///< Disable BAR1
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR2DIS            BIT18                   ///< Disable BAR2
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR3DIS            BIT19                   ///< Disable BAR3
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR4DIS            BIT20                   ///< Disable BAR4
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR5DIS            BIT21                   ///< Disable BAR5
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS             BIT8                    ///< Function disable
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_MEMEN              BIT1                    ///< Memory decoding enable
+#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN               BIT0                    ///< IO decoding enable
+#define R_PCH_PSFX_PCR_T0_SHDW_PMCSR                    0x20                    ///< PCI power management configuration
+#define B_PCH_PSFX_PCR_T0_SHDW_PMCSR_PWRST              (BIT1 | BIT0)           ///< Power status
+#define R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS                  0x38                    ///< PCI configuration disable
+#define B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS           BIT0                    ///< config disable
+
+#define R_PCH_PSFX_PCR_T1_SHDW_PCIEN                    0x3C                    ///< PCI configuration space enable bits
+#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_FUNDIS             BIT8                    ///< Function disable
+#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_MEMEN              BIT1                    ///< Memory decoding enable
+#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_IOEN               BIT0                    ///< IO decoding enable
+
+#define B_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_DEVICE    0x01F0                 ///< device number
+#define N_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_DEVICE    4
+#define B_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_FUNCTION  (BIT3 | BIT2 | BIT1)   ///< function number
+#define N_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_FUNCTION  1
+
+#define B_PCH_PSFX_PCR_TARGET_CHANNELID                 0xFF
+#define B_PCH_PSFX_PCR_TARGET_PORTID                    0x7F00
+#define N_PCH_PSFX_PCR_TARGET_PORTID                    8
+#define B_PCH_PSFX_PCR_TARGET_PORTGROUPID               BIT15
+#define N_PCH_PSFX_PCR_TARGET_PORTGROUPID               15
+#define B_PCH_PSFX_PCR_TARGET_PSFID                     0xFF0000
+#define N_PCH_PSFX_PCR_TARGET_PSFID                     16
+#define B_PCH_PSFX_PCR_TARGET_CHANMAP                   BIT31
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
new file mode 100644
index 0000000000..9a5e536f18
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
@@ -0,0 +1,113 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PSF_CNL_H_
+#define _PCH_REGS_PSF_CNL_H_
+
+//PSF 1 Multicast Message Configuration
+#define R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI                 0x404C      ///< Multicast Control Register
+#define R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI              0x4064      ///< Destination ID
+#define R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI                  0x403C      ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI               0x4054      ///< Destination ID
+
+//
+// PSF3 PCRs (PID:PSF3)
+//
+// PSF3 PCH-LP Specific Base Address
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE         0x0100                  ///< D18F6 PSF base address (SerialIo: SPI2)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_ISH_REG_BASE          0x0200                  ///< D19F0 PSF base address (ISH)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_CNVI_REG_BASE         0x0400                  ///< D20F3 PSF base address (CNVi)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SDCARD_REG_BASE       0x0500                  ///< D20F5 PSF base address (SCC: SDCard)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE         0x0600                  ///< D21F0 PSF base address (SerialIo: I2C0)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE         0x0700                  ///< D21F1 PSF base address (SerialIo: I2C1)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE         0x0800                  ///< D21F2 PSF base address (SerialIo: I2C2)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE         0x0900                  ///< D21F3 PSF base address (SerialIo: I2C3)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE         0x0A00                  ///< D25F0 PSF base address (SerialIo: I2C4)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE         0x0B00                  ///< D25F1 PSF base address (SerialIo: I2C5)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE        0x0C00                  ///< D25F2 PSF base address (SerialIo: UART2)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE        0x0D00                  ///< D30F0 PSF base address (SerialIo: UART0)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE        0x0E00                  ///< D30F1 PSF base address (SerialIo: UART1)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE         0x0F00                  ///< D30F2 PSF base address (SerialIo: SPI0)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE         0x1000                  ///< D30F3 PSF base address (SerialIo: SPI1)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_LPC_REG_BASE          0x1100                  ///< D31F0 PSF base address (LPC)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_P2SB_REG_BASE         0x1300                  ///< D31F1 PSF base address (P2SB)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE          0x1400                  ///< D31F2 PSF base address (PMC)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_AUD_REG_BASE          0x1500                  ///< D31F3 PSF base address (HDA, ADSP)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SMBUS_REG_BASE        0x1600                  ///< D31F4 PSF base address (SMBUS)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI_SPI_REG_BASE      0x1700                  ///< D31F5 PSF base address (SPI SPI)
+#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_GBE_REG_BASE          0x1800                  ///< D31F6 PSF base address (GBE)
+// PSF3 PCH-H Specific Base Address
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE          0x0100                  ///< D18F6 PSF base address (SerialIo: SPI2)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_ISH_REG_BASE           0x0180                  ///< D19F0 PSF base address (ISH)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_CNVI_REG_BASE          0x0280                  ///< D20F3 PSF base address (CNVi)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SDCARD_REG_BASE        0x0300                  ///< D20F5 PSF base address (SCC: SDCard)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE          0x0380                  ///< D21F0 PSF base address (SerialIo: I2C0)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE          0x0400                  ///< D21F1 PSF base address (SerialIo: I2C1)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE          0x0480                  ///< D21F2 PSF base address (SerialIo: I2C2)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE          0x0500                  ///< D21F3 PSF base address (SerialIo: I2C3)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE         0x0580                  ///< D25F2 PSF base address (SerialIo: UART2)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE         0x0600                  ///< D30F0 PSF base address (SerialIo: UART0)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE         0x0680                  ///< D30F1 PSF base address (SerialIo: UART1)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE          0x0700                  ///< D30F2 PSF base address (SerialIo: SPI0)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE          0x0780                  ///< D30F3 PSF base address (SerialIo: SPI1)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_LPC_REG_BASE           0x0800                  ///< D31F0 PSF base address (LPC)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_P2SB_REG_BASE          0x0900                  ///< D31F1 PSF base address (P2SB)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE           0x0980                  ///< D31F2 PSF base address (PMC)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_AUD_REG_BASE           0x0A00                  ///< D31F3 PSF base address (HDA, ADSP)H
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SMBUS_REG_BASE         0x0A80                  ///< D31F4 PSF base address (SMBUS)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI_SPI_REG_BASE       0x0B00                  ///< D31F5 PSF base address (SPI SPI)
+#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_GBE_REG_BASE           0x0B80                  ///< D31F6 PSF base address (GBE)
+
+// Other PSF3 PCRs definition
+#define R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI        0x4058                  ///< Multicast Control Register  // LP&H
+#define R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI     0x4064                  ///< Destination ID  // LP&H
+
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI              0x4030          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI           0x4048          ///< Destination ID
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1        0x403C          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1     0x4070          ///< Destination ID
+
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI              0x4030          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI           0x4048          ///< Destination ID
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1        0x403C          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1     0x4070          ///< Destination ID
+
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI              0x4030          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI           0x4048          ///< Destination ID
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1        0x403C          ///< Multicast Control Register
+#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1     0x4070          ///< Destination ID
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
new file mode 100644
index 0000000000..d6030ed10d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
@@ -0,0 +1,77 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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 register (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 B_PSTH_PCR_PSTHIOSFSTCGE    BIT1                  ///< PSTH IOSF sideband trunk clock gating enable
+#define B_PSTH_PCR_PSTHDCGE         BIT0                  ///< PSTH dynamic clock gating enable
+#define R_PSTH_PCR_TRPST            0x1E00                ///< Trap status register
+#define B_PSTH_PCR_TRPST_CTSS       0x0000000F            ///< Cycle Trap SMI# Status mask
+#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 B_PSTH_PCR_TRPD_IOD         0x00000000FFFFFFFF    ///< Trap cycle I/O 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 B_PSTH_PCR_TRPREG_BEM       0x000000F000000000    ///< Byte enable mask
+#define N_PSTH_PCR_TRPREG_BE        32
+#define B_PSTH_PCR_TRPREG_BE        0x0000000F00000000    ///< Byte enable
+#define B_PSTH_PCR_TRPREG_AM        0x0000000000FC0000    ///< IO Address mask
+#define B_PSTH_PCR_TRPREG_AD        0x000000000000FFFC    ///< IO Address
+#define B_PSTH_PCR_TRPREG_TSE       BIT0                  ///< Trap and SMI# Enable
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
new file mode 100644
index 0000000000..d98ce39df6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
@@ -0,0 +1,668 @@
+/** @file
+  Register names for PCH 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SATA_H_
+#define _PCH_REGS_SATA_H_
+
+//
+//  SATA Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SATA          23
+#define PCI_FUNCTION_NUMBER_PCH_SATA        0
+
+#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_1    7
+#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1  0
+
+#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_2    8
+#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2  0
+
+#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_3    14
+#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3  0
+
+//
+//  PCH-LP SATA Device ID's
+//
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_AHCI         0x9DD3  ///< SATA Controller (AHCI) - Mobile
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID         0x9DD5  ///< SATA Controller (RAID 0/1/5/10) - NOT premium - Mobile
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_PREM    0x9DD7  ///< SATA Controller (RAID 0/1/5/10) - premium - Mobile
+#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_IBC     0x282A  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible - Mobile
+
+//
+//  PCH-H SATA Device ID's
+//
+#define V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_ALTDIS   0x2822  ///< SATA Controller (RAID 0/1/5/10) - premium - Alternate ID
+#define V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_RSTE     0x2826  ///< SATA Controller (RAID 0/1/5/10) - RSTe of Server SKU
+
+//
+//  PCH-H SATA Device ID's
+//
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_AHCI         0xA352  ///< SATA Controller (AHCI) Desktop/Server
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_AHCI        0xA353  ///< SATA Controller (AHCI) Mobile Halo
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID         0xA354  ///< SATA Controller (RAID 0/1/5/10) - NOT premium Desktop/Server
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID        0xA355  ///< SATA Controller (RAID 0/1/5/10) - NOT premium Mobile Halo
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_PREM    0xA356  ///< SATA Controller (RAID 0/1/5/10) - premium Desktop/Server
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID_PREM   0xA357  ///< SATA Controller (RAID 0/1/5/10) - premium Mobile Halo
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_OP_AHCI      0xA35E  ///< SATA Controller (AHCI) Optane Caching - Desktop
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC     0x2822  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_RST 0x2826  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible (RSTe)
+#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_2   0x282A  ///< SATA Controller (RAID 0/1/5/10) - In-box compatible (Alternate)
+
+
+//
+//  SATA Controller common Registers
+//
+#define V_SATA_CFG_SUB_CLASS_CODE_AHCI      0x06
+#define V_SATA_CFG_SUB_CLASS_CODE_RAID      0x04
+#define R_SATA_CFG_AHCI_BAR                 0x24
+#define B_SATA_CFG_AHCI_BAR_BA              0xFFFFF800
+#define V_SATA_CFG_AHCI_BAR_LENGTH          0x800
+#define N_SATA_CFG_AHCI_BAR_ALIGNMENT       11
+#define V_SATA_CFG_AHCI_BAR_LENGTH_512K     0x80000
+#define N_SATA_CFG_AHCI_BAR_ALIGNMENT_512K  19
+#define B_SATA_CFG_AHCI_BAR_PF              BIT3
+#define B_SATA_CFG_AHCI_BAR_TP              (BIT2 | BIT1)
+#define B_SATA_CFG_AHCI_BAR_RTE             BIT0
+#define R_SATA_CFG_PID                      0x70
+#define B_SATA_CFG_PID_NEXT                 0xFF00
+#define V_SATA_CFG_PID_NEXT_0               0xB000
+#define V_SATA_CFG_PID_NEXT_1               0xA800
+#define B_SATA_CFG_PID_CID                  0x00FF
+#define R_SATA_CFG_PC                       0x72
+#define S_SATA_CFG_PC                       2
+#define B_SATA_CFG_PC_PME                   (BIT15 | BIT14 | BIT13 | BIT12 | BIT11)
+#define V_SATA_CFG_PC_PME_0                 0x0000
+#define V_SATA_CFG_PC_PME_1                 0x4000
+#define B_SATA_CFG_PC_D2_SUP                BIT10
+#define B_SATA_CFG_PC_D1_SUP                BIT9
+#define B_SATA_CFG_PC_AUX_CUR               (BIT8 | BIT7 | BIT6)
+#define B_SATA_CFG_PC_DSI                   BIT5
+#define B_SATA_CFG_PC_PME_CLK               BIT3
+#define B_SATA_CFG_PC_VER                   (BIT2 | BIT1 | BIT0)
+#define R_SATA_CFG_PMCS                     0x74
+#define B_SATA_CFG_PMCS_PMES                BIT15
+#define B_SATA_CFG_PMCS_PMEE                BIT8
+#define B_SATA_CFG_PMCS_NSFRST              BIT3
+#define V_SATA_CFG_PMCS_NSFRST_1            0x01
+#define V_SATA_CFG_PMCS_NSFRST_0            0x00
+#define B_SATA_CFG_PMCS_PS                  (BIT1 | BIT0)
+#define V_SATA_CFG_PMCS_PS_3                0x03
+#define V_SATA_CFG_PMCS_PS_0                0x00
+#define R_SATA_CFG_MID                      0x80
+#define B_SATA_CFG_MID_NEXT                 0xFF00
+#define B_SATA_CFG_MID_CID                  0x00FF
+#define R_SATA_CFG_MC                       0x82
+#define B_SATA_CFG_MC_C64                   BIT7
+#define B_SATA_CFG_MC_MME                   (BIT6 | BIT5 | BIT4)
+#define V_SATA_CFG_MC_MME_4                 0x04
+#define V_SATA_CFG_MC_MME_2                 0x02
+#define V_SATA_CFG_MC_MME_1                 0x01
+#define V_SATA_CFG_MC_MME_0                 0x00
+#define B_SATA_CFG_MC_MMC                   (BIT3 | BIT2 | BIT1)
+#define V_SATA_CFG_MC_MMC_4                 0x04
+#define V_SATA_CFG_MC_MMC_0                 0x00
+#define B_SATA_CFG_MC_MSIE                  BIT0
+#define V_SATA_CFG_MC_MSIE_1                0x01
+#define V_SATA_CFG_MC_MSIE_0                0x00
+#define R_SATA_CFG_MA                       0x84
+#define B_SATA_CFG_MA                       0xFFFFFFFC
+#define R_SATA_CFG_MD                       0x88
+#define B_SATA_CFG_MD_MSIMD                 0xFFFF
+
+#define R_SATA_CFG_MAP                      0x90
+#define B_SATA_CFG_MAP_PCD                  0xFF
+#define N_SATA_CFG_MAP_SPD                  16
+#define B_SATA_CFG_MAP_SPD7                 BIT23
+#define B_SATA_CFG_MAP_SPD6                 BIT22
+#define B_SATA_CFG_MAP_SPD5                 BIT21
+#define B_SATA_CFG_MAP_SPD4                 BIT20
+#define B_SATA_CFG_MAP_SPD3                 BIT19
+#define B_SATA_CFG_MAP_SPD2                 BIT18
+#define B_SATA_CFG_MAP_SPD1                 BIT17
+#define B_SATA_CFG_MAP_SPD0                 BIT16
+#define B_SATA_CFG_MAP_PORT7_PCD            BIT7
+#define B_SATA_CFG_MAP_PORT6_PCD            BIT6
+#define B_SATA_CFG_MAP_PORT5_PCD            BIT5
+#define B_SATA_CFG_MAP_PORT4_PCD            BIT4
+#define B_SATA_CFG_MAP_PORT3_PCD            BIT3
+#define B_SATA_CFG_MAP_PORT2_PCD            BIT2
+#define B_SATA_CFG_MAP_PORT1_PCD            BIT1
+#define B_SATA_CFG_MAP_PORT0_PCD            BIT0
+#define R_SATA_CFG_PCS                      0x94
+#define B_SATA_CFG_PCS_P7P                  BIT23
+#define B_SATA_CFG_PCS_P6P                  BIT22
+#define B_SATA_CFG_PCS_P5P                  BIT21
+#define B_SATA_CFG_PCS_P4P                  BIT20
+#define B_SATA_CFG_PCS_P3P                  BIT19
+#define B_SATA_CFG_PCS_P2P                  BIT18
+#define B_SATA_CFG_PCS_P1P                  BIT17
+#define B_SATA_CFG_PCS_P0P                  BIT16
+#define B_SATA_CFG_PCS_P7E                  BIT7
+#define B_SATA_CFG_PCS_P6E                  BIT6
+#define B_SATA_CFG_PCS_P5E                  BIT5
+#define B_SATA_CFG_PCS_P4E                  BIT4
+#define B_SATA_CFG_PCS_P3E                  BIT3
+#define B_SATA_CFG_PCS_P2E                  BIT2
+#define B_SATA_CFG_PCS_P1E                  BIT1
+#define B_SATA_CFG_PCS_P0E                  BIT0
+#define R_SATA_CFG_SATAGC                   0x9C
+#define B_SATA_CFG_SATAGC_SMS_MASK          BIT16
+#define N_SATA_CFG_SATAGC_SMS_MASK          16
+#define V_SATA_CFG_SATAGC_SMS_AHCI          0x0
+#define V_SATA_CFG_SATAGC_SMS_RAID          0x1
+#define B_SATA_CFG_SATAGC_AIE               BIT7
+#define B_SATA_CFG_SATAGC_AIES              BIT6
+#define B_SATA_CFG_SATAGC_MSS               (BIT4 | BIT3)
+#define V_SATA_CFG_SATAGC_MSS_8K            0x2
+#define N_SATA_CFG_SATAGC_MSS               3
+#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
+
+#define R_SATA_CFG_SIRI                     0xA0
+#define R_SATA_CFG_STRD                     0xA4
+#define R_SATA_CFG_SIR_0C                   0x0C
+#define R_SATA_CFG_SIR_50                   0x50
+#define R_SATA_CFG_SIR_54                   0x54
+#define R_SATA_CFG_SIR_58                   0x58
+#define R_SATA_CFG_SIR_5C                   0x5C
+#define R_SATA_CFG_SIR_60                   0x60
+#define R_SATA_CFG_SIR_64                   0x64
+#define R_SATA_CFG_SIR_68                   0x68
+#define R_SATA_CFG_SIR_6C                   0x6C
+#define R_SATA_CFG_SIR_70                   0x70
+#define R_SATA_CFG_SIR_80                   0x80
+#define R_SATA_CFG_SIR_84                   0x84
+#define R_SATA_CFG_SIR_8C                   0x8C
+#define R_SATA_CFG_SIR_90                   0x90
+#define R_SATA_CFG_SIR_98                   0x98
+#define R_SATA_CFG_SIR_9C                   0x9C
+#define R_SATA_CFG_SIR_A0                   0xA0
+#define R_SATA_CFG_SIR_A4                   0xA4
+#define R_SATA_CFG_SIR_A8                   0xA8
+#define R_SATA_CFG_SIR_C8                   0xC8
+#define R_SATA_CFG_SIR_CC                   0xCC
+#define R_SATA_CFG_SIR_D0                   0xD0
+#define R_SATA_CFG_SIR_D4                   0xD4
+#define B_SATA_CFG_STRD_DTA                 0xFFFFFFFF
+#define R_SATA_CFG_CR0                      0xA8
+#define B_SATA_CFG_CR0_MAJREV               0x00F00000
+#define B_SATA_CFG_CR0_MINREV               0x000F0000
+#define B_SATA_CFG_CR0_NEXT                 0x0000FF00
+#define B_SATA_CFG_CR0_CAP                  0x000000FF
+#define R_SATA_CFG_CR1                      0xAC
+#define B_SATA_CFG_CR1_BAROFST              0xFFF0
+#define B_SATA_CFG_CR1_BARLOC               0x000F
+#define R_SATA_CFG_FLR_CID                  0xB0
+#define B_SATA_CFG_FLR_CID_NEXT             0xFF00
+#define B_SATA_CFG_FLR_CID                  0x00FF
+#define V_SATA_CFG_FLR_CID_1                0x0009
+#define V_SATA_CFG_FLR_CID_0                0x0013
+#define R_SATA_CFG_FLR_CLV                  0xB2
+#define B_SATA_CFG_FLR_CLV_FLRC_FLRCSSEL_0  BIT9
+#define B_SATA_CFG_FLR_CLV_TXPC_FLRCSSEL_0  BIT8
+#define B_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL_0 0x00FF
+#define B_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL_1 0x00FF
+#define V_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL   0x0006
+#define R_SATA_CFG_FLRC                     0xB4
+#define B_SATA_CFG_FLRC_TXP                 BIT8
+#define B_SATA_CFG_FLRC_INITFLR             BIT0
+#define R_SATA_CFG_SP                       0xC0
+#define B_SATA_CFG_SP                       0xFFFFFFFF
+#define R_SATA_CFG_MXID                     0xD0
+#define N_SATA_CFG_MXID_NEXT                8
+
+#define R_SATA_CFG_BFCS                     0xE0
+#define B_SATA_CFG_BFCS_P7BFI               BIT17
+#define B_SATA_CFG_BFCS_P6BFI               BIT16
+#define B_SATA_CFG_BFCS_P5BFI               BIT15
+#define B_SATA_CFG_BFCS_P4BFI               BIT14
+#define B_SATA_CFG_BFCS_P3BFI               BIT13
+#define B_SATA_CFG_BFCS_P2BFI               BIT12
+#define B_SATA_CFG_BFCS_P2BFS               BIT11
+#define B_SATA_CFG_BFCS_P2BFF               BIT10
+#define B_SATA_CFG_BFCS_P1BFI               BIT9
+#define B_SATA_CFG_BFCS_P0BFI               BIT8
+#define B_SATA_CFG_BFCS_BIST_FIS_T          BIT7
+#define B_SATA_CFG_BFCS_BIST_FIS_A          BIT6
+#define B_SATA_CFG_BFCS_BIST_FIS_S          BIT5
+#define B_SATA_CFG_BFCS_BIST_FIS_L          BIT4
+#define B_SATA_CFG_BFCS_BIST_FIS_F          BIT3
+#define B_SATA_CFG_BFCS_BIST_FIS_P          BIT2
+#define R_SATA_CFG_BFTD1                    0xE4
+#define B_SATA_CFG_BFTD1                    0xFFFFFFFF
+#define R_SATA_CFG_BFTD2                    0xE8
+#define B_SATA_CFG_BFTD2                    0xFFFFFFFF
+
+#define R_SATA_CFG_VS_CAP                   0xA4
+#define B_SATA_CFG_VS_CAP_NRMBE             BIT0                            ///< NVM Remap Memory BAR Enable
+#define B_SATA_CFG_VS_CAP_MSL               0x1FFE                          ///< Memory Space Limit
+#define N_SATA_CFG_VS_CAP_MSL               1
+#define V_SATA_CFG_VS_CAP_MSL               0x1EF                           ///< Memory Space Limit Field Value
+#define B_SATA_CFG_VS_CAP_NRMO              0xFFF0000                       ///< NVM Remapped Memory Offset
+#define N_SATA_CFG_VS_CAP_NRMO              16
+#define V_SATA_CFG_VS_CAP_NRMO              0x10                            ///< NVM Remapped Memory Offset Field Value
+
+//
+// RST PCIe Storage Remapping Registers
+//
+#define R_SATA_CFG_RST_PCIE_STORAGE_RCR                 0x800                           ///< Remap Capability Register
+#define B_SATA_CFG_RST_PCIE_STORAGE_RCR_NRS             (BIT2|BIT1|BIT0)                ///< Number of Remapping Supported
+#define B_SATA_CFG_RST_PCIE_STORAGE_RCR_NRS_CR1         BIT0                            ///< Number of Remapping Supported (RST PCIe Storage Cycle Router #1)
+#define R_SATA_CFG_RST_PCIE_STORAGE_SPR                 0x80C                           ///< Scratch Pad Register
+#define R_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC             0x880                           ///< CR#1 Device Class Code
+#define N_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_SCC         8
+#define N_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_BCC         16
+#define B_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_DT          BIT31                           ///< Device Type
+#define V_SATA_CFG_RST_PCIE_STORAGE_REMAP_CONFIG_CR     0x80                            ///< Remapped Configuration for RST PCIe Storage Cycle Router #n
+#define V_SATA_CFG_RST_PCIE_STORAGE_REMAP_RP_OFFSET     0x100                           ///< Remapped Root Port Offset Value
+#define R_SATA_CFG_RST_PCIE_STORAGE_CCFG                0x1D0                           ///< Port Configuration Register
+//
+// AHCI BAR Area related Registers
+//
+#define R_SATA_MEM_AHCI_CAP                 0x0
+#define B_SATA_MEM_AHCI_CAP_S64A            BIT31
+#define B_SATA_MEM_AHCI_CAP_SCQA            BIT30
+#define B_SATA_MEM_AHCI_CAP_SSNTF           BIT29
+#define B_SATA_MEM_AHCI_CAP_SMPS            BIT28 ///< Supports Interlock Switch
+#define B_SATA_MEM_AHCI_CAP_SSS             BIT27 ///< Supports Stagger Spin-up
+#define B_SATA_MEM_AHCI_CAP_SALP            BIT26
+#define B_SATA_MEM_AHCI_CAP_SAL             BIT25
+#define B_SATA_MEM_AHCI_CAP_SCLO            BIT24 ///< Supports Command List Override
+#define B_SATA_MEM_AHCI_CAP_ISS_MASK        (BIT23 | BIT22 | BIT21 | BIT20)
+#define N_SATA_MEM_AHCI_CAP_ISS             20    ///< Interface Speed Support
+#define V_SATA_MEM_AHCI_CAP_ISS_1_5_G       0x01
+#define V_SATA_MEM_AHCI_CAP_ISS_3_0_G       0x02
+#define V_SATA_MEM_AHCI_CAP_ISS_6_0_G       0x03
+#define B_SATA_MEM_AHCI_CAP_SNZO            BIT19
+#define B_SATA_MEM_AHCI_CAP_SAM             BIT18
+#define B_SATA_MEM_AHCI_CAP_SPM             BIT17 ///< Supports Port Multiplier
+#define B_SATA_MEM_AHCI_CAP_PMD             BIT15 ///< PIO Multiple DRQ Block
+#define B_SATA_MEM_AHCI_CAP_SSC             BIT14
+#define B_SATA_MEM_AHCI_CAP_PSC             BIT13
+#define B_SATA_MEM_AHCI_CAP_NCS             0x1F00
+#define B_SATA_MEM_AHCI_CAP_CCCS            BIT7
+#define B_SATA_MEM_AHCI_CAP_EMS             BIT6
+#define B_SATA_MEM_AHCI_CAP_SXS             BIT5  ///< External SATA is supported
+#define B_SATA_MEM_AHCI_CAP_NPS             0x001F
+
+#define R_SATA_MEM_AHCI_GHC                 0x04
+#define B_SATA_MEM_AHCI_GHC_AE              BIT31
+#define B_SATA_MEM_AHCI_GHC_MRSM            BIT2
+#define B_SATA_MEM_AHCI_GHC_IE              BIT1
+#define B_SATA_MEM_AHCI_GHC_HR              BIT0
+
+#define R_SATA_MEM_AHCI_IS                  0x08
+#define B_SATA_MEM_AHCI_IS_PORT7            BIT7
+#define B_SATA_MEM_AHCI_IS_PORT6            BIT6
+#define B_SATA_MEM_AHCI_IS_PORT5            BIT5
+#define B_SATA_MEM_AHCI_IS_PORT4            BIT4
+#define B_SATA_MEM_AHCI_IS_PORT3            BIT3
+#define B_SATA_MEM_AHCI_IS_PORT2            BIT2
+#define B_SATA_MEM_AHCI_IS_PORT1            BIT1
+#define B_SATA_MEM_AHCI_IS_PORT0            BIT0
+#define R_SATA_MEM_AHCI_PI                  0x0C
+#define B_SATA_MEM_AHCI_PI_PORT_MASK        0xFF
+#define B_SATA_MEM_PORT7_IMPLEMENTED        BIT7
+#define B_SATA_MEM_PORT6_IMPLEMENTED        BIT6
+#define B_SATA_MEM_PORT5_IMPLEMENTED        BIT5
+#define B_SATA_MEM_PORT4_IMPLEMENTED        BIT4
+#define B_SATA_MEM_PORT3_IMPLEMENTED        BIT3
+#define B_SATA_MEM_PORT2_IMPLEMENTED        BIT2
+#define B_SATA_MEM_PORT1_IMPLEMENTED        BIT1
+#define B_SATA_MEM_PORT0_IMPLEMENTED        BIT0
+#define R_SATA_MEM_AHCI_VS                  0x10
+#define B_SATA_MEM_AHCI_VS_MJR              0xFFFF0000
+#define B_SATA_MEM_AHCI_VS_MNR              0x0000FFFF
+#define R_SATA_MEM_AHCI_EM_LOC              0x1C
+#define B_SATA_MEM_AHCI_EM_LOC_OFST         0xFFFF0000
+#define B_SATA_MEM_AHCI_EM_LOC_SZ           0x0000FFFF
+#define R_SATA_MEM_AHCI_EM_CTRL             0x20
+#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_ALHD   BIT26
+#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_XMT    BIT25
+#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_SMB    BIT24
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SGPIO  BIT19
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SES2   BIT18
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SAFTE  BIT17
+#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_LED    BIT16
+#define B_SATA_MEM_AHCI_EM_CTRL_RST         BIT9
+#define B_SATA_MEM_AHCI_EM_CTRL_CTL_TM      BIT8
+#define B_SATA_MEM_AHCI_EM_CTRL_STS_MR      BIT0
+#define R_SATA_MEM_AHCI_CAP2                0x24
+#define B_SATA_MEM_AHCI_CAP2_DESO           BIT5
+#define B_SATA_MEM_AHCI_CAP2_SADM           BIT4
+#define B_SATA_MEM_AHCI_CAP2_SDS            BIT3
+#define B_SATA_MEM_AHCI_CAP2_APST           BIT2  ///< Automatic Partial to Slumber Transitions
+#define R_SATA_MEM_AHCI_VSP                 0xA0
+#define B_SATA_MEM_AHCI_VSP_SLPD            BIT0
+#define R_SATA_MEM_AHCI_SFM                 0xC8  ///< RST Feature Capabilities
+#define B_SATA_MEM_AHCI_SFM_LEGACY          BIT12
+#define B_SATA_MEM_AHCI_SFM_OUD             (BIT11 | BIT10)
+#define N_SATA_MEM_AHCI_SFM_OUD             10
+#define B_SATA_MEM_AHCI_SFM_SEREQ           BIT9
+#define B_SATA_MEM_AHCI_SFM_IROES           BIT8
+#define B_SATA_MEM_AHCI_SFM_LEDL            BIT7
+#define B_SATA_MEM_AHCI_SFM_HDDLK           BIT6
+#define B_SATA_MEM_AHCI_SFM_IRSTOROM        BIT5
+#define B_SATA_MEM_AHCI_SFM_RSTE            BIT4
+#define B_SATA_MEM_AHCI_SFM_R5E             BIT3
+#define B_SATA_MEM_AHCI_SFM_R10E            BIT2
+#define B_SATA_MEM_AHCI_SFM_R1E             BIT1
+#define B_SATA_MEM_AHCI_SFM_R0E             BIT0
+#define B_SATA_MEM_AHCI_SFM_LOWBYTES        0x1FF
+#define R_SATA_MEM_AHCI_P0CLB               0x100
+#define R_SATA_MEM_AHCI_P1CLB               0x180
+#define R_SATA_MEM_AHCI_P2CLB               0x200
+#define R_SATA_MEM_AHCI_P3CLB               0x280
+#define R_SATA_MEM_AHCI_P4CLB               0x300
+#define R_SATA_MEM_AHCI_P5CLB               0x380
+#define R_SATA_MEM_AHCI_P6CLB               0x400
+#define R_SATA_MEM_AHCI_P7CLB               0x480
+#define B_SATA_MEM_AHCI_PXCLB               0xFFFFFC00
+#define R_SATA_MEM_AHCI_P0CLBU              0x104
+#define R_SATA_MEM_AHCI_P1CLBU              0x184
+#define R_SATA_MEM_AHCI_P2CLBU              0x204
+#define R_SATA_MEM_AHCI_P3CLBU              0x284
+#define R_SATA_MEM_AHCI_P4CLBU              0x304
+#define R_SATA_MEM_AHCI_P5CLBU              0x384
+#define R_SATA_MEM_AHCI_P6CLBU              0x404
+#define R_SATA_MEM_AHCI_P7CLBU              0x484
+#define B_SATA_MEM_AHCI_PXCLBU              0xFFFFFFFF
+#define R_SATA_MEM_AHCI_P0FB                0x108
+#define R_SATA_MEM_AHCI_P1FB                0x188
+#define R_SATA_MEM_AHCI_P2FB                0x208
+#define R_SATA_MEM_AHCI_P3FB                0x288
+#define R_SATA_MEM_AHCI_P4FB                0x308
+#define R_SATA_MEM_AHCI_P5FB                0x388
+#define R_SATA_MEM_AHCI_P6FB                0x408
+#define R_SATA_MEM_AHCI_P7FB                0x488
+#define B_SATA_MEM_AHCI_PXFB                0xFFFFFF00
+#define R_SATA_MEM_AHCI_P0FBU               0x10C
+#define R_SATA_MEM_AHCI_P1FBU               0x18C
+#define R_SATA_MEM_AHCI_P2FBU               0x20C
+#define R_SATA_MEM_AHCI_P3FBU               0x28C
+#define R_SATA_MEM_AHCI_P4FBU               0x30C
+#define R_SATA_MEM_AHCI_P5FBU               0x38C
+#define R_SATA_MEM_AHCI_P6FBU               0x40C
+#define R_SATA_MEM_AHCI_P7FBU               0x48C
+#define B_SATA_MEM_AHCI_PXFBU               0xFFFFFFFF
+#define R_SATA_MEM_AHCI_P0IS                0x110
+#define R_SATA_MEM_AHCI_P1IS                0x190
+#define R_SATA_MEM_AHCI_P2IS                0x210
+#define R_SATA_MEM_AHCI_P3IS                0x290
+#define R_SATA_MEM_AHCI_P4IS                0x310
+#define R_SATA_MEM_AHCI_P5IS                0x390
+#define R_SATA_MEM_AHCI_P6IS                0x410
+#define R_SATA_MEM_AHCI_P7IS                0x490
+#define B_SATA_MEM_AHCI_PXIS_CPDS           BIT31
+#define B_SATA_MEM_AHCI_PXIS_TFES           BIT30
+#define B_SATA_MEM_AHCI_PXIS_HBFS           BIT29
+#define B_SATA_MEM_AHCI_PXIS_HBDS           BIT28
+#define B_SATA_MEM_AHCI_PXIS_IFS            BIT27
+#define B_SATA_MEM_AHCI_PXIS_INFS           BIT26
+#define B_SATA_MEM_AHCI_PXIS_OFS            BIT24
+#define B_SATA_MEM_AHCI_PXIS_IPMS           BIT23
+#define B_SATA_MEM_AHCI_PXIS_PRCS           BIT22
+#define B_SATA_MEM_AHCI_PXIS_DIS            BIT7
+#define B_SATA_MEM_AHCI_PXIS_PCS            BIT6
+#define B_SATA_MEM_AHCI_PXIS_DPS            BIT5
+#define B_SATA_MEM_AHCI_PXIS_UFS            BIT4
+#define B_SATA_MEM_AHCI_PXIS_SDBS           BIT3
+#define B_SATA_MEM_AHCI_PXIS_DSS            BIT2
+#define B_SATA_MEM_AHCI_PXIS_PSS            BIT1
+#define B_SATA_MEM_AHCI_PXIS_DHRS           BIT0
+#define R_SATA_MEM_AHCI_P0IE                0x114
+#define R_SATA_MEM_AHCI_P1IE                0x194
+#define R_SATA_MEM_AHCI_P2IE                0x214
+#define R_SATA_MEM_AHCI_P3IE                0x294
+#define R_SATA_MEM_AHCI_P4IE                0x314
+#define R_SATA_MEM_AHCI_P5IE                0x394
+#define R_SATA_MEM_AHCI_P6IE                0x414
+#define R_SATA_MEM_AHCI_P7IE                0x494
+#define B_SATA_MEM_AHCI_PXIE_CPDE           BIT31
+#define B_SATA_MEM_AHCI_PXIE_TFEE           BIT30
+#define B_SATA_MEM_AHCI_PXIE_HBFE           BIT29
+#define B_SATA_MEM_AHCI_PXIE_HBDE           BIT28
+#define B_SATA_MEM_AHCI_PXIE_IFE            BIT27
+#define B_SATA_MEM_AHCI_PXIE_INFE           BIT26
+#define B_SATA_MEM_AHCI_PXIE_OFE            BIT24
+#define B_SATA_MEM_AHCI_PXIE_IPME           BIT23
+#define B_SATA_MEM_AHCI_PXIE_PRCE           BIT22
+#define B_SATA_MEM_AHCI_PXIE_DIE            BIT7
+#define B_SATA_MEM_AHCI_PXIE_PCE            BIT6
+#define B_SATA_MEM_AHCI_PXIE_DPE            BIT5
+#define B_SATA_MEM_AHCI_PXIE_UFIE           BIT4
+#define B_SATA_MEM_AHCI_PXIE_SDBE           BIT3
+#define B_SATA_MEM_AHCI_PXIE_DSE            BIT2
+#define B_SATA_MEM_AHCI_PXIE_PSE            BIT1
+#define B_SATA_MEM_AHCI_PXIE_DHRE           BIT0
+#define R_SATA_MEM_AHCI_P0CMD               0x118
+#define R_SATA_MEM_AHCI_P1CMD               0x198
+#define R_SATA_MEM_AHCI_P2CMD               0x218
+#define R_SATA_MEM_AHCI_P3CMD               0x298
+#define R_SATA_MEM_AHCI_P4CMD               0x318
+#define R_SATA_MEM_AHCI_P5CMD               0x398
+#define R_SATA_MEM_AHCI_P6CMD               0x418
+#define R_SATA_MEM_AHCI_P7CMD               0x498
+#define B_SATA_MEM_AHCI_PxCMD_ESP           BIT21 ///< Used with an external SATA device
+#define B_SATA_MEM_AHCI_PxCMD_MPSP          BIT19 ///< Mechanical Switch Attached to Port
+#define B_SATA_MEM_AHCI_PxCMD_HPCP          BIT18 ///< Hotplug capable
+#define B_SATA_MEM_AHCI_PxCMD_CR            BIT15
+#define B_SATA_MEM_AHCI_PxCMD_FR            BIT14
+#define B_SATA_MEM_AHCI_PxCMD_ISS           BIT13
+#define B_SATA_MEM_AHCI_PxCMD_CCS           0x00001F00
+#define B_SATA_MEM_AHCI_PxCMD_FRE           BIT4
+#define B_SATA_MEM_AHCI_PxCMD_CLO           BIT3
+#define B_SATA_MEM_AHCI_PxCMD_POD           BIT2
+#define B_SATA_MEM_AHCI_PxCMD_SUD           BIT1
+#define B_SATA_MEM_AHCI_PxCMD_ST            BIT0
+#define R_SATA_MEM_AHCI_P0TFD               0x120
+#define R_SATA_MEM_AHCI_P1TFD               0x1A0
+#define R_SATA_MEM_AHCI_P2TFD               0x220
+#define R_SATA_MEM_AHCI_P3TFD               0x2A0
+#define R_SATA_MEM_AHCI_P4TFD               0x320
+#define R_SATA_MEM_AHCI_P5TFD               0x3A0
+#define R_SATA_MEM_AHCI_P6TFD               0x420
+#define B_SATA_MEM_AHCI_PXTFD_ERR           0x0000FF00
+#define B_SATA_MEM_AHCI_PXTFD_STS           0x000000FF
+#define R_SATA_MEM_AHCI_P0SIG               0x124
+#define R_SATA_MEM_AHCI_P1SIG               0x1A4
+#define R_SATA_MEM_AHCI_P2SIG               0x224
+#define R_SATA_MEM_AHCI_P3SIG               0x2A4
+#define R_SATA_MEM_AHCI_P4SIG               0x324
+#define R_SATA_MEM_AHCI_P5SIG               0x3A4
+#define R_SATA_MEM_AHCI_P6SIG               0x424
+#define B_SATA_MEM_AHCI_PXSIG_LBA_HR        0xFF000000
+#define B_SATA_MEM_AHCI_PXSIG_LBA_MR        0x00FF0000
+#define B_SATA_MEM_AHCI_PXSIG_LBA_LR        0x0000FF00
+#define B_SATA_MEM_AHCI_PXSIG_SCR           0x000000FF
+#define R_SATA_MEM_AHCI_P0SSTS              0x128
+#define R_SATA_MEM_AHCI_P1SSTS              0x1A8
+#define R_SATA_MEM_AHCI_P2SSTS              0x228
+#define R_SATA_MEM_AHCI_P3SSTS              0x2A8
+#define R_SATA_MEM_AHCI_P4SSTS              0x328
+#define R_SATA_MEM_AHCI_P5SSTS              0x3A8
+#define R_SATA_MEM_AHCI_P6SSTS              0x428
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_0        0x00000000
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_1        0x00000100
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_2        0x00000200
+#define B_SATA_MEM_AHCI_PXSSTS_IPM_6        0x00000600
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_0        0x00000000
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_1        0x00000010
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_2        0x00000020
+#define B_SATA_MEM_AHCI_PXSSTS_SPD_3        0x00000030
+#define B_SATA_MEM_AHCI_PXSSTS_DET_0        0x00000000
+#define B_SATA_MEM_AHCI_PXSSTS_DET_1        0x00000001
+#define B_SATA_MEM_AHCI_PXSSTS_DET_3        0x00000003
+#define B_SATA_MEM_AHCI_PXSSTS_DET_4        0x00000004
+#define R_SATA_MEM_AHCI_P0SCTL              0x12C
+#define R_SATA_MEM_AHCI_P1SCTL              0x1AC
+#define R_SATA_MEM_AHCI_P2SCTL              0x22C
+#define R_SATA_MEM_AHCI_P3SCTL              0x2AC
+#define R_SATA_MEM_AHCI_P4SCTL              0x32C
+#define R_SATA_MEM_AHCI_P5SCTL              0x3AC
+#define R_SATA_MEM_AHCI_P6SCTL              0x42C
+#define B_SATA_MEM_AHCI_PXSCTL_IPM          0x00000F00
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_0        0x00000000
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_1        0x00000100
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_2        0x00000200
+#define V_SATA_MEM_AHCI_PXSCTL_IPM_3        0x00000300
+#define B_SATA_MEM_AHCI_PXSCTL_SPD          0x000000F0
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_0        0x00000000
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_1        0x00000010
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_2        0x00000020
+#define V_SATA_MEM_AHCI_PXSCTL_SPD_3        0x00000030
+#define B_SATA_MEM_AHCI_PXSCTL_DET          0x0000000F
+#define V_SATA_MEM_AHCI_PXSCTL_DET_0        0x00000000
+#define V_SATA_MEM_AHCI_PXSCTL_DET_1        0x00000001
+#define V_SATA_MEM_AHCI_PXSCTL_DET_4        0x00000004
+#define R_SATA_MEM_AHCI_P0SERR              0x130
+#define R_SATA_MEM_AHCI_P1SERR              0x1B0
+#define R_SATA_MEM_AHCI_P2SERR              0x230
+#define R_SATA_MEM_AHCI_P3SERR              0x2B0
+#define R_SATA_MEM_AHCI_P4SERR              0x330
+#define R_SATA_MEM_AHCI_P5SERR              0x3B0
+#define R_SATA_MEM_AHCI_P6SERR              0x430
+#define B_SATA_MEM_AHCI_PXSERR_EXCHG        BIT26
+#define B_SATA_MEM_AHCI_PXSERR_UN_FIS_TYPE  BIT25
+#define B_SATA_MEM_AHCI_PXSERR_TRSTE_24     BIT24
+#define B_SATA_MEM_AHCI_PXSERR_TRSTE_23     BIT23
+#define B_SATA_MEM_AHCI_PXSERR_HANDSHAKE    BIT22
+#define B_SATA_MEM_AHCI_PXSERR_CRC_ERROR    BIT21
+#define B_SATA_MEM_AHCI_PXSERR_10B8B_DECERR BIT19
+#define B_SATA_MEM_AHCI_PXSERR_COMM_WAKE    BIT18
+#define B_SATA_MEM_AHCI_PXSERR_PHY_ERROR    BIT17
+#define B_SATA_MEM_AHCI_PXSERR_PHY_RDY_CHG  BIT16
+#define B_SATA_MEM_AHCI_PXSERR_INTRNAL_ERR  BIT11
+#define B_SATA_MEM_AHCI_PXSERR_PROTOCOL_ERR BIT10
+#define B_SATA_MEM_AHCI_PXSERR_PCDIE        BIT9
+#define B_SATA_MEM_AHCI_PXSERR_TDIE         BIT8
+#define B_SATA_MEM_AHCI_PXSERR_RCE          BIT1
+#define B_SATA_MEM_AHCI_PXSERR_RDIE         BIT0
+#define R_SATA_MEM_AHCI_P0SACT              0x134
+#define R_SATA_MEM_AHCI_P1SACT              0x1B4
+#define R_SATA_MEM_AHCI_P2SACT              0x234
+#define R_SATA_MEM_AHCI_P3SACT              0x2B4
+#define R_SATA_MEM_AHCI_P4SACT              0x334
+#define R_SATA_MEM_AHCI_P5SACT              0x3B4
+#define R_SATA_MEM_AHCI_P6SACT              0x434
+#define B_SATA_MEM_AHCI_PXSACT_DS           0xFFFFFFFF
+#define R_SATA_MEM_AHCI_P0CI                0x138
+#define R_SATA_MEM_AHCI_P1CI                0x1B8
+#define R_SATA_MEM_AHCI_P2CI                0x238
+#define R_SATA_MEM_AHCI_P3CI                0x2B8
+#define R_SATA_MEM_AHCI_P4CI                0x338
+#define R_SATA_MEM_AHCI_P5CI                0x3B8
+#define R_SATA_MEM_AHCI_P6CI                0x438
+#define B_SATA_MEM_AHCI_PXCI                0xFFFFFFFF
+
+//
+//  SATA AHCI Device ID macros
+//
+#define IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_AHCI) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_AHCI) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_OP_AHCI) \
+    )
+
+#define IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_AHCI) \
+    )
+
+#define IS_PCH_SATA_AHCI_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) \
+    )
+
+//
+//  SATA RAID Device ID macros
+//
+#define IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_PREM) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID_PREM) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_RST) || \
+      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_2) || \
+      (DeviceId == V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_ALTDIS) || \
+      (DeviceId == V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_RSTE) \
+    )
+
+#define IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID) || \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_PREM) || \
+      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_IBC) \
+    )
+
+#define IS_PCH_SATA_RAID_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
+    )
+
+//
+//  Combined SATA IDE/AHCI/RAID Device ID macros
+//
+#define IS_PCH_H_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) || \
+      IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) \
+    )
+
+#define IS_PCH_LP_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
+    )
+#define IS_PCH_SATA_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SATA_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SATA_DEVICE_ID(DeviceId) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
new file mode 100644
index 0000000000..00e7881408
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
@@ -0,0 +1,52 @@
+/** @file
+  Register names for PCH Storage and Communication Subsystem
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SCS_H_
+#define _PCH_REGS_SCS_H_
+
+//
+// SCS Devices proprietary PCI Config Space Registers
+//
+#define R_SCS_CFG_PCS                     0x84                          ///< PME Control Status
+#define B_SCS_CFG_PCS_PMESTS              BIT15                         ///< PME Status
+#define B_SCS_CFG_PCS_PMEEN               BIT8                          ///< PME Enable
+#define B_SCS_CFG_PCS_NSS                 BIT3                          ///< No Soft Reset
+#define B_SCS_CFG_PCS_PS                  (BIT1 | BIT0)                 ///< Power State
+#define B_SCS_CFG_PCS_PS_D3HOT            (BIT1 | BIT0)                 ///< Power State: D3Hot State
+#define R_SCS_CFG_PG_CONFIG               0xA2                          ///< PG Config
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
new file mode 100644
index 0000000000..c18e1ef38c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
@@ -0,0 +1,48 @@
+/** @file
+  Project specific SCS register definitions.
+
+  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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SCS_CNL_H_
+#define _PCH_REGS_SCS_CNL_H_
+
+//
+//  SCS SDCARD Controller PCI config
+//
+#define PCI_DEVICE_NUMBER_PCH_CNL_SCS_SDCARD      20
+#define PCI_FUNCTION_NUMBER_PCH_CNL_SCS_SDCARD    5
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
new file mode 100644
index 0000000000..449335b073
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
@@ -0,0 +1,232 @@
+/** @file
+  Register names for PCH 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SERIAL_IO_
+#define _PCH_REGS_SERIAL_IO_
+
+//
+// Serial IO Controllers General PCI Configuration Registers
+// registers accessed using PciD21FxRegBase + offset
+//
+#define R_SERIAL_IO_CFG_BAR0_LOW                        0x10
+#define B_SERIAL_IO_CFG_BAR0_LOW_BAR                    0xFFFFF000
+#define R_SERIAL_IO_CFG_BAR0_HIGH                       0x14
+#define R_SERIAL_IO_CFG_BAR1_LOW                        0x18
+#define B_SERIAL_IO_CFG_BAR1_LOW_BAR                    0xFFFFF000
+#define R_SERIAL_IO_CFG_BAR1_HIGH                       0x1C
+#define V_SERIAL_IO_CFG_BAR_SIZE                        (4 * 1024)
+#define N_SERIAL_IO_CFG_BAR_ALIGNMENT                   12
+
+#define R_SERIAL_IO_CFG_PME_CTRL_STS                    0x84
+#define B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST             (BIT1| BIT0)
+
+#define R_SERIAL_IO_CFG_D0I3MAXDEVPG                    0xA0
+#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_PMCRE              BIT16
+#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_I3E                BIT17
+#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_PGE                BIT18
+
+#define R_SERIAL_IO_CFG_INTERRUPTREG                    0x3C
+#define B_SERIAL_IO_CFG_INTERRUPTREG_INTLINE            0x000000FF
+
+//
+// Serial IO Controllers MMIO Registers
+// registers accessed : BAR0 + offset
+//
+#define R_SERIAL_IO_MEM_SSCR1                           0x4
+#define B_SERIAL_IO_MEM_SSCR1_IFS                       BIT16
+
+#define R_SERIAL_IO_MEM_PPR_CLK                         0x200
+#define B_SERIAL_IO_MEM_PPR_CLK_EN                      BIT0
+#define B_SERIAL_IO_MEM_PPR_CLK_UPDATE                  BIT31
+#define V_SERIAL_IO_MEM_PPR_CLK_M_DIV                   0x30
+#define V_SERIAL_IO_MEM_PPR_CLK_N_DIV                   0xC35
+
+#define R_SERIAL_IO_MEM_PPR_RESETS                      0x204
+#define B_SERIAL_IO_MEM_PPR_RESETS_FUNC                 BIT0
+#define B_SERIAL_IO_MEM_PPR_RESETS_APB                  BIT1
+#define B_SERIAL_IO_MEM_PPR_RESETS_IDMA                 BIT2
+
+#define R_SERIAL_IO_MEM_ACTIVE_LTR                      0x210
+#define R_SERIAL_IO_MEM_IDLE_LTR                        0x214
+#define B_SERIAL_IO_MEM_LTR_SNOOP_VALUE                 0x000003FF
+#define B_SERIAL_IO_MEM_LTR_SNOOP_SCALE                 0x00001C00
+#define B_SERIAL_IO_MEM_LTR_SNOOP_REQUIREMENT           BIT15
+
+#define R_SERIAL_IO_MEM_SPI_CS_CONTROL                  0x224
+#define B_SERIAL_IO_MEM_SPI_CS_CONTROL_STATE            BIT1
+#define B_SERIAL_IO_MEM_SPI_CS_CONTROL_MODE             BIT0
+
+#define R_SERIAL_IO_MEM_REMAP_ADR_LOW                   0x240
+#define R_SERIAL_IO_MEM_REMAP_ADR_HIGH                  0x244
+
+#define R_SERIAL_IO_MEM_I2C_SDA_HOLD                    0x7C
+#define V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE              0x002C002C
+
+//
+// I2C Controller
+// Registers accessed through BAR0 + offset
+//
+#define    R_IC_CON                            0x00 // I2c Control
+#define    B_IC_MASTER_MODE                    BIT0
+#define    B_IC_RESTART_EN                     BIT5
+#define    B_IC_SLAVE_DISABLE                  BIT6
+#define    V_IC_SPEED_STANDARD                 0x02
+#define    V_IC_SPEED_FAST                     0x04
+#define    V_IC_SPEED_HIGH                     0x06
+
+#define    R_IC_TAR                            0x04 // I2c Target Address
+#define    B_IC_TAR_10BITADDR_MASTER           BIT12
+
+#define    R_IC_DATA_CMD                       0x10  // I2c Rx/Tx Data Buffer and Command
+#define    B_IC_CMD_READ                       BIT8    // 1 = read, 0 = write
+#define    B_IC_CMD_STOP                       BIT9    // 1 = STOP
+#define    B_IC_CMD_RESTART                    BIT10   // 1 = IC_RESTART_EN
+#define    V_IC_WRITE_CMD_MASK                 0xFF
+
+#define    R_IC_SS_SCL_HCNT                    0x14 // Standard Speed I2c Clock SCL High Count
+#define    R_IC_SS_SCL_LCNT                    0x18 // Standard Speed I2c Clock SCL Low Count
+#define    R_IC_FS_SCL_HCNT                    0x1C // Full Speed I2c Clock SCL High Count
+#define    R_IC_FS_SCL_LCNT                    0x20 // Full Speed I2c Clock SCL Low Count
+#define    R_IC_HS_SCL_HCNT                    0x24 // High Speed I2c Clock SCL High Count
+#define    R_IC_HS_SCL_LCNT                    0x28 // High Speed I2c Clock SCL Low Count
+#define    R_IC_INTR_STAT                      0x2C // I2c Inetrrupt Status
+#define    R_IC_INTR_MASK                      0x30 // I2c Interrupt Mask
+#define    B_IC_INTR_GEN_CALL                  BIT11  // General call received
+#define    B_IC_INTR_START_DET                 BIT10
+#define    B_IC_INTR_STOP_DET                  BIT9
+#define    B_IC_INTR_ACTIVITY                  BIT8
+#define    B_IC_INTR_TX_ABRT                   BIT6   // Set on NACK
+#define    B_IC_INTR_TX_EMPTY                  BIT4
+#define    B_IC_INTR_TX_OVER                   BIT3
+#define    B_IC_INTR_RX_FULL                   BIT2   // Data bytes in RX FIFO over threshold
+#define    B_IC_INTR_RX_OVER                   BIT1
+#define    B_IC_INTR_RX_UNDER                  BIT0
+#define    R_IC_RAW_INTR_STAT                ( 0x34) // I2c Raw Interrupt Status
+#define    R_IC_RX_TL                        ( 0x38) // I2c Receive FIFO Threshold
+#define    R_IC_TX_TL                        ( 0x3C) // I2c Transmit FIFO Threshold
+#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and Individual Interrupts
+#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER Interrupt
+#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear RX_OVERinterrupt
+#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER interrupt
+#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
+#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
+#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE interrupt
+#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
+#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET interrupt
+#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET interrupt
+#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL interrupt
+#define    R_IC_ENABLE                       ( 0x6C) // I2c Enable
+
+#define    R_IC_STATUS                         0x70  // I2c Status
+#define    B_IC_STATUS_RFF                     BIT4   // RX FIFO is completely full
+#define    B_IC_STATUS_RFNE                    BIT3   // RX FIFO is not empty
+#define    B_IC_STATUS_TFE                     BIT2   // TX FIFO is completely empty
+#define    B_IC_STATUS_TFNF                    BIT1   // TX FIFO is not full
+#define    B_IC_STATUS_ACTIVITY                BIT0   // Controller Activity Status.
+
+#define    R_IC_TXFL R                       ( 0x74) // Transmit FIFO Level Register
+#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
+#define    R_IC_SDA_HOLD                     ( 0x7C)
+#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2c Transmit Abort Status Register
+#define    B_IC_TX_ABRT_7B_ADDR_NACK          BIT0 // NACK on 7-bit address
+
+#define    R_IC_SDA_SETUP                    ( 0x94) // I2c SDA Setup Register
+#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2c ACK General Call Register
+#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2c Enable Status Register
+#define    B_IC_EN                            BIT0   // I2c enable status
+
+#define    R_IC_CLK_GATE                     ( 0xC0)
+#define    R_IC_COMP_PARAM                   ( 0xF4) // Component Parameter Register
+#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
+#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
+
+//
+// Bridge Private Configuration Registers
+// accessed only through SB messaging. SB access = SerialIo IOSF2OCP Bridge Port ID + offset
+//
+#define R_SERIAL_IO_PCR_PMCTL                        0x1D0
+#define V_SERIAL_IO_PCR_PMCTL_PWR_GATING             0x3F
+
+#define R_SERIAL_IO_PCR_PCICFGCTRLx                 0x200
+#define V_SERIAL_IO_PCR_PCICFGCTRL_N_OFFS           0x04
+#define R_SERIAL_IO_PCR_PCICFGCTRL1                 0x200 //I2C0
+#define R_SERIAL_IO_PCR_PCICFGCTRL2                 0x204 //I2C1
+#define R_SERIAL_IO_PCR_PCICFGCTRL3                 0x208 //I2C2
+#define R_SERIAL_IO_PCR_PCICFGCTRL4                 0x20C //I2C3
+#define R_SERIAL_IO_PCR_PCICFGCTRL5                 0x210 //I2C4
+#define R_SERIAL_IO_PCR_PCICFGCTRL6                 0x214 //I2C5
+#define R_SERIAL_IO_PCR_PCICFGCTRL9                 0x218 //UA00
+#define R_SERIAL_IO_PCR_PCICFGCTRL10                0x21C //UA01
+#define R_SERIAL_IO_PCR_PCICFGCTRL11                0x220 //UA02
+#define R_SERIAL_IO_PCR_PCICFGCTRL13                0x224 //SPI0
+#define R_SERIAL_IO_PCR_PCICFGCTRL14                0x228 //SPI1
+
+#define B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS      BIT0
+#define B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN     BIT1
+#define B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS         BIT7
+#define B_SERIAL_IO_PCR_PCICFGCTRL_INT_PIN          (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_SERIAL_IO_PCR_PCICFGCTRL_INT_PIN          8
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTA             0x01
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTB             0x02
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTC             0x03
+#define V_SERIAL_IO_PCR_PCICFGCTRL_INTD             0x04
+#define B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_IRQ         0x000FF000
+#define N_SERIAL_IO_PCR_PCICFGCTRL_ACPI_IRQ         12
+#define B_SERIAL_IO_PCR_PCICFGCTRL_PCI_IRQ          0x0FF00000
+#define N_SERIAL_IO_PCR_PCICFGCTRL_PCI_IRQ          20
+
+#define R_SERIAL_IO_PCR_GPPRVRW2                            0x604
+#define B_SERIAL_IO_PCR_GPPRVRW2_PGCB_FRC_CLK_CP_EN         BIT1
+#define B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CG_EN         BIT5
+#define B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CLKREQ_CTL_EN BIT11
+#define V_SERIAL_IO_PCR_GPPRVRW2_CLK_GATING                 (B_SERIAL_IO_PCR_GPPRVRW2_PGCB_FRC_CLK_CP_EN | B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CG_EN | B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CLKREQ_CTL_EN)
+
+
+#define R_SERIAL_IO_PCR_GPPRVRW7                    0x618
+#define B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN BIT0
+#define B_SERIAL_IO_PCR_GPPRVRW7_UART1_BYTE_ADDR_EN BIT1
+#define B_SERIAL_IO_PCR_GPPRVRW7_UART2_BYTE_ADDR_EN BIT2
+
+//
+// Number of pins used by SerialIo controllers
+//
+#define PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER               2
+#define PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER              4
+#define PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL 2
+#define PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER               4
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
new file mode 100644
index 0000000000..62b859dc99
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
@@ -0,0 +1,138 @@
+/** @file
+  Device IDs for PCH Serial IO Controllers for 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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SERIAL_IO_CNL_
+#define _PCH_REGS_SERIAL_IO_CNL_
+
+//
+//  Serial IO I2C0 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0          0
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID       0x9DE8
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID        0xA368
+
+//
+//  Serial IO I2C1 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1          1
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID       0x9DE9
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID        0xA369
+
+//
+//  Serial IO I2C2 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2          2
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID       0x9DEA
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID        0xA36A
+
+//
+//  Serial IO I2C3 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3            21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3          3
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID       0x9DEB
+#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID        0xA36B
+
+//
+//  Serial IO I2C4 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4            25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4          0
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID       0x9DC5
+
+//
+//  Serial IO I2C5 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5            25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5          1
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID       0x9DC6
+
+//
+//  Serial IO SPI0 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0            30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0          2
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID       0x9DAA
+#define V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID        0xA32A
+
+//
+//  Serial IO SPI1 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1            30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1          3
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID       0x9DAB
+#define V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID        0xA32B
+
+//
+//  Serial IO UART0 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0           30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0         0
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID      0x9DA8
+#define V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID       0xA328
+
+//
+//  Serial IO UART1 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1           30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1         1
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID      0x9DA9
+#define V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID       0xA329
+
+//
+//  Serial IO UART2 Controller Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2           25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2         2
+
+#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID      0x9DC7
+#define V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID       0xA347
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
new file mode 100644
index 0000000000..e571a6a127
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
@@ -0,0 +1,151 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 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 (D31:F4)
+//
+#define PCI_DEVICE_NUMBER_PCH_SMBUS           31
+#define PCI_FUNCTION_NUMBER_PCH_SMBUS         4
+#define R_SMBUS_CFG_BASE                      0x20
+#define V_SMBUS_CFG_BASE_SIZE                 (1 << 5)
+#define B_SMBUS_CFG_BASE_BAR                  0x0000FFE0
+#define R_SMBUS_CFG_HOSTC                     0x40
+#define B_SMBUS_CFG_HOSTC_SPDWD               BIT4
+#define B_SMBUS_CFG_HOSTC_SSRESET             BIT3
+#define B_SMBUS_CFG_HOSTC_I2C_EN              BIT2
+#define B_SMBUS_CFG_HOSTC_SMI_EN              BIT1
+#define B_SMBUS_CFG_HOSTC_HST_EN              BIT0
+#define R_SMBUS_CFG_TCOBASE                   0x50
+#define B_SMBUS_CFG_TCOBASE_BAR               0x0000FFE0
+#define R_SMBUS_CFG_TCOCTL                    0x54
+#define B_SMBUS_CFG_TCOCTL_TCO_BASE_EN        BIT8
+#define B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK      BIT0
+#define R_SMBUS_CFG_64                        0x64
+#define R_SMBUS_CFG_80                        0x80
+
+//
+// SMBus I/O Registers
+//
+#define R_SMBUS_IO_HSTS                  0x00  ///< Host Status Register R/W
+#define B_SMBUS_IO_HBSY                  0x01
+#define B_SMBUS_IO_INTR                  0x02
+#define B_SMBUS_IO_DERR                  0x04
+#define B_SMBUS_IO_BERR                  0x08
+#define B_SMBUS_IO_FAIL                  0x10
+#define B_SMBUS_IO_SMBALERT_STS          0x20
+#define B_SMBUS_IO_IUS                   0x40
+#define B_SMBUS_IO_BYTE_DONE_STS         0x80
+#define B_SMBUS_IO_ERROR                 (B_SMBUS_IO_DERR | B_SMBUS_IO_BERR | B_SMBUS_IO_FAIL)
+#define B_SMBUS_IO_HSTS_ALL              0xFF
+#define R_SMBUS_IO_HCTL                  0x02  ///< Host Control Register R/W
+#define B_SMBUS_IO_INTREN                0x01
+#define B_SMBUS_IO_KILL                  0x02
+#define B_SMBUS_IO_SMB_CMD               0x1C
+#define V_SMBUS_IO_SMB_CMD_QUICK         0x00
+#define V_SMBUS_IO_SMB_CMD_BYTE          0x04
+#define V_SMBUS_IO_SMB_CMD_BYTE_DATA     0x08
+#define V_SMBUS_IO_SMB_CMD_WORD_DATA     0x0C
+#define V_SMBUS_IO_SMB_CMD_PROCESS_CALL  0x10
+#define V_SMBUS_IO_SMB_CMD_BLOCK         0x14
+#define V_SMBUS_IO_SMB_CMD_IIC_READ      0x18
+#define V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS 0x1C
+#define B_SMBUS_IO_LAST_BYTE             0x20
+#define B_SMBUS_IO_START                 0x40
+#define B_SMBUS_IO_PEC_EN                0x80
+#define R_SMBUS_IO_HCMD                  0x03  ///< Host Command Register R/W
+#define R_SMBUS_IO_TSA                   0x04  ///< Transmit Slave Address Register R/W
+#define B_SMBUS_IO_RW_SEL                0x01
+#define B_SMBUS_IO_READ                  0x01  // RW
+#define B_SMBUS_IO_WRITE                 0x00  // RW
+#define B_SMBUS_IO_ADDRESS               0xFE
+#define R_SMBUS_IO_HD0                   0x05  ///< Data 0 Register R/W
+#define R_SMBUS_IO_HD1                   0x06  ///< Data 1 Register R/W
+#define R_SMBUS_IO_HBD                   0x07  ///< Host Block Data Register R/W
+#define R_SMBUS_IO_PEC                   0x08  ///< Packet Error Check Data Register R/W
+#define R_SMBUS_IO_RSA                   0x09  ///< Receive Slave Address Register R/W
+#define B_SMBUS_IO_SLAVE_ADDR            0x7F
+#define R_SMBUS_IO_SD                    0x0A  ///< Receive Slave Data Register R/W
+#define R_SMBUS_IO_AUXS                  0x0C  ///< Auxiliary Status Register R/WC
+#define B_SMBUS_IO_CRCE                  0x01
+#define B_SMBUS_IO_STCO                  0x02  ///< SMBus TCO Mode
+#define R_SMBUS_IO_AUXC                  0x0D  ///< Auxiliary Control Register R/W
+#define B_SMBUS_IO_AAC                   0x01
+#define B_SMBUS_IO_E32B                  0x02
+#define R_SMBUS_IO_SMLC                  0x0E  ///< SMLINK Pin Control Register R/W
+#define B_SMBUS_IO_SMLINK0_CUR_STS       0x01
+#define B_SMBUS_IO_SMLINK1_CUR_STS       0x02
+#define B_SMBUS_IO_SMLINK_CLK_CTL        0x04
+#define R_SMBUS_IO_SMBC                  0x0F  ///< SMBus Pin Control Register R/W
+#define B_SMBUS_IO_SMBCLK_CUR_STS        0x01
+#define B_SMBUS_IO_SMBDATA_CUR_STS       0x02
+#define B_SMBUS_IO_SMBCLK_CTL            0x04
+#define R_SMBUS_IO_SSTS                  0x10  ///< Slave Status Register R/WC
+#define B_SMBUS_IO_HOST_NOTIFY_STS       0x01
+#define R_SMBUS_IO_SCMD                  0x11  ///< Slave Command Register R/W
+#define B_SMBUS_IO_HOST_NOTIFY_INTREN    0x01
+#define B_SMBUS_IO_HOST_NOTIFY_WKEN      0x02
+#define B_SMBUS_IO_SMBALERT_DIS          0x04
+#define R_SMBUS_IO_NDA                   0x14  ///< Notify Device Address Register RO
+#define B_SMBUS_IO_DEVICE_ADDRESS        0xFE
+#define R_SMBUS_IO_NDLB                  0x16  ///< Notify Data Low Byte Register RO
+#define R_SMBUS_IO_NDHB                  0x17  ///< Notify Data High Byte Register RO
+
+//
+// SMBus Private Config Registers
+// (PID:SMB)
+//
+#define R_SMBUS_PCR_TCOCFG                0x00                        ///< TCO Configuration register
+#define B_SMBUS_PCR_TCOCFG_IE             BIT7                        ///< TCO IRQ Enable
+#define B_SMBUS_PCR_TCOCFG_IS             (BIT2 | BIT1 | BIT0)        ///< TCO IRQ Select
+#define V_SMBUS_PCR_TCOCFG_IRQ_9          0x00
+#define V_SMBUS_PCR_TCOCFG_IRQ_10         0x01
+#define V_SMBUS_PCR_TCOCFG_IRQ_11         0x02
+#define V_SMBUS_PCR_TCOCFG_IRQ_20         0x04                        ///< only if APIC enabled
+#define V_SMBUS_PCR_TCOCFG_IRQ_21         0x05                        ///< only if APIC enabled
+#define V_SMBUS_PCR_TCOCFG_IRQ_22         0x06                        ///< only if APIC enabled
+#define V_SMBUS_PCR_TCOCFG_IRQ_23         0x07                        ///< only if APIC enabled
+#define R_SMBUS_PCR_SMBTM                 0x04                        ///< SMBus Test Mode
+#define B_SMBUS_PCR_SMBTM_SMBCT           BIT1                        ///< SMBus Counter
+#define B_SMBUS_PCR_SMBTM_SMBDG           BIT0                        ///< SMBus Deglitch
+#define R_SMBUS_PCR_SCTM                  0x08                        ///< Short Counter Test Mode
+#define B_SMBUS_PCR_SCTM_SSU              BIT31                       ///< Simulation Speed-Up
+#define R_SMBUS_PCR_GC                    0x0C                        ///< General Control
+#define B_SMBUS_PCR_GC_FD                 BIT0                        ///< Function Disable
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
new file mode 100644
index 0000000000..013603ca25
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
@@ -0,0 +1,295 @@
+/** @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
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SPI_H_
+#define _PCH_REGS_SPI_H_
+
+//
+// SPI Registers (D31:F5)
+//
+
+#define PCI_DEVICE_NUMBER_PCH_SPI           31
+#define PCI_FUNCTION_NUMBER_PCH_SPI         5
+
+#define R_SPI_CFG_BAR0                      0x10
+#define B_SPI_CFG_BAR0_MASK                 0x0FFF
+
+#define R_SPI_CFG_BDE                       0xD8
+#define B_SPI_CFG_BDE_F8                    0x8000
+#define B_SPI_CFG_BDE_F0                    0x4000
+#define B_SPI_CFG_BDE_E8                    0x2000
+#define B_SPI_CFG_BDE_E0                    0x1000
+#define B_SPI_CFG_BDE_D8                    0x0800
+#define B_SPI_CFG_BDE_D0                    0x0400
+#define B_SPI_CFG_BDE_C8                    0x0200
+#define B_SPI_CFG_BDE_C0                    0x0100
+#define B_SPI_CFG_BDE_LEG_F                 0x0080
+#define B_SPI_CFG_BDE_LEG_E                 0x0040
+#define B_SPI_CFG_BDE_70                    0x0008
+#define B_SPI_CFG_BDE_60                    0x0004
+#define B_SPI_CFG_BDE_50                    0x0002
+#define B_SPI_CFG_BDE_40                    0x0001
+
+#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 B_SPI_CFG_BC_OSFH                   BIT9            ///< OS Function Hide
+#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 V_SPI_CFG_BC_BBS_LPC                1               ///< Boot BIOS strapped to LPC
+#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_EN_CACHE_EN   0x02            ///< Prefetching and Caching enabled
+#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS 0x01            ///< No prefetching and no caching
+#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_EN  0x00            ///< No prefetching, but caching enabled
+#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_BFPR                      0x00                          ///< BIOS Flash Primary Region Register(32bits), which is RO and contains the same value from FREG1
+#define B_SPI_MEM_BFPR_PRL                  0x7FFF0000                    ///< BIOS Flash Primary Region Limit mask
+#define N_SPI_MEM_BFPR_PRL                  16                            ///< BIOS Flash Primary Region Limit bit position
+#define B_SPI_MEM_BFPR_PRB                  0x00007FFF                    ///< BIOS Flash Primary Region Base mask
+#define N_SPI_MEM_BFPR_PRB                  0                             ///< BIOS Flash Primary Region Base bit position
+#define R_SPI_MEM_HSFSC                     0x04                          ///< Hardware Sequencing Flash Status and Control Register(32bits)
+#define B_SPI_MEM_HSFSC_FSMIE               BIT31                         ///< Flash SPI SMI# Enable
+#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_PRR34_LOCKDN        BIT12                         ///< PRR3 PRR4 Lock-Down
+#define B_SPI_MEM_HSFSC_WRSDIS              BIT11                         ///< Write Status Disable
+#define B_SPI_MEM_HSFSC_SAF_CE              BIT8                          ///< SAF ctype error
+#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_SAF_LE              BIT6                          ///< SAF link error
+#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_FDATA01                   0x14                          ///< SPI Data 01
+#define R_SPI_MEM_FDATA02                   0x18                          ///< SPI Data 02
+#define R_SPI_MEM_FDATA03                   0x1C                          ///< SPI Data 03
+#define R_SPI_MEM_FDATA04                   0x20                          ///< SPI Data 04
+#define R_SPI_MEM_FDATA05                   0x24                          ///< SPI Data 05
+#define R_SPI_MEM_FDATA06                   0x28                          ///< SPI Data 06
+#define R_SPI_MEM_FDATA07                   0x2C                          ///< SPI Data 07
+#define R_SPI_MEM_FDATA08                   0x30                          ///< SPI Data 08
+#define R_SPI_MEM_FDATA09                   0x34                          ///< SPI Data 09
+#define R_SPI_MEM_FDATA10                   0x38                          ///< SPI Data 10
+#define R_SPI_MEM_FDATA11                   0x3C                          ///< SPI Data 11
+#define R_SPI_MEM_FDATA12                   0x40                          ///< SPI Data 12
+#define R_SPI_MEM_FDATA13                   0x44                          ///< SPI Data 13
+#define R_SPI_MEM_FDATA14                   0x48                          ///< SPI Data 14
+#define R_SPI_MEM_FDATA15                   0x4C                          ///< SPI Data 15
+#define R_SPI_MEM_FRAP                      0x50                          ///< Flash Region Access Permisions 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_FREG1_BIOS                0x58                          ///< Flash Region 1(BIOS)(32bits)
+#define R_SPI_MEM_FREG2_ME                  0x5C                          ///< Flash Region 2(ME)(32bits)
+#define R_SPI_MEM_FREG3_GBE                 0x60                          ///< Flash Region 3(GbE)(32bits)
+#define R_SPI_MEM_FREG4_PLATFORM_DATA       0x64                          ///< Flash Region 4(Platform Data)(32bits)
+#define R_SPI_MEM_FREG5_DER                 0x68                          ///< Flash Region 5(Device Expansion Region)(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 R_SPI_MEM_PR1                       0x88                          ///< Protected Region 1 Register
+#define R_SPI_MEM_PR2                       0x8C                          ///< Protected Region 2 Register
+#define R_SPI_MEM_PR3                       0x90                          ///< Protected Region 3 Register
+#define R_SPI_MEM_PR4                       0x94                          ///< Protected Region 4 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_SFRAP                     0xB0                          ///< Secondary Flash Regions Access Permisions Register
+#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_REGN            0x2000                        ///< Region
+#define V_SPI_MEM_FDOC_FDSS_MSTR            0x3000                        ///< Master
+#define V_SPI_MEM_FDOC_FDSS_PCHS            0x4000                        ///< PCH soft straps
+#define V_SPI_MEM_FDOC_FDSS_SFDP            0x5000                        ///< SFDP Parameter Table
+#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 B_SPI_MEM_SFDPX_VSCCX_EO_4K         BIT28                         ///< 4k Erase valid (EO_4k_valid)
+#define B_SPI_MEM_SFDPX_VSCCX_RPMC          BIT27                         ///< RPMC Supported
+#define B_SPI_MEM_SFDPX_VSCCX_DPD           BIT26                         ///< Deep Powerdown Supported
+#define B_SPI_MEM_SFDPX_VSCCX_SUSRES        BIT25                         ///< Suspend/Resume Supported
+#define B_SPI_MEM_SFDPX_VSCCX_SOFTRES       BIT24                         ///< Soft Reset Supported
+#define B_SPI_MEM_SFDPX_VSCCX_64k_EO_MASK   0x00FF0000                    ///< 64k Erase Opcode (EO_64k)
+#define B_SPI_MEM_SFDPX_VSCCX_4k_EO_MASK    0x0000FF00                    ///< 4k Erase Opcode (EO_4k)
+#define B_SPI_MEM_SFDPX_VSCCX_QER           (BIT7 | BIT6 | BIT5)          ///< Quad Enable Requirements
+#define B_SPI_MEM_SFDPX_VSCCX_WEWS          BIT4                          ///< Write Enable on Write Status
+#define B_SPI_MEM_SFDPX_VSCCX_WSR           BIT3                          ///< Write Status Required
+#define B_SPI_MEM_SFDPX_VSCCX_WG_64B        BIT2                          ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
+#define R_SPI_MEM_SFDP1_VSCC1               0xC8                          ///< Vendor Specific Component Capabilities Register(32 bits)
+#define R_SPI_MEM_PINTX                     0xCC                          ///< Parameter Table Index
+#define N_SPI_MEM_PINTX_SPT                 14
+#define V_SPI_MEM_PINTX_SPT_CPT0            0x0                           ///< Component 0 Property Parameter Table
+#define V_SPI_MEM_PINTX_SPT_CPT1            0x1                           ///< Component 1 Property Parameter Table
+#define N_SPI_MEM_PINTX_HORD                12
+#define V_SPI_MEM_PINTX_HORD_SFDP           0x0                           ///< SFDP Header
+#define V_SPI_MEM_PINTX_HORD_PT             0x1                           ///< Parameter Table Header
+#define V_SPI_MEM_PINTX_HORD_DATA           0x2                           ///< Data
+#define R_SPI_MEM_PTDATA                    0xD0                          ///< Parameter Table Data
+#define R_SPI_MEM_SBRS                      0xD4                          ///< SPI Bus Requester Status
+
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_SPI_FLASH_FDBAR_FLVALSIG            0x00                          ///< Flash Valid Signature
+#define V_SPI_FLASH_FDBAR_FLVALSIG            0x0FF0A55A
+#define R_SPI_FLASH_FDBAR_FLASH_MAP0          0x04
+#define B_SPI_FLASH_FDBAR_FCBA                0x000000FF                    ///< Flash Component Base Address
+#define B_SPI_FLASH_FDBAR_NC                  0x00000300                    ///< Number Of Components
+#define N_SPI_FLASH_FDBAR_NC                  8                             ///< Number Of Components
+#define V_SPI_FLASH_FDBAR_NC_1                0x00000000
+#define V_SPI_FLASH_FDBAR_NC_2                0x00000100
+#define B_SPI_FLASH_FDBAR_FRBA                0x00FF0000                    ///< Flash Region Base Address
+#define B_SPI_FLASH_FDBAR_NR                  0x07000000                    ///< Number Of Regions
+#define R_SPI_FLASH_FDBAR_FLASH_MAP1          0x08
+#define B_SPI_FLASH_FDBAR_FMBA                0x000000FF                    ///< Flash Master Base Address
+#define B_SPI_FLASH_FDBAR_NM                  0x00000700                    ///< Number Of Masters
+#define B_SPI_FLASH_FDBAR_FPSBA               0x00FF0000                    ///< PCH Strap Base Address, [23:16] represents [11:4]
+#define N_SPI_FLASH_FDBAR_FPSBA               16                            ///< PCH Strap base Address bit position
+#define N_SPI_FLASH_FDBAR_FPSBA_REPR          4                             ///< PCH Strap base Address bit represents position
+#define B_SPI_FLASH_FDBAR_PCHSL               0xFF000000                    ///< PCH Strap Length, [31:24] represents number of Dwords
+#define N_SPI_FLASH_FDBAR_PCHSL               24                            ///< PCH Strap Length bit position
+#define R_SPI_FLASH_FDBAR_FLASH_MAP2          0x0C
+#define B_SPI_FLASH_FDBAR_FCPUSBA             0x000000FF                    ///< CPU Strap Base Address, [7:0] represents [11:4]
+#define N_SPI_FLASH_FDBAR_FCPUSBA             0                             ///< CPU Strap Base Address bit position
+#define N_SPI_FLASH_FDBAR_FCPUSBA_REPR        4                             ///< CPU Strap Base Address bit represents position
+#define B_SPI_FLASH_FDBAR_CPUSL               0x0000FF00                    ///< CPU Strap Length, [15:8] represents number of Dwords
+#define N_SPI_FLASH_FDBAR_CPUSL               8                             ///< CPU Strap Length bit position
+//
+// Flash Component Base Address (FCBA) from Flash Region 0
+//
+#define R_SPI_FLASH_FCBA_FLCOMP               0x00                          ///< Flash Components Register
+#define B_SPI_FLASH_FLCOMP_RIDS_FREQ          (BIT29 | BIT28 | BIT27)       ///< Read ID and Read Status Clock Frequency
+#define B_SPI_FLASH_FLCOMP_WE_FREQ            (BIT26 | BIT25 | BIT24)       ///< Write and Erase Clock Frequency
+#define B_SPI_FLASH_FLCOMP_FRCF_FREQ          (BIT23 | BIT22 | BIT21)       ///< Fast Read Clock Frequency
+#define B_SPI_FLASH_FLCOMP_FR_SUP             BIT20                         ///< Fast Read Support.
+#define B_SPI_FLASH_FLCOMP_RC_FREQ            (BIT19 | BIT18 | BIT17)       ///< Read Clock Frequency.
+#define V_SPI_FLASH_FLCOMP_FREQ_48MHZ         0x02
+#define V_SPI_FLASH_FLCOMP_FREQ_30MHZ         0x04
+#define V_SPI_FLASH_FLCOMP_FREQ_17MHZ         0x06
+#define B_SPI_FLASH_FLCOMP_COMP1_MASK         0xF0                          ///< Flash Component 1 Size MASK
+#define N_SPI_FLASH_FLCOMP_COMP1              4                             ///< Flash Component 1 Size bit position
+#define B_SPI_FLASH_FLCOMP_COMP0_MASK         0x0F                          ///< Flash Component 0 Size MASK
+#define V_SPI_FLASH_FLCOMP_COMP_512KB         0x80000
+//
+// Descriptor Upper Map Section from Flash Region 0
+//
+#define R_SPI_FLASH_UMAP1                     0xEFC                         ///< Flash Upper Map 1
+#define B_SPI_FLASH_UMAP1_VTBA                0x000000FF                    ///< VSCC Table Base Address
+#define B_SPI_FLASH_UMAP1_VTL                 0x0000FF00                    ///< VSCC Table Length
+
+//
+// SPI Private Configuration Space Registers
+//
+#define R_SPI_PCR_CLK_CTL               0xC004
+#define R_SPI_PCR_PWR_CTL               0xC008
+#define R_SPI_PCR_ESPI_SOFTSTRAPS       0xC210
+#define B_SPI_PCR_ESPI_SLAVE            BIT12
+
+//
+// MMP0
+//
+#define R_PCH_SPI_STRP_MMP0                 0xC4    ///< MMP0 Soft strap offset
+#define B_PCH_SPI_STRP_MMP0                 0x10    ///< MMP0 Soft strap bit
+
+
+#define R_PCH_SPI_STRP_SFDP                 0xF0    ///< PCH Soft Strap SFDP
+#define B_PCH_SPI_STRP_SFDP_QIORE           BIT3    ///< Quad IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_QORE            BIT2    ///< Quad Output Read Enable
+#define B_PCH_SPI_STRP_SFDP_DIORE           BIT1    ///< Dual IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_DORE            BIT0    ///< Dual Output Read Enable
+
+//
+// Descriptor Record 0
+//
+#define R_PCH_SPI_STRP_DSCR_0               0x00    ///< PCH Soft Strap 0
+#define B_PCH_SPI_STRP_DSCR_0_PTT_SUPP      BIT22   ///< PTT Supported
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h
new file mode 100644
index 0000000000..fb93a62364
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h
@@ -0,0 +1,49 @@
+/** @file
+  Register names for PCH Thermal 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
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_THERMAL_H_
+#define _PCH_REGS_THERMAL_H_
+
+//
+//  Thermal Device Registers (D18:0)
+//
+#define PCI_DEVICE_NUMBER_PCH_THERMAL   18
+#define PCI_FUNCTION_NUMBER_PCH_THERMAL 0
+#define R_THERMAL_CFG_MEM_TBAR              0x10
+#define B_THERMAL_CFG_MEM_TBAR_MASK         0xFFFFF000
+#define R_THERMAL_CFG_MEM_TBARH             0x14
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
new file mode 100644
index 0000000000..21f9839546
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
@@ -0,0 +1,134 @@
+/** @file
+  Register names for PCH TraceHub 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
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_TRACE_HUB_H_
+#define _PCH_REGS_TRACE_HUB_H_
+
+//
+// TraceHub Registers (D31:F7)
+//
+#define PCI_DEVICE_NUMBER_PCH_TRACE_HUB               31
+#define PCI_FUNCTION_NUMBER_PCH_TRACE_HUB             7
+
+#define R_TRACE_HUB_CFG_CSR_MTB_LBAR                  0x10
+#define B_TRACE_HUB_CFG_CSR_MTB_RBAL                  0xFFF00000
+#define R_TRACE_HUB_CFG_CSR_MTB_UBAR                  0x14
+#define B_TRACE_HUB_CFG_CSR_MTB_RBAU                  0xFFFFFFFF
+#define R_TRACE_HUB_CFG_SW_LBAR                       0x18
+#define R_TRACE_HUB_CFG_SW_UBAR                       0x1C
+#define B_TRACE_HUB_CFG_SW_RBAU                       0xFFFFFFFF
+#define R_TRACE_HUB_CFG_RTIT_LBAR                     0x20
+#define B_TRACE_HUB_CFG_RTIT_RBAL                     0xFFFFFF00
+#define R_TRACE_HUB_CFG_RTIT_UBAR                     0x24
+#define B_TRACE_HUB_CFG_RTIT_RBAU                     0xFFFFFFFF
+#define R_TRACE_HUB_CFG_MSICID                        0x40
+#define R_TRACE_HUB_CFG_MSINCP                        0x41
+#define R_TRACE_HUB_CFG_MSIMC                         0x42
+#define R_TRACE_HUB_CFG_MSILMA                        0x44
+#define R_TRACE_HUB_CFG_MSIUMA                        0x48
+#define R_TRACE_HUB_CFG_MSIMD                         0x4C
+#define B_TRACE_HUB_CFG_FW_RBAU                       0xFFFFFFFF
+#define R_TRACE_HUB_CFG_DSC                           0x80
+#define B_TRACE_HUB_CFG_BYP                           BIT0 //< TraceHub Bypass
+#define R_TRACE_HUB_CFG_DSS                           0x81
+#define R_TRACE_HUB_CFG_ISTOT                         0x84
+#define R_TRACE_HUB_CFG_ICTOT                         0x88
+#define R_TRACE_HUB_CFG_IPAD                          0x8C
+#define R_TRACE_HUB_CFG_DSD                           0x90
+
+//
+// Offsets from CSR_MTB_BAR
+//
+#define R_TRACE_HUB_MEM_MTB_GTHOPT0                   0x00
+#define B_TRACE_HUB_MEM_MTB_GTHOPT0_P0FLUSH           BIT7
+#define B_TRACE_HUB_MEM_MTB_GTHOPT0_P1FLUSH           BIT15
+#define V_TRACE_HUB_MEM_MTB_SWDEST_PTI                0x0A
+#define V_TRACE_HUB_MEM_MTB_SWDEST_MEMEXI             0x08
+#define V_TRACE_HUB_MEM_MTB_SWDEST_DISABLE            0x00
+#define R_TRACE_HUB_MEM_MTB_SWDEST_1                  0x0C
+#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_1              0x0000000F
+#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_2              0x000000F0
+#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_3              0x00000F00
+#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_1              0x0000F000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_2              0x000F0000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_3              0x00F00000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_AUDIO              0x0F000000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_PMC                0xF0000000
+#define R_TRACE_HUB_MEM_MTB_SWDEST_2                  0x10
+#define B_TRACE_HUB_MEM_MTB_SWDEST_FTH                0x0000000F
+#define R_TRACE_HUB_MEM_MTB_SWDEST_3                  0x14
+#define B_TRACE_HUB_MEM_MTB_SWDEST_MAESTRO            0x00000F00
+#define B_TRACE_HUB_MEM_MTB_SWDEST_MIPICAM            0x0F000000
+#define B_TRACE_HUB_MEM_MTB_SWDEST_AET                0xF0000000
+#define R_TRACE_HUB_MEM_MTB_SWDEST_4                  0x18
+#define R_TRACE_HUB_MEM_MTB_MSC0CTL                   0xA0100
+#define R_TRACE_HUB_MEM_MTB_MSC1CTL                   0xA0200
+#define V_TRACE_HUB_MEM_MTB_MSCNMODE_DCI              0x2
+#define V_TRACE_HUB_MEM_MTB_MSCNMODE_DEBUG            0x3
+#define B_TRACE_HUB_MEM_MTB_MSCNLEN                   (BIT10 | BIT9 | BIT8)
+#define B_TRACE_HUB_MEM_MTB_MSCNMODE                  (BIT5 | BIT4)
+#define N_TRACE_HUB_MEM_MTB_MSCNMODE                  0x4
+#define B_TRACE_HUB_MEM_MTB_MSCN_RD_HDR_OVRD          BIT2
+#define B_TRACE_HUB_MEM_MTB_WRAPENN                   BIT1
+#define B_TRACE_HUB_MEM_MTB_MSCNEN                    BIT0
+#define R_TRACE_HUB_MEM_MTB_GTHSTAT                   0xD4
+#define R_TRACE_HUB_MEM_MTB_SCR2                      0xD8
+#define B_TRACE_HUB_MEM_MTB_SCR2_FCD                  BIT0
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF2              BIT2
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF3              BIT3
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF4              BIT4
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF5              BIT5
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF6              BIT6
+#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF7              BIT7
+#define R_TRACE_HUB_MEM_MTB_MSC0BAR                   0xA0108
+#define R_TRACE_HUB_MEM_MTB_MSC0SIZE                  0xA010C
+#define R_TRACE_HUB_MEM_MTB_MSC1BAR                   0xA0208
+#define R_TRACE_HUB_MEM_MTB_MSC1SIZE                  0xA020C
+#define R_TRACE_HUB_MEM_MTB_STREAMCFG1                0xA1000
+#define R_TRACE_HUB_MEM_MTB_SCR                       0xC8
+#define R_TRACE_HUB_MEM_MTB_GTH_FREQ                  0xCC
+#define V_TRACE_HUB_MEM_MTB_SCR                       0x00130000
+#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0           0xE0
+#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD1           0xE4
+#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD10          0xE40
+#define R_TRACE_HUB_MEM_MTB_CTPGCS                    0x1C14
+#define B_TRACE_HUB_MEM_MTB_CTPEN                     BIT0
+#define V_TRACE_HUB_MEM_MTB_CHLCNT                    0x80
+#define R_TRACE_HUB_MEM_CSR_MTB_TSUCTRL               0x2000
+#define B_TRACE_HUB_MEM_CSR_MTB_TSUCTRL_CTCRESYNC     BIT0
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private include headers

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

Adds the following header files:
 * Pch/Include/Private

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h     |  16 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h       | 273 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h    | 115 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h            |  92 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h      | 269 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h          |  58 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h |  25 ++
 7 files changed, 848 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
new file mode 100644
index 0000000000..6c9d10e928
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
@@ -0,0 +1,16 @@
+/** @file
+    CnlPchLp Dx HSIO Header File
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CNL_PCH_LP_HSIO_DX_H_
+#define _CNL_PCH_LP_HSIO_DX_H_
+
+#define CNL_PCH_LP_HSIO_VER_DX   0x7
+
+
+extern UINT8                      CnlPchLpChipsetInitTable_Dx[5072];
+extern UINT8                      CnlPchLpChipsetInitTable_eDBC_Dx[4612];
+#endif //_CNL_PCH_LP_HSIO_DX_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
new file mode 100644
index 0000000000..5569da670d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
@@ -0,0 +1,273 @@
+/** @file
+  The GUID definition for PchConfigHob
+
+  Copyright (c) 2019 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 <ConfigBlock/SmbusConfig.h>
+#include <ConfigBlock/InterruptConfig.h>
+#include <ConfigBlock/PcieRpConfig.h>
+#include <ConfigBlock/SataConfig.h>
+#include <ConfigBlock/FlashProtectionConfig.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];
+  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 describes interrupt settings for PCH HOB.
+///
+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
+  UINT8                        PxRcConfig[PCH_MAX_PXRC_CONFIG];                 ///< PCI interrupt routing for 8259 PIC controller
+} INTERRUPT_HOB;
+
+///
+/// The CNVI_HOB block describes CNVi device.
+///
+typedef struct {
+  UINT32 Mode                      :  1;         ///< 0: Disabled, <b>1: Auto</b>
+  UINT32 RsvdBits0                 : 31;
+} CNVI_HOB;
+
+/**
+  The SERIAL_IO block provides the configurations to set the Serial IO controllers
+**/
+typedef struct {
+  /**
+       0: Disabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - Device will be disabled in PSF
+          - !important! If given device is Function 0 and not all other LPSS functions on given device
+                        are disabled, then 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: Pci</b>;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be enabled in PSF
+          - Only Bar 0 will be enabled
+       2: Acpi;
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+    @note Intel does not provide Windows SerialIo drivers for this mode
+       3: Hidden;
+          Designated for Kernel Debug and Legacy UART configuartion, might also be used for IO Expander on I2C
+          - Device is placed in D0
+          - Gpio pin configuration in native mode for each assigned pin
+            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
+          - Device will be hidden in PSF and not available to PCI enumerator
+          - Both BARs are enabled, BAR1 becomes devices Pci config Space
+          - !important! In this mode UART will work in 16550 Legacy 8BIT Mode, it's resources will be assigned to mother board through ACPI (PNP0C02)
+    @note Considering the PcdSerialIoUartDebugEnable and PcdSerialIoUartNumber for all SerialIo UARTx,
+          the PCD is more meaningful to represent the board design. It means, if PcdSerialIoUartDebugEnable is not 0,
+          the board is designed to use the SerialIo UART for debug message and the PcdSerialIoUartNumber is dedicated
+          to be Debug UART usage. Therefore, it should grayout the option from setup menu since no other options
+          available for this UART controller on this board, and also override the policy default accordingly.
+          While PcdSerialIoUartDebugEnable is 0, then it's allowed to configure the UART controller by policy.
+  **/
+  UINT8  DevMode[PCH_MAX_SERIALIO_CONTROLLERS];
+  UINT32 DebugUartNumber           :  2;                    ///< UART number for debug purpose. 0:UART0, 1: UART1, <b>2:UART2</b>
+  UINT32 EnableDebugUartAfterPost  :  1;                    ///< Enable debug UART controller after post. 0: disabled, <b>1: enabled</b>
+  UINT32 RsvdBits0                 : 29;
+} SERIAL_IO_HOB;
+
+
+///
+/// The PCH_PCIE_CONFIG 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];
+  /**
+    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;
+} PCIERP_HOB;
+
+typedef struct {
+  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1: Enable</b>
+  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  RsvdBits0             : 26;    ///< Reserved bits
+} HDAUDIO_HOB;
+
+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];
+  /**
+    This member describes the details of implementation of Intel RST for PCIe Storage remapping (Intel RST Driver is required)
+  **/
+  PCH_RST_PCIE_STORAGE_CONFIG   RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
+} SATA_HOB;
+
+///
+/// The SCS_HOB block describes Storage and Communication Subsystem (SCS) settings for PCH.
+///
+typedef struct {
+  UINT32  ScsEmmcEnabled                      :  2;  ///< Determine if eMMC is enabled - 0: Disabled, <b>1: Enabled</b>.
+  UINT32  ScsEmmcHs400Enabled                 :  1;  ///< Determine eMMC HS400 Mode if ScsEmmcEnabled - <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  ScsEmmcHs400TuningRequired          :  1;
+  UINT32  ScsEmmcHs400DllDataValid            :  1;  ///< Set if HS400 Tuning Data Valid
+  UINT32  ScsEmmcHs400DriverStrength          :  3;  ///< I/O driver strength: <b>0 - 33 Ohm</b>, 1 - 40 Ohm, 2 - 50 Ohm
+  UINT32  ScsSdPowerEnableActiveHigh          :  1;  ///< Sd PWREN# active high
+  UINT32  ScsSdCardEnabled                    :  1;  ///< Sd card enabled
+  UINT32  RsvdBits                            : 22;
+} SCS_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 RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the upper
+    and lower 128-byte bank of RTC RAM. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  RtcMemoryLock   :  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        : 28;
+} 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                  SlpS0VmRuntimeControl        :  1;     /// < SLP_S0 Voltage Margining Runtime Control. <b>0: Disable</b>; 1: Enable.
+  UINT32                  SlpS0Vm070VSupport           :  1;     /// < SLP_S0 0.70V Voltage Margining Support. <b>0: Disable</b>; 1: Enable.
+  UINT32                  SlpS0Vm075VSupport           :  1;     /// < SLP_S0 0.75V Voltage Margining Support. <b>0: Disable</b>; 1: Enable.
+  UINT32                  PsOnEnable                   :  1;     /// < Indicates if PS_ON support has been enabled, <b>0: Disable</b>; 1: Enable.
+  UINT32                  RsvdBits1                    : 28;
+} PM_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 bytes
+} PCH_TRACEHUB_HOB;
+
+/**
+  PCH eSPI HOB settings.
+**/
+typedef struct {
+  UINT32  BmeMasterSlaveEnabled :  1; // <b>0 = BME disable</b>; 1 = BME enable
+  UINT32  RsvdBits              : 31;
+} PCH_ESPI_HOB;
+
+
+///
+/// Pch Config Hob
+///
+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
+  SCS_HOB            Scs;                ///< Scs HOB definition
+  CNVI_HOB           Cnvi;               ///< Cnvi 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
+  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
+
+} PCH_CONFIG_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
new file mode 100644
index 0000000000..faaff9f497
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
@@ -0,0 +1,115 @@
+/** @file
+  Header file for PchHdaLib Endpoint descriptors.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_ENDPOINTS_H_
+#define _PCH_HDA_ENDPOINTS_H_
+
+#include <Private/Library/DxePchHdaNhlt.h>
+
+typedef enum {
+  HdaDmicX1       = 0,
+  HdaDmicX2,
+  HdaDmicX4,
+  HdaBtRender,
+  HdaBtCapture,
+  HdaI2sRender1,
+  HdaI2sRender2,
+  HdaI2sCapture,
+  HdaEndpointMax
+} NHLT_ENDPOINT;
+
+typedef struct {
+  NHLT_ENDPOINT EndpointType;
+  UINT32        EndpointFormatsBitmask;
+  UINT32        EndpointDevicesBitmask;
+  BOOLEAN       Enable;
+} PCH_HDA_NHLT_ENDPOINTS;
+
+#define PCH_HDA_NHLT_TABLE_SIZE 0x2000
+
+// Format bitmask
+#define B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT                BIT0
+#define B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT                BIT1
+#define B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT                BIT2
+#define B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT                BIT3
+#define B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT                BIT4
+#define B_HDA_BT_NARROWBAND_FORMAT                       BIT5
+#define B_HDA_BT_WIDEBAND_FORMAT                         BIT6
+#define B_HDA_BT_A2DP_FORMAT                             BIT7
+#define B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT   BIT8
+#define B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT  BIT9
+#define V_HDA_FORMAT_MAX                                 10
+
+// Formats
+extern CONST WAVEFORMATEXTENSIBLE Ch1_48kHz16bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz16bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz24bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz32bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch4_48kHz16bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE Ch4_48kHz32bitFormat;
+extern CONST WAVEFORMATEXTENSIBLE NarrowbandFormat;
+extern CONST WAVEFORMATEXTENSIBLE WidebandFormat;
+extern CONST WAVEFORMATEXTENSIBLE A2dpFormat;
+
+// Format Config
+extern CONST UINT32 DmicStereo16BitFormatConfig[];
+extern CONST UINT32 DmicStereo16BitFormatConfigSize;
+extern CONST UINT32 DmicStereo32BitFormatConfig[];
+extern CONST UINT32 DmicStereo32BitFormatConfigSize;
+extern CONST UINT32 DmicQuad16BitFormatConfig[];
+extern CONST UINT32 DmicQuad16BitFormatConfigSize;
+extern CONST UINT32 DmicQuad32BitFormatConfig[];
+extern CONST UINT32 DmicQuad32BitFormatConfigSize;
+extern CONST UINT32 DmicMono16BitFormatConfig[];
+extern CONST UINT32 DmicMono16BitFormatConfigSize;
+
+extern CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfig[];
+extern CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfigSize;
+extern CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfig[];
+extern CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
+extern CONST UINT32 BtFormatConfig[];
+extern CONST UINT32 BtFormatConfigSize;
+
+// Endpoints
+extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX1;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX2;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX4;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointBtRender;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointBtCapture;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointI2sRender;
+extern ENDPOINT_DESCRIPTOR  HdaEndpointI2sCapture;
+
+// Endpoint Config
+extern CONST UINT8  DmicX1Config[];
+extern CONST UINT32 DmicX1ConfigSize;
+extern CONST UINT8  DmicX2Config[];
+extern CONST UINT32 DmicX2ConfigSize;
+extern CONST UINT8  DmicX4Config[];
+extern CONST UINT32 DmicX4ConfigSize;
+extern CONST UINT8  BtConfig[];
+extern CONST UINT32 BtConfigSize;
+extern CONST UINT8  I2sRender1Config[];
+extern CONST UINT32 I2sRender1ConfigSize;
+extern CONST UINT8  I2sRender2Config[];
+extern CONST UINT32 I2sRender2ConfigSize;
+extern CONST UINT8  I2sCaptureConfig[];
+extern CONST UINT32 I2sCaptureConfigSize;
+
+// Device Info bitmask
+#define B_HDA_I2S_RENDER_DEVICE_INFO  BIT0
+#define B_HDA_I2S_CAPTURE_DEVICE_INFO BIT1
+
+// Device Info
+extern CONST DEVICE_INFO I2sRenderDeviceInfo;
+extern CONST DEVICE_INFO I2sCaptureDeviceInfo;
+
+// Oed Configuration
+extern CONST UINT32 NhltConfiguration[];
+extern CONST UINT32 NhltConfigurationSize;
+
+#endif // _PCH_HDA_ENDPOINTS_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
new file mode 100644
index 0000000000..860ed89f0d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
@@ -0,0 +1,92 @@
+/** @file
+  Header file with all common HSIO information
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HSIO_H_
+#define _PCH_HSIO_H_
+
+#define PCH_LANE_OWN_COMMON                      0x10
+#define PCH_LANE_BDCAST                          0x11
+#define PCH_HSIO_LANE_GROUP_NO                   0x09
+#define PCH_HSIO_LANE_GROUP_COMMON_LANE          0x00
+#define PCH_HSIO_LANE_GROUP_PCIE                 0x01
+#define PCH_HSIO_LANE_GROUP_DMI                  0x02
+#define PCH_HSIO_LANE_GROUP_GBE                  0x03
+#define PCH_HSIO_LANE_GROUP_USB3                 0x04
+#define PCH_HSIO_LANE_GROUP_SATA                 0x05
+#define PCH_HSIO_LANE_GROUP_SSIC                 0x06
+
+
+/**
+  PCH HSIO ChipsetInit Version Information
+**/
+typedef struct {
+  UINT16 BaseCrc;
+  UINT16 SusCrc;
+  UINT16 OemCrc;
+  UINT8  Version;
+  UINT8  Product;
+  UINT8  MetalLayer : 4;
+  UINT8  BaseLayer : 4;
+  UINT8  OemVersion;
+  UINT16 DebugMode : 1;
+  UINT16 OemCrcValid : 1;
+  UINT16 SusCrcValid : 1;
+  UINT16 BaseCrcValid : 1;
+  UINT16 Reserved : 12;
+} PCH_HSIO_VER_INFO;
+
+#define PMC_DATA_CMD_SIZE   ((12/sizeof(UINT16))-1)
+#define PMC_DATA_DELAY_CMD_SIZE ((4/sizeof(UINT16))-1)
+
+#define RECORD_OFFSET(X, Y)  ((X << 4) | Y)
+/**
+  PCH HSIO ChipsetInit Command Field
+**/
+typedef struct {
+  UINT8 Command : 3;
+  UINT8 Size : 5;
+  UINT8 Pid;
+  UINT8 OpCode; //PrivateControlWrite
+  UINT8 Bar; //0
+  UINT8 Fbe; //First Byte Enable  : 0x0F
+  UINT8 Fid; //0
+  UINT16 Offset;
+  UINT32 Value;
+} PCH_HSIO_CMD_FIELD;
+
+/**
+PCH HSIO Delay XRAM Data
+**/
+typedef struct {
+  UINT8 Command : 3;
+  UINT8 Size : 5;
+  UINT8 DelayPeriod; //(00h = 1us, 01h = 10us, 02h = 100us, ..., 07h = 10s; others reserved)
+  UINT8 DelayCount; //(0 - 255); total delay = Delay period * Delay count
+  UINT8 Padding;
+} PCH_HSIO_DELAY_CMD_FIELD;
+
+typedef enum {
+  Delay1us = 0x0,
+  Delay10us,
+  Delay100us,
+  Delay1ms,
+  Delay10ms,
+  Delay100ms,
+  Delay1s,
+  Delay10s
+} PCH_HSIO_DELAY;
+
+/**
+PCH PCIE PLL SSC Data
+**/
+#define MAX_PCIE_PLL_SSC_PERCENT  20
+
+#include <Private/CnlPchLpHsioDx.h>
+
+#endif //_PCH_HSIO_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
new file mode 100644
index 0000000000..4617a01c0b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
@@ -0,0 +1,269 @@
+/** @file
+  Copyright (c) 2019 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[24];                           ///< 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
+  UINT64   NHLA;                                    ///< Offset 102     HD-Audio NHLT ACPI address
+  UINT32   NHLL;                                    ///< Offset 110     HD-Audio NHLT ACPI length
+  UINT32   ADFM;                                    ///< Offset 114     HD-Audio DSP Feature Mask
+  UINT8    SWQ0;                                    ///< Offset 118     HD-Audio SoundWire Link #1 quirk mask
+  UINT8    SWQ1;                                    ///< Offset 119     HD-Audio SoundWire Link #2 quirk mask
+  UINT8    SWQ2;                                    ///< Offset 120     HD-Audio SoundWire Link #3 quirk mask
+  UINT8    SWQ3;                                    ///< Offset 121     HD-Audio SoundWire Link #4 quirk mask
+  UINT32   DSPM;                                    ///< Offset 122     HD-Audio DSP Stolen Memory Base Address
+  UINT32   SBRG;                                    ///< Offset 126     SBREG_BAR
+  UINT8    GEI0;                                    ///< Offset 130     GPIO GroupIndex mapped to GPE_DW0
+  UINT8    GEI1;                                    ///< Offset 131     GPIO GroupIndex mapped to GPE_DW1
+  UINT8    GEI2;                                    ///< Offset 132     GPIO GroupIndex mapped to GPE_DW2
+  UINT8    GED0;                                    ///< Offset 133     GPIO DW part of group mapped to GPE_DW0
+  UINT8    GED1;                                    ///< Offset 134     GPIO DW part of group mapped to GPE_DW1
+  UINT8    GED2;                                    ///< Offset 135     GPIO DW part of group mapped to GPE_DW2
+  UINT16   PcieLtrMaxSnoopLatency[24];              ///< Offset 136     PCIE LTR max snoop Latency 1
+                                                    ///< Offset 138     PCIE LTR max snoop Latency 2
+                                                    ///< Offset 140     PCIE LTR max snoop Latency 3
+                                                    ///< Offset 142     PCIE LTR max snoop Latency 4
+                                                    ///< Offset 144     PCIE LTR max snoop Latency 5
+                                                    ///< Offset 146     PCIE LTR max snoop Latency 6
+                                                    ///< Offset 148     PCIE LTR max snoop Latency 7
+                                                    ///< Offset 150     PCIE LTR max snoop Latency 8
+                                                    ///< Offset 152     PCIE LTR max snoop Latency 9
+                                                    ///< Offset 154     PCIE LTR max snoop Latency 10
+                                                    ///< Offset 156     PCIE LTR max snoop Latency 11
+                                                    ///< Offset 158     PCIE LTR max snoop Latency 12
+                                                    ///< Offset 160     PCIE LTR max snoop Latency 13
+                                                    ///< Offset 162     PCIE LTR max snoop Latency 14
+                                                    ///< Offset 164     PCIE LTR max snoop Latency 15
+                                                    ///< Offset 166     PCIE LTR max snoop Latency 16
+                                                    ///< Offset 168     PCIE LTR max snoop Latency 17
+                                                    ///< Offset 170     PCIE LTR max snoop Latency 18
+                                                    ///< Offset 172     PCIE LTR max snoop Latency 19
+                                                    ///< Offset 174     PCIE LTR max snoop Latency 20
+                                                    ///< Offset 176     PCIE LTR max snoop Latency 21
+                                                    ///< Offset 178     PCIE LTR max snoop Latency 22
+                                                    ///< Offset 180     PCIE LTR max snoop Latency 23
+                                                    ///< Offset 182     PCIE LTR max snoop Latency 24
+  UINT16   PcieLtrMaxNoSnoopLatency[24];            ///< Offset 184     PCIE LTR max no snoop Latency 1
+                                                    ///< Offset 186     PCIE LTR max no snoop Latency 2
+                                                    ///< Offset 188     PCIE LTR max no snoop Latency 3
+                                                    ///< Offset 190     PCIE LTR max no snoop Latency 4
+                                                    ///< Offset 192     PCIE LTR max no snoop Latency 5
+                                                    ///< Offset 194     PCIE LTR max no snoop Latency 6
+                                                    ///< Offset 196     PCIE LTR max no snoop Latency 7
+                                                    ///< Offset 198     PCIE LTR max no snoop Latency 8
+                                                    ///< Offset 200     PCIE LTR max no snoop Latency 9
+                                                    ///< Offset 202     PCIE LTR max no snoop Latency 10
+                                                    ///< Offset 204     PCIE LTR max no snoop Latency 11
+                                                    ///< Offset 206     PCIE LTR max no snoop Latency 12
+                                                    ///< Offset 208     PCIE LTR max no snoop Latency 13
+                                                    ///< Offset 210     PCIE LTR max no snoop Latency 14
+                                                    ///< Offset 212     PCIE LTR max no snoop Latency 15
+                                                    ///< Offset 214     PCIE LTR max no snoop Latency 16
+                                                    ///< Offset 216     PCIE LTR max no snoop Latency 17
+                                                    ///< Offset 218     PCIE LTR max no snoop Latency 18
+                                                    ///< Offset 220     PCIE LTR max no snoop Latency 19
+                                                    ///< Offset 222     PCIE LTR max no snoop Latency 20
+                                                    ///< Offset 224     PCIE LTR max no snoop Latency 21
+                                                    ///< Offset 226     PCIE LTR max no snoop Latency 22
+                                                    ///< Offset 228     PCIE LTR max no snoop Latency 23
+                                                    ///< Offset 230     PCIE LTR max no snoop Latency 24
+  UINT8    XHPC;                                    ///< Offset 232     Number of HighSpeed ports implemented in XHCI controller
+  UINT8    XRPC;                                    ///< Offset 233     Number of USBR ports implemented in XHCI controller
+  UINT8    XSPC;                                    ///< Offset 234     Number of SuperSpeed ports implemented in XHCI controller
+  UINT8    XSPA;                                    ///< Offset 235     Address of 1st SuperSpeed port
+  UINT32   HPTB;                                    ///< Offset 236     HPET base address
+  UINT8    HPTE;                                    ///< Offset 240     HPET enable
+  //SerialIo block
+  UINT8    SMD[12];                                 ///< Offset 241     SerialIo controller 0 mode
+                                                    ///< Offset 242     SerialIo controller 1 mode
+                                                    ///< Offset 243     SerialIo controller 2 mode
+                                                    ///< Offset 244     SerialIo controller 3 mode
+                                                    ///< Offset 245     SerialIo controller 4 mode
+                                                    ///< Offset 246     SerialIo controller 5 mode
+                                                    ///< Offset 247     SerialIo controller 6 mode
+                                                    ///< Offset 248     SerialIo controller 7 mode
+                                                    ///< Offset 249     SerialIo controller 8 mode
+                                                    ///< Offset 250     SerialIo controller 9 mode
+                                                    ///< Offset 251     SerialIo controller A mode
+                                                    ///< Offset 252     SerialIo controller B mode
+  UINT8    SIR[12];                                 ///< Offset 253     SerialIo controller 0 irq number
+                                                    ///< Offset 254     SerialIo controller 1 irq number
+                                                    ///< Offset 255     SerialIo controller 2 irq number
+                                                    ///< Offset 256     SerialIo controller 3 irq number
+                                                    ///< Offset 257     SerialIo controller 4 irq number
+                                                    ///< Offset 258     SerialIo controller 5 irq number
+                                                    ///< Offset 259     SerialIo controller 6 irq number
+                                                    ///< Offset 260     SerialIo controller 7 irq number
+                                                    ///< Offset 261     SerialIo controller 8 irq number
+                                                    ///< Offset 262     SerialIo controller 9 irq number
+                                                    ///< Offset 263     SerialIo controller A irq number
+                                                    ///< Offset 264     SerialIo controller B irq number
+  UINT64   SB0[12];                                 ///< Offset 265     SerialIo controller 0 BAR0
+                                                    ///< Offset 273     SerialIo controller 1 BAR0
+                                                    ///< Offset 281     SerialIo controller 2 BAR0
+                                                    ///< Offset 289     SerialIo controller 3 BAR0
+                                                    ///< Offset 297     SerialIo controller 4 BAR0
+                                                    ///< Offset 305     SerialIo controller 5 BAR0
+                                                    ///< Offset 313     SerialIo controller 6 BAR0
+                                                    ///< Offset 321     SerialIo controller 7 BAR0
+                                                    ///< Offset 329     SerialIo controller 8 BAR0
+                                                    ///< Offset 337     SerialIo controller 9 BAR0
+                                                    ///< Offset 345     SerialIo controller A BAR0
+                                                    ///< Offset 353     SerialIo controller B BAR0
+  UINT64   SB1[12];                                 ///< Offset 361     SerialIo controller 0 BAR1
+                                                    ///< Offset 369     SerialIo controller 1 BAR1
+                                                    ///< Offset 377     SerialIo controller 2 BAR1
+                                                    ///< Offset 385     SerialIo controller 3 BAR1
+                                                    ///< Offset 393     SerialIo controller 4 BAR1
+                                                    ///< Offset 401     SerialIo controller 5 BAR1
+                                                    ///< Offset 409     SerialIo controller 6 BAR1
+                                                    ///< Offset 417     SerialIo controller 7 BAR1
+                                                    ///< Offset 425     SerialIo controller 8 BAR1
+                                                    ///< Offset 433     SerialIo controller 9 BAR1
+                                                    ///< Offset 441     SerialIo controller A BAR1
+                                                    ///< Offset 449     SerialIo controller B BAR1
+  //end of SerialIo block
+  UINT8    SGIR;                                    ///< Offset 457     GPIO IRQ
+  UINT8    GPHD;                                    ///< Offset 458     Hide GPIO ACPI device
+  UINT8    RstPcieStorageInterfaceType[3];          ///< Offset 459     RST PCIe Storage Cycle Router#1 Interface Type
+                                                    ///< Offset 460     RST PCIe Storage Cycle Router#2 Interface Type
+                                                    ///< Offset 461     RST PCIe Storage Cycle Router#3 Interface Type
+  UINT8    RstPcieStoragePmCapPtr[3];               ///< Offset 462     RST PCIe Storage Cycle Router#1 Power Management Capability Pointer
+                                                    ///< Offset 463     RST PCIe Storage Cycle Router#2 Power Management Capability Pointer
+                                                    ///< Offset 464     RST PCIe Storage Cycle Router#3 Power Management Capability Pointer
+  UINT8    RstPcieStoragePcieCapPtr[3];             ///< Offset 465     RST PCIe Storage Cycle Router#1 PCIe Capabilities Pointer
+                                                    ///< Offset 466     RST PCIe Storage Cycle Router#2 PCIe Capabilities Pointer
+                                                    ///< Offset 467     RST PCIe Storage Cycle Router#3 PCIe Capabilities Pointer
+  UINT16   RstPcieStorageL1ssCapPtr[3];             ///< Offset 468     RST PCIe Storage Cycle Router#1 L1SS Capability Pointer
+                                                    ///< Offset 470     RST PCIe Storage Cycle Router#2 L1SS Capability Pointer
+                                                    ///< Offset 472     RST PCIe Storage Cycle Router#3 L1SS Capability Pointer
+  UINT8    RstPcieStorageEpL1ssControl2[3];         ///< Offset 474     RST PCIe Storage Cycle Router#1 Endpoint L1SS Control Data2
+                                                    ///< Offset 475     RST PCIe Storage Cycle Router#2 Endpoint L1SS Control Data2
+                                                    ///< Offset 476     RST PCIe Storage Cycle Router#3 Endpoint L1SS Control Data2
+  UINT32   RstPcieStorageEpL1ssControl1[3];         ///< Offset 477     RST PCIe Storage Cycle Router#1 Endpoint L1SS Control Data1
+                                                    ///< Offset 481     RST PCIe Storage Cycle Router#2 Endpoint L1SS Control Data1
+                                                    ///< Offset 485     RST PCIe Storage Cycle Router#3 Endpoint L1SS Control Data1
+  UINT16   RstPcieStorageLtrCapPtr[3];              ///< Offset 489     RST PCIe Storage Cycle Router#1 LTR Capability Pointer
+                                                    ///< Offset 491     RST PCIe Storage Cycle Router#2 LTR Capability Pointer
+                                                    ///< Offset 493     RST PCIe Storage Cycle Router#3 LTR Capability Pointer
+  UINT32   RstPcieStorageEpLtrData[3];              ///< Offset 495     RST PCIe Storage Cycle Router#1 Endpoint LTR Data
+                                                    ///< Offset 499     RST PCIe Storage Cycle Router#2 Endpoint LTR Data
+                                                    ///< Offset 503     RST PCIe Storage Cycle Router#3 Endpoint LTR Data
+  UINT16   RstPcieStorageEpLctlData16[3];           ///< Offset 507     RST PCIe Storage Cycle Router#1 Endpoint LCTL Data
+                                                    ///< Offset 509     RST PCIe Storage Cycle Router#2 Endpoint LCTL Data
+                                                    ///< Offset 511     RST PCIe Storage Cycle Router#3 Endpoint LCTL Data
+  UINT16   RstPcieStorageEpDctlData16[3];           ///< Offset 513     RST PCIe Storage Cycle Router#1 Endpoint DCTL Data
+                                                    ///< Offset 515     RST PCIe Storage Cycle Router#2 Endpoint DCTL Data
+                                                    ///< Offset 517     RST PCIe Storage Cycle Router#3 Endpoint DCTL Data
+  UINT16   RstPcieStorageEpDctl2Data16[3];          ///< Offset 519     RST PCIe Storage Cycle Router#1 Endpoint DCTL2 Data
+                                                    ///< Offset 521     RST PCIe Storage Cycle Router#2 Endpoint DCTL2 Data
+                                                    ///< Offset 523     RST PCIe Storage Cycle Router#3 Endpoint DCTL2 Data
+  UINT16   RstPcieStorageRpDctl2Data16[3];          ///< Offset 525     RST PCIe Storage Cycle Router#1 RootPort DCTL2 Data
+                                                    ///< Offset 527     RST PCIe Storage Cycle Router#2 RootPort DCTL2 Data
+                                                    ///< Offset 529     RST PCIe Storage Cycle Router#3 RootPort DCTL2 Data
+  UINT32   RstPcieStorageUniqueTableBar[3];         ///< Offset 531     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR
+                                                    ///< Offset 535     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X Table BAR
+                                                    ///< Offset 539     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X Table BAR
+  UINT32   RstPcieStorageUniqueTableBarValue[3];    ///< Offset 543     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR value
+                                                    ///< Offset 547     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X Table BAR value
+                                                    ///< Offset 551     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X Table BAR value
+  UINT32   RstPcieStorageUniquePbaBar[3];           ///< Offset 555     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR
+                                                    ///< Offset 559     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X PBA BAR
+                                                    ///< Offset 563     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X PBA BAR
+  UINT32   RstPcieStorageUniquePbaBarValue[3];      ///< Offset 567     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR value
+                                                    ///< Offset 571     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X PBA BAR value
+                                                    ///< Offset 575     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X PBA BAR value
+  UINT32   RstPcieStorageRootPortNum[3];            ///< Offset 579     RST PCIe Storage Cycle Router#1 Root Port number
+                                                    ///< Offset 583     RST PCIe Storage Cycle Router#2 Root Port number
+                                                    ///< Offset 587     RST PCIe Storage Cycle Router#3 Root Port number
+  UINT8    EMH4;                                    ///< Offset 591     eMMC HS400 mode enabled
+  UINT8    EMDS;                                    ///< Offset 592     eMMC Driver Strength
+  UINT8    CpuSku;                                  ///< Offset 593     CPU SKU
+  UINT16   IoTrapAddress[4];                        ///< Offset 594
+  UINT8    IoTrapStatus[4];                         ///< Offset 602
+  UINT16   PMBS;                                    ///< Offset 606     ACPI IO BASE address
+  UINT32   PWRM;                                    ///< Offset 608     PWRM MEM BASE address
+  // Cnvi specific
+  UINT8    CnviMode;                                ///< Offset 612     CNVi mode
+  UINT32   RmrrCsmeBaseAddress;                     ///< Offset 613     RMRR CSME Base Address
+  //Voltage Margining
+  UINT8    SlpS0VmRuntimeControl;                   ///< Offset 617     SLP_S0 Voltage Margining Runtime Control
+  UINT8    SlpS0Vm070VSupport;                      ///< Offset 618     SLP_S0 0.70V Voltage Margining Support
+  UINT8    SlpS0Vm075VSupport;                      ///< Offset 619     SLP_S0 0.75V Voltage Margining Support
+  // PCH Trace Hub
+  UINT8    PchTraceHubMode;                         ///< Offset 620     PCH Trace Hub Mode
+  // PCH PS_ON support
+  UINT8    PsOnEnable;                              ///< Offset 621     PCH PS_ON enable
+  UINT32   TempRsvdMemBase;                         ///< Offset 622     Reserved memory base address for Temp MBAR
+  //
+  // These are for PchApciTablesSelfTest use
+  //
+  UINT8    LtrEnable[24];                           ///< Offset 626     Latency Tolerance Reporting Enable
+                                                    ///< Offset 627     Latency Tolerance Reporting Enable
+                                                    ///< Offset 628     Latency Tolerance Reporting Enable
+                                                    ///< Offset 629     Latency Tolerance Reporting Enable
+                                                    ///< Offset 630     Latency Tolerance Reporting Enable
+                                                    ///< Offset 631     Latency Tolerance Reporting Enable
+                                                    ///< Offset 632     Latency Tolerance Reporting Enable
+                                                    ///< Offset 633     Latency Tolerance Reporting Enable
+                                                    ///< Offset 634     Latency Tolerance Reporting Enable
+                                                    ///< Offset 635     Latency Tolerance Reporting Enable
+                                                    ///< Offset 636     Latency Tolerance Reporting Enable
+                                                    ///< Offset 637     Latency Tolerance Reporting Enable
+                                                    ///< Offset 638     Latency Tolerance Reporting Enable
+                                                    ///< Offset 639     Latency Tolerance Reporting Enable
+                                                    ///< Offset 640     Latency Tolerance Reporting Enable
+                                                    ///< Offset 641     Latency Tolerance Reporting Enable
+                                                    ///< Offset 642     Latency Tolerance Reporting Enable
+                                                    ///< Offset 643     Latency Tolerance Reporting Enable
+                                                    ///< Offset 644     Latency Tolerance Reporting Enable
+                                                    ///< Offset 645     Latency Tolerance Reporting Enable
+                                                    ///< Offset 646     Latency Tolerance Reporting Enable
+                                                    ///< Offset 647     Latency Tolerance Reporting Enable
+                                                    ///< Offset 648     Latency Tolerance Reporting Enable
+                                                    ///< Offset 649     Latency Tolerance Reporting Enable
+  UINT8    GBES;                                    ///< Offset 650     GbE Support
+  UINT8    SataPortPresence;                        ///< Offset 651     Holds information from SATA PCS register about SATA ports which recieved COMINIT from connected devices.
+  UINT8    SdPowerEnableActiveHigh;                 ///< Offset 652     SD PWREN# active high indication
+  UINT8    EmmcEnabled;                             ///< Offset 653     Set to indicate that eMMC is enabled
+  UINT8    SdCardEnabled;                           ///< Offset 654     Set to indicate that SD card is enabled
+} PCH_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
new file mode 100644
index 0000000000..94a5e0fad2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
@@ -0,0 +1,58 @@
+/** @file
+  Definitions required to create RstHob
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h
new file mode 100644
index 0000000000..7a92a509b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h
@@ -0,0 +1,25 @@
+/** @file
+  This file contains definitions of Si Schedule Reset HOB.
+
+  Copyright (c) 2019 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_
+
+#include <PchResetPlatformSpecific.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.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
@ 2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:10   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:51 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol include headers

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

Adds the following header files:
 * Pch/Include/Private/Protocol

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h | 31 ++++++++++++++++  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h | 37 ++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h
new file mode 100644
index 0000000000..75003c82ad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/Pc
+++ hNvsArea.h
@@ -0,0 +1,31 @@
+/** @file
+  This file defines the PCH NVS Area Protocol.
+
+  Copyright (c) 2019 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 <Private/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/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h
new file mode 100644
index 0000000000..2cd6b85d29
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/Pc
+++ ieIoTrap.h
@@ -0,0 +1,37 @@
+/** @file
+  This file defines the PCH PCIE IoTrap Protocol.
+
+  Copyright (c) 2019 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 {
+  PciePmTrap,
+  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
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers

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

Adds header files common to silicon Sample Code.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h                     |   82 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h  |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h      | 1513 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h |  118 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h            |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h         |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h    |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h        |   80 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h                 |  137 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h                |   87 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h          |   33 +
 11 files changed, 2213 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h
new file mode 100644
index 0000000000..829d1190fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h
@@ -0,0 +1,82 @@
+/** @file
+  Prototype of SEC Platform hook library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef  _SEC_PLATFORM_LIB_H_
+#define  _SEC_PLATFORM_LIB_H_
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+
+/**
+  A developer supplied function to perform platform specific operations.
+
+  It's a developer supplied function to perform any operations appropriate to a
+  given platform. It's invoked just before passing control to PEI core by SEC
+  core. Platform developer may modify the SecCoreData passed to PEI Core.
+  It returns a platform specific PPI list that platform wishes to pass to PEI core.
+  The Generic SEC core module will merge this list to join the final list passed to
+  PEI core.
+
+  @param  SecCoreData           The same parameter as passing to PEI core. It
+                                could be overridden by this function.
+
+  @return The platform specific PPI list to be passed to PEI core or
+          NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
+  );
+
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param  PeiServices               Pointer to the PEI Services Table.
+  @param  StructureSize             Pointer to the variable describing size of the input buffer.
+  @param  PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  );
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval     EFI_SUCCESS  The data was successfully returned.
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  );
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h
new file mode 100644
index 0000000000..862a7c8aea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h
@@ -0,0 +1,51 @@
+/** @file
+  Definition of GUIDed HOB for reserving SMRAM regions.
+
+  This file defines:
+  * the GUID used to identify the GUID HOB for reserving SMRAM regions.
+  * the data structure of SMRAM descriptor to describe SMRAM candidate regions
+  * values of state of SMRAM candidate regions
+  * the GUID specific data structure of HOB for reserving SMRAM regions.
+  This GUIDed HOB can be used to convey the existence of the T-SEG reservation and H-SEG usage
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_
+#define _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_
+
+#define EFI_SMM_PEI_SMRAM_MEMORY_RESERVE \
+  { \
+    0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d } \
+  }
+
+/**
+* GUID specific data structure of HOB for reserving SMRAM regions.
+*
+* Inconsistent with specification here:
+* EFI_HOB_SMRAM_DESCRIPTOR_BLOCK has been changed to EFI_SMRAM_HOB_DESCRIPTOR_BLOCK.
+* This inconsistency is kept in code in order for backward compatibility.
+**/
+typedef struct {
+  ///
+  /// Designates the number of possible regions in the system
+  /// that can be usable for SMRAM.
+  ///
+  /// Inconsistent with specification here:
+  /// In Framework SMM CIS 0.91 specification, it defines the field type as UINTN.
+  /// However, HOBs are supposed to be CPU neutral, so UINT32 should be used instead.
+  ///
+  UINT32                NumberOfSmmReservedRegions;
+  ///
+  /// Used throughout this protocol to describe the candidate
+  /// regions for SMRAM that are supported by this platform.
+  ///
+  EFI_SMRAM_DESCRIPTOR  Descriptor[1];
+} EFI_SMRAM_HOB_DESCRIPTOR_BLOCK;
+
+extern EFI_GUID gEfiSmmPeiSmramMemoryReserveGuid;
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h
new file mode 100644
index 0000000000..6ba23381b0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h
@@ -0,0 +1,1513 @@
+/** @file
+  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage
+  under EFI and Legacy OS boot.  This file also includes all the related
+  COMPATIBILIY16 structures and defintions.
+
+  Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow
+  well known naming conventions.
+
+  Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode
+  environment. Reverse thunk is the code that does the opposite.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _EFI_LEGACY_BIOS_H_
+#define _EFI_LEGACY_BIOS_H_
+
+///
+///
+///
+#pragma pack(1)
+
+typedef UINT8                       SERIAL_MODE;
+typedef UINT8                       PARALLEL_MODE;
+
+#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$')
+
+///
+/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx
+/// physical address range. It is located on a 16-byte boundary and provides the physical address of the
+/// entry point for the Compatibility16 functions. These functions provide the platform-specific
+/// information that is required by the generic EfiCompatibility code. The functions are invoked via
+/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical
+/// entry point.
+///
+typedef struct {
+  ///
+  /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte
+  /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32.
+  ///
+  UINT32                            Signature;
+
+  ///
+  /// The value required such that byte checksum of TableLength equals zero.
+  ///
+  UINT8                             TableChecksum;
+
+  ///
+  /// The length of this table.
+  ///
+  UINT8                             TableLength;
+
+  ///
+  /// The major EFI revision for which this table was generated.
+  ///
+  UINT8                             EfiMajorRevision;
+
+  ///
+  /// The minor EFI revision for which this table was generated.
+  ///
+  UINT8                             EfiMinorRevision;
+
+  ///
+  /// The major revision of this table.
+  ///
+  UINT8                             TableMajorRevision;
+
+  ///
+  /// The minor revision of this table.
+  ///
+  UINT8                             TableMinorRevision;
+
+  ///
+  /// Reserved for future usage.
+  ///
+  UINT16                            Reserved;
+
+  ///
+  /// The segment of the entry point within the traditional BIOS for Compatibility16 functions.
+  ///
+  UINT16                            Compatibility16CallSegment;
+
+  ///
+  /// The offset of the entry point within the traditional BIOS for Compatibility16 functions.
+  ///
+  UINT16                            Compatibility16CallOffset;
+
+  ///
+  /// The segment of the entry point within the traditional BIOS for EfiCompatibility
+  /// to invoke the PnP installation check.
+  ///
+  UINT16                            PnPInstallationCheckSegment;
+
+  ///
+  /// The Offset of the entry point within the traditional BIOS for EfiCompatibility
+  /// to invoke the PnP installation check.
+  ///
+  UINT16                            PnPInstallationCheckOffset;
+
+  ///
+  /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform
+  ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS).
+  ///
+  UINT32                            EfiSystemTable;
+
+  ///
+  /// The address of an OEM-provided identifier string. The string is null terminated.
+  ///
+  UINT32                            OemIdStringPointer;
+
+  ///
+  /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional
+  /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size
+  /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI
+  /// RSD PTR with either the ACPI 1.0b or 2.0 values.
+  ///
+  UINT32                            AcpiRsdPtrPointer;
+
+  ///
+  /// The OEM revision number. Usage is undefined but provided for OEM module usage.
+  ///
+  UINT16                            OemRevision;
+
+  ///
+  /// The 32-bit physical address where INT15 E820 data is stored within the traditional
+  /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the
+  /// data to the indicated area.
+  ///
+  UINT32                            E820Pointer;
+
+  ///
+  /// The length of the E820 data and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            E820Length;
+
+  ///
+  /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS.
+  /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and
+  /// copy the data to the indicated area.
+  ///
+  UINT32                            IrqRoutingTablePointer;
+
+  ///
+  /// The length of the $PIR table and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            IrqRoutingTableLength;
+
+  ///
+  /// The 32-bit physical address where the MP table is stored in the traditional BIOS.
+  /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data
+  /// to the indicated area.
+  ///
+  UINT32                            MpTablePtr;
+
+  ///
+  /// The length of the MP table and is filled in by the EfiCompatibility code.
+  ///
+  UINT32                            MpTableLength;
+
+  ///
+  /// The segment of the OEM-specific INT table/code.
+  ///
+  UINT16                            OemIntSegment;
+
+  ///
+  /// The offset of the OEM-specific INT table/code.
+  ///
+  UINT16                            OemIntOffset;
+
+  ///
+  /// The segment of the OEM-specific 32-bit table/code.
+  ///
+  UINT16                            Oem32Segment;
+
+  ///
+  /// The offset of the OEM-specific 32-bit table/code.
+  ///
+  UINT16                            Oem32Offset;
+
+  ///
+  /// The segment of the OEM-specific 16-bit table/code.
+  ///
+  UINT16                            Oem16Segment;
+
+  ///
+  /// The offset of the OEM-specific 16-bit table/code.
+  ///
+  UINT16                            Oem16Offset;
+
+  ///
+  /// The segment of the TPM binary passed to 16-bit CSM.
+  ///
+  UINT16                            TpmSegment;
+
+  ///
+  /// The offset of the TPM binary passed to 16-bit CSM.
+  ///
+  UINT16                            TpmOffset;
+
+  ///
+  /// A pointer to a string identifying the independent BIOS vendor.
+  ///
+  UINT32                            IbvPointer;
+
+  ///
+  /// This field is NULL for all systems not supporting PCI Express. This field is the base
+  /// value of the start of the PCI Express memory-mapped configuration registers and
+  /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function
+  /// Compatibility16InitializeYourself().
+  /// Compatibility16InitializeYourself() is defined in Compatability16
+  /// Functions.
+  ///
+  UINT32                            PciExpressBase;
+
+  ///
+  /// Maximum PCI bus number assigned.
+  ///
+  UINT8                             LastPciBus;
+
+  ///
+  /// Start Address of Upper Memory Area (UMA) to be set as Read/Write. If
+  /// UmaAddress is a valid address in the shadow RAM, it also indicates that the region
+  /// from 0xC0000 to (UmaAddress - 1) can be used for Option ROM.
+  ///
+  UINT32                            UmaAddress;
+
+  ///
+  /// Upper Memory Area size in bytes to be set as Read/Write. If zero, no UMA region
+  /// will be set as Read/Write (i.e. all Shadow RAM is set as Read-Only).
+  ///
+  UINT32                            UmaSize;
+
+  ///
+  /// Start Address of high memory that can be used for permanent allocation. If zero,
+  /// high memory is not available for permanent allocation.
+  ///
+  UINT32                            HiPermanentMemoryAddress;
+
+  ///
+  /// Size of high memory that can be used for permanent allocation in bytes. If zero,
+  /// high memory is not available for permanent allocation.
+  ///
+  UINT32                            HiPermanentMemorySize;
+} EFI_COMPATIBILITY16_TABLE;
+
+///
+/// Functions provided by the CSM binary which communicate between the EfiCompatibility
+/// and Compatability16 code.
+///
+/// Inconsistent with the specification here:
+/// The member's name started with "Compatibility16" [defined in Intel Framework
+/// Compatibility Support Module Specification / 0.97 version]
+/// has been changed to "Legacy16" since keeping backward compatible.
+///
+typedef enum {
+  ///
+  /// Causes the Compatibility16 code to do any internal initialization required.
+  /// Input:
+  ///   AX = Compatibility16InitializeYourself
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE
+  /// Return:
+  ///   AX = Return Status codes
+  ///
+  Legacy16InitializeYourself    = 0x0000,
+
+  ///
+  /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence.
+  /// Input:
+  ///   AX = Compatibility16UpdateBbs
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
+  /// Return:
+  ///   AX = Returned status codes
+  ///
+  Legacy16UpdateBbs             = 0x0001,
+
+  ///
+  /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16
+  /// code is read/write.
+  /// Input:
+  ///   AX = Compatibility16PrepareToBoot
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure
+  /// Return:
+  ///   AX = Returned status codes
+  ///
+  Legacy16PrepareToBoot         = 0x0002,
+
+  ///
+  /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only.
+  /// Input:
+  ///   AX = Compatibility16Boot
+  /// Output:
+  ///   AX = Returned status codes
+  ///
+  Legacy16Boot                  = 0x0003,
+
+  ///
+  /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is
+  /// stored in CMOS and is the priority number of the last attempted boot device.
+  /// Input:
+  ///   AX = Compatibility16RetrieveLastBootDevice
+  /// Output:
+  ///   AX = Returned status codes
+  ///   BX = Priority number of the boot device.
+  ///
+  Legacy16RetrieveLastBootDevice = 0x0004,
+
+  ///
+  /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM.
+  /// Input:
+  ///   AX = Compatibility16DispatchOprom
+  ///   ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE
+  /// Output:
+  ///   AX = Returned status codes
+  ///   BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant.
+  ///
+  Legacy16DispatchOprom         = 0x0005,
+
+  ///
+  /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address
+  /// of that region.
+  /// Input:
+  ///   AX = Compatibility16GetTableAddress
+  ///   BX = Allocation region
+  ///       00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.
+  ///       Bit 0 = 1 Allocate from 0xF0000 64 KB block
+  ///       Bit 1 = 1 Allocate from 0xE0000 64 KB block
+  ///   CX = Requested length in bytes.
+  ///   DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment.
+  /// Output:
+  ///   AX = Returned status codes
+  ///   DS:BX = Address of the region
+  ///
+  Legacy16GetTableAddress       = 0x0006,
+
+  ///
+  /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state.
+  /// Input:
+  ///   AX = Compatibility16SetKeyboardLeds
+  ///   CL = LED status.
+  ///     Bit 0  Scroll Lock 0 = Off
+  ///     Bit 1  NumLock
+  ///     Bit 2  Caps Lock
+  /// Output:
+  ///     AX = Returned status codes
+  ///
+  Legacy16SetKeyboardLeds       = 0x0007,
+
+  ///
+  /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that
+  /// do not have an OpROM associated with them. An example is SATA.
+  /// Input:
+  ///   AX = Compatibility16InstallPciHandler
+  ///   ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure
+  /// Output:
+  ///   AX = Returned status codes
+  ///
+  Legacy16InstallPciHandler     = 0x0008
+} EFI_COMPATIBILITY_FUNCTIONS;
+
+
+///
+/// EFI_DISPATCH_OPROM_TABLE
+///
+typedef struct {
+  UINT16  PnPInstallationCheckSegment;  ///< A pointer to the PnpInstallationCheck data structure.
+  UINT16  PnPInstallationCheckOffset;   ///< A pointer to the PnpInstallationCheck data structure.
+  UINT16  OpromSegment;                 ///< The segment where the OpROM was placed. Offset is assumed to be 3.
+  UINT8   PciBus;                       ///< The PCI bus.
+  UINT8   PciDeviceFunction;            ///< The PCI device * 0x08 | PCI function.
+  UINT8   NumberBbsEntries;             ///< The number of valid BBS table entries upon entry and exit. The IBV code may
+                                        ///< increase this number, if BBS-compliant devices also hook INTs in order to force the
+                                        ///< OpROM BIOS Setup to be executed.
+  UINT32  BbsTablePointer;              ///< A pointer to the BBS table.
+  UINT16  RuntimeSegment;               ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this
+                                        ///< means that the relocation of this run time code is not supported.
+                                        ///< Inconsistent with specification here:
+                                        ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version]
+                                        ///< has been changed to "RuntimeSegment" since keeping backward compatible.
+
+} EFI_DISPATCH_OPROM_TABLE;
+
+///
+/// EFI_TO_COMPATIBILITY16_INIT_TABLE
+///
+typedef struct {
+  ///
+  /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF.
+  ///
+  UINT32                            BiosLessThan1MB;
+
+  ///
+  /// The starting address of the high memory block.
+  ///
+  UINT32                            HiPmmMemory;
+
+  ///
+  /// The length of high memory block.
+  ///
+  UINT32                            HiPmmMemorySizeInBytes;
+
+  ///
+  /// The segment of the reverse thunk call code.
+  ///
+  UINT16                            ReverseThunkCallSegment;
+
+  ///
+  /// The offset of the reverse thunk call code.
+  ///
+  UINT16                            ReverseThunkCallOffset;
+
+  ///
+  /// The number of E820 entries copied to the Compatibility16 BIOS.
+  ///
+  UINT32                            NumberE820Entries;
+
+  ///
+  /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory.
+  ///
+  UINT32                            OsMemoryAbove1Mb;
+
+  ///
+  /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM.
+  ///
+  UINT32                            ThunkStart;
+
+  ///
+  /// The size of the thunk code.
+  ///
+  UINT32                            ThunkSizeInBytes;
+
+  ///
+  /// Starting address of memory under 1 MB.
+  ///
+  UINT32                            LowPmmMemory;
+
+  ///
+  /// The length of low Memory block.
+  ///
+  UINT32                            LowPmmMemorySizeInBytes;
+} EFI_TO_COMPATIBILITY16_INIT_TABLE;
+
+///
+/// DEVICE_PRODUCER_SERIAL.
+///
+typedef struct {
+  UINT16                            Address;    ///< I/O address assigned to the serial port.
+  UINT8                             Irq;        ///< IRQ assigned to the serial port.
+  SERIAL_MODE                       Mode;       ///< Mode of serial port. Values are defined below.
+} DEVICE_PRODUCER_SERIAL;
+
+///
+/// DEVICE_PRODUCER_SERIAL's modes.
+///@{
+#define DEVICE_SERIAL_MODE_NORMAL               0x00
+#define DEVICE_SERIAL_MODE_IRDA                 0x01
+#define DEVICE_SERIAL_MODE_ASK_IR               0x02
+#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00
+#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10
+///@)
+
+///
+/// DEVICE_PRODUCER_PARALLEL.
+///
+typedef struct {
+  UINT16                            Address;  ///< I/O address assigned to the parallel port.
+  UINT8                             Irq;      ///< IRQ assigned to the parallel port.
+  UINT8                             Dma;      ///< DMA assigned to the parallel port.
+  PARALLEL_MODE                     Mode;     ///< Mode of the parallel port. Values are defined below.
+} DEVICE_PRODUCER_PARALLEL;
+
+///
+/// DEVICE_PRODUCER_PARALLEL's modes.
+///@{
+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00
+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01
+#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02
+#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03
+///@}
+
+///
+/// DEVICE_PRODUCER_FLOPPY
+///
+typedef struct {
+  UINT16                            Address;          ///< I/O address assigned to the floppy.
+  UINT8                             Irq;              ///< IRQ assigned to the floppy.
+  UINT8                             Dma;              ///< DMA assigned to the floppy.
+  UINT8                             NumberOfFloppy;   ///< Number of floppies in the system.
+} DEVICE_PRODUCER_FLOPPY;
+
+///
+/// LEGACY_DEVICE_FLAGS
+///
+typedef struct {
+  UINT32                            A20Kybd : 1;      ///< A20 controller by keyboard controller.
+  UINT32                            A20Port90 : 1;    ///< A20 controlled by port 0x92.
+  UINT32                            Reserved : 30;    ///< Reserved for future usage.
+} LEGACY_DEVICE_FLAGS;
+
+///
+/// DEVICE_PRODUCER_DATA_HEADER
+///
+typedef struct {
+  DEVICE_PRODUCER_SERIAL            Serial[4];      ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below.
+  DEVICE_PRODUCER_PARALLEL          Parallel[3];    ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below.
+  DEVICE_PRODUCER_FLOPPY            Floppy;         ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below.
+  UINT8                             MousePresent;   ///< Flag to indicate if mouse is present.
+  LEGACY_DEVICE_FLAGS               Flags;          ///< Miscellaneous Boolean state information passed to CSM.
+} DEVICE_PRODUCER_DATA_HEADER;
+
+///
+/// ATAPI_IDENTIFY
+///
+typedef struct {
+  UINT16                            Raw[256];     ///< Raw data from the IDE IdentifyDrive command.
+} ATAPI_IDENTIFY;
+
+///
+/// HDD_INFO
+///
+typedef struct {
+  ///
+  /// Status of IDE device. Values are defined below. There is one HDD_INFO structure
+  /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index
+  /// 1 is slave.
+  ///
+  UINT16                            Status;
+
+  ///
+  /// PCI bus of IDE controller.
+  ///
+  UINT32                            Bus;
+
+  ///
+  /// PCI device of IDE controller.
+  ///
+  UINT32                            Device;
+
+  ///
+  /// PCI function of IDE controller.
+  ///
+  UINT32                            Function;
+
+  ///
+  /// Command ports base address.
+  ///
+  UINT16                            CommandBaseAddress;
+
+  ///
+  /// Control ports base address.
+  ///
+  UINT16                            ControlBaseAddress;
+
+  ///
+  /// Bus master address.
+  ///
+  UINT16                            BusMasterAddress;
+
+  UINT8                             HddIrq;
+
+  ///
+  /// Data that identifies the drive data; one per possible attached drive.
+  ///
+  ATAPI_IDENTIFY                    IdentifyDrive[2];
+} HDD_INFO;
+
+///
+/// HDD_INFO status bits
+///
+#define HDD_PRIMARY               0x01
+#define HDD_SECONDARY             0x02
+#define HDD_MASTER_ATAPI_CDROM    0x04
+#define HDD_SLAVE_ATAPI_CDROM     0x08
+#define HDD_MASTER_IDE            0x20
+#define HDD_SLAVE_IDE             0x40
+#define HDD_MASTER_ATAPI_ZIPDISK  0x10
+#define HDD_SLAVE_ATAPI_ZIPDISK   0x80
+
+///
+/// BBS_STATUS_FLAGS;\.
+///
+typedef struct {
+  UINT16                            OldPosition : 4;    ///< Prior priority.
+  UINT16                            Reserved1 : 4;      ///< Reserved for future use.
+  UINT16                            Enabled : 1;        ///< If 0, ignore this entry.
+  UINT16                            Failed : 1;         ///< 0 = Not known if boot failure occurred.
+                                                        ///< 1 = Boot attempted failed.
+
+  ///
+  /// State of media present.
+  ///   00 = No bootable media is present in the device.
+  ///   01 = Unknown if a bootable media present.
+  ///   10 = Media is present and appears bootable.
+  ///   11 = Reserved.
+  ///
+  UINT16                            MediaPresent : 2;
+  UINT16                            Reserved2 : 4;      ///< Reserved for future use.
+} BBS_STATUS_FLAGS;
+
+///
+/// BBS_TABLE, device type values & boot priority values.
+///
+typedef struct {
+  ///
+  /// The boot priority for this boot device. Values are defined below.
+  ///
+  UINT16                            BootPriority;
+
+  ///
+  /// The PCI bus for this boot device.
+  ///
+  UINT32                            Bus;
+
+  ///
+  /// The PCI device for this boot device.
+  ///
+  UINT32                            Device;
+
+  ///
+  /// The PCI function for the boot device.
+  ///
+  UINT32                            Function;
+
+  ///
+  /// The PCI class for this boot device.
+  ///
+  UINT8                             Class;
+
+  ///
+  /// The PCI Subclass for this boot device.
+  ///
+  UINT8                             SubClass;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
+  ///
+  UINT16                            MfgStringOffset;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.
+  ///
+  UINT16                            MfgStringSegment;
+
+  ///
+  /// BBS device type. BBS device types are defined below.
+  ///
+  UINT16                            DeviceType;
+
+  ///
+  /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below.
+  ///
+  BBS_STATUS_FLAGS                  StatusFlags;
+
+  ///
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
+  /// BCV devices.
+  ///
+  UINT16                            BootHandlerOffset;
+
+  ///
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for
+  /// BCV devices.
+  ///
+  UINT16                            BootHandlerSegment;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing this device.
+  ///
+  UINT16                            DescStringOffset;
+
+  ///
+  /// Segment:offset address of an ASCIIZ description string describing this device.
+  ///
+  UINT16                            DescStringSegment;
+
+  ///
+  /// Reserved.
+  ///
+  UINT32                            InitPerReserved;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq13Handler;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq18Handler;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq19Handler;
+
+  ///
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup
+  ///
+  UINT32                            AdditionalIrq40Handler;
+  UINT8                             AssignedDriveNumber;
+  UINT32                            AdditionalIrq41Handler;
+  UINT32                            AdditionalIrq46Handler;
+  UINT32                            IBV1;
+  UINT32                            IBV2;
+} BBS_TABLE;
+
+///
+/// BBS device type values
+///@{
+#define BBS_FLOPPY              0x01
+#define BBS_HARDDISK            0x02
+#define BBS_CDROM               0x03
+#define BBS_PCMCIA              0x04
+#define BBS_USB                 0x05
+#define BBS_EMBED_NETWORK       0x06
+#define BBS_BEV_DEVICE          0x80
+#define BBS_UNKNOWN             0xff
+///@}
+
+///
+/// BBS boot priority values
+///@{
+#define BBS_DO_NOT_BOOT_FROM    0xFFFC
+#define BBS_LOWEST_PRIORITY     0xFFFD
+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE
+#define BBS_IGNORE_ENTRY        0xFFFF
+///@}
+
+///
+/// SMM_ATTRIBUTES
+///
+typedef struct {
+  ///
+  /// Access mechanism used to generate the soft SMI. Defined types are below. The other
+  /// values are reserved for future usage.
+  ///
+  UINT16                            Type : 3;
+
+  ///
+  /// The size of "port" in bits. Defined values are below.
+  ///
+  UINT16                            PortGranularity : 3;
+
+  ///
+  /// The size of data in bits. Defined values are below.
+  ///
+  UINT16                            DataGranularity : 3;
+
+  ///
+  /// Reserved for future use.
+  ///
+  UINT16                            Reserved : 7;
+} SMM_ATTRIBUTES;
+
+///
+/// SMM_ATTRIBUTES type values.
+///@{
+#define STANDARD_IO       0x00
+#define STANDARD_MEMORY   0x01
+///@}
+
+///
+/// SMM_ATTRIBUTES port size constants.
+///@{
+#define PORT_SIZE_8       0x00
+#define PORT_SIZE_16      0x01
+#define PORT_SIZE_32      0x02
+#define PORT_SIZE_64      0x03
+///@}
+
+///
+/// SMM_ATTRIBUTES data size constants.
+///@{
+#define DATA_SIZE_8       0x00
+#define DATA_SIZE_16      0x01
+#define DATA_SIZE_32      0x02
+#define DATA_SIZE_64      0x03
+///@}
+
+///
+/// SMM_FUNCTION & relating constants.
+///
+typedef struct {
+  UINT16                            Function : 15;
+  UINT16                            Owner : 1;
+} SMM_FUNCTION;
+
+///
+/// SMM_FUNCTION Function constants.
+///@{
+#define INT15_D042        0x0000
+#define GET_USB_BOOT_INFO 0x0001
+#define DMI_PNP_50_57     0x0002
+///@}
+
+///
+/// SMM_FUNCTION Owner constants.
+///@{
+#define STANDARD_OWNER    0x0
+#define OEM_OWNER         0x1
+///@}
+
+///
+/// This structure assumes both port and data sizes are 1. SmmAttribute must be
+/// properly to reflect that assumption.
+///
+typedef struct {
+  ///
+  /// Describes the access mechanism, SmmPort, and SmmData sizes. Type
+  /// SMM_ATTRIBUTES is defined below.
+  ///
+  SMM_ATTRIBUTES                    SmmAttributes;
+
+  ///
+  /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below.
+  ///
+  SMM_FUNCTION                      SmmFunction;
+
+  ///
+  /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
+  ///
+  UINT8                             SmmPort;
+
+  ///
+  /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.
+  ///
+  UINT8                             SmmData;
+} SMM_ENTRY;
+
+///
+/// SMM_TABLE
+///
+typedef struct {
+  UINT16                            NumSmmEntries;    ///< Number of entries represented by SmmEntry.
+  SMM_ENTRY                         SmmEntry;         ///< One entry per function. Type SMM_ENTRY is defined below.
+} SMM_TABLE;
+
+///
+/// UDC_ATTRIBUTES
+///
+typedef struct {
+  ///
+  /// This bit set indicates that the ServiceAreaData is valid.
+  ///
+  UINT8                             DirectoryServiceValidity : 1;
+
+  ///
+  /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if
+  /// DirectoryServiceValidity is 0.
+  ///
+  UINT8                             RabcaUsedFlag : 1;
+
+  ///
+  /// This bit set indicates to execute hard disk diagnostics.
+  ///
+  UINT8                             ExecuteHddDiagnosticsFlag : 1;
+
+  ///
+  /// Reserved for future use. Set to 0.
+  ///
+  UINT8                             Reserved : 5;
+} UDC_ATTRIBUTES;
+
+///
+/// UD_TABLE
+///
+typedef struct {
+  ///
+  /// This field contains the bit-mapped attributes of the PARTIES information. Type
+  /// UDC_ATTRIBUTES is defined below.
+  ///
+  UDC_ATTRIBUTES                    Attributes;
+
+  ///
+  /// This field contains the zero-based device on which the selected
+  /// ServiceDataArea is present. It is 0 for master and 1 for the slave device.
+  ///
+  UINT8                             DeviceNumber;
+
+  ///
+  /// This field contains the zero-based index into the BbsTable for the parent device.
+  /// This index allows the user to reference the parent device information such as PCI
+  /// bus, device function.
+  ///
+  UINT8                             BbsTableEntryNumberForParentDevice;
+
+  ///
+  /// This field contains the zero-based index into the BbsTable for the boot entry.
+  ///
+  UINT8                             BbsTableEntryNumberForBoot;
+
+  ///
+  /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry.
+  ///
+  UINT8                             BbsTableEntryNumberForHddDiag;
+
+  ///
+  /// The raw Beer data.
+  ///
+  UINT8                             BeerData[128];
+
+  ///
+  /// The raw data of selected service area.
+  ///
+  UINT8                             ServiceAreaData[64];
+} UD_TABLE;
+
+#define EFI_TO_LEGACY_MAJOR_VERSION 0x02
+#define EFI_TO_LEGACY_MINOR_VERSION 0x00
+#define MAX_IDE_CONTROLLER          8
+
+///
+/// EFI_TO_COMPATIBILITY16_BOOT_TABLE
+///
+typedef struct {
+  UINT16                            MajorVersion;                 ///< The EfiCompatibility major version number.
+  UINT16                            MinorVersion;                 ///< The EfiCompatibility minor version number.
+  UINT32                            AcpiTable;                    ///< The location of the RSDT ACPI table. < 4G range.
+  UINT32                            SmbiosTable;                  ///< The location of the SMBIOS table in EFI memory. < 4G range.
+  UINT32                            SmbiosTableLength;
+  //
+  // Legacy SIO state
+  //
+  DEVICE_PRODUCER_DATA_HEADER       SioData;                      ///< Standard traditional device information.
+  UINT16                            DevicePathType;               ///< The default boot type.
+  UINT16                            PciIrqMask;                   ///< Mask of which IRQs have been assigned to PCI.
+  UINT32                            NumberE820Entries;            ///< Number of E820 entries. The number can change from the
+                                                                  ///< Compatibility16InitializeYourself() function.
+  //
+  // Controller & Drive Identify[2] per controller information
+  //
+  HDD_INFO                          HddInfo[MAX_IDE_CONTROLLER];  ///< Hard disk drive information, including raw Identify Drive data.
+  UINT32                            NumberBbsEntries;             ///< Number of entries in the BBS table
+  UINT32                            BbsTable;                     ///< A pointer to the BBS table. Type BBS_TABLE is defined below.
+  UINT32                            SmmTable;                     ///< A pointer to the SMM table. Type SMM_TABLE is defined below.
+  UINT32                            OsMemoryAbove1Mb;             ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can
+                                                                  ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more
+                                                                  ///< memory may have been discovered.
+  UINT32                            UnconventionalDeviceTable;    ///< Information to boot off an unconventional device like a PARTIES partition. Type
+                                                                  ///< UD_TABLE is defined below.
+} EFI_TO_COMPATIBILITY16_BOOT_TABLE;
+
+///
+/// EFI_LEGACY_INSTALL_PCI_HANDLER
+///
+typedef struct {
+  UINT8                             PciBus;             ///< The PCI bus of the device.
+  UINT8                             PciDeviceFun;       ///< The PCI device in bits 7:3 and function in bits 2:0.
+  UINT8                             PciSegment;         ///< The PCI segment of the device.
+  UINT8                             PciClass;           ///< The PCI class code of the device.
+  UINT8                             PciSubclass;        ///< The PCI subclass code of the device.
+  UINT8                             PciInterface;       ///< The PCI interface code of the device.
+  //
+  // Primary section
+  //
+  UINT8                             PrimaryIrq;         ///< The primary device IRQ.
+  UINT8                             PrimaryReserved;    ///< Reserved.
+  UINT16                            PrimaryControl;     ///< The primary device control I/O base.
+  UINT16                            PrimaryBase;        ///< The primary device I/O base.
+  UINT16                            PrimaryBusMaster;   ///< The primary device bus master I/O base.
+  //
+  // Secondary Section
+  //
+  UINT8                             SecondaryIrq;       ///< The secondary device IRQ.
+  UINT8                             SecondaryReserved;  ///< Reserved.
+  UINT16                            SecondaryControl;   ///< The secondary device control I/O base.
+  UINT16                            SecondaryBase;      ///< The secondary device I/O base.
+  UINT16                            SecondaryBusMaster; ///< The secondary device bus master I/O base.
+} EFI_LEGACY_INSTALL_PCI_HANDLER;
+
+//
+// Restore default pack value
+//
+#pragma pack()
+
+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \
+  { \
+    0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \
+  }
+
+typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL;
+
+///
+/// Flags returned by CheckPciRom().
+///
+#define NO_ROM            0x00
+#define ROM_FOUND         0x01
+#define VALID_LEGACY_ROM  0x02
+#define ROM_WITH_CONFIG   0x04     ///< Not defined in the Framework CSM Specification.
+
+///
+/// The following macros do not appear in the Framework CSM Specification and
+/// are kept for backward compatibility only.  They convert 32-bit address (_Adr)
+/// to Segment:Offset 16-bit form.
+///
+///@{
+#define EFI_SEGMENT(_Adr)     (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)
+#define EFI_OFFSET(_Adr)      (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)
+///@}
+
+#define CARRY_FLAG            0x01
+
+///
+/// EFI_EFLAGS_REG
+///
+typedef struct {
+  UINT32 CF:1;
+  UINT32 Reserved1:1;
+  UINT32 PF:1;
+  UINT32 Reserved2:1;
+  UINT32 AF:1;
+  UINT32 Reserved3:1;
+  UINT32 ZF:1;
+  UINT32 SF:1;
+  UINT32 TF:1;
+  UINT32 IF:1;
+  UINT32 DF:1;
+  UINT32 OF:1;
+  UINT32 IOPL:2;
+  UINT32 NT:1;
+  UINT32 Reserved4:2;
+  UINT32 VM:1;
+  UINT32 Reserved5:14;
+} EFI_EFLAGS_REG;
+
+///
+/// EFI_DWORD_REGS
+///
+typedef struct {
+    UINT32           EAX;
+    UINT32           EBX;
+    UINT32           ECX;
+    UINT32           EDX;
+    UINT32           ESI;
+    UINT32           EDI;
+    EFI_EFLAGS_REG   EFlags;
+    UINT16           ES;
+    UINT16           CS;
+    UINT16           SS;
+    UINT16           DS;
+    UINT16           FS;
+    UINT16           GS;
+    UINT32           EBP;
+    UINT32           ESP;
+} EFI_DWORD_REGS;
+
+///
+/// EFI_FLAGS_REG
+///
+typedef struct {
+  UINT16     CF:1;
+  UINT16     Reserved1:1;
+  UINT16     PF:1;
+  UINT16     Reserved2:1;
+  UINT16     AF:1;
+  UINT16     Reserved3:1;
+  UINT16     ZF:1;
+  UINT16     SF:1;
+  UINT16     TF:1;
+  UINT16     IF:1;
+  UINT16     DF:1;
+  UINT16     OF:1;
+  UINT16     IOPL:2;
+  UINT16     NT:1;
+  UINT16     Reserved4:1;
+} EFI_FLAGS_REG;
+
+///
+/// EFI_WORD_REGS
+///
+typedef struct {
+    UINT16           AX;
+    UINT16           ReservedAX;
+    UINT16           BX;
+    UINT16           ReservedBX;
+    UINT16           CX;
+    UINT16           ReservedCX;
+    UINT16           DX;
+    UINT16           ReservedDX;
+    UINT16           SI;
+    UINT16           ReservedSI;
+    UINT16           DI;
+    UINT16           ReservedDI;
+    EFI_FLAGS_REG    Flags;
+    UINT16           ReservedFlags;
+    UINT16           ES;
+    UINT16           CS;
+    UINT16           SS;
+    UINT16           DS;
+    UINT16           FS;
+    UINT16           GS;
+    UINT16           BP;
+    UINT16           ReservedBP;
+    UINT16           SP;
+    UINT16           ReservedSP;
+} EFI_WORD_REGS;
+
+///
+/// EFI_BYTE_REGS
+///
+typedef struct {
+    UINT8   AL, AH;
+    UINT16  ReservedAX;
+    UINT8   BL, BH;
+    UINT16  ReservedBX;
+    UINT8   CL, CH;
+    UINT16  ReservedCX;
+    UINT8   DL, DH;
+    UINT16  ReservedDX;
+} EFI_BYTE_REGS;
+
+///
+/// EFI_IA32_REGISTER_SET
+///
+typedef union {
+  EFI_DWORD_REGS  E;
+  EFI_WORD_REGS   X;
+  EFI_BYTE_REGS   H;
+} EFI_IA32_REGISTER_SET;
+
+/**
+  Thunk to 16-bit real mode and execute a software interrupt with a vector
+  of BiosInt. Regs will contain the 16-bit register context on entry and
+  exit.
+
+  @param[in]     This      The protocol instance pointer.
+  @param[in]     BiosInt   The processor interrupt vector to invoke.
+  @param[in,out] Reg       Register contexted passed into (and returned) from thunk to
+                           16-bit mode.
+
+  @retval TRUE                Thunk completed with no BIOS errors in the target code. See Regs for status.
+  @retval FALSE                  There was a BIOS error in the target code.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_LEGACY_BIOS_INT86)(
+  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN     UINT8                     BiosInt,
+  IN OUT EFI_IA32_REGISTER_SET     *Regs
+  );
+
+/**
+  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the
+  16-bit register context on entry and exit. Arguments can be passed on
+  the Stack argument
+
+  @param[in] This        The protocol instance pointer.
+  @param[in] Segment     The segemnt of 16-bit mode call.
+  @param[in] Offset      The offset of 16-bit mdoe call.
+  @param[in] Reg         Register contexted passed into (and returned) from thunk to
+                         16-bit mode.
+  @param[in] Stack       The caller allocated stack used to pass arguments.
+  @param[in] StackSize   The size of Stack in bytes.
+
+  @retval FALSE                 Thunk completed with no BIOS errors in the target code.                                See Regs for status.  @retval TRUE                  There was a BIOS error in the target code.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_LEGACY_BIOS_FARCALL86)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UINT16                    Segment,
+  IN UINT16                    Offset,
+  IN EFI_IA32_REGISTER_SET     *Regs,
+  IN VOID                      *Stack,
+  IN UINTN                     StackSize
+  );
+
+/**
+  Test to see if a legacy PCI ROM exists for this device. Optionally return
+  the Legacy ROM instance for this PCI device.
+
+  @param[in]  This        The protocol instance pointer.
+  @param[in]  PciHandle   The PCI PC-AT OPROM from this devices ROM BAR will be loaded
+  @param[out] RomImage    Return the legacy PCI ROM for this device.
+  @param[out] RomSize     The size of ROM Image.
+  @param[out] Flags       Indicates if ROM found and if PC-AT. Multiple bits can be set as follows:
+                            - 00 = No ROM.
+                            - 01 = ROM Found.
+                            - 02 = ROM is a valid legacy ROM.
+
+  @retval EFI_SUCCESS       The Legacy Option ROM available for this device
+  @retval EFI_UNSUPPORTED   The Legacy Option ROM is not supported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN  EFI_HANDLE                PciHandle,
+  OUT VOID                      **RomImage, OPTIONAL
+  OUT UINTN                     *RomSize, OPTIONAL
+  OUT UINTN                     *Flags
+  );
+
+/**
+  Load a legacy PC-AT OPROM on the PciHandle device. Return information
+  about how many disks were added by the OPROM and the shadow address and
+  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:
+
+  @param[in]  This               The protocol instance pointer.
+  @param[in]  PciHandle          The PCI PC-AT OPROM from this devices ROM BAR will be loaded.
+                                 This value is NULL if RomImage is non-NULL. This is the normal
+                                 case.
+  @param[in]  RomImage           A PCI PC-AT ROM image. This argument is non-NULL if there is
+                                 no hardware associated with the ROM and thus no PciHandle,
+                                 otherwise is must be NULL.
+                                 Example is PXE base code.
+  @param[out] Flags              The type of ROM discovered. Multiple bits can be set, as follows:
+                                   - 00 = No ROM.
+                                   - 01 = ROM found.
+                                   - 02 = ROM is a valid legacy ROM.
+  @param[out] DiskStart          The disk number of first device hooked by the ROM. If DiskStart
+                                 is the same as DiskEnd no disked were hooked.
+  @param[out] DiskEnd            disk number of the last device hooked by the ROM.
+  @param[out] RomShadowAddress   Shadow address of PC-AT ROM.
+  @param[out] RomShadowSize      Size of RomShadowAddress in bytes.
+
+  @retval EFI_SUCCESS             Thunk completed, see Regs for status.
+  @retval EFI_INVALID_PARAMETER   PciHandle not found
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN  EFI_HANDLE                PciHandle,
+  IN  VOID                      **RomImage,
+  OUT UINTN                     *Flags,
+  OUT UINT8                     *DiskStart, OPTIONAL
+  OUT UINT8                     *DiskEnd, OPTIONAL
+  OUT VOID                      **RomShadowAddress, OPTIONAL
+  OUT UINT32                    *ShadowedRomSize OPTIONAL
+  );
+
+/**
+  This function attempts to traditionally boot the specified BootOption. If the EFI context has
+  been compromised, this function will not return. This procedure is not used for loading an EFI-aware
+  OS off a traditional device. The following actions occur:
+  - Get EFI SMBIOS data structures, convert them to a traditional format, and copy to
+    Compatibility16.
+  - Get a pointer to ACPI data structures and copy the Compatibility16 RSD PTR to F0000 block.
+  - Find the traditional SMI handler from a firmware volume and register the traditional SMI
+    handler with the EFI SMI handler.
+  - Build onboard IDE information and pass this information to the Compatibility16 code.
+  - Make sure all PCI Interrupt Line registers are programmed to match 8259.
+  - Reconfigure SIO devices from EFI mode (polled) into traditional mode (interrupt driven).
+  - Shadow all PCI ROMs.
+  - Set up BDA and EBDA standard areas before the legacy boot.
+  - Construct the Compatibility16 boot memory map and pass it to the Compatibility16 code.
+  - Invoke the Compatibility16 table function Compatibility16PrepareToBoot(). This
+    invocation causes a thunk into the Compatibility16 code, which sets all appropriate internal
+    data structures. The boot device list is a parameter.
+  - Invoke the Compatibility16 Table function Compatibility16Boot(). This invocation
+    causes a thunk into the Compatibility16 code, which does an INT19.
+  - If the Compatibility16Boot() function returns, then the boot failed in a graceful
+    manner--meaning that the EFI code is still valid. An ungraceful boot failure causes a reset because the state
+    of EFI code is unknown.
+
+  @param[in] This             The protocol instance pointer.
+  @param[in] BootOption       The EFI Device Path from BootXXXX variable.
+  @param[in] LoadOptionSize   The size of LoadOption in size.
+  @param[in] LoadOption       LThe oadOption from BootXXXX variable.
+
+  @retval EFI_DEVICE_ERROR      Failed to boot from any boot device and memory is uncorrupted.                                Note: This function normally does not returns. It will either boot the                                OS or reset the system if memory has been "corrupted" by loading                                a boot sector and passing control to it.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_BOOT)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN BBS_BBS_DEVICE_PATH       *BootOption,
+  IN UINT32                    LoadOptionsSize,
+  IN VOID                      *LoadOptions
+  );
+
+/**
+  This function takes the Leds input parameter and sets/resets the BDA accordingly.
+  Leds is also passed to Compatibility16 code, in case any special processing is required.
+  This function is normally called from EFI Setup drivers that handle user-selectable
+  keyboard options such as boot with NUM LOCK on/off. This function does not
+  touch the keyboard or keyboard LEDs but only the BDA.
+
+  @param[in] This   The protocol instance pointer.
+  @param[in] Leds   The status of current Scroll, Num & Cap lock LEDS:
+                      - Bit 0 is Scroll Lock 0 = Not locked.
+                      - Bit 1 is Num Lock.
+                      - Bit 2 is Caps Lock.
+
+  @retval EFI_SUCCESS   The BDA was updated successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UINT8                     Leds
+  );
+
+/**
+  Retrieve legacy BBS info and assign boot priority.
+
+  @param[in]     This       The protocol instance pointer.
+  @param[out]    HddCount   The number of HDD_INFO structures.
+  @param[out]    HddInfo    Onboard IDE controller information.
+  @param[out]    BbsCount   The number of BBS_TABLE structures.
+  @param[in,out] BbsTable   Points to List of BBS_TABLE.
+
+  @retval EFI_SUCCESS   Tables were returned.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO)(
+  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,
+  OUT    UINT16                    *HddCount,
+  OUT    HDD_INFO                  **HddInfo,
+  OUT    UINT16                    *BbsCount,
+  IN OUT BBS_TABLE                 **BbsTable
+  );
+
+/**
+  Assign drive number to legacy HDD drives prior to booting an EFI
+  aware OS so the OS can access drives without an EFI driver.
+
+  @param[in]  This       The protocol instance pointer.
+  @param[out] BbsCount   The number of BBS_TABLE structures
+  @param[out] BbsTable   List of BBS entries
+
+  @retval EFI_SUCCESS   Drive numbers assigned.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  OUT UINT16                    *BbsCount,
+  OUT BBS_TABLE                 **BbsTable
+  );
+
+/**
+  To boot from an unconventional device like parties and/or execute
+  HDD diagnostics.
+
+  @param[in]  This              The protocol instance pointer.
+  @param[in]  Attributes        How to interpret the other input parameters.
+  @param[in]  BbsEntry          The 0-based index into the BbsTable for the parent
+                                device.
+  @param[in]  BeerData          A pointer to the 128 bytes of ram BEER data.
+  @param[in]  ServiceAreaData   A pointer to the 64 bytes of raw Service Area data. The
+                                caller must provide a pointer to the specific Service
+                                Area and not the start all Service Areas.
+
+  @retval EFI_INVALID_PARAMETER   If error. Does NOT return if no error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UDC_ATTRIBUTES            Attributes,
+  IN UINTN                     BbsEntry,
+  IN VOID                      *BeerData,
+  IN VOID                      *ServiceAreaData
+  );
+
+/**
+  Shadow all legacy16 OPROMs that haven't been shadowed.
+  Warning: Use this with caution. This routine disconnects all EFI
+  drivers. If used externally, then  the caller must re-connect EFI
+  drivers.
+
+  @param[in]  This   The protocol instance pointer.
+
+  @retval EFI_SUCCESS   OPROMs were shadowed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This
+  );
+
+/**
+  Get a region from the LegacyBios for S3 usage.
+
+  @param[in]  This                  The protocol instance pointer.
+  @param[in]  LegacyMemorySize      The size of required region.
+  @param[in]  Region                The region to use.
+                                    00 = Either 0xE0000 or 0xF0000 block.
+                                      - Bit0 = 1 0xF0000 block.
+                                      - Bit1 = 1 0xE0000 block.
+  @param[in]  Alignment             Address alignment. Bit mapped. The first non-zero
+                                    bit from right is alignment.
+  @param[out] LegacyMemoryAddress   The Region Assigned
+
+  @retval EFI_SUCCESS           The Region was assigned.
+  @retval EFI_ACCESS_DENIED     The function was previously invoked.
+  @retval Other                 The Region was not assigned.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION)(
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN  UINTN                     LegacyMemorySize,
+  IN  UINTN                     Region,
+  IN  UINTN                     Alignment,
+  OUT VOID                      **LegacyMemoryAddress
+  );
+
+/**
+  Get a region from the LegacyBios for Tiano usage. Can only be invoked once.
+
+  @param[in]  This                        The protocol instance pointer.
+  @param[in]  LegacyMemorySize            The size of data to copy.
+  @param[in]  LegacyMemoryAddress         The Legacy Region destination address.
+                                          Note: must be in region assigned by
+                                          LegacyBiosGetLegacyRegion.
+  @param[in]  LegacyMemorySourceAddress   The source of the data to copy.
+
+  @retval EFI_SUCCESS           The Region assigned.
+  @retval EFI_ACCESS_DENIED     Destination was outside an assigned region.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION)(
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
+  IN UINTN                     LegacyMemorySize,
+  IN VOID                      *LegacyMemoryAddress,
+  IN VOID                      *LegacyMemorySourceAddress
+  );
+
+///
+/// Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot()
+/// member function allows the BDS to support booting a traditional OS.
+/// EFI thunks drivers that make EFI bindings for BIOS INT services use
+/// all the other member functions.
+///
+struct _EFI_LEGACY_BIOS_PROTOCOL {
+  ///
+  /// Performs traditional software INT. See the Int86() function description.
+  ///
+  EFI_LEGACY_BIOS_INT86                       Int86;
+
+  ///
+  /// Performs a far call into Compatibility16 or traditional OpROM code.
+  ///
+  EFI_LEGACY_BIOS_FARCALL86                   FarCall86;
+
+  ///
+  /// Checks if a traditional OpROM exists for this device.
+  ///
+  EFI_LEGACY_BIOS_CHECK_ROM                   CheckPciRom;
+
+  ///
+  /// Loads a traditional OpROM in traditional OpROM address space.
+  ///
+  EFI_LEGACY_BIOS_INSTALL_ROM                 InstallPciRom;
+
+  ///
+  /// Boots a traditional OS.
+  ///
+  EFI_LEGACY_BIOS_BOOT                        LegacyBoot;
+
+  ///
+  /// Updates BDA to reflect the current EFI keyboard LED status.
+  ///
+  EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS  UpdateKeyboardLedStatus;
+
+  ///
+  /// Allows an external agent, such as BIOS Setup, to get the BBS data.
+  ///
+  EFI_LEGACY_BIOS_GET_BBS_INFO                GetBbsInfo;
+
+  ///
+  /// Causes all legacy OpROMs to be shadowed.
+  ///
+  EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS    ShadowAllLegacyOproms;
+
+  ///
+  /// Performs all actions prior to boot. Used when booting an EFI-aware OS
+  /// rather than a legacy OS.
+  ///
+  EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI         PrepareToBootEfi;
+
+  ///
+  /// Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block.
+  ///
+  EFI_LEGACY_BIOS_GET_LEGACY_REGION           GetLegacyRegion;
+
+  ///
+  /// Allows EFI to copy data to the area specified by GetLegacyRegion.
+  ///
+  EFI_LEGACY_BIOS_COPY_LEGACY_REGION          CopyLegacyRegion;
+
+  ///
+  /// Allows the user to boot off an unconventional device such as a PARTIES partition.
+  ///
+  EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE  BootUnconventionalDevice;
+};
+
+extern EFI_GUID gEfiLegacyBiosProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h
new file mode 100644
index 0000000000..1d776793d2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h
@@ -0,0 +1,118 @@
+/** @file
+  This protocol abstracts the PIRQ programming from the generic EFI Compatibility Support Modules (CSMs).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _EFI_LEGACY_INTERRUPT_H_
+#define _EFI_LEGACY_INTERRUPT_H_
+
+
+#define EFI_LEGACY_INTERRUPT_PROTOCOL_GUID \
+  { \
+    0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe } \
+  }
+
+typedef struct _EFI_LEGACY_INTERRUPT_PROTOCOL EFI_LEGACY_INTERRUPT_PROTOCOL;
+
+/**
+  Get the number of PIRQs this hardware supports.
+
+  @param  This                  The protocol instance pointer.
+  @param  NumberPirsq           The number of PIRQs that are supported.
+
+  @retval EFI_SUCCESS           The number of PIRQs was returned successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,
+  OUT UINT8                                   *NumberPirqs
+  );
+
+/**
+  Gets the PCI location associated with this protocol.
+
+  @param  This                  The Protocol instance pointer.
+  @param  Bus                   The PCI Bus.
+  @param  Device                The PCI Device.
+  @param  Function              The PCI Function.
+
+  @retval EFI_SUCCESS           The Bus, Device, and Function were returned successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_GET_LOCATION)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,
+  OUT UINT8                                   *Bus,
+  OUT UINT8                                   *Device,
+  OUT UINT8                                   *Function
+  );
+
+/**
+  Read the PIRQ register and return the data
+
+  @param  This                  The protocol instance pointer.
+  @param  PirqNumber            The PIRQ register to read.
+  @param  PirqData              The data read.
+
+  @retval EFI_SUCCESS           The data was read.
+  @retval EFI_INVALID_PARAMETER Invalid PIRQ number.
+  @retval EFI_DEVICE_ERROR      Operation was unsuccessful
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_READ_PIRQ)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,
+  IN  UINT8                                  PirqNumber,
+  OUT UINT8                                  *PirqData
+  );
+
+/**
+  Write the specified PIRQ register with the given data.
+
+  @param  This                  The protocol instance pointer.
+  @param  PirqNumber            A PIRQ register to read.
+  @param  PirqData              The data to write.
+
+  @retval EFI_SUCCESS           The PIRQ was programmed.
+  @retval EFI_INVALID_PARAMETER Invalid PIRQ number.
+  @retval EFI_DEVICE_ERROR      Operation was unsuccessful
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_INTERRUPT_WRITE_PIRQ)(
+  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,
+  IN  UINT8                                  PirqNumber,
+  IN UINT8                                   PirqData
+  );
+
+struct _EFI_LEGACY_INTERRUPT_PROTOCOL {
+  ///
+  ///   Gets the number of PIRQs supported.
+  ///
+  EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS GetNumberPirqs;
+
+  ///
+  /// Gets the PCI bus, device, and function that is associated with this protocol.
+  ///
+  EFI_LEGACY_INTERRUPT_GET_LOCATION     GetLocation;
+
+  ///
+  /// Reads the indicated PIRQ register.
+  ///
+  EFI_LEGACY_INTERRUPT_READ_PIRQ        ReadPirq;
+
+  ///
+  /// Writes to the indicated PIRQ register.
+  ///
+  EFI_LEGACY_INTERRUPT_WRITE_PIRQ       WritePirq;
+};
+
+extern EFI_GUID gEfiLegacyInterruptProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h
new file mode 100644
index 0000000000..c1d1fc89ec
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h
@@ -0,0 +1,65 @@
+/** @file
+  Definitions for data structures used in S3 resume.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_S3_DATA_H_
+#define _ACPI_S3_DATA_H_
+
+#include <Library/BaseLib.h>
+
+#define SMM_S3_RESUME_SMM_32 SIGNATURE_64 ('S','M','M','S','3','_','3','2')
+#define SMM_S3_RESUME_SMM_64 SIGNATURE_64 ('S','M','M','S','3','_','6','4')
+
+#pragma pack(1)
+
+typedef struct {
+  UINT64                Signature;
+  EFI_PHYSICAL_ADDRESS  SmmS3ResumeEntryPoint;
+  EFI_PHYSICAL_ADDRESS  SmmS3StackBase;
+  UINT64                SmmS3StackSize;
+  UINT64                SmmS3Cr0;
+  UINT64                SmmS3Cr3;
+  UINT64                SmmS3Cr4;
+  UINT16                ReturnCs;
+  EFI_PHYSICAL_ADDRESS  ReturnEntryPoint;
+  EFI_PHYSICAL_ADDRESS  ReturnContext1;
+  EFI_PHYSICAL_ADDRESS  ReturnContext2;
+  EFI_PHYSICAL_ADDRESS  ReturnStackPointer;
+  EFI_PHYSICAL_ADDRESS  Smst;
+} SMM_S3_RESUME_STATE;
+
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS  AcpiFacsTable;
+  EFI_PHYSICAL_ADDRESS  IdtrProfile;
+  EFI_PHYSICAL_ADDRESS  S3NvsPageTableAddress;
+  EFI_PHYSICAL_ADDRESS  BootScriptStackBase;
+  UINT64                BootScriptStackSize;
+  EFI_PHYSICAL_ADDRESS  S3DebugBufferAddress;
+} ACPI_S3_CONTEXT;
+
+typedef struct {
+  UINT16                ReturnCs;
+  UINT64                ReturnStatus;
+  EFI_PHYSICAL_ADDRESS  ReturnEntryPoint;
+  EFI_PHYSICAL_ADDRESS  ReturnStackPointer;
+  EFI_PHYSICAL_ADDRESS  AsmTransferControl;
+  IA32_DESCRIPTOR       Idtr;
+} PEI_S3_RESUME_STATE;
+
+#pragma pack()
+
+#define EFI_ACPI_S3_CONTEXT_GUID \
+  { \
+    0xef98d3a, 0x3e33, 0x497a, {0xa4, 0x1, 0x77, 0xbe, 0x3e, 0xb7, 0x4f, 0x38} \
+  }
+
+extern EFI_GUID gEfiAcpiS3ContextGuid;
+
+extern EFI_GUID gEfiAcpiVariableGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h
new file mode 100644
index 0000000000..c770101b38
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h
@@ -0,0 +1,17 @@
+/** @file
+  This GUID can be installed to the device handle to specify that the device is the console-out device.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __CONSOLE_OUT_DEVICE_H__
+#define __CONSOLE_OUT_DEVICE_H__
+
+#define EFI_CONSOLE_OUT_DEVICE_GUID    \
+    { 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+extern EFI_GUID gEfiConsoleOutDeviceGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
new file mode 100644
index 0000000000..bf4b3cdeca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
@@ -0,0 +1,30 @@
+/** @file
+  This file defines:
+  * Memory Type Information GUID for HOB and Variable.
+  * Memory Type Information Variable Name.
+  * Memory Type Information GUID HOB data structure.
+
+  The memory type information HOB and variable can
+  be used to store the information for each memory type in Variable or HOB.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __MEMORY_TYPE_INFORMATION_GUID_H__
+#define __MEMORY_TYPE_INFORMATION_GUID_H__
+
+#define EFI_MEMORY_TYPE_INFORMATION_GUID \
+  { 0x4c19049f,0x4137,0x4dd3, { 0x9c,0x10,0x8b,0x97,0xa8,0x3f,0xfd,0xfa } }
+
+#define EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME L"MemoryTypeInformation"
+
+extern EFI_GUID gEfiMemoryTypeInformationGuid;
+
+typedef struct {
+  UINT32  Type;             ///< EFI memory type defined in UEFI specification.
+  UINT32  NumberOfPages;    ///< The pages of this type memory.
+} EFI_MEMORY_TYPE_INFORMATION;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h
new file mode 100644
index 0000000000..754865943e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h
@@ -0,0 +1,80 @@
+/** @file
+  System reset Library Services.  This library class defines a set of
+  methods that reset the whole system.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h
new file mode 100644
index 0000000000..565d35b654
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h
@@ -0,0 +1,137 @@
+/** @file
+  EFI SMM Access PPI definition.
+
+  This PPI is used to control the visibility of the SMRAM on the platform.
+  It abstracts the location and characteristics of SMRAM.  The expectation is
+  that the north bridge or memory controller would publish this PPI.
+
+  The principal functionality found in the memory controller includes the following:
+  - Exposing the SMRAM to all non-SMM agents, or the "open" state
+  - Shrouding the SMRAM to all but the SMM agents, or the "closed" state
+  - Preserving the system integrity, or "locking" the SMRAM, such that the settings cannot be
+    perturbed by either boot service or runtime agents
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_PPI_H_
+#define _SMM_ACCESS_PPI_H_
+
+#define PEI_SMM_ACCESS_PPI_GUID \
+  { 0x268f33a9, 0xcccd, 0x48be, { 0x88, 0x17, 0x86, 0x5, 0x3a, 0xc3, 0x2e, 0xd6 }}
+
+typedef struct _PEI_SMM_ACCESS_PPI  PEI_SMM_ACCESS_PPI;
+
+/**
+  Opens the SMRAM area to be accessible by a PEIM driver.
+
+  This function "opens" SMRAM so that it is visible while not inside of SMM. The function should
+  return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. The function
+  should return EFI_DEVICE_ERROR if the SMRAM configuration is locked.
+
+  @param  PeiServices            General purpose services available to every PEIM.
+  @param  This                   The pointer to the SMM Access Interface.
+  @param  DescriptorIndex        The region of SMRAM to Open.
+
+  @retval EFI_SUCCESS            The region was successfully opened.
+  @retval EFI_DEVICE_ERROR       The region could not be opened because locked by chipset.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_OPEN)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  );
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function "closes" SMRAM so that it is not visible while outside of SMM. The function should
+  return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM.
+
+  @param  PeiServices              General purpose services available to every PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS              The region was successfully closed.
+  @retval EFI_DEVICE_ERROR         The region could not be closed because locked by chipset.
+  @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CLOSE)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  );
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function prohibits access to the SMRAM region.  This function is usually implemented such
+  that it is a write-once operation.
+
+  @param  PeiServices              General purpose services available to every PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS            The region was successfully locked.
+  @retval EFI_DEVICE_ERROR       The region could not be locked because at least
+                                 one range is still open.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_LOCK)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  );
+
+/**
+  Queries the memory controller for the possible regions that will support SMRAM.
+
+  @param  PeiServices           General purpose services available to every PEIM.
+  @param This                   The pointer to the SmmAccessPpi Interface.
+  @param SmramMapSize           The pointer to the variable containing size of the
+                                buffer to contain the description information.
+  @param SmramMap               The buffer containing the data describing the Smram
+                                region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CAPABILITIES)(
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  );
+
+///
+///  EFI SMM Access PPI is used to control the visibility of the SMRAM on the platform.
+///  It abstracts the location and characteristics of SMRAM.  The expectation is
+///  that the north bridge or memory controller would publish this PPI.
+///
+struct _PEI_SMM_ACCESS_PPI {
+  PEI_SMM_OPEN          Open;
+  PEI_SMM_CLOSE         Close;
+  PEI_SMM_LOCK          Lock;
+  PEI_SMM_CAPABILITIES  GetCapabilities;
+  BOOLEAN               LockState;
+  BOOLEAN               OpenState;
+};
+
+extern EFI_GUID gPeiSmmAccessPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h
new file mode 100644
index 0000000000..e982c00bf4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h
@@ -0,0 +1,87 @@
+/** @file
+  EFI SMM Control PPI definition.
+
+  This PPI is used to initiate SMI/PMI activations. This protocol could be published by either:
+  - A processor driver to abstract the SMI/PMI IPI
+  - The driver that abstracts the ASIC that is supporting the APM port, such as the ICH in an
+  Intel chipset
+  Because of the possibility of performing SMI or PMI IPI transactions, the ability to generate this
+  event from a platform chipset agent is an optional capability for both IA-32 and Itanium-based
+  systems.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_CONTROL_PPI_H_
+#define _SMM_CONTROL_PPI_H_
+
+#define PEI_SMM_CONTROL_PPI_GUID \
+  { 0x61c68702, 0x4d7e, 0x4f43, 0x8d, 0xef, 0xa7, 0x43, 0x5, 0xce, 0x74, 0xc5 }
+
+typedef struct _PEI_SMM_CONTROL_PPI  PEI_SMM_CONTROL_PPI;
+
+/**
+  Invokes SMI activation from either the preboot or runtime environment.
+
+  @param  PeiServices           General purpose services available to every PEIM.
+  @param  This                  The PEI_SMM_CONTROL_PPI instance.
+  @param  ArgumentBuffer        The optional sized data to pass into the protocol activation.
+  @param  ArgumentBufferSize    The optional size of the data.
+  @param  Periodic              An optional mechanism to periodically repeat activation.
+  @param  ActivationInterval    An optional parameter to repeat at this period one
+                                time or, if the Periodic Boolean is set, periodically.
+
+  @retval EFI_SUCCESS           The SMI/PMI has been engendered.
+  @retval EFI_DEVICE_ERROR      The timing is unsupported.
+  @retval EFI_INVALID_PARAMETER The activation period is unsupported.
+  @retval EFI_NOT_STARTED       The SMM base service has not been initialized.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_ACTIVATE) (
+  IN EFI_PEI_SERVICES                                **PeiServices,
+  IN PEI_SMM_CONTROL_PPI                             * This,
+  IN OUT INT8                                        *ArgumentBuffer OPTIONAL,
+  IN OUT UINTN                                       *ArgumentBufferSize OPTIONAL,
+  IN BOOLEAN                                         Periodic OPTIONAL,
+  IN UINTN                                           ActivationInterval OPTIONAL
+  );
+
+/**
+  Clears any system state that was created in response to the Active call.
+
+  @param  PeiServices           General purpose services available to every PEIM.
+  @param  This                  The PEI_SMM_CONTROL_PPI instance.
+  @param  Periodic              Optional parameter to repeat at this period one
+                                time or, if the Periodic Boolean is set, periodically.
+
+  @retval EFI_SUCCESS           The SMI/PMI has been engendered.
+  @retval EFI_DEVICE_ERROR      The source could not be cleared.
+  @retval EFI_INVALID_PARAMETER The service did not support the Periodic input argument.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_DEACTIVATE) (
+  IN EFI_PEI_SERVICES                      **PeiServices,
+  IN PEI_SMM_CONTROL_PPI                   * This,
+  IN BOOLEAN                               Periodic OPTIONAL
+  );
+
+///
+///  PEI SMM Control PPI is used to initiate SMI/PMI activations. This protocol could be published by either:
+///  - A processor driver to abstract the SMI/PMI IPI
+///  - The driver that abstracts the ASIC that is supporting the APM port, such as the ICH in an
+///  Intel chipset
+///
+struct _PEI_SMM_CONTROL_PPI {
+  PEI_SMM_ACTIVATE    Trigger;
+  PEI_SMM_DEACTIVATE  Clear;
+};
+
+extern EFI_GUID gPeiSmmControlPpiGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h
new file mode 100644
index 0000000000..4aaa715d77
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h
@@ -0,0 +1,33 @@
+/** @file
+  EFI SMM Variable Protocol is related to EDK II-specific implementation of variables
+  and intended for use as a means to store data in the EFI SMM environment.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SMM_VARIABLE_H__
+#define __SMM_VARIABLE_H__
+
+#define EFI_SMM_VARIABLE_PROTOCOL_GUID \
+  { \
+    0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 } \
+  }
+
+typedef struct _EFI_SMM_VARIABLE_PROTOCOL  EFI_SMM_VARIABLE_PROTOCOL;
+
+///
+/// EFI SMM Variable Protocol is intended for use as a means
+/// to store data in the EFI SMM environment.
+///
+struct _EFI_SMM_VARIABLE_PROTOCOL {
+  EFI_GET_VARIABLE            SmmGetVariable;
+  EFI_GET_NEXT_VARIABLE_NAME  SmmGetNextVariableName;
+  EFI_SET_VARIABLE            SmmSetVariable;
+  EFI_QUERY_VARIABLE_INFO     SmmQueryVariableInfo;
+};
+
+extern EFI_GUID gEfiSmmVariableProtocolGuid;
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: Add Include headers

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

Adds header files common to System Agent (SA) modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h                |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h        |  53 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h        |  96 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h  |  70 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h          |  46 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h             | 534 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h          |  61 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h            |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h       |  51 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h            | 135 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h            |  60 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h      | 354 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h          |  61 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h    | 103 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h |  63 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h           |  39 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h                |  42 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h                    |  77 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h               |  60 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h               |  87 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h                |  88 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h                           | 259 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h      |  15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h         |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h    |  23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h            |  70 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h         |  36 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h           |  31 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h                  |  89 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h                 | 151 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h           |  63 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h                   |  73 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h                 |  24 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h                     | 132 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h                    |  66 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h                   |  32 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h            | 214 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h                   |  50 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h                   |  37 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h                   |  64 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h                             | 106 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h                  |  23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h                      |  25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h                       |  51 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h                               |  32 ++
 45 files changed, 3845 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h
new file mode 100644
index 0000000000..020a4aeab5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  Policy definition for GNA Config Block
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h
new file mode 100644
index 0000000000..cc337a83f3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h
@@ -0,0 +1,53 @@
+/** @file
+  Graphics DXE Policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_DXE_CONFIG_H_
+#define _GRAPHICS_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define GRAPHICS_DXE_CONFIG_REVISION 2
+
+#define MAX_BCLM_ENTRIES    20
+
+/**
+  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.
+  <b>Revision 2</b>:
+  - Adding BCLM[MAX_BCLM_ENTRIES]
+**/
+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_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h
new file mode 100644
index 0000000000..276289ae81
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h
@@ -0,0 +1,96 @@
+/** @file
+  Policy definition for Internal Graphics Config Block (PostMem)
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_PEI_CONFIG_H_
+#define _GRAPHICS_PEI_CONFIG_H_
+#pragma pack(push, 1)
+
+#define GRAPHICS_PEI_CONFIG_REVISION 4
+#define DDI_DEVICE_NUMBER 4
+
+//
+// DDI defines
+//
+typedef enum {
+  DdiDisable       = 0x00,
+  DdiDdcEnable     = 0x01,
+  DdiTbtLsxEnable  = 0x02,
+} DDI_DDC_TBT_VAL;
+
+typedef enum {
+  DdiHpdDisable  = 0x00,
+  DdiHpdEnable   = 0x01,
+} DDI_HPD_VAL;
+
+typedef enum {
+  DdiPortADisabled = 0x00,
+  DdiPortAEdp      = 0x01,
+  DdiPortAMipiDsi  = 0x02,
+} DDI_PORTA_SETTINGS;
+/**
+  This structure configures the Native GPIOs for DDI port per VBT settings.
+**/
+typedef struct {
+  UINT8 DdiPortEdp;    /// The setting of eDP port, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortBHpd;   /// The HPD setting of DDI Port B, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortCHpd;   /// The HPD setting of DDI Port C, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortDHpd;   /// The HPD setting of DDI Port D, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortFHpd;   /// The HPD setting of DDI Port F, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortBDdc;   /// The DDC setting of DDI Port B, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortCDdc;   /// The DDC setting of DDI Port C, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortDDdc;   /// The DDC setting of DDI Port D, this settings must match VBT's settings. 0- Disable, <b>1- Enable</b>
+  UINT8 DdiPortFDdc;   /// The DDC setting of DDI Port F, this settings must match VBT's settings. <b>0- Disable</b>, 1- Enable
+  UINT8 Rsvd[3];       ///< Reserved for 4 bytes alignment
+} DDI_CONFIGURATION;
+
+/**
+  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>:
+  - Added SkipS3CdClockInit.
+  <b>Revision 3</b>:
+  - Added DeltaT12PowerCycleDelay, BltBufferAddress, BltBufferSize.
+  <b>Revision 4</b>:
+  - Deprecated DeltaT12PowerCycleDelay.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config Block Header
+  UINT32                RenderStandby     : 1;    ///< Offset 28:0 :<b>(Test)</b> This field is used to enable or disable RC6 (Render Standby): 0=FALSE, <b>1=TRUE</b>
+  UINT32                PmSupport         : 1;    ///< Offset 28:1 :<b>(Test)</b> IGD PM Support TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
+  UINT32                PavpEnable        : 1;    ///< Offset 28:2 :IGD PAVP TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
+  /**
+    Offset 28:3
+    CdClock Frequency select\n
+    CFL\n
+    0   = 337.5 Mhz, 1 = 450 Mhz,\n
+    2   = 540 Mhz,<b> 3 = 675 Mhz</b>,\n
+
+  **/
+  UINT32                CdClock            : 3;
+  UINT32                PeiGraphicsPeimInit: 1;   ///< Offset 28:6 : This policy is used to enable/disable Intel Gfx PEIM.<b>0- Disable</b>, 1- Enable
+  UINT32                CdynmaxClampEnable : 1;   ///< Offset 28:7 : This policy is used to enable/disable CDynmax Clamping Feature (CCF) <b>1- Enable</b>, 0- Disable
+  UINT32                GtFreqMax          : 8;   ///< Offset 28:8 : <b>(Test)</b> Max GT frequency limited by user in multiples of 50MHz: Default value which indicates normal frequency is <b>0xFF</b>
+  UINT32                DisableTurboGt     : 1;   ///< Offset 28:9 : This policy is used to enable/disable DisableTurboGt <b>0- Disable</b>, 1- Enable
+  UINT32                RsvdBits0          : 15;  ///< Offser 28:15 :Reserved for future use
+  VOID*                 LogoPtr;                  ///< Offset 32 Address of Intel Gfx PEIM Logo to be displayed
+  UINT32                LogoSize;                 ///< Offset 36 Intel Gfx PEIM Logo Size
+  VOID*                 GraphicsConfigPtr;        ///< Offset 40 Address of the Graphics Configuration Table
+  DDI_CONFIGURATION     DdiConfiguration;         ///< Offset 44 DDI configuration, need to match with VBT settings.
+  UINT32                SkipS3CdClockInit  : 1;   ///< Offset 56 SKip full CD clock initialization being done during S3 resume.<b>0- Disable<\b>, 1- Enable
+  UINT32                ReservedBits       : 31;  ///< Offset 56: 1 : Reserved for future use.
+  UINT16                DeltaT12PowerCycleDelay;  ///< Offset 60 @deprecated Power Cycle Delay required for eDP as per VESA standard.<b>0 - 0 ms<\b>, 0xFFFF - Auto calculate to max 500 ms
+  UINT8                 Reserved[2];              ///< Offset 62 Reserved for future use.
+  VOID*                 BltBufferAddress;         ///< Offset 64 Address of Blt buffer for PEIM Logo use
+  UINT32                BltBufferSize;            ///< Offset 68 The size for Blt Buffer, calculating by PixelWidth * PixelHeight * 4 bytes (the size of EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+} GRAPHICS_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _GRAPHICS_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h
new file mode 100644
index 0000000000..4986fdab60
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h
@@ -0,0 +1,70 @@
+/** @file
+  Policy definition for Internal Graphics Config Block (PreMem)
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_PEI_PREMEM_CONFIG_H_
+#define _GRAPHICS_PEI_PREMEM_CONFIG_H_
+#pragma pack(push, 1)
+
+#define GRAPHICS_PEI_PREMEM_CONFIG_REVISION 2
+
+
+/**
+  This Configuration block is to configure GT related PreMem data/variables.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added DeltaT12PowerCycleDelayPreMem.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28:0
+    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
+  **/
+  UINT32                PrimaryDisplay    : 3;
+  /**
+    Offset 28:3
+    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.
+  **/
+  UINT32                InternalGraphics  : 2;
+  /**
+    Offset 28:5
+    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>
+  **/
+  UINT32                IgdDvmt50PreAlloc : 8;
+  UINT32                PanelPowerEnable  : 1;          ///< Offset 28:13 :<b>(Test)</b> Control for enabling/disabling VDD force bit (Required only for early enabling of eDP panel): 0=FALSE, <b>1=TRUE</b>
+  UINT32                ApertureSize      : 7;          ///< Offser 28:14 :Graphics aperture size (256MB is the recommended size as per BWG) : 0=128MB, <b>1=256MB</b>, 3=512MB, 7=1024MB, 15=2048MB.
+  UINT32                GtPsmiSupport     : 1;          ///< Offser 28:21 :PSMI support On/Off: <b>0=FALSE</b>, 1=TRUE
+  UINT32                PsmiRegionSize    : 3;          ///< Offser 28:22 :Psmi region size: <b>0=32MB</b>, 1=288MB, 2=544MB, 3=800MB, 4=1056MB
+  UINT32                RsvdBits0         : 7;          ///< Offser 28:25 :Reserved for future use
+  UINT32                GttMmAdr;                       ///< Offset 32 Temp Address of System Agent GTTMMADR : Default is <b>0xCF000000< / b>
+  UINT16                GttSize;                        ///< Offset 36 Selection of iGFX GTT Memory size: 1=2MB, 2=4MB, <b>3=8MB</b>
+  UINT8                 Rsvd1[2];                       ///< Offset 38 Reserved for DWORD alignment
+  UINT32                GmAdr;                          ///< Offset 40 Temp Address of System Agent GMADR : Default is <b>0xD0000000< / b>
+  UINT16                DeltaT12PowerCycleDelayPreMem;  ///< Offset 44 Power Cycle Delay required for eDP as per VESA standard.<b>0 - 0 ms<\b>, 0xFFFF - Auto calculate to max 500 ms
+  UINT8                 Reserved[2];                    ///< Offset 46 Reserved for future use.
+} GRAPHICS_PEI_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _GRAPHICS_PEI_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h
new file mode 100644
index 0000000000..79025d16fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h
@@ -0,0 +1,46 @@
+/** @file
+  IPU policy definitions (PreMem)
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IPU_CONFIG_PREMEM_H_
+#define _IPU_CONFIG_PREMEM_H_
+
+#pragma pack(push, 1)
+
+#define IPU_PREMEM_CONFIG_REVISION 1
+
+#define SA_IMR_IPU_CAMERA   0
+#define SA_IMR_IPU_GEN      1
+
+/**
+ IPU PreMem configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;           ///< Offset  0-27 Config Block Header
+  /**
+  Offset 28:0 :
+  <b>(Test)</b> It enables the SA IPU Device if supported and not fused off.
+  If FALSE, all other policies in this config block will be ignored.
+  <b>1=TRUE</b>;
+  0=FALSE.
+  **/
+  UINT32    SaIpuEnable:1;
+  /**
+  Offset 28:1 :
+  <b>(Test)</b> It configure the IPU IMR to IPU Camera or IPU Gen when IPU is enabled.
+  If FALSE, all other policies in this config block will be ignored.
+  <b>0=IPU Camera</b>;
+  1=IPU Gen
+  **/
+  UINT32    SaIpuImrConfiguration:1;
+  UINT32    RsvdBits0:30;                     /// Offset 28:2 :Reserved for future use.
+} IPU_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _IPU_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h
new file mode 100644
index 0000000000..8374ff5f68
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h
@@ -0,0 +1,534 @@
+/** @file
+  Policy definition of Memory Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MEMORY_CONFIG_H_
+#define _MEMORY_CONFIG_H_
+
+#include <SaRegs.h>
+
+#pragma pack(push, 1)
+
+#define SA_MRC_ITERATION_MAX      (6)
+#define SA_MRC_MAX_RCOMP          (3)
+#define SA_MRC_MAX_RCOMP_TARGETS  (5)
+
+#define MEMORY_CONFIG_REVISION 3
+
+///
+/// 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;
+
+typedef struct {
+  UINT8 SpdData[SA_MC_MAX_CHANNELS][SA_MC_MAX_SLOTS][SA_MC_MAX_SPD_SIZE];
+//Next Field Offset 2048
+} SPD_DATA_BUFFER;
+
+typedef struct {
+  UINT8 DqByteMap[SA_MC_MAX_CHANNELS][SA_MRC_ITERATION_MAX][2];
+//Next Field Offset 24
+} SA_MEMORY_DQ_MAPPING;
+
+typedef struct {
+  UINT8 DqsMapCpu2Dram[SA_MC_MAX_CHANNELS][SA_MC_MAX_BYTES_NO_ECC];
+//Next Field Offset 16
+} SA_MEMORY_DQS_MAPPING;
+
+typedef struct {
+  UINT16  RcompResistor[SA_MRC_MAX_RCOMP];       ///< Offset 0: Reference RCOMP resistors on motherboard
+  UINT16  RcompTarget[SA_MRC_MAX_RCOMP_TARGETS]; ///< Offset 6: RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+//Next Field Offset 16
+} SA_MEMORY_RCOMP;
+
+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);
+typedef UINT16     (EFIAPI * SA_IO_READ_16)              (UINTN IoAddress);
+typedef UINT32     (EFIAPI * SA_IO_READ_32)              (UINTN IoAddress);
+typedef UINT8      (EFIAPI * SA_IO_WRITE_8)              (UINTN IoAddress, UINT8 Value);
+typedef UINT16     (EFIAPI * SA_IO_WRITE_16)             (UINTN IoAddress, UINT16 Value);
+typedef UINT32     (EFIAPI * SA_IO_WRITE_32)             (UINTN IoAddress, UINT32 Value);
+typedef UINT8      (EFIAPI * SA_MMIO_READ_8)             (UINTN Address);
+typedef UINT16     (EFIAPI * SA_MMIO_READ_16)            (UINTN Address);
+typedef UINT32     (EFIAPI * SA_MMIO_READ_32)            (UINTN Address);
+typedef UINT64     (EFIAPI * SA_MMIO_READ_64)            (UINTN Address);
+typedef UINT8      (EFIAPI * SA_MMIO_WRITE_8)            (UINTN Address, UINT8 Value);
+typedef UINT16     (EFIAPI * SA_MMIO_WRITE_16)           (UINTN Address, UINT16 Value);
+typedef UINT32     (EFIAPI * SA_MMIO_WRITE_32)           (UINTN Address, UINT32 Value);
+typedef UINT64     (EFIAPI * SA_MMIO_WRITE_64)           (UINTN Address, UINT64 Value);
+typedef UINT8      (EFIAPI * SA_SMBUS_READ_8)            (UINTN Address, RETURN_STATUS *Status);
+typedef UINT16     (EFIAPI * SA_SMBUS_READ_16)           (UINTN Address, RETURN_STATUS *Status);
+typedef UINT8      (EFIAPI * SA_SMBUS_WRITE_8)           (UINTN Address, UINT8 Value, RETURN_STATUS *Status);
+typedef UINT16     (EFIAPI * SA_SMBUS_WRITE_16)          (UINTN Address, UINT16 Value, RETURN_STATUS *Status);
+typedef UINT32     (EFIAPI * SA_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef UINT32     (EFIAPI * SA_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef VOID       (EFIAPI * SA_GET_RTC_TIME)            (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
+typedef UINT64     (EFIAPI * SA_GET_CPU_TIME)            (VOID *GlobalData);
+typedef VOID *     (EFIAPI * SA_MEMORY_COPY)             (VOID *Destination, CONST VOID *Source, UINTN NumBytes);
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_BYTE)         (VOID *Buffer, UINTN NumBytes, UINT8 Value);
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_WORD)         (VOID *Buffer, UINTN NumWords, UINT16 Value);
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_DWORD)        (VOID *Buffer, UINTN NumDwords, UINT32 Value);
+typedef UINT64     (EFIAPI * SA_LEFT_SHIFT_64)           (UINT64 Data, UINTN NumBits);
+typedef UINT64     (EFIAPI * SA_RIGHT_SHIFT_64)          (UINT64 Data, UINTN NumBits);
+typedef UINT64     (EFIAPI * SA_MULT_U64_U32)            (UINT64 Multiplicand, UINT32 Multiplier);
+typedef UINT64     (EFIAPI * SA_DIV_U64_U64)             (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);
+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);
+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);
+typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_READ)        (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);
+typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_WRITE)       (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);
+typedef UINT32     (EFIAPI * SA_GET_MEMORY_VDD)          (VOID *GlobalData, UINT32 DefaultVdd);
+typedef UINT32     (EFIAPI * SA_SET_MEMORY_VDD)          (VOID *GlobalData, UINT32 DefaultVdd, UINT32 Value);
+typedef UINT32     (EFIAPI * SA_CHECKPOINT)              (VOID *GlobalData, UINT32 CheckPoint, VOID *Scratch);
+typedef VOID       (EFIAPI * SA_DEBUG_HOOK)              (VOID *GlobalData, UINT16 DisplayDebugNumber);
+typedef UINT8      (EFIAPI * SA_CHANNEL_EXIST)           (VOID *Outputs, UINT8 Channel);
+typedef INT32      (EFIAPI * SA_PRINTF)                  (VOID *Debug, UINT32 Level, char *Format, ...);
+typedef VOID       (EFIAPI * SA_DEBUG_PRINT)             (VOID *String);
+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);
+typedef UINT8      (EFIAPI * SA_SIGN_EXTEND)             (UINT8 Value, UINT8 OldMsb, UINT8 NewMsb);
+typedef VOID       (EFIAPI * SA_SHIFT_PI_COMMAND_TRAIN)  (VOID *GlobalData, UINT8 Channel, UINT8 Iteration, UINT8 RankMask, UINT8 GroupMask, INT32 NewValue, UINT8 UpdateHost);
+typedef VOID       (EFIAPI * SA_UPDATE_VREF)             (VOID *GlobalData, UINT8 Channel, UINT8 RankMask, UINT16 DeviceMask, UINT8 VrefType, INT32 Offset, BOOLEAN UpdateMrcData, BOOLEAN PDAmode, BOOLEAN SkipWait);
+typedef UINT8      (EFIAPI * SA_GET_RTC_CMOS)            (UINT8 Location);
+typedef UINT64     (EFIAPI * SA_MSR_READ_64)             (UINT32 Location);
+typedef UINT64     (EFIAPI * SA_MSR_WRITE_64)            (UINT32 Location, UINT64 Data);
+typedef UINT32     (EFIAPI * SA_THERMAL_OVERRIDES)       (VOID *GlobalData);
+typedef VOID       (EFIAPI * SA_MRC_RETURN_FROM_SMC)     (VOID *GlobalData, UINT32 MrcStatus);
+typedef VOID       (EFIAPI * SA_MRC_DRAM_RESET)          (UINT32 PciEBaseAddress, UINT32 ResetValue);
+typedef VOID       (EFIAPI * SA_SET_LOCK_PRMRR)          (UINT32 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_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>:
+ - Removed GearType.
+ - Added Lp4DqsOscEn, RMTLoopCount, EnBER, DualDimmPerChannelBoardType.
+ <b>Revision 3</b>:
+ - Removed EvLoader, EvLoaderDelay.
+**/
+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 DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  RemapEnable:1;                  ///<  - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+  UINT32  ScramblerSupport:1;             ///<  - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor: 0=Disable, <b>1=Enable</b>
+  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set option: 0=Set A, <b>1=Set B</b>
+  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bit 7-8 Reserved
+  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+  UINT32  Ddr4DdpSharedClock:1;           ///<  - Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  UINT32  SharedZqPin:1;                  ///<  - Select if ZQ pin is shared between Rank ranks.  For CFL, this option only works for DDR4.  the option works for LPDDR4 and DDR4. <b>0=Not shared</b>, 1=Shared
+  // Thermal Management
+  UINT32  ThermalManagement:1;            ///<  - <CFL> Memory Thermal Management Support: <b>0=Disable</b>, 1=Enable.
+  UINT32  PeciInjectedTemp:1;             ///<  - <CFL> Enable/Disable memory temperatures to be injected to the processor via PECI: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnBoard:1;            ///<  - <CFL> Enable/Disable routing TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnDimm:1;             ///<  - <CFL> Enable/Disable routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  VirtualTempSensor:1;            ///<  - <CFL> Enable/Disable Virtual Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
+  UINT32  Lp4DqsOscEn :1;                 ///<  - <CNL> LpDdrDqDqsReTraining - DqDqsReTraining Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DualDimmPerChannelBoardType:1;  ///<  - <CFL> DualDimmPerChannelBoardType - Option to indicate if the Memory Design for the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>, 1=Dual DIMM Design
+  UINT32  ReservedBits1:13;
+  /**
+   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[SA_MC_MAX_CHANNELS]; ///< Offset 68
+  /**
+   Selects the ratio to multiply the reference clock by for the DDR frequency\n
+   When RefClk is 133MHz\n
+   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are invalid\n
+   When RefClk is 100MHz\n
+   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are invalid\n
+  **/
+  UINT8   Ratio;                  ///< Offset 70
+  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+  /**
+     - 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 76 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   EnergyScaleFact;        ///< Offset 77 Energy Scale Factor. 0=Minimal, 7=Maximum, <b>4=Default</b>
+  BOOLEAN PerBankRefresh;         ///< <CNL> Offset 78 Enables and Disables the per bank refresh.  This only impacts memory technologies that support PBR: LPDDR3, LPDDR4.  FALSE=Disabled, <b>TRUE=Enabled</b>
+  UINT8   McLock;                 ///< <CFL> Offset 79 Enable/Disable memory configuration register locking: 0=Disable, <b>1=Enable</b>.
+  // Training Algorithms 1
+  UINT32 ECT:1;                   ///< Offset 80 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;                   ///<  - 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;            ///<  - 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;                ///<  - 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;                 ///<  - 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;                  ///<  - 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;               ///<  - 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;               ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;              ///<  - 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;              ///<  - 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;               ///<  - 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;                 ///<  - 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;                ///<  - 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;                 ///<  - 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;                 ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;                 ///<  - 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;                   ///<  - 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;                   ///<  - 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;                   ///<  - 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;                   ///<  - Enable/Disable Rank Margin Tool function: <b>0=Disable</b>, 1=Enable.
+  UINT32 MEMTST:1;                ///<  - Enable/Disable Memory Test function: <b>0=Disable</b>, 1=Enable.
+  UINT32 ALIASCHK:1;              ///<  - Enable/Disable DIMM SPD Alias Check: 0=Disable, <b>1=Enable</b>
+  UINT32 RCVENC1D:1;              ///<  - 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;                   ///<  - 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;               ///<  - 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
+  UINT32  CMDSR    : 1;           ///< <CFL> Offset 84 - Enable/Disable CMD Slew Rate Training: 0=Disable, <b>1=Enable</b>.
+  UINT32  CMDDSEQ  : 1;           ///< <CFL>  - Enable/Disable CMD Drive Strength and Tx Equalization: 0=Disable, <b>1=Enable</b>.
+  UINT32  CMDNORM  : 1;           ///< <CFL>  - Enable/Disable CMD Normalization: 0=Disable, <b>1=Enable</b>.
+  UINT32  EWRDSEQ  : 1;           ///< <CFL>  - Enable/Disable Early DQ Write Drive Strength and Equalization Training: 0=Disable, <b>1=Enable</b>.
+  UINT32  RDVC1D   : 1;           ///< <CNL>  - Enable/Disable Read Voltage Centering 1D
+  UINT32  TXTCO    : 1;           ///< <CNL>  - Enable/Disable Write TCO Comp Training
+  UINT32  CLKTCO   : 1;           ///< <CNL>  - Enable/Disable Clock TCO Comp Training
+  UINT32  ReservedBits2 :25;
+
+  UINT32  OddRatioMode:1;             ///< Offset 88 If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcTimeMeasure:1;           ///<  - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcFastBoot:1;              ///<  - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+  UINT32  DqPinsInterleaved:1;        ///<  - Interleaving mode of DQ/DQS pins for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
+  UINT32  RankInterleave:1;           ///<  - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  EnhancedInterleave:1;       ///<  - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  WeaklockEn:1;               ///<  - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  CmdTriStateDis:1;           ///<  - CMD Tri-State Support: <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if Command RTT is not present on the platform.
+  UINT32  MemoryTrace:1;              ///<  - Memory Trace to second DDR channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  ChHashEnable:1;             ///<  - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  EnableExtts:1;              ///<  - Enable Extts: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableCltm:1;               ///<  - Enable Closed Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableOltm:1;               ///<  - Enable Open Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnablePwrDn:1;              ///<  - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  EnablePwrDnLpddr:1;         ///<  - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  LockPTMregs:1;              ///<  - Lock PCU Thermal Management registers: 0=Disable, <b>1=Enable</b>
+  UINT32  UserPowerWeightsEn:1;       ///<  - Allows user to explicitly set power weight, scale factor, and channel power floor values: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Lock:1;             ///<  - Lock DDR_RAPL_LIMIT register: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Ena:1;              ///<  - Enable Power Limit 2: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim1Ena:1;              ///<  - Enable Power Limit 1: <b>0=Disable</b>, 1=Enable
+  UINT32  SrefCfgEna:1;               ///<  - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeatLpddr:1;    ///<  - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeat:1;         ///<  - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+  UINT32  AutoSelfRefreshSupport:1;   ///<  - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+  UINT32  ExtTemperatureSupport:1;    ///<  - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+  UINT32  MobilePlatform:1;           ///<  - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+  UINT32  Force1Dpc:1;                ///<  - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+  UINT32  ForceSingleRank:1;          ///<  - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+  UINT32  RhPrevention:1;             ///<  - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+  UINT32  VttTermination:1;           ///<  - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+  UINT32  VttCompForVsshi:1;          ///<  - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+  UINT32  ExitOnFailure:1;            ///<  - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+
+  UINT32  VddSettleWaitTime;      ///< Offset 92 Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+  UINT16  FreqSaGvLow;            ///< Offset 96 SA GV: 0 is Auto/default, otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333, 1400, 1600, 1800, 1867.
+  UINT16  SrefCfgIdleTmr;         ///< Offset 98 Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+  UINT8   RhActProbability;       ///< Offset 100 Activation probability for Hardware RHP
+  UINT8   SmramMask;              ///< Offset 101 Reserved memory ranges for SMRAM
+  UINT16  Vc1ReadMeterThreshold;  ///< <CFL> Offset 102 VC1 Read Meter Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum, <b>0x118=Default</b>
+  UINT32  Vc1ReadMeterTimeWindow; ///< <CFL> Offset 104 VC1 Read Meter Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
+  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es): <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
+
+  UINT16  ChHashMask;             ///< Offset 140 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 142 Memory Frequency setting: 3=1067, 5=1333, 7=1600, 9=1867, 11=2133, 13=2400, <b>15=2667</b>
+  UINT8   RaplLim2WindX;          ///< Offset 144 Power Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8   RaplLim2WindY;          ///< Offset 145 Power Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8   RaplLim1WindX;          ///< Offset 146 Power Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
+  UINT8   RaplLim1WindY;          ///< Offset 147 Power Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
+  UINT16  RaplLim2Pwr;            ///< Offset 148  Power Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
+  UINT16  RaplLim1Pwr;            ///< Offset 150  Power Limit 1: <b>0=Minimal</b>, 16383=Maximum
+  UINT8   WarmThresholdCh0Dimm0;  ///< Offset 152 Warm Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmThresholdCh0Dimm1;  ///< Offset 153 Warm Threshold (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmThresholdCh1Dimm0;  ///< Offset 154 Warm Threshold (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmThresholdCh1Dimm1;  ///< Offset 155 Warm Threshold (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh0Dimm0;   ///< Offset 156 Hot Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh0Dimm1;   ///< Offset 157 Hot Threshold (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh1Dimm0;   ///< Offset 158 Hot Threshold (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotThresholdCh1Dimm1;   ///< Offset 159 Hot Threshold (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh0Dimm0;     ///< Offset 160 Warm Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh0Dimm1;     ///< Offset 161 Warm Budget (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh1Dimm0;     ///< Offset 162 Warm Budget (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   WarmBudgetCh1Dimm1;     ///< Offset 163 Warm Budget (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh0Dimm0;      ///< Offset 164 Hot Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh0Dimm1;      ///< Offset 165 Hot Budget (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh1Dimm0;      ///< Offset 166 Hot Budget (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8   HotBudgetCh1Dimm1;      ///< Offset 167 Hot Budget (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
+  UINT8   IdleEnergyCh0Dimm0;     ///< Offset 168 Idle Energy (Channel 0, Dimm 0): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   IdleEnergyCh0Dimm1;     ///< Offset 169 Idle Energy (Channel 0, Dimm 1): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   IdleEnergyCh1Dimm0;     ///< Offset 170 Idle Energy (Channel 1, Dimm 0): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   IdleEnergyCh1Dimm1;     ///< Offset 171 Idle Energy (Channel 1, Dimm 1): 0=Minimal, 63=Maximum, <b>10=Default</b>
+  UINT8   PdEnergyCh0Dimm0;       ///< Offset 172 Power Down Energy (Channel 0, Dimm 0): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   PdEnergyCh0Dimm1;       ///< Offset 173 Power Down Energy (Channel 0, Dimm 1): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   PdEnergyCh1Dimm0;       ///< Offset 174 Power Down Energy (Channel 1, Dimm 0): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   PdEnergyCh1Dimm1;       ///< Offset 175 Power Down Energy (Channel 1, Dimm 1): 0=Minimal, 63=Maximum, <b>6=Default</b>
+  UINT8   ActEnergyCh0Dimm0;      ///< Offset 176 Activation Energy (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   ActEnergyCh0Dimm1;      ///< Offset 177 Activation Energy (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   ActEnergyCh1Dimm0;      ///< Offset 178 Activation Energy (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   ActEnergyCh1Dimm1;      ///< Offset 179 Activation Energy (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>172=Default</b>
+  UINT8   RdEnergyCh0Dimm0;       ///< Offset 180 Read Energy (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   RdEnergyCh0Dimm1;       ///< Offset 181 Read Energy (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   RdEnergyCh1Dimm0;       ///< Offset 182 Read Energy (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   RdEnergyCh1Dimm1;       ///< Offset 183 Read Energy (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>212=Default</b>
+  UINT8   WrEnergyCh0Dimm0;       ///< Offset 184 Write Energy (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>221=Default</b>
+  UINT8   WrEnergyCh0Dimm1;       ///< Offset 185 Write Energy (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>221=Default</b>
+  UINT8   WrEnergyCh1Dimm0;       ///< Offset 186 Write Energy (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>221=Default</b>
+  UINT8   WrEnergyCh1Dimm1;       ///< Offset 187 Write Energy (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>221=Default</b>
+
+
+  UINT8   MaxRttWr;               ///< Offset 188 Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+  UINT8   ThrtCkeMinTmr;          ///< Offset 189 Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
+  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
+  UINT8   BerEnable;              ///< Offset 191 BER Enable and # of Addresses passed in: <b>0=Minimal</b>, 8=Maximum
+  UINT8   CkeRankMapping;         ///< Offset 192 Bits [7:4] - Channel 1, bits [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes to.
+  UINT8   StrongWkLeaker;         ///< Offset 193 Strong Weak Leaker: 1=Minimal, <b>7=Maximum</b>
+  UINT8   CaVrefConfig;           ///< Offset 194 0=VREF_CA goes to both CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A, VREF_DQ_B to CH_B</b>
+  UINT8   SaGv;                   ///< Offset 195 SA GV: 0=Disabled; 1=FixedLow; CFL: 2=FixedHigh, CNL: 2=FixedMid; <b>CFL: 3=Enabled</b> CNL: 3=FixedHigh; <b>CNL: 4=Enabled</b>
+  UINT8   RaplPwrFlCh1;           ///< Offset 196 Power Channel 1 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   RaplPwrFlCh0;           ///< Offset 197 Power Channel 0 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   NModeSupport;           ///< Offset 198 Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+  UINT8   RefClk;                 ///< Offset 199 Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+  UINT8   EnCmdRate;              ///< Offset 200 CMD Rate Enable: 0=Disable, 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7 CMDs
+  UINT8   Refresh2X;              ///< Offset 201 Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+  UINT8   EpgEnable;              ///< Offset 202 Enable Energy Performance Gain.
+  UINT8   RhSolution;             ///< Offset 203 Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  UINT8   UserThresholdEnable;    ///< Offset 204 Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   UserBudgetEnable;       ///< Offset 205 Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodTcritMax;           ///< Offset 206 TSOD Tcrit Maximum Value  to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
+
+  UINT8   TsodEventMode;          ///< Offset 207 Flag to Enable Event Mode Interruption in TSOD Configuration Register, 0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventPolarity;      ///< Offset 208 Event Signal Polarity in TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
+  UINT8   TsodCriticalEventOnly;  ///< Offset 209 Critical Trigger Only in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventOutputControl; ///< Offset 210 Event Output Control in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 Alarm Windows Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodCriticaltripLockBit;///< Offset 212 Critical Trip Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodShutdownMode;       ///< Offset 213 Shutdown Mode TSOD Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
+  UINT8   TsodThigMax;            ///< Offset 214 Thigh Max Value In the  for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodManualEnable;       ///< Offset 215 Flag to manually select the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   DllBwEn0;               ///< Offset 216 DllBwEn value for 1067
+  UINT8   DllBwEn1;               ///< Offset 217 DllBwEn value for 1333
+  UINT8   DllBwEn2;               ///< Offset 218 DllBwEn value for 1600
+  UINT8   DllBwEn3;               ///< Offset 219 DllBwEn value for 1867 and up
+  UINT8   RetrainOnFastFail;      ///< Offset 220 Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 Force OLTM or 2X Refresh when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
+  UINT8   PowerDownMode;          ///< Offset 222 CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+  UINT8   PwdwnIdleCounter;       ///< Offset 223 CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal, 0xFF=Maximum, <b>0x99=Default</b>
+  UINT8   CmdRanksTerminated;     ///< <CNL> Offset 225 LPDDR4: Bitmask of ranks that have CA bus terminated. <b>0x01=Default, Rank0 is terminating and Rank1 is non-terminating</b>
+  UINT8   GdxcEnable;             ///< <CFL> Offset 226 GDXC  MOT enable
+  UINT8   GdxcIotSize;            ///< <CFL> Offset 227 IOT size in multiples of 8MEG
+  UINT8   GdxcMotSize;            ///< <CFL> Offset 228 MOT size in multiples of 8MEG
+  UINT8   RMTLoopCount;           ///< Offset 229 Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+  UINT16  FreqSaGvMid;            ///< Offset 230 SA GV: 0 is Auto/default, otherwise holds the frequency value expressed as an integer: <b>0=Default</b>, 1600, 1800, 1867, 2000, 2133, etc.
+
+  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  TrainTrace:1;                 ///< Offset 232 Bit 1: Trained state tracing debug. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  SafeMode:1;                   ///< Offset 232 Bit 2: Define if safe mode is enabled for MC/IO
+  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is enabled for Rank Margin Tool
+  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4: Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
+  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Force MRC training on warm boot : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
+
+  // TurnAround Timing
+  UINT8   tRd2RdSG;               ///< Offset 236 - Read-to-Read   Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2RdDG;               ///< Offset 237 - Read-to-Read   Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tRd2RdDR;               ///< Offset 238 - Read-to-Read   Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2RdDD;               ///< Offset 239 - Read-to-Read   Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2WrSG;               ///< Offset 240 - Read-to-Write  Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2WrDG;               ///< Offset 241 - Read-to-Write  Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tRd2WrDR;               ///< Offset 242 - Read-to-Write  Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tRd2WrDD;               ///< Offset 243 - Read-to-Write  Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2RdSG;               ///< Offset 244 - Write-to-Read  Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 86=Maximum.
+  UINT8   tWr2RdDG;               ///< Offset 245 - Write-to-Read  Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tWr2RdDR;               ///< Offset 246 - Write-to-Read  Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2RdDD;               ///< Offset 247 - Write-to-Read  Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2WrSG;               ///< Offset 248 - Write-to-Write Same Group      Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2WrDG;               ///< Offset 249 - Write-to-Write Different Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same Group and Different Group Timings must be the same for Non-DDR4 memory.
+  UINT8   tWr2WrDR;               ///< Offset 250 - Write-to-Write Different Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT8   tWr2WrDD;               ///< Offset 251 - Write-to-Write Different DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
+  UINT16  tRRD_L;                 ///< <CFL> Offset 252 - User defined DDR4 Memory Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tRRD_S;                 ///< <CFL> Offset 254 - User defined DDR4 Memory Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR_L;                 ///< <CFL> Offset 266 - User defined DDR4 Memory Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tWTR_S;                 ///< <CFL> Offset 268 - User defined DDR4 Memory Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+
+} MEMORY_CONFIGURATION;
+
+/// Memory Configuration
+/// The contents of this structure are not CRC'd by the MRC for option change detection.
+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 200  Function calls into the MRC.
+  SPD_DATA_BUFFER          *SpdData;            ///< Offset 236  Memory SPD data, will be used by the MRC when SPD SmBus address is zero.
+  SA_MEMORY_DQ_MAPPING     *DqByteMap;          ///< Offset 240  LPDDR3 DQ byte mapping to CMD/CTL/CLK, from the CPU side.
+  SA_MEMORY_DQS_MAPPING    *DqsMap;             ///< Offset 244  LPDDR3 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 260  Ask MRC to clear memory content: <b>FALSE=Do not Clear Memory</b>; TRUE=Clear Memory
+  UINT32                   MemTestOnWarmBoot:1; ///< Offset 260  Run Base Memory Test On WarmBoot:  0=Disabled, <b>1=Enabled</b>
+  UINT32                   ReservedBits5:30;
+  /**
+   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 264
+  UINT8   Reserved11[3];                        ///< Offset 265  Reserved
+} MEMORY_CONFIG_NO_CRC;
+#pragma pack(pop)
+
+#endif // _MEMORY_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
new file mode 100644
index 0000000000..9f01c172f2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
@@ -0,0 +1,61 @@
+/** @file
+  Memory DXE Policy definitions
+
+  Copyright (c) 2019 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
+
+/**
+  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.
+**/
+typedef struct {
+  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;
+  UINT8                 MrcTimeMeasure;   ///< Offset 38: MRC execution time measurement: <b>0=Disable</b>, 1=Enable
+  UINT8                 MrcFastBoot;      ///< Offset 39: Fast boot: 0=Disable, <b>1=Enable</b>
+} MEMORY_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _MEMORY_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h
new file mode 100644
index 0000000000..7a8894a5c0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  MISC DXE policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MISC_DXE_CONFIG_H_
+#define _MISC_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define MISC_DXE_CONFIG_REVISION 2
+
+/**
+  This data structure includes miscellaneous configuration variables such SA thermal device
+  control. The data elements should be initialized by a Platform Module.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2:</b>
+  - Added RmrrCsmeBaseAddress fields.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                    ///< Offset 0-27 Config Block Header
+  EFI_PHYSICAL_ADDRESS  *RmrrUsbBaseAddress;       ///< Offset 28 The field is used to describe the platform USB Reserved memory for Intel VT-d support. Platform code should provide this information for Intel VT-d DXE driver use
+  UINT32                EnableAbove4GBMmio : 1;    ///< Offset 29:0 Enable/disable above 4GB MMIO resource support: <b>0=Disable</b>, 1=Enable
+  UINT32                RsvdBits0          : 31;   ///< Offset 29:1 Reserved bits.
+  EFI_PHYSICAL_ADDRESS  *RmrrCsmeBaseAddress;      ///< The field is used to describe the CSME Reserved memory.
+} MISC_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _MISC_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h
new file mode 100644
index 0000000000..b623f14c15
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h
@@ -0,0 +1,51 @@
+/** @file
+  Policy definition for System Agent overclocking Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _OVERCLOCKING_PREMEM_CONFIG__H_
+#define _OVERCLOCKING_PREMEM_CONFIG__H_
+#pragma pack(push, 1)
+
+#define SA_OVERCLOCKING_CONFIG_REVISION 2
+
+/**
+ Defines the overclocking configuration parameters for System Agent.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add GT unslice support.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;    ///< Offset 0-27 Config Block Header
+  /**
+  Offset 28:0 :
+  Enable disable of SA overclocking mailbox commands.
+  If disabled, or if PcdSaOcEnable is disabled, all other policies in this config block are ignored.
+  <b>0=Disable</b>,
+  1=Enable
+  **/
+  UINT32  OcSupport             : 1;
+  UINT32  GtVoltageMode         : 1;    ///< Offset 28:1 :Specifies whether GT voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>, 1=Override
+  UINT32  RealtimeMemoryTiming  : 1;    ///< Offset 28:2 :Enable/Disable the message sent to the CPU to allow realtime memory timing changes after MRC_DONE. <b>0=Disable</b>, 1=Enable
+  UINT32  GtusVoltageMode       : 1;    ///< Offset 28:3 :Specifies whether GT unslice voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>, 1=Override
+  UINT32  RsvdBits0             : 28;   ///< Offset 28:4 - 31 :Reserved for future use
+  UINT8   GtMaxOcRatio;                 ///< Offset 32 Maximum GT turbo ratio override: 0=Minimal, 255=Maximum, <b>0=AUTO</b>
+  UINT8   Rsvd0;                        ///< Offset 33 Reserved for DWORD alignment
+  INT16   GtVoltageOffset;              ///< Offset 34 The voltage offset applied to GT slice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>, 1000=Maximum
+  UINT16  GtVoltageOverride;            ///< Offset 36 The GT voltage override which is applied to the entire range of GT frequencies <b>0=Default</b>
+  UINT16  GtExtraTurboVoltage;          ///< Offset 38 The adaptive voltage applied during turbo frequencies. Valid range from 0 to 2000mV: <b>0=Minimal</b>, 2000=Maximum
+  INT16   SaVoltageOffset;              ///< Offset 40 The voltage offset applied to the SA. Valid range from -1000mv to 1000mv: <b>0=Default</b>
+  INT16   GtusVoltageOffset;            ///< Offset 42 The voltage offset applied to GT unslice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>, 1000=Maximum
+  UINT16  GtusVoltageOverride;          ///< Offset 44 The GT unslice voltage override which is applied to the entire range of GT frequencies: <b>0=Default</b>
+  UINT16  GtusExtraTurboVoltage;        ///< Offset 46 The adaptive voltage applied during turbo frequencies. Valid range from 0 to 2000mV: <b>0=Default</b>
+  UINT8   GtusMaxOcRatio;               ///< Offset 48 Maximum GTus turbo ratio override: 0=Minimal, 6=Maximum, <b>0=AUTO</b>
+  UINT8   Rsvd1[3];                     ///< Offset 49-51 Reserved for DWORD alignment
+} OVERCLOCKING_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _OVERCLOCKING_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
new file mode 100644
index 0000000000..f0b9670f64
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
@@ -0,0 +1,135 @@
+/** @file
+  PCIE DXE policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_DXE_CONFIG_H_
+#define _PCIE_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define PCIE_DXE_CONFIG_REVISION 1
+
+///
+/// Device List for special ASPM override
+///
+typedef struct {
+  UINT16  VendorId;         ///< Offset 0 PCI Configuration space offset 0
+  UINT16  DeviceId;         ///< Offset 2 PCI Configuration space offset 2
+  UINT8   RevId;            ///< Offset 4 PCI Configuration space offset 8; 0xFF means all steppings
+  UINT8   RootApmcMask;     ///< Offset 5 Root ASPM override bit mask <b>0=No override</b>
+  UINT8   EndpointApmcMask; ///< Offset 6 Endpoint ASPM override bit mask <b>0=No override</b>
+  UINT8   Rsvd;             ///< Offset 7 Reserved
+} PCIE_ASPM_OVERRIDE_LIST;
+
+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
+} SA_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.
+**/
+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: This field is used to describe the PEG L0s advanced control
+  0=ASPM L0s disabled, 1=ASPM L0s enabled on RP, 2=ASPM L0s enabled on EP, <b>3=ASPM L0s enabled on both RP and EP</b>
+**/
+  UINT8                    PegAspmL0s[SA_PEG_MAX_FUN];
+/**
+  Offset 36: 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];
+/**
+  Offset 40: This field is used as a pointer to the ASPM device override table, default points to an\n
+  existing table mPcieAspmDevsOverride\n
+  Refer to DxeSaPolicyLib.c for the usage.
+  Note:  This exclusion list helps avoid potential system hangs.
+**/
+  PCIE_ASPM_OVERRIDE_LIST  *PcieAspmDevsOverride;
+/**
+  Offset 48: This field is used as a pointer to the LTR device override table, default points to an existing
+  table mPcieLtrDevsOverride.\n
+  Refer to DxeSaPolicyLib.c for the usage.
+**/
+  PCIE_LTR_DEV_INFO        *PcieLtrDevsOverride;
+  SA_PCIE_PWR_OPT          PegPwrOpt[SA_PEG_MAX_FUN];     ///< Offset 60: This field is used to describe the PCIe LTR/OBFF relevant settings
+  UINT8                    Rsvd1[3];                      /// Reserved for future use
+} PCIE_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h
new file mode 100644
index 0000000000..7899504865
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h
@@ -0,0 +1,60 @@
+/** @file
+  Policy definition for PCIe Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_PEI_CONFIG_H_
+#define _PCIE_PEI_CONFIG_H_
+
+#include <Library/GpioLib.h>
+#include <SaAccess.h>
+
+#pragma pack(push, 1)
+
+#define SA_PCIE_PEI_CONFIG_REVISION 1
+
+/**
+ PCI Express and DMI controller configuration - PostMem\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 Extended Sync Control
+  - <b>Disabled</b> (0x0)  : Disable DMI Extended Sync (Default)
+  - Enabled         (0x1)  : Enable DMI Extended Sync
+  **/
+  UINT32                 DmiExtSync                      :  1;
+  /**
+    Offset 28:1
+   <b>(Test)</b>DMI IOT Control
+  - <b>Disabled</b> (0x0)  : Disable DMI IOT (Default)
+  - Enabled         (0x1)  : Enable DMI IOT
+  **/
+  UINT32                 DmiIot                          :  1;
+  UINT32                 RsvdBits1                       :  30;       ///< Offset 28:2-31 :Reserved for future use.
+  UINT8                  DmiAspm;                                     ///< Offset 32 This field is used to describe the ASPM control for DMI: <b>3=PcieAspmL0sL1</b>, 2=PcieAspmL1, 1=PcieAspmL0s, 0=PcieAspmDisabled.
+  UINT8                  Rsvd1[3];                                    ///< Offset 33 to 35
+  UINT8                  PegDeEmphasis[SA_PEG_MAX_FUN];               ///< Offset 36 This field is used to describe the DeEmphasis control for PEG (-6 dB and -3.5 dB are the options)SA_PEG_MAX_FUN = 3 for CFL and SA_PEG_MAX_FUN = 4 for CNL, offsets are adjusted accordingly
+  UINT8                  PegMaxPayload[SA_PEG_MAX_FUN];               ///< <b>(Test)</b> Offset 39/40 This field is used to describe the PEG Max Pay Load Size (0xFF: Auto, 0:128B, 1:256B)
+  /**
+   PCIe Slot Power Capabilities. SlotPowerLimitValue in combination with SlotPowerLimitScale specifies the upper limit on power supplied by slot.
+  **/
+  UINT8                  PegSlotPowerLimitValue[SA_PEG_MAX_FUN];      ///< Offset 42/44 8 bit value
+  UINT8                  PegSlotPowerLimitScale[SA_PEG_MAX_FUN];      ///< Offset 45/48 2 bit value: <b>00 = 1.0x</b>, 01 = 0.1x, 10 = 0.01x and 11 = 0.001x
+  /**
+   Offset 48/52
+   PCIe Physical Slot Number (13 bit value). Indicates the physical slot number attached to the port.
+  **/
+  UINT16                 PegPhysicalSlotNumber[SA_PEG_MAX_FUN];
+  UINT8                  Rsvd2[2];
+} PCIE_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h
new file mode 100644
index 0000000000..a53bf3c7bd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h
@@ -0,0 +1,354 @@
+/** @file
+  Policy definition for PCIe Config Block
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_PEI_PREMEM_CONFIG_H_
+#define _PCIE_PEI_PREMEM_CONFIG_H_
+
+#include <Library/GpioLib.h>
+#include <SaAccess.h>
+
+#pragma pack(push, 1)
+
+#define SA_PCIE_PEI_PREMEM_CONFIG_REVISION 3
+
+///
+/// SA GPIO Data Structure
+///
+typedef struct {
+  GPIO_PAD      GpioPad;        ///< Offset 0: GPIO Pad
+  UINT8         Value;          ///< Offset 4: GPIO Value
+  UINT8         Rsvd0[3];       ///< Offset 5: Reserved for 4 bytes alignment
+  UINT32        Active  :1;     ///< Offset 8: 0=Active Low; 1=Active High
+  UINT32        RsvdBits0:31;
+} SA_GPIO_INFO_PCIE;
+
+///
+/// SA Board PEG GPIO Info
+///
+typedef struct {
+  SA_GPIO_INFO_PCIE  SaPeg0ResetGpio;    ///< Offset 0:  PEG0 PERST# GPIO assigned, must be a PCH GPIO pin
+  SA_GPIO_INFO_PCIE  SaPeg3ResetGpio;    ///< Offset 12: PEG3 PERST# GPIO assigned, must be a PCH GPIO pin
+  BOOLEAN            GpioSupport;        ///< Offset 24: 1=Supported; 0=Not Supported
+  UINT8              Rsvd0[3];           ///< Offset 25: Reserved for 4 bytes alignment
+} PEG_GPIO_DATA;
+
+
+/**
+ 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.
+  <b>Revision 2</b>:
+  - Change PegGen3RxCtleOverride of PCIE_PEI_PREMEM_CONFIG from one bit to UINT8
+  - Change DmiGen3RxCtlePeaking default to 0
+  <b>Revision 3</b>:
+  - Added PEG IMR support
+  - Added UINT8 PegImrEnable
+  - Added UINT16 PegImrSize
+  - Added UINT8 ImrRpSelection
+**/
+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;
+
+  /**
+   Offset 28:8 to 28:15 :
+   <b>(Test)</b> PEG Enable Control
+  - Disabled    (0x0)  : Disable PEG Port
+  - Enabled     (0x1)  : Enable PEG Port (If Silicon SKU permits it)
+  - <b>Auto</b> (0x2)  : If an endpoint is present, enable the PEG Port, Disable otherwise (Default)
+  **/
+  UINT32                 Peg0Enable                      :  2;        ///< Enable/Disable PEG 0:1:0 Root Port
+  UINT32                 Peg1Enable                      :  2;        ///< <b>(Test)</b> Enable/Disable PEG 0:1:1 Root Port
+  UINT32                 Peg2Enable                      :  2;        ///< <b>(Test)</b> Enable/Disable PEG 0:1:2 Root Port
+  UINT32                 Peg3Enable                      :  2;        ///< <b>(Test)</b> Enable/Disable PEG 0:6:0 Root Port.
+
+  /**
+   Offset 28:16 :
+   <b>(Test)</b> PCIe 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                 Peg0MaxLinkSpeed                :  2;        ///< PCIe Link Speed Control for PEG 0:1:0 Root Port.
+  UINT32                 Peg1MaxLinkSpeed                :  2;        ///< <b>(Test)</b> PCIe Link Speed Control for PEG 0:1:1 Root Port.
+  UINT32                 Peg2MaxLinkSpeed                :  2;        ///< <b>(Test)</b> PCIe Link Speed Control for PEG 0:1:2 Root Port.
+  UINT32                 Peg3MaxLinkSpeed                :  2;        ///< <b>(Test)</b> PCIe Link Speed Control for PEG 0:6:0 Root Port.
+  UINT32                 RsvdBits0                       :  8;        ///< Offset 28:24 :Reserved for future use
+
+  /**
+   Offset 32:0 :
+   <b>(Test)</b> PCIe Link Width Control
+  - <b>Auto</b> (0x0)  : Maximum possible Link width (Default)
+  - X1          (0x1)  : Limit Link to X1 Width
+  - X2          (0x2)  : Limit Link to X2 Width
+  - X4          (0x3)  : Limit Link to X4 Width
+  - X8          (0x4)  : Limit Link to X8 Width
+  **/
+  UINT32                 Peg0MaxLinkWidth                :  3;        ///< PCIe Link Width Control for PEG 0:1:0 Root Port.
+  UINT32                 Peg1MaxLinkWidth                :  3;        ///< <b>(Test)</b> PCIe Link Width Control for PEG 0:1:1 Root Port.
+  UINT32                 Peg2MaxLinkWidth                :  3;        ///< <b>(Test)</b> PCIe Link Width Control for PEG 0:1:2 Root Port.
+  UINT32                 Peg3MaxLinkWidth                :  3;        ///< <b>(Test)</b> PCIe Link Width Control for PEG 0:6:0 Root Port.
+  /**
+    Offset 32:12 to 32:15 :
+    Power down unused lanes on the PEG Root Port.
+  - Disabled     (0x0) : No power saving.
+  - <b>Auto</b>  (0x1) : Bios will power down unused lanes based on the max possible link width
+  **/
+  UINT32                 Peg0PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:1:0 Root Port.
+  UINT32                 Peg1PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:1:1 Root Port.
+  UINT32                 Peg2PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:1:2 Root Port.
+  UINT32                 Peg3PowerDownUnusedLanes        :  1;        ///< Power down unused lanes on the PEG 0:6:0 Root Port.
+
+  /**
+   Offset 32:16 to 32:23 :
+   <b>(Test)</b> PCIe 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                 Peg0Gen3EqPh2Enable             :  2;        ///< Phase2 EQ enable on the PEG 0:1:0 Root Port.
+  UINT32                 Peg1Gen3EqPh2Enable             :  2;        ///< <b>(Test)</b> Phase2 EQ enable on the PEG 0:1:1 Root Port.
+  UINT32                 Peg2Gen3EqPh2Enable             :  2;        ///< <b>(Test)</b> Phase2 EQ enable on the PEG 0:1:2 Root Port.
+  UINT32                 Peg3Gen3EqPh2Enable             :  2;        ///< <b>(Test)</b> Phase2 EQ enable on the PEG 0:6:0 Root Port.
+  UINT32                 RsvdBits1                       :  8;        ///< Offset 32:24 :Reserved for future use
+  /**
+   Offset 36:0 to 36:11 :
+   <b>(Test)</b> Select the method for performing Phase3 of Gen3 Equalization.
+  - <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 PegGen3EndPointPreset array for Phase1 AND Phase3 (Instead of just Phase1)
+  - Disabled    (0x4)  : Bypass Equalization Phase 3
+  **/
+  UINT32                 Peg0Gen3EqPh3Method             :  3;        ///< Phase3 EQ method on the PEG 0:1:0 Root Port.
+  UINT32                 Peg1Gen3EqPh3Method             :  3;        ///< <b>(Test)</b> Phase3 EQ method on the PEG 0:1:1 Root Port.
+  UINT32                 Peg2Gen3EqPh3Method             :  3;        ///< <b>(Test)</b> Phase3 EQ method on the PEG 0:1:2 Root Port.
+  UINT32                 Peg3Gen3EqPh3Method             :  3;        ///< <b>(Test)</b> Phase3 EQ method on the PEG 0:6:0 Root Port.
+  /**
+   Offset 36:12 :
+   <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;
+  /**
+   Offset 36:13 :
+   <b>(Test)</b> Always Attempt Gen3 Software Equalization
+
+   When enabled, Gen3 Software Equalization will be executed every boot.  When disabled, it will be only executed if the CPU
+   or EP is changed, otherwise it is skipped and the previous EQ value will be re-used.
+
+   This setting will only have an effect if Software Equalization is enabled and OEM Platform Code implements
+   save/restore of the PegDataPtr data (see below).  If PegDataPtr is not saved/restored RC forces this to be enabled.
+
+  - <b>Disabled</b> (0x0)  : Reuse EQ settings saved/restored from NVRAM whenever possible (Default)
+  - Enabled         (0x1)  : Re-test and generate new EQ values every boot, not recommended
+  **/
+  UINT32                 Gen3SwEqAlwaysAttempt           :  1;
+  /**
+   Offset 36:14 to 36:16 :
+   <b>(Test)</b> Select number of TxEq presets to test in the PCIe/DMI Software Equalization Algorithm
+  - P7,P3,P5,P8 (0x0)  : Test Presets 7, 3, 5, and 8
+  - P0-P9       (0x1)  : Test Presets 0-9
+  - <b>Auto</b> (0x2)  : Use the current default method (Default)
+  Auto will test Presets 7, 3, 5, and 8.  It is possible for this default to change over time;
+  using "Auto" will ensure Reference Code always uses the latest default settings.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  **/
+  UINT32                 Gen3SwEqNumberOfPresets         :  3;
+  /**
+   Offset 36:17 to 36:18:
+   <b>(Test)</b> Offset 36 Enable use of the Voltage Offset and Centering Test in the PCIe Software Equalization Algorithm
+  - Disabled     (0x0) : Disable VOC Test
+  - Enabled      (0x1) : Enable VOC Test
+  - <b>Auto</b>  (0x2) : Use the current default (Default)
+  **/
+  UINT32                 Gen3SwEqEnableVocTest           :  2;
+  /**
+    Offset 36:19 :
+    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;
+  /**
+   Offset 36:20 :
+   <b>(Test)</b> PCIe Rx Compliance Testing Mode
+  - <b>Disabled</b> (0x0) : Normal Operation             - Disable PCIe Rx Compliance testing (Default)
+  - Enabled         (0x1) : PCIe Rx Compliance Test Mode - PEG controller is in Rx Compliance Testing Mode; it should only be set when doing PCIe compliance testing
+  **/
+  UINT32                 PegRxCemTestingMode             :  1;
+
+  /**
+    Offset 36:21 to 36:24 :
+    <b>(Test)</b> PCIe Rx Compliance Loopback Lane
+
+    When PegRxCemTestingMode is Enabled, the specificied Lane (0 - 15) will be
+    used for RxCEMLoopback.
+
+    Default is Lane 0.
+  **/
+  UINT32                 PegRxCemLoopbackLane            :  4;
+  /**
+   Offset 36:25 to 36:28 :
+   <b>(Test)</b> Generate PCIe BDAT Margin Table. Set this policy to enable the generation and addition of PCIe margin data to the BDAT table.
+  - <b>Disabled</b> (0x0) : Normal Operation          - Disable PCIe BDAT margin data generation (Default)
+  - PortData        (0x1) : Port Data                 - Generate PCIe BDAT margin data
+  **/
+  UINT32                 PegGenerateBdatMarginTable      :  4;
+   /**
+   Offset 36:29 :
+   <b>(Test)</b> PCIe Non-Protocol Awareness for Rx Compliance Testing
+  - <b>Disabled</b> (0x0) : Normal Operation                - Disable non-protocol awareness (Default)
+  - Enabled         (0x1) : Non-Protocol Awareness Enabled  - Enable non-protocol awareness for compliance testing
+  **/
+  UINT32                 PegRxCemNonProtocolAwareness    :  1;
+   /**
+   Offset 36:30 :
+   <b>(Test)</b> PCIe Disable Spread Spectrum Clocking. This feature should be TRUE only for compliance testing
+  - <b>False</b>          (0x0) : Normal Operation                 - SSC enabled  (Default)
+  - True                  (0x1) : Disable SSC                      - Disable SSC for compliance testing
+  **/
+  UINT32                 PegDisableSpreadSpectrumClocking :  1;
+
+  UINT32                 RsvdBits2                        :  1;
+
+  UINT8                  DmiGen3RootPortPreset[SA_DMI_MAX_LANE];      ///< Offset 40 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 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 48 Hint value per lane for the DMI Gen3 End Point. Range: 0-6, 2 is default for each lane
+  /**
+   Offset 52 :
+   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 0.
+  **/
+
+  UINT8                  DmiGen3RxCtlePeaking[SA_DMI_MAX_BUNDLE];
+
+  UINT8                  PegGen3RootPortPreset[SA_PEG_MAX_LANE];      ///< Offset 54 <b>(Test)</b> Used for programming PEG Gen3 preset values per lane. Range: 0-9, 8 is default for each lane
+  UINT8                  PegGen3EndPointPreset[SA_PEG_MAX_LANE];      ///< Offset 70 <b>(Test)</b> Used for programming PEG Gen3 preset values per lane. Range: 0-9, 7 is default for each lane
+  UINT8                  PegGen3EndPointHint[SA_PEG_MAX_LANE];        ///< Offset 86 <b>(Test)</b> Hint value per lane for the PEG Gen3 End Point. Range: 0-6, 2 is default for each lane
+  /**
+   Offset 102:
+   PCIe 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                  PegGen3RxCtlePeaking[SA_PEG_MAX_BUNDLE];
+  /**
+  Offset 110:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 1000.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  @note An attack on this policy could result in an apparent hang,
+    but the system will eventually boot.  This variable should be protected.
+  **/
+  UINT16                 Gen3SwEqJitterDwellTime;
+  /**
+   Offset 112:
+   This is a memory data pointer for saved preset search results. The reference code will store
+   the Gen3 Preset Search results in the SaPegHob. In order to skip the Gen3
+   preset search on boots where the PEG card configuration has not changed since the previous boot,
+   platform code can save the contents of the SaPegHob in DXE (When it present and for size reported by Header.HobLength)
+   and provide a pointer to a restored copy of that data. Default value is NULL, which results in a full
+   preset search every boot.
+
+   @note An attack on this policy could prevent the PCIe display from working until a boot when
+   PegDataPtr is NULL or Gen3SwEqAlwaysAttempt is enabled.  The variable used to save the
+   preset search results should be protected in a way that it can only be modified by the
+   platform manufacturer.
+  **/
+  VOID                   *PegDataPtr;
+  /**
+  Offset 116:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 1.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  **/
+  UINT16                 Gen3SwEqJitterErrorTarget;
+
+  /**
+  Offset 118:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 10000.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  @note An attack on this policy could result in an apparent hang,
+    but the system will eventually boot.  This variable should be protected.
+  **/
+  UINT16                 Gen3SwEqVocDwellTime;
+
+  /**
+  Offset 120:
+  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535, default is 2.
+  @warning Do not change from the default.  Hard to detect issues are likely.
+  **/
+  UINT16                 Gen3SwEqVocErrorTarget;
+  /**
+  Offset 122:
+    PCIe Hot Plug Enable/Disable. It has 2 policies.
+  - Disabled (0x0)     : No hotplug.
+  - Enabled (0x1)      : Bios assist hotplug.
+  **/
+  UINT8                  PegRootPortHPE[SA_PEG_MAX_FUN];
+  UINT8                  DmiDeEmphasis;                               ///< Offset 125 This field is used to describe the DeEmphasis control for DMI (-6 dB and -3.5 dB are the options)
+  UINT8                  Rsvd0[2];                                    ///< Offset 126
+  /**
+   Offset 128:
+   This contains the PCIe PERST# GPIO information.  This structure is required
+   for PCIe Gen3 operation. The reference code will use the information in this structure in
+   order to reset PCIe Gen3 devices during equalization, if necessary.  Refer to the Platform
+   Developer's Guide (PDG) for additional details.
+  **/
+  PEG_GPIO_DATA          PegGpioData;
+
+   /**
+   Offset 156
+   <b>(Test)</b> PCIe Override RxCTLE. This feature should only be true to disable RxCTLE adaptive behavior for compliance testing
+  - <b>False</b>          (0x0) : Normal Operation                 - RxCTLE adaptive behavior enabled  (Default)
+  - True                  (0x1) : Override RxCTLE                  - Disable RxCTLE adaptive behavior to keep the configured RxCTLE peak values unmodified
+  From CFL onwards, modularity is introduced to this setup option so that the RxCTLE adaptive behavior could be controlled at the controller level.
+  Making this variable a UINT8 to accomodate the values of all controllers as bit definition
+  **/
+  UINT8                 PegGen3RxCtleOverride;
+  UINT8                 Reserved1;
+  UINT16                Reserved2;
+
+} PCIE_PEI_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_PEI_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
new file mode 100644
index 0000000000..12648b836b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
@@ -0,0 +1,61 @@
+/** @file
+  Policy details for miscellaneous configuration in System Agent
+
+  Copyright (c) 2019 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)
+
+#ifndef SA_MC_MAX_SOCKETS
+#define SA_MC_MAX_SOCKETS 4
+#endif
+
+#define SA_MISC_PEI_CONFIG_REVISION 1
+
+///
+/// Subsystem Vendor ID / Subsystem ID
+///
+typedef struct _SA_DEFAULT_SVID_SID{
+  UINT16         SubSystemVendorId;
+  UINT16         SubSystemId;
+} SA_DEFAULT_SVID_SID;
+
+/**
+  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
+  /**
+  Offset 28:0
+  This policy is used to control enable or disable System Agent Thermal device (0,4,0).
+  The default value is <b>1: TRUE</b> for WHL, and <b>0: FALSE</b> for all other CPU's
+  **/
+  UINT32  Device4Enable:1;
+  /**
+  Offset 28:1
+  <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.
+  **/
+  UINT32  ChapDeviceEnable:1;
+  /**
+  Offset 28:2
+  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  CridEnable:1;
+  UINT32  SkipPamLock:1;                     ///< Offset 28:3 :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.
+  UINT32  EdramTestMode:2;                   ///< Offset 28:4 :EDRAM Test Mode. For EDRAM stepping - 0- EDRAM SW Disable, 1- EDRAM SW Enable, <b> 2- EDRAM HW Mode</b>
+  UINT32  RsvdBits0          :26;            ///< Offset 28:7 :Reserved for future use
+} SA_MISC_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _SA_MISC_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
new file mode 100644
index 0000000000..2c831404ef
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
@@ -0,0 +1,103 @@
+/** @file
+  Policy details for miscellaneous configuration in System Agent
+
+  Copyright (c) 2019 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 SA_MC_MAX_SOCKETS
+#define SA_MC_MAX_SOCKETS 4
+#endif
+
+#define SA_MISC_PEI_PREMEM_CONFIG_REVISION 3
+
+/**
+  This configuration block is to configure SA Miscellaneous variables during PEI Pre-Mem phase like programming
+  different System Agent BARs, TsegSize, IedSize, MmioSize required etc.
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - add BdatTestType, default is RMT
+  <b>Revision 3</b>:
+  - Remove SgSubSystemId.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+  UINT8   SpdAddressTable[SA_MC_MAX_SOCKETS];///< Offset 28 Memory DIMMs' SPD address for reading SPD data. <b>example: SpdAddressTable[0]=0xA2(C0D0), SpdAddressTable[1]=0xA0(C0D1), SpdAddressTable[2]=0xA2(C1D0), SpdAddressTable[3]=0xA0(C1D1)</b>
+  VOID    *S3DataPtr;                        ///< Offset 32 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  MchBar;                            ///< Offset 36 Address of System Agent MCHBAR: <b>0xFED10000</b>
+  UINT32  DmiBar;                            ///< Offset 40 Address of System Agent DMIBAR: <b>0xFED18000</b>
+  UINT32  EpBar;                             ///< Offset 44 Address of System Agent EPBAR: <b>0xFED19000</b>
+  UINT32  SmbusBar;                          ///< Offset 48 Address of System Agent SMBUS BAR: <b>0xEFA0</b>
+  UINT32  GdxcBar;                           ///< Offset 52 Address of System Agent GDXCBAR: <b>0xFED84000</b>
+  /**
+    Offset 56 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;
+  UINT32  EdramBar;                          ///< Offset 60 Address of System Agent EDRAMBAR: <b>0xFED80000</b>
+  /**
+    Offset 64
+    <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>
+  **/
+  UINT32  IedSize;
+  UINT8   UserBd;                            ///< Offset 68 <b>0=Mobile/Mobile Halo</b>, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile Halo, 7=UP Server
+  UINT8   SgMode;                            ///< Offset 69 SgMode: <b>0=Disabled</b>, 1=SG Muxed, 2=SG Muxless, 3=PEG
+  UINT16  SgDelayAfterPwrEn;                 ///< Offset 70 Dgpu Delay after Power enable using Setup option: 0=Minimal, 1000=Maximum, <b>300=300 microseconds</b>
+  UINT16  SgDelayAfterHoldReset;             ///< Offset 72 Dgpu Delay after Hold Reset using Setup option: 0=Minimal, 1000=Maximum, <b>100=100 microseconds</b>
+  UINT32  SkipExtGfxScan:1;                  ///< <b>(Test)</b> OFfset 74: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 74:1 :This field enables the generation of the BIOS DATA ACPI Tables: <b>0=FALSE</b>, 1=TRUE.
+  UINT32  TxtImplemented:1;                  ///< OFfset 74: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 74: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.  If the primary graphics device only implements legacy VBIOS, then the
+   LegacyOnlyVgaOpRomDetected field in the SA_DATA_HOB will be set to 1.
+
+   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 74:4 :Reserved for future use
+  UINT8   LockPTMregs;                       ///< <b>(Test)</b> Offset 78 Lock PCU Thermal Management registers: 0=FALSE, <b>1=TRUE</b>
+  UINT8   BdatTestType;                      ///< Offset 79 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   Rsvd1[4];                          ///< Offset 80 Reserved for future use
+  /**
+    Offset 84 :
+    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.
+  **/
+  UINT16  MmioSize;
+  INT16   MmioSizeAdjustment;                ///< Offset 86 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>
+  UINT64  AcpiReservedMemoryBase;            ///< Offset 88 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 96 Total system memory length from previous boot, this is required for S3 resume. Originally it is retrieved from AcpiVariableCompatibility variable.
+  UINT32  AcpiReservedMemorySize;            ///< Offset 104 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 108 Temporary address to MMIO map OpROMs during VGA scanning.  Used for ScanExtGfxForLegacyOpRom feature.  MUST BE 16MB ALIGNED!
+  UINT32  OpRomScanTempMmioLimit;            ///< <b>(Test)</b> Offset 112 Limit address for OpROM MMIO range.  Used for ScanExtGfxForLegacyOpRom feature. (OpROMScanTempMmioLimit - OpRomScanTempMmioBar) MUST BE >= 16MB!
+
+  // 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/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h
new file mode 100644
index 0000000000..cc6179a61c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h
@@ -0,0 +1,63 @@
+/** @file
+  Switchable Graphics policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SWITCHABLE_GRAPHICS_CONFIG_H_
+#define _SWITCHABLE_GRAPHICS_CONFIG_H_
+
+#define SWITCHABLE_GRAPHICS_CONFIG_REVISION 1
+
+#define GP_ENABLE   1
+#define GP_DISABLE  0
+
+#pragma pack(push, 1)
+///
+/// GPIO Support
+///
+typedef enum {
+  NotSupported = 0,
+  PchGpio,
+  I2CGpio,
+} GPIO_SUPPORT;
+
+///
+/// SA 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
+} SA_GPIO_INFO;
+
+/**
+ SA PCIE RTD3 GPIO Data Structure
+**/
+typedef struct {
+  SA_GPIO_INFO  HoldRst;      ///< Offset 0 This field contain PCIe HLD RESET GPIO value and level information
+  SA_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
+} SA_PCIE_RTD3_GPIO;
+
+/**
+  This Configuration block configures SA PCI Express 0/1/2 RTD3 GPIOs & Root Port.
+  Swithable Gfx/Hybrid Gfx uses the same GPIOs & Root port as PCI Express 0/1/2 RTD3.
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER Header;             ///< Offset 0-27 Config Block Header
+  SA_PCIE_RTD3_GPIO   SaRtd3Pcie0Gpio;    ///< Offset 28 RTD3 GPIOs used for PCIe0
+  SA_PCIE_RTD3_GPIO   SaRtd3Pcie1Gpio;    ///< Offset 52 RTD3 GPIOs used for PCIe1
+  SA_PCIE_RTD3_GPIO   SaRtd3Pcie2Gpio;    ///< Offset 76 RTD3 GPIOs used for PCIe2
+  UINT8               RootPortIndex;      ///< Offset 124 Root Port Index number used for SG
+  UINT8               Rsvd0[3];           ///< Offset 125 Reserved for DWORD Alignment
+} SWITCHABLE_GRAPHICS_CONFIG;
+#pragma pack(pop)
+#endif // _SWITCHABLE_GRAPHICS_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h
new file mode 100644
index 0000000000..690ad8630a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h
@@ -0,0 +1,39 @@
+/** @file
+  VBIOS DXE policy definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VBIOS_DXE_CONFIG_H_
+#define _VBIOS_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define VBIOS_DXE_CONFIG_REVISION 1
+
+/**
+  This data structure includes Switchable Graphics VBIOS configuration.
+  If Switchable Graphics/Hybrid Gfaphics feature is not supported, all the policies in this configuration block can 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
+  UINT8                 LoadVbios    : 1;    ///< Offset 28:0 :This field is used to describe if the dGPU VBIOS needs to be loaded: <b>0=Not load</b>, 1=Load
+  UINT8                 ExecuteVbios : 1;    ///< Offset 28:1 :This field is used to describe if the dGPU VBIOS need to be executed: <b>0=Not execute</b>, 1=Execute
+/**
+  Offset 28:2 :
+  This field is used to identify the source location of dGPU VBIOS\n
+  <b>1 = secondary display device VBIOS Source is PCI Card</b>\n
+  0 = secondary display device VBIOS Source is FW Volume\n
+**/
+  UINT8                 VbiosSource  : 1;
+  UINT8                 RsvdBits0    : 5;    ///< Offset 28:3 Reserved for future use
+  UINT8                 Rsvd[3];             ///< Offset 29 : Reserved for DWORD alignment
+} VBIOS_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _VBIOS_DXE_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h
new file mode 100644
index 0000000000..adde1f836b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h
@@ -0,0 +1,42 @@
+/** @file
+  VT-d policy definitions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VTD_CONFIG_H_
+#define _VTD_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define VTD_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.
+  <b>Revision 2</b>:
+  - Add DMA_CONTROL_GUARANTEE bit in the DMAR table
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;                      ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28:0 :
+    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.
+  **/
+  UINT32        VtdDisable               : 1;
+  UINT32        X2ApicOptOut             : 1;       ///< Offset 28:1 :This field is used to enable the X2APIC_OPT_OUT bit in the DMAR table. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT32        DmaControlGuarantee      : 1;       ///< Offset 28:2 :This field is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT32        RsvdBits0                : 29;      ///< Offset 28:3 :Reserved bits for future use
+  UINT32        BaseAddress[SA_VTD_ENGINE_NUMBER];  ///< Offset 32: This field is used to describe the base addresses for VT-d function: <b>BaseAddress[0]=0xFED90000, BaseAddress[1]=0xFED92000, BaseAddress[2]=0xFED91000 </b>
+} VTD_CONFIG;
+#pragma pack(pop)
+
+#endif   //  _VTD_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h
new file mode 100644
index 0000000000..a1d88cb5a2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h
@@ -0,0 +1,77 @@
+/** @file
+  This code defines ACPI DMA Remapping table related definitions.
+  See the System Agent BIOS specification for definition of the table.
+
+  Copyright (c) 2019 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>
+
+#pragma pack(1)
+///
+/// DMAR table signature
+///
+#define EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE   0x52414D44  ///< "DMAR"
+#define EFI_ACPI_DMAR_TABLE_REVISION        1
+#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];    // CSME
+} EFI_ACPI_RMRR_CSME_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_USB_STRUC       RmrrUsb;
+  EFI_ACPI_RMRR_IGD_STRUC       RmrrIgd;
+  EFI_ACPI_RMRR_CSME_STRUC      RmrrCsme;
+} EFI_ACPI_DMAR_TABLE;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h
new file mode 100644
index 0000000000..663b0f2202
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h
@@ -0,0 +1,60 @@
+/** @file
+  Prototype of the DxeSaPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_LIB_H_
+#define _DXE_SA_POLICY_LIB_H_
+
+#include <Protocol/SaPolicy.h>
+
+/**
+  This function prints the DXE phase policy.
+
+  @param[in] SaPolicy    - SA DXE Policy protocol
+**/
+VOID
+SaPrintPolicyProtocol (
+  IN  SA_POLICY_PROTOCOL         *SaPolicy
+  )
+;
+
+/**
+  CreateSaDxeConfigBlocks generates the config blocksg 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 Policy 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
+);
+
+/**
+  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
+  )
+;
+
+#endif // _DXE_SA_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h
new file mode 100644
index 0000000000..c29d67a305
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h
@@ -0,0 +1,87 @@
+/** @file
+  Prototype of the PeiSaPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_LIB_H_
+#define _PEI_SA_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI instance
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  );
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi              The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  );
+
+/**
+  Get SA config block table total size.
+
+  @retval     Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get SA config block table total size.
+
+  @retval      Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSizePreMem (
+  VOID
+  );
+
+/**
+  SaAddConfigBlocksPreMem add all SA config blocks.
+
+  @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
+SaAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  SaAddConfigBlocks add all SA config blocks.
+
+  @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
+SaAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
new file mode 100644
index 0000000000..a1289abe81
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
@@ -0,0 +1,88 @@
+/** @file
+  Header file for SaPlatformLib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PLATFORM_LIB_H_
+#define _SA_PLATFORM_LIB_H_
+
+#include <SaAccess.h>
+#include <CpuAccess.h>
+
+/**
+  Determine if PCH Link is DMI/OPI
+
+  @param[in] CpuModel             CPU model
+
+  @retval TRUE                    DMI
+  @retval FALSE                   OPI
+**/
+BOOLEAN
+IsPchLinkDmi (
+  IN CPU_FAMILY  CpuModel
+  );
+
+/**
+  Returns the number of DMI lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiLanes (
+  );
+
+
+/**
+  Returns the number of DMI bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiBundles (
+  );
+
+
+/**
+  Returns the function numbers for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegFuncs (
+  );
+
+
+/**
+  Returns the number of DMI lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegLanes (
+  );
+
+
+/**
+  Returns the number of DMI bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegBundles (
+  );
+
+/**
+  Checks if PEG port is present
+
+  @retval TRUE     PEG is presented
+  @retval FALSE    PEG is not presented
+**/
+BOOLEAN
+IsPegPresent (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
new file mode 100644
index 0000000000..da285bbcba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
@@ -0,0 +1,259 @@
+/** @file
+  This file contains definitions required for creation of
+  Memory S3 Save data, Memory Info data and Memory Platform
+  data hobs.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MEM_INFO_HOB_H_
+#define _MEM_INFO_HOB_H_
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+
+#pragma pack (push, 1)
+
+extern EFI_GUID gSiMemoryS3DataGuid;
+extern EFI_GUID gSiMemoryInfoDataGuid;
+extern EFI_GUID gSiMemoryPlatformDataGuid;
+
+#define MAX_NODE        1
+#define MAX_CH          2
+#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 MrcChannelSts enum in MRC
+//
+#ifndef CHANNEL_NOT_PRESENT
+#define CHANNEL_NOT_PRESENT     0  // There is no channel present on the controller.
+#endif
+#ifndef CHANNEL_DISABLED
+#define CHANNEL_DISABLED     1  // There is a channel present but it is disabled.
+#endif
+#ifndef CHANNEL_PRESENT
+#define CHANNEL_PRESENT     2  // There is a channel present and it is enabled.
+#endif
+
+//
+// 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 bmCold
+#define bmCold 0            // Cold boot
+#endif
+#ifndef bmWarm
+#define bmWarm 1            // Warm boot
+#endif
+#ifndef bmS3
+#define bmS3   2            // S3 resume
+#endif
+#ifndef bmFast
+#define bmFast 3            // Fast boot
+#endif
+
+//
+// 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_UNKNOWN
+#define MRC_DDR_TYPE_UNKNOWN  3
+#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;
+
+typedef struct {
+  UINT8 SG;         ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;         ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;         ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;         ///< Number of tCK cycles between transactions when switching between DIMMs.
+} MRC_TA_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.
+} 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.
+  MRC_TA_TIMING    tRd2Rd;                  ///< Read-to-Read   Turn Around Timings
+  MRC_TA_TIMING    tRd2Wr;                  ///< Read-to-Write  Turn Around Timings
+  MRC_TA_TIMING    tWr2Rd;                  ///< Write-to-Read  Turn Around Timings
+  MRC_TA_TIMING    tWr2Wr;                  ///< Write-to-Write Turn Around Timings
+} 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.
+  MRC_TA_TIMING    tRd2Rd;                   ///< Deprecated and moved to CHANNEL_INFO. Read-to-Read   Turn Around Timings
+  MRC_TA_TIMING    tRd2Wr;                   ///< Deprecated and moved to CHANNEL_INFO. Read-to-Write  Turn Around Timings
+  MRC_TA_TIMING    tWr2Rd;                   ///< Deprecated and moved to CHANNEL_INFO. Write-to-Read  Turn Around Timings
+  MRC_TA_TIMING    tWr2Wr;                   ///< Deprecated and moved to CHANNEL_INFO. Write-to-Write Turn Around Timings
+} CONTROLLER_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;
+  UINT32            PrmrrBase;
+  UINT32            GttBase;
+  UINT32            MmioSize;
+  UINT32            PciEBaseAddress;
+  UINT32            GdxcIotBase;
+  UINT32            GdxcIotSize;
+  UINT32            GdxcMotBase;
+  UINT32            GdxcMotSize;
+} 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/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h
new file mode 100644
index 0000000000..ff7cfa838f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h
@@ -0,0 +1,15 @@
+/** @file
+  Graphics header file
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_INIT_H_
+#define _GRAPHICS_INIT_H_
+
+#include <SaPolicyCommon.h>
+#include <Ppi/SiPolicy.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h
new file mode 100644
index 0000000000..497c860824
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h
@@ -0,0 +1,33 @@
+/** @file
+  This code supports a private implementation of the Legacy Region protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _LEGACY_REGION_H_
+#define _LEGACY_REGION_H_
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/LegacyRegion2.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/Cpu.h>
+#include <IndustryStandard/Pci22.h>
+#include <SaAccess.h>
+
+/**
+  Install Driver to produce Legacy Region protocol.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS - Legacy Region protocol installed
+  @retval Other       - No protocol installed, unload driver.
+**/
+EFI_STATUS
+LegacyRegionInstall (
+  IN EFI_HANDLE           ImageHandle
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h
new file mode 100644
index 0000000000..8bf46528ab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for North TraceHub Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _NORTH_TRACEHUB_LIB_H_
+#define _NORTH_TRACEHUB_LIB_H_
+
+#include <SaPolicyCommon.h>
+#include <SaAccess.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/MtrrLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h
new file mode 100644
index 0000000000..19dd634a35
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h
@@ -0,0 +1,70 @@
+/** @file
+  Defines and prototypes for the System Agent PCIe library module
+  This library is expected to share between DXE and SMM drivers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PCIE_LIB_H_
+#define _SA_PCIE_LIB_H_
+
+#include <Library/S3BootScriptLib.h>
+#include <Protocol/SaPolicy.h>
+
+#define MAX_SUPPORTED_ROOT_BRIDGE_NUMBER  3
+#define MAX_SUPPORTED_DEVICE_NUMBER       192
+
+/**
+  Enumerate all end point devices connected to root bridge ports and record their MMIO base address
+
+  @exception EFI_UNSUPPORTED      PCIe capability structure not found
+  @retval    EFI_SUCCESS          All done successfully
+**/
+EFI_STATUS
+EnumerateAllPcieDevices (
+  VOID
+  );
+
+/**
+  Sets Common Clock, TCx-VC0 mapping, and Max Payload for PCIe
+**/
+VOID
+SaPcieConfigBeforeOpRom (
+  VOID
+  );
+
+/**
+  This function does all SA ASPM initialization
+**/
+VOID
+SaAspm (
+  VOID
+  );
+
+/**
+  This function checks PEG end point device for extended tag capability and enables them if they are.
+**/
+VOID
+EnableExtendedTag (
+  VOID
+  );
+
+/**
+  This function handles SA S3 resume
+**/
+VOID
+SaS3Resume (
+  VOID
+  );
+
+/**
+  Wrapper function for all SA S3 resume tasks which can be a callback function.
+**/
+VOID
+SaS3ResumeCallback (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h
new file mode 100644
index 0000000000..2c765b09b8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h
@@ -0,0 +1,36 @@
+/** @file
+  This file defines the SA Iotrap SMI Protocol to provide the
+  I/O address for registered Iotrap SMI.
+
+  Copyright (c) 2019 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;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h
new file mode 100644
index 0000000000..1bae2d95e5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h
@@ -0,0 +1,31 @@
+/** @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) 2019 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 <Private/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/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h
new file mode 100644
index 0000000000..f1b72488ca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h
@@ -0,0 +1,89 @@
+/** @file
+  The GUID definition for SaConfigHob
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_CONFIG_HOB_H_
+#define _SA_CONFIG_HOB_H_
+
+#include <SaAccess.h>
+#include <Base.h>
+
+extern EFI_GUID gSaConfigHobGuid;
+
+#pragma pack (push,1)
+///
+#define DPR_DIRECTORY_MAX               2         ///< 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;
+
+///
+/// The data elements should be initialized by a Platform Module.
+/// The data structure is for VT-d driver initialization
+///
+typedef struct {
+  BOOLEAN               VtdDisable;                        ///< 1 = Avoids programming Vtd bars, Vtd overrides and DMAR table
+  UINT32                BaseAddress[SA_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               InterruptRemappingSupport;         ///< This field is used to indicate Interrupt Remapping supported or not
+} SA_VTD_CONFIGURATION_HOB;
+
+///
+/// SA GPIO Data Structure
+///
+typedef struct {
+  UINT8   ExpanderNo; ///< =Expander No For I2C based GPIO
+  UINT32  GpioNo;     ///< GPIO pad
+  BOOLEAN Active;     ///< 0=Active Low; 1=Active High
+} SA_GPIO;
+
+///
+/// SA PCIE RTD3 GPIO Data Structure
+///
+typedef struct {
+  UINT8              GpioSupport;      ///< 0=Not Supported; 1=PCH based; 2=I2C Based
+  SA_GPIO            HoldRst;          ///< Offset 8 This field contain PCIe HLD RESET GPIO value and level information
+  SA_GPIO            PwrEnable;        ///< This field contain PCIe PWR Enable GPIO value and level information
+  UINT32             WakeGpioNo;       ///< This field contain PCIe RTD3 Device Wake GPIO number
+} PCIE_RTD3_GPIO;
+
+///
+/// SG Info HOB
+///
+typedef struct {
+  SG_MODE           SgMode;
+  UINT8             RootPortIndex;
+  PCIE_RTD3_GPIO    Rtd3Pcie0Gpio;
+  PCIE_RTD3_GPIO    Rtd3Pcie1Gpio;
+  PCIE_RTD3_GPIO    Rtd3Pcie2Gpio;
+  UINT16            DelayAfterPwrEn;
+  UINT16            DelayAfterHoldReset;
+} SA_RTD3;
+
+///
+/// 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
+  BOOLEAN                  InitPcieAspmAfterOprom;                   ///< 1=initialize PCIe ASPM after Oprom; 0=before (This will be set basing on policy)
+  SA_RTD3                  SaRtd3;                                   ///< SG Info HOB
+  UINT8                    ApertureSize;                             ///< Aperture size value
+  UINT8                    IpuAcpiMode;                              ///< IPU ACPI mode: 0=Disabled, 1=IGFX Child device, 2=ACPI device
+  SA_VTD_CONFIGURATION_HOB VtdData;                                  ///< VT-d Data HOB
+  BOOLEAN                  CridEnable;                               ///< This field inidicates if CRID is enabled or disabled (to support Intel(R) SIPP)
+  BOOLEAN                  SkipPamLock;                              ///< 0=All PAM registers will be locked in System Agent code, 1=Do not lock PAM registers in System Agent code.
+  UINT8                    PowerDownUnusedBundles[SA_PEG_MAX_FUN];   ///< PCIe power down unused bundles support
+  UINT8                    PegMaxPayload[SA_PEG_MAX_FUN];            ///< PEG Max Pay Load Size (0xFF: Auto, 0:128B, 1:256B)
+} SA_CONFIG_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h
new file mode 100644
index 0000000000..095942d483
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h
@@ -0,0 +1,151 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define SA NVS Area operatino 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    SgMode;                                  ///< Offset 136     SG Mode (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
+  UINT8    SgFeatureList;                           ///< Offset 137     SG 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
+  UINT16   DelayAfterPwrEn;                         ///< Offset 177     Delay after power enable for PCIe
+  UINT16   DelayAfterHoldReset;                     ///< Offset 179     Delay after Hold Reset for PCIe
+  UINT8    Pcie0EpCapOffset;                        ///< Offset 181     PCIe0 Endpoint Capability Structure Offset
+  UINT32   XPcieCfgBaseAddress;                     ///< Offset 182     Any Device's PCIe Config Space Base Address
+  UINT16   GpioBaseAddress;                         ///< Offset 186     GPIO Base Address
+  UINT32   NvIgOpRegionAddress;                     ///< Offset 188     NVIG opregion address
+  UINT32   NvHmOpRegionAddress;                     ///< Offset 192     NVHM opregion address
+  UINT32   ApXmOpRegionAddress;                     ///< Offset 196     AMDA opregion address
+  UINT8    Peg0LtrEnable;                           ///< Offset 200     Latency Tolerance Reporting Enable
+  UINT8    Peg0ObffEnable;                          ///< Offset 201     Optimized Buffer Flush and Fill
+  UINT8    Peg1LtrEnable;                           ///< Offset 202     Latency Tolerance Reporting Enable
+  UINT8    Peg1ObffEnable;                          ///< Offset 203     Optimized Buffer Flush and Fill
+  UINT8    Peg2LtrEnable;                           ///< Offset 204     Latency Tolerance Reporting Enable
+  UINT8    Peg2ObffEnable;                          ///< Offset 205     Optimized Buffer Flush and Fill
+  UINT8    Peg3LtrEnable;                           ///< Offset 206     Latency Tolerance Reporting Enable
+  UINT8    Peg3ObffEnable;                          ///< Offset 207     Optimized Buffer Flush and Fill
+  UINT16   PegLtrMaxSnoopLatency;                   ///< Offset 208     SA Peg Latency Tolerance Reporting Max Snoop Latency
+  UINT16   PegLtrMaxNoSnoopLatency;                 ///< Offset 210     SA Peg Latency Tolerance Reporting Max No Snoop Latency
+  UINT8    Peg0PowerDownUnusedBundles;              ///< Offset 212     Peg0 Unused Bundle Control
+  UINT8    Peg1PowerDownUnusedBundles;              ///< Offset 213     Peg1 Unused Bundle Control
+  UINT8    Peg2PowerDownUnusedBundles;              ///< Offset 214     Peg2 Unused Bundle Control
+  UINT8    Peg3PowerDownUnusedBundles;              ///< Offset 215     Peg3 Unused Bundle Control
+  UINT8    PackageCstateLimit;                      ///< Offset 216     The lowest C-state for the package
+  UINT8    PwrDnBundlesGlobalEnable;                ///< Offset 217     Pegx Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
+  UINT64   Mmio64Base;                              ///< Offset 218     Base of above 4GB MMIO resource
+  UINT64   Mmio64Length;                            ///< Offset 226     Length of above 4GB MMIO resource
+  UINT32   CpuIdInfo;                               ///< Offset 234     CPU ID info to get Family Id or Stepping
+  UINT8    Pcie1EpCapOffset;                        ///< Offset 238     PCIe1 Endpoint Capability Structure Offset
+  UINT8    Pcie2EpCapOffset;                        ///< Offset 239     PCIe2 Endpoint Capability Structure Offset
+  UINT8    Pcie0SecBusNum;                          ///< Offset 240     PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie1SecBusNum;                          ///< Offset 241     PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie2SecBusNum;                          ///< Offset 242     PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT32   Mmio32Base;                              ///< Offset 243     Base of below 4GB MMIO resource
+  UINT32   Mmio32Length;                            ///< Offset 247     Length of below 4GB MMIO resource
+  UINT32   Pcie0WakeGpioNo;                         ///< Offset 251     PCIe0 RTD3 Device Wake GPIO Number
+  UINT32   Pcie1WakeGpioNo;                         ///< Offset 255     PCIe1 RTD3 Device Wake GPIO Number
+  UINT32   Pcie2WakeGpioNo;                         ///< Offset 259     PCIe2 RTD3 Device Wake GPIO Number
+  UINT8    VtdDisable;                              ///< Offset 263     VT-d Enable/Disable
+  UINT32   VtdBaseAddress1;                         ///< Offset 264     VT-d Base Address 1
+  UINT32   VtdBaseAddress2;                         ///< Offset 268     VT-d Base Address 2
+  UINT32   VtdBaseAddress3;                         ///< Offset 272     VT-d Base Address 3
+  UINT16   VtdEngine1Vid;                           ///< Offset 276     VT-d Engine#1 Vendor ID
+  UINT16   VtdEngine2Vid;                           ///< Offset 278     VT-d Engine#2 Vendor ID
+  UINT8    Pcie3SecBusNum;                          ///< Offset 280     PCIe3 Secondary Bus Number (PCIe3 Endpoint Bus Number)
+  UINT8    Pcie3GpioSupport;                        ///< Offset 281     PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  UINT8    Pcie3HoldRstExpanderNo;                  ///< Offset 282     PCIe3 HLD RST IO Expander Number
+  UINT32   Pcie3HoldRstGpioNo;                      ///< Offset 283     PCIe3 HLD RST GPIO Number
+  UINT8    Pcie3HoldRstActiveInfo;                  ///< Offset 287     PCIe3 HLD RST GPIO Active Information
+  UINT8    Pcie3PwrEnExpanderNo;                    ///< Offset 288     PCIe3 PWR Enable IO Expander Number
+  UINT32   Pcie3PwrEnGpioNo;                        ///< Offset 289     PCIe3 PWR Enable GPIO Number
+  UINT8    Pcie3PwrEnActiveInfo;                    ///< Offset 293     PCIe3 PWR Enable GPIO Active Information
+  UINT32   Pcie3WakeGpioNo;                         ///< Offset 294     PCIe3 RTD3 Device Wake GPIO Number
+  UINT8    Pcie3EpCapOffset;                        ///< Offset 298     PCIe3 Endpoint Capability Structure Offset
+  UINT8    RootPortIndex;                           ///< Offset 299     RootPort Number
+  UINT32   RootPortAddress;                         ///< Offset 300     RootPortAddress
+  UINT8    Reserved0[196];                          ///< Offset 304:499
+} SYSTEM_AGENT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h
new file mode 100644
index 0000000000..a9db25404f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h
@@ -0,0 +1,63 @@
+/** @file
+  Protocol to retrieve the GOP driver version
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h
new file mode 100644
index 0000000000..866f60b9c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h
@@ -0,0 +1,73 @@
+/** @file
+  Interface definition for GopPolicy Protocol.
+
+  Copyright (c) 2019 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 gIntelGraphicsVbtGuid;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h
new file mode 100644
index 0000000000..ef2edfe122
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h
@@ -0,0 +1,24 @@
+/** @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) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
new file mode 100644
index 0000000000..031e55b9b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
@@ -0,0 +1,132 @@
+/** @file
+  This protocol provides the memory information data, such as
+  total physical memory size, memory frequency, memory size
+  of each dimm and rank.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MEM_INFO_PROTOCOL_H_
+#define _MEM_INFO_PROTOCOL_H_
+
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gMemInfoProtocolGuid;
+
+//
+// Protocol definitions
+//
+#define NODE_NUM  1
+#define CH_NUM    2
+#define DIMM_NUM  2
+#define RANK_NUM  2
+#define SLOT_NUM  (CH_NUM * DIMM_NUM)
+#define PROFILE_NUM 4 // number of memory profiles supported
+#define XMP_PROFILE_NUM 2 // number of XMP profiles supported
+
+//
+// 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_UNKNOWN
+#define MRC_DDR_TYPE_UNKNOWN  3
+#endif
+
+//
+// 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
+
+#pragma pack(1)
+///
+/// Memory timing Structure
+///
+typedef struct {
+  UINT32 tCK;     ///< Offset 0 Memory cycle time, in femtoseconds.
+  UINT16 NMode;   ///< Offset 4 Number of tCK cycles for the channel DIMM's command rate mode.
+  UINT16 tCL;     ///< Offset 6 Number of tCK cycles for the channel DIMM's CAS latency.
+  UINT16 tCWL;    ///< Offset 8 Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
+  UINT16 tFAW;    ///< Offset 10 Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
+  UINT16 tRAS;    ///< Offset 12 Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
+  UINT16 tRCDtRP; ///< Offset 14 Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time
+  UINT16 tREFI;   ///< Offset 16 Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
+  UINT16 tRFC;    ///< Offset 18 Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRPab;   ///< Offset 20 Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
+  UINT16 tRRD;    ///< Offset 22 Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
+  UINT16 tRTP;    ///< Offset 24 Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
+  UINT16 tWR;     ///< Offset 26 Number of tCK cycles for the channel DIMM's minimum write recovery time.
+  UINT16 tWTR;    ///< Offset 28 Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
+  UINT16 tRRD_L;  ///< Offset 30 Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
+  UINT16 tRRD_S;  ///< Offset 32 Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
+  UINT16 tWTR_L;  ///< Offset 34 Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
+  UINT16 tWTR_S;  ///< Offset 36 Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
+  UINT8  Rsvd[2]; ///< Offset 38
+} MEMORY_TIMING;
+
+typedef struct {
+  UINT8 SG;       ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;       ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;       ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;       ///< Number of tCK cycles between transactions when switching between DIMMs
+} TURNAROUND_TIMING;
+
+// @todo use the MemInfoHob data instead of duplicate structure.
+///
+/// Memory information Data Structure
+///
+typedef struct {
+  MEMORY_TIMING Timing[PROFILE_NUM];                   ///< Offset 0 Timming information for the DIMM
+  UINT32  memSize;                                     ///< Offset 128 Total physical memory size
+  UINT16  ddrFreq;                                     ///< Offset 132 DDR Current Frequency
+  UINT16  ddrFreqMax;                                  ///< Offset 134 DDR Maximum Frequency
+  UINT16  dimmSize[NODE_NUM * CH_NUM * DIMM_NUM];      ///< Offset 136 Size of each DIMM
+  UINT16  VddVoltage[PROFILE_NUM];                     ///< Offset 144 The voltage setting for the DIMM
+  UINT8   DimmStatus[NODE_NUM * CH_NUM * DIMM_NUM];    ///< Offset 152 The enumeration value from MrcDimmSts
+  UINT8   RankInDimm[NODE_NUM * CH_NUM * DIMM_NUM];    ///< Offset 156 No. of ranks in a dimm
+  UINT8   *DimmsSpdData[NODE_NUM * CH_NUM * DIMM_NUM]; ///< Offset 160 SPD data of each DIMM
+  UINT8   RefClk;                                      ///< Offset 192 Reference Clock
+  UINT8   Ratio;                                       ///< Offset 193 Clock Multiplier
+  BOOLEAN EccSupport;                                  ///< Offset 194 ECC supported or not
+  UINT8   Profile;                                     ///< Offset 195 Currently running memory profile
+  UINT8   XmpProfileEnable;                            ///< Offset 196: 0 = no XMP DIMMs in system
+  UINT8   DdrType;                                     ///< Offset 197: Current DDR type, see DDR_TYPE_xxx defines above
+  UINT8   Reserved[2];                                 ///< Offset 198 Reserved bytes for future use
+  UINT32  DefaultXmptCK[XMP_PROFILE_NUM];              ///< Offset 200 The Default XMP tCK values read from SPD.
+  TURNAROUND_TIMING tRd2Rd[CH_NUM];                    ///< Read-to-Read   Turn Around Timings
+  TURNAROUND_TIMING tRd2Wr[CH_NUM];                    ///< Read-to-Write  Turn Around Timings
+  TURNAROUND_TIMING tWr2Rd[CH_NUM];                    ///< Write-to-Read  Turn Around Timings
+  TURNAROUND_TIMING tWr2Wr[CH_NUM];                    ///< Write-to-Write Turn Around Timings
+} MEMORY_INFO_DATA;
+#pragma pack()
+
+///
+/// Memory information Protocol definition
+///
+typedef struct {
+  MEMORY_INFO_DATA  MemInfoData; ///< Memory Information Data Structure
+} MEM_INFO_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
new file mode 100644
index 0000000000..7b68f3072b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
@@ -0,0 +1,66 @@
+/** @file
+  Interface definition details between System Agent and platform drivers during DXE phase.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_H_
+#define _SA_POLICY_H_
+
+#include <SaAccess.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/GraphicsDxeConfig.h>
+#include <ConfigBlock/MemoryDxeConfig.h>
+#include <ConfigBlock/MiscDxeConfig.h>
+#include <ConfigBlock/PcieDxeConfig.h>
+#include <ConfigBlock/VbiosDxeConfig.h>
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gSaPolicyProtocolGuid;
+extern EFI_GUID gGraphicsDxeConfigGuid;
+extern EFI_GUID gMiscDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gVbiosDxeConfigGuid;
+
+/**
+  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 SA_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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h
new file mode 100644
index 0000000000..6f3541e3e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h
@@ -0,0 +1,32 @@
+/** @file
+  Register names for GNA 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_GNA_H_
+#define _SA_REGS_GNA_H_
+
+//
+// Device 8 Equates
+//
+#define SA_GNA_BUS_NUM    0x00
+#define SA_GNA_DEV_NUM    0x08
+#define SA_GNA_FUN_NUM    0x00
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h
new file mode 100644
index 0000000000..2cc0e5be68
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h
@@ -0,0 +1,214 @@
+/** @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) 2019 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_
+
+//
+// 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
+
+///
+/// Maximum number of SDRAM channels supported by the memory controller
+///
+#define SA_MC_MAX_CHANNELS 2
+
+///
+/// Maximum number of DIMM sockets supported by each channel
+///
+#define SA_MC_MAX_SLOTS 2
+
+///
+/// Maximum number of sides supported per DIMM
+///
+#define SA_MC_MAX_SIDES 2
+
+///
+/// Maximum number of DIMM sockets supported by the memory controller
+///
+#define SA_MC_MAX_SOCKETS (SA_MC_MAX_CHANNELS * SA_MC_MAX_SLOTS)
+
+///
+/// Maximum number of rows supported by the memory controller
+///
+#define SA_MC_MAX_RANKS (SA_MC_MAX_SOCKETS * SA_MC_MAX_SIDES)
+
+///
+/// Maximum number of rows supported by the memory controller
+///
+#define SA_MC_MAX_ROWS (SA_MC_MAX_SIDES * SA_MC_MAX_SOCKETS)
+
+///
+/// Maximum memory supported by the memory controller
+/// 4 GB in terms of KB
+///
+#define SA_MC_MAX_MEM_CAPACITY (4 * 1024 * 1024)
+
+///
+/// Define the maximum number of data bytes on a system with no ECC memory support.
+///
+#define SA_MC_MAX_BYTES_NO_ECC (8)
+
+///
+/// Define the maximum number of SPD data bytes on a DIMM.
+///
+#define SA_MC_MAX_SPD_SIZE (512)
+//
+// Maximum DMI lanes and bundles supported (x8 and 4 lanes)
+//
+#define SA_DMI_MAX_LANE                      0x04
+#define SA_DMI_MAX_BUNDLE                    0x02
+
+#define SA_DMI_CFL_MAX_LANE                  0x04
+#define SA_DMI_CFL_MAX_BUNDLE                0x02
+//
+// KabyLake CPU Mobile SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_MB_ULT_1 0x5904   ///< Kabylake Ult (OPI) (2+1F/1.5F/2F/3/3E) Mobile SA DID
+//
+// KabyLake CPU Halo SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_HALO_2   0x5910   ///< Kabylake Halo (4+2/4E/3FE) SA DID
+//
+// KabyLake CPU Desktop SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_DT_2     0x591F   ///< Kabylake Desktop (4+1.5F/2/4) SA DID
+//
+// KabyLake CPU Server SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_KBL_SVR_2    0x5918   ///< Kabylake Server (4+1/2/4E) SA DID
+
+//
+// CoffeeLake CPU Mobile SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_ULT_1        0x3ED0   ///< CoffeeLake Mobile (CFL-U 4+3e) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_2        0x3ECC   ///< CoffeeLake Mobile (CFL-U 2+3e) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_3        0x3E34   ///< CoffeeLake Mobile (CFL-U 4+(1 or 2)) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_4        0x3E35   ///< CoffeeLake Mobile (CFL-U 2+(1 or 2)) SA DID
+#define V_SA_DEVICE_ID_CFL_ULT_6        0x3ECC   ///< CoffeeLake Mobile (CFL-U 2+3e) SA DID
+
+//
+// CoffeeLake CPU Desktop SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_DT_1         0x3EC2   ///< CoffeeLake Desktop (6+2) SA DID
+#define V_SA_DEVICE_ID_CFL_DT_2         0x3E1F   ///< CoffeeLake Desktop (4+2) SA DID
+#define V_SA_DEVICE_ID_CFL_DT_3         0x3E0F   ///< CoffeeLake Desktop (2+2) SA DID
+#define V_SA_DEVICE_ID_CFL_DT_4         0x3E30   ///< CoffeeLake Desktop (8+2) SA DID
+
+//
+// CoffeeLake CPU Halo SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_HALO_1       0x3EC4   ///< CoffeeLake Halo (6+2) SA DID
+#define V_SA_DEVICE_ID_CFL_HALO_2       0x3E10   ///< CoffeeLake Halo (4+2) SA DID
+#define V_SA_DEVICE_ID_CFL_HALO_3       0x3E20   ///< CoffeeLake Halo (8+2) SA DID
+
+//
+// CoffeeLake CPU WS SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_WS_1         0x3EC6   ///< CoffeeLake WorkStation (6+2) SA DID
+#define V_SA_DEVICE_ID_CFL_WS_2         0x3E18   ///< CoffeeLake WrokStation (4+2) SA DID
+#define V_SA_DEVICE_ID_CFL_WS_3         0x3E31   ///< CoffeeLake WrokStation (8+2) SA DID
+
+//
+// CPU Server SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_CFL_SVR_1        0x3ECA   ///< CoffeeLake Server (6+0) SA DID
+#define V_SA_DEVICE_ID_CFL_SVR_2        0x3E32   ///< CoffeeLake Server (8+0) SA DID
+#define V_SA_DEVICE_ID_CFL_SVR_3        0x3E33   ///< CoffeeLake Server (4+0) SA DID
+/**
+ <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)
+#define N_SA_GGC_GMS_OFFSET  (0x8)
+#define B_SA_GGC_GMS_MASK    (0xff00)
+#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)
+#define B_SA_DEVEN_D2EN_MASK     (0x10)
+/**
+ Description:
+  This is the base address for the PCI Express configuration space.  This window of addresses contains the 4KB of configuration space for each PCI Express device that can potentially be part of the PCI Express Hierarchy associated with the Uncore.  There is no actual physical memory within this window of up to 256MB that can be addressed.  The actual size of this range is determined by a field in this register.
+  Each PCI Express Hierarchy requires a PCI Express BASE register.  The Uncore supports one PCI Express Hierarchy.  The region reserved by this register does not alias to any PCI2.3 compliant memory mapped space.  For example, the range reserved for MCHBAR is outside of PCIEXBAR space.
+  On reset, this register is disabled and must be enabled by writing a 1 to the enable field in this register.  This base address shall be assigned on a boundary consistent with the number of buses (defined by the length field in this register), above TOLUD and still within 39-bit addressable memory space.
+  The PCI Express Base Address cannot be less than the maximum address written to the Top of physical memory register (TOLUD).  Software must guarantee that these ranges do not overlap with known ranges located above TOLUD.
+  Software must ensure that the sum of the length of the enhanced configuration region + TOLUD + any other known ranges reserved above TOLUD is not greater than the 39-bit addessable limit of 512GB.  In general, system implementation and the number of PCI/PCI Express/PCI-X buses supported in the hierarchy will dictate the length of the region.
+  All the bits in this register are locked in LT mode.
+**/
+#define R_SA_PCIEXBAR  (0x60)
+
+/**
+ Description:
+ - This register controls the read, write and shadowing attributes of the BIOS range from F_0000h to F_FFFFh.  The Uncore allows programmable memory attributes on 13 legacy memory segments of various sizes in the 768KB to 1MB address range.  Seven Programmable Attribute Map (PAM) registers are used to support these features.  Cacheability of these areas is controlled via the MTRR register in the core.
+ - Two bits are used to specify memory attributes for each memory segment.  These bits apply to host accesses to the PAM areas.  These attributes are:
+ - RE - Read Enable.  When RE=1, the host read accesses to the corresponding memory segment are claimed by the Uncore and directed to main memory.  Conversely, when RE=0, the host read accesses are directed to DMI.
+ - WE - Write Enable.  When WE=1, the host write accesses to the corresponding memory segment are claimed by the Uncore and directed to main memory.  Conversely, when WE=0, the host read accesses are directed to DMI.
+ - The RE and WE attributes permit a memory segment to be Read Only, Write Only, Read/Write or Disabled.  For example, if a memory segment has RE=1 and WE=0, the segment is Read Only.
+**/
+#define R_SA_PAM0  (0x80)
+
+///
+/// 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)
+#define B_SA_SMRAMC_D_LCK_MASK     (0x10)
+#define B_SA_SMRAMC_D_CLS_MASK     (0x20)
+#define B_SA_SMRAMC_D_OPEN_MASK    (0x40)
+///
+/// Description:
+///  This register contains the Top of low memory address.
+///
+#define R_SA_TOLUD (0xbc)
+#define R_SA_MC_CAPID0_A_OFFSET    0xE4
+//
+// MCHBAR IO Register Offset Equates
+//
+#define R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET          0x5DA8
+
+#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)
+///
+/// Vt-d Engine base address.
+///
+#define R_SA_MCHBAR_VTD1_OFFSET                 0x5400  ///< HW UNIT1 for IGD
+#define R_SA_MCHBAR_VTD3_OFFSET      0x5410  ///< HW UNIT3 for all other - PEG, USB, SATA etc
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h
new file mode 100644
index 0000000000..f8b794a9fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h
@@ -0,0 +1,50 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_IGD_H_
+#define _SA_REGS_IGD_H_
+
+///
+/// Device 2 Register Equates
+///
+//
+// The following equates must be reviewed and revised when the specification is ready.
+//
+#define SA_IGD_BUS           0x00
+#define SA_IGD_DEV           0x02
+#define SA_IGD_FUN_0         0x00
+#define SA_IGD_DEV_FUN       (SA_IGD_DEV << 3)
+#define SA_IGD_BUS_DEV_FUN   (SA_MC_BUS << 8) + SA_IGD_DEV_FUN
+
+#define V_SA_IGD_VID         0x8086
+#define SA_GT_APERTURE_SIZE_256MB    1      ///< 256MB is the recommanded GT Aperture Size as per BWG.
+
+#define V_SA_PCI_DEV_2_GT2_CFL_ULT_1_ID   0x3EA0 ///< Dev2 CFL-U GT2
+#define V_SA_PCI_DEV_2_GT1_CFL_ULT_1_ID   0x3EA1 ///< Dev2 CFL-U GT1
+#define R_SA_IGD_VID               0x00
+#define R_SA_IGD_DID               0x02
+#define R_SA_IGD_CMD               0x04
+
+#define R_SA_IGD_SWSCI_OFFSET      0x00E8
+#define R_SA_IGD_ASLS_OFFSET       0x00FC  ///< ASL Storage
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h
new file mode 100644
index 0000000000..b26c79ec95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h
@@ -0,0 +1,37 @@
+/** @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
+  - 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_IPU_H_
+#define _SA_REGS_IPU_H_
+
+//
+// Device 5 Equates
+//
+#define SA_IPU_BUS_NUM    0x00
+#define SA_IPU_DEV_NUM    0x05
+#define SA_IPU_FUN_NUM    0x00
+
+//
+// GPIO native features pins data
+//
+#define SA_GPIO_IMGUCLK_NUMBER_OF_PINS     2
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h
new file mode 100644
index 0000000000..b7e9416fc6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h
@@ -0,0 +1,64 @@
+/** @file
+  Register names for PEG 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_PEG_H_
+#define _SA_REGS_PEG_H_
+//
+// Device 1 Memory Mapped IO Register Offset Equates
+//
+#define SA_PEG_BUS_NUM     0x00
+#define SA_PEG_DEV_NUM     0x01
+#define SA_PEG0_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG0_FUN_NUM    0x00
+#define SA_PEG1_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG1_FUN_NUM    0x01
+#define SA_PEG2_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG2_FUN_NUM    0x02
+//
+// Temporary Device & Function Number used for Switchable Graphics DGPU
+//
+#define SA_TEMP_DGPU_DEV   0x00
+#define SA_TEMP_DGPU_FUN   0x00
+
+//
+// SA PCI Express* Port configuration
+//
+#define SA_PEG_MAX_FUN     0x03
+#define SA_PEG_MAX_LANE    0x10
+#define SA_PEG_MAX_BUNDLE  0x08
+
+//
+// Silicon and SKU- specific MAX defines
+//
+#define SA_PEG_CNL_H_MAX_FUN           SA_PEG_MAX_FUN      // CNL-H- SKU supports 4 controllers with 20 PEG lanes and 10 bundles
+#define SA_PEG_CNL_H_MAX_LANE          SA_PEG_MAX_LANE
+#define SA_PEG_CNL_H_MAX_BUNDLE        SA_PEG_MAX_BUNDLE
+#define SA_PEG_NON_CNL_H_MAX_FUN       0x03                // All non-CNL-H- SKU supports 3 controllers with 16 PEG lanes and 8 bundles
+#define SA_PEG_NON_CNL_H_MAX_LANE      0x10
+#define SA_PEG_NON_CNL_H_MAX_BUNDLE    0x08
+
+
+
+#define R_SA_PEG_VID_OFFSET            0x00  ///< Vendor ID
+#define R_SA_PEG_DID_OFFSET            0x02  ///< Device ID
+#define R_SA_PEG_SS_OFFSET             0x8C  ///< Subsystem ID
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
new file mode 100644
index 0000000000..b98f1732ba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
@@ -0,0 +1,106 @@
+/** @file
+  Macros to simplify and abstract the interface to PCI configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SAACCESS_H_
+#define _SAACCESS_H_
+
+#include "SaRegs.h"
+#include "SaCommonDefinitions.h"
+
+///
+/// SystemAgent Base Address definition
+///
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND  1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND  1000
+#endif
+
+//
+// SA Segement Number
+//
+#define SA_SEG_NUM         0x00
+
+#define V_SA_DEVICE_ID_INVALID 0xFFFF
+
+
+///
+/// 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
+} SA_PCIE_ASPM_CONFIG;
+
+///
+/// SgMode settings
+///
+typedef enum {
+  SgModeDisabled = 0,
+  SgModeReserved,
+  SgModeMuxless,
+  SgModeDgpu,
+  SgModeMax
+} SG_MODE;
+
+//
+// Macros that judge which type a device ID belongs to
+//
+#define IS_SA_DEVICE_ID_MOBILE(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_MB_ULT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_3) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_4) \
+    )
+
+///
+/// Device IDs that are Desktop specific B0:D0:F0
+///
+#define IS_SA_DEVICE_ID_DESKTOP(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_DT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_3) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_DT_4) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_WS_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_WS_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_WS_3) \
+    )
+
+///
+/// Device IDS that are Server specific B0:D0:F0
+///
+#define IS_SA_DEVICE_ID_SERVER(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_SVR_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_3) \
+    )
+
+///
+/// Device IDs that are Halo specific B0:D0:F0
+///
+#define IS_SA_DEVICE_ID_HALO(DeviceId) \
+    ( \
+      (DeviceId == V_SA_DEVICE_ID_KBL_HALO_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_1) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_2) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_3) || \
+      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_IOT_1) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h
new file mode 100644
index 0000000000..ab9224e573
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h
@@ -0,0 +1,23 @@
+/** @file
+  This header file provides common definitions just for System Agent using to avoid including extra module's file.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_COMMON_DEFINITIONS_H_
+#define _SA_COMMON_DEFINITIONS_H_
+
+#define ERROR_BY_16     (0xEE15)
+#define ERROR_NOT_BY_16 (0xED15)
+
+#define MAX_PCIE_ASPM_OVERRIDE       500
+#define MAX_PCIE_LTR_OVERRIDE        500
+
+#define DISABLED  0
+#define ENABLED   1
+
+#define SA_VTD_ENGINE_NUMBER        3
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
new file mode 100644
index 0000000000..87aa105df2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
@@ -0,0 +1,25 @@
+/** @file
+  Header file for the PCI Express library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PCI_EXPRESS_LIB_H_
+#define _SA_PCI_EXPRESS_LIB_H_
+
+
+/**
+  Gets the base address of PCI Express.
+
+  This internal functions retrieves PCI Express Base Address.
+
+  @return The base address of PCI Express.
+**/
+VOID*
+GetPciExpressBaseAddress (
+  VOID
+);
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
new file mode 100644
index 0000000000..086c60bfed
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
@@ -0,0 +1,51 @@
+/** @file
+  Main System Agent Policy structure definition which will contain several config blocks during runtime.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_COMMON_H_
+#define _SA_POLICY_COMMON_H_
+
+#include <Uefi.h>
+#include <Library/SmbusLib.h>
+#include <SaAccess.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/SwitchableGraphicsConfig.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <ConfigBlock/GraphicsPeiPreMemConfig.h>
+#include <ConfigBlock/PciePeiPreMemConfig.h>
+#include <ConfigBlock/IpuPreMemConfig.h>
+#include <ConfigBlock/SaMiscPeiPreMemConfig.h>
+#include <ConfigBlock/GnaConfig.h>
+#include <ConfigBlock/GraphicsPeiConfig.h>
+#include <ConfigBlock/SaMiscPeiConfig.h>
+#include <ConfigBlock/OverClockingConfig.h>
+#include <ConfigBlock/VtdConfig.h>
+#include <ConfigBlock/PciePeiConfig.h>
+
+
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gSiPolicyPpiGuid;
+extern EFI_GUID gSaMiscPeiConfigGuid;
+extern EFI_GUID gGraphicsPeiConfigGuid;
+extern EFI_GUID gSaPciePeiConfigGuid;
+extern EFI_GUID gGnaConfigGuid;
+extern EFI_GUID gVtdConfigGuid;
+extern EFI_GUID gSaOverclockingPreMemConfigGuid;
+extern EFI_GUID gSiPreMemPolicyPpiGuid;
+extern EFI_GUID gSaMiscPeiPreMemConfigGuid;
+extern EFI_GUID gSaPciePeiPreMemConfigGuid;
+extern EFI_GUID gGraphicsPeiPreMemConfigGuid;
+extern EFI_GUID gIpuPreMemConfigGuid;
+extern EFI_GUID gSwitchableGraphicsConfigGuid;
+extern EFI_GUID gCpuTraceHubConfigGuid;
+extern EFI_GUID gMemoryConfigGuid;
+extern EFI_GUID gMemoryConfigNoCrcGuid;
+
+#endif // _SA_POLICY_COMMON_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
new file mode 100644
index 0000000000..593b907d2a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
@@ -0,0 +1,32 @@
+/** @file
+  Register names for System Agent (SA) registers
+  <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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_REGS_H_
+#define _SA_REGS_H_
+
+#include <Register/SaRegsHostBridge.h>
+#include <Register/SaRegsIgd.h>
+#include <Register/SaRegsPeg.h>
+#include <Register/SaRegsIpu.h>
+#include <Register/SaRegsGna.h>
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library include headers

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

Adds the following header files:
 * Pch/Include/Private/Library

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h           |  134 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h          |   97 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h       |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h          | 1061 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h      |  288 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h               |  344 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h               |   56 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h        |  100 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h |  371 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h        |  578 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h       |   98 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h         |  366 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h            |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h           |  706 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h      |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h        |   28 +
 16 files changed, 4325 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h
new file mode 100644
index 0000000000..9d8e34eb0d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h
@@ -0,0 +1,134 @@
+/** @file
+  Header file for DxePchHdaLib - NHLT structure definitions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_HDA_NHLT_H_
+#define _DXE_PCH_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_DEVICE_TYPE
+{
+  HdaNhltDeviceBt   = 0,
+  HdaNhltDeviceDmic = 1,
+  HdaNhltDeviceI2s  = 4,
+  HdaNhltDeviceInvalid
+};
+
+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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h
new file mode 100644
index 0000000000..9e0658331f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h
@@ -0,0 +1,97 @@
+/** @file
+  Header file for GPIO Helpers Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_HELPERS_LIB_H_
+#define _GPIO_HELPERS_LIB_H_
+
+#include <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
+  );
+#endif // _GPIO_HELPERS_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h
new file mode 100644
index 0000000000..a6ab42e4d5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h
@@ -0,0 +1,25 @@
+/** @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) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h
new file mode 100644
index 0000000000..245618ff6d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h
@@ -0,0 +1,1061 @@
+/** @file
+  Header file for GpioPrivateLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_PRIVATE_LIB_H_
+#define _GPIO_PRIVATE_LIB_H_
+
+#include <GpioConfig.h>
+#include <Library/PchPcrLib.h>
+
+//
+// Structure for native pin data
+//
+typedef struct {
+  GPIO_PAD       Pad;
+  GPIO_PAD_MODE  Mode;
+} GPIO_PAD_NATIVE_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
+
+//
+// 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
+
+/**
+  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
+  );
+
+/**
+  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 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;
+  UINT8       GpioGpeDwxVal;
+} 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 set 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
+GpioSetPadMode (
+  IN GPIO_PAD                GpioPad,
+  IN GPIO_PAD_MODE           PadModeValue
+  );
+
+/**
+  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 sets SerialIo I2C controller pins into native mode
+
+  @param[in]  SerialIoI2cControllerNumber   I2C controller
+  @param[in]  GpioTermination               GPIO termination type
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoI2c (
+  IN  UINT32                  SerialIoI2cControllerNumber,
+  IN  GPIO_ELECTRICAL_CONFIG  GpioTermination
+  );
+
+/**
+  This function sets SerialIo UART controller pins into native mode
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoUart (
+  IN  UINT32            SerialIoUartControllerNumber,
+  IN  BOOLEAN           HardwareFlowControl,
+  IN  UINT32            PinMuxing
+  );
+
+/**
+  This function sets SerialIo SPI controller pins into native mode
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoSpi (
+  IN  UINT32            SerialIoSpiControllerNumber
+  );
+
+/**
+  This function sets ISH I2C controller pins into native mode
+
+  @param[in]  IshI2cControllerNumber   I2C controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshI2c (
+  IN  UINT32            IshI2cControllerNumber
+  );
+
+/**
+  This function sets ISH UART controller pins into native mode
+
+  @param[in]  IshUartControllerNumber   UART controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshUart (
+  IN  UINT32            IshUartControllerNumber
+  );
+
+/**
+  This function sets ISH SPI controller pins into native mode
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshSpi (
+  IN  UINT32            IshSpiControllerNumber
+  );
+
+/**
+  This function sets ISH GP pin into native mode
+
+  @param[in]  IshGpPinNumber   ISH GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshGpPin (
+  IN  UINT32            IshGpPinNumber
+  );
+
+/**
+  This function sets SCS SD card controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCard (
+  VOID
+  );
+
+/**
+  This function enables SCS SD Card controller card detect pin
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCardDetect (
+  VOID
+  );
+
+/**
+  This function sets SCS eMMC controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsEmmc (
+  VOID
+  );
+
+/**
+  This function sets HDA Link pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaLink (
+  VOID
+  );
+
+/**
+  This function sets HDA DMIC pins into native mode
+
+  @param[in]  DmicNumber   DMIC number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaDmic (
+  IN  UINT32            DmicNumber
+  );
+
+/**
+  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]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSspMasterClock (
+  VOID
+  );
+
+/**
+  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 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 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 sets SATA DevSlp pins into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataDevSlpPin (
+  IN  UINT32  SataCtrlIndex,
+  IN  UINTN   SataPort
+  );
+
+/**
+  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]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataLed (
+  VOID
+  );
+
+/**
+  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
+  );
+
+//
+// DDSP_HPD pins
+//
+typedef enum {
+  GpioDdspHpd0 = 0x00,
+  GpioDdspHpd1 = 0x01,
+  GpioDdspHpd2 = 0x02,
+  GpioDdspHpd3 = 0x03,
+  GpioDdspHpd4 = 0x04,
+  GpioDdspHpdA = 0x10,
+  GpioDdspHpdB = 0x11,
+  GpioDdspHpdC = 0x12
+} GPIO_DDSP_HPD;
+
+/**
+  This function sets DDSP_HPDx pin into native mode
+
+  @param[in]  DdspHpdPin     DDSP_HPDx pin
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpHotPlugDetect (
+  IN GPIO_DDSP_HPD  DdspHpdPin
+  );
+
+/**
+  This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode for eDP Panel
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableEdpPins (
+  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
+  );
+
+/**
+  This function configures GPIO connection between CNVi and CRF
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviCrfConnection (
+  VOID
+  );
+
+/**
+  This function enables CNVi RF Reset pin
+**/
+VOID
+GpioEnableCnviRfResetPin (
+  VOID
+  );
+
+/**
+  This function enables CNVi MODEM CLKREQ pin
+**/
+VOID
+GpioEnableCnviModemClkReqPin (
+  VOID
+  );
+
+/**
+  CNVi Bluetooth UART connection options
+**/
+typedef enum {
+  GpioCnviBtUartNotConnected,
+  GpioCnviBtUartToSerialIoUart0,
+  GpioCnviBtUartToIshUart0,
+  GpioCnviBtUartToExternalPads
+} VGPIO_CNVI_BT_UART_CONNECTION_TYPE;
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth UART
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtUartConnection (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType
+  );
+
+/**
+  CNVi Bluetooth I2S connection options
+**/
+typedef enum {
+  GpioCnviBtI2sNotConnected,
+  GpioCnviBtI2sToSsp0,
+  GpioCnviBtI2sToSsp1,
+  GpioCnviBtI2sToSsp2,
+  GpioCnviBtI2sToExternalPads
+} VGPIO_CNVI_BT_I2S_CONNECTION_TYPE;
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth I2S
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtI2sConnection (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType
+  );
+
+/**
+  CNVi MultiFunction UART connection options
+**/
+typedef enum {
+  GpioCnviMfUart1NotConnected,
+  GpioCnviMfUart1ToSerialIoUart2,
+  GpioCnviMfUart1ToIshUart0,
+  GpioCnviMfUart1ToExternalPads
+} VGPIO_CNVI_MF_UART1_CONNECTION_TYPE;
+
+/**
+  This function configures virtual GPIO connection for CNVi MFUART1
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviMfUart1Connection (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType
+  );
+
+
+/**
+  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
+  );
+
+/**
+  CNVi Bluetooth UART connection options
+**/
+typedef enum {
+  GpioCnviBtIfUart = 0,
+  GpioCnviBtIfUsb,
+} VGPIO_CNVI_BT_INTERFACE;
+
+/**
+  This function sets CNVi Bluetooth main host interface
+
+  @param[in] BtInterface          CNVi BT Interface Select value
+                                  GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviBtInterface (
+  IN  VGPIO_CNVI_BT_INTERFACE  BtInterface
+  );
+
+/**
+  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
+  );
+
+/**
+  CNVi WiFi mode
+**/
+typedef enum {
+  GpioCnviWiFiEnabled,
+  GpioCnviWiFiAuto
+} VGPIO_CNVI_WIFI_MODE;
+
+/**
+  This function sets CNVi WiFi mode
+
+  @param[in] Value                CNVi WiFi Mode value
+                                  GpioCnviWiFiAuto: WiFi is automatically enabled/disabled by WiFi core
+                                  GpioCnviWiFiEnabled: WiFi is enabled regardless of WiFi core decision
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviWifiMode (
+  IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
+  );
+
+/**
+  This function enables IMGU CLKOUT native pin
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableImguClkOut (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  Configure LPC GPIO
+**/
+VOID
+LpcConfigureGpio (
+  VOID
+  );
+
+#endif // _GPIO_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h
new file mode 100644
index 0000000000..a4bd42f420
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h
@@ -0,0 +1,288 @@
+/** @file
+ Implement the I2C port control.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _I2C_MASTER_COMMON_LIB_H_
+#define _I2C_MASTER_COMMON_LIB_H_
+
+///
+/// Each I2C port instance uses an I2C_MASTER_CONTEXT structure
+/// to maintain its context.
+///
+typedef struct {
+  EFI_I2C_CONTROLLER_CAPABILITIES Capabilities;
+  //
+  // I2C master's mmio addresses cached to speed up operation
+  //
+  UINTN                           MmioAddress;
+  UINTN                           ConfigAddress;
+  //
+  // copy of all pointers and data provided in StartRequest call
+  // if transfer didn't finish in one go, those will be needed to continue it
+  //
+  EFI_I2C_REQUEST_PACKET          *Request;
+  //
+  // Internal copy of Transfer status, to be returned from StartRequest()
+  //
+  EFI_STATUS                      TransferStatus;
+  //
+  // Index (Operation:Postition in Buffer) of next operation to be performed
+  // Write is for both R/W operations as both need to be put in fifo
+  // Read is for Read only, for filling buffer with data retrieved from bus
+  //
+  UINTN                           WriteOp;
+  UINTN                           WritePos;
+  UINTN                           ReadOp;
+  UINTN                           ReadPos;
+  BOOLEAN                         TransferInProgress;
+} I2C_MASTER_CONTEXT;
+
+/**
+  Prepare I2c controller for use: enable its mmio range, put in D0, get out of reset
+  Verifies I2C Line SDA and SCL states
+
+  @param[in] Context - driver context
+
+  @retval EFI_SUCCESS         Controller prepared
+  @retval EFI_DEVICE_ERROR    SCL and/or SDA lines are not pulled up
+**/
+EFI_STATUS
+PrepareController (
+  I2C_MASTER_CONTEXT  *Context
+  );
+
+/**
+  Determine the state of the I2C controller
+
+  @param[in] Context - driver context
+
+  @retval TRUE              The I2C controller is active
+  @retval FALSE             The I2C controller is idle
+**/
+BOOLEAN
+IsHardwareActive (
+  I2C_MASTER_CONTEXT  *Context
+  );
+
+/**
+  Updates WriteOperation and WritePosition, two variables that determine
+  which part of Request is being committed to I2C bus.
+  This iterates over both Read and Write operations from a request, because
+  things that need to be written to WriteFifo are both I2c bus writes
+  and I2c bus reads (the command to perform bus read needs to be put into Write Fifo)
+
+  @param[in] Context - driver context
+**/
+VOID
+UpdateWritePosition (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  FindReadOp checks if current Operation is of Read type. If so, returns.
+  If not, increases ReadOp until it finds one or goes beyond Request's OperationCount
+
+  @param[in] Context - driver context
+**/
+VOID
+FindReadOp (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Updates ReadOperation and ReadPosition, two variables that determine
+  which part of Request is being filled with data incoming from I2C reads.
+  This iterates only over Read operations from a request.
+
+  @param[in] Context - driver context
+**/
+VOID
+UpdateReadPosition (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  ValidateRequest checks if Request is valid and can be started
+
+  @param[in] Context            driver context
+  @param[in] RequestPacket      content of I2C request package
+
+  @retval EFI_SUCCESS           Request is valid and can be started
+  @retval EFI_ALREADY_STARTED   The controller is busy with another transfer
+  @retval EFI_BAD_BUFFER_SIZE   Transfer size too big
+  @retval EFI_INVALID_PARAMETER RequestPacket is NULL, invalid Operation flags
+  @retval EFI_UNSUPPORTED       10bit I2C address or "ping" operation attempted (0-byte transfer, address byte not followed by any data)
+**/
+EFI_STATUS
+ValidateRequest (
+  I2C_MASTER_CONTEXT           *Context,
+  CONST EFI_I2C_REQUEST_PACKET *RequestPacket
+  );
+
+/**
+  IsLastFromRequest checks if WritePos and WriteOp point to the last byte of the request
+
+  @param[in] Context - driver context
+**/
+BOOLEAN
+IsLastFromRequest (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  IsLastFromRequest checks if WritePos and WriteOp point to the first byte of an operation
+
+  @param[in] Context - driver context
+
+  @retval Boolean
+**/
+BOOLEAN
+IsFirstFromOperation (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  InitializeTransfer checks if HW is ready to accept new transfer.
+  If so, sets up slave address
+
+  @param[in] Context - driver context
+
+  @retval Status
+**/
+EFI_STATUS
+InitializeTransfer (
+  I2C_MASTER_CONTEXT           *Context,
+  UINTN                        SlaveAddress,
+  CONST EFI_I2C_REQUEST_PACKET *RequestPacket
+  );
+
+/**
+  WriteFifo writes to I2c controller's transmit Fifo. Data written to Fifo could be
+  - data bytes to be written to an I2C slave
+  - read requests that trigger I2C bus reads
+  First transfer from each operation adds Restart bit which triggers Restart condition on bus
+  Last transfer from the whole Request adds Stop bit which triggers Stop condtion on bus
+  Driver keeps track of which parts of Request were already committed to hardware using
+  pointer consisting of WritePosition and WriteOperation variables. This pointer is updated
+  every time data byte/read request is committed to FIFO
+  WriteFifo executes while there's anything more to write and the write fifo isn't full
+
+  @param[in] Context - driver context
+**/
+VOID
+WriteFifo (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  ReadFifo reads from I2c controller's receive Fifo. It contains data retrieved
+  from slave device as a result of executing read transfers, which were
+  triggered by putting read requests into Write Fifo. Retrieved data is copied into buffers
+  pointed to by Request structure.
+  Driver keeps track where to copy incoming data using pointer consisting of
+  ReadPosition and ReadOperation variables. This pointer is updated
+  every time data was retrieved from hardware
+  ReadFifo executes while there's data available and receive buffers were not filled
+
+  @param[in] Context - driver context
+**/
+VOID
+ReadFifo (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  CheckErrors checks if there were any transfer errors.
+
+  @param[in] Context - driver context
+**/
+VOID
+CheckErrors (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Transfer is finished when all requested operations were placed in fifo,
+  all read requests were filled and hardware is inactive
+  The last part is necessary for write-only transfers where after
+  placing all writes in fifo sw needs to wait until they flush down the bus
+
+  @param[in] Context - driver context
+
+  @retval Boolean
+**/
+BOOLEAN
+IsTransferFinished (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Clean up Hw activity and errors
+  Return status to Request's submitter and signal the event that tells
+  it that the request is complete
+  Clear up Sw context to allow new request to start
+
+  @param[in] Context - driver context
+**/
+VOID
+FinishTransfer (
+  I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  PerformTransfer. For synchronous transfer this function is called in a loop
+  and for asynchronous transfers, as a timer callback. It writes data and/or
+  read requests to hadrware, copies read data to destination buffers. When
+  transfer completes, it cleans up Sw context and Hw registers in preparation
+  for new transfer
+
+  @param[in] Context - driver context
+**/
+VOID
+PerformTransfer (
+  IN I2C_MASTER_CONTEXT *Context
+  );
+
+/**
+  Set the I2C controller bus clock frequency.
+
+  This routine must be called at or below TPL_NOTIFY.
+
+  The software and controller do a best case effort of using the specified
+  frequency for the I2C bus.  If the frequency does not match exactly then
+  the controller will use lower frequency for the I2C to avoid exceeding
+  the operating conditions for any of the I2C devices on the bus.
+  For example if 400 KHz was specified and the controller's divide network
+  only supports 402 KHz or 398 KHz then the controller would be set to 398
+  KHz.
+
+  @param[in] MmioAddress    Address of I2C controller
+  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
+
+  @retval EFI_SUCCESS       The bus frequency was set successfully.
+  @retval EFI_UNSUPPORTED   The controller does not support this frequency.
+**/
+
+EFI_STATUS
+FrequencySet (
+  IN UINTN     MmioAddress,
+  IN OUT UINTN *BusClockHertz
+  );
+
+/**
+  Reset the I2C controller
+
+  @param[in] MmioAddress    Address of I2C controller
+
+  @retval Status
+**/
+EFI_STATUS
+I2cReset (
+  IN UINTN     MmioAddress
+  );
+
+#endif // _I2C_MASTER_COMMON_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
new file mode 100644
index 0000000000..d17b65c598
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
@@ -0,0 +1,344 @@
+/** @file
+  Header file for PchDmiLib.
+
+  Copyright (c) 2019 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
+  );
+
+/**
+  Set ACPI base address decoding in DMI
+
+  @param[in] Address                    Address for ACPI base.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetAcpiBase (
+  IN  UINT16                            Address
+  );
+
+/**
+  Set PWRM base address decoding in DMI
+
+  @param[in] Address                    Address for PWRM base.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetPwrmBase (
+  IN  UINT32                            Address
+  );
+
+/**
+  Set PCH TCO base address decoding in DMI
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetTcoBase (
+  IN  UINT16                            Address
+  );
+
+/**
+  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
+  );
+
+/**
+  Clear PCH LPC/eSPI generic IO range decoding in DMI
+
+  @param[in] RangeIndex                 Index of chosen range
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearLpcGenIoRange (
+  IN  UINTN                             RangeIndex
+  );
+
+/**
+  Clear PCH eSPI CS1# generic IO range decoding in DMI
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearEspiCs1GenIoRange (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port in DMI
+
+  @param[in] RpNumber                   PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchDmiSetIoPort80Decode (
+  IN  UINTN                             RpNumber
+  );
+
+/**
+  Set DMI thermal throttling to recommended configuration
+**/
+VOID
+PchDmiSetRecommendedThermalThrottling (
+  VOID
+  );
+
+//
+// Thermal Sensor Target Width structure
+// Look at DMI_THERMAL_SENSOR_TARGET_WIDTH for possible values
+//
+typedef struct {
+  UINT32  ThermalSensor0TargetWidth :3;
+  UINT32  ThermalSensor1TargetWidth :3;
+  UINT32  ThermalSensor2TargetWidth :3;
+  UINT32  ThermalSensor3TargetWidth :3;
+  UINT32  Rsvd                      :20;
+} DMI_THERMAL_THROTTLING;
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmiSetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  );
+
+/**
+  Determines where to send the reserved page registers
+  Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Port
+  with the destination ID specified in GCS.RPRDID using DMI source decode.
+**/
+VOID
+PchDmiSetReservedPageRegToPcieRootPort (
+  VOID
+  );
+
+/**
+  Determines where to send the reserved page registers
+  DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cycles hitting these ranges will
+  end up in P2SB which will then forward the cycle to LPC or eSPI through IOSF Sideband.
+**/
+VOID
+PchDmiSetReservedPageRegToLpc (
+  VOID
+  );
+
+/**
+  uCode Patch Region Enable (UPRE). Enables memory access targeting the uCode patch region (0xFEF00000 to 0xFEFFFFFF)
+  to be forwarded to SPI Flash. This can only be set if the boot flash is on SPI.
+**/
+VOID
+PchDmiEnableUCodePatchRegion (
+  VOID
+  );
+
+/**
+  Enable PCIe Relaxed Order
+**/
+VOID
+PchDmiEnablePcieRelaxedOrder (
+  VOID
+  );
+
+/**
+  This function will switch SAI value to be driven to IOSF Primary Fabric
+  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
+  To be used when PCH is paired with CFL CPU.
+**/
+VOID
+PchDmiEnablePostBootSai (
+  VOID
+  );
+
+/**
+  This function will do necessary configuration after platform
+  should have switched to POSTBOOT_SAI. It needs to be called even if
+  POSTBOOT_SAI was not set.
+**/
+VOID
+PchDmiConfigAfterPostBootSai (
+  VOID
+  );
+
+/**
+  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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
new file mode 100644
index 0000000000..e53ed881df
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
@@ -0,0 +1,56 @@
+/** @file
+  This library provides PCH HD Audio functions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_LIB_H_
+#define _PCH_HDA_LIB_H_
+
+#include <Private/Library/DxePchHdaNhlt.h>
+#include <Private/PchHdaEndpoints.h>
+
+/**
+  Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload Engine Driver) Configuration Table).
+
+  @param[in] *NhltAcpiTable    The NHLT table to print
+**/
+VOID
+NhltAcpiTableDump(
+  IN NHLT_ACPI_TABLE           *NhltTable
+  );
+
+/**
+  Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
+
+  @param[in][out] *NhltTable            NHLT table for which header will be created
+  @param[in]      NhltTableSize         Size of NHLT table
+
+  @retval None
+**/
+VOID
+NhltAcpiHeaderConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable,
+  IN UINT32                     NhltTableSize
+  );
+
+/**
+  Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
+
+  @param[in]      *EndpointTable List of endpoints for NHLT
+  @param[in][out] **NhltTable    NHLT table to be created
+  @param[in][out] *NhltTableSize Size of created NHLT table
+
+  @retval EFI_SUCCESS            NHLT created successfully
+  @retval EFI_BAD_BUFFER_SIZE    Not enough resources to allocate NHLT
+**/
+EFI_STATUS
+NhltConstructor(
+  IN PCH_HDA_NHLT_ENDPOINTS    *EndpointTable,
+  IN OUT NHLT_ACPI_TABLE       **NhltTable,
+  IN OUT UINT32                *NhltTableSize
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h
new file mode 100644
index 0000000000..6d71504772
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h
@@ -0,0 +1,100 @@
+/** @file
+  Header file for PCH Init Common Lib
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_COMMON_LIB_H_
+#define _PCH_INIT_COMMON_LIB_H_
+
+#include <Library/PchPcrLib.h>
+
+/**
+  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] RpPort             Root Port Number
+
+  @retval PCH_SBI_PID    Returns PID for SBI Access
+**/
+PCH_SBI_PID
+GetRpSbiPid (
+  IN  UINTN  RpPort
+  );
+
+/**
+  Calculate root port device number based on physical port index.
+
+  @param[in]  RpIndex              Root port index (0-based).
+
+  @retval     Root port device number.
+**/
+UINT32
+PchGetPcieRpDevice (
+  IN  UINT32   RpIndex
+  );
+
+/**
+  This function reads Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[out] *Data32             Value of Config register
+
+  @retval EFI_SUCCESS             SBI Read successful.
+**/
+EFI_STATUS
+PchSbiRpPciRead32 (
+  IN    UINT32  RpIndex,
+  IN    UINT32  Offset,
+  OUT   UINT32  *Data32
+  );
+
+/**
+  This function And then Or Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[in]  Data32And           Value of Config register to be And-ed
+  @param[in]  Data32AOr           Value of Config register to be Or-ed
+
+  @retval EFI_SUCCESS             SBI Read and Write successful.
+**/
+EFI_STATUS
+PchSbiRpPciAndThenOr32 (
+  IN  UINT32  RpIndex,
+  IN  UINT32  Offset,
+  IN  UINT32  Data32And,
+  IN  UINT32  Data32Or
+  );
+
+/**
+  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
+PrintRegisters (
+  IN  UINTN        PrintMmioBase,
+  IN  UINT32       PrintSize,
+  IN  UINT32       OffsetFromBase
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h
new file mode 100644
index 0000000000..b0e4eb64c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h
@@ -0,0 +1,371 @@
+/** @file
+  Header file for PCH PCI Express helpers library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIB_H_
+#define _PCH_PCI_EXPRESS_HELPERS_LIB_H_
+
+#include <PchPolicyCommon.h>
+
+typedef enum {
+  TpoScale2us,
+  TpoScale10us,
+  TpoScale100us,
+  TpoScaleMax
+} T_PO_SCALE;
+
+typedef struct {
+  UINT32     Value;
+  T_PO_SCALE Scale;
+} T_POWER_ON;
+
+//
+// Function prototypes
+//
+
+/**
+  Get PCIe port number for enabled port.
+  @param[in] RpBase    Root Port pci segment base address
+  @return 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
+  );
+
+/**
+  Translate PCIe Port/Lane pair to 0-based PCIe lane number.
+
+  @param[in] RpIndex    Root Port index
+  @param[in] RpLane     Root Port Lane (0-3)
+
+  @retval PCIe lane number (0-based)
+**/
+UINT32
+PchPciePhysicalLane (
+  UINT32 RpIndex,
+  UINT32 RpLane
+  );
+
+/**
+  Checks if lane reversal is enabled on a given root port
+
+  @param[in] RpIndex  Root port index (0-based)
+
+  @retval TRUE if lane reversal is enbabled, FALSE otherwise
+**/
+BOOLEAN
+IsPcieLaneReversalEnabled (
+  IN     UINT32  RpIndex
+  );
+
+/**
+  Calculates the index of the first port on the same controller.
+
+  @param[in] RpIndex     Root Port Number (0-based)
+
+  @retval Index of the first port on the first controller.
+**/
+UINT32
+PchGetPcieFirstPortIndex (
+  IN     UINT32  RpIndex
+  );
+
+/*
+  Returns Tpower_on capability of device
+
+  @param[in] DeviceBase       device's PCI segment base address
+  @param[in] L1ssCapOffset    offset to L1substates capability in device's extended config space
+
+  @retval                     structure containing Tpoweron scale and value
+*/
+T_POWER_ON
+GetTpoCapability (
+  UINT64 DeviceBase,
+  UINT32 L1ssCapOffset
+  );
+
+/*
+  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
+  );
+
+/**
+  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
+
+  @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] 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
+*/
+VOID
+RetrainLink (
+  UINT64  Base,
+  UINT8   PcieCapOffset,
+  BOOLEAN WaitUntilDone
+  );
+
+/*
+  Checks if device at given address exists
+
+  @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
+  );
+
+/*
+  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
+  );
+
+/*
+  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] 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,
+  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
+  UINT32                    AspmOverrideTableSize,
+  PCH_PCIE_DEVICE_OVERRIDE  *AspmOverrideTable
+  );
+
+/**
+  Get current PCIe link speed.
+
+  @param[in] RpBase    Root Port base address
+  @return Link speed
+**/
+UINT32
+GetLinkSpeed (
+  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
+GetMaxLinkSpeed (
+  UINT64 RpBase
+  );
+
+/**
+  PCIe controller configuration.
+**/
+typedef enum {
+  Pcie4x1      = 0,
+  Pcie1x2_2x1  = 1,
+  Pcie2x2      = 2,
+  Pcie1x4      = 3
+} PCIE_CONTROLLER_CONFIG;
+
+#endif // _PEI_DXE_SMM_PCH_PCI_EXPRESS_HELPERS_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h
new file mode 100644
index 0000000000..9e68615717
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h
@@ -0,0 +1,578 @@
+/** @file
+  Header file for PchPsfPrivateLib.
+
+  Copyright (c) 2019 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/PchRegsPcr.h>
+
+//
+// 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
+  );
+
+/**
+  Return PSF_PORT for SerialIO I2C device
+
+  @param[in] I2cNum  Serial IO I2C device (I2C0, I2C1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO I2C device
+**/
+PSF_PORT
+PsfSerialIoI2cPort (
+  IN UINT32  I2cNum
+  );
+
+/**
+  Return PSF_PORT for SerialIO SPI device
+
+  @param[in] SpiNum  Serial IO SPI device (SPI0, SPI1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO SPI device
+**/
+PSF_PORT
+PsfSerialIoSpiPort (
+  IN UINT32  SpiNum
+  );
+
+/**
+  Return PSF_PORT for SerialIO UART device
+
+  @param[in] UartNum  Serial IO UART device (UART0, UART1, ....)
+
+  @retval  PsfPort    PSF PORT structure for SerialIO UART device
+**/
+PSF_PORT
+PsfSerialIoUartPort (
+  IN UINT32  UartNum
+  );
+
+/**
+  This procedure will set BARx value for TraceHub ACPI device at PSF level
+
+  @param[in] BarNum          BAR Number (0:BAR0, 1:BAR1)
+  @param[in] BarValue        32bit BAR value
+**/
+VOID
+PsfSetTraceHubAcpiDeviceBarValue (
+  IN UINT8   BarNum,
+  IN UINT32  BarValue
+  );
+
+/**
+  This procedure will enable MSE for TraceHub ACPI device at PSF level
+**/
+VOID
+PsfEnableTraceHubAcpiDeviceMemorySpace (
+  VOID
+  );
+
+/**
+  Enable HECI device at PSF level
+
+  @param[in] HeciDevice       HECIx Device (HECI1-4)
+**/
+VOID
+PsfEnableHeciDevice (
+  IN UINT8      HeciDevice
+  );
+
+/**
+  Disable HECI device at PSF level
+
+  @param[in] HeciDevice       HECIx Device (HECI1-4)
+**/
+VOID
+PsfDisableHeciDevice (
+  IN UINT8      HeciDevice
+  );
+
+/**
+  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 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 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
+  );
+
+typedef enum {
+  PsfPcieCtrl4x1,
+  PsfPcieCtrl1x2_2x1,
+  PsfPcieCtrl2x2,
+  PsfPcieCtrl1x4
+} 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
+  );
+
+/**
+  Program PSF EOI Multicast configuration for ITSS
+**/
+VOID
+PsfConfigurEoiForItss (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  Configure PSF power management.
+  Must be called after all PSF configuration is completed.
+**/
+VOID
+PsfConfigurePowerManagement (
+  VOID
+  );
+
+/**
+  Enable VTd support in PSF.
+**/
+VOID
+PchPsfEnableVtd (
+  VOID
+  );
+
+/**
+  Disable PSF address-based peer-to-peer decoding.
+**/
+VOID
+PchPsfDisableP2pDecoding (
+  VOID
+  );
+
+/**
+  Perform registers programming required for
+  Management Component Transport Protocol Broadcast Cycle.
+
+  Agent Destination Addresses are being programmed only when adequate
+  PCIe root port controllers are function enabled.
+
+  Function sets CSME PMT as a message broadcaster and programs the targets
+  of the message in registers only if adequate PCIe root port controllers
+  are function enabled. Conditionally, if the CPU PEG exist and is function
+  enabled, DMI is also a target.
+**/
+VOID
+PsfConfigureMctpCycle (
+  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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h
new file mode 100644
index 0000000000..313b13060f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h
@@ -0,0 +1,98 @@
+/** @file
+  PCH Smbus Protocol
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SMBUS_COMMON_LIB_H
+#define _PCH_SMBUS_COMMON_LIB_H
+
+//
+// Definitions
+//
+#define SMBUS_NUM_RESERVED          38      ///< Number of device addresses that are reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP           0xC2 >> 1
+#define SMBUS_DATA_PREPARE_TO_ARP   0x01
+#define SMBUS_DATA_RESET_DEVICE     0x02
+#define SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define SMBUS_DATA_ASSIGN_ADDRESS   0x04
+#define SMBUS_GET_UDID_LENGTH       17      ///< 16 byte UDID + 1 byte address
+//
+// Private data and functions
+//
+
+#define PCH_SMBUS_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('p', 's', 'm', 'b')
+
+/**
+  This function provides a standard way to read PCH Smbus IO registers.
+
+  @param[in] Offset               Register offset from Smbus base IO address.
+
+  @retval UINT8                   Returns data read from IO.
+**/
+UINT8
+SmbusIoRead (
+  IN      UINT8           Offset
+  );
+
+/**
+  This function provides a standard way to write PCH Smbus IO registers.
+
+  @param[in] Offset               Register offset from Smbus base IO address.
+  @param[in] Data                 Data to write to register.
+
+**/
+VOID
+SmbusIoWrite (
+  IN      UINT8           Offset,
+  IN      UINT8           Data
+  );
+
+/**
+  This function provides a standard way to execute Smbus protocols
+  as defined in the SMBus Specification. The data can either be of
+  the Length byte, word, or a block of data. The resulting transaction will be
+  either the SMBus Slave Device accepts this transaction or this function
+  returns with an error
+
+  @param[in] SlaveAddress         Smbus Slave device the command is directed at
+  @param[in] Command              Slave Device dependent
+  @param[in] Operation            Which SMBus protocol will be used
+  @param[in] PecCheck             Defines if Packet Error Code Checking is to be used
+  @param[in, out] Length          How many bytes to read. Must be 0 <= Length <= 32 depending on Operation
+                                  It will contain the actual number of bytes read/written.
+  @param[in, out] Buffer          Contain the data read/written.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @exception EFI_UNSUPPORTED      The operation is unsupported.
+
+  @retval EFI_INVALID_PARAMETER   Length or Buffer is NULL for any operation besides
+                                  quick read or quick write.
+  @retval EFI_TIMEOUT             The transaction did not complete within an internally
+                                  specified timeout period, or the controller is not
+                                  available for use.
+  @retval EFI_DEVICE_ERROR        There was an Smbus error (NACK) during the operation.
+                                  This could indicate the slave device is not present
+                                  or is in a hung condition.
+**/
+EFI_STATUS
+SmbusExec (
+  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN      EFI_SMBUS_DEVICE_COMMAND  Command,
+  IN      EFI_SMBUS_OPERATION       Operation,
+  IN      BOOLEAN                   PecCheck,
+  IN OUT  UINTN                     *Length,
+  IN OUT  VOID                      *Buffer
+  );
+
+/**
+  This function initializes the Smbus Registers.
+
+**/
+VOID
+InitializeSmbusRegisters (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..0a973a77a3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h
@@ -0,0 +1,366 @@
+/** @file
+  Header file for the PCH SPI Common Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_COMMON_LIB_H_
+#define _PCH_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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h
new file mode 100644
index 0000000000..301ec3dd48
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h
@@ -0,0 +1,25 @@
+/** @file
+  This file contains PEI DMI methods
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_DMI_LIB_H_
+#define _PEI_PCH_DMI_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+//
+// Data structure definitions
+//
+typedef enum {
+  DmiVcTypeVc0,
+  DmiVcTypeVc1,
+  DmiVcTypeVcm,
+  DmiVcTypeMax
+} PCH_DMI_VC_TYPE;
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h
new file mode 100644
index 0000000000..44e7567e0f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h
@@ -0,0 +1,706 @@
+/** @file
+  Header file for private PmcLib.
+
+  Copyright (c) 2019 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/PchRegsPmc.h>
+
+/**
+  Send PMC IPC1 Normal Read/Write command
+
+  @param[in]  Command           Command to be issued to PMC IPC 1 interface
+  @param[in]  SubCmdId          SUB_CMD_ID for provided Command
+  @param[in]  CmdSize           Total size in byte to be sent via PMC IPC 1 interface
+  @param[in]  WriteBufPtr       Pointer to Structure of 4 DWORDs to be issued to PMC IPC 1 interface
+  @param[out] ReadBufPtr        Pointer to Structure of 4 DWORDs to be filled by PMC IPC 1 interface
+
+  @retval EFI_SUCCESS             Command was executed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid command size
+  @retval EFI_DEVICE_ERROR        IPC command failed with an error
+  @retval EFI_TIMEOUT             IPC command did not complete after 1s
+**/
+EFI_STATUS
+PmcSendCommand (
+  IN  UINT8                    Command,
+  IN  UINT8                    SubCmdId,
+  IN  UINT8                    CmdSize,
+  IN  PMC_IPC_COMMAND_BUFFER   *WriteBufPtr,
+  OUT PMC_IPC_COMMAND_BUFFER   *ReadBufPtr
+  );
+
+/**
+  Set PCH ACPI base address.
+  The Address should not be 0 and should be 256 bytes alignment, and it is IO space, so must not exceed 0xFFFF.
+
+  @param[in] Address                    Address for ACPI base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PmcSetAcpiBase (
+  IN  UINT16                            Address
+  );
+
+/**
+  Set PCH PWRM base address.
+  Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for PWRMBASE
+
+  @param[in] Address                    Address for PWRM base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PmcSetPwrmBase (
+  IN  UINT32                            Address
+  );
+
+/**
+  This function checks if function disable (static and non-static power gating)
+  configuration is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsFunctionDisableConfigLocked (
+  VOID
+  );
+
+/**
+  This function locks static power gating configuration with S3 Boot Script programming
+**/
+VOID
+PmcLockFunctionDisableConfigWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function checks if ISH is function disabled
+  by static power gating
+
+  @retval ISH device state
+**/
+BOOLEAN
+PmcIsIshFunctionDisabled (
+  VOID
+  );
+
+/**
+  This function checks if ISH device is supported (not disabled by fuse)
+
+  @retval ISH support state
+**/
+BOOLEAN
+PmcIsIshSupported (
+  VOID
+  );
+
+/**
+  This function disables ISH device by static power gating
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableIsh (
+  VOID
+  );
+
+/**
+  This function enables ISH device by disabling static power gating
+**/
+VOID
+PmcEnableIsh (
+  VOID
+  );
+
+/**
+  This function enables GBE ModPHY SPD gating.
+**/
+VOID
+PmcGbeModPhyPowerGating (
+  VOID
+  );
+
+/**
+  This function checks if GbE is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsGbeFunctionDisabled (
+  VOID
+  );
+
+/**
+  This function disables GbE device by static power gating
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableGbe (
+  VOID
+  );
+
+/**
+  This function enables GbE device by disabling static power gating
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableGbe (
+  VOID
+  );
+
+/**
+  This function checks if GbE device is supported (not disabled by fuse)
+
+  @retval GbE support state
+**/
+BOOLEAN
+PmcIsGbeSupported (
+  VOID
+  );
+
+/**
+  This function enables all SerailIo devices
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableSerialIo (
+  VOID
+  );
+
+/**
+  This function disables (static power gating) all SerailIo devices.
+  For SerialIo controllers they can be power gated only if all of them are to be disabled.
+  They cannot be statically power gated separately.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableSerialIo (
+  VOID
+  );
+
+/**
+  This function checks if all SerialIo devices are statically disabled (static power gating)
+
+  @retval SerialIo disable state
+**/
+BOOLEAN
+PmcIsSerialIoStaticallyDisabled (
+  VOID
+  );
+
+/**
+  This function checks if SerialIo device is supported (not disabled by fuse)
+
+  @retval SerialIo support state
+**/
+BOOLEAN
+PmcIsSerialIoSupported (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) HDA device
+**/
+VOID
+PmcDisableHda (
+  VOID
+  );
+
+/**
+  This function checks if Cnvi device is supported (not disabled by fuse)
+
+  @retval Cnvi support state
+**/
+BOOLEAN
+PmcIsCnviSupported (
+  VOID
+  );
+
+/**
+  This function checks if CNVi is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsCnviFunctionDisabled (
+  VOID
+  );
+
+/**
+  This function enables CNVi device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableCnvi (
+  VOID
+  );
+
+/**
+  This function disables CNVi device by static power gating
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableCnvi (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) PCIe Root Port
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+**/
+VOID
+PmcDisablePcieRootPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  This function disables (non-static power gating) SATA
+
+  @param[in]  SataCtrlIndex     SATA controller index
+**/
+VOID
+PmcDisableSata (
+  IN UINT32     SataCtrlIndex
+  );
+
+/**
+  This function checks if SATA device is supported (not disabled by fuse)
+
+  @param[in] SataCtrlIndex SATA controller index
+
+  @retval SATA support state
+**/
+BOOLEAN
+PmcIsSataSupported (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  This function gets NMI regsiter.
+
+  @retval  NMI register setting
+**/
+UINT32
+PmcGetNmiControl (
+  VOID
+  );
+
+/**
+  This function sets the NMI register
+
+  @param[in]  NmiRegister    The whole NMI register
+**/
+VOID
+PmcSetNmiControl (
+  UINT32   NmiRegister
+  );
+
+/**
+  This function disables (non-static power gating) xHCI
+**/
+VOID
+PmcDisableXhci (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) XDCI
+**/
+VOID
+PmcDisableXdci (
+  VOID
+  );
+
+/**
+  This function checks if XDCI device is supported (not disabled by fuse)
+
+  @retval XDCI support state
+**/
+BOOLEAN
+PmcIsXdciSupported (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) SCS eMMC controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsEmmc (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) SCS SD Card controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsSdCard (
+  VOID
+  );
+
+/**
+  This function disables (non-static power gating) SCS UFS controller and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in] UfsNum     SCS UFS Device
+**/
+VOID
+PmcDisableScsUfs (
+  IN UINT32   UfsNum
+  );
+
+/**
+  This function checks if SCS eMMC device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsEmmcSupported (
+  VOID
+  );
+
+/**
+  This function checks if SCS SD Card device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsSdCardSupported (
+  VOID
+  );
+
+/**
+  This function checks if SCS UFS device is supported (not disabled by fuse)
+
+  @param[in] UfsNum     SCS UFS Device
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsUfsSupported (
+  IN UINT32   UfsNum
+  );
+
+
+/**
+  This function locks HOST SW power gating control
+**/
+VOID
+PmcLockHostSwPgCtrl (
+  VOID
+  );
+
+/**
+  This function checks if HOST SW Power Gating Control is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsHostSwPgCtrlLocked (
+  VOID
+  );
+
+/**
+  This function disables Trace Hub by enabling power gating
+**/
+VOID
+PmcDisableTraceHub (
+  VOID
+  );
+
+/**
+  This function enables Trace Hub by disabling power gating
+**/
+VOID
+PmcEnableTraceHub (
+  VOID
+  );
+
+/**
+  This function checks if LAN wake from DeepSx is enabled
+
+  @retval Lan Wake state
+**/
+BOOLEAN
+PmcIsLanDeepSxWakeEnabled (
+  VOID
+  );
+
+/**
+  This function locks down PMC (DebugModeLock)
+**/
+VOID
+PmcLockWithS3BootScript (
+  VOID
+  );
+
+/**
+  Checks if conditions for proper USB2 PHY AFE programming are met
+**/
+VOID
+PmcUsb2CorePhyPowerGatingDisable (
+  VOID
+  );
+
+/**
+  This function reads CPU Early Power-on Configuration (EPOC)
+
+  @retval CPU EPOC value
+**/
+UINT32
+PmcGetCpuEpoc (
+  VOID
+  );
+
+/**
+  This function sets CPU Early Power-on Configuration (EPOC)
+
+  @param[in] CpuEpocValue      CPU EPOC value
+**/
+VOID
+PmcSetCpuEpoc (
+  IN UINT32     CpuEpocValue
+  );
+
+/**
+  This function sets DRAM_RESET# Control Pin value
+
+  @param[in] DramResetVal      0: Pin output is low
+                               1: Pin output is tri-stated
+**/
+VOID
+PmcSetDramResetCtlState (
+  IN UINT32     DramResetVal
+  );
+
+/**
+  This function enables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh
+**/
+VOID
+PmcEnableCf9GlobalReset (
+  VOID
+  );
+
+/**
+  This function disables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh.
+**/
+VOID
+PmcDisableCf9GlobalReset (
+  VOID
+  );
+
+/**
+  This 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
+PmcDisableCf9GlobalResetWithLock (
+  VOID
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  This function disables CF9 reset without Resume Well reset.
+  Cf9 0x6/0xE reset will also reset resume well logic.
+**/
+VOID
+PmcDisableCf9ResetWithoutResumeWell (
+  VOID
+  );
+
+/**
+  This function locks PMC Set Strap Message interface with S3 Boot Script programming
+**/
+VOID
+PmcLockSetStrapMsgInterfaceWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function clears RTC Power Failure status (RTC_PWR_FLR)
+**/
+VOID
+PmcClearRtcPowerFailureStatus (
+  VOID
+  );
+
+/**
+  This function enables PCI Express* PME events
+**/
+VOID
+PmcEnablePciExpressPmeEvents (
+  VOID
+  );
+
+/**
+  This function sets SLP_SX Stretching Policy and adds
+  lock setting to S3 Boot Script
+**/
+VOID
+PmcLockSlpSxStretchingPolicyWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function sets SMI Lock with S3 Boot Script programming
+**/
+VOID
+PmcLockSmiWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function sets eSPI SMI Lock
+**/
+VOID
+PmcLockEspiSmi (
+  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
+  );
+
+/**
+  This function sets 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
+PmcSetGpioGpe (
+  IN UINT32    GpeDw0Value,
+  IN UINT32    GpeDw1Value,
+  IN UINT32    GpeDw2Value
+  );
+
+/**
+  This function checks if SCI interrupt is enabled
+
+  @retval SCI Enable state
+**/
+BOOLEAN
+PmcIsSciEnabled (
+  VOID
+  );
+
+/**
+  This function triggers Software GPE
+**/
+VOID
+PmcTriggerSwGpe (
+  VOID
+  );
+
+/**
+  Disable SLP_S0# assertion when system is in debug mode
+**/
+VOID
+PmcDisableSlpS0AssertionInDebugMode (
+  VOID
+  );
+
+/**
+  Enable SLP_S0# assertion even when system is in debug mode
+**/
+VOID
+PmcEnableSlpS0AssertionInDebugMode (
+  VOID
+  );
+
+#endif // _PMC_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h
new file mode 100644
index 0000000000..af5734b74b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h
@@ -0,0 +1,48 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h
new file mode 100644
index 0000000000..f074e0073a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h
@@ -0,0 +1,28 @@
+/** @file
+  Header file for private PCH SMM Lib.
+
+  Copyright (c) 2019 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_
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances

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

Adds package-level library class instances.

* BaseConfigBlockLib - Library functions for config block management.
* BaseSiConfigBlockLib - Library functions for managing component
  config blocks.
* DxeAslUpdateLib - Services to update ACPI tables.
* PeiDxeSmmMmPciLib - Services to manage PCI Express addresses.
* PeiStallPpiLib - Installs an instance of EFI_PEI_STALL_PPI.
* PeiSiPolicyLib - Installs an instance of the Silicon Policy PPI.
  Prints the Silicon Policy PPI values when DEBUG prints are enabled.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf     |  29 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf           |  40 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf   |  30 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf       |  35 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf      |  31 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf             |  51 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h           |  35 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c       | 146 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c   |  87 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c             | 403 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c     | 126 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c         |  32 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c        |  78 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c               | 214 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c         | 122 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c                |  36 ++
 17 files changed, 1528 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
new file mode 100644
index 0000000000..a7def2481d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
@@ -0,0 +1,29 @@
+## @file
+# Component INF file for the BaseConfigBlock library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseConfigBlockLib
+FILE_GUID = 1EC07EA8-7808-4e06-9D79-309AE331D2D5
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = ConfigBlockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+BaseConfigBlockLib.c
+
+[LibraryClasses]
+DebugLib
+BaseMemoryLib
+MemoryAllocationLib
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
new file mode 100644
index 0000000000..b04dc3cfa4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for the BaseSiConfigBlockLib library.
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseSiConfigBlockLib.c
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
new file mode 100644
index 0000000000..658caccb43
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Provides services to update ASL tables.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeAslUpdateLib
+FILE_GUID = 8621697D-4E3A-4bf2-ADB0-3E2FF06559CA
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = AslUpdateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PcdLib
+BaseMemoryLib
+UefiLib
+MemoryAllocationLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeAslUpdateLib.c
+
+
+[Protocols]
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiAcpiSdtProtocolGuid ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
new file mode 100644
index 0000000000..ae78a8e8f9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
@@ -0,0 +1,30 @@
+## @file
+# Provides services to update ASL tables.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeAslUpdateLibNull
+FILE_GUID = C7A3725F-6146-4FAB-B2EF-B4CED222DA52
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = AslUpdateLib
+
+
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeAslUpdateLibNull.c
+
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
new file mode 100644
index 0000000000..fdf376bc70
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the PeiDxeSmmMmPciLib
+#
+# Copyright (c) 2019 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
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+PeiDxeSmmMmPciLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
new file mode 100644
index 0000000000..2e07a90406
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Library description file for Stall Ppi installation
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiStallPpiLib
+FILE_GUID = 73E3DD0E-B2C1-4429-B0B8-F8C2BD64F8CE
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = StallPpiLib
+
+[Sources]
+PeiStallPpiLib.c
+
+[LibraryClasses]
+BaseLib
+DebugLib
+TimerLib
+PeiServicesLib
+
+[Packages]
+MdePkg/MdePkg.dec
+
+[Ppis]
+gEfiPeiStallPpiGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
new file mode 100644
index 0000000000..c5945c3129
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for the PeiSiPolicyLib library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSiPolicyLib
+FILE_GUID = 97584FAE-9299-4202-9889-2D339E4BFA5B
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = SiPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+CpuPolicyLib
+PchPolicyLib
+PeiSaPolicyLib
+PeiMePolicyLib
+PcdLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiSiPolicyLib.c
+PeiSiPolicyLibrary.h
+SiPrintPolicy.c
+PeiSiPolicyLibPreMem.c
+
+
+[Guids]
+gSiConfigGuid        ## CONSUMES
+
+
+[Ppis]
+gSiPolicyPpiGuid       ## PRODUCES
+gSiPreMemPolicyPpiGuid ## PRODUCES
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
new file mode 100644
index 0000000000..cb6b14fdd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
@@ -0,0 +1,35 @@
+/** @file
+  Header file for the PeiSiPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_LIBRARY_H_
+#define _PEI_SI_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/PchPolicyLib.h>
+#include <Library/PeiMePolicyLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <PchAccess.h>
+#include <Library/CpuPolicyLib.h>
+
+#define TEMP_MEM_BASE_ADDRESS 0xFE600000
+#define TEMP_IO_BASE_ADDRESS  0xD000
+
+//
+// IO/MMIO resource limits
+//
+#define TEMP_MEM_SIZE         V_PCH_XDCI_MEM_LENGTH
+#define TEMP_IO_SIZE          0x10
+
+#endif // _PEI_SI_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c
new file mode 100644
index 0000000000..369dab97ee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c
@@ -0,0 +1,146 @@
+/** @file
+  Library functions for Config Block management.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.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
+  )
+{
+  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
+  UINT32                    ConfigBlkTblHdrSize;
+
+  ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
+
+  if (TotalSize <= (ConfigBlkTblHdrSize + sizeof (CONFIG_BLOCK_HEADER))) {
+    DEBUG ((DEBUG_ERROR, "Invalid Parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)AllocateZeroPool (TotalSize);
+  if (ConfigBlkTblAddrPtr == NULL) {
+    DEBUG ((DEBUG_ERROR, "Could not allocate memory.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ConfigBlkTblAddrPtr->NumberOfBlocks = 0;
+  ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength = TotalSize;
+  ConfigBlkTblAddrPtr->AvailableSize = TotalSize - ConfigBlkTblHdrSize;
+
+  *ConfigBlockTableAddress = (VOID *)ConfigBlkTblAddrPtr;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  CONFIG_BLOCK              *TempConfigBlk;
+  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
+  CONFIG_BLOCK              *ConfigBlkAddrPtr;
+  UINT16                    ConfigBlkSize;
+
+  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)ConfigBlockTableAddress;
+  ConfigBlkAddrPtr = (CONFIG_BLOCK *)(*ConfigBlockAddress);
+  ConfigBlkSize = ConfigBlkAddrPtr->Header.GuidHob.Header.HobLength;
+  DEBUG ((DEBUG_INFO, "Config Block GUID: %g / Config Block Size: 0x%x bytes\n", &(ConfigBlkAddrPtr->Header.GuidHob.Name), ConfigBlkSize));
+  if ((ConfigBlkSize % 4) != 0) {
+    DEBUG ((DEBUG_ERROR, "Config Block must be multiples of 4 bytes\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  if (ConfigBlkTblAddrPtr->AvailableSize < ConfigBlkSize) {
+    DEBUG ((DEBUG_ERROR, "Config Block Table is full and cannot add new Config Block.\n"));
+    DEBUG ((DEBUG_ERROR, "Available Config Block Size: 0x%x bytes / Requested Config Block Size: 0x%x bytes\n", ConfigBlkTblAddrPtr->AvailableSize, ConfigBlkSize));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr + (UINTN)(ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength - ConfigBlkTblAddrPtr->AvailableSize));
+  CopyMem (&TempConfigBlk->Header, &ConfigBlkAddrPtr->Header, sizeof(CONFIG_BLOCK_HEADER));
+
+  ConfigBlkTblAddrPtr->NumberOfBlocks++;
+  ConfigBlkTblAddrPtr->AvailableSize = ConfigBlkTblAddrPtr->AvailableSize - ConfigBlkSize;
+
+  *ConfigBlockAddress = (VOID *) TempConfigBlk;
+  DEBUG ((DEBUG_INFO, "Config Block Address: 0x%x / Available Config Block Size: 0x%x bytes\n", (UINT32)(UINTN)*ConfigBlockAddress, ConfigBlkTblAddrPtr->AvailableSize));
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  UINT16                    OffsetIndex;
+  CONFIG_BLOCK              *TempConfigBlk;
+  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
+  UINT32                    ConfigBlkTblHdrSize;
+  UINT32                    ConfigBlkOffset;
+  UINT16                    NumOfBlocks;
+
+  ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
+  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)ConfigBlockTableAddress;
+  NumOfBlocks = ConfigBlkTblAddrPtr->NumberOfBlocks;
+
+  ConfigBlkOffset = 0;
+  for (OffsetIndex = 0; OffsetIndex < NumOfBlocks; OffsetIndex++) {
+    if ((ConfigBlkTblHdrSize + ConfigBlkOffset) > (ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength)) {
+      break;
+    }
+    TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr + (UINTN)ConfigBlkTblHdrSize + (UINTN)ConfigBlkOffset);
+    if (CompareGuid (&(TempConfigBlk->Header.GuidHob.Name), ConfigBlockGuid)) {
+      *ConfigBlockAddress = (VOID *)TempConfigBlk;
+      return EFI_SUCCESS;
+    }
+    ConfigBlkOffset = ConfigBlkOffset + TempConfigBlk->Header.GuidHob.Header.HobLength;
+  }
+  DEBUG ((DEBUG_ERROR, "Could not find the config block.\n"));
+  return EFI_NOT_FOUND;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
new file mode 100644
index 0000000000..16a14b3245
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
@@ -0,0 +1,87 @@
+/** @file
+  This file is BaseSiConfigBlockLib library is used to add config blocks
+  to config block header.
+
+  Copyright (c) 2019 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++) {
+    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/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
new file mode 100644
index 0000000000..04cf66fd2f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
@@ -0,0 +1,403 @@
+/** @file
+  Boot service DXE ASL update library implementation.
+
+  These functions in this file can be called during DXE and cannot be called during runtime
+  or in SMM which should use a RT or SMM library.
+
+  This library uses the ACPI Support protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/AslUpdateLib.h>
+
+//
+// Function implemenations
+//
+static EFI_ACPI_SDT_PROTOCOL      *mAcpiSdt = NULL;
+static EFI_ACPI_TABLE_PROTOCOL    *mAcpiTable = NULL;
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  ///
+  /// Locate ACPI tables
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **) &mAcpiSdt);
+  ASSERT_EFI_ERROR (Status);
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateNameAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER *Table;
+  UINT8                       *CurrPtr;
+  UINT32                      *Signature;
+  UINT8                       *DsdtPointer;
+  UINTN                       Handle;
+  UINT8                       DataSize;
+
+  if (mAcpiTable == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiTable == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+
+  ///
+  /// Locate table with matching ID
+  ///
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+             (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+             &Handle
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ///
+  /// Point to the beginning of the DSDT table
+  ///
+  CurrPtr = (UINT8 *) Table;
+  if (CurrPtr == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Loop through the ASL looking for values that we must fix up.
+  ///
+  for (DsdtPointer = CurrPtr; DsdtPointer < (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+    ///
+    /// Get a pointer to compare for signature
+    ///
+    Signature = (UINT32 *) DsdtPointer;
+    ///
+    /// Check if this is the Device Object signature we are looking for
+    ///
+    if ((*Signature) == AslSignature) {
+      ///
+      /// Look for Name Encoding
+      ///
+      if (*(DsdtPointer-1) == AML_NAME_OP) {
+        ///
+        /// Check if size of new and old data is the same
+        ///
+        DataSize = *(DsdtPointer+4);
+        if ((Length == 1 && DataSize == 0xA) ||
+            (Length == 2 && DataSize == 0xB) ||
+            (Length == 4 && DataSize == 0xC)) {
+          CopyMem (DsdtPointer+5, Buffer, Length);
+        } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+          CopyMem (DsdtPointer+4, Buffer, Length);
+        } else {
+          FreePool (Table);
+          return EFI_BAD_BUFFER_SIZE;
+        }
+        Status = mAcpiTable->UninstallAcpiTable (
+                               mAcpiTable,
+                               Handle
+                               );
+        Handle = 0;
+        Status = mAcpiTable->InstallAcpiTable (
+                               mAcpiTable,
+                               Table,
+                               Table->Length,
+                               &Handle
+                               );
+        FreePool (Table);
+        return Status;
+      }
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This procedure will update the name of ASL Method
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateMethodAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ACPI_DESCRIPTION_HEADER *Table;
+  UINT8                       *CurrPtr;
+  UINT32                      *Signature;
+  UINT8                       *DsdtPointer;
+  UINTN                       Handle;
+
+  if (mAcpiTable == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiTable == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+
+  ///
+  /// Locate table with matching ID
+  ///
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+             (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+             &Handle
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ///
+  /// Point to the beginning of the DSDT table
+  ///
+  CurrPtr = (UINT8 *) Table;
+  if (CurrPtr == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Loop through the ASL looking for values that we must fix up.
+  ///
+  for (DsdtPointer = CurrPtr; DsdtPointer < (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+    ///
+    /// Get a pointer to compare for signature
+    ///
+    Signature = (UINT32 *) DsdtPointer;
+    ///
+    /// Check if this is the Device Object signature we are looking for
+    ///
+    if ((*Signature) == AslSignature) {
+      ///
+      /// Look for Name Encoding
+      ///
+      if ((*(DsdtPointer-3) == AML_METHOD_OP)
+         || (*(DsdtPointer-2) == AML_METHOD_OP)
+         )
+      {
+        CopyMem (DsdtPointer, Buffer, Length);
+        Status = mAcpiTable->UninstallAcpiTable (
+                               mAcpiTable,
+                               Handle
+                               );
+        Handle = 0;
+        Status = mAcpiTable->InstallAcpiTable (
+                               mAcpiTable,
+                               Table,
+                               Table->Length,
+                               &Handle
+                               );
+        FreePool (Table);
+        return Status;
+      }
+    }
+  }
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI table.
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+
+  @param[in] Signature           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in, out] Table          - Updated with a pointer to the table
+  @param[in, out] Handle         - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  EFI_STATUS                  Status;
+  INTN                        Index;
+  EFI_ACPI_TABLE_VERSION      Version;
+  EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+  if (mAcpiSdt == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiSdt == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+
+  ///
+  /// Locate table with matching ID
+  ///
+  Version = 0;
+  Index = 0;
+  do {
+    Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+    if (Status == EFI_NOT_FOUND) {
+      break;
+    }
+    ASSERT_EFI_ERROR (Status);
+    Index++;
+  } while (OrgTable->Signature != Signature);
+
+  if (Status != EFI_NOT_FOUND) {
+    *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
+    ASSERT (*Table);
+  }
+
+  ///
+  /// If we found the table, there will be no error.
+  ///
+  return Status;
+}
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
+
+  @param[in] TableId           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize       - Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                 will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table        - Updated with a pointer to the table
+  @param[in, out] Handle       - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  EFI_STATUS                  Status;
+  INTN                        Index;
+  EFI_ACPI_TABLE_VERSION      Version;
+  EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+  if (mAcpiSdt == NULL) {
+    InitializeAslUpdateLib ();
+    if (mAcpiSdt == NULL) {
+      return EFI_NOT_READY;
+    }
+  }
+  ///
+  /// Locate table with matching ID
+  ///
+  Version = 0;
+  Index = 0;
+  do {
+    Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+    if (Status == EFI_NOT_FOUND) {
+      break;
+    }
+    ASSERT_EFI_ERROR (Status);
+    Index++;
+  } while (CompareMem (&(OrgTable->OemTableId), TableId, TableIdSize));
+
+  if (Status != EFI_NOT_FOUND) {
+    *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
+    ASSERT (*Table);
+  }
+
+  ///
+  /// If we found the table, there will be no error.
+  ///
+  return Status;
+}
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer          Pointer to buffer to checksum
+  @param[in] Size            Number of bytes to checksum
+  @param[in] ChecksumOffset  Offset to place the checksum result in
+
+  @retval EFI_SUCCESS        The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  )
+{
+  UINT8 Sum;
+  UINT8 *Ptr;
+
+  Sum = 0;
+  ///
+  /// Initialize pointer
+  ///
+  Ptr = Buffer;
+
+  ///
+  /// set checksum to 0 first
+  ///
+  Ptr[ChecksumOffset] = 0;
+
+  ///
+  /// add all content of buffer
+  ///
+  while (Size--) {
+    Sum = (UINT8) (Sum + (*Ptr++));
+  }
+  ///
+  /// set checksum
+  ///
+  Ptr                 = Buffer;
+  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c
new file mode 100644
index 0000000000..a7ce92b7c3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c
@@ -0,0 +1,126 @@
+/** @file
+  Boot service DXE ASL update library implementation.
+
+  These functions in this file can be called during DXE and cannot be called during runtime
+  or in SMM which should use a RT or SMM library.
+
+  This library uses the ACPI Support protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/AslUpdateLib.h>
+
+//
+// Function implemenations
+//
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI table.
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+
+  @param[in] Signature           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in, out] Table          - Updated with a pointer to the table
+  @param[in, out] Handle         - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
+
+  @param[in] TableId           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize       - Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                 will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table        - Updated with a pointer to the table
+  @param[in, out] Handle       - AcpiSupport protocol table handle for the table found
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer          Pointer to buffer to checksum
+  @param[in] Size            Number of bytes to checksum
+  @param[in] ChecksumOffset  Offset to place the checksum result in
+
+  @retval EFI_SUCCESS        The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
new file mode 100644
index 0000000000..5085f29d6d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
@@ -0,0 +1,32 @@
+/** @file
+  This file contains routines that get PCI Express Address
+
+  Copyright (c) 2019 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
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+  )
+{
+  ASSERT ((Bus <= 0xFF) && (Device <= 0x1F) && (Function <= 0x7));
+
+  return ((UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c
new file mode 100644
index 0000000000..d462aef407
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c
@@ -0,0 +1,78 @@
+/** @file
+  Library to install StallPpi.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Ppi/Stall.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PeiServicesLib.h>
+
+#define PEI_STALL_RESOLUTION   1
+
+/**
+  This function provides a blocking stall for reset at least the given number of microseconds
+  stipulated in the final argument.
+
+  @param  PeiServices General purpose services available to every PEIM.
+  @param  this Pointer to the local data for the interface.
+  @param  Microseconds number of microseconds for which to stall.
+
+  @retval  EFI_SUCCESS the function provided at least the required stall.
+**/
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  );
+
+
+EFI_PEI_STALL_PPI   mStallPpi = {
+  PEI_STALL_RESOLUTION,
+  Stall
+};
+
+EFI_PEI_PPI_DESCRIPTOR    mPeiInstallStallPpi = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiStallPpiGuid,
+  &mStallPpi
+};
+
+EFI_STATUS
+EFIAPI
+Stall (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN CONST EFI_PEI_STALL_PPI  *This,
+  IN UINTN                    Microseconds
+  )
+{
+  MicroSecondDelay (Microseconds);
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will install the StallPpi.
+
+  @retval EFI_SUCCESS if StallPpi is installed successfully.
+**/
+EFI_STATUS
+EFIAPI
+InstallStallPpi (
+  VOID
+  )
+{
+  EFI_STATUS   Status;
+
+  DEBUG((DEBUG_INFO, "Installing StallPpi \n"));
+
+  Status = PeiServicesInstallPpi (&mPeiInstallStallPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
new file mode 100644
index 0000000000..de8d9745d3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
@@ -0,0 +1,214 @@
+/** @file
+  This file is PeiSiPolicyLib library creates default settings of RC
+  Policy and installs RC Policy PPI.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyLibrary.h"
+#include <Library/PcdLib.h>
+
+/**
+  Get Si config block table total size.
+
+  @retval                               Size of PCH config block table
+**/
+UINT16
+EFIAPI
+SiGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return (UINT16) sizeof (SI_CONFIG);
+}
+
+EFI_STATUS
+EFIAPI
+LoadSiConfigBlockDefault (
+  IN VOID *ConfigBlockPointer
+  )
+{
+  SI_CONFIG                         *SiConfig;
+
+  SiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Name = %g\n", &SiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SiConfig->Header.GuidHob.Header.HobLength));
+
+  SiConfig->Header.Revision = SI_CONFIG_REVISION;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SiAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  VOID                 *ConfigBlockPointer;
+  EFI_STATUS           Status;
+  CONFIG_BLOCK_HEADER  SiBlock;
+
+  //
+  // Initalize SiBlock
+  //
+  CopyMem (&(SiBlock.GuidHob.Name), &gSiConfigGuid, sizeof (EFI_GUID));
+  SiBlock.GuidHob.Header.HobLength = sizeof (SI_CONFIG);
+  SiBlock.Revision                 = SI_CONFIG_REVISION;
+  //
+  // Initialize ConfigBlockPointer
+  //
+  ConfigBlockPointer = (VOID *)&SiBlock;
+  //
+  // Add config block fro SiBlock
+  //
+  DEBUG ((DEBUG_INFO, "gSiConfigGuid = %g\n", &gSiConfigGuid));
+  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Name = %g\n", &(SiBlock.GuidHob.Name)));
+  Status = AddConfigBlock (ConfigBlockTableAddress, (VOID *) &ConfigBlockPointer);
+  ASSERT_EFI_ERROR (Status);
+
+  LoadSiConfigBlockDefault ((VOID *) ConfigBlockPointer);
+
+  return Status;
+}
+
+/**
+  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreateConfigBlocks (
+  OUT  SI_POLICY_PPI **SiPolicyPpi
+  )
+{
+  UINT16        TotalBlockSize;
+  EFI_STATUS    Status;
+  SI_POLICY_PPI *SiPolicy;
+  UINT16        RequiredSize;
+
+  SiPolicy = NULL;
+  //
+  // TotalBlockSize = Si, Pch, ME, SA and CPU config block size.
+  //
+  TotalBlockSize = SiGetConfigBlockTotalSize () +
+                   PchGetConfigBlockTotalSize () +
+                   MeGetConfigBlockTotalSize () +
+                   SaGetConfigBlockTotalSize () +
+                   CpuGetConfigBlockTotalSize ();
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *) &SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // General initialization
+  //
+  SiPolicy->TableHeader.Header.Revision = SI_POLICY_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status = SiAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = PchAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = MeAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = SaAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = CpuAddConfigBlocks ((VOID *) SiPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *SiPolicyPpi = SiPolicy;
+  return Status;
+}
+
+/**
+  Print out all silicon policy information.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval none
+**/
+VOID
+DumpSiPolicy (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  )
+{
+  //
+  // Print SI config blocks and serial out.
+  //
+  SiPrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print PCH config blocks and serial out.
+  //
+  PchPrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print ME config blocks and serial out.
+  //
+  MePrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print SA config blocks and serial out.
+  //
+  SaPrintPolicyPpi (SiPolicyPpi);
+  //
+  // Print CPU config block and serial out.
+  //
+  CpuPrintPolicy (SiPolicyPpi);
+}
+
+/**
+  SiInstallPolicyPpi installs SiPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiInstallPolicyPpi (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  )
+{
+  EFI_STATUS             Status;
+  EFI_PEI_PPI_DESCRIPTOR *SiPolicyPpiDesc;
+  SI_CONFIG              *SiConfig;
+
+  SiPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  if (SiPolicyPpiDesc == NULL) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SiPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  SiPolicyPpiDesc->Guid  = &gSiPolicyPpiGuid;
+  SiPolicyPpiDesc->Ppi   = SiPolicyPpi;
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "Dump Silicon Policy update by Platform...\n"));
+  DumpSiPolicy (SiPolicyPpi);
+
+  //
+  // Install Silicon Policy PPI
+  //
+  Status = PeiServicesInstallPpi (SiPolicyPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c
new file mode 100644
index 0000000000..499f895e8e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c
@@ -0,0 +1,122 @@
+/** @file
+  This file is PeiSiPolicyLib library creates default settings of RC
+  Policy and installs RC Policy PPI.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyLibrary.h"
+#include <Base.h>
+
+/**
+  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon PREMEM Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreatePreMemConfigBlocks (
+  OUT  SI_PREMEM_POLICY_PPI **SiPreMemPolicyPpi
+  )
+{
+  UINT16               TotalBlockSize;
+  EFI_STATUS           Status;
+  SI_PREMEM_POLICY_PPI *SiPreMemPolicy;
+  UINT16               RequiredSize;
+
+  SiPreMemPolicy = NULL;
+  //
+  // TotalBlockSize = Pch , SA, ME and CPU config block size.
+  //
+  TotalBlockSize = PchGetPreMemConfigBlockTotalSize () +
+                   MeGetConfigBlockTotalSizePreMem () +
+                   SaGetConfigBlockTotalSizePreMem () +
+                   CpuGetPreMemConfigBlockTotalSize ();
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // General initialization
+  //
+  SiPreMemPolicy->TableHeader.Header.Revision = SI_PREMEM_POLICY_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status = PchAddPreMemConfigBlocks ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = MeAddConfigBlocksPreMem ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = SaAddConfigBlocksPreMem ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  Status = CpuAddPreMemConfigBlocks ((VOID *) SiPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *SiPreMemPolicyPpi = SiPreMemPolicy;
+  return Status;
+}
+
+/**
+  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPreMemPolicyPpi   The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiPreMemInstallPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  )
+{
+  EFI_STATUS             Status;
+  EFI_PEI_PPI_DESCRIPTOR *SiPolicyPreMemPpiDesc;
+
+  SiPolicyPreMemPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  if (SiPolicyPreMemPpiDesc == NULL) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SiPolicyPreMemPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  SiPolicyPreMemPpiDesc->Guid  = &gSiPreMemPolicyPpiGuid;
+  SiPolicyPreMemPpiDesc->Ppi   = SiPolicyPreMemPpi;
+
+  //
+  // Print whole PCH_POLICY_PPI and serial out.
+  //
+  PchPreMemPrintPolicyPpi (SiPolicyPreMemPpi);
+  //
+  // Print ME config blocks and serial out.
+  //
+  MePrintPolicyPpiPreMem (SiPolicyPreMemPpi);
+  //
+  // Print whole SI_POLICY_PPI and serial out.
+  //
+  SaPrintPolicyPpiPreMem (SiPolicyPreMemPpi);
+  //
+  // Print whole CPU of SI_PREMEM_POLICY_PPI and serial out.
+  //
+  CpuPreMemPrintPolicy (SiPolicyPreMemPpi);
+  //
+  // Install Silicon Policy PPI
+  //
+  Status = PeiServicesInstallPpi (SiPolicyPreMemPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
new file mode 100644
index 0000000000..cf7e1b2308
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
@@ -0,0 +1,36 @@
+/** @file
+  This file is PeiSiPolicyLib library for printing Policy settings.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyLibrary.h"
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPrintPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  SI_CONFIG     *SiConfig;
+  EFI_STATUS    Status;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ Silicon Print Policy Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " CsmFlag= %x\n", SiConfig->CsmFlag));
+  DEBUG ((DEBUG_INFO, " TraceHubMemBase = 0x%08x\n", SiConfig->TraceHubMemBase));
+
+  DEBUG ((DEBUG_INFO, "------------------------ Silicon Print Policy End --------------------------\n"));
+  DEBUG_CODE_END ();
+}
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: Add library instances

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

Adds ME library class instances.

* PeiMePolicyLib - PEI ME policy configuration services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf   |  44 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h |  25 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c     | 251 ++++++++++++++++++++
 3 files changed, 320 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf
new file mode 100644
index 0000000000..85a227f950
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMe
+++ PolicyLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for the PeiMePolicyLib libbrary.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiMePolicyLib
+FILE_GUID = 2655FA94-4559-F393-B0B1-85A8E79C1532
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiMePolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiMePolicyLib.c
+PeiMePolicyLibrary.h
+
+
+[Ppis]
+gSiPolicyPpiGuid       ## PRODUCES
+gSiPreMemPolicyPpiGuid ## PRODUCES
+
+
+[Guids]
+gMePeiPreMemConfigGuid
+gMePeiConfigGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h
new file mode 100644
index 0000000000..3ac6a639e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMe
+++ PolicyLibrary.h
@@ -0,0 +1,25 @@
+/** @file
+  Header file for the PeiMePolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PEI_ME_POLICY_LIBRARY_H_
+#define _PEI_ME_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h> #include <Ppi/SiPolicy.h> 
+#include <Library/PeiMePolicyLib.h> #include <ConfigBlock.h> #include 
+<ConfigBlock/MePeiConfig.h> #include <Library/ConfigBlockLib.h> 
+#include <Library/SiConfigBlockLib.h> #include <MkhiMsgs.h>
+
+#endif // _PEI_ME_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c
new file mode 100644
index 0000000000..6f3d70b841
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMe
+++ PolicyLib.c
@@ -0,0 +1,251 @@
+/** @file
+  This file is PeiMePolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include "PeiMePolicyLibrary.h"
+
+/**
+  Load default settings for ME config block in pre-mem phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiPreMemDefault (
+  IN VOID                           *ConfigBlockPointer
+  );
+
+/**
+  Load default settings for ME config block in PEI phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiDefault (
+  IN VOID                           *ConfigBlockPointer
+  );
+
+STATIC COMPONENT_BLOCK_ENTRY  mMeCompontBlockPreMemBlocks [] = {
+  {&gMePeiPreMemConfigGuid, sizeof (ME_PEI_PREMEM_CONFIG),  
+ME_PEI_PREMEM_CONFIG_REVISION,  LoadMePeiPreMemDefault} };
+
+STATIC COMPONENT_BLOCK_ENTRY  mMeCompontBlockBlocks [] = {
+  {&gMePeiConfigGuid,       sizeof (ME_PEI_CONFIG),         ME_PEI_CONFIG_REVISION,         LoadMePeiDefault}
+};
+
+/**
+  Load default settings for ME config block in pre-mem phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiPreMemDefault (
+  IN VOID                           *ConfigBlockPointer
+  )
+{
+  ME_PEI_PREMEM_CONFIG *MePeiPreMemConfig;
+  MePeiPreMemConfig = ConfigBlockPointer;
+
+  MePeiPreMemConfig->HeciTimeouts                  = 1;
+
+  MePeiPreMemConfig->Heci1BarAddress               = 0xFED1A000;
+  MePeiPreMemConfig->Heci2BarAddress               = 0xFED1B000;
+  MePeiPreMemConfig->Heci3BarAddress               = 0xFED1C000;
+
+  //
+  // Test policies
+  //
+  MePeiPreMemConfig->SendDidMsg                    = 1;
+
+  MePeiPreMemConfig->KtDeviceEnable                = 1;
+}
+
+/**
+  Load default settings for ME config block in PEI phase.
+
+  @param[in] ConfigBlockPointer                 The pointer to the config block
+**/
+VOID
+LoadMePeiDefault (
+  IN VOID                           *ConfigBlockPointer
+  )
+{
+  ME_PEI_CONFIG *MePeiConfig;
+  MePeiConfig = ConfigBlockPointer;
+
+  MePeiConfig->EndOfPostMessage     = EOP_SEND_IN_DXE;
+  MePeiConfig->MeUnconfigOnRtcClear = 1; }
+
+/**
+  Dump values of ME config block in pre-mem phase.
+
+  @param[in] MePeiPreMemConfig                     The pointer to the config block
+**/
+VOID
+EFIAPI
+PrintMePeiPreMemConfig (
+  IN ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "------------------------ ME_PEI_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision                  : 0x%x\n", MePeiPreMemConfig->Header.Revision));
+  ASSERT (MePeiPreMemConfig->Header.Revision == 
+ME_PEI_PREMEM_CONFIG_REVISION);
+
+  DEBUG ((DEBUG_INFO, " HeciTimeouts              : 0x%x\n", MePeiPreMemConfig->HeciTimeouts));
+  DEBUG ((DEBUG_INFO, " DidInitStat               : 0x%x\n", MePeiPreMemConfig->DidInitStat));
+  DEBUG ((DEBUG_INFO, " DisableCpuReplacedPolling : 0x%x\n", MePeiPreMemConfig->DisableCpuReplacedPolling));
+  DEBUG ((DEBUG_INFO, " SendDidMsg                : 0x%x\n", MePeiPreMemConfig->SendDidMsg));
+  DEBUG ((DEBUG_INFO, " DisableHeciRetry          : 0x%x\n", MePeiPreMemConfig->DisableHeciRetry));
+  DEBUG ((DEBUG_INFO, " DisableMessageCheck       : 0x%x\n", MePeiPreMemConfig->DisableMessageCheck));
+  DEBUG ((DEBUG_INFO, " SkipMbpHob                : 0x%x\n", MePeiPreMemConfig->SkipMbpHob));
+  DEBUG ((DEBUG_INFO, " HeciCommunication2        : 0x%x\n", MePeiPreMemConfig->HeciCommunication2));
+  DEBUG ((DEBUG_INFO, " KtDeviceEnable            : 0x%x\n", MePeiPreMemConfig->KtDeviceEnable));
+  DEBUG ((DEBUG_INFO, " Heci1BarAddress           : 0x%x\n", MePeiPreMemConfig->Heci1BarAddress));
+  DEBUG ((DEBUG_INFO, " Heci2BarAddress           : 0x%x\n", MePeiPreMemConfig->Heci2BarAddress));
+  DEBUG ((DEBUG_INFO, " Heci3BarAddress           : 0x%x\n", MePeiPreMemConfig->Heci3BarAddress));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Dump values of ME config block in PEI phase.
+
+  @param[in] MePeiConfig                    The pointer to the config block
+**/
+VOID
+EFIAPI
+PrintMePeiConfig (
+  IN ME_PEI_CONFIG              *MePeiConfig
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "------------------------ ME_PEI_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision                  : 0x%x\n", MePeiConfig->Header.Revision));
+  ASSERT (MePeiConfig->Header.Revision == ME_PEI_CONFIG_REVISION);
+
+  DEBUG ((DEBUG_INFO, " MctpBroadcastCycle        : 0x%x\n", MePeiConfig->MctpBroadcastCycle));
+  DEBUG ((DEBUG_INFO, " EndOfPostMessage          : 0x%x\n", MePeiConfig->EndOfPostMessage));
+  DEBUG ((DEBUG_INFO, " Heci3Enabled              : 0x%x\n", MePeiConfig->Heci3Enabled));
+  DEBUG ((DEBUG_INFO, " DisableD0I3SettingForHeci : 0x%x\n", MePeiConfig->DisableD0I3SettingForHeci));
+  DEBUG ((DEBUG_INFO, " MeUnconfigOnRtcClear      : 0x%x\n", MePeiConfig->MeUnconfigOnRtcClear));
+
+  DEBUG_CODE_END ();
+}
+
+/**
+  Print PEI ME config block
+
+  @param[in] SiPolicyPpiPreMem The RC Policy PPI instance **/ VOID 
+EFIAPI MePrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPpiPreMem
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                        Status;
+  ME_PEI_PREMEM_CONFIG              *MePeiPreMemConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpiPreMem, 
+ &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);  
+ ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Pre-Mem 
+Print Begin -----------------\n"));
+  PrintMePeiPreMemConfig (MePeiPreMemConfig);
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Pre-Mem 
+Print End -------------------\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Print PEI ME config block
+
+  @param[in] SiPolicyPpi The RC Policy PPI instance **/ VOID EFIAPI 
+MePrintPolicyPpi (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                        Status;
+  ME_PEI_CONFIG                     *MePeiConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, 
+ (VOID *) &MePeiConfig);  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Print 
+Begin -----------------\n"));
+  PrintMePeiConfig (MePeiConfig);
+  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Print 
+End -------------------\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Get ME config block table total size.
+
+  @retval        Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSizePreMem (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize 
+(&mMeCompontBlockPreMemBlocks[0], sizeof (mMeCompontBlockPreMemBlocks) 
+/ sizeof (COMPONENT_BLOCK_ENTRY)); }
+
+/**
+  Get ME config block table total size.
+
+  @retval        Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mMeCompontBlockBlocks[0], 
+sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)); }
+
+/**
+  MeAddConfigBlocksPreMem add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "Me AddConfigBlocks. TotalBlockCount = 0x%x\n",  
+sizeof (mMeCompontBlockPreMemBlocks) / sizeof 
+(COMPONENT_BLOCK_ENTRY)));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, 
+&mMeCompontBlockPreMemBlocks[0], sizeof (mMeCompontBlockPreMemBlocks) / 
+sizeof (COMPONENT_BLOCK_ENTRY)); }
+
+/**
+  MeAddConfigBlocks add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "ME AddConfigBlocks. TotalBlockCount = 0x%x\n",  
+sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, 
+&mMeCompontBlockBlocks[0], sizeof (mMeCompontBlockBlocks) / sizeof 
+(COMPONENT_BLOCK_ENTRY)); }
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add library instances

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

Adds CPU library class instances.

* BaseCpuMailboxLibNull - Generic CPU mailbox interaction services.
* PeiCpuPolicyLib - CPU policy configuration services.
* PeiCpuPolicyLibPreMem - CPU policy pre-memory configuration services.
* PeiDxeSmmCpuPlatformLib - CPU platform services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf     |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf                 |  65 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf           |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf |  39 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h               |  30 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h        |  28 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c       |  90 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c                    | 293 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c              | 108 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c                   | 434 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c             | 160 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c        | 415 +++++++++++++++++++
 12 files changed, 1727 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
new file mode 100644
index 0000000000..4fcfca4670
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
@@ -0,0 +1,22 @@
+## @file
+# Component description file for Cpu Mailbox Null Lib
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseCpuMailboxLibNull
+FILE_GUID = 74F470BC-1769-4732-B9C0-EE9AB0B12411
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuMailboxLib
+
+[Packages]
+MdePkg/MdePkg.dec
+
+[Sources]
+BaseCpuMailboxLibNull.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
new file mode 100644
index 0000000000..c986e35360
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Component description file for the PeiCpuPolicyLib library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiCpuPolicyLib
+FILE_GUID = 5baafc8f-25c6-4d19-b141-585757509372
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = CpuPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+PciSegmentLib
+SaPlatformLib
+SiConfigBlockLib
+PostCodeLib
+PcdLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiCpuPolicyLib.c
+PeiCpuPolicyLibrary.h
+CpuPrintPolicy.c
+PeiCpuPolicyLibPreMem.c
+CpuPrintPolicyPreMem.c
+
+[Ppis]
+gSiPolicyPpiGuid                    ## CONSUMES
+gSiPreMemPolicyPpiGuid              ## CONSUMES
+
+[FixedPcd]
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+
+[Pcd]
+gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode  ## Produces
+
+[Guids]
+gCpuConfigGuid                      ## PRODUCES
+gCpuSgxConfigGuid                   ## PRODUCES
+gCpuPowerMgmtBasicConfigGuid        ## PRODUCES
+gCpuPowerMgmtCustomConfigGuid       ## PRODUCES
+gCpuTestConfigGuid                  ## PRODUCES
+gCpuPidTestConfigGuid               ## PRODUCES
+gCpuPowerMgmtTestConfigGuid         ## PRODUCES
+gCpuConfigLibPreMemConfigGuid       ## PRODUCES
+gCpuSecurityPreMemConfigGuid        ## PRODUCES
+gCpuOverclockingPreMemConfigGuid    ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
new file mode 100644
index 0000000000..52dc989f74
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiCpuPolicyLibPreMem library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiCpuPolicyLibPreMem
+FILE_GUID = 5F4C2CF1-9DFE-4D99-9318-98FD31C8517D
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = CpuPolicyLibPreMem
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+SiConfigBlockLib
+PostCodeLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiCpuPolicyLib.c
+PeiCpuPolicyLibrary.h
+CpuPrintPolicy.c
+
+[Ppis]
+gSiPreMemPolicyPpiGuid         ## CONSUMES
+
+[Guids]
+gCpuSecurityPreMemConfigGuid      ## PRODUCES
+gCpuOverclockingPreMemConfigGuid  ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
new file mode 100644
index 0000000000..0a56e42817
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for CPU Platform Lib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmCpuPlatformLib
+FILE_GUID = 11647130-6AA4-41A4-A3A8-5FA296ABD977
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuPlatformLib
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+DebugLib
+IoLib
+PcdLib
+CpuLib
+TimerLib
+SynchronizationLib
+PciSegmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+CpuPlatformLibrary.h
+CpuPlatformLibrary.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
new file mode 100644
index 0000000000..6e993053fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
@@ -0,0 +1,30 @@
+/** @file
+  Header file for the PeiCpuPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_LIBRARY_H_
+#define _PEI_CPU_POLICY_LIBRARY_H_
+
+#include <PiPei.h>
+#include <CpuAccess.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/CpuPolicyLib.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/Cpuid.h>
+#include <Library/PcdLib.h>
+
+#define MAX_MICROCODE_PATCH_SIZE 0x20000
+
+#endif // _PEI_CPU_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
new file mode 100644
index 0000000000..0b780acd22
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
@@ -0,0 +1,28 @@
+/** @file
+  Header file for Cpu Platform Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SynchronizationLib.h>
+
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <CpuAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
new file mode 100644
index 0000000000..2af11ce8d0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
@@ -0,0 +1,90 @@
+/** @file
+  Mailbox Library.
+
+  Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+
+/**
+  Generic Mailbox function for mailbox write commands. This function will
+  poll the mailbox interface for control, issue the write request, poll
+  for completion, and verify the write was successful.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[in]  MailboxData     Overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status values are:
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval    EFI_SUCCESS           Command succeeded.
+  @retval    EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+  @retval    EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  IN UINT32  MailboxData,
+  OUT UINT32 *MailboxStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Generic Mailbox function for mailbox read commands. This function will write
+  the read request from MailboxType, and populate the read results in the MailboxDataPtr.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status are
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_SUCCESS           Command succeeded.
+  @retval EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+  @retval EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  OUT UINT32 *MailboxDataPtr,
+  OUT UINT32 *MailboxStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Poll the run/busy bit of the mailbox until available or timeout expires.
+
+  @param[in]  MailboxType
+
+  @retval EFI_SUCCESS           Command succeeded.
+  @retval EFI_TIMEOUT           Command timeout.
+**/
+EFI_STATUS
+EFIAPI
+PollMailboxReady (
+  IN UINT32 MailboxType
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
new file mode 100644
index 0000000000..38cf383e8d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
@@ -0,0 +1,293 @@
+/** @file
+  This file is PeiCpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/PcdLib.h>
+
+/**
+  Print CPU_CONFIG and serial out.
+
+  @param[in] CpuConfig   Pointer to a CPU_CONFIG
+**/
+VOID
+CpuConfigPrint (
+  IN CONST CPU_CONFIG   *CpuConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ CPU Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_CONFIG : AesEnable : 0x%x\n", CpuConfig->AesEnable));
+  DEBUG ((DEBUG_INFO, " CPU_CONFIG : MicrocodePatchAddress : 0x%x\n", CpuConfig->MicrocodePatchAddress));
+  DEBUG ((DEBUG_INFO, " CPU_CONFIG : DebugInterfaceEnable : 0x%X\n", CpuConfig->DebugInterfaceEnable));
+}
+
+/**
+  Print CPU_POWER_MGMT_BASIC_CONFIG and serial out.
+
+  @param[in] CpuPowerMgmtBasicConfig   Pointer to a CPU_POWER_MGMT_BASIC_CONFIG
+**/
+VOID
+CpuPowerMgmtBasicConfigPrint (
+  IN CONST CPU_POWER_MGMT_BASIC_CONFIG   *CpuPowerMgmtBasicConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Basic Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG : OneCoreRatioLimit : 0x%X , TwoCoreRatioLimit = 0x%X , ThreeCoreRatioLimit = 0x%X , FourCoreRatioLimit = 0x%X, FiveCoreRatioLimit = 0x%X, SixCoreRatioLimit = 0x%X, SevenCoreRatioLimit = 0x%X, EightCoreRatioLimit = 0x%X \n",  CpuPowerMgmtBasicConfig->OneCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->TwoCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->FourCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->FiveCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->SixCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->SevenCoreRatioLimit, \
+          CpuPowerMgmtBasicConfig->EightCoreRatioLimit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: Hwp : 0x%x\n", CpuPowerMgmtBasicConfig->Hwp));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: SkipSetBootPState : 0x%x\n", CpuPowerMgmtBasicConfig->SkipSetBootPState));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HdcControl : 0x%X\n", CpuPowerMgmtBasicConfig->HdcControl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: (Intel Turbo Boost Max Technology 3.0)EnableItbm : 0x%X\n", CpuPowerMgmtBasicConfig->EnableItbm));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: EnableItbmDriver : 0x%X\n", CpuPowerMgmtBasicConfig->EnableItbmDriver));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit2 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboPowerLimitLock : 0x%x\n", CpuPowerMgmtBasicConfig->TurboPowerLimitLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3DutyCycle : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Lock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit4Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4Lock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetClamp : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetClamp));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetLock : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboMode : 0x%x\n", CpuPowerMgmtBasicConfig->TurboMode));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccActivationOffset : 0x%X\n", CpuPowerMgmtBasicConfig->TccActivationOffset));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit1 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit2Power : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2Power));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit4 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit1Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1Time));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Time));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetTimeWindowForRatl : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HwpInterruptControl : 0x%x\n", CpuPowerMgmtBasicConfig->HwpInterruptControl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: MinRingRatioLimit : 0x%x\n", CpuPowerMgmtBasicConfig->MinRingRatioLimit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: MaxRingRatioLimit : 0x%x\n", CpuPowerMgmtBasicConfig->MaxRingRatioLimit));
+}
+
+/**
+  Print CPU_POWER_MGMT_CUSTOM_CONFIG and serial out.
+
+  @param[in] CpuPowerMgmtCustomConfig   Pointer to a CPU_POWER_MGMT_CUSTOM_CONFIG
+**/
+VOID
+CpuPowerMgmtCustomConfigPrint (
+  IN CONST CPU_POWER_MGMT_CUSTOM_CONFIG   *CpuPowerMgmtCustomConfig
+  )
+{
+  UINT32 Index = 0;
+  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Custom Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "\n CustomRatioTable... \n"));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidNumber : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidCpuid : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidMaxRatio : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio));
+  for (Index = 0; Index < MAX_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: StateRatio[%d] : 0x%x\n", Index, CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index]));
+  }
+  for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: StateRatioMax16[%d] : 0x%x\n", Index, CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index]));
+  }
+  for (Index = 0; Index < MAX_CUSTOM_CTDP_ENTRIES; Index++) {
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit1 : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit1)
+            );
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit2 : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit2)
+            );
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit1Time : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit1Time)
+            );
+    DEBUG (
+            (DEBUG_INFO,
+             " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomTurboActivationRatio : 0x%x\n",
+             Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomTurboActivationRatio)
+            );
+  }
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: ConfigTdpLock : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: ConfigTdpBios : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpBios));
+}
+
+/**
+  Print CPU_TEST_CONFIG and serial out.
+
+  @param[in] CpuTestConfig   Pointer to a CPU_TEST_CONFIG
+**/
+VOID
+CpuTestConfigPrint (
+  IN CONST CPU_TEST_CONFIG   *CpuTestConfig
+  )
+{
+  UINT8 PcdCpuApLoopMode;
+
+  PcdCpuApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+
+  DEBUG ((DEBUG_INFO, "------------------ CPU Test Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcStreamerPrefetcher : 0x%X\n", CpuTestConfig->MlcStreamerPrefetcher));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcSpatialPrefetcher : 0x%X\n", CpuTestConfig->MlcSpatialPrefetcher));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MonitorMwaitEnable : 0x%X\n", CpuTestConfig->MonitorMwaitEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MachineCheckEnable : 0x%X\n", CpuTestConfig->MachineCheckEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: DebugInterfaceLockEnable : 0x%X\n", CpuTestConfig->DebugInterfaceLockEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceOutputScheme : 0x%X\n", CpuTestConfig->ProcessorTraceOutputScheme));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceEnable : 0x%X\n", CpuTestConfig->ProcessorTraceEnable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemBase : 0x%llX\n", CpuTestConfig->ProcessorTraceMemBase));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemLength : 0x%X\n", CpuTestConfig->ProcessorTraceMemLength));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ThreeStrikeCounterDisable : 0x%X\n", CpuTestConfig->ThreeStrikeCounterDisable));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: VoltageOptimization : 0x%X\n", CpuTestConfig->VoltageOptimization));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: CpuWakeUpTimer : 0x%X\n", CpuTestConfig->CpuWakeUpTimer));
+  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: PcdCpuApLoopMode: 0x%X\n", PcdCpuApLoopMode));
+}
+
+/**
+  Print CPU_PID_TEST_CONFIG and serial out.
+
+  @param[in] CpuPidTestConfig   Pointer to a CPU_PID_TEST_CONFIG
+**/
+VOID
+CpuPidTestConfigPrint (
+  IN CONST CPU_PID_TEST_CONFIG   *CpuPidTestConfig
+  )
+{
+  UINT32 Index = 0;
+  DEBUG ((DEBUG_INFO, "------------------ CPU PID Test Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PidTuning : 0x%X\n", Index,  CpuPidTestConfig->PidTuning));
+  if ( CpuPidTestConfig->PidTuning == 1) {
+    for (Index = PID_DOMAIN_KP; Index <= PID_DOMAIN_KD; Index++) {
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : Ratl[%X] : 0x%X\n", Index,  CpuPidTestConfig->Ratl[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr0[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr0[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr1[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr1[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr2[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr2[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr3[%X] : 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr3[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl1Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl1MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl2Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl2MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl1Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl1MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl2Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl2MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl1Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl1MmioPcs[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2Msr[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl2Msr[Index]));
+        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2MmioPcs[%X] : 0x%X\n", Index,  CpuPidTestConfig->DdrPl2MmioPcs[Index]));
+    }
+  }
+}
+
+/**
+  Print CPU_POWER_MGMT_TEST_CONFIG and serial out.
+
+  @param[in] CpuPowerMgmtTestConfig   Pointer to a CPU_POWER_MGMT_TEST_CONFIG
+**/
+VOID
+CpuPowerMgmtTestConfigPrint (
+  IN CONST CPU_POWER_MGMT_TEST_CONFIG   *CpuPowerMgmtTestConfig
+  )
+{
+  CPU_GENERATION CpuGeneration;
+  CpuGeneration = GetCpuGeneration();
+  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Test Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Eist : 0x%x\n", CpuPowerMgmtTestConfig->Eist));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: EnergyEfficientPState : 0x%x\n", CpuPowerMgmtTestConfig->EnergyEfficientPState));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: EnergyEfficientTurbo : 0x%x\n", CpuPowerMgmtTestConfig->EnergyEfficientTurbo));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TStates : 0x%x\n", CpuPowerMgmtTestConfig->TStates));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: BiProcHot : 0x%x\n", CpuPowerMgmtTestConfig->BiProcHot));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: DisableProcHotOut : 0x%x\n", CpuPowerMgmtTestConfig->DisableProcHotOut));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotResponse : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotResponse));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: DisableVrThermalAlert : 0x%x\n", CpuPowerMgmtTestConfig->DisableVrThermalAlert));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: AutoThermalReporting : 0x%x\n", CpuPowerMgmtTestConfig->AutoThermalReporting));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ThermalMonitor : 0x%x\n", CpuPowerMgmtTestConfig->ThermalMonitor));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Cx : 0x%x\n", CpuPowerMgmtTestConfig->Cx));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PmgCstCfgCtrlLock : 0x%x\n", CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1e : 0x%x\n", CpuPowerMgmtTestConfig->C1e));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1Autodemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1AutoDemotion));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1Undemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1UnDemotion));
+  if(CpuGeneration == EnumCflCpu){
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C3AutoDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3AutoDemotion));
+    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C3UnDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3UnDemotion));
+  }
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCState Demotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateDemotion));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCstateUndemotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateUnDemotion));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CStatePreWake : 0x%x\n", CpuPowerMgmtTestConfig->CStatePreWake));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TimedMwait : 0x%x\n", CpuPowerMgmtTestConfig->TimedMwait));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstCfgCtrIoMwaitRedirection : 0x%x\n", CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotLock : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotLock));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ConfigTdpLevel : 0x%x\n", CpuPowerMgmtTestConfig->ConfigTdpLevel));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: RaceToHalt  : 0x%x\n",  CpuPowerMgmtTestConfig->RaceToHalt));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl0Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl0TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl1Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl2Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl3Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl4Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl5Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCStateLimit : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateLimit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl1TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl2TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl3TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl4TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl5TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit));
+  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CustomPowerUnit : 0x%x\n", CpuPowerMgmtTestConfig->CustomPowerUnit));
+  DEBUG ((DEBUG_INFO, " PpmIrmSetting : 0x%x\n", CpuPowerMgmtTestConfig->PpmIrmSetting));
+}
+/**
+  Print whole CPU config blocks of SI_POLICY_PPI and serial out in PostMem.
+
+  @param[in] SiPolicyPpi The SI Policy PPI instance
+**/
+VOID
+CpuPrintPolicy (
+  IN  SI_POLICY_PPI       *SiPolicyPpi
+  )
+{
+DEBUG_CODE_BEGIN();
+  EFI_STATUS                       Status;
+  CPU_CONFIG                       *CpuConfig;
+  CPU_POWER_MGMT_BASIC_CONFIG      *CpuPowerMgmtBasicConfig;
+  CPU_POWER_MGMT_CUSTOM_CONFIG     *CpuPowerMgmtCustomConfig;
+  CPU_TEST_CONFIG                  *CpuTestConfig;
+  CPU_PID_TEST_CONFIG              *CpuPidTestConfig;
+  CPU_POWER_MGMT_TEST_CONFIG       *CpuPowerMgmtTestConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *) &CpuPowerMgmtCustomConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID *) &CpuTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPidTestConfigGuid, (VOID *) &CpuPidTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print Begin in PostMem----------------- \n"));
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPolicyPpi->TableHeader.Header.Revision));
+
+  CpuConfigPrint(CpuConfig);
+  CpuPowerMgmtBasicConfigPrint(CpuPowerMgmtBasicConfig);
+  CpuPowerMgmtCustomConfigPrint(CpuPowerMgmtCustomConfig);
+  CpuTestConfigPrint(CpuTestConfig);
+  CpuPidTestConfigPrint(CpuPidTestConfig);
+  CpuPowerMgmtTestConfigPrint(CpuPowerMgmtTestConfig);
+  DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print End in PostMem ----------------- \n\n"));
+DEBUG_CODE_END();
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
new file mode 100644
index 0000000000..0bcb34c99c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
@@ -0,0 +1,108 @@
+/** @file
+  This file is PeiCpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/ConfigBlockLib.h>
+
+/**
+  Print CPU_CONFIG_LIB_PREMEM_CONFIG and serial out.
+
+  @param[in] CpuConfigLibPreMemConfig     Pointer to a CPU_CONFIG_LIB_PREMEM_CONFIG
+
+**/
+VOID
+CpuConfigLibPreMemConfigPrint (
+  IN CONST CPU_CONFIG_LIB_PREMEM_CONFIG        *CpuConfigLibPreMemConfig
+  )
+{
+  CPU_GENERATION CpuGeneration;
+  CpuGeneration = GetCpuGeneration();
+  DEBUG ((DEBUG_INFO, "------------------ CPU Config Lib PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : HyperThreading = 0x%x\n", CpuConfigLibPreMemConfig->HyperThreading));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BootFrequency = 0x%x\n", CpuConfigLibPreMemConfig->BootFrequency));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : ActiveCoreCount = 0x%x\n", CpuConfigLibPreMemConfig->ActiveCoreCount));
+  if(CpuGeneration == EnumCflCpu){
+    DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : FClkFrequency = 0x%x\n", CpuConfigLibPreMemConfig->FClkFrequency));
+  }
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : JtagC10PowerGateDisable = 0x%x\n", CpuConfigLibPreMemConfig->JtagC10PowerGateDisable));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BistOnReset = 0x%x\n", CpuConfigLibPreMemConfig->BistOnReset));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : VmxEnable = 0x%x\n", CpuConfigLibPreMemConfig->VmxEnable));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : CpuRatio = 0x%x\n", CpuConfigLibPreMemConfig->CpuRatio));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciSxReset = 0x%x\n", CpuConfigLibPreMemConfig->PeciSxReset));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciC10Reset = 0x%x\n", CpuConfigLibPreMemConfig->PeciC10Reset));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : SkipMpInit = 0x%x\n", CpuConfigLibPreMemConfig->SkipMpInit));
+  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : DpSscMarginEnable = 0x%x\n", CpuConfigLibPreMemConfig->DpSscMarginEnable));
+}
+
+/**
+  Print CPU_OVERCLOCKING_PREMEM_CONFIG and serial out.
+
+  @param[in] CpuOverClockingConfig   Pointer to a CPU_OVERCLOCKING_CONFIG
+**/
+VOID
+CpuOverClockingPreMemConfigPrint (
+  IN CONST CPU_OVERCLOCKING_PREMEM_CONFIG   *CpuOverClockingPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ CPU OverClocking Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcSupport : 0x%X\n", CpuOverClockingPreMemConfig->OcSupport));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcLock : 0x%X\n", CpuOverClockingPreMemConfig->OcLock));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageMode : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageMode));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreMaxOcRatio  : 0x%X\n", CpuOverClockingPreMemConfig->CoreMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageOverride : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageOverride));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageAdaptive : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageAdaptive));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageMode : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageMode));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageOverride : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageOverride));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageAdaptive : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageAdaptive));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingMaxOcRatio  : 0x%X\n", CpuOverClockingPreMemConfig->RingMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingDownBin     : 0x%X\n", CpuOverClockingPreMemConfig->RingDownBin));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: Avx2RatioOffset : 0x%X\n", CpuOverClockingPreMemConfig->Avx2RatioOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: Avx3RatioOffset : 0x%X\n", CpuOverClockingPreMemConfig->Avx3RatioOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: BclkAdaptiveVoltage  : 0x%X\n", CpuOverClockingPreMemConfig->BclkAdaptiveVoltage));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CorePllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->CorePllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: GtPllVoltageOffset   : 0x%X\n", CpuOverClockingPreMemConfig->GtPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingPllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->RingPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: SaPllVoltageOffset   : 0x%X\n", CpuOverClockingPreMemConfig->SaPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: McPllVoltageOffset   : 0x%X\n", CpuOverClockingPreMemConfig->McPllVoltageOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TjMaxOffset          : 0x%X\n", CpuOverClockingPreMemConfig->TjMaxOffset));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TvbRatioClipping     : 0x%X\n", CpuOverClockingPreMemConfig->TvbRatioClipping));
+  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TvbVoltageOptimization : 0x%X\n", CpuOverClockingPreMemConfig->TvbVoltageOptimization));
+}
+
+
+/**
+  Print whole CPU Config blocks of SI_PREMEM_POLICY_PPI and serial out in PreMem.
+
+  @param[in] SiPreMemPolicyPpi The SI Pre-Mem Policy PPI instance
+**/
+VOID
+CpuPreMemPrintPolicy (
+  IN  SI_PREMEM_POLICY_PPI       *SiPreMemPolicyPpi
+  )
+{
+DEBUG_CODE_BEGIN();
+  EFI_STATUS                      Status;
+  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverclockingPreMemConfig;
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print Begin in PreMem -----------------\n"));
+
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPreMemPolicyPpi->TableHeader.Header.Revision));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverclockingPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  CpuConfigLibPreMemConfigPrint(CpuConfigLibPreMemConfig);
+  CpuOverClockingPreMemConfigPrint(CpuOverclockingPreMemConfig);
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print End -----------------\n\n"));
+DEBUG_CODE_END();
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
new file mode 100644
index 0000000000..181b72fec5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
@@ -0,0 +1,434 @@
+/** @file
+  This file is PeiCpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <SaAccess.h>
+#include <CpuAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/PcdLib.h>
+
+#ifndef FSP_FLAG
+/**
+  Get the next microcode patch pointer.
+
+  @param[in, out] MicrocodeData - Input is a pointer to the last microcode patch address found,
+                                  and output points to the next patch address found.
+
+  @retval EFI_SUCCESS           - Patch found.
+  @retval EFI_NOT_FOUND         - Patch not found.
+**/
+EFI_STATUS
+EFIAPI
+RetrieveMicrocode (
+  IN OUT CPU_MICROCODE_HEADER **MicrocodeData
+  )
+{
+  UINTN                MicrocodeStart;
+  UINTN                MicrocodeEnd;
+  UINTN                TotalSize;
+
+  if ((FixedPcdGet32 (PcdFlashMicrocodeFvBase) == 0) || (FixedPcdGet32 (PcdFlashMicrocodeFvSize) == 0)) {
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// Microcode binary in SEC
+  ///
+  MicrocodeStart = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) +
+          ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase))->HeaderLength +
+          sizeof (EFI_FFS_FILE_HEADER);
+
+  MicrocodeEnd = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) + (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvSize);
+
+  if (*MicrocodeData == NULL) {
+    *MicrocodeData = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodeStart;
+  } else {
+    if (*MicrocodeData < (CPU_MICROCODE_HEADER *) (UINTN) MicrocodeStart) {
+      DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData < MicrocodeStart \n"));
+      return EFI_NOT_FOUND;
+    }
+
+    TotalSize = (UINTN) ((*MicrocodeData)->TotalSize);
+    if (TotalSize == 0) {
+      TotalSize = 2048;
+    }
+
+    *MicrocodeData = (CPU_MICROCODE_HEADER *) ((UINTN)*MicrocodeData + TotalSize);
+    if (*MicrocodeData >= (CPU_MICROCODE_HEADER *) (UINTN) (MicrocodeEnd) || (*MicrocodeData)->TotalSize == (UINT32) -1) {
+      DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData >= MicrocodeEnd \n"));
+      return EFI_NOT_FOUND;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Get the microcode patch pointer.
+
+  @retval EFI_PHYSICAL_ADDRESS - Address of the microcode patch, or NULL if not found.
+**/
+EFI_PHYSICAL_ADDRESS
+PlatformCpuLocateMicrocodePatch (
+  VOID
+  )
+{
+  EFI_STATUS           Status;
+  CPU_MICROCODE_HEADER *MicrocodeData;
+  EFI_CPUID_REGISTER   Cpuid;
+  UINT32               UcodeRevision;
+  UINTN                MicrocodeBufferSize;
+  VOID                 *MicrocodeBuffer = NULL;
+
+  AsmCpuid (
+    CPUID_VERSION_INFO,
+    &Cpuid.RegEax,
+    &Cpuid.RegEbx,
+    &Cpuid.RegEcx,
+    &Cpuid.RegEdx
+    );
+
+  UcodeRevision = GetCpuUcodeRevision ();
+  MicrocodeData = NULL;
+  while (TRUE) {
+    ///
+    /// Find the next patch address
+    ///
+    Status = RetrieveMicrocode (&MicrocodeData);
+    DEBUG ((DEBUG_INFO, "MicrocodeData = %x\n", MicrocodeData));
+
+    if (Status != EFI_SUCCESS) {
+      break;
+    } else if (CheckMicrocode (Cpuid.RegEax, MicrocodeData, &UcodeRevision)) {
+      break;
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+  }
+
+  ///
+  /// Check that microcode patch size is <= 128K max size,
+  /// then copy the patch from FV to temp buffer for faster access.
+  ///
+  MicrocodeBufferSize = (UINTN) MicrocodeData->TotalSize;
+
+  if (MicrocodeBufferSize <= MAX_MICROCODE_PATCH_SIZE) {
+    MicrocodeBuffer = AllocatePages (EFI_SIZE_TO_PAGES (MicrocodeBufferSize));
+    if (MicrocodeBuffer != NULL) {
+      DEBUG(( DEBUG_INFO, "Copying Microcode to temp buffer.\n"));
+      CopyMem (MicrocodeBuffer, MicrocodeData, MicrocodeBufferSize);
+
+      return (EFI_PHYSICAL_ADDRESS) (UINTN) MicrocodeBuffer;
+    } else {
+      DEBUG(( DEBUG_ERROR, "Failed to allocate enough memory for Microcode Patch.\n"));
+    }
+  } else {
+    DEBUG(( DEBUG_ERROR, "Microcode patch size is greater than max allowed size of 128K.\n"));
+  }
+  return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+}
+#endif
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_CONFIG  *CpuConfig;
+  CpuConfig  = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Name = %g\n", &CpuConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU configuration
+  ********************************/
+  CpuConfig->AesEnable             = CPU_FEATURE_ENABLE;
+#ifndef FSP_FLAG
+  CpuConfig->MicrocodePatchAddress = PlatformCpuLocateMicrocodePatch ();
+#endif //FSP_FLAG
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuSgxConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+
+  /********************************
+    CPU SGX configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtBasicConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_POWER_MGMT_BASIC_CONFIG  *CpuPowerMgmtBasicConfig;
+  CPU_SKU      CpuSku;
+  MSR_REGISTER TempMsr;
+
+  CpuPowerMgmtBasicConfig = ConfigBlockPointer;
+  CpuSku                  = GetCpuSku();
+
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtBasicConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtBasicConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Power Management Basic configuration
+  ********************************/
+  CpuPowerMgmtBasicConfig->Hwp                          = TRUE;
+  CpuPowerMgmtBasicConfig->HdcControl                   = TRUE;
+  CpuPowerMgmtBasicConfig->PowerLimit2                  = TRUE;
+  CpuPowerMgmtBasicConfig->PowerLimit3Lock              = TRUE;
+  CpuPowerMgmtBasicConfig->TccOffsetLock                = FALSE;
+  CpuPowerMgmtBasicConfig->EnableItbm                   = TRUE;
+  CpuPowerMgmtBasicConfig->EnableItbmDriver             = FALSE;
+
+  ///
+  /// Initialize RATL (Runtime Average Temperature Limit) Config for ULX.
+  ///
+  if (CpuSku == EnumCpuUlx) {
+    CpuPowerMgmtBasicConfig->TccActivationOffset        = 15;
+    CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl = 5000; // 5 sec
+    CpuPowerMgmtBasicConfig->TccOffsetClamp             = CPU_FEATURE_ENABLE;
+  }
+  CpuPowerMgmtBasicConfig->TurboMode                    = TRUE;
+
+  TempMsr.Qword = AsmReadMsr64 (MSR_TURBO_RATIO_LIMIT);
+  CpuPowerMgmtBasicConfig->OneCoreRatioLimit = TempMsr.Bytes.FirstByte;
+  CpuPowerMgmtBasicConfig->TwoCoreRatioLimit = TempMsr.Bytes.SecondByte;
+  CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit = TempMsr.Bytes.ThirdByte;
+  CpuPowerMgmtBasicConfig->FourCoreRatioLimit = TempMsr.Bytes.FouthByte;
+  CpuPowerMgmtBasicConfig->FiveCoreRatioLimit = TempMsr.Bytes.FifthByte;
+  CpuPowerMgmtBasicConfig->SixCoreRatioLimit = TempMsr.Bytes.SixthByte;
+  CpuPowerMgmtBasicConfig->SevenCoreRatioLimit = TempMsr.Bytes.SeventhByte;
+  CpuPowerMgmtBasicConfig->EightCoreRatioLimit = TempMsr.Bytes.EighthByte;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtCustomConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_POWER_MGMT_CUSTOM_CONFIG  *CpuPowerMgmtCustomConfig;
+  CpuPowerMgmtCustomConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtCustomConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtCustomConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Power Management Custom configuration
+  ********************************/
+  CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid = (UINT16) ((GetCpuFamily() | GetCpuStepping()) & (0x0FFF));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuTestConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_TEST_CONFIG  *CpuTestConfig;
+  CPU_SKU          CpuSku;
+  CpuTestConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Name = %g\n", &CpuTestConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuTestConfig->Header.GuidHob.Header.HobLength));
+
+  CpuSku = GetCpuSku();
+  /********************************
+    CPU Test configuration
+  ********************************/
+
+  CpuTestConfig->MlcStreamerPrefetcher    = CPU_FEATURE_ENABLE;
+  CpuTestConfig->MlcSpatialPrefetcher     = CPU_FEATURE_ENABLE;
+  CpuTestConfig->MonitorMwaitEnable       = CPU_FEATURE_ENABLE;
+  CpuTestConfig->MachineCheckEnable       = CPU_FEATURE_ENABLE;
+  CpuTestConfig->DebugInterfaceLockEnable = CPU_FEATURE_ENABLE;
+
+  if ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt)){
+    /**
+    This policy should be used to enable or disable Voltage Optimization feature. Recommended defaults:
+     Enable  - For Mobile SKUs(U/Y)
+     Disable - Rest of all SKUs other than Mobile.
+    **/
+    CpuTestConfig->VoltageOptimization      = CPU_FEATURE_ENABLE;
+  }
+  else {
+    CpuTestConfig->VoltageOptimization      = CPU_FEATURE_DISABLE;
+  }
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPidTestConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_PID_TEST_CONFIG  *CpuPidTestConfig;
+  CpuPidTestConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Name = %g\n", &CpuPidTestConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPidTestConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU PID Test configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtTestConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_POWER_MGMT_TEST_CONFIG  *CpuPowerMgmtTestConfig;
+  CPU_GENERATION              CpuGeneration;
+  UINT16                      CpuDid;
+
+  CpuPowerMgmtTestConfig = ConfigBlockPointer;
+  CpuDid    = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtTestConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtTestConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Power Management Test configuration
+  ********************************/
+  CpuPowerMgmtTestConfig->Eist                          = TRUE;
+  CpuPowerMgmtTestConfig->EnergyEfficientPState         = TRUE;
+  CpuPowerMgmtTestConfig->EnergyEfficientTurbo          = TRUE;
+  if ((CpuDid == V_SA_DEVICE_ID_CFL_DT_1) || (CpuDid == V_SA_DEVICE_ID_CFL_DT_2)
+     || (CpuDid == V_SA_DEVICE_ID_CFL_DT_3) || (CpuDid == V_SA_DEVICE_ID_CFL_DT_4)) {
+    ///
+    /// CFL-S 6+2, CFL S 8+2, CFl S 4+2, CFL S 2+2
+    ///
+    CpuPowerMgmtTestConfig->EnergyEfficientTurbo      = FALSE;
+  }
+  CpuPowerMgmtTestConfig->BiProcHot                     = TRUE;
+  CpuPowerMgmtTestConfig->DisableProcHotOut             = TRUE;
+  CpuPowerMgmtTestConfig->AutoThermalReporting          = TRUE;
+  CpuPowerMgmtTestConfig->ThermalMonitor                = TRUE;
+  CpuPowerMgmtTestConfig->Cx                            = TRUE;
+  CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock             = TRUE;
+  CpuPowerMgmtTestConfig->C1e                           = TRUE;
+  CpuPowerMgmtTestConfig->C1AutoDemotion                = TRUE;
+  CpuPowerMgmtTestConfig->C1UnDemotion                  = TRUE;
+  CpuGeneration = GetCpuGeneration();
+  if(CpuGeneration == EnumCflCpu){
+    CpuPowerMgmtTestConfig->C3AutoDemotion                = TRUE;
+    CpuPowerMgmtTestConfig->C3UnDemotion                  = TRUE;
+  }
+
+  CpuPowerMgmtTestConfig->CStatePreWake                 = TRUE;
+  CpuPowerMgmtTestConfig->RaceToHalt                    = TRUE;
+  CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit = TimeUnit1024ns;
+  CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl     = C3_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl     = C6_C7_SHORT_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl     = C6_C7_LONG_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl     = C8_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl     = C9_LATENCY;
+  CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl     = C10_LATENCY;
+
+  CpuPowerMgmtTestConfig->PkgCStateLimit                = PkgAuto;
+  CpuPowerMgmtTestConfig->CustomPowerUnit               = PowerUnit125MilliWatts;
+  CpuPowerMgmtTestConfig->PpmIrmSetting                 = PpmIrmPairFixedPriority;
+}
+
+static COMPONENT_BLOCK_ENTRY  mCpuIpBlocks [] = {
+  {&gCpuConfigGuid,                     sizeof (CPU_CONFIG),                         CPU_CONFIG_REVISION,                        LoadCpuConfigDefault},
+  {&gCpuPowerMgmtBasicConfigGuid,       sizeof (CPU_POWER_MGMT_BASIC_CONFIG),        CPU_POWER_MGMT_BASIC_CONFIG_REVISION,       LoadCpuPowerMgmtBasicConfigDefault},
+  {&gCpuPowerMgmtCustomConfigGuid,      sizeof (CPU_POWER_MGMT_CUSTOM_CONFIG),       CPU_POWER_MGMT_CUSTOM_CONFIG_REVISION,      LoadCpuPowerMgmtCustomConfigDefault},
+  {&gCpuTestConfigGuid,                 sizeof (CPU_TEST_CONFIG),                    CPU_TEST_CONFIG_REVISION,                   LoadCpuTestConfigDefault},
+  {&gCpuPidTestConfigGuid,              sizeof (CPU_PID_TEST_CONFIG),                CPU_PID_TEST_CONFIG_REVISION,               LoadCpuPidTestConfigDefault},
+  {&gCpuPowerMgmtTestConfigGuid,        sizeof (CPU_POWER_MGMT_TEST_CONFIG),         CPU_POWER_MGMT_TEST_CONFIG_REVISION,        LoadCpuPowerMgmtTestConfigDefault},
+};
+
+/**
+  Get CPU config block table total size.
+
+  @retval Size of CPU config block table
+**/
+UINT16
+EFIAPI
+CpuGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  CpuAddConfigBlocks add all Cpu config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS Status;
+  DEBUG((DEBUG_INFO, "CPU Post-Mem Entry \n"));
+  PostCode (0xC00);
+
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  DEBUG ((DEBUG_INFO, "CpuAddConfigBlocks Done \n"));
+  PostCode (0xC09);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
new file mode 100644
index 0000000000..7d45e10236
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
@@ -0,0 +1,160 @@
+/** @file
+  This file is PeiCpuPolicyLibPreMem library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/SaPlatformLib.h>
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuSecurityPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuConfigLibPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_GENERATION  CpuGeneration;
+  CPU_CONFIG_LIB_PREMEM_CONFIG  *CpuConfigLibPreMemConfig;
+  CPU_FAMILY      CpuFamily;
+  CPU_SKU         CpuSku;
+  BOOLEAN         PegDisabled;
+  UINT64          MchBar;
+  UINT64          SaPciBase;
+
+  CpuConfigLibPreMemConfig = ConfigBlockPointer;
+  CpuFamily  = GetCpuFamily();
+  CpuSku     = GetCpuSku();
+
+  DEBUG ((DEBUG_INFO, "CpuConfigLibPreMemConfig->Header.GuidHob.Name = %g\n", &CpuConfigLibPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    CPU Config Lib PreMem configuration
+  ********************************/
+  CpuConfigLibPreMemConfig->HyperThreading          = CPU_FEATURE_ENABLE;
+  CpuConfigLibPreMemConfig->BootFrequency           = 1;    // Maximum non-turbo Performance
+  CpuConfigLibPreMemConfig->ActiveCoreCount         = 0;    // All cores active
+  CpuConfigLibPreMemConfig->JtagC10PowerGateDisable = CPU_FEATURE_DISABLE;
+  CpuConfigLibPreMemConfig->BistOnReset             = CPU_FEATURE_DISABLE;
+  CpuConfigLibPreMemConfig->VmxEnable               = CPU_FEATURE_ENABLE;
+  CpuConfigLibPreMemConfig->CpuRatio = (RShiftU64 (AsmReadMsr64 (MSR_PLATFORM_INFO), N_PLATFORM_INFO_MAX_RATIO) & B_PLATFORM_INFO_RATIO_MASK);
+
+  CpuGeneration = GetCpuGeneration();
+  if(CpuGeneration == EnumCflCpu){
+    ///
+    /// FCLK Frequency
+    ///
+
+    SaPciBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, 0);
+    PciSegmentReadBuffer (SaPciBase + R_SA_MCHBAR, sizeof (MchBar), &MchBar);
+    MchBar &= ((UINT64) ~BIT0);
+    if (IsPchLinkDmi (CpuFamily) && (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF)) {
+      PegDisabled = MmioRead32 ((UINTN) MchBar + R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET) & BIT3;
+    } else {
+      PegDisabled = 1;
+    }
+
+    ///
+    /// DT/Halo FCLK = 1GHz
+    /// Ulx/Ult FCLK = 800MHz
+    ///
+    if (((CpuSku == EnumCpuHalo) && (!PegDisabled)) || (CpuSku == EnumCpuTrad)) {
+      CpuConfigLibPreMemConfig->FClkFrequency = 1;  // 1Ghz
+    }
+    else {
+      CpuConfigLibPreMemConfig->FClkFrequency = 0;  // 800MHz
+    }
+    ///
+    /// Disable Peci Reset on C10 exit on CFL based CPU's
+    /// Setting to 1 will activate the message that disables peci reset.
+    ///
+    CpuConfigLibPreMemConfig->PeciC10Reset = 1;
+  }
+}
+
+/**
+  Load Overclocking pre-mem Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCpuOverclockingPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverclockingPreMemConfig;
+  CpuOverclockingPreMemConfig = ConfigBlockPointer;
+
+  /********************************
+    CPU Overclocking PreMem configuration
+  ********************************/
+  DEBUG ((DEBUG_INFO, "CpuOverclockingPreMemConfig->Header.GuidHob.Name = %g\n", &CpuOverclockingPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY  mCpuIpBlocksPreMem [] = {
+  {&gCpuConfigLibPreMemConfigGuid,    sizeof (CPU_CONFIG_LIB_PREMEM_CONFIG),    CPU_CONFIG_LIB_PREMEM_CONFIG_REVISION,  LoadCpuConfigLibPreMemConfigDefault},
+  {&gCpuOverclockingPreMemConfigGuid, sizeof (CPU_OVERCLOCKING_PREMEM_CONFIG),  CPU_OVERCLOCKING_CONFIG_REVISION,       LoadCpuOverclockingPreMemConfigDefault},
+};
+
+/**
+  Get CPU PREMEM config block table total size.
+
+  @retval Size of CPU PREMEM config block table
+**/
+UINT16
+EFIAPI
+CpuGetPreMemConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS Status;
+  DEBUG((DEBUG_INFO, "CPU Pre-Mem Entry \n"));
+  PostCode (0xC00);
+
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+  DEBUG((DEBUG_INFO, "CpuAddPreMemConfigBlocks Done \n"));
+  PostCode (0xC0F);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
new file mode 100644
index 0000000000..18f2028fa9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
@@ -0,0 +1,415 @@
+/** @file
+  CPU Platform Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "CpuPlatformLibrary.h"
+#include <SaAccess.h>
+#include <MeChipset.h>
+
+#define SKIP_MICROCODE_CHECKSUM_CHECK 1
+#define C6DRAM_ENABLE 1
+#define C6DRAM_DISABLE 0
+
+/**
+  Return CPU Family ID
+
+  @retval CPU_FAMILY              CPU Family ID
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER Cpuid;
+  ///
+  /// Read the CPUID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  return ((CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL));
+}
+
+/**
+  Return Cpu stepping type
+
+  @retval UINT8                   Cpu stepping type
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER Cpuid;
+  ///
+  /// Read the CPUID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  return ((CPU_STEPPING) (Cpuid.RegEax & CPUID_FULL_STEPPING));
+}
+
+/**
+  Return CPU Sku
+
+  @retval UINT8              CPU Sku
+**/
+UINT8
+EFIAPI
+GetCpuSku (
+  VOID
+  )
+{
+  UINT8              CpuType;
+  UINT16             CpuDid;
+  UINT32             CpuFamilyModel;
+  EFI_CPUID_REGISTER Cpuid;
+  BOOLEAN            SkuFound;
+
+  SkuFound  = TRUE;
+  CpuType   = EnumCpuUnknown;
+
+  ///
+  /// Read the CPUID & DID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  CpuFamilyModel = Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL;
+  CpuDid = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+
+  switch (CpuFamilyModel) {
+    case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX:
+      switch (CpuDid) {
+        case V_SA_DEVICE_ID_KBL_MB_ULT_1:    // KBL ULT OPI
+        case V_SA_DEVICE_ID_CFL_ULT_1:       // CFL ULT
+        case V_SA_DEVICE_ID_CFL_ULT_2:       // CFL ULT
+        case V_SA_DEVICE_ID_CFL_ULT_3:       // CFL ULT
+        case V_SA_DEVICE_ID_CFL_ULT_4:       // CFL ULT
+          CpuType = EnumCpuUlt;
+          break;
+
+        default:
+          SkuFound = FALSE;
+          break;
+      }
+      break;
+
+    case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO:
+      switch (CpuDid) {
+
+        case V_SA_DEVICE_ID_KBL_DT_2:      // DT
+        case V_SA_DEVICE_ID_KBL_SVR_2:     // Server
+        case V_SA_DEVICE_ID_CFL_DT_1:      // DT
+        case V_SA_DEVICE_ID_CFL_DT_2:      // DT
+        case V_SA_DEVICE_ID_CFL_DT_3:      // DT
+        case V_SA_DEVICE_ID_CFL_DT_4:      // DT
+        case V_SA_DEVICE_ID_CFL_WS_1:      // WorkStation
+        case V_SA_DEVICE_ID_CFL_WS_2:      // Workstation
+        case V_SA_DEVICE_ID_CFL_WS_3:      // Workstation
+        case V_SA_DEVICE_ID_CFL_SVR_1:     // Server
+        case V_SA_DEVICE_ID_CFL_SVR_2:     // Server
+        case V_SA_DEVICE_ID_CFL_SVR_3:     // Server
+          CpuType = EnumCpuTrad;
+          break;
+
+        case V_SA_DEVICE_ID_KBL_HALO_2:    // Halo
+        case V_SA_DEVICE_ID_CFL_HALO_1:    // Halo
+        case V_SA_DEVICE_ID_CFL_HALO_2:    // Halo
+        case V_SA_DEVICE_ID_CFL_HALO_3:    // Halo
+          CpuType = EnumCpuHalo;
+          break;
+
+        default:
+          SkuFound = FALSE;
+          break;
+      }
+      break;
+
+    default:
+      SkuFound = FALSE;
+      break;
+  }
+#ifdef CFL_SIMICS
+  CpuType = EnumCpuTrad;
+#else
+  if (!SkuFound) {
+    DEBUG ((DEBUG_ERROR, "Unsupported CPU SKU, Device ID: 0x%02X, CPUID: 0x%08X!\n", CpuDid, CpuFamilyModel));
+    ASSERT (FALSE);
+  }
+#endif
+
+  return CpuType;
+}
+
+/**
+  Returns the processor microcode revision of the processor installed in the system.
+
+  @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+  VOID
+  )
+{
+  AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
+  return (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+/**
+  Verify the DWORD type checksum
+
+  @param[in] ChecksumAddr  - The start address to be checkumed
+  @param[in] ChecksumLen   - The length of data to be checksumed
+
+  @retval EFI_SUCCESS           - Checksum correct
+  @retval EFI_CRC_ERROR         - Checksum incorrect
+**/
+EFI_STATUS
+Checksum32Verify (
+  IN UINT32 *ChecksumAddr,
+  IN UINT32 ChecksumLen
+  )
+{
+#if SKIP_MICROCODE_CHECKSUM_CHECK
+  return EFI_SUCCESS;
+#else
+  UINT32 Checksum;
+  UINT32 Index;
+
+  Checksum = 0;
+
+  for (Index = 0; Index < ChecksumLen; Index++) {
+    Checksum += ChecksumAddr[Index];
+  }
+
+  return (Checksum == 0) ? EFI_SUCCESS : EFI_CRC_ERROR;
+#endif
+}
+
+/**
+  This function checks the MCU revision to decide if BIOS needs to load
+  microcode.
+
+  @param[in] MicrocodePointer - Microcode in memory
+  @param[in] Revision         - Current CPU microcode revision
+
+  @retval EFI_SUCCESS - BIOS needs to load microcode
+  @retval EFI_ABORTED - Don't need to update microcode
+**/
+EFI_STATUS
+CheckMcuRevision (
+  IN CPU_MICROCODE_HEADER *MicrocodePointer,
+  IN UINT32               Revision
+  )
+{
+  EFI_STATUS Status;
+  Status = EFI_ABORTED;
+
+  if ((MicrocodePointer->UpdateRevision & 0x80000000) ||
+      (MicrocodePointer->UpdateRevision > Revision) ||
+      (Revision == 0)) {
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+/**
+  Check if this microcode is correct one for processor
+
+  @param[in] Cpuid               - processor CPUID
+  @param[in] MicrocodeEntryPoint - entry point of microcode
+  @param[in] Revision            - revision of microcode
+
+  @retval CorrectMicrocode if this microcode is correct
+**/
+BOOLEAN
+CheckMicrocode (
+  IN UINT32               Cpuid,
+  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+  IN UINT32               *Revision
+  )
+{
+  EFI_STATUS                          Status;
+  UINT8                               ExtendedIndex;
+  MSR_IA32_PLATFORM_ID_REGISTER       Msr;
+  UINT32                              ExtendedTableLength;
+  UINT32                              ExtendedTableCount;
+  BOOLEAN                             CorrectMicrocode;
+  CPU_MICROCODE_EXTENDED_TABLE        *ExtendedTable;
+  CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+
+  Status              = EFI_NOT_FOUND;
+  ExtendedTableLength = 0;
+  CorrectMicrocode    = FALSE;
+
+  if (MicrocodeEntryPoint == NULL) {
+    return FALSE;
+  }
+
+  Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+
+  ///
+  /// Check if the microcode is for the Cpu and the version is newer
+  /// and the update can be processed on the platform
+  ///
+  if ((MicrocodeEntryPoint->HeaderVersion == 0x00000001) &&
+      !EFI_ERROR (CheckMcuRevision (MicrocodeEntryPoint, *Revision))
+      ) {
+    if ((MicrocodeEntryPoint->ProcessorId == Cpuid) && (MicrocodeEntryPoint->ProcessorFlags & (1 << (UINT8) Msr.Bits.PlatformId))) {
+      if (MicrocodeEntryPoint->DataSize == 0) {
+        Status = Checksum32Verify ((UINT32 *) MicrocodeEntryPoint, 2048 / sizeof (UINT32));
+      } else {
+        Status = Checksum32Verify (
+                   (UINT32 *) MicrocodeEntryPoint,
+                   (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)) / sizeof (UINT32)
+                   );
+      }
+
+      if (!EFI_ERROR (Status)) {
+        CorrectMicrocode = TRUE;
+      }
+    } else if ((MicrocodeEntryPoint->DataSize != 0)) {
+      ///
+      /// Check the  Extended Signature if the entended signature exist
+      /// Only the data size != 0 the extended signature may exist
+      ///
+      ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
+      if (ExtendedTableLength != 0) {
+        ///
+        /// Extended Table exist, check if the CPU in support list
+        ///
+        ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + 48);
+        ///
+        /// Calulate Extended Checksum
+        ///
+        if ((ExtendedTableLength % 4) == 0) {
+          Status = Checksum32Verify ((UINT32 *) ExtendedTableHeader, ExtendedTableLength / sizeof (UINT32));
+          if (!EFI_ERROR (Status)) {
+            ///
+            /// Checksum correct
+            ///
+            ExtendedTableCount  = ExtendedTableHeader->ExtendedSignatureCount;
+            ExtendedTable       = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
+            for (ExtendedIndex = 0; ExtendedIndex < ExtendedTableCount; ExtendedIndex++) {
+              ///
+              /// Verify Header
+              ///
+              if ((ExtendedTable->ProcessorSignature == Cpuid) && (ExtendedTable->ProcessorFlag & (1 << (UINT8) Msr.Bits.PlatformId))) {
+                Status = Checksum32Verify (
+                           (UINT32 *) ExtendedTable,
+                           sizeof (CPU_MICROCODE_EXTENDED_TABLE) / sizeof (UINT32)
+                           );
+                if (!EFI_ERROR (Status)) {
+                  ///
+                  /// Find one
+                  ///
+                  CorrectMicrocode = TRUE;
+                  break;
+                }
+              }
+
+              ExtendedTable++;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return CorrectMicrocode;
+}
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval TRUE  if SGX supported
+  @retval FALSE if SGX is not supported
+**/
+BOOLEAN
+IsSgxSupported (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER CpuidRegs;
+
+  //
+  // Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
+  //
+  AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.RegEdx);
+
+  ///
+  /// SGX feature is supported with CPUID.(EAX=7,ECX=0):EBX[2]=1
+  /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
+  ///
+  if (((CpuidRegs.RegEbx & BIT2)) && (AsmReadMsr64 (MSR_IA32_MTRRCAP) & BIT12)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Get processor generation
+
+  @retval CPU_GENERATION  Returns the executing thread's processor generation.
+**/
+CPU_GENERATION
+GetCpuGeneration (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER Cpuid;
+  CPU_FAMILY         CpuFamilyModel;
+  CPU_GENERATION     CpuGeneration;
+
+  CpuGeneration = EnumCflCpu;
+  ///
+  /// Read the CPUID information
+  ///
+  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+  CpuFamilyModel = (CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL);
+
+  switch (CpuFamilyModel) {
+    case EnumCpuCflUltUlx:
+    case EnumCpuCflDtHalo:
+      CpuGeneration = EnumCflCpu;
+      break;
+
+    default:
+      CpuGeneration = EnumCpuUnknownGeneration;
+      ASSERT (FALSE);
+      break;
+  }
+
+  return CpuGeneration;
+}
+
+/**
+  Is Whiskey Lake CPU.
+
+  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
+  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
+**/
+BOOLEAN
+IsWhlCpu (
+  VOID
+  )
+{
+  CPU_FAMILY    CpuFamily;
+  CPU_STEPPING  CpuStepping;
+
+  CpuFamily   = GetCpuFamily ();
+  CpuStepping = GetCpuStepping ();
+
+  //
+  // Check if it is Whiskey Lake CPU
+  //
+  if ((CpuFamily == EnumCpuCflUltUlx) && ((CpuStepping == EnumCflW0) || (CpuStepping == EnumCflV0))) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE library instances

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

Adds PCH DXE library class instances.

* DxePchPolicyLib
* DxeResetSystemLib
* DxeRuntimeResetSystemLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf                   |  41 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf               |  49 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf |  52 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c                     | 218 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c                 | 310 +++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c   | 323 ++++++++++++++++++++
 6 files changed, 993 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
new file mode 100644
index 0000000000..8845ab796c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/Dxe
+++ PchPolicyLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Component description file for the PeiPchPolicy library.
+#
+# Copyright (c) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxePchPolicyLib.c
+
+
+[Guids]
+gHdAudioDxeConfigGuid
+gGpioDxeConfigGuid
+
+[Protocols]
+gPchPolicyProtocolGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf
new file mode 100644
index 0000000000..0bb2d6e247
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/D
+++ xeResetSystemLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeResetSystemLib
+FILE_GUID = 239383BC-499E-4DC5-8CDC-F85AF27B1BC4
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+CONSTRUCTOR = DxeResetSystemLibConstructor # # The following 
+information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+TimerLib
+BaseMemoryLib
+UefiBootServicesTableLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeResetSystemLib.c
+
+
+[Protocols]
+gPchResetCallbackProtocolGuid ## CONSUMES
+
+
+[Guids]
+gPchGlobalResetGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
new file mode 100644
index 0000000000..a1777293ab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSyst
+++ emLib/DxeRuntimeResetSystemLib.inf
@@ -0,0 +1,52 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeRuntimeResetSystemLib
+FILE_GUID = 1026813A-E46F-43D1-B709-FF1F996F2E72
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_RUNTIME_DRIVER
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+CONSTRUCTOR = DxeRuntimeResetSystemLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+TimerLib
+BaseMemoryLib
+UefiRuntimeLib
+DxeServicesTableLib
+UefiBootServicesTableLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeRuntimeResetSystemLib.c
+
+
+[Protocols]
+gPchResetCallbackProtocolGuid ## CONSUMES
+
+
+[Guids]
+gPchGlobalResetGuid
+gEfiEventVirtualAddressChangeGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
new file mode 100644
index 0000000000..62c8a91eb9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/Dxe
+++ PchPolicyLib.c
@@ -0,0 +1,218 @@
+/** @file
+  This file provide services for DXE phase policy default 
+initialization
+
+  Copyright (c) 2019 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 <ConfigBlock/HdAudioConfig.h>
+#include <ConfigBlock/GpioDevConfig.h>
+
+/**
+  Load DXE Config block default for HD Audio
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHdAudioDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_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));
+
+  HdAudioDxeConfig->DspEndpointDmic = PchHdaDmic4chArray;
+  HdAudioDxeConfig->NhltDefaultFlow = TRUE; }
+
+/**
+  Load DXE Config block default for GPIO
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadGpioDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_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; }
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchDxeIpBlocks [] 
+= {
+  {&gHdAudioDxeConfigGuid, sizeof (PCH_HDAUDIO_DXE_CONFIG), 
+HDAUDIO_DXE_CONFIG_REVISION, LoadHdAudioDxeConfigDefault},
+  {&gGpioDxeConfigGuid, sizeof (PCH_GPIO_DXE_CONFIG), 
+GPIO_DXE_CONFIG_REVISION, LoadGpioDxeConfigDefault} };
+
+/**
+  Print PCH_HDAUDIO_DXE_CONFIG.
+
+  @param[in] HdaDxeConfig         Pointer to a PCH_HDAUDIO_DXE_CONFIG that provides the HD Audio settings
+**/
+VOID
+PchPrintHdAudioDxeConfig (
+  IN CONST PCH_HDAUDIO_DXE_CONFIG   *HdaDxeConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio DXE Config 
+------------------\n"));
+  DEBUG ((DEBUG_INFO, " DSP Endpoint: DMIC : %d\n", 
+HdaDxeConfig->DspEndpointDmic));
+  DEBUG ((DEBUG_INFO, " DSP Endpoint: I2S  : %d\n", HdaDxeConfig->DspEndpointI2s));
+  DEBUG ((DEBUG_INFO, " DSP Endpoint: BT   : %d\n", HdaDxeConfig->DspEndpointBluetooth));
+  DEBUG ((DEBUG_INFO, " DSP Feature Mask   : 0x%x\n", HdaDxeConfig->DspFeatureMask));
+  DEBUG ((DEBUG_INFO, " Nhlt Default Flow  : %d\n", 
+HdaDxeConfig->NhltDefaultFlow)); }
+
+/**
+  Print PCH_GPIO_DXE_CONFIG.
+
+  @param[in] GpioDxeConfig         Pointer to a PCH_GPIO_DXE_CONFIG that provides the GPIO settings
+**/
+VOID
+PchPrintGpioDxeConfig (
+  IN CONST PCH_GPIO_DXE_CONFIG   *GpioDxeConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH GPIO DXE Config 
+------------------\n"));
+  DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n", 
+GpioDxeConfig->HideGpioAcpiDevice));
+}
+
+/**
+  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;
+  PCH_HDAUDIO_DXE_CONFIG     *HdaDxeConfig;
+  PCH_GPIO_DXE_CONFIG        *GpioDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here  //  
+ Status = GetConfigBlock ((VOID *) PchPolicy, &gHdAudioDxeConfigGuid, 
+ (VOID *)&HdaDxeConfig);  ASSERT_EFI_ERROR (Status);  Status = 
+ GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (VOID 
+ *)&GpioDxeConfig);  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print 
+ Start ------------------------\n"));  DEBUG ((DEBUG_INFO, " Revision : 
+ %x\n", PchPolicy->TableHeader.Header.Revision));
+
+  PchPrintHdAudioDxeConfig (HdaDxeConfig);  PchPrintGpioDxeConfig 
+ (GpioDxeConfig);
+
+  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));
+
+  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);
+
+  //
+  // 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/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c
new file mode 100644
index 0000000000..fd3c280605
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/D
+++ xeResetSystemLib.c
@@ -0,0 +1,310 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Protocol/PchReset.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32           mDxeResetSystemPwrmBase;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mDxeResetSystemABase;
+
+/**
+  Dump reset message for debug build readability **/ VOID 
+DumpResetMessage (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINTN       Index;
+  //
+  // ******************************
+  // **    SYSTEM REBOOT !!!     **
+  // ******************************
+  //
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+**/
+VOID
+EFIAPI
+PchResetCallback (
+  IN  EFI_RESET_TYPE          ResetType,
+  IN  EFI_GUID                *ResetTypeGuid
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       NumHandles;
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       Index;
+  PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
+
+  ///
+  /// Retrieve all instances of Pch Reset Callback protocol  ///  
+ Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gPchResetCallbackProtocolGuid,
+                  NULL,
+                  &NumHandles,
+                  &HandleBuffer
+                  );
+
+  if (EFI_ERROR (Status)) {
+    ///
+    /// Those drivers that need to install Pch Reset Callback protocol have the responsibility
+    /// to make sure themselves execute before Pch Reset Runtime driver.
+    ///
+    if (Status == EFI_NOT_FOUND) {
+      DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback protocol is installed.\n"));
+    }
+    return;
+  }
+
+  for (Index = 0; Index < NumHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gPchResetCallbackProtocolGuid,
+                    (VOID **) &PchResetCallback
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    if (!EFI_ERROR (Status)) {
+      PchResetCallback->ResetCallback (ResetType, ResetTypeGuid);
+    }
+  }
+}
+
+/**
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetCold, NULL);
+
+  DumpResetMessage ();
+
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetWarm, NULL);
+
+  DumpResetMessage ();
+  //
+  // In case there are pending capsules to process, need to flush the cache.
+  //
+  AsmWbinvd ();
+
+  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
+  )
+{
+  UINT32         Data32;
+
+  //
+  // Loop through callback functions of PchResetCallback Protocol  //  
+ PchResetCallback (EfiResetShutdown, NULL);
+
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up 
+ the system from S5  ///
+  IoWrite32 (mDxeResetSystemABase + 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 (mDxeResetSystemABase + R_ACPI_IO_PM1_STS, 
+ B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state  ///
+  Data32 = IoRead32 (mDxeResetSystemABase + 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 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  DumpResetMessage ();
+
+  IoWrite32 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  return;
+}
+
+/**
+  Internal function to execute the required HECI command for 
+GlobalReset,
+  if failed will use PCH Reest.
+
+**/
+STATIC
+VOID
+PchGlobalReset (
+  VOID
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
+
+  //
+  // PCH BIOS Spec Section 4.6 GPIO Reset Requirement  //
+  MmioOr32 (
+    mDxeResetSystemPwrmBase + R_PMC_PWRM_ETR3,
+    (UINT32) B_PMC_PWRM_ETR3_CF9GR
+    );
+
+  DumpResetMessage ();
+
+  //
+  // ME Global Reset should fail after EOP is sent. Go to use PCH Reset.
+  //
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); }
+
+/**
+  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
+  )
+{
+  EFI_GUID            *GuidPtr;
+
+  if (ResetData == NULL) {
+    DEBUG ((DEBUG_ERROR, "[DxeResetSystemLib] ResetData is not available.\n"));
+    return;
+  }
+  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof 
+(EFI_GUID));
+  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
+    PchGlobalReset();
+  } else {
+    return;
+  }
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library DXE instance.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+**/
+EFI_STATUS
+EFIAPI
+DxeResetSystemLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  mDxeResetSystemABase    = PmcGetAcpiBase ();
+  mDxeResetSystemPwrmBase = PmcGetPwrmBase ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c
new file mode 100644
index 0000000000..a39e171804
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSyst
+++ emLib/DxeRuntimeResetSystemLib.c
@@ -0,0 +1,323 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DxeServicesTableLib.h> #include 
+<Library/UefiBootServicesTableLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Protocol/PchReset.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32           mDxeRuntimeResetSystemPwrmBase;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mDxeRuntimeResetSystemABase;
+
+/**
+  Dump reset message for debug build readability **/ VOID 
+DumpResetMessage (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINTN       Index;
+  //
+  // ******************************
+  // **    SYSTEM REBOOT !!!     **
+  // ******************************
+  //
+  if (!EfiAtRuntime ()) {
+    for (Index = 0; Index < 30; Index++) {
+      DEBUG ((DEBUG_INFO, "*"));
+    }
+    DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
+    for (Index = 0; Index < 30; Index++) {
+      DEBUG ((DEBUG_INFO, "*"));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  DEBUG_CODE_END ();
+}
+
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+**/
+VOID
+EFIAPI
+PchResetCallback (
+  IN  EFI_RESET_TYPE          ResetType,
+  IN  EFI_GUID                *ResetTypeGuid
+  )
+{
+  EFI_STATUS                  Status;
+  UINTN                       NumHandles;
+  EFI_HANDLE                  *HandleBuffer;
+  UINTN                       Index;
+  PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
+
+  if (!EfiAtRuntime ()) {
+    ///
+    /// Retrieve all instances of Pch Reset Callback protocol
+    ///
+    Status = gBS->LocateHandleBuffer (
+                    ByProtocol,
+                    &gPchResetCallbackProtocolGuid,
+                    NULL,
+                    &NumHandles,
+                    &HandleBuffer
+                    );
+    if (EFI_ERROR (Status)) {
+      ///
+      /// Those drivers that need to install Pch Reset Callback protocol have the responsibility
+      /// to make sure themselves execute before Pch Reset Runtime driver.
+      ///
+      if (Status == EFI_NOT_FOUND) {
+        DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback protocol is installed.\n"));
+      }
+      return;
+    }
+
+    for (Index = 0; Index < NumHandles; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gPchResetCallbackProtocolGuid,
+                      (VOID **) &PchResetCallback
+                      );
+      ASSERT_EFI_ERROR (Status);
+
+      if (!EFI_ERROR (Status)) {
+        PchResetCallback->ResetCallback (ResetType, ResetTypeGuid);
+      }
+    }
+  }
+}
+
+/**
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetCold, NULL);
+
+  DumpResetMessage ();
+
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetWarm, NULL);
+
+  DumpResetMessage ();
+  //
+  // In case there are pending capsules to process, need to flush the cache.
+  //
+  AsmWbinvd ();
+
+  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
+  )
+{
+  UINT32         Data32;
+
+  //
+  // Loop through callback functions of PchResetCallback Protocol  //  
+ PchResetCallback (EfiResetShutdown, NULL);
+
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up 
+ the system from S5  ///
+  IoWrite32 (mDxeRuntimeResetSystemABase + 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 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_STS, 
+ B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state  ///
+  Data32 = IoRead32 (mDxeRuntimeResetSystemABase + 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 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  DumpResetMessage ();
+
+  IoWrite32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  return;
+}
+
+/**
+  Internal function to execute the required HECI command for 
+GlobalReset,
+  if failed will use PCH Reest.
+
+**/
+STATIC
+VOID
+PchGlobalReset (
+  VOID
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback Protocol
+  //
+  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
+
+  DumpResetMessage ();
+
+  //
+  // Let ME do global reset if Me Fw is available  //  if 
+ (!EfiAtRuntime ()) {
+    //
+    // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
+    //
+    MmioOr32 (
+      mDxeRuntimeResetSystemPwrmBase + R_PMC_PWRM_ETR3,
+      (UINT32) B_PMC_PWRM_ETR3_CF9GR
+      );
+  }
+
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); }
+
+/**
+  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
+  )
+{
+  EFI_GUID            *GuidPtr;
+
+  if (ResetData == NULL) {
+    if (!EfiAtRuntime ()) {
+      DEBUG ((DEBUG_ERROR, "[DxeRuntimeResetSystemLib] ResetData is not available.\n"));
+    }
+    return;
+  }
+  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof 
+(EFI_GUID));
+  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
+    PchGlobalReset ();
+  } else {
+    return;
+  }
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+}
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library instance.
+
+  The PMC PCI configuration and PWRM space memory ranges are converted 
+ into EFI_RUNTIME_XXX  in PciHostBridgeEntryPoint
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+**/
+EFI_STATUS
+EFIAPI
+DxeRuntimeResetSystemLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  mDxeRuntimeResetSystemABase    = PmcGetAcpiBase ();
+  mDxeRuntimeResetSystemPwrmBase = PmcGetPwrmBase ();
+
+  return EFI_SUCCESS;
+}
+
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances

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

Adds PCH Base library class instances.

* BaseResetSystemLib
* BaseSmbusLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf |  38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf             |  39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c   | 153 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c               | 993 ++++++++++++++++++++
 4 files changed, 1223 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
new file mode 100644
index 0000000000..8d68f2dd83
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/
+++ BaseResetSystemLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 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
+DebugLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseResetSystemLib.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
new file mode 100644
index 0000000000..f3388a2624
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSm
+++ busLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for PCH Smbus Library.
+#
+# SMBUS Library that layers on top of the I/O Library to directly # 
+access a standard SMBUS host controller.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSmbusLib
+FILE_GUID = 5C4D0430-F81B-42D3-BB88-4A6CD2796FF8
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SmbusLib
+CONSTRUCTOR = BaseSmbusLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC #
+
+[LibraryClasses]
+BaseLib
+DebugLib
+IoLib
+PciSegmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+BaseSmbusLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
new file mode 100644
index 0000000000..a603f5e794
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/
+++ BaseResetSystemLib.c
@@ -0,0 +1,153 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 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 <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.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
+  )
+{
+  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/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c
new file mode 100644
index 0000000000..3d6386d433
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSm
+++ busLib.c
@@ -0,0 +1,993 @@
+/** @file
+  PCH SMBUS library implementation built upon I/O library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Base.h>
+#include <Library/SmbusLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSmbus.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mSmbusIoBase = 0;
+
+/**
+  Gets Io port base address of Smbus Host Controller.
+
+  @retval The Io port base address of Smbus host controller.
+
+**/
+UINT16
+InternalGetSmbusIoPortBaseAddress (
+  VOID
+  )
+{
+  UINT64    SmbusPciBase;
+  UINT16    IoPortBaseAddress;
+
+  if (mSmbusIoBase != 0) {
+    return mSmbusIoBase;
+  }
+
+  SmbusPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                   0
+                   );
+  IoPortBaseAddress = (UINT16) PciSegmentRead32 (SmbusPciBase + 
+ R_SMBUS_CFG_BASE);
+
+  //
+  // Make sure that the IO port base address has been properly set.
+  //
+  if ((IoPortBaseAddress == 0) || (IoPortBaseAddress == 0xFFFF)) {
+    ASSERT (FALSE);
+    return 0;
+  }
+
+  IoPortBaseAddress &= B_SMBUS_CFG_BASE_BAR;  mSmbusIoBase = 
+ IoPortBaseAddress;
+
+  return IoPortBaseAddress;
+}
+
+
+/**
+  Acquires the ownership of SMBUS.
+
+  This internal function reads the host state register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;  
+ Otherwise, it performs some basic initializations and returns  
+ RETURN_SUCCESS.
+
+  @param[in]  IoPortBaseAddress The Io port base address of Smbus Host controller.
+
+  @retval     RETURN_SUCCESS    The SMBUS command was executed successfully.
+  @retval     RETURN_TIMEOUT    A timeout occurred while executing the SMBUS command.
+
+**/
+RETURN_STATUS
+InternalSmBusAcquire (
+  IN UINT16                   IoPortBaseAddress
+  )
+{
+  UINT8   HostStatus;
+
+  HostStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);  if 
+ ((HostStatus & B_SMBUS_IO_IUS) != 0) {
+    return RETURN_TIMEOUT;
+  } else if ((HostStatus & B_SMBUS_IO_HBSY) != 0) {
+    //
+    // Clear host status register and exit.
+    //
+    IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_HSTS_ALL);
+    return RETURN_TIMEOUT;
+  }
+  //
+  // Clear out any odd status information (Will Not Clear In Use).
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, HostStatus);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Starts the SMBUS transaction and waits until the end.
+
+  This internal function start the SMBUS transaction and waits until 
+ the transaction  of SMBUS is over by polling the INTR bit of Host status register.
+  If the SMBUS is not available, RETURN_TIMEOUT is returned;  
+ Otherwise, it performs some basic initializations and returns  
+ RETURN_SUCCESS.
+
+  @param[in]  IoPortBaseAddress   The Io port base address of Smbus Host controller.
+  @param[in]  HostControl         The Host control command to start SMBUS transaction.
+
+  @retval     RETURN_SUCCESS      The SMBUS command was executed successfully.
+  @retval     RETURN_CRC_ERROR    The checksum is not correct (PEC is incorrect).
+  @retval     RETURN_DEVICE_ERROR The request was not completed because a failure reflected
+                                  in the Host Status Register bit.  Device errors are
+                                  a result of a transaction collision, illegal command field,
+                                  unclaimed cycle (host initiated), or bus errors (collisions).
+
+**/
+RETURN_STATUS
+InternalSmBusStart (
+  IN  UINT16                  IoPortBaseAddress,
+  IN  UINT8                   HostControl
+  )
+{
+  UINT8   HostStatus;
+  UINT8   AuxiliaryStatus;
+
+  //
+  // Set Host Control Register (Initiate Operation, Interrupt disabled).
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCTL, (UINT8)(HostControl + 
+ B_SMBUS_IO_START));
+
+  do {
+    //
+    // Poll INTR bit of Host Status Register.
+    //
+    HostStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);  } 
+ while ((HostStatus & (B_SMBUS_IO_INTR | B_SMBUS_IO_ERROR | 
+ B_SMBUS_IO_BYTE_DONE_STS)) == 0);
+
+  if ((HostStatus & B_SMBUS_IO_ERROR) == 0) {
+    return RETURN_SUCCESS;
+  }
+  //
+  // Clear error bits of Host Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_ERROR);  //  
+ // Read Auxiliary Status Register to judge CRC error.
+  //
+  AuxiliaryStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_AUXS);  if 
+ ((AuxiliaryStatus & B_SMBUS_IO_CRCE) != 0) {
+    return RETURN_CRC_ERROR;
+  }
+
+  return RETURN_DEVICE_ERROR;
+}
+
+/**
+  Executes an SMBUS quick, byte or word command.
+
+  This internal function executes an SMBUS quick, byte or word commond.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+
+  @param[in]  HostControl     The value of Host Control Register to set.
+  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                              SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value           The byte/word write to the SMBUS.
+  @param[out] Status          Return status for the executed command.
+                              This is an optional parameter and may be NULL.
+
+  @retval The byte/word read from the SMBUS.
+
+**/
+UINT16
+InternalSmBusNonBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT16                    Value,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINT16                        IoPortBaseAddress;
+  UINT8                         AuxiliaryControl;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  //
+  // Try to acquire the ownership of SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);  if 
+ (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+  //
+  // Set the appropriate Host Control Register and auxiliary Control Register.
+  //
+  AuxiliaryControl = 0;
+  if (SMBUS_LIB_PEC (SmBusAddress)) {
+    AuxiliaryControl |= B_SMBUS_IO_AAC;  }  //  // Set Host Commond 
+ Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8) 
+ SMBUS_LIB_COMMAND (SmBusAddress));  //  // Write value to Host Data 0 
+ and Host Data 1 Registers.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) Value);
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD1, (UINT8) (Value >> 8));  
+ //  // Set Auxiliary Control Regiester.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl);  //  
+ // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress);  
+ //  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);  
+ //  // Read value from Host Data 0 and Host Data 1 Registers.
+  //
+  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD1) << 8);  
+ Value = (UINT16)(Value | IoRead8 (IoPortBaseAddress + 
+ R_SMBUS_IO_HD0));  //  // Clear Host Status Register and Auxiliary 
+ Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_HSTS_ALL);
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE);
+
+Done:
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return Value;
+}
+
+/**
+  Executes an SMBUS quick read command.
+
+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickRead (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if (SMBUS_LIB_PEC (SmBusAddress)           ||
+    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return;
+  }
+
+  InternalSmBusNonBlock (
+    V_SMBUS_IO_SMB_CMD_QUICK,
+    SmBusAddress | B_SMBUS_IO_READ,
+    0,
+    Status
+    );
+}
+
+/**
+  Executes an SMBUS quick write command.
+
+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If PEC is set in SmBusAddress, then ASSERT().
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+**/
+VOID
+EFIAPI
+SmBusQuickWrite (
+  IN  UINTN                     SmBusAddress,
+  OUT RETURN_STATUS             *Status       OPTIONAL
+  )
+{
+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if (SMBUS_LIB_PEC (SmBusAddress)           ||
+    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return;
+  }
+
+  InternalSmBusNonBlock (
+    V_SMBUS_IO_SMB_CMD_QUICK,
+    SmBusAddress | B_SMBUS_IO_WRITE,
+    0,
+    Status
+    );
+}
+
+/**
+  Executes an SMBUS receive byte command.
+
+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address field of SmBusAddress is required.
+  The byte received from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The byte received from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReceiveByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE,
+                   SmBusAddress | B_SMBUS_IO_READ,
+                   0,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS send byte command.
+
+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
+  The byte specified by Value is sent.
+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Command in SmBusAddress is not zero, then ASSERT().
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 8-bit value to send.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusSendByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE,
+                   SmBusAddress | B_SMBUS_IO_WRITE,
+                   Value,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS read data byte command.
+
+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 8-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                              SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status          Return status for the executed command.
+                              This is an optional parameter and may be NULL.
+
+  @retval The byte read from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReadDataByte (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE_DATA,
+                   SmBusAddress | B_SMBUS_IO_READ,
+                   0,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS write data byte command.
+
+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
+  The 8-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 8-bit value to write.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusWriteDataByte (
+  IN  UINTN          SmBusAddress,
+  IN  UINT8          Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return (UINT8) InternalSmBusNonBlock (
+                   V_SMBUS_IO_SMB_CMD_BYTE_DATA,
+                   SmBusAddress | B_SMBUS_IO_WRITE,
+                   Value,
+                   Status
+                   );
+}
+
+/**
+  Executes an SMBUS read data word command.
+
+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value read from the SMBUS is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The byte read from the SMBUS.
+
+**/
+UINT16
+EFIAPI
+SmBusReadDataWord (
+  IN  UINTN          SmBusAddress,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusNonBlock (
+           V_SMBUS_IO_SMB_CMD_WORD_DATA,
+           SmBusAddress | B_SMBUS_IO_READ,
+           0,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS write data word command.
+
+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Value is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 16-bit value to write.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+SmBusWriteDataWord (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusNonBlock (
+           V_SMBUS_IO_SMB_CMD_WORD_DATA,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           Value,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS process call command.
+
+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
+  The 16-bit value specified by Value is written.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  The 16-bit value returned by the process call command is returned.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  Value         The 16-bit value to write.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The 16-bit value returned by the process call command.
+
+**/
+UINT16
+EFIAPI
+SmBusProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  UINT16         Value,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusNonBlock (
+           V_SMBUS_IO_SMB_CMD_PROCESS_CALL,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           Value,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS block command.
+
+  Executes an SMBUS block read, block write and block write-block read 
+ command  on the SMBUS device specified by SmBusAddress.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+
+  @param[in]  HostControl     The value of Host Control Register to set.
+  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave Address,
+                              SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.
+  @param[out] ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.
+  @param[out] Status          Return status for the executed command.
+                              This is an optional parameter and may be NULL.
+
+  @retval The number of bytes read from the SMBUS.
+
+**/
+UINTN
+InternalSmBusBlock (
+  IN  UINT8                     HostControl,
+  IN  UINTN                     SmBusAddress,
+  IN  UINT8                     *WriteBuffer,
+  OUT UINT8                     *ReadBuffer,
+  OUT RETURN_STATUS             *Status
+  )
+{
+  RETURN_STATUS                 ReturnStatus;
+  UINTN                         Index;
+  UINTN                         BytesCount;
+  UINT16                        IoPortBaseAddress;
+  UINT8                         AuxiliaryControl;
+
+  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
+
+  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
+
+  //
+  // Try to acquire the ownership of SMBUS.
+  //
+  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);  if 
+ (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+  //
+  // Set the appropriate Host Control Register and auxiliary Control Register.
+  //
+  AuxiliaryControl = B_SMBUS_IO_E32B;
+  if (SMBUS_LIB_PEC (SmBusAddress)) {
+    AuxiliaryControl |= B_SMBUS_IO_AAC;  }  //  // Set Host Command 
+ Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8) 
+ SMBUS_LIB_COMMAND (SmBusAddress));  //  // Set Auxiliary Control 
+ Regiester.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl);  //  
+ // Clear byte pointer of 32-byte buffer.
+  //
+  IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HCTL);
+
+  if (WriteBuffer != NULL) {
+    //
+    // Write the number of block to Host Block Data Byte Register.
+    //
+    IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) BytesCount);
+    //
+    // Write data block to Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HBD, WriteBuffer[Index]);
+    }
+  }
+  //
+  // Set SMBUS slave address for the device to send/receive from.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress);  
+ //  // Start the SMBUS transaction and wait for the end.
+  //
+  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);  
+ if (RETURN_ERROR (ReturnStatus)) {
+    goto Done;
+  }
+
+  if (ReadBuffer != NULL) {
+    //
+    // Read the number of block from host block data byte register.
+    //
+    BytesCount = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD0);
+    //
+    // Write data block from Host Block Data Register.
+    //
+    for (Index = 0; Index < BytesCount; Index++) {
+      ReadBuffer[Index] = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HBD);
+    }
+  }
+
+Done:
+  //
+  // Clear Host Status Register and Auxiliary Status Register.
+  //
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_HSTS_ALL);
+  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE);
+
+  if (Status != NULL) {
+    *Status = ReturnStatus;
+  }
+
+  return BytesCount;
+}
+
+/**
+  Executes an SMBUS read block command.
+
+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+  Bytes are read from the SMBUS and stored in Buffer.
+  The number of bytes read is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is not zero, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Buffer        Pointer to the buffer to store the bytes read from the SMBUS.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The number of bytes read.
+
+**/
+UINTN
+EFIAPI
+SmBusReadBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((Buffer == NULL)                         ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusBlock (
+           V_SMBUS_IO_SMB_CMD_BLOCK,
+           SmBusAddress | B_SMBUS_IO_READ,
+           NULL,
+           Buffer,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS write block command.
+
+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from Buffer.
+  The number of bytes written is returned, and will never return a value larger than 32-bytes.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[out] Buffer        Pointer to the buffer to store the bytes read from the SMBUS.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusWriteBlock (
+  IN  UINTN          SmBusAddress,
+  OUT VOID           *Buffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (Buffer != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((Buffer == NULL)                         ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusBlock (
+           V_SMBUS_IO_SMB_CMD_BLOCK,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           Buffer,
+           NULL,
+           Status
+           );
+}
+
+/**
+  Executes an SMBUS block process call command.
+
+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.
+  If Status is not NULL, then the status of the executed command is returned in Status.
+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+  If WriteBuffer is NULL, then ASSERT().
+  If ReadBuffer is NULL, then ASSERT().
+  If any reserved bits of SmBusAddress are set, then ASSERT().
+
+  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave Address,
+                            SMBUS Command, SMBUS Data Length, and PEC.
+  @param[in]  WriteBuffer   Pointer to the buffer of bytes to write to the SMBUS.
+  @param[out] ReadBuffer    Pointer to the buffer of bytes to read from the SMBUS.
+  @param[out] Status        Return status for the executed command.
+                            This is an optional parameter and may be NULL.
+
+  @retval The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusBlockProcessCall (
+  IN  UINTN          SmBusAddress,
+  IN  VOID           *WriteBuffer,
+  OUT VOID           *ReadBuffer,
+  OUT RETURN_STATUS  *Status        OPTIONAL
+  )
+{
+  ASSERT (WriteBuffer != NULL);
+  ASSERT (ReadBuffer  != NULL);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+
+  if ((WriteBuffer == NULL)                    ||
+      (ReadBuffer  == NULL)                    ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
+      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
+      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
+    if (Status != NULL) {
+      *Status = RETURN_INVALID_PARAMETER;
+    }
+    return 0;
+  }
+
+  return InternalSmBusBlock (
+           V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS,
+           SmBusAddress | B_SMBUS_IO_WRITE,
+           WriteBuffer,
+           ReadBuffer,
+           Status
+           );
+}
+
+/**
+  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.
+**/
+RETURN_STATUS
+EFIAPI
+BaseSmbusLibConstructor (
+  VOID
+  )
+{
+  UINT64    SmbusPciBase;
+  UINT16    IoPortBaseAddress;
+
+  //
+  // Init mSmbusIoBase variable.
+  //
+  SmbusPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                   0
+                   );
+  IoPortBaseAddress = (UINT16) PciSegmentRead32 (SmbusPciBase + 
+ R_SMBUS_CFG_BASE);
+
+  if ((IoPortBaseAddress != 0) && (IoPortBaseAddress != 0xFFFF)) {
+    mSmbusIoBase = IoPortBaseAddress & B_SMBUS_CFG_BASE_BAR;  }
+
+  return RETURN_SUCCESS;
+}
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI library instances

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

Adds PCH PEI library class instances. These libraries may also be
compatible in other boot phases as indicated by the library type.

* PeiDxeSmmBiosLockLib
* PeiDxeSmmGpioLib
* PeiDxeSmmPchCycleDecodingLib
* PeiDxeSmmPchDmiWithS3Lib
* PeiDxeSmmPchEspiLib
* PeiDxeSmmPchGbeLib
* PeiDxeSmmPchHsioLib
* PeiDxeSmmPchInfoLib
* PeiDxeSmmPchPcieRpLib
* PeiDxeSmmPchPcrLib
* PeiDxeSmmPchPmcLib
* PeiDxeSmmPchSbiAccessLib
* PeiDxeSmmPchSerialIoLib
* PeiDxeSmmPchSerialIoUartLib
* PeiDxeSmmPchWdtCommonLib
* PeiDxeSmmPmcLib
* PeiDxeSmmSataLib
* PeiOcWdtLib
* PeiOcWdtLibNull
* PeiPchPolicyLib
* PeiPchResetLib
* PeiResetSystemLib
* PeiSpiLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf                 |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf                         |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf                   |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf                   |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf                |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf               |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf                     |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf                     |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf        |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf   |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf         |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf                           |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf                      |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf                           |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf                        |   86 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf                             |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf                       |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf                                       |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h                                |  117 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h                       |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h              |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c                            |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c                                   |  553 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c                                    | 2710 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c                                  |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c                              |  234 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c            | 1136 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c                              |  505 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c                                |   82 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c                              |  127 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c                              |  272 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c                        |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c                           |  386 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c                          |  183 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c                                |  279 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c                                |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c                    |  270 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c                      |  516 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c                   |  181 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c     |  372 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c                          |  242 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c                                      |  330 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c                                    |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c                                 |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c                                 |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c                                     |  130 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c                             |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c                        |  307 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c                              |  778 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c                             |  739 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c                          |  169 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c                       |  318 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c                                     |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c                         |  257 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c                                            |  217 ++
 60 files changed, 13130 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
new file mode 100644
index 0000000000..6db81f6cf3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
@@ -0,0 +1,40 @@
+## @file
+# BIOS LOCK library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmBiosLockLib
+FILE_GUID = 64EBA6B1-CC36-4C2E-A0F5-D90199432E6C
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = BiosLockLib
+
+
+[LibraryClasses]
+BaseLib
+DebugLib
+PcdLib
+PciSegmentLib
+S3BootScriptLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BiosLockLib.c
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
new file mode 100644
index 0000000000..00d06591fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the PeiDxeSmmGpioLib
+#
+# Copyright (c) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+GpioLib.c
+GpioLibrary.h
+GpioNativeLib.c
+GpioInit.c
+GpioNames.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
new file mode 100644
index 0000000000..2a53f42004
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/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) 2019 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
+PchEspiLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[Sources]
+PchCycleDecodingLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress          ## CONSUMES
+gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress        ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
new file mode 100644
index 0000000000..a775210984
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for the PeiDxeSmmPchEspiLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchEspiLib
+FILE_GUID = 7F25F990-7989-4413-B414-1EDE557E9389
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchEspiLib
+#
+# 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchEspiLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
new file mode 100644
index 0000000000..a685104249
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
@@ -0,0 +1,38 @@
+## @file
+# PCH Gbe Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchGbeLib
+FILE_GUID = FC022ED0-6EB3-43E1-A740-0BA27CBBD010
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchGbeLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+PchCycleDecodingLib
+PmcPrivateLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchGbeLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
new file mode 100644
index 0000000000..7c67e0fa20
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
@@ -0,0 +1,37 @@
+## @file
+# PCH HSIO Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchHsioLib
+FILE_GUID = 6B2D3D0D-9A04-4E7C-AE84-1C2EF2E00E2E
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchHsioLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+MmPciLib
+PchInfoLib
+PchPcrLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchHsioLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf
new file mode 100644
index 0000000000..b9781de810
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf
@@ -0,0 +1,42 @@
+## @file
+# PCH information library for PCH.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchInfoLibCnl
+FILE_GUID = 455CD363-0E78-46B7-8DD3-634003F1614F
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchInfoLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PrintLib
+PciSegmentLib
+PchPcrLib
+PmcPrivateLib
+PcdLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchInfoLib.c
+PchInfoLibClient.c
+PchInfoLibCnl.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
new file mode 100644
index 0000000000..b1ee095423
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
@@ -0,0 +1,37 @@
+## @file
+# PCH 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) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPcieRpLib
+FILE_GUID = B4129C2C-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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcieRpLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
new file mode 100644
index 0000000000..0244e1c0c8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/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) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcrLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
new file mode 100644
index 0000000000..3b1f1e467b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
@@ -0,0 +1,36 @@
+## @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) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPmcLib
+FILE_GUID = 9D60C364-5086-41E3-BC9D-C62AB7233DBF
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPmcLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+MmPciLib
+PchCycleDecodingLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPmcLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
new file mode 100644
index 0000000000..ceb109168b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
@@ -0,0 +1,35 @@
+## @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) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSbiAccessLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
new file mode 100644
index 0000000000..3bfada0b22
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for PEI/DXE/SMM PCH Serial IO Lib.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSerialIoLibCnl
+FILE_GUID = 613A22A2-5736-40f8-909B-DF10EA389C72
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchSerialIoLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PcdLib
+PciSegmentLib
+GpioPrivateLib
+PchPcrLib
+PchSerialIoUartLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSerialIoLib.c
+PchSerialIoLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
new file mode 100644
index 0000000000..1becfc7a96
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for PCH Serial IO UART Lib.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSerialIoUartLib
+FILE_GUID = 55463A54-FD0D-4e8e-8D57-D54FAAEFDC2F
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchSerialIoUartLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PchSerialIoLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiDxeSmmPchSerialIoUartLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
new file mode 100644
index 0000000000..8a01a749bf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
@@ -0,0 +1,31 @@
+## @file
+#  Component description file for the PchWdtCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiDxeSmmPchWdtCommonLib
+  FILE_GUID                      = 171F78D2-0A52-4692-8830-AB693791EA23
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchWdtCommonLib
+
+[Sources]
+  WdtCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PmcLib
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug           ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
new file mode 100644
index 0000000000..78e212eeb0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
@@ -0,0 +1,43 @@
+## @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) 2019 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
+PmcPrivateLib
+BaseMemoryLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+
+
+[Sources]
+PmcLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf
new file mode 100644
index 0000000000..128b348b3d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf
@@ -0,0 +1,32 @@
+## @file
+# PEI/DXE/SMM PCH SATA library for Cannon Lake PCH.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSataLibCnl
+FILE_GUID = 5163ECE3-5372-47E1-B057-2282E753DD55
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SataLib
+
+[LibraryClasses]
+BaseLib
+PciSegmentLib
+PchInfoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+SataLib.c
+SataLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
new file mode 100644
index 0000000000..37d0c80ea4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component Description File for OcWdt Support.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiOcWdtLib
+FILE_GUID = D5207C23-3632-4078-A671-3B5C364B2BDB
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = OcWdtLib
+
+
+[LibraryClasses]
+IoLib
+DebugLib
+PeiServicesLib
+PchWdtCommonLib
+PmcLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiOcWdtLib.c
+
+
+[Ppis]
+gWdtPpiGuid  ## PRODUCES
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug           ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
new file mode 100644
index 0000000000..68ff41ef7f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
@@ -0,0 +1,24 @@
+## @file
+# Component Description File for OcWdt Support.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiOcWdtLib
+FILE_GUID = DB65B36B-E276-4A2b-AB20-61764889E483
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = OcWdtLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+
+
+[Sources]
+PeiOcWdtLibNull.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
new file mode 100644
index 0000000000..49e63cfc51
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
@@ -0,0 +1,86 @@
+## @file
+# Component description file for the PeiPchPolicy libbrary.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiPchPolicyLibCnl
+FILE_GUID = BB1AC992-B2CA-4744-84B7-915C185576C5
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PchPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PcdLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+PchInfoLib
+ConfigBlockLib
+SiConfigBlockLib
+SataLib
+PchPcieRpLib
+CpuPlatformLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable
+gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber
+
+
+[Sources]
+PeiPchPolicyLib.c
+PeiPchPolicyLibCnl.c
+PeiPchPolicyLibrary.h
+PeiPchPreMemPolicyLib.c
+PchPrintPolicy.c
+PchPreMemPrintPolicy.c
+
+[Guids]
+gPchGeneralConfigGuid              ## CONSUMES
+gPcieRpConfigGuid                  ## CONSUMES
+gSataConfigGuid                    ## CONSUMES
+gIoApicConfigGuid                  ## CONSUMES
+gDmiConfigGuid                     ## CONSUMES
+gFlashProtectionConfigGuid         ## CONSUMES
+gHdAudioConfigGuid                 ## CONSUMES
+gInterruptConfigGuid               ## CONSUMES
+gIshConfigGuid                     ## CONSUMES
+gLanConfigGuid                     ## CONSUMES
+gLockDownConfigGuid                ## CONSUMES
+gP2sbConfigGuid                    ## CONSUMES
+gPmConfigGuid                      ## CONSUMES
+gScsConfigGuid                     ## CONSUMES
+gSerialIoConfigGuid                ## CONSUMES
+gSerialIrqConfigGuid               ## CONSUMES
+gThermalConfigGuid                 ## CONSUMES
+gUsbConfigGuid                     ## CONSUMES
+gEspiConfigGuid                    ## CONSUMES
+gCnviConfigGuid                    ## CONSUMES
+gHsioConfigGuid                    ## CONSUMES
+gPchGeneralPreMemConfigGuid        ## COMSUMES
+gDciPreMemConfigGuid               ## CONSUMES
+gWatchDogPreMemConfigGuid          ## CONSUMES
+gPchTraceHubPreMemConfigGuid       ## CONSUMES
+gSmbusPreMemConfigGuid             ## CONSUMES
+gLpcPreMemConfigGuid               ## CONSUMES
+gHsioPciePreMemConfigGuid          ## CONSUMES
+gHsioSataPreMemConfigGuid          ## CONSUMES
+gPcieRpPreMemConfigGuid            ## CONSUMES
+gHdAudioPreMemConfigGuid           ## CONSUMES
+gIshPreMemConfigGuid               ## CONSUMES
+
+[Ppis]
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
new file mode 100644
index 0000000000..41e339a2e8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Component description file for PCH Reset Lib Pei Phase
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiPchResetLib
+FILE_GUID = DB91FFF0-5B99-4A88-9EC8-183A2106DCA2
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PchResetLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+DebugLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+ResetSystemLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchReset.c
+
+[Ppis]
+gEfiPeiReset2PpiGuid ## PRODUCES
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
new file mode 100644
index 0000000000..f8f8bf1b66
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiResetSystemLib
+FILE_GUID = D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+DebugLib
+BaseMemoryLib
+PeiServicesLib
+PmcLib
+PmcPrivateLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiResetSystemLib.c
+
+
+[Ppis]
+gMeDidSentPpiGuid ## CONSUMES
+gPchResetCallbackPpiGuid ## CONSUMES
+
+
+[Guids]
+gPchGlobalResetGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
new file mode 100644
index 0000000000..fb2fad78d3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for PCH Reset Lib Pei Phase
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSpiLib
+FILE_GUID = 4998447D-7948-448F-AB75-96E24E18FF23
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = SpiLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+DebugLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+PciSegmentLib
+PchSpiCommonLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSpi.c
+
+
+[Ppis]
+gPchSpiPpiGuid ## PRODUCES
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h
new file mode 100644
index 0000000000..7a480b6cad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h
@@ -0,0 +1,117 @@
+/** @file
+  Header file for GPIO Lib implementation.
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/GpioHelpersLib.h>
+#include <Register/PchRegsGpio.h>
+
+// BIT15-0  - pad number
+// BIT31-16 - group info
+//   BIT23- 16 - group index
+//   BIT31- 24 - chipset ID
+#define PAD_INFO_MASK          0x0000FFFF
+#define GROUP_INFO_POSITION    16
+#define GROUP_INFO_MASK        0xFFFF0000
+#define GROUP_INDEX_MASK       0x00FF0000
+#define UNIQUE_ID_MASK         0xFF000000
+#define UNIQUE_ID_POSITION     24
+
+#define GPIO_PAD_DEF(Group,Pad)               (UINT32)(((Group) << 16) + (Pad))
+#define GPIO_GROUP_DEF(Index,ChipsetId)       ((Index) | ((ChipsetId) << 8))
+#define GPIO_GET_GROUP_INDEX(Group)           ((Group) & 0xFF)
+#define GPIO_GET_GROUP_FROM_PAD(Pad)          ((Pad) >> 16)
+#define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad)    GPIO_GET_GROUP_INDEX (((Pad) >> 16))
+#define GPIO_GET_PAD_NUMBER(Pad)              ((Pad) & 0xFFFF)
+#define GPIO_GET_CHIPSET_ID(Pad)              ((Pad) >> 24)
+
+#define GPIO_GET_PAD_POSITION(PadNumber)      ((PadNumber) % 32)
+#define GPIO_GET_DW_NUM(PadNumber)            ((PadNumber) / 32u)
+
+//
+// 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
+**/
+VOID
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  );
+
+/**
+  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_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
new file mode 100644
index 0000000000..79e03fef44
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
@@ -0,0 +1,45 @@
+/** @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) 2019 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;
+};
+
+extern struct PCH_SKU_STRING mSkuStrs[];
+
+/**
+  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
+  );
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h
new file mode 100644
index 0000000000..17e4bb863a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h
@@ -0,0 +1,16 @@
+/** @file
+  Header file for PchSerialIoLibInternal.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SERIAL_IO_LIB_INTERNAL_H_
+#define _PCH_SERIAL_IO_LIB_INTERNAL_H_
+
+typedef struct {
+  UINT8  DevNum;
+  UINT8  FuncNum;
+} SERIAL_IO_BDF_NUMBERS;
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h
new file mode 100644
index 0000000000..abd7e63365
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h
@@ -0,0 +1,35 @@
+/** @file
+  Header file for the PeiPchPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_LIBRARY_H_
+#define _PEI_PCH_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchPolicyLib.h>
+
+/**
+  Adds interrupt configuration for device
+
+  @param[in/out] InterruptConfig         Pointer to interrupt config
+**/
+VOID
+LoadDeviceInterruptConfig (
+  IN OUT  PCH_INTERRUPT_CONFIG  *InterruptConfig
+  );
+
+#endif // _PEI_PCH_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c
new file mode 100644
index 0000000000..20c024e893
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c
@@ -0,0 +1,98 @@
+/** @file
+  Bios Lock library.
+
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+
+/**
+  Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable In SMM.STS).
+  When this is set, attempts to write the WPD (Write Protect Disable) bit in PCH
+  will cause a SMI which will allow the BIOS to verify that the write is from a valid source.
+
+  Bios should always enable LockDownConfig.BiosLock policy to set Bios Lock bit in FRC.
+  If capsule udpate is enabled, it's expected to not do BiosLock by setting BiosLock policy disable
+  so it can udpate BIOS region.
+  After flash update, it should utilize this lib to do BiosLock for security.
+**/
+VOID
+BiosLockEnable (
+  VOID
+  )
+{
+  UINT64  LpcBaseAddress;
+  UINT64  SpiBaseAddress;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+  SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+
+  ///
+  /// 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.
+  ///
+  PciSegmentOr8 (SpiBaseAddress + R_SPI_CFG_BC, B_SPI_CFG_BC_EISS | B_SPI_CFG_BC_LE);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC,
+    1,
+    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC)
+    );
+  PciSegmentOr8 (LpcBaseAddress + R_LPC_CFG_BC, B_LPC_CFG_BC_EISS | B_LPC_CFG_BC_LE);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    PcdGet64 (PcdPciExpressBaseAddress) + LpcBaseAddress + R_LPC_CFG_BC,
+    1,
+    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + LpcBaseAddress + R_LPC_CFG_BC)
+    );
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
new file mode 100644
index 0000000000..76eb3a9b81
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
@@ -0,0 +1,553 @@
+/** @file
+  This file contains routines for GPIO initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GpioLibrary.h"
+#include <Register/PchRegsPcr.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.
+//
+// For Cannonlake only vGPIO group has >32 pads but those pads
+// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be 1
+//
+#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.
+**/
+STATIC
+VOID
+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
+          );
+      }
+    }
+
+  }
+}
+
+/**
+  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);
+  GpioClearAllGpioInterrupts ();
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
new file mode 100644
index 0000000000..0be50f75df
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
@@ -0,0 +1,2710 @@
+/** @file
+  This file contains routines for GPIO
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GpioLibrary.h"
+#include <Register/PchRegsPcr.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
+**/
+STATIC
+VOID
+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) {
+    *ReadVal = 0;
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // 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));
+}
+
+/**
+  This function determines if the group is SMI capable.
+
+  @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                    The function completed successfully
+  @retval FALSE                   Setting SMI for a group is not supported
+**/
+STATIC
+BOOLEAN
+GpioIsSmiSupportedByGroupDw (
+  IN GPIO_GROUP             Group,
+  IN UINT32                 Dw
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  This function determines if the group is NMI capable.
+
+  @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                    The function completed successfully
+  @retval FALSE                   Setting NMI for a group is not supported
+**/
+STATIC
+BOOLEAN
+GpioIsNmiSupportedByGroupDw (
+  IN GPIO_GROUP             Group,
+  IN UINT32                 Dw
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  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
+**/
+STATIC
+VOID
+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;
+  EFI_STATUS             Status;
+
+  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;
+  }
+
+  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
+        //
+        Status = GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+        if (EFI_ERROR (Status)) {
+          ASSERT (FALSE);
+          return;
+        }
+      } 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
+    //
+    Status = GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+    if (EFI_ERROR (Status)) {
+      ASSERT (FALSE);
+      return;
+    }
+  }
+}
+
+/**
+  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;
+
+  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;
+
+  Status = PchSbiExecutionEx (
+             GpioGroupInfo[GroupIndex].Community,
+             RegOffset,
+             GpioLockUnlock,
+             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  GppPadRstCfgToGpioResetConfigMap[] = {
+                              GpioResumeReset,
+                              GpioHostDeepReset,
+                              GpioPlatformReset};
+  static GPIO_RESET_CONFIG  GpdPadRstCfgToGpioResetConfigMap[] = {
+                              GpioDswReset,
+                              GpioHostDeepReset,
+                              GpioPlatformReset,
+                              GpioResumeReset};
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+
+  if (GpioIsDswGroup (Group) && PadRstCfg < 4) {
+    return GpdPadRstCfgToGpioResetConfigMap[PadRstCfg];
+  } else if (PadRstCfg < 3) {
+    return GppPadRstCfgToGpioResetConfigMap[PadRstCfg];
+  } else {
+    ASSERT (FALSE);
+    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) | 0x1;
+
+  //
+  // Read PADCFGLOCKTX register
+  //
+  GpioReadReg (
+    GpioPadLockOutputRegister,
+    Group,
+    GPIO_GET_DW_NUM (PadNumber),
+    &RegVal
+    );
+
+  //
+  // Get Pad Configuration Lock Tx state
+  //
+  GpioData->LockConfig |= ((!((RegVal >> PadBitPosition) & 0x1)) << 2) | 0x1;
+
+  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
+**/
+VOID
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  )
+{
+  UINT32               PadRstCfg;
+  EFI_STATUS           Status;
+
+  //
+  // Configure Reset Type (PadRstCfg)
+  // Reset configuration depends on group type.
+  // This field requires support for new and deprecated settings.
+  //
+  Status = GpioPadRstCfgFromResetConfig (
+             GpioPad,
+             GpioConfig->PowerConfig,
+             &PadRstCfg
+             );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  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);
+}
+
+/**
+  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;
+
+  Status = EFI_SUCCESS;
+  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;
+
+  if (GpioIsNmiSupportedByGroupDw (Group, DwNum)) {
+    GpioWriteReg (
+      GpioNmiEnableRegister,
+      Group,
+      DwNum,
+      ~GpiNmiEnRegMask,
+      GpiNmiEnReg
+      );
+  } else {
+    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 EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Update value to be programmed in GPI_SMI_EN register
+  //
+  GpiSmiEnRegMask = (GpioData->InterruptConfig & 0x1) << PadBitPosition;
+  GpiSmiEnReg = ((GpioData->InterruptConfig & GpioIntSmi) >> 2) << PadBitPosition;
+
+  if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) {
+    GpioWriteReg (
+      GpioSmiEnableRegister,
+      Group,
+      DwNum,
+      ~GpiSmiEnRegMask,
+      GpiSmiEnReg
+      );
+  } else {
+    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 EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // 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;
+  BOOLEAN     IsNmiSupported;
+  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;
+    }
+
+    IsNmiSupported = GpioIsNmiSupportedByGroupDw (
+                       GpioGetGroupFromGpioPad (GpioPad),
+                       GPIO_GET_DW_NUM (PadNumber)
+                       );
+    if (IsNmiSupported) {
+      GpioWriteReg (
+        GpioNmiEnableRegister,
+        GpioGetGroupFromGpioPad (GpioPad),
+        GPIO_GET_DW_NUM (PadNumber),
+        ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+        NmiEnable << GPIO_GET_PAD_POSITION (PadNumber)
+        );
+    } else {
+      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 (FALSE);
+      }
+    }
+  }
+
+  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;
+  EFI_STATUS  Status;
+
+  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.
+    //
+    Status = GpioPadRstCfgFromResetConfig (
+               GpioPad,
+               Value,
+               &PadRstCfg
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    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 Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetHostSwOwnershipForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *HostSwRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioReadReg (
+    GpioHostOwnershipRegister,
+    Group,
+    DwNum,
+    HostSwRegVal
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO Host Software Pad Ownership for certain group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               Host Ownership register number for current group
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  HostSwRegVal        Value of Host Software Pad Ownership register
+                                  Bit position - PadNumber
+                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioSetHostSwOwnershipForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       HostSwRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioWriteReg (
+    GpioHostOwnershipRegister,
+    Group,
+    DwNum,
+    0,
+    HostSwRegVal
+    );
+  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);
+
+  GpioWriteReg (
+    GpioHostOwnershipRegister,
+    GpioGetGroupFromGpioPad (GpioPad),
+    GPIO_GET_DW_NUM (PadNumber),
+    (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+    PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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;
+  }
+
+  GpioReadReg (
+    GpioPadConfigLockRegister,
+    Group,
+    DwNum,
+    PadCfgLockRegVal
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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;
+  }
+
+  GpioReadReg (
+    GpioPadLockOutputRegister,
+    Group,
+    DwNum,
+    PadCfgLockTxRegVal
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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 set 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 GpioSetGroupDwToGpeDwX()
+
+  @param[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  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
+GpioSetGroupToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2
+  )
+{
+  return GpioSetGroupDwToGpeDwX (
+           GroupToGpeDw0,
+           0,
+           GroupToGpeDw1,
+           0,
+           GroupToGpeDw2,
+           0
+           );
+}
+
+/**
+  This procedure will set 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[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[in]  GroupDwForGpeDw0    DW of pins to be mapped to GPE_DW0
+  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[in]  GroupDwForGpeDw1    DW of pins to be mapped to GPE_DW1
+  @param[in]  GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
+  @param[in]  GroupDwForGpeDw2    DW of pins to be mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetGroupDwToGpeDwX (
+  IN GPIO_GROUP                GroupToGpeDw0,
+  IN UINT32                    GroupDwForGpeDw0,
+  IN GPIO_GROUP                GroupToGpeDw1,
+  IN UINT32                    GroupDwForGpeDw1,
+  IN GPIO_GROUP                GroupToGpeDw2,
+  IN UINT32                    GroupDwForGpeDw2
+  )
+{
+  UINT32                     Data32Or;
+  UINT32                     Data32And;
+  PCH_SBI_PID                *GpioComSbiIds;
+  UINT32                     NoOfGpioComs;
+  UINT32                     GpioComIndex;
+  UINT32                     GpioGpeDwx[3];
+  UINT32                     PmcGpeDwx[3];
+  GPIO_GROUP                 GroupToGpeDwX[3];
+  UINT32                     GroupDwForGpeDwX[3];
+  UINT8                      GpeDwXIndex;
+  UINT32                     Index;
+  GPIO_GROUP_TO_GPE_MAPPING  *GpioGpeMap;
+  UINT32                     GpioGpeMapLength;
+
+  ZeroMem (GpioGpeDwx, sizeof (GpioGpeDwx));
+  ZeroMem (PmcGpeDwx, sizeof (PmcGpeDwx));
+  //
+  // Check if each group number is unique
+  //
+  if ((GroupToGpeDw0 == GroupToGpeDw1) ||
+      (GroupToGpeDw0 == GroupToGpeDw2) ||
+      (GroupToGpeDw1 == GroupToGpeDw2)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GroupToGpeDwX[0] = GroupToGpeDw0;
+  GroupDwForGpeDwX[0] = GroupDwForGpeDw0;
+  GroupToGpeDwX[1] = GroupToGpeDw1;
+  GroupDwForGpeDwX[1] = GroupDwForGpeDw1;
+  GroupToGpeDwX[2] = GroupToGpeDw2;
+  GroupDwForGpeDwX[2] = GroupDwForGpeDw2;
+
+  GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength);
+
+  for (GpeDwXIndex = 0; GpeDwXIndex < 3; GpeDwXIndex++) {
+    for (Index = 0; Index < GpioGpeMapLength; Index++) {
+
+      if ((GpioGpeMap[Index].Group == GroupToGpeDwX[GpeDwXIndex]) &&
+          (GpioGpeMap[Index].GroupDw == GroupDwForGpeDwX[GpeDwXIndex])) {
+        PmcGpeDwx[GpeDwXIndex] = GpioGpeMap[Index].PmcGpeDwxVal;
+        GpioGpeDwx[GpeDwXIndex] = GpioGpeMap[Index].GpioGpeDwxVal;
+        break;
+      }
+    }
+
+    if (Index == GpioGpeMapLength) {
+      ASSERT (FALSE);
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Program GPE configuration in PMC register
+  //
+  PmcSetGpioGpe (
+    PmcGpeDwx[0],
+    PmcGpeDwx[1],
+    PmcGpeDwx[2]
+    );
+
+  //
+  // Program GPE configuration in GPIO registers
+  //
+  Data32And = (UINT32) ~(B_GPIO_PCR_MISCCFG_GPE0_DW2 | B_GPIO_PCR_MISCCFG_GPE0_DW1 | B_GPIO_PCR_MISCCFG_GPE0_DW0);
+  Data32Or = (UINT32) ((GpioGpeDwx[2] << N_GPIO_PCR_MISCCFG_GPE0_DW2) |
+                       (GpioGpeDwx[1] << N_GPIO_PCR_MISCCFG_GPE0_DW1) |
+                       (GpioGpeDwx[0] << N_GPIO_PCR_MISCCFG_GPE0_DW0));
+
+  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
+
+  //
+  // Program MISCCFG register for each community
+  //
+  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) {
+    MmioAndThenOr32 (
+      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], R_GPIO_PCR_MISCCFG),
+      Data32And,
+      Data32Or
+      );
+  }
+
+  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;
+  EFI_STATUS           Status;
+
+  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
+  //
+  Status = GpioGetGroupDwToGpeDwX (
+             &GroupToGpeDwX[0], &GroupDw[0],
+             &GroupToGpeDwX[1], &GroupDw[1],
+             &GroupToGpeDwX[2], &GroupDw[2]
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // 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'
+  //
+  GpioWriteReg (
+    GpioSmiStatusRegister,
+    Group,
+    DwNum,
+    0u,
+    (UINT32) (BIT0 << PadBitPosition)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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++) {
+      if (GpioIsSmiSupportedByGroupDw(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++) {
+      if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) {
+        SmiEnRegVal = 0;
+        //
+        // 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;
+  EFI_STATUS           Status;
+
+  Status = GpioGetGpeNumber (GpioPad, &Data32);
+  if (EFI_ERROR (Status)) {
+    DEBUG (( DEBUG_ERROR, "GpioCheckFor2Tier: Failed to get GPE number. Status: %r\n", Status ));
+    return FALSE;
+  }
+
+  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'
+  //
+  GpioWriteReg (
+    GpioGpeStatusRegister,
+    Group,
+    DwNum,
+    0u,
+    (UINT32) (BIT0 << PadBitPosition)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to read GPE STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] Data                GPE STS data
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiGpeSts (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *Data
+  )
+{
+  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
+    );
+
+  *Data = (GpeStsRegVal >> PadBitPosition) & 0x1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to lock all GPIO pads except the ones
+  which were requested during their configuration to be left unlocked.
+  This function must be called before BIOS_DONE - before POSTBOOT_SAI is enabled.
+    FSP - call this function from wrapper before transition to FSP-S
+    UEFI/EDK - call this function before EndOfPei event
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioLockPads (
+  VOID
+  )
+{
+  UINT32         DwNum;
+  GPIO_GROUP     Group;
+  GPIO_GROUP     GroupMin;
+  GPIO_GROUP     GroupMax;
+  UINT32         UnlockedPads;
+  EFI_STATUS     Status;
+
+  GroupMin = GpioGetLowestGroup ();
+  GroupMax = GpioGetHighestGroup ();
+
+  for (Group = GroupMin; Group <= GroupMax; Group++) {
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
+
+      UnlockedPads = GpioGetGroupDwUnlockPadConfigMask (GpioGetGroupIndexFromGroup (Group), DwNum);
+
+      Status = GpioLockPadCfgForGroupDw (Group, DwNum, (UINT32)~UnlockedPads);
+      if (EFI_ERROR (Status)) {
+        ASSERT (FALSE);
+        return Status;
+      }
+
+      UnlockedPads = GpioGetGroupDwUnlockOutputMask (GpioGetGroupIndexFromGroup (Group), DwNum);
+
+      Status = GpioLockPadCfgTxForGroupDw (Group, DwNum, (UINT32)~UnlockedPads);
+      if (EFI_ERROR (Status)) {
+        ASSERT (FALSE);
+        return Status;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c
new file mode 100644
index 0000000000..ec33d06156
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c
@@ -0,0 +1,87 @@
+/** @file
+  This file contains GPIO name library implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
new file mode 100644
index 0000000000..9b71cb1d95
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
@@ -0,0 +1,234 @@
+/** @file
+  This file contains routines for GPIO native and chipset specific usage
+
+  Copyright (c) 2019 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
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_PAD_DEF (Group,PadNumber);
+  } else {
+    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);
+}
+
+/**
+  This function checks if SATA GP pin is enabled
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval TRUE                    SATA GPx is enabled (pad is in required native mode)
+          FALSE                   SATA GPx is not enabled
+**/
+BOOLEAN
+GpioIsSataGpEnabled (
+  IN  UINT32          SataCtrlIndex,
+  IN  UINTN           SataPort
+  )
+{
+  EFI_STATUS                Status;
+  GPIO_PAD_NATIVE_FUNCTION  SataGpGpio;
+  GPIO_PAD_MODE             GpioMode;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  GpioGetSataGpPin (
+    SataCtrlIndex,
+    SataPort,
+    &SataGpGpio
+    );
+
+  Status =  GpioGetPadMode (SataGpGpio.Pad, &GpioMode);
+  if ((EFI_ERROR (Status)) || (GpioMode != SataGpGpio.Mode)) {
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
new file mode 100644
index 0000000000..24afbbf712
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
@@ -0,0 +1,1136 @@
+/** @file
+  PCH cycle deocding configuration and query library.
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PchEspiLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsSmbus.h>
+
+typedef enum {
+  SlaveLpcEspiCS0,
+  SlaveEspiCS1,
+  SlaveId_Max
+} SLAVE_ID_INDEX;
+
+/**
+  Set PCH TCO base address.
+  This cycle decoding is required also on DMI side
+  Programming steps:
+  1. set Smbus PCI offset 54h [8] to enable TCO base address.
+  2. program Smbus PCI offset 50h [15:5] to TCO base address.
+  3. set Smbus PCI offset 54h [8] to enable TCO base address.
+  4. program "TCO Base Address" in DMI
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchTcoBaseSet (
+  IN  UINT16                            Address
+  )
+{
+  UINT64                                SmbusBase;
+  EFI_STATUS                            Status;
+
+  if ((Address & ~B_SMBUS_CFG_TCOBASE_BAR) != 0) {
+    DEBUG ((DEBUG_ERROR, "PchTcoBaseSet Error. Invalid Address: %x.\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = PchDmiSetTcoBase (Address);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  SmbusBase = PCI_SEGMENT_LIB_ADDRESS (
+                DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                DEFAULT_PCI_BUS_NUMBER_PCH,
+                PCI_DEVICE_NUMBER_PCH_SMBUS,
+                PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                0
+                );
+  if (PciSegmentRead16 (SmbusBase) == 0xFFFF) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Verify TCO base is not locked.
+  //
+  if ((PciSegmentRead8 (SmbusBase + R_SMBUS_CFG_TCOCTL) & B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK) != 0) {
+    ASSERT (FALSE);
+    return EFI_DEVICE_ERROR;
+  }
+  //
+  // Disable TCO in SMBUS Device first before changing base address.
+  // Byte access to not touch the TCO_BASE_LOCK bit
+  //
+  PciSegmentAnd8 (
+    SmbusBase + R_SMBUS_CFG_TCOCTL + 1,
+    (UINT8) ~(B_SMBUS_CFG_TCOCTL_TCO_BASE_EN >> 8)
+    );
+  //
+  // Program TCO in SMBUS Device
+  //
+  PciSegmentAndThenOr16 (
+    SmbusBase + R_SMBUS_CFG_TCOBASE,
+    (UINT16) (~B_SMBUS_CFG_TCOBASE_BAR),
+    Address
+    );
+  //
+  // Enable TCO in SMBUS Device and lock TCO BASE
+  //
+  PciSegmentOr16 (
+    SmbusBase + R_SMBUS_CFG_TCOCTL,
+    B_SMBUS_CFG_TCOCTL_TCO_BASE_EN | B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK
+    );
+
+  return Status;
+}
+
+/**
+  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;
+}
+
+/**
+  Returns PCH LPC device PCI base address.
+
+  @retval                   PCH LPC PCI base address.
+**/
+STATIC
+UINT64
+LpcPciBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           PCI_DEVICE_NUMBER_PCH_LPC,
+           PCI_FUNCTION_NUMBER_PCH_LPC,
+           0
+           );
+}
+
+/**
+  Function checks if passed Generic LPC IO Address and Length meets requirements.
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @param[in] Length                     Length of generic IO range.
+
+  @retval TRUE                          Passed IO range meets requirements
+  @retval FALSE                         Passed IO range does not meets requirements.
+**/
+STATIC
+BOOLEAN
+IsLpcIoRangeValid (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length
+  )
+{
+  UINT32            Index;
+  UINT32            NumRanges;
+
+  STATIC struct EXCEPT_RANGE {
+    UINT8 Start;
+    UINT8 Length;
+  } ExceptRanges[] = { {0x00, 0x20}, {0x44, 0x08}, {0x54, 0x0C}, {0x68, 0x08}, {0x80, 0x10}, {0xC0, 0x40} };
+
+  NumRanges = ARRAY_SIZE (ExceptRanges);
+  //
+  // For generic IO range, the base address must align to 4 and less than 0xFFFF,
+  // the length must be power of 2 and less than or equal to 256, and the address must be length aligned.
+  // 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
+  //
+  if (((Length & (Length - 1)) != 0)  ||
+      ((Address & (UINT16) ~B_LPC_CFG_GENX_DEC_IOBAR) != 0) ||
+      (Length > 256)) {
+    return FALSE;
+  }
+  if (Address < 0x100) {
+    for (Index = 0; Index < NumRanges; Index++) {
+      if ((Address >= ExceptRanges[Index].Start) &&
+          ((Address + Length) <= ((UINTN) ExceptRanges[Index].Start + (UINTN) ExceptRanges[Index].Length))) {
+        break;
+      }
+    }
+    if (Index >= NumRanges) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+  Function checks if passed Generic LPC IO Range is already in Gen IO Range list
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] GenIoRangeList             Pointer to Generic IO Ranges List
+
+  @retval TRUE                          Passed IO range alredy covered
+  @retval FALSE                         Passed IO range NOT covered
+**/
+STATIC
+BOOLEAN
+IsRangeInList (
+  IN  UINT32                      Address,
+  IN  UINT32                      Length,
+  IN  PCH_LPC_GEN_IO_RANGE_LIST   *GenIoRangeList
+  )
+{
+  UINT32                                CurrentBaseAddr;
+  UINT32                                CurrentLength;
+  UINT32                                Index;
+
+  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
+    CurrentBaseAddr = GenIoRangeList->Range[Index].BaseAddr;
+    CurrentLength   = GenIoRangeList->Range[Index].Length;
+    if (GenIoRangeList->Range[Index].Enable == 0) {
+      continue;
+    }
+    if ((Address >= CurrentBaseAddr) && ((Address + Length) <= (CurrentBaseAddr + CurrentLength))) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Function checks if passed Generic LPC IO Range overlaps with existing range
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] GenIoRangeList             Pointer to Generic IO Ranges List
+
+  @retval TRUE                          Passed LPC IO range overlaps with existing range
+  @retval FALSE                         Passed LPC IO range NOT overlaps
+**/
+STATIC
+BOOLEAN
+FindOverlappingGenIoRange (
+  IN  UINT32                          Address,
+  IN  UINT32                          Length,
+  IN  PCH_LPC_GEN_IO_RANGE_LIST       *GenIoRangeList
+  )
+{
+  UINT32                              Index;
+  UINT32                              CurrentBaseAddr;
+  UINT32                              CurrentLength;
+
+  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
+    CurrentBaseAddr = GenIoRangeList->Range[Index].BaseAddr;
+    CurrentLength = GenIoRangeList->Range[Index].Length;
+    if (GenIoRangeList->Range[Index].Enable == 0) {
+      continue;
+    }
+
+    if ((Address >= CurrentBaseAddr) &&
+        (Address <= (CurrentBaseAddr + CurrentLength))) {
+      return TRUE;
+    } else if (((Address + Length) >= CurrentBaseAddr) &&
+              ((Address + Length) <= (CurrentBaseAddr + CurrentLength))) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Function look for empty Generic IO range register.
+  If found return range index.
+
+  @param[in]      GenIoRangeList        Pointer to Generic IO Ranges List
+  @param[in]      ListLength            Length of passed list
+  @param[out]     RangeIndex            Generic IO Range Index
+
+  @retval TRUE                          Empty range found
+  @retval FALSE                         NOT found empty range
+**/
+STATIC
+BOOLEAN
+FindEmptyGenIoRange (
+  IN  PCH_LPC_GEN_IO_RANGE_LIST   *GenIoRangeList,
+  IN  UINT32                      ListLength,
+  OUT UINT32                      *RangeIndex
+  )
+{
+  UINT32                          Index;
+
+  for (Index = 0; Index < ListLength; Index++) {
+    if (GenIoRangeList->Range[Index].Enable == 0) {
+      *RangeIndex = Index;
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Get PCH LPC/eSPI and eSPI CS1# generic IO range list.
+  This function returns a list of base address, length, and enable for all LPC/eSPI or eSPI CS1# generic IO range registers.
+
+  @param[in]  RangeIndex                Slave ID (refer to SLAVE_ID_INDEX)
+  @param[out] GenIoRangeList            LPC/eSPI or eSPI CS1# generic IO range registers.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+LpcEspiGenIoRangeGetHelper (
+  IN  SLAVE_ID_INDEX                    SlaveId,
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
+  )
+{
+  UINT32                                Index;
+  UINT64                                LpcBase;
+  UINT32                                Data32;
+  UINT32                                GenIoReg;
+
+  if ((GenIoRangeList == NULL) || (SlaveId >= SlaveId_Max)) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  LpcBase = LpcPciBase ();
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenIoReg = R_ESPI_CFG_CS1GIR1;
+  } else {
+    GenIoReg = R_LPC_CFG_GEN1_DEC;
+  }
+
+  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
+    if ((SlaveId == SlaveEspiCS1) &&
+        (Index > 0)) {
+      // For eSPI CS1# we have only one range. Reset remaining entries to zero.
+      GenIoRangeList->Range[Index].BaseAddr = 0;
+      GenIoRangeList->Range[Index].Enable = 0;
+      GenIoRangeList->Range[Index].Length = 0;
+      continue;
+    }
+    Data32 = PciSegmentRead32 (LpcBase + GenIoReg + Index * 4);
+    GenIoRangeList->Range[Index].BaseAddr = Data32 & B_LPC_CFG_GENX_DEC_IOBAR;
+    GenIoRangeList->Range[Index].Length   = ((Data32 & B_LPC_CFG_GENX_DEC_IODRA) >> 16) + 4;
+    GenIoRangeList->Range[Index].Enable   = Data32 & B_LPC_CFG_GENX_DEC_EN;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Function checks if passed Generic LPC IO Range colliding
+  with range alredy defined for other eSPI chiselect (CS)
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] SlaveId                    Slave ID (refer to SLAVE_ID_INDEX)
+
+  @retval TRUE                          Passed IO range conflicting
+  @retval FALSE                         There is no conflict
+**/
+STATIC
+BOOLEAN
+IsRangeColliding (
+  IN  UINT32                      Address,
+  IN  UINT32                      Length,
+  IN  SLAVE_ID_INDEX              SlaveId
+  )
+{
+  EFI_STATUS                      Status;
+  PCH_LPC_GEN_IO_RANGE_LIST       GenIoRangeList;
+
+  if (SlaveId == SlaveEspiCS1) {
+    Status  = LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0, &GenIoRangeList);
+    if (!EFI_ERROR (Status)) {
+      if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) ||
+          IsRangeInList (Address, Length, &GenIoRangeList)) {
+        return TRUE;
+      }
+    }
+  } else {
+    Status  = LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, &GenIoRangeList);
+    if (!EFI_ERROR (Status)) {
+      if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) ||
+          IsRangeInList (Address, Length, &GenIoRangeList)) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS                            Status;
+  PCH_LPC_GEN_IO_RANGE_LIST             GenIoRangeList;
+  UINT32                                RangeIndex;
+  UINT32                                Data32;
+  UINT32                                GenIoReg;
+  UINT32                                ListLength;
+
+  //
+  // Check if pasesed Address and Length meets all requirements
+  //
+  if(!IsLpcIoRangeValid (Address, Length) || (SlaveId >= SlaveId_Max)) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Read current Generic IO configuration
+  //
+  Status  = LpcEspiGenIoRangeGetHelper (SlaveId, &GenIoRangeList);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Check if passed Generic IO range is already covered in current configuration
+  //
+  if (IsRangeInList (Address, Length, &GenIoRangeList)) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Check if passed Generic IO range conflicting with other eSPI CS decoding
+  //
+  if (IsRangeColliding (Address, Length, SlaveId)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenIoReg = R_ESPI_CFG_CS1GIR1;
+    ListLength = ESPI_CS1_GEN_IO_RANGE_MAX;
+  } else {
+    GenIoReg = R_LPC_CFG_GEN1_DEC;
+    ListLength = PCH_LPC_GEN_IO_RANGE_MAX;
+  }
+
+  RangeIndex = ListLength;
+  //
+  // Check if there is an empty Generic IO range register
+  //
+  if (FindEmptyGenIoRange (&GenIoRangeList, ListLength, &RangeIndex) == FALSE) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Program decoding in DMI and LPC/eSPI registers
+  //
+  if (SlaveId == SlaveEspiCS1) {
+    ASSERT (RangeIndex == 0);
+    Status = PchDmiSetEspiCs1GenIoRange (Address, Length);
+  } else {
+    Status = PchDmiSetLpcGenIoRange (Address, Length, RangeIndex);
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Program LPC/eSPI generic IO range register accordingly.
+  //
+  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
+  Data32 |= (UINT32) Address;
+  Data32 |= B_LPC_CFG_GENX_DEC_EN;
+
+  //
+  // Program LPC/eSPI PCI Offset 84h ~ 93h (LPC, eSPI CS0#) or A4h (eSPI CS1#) of Mask, Address, and Enable.
+  //
+  PciSegmentWrite32 (
+    LpcPciBase () + GenIoReg + RangeIndex * 4,
+    Data32
+    );
+
+  return Status;
+}
+
+/**
+  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 eSPI CS1# generic IO range decoding.
+
+  Steps of programming generic IO range:
+  1. Program eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enable.
+  2. Program eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @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               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeSet (
+  IN  UINT16                            Address,
+  IN  UINTN                             Length
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiGenIoRangeSetHelper ((UINT32)Address, (UINT32)Length, SlaveEspiCS1);
+}
+
+/**
+  Get PCH LPC/eSPI generic IO range list.
+  This function returns a list of base address, length, and enable for all LPC/eSPI generic IO range registers.
+
+  @param[out] LpcGenIoRangeList         Return all LPC/eSPI generic IO range register status.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchLpcGenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *LpcGenIoRangeList
+  )
+{
+  return LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0, LpcGenIoRangeList);
+}
+
+/**
+  Get PCH eSPI CS1# generic IO range list.
+  This function returns a list of base address, length, and enable for all eSPI CS1# generic IO range registers.
+
+  @param[out] GenIoRangeList            eSPI generic IO range registers.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1GenIoRangeGet (
+  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, GenIoRangeList);
+}
+
+/**
+  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.
+**/
+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, "PchLpcEspiMemRangeSet Error. Invalid Address: %x or invalid SlaveId\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  LpcBase = LpcPciBase ();
+
+  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);
+}
+
+/**
+  @deprecated. Keep this for backward compatibility.
+  It's replaced by PchEspiCs1MemRangeSet.
+**/
+EFI_STATUS
+PchEspiMemRange2Set (
+  IN  UINT32                            Address
+  )
+{
+  return PchEspiCs1MemRangeSet (Address);
+}
+
+/**
+  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
+**/
+EFI_STATUS
+LpcEspiMemRangeGetHelper (
+  IN  SLAVE_ID_INDEX                    SlaveId,
+  OUT UINT32                            *Address
+  )
+{
+  UINT32                                GenMemReg;
+
+  if ((Address == NULL) || (SlaveId >= SlaveId_Max)) {
+    DEBUG ((DEBUG_ERROR, "PchLpcEspiMemRangeGet Error. Invalid pointer or SlaveId.\n"));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenMemReg = R_ESPI_CFG_CS1GMR1;
+  } else {
+    GenMemReg = R_LPC_CFG_LGMR;
+  }
+  *Address = PciSegmentRead32 (LpcPciBase () + 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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+    //
+    // Read SPI CFG cycle before write SPI CFG cycle
+    PciSegmentRead16 (BaseAddr + R_SPI_CFG_BDE);
+    //
+    // If SPI, Program SPI offset D8h to BiosDecodeEnable.
+    //
+    PciSegmentWrite16 (BaseAddr + R_SPI_CFG_BDE, BiosDecodeEnable);
+  } else {
+    BaseAddr = LpcPciBase ();
+    //
+    // 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  = LpcPciBase ();
+
+  //
+  // 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 = LpcPciBase ();
+
+  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);
+}
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port.
+  System BIOS is likely to do this very soon after reset before PCI bus enumeration.
+  This cycle decoding is allowed to set when DMI is unlocked
+
+  @param[in] RpNumber                PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoPort80DecodeSet (
+  IN  UINTN                             RpNumber
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PchDmiSetIoPort80Decode (RpNumber);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Get IO APIC registers base address.
+
+  @param[out] IoApicBase                Buffer of IO APIC register address
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoApicBaseGet (
+  OUT UINT32                            *IoApicBase
+  )
+{
+  *IoApicBase = PcdGet32 (PcdIoApicBaseAddress);
+  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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c
new file mode 100644
index 0000000000..1bbecc71ed
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c
@@ -0,0 +1,505 @@
+/** @file
+  This file contains routines for eSPI
+
+  Copyright (c) 2019 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/PchEspiLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/TimerLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsPcr.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 (IsPchH () && ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAPS) & R_ESPI_PCR_SOFTSTRAPS_CS1_EN) != 0));
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Data32;
+  UINT8       SupportedChannels;
+
+  Status = PchEspiSlaveGetConfig (SlaveId, R_ESPI_SLAVE_GENCAP, &Data32);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  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 a PCH_H
+  //
+  if ((SlaveId == 1) && (IsPchLp ())) {
+    DEBUG ((DEBUG_ERROR, "eSPI Slave ID of 1 is only available on PCH_H \n"));
+    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);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = 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;
+  EFI_STATUS  Status;
+
+  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) {
+    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    if ((Data32 & B_ESPI_SLAVE_BME) != 0) {
+      Data32 &= ~(B_ESPI_SLAVE_BME);
+      Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+      SlaveBmeSet = TRUE;
+    }
+  }
+
+  // Disable channel
+  Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Data32 &= ~(B_ESPI_SLAVE_CHACAP_CHEN);
+  Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  // Enable channel
+  Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Data32 |= B_ESPI_SLAVE_CHACAP_CHEN;
+  Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  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)) {
+    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    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) {
+    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    Data32 |= B_ESPI_SLAVE_BME;
+    Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c
new file mode 100644
index 0000000000..652a47ebaf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c
@@ -0,0 +1,82 @@
+/** @file
+  PCH Gbe Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.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
+PchIsGbeRegionValid (
+  VOID
+  )
+{
+  UINT32  SpiBar;
+  SpiBar = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
+                               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                               DEFAULT_PCI_BUS_NUMBER_PCH,
+                               PCI_DEVICE_NUMBER_PCH_SPI,
+                               PCI_FUNCTION_NUMBER_PCH_SPI,
+                               R_SPI_CFG_BAR0)) & ~B_SPI_CFG_BAR0_MASK;
+  ASSERT (SpiBar != 0);
+  if (MmioRead32 (SpiBar + R_SPI_MEM_FREG3_GBE) != B_SPI_MEM_FREGX_BASE_MASK) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/**
+  Check whether LAN controller is enabled in the platform.
+
+  @retval TRUE                    GbE is enabled
+  @retval FALSE                   GbE is disabled
+**/
+BOOLEAN
+PchIsGbePresent (
+  VOID
+  )
+{
+  //
+  // Check PCH Support
+  //
+  if (!PchIsGbeSupported ()) {
+    return FALSE;
+  }
+  //
+  // Check PMC strap/fuse
+  //
+  if (!PmcIsGbeSupported ()) {
+    return FALSE;
+  }
+  //
+  // Check GbE NVM
+  //
+  if (PchIsGbeRegionValid () == FALSE) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c
new file mode 100644
index 0000000000..2be8e8ed49
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c
@@ -0,0 +1,127 @@
+/** @file
+  PCH HSIO Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <PchAccess.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchHsioLib.h>
+
+/**
+  The function returns the Port Id and lane owner for the specified lane
+
+  @param[in]  PhyMode             Phymode that needs to be checked
+  @param[out] PortId              Common Lane End Point ID
+  @param[out] LaneOwner           Lane Owner
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid lane number
+**/
+EFI_STATUS
+EFIAPI
+PchGetLaneInfo (
+  IN  UINT32                            LaneNum,
+  OUT UINT8                             *PortId,
+  OUT UINT8                             *LaneOwner
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[out] LaneNum                   GBE Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetGbeLaneNum (
+  UINT8               *LaneNum
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  Usb3LaneIndex             USB3 Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetUsb3LaneNum (
+  UINT32              Usb3LaneIndex,
+  UINT8               *LaneNum
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  SataLaneIndex             Sata Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetSataLaneNum (
+  UINT32              SataLaneIndex,
+  UINT8               *LaneNum
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Determine the lane number of a specified port
+
+  @param[in]  PcieLaneIndex             PCIE Root Port Lane Index
+  @param[out] LaneNum                   Lane Number
+
+  @retval EFI_SUCCESS                   Lane number valid.
+  @retval EFI_UNSUPPORTED               Incorrect input device port
+**/
+EFI_STATUS
+PchGetPcieLaneNum (
+  UINT32              PcieLaneIndex,
+  UINT8               *LaneNum
+  )
+{
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get HSIO lane representation needed to perform any operation on the lane.
+
+  @param[in]  LaneIndex  Number of the HSIO lane
+  @param[out] HsioLane   HSIO lane representation
+**/
+VOID
+HsioGetLane (
+  IN   UINT8       LaneIndex,
+  OUT  HSIO_LANE   *HsioLane
+  )
+{
+
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
new file mode 100644
index 0000000000..7c3ade49b6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
@@ -0,0 +1,272 @@
+/** @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) 2019 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 <Register/PchRegsPcie.h>
+#include <IndustryStandard/Pci30.h>
+
+/**
+  Return LPC Device Id
+
+  @retval PCH_LPC_DEVICE_ID         PCH Lpc Device ID
+**/
+UINT16
+PchGetLpcDid (
+  VOID
+  )
+{
+  UINT64  LpcBaseAddress;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+
+  return PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
+}
+
+/**
+  Return Pch Series
+
+  @retval PCH_SERIES            Pch Series
+**/
+PCH_SERIES
+PchSeries (
+  VOID
+  )
+{
+  PCH_SERIES        PchSer;
+  static PCH_SERIES PchSeries = PCH_UNKNOWN_SERIES;
+
+  if (PchSeries != PCH_UNKNOWN_SERIES) {
+    return PchSeries;
+  }
+
+  PchSer = PchSeriesFromLpcDid (PchGetLpcDid ());
+
+  PchSeries = PchSer;
+
+  return PchSer;
+}
+
+/**
+  Return Pch stepping type
+
+  @retval PCH_STEPPING            Pch stepping type
+**/
+PCH_STEPPING
+PchStepping (
+  VOID
+  )
+{
+  UINT8                RevId;
+  UINT64               LpcBaseAddress;
+  static PCH_STEPPING  PchStepping = PCH_STEPPING_MAX;
+
+  if (PchStepping != PCH_STEPPING_MAX) {
+    return PchStepping;
+  }
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+  RevId = PciSegmentRead8 (LpcBaseAddress + PCI_REVISION_ID_OFFSET);
+
+  PchStepping = RevId;
+
+  return RevId;
+}
+
+/**
+  Determine if PCH is supported
+
+  @retval TRUE                    PCH is supported
+  @retval FALSE                   PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+  VOID
+  )
+{
+  UINT16         LpcDeviceId;
+  UINT16         LpcVendorId;
+  UINT64         LpcBaseAddress;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_LPC,
+                     PCI_FUNCTION_NUMBER_PCH_LPC,
+                     0
+                     );
+
+  LpcDeviceId = PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
+  LpcVendorId = PciSegmentRead16 (LpcBaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  ///
+  /// Verify that this is a supported chipset
+  ///
+  if ((LpcVendorId == V_LPC_CFG_VENDOR_ID) && (PchSeries () != PCH_UNKNOWN_SERIES)) {
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_ERROR, "PCH code doesn't support the LpcDeviceId: 0x%04x!\n", LpcDeviceId));
+    return FALSE;
+  }
+}
+
+/**
+  Check if this is PCH LP series
+
+  @retval TRUE                It's PCH LP series
+  @retval FALSE               It's not PCH LP series
+**/
+BOOLEAN
+IsPchLp (
+  VOID
+  )
+{
+  return (PchSeries () == PCH_LP);
+}
+
+/**
+  Check if this is PCH H series
+
+  @retval TRUE                It's PCH H series
+  @retval FALSE               It's not PCH H series
+**/
+BOOLEAN
+IsPchH (
+  VOID
+  )
+{
+  return (PchSeries () == PCH_H);
+}
+
+/**
+  Check if this is CDF PCH generation
+
+  @retval TRUE                It's CDF PCH
+  @retval FALSE               It's not CDF PCH
+**/
+BOOLEAN
+IsCdfPch (
+  VOID
+  )
+{
+  return (PchGeneration () == CDF_PCH);
+}
+
+/**
+  Check if this is PCH generation
+
+  @retval TRUE                It's CNL PCH
+  @retval FALSE               It's not CNL PCH
+**/
+BOOLEAN
+IsCnlPch (
+  VOID
+  )
+{
+  return (PchGeneration () == CNL_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;
+  }
+
+  AsciiSPrint (Buffer, BufferSize, "%c%c", 'A' + (PchStep >> 4), '0' + (PchStep & 0xF));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get PCH Sku ASCII string
+  The return string is zero terminated.
+
+  @retval Static ASCII string of PCH Sku
+**/
+CHAR8*
+PchGetSkuStr (
+  VOID
+  )
+{
+  UINTN          Index;
+  UINT16         LpcDid;
+
+  LpcDid = PchGetLpcDid ();
+
+  for (Index = 0; mSkuStrs[Index].Id != 0xFFFF; Index++) {
+    if (LpcDid == mSkuStrs[Index].Id) {
+      return mSkuStrs[Index].String;
+    }
+  }
+
+  return "Undefined SKU";
+}
+
+/**
+  Get Pch Maximum Pcie Controller Number
+
+  @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPcieControllerNum (
+  VOID
+  )
+{
+  return GetPchMaxPciePortNum () / PCH_PCIE_CONTROLLER_PORTS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c
new file mode 100644
index 0000000000..7b09a2dbb9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c
@@ -0,0 +1,87 @@
+/** @file
+  Common Pch information library for Client PCH silicon.
+
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+
+/**
+  Get Pch Maximum Pcie Clock Number
+
+  @retval Pch Maximum Pcie Clock Number
+**/
+UINT8
+GetPchMaxPcieClockNum (
+  VOID
+  )
+{
+  if (IsPchH ()) {
+    return 16;
+  } else {
+    return 6;
+  }
+}
+
+/**
+  Get Pch Maximum Serial IO controllers number
+
+  @retval Pch Maximum Serial IO controllers number
+**/
+UINT8
+GetPchMaxSerialIoControllersNum (
+  VOID
+  )
+{
+  return 12;
+}
+
+/**
+  Get Pch Maximum Serial IO I2C controllers number
+
+  @retval Pch Maximum Serial IO I2C controllers number
+**/
+UINT8
+GetPchMaxSerialIoI2cControllersNum (
+  VOID
+  )
+{
+  if (IsPchH ()) {
+    return 4;
+  } else {
+    return 6;
+  }
+}
+
+/**
+  Get Pch Maximum Serial IO SPI controllers number
+
+  @retval Pch Maximum Serial IO SPI controllers number
+**/
+UINT8
+GetPchMaxSerialIoSpiControllersNum (
+  VOID
+  )
+{
+  return 3;
+}
+
+/**
+  Get Pch Maximum Serial IO UART controllers number
+
+  @retval Pch Maximum Serial IO UART controllers number
+**/
+UINT8
+GetPchMaxSerialIoUartControllersNum (
+  VOID
+  )
+{
+  return 3;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c
new file mode 100644
index 0000000000..431b1470c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c
@@ -0,0 +1,386 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsLpcCnl.h>
+#include "PchInfoLibPrivate.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegsLpc.h>
+
+/**
+  Determine Pch Series based on Device Id
+
+  @param[in] LpcDeviceId      Lpc Device Id
+
+  @retval PCH_SERIES          Pch Series
+**/
+PCH_SERIES
+PchSeriesFromLpcDid (
+  IN UINT16 LpcDeviceId
+  )
+{
+  switch (LpcDeviceId & B_LPC_CFG_DID) {
+
+    case V_LPC_CFG_DID_CNL_H:
+      return PCH_H;
+
+    case V_LPC_CFG_DID_CNL_LP:
+      return PCH_LP;
+
+    default:
+      return PCH_UNKNOWN_SERIES;
+  }
+}
+
+/**
+  Return Pch Generation
+
+  @retval PCH_GENERATION            Pch Generation
+**/
+PCH_GENERATION
+PchGeneration (
+  VOID
+  )
+{
+  return CNL_PCH;
+}
+
+/**
+  Check if this is Server PCH
+
+  @retval TRUE                It's a Server PCH
+  @retval FALSE               It's not a Server PCH
+**/
+BOOLEAN
+IsPchServer (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Get RST mode supported by the silicon
+
+  @retval RST_MODE    RST mode supported by silicon
+**/
+RST_MODE
+PchGetSupportedRstMode (
+  VOID
+  )
+{
+  switch (PchGetLpcDid ()) {
+
+    case V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4:
+    case V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU:
+      return RstUnsupported;
+      break;
+
+    default:
+      return RstPremium;
+      break;
+  }
+}
+
+/**
+  Check if this is Server SKU
+
+  @retval TRUE                It's PCH Server SKU
+  @retval FALSE               It's not PCH Server SKU
+**/
+BOOLEAN
+IsPchServerSku (
+  VOID
+  )
+{
+  UINT16 LpcDid;
+
+  LpcDid = PchGetLpcDid ();
+
+  if (LpcDid == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Get PCH series ASCII string.
+
+  @retval PCH Series string
+**/
+CHAR8*
+PchGetSeriesStr (
+  VOID
+  )
+{
+  switch (PchSeries ()) {
+
+    case PCH_LP:
+      return "CNL PCH-LP";
+
+    case PCH_H:
+      return "CNL PCH-H";
+
+    default:
+      return NULL;
+  }
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+struct PCH_SKU_STRING mSkuStrs[] = {
+  //
+  // PCH LP Mobile LPC Device IDs
+  //
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU, "Super SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0, "(U) Super SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1, "Super SKU (locked)"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2, "(Y) Premium SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3, "(U) Premium  SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4, "(U) Base/Mainstream SKU"},
+  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5, "(Y) Super SKU"},
+  //
+  // PCH H LPC Device IDs
+  //
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU, "CNL PCH-H SKU A300"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU, "H310"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU, "H370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU, "Z390"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU, "Q370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU, "C246"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU, "C242"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU, "X399"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU, "QM370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU, "HM370"},
+  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU, "CM246"},
+  {0xFFFF, NULL}
+};
+
+/**
+  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;
+}
+
+/**
+  Get Pch Maximum Pcie Root Port Number
+
+  @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPciePortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 16;
+  } else {
+    return 24;
+  }
+}
+
+/**
+  Get Pch Usb2 Maximum Physical Port Number
+
+  @retval Pch Usb2 Maximum Physical Port Number
+**/
+UINT8
+GetPchUsb2MaxPhysicalPortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 10;
+  } else {
+    return 14;
+  }
+}
+
+/**
+  Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb2PortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 12;
+  } else {
+    return 16;
+  }
+}
+
+/**
+  Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb3PortNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 6;
+  } else {
+    return 10;
+  }
+}
+
+/**
+  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 PCH_HDAUDIO_IDISP_TMODE Tmode
+  )
+{
+  //
+  // iDisplay Audio Link T-mode support per PCH Generation/Series:
+  // 1. 1T  - CNP-LP
+  // 2. 2T  - CNP-LP/H (default)
+  //
+  switch (Tmode) {
+    case PchHdaIDispMode1T:
+      return IsPchLp ();
+    case PchHdaIDispMode2T:
+      return TRUE;
+    case PchHdaIDispMode4T:
+    case PchHdaIDispMode8T:
+    case PchHdaIDispMode16T:
+    default:
+      return FALSE;
+  }
+}
+
+/**
+  Gets the maximum number of UFS controller supported by this chipset.
+
+  @return Number of supported UFS controllers
+**/
+UINT8
+PchGetMaxUfsNum (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/**
+  Check if this chipset supports eMMC controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchEmmcSupported (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Check if this chipset supports SD controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchSdCardSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Check if this chipset supports UFS controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchUfsSupported (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  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 IsPchH ();
+}
+
+/**
+  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 !IsPchH ();
+}
+
+/**
+  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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
new file mode 100644
index 0000000000..9997c3612b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
@@ -0,0 +1,183 @@
+/** @file
+  PCH 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) 2019 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 <Register/PchRegsPcie.h>
+#include <Register/PchRegsPcr.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[] = {
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPA,  0 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPB,  4 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPC,  8 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPD, 12 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPE, 16 }, // PCH-H only
+  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPF, 20 }  // PCH-H only
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 mPchPcieControllerInfoSize = sizeof (mPchPcieControllerInfo) / sizeof (mPchPcieControllerInfo[0]);
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchLpRstPcieStorageSupportedPort[] = {
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP1..RP4
+  RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,         // RP5..RP8
+  RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,         // RP9..RP12
+  RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3          // RP13..RP16
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchHRstPcieStorageSupportedPort[] = {
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP1..RP4
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP5..RP8
+  RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,         // RP9..RP12
+  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   // RP13..RP16
+  RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,         // RP17..RP20
+  RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2          // RP21..RP24
+};
+
+/**
+  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;
+}
+
+/**
+  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
+  )
+{
+  UINTN       RpDevice;
+  UINTN       RpFunction;
+
+  GetPchPcieRpDevFun (RpIndex, &RpDevice, &RpFunction);
+
+  return PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+}
+
+/**
+  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 ();
+}
+
+/**
+  Check the RST PCIe Storage Cycle Router number according to the root port number and PCH type
+
+  @param[in] RootPortNum  Root Port Number
+
+  @return  The RST PCIe Storage Cycle Router Number
+**/
+UINT8
+RstGetCycleRouterNumber (
+  IN  UINT32                   RootPortNum
+  )
+{
+  if (IsPchLp ()) {
+    if (RootPortNum < ARRAY_SIZE (mPchLpRstPcieStorageSupportedPort)) {
+      return mPchLpRstPcieStorageSupportedPort[RootPortNum];
+    }
+  } else if (IsPchH ()) {
+    if (RootPortNum < ARRAY_SIZE (mPchHRstPcieStorageSupportedPort)) {
+      return mPchHRstPcieStorageSupportedPort[RootPortNum];
+    }
+  }
+  return RST_PCIE_STORAGE_CR_INVALID;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
new file mode 100644
index 0000000000..6f70733fe7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
@@ -0,0 +1,279 @@
+/** @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) 2019 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 <Register/PchRegsPcr.h>
+
+#ifndef MDEPKG_NDEBUG
+/**
+  Checks if the offset is valid for a given memory access width
+
+  @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 (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFF)) {
+    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);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c
new file mode 100644
index 0000000000..2654a76983
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c
@@ -0,0 +1,101 @@
+/** @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) 2019 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/MmPciLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPmcLib.h>
+
+/**
+  Query PCH to determine the Pm Status
+  NOTE:
+  It's matter when did platform code use this library, since some status could be cleared by write one clear.
+  Therefore this funciton is not always return the same result in one boot.
+  It's suggested that platform code read this status in the beginning of post.
+  For the ColdBoot case, this function only returns one case of the cold boot. Some cold boot case might
+  depends on the power cycle scenario and should check with different condtion.
+
+  @param[in] PmStatus - The Pch Pm Status to be probed
+
+  @retval Return TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+  PCH_PM_STATUS PmStatus
+  )
+{
+  UINTN  PmcRegBase;
+  UINT32 GblRst0;
+
+  PmcRegBase = MmPciBase (
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_PMC,
+                 PCI_FUNCTION_NUMBER_PCH_PMC
+                 );
+
+  switch (PmStatus) {
+    case WarmBoot:
+      break;
+
+    case PwrFlr:
+      break;
+
+    case PwrFlrSys:
+      if (GblRst0 & BIT12) {
+        return TRUE;
+      }
+      break;
+
+    case PwrFlrPch:
+      if (GblRst0 & BIT11) {
+        return TRUE;
+      }
+      break;
+
+    case ColdBoot:
+      break;
+
+    default:
+      break;
+  }
+
+  return FALSE;
+}
+
+/**
+  Funtion to check if Battery lost or CMOS cleared.
+
+  @reval TRUE  Battery is always present.
+  @reval FALSE CMOS is cleared.
+**/
+BOOLEAN
+EFIAPI
+PchIsRtcBatteryGood (
+  VOID
+  )
+{
+  UINTN    PmcBaseAddress;
+
+  //
+  // Check if the CMOS battery is present
+  // Checks RTC_PWR_STS bit in the GEN_PMCON_3 register
+  //
+  PmcBaseAddress = MmPciBase (
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_PMC,
+                     PCI_FUNCTION_NUMBER_PCH_PMC
+                     );
+  return FALSE;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
new file mode 100644
index 0000000000..43690e2409
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
@@ -0,0 +1,270 @@
+/** @file
+  PCH SBI access library.
+
+  Copyright (c) 2019 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 <Register/PchRegs.h>
+#include <Register/PchRegsP2sb.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
+EFIAPI
+PchSbiExecution (
+  IN     PCH_SBI_PID                    Pid,
+  IN     UINT64                         Offset,
+  IN     PCH_SBI_OPCODE                 Opcode,
+  IN     BOOLEAN                        Posted,
+  IN OUT UINT32                         *Data32,
+  OUT    UINT8                          *Response
+  )
+{
+  //
+  // Check address valid
+  //
+  if (((UINT32) Offset & 0x3) != 0) {
+    //
+    // Warning message for the address not DWORD alignment.
+    //
+    DEBUG ((DEBUG_INFO, "PchSbiExecution: Address is not DWORD aligned.\n"));
+  }
+
+  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
+EFIAPI
+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 = PCI_SEGMENT_LIB_ADDRESS (
+               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+               DEFAULT_PCI_BUS_NUMBER_PCH,
+               PCI_DEVICE_NUMBER_PCH_P2SB,
+               PCI_FUNCTION_NUMBER_PCH_P2SB,
+               0
+               );
+  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 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 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 {
+      return EFI_DEVICE_ERROR;
+    }
+  }
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c
new file mode 100644
index 0000000000..0e79d83a12
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c
@@ -0,0 +1,516 @@
+/** @file
+  PCH Serial IO Lib implementation.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <SaAccess.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchSerialIoUartLib.h>
+#include <Include/PcieRegs.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsSerialIo.h>
+
+#define PCIEX_BAR_ADDR_MASK  0x0000007FFC000000
+
+typedef struct {
+  UINT32 Bar0;
+  UINT32 Bar1;
+} SERIAL_IO_CONTROLLER_DESCRIPTOR;
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR mSerialIoAcpiAddress [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  {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},
+  {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}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchSerialIoPciCfgCtrAddr [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  R_SERIAL_IO_PCR_PCICFGCTRL1,
+  R_SERIAL_IO_PCR_PCICFGCTRL2,
+  R_SERIAL_IO_PCR_PCICFGCTRL3,
+  R_SERIAL_IO_PCR_PCICFGCTRL4,
+  R_SERIAL_IO_PCR_PCICFGCTRL5,
+  R_SERIAL_IO_PCR_PCICFGCTRL6,
+  R_SERIAL_IO_PCR_PCICFGCTRL13,
+  R_SERIAL_IO_PCR_PCICFGCTRL14,
+  R_SERIAL_IO_PCR_PCICFGCTRL9,
+  R_SERIAL_IO_PCR_PCICFGCTRL10,
+  R_SERIAL_IO_PCR_PCICFGCTRL11
+};
+
+/**
+  Returns Serial IO Controller Type  I2C, SPI or UART
+
+  @param[in] Number  Number of SerialIo controller
+
+  @retval            I2C, SPI or UART
+  @retval            UNKNOWN - in case if undefined controller
+**/
+PCH_SERIAL_IO_CONTROLLER_TYPE
+GetSerialIoControllerType (
+  IN PCH_SERIAL_IO_CONTROLLER  Controller
+  )
+{
+  if (Controller >= PchSerialIoIndexI2C0 && Controller <= GetMaxI2cNumber ()) {
+    return SERIAL_IO_I2C;
+  } else if (Controller >= PchSerialIoIndexSpi0 && Controller < (PchSerialIoIndexSpi0 + GetPchMaxSerialIoSpiControllersNum ())) {
+    return SERIAL_IO_SPI;
+  } else if (Controller >= PchSerialIoIndexUart0 && Controller <= PchSerialIoIndexUart2) {
+    return SERIAL_IO_UART;
+  }
+  return SERIAL_IO_UNKNOWN;
+}
+
+/**
+  Checks if given Serial IO Controller Function equals 0
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               TRUE if SerialIO Function is equal to 0
+                                        FALSE if Function is higher then 0
+**/
+BOOLEAN
+IsSerialIoFunctionZero (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  )
+{
+  if (GetSerialIoFunctionNumber (SerialIoNumber) > 0) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Checks if given Serial IO Controller is enabled or not
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval TRUE                          TRUE if given serial io device is enabled.
+  @retval FALSE                         FALSE if given serial io device is disabled.
+**/
+BOOLEAN
+IsSerialIoDeviceEnabled (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  )
+{
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, DeviceNumber, FunctionNumber, PCI_DEVICE_ID_OFFSET)) != 0xFFFF) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Checks if given device corresponds to any of LPSS Devices
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval                               TRUE if SerialIO Device/Function Number is equal to any of LPSS devices
+                                        FALSE Device/Function is not in Serial IO scope
+**/
+BOOLEAN
+IsSerialIoDevice (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER  Controller;
+  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
+
+  ControllerMax = GetPchMaxSerialIoControllersNum ();
+
+  for (Controller = 0; Controller < ControllerMax; Controller++) {
+    if ((DeviceNumber == GetSerialIoDeviceNumber (Controller)) &&
+        (FunctionNumber == GetSerialIoFunctionNumber (Controller))) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Gets Pci Config control offset
+
+  @param[in] DeviceNumber               device number
+  @param[in] FunctionNumber             function number
+
+  @retval    CfgCtrAddr                 Offset of Pci config control
+                                        0 if Device and Function do not correspond to Serial IO
+**/
+UINT16
+GetSerialIoConfigControlOffset (
+  IN UINT8  DeviceNumber,
+  IN UINT8  FunctionNumber
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER  Controller;
+  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
+
+  ControllerMax = GetPchMaxSerialIoControllersNum ();
+
+  for (Controller = 0; Controller < ControllerMax; Controller++) {
+    if ((DeviceNumber == GetSerialIoDeviceNumber (Controller)) &&
+        (FunctionNumber == GetSerialIoFunctionNumber (Controller))) {
+      return mPchSerialIoPciCfgCtrAddr[Controller];
+    }
+  }
+
+  return 0;
+}
+
+/**
+  Checks if Device with given AcpiHid string is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  AcpiHid                   String
+  @param[out] Number                    Number of SerialIo controller
+
+  @retval TRUE                          yes it is a SerialIo controller
+  @retval FALSE                         no it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoAcpiHid (
+  IN CHAR8                      *AcpiHid,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Controller;
+  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
+
+  ControllerMax = GetPchMaxSerialIoControllersNum ();
+
+  for (Controller = 0; Controller < ControllerMax; Controller++) {
+    if (!AsciiStrCmp ((const CHAR8 *) AcpiHid, GetSerialIoAcpiHid(Controller))) {
+      *Number = Controller;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Finds BAR values of SerialIo devices.
+  SerialIo devices can be configured to not appear on PCI so traditional method of reading BAR might not work.
+  If the SerialIo device is in PCI mode, a request for BAR1 will return its PCI CFG space instead
+
+  @param[in] SerialIoDevice             Serial IO device
+  @param[in] BarNumber                  0=BAR0, 1=BAR1
+
+  @retval                               SerialIo Bar value
+**/
+UINTN
+FindSerialIoBar (
+  IN PCH_SERIAL_IO_CONTROLLER           SerialIoDevice,
+  IN UINT8                              BarNumber
+  )
+{
+  UINT64   Bar;
+  UINT64   PcieBase;
+  UINT64   PciSegBase;
+  UINT16   VenId;
+  UINT32   Device;
+  UINT32   Function;
+
+  Device   = GetSerialIoDeviceNumber (SerialIoDevice);
+  Function = GetSerialIoFunctionNumber (SerialIoDevice);
+
+  PcieBase = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_PCIEXBAR)); // S0:B0:D0:F0:R60
+  PcieBase = (PcieBase & PCIEX_BAR_ADDR_MASK) + LShiftU64 (DEFAULT_PCI_BUS_NUMBER_PCH, 20) + LShiftU64 (Device, 15) + LShiftU64 (Function, 12);
+
+  PciSegBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 Device,
+                 Function,
+                 0
+                 );
+
+  VenId = PciSegmentRead16 (PciSegBase + PCI_VENDOR_ID_OFFSET) & 0xFFFF;
+  if (VenId == V_PCH_INTEL_VENDOR_ID) {
+    if (BarNumber == 1) {
+      return ((UINTN) PcieBase);
+    }
+    Bar = PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET);
+    // For 64-Bit Memory Space BARs ((BAR[x] & 0xFFFFFFF0) + ((BAR[x+1] & 0xFFFFFFFF) << 32)
+    if ((Bar & B_PCI_BAR_MEMORY_TYPE_MASK) == B_PCI_BAR_MEMORY_TYPE_64) {
+      Bar = (Bar & 0xFFFFF000) + (UINTN) ((UINT64) LShiftU64 ((PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET + 4) & 0xFFFFFFFF), 32));
+      return (UINTN) Bar;
+    }
+    return (UINTN) (Bar & 0xFFFFF000);
+  }
+  //PCI mode failed? Try hardcoded addresses from ACPI
+  if (BarNumber == 0) {
+    Bar = mSerialIoAcpiAddress[SerialIoDevice].Bar0;
+  } else {
+    Bar = mSerialIoAcpiAddress[SerialIoDevice].Bar1;
+  }
+  return (UINTN) Bar;
+}
+
+/**
+  Get PSF_PORT for a given Serial IO Controller
+
+  @param[in] Controller    Serial IO controller number
+**/
+STATIC
+PSF_PORT
+SerialIoPsfPort (
+  IN PCH_SERIAL_IO_CONTROLLER Controller
+  )
+{
+  switch (GetSerialIoControllerType (Controller)) {
+    case SERIAL_IO_I2C:
+      return PsfSerialIoI2cPort (Controller - PchSerialIoIndexI2C0);
+    case SERIAL_IO_SPI:
+      return PsfSerialIoSpiPort (Controller - PchSerialIoIndexSpi0);
+    case SERIAL_IO_UART:
+      return PsfSerialIoUartPort (Controller - PchSerialIoIndexUart0);
+    case SERIAL_IO_UNKNOWN:
+    default:
+      return (PSF_PORT){0};
+  }
+}
+
+/**
+  Configures Serial IO Controller
+
+  @param[in] Controller    Serial IO controller number
+  @param[in] DeviceMode    Device operation mode
+  @param[in] PsfDisable    Disable device at PSF level
+
+  @retval None
+**/
+VOID
+ConfigureSerialIoController (
+  IN PCH_SERIAL_IO_CONTROLLER Controller,
+  IN PCH_SERIAL_IO_MODE       DeviceMode,
+  IN BOOLEAN                  PsfDisable
+  )
+{
+  UINT64          PciCfgBase;
+  UINT32          Data32And;
+  UINT32          Data32Or;
+  UINT16          *SerialIoPciCfgCtrAddr;
+  UINT8           Uart8BitLoop;
+
+/*
+  Please do not add DEBUG message here because this routine is configuring SerialIoUart.
+  Printing DEBUG message before SerialIoUart initialization may cause system hang (in Debug build).
+*/
+
+  //
+  // This is to prevent from overflow of array access.
+  //
+  if (Controller >= PCH_MAX_SERIALIO_CONTROLLERS) {
+    return;
+  }
+
+  if (GetSerialIoControllerType (Controller) == SERIAL_IO_UNKNOWN) {
+    return;
+  }
+
+  PciCfgBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 GetSerialIoDeviceNumber (Controller),
+                 GetSerialIoFunctionNumber (Controller),
+                 0
+                 );
+  //
+  // Do not modify a device that has already been disabled/hidden
+  //
+  if (PciSegmentRead16 (PciCfgBase + PCI_VENDOR_ID_OFFSET) != V_PCH_INTEL_VENDOR_ID) {
+    return;
+  }
+
+  ///
+  /// Step 0. set Bit 16,17,18.
+  ///
+  PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_D0I3MAXDEVPG, BIT18 | BIT17 | BIT16);
+
+  SerialIoPciCfgCtrAddr = mPchSerialIoPciCfgCtrAddr;
+
+  switch (DeviceMode) {
+    case PchSerialIoDisabled:
+      ///
+      /// Step 1. Put device in D3
+      /// Step 2. Function Disable in PSF
+      ///
+      PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0);
+
+      if (PsfDisable) {
+        PsfDisableDevice (SerialIoPsfPort (Controller));
+      }
+      break;
+    case PchSerialIoAcpi:
+    case PchSerialIoHidden:
+      ///
+      /// reenable BAR1 in case it was disabled earlier
+      /// Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS),
+        0
+        );
+      PsfEnableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2);
+      ///
+      /// Step 1. Assign BAR0
+      /// Step 2. Assign BAR1
+      ///
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,  mSerialIoAcpiAddress[Controller].Bar0);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_LOW,  mSerialIoAcpiAddress[Controller].Bar1);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_HIGH, 0x0);
+      ///
+      /// Step 3. Set Memory space Enable
+      ///
+      PciSegmentOr32 (PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+      ///
+      /// Step 4. Disable device's PciCfg and enable ACPI interrupts
+      ///         Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        ~0u,
+        (B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS | B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN)
+        );
+      ///
+      /// Step 5. Disable device's PciCfg in PSF
+      ///
+      PsfHideDevice (SerialIoPsfPort (Controller));
+      ///
+      /// get controller out of reset
+      ///
+      MmioOr32 (
+        mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_RESETS,
+        B_SERIAL_IO_MEM_PPR_RESETS_FUNC | B_SERIAL_IO_MEM_PPR_RESETS_APB | B_SERIAL_IO_MEM_PPR_RESETS_IDMA
+        );
+      break;
+    case PchSerialIoPci:
+      //
+      //  Check If device is already initialized
+      //
+      if (PciSegmentRead32 (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFF000) {
+        return;
+      }
+      ///
+      /// reenable PciCfg in case it was disabled earlier
+      /// Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS | B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN),
+        0
+        );
+      PsfUnhideDevice (SerialIoPsfPort (Controller));
+      ///
+      /// Disable Bar1
+      /// Disable Bar1 in PSF
+      /// Read back is needed to enforce the sideband and primary ordering.
+      ///
+      PchPcrAndThenOr32WithReadback (
+        PID_SERIALIO,
+        SerialIoPciCfgCtrAddr[Controller],
+        ~0u,
+        B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS
+        );
+      PsfDisableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2);
+
+      //
+      // Assign BAR0 and Set Memory space Enable
+      //
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,  mSerialIoAcpiAddress[Controller].Bar0);
+      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
+      PciSegmentOr32    (PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+      ///
+      /// get controller out of reset
+      ///
+      MmioOr32 (
+        mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_RESETS,
+        B_SERIAL_IO_MEM_PPR_RESETS_FUNC | B_SERIAL_IO_MEM_PPR_RESETS_APB | B_SERIAL_IO_MEM_PPR_RESETS_IDMA
+        );
+      break;
+    default:
+      return;
+  }
+
+  ///
+  /// Step X. Program clock dividers for UARTs
+  /// Step Y. Enable Byte addressing for UARTs in legacy mode
+  ///
+  if ((Controller >= PchSerialIoIndexUart0 && Controller <= PchSerialIoIndexUart2) && (DeviceMode != PchSerialIoDisabled)) {
+    MmioWrite32 (mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_CLK,
+      (B_SERIAL_IO_MEM_PPR_CLK_UPDATE | (V_SERIAL_IO_MEM_PPR_CLK_N_DIV << 16) |
+       (V_SERIAL_IO_MEM_PPR_CLK_M_DIV << 1) | B_SERIAL_IO_MEM_PPR_CLK_EN )
+      );
+
+    Data32And = (UINT32) (~(B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << (Controller - PchSerialIoIndexUart0)));
+    Data32Or = 0x0;
+    if (DeviceMode == PchSerialIoHidden) {
+      Data32Or = (B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << (Controller - PchSerialIoIndexUart0));
+    }
+    PchPcrAndThenOr32 (PID_SERIALIO, R_SERIAL_IO_PCR_GPPRVRW7,Data32And,Data32Or);
+    //
+    // Dummy read after setting any of GPPRVRW7.
+    // Required for UART 16550 8-bit Legacy mode to become active
+    //
+    MmioRead32 (mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_PPR_CLK);
+    //
+    // Loop until Uart has successfuly moved to 8 bit mode
+    //
+    if (DeviceMode == PchSerialIoHidden) {
+      Uart8BitLoop = 10;
+      while (Uart8BitLoop > 0) {
+        if (DetectAccessMode (mSerialIoAcpiAddress[Controller].Bar0) == AccessMode8bit) {
+          return;
+        }
+        Uart8BitLoop--;
+      }
+    }
+  }
+
+  ///
+  /// Step Z. Program I2C SDA hold registers
+  ///
+  if (Controller >= PchSerialIoIndexI2C0 && Controller <= GetMaxI2cNumber ()) {
+    if (DeviceMode != PchSerialIoDisabled) {
+      MmioOr32 (mSerialIoAcpiAddress[Controller].Bar0 + R_SERIAL_IO_MEM_I2C_SDA_HOLD, V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE);
+    }
+  }
+
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c
new file mode 100644
index 0000000000..28ccd626af
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c
@@ -0,0 +1,181 @@
+/** @file
+  PCH Serial IO Lib implementation Cannon Lake specific.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <IndustryStandard/Pci30.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+
+#include <PchLimits.h>
+#include <Register/PchRegsSerialIoCnl.h>
+#include "PchSerialIoLibInternal.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mCnlAcpiHid[PCH_MAX_SERIALIO_CONTROLLERS][SERIALIO_HID_LENGTH] =
+{
+  "INT34B2",
+  "INT34B3",
+  "INT34B4",
+  "INT34B5",
+  "INT34B6",
+  "INT34B7",
+  "INT34B0",
+  "INT34B1",
+  "INT34BC",
+  "INT34B8",
+  "INT34B9",
+  "INT34BA"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchLpSerialIoId [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID,
+  V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchHSerialIoId [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID,
+                                         0,
+                                         0,
+  V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID,
+  V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_BDF_NUMBERS mSerialIoBdf [PCH_MAX_SERIALIO_CONTROLLERS] =
+{
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1},
+  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2}
+};
+
+
+/**
+  Returns index of the last i2c controller
+
+  @param[in] Number                     Number of SerialIo controller
+
+  @retval                               Index of I2C controller
+**/
+PCH_SERIAL_IO_CONTROLLER
+GetMaxI2cNumber (
+  VOID
+  )
+{
+  if (IsPchH ()) {
+    return PchSerialIoIndexI2C3;
+  } else {
+    return PchSerialIoIndexI2C5;
+  }
+}
+
+/**
+  Checks if Device with given PciDeviceId is one of SerialIo controllers
+  If yes, its number is returned through Number parameter, otherwise Number is not updated
+
+  @param[in]  PciDevId                  Device ID
+  @param[out] Number                    Number of SerialIo controller
+
+  @retval TRUE                          Yes it is a SerialIo controller
+  @retval FALSE                         No it isn't a SerialIo controller
+**/
+BOOLEAN
+IsSerialIoPciDevId (
+  IN  UINT16                    PciDevId,
+  OUT PCH_SERIAL_IO_CONTROLLER  *Number
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Controller;
+
+  for (Controller = 0; Controller < GetPchMaxSerialIoControllersNum (); Controller++) {
+    if ((IsPchLp () && (PciDevId == mCnlPchLpSerialIoId[Controller])) ||
+        (IsPchH () && (PciDevId == mCnlPchHSerialIoId[Controller])))
+    {
+      *Number = Controller;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Finds PCI Device Number of SerialIo devices.
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo device number
+**/
+UINT8
+GetSerialIoDeviceNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  )
+{
+  return mSerialIoBdf[SerialIoNumber].DevNum;
+}
+
+/**
+  Finds PCI Function Number of SerialIo devices.
+
+  @param[in] SerialIoNumber             Serial IO device
+
+  @retval                               SerialIo funciton number
+**/
+UINT8
+GetSerialIoFunctionNumber (
+  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
+  )
+{
+  return mSerialIoBdf[SerialIoNumber].FuncNum;
+}
+
+/**
+  Returns string with AcpiHid assigned to selected SerialIo controller
+
+  @param[in] Number                     Number of SerialIo controller
+
+  @retval                               pointer to 8-byte string
+**/
+CHAR8*
+GetSerialIoAcpiHid (
+  IN PCH_SERIAL_IO_CONTROLLER Number
+  )
+{
+  return mCnlAcpiHid[Number];
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c
new file mode 100644
index 0000000000..621a473cfa
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c
@@ -0,0 +1,372 @@
+/** @file
+  PCH Serial IO UART Lib implementation.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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/PchPcrLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchSerialIoUartLib.h>
+#include <IndustryStandard/Pci30.h>
+
+#define MAX_BAUD_RATE      115200
+
+#define R_PCH_SERIAL_IO_8BIT_UART_RXBUF      0x00
+#define R_PCH_SERIAL_IO_8BIT_UART_TXBUF      0x00
+#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW   0x00
+#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH  0x01
+#define R_PCH_SERIAL_IO_8BIT_UART_FCR        0x02
+#define R_PCH_SERIAL_IO_8BIT_UART_IIR        0x02
+#define R_PCH_SERIAL_IO_8BIT_UART_LCR        0x03
+#define R_PCH_SERIAL_IO_8BIT_UART_MCR        0x04
+#define R_PCH_SERIAL_IO_8BIT_UART_LSR        0x05
+#define R_PCH_SERIAL_IO_8BIT_UART_USR        0x1F
+#define R_PCH_SERIAL_IO_32BIT_UART_CTR       0xFC //Component Type Register contains identification code
+#define UART_COMPONENT_IDENTIFICATION_CODE   0x44570110
+
+#define B_PCH_SERIAL_IO_UART_IIR_FIFOSE   BIT7|BIT6
+#define B_PCH_SERIAL_IO_UART_LSR_RXDA     BIT0
+#define B_PCH_SERIAL_IO_UART_LSR_BI       BIT4
+#define B_PCH_SERIAL_IO_UART_LSR_TXRDY    BIT5
+#define B_PCH_SERIAL_IO_UART_LCR_DLAB     BIT7
+#define B_PCH_SERIAL_IO_UART_FCR_FCR      BIT0
+#define B_PCH_SERIAL_IO_UART_MCR_RTS      BIT1
+#define B_PCH_SERIAL_IO_UART_MCR_AFCE     BIT5
+#define B_PCH_SERIAL_IO_UART_USR_TFNF     BIT1
+
+/**
+  Returns UART's currently active access mode, 8 or 32 bit
+
+  @param[in]  MmioBase    Base address of UART MMIO space
+
+  @retval     AccessMode8bit
+  @retval     AccessMode32bit
+**/
+UART_ACCESS_MODE
+DetectAccessMode (
+  IN UINTN  MmioBase
+  )
+{
+  if (MmioRead32 (MmioBase + R_PCH_SERIAL_IO_32BIT_UART_CTR) == UART_COMPONENT_IDENTIFICATION_CODE) {
+    return AccessMode32bit;
+  } else {
+    return AccessMode8bit;
+  }
+}
+
+
+/**
+  Register access helper. Depending on SerialIO UART mode,
+  its registers are aligned to 1 or 4 bytes and have 8 or 32bit size
+
+  @param[in]  AccessMode     Selects between 8bit access to 1-byte aligned registers or 32bit access to 4-byte algined
+  @param[in]  BaseAddress    Base address of UART MMIO space
+  @param[in]  Offset         Register offset in 8bit mode
+  @param[in]  Data           Data to be written
+**/
+STATIC
+VOID
+WriteRegister (
+  IN UART_ACCESS_MODE AccessMode,
+  IN UINTN            BaseAddress,
+  IN UINTN            Offset,
+  IN UINT8            Data
+  )
+{
+  if (AccessMode == AccessMode32bit) {
+    MmioWrite32 (BaseAddress + 4*Offset, Data);
+  } else {
+    MmioWrite8 (BaseAddress + Offset, Data);
+  }
+}
+
+/**
+  Register access helper. Depending on SerialIO UART mode,
+  its registers are aligned to 1 or 4 bytes and have 8 or 32bit size
+
+  @param[in]  AccessMode     Selects between 8bit access to 1-byte aligned registers or 32bit access to 4-byte algined
+  @param[in]  BaseAddress    Base address of UART MMIO space
+  @param[in]  Offset         Register offset in 8bit mode
+  @retval                    retrieved register value, always 8bit regardless of access mode
+**/
+STATIC
+UINT8
+ReadRegister (
+  IN UART_ACCESS_MODE AccessMode,
+  IN UINTN            BaseAddress,
+  IN UINTN            Offset
+  )
+{
+  if (AccessMode == AccessMode32bit) {
+    return (UINT8) (0xFF & MmioRead32 (BaseAddress + 4*Offset));
+  } else {
+    return MmioRead8 (BaseAddress + Offset);
+  }
+}
+
+/**
+  SerialIo UART in PCI mode will become unavailable when PCI enumerator
+  disables its memory space. This function re-enables it
+
+  @param[in]  UartNumber           Selects Serial IO UART device (0-2)
+**/
+STATIC
+VOID
+EnablePciMse (
+  IN UINT8  UartNumber
+  )
+{
+  UINTN  CfgSpace;
+
+  CfgSpace = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 1);
+  if (MmioRead16 (CfgSpace + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+  if ((MmioRead16 (CfgSpace + PCI_COMMAND_OFFSET) & EFI_PCI_COMMAND_MEMORY_SPACE) != EFI_PCI_COMMAND_MEMORY_SPACE) {
+    if ((MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFF000) != 0x0 &&
+        (MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFF000) != 0xFFFFF000 ) {
+      MmioOr8 (CfgSpace + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+    }
+  }
+}
+
+/**
+  Initialize selected SerialIo UART.
+  This init function MUST be used prior any SerialIo UART functions to init serial io controller if platform is going use serialio UART as debug output.
+
+  @param  UartNumber           Selects Serial IO UART device (0-2)
+  @param  FifoEnable           When TRUE, enables 64-byte FIFOs.
+  @param  BaudRate             Baud rate.
+  @param  LineControl          Data length, parity, stop bits.
+  @param  HardwareFlowControl  Automated hardware flow control. If TRUE, hardware automatically checks CTS when sending data, and sets RTS when receiving data.
+**/
+VOID
+EFIAPI
+PchSerialIoUartInit (
+  UINT8            UartNumber,
+  BOOLEAN          FifoEnable,
+  UINT32           BaudRate,
+  UINT8            LineControl,
+  BOOLEAN          HardwareFlowControl
+  )
+{
+  UINTN            Base;
+  UINTN            Divisor;
+  UART_ACCESS_MODE AccessMode;
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    //
+    // Base is not programmed, skip it.
+    //
+    return;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  Divisor = MAX_BAUD_RATE / BaudRate;
+
+  //
+  // Configure baud rate
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR, B_PCH_SERIAL_IO_UART_LCR_DLAB);
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
+  //
+  //  Configure Line control and switch back to bank 0
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR, LineControl & 0x1F);
+  //
+  // Enable and reset FIFOs
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_FCR, FifoEnable?B_PCH_SERIAL_IO_UART_FCR_FCR:0 );
+  //
+  // Put Modem Control Register(MCR) into its reset state of 0x00.
+  //
+  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_MCR, B_PCH_SERIAL_IO_UART_MCR_RTS | (HardwareFlowControl?B_PCH_SERIAL_IO_UART_MCR_AFCE:0));
+}
+
+/**
+  Write data to serial device.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param  UartNumber       Selects Serial IO UART device (0-2)
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval                  Actual number of bytes writed to serial device.
+**/
+UINTN
+EFIAPI
+PchSerialIoUartOut (
+  IN UINT8            UartNumber,
+  IN UINT8            *Buffer,
+  IN UINTN            NumberOfBytes
+  )
+{
+  UINTN            BytesLeft;
+  UINTN            Base;
+  UART_ACCESS_MODE AccessMode;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  //
+  // Sanity checks to avoid infinite loop when trying to print through uninitialized UART
+  //
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    return 0;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) == 0xFF) {
+    return 0;
+  }
+
+  BytesLeft = NumberOfBytes;
+
+  while (BytesLeft != 0) {
+    //
+    // Write data while there's room in TXFIFO. If HW Flow Control was enabled, it happens automatically on hardware level.
+    //
+    if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) & B_PCH_SERIAL_IO_UART_USR_TFNF) {
+      WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_TXBUF, *Buffer);
+      Buffer++;
+      BytesLeft--;
+    }
+  }
+
+  return NumberOfBytes;
+}
+
+/*
+  Read data from serial device and save the datas in buffer.
+
+  If the buffer is NULL, then return 0;
+  if NumberOfBytes is zero, then return 0.
+
+  @param  UartNumber           Selects Serial IO UART device (0-2)
+  @param  Buffer               Point of data buffer which need to be writed.
+  @param  NumberOfBytes        Number of output bytes which are cached in Buffer.
+  @param  WaitUntilBufferFull  When TRUE, function waits until whole buffer is filled. When FALSE, function returns as soon as no new characters are available.
+
+  @retval                      Actual number of bytes raed to serial device.
+
+**/
+UINTN
+EFIAPI
+PchSerialIoUartIn (
+  IN  UINT8            UartNumber,
+  OUT UINT8            *Buffer,
+  IN  UINTN            NumberOfBytes,
+  IN  BOOLEAN          WaitUntilBufferFull
+  )
+{
+  UINTN            BytesReceived;
+  UINTN            Base;
+  UART_ACCESS_MODE AccessMode;
+  UINT8            Lsr;
+  UINT8            Byte;
+
+  if (NULL == Buffer) {
+    return 0;
+  }
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  //
+  // Sanity checks to avoid infinite loop when trying to print through uninitialized UART
+  //
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    return 0;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  BytesReceived = 0;
+
+  while (BytesReceived != NumberOfBytes) {
+    //
+    // Read the line status register
+    //
+    Lsr = ReadRegister(AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LSR);
+
+    //
+    // If there is data in the RX buffer, read it.
+    //
+    if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_RXDA) != 0) {
+      Byte = ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_RXBUF);
+      //
+      // Check if the break interrupt bit is set. If set, the byte read from the
+      // RX buffer is invalid and should be ignored. If not set, copy the byte into
+      // the receive buffer.
+      //
+      if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_BI) == 0) {
+        *Buffer = Byte;
+        Buffer++;
+        BytesReceived++;
+      }
+    } else {
+      if (!WaitUntilBufferFull) {
+        //
+        // If there's no data and function shouldn't wait, exit early
+        //
+        return BytesReceived;
+      }
+    }
+  }
+  return BytesReceived;
+}
+
+/**
+  Polls a serial device to see if there is any data waiting to be read.
+
+  Polls a serial device to see if there is any data waiting to be read.
+  If there is data waiting to be read from the serial device, then TRUE is returned.
+  If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+  @param  UartNumber       Selects Serial IO UART device (0-2)
+
+  @retval TRUE             Data is waiting to be read from the serial device.
+  @retval FALSE            There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+PchSerialIoUartPoll (
+  IN  UINT8            UartNumber
+  )
+{
+  UINTN Base;
+  UART_ACCESS_MODE AccessMode;
+
+  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
+  //
+  // Sanity checks to avoid infinite loop when trying to print through uninitialized UART
+  //
+  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
+    return 0;
+  }
+  EnablePciMse (UartNumber);
+  AccessMode = DetectAccessMode (Base);
+
+  //
+  // Read the serial port status
+  //
+  if ((ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LSR) & B_PCH_SERIAL_IO_UART_LSR_RXDA) != 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c
new file mode 100644
index 0000000000..679dcae0ab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c
@@ -0,0 +1,242 @@
+/** @file
+  Library that contains common parts of WdtPei and WdtDxe. Not a standalone module.
+
+  Copyright (c) 2019 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/PmcLib.h>
+#include <Register/PchRegsPmc.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8     mAllowExpectedReset = 0;
+
+/**
+  Reads LPC bridge to get Watchdog Timer address
+
+
+  @retval UINT32                  Watchdog's address
+**/
+UINT32
+WdtGetAddress (
+  VOID
+  )
+{
+  return PmcGetAcpiBase () + R_ACPI_IO_OC_WDT_CTL;
+}
+
+/**
+  Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+  causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+  function was called too.
+
+  @param[in] TimeoutValue         Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+  @retval EFI_SUCCESS             if everything's OK
+  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
+**/
+EFI_STATUS
+EFIAPI
+WdtReloadAndStart (
+  IN  UINT32  TimeoutValue
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "\n(Wdt) ReloadAndStartTimer(%d)\n", TimeoutValue));
+
+  if ((TimeoutValue > B_ACPI_IO_OC_WDT_CTL_TOV_MASK) || (TimeoutValue == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Readback = IoRead32 (WdtGetAddress ());
+  Readback |= (B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_ICCSURV);
+  if (mAllowExpectedReset == 0) {
+    Readback |= B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS;
+  }
+
+  if (PcdGetBool (PcdOcEnableWdtforDebug) == FALSE) {
+    ///
+    /// WDT will not be turned on. This is to prevent platform reboots triggered
+    /// by WDT expiration, which can be expected when processor is halted for debugging
+    ///
+    Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+    DEBUG ((DEBUG_INFO, "(Wdt) Wdt disabled in Debug BIOS\n"));
+  }
+
+  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
+  Readback |= ((TimeoutValue - 1) & B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
+  IoWrite32 (WdtGetAddress (), Readback);
+  Readback |= B_ACPI_IO_OC_WDT_CTL_RLD;
+  IoWrite32 (WdtGetAddress (), Readback);
+  return EFI_SUCCESS;
+}
+
+/**
+  Disables WDT timer.
+
+
+**/
+VOID
+EFIAPI
+WdtDisable (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) DisableTimer\n"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+  IoWrite32 (WdtGetAddress (), Readback);
+}
+
+/**
+  Returns WDT failure status.
+
+
+  @retval V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE   If there was WDT expiration or unexpected reset
+  @retval V_ACPI_IO_OC_WDT_CTL_STATUS_OK        Otherwise
+**/
+UINT8
+EFIAPI
+WdtCheckStatus (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) CheckTimerStatus\n"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+  DEBUG ((DEBUG_INFO, "(Wdt) Readback = (%x)\n", Readback));
+
+  if (Readback & B_ACPI_IO_OC_WDT_CTL_FAILURE_STS) {
+    DEBUG ((DEBUG_INFO, "(Wdt) Status = FAILURE\n"));
+    return V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE;
+  } else {
+    return V_ACPI_IO_OC_WDT_CTL_STATUS_OK;
+  }
+}
+
+/**
+  Normally, each reboot performed while watchdog runs is considered a failure.
+  This function allows platform to perform expected reboots with WDT running,
+  without being interpreted as failures.
+  In DXE phase, it is enough to call this function any time before reset.
+  In PEI phase, between calling this function and performing reset, ReloadAndStart()
+  must not be called.
+
+
+**/
+VOID
+EFIAPI
+WdtAllowKnownReset (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) AllowKnownReset\n"));
+
+  mAllowExpectedReset = 1;
+
+  Readback  = IoRead32 (WdtGetAddress ());
+  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS | B_ACPI_IO_OC_WDT_CTL_FORCE_ALL);
+  IoWrite32 (WdtGetAddress (), Readback);
+}
+
+/**
+  Returns information if WDT coverage for the duration of BIOS execution
+  was requested by an OS application
+
+
+  @retval TRUE                    if WDT was requested
+  @retval FALSE                   if WDT was not requested
+**/
+UINT8
+EFIAPI
+IsWdtRequired (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtRequired"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+
+  if ((Readback & B_ACPI_IO_OC_WDT_CTL_AFTER_POST) != 0) {
+    DEBUG ((DEBUG_INFO, " - yes\n"));
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_INFO, " - no\n"));
+    return FALSE;
+  }
+
+}
+
+/**
+  Returns WDT enabled/disabled status.
+
+
+  @retval TRUE                    if WDT is enabled
+  @retval FALSE                   if WDT is disabled
+**/
+UINT8
+EFIAPI
+IsWdtEnabled (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtEnabled"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+
+  if ((Readback & B_ACPI_IO_OC_WDT_CTL_EN) != 0) {
+    DEBUG ((DEBUG_INFO, " - yes\n"));
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_INFO, " - no\n"));
+    return FALSE;
+  }
+
+}
+
+/**
+  Returns WDT locked status.
+
+
+  @retval TRUE                    if WDT is locked
+  @retval FALSE                   if WDT is unlocked
+**/
+UINT8
+EFIAPI
+IsWdtLocked (
+  VOID
+  )
+{
+  UINT32  Readback;
+
+  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtLocked"));
+
+  Readback = IoRead32 (WdtGetAddress ());
+
+
+  if ((Readback & B_ACPI_IO_OC_WDT_CTL_LCK) != 0) {
+    DEBUG ((DEBUG_INFO, " - yes\n"));
+    return TRUE;
+  } else {
+    DEBUG ((DEBUG_INFO, " - no\n"));
+    return FALSE;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
new file mode 100644
index 0000000000..8e026b3ab6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
@@ -0,0 +1,330 @@
+/** @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) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegsPmc.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);
+}
+
+/**
+  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 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 RTC 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_B) & 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 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);
+}
+
+/**
+  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);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
new file mode 100644
index 0000000000..05557931c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
@@ -0,0 +1,41 @@
+/** @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) 2019 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>
+/**
+  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
+GetSataRegBase (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           GetSataPcieDeviceNum (SataCtrlIndex),
+           GetSataPcieFunctionNum (SataCtrlIndex),
+           0
+           );
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c
new file mode 100644
index 0000000000..5cec818dd6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c
@@ -0,0 +1,101 @@
+/** @file
+  Pch SATA library for CedarFork SouthCluster.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PchInfoLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsSata.h>
+#include <Library/SataLib.h>
+
+/**
+  Get Maximum Sata Controller Number
+
+  @param[in] None
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+GetPchMaxSataControllerNum (
+  VOID
+  )
+{
+  return 3;
+}
+
+/**
+  Get Pch Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval Pch Maximum Sata Port Number
+**/
+UINT8
+GetPchMaxSataPortNum (
+  IN UINT8      SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return 8;
+}
+
+/**
+  Get SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+GetSataPcieDeviceNum (
+  IN UINT8  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_1;
+  } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_2;
+  } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_3;
+  } else {
+    ASSERT (FALSE);
+    return 0;
+  }
+}
+
+/**
+  Get SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+GetSataPcieFunctionNum (
+  IN UINT8  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1;
+  } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2;
+  } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3;
+  } else {
+    ASSERT (FALSE);
+    return 0;
+  }
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c
new file mode 100644
index 0000000000..0eca692a74
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c
@@ -0,0 +1,88 @@
+/** @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) 2019 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/PchRegsSata.h>
+#include <Library/SataLib.h>
+
+/**
+  Get Maximum Sata Controller Number
+
+  @param[in] None
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+GetPchMaxSataControllerNum (
+  VOID
+  )
+{
+  return 1;
+}
+
+/**
+  Get Pch Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval Pch Maximum Sata Port Number
+**/
+UINT8
+GetPchMaxSataPortNum (
+  IN UINT32      SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  if (IsPchLp ()) {
+    return 3;
+  } else {
+    return 8;
+  }
+}
+
+/**
+  Get SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+GetSataPcieDeviceNum (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return PCI_DEVICE_NUMBER_PCH_SATA;
+}
+
+/**
+  Get SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+GetSataPcieFunctionNum (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  return PCI_FUNCTION_NUMBER_PCH_SATA;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
new file mode 100644
index 0000000000..22f6fb215f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
@@ -0,0 +1,130 @@
+/** @file
+  The PEI Library Implements OcWdt Support.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/Wdt.h>
+#include <Library/PchWdtCommonLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/IoLib.h>
+#include <Register/PchRegsPmc.h>
+
+static WDT_PPI mWdtPpi = {
+  WdtReloadAndStart,
+  WdtCheckStatus,
+  WdtDisable,
+  WdtAllowKnownReset,
+  IsWdtRequired,
+  IsWdtEnabled
+};
+
+static EFI_PEI_PPI_DESCRIPTOR  mInstallWdtPpi = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gWdtPpiGuid,
+  &mWdtPpi
+};
+
+/**
+  Reads PCH registers to check if platform wakes from S3/S4
+
+  @retval TRUE                    if platfrom wakes from S3/S4
+  @retval FALSE                   otherwise
+**/
+BOOLEAN
+IsWakeFromS3S4 (
+  VOID
+  )
+{
+  PMC_SLEEP_STATE  SleepType;
+
+  SleepType = PmcGetSleepTypeAfterWake ();
+  if ((SleepType == PmcS3SleepState) || (SleepType == PmcS4SleepState)) {
+    return TRUE;
+  }
+
+  return FALSE;
+
+}
+
+/**
+  Check for unexpected reset.
+  If there was an unexpected reset, enforces WDT expiration.
+**/
+VOID
+OcWdtResetCheck (
+  VOID
+  )
+{
+  UINT32      Readback;
+
+  Readback = IoRead32 (WdtGetAddress ());
+  DEBUG ((DEBUG_INFO, "(WDT) OcWdtResetCheck()\n"));
+
+  ///
+  /// If there was a WDT expiration, set Failure Status and clear timeout status bits
+  /// Timeout status bits are cleared by writing '1'
+  ///
+  if (Readback & (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS)) {
+    DEBUG ((DEBUG_ERROR, "(WDT) Expiration detected.\n", Readback));
+    Readback |= B_ACPI_IO_OC_WDT_CTL_FAILURE_STS;
+    Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
+    Readback &= ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+  } else {
+    ///
+    /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
+    /// clear unexpected reset status and enforce expiration. This is to inform Firmware
+    /// which has no access to unexpected reset status bit, that something went wrong.
+    ///
+    if ((Readback & B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS) && !IsWakeFromS3S4()) {
+      if (PcdGetBool (PcdOcEnableWdtforDebug)) {
+        DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected and ignored.\n"));
+        Readback &= ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS | B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
+        Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
+      } else {
+        DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected. Enforcing Wdt expiration.\n"));
+        WdtReloadAndStart (1);
+        ///
+        /// wait for reboot caused by WDT expiration
+        ///
+        CpuDeadLoop ();
+      }
+    } else {
+      ///
+      /// No WDT expiration and no unexpected reset - clear Failure status
+      ///
+      DEBUG ((DEBUG_INFO, "(WDT) Status OK.\n", Readback));
+      Readback &= ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS);
+      Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
+    }
+  }
+
+  IoWrite32 (WdtGetAddress (), Readback);
+
+  return;
+}
+
+/**
+  This function install WDT PPI
+
+  @retval EFI_STATUS  Results of the installation of the WDT PPI
+**/
+EFI_STATUS
+EFIAPI
+OcWdtInit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = PeiServicesInstallPpi (&mInstallWdtPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c
new file mode 100644
index 0000000000..182218ffcf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c
@@ -0,0 +1,23 @@
+/** @file
+  The Null PEI Library Implements OcWdt Support.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+
+/**
+  This function install WDT PPI
+
+  @retval EFI_STATUS  Results of the installation of the WDT PPI
+**/
+EFI_STATUS
+EFIAPI
+OcWdtInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c
new file mode 100644
index 0000000000..bd1e2711da
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c
@@ -0,0 +1,307 @@
+/** @file
+  Print whole PCH_PREMEM_POLICY_PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+
+/**
+  Print PCH_GENERAL_PREMEM_CONFIG and serial out.
+
+  @param[in] PchGeneralPreMemConfig     Pointer to a PCH_GENERAL_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintGeneralPreMemConfig (
+  IN CONST PCH_GENERAL_PREMEM_CONFIG    *PchGeneralPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH General PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Port80Route= %x\n", PchGeneralPreMemConfig->Port80Route));
+}
+
+/**
+  Print PCH_DCI_PREMEM_CONFIG and serial out.
+
+  @param[in] DciPreMemConfig            Pointer to a PCH_DCI_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintDciPreMemConfig (
+  IN CONST PCH_DCI_PREMEM_CONFIG        *DciPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH DCI PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "PlatformDebugConsent = %x\n", DciPreMemConfig->PlatformDebugConsent));
+  DEBUG ((DEBUG_INFO, "DciUsb3TypecUfpDbg = %x\n", DciPreMemConfig->DciUsb3TypecUfpDbg));
+}
+
+/**
+  Print PCH_WDT_PREMEM_CONFIG and serial out.
+
+  @param[in] WdtPreMemConfig            Pointer to a PCH_WDT_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintWdtPreMemConfig (
+  IN CONST PCH_WDT_PREMEM_CONFIG               *WdtPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH WDT PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "DisableAndLock= %x\n", WdtPreMemConfig->DisableAndLock));
+}
+
+/**
+  Print PCH_TRACE_HUB_CONFIG and serial out.
+
+  @param[in] TraceHubConfig             Pointer to a PCH_TRACE_HUB_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintTraceHubPreMemConfig (
+  IN CONST PCH_TRACE_HUB_PREMEM_CONFIG         *PchTraceHubPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH TraceHub PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "EnableMode= %x\n", PchTraceHubPreMemConfig->EnableMode));
+  DEBUG ((DEBUG_INFO, "MemReg0Size= %x\n", PchTraceHubPreMemConfig->MemReg0Size));
+  DEBUG ((DEBUG_INFO, "MemReg1Size= %x\n", PchTraceHubPreMemConfig->MemReg1Size));
+}
+
+/**
+  Print PCH_SMBUS_CONFIG and serial out.
+
+  @param[in] SmbusConfig         Pointer to a PCH_SMBUS_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSmbusPreMemConfig (
+  IN CONST PCH_SMBUS_PREMEM_CONFIG    *SmbusPreMemConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH SMBUS PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", SmbusPreMemConfig->Enable));
+  DEBUG ((DEBUG_INFO, " ArpEnable= %x\n", SmbusPreMemConfig->ArpEnable));
+  DEBUG ((DEBUG_INFO, " DynamicPowerGating= %x\n", SmbusPreMemConfig->DynamicPowerGating));
+  DEBUG ((DEBUG_INFO, " SpdWriteDisable= %x\n", SmbusPreMemConfig->SpdWriteDisable));
+  DEBUG ((DEBUG_INFO, " SmbAlertEnable= %x\n", SmbusPreMemConfig->SmbAlertEnable));
+  DEBUG ((DEBUG_INFO, " SmbusIoBase= %x\n", SmbusPreMemConfig->SmbusIoBase));
+  DEBUG ((DEBUG_INFO, " NumRsvdSmbusAddresses= %x\n", SmbusPreMemConfig->NumRsvdSmbusAddresses));
+  DEBUG ((DEBUG_INFO, " RsvdSmbusAddressTable= {"));
+  for (Index = 0; Index < SmbusPreMemConfig->NumRsvdSmbusAddresses; ++Index) {
+    DEBUG ((DEBUG_INFO, " %02xh", SmbusPreMemConfig->RsvdSmbusAddressTable[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " }\n"));
+}
+
+/**
+  Print PCH_LPC_PREMEM_CONFIG and serial out.
+
+  @param[in] LpcPreMemConfig                  Pointer to a PCH_LPC_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintLpcPreMemConfig (
+  IN CONST PCH_LPC_PREMEM_CONFIG              *LpcPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH LPC PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "EnhancePort8xhDecoding= %x\n", LpcPreMemConfig->EnhancePort8xhDecoding));
+}
+
+/**
+  Print PCH_HSIO_PCIE_PREMEM_CONFIG and serial out.
+
+  @param[in] HsioPciePreMemConfig     Pointer to a PCH_HSIO_PCIE_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintHsioPciePreMemConfig (
+  IN CONST PCH_HSIO_PCIE_PREMEM_CONFIG *HsioPciePreMemConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ HSIO PCIE PreMem Config ------------------\n"));
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtleEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtle= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DownscaleAmpEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DownscaleAmp= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DownscaleAmpEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DownscaleAmp= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen3DownscaleAmpEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen3DownscaleAmp= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmphEnable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmph= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5Enable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0Enable= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0= %x\n", Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0));
+  }
+}
+
+/**
+  Print PCH_HSIO_SATA_PREMEM_CONFIG and serial out.
+
+  @param[in] SataCtrlIndex            SATA controller index
+  @param[in] HsioSataPreMemConfig     Pointer to a PCH_HSIO_SATA_PREMEM_CONFIG that provides the platform setting
+**/
+VOID
+PchPrintHsioSataPreMemConfig (
+  IN UINT8                             SataCtrlIndex,
+  IN CONST PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "---------------- HSIO SATA PreMem Config for controller %d ----------------\n", SataCtrlIndex));
+  for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen1EqBoostMagEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen1EqBoostMag= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen2EqBoostMagEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen2EqBoostMag= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen3EqBoostMagEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen3EqBoostMag= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DownscaleAmpEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DownscaleAmp= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DownscaleAmpEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DownscaleAmp= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DownscaleAmpEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DownscaleAmp= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmphEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmph= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmphEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmph= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmphEnable= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmph= %x\n", Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph));
+  }
+}
+
+/**
+  Print PCH_PCIE_RP_PREMEM_CONFIG and serial out.
+
+  @param[in] PcieRpPreMemConfig        Pointer to a PCH_PCIE_RP_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintPcieRpPreMemConfig (
+  IN CONST PCH_PCIE_RP_PREMEM_CONFIG    *PcieRpPreMemConfig
+  )
+{
+  UINT32 Index;
+  DEBUG ((DEBUG_INFO, "------------------ PCH PCIe RP PreMem Config ------------------\n"));
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " Port[%d] RpEnabled= %x\n", Index, (PcieRpPreMemConfig->RpEnabledMask & (UINT32) (1 << Index)) != 0 ));
+  }
+  DEBUG ((DEBUG_INFO, " PcieImrEnabled= %x\n", PcieRpPreMemConfig->PcieImrEnabled));
+  DEBUG ((DEBUG_INFO, " PcieImrSize= %d MB\n", PcieRpPreMemConfig->PcieImrSize));
+  DEBUG ((DEBUG_INFO, " ImrRpSelection= %d\n", PcieRpPreMemConfig->ImrRpSelection));
+}
+
+/**
+  Print PCH_HDAUDIO_PREMEM_CONFIG and serial out.
+
+  @param[in] LpcPreMemConfig                  Pointer to a PCH_HDAUDIO_PREMEM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintHdAudioPreMemConfig (
+  IN CONST PCH_HDAUDIO_PREMEM_CONFIG *HdaPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ HD Audio PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", HdaPreMemConfig->Enable));
+}
+
+/**
+  Print PCH_ISH_PREMEM_CONFIG  and serial out.
+
+  @param[in] IshPreMemConfig                  Pointer to a PCH_ISH_PREMEM_CONFIG  that provides the platform setting
+
+**/
+VOID
+PchPrintIshPreMemConfig (
+  IN CONST PCH_ISH_PREMEM_CONFIG *IshPreMemConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ ISH PreMem Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", IshPreMemConfig->Enable));
+}
+
+
+/**
+  Print whole PCH_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi    The RC PREMEM Policy PPI instance
+
+**/
+VOID
+EFIAPI
+PchPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI     *SiPreMemPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                      Status;
+  PCH_GENERAL_PREMEM_CONFIG       *PchGeneralPreMemConfig;
+  PCH_DCI_PREMEM_CONFIG           *DciPreMemConfig;
+  PCH_WDT_PREMEM_CONFIG           *WdtPreMemConfig;
+  PCH_TRACE_HUB_PREMEM_CONFIG     *PchTraceHubPreMemConfig;
+  PCH_SMBUS_PREMEM_CONFIG         *SmbusPreMemConfig;
+  PCH_LPC_PREMEM_CONFIG           *LpcPreMemConfig;
+  PCH_HSIO_PCIE_PREMEM_CONFIG     *HsioPciePreMemConfig;
+  PCH_HSIO_SATA_PREMEM_CONFIG     *HsioSataPreMemConfig;
+  PCH_PCIE_RP_PREMEM_CONFIG       *PcieRpPreMemConfig;
+  PCH_HDAUDIO_PREMEM_CONFIG       *HdaPreMemConfig;
+  PCH_ISH_PREMEM_CONFIG           *IshPreMemConfig;
+  UINT8                           SataCtrlIndex;
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPreMemPolicyPpi->TableHeader.Header.Revision));
+
+  PchPrintGeneralPreMemConfig (PchGeneralPreMemConfig);
+  PchPrintDciPreMemConfig (DciPreMemConfig);
+  PchPrintWdtPreMemConfig (WdtPreMemConfig);
+  PchPrintTraceHubPreMemConfig (PchTraceHubPreMemConfig);
+  PchPrintSmbusPreMemConfig (SmbusPreMemConfig);
+  PchPrintLpcPreMemConfig (LpcPreMemConfig);
+  PchPrintHsioPciePreMemConfig (HsioPciePreMemConfig);
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++) {
+    HsioSataPreMemConfig = GetPchHsioSataPreMemConfig (SiPreMemPolicyPpi, SataCtrlIndex);
+    PchPrintHsioSataPreMemConfig (SataCtrlIndex, HsioSataPreMemConfig);
+  }
+  PchPrintPcieRpPreMemConfig (PcieRpPreMemConfig);
+  PchPrintHdAudioPreMemConfig (HdaPreMemConfig);
+  PchPrintIshPreMemConfig (IshPreMemConfig);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy End --------------------------\n"));
+  DEBUG_CODE_END ();
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c
new file mode 100644
index 0000000000..d9005b50ef
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c
@@ -0,0 +1,778 @@
+/** @file
+  Print whole PCH_POLICY_PPI
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Private/PchHsio.h>
+
+/**
+  Print USB_CONFIG and serial out.
+
+  @param[in] UsbConfig         Pointer to a USB_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintUsbConfig (
+  IN CONST USB_CONFIG     *UsbConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH USB Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " EnableComplianceMode           = %x\n", UsbConfig->EnableComplianceMode));
+  DEBUG ((DEBUG_INFO, " PdoProgramming                 = %x\n", UsbConfig->PdoProgramming));
+  DEBUG ((DEBUG_INFO, " OverCurrentEnable              = %x\n", UsbConfig->OverCurrentEnable));
+  DEBUG ((DEBUG_INFO, " XhciOcLock                     = %x\n", UsbConfig->XhciOcLock));
+  DEBUG ((DEBUG_INFO, " Usb2PhySusPgEnable             = %x\n", UsbConfig->Usb2PhySusPgEnable));
+
+  for (Index = 0; Index < GetPchUsb2MaxPhysicalPortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Enabled        = %x\n", Index, UsbConfig->PortUsb20[Index].Enable));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].OverCurrentPin = OC%x\n", Index, UsbConfig->PortUsb20[Index].OverCurrentPin));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Petxiset   = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Petxiset));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Txiset     = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Txiset));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Predeemp   = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Predeemp));
+    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Pehalfbit  = %x\n", Index, UsbConfig->PortUsb20[Index].Afe.Pehalfbit));
+  }
+
+  for (Index = 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d] Enabled                  = %x\n", Index, UsbConfig->PortUsb30[Index].Enable));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].OverCurrentPin           = OC%x\n", Index, UsbConfig->PortUsb30[Index].OverCurrentPin));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmphEnable       = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmph             = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDeEmph));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmpEnable = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmp       = %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp));
+
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfgEnable    = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfg          = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelNEnable            = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelN                  = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelPEnable            = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelP                  = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnResEnable  = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable));
+    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnRes        = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes));
+  }
+
+  DEBUG ((DEBUG_INFO, " XdciConfig.Enable= %x\n", UsbConfig->XdciConfig.Enable));
+
+}
+
+/**
+  Print PCH_PCIE_CONFIG and serial out.
+
+  @param[in] PcieConfig         Pointer to a PCH_PCIE_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintPcieConfig (
+  IN CONST PCH_PCIE_CONFIG      *PcieConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH PCIE Config ------------------\n"));
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " RootPort[%d] HotPlug= %x\n", Index, PcieConfig->RootPort[Index].HotPlug));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PmSci= %x\n", Index, PcieConfig->RootPort[Index].PmSci));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] ExtSync= %x\n", Index, PcieConfig->RootPort[Index].ExtSync));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] ClkReqDetect= %x\n", Index, PcieConfig->RootPort[Index].ClkReqDetect));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] UnsupportedRequestReport= %x\n", Index, PcieConfig->RootPort[Index].UnsupportedRequestReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] FatalErrorReport= %x\n", Index, PcieConfig->RootPort[Index].FatalErrorReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NoFatalErrorReport= %x\n", Index, PcieConfig->RootPort[Index].NoFatalErrorReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] CorrectableErrorReport= %x\n", Index, PcieConfig->RootPort[Index].CorrectableErrorReport));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnFatalError= %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnFatalError));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnNonFatalError= %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnNonFatalError));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnCorrectableError= %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnCorrectableError));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] MaxPayload= %x\n", Index, PcieConfig->RootPort[Index].MaxPayload));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotImplemented= %x\n", Index, PcieConfig->RootPort[Index].SlotImplemented));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] AcsEnabled= %x\n", Index, PcieConfig->RootPort[Index].AcsEnabled));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PtmEnabled= %x\n", Index, PcieConfig->RootPort[Index].PtmEnabled));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] AdvancedErrorReporting= %x\n", Index, PcieConfig->RootPort[Index].AdvancedErrorReporting));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] TransmitterHalfSwing= %x\n", Index, PcieConfig->RootPort[Index].TransmitterHalfSwing));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PcieSpeed= %x\n", Index, PcieConfig->RootPort[Index].PcieSpeed));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Gen3EqPh3Method= %x\n", Index, PcieConfig->RootPort[Index].Gen3EqPh3Method));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] PhysicalSlotNumber= %x\n", Index, PcieConfig->RootPort[Index].PhysicalSlotNumber));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] CompletionTimeout= %x\n", Index, PcieConfig->RootPort[Index].CompletionTimeout));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Aspm= %x\n", Index, PcieConfig->RootPort[Index].Aspm));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] L1Substates= %x\n", Index, PcieConfig->RootPort[Index].L1Substates));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrEnable= %x\n", Index, PcieConfig->RootPort[Index].LtrEnable));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrConfigLock= %x\n", Index, PcieConfig->RootPort[Index].LtrConfigLock));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxSnoopLatency= %x\n", Index, PcieConfig->RootPort[Index].LtrMaxSnoopLatency));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxNoSnoopLatency= %x\n", Index, PcieConfig->RootPort[Index].LtrMaxNoSnoopLatency));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMode= %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMode));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMultiplier= %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMultiplier));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideValue= %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideValue));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideMode= %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMode));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideMultiplier= %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideValue= %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideValue));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] ForceLtrOverride= %x\n", Index, PcieConfig->RootPort[Index].ForceLtrOverride));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] DetectTimeoutMs= %x\n", Index, PcieConfig->RootPort[Index].DetectTimeoutMs));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitScale= %x\n", Index, PcieConfig->RootPort[Index].SlotPowerLimitScale));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitValue= %x\n", Index, PcieConfig->RootPort[Index].SlotPowerLimitValue));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Uptp= %x\n", Index, PcieConfig->RootPort[Index].Uptp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] Dptp= %x\n", Index, PcieConfig->RootPort[Index].Dptp));
+    DEBUG ((DEBUG_INFO, " RootPort[%d] EnableCpm= %x\n", Index, PcieConfig->RootPort[Index].EnableCpm));
+
+  }
+  for (Index = 0; Index < GetPchMaxPcieClockNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " Clock[%d] Usage= %x\n", Index, PcieConfig->PcieClock[Index].Usage));
+    DEBUG ((DEBUG_INFO, " Clock[%d] ClkReq= %x\n", Index, PcieConfig->PcieClock[Index].ClkReq));
+  }
+  for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index++) {
+    DEBUG ((DEBUG_INFO, " SwEqCoeffCm[%d] = %x\n", Index, PcieConfig->SwEqCoeffList[Index].Cm));
+    DEBUG ((DEBUG_INFO, " SwEqCoeffCp[%d] = %x\n", Index, PcieConfig->SwEqCoeffList[Index].Cp));
+  }
+  DEBUG ((DEBUG_INFO, " EnablePort8xhDecode= %x\n", PcieConfig->EnablePort8xhDecode));
+  DEBUG ((DEBUG_INFO, " PchPciePort8xhDecodePortIndex= %x\n", PcieConfig->PchPciePort8xhDecodePortIndex));
+  DEBUG ((DEBUG_INFO, " DisableRootPortClockGating= %x\n", PcieConfig->DisableRootPortClockGating));
+  DEBUG ((DEBUG_INFO, " EnablePeerMemoryWrite= %x\n", PcieConfig->EnablePeerMemoryWrite));
+  DEBUG ((DEBUG_INFO, " ComplianceTestMode= %x\n", PcieConfig->ComplianceTestMode));
+  DEBUG ((DEBUG_INFO, " RpFunctionSwap= %x\n", PcieConfig->RpFunctionSwap));
+  DEBUG ((DEBUG_INFO, " PcieDeviceOverrideTablePtr= %x\n", PcieConfig->PcieDeviceOverrideTablePtr));
+}
+
+/**
+  Print PCH_SATA_CONFIG and serial out.
+
+  @param[in]  SataCtrlIndex     SATA controller index
+  @param[in]  SataConfig        Pointer to a PCH_SATA_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSataConfig (
+  IN UINT32                     SataCtrlIndex,
+  IN CONST PCH_SATA_CONFIG      *SataConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "--------------- PCH SATA Config for controller %d -----------\n", SataCtrlIndex));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", SataConfig->Enable));
+  DEBUG ((DEBUG_INFO, " SataMode= %x\n", SataConfig->SataMode));
+
+  for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] Enabled= %x\n", Index, SataConfig->PortSettings[Index].Enable));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] HotPlug= %x\n", Index, SataConfig->PortSettings[Index].HotPlug));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] InterlockSw= %x\n", Index, SataConfig->PortSettings[Index].InterlockSw));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] External= %x\n", Index, SataConfig->PortSettings[Index].External));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] SpinUp= %x\n", Index, SataConfig->PortSettings[Index].SpinUp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] SolidStateDrive= %x\n", Index, SataConfig->PortSettings[Index].SolidStateDrive));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] DevSlp= %x\n", Index, SataConfig->PortSettings[Index].DevSlp));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] EnableDitoConfig= %x\n", Index, SataConfig->PortSettings[Index].EnableDitoConfig));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] DmVal= %x\n", Index, SataConfig->PortSettings[Index].DmVal));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] DitoVal= %x\n", Index, SataConfig->PortSettings[Index].DitoVal));
+    DEBUG ((DEBUG_INFO, " PortSettings[%d] ZpOdd= %x\n", Index, SataConfig->PortSettings[Index].ZpOdd));
+  }
+
+  DEBUG ((DEBUG_INFO, " RaidDeviceId= %x\n", SataConfig->Rst.RaidDeviceId));
+  DEBUG ((DEBUG_INFO, " Sata interrupt mode =  %x\n", SataConfig->Rst.SataRstInterrupt));
+  DEBUG ((DEBUG_INFO, " Raid0= %x\n", SataConfig->Rst.Raid0));
+  DEBUG ((DEBUG_INFO, " Raid1= %x\n", SataConfig->Rst.Raid1));
+  DEBUG ((DEBUG_INFO, " Raid10= %x\n", SataConfig->Rst.Raid10));
+  DEBUG ((DEBUG_INFO, " Raid5= %x\n", SataConfig->Rst.Raid5));
+  DEBUG ((DEBUG_INFO, " Irrt= %x\n", SataConfig->Rst.Irrt));
+  DEBUG ((DEBUG_INFO, " OromUiBanner= %x\n", SataConfig->Rst.OromUiBanner));
+  DEBUG ((DEBUG_INFO, " OromUiDelay= %x\n", SataConfig->Rst.OromUiDelay));
+  DEBUG ((DEBUG_INFO, " HddUnlock= %x\n", SataConfig->Rst.HddUnlock));
+  DEBUG ((DEBUG_INFO, " LedLocate= %x\n", SataConfig->Rst.LedLocate));
+  DEBUG ((DEBUG_INFO, " IrrtOnly= %x\n", SataConfig->Rst.IrrtOnly));
+  DEBUG ((DEBUG_INFO, " SmartStorage= %x\n", SataConfig->Rst.SmartStorage));
+  DEBUG ((DEBUG_INFO, " LegacyOrom= %x\n", SataConfig->Rst.LegacyOrom));
+  DEBUG ((DEBUG_INFO, " OptaneMemory= %x\n", SataConfig->Rst.OptaneMemory));
+  DEBUG ((DEBUG_INFO, " CpuAttachedStorage= %x\n", SataConfig->Rst.CpuAttachedStorage));
+
+  DEBUG ((DEBUG_INFO, " SpeedSupport= %x\n", SataConfig->SpeedLimit));
+  DEBUG ((DEBUG_INFO, " EsataSpeedLimit= %x\n", SataConfig->EsataSpeedLimit));
+  DEBUG ((DEBUG_INFO, " LedEnable= %x\n", SataConfig->LedEnable));
+  DEBUG ((DEBUG_INFO, " TestMode= %x\n", SataConfig->TestMode));
+  DEBUG ((DEBUG_INFO, " SalpSupport= %x\n", SataConfig->SalpSupport));
+  DEBUG ((DEBUG_INFO, " PwrOptEnable= %x\n", SataConfig->PwrOptEnable));
+
+  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].Enable                  = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].Enable));
+    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].RstPcieStoragePort      = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort));
+    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].DeviceResetDelay        = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay));
+  }
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T1M %x\n", SataConfig->ThermalThrottling.P0T1M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T2M %x\n", SataConfig->ThermalThrottling.P0T2M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T3M %x\n", SataConfig->ThermalThrottling.P0T3M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDisp %x\n", SataConfig->ThermalThrottling.P0TDisp));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0Tinact %x\n", SataConfig->ThermalThrottling.P0Tinact));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDispFinit %x\n", SataConfig->ThermalThrottling.P0TDispFinit));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T1M %x\n", SataConfig->ThermalThrottling.P1T1M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T2M %x\n", SataConfig->ThermalThrottling.P1T2M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T3M %x\n", SataConfig->ThermalThrottling.P1T3M));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDisp %x\n", SataConfig->ThermalThrottling.P1TDisp));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1Tinact %x\n", SataConfig->ThermalThrottling.P1Tinact));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDispFinit %x\n", SataConfig->ThermalThrottling.P1TDispFinit));
+  DEBUG ((DEBUG_INFO, " ThermalThrottling SuggestedSetting %x\n", SataConfig->ThermalThrottling.SuggestedSetting));
+}
+
+/**
+  Print PCH_IOAPIC_CONFIG and serial out.
+
+  @param[in] IoApicConfig         Pointer to a PCH_IOAPIC_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintIoApicConfig (
+  IN CONST PCH_IOAPIC_CONFIG   *IoApicConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH IOAPIC Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " IoApicEntry24_119= %x\n", IoApicConfig->IoApicEntry24_119));
+  DEBUG ((DEBUG_INFO, " Enable8254ClockGating= %x\n", IoApicConfig->Enable8254ClockGating));
+  DEBUG ((DEBUG_INFO, " Enable8254ClockGatingOnS3= %x\n", IoApicConfig->Enable8254ClockGatingOnS3));
+  DEBUG ((DEBUG_INFO, " IoApicId= %x\n", IoApicConfig->IoApicId));
+}
+
+/**
+  Print PCH_LOCK_DOWN_CONFIG and serial out.
+
+  @param[in] LockDownConfig         Pointer to a PCH_LOCK_DOWN_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintLockDownConfig (
+  IN CONST PCH_LOCK_DOWN_CONFIG   *LockDownConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH Lock Down Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " GlobalSmi= %x\n", LockDownConfig->GlobalSmi));
+  DEBUG ((DEBUG_INFO, " BiosInterface= %x\n", LockDownConfig->BiosInterface));
+  DEBUG ((DEBUG_INFO, " RtcMemoryLock= %x\n", LockDownConfig->RtcMemoryLock));
+  DEBUG ((DEBUG_INFO, " BiosLock= %x\n", LockDownConfig->BiosLock));
+  DEBUG ((DEBUG_INFO, " UnlockGpioPads= %x\n", LockDownConfig->UnlockGpioPads));
+}
+
+/**
+  Print PCH_HDAUDIO_CONFIG and serial out.
+
+  @param[in] HdaConfig         Pointer to a PCH_HDAUDIO_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintHdAudioConfig (
+  IN CONST PCH_HDAUDIO_CONFIG   *HdaConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " DSP Enable               = %x\n", HdaConfig->DspEnable));
+  DEBUG ((DEBUG_INFO, " DSP UAA Compliance       = %x\n", HdaConfig->DspUaaCompliance));
+  DEBUG ((DEBUG_INFO, " iDisp Codec Disconnect   = %x\n", HdaConfig->IDispCodecDisconnect));
+  DEBUG ((DEBUG_INFO, " Pme                      = %x\n", HdaConfig->Pme));
+  DEBUG ((DEBUG_INFO, " Codec Sx Wake Capability = %x\n", HdaConfig->CodecSxWakeCapability));
+  DEBUG ((DEBUG_INFO, " VC Type                  = %x\n", HdaConfig->VcType));
+  DEBUG ((DEBUG_INFO, " HD-A Link Frequency      = %x\n", HdaConfig->HdAudioLinkFrequency));
+  DEBUG ((DEBUG_INFO, " iDisp Link Frequency     = %x\n", HdaConfig->IDispLinkFrequency));
+  DEBUG ((DEBUG_INFO, " iDisp Link T-Mode        = %x\n", HdaConfig->IDispLinkTmode));
+  DEBUG ((DEBUG_INFO, " Audio Link: HDA Link     = %x\n", HdaConfig->AudioLinkHda));
+  DEBUG ((DEBUG_INFO, " Audio Link: DMIC#0       = %x\n", HdaConfig->AudioLinkDmic0));
+  DEBUG ((DEBUG_INFO, " Audio Link: DMIC#1       = %x\n", HdaConfig->AudioLinkDmic1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SSP#0        = %x\n", HdaConfig->AudioLinkSsp0));
+  DEBUG ((DEBUG_INFO, " Audio Link: SSP#1        = %x\n", HdaConfig->AudioLinkSsp1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SSP#2        = %x\n", HdaConfig->AudioLinkSsp1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#1  = %x\n", HdaConfig->AudioLinkSndw1));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#2  = %x\n", HdaConfig->AudioLinkSndw2));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#3  = %x\n", HdaConfig->AudioLinkSndw3));
+  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#4  = %x\n", HdaConfig->AudioLinkSndw4));
+  DEBUG ((DEBUG_INFO, " SoundWire Buffer RCOMP   = %x\n", HdaConfig->SndwBufferRcomp));
+  DEBUG ((DEBUG_INFO, " ResetWaitTimer           = %x\n", HdaConfig->ResetWaitTimer));
+  DEBUG ((DEBUG_INFO, " VerbTableEntryNum        = %x\n", HdaConfig->VerbTableEntryNum));
+  DEBUG ((DEBUG_INFO, " VerbTablePtr             = %x\n", HdaConfig->VerbTablePtr));
+}
+
+/**
+  Print PCH_PM_CONFIG and serial out.
+
+  @param[in] PmConfig         Pointer to a PCH_PM_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintPmConfig (
+  IN CONST PCH_PM_CONFIG   *PmConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH PM Config ------------------\n"));
+
+  DEBUG ((DEBUG_INFO, " WakeConfig PmeB0S5Dis               = %x\n", PmConfig->WakeConfig.PmeB0S5Dis));
+  DEBUG ((DEBUG_INFO, " WakeConfig WolEnableOverride        = %x\n", PmConfig->WakeConfig.WolEnableOverride));
+  DEBUG ((DEBUG_INFO, " WakeConfig LanWakeFromDeepSx        = %x\n", PmConfig->WakeConfig.LanWakeFromDeepSx));
+  DEBUG ((DEBUG_INFO, " WakeConfig PcieWakeFromDeepSx       = %x\n", PmConfig->WakeConfig.PcieWakeFromDeepSx));
+  DEBUG ((DEBUG_INFO, " WakeConfig WoWlanEnable             = %x\n", PmConfig->WakeConfig.WoWlanEnable));
+  DEBUG ((DEBUG_INFO, " WakeConfig WoWlanDeepSxEnable       = %x\n", PmConfig->WakeConfig.WoWlanDeepSxEnable));
+
+  DEBUG ((DEBUG_INFO, " PchDeepSxPol                        = %x\n", PmConfig->PchDeepSxPol));
+  DEBUG ((DEBUG_INFO, " PchSlpS3MinAssert                   = %x\n", PmConfig->PchSlpS3MinAssert));
+  DEBUG ((DEBUG_INFO, " PchSlpS4MinAssert                   = %x\n", PmConfig->PchSlpS4MinAssert));
+  DEBUG ((DEBUG_INFO, " PchSlpSusMinAssert                  = %x\n", PmConfig->PchSlpSusMinAssert));
+  DEBUG ((DEBUG_INFO, " PchSlpAMinAssert                    = %x\n", PmConfig->PchSlpAMinAssert));
+  DEBUG ((DEBUG_INFO, " LpcClockRun                         = %x\n", PmConfig->LpcClockRun));
+  DEBUG ((DEBUG_INFO, " SlpStrchSusUp                       = %x\n", PmConfig->SlpStrchSusUp));
+  DEBUG ((DEBUG_INFO, " SlpLanLowDc                         = %x\n", PmConfig->SlpLanLowDc));
+  DEBUG ((DEBUG_INFO, " PwrBtnOverridePeriod                = %x\n", PmConfig->PwrBtnOverridePeriod));
+  DEBUG ((DEBUG_INFO, " DisableEnergyReport                 = %x\n", PmConfig->DisableEnergyReport));
+  DEBUG ((DEBUG_INFO, " DisableDsxAcPresentPulldown         = %x\n", PmConfig->DisableDsxAcPresentPulldown));
+  DEBUG ((DEBUG_INFO, " PchPwrCycDur                        = %x\n", PmConfig->PchPwrCycDur));
+  DEBUG ((DEBUG_INFO, " PciePllSsc                          = %x\n", PmConfig->PciePllSsc));
+  DEBUG ((DEBUG_INFO, " DisableNativePowerButton            = %x\n", PmConfig->DisableNativePowerButton));
+  DEBUG ((DEBUG_INFO, " SlpS0Enabled                        = %x\n", PmConfig->SlpS0Enable));
+  DEBUG ((DEBUG_INFO, " MeWakeSts                           = %x\n", PmConfig->MeWakeSts));
+  DEBUG ((DEBUG_INFO, " WolOvrWkSts                         = %x\n", PmConfig->WolOvrWkSts));
+  DEBUG ((DEBUG_INFO, " EnableTcoTimer                      = %x\n", PmConfig->EnableTcoTimer));
+  DEBUG ((DEBUG_INFO, " VrAlert                             = %x\n", PmConfig->VrAlert));
+  DEBUG ((DEBUG_INFO, " PowerButtonDebounce                 = %x\n", PmConfig->PowerButtonDebounce));
+  DEBUG ((DEBUG_INFO, " SlpS0VmRuntimeControl               = %x\n", PmConfig->SlpS0VmRuntimeControl));
+  DEBUG ((DEBUG_INFO, " SlpS0Vm070VSupport                  = %x\n", PmConfig->SlpS0Vm070VSupport));
+  DEBUG ((DEBUG_INFO, " SlpS0Vm075VSupport                  = %x\n", PmConfig->SlpS0Vm075VSupport));
+  DEBUG ((DEBUG_INFO, " SlpS0Override                       = %x\n", PmConfig->SlpS0Override));
+  DEBUG ((DEBUG_INFO, " SlpS0DisQForDebug                   = %x\n", PmConfig->SlpS0DisQForDebug));
+  DEBUG ((DEBUG_INFO, " PsOnEnable                          = %x\n", PmConfig->PsOnEnable));
+  DEBUG ((DEBUG_INFO, " CpuC10GatePinEnable                 = %x\n", PmConfig->CpuC10GatePinEnable));
+  DEBUG ((DEBUG_INFO, " PmcDbgMsgEn                         = %x\n", PmConfig->PmcDbgMsgEn));
+  DEBUG ((DEBUG_INFO, " ModPhySusPgEnable                   = %x\n", PmConfig->ModPhySusPgEnable));
+  DEBUG ((DEBUG_INFO, " SlpS0WithGbeSupport                 = %x\n", PmConfig->SlpS0WithGbeSupport));
+}
+
+/**
+  Print PCH_DMI_CONFIG and serial out.
+
+  @param[in] DmiConfig         Pointer to a PCH_DMI_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintDmiConfig (
+  IN CONST PCH_DMI_CONFIG   *DmiConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH DMI Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " PwrOptEnable= %x\n", DmiConfig->PwrOptEnable));
+  DEBUG ((DEBUG_INFO, " DmiAspmCtrl= %x\n", DmiConfig->DmiAspmCtrl));
+}
+/**
+  Print PCH_LPC_SIRQ_CONFIG and serial out.
+
+  @param[in] SerialIrqConfig         Pointer to a PCH_LPC_SIRQ_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSerialIrqConfig (
+  IN CONST PCH_LPC_SIRQ_CONFIG   *SerialIrqConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH LPC SIRQ Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " SirqEnable= %x\n", SerialIrqConfig->SirqEnable));
+  DEBUG ((DEBUG_INFO, " SirqMode= %x\n", SerialIrqConfig->SirqMode));
+  DEBUG ((DEBUG_INFO, " StartFramePulse= %x\n", SerialIrqConfig->StartFramePulse));
+}
+/**
+  Print PCH_THERMAL_CONFIG and serial out.
+
+  @param[in] ThermalConfig         Pointer to a PCH_THERMAL_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintThermalConfig (
+  IN CONST PCH_THERMAL_CONFIG   *ThermalConfig
+  )
+{
+  UINTN Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH Thermal Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " TsmicLock= %x\n", ThermalConfig->TsmicLock));
+  DEBUG ((DEBUG_INFO, " TTLevels T0Level %x centigrade degree\n", ThermalConfig->TTLevels.T0Level));
+  DEBUG ((DEBUG_INFO, " TTLevels T1Level %x centigrade degree\n", ThermalConfig->TTLevels.T1Level));
+  DEBUG ((DEBUG_INFO, " TTLevels T2Level %x centigrade degree\n", ThermalConfig->TTLevels.T2Level));
+  DEBUG ((DEBUG_INFO, " TTLevels TTEnable %x\n", ThermalConfig->TTLevels.TTEnable));
+  DEBUG ((DEBUG_INFO, " TTLevels TTState13Enable %x\n", ThermalConfig->TTLevels.TTState13Enable));
+  DEBUG ((DEBUG_INFO, " TTLevels TTLock %x\n", ThermalConfig->TTLevels.TTLock));
+  DEBUG ((DEBUG_INFO, " TTLevels SuggestedSetting %x\n", ThermalConfig->TTLevels.SuggestedSetting));
+  DEBUG ((DEBUG_INFO, " TTLevels PchCrossThrottling %x\n", ThermalConfig->TTLevels.PchCrossThrottling));
+
+  DEBUG ((DEBUG_INFO, " DmiHaAWC DmiTsawEn %x\n", ThermalConfig->DmiHaAWC.DmiTsawEn));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS0TW %x\n", ThermalConfig->DmiHaAWC.TS0TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS1TW %x\n", ThermalConfig->DmiHaAWC.TS1TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS2TW %x\n", ThermalConfig->DmiHaAWC.TS2TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC TS3TW %x\n", ThermalConfig->DmiHaAWC.TS3TW));
+  DEBUG ((DEBUG_INFO, " DmiHaAWC SuggestedSetting %x\n", ThermalConfig->DmiHaAWC.SuggestedSetting));
+
+  DEBUG ((DEBUG_INFO, " MemoryThrottling Enable= %x\n", ThermalConfig->MemoryThrottling.Enable));
+  for (Index = 0; Index < MaxTsGpioPin; Index++) {
+    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting PmsyncEnable= %x\n", ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PmsyncEnable));
+    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting C0TransmitEnable= %x\n", ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].C0TransmitEnable));
+    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting PinSelection= %x\n", ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PinSelection));
+  }
+  DEBUG ((DEBUG_INFO, " PchHotEnable = %x\n", ThermalConfig->PchHotEnable));
+  DEBUG ((DEBUG_INFO, " PchHotLevel = %x\n", ThermalConfig->PchHotLevel));
+}
+
+/**
+  Print PCH_GENERAL_CONFIG and serial out.
+
+  @param[in] PchGeneralConfig   Pointer to a PCH_GENERAL_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintGeneralConfig (
+  IN CONST PCH_GENERAL_CONFIG   *PchGeneralConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH General Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Crid= %x\n", PchGeneralConfig->Crid));
+  DEBUG ((DEBUG_INFO, " LegacyIoLowLatency = %x\n", PchGeneralConfig->LegacyIoLowLatency));
+}
+
+/**
+  Print PCH_LAN_CONFIG and serial out.
+
+  @param[in] LanConfig         Pointer to a PCH_LAN_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintLanConfig (
+  IN CONST PCH_LAN_CONFIG   *LanConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH LAN Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Enable= %x\n", LanConfig->Enable));
+  DEBUG ((DEBUG_INFO, " LtrEnable= %x\n", LanConfig->LtrEnable));
+}
+
+/**
+  Print PCH_SERIAL_IO_CONFIG and serial out.
+
+  @param[in] SerialIoConfig         Pointer to a PCH_SERIAL_IO_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintSerialIoConfig (
+  IN CONST PCH_SERIAL_IO_CONFIG   *SerialIoConfig
+  )
+{
+  UINTN Index;
+#ifndef MDEPKG_NDEBUG
+  static UINT8 DeviceName[PCH_MAX_SERIALIO_CONTROLLERS][5] = {"I2C0","I2C1","I2C2","I2C3","I2C4","I2C5","SPI0","SPI1","SPI2","UA00","UA01","UA02"};
+#endif
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH Serial IO Config ------------------\n"));
+  DEBUG_CODE_BEGIN ();
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " SerialIoController %a: Mode 0x%x\n", DeviceName[Index], SerialIoConfig->DevMode[Index]));
+  }
+  DEBUG_CODE_END ();
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " SpiCsPolarity[%d] = 0x%x\n", Index, SerialIoConfig->SpiCsPolarity[Index]));
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, " UartHwFlowCtrl[%d] = 0x%x\n", Index, SerialIoConfig->UartHwFlowCtrl[Index]));
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index ++) {
+    DEBUG ((DEBUG_INFO, " I2cPadsTermination[%d] = 0x%x\n", Index, SerialIoConfig->I2cPadsTermination[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " DebugUartNumber = 0x%x\n", SerialIoConfig->DebugUartNumber));
+  DEBUG ((DEBUG_INFO, " EnableDebugUartAfterPost = 0x%x\n", SerialIoConfig->EnableDebugUartAfterPost));
+  DEBUG ((DEBUG_INFO, " Uart0PinMuxing = 0x%x\n", SerialIoConfig->Uart0PinMuxing));
+}
+
+/**
+  Print PCH_INTERRUPT_CONFIG and serial out
+
+  @param[in] InterruptConfig        Pointer to Interrupt Configuration structure
+
+**/
+VOID
+PchPrintInterruptConfig (
+  IN CONST PCH_INTERRUPT_CONFIG     *InterruptConfig
+  )
+{
+  UINTN Index;
+  //
+  // Print interrupt information
+  //
+  DEBUG ((DEBUG_INFO, "------------------ PCH Interrupt Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " Interrupt assignment:\n"));
+  DEBUG ((DEBUG_INFO, "  Dxx:Fx INTx IRQ\n"));
+  for (Index = 0; Index < InterruptConfig->NumOfDevIntConfig; Index++) {
+    DEBUG ((DEBUG_INFO, "  D%02d:F%d    %d %03d\n",
+            InterruptConfig->DevIntConfig[Index].Device,
+            InterruptConfig->DevIntConfig[Index].Function,
+            InterruptConfig->DevIntConfig[Index].IntX,
+            InterruptConfig->DevIntConfig[Index].Irq));
+  }
+  DEBUG ((DEBUG_INFO, " Legacy PIC interrupt routing:\n"));
+  DEBUG ((DEBUG_INFO, "  PIRQx    IRQx\n"));
+  for (Index = 0; Index < PCH_MAX_PXRC_CONFIG; Index++) {
+    DEBUG ((DEBUG_INFO, "  PIRQ%c -> IRQ%d\n", Index + 65, InterruptConfig->PxRcConfig[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " Other interrupt configuration:\n"));
+  DEBUG ((DEBUG_INFO, "  GpioIrqRoute= %d\n", InterruptConfig->GpioIrqRoute));
+  DEBUG ((DEBUG_INFO, "  SciIrqSelect= %d\n", InterruptConfig->SciIrqSelect));
+  DEBUG ((DEBUG_INFO, "  TcoIrqEnable= %d\n", InterruptConfig->TcoIrqEnable));
+  DEBUG ((DEBUG_INFO, "  TcoIrqSelect= %d\n", InterruptConfig->TcoIrqSelect));
+}
+
+/**
+  Print PCH_SCS_CONFIG and serial out.
+
+  @param[in] ScsConfig         Pointer to a PCH_SCS_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintScsConfig (
+  IN CONST PCH_SCS_CONFIG   *ScsConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH SCS Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " ScsEmmcEnabled = %x\n", ScsConfig->ScsEmmcEnabled));
+  DEBUG ((DEBUG_INFO, " ScsSdcardEnabled = %x\n", ScsConfig->ScsSdcardEnabled));
+  DEBUG ((DEBUG_INFO, " SdCardPowerEnableActiveHigh = %x\n", ScsConfig->SdCardPowerEnableActiveHigh));
+  DEBUG ((DEBUG_INFO, " ScsUfsEnabled = %x\n", ScsConfig->ScsUfsEnabled));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400Enabled = %x\n", ScsConfig->ScsEmmcHs400Enabled));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400TuningRequired = %x\n", ScsConfig->ScsEmmcHs400TuningRequired));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400DllDataValid = %x\n", ScsConfig->ScsEmmcHs400DllDataValid));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400RxStrobeDll1 = %x\n", ScsConfig->ScsEmmcHs400RxStrobeDll1));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400TxDataDll = %x\n", ScsConfig->ScsEmmcHs400TxDataDll));
+  DEBUG ((DEBUG_INFO, " ScsEmmcHs400DriverStrength = %x\n", ScsConfig->ScsEmmcHs400DriverStrength));
+}
+
+/**
+  Print PCH_ISH_CONFIG and serial out.
+
+  @param[in] IshConfig         Pointer to a PCH_ISH_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintIshConfig (
+  IN CONST PCH_ISH_CONFIG   *IshConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH ISH Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " SPI GPIO Assigned   = %x\n", IshConfig->SpiGpioAssign));
+  DEBUG ((DEBUG_INFO, " UART0 GPIO Assigned = %x\n", IshConfig->Uart0GpioAssign));
+  DEBUG ((DEBUG_INFO, " UART1 GPIO Assigned = %x\n", IshConfig->Uart1GpioAssign));
+  DEBUG ((DEBUG_INFO, " I2C0 GPIO Assigned  = %x\n", IshConfig->I2c0GpioAssign));
+  DEBUG ((DEBUG_INFO, " I2C1 GPIO Assigned  = %x\n", IshConfig->I2c1GpioAssign));
+  DEBUG ((DEBUG_INFO, " I2C2 GPIO Assigned  = %x\n", IshConfig->I2c2GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_0 GPIO Assigned  = %x\n", IshConfig->Gp0GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_1 GPIO Assigned  = %x\n", IshConfig->Gp1GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_2 GPIO Assigned  = %x\n", IshConfig->Gp2GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_3 GPIO Assigned  = %x\n", IshConfig->Gp3GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_4 GPIO Assigned  = %x\n", IshConfig->Gp4GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_5 GPIO Assigned  = %x\n", IshConfig->Gp5GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_6 GPIO Assigned  = %x\n", IshConfig->Gp6GpioAssign));
+  DEBUG ((DEBUG_INFO, " GP_7 GPIO Assigned  = %x\n", IshConfig->Gp7GpioAssign));
+}
+
+/**
+  Print PCH_FLASH_PROTECTION_CONFIG and serial out.
+
+  @param[in] FlashProtectConfig  Pointer to a PCH_FLASH_PROTECTION_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintFlashProtectionConfig (
+  IN CONST PCH_FLASH_PROTECTION_CONFIG   *FlashProtectConfig
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH Flash Protection Config ------------------\n"));
+  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; ++Index) {
+    DEBUG ((DEBUG_INFO, " WriteProtectionEnable[%d] = %x\n", Index, FlashProtectConfig->ProtectRange[Index].WriteProtectionEnable));
+    DEBUG ((DEBUG_INFO, " ReadProtectionEnable[%d]  = %x\n", Index, FlashProtectConfig->ProtectRange[Index].ReadProtectionEnable));
+    DEBUG ((DEBUG_INFO, " ProtectedRangeLimit[%d]   = %x\n", Index, FlashProtectConfig->ProtectRange[Index].ProtectedRangeLimit));
+    DEBUG ((DEBUG_INFO, " ProtectedRangeBase[%d]    = %x\n", Index, FlashProtectConfig->ProtectRange[Index].ProtectedRangeBase));
+  }
+}
+
+/**
+  Print PCH_P2SB_CONFIG and serial out.
+
+  @param[in] P2sbConfig                 Pointer to a PCH_P2SB_CONFIG that provides the platform setting
+
+**/
+VOID
+PchPrintP2sbConfig (
+  IN CONST PCH_P2SB_CONFIG              *P2sbConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH P2SB Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "SbAccessUnlock= %x\n", P2sbConfig->SbAccessUnlock));
+}
+
+/**
+  Print PCH_ESPI_CONFIG.
+
+  @param[in] EspiConfig         Pointer to a PCH_ESPI_CONFIG that provides the eSPI setting
+
+**/
+VOID
+PchPrintEspiConfig (
+  IN CONST PCH_ESPI_CONFIG   *EspiConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH eSPI Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " LGMR Enable %x\n", EspiConfig->LgmrEnable));
+  DEBUG ((DEBUG_INFO, " BME for Master and Slave Enabled %x\n", EspiConfig->BmeMasterSlaveEnabled));
+}
+
+/**
+  Print PCH_CNVI_CONFIG.
+
+  @param[in] CnviConfig         Pointer to a PCH_CNVI_CONFIG that provides the CNVi settings
+
+**/
+VOID
+PchPrintCnviConfig (
+  IN CONST PCH_CNVI_CONFIG   *CnviConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH CNVi Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, "CNVi Mode = %x\n", CnviConfig->Mode));
+  DEBUG ((DEBUG_INFO, "CNVi MfUart1 type = %x\n", CnviConfig->MfUart1Type));
+}
+
+/**
+  Print PCH_HSIO_CONFIG.
+
+  @param[in] HsioConfig         Pointer to a PCH_HSIO_CONFIG that provides the eSPI setting
+
+**/
+VOID
+PchPrintHsioConfig (
+  IN CONST PCH_HSIO_CONFIG   *HsioConfig
+  )
+{
+  PCH_HSIO_VER_INFO             *BiosChipsetInitVerInfoPtr;
+  DEBUG ((DEBUG_INFO, "------------------ PCH HSIO Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " ChipsetInit Binary Pointer            = %x\n", HsioConfig->ChipsetInitBinPtr));
+  DEBUG ((DEBUG_INFO, " ChipsetInit Binary Length             = %x\n", HsioConfig->ChipsetInitBinLen));
+  BiosChipsetInitVerInfoPtr = (PCH_HSIO_VER_INFO *) HsioConfig->ChipsetInitBinPtr;
+  if (HsioConfig->ChipsetInitBinPtr && HsioConfig->ChipsetInitBinLen) {
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC           = %x\n", BiosChipsetInitVerInfoPtr->BaseCrc));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC            = %x\n", BiosChipsetInitVerInfoPtr->OemCrc));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC            = %x\n", BiosChipsetInitVerInfoPtr->SusCrc));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Version            = %x\n", BiosChipsetInitVerInfoPtr->Version));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Product            = %x\n", BiosChipsetInitVerInfoPtr->Product));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Metal Layer        = %x\n", BiosChipsetInitVerInfoPtr->MetalLayer));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base Layer         = %x\n", BiosChipsetInitVerInfoPtr->BaseLayer));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM Version        = %x\n", BiosChipsetInitVerInfoPtr->OemVersion));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Debug Mode         = %x\n", BiosChipsetInitVerInfoPtr->DebugMode));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC Valid      = %x\n", BiosChipsetInitVerInfoPtr->OemCrcValid));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC Valid      = %x\n", BiosChipsetInitVerInfoPtr->SusCrcValid));
+    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC Valid     = %x\n", BiosChipsetInitVerInfoPtr->BaseCrcValid));
+  }
+}
+
+/**
+  Print whole PCH config blocks and serial out.
+
+  @param[in] SiPolicyPpi    The RC Policy PPI instance
+
+**/
+VOID
+EFIAPI
+PchPrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  )
+{
+DEBUG_CODE_BEGIN();
+  EFI_STATUS                      Status;
+  PCH_GENERAL_CONFIG              *PchGeneralConfig;
+  PCH_PCIE_CONFIG                 *PcieRpConfig;
+  PCH_SATA_CONFIG                 *SataConfig;
+  PCH_IOAPIC_CONFIG               *IoApicConfig;
+  PCH_DMI_CONFIG                  *DmiConfig;
+  PCH_FLASH_PROTECTION_CONFIG     *FlashProtectionConfig;
+  PCH_HDAUDIO_CONFIG              *HdAudioConfig;
+  PCH_INTERRUPT_CONFIG            *InterruptConfig;
+  PCH_ISH_CONFIG                  *IshConfig;
+  PCH_LAN_CONFIG                  *LanConfig;
+  PCH_P2SB_CONFIG                 *P2sbConfig;
+  PCH_LOCK_DOWN_CONFIG            *LockDownConfig;
+  PCH_PM_CONFIG                   *PmConfig;
+  PCH_SCS_CONFIG                  *ScsConfig;
+  PCH_SERIAL_IO_CONFIG            *SerialIoConfig;
+  PCH_LPC_SIRQ_CONFIG             *SerialIrqConfig;
+  PCH_THERMAL_CONFIG              *ThermalConfig;
+  USB_CONFIG                      *UsbConfig;
+  PCH_ESPI_CONFIG                 *EspiConfig;
+  PCH_CNVI_CONFIG                 *CnviConfig;
+  PCH_HSIO_CONFIG                 *HsioConfig;
+  UINT32                          SataCtrlIndex;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gDmiConfigGuid, (VOID *) &DmiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHdAudioConfigGuid, (VOID *) &HdAudioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gIshConfigGuid, (VOID *) &IshConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gLanConfigGuid, (VOID *) &LanConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gP2sbConfigGuid, (VOID *) &P2sbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gScsConfigGuid, (VOID *) &ScsConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIoConfigGuid, (VOID *) &SerialIoConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIrqConfigGuid, (VOID *) &SerialIrqConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gThermalConfigGuid, (VOID *) &ThermalConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gUsbConfigGuid, (VOID *) &UsbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gEspiConfigGuid, (VOID *) &EspiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCnviConfigGuid, (VOID *) &CnviConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHsioConfigGuid, (VOID *) &HsioConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print Policy Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPolicyPpi->TableHeader.Header.Revision));
+
+  PchPrintGeneralConfig (PchGeneralConfig);
+  PchPrintPcieConfig (PcieRpConfig);
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++) {
+    SataConfig = GetPchSataConfig (SiPolicyPpi, SataCtrlIndex);
+    PchPrintSataConfig (SataCtrlIndex, SataConfig);
+  }
+  PchPrintUsbConfig (UsbConfig);
+  PchPrintIoApicConfig (IoApicConfig);
+  PchPrintHdAudioConfig (HdAudioConfig);
+  PchPrintLanConfig (LanConfig);
+  PchPrintLockDownConfig (LockDownConfig);
+  PchPrintThermalConfig (ThermalConfig);
+  PchPrintPmConfig (PmConfig);
+  PchPrintDmiConfig (DmiConfig);
+  PchPrintSerialIrqConfig (SerialIrqConfig);
+  PchPrintSerialIoConfig (SerialIoConfig);
+  PchPrintInterruptConfig (InterruptConfig);
+  PchPrintScsConfig (ScsConfig);
+  PchPrintIshConfig (IshConfig);
+  PchPrintFlashProtectionConfig (FlashProtectionConfig);
+  PchPrintP2sbConfig (P2sbConfig);
+  PchPrintEspiConfig (EspiConfig);
+  PchPrintCnviConfig (CnviConfig);
+  PchPrintHsioConfig (HsioConfig);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Print Platform Protocol End --------------------------\n"));
+DEBUG_CODE_END();
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c
new file mode 100644
index 0000000000..2a1da20667
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c
@@ -0,0 +1,739 @@
+/** @file
+  This file is PeiPchPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/PchRegsLpcCnl.h>
+
+/**
+  mPxRcConfig[] table contains data for 8259 routing (how PIRQx is mapped to IRQy).
+  This information is used by systems which choose to use legacy PIC
+  interrupt controller. Only IRQ3-7,9-12,14,15 are valid. Values from this table
+  will be programmed into ITSS.PxRC registers.
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPxRcConfig[] = {
+  11,  // PARC: PIRQA -> IRQ11
+  10,  // PBRC: PIRQB -> IRQ10
+  11,  // PCRC: PIRQC -> IRQ11
+  11,  // PDRC: PIRQD -> IRQ11
+  11,  // PERC: PIRQE -> IRQ11
+  11,  // PFRC: PIRQF -> IRQ11
+  11,  // PGRC: PIRQG -> IRQ11
+  11   // PHRC: PIRQH -> IRQ11
+};
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchGeneralConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_GENERAL_CONFIG  *PchGeneralConfig;
+  PchGeneralConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PchGeneralConfig->Header.GuidHob.Name = %g\n", &PchGeneralConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PchGeneralConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PchGeneralConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    PCH general configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPcieRpConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN            Index;
+  PCH_PCIE_CONFIG  *PcieRpConfig;
+
+  PcieRpConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpConfig->Header.GuidHob.Name = %g\n", &PcieRpConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieRpConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    PCI Express related settings
+  ********************************/
+  PcieRpConfig->RpFunctionSwap = TRUE;
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    PcieRpConfig->RootPort[Index].Aspm                   = PchPcieAspmAutoConfig;
+    PcieRpConfig->RootPort[Index].PmSci                  = TRUE;
+    PcieRpConfig->RootPort[Index].AcsEnabled             = TRUE;
+    PcieRpConfig->RootPort[Index].PtmEnabled             = TRUE;
+    PcieRpConfig->RootPort[Index].DpcEnabled             = TRUE;
+    PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled = TRUE;
+    PcieRpConfig->RootPort[Index].MaxPayload             = PchPcieMaxPayload256;
+    PcieRpConfig->RootPort[Index].SlotImplemented        = TRUE;
+    PcieRpConfig->RootPort[Index].PhysicalSlotNumber     = (UINT8) Index;
+    PcieRpConfig->RootPort[Index].L1Substates            = PchPcieL1SubstatesL1_1_2;
+    PcieRpConfig->RootPort[Index].EnableCpm              = TRUE;
+    PcieRpConfig->RootPort[Index].Gen3EqPh3Method        = PchPcieEqHardware;
+
+    //
+    // PCIe LTR Configuration.
+    //
+    PcieRpConfig->RootPort[Index].LtrEnable             = TRUE;
+
+    PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency               = 0x1003;
+    PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency             = 0x1003;
+
+    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode           = 2;
+    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier     = 2;
+    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue          = 60;
+    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode        = 2;
+    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier  = 2;
+    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue       = 60;
+
+    PcieRpConfig->RootPort[Index].Uptp                               = 5;
+    PcieRpConfig->RootPort[Index].Dptp                               = 7;
+
+    PcieRpConfig->EqPh3LaneParam[Index].Cm                           = 6;
+    PcieRpConfig->EqPh3LaneParam[Index].Cp                           = 2;
+  }
+
+  PcieRpConfig->SwEqCoeffList[0].Cm = 4;
+  PcieRpConfig->SwEqCoeffList[0].Cp = 8;
+  PcieRpConfig->SwEqCoeffList[1].Cm = 6;
+  PcieRpConfig->SwEqCoeffList[1].Cp = 2;
+  PcieRpConfig->SwEqCoeffList[2].Cm = 8;
+  PcieRpConfig->SwEqCoeffList[2].Cp = 6;
+  PcieRpConfig->SwEqCoeffList[3].Cm = 10;
+  PcieRpConfig->SwEqCoeffList[3].Cp = 8;
+  PcieRpConfig->SwEqCoeffList[4].Cm = 12;
+  PcieRpConfig->SwEqCoeffList[4].Cp = 2;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSataConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN            PortIndex;
+  UINTN            Index;
+  UINT32           SataCtrlIndex;
+  PCH_SATA_CONFIG  *SataConfig;
+
+  SataConfig = (PCH_SATA_CONFIG *)ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Name = %g\n", &SataConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SataConfig->Header.GuidHob.Header.HobLength));
+
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++, SataConfig++) {
+    /********************************
+      SATA related settings
+    ********************************/
+    SataConfig->Enable               = TRUE;
+    SataConfig->SalpSupport          = TRUE;
+    SataConfig->SataMode             = PchSataModeAhci;
+
+    for (PortIndex = 0; PortIndex < GetPchMaxSataPortNum (SataCtrlIndex); PortIndex++) {
+      SataConfig->PortSettings[PortIndex].Enable           = TRUE;
+      SataConfig->PortSettings[PortIndex].DmVal            = 15;
+      SataConfig->PortSettings[PortIndex].DitoVal          = 625;
+    }
+
+    SataConfig->Rst.Raid0              = TRUE;
+    SataConfig->Rst.Raid1              = TRUE;
+    SataConfig->Rst.Raid10             = TRUE;
+    SataConfig->Rst.Raid5              = TRUE;
+    SataConfig->Rst.Irrt               = TRUE;
+    SataConfig->Rst.OromUiBanner       = TRUE;
+    SataConfig->Rst.OromUiDelay        = PchSataOromDelay2sec;
+    SataConfig->Rst.HddUnlock          = TRUE;
+    SataConfig->Rst.LedLocate          = TRUE;
+    SataConfig->Rst.IrrtOnly           = TRUE;
+    SataConfig->Rst.SmartStorage       = TRUE;
+    SataConfig->Rst.OptaneMemory       = TRUE;
+    SataConfig->Rst.CpuAttachedStorage = TRUE;
+
+    for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+      SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay             = 100;
+    }
+
+    SataConfig->PwrOptEnable     = TRUE;
+    SataConfig->ThermalThrottling.SuggestedSetting = TRUE;
+  }
+}
+
+/**
+  Get Sata Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     SataConfig          Pointer to Sata Config Policy
+**/
+PCH_SATA_CONFIG *
+GetPchSataConfig (
+  IN SI_POLICY_PPI      *SiPolicy,
+  IN UINT32             SataCtrlIndex
+  )
+{
+  PCH_SATA_CONFIG     *SataConfig;
+  EFI_STATUS          Status;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *) &SataConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  SataConfig += SataCtrlIndex;
+
+  return SataConfig;
+}
+
+/**
+  Load Config block default
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadIoApicConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_IOAPIC_CONFIG  *IoApicConfig;
+  IoApicConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Name = %g\n", &IoApicConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Header.HobLength = 0x%x\n", IoApicConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Io Apic configuration
+  ********************************/
+  IoApicConfig->IoApicId                   = 0x02;
+  IoApicConfig->IoApicEntry24_119          = TRUE;
+  IoApicConfig->Enable8254ClockGating      = TRUE;
+  IoApicConfig->Enable8254ClockGatingOnS3  = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadDmiConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_DMI_CONFIG  *DmiConfig;
+  DmiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Name = %g\n", &DmiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", DmiConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    DMI related settings
+  ********************************/
+  DmiConfig->DmiAspmCtrl = PchPcieAspmAutoConfig;
+}
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadFlashProtectionConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_FLASH_PROTECTION_CONFIG  *FlashProtectionConfig;
+  FlashProtectionConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "FlashProtectionConfig->Header.GuidHob.Name = %g\n", &FlashProtectionConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "FlashProtectionConfig->Header.GuidHob.Header.HobLength = 0x%x\n", FlashProtectionConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHdAudioConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HDAUDIO_CONFIG  *HdAudioConfig;
+  HdAudioConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HdAudioConfig->Header.GuidHob.Name = %g\n", &HdAudioConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HdAudioConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HdAudioConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    HD-Audio configuration
+  ********************************/
+  HdAudioConfig->DspEnable            = TRUE;
+  HdAudioConfig->HdAudioLinkFrequency = PchHdaLinkFreq24MHz;
+  HdAudioConfig->IDispLinkFrequency   = PchHdaLinkFreq96MHz;
+  HdAudioConfig->IDispLinkTmode       = PchHdaIDispMode2T;
+  HdAudioConfig->ResetWaitTimer       = 600; // Must be at least 521us (25 frames)
+  HdAudioConfig->AudioLinkHda         = TRUE;
+  HdAudioConfig->AudioLinkDmic0       = TRUE;
+  HdAudioConfig->AudioLinkDmic1       = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadInterruptConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_INTERRUPT_CONFIG  *InterruptConfig;
+  InterruptConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "InterruptConfig->Header.GuidHob.Name = %g\n", &InterruptConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "InterruptConfig->Header.GuidHob.Header.HobLength = 0x%x\n", InterruptConfig->Header.GuidHob.Header.HobLength));
+
+  LoadDeviceInterruptConfig (InterruptConfig);
+
+  ASSERT ((sizeof (mPxRcConfig) / sizeof (UINT8)) <= PCH_MAX_PXRC_CONFIG);
+  CopyMem (
+    InterruptConfig->PxRcConfig,
+    mPxRcConfig,
+    sizeof (mPxRcConfig)
+    );
+
+  InterruptConfig->GpioIrqRoute = 14;
+  InterruptConfig->SciIrqSelect = 9;
+  InterruptConfig->TcoIrqSelect = 9;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadIshConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_ISH_CONFIG  *IshConfig;
+  IshConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Name = %g\n", &IshConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Header.HobLength = 0x%x\n", IshConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadLanConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LAN_CONFIG  *LanConfig;
+  UINT16          LpcDid;
+
+  LanConfig = ConfigBlockPointer;
+  LpcDid    = PchGetLpcDid ();
+
+  DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Name = %g\n", &LanConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Header.HobLength = 0x%x\n", LanConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Lan configuration
+  ********************************/
+  LanConfig->Enable = TRUE;
+  LanConfig->LtrEnable = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadLockDownConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LOCK_DOWN_CONFIG  *LockDownConfig;
+  LockDownConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "LockDownConfig->Header.GuidHob.Name = %g\n", &LockDownConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "LockDownConfig->Header.GuidHob.Header.HobLength = 0x%x\n", LockDownConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Lockdown configuration
+  ********************************/
+  LockDownConfig->GlobalSmi       = TRUE;
+  LockDownConfig->BiosInterface   = TRUE;
+  LockDownConfig->RtcMemoryLock   = TRUE;
+  LockDownConfig->BiosLock        = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadP2sbConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_P2SB_CONFIG  *P2sbConfig;
+  P2sbConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Name = %g\n", &P2sbConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Header.HobLength = 0x%x\n", P2sbConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPmConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_PM_CONFIG  *PmConfig;
+  PmConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Name = %g\n", &PmConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PmConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    MiscPm Configuration
+  ********************************/
+  PmConfig->MeWakeSts                            = TRUE;
+  PmConfig->WolOvrWkSts                          = TRUE;
+
+  PmConfig->WakeConfig.WolEnableOverride         = TRUE;
+  PmConfig->WakeConfig.LanWakeFromDeepSx         = TRUE;
+
+  PmConfig->PchSlpS3MinAssert                    = PchSlpS350ms;
+  PmConfig->PchSlpS4MinAssert                    = PchSlpS41s;
+  PmConfig->PchSlpSusMinAssert                   = PchSlpSus4s;
+  PmConfig->PchSlpAMinAssert                     = PchSlpA2s;
+
+  PmConfig->SlpLanLowDc                          = TRUE;
+  PmConfig->PciePllSsc                           = 0xFF;
+  PmConfig->LpcClockRun                          = TRUE;
+  PmConfig->SlpS0Enable                          = TRUE;
+  PmConfig->CpuC10GatePinEnable                  = TRUE;
+  if (IsWhlCpu () && (GetCpuStepping () == EnumCflV0)) {
+    PmConfig->SlpS0WithGbeSupport                  = FALSE;
+  } else {
+    PmConfig->SlpS0WithGbeSupport                  = TRUE;
+  }
+
+  if (IsPchLp ()) {
+    PmConfig->ModPhySusPgEnable                  = TRUE;
+  }
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadScsConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_SCS_CONFIG  *ScsConfig;
+  ScsConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Name = %g\n", &ScsConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Header.HobLength = 0x%x\n", ScsConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    SCS Configuration
+  ********************************/
+  ScsConfig->ScsEmmcEnabled   = IsPchLp () ? TRUE : FALSE; // eMMC present on PCH-LP only
+  ScsConfig->ScsEmmcHs400DriverStrength = DriverStrength40Ohm;
+  //Enable Sd Card controller for Non-Desktop sku platforms
+  if (GetCpuSku () != EnumCpuTrad) {
+    ScsConfig->ScsSdcardEnabled = TRUE;
+  }
+  ScsConfig->SdCardPowerEnableActiveHigh = TRUE;
+  ScsConfig->ScsUfsEnabled    = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSerialIoConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN                 Index;
+  PCH_SERIAL_IO_CONFIG  *SerialIoConfig;
+  SerialIoConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SerialIoConfig->Header.GuidHob.Name = %g\n", &SerialIoConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SerialIoConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SerialIoConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    SerialIo Configuration
+  ********************************/
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    SerialIoConfig->DevMode[Index]         = PchSerialIoPci;
+  }
+  SerialIoConfig->DebugUartNumber          = PcdGet8 (PcdSerialIoUartNumber);
+}
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSerialIrqConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LPC_SIRQ_CONFIG  *SerialIrqConfig;
+  SerialIrqConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SerialIrqConfig->Header.GuidHob.Name = %g\n", &SerialIrqConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SerialIrqConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SerialIrqConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Serial IRQ Configuration
+  ********************************/
+  SerialIrqConfig->SirqEnable       = TRUE;
+  SerialIrqConfig->SirqMode         = PchQuietMode;
+  SerialIrqConfig->StartFramePulse  = PchSfpw4Clk;
+}
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadThermalConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_THERMAL_CONFIG  *ThermalConfig;
+  ThermalConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "ThermalConfig->Header.GuidHob.Name = %g\n", &ThermalConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "ThermalConfig->Header.GuidHob.Header.HobLength = 0x%x\n", ThermalConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Thermal configuration.
+  ********************************/
+  ThermalConfig->TsmicLock                   = TRUE;
+  ThermalConfig->PchHotLevel                 = 0x154;
+  ThermalConfig->TTLevels.SuggestedSetting   = TRUE;
+  ThermalConfig->TTLevels.PchCrossThrottling = TRUE;
+  ThermalConfig->DmiHaAWC.SuggestedSetting   = TRUE;
+
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].PmsyncEnable     = TRUE;
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].C0TransmitEnable = TRUE;
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].PmsyncEnable     = TRUE;
+  ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].C0TransmitEnable = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadUsbConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  UINTN           PortIndex;
+  USB_CONFIG      *UsbConfig;
+  UsbConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Name = %g\n", &UsbConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Header.HobLength = 0x%x\n", UsbConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    USB related configuration
+  ********************************/
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++) {
+    UsbConfig->PortUsb20[PortIndex].Enable  = TRUE;
+  }
+
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+    UsbConfig->PortUsb30[PortIndex].Enable  = TRUE;
+  }
+
+  //
+  // BIOS should program PDO in PEI phase by default
+  //
+  UsbConfig->PdoProgramming = TRUE;
+
+  //
+  // Default values of USB2 AFE settings.
+  //
+  UsbConfig->Usb2PhySusPgEnable = TRUE;
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++) {
+    UsbConfig->PortUsb20[PortIndex].Afe.Petxiset  = 3;
+    UsbConfig->PortUsb20[PortIndex].Afe.Txiset    = 2;
+    UsbConfig->PortUsb20[PortIndex].Afe.Predeemp  = 1;
+    UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit = 1;
+  }
+
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+    UsbConfig->PortUsb30HsioRx[PortIndex].HsioOlfpsCfgPullUpDwnRes = 3;
+  }
+
+  UsbConfig->XhciOcLock = TRUE;
+
+  //
+  // xDCI configuration
+  //
+  UsbConfig->XdciConfig.Enable = FALSE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadEspiConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_ESPI_CONFIG  *EspiConfig;
+  EspiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Name = %g\n", &EspiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", EspiConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Espi configuration.
+  ********************************/
+  EspiConfig->BmeMasterSlaveEnabled = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadCnviConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_CNVI_CONFIG  *CnviConfig;
+  CnviConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Name = %g\n", &CnviConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CnviConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    Cnvi configuration.
+  ********************************/
+  CnviConfig->Mode = CnviModeAuto; // Automatic detection
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHsioConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HSIO_CONFIG  *HsioConfig;
+  HsioConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Name = %g\n", &HsioConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HsioConfig->Header.GuidHob.Header.HobLength));
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchIpBlocks [] = {
+  {&gPchGeneralConfigGuid,       sizeof (PCH_GENERAL_CONFIG),           PCH_GENERAL_CONFIG_REVISION,       LoadPchGeneralConfigDefault},
+  {&gPcieRpConfigGuid,           sizeof (PCH_PCIE_CONFIG),              PCIE_RP_CONFIG_REVISION,           LoadPcieRpConfigDefault},
+  {&gSataConfigGuid,             sizeof (PCH_SATA_CONFIG),              SATA_CONFIG_REVISION,              LoadSataConfigDefault},
+  {&gIoApicConfigGuid,           sizeof (PCH_IOAPIC_CONFIG),            IOAPIC_CONFIG_REVISION,            LoadIoApicConfigDefault},
+  {&gDmiConfigGuid,              sizeof (PCH_DMI_CONFIG),               DMI_CONFIG_REVISION,               LoadDmiConfigDefault},
+  {&gFlashProtectionConfigGuid,  sizeof (PCH_FLASH_PROTECTION_CONFIG),  FLASH_PROTECTION_CONFIG_REVISION,  LoadFlashProtectionConfigDefault},
+  {&gHdAudioConfigGuid,          sizeof (PCH_HDAUDIO_CONFIG),           HDAUDIO_CONFIG_REVISION,           LoadHdAudioConfigDefault},
+  {&gInterruptConfigGuid,        sizeof (PCH_INTERRUPT_CONFIG),         INTERRUPT_CONFIG_REVISION,         LoadInterruptConfigDefault},
+  {&gIshConfigGuid,              sizeof (PCH_ISH_CONFIG),               ISH_CONFIG_REVISION,               LoadIshConfigDefault},
+  {&gLanConfigGuid,              sizeof (PCH_LAN_CONFIG),               LAN_CONFIG_REVISION,               LoadLanConfigDefault},
+  {&gLockDownConfigGuid,         sizeof (PCH_LOCK_DOWN_CONFIG),         LOCK_DOWN_CONFIG_REVISION,         LoadLockDownConfigDefault},
+  {&gP2sbConfigGuid,             sizeof (PCH_P2SB_CONFIG),              P2SB_CONFIG_REVISION,              LoadP2sbConfigDefault},
+  {&gPmConfigGuid,               sizeof (PCH_PM_CONFIG),                PM_CONFIG_REVISION,                LoadPmConfigDefault},
+  {&gScsConfigGuid,              sizeof (PCH_SCS_CONFIG),               SCS_CONFIG_REVISION,               LoadScsConfigDefault},
+  {&gSerialIoConfigGuid,         sizeof (PCH_SERIAL_IO_CONFIG),         SERIAL_IO_CONFIG_REVISION,         LoadSerialIoConfigDefault},
+  {&gSerialIrqConfigGuid,        sizeof (PCH_LPC_SIRQ_CONFIG),          SERIAL_IRQ_CONFIG_REVISION,        LoadSerialIrqConfigDefault},
+  {&gThermalConfigGuid,          sizeof (PCH_THERMAL_CONFIG),           THERMAL_CONFIG_REVISION,           LoadThermalConfigDefault},
+  {&gUsbConfigGuid,              sizeof (USB_CONFIG),                   USB_CONFIG_REVISION,               LoadUsbConfigDefault},
+  {&gEspiConfigGuid,             sizeof (PCH_ESPI_CONFIG),              ESPI_CONFIG_REVISION,              LoadEspiConfigDefault},
+  {&gCnviConfigGuid,             sizeof (PCH_CNVI_CONFIG),              CNVI_CONFIG_REVISION,              LoadCnviConfigDefault},
+  {&gHsioConfigGuid,             sizeof (PCH_HSIO_CONFIG),              HSIO_CONFIG_REVISION,              LoadHsioConfigDefault},
+};
+
+/**
+  Get PCH config block table total size.
+
+  @retval                               Size of PCH config block table
+**/
+UINT16
+EFIAPI
+PchGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mPchIpBlocks[0], sizeof (mPchIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  PchAddConfigBlocks add all PCH config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "PCH AddConfigBlocks\n"));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mPchIpBlocks[0], sizeof (mPchIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c
new file mode 100644
index 0000000000..d19692ff2c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c
@@ -0,0 +1,169 @@
+/** @file
+  This file is PeiPchPolicy library Cannon Lake specific.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+
+/**
+  mDevIntConfig[] table contains data on INTx and IRQ for each device.
+  IRQ value for devices which use ITSS INTx->PIRQx mapping need to be set in a way
+  that for each multifunctional Dxx:Fy same interrupt pins must map to the same IRQ.
+  Those IRQ values will be used to update ITSS.PIRx register.
+  In APIC relationship between PIRQs and IRQs is:
+  PIRQA -> IRQ16
+  PIRQB -> IRQ17
+  PIRQC -> IRQ18
+  PIRQD -> IRQ19
+  PIRQE -> IRQ20
+  PIRQF -> IRQ21
+  PIRQG -> IRQ22
+  PIRQH -> IRQ23
+
+  Devices which use INTx->PIRQy mapping are: cAVS(in PCI mode), SMBus, GbE, TraceHub, PCIe,
+  SATA, HECI, IDE-R, KT Redirection, xHCI, Thermal Subsystem, Camera IO Host Controller
+
+  PCI Express Root Ports mapping should be programmed only with values as in below table (D27/28/29)
+  otherwise _PRT methods in ACPI for RootPorts would require additional patching as
+  PCIe Endpoint Device Interrupt is further subjected to INTx to PIRQy Mapping
+
+  Configured IRQ values are not used if an OS chooses to be in PIC instead of APIC mode
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG mDevIntConfig[] = {
+//  {31, 0, PchNoInt, 0}, // LPC/eSPI Interface, doesn't use interrupts
+//  {31, 1, PchNoInt, 0}, // P2SB, doesn't use interrupts
+//  {31, 2, PchNoInt, 0}, // PMC , doesn't use interrupts
+  {31, 3, PchIntA, 16}, // cAVS(Audio, Voice, Speach), INTA is default, programmed in PciCfgSpace 3Dh
+  {31, 4, PchIntA, 16}, // SMBus Controller, no default value, programmed in PciCfgSpace 3Dh
+//  {31, 5, PchNoInt, 0}, // SPI , doesn't use interrupts
+  {31, 7, PchIntA, 16}, // TraceHub, INTA is default, RO register
+  {30, 0, PchIntA, 20}, // SerialIo: UART #0, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[7]
+  {30, 1, PchIntB, 21}, // SerialIo: UART #1, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[8]
+  {30, 2, PchIntC, 22}, // SerialIo: SPI #0, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[10]
+  {30, 3, PchIntD, 23}, // SerialIo: SPI #1, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[11]
+  {28, 0, PchIntA, 16}, // PCI Express Port 1, INT is default, programmed in PciCfgSpace + FCh
+  {28, 1, PchIntB, 17}, // PCI Express Port 2, INT is default, programmed in PciCfgSpace + FCh
+  {28, 2, PchIntC, 18}, // PCI Express Port 3, INT is default, programmed in PciCfgSpace + FCh
+  {28, 3, PchIntD, 19}, // PCI Express Port 4, INT is default, programmed in PciCfgSpace + FCh
+  {28, 4, PchIntA, 16}, // PCI Express Port 5, INT is default, programmed in PciCfgSpace + FCh
+  {28, 5, PchIntB, 17}, // PCI Express Port 6, INT is default, programmed in PciCfgSpace + FCh
+  {28, 6, PchIntC, 18}, // PCI Express Port 7, INT is default, programmed in PciCfgSpace + FCh
+  {28, 7, PchIntD, 19}, // PCI Express Port 8, INT is default, programmed in PciCfgSpace + FCh
+  {25, 2, PchIntC, 34}, // SerialIo UART Controller #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[9]
+//  {24, 0, 0, 0}, // Reserved (used by RST PCIe Storage Cycle Router)
+  {23, 0, PchIntA, 16}, // SATA Controller, INTA is default, programmed in PciCfgSpace + 3Dh
+  {22, 0, PchIntA, 16}, // CSME: HECI #1
+  {22, 1, PchIntB, 17}, // CSME: HECI #2
+  {22, 4, PchIntA, 16}, // CSME: HECI #3
+//  {22, 7, PchNoInt, 0}, // CSME: WLAN
+  {21, 0, PchIntA, 16}, // SerialIo I2C Controller #0, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[1]
+  {21, 1, PchIntB, 17}, // SerialIo I2C Controller #1, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[2]
+  {21, 2, PchIntC, 18}, // SerialIo I2C Controller #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[3]
+  {21, 3, PchIntD, 19}, // SerialIo I2C Controller #3, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[4]
+  {20, 0, PchIntA, 16}, // USB 3.0 xHCI Controller, no default value, programmed in PciCfgSpace 3Dh
+  {20, 1, PchIntB, 17}, // USB Device Controller (OTG)
+  //{20, 2, PchNoInt, 0}, // Shared SRAM, no interrupts
+  {20, 3, PchIntA, 16}, // CNVi WiFir
+//  {20, 4, 0, 0}, // TraceHub Phantom (ACPI) Function
+  {20, 5, PchIntD, 19}, // SCS: SDCard
+//  {18, 0, PchNoInt, 0}, // CSME: KVMcc,  doesn't use interrupts
+//  {18, 1, PchNoInt, 0}, // CSME: Clink,  doesn't use interrupts
+//  {18, 2, PchNoInt, 0}, // CSME: PMT,  doesn't use interrupts
+//  {18, 3, 0, 0}, // CSME: CSE UMA
+//  {18, 4, 0, 0}  // CSME: fTPM DMA
+  {18, 5, PchIntA, 16}  // SCS: UFS
+};
+
+//
+// mCnlPchLpOnlyDevIntConfig[] table contains data on INTx and IRQ for devices that exist on PCH-LP
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG mPchLpOnlyDevIntConfig[] = {
+  {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed in PciCfgSpace 3Dh
+  {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programmed in PciCfgSpace + FCh
+  {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programmed in PciCfgSpace + FCh
+  {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programmed in PciCfgSpace + FCh
+  {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programmed in PciCfgSpace + FCh
+  {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programmed in PciCfgSpace + FCh
+  {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programmed in PciCfgSpace + FCh
+  {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programmed in PciCfgSpace + FCh
+  {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programmed in PciCfgSpace + FCh
+  {26, 0, PchIntA, 16}, // SCS: eMMC
+  {25, 0, PchIntA, 32}, // SerialIo I2C Controller #4, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[5]
+  {25, 1, PchIntB, 33}, // SerialIo I2C Controller #5, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[6]
+  {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R)
+  {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection
+  {19, 0, PchIntA, 20}, // Integrated Sensor Hub
+  {18, 0, PchIntA, 16}, // Thermal Subsystem
+  {18, 6, PchIntB, 24}  // SerialIo: SPI #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[12]
+};
+
+//
+// mPchHOnlyDevIntConfig[] table contains data on INTx and IRQ for devices that exist on PCH-H
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG mPchHOnlyDevIntConfig[] = {
+  {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed in PciCfgSpace 3Dh
+  {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programmed in PciCfgSpace + FCh
+  {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programmed in PciCfgSpace + FCh
+  {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programmed in PciCfgSpace + FCh
+  {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programmed in PciCfgSpace + FCh
+  {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programmed in PciCfgSpace + FCh
+  {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programmed in PciCfgSpace + FCh
+  {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programmed in PciCfgSpace + FCh
+  {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programmed in PciCfgSpace + FCh
+  {27, 0, PchIntA, 16}, // PCI Express Port 17, INT is default, programmed in PciCfgSpace + FCh
+  {27, 1, PchIntB, 17}, // PCI Express Port 18, INT is default, programmed in PciCfgSpace + FCh
+  {27, 2, PchIntC, 18}, // PCI Express Port 19, INT is default, programmed in PciCfgSpace + FCh
+  {27, 3, PchIntD, 19}, // PCI Express Port 20, INT is default, programmed in PciCfgSpace + FCh
+  {27, 4, PchIntA, 16}, // PCI Express Port 21
+  {27, 5, PchIntB, 17}, // PCI Express Port 22
+  {27, 6, PchIntC, 18}, // PCI Express Port 23
+  {27, 7, PchIntD, 19}, // PCI Express Port 24
+  {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R)
+  {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection
+  {19, 0, PchIntA, 20}, // Integrated Sensor Hub
+  {18, 0, PchIntA, 16}, // Thermal Subsystem
+  {18, 6, PchIntB, 24}  // SerialIo: SPI #2, INTA is default, programmed in PCR[SERIALIO] + PCICFGCTRL[12]
+};
+
+/**
+  Adds interrupt configuration for device
+
+  @param[in/out] InterruptConfig         Pointer to interrupt config
+**/
+VOID
+LoadDeviceInterruptConfig (
+  IN OUT  PCH_INTERRUPT_CONFIG  *InterruptConfig
+  )
+{
+  UINT8                 IntConfigTableEntries;
+
+  IntConfigTableEntries = ARRAY_SIZE (mDevIntConfig);
+  ASSERT (IntConfigTableEntries <= PCH_MAX_DEVICE_INTERRUPT_CONFIG);
+  InterruptConfig->NumOfDevIntConfig = IntConfigTableEntries;
+  CopyMem (
+    InterruptConfig->DevIntConfig,
+    mDevIntConfig,
+    sizeof (mDevIntConfig)
+    );
+
+  if (IsPchLp ()) {
+    CopyMem (
+      &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]),
+      mPchLpOnlyDevIntConfig,
+      sizeof (mPchLpOnlyDevIntConfig)
+      );
+    InterruptConfig->NumOfDevIntConfig += ARRAY_SIZE (mPchLpOnlyDevIntConfig);
+  } else if (IsPchH ()) {
+    CopyMem (
+      &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]),
+      mPchHOnlyDevIntConfig,
+      sizeof (mPchHOnlyDevIntConfig)
+      );
+    InterruptConfig->NumOfDevIntConfig += ARRAY_SIZE (mPchHOnlyDevIntConfig);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c
new file mode 100644
index 0000000000..dfab5d29c2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c
@@ -0,0 +1,318 @@
+/** @file
+  This file is PeiPchPreMemPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyLibrary.h"
+#include <Library/CpuPlatformLib.h>
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchGeneralPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_GENERAL_PREMEM_CONFIG  *PchGeneralPreMemConfig;
+  PchGeneralPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PchGeneralPreMemConfig->Header.GuidHob.Name = %g\n", &PchGeneralPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    PCH general premem configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadDciPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_DCI_PREMEM_CONFIG  *DciPreMemConfig;
+  DciPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "DciPreMemConfig->Header.GuidHob.Name = %g\n", &DciPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "DciPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", DciPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    DCI Configuration
+  ********************************/
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadWatchDogPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_WDT_PREMEM_CONFIG       *WdtPreMemConfig;
+  WdtPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "WdtPreMemConfig->Header.GuidHob.Name = %g\n", &WdtPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "WdtPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", WdtPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchTraceHubPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_TRACE_HUB_PREMEM_CONFIG  *PchTraceHubPreMemConfig;
+  PchTraceHubPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PchTraceHubPreMemConfig->Header.GuidHob.Name = %g\n", &PchTraceHubPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusRsvdAddresses[] = {
+  0xA0,
+  0xA2,
+  0xA4,
+  0xA6
+};
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadSmbusPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_SMBUS_PREMEM_CONFIG  *SmbusPreMemConfig;
+  SmbusPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "SmbusPreMemConfig->Header.GuidHob.Name = %g\n", &SmbusPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SmbusPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SmbusPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    SMBus configuration
+  ********************************/
+  SmbusPreMemConfig->Enable                = TRUE;
+  SmbusPreMemConfig->DynamicPowerGating    = TRUE;
+  SmbusPreMemConfig->SpdWriteDisable       = TRUE;
+  SmbusPreMemConfig->SmbusIoBase           = PcdGet16 (PcdSmbusBaseAddress);
+  ASSERT (sizeof (mSmbusRsvdAddresses) <= PCH_MAX_SMBUS_RESERVED_ADDRESS);
+  SmbusPreMemConfig->NumRsvdSmbusAddresses = sizeof (mSmbusRsvdAddresses);
+  CopyMem (
+    SmbusPreMemConfig->RsvdSmbusAddressTable,
+    mSmbusRsvdAddresses,
+    sizeof (mSmbusRsvdAddresses)
+    );
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadLpcPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_LPC_PREMEM_CONFIG  *LpcPreMemConfig;
+  LpcPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "LpcPreMemConfig->Header.GuidHob.Name = %g\n", &LpcPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "LpcPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", LpcPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  /********************************
+    LPC Configuration
+  ********************************/
+  LpcPreMemConfig->EnhancePort8xhDecoding     = TRUE;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHsioPciePreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HSIO_PCIE_PREMEM_CONFIG  *HsioPciePreMemConfig;
+  HsioPciePreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HsioPciePreMemConfig->Header.GuidHob.Name = %g\n", &HsioPciePreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HsioPciePreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HsioPciePreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHsioSataPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HSIO_SATA_PREMEM_CONFIG  *HsioSataPreMemConfig;
+  HsioSataPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HsioSataPreMemConfig->Header.GuidHob.Name = %g\n", &HsioSataPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HsioSataPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HsioSataPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+/**
+  Get Hsio Sata Pre Mem Config Policy
+
+  @param[in]  SiPolicy            The RC Policy PPI instance
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Pointer to Hsio Sata Pre Mem Config Policy
+**/
+PCH_HSIO_SATA_PREMEM_CONFIG *
+GetPchHsioSataPreMemConfig (
+  IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy,
+  IN UINT32               SataCtrlIndex
+  )
+{
+  PCH_HSIO_SATA_PREMEM_CONFIG     *HsioSataPreMemConfig;
+  EFI_STATUS                      Status;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  HsioSataPreMemConfig += SataCtrlIndex;
+
+  return HsioSataPreMemConfig;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPcieRpPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_PCIE_RP_PREMEM_CONFIG  *PcieRpPreMemConfig;
+  UINT32                     RpIndex;
+
+  PcieRpPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name = %g\n", &PcieRpPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieRpPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  for (RpIndex = 0; RpIndex < GetPchMaxPciePortNum (); RpIndex ++) {
+    PcieRpPreMemConfig->RpEnabledMask |= (UINT32) (1 << RpIndex);
+  }
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadHdAudioPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_HDAUDIO_PREMEM_CONFIG  *HdaPreMemConfig;
+  HdaPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name = %g\n", &HdaPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HdaPreMemConfig->Header.GuidHob.Header.HobLength));
+  HdaPreMemConfig->Enable = 1;
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadIshPreMemConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCH_ISH_PREMEM_CONFIG  *IshPreMemConfig;
+  IshPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name = %g\n", &IshPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", IshPreMemConfig->Header.GuidHob.Header.HobLength));
+  //Enable ISH controller for Non-Desktop sku platforms
+  if (GetCpuSku () != EnumCpuTrad) {
+    IshPreMemConfig->Enable = TRUE;
+  }
+}
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchIpBlocksPreMem [] = {
+  {&gPchGeneralPreMemConfigGuid,     sizeof (PCH_GENERAL_PREMEM_CONFIG),    PCH_GENERAL_PREMEM_CONFIG_REVISION,        LoadPchGeneralPreMemConfigDefault},
+  {&gDciPreMemConfigGuid,            sizeof (PCH_DCI_PREMEM_CONFIG),        DCI_PREMEM_CONFIG_REVISION,                LoadDciPreMemConfigDefault},
+  {&gWatchDogPreMemConfigGuid,       sizeof (PCH_WDT_PREMEM_CONFIG),        WATCH_DOG_PREMEM_CONFIG_REVISION,          LoadWatchDogPreMemConfigDefault},
+  {&gPchTraceHubPreMemConfigGuid,    sizeof (PCH_TRACE_HUB_PREMEM_CONFIG),  PCH_TRACEHUB_PREMEM_CONFIG_REVISION,       LoadPchTraceHubPreMemConfigDefault},
+  {&gSmbusPreMemConfigGuid,          sizeof (PCH_SMBUS_PREMEM_CONFIG),      SMBUS_PREMEM_CONFIG_REVISION,              LoadSmbusPreMemConfigDefault},
+  {&gLpcPreMemConfigGuid,            sizeof (PCH_LPC_PREMEM_CONFIG),        LPC_PREMEM_CONFIG_REVISION,                LoadLpcPreMemConfigDefault},
+  {&gHsioPciePreMemConfigGuid,       sizeof (PCH_HSIO_PCIE_PREMEM_CONFIG),  HSIO_PCIE_PREMEM_CONFIG_REVISION,          LoadHsioPciePreMemConfigDefault},
+  {&gHsioSataPreMemConfigGuid,       sizeof (PCH_HSIO_SATA_PREMEM_CONFIG),  HSIO_SATA_PREMEM_CONFIG_REVISION,          LoadHsioSataPreMemConfigDefault},
+  {&gPcieRpPreMemConfigGuid,         sizeof (PCH_PCIE_RP_PREMEM_CONFIG),    PCIE_RP_PREMEM_CONFIG_REVISION,            LoadPcieRpPreMemConfigDefault},
+  {&gHdAudioPreMemConfigGuid,        sizeof (PCH_HDAUDIO_PREMEM_CONFIG),    HDAUDIO_PREMEM_CONFIG_REVISION,            LoadHdAudioPreMemConfigDefault},
+  {&gIshPreMemConfigGuid,            sizeof (PCH_ISH_PREMEM_CONFIG),        ISH_PREMEM_CONFIG_REVISION,                LoadIshPreMemConfigDefault},
+};
+
+/**
+  Get PCH PREMEM config block table total size.
+
+  @retval                               Size of PCH PREMEM config block table
+**/
+UINT16
+EFIAPI
+PchGetPreMemConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mPchIpBlocksPreMem[0], sizeof (mPchIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  PchAddPreMemConfigBlocks add all PCH PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add PCH PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+PchAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "PCH AddPreMemConfigBlocks\n"));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mPchIpBlocksPreMem[0], sizeof (mPchIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
new file mode 100644
index 0000000000..2210344462
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
@@ -0,0 +1,109 @@
+/** @file
+  PCH RESET PEIM DRIVER.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/Reset2.h>
+#include <Ppi/PchReset.h>
+#include <Library/PchResetLib.h>
+#include <Library/ResetSystemLib.h>
+
+
+/**
+  Resets the entire platform.
+
+  @param[in] ResetType            UEFI defined reset type.
+  @param[in] ResetStatus          The status code for the reset.
+  @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
+ResetSystem (
+  IN EFI_RESET_TYPE     ResetType,
+  IN EFI_STATUS         ResetStatus,
+  IN UINTN              DataSize,
+  IN VOID               *ResetData OPTIONAL
+  )
+{
+  switch (ResetType) {
+  case EfiResetWarm:
+    ResetWarm ();
+    break;
+
+  case EfiResetCold:
+    ResetCold ();
+    break;
+
+  case EfiResetShutdown:
+    ResetShutdown ();
+    return;
+
+  case EfiResetPlatformSpecific:
+    ResetPlatformSpecific (DataSize, ResetData);
+    return;
+
+  default:
+    return;
+  }
+
+  //
+  // Given we should have reset getting here would be bad
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop();
+}
+
+/**
+  Initialize PCH Reset APIs
+
+  @retval EFI_SUCCESS             APIs are installed successfully
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
+**/
+EFI_STATUS
+EFIAPI
+PchInitializeReset (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  EFI_PEI_RESET2_PPI        *EfiPeiReset2Ppi;
+  EFI_PEI_PPI_DESCRIPTOR    *EfiPeiReset2Descriptor;
+
+  DEBUG ((DEBUG_INFO, "PchInitializeReset() Start\n"));
+
+
+  EfiPeiReset2Descriptor = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  EfiPeiReset2Ppi = (EFI_PEI_RESET2_PPI *) AllocateZeroPool (sizeof (EFI_PEI_RESET2_PPI));
+  if ((EfiPeiReset2Descriptor == NULL) ||
+      (EfiPeiReset2Ppi == NULL)) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  ///
+  /// Initialize the EFI Reset2 ppi instance
+  ///
+  EfiPeiReset2Ppi->ResetSystem  = ResetSystem;
+
+  EfiPeiReset2Descriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  EfiPeiReset2Descriptor->Guid  = &gEfiPeiReset2PpiGuid;
+  EfiPeiReset2Descriptor->Ppi   = EfiPeiReset2Ppi;
+
+  Status = PeiServicesInstallPpi (EfiPeiReset2Descriptor);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "PchInitializeReset() End\n"));
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c
new file mode 100644
index 0000000000..58f2d86103
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c
@@ -0,0 +1,257 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchResetLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Ppi/PchReset.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.h>
+
+/**
+  Dump reset message for debug build readability
+**/
+VOID
+DumpResetMessage (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINTN       Index;
+  //
+  // ******************************
+  // **    SYSTEM REBOOT !!!     **
+  // ******************************
+  //
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
+  for (Index = 0; Index < 30; Index++) {
+    DEBUG ((DEBUG_INFO, "*"));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG_CODE_END ();
+}
+/**
+  Execute call back function for Pch Reset.
+
+  @param[in] ResetType            Reset Types which includes GlobalReset.
+  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset Type Guid.
+**/
+VOID
+PchResetCallback (
+  IN  EFI_RESET_TYPE      ResetType,
+  IN  EFI_GUID            *ResetTypeGuid
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   Instance;
+  PCH_RESET_CALLBACK_PPI  *PchResetCallbackPpi;
+
+  Instance = 0;
+  do {
+    Status = PeiServicesLocatePpi (
+               &gPchResetCallbackPpiGuid,
+               Instance,
+               NULL,
+               (VOID **) &PchResetCallbackPpi
+               );
+
+    switch (Status) {
+      case EFI_SUCCESS:
+        PchResetCallbackPpi->ResetCallback (ResetType, ResetTypeGuid);
+        break;
+      case EFI_NOT_FOUND:
+        break;
+      default:
+        ASSERT_EFI_ERROR (Status);
+        break;
+    }
+    ++Instance;
+  } while (Status == EFI_SUCCESS);
+}
+
+/**
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetCold, NULL);
+  DumpResetMessage ();
+
+  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
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetWarm, NULL);
+  DumpResetMessage ();
+
+  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;
+
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetShutdown, NULL);
+
+  ABase = PmcGetAcpiBase ();
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+  ///
+  IoWrite32 ((UINTN) (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 ((UINTN) (ABase + R_ACPI_IO_PM1_STS), B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state
+  ///
+  Data32 = IoRead32 ((UINTN) (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 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  DumpResetMessage ();
+
+  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32);
+
+  return;
+}
+
+/**
+  Internal function to execute the required HECI command for GlobalReset,
+  if failed will use PCH Reest.
+
+**/
+STATIC
+VOID
+PchGlobalReset (
+  VOID
+  )
+{
+  //
+  // Loop through callback functions of PchResetCallback PPI
+  //
+  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
+
+  //
+  // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
+  //
+  PmcEnableCf9GlobalReset ();
+
+  DumpResetMessage ();
+
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
+}
+
+/**
+  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
+  )
+{
+  EFI_GUID            *GuidPtr;
+
+  if (ResetData == NULL) {
+    DEBUG ((DEBUG_ERROR, "[PeiResetSystemLib] ResetData is not available.\n"));
+    return;
+  }
+  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID));
+  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
+    PchGlobalReset();
+  } else {
+    return;
+  }
+}
+
+/**
+  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
+  )
+{
+  ASSERT (FALSE);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
new file mode 100644
index 0000000000..1a5db7f24a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
@@ -0,0 +1,217 @@
+/** @file
+  PCH SPI PEI Library implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Ppi/Spi.h>
+#include <Private/Library/PchSpiCommonLib.h>
+#include <PchReservedResources.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+
+typedef struct {
+  EFI_PEI_PPI_DESCRIPTOR  PpiDescriptor;
+  SPI_INSTANCE            SpiInstance;
+} PEI_SPI_INSTANCE;
+
+/**
+  PCI Enumeratuion is not done till later in DXE
+  Initlialize SPI BAR0 to a default value till enumeration is done
+  also enable memory space decoding for SPI
+
+**/
+VOID
+InitSpiBar0 (
+  VOID
+  )
+{
+  UINT64       PchSpiBase;
+  PchSpiBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  PciSegmentAnd8 (PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+  PciSegmentWrite32 (PchSpiBase + R_SPI_CFG_BAR0, PCH_SPI_BASE_ADDRESS);
+  PciSegmentOr8 (PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+}
+
+/**
+  This function Initial SPI services
+
+  @retval EFI_STATUS  Results of the installation of the SPI services
+**/
+EFI_STATUS
+EFIAPI
+SpiServiceInit (
+  VOID
+  )
+{
+  EFI_STATUS        Status;
+  PEI_SPI_INSTANCE  *PeiSpiInstance;
+  SPI_INSTANCE      *SpiInstance;
+  PCH_SPI_PPI       *SpiPpi;
+
+  Status = PeiServicesLocatePpi (
+             &gPchSpiPpiGuid,
+             0,
+             NULL,
+             (VOID **)&SpiPpi
+             );
+
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_INFO, "SpiServiceInit() Start\n"));
+
+    //
+    // PCI Enumeratuion is not done till later in DXE
+    // Initlialize SPI BAR0 to a default value till enumeration is done
+    // also enable memory space decoding for SPI
+    //
+    InitSpiBar0 ();
+
+    PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof (PEI_SPI_INSTANCE));
+    if (NULL == PeiSpiInstance) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    SpiInstance = &(PeiSpiInstance->SpiInstance);
+    SpiProtocolConstructor (SpiInstance);
+
+    PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+    PeiSpiInstance->PpiDescriptor.Guid = &gPchSpiPpiGuid;
+    PeiSpiInstance->PpiDescriptor.Ppi = &(SpiInstance->SpiProtocol);
+
+    ///
+    /// Install the SPI PPI
+    ///
+    DEBUG ((DEBUG_INFO, "SPI PPI Installed\n"));
+    Status = PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor);
+    ASSERT_EFI_ERROR (Status);
+
+    DEBUG ((DEBUG_INFO, "SpiServiceInit() End\n"));
+  }
+  else {
+    DEBUG ((DEBUG_INFO, "SPI PPI already installed\n"));
+  }
+  return Status;
+}
+
+/**
+  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
+  )
+{
+  return PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
+}
+
+/**
+  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 = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & B_SPI_CFG_BC_EISS) != 0) {
+    return EFI_ACCESS_DENIED;
+  }
+  ///
+  /// Enable the access to the BIOS space for both read and write cycles
+  ///
+  PciSegmentOr8 (
+    SpiBaseAddress + R_SPI_CFG_BC,
+    B_SPI_CFG_BC_WPD
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+  VOID
+  )
+{
+  UINT64           SpiBaseAddress;
+
+  SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  ///
+  /// Disable the access to the BIOS space for write cycles
+  ///
+  PciSegmentAnd8 (
+    SpiBaseAddress + R_SPI_CFG_BC,
+    (UINT8) (~B_SPI_CFG_BC_WPD)
+    );
+}
+
+/**
+  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
+  )
+{
+  return TRUE;
+}
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base library instances

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

Adds Pch/Library/Private Base library class instances.

* BaseGpioHelpersLibNull
* BasePchSpiCommonlib
* BaseSiScheduleResetLib
* BaseSiScheduleResetLibFsp

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf     |   26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf           |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf     |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf  |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c       |  108 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c                       | 1081 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c       |   70 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c |  125 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c    |   61 ++
 9 files changed, 1579 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
new file mode 100644
index 0000000000..5502af824f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
@@ -0,0 +1,26 @@
+## @file
+# Component description file for the NULL GpioHelpersLib
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseGpioHelpersLibNull.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
new file mode 100644
index 0000000000..ea23e628c8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,28 @@
+## @file
+#  Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BasePchSpiCommonLib
+  FILE_GUID                      = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchSpiCommonLib
+
+[Sources]
+  SpiCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PmcLib
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
new file mode 100644
index 0000000000..de7f6eeb73
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for Si Reset Schedule Library.
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Guids]
+gSiScheduleResetHobGuid
+gPchConfigHobGuid
+
+[Sources]
+BaseSiScheduleResetLibCommon.c
+BaseSiScheduleResetLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf
new file mode 100644
index 0000000000..c8fe9e6079
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for Si Reset Schedule Library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSiScheduleResetLibFsp
+FILE_GUID = 1478D005-8DEC-4A6E-9619-309C6A7F313A
+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
+PeiServicesTablePointerLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Guids]
+gSiScheduleResetHobGuid
+gPchConfigHobGuid
+
+[Sources]
+BaseSiScheduleResetLibCommon.c
+BaseSiScheduleResetLibFsp.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
new file mode 100644
index 0000000000..46390eeca1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
@@ -0,0 +1,108 @@
+/** @file
+  This file contains NULL implementation for GPIO Helpers Lib
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c
new file mode 100644
index 0000000000..bc84a4f27f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c
@@ -0,0 +1,1081 @@
+/** @file
+  PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPmc.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;
+
+  //
+  // 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 = PCI_SEGMENT_LIB_ADDRESS (
+                              DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                              DEFAULT_PCI_BUS_NUMBER_PCH,
+                              PCI_DEVICE_NUMBER_PCH_SPI,
+                              PCI_FUNCTION_NUMBER_PCH_SPI,
+                              0
+                              );
+
+  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_SPI_FLASH_FDBAR_FLASH_MAP0)
+    );
+
+  //
+  // Copy Zero based Number Of Components
+  //
+  SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16 (PchSpiBar0 + R_SPI_MEM_FDOD) & B_SPI_FLASH_FDBAR_NC) >> N_SPI_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_SPI_FLASH_FCBA_FLCOMP)
+    );
+
+  //
+  // Copy Component 0 Density
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  if (SpiInstance->NumberOfComponents > 0) {
+    SpiInstance->Component1StartAddr = V_SPI_FLASH_FLCOMP_COMP_512KB <<
+      (Data32 & B_SPI_FLASH_FLCOMP_COMP0_MASK);
+    DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n", SpiInstance->Component1StartAddr));
+    SpiInstance->TotalFlashSize = SpiInstance->Component1StartAddr +
+      (V_SPI_FLASH_FLCOMP_COMP_512KB <<
+      ((Data32 & B_SPI_FLASH_FLCOMP_COMP1_MASK) >>
+      N_SPI_FLASH_FLCOMP_COMP1));
+  } else {
+    SpiInstance->TotalFlashSize = V_SPI_FLASH_FLCOMP_COMP_512KB <<
+      (Data32 & B_SPI_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_SPI_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_SPI_FLASH_FDBAR_FPSBA)
+                                             >> N_SPI_FLASH_FDBAR_FPSBA)
+                                            << N_SPI_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_SPI_FLASH_FDBAR_PCHSL)
+                                         >> N_SPI_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_SPI_FLASH_FDBAR_FLASH_MAP2)
+    );
+  //
+  // Align FPSBA with address bits for the PCH Strap portion of flash descriptor
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  SpiInstance->CpuStrapBaseAddr = (UINT16) (((Data32 & B_SPI_FLASH_FDBAR_FCPUSBA)
+                                             >> N_SPI_FLASH_FDBAR_FCPUSBA)
+                                            << N_SPI_FLASH_FDBAR_FCPUSBA_REPR);
+  DEBUG ((DEBUG_INFO, "CpuStrapBaseAddr : %0x\n", SpiInstance->CpuStrapBaseAddr));
+  ASSERT (SpiInstance->CpuStrapBaseAddr != 0);
+  //
+  // CPU Strap Length, [15:8] represents number of Dwords
+  //
+  SpiInstance->CpuStrapSize = (UINT16) (((Data32 & B_SPI_FLASH_FDBAR_CPUSL)
+                                         >> N_SPI_FLASH_FDBAR_CPUSL)
+                                        * sizeof (UINT32));
+  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 (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.
+**/
+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;
+
+  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.
+**/
+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;
+
+  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.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // 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.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // 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/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
new file mode 100644
index 0000000000..dfc49d9bf6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
@@ -0,0 +1,70 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 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 <Private/Library/SiScheduleResetLib.h>
+#include <Private/SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+SI_SCHEDULE_RESET_HOB *
+SiScheduleGetResetData (
+  VOID
+  );
+
+/**
+  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/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c
new file mode 100644
index 0000000000..e1d783b2e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c
@@ -0,0 +1,125 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Library/HobLib.h>
+#include <Private/SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c
new file mode 100644
index 0000000000..15ac61a21b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c
@@ -0,0 +1,61 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/HobLib.h>
+#include <Private/Library/SiScheduleResetLib.h>
+#include <Private/SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+SI_SCHEDULE_RESET_HOB *
+SiScheduleGetResetData (
+  VOID
+  );
+
+/**
+  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));
+  if (SiScheduleResetHob->ResetType == EfiResetPlatformSpecific) {
+    DataSize = sizeof (PCH_RESET_DATA);
+    (*GetPeiServicesTablePointer ())->ResetSystem2 (SiScheduleResetHob->ResetType, EFI_SUCCESS, DataSize, &SiScheduleResetHob->ResetData);
+  } else {
+    (*GetPeiServicesTablePointer ())->ResetSystem2 (SiScheduleResetHob->ResetType, EFI_SUCCESS, 0, NULL);
+  }
+  //
+  // Code should never reach here
+  //
+  ASSERT (FALSE);
+  return TRUE;
+}
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
@ 2019-08-17  0:52   ` Nate DeSimone
  2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:52 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private library instances

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

Adds PCH DXE private library class instances.

* DxeGpioNameBufferLib
* DxePchHdaLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf |  32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf                 |  43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c      |  20 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c                | 333 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c                      | 886 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c               | 439 ++++++++++
 6 files changed, 1753 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
new file mode 100644
index 0000000000..0dc8f9749d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
@@ -0,0 +1,32 @@
+## @file
+# Component description file for the DxeGpioMemLib
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+GpioNameBufferDxe.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
new file mode 100644
index 0000000000..a8a3f60b53
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component information file for PCH HD Audio Library
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxePchHdaLib
+FILE_GUID = DA915B7F-EE08-4C1D-B3D0-DE7C52AB155A
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchHdaLib
+
+
+[LibraryClasses]
+BaseLib
+DebugLib
+MemoryAllocationLib
+BaseMemoryLib
+PchInfoLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+
+[Sources]
+PchHdaLib.c
+PchHdaEndpoints.c
+PchHdaNhltConfig.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c
new file mode 100644
index 0000000000..af53387faf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c
@@ -0,0 +1,20 @@
+/** @file
+  This file contains implementation of the GpioMemLib for DXE phase
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Private/Library/GpioNameBufferLib.h>
+
+STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];
+
+CHAR8*
+GpioGetStaticNameBuffer (
+  VOID
+  )
+{
+  return mGpioNameBuffer;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c
new file mode 100644
index 0000000000..ea04512501
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c
@@ -0,0 +1,333 @@
+/** @file
+  This file contains HD Audio NHLT Endpoints definitions
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Private/PchHdaEndpoints.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch1_48kHz16bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    1,
+    48000,
+    96000,
+    2,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_MONO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch2_48kHz16bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    192000,
+    4,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch2_48kHz24bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {24},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch2_48kHz32bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {32},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch4_48kHz16bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    4,
+    48000,
+    384000,
+    8,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_QUAD,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE Ch4_48kHz32bitFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    4,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {32},
+  KSAUDIO_SPEAKER_QUAD,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE NarrowbandFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    1,
+    8000,
+    16000,
+    2,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_MONO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE WidebandFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    1,
+    16000,
+    32000,
+    2,
+    16,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {16},
+  KSAUDIO_SPEAKER_MONO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST WAVEFORMATEXTENSIBLE A2dpFormat =
+{
+  {
+    WAVE_FORMAT_EXTENSIBLE,
+    2,
+    48000,
+    384000,
+    8,
+    32,
+    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
+  },
+  {24},
+  KSAUDIO_SPEAKER_STEREO,
+  KSDATAFORMAT_SUBTYPE_PCM
+};
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointDmicX1 = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkDmic,   // LinkType
+  0,                 // InstanceId
+  0x8086,            // HwVendorId
+  0xae20,            // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceDmic, // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointDmicX2 = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkDmic,   // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae20,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceDmic, // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointDmicX4 = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkDmic,   // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae20,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceDmic, // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointBtRender = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae30,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceBt,   // DeviceType
+  0,                 // Direction
+  2,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointBtCapture = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  0,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae30,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceBt,   // DeviceType
+  1,                 // Direction
+  2,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointI2sRender = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  1,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae34,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceI2s,  // DeviceType
+  0,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+ENDPOINT_DESCRIPTOR  HdaEndpointI2sCapture = {
+  0,                 // EndpointDescriptorLength
+  HdaNhltLinkSsp,    // LinkType
+  1,                 // InstanceId
+  0x8086,           // HwVendorId
+  0xae34,           // HwDeviceId
+  1,                 // HwRevisionId
+  1,                 // HwSubsystemId
+  HdaNhltDeviceI2s,  // DeviceType
+  1,                 // Direction
+  0,                 // VirtualBusId
+  { 0 },             // EndpointConfig
+  { 0 },             // FormatsConfig
+  { 0 }              // DevicesInformation
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX1Config[] =
+{
+  0x00, // VirtualSlot
+  0x00, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX1ConfigSize = sizeof (DmicX1Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX2Config[] =
+{
+  0x00, // VirtualSlot
+  0x01, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
+  0x0A  // ArrayType
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX2ConfigSize = sizeof (DmicX2Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX4Config[] =
+{
+  0x00, // VirtualSlot
+  0x01, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
+  0x0D  // ArrayType
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX4ConfigSize = sizeof (DmicX4Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  BtConfig[] = {0};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 BtConfigSize = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sRender1Config[] = {0};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRender1ConfigSize = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sRender2Config[] = {0x01};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRender2ConfigSize = sizeof (I2sRender2Config);
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sCaptureConfig[] = {0};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sCaptureConfigSize = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST DEVICE_INFO I2sRenderDeviceInfo =
+{
+  "INT34C2", // DeviceId
+  0x00,      // DeviceInstanceId
+  0x01       // DevicePortId
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST DEVICE_INFO I2sCaptureDeviceInfo =
+{
+  "INT34C2", // DeviceId
+  0x00,      // DeviceInstanceId
+  0x01       // DevicePortId
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 NhltConfiguration[] = { 0xEFBEADDE };
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 NhltConfigurationSize = sizeof (NhltConfiguration);
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c
new file mode 100644
index 0000000000..a87509de1b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c
@@ -0,0 +1,886 @@
+/** @file
+  PCH HD Audio Library implementation.
+
+  Copyright (c) 2019 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 <Private/Library/PchHdaLib.h>
+#include <Library/PchInfoLib.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               i;
+  ENDPOINT_DESCRIPTOR *Endpoint;
+  Endpoint = (ENDPOINT_DESCRIPTOR*) (NhltTable->EndpointDescriptors);
+
+  if (EndpointIndex > NhltTable->EndpointCount) {
+    return NULL;
+  }
+
+  for (i = 0; i < EndpointIndex; i++) {
+    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          i;
+  UINT32         Length;
+  FORMATS_CONFIG *FormatsConfig;
+  FORMAT_CONFIG  *Format;
+
+  Length = 0;
+  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
+  Format = FormatsConfig->FormatsConfiguration;
+
+  if (FormatIndex > FormatsConfig->FormatsCount) {
+    return NULL;
+  }
+
+  for (i = 0; i < FormatIndex; i++) {
+    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) {
+    return NULL;
+  }
+
+  if (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 i;
+
+  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 (i = 0; i < (  Format->FormatConfiguration.CapabilitiesSize ) ; i++) {
+    if (i % 16 == 0) {
+      DEBUG ((DEBUG_VERBOSE, "\n"));
+    }
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Format->FormatConfiguration.Capabilities[i]));
+  }
+  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 i;
+  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 (i = 0; i < (Endpoint->EndpointConfig.CapabilitiesSize ) ; i++) {
+    if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Endpoint->EndpointConfig.Capabilities[i]));
+  }
+
+  FormatsConfigs = GetNhltEndpointFormatsConfig (Endpoint);
+
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, " Endpoint->FormatsConfig.FormatsCount = %d\n", FormatsConfigs->FormatsCount));
+  for (i = 0; i < FormatsConfigs->FormatsCount; i++) {
+    Format = GetNhltEndpointFormat (Endpoint, i);
+    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 (i = 0; i < DevicesInfo->DeviceInfoCount; i++) {
+      DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, i);
+      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 i;
+
+  DEBUG ((DEBUG_INFO, "-------------------------- OED CONFIGURATION -------------------------\n"));
+  DEBUG ((DEBUG_INFO, " OedConfig->CapabilitiesSize = %d B\n", OedConfig->CapabilitiesSize));
+  DEBUG ((DEBUG_VERBOSE, " OedConfig->Capabilities:"));
+  for (i = 0; i < (OedConfig->CapabilitiesSize) ; i++) {
+    if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", OedConfig->Capabilities[i]));
+  }
+
+  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 i;
+
+  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 (i = 0; i < NhltTable->EndpointCount; i++) {
+    NhltEndpointDump (GetNhltEndpoint (NhltTable, i));
+  }
+
+  NhltOedConfigDump (GetNhltOedConfig (NhltTable));
+  DEBUG ((DEBUG_INFO, "----------------------------------------------------------------------\n"));
+
+  DEBUG_CODE_END ();
+}
+
+/**
+  Constructs FORMATS_CONFIGS structure based on given formats list.
+
+  @param[in][out] *Endpoint     Endpoint for which format structures are created
+  @param[in]      FormatBitmask Bitmask of formats supported for given endpoint
+
+  @retval                       Size of created FORMATS_CONFIGS structure
+**/
+UINT32
+NhltFormatsConstructor (
+  IN OUT ENDPOINT_DESCRIPTOR    *Endpoint,
+  IN CONST UINT32               FormatsBitmask
+  )
+{
+  FORMATS_CONFIG *FormatsConfig;
+  FORMAT_CONFIG  *Format;
+  UINT8          FormatIndex;
+  UINT32         FormatsConfigLength;
+
+  DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() Start, FormatsBitmask = 0x%08x\n", FormatsBitmask));
+
+  FormatsConfig = NULL;
+  FormatIndex = 0;
+  FormatsConfigLength = 0;
+
+  if (!FormatsBitmask) {
+    DEBUG ((DEBUG_WARN, "No supported format found!\n"));
+    return 0;
+  }
+
+  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
+  FormatsConfig->FormatsCount = 0;
+
+  if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+      Format->FormatConfiguration.CapabilitiesSize = DmicStereo16BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicStereo16BitFormatConfig, DmicStereo16BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz32bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = DmicStereo32BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicStereo32BitFormatConfig, DmicStereo32BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch4_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+      Format->FormatConfiguration.CapabilitiesSize = DmicQuad16BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicQuad16BitFormatConfig, DmicQuad16BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch4_48kHz32bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = DmicQuad32BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicQuad32BitFormatConfig, DmicQuad32BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch1_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = DmicMono16BitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, DmicMono16BitFormatConfig, DmicMono16BitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_BT_NARROWBAND_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_NARROWBAND_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &NarrowbandFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_BT_WIDEBAND_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_WIDEBAND_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &WidebandFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_BT_A2DP_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_A2DP_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &A2dpFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = I2sRtk274Render4ch48kHz24bitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, I2sRtk274Render4ch48kHz24bitFormatConfig, I2sRtk274Render4ch48kHz24bitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  if (FormatsBitmask & B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT) {
+    DEBUG ((DEBUG_INFO, "Format: B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT\n"));
+
+    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
+    if (Format != NULL) {
+      CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
+
+      Format->FormatConfiguration.CapabilitiesSize = I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
+      CopyMem (Format->FormatConfiguration.Capabilities, I2sRtk274Capture4ch48kHz24bitFormatConfig, I2sRtk274Capture4ch48kHz24bitFormatConfigSize);
+
+      FormatsConfigLength += sizeof (*Format)
+        - sizeof (Format->FormatConfiguration.Capabilities)
+        + Format->FormatConfiguration.CapabilitiesSize;
+      FormatsConfig->FormatsCount++;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() End, FormatsCount = %d, FormatsConfigLength = %d B\n", FormatsConfig->FormatsCount, FormatsConfigLength));
+  return FormatsConfigLength;
+}
+
+/**
+  Constructs DEVICES_INFO structure based on given device info list.
+
+  @param[in][out] *Endpoint      Endpoint for which device info structures are created
+  @param[in]      DevicesBitmask Bitmask of devices supported for given endpoint
+
+  @retval                        Size of created DEVICES_INFO structure
+**/
+UINT32
+NhltDevicesInfoConstructor (
+  IN OUT   ENDPOINT_DESCRIPTOR  *Endpoint,
+  IN CONST UINT32               DevicesBitmask
+  )
+{
+  DEVICES_INFO  *DevicesInfo;
+  DEVICE_INFO   *DeviceInfo;
+  UINT8         DeviceIndex;
+  UINT32        DevicesInfoLength;
+
+  DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() Start, DevicesBitmask = 0x%08x\n", DevicesBitmask));
+
+  DevicesInfo = NULL;
+  DeviceIndex = 0;
+  DevicesInfoLength = 0;
+
+  if (!DevicesBitmask) {
+    return 0;
+  }
+
+  DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
+  if (DevicesInfo == NULL) {
+    return 0;
+  }
+  DevicesInfo->DeviceInfoCount = 0;
+
+  if (DevicesBitmask & B_HDA_I2S_RENDER_DEVICE_INFO) {
+    DEBUG ((DEBUG_INFO, "DeviceInfo: B_HDA_I2S_RENDER_DEVICE_INFO\n"));
+
+    DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
+    if (DeviceInfo != NULL) {
+      CopyMem (DeviceInfo, &I2sRenderDeviceInfo, sizeof (DEVICE_INFO));
+      DevicesInfo->DeviceInfoCount++;
+    }
+  } else if (DevicesBitmask & B_HDA_I2S_CAPTURE_DEVICE_INFO) {
+    DEBUG ((DEBUG_INFO, "DeviceInfo: B_HDA_I2S_CAPTURE_DEVICE_INFO\n"));
+
+    DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
+    if (DeviceInfo != NULL) {
+      CopyMem (DeviceInfo, &I2sCaptureDeviceInfo, sizeof (DEVICE_INFO));
+      DevicesInfo->DeviceInfoCount++;
+    }
+  }
+
+  DevicesInfoLength = DevicesInfo->DeviceInfoCount * sizeof (DEVICE_INFO);
+
+  DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() End, DevicesCount = %d, DevicesInfoLength = %d B\n", DevicesInfo->DeviceInfoCount, DevicesInfoLength));
+  return DevicesInfoLength;
+}
+
+/**
+  Constructs NHLT_ENDPOINT structure based on given endpoint type.
+
+  @param[in][out] *NhltTable              NHLT table for which endpoint is created
+  @param[in]      EndpointType            Type of endpoint to be created
+  @param[in]      EndpointFormatsBitmask  Bitmask of formats supported by endpoint
+  @param[in]      EndpointDevicesBitmask  Bitmask of device info for endpoint
+  @param[in]      EndpointIndex           Endpoint index in NHLT table
+
+  @retval                       Size of created NHLT_ENDPOINT structure
+**/
+UINT32
+NhltEndpointConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable,
+  IN NHLT_ENDPOINT              EndpointType,
+  IN UINT32                     EndpointFormatsBitmask,
+  IN UINT32                     EndpointDevicesBitmask,
+  IN UINT8                      EndpointIndex
+  )
+{
+
+  ENDPOINT_DESCRIPTOR *Endpoint;
+  SPECIFIC_CONFIG     *EndpointConfig;
+  CONST UINT8         *EndpointConfigBuffer;
+  UINT32              EndpointConfigBufferSize;
+  UINT32              EndpointDescriptorLength;
+
+  DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() Start, EndpointIndex = %d\n", EndpointIndex));
+
+  EndpointDescriptorLength = 0;
+  Endpoint = GetNhltEndpoint (NhltTable, EndpointIndex);
+  if (Endpoint == NULL) {
+    return 0;
+  }
+  EndpointDescriptorLength = sizeof (ENDPOINT_DESCRIPTOR)
+    - sizeof (SPECIFIC_CONFIG)
+    - sizeof (FORMAT_CONFIG)
+    - sizeof (DEVICE_INFO);
+
+  switch (EndpointType) {
+    case HdaDmicX1:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX1\n"));
+      CopyMem (Endpoint, &HdaEndpointDmicX1, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = DmicX1Config;
+      EndpointConfigBufferSize = DmicX1ConfigSize;
+      break;
+    case HdaDmicX2:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX2\n"));
+      CopyMem (Endpoint, &HdaEndpointDmicX2, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = DmicX2Config;
+      EndpointConfigBufferSize = DmicX2ConfigSize;
+      break;
+    case HdaDmicX4:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX4\n"));
+      CopyMem (Endpoint, &HdaEndpointDmicX4, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = DmicX4Config;
+      EndpointConfigBufferSize = DmicX4ConfigSize;
+      break;
+    case HdaBtRender:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaBtRender\n"));
+      CopyMem (Endpoint, &HdaEndpointBtRender, sizeof (ENDPOINT_DESCRIPTOR));
+      if (IsPchH ()) {
+        Endpoint->VirtualBusId = 0;
+      }
+
+      EndpointConfigBuffer = BtConfig;
+      EndpointConfigBufferSize = BtConfigSize;
+      break;
+    case HdaBtCapture:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaBtCapture\n"));
+      CopyMem (Endpoint, &HdaEndpointBtCapture, sizeof (ENDPOINT_DESCRIPTOR));
+      if (IsPchH ()) {
+        Endpoint->VirtualBusId = 0;
+      }
+
+      EndpointConfigBuffer = BtConfig;
+      EndpointConfigBufferSize = BtConfigSize;
+      break;
+    case HdaI2sRender1:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender1\n"));
+      CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = I2sRender1Config;
+      EndpointConfigBufferSize = I2sRender1ConfigSize;
+      break;
+    case HdaI2sRender2:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender2\n"));
+      CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = I2sRender2Config;
+      EndpointConfigBufferSize = I2sRender2ConfigSize;
+      break;
+    case HdaI2sCapture:
+      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sCapture\n"));
+      CopyMem (Endpoint, &HdaEndpointI2sCapture, sizeof (ENDPOINT_DESCRIPTOR));
+      EndpointConfigBuffer = I2sCaptureConfig;
+      EndpointConfigBufferSize = I2sCaptureConfigSize;
+      break;
+    default:
+      DEBUG ((DEBUG_WARN, "Unknown endpoint!\n"));
+      return 0;
+  }
+
+  EndpointConfig = GetNhltEndpointDeviceCapabilities (Endpoint);
+  EndpointConfig->CapabilitiesSize = EndpointConfigBufferSize;
+  CopyMem (EndpointConfig->Capabilities, EndpointConfigBuffer, EndpointConfig->CapabilitiesSize);
+  EndpointDescriptorLength += sizeof (*EndpointConfig)
+    - sizeof (EndpointConfig->Capabilities)
+    + EndpointConfig->CapabilitiesSize;
+
+  EndpointDescriptorLength += NhltFormatsConstructor (Endpoint, EndpointFormatsBitmask);
+  EndpointDescriptorLength += NhltDevicesInfoConstructor (Endpoint, EndpointDevicesBitmask);
+
+  Endpoint->EndpointDescriptorLength = EndpointDescriptorLength;
+
+  DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() End, EndpointDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
+  return Endpoint->EndpointDescriptorLength;
+}
+
+/**
+  Constructs SPECIFIC_CONFIG structure for OED configuration.
+
+  @param[in][out] *NhltTable    NHLT table for which OED config is created
+
+  @retval                       Size of created SPECIFIC_CONFIG structure
+**/
+UINT32
+NhltOedConfigConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable
+  )
+{
+  SPECIFIC_CONFIG *OedConfig;
+  UINT32          OedConfigLength;
+
+  OedConfigLength = 0;
+  OedConfig = GetNhltOedConfig (NhltTable);
+
+  OedConfig->CapabilitiesSize = NhltConfigurationSize;
+  CopyMem (OedConfig->Capabilities, (UINT8*) NhltConfiguration, NhltConfigurationSize);
+
+  OedConfigLength = sizeof (*OedConfig)
+    - sizeof (OedConfig->Capabilities)
+    + OedConfig->CapabilitiesSize;
+
+  return OedConfigLength;
+}
+
+/**
+  Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
+
+  @param[in]      *EndpointTable List of endpoints for NHLT
+  @param[in][out] **NhltTable    NHLT table to be created
+  @param[in][out] *NhltTableSize Size of created NHLT table
+
+  @retval EFI_SUCCESS            NHLT created successfully
+  @retval EFI_BAD_BUFFER_SIZE    Not enough resources to allocate NHLT
+**/
+EFI_STATUS
+NhltConstructor (
+  IN PCH_HDA_NHLT_ENDPOINTS     *EndpointTable,
+  IN OUT NHLT_ACPI_TABLE        **NhltTable,
+  IN OUT UINT32                 *NhltTableSize
+  )
+{
+  EFI_STATUS Status;
+  UINT8  Index;
+  UINT32 TableSize;
+  UINT32 EndpointDescriptorsLength;
+  UINT32 OedConfigLength;
+  NHLT_ACPI_TABLE *Table;
+
+
+  Status = EFI_SUCCESS;
+  TableSize = PCH_HDA_NHLT_TABLE_SIZE;
+  EndpointDescriptorsLength = 0;
+  OedConfigLength = 0;
+
+  Table = AllocateZeroPool (TableSize);
+
+  if (Table == NULL) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  Table->EndpointCount = 0;
+
+  for (Index = 0; Index < HdaEndpointMax; Index++) {
+    if (EndpointTable[Index].Enable == TRUE) {
+      EndpointDescriptorsLength += NhltEndpointConstructor (Table,
+                                     EndpointTable[Index].EndpointType,
+                                     EndpointTable[Index].EndpointFormatsBitmask,
+                                     EndpointTable[Index].EndpointDevicesBitmask,
+                                     Table->EndpointCount++);
+    }
+  }
+  DEBUG ((DEBUG_INFO, "NhltConstructor: EndpointCount = %d, All EndpointDescriptorsLength = %d B\n", Table->EndpointCount, EndpointDescriptorsLength));
+
+  OedConfigLength = NhltOedConfigConstructor (Table);
+  DEBUG ((DEBUG_INFO, "NhltConstructor: OedConfigLength = %d B\n", OedConfigLength));
+
+  TableSize = EndpointDescriptorsLength + OedConfigLength;
+
+  *NhltTableSize = TableSize;
+  *NhltTable = Table;
+
+  return Status;
+}
+
+/**
+  Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
+
+  @param[in][out] *NhltTable            NHLT table for which header will be created
+  @param[in]      NhltTableSize         Size of NHLT table
+
+  @retval None
+**/
+VOID
+NhltAcpiHeaderConstructor (
+  IN OUT NHLT_ACPI_TABLE        *NhltTable,
+  IN UINT32                     NhltTableSize
+  )
+{
+  DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor() Start\n"));
+
+  // Header
+  NhltTable->Header.Signature = NHLT_ACPI_TABLE_SIGNATURE;
+  NhltTable->Header.Length = (UINT32) (NhltTableSize + sizeof (NHLT_ACPI_TABLE) - sizeof (ENDPOINT_DESCRIPTOR) - sizeof (SPECIFIC_CONFIG));
+  NhltTable->Header.Revision = 0x0;
+  NhltTable->Header.Checksum = 0x0;
+
+  CopyMem (NhltTable->Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (NhltTable->Header.OemId));
+  NhltTable->Header.OemTableId      = PcdGet64 (PcdAcpiDefaultOemTableId);
+  NhltTable->Header.OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
+  NhltTable->Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
+  NhltTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor(), NhltAcpiTable->Header.Length = %d B\n", NhltTable->Header.Length));
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c
new file mode 100644
index 0000000000..301b1f8d10
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c
@@ -0,0 +1,439 @@
+/** @file
+  This file contains HD Audio NHLT Configuration BLOBs
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// CFL NHLT Configuration BLOBs
+//
+
+//
+// DMIC Configuration BLOBs
+//
+// DMIC Config 2 channels, 16 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicStereo16BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x00300003,
+  0x00300003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicStereo16BitFormatConfigSize = sizeof (DmicStereo16BitFormatConfig);
+
+// DMIC Config 2 channels, 32 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicStereo32BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x00380003,
+  0x00380003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicStereo32BitFormatConfigSize = sizeof (DmicStereo32BitFormatConfig);
+
+// DMIC Config 4 channels, 16 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicQuad16BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x00320003,
+  0x00320003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicQuad16BitFormatConfigSize = sizeof (DmicQuad16BitFormatConfig);
+
+// DMIC Config 4 channels, 32 bits, 2.4Mhz BCLK
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicQuad32BitFormatConfig[] =
+{
+  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
+  3,
+  3,
+  0x003A0003,
+  0x003A0003,
+  0x3,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
+  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicQuad32BitFormatConfigSize = sizeof (DmicQuad32BitFormatConfig);
+
+
+// DMIC Config 1 channel, 16 bits
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 DmicMono16BitFormatConfig[] =
+{
+  0x00000000,
+  0xfffffff0,0xfffffff0,0xfffffff0,0xfffffff0,
+  3,
+  3,
+  0x00300003,
+  0x00300003,
+  0x3,
+  0x0, 0x09001303, 0x0, 0x0301, 0, 0, 0, 0,
+  0x10, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x10, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
+  0x0, 0x09001303, 0x0, 0x0301, 0, 0, 0, 0,
+  0x10, 0x402a0, 0, 0, 0, 0, 0, 0,
+  0x10, 0xe03ae, 0, 0, 0, 0, 0, 0,
+  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520, 0xff544, 0xff6f4, 0xffa25, 0xffe65,
+  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a, 0xff4bf, 0xff64f, 0xffb20,
+  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0, 0xfeb6e, 0xfec2a, 0xff351,
+  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f, 0xfddf5, 0xfdc4d, 0xfe5ee,
+  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c, 0xfcc64, 0xfc5ee, 0xfd17e,
+  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e, 0xfb781, 0xfa86b, 0xfb408,
+  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c, 0xfa1c8, 0xf840f, 0xf8b52,
+  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e, 0xf9101, 0xf5b1e, 0xf54f4,
+  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd, 0xf92ba, 0xf3606, 0xf10ed,
+  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf, 0xfc6ed, 0xf2ff4, 0xecc96,
+  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728, 0x07874, 0xf9edb, 0xed202,
+  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2, 0x220fa, 0x16be1, 0x05638,
+  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656, 0x26d63, 0x3d808, 0x4ecc3,
+  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d, 0x14234, 0x0cae0, 0x07669,
+  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f, 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543, 0x028c8, 0x02baa,
+  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b, 0x0125c, 0x00994, 0x00025,
+  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd, 0xfc86b, 0xfcb6e, 0xfd0e6,
+  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474, 0x04065, 0x04a36, 0x0515a,
+  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3, 0xff9fb, 0xfe430, 0xfce78,
+  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e, 0xf98ea, 0xfab78, 0xfc288,
+  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3, 0x0aedc, 0x0b61f, 0x0b614,
+  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f, 0xf9eae, 0xf7533, 0xf4fa8,
+  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42, 0xf7486, 0xfa62a, 0xfdd81,
+  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb, 0x16d75, 0x16ac4, 0x15a52,
+  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4, 0xf0350, 0xeb5d6, 0xe7020,
+  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5, 0xe8dab, 0xee397, 0xf4699,
+  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400, 0x36803, 0x3bff8, 0x40a63,
+  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632, 0x413a6, 0x3d8b3, 0x3971b,
+  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1, 0x1267c, 0x0f2c0, 0x0c4c2,
+  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicMono16BitFormatConfigSize = sizeof (DmicMono16BitFormatConfig);
+
+//
+// I2S/SSP Configuration BLOBs
+// Audio Format and Configuration details
+//
+// Frequency: 48kHz, PCM resolution: 24 bits
+// TDM slots: 4
+// Codec: Realtek ALC274, mode: slave
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfig[]  = {0x0, 0xffffff10, 0xffffff32, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0x83d00437, 0xc0700000, 0x0, 0x02010004, 0xf, 0xf, 0x4002, 0x4, 0x7070f00, 0x20, 0x00000001, 0x00000fff};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfigSize = sizeof (I2sRtk274Render4ch48kHz24bitFormatConfig);
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfig[]  = {0x0, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0x83d00437, 0xc0700000, 0x0, 0x02010004, 0xf, 0xf, 0x4002, 0x4, 0x7070f00, 0x20, 0x00000001, 0x00000fff};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfigSize = sizeof (I2sRtk274Capture4ch48kHz24bitFormatConfig);
+
+//
+// BlueTooth Configuration BLOBs
+//
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 BtFormatConfig[] =
+{
+  0x0, 0xfffffff0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+  0x0, 0x80c0003f, 0xd3400000, 0x0, 0x02000005, 0x01, 0x01, 0x4002,
+  0x0, 0x07020000, 0x0, 0x01, 0x0
+};
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 BtFormatConfigSize = sizeof (BtFormatConfig);
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM library instances

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

Adds PCH SMM library class instances.

* SmmSpiFlashCommonLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf |  51 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c         | 196 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c   |  54 ++++++
 3 files changed, 301 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
new file mode 100644
index 0000000000..abc919867c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLi
+++ b/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,51 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class # # Copyright 
+(c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmSpiFlashCommonLib
+  FILE_GUID                      = 9632D96E-E849-4217-9217-DC500B8AAE47
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  LIBRARY_CLASS                  = SpiFlashCommonLib|DXE_SMM_DRIVER
+  CONSTRUCTOR                    = SmmSpiFlashCommonLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+  PciLib
+  IoLib
+  MemoryAllocationLib
+  BaseLib
+  UefiLib
+  SmmServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  MmPciLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress  ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdBiosSize         ## CONSUMES
+
+[Sources]
+  SpiFlashCommonSmmLib.c
+  SpiFlashCommon.c
+
+[Protocols]
+  gPchSmmSpiProtocolGuid                        ## CONSUMES
+
+[Depex.X64.DXE_SMM_DRIVER]
+  gPchSmmSpiProtocolGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
new file mode 100644
index 0000000000..53711db632
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLi
+++ b/SpiFlashCommon.c
@@ -0,0 +1,196 @@
+/** @file
+  Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
+  for module use.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <PchAccess.h>
+#include <Library/MmPciLib.h>
+#include <Protocol/Spi.h>
+
+
+PCH_SPI_PROTOCOL       *mSpiProtocol;
+
+//
+// FlashAreaBaseAddress and Size for boottime and runtime usage.
+//
+UINTN mFlashAreaBaseAddress = 0;
+UINTN mFlashAreaSize        = 0;
+
+/**
+  Enable block protection on the Serial Flash device.
+
+  @retval     EFI_SUCCESS       Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      Address       The starting physical address of the read.
+  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
+                                of bytes actually read.
+  @param[out]     Buffer        The destination data buffer for the read.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN                        Address,
+  IN OUT UINT32                       *NumBytes,
+     OUT UINT8                        *Buffer
+  )
+{
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // This function is implemented specifically for those platforms  // 
+ at which the SPI device is memory mapped for read. So this  // 
+ function just do a memory copy for Spi Flash Read.
+  //
+  CopyMem (Buffer, (VOID *) Address, *NumBytes);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      Address         The starting physical address of the write.
+  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
+                                  the actual number of bytes written.
+  @param[in]      Buffer          The source data buffer for the write.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN                      Address,
+  IN OUT UINT32                     *NumBytes,
+  IN     UINT8                      *Buffer
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Offset;
+  UINT32                    Length;
+  UINT32                    RemainingBytes;
+
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));  if ((NumBytes == 
+ NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ASSERT (Address >= mFlashAreaBaseAddress);
+
+  Offset = Address - mFlashAreaBaseAddress;
+
+  ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+
+  while (RemainingBytes > 0) {
+    if (RemainingBytes > SECTOR_SIZE_4KB) {
+      Length = SECTOR_SIZE_4KB;
+    } else {
+      Length = RemainingBytes;
+    }
+    Status = mSpiProtocol->FlashWrite (
+                             mSpiProtocol,
+                             FlashRegionBios,
+                             (UINT32) Offset,
+                             Length,
+                             Buffer
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    RemainingBytes -= Length;
+    Offset += Length;
+    Buffer += Length;
+  }
+
+  //
+  // Actual number of bytes written
+  //
+  *NumBytes -= RemainingBytes;
+
+  return Status;
+}
+
+/**
+  Erase the block starting at Address.
+
+  @param[in]  Address         The starting physical address of the block to be erased.
+                              This library assume that caller garantee that the PAddress
+                              is at the starting address of this block.
+  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
+                              On output, the actual number of bytes erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN    UINTN                     Address,
+  IN    UINTN                     *NumBytes
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Offset;
+  UINTN               RemainingBytes;
+
+  ASSERT (NumBytes != NULL);
+  if (NumBytes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ASSERT (Address >= mFlashAreaBaseAddress);
+
+  Offset = Address - mFlashAreaBaseAddress;
+
+  ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0);  ASSERT ((*NumBytes + 
+ Offset) <= mFlashAreaSize);
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+
+  Status = mSpiProtocol->FlashErase (
+                           mSpiProtocol,
+                           FlashRegionBios,
+                           (UINT32) Offset,
+                           (UINT32) RemainingBytes
+                           );
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
new file mode 100644
index 0000000000..43c0218d85
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLi
+++ b/SpiFlashCommonSmmLib.c
@@ -0,0 +1,54 @@
+/** @file
+  SMM Library instance of SPI Flash Common Library Class
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/SmmServicesTableLib.h> #include <Protocol/Spi.h>
+
+extern PCH_SPI_PROTOCOL   *mSpiProtocol;
+
+extern UINTN mFlashAreaBaseAddress;
+extern UINTN mFlashAreaSize;
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library  
+ instance.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+                                It will ASSERT on error for debug version.
+  @retval     EFI_ERROR         Please reference LocateProtocol for error code details.
+**/
+EFI_STATUS
+EFIAPI
+SmmSpiFlashCommonLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  mFlashAreaBaseAddress = (UINTN)PcdGet32 (PcdBiosAreaBaseAddress);
+  mFlashAreaSize        = (UINTN)PcdGet32 (PcdBiosSize);
+
+  //
+  // Locate the SMM SPI protocol.
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gPchSmmSpiProtocolGuid,
+                    NULL,
+                    (VOID **) &mSpiProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM private library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM private library instances

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

Adds PCH SMM private library class instances.

* SmmPchPrivateLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf | 32 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c   | 58 ++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf
new file mode 100644
index 0000000000..5cbad21fa5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPriva
+++ teLib/SmmPchPrivateLib.inf
@@ -0,0 +1,32 @@
+## @file
+#  PCH SMM private lib.
+#
+# Copyright (c) 2019 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
+CpuPlatformLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmPchPrivateLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c
new file mode 100644
index 0000000000..85a3086874
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPriva
+++ teLib/SmmPchPrivateLib.c
@@ -0,0 +1,58 @@
+/** @file
+  PCH SMM private lib.
+
+  Copyright (c) 2019 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/CpuPlatformLib.h>
+#include <CpuRegs.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_ADDR, 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_ADDR, Data32 & (UINT32) 
+(~BIT0));
+  ///
+  /// Read FED30880h back to ensure the setting went through.
+  ///
+  Data32 = MmioRead32 (0xFED30880);
+}
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add library instances

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

Adds System Agent (SA) library class instances.

* DxeSaPolicyLib - DXE SA policy configuration services.
* PeiDxeSmmSaPlatformLib - SA platform generation services.
* PeiSaPolicyLib - PEI SA policy configuration services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf                 |  43 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf |  38 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf                 |  74 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h               |  37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h        |  21 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h                   | 323 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h               |  39 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c                   | 473 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c        | 128 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c                   | 745 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c                   | 656 +++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c             | 284 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c                    | 559 +++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S              | 114 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm            | 126 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm           | 118 ++++
 16 files changed, 3778 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
new file mode 100644
index 0000000000..8a5092e199
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+# Copyright (c) 2019 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
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeSaPolicyLib.c
+DxeSaPolicyLibrary.h
+
+[Guids]
+gGraphicsDxeConfigGuid
+gMiscDxeConfigGuid
+gPcieDxeConfigGuid
+gMemoryDxeConfigGuid
+gVbiosDxeConfigGuid
+
+[Protocols]
+gSaPolicyProtocolGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
new file mode 100644
index 0000000000..ffc4043e7a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for SA Platform Lib
+#
+# Copyright (c) 2019 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
+CpuPlatformLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Sources]
+SaPlatformLibrary.h
+SaPlatformLibrary.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
new file mode 100644
index 0000000000..22d0f0c945
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
@@ -0,0 +1,74 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSaPolicyLib
+FILE_GUID = d7022865-ef1b-449d-8c3f-ac36488c408b
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiSaPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+ConfigBlockLib
+CpuMailboxLib
+SiConfigBlockLib
+RngLib
+PmcPrivateLib
+GpioLib
+PchInfoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdTsegSize
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress
+gSiPkgTokenSpaceGuid.PcdIpuEnable                   ## CONSUMES
+
+[Sources]
+PeiSaPolicyLib.c
+PeiSaPolicyLibrary.h
+MrcOemPlatform.c
+MrcOemPlatform.h
+SaPrintPolicy.c
+PeiSaPolicyLibSample.c
+
+[Sources.IA32]
+Ia32/MrcOemPlatform.nasm
+Ia32/MrcOemPlatform.S
+
+[Ppis]
+gSiPreMemPolicyPpiGuid        ## CONSUMES
+gSiPolicyPpiGuid              ## CONSUMES
+
+[Guids]
+gSaMiscPeiPreMemConfigGuid    ## PRODUCES
+gSaMiscPeiConfigGuid          ## PRODUCES
+gSaPciePeiPreMemConfigGuid    ## PRODUCES
+gSaPciePeiConfigGuid          ## PRODUCES
+gGraphicsPeiPreMemConfigGuid  ## CONSUMES
+gGraphicsPeiConfigGuid        ## CONSUMES
+gSwitchableGraphicsConfigGuid ## PRODUCES
+gCpuTraceHubConfigGuid        ## PRODUCES
+gMemoryConfigGuid             ## PRODUCES
+gMemoryConfigNoCrcGuid        ## PRODUCES
+gIpuPreMemConfigGuid          ## PRODUCES
+gGnaConfigGuid                ## PRODUCES
+gVtdConfigGuid                ## PRODUCES
+gSaOverclockingPreMemConfigGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
new file mode 100644
index 0000000000..449b67798c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the DxeSaPolicy library.
+
+  Copyright (c) 2019 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 <Base.h>
+#include <ConfigBlock.h>
+#include <Library/HobLib.h>
+#include <MkhiMsgs.h>
+
+#include <Protocol/SaPolicy.h>
+
+#define WORD_FIELD_VALID_BIT  BIT15
+///
+/// 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/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
new file mode 100644
index 0000000000..07d4c6e666
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for SA Platform Lib implementation.
+
+  Copyright (c) 2019 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 <SaAccess.h>
+#include <CpuAccess.h>
+#include <Library/SaPlatformLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
new file mode 100644
index 0000000000..61a6e2a691
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
@@ -0,0 +1,323 @@
+/** @file
+  This file contains functions that read the SPD data for each DIMM slot over
+  the SMBus interface.
+  This file is SampleCode for Intel SA PEI Policy initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyLibrary.h"
+#include "MrcInterface.h"
+
+#define RTC_INDEX_REGISTER        (0x70)
+#define RTC_TARGET_REGISTER       (0x71)
+
+#define RTC_INDEX_MASK            (0x7F)
+#define RTC_BANK_SIZE             (0x80)
+
+#define RTC_SECONDS               (0x00)
+#define RTC_MINUTES               (0x02)
+#define RTC_HOURS                 (0x04)
+#define RTC_DAY_OF_MONTH          (0x07)
+#define RTC_MONTH                 (0x08)
+#define RTC_YEAR                  (0x09)
+#define CMOS_REGA                 (0x0A)
+#define CMOS_REGB                 (0x0B)
+#define CMOS_REGC                 (0x0C)
+#define CMOS_REGD                 (0x0D)
+
+#define RTC_UPDATE_IN_PROGRESS    (0x80)
+#define RTC_HOLD                  (0x80)
+#define RTC_MODE_24HOUR           (0x02)
+#define RTC_CLOCK_DIVIDER         (0x20)
+#define RTC_RATE_SELECT           (0x06)
+
+#define BCD2BINARY(A)             (((((A) >> 4) & 0xF) * 10) + ((A) & 0xF))
+#define CENTURY_OFFSET            (2000)
+
+/**
+  Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+  The SPD data locations read is controlled by the current boot mode.
+
+  @param[in] BootMode           - The current MRC boot mode.
+  @param[in] Address            - SPD SmBus address offset.
+  @param[in] Buffer             - Buffer that contains the data read from the SPD.
+  @param[in] SpdDdr3Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr3TableSize   - Size of SpdDdr3Table in bytes.
+  @param[in] SpdDdr4Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr4TableSize   - Size of SpdDdr4Table in bytes.
+  @param[in] SpdLpddrTable      - Indicates which SPD bytes to read.
+  @param[in] SpdLpddrTableSize  - Size of SpdLpddrTable in bytes.
+
+  @retval TRUE if the read is successful, otherwise FALSE on error.
+**/
+BOOLEAN
+GetSpdData (
+  IN SPD_BOOT_MODE BootMode,
+  IN UINT8         Address,
+  IN OUT   UINT8   *Buffer,
+  IN UINT8         *SpdDdr3Table,
+  IN UINT32        SpdDdr3TableSize,
+  IN UINT8         *SpdDdr4Table,
+  IN UINT32        SpdDdr4TableSize,
+  IN UINT8         *SpdLpddrTable,
+  IN UINT32        SpdLpddrTableSize
+  );
+
+/**
+  Output a string to the debug stream/device.
+
+  @param[in] String     - The string to output.
+**/
+VOID
+SaDebugPrint (
+  VOID   *String
+  );
+
+/**
+  Calculate the PCI device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+  @retval The PCI device address.
+**/
+UINT32
+GetPciDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  );
+
+/**
+  Calculate the PCIE device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+   The PCIE device address.
+
+  @retval The PCIe device address
+**/
+UINT32
+GetPcieDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  );
+
+/**
+  Read specific RTC/CMOS RAM
+
+  @param[in] Location        Point to RTC/CMOS RAM offset for read
+
+  @retval The data of specific location in RTC/CMOS RAM.
+**/
+UINT8
+PeiRtcRead (
+  IN const UINT8 Location
+  );
+
+/**
+  Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
+  Since RTC time is stored in BCD, convert each value to binary.
+
+  @param[out] Seconds       - The current second (0-59).
+  @param[out] Minutes       - The current minute (0-59).
+  @param[out] Hours         - The current hour (0-23).
+  @param[out] DayOfMonth    - The current day of the month (1-31).
+  @param[out] Month         - The current month (1-12).
+  @param[out] Year          - The current year (2000-2099).
+**/
+VOID
+GetRtcTime (
+  OUT UINT8  *const Seconds,
+  OUT UINT8  *const Minutes,
+  OUT UINT8  *const Hours,
+  OUT UINT8  *const DayOfMonth,
+  OUT UINT8  *const Month,
+  OUT UINT16 *const Year
+  );
+
+/**
+  Gets CPU current time.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+
+  @retval The current CPU time in milliseconds.
+**/
+UINT64
+GetCpuTime (
+  IN VOID     *GlobalData
+  );
+
+/**
+  Sets the specified number of memory words, a word at a time, at the
+  specified destination.
+
+  @param[in, out] Dest     - Destination pointer.
+  @param[in]      NumWords - The number of dwords to set.
+  @param[in]      Value    - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemWord (
+  IN OUT VOID     *Dest,
+  IN UINTN        NumWords,
+  IN const UINT16 Value
+  );
+
+/**
+  Sets the specified number of memory dwords, a dword at a time, at the
+  specified destination.
+
+  @param[in, out] Dest      - Destination pointer.
+  @param[in]      NumDwords - The number of dwords to set.
+  @param[in]      Value     - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemDword (
+  IN OUT VOID     *Dest,
+  IN UINT32       NumDwords,
+  IN const UINT32 Value
+  );
+
+/**
+  Read 64 bits from the Memory Mapped I/O space.
+  Use MMX instruction for atomic access, because some MC registers have side effect.
+
+  @param[in] Address - Memory mapped I/O address.
+**/
+UINT64
+SaMmioRead64 (
+  IN  UINTN Address
+  );
+
+/**
+  Write 64 bits to the Memory Mapped I/O space.
+  Use MMX instruction for atomic access, because some MC registers have side effect.
+
+  @param[in] Address - Memory mapped I/O address.
+  @param[in] Value   - The value to write.
+**/
+UINT64
+SaMmioWrite64 (
+  IN UINTN Address,
+  IN UINT64 Value
+  );
+
+/**
+  Intel Silicon View Technology check point interface based on IO port reading
+
+  @param CheckPoint        Check point AH value.
+                           AH = 0x10:  End of MRC State
+                           AH = 0x20:  End of DXE State
+                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD)
+
+  @param PortReading       IO port reading address used for breakpoints
+**/
+VOID
+EFIAPI
+IsvtCheckPoint (
+  IN UINT32          CheckPoint,
+  IN UINT32          PortReading
+  );
+
+/**
+  Gets the current memory voltage (VDD).
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+
+  @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
+**/
+UINT32
+GetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd
+  );
+
+/**
+  Sets the memory voltage (VDD) to the specified value.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+  @param[in] Voltage    - The new memory voltage to set.
+
+  @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
+**/
+UINT32
+SetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd,
+  IN UINT32   Voltage
+  );
+
+/**
+  Check point that is called at various points in the MRC.
+
+  @param[in] GlobalData - MRC global data.
+  @param[in] Command    - OEM command.
+  @param[in] Pointer    - Command specific data.
+
+  @retval MrcStatus value.
+**/
+UINT32
+CheckPoint (
+  VOID   *GlobalData,
+  UINT32 Command,
+  VOID   *Pointer
+  );
+
+/**
+  Typically used to display to the I/O port 80h.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] DisplayDebugNumber - the number to display on port 80.
+
+  @retval Nothing.
+**/
+VOID
+DebugHook (
+  VOID          *GlobalData,
+  UINT16        DisplayDebugNumber
+  );
+
+/**
+  Hook to take any action after returning from MrcStartMemoryConfiguration()
+  and prior to taking any action regarding MrcStatus.  Pre-populated with issuing
+  Intel Silicon View Technology (ISVT) checkpoint 0x01.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] MrcStatus          - Mrc status variable
+**/
+VOID
+ReturnFromSmc (
+  VOID          *GlobalData,
+  UINT32        MrcStatus
+  );
+
+/**
+  Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+
+  @param[in] PciEBaseAddress  - PCI express base address.
+  @param[in] ResetValue       - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
+**/
+VOID
+SaDramReset (
+  IN UINT32 PciEBaseAddress,
+  IN UINT32 ResetValue
+  );
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
new file mode 100644
index 0000000000..124ca6a57f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
@@ -0,0 +1,39 @@
+/** @file
+  Header file for the PeiSaPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_LIBRARY_H_
+#define _PEI_SA_POLICY_LIBRARY_H_
+
+#include <CpuRegs.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/SiConfigBlockLib.h>
+
+/**
+  SaLoadSamplePolicyPreMem - Load some policy default for reference board.
+
+  @param[in] ConfigBlockTableAddress    The pointer for SA config blocks
+
+**/
+VOID
+SaLoadSamplePolicyPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+#endif // _PEI_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
new file mode 100644
index 0000000000..0e8d518fe7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
@@ -0,0 +1,473 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeSaPolicyLibrary.h"
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_ASPM_OVERRIDE_LIST mPcieAspmDevsOverride[] = {
+  {0x8086, 0x108b, 0xff, 2, 2},           ///< Tekoa w/o iAMT
+  {0x8086, 0x108c, 0x00, 0, 0},           ///< Tekoa A2
+  {0x8086, 0x108c, 0xff, 2, 2},           ///< Tekoa others
+  {0x8086, 0x109a, 0xff, 2, 2},           ///< Vidalia
+  {0x8086, 0x4222, 0xff, 2, 3},           ///< 3945ABG
+  {0x8086, 0x4227, 0xff, 2, 3},           ///< 3945ABG
+  {0x8086, 0x4228, 0xff, 2, 3},           ///< 3945ABG
+  ///
+  /// Place structures for known bad OEM/IHV devices here
+  ///
+  {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}  ///< End of table
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_LTR_DEV_INFO mPcieLtrDevsOverride[] = {
+  ///
+  /// Place holder for PCIe devices with correct LTR requirements
+  ///
+  {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}  ///< End of table
+};
+
+extern EFI_GUID gGraphicsDxeConfigGuid;
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gMiscDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+extern EFI_GUID gVbiosDxeConfigGuid;
+
+/**
+  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;
+  GRAPHICS_DXE_CONFIG         *GraphicsDxeConfig;
+  PCIE_DXE_CONFIG             *PcieDxeConfig;
+  MISC_DXE_CONFIG             *MiscDxeConfig;
+  MEMORY_DXE_CONFIG           *MemoryDxeConfig;
+  VBIOS_DXE_CONFIG            *VbiosDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gVbiosDxeConfigGuid, (VOID *)&VbiosDxeConfig);
+  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] :", SA_MC_MAX_SOCKETS));
+  for (i = 0; i < SA_MC_MAX_SOCKETS; 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, "------------------------ SA_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, " PegAspmL0s[%d] :", SA_PEG_MAX_FUN));
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspmL0s[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"));
+
+  if (PcieDxeConfig->PcieAspmDevsOverride != NULL) {
+    DEBUG ((DEBUG_INFO, "------------------------ PCIE_ASPM_OVERRIDE_LIST -----------------\n"));
+    DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId RootApmcMask EndpointApmcMask\n"));
+    i = 0;
+    while ((PcieDxeConfig->PcieAspmDevsOverride[i].VendorId != SA_PCIE_DEV_END_OF_TABLE) &&
+           (i < MAX_PCIE_ASPM_OVERRIDE)) {
+      DEBUG ((DEBUG_INFO, " %04x     %04x     %02x    %01x            %01x\n",
+              PcieDxeConfig->PcieAspmDevsOverride[i].VendorId,
+              PcieDxeConfig->PcieAspmDevsOverride[i].DeviceId,
+              PcieDxeConfig->PcieAspmDevsOverride[i].RevId,
+              PcieDxeConfig->PcieAspmDevsOverride[i].RootApmcMask,
+              PcieDxeConfig->PcieAspmDevsOverride[i].EndpointApmcMask));
+      i++;
+    }
+    DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE -----------------------\n"));
+  }
+  if (PcieDxeConfig->PcieLtrDevsOverride != NULL) {
+    DEBUG ((DEBUG_INFO, "------------------------ PCIE_LTR_DEV_INFO -----------------\n"));
+    DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId SnoopLatency NonSnoopLatency\n"));
+    i = 0;
+    while ((PcieDxeConfig->PcieLtrDevsOverride[i].VendorId != SA_PCIE_DEV_END_OF_TABLE) &&
+           (i < MAX_PCIE_LTR_OVERRIDE)) {
+      DEBUG ((DEBUG_INFO, " %04x     %04x     %02x    %01x            %01x\n",
+              PcieDxeConfig->PcieLtrDevsOverride[i].VendorId,
+              PcieDxeConfig->PcieLtrDevsOverride[i].DeviceId,
+              PcieDxeConfig->PcieLtrDevsOverride[i].RevId,
+              PcieDxeConfig->PcieLtrDevsOverride[i].SnoopLatency,
+              PcieDxeConfig->PcieLtrDevsOverride[i].NonSnoopLatency));
+      i++;
+    }
+    DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE ----------------------\n"));
+  }
+
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrEnable            : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrEnable));
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxSnoopLatency   : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrMaxSnoopLatency));
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].ObffEnable           : %x\n", i, PcieDxeConfig->PegPwrOpt[i].ObffEnable));
+    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxNoSnoopLatency : %x\n", i, PcieDxeConfig->PegPwrOpt[i].LtrMaxNoSnoopLatency));
+  }
+
+
+  if (VbiosDxeConfig != NULL) {
+    DEBUG ((DEBUG_INFO, "------------------------ SA_SG_VBIOS_CONFIGURATION -----------------\n"));
+    DEBUG ((DEBUG_INFO, " LoadVbios    : %x\n", VbiosDxeConfig->LoadVbios));
+    DEBUG ((DEBUG_INFO, " ExecuteVbios : %x\n", VbiosDxeConfig->ExecuteVbios));
+    DEBUG ((DEBUG_INFO, " VbiosSource  : %x\n", VbiosDxeConfig->VbiosSource));
+  }
+
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_CONFIGURATION -----------------\n"));
+  DEBUG ((DEBUG_INFO, " EnableAbove4GBMmio : %x\n", MiscDxeConfig->EnableAbove4GBMmio));
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+EFI_STATUS
+EFIAPI
+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%
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadPcieDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  UINT8                  pegFn;
+  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 (pegFn = 0; pegFn < SA_PEG_MAX_FUN; pegFn++) {
+    PcieDxeConfig->PegAspm[pegFn]       = PcieAspmAutoConfig;
+    PcieDxeConfig->PegAspmL0s[pegFn]    = 0;
+  }
+
+  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;
+  }
+
+  PcieDxeConfig->PcieAspmDevsOverride = mPcieAspmDevsOverride;
+  PcieDxeConfig->PcieLtrDevsOverride = mPcieLtrDevsOverride;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadMiscDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  MISC_DXE_CONFIG        *MiscDxeConfig;
+
+  MiscDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Name = %g\n", &MiscDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// RMRR Base and Limit Address for USB
+  ///
+  MiscDxeConfig->RmrrUsbBaseAddress = AllocateZeroPool (sizeof (EFI_PHYSICAL_ADDRESS) * 2);
+  ASSERT (MiscDxeConfig->RmrrUsbBaseAddress != NULL);
+  if (MiscDxeConfig->RmrrUsbBaseAddress != NULL) {
+    ///
+    /// BIOS must update USB RMRR base address
+    ///
+    MiscDxeConfig->RmrrUsbBaseAddress[0] = 0;
+    MiscDxeConfig->RmrrUsbBaseAddress[1] = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+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;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LoadVbiosDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  VBIOS_DXE_CONFIG        *VbiosDxeConfig;
+
+  VbiosDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Name = %g\n", &VbiosDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", VbiosDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// Initialize the SG VBIOS DXE Policies
+  ///
+  ///
+  /// 1 = secondary display device VBIOS Source is PCI Card
+  /// 0 = secondary display device VBIOS Source is FW Volume
+  ///
+  VbiosDxeConfig->VbiosSource = 1;
+  return EFI_SUCCESS;
+}
+
+/**
+  LoadSaDxeConfigBlockDefault - Initialize default settings for each SA Config block
+
+  @param[in] ConfigBlockPointer         The buffer pointer that will be initialized as specific config block
+  @param[in] BlockId                    Request to initialize defaults of specified config block by given Block ID
+
+  @retval EFI_SUCCESS                   The given buffer has contained the defaults of requested config block
+  @retval EFI_NOT_FOUND                 Block ID is not defined so no default Config block will be initialized
+**/
+EFI_STATUS
+EFIAPI
+LoadSaDxeConfigBlockDefault (
+  IN   VOID          *ConfigBlockPointer,
+  IN   EFI_GUID      BlockGuid
+  )
+{
+  if (CompareGuid (&BlockGuid, &gGraphicsDxeConfigGuid)) {
+    LoadIgdDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gMiscDxeConfigGuid)) {
+    LoadMiscDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gPcieDxeConfigGuid)) {
+    LoadPcieDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gMemoryDxeConfigGuid)) {
+    LoadMemoryDxeDefault (ConfigBlockPointer);
+  } else if (CompareGuid (&BlockGuid, &gVbiosDxeConfigGuid)) {
+    LoadVbiosDxeDefault (ConfigBlockPointer);
+  } else {
+    return EFI_NOT_FOUND;
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  CreateSaDxeConfigBlocks generates the config blocksg 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;
+  UINT16                            TotalBlockCount;
+  UINT16                            BlockCount;
+  VOID                              *ConfigBlockPointer;
+  EFI_STATUS                        Status;
+  SA_POLICY_PROTOCOL                *SaInitPolicy;
+  UINT16                            RequiredSize;
+  STATIC CONFIG_BLOCK_HEADER        SaDxeIpBlocks [] = {
+       {{{0, sizeof (GRAPHICS_DXE_CONFIG),    0},  {0}},     GRAPHICS_DXE_CONFIG_REVISION,           0, {0, 0}},
+       {{{0, sizeof (MEMORY_DXE_CONFIG), 0},  {0}},     MEMORY_DXE_CONFIG_REVISION,        0, {0, 0}},
+       {{{0, sizeof (MISC_DXE_CONFIG),   0},  {0}},     MISC_DXE_CONFIG_REVISION,          0, {0, 0}},
+       {{{0, sizeof (PCIE_DXE_CONFIG),   0},  {0}},     PCIE_DXE_CONFIG_REVISION,          0, {0, 0}},
+       {{{0, sizeof (VBIOS_DXE_CONFIG),  0},  {0}},     VBIOS_DXE_CONFIG_REVISION,         0, {0, 0}}
+  };
+
+  SaInitPolicy = NULL;
+  TotalBlockCount = sizeof (SaDxeIpBlocks) / sizeof (CONFIG_BLOCK_HEADER);
+  DEBUG ((DEBUG_INFO, "TotalBlockCount = 0x%x\n", TotalBlockCount));
+
+  TotalBlockSize = 0;
+  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
+    TotalBlockSize += (UINT32) SaDxeIpBlocks[BlockCount].GuidHob.Header.HobLength;
+    DEBUG ((DEBUG_INFO, "TotalBlockSize after adding  Block[0x%x]= 0x%x\n", BlockCount, TotalBlockSize));
+  }
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Initalize SklSaIpBlocks table GUID
+  //
+  CopyMem (&SaDxeIpBlocks[0].GuidHob.Name,  &gGraphicsDxeConfigGuid, sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[1].GuidHob.Name,  &gMemoryDxeConfigGuid,   sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[2].GuidHob.Name,  &gMiscDxeConfigGuid,     sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[3].GuidHob.Name,  &gPcieDxeConfigGuid,     sizeof (EFI_GUID));
+  CopyMem (&SaDxeIpBlocks[4].GuidHob.Name,  &gVbiosDxeConfigGuid,    sizeof (EFI_GUID));
+
+  //
+  // Initialize Policy Revision
+  //
+  SaInitPolicy->TableHeader.Header.Revision = SA_POLICY_PROTOCOL_REVISION;
+  //
+  // Initialize ConfigBlockPointer to NULL
+  //
+  ConfigBlockPointer = NULL;
+  //
+  // Loop to identify each config block from SaDxeIpBlocks[] Table and add each of them
+  //
+  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
+    ConfigBlockPointer = (VOID *)&SaDxeIpBlocks[BlockCount];
+    Status = AddConfigBlock ((VOID *) SaInitPolicy, (VOID *)&ConfigBlockPointer);
+    ASSERT_EFI_ERROR (Status);
+    LoadSaDxeConfigBlockDefault ((VOID *) ConfigBlockPointer, SaDxeIpBlocks[BlockCount].GuidHob.Name);
+  }
+  //
+  // Assignment for returning SaPolicy config block base address
+  //
+  *SaPolicy = SaInitPolicy;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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);
+
+  ///
+  /// 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/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
new file mode 100644
index 0000000000..fc6e469ae3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
@@ -0,0 +1,128 @@
+/** @file
+  SA Platform Lib implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaPlatformLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <SaRegs.h>
+#include <Library/CpuPlatformLib.h>
+
+/**
+  Determine if PCH Link is DMI/OPI
+
+  @param[in] CpuModel             CPU model
+
+  @retval TRUE                    DMI
+  @retval FALSE                   OPI
+**/
+BOOLEAN
+IsPchLinkDmi (
+  IN CPU_FAMILY  CpuModel
+  )
+{
+  if ((CpuModel == EnumCpuCflDtHalo) || (CpuModel == EnumCpuCnlDtHalo)) {
+    return TRUE; // DMI
+  }
+  return FALSE;  // OPI
+}
+
+
+/**
+  Returns the number of DMI lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiLanes (
+  )
+{
+    return SA_DMI_CFL_MAX_LANE;
+}
+
+
+/**
+  Returns the number of DMI bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxDmiBundles (
+  )
+{
+    return SA_DMI_CFL_MAX_BUNDLE;
+}
+
+
+/**
+  Returns the function numbers for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegFuncs (
+  )
+{
+  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
+    return SA_PEG_CNL_H_MAX_FUN;
+  } else {
+    return SA_PEG_NON_CNL_H_MAX_FUN;
+  }
+}
+
+
+/**
+  Returns the number of PEG lanes for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegLanes (
+  )
+{
+  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
+    return SA_PEG_CNL_H_MAX_LANE;
+  } else {
+    return SA_PEG_NON_CNL_H_MAX_LANE;
+  }
+}
+
+
+/**
+  Returns the number of PEG bundles for current CPU
+
+  @retval UINT8
+**/
+UINT8
+GetMaxPegBundles (
+  )
+{
+  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
+    return  SA_PEG_CNL_H_MAX_BUNDLE;
+  } else {
+    return  SA_PEG_NON_CNL_H_MAX_BUNDLE;
+  }
+}
+
+/**
+  Checks if PEG port is present
+
+  @retval TRUE     PEG is presented
+  @retval FALSE    PEG is not presented
+**/
+BOOLEAN
+IsPegPresent (
+  VOID
+  )
+{
+  UINT64  PegBaseAddress;
+
+  PegBaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, 0, 0);
+  if (PciSegmentRead16 (PegBaseAddress) != 0xFFFF) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
new file mode 100644
index 0000000000..b7aec77842
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
@@ -0,0 +1,745 @@
+/** @file
+  This file is SampleCode for Intel SA PEI Policy initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "MrcOemPlatform.h"
+#include <Library/CpuPlatformLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmbusLib.h>
+#include <PchAccess.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+
+#pragma pack (push, 1)
+typedef union {
+  struct {
+    UINT32                         : 8;
+    UINT32 MAX_NON_TURBO_LIM_RATIO : 8;
+    UINT32                         : 16;
+    UINT32                         : 32;
+  } Bits;
+  UINT64 Data;
+  UINT32 Data32[2];
+  UINT16 Data16[4];
+  UINT8  Data8[8];
+} PCU_CR_PLATFORM_INFO_STRUCT;
+
+#pragma pack (pop)
+
+#define SA_SYSTEM_BCLK                (100)
+#define PCU_CR_PLATFORM_INFO          (0xCE)
+#define MRC_POST_CODE_LOW_BYTE_ADDR   (0x48)
+#define MRC_POST_CODE_HIGH_BYTE_ADDR  (0x49)
+#define MAX_SPD_PAGE_COUNT            (2)
+#define MAX_SPD_PAGE_SIZE             (256)
+#define MAX_SPD_DDR3_SIZE             (MAX_SPD_PAGE_SIZE * 1)
+#define MAX_SPD_DDR4_SIZE             (MAX_SPD_PAGE_SIZE * 2)
+#define MAX_SPD_SIZE                  (MAX_SPD_PAGE_SIZE * MAX_SPD_PAGE_COUNT)
+#define SPD_PAGE_ADDRESS_0            (0x6C)
+#define SPD_PAGE_ADDRESS_1            (0x6E)
+#define SPD_DDR3_XMP_OFFSET           (176)
+#define SPD_DDR4_XMP_OFFSET           (384)
+#define SPD_DDR3_SDRAM_TYPE_OFFSET    (0x02)
+#define SPD_DDR3_SDRAM_TYPE_NUMBER    (0x0B)
+#define SPD_DDR4_SDRAM_TYPE_NUMBER    (0x0C)
+#define SPD_LPDDR3_SDRAM_TYPE_NUMBER  (0x0F)
+#define SPD_LPDDR4_SDRAM_TYPE_NUMBER  (0x10)
+#define SPD_LPDDR4X_SDRAM_TYPE_NUMBER (0x11)
+#define ISVT_END_OF_MRC_STATE         (0x10)
+
+/**
+  Read the SPD data over the SMBus, at the specified SPD address, starting at
+  the specified starting offset and read the given amount of data.
+
+  @param[in] SpdAddress  - SPD SMBUS address
+  @param[in, out] Buffer - Buffer to store the data.
+  @param[in] Start       - Starting SPD offset
+  @param[in] Size        - The number of bytes of data to read and also the size of the buffer.
+  @param[in, out] Page   - The final page that is being pointed to.
+
+  @retval RETURN_SUCCESS if the read is successful, otherwise error status.
+**/
+static
+RETURN_STATUS
+DoSpdRead (
+  IN     const UINT8  SpdAddress,
+  IN OUT UINT8        *const Buffer,
+  IN     const UINT16 Start,
+  IN           UINT16 Size,
+  IN OUT UINT8        *const Page
+  )
+{
+  RETURN_STATUS EfiStatus;
+  BOOLEAN       PageUpdate;
+  UINT16        Count;
+  UINT16        Index;
+
+  EfiStatus = RETURN_DEVICE_ERROR;
+  if ((Buffer != NULL) && (Start < MAX_SPD_SIZE) && ((Start + Size) < MAX_SPD_SIZE)) {
+    Count = 0;
+    PageUpdate = FALSE;
+    while (Size--) {
+      Index = Start + Count;
+      if ((Index / MAX_SPD_PAGE_SIZE) != *Page) {
+        *Page = (UINT8) (Index / MAX_SPD_PAGE_SIZE);
+        PageUpdate = TRUE;
+      }
+      Index %= MAX_SPD_PAGE_SIZE;
+      if (PageUpdate == TRUE) {
+        PageUpdate = FALSE;
+        SmBusWriteDataByte ((*Page == 0) ? SPD_PAGE_ADDRESS_0 : SPD_PAGE_ADDRESS_1, 0, &EfiStatus);
+      }
+      Buffer[Count] = SmBusReadDataByte (SpdAddress | ((UINT32) Index << 8), &EfiStatus);
+      if (RETURN_SUCCESS != EfiStatus) {
+        Buffer[Count] = 0;
+        break;
+      }
+      Count++;
+    }
+    EfiStatus = RETURN_SUCCESS;
+  }
+  return (EfiStatus);
+}
+
+/**
+  See if there is valid XMP SPD data.
+
+  @param[in] Debug    - Mrc debug structure.
+  @param[in, out] Spd - Mrc SPD structure.
+  @param[in] XmpStart - The current offset in the SPD.
+
+  @retval TRUE if valid, FALSE in not.
+**/
+static
+BOOLEAN
+VerifyXmp (
+  IN OUT MrcSpd *const Spd,
+  IN const UINT16 XmpStart
+  )
+{
+  SPD_EXTREME_MEMORY_PROFILE_HEADER      *Header1;
+  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0  *Header2;
+  BOOLEAN                                 Xmp;
+
+  Xmp = FALSE;
+
+  switch (((UINT8 *) Spd) [2]) {
+    case SPD_DDR3_SDRAM_TYPE_NUMBER:
+      Header1 = &Spd->Ddr3.Xmp.Header;
+      if (XmpStart == ((UINT32) (Header1) - (UINT32) Spd)) {
+        Xmp = TRUE;
+        if ((Header1->XmpRevision.Data & 0xFE) == 0x12) {
+          return (TRUE);
+        } else {
+          Header1->XmpId            = 0;
+          Header1->XmpOrgConf.Data  = 0;
+          Header1->XmpRevision.Data = 0;
+        }
+      }
+      break;
+    case SPD_DDR4_SDRAM_TYPE_NUMBER:
+      Header2 = &Spd->Ddr4.EndUser.Xmp.Header;
+      if (XmpStart == ((UINT32) (Header2) - (UINT32) Spd)) {
+        Xmp = TRUE;
+        if ((Header2->XmpRevision.Data) == 0x20) {
+          return (TRUE);
+        } else {
+          Header2->XmpId            = 0;
+          Header2->XmpOrgConf.Data  = 0;
+          Header2->XmpRevision.Data = 0;
+        }
+      }
+      break;
+    case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
+    case SPD_LPDDR4_SDRAM_TYPE_NUMBER:
+    case SPD_LPDDR4X_SDRAM_TYPE_NUMBER:
+      return (TRUE);
+    default:
+      return (FALSE);
+  }
+  if (!Xmp) {
+    return (TRUE);
+  }
+  return (FALSE);
+}
+
+/**
+  Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+  The SPD data locations read is controlled by the current boot mode.
+
+  @param[in] BootMode           - The current MRC boot mode.
+  @param[in] Address            - SPD SmBus address offset.
+  @param[in] Buffer             - Buffer that contains the data read from the SPD.
+  @param[in] SpdDdr3Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr3TableSize   - Size of SpdDdr3Table in bytes.
+  @param[in] SpdDdr4Table       - Indicates which SPD bytes to read.
+  @param[in] SpdDdr4TableSize   - Size of SpdDdr4Table in bytes.
+  @param[in] SpdLpddrTable      - Indicates which SPD bytes to read.
+  @param[in] SpdLpddrTableSize  - Size of SpdLpddrTable in bytes.
+
+  @retval TRUE if the read is successful, otherwise FALSE on error.
+**/
+BOOLEAN
+GetSpdData (
+  IN SPD_BOOT_MODE BootMode,
+  IN UINT8         Address,
+  IN OUT   UINT8   *Buffer,
+  IN UINT8         *SpdDdr3Table,
+  IN UINT32        SpdDdr3TableSize,
+  IN UINT8         *SpdDdr4Table,
+  IN UINT32        SpdDdr4TableSize,
+  IN UINT8         *SpdLpddrTable,
+  IN UINT32        SpdLpddrTableSize
+  )
+{
+  const SPD_OFFSET_TABLE *Tbl;
+  const SPD_OFFSET_TABLE *TableSelect;
+  RETURN_STATUS          Status;
+  UINT32                 Byte;
+  UINT32                 Stop;
+  UINT8                  Page;
+
+  Page   = (UINT8) (~0);
+  Status = DoSpdRead (Address, &Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET], 2, 1, &Page);
+  if (RETURN_SUCCESS == Status) {
+    switch (Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET]) {
+      case SPD_DDR3_SDRAM_TYPE_NUMBER:
+      default:
+        TableSelect = (SPD_OFFSET_TABLE *) SpdDdr3Table;
+        Stop = (SpdDdr3TableSize / sizeof (SPD_OFFSET_TABLE));
+        break;
+      case SPD_DDR4_SDRAM_TYPE_NUMBER:
+        TableSelect = (SPD_OFFSET_TABLE *) SpdDdr4Table;
+        Stop = (SpdDdr4TableSize / sizeof (SPD_OFFSET_TABLE));
+        break;
+      case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
+      case SPD_LPDDR4_SDRAM_TYPE_NUMBER:
+      case SPD_LPDDR4X_SDRAM_TYPE_NUMBER:
+        TableSelect = (SPD_OFFSET_TABLE *) SpdLpddrTable;
+        Stop = (SpdLpddrTableSize / sizeof (SPD_OFFSET_TABLE));
+        break;
+    }
+    for (Byte = 0; (RETURN_SUCCESS == Status) && (Byte < Stop); Byte++) {
+      Tbl = &TableSelect[Byte];
+      if ((1 << BootMode) & Tbl->BootMode) {
+        Status = DoSpdRead (Address, &Buffer[Tbl->Start], Tbl->Start, Tbl->End - Tbl->Start + 1, &Page);
+        if (Status == RETURN_SUCCESS) {
+          if (SpdCold == BootMode) {
+            if (FALSE == VerifyXmp ((MrcSpd *) Buffer, Tbl->Start)) {
+              break;
+            }
+          }
+        } else {
+          break;
+        }
+      }
+    }
+  }
+
+  return ((RETURN_SUCCESS == Status) ? TRUE : FALSE);
+}
+
+//
+// This is from MdeModulePkg\Include\Guid\StatusCodeDataTypeDebug.h
+// Might need to be adjusted for a particular BIOS core
+//
+#ifndef EFI_STATUS_CODE_DATA_MAX_SIZE
+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
+#endif
+
+/**
+  Output a string to the debug stream/device.
+  If there is a '%' sign in the string, convert it to '%%', so that DEBUG() macro will print it properly.
+
+  @param[in] String     - The string to output.
+
+  @retval Nothing.
+**/
+VOID
+SaDebugPrint (
+  VOID   *String
+  )
+{
+  CHAR8   Str[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  CHAR8   *InputStr;
+  CHAR8   *OutputStr;
+  UINT32  i;
+
+  InputStr = (CHAR8 *) String;
+  OutputStr = Str;
+  i = 0;
+  while (*InputStr != 0) {
+    if (i < (EFI_STATUS_CODE_DATA_MAX_SIZE - 2)) {
+      *OutputStr++ = *InputStr;
+      i++;
+      if (*InputStr++ == '%') {
+        *OutputStr++ = '%';
+        i++;
+      }
+    }
+  }
+  *OutputStr = 0;  // Terminating NULL
+  DEBUG ((DEBUG_INFO, Str));
+  return;
+}
+
+/**
+  Calculate the PCI device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+  @retval The PCI device address.
+**/
+UINT32
+GetPciDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  )
+{
+  return (
+    ((UINT32) ((Bus)      & 0xFF) << 16) |
+    ((UINT32) ((Device)   & 0x1F) << 11) |
+    ((UINT32) ((Function) & 0x07) << 8)  |
+    ((UINT32) ((Offset)   & 0xFF) << 0)  |
+    (1UL << 31));
+}
+
+/**
+  Calculate the PCIE device address for the given Bus/Device/Function/Offset.
+
+  @param[in] Bus      - PCI bus
+  @param[in] Device   - PCI device
+  @param[in] Function - PCI function
+  @param[in] Offset   - Offset
+
+   The PCIE device address.
+
+  @retval The PCIe device address
+**/
+UINT32
+GetPcieDeviceAddress (
+  IN const UINT8 Bus,
+  IN const UINT8 Device,
+  IN const UINT8 Function,
+  IN const UINT8 Offset
+  )
+{
+  return (
+    ((UINT32) Bus << 20) +
+    ((UINT32) Device << 15) +
+    ((UINT32) Function << 12) +
+    ((UINT32) Offset << 0));
+}
+
+/**
+  Read specific RTC/CMOS RAM
+
+  @param[in] Location        Point to RTC/CMOS RAM offset for read
+
+  @retval The data of specific location in RTC/CMOS RAM.
+**/
+UINT8
+PeiRtcRead (
+  IN const UINT8 Location
+  )
+{
+  UINT8  RtcIndexPort;
+  UINT8  RtcDataPort;
+
+  //
+  // CMOS access registers (using alternative access not to handle NMI bit)
+  //
+  if (Location < RTC_BANK_SIZE) {
+    //
+    // First bank
+    //
+    RtcIndexPort  = R_RTC_IO_INDEX_ALT;
+    RtcDataPort   = R_RTC_IO_TARGET_ALT;
+  } else {
+    //
+    // Second bank
+    //
+    RtcIndexPort  = R_RTC_IO_EXT_INDEX_ALT;
+    RtcDataPort   = R_RTC_IO_EXT_TARGET_ALT;
+  }
+
+  IoWrite8 (RtcIndexPort, Location & RTC_INDEX_MASK);
+  return IoRead8 (RtcDataPort);
+}
+
+/**
+  Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
+  Since RTC time is stored in BCD, convert each value to binary.
+
+  @param[out] Seconds       - The current second (0-59).
+  @param[out] Minutes       - The current minute (0-59).
+  @param[out] Hours         - The current hour (0-23).
+  @param[out] DayOfMonth    - The current day of the month (1-31).
+  @param[out] Month         - The current month (1-12).
+  @param[out] Year          - The current year (2000-2099).
+
+  @retval Nothing.
+**/
+VOID
+GetRtcTime (
+  OUT UINT8  *const Seconds,
+  OUT UINT8  *const Minutes,
+  OUT UINT8  *const Hours,
+  OUT UINT8  *const DayOfMonth,
+  OUT UINT8  *const Month,
+  OUT UINT16 *const Year
+  )
+{
+  UINT32 Timeout;
+
+  //
+  // Wait until RTC "update in progress" bit goes low.
+  //
+  Timeout = 0x0FFFFF;
+  do {
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
+    if ((IoRead8 (RTC_TARGET_REGISTER) & RTC_UPDATE_IN_PROGRESS) != RTC_UPDATE_IN_PROGRESS) {
+      break;
+    }
+  } while (--Timeout > 0);
+
+  if (0 == Timeout) {
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
+    IoWrite8 (RTC_TARGET_REGISTER, RTC_HOLD | RTC_MODE_24HOUR);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
+    IoWrite8 (RTC_TARGET_REGISTER, RTC_CLOCK_DIVIDER | RTC_RATE_SELECT);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGC);
+    IoRead8 (RTC_TARGET_REGISTER);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGD);
+    IoRead8 (RTC_TARGET_REGISTER);
+
+    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
+    IoWrite8 (RTC_TARGET_REGISTER, RTC_MODE_24HOUR);
+  }
+  //
+  // Read seconds
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_SECONDS);
+  *Seconds = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read minutes
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_MINUTES);
+  *Minutes = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read hours
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_HOURS);
+  *Hours = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read day of month
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_DAY_OF_MONTH);
+  *DayOfMonth = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read month
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_MONTH);
+  *Month = IoRead8 (RTC_TARGET_REGISTER);
+
+  //
+  // Read year and add current century.
+  //
+  IoWrite8 (RTC_INDEX_REGISTER, RTC_YEAR);
+  *Year = IoRead8 (RTC_TARGET_REGISTER);
+
+  *Seconds    = BCD2BINARY (*Seconds);
+  *Minutes    = BCD2BINARY (*Minutes);
+  *Hours      = BCD2BINARY (*Hours);
+  *DayOfMonth = BCD2BINARY (*DayOfMonth);
+  *Month      = BCD2BINARY (*Month);
+  *Year       = BCD2BINARY (*Year) + CENTURY_OFFSET;
+}
+
+/**
+  Gets CPU current time.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+
+  @retval The current CPU time in milliseconds.
+**/
+UINT64
+GetCpuTime (
+  IN VOID         *GlobalData
+  )
+{
+  MrcParameters               *MrcData;
+  MrcInput                    *Inputs;
+  PCU_CR_PLATFORM_INFO_STRUCT Msr;
+  UINT32                      TimeBase;
+
+  MrcData   = (MrcParameters *) GlobalData;
+  Inputs    = &MrcData->Inputs;
+
+  Msr.Data = AsmReadMsr64 (PCU_CR_PLATFORM_INFO);
+  TimeBase = (Inputs->BClkFrequency / 1000) * Msr.Bits.MAX_NON_TURBO_LIM_RATIO; //In Millisec
+  return ((TimeBase == 0) ? 0 : DivU64x32 (AsmReadTsc (), TimeBase));
+}
+
+/**
+  Sets the specified number of memory words, a word at a time, at the
+  specified destination.
+
+  @param[in, out] Dest     - Destination pointer.
+  @param[in]      NumWords - The number of dwords to set.
+  @param[in]      Value    - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemWord (
+  IN OUT VOID     *Dest,
+  IN UINTN        NumWords,
+  IN const UINT16 Value
+  )
+{
+  UINT16 *Buffer;
+
+  Buffer = (UINT16 *) Dest;
+  while (0 != NumWords--) {
+    *Buffer++ = Value;
+  }
+
+  return (Dest);
+}
+
+/**
+  Sets the specified number of memory dwords, a dword at a time, at the
+  specified destination.
+
+  @param[in, out] Dest      - Destination pointer.
+  @param[in]      NumDwords - The number of dwords to set.
+  @param[in]      Value     - The value to set.
+
+  @retval Pointer to the buffer.
+**/
+VOID *
+SetMemDword (
+  IN OUT VOID     *Dest,
+  IN UINT32       NumDwords,
+  IN const UINT32 Value
+  )
+{
+  UINT32 *Buffer;
+
+  Buffer = (UINT32 *) Dest;
+  while (0 != NumDwords--) {
+    *Buffer++ = Value;
+  }
+
+  return (Dest);
+}
+
+
+/**
+  Gets the current memory voltage (VDD).
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+
+  @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
+**/
+UINT32
+GetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd
+  )
+{
+  UINT32          CurrentVoltage;
+
+  CurrentVoltage = DefaultVdd;
+
+  return CurrentVoltage;
+}
+
+/**
+  Sets the memory voltage (VDD) to the specified value.
+
+  @param[in] GlobalData - Pointer to global MRC data struct.
+  @param[in] DefaultVdd - Default Vdd for the given platform.
+  @param[in] Voltage    - The new memory voltage to set.
+
+  @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
+**/
+UINT32
+SetMemoryVdd (
+  IN VOID     *GlobalData,
+  IN UINT32   DefaultVdd,
+  IN UINT32   Voltage
+  )
+{
+
+  return Voltage;
+}
+
+/**
+  This function is used by the OEM to do a dedicated task during the MRC.
+
+  @param[in] GlobalData        - include all the MRC data
+  @param[in] OemStatusCommand  - A command that indicates the task to perform.
+  @param[in] Pointer           - general ptr for general use.
+
+  @retval The status of the task.
+**/
+MrcStatus
+CheckPoint (
+  IN VOID                *GlobalData,
+  IN MrcOemStatusCommand OemStatusCommand,
+  IN VOID                *Pointer
+  )
+{
+  MrcParameters                *MrcData;
+  MrcInput                     *Inputs;
+  MrcStatus                    Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+  MEMORY_CONFIG_NO_CRC         *MemConfigNoCrc;
+  EFI_STATUS                   Status1;
+
+  //
+  // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform data
+  //
+  Status1 = PeiServicesLocatePpi (
+              &gSiPreMemPolicyPpiGuid,
+              0,
+              NULL,
+              (VOID **) &SiPreMemPolicyPpi
+              );
+  ASSERT_EFI_ERROR (Status1);
+
+  Status1 = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR (Status1);
+  MrcData             = (MrcParameters *) GlobalData;
+  Inputs              = &MrcData->Inputs;
+  SiPreMemPolicyPpi = (SI_PREMEM_POLICY_PPI *) Inputs->SiPreMemPolicyPpi;
+  Status              = mrcSuccess;
+
+  switch (OemStatusCommand) {
+    default:
+      break;
+  }
+
+  return (Status);
+}
+
+/**
+  Typically used to display to the I/O port 80h.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] DisplayDebugNumber - the number to display on port 80.
+
+  @retval Nothing.
+**/
+VOID
+DebugHook (
+  IN VOID       *GlobalData,
+  UINT16        DisplayDebugNumber
+  )
+{
+  MrcParameters                *MrcData;
+  MrcOutput                    *Outputs;
+  MrcDebug                     *Debug;
+  EFI_STATUS                   Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+  SA_MISC_PEI_PREMEM_CONFIG    *MiscPeiPreMemConfig;
+
+  MrcData = (MrcParameters *) GlobalData;
+  Outputs = &MrcData->Outputs;
+  Debug   = &Outputs->Debug;
+
+  Debug->PostCode[MRC_POST_CODE] = DisplayDebugNumber;
+  IoWrite16 (0x80, DisplayDebugNumber);
+  DEBUG ((DEBUG_INFO, "Post Code: %04Xh\n", DisplayDebugNumber));
+
+  //
+  // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform data
+  //
+  Status = PeiServicesLocatePpi (&gSiPreMemPolicyPpiGuid, 0, NULL, (VOID **) &SiPreMemPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+  if (Status == EFI_SUCCESS) {
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+    if (Status == EFI_SUCCESS) {
+      //
+      // Put the Port80 code also here:
+      // #define BIOS_POST_CODE_PCU_CNL_REG          (0x00005824)
+      //
+      MmioWrite16 (MiscPeiPreMemConfig->MchBar + 0x5824, DisplayDebugNumber);
+    }
+  }
+  return;
+}
+
+/**
+  Hook to take any action after returning from MrcStartMemoryConfiguration()
+  and prior to taking any action regarding MrcStatus.  Pre-populated with issuing
+  Intel Silicon View Technology (ISVT) checkpoint 0x10.
+
+  @param[in] GlobalData         - Mrc Global Data
+  @param[in] MrcStatus          - Mrc status variable
+**/
+void
+ReturnFromSmc (
+  IN VOID         *GlobalData,
+  IN UINT32       MrcStatus
+  )
+{
+  MrcInput        *Inputs;
+  MrcParameters   *MrcData;
+  UINT32          CheckPoint;
+  UINT32          PortReading;
+
+  MrcData   = (MrcParameters *) GlobalData;
+  Inputs    = &MrcData->Inputs;
+
+  DEBUG ((DEBUG_INFO, "Returned From MrcStartMemoryConfiguration(). MrcStatus = %08Xh\n", MrcStatus));
+
+  //
+  // Intel Silicon View Technology (ISVT) IO Reading port with EAX = 0x10 for End of MRC
+  //
+  CheckPoint = ISVT_END_OF_MRC_STATE;
+  PortReading = (UINT32) Inputs->IsvtIoPort;
+  IsvtCheckPoint (CheckPoint, PortReading);
+
+  return;
+}
+
+/**
+  Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+
+  @param[in] PciEBaseAddress  - PCI express base address.
+  @param[in] ResetValue       - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
+**/
+VOID
+SaDramReset (
+  IN UINT32 PciEBaseAddress,
+  IN UINT32 ResetValue
+  )
+{
+  PmcSetDramResetCtlState (ResetValue);
+
+  return;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
new file mode 100644
index 0000000000..2ac3543f93
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
@@ -0,0 +1,656 @@
+/** @file
+  This file provides services for PEI policy default initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyLibrary.h"
+#include <Library/GpioLib.h>
+#include <Library/CpuPlatformLib.h>
+#include "MrcInterface.h"
+#include <Library/PchInfoLib.h>
+
+#define DEFAULT_OPTION_ROM_TEMP_BAR            0x80000000
+#define DEFAULT_OPTION_ROM_TEMP_MEM_LIMIT      0xC0000000
+//
+// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
+//
+#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)    // 80MB + 256MB
+
+//
+// Function call to Load defaults for Individial IP Blocks
+//
+VOID
+LoadSaMiscPeiPreMemDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  SA_MISC_PEI_PREMEM_CONFIG            *MiscPeiPreMemConfig;
+
+  MiscPeiPreMemConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Name = %g\n", &MiscPeiPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Policy initialization commented out here is because it's the same with default 0 and no need to re-do again.
+  //
+  MiscPeiPreMemConfig->LockPTMregs                      = 1;
+
+  //
+  // Initialize the Platform Configuration
+  //
+  MiscPeiPreMemConfig->MchBar              = 0xFED10000;
+  MiscPeiPreMemConfig->DmiBar              = 0xFED18000;
+  MiscPeiPreMemConfig->EpBar               = 0xFED19000;
+  MiscPeiPreMemConfig->EdramBar            = 0xFED80000;
+  MiscPeiPreMemConfig->SmbusBar            = 0xEFA0;
+  MiscPeiPreMemConfig->TsegSize            = PcdGet32 (PcdTsegSize);
+  MiscPeiPreMemConfig->GdxcBar             = 0xFED84000;
+
+  //
+  // Initialize the Switchable Graphics Default Configuration
+  //
+  MiscPeiPreMemConfig->SgDelayAfterHoldReset = 100; //100ms
+  MiscPeiPreMemConfig->SgDelayAfterPwrEn     = 300; //300ms
+
+  ///
+  /// Initialize the DataPtr for S3 resume
+  ///
+  MiscPeiPreMemConfig->S3DataPtr = NULL;
+  MiscPeiPreMemConfig->OpRomScanTempMmioBar      = DEFAULT_OPTION_ROM_TEMP_BAR;
+  MiscPeiPreMemConfig->OpRomScanTempMmioLimit    = DEFAULT_OPTION_ROM_TEMP_MEM_LIMIT;
+}
+
+VOID
+LoadSaMiscPeiDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  SA_MISC_PEI_CONFIG        *MiscPeiConfig;
+
+  MiscPeiConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "MiscPeiConfig->Header.GuidHob.Name = %g\n", &MiscPeiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MiscPeiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MiscPeiConfig->Header.GuidHob.Header.HobLength));
+
+  ///
+  /// EDRAM H/W Mode by default (0- EDRAM SW Disable, 1- EDRAM SW Enable, 2- EDRAM HW Mode)
+  ///
+  MiscPeiConfig->EdramTestMode = 2;
+
+  if (IsWhlCpu()) {
+    MiscPeiConfig->Device4Enable = 1;
+  }
+}
+
+VOID
+LoadVtdDefault (
+  IN VOID   *ConfigBlockPointer
+  )
+{
+  VTD_CONFIG   *Vtd;
+
+  Vtd = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Name = %g\n", &Vtd->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Header.HobLength = 0x%x\n", Vtd->Header.GuidHob.Header.HobLength));
+
+  //
+  // Initialize the Vtd Configuration
+  //
+  Vtd->VtdDisable      = 0;
+  Vtd->BaseAddress[0]  = 0xFED90000;
+  Vtd->BaseAddress[1]  = 0xFED92000;
+  Vtd->BaseAddress[2]  = 0xFED91000;
+}
+
+VOID
+LoadIpuPreMemDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  IPU_PREMEM_CONFIG      *IpuPreMemPolicy;
+
+  IpuPreMemPolicy = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "IpuPreMemPolicy->Header.GuidHob.Name = %g\n", &IpuPreMemPolicy->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "IpuPreMemPolicy->Header.GuidHob.Header.HobLength = 0x%x\n", IpuPreMemPolicy->Header.GuidHob.Header.HobLength));
+
+}
+
+VOID
+LoadPciePeiPreMemDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  UINT8                  Index;
+  PCIE_PEI_PREMEM_CONFIG *PciePeiPreMemConfig;
+
+  PciePeiPreMemConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "PciePeiPreMemConfig->Header.GuidHob.Name = %g\n", &PciePeiPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PciePeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PciePeiPreMemConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Initialize the PciExpress Configuration
+  //
+  PciePeiPreMemConfig->DmiGen3EqPh2Enable             = 2;
+  PciePeiPreMemConfig->DmiGen3ProgramStaticEq         = 1;
+  PciePeiPreMemConfig->Peg0Enable                     = 2;
+  PciePeiPreMemConfig->Peg1Enable                     = 2;
+  PciePeiPreMemConfig->Peg2Enable                     = 2;
+  PciePeiPreMemConfig->Peg3Enable                     = 2;
+  PciePeiPreMemConfig->Peg0PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg1PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg2PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg3PowerDownUnusedLanes       = 1;
+  PciePeiPreMemConfig->Peg0Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->Peg1Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->Peg2Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->Peg3Gen3EqPh2Enable            = 2;
+  PciePeiPreMemConfig->PegGen3ProgramStaticEq         = 1;
+  PciePeiPreMemConfig->Gen3SwEqNumberOfPresets        = 2;
+  PciePeiPreMemConfig->Gen3SwEqEnableVocTest          = 2;
+
+  if (IsCnlPch() && IsPchH() && (PchStepping() == PCH_A0)) {
+    PciePeiPreMemConfig->DmiMaxLinkSpeed = 1;
+  }
+
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    PciePeiPreMemConfig->DmiGen3RootPortPreset[Index] = 4;
+    PciePeiPreMemConfig->DmiGen3EndPointPreset[Index] = 7;
+    PciePeiPreMemConfig->DmiGen3EndPointHint[Index]   = 2;
+  }
+  for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
+    ///
+    /// Gen3 RxCTLE peaking default is 0 for DMI
+    ///
+    PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index]  = 0;
+  }
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    PciePeiPreMemConfig->PegGen3RootPortPreset[Index] = 7;
+    PciePeiPreMemConfig->PegGen3EndPointPreset[Index] = 7;
+    PciePeiPreMemConfig->PegGen3EndPointHint[Index]   = 2;
+  }
+  PciePeiPreMemConfig->DmiDeEmphasis = 1;
+  ///
+  /// Gen3 Software Equalization Jitter Dwell Time:               1 msec
+  /// Gen3 Software Equalization Jitter Error Target:             1
+  /// Gen3 Software Equalization VOC    Dwell Time:               10 msec
+  /// Gen3 Software Equalization VOC    Error Target:             2
+  ///
+  PciePeiPreMemConfig->Gen3SwEqJitterDwellTime        = 3 * STALL_ONE_MILLI_SECOND;
+  PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget      = 2;
+  PciePeiPreMemConfig->Gen3SwEqVocDwellTime           = 10 * STALL_ONE_MILLI_SECOND;
+  PciePeiPreMemConfig->Gen3SwEqVocErrorTarget         = 2;
+
+  /**
+  Parameters for PCIe Gen3 device reset
+  @note Refer to the Platform Design Guide (PDG) for additional information about this GPIO.
+  **/
+  PciePeiPreMemConfig->PegGpioData.GpioSupport        = FALSE;
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad = 0;
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active  = FALSE;
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad = 0;
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active  = FALSE;
+}
+
+VOID
+LoadPciePeiDefault (
+  IN   VOID          *ConfigBlockPointer
+  )
+{
+  UINT8                Index;
+  PCIE_PEI_CONFIG      *PciePeiConfig;
+
+  PciePeiConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "PciePeiConfig->Header.GuidHob.Name = %g\n", &PciePeiConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PciePeiConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PciePeiConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Initialize the PciExpress Configuration
+  //
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PciePeiConfig->PegDeEmphasis[Index] = 1;
+    PciePeiConfig->PegMaxPayload[Index] = 0xFF;
+  }
+  ///
+  /// Slot Power Limit Value:   75 W
+  /// Slot Power Limit Scale:   1.0x
+  /// Physical Slot Number:     Peg Index + 1 (1,2,3)
+  ///
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PciePeiConfig->PegSlotPowerLimitValue[Index] = 75;
+    PciePeiConfig->PegPhysicalSlotNumber[Index] =  Index + 1;
+  }
+
+}
+
+VOID
+LoadGraphichsPeiPreMemDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  GRAPHICS_PEI_PREMEM_CONFIG                         *GtPreMemConfig;
+
+  GtPreMemConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GtPreMemConfig->Header.GuidHob.Name = %g\n", &GtPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GtPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GtPreMemConfig->Header.GuidHob.Header.HobLength));
+
+  ///
+  /// Initialize Graphics Pre-Mem Configurations.
+  ///
+  GtPreMemConfig->GmAdr               = 0xD0000000;
+  GtPreMemConfig->GttMmAdr            = 0xCF000000;
+  GtPreMemConfig->GttSize             = 3;
+  GtPreMemConfig->IgdDvmt50PreAlloc   = 1;
+  GtPreMemConfig->InternalGraphics    = 2;
+  GtPreMemConfig->PrimaryDisplay      = 3;
+  GtPreMemConfig->ApertureSize        = SA_GT_APERTURE_SIZE_256MB;
+  GtPreMemConfig->PanelPowerEnable    = 1;
+}
+
+VOID
+LoadGraphichsPeiDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  GRAPHICS_PEI_CONFIG                         *GtConfig;
+
+  GtConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Name = %g\n", &GtConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GtConfig->Header.GuidHob.Header.HobLength));
+
+  //
+  // Initialize the Graphics configuration
+  //
+  GtConfig->RenderStandby       = 1;
+  GtConfig->PavpEnable          = 1;
+  GtConfig->PmSupport           = 1;
+  GtConfig->CdynmaxClampEnable  = 1;
+  GtConfig->GtFreqMax           = 0xFF;
+  //
+  // Initialize the default VBT settings
+  //
+  GtConfig->DdiConfiguration.DdiPortEdp  = 1;
+  GtConfig->DdiConfiguration.DdiPortBHpd = 1;
+  GtConfig->DdiConfiguration.DdiPortCHpd = 1;
+  GtConfig->DdiConfiguration.DdiPortDHpd = 1;
+  GtConfig->DdiConfiguration.DdiPortFHpd = 0;
+  GtConfig->DdiConfiguration.DdiPortBDdc = 1;
+  GtConfig->DdiConfiguration.DdiPortCDdc = 1;
+  GtConfig->DdiConfiguration.DdiPortDDdc = 1;
+  GtConfig->DdiConfiguration.DdiPortFDdc = 0;
+
+  ///
+  /// Initialize the CdClock to 675 Mhz
+  ///
+  GtConfig->CdClock             = 3;
+}
+
+VOID
+LoadSwitchableGraphichsDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  SWITCHABLE_GRAPHICS_CONFIG        *SgConfig;
+  SgConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "SgConfig->Header.GuidHob.Name = %g\n", &SgConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "SgConfig->Header.GuidHob.Header.HobLength = 0x%x\n", SgConfig->Header.GuidHob.Header.HobLength));
+  SgConfig->SaRtd3Pcie0Gpio.GpioSupport    = NotSupported;
+  SgConfig->SaRtd3Pcie1Gpio.GpioSupport    = NotSupported;
+  SgConfig->SaRtd3Pcie2Gpio.GpioSupport    = NotSupported;
+}
+
+VOID
+LoadMemConfigNoCrcDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+
+  MEMORY_CONFIG_NO_CRC                    *MemConfigNoCrc;
+
+  MemConfigNoCrc = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Name = %g\n", &MemConfigNoCrc->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Header.HobLength = 0x%x\n", MemConfigNoCrc->Header.GuidHob.Header.HobLength));
+  //
+  // Allocating memory space for pointer structures inside MemConfigNoCrc
+  //
+  MemConfigNoCrc->SpdData = (SPD_DATA_BUFFER *) AllocateZeroPool (sizeof (SPD_DATA_BUFFER));
+  ASSERT (MemConfigNoCrc->SpdData != NULL);
+  if (MemConfigNoCrc->SpdData == NULL) {
+    return;
+  }
+
+  MemConfigNoCrc->DqByteMap = (SA_MEMORY_DQ_MAPPING *) AllocateZeroPool (sizeof (SA_MEMORY_DQ_MAPPING));
+  ASSERT (MemConfigNoCrc->DqByteMap != NULL);
+  if (MemConfigNoCrc->DqByteMap == NULL) {
+    return;
+  }
+
+  MemConfigNoCrc->DqsMap = (SA_MEMORY_DQS_MAPPING *) AllocateZeroPool (sizeof (SA_MEMORY_DQS_MAPPING));
+  ASSERT (MemConfigNoCrc->DqsMap != NULL);
+  if (MemConfigNoCrc->DqsMap == NULL) {
+    return;
+  }
+
+  MemConfigNoCrc->RcompData = (SA_MEMORY_RCOMP *) AllocateZeroPool (sizeof (SA_MEMORY_RCOMP));
+  ASSERT (MemConfigNoCrc->RcompData != NULL);
+  if (MemConfigNoCrc->RcompData == NULL) {
+    return;
+  }
+
+  //
+  // Set PlatformMemory Size
+  //
+
+  MemConfigNoCrc->PlatformMemorySize = PEI_MIN_MEMORY_SIZE;
+
+  MemConfigNoCrc->SerialDebugLevel  = 3;  //< Enable MRC debug message
+
+  MemConfigNoCrc->MemTestOnWarmBoot = 1;  //< Enable to run BaseMemoryTest on warm boot by default
+
+}
+
+VOID
+LoadGnaDefault (
+  IN VOID *ConfigBlockPointer
+  )
+{
+  GNA_CONFIG                        *GnaConfig;
+  GnaConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GnaConfig->Header.GuidHob.Name = %g\n", &GnaConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GnaConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GnaConfig->Header.GuidHob.Header.HobLength));
+  GnaConfig->GnaEnable    = TRUE;
+}
+
+VOID
+LoadMemConfigDefault (
+  IN VOID *ConfigBlockPointer
+  )
+{
+  MEMORY_CONFIGURATION                    *MemConfig;
+  CPU_FAMILY                              CpuFamily;
+  UINT16                                  DeviceId;
+
+  CPU_SKU                                 CpuSku;
+  CpuSku = GetCpuSku ();
+  CpuFamily   = GetCpuFamily ();
+  DeviceId    = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_DEVICE_ID));
+
+  MemConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Name = %g\n", &MemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
+  //
+  // Initialize the Memory Configuration
+  //
+  MemConfig->EnBER              = 1;
+  MemConfig->EccSupport         = 1;
+  MemConfig->ScramblerSupport   = 1;
+  MemConfig->PowerDownMode      = 0xFF;
+  MemConfig->RankInterleave     = TRUE;
+  MemConfig->EnhancedInterleave = TRUE;
+  MemConfig->EnCmdRate          = 3;
+  MemConfig->AutoSelfRefreshSupport = TRUE;
+  MemConfig->ExtTemperatureSupport  = TRUE;
+  MemConfig->WeaklockEn = 1;
+  MemConfig->Ddr4MixedUDimm2DpcLimit = 1;
+
+  MemConfig->DualDimmPerChannelBoardType = (CpuFamily == EnumCpuCflDtHalo) ? TRUE : FALSE;
+
+  //
+  // Channel Hash Configuration
+  //
+  MemConfig->ChHashEnable         = TRUE;
+  MemConfig->ChHashMask           = 0;
+  MemConfig->ChHashInterleaveBit  = 2;
+  MemConfig->PerBankRefresh       = TRUE;
+  //
+  // Options for Thermal settings
+  //
+  MemConfig->EnablePwrDn            = 1;
+  MemConfig->EnablePwrDnLpddr       = 1;
+  MemConfig->DdrThermalSensor       = 1;
+
+  MemConfig->EnergyScaleFact        = 4;
+  MemConfig->IdleEnergyCh0Dimm0     = 0xA;
+  MemConfig->IdleEnergyCh0Dimm1     = 0xA;
+  MemConfig->IdleEnergyCh1Dimm0     = 0xA;
+  MemConfig->IdleEnergyCh1Dimm1     = 0xA;
+  MemConfig->PdEnergyCh0Dimm0       = 0x6;
+  MemConfig->PdEnergyCh0Dimm1       = 0x6;
+  MemConfig->PdEnergyCh1Dimm0       = 0x6;
+  MemConfig->PdEnergyCh1Dimm1       = 0x6;
+  MemConfig->ActEnergyCh0Dimm0      = 0xAC;
+  MemConfig->ActEnergyCh0Dimm1      = 0xAC;
+  MemConfig->ActEnergyCh1Dimm0      = 0xAC;
+  MemConfig->ActEnergyCh1Dimm1      = 0xAC;
+  MemConfig->RdEnergyCh0Dimm0       = 0xD4;
+  MemConfig->RdEnergyCh0Dimm1       = 0xD4;
+  MemConfig->RdEnergyCh1Dimm0       = 0xD4;
+  MemConfig->RdEnergyCh1Dimm1       = 0xD4;
+  MemConfig->WrEnergyCh0Dimm0       = 0xDD;
+  MemConfig->WrEnergyCh0Dimm1       = 0xDD;
+  MemConfig->WrEnergyCh1Dimm0       = 0xDD;
+  MemConfig->WrEnergyCh1Dimm1       = 0xDD;
+  MemConfig->WarmThresholdCh0Dimm0  = 0xFF;
+  MemConfig->WarmThresholdCh0Dimm1  = 0xFF;
+  MemConfig->WarmThresholdCh1Dimm0  = 0xFF;
+  MemConfig->WarmThresholdCh1Dimm1  = 0xFF;
+  MemConfig->HotThresholdCh0Dimm0   = 0xFF;
+  MemConfig->HotThresholdCh0Dimm1   = 0xFF;
+  MemConfig->HotThresholdCh1Dimm0   = 0xFF;
+  MemConfig->HotThresholdCh1Dimm1   = 0xFF;
+  MemConfig->WarmBudgetCh0Dimm0     = 0xFF;
+  MemConfig->WarmBudgetCh0Dimm1     = 0xFF;
+  MemConfig->WarmBudgetCh1Dimm0     = 0xFF;
+  MemConfig->WarmBudgetCh1Dimm1     = 0xFF;
+  MemConfig->HotBudgetCh0Dimm0      = 0xFF;
+  MemConfig->HotBudgetCh0Dimm1      = 0xFF;
+  MemConfig->HotBudgetCh1Dimm0      = 0xFF;
+  MemConfig->HotBudgetCh1Dimm1      = 0xFF;
+
+  MemConfig->SrefCfgEna             = 1;
+  MemConfig->SrefCfgIdleTmr         = 0x200;
+  MemConfig->ThrtCkeMinTmr          = 0x30;
+  MemConfig->ThrtCkeMinDefeatLpddr  = 1;
+  MemConfig->ThrtCkeMinTmrLpddr     = 0x40;
+
+  MemConfig->RaplLim2WindX = 1;
+  MemConfig->RaplLim2WindY = 1;
+  MemConfig->RaplLim2Pwr   = 0xDE;
+
+  //
+  // CA Vref routing: board-dependent
+  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
+  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
+  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
+  //
+  //MemConfig->CaVrefConfig = 0;
+  MemConfig->VttTermination     = ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt));
+  MemConfig->VttCompForVsshi    = 0;
+
+#ifdef UP_SERVER_FLAG
+  MemConfig->TsodTcritmax = 0x69;
+  MemConfig->TsodThigMax  = 0x5D;
+#endif
+
+
+  //
+  // MRC training steps
+  //
+  MemConfig->ECT                  = 1;
+  MemConfig->ERDMPRTC2D           = 1;
+  MemConfig->SOT                  = 1;
+  MemConfig->RDMPRT               = 1;
+  MemConfig->RCVET                = 1;
+  MemConfig->JWRL                 = 1;
+  MemConfig->EWRTC2D              = 1;
+  MemConfig->ERDTC2D              = 1;
+  MemConfig->WRTC1D               = 1;
+  MemConfig->WRVC1D               = 1;
+  MemConfig->RDTC1D               = 1;
+  MemConfig->DIMMODTT             = 1;
+  MemConfig->DIMMRONT             = 1;
+  MemConfig->WRSRT                = 1;
+  MemConfig->RDODTT               = 1;
+  MemConfig->RDAPT                = 1;
+  MemConfig->WRTC2D               = 1;
+  MemConfig->RDTC2D               = 1;
+  MemConfig->CMDVC                = 1;
+  MemConfig->WRVC2D               = 1;
+  MemConfig->RDVC2D               = 1;
+  MemConfig->LCT                  = 1;
+  MemConfig->RTL                  = 1;
+  MemConfig->TAT                  = 1;
+  MemConfig->ALIASCHK             = 1;
+  MemConfig->RCVENC1D             = 1;
+  MemConfig->RMC                  = 1;
+  MemConfig->CMDSR                = 1;
+  MemConfig->CMDDSEQ              = 1;
+  MemConfig->CMDNORM              = 1;
+  MemConfig->EWRDSEQ              = 1;
+  MemConfig->McLock               = TRUE;
+  MemConfig->GdxcIotSize          = 4;
+  MemConfig->GdxcMotSize          = 12;
+  MemConfig->RDEQT                = 1;
+
+  MemConfig->MrcFastBoot          = TRUE;
+  MemConfig->MrcTrainOnWarm       = FALSE;
+  MemConfig->RemapEnable          = TRUE;
+  MemConfig->BClkFrequency        = 100 * 1000 * 1000;
+
+#ifdef EMBEDDED_FLAG
+  MemConfig->Force1Dpc = TRUE;
+#endif
+  MemConfig->Vc1ReadMeter           = TRUE;
+  MemConfig->Vc1ReadMeterTimeWindow = 0x320;
+  MemConfig->Vc1ReadMeterThreshold  = 0x118;
+  MemConfig->StrongWkLeaker         = 7;
+
+  MemConfig->MobilePlatform     = (IS_SA_DEVICE_ID_MOBILE (DeviceId)) ? TRUE : FALSE;
+  MemConfig->PciIndex           = 0xCF8;
+  MemConfig->PciData            = 0xCFC;
+  MemConfig->CkeRankMapping     = 0xAA;
+
+  // This only affects ULX/ULT; otherwise SA GV is disabled.
+  // CFL SA GV: 0 - Disabled, 1 - FixedLow, 2 - FixedHigh, 3 - Enabled
+  MemConfig->SaGv             = 3;
+  MemConfig->SimicsFlag       = 0;
+
+  MemConfig->Idd3n              = 26;
+  MemConfig->Idd3p              = 11;
+
+  MemConfig->RhPrevention       = TRUE;         // Row Hammer prevention.
+  MemConfig->RhSolution         = HardwareRhp;  // Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  MemConfig->RhActProbability   = OneIn2To11;    // Activation probability for Hardware RHP
+
+  MemConfig->LpddrMemWriteLatencySet = 1;  // Enable LPDDR3 WL Set B if supported by DRAM
+
+  MemConfig->DllBwEn1 = 1;
+  MemConfig->DllBwEn2 = 2;
+  MemConfig->DllBwEn3 = 2;
+
+  MemConfig->RetrainOnFastFail  = 1; //  Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, 1 = Enabled
+  MemConfig->Lp4DqsOscEn        = 1;
+  MemConfig->IsvtIoPort         = 0x99;
+}
+
+
+VOID
+LoadOverClockConfigDefault (
+  IN VOID   *ConfigBlockPointer
+  )
+{
+  OVERCLOCKING_PREMEM_CONFIG    *OcPreMemConfig;
+  OcPreMemConfig = (OVERCLOCKING_PREMEM_CONFIG *)ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "OcPreMemConfig->Header.GuidHob.Name = %g\n", &OcPreMemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "OcPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", OcPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY  mSaIpBlocksPreMem [] = {
+  {&gSaMiscPeiPreMemConfigGuid,       sizeof (SA_MISC_PEI_PREMEM_CONFIG),  SA_MISC_PEI_PREMEM_CONFIG_REVISION,  LoadSaMiscPeiPreMemDefault},
+  {&gSaPciePeiPreMemConfigGuid,       sizeof (PCIE_PEI_PREMEM_CONFIG),     SA_PCIE_PEI_PREMEM_CONFIG_REVISION,  LoadPciePeiPreMemDefault},
+  {&gGraphicsPeiPreMemConfigGuid,     sizeof (GRAPHICS_PEI_PREMEM_CONFIG), GRAPHICS_PEI_PREMEM_CONFIG_REVISION, LoadGraphichsPeiPreMemDefault},
+  {&gSwitchableGraphicsConfigGuid,    sizeof (SWITCHABLE_GRAPHICS_CONFIG), SWITCHABLE_GRAPHICS_CONFIG_REVISION, LoadSwitchableGraphichsDefault},
+  {&gMemoryConfigGuid,                sizeof (MEMORY_CONFIGURATION),       MEMORY_CONFIG_REVISION,              LoadMemConfigDefault},
+  {&gMemoryConfigNoCrcGuid,           sizeof (MEMORY_CONFIG_NO_CRC),       MEMORY_CONFIG_REVISION,              LoadMemConfigNoCrcDefault},
+  {&gSaOverclockingPreMemConfigGuid,  sizeof (OVERCLOCKING_PREMEM_CONFIG), SA_OVERCLOCKING_CONFIG_REVISION,     LoadOverClockConfigDefault},
+  {&gVtdConfigGuid,                   sizeof (VTD_CONFIG),                 VTD_CONFIG_REVISION,                 LoadVtdDefault},
+  {&gIpuPreMemConfigGuid,             sizeof (IPU_PREMEM_CONFIG),          IPU_PREMEM_CONFIG_REVISION,          LoadIpuPreMemDefault}
+};
+
+static COMPONENT_BLOCK_ENTRY  mSaIpBlocks [] = {
+  {&gSaMiscPeiConfigGuid,       sizeof (SA_MISC_PEI_CONFIG),   SA_MISC_PEI_CONFIG_REVISION,      LoadSaMiscPeiDefault},
+  {&gSaPciePeiConfigGuid,       sizeof (PCIE_PEI_CONFIG),      SA_PCIE_PEI_CONFIG_REVISION,      LoadPciePeiDefault},
+  {&gGraphicsPeiConfigGuid,     sizeof (GRAPHICS_PEI_CONFIG),  GRAPHICS_PEI_CONFIG_REVISION,     LoadGraphichsPeiDefault},
+  {&gGnaConfigGuid,             sizeof (GNA_CONFIG),           GNA_CONFIG_REVISION,              LoadGnaDefault}
+};
+
+/**
+  Get SA config block table total size.
+
+  @retval     Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  Get SA config block table total size.
+
+  @retval      Size of SA config block table
+**/
+UINT16
+EFIAPI
+SaGetConfigBlockTotalSizePreMem (
+  VOID
+  )
+{
+  return GetComponentConfigBlockTotalSize (&mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+  SaAddConfigBlocksPreMem add all SA config blocks.
+
+  @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
+SaAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n",  sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY)));
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+  if (Status == EFI_SUCCESS) {
+    SaLoadSamplePolicyPreMem (ConfigBlockTableAddress);
+  }
+  return Status;
+}
+
+/**
+  SaAddConfigBlocks add all SA config blocks.
+
+  @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
+SaAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n",  sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
+
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
new file mode 100644
index 0000000000..463e75702d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
@@ -0,0 +1,284 @@
+/** @file
+  This file provides services for Sample PEI policy default initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <SaPolicyCommon.h>
+#include "PeiSaPolicyLibrary.h"
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "MrcOemPlatform.h"
+#include <Library/GpioLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/RngLib.h>
+#include <Library/CpuMailboxLib.h>
+
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapSkl[2][6][2] = {
+  // Channel 0:
+  {
+    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  },
+  // Channel 1:
+  {
+    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  }
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqsMapCpu2DramSklRvp[2][8] = {
+  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
+  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
+};
+
+//
+// Reference RCOMP resistors on motherboard
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 mRcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 mRcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
+
+/**
+  Hynix H9CCNNN8JTMLAR-NTM_178b_DDP LPDDR3, 4Gb die (128Mx32), x32
+  or Elpida  EDF8132A1MC-GD-F
+  or Samsung K4E8E304EB-EGCE
+  1600, 12-15-15-34
+  2 rank per channel, 2 SDRAMs per rank, 4x4Gb = 2GB total per channel
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSkylakeRvp3Spd[] = {
+  0x24,                                 ///< 0   Number of Serial PD Bytes Written / SPD Device Size
+  0x20,                                 ///< 1   SPD Revision
+  0x0F,                                 ///< 2   DRAM Device Type
+  0x0E,                                 ///< 3   Module Type
+  0x14,                                 ///< 4   SDRAM Density and Banks: 8 Banks, 4 Gb SDRAM density
+  0x11,                                 ///< 5   SDRAM Addressing: 14 Rows, 10 Columns
+  0x90,                                 ///< 6   SDRAM Package Type: Non-Monolithic, DDP, 1 Channel per package
+  0x00,                                 ///< 7   SDRAM Optional Features
+  0x00,                                 ///< 8   SDRAM Thermal and Refresh Options
+  0x00,                                 ///< 9   Other SDRAM Optional Features
+  0x00,                                 ///< 10  Reserved - must be coded as 0x00
+  0x03,                                 ///< 11  Module Nominal Voltage, VDD
+  0x0B,                                 ///< 12  Module Organization, SDRAM width: 32 bits, 2 Ranks
+  0x03,                                 ///< 13  Module Memory Bus Width: 1 Channel, 64 bits channel width
+  0x00,                                 ///< 14  Module Thermal Sensor
+  0x00,                                 ///< 15  Extended Module Type
+  0x00,                                 ///< 16  Reserved - must be coded as 0x00
+  0x00,                                 ///< 17  Timebases
+  0x0A,                                 ///< 18  SDRAM Minimum Cycle Time (tCKmin)
+  0xFF,                                 ///< 19  SDRAM Minimum Cycle Time (tCKmax)
+  0x54,                                 ///< 20  CAS Latencies Supported, First Byte (tCk): 12 10 8
+  0x00,                                 ///< 21  CAS Latencies Supported, Second Byte
+  0x00,                                 ///< 22  CAS Latencies Supported, Third Byte
+  0x00,                                 ///< 23  CAS Latencies Supported, Fourth Byte
+  0x78,                                 ///< 24  Minimum CAS Latency Time (tAAmin)
+  0x00,                                 ///< 25  Read and Write Latency Set Options
+  0x90,                                 ///< 26  Minimum RAS# to CAS# Delay Time (tRCDmin)
+  0xA8,                                 ///< 27  Minimum Row Precharge Delay Time for all banks (tRPab)
+  0x90,                                 ///< 28  Minimum Row Precharge Delay Time per bank (tRPpb)
+  0x10,                                 ///< 29  Minimum Refresh Recovery Delay Time for all banks (tRFCab), Least Significant Byte
+  0x04,                                 ///< 30  Minimum Refresh Recovery Delay Time for all banks (tRFCab), Most Significant Byte
+  0xE0,                                 ///< 31  Minimum Refresh Recovery Delay Time for per bank (tRFCpb), Least Significant Byte
+  0x01,                                 ///< 32  Minimum Refresh Recovery Delay Time for per bank (tRFCpb), Most Significant Byte
+  0, 0, 0, 0, 0, 0, 0,                  ///< 33 - 39
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 40 - 49
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 50 - 59
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 60 - 69 Connector to SDRAM Bit Mapping
+  0, 0, 0, 0, 0, 0, 0, 0,               ///< 70 - 77 Connector to SDRAM Bit Mapping
+  0, 0,                                 ///< 78 - 79
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 80 - 89
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 90 - 99
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 100 - 109
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 110 - 119
+  0x00,                                 ///< 120 Fine Offset for Minimum Row Precharge Delay Time per bank (tRPpb)
+  0x00,                                 ///< 121 Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+  0x00,                                 ///< 122 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  0x00,                                 ///< 123 Fine Offset for Minimum CAS Latency Time (tAAmin)
+  0x7F,                                 ///< 124 Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+  0x00,                                 ///< 125 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  0x00,                                 ///< 126 CRC A
+  0x00,                                 ///< 127 CRC B
+  0, 0,                                 ///< 128 - 129
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 130 - 139
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 140 - 149
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 150 - 159
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 160 - 169
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 170 - 179
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 180 - 189
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 190 - 199
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 200 - 209
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 210 - 219
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 220 - 229
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 230 - 239
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 240 - 249
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 250 - 259
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 260 - 269
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 270 - 279
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 280 - 289
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 290 - 299
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 300 - 309
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 310 - 319
+  0x00,                                 ///< 320 Module Manufacturer ID Code, Least Significant Byte
+  0x00,                                 ///< 321 Module Manufacturer ID Code, Most Significant Byte
+  0x00,                                 ///< 322 Module Manufacturing Location
+  0x00,                                 ///< 323 Module Manufacturing Date Year
+  0x00,                                 ///< 324 Module Manufacturing Date Week
+  0x55,                                 ///< 325 Module Serial Number A
+  0x00,                                 ///< 326 Module Serial Number B
+  0x00,                                 ///< 327 Module Serial Number C
+  0x00,                                 ///< 328 Module Serial Number D
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 329 - 333 Module Part Number: Unused bytes coded as ASCII Blanks (0x20)
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 334 - 338 Module Part Number
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 339 - 343 Module Part Number
+  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 344 - 348 Module Part Number
+  0x00,                                 ///< 349 Module Revision Code
+  0x00,                                 ///< 350 DRAM Manufacturer ID Code, Least Significant Byte
+  0x00,                                 ///< 351 DRAM Manufacturer ID Code, Most Significant Byte
+  0x00,                                 ///< 352 DRAM Stepping
+  0, 0, 0, 0, 0, 0, 0,                  ///< 353 - 359
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 360 - 369
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 370 - 379
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 380 - 389
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 390 - 399
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 400 - 409
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 410 - 419
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 420 - 429
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 430 - 439
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 440 - 449
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 450 - 459
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 460 - 469
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 470 - 479
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 480 - 489
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 490 - 499
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 500 - 509
+  0, 0                                  ///< 510 - 511
+};
+
+#define SaIoRead8    IoRead8
+#define SaIoRead16   IoRead16
+#define SaIoRead32   IoRead32
+#define SaIoWrite8   IoWrite8
+#define SaIoWrite16  IoWrite16
+#define SaIoWrite32  IoWrite32
+#define SaCopyMem    CopyMem
+#define SaSetMem     SetMem
+#define SaLShiftU64  LShiftU64
+#define SaRShiftU64  RShiftU64
+#define SaMultU64x32 MultU64x32
+
+/**
+  SaLoadSamplePolicyPreMem - Load some policy default for reference board.
+
+  @param[in] ConfigBlockTableAddress    The pointer for SA config blocks
+
+**/
+VOID
+SaLoadSamplePolicyPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  SA_FUNCTION_CALLS     *MemCall;
+  EFI_STATUS            Status;
+  MEMORY_CONFIG_NO_CRC  *MemConfigNoCrc;
+  CPU_FAMILY            CpuFamilyId;
+  UINT8                 *DqByteMap;
+  BOOLEAN               KblCpu;
+
+  MemConfigNoCrc = NULL;
+  Status = GetConfigBlock (ConfigBlockTableAddress, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR (Status);
+
+  if (MemConfigNoCrc == NULL) {
+    return;
+  }
+  CpuFamilyId = GetCpuFamily ();
+  KblCpu = ((CpuFamilyId == EnumCpuCflUltUlx) || (CpuFamilyId == EnumCpuCflDtHalo));
+
+  DEBUG ((DEBUG_INFO, "Applying Sample policy defaults for RVP3\n"));
+  MemCall                       = &MemConfigNoCrc->SaCall;
+  MemCall->IoRead8              = &SaIoRead8;
+  MemCall->IoRead16             = &SaIoRead16;
+  MemCall->IoRead32             = &SaIoRead32;
+  MemCall->IoWrite8             = &SaIoWrite8;
+  MemCall->IoWrite16            = &SaIoWrite16;
+  MemCall->IoWrite32            = &SaIoWrite32;
+  MemCall->MmioRead8            = &MmioRead8;
+  MemCall->MmioRead16           = &MmioRead16;
+  MemCall->MmioRead32           = &MmioRead32;
+  MemCall->MmioRead64           = &SaMmioRead64;
+  MemCall->MmioWrite8           = &MmioWrite8;
+  MemCall->MmioWrite16          = &MmioWrite16;
+  MemCall->MmioWrite32          = &MmioWrite32;
+  MemCall->MmioWrite64          = &SaMmioWrite64;
+  MemCall->SmbusRead8           = &SmBusReadDataByte;
+  MemCall->SmbusRead16          = &SmBusReadDataWord;
+  MemCall->SmbusWrite8          = &SmBusWriteDataByte;
+  MemCall->SmbusWrite16         = &SmBusWriteDataWord;
+  MemCall->GetPciDeviceAddress  = &GetPciDeviceAddress;
+  MemCall->GetPcieDeviceAddress = &GetPcieDeviceAddress;
+  MemCall->GetRtcTime           = &GetRtcTime;
+  MemCall->GetCpuTime           = &GetCpuTime;
+  MemCall->CopyMem              = &SaCopyMem;
+  MemCall->SetMem               = &SaSetMem;
+  MemCall->SetMemWord           = &SetMemWord;
+  MemCall->SetMemDword          = &SetMemDword;
+  MemCall->LeftShift64          = &SaLShiftU64;
+  MemCall->RightShift64         = &SaRShiftU64;
+  MemCall->MultU64x32           = &SaMultU64x32;
+  MemCall->DivU64x64            = &DivU64x64Remainder;
+  MemCall->GetSpdData           = &GetSpdData;
+  MemCall->GetRandomNumber      = &GetRandomNumber32;
+  MemCall->CpuMailboxRead       = &MailboxRead;
+  MemCall->CpuMailboxWrite      = &MailboxWrite;
+  MemCall->GetMemoryVdd         = &GetMemoryVdd;
+  MemCall->SetMemoryVdd         = &SetMemoryVdd;
+  MemCall->CheckPoint           = &CheckPoint;
+  MemCall->DebugHook            = &DebugHook;
+  MemCall->DebugPrint           = &SaDebugPrint;
+  MemCall->GetRtcCmos           = &PeiRtcRead;
+  MemCall->ReadMsr64            = &AsmReadMsr64;
+  MemCall->WriteMsr64           = &AsmWriteMsr64;
+  MemCall->MrcReturnFromSmc     = &ReturnFromSmc;
+  MemCall->MrcDramReset         = &SaDramReset;
+
+  //
+  // RCOMP resistors and target values: board-dependent
+  //
+  if (KblCpu) {
+    CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompResistor, mRcompResistorSklRvp1, sizeof (mRcompResistorSklRvp1));
+    CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompTarget,   mRcompTargetSklRvp1,   sizeof (mRcompTargetSklRvp1));
+  }
+
+  CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[0][0], mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
+  CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[1][0], mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
+
+  DqByteMap = (UINT8 *) mDqByteMapSkl;
+
+  CopyMem ((VOID *) MemConfigNoCrc->DqByteMap, DqByteMap, sizeof (UINT8) * SA_MC_MAX_CHANNELS * SA_MRC_ITERATION_MAX * 2);
+  CopyMem ((VOID *) MemConfigNoCrc->DqsMap, mDqsMapCpu2DramSklRvp, sizeof (UINT8) * SA_MC_MAX_CHANNELS * SA_MC_MAX_BYTES_NO_ECC);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
new file mode 100644
index 0000000000..ce3ef52733
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
@@ -0,0 +1,559 @@
+/** @file
+  This file provides service for PEI phase policy printing
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyLibrary.h"
+#include <Library/GpioNativeLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi - Instance of SI_PREMEM_POLICY_PPI
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  INTN                                  Index;
+  INTN                                  Index2;
+  EFI_STATUS                            Status;
+  SA_MISC_PEI_PREMEM_CONFIG             *MiscPeiPreMemConfig;
+  GRAPHICS_PEI_PREMEM_CONFIG            *GtPreMemConfig;
+  MEMORY_CONFIGURATION                  *MemConfig;
+  PCIE_PEI_PREMEM_CONFIG                *PciePeiPreMemConfig;
+  SWITCHABLE_GRAPHICS_CONFIG            *SgConfig;
+  MEMORY_CONFIG_NO_CRC                  *MemConfigNoCrc;
+  VTD_CONFIG                            *Vtd;
+  OVERCLOCKING_PREMEM_CONFIG            *OcPreMemConfig;
+  IPU_PREMEM_CONFIG                     *IpuPreMemPolicy;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gVtdConfigGuid, (VOID *) &Vtd);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gSwitchableGraphicsConfigGuid, (VOID *) &SgConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", SiPolicyPreMemPpi->TableHeader.Header.Revision));
+  ASSERT (SiPolicyPreMemPpi->TableHeader.Header.Revision == SI_PREMEM_POLICY_REVISION);
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_PREMEM_CONFIG  -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", MiscPeiPreMemConfig->Header.Revision));
+  ASSERT (MiscPeiPreMemConfig->Header.Revision == SA_MISC_PEI_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", SA_MC_MAX_SOCKETS));
+  for (Index = 0; Index < SA_MC_MAX_SOCKETS; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", MiscPeiPreMemConfig->SpdAddressTable[Index]));
+  }
+
+  DEBUG ((DEBUG_INFO, "\n MchBar : 0x%x\n", MiscPeiPreMemConfig->MchBar));
+  DEBUG ((DEBUG_INFO, " DmiBar : 0x%x\n", MiscPeiPreMemConfig->DmiBar));
+  DEBUG ((DEBUG_INFO, " EpBar : 0x%x\n", MiscPeiPreMemConfig->EpBar));
+  DEBUG ((DEBUG_INFO, " SmbusBar : 0x%x\n", MiscPeiPreMemConfig->SmbusBar));
+  DEBUG ((DEBUG_INFO, " GdxcBar : 0x%x\n", MiscPeiPreMemConfig->GdxcBar));
+  DEBUG ((DEBUG_INFO, " TsegSize : 0x%x\n", MiscPeiPreMemConfig->TsegSize));
+  DEBUG ((DEBUG_INFO, " UserBd : 0x%x\n", MiscPeiPreMemConfig->UserBd));
+  DEBUG ((DEBUG_INFO, " EdramBar : 0x%x\n", MiscPeiPreMemConfig->EdramBar));
+  DEBUG ((DEBUG_INFO, " MmioSize : %d MB\n", MiscPeiPreMemConfig->MmioSize));
+  DEBUG ((DEBUG_INFO, " MmioSizeAdjustment : %d MB\n", MiscPeiPreMemConfig->MmioSizeAdjustment));
+  DEBUG ((DEBUG_INFO, " SkipExtGfxScan: 0x%x\n", MiscPeiPreMemConfig->SkipExtGfxScan));
+  DEBUG ((DEBUG_INFO, " S3DataPtr : 0x%x\n", MiscPeiPreMemConfig->S3DataPtr));
+  DEBUG ((DEBUG_INFO, "------------------------ SG_DELAY_OPTIMIZATION_DATA -----------------\n"));
+  DEBUG ((DEBUG_INFO, " SaRtd3.SgDelayAfterHoldReset : 0x%x\n", MiscPeiPreMemConfig->SgDelayAfterHoldReset));
+  DEBUG ((DEBUG_INFO, " SaRtd3.SgDelayAfterPwrEn     : 0x%x\n", MiscPeiPreMemConfig->SgDelayAfterPwrEn));
+
+  DEBUG ((DEBUG_INFO, " ScanExtGfxForLegacyOpRom : 0x%x\n", MiscPeiPreMemConfig->ScanExtGfxForLegacyOpRom));
+  DEBUG ((DEBUG_INFO, " AcpiReservedMemoryBase : 0x%x\n", MiscPeiPreMemConfig->AcpiReservedMemoryBase));
+  DEBUG ((DEBUG_INFO, " AcpiReservedMemorySize : 0x%x\n", MiscPeiPreMemConfig->AcpiReservedMemorySize));
+  DEBUG ((DEBUG_INFO, " SystemMemoryLength : 0x%x\n", MiscPeiPreMemConfig->SystemMemoryLength));
+  DEBUG ((DEBUG_INFO, " OpRomScanTempMmioBar : 0x%x\n", MiscPeiPreMemConfig->OpRomScanTempMmioBar));
+  DEBUG ((DEBUG_INFO, " OpRomScanTempMmioLimit : 0x%x\n", MiscPeiPreMemConfig->OpRomScanTempMmioLimit));
+
+  DEBUG ((DEBUG_INFO, "------------------------ GRAPHICS_PEI_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", GtPreMemConfig->Header.Revision));
+  ASSERT (GtPreMemConfig->Header.Revision == GRAPHICS_PEI_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " PanelPowerEnable : 0x%x\n", GtPreMemConfig->PanelPowerEnable));
+  DEBUG ((DEBUG_INFO, " GttSize : %d MB\n", GtPreMemConfig->GttSize));
+  DEBUG ((DEBUG_INFO, " IgdDvmt50PreAlloc : 0x%x\n", GtPreMemConfig->IgdDvmt50PreAlloc));
+  DEBUG ((DEBUG_INFO, " InternalGraphics : 0x%x\n", GtPreMemConfig->InternalGraphics));
+  DEBUG ((DEBUG_INFO, " PrimaryDisplay : 0x%x\n", GtPreMemConfig->PrimaryDisplay));
+  DEBUG ((DEBUG_INFO, " ApertureSize : 0x%x\n", GtPreMemConfig->ApertureSize));
+  DEBUG ((DEBUG_INFO, " GtPsmiSupport : 0x%x\n", GtPreMemConfig->GtPsmiSupport));
+  DEBUG ((DEBUG_INFO, " PsmiRegionSize : 0x%x\n", GtPreMemConfig->PsmiRegionSize));
+  DEBUG ((DEBUG_INFO, " GttMmAdr : 0x%x\n", GtPreMemConfig->GttMmAdr));
+  DEBUG ((DEBUG_INFO, " GmAdr : 0x%x\n", GtPreMemConfig->GmAdr));
+  DEBUG ((DEBUG_INFO, " DeltaT12PowerCycleDelayPreMem : 0x%x\n", GtPreMemConfig->DeltaT12PowerCycleDelayPreMem));
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCIE_PEI_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", PciePeiPreMemConfig->Header.Revision));
+  ASSERT (PciePeiPreMemConfig->Header.Revision == SA_PCIE_PEI_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " DmiMaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->DmiMaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " DmiGen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->DmiGen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " DmiGen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->DmiGen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " DmiGen3ProgramStaticEq : 0x%x\n", PciePeiPreMemConfig->DmiGen3ProgramStaticEq));
+  DEBUG ((DEBUG_INFO, " Peg0Enable : 0x%x\n", PciePeiPreMemConfig->Peg0Enable));
+  DEBUG ((DEBUG_INFO, " Peg1Enable : 0x%x\n", PciePeiPreMemConfig->Peg1Enable));
+  DEBUG ((DEBUG_INFO, " Peg2Enable : 0x%x\n", PciePeiPreMemConfig->Peg2Enable));
+  DEBUG ((DEBUG_INFO, " Peg3Enable : 0x%x\n", PciePeiPreMemConfig->Peg3Enable));
+  DEBUG ((DEBUG_INFO, " Peg0MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg0MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg1MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg1MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg2MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg2MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg3MaxLinkSpeed : 0x%x\n", PciePeiPreMemConfig->Peg3MaxLinkSpeed));
+  DEBUG ((DEBUG_INFO, " Peg0MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg0MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg1MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg1MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg2MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg2MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg3MaxLinkWidth : 0x%x\n", PciePeiPreMemConfig->Peg3MaxLinkWidth));
+  DEBUG ((DEBUG_INFO, " Peg0PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg0PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg1PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg1PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg2PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg2PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg3PowerDownUnusedLanes : 0x%x\n", PciePeiPreMemConfig->Peg3PowerDownUnusedLanes));
+  DEBUG ((DEBUG_INFO, " Peg0Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg0Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg1Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg1Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg2Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg2Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg3Gen3EqPh2Enable : 0x%x\n", PciePeiPreMemConfig->Peg3Gen3EqPh2Enable));
+  DEBUG ((DEBUG_INFO, " Peg0Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg0Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " Peg1Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg1Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " Peg2Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg2Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " Peg3Gen3EqPh3Method : 0x%x\n", PciePeiPreMemConfig->Peg3Gen3EqPh3Method));
+  DEBUG ((DEBUG_INFO, " PegGen3ProgramStaticEq : 0x%x\n", PciePeiPreMemConfig->PegGen3ProgramStaticEq));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqAlwaysAttempt : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqAlwaysAttempt));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqNumberOfPresets : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqNumberOfPresets));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqEnableVocTest : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqEnableVocTest));
+  DEBUG ((DEBUG_INFO, " InitPcieAspmAfterOprom : 0x%x\n", PciePeiPreMemConfig->InitPcieAspmAfterOprom));
+  DEBUG ((DEBUG_INFO, " PegRxCemTestingMode : 0x%x\n", PciePeiPreMemConfig->PegRxCemTestingMode));
+  DEBUG ((DEBUG_INFO, " PegRxCemLoopbackLane : 0x%x\n", PciePeiPreMemConfig->PegRxCemLoopbackLane));
+  DEBUG ((DEBUG_INFO, " PegRxCemNonProtocolAwareness : 0x%x\n", PciePeiPreMemConfig->PegRxCemNonProtocolAwareness));
+  DEBUG ((DEBUG_INFO, " PegDisableSpreadSpectrumClocking : 0x%x\n", PciePeiPreMemConfig->PegDisableSpreadSpectrumClocking));
+  DEBUG ((DEBUG_INFO, " PegGenerateBdatMarginTable : 0x%x\n", PciePeiPreMemConfig->PegGenerateBdatMarginTable));
+  DEBUG ((DEBUG_INFO, " DmiGen3RootPortPreset[%d] :", SA_DMI_MAX_LANE));
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3RootPortPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n DmiGen3EndPointPreset[%d] :", SA_DMI_MAX_LANE));
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3EndPointPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n DmiGen3EndPointHint[%d] :", SA_DMI_MAX_LANE));
+  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3EndPointHint[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n DmiGen3RxCtlePeaking[%d] :", SA_DMI_MAX_BUNDLE));
+  for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3RootPortPreset[%d] :", SA_PEG_MAX_LANE));
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3RootPortPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegRootPortHPE[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegRootPortHPE[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3EndPointPreset[%d] :", SA_PEG_MAX_LANE));
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3EndPointPreset[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3EndPointHint[%d] :", SA_PEG_MAX_LANE));
+  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3EndPointHint[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3RxCtlePeaking[%d] :", SA_PEG_MAX_BUNDLE));
+  for (Index = 0; Index < SA_PEG_MAX_BUNDLE; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiPreMemConfig->PegGen3RxCtlePeaking[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegGen3RxCtleOverride : 0x%x\n", PciePeiPreMemConfig->PegGen3RxCtleOverride));
+  DEBUG ((DEBUG_INFO, " DmiDeEmphasis : 0x%x\n", PciePeiPreMemConfig->DmiDeEmphasis));
+  DEBUG ((DEBUG_INFO, "\n Gen3SwEqJitterDwellTime : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqJitterDwellTime));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqJitterErrorTarget : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqVocDwellTime : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqVocDwellTime));
+  DEBUG ((DEBUG_INFO, " Gen3SwEqVocErrorTarget : 0x%x\n", PciePeiPreMemConfig->Gen3SwEqVocErrorTarget));
+  DEBUG ((DEBUG_INFO, " PegDataPtr : %p\n", PciePeiPreMemConfig->PegDataPtr));
+  DEBUG ((DEBUG_INFO, " PegGpioData->GpioSupport : 0x%x\n", PciePeiPreMemConfig->PegGpioData.GpioSupport));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg0ResetGpio.GpioPad Group:%d, PadNumber:%d\n", GpioGetGroupIndexFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad), GpioGetPadNumberFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad)));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg0ResetGpio.Active : 0x%x\n", PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg3ResetGpio.GpioPad Group:%d, PadNumber:%d\n", GpioGetGroupIndexFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad), GpioGetPadNumberFromGpioPad (PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad)));
+  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg3ResetGpio.Active : 0x%x\n", PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active));
+
+  DEBUG ((DEBUG_INFO, "------------------------ VTD_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", Vtd->Header.Revision));
+  ASSERT (Vtd->Header.Revision == VTD_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " VtdDisable : 0x%x\n", Vtd->VtdDisable));
+  DEBUG ((DEBUG_INFO, " X2ApicOptOut : 0x%x\n", Vtd->X2ApicOptOut));
+  DEBUG ((DEBUG_INFO, " VtdBaseAddress[%d] :", SA_VTD_ENGINE_NUMBER));
+  for (Index = 0; Index < SA_VTD_ENGINE_NUMBER; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", Vtd->BaseAddress[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, "------------------------ SWITCHABLE_GRAPHICS_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", SgConfig->Header.Revision));
+  ASSERT (SgConfig->Header.Revision == SWITCHABLE_GRAPHICS_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " SgConfig->SaRtd3Pcie0Gpio.GpioSupport : 0x%x\n", SgConfig->SaRtd3Pcie0Gpio.GpioSupport));
+
+  DEBUG ((DEBUG_INFO, "------------------------ IPU_PREMEM_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", IpuPreMemPolicy->Header.Revision));
+  ASSERT (IpuPreMemPolicy->Header.Revision == IPU_PREMEM_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " SaIpuEnable : 0x%x\n", IpuPreMemPolicy->SaIpuEnable));
+  DEBUG ((DEBUG_INFO, " SaIpuImrConfiguration : 0x%x\n", IpuPreMemPolicy->SaIpuImrConfiguration));
+
+  DEBUG ((DEBUG_INFO, "------------------------ MEMORY_CONFIG ------------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Guid                   : %g\n", &MemConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, " Revision               : %d\n",   MemConfig->Header.Revision));
+  ASSERT (MemConfig->Header.Revision == MEMORY_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " Size                   : 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
+  DEBUG ((DEBUG_INFO, " HobBufferSize          : 0x%x\n", MemConfig->HobBufferSize));
+  DEBUG ((DEBUG_INFO, " EccSupport             : 0x%x\n", MemConfig->EccSupport));
+  DEBUG ((DEBUG_INFO, " DdrFreqLimit           : %d\n",   MemConfig->DdrFreqLimit));
+  DEBUG ((DEBUG_INFO, " SpdProfileSelected     : 0x%x\n", MemConfig->SpdProfileSelected));
+  DEBUG ((DEBUG_INFO, " tCL                    : 0x%x\n", MemConfig->tCL));
+  DEBUG ((DEBUG_INFO, " tRCDtRP                : 0x%x\n", MemConfig->tRCDtRP));
+  DEBUG ((DEBUG_INFO, " tRAS                   : 0x%x\n", MemConfig->tRAS));
+  DEBUG ((DEBUG_INFO, " tWR                    : 0x%x\n", MemConfig->tWR));
+  DEBUG ((DEBUG_INFO, " tRFC                   : 0x%x\n", MemConfig->tRFC));
+  DEBUG ((DEBUG_INFO, " tRRD                   : 0x%x\n", MemConfig->tRRD));
+  DEBUG ((DEBUG_INFO, " tWTR                   : 0x%x\n", MemConfig->tWTR));
+  DEBUG ((DEBUG_INFO, " tRTP                   : 0x%x\n", MemConfig->tRTP));
+  DEBUG ((DEBUG_INFO, " tFAW                   : 0x%x\n", MemConfig->tFAW));
+  DEBUG ((DEBUG_INFO, " tCWL                   : 0x%x\n", MemConfig->tCWL));
+  DEBUG ((DEBUG_INFO, " tREFI                  : 0x%x\n", MemConfig->tREFI));
+  DEBUG ((DEBUG_INFO, " NModeSupport           : 0x%x\n", MemConfig->NModeSupport));
+  DEBUG ((DEBUG_INFO, " VddVoltage             : %d\n", MemConfig->VddVoltage));
+
+  DEBUG ((DEBUG_INFO, " DisableDimmChannel[%d] :", SA_MC_MAX_CHANNELS));
+  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", MemConfig->DisableDimmChannel[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n RemapEnable            : 0x%x\n", MemConfig->RemapEnable));
+  DEBUG ((DEBUG_INFO, " ScramblerSupport       : 0x%x\n", MemConfig->ScramblerSupport));
+  DEBUG ((DEBUG_INFO, " SerialDebug            : 0x%x\n", MemConfigNoCrc->SerialDebugLevel));
+  DEBUG ((DEBUG_INFO, " ProbelessTrace      : 0x%x\n", MemConfig->ProbelessTrace));
+  DEBUG ((DEBUG_INFO, " ECT                    : 0x%x\n", MemConfig->ECT));
+  DEBUG ((DEBUG_INFO, " SOT                    : 0x%x\n", MemConfig->SOT));
+  DEBUG ((DEBUG_INFO, " ERDMPRTC2D             : 0x%x\n", MemConfig->ERDMPRTC2D));
+  DEBUG ((DEBUG_INFO, " RDMPRT                 : 0x%x\n", MemConfig->RDMPRT));
+  DEBUG ((DEBUG_INFO, " RCVET                  : 0x%x\n", MemConfig->RCVET));
+  DEBUG ((DEBUG_INFO, " JWRL                   : 0x%x\n", MemConfig->JWRL));
+  DEBUG ((DEBUG_INFO, " EWRTC2D                : 0x%x\n", MemConfig->EWRTC2D));
+  DEBUG ((DEBUG_INFO, " ERDTC2D                : 0x%x\n", MemConfig->ERDTC2D));
+  DEBUG ((DEBUG_INFO, " WRTC1D                 : 0x%x\n", MemConfig->WRTC1D));
+  DEBUG ((DEBUG_INFO, " WRVC1D                 : 0x%x\n", MemConfig->WRVC1D));
+  DEBUG ((DEBUG_INFO, " RDTC1D                 : 0x%x\n", MemConfig->RDTC1D));
+  DEBUG ((DEBUG_INFO, " DIMMODTT               : 0x%x\n", MemConfig->DIMMODTT));
+  DEBUG ((DEBUG_INFO, " DIMMRONT               : 0x%x\n", MemConfig->DIMMRONT));
+  DEBUG ((DEBUG_INFO, " WRDSEQT                : 0x%x\n", MemConfig->WRDSEQT));
+  DEBUG ((DEBUG_INFO, " WRSRT                  : 0x%x\n", MemConfig->WRSRT));
+  DEBUG ((DEBUG_INFO, " RDODTT                 : 0x%x\n", MemConfig->RDODTT));
+  DEBUG ((DEBUG_INFO, " RDEQT                  : 0x%x\n", MemConfig->RDEQT));
+  DEBUG ((DEBUG_INFO, " RDAPT                  : 0x%x\n", MemConfig->RDAPT));
+  DEBUG ((DEBUG_INFO, " WRTC2D                 : 0x%x\n", MemConfig->WRTC2D));
+  DEBUG ((DEBUG_INFO, " RDTC2D                 : 0x%x\n", MemConfig->RDTC2D));
+  DEBUG ((DEBUG_INFO, " WRVC2D                 : 0x%x\n", MemConfig->WRVC2D));
+  DEBUG ((DEBUG_INFO, " RDVC2D                 : 0x%x\n", MemConfig->RDVC2D));
+  DEBUG ((DEBUG_INFO, " CMDVC                  : 0x%x\n", MemConfig->CMDVC));
+  DEBUG ((DEBUG_INFO, " LCT                    : 0x%x\n", MemConfig->LCT));
+  DEBUG ((DEBUG_INFO, " RTL                    : 0x%x\n", MemConfig->RTL));
+  DEBUG ((DEBUG_INFO, " TAT                    : 0x%x\n", MemConfig->TAT));
+  DEBUG ((DEBUG_INFO, " RMT                    : 0x%x\n", MemConfig->RMT));
+  DEBUG ((DEBUG_INFO, " MEMTST                 : 0x%x\n", MemConfig->MEMTST));
+  DEBUG ((DEBUG_INFO, " ALIASCHK               : 0x%x\n", MemConfig->ALIASCHK));
+  DEBUG ((DEBUG_INFO, " RCVENC1D               : 0x%x\n", MemConfig->RCVENC1D));
+  DEBUG ((DEBUG_INFO, " RMC                    : 0x%x\n", MemConfig->RMC));
+  DEBUG ((DEBUG_INFO, " WRDSUDT                : 0x%x\n", MemConfig->WRDSUDT));
+
+  DEBUG ((DEBUG_INFO, " VddSettleWaitTime      : 0x%x\n", MemConfig->VddSettleWaitTime));
+  DEBUG ((DEBUG_INFO, " RefClk                 : 0x%x\n", MemConfig->RefClk));
+  DEBUG ((DEBUG_INFO, " Ratio                  : 0x%x\n", MemConfig->Ratio));
+  DEBUG ((DEBUG_INFO, " OddRatioMode           : 0x%x\n", MemConfig->OddRatioMode));
+  DEBUG ((DEBUG_INFO, " MrcTimeMeasure         : 0x%x\n", MemConfig->MrcTimeMeasure));
+  DEBUG ((DEBUG_INFO, " MrcFastBoot            : 0x%x\n", MemConfig->MrcFastBoot));
+  DEBUG ((DEBUG_INFO, " DqPinsInterleaved      : 0x%x\n", MemConfig->DqPinsInterleaved));
+  DEBUG ((DEBUG_INFO, " MrcSafeConfig          : 0x%x\n", MemConfig->MrcSafeConfig));
+  DEBUG ((DEBUG_INFO, " SafeMode               : 0x%x\n", MemConfig->SafeMode));
+  DEBUG ((DEBUG_INFO, " Lp4DqsOscEn            : 0x%x\n", MemConfig->Lp4DqsOscEn));
+  DEBUG ((DEBUG_INFO, " EnBER                  : 0x%x\n", MemConfig->EnBER));
+  DEBUG ((DEBUG_INFO, " Ddr4MixedUDimm2DpcLimit: 0x%x\n", MemConfig->Ddr4MixedUDimm2DpcLimit));
+  DEBUG ((DEBUG_INFO, " PowerDownMode          : 0x%x\n", MemConfig->PowerDownMode));
+  DEBUG ((DEBUG_INFO, " PwdwnIdleCounter       : 0x%x\n", MemConfig->PwdwnIdleCounter));
+  DEBUG ((DEBUG_INFO, " RankInterleave         : 0x%x\n", MemConfig->RankInterleave));
+  DEBUG ((DEBUG_INFO, " EnhancedInterleave     : 0x%x\n", MemConfig->EnhancedInterleave));
+  DEBUG ((DEBUG_INFO, " WeaklockEn             : 0x%x\n", MemConfig->WeaklockEn));
+  DEBUG ((DEBUG_INFO, " EnCmdRate              : 0x%x\n", MemConfig->EnCmdRate));
+  DEBUG ((DEBUG_INFO, " CmdTriStateDis         : 0x%x\n", MemConfig->CmdTriStateDis));
+  DEBUG ((DEBUG_INFO, " BClkFrequency          : 0x%x\n", MemConfig->BClkFrequency));
+  DEBUG ((DEBUG_INFO, " MemoryTrace            : 0x%x\n", MemConfig->MemoryTrace));
+  DEBUG ((DEBUG_INFO, " ChHashEnable           : 0x%x\n", MemConfig->ChHashEnable));
+  DEBUG ((DEBUG_INFO, " ChHashMask             : 0x%x\n", MemConfig->ChHashMask));
+  DEBUG ((DEBUG_INFO, " ChHashInterleaveBit    : 0x%x\n", MemConfig->ChHashInterleaveBit));
+  DEBUG ((DEBUG_INFO, " PerBankRefresh         : 0x%x\n", MemConfig->PerBankRefresh));
+  DEBUG ((DEBUG_INFO, " EnableExtts            : 0x%x\n", MemConfig->EnableExtts));
+  DEBUG ((DEBUG_INFO, " EnableCltm             : 0x%x\n", MemConfig->EnableCltm));
+  DEBUG ((DEBUG_INFO, " EnableOltm             : 0x%x\n", MemConfig->EnableOltm));
+  DEBUG ((DEBUG_INFO, " EnablePwrDn            : 0x%x\n", MemConfig->EnablePwrDn));
+  DEBUG ((DEBUG_INFO, " EnablePwrDnLpddr       : 0x%x\n", MemConfig->EnablePwrDnLpddr));
+  DEBUG ((DEBUG_INFO, " Refresh2X              : 0x%x\n", MemConfig->Refresh2X));
+  DEBUG ((DEBUG_INFO, " DdrThermalSensor       : 0x%x\n", MemConfig->DdrThermalSensor));
+  DEBUG ((DEBUG_INFO, " LockPTMregs            : 0x%x\n", MemConfig->LockPTMregs));
+  DEBUG ((DEBUG_INFO, " UserPowerWeightsEn     : 0x%x\n", MemConfig->UserPowerWeightsEn));
+  DEBUG ((DEBUG_INFO, " EnergyScaleFact        : 0x%x\n", MemConfig->EnergyScaleFact));
+  DEBUG ((DEBUG_INFO, " RaplPwrFlCh1           : 0x%x\n", MemConfig->RaplPwrFlCh1));
+  DEBUG ((DEBUG_INFO, " RaplPwrFlCh0           : 0x%x\n", MemConfig->RaplPwrFlCh0));
+  DEBUG ((DEBUG_INFO, " RaplLim2Lock           : 0x%x\n", MemConfig->RaplLim2Lock));
+  DEBUG ((DEBUG_INFO, " RaplLim2WindX          : 0x%x\n", MemConfig->RaplLim2WindX));
+  DEBUG ((DEBUG_INFO, " RaplLim2WindY          : 0x%x\n", MemConfig->RaplLim2WindY));
+  DEBUG ((DEBUG_INFO, " RaplLim2Ena            : 0x%x\n", MemConfig->RaplLim2Ena));
+  DEBUG ((DEBUG_INFO, " RaplLim2Pwr            : 0x%x\n", MemConfig->RaplLim2Pwr));
+  DEBUG ((DEBUG_INFO, " RaplLim1WindX          : 0x%x\n", MemConfig->RaplLim1WindX));
+  DEBUG ((DEBUG_INFO, " RaplLim1WindY          : 0x%x\n", MemConfig->RaplLim1WindY));
+  DEBUG ((DEBUG_INFO, " RaplLim1Ena            : 0x%x\n", MemConfig->RaplLim1Ena));
+  DEBUG ((DEBUG_INFO, " RaplLim1Pwr            : 0x%x\n", MemConfig->RaplLim1Pwr));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm0  : 0x%x\n", MemConfig->WarmThresholdCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm1  : 0x%x\n", MemConfig->WarmThresholdCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm0  : 0x%x\n", MemConfig->WarmThresholdCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm1  : 0x%x\n", MemConfig->WarmThresholdCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm0   : 0x%x\n", MemConfig->HotThresholdCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm1   : 0x%x\n", MemConfig->HotThresholdCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm0   : 0x%x\n", MemConfig->HotThresholdCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm1   : 0x%x\n", MemConfig->HotThresholdCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm0     : 0x%x\n", MemConfig->WarmBudgetCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm1     : 0x%x\n", MemConfig->WarmBudgetCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm0     : 0x%x\n", MemConfig->WarmBudgetCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm1     : 0x%x\n", MemConfig->WarmBudgetCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm0      : 0x%x\n", MemConfig->HotBudgetCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm1      : 0x%x\n", MemConfig->HotBudgetCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm0      : 0x%x\n", MemConfig->HotBudgetCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm1      : 0x%x\n", MemConfig->HotBudgetCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm0     : 0x%x\n", MemConfig->IdleEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm1     : 0x%x\n", MemConfig->IdleEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm0     : 0x%x\n", MemConfig->IdleEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm1     : 0x%x\n", MemConfig->IdleEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm0       : 0x%x\n", MemConfig->PdEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm1       : 0x%x\n", MemConfig->PdEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm0       : 0x%x\n", MemConfig->PdEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm1       : 0x%x\n", MemConfig->PdEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm0      : 0x%x\n", MemConfig->ActEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm1      : 0x%x\n", MemConfig->ActEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm0      : 0x%x\n", MemConfig->ActEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm1      : 0x%x\n", MemConfig->ActEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm0       : 0x%x\n", MemConfig->RdEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm1       : 0x%x\n", MemConfig->RdEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm0       : 0x%x\n", MemConfig->RdEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm1       : 0x%x\n", MemConfig->RdEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm0       : 0x%x\n", MemConfig->WrEnergyCh0Dimm0));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm1       : 0x%x\n", MemConfig->WrEnergyCh0Dimm1));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm0       : 0x%x\n", MemConfig->WrEnergyCh1Dimm0));
+  DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm1       : 0x%x\n", MemConfig->WrEnergyCh1Dimm1));
+  DEBUG ((DEBUG_INFO, " SrefCfgEna             : 0x%x\n", MemConfig->SrefCfgEna));
+  DEBUG ((DEBUG_INFO, " SrefCfgIdleTmr         : 0x%x\n", MemConfig->SrefCfgIdleTmr));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeat       : 0x%x\n", MemConfig->ThrtCkeMinDefeat));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinTmr          : 0x%x\n", MemConfig->ThrtCkeMinTmr));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeatLpddr  : 0x%x\n", MemConfig->ThrtCkeMinDefeatLpddr));
+  DEBUG ((DEBUG_INFO, " ThrtCkeMinTmrLpddr     : 0x%x\n", MemConfig->ThrtCkeMinTmrLpddr));
+  DEBUG ((DEBUG_INFO, " AutoSelfRefreshSupport : 0x%x\n", MemConfig->AutoSelfRefreshSupport));
+  DEBUG ((DEBUG_INFO, " ExtTemperatureSupport  : 0x%x\n", MemConfig->ExtTemperatureSupport));
+  DEBUG ((DEBUG_INFO, " MaxRttWr               : 0x%x\n", MemConfig->MaxRttWr));
+  DEBUG ((DEBUG_INFO, " MobilePlatform         : 0x%x\n", MemConfig->MobilePlatform));
+  DEBUG ((DEBUG_INFO, " Force1Dpc              : 0x%x\n", MemConfig->Force1Dpc));
+
+
+  DEBUG ((DEBUG_INFO, " ForceSingleRank        : 0x%x\n", MemConfig->ForceSingleRank));
+  DEBUG ((DEBUG_INFO, " PciIndex               : 0x%x\n", MemConfig->PciIndex));
+  DEBUG ((DEBUG_INFO, " PciData                : 0x%x\n", MemConfig->PciData));
+  DEBUG ((DEBUG_INFO, " CkeRankMapping         : 0x%x\n", MemConfig->CkeRankMapping));
+  DEBUG ((DEBUG_INFO, " RhPrevention           : 0x%x\n", MemConfig->RhPrevention));
+  DEBUG ((DEBUG_INFO, " RhSolution             : 0x%x\n", MemConfig->RhSolution));
+  DEBUG ((DEBUG_INFO, " RhActProbability       : 0x%x\n", MemConfig->RhActProbability));
+  DEBUG ((DEBUG_INFO, " VttTermination         : 0x%x\n", MemConfig->VttTermination));
+  DEBUG ((DEBUG_INFO, " VttCompForVsshi        : 0x%x\n", MemConfig->VttCompForVsshi));
+  DEBUG ((DEBUG_INFO, " BerEnable              : 0x%x\n", MemConfig->BerEnable));
+  for (Index = 0; Index < 4; Index++) {
+    DEBUG ((DEBUG_INFO, " BerAddress[%d]      : 0x%x\n",Index , MemConfig->BerAddress[Index]));
+  }
+  DEBUG ((DEBUG_INFO, " CleanMemory            : 0x%x\n", MemConfigNoCrc->CleanMemory));
+  DEBUG ((DEBUG_INFO, " MemTestOnWarmBoot      : 0x%x\n", MemConfigNoCrc->MemTestOnWarmBoot));
+  DEBUG ((DEBUG_INFO, " ExitOnFailure          : 0x%x\n", MemConfig->ExitOnFailure));
+  DEBUG ((DEBUG_INFO, " Vc1ReadMeter           : 0x%x\n", MemConfig->Vc1ReadMeter));
+  DEBUG ((DEBUG_INFO, " SaGv                   : 0x%x\n", MemConfig->SaGv));
+  DEBUG ((DEBUG_INFO, " FreqSaGvLow            : 0x%x\n FreqSaGvMid            : 0x%x\n",
+          MemConfig->FreqSaGvLow, MemConfig->FreqSaGvMid));
+  DEBUG ((DEBUG_INFO, " StrongWkLeaker         : 0x%x\n", MemConfig->StrongWkLeaker));
+  DEBUG ((DEBUG_INFO, " CaVrefConfig           : 0x%x\n", MemConfig->CaVrefConfig));
+  DEBUG ((DEBUG_INFO, " SimicsFlag             : 0x%x\n", MemConfig->SimicsFlag));
+  DEBUG ((DEBUG_INFO, " PlatformMemorySize     : 0x%x\n", MemConfigNoCrc->PlatformMemorySize));
+  DEBUG ((DEBUG_INFO, " SmramMask              : 0x%x\n", MemConfig->SmramMask));
+  DEBUG ((DEBUG_INFO, " DllBwEn0: %d\n DllBwEn1: %d\n DllBwEn2: %d\n DllBwEn3: %d\n",
+          MemConfig->DllBwEn0, MemConfig->DllBwEn1, MemConfig->DllBwEn2, MemConfig->DllBwEn3));
+  DEBUG ((DEBUG_INFO, " RetrainOnFastFail: %d\n ForceOltmOrRefresh2x: %d\n",
+          MemConfig->RetrainOnFastFail, MemConfig->ForceOltmOrRefresh2x));
+  DEBUG ((DEBUG_INFO, " RmtPerTask: %u\n TrainTrace: %u\n", MemConfig->RmtPerTask, MemConfig->TrainTrace));
+  DEBUG ((DEBUG_INFO, " tRd2RdSG               : 0x%x\n tRd2RdDG               : 0x%x\n", MemConfig->tRd2RdSG, MemConfig->tRd2RdDG));
+  DEBUG ((DEBUG_INFO, " tRd2RdDR               : 0x%x\n tRd2RdDD               : 0x%x\n", MemConfig->tRd2RdDR, MemConfig->tRd2RdDD));
+  DEBUG ((DEBUG_INFO, " tRd2WrSG               : 0x%x\n tRd2WrDG               : 0x%x\n", MemConfig->tRd2WrSG, MemConfig->tRd2WrDG));
+  DEBUG ((DEBUG_INFO, " tRd2WrDR               : 0x%x\n tRd2WrDD               : 0x%x\n", MemConfig->tRd2WrDR, MemConfig->tRd2WrDD));
+  DEBUG ((DEBUG_INFO, " tWr2RdSG               : 0x%x\n tWr2RdDG               : 0x%x\n", MemConfig->tWr2RdSG, MemConfig->tWr2RdDG));
+  DEBUG ((DEBUG_INFO, " tWr2RdDR               : 0x%x\n tWr2RdDD               : 0x%x\n", MemConfig->tWr2RdDR, MemConfig->tWr2RdDD));
+  DEBUG ((DEBUG_INFO, " tWr2WrSG               : 0x%x\n tWr2WrDG               : 0x%x\n", MemConfig->tWr2WrSG, MemConfig->tWr2WrDG));
+  DEBUG ((DEBUG_INFO, " tWr2WrDR               : 0x%x\n tWr2WrDD               : 0x%x\n", MemConfig->tWr2WrDR, MemConfig->tWr2WrDD));
+  DEBUG ((DEBUG_INFO, "------------------------ OVERCLOCKING_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", OcPreMemConfig->Header.Revision));
+  ASSERT (OcPreMemConfig->Header.Revision == SA_OVERCLOCKING_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " OcSupport : 0x%x\n", OcPreMemConfig->OcSupport));
+  DEBUG ((DEBUG_INFO, " GtMaxOcRatio : 0x%x\n", OcPreMemConfig->GtMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " GtVoltageMode : 0x%x\n", OcPreMemConfig->GtVoltageMode));
+  DEBUG ((DEBUG_INFO, " GtVoltageOffset : 0x%x\n", OcPreMemConfig->GtVoltageOffset));
+  DEBUG ((DEBUG_INFO, " GtVoltageOverride : 0x%x\n", OcPreMemConfig->GtVoltageOverride));
+  DEBUG ((DEBUG_INFO, " GtExtraTurboVoltage : 0x%x\n", OcPreMemConfig->GtExtraTurboVoltage));
+  DEBUG ((DEBUG_INFO, " SaVoltageOffset : 0x%x\n", OcPreMemConfig->SaVoltageOffset));
+  DEBUG ((DEBUG_INFO, " GtusMaxOcRatio : 0x%x\n", OcPreMemConfig->GtusMaxOcRatio));
+  DEBUG ((DEBUG_INFO, " GtusVoltageMode : 0x%x\n", OcPreMemConfig->GtusVoltageMode));
+  DEBUG ((DEBUG_INFO, " GtusVoltageOffset : 0x%x\n", OcPreMemConfig->GtusVoltageOffset));
+  DEBUG ((DEBUG_INFO, " GtusVoltageOverride : 0x%x\n", OcPreMemConfig->GtusVoltageOverride));
+  DEBUG ((DEBUG_INFO, " GtusExtraTurboVoltage : 0x%x\n", OcPreMemConfig->GtusExtraTurboVoltage));
+  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+    DEBUG ((DEBUG_INFO, " DqByteMapCh%d        : ", Index));
+    for (Index2 = 0; Index2 < SA_MRC_ITERATION_MAX; Index2++) {
+      DEBUG ((DEBUG_INFO, "0x%02x ", MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][0]));
+      DEBUG ((DEBUG_INFO, "0x%02x ", MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][1]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
+    DEBUG ((DEBUG_INFO, " DqsMapCpu2DramCh%d   : ", Index));
+    for (Index2 = 0; Index2 < SA_MC_MAX_BYTES_NO_ECC; Index2++) {
+      DEBUG ((DEBUG_INFO, "%d ", MemConfigNoCrc->DqsMap->DqsMapCpu2Dram[Index][Index2]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print END -----------------\n"));
+  DEBUG_CODE_END ();
+  return;
+}
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi - Instance of SI_POLICY_PPI
+**/
+VOID
+EFIAPI
+SaPrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  INTN                                  Index;
+  EFI_STATUS                            Status;
+  GRAPHICS_PEI_CONFIG                   *GtConfig;
+  PCIE_PEI_CONFIG                       *PciePeiConfig;
+  SA_MISC_PEI_CONFIG                    *MiscPeiConfig;
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *) &GtConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID *) &PciePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid, (VOID *) &MiscPeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", SiPolicyPpi->TableHeader.Header.Revision));
+  ASSERT (SiPolicyPpi->TableHeader.Header.Revision == SI_POLICY_REVISION);
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_CONFIG  -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", MiscPeiConfig->Header.Revision));
+  ASSERT (MiscPeiConfig->Header.Revision == SA_MISC_PEI_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " ChapDeviceEnable : 0x%x\n", MiscPeiConfig->ChapDeviceEnable));
+  DEBUG ((DEBUG_INFO, " Device4Enable : 0x%x\n", MiscPeiConfig->Device4Enable));
+  DEBUG ((DEBUG_INFO, " CridEnable : 0x%x\n", MiscPeiConfig->CridEnable));
+  DEBUG ((DEBUG_INFO, " SkipPamLock : 0x%x\n", MiscPeiConfig->SkipPamLock));
+  DEBUG ((DEBUG_INFO, " EdramTestMode : 0x%x\n", MiscPeiConfig->EdramTestMode));
+
+  DEBUG ((DEBUG_INFO, "------------------------ GRAPHICS_PEI_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", GtConfig->Header.Revision));
+  ASSERT (GtConfig->Header.Revision == GRAPHICS_PEI_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " RenderStandby : 0x%x\n", GtConfig->RenderStandby));
+  DEBUG ((DEBUG_INFO, " PmSupport : 0x%x\n", GtConfig->PmSupport));
+  DEBUG ((DEBUG_INFO, " PavpEnable : 0x%x\n", GtConfig->PavpEnable));
+  DEBUG ((DEBUG_INFO, " CdClock : 0x%x\n", GtConfig->CdClock));
+  DEBUG ((DEBUG_INFO, " PeiGraphicsPeimInit : 0x%x\n", GtConfig->PeiGraphicsPeimInit));
+  DEBUG ((DEBUG_INFO, " LogoPtr : 0x%x\n", GtConfig->LogoPtr));
+  DEBUG ((DEBUG_INFO, " LogoSize : 0x%x\n", GtConfig->LogoSize));
+  DEBUG ((DEBUG_INFO, " BltBufferAddress : 0x%x\n", GtConfig->BltBufferAddress));
+  DEBUG ((DEBUG_INFO, " BltBufferSize : 0x%x\n", GtConfig->BltBufferSize));
+  DEBUG ((DEBUG_INFO, " GraphicsConfigPtr : 0x%x\n", GtConfig->GraphicsConfigPtr));
+  DEBUG ((DEBUG_INFO, " CdynmaxClampEnable : 0x%x\n", GtConfig->CdynmaxClampEnable));
+  DEBUG ((DEBUG_INFO, " GtFreqMax : 0x%x\n", GtConfig->GtFreqMax));
+  DEBUG ((DEBUG_INFO, " DisableTurboGt : 0x%x\n", GtConfig->DisableTurboGt));
+  DEBUG ((DEBUG_INFO, " DdiPortEdp  : 0x%x\n", GtConfig->DdiConfiguration.DdiPortEdp));
+  DEBUG ((DEBUG_INFO, " DdiPortBHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortBHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortCHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortCHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortDHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortDHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortFHpd : 0x%x\n", GtConfig->DdiConfiguration.DdiPortFHpd));
+  DEBUG ((DEBUG_INFO, " DdiPortBDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortBDdc));
+  DEBUG ((DEBUG_INFO, " DdiPortCDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortCDdc));
+  DEBUG ((DEBUG_INFO, " DdiPortDDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortDDdc));
+  DEBUG ((DEBUG_INFO, " DdiPortFDdc : 0x%x\n", GtConfig->DdiConfiguration.DdiPortFDdc));
+  DEBUG ((DEBUG_INFO, " SkipS3CdClockInit : 0x%x\n", GtConfig->SkipS3CdClockInit));
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCIE_PEI_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", PciePeiConfig->Header.Revision));
+  ASSERT (PciePeiConfig->Header.Revision == SA_PCIE_PEI_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, " DmiExtSync : 0x%x\n", PciePeiConfig->DmiExtSync));
+  DEBUG ((DEBUG_INFO, " DmiIot : 0x%x\n", PciePeiConfig->DmiIot));
+  DEBUG ((DEBUG_INFO, " DmiAspm : 0x%x\n", PciePeiConfig->DmiAspm));
+  DEBUG ((DEBUG_INFO, "\n PegSlotPowerLimitValue[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegSlotPowerLimitValue[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegSlotPowerLimitScale[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegSlotPowerLimitScale[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegPhysicalSlotNumber[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegPhysicalSlotNumber[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegDeEmphasis[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegDeEmphasis[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n PegMaxPayload[%d] :", SA_PEG_MAX_FUN));
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegMaxPayload[Index]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print END -----------------\n"));
+  DEBUG_CODE_END ();
+  return;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
new file mode 100644
index 0000000000..97b58c460f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
@@ -0,0 +1,114 @@
+## @file
+//
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+//-----------------------------------------------------------------------------
+//
+//  Section:     SaMmioRead64
+//
+//  Description: Read 64 bits from the Memory Mapped I/O space.
+//  Use MMX instruction for atomic access, because some MC registers have side effect.
+//
+//  @param[in] Address - Memory mapped I/O address.
+//
+//-----------------------------------------------------------------------------
+//UINT64
+//SaMmioRead64 (
+//  IN  UINTN Address
+//  )
+
+ASM_GLOBAL ASM_PFX(SaMmioRead64)
+ASM_PFX(SaMmioRead64):
+   subl    $16, %esp
+   movq    %mm0, (%esp)       //Save mm0 on stack
+   movl    20(%esp), %edx     //edx = Address
+   movq    (%edx), %mm0       //mm0 = [Address]
+   movq    %mm0, 8(%esp)      //Store mm0 on Stack
+   movq    (%esp), %mm0       //Restore mm0
+   emms
+   movl    8(%esp), %eax      //eax = [Address][31:0]
+   movl    12(%esp), %edx     //edx = [Address][64:32]
+   addl    $16, %esp
+   ret
+
+//-----------------------------------------------------------------------------
+//
+//  Section:     SaMmioWrite64
+//
+//  Description: Write 64 bits to the Memory Mapped I/O space.
+//  Use MMX instruction for atomic access, because some MC registers have side effect.
+//
+//  @param[in] Address - Memory mapped I/O address.
+//  @param[in] Value   - The value to write.
+//
+//-----------------------------------------------------------------------------
+
+//UINT64
+//SaMmioWrite64 (
+//  IN UINTN Address,
+//  IN UINT64 Value
+//  )
+
+ASM_GLOBAL ASM_PFX(SaMmioWrite64)
+ASM_PFX(SaMmioWrite64):
+   subl    $8, %esp
+   movq    %mm0, (%esp)       //Save mm0 on Stack
+   movl    12(%esp), %edx     //edx = Address
+   movq    16(%esp), %mm0     //mm0 = Value
+   movq    %mm0, (%edx)       //[Address] = Value
+   movq    (%esp), %mm0       //Restore mm0
+   emms
+   movl     16(%esp), %eax    //eax = Value[31:0]
+   movl     20(%esp), %edx    //edx = Value[64:32]
+   addl     $8, %esp
+   ret
+
+//-----------------------------------------------------------------------------
+//  Intel Silicon View Technology check point interface based on IO port reading
+//
+//  @param CheckPoint        Check point AH value.
+//                           AH = 0x10:  End of MRC State
+//                           AH = 0x20:  End of DXE State
+//                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+//                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD);
+//
+//  @param PortReading       IO port reading address used for breakpoints
+//-----------------------------------------------------------------------------
+
+//VOID
+//EFIAPI
+//IsvtCheckPoint (
+//  IN UINT32          CheckPoint,
+//  IN UINT32          PortReading
+//  )
+
+ASM_GLOBAL ASM_PFX(IsvtCheckPoint)
+ASM_PFX(IsvtCheckPoint):
+   pushl    %eax
+   pushl    %edx
+
+   // Stack layout at this point:
+   //-------------
+   // PortReading     ESP + 16
+   //-------------
+   // CheckPoint      ESP + 12
+   //-------------
+   // EIP             ESP + 8
+   //-------------
+   // EAX             ESP + 4
+   //-------------
+   // EDX         <-- ESP
+   //-------------
+
+   mov      12(%esp), %ah    // CheckPoint
+   mov      16(%esp), %dx    // PortReading
+   in       %dx, %al         // signal debugger
+
+   popl     %edx
+   popl     %eax
+   ret
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
new file mode 100644
index 0000000000..288fe7a2fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
@@ -0,0 +1,126 @@
+; @file
+;  This file provides assembly 64-bit atomic reads/writes required for memory initialization.
+;
+; Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+.686p
+.xmm
+.model small, c
+
+.CODE
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioRead64
+;
+;  Description: Read 64 bits from the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioRead64 (
+;  IN  UINTN Address
+;  )
+
+SaMmioRead64    PROC    NEAR    PUBLIC
+   sub     esp, 16
+   movq    [esp], mm0         ;Save mm0 on stack
+   mov     edx,  [esp + 20]   ;edx = Address
+   movq    mm0, [edx]         ;mm0 = [Address]
+   movq    [esp + 8], mm0     ;Store mm0 on Stack
+   movq    mm0, [esp]         ;Restore mm0
+   emms
+   mov     eax, [esp + 8]     ;eax = [Address][31:0]
+   mov     edx, [esp + 12]    ;edx = [Address][64:32]
+   add     esp, 16
+   ret
+SaMmioRead64    ENDP
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioWrite64
+;
+;  Description: Write 64 bits to the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;  @param[in] Value   - The value to write.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioWrite64 (
+;  IN UINTN Address,
+;  IN UINT64 Value
+;  )
+
+SaMmioWrite64    PROC    NEAR    PUBLIC
+   sub     esp, 8
+   movq    [esp], mm0          ;Save mm0 on Stack
+   mov     edx, [esp + 12]     ;edx = Address
+   movq    mm0, [esp + 16]     ;mm0 = Value
+   movq    [edx], mm0          ;[Address] = Value
+   movq    mm0, [esp]          ;Restore mm0
+   emms
+   mov     eax, [esp + 16]     ;eax = Value[31:0]
+   mov     edx, [esp + 20]     ;edx = Value[64:32]
+   add     esp, 8
+   ret
+SaMmioWrite64    ENDP
+
+
+;-----------------------------------------------------------------------------
+;  Intel Silicon View Technology check point interface based on IO port reading
+;
+;  @param CheckPoint        Check point AH value.
+;                           AH = 0x10:  End of MRC State
+;                           AH = 0x20:  End of DXE State
+;                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+;                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD);
+;
+;  @param PortReading       IO port reading address used for breakpoints
+;-----------------------------------------------------------------------------
+
+;VOID
+;EFIAPI
+;IsvtCheckPoint (
+;  IN UINT32          CheckPoint,
+;  IN UINT32          PortReading
+;  )
+
+IsvtCheckPoint    PROC    NEAR    PUBLIC
+   push eax
+   push edx
+
+   ; Stack layout at this point:
+   ;-------------
+   ; PortReading     ESP + 16
+   ;-------------
+   ; CheckPoint      ESP + 12
+   ;-------------
+   ; EIP             ESP + 8
+   ;-------------
+   ; EAX             ESP + 4
+   ;-------------
+   ; EDX         <-- ESP
+   ;-------------
+
+   mov  ah, BYTE PTR [esp + 12]      ; CheckPoint
+   mov  dx, WORD PTR [esp + 16]      ; PortReading
+   in   al, dx                       ; signal debugger
+
+   pop  edx
+   pop  eax
+   ret
+IsvtCheckPoint    ENDP
+
+
+end
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm
new file mode 100644
index 0000000000..da7ef004ad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm
@@ -0,0 +1,118 @@
+; @file
+;  This file provides assembly 64-bit atomic reads/writes required for memory initialization.
+;
+; Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioRead64
+;
+;  Description: Read 64 bits from the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioRead64 (
+;  IN  UINTN Address
+;  )
+
+global ASM_PFX(SaMmioRead64)
+ASM_PFX(SaMmioRead64):
+   sub     esp, 16
+   movq    [esp], mm0         ;Save mm0 on stack
+   mov     edx,  [esp + 20]   ;edx = Address
+   movq    mm0, [edx]         ;mm0 = [Address]
+   movq    [esp + 8], mm0     ;Store mm0 on Stack
+   movq    mm0, [esp]         ;Restore mm0
+   emms
+   mov     eax, [esp + 8]     ;eax = [Address][31:0]
+   mov     edx, [esp + 12]    ;edx = [Address][64:32]
+   add     esp, 16
+   ret
+
+;-----------------------------------------------------------------------------
+;
+;  Section:     SaMmioWrite64
+;
+;  Description: Write 64 bits to the Memory Mapped I/O space.
+;  Use MMX instruction for atomic access, because some MC registers have side effect.
+;
+;  @param[in] Address - Memory mapped I/O address.
+;  @param[in] Value   - The value to write.
+;
+;-----------------------------------------------------------------------------
+
+;UINT64
+;SaMmioWrite64 (
+;  IN UINTN Address,
+;  IN UINT64 Value
+;  )
+
+global ASM_PFX(SaMmioWrite64)
+ASM_PFX(SaMmioWrite64):
+   sub     esp, 8
+   movq    [esp], mm0          ;Save mm0 on Stack
+   mov     edx, [esp + 12]     ;edx = Address
+   movq    mm0, [esp + 16]     ;mm0 = Value
+   movq    [edx], mm0          ;[Address] = Value
+   movq    mm0, [esp]          ;Restore mm0
+   emms
+   mov     eax, [esp + 16]     ;eax = Value[31:0]
+   mov     edx, [esp + 20]     ;edx = Value[64:32]
+   add     esp, 8
+   ret
+
+;-----------------------------------------------------------------------------
+;  Intel Silicon View Technology check point interface based on IO port reading
+;
+;  @param CheckPoint        Check point AH value.
+;                           AH = 0x10:  End of MRC State
+;                           AH = 0x20:  End of DXE State
+;                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
+;                           AH = 0x40:  After OS booting, need a timer SMI trigger to implement (TBD);
+;
+;  @param PortReading       IO port reading address used for breakpoints
+;-----------------------------------------------------------------------------
+
+;VOID
+;EFIAPI
+;IsvtCheckPoint (
+;  IN UINT32          CheckPoint,
+;  IN UINT32          PortReading
+;  )
+
+global ASM_PFX(IsvtCheckPoint)
+ASM_PFX(IsvtCheckPoint):
+   push eax
+   push edx
+
+   ; Stack layout at this point:
+   ;-------------
+   ; PortReading     ESP + 16
+   ;-------------
+   ; CheckPoint      ESP + 12
+   ;-------------
+   ; EIP             ESP + 8
+   ;-------------
+   ; EAX             ESP + 4
+   ;-------------
+   ; EDX         <-- ESP
+   ;-------------
+
+   mov  ah, BYTE [esp + 12]      ; CheckPoint
+   mov  dx, WORD [esp + 16]      ; PortReading
+   in   al, dx                   ; signal debugger
+
+   pop  edx
+   pop  eax
+   ret
+
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules

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

* PchInitDxeCnl - Generic DXE PCH initialization.
* PchInitDxeFspCnl - Generic DXE PCH FSP initialization.
* PchInitSmm - Generic SMM PCH initialization.
* SmmControl - Produces an instance of EFI_SMM_CONTROL2_PROTOCOL.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf            |  99 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf         |  77 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf               | 101 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf     |  54 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf                    |  45 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h                    | 223 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h                 | 187 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h | 132 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c                    | 451 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c                |  33 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c                 | 323 ++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c                    | 554 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c                 | 382 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c                 |  85 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c                    |  89 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c                |  57 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c             | 156 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c        | 156 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c                 | 179 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c                | 298 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c                 | 436 +++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c                |  69 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c | 399 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c                         | 310 +++++++++++
 24 files changed, 4895 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
new file mode 100644
index 0000000000..5e0cf06cb6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
@@ -0,0 +1,99 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE823
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = PchInitEntryPointDxe
+
+
+[LibraryClasses]
+S3BootScriptLib
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PchPciExpressHelpersLib
+UefiBootServicesTableLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+UefiLib
+DxeServicesTableLib
+UefiDriverEntryPoint
+UefiRuntimeServicesTableLib
+AslUpdateLib
+CpuPlatformLib
+GpioLib
+PchSerialIoLib
+PchHdaLib
+PchInitCommonLib
+ConfigBlockLib
+PmcLib
+PmcPrivateLib
+PmcPrivateLibWithS3
+SataLib
+PchDmiWithS3Lib
+PchGbeLib
+SiScheduleResetLib
+BiosLockLib
+DxeSaPolicyLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+
+
+[Sources]
+PchInitDxe.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+PchSerialIoDxe.c
+PchHdaAcpi.c
+PchCnviAcpi.c
+PchAcpi.c
+
+[Protocols]
+gPchNvsAreaProtocolGuid ## PRODUCES
+gPchEmmcTuningProtocolGuid ## PRODUCES
+gEfiPciIoProtocolGuid ## CONSUMES
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiBlockIoProtocolGuid ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## CONSUMES
+gPchPolicyProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gEfiAcpiTableGuid
+gSiConfigHobGuid                 ## CONSUMES
+gPchConfigHobGuid                ## CONSUMES
+gPchRstHobGuid                   ## CONSUMES
+gHdAudioDxeConfigGuid            ## CONSUMES
+gGpioDxeConfigGuid               ## 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/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
new file mode 100644
index 0000000000..528cfd0296
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
@@ -0,0 +1,77 @@
+## @file
+#  Component description file for Pch Initialization driver for FSP package
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = PchInitDxe
+FILE_GUID            = 5AA5031E-4CB6-43D4-B219-FE50FF5D116C
+MODULE_TYPE          = PEIM
+VERSION_STRING       = 1.0
+ENTRY_POINT          = PchInitEntryPointFsp
+
+
+[LibraryClasses]
+PeimEntryPoint
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PchPciExpressHelpersLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+GpioLib
+PchSerialIoLib
+PchInitCommonLib
+S3BootScriptLib  # NULL library
+ConfigBlockLib
+PmcLib
+PmcPrivateLib
+PmcPrivateLibWithS3
+UsbInitLib
+PchDmiWithS3Lib
+PchGbeLib
+SiScheduleResetLib
+BiosLockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Sources]
+PchInitFsp.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+
+
+[Protocols]
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEventReadyToBootGuid
+gSiConfigHobGuid                 ## CONSUMES
+gPchConfigHobGuid                ## CONSUMES
+
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
new file mode 100644
index 0000000000..308da65385
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
@@ -0,0 +1,101 @@
+## @file
+# Component description file for PchInitSmm driver
+#
+# Copyright (c) 2019 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
+PchPciExpressHelpersLib
+SmmServicesTableLib
+PciSegmentLib
+HobLib
+GpioLib
+GpioPrivateLib
+ReportStatusCodeLib
+DevicePathLib
+PmcLib
+PchPcieRpLib
+PchInfoLib
+TimerLib
+ConfigBlockLib
+PmcPrivateLib
+SataLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemSize
+
+
+[Sources]
+PchInitSmm.c
+PchPcieSmm.c
+PchLanSxSmm.c
+PchInitSmm.h
+PchBiosWriteProtect.c
+PchSpiAsync.c
+
+
+[Protocols]
+gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES
+gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
+gPchSmmIoTrapControlGuid ## CONSUMES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+gPchNvsAreaProtocolGuid ## CONSUMES
+gPchPcieSmiDispatchProtocolGuid ## CONSUMES
+gPchTcoSmiDispatchProtocolGuid ## CONSUMES
+gPchSmiDispatchProtocolGuid ## CONSUMES
+gPchEspiSmiDispatchProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## PRODUCES
+
+
+[Guids]
+gSiConfigHobGuid             ## CONSUMES
+gPchConfigHobGuid            ## CONSUMES
+gPchDeviceTableHobGuid
+
+
+[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 # This is for SmmServicesTableLib
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000000..ff712f8635
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,54 @@
+## @file
+# Component description file for SmmControl module
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmControlDriver.h
+SmmControlDriver.c
+
+
+[Protocols]
+gEfiSmmControl2ProtocolGuid ## PRODUCES
+
+
+[Guids]
+gEfiEventVirtualAddressChangeGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
new file mode 100644
index 0000000000..77bd3ad72b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchSpiSmm
+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
+PchSpiCommonLib
+SmmPchPrivateLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSpi.c
+
+
+[Protocols]
+gPchSmmSpiProtocolGuid ## PRODUCES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+
+[Depex]
+gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
+gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
new file mode 100644
index 0000000000..b84c574a2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
@@ -0,0 +1,223 @@
+/** @file
+  Header file for PCH Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_DXE_H_
+#define _PCH_INIT_DXE_H_
+
+#include <Protocol/PchEmmcTuning.h>
+#include <SiConfigHob.h>
+#include <Private/PchConfigHob.h>
+#include <Private/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
+//
+/**
+  Initialize the PCH device according to the PCH Policy HOB
+  and install PCH info instance.
+
+**/
+VOID
+InitializePchDevice (
+  VOID
+  );
+
+/**
+  Common PchInit Module Entry Point
+**/
+VOID
+PchInitEntryPointCommon (
+  VOID
+  );
+
+/**
+  Common PCH initialization on PCI enumeration complete.
+**/
+VOID
+PchOnPciEnumCompleteCommon (
+  VOID
+  );
+
+/**
+  Configures Serial IO Controllers
+
+**/
+EFI_STATUS
+ConfigureSerialIoAtBoot (
+  VOID
+  );
+
+/**
+  Creates device handles for SerialIo devices in ACPI mode
+
+**/
+VOID
+CreateSerialIoHandles (
+  VOID
+  );
+
+/**
+  Mark memory used by SerialIo devices in ACPI mode as allocated
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+AllocateSerialIoMemory (
+  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
+  );
+
+/**
+  Update ASL definitions for SerialIo devices.
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+  VOID
+  );
+
+/**
+  Initialize PCIE SRC clocks in ICC subsystem
+
+  @param[in] GbePortNumber        Number of PCIE rootport assigned to GbE adapter
+
+**/
+VOID
+ConfigurePchPcieClocks (
+  IN UINTN                        GbePortNumber
+  );
+
+/**
+  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
+  );
+
+/**
+  Configure eMMC in HS400 Mode
+
+  @param[in] This                         A pointer to PCH_EMMC_TUNING_PROTOCOL structure
+  @param[in] Revision                     Revision parameter used to verify the layout of EMMC_INFO and TUNINGDATA.
+  @param[in] EmmcInfo                     A pointer to EMMC_INFO structure
+  @param[out] EmmcTuningData              A pointer to EMMC_TUNING_DATA structure
+
+  @retval EFI_SUCCESS                     The function completed successfully
+  @retval EFI_NOT_FOUND                   The item was not found
+  @retval EFI_OUT_OF_RESOURCES            The request could not be completed due to a lack of resources.
+  @retval EFI_INVALID_PARAMETER           A parameter was incorrect.
+  @retval EFI_DEVICE_ERROR                Hardware Error
+  @retval EFI_NO_MEDIA                    No media
+  @retval EFI_MEDIA_CHANGED               Media Change
+  @retval EFI_BAD_BUFFER_SIZE             Buffer size is bad
+  @retval EFI_CRC_ERROR                   Command or Data CRC Error
+**/
+EFI_STATUS
+EFIAPI
+ConfigureEmmcHs400Mode (
+  IN  PCH_EMMC_TUNING_PROTOCOL          *This,
+  IN  UINT8                             Revision,
+  IN  EMMC_INFO                         *EmmcInfo,
+  OUT EMMC_TUNING_DATA                  *EmmcTuningData
+  );
+
+/**
+  Get eMMC PCI cfg space address
+
+  @return UINT64  PCI base address
+**/
+UINT64
+ScsGetEmmcBaseAddress (
+  VOID
+  );
+
+/**
+  Perform the remaining configuration on PCH SATA to perform device detection,
+  then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+  @retval None
+**/
+VOID
+ConfigurePchSataOnEndOfDxe (
+  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
+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
+  );
+
+/**
+  Initialize PCH Nvs Area opeartion region.
+
+**/
+VOID
+PatchPchNvsAreaAddress (
+  VOID
+  );
+
+#endif // _PCH_INIT_DXE_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
new file mode 100644
index 0000000000..693c5d3f50
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
@@ -0,0 +1,187 @@
+/** @file
+  Header file for PCH Init SMM Handler
+
+  Copyright (c) 2019 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/PchEspiLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Private/Library/PchPciExpressHelpersLib.h>
+#include <Protocol/PchPcieSmiDispatch.h>
+#include <Protocol/PchTcoSmiDispatch.h>
+#include <Protocol/PchSmiDispatch.h>
+#include <Protocol/PchEspiSmiDispatch.h>
+#include <Protocol/PchSmmIoTrapControl.h>
+#include <Private/Protocol/PchNvsArea.h>
+#include <Private/Protocol/PcieIoTrap.h>
+#include <SiConfigHob.h>
+#include <Private/PchConfigHob.h>
+#include <Private/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
+  );
+
+/**
+  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
+  );
+
+/**
+  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/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000000..08e64fa5a7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,132 @@
+/** @file
+  Header file for SMM Control Driver.
+
+  Copyright (c) 2019 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
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
new file mode 100644
index 0000000000..bcbdb12dc3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
@@ -0,0 +1,451 @@
+/** @file
+  This is the driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 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 <IndustryStandard/Pci.h>
+
+#include "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/GpioDevConfig.h>
+#include <ConfigBlock/ScsConfig.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchGbeLib.h>
+#include <Private/PchRstHob.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SataLib.h>
+#include <Register/PchRegsSata.h>
+#include <TraceHubCommonConfig.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegsTraceHub.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA_PROTOCOL    mPchNvsAreaProtocol;
+
+/**
+  Retrieve interrupt information about a PCH device from policy
+
+  @param[in] Device                     PCI device number
+
+  @retval PCH_DEVICE_INTERRUPT_CONFIG   structure with device's interrupt information
+**/
+PCH_DEVICE_INTERRUPT_CONFIG
+GetInterruptPolicy (
+  IN PCH_SERIAL_IO_CONTROLLER  Device
+  )
+{
+  PCH_DEVICE_INTERRUPT_CONFIG EmptyRecord;
+  UINT8                       DevNum;
+  UINT8                       FuncNum;
+  UINT8                       Index;
+
+  ZeroMem (&EmptyRecord, sizeof (PCH_DEVICE_INTERRUPT_CONFIG));
+  DevNum  = GetSerialIoDeviceNumber (Device);
+  FuncNum = GetSerialIoFunctionNumber (Device);
+
+  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.
+
+  @retval EFI_SUCCESS                   The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Index;
+
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    mPchNvsAreaProtocol.Area->SMD[Index] = mPchConfigHob->SerialIo.DevMode[Index];
+    mPchNvsAreaProtocol.Area->SIR[Index] = (GetInterruptPolicy (Index)).Irq;
+    mPchNvsAreaProtocol.Area->SB0[Index] = (UINT32) FindSerialIoBar (Index, 0);
+    mPchNvsAreaProtocol.Area->SB1[Index] = (UINT32) FindSerialIoBar (Index, 1);
+  }
+  if (IsPchH ()) {
+    mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C4] = PchSerialIoDisabled;
+    mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C5] = PchSerialIoDisabled;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Update NVS Area after RST PCIe Storage Remapping and before Boot
+**/
+VOID
+PchUpdateNvsAreaAfterRemapping (
+  VOID
+  )
+{
+  UINTN                 Index;
+  VOID                  *Hob;
+  PCH_RST_HOB           *RstHob;
+
+  Hob = GetFirstGuidHob (&gPchRstHobGuid);
+  if (Hob == NULL) {
+    DEBUG (( DEBUG_INFO , "PchUpdateNvsAreaAfterRemapping: cannot fetch RstHob" ));
+    return;
+  }
+
+  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;
+  }
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS  Status;
+
+  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 ();
+
+  //
+  // Update Pch Nvs Area
+  //
+  Status = PchUpdateNvsArea ();
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  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
+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 ();
+
+  //
+  // 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 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;
+  PCH_GPIO_DXE_CONFIG   *GpioDxeConfig;
+
+  ///
+  /// 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++) {
+    Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFun);
+    ASSERT_EFI_ERROR (Status);
+
+    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].LtrMaxSnoopLatency;
+    mPchNvsAreaProtocol.Area->PcieLtrMaxNoSnoopLatency[Index] = mPchConfigHob->PcieRp.RootPort[Index].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 PMC ACPIBASE and PWRMBASE
+  //
+  mPchNvsAreaProtocol.Area->PMBS = PmcGetAcpiBase ();
+
+  mPchNvsAreaProtocol.Area->PWRM = PmcGetPwrmBase ();
+
+  //
+  // 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
+  //
+  // Update eMMC HS400 mode enablement
+  //
+  mPchNvsAreaProtocol.Area->EMH4 = (UINT8) mPchConfigHob->Scs.ScsEmmcHs400Enabled;
+  mPchNvsAreaProtocol.Area->EmmcEnabled = (UINT8) mPchConfigHob->Scs.ScsEmmcEnabled;
+
+  //
+  // Update eMMC Driver Strength
+  // Per eMMC 5.01 JEDEC Specification (JESD84-B50.1, Table 186)
+  // Nominal Impedance - Driver Type Values:
+  // 50 Ohm              0x0
+  // 33 Ohm              0x1
+  // 40 Ohm              0x4
+  //
+  switch (mPchConfigHob->Scs.ScsEmmcHs400DriverStrength) {
+    case DriverStrength33Ohm:
+      mPchNvsAreaProtocol.Area->EMDS = 0x1;
+      break;
+    case DriverStrength40Ohm:
+      mPchNvsAreaProtocol.Area->EMDS = 0x4;
+      break;
+    case DriverStrength50Ohm:
+    default:
+      mPchNvsAreaProtocol.Area->EMDS = 0x0;
+  }
+
+  mPchNvsAreaProtocol.Area->SdPowerEnableActiveHigh = (UINT8) mPchConfigHob->Scs.ScsSdPowerEnableActiveHigh;
+  mPchNvsAreaProtocol.Area->SdCardEnabled           = (UINT8) mPchConfigHob->Scs.ScsSdCardEnabled;
+
+  //
+  // SATA configuration.
+  //
+  if (PciSegmentRead16 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+    mPchNvsAreaProtocol.Area->SataPortPresence = 0;
+  } else {
+    mPchNvsAreaProtocol.Area->SataPortPresence = PciSegmentRead8 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + R_SATA_CFG_PCS + 2);
+  }
+
+  //
+  // CPU SKU
+  //
+  mPchNvsAreaProtocol.Area->CpuSku = GetCpuSku ();
+
+  mPchNvsAreaProtocol.Area->SlpS0VmRuntimeControl = (UINT8)mPchConfigHob->Pm.SlpS0VmRuntimeControl;
+  mPchNvsAreaProtocol.Area->SlpS0Vm070VSupport    = (UINT8)mPchConfigHob->Pm.SlpS0Vm070VSupport;
+  mPchNvsAreaProtocol.Area->SlpS0Vm075VSupport    = (UINT8)mPchConfigHob->Pm.SlpS0Vm075VSupport;
+  mPchNvsAreaProtocol.Area->PsOnEnable            = (UINT8)mPchConfigHob->Pm.PsOnEnable;
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    mPchNvsAreaProtocol.Area->LtrEnable[Index]  = (UINT8)mPchConfigHob->PcieRp.RootPort[Index].LtrEnable;
+  }
+
+  mPchNvsAreaProtocol.Area->GBES = PchIsGbePresent ();
+
+  //
+  // Update PCH Trace Hub Mode
+  //
+  mPchNvsAreaProtocol.Area->PchTraceHubMode     = (UINT8) mPchConfigHob->PchTraceHub.PchTraceHubMode;
+  //
+  // if SCRPD0[24] is set, force TH to be host debugger mode.
+  //
+  if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS) != 0xFFFFFFFF) {
+    if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS + R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0) & BIT24) {
+      mPchNvsAreaProtocol.Area->PchTraceHubMode = TraceHubModeHostDebugger;
+    }
+  }
+
+  //
+  // Update TWMB, Temp memory base address
+  //
+  mPchNvsAreaProtocol.Area->TempRsvdMemBase = (UINT32) PcdGet32 (PcdSiliconInitTempMemBaseAddr);
+
+  return Status;
+}
+
+/**
+  Initialize PCH Nvs Area opeartion region.
+
+**/
+VOID
+PatchPchNvsAreaAddress (
+  VOID
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Address;
+  UINT16                                Length;
+
+  Status = InitializeAslUpdateLib ();
+  ASSERT_EFI_ERROR (Status);
+
+  Address = (UINT32) (UINTN) mPchNvsAreaProtocol.Area;
+  Length  = (UINT16) sizeof (PCH_NVS_AREA);
+  DEBUG ((DEBUG_INFO, "PatchPchNvsAreaAddress: PCH NVS Address %x Length %x\n", Address, Length));
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','B'), &Address, sizeof (Address));
+  ASSERT_EFI_ERROR (Status);
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','L'), &Length, sizeof (Length));
+  ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
new file mode 100644
index 0000000000..4e38db1027
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
@@ -0,0 +1,33 @@
+/** @file
+  Initializes PCH CNVi device ACPI data.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include "PchInit.h"
+#include <Library/DxeSaPolicyLib.h>
+
+/**
+  Update ASL definitions for CNVi device.
+
+  @retval EFI_SUCCESS         The function completed successfully
+**/
+EFI_STATUS
+UpdateCnviAcpiData (
+  VOID
+  )
+{
+
+  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() Start\n"));
+
+  mPchNvsAreaProtocol.Area->CnviMode = (UINT8) mPchConfigHob->Cnvi.Mode;
+
+  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
new file mode 100644
index 0000000000..57f2e1dca0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
@@ -0,0 +1,323 @@
+/** @file
+  Initializes the PCH HD Audio ACPI Tables.
+
+  Copyright (c) 2019 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 "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/HdAudioConfig.h>
+#include <Private/PchConfigHob.h>
+#include <Library/PchInfoLib.h>
+#include <Private/Library/PchHdaLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsHda.h>
+
+PCH_HDA_NHLT_ENDPOINTS mPchHdaNhltEndpoints[HdaEndpointMax] =
+{
+  {HdaDmicX1,     B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT,                                              0, FALSE},
+  {HdaDmicX2,     (B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT),        0, FALSE},
+  {HdaDmicX4,     (B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT),        0, FALSE},
+  {HdaBtRender,   (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT | B_HDA_BT_A2DP_FORMAT), 0, FALSE},
+  {HdaBtCapture,  (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT),                        0, FALSE},
+  {HdaI2sRender1, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO,      FALSE},
+  {HdaI2sRender2, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO,      FALSE},
+  {HdaI2sCapture, B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_CAPTURE_DEVICE_INFO,    FALSE}
+};
+
+#define DSP_FW_STOLEN_MEMORY_SIZE 0x400000 //4MB
+/**
+  Allocates 4MB of memory for DSP FW usage.
+
+  @retval EFI_PHYSICAL_ADDRESS  Allocated memory address
+**/
+EFI_PHYSICAL_ADDRESS
+AllocateAudioDspStolenMemory (
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PHYSICAL_ADDRESS DspStolenMemBaseAddress;
+
+  DspStolenMemBaseAddress = 0;
+
+  DEBUG ((DEBUG_INFO, "AllocateAudioDspStolenMemory()\n"));
+
+  //
+  // Reserve memory to store Acpi Debug data.
+  //
+  DspStolenMemBaseAddress = 0xFFFFFFFF;
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  EfiReservedMemoryType,
+                  EFI_SIZE_TO_PAGES (DSP_FW_STOLEN_MEMORY_SIZE),
+                  &DspStolenMemBaseAddress
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  ZeroMem ((VOID *) (UINTN) DspStolenMemBaseAddress, DSP_FW_STOLEN_MEMORY_SIZE);
+
+  mPchNvsAreaProtocol.Area->DSPM = (UINT32) DspStolenMemBaseAddress;
+  DEBUG ((DEBUG_INFO, "mPchNvsAreaProtocol.Area->DSPM = 0x%016x\n", mPchNvsAreaProtocol.Area->DSPM));
+
+  return DspStolenMemBaseAddress;
+}
+
+/**
+  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->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) {
+      break;
+    }
+  }
+
+  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;
+}
+
+/**
+  Constructs and installs NHLT table.
+
+  @retval EFI_SUCCESS       ACPI Table installed successfully
+  @retval EFI_UNSUPPORTED   ACPI Table protocol not found
+**/
+EFI_STATUS
+PublishNhltAcpiTable (
+  VOID
+  )
+{
+  UINTN                                     AcpiTableKey;
+  EFI_ACPI_TABLE_PROTOCOL                   *AcpiTable;
+  NHLT_ACPI_TABLE                           *NhltTable;
+  UINT32                                    TableLength;
+  EFI_STATUS                                Status;
+
+  AcpiTable = NULL;
+  NhltTable = NULL;
+  AcpiTableKey = 0;
+
+  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n"));
+
+  //
+  // Locate ACPI support protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+  if ( EFI_ERROR (Status) || AcpiTable == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  NhltConstructor (mPchHdaNhltEndpoints, &NhltTable, &TableLength);
+  NhltAcpiHeaderConstructor (NhltTable, TableLength);
+
+  Status = AcpiTable->InstallAcpiTable (AcpiTable, NhltTable, NhltTable->Header.Length, &AcpiTableKey);
+
+  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n"));
+  return Status;
+}
+
+/**
+  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 PCH_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->NHLA = NhltAcpiTableAddress;
+  mPchNvsAreaProtocol.Area->NHLL = NhltAcpiTableLength;
+  mPchNvsAreaProtocol.Area->ADFM = HdAudioDxeConfig->DspFeatureMask;
+  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;
+}
+
+/**
+  Initialize and publish NHLT (Non-HDA Link Table), update NVS variables.
+
+  @param[in]                *HdAudioConfigHob
+  @param[in]                *HdAudioDxeConfig
+
+  @retval EFI_SUCCESS    The function completed successfully
+**/
+EFI_STATUS
+SetHdaAcpiTable (
+  IN CONST HDAUDIO_HOB            *HdAudioConfigHob,
+  IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
+  )
+{
+  NHLT_ACPI_TABLE     *NhltTable;
+  EFI_STATUS          Status;
+  NhltTable = NULL;
+
+  Status = EFI_SUCCESS;
+
+  if (HdAudioDxeConfig->NhltDefaultFlow == TRUE) {
+    switch (HdAudioDxeConfig->DspEndpointDmic) {
+      case PchHdaDmic1chArray:
+        mPchHdaNhltEndpoints[HdaDmicX1].Enable   = TRUE;
+        break;
+      case PchHdaDmic2chArray:
+        mPchHdaNhltEndpoints[HdaDmicX2].Enable   = TRUE;
+        break;
+      case PchHdaDmic4chArray:
+        mPchHdaNhltEndpoints[HdaDmicX4].Enable   = TRUE;
+        break;
+      case PchHdaDmicDisabled:
+      default:
+        mPchHdaNhltEndpoints[HdaDmicX2].Enable   = FALSE;
+        mPchHdaNhltEndpoints[HdaDmicX4].Enable   = FALSE;
+    }
+
+    if (HdAudioDxeConfig->DspEndpointBluetooth) {
+      mPchHdaNhltEndpoints[HdaBtRender].Enable   = TRUE;
+      mPchHdaNhltEndpoints[HdaBtCapture].Enable  = TRUE;
+    }
+
+    if (HdAudioDxeConfig->DspEndpointI2s) {
+      mPchHdaNhltEndpoints[HdaI2sRender1].Enable = TRUE;
+      mPchHdaNhltEndpoints[HdaI2sRender2].Enable = TRUE;
+      mPchHdaNhltEndpoints[HdaI2sCapture].Enable = TRUE;
+    }
+
+    Status    = PublishNhltAcpiTable ();
+  }
+  NhltTable = LocateNhltAcpiTable ();
+  if (NhltTable == NULL) {
+    return EFI_LOAD_ERROR;
+  }
+
+  UpdateHdaAcpiData ((UINT64) (UINTN) NhltTable, (UINT32) (NhltTable->Header.Length), HdAudioConfigHob, HdAudioDxeConfig);
+
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    AllocateAudioDspStolenMemory ();
+  }
+
+  DEBUG_CODE ( NhltAcpiTableDump (NhltTable); );
+  return Status;
+}
+
+/**
+  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;
+  PCH_HDAUDIO_DXE_CONFIG        *HdAudioDxeConfig;
+
+
+  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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_HDA,
+                 PCI_FUNCTION_NUMBER_PCH_HDA,
+                 0
+                 );
+
+  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;
+  }
+
+  Status = SetHdaAcpiTable (HdAudioConfigHob, HdAudioDxeConfig);
+
+  DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", Status));
+  return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
new file mode 100644
index 0000000000..55f1e086fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
@@ -0,0 +1,554 @@
+/** @file
+  This is the Common driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/SiScheduleResetLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/BiosLockLib.h>
+#include <Library/PchPcrLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsPmc.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB           *mPchConfigHob;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA       *mSiConfigHobData;
+
+//
+// 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);
+
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  ASSERT (HobPtr.Guid != NULL);
+  mSiConfigHobData = (SI_CONFIG_HOB_DATA *) 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   = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      PCI_DEVICE_NUMBER_PCH_SPI,
+                      PCI_FUNCTION_NUMBER_PCH_SPI,
+                      0
+                      );
+
+  //
+  // Check for SPI controller presence before programming
+  //
+  if (PciSegmentRead32 (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);
+
+  //
+  // 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)
+    );
+}
+
+/**
+  Process all the lock downs
+**/
+VOID
+ProcessAllLocks (
+  VOID
+  )
+{
+  UINT8         Data8;
+  UINT16        Data16And;
+  UINT16        Data16Or;
+  UINT32        Data32And;
+  UINT32        Data32Or;
+  UINT64        PciLpcRegBase;
+  UINT16        TcoBase;
+  UINT64        PciSpiRegBase;
+
+  PciLpcRegBase   = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      PCI_DEVICE_NUMBER_PCH_LPC,
+                      PCI_FUNCTION_NUMBER_PCH_LPC,
+                      0
+                      );
+  PciSpiRegBase   = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      PCI_DEVICE_NUMBER_PCH_SPI,
+                      PCI_FUNCTION_NUMBER_PCH_SPI,
+                      0
+                      );
+
+  PchTcoBaseGet (&TcoBase);
+
+  //
+  // Lock function disable (ST and NST PG) register fields.
+  //
+  PmcLockFunctionDisableConfigWithS3BootScript ();
+
+  ///
+  /// PCH BWG Additional PCH DMI and OP-DMI Programming Steps
+  /// Lock DMI.
+  ///
+    PchDmiSetLockWithS3BootScript ();
+
+  //
+  // Lock SPI register before boot.
+  //
+  LockSpiConfiguration ();
+
+  ///
+  /// Additional Power Management Programming
+  /// Step 3
+  /// Lock configuration after stretch and ACPI base programming completed.
+  ///
+  PmcLockSlpSxStretchingPolicyWithS3BootScript ();
+
+  //
+  // Set BiosLock.
+  //
+  if (mPchConfigHob->LockDown.BiosLock == TRUE) {
+    BiosLockEnable ();
+  }
+
+  ///
+  /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+  /// 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]).
+  /// 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 (mPchConfigHob->LockDown.BiosInterface == TRUE) {
+    //
+    // LPC
+    //
+    PciSegmentOr8 ((UINT64) (PciLpcRegBase + R_LPC_CFG_BC), (UINT32) B_LPC_CFG_BC_BILD);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC)
+      );
+
+    //
+    // Reads back for posted write to take effect
+    //
+    Data8 = PciSegmentRead8 ((UINTN) (PciLpcRegBase + R_LPC_CFG_BC));
+    S3BootScriptSaveMemPoll  (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC,
+      &Data8,  // BitMask
+      &Data8,  // BitValue
+      1,       // Duration
+      1        // LoopTimes
+      );
+
+    //
+    // SPI
+    //
+    PciSegmentOr8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC), (UINT32) B_SPI_CFG_BC_BILD);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC)
+      );
+
+    //
+    // Reads back for posted write to take effect
+    //
+    Data8 = PciSegmentRead8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC));
+    S3BootScriptSaveMemPoll  (
+      S3BootScriptWidthUint8,
+      PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
+      &Data8,     // BitMask
+      &Data8,     // BitValue
+      1,          // Duration
+      1           // LoopTimes
+      );
+
+    ///
+    /// Set BIOS interface Lock-Down
+    ///
+    PchDmiSetBiosLockDownWithS3BootScript ();
+  }
+
+  ///
+  /// PCH BIOS Spec on using RTC RAM
+  /// Regardless of BUC.TS being updated or not, BIOS must set RC.BILD bit PCR[RTC] + 3400h[31] before exit
+  /// For Data integrity protection, set RTC Memory locks (Upper 128 Byte Lock and
+  /// Lower 128 Byte Lock) at PCR[RTC] + 3400h[4] and PCR[RTC] + 3400h[3].
+  /// Note once locked bytes 0x38 - 0x3F in each of the Upper and Lower Byte blocks, respectively,
+  /// cannot be unlocked until next reset.
+  ///
+  Data32And = 0xFFFFFFFF;
+  Data32Or = 0x0;
+
+  if (mPchConfigHob->LockDown.BiosInterface == TRUE) {
+    Data32Or  = B_RTC_PCR_CONF_BILD;
+  }
+  if (mPchConfigHob->LockDown.RtcMemoryLock == TRUE) {
+    Data32Or |= (B_RTC_PCR_CONF_UCMOS_LOCK | B_RTC_PCR_CONF_LCMOS_LOCK);
+  }
+  PchPcrAndThenOr32 (
+    PID_RTC_HOST, R_RTC_PCR_CONF,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_RTC_HOST, R_RTC_PCR_CONF,
+    &Data32Or,
+    &Data32And
+    );
+
+  ///
+  ///  Remove access to RTC PCRs
+  ///
+  Data32And = (UINT32)~(BIT0);
+  Data32Or  = 0;
+  PchPcrAndThenOr32 (
+    PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
+    &Data32Or,
+    &Data32And
+    );
+  PchPcrAndThenOr32 (
+    PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
+    &Data32Or,
+    &Data32And
+    );
+
+  //
+  // Lock Down TCO
+  //
+  Data16And = 0xFFFF;
+  Data16Or  = B_TCO_IO_TCO1_CNT_LOCK;
+  IoOr16 (TcoBase + R_TCO_IO_TCO1_CNT, Data16Or);
+  S3BootScriptSaveIoReadWrite (
+    S3BootScriptWidthUint16,
+    (UINTN) (TcoBase + R_TCO_IO_TCO1_CNT),
+    &Data16Or,  // Data to be ORed
+    &Data16And  // Data to be ANDed
+    );
+
+  ///
+  /// PCH BIOS Spec Section 5.15.1 Additional Chipset Initialization
+  /// Step 1
+  /// Lock PMC Set Strap Message Interface
+  ///
+  PmcLockSetStrapMsgInterfaceWithS3BootScript ();
+  //
+  // Lock Down PMC
+  //
+  PmcLockWithS3BootScript ();
+}
+
+/**
+  Set eSPI BME bit
+**/
+VOID
+ConfigureEspiBme (
+  VOID
+  )
+{
+  UINT64 EspiPciBase;
+
+  EspiPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPC,
+                  PCI_FUNCTION_NUMBER_PCH_LPC,
+                  0
+                  );
+
+  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);
+  }
+}
+
+/**
+  Common PCH initialization before Boot Sript Table is closed
+
+**/
+VOID
+PchOnPciEnumCompleteCommon (
+  VOID
+  )
+{
+  UINT32                                    Data32Or;
+  UINT32                                    Data32And;
+  BOOLEAN                                   ResetStatus;
+
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() Start\n"));
+
+  if (SiScheduleResetIsRequired ()) {
+    ResetStatus = SiScheduleResetPerformReset ();
+    ASSERT (!ResetStatus);
+  }
+
+  ProcessAllLocks ();
+
+  //
+  // Perform remaining configuration for PCH SATA on End of DXE
+  //
+  ConfigurePchSataOnEndOfDxe ();
+  //
+  // PSTHCTL (0xD00h[2]) = 1, PSTH IOSF Primary Trunk Clock Gating Enable (PSTHIOSFPTCGE)
+  //
+  Data32And = 0xFFFFFFFF;
+  Data32Or =  B_PSTH_PCR_PSTHIOSFPTCGE;
+  PchPcrAndThenOr32 (PID_PSTH, R_PSTH_PCR_PSTHCTL, Data32And, Data32Or);
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_PSTH, R_PSTH_PCR_PSTHCTL,
+    &Data32Or,
+    &Data32And
+    );
+
+  //
+  // Set eSPI BME after PCI enumeration
+  //
+  ConfigureEspiBme ();
+
+  ///
+  /// Clear Global Reset Status, Power Failure and Host Reset Status bits
+  ///
+  PmcClearGlobalResetStatus ();
+  PmcClearPowerFailureStatus ();
+  PmcClearHostResetStatus ();
+
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
new file mode 100644
index 0000000000..b106c849e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
@@ -0,0 +1,382 @@
+/** @file
+  This is the Uefi driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 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 <Private/Protocol/PcieIoTrap.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchPciExpressHelpersLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcie.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsThermalCnl.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 = PciePmTrap;
+    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;
+  UINT64              ThermalPciBase;
+
+  ///
+  /// 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);
+
+  //
+  // Enable Thermal MSE
+  //
+  ThermalPciBase = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_THERMAL,
+                     PCI_FUNCTION_NUMBER_PCH_THERMAL,
+                     0
+                     );
+  if (PciSegmentRead16 (ThermalPciBase + PCI_VENDOR_ID_OFFSET) != 0xFFFF) {
+    if (((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBAR) & B_THERMAL_CFG_MEM_TBAR_MASK) != 0) ||
+        ((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBARH) != 0))) {
+      PciSegmentOr8 (ThermalPciBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+    }
+  }
+
+  ReconfigurePciePowerManagementForS3 ();
+  ProcessSmiLocks ();
+#ifndef FSP_WRAPPER_FLAG
+  PchOnPciEnumCompleteCommon ();
+#endif
+  ConfigureSerialIoAtS3Resume ();
+}
+
+/**
+  Register callback functions for PCH DXE.
+**/
+VOID
+PchRegisterNotifications (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   LegacyBootEvent;
+  EFI_EVENT   ExitBootServicesEvent;
+  VOID        *Registration;
+
+  ///
+  /// Create PCI Enumeration Completed callback for PCH
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    PchOnPciEnumComplete,
+    NULL,
+    &Registration
+    );
+
+  //
+  // 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);
+}
+
+/**
+  Initialize the PCH device according to the PCH Policy HOB
+  and install PCH info instance.
+**/
+VOID
+InitializePchDevice (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "InitializePchDevice() Start\n"));
+
+  DEBUG ((DEBUG_INFO, "InitializePchDevice() End\n"));
+}
+/**
+  <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 ();
+
+  InitializePchDevice ();
+
+  Status = PchAcpiInit (ImageHandle);
+
+  CreateSerialIoHandles ();
+
+  PchRegisterNotifications ();
+
+  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, PciePmTrap);
+  } else {
+    ASSERT (FALSE);
+  }
+
+  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() End\n"));
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
new file mode 100644
index 0000000000..15fe4628fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
@@ -0,0 +1,85 @@
+/** @file
+  This is the FSP driver that initializes the Intel PCH.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include "PchInit.h"
+
+EFI_STATUS
+EFIAPI
+PchOnPciEnumCompleteFsp (
+  IN  EFI_PEI_SERVICES            **PeiServices,
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN  VOID                        *Ppi
+  );
+
+STATIC
+EFI_PEI_NOTIFY_DESCRIPTOR  mPchOnPciEnumCompleteNotifyList[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK  | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    PchOnPciEnumCompleteFsp
+  }
+};
+
+/**
+  <b>FSP PchInit Module Entry Point for FSP</b>\n
+
+  @param[in] FileHandle      PEIM's file handle
+  @param[in] PeiServices     An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPointFsp (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() Start\n"));
+
+  PchInitEntryPointCommon ();
+
+  Status = PeiServicesNotifyPpi (mPchOnPciEnumCompleteNotifyList);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() End\n"));
+
+  return Status;
+}
+
+/**
+  Fsp PCH initialization on PCI enumeration complete
+
+  @param[in]  PeiServices       An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+  @param[in]  NotifyDescriptor  Address of the notification descriptor data structure.
+  @param[in]  Ppi               Address of the PPI that was installed.
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchOnPciEnumCompleteFsp (
+  IN  EFI_PEI_SERVICES            **PeiServices,
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN  VOID                        *Ppi
+  )
+{
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() Start\n"));
+
+  PchOnPciEnumCompleteCommon ();
+
+  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() End\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
new file mode 100644
index 0000000000..6e30280fa7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
@@ -0,0 +1,89 @@
+/** @file
+  Perform related functions for PCH Sata in DXE phase
+
+  Copyright (c) 2019 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 <Register/PchRegsSata.h>
+
+/**
+  Perform the remaining configuration on PCH SATA to perform device detection,
+  then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+  @retval None
+**/
+VOID
+ConfigurePchSataOnEndOfDxe (
+  VOID
+  )
+{
+  UINT64        PciSataRegBase;
+  UINT16        SataPortsEnabled;
+  UINT32        DwordReg;
+  UINTN         Index;
+  UINT32        SataCtrlIndex;
+
+  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); 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    = GetSataRegBase (SataCtrlIndex);
+    SataPortsEnabled  = 0;
+
+    DwordReg = PciSegmentRead32 (PciSataRegBase + R_SATA_CFG_PCS);
+    for (Index = 0; Index < GetPchMaxSataPortNum (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 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_MAP,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + 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 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_PCS,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + 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 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC)
+      );
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
new file mode 100644
index 0000000000..d0f4b4fa56
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
@@ -0,0 +1,57 @@
+/** @file
+  Initializes Serial IO Controllers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include "PchInit.h"
+#include <Library/PchSerialIoLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsSerialIo.h>
+
+/**
+  Puts all SerialIo controllers (except UARTs in debug mode) in D3
+  Clears MemoryEnable for all PCI-mode controllers
+**/
+EFI_STATUS
+ConfigureSerialIoAtBoot (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Index;
+  UINTN                    PciCfgBase;
+
+  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
+      if (IsSerialIoFunctionZero (Index)) {
+        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
+          PciCfgBase = FindSerialIoBar (Index,1);
+          MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
+        }
+      }
+      continue;
+    }
+    if ((Index >= PchSerialIoIndexUart0) &&
+        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
+        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
+      continue;
+    }
+    PciCfgBase = FindSerialIoBar (Index,1);
+    MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
+    MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
+      MmioAnd32 (PciCfgBase + PCI_COMMAND_OFFSET, (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) );
+      if (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0)) {
+        continue;
+      }
+      MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, 0);
+      MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
new file mode 100644
index 0000000000..5563d82076
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
@@ -0,0 +1,156 @@
+/** @file
+  Initializes Serial IO Controllers.
+
+  Copyright (c) 2019 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/S3BootScriptLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+
+#include "PchInit.h"
+#include <Library/PchSerialIoLib.h>
+#include <Library/DevicePathLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsSerialIo.h>
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH          RootPort;
+  ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
+  CHAR8                         HidString[8];
+  CHAR8                         UidString;
+  CHAR8                         CidString;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} SERIALIO_DEVICE_PATH;
+
+#define gPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof(ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
+#define gAcpiDev {{ACPI_DEVICE_PATH,ACPI_EXTENDED_DP,{(UINT8)(sizeof(ACPI_EXTENDED_HID_DEVICE_PATH)+SERIALIO_TOTAL_ID_LENGTH),0}},0,0,0}
+#define gEndEntire {END_DEVICE_PATH_TYPE,END_ENTIRE_DEVICE_PATH_SUBTYPE,{END_DEVICE_PATH_LENGTH,0}}
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_DEVICE_PATH gSerialIoPath = {
+  gPciRootBridge,
+  gAcpiDev,
+  "\0\0\0\0\0\0\0",
+  '\0',
+  '\0',
+  gEndEntire
+};
+
+/**
+Mark memory used by SerialIo devices in ACPI mode as allocated
+
+@retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+AllocateSerialIoMemory (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER i;
+  UINT8                    BarNumber;
+  UINTN                    Bar;
+  EFI_STATUS               Status;
+
+  for (i=0; i<PchSerialIoIndexMax; i++) {
+    if (mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoHidden ||
+        mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoAcpi) {
+      for (BarNumber = 0; BarNumber<=1; BarNumber++) {
+        Bar = FindSerialIoBar (i,BarNumber);
+        Status = gDS->AddMemorySpace (
+                        EfiGcdMemoryTypeReserved,
+                        Bar,
+                        V_SERIAL_IO_CFG_BAR_SIZE,
+                        0
+                        );
+        ASSERT_EFI_ERROR (Status);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        Status = gDS->AllocateMemorySpace (
+                        EfiGcdAllocateAddress,
+                        EfiGcdMemoryTypeReserved,
+                        N_SERIAL_IO_CFG_BAR_ALIGNMENT,
+                        V_SERIAL_IO_CFG_BAR_SIZE,
+                        &Bar,
+                        mImageHandle,
+                        NULL
+                        );
+        ASSERT_EFI_ERROR (Status);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+VOID
+CreateSerialIoHandles (
+  VOID
+  )
+{
+  EFI_HANDLE NewHandle;
+  EFI_DEVICE_PATH_PROTOCOL *NewPath;
+  UINT32 Controller;
+
+  for (Controller = 0; Controller < PchSerialIoIndexMax; Controller++) {
+    if (mPchConfigHob->SerialIo.DevMode[Controller] == PchSerialIoAcpi) {
+      NewHandle = NULL;
+      CopyMem (gSerialIoPath.HidString, GetSerialIoAcpiHid (Controller), SERIALIO_HID_LENGTH);
+      NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&gSerialIoPath);
+      gBS->InstallMultipleProtocolInterfaces (
+             &NewHandle,
+             &gEfiDevicePathProtocolGuid,
+             NewPath,
+             NULL );
+    }
+  }
+}
+
+/**
+  Puts all SerialIo controllers (except UARTs in debug mode) in D3.
+  Clears MemoryEnable for all PCI-mode controllers on S3 resume
+**/
+VOID
+ConfigureSerialIoAtS3Resume (
+  VOID
+  )
+{
+  PCH_SERIAL_IO_CONTROLLER Index;
+  UINTN                    PciCfgBase;
+  UINT32                   Data32;
+
+  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
+      if (IsSerialIoFunctionZero (Index)) {
+        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
+          PciCfgBase = FindSerialIoBar (Index,1);
+          Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+          Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
+          S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
+        }
+      }
+      continue;
+    }
+    if ((Index >= PchSerialIoIndexUart0) &&
+        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
+        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
+      continue;
+    }
+    PciCfgBase = FindSerialIoBar (Index,1);
+    Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+    Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
+    S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
+    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
+      Data32 = MmioRead32 (PciCfgBase + PCI_COMMAND_OFFSET);
+      Data32 &= (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
+      S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + PCI_COMMAND_OFFSET, 1, &Data32);
+    }
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
new file mode 100644
index 0000000000..7fe1567c9f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
@@ -0,0 +1,156 @@
+/** @file
+  PCH BIOS Write Protect Driver.
+
+  Copyright (c) 2019 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/PchRegsSpi.h>
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_TCO_SMI_DISPATCH_PROTOCOL     *mPchTcoSmiDispatchProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64                            mSpiRegBase;
+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
+  )
+{
+  //
+  // Disable BIOSWE bit to protect BIOS
+  //
+  PciSegmentAnd8 ((UINTN) (mSpiRegBase + R_SPI_CFG_BC), (UINT8) ~B_SPI_CFG_BC_WPD);
+}
+
+/**
+  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;
+  }
+
+  mSpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_SPI,
+                  PCI_FUNCTION_NUMBER_PCH_SPI,
+                  0
+                  );
+
+  mLpcRegBase = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_LPC,
+                   PCI_FUNCTION_NUMBER_PCH_LPC,
+                   0
+                   );
+
+  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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
new file mode 100644
index 0000000000..e9f4c91ed4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
@@ -0,0 +1,179 @@
+/** @file
+  PCH Init Smm module for PCH specific SMI handlers.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/RegsUsb.h>
+#include <Register/PchRegsSmbus.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;
+
+//
+// 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;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA                        *mSiConfigHobData;
+
+//
+// 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 = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SMBUS,
+                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
+                   0
+                   );
+
+  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);
+}
+
+/**
+  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);
+
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  ASSERT (HobPtr.Guid != NULL);
+  mSiConfigHobData = (SI_CONFIG_HOB_DATA *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  mAcpiBaseAddr = PmcGetAcpiBase ();
+
+  AllocateReservedMmio ();
+
+  Status = InitializePchPcieSmm (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InstallPchBiosWriteProtect (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InstallPchSpiAsyncSmiHandler ();
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
new file mode 100644
index 0000000000..4a2d1f9cea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
@@ -0,0 +1,298 @@
+/** @file
+  PCH LAN Sx handler implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/TimerLib.h>
+#include "PchInitSmm.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Library/GbeMdiLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLan.h>
+
+/**
+  Checks if Lan is Enabled or Disabled
+
+  @retval  BOOLEAN    TRUE if device is enabled, FALSE otherwise.
+**/
+BOOLEAN
+IsGbeEnabled (
+  VOID
+  )
+{
+  UINT64  GbePciBase;
+
+  GbePciBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_LAN,
+                 PCI_FUNCTION_NUMBER_PCH_LAN,
+                 0
+                 );
+
+  if (PciSegmentRead32 (GbePciBase) != 0xFFFFFFFF) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+/**
+  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_LAN_MEM_CSR_RAL);
+  RAH0 = MmioRead32 (GbeBar + R_LAN_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_LAN_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_LAN_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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_LAN,
+                 PCI_FUNCTION_NUMBER_PCH_LAN,
+                 0
+                 );
+
+  if (PciSegmentRead16 (LanRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+
+  //
+  // Check if GbE device is in D0
+  //
+  if ((PciSegmentRead16 (LanRegBase + R_LAN_CFG_PMCS) & B_LAN_CFG_PMCS_PS) != V_LAN_CFG_PMCS_PS0) {
+    return;
+  }
+
+  ASSERT (mResvMmioSize >= (1 << N_LAN_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_LAN_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_LAN_MEM_CSR_WUC) & B_LAN_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_LAN_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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
new file mode 100644
index 0000000000..eac2e1c3ec
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
@@ -0,0 +1,436 @@
+/** @file
+  PCH Pcie SMM Driver Entry
+
+  Copyright (c) 2019 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/PchRegsPcie.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                     mPciePmTrapExecuted = 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
+**/
+STATIC
+VOID
+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;
+  }
+  //
+  // 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;
+      }
+    }
+    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
+      );
+    RootportDownstreamPmConfiguration (
+      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      RpDevice,
+      RpFunction,
+      mTempRootPortBusNumMin,
+      mTempRootPortBusNumMax,
+      &mPcieRootPortConfig[PortIndex],
+      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);
+    }
+  }
+}
+
+/**
+  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;
+  UINTN                                     RpDevice;
+  UINTN                                     RpFunction;
+
+  MaxPciePortNum                   = GetPchMaxPciePortNum ();
+
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+    RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+
+    if (PciSegmentRead16 (RpBase) != 0xFFFF) {
+      RootportDownstreamPmConfiguration (
+        DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+        DEFAULT_PCI_BUS_NUMBER_PCH,
+        (UINT8)RpDevice,
+        (UINT8)RpFunction,
+        mTempRootPortBusNumMin,
+        mTempRootPortBusNumMax,
+        &mPcieRootPortConfig[PortIndex],
+        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 == PciePmTrap) {
+    if (mPciePmTrapExecuted == FALSE) {
+      PchPciePmIoTrapSmiCallback ();
+      mPciePmTrapExecuted = 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
+  )
+{
+  mPciePmTrapExecuted = 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;
+  UINTN                                 RpDevice;
+  UINTN                                 RpFunction;
+  EFI_HANDLE                            PcieHandle;
+  PCH_PCIE_SMI_DISPATCH_PROTOCOL        *PchPcieSmiDispatchProtocol;
+  EFI_HOB_GUID_TYPE*                    Hob;
+  UINT32                                DevTableSize;
+  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;
+
+  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)
+    );
+
+  mDevAspmOverride                  = NULL;
+  mNumOfDevAspmOverride             = 0;
+
+  Hob = GetFirstGuidHob (&gPchDeviceTableHobGuid);
+  if (Hob != NULL) {
+    DevTableSize = GET_GUID_HOB_DATA_SIZE (Hob);
+    ASSERT ((DevTableSize % sizeof (PCH_PCIE_DEVICE_OVERRIDE)) == 0);
+    mNumOfDevAspmOverride = DevTableSize / sizeof (PCH_PCIE_DEVICE_OVERRIDE);
+    DEBUG ((DEBUG_INFO, "Found PcieDeviceTable HOB (%d entries)\n", mNumOfDevAspmOverride));
+    Status = gSmst->SmmAllocatePool (
+                      EfiRuntimeServicesData,
+                      DevTableSize,
+                      (VOID **) &mDevAspmOverride
+                      );
+    CopyMem (mDevAspmOverride, GET_GUID_HOB_DATA (Hob), DevTableSize);
+  }
+
+  //
+  // Throught all PCIE root port function and register the SMI Handler for enabled ports.
+  //
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+    RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (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_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;
+      S3BootScriptSaveMemReadWrite (
+        S3BootScriptWidthUint32,
+        PcdGet64 (PcdPciExpressBaseAddress) + 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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
new file mode 100644
index 0000000000..3c843616e4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
@@ -0,0 +1,69 @@
+/** @file
+  PCH SPI Async SMI handler.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..d843de3ad8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,399 @@
+/** @file
+  This is the driver that publishes the SMM Control Protocol.
+
+  Copyright (c) 2019 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/PchRegsSpi.h>
+#include <Register/PchRegsPmc.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_EVENT,
+     "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_EVENT,
+     "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_EVENT,
+     "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_EVENT,
+     "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_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)
+      );
+    //
+    // Disable WADT_EN by default can avoid the WADT SMI during POST time when the WADT_STS is set as a wake source.
+    // BIOS disable WADT_EN and keep WADT_STS into OS so OS can be aware of the wake source.
+    //
+    IoAnd32 ((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/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000000..458d137e4f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
@@ -0,0 +1,310 @@
+/** @file
+  PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
+#include <Private/Library/SmmPchPrivateLib.h>
+#include <PchReservedResources.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.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 = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  // 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 = PCI_SEGMENT_LIB_ADDRESS (
+                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                     DEFAULT_PCI_BUS_NUMBER_PCH,
+                     PCI_DEVICE_NUMBER_PCH_SPI,
+                     PCI_FUNCTION_NUMBER_PCH_SPI,
+                     0
+                     );
+  ///
+  /// 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;
+}
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher

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

Adds the PchSmiDispatcher module. Dispatches PCH SMIs to appropriate
SMI handlers registered in various SMM modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf  |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h              |  228 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h              | 1031 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h          |  342 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h       |  157 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h      |  105 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c              | 1264 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c      | 2452 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c          |  911 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c          | 1595 +++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c           |  254 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c       |  358 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c |  675 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c   |   83 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c            |  385 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c            |  229 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c           |  231 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c      |  764 ++++++
 18 files changed, 11173 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
new file mode 100644
index 0000000000..38d5dbeebf
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
@@ -0,0 +1,109 @@
+## @file
+# Component description file for the Pch SMI Dispatch Handlers module
+#
+# Copyright (c) 2019 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
+PchEspiLib
+S3BootScriptLib
+ConfigBlockLib
+PmcPrivateLib
+PmcLib
+SmiHandlerProfileLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+# 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
+
+
+[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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
new file mode 100644
index 0000000000..9d6a459ff3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
@@ -0,0 +1,228 @@
+/** @file
+  Defines and prototypes for the IoTrap SMM driver
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
new file mode 100644
index 0000000000..1906e32b5a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
@@ -0,0 +1,1031 @@
+/** @file
+  Prototypes and defines for the PCH SMM Dispatcher.
+
+  Copyright (c) 2019 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/PchEspiLib.h>
+#include <Private/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 \
+  }
+
+///
+/// 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_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 union {
+  UINTN ElapsedTime;
+} 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 CONST 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
new file mode 100644
index 0000000000..193eed6bac
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
@@ -0,0 +1,342 @@
+/** @file
+  eSPI SMI Dispatch header
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
new file mode 100644
index 0000000000..24e0975025
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
@@ -0,0 +1,157 @@
+/** @file
+  Helper functions for PCH SMM
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
new file mode 100644
index 0000000000..ba7ad42c9d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
@@ -0,0 +1,105 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2019 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.
+**/
+VOID
+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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
new file mode 100644
index 0000000000..ddab2fc378
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
@@ -0,0 +1,1264 @@
+/** @file
+  Main implementation source file for the Io Trap SMM driver
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Private/Protocol/PchNvsArea.h>
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsDmi.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), NULL, 0);
+  }
+  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 (&gEfiSmmIoTrapDispatch2ProtocolGuid, RecordToDelete->IoTrapCallback, NULL, 0);
+  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), NULL, 0);
+  }
+  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, NULL, 0);
+  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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
new file mode 100644
index 0000000000..2b70008fee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
@@ -0,0 +1,2452 @@
+/** @file
+  This function handle the register/unregister of PCH specific SMI events.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Library/SmiHandlerProfileLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPcie.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsItss.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,
+  {
+    {
+      {
+        PCR_ADDR_TYPE,
+        {PCH_PCR_ADDRESS (PID_ITSS, R_ITSS_PCR_NMI)}
+      },
+      4,
+      N_ITSS_PCR_NMI_NMI2SMI_EN
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        PCR_ADDR_TYPE,
+        {PCH_PCR_ADDRESS (PID_ITSS, R_ITSS_PCR_NMI)}
+      },
+      4,
+      N_ITSS_PCR_NMI_NMI2SMI_STS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  Enable the Nmi2Smi source
+**/
+VOID
+PchNmi2SmiEnableSource (
+  VOID
+  )
+{
+  //
+  // The PCR[ITSS].NMI register can only be accessed with BOOT_SAI and SMM_SAI.
+  // Since in CFL there is no SMM_SAI it needs PMC assistance to access this register.
+  //
+  UINT32  ItssNmi;
+  ItssNmi = PmcGetNmiControl ();
+  PmcSetNmiControl (ItssNmi | B_ITSS_PCR_NMI_NMI2SMI_EN);
+}
+
+/**
+  Clear the NMI status bit after the SMI handling is done
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+**/
+VOID
+EFIAPI
+PchNmi2SmiClearSource (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  )
+{
+  // No need to clear NMI2SMI_STS since it's cleared when NMI source is cleared.
+  // Clear TCO status only.
+  PchSmmClearSource (&mDescSrcTcoSts);
+}
+
+/**
+  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);
+    //
+    // Since the NMI2SMI status and enable bit are at the same register,
+    // it needs separate function to handle the source enable and clear.
+    //
+    Record->ClearSource = PchNmi2SmiClearSource;
+    PchNmi2SmiEnableSource ();
+    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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  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);
+}
+
+/**
+  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.
+    //
+    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.
+    //
+    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 == PCI_DEVICE_NUMBER_PCH_SPI) &&
+      (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc == PCI_FUNCTION_NUMBER_PCH_SPI) &&
+      (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 == PCI_DEVICE_NUMBER_PCH_LPC) &&
+             (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc == PCI_FUNCTION_NUMBER_PCH_LPC) &&
+             (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                   Indicate the RP index (0-based)
+  @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;
+
+  //
+  // 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;
+  }
+
+  GetPchPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+  //
+  // Patch the RP device number and function number of srcdesc.
+  //
+  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)) {
+    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  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                   Indicate the RP index (0-based)
+  @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;
+
+  //
+  // 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;
+  }
+
+  GetPchPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+  //
+  // Patch the RP device number and function number of srcdesc.
+  //
+  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)) {
+    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  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                   Indicate the RP index (0-based)
+  @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;
+
+  //
+  // 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;
+  }
+
+  GetPchPcieRpDevFun (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)) {
+    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid, (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
+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, NULL, 0);
+  }
+  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 = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  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;
+  SpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                 DEFAULT_PCI_BUS_NUMBER_PCH,
+                 PCI_DEVICE_NUMBER_PCH_SPI,
+                 PCI_FUNCTION_NUMBER_PCH_SPI,
+                 0
+                 );
+  PciSegmentAndThenOr32 (
+    SpiRegBase + R_SPI_CFG_BC,
+    (UINT32) ~B_SPI_CFG_BC_SYNC_SS,
+    B_SPI_CFG_BC_ASE_BWP
+    );
+
+  //
+  // 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 == PCI_DEVICE_NUMBER_PCH_SPI) &&
+      (Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Fnc == PCI_FUNCTION_NUMBER_PCH_SPI) &&
+      (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 = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_SPI,
+                   PCI_FUNCTION_NUMBER_PCH_SPI,
+                   0
+                   );
+    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;
+      GetPchPcieRpNumber (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]);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gEfiSmmIoTrapDispatch2ProtocolGuid, (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] 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
+  )
+{
+  DATABASE_RECORD                   *RecordToDelete;
+  EFI_STATUS                        Status;
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (&gEfiSmmIoTrapDispatch2ProtocolGuid, RecordToDelete->Callback, NULL, 0);
+  }
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
new file mode 100644
index 0000000000..9c36103396
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
@@ -0,0 +1,911 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2019 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/PchRegsGpio.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsLpc.h>
+
+//
+// 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 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;
+
+  //
+  // 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, NULL, 0);
+  }
+  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.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_EN_127_96) & B_ACPI_IO_GPE0_EN_127_96_WADT) &&
+        (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 {
+                  //
+                  // 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
new file mode 100644
index 0000000000..9eb61947a3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
@@ -0,0 +1,1595 @@
+/** @file
+  eSPI SMI implementation
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmEspi.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Library/PchEspiLib.h>
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsLpc.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 = PCI_SEGMENT_LIB_ADDRESS (
+                         DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                         DEFAULT_PCI_BUS_NUMBER_PCH,
+                         PCI_DEVICE_NUMBER_PCH_LPC,
+                         PCI_FUNCTION_NUMBER_PCH_LPC,
+                         0
+                         );
+      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.
+  //
+  PmcLockEspiSmi ();
+  //
+  // 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;
+    default:
+      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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
new file mode 100644
index 0000000000..43277f0938
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
@@ -0,0 +1,254 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Gpi dispatch protocol.
+
+  Copyright (c) 2019 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/PchRegsGpio.h>
+#include <Register/PchRegsPmc.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 CONST 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), (void *)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, NULL, 0);
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
new file mode 100644
index 0000000000..f6413921eb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
@@ -0,0 +1,358 @@
+/** @file
+  Helper functions for PCH SMM dispatcher.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsItss.h>
+#include <Private/Library/PmcPrivateLib.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;
+    }
+  }
+
+  //
+  // Special handling for NMI bit since it requires PMC IPC command.
+  // Do w/a here instead of in ReadBitDesc to reduce the PMC IPC command usage.
+  //
+  // The PCR[ITSS].NMI register can only be accessed with BOOT_SAI and SMM_SAI.
+  // Since in CFL there is no SMM_SAI it needs PMC assistance to access this register.
+  //
+  if ((Src->En[0].Reg.Data.Pcr.Fields.Pid == PID_ITSS) &&
+      (Src->En[0].Reg.Data.Pcr.Fields.Offset == R_ITSS_PCR_NMI))
+  {
+    UINT32  ItssNmi;
+    ItssNmi = PmcGetNmiControl ();
+    if ((ItssNmi & (BIT0 << Src->En[0].Bit)) &&
+        (ItssNmi & (BIT0 << Src->Sts[0].Bit)))
+    {
+      return TRUE;
+    } else {
+      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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
new file mode 100644
index 0000000000..9a5ae464e0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
@@ -0,0 +1,675 @@
+/** @file
+  File to contain all the hardware specific stuff for the Periodical Timer dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Protocol/PchSmmPeriodicTimerControl.h>
+#include <Private/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.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) {
+      ///
+      /// 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;
+
+  if (SmiTickInterval == NULL) {
+    ASSERT(FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  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;
+  TIMER_INTERVAL                        *TimerInterval;
+
+  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  TimerInterval = NULL;
+  TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+  if (TimerInterval == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PchSmmDisableSource (&mTimerSourceDesc[TimerInterval->AssociatedTimer]);
+  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;
+  TIMER_INTERVAL                        *TimerInterval;
+
+  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  TimerInterval = NULL;
+  TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+  if (TimerInterval == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PchSmmEnableSource (&mTimerSourceDesc[TimerInterval->AssociatedTimer]);
+  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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
new file mode 100644
index 0000000000..17898b899b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
@@ -0,0 +1,83 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Power Button dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PchSmmHelpers.h>
+#include <Private/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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
new file mode 100644
index 0000000000..35ecfe5238
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
@@ -0,0 +1,385 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Sw dispatch protocol.
+
+  Copyright (c) 2019 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/PchRegsPmc.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++) {
+      Status = SmiInputValueDuplicateCheck (Index);
+      if (!EFI_ERROR (Status)) {
+        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;
+  }
+
+  Status = SmiInputValueDuplicateCheck (DispatchContext->SwSmiInputValue);
+  if (EFI_ERROR (Status)) {
+    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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
new file mode 100644
index 0000000000..52bb906315
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
@@ -0,0 +1,229 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsPcie.h>
+
+#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 = PchPcieBase (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 ();
+
+  ///
+  /// Flush cache into memory before we go to sleep. It is necessary for S3 sleep
+  /// because we may update memory in SMM Sx sleep handlers -- the updates are in cache now
+  ///
+  AsmWbinvd ();
+
+  ///
+  /// 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);
+
+    ///
+    /// Flush cache into memory before we go 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
new file mode 100644
index 0000000000..061dbe4300
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
@@ -0,0 +1,231 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm USB dispatch protocol.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/RegsUsb.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsPmc.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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
new file mode 100644
index 0000000000..4ac00b831f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
@@ -0,0 +1,764 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmHelpers.h"
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPmc.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.
+**/
+VOID
+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 &= (UINT32)~(B_ACPI_IO_GPE0_STS_127_96_WADT);
+
+    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);
+}
+
+/**
+  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;
+  }
+}
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI private library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI private library instances

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

Adds PCH PEI private library class instances. These library instances
may be compatible with other boot phases as indicated by the library type.

* PeiDxeSmmGpioPrivateLibCnl
* PeiDxeSmmPchDmiLib
* PeiDxeSmmPchDmiWithS3Lib
* PeiDxeSmmPchInitCommonLib
* PeiDxeSmmPchPciExpressHelpersLib
* PeiDxeSmmPchPsfPrivateLibCnl
* PeiDxeSmmPmcPrivateLibCnl
* PeiDxeSmmPmcPrivateLibWithS3
* PeiGpioHelpersLib
* PeiGpioNameBufferLib
* PeiPmcPrivateLibCnl

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf                |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf                             |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf                       |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf               |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf            |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf                  |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf               |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf                        |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf                               |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h                |  477 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h                                         |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h        |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h                  |  490 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h                        |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c                                |  166 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c                        | 1304 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c                     | 2275 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c                              |  752 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c                           |  225 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c                                         |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c                                        |  569 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c                                  |   79 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c                             |  221 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c        | 2407 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c                          |  542 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c                       |  338 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c                             |   92 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c                                | 1033 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c                          |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c                             |  360 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c                          |  194 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c                                 |  356 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c                              |   68 +
 37 files changed, 12919 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
new file mode 100644
index 0000000000..318b54a99c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
@@ -0,0 +1,45 @@
+## @file
+#  Component description file for the PeiDxeSmmGpioPrivateLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmGpioPrivateLibCnl
+FILE_GUID                      = E078A734-BEA0-47CF-A476-3742316D01FC
+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
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  GpioPrivateLib.c
+  GpioNativePrivateLib.c
+  GpioPrivateLibCnl.c
+  GpioNativePrivateLibCnl.c
+  GpioNamesCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
new file mode 100644
index 0000000000..b36fc15901
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
@@ -0,0 +1,40 @@
+## @file
+#  Component description file for the PeiDxeSmmPchDmiLib
+#
+# Copyright (c) 2019 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
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchDmiLib.c
+  PchDmi14.c
+  PchDmi15.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
new file mode 100644
index 0000000000..1eda7cdba8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
@@ -0,0 +1,40 @@
+## @file
+#  Component description file for the PeiDxeSmmPchDmiWithS3Lib
+#
+# Copyright (c) 2019 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
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchDmiWithS3Lib.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
new file mode 100644
index 0000000000..d81c428a1c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
@@ -0,0 +1,34 @@
+## @file
+#  Component description file for the PchInitCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiDxeSmmPchInitCommonLib
+  FILE_GUID                      = E9C4FE04-8A79-43FA-B3E0-603359C31B43
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PchInitCommonLib
+
+[Sources]
+  PchInitCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PciSegmentLib
+  PchCycleDecodingLib
+  PchPcieRpLib
+  PchSbiAccessLib
+  PchInfoLib
+  SataLib
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
new file mode 100644
index 0000000000..16b1c019b8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for the PeiDxeSmmPchPciExpressHelpersLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPciExpressHelpersLib
+FILE_GUID = 07E3F76D-6D26-419d-9053-58696A15B519
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPciExpressHelpersLib
+#
+# 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
+PchInitCommonLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPciExpressHelpersLibrary.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
new file mode 100644
index 0000000000..0ed9f30dcc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
@@ -0,0 +1,41 @@
+## @file
+#  PEI/DXE/SMM PCH PSF Private Lib for Cannon Lake PCH
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmPchPsfPrivateLibCnl
+FILE_GUID                      = 7A6C18CA-0353-433E-885D-DD68BFAD38BE
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = PchPsfPrivateLib
+#
+# 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
+  SaPlatformLib
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchPsfPrivateLib.c
+  PchPsfPrivateLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
new file mode 100644
index 0000000000..adb154dd14
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
@@ -0,0 +1,48 @@
+## @file
+# PEI/DXE/SMM PCH PMC Private Lib for Cannon Lake PCH.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPmcPrivateLibCnl
+FILE_GUID = A1CB52AD-4FAB-4214-94A0-323E3BE4E934
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PmcPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+TimerLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+PmcLib
+PchPsfPrivateLib
+PchDmiLib
+SataLib
+BaseMemoryLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+
+
+[Sources]
+PmcPrivateLib.c
+PmcPrivateLibClient.c
+PmcPrivateLibCnl.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
new file mode 100644
index 0000000000..cd1380dc43
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
@@ -0,0 +1,39 @@
+## @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) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PmcPrivateLibWithS3.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf
new file mode 100644
index 0000000000..ab3645c61d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf
@@ -0,0 +1,40 @@
+## @file
+# PEI PCH PMC Private Lib for Cannon Lake PCH.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiPmcPrivateLibCnl
+FILE_GUID = 1DD4EA23-12F2-4F05-93AF-535476106D8C
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiPmcPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+IoLib
+DebugLib
+PeiServicesLib
+PciSegmentLib
+ConfigBlockLib
+PchInfoLib
+PchPcrLib
+PmcLib
+PmcPrivateLib
+PchEspiLib
+GpioPrivateLib
+PeiItssLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiPmcPrivateLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
new file mode 100644
index 0000000000..b6f786d80b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Component description file for the PeiGpioHelpersLib
+#
+# Copyright (c) 2019 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
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiGpioHelpersLib.c
+
+
+[Guids]
+gGpioLibUnlockHobGuid
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
new file mode 100644
index 0000000000..3619a2e6a7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the PeiGpioMemLib
+#
+# Copyright (c) 2019 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
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+GpioNameBufferPei.c
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
new file mode 100644
index 0000000000..e081027c40
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
@@ -0,0 +1,477 @@
+/** @file
+  Header file for GPIO Private Lib Internal functions.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
+#define _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
+
+#include <Private/Library/GpioPrivateLib.h>
+
+#define GPIO_PAD_NONE 0
+
+/**
+  This function provides SerialIo I2C controller pins
+
+  @param[in]  SerialIoI2cControllerNumber    I2C controller
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoI2cPins (
+  IN  UINT32                      SerialIoI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SerialIo UART controller pins
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoUartPins (
+  IN  UINT32                      SerialIoUartControllerNumber,
+  IN  BOOLEAN                     HardwareFlowControl,
+  IN  UINT32                      PinMuxing,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides SerialIo SPI controller pins
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @param[out] NativePinsTable               Table with pins
+  @param[out] NoOfNativePins                Number of pins
+**/
+VOID
+GpioGetSerialIoSpiPins (
+  IN  UINT32                      SerialIoSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides ISH GP pin data
+
+  @param[in]  IshGpPinNumber        ISH GP pin number
+
+  @param[out] NativePin             ISH GP pin
+**/
+VOID
+GpioGetIshGpPin (
+  IN  UINT32                      IshGpPinNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  );
+
+/**
+  This function provides ISH UART controller pins
+
+  @param[in]  IshUartControllerNumber   ISH UART controller
+
+  @param[out] NativePinsTable           Table with pins
+**/
+VOID
+GpioGetIshUartPins (
+  IN  UINT32                      IshUartControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides ISH I2C controller pins
+
+  @param[in]  IshI2cControllerNumber   ISH I2C controller
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetIshI2cPins (
+  IN  UINT32                      IshI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides ISH SPI controller pins
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins           Number of pins
+**/
+VOID
+GpioGetIshSpiPins (
+  IN  UINT32                      IshSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides SCS SD CARD controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsSdCardPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides SCS SD CARD detect pin
+
+  @retval GpioPin             SD CARD Detect pin
+**/
+GPIO_PAD
+GpioGetScsSdCardDetectPin (
+  VOID
+  );
+
+/**
+  This function provides SCS eMMC controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsEmmcPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides HD Audio Link pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetHdAudioLinkPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides DMIC interface pins
+
+  @param[in]  DmicNumber               DMIC interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaDmicPins (
+  IN  UINT32                      DmicNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SSP/I2S interface pins
+
+  @param[in]  SspInterfaceNumber       SSP/I2S interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSspPins (
+  IN  UINT32                      SspInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SNDW interface pins
+
+  @param[in]  SndwInterfaceNumber      SNDWx interface number
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSndwPins (
+  IN  UINT32                      SndwInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SMBUS interface pins
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetSmbusPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides SATA DevSlp pin data
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+  @param[out] NativePin           SATA DevSlp pin
+**/
+VOID
+GpioGetSataDevSlpPin (
+  IN  UINT32                    SataCtrlIndex,
+  IN  UINTN                     SataPort,
+  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
+  );
+
+/**
+  This function provides PCIe CLKREQ pin data
+
+  @param[in]  ClkreqIndex        CLKREQ# number
+  @param[out] NativePin          Native pin data
+**/
+VOID
+GpioGetPcieClkReqPin (
+  IN  UINT32                      ClkreqIndex,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  );
+
+/**
+  This function provides eDP pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetEdpPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  );
+
+/**
+  This function provides DDPx interface pins
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetDdpPins (
+  IN  GPIO_DDP                    DdpInterface,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  );
+
+/**
+  This function provides CNVi BT UART pins
+
+  @param[in]  ConnectionType           CNVi BT UART connection type
+  @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
+  @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
+  @param[out] VUartForCnviBtPad        Table with vUART0 pads
+  @param[out] VUartForCnviBtPadMode    vUART0 pad mode
+**/
+VOID
+GpioGetCnviBtUartPins (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                            **VCnviBtUartPad,
+  OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
+  OUT GPIO_PAD                            **VUartForCnviBtPad,
+  OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
+  );
+
+/**
+  This function provides CNVi BT UART external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtUartExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi BT I2S pins
+
+  @param[in]  ConnectionType          CNVi BT I2S connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
+  @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
+  @param[out] VSspForCnviBtPad        Table with vSSP2 pads
+  @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
+**/
+VOID
+GpioGetCnviBtI2sPins (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviBtI2sPad,
+  OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
+  OUT GPIO_PAD                 **VSspForCnviBtPad,
+  OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
+  );
+
+/**
+  This function provides CNVi BT I2S external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtI2sExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi MFUART1 pins
+
+  @param[in]  ConnectionType          CNVi MFUART1 connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
+  @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
+  @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
+  @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
+**/
+VOID
+GpioGetCnviMfUart1Pins (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
+  OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
+  );
+
+/**
+  This function provides CNVi MFUART1 external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviMfUart1ExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi Bluetooth Enable pad
+
+  @retval GpioPad           CNVi Bluetooth Enable pad
+**/
+GPIO_PAD
+GpioGetCnviBtEnablePin (
+  VOID
+  );
+
+/**
+  This function provides CNVi BRI RGI GPIO pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnvBriRgiPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi MFUART2 external pins
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnvMfUart2ExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  );
+
+/**
+  This function provides CNVi BT interface select pin
+
+  @retval GpioPad          GPIO pad for CNVi BT interface select
+**/
+GPIO_PAD
+GpioGetCnviBtIfSelectPin (
+  VOID
+  );
+
+/**
+  This function provides CNVi BT Charging pin
+
+  @retval GpioPad          GPIO pad for CNVi BT Charging select
+**/
+GPIO_PAD
+GpioGetCnviBtChargingPin (
+  VOID
+  );
+
+/**
+  This function provides CNVi A4WP pin
+
+  @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
+**/
+VOID
+GpioGetCnviA4WpPin (
+  OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
+  );
+
+/**
+  This function provides CNVi BT host wake int pin
+
+  @retval GpioPad          GPIO pad BT host wake int
+**/
+GPIO_PAD
+GpioGetCnviBtHostWakeIntPin (
+  VOID
+  );
+
+/**
+  This function provides IMGCLKOUT pins
+
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins            Number of pins
+**/
+VOID
+GpioGetImgClkOutPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
+  OUT UINT32                   *NoOfNativePins
+  );
+
+/**
+  This function provides PWRBTN pin
+
+  @retval GpioPad          PWRTBTN pin
+**/
+GPIO_PAD
+GpioGetPwrBtnPin (
+  VOID
+  );
+
+/**
+  This procedure enables debounce feature on a selected pad configured in input mode
+  Debounce time can be specified in microseconds. GPIO HW supports only certain values
+  according to below formula:
+   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 GPIO HW, function will round down
+  to closest supported
+
+  @param[in] GpioPad              GPIO pad
+  @param[in, out] DebounceTime    Debounce Time in microseconds
+                                  If Debounce Time = 0, Debouncer feature will be disabled
+                                  Function will set DebounceTime argument to rounded supported value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad or unsupported DebounceDuration value
+  @retval EFI_UNSUPPORTED         GpioPad is not owned by host
+**/
+EFI_STATUS
+GpioSetDebounceTimer (
+  IN GPIO_PAD                  GpioPad,
+  IN OUT UINT32                *DebounceTime
+  );
+
+/**
+  This function provides LPC pin
+
+  @retval GpioPad          LPC pin
+**/
+GPIO_PAD
+GpioGetLpcPin (
+  VOID
+  );
+
+#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h
new file mode 100644
index 0000000000..1d50c04b0f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h
@@ -0,0 +1,70 @@
+/** @file
+  Internal header file for PCH DMI library for SIP14
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PCH_DMI_14_H__
+#define __PCH_DMI_14_H__
+
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/PeiPchDmiLib.h>
+
+/**
+  This function checks if DMI SIP14 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi14Locked (
+  VOID
+  );
+
+/**
+  Enable PCIe Relaxed Order for DMI SIP14
+**/
+VOID
+PchDmi14EnablePcieRelaxedOrder (
+  VOID
+  );
+
+/**
+  This function will switch SAI value to be driven to IOSF Primary Fabric
+  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
+  To be used when PCH is paired with CFL CPU.
+**/
+VOID
+PchDmi14EnablePostBootSai (
+  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
+  );
+
+/**
+  Get PCH DMI SIP14 Virtual Channel Control and Status registers
+
+  @param[in]  Vc                   The virtual channel number for programing
+  @param[out] DmiVcCtlAddress      DMI Virtual Channel Control register address
+  @param[out] DmiVcStsAddress      DMI Virtual Channel Status register address
+**/
+VOID
+PchDmi14VcRegs (
+  IN   PCH_DMI_VC_TYPE  Vc,
+  OUT  UINT16           *DmiVcCtlAddress,
+  OUT  UINT16           *DmiVcStsAddress
+  );
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h
new file mode 100644
index 0000000000..744a96fe14
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h
@@ -0,0 +1,113 @@
+/** @file
+  Internal header file for PCH DMI library for SIP15
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PCH_DMI_15_H__
+#define __PCH_DMI_15_H__
+
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/PeiPchDmiLib.h>
+
+/**
+  This function checks if DMI SIP15 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi15Locked (
+  VOID
+  );
+
+/**
+  Set DMI thermal throttling to recommended configuration.
+  It's intended only for P-DMI SIP15.
+**/
+VOID
+PchDmi15SetRecommendedThermalThrottling (
+  VOID
+  );
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+  It's intended only for P-DMI SIP15.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmi15SetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  );
+
+/**
+  Enable PCIe Relaxed Order for DMI SIP15
+**/
+VOID
+PchDmi15EnablePcieRelaxedOrder (
+  VOID
+  );
+
+/**
+  This function will switch SAI value to be driven to IOSF Primary Fabric
+  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
+  To be used when PCH is paired with CFL CPU.
+**/
+VOID
+PchDmi15EnablePostBootSai (
+  VOID
+  );
+
+/**
+  This function will do necessary configuration after platform
+  should have switched to POSTBOOT_SAI. It needs to be called even if
+  POSTBOOT_SAI was not set.
+**/
+VOID
+PchDmi15ConfigAfterPostBootSai (
+  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
+PchDmi15SrlRegData (
+  OUT UINT16  *SrlRegOffset,
+  OUT UINT32  *SrlRegMask
+  );
+
+/**
+  Get PCH DMI SIP15 Virtual Channel Control and Status registers
+
+  @param[in]  Vc                   The virtual channel number for programing
+  @param[out] DmiVcCtlAddress      DMI Virtual Channel Control register address
+  @param[out] DmiVcStsAddress      DMI Virtual Channel Status register address
+**/
+VOID
+PchDmi15VcRegs (
+  IN   PCH_DMI_VC_TYPE  Vc,
+  OUT  UINT16           *DmiVcCtlAddress,
+  OUT  UINT16           *DmiVcStsAddress
+  );
+
+/**
+  The function sets the Target Link Speed to GEN 3 in P-DMI SIP15.
+
+  @param[in] TargetLinkSpeed        Target Link Speed
+                                    2: GEN2
+                                    3: GEN3
+**/
+VOID
+PchDmi15SetTargetLinkSpeed (
+  IN  UINT8                 TargetLinkSpeed
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
new file mode 100644
index 0000000000..b14f24b18f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
@@ -0,0 +1,42 @@
+/** @file
+  Header file for PCH Pci Express helps library implementation.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
+#define _PCH_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 <Private/Library/PchPciExpressHelpersLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <Private/Library/PchInitCommonLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegsPcie.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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h
new file mode 100644
index 0000000000..f633df0411
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h
@@ -0,0 +1,490 @@
+/** @file
+  This file contains internal header for PSF lib usage
+
+  Copyright (c) 2019 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 <Private/Library/PchPsfPrivateLib.h>
+#include <Register/PchRegsPcr.h>
+
+#define PSF_PORT_NULL ((PSF_PORT){0,0})
+#define PSF_IS_PORT_NULL(PsfPort) ((PsfPort.PsfPid == 0) && (PsfPort.RegBase == 0))
+
+/**
+  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
+  );
+
+/**
+  Return PSF_PORT for HECI device
+
+  @param[in] HeciDevice      HECIx Device (HECI1-4)
+
+  @retval    PsfPort         PSF PORT structure for HECI device
+**/
+PSF_PORT
+PsfHeciPort (
+  IN UINT8      HeciDevice
+  );
+
+/**
+  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 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
+
+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
+  );
+
+/**
+  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
+  );
+
+/**
+  P2SB PSF port Destination ID (psf_id:port_group_id:port_id:channel_id)
+
+  @retval P2SB Destination ID
+**/
+PSF_PORT_DEST_ID
+PsfP2sbDestinationId (
+  VOID
+  );
+
+/**
+  DMI PSF port Destination ID (psf_id:port_group_id:port_id:channel_id)
+
+  @retval DMI Destination ID
+**/
+PSF_PORT_DEST_ID
+PsfDmiDestinationId (
+  VOID
+  );
+
+/**
+  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
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h
new file mode 100644
index 0000000000..c08d1cf10d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h
@@ -0,0 +1,47 @@
+/** @file
+  Internal header file for PMC Private library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PMC_PRIVATE_LIB_INTERNAL_H_
+#define _PMC_PRIVATE_LIB_INTERNAL_H_
+
+/**
+  Check if MODPHY SUS PG is supported
+
+  @retval  Status of MODPHY SUS PG support
+**/
+BOOLEAN
+PmcIsModPhySusPgSupported (
+  VOID
+  );
+
+/**
+  This function is part of PMC init and configures which clock wake signals should
+  set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent up to the CPU/PCH
+**/
+VOID
+PmcInitClockWakeEnable (
+  VOID
+  );
+
+/**
+  This function configures PWRMBASE + 0x1E00 register
+**/
+VOID
+PmcConfigureRegPwrm1E00 (
+  VOID
+  );
+
+/**
+  This function configures Misc PM_SYNC events settings
+**/
+VOID
+PmcConfigurePmSyncEventsSettings (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c
new file mode 100644
index 0000000000..5a4876bfeb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c
@@ -0,0 +1,166 @@
+/** @file
+  This file contains GPIO name library implementation
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+
+STATIC CONST CHAR8*  mGpioGppaNames[] = {
+  "ESPI_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGppbNames[] = {
+  "GSPI0_CLK_LOOPBK",
+  "GSPI1_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGpdNames[] = {
+  "SLP_LANB",
+  "SLP_SUSB",
+  "SLP_WAKEB",
+  "SLP_DRAM_RESETB"
+};
+
+STATIC CONST CHAR8*  mGpioGppiNames[] = {
+  "SYS_PWROK",
+  "SYS_RESETB",
+  "MLK_RSTB"
+};
+
+STATIC CONST CHAR8*  mGpioSpiNames[] = {
+  "SPI0_IO_2",
+  "SPI0_IO_3",
+  "SPI0_MOSI_IO_0",
+  "SPI0_MOSI_IO_1",
+  "SPI0_TPM_CSB",
+  "SPI0_FLASH_0_CSB",
+  "SPI0_FLASH_1_CSB",
+  "SPI0_CLK",
+  "SPI0_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioAzaNames[] = {
+  "HDA_BCLK",
+  "HDA_RSTB",
+  "HDA_SYNC",
+  "HDA_SDO",
+  "HDA_SDI_0",
+  "HDA_SDI_1",
+  "SSP1_SFRM",
+  "SSP1_TXD"
+};
+
+STATIC CONST CHAR8*  mGpioJtagNames[] = {
+  "JTAG_TDO",
+  "JTAGX",
+  "PRDYB",
+  "PREQB",
+  "CPU_TRSTB",
+  "JTAG_TDI",
+  "JTAG_TMS",
+  "JTAG_TCK",
+  "ITP_PMODE"
+};
+
+STATIC CONST CHAR8*  mGpioHvmosNames[] = {
+  "HVMOS_L_BKLTEN",
+  "HVMOS_L_BKLCTL",
+  "HVMOS_L_VDDEN",
+  "HVMOS_SYS_PWROK",
+  "HVMOS_SYS_RESETB",
+  "HVMOS_MLK_RSTB"
+};
+
+STATIC CONST CHAR8*  mGpioCpuNames[] = {
+  "HDACPU_SDI",
+  "HDACPU_SDO",
+  "HDACPU_SCLK",
+  "PM_SYNC",
+  "PECI",
+  "CPUPWRGD",
+  "THRMTRIPB",
+  "PLTRST_CPUB",
+  "PM_DOWN",
+  "TRIGGER_IN",
+  "TRIGGER_OUT"
+};
+
+STATIC CONST GPIO_GROUP_NAME_INFO  mPchLpGroupDescriptors[] = {
+  GPIO_GROUP_NAME("GPP_A", GPIO_CNL_LP_ESPI_CLK_LOOPBK, mGpioGppaNames),
+  GPIO_GROUP_NAME("GPP_B", GPIO_CNL_LP_GSPI0_CLK_LOOPBK, mGpioGppbNames),
+  GPIO_GROUP_NAME_BASIC("GPP_C"),
+  GPIO_GROUP_NAME_BASIC("GPP_D"),
+  GPIO_GROUP_NAME_BASIC("GPP_E"),
+  GPIO_GROUP_NAME_BASIC("GPP_F"),
+  GPIO_GROUP_NAME_BASIC("GPP_G"),
+  GPIO_GROUP_NAME_BASIC("GPP_H"),
+  GPIO_GROUP_NAME("GPD", GPIO_CNL_LP_SLP_LANB, mGpioGpdNames),
+  GPIO_GROUP_NAME_BASIC("VGPIO"),
+  GPIO_GROUP_NAME("SPI", GPIO_CNL_LP_SPI0_IO_2, mGpioSpiNames),
+  GPIO_GROUP_NAME("AZA", GPIO_CNL_LP_HDA_BCLK, mGpioAzaNames),
+  GPIO_GROUP_NAME("CPU", GPIO_CNL_LP_HDACPU_SDI, mGpioCpuNames),
+  GPIO_GROUP_NAME("JTAG", GPIO_CNL_LP_JTAG_TDO, mGpioJtagNames),
+  GPIO_GROUP_NAME("HVMOS", GPIO_CNL_LP_HVMOS_L_BKLTEN, mGpioHvmosNames)
+};
+
+STATIC CONST GPIO_GROUP_NAME_INFO  mPchHGroupDescriptors[] = {
+  GPIO_GROUP_NAME("GPP_A", GPIO_CNL_H_ESPI_CLK_LOOPBK, mGpioGppaNames),
+  GPIO_GROUP_NAME("GPP_B", GPIO_CNL_H_GSPI0_CLK_LOOPBK, mGpioGppbNames),
+  GPIO_GROUP_NAME_BASIC("GPP_C"),
+  GPIO_GROUP_NAME_BASIC("GPP_D"),
+  GPIO_GROUP_NAME_BASIC("GPP_E"),
+  GPIO_GROUP_NAME_BASIC("GPP_F"),
+  GPIO_GROUP_NAME_BASIC("GPP_G"),
+  GPIO_GROUP_NAME_BASIC("GPP_H"),
+  GPIO_GROUP_NAME("GPP_I", GPIO_CNL_H_SYS_PWROK, mGpioGppiNames),
+  GPIO_GROUP_NAME_BASIC("GPP_J"),
+  GPIO_GROUP_NAME_BASIC("GPP_K"),
+  GPIO_GROUP_NAME("GPD", GPIO_CNL_H_SLP_LANB, mGpioGpdNames),
+  GPIO_GROUP_NAME_BASIC("VGPIO"),
+  GPIO_GROUP_NAME("SPI", GPIO_CNL_H_SPI0_IO_2, mGpioSpiNames),
+  GPIO_GROUP_NAME("AZA", GPIO_CNL_H_HDA_BCLK, mGpioAzaNames),
+  GPIO_GROUP_NAME("CPU", GPIO_CNL_H_HDACPU_SDI, mGpioCpuNames),
+  GPIO_GROUP_NAME("JTAG", GPIO_CNL_H_JTAG_TDO, mGpioJtagNames),
+};
+
+/**
+  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 (IsPchLp ()) {
+    if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) {
+      return &mPchLpGroupDescriptors[GroupIndex];
+    } else {
+      ASSERT (FALSE);
+      return NULL;
+    }
+  } else {
+    if (GroupIndex < ARRAY_SIZE (mPchHGroupDescriptors)) {
+      return &mPchHGroupDescriptors[GroupIndex];
+    } else {
+      ASSERT (FALSE);
+      return NULL;
+    }
+  }
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c
new file mode 100644
index 0000000000..affecf9ec0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c
@@ -0,0 +1,1304 @@
+/** @file
+  This file contains routines for GPIO native and chipset specific purpose
+  used by Reference Code only.
+
+  Copyright (c) 2019 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/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <SaAccess.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include "GpioNativePrivateLibInternal.h"
+#include <Register/PchRegsGpio.h>
+#include <Register/PchRegsSerialIo.h>
+#include <Register/PchRegsIsh.h>
+
+/**
+  This function sets SerialIo I2C controller pins into native mode
+
+  @param[in]  SerialIoI2cControllerNumber   I2C controller
+  @param[in]  GpioTermination               GPIO termination type
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoI2c (
+  IN  UINT32                  SerialIoI2cControllerNumber,
+  IN  GPIO_ELECTRICAL_CONFIG  GpioTermination
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
+  GPIO_CONFIG              GpioConfig;
+
+  GpioGetSerialIoI2cPins (
+    SerialIoI2cControllerNumber,
+    &I2cGpio
+    );
+
+  if (I2cGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
+  GpioConfig.ElectricalConfig = GpioTermination;
+
+  for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index++) {
+    GpioConfig.PadMode          = I2cGpio[Index].Mode;
+
+    Status = GpioSetPadConfig(I2cGpio[Index].Pad, &GpioConfig);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SerialIo UART controller pins into native mode
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoUart (
+  IN  UINT32            SerialIoUartControllerNumber,
+  IN  BOOLEAN           HardwareFlowControl,
+  IN  UINT32            PinMuxing
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  UINT32                   PinsUsed;
+  GPIO_PAD_NATIVE_FUNCTION *UartGpio;
+
+  GpioGetSerialIoUartPins (
+    SerialIoUartControllerNumber,
+    HardwareFlowControl,
+    PinMuxing,
+    &UartGpio,
+    &PinsUsed
+    );
+
+  if (UartGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PinsUsed; Index++) {
+    Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+    GpioSetInputInversion (UartGpio[Index].Pad, 0);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SerialIo SPI controller pins into native mode
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSerialIoSpi (
+  IN  UINT32            SerialIoSpiControllerNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
+  UINT32                   NumOfSpiPins;
+
+  GpioGetSerialIoSpiPins (
+    SerialIoSpiControllerNumber,
+    &SpiGpio,
+    &NumOfSpiPins
+    );
+
+  if (SpiGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfSpiPins; Index++) {
+    Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+    GpioSetInputInversion (SpiGpio[Index].Pad, 0);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH I2C controller pins into native mode
+
+  @param[in]  IshI2cControllerNumber   I2C controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshI2c (
+  IN  UINT32            IshI2cControllerNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
+
+  GpioGetIshI2cPins (
+    IshI2cControllerNumber,
+    &I2cGpio
+    );
+
+  if (I2cGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_ISH_PINS_PER_I2C_CONTROLLER; Index++) {
+    Status = GpioSetPadMode (I2cGpio[Index].Pad, I2cGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH UART controller pins into native mode
+
+  @param[in]  IshUartControllerNumber   UART controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshUart (
+  IN  UINT32            IshUartControllerNumber
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *UartGpio;
+
+  GpioGetIshUartPins (
+    IshUartControllerNumber,
+    &UartGpio
+    );
+
+  if (UartGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_ISH_PINS_PER_UART_CONTROLLER; Index++) {
+    Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH SPI controller pins into native mode
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshSpi (
+  IN  UINT32            IshSpiControllerNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
+  UINT32                   NumOfSpiPins;
+
+  GpioGetIshSpiPins (
+    IshSpiControllerNumber,
+    &SpiGpio,
+    &NumOfSpiPins
+    );
+
+  if (SpiGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfSpiPins; Index++) {
+    Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets ISH GP pin into native mode
+
+  @param[in]  IshGpPinNumber   ISH GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableIshGpPin (
+  IN  UINT32            IshGpPinNumber
+  )
+{
+  EFI_STATUS               Status;
+  GPIO_PAD_NATIVE_FUNCTION IshGp;
+
+  GpioGetIshGpPin (
+    IshGpPinNumber,
+    &IshGp
+    );
+
+  Status = GpioSetPadMode (IshGp.Pad, IshGp.Mode);
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SCS SD card controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCard (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *SdCardGpio;
+  UINT32                    NumOfSdCardPins;
+  GPIO_CONFIG               PwrEnConfig;
+
+  GpioGetScsSdCardPins (
+    &SdCardGpio,
+    &NumOfSdCardPins
+    );
+
+  if (SdCardGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // We need to leave the PWREN#
+  // GPIO pad unlocked since it is controlled at runtime
+  // by ACPI code. It is a work around for our SD card
+  // controller not respecting PWREN# invertion settings
+  // during D3. Since this pad will be in GPIO mode when
+  // SD controller is in D3 we need to set correct pad config.
+  //
+  GpioUnlockPadCfg (SdCardGpio[0].Pad);
+  GpioGetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
+  PwrEnConfig.PadMode = SdCardGpio[0].Mode;
+  PwrEnConfig.Direction = GpioDirOut;
+  PwrEnConfig.HostSoftPadOwn = GpioHostOwnAcpi;
+  PwrEnConfig.InterruptConfig = GpioIntDis;
+  PwrEnConfig.PowerConfig = GpioHostDeepReset;
+  PwrEnConfig.LockConfig = GpioPadUnlock;
+  GpioSetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
+
+  for (Index = 1; Index < NumOfSdCardPins; Index++) {
+    Status = GpioSetPadMode (SdCardGpio[Index].Pad, SdCardGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // SD Card Pins GPP_G0 - G4 require Native Termination
+    // Index in mPch[Lp/H]ScsSdCardGpio (depends on mPch[Lp/H]ScsSdCardGpio internal organization):
+    // GPP_G0 = 1
+    // GPP_G4 = 5
+    //
+    if (Index >= 1 && Index <= 5) {
+      Status = GpioSetPadElectricalConfig (SdCardGpio[Index].Pad, GpioTermNative);
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function enables SCS Sd Card controller card detect pin
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCardDetect (
+  VOID
+  )
+{
+  GPIO_CONFIG   PadConfig;
+  GPIO_PAD      GpioPad;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  ///
+  /// vSD3_CD_B line is driven by GPPC_G_5_SD3_CDB
+  /// and is used for interrupt for card detect event.
+  /// GPPC_G_5_SD3_CDB cannot be used for interrupt because this pin
+  /// is in native mode.
+  ///
+  GpioPad = GpioGetScsSdCardDetectPin ();
+  PadConfig.PadMode         = GpioPadModeGpio;
+  PadConfig.Direction       = GpioDirIn;
+  PadConfig.HostSoftPadOwn  = GpioHostOwnGpio;
+  PadConfig.InterruptConfig = GpioIntBothEdge;
+  PadConfig.PowerConfig     = GpioHostDeepReset;
+
+  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode.
+  GpioUnlockPadCfg (GpioPad);
+
+  return GpioSetPadConfig (GpioPad, &PadConfig);
+}
+
+/**
+  This function sets SCS eMMC controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsEmmc (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *EmmcGpio;
+  UINT32                    NumOfEmmcPins;
+
+  GpioGetScsEmmcPins (
+    &EmmcGpio,
+    &NumOfEmmcPins
+    );
+
+  if (EmmcGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfEmmcPins; Index++) {
+    Status = GpioSetPadMode (EmmcGpio[Index].Pad, EmmcGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA Link pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaLink (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *HdaLinkGpio;
+  UINT32                    NumOfHdaLinkPins;
+
+  GpioGetHdAudioLinkPins (
+    &HdaLinkGpio,
+    &NumOfHdaLinkPins
+    );
+
+  if (HdaLinkGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NumOfHdaLinkPins; Index++) {
+    Status = GpioSetPadMode (HdaLinkGpio[Index].Pad, HdaLinkGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA DMIC pins into native mode
+
+  @param[in]  DmicNumber   DMIC number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaDmic (
+  IN  UINT32            DmicNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *DmicGpio;
+
+  GpioGetHdaDmicPins (
+    DmicNumber,
+    &DmicGpio
+    );
+
+  if (DmicGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (DmicGpio[Index].Pad, DmicGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA SSP interface pins into native mode
+
+  @param[in]  SspInterfaceNumber   SSPx interface number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSsp (
+  IN  UINT32            SspInterfaceNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SspGpio;
+
+  GpioGetHdaSspPins (
+    SspInterfaceNumber,
+    &SspGpio
+    );
+
+  if (SspGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_HDA_SSP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (SspGpio[Index].Pad, SspGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets HDA SoundWire interface pins into native mode
+
+  @param[in]  SndwInterfaceNumber   SNDWx interface number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSndw (
+  IN  UINT32            SndwInterfaceNumber
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SndwGpio;
+
+  GpioGetHdaSndwPins (
+    SndwInterfaceNumber,
+    &SndwGpio
+    );
+
+  if (SndwGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (SndwGpio[Index].Pad, SndwGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SMBUS controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSmbus (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *SmbusGpio;
+
+  GpioGetSmbusPins (&SmbusGpio);
+
+  if (SmbusGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_SMBUS_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (SmbusGpio[Index].Pad, SmbusGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets SATA DevSlp pins into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataDevSlpPin (
+  IN  UINT32  SataCtrlIndex,
+  IN  UINTN   SataPort
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  DevSlpGpio;
+
+  GpioGetSataDevSlpPin (
+    SataCtrlIndex,
+    SataPort,
+    &DevSlpGpio
+    );
+
+  GpioSetPadResetConfig (DevSlpGpio.Pad, GpioResumeReset);
+
+  return GpioSetPadMode (DevSlpGpio.Pad, DevSlpGpio.Mode);
+}
+
+/**
+  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
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  DevSlpNativePad;
+  GPIO_PAD_MODE             GpioMode;
+  EFI_STATUS                Status;
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  GpioGetSataDevSlpPin (
+    SataCtrlIndex,
+    SataPort,
+    &DevSlpNativePad
+    );
+
+  Status = GpioGetPadMode (DevSlpNativePad.Pad, &GpioMode);
+
+  if (EFI_ERROR (Status) || (GpioMode != DevSlpNativePad.Mode)) {
+    if (DevSlpPad != NULL) {
+      *DevSlpPad = GPIO_PAD_NONE;
+    }
+    return FALSE;
+  } else {
+    if (DevSlpPad != NULL) {
+      *DevSlpPad = DevSlpNativePad.Pad;
+    }
+    return TRUE;
+  }
+}
+
+/**
+  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
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  SataGpGpio;
+
+  GpioGetSataGpPin (
+    SataCtrlIndex,
+    SataPort,
+    &SataGpGpio
+    );
+
+  DEBUG_CODE_BEGIN ();
+  GPIO_PAD_MODE  PadMode;
+  GpioGetPadMode (SataGpGpio.Pad, &PadMode);
+  if (PadMode == GpioPadModeNative1) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Cannot enable SATAGP%d, %a already used for SATAXPCIE_%d\n",
+        SataPort,
+        GpioName (SataGpGpio.Pad),
+        SataPort));
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  DEBUG_CODE_END ();
+
+  return GpioSetPadMode (SataGpGpio.Pad, SataGpGpio.Mode);
+}
+
+/**
+  Returns a pad for given CLKREQ# index.
+
+  @param[in]  ClkreqIndex       CLKREQ# number
+
+  @return CLKREQ# pad.
+**/
+GPIO_PAD
+GpioGetClkreqPad (
+  IN     UINT32   ClkreqIndex
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  ClkReqGpio;
+
+  GpioGetPcieClkReqPin (
+    ClkreqIndex,
+    &ClkReqGpio
+    );
+
+  return ClkReqGpio.Pad;
+}
+
+/**
+  Enables CLKREQ# pad in native mode.
+
+  @param[in]  ClkreqIndex       CLKREQ# number
+
+  @return none
+**/
+VOID
+GpioEnableClkreq (
+  IN     UINT32   ClkreqIndex
+  )
+{
+  GPIO_CONFIG               PadConfig;
+  GPIO_PAD_NATIVE_FUNCTION  ClkReqGpio;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  GpioGetPcieClkReqPin (
+    ClkreqIndex,
+    &ClkReqGpio
+    );
+
+  PadConfig.PadMode      = ClkReqGpio.Mode;
+  PadConfig.Direction    = GpioDirNone;
+  PadConfig.PowerConfig  = GpioHostDeepReset;
+  DEBUG ((DEBUG_INFO, "Enabling CLKREQ%d\n", ClkreqIndex));
+  GpioSetPadConfig (ClkReqGpio.Pad, &PadConfig);
+}
+
+
+/**
+  This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode for eDP Panel
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableEdpPins (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD_NATIVE_FUNCTION *EdpPins;
+  UINT32                   EdpPinsNumber;
+
+  GpioGetEdpPins (
+    &EdpPins,
+    &EdpPinsNumber
+    );
+
+  if (EdpPins == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure HPD, VDD and BKLT Pins for eDP panel
+  //
+  for (Index = 0; Index < EdpPinsNumber; Index++) {
+    Status = GpioSetPadMode (EdpPins[Index].Pad, EdpPins[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets DDP pins into native mode
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpInterface (
+  IN  GPIO_DDP            DdpInterface
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    Index;
+  GPIO_PAD_NATIVE_FUNCTION *DdpGpio;
+
+  GpioGetDdpPins (
+    DdpInterface,
+    &DdpGpio
+    );
+
+  if (DdpGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < PCH_GPIO_DDP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (DdpGpio[Index].Pad, DdpGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures GPIO connection between CNVi and CRF
+  @param[in]  None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviCrfConnection (
+  VOID
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD_NATIVE_FUNCTION *CnviBriRgiExternalPad;
+
+  GpioGetCnvBriRgiPins (&CnviBriRgiExternalPad);
+
+  if (CnviBriRgiExternalPad == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi BRI and RGI buses for high speed communication with CRF
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (CnviBriRgiExternalPad[Index].Pad, CnviBriRgiExternalPad[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth UART
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtUartConnection (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD                 *VCnviBtUartPad;
+  GPIO_PAD_MODE            VCnviBtUartPadMode;
+  GPIO_PAD                 *VUartForCnviBtPad;
+  GPIO_PAD_MODE            VUartForCnviBtPadMode;
+  GPIO_PAD_NATIVE_FUNCTION *CnviBtUartExternalPad;
+
+  GpioGetCnviBtUartPins (
+    ConnectionType,
+    &VCnviBtUartPad,
+    &VCnviBtUartPadMode,
+    &VUartForCnviBtPad,
+    &VUartForCnviBtPadMode
+    );
+
+  if ((VCnviBtUartPad == NULL) ||
+      (VUartForCnviBtPad == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi Bluetooth UART for certain connection
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VCnviBtUartPad[Index], VCnviBtUartPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable virtual connection for UART for Bluetooth
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VUartForCnviBtPad[Index], VUartForCnviBtPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable CNVi BT UART on external pads
+  //
+  if (ConnectionType == GpioCnviBtUartToExternalPads) {
+
+    GpioGetCnviBtUartExternalPins (&CnviBtUartExternalPad);
+
+    if (CnviBtUartExternalPad == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+      Status = GpioSetPadMode (CnviBtUartExternalPad[Index].Pad, CnviBtUartExternalPad[Index].Mode);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return EFI_UNSUPPORTED;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures virtual GPIO connection for CNVi Bluetooth I2S
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtI2sConnection (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD                 *VCnviBtI2sPad;
+  GPIO_PAD_MODE            VCnviBtI2sPadMode;
+  GPIO_PAD                 *VSspForCnviBtPad;
+  GPIO_PAD_MODE            VSspForCnviBtPadMode;
+  GPIO_PAD_NATIVE_FUNCTION *CnviBtI2sExternalPad;
+
+  GpioGetCnviBtI2sPins (
+    ConnectionType,
+    &VCnviBtI2sPad,
+    &VCnviBtI2sPadMode,
+    &VSspForCnviBtPad,
+    &VSspForCnviBtPadMode
+    );
+
+  if ((VCnviBtI2sPad == NULL) ||
+      (VSspForCnviBtPad == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi Bluetooth I2S for certain connection
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VCnviBtI2sPad[Index], VCnviBtI2sPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable virtual connection for SSP for Bluetooth
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VSspForCnviBtPad[Index], VSspForCnviBtPadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable CNV BT I2S on external pads
+  //
+  if (ConnectionType == (VGPIO_CNVI_BT_I2S_CONNECTION_TYPE) GpioCnviBtI2sToExternalPads) {
+
+    GpioGetCnviBtI2sExternalPins (&CnviBtI2sExternalPad);
+
+    if (CnviBtI2sExternalPad == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
+      Status = GpioSetPadMode (CnviBtI2sExternalPad[Index].Pad, CnviBtI2sExternalPad[Index].Mode);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return EFI_UNSUPPORTED;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function configures virtual GPIO connection for CNVi MFUART1
+
+  @param[in]  ConnectionType
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviMfUart1Connection (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType
+  )
+{
+  EFI_STATUS               Status;
+  UINT32                   Index;
+  GPIO_PAD                 *VCnviMfUart1Pad;
+  GPIO_PAD_MODE            VCnviMfUart1PadMode;
+  GPIO_PAD                 *VUartForCnviMfUart1Pad;
+  GPIO_PAD_MODE            VUartForCnviMfUart1PadMode;
+  GPIO_PAD_NATIVE_FUNCTION *CnviMfUart1ExternalPad;
+
+  GpioGetCnviMfUart1Pins (
+    ConnectionType,
+    &VCnviMfUart1Pad,
+    &VCnviMfUart1PadMode,
+    &VUartForCnviMfUart1Pad,
+    &VUartForCnviMfUart1PadMode
+    );
+
+  if ((VCnviMfUart1Pad == NULL) ||
+      (VUartForCnviMfUart1Pad == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Configure CNVi MFUART1 for certain connection
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VCnviMfUart1Pad[Index], VCnviMfUart1PadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable virtual connection for MFUART1
+  //
+  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+    Status = GpioSetPadMode (VUartForCnviMfUart1Pad[Index], VUartForCnviMfUart1PadMode);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Enable CNV MFUART1 on external pads
+  //
+  if (ConnectionType == GpioCnviMfUart1ToExternalPads) {
+
+    GpioGetCnviMfUart1ExternalPins (&CnviMfUart1ExternalPad);
+
+    if (CnviMfUart1ExternalPad == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
+      Status = GpioSetPadMode (CnviMfUart1ExternalPad[Index].Pad, CnviMfUart1ExternalPad[Index].Mode);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return EFI_UNSUPPORTED;
+      }
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  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
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_PAD    CnviBtEnPad;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode        = GpioPadModeGpio;
+  PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
+  PadConfig.Direction      = GpioDirOut;
+  if (Value == 1) {
+    PadConfig.OutputState  = GpioOutHigh;
+  } else {
+    PadConfig.OutputState  = GpioOutLow;
+  }
+  CnviBtEnPad = GpioGetCnviBtEnablePin ();
+
+  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode and it is GPO
+  GpioUnlockPadCfg (CnviBtEnPad);
+  GpioUnlockPadCfgTx (CnviBtEnPad);
+  Status = GpioSetPadConfig (CnviBtEnPad, &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  This function sets CNVi Bluetooth main host interface
+
+  @param[in] BtInterface          CNVi BT Interface Select value
+                                  GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviBtInterface (
+  IN  VGPIO_CNVI_BT_INTERFACE  BtInterface
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode        = GpioPadModeGpio;
+  PadConfig.Direction      = GpioDirOut;
+  if (BtInterface == GpioCnviBtIfUsb) {
+    PadConfig.OutputState  = GpioOutHigh;
+  } else {
+    PadConfig.OutputState  = GpioOutLow;
+  }
+
+  Status = GpioSetPadConfig (GpioGetCnviBtIfSelectPin (), &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  EFI_STATUS                Status;
+  GPIO_CONFIG               CnviBtChargingPadConfig;
+  GPIO_PAD_NATIVE_FUNCTION  A4WpPad;
+
+  ZeroMem (&CnviBtChargingPadConfig, sizeof (CnviBtChargingPadConfig));
+
+  CnviBtChargingPadConfig.PadMode        = GpioPadModeGpio;
+  CnviBtChargingPadConfig.Direction      = GpioDirOut;
+
+  if (BtWirelessCharging == 1) {
+    CnviBtChargingPadConfig.OutputState  = GpioOutHigh;
+
+    GpioGetCnviA4WpPin (&A4WpPad);
+
+    Status = GpioSetPadMode (A4WpPad.Pad, A4WpPad.Mode);
+    ASSERT_EFI_ERROR (Status);
+
+  } else {
+    CnviBtChargingPadConfig.OutputState  = GpioOutLow;
+  }
+
+  Status = GpioSetPadConfig (GpioGetCnviBtChargingPin (), &CnviBtChargingPadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function enables and configures CNVi Bluetooth Host wake-up interrupt
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtHostWakeInt (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_PAD    CnviBtHostWakeIntPad;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode = GpioPadModeGpio;
+  PadConfig.Direction = GpioDirIn;
+  PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
+  PadConfig.InterruptConfig = GpioIntEdge;
+  PadConfig.PowerConfig  = GpioHostDeepReset;
+  CnviBtHostWakeIntPad = GpioGetCnviBtHostWakeIntPin ();
+
+  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode.
+  GpioUnlockPadCfg (CnviBtHostWakeIntPad);
+  Status = GpioSetPadConfig (CnviBtHostWakeIntPad, &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function enables IMGU CLKOUT native pin
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableImguClkOut (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  GPIO_PAD_NATIVE_FUNCTION  *ImguClkOutGpio;
+  UINT32                    NoOfNativePins;
+
+  GpioGetImgClkOutPins (
+    &ImguClkOutGpio,
+    &NoOfNativePins
+    );
+
+  if (ImguClkOutGpio == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  for (Index = 0; Index < NoOfNativePins; Index++) {
+    Status = GpioSetPadMode (ImguClkOutGpio[Index].Pad, ImguClkOutGpio[Index].Mode);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  GpioSetDebounceTimer (GpioGetPwrBtnPin (), &DebounceTime);
+}
+
+/**
+  Configure LPC GPIO
+**/
+VOID
+LpcConfigureGpio (
+  VOID
+  )
+{
+  GPIO_PAD      GpioPad;
+  GpioPad = GpioGetLpcPin();
+
+  if (GpioPad == 0) {
+    return;
+  } else {
+    GpioSetPadElectricalConfig (GpioPad, GpioTermWpu20K);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c
new file mode 100644
index 0000000000..4cff00c27b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c
@@ -0,0 +1,2275 @@
+/** @file
+  This file contains specific GPIO information
+
+  Copyright (c) 2019 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 <SaAccess.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Register/PchRegsGpio.h>
+#include <Register/PchRegsGpioCnl.h>
+#include <Register/PchRegsSerialIo.h>
+#include <Register/PchRegsIsh.h>
+#include <Register/PchRegsScs.h>
+#include <Register/PchRegsLpcCnl.h>
+
+#include "GpioNativePrivateLibInternal.h"
+
+//
+// I2C controller pins
+// I2C[controller number][pin: SDA/SCL]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
+{
+  {{GPIO_CNL_LP_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C17, GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C19, GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H4,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H5 , GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H6,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H7 , GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H8,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H9 , GpioPadModeNative1}},
+  {{GPIO_CNL_LP_GPP_H10, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H11, GpioPadModeNative1}}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION  mPchHI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
+{
+  {{GPIO_CNL_H_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C17, GpioPadModeNative1}}, // I2C0
+  {{GPIO_CNL_H_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C19, GpioPadModeNative1}}, // I2C1
+  {{GPIO_CNL_H_GPP_D13, GpioPadModeNative3}, {GPIO_CNL_H_GPP_D14, GpioPadModeNative3}}, // I2C2
+  {{GPIO_CNL_H_GPP_D4,  GpioPadModeNative2}, {GPIO_CNL_H_GPP_D23, GpioPadModeNative2}}  // I2C3
+};
+
+
+/**
+  This function provides SerialIo I2C controller pins
+
+  @param[in]  SerialIoI2cControllerNumber    I2C controller
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoI2cPins (
+  IN  UINT32                      SerialIoI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchLpI2cGpio)) {
+      *NativePinsTable = mPchLpI2cGpio[SerialIoI2cControllerNumber];
+      return;
+    }
+  } else {
+    if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchHI2cGpio)) {
+      *NativePinsTable = mPchHI2cGpio[SerialIoI2cControllerNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+//
+// UART controller pins
+// UART[controller number][pin: RXD/TXD/RTSB/CTSB]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
+{
+  { // UART0
+    {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C10, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C11, GpioPadModeNative1}
+  },
+  { // UART1
+    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative1}
+  },
+  { // UART2
+    {GPIO_CNL_LP_GPP_C20, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C21, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C22, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_C23, GpioPadModeNative1},
+  },
+  { // UART0 (2nd pin set)
+    {GPIO_CNL_LP_GPP_F5, GpioPadModeNative2},
+    {GPIO_CNL_LP_GPP_F6, GpioPadModeNative2},
+    {GPIO_CNL_LP_GPP_F4, GpioPadModeNative2},
+    {GPIO_CNL_LP_GPP_F7, GpioPadModeNative2}
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
+{
+  { // UART0
+    {GPIO_CNL_H_GPP_C8,  GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C9,  GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C10, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C11, GpioPadModeNative1}
+  },
+  { // UART1
+    {GPIO_CNL_H_GPP_C12, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C13, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C14, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C15, GpioPadModeNative1}
+  },
+  { // UART2
+    {GPIO_CNL_H_GPP_C20, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C21, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C22, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_C23, GpioPadModeNative1}
+  },
+  { // UART0 (2nd pin set)
+    {GPIO_CNL_H_GPP_J5, GpioPadModeNative2},
+    {GPIO_CNL_H_GPP_J6, GpioPadModeNative2},
+    {GPIO_CNL_H_GPP_J4, GpioPadModeNative2},
+    {GPIO_CNL_H_GPP_J7, GpioPadModeNative2}
+  }
+};
+
+/**
+  This function provides SerialIo UART controller pins
+
+  @param[in]  SerialIoUartControllerNumber   UART controller
+  @param[in]  HardwareFlowControl            Hardware Flow control
+  @param[in]  PinMuxing                      UART controller pin muxing
+   @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetSerialIoUartPins (
+  IN  UINT32                      SerialIoUartControllerNumber,
+  IN  BOOLEAN                     HardwareFlowControl,
+  IN  UINT32                      PinMuxing,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  UINTN                    UartGpioIndex;
+
+  UartGpioIndex = SerialIoUartControllerNumber;
+
+  if ((SerialIoUartControllerNumber == 0) && (PinMuxing == 1)) {
+    // Last record is for UART0 second pin set
+    if (IsPchLp ()) {
+      UartGpioIndex = ARRAY_SIZE (mPchLpUartGpio) - 1;
+    } else {
+      UartGpioIndex = ARRAY_SIZE (mPchHUartGpio) - 1;
+    }
+  }
+
+  if (HardwareFlowControl) {
+    *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER;
+  } else {
+    *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL;
+  }
+
+  if (IsPchLp ()) {
+    if (UartGpioIndex < ARRAY_SIZE (mPchLpUartGpio)) {
+      *NativePinsTable = mPchLpUartGpio[UartGpioIndex];
+      return;
+    }
+  } else {
+    if (UartGpioIndex < ARRAY_SIZE (mPchHUartGpio)) {
+      *NativePinsTable = mPchHUartGpio[UartGpioIndex];
+      return;
+    }
+  }
+
+  *NativePinsTable = NULL;
+  *NoOfNativePins = 0;
+  ASSERT (FALSE);
+}
+
+//
+// SPI controller pins
+// SPI[controller number][pin: CSB/CLK/MISO/MOSI]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
+{
+  { // SPI0
+    {GPIO_CNL_LP_GPP_B15, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B16, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B17, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B18, GpioPadModeNative1}
+  },
+  { // SPI1
+    {GPIO_CNL_LP_GPP_B19, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B20, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B21, GpioPadModeNative1},
+    {GPIO_CNL_LP_GPP_B22, GpioPadModeNative1}
+  },
+  { // SPI2
+    {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative3},
+    {GPIO_CNL_LP_GPP_D10, GpioPadModeNative3},
+    {GPIO_CNL_LP_GPP_D11, GpioPadModeNative3},
+    {GPIO_CNL_LP_GPP_D12, GpioPadModeNative3}
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
+{
+  { // SPI0
+    {GPIO_CNL_H_GPP_B15, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B16, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B17, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B18, GpioPadModeNative1}
+  },
+  { // SPI1
+    {GPIO_CNL_H_GPP_B19, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B20, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B21, GpioPadModeNative1},
+    {GPIO_CNL_H_GPP_B22, GpioPadModeNative1}
+  },
+  { // SPI2
+    {GPIO_CNL_H_GPP_D9,  GpioPadModeNative3},
+    {GPIO_CNL_H_GPP_D10, GpioPadModeNative3},
+    {GPIO_CNL_H_GPP_D11, GpioPadModeNative3},
+    {GPIO_CNL_H_GPP_D12, GpioPadModeNative3}
+  }
+};
+
+/**
+  This function provides SerialIo SPI controller pins
+
+  @param[in]  SerialIoSpiControllerNumber   SPI controller
+
+  @param[out] NativePinsTable               Table with pins
+  @param[out] NoOfNativePins                Number of pins
+**/
+VOID
+GpioGetSerialIoSpiPins (
+  IN  UINT32                      SerialIoSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchLpSpiGpio)) {
+      *NativePinsTable = mPchLpSpiGpio[SerialIoSpiControllerNumber];
+      *NoOfNativePins =  ARRAY_SIZE (mPchLpSpiGpio[SerialIoSpiControllerNumber]);
+      return;
+    }
+  } else {
+    if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchHSpiGpio)) {
+      *NativePinsTable = mPchHSpiGpio[SerialIoSpiControllerNumber];
+      *NoOfNativePins =  ARRAY_SIZE (mPchHSpiGpio[SerialIoSpiControllerNumber]);
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  *NoOfNativePins = 0;
+  ASSERT (FALSE);
+}
+
+//
+// ISH GP pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshGPGpio[] =
+{
+  {GPIO_CNL_LP_GPP_A18, GpioPadModeNative1},// ISH_GP_0
+  {GPIO_CNL_LP_GPP_A19, GpioPadModeNative1},// ISH_GP_1
+  {GPIO_CNL_LP_GPP_A20, GpioPadModeNative1},// ISH_GP_2
+  {GPIO_CNL_LP_GPP_A21, GpioPadModeNative1},// ISH_GP_3
+  {GPIO_CNL_LP_GPP_A22, GpioPadModeNative1},// ISH_GP_4
+  {GPIO_CNL_LP_GPP_A23, GpioPadModeNative1},// ISH_GP_5
+  {GPIO_CNL_LP_GPP_A12, GpioPadModeNative2},// ISH_GP_6
+  {GPIO_CNL_LP_GPP_A17, GpioPadModeNative2} // ISH_GP_7
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshGPGpio[] =
+{
+  {GPIO_CNL_H_GPP_A18, GpioPadModeNative1},// ISH_GP_0
+  {GPIO_CNL_H_GPP_A19, GpioPadModeNative1},// ISH_GP_1
+  {GPIO_CNL_H_GPP_A20, GpioPadModeNative1},// ISH_GP_2
+  {GPIO_CNL_H_GPP_A21, GpioPadModeNative1},// ISH_GP_3
+  {GPIO_CNL_H_GPP_A22, GpioPadModeNative1},// ISH_GP_4
+  {GPIO_CNL_H_GPP_A23, GpioPadModeNative1},// ISH_GP_5
+  {GPIO_CNL_H_GPP_A12, GpioPadModeNative2},// ISH_GP_6
+  {GPIO_CNL_H_GPP_A17, GpioPadModeNative2} // ISH_GP_7
+};
+
+/**
+  This function provides ISH GP pin data
+
+  @param[in]  IshGpPinNumber        ISH GP pin number
+  @param[out] NativePin             ISH GP pin
+**/
+VOID
+GpioGetIshGpPin (
+  IN  UINT32                      IshGpPinNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  )
+{
+  if (IsPchLp ()) {
+    if (IshGpPinNumber < ARRAY_SIZE (mPchLpIshGPGpio)) {
+      *NativePin = mPchLpIshGPGpio[IshGpPinNumber];
+      return;
+    }
+  } else {
+    if (IshGpPinNumber < ARRAY_SIZE (mPchHIshGPGpio)) {
+      *NativePin = mPchHIshGPGpio[IshGpPinNumber];
+      return;
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// ISH UART controller pins
+// ISH UART[controller number][pin: RXD/TXD/RTSB/CTSB]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
+{
+  { // UART0
+    {GPIO_CNL_LP_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
+    {GPIO_CNL_LP_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
+    {GPIO_CNL_LP_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
+    {GPIO_CNL_LP_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
+  },
+  { // UART1
+    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
+    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
+    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTSB
+    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTSB
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
+{
+  { // UART0
+    {GPIO_CNL_H_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
+    {GPIO_CNL_H_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
+    {GPIO_CNL_H_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
+    {GPIO_CNL_H_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
+  },
+  { // UART1
+    {GPIO_CNL_H_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
+    {GPIO_CNL_H_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
+    {GPIO_CNL_H_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTS
+    {GPIO_CNL_H_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTS
+  }
+};
+
+/**
+  This function provides ISH UART controller pins
+
+  @param[in]  IshUartControllerNumber   ISH UART controller
+
+  @param[out] NativePinsTable           Table with pins
+**/
+VOID
+GpioGetIshUartPins (
+  IN  UINT32                      IshUartControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (IshUartControllerNumber < ARRAY_SIZE (mPchLpIshUartGpio)) {
+      *NativePinsTable = mPchLpIshUartGpio[IshUartControllerNumber];
+      return;
+    }
+  } else {
+    if (IshUartControllerNumber < ARRAY_SIZE (mPchHIshUartGpio)) {
+      *NativePinsTable = mPchHIshUartGpio[IshUartControllerNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// ISH I2C controller pins
+// ISH I2C[controller number][pin: SDA/SCL]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
+{
+  { // I2C0
+    {GPIO_CNL_LP_GPP_D5,  GpioPadModeNative1},// ISH_I2C0_SDA
+    {GPIO_CNL_LP_GPP_D6,  GpioPadModeNative1} // ISH_I2C0_SCL
+  },
+  { // I2C1
+    {GPIO_CNL_LP_GPP_D7,  GpioPadModeNative1},// ISH_I2C1_SDA
+    {GPIO_CNL_LP_GPP_D8,  GpioPadModeNative1} // ISH_I2C1_SCL
+  },
+  { // I2C2
+    {GPIO_CNL_LP_GPP_H10, GpioPadModeNative2},// ISH_I2C2_SDA
+    {GPIO_CNL_LP_GPP_H11, GpioPadModeNative2} // ISH_I2C2_SCL
+  },
+  { // I2C3
+    {GPIO_CNL_LP_GPP_H4,  GpioPadModeNative2},// ISH_I2C3_SDA
+    {GPIO_CNL_LP_GPP_H5,  GpioPadModeNative2} // ISH_I2C3_SCL
+  },
+  { // I2C4
+    {GPIO_CNL_LP_GPP_H6,  GpioPadModeNative2},// ISH_I2C4_SDA
+    {GPIO_CNL_LP_GPP_H7,  GpioPadModeNative2} // ISH_I2C4_SCL
+  },
+  { // I2C5
+    {GPIO_CNL_LP_GPP_H8,  GpioPadModeNative2},// ISH_I2C5_SDA
+    {GPIO_CNL_LP_GPP_H9,  GpioPadModeNative2} // ISH_I2C5_SCL
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
+{
+  { // I2C0
+    {GPIO_CNL_H_GPP_H19, GpioPadModeNative1},// ISH_I2C0_SDA
+    {GPIO_CNL_H_GPP_H20, GpioPadModeNative1} // ISH_I2C0_SCL
+  },
+  { // I2C1
+    {GPIO_CNL_H_GPP_H21, GpioPadModeNative1},// ISH_I2C1_SDA
+    {GPIO_CNL_H_GPP_H22, GpioPadModeNative1} // ISH_I2C1_SCL
+  },
+  { // I2C2
+    {GPIO_CNL_H_GPP_D4,  GpioPadModeNative1},// ISH_I2C2_SDA
+    {GPIO_CNL_H_GPP_D23, GpioPadModeNative1} // ISH_I2C2_SCL
+  }
+};
+
+/**
+  This function provides ISH I2C controller pins
+
+  @param[in]  IshI2cControllerNumber   ISH I2C controller
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetIshI2cPins (
+  IN  UINT32                      IshI2cControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (IshI2cControllerNumber < ARRAY_SIZE (mPchLpIshI2cGpio)) {
+      *NativePinsTable = mPchLpIshI2cGpio[IshI2cControllerNumber];
+      return;
+    }
+  } else {
+    if (IshI2cControllerNumber < ARRAY_SIZE (mPchHIshI2cGpio)) {
+      *NativePinsTable = mPchHIshI2cGpio[IshI2cControllerNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// ISH SPI controller pins
+// ISH SPI[pin: CSB/CLK/MISO/MOSI]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
+{
+  {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
+  {GPIO_CNL_LP_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
+  {GPIO_CNL_LP_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
+  {GPIO_CNL_LP_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
+{
+  {GPIO_CNL_H_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
+  {GPIO_CNL_H_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
+  {GPIO_CNL_H_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
+  {GPIO_CNL_H_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
+};
+
+/**
+  This function provides ISH SPI controller pins
+
+  @param[in]  IshSpiControllerNumber   SPI controller
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins           Number of pins
+**/
+VOID
+GpioGetIshSpiPins (
+  IN  UINT32                      IshSpiControllerNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    if (IshSpiControllerNumber < ARRAY_SIZE (mPchLpIshSpiGpio)) {
+      *NativePinsTable = mPchLpIshSpiGpio;
+      *NoOfNativePins = ARRAY_SIZE (mPchLpIshSpiGpio);
+      return;
+    }
+  } else {
+    if (IshSpiControllerNumber < ARRAY_SIZE (mPchHIshSpiGpio)) {
+      *NativePinsTable = mPchHIshSpiGpio;
+      *NoOfNativePins = ARRAY_SIZE (mPchHIshSpiGpio);
+      return;
+    }
+  }
+
+  *NoOfNativePins = 0;
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO pins for SD controller
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpScsSdCardGpio[9] =
+{
+  {GPIO_CNL_LP_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
+  {GPIO_CNL_LP_GPP_G0,  GpioPadModeNative1},// SD_CMD
+  {GPIO_CNL_LP_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
+  {GPIO_CNL_LP_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
+  {GPIO_CNL_LP_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
+  {GPIO_CNL_LP_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
+  {GPIO_CNL_LP_GPP_G5,  GpioPadModeNative1},// SD_CDB
+  {GPIO_CNL_LP_GPP_G6,  GpioPadModeNative1},// SD_CLK
+  {GPIO_CNL_LP_GPP_G7,  GpioPadModeNative1} // SD_WP
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHScsSdCardGpio[9] =
+{
+  {GPIO_CNL_H_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
+  {GPIO_CNL_H_GPP_G0,  GpioPadModeNative1},// SD_CMD
+  {GPIO_CNL_H_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
+  {GPIO_CNL_H_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
+  {GPIO_CNL_H_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
+  {GPIO_CNL_H_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
+  {GPIO_CNL_H_GPP_G5,  GpioPadModeNative1},// SD_CDB
+  {GPIO_CNL_H_GPP_G6,  GpioPadModeNative1},// SD_CLK
+  {GPIO_CNL_H_GPP_G7,  GpioPadModeNative1} // SD_WP
+};
+
+/**
+  This function provides SCS SD CARD controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsSdCardPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpScsSdCardGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpScsSdCardGpio);
+  } else {
+    *NativePinsTable = mPchHScsSdCardGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchHScsSdCardGpio);
+  }
+}
+
+/**
+  This function provides SCS SD CARD detect pin
+
+  @retval GpioPin             SD CARD Detect pin
+**/
+GPIO_PAD
+GpioGetScsSdCardDetectPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO39;
+  } else {
+    return GPIO_CNL_H_VGPIO6;
+  }
+}
+
+//
+// GPIO pins for eMMC controller
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpScsEmmcGpio[12] =
+{
+  {GPIO_CNL_LP_GPP_F11, GpioPadModeNative1},// EMMC_CMD
+  {GPIO_CNL_LP_GPP_F12, GpioPadModeNative1},// EMMC_DATA_0
+  {GPIO_CNL_LP_GPP_F13, GpioPadModeNative1},// EMMC_DATA_1
+  {GPIO_CNL_LP_GPP_F14, GpioPadModeNative1},// EMMC_DATA_2
+  {GPIO_CNL_LP_GPP_F15, GpioPadModeNative1},// EMMC_DATA_3
+  {GPIO_CNL_LP_GPP_F16, GpioPadModeNative1},// EMMC_DATA_4
+  {GPIO_CNL_LP_GPP_F17, GpioPadModeNative1},// EMMC_DATA_5
+  {GPIO_CNL_LP_GPP_F18, GpioPadModeNative1},// EMMC_DATA_6
+  {GPIO_CNL_LP_GPP_F19, GpioPadModeNative1},// EMMC_DATA_7
+  {GPIO_CNL_LP_GPP_F20, GpioPadModeNative1},// EMMC_RCLK
+  {GPIO_CNL_LP_GPP_F21, GpioPadModeNative1},// EMMC_CLK
+  {GPIO_CNL_LP_GPP_F22, GpioPadModeNative1} // EMMC_RESETB
+};
+
+/**
+  This function provides SCS eMMC controller pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetScsEmmcPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpScsEmmcGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpScsEmmcGpio);
+  } else {
+    ASSERT (FALSE);
+    return;
+  }
+}
+
+//
+// GPIO pins for HD Audio Link [pin: BCLK/RSTB/SYNC/SDO/SDIx]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
+  {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
+  {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
+  {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
+  {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
+  {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
+  {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
+  {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
+  {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
+  {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
+  {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
+};
+
+/**
+  This function provides HD Audio Link pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetHdAudioLinkPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpHdaLinkGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpHdaLinkGpio);
+  } else {
+    *NativePinsTable = mPchHHdaLinkGpio;
+    *NoOfNativePins = ARRAY_SIZE (mPchHHdaLinkGpio);
+  }
+}
+
+//
+// GPIO pins for HD Audio DMIC [DMIC number][pin: CLK/DATA]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
+{
+  { // DMIC0
+    {GPIO_CNL_LP_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
+    {GPIO_CNL_LP_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
+  },
+  { // DMIC1
+    {GPIO_CNL_LP_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
+    {GPIO_CNL_LP_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
+{
+  { // DMIC0
+    {GPIO_CNL_H_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
+    {GPIO_CNL_H_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
+  },
+  { // DMIC1
+    {GPIO_CNL_H_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
+    {GPIO_CNL_H_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
+  }
+};
+
+/**
+  This function provides DMIC interface pins
+
+  @param[in]  DmicNumber               DMIC interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaDmicPins (
+  IN  UINT32                      DmicNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (DmicNumber < ARRAY_SIZE (mPchLpHdaDmicGpio)) {
+      *NativePinsTable = mPchLpHdaDmicGpio[DmicNumber];
+      return;
+    }
+  } else {
+    if (DmicNumber < ARRAY_SIZE (mPchHHdaDmicGpio)) {
+      *NativePinsTable = mPchHHdaDmicGpio[DmicNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO pins for HD Audio SSPx/I2Sx interface [SSP number][pin: SCLK/SFRM/TXD/RXD]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
+{
+  { // SSP0/I2S0
+    {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
+    {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
+    {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
+    {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
+  },
+  { // SSP1/I2S1
+    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
+    {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
+    {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
+    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
+  },
+  { // SSP2/I2S2
+    {GPIO_CNL_LP_GPP_H0, GpioPadModeNative1},// SSP2_SCLK
+    {GPIO_CNL_LP_GPP_H1, GpioPadModeNative1},// SSP2_SFRM
+    {GPIO_CNL_LP_GPP_H2, GpioPadModeNative1},// SSP2_TXD
+    {GPIO_CNL_LP_GPP_H3, GpioPadModeNative1} // SSP2_RXD
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
+{
+  { // SSP0/I2S0
+    {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
+    {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
+    {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
+    {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
+  },
+  { // SSP1/I2S1
+    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
+    {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
+    {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
+    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
+  },
+  { // SSP2/I2S2
+    {GPIO_CNL_H_GPP_D5, GpioPadModeNative1}, // SSP2_SFRM
+    {GPIO_CNL_H_GPP_D6, GpioPadModeNative1}, // SSP2_TXD
+    {GPIO_CNL_H_GPP_D7, GpioPadModeNative1}, // SSP2_RXD
+    {GPIO_CNL_H_GPP_D8, GpioPadModeNative1}  // SSP2_SCLK
+  }
+};
+
+/**
+  This function provides SSP/I2S interface pins
+
+  @param[in]  SspInterfaceNumber       SSP/I2S interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSspPins (
+  IN  UINT32                      SspInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (SspInterfaceNumber < ARRAY_SIZE (mPchLpHdaSspInterfaceGpio)) {
+      *NativePinsTable = mPchLpHdaSspInterfaceGpio[SspInterfaceNumber];
+      return;
+    }
+  } else {
+    if (SspInterfaceNumber < ARRAY_SIZE (mPchHHdaSspInterfaceGpio)) {
+      *NativePinsTable = mPchHHdaSspInterfaceGpio[SspInterfaceNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO Pin for HD Audio SSP_MCLK/I2S_MCLK
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSspMasterClockGpio = {GPIO_CNL_LP_GPP_D23, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSspMasterClockGpio = {GPIO_CNL_H_GPP_B11, GpioPadModeNative1};
+
+/**
+  This function sets HDA SSP Master Clock into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSspMasterClock (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GpioSetPadMode (mPchLpHdaSspMasterClockGpio.Pad, mPchLpHdaSspMasterClockGpio.Mode);
+  } else {
+    return GpioSetPadMode (mPchHHdaSspMasterClockGpio.Pad, mPchHHdaSspMasterClockGpio.Mode);
+  }
+}
+
+//
+// GPIO pins for HD Audio SoundWire interface [SNDW number][pin: CLK/DATA]
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
+{
+  { // SNDW1
+    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
+    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
+  },
+  { // SNDW2
+    {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
+    {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
+  },
+  { // SNDW3
+    {GPIO_CNL_LP_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
+    {GPIO_CNL_LP_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
+  },
+  { // SNDW4
+    {GPIO_CNL_LP_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
+    {GPIO_CNL_LP_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
+{
+  { // SNDW1
+    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
+    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
+  },
+  { // SNDW2
+    {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
+    {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
+  },
+  { // SNDW3
+    {GPIO_CNL_H_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
+    {GPIO_CNL_H_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
+  },
+  { // SNDW4
+    {GPIO_CNL_H_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
+    {GPIO_CNL_H_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
+  }
+};
+
+/**
+  This function provides SNDW interface pins
+
+  @param[in]  SndwInterfaceNumber      SNDWx interface number
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetHdaSndwPins (
+  IN  UINT32                      SndwInterfaceNumber,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    if (SndwInterfaceNumber < ARRAY_SIZE (mPchLpHdaSndwGpio)) {
+      *NativePinsTable = mPchLpHdaSndwGpio[SndwInterfaceNumber];
+      return;
+    }
+  } else {
+    if (SndwInterfaceNumber < ARRAY_SIZE (mPchHHdaSndwGpio)) {
+      *NativePinsTable = mPchHHdaSndwGpio[SndwInterfaceNumber];
+      return;
+    }
+  }
+  *NativePinsTable = NULL;
+  ASSERT (FALSE);
+}
+
+//
+// GPIO pins for SMBUS
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_C0, GpioPadModeNative1},// SMB_CLK
+  {GPIO_CNL_LP_GPP_C1, GpioPadModeNative1} // SMB_DATA
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_C0, GpioPadModeNative1}, // SMB_CLK
+  {GPIO_CNL_H_GPP_C1, GpioPadModeNative1}  // SMB_DATA
+};
+
+/**
+  This function provides SMBUS interface pins
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetSmbusPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpSmbusGpio;
+  } else {
+    *NativePinsTable = mPchHSmbusGpio;
+  }
+}
+
+//
+// SMBUS Alert pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSmbusAlertGpio = {GPIO_CNL_LP_GPP_C2,  GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSmbusAlertGpio = {GPIO_CNL_H_GPP_C2,  GpioPadModeNative1};
+
+/**
+  This function sets SMBUS ALERT pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSmbusAlert (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION SmbusAlertGpio;
+
+  if (IsPchLp ()) {
+    SmbusAlertGpio = mPchLpSmbusAlertGpio;
+  } else {
+    SmbusAlertGpio = mPchHSmbusAlertGpio;
+  }
+
+  return GpioSetPadMode (SmbusAlertGpio.Pad, SmbusAlertGpio.Mode);
+}
+
+//
+// SATADevSlpPin to GPIO pin mapping
+// SATA_DEVSLP_x -> GPIO pin y
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataDevSlpPinToGpioMap[] =
+{
+  {GPIO_CNL_LP_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_E6, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataDevSlpPinToGpioMap[] =
+{
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F8, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F9, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata1DevSlpPinToGpioMap[] =
+{
+/// @todo SERVER- update for SATA 1
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata2DevSlpPinToGpioMap[] =
+{
+/// @todo SERVER- update for SATA 2
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata3DevSlpPinToGpioMap[] =
+{
+/// @todo SERVER- update for SATA 3
+  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
+};
+
+/**
+  This function provides SATA DevSlp pin data
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+  @param[out] NativePin           SATA DevSlp pin
+**/
+VOID
+GpioGetSataDevSlpPin (
+  IN  UINT32                    SataCtrlIndex,
+  IN  UINTN                     SataPort,
+  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
+  )
+{
+  if (IsCdfPch ()) {
+    if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata1DevSlpPinToGpioMap)) {
+        *NativePin = mCdfPchSata1DevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata2DevSlpPinToGpioMap)) {
+        *NativePin = mCdfPchSata2DevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata3DevSlpPinToGpioMap)) {
+        *NativePin = mCdfPchSata3DevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    }
+  } else {
+    if (IsPchLp ()) {
+      if (SataPort < ARRAY_SIZE (mPchLpSataDevSlpPinToGpioMap)) {
+        *NativePin = mPchLpSataDevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    } else {
+      if (SataPort < ARRAY_SIZE (mPchHSataDevSlpPinToGpioMap)) {
+        *NativePin = mPchHSataDevSlpPinToGpioMap[SataPort];
+        return;
+      }
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// SATA reset port to GPIO pin mapping
+// SATAGP_x -> GPIO pin y
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataGpToGpioMap[] =
+{
+  {GPIO_CNL_LP_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_LP_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_LP_GPP_E2, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataGpToGpioMap[]  =
+{
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F3, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F4, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata1GpToGpioMap[]  =
+{
+/// @todo SERVER- update for SATA 1
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata2GpToGpioMap[]  =
+{
+/// @todo SERVER- update for SATA 2
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mCdfPchSata3GpToGpioMap[]  =
+{
+/// @todo SERVER- update for SATA 3
+  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
+  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
+};
+
+/**
+  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
+  )
+{
+  if (IsCdfPch ()) {
+    if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata1GpToGpioMap)) {
+        *NativePin = mCdfPchSata1GpToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata2GpToGpioMap)) {
+        *NativePin = mCdfPchSata2GpToGpioMap[SataPort];
+        return;
+      }
+    } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
+      if (SataPort < ARRAY_SIZE (mCdfPchSata3GpToGpioMap)) {
+        *NativePin = mCdfPchSata3GpToGpioMap[SataPort];
+        return;
+      }
+    }
+  } else {
+    if (IsPchLp ()) {
+      if (SataPort < ARRAY_SIZE (mPchLpSataGpToGpioMap)) {
+        *NativePin = mPchLpSataGpToGpioMap[SataPort];
+        return;
+      }
+    } else {
+      if (SataPort < ARRAY_SIZE (mPchHSataGpToGpioMap)) {
+        *NativePin = mPchHSataGpToGpioMap[SataPort];
+        return;
+      }
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// SATA LED pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpSataLedGpio = {GPIO_CNL_LP_GPP_E8, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHSataLedGpio = {GPIO_CNL_H_GPP_E8, GpioPadModeNative1};
+
+/**
+  This function sets SATA LED pin into native mode. SATA LED indicates
+  SATA controller activity
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataLed (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  SataLedGpio;
+
+  if (IsPchLp ()) {
+    SataLedGpio = mPchLpSataLedGpio;
+  } else {
+    SataLedGpio = mPchHSataLedGpio;
+  }
+
+  return GpioSetPadMode (SataLedGpio.Pad, SataLedGpio.Mode);
+}
+
+//
+// USB2 OC pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpUsbOcGpioPins[] =
+{
+  {GPIO_CNL_LP_GPP_E9,  GpioPadModeNative1},// USB_OC_0
+  {GPIO_CNL_LP_GPP_E10, GpioPadModeNative1},// USB_OC_1
+  {GPIO_CNL_LP_GPP_E11, GpioPadModeNative1},// USB_OC_2
+  {GPIO_CNL_LP_GPP_E12, GpioPadModeNative1} // USB_OC_3
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHUsbOcGpioPins[] =
+{
+  {GPIO_CNL_H_GPP_E9,  GpioPadModeNative1},// USB_OC_0
+  {GPIO_CNL_H_GPP_E10, GpioPadModeNative1},// USB_OC_1
+  {GPIO_CNL_H_GPP_E11, GpioPadModeNative1},// USB_OC_2
+  {GPIO_CNL_H_GPP_E12, GpioPadModeNative1},// USB_OC_3
+  {GPIO_CNL_H_GPP_F15, GpioPadModeNative1},// USB_OC_4
+  {GPIO_CNL_H_GPP_F16, GpioPadModeNative1},// USB_OC_5
+  {GPIO_CNL_H_GPP_F17, GpioPadModeNative1},// USB_OC_6
+  {GPIO_CNL_H_GPP_F18, GpioPadModeNative1} // USB_OC_7
+};
+
+/**
+  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
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  OcGpio;
+
+  if (IsPchLp ()) {
+    if (OcPinNumber >= ARRAY_SIZE (mPchLpUsbOcGpioPins)) {
+      ASSERT(FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    OcGpio = mPchLpUsbOcGpioPins[OcPinNumber];
+  } else {
+    if (OcPinNumber >= ARRAY_SIZE (mPchHUsbOcGpioPins)) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    OcGpio = mPchHUsbOcGpioPins[OcPinNumber];
+  }
+
+  return GpioSetPadMode (OcGpio.Pad, OcGpio.Mode);
+}
+
+//
+// GPIO pin for PCIE SCRCLKREQB
+// SCRCLKREQB_x -> GPIO pin y
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpPcieSrcClkReqbPinToGpioMap[] =
+{
+  {GPIO_CNL_LP_GPP_B5,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B6,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B7,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B8,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B9,  GpioPadModeNative1},
+  {GPIO_CNL_LP_GPP_B10, GpioPadModeNative1}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHPcieSrcClkReqbPinToGpioMap[]  =
+{
+  {GPIO_CNL_H_GPP_B5,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B6,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B7,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B8,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B9,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_B10, GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H0,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H1,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H2,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H3,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H4,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H5,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H6,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H7,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H8,  GpioPadModeNative1},
+  {GPIO_CNL_H_GPP_H9,  GpioPadModeNative1}
+};
+
+/**
+  This function provides PCIe CLKREQ pin data
+
+  @param[in]  ClkreqIndex        CLKREQ# number
+  @param[out] NativePin          Native pin data
+**/
+VOID
+GpioGetPcieClkReqPin (
+  IN  UINT32                      ClkreqIndex,
+  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
+  )
+{
+  if (IsPchLp ()) {
+    if (ClkreqIndex < ARRAY_SIZE (mPchLpPcieSrcClkReqbPinToGpioMap)) {
+      *NativePin = mPchLpPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
+      return;
+    }
+  } else {
+    if (ClkreqIndex < ARRAY_SIZE (mPchHPcieSrcClkReqbPinToGpioMap)) {
+      *NativePin = mPchHPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
+      return;
+    }
+  }
+  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
+  ASSERT (FALSE);
+}
+
+//
+// PCHHOTB pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpPchHotbPin = {GPIO_CNL_LP_GPP_B23,  GpioPadModeNative2};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHPchHotbPin = {GPIO_CNL_H_GPP_B23,  GpioPadModeNative2};
+
+/**
+  This function sets PCHHOT pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnablePchHot (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION PchHotbPin;
+
+  if (IsPchLp ()) {
+    PchHotbPin = mPchLpPchHotbPin;
+  } else {
+    PchHotbPin = mPchHPchHotbPin;
+  }
+
+  return GpioSetPadMode (PchHotbPin.Pad, PchHotbPin.Mode);
+}
+
+//
+// VRALERTB pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpVrAlertbPin = {GPIO_CNL_LP_GPP_B2, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHVrAlertbPin = {GPIO_CNL_H_GPP_B2, GpioPadModeNative1};
+
+//
+// CPU_C10_GATE pin
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCpuC10GatePin = {GPIO_CNL_LP_GPP_H18, GpioPadModeNative1};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCpuC10GatePin = {GPIO_CNL_H_GPP_J1, GpioPadModeNative2};
+
+/**
+  This function sets VRALERTB pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableVrAlert (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  VrAlertGpio;
+
+  if (IsPchLp ()) {
+    VrAlertGpio = mPchLpVrAlertbPin;
+  } else {
+    VrAlertGpio = mPchHVrAlertbPin;
+  }
+
+  return GpioSetPadMode (VrAlertGpio.Pad, VrAlertGpio.Mode);
+}
+
+/**
+This function sets CPU C10 Gate pins into native mode
+
+@retval Status
+**/
+EFI_STATUS
+GpioEnableCpuC10GatePin (
+  VOID
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  CpuC10GateGpio;
+
+  if (IsPchLp ()) {
+    CpuC10GateGpio = mPchLpCpuC10GatePin;
+  } else {
+    CpuC10GateGpio = mPchHCpuC10GatePin;
+  }
+
+  return GpioSetPadMode (CpuC10GateGpio.Pad, CpuC10GateGpio.Mode);
+}
+
+//
+// CPU GP pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
+  {GPIO_CNL_LP_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
+  {GPIO_CNL_LP_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
+  {GPIO_CNL_LP_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
+};
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
+  {GPIO_CNL_H_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
+  {GPIO_CNL_H_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
+  {GPIO_CNL_H_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
+};
+
+/**
+  This function sets CPU GP pins into native mode
+
+  @param[in]  CpuGpPinNum               CPU GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableCpuGpPin (
+  IN  UINT32                            CpuGpPinNum
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION CpuGpPin;
+
+  if (IsPchLp ()) {
+    if (CpuGpPinNum >= ARRAY_SIZE (mPchLpCpuGpPinMap)) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    CpuGpPin = mPchLpCpuGpPinMap[CpuGpPinNum];
+  } else {
+    if (CpuGpPinNum >= ARRAY_SIZE (mPchHCpuGpPinMap)) {
+      ASSERT(FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    CpuGpPin = mPchHCpuGpPinMap[CpuGpPinNum];
+  }
+
+  return GpioSetPadMode (CpuGpPin.Pad, CpuGpPin.Mode);
+}
+
+//
+// DDSP_HPD pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpDdspHpdPins[] =
+{
+  {GPIO_CNL_LP_GPP_E13, GpioPadModeNative1},// DDSP_HPD_0
+  {GPIO_CNL_LP_GPP_E14, GpioPadModeNative1},// DDSP_HPD_1
+  {GPIO_CNL_LP_GPP_E15, GpioPadModeNative1},// DDSP_HPD_2
+  {GPIO_CNL_LP_GPP_E16, GpioPadModeNative1} // DDSP_HPD_3
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHDdspHpdPins[] =
+{
+  {GPIO_CNL_H_GPP_I0, GpioPadModeNative1},// DDSP_HPD_0
+  {GPIO_CNL_H_GPP_I1, GpioPadModeNative1},// DDSP_HPD_1
+  {GPIO_CNL_H_GPP_I2, GpioPadModeNative1},// DDSP_HPD_2
+  {GPIO_CNL_H_GPP_I3, GpioPadModeNative1} // DDSP_HPD_3
+};
+
+/**
+  This function sets DDSP_HPDx pin into native mode
+
+  @param[in]  DdspHpdPin     DDSP_HPDx pin
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpHotPlugDetect (
+  IN GPIO_DDSP_HPD  DdspHpdPin
+  )
+{
+  GPIO_PAD_NATIVE_FUNCTION  DdspHpdGpio;
+  UINT32                    DdspHpdPinIndex;
+
+  if (DdspHpdPin > GpioDdspHpd3) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DdspHpdPinIndex = DdspHpdPin - GpioDdspHpd0;
+
+  if (IsPchLp ()) {
+    if (DdspHpdPinIndex >= ARRAY_SIZE (mPchLpDdspHpdPins)) {
+      goto Error;
+    }
+    DdspHpdGpio = mPchLpDdspHpdPins[DdspHpdPinIndex];
+  } else {
+    if (DdspHpdPinIndex >= ARRAY_SIZE (mPchHDdspHpdPins)) {
+      goto Error;
+    }
+    DdspHpdGpio = mPchHDdspHpdPins[DdspHpdPinIndex];
+  }
+
+  return GpioSetPadMode (DdspHpdGpio.Pad, DdspHpdGpio.Mode);
+Error:
+  ASSERT (FALSE);
+  return EFI_UNSUPPORTED;
+}
+
+//
+// EDP HPD, VDD and BKLT pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_E17,         GpioPadModeNative1},// EDP_HPD
+  {GPIO_CNL_LP_HVMOS_L_VDDEN,   GpioPadModeNative1},// VDDEN
+  {GPIO_CNL_LP_HVMOS_L_BKLTEN,  GpioPadModeNative1},// BKLTEN
+  {GPIO_CNL_LP_HVMOS_L_BKLTCTL, GpioPadModeNative1} // BKLTCTL
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_I4,  GpioPadModeNative1},// EDP_HPD
+  {GPIO_CNL_H_GPP_F19, GpioPadModeNative1},// VDDEN
+  {GPIO_CNL_H_GPP_F20, GpioPadModeNative1},// BKLTEN
+  {GPIO_CNL_H_GPP_F21, GpioPadModeNative1} // BKLTCTL
+};
+
+/**
+  This function provides eDP pins
+
+  @param[out] NativePinsTable                Table with pins
+  @param[out] NoOfNativePins                 Number of pins
+**/
+VOID
+GpioGetEdpPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
+  OUT UINT32                      *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpEdpPins;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpEdpPins);
+  } else {
+    *NativePinsTable = mPchHEdpPins;
+    *NoOfNativePins = ARRAY_SIZE (mPchHEdpPins);
+  }
+}
+
+//
+// DDPB/C/D/F  CTRLCLK and CTRLDATA pins
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GPIO_DDP_NUMBER_OF_PINS] =
+{
+  {// DDPB
+    {GPIO_CNL_LP_GPP_E18, GpioPadModeNative1},// DDPB_CTRLCLK
+    {GPIO_CNL_LP_GPP_E19, GpioPadModeNative1} // DDPB_CTRLDATA
+  },
+  {// DDPC
+    {GPIO_CNL_LP_GPP_E20, GpioPadModeNative1},// DDPC_CTRLCLK
+    {GPIO_CNL_LP_GPP_E21, GpioPadModeNative1} // DDPC_CTRLDATA
+  },
+  {// DDPD
+    {GPIO_CNL_LP_GPP_E22, GpioPadModeNative1},// DDPD_CTRLCLK
+    {GPIO_CNL_LP_GPP_E23, GpioPadModeNative1} // DDPD_CTRLDATA
+  },
+  {// DDPF
+    {GPIO_CNL_LP_GPP_H16, GpioPadModeNative1},// DDPF_CTRLCLK
+    {GPIO_CNL_LP_GPP_H17, GpioPadModeNative1} // DDPF_CTRLDATA
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GPIO_DDP_NUMBER_OF_PINS] =
+{
+  {// DDPB
+    {GPIO_CNL_H_GPP_I5,  GpioPadModeNative1}, // DDPB_CTRLCLK
+    {GPIO_CNL_H_GPP_I6,  GpioPadModeNative1}, // DDPB_CTRLDATA
+  },
+  {// DDPC
+    {GPIO_CNL_H_GPP_I7,  GpioPadModeNative1}, // DDPC_CTRLCLK
+    {GPIO_CNL_H_GPP_I8,  GpioPadModeNative1}, // DDPC_CTRLDATA
+  },
+  {// DDPD
+    {GPIO_CNL_H_GPP_I9,  GpioPadModeNative1}, // DDPD_CTRLCLK
+    {GPIO_CNL_H_GPP_I10, GpioPadModeNative1}, // DDPD_CTRLDATA
+  },
+  {// DDPF
+    {GPIO_CNL_H_GPP_F22, GpioPadModeNative1}, // DDPF_CTRLCLK
+    {GPIO_CNL_H_GPP_F23, GpioPadModeNative1}, // DDPF_CTRLDATA
+  }
+};
+
+/**
+  This function provides DDPx interface pins
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetDdpPins (
+  IN  GPIO_DDP                    DdpInterface,
+  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
+  )
+{
+  UINT32  DdpInterfaceIndex;
+
+  switch (DdpInterface) {
+    case GpioDdpB:
+    case GpioDdpC:
+    case GpioDdpD:
+      DdpInterfaceIndex = DdpInterface - GpioDdpB;
+      break;
+    case GpioDdpF:
+      DdpInterfaceIndex = 3;
+      break;
+    default:
+      goto Error;
+  }
+
+  if (IsPchLp ()) {
+    if (DdpInterfaceIndex < ARRAY_SIZE (mPchLpDdpInterfacePins)) {
+      *NativePinsTable = mPchLpDdpInterfacePins[DdpInterfaceIndex];
+      return;
+    }
+  } else {
+    if (DdpInterfaceIndex < ARRAY_SIZE (mPchHDdpInterfacePins)) {
+      *NativePinsTable = mPchHDdpInterfacePins[DdpInterfaceIndex];
+      return;
+    }
+  }
+Error:
+  *NativePinsTable = NULL;
+  ASSERT(FALSE);
+}
+
+/**
+  This function enables CNVi RF Reset pin
+**/
+VOID
+GpioEnableCnviRfResetPin (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  GPIO_PAD        GpioPad;
+  GPIO_PAD_MODE   PadMode;
+
+  if (IsPchLp ()) {
+    GpioPad = GPIO_CNL_LP_GPP_H1;
+    PadMode = GpioPadModeNative3;
+  } else {
+    GpioPad = GPIO_CNL_H_GPP_D5;
+    PadMode = GpioPadModeNative3;
+  }
+
+  Status = GpioSetPadMode (GpioPad, PadMode);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function enables CNVi MODEM CLKREQ pin
+**/
+VOID
+GpioEnableCnviModemClkReqPin (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  GPIO_PAD        GpioPad;
+  GPIO_PAD_MODE   PadMode;
+
+  if (IsPchLp ()) {
+    GpioPad = GPIO_CNL_LP_GPP_H2;
+    PadMode = GpioPadModeNative3;
+  } else {
+    GpioPad = GPIO_CNL_H_GPP_D6;
+    PadMode = GpioPadModeNative3;
+  }
+
+  Status = GpioSetPadMode (GpioPad, PadMode);
+  ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+  This function provides CNVi BT interface select pin
+
+  @retval GpioPad          GPIO pad for CNVi BT interface select
+**/
+GPIO_PAD
+GpioGetCnviBtIfSelectPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO5;
+  } else {
+    return GPIO_CNL_H_VGPIO7;
+  }
+}
+
+/**
+  This function provides CNVi BT Charging pin
+
+  @retval GpioPad          GPIO pad for CNVi BT Charging select
+**/
+GPIO_PAD
+GpioGetCnviBtChargingPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO3;
+  } else {
+    return GPIO_CNL_H_VGPIO3;
+  }
+}
+
+/**
+  This function provides CNVi A4WP pin
+
+  @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
+**/
+VOID
+GpioGetCnviA4WpPin (
+  OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
+  )
+{
+  GpioNativePad->Mode = GpioPadModeNative1;
+  if (IsPchLp ()) {
+    GpioNativePad->Pad = GPIO_CNL_LP_GPP_F23;
+  } else {
+    GpioNativePad->Pad = GPIO_CNL_H_GPP_J11;
+  }
+}
+
+/**
+  This function provides CNVi BT host wake int pin
+
+  @retval GpioPad          GPIO pad BT host wake int
+**/
+GPIO_PAD
+GpioGetCnviBtHostWakeIntPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO4;
+  } else {
+    return GPIO_CNL_H_VGPIO4;
+  }
+}
+
+//
+// CNVi Bluetooth UART pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO6, // vCNV_BT_UART_TXD
+  GPIO_CNL_LP_VGPIO7, // vCNV_BT_UART_RXD
+  GPIO_CNL_LP_VGPIO8, // vCNV_BT_UART_CTS_B
+  GPIO_CNL_LP_VGPIO9  // vCNV_BT_UART_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO8, // vCNV_BT_UART_TXD
+  GPIO_CNL_H_VGPIO9, // vCNV_BT_UART_RXD
+  GPIO_CNL_H_VGPIO10,// vCNV_BT_UART_CTS_B
+  GPIO_CNL_H_VGPIO11 // vCNV_BT_UART_RTS_B
+};
+
+//
+// vUART for Bluetooth
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO18, // vUART0_TXD
+  GPIO_CNL_LP_VGPIO19, // vUART0_RXD
+  GPIO_CNL_LP_VGPIO20, // vUART0_CTS_B
+  GPIO_CNL_LP_VGPIO21  // vUART0_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO20, // vUART0_TXD
+  GPIO_CNL_H_VGPIO21, // vUART0_RXD
+  GPIO_CNL_H_VGPIO22, // vUART0_CTS_B
+  GPIO_CNL_H_VGPIO23  // vUART0_RTS_B
+};
+
+/**
+  This function provides CNVi BT UART pins
+
+  @param[in]  ConnectionType           CNVi BT UART connection type
+  @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
+  @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
+  @param[out] VUartForCnviBtPad        Table with vUART0 pads
+  @param[out] VUartForCnviBtPadMode    vUART0 pad mode
+**/
+VOID
+GpioGetCnviBtUartPins (
+  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                            **VCnviBtUartPad,
+  OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
+  OUT GPIO_PAD                            **VUartForCnviBtPad,
+  OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
+  )
+{
+  if (IsPchLp ()) {
+    *VCnviBtUartPad = mPchLpVCnviBtUartGpioPad;
+    *VUartForCnviBtPad = mPchLpVUartForCnviBtGpioPad;
+  } else {
+    *VCnviBtUartPad = mPchHVCnviBtUartGpioPad;
+    *VUartForCnviBtPad = mPchHVUartForCnviBtGpioPad;
+  }
+
+  switch (ConnectionType) {
+    case GpioCnviBtUartToSerialIoUart0:
+      *VCnviBtUartPadMode = GpioPadModeNative1;
+      *VUartForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtUartToIshUart0:
+      *VCnviBtUartPadMode = GpioPadModeNative2;
+      *VUartForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtUartNotConnected:
+    case GpioCnviBtUartToExternalPads:
+      *VCnviBtUartPadMode = GpioPadModeGpio;
+      *VUartForCnviBtPadMode = GpioPadModeGpio;
+      break;
+    default:
+      ASSERT (FALSE);
+      return;
+  }
+}
+
+//
+// CNVi Bluetooth UART external pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
+  {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
+  {GPIO_CNL_LP_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
+  {GPIO_CNL_LP_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
+  {GPIO_CNL_H_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
+  {GPIO_CNL_H_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
+  {GPIO_CNL_H_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
+};
+
+/**
+  This function provides CNVi BT UART external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtUartExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviBtUartExternalPads;
+  } else {
+    *NativePinsTable = mPchHCnviBtUartExternalPads;
+  }
+}
+
+//
+// CNVi Bluetooth I2S pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO30, // vCNV_BT_I2S_BCLK
+  GPIO_CNL_LP_VGPIO31, // vCNV_BT_I2S_WS_SYNC
+  GPIO_CNL_LP_VGPIO32, // vCNV_BT_I2S_SDO
+  GPIO_CNL_LP_VGPIO33  // vCNV_BT_I2S_SDI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO32, // vCNV_BT_I2S_BCLK
+  GPIO_CNL_H_VGPIO33, // vCNV_BT_I2S_WS_SYNC
+  GPIO_CNL_H_VGPIO34, // vCNV_BT_I2S_SDO
+  GPIO_CNL_H_VGPIO35  // vCNV_BT_I2S_SDI
+};
+
+//
+// vSSP for Bluetooth
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO34, // vSSP2_SCLK
+  GPIO_CNL_LP_VGPIO35, // vSSP2_SFRM
+  GPIO_CNL_LP_VGPIO36, // vSSP2_TXD
+  GPIO_CNL_LP_VGPIO37  // vSSP2_RXD
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO36, // vSSP2_SCLK
+  GPIO_CNL_H_VGPIO37, // vSSP2_SFRM
+  GPIO_CNL_H_VGPIO38, // vSSP2_TXD
+  GPIO_CNL_H_VGPIO39  // vSSP2_RXD
+};
+
+/**
+  This function provides CNVi BT I2S pins
+
+  @param[in]  ConnectionType          CNVi BT I2S connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
+  @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
+  @param[out] VSspForCnviBtPad        Table with vSSP2 pads
+  @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
+**/
+VOID
+GpioGetCnviBtI2sPins (
+  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviBtI2sPad,
+  OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
+  OUT GPIO_PAD                 **VSspForCnviBtPad,
+  OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
+  )
+{
+  if (IsPchLp ()) {
+    *VCnviBtI2sPad = mPchLpVCnviBtI2sGpioPad;
+    *VSspForCnviBtPad = mPchLpVSspForCnviBtGpioPad;
+  } else {
+    *VCnviBtI2sPad = mPchHVCnviBtI2sGpioPad;
+    *VSspForCnviBtPad = mPchHVSspForCnviBtGpioPad;
+  }
+
+  switch (ConnectionType) {
+    case GpioCnviBtI2sToSsp0:
+      *VCnviBtI2sPadMode = GpioPadModeNative1;
+      *VSspForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtI2sToSsp1:
+      *VCnviBtI2sPadMode = GpioPadModeNative2;
+      *VSspForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtI2sToSsp2:
+      *VCnviBtI2sPadMode = GpioPadModeNative3;
+      *VSspForCnviBtPadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviBtI2sNotConnected:
+    case GpioCnviBtI2sToExternalPads:
+      *VCnviBtI2sPadMode = GpioPadModeGpio;
+      *VSspForCnviBtPadMode = GpioPadModeGpio;
+      break;
+    default:
+      ASSERT (FALSE);
+      return;
+  }
+}
+
+//
+// CNVi Bluetooth I2S external pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_H0, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
+  {GPIO_CNL_LP_GPP_H1, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
+  {GPIO_CNL_LP_GPP_H2, GpioPadModeNative2}, // CNV_BT_I2S_SDI
+  {GPIO_CNL_LP_GPP_H3, GpioPadModeNative2}  // CNV_BT_I2S_SDO
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_D8, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
+  {GPIO_CNL_H_GPP_D5, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
+  {GPIO_CNL_H_GPP_D6, GpioPadModeNative2}, // CNV_BT_I2S_SDI
+  {GPIO_CNL_H_GPP_D7, GpioPadModeNative2}  // CNV_BT_I2S_SDO
+};
+
+/**
+  This function provides CNVi BT I2S external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviBtI2sExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviBtI2sExternalPads;
+  } else {
+    *NativePinsTable = mPchHCnviBtI2sExternalPads;
+  }
+}
+
+//
+// CNVi MFUART1 pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO10, // vCNV_MFUART1_TXD
+  GPIO_CNL_LP_VGPIO11, // vCNV_MFUART1_RXD
+  GPIO_CNL_LP_VGPIO12, // vCNV_MFUART1_CTS_B
+  GPIO_CNL_LP_VGPIO13  // vCNV_MFUART1_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO12, // vCNV_MFUART1_TXD
+  GPIO_CNL_H_VGPIO13, // vCNV_MFUART1_RXD
+  GPIO_CNL_H_VGPIO14, // vCNV_MFUART1_CTS_B
+  GPIO_CNL_H_VGPIO15  // vCNV_MFUART1_RTS_B
+};
+
+//
+// vUART for MFUART1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchLpVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_LP_VGPIO22, // vISH_UART0_TXD
+  GPIO_CNL_LP_VGPIO23, // vISH_UART0_RXD
+  GPIO_CNL_LP_VGPIO24, // vISH_UART0_CTS_B
+  GPIO_CNL_LP_VGPIO25  // vISH_UART0_RTS_B
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD mPchHVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  GPIO_CNL_H_VGPIO24, // vISH_UART0_TXD
+  GPIO_CNL_H_VGPIO25, // vISH_UART0_RXD
+  GPIO_CNL_H_VGPIO26, // vISH_UART0_CTS_B
+  GPIO_CNL_H_VGPIO27  // vISH_UART0_RTS_B
+};
+
+/**
+  This function provides CNVi MFUART1 pins
+
+  @param[in]  ConnectionType          CNVi MFUART1 connection type
+  @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
+  @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
+  @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
+  @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
+**/
+VOID
+GpioGetCnviMfUart1Pins (
+  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
+  OUT GPIO_PAD                 **VCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
+  OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
+  OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
+  )
+{
+  if (IsPchLp ()) {
+    *VCnviMfUart1Pad = mPchLpVCnviMfUart1GpioPad;
+    *VUartForCnviMfUart1Pad = mPchLpVUartForCnviMfUart1GpioPad;
+  } else {
+    *VCnviMfUart1Pad = mPchHVCnviMfUart1GpioPad;
+    *VUartForCnviMfUart1Pad = mPchHVUartForCnviMfUart1GpioPad;
+  }
+
+  switch (ConnectionType) {
+    case GpioCnviMfUart1ToSerialIoUart2:
+      *VCnviMfUart1PadMode = GpioPadModeNative2;
+      *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviMfUart1ToIshUart0:
+      *VCnviMfUart1PadMode = GpioPadModeNative1;
+      *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
+      break;
+    case GpioCnviMfUart1NotConnected:
+    case GpioCnviMfUart1ToExternalPads:
+      *VCnviMfUart1PadMode = GpioPadModeGpio;
+      *VUartForCnviMfUart1PadMode = GpioPadModeGpio;
+      break;
+    default:
+      ASSERT (FALSE);
+      return;
+  }
+}
+
+//
+// CNVi MFUART1 external pads
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
+  {GPIO_CNL_LP_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
+  {GPIO_CNL_LP_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
+  {GPIO_CNL_LP_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
+  {GPIO_CNL_H_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
+  {GPIO_CNL_H_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
+  {GPIO_CNL_H_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
+};
+
+/**
+  This function provides CNVi MFUART1 external pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnviMfUart1ExternalPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviMfUart1ExternalPads;
+  } else {
+    *NativePinsTable = mPchHCnviMfUart1ExternalPads;
+  }
+}
+
+/**
+  This function provides CNVi Bluetooth Enable pad
+
+  @retval GpioPad           CNVi Bluetooth Enable pad
+**/
+GPIO_PAD
+GpioGetCnviBtEnablePin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_VGPIO0;
+  } else {
+    return GPIO_CNL_H_VGPIO0;
+  }
+}
+
+//
+// CNVi BRI (Bluetooth Radio Interface) and RGI (Radio Generic Interface) buses from Pulsar to CRF (Companion RF)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_F4, GpioPadModeNative1}, // CNV_BRI_DT
+  {GPIO_CNL_LP_GPP_F5, GpioPadModeNative1}, // CNV_BRI_RSP
+  {GPIO_CNL_LP_GPP_F6, GpioPadModeNative1}, // CNV_RGI_DT
+  {GPIO_CNL_LP_GPP_F7, GpioPadModeNative1}  // CNV_RGI_RSP
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_J4, GpioPadModeNative1}, // CNV_BRI_DT
+  {GPIO_CNL_H_GPP_J5, GpioPadModeNative1}, // CNV_BRI_RSP
+  {GPIO_CNL_H_GPP_J6, GpioPadModeNative1}, // CNV_RGI_DT
+  {GPIO_CNL_H_GPP_J7, GpioPadModeNative1}  // CNV_RGI_RSP
+};
+
+/**
+  This function provides CNVi BRI RGI GPIO pads
+
+  @param[out] NativePinsTable          Table with pins
+**/
+VOID
+GpioGetCnvBriRgiPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpCnviBriRgiGpioPad;
+  } else {
+    *NativePinsTable = mPchHCnviBriRgiGpioPad;
+  }
+}
+
+
+/**
+  This function sets CNVi WiFi mode
+
+  @param[in] Value                CNVi WiFi Mode value
+                                  GpioCnviWiFiAuto: WiFi is automatically enabled/disabled by WiFi core
+                                  GpioCnviWiFiEnabled: WiFi is enabled regardless of WiFi core decision
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviWifiMode (
+  IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
+  )
+{
+  EFI_STATUS  Status;
+  GPIO_PAD    CnviWifiModePad;
+  GPIO_CONFIG PadConfig;
+
+  ZeroMem (&PadConfig, sizeof (PadConfig));
+
+  PadConfig.PadMode = GpioPadModeGpio;
+  PadConfig.Direction = GpioDirOut;
+  if (WiFiMode == GpioCnviWiFiEnabled) {
+    PadConfig.OutputState = GpioOutHigh;
+  } else {
+    PadConfig.OutputState = GpioOutLow;
+  }
+
+  if (IsPchLp ()) {
+    CnviWifiModePad = GPIO_CNL_LP_VGPIO2;
+  } else {
+    CnviWifiModePad = GPIO_CNL_H_VGPIO2;
+  }
+
+  Status = GpioSetPadConfig (CnviWifiModePad, &PadConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchLpImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_LP_GPP_D4,  GpioPadModeNative1}, // IMGCLKOUT_0
+  {GPIO_CNL_LP_GPP_H20, GpioPadModeNative1}, // IMGCLKOUT_1
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION mPchHImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
+{
+  {GPIO_CNL_H_GPP_K22, GpioPadModeNative1}, // IMGCLKOUT_0
+  {GPIO_CNL_H_GPP_K23, GpioPadModeNative1}, // IMGCLKOUT_1
+};
+
+/**
+  This function provides IMGCLKOUT pins
+
+  @param[out] NativePinsTable          Table with pins
+  @param[out] NoOfNativePins            Number of pins
+**/
+VOID
+GpioGetImgClkOutPins (
+  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
+  OUT UINT32                   *NoOfNativePins
+  )
+{
+  if (IsPchLp ()) {
+    *NativePinsTable = mPchLpImguClkOutGpioPad;
+    *NoOfNativePins = ARRAY_SIZE (mPchLpImguClkOutGpioPad);
+  } else {
+    *NativePinsTable = mPchHImguClkOutGpioPad;
+    *NoOfNativePins = ARRAY_SIZE (mPchHImguClkOutGpioPad);
+  }
+}
+
+/**
+  This function provides PWRBTN pin
+
+  @retval GpioPad          PWRTBTN pin
+**/
+GPIO_PAD
+GpioGetPwrBtnPin (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_GPD3;
+  } else {
+    return GPIO_CNL_H_GPD3;
+  }
+}
+
+/**
+  This function provides LPC pin
+
+  @retval GpioPad          LPC pin
+**/
+GPIO_PAD
+GpioGetLpcPin (
+  VOID
+  )
+{
+  if (PchGetLpcDid () == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU) {
+    return GPIO_CNL_H_GPP_A8;
+  } else {
+    return 0;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
new file mode 100644
index 0000000000..2cf11c6da2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
@@ -0,0 +1,752 @@
+/** @file
+  This file contains GPIO routines for RC usage
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h>
+#include <Private/Library/GpioNameBufferLib.h>
+#include <Register/PchRegsPcr.h>
+
+#include "GpioNativePrivateLibInternal.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 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
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  //
+  // Check if group argument exceeds GPIO GROUP INFO array
+  //
+  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *RegVal = MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, Offset));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  //
+  // Check if group argument exceeds GPIO GROUP INFO array
+  //
+  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MmioWrite32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, Offset), RegVal);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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 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
+  )
+{
+  UINT32       Data32And;
+  UINT32       Data32Or;
+  PCH_SBI_PID  *GpioComSbiIds;
+  UINT32       NoOfGpioComs;
+  UINT32       GpioComIndex;
+
+  Data32And = (UINT32)~(B_GPIO_PCR_MISCCFG_IRQ_ROUTE);
+  Data32Or  = (UINT32)Irq << N_GPIO_PCR_MISCCFG_IRQ_ROUTE;
+
+  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
+
+  //
+  // Program MISCCFG register for each community
+  //
+  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) {
+    MmioAndThenOr32 (
+      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], R_GPIO_PCR_MISCCFG),
+      Data32And,
+      Data32Or
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  return GpioGroupInfo[GroupIndex].Community;
+}
+
+/**
+  This procedure will return PadCfg address from GpioPad
+
+  @param[in] GpioPad            GpioPad
+
+  @retval GpioPadCfgAddress     PadCfg Address of GpioPad
+**/
+UINT32
+GpioGetGpioPadCfgAddressFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  )
+{
+  UINT32                 PadCfgRegAddress;
+  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
+  //
+  PadCfgRegAddress = GpioGroupInfo[GroupIndex].PadCfgOffset + S_GPIO_PCR_PADCFG * PadNumber;
+
+  return PadCfgRegAddress;
+}
+
+
+/**
+  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;
+
+  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
+  //
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  if (PadNumber >= GpioGroupInfo[GpioGetGroupIndexFromGpioPad (GpioPad)].PadPerGroup) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for this group\n", PadNumber));
+    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[out] 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;
+
+  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;
+}
+
+/**
+  The function performs GPIO Power Management programming.
+**/
+VOID
+GpioConfigurePm (
+  VOID
+  )
+{
+  UINT32       Data32Or;
+  UINT32       Data32And;
+  PCH_SBI_PID  *GpioComSbiIds;
+  UINT32       NoOfGpioComs;
+  UINT32       GpioComIndex;
+
+  Data32And = (UINT32)~0,
+  //
+  // Enable MISCCFG.GPSIDEDPCGEn, MISCCFG.GPRCOMPCDLCGEn, MISCCFG.GPRTCDLCGEn,
+  // MISCCFG.GPDLCGEn and MISCCFG.GPDPCGEn for GPIO communities
+  //
+  Data32Or = (B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN |
+              B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN |
+              B_GPIO_PCR_MISCCFG_GPRTCDLCGEN |
+              B_GPIO_PCR_MISCCFG_GPDLCGEN |
+              B_GPIO_PCR_MISCCFG_GPDPCGEN);
+
+  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
+
+  //
+  // Configure Clock Gating in each community
+  //
+  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) {
+    MmioAndThenOr32 (
+      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], R_GPIO_PCR_MISCCFG),
+      Data32And,
+      Data32Or
+      );
+  }
+}
+
+/**
+  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
+  )
+{
+  UINT32         DwNum;
+  UINT32         GroupIndex;
+  UINT32         NumberOfGroups;
+  GPIO_GROUP     Group;
+  UINT32         LockValue;
+  EFI_STATUS     Status;
+
+  NumberOfGroups = GpioGetNumberOfGroups ();
+
+  for (GroupIndex = 0; GroupIndex < NumberOfGroups; GroupIndex++) {
+    Group = GpioGetGroupFromGroupIndex (GroupIndex);
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
+
+      GpioGetPadCfgLockForGroupDw (Group, DwNum, &LockValue);
+
+      if (LockValue) {
+        Status = GpioUnlockPadCfgForGroupDw (Group, DwNum, ~0u);
+        ASSERT_EFI_ERROR (Status);
+      }
+
+      GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &LockValue);
+
+      if (LockValue) {
+        Status = GpioUnlockPadCfgTxForGroupDw (Group, DwNum, ~0u);
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+}
+
+/**
+  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);
+}
+
+
+//
+// For GPIO debounce feature glitch filter clock is used
+// which is driven by RTC clock with f = 32kHz (T = 31.25us)
+//
+#define GPIO_DEB_CLK_PERIOD_IN_NS  31250
+
+/**
+  This procedure enables debounce feature on a selected pad configured in input mode
+  Debounce time can be specified in microseconds. GPIO HW supports only certain values
+  according to below formula:
+   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 GPIO HW, function will round down
+  to closest supported
+
+  @param[in] GpioPad              GPIO pad
+  @param[in, out] DebounceTime    Debounce Time in microseconds
+                                  If Debounce Time = 0, Debouncer feature will be disabled
+                                  Function will set DebounceTime argument to rounded supported value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad or unsupported DebounceDuration value
+  @retval EFI_UNSUPPORTED         GpioPad is not owned by host
+**/
+EFI_STATUS
+GpioSetDebounceTimer (
+  IN GPIO_PAD                  GpioPad,
+  IN OUT UINT32                *DebounceTime
+  )
+{
+  UINT32   DebounceEnable;
+  UINT32   DebounceValue;
+  UINT32   InRangeDebounceTime;
+  UINT32   SupportedDebounceTime;
+  UINT32   Temp;
+  BOOLEAN  SupportedValue;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (*DebounceTime > 1024000) {
+    InRangeDebounceTime = 1024000;
+    SupportedValue = FALSE;
+  } else if ((*DebounceTime < 250) && (*DebounceTime > 0)) {
+    InRangeDebounceTime = 0;
+    SupportedValue = FALSE;
+  } else {
+    InRangeDebounceTime = *DebounceTime;
+    SupportedValue = TRUE;
+  }
+
+  //
+  // DebounceValue = log2 (InRangeDebounceTime * f_deb_clk)
+  //
+  DebounceValue = 0;
+  Temp = InRangeDebounceTime * 1000 / GPIO_DEB_CLK_PERIOD_IN_NS;
+
+  //
+  // Check if any rounding occurred
+  //
+  if (InRangeDebounceTime != (Temp * GPIO_DEB_CLK_PERIOD_IN_NS / 1000)) {
+    SupportedValue = FALSE;
+  }
+
+  //
+  // Check if value is power of 2
+  //
+  if ((Temp != 0) && ((Temp & (Temp - 1)) != 0)) {
+    SupportedValue = FALSE;
+  }
+
+  //
+  // DebounceValue = log2 (Temp)
+  //
+  while (Temp > 1) {
+    Temp >>= 1;
+    DebounceValue++;
+  }
+
+  if (DebounceValue > 0) {
+    DebounceEnable = B_GPIO_PCR_DEBEN;
+    SupportedDebounceTime = (1 << DebounceValue) * GPIO_DEB_CLK_PERIOD_IN_NS / 1000;
+  } else {
+    DebounceEnable = 0;
+    SupportedDebounceTime = 0;
+  }
+
+  GpioWritePadCfgReg (
+    GpioPad,
+    2,
+    (UINT32)~(B_GPIO_PCR_DEBOUNCE | B_GPIO_PCR_DEBEN),
+    (DebounceValue << N_GPIO_PCR_DEBOUNCE) | DebounceEnable
+    );
+
+  if (!SupportedValue) {
+    DEBUG ((DEBUG_WARN, "GPIO WARNING: %a %dus debounce time rounded down to %dus\n",
+            GpioName (GpioPad),
+            *DebounceTime,
+            SupportedDebounceTime));
+  }
+
+  *DebounceTime = SupportedDebounceTime;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c
new file mode 100644
index 0000000000..a6d260f4ad
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c
@@ -0,0 +1,225 @@
+/** @file
+  This file contains specific GPIO information
+
+  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
+#include <Register/PchRegsGpioCnl.h>
+#include <Register/PchRegsPmcCnl.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <GpioConfig.h>
+#include <Register/PchRegsPcr.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] = {
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS, R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_A_PAD_MAX}, //CNL PCH-LP GPP_A
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_B_PAD_MAX}, //CNL PCH-LP GPP_B
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_C_PAD_MAX}, //CNL PCH-LP GPP_C
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_D_PAD_MAX}, //CNL PCH-LP GPP_D
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_E_PAD_MAX}, //CNL PCH-LP GPP_E
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS, R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_F_PAD_MAX}, //CNL PCH-LP GPP_F
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_G_PAD_MAX}, //CNL PCH-LP GPP_G
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS, R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET, CNL_PCH_LP_GPIO_GPP_H_PAD_MAX}, //CNL PCH-LP GPP_H
+  {PID_GPIOCOM2, R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN,   R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS,   R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE,   R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS,   R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_GPD_PAD_MAX},   //CNL PCH-LP GPD
+  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK, R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX, R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET, CNL_PCH_LP_GPIO_VGPIO_PAD_MAX}, //CNL PCH-LP vGPIO
+  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS,   R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_SPI_PAD_MAX},   //CNL PCH-LP SPI
+  {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS,   R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_AZA_PAD_MAX},   //CNL PCH-LP AZA
+  {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN,   R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN,   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,           R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK,     R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX,     R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET,   CNL_PCH_LP_GPIO_CPU_PAD_MAX},   //CNL PCH-LP CPU
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN,  R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN,  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,           R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK,    R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX,    R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET,  CNL_PCH_LP_GPIO_JTAG_PAD_MAX},  //CNL PCH-LP JTAG
+  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN, R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS, R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK,   R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX,   R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET, CNL_PCH_LP_GPIO_HVMOS_PAD_MAX}  //CNL PCH-LP HVMOS
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchHGpioGroupInfo[] = {
+  {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_A_PAD_MAX}, //CNL PCH-H GPP_A
+  {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_B_PAD_MAX}, //CNL PCH-H GPP_B
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_C_PAD_MAX}, //CNL PCH-H GPP_C
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_D_PAD_MAX}, //CNL PCH-H GPP_D
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_E_PAD_MAX}, //CNL PCH-H GPP_E
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_F_PAD_MAX}, //CNL PCH-H GPP_F
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_G_PAD_MAX}, //CNL PCH-H GPP_G
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_H_PAD_MAX}, //CNL PCH-H GPP_H
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN, R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS, R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN, R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_I_PAD_MAX}, //CNL PCH-H GPP_I
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_J_PAD_MAX}, //CNL PCH-H GPP_J
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK,   R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX,   R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET, CNL_PCH_H_GPIO_GPP_K_PAD_MAX}, //CNL PCH-H GPP_K
+  {PID_GPIOCOM2, R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS,   R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET,   CNL_PCH_H_GPIO_GPD_PAD_MAX},   //CNL PCH-H GPD
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN, R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS, R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,          R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK, R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX, R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET, CNL_PCH_H_GPIO_VGPIO_PAD_MAX}, //CNL PCH-H vGPIO
+  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN,   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,          R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET,   CNL_PCH_H_GPIO_SPI_PAD_MAX},   //CNL PCH-H SPI
+  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN,   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,          R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET,   CNL_PCH_H_GPIO_AZA_PAD_MAX},   //CNL PCH-H AZA
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN,   R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN,   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,          R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK,     R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX,     R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET,   CNL_PCH_H_GPIO_CPU_PAD_MAX},   //CNL PCH-H CPU
+  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN,  R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN,  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,          R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK,    R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX,    R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET,  CNL_PCH_H_GPIO_JTAG_PAD_MAX}   //CNL PCH-H JTAG
+};
+
+/**
+  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
+  )
+{
+  if (IsPchLp ()) {
+    *GpioGroupInfoTableLength = ARRAY_SIZE (mPchLpGpioGroupInfo);
+    return mPchLpGpioGroupInfo;
+  } else {
+    *GpioGroupInfoTableLength = ARRAY_SIZE (mPchHGpioGroupInfo);
+    return mPchHGpioGroupInfo;
+  }
+}
+
+/**
+  Get GPIO Chipset ID specific to PCH generation and series
+**/
+UINT32
+GpioGetThisChipsetId (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    return GPIO_CNL_LP_CHIPSET_ID;
+  } else {
+    return GPIO_CNL_H_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_CNL_LP_GROUP_GPD) || (Group == GPIO_CNL_H_GROUP_GPD)) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  This procedure will perform special handling of GPP_A_12.
+
+  @param[in]  None
+
+  @retval None
+**/
+VOID
+GpioA12SpecialHandling (
+  VOID
+  )
+{
+  GPIO_PAD_OWN         PadOwnVal;
+  GPIO_PAD             GpioPad;
+
+  //
+  // PCH BWG 16.6. GPP_A_12 Special Handling
+  //
+  if (IsPchLp ()) {
+    GpioPad = GPIO_CNL_LP_GPP_A12;
+  } else {
+    GpioPad = GPIO_CNL_H_GPP_A12;
+  }
+  GpioGetPadOwnership (GpioPad, &PadOwnVal);
+
+  //
+  // If the pad is host-own, BIOS has to always lock this pad after being initialized
+  //
+  if (PadOwnVal == GpioPadOwnHost) {
+    //
+    // Set PadCfgLock for GPP_A_12
+    //
+    GpioLockPadCfg (GpioPad);
+  }
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SBI_PID mGpioComSbiIds[] =
+{
+  PID_GPIOCOM0, PID_GPIOCOM1, PID_GPIOCOM2, PID_GPIOCOM3, PID_GPIOCOM4
+};
+
+/**
+  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
+  )
+{
+  *GpioComSbiIds = mGpioComSbiIds;
+  return ARRAY_SIZE (mGpioComSbiIds);
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING mPchLpGpioGroupToGpeMapping[] = {
+  {GPIO_CNL_LP_GROUP_GPP_A,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A},
+  {GPIO_CNL_LP_GROUP_GPP_B,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B},
+  {GPIO_CNL_LP_GROUP_GPP_C,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C},
+  {GPIO_CNL_LP_GROUP_GPP_D,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D},
+  {GPIO_CNL_LP_GROUP_GPP_E,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E},
+  {GPIO_CNL_LP_GROUP_GPP_F,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F},
+  {GPIO_CNL_LP_GROUP_GPP_G,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G},
+  {GPIO_CNL_LP_GROUP_GPP_H,  0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H},
+  {GPIO_CNL_LP_GROUP_GPD,    0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD,   V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD},
+  {GPIO_CNL_LP_GROUP_VGPIO , 0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO, V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO},
+  {GPIO_CNL_LP_GROUP_SPI,    0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI,   V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI},
+  {GPIO_CNL_LP_GROUP_AZA,    0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA,   V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA},
+  {GPIO_CNL_LP_GROUP_JTAG,   0, V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG,  V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING mPchHGpioGroupToGpeMapping[] = {
+  {GPIO_CNL_H_GROUP_GPP_A,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A},
+  {GPIO_CNL_H_GROUP_GPP_B,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B},
+  {GPIO_CNL_H_GROUP_GPP_C,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C},
+  {GPIO_CNL_H_GROUP_GPP_D,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D},
+  {GPIO_CNL_H_GROUP_GPP_E,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E},
+  {GPIO_CNL_H_GROUP_GPP_F,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F},
+  {GPIO_CNL_H_GROUP_GPP_G,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G},
+  {GPIO_CNL_H_GROUP_GPP_H,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H},
+  {GPIO_CNL_H_GROUP_GPP_I,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I},
+  {GPIO_CNL_H_GROUP_GPP_J,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J},
+  {GPIO_CNL_H_GROUP_GPP_K,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K},
+  {GPIO_CNL_H_GROUP_GPD,    0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD,   V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD},
+  {GPIO_CNL_H_GROUP_VGPIO,  0, V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO, V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO}
+};
+
+/**
+  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
+  )
+{
+  if (IsPchLp ()) {
+    *GpioGroupToGpeMapping = mPchLpGpioGroupToGpeMapping;
+    *GpioGroupToGpeMappingLength = ARRAY_SIZE (mPchLpGpioGroupToGpeMapping);
+  } else {
+    *GpioGroupToGpeMapping = mPchHGpioGroupToGpeMapping;
+    *GpioGroupToGpeMappingLength = ARRAY_SIZE (mPchHGpioGroupToGpeMapping);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c
new file mode 100644
index 0000000000..2f9b6a7e6f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c
@@ -0,0 +1,67 @@
+/** @file
+  This file contains functions for PCH DMI SIP14
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsDmi.h>
+#include <Register/PchRegsDmi14.h>
+#include <Register/PchRegsPcr.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);
+}
+
+/**
+  Enable PCIe Relaxed Order for DMI SIP14
+**/
+VOID
+PchDmi14EnablePcieRelaxedOrder (
+  VOID
+  )
+{
+  //
+  // Enable Forced Relaxed Ordering to always allow downstream completions to pass posted writes.
+  // Set Completion Relaxed Ordering Attribute Override Value
+  // and Completion Relaxed Ordering Attribute Override Enable
+  //
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI14_PCR_2314, ~0u, (BIT31 | BIT7));
+}
+
+/**
+ 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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c
new file mode 100644
index 0000000000..c711b3de39
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c
@@ -0,0 +1,113 @@
+/** @file
+  This file contains functions for PCH DMI SIP15
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsDmi.h>
+#include <Register/PchRegsDmi15.h>
+#include <Register/PchRegsPcr.h>
+
+/**
+  This function checks if DMI SIP15 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi15Locked (
+  VOID
+  )
+{
+  return ((PchPcrRead32 (PID_DMI, R_PCH_DMI15_PCR_MPC) & B_PCH_DMI15_PCR_MPC_SRL) != 0);
+}
+
+/**
+  Set DMI thermal throttling to recommended configuration.
+  It's intended only for P-DMI SIP15.
+**/
+VOID
+PchDmi15SetRecommendedThermalThrottling (
+  VOID
+  )
+{
+  UINT32  Data32And;
+  UINT32  Data32Or;
+  ///
+  /// DMI recommended Thermal Sensor Target Width
+  /// is the HW default configuration:
+  ///  - Thermal Sensor 3 Target Width: 0 (x1)
+  ///  - Thermal Sensor 2 Target Width: 1 (x2)
+  ///  - Thermal Sensor 1 Target Width: 2 (x4)
+  ///  - Thermal Sensor 0 Target Width: 3 (x8)
+  /// Enable Thermal Sensor Autonomous Width
+  ///
+  Data32And = (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW | B_PCH_DMI15_PCR_UPHWAWC_TS2TW |
+                        B_PCH_DMI15_PCR_UPHWAWC_TS1TW | B_PCH_DMI15_PCR_UPHWAWC_TS0TW);
+  Data32Or  = (0 << N_PCH_DMI15_PCR_UPHWAWC_TS3TW) |
+              (1 << N_PCH_DMI15_PCR_UPHWAWC_TS2TW) |
+              (2 << N_PCH_DMI15_PCR_UPHWAWC_TS1TW) |
+              (3 << N_PCH_DMI15_PCR_UPHWAWC_TS0TW) |
+              B_PCH_DMI15_PCR_UPHWAWC_TSAWEN;
+
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC, Data32And, Data32Or);
+}
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+  It's intended only for P-DMI SIP15.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmi15SetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  )
+{
+  UINT32  Data32And;
+  UINT32  Data32Or;
+
+  ///
+  /// DMI Throttling action
+  ///
+  Data32And = (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW | B_PCH_DMI15_PCR_UPHWAWC_TS2TW |
+                        B_PCH_DMI15_PCR_UPHWAWC_TS1TW | B_PCH_DMI15_PCR_UPHWAWC_TS0TW);
+  Data32Or  = (DmiThermalThrottling.ThermalSensor3TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS3TW) |
+              (DmiThermalThrottling.ThermalSensor2TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS2TW) |
+              (DmiThermalThrottling.ThermalSensor1TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS1TW) |
+              (DmiThermalThrottling.ThermalSensor0TargetWidth << N_PCH_DMI15_PCR_UPHWAWC_TS0TW) |
+              B_PCH_DMI15_PCR_UPHWAWC_TSAWEN;
+
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC, Data32And, Data32Or);
+}
+
+
+/**
+ Secure Register Lock data
+
+ @param[out] SrlRegOffset        Register offset holding Secure Register Lock setting
+ @param[out] SrlRegMask          Mask for Secure Register Lock setting
+**/
+VOID
+PchDmi15SrlRegData (
+  OUT UINT16  *SrlRegOffset,
+  OUT UINT32  *SrlRegMask
+  )
+{
+  *SrlRegMask = B_PCH_DMI15_PCR_MPC_SRL;
+  *SrlRegOffset = R_PCH_DMI15_PCR_MPC;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c
new file mode 100644
index 0000000000..f1b2867659
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c
@@ -0,0 +1,569 @@
+/** @file
+  PCH DMI library.
+
+  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsDmi.h>
+
+#include "PchDmi14.h"
+#include "PchDmi15.h"
+
+/**
+  This function checks if DMI Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmiLocked (
+  VOID
+  )
+{
+  if (IsPchWithPdmi ()) {
+    return IsPchDmi15Locked ();
+  } else {
+    return IsPchDmi14Locked ();
+  }
+}
+
+/**
+  Backward DMI library API compatibility
+  ACPI base address programming is done in PSF
+
+  @param[in] Address                    Address for ACPI base.
+
+  @retval EFI_UNSUPPORTED               NOT supported programming.
+**/
+EFI_STATUS
+PchDmiSetAcpiBase (
+  IN  UINT16                            Address
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Backward DMI library API compatibility
+  PWRMBASE is a standard BAR and doesn't require
+  additional DMI base decoding programming
+
+  @param[in] Address                    Address for PWRM base.
+
+  @retval EFI_UNSUPPORTED               NOT supported programming.
+**/
+EFI_STATUS
+PchDmiSetPwrmBase (
+  IN  UINT32                            Address
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Set PCH TCO base address decoding in DMI
+
+  @param[in] Address                    Address for TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetTcoBase (
+  IN  UINT16                            Address
+  )
+{
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [SMBUS PCI offset 50h[15:5], 1].
+  //
+  PchPcrWrite16 (
+    PID_DMI, R_PCH_DMI_PCR_TCOBASE,
+    (Address | BIT1)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  UINT32                                Data32;
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
+  Data32 |= (UINT32) Address;
+  Data32 |= B_LPC_CFG_GENX_DEC_EN;
+  //
+  // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the same value programmed in LPC/eSPI PCI Offset 84h~93h.
+  //
+  PchPcrWrite32 (
+    PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4),
+    Data32
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+  )
+{
+  UINT32                                Data32;
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
+  Data32 |= (UINT32) Address;
+  Data32 |= B_LPC_CFG_GENX_DEC_EN;
+  //
+  // Program eSPI Generic IO Range #, PCR[DMI] + 27BCh to the same value programmed in eSPI PCI Offset A4h.
+  //
+  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, Data32);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear PCH LPC/eSPI generic IO range decoding in DMI
+
+  @param[in] RangeIndex                 Index of chosen range
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearLpcGenIoRange (
+  IN  UINTN                             RangeIndex
+  )
+{
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the same value programmed in LPC/eSPI PCI Offset 84h~93h.
+  //
+  PchPcrWrite32 (
+    PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4),
+    0
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear PCH eSPI CS1# generic IO range decoding in DMI
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiClearEspiCs1GenIoRange (
+  VOID
+  )
+{
+  //
+  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Program LPC Generic IO Range #, PCR[DMI] + 27BCh to the same value programmed in eSPI PCI Offset A4h.
+  //
+  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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, "PchDmiSetLpcMemRange Error. DMI is locked.\n"));
+    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, "PchLpcMemRange2Set Error. DMI is locked.\n"));
+    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;
+}
+
+
+/**
+  Set PCH IO port 80h cycle decoding to PCIE root port in DMI
+
+  @param[in] RpNumber                   PCIE root port physical number.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchDmiSetIoPort80Decode (
+  IN  UINTN                             RpNumber
+  )
+{
+  UINT16            DmiRpDestinationId;
+  PSF_PORT_DEST_ID  PsfRpDestinationId;
+
+  if (IsPchDmiLocked ()) {
+    DEBUG ((DEBUG_ERROR, "PchIoPort80DecodeSet Error. DMI is locked.\n"));
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  ///
+  /// IO port 80h is typically used by decoder/LED hardware for debug purposes.
+  /// By default PCH will forward IO port 80h cycles to LPC bus. The Reserved Page Route (RPR) bit
+  /// of General Control and Status register, located at PCR[DMI] + 274Ch[11] , allows software to
+  /// re-direct IO port 80h cycles to PCIe bus so that a target (for example, a debug card) on
+  /// PCIe bus can receive and claim these cycles.
+  /// The "RPR Destination ID", PCR[DMI] + 274Ch[31:16] need to be set accordingly to point
+  /// to the root port that decode this range. Reading from Port 80h may not return valid values
+  /// if the POST-card itself do not shadow the writes. Unlike LPC, PCIe does not shadow the Port 80 writes.
+  ///
+  PsfRpDestinationId = PsfPcieDestinationId ((UINT32)RpNumber);
+
+  DmiRpDestinationId = (UINT16)((0x2 << 12) |
+                                (PsfRpDestinationId.Fields.PsfId << 8) |
+                                (PsfRpDestinationId.Fields.PortGroupId << 7) |
+                                (PsfRpDestinationId.Fields.PortId << 3) |
+                                 PsfRpDestinationId.Fields.ChannelId);
+
+  //
+  // Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest ID of RP.
+  //
+  PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_GCS + 2, DmiRpDestinationId);
+  //
+  // Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'.
+  // Use byte write on GCS+1 and leave the BILD bit which is RWO.
+  //
+  PchPcrAndThenOr8 (PID_DMI, R_PCH_DMI_PCR_GCS + 1, 0xFF, (B_PCH_DMI_PCR_RPR >> 8));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set DMI thermal throttling to recommended configuration.
+  It's intended only for P-DMI.
+**/
+VOID
+PchDmiSetRecommendedThermalThrottling (
+  VOID
+  )
+{
+  if (IsPchWithPdmi ()) {
+    PchDmi15SetRecommendedThermalThrottling ();
+  }
+}
+
+/**
+  Set DMI thermal throttling to custom configuration.
+  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
+  DMI Thermal Sensor Autonomous Width Enable.
+  It's intended only for P-DMI.
+
+  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
+**/
+VOID
+PchDmiSetCustomThermalThrottling (
+  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
+  )
+{
+  if (IsPchWithPdmi ()) {
+    PchDmi15SetCustomThermalThrottling (DmiThermalThrottling);
+  }
+}
+
+/**
+  Determines where to send the reserved page registers
+  Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Port
+  with the destination ID specified in GCS.RPRDID using DMI source decode.
+**/
+VOID
+PchDmiSetReservedPageRegToPcieRootPort (
+  VOID
+  )
+{
+  PchPcrAndThenOr8 (
+    PID_DMI, R_PCH_DMI_PCR_GCS + 1,
+    (UINT8) ~0,
+    (UINT8) (B_PCH_DMI_PCR_RPR >> 8)
+    );
+}
+
+/**
+  Determines where to send the reserved page registers
+  DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cycles hitting these ranges will
+  end up in P2SB which will then forward the cycle to LPC or eSPI through IOSF Sideband.
+**/
+VOID
+PchDmiSetReservedPageRegToLpc (
+  VOID
+  )
+{
+  PchPcrAndThenOr8 (
+    PID_DMI, R_PCH_DMI_PCR_GCS + 1,
+    (UINT8) (~(B_PCH_DMI_PCR_RPR >> 8)),
+    0
+    );
+}
+
+/**
+  uCode Patch Region Enable (UPRE). Enables memory access targeting the uCode patch region (0xFEF00000 to 0xFEFFFFFF)
+  to be forwarded to SPI Flash. This can only be set if the boot flash is on SPI.
+**/
+VOID
+PchDmiEnableUCodePatchRegion (
+  VOID
+  )
+{
+  ///
+  /// Setup "uCode Patch Region Enable", PCR [DMI] + 2748h[0] to '0b'
+  ///
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI_PCR_UCPR, (UINT32) ~B_PCH_DMI_PCR_UCPR_UPRE, 0);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
new file mode 100644
index 0000000000..9778c9a252
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
@@ -0,0 +1,79 @@
+/** @file
+  PCH DMI library with S3 boot script support.
+
+  Copyright (c) 2019 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/PchRegsPcr.h>
+#include <Register/PchRegsDmi.h>
+
+#include "PchDmi14.h"
+#include "PchDmi15.h"
+
+/**
+  Configure PCH DMI Lock
+**/
+VOID
+PchDmiSetLockWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  Data32Or;
+  UINT32  Data32And;
+  UINT16  Address;
+
+  Data32And = 0xFFFFFFFF;
+  if (IsPchWithPdmi ()) {
+    PchDmi15SrlRegData (&Address, &Data32Or);
+  } else {
+    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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c
new file mode 100644
index 0000000000..14bd51ec43
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c
@@ -0,0 +1,221 @@
+/** @file
+  Pch common library for PCH INIT PEI/DXE/SMM modules
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PchPolicyCommon.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/PchRegsPcie.h>
+
+extern CONST PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[];
+extern CONST UINT32 mPchPcieControllerInfoSize;
+
+#define PORT_PLS_TIMEOUT 100    ///< 100 * 10 us = 1ms timeout for USB3 PortSC PLS polling
+
+/**
+  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 < mPchPcieControllerInfoSize);
+  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));
+}
+
+/**
+  Calculate root port device number based on physical port index.
+
+  @param[in]  RpIndex              Root port index (0-based).
+
+  @retval     Root port device number.
+**/
+UINT32
+PchGetPcieRpDevice (
+  IN  UINT32   RpIndex
+  )
+{
+  UINTN ControllerIndex;
+  ControllerIndex = RpIndex / PCH_PCIE_CONTROLLER_PORTS;
+  ASSERT (ControllerIndex < mPchPcieControllerInfoSize);
+  return mPchPcieControllerInfo[ControllerIndex].DevNum;
+}
+
+/**
+  This function reads Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[out] *Data32             Value of Config register
+
+  @retval EFI_SUCCESS             SBI Read successful.
+**/
+EFI_STATUS
+PchSbiRpPciRead32 (
+  IN    UINT32  RpIndex,
+  IN    UINT32  Offset,
+  OUT   UINT32  *Data32
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        RpDevice;
+  UINT8         Response;
+  UINT16        Fid;
+
+  RpDevice = PchGetPcieRpDevice (RpIndex);
+  Fid = (UINT16) ((RpDevice << 3) | (RpIndex % 4 ));
+  Status = PchSbiExecutionEx (
+             GetRpSbiPid (RpIndex),
+             Offset,
+             PciConfigRead,
+             FALSE,
+             0xF,
+             0,
+             Fid,
+             Data32,
+             &Response
+             );
+  if (Status != EFI_SUCCESS) {
+    DEBUG((DEBUG_ERROR,"Sideband Read Failed of RpIndex %d Offset 0x%x. Device = %d Fid = 0x%x\n",RpIndex, Offset, RpDevice, Fid));
+    ASSERT (FALSE);
+  }
+  return Status;
+}
+
+/**
+  This function And then Or Pci Config register via SBI Access
+
+  @param[in]  RpIndex             Root Port Index (0-based)
+  @param[in]  Offset              Offset of Config register
+  @param[in]  Data32And           Value of Config register to be And-ed
+  @param[in]  Data32AOr           Value of Config register to be Or-ed
+
+  @retval EFI_SUCCESS             SBI Read and Write successful.
+**/
+EFI_STATUS
+PchSbiRpPciAndThenOr32 (
+  IN  UINT32  RpIndex,
+  IN  UINT32  Offset,
+  IN  UINT32  Data32And,
+  IN  UINT32  Data32Or
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      RpDevice;
+  UINT32      Data32;
+  UINT8       Response;
+  UINT16      Fid;
+
+  RpDevice = PchGetPcieRpDevice (RpIndex);
+  Status = PchSbiRpPciRead32 (RpIndex, Offset, &Data32);
+  if (Status == EFI_SUCCESS) {
+    Data32 &= Data32And;
+    Data32 |= Data32Or;
+    Fid = (UINT16) ((RpDevice << 3) | (RpIndex % 4 ));
+    Status = PchSbiExecutionEx (
+               GetRpSbiPid (RpIndex),
+               Offset,
+               PciConfigWrite,
+               FALSE,
+               0xF,
+               0,
+               Fid,
+               &Data32,
+               &Response
+               );
+    if (Status != EFI_SUCCESS) {
+      DEBUG((DEBUG_ERROR,"Sideband Write Failed of RpIndex %d Offset 0x%x. Device = %d Fid = 0x%x\n",RpIndex, Offset, RpDevice, Fid));
+      ASSERT (FALSE);
+    }
+  } else {
+    ASSERT (FALSE);
+  }
+  return Status;
+}
+
+/**
+  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
+PrintRegisters (
+  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
+PrintPciRegisters (
+  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"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
new file mode 100644
index 0000000000..dcb43285b7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
@@ -0,0 +1,2407 @@
+/** @file
+  This file contains routines that support PCI Express initialization
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchPciExpressHelpersLibrary.h"
+#include <Library/BaseMemoryLib.h>
+
+#define ASPM_L1_NO_LIMIT 0xFF
+#define ASPM_L0s_NO_LIMIT 0x7
+
+#define LINK_RETRAIN_WAIT_TIME 1000 // microseconds
+//
+// This structure conveniently keeps segment:bus:device:function coordinates of a PCIe device
+// in a single variable. PcieCap is offset to PCI Express capabilities. Having it cached together
+// with coordinates is an optimization feature, because code in this file uses it a lot
+//
+typedef struct {
+  UINT32 Seg     : 8;
+  UINT32 Bus     : 8;
+  UINT32 Dev     : 5;
+  UINT32 Func    : 3;
+  UINT32 PcieCap : 8;
+} SBDF;
+
+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;
+
+typedef struct {
+  UINT32 MaxSnoopLatencyValue         : 10;
+  UINT32 MaxSnoopLatencyScale         : 3;
+  UINT32 MaxNoSnoopLatencyValue       : 10;
+  UINT32 MaxNoSnoopLatencyScale       : 3;
+} LTR_LIMIT;
+
+#define MSLV_BIT_OFFSET   0
+#define MSLS_BIT_OFFSET  10
+#define MNSLV_BIT_OFFSET 13
+#define MNSLS_BIT_OFFSET 23
+
+
+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);
+}
+
+/**
+  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;
+}
+
+/**
+  Translate PCIe Port/Lane pair to 0-based PCIe lane number.
+
+  @param[in] RpIndex    Root Port index
+  @param[in] RpLane     Root Port Lane (0-3)
+
+  @retval PCIe lane number (0-based)
+**/
+UINT32
+PchPciePhysicalLane (
+  UINT32 RpIndex,
+  UINT32 RpLane
+  )
+{
+  UINT32  ControllerIndex;
+  UINT32  ControllerLane;
+
+  ASSERT (RpIndex < GetPchMaxPciePortNum ());
+  ASSERT (((RpIndex % 4) + RpLane) < 4);
+
+  ControllerIndex = (RpIndex / 4);
+  ControllerLane  = (RpIndex % 4) + RpLane;
+  if (IsPcieLaneReversalEnabled (RpIndex)) {
+    ControllerLane = 3 - ControllerLane;
+  }
+  return (ControllerIndex * 4) + ControllerLane;
+}
+
+/**
+  Checks if lane reversal is enabled on a given root port
+
+  @param[in] RpIndex  Root port index (0-based)
+
+  @retval TRUE if lane reversal is enbabled, FALSE otherwise
+**/
+BOOLEAN
+IsPcieLaneReversalEnabled (
+  IN     UINT32  RpIndex
+  )
+{
+  UINT32  Data32;
+  PchSbiRpPciRead32 (PchGetPcieFirstPortIndex (RpIndex), R_PCH_PCIE_CFG_PCIEDBG, &Data32);
+  return !! (Data32 & B_PCH_PCIE_CFG_PCIEDBG_LR);
+}
+
+/**
+  Calculates the index of the first port on the same controller.
+
+  @param[in] RpIndex     Root Port Number (0-based)
+
+  @retval Index of the first port on the first controller.
+**/
+UINT32
+PchGetPcieFirstPortIndex (
+  IN     UINT32  RpIndex
+  )
+{
+  UINT32  ControllerIndex;
+
+  ControllerIndex = RpIndex / PCH_PCIE_CONTROLLER_PORTS;
+  return ControllerIndex * PCH_PCIE_CONTROLLER_PORTS;
+}
+
+/*
+  Returns Tpower_on capability of device
+
+  @param[in] DeviceBase       device's PCI segment base address
+  @param[in] L1ssCapOffset    offset to L1substates capability in device's extended config space
+
+  @retval                     structure containing Tpoweron scale and value
+*/
+T_POWER_ON
+GetTpoCapability (
+  UINT64 DeviceBase,
+  UINT32 L1ssCapOffset
+  )
+{
+  T_POWER_ON Tpo;
+  UINT32     L1ssCapabilities;
+
+  L1ssCapabilities = PciSegmentRead32 (DeviceBase + L1ssCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+  Tpo.Scale = (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTPOS) >> N_PCIE_EX_L1SCAP_PTPOS;
+  Tpo.Value = (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTV) >> N_PCIE_EX_L1SCAP_PTV;
+  return Tpo;
+}
+
+/*
+  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);
+}
+
+/**
+  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
+          ///
+          DEBUG ((DEBUG_INFO,"CapId %x,%x->%02x\n", ((UINT32)(DeviceBase&0xFFFFF000)>>12), CapId, CapHeaderOffset));
+          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;
+
+  DEBUG ((DEBUG_INFO,"PcieFindCapId () SBDF %0x: %0x: %0x :%0x, CapId = %0x \n", Segment, Bus, Device, Function, CapId));
+  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_PCH_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);
+}
+
+/**
+  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
+**/
+STATIC
+BOOLEAN
+PcieIsPhyLanePgEnabled (
+  IN     UINT64  RpBase
+  )
+{
+  UINT32 Data32;
+  Data32 = PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL);
+  return (Data32 & B_PCH_PCIE_CFG_PCIEPMECTL_DLSULPPGE) != 0;
+}
+
+/**
+  Get current PCIe link speed.
+
+  @param[in] RpBase    Root Port base address
+  @retval Link speed
+**/
+UINT32
+GetLinkSpeed (
+  UINT64  RpBase
+  )
+{
+  return PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_LSTS) & B_PCIE_LSTS_CLS;
+}
+
+/**
+  Get max PCIe link speed supported by the root port.
+
+  @param[in] RpBase    Root Port base address
+  @retval Max link speed
+**/
+UINT32
+GetMaxLinkSpeed (
+  UINT64 RpBase
+  )
+{
+  return PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) & B_PCIE_LCAP_MLS;
+}
+
+/**
+  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);
+}
+
+/**
+  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
+**/
+STATIC
+BOOLEAN
+IsLtrCapable (
+  SBDF Sbdf
+  )
+{
+  if (Sbdf.PcieCap == 0) {
+    return FALSE;
+  }
+  return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCAP2_OFFSET) & B_PCIE_DCAP2_LTRMS);
+}
+
+/**
+  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);
+}
+
+/**
+  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;
+}
+
+/**
+  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;
+  }
+}
+
+/**
+  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;
+}
+
+/**
+  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
+**/
+STATIC
+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};
+
+  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;
+  }
+  Result.ForceOverride = FALSE;
+  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
+**/
+STATIC
+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;
+}
+
+/**
+  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_PCH_PCIE_LTRECH_CID);
+  if (LtrCapOffset == 0) {
+    return;
+  }
+  Data16 = (UINT16)((Ltr.MaxSnoopLatencyValue << N_PCH_PCIE_LTRECH_MSLR_VALUE) | (Ltr.MaxSnoopLatencyScale << N_PCH_PCIE_LTRECH_MSLR_SCALE));
+  PciSegmentWrite16(Base + LtrCapOffset + R_PCH_PCIE_LTRECH_MSLR_OFFSET, Data16);
+
+  Data16 = (UINT16)((Ltr.MaxNoSnoopLatencyValue << N_PCH_PCIE_LTRECH_MNSLR_VALUE) | (Ltr.MaxNoSnoopLatencyScale << N_PCH_PCIE_LTRECH_MNSLR_SCALE));
+  PciSegmentWrite16(Base + LtrCapOffset + R_PCH_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
+**/
+STATIC
+BOOLEAN
+FindNextPcieChild (
+  IN     PCI_DEV_TYPE ParentDevType,
+  IN OUT SBDF   *Sbdf
+  )
+{
+  while ( FindNextLegalSbdf (ParentDevType, Sbdf)) {
+    if (IsPcieDevice (Sbdf)) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Checks device's Slot Clock Configuration
+
+  @param[in] Base            device's base address
+
+  @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] 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] Sbdf           Device's Segment:Bus:Device:Function coordinates
+  @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));
+  }
+}
+
+/**
+  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] Base            device's base address
+**/
+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 == 0xFF)) {
+      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) {
+    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
+  )
+{
+  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);
+  }
+  ///
+  ///  Set L1.2 LTR threshold to 80us (value = 0x50, scale = 0x2 = 1024ns), in accordance to BWG
+  ///  BUG BUG BUG  It shouldn't be hardcoded, it should consider Tpoweron, otherwise we risk situation where
+  ///  BUG BUG BUG  threshold is lower than Tpo, and every L1 entry turns into L1.2 entry with no possibility
+  ///  BUG BUG BUG  to exit before LTR elapses, because exit can take no less than Tpo
+  ///
+  Ctrl1Register |= (0x50 << N_PCIE_EX_L1SCTL1_L12LTRTLV);
+  Ctrl1Register |= (2 << N_PCIE_EX_L1SCTL1_L12LTRTLSV);
+
+  Ctrl2Register |= (L1ss.TpoScale);
+  Ctrl2Register |= (L1ss.TpoValue << N_PCIE_EX_L1SCTL2_POWT);
+
+  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
+  //
+  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;
+
+  DEBUG ((DEBUG_INFO, "RecursiveL1ssConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  Base = SbdfToBase (Sbdf);
+  //
+  // 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);
+        SetL1ss (ChildSbdf, CombinedCaps, Override);
+      }
+    }
+  }
+  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);
+}
+
+/**
+  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
+**/
+STATIC
+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 rootport packet split.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] Mps                            maximum packet size
+**/
+STATIC
+VOID
+ConfigureRpPacketSplit (
+  SBDF   RpSbdf,
+  UINT8  Mps
+  )
+{
+  UINT64 RpBase;
+
+  RpBase = SbdfToBase (RpSbdf);
+  PciSegmentAndThenOr32 (RpBase + R_PCH_PCIE_CFG_CCFG, (UINT32) ~(B_PCH_PCIE_CFG_CCFG_UNRS), Mps << N_PCH_PCIE_CFG_CCFG_UNRS);
+}
+
+/**
+  Configures LTR override in rootport's proprietary registers.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] RpConfig                       rootport configuration
+  @param[in] TreeLtr                        combination of LTR override values from all devices under this rootport
+**/
+STATIC
+VOID
+ConfigureRpLtrOverride (
+  SBDF                      RpSbdf,
+  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
+  OVERRIDE_TABLE            *AspmOverride
+  )
+{
+  UINT64       RpBase;
+  UINT32       OvrEn;
+  UINT32       OvrVal;
+  LTR_OVERRIDE TreeLtr;
+
+  OvrEn = 0;
+  OvrVal = 0;
+  RpBase = SbdfToBase (RpSbdf);
+  //
+  // 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
+  //
+
+  TreeLtr = RecursiveLtrOverrideCheck (RpSbdf, AspmOverride);
+
+  if (RpConfig->ForceLtrOverride || TreeLtr.ForceOverride) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_FORCE_OVERRIDE;
+  }
+  if (RpConfig->LtrConfigLock == TRUE) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LOCK;
+  }
+
+  if (RpConfig->SnoopLatencyOverrideMode == 1) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN;
+    OvrVal |= RpConfig->SnoopLatencyOverrideValue;
+    OvrVal |= RpConfig->SnoopLatencyOverrideMultiplier << 10;
+    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRSROVR;
+  } else if (RpConfig->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 (RpConfig->NonSnoopLatencyOverrideMode == 1) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN;
+    OvrVal |= RpConfig->NonSnoopLatencyOverrideValue << 16;
+    OvrVal |= RpConfig->NonSnoopLatencyOverrideMultiplier << 26;
+    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRNSROVR;
+  } else if (RpConfig->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 %x:%x Val %x En %x\n", RpSbdf.Dev, RpSbdf.Func, 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] 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] IoApicPresent  TRUE if there's IoAPIC behind this rootprot
+**/
+VOID
+ConfigureEoiForwarding (
+  UINT8    RpSegment,
+  UINT8    RpBus,
+  UINT8    RpDevice,
+  UINT8    RpFunction,
+  BOOLEAN  IoApicPresent
+  )
+{
+  UINT64 RpBase;
+  UINT32 RpIndex;
+
+  RpBase = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  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
+    /// accordingly to PCH 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 rootport
+
+  @param[in] RpSbdf   segment:bus:device:function coordinates of rootport
+**/
+STATIC
+VOID
+L1ssProprietaryConfiguration (
+  SBDF RpSbdf
+  )
+{
+  BOOLEAN ClkreqSupported;
+  BOOLEAN L1ssEnabled;
+  UINT16  PcieCapOffset;
+  UINT32  Data32;
+  BOOLEAN L1LowSupported;
+  UINT64  RpBase;
+
+  RpBase = SbdfToBase (RpSbdf);
+  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 && IsLtrCapable (RpSbdf) && !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 L1LOW)
+    ///
+    PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, B_PCH_PCIE_CFG_PCIEPMECTL_L1FSOE);
+  }
+}
+
+/**
+  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
+  )
+{
+  UINT8      Mps;
+  BOOLEAN    IoApicPresent;
+  UINT64     RpBase;
+  SBDF       RpSbdf;
+  SBDF_TABLE BridgeCleanupList;
+
+  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);
+  ConfigureRpPacketSplit (RpSbdf, Mps);
+  IoApicPresent = RecursiveIoApicCheck (RpSbdf);
+  ConfigureEoiForwarding (RpSegment, RpBus, RpDevice, RpFunction, IoApicPresent);
+  RecursiveCccConfiguration (RpSbdf, TRUE);
+
+  ClearBusFromTable (&BridgeCleanupList);
+}
+
+/**
+  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] AspmOverrideTableSize    size of override array
+  @param[in] AspmOverrideTable        array of device that need exceptions in configuration
+  @param[in] PerformAspmConfiguration enables/disables ASPM programming
+**/
+VOID
+RootportDownstreamPmConfiguration (
+  UINT8                     RpSegment,
+  UINT8                     RpBus,
+  UINT8                     RpDevice,
+  UINT8                     RpFunction,
+  UINT8                     BusMin,
+  UINT8                     BusMax,
+  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
+  UINT32                    AspmOverrideTableSize,
+  PCH_PCIE_DEVICE_OVERRIDE  *AspmOverrideTable
+  )
+{
+  LTR_LIMIT      PolicyLtr;
+  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 = (RpConfig->LtrMaxNoSnoopLatency & 0x1c00) >> 10;
+  PolicyLtr.MaxNoSnoopLatencyValue = RpConfig->LtrMaxNoSnoopLatency & 0x3FF;
+  PolicyLtr.MaxSnoopLatencyScale   = (RpConfig->LtrMaxSnoopLatency & 0x1c00) >> 10;
+  PolicyLtr.MaxSnoopLatencyValue   = RpConfig->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);
+  ConfigureRpLtrOverride (RpSbdf, RpConfig, &PmOverrideTable);
+  if (RpConfig->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 (RpSbdf);
+  RecursiveAspmConfiguration (RpSbdf, 0, &PmOverrideTable);
+  ClearBusFromTable (&BridgeCleanupList);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c
new file mode 100644
index 0000000000..f2d20c625a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c
@@ -0,0 +1,542 @@
+/** @file
+  This file contains PSF routines for RC usage
+
+  Copyright (c) 2019 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/SaPlatformLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsPsf.h>
+#include <Register/PchRegsPcie.h>
+#include "PchPsfPrivateLibInternal.h"
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~0u,
+    B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  // If there is PCI access right after the PSF hide device, the device might
+  // still be accessible since the PSF cycle is not completed yet, and causes
+  // the race condition between sideband and primary cycles.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS,
+    ~0u,
+    B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS,
+    (UINT32) ~(B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS),
+    0
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // BAR0-5 supported
+  //
+  ASSERT (BarDisMask < BIT6);
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~0u,
+    BarDisMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // BAR0-5 supported
+  //
+  ASSERT (BarEnMask < BIT6);
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    (UINT32)~(BarEnMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS),
+    0
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~(UINT32)(B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN),
+    0
+    );
+}
+
+/**
+  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
+  )
+{
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
+    ~0u,
+    B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN
+    );
+}
+
+/**
+  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
+  )
+{
+  ASSERT (BarNum < 6);
+
+  if (PSF_IS_PORT_NULL (PsfPort)) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Read back is needed to enforce the sideband and primary ordering.
+  //
+  PchPcrAndThenOr32WithReadback (
+    PsfPort.PsfPid,
+    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0 + BarNum * 0x4,
+    0,
+    BarValue
+    );
+}
+
+/**
+  Hide PMC device at PSF level
+**/
+VOID
+PsfHidePmcDevice (
+  VOID
+  )
+{
+  PsfHideDevice (PsfPmcPort ());
+}
+
+/**
+  Set PMC ABASE value in PSF
+
+  @param[in] Address     Address for ACPI base address.
+**/
+VOID
+PsfSetPmcAbase (
+  IN  UINT16       Address
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort = PsfPmcPort ();
+
+  ASSERT (PchPcrRead32 (PsfPort.PsfPid, PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR4) != 0xFFFFFFFF);
+
+  //
+  // Disable IOSpace before changing the address
+  //
+  PsfDisableDeviceIoSpace (PsfPort);
+
+  //
+  // Program ABASE in PSF PMC space BAR4
+  //
+  PsfSetDeviceBarValue (PsfPort, 4, Address);
+
+  //
+  // Enable IOSpace
+  //
+  PsfEnableDeviceIoSpace (PsfPort);
+}
+
+/**
+  Get PMC ABASE value from PSF
+
+  @retval Address     Address for ACPI base.
+**/
+UINT16
+PsfGetPmcAbase (
+  VOID
+  )
+{
+  UINT16    Address;
+  PSF_PORT  PsfPort;
+
+  PsfPort = PsfPmcPort ();
+  //
+  // Read ABASE from PSF PMC space BAR4
+  //
+  Address = PchPcrRead16 (
+              PsfPort.PsfPid,
+              PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR4
+              );
+
+  ASSERT (Address != 0xFFFF);
+
+  return Address;
+}
+
+/**
+  Get PMC PWRMBASE value from PSF
+
+  @retval Address     Address for PWRM base.
+**/
+UINT32
+PsfGetPmcPwrmBase (
+  VOID
+  )
+{
+  UINT32    Address;
+  PSF_PORT  PsfPort;
+
+  PsfPort = PsfPmcPort ();
+  //
+  // Read PWRMBASE from PSF PMC space BAR0
+  //
+  Address = PchPcrRead32 (
+              PsfPort.PsfPid,
+              PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0
+              );
+
+  ASSERT (Address != 0xFFFFFFFF);
+
+  return Address;
+}
+
+/**
+  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 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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c
new file mode 100644
index 0000000000..d1c87a9e84
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c
@@ -0,0 +1,338 @@
+/** @file
+  This file contains internal PSF routines for PCH PSF lib usage
+
+  Copyright (c) 2019 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 <Register/PchRegsPsfCnl.h>
+#include <Register/PchRegsPcie.h>
+#include "PchPsfPrivateLibInternal.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoI2cPsfRegs[] =
+{
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoI2cPsfRegs[] =
+{
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE
+};
+
+/**
+  Return PSF_PORT for SerialIO I2C device
+
+  @param[in] I2cNum  Serial IO I2C device (I2C0, I2C1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO I2C device
+**/
+PSF_PORT
+PsfSerialIoI2cPort (
+  IN UINT32  I2cNum
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    if (I2cNum < ARRAY_SIZE(mPchLpSerialIoI2cPsfRegs)) {
+      PsfPort.RegBase = mPchLpSerialIoI2cPsfRegs[I2cNum];
+      return PsfPort;
+    }
+  } else {
+    if (I2cNum < ARRAY_SIZE(mPchHSerialIoI2cPsfRegs)) {
+      PsfPort.RegBase = mPchHSerialIoI2cPsfRegs[I2cNum];
+      return PsfPort;
+    }
+  }
+
+  ASSERT(FALSE);
+  return PSF_PORT_NULL;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoSpiPsfRegs[] =
+{
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoSpiPsfRegs[] =
+{
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
+};
+
+/**
+  Return PSF_PORT for SerialIO SPI device
+
+  @param[in] SpiNum  Serial IO SPI device (SPI0, SPI1, ....)
+
+  @retval  PsfPort   PSF PORT structure for SerialIO SPI device
+**/
+PSF_PORT
+PsfSerialIoSpiPort (
+  IN UINT32  SpiNum
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    if (SpiNum < ARRAY_SIZE(mPchLpSerialIoSpiPsfRegs)) {
+      PsfPort.RegBase = mPchLpSerialIoSpiPsfRegs[SpiNum];
+      return PsfPort;
+    }
+  } else {
+    if (SpiNum < ARRAY_SIZE(mPchHSerialIoSpiPsfRegs)) {
+      PsfPort.RegBase = mPchHSerialIoSpiPsfRegs[SpiNum];
+      return PsfPort;
+    }
+  }
+
+  ASSERT(FALSE);
+  return PSF_PORT_NULL;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoUartPsfRegs[] =
+{
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
+  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoUartPsfRegs[] =
+{
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
+  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE
+};
+
+/**
+  Return PSF_PORT for SerialIO UART device
+
+  @param[in] UartNum  Serial IO UART device (UART0, UART1, ....)
+
+  @retval  PsfPort    PSF PORT structure for SerialIO UART device
+**/
+PSF_PORT
+PsfSerialIoUartPort (
+  IN UINT32  UartNum
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    if (UartNum < ARRAY_SIZE(mPchLpSerialIoUartPsfRegs)) {
+      PsfPort.RegBase = mPchLpSerialIoUartPsfRegs[UartNum];
+      return PsfPort;
+    }
+  } else {
+    if (UartNum < ARRAY_SIZE(mPchHSerialIoUartPsfRegs)) {
+      PsfPort.RegBase = mPchHSerialIoUartPsfRegs[UartNum];
+      return PsfPort;
+    }
+  }
+
+  ASSERT(FALSE);
+  return PSF_PORT_NULL;
+}
+
+/**
+  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:
+      if (IsPchLp ()) {
+        *EoiTargetBase = R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 17;
+      } else {
+        *EoiTargetBase = R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 7;
+      }
+      break;
+
+    case 3:
+      *EoiTargetBase = R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+      *EoiControlBase = R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+      MaxTargets = 1;
+      break;
+
+    case 6:
+      if (IsPchH ()) {
+        *EoiTargetBase = R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 8;
+      }
+      break;
+
+    case 7:
+      if (IsPchH ()) {
+        *EoiTargetBase = R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 8;
+      }
+      break;
+
+    case 8:
+      if (IsPchH ()) {
+        *EoiTargetBase = R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
+        *EoiControlBase = R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI;
+        MaxTargets = 8;
+      }
+      break;
+  }
+  return MaxTargets;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchLpRpDestId[] =
+{
+  {0x18000}, {0x18001}, {0x18002}, {0x18003}, // SPA: PSF1, PortID = 0
+  {0x18200}, {0x18201}, {0x18202}, {0x18203}, // SPB: PSF1, PortID = 2
+  {0x18400}, {0x18401}, {0x18402}, {0x18403}, // SPC: PSF1, PortID = 4
+  {0x18600}, {0x18601}, {0x18602}, {0x18603}  // SPD: PSF1, PortID = 6
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchHRpDestId[] =
+{
+  {0x68000}, {0x68001}, {0x68002}, {0x68003}, // SPA: PSF6, PortID = 0
+  {0x88000}, {0x88001}, {0x88002}, {0x88003}, // SPB: PSF8, PortID = 0
+  {0x68100}, {0x68101}, {0x68102}, {0x68103}, // SPC: PSF6, PortID = 1
+  {0x78000}, {0x78001}, {0x78002}, {0x78003}, // SPD: PSF7, PortID = 0
+  {0x78100}, {0x78101}, {0x78102}, {0x78103}, // SPE: PSF7, PortID = 1
+  {0x88100}, {0x88101}, {0x88102}, {0x88103}  // SPF: PSF8, PortID = 1
+};
+
+/**
+  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 (IsPchLp ()) {
+    if (RpIndex < ARRAY_SIZE(PchLpRpDestId)) {
+      return PchLpRpDestId[RpIndex];
+    }
+  } else {
+    if (RpIndex < ARRAY_SIZE(PchHRpDestId)) {
+      return PchHRpDestId[RpIndex];
+    }
+  }
+  ASSERT (FALSE);
+  return (PSF_PORT_DEST_ID){0};
+}
+
+
+/**
+  Return PSF_PORT for PMC device
+
+  @retval    PsfPort         PSF PORT structure for PMC device
+**/
+PSF_PORT
+PsfPmcPort (
+  VOID
+  )
+{
+  PSF_PORT PsfPort;
+
+  PsfPort.PsfPid = PID_PSF3;
+
+  if (IsPchLp ()) {
+    PsfPort.RegBase = R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
+  } else {
+    PsfPort.RegBase = R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
+  }
+  return PsfPort;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchLpPsfTable[] =
+{
+  {1, PID_PSF1},
+  {2, PID_PSF2},
+  {3, PID_PSF3},
+  {4, PID_PSF4},
+  {5, PID_CSME_PSF}
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchHPsfTable[]  =
+{
+  {1, PID_PSF1},
+  {2, PID_PSF2},
+  {3, PID_PSF3},
+  {4, PID_PSF4},
+  {5, PID_CSME_PSF},
+  {6, PID_PSF6},
+  {7, PID_PSF7},
+  {8, PID_PSF8}
+};
+
+/**
+  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
+  )
+{
+  if (IsPchLp ()) {
+    *PsfTable = mPchLpPsfTable;
+    *PsfTableLength = ARRAY_SIZE(mPchLpPsfTable);
+  } else {
+    *PsfTable = mPchHPsfTable;
+    *PsfTableLength = ARRAY_SIZE(mPchHPsfTable);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c
new file mode 100644
index 0000000000..f88febfa48
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c
@@ -0,0 +1,92 @@
+/** @file
+  PCH private PEI PMC Library for all PCH generations.
+
+  Copyright (c) 2019 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/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchEspiLib.h>
+#include <Private/Library/GpioPrivateLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsClk.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLan.h>
+#include "PmcPrivateLibInternal.h"
+
+/**
+  Check if PCH PM Timer enabled based on platform policy
+
+  @retval TRUE       PCH PM Timer is enabled.
+  @retval FALSE      PCH PM Timer is disabled.
+**/
+BOOLEAN
+PmcIsPchPmTimerEnabled (
+  VOID
+  )
+{
+  BOOLEAN           PchPmTimerEnabled;
+  EFI_STATUS        Status;
+  SI_POLICY_PPI     *SiPolicy;
+  PCH_PM_CONFIG     *PmConfig;
+
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **)&SiPolicy
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  PchPmTimerEnabled = TRUE;
+  if (!PmConfig->EnableTcoTimer) {
+    PchPmTimerEnabled = FALSE;
+  }
+
+  DEBUG ((DEBUG_INFO, "PmcIsPchPmTimerEnabled () = %x\n", PchPmTimerEnabled));
+
+  return PchPmTimerEnabled;
+}
+
+/**
+  Lock down PMC settings
+
+  @param[in] SiPolicy   The SI Policy PPI instance
+**/
+VOID
+PmcLockSettings (
+  IN  SI_POLICY_PPI     *SiPolicy
+  )
+{
+
+  UINT32         PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  ///
+  /// Set PWRMBASE Offset 0x1048 [24]
+  ///
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ETR3, BIT24);
+
+  ///
+  /// PM_SYNC_LOCK
+  /// Set PWRMBASE Offset 0x18C8 [15]
+  ///
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_PMSYNC_MISC_CFG, B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK);
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
new file mode 100644
index 0000000000..a6ccf4b96b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
@@ -0,0 +1,1033 @@
+/** @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) 2019 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/TimerLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchPsfPrivateLib.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsItss.h>
+#include <IndustryStandard/Pci30.h>
+
+#include "PmcPrivateLibInternal.h"
+
+/**
+  Send PMC IPC1 Normal Read/Write command
+
+  @param[in]  Command           Command to be issued to PMC IPC 1 interface
+  @param[in]  SubCmdId          SUB_CMD_ID for provided Command
+  @param[in]  CmdSize           Total size in byte to be sent via PMC IPC 1 interface
+  @param[in]  WriteBufPtr       Pointer to Structure of 4 DWORDs to be issued to PMC IPC 1 interface
+  @param[out] ReadBufPtr        Pointer to Structure of 4 DWORDs to be filled by PMC IPC 1 interface
+
+  @retval EFI_SUCCESS             Command was executed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid command size
+  @retval EFI_DEVICE_ERROR        IPC command failed with an error
+  @retval EFI_TIMEOUT             IPC command did not complete after 1s
+**/
+EFI_STATUS
+PmcSendCommand (
+  IN  UINT8                    Command,
+  IN  UINT8                    SubCmdId,
+  IN  UINT8                    CmdSize,
+  IN  PMC_IPC_COMMAND_BUFFER   *WriteBufPtr,
+  OUT PMC_IPC_COMMAND_BUFFER   *ReadBufPtr
+  )
+{
+  EFI_STATUS             Status;
+  UINT32                 PchPwrmBase;
+  UINT32                 IpcSts;
+  UINTN                  Timeout;
+
+  DEBUG ((DEBUG_INFO, "PmcSendCommand(): IPC_COMMAND=0x%02X, IPC_SUB_CMD = 0x%02X, IPC_SIZE=0x%02X \n", Command, SubCmdId, CmdSize));
+  DEBUG ((DEBUG_INFO, "WBUF0=0x%08X, WBUF1=0x%08X, WBUF2=0x%08X, WBUF3=0x%08X \n", WriteBufPtr->Buf0, WriteBufPtr->Buf1, WriteBufPtr->Buf2, WriteBufPtr->Buf3));
+
+  if (CmdSize > 16) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Program the Write Buffer 0 with the Data that needs to be written to PMC
+  //
+  PchPwrmBase = PmcGetPwrmBase ();
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF0), WriteBufPtr->Buf0);
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF1), WriteBufPtr->Buf1);
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF2), WriteBufPtr->Buf2);
+  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF3), WriteBufPtr->Buf3);
+  //
+  // Program the command register with command and size
+  //
+  MmioWrite32 (
+    PchPwrmBase + R_PMC_PWRM_IPC_CMD,
+    (UINT32) ((CmdSize << N_PMC_PWRM_IPC_CMD_SIZE) |
+      (SubCmdId << N_PMC_PWRM_IPC_CMD_CMD_ID) |
+      (Command << N_PMC_PWRM_IPC_CMD_COMMAND))
+    );
+
+  //
+  // Read the IPC_STS register to get BUSY or Error status
+  //
+  Timeout = 0;
+  Status = EFI_SUCCESS;
+  while (TRUE) {
+    IpcSts = MmioRead32 (PchPwrmBase + R_PMC_PWRM_IPC_STS);
+    if ((IpcSts & B_PMC_PWRM_IPC_STS_BUSY) == 0) {
+      break;
+    }
+
+    if (Timeout > (1000 * 100)) {
+      Status = EFI_TIMEOUT;
+      break;
+    }
+    MicroSecondDelay (10);
+    Timeout++;
+  }
+
+  if ((IpcSts & B_PMC_PWRM_IPC_STS_ERROR) != 0) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "PmcSendCommand() Error: IPC_STS=0x%08X\n", IpcSts));
+    return Status;
+  }
+
+  if (ReadBufPtr != NULL) {
+    //
+    // Fill the  ReadBuffer contents with the Data that needs to be read from PMC
+    //
+    ReadBufPtr->Buf0 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF0);
+    ReadBufPtr->Buf1 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF1);
+    ReadBufPtr->Buf2 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF2);
+    ReadBufPtr->Buf3 = MmioRead32(PchPwrmBase + R_PMC_PWRM_IPC_RBUF3);
+
+    DEBUG ((DEBUG_INFO, "RBUF0=0x%08X, RBUF1=0x%08X, RBUF2=0x%08X, RBUF3=0x%08X \n", ReadBufPtr->Buf0, ReadBufPtr->Buf1, ReadBufPtr->Buf2, ReadBufPtr->Buf3));
+  }
+
+  return Status;
+}
+
+/**
+  This function checks if SCI interrupt is enabled
+
+  @retval SCI Enable state
+**/
+BOOLEAN
+PmcIsSciEnabled (
+  VOID
+  )
+{
+  return ((IoRead8 (PmcGetAcpiBase () + R_ACPI_IO_PM1_CNT) & B_ACPI_IO_PM1_CNT_SCI_EN) != 0);
+}
+
+/**
+  This function triggers Software GPE
+**/
+VOID
+PmcTriggerSwGpe (
+  VOID
+  )
+{
+  IoOr32 (PmcGetAcpiBase () + R_ACPI_IO_GPE_CNTL, B_ACPI_IO_GPE_CNTL_SWGPE_CTRL);
+}
+
+/**
+  Set PCH ACPI base address.
+  The Address should not be 0 and should be 256 bytes aligned. It is IO space, so must not exceed 0xFFFF.
+  Only address matching PcdAcpiBaseAddress is the acceptable value for ACPI IO Base
+
+  @param[in] Address                    Address for ACPI base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PmcSetAcpiBase (
+  IN  UINT16                            Address
+  )
+{
+
+  if (Address != PcdGet16 (PcdAcpiBaseAddress)) {
+    DEBUG ((DEBUG_ERROR, "PmcSetAcpiBase Error. Invalid Address: %x.\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PsfSetPmcAbase (Address);
+  return EFI_SUCCESS;
+}
+
+/**
+  Set PCH PWRM base address.
+  Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for PWRMBASE
+
+  @param[in] Address                    Address for PWRM base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PmcSetPwrmBase (
+  IN  UINT32                            Address
+  )
+{
+  UINT64                                PmcBase;
+
+  if (Address != PCH_PWRM_BASE_ADDRESS) {
+    DEBUG ((DEBUG_ERROR, "PmcSetPwrmBase Error. Invalid Address: %x.\n", Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PmcBase      = PCI_SEGMENT_LIB_ADDRESS (
+                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                   PCI_DEVICE_NUMBER_PCH_PMC,
+                   PCI_FUNCTION_NUMBER_PCH_PMC,
+                   0
+                   );
+  if (PciSegmentRead16 (PmcBase) == 0xFFFF) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Disable PWRMBASE in PMC Device first before changing PWRM base address.
+  //
+  PciSegmentAnd16 (
+    PmcBase + PCI_COMMAND_OFFSET,
+    (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE
+    );
+
+  //
+  // Program PWRMBASE in PMC Device
+  //
+  PciSegmentAndThenOr32 (
+    PmcBase + R_PMC_CFG_BASE,
+    (UINT32) (~B_PMC_CFG_PWRM_BASE_MASK),
+    Address
+    );
+
+  //
+  // Enable PWRMBASE in PMC Device
+  //
+  PciSegmentOr16 (
+    PmcBase + PCI_COMMAND_OFFSET,
+    EFI_PCI_COMMAND_MEMORY_SPACE
+    );
+  return EFI_SUCCESS;
+}
+
+/**
+  This function checks if function disable (static and non-static power gating)
+  configuration is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsFunctionDisableConfigLocked (
+  VOID
+  )
+{
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK) != 0);
+}
+
+/**
+  Check if MODPHY SUS PG is supported
+
+  @retval  Status of MODPHY SUS PG support
+**/
+BOOLEAN
+PmcIsModPhySusPgSupported (
+  VOID
+  )
+{
+  if (IsPchLp ()) {
+    //
+    // MPHY SUS PG supported on PCH-LP only:
+    //
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  This function checks if ISH is function disabled
+  by static power gating
+
+  @retval ISH device state
+**/
+BOOLEAN
+PmcIsIshFunctionDisabled (
+  VOID
+  )
+{
+  //
+  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
+  //
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1)) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC) != 0);
+}
+
+/**
+  This function checks if ISH device is supported (not disabled by fuse)
+
+  @retval ISH support state
+**/
+BOOLEAN
+PmcIsIshSupported (
+  VOID
+  )
+{
+  //
+  // Get fuse info from PWRMBASE + FUSE_DIS_RD_2
+  //
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_FUSE_DIS_RD_2)) & B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function disables ISH device by static power gating.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableIsh (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] = 1b to statically disable ISH Controller
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC);
+}
+
+/**
+  This function enables ISH device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableIsh (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] = 0b to enable ISH controller
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) (~B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC));
+}
+
+/**
+  This function checks if GbE is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsGbeFunctionDisabled (
+  VOID
+  )
+{
+  //
+  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
+  //
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1)) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC) != 0);
+}
+
+/**
+  This function disables GbE device by static power gating and enables ModPHY SPD gating (PCH-LP only).
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableGbe (
+  VOID
+  )
+{
+  UINT32 PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] = 1b to statically disable GbE Controller
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[13] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    PmcGbeModPhyPowerGating ();
+  }
+}
+
+/**
+  This function enables GbE device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableGbe (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] = 0b to enable GbE controller
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC);
+}
+
+/**
+  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 disables (non-static power gating) HDA device
+**/
+VOID
+PmcDisableHda (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC);
+}
+
+/**
+  This function checks if Cnvi device is supported (not disabled by fuse)
+
+  @retval Cnvi support state
+**/
+BOOLEAN
+PmcIsCnviSupported (
+  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_CNVI_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if CNVi is function disabled
+  by static power gating
+
+  @retval GbE device state
+**/
+BOOLEAN
+PmcIsCnviFunctionDisabled (
+  VOID
+  )
+{
+  //
+  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1) & B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC) != 0);
+}
+
+/**
+  This function enables CNVi device by disabling static power gating.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableCnvi (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_1 to enable CNVi controller
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC);
+}
+
+/**
+  This function disables CNVi device by static power gating.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableCnvi (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1, B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC);
+}
+
+/**
+  This function disables (non-static power gating) PCIe Root Port and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+**/
+VOID
+PmcDisablePcieRootPort (
+  IN UINT32  RpIndex
+  )
+{
+  UINT32   NstPgFdis1Mask;
+  UINT32   PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+  //
+  // Set PchPwrmBase + NST_PG_FDIS_1 to function disable PCIE port in PMC
+  //
+  if (IsPchH () && RpIndex >= 20) {
+    NstPgFdis1Mask = B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC << (RpIndex % 20);
+  } else {
+    NstPgFdis1Mask = B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC << RpIndex;
+  }
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, NstPgFdis1Mask);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[26:0] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    if (RpIndex <= 11) {
+      MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0 << RpIndex);
+    } else {
+      MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0 << (RpIndex - 12));
+    }
+  }
+}
+
+/**
+  This function disables (non-static power gating) xHCI and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableXhci (
+  VOID
+  )
+{
+  UINT32   PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 [0] = 1b
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[14] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI);
+  }
+}
+
+/**
+  This function disables (non-static power gating) XDCI and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableXdci (
+  VOID
+  )
+{
+  UINT32 PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 [26] = 1b to disable XDCI Controller in PMC
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[15] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI);
+  }
+}
+
+/**
+  This function checks if XDCI device is supported (not disabled by fuse)
+
+  @retval XDCI support state
+**/
+BOOLEAN
+PmcIsXdciSupported (
+  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_OTG_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function locks HOST SW power gating control
+**/
+VOID
+PmcLockHostSwPgCtrl (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1, B_PMC_PWRM_SW_PG_CTRL_LOCK);
+}
+
+/**
+  This function checks if HOST SW Power Gating Control is locked
+
+  @retval lock state
+**/
+BOOLEAN
+PmcIsHostSwPgCtrlLocked (
+  VOID
+  )
+{
+  //
+  // Get lock info from PWRMBASE + HSWPGCR1
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1) & B_PMC_PWRM_SW_PG_CTRL_LOCK) != 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);
+}
+
+/**
+  Disables USB2 Core PHY PowerGating during power on for Chipsetinit table update
+**/
+VOID
+PmcUsb2CorePhyPowerGatingDisable (
+  VOID
+  )
+{
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_CFG, (UINT32) ~B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG);
+}
+
+
+/**
+  This function reads CPU Early Power-on Configuration (EPOC)
+
+  @retval CPU EPOC value
+**/
+UINT32
+PmcGetCpuEpoc (
+  VOID
+  )
+{
+  return MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC);
+}
+
+/**
+  This function sets CPU Early Power-on Configuration (EPOC)
+
+  @param[in] CpuEpocValue      CPU EPOC value
+**/
+VOID
+PmcSetCpuEpoc (
+  IN UINT32     CpuEpocValue
+  )
+{
+  MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC, CpuEpocValue);
+}
+
+/**
+  This function sets DRAM_RESET# Control Pin value
+
+  @param[in] DramResetVal      0: Pin output is low
+                               1: Pin output is tri-stated
+**/
+VOID
+PmcSetDramResetCtlState (
+  IN UINT32     DramResetVal
+  )
+{
+  ASSERT (DramResetVal < 2);
+
+  MmioAndThenOr32 (
+    PmcGetPwrmBase () + R_PMC_PWRM_CFG2,
+    (UINT32)~B_PMC_PWRM_CFG2_DRAM_RESET_CTL,
+    DramResetVal << N_PMC_PWRM_CFG2_DRAM_RESET_CTL
+    );
+}
+
+/**
+  This function enables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh
+**/
+VOID
+PmcEnableCf9GlobalReset (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) (B_PMC_PWRM_ETR3_CF9GR));
+}
+
+/**
+  This function disables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh.
+**/
+VOID
+PmcDisableCf9GlobalReset (
+  VOID
+  )
+{
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) ~B_PMC_PWRM_ETR3_CF9GR);
+}
+
+/**
+  This 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
+PmcDisableCf9GlobalResetWithLock (
+  VOID
+  )
+{
+  MmioAndThenOr32 (
+    PmcGetPwrmBase () + R_PMC_PWRM_ETR3,
+    (UINT32) ~B_PMC_PWRM_ETR3_CF9GR,
+    (UINT32) B_PMC_PWRM_ETR3_CF9LOCK
+    );
+}
+
+/**
+  This function disables CF9 reset without Resume Well reset.
+  Cf9 0x6/0xE reset will also reset resume well logic.
+**/
+VOID
+PmcDisableCf9ResetWithoutResumeWell (
+  VOID
+  )
+{
+
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32) ~B_PMC_PWRM_ETR3_CWORWRE);
+}
+
+/**
+  This function clears RTC Power Failure status (RTC_PWR_FLR)
+**/
+VOID
+PmcClearRtcPowerFailureStatus (
+  VOID
+  )
+{
+  //
+  // Set B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS to 0 to clear it.
+  //
+  MmioAnd8 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B), (UINT8) (~B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS));
+}
+
+/**
+  This function enables PCI Express* PME events
+**/
+VOID
+PmcEnablePciExpressPmeEvents (
+  VOID
+  )
+{
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B, B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN);
+}
+
+/**
+  This function sets eSPI SMI Lock
+**/
+VOID
+PmcLockEspiSmi (
+  VOID
+  )
+{
+  MmioAndThenOr8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1,
+    (UINT8) ~((B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS) >> 8),
+    B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK >> 8
+    );
+}
+
+/**
+  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);
+}
+
+/**
+  This function sets 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
+PmcSetGpioGpe (
+  IN UINT32    GpeDw0Value,
+  IN UINT32    GpeDw1Value,
+  IN UINT32    GpeDw2Value
+  )
+{
+  UINT32               Data32Or;
+  UINT32               Data32And;
+
+  //
+  // Program GPIO_CFG register
+  //
+  Data32And = (UINT32) ~(B_PMC_PWRM_GPIO_CFG_GPE0_DW2 | B_PMC_PWRM_GPIO_CFG_GPE0_DW1 | B_PMC_PWRM_GPIO_CFG_GPE0_DW0);
+  Data32Or  = (UINT32) ((GpeDw2Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW2) |
+                        (GpeDw1Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW1) |
+                        (GpeDw0Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW0));
+
+  MmioAndThenOr32 (
+    (PmcGetPwrmBase () + R_PMC_PWRM_GPIO_CFG),
+    Data32And,
+    Data32Or
+    );
+}
+
+/**
+  Disable SLP_S0# assertion when system is in debug mode
+**/
+VOID
+PmcDisableSlpS0AssertionInDebugMode (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Enable SLP_S0# assertion even when system is in debug mode
+**/
+VOID
+PmcEnableSlpS0AssertionInDebugMode (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Wbuf.Buf0 = 1;
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function gets NMI regsiter.
+
+  @retval  NMI register setting
+**/
+UINT32
+PmcGetNmiControl (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+  PMC_IPC_COMMAND_BUFFER    Rbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+  ZeroMem (&Rbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+  //
+  // WBUF0 = 2 for NMI delivery control and status register (entire register PCR[ITSS] 0x3330)
+  //
+  Wbuf.Buf0 = V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI;
+  Status = PmcSendCommand (
+             V_PMC_PWRM_IPC_CMD_COMMAND_PROXY,
+             V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ,
+             4,
+             &Wbuf,
+             &Rbuf
+             );
+  ASSERT_EFI_ERROR (Status);
+  return Rbuf.Buf0;
+}
+
+/**
+  This function sets the NMI register
+
+  @param[in]  NmiRegister    The whole NMI register
+**/
+VOID
+PmcSetNmiControl (
+  UINT32   NmiRegister
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+  //
+  // WBUF0 = 2 for NMI delivery control and status register (entire register PCR[ITSS] 0x3330)
+  //
+  Wbuf.Buf0 = V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI;
+  Wbuf.Buf1 = NmiRegister;
+  Status = PmcSendCommand (
+             V_PMC_PWRM_IPC_CMD_COMMAND_PROXY,
+             V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE,
+             8,
+             &Wbuf,
+             NULL
+             );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function enables GBE ModPHY SPD gating.
+**/
+VOID
+PmcGbeModPhyPowerGating (
+  VOID
+  )
+{
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set B_PCH_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE ModPHY SPD RT Request
+    //
+    MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE);
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c
new file mode 100644
index 0000000000..2411a2be23
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c
@@ -0,0 +1,73 @@
+/** @file
+  PCH PMC Private Library implementation for Cannon Lake PCH.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPmc.h>
+
+#include "PmcPrivateLibInternal.h"
+
+/**
+  This function disables (non-static power gating) SATA and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in]  SataCtrlIndex     SATA controller index
+**/
+VOID
+PmcDisableSata (
+  IN UINT32     SataCtrlIndex
+  )
+{
+  UINT32 PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 [22] = 1b to disable SATA Controller in PMC
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // MPHY SUS PG supported on PCH-LP only:
+    //
+    // Set MSPDRTREQ:
+    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[12] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA);
+  }
+}
+
+/**
+  This function checks if SATA device is supported (not disabled by fuse)
+
+  @param[in] SataCtrlIndex SATA controller index
+
+  @retval SATA support state
+**/
+BOOLEAN
+PmcIsSataSupported (
+  UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
+
+  //
+  // 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_SATA_FUSE_SS_DIS) == 0);
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c
new file mode 100644
index 0000000000..847be42937
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c
@@ -0,0 +1,360 @@
+/** @file
+  PCH PMC Private Library implementation for Cannon Lake PCH.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPmc.h>
+
+#include "PmcPrivateLibInternal.h"
+
+/**
+  This function disables Trace Hub by enabling power gating
+**/
+VOID
+PmcDisableTraceHub (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Wbuf.Buf0 = BIT0;
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function enables Trace Hub by disabling power gating
+**/
+VOID
+PmcEnableTraceHub (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  PMC_IPC_COMMAND_BUFFER    Wbuf;
+
+  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
+
+  Wbuf.Buf0 = BIT1;
+  Status = PmcSendCommand (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL);
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  This function is part of PMC init and configures which clock wake signals should
+  set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent up to the CPU/PCH
+**/
+VOID
+PmcInitClockWakeEnable (
+  VOID
+  )
+{
+  UINT32                    PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    ///
+    /// PWRMBASE + 0x1880 = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING, 0x0);
+  } else {
+    ///
+    /// PWRMBASE + 0x1880 = 0x2F8FBB01
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING, 0x2F8FBB01);
+  }
+
+  if (IsPchLp ()) {
+    if (PchStepping () < PCH_B0) {
+      ///
+      /// PWRMBASE + 0x1884 = 0x0
+      ///
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, 0x0);
+    } else {
+      ///
+      /// PWRMBASE + 0x1884
+      ///  PCH-LP: 0x0280C7E1
+      ///
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, 0x0280C7E1);
+    }
+  } else {
+    ///
+    /// PWRMBASE + 0x1884
+    ///  PCH-H:  0x0280D7E1
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2, 0x0280D7E1);
+  }
+
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    ///
+    /// PWRMBASE + 0x1888 = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x0);
+    ///
+    /// PWRMBASE + 0x188C = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0);
+  } else {
+    ///
+    /// PWRMBASE + 0x1888 = 0x2F8FAB01
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x2F8FAB01);
+
+    ///
+    /// PWRMBASE + 0x188C
+    ///  PCH-LP: 0x0280C7E1
+    ///  PCH-H:  0x0280D7E1
+    ///
+    if (IsPchLp ()) {
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0280C7E1);
+    } else {
+      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0280D7E1);
+    }
+  }
+
+  if (IsPchLp () && (PchStepping () < PCH_B0)) {
+    ///
+    /// PWRMBASE + 0x1898 = 0x0
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF, 0x0);
+  } else {
+    ///
+    /// PWRMBASE + 0x1898 = 0x00018000
+    ///
+    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF, 0x00018000);
+  }
+}
+
+/**
+  This function configures PWRMBASE + 0x1E00 register
+**/
+VOID
+PmcConfigureRegPwrm1E00 (
+  VOID
+  )
+{
+  ///
+  /// PWRMBASE + 0x1E00[31,30] = 1,1
+  /// PWRMBASE + 0x1E00[29] = 0
+  /// PWRMBASE + 0x1E00[10:6] = 0
+  /// PWRMBASE + 0x1E00[3:0] = 2
+  ///
+  MmioAndThenOr32 (
+    PmcGetPwrmBase () + R_PMC_PWRM_1E00,
+    (UINT32) ~(BIT29 | (0x1F << 6) | 0xF),
+    BIT31 | BIT30 | 2
+    );
+}
+
+/**
+  This function configures Misc PM_SYNC events settings
+**/
+VOID
+PmcConfigurePmSyncEventsSettings (
+  VOID
+  )
+{
+  ///
+  /// PWRMBASE + 0x18C0 = 0x00000A20
+  ///
+  MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_EN_MISC_EVENT, 0x00000A20);
+}
+
+/**
+  This function enables all SerailIo devices.
+  Static power gating disabling takes place after Global Reset, G3 or DeepSx transition.
+**/
+VOID
+PmcEnableSerialIo (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_2
+  //
+  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2, (UINT32)~B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
+}
+
+/**
+  This function disables (static power gating) all SerailIo devices.
+  For SerialIo controllers they can be power gated only if all of them are to be disabled.
+  They cannot be statically power gated separately.
+  For static power gating to take place Global Reset, G3 or DeepSx transition must happen.
+**/
+VOID
+PmcStaticDisableSerialIo (
+  VOID
+  )
+{
+  //
+  // Set PWRMBASE + ST_PG_FDIS_PMC_2
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2, B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
+}
+
+/**
+  This function checks if all SerialIo devices are statically disabled (static power gating)
+
+  @retval SerialIo disable state
+**/
+BOOLEAN
+PmcIsSerialIoStaticallyDisabled (
+  VOID
+  )
+{
+  //
+  // Check if all SerialIo controllers are statically disabled in PMC
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2) & B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO) == B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
+}
+
+/**
+  This function checks if SerialIo device is supported (not disabled by fuse)
+
+  @retval SerialIo support state
+**/
+BOOLEAN
+PmcIsSerialIoSupported (
+  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_SERIALIO_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function disables (non-static power gating) SCS eMMC controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsEmmc (
+  VOID
+  )
+{
+  ASSERT (IsPchLp ());
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC);
+}
+
+/**
+  This function disables (non-static power gating) SCS SD Card controller and enables ModPHY SPD gating (PCH-LP only).
+**/
+VOID
+PmcDisableScsSdCard (
+  VOID
+  )
+{
+  UINT32        ScsDevicePgMask;
+
+  if (IsPchLp ()) {
+    ScsDevicePgMask = B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC;
+  } else {
+    ScsDevicePgMask = B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC;
+  }
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
+  //
+  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1, ScsDevicePgMask);
+}
+
+/**
+  This function disables (non-static power gating) SCS UFS controller and enables ModPHY SPD gating (PCH-LP only).
+
+  @param[in] UfsNum     SCS UFS Device
+**/
+VOID
+PmcDisableScsUfs (
+  IN UINT32   UfsNum
+  )
+{
+  UINT32        PchPwrmBase;
+
+  ASSERT ((UfsNum == 0) && IsPchLp ());
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1, B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC);
+
+  if (PmcIsModPhySusPgSupported ()) {
+    //
+    // Set MSPDRTREQ:
+    // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[16] = 1 to enable ASL code trigger request for ModPHY SPD gating.
+    //
+    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5, B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2);
+  }
+}
+
+/**
+  This function checks if SCS eMMC device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsEmmcSupported (
+  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_EMMC_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if SCS SD Card device is supported (not disabled by fuse)
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsSdCardSupported (
+  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_SDX_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if SCS UFS device is supported (not disabled by fuse)
+
+  @param[in] UfsNum     SCS UFS Device
+
+  @retval SCS device support state
+**/
+BOOLEAN
+PmcIsScsUfsSupported (
+  IN UINT32   UfsNum
+  )
+{
+  //
+  // 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_UFSX2_FUSE_SS_DIS) == 0);
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
new file mode 100644
index 0000000000..bbe944da5c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
@@ -0,0 +1,194 @@
+/** @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) 2019 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 <Private/Library/PmcPrivateLib.h>
+
+/**
+  This function locks down PMC (DebugModeLock)
+**/
+VOID
+PmcLockWithS3BootScript (
+  VOID
+  )
+{
+
+  UINT32 PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // Set PWRM_CFG[27] prior to OS.
+  //
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_CFG, B_PMC_PWRM_CFG_DBG_MODE_LOCK);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (PchPwrmBase + R_PMC_PWRM_CFG),
+    1,
+    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_CFG)
+    );
+
+}
+
+/**
+  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 SLP_SX Stretching Policy and adds
+  lock setting to S3 Boot Script
+**/
+VOID
+PmcLockSlpSxStretchingPolicyWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr8 (
+    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2),
+    (UINT8) ((B_PMC_PWRM_GEN_PMCON_B_SLPSX_STR_POL_LOCK) >> 16)
+    );
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2),
+    1,
+    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2)
+    );
+}
+
+/**
+  This function sets SMI Lock with S3 Boot Script programming
+**/
+VOID
+PmcLockSmiWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr8 ((PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B),
+    1,
+    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B)
+    );
+}
+
+/**
+  This function locks static power gating configuration with S3 Boot Script programming
+**/
+VOID
+PmcLockFunctionDisableConfigWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32) (B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK));
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1),
+    1,
+    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1)
+    );
+}
+
+/**
+  This function locks PMC Set Strap Message interface with S3 Boot Script programming
+**/
+VOID
+PmcLockSetStrapMsgInterfaceWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr32 ((UINTN) (PchPwrmBase + R_PMC_PWRM_SSML), B_PMC_PWRM_SSML_SSL);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML),
+    1,
+    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML)
+    );
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c
new file mode 100644
index 0000000000..9c722bce07
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c
@@ -0,0 +1,356 @@
+/** @file
+  This file contains routines for PEI GPIO Helpers Lib
+
+  Copyright (c) 2019 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 <Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h>
+#include <Private/Library/GpioHelpersLib.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;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c
new file mode 100644
index 0000000000..1b05378799
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c
@@ -0,0 +1,68 @@
+/** @file
+  This file contains GpioMemLib implementation for PEI phase
+
+  Copyright (c) 2019 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 <Private/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 ();
+  }
+}
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules

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

* SaAcpiTables - SA (DMAR) ACPI tables.
* SaSsdt - SA SSDT ACPI tables.
* SaInitDxe - Generic DXE SA initialization.
* SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf                    |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                   |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf                       |  116 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf                    |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h                         |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h |  230 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h   | 1567 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h     |  203 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h     | 1167 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h       |  237 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h              |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h                      |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h                   |  193 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h                    |   91 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h                       |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h                            |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h                         |  139 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h            |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h                               |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h                |  162 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c                      |  157 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c                   |  570 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c                    |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c                       |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c                            |  496 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c                            |  179 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c                         |  122 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c                               |  717 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c                |  356 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc                      |  250 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl                         |  794 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl                     | 1666 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl               |  472 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl                  |  369 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl               |  129 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl                 |  296 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl               |  262 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl                      |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                       |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl                    |  147 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                   |   22 +
 41 files changed, 11970 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
new file mode 100644
index 0000000000..56ddc2957f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
@@ -0,0 +1,50 @@
+## @file
+#  Component description file for the ACPI tables
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SaAcpiTables
+FILE_GUID            = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  Dmar/Dmar.aslc
+  Dmar/Dmar.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
new file mode 100644
index 0000000000..3588565aac
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
@@ -0,0 +1,49 @@
+## @file
+#  Component description file for the ACPI tables
+#
+# Copyright (c) 2019 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
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+#                         this module.
+#
+################################################################################
+
+[LibraryClasses]
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+#                           that this module uses or produces.
+#
+################################################################################
+[Pcd]
+
+[Protocols]
+
+[PPIs]
+
+[Guids]
+
+[Depex]
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
new file mode 100644
index 0000000000..9937fc60e5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
@@ -0,0 +1,116 @@
+## @file
+# Component description file for SystemAgent Initialization driver
+#
+# Copyright (c) 2019 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
+TimerLib
+PciCf8Lib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+IoLib
+S3BootScriptLib
+PmcLib
+PchCycleDecodingLib
+PchInfoLib
+GpioLib
+ConfigBlockLib
+SaPlatformLib
+PchPcieRpLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
+
+[Sources]
+SaInitDxe.h
+SaInitDxe.c
+SaInit.h
+SaInit.c
+VTd.c
+VTd.h
+IgdOpRegionInit.h
+IgdOpRegionInit.c
+GraphicsInit.h
+GraphicsInit.c
+PciExpressInit.h
+PciExpressInit.c
+PcieComplex.c
+PcieComplex.h
+SaAcpi.c
+
+[Protocols]
+gEfiAcpiTableProtocolGuid              ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## PRODUCES
+gSaPolicyProtocolGuid                  ## CONSUMES
+gEfiCpuArchProtocolGuid                ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
+gEfiPciIoProtocolGuid                  ## CONSUMES
+gIgdOpRegionProtocolGuid               ## PRODUCES
+gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
+gEfiLegacyBiosProtocolGuid             ## CONSUMES
+gGopComponentName2ProtocolGuid         ## CONSUMES
+gSaIotrapSmiProtocolGuid               ## CONSUMES
+
+[Guids]
+gSaConfigHobGuid
+gSgAcpiTablePchStorageGuid
+gSaAcpiTableStorageGuid
+gSgAcpiTableStorageGuid
+gSaSsdtAcpiTableStorageGuid
+gPegSsdtAcpiTableStorageGuid
+gEfiEndOfDxeEventGroupGuid
+gSiConfigHobGuid        ## CONSUMES
+gMiscDxeConfigGuid
+gGraphicsDxeConfigGuid
+gMemoryDxeConfigGuid
+gPcieDxeConfigGuid
+gVbiosDxeConfigGuid
+gPchInfoHobGuid
+
+[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/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
new file mode 100644
index 0000000000..9356781c9e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the SmmAccess module
+#
+# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmAccess
+FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SmmAccessDriverEntryPoint
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+BaseLib
+BaseMemoryLib
+DebugLib
+HobLib
+PciLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmAccessDriver.h
+SmmAccessDriver.c
+
+
+[Protocols]
+gEfiSmmAccess2ProtocolGuid       ## PRODUCES
+
+
+[Guids]
+gEfiSmmPeiSmramMemoryReserveGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
new file mode 100644
index 0000000000..4339256bba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
@@ -0,0 +1,25 @@
+/** @file
+  This file describes the contents of the ACPI DMA address Remapping
+  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_DMAR_H_
+#define _SA_DMAR_H_
+
+///
+/// Include standard ACPI table definitions
+///
+#include <IndustryStandard/Acpi30.h>
+#include <DmaRemappingTable.h>
+
+#pragma pack(1)
+
+#define EFI_ACPI_DMAR_OEM_TABLE_ID    0x20202020324B4445  ///< "EDK2    "
+#define EFI_ACPI_DMAR_OEM_CREATOR_ID  0x4C544E49  ///< "INTL"
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
new file mode 100644
index 0000000000..54cb69066d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
@@ -0,0 +1,230 @@
+/** @file
+  This file contains the definitions common to the MRC API and other APIs.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcCommonTypes_h_
+#define _MrcCommonTypes_h_
+
+#define INT32_MIN                       (0x80000000)
+#ifndef INT32_MAX  //INT32_MAX->Already defined
+#define INT32_MAX                       (0x7FFFFFFF)
+#endif
+#define INT16_MIN                       (0x8000)
+#define INT16_MAX                       (0x7FFF)
+
+///
+/// System boot mode.
+///
+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.
+} MrcBootMode;
+
+///
+/// DIMM memory package
+/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
+/// Note that DDR4 have different encoding for some module types
+///
+typedef enum {
+  RDimmMemoryPackage          = 1,
+  UDimmMemoryPackage          = 2,
+  SoDimmMemoryPackage         = 3,
+  MicroDimmMemoryPackageDdr3  = 4,
+  LrDimmMemoryPackageDdr4     = 4,
+  MiniRDimmMemoryPackage      = 5,
+  MiniUDimmMemoryPackage      = 6,
+  MiniCDimmMemoryPackage      = 7,
+  LpDimmMemoryPackage         = 7,
+  SoUDimmEccMemoryPackageDdr3 = 8,
+  SoRDimmEccMemoryPackageDdr4 = 8,
+  SoRDimmEccMemoryPackageDdr3 = 9,
+  SoUDimmEccMemoryPackageDdr4 = 9,
+  SoCDimmEccMemoryPackage     = 10,
+  LrDimmMemoryPackage         = 11,
+  SoDimm16bMemoryPackage      = 12,
+  SoDimm32bMemoryPackage      = 13,
+  NonDimmMemoryPackage        = 14,
+  MemoryPackageMax,                       ///< MEMORY_PACKAGE enumeration maximum value.
+  MemoryPackageDelim = INT32_MAX          ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MEMORY_PACKAGE;
+
+///
+/// Memory training I/O levels.
+///
+typedef enum {
+  DdrLevel   = 0,                         ///< Refers to frontside of DIMM
+  LrbufLevel = 1,                         ///< Refers to data level at backside of LRDIMM or AEP buffer
+  RegALevel  = 2,                         ///< Refers to cmd level at backside of register - side A
+  RegBLevel  = 3,                         ///< Refers to cmd level at backside of register - side B
+  GsmLtMax,                               ///< GSM_LT enumeration maximum value.
+  GsmLtDelim = INT32_MAX                  ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_LT;
+
+///
+/// Memory training margin group selectors.
+///
+typedef enum {
+  RecEnDelay       = 0,                   ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+  RxDqsDelay       = 1,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+  RxDqDelay        = 2,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQ byte/nibble/bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+  RxDqsPDelay      = 3,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "even" chunks later in time relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxDqsNDelay      = 4,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe for "odd" chunks later in time relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxVref           = 5,                   ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+  RxEq             = 6,                   ///< RX CTLE setting indicating a set of possible resistances, capacitance, current steering, etc. values, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  RxDqBitDelay     = 7,                   ///< Linear delay (PI ticks), where the positive increment moves the RX DQ bitlane later in time relative to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
+  RxVoc            = 8,                   ///< Monotonic increment (Sense Amp setting), where the positive increment moves the byte/nibble/bitlane's effective switching point to a lower Vref value.
+  RxOdt            = 9,                   ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  RxOdtUp          = 10,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  RxOdtDn          = 11,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  DramDrvStr       = 12,                  ///< Drive strength setting resistance setting within a set of possible resistances (or currents), which may be a different set of values per product. Indexed by integer values.
+  McOdtDelay       = 13,                  ///<
+  McOdtDuration    = 14,                  ///<
+  SenseAmpDelay    = 15,                  ///< This may be used to indicate CmdToDiffAmpEn for SoC's.
+  SenseAmpDuration = 16,                  ///<
+  RoundTripDelay   = 17,                  ///< This may be used to indicate CmdToRdDataValid for SoC's.
+  RxDqsBitDelay    = 18,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS within the bitlane later in time relative to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of the eye).
+  RxDqDqsDelay     = 19,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS per strobe later in time relative to the RX DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye. The difference between this parameter and RxDqsDelay is that both the DQ and DQS timings may be moved in order to increase the total range of DQDQS timings.
+  WrLvlDelay       = 20,                  ///< Linear delay (PI ticks), where the positive increment moves both the TX DQS and TX DQ signals later in time relative to all other bus signals.
+  TxDqsDelay       = 21,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+  TxDqDelay        = 22,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+  TxVref           = 23,                  ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane TX Vref to a higher voltage. (Assuming this will abstract away from the range specifics for DDR4, for example.)
+  TxEq             = 24,                  ///< TX EQ setting indicating a set of possible equalization levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  TxDqBitDelay     = 25,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ bitlane later in time relative to all other bus signals.
+  TxRon            = 26,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxRonUp          = 27,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxRonDn          = 28,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxSlewRate       = 29,                  ///< Monotonic increment, where the positive increment moves the byte/nibble/bitlane's effective slew rate to a higher slope.
+  TxImode          = 30,                  ///< TX I-Mode Boost setting indicating a set of possible current boost levels, which may be a different set of values per product. The setting combinations are indexed by integer values.
+  WrOdt            = 31,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  NomOdt           = 32,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  ParkOdt          = 33,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+  TxTco            = 34,                  ///<
+  RxCtleR          = 36,                  ///<
+  RxCtleC          = 37,                  ///<
+  RxDqsPBitDelay   = 38,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "even" chunks later in time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  RxDqsNBitDelay   = 39,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS bitlane timing for "odd" chunks later in time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks of an 8 burst length cacheline, for example.
+  CmdAll           = 40,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_ALL category later in time relative to all other signals on the bus.
+  CmdGrp0          = 41,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP0 category later in time relative to all other signals on the bus.
+  CmdGrp1          = 42,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP1 category later in time relative to all other signals on the bus.
+  CmdGrp2          = 43,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_GRP2 category later in time relative to all other signals on the bus.
+  CtlAll           = 44,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_ALL category later in time relative to all other signals on the bus.
+  CtlGrp0          = 45,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP0 category later in time relative to all other signals on the bus.
+  CtlGrp1          = 46,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP1 category later in time relative to all other signals on the bus.
+  CtlGrp2          = 47,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP2 category later in time relative to all other signals on the bus.
+  CtlGrp3          = 48,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP3 category later in time relative to all other signals on the bus.
+  CtlGrp4          = 49,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP4 category later in time relative to all other signals on the bus.
+  CtlGrp5          = 50,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CTL_GRP5 category later in time relative to all other signals on the bus.
+  CmdCtlAll        = 51,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CMD_CTL_ALL category later in time relative to all other signals on the bus.
+  CkAll            = 52,                  ///< Linear delay (PI ticks), where the positive increment moves all signals assigned to the CK_ALL category later in time relative to all other signals on the bus.
+  CmdVref          = 53,                  ///< Linear increment (Vref ticks), where the positive increment moves the CMD Vref to a higher voltage.
+  AlertVref        = 54,                  ///< Linear increment (Vref ticks), where the positive increment moves the ALERT Vref to a higher voltage.
+  CmdRon           = 55,                  ///< Resistance setting within a set of possible resistances, which may be a different set of values per product. Indexed by integer values.
+
+  EridDelay        = 60,                  ///< Linear delay (PI ticks), where the positive increment moves the ERID signals later in time relative to the internal sampling clock (i.e.closing the gap between ERID and internal sampling clock in the setup side of the eye). This group is applicable for DDRT DIMMs.
+  EridVref         = 61,                  ///< Linear increment (Vref ticks), where the positive increment moves the ERID Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  ErrorVref        = 62,                  ///< Linear increment (Vref ticks), where the positive increment moves the ERROR Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  ReqVref          = 63,                  ///< Linear increment (Vref ticks), where the positive increment moves the REQ Vref to a higher voltage. This group is applicable for DDRT DIMMs.
+  RecEnOffset      = 64,                  ///< Linear delay (PI ticks), where the positive increment moves the RCVEN sampling window later in time relative to the RX DQS strobes.
+  RxDqsOffset      = 65,                  ///< Linear delay (PI ticks), where the positive increment moves the RX DQS strobe later in time relative to the RX DQ signal (i.e. toward the hold side of the eye).
+  RxVrefOffset     = 66,                  ///< Linear increment (Vref ticks), where the positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
+  TxDqsOffset      = 67,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQS strobe later in time relative to all other bus signals.
+  TxDqOffset       = 68,                  ///< Linear delay (PI ticks), where the positive increment moves the TX DQ byte/nibble/bitlane later in time relative to all other bus signals.
+  GsmGtMax,                               ///< SSA_GSM_GT enumeration maximum value.
+  GsmGtDelim = INT32_MAX                  ///< This value ensures the enum size is consistent on both sides of the PPI.
+} GSM_GT;
+
+typedef enum {
+  SigRasN   = 0,
+  SigCasN   = 1,
+  SigWeN    = 2,
+  SigBa0    = 3,
+  SigBa1    = 4,
+  SigBa2    = 5,
+  SigA0     = 6,
+  SigA1     = 7,
+  SigA2     = 8,
+  SigA3     = 9,
+  SigA4     = 10,
+  SigA5     = 11,
+  SigA6     = 12,
+  SigA7     = 13,
+  SigA8     = 14,
+  SigA9     = 15,
+  SigA10    = 16,
+  SigA11    = 17,
+  SigA12    = 18,
+  SigA13    = 19,
+  SigA14    = 20,
+  SigA15    = 21,
+  SigA16    = 22,
+  SigA17    = 23,
+  SigCs0N   = 24,
+  SigCs1N   = 25,
+  SigCs2N   = 26,
+  SigCs3N   = 27,
+  SigCs4N   = 28,
+  SigCs5N   = 29,
+  SigCs6N   = 30,
+  SigCs7N   = 31,
+  SigCs8N   = 32,
+  SigCs9N   = 33,
+  SigCke0   = 34,
+  SigCke1   = 35,
+  SigCke2   = 36,
+  SigCke3   = 37,
+  SigCke4   = 38,
+  SigCke5   = 39,
+  SigOdt0   = 40,     //could also be used for CA-ODT for LP4
+  SigOdt1   = 41,     //could also be used for CA-ODT for LP4
+  SigOdt2   = 42,
+  SigOdt3   = 43,
+  SigOdt4   = 44,
+  SigOdt5   = 45,
+  SigPar    = 46,
+  SigAlertN = 47,
+  SigBg0    = 48,
+  SigBg1    = 49,
+  SigActN   = 50,
+  SigCid0   = 51,
+  SigCid1   = 52,
+  SigCid2   = 53,
+  SigCk0    = 54,
+  SigCk1    = 55,
+  SigCk2    = 56,
+  SigCk3    = 57,
+  SigCk4    = 58,
+  SigCk5    = 59,
+  SigGnt0   = 60,
+  SigGnt1   = 61,
+  SigErid00 = 62,
+  SigErid01 = 63,
+  SigErid10 = 64,
+  SigErid11 = 65,
+  SigErr0   = 66,
+  SigErr1   = 67,
+  SigCa00   = 68,    // First instantiation of the CA bus for a given channel
+  SigCa01   = 69,
+  SigCa02   = 70,
+  SigCa03   = 71,
+  SigCa04   = 72,
+  SigCa05   = 73,
+  SigCa10   = 74,    // Second instantiation of the CA bus for a given channel
+  SigCa11   = 75,
+  SigCa12   = 76,
+  SigCa13   = 77,
+  SigCa14   = 78,
+  SigCa15   = 79,
+  GsmCsnMax,
+  GsmCsnDelim = INT32_MAX
+} GSM_CSN;
+
+
+#endif // _MrcCommonTypes_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
new file mode 100644
index 0000000000..635906cc2b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
@@ -0,0 +1,1567 @@
+/** @file
+  This file includes all the data structures that the MRC considers "global data".
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcInterface_h_
+#define _MrcInterface_h_
+
+#define MAX_CPU_SOCKETS          (1)       ///< The maximum number of CPUs per system.
+#define MAX_CONTROLLERS          (1)       ///< The maximum number of memory controllers per CPU socket.
+#define MAX_CHANNEL              (2)       ///< The maximum number of channels per memory controller.
+#define MAX_DIMMS_IN_CHANNEL     (2)       ///< The maximum number of DIMMs per channel.
+#define MAX_RANK_IN_DIMM         (2)       ///< The maximum number of ranks per DIMM.
+#define MAX_RANK_IN_CHANNEL      (MAX_DIMMS_IN_CHANNEL * MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
+#define MAX_SDRAM_IN_DIMM        (9)       ///< The maximum number of SDRAMs per DIMM when ECC is enabled.
+#define MAX_MR_IN_DIMM           (7)       ///< Maximum number of mode registers in a DIMM.
+#define MAX_DEVICES_IN_DDR4      (8)       ///< The maximum number of SDRAMs per DDR4 DIMM.
+#define MAX_BITS                 (8)       ///< BITS per byte.
+#define MAX_STROBE               (18)      ///< Number of strobe groups.
+#define MAX_DQ                   (72)      ///< Number of Dq bits used by the rank.
+#define CHAR_BITS                (8)       ///< Number of bits in a char.
+#define PSMI_SIZE_MB             (64)      ///< Define the max size of PSMI needed in MB
+#define BCLK_DEFAULT             (100 * 1000 * 1000) ///< BCLK default value, in Hertz.
+#define MAX_COMMAND_GROUPS       (2)
+#define MAX_EDGES                (2) ///< Maximum number of edges.
+#define SUPPORT_DDR3             SUPPORT   ///< SUPPORT means that DDR3 is supported by the MRC.
+#define ULT_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define TRAD_SUPPORT_LPDDR3      /*UN*/SUPPORT ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define BDW_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that LPDDR3 is supported by the MRC.
+#define JEDEC_SUPPORT_LPDDR      SUPPORT   ///< SUPPORT means that JEDEC SPD Spec for LPDDR3 is supported by the MRC.
+#define SUPPORT_DDR4             SUPPORT   ///< SUPPORT means that DDR4 is supported by the MRC.
+#define SUPPORT_LPDDR3           (ULT_SUPPORT_LPDDR3 || TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 || JEDEC_SUPPORT_LPDDR)
+#define MRC_ALL_DDR_SUPPORTED    ((SUPPORT_DDR4 == SUPPORT) && ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
+#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) || (SUPPORT_LPDDR3 == SUPPORT))
+#define SPD3_MANUF_START       117         ///< The starting point for the SPD manufacturing data.
+#define SPD3_MANUF_END         127         ///< The ending point for the SPD manufacturing data.
+#if (SUPPORT_DDR4 == SUPPORT)
+#define SPD4_MANUF_START       320         ///< The starting point for the SPD manufacturing data.
+#define SPD4_MANUF_END         328         ///< The ending point for the SPD manufacturing data.
+#endif
+#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
+#define SPDLP_MANUF_START      320         ///< The starting point for the SPD manufacturing data.
+#define SPDLP_MANUF_END        328         ///< The ending point for the SPD manufacturing data.
+#endif
+#include "MrcSpdData.h"
+#include "MrcRmtData.h"
+#include "MrcCommonTypes.h"
+#pragma pack (push, 1)
+
+
+///
+//////////////////////////////////////////////////////////////////////////////////////
+///                           OEM platform  routines and types                      //
+//////////////////////////////////////////////////////////////////////////////////////
+///
+/// define the oem check points the OEM can define more point and locate them in the code.
+///
+typedef enum {
+  OemFastBootPermitted,     ///<  before fast boot.
+  OemRestoreNonTraining,
+  OemPrintInputParameters,  ///<  before printing input parameters
+  OemSpdProcessingRun,      ///<  before spd processing code
+  OemSetOverridePreSpd,     ///<  before set overrides pre spd
+  OemSetOverride,           ///<  before set overrides
+  OemMcCapability,          ///<  before MC capability
+  OemMcInitRun,             ///<  before mc init code
+  OemMcMemoryMap,           ///<  before memory map
+  OemMcResetRun,            ///<  before jedec reset
+  OemPreTraining,           ///<  before the training.
+  OemMcTrainingRun,         ///<  before training code
+  OemEarlyCommandTraining,  ///<  before Early Command training
+  OemJedecInitLpddr3,       ///<  before Jedec Init Lpddr3
+  OemSenseAmpTraining,      ///<  before Sense Amp Training
+  OemReadMprTraining,       ///<  before Read MPR Training
+  OemReceiveEnable,         ///<  before Read Leveling
+  OemJedecWriteLeveling,    ///<  before Jedec Write Leveling
+  OemLpddrLatencySetB,      ///<  before LPDDR Latency Set B
+  OemWriteDqDqs,            ///<  before Write Timing Centering
+  OemWriteVoltage,          ///<  before Write Voltage Centering
+  OemEarlyWriteDqDqs2D,     ///<  before Early Write Timing Centering 2D
+  OemEarlyWrDsEq,           ///<  before Early Write Drive Strength / Equalization
+  OemEarlyReadDqDqs2D,      ///<  before Early Read Timing Centering 2D
+  OemEarlyReadMprDqDqs2D,   ///<  before Early MPR Read Timing Centering 2D
+  OemReadDqDqs,             ///<  before Read Timing Centering
+  OemDdr4Map,               ///<  before DDR4 PDA Mapping
+  OemDimmRonTraining,       ///<  before DIMM Ron Training
+  OemDimmODTTraining,       ///<  before DIMM ODT Training
+  OemWriteDriveStrengthEq,  ///<  before Write Drive Strength/Equalization 2D Training
+  OemWriteDriveUpDn,        ///<  before Write Drive Strength Up/Dn 2D Training
+  OemWriteSlewRate,         ///<  before Write Slew Rate Training
+  OemReadODTTraining,       ///<  before Read ODT algorithm.
+  OemReadEQTraining,        ///<  before Read Equalization Training
+  OemReadAmplifierPower,    ///<  before Read Amplifier Power
+  OemOptimizeComp,          ///<  before Comp Optimization Training
+  OemPowerSavingMeter,      ///<  before PowerSavingMeter step
+  OemWriteDqDqs2D,          ///<  before Write Timing Centering 2D
+  OemReadDqDqs2D,           ///<  before Read Timing Centering 2D
+  OemCmdVoltCenterPreLct,   ///<  before Command Voltage Centering that runs pre-LCT
+  OemCmdSlewRate,           ///<  before CMD Slew Rate
+  OemCmdVoltCentering,      ///<  before Command Voltage Centering
+  OemCmdDriveStrengthEq,    ///<  before Command Drive Strength Equalization
+  OemWriteVoltCentering2D,  ///<  before Write Voltage Centering 2D
+  OemReadVoltCentering2D,   ///<  before Read Voltage Centering 2D
+  OemLateCommandTraining,   ///<  before Late Command training
+  OemCmdNormalization,      ///<  before CMD Normalization
+  OemRoundTripLatency,      ///<  before Round Trip Latency Traiing
+  OemTurnAroundTimes,       ///<  before Turn Aorund Times.
+  OemRcvEnCentering1D,      ///<  before Receive Enable Centring
+  OemSaveMCValues,          ///<  before saving memory controller values
+  OemRmt,                   ///<  before RMT crosser tool.
+  OemMemTest,               ///<  before Memory testing
+  OemRestoreTraining,       ///<  before Restoring Training Values
+  OemJedecResetDdr4Fast,    ///<  before JEDEC reset for DDR4 in Fast flow
+  OemSelfRefreshExit,       ///<  before Self Refresh Exit
+  OemNormalMode,            ///<  before Normal Mode on non-cold boots.
+  OemThermalConfig,         ///<  set Thermal config values.
+  OemTxtAliasCheck,         ///<  before TxT Alias Check Call.
+  OemAliasCheck,            ///<  before alias checking on cold boots.
+  OemHwMemInit,
+
+  OemPostTraining,          ///<  after the training.
+  OemForceOltm,             ///<  before MrcForceOltm
+  OemMrcActivate,           ///<  before MrcActivate call.
+  OemMrcRhPrevention,       ///<  before MrcRhPrevention
+  OemSaGvSwitch,            ///<  before SA GV switch
+  OemEngPerfGain,           ///<  before Energy Performance Gain.
+  OemMrcDone,               ///<  call to MrcOemCheckPoint when MRC was done.
+  OemFrequencySet,          ///<  do operation before frequency set.
+  OemFrequencySetDone,      ///<  do operation after frequency set.
+  OemStartMemoryConfiguration,
+  OemBeforeNormalMode,      ///<  call to MrcOemCheckPoint before normal mode is enalbed
+  OemAfterNormalMode,       ///<  call to MrcOemCheckPoint after normal mode is enalbed
+  OemMrcFillBdat,
+  OemRetrainMarginCheck,
+  OemRmtPerBit,             ///< before Rank Margin Tool Per-Bit.
+  OemUpdateSaveMCValues,    ///< before Updating memory controller values.
+  ///
+  ///*********************************************************************************
+  ///
+  OemNumOfCommands          ///<  Should always be last in the list!
+} MrcOemStatusCommand;
+
+typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with 0 and increment by one each time MRC library is called.
+#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 << ((sizeof (MrcIteration) * 8) - 1)) - 1))
+
+#define MAX_RCOMP         (3)
+#define MAX_RCOMP_TARGETS (5)
+
+///
+/// Thermal Options
+///
+typedef struct {
+  UINT8  RaplLim2WindX;                                    ///< Offset 110  - Power Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8  RaplLim2WindY;                                    ///< Offset 111  - Power Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
+  UINT8  RaplLim1WindX;                                    ///< Offset 112  - Power Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
+  UINT8  RaplLim1WindY;                                    ///< Offset 113  - Power Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
+  UINT16 RaplLim2Pwr;                                      ///< Offset 114  - Power Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
+  UINT16 RaplLim1Pwr;                                      ///< Offset 116  - Power Limit 1: <b>0=Minimal</b>, 16383=Maximum
+  UINT8  WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///< Offset 118  - Warm Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];  ///< Offset 122  - Hot Threshold (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];    ///< Offset 126  - Warm Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];     ///< Offset 130  - Hot Budget (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
+  UINT8  IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+  UINT8  WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+} ThermalMngmtEn;
+
+
+typedef struct {
+  UINT8      GdxcEnable;   ///< GDXC  MOT enable
+  UINT8      GdxcIotSize;  ///< IOT size in multiples of 8MEG
+  UINT8      GdxcMotSize;  ///< MOT size in multiples of 8MEG
+} MrcGdxc;
+
+typedef struct {
+  UINT32 ECT : 1;        ///< BIT0 - Early Command Training
+  UINT32 SOT : 1;        ///< BIT1 - Sense Amp Offset Training
+  UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
+  UINT32 RDMPRT : 1;     ///< BIT3 - Read MPR Training
+  UINT32 RCVET : 1;      ///< BIT4 - Read Leveling Training (RcvEn)
+  UINT32 JWRL : 1;       ///< BIT5 - Jedec Write Leveling
+  UINT32 EWRTC2D : 1;    ///< BIT6 - Early Write Time Centering 2D
+  UINT32 ERDTC2D : 1;    ///< BIT7  - Early Read Time Centering 2D
+  UINT32 WRTC1D : 1;     ///< BIT8 - Write Timing Centering 1D
+  UINT32 WRVC1D : 1;     ///< BIT9 - Write Voltage Centering 1D
+  UINT32 RDTC1D : 1;     ///< BIT10 - Read Timing Centering 1D
+  UINT32 DIMMODTT : 1;   ///< BIT11 - Dimm ODT Training
+  UINT32 DIMMRONT : 1;   ///< BIT12 - Dimm Ron Training
+  UINT32 WRDSEQT : 1;    ///< BIT13 - Write Drive Strength / Equalization Training 2D
+  UINT32 WRSRT : 1;      ///< BIT14 - Write Slew Rate Training
+  UINT32 RDODTT : 1;     ///< BIT15 - Read ODT Training
+  UINT32 RDEQT : 1;      ///< BIT16 - Read Equalization Training
+  UINT32 RDAPT : 1;      ///< BIT17 - Read Amplifier Power Training
+  UINT32 WRTC2D : 1;     ///< BIT18 - Write Timing Centering 2D
+  UINT32 RDTC2D : 1;     ///< BIT19 - Read Timing Centering 2D
+  UINT32 WRVC2D : 1;     ///< BIT20 - Write Voltage Centering 2D
+  UINT32 RDVC2D : 1;     ///< BIT21 - Read Voltage Centering 2D
+  UINT32 CMDVC : 1;      ///< BIT22 - Command Voltage Centering
+  UINT32 LCT : 1;        ///< BIT23 - Late Command Training
+  UINT32 RTL : 1;        ///< BIT24 - Round Trip latency
+  UINT32 TAT : 1;        ///< BIT25 - Turn Around Timing
+  UINT32 RMT : 1;        ///< BIT26 - RMT Tool
+  UINT32 MEMTST : 1;     ///< BIT27 - Memory Test
+  UINT32 ALIASCHK: 1;    ///< BIT28 - SPD Alias Check
+  UINT32 RCVENC1D: 1;    ///< BIT29 - Receive Enable Centering 1D
+  UINT32 RMC : 1;        ///< BIT30 - Retrain Margin Check
+  UINT32 WRDSUDT : 1;    ///< BIT31 - Write Drive Strength Up/Dn independently
+} TrainingStepsEn;
+
+typedef struct {
+  UINT32 CMDSR    : 1;   ///< BIT0  - CMD Slew Rate Training
+  UINT32 CMDDSEQ  : 1;   ///< BIT1  - CMD Drive Strength and Tx Equalization
+  UINT32 CMDNORM  : 1;   ///< BIT2  - CMD Normalization
+  UINT32 EWRDSEQ  : 1;   ///< BIT3  - Early DQ Write Drive Strength and Equalization Training
+  UINT32 TeRsv4   : 1;   ///< BIT4 - Reserved
+  UINT32 TeRsv5   : 1;   ///< BIT5 - Reserved
+  UINT32 TeRsv6   : 1;   ///< BIT6 - Reserved
+  UINT32 RsvdBits :25;
+} TrainingStepsEn2;
+
+///
+/// Defines whether the MRC is executing in full or mini BIOS mode.
+///
+typedef enum {
+  MrcModeFull,   ///< Select full BIOS MRC execution.
+  MrcModeMini,   ///< Select mini BIOS MRC execution.
+  MrcModeMaximum ///< Delimiter.
+} MrcMode;
+
+typedef enum {
+  MrcTmPower,
+  MrcTmMargin,
+  MrcTmMax
+} TrainingModeType;
+
+typedef enum {
+  LastRxV,
+  LastRxT,
+  LastTxV,
+  LastTxT,
+  LastRcvEna,
+  LastWrLevel,
+  LastCmdT,
+  LastCmdV,
+  MAX_RESULT_TYPE
+} MrcMarginResult;
+
+typedef enum {
+  MSG_LEVEL_NEVER,
+  MSG_LEVEL_ERROR,
+  MSG_LEVEL_WARNING,
+  MSG_LEVEL_NOTE,
+  MSG_LEVEL_EVENT,
+  MSG_LEVEL_ALGO,
+  MSG_LEVEL_MMIO,
+  MSG_LEVEL_CSV,
+  MSG_LEVEL_TIME,
+  MSG_LEVEL_ALL = MRC_INT32_MAX
+} MrcDebugMsgLevel;
+
+///
+/// Define the frequencies that may be possible in the memory controller.
+/// Note that not all these values may be supported.
+///
+#define fNoInit     (0)
+#define f800        (800)
+#define f1000       (1000)
+#define f1100       (1100)
+#define f1067       (1067)
+#define f1200       (1200)
+#define f1300       (1300)
+#define f1333       (1333)
+#define f1400       (1400)
+#define f1467       (1467)
+#define f1500       (1500)
+#define f1600       (1600)
+#define f1700       (1700)
+#define f1733       (1733)
+#define f1800       (1800)
+#define f1867       (1867)
+#define f1900       (1900)
+#define f2000       (2000)
+#define f2100       (2100)
+#define f2133       (2133)
+#define f2200       (2200)
+#define f2267       (2267)
+#define f2300       (2300)
+#define f2400       (2400)
+#define f2500       (2500)
+#define f2533       (2533)
+#define f2600       (2600)
+#define f2667       (2667)
+#define f2700       (2700)
+#define f2800       (2800)
+#define f2900       (2900)
+#define f2933       (2933)
+#define f3000       (3000)
+#define f3067       (3067)
+#define f3100       (3100)
+#define f3200       (3200)
+#define f3333       (3333)
+#define f3467       (3467)
+#define f3600       (3600)
+#define f3733       (3733)
+#define f3867       (3867)
+#define f4000       (4000)
+#define f4133       (4133)
+#define fInvalid    (0x7FFFFFFF)
+typedef UINT32 MrcFrequency;
+
+//
+// Max supported frequency in OC mode
+// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
+// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
+//
+#define MAX_FREQ_OC_133   f4133
+#define MAX_FREQ_OC_100   f3100
+
+//
+// tCK value in femtoseconds for various frequencies
+// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
+//
+#define MRC_DDR_800_TCK_MIN      2500000
+#define MRC_DDR_1000_TCK_MIN     2000000
+#define MRC_DDR_1067_TCK_MIN     1875000
+#define MRC_DDR_1100_TCK_MIN     1818182
+#define MRC_DDR_1200_TCK_MIN     1666667
+#define MRC_DDR_1300_TCK_MIN     1538462
+#define MRC_DDR_1333_TCK_MIN     1500000
+#define MRC_DDR_1400_TCK_MIN     1428571
+#define MRC_DDR_1467_TCK_MIN     1363636
+#define MRC_DDR_1500_TCK_MIN     1333333
+#define MRC_DDR_1600_TCK_MIN     1250000
+#define MRC_DDR_1700_TCK_MIN     1176471
+#define MRC_DDR_1733_TCK_MIN     1153846
+#define MRC_DDR_1800_TCK_MIN     1111111
+#define MRC_DDR_1867_TCK_MIN     1071429
+#define MRC_DDR_1900_TCK_MIN     1052632
+#define MRC_DDR_2000_TCK_MIN     1000000
+#define MRC_DDR_2100_TCK_MIN     952381
+#define MRC_DDR_2133_TCK_MIN     938000
+#define MRC_DDR_2200_TCK_MIN     909091
+#define MRC_DDR_2267_TCK_MIN     882353
+#define MRC_DDR_2300_TCK_MIN     869565
+#define MRC_DDR_2400_TCK_MIN     833333
+#define MRC_DDR_2500_TCK_MIN     800000
+#define MRC_DDR_2533_TCK_MIN     789474
+#define MRC_DDR_2600_TCK_MIN     769231
+#define MRC_DDR_2667_TCK_MIN     750000
+#define MRC_DDR_2700_TCK_MIN     740741
+#define MRC_DDR_2800_TCK_MIN     714286
+#define MRC_DDR_2900_TCK_MIN     689655
+#define MRC_DDR_2933_TCK_MIN     681818
+#define MRC_DDR_3000_TCK_MIN     666667
+#define MRC_DDR_3067_TCK_MIN     652174
+#define MRC_DDR_3100_TCK_MIN     645161
+#define MRC_DDR_3200_TCK_MIN     625000
+#define MRC_DDR_3333_TCK_MIN     600000
+#define MRC_DDR_3467_TCK_MIN     576923
+#define MRC_DDR_3600_TCK_MIN     555556
+#define MRC_DDR_3733_TCK_MIN     535714
+#define MRC_DDR_3867_TCK_MIN     517241
+#define MRC_DDR_4000_TCK_MIN     500000
+#define MRC_DDR_4133_TCK_MIN     483871
+
+///
+/// Define the memory nominal voltage (VDD).
+/// Note that not all these values may be supported.
+///
+typedef enum {
+  VDD_INVALID,
+  VDD_1_00    = 1000,
+  VDD_1_05    = 1050,
+  VDD_1_10    = 1100,
+  VDD_1_15    = 1150,
+  VDD_1_20    = 1200,
+  VDD_1_25    = 1250,
+  VDD_1_30    = 1300,
+  VDD_1_35    = 1350,
+  VDD_1_40    = 1400,
+  VDD_1_45    = 1450,
+  VDD_1_50    = 1500,
+  VDD_1_55    = 1550,
+  VDD_1_60    = 1600,
+  VDD_1_65    = 1650,
+  VDD_1_70    = 1700,
+  VDD_1_75    = 1750,
+  VDD_1_80    = 1800,
+  VDD_1_85    = 1850,
+  VDD_1_90    = 1900,
+  VDD_1_95    = 1950,
+  VDD_2_00    = 2000,
+  VDD_2_05    = 2050,
+  VDD_2_10    = 2100,
+  VDD_2_15    = 2150,
+  VDD_2_20    = 2200,
+  VDD_2_25    = 2250,
+  VDD_2_30    = 2300,
+  VDD_2_35    = 2350,
+  VDD_2_40    = 2400,
+  VDD_2_45    = 2450,
+  VDD_2_50    = 2500,
+  VDD_2_55    = 2550,
+  VDD_2_60    = 2600,
+  VDD_2_65    = 2650,
+  VDD_2_70    = 2700,
+  VDD_2_75    = 2750,
+  VDD_2_80    = 2800,
+  VDD_2_85    = 2850,
+  VDD_2_90    = 2900,
+  VDD_2_95    = 2950,
+  VDD_MAXIMUM = 0x7FFFFFFF
+} MrcVddSelect;
+
+///
+/// SA GV points
+///
+typedef enum {
+  MrcSaGvPointLow,
+  MrcSaGvPointHigh,
+} MrcSaGvPoint;
+
+///
+/// SA GV modes
+///  Disabled:  SA GV Disabled, run all MRC tasks
+///  FixedLow:  SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_LOW
+///  FixedHigh: SA GV Disabled, run only MRC tasks marked with MRC_PF_GV_HIGH
+///  Enabled:   SA GV Enabled
+///
+typedef enum {
+  MrcSaGvDisabled,
+  MrcSaGvFixedLow,
+  MrcSaGvFixedHigh,
+  MrcSaGvEnabled,
+} MrcSaGv;
+
+///
+/// DIMM SPD Security Status
+///
+typedef enum {
+  MrcSpdStatusGood,      ///< Memory is in a secure state.
+  MrcSpdStatusAliased,   ///< Memory is aliased.
+  MrcSpdStatusLast       ///< Must be last in the list
+} MrcSpdStatus;
+
+///
+/// Define the virtual channel.
+///
+typedef enum {
+  vcL,  ///< Virtual channel L
+  vcS,  ///< Virtual channel S
+} MrcVirtualChannel;
+
+///
+/// Define the board types.
+///
+typedef enum {
+  btCRBMB,    ///< 0 - CRB Mobile
+  btCRBDT,    ///< 1 - CRB Desktop
+  btUser1,    ///< 2 - SV Karkom
+  btUser2,    ///< 3 - SV desktop
+  btUser3,    ///< 4 - SV miniDVP
+  btUser4,    ///< 5 - Ult
+  btCRBEMB,   ///< 6 - CRB Embedded
+  btUpServer, ///< 7 - Up Server
+  btUnknown,  ///< 8 - Unknown
+  btMaximum   ///< Delimiter
+} MrcBoardType;
+
+///
+/// Define the CPU family/model.
+///
+typedef enum {
+  cmCFL_ULX_ULT   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,  ///< Coffeelake ULT/ULX
+  cmCFL_DT_HALO   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO   ///< Coffeelake DT/Halo
+} MrcCpuModel;
+
+///
+/// Define the CPU Tick/Tock.
+///
+typedef enum {
+  cfCfl    = 0,  ///< Coffeelake
+  cfMax
+} MrcCpuFamily;
+
+///
+/// Define the CPU stepping number.
+///
+typedef enum {
+  ///
+  /// Coffeelake ULX/ULT
+  ///
+  csKblH0         = EnumKblH0,
+  csCflD0         = EnumCflD0,
+  csCflW0         = EnumCflW0,
+  csCflV0         = EnumCflV0,
+  csCflUlxUltLast = csCflV0,
+
+  ///
+  /// Coffeelake DT/Halo
+  ///
+  csCflU0         = EnumCflU0,
+  csCflB0         = EnumCflB0,
+  csCflP0         = EnumCflP0,
+  csCflR0         = EnumCflR0,
+  csCflDtHaloLast = csCflR0,
+} MrcCpuStepping;
+
+typedef enum {
+  CONTROLLER_NOT_PRESENT, ///< There is no controller present in the system.
+  CONTROLLER_DISABLED,    ///< There is a controller present but it is disabled.
+  CONTROLLER_PRESENT,     ///< There is a controller present and it is enabled.
+  MAX_CONTROLLER_STATUS   ///< Delimiter
+} MrcControllerSts;
+
+typedef enum {
+  CHANNEL_NOT_PRESENT,    ///< There is no channel present on the controller.
+  CHANNEL_DISABLED,       ///< There is a channel present but it is disabled.
+  CHANNEL_PRESENT,        ///< There is a channel present and it is enabled.
+  MAX_CHANNEL_STATUS      ///< Delimiter
+} MrcChannelSts;
+
+typedef enum {
+  DIMM_ENABLED,           ///< DIMM/rank Pair is enabled, presence will be detected.
+  DIMM_DISABLED,          ///< DIMM/rank Pair is disabled, regardless of presence.
+  DIMM_PRESENT,           ///< There is a DIMM present in the slot/rank pair and it will be used.
+  DIMM_NOT_PRESENT,       ///< There is no DIMM present in the slot/rank pair.
+  MAX_DIMM_STATUS         ///< Delimiter
+} MrcDimmSts;
+
+typedef enum {
+  STD_PROFILE,            ///< Standard DIMM profile select.
+  USER_PROFILE,           ///< User specifies various override values.
+  XMP_PROFILE1,           ///< XMP enthusiast settings select (XMP profile #1).
+  XMP_PROFILE2,           ///< XMP extreme settings select (XMP profile #2).
+  MAX_PROFILE             ///< Delimiter
+} MrcProfile;
+
+#define XMP_PROFILES_ENABLE   (0x3)
+#define XMP1_PROFILE_ENABLE   (0x1)
+#define XMP2_PROFILE_ENABLE   (0x2)
+
+typedef enum {
+  MRC_REF_CLOCK_133,      ///< 133MHz reference clock
+  MRC_REF_CLOCK_100,      ///< 100MHz reference clock
+  MRC_REF_CLOCK_MAXIMUM   ///< Delimiter
+} MrcRefClkSelect;        ///< This value times the MrcClockRatio determines the MrcFrequency.
+
+typedef enum {
+  MRC_FREQ_INVALID       = 0,
+  MRC_FREQ_133           = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
+  MRC_FREQ_100           = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
+  MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit 2
+  MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit 3
+  MRC_FREQ_MAX                                              // Delimiter
+} MrcFreqFlag;
+
+typedef UINT32 MrcBClkRef;   ///< Base clock, in Hertz, Default is 100MHz or leave at zero for default.
+
+//
+// This encoding matches CFL SC_GS_CFG.DRAM_technology and MAD_INTER_CHANNEL.DDR_TYPE registers
+//
+typedef enum {
+  MRC_DDR_TYPE_DDR4     = 0,
+  MRC_DDR_TYPE_DDR3     = 1,
+  MRC_DDR_TYPE_LPDDR3   = 2,
+  MRC_DDR_TYPE_UNKNOWN  = 3,
+  MAX_MRC_DDR_TYPE        ///< Delimiter
+} MrcDdrType;
+
+typedef enum {
+  MrcIterationClock,
+  MrcIterationCmdN,
+  MrcIterationCmdS,
+  MrcIterationCke,
+  MrcIterationCtl,
+  MrcIterationCmdV,
+  MrcIterationMax
+} MrcIterationType;
+
+typedef enum {
+  UpmLimit,
+  PowerLimit,
+  RetrainLimit,
+  MarginLimitMax
+} MRC_MARGIN_LIMIT_TYPE;
+
+
+typedef enum {
+  HardwareRhp,
+  Refresh2x
+} MrcRhpType;
+
+typedef enum {
+  OneIn2To1 = 1,
+  OneIn2To2,
+  OneIn2To3,
+  OneIn2To4,
+  OneIn2To5,
+  OneIn2To6,
+  OneIn2To7,
+  OneIn2To8,
+  OneIn2To9,
+  OneIn2To10,
+  OneIn2To11,
+  OneIn2To12,
+  OneIn2To13,
+  OneIn2To14,
+  OneIn2To15
+} MrcRhProbType;
+
+typedef enum {
+  MRC_POST_CODE,
+  MRC_POST_CODE_WRITE,
+  MRC_POST_CODE_READ,
+  MRC_POST_CODE_MAX
+} MrcDebugPostCode;
+
+typedef struct {
+  UINT32 MrcData;
+  UINT32 Stream;
+  UINT32 Start;
+  UINT32 End;
+  UINT32 Current;
+  int Level;
+  UINT16 PostCode[MRC_POST_CODE_MAX];
+  UINT32 TopStackAddr;     ///< Initial stack address.
+  UINT32 LowestStackAddr;  ///< Track the lowest stack address used through MrcPrintfVaList()
+} MrcDebug;
+
+typedef UINT16 MrcPostCode;
+typedef UINT8  MrcClockRatio;  ///< This value times the MrcRefClkSelect determines the MrcFrequency.
+typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data memory, in MBytes.
+typedef UINT32 MrcGfxGttSize;  ///< The size of the graphics translation table, in MBytes.
+
+
+///
+/// This data structure contains all the "DDR power saving data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  BOOLEAN    BaseFlag;      ///< Indicates if the base line of power was already calculated.
+  UINT16     BaseSavingRd;  ///< Indicates the base line of power consume by the ddr on read.
+  UINT16     BaseSavingWr;  ///< Indicates the base line of power consume by the ddr on write.
+  UINT16     BaseSavingCmd; ///< Indicates the base line of power consume by the ddr on command.
+  UINT16     MrcSavingRd;   ///< Indicates the power consume by the ddr on read at the end of MRC.
+  UINT16     MrcSavingWr;   ///< Indicates the power consume by the ddr on write at the end of MRC.
+  UINT16     MrcSavingCmd;  ///< Indicates the power consume by the ddr on command at the end of MRC.
+} MrcOdtPowerSaving;
+
+///
+/// The memory controller capabilities.
+///
+typedef union {
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} MrcCapabilityIdA;
+
+typedef union {
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} MrcCapabilityIdB;
+
+typedef union {
+  UINT64 Data;
+  struct {
+    MrcCapabilityIdA A;
+    MrcCapabilityIdB B;
+  } Data32;
+} MrcCapabilityId;
+
+///
+/// MRC version description.
+///
+typedef struct {
+  UINT8  Major;  ///< Major version number
+  UINT8  Minor;  ///< Minor version number
+  UINT8  Rev;    ///< Revision number
+  UINT8  Build;  ///< Build number
+} MrcVersion;
+
+///
+/// Memory map configuration information.
+///
+typedef struct {
+  UINT32     TomMinusMe;
+  UINT32     ToludBase;
+  UINT32     BdsmBase;
+  UINT32     GttBase;
+  UINT32     GraphicsControlRegister;
+  UINT32     TsegBase;
+  BOOLEAN    ReclaimEnable;
+  UINT32     RemapBase;
+  UINT32     RemapLimit;
+  UINT32     TouudBase;
+  UINT32     TotalPhysicalMemorySize;
+  UINT32     MeStolenBase;
+  UINT32     MeStolenSize;
+  UINT32     GdxcMotBase;
+  UINT32     GdxcMotSize;
+  UINT32     GdxcIotBase;
+  UINT32     GdxcIotSize;
+  UINT32     DprSize;
+  UINT32     PttStolenBase;
+  UINT32     PrmrrBase;
+  UINT32     LowestBase;
+} MrcMemoryMap;
+
+///
+/// Real time clock information.
+///
+typedef struct {
+  UINT8  Seconds;    ///< Seconds, 0-59
+  UINT8  Minutes;    ///< Minutes, 0-59
+  UINT8  Hours;      ///< Hours, 0-23
+  UINT8  DayOfMonth; ///< Day of the month, 1-31
+  UINT8  Month;      ///< Month of the year, 1-12
+  UINT16 Year;       ///< Year, 0-65535
+} MrcBaseTime;
+
+///
+/// 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.
+} MrcTiming;
+
+typedef struct {
+  UINT8 SG;       ///< Number of tCK cycles between transactions in the same bank group.
+  UINT8 DG;       ///< Number of tCK cycles between transactions when switching bank groups.
+  UINT8 DR;       ///< Number of tCK cycles between transactions when switching between Ranks (in the same DIMM).
+  UINT8 DD;       ///< Number of tCK cycles between transactions when switching between DIMMs
+} MrcTurnaroundTimes;
+
+typedef struct {
+  INT32 Mtb;    ///< Medium time base.
+  INT32 Ftb;    ///< Fine time base.
+} MrcTimeBase;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the timing eye.
+  UINT8  Center; ///< The center of the timing eye.
+  UINT8  Right;  ///< The right side of the timing eye.
+} MrcDqTimeMargin;
+
+typedef struct {
+  UINT8  High;   ///< The high side of the Vref eye.
+  UINT8  Center; ///< The center of the Vref eye.
+  UINT8  Low;    ///< The low side of the Vref eye.
+} MrcDqVrefMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the command eye.
+  UINT8  Right;  ///< The right side of the command eye.
+  UINT8  High;   ///< The high side of the command eye.
+  UINT8  Low;    ///< The low side of the command eye.
+} MrcCommandMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the receive enable eye.
+  UINT8  Right;  ///< The right side of the receive enableeye.
+} MrcRecvEnMargin;
+
+typedef struct {
+  UINT8  Left;   ///< The left side of the write leveling eye.
+  UINT8  Right;  ///< The right side of the write leveling eye.
+} MrcWrLevelMargin;
+
+typedef struct {
+  UINT8     SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///< Each valid bit maps to SPD byte.
+  UINT8     MrcSpdString[3]; ///< The SPD data start marker. This must be located at the start of the SPD data structure. It includes this string plus the following flag.
+  union {
+    struct {
+      UINT8   DimmNumber    : 4; ///< SPD zero based DIMM number.
+      UINT8   ChannelNumber : 3; ///< SPD zero based channel number.
+      UINT8   MdSocket      : 1; ///< 0 = memory down, 1 = socketed.
+    } Bit;
+    UINT8 Data;
+  } Flag;
+  MrcSpd Data;            ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+} MrcSpdData;
+
+typedef UINT8        (*MRC_IO_READ_8)               (UINT32 IoAddress);
+typedef UINT16       (*MRC_IO_READ_16)              (UINT32 IoAddress);
+typedef UINT32       (*MRC_IO_READ_32)              (UINT32 IoAddress);
+typedef void         (*MRC_IO_WRITE_8)              (UINT32 IoAddress, UINT8 Value);
+typedef void         (*MRC_IO_WRITE_16)             (UINT32 IoAddress, UINT16 Value);
+typedef void         (*MRC_IO_WRITE_32)             (UINT32 IoAddress, UINT32 Value);
+typedef UINT8        (*MRC_MMIO_READ_8)             (UINT32 Address);
+typedef UINT16       (*MRC_MMIO_READ_16)            (UINT32 Address);
+typedef UINT32       (*MRC_MMIO_READ_32)            (UINT32 Address);
+typedef UINT64       (*MRC_MMIO_READ_64)            (UINT32 Address);
+typedef UINT8        (*MRC_MMIO_WRITE_8)            (UINT32 Address, UINT8 Value);
+typedef UINT16       (*MRC_MMIO_WRITE_16)           (UINT32 Address, UINT16 Value);
+typedef UINT32       (*MRC_MMIO_WRITE_32)           (UINT32 Address, UINT32 Value);
+typedef UINT64       (*MRC_MMIO_WRITE_64)           (UINT32 Address, UINT64 Value);
+typedef UINT8        (*MRC_SMBUS_READ_8)            (UINT32 Address, UINT32 *Status);
+typedef UINT16       (*MRC_SMBUS_READ_16)           (UINT32 Address, UINT32 *Status);
+typedef UINT8        (*MRC_SMBUS_WRITE_8)           (UINT32 Address, UINT8 Value, UINT32 *Status);
+typedef UINT16       (*MRC_SMBUS_WRITE_16)          (UINT32 Address, UINT16 Value, UINT32 *Status);
+typedef UINT32       (*MRC_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef UINT32       (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);
+typedef void         (*MRC_GET_RTC_TIME)            (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
+typedef UINT64       (*MRC_GET_CPU_TIME)            (void *MrcData);
+typedef void *       (*MRC_MEMORY_COPY)             (UINT8 *Destination, UINT8 *Source, UINT32 NumBytes);
+typedef void *       (*MRC_MEMORY_SET_BYTE)         (UINT8 *Destination, UINT32 NumBytes, UINT8 Value);
+typedef void *       (*MRC_MEMORY_SET_WORD)         (UINT16 *Destination, UINT32 NumWords, UINT16 Value);
+typedef void *       (*MRC_MEMORY_SET_DWORD)        (UINT32 *Destination, UINT32 NumDwords, UINT32 Value);
+typedef UINT64       (*MRC_LEFT_SHIFT_64)           (UINT64 Data, UINT32 NumBits);
+typedef UINT64       (*MRC_RIGHT_SHIFT_64)          (UINT64 Data, UINT32 NumBits);
+typedef UINT64       (*MRC_MULT_U64_U32)            (UINT64 Multiplicand, UINT32 Multiplier);
+typedef UINT64       (*MRC_DIV_U64_U64)             (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);
+typedef BOOLEAN      (*MRC_GET_SPD_DATA)            (UINT8 BootMode, UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize, UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32 LpddrTableSize);
+typedef BOOLEAN      (*MRC_GET_RANDOM_NUMBER)       (UINT32 *Rand);
+typedef UINT32       (*MRC_CPU_MAILBOX_READ)        (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);
+typedef UINT32       (*MRC_CPU_MAILBOX_WRITE)       (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);
+typedef UINT32       (*MRC_GET_MEMORY_VDD)          (void *MrcData, UINT32 DefaultVdd);
+typedef UINT32       (*MRC_SET_MEMORY_VDD)          (void *MrcData, UINT32 DefaultVdd, UINT32 Value);
+typedef UINT32       (*MRC_CHECKPOINT)              (void *MrcData, UINT32 CheckPoint, void *Scratch);
+typedef void         (*MRC_DEBUG_HOOK)              (void *GlobalData, UINT16 DisplayDebugNumber);
+typedef void         (*MRC_PRINT_STRING)            (void *String);
+typedef UINT8        (*MRC_GET_RTC_CMOS)            (UINT8 Location);
+typedef UINT64       (*MRC_MSR_READ_64)             (UINT32 Location);
+typedef UINT64       (*MRC_MSR_WRITE_64)            (UINT32 Location, UINT64 Data);
+typedef void         (*MRC_RETURN_FROM_SMC)         (void *GlobalData, UINT32 MrcStatus);
+typedef void         (*MRC_DRAM_RESET)              (UINT32 PciEBaseAddress, UINT32 ResetValue);
+typedef void         (*MRC_SET_LOCK_PRMRR)          (UINT32 PrmrrBase, UINT32 PrmrrSize);
+typedef void         (*MRC_TXT_ACHECK)              (void);
+
+///
+/// Function calls that are called external to the MRC.
+///   This structure needs to be aligned with SA_FUNCTION_CALLS.  All functions that are
+///   not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
+///
+typedef struct {
+  MRC_IO_READ_8               MrcIoRead8;
+  MRC_IO_READ_16              MrcIoRead16;
+  MRC_IO_READ_32              MrcIoRead32;
+  MRC_IO_WRITE_8              MrcIoWrite8;
+  MRC_IO_WRITE_16             MrcIoWrite16;
+  MRC_IO_WRITE_32             MrcIoWrite32;
+  MRC_MMIO_READ_8             MrcMmioRead8;
+  MRC_MMIO_READ_16            MrcMmioRead16;
+  MRC_MMIO_READ_32            MrcMmioRead32;
+  MRC_MMIO_READ_64            MrcMmioRead64;
+  MRC_MMIO_WRITE_8            MrcMmioWrite8;
+  MRC_MMIO_WRITE_16           MrcMmioWrite16;
+  MRC_MMIO_WRITE_32           MrcMmioWrite32;
+  MRC_MMIO_WRITE_64           MrcMmioWrite64;
+  MRC_SMBUS_READ_8            MrcSmbusRead8;
+  MRC_SMBUS_READ_16           MrcSmbusRead16;
+  MRC_SMBUS_WRITE_8           MrcSmbusWrite8;
+  MRC_SMBUS_WRITE_16          MrcSmbusWrite16;
+  MRC_GET_PCI_DEVICE_ADDRESS  MrcGetPciDeviceAddress;
+  MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
+  MRC_GET_RTC_TIME            MrcGetRtcTime;
+  MRC_GET_CPU_TIME            MrcGetCpuTime;
+  MRC_MEMORY_COPY             MrcCopyMem;
+  MRC_MEMORY_SET_BYTE         MrcSetMem;
+  MRC_MEMORY_SET_WORD         MrcSetMemWord;
+  MRC_MEMORY_SET_DWORD        MrcSetMemDword;
+  MRC_LEFT_SHIFT_64           MrcLeftShift64;
+  MRC_RIGHT_SHIFT_64          MrcRightShift64;
+  MRC_MULT_U64_U32            MrcMultU64x32;
+  MRC_DIV_U64_U64             MrcDivU64x64;
+  MRC_GET_SPD_DATA            MrcGetSpdData;
+  MRC_GET_RANDOM_NUMBER       MrcGetRandomNumber;
+  MRC_CPU_MAILBOX_READ        MrcCpuMailboxRead;
+  MRC_CPU_MAILBOX_WRITE       MrcCpuMailboxWrite;
+  MRC_GET_MEMORY_VDD          MrcGetMemoryVdd;
+  MRC_SET_MEMORY_VDD          MrcSetMemoryVdd;
+  MRC_CHECKPOINT              MrcCheckpoint;
+  MRC_DEBUG_HOOK              MrcDebugHook;
+  MRC_PRINT_STRING            MrcPrintString;
+  MRC_GET_RTC_CMOS            MrcRtcCmos;
+  MRC_MSR_READ_64             MrcReadMsr64;
+  MRC_MSR_WRITE_64            MrcWriteMsr64;
+  MRC_RETURN_FROM_SMC         MrcReturnFromSmc;
+  MRC_DRAM_RESET              MrcDramReset;
+  MRC_SET_LOCK_PRMRR          MrcSetLockPrmrr;
+  MRC_TXT_ACHECK              MrcTxtAcheck;
+} MRC_FUNCTION;
+
+///
+///*****************************************
+/// Output related "global data" structures.
+///*****************************************
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+} MrcSdramOut;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+//MrcSdramOut     Sdram[MAX_SDRAM_IN_DIMM];         ///< The following are SDRAM level definitions.
+  UINT16             MR[MAX_MR_IN_DIMM];            ///< DRAM mode register value.
+  UINT16             MR11;                          ///< LPDDR3 ODT MR
+  UINT8              Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0] for per-DRAM VrefDQ (PDA)
+#if (SUPPORT_DDR4 == SUPPORT)
+  UINT8              Device[MAX_SDRAM_IN_DIMM];     ///< Which Bytes are tied to which Device where BIT0 set means Byte 0
+#endif //SUPPORT_DDR4
+} MrcRankOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+  MrcDimmSts     Status;                    ///< See MrcDimmSts for the definition of this field.
+  MrcTiming      Timing[MAX_PROFILE];       ///< The DIMMs timing values.
+  MrcVddSelect   VddVoltage[MAX_PROFILE];   ///< The voltage (VDD) setting for this DIMM, per profile.
+  BOOLEAN        EccSupport;                ///< TRUE if ECC is enabled and supported on this DIMM.
+  BOOLEAN        IgnoreNonEccDimm;          ///< TRUE if a DIMM without ECC capability should be ignored.
+  BOOLEAN        AddressMirrored;           ///< TRUE if the DIMM is address mirrored.
+  BOOLEAN        SelfRefreshTemp;           ///< TRUE if the DIMM supports self refresh extended operating temperature range (SRT).
+  BOOLEAN        AutoSelfRefresh;           ///< TRUE if the DIMM supports automatic self refresh (ASR).
+  BOOLEAN        PartialSelfRefresh;        ///< TRUE if the DIMM supports Partial Array Self Refresh (PASR).
+  BOOLEAN        OnDieThermalSensor;        ///< TRUE if the DIMM supports On-die Thermal Sensor (ODTS) Readout.
+  BOOLEAN        ExtendedTemperRange;       ///< TRUE if the DIMM supports Extended Temperature Range (ETR).
+  BOOLEAN        ExtendedTemperRefresh;     ///< TRUE if the DIMM supports 1x Extended Temperature Refresh rate, FALSE = 2x.
+  MrcDdrType     DdrType;                   ///< DDR type: DDR3 or LPDDR3
+  MEMORY_PACKAGE ModuleType;                ///< Module type: UDIMM, SO-DIMM, etc.
+  UINT32         SdramCount;                ///< The number of SDRAM components on a DIMM.
+  UINT32         DimmCapacity;              ///< DIMM size in MBytes.
+  UINT32         RowSize;                   ///< The DIMMs row address size.
+  UINT16         ColumnSize;                ///< The DIMMs column address size.
+  UINT16         Crc;                       ///< Calculated CRC16 of the DIMM's provided SPD. Can be used to detect DIMM change.
+  UINT8          RankInDimm;                ///< The number of ranks in this DIMM.
+  UINT8          Banks;                     ///< Number of banks the DIMM contains.
+  UINT8          BankGroups;                ///< Number of bank groups the DIMM contains.
+  UINT8          PrimaryBusWidth;           ///< DIMM primary bus width.
+  UINT8          SdramWidth;                ///< DIMM SDRAM width.
+  UINT8          SdramWidthIndex;           ///< DIMM SDRAM width index (0 = x4, 1 = x8, 2 = x16, 3 = x32).
+  UINT8          DensityIndex;              ///< Total SDRAM capacity index (0 = 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
+  UINT8          tMAC;                      ///< Maximum Activate Count for pTRR.
+  UINT8          ReferenceRawCard;          ///< Indicates which JEDEC reference design raw card was used as the basis for the module assembly.
+  UINT8          ReferenceRawCardRevision;  ///< Indicates which JEDEC reference design raw card revision.
+  UINT8          XmpSupport;                ///< Indicates if XMP profiles are supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
+  UINT8          XmpRevision;               ///< Indicates the XMP revision of this DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
+  MrcFrequency   Speed;                     ///< Max DIMM speed in the current profile - needed for SMBIOS.
+  MrcRankOut     Rank[MAX_RANK_IN_DIMM];    ///< The following are rank level definitions.
+} MrcDimmOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+  MrcChannelSts       Status;                                                       ///< Indicates whether this channel should be used.
+  MrcVirtualChannel   VirtualChannel;                                               ///< define the virtual channel type A or B.
+  MrcTiming           Timing[MAX_PROFILE];                                          ///< The channel timing values.
+  MrcTimeBase         TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE];                  ///< Medium and fine timebases for each DIMM in the channel and each memory profile.
+  UINT32              Capacity;                                                     ///< Amount of memory in this channel, in MBytes.
+  UINT32              DimmCount;                                                    ///< Number of valid DIMMs that exist in the channel.
+  UINT32              DataOffsetTrain[MAX_SDRAM_IN_DIMM];                           ///< DataOffsetTrain CR
+  UINT32              DataCompOffset[MAX_SDRAM_IN_DIMM];                            ///< DataCompOffset CR
+  UINT32              CkeCmdPiCode[MAX_COMMAND_GROUPS];                             ///< CKE  CmdPiCode CR, per group
+  UINT32              CmdsCmdPiCode[MAX_COMMAND_GROUPS];                            ///< CmdS CmdPiCode CR, per group
+  UINT32              CmdnCmdPiCode[MAX_COMMAND_GROUPS];                            ///< CmdN CmdPiCode CR, per group
+  UINT16              TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///< TxDQS PI Code
+  UINT16              TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< TxDQ Pi Code
+  UINT16              RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///< RcvEn PI Code
+  UINT16              WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];              ///< WlDelay PI Code
+  UINT8               ClkPiCode[MAX_RANK_IN_CHANNEL];                               ///< Clk Pi Code
+  UINT8               CtlPiCode[MAX_RANK_IN_CHANNEL];                               ///< Ctl Pi Code
+  UINT8               CkePiCode[MAX_RANK_IN_CHANNEL];                               ///< Ctl Pi Code
+  UINT8               TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< TxEq setting
+  MrcCommandMargin    Command[MAX_RANK_IN_CHANNEL];                                 ///< Cmd setting
+  MrcDqTimeMargin     RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];     ///< Rx PerBit Pi Code
+  MrcDqTimeMargin     TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];     ///< Tx PerBit Pi Code
+  MrcDqVrefMargin     RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+  MrcDqVrefMargin     TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS]; ///< Rx PerBit Vref
+  MrcRecvEnMargin     ReceiveEnable[MAX_RANK_IN_CHANNEL];                           ///< Receive enable per rank
+  MrcWrLevelMargin    WriteLevel[MAX_RANK_IN_CHANNEL];                              ///< Write leveling per rank
+  UINT8               IoLatency[MAX_RANK_IN_CHANNEL];                               ///< IOLatency
+  UINT8               RTLatency[MAX_RANK_IN_CHANNEL];                               ///< RoundTripLatency
+  UINT32              RTIoComp;                                                     ///< RoundTrip IO Compensation of the Channel
+  UINT8               RxVref[MAX_SDRAM_IN_DIMM];                                    ///< RX Vref in steps of 7.9 mv
+  UINT8               RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///< RxEQ Setting
+  UINT8               RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///< RxDQSP PI Code
+  UINT8               RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///< RxDQSN PI Code
+  UINT8               ValidRankBitMask;                                             ///< Bit map of the populated ranks per channel
+  UINT8               ValidCkeBitMask;                                              ///< Bit map of the used CKE pins per channel
+  MrcDimmOut          Dimm[MAX_DIMMS_IN_CHANNEL];                                   ///< DIMM specific output variables.
+  MrcTurnaroundTimes  tRd2Rd;                                                       ///< The system's minimal delay timings for Read  command followed by Read  command.
+  MrcTurnaroundTimes  tRd2Wr;                                                       ///< The system's minimal delay timings for Read  command followed by Write command.
+  MrcTurnaroundTimes  tWr2Rd;                                                       ///< The system's minimal delay timings for Write command followed by Read  command.
+  MrcTurnaroundTimes  tWr2Wr;                                                       ///< The system's minimal delay timings for Write command followed by Write command.
+} MrcChannelOut;
+
+///
+/// This data structure contains all the "global data" values that are considered output by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  MrcControllerSts 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.
+  MrcChannelOut    Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerOut;
+
+///
+///********************************************
+/// Saved data related "global data" structures.
+///********************************************
+///
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are DIMM level definitions.
+///
+typedef struct {
+  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.
+} MrcDimmSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are channel level definitions.
+///
+typedef struct {
+  MrcChannelSts Status;                               ///< Indicates whether this channel should be used.
+  UINT32        DimmCount;                            ///< Number of valid DIMMs that exist in the channel.
+  UINT8         ValidRankBitMask;                     ///< Bit map of the populated ranks per channel
+  MrcTiming     Timing[MAX_PROFILE];                  ///< The channel timing values.
+  MrcDimmOut    Dimm[MAX_DIMMS_IN_CHANNEL];           ///< Save the DIMM output characteristics.
+  MrcDimmSave   DimmSave[MAX_DIMMS_IN_CHANNEL];       ///< Save SPD information needed for SMBIOS structure creation.
+} MrcChannelSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are controller level definitions.
+///
+typedef struct {
+  MrcControllerSts  Status;               ///< Indicates whether this controller should be used.
+  UINT8             ChannelCount;         ///< Number of valid channels that exist on the controller.
+  MrcChannelSave    Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcContSave;
+
+///
+/// This data structure contains all the "global data" values that are considered to be needed
+/// by the MRC between power state transitions (S0->S3->S0) and also fast and warm boot modes.
+/// The following are system level definitions.
+///
+typedef struct {
+  UINT32 Crc;                  ///< The CRC-32 of the data in this structure.
+} MrcSaveHeader;
+
+//
+// ------- IMPORTANT NOTE --------
+// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in MrcSaveRestore.c.
+// Update this define whenever you add/remove registers from this table.
+//
+#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (common)
+#define MRC_REGISTER_COUNT_SAGV   (1528 / sizeof (UINT32)) ///< The number of MC registers that need to be saved (per SA GV point)
+
+typedef struct {
+  MrcCapabilityId McCapId;                                   ///< The memory controller's capabilities.
+  UINT32          RegSaveCommon[MRC_REGISTER_COUNT_COMMON];  ///< The MC registers that are common to both SA GV points
+  UINT32          RegSaveLow[MRC_REGISTER_COUNT_SAGV];       ///< The MC registers for the Low SA GV point
+  UINT32          RegSaveHigh[MRC_REGISTER_COUNT_SAGV];      ///< The MC registers for the High SA GV point, or for SA GV Disabled case
+  UINT32          MeStolenSize;                              ///< The managebility engine memory size, in Mbyte units.
+  MrcCpuStepping  CpuStepping;                               ///< The last cold boot happended with this CPU stepping.
+  MrcCpuModel     CpuModel;                                  ///< The last cold boot happended with this CPU model.
+  MrcCpuFamily    CpuFamily;                                 ///< CPU is Coffeelake
+  MrcVersion      Version;                                   ///< The last cold boot happended with this MRC version.
+  UINT32          SaMemCfgCrc;                               ///< The CRC32 of the system agent memory configuration structure.
+  MrcContSave     Controller[MAX_CONTROLLERS];               ///< The following are controller level definitions.
+  MrcFrequency    FreqMax;                                   ///< The system's requested maximum frequency.
+  MrcFrequency    Frequency;                                 ///< The system's common memory controller frequency.
+  UINT32          MemoryClock;                               ///< The system's common memory controller clock, in femtoseconds.
+  BOOLEAN         OddRatioModeLow;                           ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV Low point.
+  BOOLEAN         OddRatioModeHigh;                          ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for SAGV High point, or SAGV disabled / fixed high / fixed low
+  MrcRefClkSelect RefClk;                                    ///< The memory controller is going to use this reference clock.
+  MrcClockRatio   Ratio;                                     ///< Request for this memory controller to use this clock ratio.
+  MrcVddSelect    VddVoltage[MAX_PROFILE];                   ///< The voltage (VDD) setting for all DIMMs in the system, per profile.
+  BOOLEAN         EccSupport;                                ///< TRUE if ECC is enabled and supported on this controller.
+  MrcDdrType      DdrType;                                   ///< DDR type: DDR3, DDR4, or LPDDR3
+  UINT32          DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The Default XMP tCK values read from SPD.
+  UINT8           XmpProfileEnable;                          ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  BOOLEAN         BinnedLpddrDevices;                        ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+  BOOLEAN         TCRSensitiveHynixDDR4;                     ///< TCR sensitive Hynix DDR4 in the system
+  BOOLEAN         TCRSensitiveMicronDDR4;                    ///< TCR sensitive Micron DDR4 in the system
+  BOOLEAN         LpddrEctDone;                       ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+  UINT8           BerEnable;                          ///< BER Enable (and # of Addresses)
+  UINT64          BerAddress[4];                      ///< BER Addresses
+  BOOLEAN         DmfcLimitedBoard;                   ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+  BOOLEAN         DmfcLimited;                        ///< Indicates if the system has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
+  BOOLEAN         MixedUDimmConfig2Dpc;               ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+  BOOLEAN         ExtendedDdrOverclock;               ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+} MrcSaveData;
+
+typedef struct {
+  UINT32              Size;                        ///< The size of this structure, in bytes. Must be the first entry in this structure.
+  MrcDebug            Debug;                       ///< MRC debug related variables used for serial output and debugging purposes.
+  MrcVersion          Version;                     ///< The memory reference code version.
+  MrcFrequency        FreqMax;                     ///< The requested maximum valid frequency.
+  MrcFrequency        Frequency;                   ///< The system's common memory controller frequency.
+  UINT32              MemoryClockMax;              ///< The system's common memory controller maximum clock, in femtoseconds.
+  UINT32              MemoryClock;                 ///< The system's common memory controller clock, in femtoseconds.
+  MrcRefClkSelect     RefClk;                      ///< The memory controller is going to use this reference clock.
+  MrcClockRatio       Ratio;                       ///< Request for this memory controller to use this clock ratio.
+  MrcMemoryMap        MemoryMapData;               ///< The system's memory map data.
+  MrcGfxDataSize      GraphicsStolenSize;          ///< Graphics Data Stolen Memory size in MB
+  MrcGfxGttSize       GraphicsGttSize;             ///< GTT graphics stolen memory size in MB
+  MrcVddSelect        VddVoltage[MAX_PROFILE];     ///< The currently running voltage (VDD) setting for all DIMMs in the system, per profile.
+  MrcGdxc             Gdxc;                        ///< GDXC enable and size.
+  BOOLEAN             VddVoltageDone;              ///< To determine if VddVoltageDone update has been done already
+  BOOLEAN             EccSupport;                  ///< TRUE if ECC is enabled and supported on this controller.
+  BOOLEAN             EnDumRd;                     ///< Enable/Disable Logic Analyzer
+  BOOLEAN             RestoreMRs;                  ///< Enable/Disable restoring
+  BOOLEAN             LpddrEctDone;                ///< Set to TRUE once Early Command Training on LPDDR is done, and we can run JEDEC Init
+  BOOLEAN             LpddrWLUpdated;              ///< Set to TRUE once LPDDR WL Memory Set has been updated
+  BOOLEAN             JedecInitDone;               ///< Set to TRUE once JEDEC Init on LPDDR/DDR4 is done
+  UINT32              DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1];            ///< The Default XMP tCK values read from SPD.
+  UINT8               XmpProfileEnable;            ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  BOOLEAN             Capable100;                  ///< The MC is capable of 100 reference clock (0 = no, 1 = yes).
+  BOOLEAN             AutoSelfRefresh;             ///< Indicates ASR is supported for all the DIMMS for 2xRefresh
+  MrcDdrType          DdrType;                     ///< Current memory type: DDR3, DDR4, or LPDDR3
+  MrcSpdStatus        SpdSecurityStatus;           ///< Status variable to inform BIOS that memory contains an alias.
+  UINT32              MrcTotalChannelLimit;        ///< The maximum allowed memory size per channel, in MBytes.
+  UINT8               SdramCount;                  ///< The number of SDRAM components on a DIMM.
+  UINT16              Qclkps;                      ///< Qclk period in pS
+  UINT8               DQPat;                       ///< Global Variables storing the current DQPat REUT Test
+  INT8                DQPatLC;                     ///< Global Variables storing the current DQPat Loopcount
+  UINT16              NumCL;                       ///< Global Variables storing the current number of Cachelines
+  UINT8               ValidRankMask;               ///< Rank bit map - includes both channels
+  UINT8               ValidChBitMask;              ///< Channel bit map of the populated channels
+  BOOLEAN             UpmPwrRetrainFlag;           ///< A flag that indicates if training with higher UPM/PWR limits.
+  UINT32              MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin measurement.
+  BOOLEAN             MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
+  MrcOdtPowerSaving   OdtPowerSavingData;          ///< ODT power savings data.
+  BOOLEAN             TxDIMMVref[MAX_CHANNEL];     ///< Whether Write DIMM Vref is enabled based on Channel
+  UINT32              MchBarWriteCount;            ///< The number of MMIO writes performed during MRC execution.
+  UINT32              MchBarReadCount;             ///< The number of MMIO reads performed during MRC execution.
+  UINT8               BerEnable;                   ///< BER Enable (and # of Addresses)
+  UINT64              BerAddress[4];               ///< BER Addresses
+  UINT8               CmdVLoop;                    ///< Keeps track of the # of CmdV training step runned
+  UINT8               CmdVLoopStatus;              ///< Keeps the last status of the CmdV training step
+  UINT8               tMAC;                        ///< Maximum Activate Count for pTRR.
+  UINT8               LpddrMemWriteLatencySet;     ///< 0 = Set A (WL), 1 = Set B (WL) if supported
+  BOOLEAN             Ddr4PdaEnable;               ///< Current status of PDA - if true all the Mr6 operations need to use PDA mode.
+  BOOLEAN             BinnedLpddrDevices;          ///< Binned LPDDR3 devices (6Gb/12Gb/etc)
+  MrcControllerOut    Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+  BOOLEAN             TCRSensitiveHynixDDR4;       ///< TCR sensitive Hynix DDR4 in the system
+  BOOLEAN             TCRSensitiveMicronDDR4;      ///< TCR sensitive Micron DDR4 in the system
+  BOOLEAN             OddRatioMode;                ///< If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz
+  BOOLEAN             LpddrDramOdt;                ///< Indicates if LPDDR DRAM ODT is used - Only used for 2133+
+  BOOLEAN             ExtendedDdrOverclock;        ///< Indicates if MC is capable of extended Overclock Memory frequencies.
+  BOOLEAN             DmfcLimitedBoard;            ///< Indicates if the system has 2DPC Memory Configuration which should be DMFC limited.
+  BOOLEAN             DmfcLimited;                 ///< Indicates if the system has DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
+  BOOLEAN             MixedUDimmConfig2Dpc;        ///< Indicates if the system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
+#ifdef BDAT_SUPPORT
+  union {
+    MRC_BDAT_SCHEMA_LIST_HOB *Pointer;             ///< Pointer to the BDAT schema list.
+    UINT64                   Data;
+  } BdatSchemasHob;
+  union {
+    BDAT_MEMORY_DATA_HOB *Pointer;                 ///< Pointer to the BDAT memory data HOB.
+    UINT64               Data;
+  } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
+  UINT8               Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
+#endif
+
+#ifdef UP_SERVER_FLAG
+  UINT8              ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];                        ///< TSOD Thermal Offset
+#endif
+} MrcOutput;
+
+///
+///****************************************
+/// Input related "global data" structures.
+///****************************************
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are SDRAM level definitions. All ranks on a rank are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+  UINT8  Placeholder;  ///< TODO: Is there anything that needs to go in here?
+} MrcSdramIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are rank level definitions. All ranks on a DIMM are set to these values.
+///
+/* Commented out until needed, in order to save space.
+typedef struct {
+  MrcSdramIn  Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are SDRAM level definitions.
+} MrcRankIn;
+*/
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are DIMM level definitions. All ranks on a DIMM are set to these values.
+///
+typedef struct {
+  MrcDimmSts  Status;                 ///< Indicates whether this DIMM should be used.
+  MrcSpdData  Spd;                    ///< The SPD data for each DIMM. SPDGeneral field = 0 when absent.
+  MrcTiming   Timing;                 ///< The DIMMs requested timing overrides.
+  UINT8       SpdAddress;             ///< The SMBus address for the DIMM's SPD data.
+//MrcRankIn   Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level definitions.
+} MrcDimmIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are channel level definitions. All DIMMs on a memory channel are set to these values.
+///
+typedef struct {
+  MrcChannelSts Status;                        ///< Indicates whether this channel should be used.
+  UINT32        DimmCount;                     ///< The maximum number of DIMMs on this channel.
+  MrcDimmIn     Dimm[MAX_DIMMS_IN_CHANNEL];    ///< The following are DIMM level definitions.
+  UINT8         DqsMapCpu2Dram[8];             ///< Mapping from CPU DQS pins to SDRAM DQS pins
+  UINT8         DqMapCpu2Dram[8][MAX_BITS];    ///< Mapping from CPU DQ pins to SDRAM DQ pins
+  UINT8         DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side), per group
+                                               ///< DQByteMap[0] - ClkDQByteMap:
+                                               ///<   If clock is per rank, program to [0xFF, 0xFF]
+                                               ///<   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+                                               ///<   If clock is shared by 2 ranks but does not go to all bytes,
+                                               ///<           Entry[i] defines which DQ bytes Group i services
+                                               ///< DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+                                               ///< DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+                                               ///< DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+                                               ///<                For DDR, DQByteMap[3:1] = [0xFF, 0]
+                                               ///< DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+                                               ///<                               Variable only exists to make the code easier to use
+                                               ///< DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+                                               ///<                               Variable only exists to make the code easier to use
+} MrcChannelIn;
+
+///
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are memory controller level definitions. All channels on a controller are set to these values.
+///
+typedef struct {
+  MrcControllerSts  Status;               ///< Indicates whether this controller should be used.
+  UINT8             ChannelCount;         ///< Number of valid channels that are requested on the controller.
+  MrcChannelIn      Channel[MAX_CHANNEL]; ///< The following are channel level definitions.
+} MrcControllerIn;
+
+/// This data structure contains all the "global data" values that are considered input by the MRC.
+/// The following are system level definitions. All memory controllers in the system are set to these values.
+typedef struct {
+  // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
+  // Alignment of this block must be maintained and field offsets must match.
+  UINT8   Header[28];             ///< 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
+  UINT8   MemoryProfile;          ///< 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 MemoryProfile is UserDefined (CUSTOM PROFILE)
+  UINT16  tCL;                    ///< Offset 32 User defined Memory Timing tCL value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 31=Maximum.
+  UINT16  tRCDtRP;                ///< Offset 34 User defined Memory Timing tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tRAS;                   ///< Offset 36 User defined Memory Timing tRAS value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 64=Maximum.
+  UINT16  tWR;                    ///< Offset 38 User defined Memory Timing tWR value,   valid when MemoryProfile 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 MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 1023=Maximum.
+  UINT16  tRRD;                   ///< Offset 42 User defined Memory Timing tRRD value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR;                   ///< Offset 44 User defined Memory Timing tWTR value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tRTP;                   ///< Offset 46 User defined Memory Timing tRTP value,  valid when MemoryProfile 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 MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tCWL;                   ///< Offset 50 User defined Memory Timing tCWL value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 20=Maximum.
+  UINT16  tREFI;                  ///< Offset 52 User defined Memory Timing tREFI value, valid when MemoryProfile 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 DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  RemapEnable:1;                  ///<  - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+  UINT32  ScramblerEnable:1;              ///<  - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor: 0=Disable, <b>1=Enable</b>
+  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set option: 0=Set A, <b>1=Set B</b>
+  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bits 7-8 Reserved
+  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+  UINT32  Ddr4DdpSharedClock:1;           ///<  - New Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  UINT32  Ddr4DdpSharedZq:1;              ///<  - Select if ZQ pin is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  // Thermal Management
+  UINT32  ThermalManagement:1;            ///<  - Memory Thermal Management Support: <b>0=Disable</b>, 1=Enable.
+  UINT32  PeciInjectedTemp:1;             ///<  - Enable/Disable memory temperatures to be injected to the processor via PECI: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnBoard:1;            ///<  - Enable/Disable routing TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  ExttsViaTsOnDimm:1;             ///<  - Enable/Disable routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
+  UINT32  VirtualTempSensor:1;            ///<  - Enable/Disable Virtual Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
+  UINT32  Lp4DqsOscEn:1;                  ///<  - DqDqsReTraining support: 0=Disable, <b>1=Enable</b>
+  UINT32  DualDimmPerChannelBoardType:1;  ///<  - DualDimmPerChannelBoardType: Option to indicate if the Memory Design for the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>, 1=Dual DIMM Design
+  UINT32  ReservedBits1:13;
+  /**
+   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[MAX_CHANNEL];  ///< Offset 68
+  /**
+   Selects the ratio to multiply the reference clock by for the DDR frequency\n
+   When RefClk is 133MHz\n
+   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are invalid\n
+   When RefClk is 100MHz\n
+   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are invalid\n
+  **/
+  UINT8   Ratio;                  ///< Offset 70
+  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+  /**
+     - Channel Hash Enable.\n
+    NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at 4 and BIT9 at 8\n
+    0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
+  **/
+  UINT8   ChHashInterleaveBit;    ///< Offset 76
+  UINT8   EnergyScaleFact;        ///< Offset 77 - Energy Scale Factor. 0=Minimal, 7=Maximum, <b>4=Default</b>
+  UINT8   Reserved0;              ///< Offset 78 - Reserved for future use.
+  UINT8   McLock;                 ///< Offset 79 - Enable/Disable memory configuration register locking: 0=Disable, <b>1=Enable</b>.
+  // Training Algorithms
+  TrainingStepsEn TrainingEnables;    ///< Offset 80 - Options to Enable individual training steps
+  TrainingStepsEn2 TrainingEnables2;  ///< Offset 84 - Options to Enable individual training steps
+
+  UINT32  OddRatioMode:1;             ///< Offset 88 - If Odd Ratio Mode is enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcTimeMeasure:1;           ///< - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcFastBoot:1;              ///< - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+  UINT32  DqPinsInterleaved:1;        ///< - Interleaving mode of DQ/DQS pins for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
+  UINT32  RankInterleave:1;           ///< - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  EnhancedInterleave:1;       ///< - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  WeaklockEn:1;               ///< - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  CmdTriStateDis:1;           ///< - CMD Tri-State Support: <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if Command RTT is not present on the platform.
+  UINT32  MemoryTrace:1;              ///< - Memory Trace to second DDR channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  ChHashEnable:1;             ///< - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  EnableExtts:1;              ///< - Enable Extts: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableCltm:1;               ///< - Enable Closed Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnableOltm:1;               ///< - Enable Open Loop Thermal Management: <b>0=Disable</b>, 1=Enable
+  UINT32  EnablePwrDn:1;              ///< - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  EnablePwrDnLpddr:1;         ///< - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  LockPTMregs:1;              ///< - Lock PCU Thermal Management registers: 0=Disable, <b>1=Enable</b>
+  UINT32  UserPowerWeightsEn:1;       ///< - Allows user to explicitly set power weight, scale factor, and channel power floor values: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Lock:1;             ///< - Lock DDR_RAPL_LIMIT register: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim2Ena:1;              ///< - Enable Power Limit 2: <b>0=Disable</b>, 1=Enable
+  UINT32  RaplLim1Ena:1;              ///< - Enable Power Limit 1: <b>0=Disable</b>, 1=Enable
+  UINT32  SrefCfgEna:1;               ///< - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeatLpddr:1;    ///< - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeat:1;         ///< - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+  UINT32  AutoSelfRefreshSupport:1;   ///< - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+  UINT32  ExtTemperatureSupport:1;    ///< - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+  UINT32  MobilePlatform:1;           ///< - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+  UINT32  Force1Dpc:1;                ///< - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+  UINT32  ForceSingleRank:1;          ///< - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+  UINT32  RhPrevention:1;             ///< - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+  UINT32  VttTermination:1;           ///< - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+  UINT32  VttCompForVsshi:1;          ///< - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+  UINT32  ExitOnFailure:1;            ///< - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+
+  UINT32  VddSettleWaitTime;      ///< Offset 92 - Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+  UINT16  FreqSaGvLow;            ///< Offset 96 - SA GV: 0 is Auto/default, otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333, 1400, 1600, 1800, 1867.
+  UINT16  SrefCfgIdleTmr;         ///< Offset 98 - Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+  UINT8   RhActProbability;       ///< Offset 100 - Activation probability for Hardware RHP
+  UINT8   SmramMask;              ///< Offset 101 - Reserved memory ranges for SMRAM
+  UINT16  Vc1ReadMeterThreshold;  ///< Offset 102 - VC1 Read Meter Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum, <b>0x118=Default</b>
+  UINT32  Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
+  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es): <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
+
+  UINT16  ChHashMask;             ///< Offset 140 - 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 142 - Memory Frequency Limit: <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see MrcFrequency in MrcInterface.h
+  ThermalMngmtEn  ThermalEnables; ///< Offset 144 - 187
+
+  UINT8   MaxRttWr;               ///< Offset 188 - Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+  UINT8   ThrtCkeMinTmr;          ///< Offset 189 - Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
+  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 - Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
+  UINT8   BerEnable;              ///< Offset 191 - BER Enable and # of Addresses passed in: <b>0=Minimal</b>, 8=Maximum
+  UINT8   CkeRankMapping;         ///< Offset 192 - Bits [7:4] - Channel 1, bits [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes to.
+  UINT8   StrongWkLeaker;         ///< Offset 193 - Strong Weak Leaker: 1=Minimal, <b>7=Maximum</b>
+  UINT8   CaVrefConfig;           ///< Offset 194 - 0=VREF_CA goes to both CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A, VREF_DQ_B to CH_B</b>
+  UINT8   SaGv;                   ///< Offset 195 - SA GV: <b>0=Disabled</b>, 1=FixedLow, 2=FixedHigh, 3=Enabled
+  UINT8   RaplPwrFlCh1;           ///< Offset 196 - Power Channel 1 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   RaplPwrFlCh0;           ///< Offset 197 - Power Channel 0 Floor value: <b>0=Minimal</b>, 255=Maximum
+  UINT8   NModeSupport;           ///< Offset 198 - Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+  UINT8   RefClk;                 ///< Offset 199 - Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+  UINT8   EnCmdRate;              ///< Offset 200 - CMD Rate Enable: 0=Disable, 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7 CMDs
+  UINT8   Refresh2X;              ///< Offset 201 - Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+  UINT8   EpgEnable;              ///< Offset 202 - Enable Energy Performance Gain.
+  UINT8   RhSolution;             ///< Offset 203 - Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  UINT8   UserThresholdEnable;    ///< Offset 204 - Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   UserBudgetEnable;       ///< Offset 205 - Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodTcritMax;           ///< Offset 206 - TSOD Tcrit Maximum Value  to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
+
+  UINT8   TsodEventMode;          ///< Offset 207 - Flag to Enable Event Mode Interruption in TSOD Configuration Register, 0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventPolarity;      ///< Offset 208 - Event Signal Polarity in TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
+  UINT8   TsodCriticalEventOnly;  ///< Offset 209 - Critical Trigger Only in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodEventOutputControl; ///< Offset 210 - Event Output Control in TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
+  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
+  UINT8   TsodShutdownMode;       ///< Offset 213 - Shutdown Mode TSOD Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
+  UINT8   TsodThigMax;            ///< Offset 214 - Thigh Max Value In the  for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   TsodManualEnable;       ///< Offset 215 - Flag to manually select the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   DllBwEn0;               ///< Offset 216 - DllBwEn value for 1067
+  UINT8   DllBwEn1;               ///< Offset 217 - DllBwEn value for 1333
+  UINT8   DllBwEn2;               ///< Offset 218 - DllBwEn value for 1600
+  UINT8   DllBwEn3;               ///< Offset 219 - DllBwEn value for 1867 and up
+  UINT8   RetrainOnFastFail;      ///< Offset 220 - Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 - Force OLTM or 2X Refresh when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
+  UINT8   PowerDownMode;          ///< Offset 222 - CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+  UINT8   PwdwnIdleCounter;       ///< Offset 223 - CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal, 0xFF=Maximum, <b>0x99=Default</b>
+  UINT8   Reserved3;              ///< Offset 225 -  ConfigBlock size must be a multiple of DWORDs
+  MrcGdxc Gdxc;                   ///< Offset 226 - 228 - GDXC enable and size.
+  UINT8   RMTLoopCount;           ///< Offset 229 - Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+  UINT8   Reserved4[2];           ///< Offset 230 - 231 Reserved for DWORD alignment.
+  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232Bit1Rsvd:2;             ///< Offset 232 Bit 1-2: Reserved
+  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is enabled for Rank Margin Tool
+  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4: Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
+  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Enalbes MRC trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
+  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
+
+  //
+  // TurnAround Timing
+  //
+  MrcTurnaroundTimes tRd2Rd;      ///< Offset 236 - User-defined overrides for Read-to-Read   Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tRd2Wr;      ///< Offset 240 - User-defined overrides for Read-to-Write  Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tWr2Rd;      ///< Offset 244 - User-defined overrides for Write-to-Read  Turn Around Timings. <b>0 = AUTO</b>
+  MrcTurnaroundTimes tWr2Wr;      ///< Offset 248 - User-defined overrides for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
+  UINT16  tRRD_L;                 ///< Offset 252 - User defined DDR4 Memory Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tRRD_S;                 ///< Offset 254 - User defined DDR4 Memory Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR_L;                 ///< Offset 266 - User defined DDR4 Memory Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tWTR_S;                 ///< Offset 268 - User defined DDR4 Memory Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+
+  //
+  // End of synchronization to the SA MEMORY_CONFIGURATION structure.
+  //
+  MrcFrequency     FreqMax;                     ///< The requested maximum valid frequency.
+  MrcBoardType     BoardType;                   ///< Define the board type (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
+  MrcCpuStepping   CpuStepping;                 ///< Define the CPU stepping.
+  MrcCpuModel      CpuModel;                    ///< Define the CPU model.
+  MrcCpuFamily     CpuFamily;                   ///< CPU is Coffeelake
+  MrcGfxDataSize   GraphicsStolenSize;          ///< Graphics Data Stolen Memory size in MB
+  MrcGfxGttSize    GraphicsGttSize;             ///< GTT graphics stolen memory size in MB
+  MrcBaseTime      BaseTime;                    ///< RTC base time.
+  MrcIteration     Iteration;                   ///< Number of iterations thru the MRC core call table.
+  MrcMode          MrcMode;                     ///< The control for full or MiniBIOS MRC.
+  MrcBootMode      BootMode;                    ///< The requested memory controller boot mode.
+  BOOLEAN          TxtFlag;                     ///< Trusted eXecution Technology flag.
+  BOOLEAN          SetRxDqs32;                  ///< Set DQS Delay to 32 control.
+  BOOLEAN          GfxIsVersatileAcceleration;  ///< iGFX engines are in Versatile Acceleration
+  BOOLEAN          DDR4MAP;                     ///< DDR4 PDA Mapping training control.
+  POINTER_STRUCT   SaMemCfgAddress;             ///< Starting address of the input parameters to CRC.
+  UINT32           SaMemCfgSize;                ///< The size of the input parameters to CRC.
+  UINT32           PciEBaseAddress;             ///< define the PciE base address.
+  UINT32           MchBarBaseAddress;           ///< define the MCH bar base address.
+  UINT32           SmbusBaseAddress;            ///< This field defines the smbus base address.
+  UINT32           GdxcBaseAddress;             ///< This field defines the GDXC base address.
+  UINT32           HpetBaseAddress;             ///< This field defines the hpet base address.
+  UINT32           MeStolenSize;                ///< define the size that the ME need in MB.
+  UINT32           MmioSize;                    ///< define the MMIO size in MB.
+  UINT32           TsegSize;                    ///< TSEG size that require by the system in MB.
+  UINT32           IedSize;                     ///< IED size that require by the system in MB.
+  UINT32           DprSize;                     ///< DPR size required by system in MB.
+  UINT32           PrmrrSize;                   ///< Prmrr size required by the system in MB.
+  POINTER_STRUCT   SerialBuffer;                ///< Pointer to the start of the serial buffer.
+  UINT32           SerialBufferSize;            ///< The size of the serial buffer, in bytes.
+  UINT32           DebugStream;                 ///< The debug port pointer.
+  INT32            DebugLevel;                  ///< Indicates the level of debug messaging.
+  UINT16           VccIomV;                     ///< VccIO logic voltage in mV.
+  MrcControllerIn  Controller[MAX_CONTROLLERS]; ///< The following are controller level definitions.
+  UINT32           HeapBase;                    ///< Starting address of the heap space.
+  UINT32           HeapSize;                    ///< Size of the heap space, in bytes.
+  UINT32           MrcStackTop;                 ///< Top of the stack at the beginning of MRC, for stack usage calculations.
+  BOOLEAN          BdatEnable;                  ///< Option to enable output of training results into BDAT.
+  UINT8            BdatTestType;                ///< When BdatEnable is set to TRUE, this option selects the type of training results data which will be populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
+  BOOLEAN          LpddrDramOdt;                ///< TRUE if LPDDR DRAM ODT is used - depends on board design
+  BOOLEAN          Ddr3DramOdt;                 ///< TRUE if DDR3  DRAM ODT is used - depends on board design
+  BOOLEAN          Ddr4DramOdt;                 ///< TRUE if DDR4  DRAM ODT is used - depends on board design
+  BOOLEAN          EnableVrefPwrDn;             ///< Setting this limits VrefGen to be off only during CKEPowerDown
+  BOOLEAN          TxEqDis;                     ///< Disable TX Equalization
+  BOOLEAN          EnVttOdt;                    ///< Enable VTT Termination for Data ODT
+  UINT32           CpuidModel;                  ///< Unique CPU identifier.
+  UINT8            CpuidStepping;               ///< Revision of the CPU.
+  UINT8            CpuidSku;                    ///< SKU of the CPU.
+  UINT32           SiPreMemPolicyPpi;
+  TrainingModeType PowerTrainingMode;           ///< 0 - Power Training. 1 - Margin Training.
+  union {
+    MRC_FUNCTION  *Func;                        ///< External to MRC function pointers
+    UINT64        Data;
+  } Call;
+  UINT16          RcompResistor[MAX_RCOMP];     ///< Reference RCOMP resistors on motherboard
+  UINT16          RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+  UINT32          CleanMemory:1;                ///< TRUE to request a memory clean
+  UINT32          OcSupport:1;                  ///< TRUE if Overclocking is enabled in BIOS
+  UINT32          RsvdBits5:30;
+  /**
+   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;
+} MrcInput;
+
+typedef struct {
+  UINT32        Size;   ///< The size of this structure, in bytes. Must be the first entry in this structure.
+  MrcSaveHeader Header; ///< The header portion of the MRC saved data.
+  MrcSaveData   Data;   ///< The data portion of the MRC saved data.
+} MrcSave;
+
+typedef struct {
+  // Global variables that will be copied to the HOB follow.
+  UINT8        MrcDataString[4]; ///< Beginning of global data marker, starts with "MRC". Must be the first entry in this structure.
+  UINT32       MrcDataSize;      ///< The size of the MRC global data area, in bytes. Must be the second entry in this structure.
+  MrcSave      Save;             ///< System specific save variables.
+  MrcInput     Inputs;           ///< System specific input variables.
+  MrcOutput    Outputs;          ///< System specific output variables.
+
+  // Global variables that will remain internal to the MRC library follow.
+  union {
+    void   *Internal; ///< System specific output variables that remain internal to the library.
+    UINT64 Data;
+  } IntOutputs;
+} MrcParameters;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
new file mode 100644
index 0000000000..9dd9b096ba
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
@@ -0,0 +1,203 @@
+/** @file
+  Copies the memory related timing and configuration information into the
+  Compatible BIOS data (BDAT) table.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcRmtData_h_
+#define _MrcRmtData_h_
+
+#include "MrcTypes.h"
+
+#define VDD_1_350             1350                      ///< VDD in millivolts
+#define VDD_1_500             1500                      ///< VDD in millivolts
+#define PI_STEP_BASE          2048                      ///< Magic number from spec
+#define PI_STEP_INTERVAL      128                       ///< tCK is split into this amount of intervals
+#define PI_STEP               ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
+#define VREF_STEP_BASE        100                       ///< Magic number from spec
+#define TX_VREF_STEP          7800                      ///< TX Vref step in microvolts
+#define TX_VREF(VDD)          (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define RX_VREF_STEP          8000                      ///< TX Vref step in microvolts
+#define RX_VREF(VDD)          (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+#define CA_VREF_STEP          8000                      ///< TX Vref step in microvolts
+#define CA_VREF(VDD)          (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD)) ///< VDD passed in is in millivolts
+
+#define MAX_SPD_RMT           512                       ///< The maximum amount of data, in bytes, in an SPD structure.
+#define RMT_PRIMARY_VERSION   4                         ///< The BDAT structure that is currently supported.
+#define RMT_SECONDARY_VERSION 0                         ///< The BDAT structure that is currently supported.
+#define MAX_MODE_REGISTER     7                         ///< Number of mode registers
+#define MAX_DRAM_DEVICE       9                         ///< Maximum number of memory devices
+#define MAX_2D_EYE_TYPE       2                         ///< Maximum number of supported Margin 2D Eye Types
+#define MAX_2D_EYE_OFFSETS    7                         ///< Number of 2D Eye Offsets
+
+//
+// Warning: Bdat4.h has its own copy of this #define
+// make sure to change it in both places
+//
+#define MAX_SCHEMA_LIST_LENGTH (10)
+
+
+#ifdef BDAT_SUPPORT
+/*
+  BSSA result Memory Schema GUID
+  {8F4E928-0F5F-46D4-8410-479FDA279DB6}
+*/
+extern EFI_GUID gSsaBiosResultsGuid;
+/*
+  RMT Results Metadata GUID
+  {02CB1552-D659-4232-B51F-CAB1E11FCA87}
+*/
+extern EFI_GUID gRmtResultMetadataGuid;
+/*
+  RMT Results Columns GUID
+  {0E60A1EB-331F-42A1-9DE7-453E84761154}
+*/
+extern EFI_GUID gRmtResultColumnsGuid;
+
+/*
+Margin2D Results Metadata GUID
+{48265582-8E49-4AC7-AA06-E1B9A74C9716}
+*/
+extern EFI_GUID gMargin2DResultMetadataGuid;
+/*
+Margin2D Results Columns GUID
+{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
+*/
+extern EFI_GUID gMargin2DResultColumnsGuid;
+
+#endif
+/*
+ GUID for Schema List HOB
+ This is private GUID used by MemoryInit internally.
+ {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
+*/
+extern EFI_GUID gMrcSchemaListHobGuid;
+
+#pragma pack(push, 1)
+
+
+///
+/// SSA results buffer header.
+///
+typedef struct {
+  UINT32  Revision;
+  BOOLEAN TransferMode;
+  struct {
+    UINT32   Reserved;
+    UINT32   MetadataSize;
+    EFI_GUID MetadataType;
+  } MdBlock;
+  struct {
+    UINT32   Reserved;
+    EFI_GUID ResultType;
+    UINT32   ResultElementSize;
+    INT32    ResultCapacity;
+    INT32    ResultElementCount;
+  } RsBlock;
+} RESULTS_DATA_HDR;
+
+// start auto-generated by the BSSA CCK sourced from the result xml files.
+typedef enum {
+  DisableScrambler = 0,
+  EnableScrambler = 1,
+  DontTouchScrambler = 2,
+  SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
+} SCRAMBLER_OVERRIDE_MODE;
+
+typedef struct _RMT_RESULT_METADATA {
+  BOOLEAN EnableCtlAllMargin;
+  UINT16 SinglesBurstLength;
+  UINT32 SinglesLoopCount;
+  UINT16 TurnaroundsBurstLength;
+  UINT32 TurnaroundsLoopCount;
+  SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
+  UINT8 PiStepUnit[2];
+  UINT16 RxVrefStepUnit[2];
+  UINT16 TxVrefStepUnit[2][2];
+  UINT16 CmdVrefStepUnit[2][2];
+  UINT8 MajorVer;
+  UINT8 MinorVer;
+  UINT8 RevVer;
+  UINT32 BuildVer;
+  UINT16 ResultEleCount;
+} RMT_RESULT_METADATA;
+
+
+typedef struct _RMT_RESULT_ROW_HEADER {
+  UINT32 ResultType : 5;
+  UINT32 Socket : 3;
+  UINT32 Controller : 2;
+  UINT32 Channel : 3;
+  UINT32 DimmA : 1;
+  UINT32 RankA : 3;
+  UINT32 DimmB : 1;
+  UINT32 RankB : 3;
+  UINT32 Lane : 8;
+  UINT32 IoLevel : 1;
+  UINT32 Reserved : 2;
+} RMT_RESULT_ROW_HEADER;
+
+typedef struct _RMT_RESULT_COLUMNS {
+  RMT_RESULT_ROW_HEADER Header;
+  UINT8 Margin[4][2];
+} RMT_RESULT_COLUMNS;
+
+// end of auto-generated by the BSSA CCK sourced from the result xml files.
+
+typedef struct _BASE_RMT_RESULT {
+  RESULTS_DATA_HDR              ResultsHeader;
+  RMT_RESULT_METADATA           Metadata;
+  RMT_RESULT_COLUMNS            Rows[1];
+} BASE_RMT_RESULT;
+
+
+typedef struct {
+  UINT32                      Data1;
+  UINT16                      Data2;
+  UINT16                      Data3;
+  UINT8                       Data4[8];
+} BDAT_EFI_GUID;
+
+typedef struct {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} BDAT_HOB_GENERIC_HEADER;
+
+typedef struct {
+  BDAT_HOB_GENERIC_HEADER  Header;
+  BDAT_EFI_GUID            Name;
+  ///
+  /// Guid specific data goes here
+  ///
+} BDAT_HOB_GUID_TYPE;
+
+typedef struct {
+  BDAT_EFI_GUID               SchemaId;                         ///< The GUID uniquely identifies the format of the data contained within the structure.
+  UINT32                      DataSize;                         ///< The total size of the memory block, including both the header as well as the schema specific data.
+  UINT16                      Crc16;                            ///< Crc16 is computed in the same manner as the field in the BDAT_HEADER_STRUCTURE.
+} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
+
+typedef struct {
+  MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader;                ///< The schema header.
+  BASE_RMT_RESULT          RMT_RESULTS_WITH_META_COLUMNS;
+} BDAT_MEMORY_DATA_STRUCTURE;
+
+typedef struct {
+  BDAT_HOB_GUID_TYPE          HobGuidType;
+  BDAT_MEMORY_DATA_STRUCTURE  MemorySchema;
+} BDAT_MEMORY_DATA_HOB;
+
+#pragma pack (pop)
+
+typedef struct {
+  BDAT_HOB_GUID_TYPE          HobGuidType;
+  UINT16                      SchemaHobCount;
+  UINT16                      Reserved;
+  BDAT_EFI_GUID               SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
+} MRC_BDAT_SCHEMA_LIST_HOB;
+
+#endif //_MrcRmtData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
new file mode 100644
index 0000000000..45de5084c0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
@@ -0,0 +1,1167 @@
+/** @file
+  SPD data format header file.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MrcSpdData_h_
+#define _MrcSpdData_h_
+#pragma pack (push, 1)
+
+#include "MrcTypes.h"
+
+#define MAX_XMP_PROFILES  (2)
+#define SPD3_MANUF_SIZE   (SPD3_MANUF_END - SPD3_MANUF_START + 1)   ///< The size of the SPD manufacturing data.
+#define SPD4_MANUF_SIZE   (SPD4_MANUF_END - SPD4_MANUF_START + 1)   ///< The size of the SPD manufacturing data.
+#define SPDLP_MANUF_SIZE  (SPDLP_MANUF_END - SPDLP_MANUF_START + 1) ///< The size of the SPD manufacturing data
+
+typedef union {
+  struct {
+    UINT8  BytesUsed                           :  4; ///< Bits 3:0
+    UINT8  BytesTotal                          :  3; ///< Bits 6:4
+    UINT8  CrcCoverage                         :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_DEVICE_DESCRIPTION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Minor                               :  4; ///< Bits 3:0
+    UINT8  Major                               :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_REVISION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Type                                :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_DRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ModuleType                          :  4; ///< Bits 3:0
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  3; ///< Bits 6:4
+    UINT8                                      :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ColumnAddress                       :  3; ///< Bits 2:0
+    UINT8  RowAddress                          :  3; ///< Bits 5:3
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_ADDRESSING_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_50                     :  1; ///< Bits 0:0
+    UINT8  OperationAt1_35                     :  1; ///< Bits 1:1
+    UINT8  OperationAt1_25                     :  1; ///< Bits 2:2
+    UINT8                                      :  5; ///< Bits 7:3
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SdramDeviceWidth                    :  3; ///< Bits 2:0
+    UINT8  RankCount                           :  3; ///< Bits 5:3
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_ORGANIZATION_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  PrimaryBusWidth                     :  3; ///< Bits 2:0
+    UINT8  BusWidthExtension                   :  2; ///< Bits 4:3
+    UINT8                                      :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Divisor                             :  4; ///< Bits 3:0
+    UINT8  Dividend                            :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_FINE_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Dividend                            :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Divisor                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
+
+typedef struct {
+  SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium Timebase (MTB) Dividend
+  SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT  Divisor;  ///< Medium Timebase (MTB) Divisor
+} SPD_MEDIUM_TIMEBASE;
+
+typedef union {
+  struct {
+    UINT8  tCKmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TCK_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 CL4                                 :  1; ///< Bits 0:0
+    UINT16 CL5                                 :  1; ///< Bits 1:1
+    UINT16 CL6                                 :  1; ///< Bits 2:2
+    UINT16 CL7                                 :  1; ///< Bits 3:3
+    UINT16 CL8                                 :  1; ///< Bits 4:4
+    UINT16 CL9                                 :  1; ///< Bits 5:5
+    UINT16 CL10                                :  1; ///< Bits 6:6
+    UINT16 CL11                                :  1; ///< Bits 7:7
+    UINT16 CL12                                :  1; ///< Bits 8:8
+    UINT16 CL13                                :  1; ///< Bits 9:9
+    UINT16 CL14                                :  1; ///< Bits 10:10
+    UINT16 CL15                                :  1; ///< Bits 11:11
+    UINT16 CL16                                :  1; ///< Bits 12:12
+    UINT16 CL17                                :  1; ///< Bits 13:13
+    UINT16 CL18                                :  1; ///< Bits 14:14
+    UINT16                                     :  1; ///< Bits 15:15
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tAAmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TAA_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tWRmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TWR_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRCDmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRCD_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRRDmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRRD_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPab                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_AB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPabFine                            :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_AB_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRPpb                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRP_PB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPpbFine                            :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_PB_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16  tRFCab                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_AB_MTB_STRUCT;
+
+typedef union {
+struct {
+    UINT16  tRFCpb                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_PB_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRASminUpper                        :  4; ///< Bits 3:0
+    UINT8  tRCminUpper                         :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_TRAS_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRASmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRAS_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRCmin                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 tRFCmin                             :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TRFC_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tWTRmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TWTR_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tRTPmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TRTP_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tFAWminUpper                        :  4; ///< Bits 3:0
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tFAWmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TFAW_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCWLmin                             :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_TCWL_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  NMode                               :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_SYSTEM_COMMAND_RATE_STRUCT;
+
+typedef union {
+  struct {
+    UINT16 tREFImin                            :  16; ///< Bits 15:0
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_TREFI_MIN_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  RZQ6                                :  1; ///< Bits 0:0
+    UINT8  RZQ7                                :  1; ///< Bits 1:1
+    UINT8                                      :  5; ///< Bits 6:2
+    UINT8  DllOff                              :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ExtendedTemperatureRange            :  1; ///< Bits 0:0
+    UINT8  ExtendedTemperatureRefreshRate      :  1; ///< Bits 1:1
+    UINT8  AutoSelfRefresh                     :  1; ///< Bits 2:2
+    UINT8  OnDieThermalSensor                  :  1; ///< Bits 3:3
+    UINT8                                      :  3; ///< Bits 6:4
+    UINT8  PartialArraySelfRefresh             :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ThermalSensorAccuracy               :  7; ///< Bits 6:0
+    UINT8  ThermalSensorPresence               :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_MODULE_THERMAL_SENSOR_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  NonStandardDeviceDescription        :  7; ///< Bits 6:0
+    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TCK_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tAAminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TAA_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRCDminFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRCD_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRPminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRP_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRCminFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRC_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tMACencoding                        :  4; ///< Bits 3:0
+    UINT8  tMAWencoding                        :  2; ///< Bits 5:4
+    UINT8  Reserved                            :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_PTRR_SUPPORT_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tRRDminFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_TRRD_MIN_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_REFERENCE_RAW_CARD;
+
+typedef union {
+  struct {
+    UINT8  MappingRank1                        :  1; ///< Bits 0:0
+    UINT8                                      :  7; ///< Bits 7:1
+  } Bits;
+  UINT8  Data;
+} SPD_UNBUF_ADDRESS_MAPPING;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8                                      :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_REFERENCE_RAW_CARD;
+
+typedef union {
+  struct {
+    UINT8  RegisterCount                       :  2; ///< Bits 1:0
+    UINT8  DramRowCount                        :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_RDIMM_MODULE_ATTRIBUTES;
+
+typedef union {
+  struct {
+    UINT16 ContinuationCount                   :  7; ///< Bits 6:0
+    UINT16 ContinuationParity                  :  1; ///< Bits 7:7
+    UINT16 LastNonZeroByte                     :  8; ///< Bits 15:8
+  } Bits;
+  UINT16 Data;
+  UINT8  Data8[2];
+} SPD_MANUFACTURER_ID_CODE;
+
+typedef struct {
+  UINT8  Year;                                 ///< Year represented in BCD (00h = 2000)
+  UINT8  Week;                                 ///< Year represented in BCD (47h = week 47)
+} SPD_MANUFACTURING_DATE;
+
+typedef union {
+  UINT32 Data;
+  UINT16 SerialNumber16[2];
+  UINT8  SerialNumber8[4];
+} SPD_MANUFACTURER_SERIAL_NUMBER;
+
+typedef struct {
+  UINT8 Location;                              ///< Module Manufacturing Location
+} SPD_MANUFACTURING_LOCATION;
+
+typedef struct {
+  SPD_MANUFACTURER_ID_CODE            IdCode;                   ///< Module Manufacturer ID Code
+  SPD_MANUFACTURING_LOCATION          Location;                 ///< Module Manufacturing Location
+  SPD_MANUFACTURING_DATE              Date;                     ///< Module Manufacturing Year, in BCD (range: 2000-2255)
+  SPD_MANUFACTURER_SERIAL_NUMBER      SerialNumber;             ///< Module Serial Number
+} SPD_UNIQUE_MODULE_ID;
+
+typedef union {
+  UINT16 Crc[1];
+  UINT8  Data8[2];
+} SPD_CYCLIC_REDUNDANCY_CODE;
+
+typedef union {
+  struct {
+    UINT8  ProfileEnable1                :  1;                     ///< Bits 0:0
+    UINT8  ProfileEnable2                :  1;                     ///< Bits 1:1
+    UINT8  ProfileConfig1                :  2;                     ///< Bits 3:2
+    UINT8  ProfileConfig2                :  2;                     ///< Bits 5:4
+    UINT8                                :  2;                     ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_XMP_ORG_CONFIG;
+
+typedef struct {
+  UINT16                              XmpId;                    ///< 176-177 XMP Identification String
+  SPD_XMP_ORG_CONFIG                  XmpOrgConf;               ///< 178 XMP Organization & Configuration
+  SPD_REVISION_STRUCT                 XmpRevision;              ///< 179 XMP Revision
+  SPD_MEDIUM_TIMEBASE                 MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase (MTB)
+  SPD_FINE_TIMEBASE_STRUCT            FineTimeBase;             ///< 184 Fine Timebase (FTB) Dividend / Divisor
+} SPD_EXTREME_MEMORY_PROFILE_HEADER;
+
+typedef union {
+  struct {
+    UINT8  Decimal : 5;
+    UINT8  Integer : 2;
+    UINT8          : 1;
+  } Bits;
+  UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Decimal : 7;
+    UINT8  Integer : 1;
+  } Bits;
+  UINT8 Data;
+} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
+
+typedef union {
+  struct {
+    UINT8  Fine                                :  2; ///< Bits 1:0
+    UINT8  Medium                              :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD4_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT32 CL7                                 :  1; ///< Bits 0:0
+    UINT32 CL8                                 :  1; ///< Bits 1:1
+    UINT32 CL9                                 :  1; ///< Bits 2:2
+    UINT32 CL10                                :  1; ///< Bits 3:3
+    UINT32 CL11                                :  1; ///< Bits 4:4
+    UINT32 CL12                                :  1; ///< Bits 5:5
+    UINT32 CL13                                :  1; ///< Bits 6:6
+    UINT32 CL14                                :  1; ///< Bits 7:7
+    UINT32 CL15                                :  1; ///< Bits 8:8
+    UINT32 CL16                                :  1; ///< Bits 9:9
+    UINT32 CL17                                :  1; ///< Bits 10:10
+    UINT32 CL18                                :  1; ///< Bits 11:11
+    UINT32 CL19                                :  1; ///< Bits 12:12
+    UINT32 CL20                                :  1; ///< Bits 13:13
+    UINT32 CL21                                :  1; ///< Bits 14:14
+    UINT32 CL22                                :  1; ///< Bits 15:15
+    UINT32 CL23                                :  1; ///< Bits 16:16
+    UINT32 CL24                                :  1; ///< Bits 17:17
+    UINT32                                     :  14; ///< Bits 31:18
+  } Bits;
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef struct {
+  SPD_VDD_VOLTAGE_LEVEL_STRUCT        Vdd;                      ///< 185, 220 XMP Module VDD Voltage Level
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 186, 221 XMP SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 187, 222 XMP Minimum CAS Latency Time (tAAmin)
+  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
+  SPD_TCWL_MIN_MTB_STRUCT             tCWLmin;                  ///< 190, 225 XMP Minimum CAS Write Latency Time (tCWLmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 191, 226 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 192, 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 193, 228 XMP Minimum Write Recovery Time (tWRmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 194, 229 XMP Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 195, 230 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 196, 231 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TREFI_MIN_MTB_STRUCT            tREFImin;                 ///< 197-198, 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 199-200, 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least Significant Byte
+  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 201, 236 XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 202, 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 203, 238 XMP Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 204, 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 205, 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
+  UINT8                               Reserved1[207 - 206 + 1]; ///< 206-207, 241-242 XMP Reserved
+  SPD_SYSTEM_COMMAND_RATE_STRUCT      SystemCmdRate;            ///< 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
+  SPD_AUTO_SELF_REFRESH_PERF_STRUCT   AsrPerf;                  ///< 209, 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6 impact)
+  UINT8                               VoltageLevel;             ///< 210, 245 XMP Memory Controller Voltage Level
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 211, 246 XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 212, 247 XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 213, 248 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 214, 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 215, 250 XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  UINT8                               Reserved2[218 - 216 + 1]; ///< 216-218, 251-253 XMP Reserved
+  UINT8                               VendorPersonality;        ///< 219, 254 XMP Vendor Personality
+} SPD_EXTREME_MEMORY_PROFILE_DATA;
+
+typedef struct {
+  SPD_EXTREME_MEMORY_PROFILE_HEADER   Header;                   ///< 176-184 XMP header
+  SPD_EXTREME_MEMORY_PROFILE_DATA     Data[MAX_XMP_PROFILES];   ///< 185-254 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE;
+
+typedef struct {
+  UINT16                              XmpId;                        ///< 384-385 XMP Identification String
+  SPD_XMP_ORG_CONFIG                  XmpOrgConf;                   ///< 386 XMP Organization & Configuration
+  SPD_REVISION_STRUCT                 XmpRevision;                  ///< 387 XMP Revision
+  SPD4_TIMEBASE_STRUCT                TimeBase[MAX_XMP_PROFILES];   ///< 388-389 Medium and Fine Timebase
+  UINT8                               Reserved[392 - 390 + 1];     ///< 390-392 Reserved
+} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
+
+typedef struct {
+  SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0    Vdd;                      ///< 393, 440 XMP Module VDD Voltage Level
+  UINT8                               Reserved1[395 - 394 + 1]; ///< 394-395, 441-442 XMP Reserved
+  SPD_TCK_MIN_MTB_STRUCT              tCKAVGmin;                ///< 396, 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
+  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///< 397-400, 444-447 XMP CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 401, 448 XMP Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 402, 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 403, 450 XMP Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 404, 451 XMP Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 405, 452 XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 406, 453 XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 407-408, 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 409-410, 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 411-412, 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 413, 460 Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 414, 461 Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 415, 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 416, 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+  UINT8                               Reserved2[424 - 417 + 1]; ///< 417-424, 464-471 XMP Reserved
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 425, 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 426, 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 427, 474 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 428, 475 Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 429, 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 430, 477 Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TCK_MIN_FTB_STRUCT              tCKAVGminFine;            ///< 431, 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
+  UINT8                               Reserved3[439 - 432 + 1]; ///< 432-439, 479-486 XMP Reserved
+} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
+
+typedef struct {
+  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0      Header;                   ///< 384-392 XMP header
+  SPD_EXTREME_MEMORY_PROFILE_DATA_2_0        Data[MAX_XMP_PROFILES];   ///< 393-486 XMP profiles
+} SPD_EXTREME_MEMORY_PROFILE_2_0;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0   Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                 Revision;                 ///< 1   SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2   DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3   Module Type
+  SPD_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;     ///< 4   SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5   SDRAM Addressing
+  SPD_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;     ///< 6   Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///< 7   Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;     ///< 8   Module Memory Bus Width
+  SPD_FINE_TIMEBASE_STRUCT            FineTimebase;             ///< 9   Fine Timebase (FTB) Dividend / Divisor
+  SPD_MEDIUM_TIMEBASE                 MediumTimebase;           ///< 10-11 Medium Timebase (MTB) Dividend
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 12  SDRAM Minimum Cycle Time (tCKmin)
+  UINT8                               Reserved1;                ///< 13  Reserved
+  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 14-15 CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 16  Minimum CAS Latency Time (tAAmin)
+  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 17  Minimum Write Recovery Time (tWRmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 18  Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 19  Minimum Row Active to Row Active Delay Time (tRRDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 20  Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 21  Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 22  Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 23  Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 24-25  Minimum Refresh Recovery Delay Time (tRFCmin)
+  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 26  Minimum Internal Write to Read Command Delay Time (tWTRmin)
+  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 27  Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 28  Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 29  Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_SDRAM_OPTIONAL_FEATURES_STRUCT  SdramOptionalFeatures;    ///< 30  SDRAM Optional Features
+  SPD_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions; ///< 31  SDRAMThermalAndRefreshOptions
+  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;      ///< 32  Module Thermal Sensor
+  SPD_SDRAM_DEVICE_TYPE_STRUCT        SdramDeviceType;          ///< 33  SDRAM Device Type
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 34  Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 35  Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 36  Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 37  Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 38  Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_AB_MTB_STRUCT               tRPab;                    ///< 39  Minimum Row Precharge Delay Time for all banks (tRPab)
+  SPD_TRP_AB_FTB_STRUCT               tRPabFine;                ///< 40  Fine Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
+  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 41 - pTRR support with TMAC value
+  UINT8                               Reserved3[59 - 42 + 1];   ///< 42 - 59 Reserved
+} SPD_GENERAL_SECTION;
+
+typedef struct {
+  SPD_UNBUF_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;      ///< 60 Module Nominal Height
+  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 61 Module Maximum Thickness
+  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 62 Reference Raw Card Used
+  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;   ///< 63 Address Mapping from Edge Connector to DRAM
+  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
+} SPD_MODULE_UNBUFFERED;
+
+typedef struct {
+  SPD_RDIMM_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;      ///< 60 Module Nominal Height
+  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 61 Module Maximum Thickness
+  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 62 Reference Raw Card Used
+  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///< 63 DIMM Module Attributes
+  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
+} SPD_MODULE_REGISTERED;
+
+typedef union {
+  SPD_MODULE_UNBUFFERED               Unbuffered;
+  SPD_MODULE_REGISTERED               Registered;
+} SPD_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                          ModulePartNumber[145 - 128 + 1];        ///< 128-145 Module Part Number
+} SPD_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                          ModuleRevisionCode[147 - 146 + 1];      ///< 146-147 Module Revision Code
+} SPD_MODULE_REVISION_CODE;
+
+typedef struct {
+  UINT8                          ManufactureSpecificData[175 - 150 + 1]; ///< 150-175 Manufacturer's Specific Data
+} SPD_MANUFACTURE_SPECIFIC;
+
+///
+/// DDR3 Serial Presence Detect structure
+///
+typedef struct {
+  SPD_GENERAL_SECTION         General;                                ///< 0-59 General Section
+  SPD_MODULE_SPECIFIC         Module;                                 ///< 60-116 Module-Specific Section
+  SPD_UNIQUE_MODULE_ID        ModuleId;                               ///< 117-125 Unique Module ID
+  SPD_CYCLIC_REDUNDANCY_CODE  Crc;                                    ///< 126-127 Cyclical Redundancy Code (CRC)
+  SPD_MODULE_PART_NUMBER      ModulePartNumber;                       ///< 128-145 Module Part Number
+  SPD_MODULE_REVISION_CODE    ModuleRevisionCode;                     ///< 146-147 Module Revision Code
+  SPD_MANUFACTURER_ID_CODE    DramIdCode;                             ///< 148-149 Dram Manufacturer ID Code
+  SPD_MANUFACTURE_SPECIFIC    ManufactureSpecificData;                ///< 150-175 Manufacturer's Specific Data
+  SPD_EXTREME_MEMORY_PROFILE  Xmp;                                    ///< 176-254 Intel(r) Extreme Memory Profile support
+  UINT8                       Reserved;                               ///< 255 Reserved
+} MrcSpdDdr3;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  2; ///< Bits 5:4
+    UINT8  BankGroup                           :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SignalLoading                       :  2; ///< Bits 1:0
+    UINT8                                      :  2; ///< Bits 3:2
+    UINT8  DieCount                            :  3; ///< Bits 6:4
+    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
+    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
+    UINT8                                      :  6; ///< Bits 7:2
+  } Bits;
+  UINT8  Data;
+} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCKmax                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD4_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKmaxFine                          :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD4_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0       Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                 Revision;                 ///< 1       SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2       DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3       Module Type
+  SPD4_SDRAM_DENSITY_BANKS_STRUCT     SdramDensityAndBanks;     ///< 4       SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5       SDRAM Addressing
+  SPD4_SDRAM_DEVICE_TYPE_STRUCT       SdramDeviceType;          ///< 6       SDRAM Device Type
+  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 7       pTRR support with TMAC value
+  SPD4_SDRAM_THERMAL_REFRESH_STRUCT   ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
+  UINT8                               Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
+  SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT  ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///< 12      Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
+  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;      ///< 14      Module Thermal Sensor
+  UINT8                               Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
+  SPD4_TIMEBASE_STRUCT                Timebase;                 ///< 17      Timebases
+  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 18      SDRAM Minimum Cycle Time (tCKmin)
+  SPD4_TCK_MAX_MTB_STRUCT             tCKmax;                   ///< 19      SDRAM Maximum Cycle Time (tCKmax)
+  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///< 20-23   CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 24      Minimum CAS Latency Time (tAAmin)
+  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 25      Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 26      Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///< 27      Upper Nibbles for tRAS and tRC
+  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 28      Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 29      Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 30-31   Minimum Refresh Recovery Delay Time (tRFC1min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 32-33   Minimum Refresh Recovery Delay Time (tRFC2min)
+  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 34-35   Minimum Refresh Recovery Delay Time (tRFC4min)
+  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///< 36      Upper Nibble for tFAW
+  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 37      Minimum Four Activate Window Delay Time (tFAWmin)
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 38      Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
+  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 39      Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
+  UINT8                               Reserved2[117 - 40 + 1];  ///< 40-117  Reserved
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 118     Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin), different bank group
+  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 119     Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same bank group
+  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 120     Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 121     Minimum Row Precharge Delay Time (tRPmin)
+  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 123     Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD4_TCK_MAX_FTB_STRUCT             tCKmaxFine;               ///< 124     Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
+  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 125     Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD4_BASE_SECTION;
+
+typedef struct {
+  SPD4_UNBUF_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;   ///< 131     Address Mapping from Edge Connector to DRAM
+  UINT8                               Reserved[253 - 132 + 1];  ///< 132-253 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_UNBUFFERED;
+
+typedef struct {
+  SPD4_RDIMM_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///< 131     DIMM Module Attributes
+  UINT8                               Reserved[253 - 132 + 1];  ///< 253-132 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD4_MODULE_REGISTERED;
+
+typedef union {
+  SPD4_MODULE_UNBUFFERED              Unbuffered;               ///< 128-255 Unbuffered Memory Module Types
+  SPD4_MODULE_REGISTERED              Registered;               ///< 128-255 Registered Memory Module Types
+} SPD4_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                               ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD4_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                               ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD4_MANUFACTURE_SPECIFIC;
+
+typedef UINT8                         SPD4_MODULE_REVISION_CODE;///< 349     Module Revision Code
+typedef UINT8                         SPD4_DRAM_STEPPING;       ///< 352     Dram Stepping
+
+typedef struct {
+  SPD_UNIQUE_MODULE_ID                ModuleId;                 ///< 320-328 Unique Module ID
+  SPD4_MODULE_PART_NUMBER             ModulePartNumber;         ///< 329-348 Module Part Number
+  SPD4_MODULE_REVISION_CODE           ModuleRevisionCode;       ///< 349     Module Revision Code
+  SPD_MANUFACTURER_ID_CODE            DramIdCode;               ///< 350-351 Dram Manufacturer ID Code
+  SPD4_DRAM_STEPPING                  DramStepping;             ///< 352     Dram Stepping
+  SPD4_MANUFACTURE_SPECIFIC           ManufactureSpecificData;  ///< 353-381 Manufacturer's Specific Data
+  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 382-383 Cyclical Redundancy Code (CRC)
+} SPD4_MANUFACTURING_DATA;
+
+typedef union {
+  SPD_EXTREME_MEMORY_PROFILE_2_0      Xmp;                      ///< 384-463 Intel(r) Extreme Memory Profile support
+  UINT8                               Reserved0[511 - 384 + 1]; ///< 384-511 Unbuffered Memory Module Types
+} SPD4_END_USER_SECTION;
+
+///
+/// DDR4 Serial Presence Detect structure
+///
+typedef struct {
+  SPD4_BASE_SECTION                   Base;                     ///< 0-127   Base Configuration and DRAM Parameters
+  SPD4_MODULE_SPECIFIC                Module;                   ///< 128-255 Module-Specific Section
+  UINT8                               Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+  SPD4_MANUFACTURING_DATA             ManufactureInfo;          ///< 320-383 Manufacturing Information
+  SPD4_END_USER_SECTION               EndUser;                  ///< 384-511 End User Programmable
+} MrcSpdDdr4;
+
+typedef union {
+  struct {
+    UINT8  Fine                                :  2; ///< Bits 1:0
+    UINT8  Medium                              :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_TIMEBASE_STRUCT;
+
+typedef union {
+  struct {
+    UINT32 CL3                                 :  1;  ///< Bits 0:0
+    UINT32 CL6                                 :  1;  ///< Bits 1:1
+    UINT32 CL8                                 :  1;  ///< Bits 2:2
+    UINT32 CL9                                 :  1;  ///< Bits 3:3
+    UINT32 CL10                                :  1;  ///< Bits 4:4
+    UINT32 CL11                                :  1;  ///< Bits 5:5
+    UINT32 CL12                                :  1;  ///< Bits 6:6
+    UINT32 CL14                                :  1;  ///< Bits 7:7
+    UINT32 CL16                                :  1;  ///< Bits 8:8
+    UINT32                                     :  1;  ///< Bits 9:9
+    UINT32 CL20                                :  1;  ///< Bits 10:10
+    UINT32 CL22                                :  1;  ///< Bits 11:11
+    UINT32 CL24                                :  1;  ///< Bits 12:12
+    UINT32                                     :  1;  ///< Bits 13:13
+    UINT32 CL28                                :  1;  ///< Bits 14:14
+    UINT32                                     :  1;  ///< Bits 15:15
+    UINT32 CL32                                :  1;  ///< Bits 16:16
+    UINT32                                     :  1;  ///< Bits 17:17
+    UINT32 CL36                                :  1;  ///< Bits 18:18
+    UINT32                                     :  1;  ///< Bits 19:19
+    UINT32 CL40                                :  1;  ///< Bits 20:20
+    UINT32                                     :  11; ///< Bits 31:21
+  } Bits;
+  UINT32 Data;
+  UINT16 Data16[2];
+  UINT8  Data8[4];
+} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Density                             :  4; ///< Bits 3:0
+    UINT8  BankAddress                         :  2; ///< Bits 5:4
+    UINT8  BankGroup                           :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  SignalLoading                       :  2; ///< Bits 1:0
+    UINT8  ChannelsPerDie                      :  2; ///< Bits 3:2
+    UINT8  DieCount                            :  3; ///< Bits 6:4
+    UINT8  SdramPackageType                    :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
+    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
+    UINT8  OperationAt1_10                     :  1; ///< Bits 2:2
+    UINT8  EndurantAt1_10                      :  1; ///< Bits 3:3
+    UINT8  OperationAtTBD2V                    :  1; ///< Bits 4:4
+    UINT8  EndurantAtTBD2V                     :  1; ///< Bits 5:5
+    UINT8                                      :  2; ///< Bits 7:6
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  tCKmax                              :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  ReadLatencyMode                     :  2; ///< Bits 1:0
+    UINT8  WriteLatencySet                     :  2; ///< Bits 3:2
+    UINT8                                      :  4; ///< Bits 7:4
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
+
+typedef union {
+  struct {
+    INT8  tCKmaxFine                           :  8; ///< Bits 7:0
+  } Bits;
+  INT8  Data;
+} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
+
+typedef union {
+  struct {
+    UINT8                                      :  8; ///< Bits 7:0
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
+
+typedef struct {
+  SPD_DEVICE_DESCRIPTION_STRUCT             Description;              ///< 0       Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+  SPD_REVISION_STRUCT                       Revision;                 ///< 1       SPD Revision
+  SPD_DRAM_DEVICE_TYPE_STRUCT               DramDeviceType;           ///< 2       DRAM Device Type
+  SPD_MODULE_TYPE_STRUCT                    ModuleType;               ///< 3       Module Type
+  SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;     ///< 4       SDRAM Density and Banks
+  SPD_SDRAM_ADDRESSING_STRUCT               SdramAddressing;          ///< 5       SDRAM Addressing
+  SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT       SdramPackageType;         ///< 6       SDRAM Package Type
+  SPD_PTRR_SUPPORT_STRUCT                   pTRRsupport;              ///< 7       pTRR support with TMAC value - SDRAM Optional Features
+  SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
+  UINT8                                     Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
+  SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
+  SPD_MODULE_ORGANIZATION_STRUCT            ModuleOrganization;       ///< 12      Module Organization
+  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT        ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
+  SPD_MODULE_THERMAL_SENSOR_STRUCT          ModuleThermalSensor;      ///< 14      Module Thermal Sensor
+  UINT8                                     Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
+  SPD_LPDDR_TIMEBASE_STRUCT                 Timebase;                 ///< 17      Timebases
+  SPD_TCK_MIN_MTB_STRUCT                    tCKmin;                   ///< 18      SDRAM Minimum Cycle Time (tCKmin)
+  SPD_LPDDR_TCK_MAX_MTB_STRUCT              tCKmax;                   ///< 19      SDRAM Maximum Cycle Time (tCKmax)
+  SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///< 20-23   CAS Latencies Supported
+  SPD_TAA_MIN_MTB_STRUCT                    tAAmin;                   ///< 24      Minimum CAS Latency Time (tAAmin)
+  SPD_LPDDR_RW_LATENCY_OPTION_STRUCT        LatencySetOptions;        ///< 25      Read and Write Latency Set Options
+  SPD_TRCD_MIN_MTB_STRUCT                   tRCDmin;                  ///< 26      Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TRP_AB_MTB_STRUCT                     tRPab;                    ///< 27      Minimum Row Precharge Delay Time (tRPab), all banks
+  SPD_TRP_PB_MTB_STRUCT                     tRPpb;                    ///< 28      Minimum Row Precharge Delay Time (tRPpb), per bank
+  SPD_TRFC_AB_MTB_STRUCT                    tRFCab;                   ///< 29-30   Minimum Refresh Recovery Delay Time (tRFCab), all banks
+  SPD_TRFC_PB_MTB_STRUCT                    tRFCpb;                   ///< 31-32   Minimum Refresh Recovery Delay Time (tRFCpb), per bank
+  UINT8                                     Reserved2[119 - 33 + 1];  ///< 33-119  Reserved
+  SPD_TRP_PB_FTB_STRUCT                     tRPpbFine;                ///< 120     Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
+  SPD_TRP_AB_FTB_STRUCT                     tRPabFine;                ///< 121     Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
+  SPD_TRCD_MIN_FTB_STRUCT                   tRCDminFine;              ///< 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+  SPD_TAA_MIN_FTB_STRUCT                    tAAminFine;               ///< 123     Fine Offset for Minimum CAS Latency Time (tAAmin)
+  SPD_LPDDR_TCK_MAX_FTB_STRUCT              tCKmaxFine;               ///< 124     Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
+  SPD_TCK_MIN_FTB_STRUCT                    tCKminFine;               ///< 125     Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+  SPD_CYCLIC_REDUNDANCY_CODE                Crc;                      ///< 126-127 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_BASE_SECTION;
+
+typedef union {
+  struct {
+    UINT8  FrontThickness                      :  4; ///< Bits 3:0
+    UINT8  BackThickness                       :  4; ///< Bits 7:4
+  } Bits;
+  UINT8 Data;
+} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
+
+typedef union {
+  struct {
+    UINT8  Height                              :  5; ///< Bits 4:0
+    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
+
+typedef union {
+  struct {
+    UINT8  Card                                :  5; ///< Bits 4:0
+    UINT8  Revision                            :  2; ///< Bits 6:5
+    UINT8  Extension                           :  1; ///< Bits 7:7
+  } Bits;
+  UINT8  Data;
+} SPD_LPDDR_REFERENCE_RAW_CARD;
+
+typedef struct {
+  SPD_LPDDR_MODULE_NOMINAL_HEIGHT         ModuleNominalHeight;      ///< 128     Module Nominal Height
+  SPD_LPDDR_MODULE_MAXIMUM_THICKNESS      ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
+  SPD_LPDDR_REFERENCE_RAW_CARD            ReferenceRawCardUsed;     ///< 130     Reference Raw Card Used
+  UINT8                                   Reserved[253 - 131 + 1];  ///< 131-253 Reserved
+  SPD_CYCLIC_REDUNDANCY_CODE              Crc;                      ///< 254-255 Cyclical Redundancy Code (CRC)
+} SPD_LPDDR_MODULE_LPDIMM;
+
+typedef union {
+  SPD_LPDDR_MODULE_LPDIMM                 LpDimm;                   ///< 128-255 Unbuffered Memory Module Types
+} SPD_LPDDR_MODULE_SPECIFIC;
+
+typedef struct {
+  UINT8                                   ModulePartNumber[348 - 329 + 1]; ///< 329-348 Module Part Number
+} SPD_LPDDR_MODULE_PART_NUMBER;
+
+typedef struct {
+  UINT8                                   ManufactureSpecificData[381 - 353 + 1]; ///< 353-381 Manufacturer's Specific Data
+} SPD_LPDDR_MANUFACTURE_SPECIFIC;
+
+typedef UINT8                             SPD_LPDDR_MODULE_REVISION_CODE;///< 349     Module Revision Code
+typedef UINT8                             SPD_LPDDR_DRAM_STEPPING;       ///< 352     Dram Stepping
+
+typedef struct {
+  SPD_UNIQUE_MODULE_ID                    ModuleId;                 ///< 320-328 Unique Module ID
+  SPD_LPDDR_MODULE_PART_NUMBER            ModulePartNumber;         ///< 329-348 Module Part Number
+  SPD_LPDDR_MODULE_REVISION_CODE          ModuleRevisionCode;       ///< 349     Module Revision Code
+  SPD_MANUFACTURER_ID_CODE                DramIdCode;               ///< 350-351 Dram Manufacturer ID Code
+  SPD_LPDDR_DRAM_STEPPING                 DramStepping;             ///< 352     Dram Stepping
+  SPD_LPDDR_MANUFACTURE_SPECIFIC          ManufactureSpecificData;  ///< 353-381 Manufacturer's Specific Data
+  UINT8                                   Reserved[383 - 382 + 1];  ///< 382-383 Reserved
+} SPD_LPDDR_MANUFACTURING_DATA;
+
+typedef union {
+  UINT8                                   Reserved0[511 - 384 + 1]; ///< 384-511 End User Programmable
+} SPD_LPDDR_END_USER_SECTION;
+
+typedef struct {
+  SPD_LPDDR_BASE_SECTION                  Base;                     ///< 0-127   Base Configuration and DRAM Parameters
+  SPD_LPDDR_MODULE_SPECIFIC               Module;                   ///< 128-255 Module-Specific Section
+  UINT8                                   Reserved0[319 - 256 + 1]; ///< 256-319 Reserved
+  SPD_LPDDR_MANUFACTURING_DATA            ManufactureInfo;          ///< 320-383 Manufacturing Information
+  SPD_LPDDR_END_USER_SECTION              EndUser;                  ///< 384-511 End User Programmable
+} MrcSpdLpDdr;
+
+typedef union {
+  MrcSpdDdr3  Ddr3;
+  MrcSpdDdr4  Ddr4;
+  MrcSpdLpDdr Lpddr;
+} MrcSpd;
+
+#ifndef MAX_SPD_SAVE
+#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
+                      sizeof (SPD_MANUFACTURING_LOCATION) + \
+                      sizeof (SPD_MANUFACTURING_DATE) + \
+                      sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
+                      sizeof (SPD4_MODULE_PART_NUMBER))
+#endif
+
+#pragma pack (pop)
+#endif // _MrcSpdData_h_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
new file mode 100644
index 0000000000..b267315f36
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
@@ -0,0 +1,237 @@
+/** @file
+  Include the the general MRC types
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _MRC_TYPES_H
+#define _MRC_TYPES_H
+
+#ifdef MRC_MINIBIOS_BUILD
+#include "MrcMiniBiosEfiDefs.h"
+#else
+#include <Base.h>
+#endif // MRC_MINIBIOS_BUILD
+
+//
+// Data Types
+//
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+typedef union {
+  struct {
+    INT32  Low;
+    INT32  High;
+  } Data32;
+  INT64 Data;
+} INT64_STRUCT;
+
+typedef union {
+  VOID    *Ptr;
+  UINTN   DataN;
+  UINT64  Data64;
+} POINTER_STRUCT;
+
+#define UNSUPPORT 0
+#define SUPPORT   1
+
+typedef enum {
+  mrcSuccess,
+  mrcFail,
+  mrcWrongInputParameter,
+  mrcCasError,
+  mrcTimingError,
+  mrcSenseAmpErr,
+  mrcReadMPRErr,
+  mrcReadLevelingError,
+  mrcWriteLevelingError,
+  mrcDataTimeCentering1DErr,
+  mrcWriteVoltage2DError,
+  mrcReadVoltage2DError,
+  mrcMiscTrainingError,
+  mrcWrError,
+  mrcDimmNotSupport,
+  mrcChannelNotSupport,
+  mrcPiSettingError,
+  mrcDqsPiSettingError,
+  mrcDeviceBusy,
+  mrcFrequencyChange,
+  mrcReutSequenceError,
+  mrcCrcError,
+  mrcFrequencyError,
+  mrcDimmNotExist,
+  mrcColdBootRequired,
+  mrcRoundTripLatencyError,
+  mrcMixedDimmSystem,
+  mrcAliasDetected,
+  mrcRetrain,
+  mrcRtpError,
+  mrcUnsupportedTechnology,
+  mrcMappingError,
+  mrcSocketNotSupported,
+  mrcControllerNotSupported,
+  mrcRankNotSupported,
+  mrcTurnAroundTripError
+} MrcStatus;
+
+//
+// general  macros
+//
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef ABS
+#define ABS(x)  (((x) < 0) ? (-(x)) : (x))
+#endif
+
+//
+// Make sure x is inside the range of [a..b]
+//
+#ifndef RANGE
+#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
+#endif
+
+#ifndef DIVIDECEIL
+#define DIVIDECEIL(a, b)   (((a) + (b) - 1) / (b))
+#endif
+
+#ifndef DIVIDEROUND
+#define DIVIDEROUND(a, b)  (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2) / (b))
+#endif
+
+#ifndef DIVIDEFLOOR
+#define DIVIDEFLOOR(a, b)  ((a) / (b))
+#endif
+
+//
+// Number of elements in a 1D array
+//
+#ifndef ARRAY_COUNT
+#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
+#endif
+
+//
+//  use for ignore parames
+//
+// #define MRC_IGNORE_PARAM(x) ((x) = (x))
+//
+#if _MSC_EXTENSIONS
+//
+// Disable warning that make it impossible to compile at /W4
+// This only works for Microsoft* tools
+//
+//
+// Disabling bitfield type checking warnings.
+//
+#pragma warning (disable : 4214)
+//
+// Unreferenced formal parameter - We are object oriented, so we pass parameters even
+//  if we don't need them.
+//
+#pragma warning (disable : 4100)
+//
+// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
+//
+#pragma warning(disable : 4127)
+//
+// The given function was selected for inline expansion, but the compiler did not perform the inlining.
+//
+#pragma warning(disable : 4710)
+
+#endif // _MSC_EXTENSIONS
+#define MRC_BIT0          0x00000001
+#define MRC_BIT1          0x00000002
+#define MRC_BIT2          0x00000004
+#define MRC_BIT3          0x00000008
+#define MRC_BIT4          0x00000010
+#define MRC_BIT5          0x00000020
+#define MRC_BIT6          0x00000040
+#define MRC_BIT7          0x00000080
+#define MRC_BIT8          0x00000100
+#define MRC_BIT9          0x00000200
+#define MRC_BIT10         0x00000400
+#define MRC_BIT11         0x00000800
+#define MRC_BIT12         0x00001000
+#define MRC_BIT13         0x00002000
+#define MRC_BIT14         0x00004000
+#define MRC_BIT15         0x00008000
+#define MRC_BIT16         0x00010000
+#define MRC_BIT17         0x00020000
+#define MRC_BIT18         0x00040000
+#define MRC_BIT19         0x00080000
+#define MRC_BIT20         0x00100000
+#define MRC_BIT21         0x00200000
+#define MRC_BIT22         0x00400000
+#define MRC_BIT23         0x00800000
+#define MRC_BIT24         0x01000000
+#define MRC_BIT25         0x02000000
+#define MRC_BIT26         0x04000000
+#define MRC_BIT27         0x08000000
+#define MRC_BIT28         0x10000000
+#define MRC_BIT29         0x20000000
+#define MRC_BIT30         0x40000000
+#define MRC_BIT31         0x80000000
+#define MRC_BIT32        0x100000000ULL
+#define MRC_BIT33        0x200000000ULL
+#define MRC_BIT34        0x400000000ULL
+#define MRC_BIT35        0x800000000ULL
+#define MRC_BIT36       0x1000000000ULL
+#define MRC_BIT37       0x2000000000ULL
+#define MRC_BIT38       0x4000000000ULL
+#define MRC_BIT39       0x8000000000ULL
+#define MRC_BIT40      0x10000000000ULL
+#define MRC_BIT41      0x20000000000ULL
+#define MRC_BIT42      0x40000000000ULL
+#define MRC_BIT43      0x80000000000ULL
+#define MRC_BIT44     0x100000000000ULL
+#define MRC_BIT45     0x200000000000ULL
+#define MRC_BIT46     0x400000000000ULL
+#define MRC_BIT47     0x800000000000ULL
+#define MRC_BIT48    0x1000000000000ULL
+#define MRC_BIT49    0x2000000000000ULL
+#define MRC_BIT50    0x4000000000000ULL
+#define MRC_BIT51    0x8000000000000ULL
+#define MRC_BIT52   0x10000000000000ULL
+#define MRC_BIT53   0x20000000000000ULL
+#define MRC_BIT54   0x40000000000000ULL
+#define MRC_BIT55   0x80000000000000ULL
+#define MRC_BIT56  0x100000000000000ULL
+#define MRC_BIT57  0x200000000000000ULL
+#define MRC_BIT58  0x400000000000000ULL
+#define MRC_BIT59  0x800000000000000ULL
+#define MRC_BIT60 0x1000000000000000ULL
+#define MRC_BIT61 0x2000000000000000ULL
+#define MRC_BIT62 0x4000000000000000ULL
+#define MRC_BIT63 0x8000000000000000ULL
+
+#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
+
+#ifndef ASM
+#define ASM __asm
+#endif
+
+///
+/// Type Max/Min Values
+///
+#define MRC_INT32_MAX   (0x7FFFFFFF)
+#define MRC_INT32_MIN   (0x80000000)
+#define MRC_INT64_MAX   (0x7FFFFFFFFFFFFFFFLL)
+#define MRC_INT64_MIN   (0x8000000000000000LL)
+#define MRC_UINT32_MAX  (0xFFFFFFFF)
+#define MRC_UINT64_MAX  (0xFFFFFFFFFFFFFFFFULL)
+#define MRC_UINT_MIN    (0x0)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
new file mode 100644
index 0000000000..d444e937d6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
@@ -0,0 +1,15 @@
+/** @file
+  This file includes all the data structures that the MRC considers "global data".
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _UNIFIED_MrcInterface_h_
+#define _UNIFIED_MrcInterface_h_
+
+#include "Coffeelake/MrcInterface.h"
+
+#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
new file mode 100644
index 0000000000..82d798b783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
@@ -0,0 +1,50 @@
+/** @file
+  Header file for initialization of GT PowerManagement
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GRAPHICS_INIT_H_
+#define _GRAPHICS_INIT_H_
+
+#include <Library/DxeServicesTableLib.h>
+#include <Guid/DxeServices.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Library/PciSegmentLib.h>
+#include <SaAccess.h>
+#include <Protocol/SaPolicy.h>
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <PchAccess.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
new file mode 100644
index 0000000000..0e95db3d02
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
@@ -0,0 +1,193 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IGD_OPREGION_INIT_H_
+#define _IGD_OPREGION_INIT_H_
+
+///
+/// Statements that include other header files.
+///
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PchAccess.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <SaAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <CpuRegs.h>
+#include <SaInit.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <SiConfigHob.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/SaPolicy.h>
+
+
+#include <Private/Protocol/SaNvsArea.h>
+
+///
+/// Driver Produced Protocol Prototypes
+///
+#include <Protocol/IgdOpRegion.h>
+
+///
+///
+/// OpRegion (Miscellaneous) defines.
+///
+/// OpRegion Header defines.
+///
+typedef UINT16  STRING_REF;
+#define HEADER_SIGNATURE            "IntelGraphicsMem"
+#define HEADER_SIZE                 0x2000
+#define HEADER_OPREGION_VER         0x0200
+#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 BLC_ENABLE            BIT1
+#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
+///
+#pragma pack(1)
+typedef struct {
+  UINT16  Signature;  /// 0xAA55
+  UINT8   Size512;
+  UINT8   Reserved[21];
+  UINT16  PcirOffset;
+  UINT16  VbtOffset;
+} INTEL_VBIOS_OPTION_ROM_HEADER;
+#pragma pack()
+
+#pragma pack(1)
+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;
+#pragma pack()
+
+#pragma pack(1)
+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()
+///
+/// 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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
new file mode 100644
index 0000000000..34a2809f80
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
@@ -0,0 +1,91 @@
+/** @file
+  Header file for PciExpress Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
+
+#include <Library/HobLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/Msr.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Private/SaConfigHob.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/Protocol/SaNvsArea.h>
+
+#define GEN1      1
+#define GEN2      2
+
+///
+/// Function prototypes
+///
+/**
+  PCI Express Dxe Initialization.
+  Run before PCI Bus Init, where assignment of Bus, Memory,
+    and I/O Resources are assigned.
+
+  @param[in] SaPolicy    -     SA DXE Policy protocol
+
+  @retval EFI_SUCCESS        - Pci Express successfully started and ready to be used
+  @exception EFI_UNSUPPORTED - Pci Express can't be initialized
+**/
+EFI_STATUS
+PciExpressInit (
+  IN SA_POLICY_PROTOCOL *SaPolicy
+  );
+
+/**
+  Find the Offset to a given 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 fo
+
+  @retval 0       - CAPID not found
+  @retval Other   - CAPID found, Offset of desired CAPID
+**/
+UINT32
+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
+
+  @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
+**/
+UINT32
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
new file mode 100644
index 0000000000..73af27e9d7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
@@ -0,0 +1,23 @@
+/** @file
+  This is header file for SA PCIE Root Complex initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+  VOID
+  );
+
+/**
+  This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Save/restore has done
+  @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+  VOID
+  );
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
new file mode 100644
index 0000000000..d7e2423ffd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for SA Common Initialization Driver.
+
+  Copyright (c) 2019 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 <CpuRegs.h>
+#include <SaAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/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
+  );
+
+/**
+  Common function locks the PAM register as part of the SA Security requirements.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+SaPamLock (
+  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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
new file mode 100644
index 0000000000..1991fd82c4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
@@ -0,0 +1,139 @@
+/** @file
+  Header file for SA Initialization Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
+#define _SA_INITIALIZATION_DXE_DRIVER_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include "VTd.h"
+#include "PcieComplex.h"
+#include "IgdOpRegionInit.h"
+#include <Private/Library/LegacyRegion.h>
+#include "GraphicsInit.h"
+#include "PciExpressInit.h"
+#include "SwitchableGraphicsInit.h"
+#include <Library/CpuPlatformLib.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/SaPolicy.h>
+
+extern EFI_GUID gSaAcpiTableStorageGuid;
+extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
+extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
+
+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 SA 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.
+
+  @retval EFI_SUCCESS   - Always.
+
+**/
+VOID
+EFIAPI
+SaPciEnumCompleteCallback (
+  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
+  );
+
+/**
+  This function locks the PAM register as part of the SA Security requirements.
+
+  @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 EFI_SUCCESS   - Always.
+**/
+VOID
+EFIAPI
+SaPamLockDxe (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
new file mode 100644
index 0000000000..2b1b4c5880
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
@@ -0,0 +1,17 @@
+/** @file
+  Header file for the SwitchableGraphics Dxe driver.
+  This driver loads SwitchableGraphics ACPI tables.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
+#define _SWITCHABLE_GRAPHICS_DXE_H_
+
+
+#include <Protocol/FirmwareVolume2.h>
+
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
new file mode 100644
index 0000000000..c4bc47f7fe
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
@@ -0,0 +1,53 @@
+/** @file
+  This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _VT_D_H_
+#define _VT_D_H_
+
+///
+/// Include files
+///
+#include <DmaRemappingTable.h>
+#include <SaAccess.h>
+#include <PchAccess.h>
+#include <Uefi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Private/PchConfigHob.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <IndustryStandard/Pci22.h>
+
+
+#define VTD_ECAP_REG  0x10
+#define IR            BIT3
+
+/**
+  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
+  );
+
+/**
+  PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..02c74c0672
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
@@ -0,0 +1,162 @@
+/** @file
+  Header file for SMM Access Driver.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H_
+#define _SMM_ACCESS_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <Guid/SmramMemoryReserve.h>
+#include <Protocol/SmmAccess2.h>
+#include <IndustryStandard/Pci22.h>
+#include <SaAccess.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a')
+
+///
+/// Private data
+///
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle;
+  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
+
+  ///
+  /// Local Data for SMM Access interface goes here
+  ///
+  UINTN                           NumberRegions;
+  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+  CR (a, \
+      SMM_ACCESS_PRIVATE_DATA, \
+      SmmAccess, \
+      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+      )
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+/**
+  <b>SMM Access Driver Entry Point</b>
+  This driver installs an SMM Access Protocol
+  - <b>Introduction</b> \n
+    This module publishes the SMM access protocol.  The protocol is used by the SMM Base driver to access the SMRAM region when the processor is not in SMM.
+    The SMM Base driver uses the services provided by the SMM access protocol to open SMRAM during post and copy the SMM handler.
+    SMM access protocol is also used to close the SMRAM region once the copying is done.
+    Finally, the SMM access protocol provides services to "Lock" the SMRAM region.
+    Please refer the SMM Protocols section in the attached SMM CIS Specification version 0.9 for further details.
+    This driver is required if SMM is supported. Proper configuration of SMM registers is recommended even if SMM is not supported.
+
+  - @result
+    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System Management Mode Core Interface Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>Porting Recommendations</b> \n
+    No modification of this module is recommended.  Any modification should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL protocol definition.
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS     - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED - Protocol was not installed
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by
+                            chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  );
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                          one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                            buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                            region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                   *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
new file mode 100644
index 0000000000..5daa2367e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
@@ -0,0 +1,157 @@
+/** @file
+  DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GraphicsInit.h"
+#include "SaInit.h"
+#include <Protocol/LegacyBios.h>
+#include <Protocol/GopComponentName2.h>
+#include <SiConfigHob.h>
+
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64                        mGttMmAdr;
+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_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  EFI_STATUS                Status;
+  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
+  EFI_PEI_HOB_POINTERS      HobPtr;
+  SI_CONFIG_HOB_DATA        *SiConfigHobData;
+
+  ///
+  /// Get the platform setup policy.
+  ///
+  DriverVersion = NULL;
+  LegacyBios = NULL;
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
+  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  if (SiConfigHobData->CsmFlag == 1) {
+    Status = gBS->LocateProtocol (
+                    &gEfiLegacyBiosProtocolGuid,
+                    NULL,
+                    (VOID **) &LegacyBios
+                    );
+  }
+
+  if (LegacyBios == NULL) {
+    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;
+
+  mGttMmAdr               = 0;
+  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);
+
+  ///
+  /// Update IGD SA Global NVS
+  ///
+  DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
+
+  mSaNvsAreaProtocol.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) {
+    mSaNvsAreaProtocol.Area->IgdState = 1;
+  } else {
+    mSaNvsAreaProtocol.Area->IgdState = 0;
+  }
+
+  mSaNvsAreaProtocol.Area->BrightnessPercentage         = 100;
+  mSaNvsAreaProtocol.Area->IgdBootType                  = GraphicsDxeConfig->IgdBootType;
+  mSaNvsAreaProtocol.Area->IgdPanelType                 = GraphicsDxeConfig->IgdPanelType;
+  mSaNvsAreaProtocol.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.
+  ///
+  mSaNvsAreaProtocol.Area->IgdDvmtMemSize               = GraphicsDxeConfig->IgdDvmtMemSize;
+  mSaNvsAreaProtocol.Area->IgdFunc1Enable               = 0;
+  mSaNvsAreaProtocol.Area->IgdHpllVco                   = MmioRead8 (mMchBarBase.Data + 0xC0F) & 0x07;
+  mSaNvsAreaProtocol.Area->IgdSciSmiMode                = 0;
+  mSaNvsAreaProtocol.Area->GfxTurboIMON                 = GraphicsDxeConfig->GfxTurboIMON;
+
+  mSaNvsAreaProtocol.Area->EdpValid                     = 0;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
new file mode 100644
index 0000000000..6ec0691074
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
@@ -0,0 +1,570 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "IgdOpRegionInit.h"
+
+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;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &mSaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &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_PCIR_STRUCTURE    *PcirBlockPtr;
+  UINT32                        PcirBlockAddress;
+  UINT16                        PciVenderId;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
+  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
+  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;
+  EFI_STATUS                    Status;
+  VBIOS_VBT_STRUCTURE           *VbtFileBuffer;
+  UINTN                         Index;
+  UINT8                         LegacyVbtFound;
+  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
+  EFI_PEI_HOB_POINTERS          HobPtr;
+  SI_CONFIG_HOB_DATA            *SiConfigHobData;
+
+  VbtFileBuffer = NULL;
+  LegacyVbtFound = 1;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &mSaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  LegacyBios = NULL;
+  VBiosPtr = NULL;
+  //
+  // Get Silicon Config data HOB
+  //
+  HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA (HobPtr.Guid);
+  if (SiConfigHobData->CsmFlag == 1) {
+    Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+
+    if (LegacyBios) {
+      VBiosPtr      = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN) (VBIOS_LOCATION_PRIMARY);
+      PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
+      PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN) (PcirBlockAddress);
+      PciVenderId   = PcirBlockPtr->VendorId;
+      ///
+      /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
+      /// the integrated Intel video BIOS (must be uncompressed).
+      ///
+      if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+        GetIntegratedIntelVBiosPtr (&VBiosPtr);
+        if (VBiosPtr != NULL) {
+          ///
+          /// Video BIOS found.
+          ///
+          PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->PcirOffset);
+          PciVenderId   = PcirBlockPtr->VendorId;
+
+          if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != V_SA_MC_VID)) {
+            ///
+            /// Intel video BIOS not found.
+            ///
+            VBiosVbtPtr = NULL;
+            LegacyVbtFound = 0;
+          }
+        }
+      }
+    }
+  }
+  if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
+    ///
+    /// No Video BIOS found, 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"));
+      for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
+      }
+      Index = (Index+1)*2;
+      CopyMem (mIgdOpRegion.OpRegion->Header.DVER, GraphicsDxeConfig->GopVersion, Index);
+      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;
+
+  ///
+  /// 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);
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
+  /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
+  /// area structure.
+  ///
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
+  ASSERT_EFI_ERROR (Status);
+
+  SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE), 0);
+  SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN) (mIgdOpRegion.OpRegion);
+
+  ///
+  /// If IGD is disabled return
+  ///
+  IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 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, 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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
new file mode 100644
index 0000000000..bbdf0d0fab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
@@ -0,0 +1,171 @@
+/** @file
+  This driver does SA PCI Express ACPI table initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+
+extern SYSTEM_AGENT_NVS_AREA_PROTOCOL   mSaNvsAreaProtocol;
+extern SA_CONFIG_HOB                    *mSaConfigHob;
+
+/**
+  PCI Express Dxe Initialization.
+  Run before PCI Bus Init, where assignment of Bus, Memory,
+    and I/O Resources are assigned.
+
+  @param[in] SaPolicy     -     SA DXE Policy protocol
+
+  @retval EFI_SUCCESS     - Pci Express successfully started and ready to be used
+**/
+EFI_STATUS
+PciExpressInit (
+  IN SA_POLICY_PROTOCOL *SaPolicy
+  )
+{
+  EFI_STATUS                                    Status;
+  PCIE_DXE_CONFIG                               *PcieDxeConfig;
+  MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  Msr.Uint64 = AsmReadMsr64 (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
+  mSaNvsAreaProtocol.Area->PackageCstateLimit  = (UINT8) Msr.Bits.Limit;
+
+  mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable  = 0;
+
+  if (mSaConfigHob != NULL) {
+    mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[0];
+    mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[1];
+    mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[2];
+    if (SA_PEG_MAX_FUN > 3) {
+      mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles  = mSaConfigHob->PowerDownUnusedBundles[3];
+    }
+  }
+  ///
+  /// LTR/OBFF
+  ///
+  mSaNvsAreaProtocol.Area->Peg0LtrEnable                = PcieDxeConfig->PegPwrOpt[0].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg0ObffEnable               = PcieDxeConfig->PegPwrOpt[0].ObffEnable;
+  mSaNvsAreaProtocol.Area->Peg1LtrEnable                = PcieDxeConfig->PegPwrOpt[1].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg1ObffEnable               = PcieDxeConfig->PegPwrOpt[1].ObffEnable;
+  mSaNvsAreaProtocol.Area->Peg2LtrEnable                = PcieDxeConfig->PegPwrOpt[2].LtrEnable;
+  mSaNvsAreaProtocol.Area->Peg2ObffEnable               = PcieDxeConfig->PegPwrOpt[2].ObffEnable;
+  mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency        = LTR_MAX_SNOOP_LATENCY_VALUE;
+  mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency      = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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
+**/
+UINT32
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  )
+{
+  UINT64 DeviceBaseAddress;
+  UINT8  CapHeader;
+
+  ///
+  /// Always start at Offset 0x34
+  ///
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  CapHeader         = PciSegmentRead8 (DeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+  if (CapHeader == 0xFF) {
+    return 0;
+  }
+
+  while (CapHeader != 0) {
+    ///
+    /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
+    ///
+    CapHeader &= ~(BIT1 + BIT0);
+    ///
+    /// Search for desired CapID
+    ///
+    if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
+      return CapHeader;
+    }
+
+    CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
+  }
+
+  return 0;
+}
+
+/**
+  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
+**/
+UINT32
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+
+  ///
+  /// Start to search at Offset 0x100
+  /// Get Capability Header
+  ///
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  CapHeaderId     = 0;
+  CapHeaderOffset = 0x100;
+
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    ///
+    /// Search for desired CapID
+    ///
+    CapHeaderId = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+
+    CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 2) >> 4);
+  }
+
+  return 0;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
new file mode 100644
index 0000000000..1dc37334ae
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
@@ -0,0 +1,171 @@
+/** @file
+  This file will perform SA PCIE Root Complex initialization.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PciExpressInit.h"
+#include <Private/Library/SaPcieLib.h>
+#include "PcieComplex.h"
+#include <Private/Protocol/SaIotrapSmi.h>
+#include "SaInit.h"
+
+///
+/// Global variables
+///
+UINT16                                 mSaIotrapSmiAddress;
+extern SA_CONFIG_HOB                   *mSaConfigHob;
+
+///
+/// Functions
+///
+/**
+    This function gets registered as a callback to perform all SA late initialization
+
+    @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
+SaLateInitSmiCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                 Status;
+  SA_IOTRAP_SMI_PROTOCOL     *SaIotrapSmiProtocol;
+
+  if (mSaIotrapSmiAddress == 0) {
+    //
+    // Use global variable instead of protocol data since it maybe tampered in unsecure environment
+    // Get IOTrap address when first time this routine calling (gEfiPciEnumerationCompleteProtocolGuid callback)
+    //
+    SaIotrapSmiProtocol = NULL;
+    Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **) &SaIotrapSmiProtocol);
+    ASSERT_EFI_ERROR (Status);
+    if (SaIotrapSmiProtocol != NULL) {
+      mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
+    }
+  }
+
+  ASSERT (mSaIotrapSmiAddress != 0);
+  if (mSaIotrapSmiAddress != 0) {
+    //
+    // Generate IOTRAP SMI immediately
+    //
+    DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n", mSaIotrapSmiAddress));
+    IoWrite8 (mSaIotrapSmiAddress, 0);
+  }
+  if (Event != NULL) {
+    gBS->CloseEvent (Event);
+  }
+  return;
+}
+
+/**
+  This function performs Peg initialization before EndOfDxe.
+  @note This function will be executed as gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA DXE/SMM drivers have been dispatched.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+EFI_STATUS
+PegInitBeforeEndOfDxe (
+  VOID
+  )
+{
+  EFI_EVENT                       ReadyToBoot;
+  EFI_STATUS                      Status;
+  BOOLEAN                         AspmHasBeenHandled;
+
+  DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
+  AspmHasBeenHandled = FALSE;
+  ///
+  /// SMM mode ASPM handling
+  /// Check if supported and enabled
+  ///
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+    ///
+    /// Do the Phase 1 SMI callback
+    /// This will enumerate PCIe downstream devices
+    ///
+    SaLateInitSmiCallback (NULL, NULL);
+
+    if (mSaIotrapSmiAddress != 0) {
+      ///
+      /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
+      /// This will handle PEG ASPM programming after OROM execution
+      /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
+      ///       to initialize rest of PCIe settings prior to OPROM
+      ///
+      Status = EfiCreateEventReadyToBootEx (
+                 TPL_NOTIFY,
+                 (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
+                 NULL,
+                 &ReadyToBoot
+                 );
+      ASSERT_EFI_ERROR (Status);
+      AspmHasBeenHandled = TRUE;
+    }
+  }
+
+  ///
+  /// DXE mode ASPM handling
+  /// Check if SMM mode already taken care all things
+  /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
+  ///
+  if (AspmHasBeenHandled == FALSE) {
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function performs SA registers Saving/Restoring in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Save/restore has done
+  @retval EFI_UNSUPPORTED - Save/restore not done successfully
+**/
+EFI_STATUS
+SaSaveRestore (
+  VOID
+  )
+{
+  BOOLEAN                         SaveRestoreHasBeenHandled;
+  UINT8                           SmiData;
+
+  SaveRestoreHasBeenHandled = FALSE;
+
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom == TRUE)) {
+    ///
+    /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and security lock
+    ///
+    SaLateInitSmiCallback (NULL, NULL);
+
+    if (mSaIotrapSmiAddress != 0) {
+      ///
+      /// Store IOTRAP SMI address into Boot Script save table
+      /// This is required to trigger this IOTRAP during S3 resume to restore all settings
+      ///
+      SmiData = 0;
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) mSaIotrapSmiAddress,
+        1,
+        &SmiData
+        );
+      SaveRestoreHasBeenHandled = TRUE;
+    }
+  }
+
+  ///
+  /// Check if SMM mode already taken care this task
+  ///
+  if (SaveRestoreHasBeenHandled == TRUE) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
new file mode 100644
index 0000000000..d5a63785b4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
@@ -0,0 +1,496 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Private/Protocol/SaNvsArea.h>
+#include <Library/PchInfoLib.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;
+
+/**
+  Initialize System Agent SSDT ACPI tables
+
+  @retval EFI_SUCCESS    ACPI tables are initialized successfully
+  @retval EFI_NOT_FOUND  ACPI tables not found
+**/
+EFI_STATUS
+InitializeSaSsdtAcpiTables (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         NumberOfHandles;
+  EFI_FV_FILETYPE               FileType;
+  UINT32                        FvStatus;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINTN                         Size;
+  UINTN                         i;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  INTN                          Instance;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINTN                         AcpiTableKey;
+  UINT8                         *CurrPtr;
+  UINT8                         *EndPtr;
+  UINT32                        *Signature;
+  EFI_ACPI_DESCRIPTION_HEADER   *SaAcpiTable;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+
+  FwVol       = NULL;
+  SaAcpiTable = NULL;
+
+  ///
+  /// Locate ACPI Table protocol
+  ///
+  DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  ///
+  /// 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,
+                      &gSaSsdtAcpiTableStorageGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (Status == EFI_SUCCESS) {
+      break;
+    }
+  }
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol != NULL);
+  if (FwVol == NULL) {
+    DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
+    return EFI_NOT_FOUND;
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  /// Read tables from the storage file.
+  ///
+  Instance      = 0;
+  CurrentTable  = NULL;
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gSaSsdtAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// Check the table ID to modify the table
+      ///
+      if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
+        SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+        ///
+        /// Locate the SSDT package
+        ///
+        CurrPtr = (UINT8 *) SaAcpiTable;
+        EndPtr  = CurrPtr + SaAcpiTable->Length;
+
+        for (; CurrPtr <= EndPtr; CurrPtr++) {
+          Signature = (UINT32 *) (CurrPtr + 3);
+          if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
+            ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) == 0xFFFF0000);
+            ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) == 0xAA55);
+            ///
+            /// SA Global NVS Area address
+            ///
+            *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN) mSaNvsAreaProtocol.Area;
+            ///
+            /// SA Global NVS Area size
+            ///
+            *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) + 1) =
+              sizeof (SYSTEM_AGENT_NVS_AREA);
+
+            AcpiTableKey = 0;
+            Status = AcpiTable->InstallAcpiTable (
+                                  AcpiTable,
+                                  SaAcpiTable,
+                                  SaAcpiTable->Length,
+                                  &AcpiTableKey
+                                  );
+            ASSERT_EFI_ERROR (Status);
+            return EFI_SUCCESS;
+          }
+        }
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  return Status;
+
+}
+
+/**
+  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 SwitchableGraphics 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, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 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, SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 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;
+  CPU_FAMILY                CpuFamilyId;
+  EFI_EVENT                 EndOfDxeEvent;
+
+  CpuFamilyId = GetCpuFamily();
+  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 (PcdPciExpressBaseAddress));
+  mSaNvsAreaProtocol.Area->CpuIdInfo            = CpuidRegs.RegEax;
+  if (mSaConfigHob != NULL) {
+    mSaNvsAreaProtocol.Area->IpuAcpiMode = mSaConfigHob->IpuAcpiMode;
+  }
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaNvsAreaProtocolGuid,
+                  &mSaNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// PciExpress Dxe Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
+  PciExpressInit (mSaPolicy);
+
+  ///
+  /// GtPostInit Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
+
+  GraphicsInit (ImageHandle, mSaPolicy);
+
+  /// 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 = InitializeSaSsdtAcpiTables ();
+
+  ///
+  /// Install PEG SSDT table only if PEG port is present
+  ///
+  if (IsPchLinkDmi (CpuFamilyId)) {
+    if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
+      Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid, SIGNATURE_64 ('P','e','g','S','s','d','t',0));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
new file mode 100644
index 0000000000..40bb107ad0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
@@ -0,0 +1,179 @@
+/** @file
+  This is the Common driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInit.h"
+#include <Library/PciSegmentLib.h>
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+//
+// Declare I/O Ports used to perform PCI Confguration Cycles
+//
+#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8
+#define PCI_CONFIGURATION_DATA_PORT     0xCFC
+
+/**
+  Convert a PCI Library address to PCI CF8 formatted address.
+
+  Declare macro to convert PCI Library address to PCI CF8 formatted address.
+  Bit fields of PCI Library and CF8 formatted address is as follows:
+  PCI Library formatted address    CF8 Formatted Address
+ =============================    ======================
+    Bits 00..11  Register           Bits 00..07  Register
+    Bits 12..14  Function           Bits 08..10  Function
+    Bits 15..19  Device             Bits 11..15  Device
+    Bits 20..27  Bus                Bits 16..23  Bus
+    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)
+                                    Bits 31..31  Must be 1
+
+  @param  A The address to convert.
+
+  @retval The coverted address.
+
+**/
+#define PCI_TO_CF8_ADDRESS(A) \
+  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
+
+///
+/// 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 SaPcieInitPolicy().
+*/
+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
+  )
+{
+  ///
+  /// Get SaConfigHob HOB
+  ///
+  mSaConfigHob              = NULL;
+  mSaConfigHob              = (SA_CONFIG_HOB *) GetFirstGuidHob (&gSaConfigHobGuid);
+  if (mSaConfigHob != NULL) {
+    mSkipPamLock = mSaConfigHob->SkipPamLock;
+  }
+
+  return;
+}
+
+
+
+/**
+  Common function locks the PAM register as part of the SA Security requirements.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+
+VOID
+SaPamLock (
+  VOID
+  )
+{
+  UINT64 BaseAddress;
+  UINT32 Data32Or;
+
+  if (mSkipPamLock == FALSE) {
+    //
+    // Lock PAM by PAM Lock Bit
+    //
+    BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
+    Data32Or    = BIT0;
+    DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
+    PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
+  }
+}
+
+/**
+  This function does SA security lock
+**/
+VOID
+SaSecurityLock (
+  VOID
+  )
+{
+  UINT8           Index;
+  UINT32          RegOffset;
+  UINT32          Data32Or;
+  UINT32          Data32;
+  UINT8           Data8;
+
+  ///
+  /// 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++) {
+    RegOffset   = mSaSecurityRegisters[Index].Offset;
+    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);
+      Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+      Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint32,
+        (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
+        1,
+        &Data32
+        );
+      S3BootScriptSaveIoWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) (PCI_CONFIGURATION_DATA_PORT),
+        1,
+        &Data8
+        );
+    }
+  }
+}
+
+/**
+  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 (PcdPciExpressBaseAddress);
+    }
+  }
+  SaSecurityLock ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
new file mode 100644
index 0000000000..d646e60618
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
@@ -0,0 +1,122 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <Private/SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <MemInfoHob.h>
+
+///
+/// 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;
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
+
+  SaInitEntryPoint ();
+
+  Status = SaAcpiInit (ImageHandle);
+
+  ///
+  /// Create PCI Enumeration Completed callback for SA
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    SaPciEnumCompleteCallback,
+    NULL,
+    &Registration
+    );
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform SA 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
+SaPciEnumCompleteCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+  VOID                *ProtocolPointer;
+
+  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback 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);
+
+  Status = PegInitBeforeEndOfDxe ();
+  if (EFI_SUCCESS != Status) {
+    DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error, Status = %r \n", Status));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  SaSaveRestore ();
+  SaSecurityInit ();
+  UpdateDmarPciEnumCompleteCallback ();
+
+  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
+  return;
+}
+
+/**
+  This function locks the PAM register as part of the SA Security requirements.
+
+  @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
+SaPamLockDxe (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
+
+  SaPamLock ();
+
+  DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
new file mode 100644
index 0000000000..acbf6b7aab
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
@@ -0,0 +1,717 @@
+/** @file
+  This code provides a initialization of intel VT-d (Virtualization Technology for Directed I/O).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include "VTd.h"
+#include <CpuRegs.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <PchInfoHob.h>
+#include <PchAccess.h>
+
+
+extern SA_CONFIG_HOB                                          *mSaConfigHob;
+
+/**
+  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}, {0x1400, 0x80}, {0x1401, 0x80}, {0x1607, 0x8F}};
+
+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 < sizeof (mDevEnMap) / 4; 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 (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 (PcdIoApicBaseAddress);
+  ///
+  /// Get current IO APIC ID
+  ///
+  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
+  IoApicId = MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_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) {
+      NeedRemove = FALSE;
+    }
+    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;
+  UINTN               MchBar;
+  UINT16              IgdMode;
+  UINT16              GttMode;
+  UINT32              IgdMemSize;
+  UINT32              GttMemSize;
+  EFI_STATUS          Status;
+  MISC_DXE_CONFIG     *MiscDxeConfig;
+
+  IgdMemSize  = 0;
+  GttMemSize  = 0;
+  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
+
+  Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
+  ///
+  if (mInterruptRemappingSupport) {
+    DmarTable->DmarHeader.Flags |= BIT0;
+  }
+
+  if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
+    DmarTable->DmarHeader.Flags |= BIT1;
+  } else {
+    DmarTable->DmarHeader.Flags &= 0xFD;
+  }
+
+  ///
+  /// 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);
+  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+  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);
+  }
+
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   = (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) - IgdMemSize - GttMemSize;
+  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));
+
+  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress   = MiscDxeConfig->RmrrUsbBaseAddress[0];
+  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress  = MiscDxeConfig->RmrrUsbBaseAddress[1];
+
+  ///
+  /// Convert to 4KB alignment.
+  ///
+  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress != 0x0) {
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress  &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
+    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress += 0x1000-1;
+  }
+
+  DEBUG ((DEBUG_INFO, "RMRR Base  address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n", DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress == 0) {
+    DEBUG ((DEBUG_WARN, "WARNING:  RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
+  }
+
+  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress   = MiscDxeConfig->RmrrCsmeBaseAddress[0];
+  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress  = MiscDxeConfig->RmrrCsmeBaseAddress[1];
+  DEBUG ((DEBUG_INFO, "RMRR Base  address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n", DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
+  ///
+  /// Update DRHD structures of DmarTable
+  ///
+  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+
+  DEBUG ((DEBUG_INFO, "VTD base address1 %x\n", DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
+  DEBUG ((DEBUG_INFO, "VTD base address3 %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);
+
+  ///
+  /// Update RMRR structures of temp DMAR table
+  ///
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
+  UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
+
+  ///
+  /// 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.RmrrUsb.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb, TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  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;
+  }
+  if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme, TempDmarTable.RmrrCsme.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);
+}
+
+/**
+  PciEnumerationComplete routine for update DMAR
+**/
+VOID
+UpdateDmarPciEnumCompleteCallback (
+  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, "UpdateDmarPciEnumCompleteCallback \n"));
+
+
+  ///
+  /// Fix DMAR Table always created, skip install when disabled
+  ///
+  if ((mSaConfigHob->VtdData.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
+      ///
+      switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
+
+        case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
+          VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+          DmarTableUpdate (VtdAcpiTable, &Version);
+          break;
+
+        default:
+          break;
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      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;
+  UINTN                           MchBar;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+
+  mInterruptRemappingSupport  = FALSE;
+  mSaConfigHob       = NULL;
+  mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
+  if (mSaConfigHob != NULL) {
+    mInterruptRemappingSupport  = mSaConfigHob->VtdData.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, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
+  mSaPolicy        = SaPolicy;
+  MchBar           = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR) & ~BIT0;
+
+  if (mSaConfigHob != NULL) {
+    SaNvsAreaProtocol->Area->VtdDisable = mSaConfigHob->VtdData.VtdDisable;
+  }
+  SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
+  SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
+  SaNvsAreaProtocol->Area->VtdEngine1Vid = PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  if (mSaConfigHob != NULL) {
+    if ((mSaConfigHob->VtdData.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/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..08fd9266c6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
@@ -0,0 +1,356 @@
+/** @file
+  This is the driver that publishes the SMM Access Protocol
+  instance for System Agent.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SmmAccessDriver.h"
+
+static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
+
+
+/**
+  This is the standard EFI driver point that
+  installs an SMM Access Protocol
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS           - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED    - Protocol was not installed
+  @retval EFI_NOT_FOUND         - Protocol can't be found.
+  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  EFI_PEI_HOB_POINTERS            *Hob;
+
+  ///
+  /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+  ///
+  /// Initialize Global variables
+  ///
+  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
+
+  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+  mSmmAccess.Handle           = NULL;
+
+  ///
+  /// Get Hob list
+  ///
+  Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
+
+  ///
+  /// Alloc space for mSmmAccess.SmramDesc
+  ///
+  mSmmAccess.SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR));
+  if (mSmmAccess.SmramDesc == NULL) {
+    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
+
+  ///
+  /// Use the HOB to publish SMRAM capabilities
+  ///
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock->Descriptor[Index].CpuStart;
+    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock->Descriptor[Index].RegionState;
+  }
+
+  mSmmAccess.NumberRegions              = Index;
+  mSmmAccess.SmmAccess.Open             = Open;
+  mSmmAccess.SmmAccess.Close            = Close;
+  mSmmAccess.SmmAccess.Lock             = Lock;
+  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
+  mSmmAccess.SmmAccess.LockState        = FALSE;
+  mSmmAccess.SmmAccess.OpenState        = FALSE;
+
+  ///
+  /// Install our protocol interfaces on the device's handle
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mSmmAccess.Handle,
+                  &gEfiSmmAccess2ProtocolGuid,
+                  &mSmmAccess.SmmAccess,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned %r\n", Status));
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  ///
+  /// BEGIN CHIPSET SPECIFIC CODE
+  ///
+  ///
+  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+  ///
+  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+  SmramControl = PciRead8 (Address);
+  ///
+  ///  Is SMRAM locked?
+  ///
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      ///
+      /// Cannot Open a locked region
+      ///
+      SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+  ///
+  /// Open SMRAM region
+  ///
+  SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
+  SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
+
+  PciWrite8 (Address, SmramControl);
+  ///
+  /// END CHIPSET SPECIFIC CODE
+  ///
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_OPEN;
+  }
+  SmmAccess->SmmAccess.OpenState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  BOOLEAN                 OpenState;
+  UINT8                   Index;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      continue;
+    }
+
+    ///
+    /// BEGIN CHIPSET SPECIFIC CODE
+    ///
+    ///
+    /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+    ///
+    Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+    SmramControl = PciRead8 (Address);
+    ///
+    ///  Is SMRAM locked?
+    ///
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      ///
+      /// Cannot Close a locked region
+      ///
+      SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+    ///
+    /// Close SMRAM region
+    ///
+    SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
+
+    PciWrite8 (Address, SmramControl);
+    ///
+    /// END CHIPSET SPECIFIC CODE
+    ///
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~EFI_SMRAM_OPEN;
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  }
+
+  ///
+  /// Find out if any regions are still open
+  ///
+  OpenState = FALSE;
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                                  one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINT64                  Address;
+  UINT8                   SmramControl;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (SmmAccess->SmmAccess.OpenState) {
+    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n"));
+    return EFI_DEVICE_ERROR;
+  }
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+  }
+  SmmAccess->SmmAccess.LockState = TRUE;
+
+  ///
+  /// BEGIN CHIPSET SPECIFIC CODE
+  ///
+  ///
+  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
+  ///
+  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+
+  SmramControl = PciRead8 (Address);
+  ///
+  /// Lock the SMRAM
+  ///
+  SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
+
+  PciWrite8 (Address, SmramControl);
+  ///
+  /// END CHIPSET SPECIFIC CODE
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                                     buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                                     region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  EFI_STATUS              Status;
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   NecessaryBufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+  if (*SmramMapSize < NecessaryBufferSize) {
+    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+    Status = EFI_SUCCESS;
+  }
+
+  *SmramMapSize = NecessaryBufferSize;
+
+  return Status;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
new file mode 100644
index 0000000000..c864a0ca8f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
@@ -0,0 +1,250 @@
+/** @file
+  This file describes the contents of the ACPI DMA address Remapping
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Dmar.h"
+#include <Register/PchRegsP2sb.h>
+
+EFI_ACPI_DMAR_TABLE DmarTable = {
+  //
+  // EFI_ACPI_DMAR_HEADER
+  //
+  {
+    //
+    // EFI_ACPI_DESCRIPTION_HEADER
+    //
+    {
+      EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
+      sizeof (EFI_ACPI_DMAR_TABLE),
+      EFI_ACPI_DMAR_TABLE_REVISION,
+
+      //
+      // Checksum will be updated at runtime
+      //
+      0x00,
+
+      //
+      // It is expected that these values will be programmed at runtime
+      //
+      { 'I', 'N', 'T', 'E', 'L', ' ' },
+      EFI_ACPI_DMAR_OEM_TABLE_ID,
+      0x1,
+      EFI_ACPI_DMAR_OEM_CREATOR_ID,
+      1
+    },
+
+    //
+    // DMAR table specific entries below:
+    //
+
+    //
+    // 39-bit addressing Host Address Width
+    //
+    38,
+
+    //
+    // Flags
+    //
+    0,
+
+    //
+    // Reserved fields
+    //
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+  },
+
+  //
+  // First DRHD structure, VT-d Engine #1
+  //
+  {
+    //
+    // EFI_ACPI_DMAR_DRHD_HEADER
+    //
+    {
+      {0,                                         // Type = 0 (DRHD)
+      sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)},     // Length of structure
+      0,                                          // Flag - Do not include all
+      0,                                          // Reserved fields
+      0,                                          // Segment
+      0                                           // Base address of DMA-remapping hardware - Updated at boot time
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                     // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),  // Length
+        0,                                      // Segment number
+        0,                                      // Reserved
+        0},                                     // Start bus number
+        {2, 0}                                  // PCI path
+      }
+    }
+  },
+
+  //
+  //Third DRHD structure VT-d Engine# 3
+  //
+  {
+    //
+    // EFI_ACPI_DMAR_DRHD_HEADER
+    //
+    {
+      {0,                                        // Type = 0 (DRHD)
+      sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)},    // Length of strucure.
+      1,                                         // Flag - Include all
+      0,                                         // Reserved
+      0,                                         // Segment Number
+      0                                          // Base address of DMA-remapping hardware.
+    },
+    {
+      //
+      // Device Scopes
+      //
+      {
+        {3,                                          // Type=IO APIC
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
+        0,                                           // Reserved
+        2,                                           // Enumeration ID
+        V_P2SB_CFG_IBDF_BUS},                        // Start bus number
+        {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC}  // PCI path
+      },
+      //
+      // Device Scopes
+      //
+      {
+        {4,                                          // Type=HPET
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
+        0,                                           // Reserved
+        0,                                           // Enumeration ID
+        V_P2SB_CFG_HBDF_BUS},                        // Start bus number
+        {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC}  // PCI path
+      }
+    }
+  },
+  //RMRR structure for USB devices.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {
+        0x1,                                     // Type 1 - RMRR structure
+        sizeof(EFI_ACPI_RMRR_USB_STRUC)          // Length
+      },
+      { 0x00, 0x00 },                            // Reserved
+      0x0000,                                    // Segment Num
+      0x00000000000E0000,                        // RMRR Base address - Updated in runtime.
+      0x00000000000EFFFF                         // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                    // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                     // Reserved
+        0,                                     // Enum ID
+        0},                                    // Start bus number
+        {20, 0}                                // PCI path
+      },
+      {
+        {1,                                    // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                     // Reserved
+        0,                                     // Enum ID
+        0},                                    // Start bus number
+        {20, 1}                                // PCI path
+      }
+    }
+  },
+
+  //RMRR structure for IGD device.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {1,                                       // Type 1 - RMRR structure
+      sizeof (EFI_ACPI_RMRR_IGD_STRUC)},        // Length
+      {0x0000},                                 // Reserved
+      0x0000,                                   // Segment Num
+      0x0000000000000000,                       // RMRR Base address - Updated in runtime.
+      0x0000000000000000                        // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                   // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                    // Reserved
+        0,                                    // Enum ID
+        0},                                   // Start bus number
+        {2, 0}                                // PCI path
+      }
+    }
+  },
+
+  // RMRR structure for WiAMT DMA access.
+  // Keep this device in end of RMRR queue.
+  {
+    //
+    // EFI_ACPI_DMAR_RMRR_HEADER
+    //
+    {
+      {1,                                       // Type 1 - RMRR structure
+      sizeof (EFI_ACPI_RMRR_CSME_STRUC)},       // Length
+      {0x0000},                                 // Reserved
+      0x0000,                                   // Segment Num
+      0x0000000000000000,                       // RMRR Base address - Updated in runtime.
+      0x0000000000000000                        // RMRR Limit address - Updated in runtime.
+    },
+    //
+    // Device Scopes
+    //
+    {
+      {
+        {1,                                   // Type
+        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
+        0,                                    // Reserved
+        0,                                    // Enum ID
+        0},                                   // Start bus number
+        {22, 7}                               // PCI path
+      }
+    }
+  }
+};
+
+//
+// Dummy function required for build tools
+//
+#if defined (__GNUC__)
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the exeutable
+  //
+  return (VOID*)&DmarTable;
+}
+#else
+int
+main (
+  VOID
+  )
+{
+  return 0;
+}
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
new file mode 100644
index 0000000000..b431a77f05
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
@@ -0,0 +1,794 @@
+/** @file
+  This file contains the SystemAgent PCI Configuration space
+  definition.
+  It defines various System Agent PCI Configuration Space registers
+  which will be used to dynamically produce all resources in the Host Bus.
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(M64B)
+External(M64L)
+External(M32B)
+External(M32L)
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x40),   // EPBAR (0:0:0:40)
+  EPEN, 1,        // Enable
+      , 11,
+  EPBR, 20,       // EPBAR [31:12]
+
+  Offset(0x48),   // MCHBAR (0:0:0:48)
+  MHEN, 1,        // Enable
+      , 14,
+  MHBR, 17,       // MCHBAR [31:15]
+
+  Offset(0x50),   // GGC (0:0:0:50)
+  GCLK, 1,        // GGCLCK
+
+  Offset(0x54),   // DEVEN (0:0:0:54)
+  D0EN, 1,        // DEV0 Enable
+  D1F2, 1,        // DEV1 FUN2 Enable
+  D1F1, 1,        // DEV1 FUN1 Enable
+  D1F0, 1,        // DEV1 FUN0 Enable
+
+  Offset(0x60),   // PCIEXBAR (0:0:0:60)
+  PXEN, 1,        // Enable
+  PXSZ, 2,        // PCI Express Size
+      , 23,
+  PXBR, 6,        // PCI Express BAR [31:26]
+
+  Offset(0x68),   // DMIBAR (0:0:0:68)
+  DIEN, 1,        // Enable
+      , 11,
+  DIBR, 20,       // DMIBAR [31:12]
+
+  Offset(0x70),   // MESEG_BASE (0:0:0:70)
+      , 20,
+  MEBR, 12,       // MESEG_BASE [31:20]
+
+  Offset(0x80),   // PAM0 Register (0:0:0:80)
+  PMLK, 1,        // PAM Lock bit.
+      , 3,
+  PM0H, 2,        // PAM 0, High Nibble
+      , 2,
+
+  Offset(0x81),   // PAM1 Register (0:0:0:81)
+  PM1L, 2,        // PAM1, Low  Nibble
+      , 2,
+  PM1H, 2,        // PAM1, High Nibble
+      , 2,
+
+  Offset(0x82),   // PAM2 Register (0:0:0:82)
+  PM2L, 2,        // PAM2, Low  Nibble
+      , 2,
+  PM2H, 2,        // PAM2, High Nibble
+      , 2,
+
+  Offset(0x83),   // PAM3 Register (0:0:0:83)
+  PM3L, 2,        // PAM3, Low  Nibble
+      , 2,
+  PM3H, 2,        // PAM3, High Nibble
+      , 2,
+
+  Offset(0x84),   // PAM4 Register (0:0:0:84)
+  PM4L, 2,        // PAM4, Low  Nibble
+      , 2,
+  PM4H, 2,        // PAM4, High Nibble
+      , 2,
+
+  Offset(0x85),   // PAM5 Register (0:0:0:85)
+  PM5L, 2,        // PAM5, Low  Nibble
+      , 2,
+  PM5H, 2,        // PAM5, High Nibble
+      , 2,
+
+  Offset(0x86),   // PAM6 Register (0:0:0:86)
+  PM6L, 2,        // PAM6, Low  Nibble
+      , 2,
+  PM6H, 2,        // PAM6, High Nibble
+      , 2,
+
+  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
+      , 20,
+  TUUD, 19,       // TOUUD [38:20]
+
+  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
+      , 20,
+  TLUD, 12,       // TOLUD [31:20]
+
+  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
+      , 7,
+  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus.  This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+  //
+  // Bus Number Allocation: Bus 0 to 0xFF
+  //
+  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+    0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+  //
+  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+  //
+  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+  //
+  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+  //
+  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+  //
+  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+  //
+  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+  //
+  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+  //
+  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+  //
+  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+  //
+  // BIOS Area ( 0xF0000 - 0xFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+//  //
+//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+//  //
+//  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+  //
+  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+  //
+  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+  // (This is dummy range for OS compatibility, will patch it in _CRS)
+  //
+  QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+  //
+  // SA reserved resources
+  //
+  Device(SRRE) {
+    Name(_HID,EISAID("PNP0C02")) // motherboard resource
+    Name(_UID,"SARESV")
+    Method(_STA,0,Serialized) // device present and decodes its resources, but not to be displayed in OSPM
+    {
+      If(LGreaterEqual(TLUD, 0x404)) {
+        Return (3)
+      } Else {
+        Return (0)
+      }
+    }
+
+    Method(_CRS,0,Serialized)
+    {
+      Name(BUF0,ResourceTemplate(){
+        //
+        // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this memory range
+        //
+        Memory32Fixed(ReadOnly,0x40000000,0x400000)
+      })
+      If(LGreaterEqual(TLUD, 0x404)) {
+        Return (BUF0)
+      } Else {
+        Return (Buffer(){})
+      }
+    }
+  }
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+  if(LEqual(EP_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+  }
+  Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+  if(LEqual(MH_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+  }
+  Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+  if(LEqual(PC_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+  }
+  Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+  if(LEqual(PC_L,0)) {
+    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+  }
+  Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+  if(LEqual(DM_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+  }
+  Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+  //
+  // Fix up Max Bus Number and Length
+  //
+  Store(\_SB.PCI0.GPCL(),Local0)
+  CreateWordField(BUF0, ^PB00._MAX, PBMX)
+  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+  CreateWordField(BUF0, ^PB00._LEN, PBLN)
+  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+  //
+  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+  //
+  If(PM1L)  // \_SB.PCI0
+  {
+    // PAMx != 0.  Set length = 0.
+
+    CreateDwordField(BUF0, ^C000._LEN,C0LN)
+    Store(Zero,C0LN)
+  }
+
+  If(LEqual(PM1L,1))
+  {
+    CreateBitField(BUF0, ^C000._RW,C0RW)
+    Store(Zero,C0RW)
+  }
+
+  If(PM1H)
+  {
+    CreateDwordField(BUF0, ^C400._LEN,C4LN)
+    Store(Zero,C4LN)
+  }
+
+  If(LEqual(PM1H,1))
+  {
+    CreateBitField(BUF0, ^C400._RW,C4RW)
+    Store(Zero,C4RW)
+  }
+
+  If(PM2L)
+  {
+    CreateDwordField(BUF0, ^C800._LEN,C8LN)
+    Store(Zero,C8LN)
+  }
+
+  If(LEqual(PM2L,1))
+  {
+    CreateBitField(BUF0, ^C800._RW,C8RW)
+    Store(Zero,C8RW)
+  }
+
+  If(PM2H)
+  {
+    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+    Store(Zero,CCLN)
+  }
+
+  If(LEqual(PM2H,1))
+  {
+    CreateBitField(BUF0, ^CC00._RW,CCRW)
+    Store(Zero,CCRW)
+  }
+
+  If(PM3L)
+  {
+    CreateDwordField(BUF0, ^D000._LEN,D0LN)
+    Store(Zero,D0LN)
+  }
+
+  If(LEqual(PM3L,1))
+  {
+    CreateBitField(BUF0, ^D000._RW,D0RW)
+    Store(Zero,D0RW)
+  }
+
+  If(PM3H)
+  {
+    CreateDwordField(BUF0, ^D400._LEN,D4LN)
+    Store(Zero,D4LN)
+  }
+
+  If(LEqual(PM3H,1))
+  {
+    CreateBitField(BUF0, ^D400._RW,D4RW)
+    Store(Zero,D4RW)
+  }
+
+  If(PM4L)
+  {
+    CreateDwordField(BUF0, ^D800._LEN,D8LN)
+    Store(Zero,D8LN)
+  }
+
+  If(LEqual(PM4L,1))
+  {
+    CreateBitField(BUF0, ^D800._RW,D8RW)
+    Store(Zero,D8RW)
+  }
+
+  If(PM4H)
+  {
+    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+    Store(Zero,DCLN)
+  }
+
+  If(LEqual(PM4H,1))
+  {
+    CreateBitField(BUF0, ^DC00._RW,DCRW)
+    Store(Zero,DCRW)
+  }
+
+  If(PM5L)
+  {
+    CreateDwordField(BUF0, ^E000._LEN,E0LN)
+    Store(Zero,E0LN)
+  }
+
+  If(LEqual(PM5L,1))
+  {
+    CreateBitField(BUF0, ^E000._RW,E0RW)
+    Store(Zero,E0RW)
+  }
+
+  If(PM5H)
+  {
+    CreateDwordField(BUF0, ^E400._LEN,E4LN)
+    Store(Zero,E4LN)
+  }
+
+  If(LEqual(PM5H,1))
+  {
+    CreateBitField(BUF0, ^E400._RW,E4RW)
+    Store(Zero,E4RW)
+  }
+
+  If(PM6L)
+  {
+    CreateDwordField(BUF0, ^E800._LEN,E8LN)
+    Store(Zero,E8LN)
+  }
+
+  If(LEqual(PM6L,1))
+  {
+    CreateBitField(BUF0, ^E800._RW,E8RW)
+    Store(Zero,E8RW)
+  }
+
+  If(PM6H)
+  {
+    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+    Store(Zero,ECLN)
+  }
+
+  If(LEqual(PM6H,1))
+  {
+    CreateBitField(BUF0, ^EC00._RW,ECRW)
+    Store(Zero,ECRW)
+  }
+
+  If(PM0H)
+  {
+    CreateDwordField(BUF0, ^F000._LEN,F0LN)
+    Store(Zero,F0LN)
+  }
+
+  If(LEqual(PM0H,1))
+  {
+    CreateBitField(BUF0, ^F000._RW,F0RW)
+    Store(Zero,F0RW)
+  }
+
+  // Enable the 1MB region between 15-16MB if HENA = 1.
+  //
+  // If( MCHC.HENA)
+  // {
+  // CreateDwordField(BUF0, HOLE._LEN,H0LN)
+  // Store(0x100000,H0LN)
+  // }
+
+  //
+  // Create pointers to Memory Sizing values.
+  //
+  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+  //
+  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+  // TOM, so shift these bits into the correct position and fix up
+  // the Memory Region available to PCI.
+  //
+  Store (M32L, M1LN)
+  Store (M32B, M1MN)
+  Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+  //
+  // Create pointers to Memory Sizing values.
+  // Patch PM02 range basing on memory size and OS type
+  //
+  If (LEqual(M64L, 0)) {
+    CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+    //
+    // Set resource length to 0
+    //
+    Store (0, MSLN)
+  }
+  Else {
+    CreateQwordField(BUF0, ^PM02._LEN,M2LN)
+    CreateQwordField(BUF0, ^PM02._MIN,M2MN)
+    CreateQwordField(BUF0, ^PM02._MAX,M2MX)
+    //
+    // Set 64bit MMIO resource Base and Length
+    //
+    Store (M64L, M2LN)
+    Store (M64B, M2MN)
+    Subtract (Add (M2MN, M2LN), 1, M2MX)
+  }
+  Return(BUF0)
+}
+
+//
+//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
+//
+Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
+          0xf7, 0x1f,
+          0x1c, 0x40,
+          0x96, 0x57,
+          0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
+
+
+Name(SUPP,0)  // PCI _OSC Support Field value
+Name(CTRL,0)  // PCI _OSC Control Field value
+Name(XCNT, 0) // Variable used in _OSC for counting
+
+Method(_OSC,4,Serialized)
+{
+  //
+  // Check for proper UUID
+  // Save the capabilities buffer
+  //
+  Store(Arg3,Local0)
+
+  //
+  // Create DWord-adressable fields from the Capabilties Buffer
+  //
+  CreateDWordField(Local0,0,CDW1)
+  CreateDWordField(Local0,4,CDW2)
+  CreateDWordField(Local0,8,CDW3)
+
+
+  //
+  // Check for proper UUID
+  //
+  If(LEqual(Arg0,GUID))
+  {
+    // Save Capabilities DWord2 & 3
+    Store(CDW2,SUPP)
+    Store(CDW3,CTRL)
+
+    //
+    // You can clear bits in CTRL here if you don't want OS to take
+    // control
+    //
+    If(LNot(NEXP))
+    {
+      And(CTRL, 0xFFFFFFF8, CTRL)       // disable Native hot plug, PME
+    }
+
+    If(LEqual(TBTS, 1)) {
+      // \_OSC disallow only Advanced Error Reporting control
+      And(CTRL, 0xFFFFFFF7, CTRL)
+    }
+
+    If(Not(And(CDW1,1)))  // Query flag clear?
+    { // Disable GPEs for features granted native control.
+      If(And(CTRL,0x01))
+      {
+        NHPG()
+      }
+      If(And(CTRL,0x04))  // PME control granted?
+      {
+        NPME()
+      }
+    }
+
+    If(LNotEqual(Arg1,One))
+    {
+      //
+      // Unknown revision
+      //
+      Or(CDW1,0x08,CDW1)
+    }
+
+    If(LNotEqual(CDW3,CTRL))
+    {
+      //
+      // Capabilities bits were masked
+      //
+      Or(CDW1,0x10,CDW1)
+    }
+    //
+    // Update DWORD3 in the buffer
+    //
+    Store(CTRL,CDW3)
+    Store(CTRL,OSCC)
+    Return(Local0)
+  } Else {
+    Or(CDW1,4,CDW1)   // Unrecognized UUID
+    Return(Local0)
+  }
+} // End _OSC
+
+//
+// Added code for Dual IRQ support. Two set of ACPI IRQ tables were generated.
+// Code has been added to select the appropriate IRQ table by checking the CPUID.
+//
+Scope(\_SB.PCI0)
+{
+  Method(AR00) {
+    Return(\_SB.AR00)
+  }
+
+  Method(PD00) {
+    Return(\_SB.PD00)
+  }
+
+  Method(AR02) {
+    Return(\_SB.AR02)
+  }
+
+  Method(PD02) {
+    Return(\_SB.PD02)
+  }
+
+  Method(AR04) {
+    Return(\_SB.AR04)
+  }
+
+  Method(PD04) {
+    Return(\_SB.PD04)
+  }
+
+  Method(AR05) {
+    Return(\_SB.AR05)
+  }
+
+  Method(PD05) {
+    Return(\_SB.PD05)
+  }
+
+  Method(AR06) {
+    Return(\_SB.AR06)
+  }
+
+  Method(PD06) {
+    Return(\_SB.PD06)
+  }
+
+  Method(AR07) {
+    Return(\_SB.AR07)
+  }
+
+  Method(PD07) {
+    Return(\_SB.PD07)
+  }
+
+  Method(AR08) {
+    Return(\_SB.AR08)
+  }
+
+  Method(PD08) {
+    Return(\_SB.PD08)
+  }
+
+  Method(AR09) {
+    Return(\_SB.AR09)
+  }
+
+  Method(PD09) {
+    Return(\_SB.PD09)
+  }
+
+  Method(AR0A) {
+    Return(\_SB.AR0A)
+  }
+
+  Method(PD0A) {
+    Return(\_SB.PD0A)
+  }
+
+  Method(AR0B) {
+    Return(\_SB.AR0B)
+  }
+
+  Method(PD0B) {
+    Return(\_SB.PD0B)
+  }
+
+  //
+  // Add device scope definition for System Agent
+  // P.E.G. Root Port D1F0
+  //
+  Device(PEG0) {
+    Name(_ADR, 0x00010000)
+    Device(PEGP) { // P.E.G. Port Slot x16
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // P.E.G. Root Port D1F1
+  //
+  Device(PEG1) {
+    Name(_ADR, 0x00010001)
+    Device(PEGP) { // P.E.G. Port Slot x8
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // P.E.G. Root Port D1F2
+  //
+  Device(PEG2) {
+    Name(_ADR, 0x00010002)
+    Device(PEGP) { // P.E.G. Port Slot x4
+      Name(_ADR, 0x00000000)
+    }
+  }
+  //
+  // I.G.D
+  //
+  Device(GFX0) {
+    Name(_ADR, 0x00020000)
+  }
+  //
+  // SA Thermal Device
+  //
+  Device(B0D4) {
+    Method(_DSM,4,serialized){if(PCIC(Arg0)) { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
+    Name(_ADR, 0x00040000)
+  }
+  //
+  // Device IPU0 is the IPU PCI device
+  //
+  Device(IPU0) {
+    Name(_ADR, 0x00050000)
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
new file mode 100644
index 0000000000..e7a797c973
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
@@ -0,0 +1,1666 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+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)
+
+Name(TMP1,Package() {0xFFFFFFFF})
+Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF})
+Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
+Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
+Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF})
+Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+                     0xFFFFFFFF, 0xFFFFFFFF})
+
+// 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)
+{
+  If (LEqual(IPTP,1)) {
+    //
+    // Increment number of devices if IPU is enabled
+    //
+    Store(1, NDID)
+  } Else {
+    Store(0, 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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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))
+  {
+    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(SGMD,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))
+    {
+      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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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.PCI0.GFX0.AINT(1, Arg0)
+      Store(Arg0,BRTL)  // Store Brightness Level.
+    }
+  }
+
+  //
+  // Brightness Query Current level.
+  //
+  Method (_BQC,0)
+  {
+    Return(BRTL)
+  }
+}
+
+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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
new file mode 100644
index 0000000000..7edbe45e2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
@@ -0,0 +1,472 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/************************************************************************;
+;* 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.PCI0.GFX0, Arg1)
+  }
+
+  If(CondRefOf(HNOT))
+  {
+    HNOT(Arg0)  //Notification handler for Switchable graphics
+  }
+  Else
+  {
+    Notify(\_SB.PCI0.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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
new file mode 100644
index 0000000000..e7b3c92cda
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
@@ -0,0 +1,369 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// _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
+    //
+    //
+    // 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 (0x1E7FF)   // bit 11 and 12 is not supported
+        }
+      }
+
+      //
+      // 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
new file mode 100644
index 0000000000..26e560a358
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
@@ -0,0 +1,129 @@
+/** @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) 2019 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
new file mode 100644
index 0000000000..a26cbdb00c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
@@ -0,0 +1,296 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//  Define an OperationRegion to cover the GMCH PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+//
+Scope(\_SB.PCI0)
+{
+  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
+  //
+  // 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.PCI0.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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
new file mode 100644
index 0000000000..0167d922ff
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
@@ -0,0 +1,262 @@
+/** @file
+  This file contains the system BIOS call back functionality for the
+  OpRegion/Software SCI mechanism.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
new file mode 100644
index 0000000000..e4e47ddf1e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
@@ -0,0 +1,87 @@
+/** @file
+  This file contains the device definition of the System Agent
+  ACPI reference code.
+  Currently defines the device objects for the
+  System Agent IPU device
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
+//
+Scope (\_SB.PCI0.GFX0)
+{
+  Device(IPUA) // IPU AVStream virtual device name
+  {
+    /*
+      The identifier for this device (Same as in
+      _DOD above). This is required so GFX driver can
+      associate a matching device ID for the AVStream
+      driver and provide it to PnP (this device ID
+      should appear in the INF file of the AVStream
+      driver).
+    */
+    Name(_ADR, 0x00003480)
+    /*
+      The following is a technique that may be used (per OEM needs) to prevent
+      the load of the camera device in one of the following cases:
+      - Camera device is fused out
+      - If the platform setup requires that in a secured boot the camera device
+      should not be enabled
+    */
+    Method (_STA, 0, NotSerialized) {
+      If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as GFX0 child
+        Return (0xF)
+      } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0 child
+        Return (0x0)
+      }
+    }
+  } // End SKC0
+} // end I.G.D
+
+Scope(\_SB.PCI0.IPU0)
+{
+//----------------------------------------------------------------------------------------
+//  Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM Method
+//
+//  Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj, IntObj, PkgObj})
+//  Arguments:
+//  Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
+//  Arg1: Integer Revision Level (Current revision is 0)
+//  Arg2: Integer Function Index
+//                0x1 - return UINT 32bit LTR values
+//                0x2 - return UINT 32bit Fill Time
+//
+//-----------------------------------------------------------------------------------------
+Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
+    If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
+    {
+      // Function 0 : Query Function
+      If (LEqual(Arg2, 0))
+      {
+        // Revision 0
+        If (LEqual(Arg1, 0)) // The current revision is 0
+        {
+          Return(Buffer() { 0x07 }) // There are 2 function defined other than Query.
+        } Else {
+          Return(0) // Revision mismatch
+        }
+      }
+      // Function 1 : Return UINT 32bit LTR values
+      If(LEqual(Arg2, 1))
+      {
+        Return(0x64503C19)
+      }
+      // Function 2 : Return UINT 32bit Fill Time
+      If(LEqual(Arg2, 2))
+      {
+        Return(0xFFF0783C)
+      }
+    }
+
+    Return(0) // Function number or GUID mismatch but normal return.
+  }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
new file mode 100644
index 0000000000..4817968240
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
@@ -0,0 +1,31 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.PCI0, DeviceObj)
+External(\_SB.PCI0.GFX0, DeviceObj)
+External(\_SB.PCI0.IPU0, DeviceObj)
+External(\_SB.PCI0.B0D3, DeviceObj)
+External(\_SB.PCI0.PCIC, MethodObj)
+External(\_SB.PCI0.PCID, MethodObj)
+
+
+///
+/// I.G.D
+///
+Scope (\_SB.PCI0.GFX0)
+{
+  include("Igfx.asl")
+} // end I.G.D
+
+///
+/// IPU Device
+///
+include("Ipu.asl")
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
new file mode 100644
index 0000000000..09d36ade53
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
@@ -0,0 +1,147 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define SA NVS Area operatino region.
+  //
+
+
+
+  OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
+  Field(SANV,AnyAcc,Lock,Preserve)
+  {  Offset(0),      ASLB, 32, // Offset(0),     IGD OpRegion base address
+  Offset(4),      IMON, 8,  // Offset(4),     IMON Current Value
+  Offset(5),      IGDS, 8,  // Offset(5),     IGD State (Primary Display = 1)
+  Offset(6),      IBTT, 8,  // Offset(6),     IGD Boot Display Device
+  Offset(7),      IPAT, 8,  // Offset(7),     IGD Panel Type CMOS option
+  Offset(8),      IPSC, 8,  // Offset(8),     IGD Panel Scaling
+  Offset(9),      IBIA, 8,  // Offset(9),     IGD BIA Configuration
+  Offset(10),     ISSC, 8,  // Offset(10),    IGD SSC Configuration
+  Offset(11),     IDMS, 8,  // Offset(11),    IGD DVMT Memory Size
+  Offset(12),     IF1E, 8,  // Offset(12),    IGD Function 1 Enable
+  Offset(13),     HVCO, 8,  // Offset(13),    HPLL VCO
+  Offset(14),     GSMI, 8,  // Offset(14),    GMCH SMI/SCI mode (0=SCI)
+  Offset(15),     PAVP, 8,  // Offset(15),    IGD PAVP data
+  Offset(16),     CADL, 8,  // Offset(16),    Current Attached Device List
+  Offset(17),     CSTE, 16, // Offset(17),    Current Display State
+  Offset(19),     NSTE, 16, // Offset(19),    Next Display State
+  Offset(21),     NDID, 8,  // Offset(21),    Number of Valid Device IDs
+  Offset(22),     DID1, 32, // Offset(22),    Device ID 1
+  Offset(26),     DID2, 32, // Offset(26),    Device ID 2
+  Offset(30),     DID3, 32, // Offset(30),    Device ID 3
+  Offset(34),     DID4, 32, // Offset(34),    Device ID 4
+  Offset(38),     DID5, 32, // Offset(38),    Device ID 5
+  Offset(42),     DID6, 32, // Offset(42),    Device ID 6
+  Offset(46),     DID7, 32, // Offset(46),    Device ID 7
+  Offset(50),     DID8, 32, // Offset(50),    Device ID 8
+  Offset(54),     DID9, 32, // Offset(54),    Device ID 9
+  Offset(58),     DIDA, 32, // Offset(58),    Device ID 10
+  Offset(62),     DIDB, 32, // Offset(62),    Device ID 11
+  Offset(66),     DIDC, 32, // Offset(66),    Device ID 12
+  Offset(70),     DIDD, 32, // Offset(70),    Device ID 13
+  Offset(74),     DIDE, 32, // Offset(74),    Device ID 14
+  Offset(78),     DIDF, 32, // Offset(78),    Device ID 15
+  Offset(82),     DIDX, 32, // Offset(82),    Device ID for eDP device
+  Offset(86),     NXD1, 32, // Offset(86),    Next state DID1 for _DGS
+  Offset(90),     NXD2, 32, // Offset(90),    Next state DID2 for _DGS
+  Offset(94),     NXD3, 32, // Offset(94),    Next state DID3 for _DGS
+  Offset(98),     NXD4, 32, // Offset(98),    Next state DID4 for _DGS
+  Offset(102),    NXD5, 32, // Offset(102),   Next state DID5 for _DGS
+  Offset(106),    NXD6, 32, // Offset(106),   Next state DID6 for _DGS
+  Offset(110),    NXD7, 32, // Offset(110),   Next state DID7 for _DGS
+  Offset(114),    NXD8, 32, // Offset(114),   Next state DID8 for _DGS
+  Offset(118),    NXDX, 32, // Offset(118),   Next state DID for eDP
+  Offset(122),    LIDS, 8,  // Offset(122),   Lid State (Lid Open = 1)
+  Offset(123),    KSV0, 32, // Offset(123),   First four bytes of AKSV (manufacturing mode)
+  Offset(127),    KSV1, 8,  // Offset(127),   Fifth byte of AKSV (manufacturing mode)
+  Offset(128),    BRTL, 8,  // Offset(128),   Brightness Level Percentage
+  Offset(129),    ALSE, 8,  // Offset(129),   Ambient Light Sensor Enable
+  Offset(130),    ALAF, 8,  // Offset(130),   Ambient Light Adjusment Factor
+  Offset(131),    LLOW, 8,  // Offset(131),   LUX Low Value
+  Offset(132),    LHIH, 8,  // Offset(132),   LUX High Value
+  Offset(133),    ALFP, 8,  // Offset(133),   Active LFP
+  Offset(134),    IPTP, 8,  // Offset(134),   IPU ACPI device type (0=Disabled, 1=AVStream virtual device as child of GFX)
+  Offset(135),    EDPV, 8,  // Offset(135),   Check for eDP display device
+  Offset(136),    SGMD, 8,  // Offset(136),   SG Mode (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
+  Offset(137),    SGFL, 8,  // Offset(137),   SG Feature List
+  Offset(138),    SGGP, 8,  // Offset(138),   PCIe0 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(139),    HRE0, 8,  // Offset(139),   PCIe0 HLD RST IO Expander Number
+  Offset(140),    HRG0, 32, // Offset(140),   PCIe0 HLD RST GPIO Number
+  Offset(144),    HRA0, 8,  // Offset(144),   PCIe0 HLD RST GPIO Active Information
+  Offset(145),    PWE0, 8,  // Offset(145),   PCIe0 PWR Enable IO Expander Number
+  Offset(146),    PWG0, 32, // Offset(146),   PCIe0 PWR Enable GPIO Number
+  Offset(150),    PWA0, 8,  // Offset(150),   PCIe0 PWR Enable GPIO Active Information
+  Offset(151),    P1GP, 8,  // Offset(151),   PCIe1 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(152),    HRE1, 8,  // Offset(152),   PCIe1 HLD RST IO Expander Number
+  Offset(153),    HRG1, 32, // Offset(153),   PCIe1 HLD RST GPIO Number
+  Offset(157),    HRA1, 8,  // Offset(157),   PCIe1 HLD RST GPIO Active Information
+  Offset(158),    PWE1, 8,  // Offset(158),   PCIe1 PWR Enable IO Expander Number
+  Offset(159),    PWG1, 32, // Offset(159),   PCIe1 PWR Enable GPIO Number
+  Offset(163),    PWA1, 8,  // Offset(163),   PCIe1 PWR Enable GPIO Active Information
+  Offset(164),    P2GP, 8,  // Offset(164),   PCIe2 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(165),    HRE2, 8,  // Offset(165),   PCIe2 HLD RST IO Expander Number
+  Offset(166),    HRG2, 32, // Offset(166),   PCIe2 HLD RST GPIO Number
+  Offset(170),    HRA2, 8,  // Offset(170),   PCIe2 HLD RST GPIO Active Information
+  Offset(171),    PWE2, 8,  // Offset(171),   PCIe2 PWR Enable IO Expander Number
+  Offset(172),    PWG2, 32, // Offset(172),   PCIe2 PWR Enable GPIO Number
+  Offset(176),    PWA2, 8,  // Offset(176),   PCIe2 PWR Enable GPIO Active Information
+  Offset(177),    DLPW, 16, // Offset(177),   Delay after power enable for PCIe
+  Offset(179),    DLHR, 16, // Offset(179),   Delay after Hold Reset for PCIe
+  Offset(181),    EECP, 8,  // Offset(181),   PCIe0 Endpoint Capability Structure Offset
+  Offset(182),    XBAS, 32, // Offset(182),   Any Device's PCIe Config Space Base Address
+  Offset(186),    GBAS, 16, // Offset(186),   GPIO Base Address
+  Offset(188),    NVGA, 32, // Offset(188),   NVIG opregion address
+  Offset(192),    NVHA, 32, // Offset(192),   NVHM opregion address
+  Offset(196),    AMDA, 32, // Offset(196),   AMDA opregion address
+  Offset(200),    LTRX, 8,  // Offset(200),   Latency Tolerance Reporting Enable
+  Offset(201),    OBFX, 8,  // Offset(201),   Optimized Buffer Flush and Fill
+  Offset(202),    LTRY, 8,  // Offset(202),   Latency Tolerance Reporting Enable
+  Offset(203),    OBFY, 8,  // Offset(203),   Optimized Buffer Flush and Fill
+  Offset(204),    LTRZ, 8,  // Offset(204),   Latency Tolerance Reporting Enable
+  Offset(205),    OBFZ, 8,  // Offset(205),   Optimized Buffer Flush and Fill
+  Offset(206),    LTRW, 8,  // Offset(206),   Latency Tolerance Reporting Enable
+  Offset(207),    OBFA, 8,  // Offset(207),   Optimized Buffer Flush and Fill
+  Offset(208),    SMSL, 16, // Offset(208),   SA Peg Latency Tolerance Reporting Max Snoop Latency
+  Offset(210),    SNSL, 16, // Offset(210),   SA Peg Latency Tolerance Reporting Max No Snoop Latency
+  Offset(212),    P0UB, 8,  // Offset(212),   Peg0 Unused Bundle Control
+  Offset(213),    P1UB, 8,  // Offset(213),   Peg1 Unused Bundle Control
+  Offset(214),    P2UB, 8,  // Offset(214),   Peg2 Unused Bundle Control
+  Offset(215),    P3UB, 8,  // Offset(215),   Peg3 Unused Bundle Control
+  Offset(216),    PCSL, 8,  // Offset(216),   The lowest C-state for the package
+  Offset(217),    PBGE, 8,  // Offset(217),   Pegx Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
+  Offset(218),    M64B, 64, // Offset(218),   Base of above 4GB MMIO resource
+  Offset(226),    M64L, 64, // Offset(226),   Length of above 4GB MMIO resource
+  Offset(234),    CPEX, 32, // Offset(234),   CPU ID info to get Family Id or Stepping
+  Offset(238),    EEC1, 8,  // Offset(238),   PCIe1 Endpoint Capability Structure Offset
+  Offset(239),    EEC2, 8,  // Offset(239),   PCIe2 Endpoint Capability Structure Offset
+  Offset(240),    SBN0, 8,  // Offset(240),   PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(241),    SBN1, 8,  // Offset(241),   PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(242),    SBN2, 8,  // Offset(242),   PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  Offset(243),    M32B, 32, // Offset(243),   Base of below 4GB MMIO resource
+  Offset(247),    M32L, 32, // Offset(247),   Length of below 4GB MMIO resource
+  Offset(251),    P0WK, 32, // Offset(251),   PCIe0 RTD3 Device Wake GPIO Number
+  Offset(255),    P1WK, 32, // Offset(255),   PCIe1 RTD3 Device Wake GPIO Number
+  Offset(259),    P2WK, 32, // Offset(259),   PCIe2 RTD3 Device Wake GPIO Number
+  Offset(263),    VTDS, 8,  // Offset(263),   VT-d Enable/Disable
+  Offset(264),    VTB1, 32, // Offset(264),   VT-d Base Address 1
+  Offset(268),    VTB2, 32, // Offset(268),   VT-d Base Address 2
+  Offset(272),    VTB3, 32, // Offset(272),   VT-d Base Address 3
+  Offset(276),    VE1V, 16, // Offset(276),   VT-d Engine#1 Vendor ID
+  Offset(278),    VE2V, 16, // Offset(278),   VT-d Engine#2 Vendor ID
+  Offset(280),    SBN3, 8,  // Offset(280),   PCIe3 Secondary Bus Number (PCIe3 Endpoint Bus Number)
+  Offset(281),    P3GP, 8,  // Offset(281),   PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  Offset(282),    HRE3, 8,  // Offset(282),   PCIe3 HLD RST IO Expander Number
+  Offset(283),    HRG3, 32, // Offset(283),   PCIe3 HLD RST GPIO Number
+  Offset(287),    HRA3, 8,  // Offset(287),   PCIe3 HLD RST GPIO Active Information
+  Offset(288),    PWE3, 8,  // Offset(288),   PCIe3 PWR Enable IO Expander Number
+  Offset(289),    PWG3, 32, // Offset(289),   PCIe3 PWR Enable GPIO Number
+  Offset(293),    PWA3, 8,  // Offset(293),   PCIe3 PWR Enable GPIO Active Information
+  Offset(294),    P3WK, 32, // Offset(294),   PCIe3 RTD3 Device Wake GPIO Number
+  Offset(298),    EEC3, 8,  // Offset(298),   PCIe3 Endpoint Capability Structure Offset
+  Offset(299),    RPIN, 8,  // Offset(299),   RootPort Number
+  Offset(300),    RPBA, 32, // Offset(300),   RootPortAddress
+  Offset (500),             // Offset(304) : Offset(499), Reserved bytes
+  }
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
new file mode 100644
index 0000000000..0db354901d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
@@ -0,0 +1,22 @@
+/** @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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+  "SaSsdt.aml",
+  "SSDT",
+  0x02,
+  "SaSsdt",
+  "SaSsdt ",
+  0x3000
+  )
+{
+  include ("SaNvs.asl")
+  include ("Sa.asl")
+}
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files

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

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc | 215 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc     | 130 ++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc       |  69 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc             |  33 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc          |  37 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc             |  21 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc          |  44 ++++
 7 files changed, 549 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
new file mode 100644
index 0000000000..37c77d8f63
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
@@ -0,0 +1,215 @@
+## @file
+#  Component description file for the Coffee Lake silicon package DSC file.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[PcdsFeatureFlag]
+gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |TRUE
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE
+gSiPkgTokenSpaceGuid.PcdSiCsmEnable                  |FALSE
+gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE
+gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE
+gSiPkgTokenSpaceGuid.PcdAcpiEnable                   |FALSE
+gSiPkgTokenSpaceGuid.PcdSourceDebugEnable            |FALSE
+gSiPkgTokenSpaceGuid.PcdPpmEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable        |FALSE
+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.PcdIpuEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE
+gSiPkgTokenSpaceGuid.PcdCflCpuEnable                 |FALSE
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |TRUE
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |TRUE
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE
+
+[PcdsFixedAtBuild.common]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress       |0xE0000000
+gSiPkgTokenSpaceGuid.PcdTemporaryPciExpressRegionLength |0x10000000
+
+  gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin        |10
+  gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax        |18
+
+[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 = CoffeelakeSiliconPkg
+  PLATFORM_GUID = A45CA44C-AB04-4932-A77C-5A7179F66A22
+  PLATFORM_VERSION = 0.4
+  DSC_SPECIFICATION = 0x00010005
+  OUTPUT_DIRECTORY = Build/CoffeelakeSiliconPkg
+  SUPPORTED_ARCHITECTURES = IA32|X64
+  BUILD_TARGETS = DEBUG|RELEASE
+  SKUID_IDENTIFIER = DEFAULT
+
+  DEFINE   PLATFORM_SI_PACKAGE        = CoffeelakeSiliconPkg
+
+  #
+  # Definition for Build Flag
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
+
+[LibraryClasses.common]
+  #
+  # Entry point
+  #
+  
+PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.in
+f
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  
+DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.in
+f
+  
+UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntr
+yPoint.inf
+  
+UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/Uefi
+ApplicationEntryPoint.inf
+  
+PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePe
+CoffExtraActionLibNull.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.i
+ nf  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  
+ PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci
+ .inf  
+ PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMa
+ intenanceLib.inf  
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BaseP
+ eCoffGetEntryPointLib.inf
+  #
+  # UEFI & PI
+  #
+  
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiB
+ ootServicesTableLib.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/PeiServicesTablePointerLibId
+ t/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTabl
+ eLib.inf
+
+  
+ S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScrip
+ tLibNull.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/BaseSynchroni
+ zationLib.inf
+
+  
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Bas
+ eDebugPrintErrorLevelLib.inf  
+ SmiHandlerProfileLib|Edk2/MdePkg/Library/SmiHandlerProfileLibNull/SmiH
+ andlerProfileLibNull.inf
+
+  #
+  # Misc
+  #
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLi
+ bNull.inf  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTempl
+ ate.inf  
+ PostCodeLib|MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.i
+ nf  
+ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseRep
+ ortStatusCodeLibNull.inf  
+ MtrrLib|ClientSiliconPkg/Override/UefiCpuPkg/Library/MtrrLib/MtrrLib.i
+ nf  # CSPO-0012: RoyalParkOverrideContent  
+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+
+#######################################################################
+##############################
+
+#
+# Silicon Init Common Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
+ConfigBlockLib|ClientSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBl
+ConfigBlockLib|ockLib.inf
+PchTraceHubInitLib|ClientSiliconPkg/Library/BasePchTraceHubInitLib/Base
+PchTraceHubInitLib|PchTraceHubInitLib.inf
+
+[LibraryClasses.IA32]
+#
+# PEI phase common
+#
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  
+MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllo
+cationLib.inf
+  
+ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiEx
+tractGuidedSectionLib.inf
+
+#######################################################################
+##############################################################
+
+#
+# Silicon Init Pei Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
+
+[LibraryClasses.IA32.SEC]
+
+[LibraryClasses.X64]
+ #
+ # DXE phase common
+ #
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  
+MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAl
+locationLib.inf
+  
+ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeEx
+tractGuidedSectionLib.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/SmmServicesTable
+Lib.inf
+  
+MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllo
+cationLib.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
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
new file mode 100644
index 0000000000..b6d2058669
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
@@ -0,0 +1,130 @@
+## @file
+# Silicon build option configuration file.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[BuildOptions]
+# Define Build Options both for EDK and EDKII drivers.
+
+# SA
+!if gSiPkgTokenSpaceGuid.PcdPttEnable == TRUE
+  DEFINE PTT_BUILD_OPTION = -DPTT_FLAG=1 !else
+  DEFINE PTT_BUILD_OPTION =
+!endif
+
+#
+# System Agent
+#
+!if gSiPkgTokenSpaceGuid.PcdSgEnable == TRUE
+  DEFINE DSC_SG_BUILD_OPTIONS = -DSG_SUPPORT=1 !else
+  DEFINE DSC_SG_BUILD_OPTIONS =
+!endif
+
+!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 =
+
+!if gSiPkgTokenSpaceGuid.PcdCflCpuEnable == TRUE
+  DEFINE CPU_FLAGS = -DCPU_CFL
+!else
+  DEFINE CPU_FLAGS =
+!endif
+
+
+DEFINE DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(BDAT_BUILD_OPTION) 
+$(PTT_BUILD_OPTION) $(DEBUG_BUILD_OPTIONS) DEFINE 
+DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) 
+$(DSC_SG_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(CPU_FLAGS) 
+$(HSLE_BUILD_OPTIONS) $(RELEASE_CATALOG_BUILD_OPTIONS) 
+$(DSC_TXT_BUILD_OPTIONS)
+
+!if gSiPkgTokenSpaceGuid.PcdSourceDebugEnable == TRUE
+  *_*_X64_GENFW_FLAGS = --keepexceptiontable !endif
+
+[BuildOptions.Common.EDKII]
+
+#
+# For IA32 Global Build Flag
+#
+       *_*_IA32_PP_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_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
+#
+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
+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_PP_FLAGS       = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_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
+#
+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
+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/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
new file mode 100644
index 0000000000..2df08c6d01
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
@@ -0,0 +1,69 @@
+## @file
+#  Component description file for the Coffee Lake silicon package both PEI and DXE libraries DSC file.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+#
+# Set PCH generation according PCD.
+# The DEFINE will be used to select PCH library INF file corresponding 
+to PCH generation # DEFINE  PCH = Cnl
+
+#
+# Cpu
+#
+ CpuPlatformLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/PeiDxeSmmCpuPlatform
+ CpuPlatformLib|Lib/PeiDxeSmmCpuPlatformLib.inf
+ CpuMailboxLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/BaseCpuMailboxLibNull
+ CpuMailboxLib|/BaseCpuMailboxLibNull.inf
+
+#
+# Me
+#
+
+#
+# Pch
+#
+ PchCycleDecodingLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchCyc
+ PchCycleDecodingLib|leDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
+ PchGbeLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxe
+ PchGbeLib|SmmPchGbeLib.inf
+ PchInfoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchInfoLib/PeiD
+ PchInfoLib|xeSmmPchInfoLib$(PCH).inf
+ SataLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmS
+ SataLib|ataLib$(PCH).inf
+ PchPcieRpLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcieRpLib/
+ PchPcieRpLib|PeiDxeSmmPchPcieRpLib.inf
+ PchPcrLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxe
+ PchPcrLib|SmmPchPcrLib.inf
+ PmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmc
+ PmcLib|Lib.inf
+
+ PchSbiAccessLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSbiAcce
+ PchSbiAccessLib|ssLib/PeiDxeSmmPchSbiAccessLib.inf
+ GpioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmG
+ GpioLib|pioLib.inf
+!if gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable == TRUE
+ PchSerialIoUartLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSeri
+ PchSerialIoUartLib|alIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
+!else
+ PchSerialIoUartLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BasePchSerialIoU
+ PchSerialIoUartLib|artLibNull/BasePchSerialIoUartLibNull.inf
+!endif
+ PchSerialIoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSerialIo
+ PchSerialIoLib|Lib/PeiDxeSmmPchSerialIoLibCnl.inf
+ PchEspiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchEspiLib/PeiD
+ PchEspiLib|xeSmmPchEspiLib.inf
+ PchWdtCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchWdtComm
+ PchWdtCommonLib|onLib/PeiDxeSmmPchWdtCommonLib.inf
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseResetSystemLib/B
+ ResetSystemLib|aseResetSystemLib.inf
+ SmbusLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseSmbusLib/BaseSmbusLib.
+ SmbusLib|inf
+ BiosLockLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmBiosLockLib/Pe
+ BiosLockLib|iDxeSmmBiosLockLib.inf
+ #private
+ PchPciExpressHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/Pei
+ PchPciExpressHelpersLib|DxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciE
+ PchPciExpressHelpersLib|xpressHelpersLib.inf
+ PchInitCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmP
+ PchInitCommonLib|chInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
+ PchSpiCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BasePchSpiC
+ PchSpiCommonLib|ommonLib/BasePchSpiCommonLib.inf
+ GpioPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmGpi
+ GpioPrivateLib|oPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
+ PchPsfPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmP
+ PchPsfPrivateLib|chPsfPrivateLib/PeiDxeSmmPchPsfPrivateLib$(PCH).inf
+ PmcPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPmcP
+ PmcPrivateLib|rivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
+ PmcPrivateLibWithS3|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeS
+ PmcPrivateLibWithS3|mmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
+ PchDmiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchDmiLi
+ PchDmiLib|b/PeiDxeSmmPchDmiLib.inf
+ PchDmiWithS3Lib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPc
+ PchDmiWithS3Lib|hDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
+ SiScheduleResetLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BaseSiSc
+ SiScheduleResetLib|heduleResetLib/BaseSiScheduleResetLib.inf
+
+#
+# SA
+#
+ SaPlatformLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiDxeSmmSaPl
+ SaPlatformLib|atformLib/PeiDxeSmmSaPlatformLib.inf
+
+#
+# Memory
+#
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
new file mode 100644
index 0000000000..07677ece1a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
@@ -0,0 +1,33 @@
+## @file
+#  Component description file for the Coffee Lake silicon package DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+#
+# Common
+#
+
+#
+# Pch
+#
+  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
+  $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
+
+  $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
+
+  $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
+  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
+
+#
+# SystemAgent
+#
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
+
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
+!endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
new file mode 100644
index 0000000000..214de06d58
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
@@ -0,0 +1,37 @@
+## @file
+#  Component description file for the Coffee Lake silicon package DXE libraries.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+#
+# Silicon Init Dxe Library
+#
+
+#
+# Common
+#
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+ AslUpdateLib|$(PLATFORM_SI_PACKAGE)/Library/DxeAslUpdateLib/DxeAslUpda
+ AslUpdateLib|teLib.inf
+!else
+ AslUpdateLib|$(PLATFORM_SI_PACKAGE)/Library/DxeAslUpdateLibNull/DxeAsl
+ AslUpdateLib|UpdateLibNull.inf
+!endif
+ SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/B
+ SiConfigBlockLib|aseSiConfigBlockLib.inf
+
+#
+# Pch
+#
+ PchHdaLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/DxePchHdaLib/DxeP
+ PchHdaLib|chHdaLib.inf
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeResetSystemLib/Dx
+ ResetSystemLib|eResetSystemLib.inf
+ DxePchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxePchPolicyLib/Dxe
+ DxePchPolicyLib|PchPolicyLib.inf
+ GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BaseGpioHelp
+ GpioHelpersLib|ersLibNull/BaseGpioHelpersLibNull.inf
+ GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/DxeGpioNa
+ GpioNameBufferLib|meBufferLib/DxeGpioNameBufferLib.inf
+ SmmPchPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/SmmPchPriv
+ SmmPchPrivateLib|ateLib/SmmPchPrivateLib.inf
+
+#
+# SystemAgent
+#
+ DxeSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/DxeSaPolicyL
+ DxeSaPolicyLib|ib/DxeSaPolicyLib.inf
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
new file mode 100644
index 0000000000..f30c7e0ae1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
@@ -0,0 +1,21 @@
+## @file
+#  Component description file for theCoffee Lake silicon package PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+#
+# Common
+#
+
+#
+# SystemAgent
+#
+
+#
+# Cpu
+#
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
new file mode 100644
index 0000000000..6e244a6ded
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
@@ -0,0 +1,44 @@
+## @file
+#  Component description file for the Coffee Lake silicon package PEI libraries.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # # 
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+#
+# Silicon Init Pei Library
+#
+ SiPolicyLib|$(PLATFORM_SI_PACKAGE)/Library/PeiSiPolicyLib/PeiSiPolicyL
+ SiPolicyLib|ib.inf
+ SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/B
+ SiConfigBlockLib|aseSiConfigBlockLib.inf
+ StallPpiLib|$(PLATFORM_SI_PACKAGE)/Library/PeiInstallStallPpiLib/PeiSt
+ StallPpiLib|allPpiLib.inf
+
+#
+# Pch
+#
+ PchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiPchPolicyLib/PeiPch
+ PchPolicyLib|PolicyLibCnl.inf
+!if gSiPkgTokenSpaceGuid.PcdOcWdtEnable == TRUE
+ OcWdtLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.in
+ OcWdtLib|f
+!else
+ OcWdtLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLi
+ OcWdtLib|bNull.inf
+!endif
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiResetSystemLib/Pe
+ ResetSystemLib|iResetSystemLib.inf
+ PchResetLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiPchResetLib/PeiPchRe
+ PchResetLib|setLib.inf
+ SpiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiSpiLib/PeiSpiLib.inf
+ GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiGpioHelpe
+ GpioHelpersLib|rsLib/PeiGpioHelpersLib.inf
+ GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiGpioNa
+ GpioNameBufferLib|meBufferLib/PeiGpioNameBufferLib.inf
+
+#
+# Me
+#
+ PeiMePolicyLib|$(PLATFORM_SI_PACKAGE)/Me/Library/PeiMePolicyLib/PeiMeP
+ PeiMePolicyLib|olicyLib.inf
+
+#
+# SA
+#
+  
+PeiSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiSaPolicyLi
+b/PeiSaPolicyLib.inf
+#
+# Cpu
+#
+ CpuPolicyLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/PeiCpuPolicyLib/PeiCpu
+ CpuPolicyLib|PolicyLib.inf
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
@ 2019-08-17  0:53   ` Nate DeSimone
  2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:53 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers

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

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Maintainers.txt | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Maintainers.txt b/Maintainers.txt index 876ae5612a..bc8cbd6458 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -125,9 +125,14 @@ Silicon/Intel/Vlv2DeviceRefCodePkg
 M: Zailiang Sun <zailiang.sun@intel.com>
 M: Yi Qian <yi.qian@intel.com>
 
+Silicon/Intel/CoffeelakeSiliconPkg
+M: Chasel Chiu <chasel.chiu@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
+M: Sai Chaganty <rangasai.v.chaganty@intel.com>
+
 Silicon/Intel/KabylakeSiliconPkg
 M: Chasel Chiu <chasel.chiu@intel.com>
-M: Michael A Kubacki <michael.a.kubacki@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
 M: Sai Chaganty <rangasai.v.chaganty@intel.com>
 
 Silicon/Intel/LewisburgPkg
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  2019-08-19 18:09   ` Sinha, Ankit
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers

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

Create the WhiskeylakeOpenBoardPkg to provide board support code. The
package may support Coffee Lake (CFL) and Whiskey Lake (WHL) boards. The
package serves as a board support package in the EDK II Minimum Platform
design. Silicon support for this package is provided in CoffeeLakeFspBinPkg
in the FSP repository and CoffeelakeSiliconPkg in the edk2-platforms
repository.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec                                           |  565 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h     |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h             |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h           |  131 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h     |   21 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h             |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h       |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h                |  261 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h                    |   31 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h      |  130 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h         |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h               |  137 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h                 |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h                        |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h                       |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h           |   84 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h                            |  118 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h                                  |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h                                           |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h                           |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h                                     | 1766 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h                                   |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h                                       |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h                    |   75 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h                     |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h                    |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h                  |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h                     |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h                         |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h                     |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h                          |  123 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h                          |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h                             |   34 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h                           |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h                  |  141 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h                         |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h                          |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h                                |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h                          |  106 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h                                         |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h                                  |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h                           |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h                                            |  144 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h                                          |  157 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl                                 |  112 ++
 46 files changed, 5288 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
new file mode 100644
index 0000000000..9d56f0e841
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
@@ -0,0 +1,565 @@
+## @file
+# Module describe the entire platform configuration.
+#
+# The DEC files are used by the utilities that parse DSC and
+# INF files to generate AutoGen.c and AutoGen.h files
+# for the build infrastructure.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+
+[Defines]
+DEC_SPECIFICATION = 0x00010017
+PACKAGE_NAME = OpenBoardPkg
+PACKAGE_VERSION = 0.1
+PACKAGE_GUID = 0A8BA6E8-C8AC-4AC1-87AC-52772FA6AE5E
+
+[Includes]
+Include
+WhiskeylakeURvp\Include
+Features\Tbt\Include
+
+[Guids]
+
+gBoardModuleTokenSpaceGuid            =  {0x72d1fff7, 0xa42a, 0x4219, {0xb9, 0x95, 0x5a, 0x67, 0x53, 0x6e, 0xa4, 0x2a}}
+
+gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+
+gTbtInfoHobGuid                       =  {0x74a81eaa, 0x033c, 0x4783, {0xbe, 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}}
+
+gPlatformModuleTokenSpaceGuid         =  {0x69d13bf0, 0xaf91, 0x4d96, {0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0}}
+
+gMeInfoSetupGuid                      =  {0x78259433, 0x7b6d, 0x4db3, {0x9a, 0xe8, 0x36, 0xc4, 0xc2, 0xc3, 0xa1, 0x7d}}
+gRealModeFileGuid                     =  {0xdf84ed23, 0x5d53, 0x423f, {0xaa, 0x81, 0x0f, 0x0e, 0x6f, 0x55, 0xc6, 0x9b}}
+gVirtualKeyboardDriverImageGuid       =  {0xe4735aac, 0x9c27, 0x493f, {0x86, 0xea, 0x9e, 0xff, 0x43, 0xd7, 0xad, 0xcd}}
+gPegConfigVariableGuid                =  {0xb414caf8, 0x8225, 0x4d6f, {0xb9, 0x18, 0xcd, 0xe5, 0xcb, 0x84, 0xcf, 0x0b}}
+gSaSetupVariableGuid                  =  {0x72c5e28c, 0x7783, 0x43a1, {0x87, 0x67, 0xfa, 0xd7, 0x3f, 0xcc, 0xaf, 0xa4}}
+gMeSetupVariableGuid                  =  {0x5432122d, 0xd034, 0x49d2, {0xa6, 0xde, 0x65, 0xa8, 0x29, 0xeb, 0x4c, 0x74}}
+gCpuSetupVariableGuid                 =  {0xb08f97ff, 0xe6e8, 0x4193, {0xa9, 0x97, 0x5e, 0x9e, 0x9b, 0xa,  0xdb, 0x32}}
+gCpuSmmGuid                           =  {0x90d93e09, 0x4e91, 0x4b3d, {0x8c, 0x77, 0xc8, 0x2f, 0xf1, 0xe,  0x3c, 0x81}}
+gPchSetupVariableGuid                 =  {0x4570b7f1, 0xade8, 0x4943, {0x8d, 0xc3, 0x40, 0x64, 0x72, 0x84, 0x23, 0x84}}
+gSiSetupVariableGuid                  =  {0xAAF8E719, 0x48F8, 0x4099, {0xA6, 0xF7, 0x64, 0x5F, 0xBD, 0x69, 0x4C, 0x3D}}
+gDebugConfigVariableGuid              =  {0xDE0A5E74, 0x4E3E, 0x3D96, {0xA4, 0x40, 0x2C, 0x96, 0xEC, 0xBD, 0x3C, 0x97}}
+gDebugConfigHobGuid                   =  {0x2f6a6bb7, 0x9dc7, 0x4bf6, {0x94, 0x04, 0x22, 0x70, 0xc0, 0xe3, 0xbe, 0x2f}}
+gChassisIntrudeDetHobGuid             =  {0xdea43de2, 0x756b, 0x4b3b, {0x75, 0x1c, 0xad, 0xeb, 0x8d, 0xff, 0x56, 0xa3}}
+
+gGpioCheckConflictHobGuid             =  {0x5603f872, 0xefac, 0x40ae, {0xb9, 0x7e, 0x13, 0xb2, 0xf8, 0x07, 0x80, 0x21}}
+
+gAttemptUsbFirstHotkeyInfoHobGuid     =  {0x38b8e214, 0x1468, 0x4bb7, {0x95, 0xb1, 0x74, 0x59, 0x1e, 0x4c, 0x6e, 0x1d}}
+gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+##
+## ChipsetInitBinary
+##
+gCnlPchLpChipsetInitTableDxGuid          =  {0xc9505bc0, 0xaa3d, 0x4056, {0x99, 0x95, 0x87, 0x0c, 0x8d, 0xe8, 0x59, 0x4e}}
+
+
+[Protocols]
+gTbtNvsAreaProtocolGuid               =  {0x4d6a54d1, 0xcd56, 0x47f3, {0x93, 0x6e, 0x7e, 0x51, 0xd9, 0x31, 0x15, 0x4f}}
+gDxeTbtPolicyProtocolGuid             =  {0x196bf9e3, 0x20d7, 0x4b7b, {0x89, 0xf9, 0x31, 0xc2, 0x72, 0x08, 0xc9, 0xb9}}
+
+[Ppis]
+gPeiTbtPolicyPpiGuid                  =  {0xd7e7e1e6, 0xcbec, 0x4f5f, {0xae, 0xd3, 0xfd, 0xc0, 0xa8, 0xb0, 0x7e, 0x25}}
+gPeiTbtPolicyBoardInitDonePpiGuid     =  {0x970f9c60, 0x8547, 0x49d7, { 0xa4, 0xb, 0x1e, 0xc4, 0xbc, 0x4e, 0xe8, 0x9b}}
+
+[LibraryClasses]
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+
+[PcdsFixedAtBuild]
+
+gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange|0x0010|UINT16|0x10001004
+gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding|0x3c03|UINT16|0x10001005
+
+gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress|0xFED18000|UINT64|0x90000003
+gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize|0x1000|UINT32|0x90000004
+gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress|0xFED19000|UINT64|0x90000005
+gPlatformModuleTokenSpaceGuid.PcdEpMmioSize|0x1000|UINT32|0x90000006
+gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress|0xFED84000|UINT64|0x90000007
+gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize|0x1000|UINT32|0x90000008
+gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress|0xFED80000|UINT64|0x90000009
+gPlatformModuleTokenSpaceGuid.PcdEdramMmioSize|0x4000|UINT32|0x9000000A
+gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress|0xFEE00000|UINT64|0x9000000B
+gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize|0x1000|UINT32|0x9000000C
+gPlatformModuleTokenSpaceGuid.PcdApicIoAddress|0xFEC00000|UINT64|0x9000000D
+gPlatformModuleTokenSpaceGuid.PcdApicIoMmioSize|0x1000|UINT32|0x9000000E
+gPlatformModuleTokenSpaceGuid.PcdGttMmAddress|0xCF000000|UINT64|0x9000000F
+gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress|0xD0000000|UINT64|0x90000010
+gPlatformModuleTokenSpaceGuid.PcdAcpiEnableSwSmi|0xF0|UINT8|0x90000012
+gPlatformModuleTokenSpaceGuid.PcdAcpiDisableSwSmi|0xF1|UINT8|0x90000013
+gPlatformModuleTokenSpaceGuid.PcdPcieDockBridgeResourcePatchSmi|0x4D|UINT8|0x90000014
+gPlatformModuleTokenSpaceGuid.PcdCmosFastBootDefaultValue|0x01|UINT8|0x90000016
+gPlatformModuleTokenSpaceGuid.PcdCmosDebugPrintErrorLevelDefaultValue|0x80000046|UINT32|0x90000017
+gPlatformModuleTokenSpaceGuid.PcdOverClockingInterfaceSwSmi|0x72|UINT8|0x90000019
+gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort|0x2F|UINT16|0x9000001A
+gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort|0x2E|UINT16|0x9000001B
+gPlatformModuleTokenSpaceGuid.PcdApicIoIdPch|0x02|UINT8|0x9000001E
+gPlatformModuleTokenSpaceGuid.PcdRuntimeUpdateFvHeaderLength|0x48|UINT8|0x90000020
+gPlatformModuleTokenSpaceGuid.PcdEcExtraIoBase|0x6A0|UINT16|0x20000505
+gPlatformModuleTokenSpaceGuid.PcdFspTemporaryRamSize|0x1000|UINT32|0x10001003
+
+gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition|0x01|UINT8|0x90000015
+gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort|0x4e|UINT16|0x90000018
+gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort|0x164E|UINT16|0x9000001C
+gBoardModuleTokenSpaceGuid.PcdSioBaseAddress|0x0680|UINT16|0x9000001D
+gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort|0x4f|UINT16|0x9000001F
+gBoardModuleTokenSpaceGuid.PcdLpcSioIndexDefaultPort|0x164E|UINT16|0x90000021
+gBoardModuleTokenSpaceGuid.PcdLpcSioDataDefaultPort|0x164F|UINT16|0x90000022
+
+[PcdsDynamic]
+# Board GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable|0|UINT32|0x00000040
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize|0|UINT16|0x00000041
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2|0|UINT32|0x00000042
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size|0|UINT16|0x00000043
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem|0|UINT32|0x000000113
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize|0|UINT16|0x000000114
+
+# Board Expander GPIO Table
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable|0|UINT32|0x00000044
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize|0|UINT16|0x00000045
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2|0|UINT32|0x00000046
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size|0|UINT16|0x00000047
+
+# TouchPanel & SDHC CD GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel|0|UINT32|0x00000048
+
+# PCH-LP HSIO PTSS Table
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1|0|UINT32|0x0000004A
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2|0|UINT32|0x0000004B
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size|0|UINT16|0x0000004C
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size|0|UINT16|0x0000004D
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1|0|UINT32|0x0000004E
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2|0|UINT32|0x0000004F
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size|0|UINT16|0x00000050
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size|0|UINT16|0x00000051
+
+# PCH-H HSIO PTSS Table
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1|0|UINT32|0x00000052
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2|0|UINT32|0x00000053
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size|0|UINT16|0x00000054
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size|0|UINT16|0x00000055
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1|0|UINT32|0x00000056
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2|0|UINT32|0x00000057
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size|0|UINT16|0x00000058
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size|0|UINT16|0x00000059
+
+# HDA Verb Table
+gBoardModuleTokenSpaceGuid.PcdHdaVerbTable|0|UINT32|0x0000005A
+gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2|0|UINT32|0x0000005B
+gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable|0|UINT32|0x0000005C
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1|0|UINT32|0x0000005D
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2|0|UINT32|0x0000005E
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3|0|UINT32|0x0000005F
+gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable|0|UINT32|0x00000060
+
+# SA Misc Configuration
+gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd|0|UINT8|0x00000066
+gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment|0|UINT16|0x00000067
+gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit|0|UINT16|0x00000101
+
+# DRAM Configuration
+gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor|0|UINT32|0x00000068
+gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget|0|UINT32|0x00000069
+gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap|0|UINT32|0x0000006A
+gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize|0|UINT16|0x0000006B
+gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram|0|UINT32|0x0000006C
+gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize|0|UINT16|0x0000006D
+gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl|FALSE|BOOLEAN|0x0000006E
+gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved|FALSE|BOOLEAN|0x0000006F
+gBoardModuleTokenSpaceGuid.PcdMrcSpdData|0|UINT32|0x00000070
+gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize|0|UINT16|0x00000071
+
+# PEG RESET GPIO
+gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl|FALSE|BOOLEAN|0x00000072
+gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort|FALSE|BOOLEAN|0x00000073
+gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo|0|UINT32|0x00000079
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo|0|UINT8|0x0000007A
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo|0|UINT32|0x0000007B
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive|FALSE|BOOLEAN|0x0000007C
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo|0|UINT8|0x0000007D
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo|0|UINT32|0x0000007E
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive|FALSE|BOOLEAN|0x0000007F
+
+# SPD Address Table
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0|0|UINT8|0x00000099
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1|0|UINT8|0x0000009A
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2|0|UINT8|0x0000009B
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3|0|UINT8|0x0000009C
+
+# CA Vref Configuration
+gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig|0|UINT8|0x0000009D
+
+# USB 2.0 Port AFE
+gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe|0|UINT32|0x000000BF
+gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe|0|UINT32|0x000000C0
+gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe|0|UINT32|0x000000C1
+gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe|0|UINT32|0x000000C2
+gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe|0|UINT32|0x000000C3
+gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe|0|UINT32|0x000000C4
+gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe|0|UINT32|0x000000C5
+gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe|0|UINT32|0x000000C6
+gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe|0|UINT32|0x000000C7
+gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe|0|UINT32|0x000000C8
+gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe|0|UINT32|0x000000C9
+gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe|0|UINT32|0x000000CA
+gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe|0|UINT32|0x000000CB
+gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe|0|UINT32|0x000000CC
+gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe|0|UINT32|0x000000CD
+gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe|0|UINT32|0x000000CE
+
+# USB 2.0 Port Over Current Pin
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0|0|UINT8|0x000000CF
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1|0|UINT8|0x000000D0
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2|0|UINT8|0x000000D1
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3|0|UINT8|0x000000D2
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4|0|UINT8|0x000000D3
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5|0|UINT8|0x000000D4
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6|0|UINT8|0x000000D5
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7|0|UINT8|0x000000D6
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8|0|UINT8|0x000000D7
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9|0|UINT8|0x000000D8
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10|0|UINT8|0x000000D9
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11|0|UINT8|0x000000DA
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12|0|UINT8|0x000000DB
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13|0|UINT8|0x000000DC
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14|0|UINT8|0x000000DD
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15|0|UINT8|0x000000DE
+
+# USB 3.0 Port Over Current Pin
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0|0|UINT8|0x000000DF
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1|0|UINT8|0x000000E0
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2|0|UINT8|0x000000E1
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3|0|UINT8|0x000000E2
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4|0|UINT8|0x000000E3
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5|0|UINT8|0x000000E4
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6|0|UINT8|0x000000E5
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7|0|UINT8|0x000000E6
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8|0|UINT8|0x000000E7
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9|0|UINT8|0x000000E8
+
+# Misc
+gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent|FALSE|BOOLEAN|0x000000EC
+
+# TBT
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel |0|BOOLEAN|0x000000F3
+gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad |0|UINT32|0x000000F4
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad |0|UINT32|0x000000F5
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport |0|UINT8|0x000000FA
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI |0|UINT8|0x000000FB
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify |0|UINT8|0x000000FC
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq|0|UINT8|0x000000FD
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm |0|UINT8|0x000000FE
+gBoardModuleTokenSpaceGuid.PcdDTbtLtr | 0 | UINT8| 0x00000116
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch |0|UINT8|0x000000FF
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt |0|UINT8|0x00000100
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq |0|UINT8|0x0000010A
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax |0|UINT8|0x00000107
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd |0|UINT16|0x00000108
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax |0|UINT8|0x00000109
+
+# UCMC GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable|0|UINT32|0x000000111
+gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize|0|UINT16|0x000000112
+
+gBoardModuleTokenSpaceGuid.PcdAcpiSleepState|1|UINT8|0x40000002
+gBoardModuleTokenSpaceGuid.PcdAcpiHibernate|1|UINT8|0x40000003
+gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle|0|UINT8|0x40000004
+gBoardModuleTokenSpaceGuid.PcdPciExpNative|0|UINT8|0x40000005
+gBoardModuleTokenSpaceGuid.PcdNativeAspmEnable|1|UINT8|0x40000006
+gBoardModuleTokenSpaceGuid.PcdPs2KbMsEnable|0|UINT8|0x40000009
+gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints|1|UINT8|0x4000000A
+gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints|0|UINT8|0x4000000B
+gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints|1|UINT8|0x4000000C
+
+# 0: Type-C
+# 1: Stacked-Jack
+gBoardModuleTokenSpaceGuid.PcdAudioConnector|0|UINT8|0x40000012
+
+gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress|0|UINT64|0x40000013
+
+# gIntelPeiGraphicsVbtGuid =  {0x4ad46122, 0xffeb, 0x4a52, {0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}}
+gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid|{0x22, 0x61, 0xd4, 0x4a, 0xeb, 0xff, 0x52, 0x4a, 0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}|VOID*|0x40000014
+#==============================================================
+#
+# The PCD which indicates the Memory Slot Population.
+#
+gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType|FALSE|BOOLEAN|0x00101027
+gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate|0|UINT64|0x00000010
+
+# Board GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem|0|UINT32|0x001000115
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize|0|UINT16|0x001000116
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem|0|UINT32|0x001000117
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize|0|UINT16|0x001000118
+gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio|0x0|UINT32|0x0010020C
+gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity|0x0|UINT8|0x0010022E
+gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio|0x0|UINT32|0x0010022F
+gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio|0x0|UINT32|0x00100230
+gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable|FALSE|BOOLEAN|0x00100231
+gBoardModuleTokenSpaceGuid.PcdWlanWakeGpio|0x0|UINT32|0x00100234
+gBoardModuleTokenSpaceGuid.PcdWlanRootPortNumber|0x0|UINT8|0x00100235
+gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround|FALSE|BOOLEAN|0x00100236
+
+# UCMC GPIO Table
+gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable|0|UINT32|0x00100033
+gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize|0|UINT16|0x00100034
+
+# PEG RESET GPIO
+gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad|0|UINT32|0x00000074
+gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive|FALSE|BOOLEAN|0x00000075
+gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad|0|UINT32|0x00000105
+gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive|FALSE|BOOLEAN|0x00000106
+
+# PCIE RTD3 GPIO
+gBoardModuleTokenSpaceGuid.PcdRootPortDev|0xFF|UINT8|0x00000076
+gBoardModuleTokenSpaceGuid.PcdRootPortFunc|0xFF|UINT8|0x00000077
+gBoardModuleTokenSpaceGuid.PcdRootPortIndex|0xFF|UINT8|0x00000104
+gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport|0|UINT8|0x00000078
+
+gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport|0|UINT8|0x00000080
+gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo|0|UINT32|0x00000081
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo|0|UINT8|0x00000082
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo|0|UINT32|0x00000083
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive|FALSE|BOOLEAN|0x00000084
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo|0|UINT8|0x00000085
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo|0|UINT32|0x00000086
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive|FALSE|BOOLEAN|0x00000087
+
+gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport|0|UINT8|0x00000088
+gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo|0|UINT32|0x00000089
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo|0|UINT8|0x0000008A
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo|0|UINT32|0x0000008B
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive|FALSE|BOOLEAN|0x0000008C
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo|0|UINT8|0x0000008D
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo|0|UINT32|0x0000008E
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive|FALSE|BOOLEAN|0x0000008F
+gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport|0|UINT8|0x00000130
+gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo|0|UINT32|0x00000131
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo|0|UINT8|0x00000132
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo|0|UINT32|0x00000133
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive|FALSE|BOOLEAN|0x00000134
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo|0|UINT8|0x00000135
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo|0|UINT32|0x00000136
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive|FALSE|BOOLEAN|0x00000137
+
+# Root Port Clock Info
+gBoardModuleTokenSpaceGuid.PcdPcieClock0|0|UINT64|0x0000009E
+gBoardModuleTokenSpaceGuid.PcdPcieClock1|0|UINT64|0x0000009F
+gBoardModuleTokenSpaceGuid.PcdPcieClock2|0|UINT64|0x000000A0
+gBoardModuleTokenSpaceGuid.PcdPcieClock3|0|UINT64|0x000000A1
+gBoardModuleTokenSpaceGuid.PcdPcieClock4|0|UINT64|0x000000A2
+gBoardModuleTokenSpaceGuid.PcdPcieClock5|0|UINT64|0x000000A3
+gBoardModuleTokenSpaceGuid.PcdPcieClock6|0|UINT64|0x000000A4
+gBoardModuleTokenSpaceGuid.PcdPcieClock7|0|UINT64|0x000000A5
+gBoardModuleTokenSpaceGuid.PcdPcieClock8|0|UINT64|0x000000A6
+gBoardModuleTokenSpaceGuid.PcdPcieClock9|0|UINT64|0x000000A7
+gBoardModuleTokenSpaceGuid.PcdPcieClock10|0|UINT64|0x000000A8
+gBoardModuleTokenSpaceGuid.PcdPcieClock11|0|UINT64|0x000000A9
+gBoardModuleTokenSpaceGuid.PcdPcieClock12|0|UINT64|0x000000AA
+gBoardModuleTokenSpaceGuid.PcdPcieClock13|0|UINT64|0x000000AB
+gBoardModuleTokenSpaceGuid.PcdPcieClock14|0|UINT64|0x000000AC
+gBoardModuleTokenSpaceGuid.PcdPcieClock15|0|UINT64|0x000000AD
+
+# GPIO Group Tier
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0|0|UINT32|0x000000E9
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1|0|UINT32|0x000000EA
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2|0|UINT32|0x000000EB
+
+# Board related PCH PmConfig
+gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl|FALSE|BOOLEAN|0x000000F6
+gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport|FALSE|BOOLEAN|0x000000F7
+gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport|FALSE|BOOLEAN|0x000000F8
+
+# Misc
+gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent|FALSE|BOOLEAN|0x000000ED
+gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable|FALSE|BOOLEAN|0x000000EE
+gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent|FALSE|BOOLEAN|0x000000EF
+gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio|0|UINT64|0x000000F0
+gBoardModuleTokenSpaceGuid.PcdMobileDramPresent|FALSE|BOOLEAN|0x000000F1
+gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable|FALSE|BOOLEAN|0x000000F2
+gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable|FALSE|BOOLEAN|0x000000F9
+#gBoardModuleTokenSpaceGuid.PcdxxxNotInUse|FALSE|BOOLEAN|0x000000FC
+
+#PlatformInfoPcd
+gBoardModuleTokenSpaceGuid.PcdEnableVoltageMargining|FALSE|BOOLEAN|0x00101000
+gBoardModuleTokenSpaceGuid.PcdGfxCrbDetect|FALSE|BOOLEAN|0x00101001
+gBoardModuleTokenSpaceGuid.PcdHsioBoardPresent|FALSE|BOOLEAN|0x00101002
+gBoardModuleTokenSpaceGuid.PcdHsioBoardType|0x0|UINT8|0x00101003
+gBoardModuleTokenSpaceGuid.PcdWakeupType|0x0|UINT8|0x00101004
+gBoardModuleTokenSpaceGuid.PcdMfgMode|FALSE|BOOLEAN|0x00101005
+gBoardModuleTokenSpaceGuid.PcdBoardName|L"0123456789ABCDEF0123456789ABCDEF"|VOID*|0x00101007
+gBoardModuleTokenSpaceGuid.PcdEcMajorRevision|0x0|UINT8|0x00101008
+gBoardModuleTokenSpaceGuid.PcdEcMinorRevision|0x0|UINT8|0x00101009
+gBoardModuleTokenSpaceGuid.PcdBiosVersion|L"0123456789012345678901234567890123456789"|VOID*|0x0010100E
+gBoardModuleTokenSpaceGuid.PcdReleaseDate|L"01234567890123456789"|VOID*|0x0010100F
+gBoardModuleTokenSpaceGuid.PcdReleaseTime|L"01234567890123456789"|VOID*|0x00101010
+gBoardModuleTokenSpaceGuid.PcdPlatformGeneration|0x0|UINT8|0x00101011
+gBoardModuleTokenSpaceGuid.PcdSpdPresent|FALSE|BOOLEAN|0x00101012
+gBoardModuleTokenSpaceGuid.PcdDockAttached|FALSE|BOOLEAN|0x00101013
+gBoardModuleTokenSpaceGuid.PcdPlatformType|0x0|UINT8|0x00101014
+gBoardModuleTokenSpaceGuid.PcdPlatformFlavor|0x0|UINT8|0x00101015
+gBoardModuleTokenSpaceGuid.PcdBoardRev|0x0|UINT8|0x00101016
+gBoardModuleTokenSpaceGuid.PcdBoardBomId|0x0|UINT8|0x00101017
+gBoardModuleTokenSpaceGuid.PcdBoardId|0x0|UINT8|0x00101018
+gBoardModuleTokenSpaceGuid.PcdBoardType|0x0|UINT8|0x00101019
+gBoardModuleTokenSpaceGuid.PcdEcPresent|FALSE|BOOLEAN|0x0010101A
+
+# PCH Misc Configuration
+gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable|FALSE|BOOLEAN|0x00000061
+gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable|FALSE|BOOLEAN|0x00000065
+gBoardModuleTokenSpaceGuid.PcdSmbiosFabBoardName|0|UINT64|0x00000102
+gBoardModuleTokenSpaceGuid.PcdSmbiosMainSlotEntry|0|UINT64|0x00000103
+gBoardModuleTokenSpaceGuid.PcdUsbcEcPdNegotiation|FALSE|BOOLEAN|0x00000110
+
+# Control PCD to dump default silicon policy
+gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy|FALSE|BOOLEAN|0x00010064
+
+# Pch SerialIo I2c Pads Termination
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm|0x1|UINT8|0x00000020
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm|0x1|UINT8|0x00000021
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm|0x1|UINT8|0x00000022
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm|0x1|UINT8|0x00000023
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm|0x1|UINT8|0x00000030
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm|0x1|UINT8|0x00000031
+#
+# The PCD which holds the pointer of Smbios Platform Info table
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosPlatformInfo|0|UINT64|0x0010101B
+#
+# The PCD which used to enable / disable the code to use RVP Smbios Board Info
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfoEnable|FALSE|BOOLEAN|0x0010101C
+#
+# The PCD which holds the pointer of RVP Smbios Board Info
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfo|0|UINT64|0x0010101D
+#
+# CoEngineering Custom Defaults PCD
+#
+gBoardModuleTokenSpaceGuid.PcdCoEngEnableCustomDefaults|0x0|UINT8|0x00100227
+#
+# The PCD which is defined to enable/disable the SMBus Alert function.
+#
+gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable|FALSE|BOOLEAN|0x0010101E
+#
+# The PCD which is defined to enable/disable the SATA LED function.
+#
+gBoardModuleTokenSpaceGuid.PcdSataLedEnable|FALSE|BOOLEAN|0x0010101F
+#
+# The PCD which is defined to enable/disable the VR Alert function.
+#
+gBoardModuleTokenSpaceGuid.PcdVrAlertEnable|FALSE|BOOLEAN|0x00101020
+#
+# The PCD which is defined to enable/disable the PCH thermal hot threshold function.
+#
+gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable|FALSE|BOOLEAN|0x00101021
+#
+# The PCD which is defined to enable/disable the memory thermal sensor GPIO C/D function.
+#
+gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEnable|TRUE|BOOLEAN|0x00101022
+gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEnable|TRUE|BOOLEAN|0x00101023
+#
+# The PCD defines the I2C bus number to which PSS chip connected.
+#
+gBoardModuleTokenSpaceGuid.PcdPssReadSN|FALSE|BOOLEAN|0x00101024
+gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber|0x04|UINT8|0x00101025
+gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress|0x6E|UINT8|0x00101026
+#
+# The PCD defines the USB port number to which BLE connected.
+#
+gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber                     |0x0|UINT8|0x00101028
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support                    |0x00|UINT8|0x00100113
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support                    |0x00|UINT8|0x00100114
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support                    |0x00|UINT8|0x00100115
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support                    |0x00|UINT8|0x00100116
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support                    |0x00|UINT8|0x00100117
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support                    |0x00|UINT8|0x00100118
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport         |FALSE|BOOLEAN|0x00100119
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport       |FALSE|BOOLEAN|0x0010011A
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport       |FALSE|BOOLEAN|0x0010011B
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport     |FALSE|BOOLEAN|0x0010011C
+gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport               |FALSE|BOOLEAN|0x0010011D
+gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport                |FALSE|BOOLEAN|0x0010011F
+gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin                 |0x00|UINT32|0x00100120
+gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport           |FALSE|BOOLEAN|0x00100121
+gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport           |FALSE|BOOLEAN|0x00100122
+gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature                  |FALSE|BOOLEAN|0x00100123
+gBoardModuleTokenSpaceGuid.PcdBatteryPresent                       |0x0|UINT8|0x00100124
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport|FALSE|BOOLEAN|0x00100212
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess|FALSE|BOOLEAN|0x00100213
+gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature|0x0|UINT64|0x00100204
+gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile|0x0|UINT8|0x00100205
+gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio|0x0|UINT32|0x00100209
+gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio|0x0|UINT32|0x0010020A
+gBoardModuleTokenSpaceGuid.PcdGnssResetGpio|0x0|UINT32|0x0010020B
+gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio|0x0|UINT32|0x0010020F
+gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio|0x0|UINT32|0x00100210
+
+gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio                   |0x0|UINT32|0x00100126
+gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber              |0x0|UINT8|0x00100127
+gBoardModuleTokenSpaceGuid.PcdEcSmiGpio|0x0|UINT32|0x00100200
+gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio                   |0x0|UINT32|0x00100125
+gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad|0x0|UINT32|0x00100201
+gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck|FALSE|BOOLEAN|0x00100202
+gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride|FALSE|BOOLEAN|0x00100203
+gBoardModuleTokenSpaceGuid.PcdDDISelection|0x0|UINT8|0x00100215
+gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio|0x0|UINT64|0x00100217
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1|0x00|UINT8|0x00100039
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch|0x00|UINT8|0x0010003A
+gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties|0x00|UINT8|0x0010003B
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2|0x00|UINT8|0x0010003C
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch|0x00|UINT8|0x0010003D
+gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties|0x00|UINT8|0x0010003E
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3|0x00|UINT8|0x0010003F
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch|0x00|UINT8|0x00100040
+gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties|0x00|UINT8|0x00100041
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4|0x00|UINT8|0x00100042
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch|0x00|UINT8|0x00100043
+gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties|0x00|UINT8|0x00100044
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5|0x00|UINT8|0x00100045
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch|0x00|UINT8|0x00100046
+gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties|0x00|UINT8|0x00100047
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6|0x00|UINT8|0x00100048
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch|0x00|UINT8|0x00100049
+gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties|0x00|UINT8|0x0010004A
+gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed                     |0x0|UINT8|0x00100128
+gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed                     |0x0|UINT8|0x00100129
+gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed                     |0x0|UINT8|0x0010012A
+gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed                     |0x0|UINT8|0x0010012B
+
+# Super IO Pcd
+gPlatformModuleTokenSpaceGuid.PcdH8S2113Present|TRUE|BOOLEAN|0xF0000100
+gPlatformModuleTokenSpaceGuid.PcdNat87393Present|TRUE|BOOLEAN|0xF0000104
+gPlatformModuleTokenSpaceGuid.PcdNct677FPresent|TRUE|BOOLEAN|0xF0000105
+gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport               |FALSE|BOOLEAN|0x00100112
+gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin                     |0x00|UINT32|0x00100111
+gBoardModuleTokenSpaceGuid.PcdRealBattery1Control                  |0x00|UINT8|0x00100103
+gBoardModuleTokenSpaceGuid.PcdRealBattery2Control                  |0x00|UINT8|0x00100104
+
+gBoardModuleTokenSpaceGuid.PcdDimmPopulationError|FALSE|BOOLEAN|0x00100221
+gBoardModuleTokenSpaceGuid.PcdBtIrqGpio|0x0|UINT32|0x0010020E
+gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio|0x0|UINT32|0x0010020D
+gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable|FALSE|BOOLEAN|0x0010022C
+gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported|0x00|UINT8|0x0010004B
+gBoardModuleTokenSpaceGuid.PcdMipiCamSensor                        |FALSE|BOOLEAN|0x00100105
+gBoardModuleTokenSpaceGuid.PcdH8S2113SIO                           |FALSE|BOOLEAN|0x0010010A
+gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM                          |FALSE|BOOLEAN|0x00100107
+gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO                          |FALSE|BOOLEAN|0x00100108
+gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON                        |FALSE|BOOLEAN|0x00100109
+
+[PcdsDynamicEx]
+
+[PcdsDynamic, PcdsDynamicEx]
+
+[PcdsPatchableInModule]
+
+[PcdsFeatureFlag]
+gBoardModuleTokenSpaceGuid.PcdIntelGopEnable      |TRUE|BOOLEAN|0xF0000062
+gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport   |TRUE|BOOLEAN|0xF0000000
+gBoardModuleTokenSpaceGuid.PcdTbtEnable           |FALSE|BOOLEAN|0x000000115
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
new file mode 100644
index 0000000000..4aae18cac4
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Header file for the DxeCheckIommuSupport library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+#define _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
+/**
+  Detect ME FW and Board Type and return the result via IommuSkuCheck.
+
+  IommuSkuCheck
+  BIT0: Indicate system has a Corporate CSME firmware
+  BIT1: Indicate BIOS is running on a WHL RVP
+  BIT2: Indicate BIOS is running on a CFL-H RVP
+  BIT3: Indicate BIOS is running on a CFL-S 8+2 RVP
+
+  @retval Return 0 means not support, otherwise value is defined by IommuSkuCheck
+**/
+UINT8
+DetectMeAndBoard (
+  VOID
+  );
+
+/**
+  DxeCheckIommuSupport
+
+  Only WHL/CFL-H/CFL-S 8+2 Crop SKUs support Iommu.
+  This function will save sku information to PcdIommuSkuCheck.
+  BIOS will use PcdIommuSkuCheck and other factors to set PcdVTdPolicyPropertyMask on the next boot in PEI phase
+
+  This function might perform a system reset.
+**/
+EFI_STATUS
+EFIAPI
+DxeCheckIommuSupport (
+  VOID
+  );
+#endif // _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
new file mode 100644
index 0000000000..167cc8af83
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
@@ -0,0 +1,49 @@
+/** @file
+  Prototype of the DxeTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_LIB_H_
+#define _DXE_TBT_POLICY_LIB_H_
+
+
+/**
+  Install TBT Policy.
+
+  @param[in] ImageHandle                Image handle of this driver.
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+  IN  EFI_HANDLE                    ImageHandle
+  );
+
+/**
+  Update Tbt Policy Callback.
+
+  @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
+UpdateTbtPolicyCallback (
+  VOID
+  );
+
+/**
+  Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+  VOID
+  );
+#endif // _DXE_TBT_POLICY_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
new file mode 100644
index 0000000000..17337ceb0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
@@ -0,0 +1,131 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_SECURITY_LIB_H_
+#define _TBT_SECURITY_LIB_H_
+
+#include <Protocol/Tcg2Protocol.h>
+#include <Protocol/AcpiTable.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi.h>
+#include <SetupVariable.h>
+#include <OemSetup.h>
+#include <DmaRemappingTable.h>
+#include <PcieRegs.h>
+#include <Tcg2ConfigNvData.h>
+#include <TbtPolicyCommonDefinition.h>
+#include <Library/TbtCommonLib.h>
+
+#define TBT_SECURITY_EVENT_STRING                 "DMA Protection Disabled"
+#define TBT_SECURITY_EVENT_STRING_LEN             (sizeof (TBT_SECURITY_EVENT_STRING) - 1)
+
+#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING      "Security Level is Downgraded to 0"
+#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING_LEN  (sizeof (TBT_SECURITY_LEVEL_DOWNGRADED_STRING) - 1)
+
+#define GET_TBT_SECURITY_MODE    0
+#define SET_TBT_SECURITY_MODE    1
+
+typedef struct {
+  UINT8       EnableVtd;
+  BOOLEAN     SLDowngrade;
+} PCR7_DATA;
+
+/**
+  TBT Security ExtendPCR7 CallBackFunction
+  If the firmware/BIOS has an option to enable and disable DMA protections via a VT-d switch in BIOS options, then the shipping configuration must be with VT-d protection enabled.
+  On every boot where VT-d/DMA protection is disabled, or will be disabled, or configured to a lower security state, and a platform has a TPM enabled, then the platform SHALL extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA.
+  The event string SHALL be "DMA Protection Disabled". The platform firmware MUST log this measurement in the event log using the string "DMA Protection Disabled" for the Event Data.
+  Measure and log launch of TBT Security, and extend the measurement result into a specific PCR.
+  Extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA. The event string SHALL be "DMA Protection Disabled". The platform firmware MUST log this measurement in the event log using the string "DMA Protection Disabled" for the Event Data.
+
+  @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
+ExtendPCR7CallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  TBT Security DisableBme CallBackFunction
+
+  BIOS will disable BME and tear down the Thunderbolt DMAR tables at ExitBootServices
+  in order to hand off security of TBT hierarchies to the OS.
+  The BIOS is expected to either: Disable BME from power on till the OS starts configuring the devices and enabling BME Enable BME only for devices that can be protected by VT-d in preboot environment,
+  but disable BME and tear down any Thunderbolt DMAR tables at ExitBootServices()
+
+  @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
+TbtDisableBmeCallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  TBT Security SetDmarOptIn CallBackFunction
+
+  A new security feature will be supported to protect against Physical DMA attacks over Thunderbolt connects.
+  In order to do this, they need a new flag added to the DMAR tables that a DMA is only permitted into RMRR at ExitBootServices().  With this flag available, OS can then Bug Check if any DMA is requested outside of the RMRR before OS supported device drivers are started.
+  ReadyToBoot callback routine to update DMAR BIT2
+  Bit definition: DMA_CONTROL_GUARANTEE
+  If Set, the platform supports blocking all DMA outside of the regions defined in the RMRR structures from ExitBootServices() until OS supported device drivers are started.
+
+  @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
+SetDmarOptInCallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+/**
+  The function install DisableBme protocol for TBT Shell validation
+**/
+VOID
+InstallDisableBmeProtocol (
+  VOID
+  );
+
+/**
+  Get or set Thunderbolt(TM) security mode
+
+  @param[in]  DelayTime           - The delay time after do ForcePwr
+  @param[in]  SecurityMode        - TBT Security Level
+  @param[in]  Gpio3ForcePwrEn     - Force GPIO to power on or not
+  @param[in]  DTbtController      - Enable/Disable DTbtController
+  @param[in]  MaxControllerNumber - Number of contorller
+  @param[in]  Action              - 0 = get, 1 = set
+
+  @retval                         - Return security level
+**/
+UINT8
+EFIAPI
+GetSetSecurityMode (
+  IN UINTN                       DelayTime,
+  IN UINT8                       SecurityMode,
+  IN UINT8                       Gpio3ForcePwrEn,
+  IN UINT8                       *DTbtController,
+  IN UINT8                       MaxControllerNumber,
+  IN UINT8                       Action
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
new file mode 100644
index 0000000000..9afb36f011
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for the PeiCheckIommuSupport library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+#define _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
+/**
+  Check Iommu Ability base on SKU type, CSME FW type, Vtd and setup options.
+**/
+VOID
+PeiCheckIommuSupport (
+  VOID
+  );
+
+#endif // _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
new file mode 100644
index 0000000000..45bd8f38ed
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Prototype of the PeiTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_LIB_H_
+#define _PEI_TBT_POLICY_LIB_H_
+
+/**
+  Install Tbt Policy
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+  VOID
+  );
+
+/**
+  Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicyCallback (
+  VOID
+  );
+
+/**
+  Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+  VOID
+  );
+#endif // _DXE_TBT_POLICY_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
new file mode 100644
index 0000000000..44ae01a3f7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
@@ -0,0 +1,61 @@
+/** @file
+  PEI TBT Task Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_TBT_TASK_DISPATCH_LIB_H__
+#define __PEI_TBT_TASK_DISPATCH_LIB_H__
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+
+typedef
+EFI_STATUS
+(EFIAPI *TBT_TASK) (
+  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+typedef enum {
+  TBT_NULL,                ///< All policy flags turned off.
+  TBT_NORMAL   = (1 << 0), ///< Execute TBT function on cold reset.
+  TBT_S3       = (1 << 1), ///< Execute TBT function on S3 exit.
+  TBT_S4       = (1 << 2), ///< Execute TBT function on S4 exit.
+  TBT_ALL      = MAX_UINTN ///< Execute TBT function always.
+} TBT_BOOT_MODE;
+
+typedef struct {
+  TBT_TASK      TbtTask;         ///< Ptr to function to execute, with parameter list.
+  TBT_BOOT_MODE TbtBootModeFlag; ///< Call table base on TbtBootModeFlag
+  CHAR8         *String;         ///< Output string describing this task.
+} TBT_CALL_TABLE_ENTRY;
+
+/**
+  Covert the current EFI_BOOT_MODE to TBT_BOOT_MODE
+**/
+TBT_BOOT_MODE
+TbtGetBootMode (
+  VOID
+);
+
+/**
+  TbtTaskDistpach: Dispatch the TBT tasks according to TBT_CALL_TABLE_ENTRY
+
+  @param[in] TBT_CALL_TABLE_ENTRY   TbtCallTable
+
+**/
+VOID
+TbtTaskDistpach (
+  IN TBT_CALL_TABLE_ENTRY *TbtCallTable
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
new file mode 100644
index 0000000000..3e9e7c4b76
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
@@ -0,0 +1,261 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_COMMON_LIB_H_
+#define _TBT_COMMON_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+
+#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_RP     0 // @todo : Update when once finalized
+#define DEFAULT_PCI_BUS_NUMBER_ITBT_RP         0
+#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_RP      0x07
+
+#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_DMA0   0
+#define DEFAULT_PCI_BUS_NUMBER_ITBT_DMA0       0
+#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_DMA0    0x0D
+#define DEFAULT_PCI_FUNCTION_NUMBER_ITBT_DMA0  0x02
+
+#define DTBT_CONTROLLER                   0x00
+#define DTBT_TYPE_PCH                     0x01
+#define DTBT_TYPE_PEG                     0x02
+#define ITBT_CONTROLLER                   0x80
+#define TBT2PCIE_ITBT_R                   0xEC
+#define PCIE2TBT_ITBT_R                   0xF0
+#define TBT2PCIE_DTBT_R                   0x548
+#define PCIE2TBT_DTBT_R                   0x54C
+
+#define INVALID_RP_CONTROLLER_TYPE        0xFF
+
+//
+//  Thunderbolt FW OS capability
+//
+#define NO_OS_NATIVE_SUPPORT    0
+#define OS_NATIVE_SUPPORT_ONLY  1
+#define OS_NATIVE_SUPPORT_RTD3  2
+
+#define ITBT_SAVE_STATE_OFFSET  BIT4 // Bits 4-7 is for ITBT (HIA0/1/2/Reserved)
+#define DTBT_SAVE_STATE_OFFSET  BIT0 // Bits 0-3 is for DTBT (only bit 0 is in use)
+/**
+Get Tbt2Pcie Register Offset
+
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@retval     Register  Register Variable
+**/
+
+#define GET_TBT2PCIE_REGISTER_ADDRESS(Type, Segment, Bus, Device, Function, RegisterAddress) \
+  if (Type == ITBT_CONTROLLER) { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_ITBT_R); \
+  } else { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_DTBT_R); \
+  }
+
+/**
+Get Pcie2Tbt Register Offset
+
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@retval     Register  Register Variable
+**/
+
+#define GET_PCIE2TBT_REGISTER_ADDRESS(Type, Segment, Bus, Device, Function, RegisterAddress) \
+  if (Type == ITBT_CONTROLLER) { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_ITBT_R); \
+  } else { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_DTBT_R); \
+  }
+
+#define PCIE2TBT_VLD_B                    BIT0
+#define TBT2PCIE_DON_R                    BIT0
+#define TBT_MAIL_BOX_DELAY                (100*1000)
+#define TBT_5S_TIMEOUT                    50
+#define TBT_1S_TIMEOUT                    10
+#define TBT_3S_TIMEOUT                    30
+
+#define PCIE2TBT_GO2SX                    (0x02 << 1)
+#define PCIE2TBT_GO2SX_NO_WAKE            (0x03 << 1)
+#define PCIE2TBT_SX_EXIT_TBT_CONNECTED    (0x04 << 1)
+#define PCIE2TBT_SX_EXIT_NO_TBT_CONNECTED (0x05 << 1)
+#define PCIE2TBT_OS_UP                    (0x06 << 1)
+#define PCIE2TBT_SET_SECURITY_LEVEL       (0x08 << 1)
+#define PCIE2TBT_GET_SECURITY_LEVEL       (0x09 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_ENTER       (0x10 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_EXIT        (0x11 << 1)
+#define PCIE2TBT_BOOT_ON                  (0x18 << 1)
+#define PCIE2TBT_BOOT_OFF                 (0x19 << 1)
+#define PCIE2TBT_USB_ON                   (0x19 << 1)
+#define PCIE2TBT_GET_ENUMERATION_METHOD   (0x1A << 1)
+#define PCIE2TBT_SET_ENUMERATION_METHOD   (0x1B << 1)
+#define PCIE2TBT_POWER_CYCLE              (0x1C << 1)
+#define PCIE2TBT_PREBOOTACL               (0x1E << 1)
+#define CONNECT_TOPOLOGY_COMMAND          (0x1F << 1)
+
+#define RESET_HR_BIT                      BIT0
+#define ENUMERATE_HR_BIT                  BIT1
+#ifndef AUTO
+#define AUTO                              0x0
+#endif
+
+//
+//Thunder Bolt Device IDs
+//
+
+//
+// Alpine Ridge HR device IDs
+//
+#define AR_HR_2C  0x1576
+#define AR_HR_4C  0x1578
+#define AR_XHC    0x15B5
+#define AR_XHC_4C 0x15B6
+#define AR_HR_LP  0x15C0
+//
+// Alpine Ridge C0 HR device IDs
+//
+#define AR_HR_C0_2C  0x15DA
+#define AR_HR_C0_4C  0x15D3
+//
+// Titan Ridge HR device IDs
+//
+#define TR_HR_2C  0x15E7
+#define TR_HR_4C  0x15EA
+//
+//End of Thunderbolt(TM) Device IDs
+//
+
+typedef struct _DEV_ID {
+  UINT8 Segment;
+  UINT8 Bus;
+  UINT8 Dev;
+  UINT8 Fun;
+} DEV_ID;
+
+//@todo Seems to only be used by Platform/TBT/Smm/TbtSmm.inf
+//@todo should refactor this to only be present in that driver
+//@todo also definitions like this should never be in a .h file anyway
+//@todo this is a quick hack to get things compiling for now
+#ifdef __GNUC__
+#pragma GCC diagnostic warning "-Wunused-variable"
+#endif
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in]  GpioNumber
+@param[in]  Value
+**/
+VOID
+ForceDtbtPower(
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+);
+
+/**
+  Get Security Level.
+  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
+  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  );
+
+/**
+  Set Security Level.
+  @param[in]  Data      Security State
+  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
+  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+  IN    UINT8                   Data,
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  );
+
+/**
+Execute TBT Mail Box Command
+
+@param[in]  Command   TBT Command
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+  IN    UINT8                   Command,
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT32                  Timeout
+);
+/**
+  Check connected TBT controller is supported or not by DeviceID
+
+  @param[in]  DeviceID              DeviceID of of TBT controller
+
+
+  @retval     TRUE                  Valid DeviceID
+  @retval     FALSE                 Invalid DeviceID
+**/
+
+BOOLEAN
+IsTbtHostRouter (
+  IN    UINT16  DeviceID
+  );
+
+/**
+  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun(
+  IN  BOOLEAN Type,
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFunc
+  );
+
+/**
+  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
+  @param[in]  TimeOut                   Time out with 100 ms garnularity
+  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to Clear/Set)
+  @param[out] *Tbt2PcieValue Function   Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion (
+  IN  UINT64   CommandOffsetAddress,
+  IN  UINT32   TimeOut,
+  IN  BOOLEAN  Tbt2PcieDone,
+  OUT UINT32   *Tbt2PcieValue
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
new file mode 100644
index 0000000000..17d8a62f66
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
@@ -0,0 +1,31 @@
+/** @file
+TBT PEI Policy
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_H_
+#define _PEI_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define PEI_TBT_POLICY_REVISION 1
+
+/**
+ TBT PEI configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _PEI_TBT_POLICY {
+  DTBT_COMMON_CONFIG     DTbtCommonConfig;                                  ///< dTbt Common Configuration
+  DTBT_CONTROLLER_CONFIG DTbtControllerConfig [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
+} PEI_TBT_POLICY;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
new file mode 100644
index 0000000000..bb30c2c0ec
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
@@ -0,0 +1,130 @@
+/** @file
+  PEI DTBT Init Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_DTBT_INIT_LIB_H__
+#define __PEI_DTBT_INIT_LIB_H__
+
+#include <Private/Library/PeiTbtCommonInitLib.h>
+#include <Library/PeiTbtTaskDispatchLib.h>
+
+extern TBT_CALL_TABLE_ENTRY DTbtCallTable[];
+
+/**
+  Get Thunderbolt(TM) (TBT) PEI Policy Data.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtGetPeiTbtPolicyData (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Toggle related GPIO pin for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtToggleGPIO (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  set tPCH25 Timing to 10 ms for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Do ForcePower for DTBT Controller
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Clear VGA Registers for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "Boot On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "USB On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "Sx Exit".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
new file mode 100644
index 0000000000..0ed13fd300
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
@@ -0,0 +1,51 @@
+/** @file
+  PEI TBT Common Init Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_TBT_COMMON_INIT_LIB_H__
+#define __PEI_TBT_COMMON_INIT_LIB_H__
+
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiTbtTaskDispatchLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TbtCommonLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PmcLib.h>
+#include <PlatformNvRamHookLib.h>
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN  UINT8        ControllerType,
+IN  UINT8        Controller
+);
+
+VOID
+TbtSetSxMode(
+IN    BOOLEAN                 Type,
+IN    UINT8                   Bus,
+IN    UINT8                   Device,
+IN    UINT8                   Function,
+IN    UINT8                   TbtBootOn
+);
+
+VOID
+TbtClearVgaRegisters(
+IN    UINTN                   Segment,
+IN    UINTN                   Bus,
+IN    UINTN                   Device,
+IN    UINTN                   Function
+);
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
new file mode 100644
index 0000000000..1948c252f0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
@@ -0,0 +1,36 @@
+/** @file
+  Definitions for DisableBmeProtocol
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DISABLE_TBT_BME_PROTOCOL_H_
+#define _DISABLE_TBT_BME_PROTOCOL_H_
+
+typedef struct EFI_DISABLE_BME_PROTOCOL EFI_DISABLE_TBT_BME_PROTOCOL;
+
+/**
+  This is for disable TBT BME bit under shell environment
+
+  @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.
+**/
+typedef
+VOID
+(EFIAPI *DISABLE_BUS_MASTER_ENABLE) (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+struct EFI_DISABLE_BME_PROTOCOL {
+  DISABLE_BUS_MASTER_ENABLE DisableBme;
+};
+
+extern EFI_GUID gDxeDisableTbtBmeProtocolGuid;
+
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
new file mode 100644
index 0000000000..437f6a8401
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
@@ -0,0 +1,137 @@
+/** @file
+TBT DXE Policy
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_H_
+#define _DXE_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define DXE_TBT_POLICY_REVISION 1
+
+//
+// TBT Common Data Structure
+//
+typedef struct _TBT_COMMON_CONFIG{
+  /**
+    TBT Security Level
+    <b>0: SL0 No Security</b>, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+  **/
+  UINT32   SecurityMode      : 3;
+  /**
+    BIOS W/A for Hot plug of 12V USB devices cause electrical noise on PCH GPIOs
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Gpio5Filter       : 1;
+  /**
+     WA for TR A0 OS_UP Command, it is only needed for TR A0 stepping
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TrA0OsupWa        : 1;
+  /**
+    Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtWakeupSupport  : 1;
+  /**
+    SMI TBT enumeration
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtHotSMI         : 1;
+  /**
+    Notify PCIe RP after Hot-Plug/Hot-Unplug occurred.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtHotNotify      : 1;
+  /**
+    CLK REQ for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtSetClkReq      : 1;
+  /**
+    ASPM setting for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: L0s, 2: L1, 3: L0sL1
+  **/
+  UINT32   TbtAspm           : 2;
+  /**
+    L1 SubState for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: L1.1, 2: L1.1 & L1.2
+  **/
+  UINT32   TbtL1SubStates    : 2;
+  /**
+    LTR for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtLtr            : 1;
+  /**
+    PTM for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtPtm            : 1;
+  /**
+    TBT Dynamic AC/DC L1.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtAcDcSwitch     : 1;
+  /**
+    TBT RTD3 Support.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Rtd3Tbt           : 1;
+  /**
+    TBT ClkReq for RTD3 Flow.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Rtd3TbtClkReq     : 1;
+  /**
+    TBT Win10support for Tbt FW execution mode.
+    <b>0: Disabled</b>, 1: Native, 2: Native + RTD3
+  **/
+  UINT32   Win10Support      : 2;
+  /**
+    TbtVtdBaseSecurity
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtVtdBaseSecurity: 1;
+  /**
+    Control Iommu behavior in pre-boot
+    <b>0: Disabled Iommu</b>, 1: Enable Iommu, Disable exception list, 2: Enable Iommu, Enable exception list
+  **/
+  UINT32   ControlIommu      : 3;
+  UINT32   Rsvd0             : 8; ///< Reserved bits
+  UINT16   Rtd3TbtClkReqDelay;
+  UINT16   Rtd3TbtOffDelay;
+} TBT_COMMON_CONFIG;
+
+//
+// dTBT Resource Data Structure
+//
+typedef struct _DTBT_RESOURCE_CONFIG{
+  UINT8  DTbtPcieExtraBusRsvd;     ///< Preserve Bus resource for PCIe RP that connect to dTBT Host Router
+  UINT16 DTbtPcieMemRsvd;          ///< Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  DTbtPcieMemAddrRngMax;    ///< Alignment of Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+  UINT16 DTbtPciePMemRsvd;         ///< Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  DTbtPciePMemAddrRngMax;   ///< Alignment of Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  Reserved[1];      ///< Reserved for DWORD alignment
+} DTBT_RESOURCE_CONFIG;
+
+/**
+ TBT DXE configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _DXE_TBT_POLICY_PROTOCOL {
+  TBT_COMMON_CONFIG      TbtCommonConfig;                                  ///< Tbt Common Information
+  DTBT_RESOURCE_CONFIG   DTbtResourceConfig[MAX_DTBT_CONTROLLER_NUMBER];   ///< dTbt Resource Configuration
+} DXE_TBT_POLICY_PROTOCOL;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
new file mode 100644
index 0000000000..e6654b4094
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
@@ -0,0 +1,50 @@
+/** @file
+  This file defines the TBT NVS Area Protocol.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_NVS_AREA_H_
+#define _TBT_NVS_AREA_H_
+
+//
+// Platform NVS Area definition
+//
+#include <TbtNvsAreaDef.h>
+
+//
+// Includes
+//
+#define TBT_NVS_DEVICE_ENABLE 1
+#define TBT_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL TBT_NVS_AREA_PROTOCOL;
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gTbtNvsAreaProtocolGuid;
+
+/**
+ Making any TBT_NVS_AREA 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.\n
+  <b>Revision 2</b>:   - Adding TBT NVS AREA Revision, Deprecated DTbtControllerEn0, DTbtControllerEn1.\n
+**/
+#define TBT_NVS_AREA_REVISION       2
+
+//
+// Platform NVS Area Protocol
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL {
+  TBT_NVS_AREA     *Area;
+} TBT_NVS_AREA_PROTOCOL;
+
+#endif // _TBT_NVS_AREA_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
new file mode 100644
index 0000000000..bd5e577fbe
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
@@ -0,0 +1,23 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_INFO_GUID_H_
+#define _TBT_INFO_GUID_H_
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(1)
+//
+// TBT Info HOB
+//
+typedef struct _TBT_INFO_HOB {
+  EFI_HOB_GUID_TYPE      EfiHobGuidType;
+  DTBT_COMMON_CONFIG     DTbtCommonConfig;                                  ///< dTbt Common Configuration
+  DTBT_CONTROLLER_CONFIG DTbtControllerConfig [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
+} TBT_INFO_HOB;
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
new file mode 100644
index 0000000000..21e17b4609
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
@@ -0,0 +1,68 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define TBT NVS Area operation region.
+  //
+
+#ifndef _TBT_NVS_AREA_DEF_H_
+#define _TBT_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT8    ThunderboltSmiFunction;                  ///< Offset 0       Thunderbolt(TM) SMI Function Number
+  UINT8    ThunderboltHotSmi;                       ///< Offset 1       SMI on Hot Plug for TBT devices
+  UINT8    TbtWin10Support;                         ///< Offset 2       TbtWin10Support
+  UINT8    TbtGpioFilter;                           ///< Offset 3       Gpio filter to detect USB Hotplug event
+  UINT8    ThunderboltHotNotify;                    ///< Offset 4       Notify on Hot Plug for TBT devices
+  UINT8    TbtSelector;                             ///< Offset 5       Thunderbolt(TM) Root port selector
+  UINT8    WAKFinished;                             ///< Offset 6       WAK Finished
+  UINT8    DiscreteTbtSupport;                      ///< Offset 7       Thunderbolt(TM) support
+  UINT8    TbtAcpiRemovalSupport;                   ///< Offset 8       TbtAcpiRemovalSupport
+  UINT32   TbtFrcPwrEn;                             ///< Offset 9       TbtFrcPwrEn
+  UINT32   TbtFrcPwrGpioNo0;                        ///< Offset 13      TbtFrcPwrGpioNo
+  UINT8    TbtFrcPwrGpioLevel0;                     ///< Offset 17      TbtFrcPwrGpioLevel
+  UINT32   TbtCioPlugEventGpioNo0;                  ///< Offset 18      TbtCioPlugEventGpioNo
+  UINT32   TbtPcieRstGpioNo0;                       ///< Offset 22      TbtPcieRstGpioNo
+  UINT8    TbtPcieRstGpioLevel0;                    ///< Offset 26      TbtPcieRstGpioLevel
+  UINT8    CurrentDiscreteTbtRootPort;              ///< Offset 27      Current Port that has plug event
+  UINT8    RootportSelected0;                       ///< Offset 28      Root port Selected by the User
+  UINT8    RootportSelected0Type;                   ///< Offset 29      Root port Type
+  UINT8    RootportSelected1;                       ///< Offset 30      Root port Selected by the User
+  UINT8    RootportSelected1Type;                   ///< Offset 31      Root port Type
+  UINT8    RootportEnabled0;                        ///< Offset 32      Root port Enabled by the User
+  UINT8    RootportEnabled1;                        ///< Offset 33      Root port Enabled by the User
+  UINT32   TbtFrcPwrGpioNo1;                        ///< Offset 34      TbtFrcPwrGpioNo
+  UINT8    TbtFrcPwrGpioLevel1;                     ///< Offset 38      TbtFrcPwrGpioLevel
+  UINT32   TbtCioPlugEventGpioNo1;                  ///< Offset 39      TbtCioPlugEventGpioNo
+  UINT32   TbtPcieRstGpioNo1;                       ///< Offset 43      TbtPcieRstGpioNo
+  UINT8    TbtPcieRstGpioLevel1;                    ///< Offset 47      TbtPcieRstGpioLevel
+  UINT8    TBtCommonGpioSupport;                    ///< Offset 48      Set if Single GPIO is used for Multi/Different Controller Hot plug support
+  UINT8    CurrentDiscreteTbtRootPortType;          ///< Offset 49      Root Port type for which SCI Triggered
+  UINT8    TrOsup;                                  ///< Offset 50      Titan Ridge Osup command
+  UINT8    TbtAcDcSwitch;                           ///< Offset 51      TBT Dynamic AcDc L1
+  UINT8    DTbtControllerEn0;                       ///< Offset 52      DTbtController0 is enabled or not.  @deprecated since revision 2
+  UINT8    DTbtControllerEn1;                       ///< Offset 53      DTbtController1 is enabled or not.  @deprecated since revision 2
+  UINT8    TbtAspm;                                 ///< Offset 54      ASPM setting for all the PCIe device in TBT daisy chain.
+  UINT8    TbtL1SubStates;                          ///< Offset 55      L1 SubState for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtSetClkReq;                            ///< Offset 56      CLK REQ for all the PCIe device in TBT daisy chain.
+  UINT8    TbtLtr;                                  ///< Offset 57      LTR for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtPtm;                                  ///< Offset 58      PTM for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtWakeupSupport;                        ///< Offset 59      Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+  UINT16   Rtd3TbtOffDelay;                         ///< Offset 60      Rtd3TbtOffDelay TBT RTD3 Off Delay
+  UINT8    TbtSxWakeSwitchLogicEnable;              ///< Offset 62      TbtSxWakeSwitchLogicEnable Set True if TBT_WAKE_N will be routed to PCH WakeB at Sx entry point. HW logic is required.
+  UINT8    Rtd3TbtSupport;                          ///< Offset 63      Enable Rtd3 support for TBT. Corresponding to Rtd3Tbt in Setup.
+  UINT8    Rtd3TbtClkReq;                           ///< Offset 64      Enable TBT RTD3 CLKREQ mask.
+  UINT16   Rtd3TbtClkReqDelay;                      ///< Offset 65      TBT RTD3 CLKREQ mask delay.
+  //
+  // Revision Field:
+  //
+  UINT8    TbtRevision;                             ///< Offset 67      Revison of TbtNvsArea
+} TBT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
new file mode 100644
index 0000000000..7771fc7a95
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
@@ -0,0 +1,84 @@
+/** @file
+TBT Policy Common definition.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_POLICY_COMMON_H_
+#define _TBT_POLICY_COMMON_H_
+
+#include <Library/GpioLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#define MAX_DTBT_CONTROLLER_NUMBER 2
+
+#define TYPE_PCIE           0x01
+#define TYPE_PEG            0x02
+
+#pragma pack(push, 1)
+
+//
+// dTBT Force Power GPIO Data Structure
+//
+typedef struct _DTBT_FORCE_POWER_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_FORCE_POWER_GPIO_CONFIG;
+
+//
+// dTBT CIO Plug Event GPIO Data Structure
+//
+typedef struct _DTBT_CIO_PLUG_EVENT_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  UINT32         AcpiGpeSignature;        ///< AcpiPlatform driver will change the XTBT method to the _Lxx or _Exx that we assign in this item.
+  BOOLEAN        AcpiGpeSignaturePorting; ///< 0 = No porting required(for 2-tier GPI GPE event architecture), 1 = Porting required(for 1-tier GPI GPE event architecture)
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_CIO_PLUG_EVENT_GPIO_CONFIG;
+
+//
+// dTBT PCIE Reset GPIO Data Structure
+//
+typedef struct _DTBT_PCIE_RESET_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_PCIE_RESET_GPIO_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_CONTROLLER_CONFIG {
+  UINT8                           DTbtControllerEn; ///< Enable/Disable DTbtController.
+  UINT8                           Type;             ///< 01-Pcie RP, 02- PEG,Reserved. <Specific according to Board Design>
+  UINT8                           PcieRpNumber;     ///< RP Number/ PEG Port (0,1,2) that connecet to dTBT controller. <Specific according to Board Design>
+  DTBT_FORCE_POWER_GPIO_CONFIG    ForcePwrGpio;     ///< The GPIO pin that can force dTBT Power On. <Specific according to Board Design>
+  DTBT_CIO_PLUG_EVENT_GPIO_CONFIG CioPlugEventGpio; ///< The GPIO pin that can generate Hot-Plug event. <Specific according to Board Design>
+  DTBT_PCIE_RESET_GPIO_CONFIG     PcieRstGpio;      ///< The GPIO pin that is use to perform Reset when platform enters to Sx, it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO <Specific according to Board Design>
+  GPIO_PAD                        PdResetGpioPad;   ///< PD HRESET GPIO Pad Number
+  GPIO_PAD                        PdSxEntryGpioPad; ///< PD SX Entry GPIO Pad Number
+  GPIO_PAD                        PdSxAckGpioPad;   ///< PD SX Ack GPIO Pad Number
+  UINT8                           Reserved[1];      ///< Reserved for DWORD alignment
+} DTBT_CONTROLLER_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_COMMON_CONFIG {
+  UINT8            TbtBootOn;                    ///< Send BootOn Mailbox command when TbtBootOn is enabled.
+  UINT8            TbtUsbOn;                     ///< Send UsbOn Mailbox command when TbtBootOn is enabled.
+  UINT8            Gpio3ForcePwr;                ///< Force GPIO to power on or not
+  UINT16           Gpio3ForcePwrDly;             ///< The delay time after do ForcePwr
+  BOOLEAN          DTbtSharedGpioConfiguration;  ///< Multiple DTBT controllers share the same GPIO pin <Specific according to Board Design>
+  BOOLEAN          PcieRstSupport;               ///< 0 = Not Support, 1 = Supported. it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO
+  UINT8            SecurityMode;                 ///< 0: SL0 No Security, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+  UINT8            ControlIommu;                 ///< Control Iommu behavior in pre-boot, 0: Disabled Iommu, 1: Enable Iommu, Disable exception list, 2: Enable Iommu, Enable exception list
+  UINT8            Reserved[3];                  ///< Reserved for DWORD alignment
+} DTBT_COMMON_CONFIG;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
new file mode 100644
index 0000000000..d8021e8c22
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
@@ -0,0 +1,118 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  // Define a Global region of ACPI NVS Region that may be used for any
+  // type of implementation.  The starting offset and size will be fixed
+  // up by the System BIOS during POST.  Note that the Size must be a word
+  // in size to be fixed up correctly.
+
+
+#ifndef _GLOBAL_NVS_AREA_DEF_H_
+#define _GLOBAL_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  //
+  // Miscellaneous Dynamic Registers:
+  //
+  UINT16   OperatingSystem;                         ///< Offset 0       Operating System
+  UINT8    SmiFunction;                             ///< Offset 2       SMI Function Call (ASL to SMI via I/O Trap)
+  UINT32   Port80DebugValue;                        ///< Offset 3       Port 80 Debug Port Value
+  UINT8    PowerState;                              ///< Offset 7       Power State (AC Mode = 1)
+  //
+  // Thermal Policy Registers:
+  //
+  UINT8    EnableDigitalThermalSensor;              ///< Offset 8       Digital Thermal Sensor Enable
+  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 9       DTS SMI Function Call
+  //
+  // CPU Identification Registers:
+  //
+  UINT8    ApicEnable;                              ///< Offset 10      APIC Enabled by SBIOS (APIC Enabled = 1)
+  UINT8    ThreadCount;                             ///< Offset 11      Number of Enabled Threads
+  //
+  // PCIe Hot Plug
+  //
+  UINT8    PcieOSCControl;                          ///< Offset 12      PCIE OSC Control
+  UINT8    NativePCIESupport;                       ///< Offset 13      Native PCIE Setup Value
+  //
+  // Global Variables
+  //
+  UINT8    DisplaySupportFlag;                      ///< Offset 14      _DOS Display Support Flag.
+  UINT8    InterruptModeFlag;                       ///< Offset 15      Global IOAPIC/8259 Interrupt Mode Flag.
+  UINT8    L01Counter;                              ///< Offset 16      Global L01 Counter.
+  UINT8    LtrEnable[24];                           ///< Offset 17      Latency Tolerance Reporting Enable
+                                                    ///< Offset 18      Latency Tolerance Reporting Enable
+                                                    ///< Offset 19      Latency Tolerance Reporting Enable
+                                                    ///< Offset 20      Latency Tolerance Reporting Enable
+                                                    ///< Offset 21      Latency Tolerance Reporting Enable
+                                                    ///< Offset 22      Latency Tolerance Reporting Enable
+                                                    ///< Offset 23      Latency Tolerance Reporting Enable
+                                                    ///< Offset 24      Latency Tolerance Reporting Enable
+                                                    ///< Offset 25      Latency Tolerance Reporting Enable
+                                                    ///< Offset 26      Latency Tolerance Reporting Enable
+                                                    ///< Offset 27      Latency Tolerance Reporting Enable
+                                                    ///< Offset 28      Latency Tolerance Reporting Enable
+                                                    ///< Offset 29      Latency Tolerance Reporting Enable
+                                                    ///< Offset 30      Latency Tolerance Reporting Enable
+                                                    ///< Offset 31      Latency Tolerance Reporting Enable
+                                                    ///< Offset 32      Latency Tolerance Reporting Enable
+                                                    ///< Offset 33      Latency Tolerance Reporting Enable
+                                                    ///< Offset 34      Latency Tolerance Reporting Enable
+                                                    ///< Offset 35      Latency Tolerance Reporting Enable
+                                                    ///< Offset 36      Latency Tolerance Reporting Enable
+                                                    ///< Offset 37      Latency Tolerance Reporting Enable
+                                                    ///< Offset 38      Latency Tolerance Reporting Enable
+                                                    ///< Offset 39      Latency Tolerance Reporting Enable
+                                                    ///< Offset 40      Latency Tolerance Reporting Enable
+  UINT8    ObffEnable[24];                          ///< Offset 41      Optimized Buffer Flush and Fill
+                                                    ///< Offset 42      Optimized Buffer Flush and Fill
+                                                    ///< Offset 43      Optimized Buffer Flush and Fill
+                                                    ///< Offset 44      Optimized Buffer Flush and Fill
+                                                    ///< Offset 45      Optimized Buffer Flush and Fill
+                                                    ///< Offset 46      Optimized Buffer Flush and Fill
+                                                    ///< Offset 47      Optimized Buffer Flush and Fill
+                                                    ///< Offset 48      Optimized Buffer Flush and Fill
+                                                    ///< Offset 49      Optimized Buffer Flush and Fill
+                                                    ///< Offset 50      Optimized Buffer Flush and Fill
+                                                    ///< Offset 51      Optimized Buffer Flush and Fill
+                                                    ///< Offset 52      Optimized Buffer Flush and Fill
+                                                    ///< Offset 53      Optimized Buffer Flush and Fill
+                                                    ///< Offset 54      Optimized Buffer Flush and Fill
+                                                    ///< Offset 55      Optimized Buffer Flush and Fill
+                                                    ///< Offset 56      Optimized Buffer Flush and Fill
+                                                    ///< Offset 57      Optimized Buffer Flush and Fill
+                                                    ///< Offset 58      Optimized Buffer Flush and Fill
+                                                    ///< Offset 59      Optimized Buffer Flush and Fill
+                                                    ///< Offset 60      Optimized Buffer Flush and Fill
+                                                    ///< Offset 61      Optimized Buffer Flush and Fill
+                                                    ///< Offset 62      Optimized Buffer Flush and Fill
+                                                    ///< Offset 63      Optimized Buffer Flush and Fill
+                                                    ///< Offset 64      Optimized Buffer Flush and Fill
+  UINT8    Rtd3Support;                             ///< Offset 65      Runtime D3 support.
+  UINT8    LowPowerS0Idle;                          ///< Offset 66      Low Power S0 Idle Enable
+  UINT8    VirtualGpioButtonSxBitmask;              ///< Offset 67      Virtual GPIO button Notify Sleep State Change
+  UINT8    PstateCapping;                           ///< Offset 68      P-state Capping
+  UINT8    Ps2MouseEnable;                          ///< Offset 69      Ps2 Mouse Enable
+  UINT8    Ps2KbMsEnable;                           ///< Offset 70      Ps2 Keyboard and Mouse Enable
+  //
+  // Driver Mode
+  //
+  UINT32   GpioIrqRoute;                            ///< Offset 71      GPIO IRQ
+  UINT8    PL1LimitCS;                              ///< Offset 75      set PL1 limit when entering CS
+  UINT16   PL1LimitCSValue;                         ///< Offset 76      PL1 limit value
+  UINT8    TenSecondPowerButtonEnable;              ///< Offset 78      10sec Power button support
+  UINT8    PciDelayOptimizationEcr;                 ///< Offset 79      Pci Delay Optimization Ecr
+  UINT8    TbtSupport;                              ///< Offset 80      Thunderbolt(TM) support
+  UINT8    TbtNativeOsHotPlug;                      ///< Offset 81      TbtNativeOsHotPlug
+  UINT8    TbtSelector;                             ///< Offset 82      Thunderbolt(TM) Root port selector
+  UINT8    TbtSelector1;                            ///< Offset 83      Thunderbolt(TM) Root port selector
+} EFI_GLOBAL_NVS_AREA;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
new file mode 100644
index 0000000000..bbdeb71da5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ATTEMPT_USB_FIRST_H_
+#define _ATTEMPT_USB_FIRST_H_
+
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_HOTKEY_INFO {
+  UINT8 RevisonId;         // Structure Revision ID
+  UINT8 HotkeyTriggered;   // Hot key status
+} ATTEMPT_USB_FIRST_HOTKEY_INFO;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_VARIABLE {
+  UINT8 UsbBootPrior;
+} ATTEMPT_USB_FIRST_VARIABLE;
+#pragma pack()
+
+//
+// Volatile variable definition for Attempt USB first features
+//
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_RUNTIME_VARIABLE {
+  UINT8 RevisonId;        // Structure Revision ID
+  UINT8 UsbFirstEnable;   // Attempt USB First is enabled or not
+} ATTEMPT_USB_FIRST_RUNTIME_VARIABLE;
+#pragma pack()
+
+//
+// Volatile variable definition for third party Default Enabling via UEFI Variable.
+//
+#pragma pack(1)
+typedef struct _ENABLE_CUSTOM_DEFAULTS{
+  UINT32 EnableCustomDefaults;
+} ENABLE_CUSTOM_DEFAULTS;
+#pragma pack()
+
+#define COENG_DEFAULTS_UNKNOWN   0
+#define COENG_DEFAULTS_SUPPORTED 1
+#define COENG_DEFAULTS_VAR_EXITS 2
+#define COENG_DEFAULTS_VAR_SET   4
+#define COENG_DEFAULTS_AVAILABLE (COENG_DEFAULTS_SUPPORTED | COENG_DEFAULTS_VAR_EXITS |COENG_DEFAULTS_VAR_SET)
+
+extern EFI_GUID gAttemptUsbFirstHotkeyInfoHobGuid;
+extern EFI_GUID gAttemptUsbFirstRuntimeVarInfoGuid;
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
new file mode 100644
index 0000000000..17ccd56373
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
@@ -0,0 +1,57 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPUSMM_H_
+#define _CPUSMM_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CPUSMM_GUID { 0x90d93e09, 0x4e91, 0x4b3d, { 0x8c, 0x77, 0xc8, 0x2f, 0xf1, 0xe, 0x3c, 0x81 }}
+#define CPUSMM_SETUP_NAME             L"CpuSmm"
+
+#pragma pack(1)
+typedef struct {
+  UINT8     CpuSmmMsrSaveStateEnable;
+  UINT8     CpuSmmCodeAccessCheckEnable;
+  UINT8     CpuSmmUseDelayIndication;
+  UINT8     CpuSmmUseBlockIndication;
+  UINT8     CpuSmmUseSmmEnableIndication;
+  UINT8     CpuSmmProcTraceEnable;
+} CPU_SMM;
+#pragma pack()
+
+#ifndef OFFSET_OF
+#ifdef __GNUC__
+#if __GNUC__ >= 4
+#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
+#endif
+#endif
+#endif
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+#define VERIFY_OFFSET(TYPE, Field, Offset) extern UINT8 _VerifyOffset##TYPE##Field[(OFFSET_OF(TYPE, Field) == Offset) / (OFFSET_OF(TYPE, Field) == Offset)]
+
+//
+// If TpmSupport/MorStae isn't in this offset, build failure (0 size array or divided by 0) will be generated.
+// Platform DSC file maps the two field to HII PCD so the offset value is critical.
+//
+VERIFY_OFFSET (CPU_SMM, CpuSmmMsrSaveStateEnable, 0x0);
+VERIFY_OFFSET (CPU_SMM, CpuSmmCodeAccessCheckEnable, 0x1);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseDelayIndication, 0x2);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseBlockIndication, 0x3);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseSmmEnableIndication, 0x4);
+VERIFY_OFFSET (CPU_SMM, CpuSmmProcTraceEnable, 0x5);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
new file mode 100644
index 0000000000..b7202a6b4a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
@@ -0,0 +1,20 @@
+/** @file
+  This header file provides definitions of firmware configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _FIRMWARE_CONFIGURATION_H_
+#define _FIRMWARE_CONFIGURATION_H_
+
+typedef enum {
+  FwConfigDefault = 0,
+  FwConfigProduction,
+  FwConfigTest,
+  FwConfigMax
+} FW_CONFIG;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
new file mode 100644
index 0000000000..ed63b28adf
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
@@ -0,0 +1,1766 @@
+/** @file
+Header file for GOP Configuration Library
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GOP_CONFIG_LIB_H_
+#define _GOP_CONFIG_LIB_H_
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#pragma pack(1)
+#define GOP_CONFIG_VBT_REVISION 0xC1
+
+#define ChildStruct_MAX                       8         ///< Maximum number of child structures in VBT
+#define CompressionStruct_MAX                 2         ///< Maximum number of compression parameter structures in VBT.
+#define NO_DEVICE                             0x00      ///< Defines a null display class.
+#define DISPLAY_PORT_ONLY                     0x68C6    ///< Defines a display class of Integrated Display Port Only
+#define DISPLAY_PORT_HDMI_DVI_COMPATIBLE      0x60D6    ///< Defines a display class of Integrated DisplayPort with HDMI/DVI Compatible
+#define DISPLAY_PORT_DVI_COMPATIBLE           0x68D6    ///< Defines a display class of Integrated DisplayPort with DVI Compatible
+#define HDMI_DVI                              0x60D2    ///< Defines a display class of Integrated HDMI/DVI
+#define DVI_ONLY                              0x68D2    ///< Defines a display class of Integrated DVI Only
+#define MIPI_ONLY                             0x1400
+#define eDP_ONLY                              0x1806    ///< Defines a display class of eDP only
+#define AUX_CHANNEL_A                         0x40
+#define AUX_CHANNEL_B                         0x10
+#define AUX_CHANNEL_C                         0x20
+#define AUX_CHANNEL_D                         0x30
+#define NO_PORT                               0x00      ///< Defines a output port NA
+#define HDMI_B                                0x01      ///< Defines a output port HDMI-B
+#define HDMI_C                                0x02      ///< Defines a output port HDMI-C
+#define HDMI_D                                0x03      ///< Defines a output port HDMI-D
+#define HDMI_F                                0x0E      ///< Defines a output port HDMI-D
+#define DISPLAY_PORT_A                        0x0A      ///< Defines a output port DisplayPort A
+#define DISPLAY_PORT_B                        0x07      ///< Defines a output port DisplayPort B
+#define DISPLAY_PORT_C                        0x08      ///< Defines a output port DisplayPort C
+#define DISPLAY_PORT_D                        0x09      ///< Defines a output port DisplayPort D
+#define DISPLAY_PORT_E                        0x0B      ///< Defines a output port DisplayPort E
+#define DISPLAY_PORT_F                        0x0D      ///< Defines a output port DisplayPort F
+#define PORT_MIPI_A                           0x15      ///< Mipi Port A
+#define PORT_MIPI_C                           0x17      ///< Mipi Port C
+
+typedef struct {
+  UINT16  Dclk;                         // DClk in 10 KHz
+  UINT8   HActive;                      // HActive [7:0]
+  UINT8   HBlank;                       // HBlank [7:0]
+  UINT8   HA_HB_UpperNibble;            // Upper nibble = HActive [11:8]
+  UINT8   VActive;                      // VActive [7:0]
+  UINT8   VBlank;                       // VBlank [7:0]
+  UINT8   VA_VB_UpperNibble;            // Upper nibble = VActive [11:8]
+  UINT8   HSyncOffset;                  // HSync offset from blank start LSB
+  UINT8   HPulseWidth;                  // HSync Pulse Width, LSB
+  UINT8   VsyncOffset_VpulseWidth_LSB;  // Bits 7:4 = VSync offset [3:0]
+  UINT8   HSO_HSPW_V_High;              // Bits 7:6 = HSync Offset [9:8]
+  UINT8   HorImageSize;                 // Horizontal Image Size
+  UINT8   VerImageSize;                 // Vertical Image Size
+  UINT8   HIS_VIS_High;                 // UpperLmtH_V Upper limits of H. and V. image size
+  UINT8   HBorder;                      // Horizontal Border
+  UINT8   VBorder;                      // Vertical Border
+  UINT8   Flags;                        // Flags
+} DTD_STRUCTURE;                        // 18 Bytes
+
+typedef struct {
+  UINT16  XRes;
+  UINT16  YRes;
+  UINT32  SerialNo;
+  UINT8   Week;
+  UINT8   Year;
+} PID_DATA;                             // 10 Bytes
+
+//
+// VBT Header
+//
+/**
+  This structure defines the VBT Header.
+**/
+typedef struct {
+  UINT8   Product_String[20]; ///< "$VBT_Cannonlake" is the product string
+  UINT16  Version_Num;        ///< Defines the VBT Header version number.
+  UINT16  Header_Size;        ///< Defines the size of VBT Header.
+  UINT16  Table_Size;         ///< Defines the size of complete VBT.
+  UINT8   Checksum;           ///< Defines the checksum of entire VBT
+  UINT8   Reserved1;          ///< Reserved field 1 of 1 byte.
+  UINT32  Bios_Data_Offset;   ///< Defines the offset of VBT Data block.
+  UINT32  Aim_Data_Offset[4]; ///< 4 reserved pointers to VBT data blocks.
+} VBT_HEADER;
+
+/**
+  This structure defines the VBT BIOS Data Block Header
+**/
+typedef struct {
+  UINT8   BDB_Signature[16];  ///< Defines the Bios Data Block signature "BIOS_DATA_BLOCK".
+  UINT16  BDB_Version;        ///< Defines the VBT (data) version.
+  UINT16  BDB_Header_Size;    ///< Defines the size of VBT Bios data block header.
+  UINT16  BDB_Size;           ///< Defines the size of Bios data block.
+} VBT_BIOS_DATA_HEADER;
+
+/**
+  This structure defines the BMP Signon Message and Copyright Message Structure
+**/
+typedef struct {
+  UINT8   BlockId;            ///< Defines Block ID : 254
+  UINT16  BlockSize;          ///< Defines the size of BMP Signon block.
+
+  UINT16  Bmp_BIOS_Size;      ///< Defines the BIOS size 32k/48k/64k.
+  UINT8   BIOS_Type;          ///< Defines the type of BIOS desktop or mobile.
+  UINT8   RelStatus;          ///< Defines the release status of the current GOP driver.
+  UINT8   BIOS_HW;            ///< Defines the Hardware i.e. Cannonlake.
+  UINT8   INT_HW;             ///< Defines the integrated hardware supported eDP/HDMI/DP.
+  UINT8   Build_Number[4];    ///< Defines the build number string.
+  UINT8   SignOn[155];        ///< Defines the sign on message.
+  UINT8   CopyRight[61];      ///< Defines the copyright message.
+} BMP_STRUCTURE_SIGNON;
+
+/**
+  This structure defines the BMP General Bits
+**/
+typedef struct {
+  UINT16  bmp_BIOS_CS;          ///< Defines the start of BIOS code segment
+  UINT8   bmp_DOS_Boot_Mode;    ///< Defines the mode number to set when DOS is boot
+  UINT8   bmp_BW_Percent;       ///< Set percentage of total memory BW
+  UINT8   bmp_Popup_Mem_Size;   ///< Default Popup memory size in KB
+  UINT8   bmp_Resize_PCI_BIOS;  ///< BIOS size granularity in 0.5 KB
+  UINT8   Switch_CRT_To_DDC2;   ///< Obsolete field: Is the CRT already switched to DDC2
+  UINT8   bmp_Allow_Config;     ///< Bit 1 : 1, Enable aspect ratio for DOS
+                                ///< Bit 0 : 1, Allow boot to DVI even if it is not attached.
+} BMPGEN;
+
+/**
+  This structure defines Block 254 (BMP structure)
+**/
+typedef struct {
+  BMP_STRUCTURE_SIGNON    bmp_Signon_Message;   ///< Instance of signon and copyright message structure
+  BMPGEN                  bmp_General_Bytes;    ///< Instance of BMP General Bits structure.
+} BLOCK254_BMP_Structure;
+
+/**
+  This structure defines Block 1 (General Bytes Definitions)
+**/
+typedef struct {
+  UINT8   BlockId;        ///< Defines the Block ID (1)
+  UINT16  BlockSize;      ///< Defines the size of General bytes definition block.
+
+  /**
+  BMP General Bit Definitions 1\n
+  Bit 7 = DVO A color flip bit
+    = 0, No DVO A color flip
+    = 1, Flip DVO A color
+  Bits 6:4 = Clear screen (CLS) after Signon
+      = 000, No CLS
+      = 001, 0.5 sec pause and then CLS
+      = 010, 1.0 sec pause and then CLS
+      = 011, 1.5 sec pause and then CLS
+      = 100, 2.0 sec pause and then CLS
+      = 101, 2.5 sec pause and then CLS
+      = 110, 3.0 sec pause and then CLS
+      = 111, 3.5 sec pause and then CLS
+  Bit 3 = 1  Enable Display Signon
+  Bit 2 = 1  Enable Flex-aim Support
+  Bits 1:0 = Flat panel fitting enabling
+      = 00, Centering
+      = 01, Reserved
+      = 10, Aspect scaling
+      = 11, Fullscreen
+  **/
+  union {
+    UINT8  Value;
+    struct {
+      UINT8 PanelFitterEnabling:2;
+      UINT8 FlexAimSupportEnable:1;
+      UINT8 DisplaySignonEnable:1;
+      UINT8 ClearScreenTime:3;
+      UINT8 DvoAColorFlipEnable:1;
+    } Bits;
+  } bmp_Bits_1;
+
+  /**
+  BMP General Bit Definitions\n
+  Bit 7 = Hot plug support
+    = 0, Hot plug disabled
+    = 1, Hot plug enabled
+  Bit 6 = Dynamic CD clock feature
+    = 0, Dynamic CD clock feature is disabled
+    = 1, Dynamic CD clock feature is enabled
+  Bit 5 = Underscan support for VGA timings
+  Bit 4 = Disable SSC in Dual Display Twin Mode. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, No
+    = 1, Yes
+  Bit 3 = LFP power state on override by 5f64h,08h
+    = 0, No Override
+    = 1, Override
+  Bit 2 = Internal LVDS SSC frequency. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, 96/120MHz
+    = 1, 100MHz
+  Bit 1 = internal LVDS SSC (Spread Spectrum Clock) (This field is obsolete now. Kept for VBIOS only.)
+    = 0, Disabled
+    = 1, Enabled
+  Bit 0 = KvmrSessionEnable.
+    = 0, Disabled
+    = 1, Enabled
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 KvmrSessionEnable:1;
+      UINT8 Reserved_1:5;
+      UINT8 DynamicCdClockEnable:1;
+      UINT8 HotPlugEnable:1;
+    } Bits;
+  } bmp_Bits_2;
+
+  /**
+  BMP General Bit Definitions 3\n
+  Bit 7 = Ignore strap status
+      = 0 Do not ignore
+      = 1 Ignore
+  Bit 6 = Panel Timing algorithm
+      = 0 Preferred timings
+      = 1 Best fit timings
+  Bit 5 Copy iLFP DTD to SDVO LVDS DTD
+      = 0 Don't copy DTD
+      = 1 Copy DTD to
+  Bit 4 = VBIOS normal/extd. DT mode
+      = 0 Normal mode
+      = 1 DUAL mode
+  Bit 3 = FDI RX Polarity
+      = 0 Normal
+      = 1 Inverted
+  Bit 2 = Enable 180 Degree Rotation
+      = 0  Disable
+      = 1  Enable
+  Bit 1 = Single DVI-I connector for CRT and DVI display: Obsolete field
+      = 0 Disabled
+      = 1 Enabled
+  Bit 0 = Smooth Vision
+      = 0  Disabled
+      = 1  Enabled
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 Reserved1:1;
+      UINT8 SingleDviiCrtConnector:1;
+      UINT8 Enable180DegRotation:1;
+      UINT8 FdiRxPolarity:1;
+      UINT8 Reserved2:4;
+    } Bits;
+  } bmp_Bits_3;
+
+  UINT8   Reserved;     ///< Reserved field. It was Legacy_Monitor_Detect in previous platforms.
+
+  /**
+  Integrated display device support\n
+  Bits 7:6 = Reserved
+  Bit 5 = DP SSC Dongle Enable/Disable
+  Bit 4 = DP SSC Frequency. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, 96 MHz
+    = 1, 100 MHz
+  Bit 3 = DP SSC Enable
+    = 0, Disable
+    = 1, Enable
+  Bit 2 = Integrated EFP support
+    = 0, Disable
+    = 1, Enable
+  Bit 1 = Integrated TV support. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, Disable
+    = 1, Enable
+  Bit 0 = Integrated CRT support: Obsolete field
+    = 0, Disable
+    = 1, Enable
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 CrtSupported:1;
+      UINT8 TvSupported:1;
+      UINT8 EfpSupported:1;
+      UINT8 DpSscEnable:1;
+      UINT8 DpSscFrequency:1;
+      UINT8 DpDongleSscEnable:1;
+      UINT8 Reserved1:2;
+    } Bits;
+  } Int_Displays_Support;
+} VBT_GENERAL1_INFO;
+
+/**
+  This defines the Structure of PRD Boot Table Entry
+**/
+typedef struct {
+  UINT8 AttachBits;     ///< Bitmap representing the displays attached currently.
+  UINT8 BootDev_PipeA;  ///< Bitmap representing the display to boot on Pipe A.
+  UINT8 BootDev_PipeB;  ///< Bitmap representing the display to boot on Pipe B.
+} PRD_TABLE;
+
+/**
+  This defines the structure of Block 254 (PRD Boot Table/Child Device List)
+**/
+typedef struct {
+  UINT8     BlockId;    ///< Defines the Block ID (254)
+  UINT16    BlockSize;  ///< Defines the size of Block 254
+
+  PRD_TABLE PRDTable[16];                     ///< Defines the Child device list for enumerating child handles.
+  UINT16    PRD_Boot_Table_Number_Of_Entries; ///< Number of entries in child device list.
+} PRD_BOOT_TABLE;
+
+/**
+  This defines the Structure for a CHILD_STRUCT (used for all the displays).
+**/
+typedef struct {
+  UINT16  DeviceHandle;         ///< Unique ID indicating the group of display device (LFP/EFP1/EFP2/EFP3/EFP4).
+  UINT16  DeviceClass;          ///< Indicates the class of display device.
+  UINT8   I2CSpeed;             ///< Defines the I2C speed to be used for I2C transaction.
+  /**
+  Defines the DP on board redriver configuration.
+  BIT[7]    : Reserved
+  BIT[6]    : Is On Board DP Redriver Present
+          0 : No
+          1 : Yes
+  BIT[5:3]  : On Board Redriver VSwing Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+     Others : Reserved
+  BIT[2:0]  : On Board Redriver PreEmph Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+  Others    : Reserved
+  **/
+  union{
+  UINT8 Value;
+  struct {
+    UINT8 OnBoardPreEmphLevel:3;
+    UINT8 OnBoardVSwingLevel:3;
+    UINT8 OnBoardRedriverPresent:1;
+    UINT8 Reserved:1;
+    } Bits;
+  } DpOnBoardRedriver;
+
+  /**
+  Defines the DP on dock redriver configuration.
+  BIT[7]    : Reserved
+  BIT[6]    : Is On Dock DP Redriver Present
+          0 : No
+          1 : Yes
+  BIT[5:3]  : On Dock Redriver VSwing Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+     Others : Reserved
+  BIT[2:0]  : On Dock Redriver PreEmph Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+  Others    : Reserved
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 OnDockPreEmphLevel:3;
+    UINT8 OnDockVSwingLevel:3;
+    UINT8 OnDockRedriverPresent:1;
+    UINT8 Reserved:1;
+    } Bits;
+  } DpOnDockRedriver;
+
+  /**
+
+  Defines the HDMI level shifter configuration.
+  BIT[7:5]  : Hdmi Maximum data rate
+  BIT[4:0]  : Hdmi Level shifter value
+
+  **/
+  union{
+  UINT8 Value;
+  struct {
+    UINT8 HdmiLevelShifterValue:5;
+    UINT8 HdmiMaxDataRateBits:3;
+    } Bits;
+  } HdmiLevelShifterConfig;
+
+  UINT16  EFPDTDBufferPointer;  ///< Pointer to the DTD timing to be used in case of edidless EFP.
+
+  /**
+  Defines the first set of flags.
+  BIT[7-4]  : Reserved
+  BIT[3]    : Dual pipe ganged display support
+          0 : Display uses a single pipe/port
+          1 : Display uses two distinct pipes/ports.
+  BIT[2]    : Compression Method Select
+          0 : Compression using picture parameter set (PPS)
+          1 : Compression using Capability parameter set (CPS)
+  BIT[1]    : Compression enable/disable for this display.
+          0 : Disabled
+          1 : Enabled
+  BIT[0]    : EDID less EFP Enable
+          0 : Enable support for EDID less EFP.
+          1 : Disable support for EDID less EFP.
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 EdidlessEfpEnable:1;
+    UINT8 CompressionEnable:1;
+    UINT8 CompressionMethod:1;
+    UINT8 IsDualPortEnabled:1;
+    UINT8 Reserved:4;
+    } Bits;
+  } Flags0;
+
+  /**
+  Defines the compression index field for the display.
+  BITS[7-4]  : Reserved
+  BITS[3-0]  : Compression Structure index in the block 55.
+        0x0  : Index 0 in block 55
+        0x1  : Index 1 in block 55
+        0xF  : Not Applicable.
+      Others : Reserved
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 IndexInBlock55:4;
+    UINT8 Reserved:4;
+    } Bits;
+  } CompressionStructureIndex;
+
+  UINT8   SlaveDdiPort;         ///< The DVO port number of slave DDI to be used in case Flags0[3] = 1.
+
+  UINT8   Reserved_1;           ///< Reserved and might be used in other platforms.
+  UINT16  AddInOffset;          ///< Obsolete field.
+  UINT8   DVOPort;              ///< Specifies the port number of the display device represented in the device class.
+  UINT8   I2CBus;               ///< Specifies the GMBUS or I2C pin pair for add in card.
+  UINT8   SlaveAddr;            ///< Specifies the I2C address of the add in card.
+  UINT8   DDCBus;               ///< Specifies the GMBUS pin pair for EDID read.
+  UINT16  TimingInfoPtr;        ///< Pointer to the buffer where VBIOS stores the EDID of device.
+  UINT8   DVOCfg;               ///< Obsolete field.
+
+  /**
+  Flags 1\n
+  Bits 7:5  : Reserved
+  Bit 4     : HPD Sense Invert
+          0 : Invert not required (default)
+          1 : Invert required
+  Bit 3     : IBoost feature enable/disable.
+          0 : IBoost feature is disabled.
+          1 : IBoost feature is enabled.
+  Bit 2     : Hdmi 2.0 Motherboard Downsuppotred options
+          0 : Motherboard Down chip not supported
+          1 : Motherboard Down Chip Supported on the Board
+  Bit 1     : Lane Reversal feature.
+          0 : Disable
+          1 : Enable
+  Bit 0     : DP/HDMI routed to dock.
+          0 : Disable
+          1 : Enable
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 DockablePort:1;
+    UINT8 EnableLaneReversal:1;
+    UINT8 OnBoardLsPconDonglePresent:1;
+    UINT8 IBoostEnable:1;
+    UINT8 IsHpdInverted:1;
+    UINT8 Reserved:3;
+    } Bits;
+  } Flags_1;
+
+  UINT8   Compatibility;        ///< Compatibility is used in VBIOS only. It was used before device class was defined.
+  UINT8   AUX_Channel;          ///< Specifies the aux channel to be used for display port devices.
+  UINT8   Dongle_Detect;        ///< Indicates whether dongle detect is enabled or not.
+  UINT8   Capabilities;         ///< Bits 1-0 indicate pipe capabilities whether display can be used on one pipe or both the pipes.
+  UINT8   DVOWiring;            ///< Obsolete field.
+  UINT8   MipiBridgeType;       ///< MIPI bridge type
+  UINT16  DeviceClassExtension; ///< Obsolete.
+  UINT8   DVOFunction;          ///< Obsolete.
+
+  /**
+  Flags 2
+  Bits 7:4  : DP Port trace length from silicon to output port on the board
+          0 : Default RVP length
+          1 : Short trace length
+          2 : Long trace length
+  Bits 3:2  : Reserved
+  Bit 1     : Indicates whether this port is Thunderbolt port or not.
+          0 : No
+          1 : Yes
+  Bit 0     : DP 2 lane RCR# 1024829: USB type C to enable 2 lane DP display
+          0 : Disable
+          1 : Enable
+  **/
+  union {
+    UINT8   Value;
+    struct {
+      UINT8   UsbTypeCDongleEnabled:1;  ///< Indicates whether this port is USB type C.
+      UINT8   IsThunderboltPort:1;      ///< Indicates whether this port is Thunderbolt. (ICL+)
+      UINT8   Reserved:2;               ///< Reserved for future use.
+      UINT8   DpPortTraceLength:4;      ///< Dp port trace length from silicon to port.
+    } Bits;
+  } Flags_2;
+  UINT8   DP2XGpioIndex;        ///< GPIO index number for the USB type C.
+  UINT16  DP2XGpioNumber;       ///< GPIO number for USB type C.
+
+  /**
+  IBoost magnitude field.
+  Bits 7:4  : DP Boost magnitude
+          0 : 1
+          1 : 3
+          2 : 7
+     Others : Reserved for WHL.
+  Bits 3:0  : HDMI Boost magnitude
+          0 : 1
+          1 : 3
+          2 : 7
+  Others : Reserved.
+  **/
+  union {
+    UINT8   Value;
+    struct {
+      UINT8   DpEdpBoostMagnitude:4;
+      UINT8   HdmiBoostMagnitude:4;
+    } Bits;
+  } BoostMagnitude;
+} CHILD_STRUCT;
+
+/**
+  This structure defines Block 2 (General Bytes Definitions)
+**/
+typedef struct {
+  UINT8         BlockId;          ///< Defines the Block ID : 2.
+  UINT16        BlockSize;        ///< Defines the size of VBT General Info 2 Block.
+
+  UINT8         bmp_CRT_DDC_GMBUS_Pin;  ///< Obsolete field: Selects the CRT DDC GMBUS pin pair.
+  UINT8         bmp_DPMS_Bits;          ///< BMP DPMS Bit Definitions.
+  UINT16        bmp_Boot_Dev_Bits;      ///< BMP Boot Device Bit Definitions.
+  UINT8         SizeChild_Struct;       ///< Size of the ChildStruc structure.
+
+  CHILD_STRUCT  Child_Struct[ChildStruct_MAX];  ///< This array defines all the supported child structures.
+} VBT_GENERAL2_INFO;
+
+/**
+  This defines the structure of Block 3 (Original Display Toggle List)
+**/
+typedef struct {
+  UINT8   BlockId;                ///< Defines the Block ID : 3
+  UINT16  BlockSize;              ///< Defines the size of Original Display Toggle List Block
+  UINT8   bmp_Display_Detect;     ///< Display must be attached or not
+} BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST;
+
+/**
+  This defines structure of a pointer table.
+**/
+typedef struct {
+  UINT16  Offset;       ///< Defines the offset of the table from start of BIOS Data block.
+  UINT16  Size;         ///< Defines the size of an entry of the table.
+} BMP_TABLE_PTR;
+
+/**
+  This structure defines Block 252 (SBIOS Hooks and BMP Table Pointers).
+**/
+typedef struct {
+  UINT8           BlockId;          ///< Defines the Block ID : 252.
+  UINT16          BlockSize;        ///< Defines the size of SBIOS Hooks block.
+  UINT8           SbiosHooks[18];   ///< This array defines a series of SBIOS hooks. Each entry represents one hook.
+  BMP_TABLE_PTR   BmpTablePtr[26];  ///< This array defines pointers to all the important tables in the VBT.
+} BLOCK252_SBIOS_Hook;
+
+/**
+  This defines the structure of MMIO boot table entry
+**/
+typedef struct {
+  UINT32  Register;   ///< Defines the MMIO offset of the register.
+  UINT32  Value;      ///< Defines the default value of the register.
+} MMIO_BOOT_TABLE;
+
+/**
+  This structure defines Block 6 (MMIO Register Block)
+**/
+typedef struct {
+  UINT8           BlockId;              ///< Defines the Block ID : 6
+  UINT16          BlockSize;            ///< Defines the size of MMIO Register Table block.
+  UINT16          RegTableId;           ///< Defines the ID for MMIO register table (0xFFFC).
+  UINT8           AccessFlag;           ///< Defines the flag for data access size (02 for 4 byte read/write).
+  MMIO_BOOT_TABLE MMIOBootTable[14];    ///< Array containing the MMIO register table.
+  UINT16          TableEnd;             ///< Special value describing End of table (0xFFFF).
+} BLOCK06_MMIO_REG_TABLE;
+
+/**
+  This structure defines Block 7 (IO SW Flag Register Table)
+**/
+typedef struct {
+  UINT8   BlockId;          ///< Defines Block ID (7).
+  UINT16  BlockSize;        ///< Defines the size of IO SW Flag register table block.
+  UINT16  RegTableId;       ///< Defines the ID for IO SW Flag register table (0xFFFE).
+  UINT8   GRIndexRegLsb;    ///< Defines the read/write size. Value is 0xCE meaning 1 byte without mask.
+  UINT8   IOSWFlagReg;      ///< Defines the offset for the IO SW Flag register.
+  UINT8   Value;            ///< Defines the data/value for the register.
+  UINT16  TableEnd;         ///< Special value describing the end of table (0xFFFF).
+} BLOCK07_IOSWFLAG_REG_TABLE;
+
+/**
+  This structure defines the entry of SWF table.
+**/
+typedef struct {
+  UINT32  Register;   ///< Defines the MMIO offset of the SWF register.
+  UINT32  Value;      ///< Defines the default value for the SWF register.
+} SWF_TABLE;
+
+/**
+  This defines the structure of Block 8 (MMIO SW Flag Block).
+**/
+typedef struct {
+  UINT8     BlockId;      ///< Defines the Block ID : 8.
+  UINT16    BlockSize;    ///< Defines the size of MMIO SWF register table block.
+  UINT16    RegTableId;   ///< Defines the ID for MMIO SWF register table (0xFFFC).
+  UINT8     AccessFlag;   ///< Defines the data access size. Value is 0x02 meaning 4 bytes read/write.
+  SWF_TABLE SWFTable[7];  ///< Array containing the MMIO SWF register table.
+  UINT16    TableEnd;     ///< Special value describing end of table (0xFFFF).
+} BLOCK08_MMIOSWFLAG_REG_TABLE;
+
+/**
+  This structure defines the PSR feature table entry.
+**/
+typedef struct {
+  UINT8   SRD_Enables;        ///< Defines PSR features such as full link enable/disable and whether aux is required to wake up.
+  UINT8   SRD_WaitTimes;      ///< Defines lines to wait before link standby and idle frames to wait before SRD enable.
+  UINT16  SRD_TP1_WakeupTime; ///< TP 1 wake up time in multiples of 100.
+  UINT16  SRD_TP2_WakeupTime; ///< TP2/TP3 wake up time in multiples of 100
+} PSR_FEATURE_TABLE;
+
+/**
+  This defines the structure of Block 9 (PSR Features Block)
+**/
+typedef struct {
+  UINT8             BlockId;              ///< Defines the block ID : 9
+  UINT16            BlockSize;            ///< Defines the size of PSR Feature block.
+  PSR_FEATURE_TABLE PSRFeatureTable[16];  ///< Array containing the PSR Feature table.
+} BLOCK09_PSR_FEATURE;
+
+/**
+  This structure defines an entry of Mode Removal table.
+**/
+typedef struct {
+  UINT16  XRes;         ///< X resolution of the mode.
+  UINT16  YRes;         ///< Y resolution of the mode.
+  UINT8   Bpp;          ///< Bits per pixel of the mode.
+  UINT16  RRate;        ///< Refresh rate of the mode.
+  UINT8   RFlags;       ///< Flags specifying display type and functional area where the mode is to be removed.
+  UINT16  PanelFlags;   ///< Applicable to LFP only. Indicates which LFP panels the mode is to be removed.
+} MODE_REMOVAL_TABLE_ENTRY;
+
+/**
+  This defines the structure of Block 10 (Mode Removal Block)
+**/
+typedef struct {
+  UINT8                     BlockId;              ///< Defines the Block ID : 10.
+  UINT16                    BlockSize;            ///< Defines the size of Mode Removal table block.
+  UINT8                     EntrySize;            ///< Defines the size of one entry of mode removal table.
+  MODE_REMOVAL_TABLE_ENTRY  ModeRemovalTable[20]; ///< Array containing the mode removal table.
+  UINT16                    Terminator;           ///< Special value indicating end of mode removal table (0xFFFF).
+} BLOCK10_MODE_REMOVAL_TABLE;
+
+/**
+  This defines the structure of Block 12 (Driver Features Data Block)
+**/
+typedef struct {
+  UINT8   BlockId;                  ///< Defines the unique Block ID : 12
+  UINT16  BlockSize;                ///< Defines the size of Driver features block.
+
+  /**
+  This field defines the various driver related bits:\n
+  Bit 7 = Use 00000110h ID for Primary LFP
+        = 0, No
+        = 1, Yes
+  Bit 6 = Enable/Disable Sprite in Clone Mode
+        = 0, Disable
+        = 1, Enable
+  Bit 5 = Driver INT 15h hook
+        = 0, Disable
+        = 1, Enable
+  Bit 4 = Dual View Zoom
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = Hot Plug DVO
+        = 0, Disable
+        = 1, Enable
+  Bit 2 = Allow display switching when in Full Screen DOS.
+        = 0, Block Display Switching
+        = 1, Allow Display Switching
+  Bit 1 = Block display switching when DVD active
+        = 0, No Block Display Switching
+        = 1, Block Display Switching
+  Bit 0 = Boot device algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  **/
+  UINT8   bmp_Driver_Bits;
+  UINT16  bmp_Driver_Boot_Mode_X;   ///< X resolution of driver boot mode.
+  UINT16  bmp_Driver_Boot_Mode_Y;   ///< Y resolution of driver boot mode.
+  UINT8   bmp_Driver_Boot_Mode_BPP; ///< Bits per pixel of driver boot mode.
+  UINT8   bmp_Driver_Boot_Mode_RR;  ///< Refresh rate of driver boot mode.
+
+  /**
+  This field defines the extended driver bits 1.\n
+  Bits [15:14] = Integrated HDMI configuration
+              = 00b,  No Integrated HDMI
+              = 01b,  Port-B Only
+              = 10b,  Port-C Only
+              = 11b,  Both Port-B and Port-C
+  Bits 13 = TV Hotplug
+  Bits [12:11]  = LFP configuration
+                = 00b,  No LVDS
+                = 01b,  Integrated LVDS
+                = 10b,  SDVO LVDS
+                = 11b,  eDP
+  Bit 10 = Obsolete field: CRT hotplug
+          = 0, Disabled
+          = 1, Enabled (Default)
+  Bit 9 = SDVO device power down
+        = 0, Disabled (Default)
+        = 1, Enabled
+  Bit 8 = Preserve Aspect Ratio
+        = 0, Disabled (Default)
+        = 1, Enabled
+  Bit 7 = Display "Maintain Aspect Scaling" via CUI
+        = 0, No
+        = 1, Yes (Default)
+  Bit 6 = Sprite Display Assignment when Overlay is Active in Clone Mode:
+        = 0, Secondary
+        = 1, Primary
+  Bit 5 = Default Power Scheme user interface
+        = 0, CUI
+        = 1, 3rd Party Application
+  Bit 4 = NT 4.0 Dual Display Clone Support
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = Default Render Clock Frequency
+        = 0, High Frequency
+        = 1, Low Frequency
+  Bit 2 = Dual-Frequency Graphics Technology
+        = 0, No
+        = 1, Yes
+  Bit 1 = Selective Mode Pruning
+        = 0, No
+        = 1, Yes
+  Bit 0 = Enable LFP as primary
+        = 0, Disable
+        = 1, Enable
+**/
+  UINT16  bmp_Ext_Driver_Bits;
+
+  /**
+  This defines the driver flags related to CUI Hot key.\n
+  Bits [7:3] - Reserved
+  Bit 2 = Display Subsystem Enable/Disable
+        = 0, Enable (default Value)
+        = 1, Disable
+  Bit 1 = Embedded Platform
+        = 0, False
+        = 1, True
+  Bit 0 = Define CUI HotK Displays Statically
+        = 0, No
+        = 1, Yes
+  **/
+  UINT8   bmp_Display_Detect_CUIHotK;
+
+  UINT16  bmp_Legacy_CRT_Max_X;         ///< Obsolete field: Defines the legacy CRT X resolution for driver boot mode.
+  UINT16  bmp_Legacy_CRT_Max_Y;         ///< Obsolete field: Defines the legacy CRT Y resolution for driver boot mode.
+  UINT8   bmp_Legacy_CRT_Max_RR;        ///< Obsolete field: Defines the legacy CRT refresh rate for driver boot mode.
+
+  /**
+  This field defines the extended driver bits 2.\n
+  Bits [7:1] - Reserved
+  Bit 0 = Enable Internal Source Termination for HDMI
+        = 0, External Termination
+        = 1, Internal Termination
+  **/
+  UINT8   bmp_Ext2_Driver_Bits;
+
+  UINT8   bmp_VBT_Customization_Version;  ///< Defines the customized VBT version number.
+
+  /**
+  This field defines all the driver feature flags.\n
+  Bit 15 = PC Features Field's Validity
+         = 0, Invalid
+         = 1, Valid
+  Bit 14 = Hpd_wake - HPD events are routed to display driver when system is in S0ix/DC9
+         = 0, Disable
+         = 1, Enable
+  Bit 13 = Assertive Display Technology (ADT)
+         = 0, Disable
+         = 1, Enable
+  Bit 12 = Dynamic Media Refresh Rate Switching (DMRRS)
+         = 0, Disable
+         = 1, Enable
+  Bit 11 = Dynamic Frames Per Second (DFPS)
+         = 0, Disable
+         = 1, Enable
+  Bit 10 = Intermediate Pixel Storage (IPS)
+         = 0, Disable
+         = 1, Enable
+  Bit 9 = Panel Self Refresh (PSR)
+        = 0, Disable
+        = 1, Enable
+  Bit 8 = Intel Turbo Boost Technology
+        = 0, Disable
+        = 1, Enable
+  Bit 7 = Graphics Power Modulation Technology (GPMT)
+        = 0, Disable
+        = 1, Enable
+  Bit 6 = Graphics Render Standby (RS)
+        = 0, Disable
+        = 1, Enable
+  Bit 5 = Intel Display Refresh Rate Switching (DRRS)
+        = 0, Disable
+        = 1, Enable
+  Bit 4 = Intel Automatic Display Brightness (ADB)
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = DxgkDDI Backlight Control (DxgkDdiBLC)
+        = 0, Disable
+        = 1, Enable
+  Bit 2 = Intel Display Power Saving Technology (DPST)
+        = 0, Disable
+        = 1, Enable
+  Bit 1 = Intel Smart 2D Display Technology (S2DDT)
+        = 0, Disable
+        = 1, Enable
+  Bit 0 = Intel Rapid Memory Power Management (RMPM)
+        = 0, Disable
+        = 1, Enable
+  **/
+  UINT16  bmp_Driver_Feature_Flags;
+} BLOCK12_DRIVER_FEATURES;
+
+/**
+  This defines the structure of Block 13 (Driver Persistence Options)
+**/
+typedef struct {
+  UINT8   BlockId;                ///< Defines the unique Block ID : 13
+  UINT16  BlockSize;              ///< Defines the size of Driver Persistence options block.
+
+  /**
+  Defines the various persistence options.\n
+  Bits [15:10] - Reserved
+  Bit 9 = Docking Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 8 = DVO Hot Plug Persistence on Mode
+  Bit 7 = EDID Persistence on Mode
+  Bit 6 = Hot Key Persistence on Mode
+        = 0, No
+        = 1, Yes
+  Bit 5 = Hot Key Persistence on RestorePipe
+        = 0, No
+        = 1, Yes
+  Bit 4 = Hot Key Persistence on RefreshRate
+        = 0, No
+        = 1, Yes
+  Bit 3 = Hot Key Persistence on MDS/Twin
+        = 0, No
+        = 1, Yes
+  Bit 2 = Power Management Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 1 = Lid Switch Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 0 = Hot Key Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  **/
+  UINT16  PersistenceAlgorithm;
+
+  UINT8   PersistMaxconfig;       ///< Maximum mode persistence configurations (10-200)
+} BLOCK13_DRIVER_PERSISTENCE;
+
+/**
+  This defines the structure of Block 17 (SV Bits)
+**/
+typedef struct {
+  UINT8   BlockId;      ///< Defnies the unique Block ID : 17
+  UINT16  BlockSize;    ///< Defines the size of SV Bits block.
+
+  /**
+  Bits [7:4] = Reserved
+    Bit3  = Allow VBlank/VblankScanline timeout hang
+          = 0, Disable
+          = 1, Enable
+    Bit2  = Special GMBus support
+          = 0, Disable
+          = 1, Enable
+    Bit1  = Skip program pipe timings when set VGA modes
+          = 0, Setmode skip DVO Update
+          = 1, Setmode updates DVO
+    Bit0  = Disable VGA fast arbiter
+          = 0, Enabled
+          = 1, Disabled
+  **/
+  UINT8   SvBits1;
+  UINT8   SvBits2;      ///< Reserved for future use.
+  UINT8   SvBits3;      ///< Reserved for future use.
+  UINT8   SvBits4;      ///< Reserved for future use.
+  UINT8   SvBits5;      ///< Reserved for future use.
+  UINT8   SvBits6;      ///< Reserved for future use.
+  UINT8   SvBits7;      ///< Reserved for future use.
+  UINT8   SvBits8;      ///< Reserved for future use.
+} BLOCK17_SV_BITS;
+
+/**
+  This defines the structure of Block 18 (Driver Rotation)
+**/
+typedef struct {
+  UINT8   BlockId;                    ///< Defines the unique Block ID : 18
+  UINT16  BlockSize;                  ///< Defines the size of Driver Rotation block.
+  UINT8   RotationFeatureSupport;     ///< Rotation feature support field used by driver.
+  UINT8   Reserved1;                  ///< Reserved for future use.
+  UINT16  Reserved2;                  ///< Reserved for future use.
+  UINT32  Reserved3;                  ///< Reserved for future use.
+  UINT32  Reserved4;                  ///< Reserved for future use.
+} BLOCK18_DRIVER_ROTATION;
+
+/**
+  This structure defines an entry of OEM mode table.
+**/
+typedef struct {
+  /**
+  Mode Flags:
+    Bits[7:3] = Reserved
+    Bit 2 = Enable/disable this OEM mode in GOP driver.
+    Bit 1 = Enable/disable this mode in Driver
+    Bit 0 = Enable/disable this mode in VBIOS
+  **/
+  UINT8   ModeFlags;
+
+  /**
+  Display Device Flags:
+    Bit 7 = LFP2
+    Bit 6 = EFP2
+    Bit 5 = EFP3
+    Bit 4 = EFP4
+    Bit 3 = LFP
+    Bit 2 = EFP
+    Bit 1 = Rsvd
+    Bit 0 = Rsvd
+  **/
+  UINT8   DisplayFlags;
+  UINT16  XRes;         ///< Defines the X resolution of the mode.
+  UINT16  YRes;         ///< Defines the Y resolution of the mode.
+
+  /**
+  Defines the bits per pixel of the mode.
+    Bit 7:3 = Reserved
+    Bit 2 = 32 BPP
+    Bit 1 = 16 BPP
+    Bit 0 = 8 BPP
+  **/
+  UINT8   Bpp;
+  UINT8   RRate;        ///< Defines the refresh rate of the mode.
+  DTD_STRUCTURE Dtd;    ///< Defines the 18 byte timing config for the mode.
+} OEM_MODE_ENTRY;
+
+/**
+  This defines the structure of Block 20 (OEM Mode Customization Block)
+**/
+typedef struct {
+  UINT8           BlockId;          ///< Defines the unique block ID : 20
+  UINT16          BlockSize;        ///< Defines the size of OEM customization block.
+  UINT8           NumOfEntry;       ///< Defines the number of entries in OEM Mode table.
+  UINT8           EntrySize;        ///< Defines the size of one entry of OEM Mode table.
+  OEM_MODE_ENTRY  OemModeTable[6];  ///< Array defining the OEM mode table.
+} BLOCK20_OEM_CUSTOMIZATION;
+
+/**
+  This defines the structure of Block 26 (TV options)
+**/
+typedef struct {
+  UINT8   BlockId;                  ///< Defines the unique Block ID : 26
+  UINT16  BlockSize;                ///< Defines the size of TV Options block.
+
+  /**
+  Defines the TV options:
+    Bit 15  = D-Conector Support
+            = 0, Disable
+            = 1, Enable
+    Bit 14 = Add 1776x1000 when 1080i is selected and add 1184x666 when 720p is selected
+            = 0, Disable
+            = 1, Enable
+    Bit 13:12 Underscan/overscan for HDTV via DVI
+            = 00b, Enable Underscan and Overscan modes (Default)
+            = 01b, Enable only overscan modes
+            = 10b, Enable only underscan modes
+    Bits 11:2 = Reserved
+    Bit 1:0 = Underscan/overscan for HDTV via Component (YPrPb)
+            = 00b, Enable Underscan and Overscan modes (Default)
+            = 01b, Enable only overscan modes
+            = 10b, Enable only underscan modes
+  **/
+  UINT16  bmp_TV_Options_1;
+} BLOCK26_TV_OPTIONS;
+
+/**
+  This structure defines the eDP panel power sequencing parameters.
+**/
+typedef struct {
+  UINT16  T3;         ///< Panel Power-Up Delay.
+  UINT16  T8;         ///< Panel Power-On to backlight Enable Delay.
+  UINT16  T9;         ///< Backlight-Off to Power-Down Delay.
+  UINT16  T10;        ///< Power-Down Delay.
+  UINT16  T12;        ///< Power Cycle Delay.
+} EDP_PWR_SEQ;
+
+/**
+  This structure defines the PWM<-->Backlight delays for a single eDP panel.
+**/
+typedef struct {
+  UINT16  PwmOnToBacklightEnableDelay;      ///< PWM on to backight enable delay.
+  UINT16  BacklightDisableToPwmOffDelay;    ///< Backlight disable to PWM off delay.
+} EDP_PWM_BACKLIGHT_DELAYS;
+
+/**
+  This defines FLT parameters for a single eDP panel.
+  Bits[15:12] : VSwing level
+            0 : 0.4V (default)
+            1 : 0.6V
+            2 : 0.8V
+            3 : 1.2V
+       Others : Reserved
+  Bits[11:8]  : Pre-emphasis level
+            0 : no pre-emphasis (default)
+            1 : 3.5dB
+            2 : 6dB
+            3 : 9.5dB
+       Others : Reserved
+  Bits[7:4]   : Lane count (port width)
+            0 : x1 mode (default)
+            1 : x2 mode
+            2 : Reserved
+            3 : x4 mode
+       Others : Reserved
+  Bits[3:0]   : data rate
+            0 : 1.62 Gbps
+            1 : 2.7 Gbps
+            2 : 5.4 Gbps
+       Others : Reserved
+**/
+typedef union {
+  UINT16 Value;
+  struct {
+    UINT16 DataRate:4;
+    UINT16 LaneCount:4;
+    UINT16 PreEmphasisLevel:4;
+    UINT16 VSwingLevel:4;
+  } Bits;
+} EDP_FAST_LINK_TRAINING_PARAMS;
+
+/**
+  This defines Full link training parameters for a single eDP panel.
+  Bits[7:4] : VSwing level
+          0 : 0.4V (default)
+          1 : 0.6V
+          2 : 0.8V
+          3 : 1.2V
+     Others : Reserved
+  Bits[3:0] : Pre-emphasis level
+          0 : no pre-emphasis (default)
+          1 : 3.5dB
+          2 : 6dB
+          3 : 9.5dB
+     Others : Reserved
+**/
+typedef union {
+  UINT8   Value;
+  struct {
+    UINT8   PreEmphasisLevel:4;
+    UINT8   VSwingLevel:4;
+  } Bits;
+} EDP_FULL_LINK_TRAINING_PARAMS;
+
+/**
+  This defines the structure of Apical Parameters for a single eDP panel.
+**/
+typedef struct {
+  UINT32      PanelOui;             ///< Apical IP specific field for Panel OUI
+  UINT32      DPCDBaseAddress;      ///< Apical IP specific field for DPCD Base address
+  UINT32      DPCDIrdidixControl0;  ///< Apical IP specific field for DPCD Idridix Control 0
+  UINT32      DPCDOptionSelect;     ///< Apical IP specific field for DPCD option select
+  UINT32      DPCDBacklight;        ///< Apical IP specific field for DPCD backlight
+  UINT32      AmbientLight;         ///< Apical IP specific field for Ambient light
+  UINT32      BacklightScale;       ///< Apical IP specific field for backlight scale
+} EDP_APICAL_PARAMS;
+
+/**
+  This defines the structure of Block 27 (eDP Display Block)
+**/
+typedef struct {
+  UINT8       BlockId;            ///< Defines the unique Block ID : 27
+  UINT16      BlockSize;          ///< Defines the size of eDP display VBT block.
+
+  EDP_PWR_SEQ eDP_PWR_SEQ[16];    ///< Array defining the panel power sequencing for all 16 eDP panels.
+
+  /**
+  Defines the panel color depth in bits per pixel. 2 Bits for each Panel.
+    Bits[1:0] Panel color depth for Panel #1
+      = 00, 18bpp
+      = 01, 24bpp
+      = 10, 30bpp
+      = 11, 36bpp
+  **/
+  UINT32      eDP_Panel_Color_Depth;
+
+  /**
+    Array containing the FLT parameters of 16 eDP panels.
+  **/
+  EDP_FAST_LINK_TRAINING_PARAMS      eDP_Fast_Link_Training_Params[16];
+
+  /**
+  This field defines the eDP sDRRS MSA Timing Delay for all 16 eDP panels. 2 Bits for Each Panel.
+  Bits[1:0] for Panel #1
+    = 00, Line 1
+    = 01, Line 2
+    = 10, Line 3
+    = 11, Line 4
+  **/
+  UINT32      eDP_sDRRS_MSA_Delay;
+
+  /**
+  Defines the S3D feature enable/disable for all 16 eDP panels. 1 Bit for Each Panel.
+  Bits[0] for Panel #1
+    = 0, S3D disabled for this panel
+    = 1, S3D enabled for this panel
+  **/
+  UINT16      eDP_S3D_Feature;
+
+  /**
+  Defines the T3 optimization enable/disable for all 16 panels. 1 Bit for each panel.
+  Bits[0] = Panel #1
+    = 0, T3 optimization disabled for this panel
+    = 1, T3 optimization enabled for this panel
+  **/
+  UINT16      eDP_T3_Optmization;
+
+  /**
+  Defines the Edp vswing and pre-emphasis for all 16 panels. 4 Bits for Each Panel
+  Bits[3:0] = Panel #1
+    = 0, Use table 1 for this panel.
+    = 1, Use table 2 for this panel.
+  **/
+  UINT64       VswingPreEmphasisTableNum;
+
+  /**
+  Defines the Edp fast link training support on all 16 panels. 1 Bit for Each Panel
+  Bits[0] = Panel #1
+    = 0, FastLinkTraining feature is disabled for this panel
+    = 1, FastLinkTraining feature is enabled for this panel
+  **/
+  UINT16     EdpFastLinkTrainingSupportOnPanel;
+
+  /**
+  Defines whether the Set power state at DPCD 600h is to be done in eDP enable/disable sequence.
+  Bits[0] = Panel #1
+    = 0, Set power state at DPCD 600h feature is disabled for this panel
+    = 1, Set power state at DPCD 600h feature is enabled for this panel
+  **/
+  UINT16     SetPowerStateAtDPCD600h; //This is not used currently
+
+  /**
+    Array defining the PWM <--> Backlight related delays for 16 panels.
+  **/
+  EDP_PWM_BACKLIGHT_DELAYS eDP_Pwm_BackLight_Delays[16];
+
+  /**
+  Defines the Edp full link training support on all 16 panels. 1 Bit for Each Panel.
+  \verbatim
+  Bits[0] : Panel #1
+        0 : Initial vswing and pre-emphasis levels are not provided for Full link training
+        1 : Initial vswing and pre-emphasis levels are provided for Full link training
+  Bits 1 to 15 are for panel # 2 to 16.
+  \endverbatim
+  **/
+  UINT16     InitialFullLinkTrainingParamsProvidedInVbt;
+
+  /**
+    Array containing the initial Vswing and Pre-emphasis parameters for Full link training.
+  **/
+  EDP_FULL_LINK_TRAINING_PARAMS    eDP_Full_Link_Training_Params[16];
+
+  /**
+  Defines the Edp Apical assertive display IP support on all 16 panels. 1 Bit for Each Panel.
+  Bit 0   : Panel #1
+        0 : Apical assertive display IP is disabled for this panel.
+        1 : Apical assertive display IP is enabled for this panel.
+  Bits 1 to 15 are for panel # 2 to 16.
+  **/
+  UINT16                           IsApicalAssertiveDisplayIpEnable;
+
+  /**
+    Array containing the Apical parameters for all 16 panels
+  **/
+  EDP_APICAL_PARAMS                eDP_Apcial_Params[16];
+} BLOCK27_EDP_FEATURES;
+
+/**
+  This defines the structure of Block 28 (Edidless EFP support DTD timings)
+**/
+typedef struct {
+  UINT8                 BlockId;                    ///< Defines the unique Block ID : 28
+  UINT16                BlockSize;                  ///< Defines the size of Edidless EFP support block.
+  DTD_STRUCTURE         Edidless_EFP_DTD_Struc[4];  ///< Array defining the DTD timing for 3 EFP devices.
+} BLOCK28_EDIDLESS_EFP;
+
+/**
+This defines the structure of toggle list entry.
+**/
+typedef struct {
+  /**
+  Defines the display device selection for toggling
+  Bit 15 = EFP4.3 (Reserved for WHL)
+  Bit 14 = EFP3.3
+  Bit 13 = EFP2.3
+  Bit 12 = EFP1.3
+  Bit 11 = EFP4.2 (Reserved for WHL)
+  Bit 10 = EFP3.2
+  Bit 9  = EFP2.2
+  Bit 8  = EFP1.2
+  Bit 7  = LFP2
+  Bit 6  = EFP2
+  Bit 5  = EFP3
+  Bit 4  = EFP4
+  Bit 3  = LFP
+  Bit 2  = EFP
+  Bit 1  = TV
+  Bit 0  = CRT
+  **/
+  UINT16  DisplayDevice;
+} CNL_TOGGLE_LIST_ENTRY;
+
+/**
+  This defines the structure of Block 31 (Toggle Lists for Cannonlake)
+**/
+typedef struct {
+  UINT8                   BlockId;              ///< Defines the unique Block ID : 31
+  UINT16                  BlockSize;            ///< Defines the size of Toggle List Block.
+  UINT16                  NumOfEntry1;          ///< Defines the number of entries in toggle list 1.
+  UINT8                   EntrySize1;           ///< Defines the size of toggle list entry present in list 1.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList1Entry[16]; ///< Array defining the toggle list 1.
+  UINT16                  NumOfEntry2;          ///< Defines the number of entries in toggle list 2.
+  UINT8                   EntrySize2;           ///< Defines the size of toggle list entry present in list 2.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList2Entry[8];  ///< Array defining the toggle list 2.
+  UINT16                  NumOfEntry3;          ///< Defines the number of entries in toggle list 3.
+  UINT8                   EntrySize3;           ///< Defines the size of toggle list entry present in list 3.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList3Entry[8];  ///< Array defining the toggle list 3.
+  UINT16                  NumOfEntry4;          ///< Defines the number of entries in toggle list 4.
+  UINT8                   EntrySize4;           ///< Defines the size of toggle list entry present in list 4.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList4Entry[8];  ///< Array defining the toggle list 4.
+} BLOCK31_TOGGLE_LIST;
+
+/**
+  This defines the structure of Display device removal configuration entry.
+**/
+typedef struct {
+  /**
+  Defines the display device configuration to be removed.
+  Bit 15 = EFP4.3 (Reserved for WHL)
+  Bit 14 = EFP3.3
+  Bit 13 = EFP2.3
+  Bit 12 = EFP1.3
+  Bit 11 = EFP4.2 (Reserved for WHL)
+  Bit 10 = EFP3.2
+  Bit 9  = EFP2.2
+  Bit 8  = EFP1.2
+  Bit 7  = LFP2
+  Bit 6  = EFP2
+  Bit 5  = EFP3
+  Bit 4  = EFP4
+  Bit 3  = LFP
+  Bit 2  = EFP
+  Bit 1  = TV
+  Bit 0  = CRT
+  **/
+  UINT16  DisplayDeviceConfiguration;
+} CNL_DISPLAY_CONFIGURATION_ENTRY;
+
+/**
+  This defines the structure of Block 32 (Display removal configuration Block)
+**/
+typedef struct {
+  UINT8                                BlockId;       ///< Defines the unique Block ID = 32
+  UINT16                               BlockSize;     ///< Defines the size of Display removal configuration block.
+  UINT8                                NumOfEntry;    ///< Defines the number of entries in display removal configuraion table.
+  UINT8                                EntrySize;     ///< Defines the size of 1 entry in display removal configuration table.
+  CNL_DISPLAY_CONFIGURATION_ENTRY      RemoveDisplayConfiguration[15];    ///< Array defining the display removal configuration table.
+}BLOCK32_DISPLAY_CONFIGURATION_REMOVAL;
+
+/**
+  This defines the Local Flat panel basic details such as resolution and the various registers.
+**/
+typedef struct {
+  UINT16  XRes;                   ///< X resolution of the panel.
+  UINT16  YRes;                   ///< Y resolution of the panel.
+  UINT32  LVDSDigDisReg;          ///< MMIO offset of LFP digital display port register.
+  UINT32  LVDSDigDisVal;          ///< Value of LFP digital display port register.
+  UINT32  OnSeqDelayReg;          ///< MMIO offset of Panel power on sequencing delay register.
+  UINT32  OnSeqDelayVal;          ///< Value of Panel power on sequencing delay register.
+  UINT32  OffSeqDelayReg;         ///< MMIO offset of Panel power off sequencing delay register.
+  UINT32  OffSeqDelayVal;         ///< Value of Panel power off sequencing delay register.
+  UINT32  CycleDelay_RefDivReg;   ///< MMIO offset of Panel power cycle delay and reference divider register.
+  UINT32  CycleDelay_RefDivVal;   ///< Value of Panel power cycle delay and reference divider register.
+  UINT16  Terminate;              ///< Special value 0xFFFF indicating end of data.
+} FP_DATA;
+
+/**
+  This defines the structure consisting of all details for a single Local Flat panel.
+**/
+typedef struct {
+  FP_DATA       FP_Data;      ///< Instance of ::FP_DATA structure.
+  DTD_STRUCTURE DTD_Data;     ///< Instance of ::DTD_STRUCTURE which contains the DTD timings for the panel.
+  PID_DATA      PID_Data;     ///< Instance of ::PID_DATA structure which contains panel related information used by driver.
+} LVDS_FP_TABLE;
+
+/**
+  This structure defines all the details regarding Backlight control for LFP.
+**/
+typedef struct {
+  /**
+  Defines the backlight features for the panel.
+  Bits 7:6  = GMBus Speed:
+            = 00, 100 KHz
+            = 01, 50 KHz
+            = 10, 400 KHz
+            = 11, 1 MHz
+  Bits 5:3  = Inverter GPIO Pins
+            = 0, None
+            = 1, I2C GPIO pins
+            = 2, Analog CRT DDC pins
+            = 3, DVI/LVDS DDC GPIO pins
+            = 5, sDVO I2C GPIO pins
+  Bit 2     = Inverter Polarity (i2c & PWM)
+            = 0, Normal (0 = Minimum brightness)
+            = 1, Inverted (0 = Maximum brightness)
+  Bits 1:0  = BLC Inverter Type
+            = 00, None/External
+            = 01, i2c
+            = 10, PWM
+            = 11, Reserved
+  **/
+  UINT8   BLC_Ftr;
+
+  UINT16  PWM_Freq;       ///< PWM inverter frequency in KHz
+  UINT8   Min_Brightness; ///< Minimum brightness in the range 0-255
+  UINT8   I2C_Add;        ///< I2C Inverter Slave Address
+  UINT8   I2C_Command;    ///< I2C Inverter command code
+} BLC;
+
+/**
+  This defines the structure of Block 40 (LFP Features)
+**/
+typedef struct {
+  UINT8   BlockId;          ///< Defines the unique Block ID : 40
+  UINT16  BlockSize;        ///< Defines the size of LFP Features block.
+
+  UINT8   bmp_Panel_type;   ///< Defines the panel type of LFP.
+  UINT8   Skip1;            ///< Obsoleted.
+
+  /**
+  Capabilities byte:
+  Bit 15:7  = SW Workaround bits
+  Bit 6     = Panel EDID support
+            = 0, Disable
+            = 1, Enable
+  Bit 5     = Pixel dithering
+            = 0, Disable
+            = 1, Enable
+  Bit 4     = Panel Fitting ratio calc.
+            = 0 - Manual
+            = 1 - Automatic
+  Bit 3     = Panel Fitting Graphics mode
+            = 0, Bilinear
+            = 1, Enhanced
+  Bit 2     = Panel Fitting Text mode
+            = 0, Bilinear
+            = 1, Enhanced
+  Bit 1:0   = Panel Fitting Support
+            = 00, No panel fitting
+            = 01, Text panel fitting
+            = 10, GFX panel fitting
+            = 11, Text+GFX panel fitting
+  **/
+  UINT16  bmp_LVDS_Capabilities;
+
+  /**
+  Defines the channel type of LFP. 2 Bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Automatic (algorithm)
+    = 01, Single Channel
+    = 10, Dual Channel
+    = 11, Reserved
+  **/
+  UINT32  INT_LVDS_Panel_Channel_Bits;
+
+  UINT16  Enable_SSC_Bit;         ///< LVDS Spread Spectrum Clock
+  UINT16  SSC_Freq_Bit;           ///< LVDS Spread Spectrum Clock Frequency
+  UINT16  Disable_SSC_DDT_Bit;    ///< Disable SSC in Dual Display Twin
+
+  /**
+  Defines the panel color depth. 1 Bits for each Panel.
+  Bits[0] for Panel #01
+    = 0, 18bpp
+    = 1, 24bpp
+  **/
+  UINT16  INT_Panel_Color_Depth;
+
+  /**
+  Defines the Panel type. 2 Bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Static DRRS
+    = 01, D2PO
+    = 10, Seamless
+    = 11, Reserved
+  **/
+  UINT32  DPS_Panel_Type_Bits;
+
+  /**
+  Defines the type of backlight control for the LFP. 2 bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Default
+    = 01, CCFL backlight
+    = 10, LED backlight
+    = 11, Reserved
+  **/
+  UINT32  BLT_Control_Type_Bits;
+  /**
+  Defines the LFP power enable flag in S0 state for all 16 panels. 1 Bit for Each Panel.
+  Bits[0] : Panel #1
+        0 : Do not keep LCDVCC on during S0 state.
+        1 : Keep LCDVCC on during S0 state.
+  Bits 1 to 15 are for panel # 2 to 16.
+  **/
+  UINT16     LcdvccOnDuringS0State;
+} BLOCK40_LVDS_FEATURES;
+
+/**
+  This structure defines the second type of BMP table pointers.
+  This is used to store pointers to LFP Flat panel data, DTD and PID information.
+**/
+typedef struct {
+  UINT16  Offset;       ///< Offset of the table.
+  UINT8   Size;         ///< Size of the table.
+} BMP_TABLE_TYPE2_PTR;
+
+/**
+  This structure defines a set of 3 pointers for LFP display.
+  These pointers point to FP data, DTD and PID information respectively.
+**/
+typedef struct {
+  BMP_TABLE_TYPE2_PTR   FpTablePtr;   ///< Pointer to FP Data of the LFP panel.
+  BMP_TABLE_TYPE2_PTR   DtdTablePtr;  ///< Pointer to DTD of the LFP panel.
+  BMP_TABLE_TYPE2_PTR   PidTablePtr;  ///< Pointer to the PID data of the LFP panel.
+} LFP_TABLE_POINTERS;
+
+/**
+  This defines the structure of Block 41 (LFP Table Pointers for FPDATA, DTD and PID)
+**/
+typedef struct {
+  UINT8               BlockId;                  ///< Defines the unique Block ID:41
+  UINT16              BlockSize;                ///< Defines the size of LFP Table Pointer Block.
+  UINT8               NumOfEntries;             ///< Defines the number of entries in the Table.
+  LFP_TABLE_POINTERS  LfpTablePointers[16];     ///< Array of ::LFP_TABLE_POINTERS for all 16 panels.
+  UINT16              LfpPanelNameTableOffset;  ///< Offset of LFP panel names table.
+  UINT8               LfpPanelNameLength;       ///< Length of a single LFP panel's name.
+} BLOCK41_LFP_TABLE_POINTERS;
+
+/**
+  This defines the structure of Block 42 (Complete LFP Panel Information)
+**/
+typedef struct {
+  UINT8         BlockId;                ///< Defines the unique block ID : 42
+  UINT16        BlockSize;              ///< Defines the size of Complete LFP panel information for all 16 panels.
+  LVDS_FP_TABLE LVDS_FP_Table[16];      ///< Array of ::LVDS_FP_TABLE containing data of 16 panels.
+  UINT8         LFP_PANEL_NAMES[16][13];///< Array defining the panel names for all 16 panels.
+
+  /**
+  1 Bit for Each Panel
+  Bit0  = Scaling feature for panel 1.
+        = 0, Scaling feature is disabled for this panel.
+        = 1, Scaling feature is enabled for this panel.
+  **/
+  UINT16        EnableScaling; //This is not used currently
+
+  /**
+    Array defining DRRS minimum refresh rate. 1 Byte for Each Panel.
+  **/
+  UINT8         Seamless_DRRS_Min_RR[16];
+
+  /**
+    Array defining Pixel Overlap Count. 1 Byte for Each Panel.
+  **/
+  UINT8         PixelOverlapCount[16];
+} BLOCK42_LVDS_PANEL_INFO;
+
+typedef union {
+  /**
+  Backlight control parameters.\n
+  Bits 7:4  : PWM Controller Selection
+          0 : Controller 0
+          1 : Controller 1
+          2 : Controller 2
+          3 : Controller 3
+     Others : Reserved.
+  Bits 3:0  : PWM Source Selection
+          0 : PMIC PWM
+          1 : LPSS PWM
+          2 : DISPLAY PWM
+          3 : CABC PWM
+     Others : Reserved.
+  **/
+  UINT8 Value;
+  struct {
+    UINT8 PwmSourceSelection:4;
+    UINT8 PwmControllerSelection:4;
+  } Bits;
+} BKLT_CTRL_PARAMS;
+
+/**
+  This defines the structure of Block 43 (LFP Brightness Control)
+**/
+typedef struct {
+  UINT8             BlockId;                ///< Defines the unique Block ID : 43
+  UINT16            BlockSize;              ///< Defines the size of Brightness control block.
+
+  UINT8             SIZE_BLCStruc;          ///< Defines the size of single entry in Backlight control table for LFP.
+  BLC               BLC_Struct[16];         ///< Array defining the backlight control for 16 LFP panels.
+  UINT8             Post_Brightness[16];    ///< Array defining the initial brightness for all 16 panels.
+  BKLT_CTRL_PARAMS  Brightness_Control[16]; ///< Array defining the brightness control method for all 16 panels
+} BLOCK43_LVDS_BLC;
+
+/**
+  This defines the structure of Block 44 (LFP Power Conservation Features)
+**/
+typedef struct {
+  UINT8   BlockId;        ///< Defines the unique block ID : 44
+  UINT16  BlockSize;      ///< Defines the size of LFP Power Conservation Features block.
+  union {
+  /**
+  Bit[7]        : ALS Enable/Disable
+               0 - Disable
+               1 - Enable
+  Bit[6]        : Display LACE support
+               0 - Not supported
+               1 - Supported
+  Bit[5]        : Default Display LACE enabled status
+               0 - Disabled
+               1 - Enabled
+  Bit[4]        : Reserved
+  Bit[3:1]      : Power conservation preference level.
+                 4 is default in a range of 1 to 6.
+  Bit[0]        : Reserved
+  **/
+    UINT8  Value;
+    struct {
+      UINT8 Reserved:1;
+      UINT8 PwrConservation:3;
+      UINT8 Reserved_1:1;
+      UINT8 DefalutDisplayLaceEnable:1;
+      UINT8 DisplayLaceSupport:1;
+      UINT8 AlsEnable:1;
+    } Bits;
+  } LfpFeatureBits;
+
+  UINT16  AlsData[10];    ///< Defines the main ALS data.
+
+  union {
+  /**
+  Bit[7:3]      : Reserved
+  Bit[2:0]      : Aggressiveness Level Profile.
+            000 - Minimum
+            001 - Moderate
+            010 - High
+  **/
+    UINT8  Value;
+    struct {
+      UINT8 AggressionProfileLevel:3;
+      UINT8 Reserved:5;
+    } Bits;
+  } LaceAggressivenessProfile; ///< Defines the LACE Aggressiveness Profile
+} BLOCK44_ALS;
+
+/**
+  This defines the structure of Black Frame Insertion table entry.
+**/
+typedef struct {
+  /**
+  BFI Features\n
+  Bit[7-2]  : Reserved\n
+  Bit[1]    : Enable Brightness control in CUI\n
+  Bit[0]    : Enable BFI in driver
+  **/
+  UINT8         EnableBits;
+  UINT8         BrightnessNonBFI;   ///< Brightness percentage in non BFI mode
+} BFI;
+
+/**
+  This defines the structure of Block 45 (Black Frame insertion Support for LFP)
+**/
+typedef struct {
+  UINT8              BlockId;         ///< Defines the unique Block ID : 45
+  UINT16             BlockSize;       ///< Defines the size of Black frame insertion support block.
+  UINT8              SIZE_BFIStruc;   ///< Defines the size of 1 entry of black frame data.
+  BFI                BFI_Struct[16];  ///< Array defining the data of black frame insertion for all 16 panels.
+} BLOCK45_BFI_SUPPORT;
+
+/**
+  This structure defines the chromaticity information for a single LFP panel.
+**/
+typedef struct {
+  /**
+  Defines the chromaticity feature enable bits
+  Bits 7:2  = Reserved
+  Bit 1     = Override EDID values for chromaticity if enabled, Instead Use VBT values
+            = 0, Disable, Use the EDID values
+            = 1, Enable, Use the values from the VBT
+  Bit 0     = Enable chromaticity feature. EDID values will be used when this feature is enabled.
+            = 0, Disable
+            = 1, Enable
+  **/
+  UINT8        EnableBits;
+
+  UINT8        Red_Green_1;   ///< Red/green chormaticity coordinates at EDID offset 19h
+  UINT8        Blue_White_1;  ///< Blue/white chromatiity coordinates at EDID offset 1Ah
+  UINT8        Red_X1;        ///< Red x coordinate at EDID offset 1Bh
+  UINT8        Red_Y1;        ///< Red x coordinate at EDID offset 1Ch
+  UINT8        Green_X1;      ///< Green x coordinate at EDID offset 1Dh
+  UINT8        Green_Y1;      ///< Green x coordinate at EDID offset 1Eh
+  UINT8        Blue_X1;       ///< Blue x coordinate at EDID offset 1Fh
+  UINT8        Blue_Y1;       ///< Blue x coordinate at EDID offset 20h
+  UINT8        White_X1;      ///< White x coordinate at EDID offset 21h
+  UINT8        White_Y1;      ///< White x coordinate at EDID offset 22h
+} CHROMATICITY;
+
+/**
+  This structure defines the Luminance information for a single LFP panel.
+**/
+typedef struct {
+  /**
+  Defines the chromaticity feature enable bits
+  Bits 7:2  : Reserved
+  Bit 1     : Enable Gamma feature.
+            : if enabled, use gamma values from this block.
+          0 : Disable
+          1 : Enable
+  Bit 0     : Enable Luminance feature.
+            : if enabled, use values from this block.
+          0 : Disable
+          1 : Enable
+  **/
+  UINT8        EnableBits;
+  /**
+    Luminance info (refer DisplayID 2.0)
+    2 byte value, encoded in IEEE 754 half-precision binary floating point format
+  **/
+  UINT16      MinLuminance;           ///< Native minimum luminance
+  UINT16      MaxFullFrameLuminance;  ///< Native maximum luminance (Full Frame)
+  UINT16      MaxLuminance;           ///< Native Maximum Luminance (1% Rectangular Coverage)
+  /**
+    Gamma EOTF
+    Gamma values range from 00h through FFh which will come from VBT.
+    Value shall define the gamma range, from 1.00 to 3.54.
+    Field Value = (Gamma (value from VBT) + 100) / 100
+
+    FFh = No gamma information shall be provided
+  **/
+  UINT8 Gamma;
+
+}LUMINANCE_AND_GAMMA;
+
+/**
+  This defines the structure of Block 46 (Chromaticity Support)
+**/
+typedef struct {
+  UINT8              BlockId;                 ///< Defines the unique Block ID : 46
+  UINT16             BlockSize;               ///< Defines the size of Chromaticity Block.
+  CHROMATICITY       Chromaticity_Struct[16]; ///< Defines the chromaticity information for all 16 panels.
+  LUMINANCE_AND_GAMMA  Luminance_Gamma_Struct[16];    ///< Defines the lumianance information for all 16 panels.
+} BLOCK46_CHROMATICITY_SUPPORT;
+
+/**
+  This defines the structure of Block 51 (Fixed Mode Set)
+**/
+typedef struct{
+  UINT8       BlockId;        ///< Defines the unique block ID : 51.
+  UINT16      BlockSize;      ///< Defines the size of Fixed mode set feature block.
+  UINT8       FeatureEnable;  ///< Whether the fixed mode set feature is enabled/disabled.
+  UINT32      XRes;           ///< X resolution of the fixed mode.
+  UINT32      YRes;           ///< Y resolution of the fixed mode.
+} BLOCK51_FIXED_MODE_SET;
+
+/**
+  This defines the Complete VBT Structure for generation purpose
+**/
+typedef struct {
+  VBT_HEADER                                VbtHeader;
+  VBT_BIOS_DATA_HEADER                      VbtBdbHeader;
+  BLOCK254_BMP_Structure                    Block254BMPStructure;
+  VBT_GENERAL1_INFO                         VbtGen1Info;
+  PRD_BOOT_TABLE                            PrdBootTable;
+  VBT_GENERAL2_INFO                         VbtGen2Info;
+  BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST      Block03OriginalDisplayToggleList;
+  BLOCK252_SBIOS_Hook                       Block252SbiosHook;
+  BLOCK06_MMIO_REG_TABLE                    Block06MmioRegTable;
+  BLOCK07_IOSWFLAG_REG_TABLE                Block07IoswflagRegTable;
+  BLOCK08_MMIOSWFLAG_REG_TABLE              Block08MmioswflagRegTable;
+  BLOCK09_PSR_FEATURE                       Block09PsrFeature;
+  BLOCK10_MODE_REMOVAL_TABLE                Block10ModeRemovalTable;
+  BLOCK12_DRIVER_FEATURES                   Block12DriverFeatures;
+  BLOCK13_DRIVER_PERSISTENCE                Block13DriverPersistence;
+  BLOCK17_SV_BITS                           Block17SvBits;
+  BLOCK18_DRIVER_ROTATION                   Block18DriverRotation;
+  BLOCK20_OEM_CUSTOMIZATION                 Block20OemCustomization;
+  BLOCK26_TV_OPTIONS                        Block26TVOptions;
+  BLOCK27_EDP_FEATURES                      Block27EDPFeatures;
+  BLOCK28_EDIDLESS_EFP                      Block28EdidlessEFP;
+  BLOCK31_TOGGLE_LIST                       Block31ToggleList;
+  BLOCK32_DISPLAY_CONFIGURATION_REMOVAL     Block32DisplayConfigurationRemoval;
+  BLOCK40_LVDS_FEATURES                     Block40LVDSFeatures;
+  BLOCK41_LFP_TABLE_POINTERS                Block41LfpTablePointers;
+  BLOCK42_LVDS_PANEL_INFO                   Block42LvdsPanelInfo;
+  BLOCK43_LVDS_BLC                          Block43LVDSBlc;
+  BLOCK44_ALS                               Block44Als;
+  BLOCK46_CHROMATICITY_SUPPORT              Block46ChromaticitySupport;
+  BLOCK51_FIXED_MODE_SET                    Block51FixedModeSet;
+} VBT_TABLE_DATA;
+
+#pragma pack()
+
+/**
+  This function will update the VBT checksum.
+
+  @param[in out] VbtPtr - Pointer to VBT table
+
+  @retval none
+**/
+VOID
+UpdateVbtChecksum(
+  VBT_TABLE_DATA *VbtPtr
+);
+
+/**
+  This function will update the VBT.
+
+  @param[in] VbtPtr - Pointer to VBT Table
+
+  @retval none
+**/
+VOID
+UpdateGopVbt (
+  IN  VBT_TABLE_DATA    *VbtPtr
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
new file mode 100644
index 0000000000..5bf2527963
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __TCO_WDT_HOB_H__
+#define __TCO_WDT_HOB_H__
+
+#define TCO_WDT_HOB_GUID \
+  { \
+    0x3e405418, 0xd8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x8, 0x41, 0x46, 0x8d } \
+  }
+
+#ifndef _PEI_HOB_H_
+#ifndef __HOB__H__
+#ifndef __PI_HOB_H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+  EFI_HOB_GENERIC_HEADER  Header;
+  EFI_GUID                Name;
+  //
+  // Guid specific data goes here
+  //
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+#endif
+
+typedef struct {
+  EFI_HOB_GUID_TYPE Header;
+  UINT8             TcoRebootHappened;
+} TCO_WDT_HOB;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
new file mode 100644
index 0000000000..671e3c5cde
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
@@ -0,0 +1,68 @@
+/** @file
+  GPIO definition table for WhiskeylakeURvp
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IO_EXPANDER_H_
+#define _IO_EXPANDER_H_
+
+typedef struct {
+  UINT32 IoExpanderNumber   : 1;  // IO Expander Number (0/1)
+  UINT32 GpioPinNumber      : 5;  // GPIO Pin Number (0 to 23)
+  UINT32 GpioDirection      : 1;  // GPIO Pin Direction (Input/Output)
+  UINT32 GpioLevel          : 1;  // GPIO Pin Output Level (High/Low)
+  UINT32 GpioInversion     : 1;  // GPIO Pin Inversion (Enabled/Disabled)
+  UINT32 Reserved           : 23; // Reserved
+} IO_EXPANDER_GPIO_CONFIG;
+
+//WHL PCH LP GPIO Expander Number
+#define IO_EXPANDER_0            0
+#define IO_EXPANDER_1            1
+
+//WHL PCH LP GPIO Pin Mapping
+#define IO_EXPANDER_GPIO_0        0   // P00
+#define IO_EXPANDER_GPIO_1        1   // P01
+#define IO_EXPANDER_GPIO_2        2   // P02
+#define IO_EXPANDER_GPIO_3        3   // P03
+#define IO_EXPANDER_GPIO_4        4   // P04
+#define IO_EXPANDER_GPIO_5        5   // P05
+#define IO_EXPANDER_GPIO_6        6   // P06
+#define IO_EXPANDER_GPIO_7        7   // P07
+#define IO_EXPANDER_GPIO_8        8   // P10
+#define IO_EXPANDER_GPIO_9        9   // P11
+#define IO_EXPANDER_GPIO_10       10  // P12
+#define IO_EXPANDER_GPIO_11       11  // P13
+#define IO_EXPANDER_GPIO_12       12  // P14
+#define IO_EXPANDER_GPIO_13       13  // P15
+#define IO_EXPANDER_GPIO_14       14  // P16
+#define IO_EXPANDER_GPIO_15       15  // P17
+#define IO_EXPANDER_GPIO_16       16  // P20
+#define IO_EXPANDER_GPIO_17       17  // P21
+#define IO_EXPANDER_GPIO_18       18  // P22
+#define IO_EXPANDER_GPIO_19       19  // P23
+#define IO_EXPANDER_GPIO_20       20  // P24
+#define IO_EXPANDER_GPIO_21       21  // P25
+#define IO_EXPANDER_GPIO_22       22  // P26
+#define IO_EXPANDER_GPIO_23       23  // P27
+
+//WHL PCH LP GPIO Expander GPIO Direction
+#define IO_EXPANDER_GPIO_OUTPUT   0
+#define IO_EXPANDER_GPIO_INPUT    1
+
+//WHL PCH LP GPIO Expaner GPIO Output Level
+#define IO_EXPANDER_GPO_LEVEL_LOW    0
+#define IO_EXPANDER_GPO_LEVEL_HIGH   1
+
+//WHL PCH LP GPIO Expaner GPIO Inversion Status
+#define IO_EXPANDER_GPI_INV_DISABLED  0
+#define IO_EXPANDER_GPI_INV_ENABLED   1
+#define IO_EXPANDER_GPIO_RESERVED     0x00
+
+//GPIO Table Terminator
+#define END_OF_GPIO_TABLE 0xFFFFFFFF
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
new file mode 100644
index 0000000000..5d5fba47ad
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
@@ -0,0 +1,75 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_CPU_POLICY_UPDATE_LIB_H_
+#define _DXE_CPU_POLICY_UPDATE_LIB_H_
+
+#include <PiDxe.h>
+#include <PchAccess.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CpuPolicyProtocol.h>
+
+/**
+
+  This function prints the CPU DXE phase policy.
+
+  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
+
+**/
+VOID
+CpuDxePrintPolicyProtocol (
+  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  );
+
+/**
+
+Routine Description:
+
+  This function updates Dxe Cpu Policy Protocol
+
+Arguments:
+
+  @param[in] DxeCpuPolicy                 The Cpu Policy protocol instance
+
+Returns:
+
+  @retval EFI_SUCCESS                     Initialization complete.
+  @retval 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
+UpdateDxeSiCpuPolicy (
+  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  );
+
+/**
+
+  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
new file mode 100644
index 0000000000..9b960159ba
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
@@ -0,0 +1,27 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_ME_POLICY_UPDATE_LIB_H_
+#define _DXE_ME_POLICY_UPDATE_LIB_H_
+
+/**
+  Update the ME Policy Library
+
+  @param[in] DxeMePolicy                The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   Initialization complete.
+  @retval 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
+UpdateDxeMePolicy (
+  IN OUT  ME_POLICY_PROTOCOL      *DxeMePolicy
+  );
+
+#endif // _DXE_ME_POLICY_UPDATE_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
new file mode 100644
index 0000000000..84db68e65c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_POLICY_UPDATE_LIB_H_
+#define _DXE_PCH_POLICY_UPDATE_LIB_H_
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] PchPolicy               The pointer to get PCH Policy protocol instance
+
+  @retval EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxePchPolicy (
+  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
new file mode 100644
index 0000000000..3bb941235c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
@@ -0,0 +1,30 @@
+/** @file
+  Header file for the DxePolicyBoardConfig Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_POLICY_BOARD_CONFIG_LIB_H_
+#define _DXE_POLICY_BOARD_CONFIG_LIB_H_
+
+#include <Protocol/MePolicy.h>
+#include <Protocol/SaPolicy.h>
+
+/**
+  This function performs DXE SA Policy update by board configuration.
+
+  @param[in, out] DxeSaPolicy     DXE SA Policy
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicyBoardConfig (
+  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
new file mode 100644
index 0000000000..4279c0c6f1
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_UPDATE_LIB_H_
+#define _DXE_SA_POLICY_UPDATE_LIB_H_
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] SaPolicy               The pointer to get SA Policy protocol instance
+
+  @retval EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicy (
+  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
new file mode 100644
index 0000000000..4709179ac6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
@@ -0,0 +1,29 @@
+/** @file
+  Function prototype of FspPolicyInitLib.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _FSP_POLICY_INIT_LIB_H_
+#define _FSP_POLICY_INIT_LIB_H_
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+  IN FSPM_UPD           *FspmUpdDataPtr
+  );
+
+VOID
+EFIAPI
+FspPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+#endif // _FSP_POLICY_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
new file mode 100644
index 0000000000..ba73cad63b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
@@ -0,0 +1,46 @@
+/** @file
+  Header file for check Gpio PadMode conflict.
+
+
+  Copyright (c) 2019, 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 <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 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 UINT16                    GpioTableCount
+  );
+
+#endif // _GPIO_CHECK_CONFLICT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
new file mode 100644
index 0000000000..40ea4abc3d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_EXPANDER_LIB_H_
+#define _GPIO_EXPANDER_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <PchAccess.h>
+#include <Library/PchSerialIoLib.h>
+
+/**
+  Set the Direction value for the given Expander Gpio pin.
+
+  This function is to Set the direction value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+**/
+VOID
+GpioExpSetDirection (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Direction
+  );
+/**
+  Set the input value for the given Expander Gpio pin.
+
+  This function is to get the input value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetPolarity  (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Polarity
+  );
+/**
+  Set the Output value for the given Expander Gpio pin.
+
+  This function is to Set the Output value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetOutput    (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  );
+/**
+  Returns the data from register value giving in the input.
+
+  This function is to get the data from the Expander
+  Registers by following the I2C Protocol communication
+
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+
+  @retval     UINT8      Value returned from the register
+**/
+UINT8
+GpioExpGetInput     (
+  IN UINT8 Expander,
+  IN UINT8 Pin
+  );
+
+/**
+  Configures all registers of a single IO Expander in one go.
+
+  @param[in]  Expander    Expander number (0/1)
+  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc. 0=output, 1=input
+  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0, etc. 0=normal, 1=inversion
+  @param[in]  Output      Bit-encoded output state, ignores polarity, only applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
+
+**/
+VOID
+GpioExpBulkConfig (
+  IN UINT8  Expander,
+  IN UINT32 Direction,
+  IN UINT32 Polarity,
+  IN UINT32 Output
+  );
+
+/**
+  Returns the Controller on which GPIO expander is present.
+
+  This function returns the Controller value
+
+  @param[out] Controller              Pointer to a Controller value on
+                                      which I2C expander is configured.
+
+  @retval     EFI_SUCCESS              non.
+**/
+EFI_STATUS
+GpioExpGetController (
+  OUT UINT8 *Controller
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
new file mode 100644
index 0000000000..f08c88f114
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
@@ -0,0 +1,48 @@
+/** @file
+
+  Header file for the Intel HD Audio Verb Table library.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _HDA_VERB_TABLE_LIB_H_
+#define _HDA_VERB_TABLE_LIB_H_
+
+#include <ConfigBlock/HdAudioConfig.h>
+#include <Library/BaseLib.h>
+
+enum HDAUDIO_CODEC_SELECT {
+  PchHdaCodecPlatformOnboard = 0,
+  PchHdaCodecExternalKit     = 1
+};
+
+/**
+  Add verb table function.
+  This function update the verb table number and verb table ptr of policy.
+
+  @param[in]  HdAudioConfig            HD Audio config block
+  @param[out] VerbTableEntryNum        Number of verb table entries
+  @param[out] HdaVerbTablePtr          Pointer to the verb table
+**/
+VOID
+AddPlatformVerbTables (
+  IN   UINT8              CodecType,
+  OUT  UINT8              *VerbTableEntryNum,
+  OUT  UINT32             *HdaVerbTablePtr
+  );
+
+/**
+  HDA VerbTable init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+HdaVerbTableInit(
+  IN UINT16 BoardId
+  );
+
+#endif
\ No newline at end of file
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
new file mode 100644
index 0000000000..cec045091b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _I2C_ACCESS_LIB_H_
+#define _I2C_ACCESS_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <PchAccess.h>
+#include <Library/PchSerialIoLib.h>
+
+#define WAIT_1_SECOND            1600000000 //1.6 * 10^9
+
+EFI_STATUS
+I2cWriteRead (
+  IN UINTN  MmioBase,
+  IN UINT8  SlaveAddress,
+  IN UINT8  WriteLength,
+  IN UINT8  *WriteBuffer,
+  IN UINT8  ReadLength,
+  IN UINT8  *ReadBuffer,
+  IN UINT64  TimeBudget
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
new file mode 100644
index 0000000000..d65586dbb9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PLATFORM_LIB_H_
+#define _PEI_PLATFORM_LIB_H_
+
+
+
+#define PEI_DEVICE_DISABLED 0
+#define PEI_DEVICE_ENABLED  1
+
+typedef struct {
+  UINT8   Register;
+  UINT32  Value;
+} PCH_GPIO_DEV;
+
+//
+// GPIO Initialization Data Structure
+//
+typedef struct{
+  PCH_GPIO_DEV Use_Sel;
+  PCH_GPIO_DEV Use_Sel2;
+  PCH_GPIO_DEV Use_Sel3;
+  PCH_GPIO_DEV Io_Sel;
+  PCH_GPIO_DEV Io_Sel2;
+  PCH_GPIO_DEV Io_Sel3;
+  PCH_GPIO_DEV Lvl;
+  PCH_GPIO_DEV Lvl2;
+  PCH_GPIO_DEV Lvl3;
+  PCH_GPIO_DEV Inv;
+  PCH_GPIO_DEV Blink;
+  PCH_GPIO_DEV Rst_Sel;
+  PCH_GPIO_DEV Rst_Sel2;
+} GPIO_INIT_STRUCT;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
new file mode 100644
index 0000000000..fe947482dc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
@@ -0,0 +1,141 @@
+/** @file
+  Header file for the PeiPolicyBoardConfig Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_BOARD_CONFIG_LIB_H_
+#define _PEI_POLICY_BOARD_CONFIG_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  This function performs PEI CPU Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI ME Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI PCH Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI SA Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI CPU Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI ME Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI PCH Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI SA Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI SI Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
new file mode 100644
index 0000000000..15db1f1fbc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for the PolicyInitPei Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POLICY_INIT_PEI_LIB_H_
+#define _POLICY_INIT_PEI_LIB_H_
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that depends
+                                     on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInitPreMem (
+  IN UINT8                     FirmwareConfiguration
+  );
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in] PeiServices            General purpose services available to every PEIM.
+  @param[in] FirmwareConfiguration  It uses to skip specific policy init that depends
+                                    on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInit (
+//  IN CONST EFI_PEI_SERVICES    **PeiServices,
+  IN UINT8                     FirmwareConfiguration
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
new file mode 100644
index 0000000000..f0da2db968
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Function prototype of PlatformInitLib.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_INIT_LIB_H_
+#define _PLATFORM_INIT_LIB_H_
+
+VOID
+PlatformLateInit (
+  VOID
+  );
+
+VOID
+InitSerialPort (
+  VOID
+  );
+
+#endif // _PLATFORM_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
new file mode 100644
index 0000000000..8bf7deaa0c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PCH_HSIO_PTSSTABLES_H_
+#define PCH_HSIO_PTSSTABLES_H_
+
+#include <PchAccess.h>
+
+///
+/// SATA PTSS Topology Types
+///
+typedef enum {
+  PchSataTopoUnknown = 0x00,
+  PchSataTopoIsata,
+  PchSataTopoDirectConnect,
+  PchSataTopoFlex,
+  PchSataTopoM2
+} PCH_SATA_TOPOLOGY;
+
+///
+/// PCIe PTSS Topology Types
+///
+typedef enum {
+  PchPcieTopoUnknown = 0x00,
+  PchPcieTopox1,
+  PchPcieTopox4,
+  PchPcieTopoSataE,
+  PchPcieTopoM2
+} PCH_PCIE_TOPOLOGY;
+
+///
+/// The PCH_SBI_PTSS_HSIO_TABLE block describes HSIO PTSS settings for PCH.
+///
+typedef struct {
+  UINT8       LaneNum;
+  UINT8       PhyMode;
+  UINT16      Offset;
+  UINT32      Value;
+  UINT32      BitMask;
+} PCH_SBI_PTSS_HSIO_TABLE;
+
+typedef struct {
+  PCH_SBI_PTSS_HSIO_TABLE   PtssTable;
+  UINT16                    Topology;
+} HSIO_PTSS_TABLES;
+
+#endif // PCH_HSIO_PTSSTABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
new file mode 100644
index 0000000000..395d08779c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
@@ -0,0 +1,106 @@
+/** @file
+  PCIe Device Override Table
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCIE_DEVICE_OVERRIDE_TABLE_H_
+#define _PCIE_DEVICE_OVERRIDE_TABLE_H_
+
+#include <ConfigBlock/PcieRpconfig.h>
+#include <IndustryStandard/Pci22.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 },
+
+  //
+  // End of Table
+  //
+  { 0 }
+};
+
+#endif
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
new file mode 100644
index 0000000000..ea96227e3d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
@@ -0,0 +1,33 @@
+/** @file
+  This header file provides platform specific definitions used
+  by other modules for platform specific initialization.
+  This is not suitable for consumption by ASL or VRF files.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//#include "CommonDefinitions.h"
+#include "PchAccess.h"
+#include "SaAccess.h"
+
+//
+// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
+//
+#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)   // 80MB + 256MB
+#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (10 * 0x800000 + 0x10000000)   // 80MB + 256MB
+
+#define FLASH_BLOCK_SIZE  0x10000
+
+#define CPU_EXTERNAL_CLOCK_FREQ  0x64
+#define CPU_FREQUENCY_MODE_100  0x64
+#define FREQUENCY_RESOLUTION_3182  0xc6e
+#define NDIVIDER_BASE_VALUE  0x19d
+#define MDIVIDER_VALUE_13  0xd
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
new file mode 100644
index 0000000000..3545b2a05c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
@@ -0,0 +1,29 @@
+/** @file
+Defines Platform BoardIds
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_BOARD_ID_H_
+#define _PLATFORM_BOARD_ID_H_
+
+#define FlavorUnknown                       0x0
+#define FlavorMobile                        0x1
+#define FlavorDesktop                       0x2
+#define FlavorWorkstation                   0x3
+#define FlavorUpServer                      0x4
+#define FlavorEmbedded                      0x5
+#define FlavorPlatformMax                   0x6
+
+#define TypeUnknown                         0x0
+#define TypeTrad                            0x1
+#define TypeUltUlx                          0x2
+
+#define BoardIdWhiskeyLakeRvp               0x60
+
+#define BoardIdUnknown1                     0xffff
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
new file mode 100644
index 0000000000..b64cfff9a2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
@@ -0,0 +1,47 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GLOBAL_NVS_AREA_H_
+#define _GLOBAL_NVS_AREA_H_
+
+//
+// Includes
+//
+#define GLOBAL_NVS_DEVICE_ENABLE 1
+#define GLOBAL_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+//
+// Global NVS Area Protocol GUID
+//
+#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
+{ 0x74e1e48, 0x8132, 0x47a1, 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc }
+
+#define GLOBAL_NVS_AREA_REVISION       16
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
+
+//
+// Global NVS Area definition
+//
+#include <Acpi/GlobalNvsAreaDef.h>
+
+//
+// Global NVS Area Protocol
+//
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
+  EFI_GLOBAL_NVS_AREA     *Area;
+} EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
new file mode 100644
index 0000000000..6dd6795a52
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
@@ -0,0 +1,144 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SETUP__H__
+#define __SETUP__H__
+
+#ifndef MDEPKG_NDEBUG
+#define DEBUG_INTERFACE_FORM_ENABLE
+#endif // MDEPKG_NDEBUG
+//
+// Form class guid for the forms those will be showed on first front page.
+//
+#define FRONT_PAGE_GUID        { 0xe58809f8, 0xfbc1, 0x48e2, { 0x88, 0x3a, 0xa3, 0xf, 0xdc, 0x4b, 0x44, 0x1e } }
+//
+// Form class guid for the forms those will be showed on boot maintenance manager menu.
+//
+#define BOOT_MAINTENANCE_GUID  { 0xb2dedc91, 0xd59f, 0x48d2, { 0x89, 0x8a, 0x12, 0x49, 0xc, 0x74, 0xa4, 0xe0 } }
+
+// VFR common Definitions
+#define INVENTORY(Name,Value) \
+    text \
+      help  = STRING_TOKEN(STR_EMPTY), \
+      text  = Name, \
+      text  = Value, \
+      flags = 0, \
+      key   = 0;
+
+#define SUBTITLE(Text) subtitle text = Text;
+#define SEPARATOR SUBTITLE(STRING_TOKEN(STR_EMPTY))
+
+#define INTERACTIVE_TEXT(HelpToken, CaptionToken, ValueToken, Key)\
+  grayoutif TRUE;\
+    oneof varid        = SETUP_DATA.InteractiveText,\
+      questionid       = Key,\
+      prompt           = CaptionToken,\
+      help             = HelpToken,\
+      option text      = ValueToken, value = 0, flags = INTERACTIVE | DEFAULT;\
+      refresh interval = 1 \
+    endoneof;\
+  endif;
+
+#define SUPPRESS_GRAYOUT_ENDIF endif; endif;
+#define DEFAULT_FLAG
+
+#define SYSTEM_ACCESS_KEY_ID            0xF000
+//
+// System Access defintions.
+//
+#define SYSTEM_ACCESS_GUID \
+ { 0xE770BB69, 0xBCB4, 0x4D04, { 0x9E, 0x97, 0x23, 0xFF, 0x94, 0x56, 0xFE, 0xAC }}
+
+#define SYSTEM_PASSWORD_ADMIN 0
+#define SYSTEM_PASSWORD_USER  1
+#define ADMIN_PW_CLEAR        0
+#define ADMIN_PW_SET          1
+
+
+typedef struct _SYSTEM_ACCESS
+{
+  //
+  // Passwords
+  //
+  UINT8       Access;
+} SYSTEM_ACCESS;
+
+//
+// Record the password status.
+//
+typedef struct {
+  UINT8   AdminName;
+  UINT8   UserName;
+} EFI_PASSWORD_STATUS;
+
+//
+// Config Data
+//
+typedef struct {
+  UINT8 SerialDebug;
+  UINT8 SerialDebugBaudRate;
+  UINT8 RamDebugInterface;
+  UINT8 UartDebugInterface;
+  UINT8 Usb3DebugInterface;
+  UINT8 SerialIoDebugInterface;
+  UINT8 TraceHubDebugInterface;
+} DEBUG_CONFIG_DATA;
+
+//
+// Config Data Hob
+//
+#define DEBUG_CONFIG_DATA_HOB DEBUG_CONFIG_DATA
+
+//
+// Secure Boot Data
+//
+typedef struct{
+  UINT8   SecureBoot;
+} SECURE_BOOT_VARIABLE;
+
+#pragma pack()
+
+//
+// Varstore statement
+// Setup is EfiVarStore that is related to EFI variable with attribute 0x07
+// (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
+//
+#define SETUP_DATA_VARSTORE\
+    efivarstore SETUP_DATA, varid = 1,\
+        attribute = 0x7, name = Setup, guid = SETUP_GUID;
+#define SA_SETUP_VARSTORE\
+    efivarstore SA_SETUP, varid = 2,\
+        attribute = 0x7, name = SaSetup, guid = SA_SETUP_GUID;
+#define CPU_SETUP_VARSTORE\
+    efivarstore CPU_SETUP, varid = 3,\
+        attribute = 0x7, name = CpuSetup, guid = CPU_SETUP_GUID;
+#define ME_SETUP_VARSTORE\
+    efivarstore ME_SETUP, varid = 4,\
+        attribute = 0x7, name = MeSetup, guid = ME_SETUP_GUID;
+#define PCH_SETUP_VARSTORE\
+    efivarstore PCH_SETUP, varid = 5,\
+        attribute = 0x7, name = PchSetup, guid = PCH_SETUP_GUID;
+#define SI_SETUP_VARSTORE\
+    efivarstore SI_SETUP, varid = 6,\
+        attribute = 0x7, name = SiSetup, guid = SI_SETUP_GUID;
+#ifdef DEBUG_INTERFACE_FORM_ENABLE
+#define DEBUG_CONFIG_DATA_ID            0xF001
+#define DEBUG_CONFIG_DATA_VARSTORE\
+    efivarstore DEBUG_CONFIG_DATA, varid = DEBUG_CONFIG_DATA_ID,\
+        attribute = 0x7, name = DebugConfigData, guid = DEBUG_CONFIG_GUID;
+#endif // DEBUG_INTERFACE_FORM_ENABLE
+#define SYSTEM_ACCESS_VARSTORE\
+    varstore SYSTEM_ACCESS, varid = SYSTEM_ACCESS_KEY_ID,\
+        name = SystemAccess, guid = SYSTEM_ACCESS_GUID;
+#define SYSTEM_PASSWORD_VARSTORE\
+    varstore EFI_PASSWORD_STATUS,\
+        name = PasswordStatus, guid = SYSTEM_ACCESS_GUID;
+
+#define BOOT_FLOW_CONDITION_RECOVERY   2
+#define BOOT_FLOW_CONDITION_FIRST_BOOT 4
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
new file mode 100644
index 0000000000..4ce85de5bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
@@ -0,0 +1,157 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_REG_H_
+#define _SIO_REG_H_
+
+#define REG_LOGICAL_DEVICE        0x07
+#define ACTIVATE                  0x30
+
+#define BASE_ADDRESS_HIGH0        0x60
+#define BASE_ADDRESS_LOW0         0x61
+#define BASE_ADDRESS_HIGH1        0x62
+#define BASE_ADDRESS_LOW1         0x63
+#define BASE_ADDRESS_HIGH2        0x64
+#define BASE_ADDRESS_LOW2         0x65
+#define BASE_ADDRESS_HIGH3        0x66
+#define BASE_ADDRESS_LOW3         0x67
+#define PRIMARY_INTERRUPT_SELECT  0x70
+#define WAKEUP_ON_IRQ_EN          0x70
+#define INTERRUPT_TYPE            0x71
+#define DMA_CHANNEL_SELECT0       0x74
+#define DMA_CHANNEL_SELECT1       0x75
+
+
+
+//
+//Port address for PILOT - III
+//
+#define PILOTIII_CHIP_ID         0x03
+#define PILOTIII_SIO_INDEX_PORT  0x04E
+#define PILOTIII_SIO_DATA_PORT   (PILOTIII_SIO_INDEX_PORT+1)
+
+#define PILOTIII_UNLOCK      0x5A
+#define PILOTIII_LOCK        0xA5
+
+//
+// logical device in PILOT-III
+//
+#define PILOTIII_SIO_PSR     0x00
+#define PILOTIII_SIO_COM2    0x01
+#define PILOTIII_SIO_COM1    0x02
+#define PILOTIII_SIO_SWCP    0x03
+#define PILOTIII_SIO_GPIO    0x04
+#define PILOTIII_SIO_WDT     0x05
+#define PILOTIII_SIO_KCS3    0x08
+#define PILOTIII_SIO_KCS4    0x09
+#define PILOTIII_SIO_KCS5    0x0A
+#define PILOTIII_SIO_BT      0x0B
+#define PILOTIII_SIO_SMIC    0x0C
+#define PILOTIII_SIO_MAILBOX 0x0D
+#define PILOTIII_SIO_RTC     0x0E
+#define PILOTIII_SIO_SPI     0x0F
+#define PILOTIII_SIO_TAP     0x10
+//
+// Regisgers for Pilot-III
+//
+#define PILOTIII_CHIP_ID_REG               0x20
+#define PILOTIII_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
+#define PILOTIII_ACTIVATE                  ACTIVATE
+#define PILOTIII_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
+#define PILOTIII_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
+#define PILOTIII_BASE_ADDRESS_HIGH1        BASE_ADDRESS_HIGH1
+#define PILOTIII_BASE_ADDRESS_LOW1         BASE_ADDRESS_LOW1
+#define PILOTIII_PRIMARY_INTERRUPT_SELECT  PRIMARY_INTERRUPT_SELECT
+
+//
+// Port address for PC8374
+//
+#define PC8374_SIO_INDEX_PORT  0x02E
+#define PC8374_SIO_DATA_PORT   (PC8374_SIO_INDEX_PORT+1)
+
+//
+// Logical device in PC8374
+//
+#define PC8374_SIO_FLOPPY  0x00
+#define PC8374_SIO_PARA    0x01
+#define PC8374_SIO_COM2    0x02
+#define PC8374_SIO_COM1    0x03
+#define PC8374_SIO_MOUSE   0x05
+#define PC8374_SIO_KYBD    0x06
+#define PC8374_SIO_GPIO    0x07
+
+//
+// Registers specific for PC8374
+//
+#define PC8374_CLOCK_SELECT  0x2D
+#define PC8374_CLOCK_CONFIG  0x29
+
+//
+// Registers for PC8374
+//
+#define PC8374_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
+#define PC8374_ACTIVATE                  ACTIVATE
+#define PC8374_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
+#define PC8374_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
+#define PC8374_PRIMARY_INTERRUPT_SELECT  PRIMARY_INTERRUPT_SELECT
+#define PC8374_DMA_CHANNEL_SELECT        DMA_CHANNEL_SELECT0
+
+#define PC87427_SERVERIO_CNF2           0x22
+
+
+//
+// Pilot III Mailbox Data Register definitions
+//
+#define MBDAT00_OFFSET                  0x00
+#define MBDAT01_OFFSET                  0x01
+#define MBDAT02_OFFSET                  0x02
+#define MBDAT03_OFFSET                  0x03
+#define MBDAT04_OFFSET                  0x04
+#define MBDAT05_OFFSET                  0x05
+#define MBDAT06_OFFSET                  0x06
+#define MBDAT07_OFFSET                  0x07
+#define MBDAT08_OFFSET                  0x08
+#define MBDAT09_OFFSET                  0x09
+#define MBDAT10_OFFSET                  0x0A
+#define MBDAT11_OFFSET                  0x0B
+#define MBDAT12_OFFSET                  0x0C
+#define MBDAT13_OFFSET                  0x0D
+#define MBDAT14_OFFSET                  0x0E
+#define MBDAT15_OFFSET                  0x0F
+#define MBST0_OFFSET                    0x10
+#define MBST1_OFFSET                    0x11
+#define MBBINT_OFFSET                   0x12
+
+//
+// Mailbox Bit definitions...
+//
+#define   MBBINT_MBBIST_BIT               0x80
+// If both are there, use the default one
+//
+#define  W83527_EXIST     BIT2
+#define  PC8374_EXIST     BIT1
+#define  PILOTIII_EXIST   BIT0
+#define  DEFAULT_SIO      PILOTIII_EXIST
+#define  DEFAULT_KDB      PC8374_EXIST
+
+#define IPMI_DEFAULT_SMM_IO_BASE           0xca2
+//
+// For Pilot III
+//
+
+#define PILOTIII_SWC_BASE_ADDRESS          0xA00
+#define PILOTIII_PM1b_EVT_BLK_BASE_ADDRESS 0x0A80
+#define PILOTIII_PM1b_CNT_BLK_BASE_ADDRESS 0x0A84
+#define PILOTIII_GPE1_BLK_BASE_ADDRESS     0x0A86
+#define PILOTIII_KCS3_DATA_BASE_ADDRESS    0x0CA4
+#define PILOTIII_KCS3_CMD_BASE_ADDRESS     0x0CA5
+#define PILOTIII_KCS4_DATA_BASE_ADDRESS    0x0CA2
+#define PILOTIII_KCS4_CMD_BASE_ADDRESS     0x0CA3
+#define PILOTIII_MAILBOX_BASE_ADDRESS      0x0600
+#define PILOTIII_MAILBOX_MASK              0xFFE0
+#define BMC_KCS_BASE_ADDRESS               0x0CA0
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
new file mode 100644
index 0000000000..af753e1dce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
@@ -0,0 +1,112 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  // Define a Global region of ACPI NVS Region that may be used for any
+  // type of implementation.  The starting offset and size will be fixed
+  // up by the System BIOS during POST.  Note that the Size must be a word
+  // in size to be fixed up correctly.
+
+  OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55)
+  Field(GNVS,AnyAcc,Lock,Preserve)
+  {
+  //
+  // Miscellaneous Dynamic Registers:
+  //
+  Offset(0),      OSYS, 16, // Offset(0),     Operating System
+  Offset(2),      SMIF, 8,  // Offset(2),     SMI Function Call (ASL to SMI via I/O Trap)
+  Offset(3),      P80D, 32, // Offset(3),     Port 80 Debug Port Value
+  Offset(7),      PWRS, 8,  // Offset(7),     Power State (AC Mode = 1)
+  //
+  // Thermal Policy Registers:
+  //
+  Offset(8),      DTSE, 8,  // Offset(8),    Digital Thermal Sensor Enable
+  Offset(9),      DTSF, 8,  // Offset(9),    DTS SMI Function Call
+  //
+  // CPU Identification Registers:
+  //
+  Offset(10),     APIC, 8,  // Offset(10),    APIC Enabled by SBIOS (APIC Enabled = 1)
+  Offset(11),     TCNT, 8,  // Offset(11),    Number of Enabled Threads
+  //
+  // PCIe Hot Plug
+  //
+  Offset(12),     OSCC, 8,  // Offset(12),    PCIE OSC Control
+  Offset(13),     NEXP, 8,  // Offset(13),    Native PCIE Setup Value
+  //
+  // Global Variables
+  //
+  Offset(14),     DSEN, 8,  // Offset(14),    _DOS Display Support Flag.
+  Offset(15),     GPIC, 8,  // Offset(15),    Global IOAPIC/8259 Interrupt Mode Flag.
+  Offset(16),     L01C, 8,  // Offset(16),    Global L01 Counter.
+  Offset(17),     LTR1, 8,  // Offset(17),    Latency Tolerance Reporting Enable
+  Offset(18),     LTR2, 8,  // Offset(18),    Latency Tolerance Reporting Enable
+  Offset(19),     LTR3, 8,  // Offset(19),    Latency Tolerance Reporting Enable
+  Offset(20),     LTR4, 8,  // Offset(20),    Latency Tolerance Reporting Enable
+  Offset(21),     LTR5, 8,  // Offset(21),    Latency Tolerance Reporting Enable
+  Offset(22),     LTR6, 8,  // Offset(22),    Latency Tolerance Reporting Enable
+  Offset(23),     LTR7, 8,  // Offset(23),    Latency Tolerance Reporting Enable
+  Offset(24),     LTR8, 8,  // Offset(24),    Latency Tolerance Reporting Enable
+  Offset(25),     LTR9, 8,  // Offset(25),    Latency Tolerance Reporting Enable
+  Offset(26),     LTRA, 8,  // Offset(26),    Latency Tolerance Reporting Enable
+  Offset(27),     LTRB, 8,  // Offset(27),    Latency Tolerance Reporting Enable
+  Offset(28),     LTRC, 8,  // Offset(28),    Latency Tolerance Reporting Enable
+  Offset(29),     LTRD, 8,  // Offset(29),    Latency Tolerance Reporting Enable
+  Offset(30),     LTRE, 8,  // Offset(30),    Latency Tolerance Reporting Enable
+  Offset(31),     LTRF, 8,  // Offset(31),    Latency Tolerance Reporting Enable
+  Offset(32),     LTRG, 8,  // Offset(32),    Latency Tolerance Reporting Enable
+  Offset(33),     LTRH, 8,  // Offset(33),    Latency Tolerance Reporting Enable
+  Offset(34),     LTRI, 8,  // Offset(34),    Latency Tolerance Reporting Enable
+  Offset(35),     LTRJ, 8,  // Offset(35),    Latency Tolerance Reporting Enable
+  Offset(36),     LTRK, 8,  // Offset(36),    Latency Tolerance Reporting Enable
+  Offset(37),     LTRL, 8,  // Offset(37),    Latency Tolerance Reporting Enable
+  Offset(38),     LTRM, 8,  // Offset(38),    Latency Tolerance Reporting Enable
+  Offset(39),     LTRN, 8,  // Offset(39),    Latency Tolerance Reporting Enable
+  Offset(40),     LTRO, 8,  // Offset(40),    Latency Tolerance Reporting Enable
+  Offset(41),     OBF1, 8,  // Offset(41),    Optimized Buffer Flush and Fill
+  Offset(42),     OBF2, 8,  // Offset(42),    Optimized Buffer Flush and Fill
+  Offset(43),     OBF3, 8,  // Offset(43),    Optimized Buffer Flush and Fill
+  Offset(44),     OBF4, 8,  // Offset(44),    Optimized Buffer Flush and Fill
+  Offset(45),     OBF5, 8,  // Offset(45),    Optimized Buffer Flush and Fill
+  Offset(46),     OBF6, 8,  // Offset(46),    Optimized Buffer Flush and Fill
+  Offset(47),     OBF7, 8,  // Offset(47),    Optimized Buffer Flush and Fill
+  Offset(48),     OBF8, 8,  // Offset(48),    Optimized Buffer Flush and Fill
+  Offset(49),     OBF9, 8,  // Offset(49),    Optimized Buffer Flush and Fill
+  Offset(50),     OBFA, 8,  // Offset(50),    Optimized Buffer Flush and Fill
+  Offset(51),     OBFB, 8,  // Offset(51),    Optimized Buffer Flush and Fill
+  Offset(52),     OBFC, 8,  // Offset(52),    Optimized Buffer Flush and Fill
+  Offset(53),     OBFD, 8,  // Offset(53),    Optimized Buffer Flush and Fill
+  Offset(54),     OBFE, 8,  // Offset(54),    Optimized Buffer Flush and Fill
+  Offset(55),     OBFF, 8,  // Offset(55),    Optimized Buffer Flush and Fill
+  Offset(56),     OBFG, 8,  // Offset(56),    Optimized Buffer Flush and Fill
+  Offset(57),     OBFH, 8,  // Offset(57),    Optimized Buffer Flush and Fill
+  Offset(58),     OBFI, 8,  // Offset(58),    Optimized Buffer Flush and Fill
+  Offset(59),     OBFJ, 8,  // Offset(59),    Optimized Buffer Flush and Fill
+  Offset(60),     OBFK, 8,  // Offset(60),    Optimized Buffer Flush and Fill
+  Offset(61),     OBFL, 8,  // Offset(61),    Optimized Buffer Flush and Fill
+  Offset(62),     OBFM, 8,  // Offset(62),    Optimized Buffer Flush and Fill
+  Offset(63),     OBFN, 8,  // Offset(63),    Optimized Buffer Flush and Fill
+  Offset(64),     OBFO, 8,  // Offset(64),    Optimized Buffer Flush and Fill
+  Offset(65),     RTD3, 8,  // Offset(65),    Runtime D3 support.
+  Offset(66),     S0ID, 8,  // Offset(66),    Low Power S0 Idle Enable
+  Offset(67),     GBSX, 8,  // Offset(67),    Virtual GPIO button Notify Sleep State Change
+  Offset(68),     PSCP, 8,  // Offset(68),    P-state Capping
+  Offset(69),     P2ME, 8,  // Offset(69),    Ps2 Mouse Enable
+  Offset(70),     P2MK, 8,  // Offset(70),    Ps2 Keyboard and Mouse Enable
+  //
+  // Driver Mode
+  //
+  Offset(71),     GIRQ, 32, // Offset(71),    GPIO IRQ
+  Offset(75),     PLCS, 8,  // Offset(75),    set PL1 limit when entering CS
+  Offset(76),     PLVL, 16, // Offset(76),    PL1 limit value
+  Offset(78),     PB1E, 8,  // Offset(78),    10sec Power button support
+  Offset(79),     ECR1, 8,  // Offset(79),    Pci Delay Optimization Ecr
+  Offset(80),     TBTS, 8,  // Offset(80),    Thunderbolt(TM) support
+  Offset(81),     TNAT, 8,  // Offset(81),    TbtNativeOsHotPlug
+  Offset(82),     TBSE, 8,  // Offset(82),    Thunderbolt(TM) Root port selector
+  Offset(83),     TBS1, 8,  // Offset(83),    Thunderbolt(TM) Root port selector
+  }
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers

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

Header files for the WhiskeylakeURvp board instance.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h  | 131 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h      |  40 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h | 105 ++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h        |  44 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h   |  12 ++
 5 files changed, 332 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h
new file mode 100644
index 0000000000..bd849b9ee2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pei
+++ PlatformHookLib.h
@@ -0,0 +1,131 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PEI_PLATFORM_HOOK_LIB_H_
+#define _PEI_PLATFORM_HOOK_LIB_H_
+
+#include <PlatformInfo.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/GpioLib.h>
+
+
+//EC Command to provide one byte of debug indication #define 
+BSSB_DEBUG_INDICATION 0xAE
+/**
+  Configure EC for specific devices
+
+  @param[in] PchLan       - The PchLan of PCH_SETUP variable.
+  @param[in] BootMode     - The current boot mode.
+**/
+VOID
+EcInit (
+  IN UINT8                PchLan,
+  IN EFI_BOOT_MODE        BootMode
+  );
+
+/**
+  Checks if Premium PMIC present
+
+  @retval  TRUE  if present
+  @retval  FALSE it discrete/other PMIC **/ BOOLEAN 
+IsPremiumPmicPresent (
+  VOID
+  );
+
+/**
+  Pmic Programming to supprort LPAL Feature
+
+  @retval     NONE
+**/
+VOID
+PremiumPmicDisableSlpS0Voltage (
+  VOID
+  );
+
+/**
+Pmic Programming to supprort LPAL Feature
+  @retval     NONE
+**/
+VOID
+PremiumPmicEnableSlpS0Voltage(
+  VOID
+  );
+
+/**
+  Do platform specific programming pre-memory. For example, EC init, 
+Chipset programming
+
+  @retval  Status
+**/
+EFI_STATUS
+PlatformSpecificInitPreMem (
+  VOID
+  );
+
+/**
+  Do platform specific programming post-memory.
+
+  @retval  Status
+**/
+EFI_STATUS
+PlatformSpecificInit (
+  VOID
+  );
+
+/**
+  Configure GPIO and SIO Before Memory is ready.
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInitPreMem (
+  VOID
+  );
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInit (
+  VOID
+  );
+
+/**
+Voltage Margining Routine
+
+@retval  EFI_SUCCESS   Operation success
+**/
+EFI_STATUS
+VoltageMarginingRoutine(
+  VOID
+  );
+
+/**
+  Detect recovery mode
+
+  @retval  EFI_SUCCESS       System in Recovery Mode
+  @retval  EFI_UNSUPPORTED   System doesn't support Recovery Mode
+  @retval  EFI_NOT_FOUND     System is not in Recovery Mode
+**/
+EFI_STATUS
+IsRecoveryMode (
+  VOID
+  );
+
+/**
+  Early board Configuration before Memory is ready.
+
+  @retval  EFI_SUCCESS  Operation success.
+**/
+EFI_STATUS
+BoardInitEarlyPreMem (
+  VOID
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h
new file mode 100644
index 0000000000..d65586dbb9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pei
+++ PlatformLib.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PEI_PLATFORM_LIB_H_
+#define _PEI_PLATFORM_LIB_H_
+
+
+
+#define PEI_DEVICE_DISABLED 0
+#define PEI_DEVICE_ENABLED  1
+
+typedef struct {
+  UINT8   Register;
+  UINT32  Value;
+} PCH_GPIO_DEV;
+
+//
+// GPIO Initialization Data Structure
+//
+typedef struct{
+  PCH_GPIO_DEV Use_Sel;
+  PCH_GPIO_DEV Use_Sel2;
+  PCH_GPIO_DEV Use_Sel3;
+  PCH_GPIO_DEV Io_Sel;
+  PCH_GPIO_DEV Io_Sel2;
+  PCH_GPIO_DEV Io_Sel3;
+  PCH_GPIO_DEV Lvl;
+  PCH_GPIO_DEV Lvl2;
+  PCH_GPIO_DEV Lvl3;
+  PCH_GPIO_DEV Inv;
+  PCH_GPIO_DEV Blink;
+  PCH_GPIO_DEV Rst_Sel;
+  PCH_GPIO_DEV Rst_Sel2;
+} GPIO_INIT_STRUCT;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h
new file mode 100644
index 0000000000..44b4059f8e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pla
+++ tformBoardConfig.h
@@ -0,0 +1,105 @@
+/** @file
+  Header file for Platform Boards Configurations.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PLATFORM_BOARD_CONFIG_H
+#define _PLATFORM_BOARD_CONFIG_H
+
+#include <ConfigBlock.h>
+#include <PchPolicyCommon.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <GpioConfig.h>
+#include <TbtBoardInfo.h>
+
+#define IS_ALIGNED(addr, size) (((addr) & (size - 1)) ? 0 : 1)
+#define ALIGN16(size)          (IS_ALIGNED(size, 16) ? size : ((size + 16) & 0xFFF0))
+
+#define BOARD_CONFIG_BLOCK_PEI_PREMEM_VERSION  0x00000001 #define 
+BOARD_CONFIG_BLOCK_PEI_POSTMEM_VERSION 0x00000001 #define 
+BOARD_CONFIG_BLOCK_DXE_VERSION 0x00000001 #define 
+BOARD_NO_BATTERY_SUPPORT 0 #define BOARD_REAL_BATTERY_SUPPORTED BIT0 
+#define BOARD_VIRTUAL_BATTERY_SUPPORTED BIT1
+
+#pragma pack(1)
+
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+} BOARD_CONFIG_BLOCK;
+
+typedef struct {
+  UINT8 GpioSupport;
+  UINT32 WakeGpioNo;
+  UINT8 HoldRstExpanderNo;
+  UINT32 HoldRstGpioNo;
+  BOOLEAN HoldRstActive;
+  UINT8 PwrEnableExpanderNo;
+  UINT32 PwrEnableGpioNo;
+  BOOLEAN PwrEnableActive;
+} SWITCH_GRAPHIC_GPIO;
+
+typedef struct {
+  UINT8 ClkReqNumber : 4;
+  UINT8 ClkReqSupported : 1;
+  UINT8 DeviceResetPadActiveHigh : 1;
+  UINT32 DeviceResetPad;
+} ROOT_PORT_CLK_INFO;
+
+typedef struct {
+  UINT8 Section;
+  UINT8 Pin;
+} EXPANDER_GPIO_CONFIG;
+
+typedef enum {
+  BoardGpioTypePch,
+  BoardGpioTypeExpander,
+  BoardGpioTypeNotSupported = 0xFF
+} BOARD_GPIO_TYPE;
+
+typedef struct {
+  UINT8 Type;
+  UINT8 Reserved[3];  // alignment for COMMON_GPIO_CONFIG
+  union {
+    UINT32 Pin;
+    EXPANDER_GPIO_CONFIG Expander;
+  } u;
+} BOARD_GPIO_CONFIG;
+
+// Do not change the encoding. It must correspond with PCH_PCIE_CLOCK_USAGE from PCH RC.
+#define NOT_USED     0xFF
+#define FREE_RUNNING 0x80
+#define LAN_CLOCK    0x70
+#define PCIE_PEG     0x40
+#define PCIE_PCH     0x00
+
+typedef struct {
+  UINT32 ClockUsage;
+  UINT32 ClkReqSupported;
+} PCIE_CLOCK_CONFIG;
+
+typedef union {
+  UINT64 Blob;
+  BOARD_GPIO_CONFIG  BoardGpioConfig;
+  ROOT_PORT_CLK_INFO Info;
+  PCIE_CLOCK_CONFIG  PcieClock;
+} PCD64_BLOB;
+
+typedef union {
+  UINT32        Blob;
+  USB20_AFE     Info;
+} PCD32_BLOB;
+
+#ifndef IO_EXPANDER_DISABLED
+#define IO_EXPANDER_DISABLED      0xFF
+#endif
+
+#define SPD_DATA_SIZE 512
+
+#pragma pack()
+
+#endif // _PLATFORM_BOARD_CONFIG_H
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h
new file mode 100644
index 0000000000..0e0b6c4f6c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pla
+++ tformInfo.h
@@ -0,0 +1,44 @@
+/** @file
+  GUID used for Platform Info Data entries in the HOB list.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PLATFORM_INFO_H_
+#define _PLATFORM_INFO_H_
+
+#pragma pack(1)
+
+///
+/// PCH_GPIO_PAD is equivalent to GPIO_PAD which is defined in 
+GpioConfig.h /// typedef UINT32 PCH_GPIO_PAD; //Copied from 
+GpioConfig.h (need to change it based on include)
+
+typedef struct {
+UINT8    Expander;
+UINT8    Pin;
+UINT16   Reserved; // Reserved for future use
+} IO_EXPANDER_PAD;
+
+typedef union {
+PCH_GPIO_PAD       PchGpio;
+IO_EXPANDER_PAD    IoExpGpio;
+} GPIO_PAD_CONFIG;
+
+typedef struct {
+UINT8                GpioType;    // 0: Disabled (no GPIO support), 1: PCH, 2: I/O Expander
+UINT8                Reserved[3]; // Reserved for future use
+GPIO_PAD_CONFIG      GpioData;
+} PACKED_GPIO_CONFIG;
+
+typedef union {
+PACKED_GPIO_CONFIG    PackedGpio;
+UINT64                Data64;
+} COMMON_GPIO_CONFIG;
+
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h
new file mode 100644
index 0000000000..7d44acccc1
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Whi
+++ skeylakeURvpId.h
@@ -0,0 +1,12 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _WHISKEYLAKE_ERB_ID_H_
+#define _WHISKEYLAKE_ERB_ID_H_
+
+#define BoardIdWhiskeyLakeRvp          0x60
+#endif // _WHISKEYLAKE_RVP3_ID_H_
+
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances

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

Common package library instances.

* BaseAcpiTimerLib - Support for ACPI timer services.
* BaseGpioExpanderLib - Support for the TCA6424 IO expander.
* DxePolicyUpdateLib - Policy update in DXE.
* DxeTbtPolicyLib - DXE Thunderbolt policy initialization.
* PeiDTbtInitLib - PEI discrete Thunderbolt initialization services.
* PeiFspPolicyInitLib - PEI Intel FSP policy initialization.
* PeiI2cAccessLib - Provides I2C read and write services.
* PeiPolicyInitLib - Policy initialization in PEI.
* PeiPolicyUpdateLib - Policy update in PEI.
* PeiSiliconPolicyUpdateLibFsp - PEI FSP silicon policy initialization.
* PeiTbtPolicyLib - PEI Thunderbolt policy initialization.
* SecFspWrapperPlatformSecLib - FSP wrapper PlatformSecLib instance.
* TbtCommonLib - Common Thunderbolt services.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf                         |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf                      |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf                         |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf                   |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf                   |  161 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf |  139 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf   |   97 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf                                        |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf                              |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf                                |   67 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf                                      |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf                         |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf                             |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf                         |  272 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h                       |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h                       |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h                     |  234 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h            |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h             |   28 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h              |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h                     |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h                        |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h                                    | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h                            |   91 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h                            |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h                               |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h                                |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h                                  |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h                                |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h                                |   22 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h                           |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h                            |   14 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h                           |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h                            |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h                            |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c                           |  148 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c                        |  316 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c                           |  206 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c                     |  567 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c                  |  461 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c                   |  121 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c                    |   77 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c                  |  736 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c                     |  223 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c                   |  848 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c             |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c                   |   95 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c         |  100 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c          |  124 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c             |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c       |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c              |   85 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c        |   87 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c        |  163 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c                    |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c               |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c          |   79 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c                  |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c                  |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c                                          |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c                                |  310 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c                                  |  132 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c                                        |  115 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c                           |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c                            |  105 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c                           |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c                            |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c                                  |   65 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c                            |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c                                |  114 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c                           |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c                     |  108 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c                            |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c                      |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c                           |  523 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c                     |  113 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c                            |  242 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c                      |  221 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c                            |  168 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm            |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm                |  361 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm                   |   72 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni                                        |   15 +
 83 files changed, 13144 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
new file mode 100644
index 0000000000..0d2a6cceeb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for Tbt functionality
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeTbtPolicyLib
+FILE_GUID = 28ABF346-4E52-4BD3-b1FF-63BA7563C9D4
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+HobLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+[Sources]
+DxeTbtPolicyLib.c
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gTbtInfoHobGuid
+
+[Protocols]
+gDxeTbtPolicyProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
new file mode 100644
index 0000000000..f2330b5b71
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
@@ -0,0 +1,60 @@
+## @file
+# Component information file for Tbt common library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtCommonLib
+  FILE_GUID                      = 5F03614E-CB56-40B1-9989-A09E25BBA294
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = TbtCommonLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+  DebugLib
+  PchPcieRpLib
+  PciSegmentLib
+  TimerLib
+  BaseLib
+  GpioLib
+  GpioExpanderLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode           ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport       ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI              ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify           ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq           ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm                ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch          ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt                ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq          ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax  ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd       ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber
+
+[Sources]
+  TbtCommonLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
new file mode 100644
index 0000000000..b74e641e16
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for Tbt policy
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiTbtPolicyLib
+FILE_GUID = 4A95FDBB-2535-49eb-9A79-D56D24257106
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+DebugLib
+PostCodeLib
+HobLib
+GpioLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad    ## CONSUMES
+
+[Sources]
+PeiTbtPolicyLib.c
+
+[Guids]
+gTbtInfoHobGuid
+
+[Ppis]
+gEfiPeiReadOnlyVariable2PpiGuid
+gPeiTbtPolicyPpiGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
new file mode 100644
index 0000000000..8e0dbe73ce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for PEI DTBT Init library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiDTbtInitLib
+  FILE_GUID                      = 06768A8D-8152-403f-83C1-59584FD2B438
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiDTbtInitLib
+
+[LibraryClasses]
+  PeiServicesLib
+  DebugLib
+  PcdLib
+  TbtCommonLib
+  PciSegmentLib
+  PeiTbtPolicyLib
+  PchPmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Ppis]
+  gPeiTbtPolicyPpiGuid                          ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  #gClientCommonModuleTokenSpaceGuid.PcdTbtSupport    ## PRODUCES
+
+[Sources]
+  PeiDTbtInitLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
new file mode 100644
index 0000000000..bd39cd60b7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
@@ -0,0 +1,161 @@
+## @file
+# Library functions for Fsp Policy Initialization Library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiFspPolicyInitLib
+  FILE_GUID                      = 2CB87D67-D1A4-4CD3-8CD7-91A1FA1DF6E0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyInitLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  PeiFspPolicyInitLib.c
+  PeiFspSiPolicyInitLib.c
+  PeiFspPchPolicyInitLib.c
+  PeiFspCpuPolicyInitLib.c
+  PeiFspMePolicyInitLib.c
+  PeiFspSaPolicyInitLib.c
+  PeiFspSecurityPolicyInitLib.c
+  PeiFspMiscUpdInitLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  CoffeeLakeFspBinPkg/CoffeeLakeFspBinPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  PeiServicesLib
+  SmbusLib
+  ConfigBlockLib
+  PcdLib
+  MemoryAllocationLib
+  PchInfoLib
+  SpiLib
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdTsegSize
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize          ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize           ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize         ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode                   ## CONSUMES
+
+[Ppis]
+  gSiPolicyPpiGuid                        ## CONSUMES
+  gSiPreMemPolicyPpiGuid                  ## CONSUMES
+  gEfiSecPlatformInformation2PpiGuid      ## CONSUMES
+  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
+
+[Guids]
+  gPchTraceHubPreMemConfigGuid            ## CONSUMES
+  gSmbusPreMemConfigGuid                  ## CONSUMES
+  gDciPreMemConfigGuid                    ## CONSUMES
+  gPcieRpPreMemConfigGuid                 ## CONSUMES
+  gHdAudioPreMemConfigGuid                ## CONSUMES
+  gIshPreMemConfigGuid                    ## CONSUMES
+  gHsioPciePreMemConfigGuid               ## CONSUMES
+  gHsioSataPreMemConfigGuid               ## CONSUMES
+  gLpcPreMemConfigGuid                    ## CONSUMES
+  gPchGeneralPreMemConfigGuid             ## CONSUMES
+  gWatchDogPreMemConfigGuid               ## CONSUMES
+  gLanConfigGuid                          ## CONSUMES
+  gPcieRpConfigGuid                       ## CONSUMES
+  gSataConfigGuid                         ## CONSUMES
+  gHdAudioConfigGuid                      ## CONSUMES
+  gScsConfigGuid                          ## CONSUMES
+  gIshConfigGuid                          ## CONSUMES
+  gSataConfigGuid                         ## CONSUMES
+  gUsbConfigGuid                          ## CONSUMES
+  gSerialIoConfigGuid                     ## CONSUMES
+  gInterruptConfigGuid                    ## CONSUMES
+  gLockDownConfigGuid                     ## CONSUMES
+  gSaMiscPeiPreMemConfigGuid              ## PRODUCES
+  gSaMiscPeiConfigGuid                    ## PRODUCES
+  gMemoryConfigGuid                       ## CONSUMES
+  gMemoryConfigNoCrcGuid                  ## CONSUMES
+  gSwitchableGraphicsConfigGuid           ## CONSUMES
+  gGraphicsPeiPreMemConfigGuid            ## CONSUMES
+  gSaPciePeiPreMemConfigGuid              ## CONSUMES
+  gSaMiscPeiConfigGuid                    ## CONSUMES
+  gSaPciePeiConfigGuid                    ## CONSUMES
+  gGraphicsPeiConfigGuid                  ## CONSUMES
+  gCpuTraceHubConfigGuid                  ## CONSUMES
+  gIpuPreMemConfigGuid                    ## CONSUMES
+  gCnviConfigGuid                         ## CONSUMES
+  gHsioConfigGuid                         ## CONSUMES
+  gEspiConfigGuid                         ## CONSUMES
+  gGnaConfigGuid                          ## CONSUMES
+  gVtdConfigGuid                          ## CONSUMES
+  gSaOverclockingPreMemConfigGuid         ## CONSUMES
+  gMePeiPreMemConfigGuid                  ## CONSUMES
+  gMePeiConfigGuid                        ## CONSUMES
+  gDmiConfigGuid                          ## CONSUMES
+  gFlashProtectionConfigGuid              ## CONSUMES
+  gIoApicConfigGuid                       ## CONSUMES
+  gPmConfigGuid                           ## CONSUMES
+  gP2sbConfigGuid                         ## CONSUMES
+  gPchGeneralConfigGuid                   ## CONSUMES
+  gSerialIrqConfigGuid                    ## CONSUMES
+  gThermalConfigGuid                      ## CONSUMES
+  gCpuSecurityPreMemConfigGuid            ## CONSUMES
+  gCpuConfigGuid                          ## CONSUMES
+  gCpuOverclockingPreMemConfigGuid        ## CONSUMES
+  gCpuConfigLibPreMemConfigGuid           ## CONSUMES
+  gCpuPowerMgmtBasicConfigGuid            ## CONSUMES
+  gCpuPowerMgmtCustomConfigGuid           ## CONSUMES
+  gCpuTestConfigGuid                      ## CONSUMES
+  gCpuPidTestConfigGuid                   ## CONSUMES
+  gCpuPowerMgmtTestConfigGuid             ## CONSUMES
+  gFspNonVolatileStorageHobGuid           ## CONSUMES
+  gSmramCpuDataHeaderGuid                 ## CONSUMES
+  gFspReservedMemoryResourceHobTsegGuid   ## CONSUMES
+  gSiConfigGuid                           ## CONSUMES
+  gDebugConfigHobGuid                     ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
new file mode 100644
index 0000000000..994cf93e33
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
@@ -0,0 +1,139 @@
+## @file
+#  Provide FSP wrapper platform related function.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SiliconPolicyUpdateLibFsp
+  FILE_GUID                      = 4E83003B-49A9-459E-AAA6-1CA3C6D04FB2
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SiliconPolicyUpdateLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  PeiFspPolicyUpdateLib.c
+  PeiPchPolicyUpdatePreMem.c
+  PeiPchPolicyUpdate.c
+  PeiSaPolicyUpdatePreMem.c
+  PeiSaPolicyUpdate.c
+  PeiFspMiscUpdUpdateLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  CoffeeLakeFspBinPkg/CoffeeLakeFspBinPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses.IA32]
+  FspWrapperApiLib
+  OcWdtLib
+  PchResetLib
+  FspWrapperPlatformLib
+  BaseMemoryLib
+  CpuPlatformLib
+  DebugLib
+  HdaVerbTableLib
+  HobLib
+  IoLib
+  PcdLib
+  PostCodeLib
+  SmbusLib
+  ConfigBlockLib
+  PeiSaPolicyLib
+  PchGbeLib
+  PchInfoLib
+  PchHsioLib
+  PchPcieRpLib
+  MemoryAllocationLib
+  DebugPrintErrorLevelLib
+  SiPolicyLib
+  PchGbeLib
+  TimerLib
+  GpioLib
+  PeiLib
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable        ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber             ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size
+
+  gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+[Guids]
+  gFspNonVolatileStorageHobGuid                 ## CONSUMES
+  gTianoLogoGuid                                ## CONSUMES
+  gEfiMemoryOverwriteControlDataGuid
+
+[Depex]
+  gEdkiiVTdInfoPpiGuid
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
new file mode 100644
index 0000000000..06489a6336
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
@@ -0,0 +1,97 @@
+## @file
+#  Provide FSP wrapper platform sec related function.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecFspWrapperPlatformSecLib
+  FILE_GUID                      = 4E1C4F95-90EA-47de-9ACC-B8920189A1F5
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSecLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  FspWrapperPlatformSecLib.c
+  SecRamInitData.c
+  SecPlatformInformation.c
+  SecGetPerformance.c
+  SecTempRamDone.c
+  PlatformInit.c
+
+[Sources.IA32]
+  Ia32/SecEntry.nasm
+  Ia32/PeiCoreEntry.nasm
+  Ia32/Stack.nasm
+  Ia32/Fsp.h
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  IntelFsp2Pkg/IntelFsp2Pkg.dec
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  LocalApicLib
+  SerialPortLib
+  FspWrapperPlatformLib
+  FspWrapperApiLib
+  BoardInitLib
+  SecBoardInitLib
+  TestPointCheckLib
+  IoLib
+
+[Ppis]
+  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
+  gPeiSecPerformancePpiGuid               ## CONSUMES
+  gTopOfTemporaryRamPpiGuid               ## PRODUCES
+  gEfiPeiFirmwareVolumeInfoPpiGuid        ## PRODUCES
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize               ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress                  ## CONSUMES
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize                  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdSecSerialPortDebugEnable        ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
+
+[FixedPcd]
+  gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress         ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize      ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset             ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress            ## CONSUMES
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize               ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
new file mode 100644
index 0000000000..e7eef24906
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
@@ -0,0 +1,54 @@
+## @file
+#  Base ACPI Timer Library
+#
+#  Provides basic timer support using the ACPI timer hardware.  The performance
+#  counter features are provided by the processors time stamp counter.
+#
+#  Note: The implementation uses the lower 24-bits of the ACPI timer and
+#  is compatible with both 24-bit and 32-bit ACPI timers.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseAcpiTimerLib
+  FILE_GUID                      = 564DE85F-049E-4481-BF7A-CA04D2788CF9
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib|SEC PEI_CORE PEIM
+  CONSTRUCTOR                    = AcpiTimerLibConstructor
+  MODULE_UNI_FILE                = BaseAcpiTimerLib.uni
+
+[Sources]
+  AcpiTimerLib.c
+  BaseAcpiTimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec      ## OVERRIDE
+
+[LibraryClasses]
+  BaseLib
+  PcdLib
+  PciLib
+  IoLib
+  DebugLib
+
+[Pcd]
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber             ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber          ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber        ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset  ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask            ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset     ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress          ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset               ## CONSUMES
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask      ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
new file mode 100644
index 0000000000..ef5ede18cc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Library producing Gpio Expander functionality.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BaseGpioExpanderLib
+  FILE_GUID                      = D10AE2A4-782E-427E-92FB-BB74505ED329
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = GpioExpanderLib
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  TimerLib
+  PchSerialIoLib
+  I2cAccessLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioExpanderLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
new file mode 100644
index 0000000000..3c017577b6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
@@ -0,0 +1,67 @@
+## @file
+#  PEI Intel HD Audio Verb Table library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiHdaVerbTableLib
+  FILE_GUID                      = 821486A2-CF3B-4D24-BC45-AFE40D9737EB
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = HdaVerbTableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  PeiHdaVerbTableLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PcdLib
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdHdaVerbTable                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable    ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
new file mode 100644
index 0000000000..887cbf84f8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
@@ -0,0 +1,39 @@
+## @file
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiI2cAccessLib
+  FILE_GUID                      = 72CD3A7B-FEA5-4F5E-9165-4DD12187BB13
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = PeiI2cAccessLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiI2cAccessLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
new file mode 100644
index 0000000000..16653f38bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
@@ -0,0 +1,58 @@
+## @file
+#  Component description file for DXE DxePolicyUpdateLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxePolicyUpdateLib
+  FILE_GUID                      = 690B3786-D215-4ABB-9EF2-7A80128560E0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  DxeMePolicyUpdate.c
+  DxeSaPolicyUpdate.c
+  DxePchPolicyUpdate.c
+  DxeCpuPolicyUpdate.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseLib
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  IoLib
+  CpuPlatformLib
+  HobLib
+  ConfigBlockLib
+  PciSegmentLib
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+
+[Guids]
+  gEfiGlobalVariableGuid                        ## CONSUMES
+  gEfiEndOfDxeEventGroupGuid                    ## CONSUMES
+  gMeInfoSetupGuid                              ## PRODUCES
+  gMePolicyHobGuid                              ## CONSUMES
+  gCpuSetupVariableGuid                         ## CONSUMES
+  gPchSetupVariableGuid                         ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
new file mode 100644
index 0000000000..293abf1904
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
@@ -0,0 +1,61 @@
+## @file
+# Component description file for PeiPolicyInit library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyInitLib
+  FILE_GUID                      = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyInitLib
+
+[LibraryClasses]
+  BaseMemoryLib
+  BaseLib
+  CpuPlatformLib
+  DebugLib
+  DebugPrintErrorLevelLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  PeiServicesLib
+  PeiPolicyBoardConfigLib
+  PeiPolicyUpdateLib
+  PostCodeLib
+  SmbusLib
+  ConfigBlockLib
+  SiPolicyLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy ## CONSUMES
+
+
+[Sources]
+  PeiPolicyInitPreMem.c
+  PeiPolicyInit.c
+  PeiPolicyInit.h
+  PeiCpuPolicyInit.h
+  PeiMePolicyInit.h
+  PeiSaPolicyInit.c
+  PeiSaPolicyInit.h
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+  gSiPreMemPolicyPpiGuid                        ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
new file mode 100644
index 0000000000..3095a7333e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
@@ -0,0 +1,272 @@
+## @file
+# Module Information file for PEI PolicyUpdateLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyUpdateLib
+  FILE_GUID                      = 6EA9585C-3C15-47DA-9FFC-25E9E4EA4D0C
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyUpdateLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+  HobLib
+  BaseCryptLib
+  CpuPlatformLib
+  IoLib
+  PeiSaPolicyLib
+  ConfigBlockLib
+  PchGbeLib
+  PchInfoLib
+  PchPcieRpLib
+  HdaVerbTableLib
+  MemoryAllocationLib
+  PeiServicesTablePointerLib
+  PcdLib
+  Tpm2CommandLib
+  Tpm12CommandLib
+  Tpm2DeviceLib
+  Tpm12DeviceLib
+  PmcLib
+  SataLib
+  PchInfoLib
+  PciSegmentLib
+  SiPolicyLib
+  PeiServicesLib
+  SpiLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdTsegSize                             ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize          ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdMchBaseAddress             ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable    ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber         ## CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGttMmAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit       ## CONSUMES
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize                 ## CONSUMES
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## CONSUMES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive            ## CONSUMES
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex                  ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive           ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo         ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo           ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive           ## CONSUMES
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3            ## CONSUMES
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent              ## CONSUMES
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9                     ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15                    ## CONSUMES
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe                 ## CONSUMES
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14      ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15      ## CONSUMES
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8       ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9       ## CONSUMES
+
+  # Pch SerialIo I2c Pads Termination
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdEcPresent
+
+  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSataLedEnable                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdVrAlertEnable                  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEnable  ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEnable  ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid   ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber           ## CONSUMES
+
+[FixedPcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiAcpiReclaimMemorySize  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiAcpiNvsMemorySize      ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize     ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize       ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize       ## CONSUMES
+
+[Sources]
+  PeiPchPolicyUpdatePreMem.c
+  PeiPchPolicyUpdate.c
+  PeiCpuPolicyUpdatePreMem.c
+  PeiCpuPolicyUpdate.c
+  PeiMePolicyUpdatePreMem.c
+  PeiMePolicyUpdate.c
+  PeiSaPolicyUpdate.c
+  PeiSaPolicyUpdatePreMem.c
+  PeiSiPolicyUpdate.c
+
+[Ppis]
+  gWdtPpiGuid                                   ## CONSUMES
+  gPchSpiPpiGuid                                ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+  gSiPreMemPolicyPpiGuid                        ## CONSUMES
+  gPeiTbtPolicyPpiGuid                          ## CONSUMES
+
+[Guids]
+  gTianoLogoGuid                                ## CONSUMES
+  gSiConfigGuid                                 ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
new file mode 100644
index 0000000000..a88385f36f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
@@ -0,0 +1,25 @@
+/** @file
+  Header file for the DxeTBTPolicy library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_LIBRARY_H_
+#define _DXE_TBT_POLICY_LIBRARY_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+//#include <SetupVariable.h>
+#include <Guid/EventGroup.h>
+
+#endif // _DXE_TBT_POLICY_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
new file mode 100644
index 0000000000..462bf780e3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
@@ -0,0 +1,19 @@
+/** @file
+  Header file for the PeiTBTPolicy library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_LIBRARY_H_
+#define _PEI_TBT_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#endif // _PEI_TBT_POLICY_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
new file mode 100644
index 0000000000..52f9fbed8b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
@@ -0,0 +1,234 @@
+/** @file
+  Internal header file for Fsp Policy Initialization Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_FSP_POLICY_INIT_LIB_H_
+#define _PEI_FSP_POLICY_INIT_LIB_H_
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+#include <Setup.h>
+
+/**
+  Performs FSP SI PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP SI PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+/**
+  Performs FSP PCH PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInit (
+  IN OUT FSPS_UPD     *FspsUpd
+  );
+
+/**
+  Performs FSP CPU PEI Policy initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+Performs FSP Security PEI Policy initialization.
+
+@param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+@retval          EFI_SUCCESS         FSP UPD Data is updated.
+@retval          EFI_NOT_FOUND       Fail to locate required PPI.
+@retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInitPreMem(
+IN OUT FSPM_UPD    *FspmUpd
+);
+
+/**
+  Performs FSP ME PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP ME PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInit (
+  IN OUT FSPS_UPD     *FspsUpd
+  );
+
+/**
+  Performs FSP SA PEI Policy initialization in pre-memory.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+/**
+  Performs FSP SA PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+/**
+  Performs FSP CPU PEI Policy post memory initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+/**
+Performs FSP Security PEI Policy post memory initialization.
+
+@param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+@retval          EFI_SUCCESS         FSP UPD Data is updated.
+@retval          EFI_NOT_FOUND       Fail to locate required PPI.
+@retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInit(
+IN OUT FSPS_UPD    *FspsUpd
+);
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32               *Size
+  );
+
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+#endif // _PEI_FSP_POLICY_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
new file mode 100644
index 0000000000..a0c8f2dae7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_MISC_POLICY_UPDATE_H_
+#define _PEI_MISC_POLICY_UPDATE_H_
+
+#include <FspmUpd.h>
+
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  );
+
+#endif
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h
new file mode 100644
index 0000000000..1ff16e2f32
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h
@@ -0,0 +1,28 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_UPDATE_H_
+#define _PEI_PCH_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/MmPciLib.h>
+#include <Library/ConfigBlockLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..9b8c28c469
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h
@@ -0,0 +1,30 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_UPDATE_H_
+#define _PEI_SA_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <SaPolicyCommon.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include "PeiPchPolicyUpdate.h"
+#include <Library/PcdLib.h>
+#include <CpuAccess.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+extern EFI_GUID gTianoLogoGuid;
+
+#endif
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
new file mode 100644
index 0000000000..e7b5ed952b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __FSPT_CORE_UPD_H__
+#define __FSPT_CORE_UPD_H__
+
+#pragma pack(1)
+
+/** Fsp T Core UPD
+**/
+typedef struct {
+
+/** Offset 0x0020
+**/
+  UINT32                      MicrocodeRegionBase;
+
+/** Offset 0x0024
+**/
+  UINT32                      MicrocodeRegionSize;
+
+/** Offset 0x0028
+**/
+  UINT32                      CodeRegionBase;
+
+/** Offset 0x002C
+**/
+  UINT32                      CodeRegionSize;
+
+/** Offset 0x0030
+**/
+  UINT8                       Reserved[16];
+} FSPT_CORE_UPD;
+
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
new file mode 100644
index 0000000000..1c88285a1d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
@@ -0,0 +1,43 @@
+/** @file
+  Fsp related definitions
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __FSP_H__
+#define __FSP_H__
+
+//
+// Fv Header
+//
+#define FVH_SIGINATURE_OFFSET         0x28
+#define FVH_SIGINATURE_VALID_VALUE    0x4856465F  // valid signature:_FVH
+#define FVH_HEADER_LENGTH_OFFSET      0x30
+#define FVH_EXTHEADER_OFFSET_OFFSET   0x34
+#define FVH_EXTHEADER_SIZE_OFFSET     0x10
+
+//
+// Ffs Header
+//
+#define FSP_HEADER_GUID_DWORD1        0x912740BE
+#define FSP_HEADER_GUID_DWORD2        0x47342284
+#define FSP_HEADER_GUID_DWORD3        0xB08471B9
+#define FSP_HEADER_GUID_DWORD4        0x0C3F3527
+#define FFS_HEADER_SIZE_VALUE         0x18
+
+//
+// Section Header
+//
+#define SECTION_HEADER_TYPE_OFFSET    0x03
+#define RAW_SECTION_HEADER_SIZE_VALUE 0x04
+
+//
+// Fsp Header
+//
+#define FSP_HEADER_IMAGEBASE_OFFSET     0x1C
+#define FSP_HEADER_TEMPRAMINIT_OFFSET   0x30
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h
new file mode 100644
index 0000000000..0d26e8ad7a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h
@@ -0,0 +1,3014 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_VERB_TABLES_H_
+#define _PCH_HDA_VERB_TABLES_H_
+
+#include <Ppi/SiPolicy.h>
+
+HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: CFL Display Audio Codec
+  //  Revision ID = 0xFF
+  //  Codec Vendor: 0x8086280B
+  //
+  0x8086, 0x280B,
+  0xFF, 0xFF,
+  //
+  // Display Audio Verb Table
+  //
+  // For GEN9, the Vendor Node ID is 08h
+  // Port to be exposed to the inbox driver in the vanilla mode: PORT C - BIT[7:6] = 01b
+  0x00878140,
+  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
+  0x00571C10,
+  0x00571D00,
+  0x00571E56,
+  0x00571F18,
+  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
+  0x00671C20,
+  0x00671D00,
+  0x00671E56,
+  0x00671F18,
+  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
+  0x00771C30,
+  0x00771D00,
+  0x00771E56,
+  0x00771F18,
+  // Disable the third converter and third Pin (NID 08h)
+  0x00878140
+);
+
+//
+//codecs verb tables
+//
+HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40622005
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D20,
+  0x01D71E62,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B,
+
+
+  //Widget node 0X20 for ALC1305   20160603 update
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+  //
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204800F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02044848,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050000,
+  0x02043330,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050000,
+  0x02043333,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x020402EC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02044909,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x020440B0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040047,
+  0x02050028,
+  0x02040C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040048,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040049,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004A,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040001,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024
+); // HdaVerbTableAlc700
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC701)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0701
+  //
+  0x10EC, 0x0701,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC701
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40610041
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC1124
+  0x00172024,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C41,
+  0x01D71D00,
+  0x01D71E61,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B
+); // HdaVerbTableAlc701
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC274)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0274
+  //
+  0x10EC, 0x0274,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC274
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
+  //The number of verb command block : 16
+
+  //    NID 0x12 : 0x40000000
+  //    NID 0x13 : 0x411111F0
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x411111F0
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11020
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40451B05
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211010
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //,DA Codec Subsystem ID  : 0x10EC10F6
+  0x001720F6,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371CF0,
+  0x01371D11,
+  0x01371E11,
+  0x01371F41,
+  //Pin widget 0x14 - NPC
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S_OUT2
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S_OUT1
+  0x01771CF0,
+  0x01771D11,
+  0x01771E11,
+  0x01771F41,
+  //Pin widget 0x18 - I2S_IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C20,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D1B,
+  0x01D71E45,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C10,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205006F,
+  0x02042C0B,
+  //Widget node 0x20 - 1 :
+  0x02050035,
+  0x02048968,
+  0x05B50001,
+  0x05B48540,
+  //Widget node 0x20 - 2 :
+  0x05850000,
+  0x05843888,
+  0x05850000,
+  0x05843888,
+  //Widget node 0x20 - 3 :
+  0x0205004A,
+  0x0204201B,
+  0x0205004A,
+  0x0204201B
+); //HdaVerbTableAlc274
+
+//
+// CFL S Audio Codec
+//
+STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) CFL S RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x90A60130
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x03011010
+  //    NID 0x17 : 0x90170120
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A1103E
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x03A11040
+  //    NID 0x1D : 0x40600001
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x0421102F
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC112C
+  0x0017202C,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C30,
+  0x01271D01,
+  0x01271EA6,
+  0x01271F90,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671C10,
+  0x01671D10,
+  0x01671E01,
+  0x01671F03,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C20,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C3E,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71C40,
+  0x01B71D10,
+  0x01B71EA1,
+  0x01B71F03,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C01,
+  0x01D71D00,
+  0x01D71E60,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C2F,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
+  0x0205006B,
+  0x02044260,
+  0x0205006B,
+  0x02044260,
+  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent control
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 4   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+
+  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove ALC1305 EQ setting
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x02042213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+);
+
+
+//
+// WHL codecs verb tables
+//
+HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) WHL RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table for WHL PCH boards
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x02A19040
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40638029
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x02211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271CF0,
+  0x01271D11,
+  0x01271E11,
+  0x01271F41,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C40,
+  0x01971D90,
+  0x01971EA1,
+  0x01971F02,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C29,
+  0x01D71D80,
+  0x01D71E63,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F02,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+
+  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass DAC02 DRE(NID5B bit14)
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+
+  //Widget node 0x20 -2:
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+
+  //Widget node 0x20 - 3   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+
+  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x0204E213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204422E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+); // WhlHdaVerbTableAlc700
+
+#endif // _PCH_HDA_VERB_TABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h
new file mode 100644
index 0000000000..8cbcace075
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h
@@ -0,0 +1,91 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_ME_POLICY_UPDATE_H_
+#define _DXE_ME_POLICY_UPDATE_H_
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Guid/EventGroup.h>
+#include <IndustryStandard/Acpi10.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/MePolicy.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/MePeiConfig.h>
+
+#define PLATFORM_BOOT_TABLE_PTR_TYPE   0x1001
+#define PLATFORM_BOOT_RECORD_TYPE      0x1022
+//
+// Timeout values based on HPET
+//
+#define HECI_MSG_DELAY                 2000000  ///< show warning msg and stay for 2 seconds.
+#define CONVERSION_MULTIPLIER          1000000  ///< msec to nanosec multiplier
+#define PLATFORM_BOOT_TABLE_SIGNATURE  SIGNATURE_32 ('P', 'B', 'P', 'T')
+
+//
+// Platform Boot Performance Table Record
+//
+
+typedef struct {
+  UINT16 Type;
+  UINT8  Length;
+  UINT8  Revision;
+  UINT32 Reserved;
+  UINT64 TimestampDelta1;
+  UINT64 TimestampDelta2;
+  UINT64 TimestampDelta3;
+} PLATFORM_BOOT_TABLE_RECORD;
+
+//
+// Platform boot Performance Table
+//
+
+typedef struct {
+  EFI_ACPI_COMMON_HEADER     Header;
+  PLATFORM_BOOT_TABLE_RECORD PlatformBoot;
+} PLATFORM_BOOT_PERFORMANCE_TABLE;
+
+/**
+  Update ME Policy while MePlatformProtocol is installed.
+
+  @param[in] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromMeSetup (
+  IN ME_POLICY_PROTOCOL           *MePolicyInstance
+  );
+
+/**
+  Update ME Policy if Setup variable exists.
+
+  @param[in, out] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromSetup (
+  IN OUT ME_POLICY_PROTOCOL     *MePolicyInstance
+  );
+
+/**
+  Functions performs HECI exchange with FW to update MePolicy settings.
+
+  @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
+UpdateMeSetupCallback (
+  IN  EFI_EVENT                       Event,
+  IN  VOID                            *Context
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
new file mode 100644
index 0000000000..4521d83567
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_UPDATE_H_
+#define _DXE_SA_POLICY_UPDATE_H_
+
+#include <PiDxe.h>
+#include <CpuRegs.h>
+#include <PchAccess.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
new file mode 100644
index 0000000000..25c5213c2d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the PeiCpuPolicyInit.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_INIT_H_
+#define _PEI_CPU_POLICY_INIT_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/CpuPolicyLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+
+/**
+  This function performs CPU PEI Policy initialization in PreMem.
+
+  @param[in, out] SiPreMemPolicyPpi  The Si Pre-Mem Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h
new file mode 100644
index 0000000000..7f3fde9fd8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for the PeiMePolicyInit
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_ME_POLICY_INIT_H_
+#define _PEI_ME_POLICY_INIT_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiMePolicyLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+
+#endif // _PEI_ME_POLICY_INIT_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h
new file mode 100644
index 0000000000..9c18f85735
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for the PolicyInitPei PEIM.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_INIT_H_
+#define _PEI_POLICY_INIT_H_
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "PeiCpuPolicyInit.h"
+#include "PeiMePolicyInit.h"
+#include "PeiSaPolicyInit.h"
+#include "PeiSiPolicyInit.h"
+#include <Ppi/SiPolicy.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
new file mode 100644
index 0000000000..83b18bf533
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
@@ -0,0 +1,58 @@
+/** @file
+  Header file for the SaPolicyInitPei PEIM.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_INIT_PEI_H_
+#define _SA_POLICY_INIT_PEI_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Ppi/SiPolicy.h>
+#include <SaPolicyCommon.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+#include <Library/TimerLib.h>
+#include <Library/GpioLib.h>
+
+//
+// Functions
+//
+/**
+PCIe GPIO Write
+
+@param[in] Gpio        - GPIO Number
+@param[in] Active      - GPIO Active Information; High/Low
+@param[in] Level       - Write GPIO value (0/1)
+
+**/
+VOID
+PcieGpioWrite(
+IN       UINT32                       Gpio,
+IN       BOOLEAN                      Active,
+IN       BOOLEAN                      Level
+);
+
+/**
+PcieCardResetWorkAround performs PCIe Card reset on root port
+
+@param[in out] SiPreMemPolicyPpi       - SI_PREMEM_POLICY_PPI
+
+@retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+PcieCardResetWorkAround(
+IN OUT   SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
new file mode 100644
index 0000000000..1a28f426d6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for the PeiSiPolicyInit
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_INIT_PEI_H_
+#define _SI_POLICY_INIT_PEI_H_
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/PeiSiPolicyUpdateLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <FirwmareConfigurations.h>
+
+#endif // _SI_POLICY_INIT_PEI_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
new file mode 100644
index 0000000000..254e58edb7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
@@ -0,0 +1,32 @@
+/** @file
+  Header file for PEI CpuPolicyUpdate.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_UPDATE_H_
+#define _PEI_CPU_POLICY_UPDATE_H_
+
+#include <PiPei.h>
+#include <Ppi/SiPolicy.h>
+#include <Ppi/Wdt.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <PlatformBoardId.h>
+#include <PchAccess.h>
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <CpuAccess.h>
+#include <Ppi/MasterBootMode.h>
+#include <Library/PeiServicesLib.h>
+#include "PeiPchPolicyUpdate.h"
+#include <Library/CpuPlatformLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h
new file mode 100644
index 0000000000..37cd373c78
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h
@@ -0,0 +1,14 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_ME_POLICY_UPDATE_H_
+#define _PEI_ME_POLICY_UPDATE_H_
+
+#include <Library/DebugLib.h>
+#include <Ppi/SiPolicy.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h
new file mode 100644
index 0000000000..5a69852801
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PCH_POLICY_UPDATE_H_
+#define _PEI_PCH_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PiPei.h>
+#include <PlatformBoardId.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+#include <PlatformBoardConfig.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
new file mode 100644
index 0000000000..8cf24ed24d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
@@ -0,0 +1,53 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SA_POLICY_UPDATE_H_
+#define _PEI_SA_POLICY_UPDATE_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PlatformBoardId.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Ppi/Wdt.h>
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include "PeiPchPolicyUpdate.h"
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <CpuAccess.h>
+
+#define WDT_TIMEOUT 60
+
+// BClk Frequency Limitations (in Hz)
+#define BCLK_MAX                538000000
+#define BCLK_100                100000000
+#define BCLK_GRANULARITY        1000000
+#define BCLK_100_KHZ            100000
+
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32               *Size
+  );
+
+#endif
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
new file mode 100644
index 0000000000..38ea081166
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
@@ -0,0 +1,19 @@
+/** @file
+   Header file for PEI SiPolicyUpdate.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_UPDATE_H_
+#define _PEI_SI_POLICY_UPDATE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Ppi/SiPolicy.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
new file mode 100644
index 0000000000..c185cda4ce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
@@ -0,0 +1,148 @@
+/** @file
+  This file is DxeTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <DxeTbtPolicyLibrary.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+
+
+/**
+  Update Tbt Policy Callback
+**/
+
+VOID
+EFIAPI
+UpdateTbtPolicyCallback (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  DXE_TBT_POLICY_PROTOCOL        *DxeTbtConfig;
+
+  DxeTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+  DEBUG ((DEBUG_INFO, "UpdateTbtPolicyCallback\n"));
+
+  Status = gBS->LocateProtocol (
+                  &gDxeTbtPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &DxeTbtConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+  } else {
+
+  }
+
+  return;
+}
+
+/**
+  Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+  VOID
+  )
+{
+  EFI_STATUS                       Status;
+  UINT8                            Index;
+  DXE_TBT_POLICY_PROTOCOL          *DxeTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtPrintDxePolicyConfig Start\n"));
+
+  DxeTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+  Status = gBS->LocateProtocol (
+                  &gDxeTbtPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &DxeTbtConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Print DTBT Policy
+  //
+  DEBUG ((DEBUG_ERROR, " ========================= DXE TBT POLICY ========================= \n"));
+  for (Index = 0; Index < MAX_DTBT_CONTROLLER_NUMBER; Index++) {
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieExtraBusRsvd = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieExtraBusRsvd));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieMemRsvd = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieMemRsvd));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieMemAddrRngMax = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieMemAddrRngMax));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPciePMemRsvd = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPciePMemRsvd));
+    DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPciePMemAddrRngMax = %x\n", Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPciePMemAddrRngMax));
+  }
+
+  //
+  // Print TBT Common Policy
+  //
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAspm = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAspm));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtL1SubStates = %x\n", DxeTbtConfig->TbtCommonConfig.TbtL1SubStates));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotNotify = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotNotify));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotSMI = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotSMI));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtLtr = %x\n", DxeTbtConfig->TbtCommonConfig.TbtLtr));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtPtm = %x\n", DxeTbtConfig->TbtCommonConfig.TbtPtm));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtSetClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.TbtSetClkReq));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = %x\n", DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.SecurityMode = %x\n", DxeTbtConfig->TbtCommonConfig.SecurityMode));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Gpio5Filter = %x\n", DxeTbtConfig->TbtCommonConfig.Gpio5Filter));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TrA0OsupWa = %x\n", DxeTbtConfig->TbtCommonConfig.TrA0OsupWa));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3Tbt = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3Tbt));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Win10Support = %x\n", DxeTbtConfig->TbtCommonConfig.Win10Support));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtVtdBaseSecurity = %x\n", DxeTbtConfig->TbtCommonConfig.TbtVtdBaseSecurity));
+  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.ControlIommu = %x\n", DxeTbtConfig->TbtCommonConfig.ControlIommu));
+  return;
+}
+
+/**
+  Install Tbt Policy
+
+  @param[in] ImageHandle                Image handle of this driver.
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+  IN  EFI_HANDLE                    ImageHandle
+  )
+{
+  EFI_STATUS                    Status;
+  DXE_TBT_POLICY_PROTOCOL       *DxeTbtPolicy;
+
+  DEBUG ((DEBUG_INFO, "Install DXE TBT Policy\n"));
+
+  DxeTbtPolicy = NULL;
+  //Alloc memory for DxeTbtPolicy
+  DxeTbtPolicy = (DXE_TBT_POLICY_PROTOCOL *) AllocateZeroPool (sizeof (DXE_TBT_POLICY_PROTOCOL));
+  if (DxeTbtPolicy == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = gBS->InstallProtocolInterface (
+                  &ImageHandle,
+                  &gDxeTbtPolicyProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  DxeTbtPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install Tbt Secure Boot List protocol failed\n"));
+  }
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
new file mode 100644
index 0000000000..690c9acf95
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
@@ -0,0 +1,316 @@
+/** @file
+  PeiTbtInit library implementition with empty functions.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+
+
+/**
+  Selects the proper TBT Root port to assign resources
+  based on the user input value
+
+  @param[in]  SetupData          Pointer to Setup data
+
+  @retval     TbtSelectorChosen  Rootport number.
+**/
+VOID
+GetRootporttoSetResourcesforTbt (
+  IN UINTN                              RpIndex,
+  OUT UINT8                             *RsvdExtraBusNum,
+  OUT UINT16                            *RsvdPcieMegaMem,
+  OUT UINT8                             *PcieMemAddrRngMax,
+  OUT UINT16                            *RsvdPciePMegaMem,
+  OUT UINT8                             *PciePMemAddrRngMax,
+  OUT BOOLEAN                           *SetResourceforTbt
+  )
+{
+  UINTN TbtRpNumber;
+  TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber);
+
+    if (RpIndex == (TbtRpNumber - 1)) {
+        *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
+        *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd);
+        *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
+        *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd);
+        *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
+        *SetResourceforTbt = TRUE;
+      }
+      else {
+        *SetResourceforTbt = FALSE;
+      }
+  }
+
+/**
+  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
+  @param[in]  TimeOut                   Time out with 100 ms garnularity
+  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to Clear/Set)
+  @param[out] *Tbt2PcieValue Function   Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion(
+  IN  UINT64   CommandOffsetAddress,
+  IN  UINT32   TimeOut,
+  IN  BOOLEAN  Tbt2PcieDone,
+  OUT UINT32   *Tbt2PcieValue
+  )
+{
+  BOOLEAN ReturnFlag;
+  UINT32  Tbt2PcieCheck;
+
+  ReturnFlag = FALSE;
+  while (TimeOut-- > 0) {
+    *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress);
+
+    if (0xFFFFFFFF == *Tbt2PcieValue ) {
+      //
+      // Device is not here return now
+      //
+      ReturnFlag     = FALSE;
+      break;
+    }
+
+    if(Tbt2PcieDone) {
+      Tbt2PcieCheck  =  *Tbt2PcieValue & TBT2PCIE_DON_R;
+    } else {
+      Tbt2PcieCheck  = !(*Tbt2PcieValue & TBT2PCIE_DON_R);
+    }
+
+    if (Tbt2PcieCheck) {
+      ReturnFlag     = TRUE;
+      break;
+    }
+
+    MicroSecondDelay(TBT_MAIL_BOX_DELAY);
+  }
+  return ReturnFlag;
+}
+/**
+  Get Security Level.
+  @param[in]  Bus       Bus number Host Router (DTBT)
+  @param[in]  Device    Device number for Host Router (DTBT)
+  @param[in]  Function  Function number for  Host Router (DTBT)
+  @param[in]  Command   Command for  Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  )
+{
+  UINT64       Pcie2Tbt;
+  UINT64       Tbt2Pcie;
+  UINT32       RegisterValue;
+  UINT8        ReturnFlag;
+
+  ReturnFlag           = 0xFF;
+
+  DEBUG ((DEBUG_INFO, "GetSecLevel() \n"));
+
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+  PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+  if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue)) {
+    ReturnFlag     = (UINT8) (0xFF & (RegisterValue >> 8));
+  }
+
+  PciSegmentWrite32 (Pcie2Tbt, 0);
+
+  InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+  DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag));
+
+  return ReturnFlag;
+}
+
+/**
+  Set Security Level.
+  @param[in]  Data      Security State
+  @param[in]  Bus       Bus number for Host Router (DTBT)
+  @param[in]  Device    Device number for Host Router (DTBT)
+  @param[in]  Function  Function number for Host Router (DTBT)
+  @param[in]  Command   Command for  Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+  IN    UINT8                   Data,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  )
+{
+  UINT64       Pcie2Tbt;
+  UINT64       Tbt2Pcie;
+  UINT32       RegisterValue;
+  BOOLEAN      ReturnFlag;
+
+  ReturnFlag   = FALSE;
+
+  DEBUG ((DEBUG_INFO, "SetSecLevel() \n"));
+
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+  PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B);
+
+  ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+  DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue));
+  PciSegmentWrite32 (Pcie2Tbt, 0);
+
+  InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+  DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag));
+  return ReturnFlag;
+}
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in]  GpioNumber
+@param[in]  Value
+**/
+VOID
+ForceDtbtPower(
+  IN  UINT8          GpioAccessType,
+  IN  UINT8          Expander,
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+)
+{
+  if (GpioAccessType == 0x01) {
+    // PCH
+    GpioSetOutputValue (GpioNumber, (UINT32)Value);
+  } else if (GpioAccessType == 0x02) {
+    // IoExpander {TCA6424A}
+    GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value);
+  }
+}
+
+/**
+Execute TBT Mail Box Command
+
+@param[in]  Command   TBT Command
+@param[in]  Bus       Bus number for  Host Router (DTBT)
+@param[in]  Device    Device number for  Host Router (DTBT)
+@param[in]  Function  Function number for  Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+   IN    UINT8                   Command,
+   IN    UINT8                   Bus,
+   IN    UINT8                   Device,
+   IN    UINT8                   Function,
+   IN    UINT32                  Timeout
+)
+{
+   UINT64      Pcie2Tbt;
+   UINT64      Tbt2Pcie;
+   UINT32      RegisterValue;
+   BOOLEAN     ReturnFlag;
+
+   GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+   GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+   PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+   ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+   PciSegmentWrite32(Pcie2Tbt, 0);
+
+   return ReturnFlag;
+}
+/**
+  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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 If Invalid Root Port Number or TYPE is Passed
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun (
+  IN  BOOLEAN Type,
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFunc
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 TbtRpDev;
+  UINTN                 TbtRpFunc;
+
+  Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if valid input found.
+  //
+  // PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be
+  // with device number 0x1 and Function number 0,1 and 2 respectively.
+  //
+  if (Type == DTBT_TYPE_PEG)
+  {
+    //
+    //  PEG Rootport
+    //
+    if (RpNumber <= 2) {
+      *RpDev  =   0x01;
+      *RpFunc =   RpNumber;
+      Status  =   EFI_SUCCESS;
+    }
+  }
+  if (Type == DTBT_TYPE_PCH)
+  {
+    //
+    //  PCH Rootport
+    //
+    if (RpNumber <= 23) {
+      Status  = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc);
+      *RpDev  = TbtRpDev;
+      *RpFunc = TbtRpFunc;
+    }
+  }
+
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+BOOLEAN
+IsTbtHostRouter (
+  IN    UINT16  DeviceID
+  )
+{
+  switch (DeviceID) {
+  case AR_HR_2C:
+  case AR_HR_4C:
+  case AR_HR_LP:
+  case AR_HR_C0_2C:
+  case AR_HR_C0_4C:
+  case TR_HR_2C:
+  case TR_HR_4C:
+    return TRUE;
+  }
+
+  return FALSE;
+} // IsTbtHostRouter
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
new file mode 100644
index 0000000000..ffd8416660
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
@@ -0,0 +1,206 @@
+/** @file
+  This file is PeiTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/PeiServicesLib.h>
+#include <Library/GpioLib.h>
+#include <PiPei.h>
+#include <PeiTbtPolicyLibrary.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Base.h>
+#include <GpioConfig.h>
+
+/**
+  Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicy (
+  VOID
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *VariableServices;
+  PEI_TBT_POLICY                   *PeiTbtConfig;
+
+  PeiTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiTbtPolicy \n"));
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,
+             0,
+             NULL,
+             (VOID **) &VariableServices
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update DTBT Policy
+  //
+  PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn = PcdGet8 (PcdDTbtControllerEn);
+  if (PcdGet8 (PcdDTbtControllerType) == TYPE_PEG)
+  {
+    PeiTbtConfig-> DTbtControllerConfig.Type = (UINT8) TYPE_PEG;
+    PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = 1; // PEG RP 1 (Function no. 0)
+  }
+  else {
+    PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = PcdGet8 (PcdDTbtPcieRpNumber);
+    PeiTbtConfig-> DTbtControllerConfig.Type = PcdGet8 (PcdDTbtControllerType);
+  }
+  PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = (GPIO_PAD) PcdGet32 (PcdDTbtCioPlugEventGpioPad);
+  if (GpioCheckFor2Tier(PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad)) {
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 0;
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+  }
+  else {
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 1;
+    //
+    // Update Signature based on platform GPIO.
+    //
+    PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+  }
+  PeiTbtConfig->DTbtCommonConfig.TbtBootOn = PcdGet8 (PcdDTbtBootOn);
+  PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = PcdGet8 (PcdDTbtUsbOn);
+  PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = PcdGet8 (PcdDTbtGpio3ForcePwr);
+  PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = PcdGet16 (PcdDTbtGpio3ForcePwrDly);
+
+  return;
+}
+
+/**
+  Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+  VOID
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  EFI_STATUS                       Status;
+  PEI_TBT_POLICY                   *PeiTbtConfig;
+
+  PeiTbtConfig = NULL;
+  Status = EFI_NOT_FOUND;
+  DEBUG ((DEBUG_INFO, "TbtPrintPolicyConfig Start\n"));
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Print DTBT Policy
+  //
+  DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", PEI_TBT_POLICY_REVISION));
+  DEBUG ((DEBUG_INFO, "------------------------ PEI_TBT_CONFIG  -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", PEI_TBT_POLICY_REVISION));
+
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.DTbtControllerEn = %x\n", PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.Type = %x\n", PeiTbtConfig-> DTbtControllerConfig.Type));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRpNumber = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting));
+
+
+  //
+  // Print DTBT Common Policy
+  //
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtBootOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtBootOn));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtUsbOn));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration = %x\n", PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration));
+  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.PcieRstSupport = %x\n", PeiTbtConfig->DTbtCommonConfig.PcieRstSupport));
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+/**
+  Install Tbt Policy
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_PEI_PPI_DESCRIPTOR        *PeiTbtPolicyPpiDesc;
+  PEI_TBT_POLICY                *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "Install PEI TBT Policy\n"));
+
+  PeiTbtConfig = NULL;
+
+  //
+  // Allocate memory for PeiTbtPolicyPpiDesc
+  //
+  PeiTbtPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+  ASSERT (PeiTbtPolicyPpiDesc != NULL);
+  if (PeiTbtPolicyPpiDesc == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Allocate memory and initialize all default to zero for PeiTbtPolicy
+  //
+  PeiTbtConfig = (PEI_TBT_POLICY *) AllocateZeroPool (sizeof (PEI_TBT_POLICY));
+  ASSERT (PeiTbtConfig != NULL);
+  if (PeiTbtConfig == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize PPI
+  //
+  PeiTbtPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+  PeiTbtPolicyPpiDesc->Guid = &gPeiTbtPolicyPpiGuid;
+  PeiTbtPolicyPpiDesc->Ppi = PeiTbtConfig;
+
+  Status = PeiServicesInstallPpi (PeiTbtPolicyPpiDesc);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Install PEI TBT Policy failed\n"));
+  }
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
new file mode 100644
index 0000000000..f33ddebdb3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
@@ -0,0 +1,567 @@
+/** @file
+  Thunderbolt(TM) Pei Library
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GpioExpanderLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+#include <Base.h>
+#include <Library/TbtCommonLib.h>
+#include <TbtBoardInfo.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Library/PchPmcLib.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+
+/**
+Is host router (For dTBT) or End Point (For iTBT) present before sleep
+
+@param[in] ControllerType - DTBT_CONTROLLER or ITBT_CONTROLLER
+@param[in] Controller     - Controller begin offset of CMOS
+
+@Retval     TRUE      There is a TBT HostRouter presented before sleep
+@Retval     FALSE     There is no TBT HostRouter presented before sleep
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN  UINT8        ControllerType,
+IN  UINT8        Controller
+)
+{
+  UINT8 SavedState;
+
+  SavedState = (UINT8)GetTbtHostRouterStatus();
+  if (ControllerType == DTBT_CONTROLLER){
+    return ((SavedState & (DTBT_SAVE_STATE_OFFSET << Controller)) == (DTBT_SAVE_STATE_OFFSET << Controller));
+  } else {
+    if (ControllerType == ITBT_CONTROLLER) {
+      return ((SavedState & (ITBT_SAVE_STATE_OFFSET << Controller)) == (ITBT_SAVE_STATE_OFFSET << Controller));
+    }
+  }
+  return 0;
+}
+**/
+
+/**
+Execute TBT PCIE2TBT_SX_EXIT_TBT_CONNECTED Mail Box Command for S4 mode with PreBootAclEnable
+
+@param[in]  Bus       Bus number for Host Router (DTBT)
+@param[in]  Device    Device number for Host Router (DTBT)
+@param[in]  Function  Function number for Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(
+   IN    UINT8                   Bus,
+   IN    UINT8                   Device,
+   IN    UINT8                   Function,
+   IN    UINT32                  Timeout
+)
+{
+  UINT64      Pcie2Tbt;
+  UINT64      Tbt2Pcie;
+  UINT32      RegisterValue;
+  BOOLEAN     ReturnFlag;
+  UINT32      Command;
+
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+// If PreBootAcl is Enable, we need to enable DATA bit while sending SX EXIT MAIL BOX Command
+  Command = (1 << 8) | PCIE2TBT_SX_EXIT_TBT_CONNECTED;
+  PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+  ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+  PciSegmentWrite32(Pcie2Tbt, 0);
+
+  return ReturnFlag;
+}
+
+/**
+Set the Sleep Mode if the HR is up.
+@param[in]  Bus       Bus number for Host Router (DTBT)
+@param[in]  Device    Device number for Host Router (DTBT)
+@param[in]  Function  Function number for Host Router (DTBT)
+**/
+VOID
+TbtSetSxMode(
+IN    UINT8                   Bus,
+IN    UINT8                   Device,
+IN    UINT8                   Function,
+IN    UINT8                   TbtBootOn
+)
+{
+  UINT64                          TbtUsDevId;
+  UINT64                          Tbt2Pcie;
+  UINT32                          RegVal;
+  UINT32                          MaxLoopCount;
+  UINTN                           Delay;
+  UINT8                           RetCode;
+  EFI_BOOT_MODE                   BootMode;
+  EFI_STATUS                      Status;
+
+  TbtUsDevId = PCI_SEGMENT_LIB_ADDRESS(0, Bus, Device, Function, 0);
+  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+
+  MaxLoopCount = TBT_5S_TIMEOUT;  // Wait 5 sec
+  Delay = 100 * 1000;
+  RetCode = 0x62;
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  if ((BootMode == BOOT_ON_S4_RESUME) && (TbtBootOn == 2)) {
+    MaxLoopCount = TBT_3S_TIMEOUT;
+    if (!TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(Bus, Device, Function, MaxLoopCount)) {
+      //
+      // Nothing to wait, HR is not responsive
+      //
+      return;
+    }
+  }
+  else {
+    if (!TbtSetPcie2TbtCommand(PCIE2TBT_SX_EXIT_TBT_CONNECTED, Bus, Device, Function, MaxLoopCount)) {
+      //
+      // Nothing to wait, HR is not responsive
+      //
+      return;
+    }
+  }
+
+  DEBUG((DEBUG_INFO, "Wait for Dev ID != 0xFF\n"));
+
+  while (MaxLoopCount-- > 0) {
+    //
+    // Check what HR still here
+    //
+    RegVal = PciSegmentRead32(Tbt2Pcie);
+    if (0xFFFFFFFF == RegVal) {
+      RetCode = 0x6F;
+      break;
+    }
+    //
+    // Check completion of TBT link
+    //
+    RegVal = PciSegmentRead32(TbtUsDevId);
+    if (0xFFFFFFFF != RegVal) {
+      RetCode = 0x61;
+      break;
+    }
+
+    MicroSecondDelay(Delay);
+  }
+
+  DEBUG((DEBUG_INFO, "Return code = 0x%x\n", RetCode));
+}
+/**
+  set tPCH25 Timing to 10 ms for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  DEBUG ((DEBUG_INFO, "DTbtSetTPch25Timing call Inside\n"));
+  UINT32                PchPwrmBase;
+
+  //
+  //During boot, reboot and wake  tPCH25 Timing should be set to 10 ms
+  //
+  MmioOr32 (
+    (UINTN) (PchPwrmBase + R_PCH_PWRM_CFG),
+    (BIT0 | BIT1)
+    );
+
+  DEBUG((DEBUG_INFO, "DTbtSetTPch25Timing call Return\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Do ForcePower for DTBT Controller
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+
+  DEBUG ((DEBUG_INFO, "DTbtForcePower call Inside\n"));
+
+      if (PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr) {
+        DEBUG((DEBUG_INFO, "ForcePwrGpio.GpioPad = %x \n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+        ForceDtbtPower(PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioAccessType,PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.Expander, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel);
+        DEBUG((DEBUG_INFO, "ForceDtbtPower asserted \n"));
+        MicroSecondDelay(PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly * 1000);
+        DEBUG((DEBUG_INFO, "Delay after ForceDtbtPower = 0x%x ms \n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+      }
+
+  DEBUG ((DEBUG_INFO, "DTbtForcePower call Return\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear VGA Registers for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  UINTN      RpDev;
+  UINTN      RpFunc;
+  EFI_STATUS Status;
+  UINT64     BridngeBaseAddress;
+  UINT16     Data16;
+
+  DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Inside\n"));
+
+  Status = EFI_SUCCESS;
+
+  Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+  ASSERT_EFI_ERROR(Status);
+  //
+  // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+  // Host router resides should be cleaned
+  //
+
+  BridngeBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0, (UINT32)RpDev, (UINT32)RpFunc, 0);
+  Data16 = PciSegmentRead16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET);
+  Data16 &= (~(EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16));
+  PciSegmentWrite16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET, Data16);
+
+  DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Return\n"));
+  return Status;
+}
+
+/**
+  Exectue Mail box command "Boot On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn(
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  EFI_STATUS Status;
+  UINT32     OrgBusNumberConfiguration;
+  UINTN      RpDev;
+  UINTN      RpFunc;
+
+  DEBUG((DEBUG_INFO, "DTbtBootOn call Inside\n"));
+
+  Status = EFI_SUCCESS;
+
+      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+      ASSERT_EFI_ERROR(Status);
+      OrgBusNumberConfiguration = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+      //
+      // Set Sec/Sub buses to 0xF0
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+      //
+      //When Thunderbolt(TM) boot [TbtBootOn] is enabled in bios setup we need to do the below:
+      //Bios should send "Boot On" message through PCIE2TBT register
+      //The Boot On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+      //once the Boot On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+      //next step from BIOS is enumeration using SMI
+      //
+
+      if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+        //
+        // Exectue Mail box command "Boot On / Pre-Boot ACL"
+        //
+        //Command may be executed only during boot/reboot and not during Sx exit flow
+        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 1) {
+          if (!TbtSetPcie2TbtCommand(PCIE2TBT_BOOT_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+            //
+            // Nothing to wait, HR is not responsive
+            //
+            DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Boot On message sent failed \n"));
+          }
+        }
+        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2) {
+          if (!TbtSetPcie2TbtCommand(PCIE2TBT_PREBOOTACL, 0xF0, 0, 0, TBT_3S_TIMEOUT)) {
+            //
+            // Nothing to wait, HR is not responsive
+            //
+            DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Pre-Boot ACL message sent failed \n"));
+          }
+        }
+      }
+      //
+      // Reset Sec/Sub buses to original value
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+  DEBUG((DEBUG_INFO, "DTbtBootOn call Return\n"));
+  return Status;
+}
+
+/**
+  Exectue Mail box command "USB On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn(
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  EFI_STATUS                      Status;
+  UINTN                           RpDev;
+  UINTN                           RpFunc;
+  UINT32                          OrgBusNumberConfiguration;
+  UINT64                          TbtBaseAddress;
+  UINT32                          MaxWaitIter;
+  UINT32                          RegVal;
+  EFI_BOOT_MODE                   BootMode;
+
+  DEBUG((DEBUG_INFO, "DTbtUsbOn call Inside\n"));
+
+  Status = EFI_SUCCESS;
+
+      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+      ASSERT_EFI_ERROR(Status);
+      OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+      //
+      // Set Sec/Sub buses to 0xF0
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+      //
+      //When Thunderbolt(TM) Usb boot [TbtUsbOn] is enabled in bios setup we need to do the below:
+      //Bios should send "Usb On" message through PCIE2TBT register
+      //The Usb On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+      //once the Usb On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+      //next step from BIOS is enumeration using SMI
+      //
+      if (PeiTbtConfig->DTbtCommonConfig.TbtUsbOn) {
+        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+          MaxWaitIter = 50;   // Wait 5 sec
+          TbtBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0xF0, 0, 0, 0);
+          //
+          // Driver clears the PCIe2TBT Valid bit to support two consicutive mailbox commands
+          //
+          PciSegmentWrite32(TbtBaseAddress + PCIE2TBT_DTBT_R, 0);
+          DEBUG((DEBUG_INFO, "TbtBaseAddress + PCIE2TBT_DTBT_R = 0x%lx \n", TbtBaseAddress + PCIE2TBT_DTBT_R));
+          while (MaxWaitIter-- > 0) {
+            RegVal = PciSegmentRead32(TbtBaseAddress + TBT2PCIE_DTBT_R);
+            if (0xFFFFFFFF == RegVal) {
+              //
+              // Device is not here return now
+              //
+              DEBUG((DEBUG_INFO, "TBT device is not present \n"));
+              break;
+            }
+
+            if (!(RegVal & TBT2PCIE_DON_R)) {
+              break;
+            }
+            MicroSecondDelay(100 * 1000);
+          }
+        }
+
+        Status = PeiServicesGetBootMode(&BootMode);
+        ASSERT_EFI_ERROR(Status);
+
+        //
+        // Exectue Mail box command "Usb On"
+        //
+        //Command may be executed only during boot/reboot and not during S3 exit flow
+        //In case of S4 Exit send USB ON cmd only if Host Router was inactive/not present during S4 entry
+        if ((BootMode == BOOT_ON_S4_RESUME) ) {
+          // USB_ON cmd not required
+        } else {
+          if (!TbtSetPcie2TbtCommand(PCIE2TBT_USB_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+            //
+            // Nothing to wait, HR is not responsive
+            //
+            DEBUG((DEBUG_INFO, "<TbtPei> TbtBootSupport - Usb On message sent failed \n"));
+          }
+        }
+      }
+      //
+      // Reset Sec/Sub buses to original value
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+  DEBUG((DEBUG_INFO, "DTbtUsbOn call return\n"));
+  return Status;
+}
+
+/**
+  Exectue Mail box command "Sx Exit".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow(
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+)
+{
+  EFI_STATUS                      Status;
+  UINT32                          OrgBusNumberConfiguration;
+  UINTN                           RpDev;
+  UINTN                           RpFunc;
+  UINT32                          Count;
+
+  DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Inside\n"));
+
+  Status = EFI_SUCCESS;
+  Count = 0;
+
+      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+      ASSERT_EFI_ERROR(Status);
+      OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+      //
+      // Set Sec/Sub buses to 0xF0
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+      if ( (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2)) {
+        //
+        // WA: When system with TBT 3.1 device, resume SX system need to wait device ready. In document that maximum time out should be 500ms.
+        //
+        while (PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS(0, 0xf0, 0x0, 0x0, 0x08)) == 0xffffffff) { //End Device will be with Device Number 0x0, Function Number 0x0.
+          MicroSecondDelay(STALL_ONE_MICRO_SECOND * 1000); // 1000usec
+          Count++;
+          if (Count > 10000) { //Allowing Max Delay of 10 sec for CFL-S board.
+          break;
+          }
+        }
+
+        //
+        // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+        // attached devices), BIOS should:
+        // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+        // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+        // 3. Continue regular wake flow.
+        //
+        //
+        // Exectue Mail box command and perform "wait for fast link bring-up" loop
+        //
+        TbtSetSxMode(0xF0, 0, 0, PeiTbtConfig->DTbtCommonConfig.TbtBootOn);
+      }
+      //
+      // Reset Sec/Sub buses to original value
+      //
+      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+  DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Return\n"));
+  return Status;
+}
+
+
+/**
+  Initialize Thunderbolt(TM)
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+EFI_STATUS
+EFIAPI
+TbtInit (
+  VOID
+  )
+{
+  EFI_STATUS            Status;
+  PEI_TBT_POLICY             *PeiTbtConfig;
+
+  //
+  // Get the TBT Policy
+  //
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Exectue Mail box command "Boot On"
+  //
+  Status = DTbtBootOn (PeiTbtConfig);
+  //
+  // Exectue Mail box command "Usb On"
+  //
+  Status = DTbtUsbOn (PeiTbtConfig);
+  //
+  //During boot, reboot and wake  (bits [1:0]) of PCH PM_CFG register should be
+  //set to 11b - 10 ms (default value is 0b - 10 us)
+  //
+  Status = DTbtSetTPch25Timing (PeiTbtConfig);
+  //
+  // Configure Tbt Force Power
+  //
+  Status = DTbtForcePower (PeiTbtConfig);
+  //
+  // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+  // Host router resides should be cleaned
+  //
+  Status = DTbtClearVgaRegisters (PeiTbtConfig);
+  //
+  // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+  // attached devices), BIOS should:
+  // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+  // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+  // 3. Continue regular wake flow.
+  //
+  Status = DTbtSxExitFlow (PeiTbtConfig);
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
new file mode 100644
index 0000000000..f38901f2ae
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
@@ -0,0 +1,461 @@
+/** @file
+  Implementation of Fsp CPU Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <Ppi/SecPlatformInformation2.h>
+
+#include <CpuAccess.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PcdLib.h>
+#include <FspEas.h>
+
+/**
+  Performs FSP CPU PEI Policy initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                      Status;
+  SI_PREMEM_POLICY_PPI            *SiPreMemPolicyPpi;
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverClockingPreMemConfig;
+  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy Pre-Mem Start\n"));
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  SiPreMemPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverClockingPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  ///
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy Pre-Mem End\n"));
+
+  //
+  // Overclocking PreMem policies
+  //
+  FspmUpd->FspmConfig.OcSupport               = (UINT8) CpuOverClockingPreMemConfig->OcSupport;
+  FspmUpd->FspmConfig.OcLock                  = (UINT8) CpuOverClockingPreMemConfig->OcLock;
+  FspmUpd->FspmConfig.CoreMaxOcRatio          = (UINT8) CpuOverClockingPreMemConfig->CoreMaxOcRatio;
+  FspmUpd->FspmConfig.CoreVoltageMode         = (UINT8) CpuOverClockingPreMemConfig->CoreVoltageMode;
+  FspmUpd->FspmConfig.CoreVoltageOverride     = (UINT16) CpuOverClockingPreMemConfig->CoreVoltageOverride;
+  FspmUpd->FspmConfig.CoreVoltageAdaptive     = (UINT16) CpuOverClockingPreMemConfig->CoreVoltageAdaptive;
+  FspmUpd->FspmConfig.CoreVoltageOffset       = (UINT16) CpuOverClockingPreMemConfig->CoreVoltageOffset;
+  FspmUpd->FspmConfig.CorePllVoltageOffset    = (UINT8) CpuOverClockingPreMemConfig->CorePllVoltageOffset;
+  FspmUpd->FspmConfig.RingMaxOcRatio          = (UINT8) CpuOverClockingPreMemConfig->RingMaxOcRatio;
+  FspmUpd->FspmConfig.RingVoltageOverride     = (UINT16) CpuOverClockingPreMemConfig->RingVoltageOverride;
+  FspmUpd->FspmConfig.RingVoltageAdaptive     = (UINT16) CpuOverClockingPreMemConfig->RingVoltageAdaptive;
+  FspmUpd->FspmConfig.RingVoltageOffset       = (UINT16) CpuOverClockingPreMemConfig->RingVoltageOffset;
+  FspmUpd->FspmConfig.RingPllVoltageOffset    = (UINT8) CpuOverClockingPreMemConfig->RingPllVoltageOffset;
+  FspmUpd->FspmConfig.GtPllVoltageOffset      = (UINT8) CpuOverClockingPreMemConfig->GtPllVoltageOffset;
+  FspmUpd->FspmConfig.RingPllVoltageOffset    = (UINT8) CpuOverClockingPreMemConfig->RingPllVoltageOffset;
+  FspmUpd->FspmConfig.SaPllVoltageOffset      = (UINT8) CpuOverClockingPreMemConfig->SaPllVoltageOffset;
+  FspmUpd->FspmConfig.McPllVoltageOffset      = (UINT8) CpuOverClockingPreMemConfig->McPllVoltageOffset;
+  FspmUpd->FspmConfig.RingDownBin             = (UINT8) CpuOverClockingPreMemConfig->RingDownBin;
+  FspmUpd->FspmConfig.RingVoltageMode         = (UINT8) CpuOverClockingPreMemConfig->RingVoltageMode;
+  FspmUpd->FspmConfig.Avx2RatioOffset         = (UINT8) CpuOverClockingPreMemConfig->Avx2RatioOffset;
+  FspmUpd->FspmConfig.Avx3RatioOffset         = (UINT8) CpuOverClockingPreMemConfig->Avx3RatioOffset;
+  FspmUpd->FspmConfig.BclkAdaptiveVoltage     = (UINT8) CpuOverClockingPreMemConfig->BclkAdaptiveVoltage;
+  FspmUpd->FspmConfig.TjMaxOffset             = (UINT8) CpuOverClockingPreMemConfig->TjMaxOffset;
+  FspmUpd->FspmConfig.TvbRatioClipping        = (UINT8) CpuOverClockingPreMemConfig->TvbRatioClipping;
+  FspmUpd->FspmConfig.TvbVoltageOptimization  = (UINT8) CpuOverClockingPreMemConfig->TvbVoltageOptimization;
+
+  //
+  //  Cpu Config Lib policies
+  //
+  FspmUpd->FspmConfig.HyperThreading            = (UINT8) CpuConfigLibPreMemConfig->HyperThreading;
+  FspmUpd->FspmConfig.BootFrequency             = (UINT8) CpuConfigLibPreMemConfig->BootFrequency;
+  FspmUpd->FspmConfig.ActiveCoreCount           = (UINT8) CpuConfigLibPreMemConfig->ActiveCoreCount;
+  FspmUpd->FspmConfig.JtagC10PowerGateDisable   = (UINT8) CpuConfigLibPreMemConfig->JtagC10PowerGateDisable;
+  FspmUpd->FspmConfig.FClkFrequency             = (UINT8) CpuConfigLibPreMemConfig->FClkFrequency;
+  FspmUpd->FspmConfig.BistOnReset               = (UINT8) CpuConfigLibPreMemConfig->BistOnReset;
+  FspmUpd->FspmConfig.VmxEnable                 = (UINT8) CpuConfigLibPreMemConfig->VmxEnable;
+  FspmUpd->FspmConfig.CpuRatio                  = (UINT8) CpuConfigLibPreMemConfig->CpuRatio;
+  FspmUpd->FspmConfig.PeciSxReset               = (UINT8) CpuConfigLibPreMemConfig->PeciSxReset;
+  FspmUpd->FspmConfig.PeciC10Reset              = (UINT8) CpuConfigLibPreMemConfig->PeciC10Reset;
+  FspmUpd->FspmConfig.SkipMpInit                = (UINT8) CpuConfigLibPreMemConfig->SkipMpInit;
+  FspmUpd->FspmConfig.DpSscMarginEnable         = (UINT8) CpuConfigLibPreMemConfig->DpSscMarginEnable;
+
+  //
+  // DisableMtrrProgram <1> Disable Mtrrs program. <0> Program Mtrrs in FSP
+  //
+  FspmUpd->FspmConfig.DisableMtrrProgram        = (UINT8) 0;
+
+  return EFI_SUCCESS;
+}
+
+/**
+ This routine is used to get Sec Platform Information Record2 Pointer.
+
+ @param[in] PeiServices    Pointer to the PEI services table
+
+ @retval GetSecPlatformInformation2 - The pointer of Sec Platform Information Record2 Pointer.
+ **/
+
+EFI_SEC_PLATFORM_INFORMATION_RECORD2 * GetSecPlatformInformation2(
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  EFI_SEC_PLATFORM_INFORMATION2_PPI    *SecPlatformInformation2Ppi;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2 = NULL;
+  UINT64                               InformationSize;
+  EFI_STATUS Status;
+
+  //
+  // Get BIST information from Sec Platform Information2 Ppi firstly
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiSecPlatformInformation2PpiGuid,   // GUID
+             0,                                     // Instance
+             NULL,                                  // EFI_PEI_PPI_DESCRIPTOR
+             (VOID ** ) &SecPlatformInformation2Ppi // PPI
+             );
+
+  DEBUG((DEBUG_INFO, "LocatePpi SecPlatformInformationPpi2 Status - %x\n", Status));
+  if (EFI_ERROR(Status)) {
+    return NULL;
+  }
+
+  InformationSize = 0;
+
+  Status = SecPlatformInformation2Ppi->PlatformInformation2 (
+                                         (CONST EFI_PEI_SERVICES  **) PeiServices,
+                                         &InformationSize,
+                                         SecPlatformInformation2
+                                         );
+
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return NULL;
+  }
+
+  SecPlatformInformation2 = AllocatePool((UINTN)InformationSize);
+  ASSERT (SecPlatformInformation2 != NULL);
+  if (SecPlatformInformation2 == NULL) {
+    return NULL;
+  }
+
+  //
+  // Retrieve BIST data from SecPlatform2
+  //
+  Status = SecPlatformInformation2Ppi->PlatformInformation2 (
+                                         PeiServices,
+                                         &InformationSize,
+                                         SecPlatformInformation2
+                                         );
+  DEBUG((DEBUG_INFO, "SecPlatformInformation2Ppi->PlatformInformation2 Status - %x\n", Status));
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  return SecPlatformInformation2;
+}
+
+/**
+ This routine is used to get Sec Platform Information Record Pointer.
+
+ @param[in] PeiServices    Pointer to the PEI services table
+
+ @retval GetSecPlatformInformation2 - The pointer of Sec Platform Information Record Pointer.
+ **/
+EFI_SEC_PLATFORM_INFORMATION_RECORD2 * GetSecPlatformInformationInfoInFormat2(
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  EFI_SEC_PLATFORM_INFORMATION_PPI     *SecPlatformInformationPpi;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD  *SecPlatformInformation = NULL;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
+  UINT64                               InformationSize;
+  EFI_STATUS                           Status;
+
+  //
+  // Get BIST information from Sec Platform Information
+  //
+  Status = PeiServicesLocatePpi (
+             &gEfiSecPlatformInformationPpiGuid,    // GUID
+             0,                                     // Instance
+             NULL,                                  // EFI_PEI_PPI_DESCRIPTOR
+             (VOID ** ) &SecPlatformInformationPpi  // PPI
+             );
+
+  DEBUG((DEBUG_INFO, "LocatePpi SecPlatformInformationPpi Status - %x\n", Status));
+  if (EFI_ERROR(Status)) {
+    return NULL;
+  }
+
+  InformationSize = 0;
+  Status = SecPlatformInformationPpi->PlatformInformation (
+                                        (CONST EFI_PEI_SERVICES  **) PeiServices,
+                                        &InformationSize,
+                                        SecPlatformInformation
+                                        );
+
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return NULL;
+  }
+
+  SecPlatformInformation = AllocatePool((UINTN)InformationSize);
+  ASSERT (SecPlatformInformation != NULL);
+  if (SecPlatformInformation == NULL) {
+    return NULL;
+  }
+
+  //
+  // Retrieve BIST data from SecPlatform
+  //
+  Status = SecPlatformInformationPpi->PlatformInformation (
+                                        PeiServices,
+                                        &InformationSize,
+                                        SecPlatformInformation
+                                        );
+  DEBUG((DEBUG_INFO, "FSP  SecPlatformInformation2Ppi->PlatformInformation Status - %x\n", Status));
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  SecPlatformInformation2 = AllocatePool(sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2));
+  ASSERT (SecPlatformInformation2 != NULL);
+  if (SecPlatformInformation2 == NULL) {
+    return NULL;
+  }
+
+  SecPlatformInformation2->NumberOfCpus = 1;
+  SecPlatformInformation2->CpuInstance[0].CpuLocation = 0;
+  SecPlatformInformation2->CpuInstance[0].InfoRecord.x64HealthFlags.Uint32 = SecPlatformInformation->x64HealthFlags.Uint32;
+
+  FreePool(SecPlatformInformation);
+
+  return SecPlatformInformation2;
+}
+
+
+/**
+ Performs FSP CPU PEI Policy post memory initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspCpuPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                           Status;
+  SI_POLICY_PPI                        *SiPolicyPpi;
+  CPU_CONFIG                           *CpuConfig;
+  CPU_POWER_MGMT_BASIC_CONFIG          *CpuPowerMgmtBasicConfig;
+  CPU_POWER_MGMT_CUSTOM_CONFIG         *CpuPowerMgmtCustomConfig;
+  CPU_TEST_CONFIG                      *CpuTestConfig;
+  CPU_POWER_MGMT_TEST_CONFIG           *CpuPowerMgmtTestConfig;
+  UINTN                                Index;
+  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
+  EFI_PEI_SERVICES                     **PeiServices;
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy\n"));
+  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
+  //
+  // Locate gSiPolicyPpiGuid
+  //
+  SiPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *) &CpuPowerMgmtCustomConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID *) &CpuTestConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
+  ASSERT_EFI_ERROR (Status);
+  ///
+  ///Production RC Policies
+  ///
+
+  FspsUpd->FspsConfig.AesEnable                 = (UINT8) CpuConfig->AesEnable;
+  FspsUpd->FspsConfig.DebugInterfaceEnable      = (UINT8) CpuConfig->DebugInterfaceEnable;
+
+  FspsUpd->FspsConfig.TurboMode                 = (UINT8) CpuPowerMgmtBasicConfig->TurboMode;
+
+  ///
+  /// Test RC Policies
+  ///
+  FspsUpd->FspsTestConfig.MlcStreamerPrefetcher      = (UINT8) CpuTestConfig->MlcStreamerPrefetcher;
+  FspsUpd->FspsTestConfig.MlcSpatialPrefetcher       = (UINT8) CpuTestConfig->MlcSpatialPrefetcher;
+  FspsUpd->FspsTestConfig.MonitorMwaitEnable         = (UINT8) CpuTestConfig->MonitorMwaitEnable;
+  FspsUpd->FspsTestConfig.DebugInterfaceLockEnable   = (UINT8) CpuTestConfig->DebugInterfaceLockEnable;
+  FspsUpd->FspsTestConfig.ApIdleManner               = PcdGet8 (PcdCpuApLoopMode);
+  FspsUpd->FspsTestConfig.ProcessorTraceOutputScheme = (UINT8) CpuTestConfig->ProcessorTraceOutputScheme;
+  FspsUpd->FspsTestConfig.ProcessorTraceEnable       = (UINT8) CpuTestConfig->ProcessorTraceEnable;
+  FspsUpd->FspsTestConfig.ProcessorTraceMemBase      = CpuTestConfig->ProcessorTraceMemBase;
+  FspsUpd->FspsTestConfig.ProcessorTraceMemLength    = (UINT32) CpuTestConfig->ProcessorTraceMemLength;
+  FspsUpd->FspsTestConfig.VoltageOptimization        = (UINT8) CpuTestConfig->VoltageOptimization;
+  FspsUpd->FspsTestConfig.ThreeStrikeCounterDisable  = (UINT8) CpuTestConfig->ThreeStrikeCounterDisable;
+  FspsUpd->FspsTestConfig.MachineCheckEnable         = (UINT8) CpuTestConfig->MachineCheckEnable;
+  FspsUpd->FspsTestConfig.CpuWakeUpTimer             = (UINT8) CpuTestConfig->CpuWakeUpTimer;
+
+  FspsUpd->FspsTestConfig.OneCoreRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->OneCoreRatioLimit;
+  FspsUpd->FspsTestConfig.TwoCoreRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->TwoCoreRatioLimit;
+  FspsUpd->FspsTestConfig.ThreeCoreRatioLimit        = (UINT8) CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit;
+  FspsUpd->FspsTestConfig.FourCoreRatioLimit         = (UINT8) CpuPowerMgmtBasicConfig->FourCoreRatioLimit;
+  FspsUpd->FspsTestConfig.FiveCoreRatioLimit         = (UINT8) CpuPowerMgmtBasicConfig->FiveCoreRatioLimit;
+  FspsUpd->FspsTestConfig.SixCoreRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->SixCoreRatioLimit;
+  FspsUpd->FspsTestConfig.SevenCoreRatioLimit        = (UINT8) CpuPowerMgmtBasicConfig->SevenCoreRatioLimit;
+  FspsUpd->FspsTestConfig.EightCoreRatioLimit        = (UINT8) CpuPowerMgmtBasicConfig->EightCoreRatioLimit;
+  FspsUpd->FspsTestConfig.Hwp                        = (UINT8) CpuPowerMgmtBasicConfig->Hwp;
+  FspsUpd->FspsTestConfig.HdcControl                 = (UINT8) CpuPowerMgmtBasicConfig->HdcControl;
+  FspsUpd->FspsTestConfig.PowerLimit1Time            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit1Time;
+  FspsUpd->FspsTestConfig.PowerLimit2                = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit2;
+  FspsUpd->FspsTestConfig.TurboPowerLimitLock        = (UINT8) CpuPowerMgmtBasicConfig->TurboPowerLimitLock;
+  FspsUpd->FspsTestConfig.PowerLimit3Time            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit3Time;
+  FspsUpd->FspsTestConfig.PowerLimit3DutyCycle       = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle;
+  FspsUpd->FspsTestConfig.PowerLimit3Lock            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit3Lock;
+  FspsUpd->FspsTestConfig.PowerLimit4Lock            = (UINT8) CpuPowerMgmtBasicConfig->PowerLimit4Lock;
+  FspsUpd->FspsTestConfig.TccActivationOffset        = (UINT8) CpuPowerMgmtBasicConfig->TccActivationOffset;
+  FspsUpd->FspsTestConfig.TccOffsetClamp             = (UINT8) CpuPowerMgmtBasicConfig->TccOffsetClamp;
+  FspsUpd->FspsTestConfig.TccOffsetLock              = (UINT8) CpuPowerMgmtBasicConfig->TccOffsetLock;
+  FspsUpd->FspsTestConfig.PowerLimit1                = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.PowerLimit2Power           = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit2Power * 125);
+  FspsUpd->FspsTestConfig.PowerLimit3                = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit3 * 125);
+  FspsUpd->FspsTestConfig.PowerLimit4                = (UINT32) (CpuPowerMgmtBasicConfig->PowerLimit4 * 125);
+  FspsUpd->FspsTestConfig.TccOffsetTimeWindowForRatl = (UINT32) CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl;
+  FspsUpd->FspsTestConfig.HwpInterruptControl        = (UINT8) CpuPowerMgmtBasicConfig->HwpInterruptControl;
+  FspsUpd->FspsTestConfig.EnableItbm                 = (UINT8) CpuPowerMgmtBasicConfig->EnableItbm;
+  FspsUpd->FspsTestConfig.EnableItbmDriver           = (UINT8) CpuPowerMgmtBasicConfig->EnableItbmDriver;
+  FspsUpd->FspsTestConfig.MinRingRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->MinRingRatioLimit;
+  FspsUpd->FspsTestConfig.MaxRingRatioLimit          = (UINT8) CpuPowerMgmtBasicConfig->MaxRingRatioLimit;
+  FspsUpd->FspsTestConfig.NumberOfEntries             = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries;
+  FspsUpd->FspsTestConfig.Custom1PowerLimit1Time      = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimit1Time;
+  FspsUpd->FspsTestConfig.Custom2PowerLimit1Time      = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimit1Time;
+  FspsUpd->FspsTestConfig.Custom3PowerLimit1Time      = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimit1Time;
+  FspsUpd->FspsTestConfig.Custom1TurboActivationRatio = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomTurboActivationRatio;
+  FspsUpd->FspsTestConfig.Custom2TurboActivationRatio = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomTurboActivationRatio;
+  FspsUpd->FspsTestConfig.Custom3TurboActivationRatio = (UINT8) CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomTurboActivationRatio;
+  FspsUpd->FspsTestConfig.ConfigTdpLock               = (UINT8) CpuPowerMgmtCustomConfig->ConfigTdpLock;
+  FspsUpd->FspsTestConfig.ConfigTdpBios               = (UINT8) CpuPowerMgmtCustomConfig->ConfigTdpBios;
+  FspsUpd->FspsTestConfig.MaxRatio                    = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio;
+  for (Index = 0; Index < CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries; Index++) {
+    FspsUpd->FspsTestConfig.StateRatio[Index]         = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index];
+  }
+  for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+    FspsUpd->FspsTestConfig.StateRatioMax16[Index]    = (UINT8) CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index];
+  }
+  FspsUpd->FspsTestConfig.Custom1PowerLimit1          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.Custom1PowerLimit2          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimit2 * 125);
+  FspsUpd->FspsTestConfig.Custom2PowerLimit1          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.Custom2PowerLimit2          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimit2 * 125);
+  FspsUpd->FspsTestConfig.Custom3PowerLimit1          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimit1 * 125);
+  FspsUpd->FspsTestConfig.Custom3PowerLimit2          = (UINT32) (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimit2 * 125);
+
+  FspsUpd->FspsTestConfig.Eist                          = (UINT8) CpuPowerMgmtTestConfig->Eist;
+  FspsUpd->FspsTestConfig.EnergyEfficientPState         = (UINT8) CpuPowerMgmtTestConfig->EnergyEfficientPState;
+  FspsUpd->FspsTestConfig.EnergyEfficientTurbo          = (UINT8) CpuPowerMgmtTestConfig->EnergyEfficientTurbo;
+  FspsUpd->FspsTestConfig.TStates                       = (UINT8) CpuPowerMgmtTestConfig->TStates;
+  FspsUpd->FspsTestConfig.BiProcHot                     = (UINT8) CpuPowerMgmtTestConfig->BiProcHot;
+  FspsUpd->FspsTestConfig.DisableProcHotOut             = (UINT8) CpuPowerMgmtTestConfig->DisableProcHotOut;
+  FspsUpd->FspsTestConfig.ProcHotResponse               = (UINT8) CpuPowerMgmtTestConfig->ProcHotResponse;
+  FspsUpd->FspsTestConfig.DisableVrThermalAlert         = (UINT8) CpuPowerMgmtTestConfig->DisableVrThermalAlert;
+  FspsUpd->FspsTestConfig.AutoThermalReporting          = (UINT8) CpuPowerMgmtTestConfig->AutoThermalReporting;
+  FspsUpd->FspsTestConfig.ThermalMonitor                = (UINT8) CpuPowerMgmtTestConfig->ThermalMonitor;
+  FspsUpd->FspsTestConfig.Cx                            = (UINT8) CpuPowerMgmtTestConfig->Cx;
+  FspsUpd->FspsTestConfig.PmgCstCfgCtrlLock             = (UINT8) CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock;
+  FspsUpd->FspsTestConfig.C1e                           = (UINT8) CpuPowerMgmtTestConfig->C1e;
+  FspsUpd->FspsTestConfig.C1StateAutoDemotion           = (UINT8) CpuPowerMgmtTestConfig->C1AutoDemotion;
+  FspsUpd->FspsTestConfig.C1StateUnDemotion             = (UINT8) CpuPowerMgmtTestConfig->C1UnDemotion;
+  FspsUpd->FspsTestConfig.C3StateAutoDemotion           = (UINT8) CpuPowerMgmtTestConfig->C3AutoDemotion;
+  FspsUpd->FspsTestConfig.C3StateUnDemotion             = (UINT8) CpuPowerMgmtTestConfig->C3UnDemotion;
+  FspsUpd->FspsTestConfig.CstateLatencyControl0TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl0Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl;
+  FspsUpd->FspsTestConfig.PkgCStateDemotion             = (UINT8) CpuPowerMgmtTestConfig->PkgCStateDemotion;
+  FspsUpd->FspsTestConfig.PkgCStateUnDemotion           = (UINT8) CpuPowerMgmtTestConfig->PkgCStateUnDemotion;
+  FspsUpd->FspsTestConfig.CStatePreWake                 = (UINT8) CpuPowerMgmtTestConfig->CStatePreWake;
+  FspsUpd->FspsTestConfig.TimedMwait                    = (UINT8) CpuPowerMgmtTestConfig->TimedMwait;
+  FspsUpd->FspsTestConfig.CstCfgCtrIoMwaitRedirection   = (UINT8) CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection;
+  FspsUpd->FspsTestConfig.PkgCStateLimit                = (UINT8) CpuPowerMgmtTestConfig->PkgCStateLimit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl1TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl2TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl3TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl4TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit;
+  FspsUpd->FspsTestConfig.CstateLatencyControl5TimeUnit = (UINT8) CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit;
+  FspsUpd->FspsTestConfig.PpmIrmSetting                 = (UINT8) CpuPowerMgmtTestConfig->PpmIrmSetting;
+  FspsUpd->FspsTestConfig.ProcHotLock                   = (UINT8) CpuPowerMgmtTestConfig->ProcHotLock;
+  FspsUpd->FspsTestConfig.RaceToHalt                    = (UINT8) CpuPowerMgmtTestConfig->RaceToHalt;
+  FspsUpd->FspsTestConfig.ConfigTdpLevel                = (UINT8) CpuPowerMgmtTestConfig->ConfigTdpLevel;
+  FspsUpd->FspsTestConfig.CstateLatencyControl1Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl2Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl3Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl4Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl;
+  FspsUpd->FspsTestConfig.CstateLatencyControl5Irtl     = (UINT16) CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl;
+
+  //
+  // Get BIST information from Sec Platform Information
+  //
+  SecPlatformInformation2 = GetSecPlatformInformation2 (PeiServices);
+  if (SecPlatformInformation2 == NULL) {
+    SecPlatformInformation2 = GetSecPlatformInformationInfoInFormat2 (PeiServices);
+  }
+
+  ASSERT (SecPlatformInformation2 != NULL);
+
+  if (SecPlatformInformation2 != NULL) {
+    FspsUpd->FspsConfig.CpuBistData = (UINT32)SecPlatformInformation2;
+    DEBUG((DEBUG_INFO, "SecPlatformInformation NumberOfCpus - %x\n", SecPlatformInformation2->NumberOfCpus));
+    DEBUG ((DEBUG_INFO, "SecPlatformInformation BIST - %x\n", SecPlatformInformation2->CpuInstance[0].InfoRecord.x64HealthFlags.Uint32));
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c
new file mode 100644
index 0000000000..97d9842aff
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c
@@ -0,0 +1,121 @@
+/** @file
+  Implementation of Fsp Me Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <ConfigBlock/MePeiConfig.h>
+#include <Ppi/SiPolicy.h>
+
+/**
+  Performs FSP ME PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_PREMEM_POLICY_PPI      *SiPreMemPolicy;
+  ME_PEI_PREMEM_CONFIG      *MePeiPreMemConfig;
+
+  DEBUG ((DEBUG_INFO, "PeiFspMePolicyInitPreMem\n"));
+
+  //
+  // Locate gSiPreMemPolicyPpi
+  //
+  SiPreMemPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  FspmUpd->FspmConfig.HeciTimeouts                      = (UINT8)  MePeiPreMemConfig->HeciTimeouts;
+  //
+  // Test policies
+  //
+  FspmUpd->FspmTestConfig.DidInitStat                   = (UINT8) MePeiPreMemConfig->DidInitStat;
+  FspmUpd->FspmTestConfig.DisableCpuReplacedPolling     = (UINT8) MePeiPreMemConfig->DisableCpuReplacedPolling;
+  FspmUpd->FspmTestConfig.SendDidMsg                    = (UINT8) MePeiPreMemConfig->SendDidMsg;
+  FspmUpd->FspmTestConfig.DisableHeciRetry              = (UINT8) MePeiPreMemConfig->DisableHeciRetry;
+  FspmUpd->FspmTestConfig.DisableMessageCheck           = (UINT8) MePeiPreMemConfig->DisableMessageCheck;
+  FspmUpd->FspmTestConfig.SkipMbpHob                    = (UINT8) MePeiPreMemConfig->SkipMbpHob;
+
+  FspmUpd->FspmTestConfig.HeciCommunication2            = (UINT8) MePeiPreMemConfig->HeciCommunication2;
+  FspmUpd->FspmTestConfig.KtDeviceEnable                = (UINT8) MePeiPreMemConfig->KtDeviceEnable;
+
+  FspmUpd->FspmConfig.Heci1BarAddress                   = MePeiPreMemConfig->Heci1BarAddress;
+  FspmUpd->FspmConfig.Heci2BarAddress                   = MePeiPreMemConfig->Heci2BarAddress;
+  FspmUpd->FspmConfig.Heci3BarAddress                   = MePeiPreMemConfig->Heci3BarAddress;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP ME PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMePolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_POLICY_PPI             *SiPolicyPpi;
+  ME_PEI_CONFIG             *MePeiConfig;
+
+  DEBUG ((DEBUG_INFO, "PeiFspMePolicyInit \n"));
+  //
+  // Locate gSiPolicyPpiGuid
+  //
+  SiPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  FspsUpd->FspsConfig.Heci3Enabled                  = (UINT8) MePeiConfig->Heci3Enabled;
+  FspsUpd->FspsConfig.MeUnconfigOnRtcClear          = (UINT8) MePeiConfig->MeUnconfigOnRtcClear;
+
+  //
+  // Test policies
+  //
+  FspsUpd->FspsTestConfig.MctpBroadcastCycle        = (UINT8) MePeiConfig->MctpBroadcastCycle;
+  FspsUpd->FspsTestConfig.EndOfPostMessage          = (UINT8) MePeiConfig->EndOfPostMessage;
+  FspsUpd->FspsTestConfig.DisableD0I3SettingForHeci = (UINT8) MePeiConfig->DisableD0I3SettingForHeci;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c
new file mode 100644
index 0000000000..9545e3df0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c
@@ -0,0 +1,77 @@
+/** @file
+  Implementation of Fsp Misc UPD Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+
+#define STATUS_CODE_USE_RAM        BIT0
+#define STATUS_CODE_USE_ISA_SERIAL BIT1
+#define STATUS_CODE_USE_USB        BIT2
+#define STATUS_CODE_USE_USB3       BIT3
+#define STATUS_CODE_USE_SERIALIO   BIT4
+#define STATUS_CODE_USE_TRACEHUB   BIT5
+#define STATUS_CODE_CMOS_INVALID   BIT6
+#define STATUS_CODE_CMOS_VALID     BIT7
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_PEI_HOB_POINTERS              Hob;
+  DEBUG_CONFIG_DATA_HOB             *DebugConfigData;
+  UINT8                             DebugInterfaces;
+
+  FspmUpd->FspmArchUpd.StackBase = (VOID *)(UINTN)(PcdGet32(PcdTemporaryRamBase) + PcdGet32(PcdTemporaryRamSize) - (PcdGet32(PcdFspTemporaryRamSize) + PcdGet32(PcdFspReservedBufferSize)));
+  FspmUpd->FspmArchUpd.StackSize = PcdGet32(PcdFspTemporaryRamSize);
+
+  Status = PeiServicesGetBootMode (&(FspmUpd->FspmArchUpd.BootMode));
+  if (EFI_ERROR (Status)) {
+    FspmUpd->FspmArchUpd.BootMode = BOOT_WITH_FULL_CONFIGURATION;
+  }
+
+  FspmUpd->FspmArchUpd.BootLoaderTolumSize = 0x0;
+
+  //
+  // Initialize DebugConfigData
+  //
+  DebugInterfaces = 0x00;
+  Hob.Guid = GetFirstGuidHob (&gDebugConfigHobGuid);
+  if (Hob.Guid != NULL) {
+    DebugConfigData = (DEBUG_CONFIG_DATA_HOB *) GET_GUID_HOB_DATA (Hob.Guid);
+    if (DebugConfigData != NULL) {
+      // Debug Interfaces
+      if (DebugConfigData->RamDebugInterface)      { DebugInterfaces |= STATUS_CODE_USE_RAM; }
+      if (DebugConfigData->UartDebugInterface)     { DebugInterfaces |= STATUS_CODE_USE_ISA_SERIAL; }
+      if (DebugConfigData->Usb3DebugInterface)     { DebugInterfaces |= STATUS_CODE_USE_USB3; }
+      if (DebugConfigData->SerialIoDebugInterface) { DebugInterfaces |= STATUS_CODE_USE_SERIALIO; }
+      if (DebugConfigData->TraceHubDebugInterface) { DebugInterfaces |= STATUS_CODE_USE_TRACEHUB; }
+      FspmUpd->FspmConfig.PcdDebugInterfaceFlags  = DebugInterfaces;
+      // Serial debug message baud rate
+      FspmUpd->FspmConfig.PcdSerialDebugBaudRate  = DebugConfigData->SerialDebugBaudRate;
+      //Serial debug message level
+      FspmUpd->FspmConfig.PcdSerialDebugLevel     = DebugConfigData->SerialDebug;
+    }
+  }
+  DEBUG ((DEBUG_INFO, "FspmConfig.PcdDebugInterfaceFlags is 0x%X\n", FspmUpd->FspmConfig.PcdDebugInterfaceFlags));
+  DEBUG ((DEBUG_INFO, "FspmUpd->FspmConfig.PcdSerialDebugBaudRate is 0x%X\n", FspmUpd->FspmConfig.PcdSerialDebugBaudRate));
+  DEBUG ((DEBUG_INFO, "FspmUpd->FspmConfig.PcdSerialDebugLevel is 0x%X\n", FspmUpd->FspmConfig.PcdSerialDebugLevel));
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c
new file mode 100644
index 0000000000..e2022929cd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c
@@ -0,0 +1,736 @@
+/** @file
+  Implementation of Fsp PCH Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PchInfoLib.h>
+
+/**
+  Performs FSP PCH PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                       Status;
+  UINTN                            Index;
+  UINTN                            MaxPcieRootPorts;
+  SI_PREMEM_POLICY_PPI             *SiPreMemPolicy;
+  PCH_TRACE_HUB_PREMEM_CONFIG      *PchTraceHubPreMemConfig;
+  PCH_SMBUS_PREMEM_CONFIG          *SmbusPreMemConfig;
+  PCH_DCI_PREMEM_CONFIG            *DciPreMemConfig;
+  PCH_HSIO_PCIE_PREMEM_CONFIG      *HsioPciePreMemConfig;
+  PCH_HSIO_SATA_PREMEM_CONFIG      *HsioSataPreMemConfig;
+  PCH_PCIE_RP_PREMEM_CONFIG        *PcieRpPreMemConfig;
+  PCH_LPC_PREMEM_CONFIG            *LpcPreMemConfig;
+  PCH_GENERAL_PREMEM_CONFIG        *PchGeneralPreMemConfig;
+  PCH_WDT_PREMEM_CONFIG            *WdtPreMemConfig;
+  PCH_HDAUDIO_PREMEM_CONFIG        *HdaPreMemConfig;
+  PCH_ISH_PREMEM_CONFIG            *IshPreMemConfig;
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP UpdatePeiPchPolicyPreMem\n"));
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "FspmUpd = 0x%x\n", FspmUpd));
+  //
+  // Locate PchPreMemPolicyPpi
+  //
+  SiPreMemPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ UpdatePeiPchPolicyPreMem\n"));
+  //
+  // Update PCIE RP policies
+  //
+//  MaxPcieRootPorts = 16;
+
+  MaxPcieRootPorts = GetPchMaxPciePortNum ();
+//  MaxPcieRootPorts = 16;
+  FspmUpd->FspmConfig.PcieRpEnableMask = PcieRpPreMemConfig->RpEnabledMask & ((1 << MaxPcieRootPorts) - 1);
+  FspmUpd->FspmConfig.PcieImrEnabled = PcieRpPreMemConfig->PcieImrEnabled;
+  FspmUpd->FspmConfig.PcieImrSize = PcieRpPreMemConfig->PcieImrSize;
+  FspmUpd->FspmConfig.ImrRpSelection = PcieRpPreMemConfig->ImrRpSelection;
+  //
+  // Update TraceHub policies
+  //
+  FspmUpd->FspmConfig.PchTraceHubMode = (UINT8) PchTraceHubPreMemConfig->EnableMode;
+  FspmUpd->FspmConfig.PchTraceHubMemReg0Size = (UINT8) PchTraceHubPreMemConfig->MemReg0Size;
+  FspmUpd->FspmConfig.PchTraceHubMemReg1Size = (UINT8) PchTraceHubPreMemConfig->MemReg1Size;
+
+  //
+  // Update Smbus policies
+  //
+  FspmUpd->FspmConfig.SmbusEnable = (UINT8)SmbusPreMemConfig->Enable;
+  FspmUpd->FspmConfig.SmbusArpEnable = (UINT8)SmbusPreMemConfig->ArpEnable;
+  FspmUpd->FspmTestConfig.SmbusDynamicPowerGating = (UINT8)SmbusPreMemConfig->DynamicPowerGating;
+  FspmUpd->FspmTestConfig.SmbusSpdWriteDisable = (UINT8)SmbusPreMemConfig->SpdWriteDisable;
+  FspmUpd->FspmConfig.PchSmbAlertEnable = (UINT8)SmbusPreMemConfig->SmbAlertEnable;
+  FspmUpd->FspmConfig.PchSmbusIoBase = (UINT16)SmbusPreMemConfig->SmbusIoBase;
+  FspmUpd->FspmConfig.PchNumRsvdSmbusAddresses = (UINT8)SmbusPreMemConfig->NumRsvdSmbusAddresses;
+  FspmUpd->FspmConfig.RsvdSmbusAddressTablePtr = (UINT32)SmbusPreMemConfig->RsvdSmbusAddressTable;
+
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ1 UpdatePeiPchPolicyPreMem\n"));
+  //
+  // Update Dci policies
+  //
+  FspmUpd->FspmConfig.PlatformDebugConsent = (UINT8)DciPreMemConfig->PlatformDebugConsent;
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ11 UpdatePeiPchPolicyPreMem\n"));
+  FspmUpd->FspmConfig.DciUsb3TypecUfpDbg = (UINT8)DciPreMemConfig->DciUsb3TypecUfpDbg;
+  //
+  // Update HSIO PCIE policies
+  //
+  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
+    FspmUpd->FspmConfig.PchPcieHsioRxSetCtleEnable[Index]           = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable;
+    FspmUpd->FspmConfig.PchPcieHsioRxSetCtle[Index]                 = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DownscaleAmpEnable[Index]  = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DownscaleAmp[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DownscaleAmpEnable[Index]  = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DownscaleAmp[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen3DownscaleAmpEnable[Index]  = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen3DownscaleAmp[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DeEmphEnable[Index]        = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen1DeEmph[Index]              = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph3p5Enable[Index]     = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph3p5[Index]           = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph6p0Enable[Index]     = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable;
+    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph6p0[Index]           = (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0;
+  }
+
+  //
+  // Update HSIO SATA policies
+  //
+  for (Index = 0; Index < PCH_MAX_SATA_PORTS; Index ++) {
+    FspmUpd->FspmConfig.PchSataHsioRxGen1EqBoostMagEnable[Index]    = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEnable;
+    FspmUpd->FspmConfig.PchSataHsioRxGen1EqBoostMag[Index]          = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag;
+    FspmUpd->FspmConfig.PchSataHsioRxGen2EqBoostMagEnable[Index]    = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEnable;
+    FspmUpd->FspmConfig.PchSataHsioRxGen2EqBoostMag[Index]          = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag;
+    FspmUpd->FspmConfig.PchSataHsioRxGen3EqBoostMagEnable[Index]    = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEnable;
+    FspmUpd->FspmConfig.PchSataHsioRxGen3EqBoostMag[Index]          = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DownscaleAmpEnable[Index]  = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DownscaleAmp[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DownscaleAmpEnable[Index]  = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DownscaleAmp[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DownscaleAmpEnable[Index]  = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmpEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DownscaleAmp[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DeEmphEnable[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen1DeEmph[Index]              = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DeEmphEnable[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen2DeEmph[Index]              = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DeEmphEnable[Index]        = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable;
+    FspmUpd->FspmConfig.PchSataHsioTxGen3DeEmph[Index]              = (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph;
+  }
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ2 UpdatePeiPchPolicyPreMem\n"));
+  // Update LPC policies
+  //
+  FspmUpd->FspmConfig.PchLpcEnhancePort8xhDecoding = (UINT8)LpcPreMemConfig->EnhancePort8xhDecoding;
+
+  //
+  // Update Pch General Premem policies
+  //
+  FspmUpd->FspmConfig.PchPort80Route = (UINT8)PchGeneralPreMemConfig->Port80Route;
+
+  //
+  // Update Wdt policies
+  //
+  FspmUpd->FspmTestConfig.WdtDisableAndLock = (UINT8)WdtPreMemConfig->DisableAndLock;
+
+  //
+  // HdAudioConfig
+  //
+  FspmUpd->FspmConfig.PchHdaEnable = (UINT8)HdaPreMemConfig->Enable;
+
+  //
+  // IshConfig
+  //
+  FspmUpd->FspmConfig.PchIshEnable = (UINT8)IshPreMemConfig->Enable;
+
+  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ3 UpdatePeiPchPolicyPreMem\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                   Status;
+  UINTN                        Index;
+  UINTN                        MaxPcieRootPorts;
+  UINT8                        Data8;
+  SI_POLICY_PPI                *SiPolicy;
+  PCH_LAN_CONFIG               *LanConfig;
+  PCH_HDAUDIO_CONFIG           *HdAudioConfig;
+  PCH_SCS_CONFIG               *ScsConfig;
+  PCH_ISH_CONFIG               *IshConfig;
+  PCH_SATA_CONFIG              *SataConfig;
+  USB_CONFIG                   *UsbConfig;
+  PCH_SERIAL_IO_CONFIG         *SerialIoConfig;
+  PCH_INTERRUPT_CONFIG         *InterruptConfig;
+  PCH_LOCK_DOWN_CONFIG         *LockDownConfig;
+  PCH_CNVI_CONFIG              *CnviConfig;
+  PCH_HSIO_CONFIG              *HsioConfig;
+  PCH_ESPI_CONFIG              *EspiConfig;
+  PCH_PCIE_CONFIG              *PcieRpConfig;
+  PCH_DMI_CONFIG               *DmiConfig;
+  PCH_FLASH_PROTECTION_CONFIG  *FlashProtectionConfig;
+  PCH_IOAPIC_CONFIG            *IoApicConfig;
+  PCH_P2SB_CONFIG              *P2sbConfig;
+  PCH_GENERAL_CONFIG           *PchGeneralConfig;
+  PCH_PM_CONFIG                *PmConfig;
+  PCH_LPC_SIRQ_CONFIG          *PchSerialIrqConfig;
+  PCH_THERMAL_CONFIG           *PchThermalConfig;
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP UpdatePeiPchPolicy\n"));
+  //
+  // Locate SiPolicyPpi
+  //
+  SiPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLanConfigGuid, (VOID *) &LanConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gHdAudioConfigGuid, (VOID *) &HdAudioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gScsConfigGuid, (VOID *) &ScsConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIshConfigGuid, (VOID *) &IshConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *) &SataConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gUsbConfigGuid, (VOID *) &UsbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIoConfigGuid, (VOID *) &SerialIoConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gDmiConfigGuid, (VOID *) &DmiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gP2sbConfigGuid, (VOID *) &P2sbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIrqConfigGuid, (VOID *) &PchSerialIrqConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gThermalConfigGuid, (VOID *) &PchThermalConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gCnviConfigGuid, (VOID *) &CnviConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gHsioConfigGuid, (VOID *) &HsioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gEspiConfigGuid, (VOID *) &EspiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update LAN policies
+  //
+  FspsUpd->FspsConfig.PchLanEnable          = (UINT8)LanConfig->Enable;
+  FspsUpd->FspsConfig.PchLanLtrEnable       = (UINT8)LanConfig->LtrEnable;
+
+  //
+  // Update HDA policies
+  //
+  FspsUpd->FspsConfig.PchHdaDspEnable             = (UINT8)HdAudioConfig->DspEnable;
+  FspsUpd->FspsConfig.PchHdaPme                   = (UINT8)HdAudioConfig->Pme;
+  FspsUpd->FspsConfig.PchHdaVcType                = (UINT8)HdAudioConfig->VcType;
+  FspsUpd->FspsConfig.PchHdaLinkFrequency         = (UINT8)HdAudioConfig->HdAudioLinkFrequency;
+  FspsUpd->FspsConfig.PchHdaIDispLinkFrequency    = (UINT8)HdAudioConfig->IDispLinkFrequency;
+  FspsUpd->FspsConfig.PchHdaIDispLinkTmode        = (UINT8)HdAudioConfig->IDispLinkTmode;
+  FspsUpd->FspsConfig.PchHdaDspUaaCompliance      = (UINT8)HdAudioConfig->DspUaaCompliance;
+  FspsUpd->FspsConfig.PchHdaIDispCodecDisconnect  = (UINT8)HdAudioConfig->IDispCodecDisconnect;
+  FspsUpd->FspsConfig.PchHdaCodecSxWakeCapability = (UINT8)HdAudioConfig->CodecSxWakeCapability;
+  FspsUpd->FspsTestConfig.PchHdaResetWaitTimer    = (UINT16)HdAudioConfig->ResetWaitTimer;
+  FspsUpd->FspsConfig.PchHdaVerbTableEntryNum     = HdAudioConfig->VerbTableEntryNum;
+  FspsUpd->FspsConfig.PchHdaVerbTablePtr          = HdAudioConfig->VerbTablePtr;
+  FspsUpd->FspsConfig.PchHdaAudioLinkHda          = (UINT8)HdAudioConfig->AudioLinkHda;
+  FspsUpd->FspsConfig.PchHdaAudioLinkDmic0        = (UINT8)HdAudioConfig->AudioLinkDmic0;
+  FspsUpd->FspsConfig.PchHdaAudioLinkDmic1        = (UINT8)HdAudioConfig->AudioLinkDmic1;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSsp0         = (UINT8)HdAudioConfig->AudioLinkSsp0;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSsp1         = (UINT8)HdAudioConfig->AudioLinkSsp1;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSsp2         = (UINT8)HdAudioConfig->AudioLinkSsp2;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw1        = (UINT8)HdAudioConfig->AudioLinkSndw1;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw2        = (UINT8)HdAudioConfig->AudioLinkSndw2;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw3        = (UINT8)HdAudioConfig->AudioLinkSndw3;
+  FspsUpd->FspsConfig.PchHdaAudioLinkSndw4        = (UINT8)HdAudioConfig->AudioLinkSndw4;
+  FspsUpd->FspsConfig.PchHdaSndwBufferRcomp       = (UINT8)HdAudioConfig->SndwBufferRcomp;
+
+  //
+  // Update SCS policies
+  //
+  FspsUpd->FspsConfig.ScsEmmcEnabled = (UINT8)ScsConfig->ScsEmmcEnabled;
+  FspsUpd->FspsConfig.ScsEmmcHs400Enabled = (UINT8)ScsConfig->ScsEmmcHs400Enabled;
+  FspsUpd->FspsConfig.ScsSdCardEnabled = (UINT8)ScsConfig->ScsSdcardEnabled;
+  FspsUpd->FspsConfig.SdCardPowerEnableActiveHigh = (UINT8)ScsConfig->SdCardPowerEnableActiveHigh;
+#ifdef CFL_SIMICS
+  FspsUpd->FspsConfig.ScsUfsEnabled    = 0;
+#else
+  FspsUpd->FspsConfig.ScsUfsEnabled    = (UINT8)ScsConfig->ScsUfsEnabled;
+#endif
+  FspsUpd->FspsConfig.PchScsEmmcHs400TuningRequired = (UINT8)ScsConfig->ScsEmmcHs400TuningRequired;
+  FspsUpd->FspsConfig.PchScsEmmcHs400DllDataValid   = (UINT8)ScsConfig->ScsEmmcHs400DllDataValid;
+  FspsUpd->FspsConfig.PchScsEmmcHs400RxStrobeDll1   = (UINT8)ScsConfig->ScsEmmcHs400RxStrobeDll1;
+  FspsUpd->FspsConfig.PchScsEmmcHs400TxDataDll      = (UINT8)ScsConfig->ScsEmmcHs400TxDataDll;
+  FspsUpd->FspsConfig.PchScsEmmcHs400DriverStrength = (UINT8)ScsConfig->ScsEmmcHs400DriverStrength;
+
+  //
+  // Update ISH policies
+  //
+  FspsUpd->FspsConfig.PchIshSpiGpioAssign   = (UINT8)IshConfig->SpiGpioAssign;
+  FspsUpd->FspsConfig.PchIshUart0GpioAssign = (UINT8)IshConfig->Uart0GpioAssign;
+  FspsUpd->FspsConfig.PchIshUart1GpioAssign = (UINT8)IshConfig->Uart1GpioAssign;
+  FspsUpd->FspsConfig.PchIshI2c0GpioAssign  = (UINT8)IshConfig->I2c0GpioAssign;
+  FspsUpd->FspsConfig.PchIshI2c1GpioAssign  = (UINT8)IshConfig->I2c1GpioAssign;
+  FspsUpd->FspsConfig.PchIshI2c2GpioAssign  = (UINT8)IshConfig->I2c2GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp0GpioAssign   = (UINT8)IshConfig->Gp0GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp1GpioAssign   = (UINT8)IshConfig->Gp1GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp2GpioAssign   = (UINT8)IshConfig->Gp2GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp3GpioAssign   = (UINT8)IshConfig->Gp3GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp4GpioAssign   = (UINT8)IshConfig->Gp4GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp5GpioAssign   = (UINT8)IshConfig->Gp5GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp6GpioAssign   = (UINT8)IshConfig->Gp6GpioAssign;
+  FspsUpd->FspsConfig.PchIshGp7GpioAssign   = (UINT8)IshConfig->Gp7GpioAssign;
+  FspsUpd->FspsConfig.PchIshPdtUnlock       = (UINT8)IshConfig->PdtUnlock;
+
+  //
+  // Update PCIE RP RootPort policies
+  //
+  MaxPcieRootPorts = GetPchMaxPciePortNum ();
+  FspsUpd->FspsConfig.PcieRpDpcMask = 0;
+  FspsUpd->FspsConfig.PcieRpDpcExtensionsMask = 0;
+  FspsUpd->FspsConfig.PcieRpPtmMask = 0;
+  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
+    FspsUpd->FspsConfig.PcieRpHotPlug[Index] = (UINT8)PcieRpConfig->RootPort[Index].HotPlug;
+    FspsUpd->FspsConfig.PcieRpSlotImplemented[Index] = (UINT8)PcieRpConfig->RootPort[Index].SlotImplemented;
+    FspsUpd->FspsConfig.PcieRpPmSci[Index] = (UINT8)PcieRpConfig->RootPort[Index].PmSci;
+    FspsUpd->FspsConfig.PcieRpExtSync[Index] = (UINT8)PcieRpConfig->RootPort[Index].ExtSync;
+    FspsUpd->FspsConfig.PcieRpTransmitterHalfSwing[Index] = (UINT8)PcieRpConfig->RootPort[Index].TransmitterHalfSwing;
+    FspsUpd->FspsConfig.PcieRpClkReqDetect[Index] = (UINT8)PcieRpConfig->RootPort[Index].ClkReqDetect;
+    FspsUpd->FspsConfig.PcieRpAdvancedErrorReporting[Index] = (UINT8)PcieRpConfig->RootPort[Index].AdvancedErrorReporting;
+    FspsUpd->FspsConfig.PcieRpUnsupportedRequestReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].UnsupportedRequestReport;
+    FspsUpd->FspsConfig.PcieRpFatalErrorReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].FatalErrorReport;
+    FspsUpd->FspsConfig.PcieRpNoFatalErrorReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].NoFatalErrorReport;
+    FspsUpd->FspsConfig.PcieRpCorrectableErrorReport[Index] = (UINT8)PcieRpConfig->RootPort[Index].CorrectableErrorReport;
+    FspsUpd->FspsConfig.PcieRpSystemErrorOnFatalError[Index] = (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnFatalError;
+    FspsUpd->FspsConfig.PcieRpSystemErrorOnNonFatalError[Index] = (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnNonFatalError;
+    FspsUpd->FspsConfig.PcieRpSystemErrorOnCorrectableError[Index] = (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnCorrectableError;
+    FspsUpd->FspsConfig.PcieRpMaxPayload[Index] = (UINT8)PcieRpConfig->RootPort[Index].MaxPayload;
+    if (PcieRpConfig->RootPort[Index].DpcEnabled) {
+      FspsUpd->FspsConfig.PcieRpDpcMask |= (BIT0<<Index);
+    }
+    if (PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled) {
+      FspsUpd->FspsConfig.PcieRpDpcExtensionsMask |= (BIT0<<Index);
+    }
+    if (PcieRpConfig->RootPort[Index].PtmEnabled) {
+      FspsUpd->FspsConfig.PcieRpPtmMask |= (BIT0<<Index);
+    }
+    FspsUpd->FspsConfig.PcieRpPcieSpeed[Index] = (UINT8)PcieRpConfig->RootPort[Index].PcieSpeed;
+    FspsUpd->FspsConfig.PcieRpGen3EqPh3Method[Index] = (UINT8)PcieRpConfig->RootPort[Index].Gen3EqPh3Method;
+    FspsUpd->FspsConfig.PcieRpPhysicalSlotNumber[Index] = (UINT8)PcieRpConfig->RootPort[Index].PhysicalSlotNumber;
+    FspsUpd->FspsConfig.PcieRpCompletionTimeout[Index] = (UINT8)PcieRpConfig->RootPort[Index].CompletionTimeout;
+    FspsUpd->FspsConfig.PcieRpAspm[Index] = (UINT8)PcieRpConfig->RootPort[Index].Aspm;
+    FspsUpd->FspsConfig.PcieRpL1Substates[Index] = (UINT8)PcieRpConfig->RootPort[Index].L1Substates;
+    FspsUpd->FspsConfig.PcieRpLtrEnable[Index] = (UINT8)PcieRpConfig->RootPort[Index].LtrEnable;
+    FspsUpd->FspsConfig.PcieRpLtrConfigLock[Index] = (UINT8)PcieRpConfig->RootPort[Index].LtrConfigLock;
+    FspsUpd->FspsConfig.PcieRpAcsEnabled[Index] = (UINT8)PcieRpConfig->RootPort[Index].AcsEnabled;
+    FspsUpd->FspsConfig.PcieRpDetectTimeoutMs[Index] = (UINT16)PcieRpConfig->RootPort[Index].DetectTimeoutMs;
+    FspsUpd->FspsConfig.PcieRootPortGen2PllL1CgDisable[Index] = (UINT8)PcieRpConfig->RootPort[Index].PcieRootPortGen2PllL1CgDisable;
+
+    FspsUpd->FspsTestConfig.PcieRpLtrMaxSnoopLatency[Index] = (UINT16)PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency;
+    FspsUpd->FspsTestConfig.PcieRpLtrMaxNoSnoopLatency[Index] = (UINT16)PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency;
+
+    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideMode[Index] = (UINT8)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode;
+    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideMultiplier[Index] = (UINT8)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier;
+    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideValue[Index] = (UINT16)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue;
+
+    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideMode[Index] = (UINT8)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode;
+    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideMultiplier[Index] = (UINT8)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier;
+    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideValue[Index] = (UINT16)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue;
+
+    FspsUpd->FspsTestConfig.PcieRpSlotPowerLimitScale[Index] = (UINT8)PcieRpConfig->RootPort[Index].SlotPowerLimitScale;
+    FspsUpd->FspsTestConfig.PcieRpSlotPowerLimitValue[Index] = (UINT16)PcieRpConfig->RootPort[Index].SlotPowerLimitValue;
+    FspsUpd->FspsTestConfig.PcieRpUptp[Index] = (UINT8)PcieRpConfig->RootPort[Index].Uptp;
+    FspsUpd->FspsTestConfig.PcieRpDptp[Index] = (UINT8)PcieRpConfig->RootPort[Index].Dptp;
+
+  }
+  for (Index = 0; Index < GetPchMaxPcieClockNum (); Index ++) {
+    FspsUpd->FspsConfig.PcieClkSrcUsage[Index] = PcieRpConfig->PcieClock[Index].Usage;
+    FspsUpd->FspsConfig.PcieClkSrcClkReq[Index] = PcieRpConfig->PcieClock[Index].ClkReq;
+  }
+
+  //
+  // Update PCIE RP EqPh3LaneParam policies
+  //
+  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
+    FspsUpd->FspsConfig.PcieEqPh3LaneParamCm[Index] = (UINT8)PcieRpConfig->EqPh3LaneParam[Index].Cm;
+    FspsUpd->FspsConfig.PcieEqPh3LaneParamCp[Index] = (UINT8)PcieRpConfig->EqPh3LaneParam[Index].Cp;
+  }
+
+  //
+  // Update PCIE RP SwEqCoeffList policies
+  //
+  for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index ++) {
+    FspsUpd->FspsConfig.PcieSwEqCoeffListCm[Index] = (UINT8)PcieRpConfig->SwEqCoeffList[Index].Cm;
+    FspsUpd->FspsConfig.PcieSwEqCoeffListCp[Index] = (UINT8)PcieRpConfig->SwEqCoeffList[Index].Cp;
+  }
+
+  //
+  // Update PCIE RP policies
+  //
+  FspsUpd->FspsTestConfig.PcieEnablePort8xhDecode        = (UINT8)PcieRpConfig->EnablePort8xhDecode;
+  FspsUpd->FspsTestConfig.PchPciePort8xhDecodePortIndex  = (UINT8)PcieRpConfig->PchPciePort8xhDecodePortIndex;
+  FspsUpd->FspsConfig.PcieDisableRootPortClockGating = (UINT8)PcieRpConfig->DisableRootPortClockGating;
+  FspsUpd->FspsConfig.PcieEnablePeerMemoryWrite      = (UINT8)PcieRpConfig->EnablePeerMemoryWrite;
+  FspsUpd->FspsConfig.PcieComplianceTestMode         = (UINT8)PcieRpConfig->ComplianceTestMode;
+  FspsUpd->FspsConfig.PcieRpFunctionSwap             = (UINT8)PcieRpConfig->RpFunctionSwap;
+  FspsUpd->FspsConfig.PchPcieDeviceOverrideTablePtr  = PcieRpConfig->PcieDeviceOverrideTablePtr;
+
+  //
+  // Update Sata Policies
+  //
+  FspsUpd->FspsConfig.SataEnable                     = (UINT8)SataConfig->Enable;
+  FspsUpd->FspsTestConfig.SataTestMode               = (UINT8)SataConfig->TestMode;
+  FspsUpd->FspsConfig.SataSalpSupport                = (UINT8)SataConfig->SalpSupport;
+  FspsUpd->FspsConfig.SataPwrOptEnable = (UINT8)SataConfig->PwrOptEnable;
+  FspsUpd->FspsConfig.EsataSpeedLimit  = (UINT8)SataConfig->EsataSpeedLimit;
+  FspsUpd->FspsConfig.SataLedEnable    = (UINT8)SataConfig->LedEnable;
+  FspsUpd->FspsConfig.SataMode         = (UINT8)SataConfig->SataMode;
+  FspsUpd->FspsConfig.SataSpeedLimit   = (UINT8)SataConfig->SpeedLimit;
+
+  for (Index = 0; Index < PCH_MAX_SATA_PORTS; Index++) {
+    FspsUpd->FspsConfig.SataPortsEnable[Index] = (UINT8)SataConfig->PortSettings[Index].Enable;
+    FspsUpd->FspsConfig.SataPortsHotPlug[Index]     = (UINT8)SataConfig->PortSettings[Index].HotPlug;
+    FspsUpd->FspsConfig.SataPortsInterlockSw[Index] = (UINT8)SataConfig->PortSettings[Index].InterlockSw;
+    FspsUpd->FspsConfig.SataPortsExternal[Index]    = (UINT8)SataConfig->PortSettings[Index].External;
+    FspsUpd->FspsConfig.SataPortsSpinUp[Index]      = (UINT8)SataConfig->PortSettings[Index].SpinUp;
+    FspsUpd->FspsConfig.SataPortsSolidStateDrive[Index]  = (UINT8)SataConfig->PortSettings[Index].SolidStateDrive;
+    FspsUpd->FspsConfig.SataPortsDevSlp[Index] = (UINT8)SataConfig->PortSettings[Index].DevSlp;
+    FspsUpd->FspsConfig.SataPortsEnableDitoConfig[Index] = (UINT8)SataConfig->PortSettings[Index].EnableDitoConfig;
+    FspsUpd->FspsConfig.SataPortsDmVal[Index]       = (UINT8)SataConfig->PortSettings[Index].DmVal;
+    FspsUpd->FspsConfig.SataPortsDitoVal[Index]     = (UINT16)SataConfig->PortSettings[Index].DitoVal;
+    FspsUpd->FspsConfig.SataPortsZpOdd[Index]       = (UINT8)SataConfig->PortSettings[Index].ZpOdd;
+  }
+
+  FspsUpd->FspsConfig.SataRstRaidDeviceId            = (UINT8)SataConfig->Rst.RaidDeviceId;
+  FspsUpd->FspsConfig.SataRstInterrupt               = (UINT8)SataConfig->Rst.SataRstInterrupt;
+  FspsUpd->FspsConfig.SataRstRaid0                   = (UINT8)SataConfig->Rst.Raid0;
+  FspsUpd->FspsConfig.SataRstRaid1                   = (UINT8)SataConfig->Rst.Raid1;
+  FspsUpd->FspsConfig.SataRstRaid10                  = (UINT8)SataConfig->Rst.Raid10;
+  FspsUpd->FspsConfig.SataRstRaid5                   = (UINT8)SataConfig->Rst.Raid5;
+  FspsUpd->FspsConfig.SataRstIrrt                    = (UINT8)SataConfig->Rst.Irrt;
+  FspsUpd->FspsConfig.SataRstOromUiBanner            = (UINT8)SataConfig->Rst.OromUiBanner;
+  FspsUpd->FspsConfig.SataRstOromUiDelay             = (UINT8)SataConfig->Rst.OromUiDelay;
+  FspsUpd->FspsConfig.SataRstHddUnlock               = (UINT8)SataConfig->Rst.HddUnlock;
+  FspsUpd->FspsConfig.SataRstLedLocate               = (UINT8)SataConfig->Rst.LedLocate;
+  FspsUpd->FspsConfig.SataRstIrrtOnly                = (UINT8)SataConfig->Rst.IrrtOnly;
+  FspsUpd->FspsConfig.SataRstSmartStorage            = (UINT8)SataConfig->Rst.SmartStorage;
+  FspsUpd->FspsConfig.SataRstOptaneMemory            = (UINT8)SataConfig->Rst.OptaneMemory;
+  FspsUpd->FspsConfig.SataRstLegacyOrom              = (UINT8)SataConfig->Rst.LegacyOrom;
+  FspsUpd->FspsConfig.SataRstCpuAttachedStorage      = (UINT8)SataConfig->Rst.CpuAttachedStorage;
+
+  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+    FspsUpd->FspsConfig.SataRstPcieEnable[Index]           = (UINT8)SataConfig->RstPcieStorageRemap[Index].Enable;
+    FspsUpd->FspsConfig.SataRstPcieStoragePort[Index]      = (UINT8)SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort;
+    FspsUpd->FspsConfig.SataRstPcieDeviceResetDelay[Index] = (UINT8)SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay;
+  }
+
+  FspsUpd->FspsConfig.SataP0T1M            = (UINT8)SataConfig->ThermalThrottling.P0T1M;
+  FspsUpd->FspsConfig.SataP0T2M            = (UINT8)SataConfig->ThermalThrottling.P0T2M;
+  FspsUpd->FspsConfig.SataP0T3M            = (UINT8)SataConfig->ThermalThrottling.P0T3M;
+  FspsUpd->FspsConfig.SataP0TDisp          = (UINT8)SataConfig->ThermalThrottling.P0TDisp;
+  FspsUpd->FspsConfig.SataP1T1M            = (UINT8)SataConfig->ThermalThrottling.P1T1M;
+  FspsUpd->FspsConfig.SataP1T2M            = (UINT8)SataConfig->ThermalThrottling.P1T2M;
+  FspsUpd->FspsConfig.SataP1T3M            = (UINT8)SataConfig->ThermalThrottling.P1T3M;
+  FspsUpd->FspsConfig.SataP1TDisp          = (UINT8)SataConfig->ThermalThrottling.P1TDisp;
+  FspsUpd->FspsConfig.SataP0Tinact         = (UINT8)SataConfig->ThermalThrottling.P0Tinact;
+  FspsUpd->FspsConfig.SataP0TDispFinit     = (UINT8)SataConfig->ThermalThrottling.P0TDispFinit;
+  FspsUpd->FspsConfig.SataP1Tinact         = (UINT8)SataConfig->ThermalThrottling.P1Tinact;
+  FspsUpd->FspsConfig.SataP1TDispFinit     = (UINT8)SataConfig->ThermalThrottling.P1TDispFinit;
+  FspsUpd->FspsConfig.SataThermalSuggestedSetting = (UINT8)SataConfig->ThermalThrottling.SuggestedSetting;
+
+  //
+  // Update USB policies
+  //
+  FspsUpd->FspsConfig.PchEnableComplianceMode           = (UINT8)UsbConfig->EnableComplianceMode;
+  FspsUpd->FspsConfig.UsbPdoProgramming                 = (UINT8)UsbConfig->PdoProgramming;
+  FspsUpd->FspsConfig.PchUsbOverCurrentEnable           = (UINT8)UsbConfig->OverCurrentEnable;
+  FspsUpd->FspsConfig.PchUsb2PhySusPgEnable             = (UINT8)UsbConfig->Usb2PhySusPgEnable;
+  FspsUpd->FspsTestConfig.PchXhciOcLock                 = (UINT8)UsbConfig->XhciOcLock;
+  for (Index = 0; Index < PCH_MAX_USB2_PORTS; Index++) {
+    FspsUpd->FspsConfig.PortUsb20Enable[Index]  = (UINT8)UsbConfig->PortUsb20[Index].Enable;
+    FspsUpd->FspsConfig.Usb2OverCurrentPin[Index] = (UINT8)UsbConfig->PortUsb20[Index].OverCurrentPin;
+    FspsUpd->FspsConfig.Usb2AfePetxiset[Index]  = (UINT8)UsbConfig->PortUsb20[Index].Afe.Petxiset;
+    FspsUpd->FspsConfig.Usb2AfeTxiset[Index]    = (UINT8)UsbConfig->PortUsb20[Index].Afe.Txiset;
+    FspsUpd->FspsConfig.Usb2AfePredeemp[Index]  = (UINT8)UsbConfig->PortUsb20[Index].Afe.Predeemp;
+    FspsUpd->FspsConfig.Usb2AfePehalfbit[Index] = (UINT8)UsbConfig->PortUsb20[Index].Afe.Pehalfbit;
+  }
+  for (Index = 0; Index < PCH_MAX_USB3_PORTS; Index++) {
+    FspsUpd->FspsConfig.PortUsb30Enable[Index]              = (UINT8)UsbConfig->PortUsb30[Index].Enable;
+    FspsUpd->FspsConfig.Usb3OverCurrentPin[Index]           = (UINT8)UsbConfig->PortUsb30[Index].OverCurrentPin;
+    FspsUpd->FspsConfig.Usb3HsioTxDeEmphEnable[Index]       = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable;
+    FspsUpd->FspsConfig.Usb3HsioTxDeEmph[Index]             = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDeEmph;
+    FspsUpd->FspsConfig.Usb3HsioTxDownscaleAmpEnable[Index] = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable;
+    FspsUpd->FspsConfig.Usb3HsioTxDownscaleAmp[Index]       = (UINT8)UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp;
+
+    Data8 = 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable ? B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN : 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable ? B_XHCI_HSIO_FILTER_SELECT_N_EN : 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable ? B_XHCI_HSIO_FILTER_SELECT_P_EN : 0;
+    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable ? B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN : 0;
+    FspsUpd->FspsConfig.PchUsbHsioRxTuningEnable[Index] = Data8;
+
+    Data8 = ((UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg & 0x1F) << N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG) |
+            ((UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes & 0x7) << N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES);
+    FspsUpd->FspsConfig.PchUsbHsioRxTuningParameters[Index] = Data8;
+
+    Data8 = ((UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN & 0x7) << N_XHCI_UPD_HSIO_FILTER_SELECT_N) |
+            ((UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP & 0x7) << N_XHCI_UPD_HSIO_FILTER_SELECT_P);
+    FspsUpd->FspsConfig.PchUsbHsioFilterSel[Index] = Data8;
+  }
+
+  FspsUpd->FspsConfig.XdciEnable     = (UINT8)UsbConfig->XdciConfig.Enable;
+
+  //
+  // Update SerialIo policies
+  //
+  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+    FspsUpd->FspsConfig.SerialIoDevMode[Index] = SerialIoConfig->DevMode[Index];
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    FspsUpd->FspsConfig.SerialIoSpiCsPolarity[Index] = SerialIoConfig->SpiCsPolarity[Index];
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    FspsUpd->FspsConfig.SerialIoUartHwFlowCtrl[Index] = SerialIoConfig->UartHwFlowCtrl[Index];
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    FspsUpd->FspsConfig.PchSerialIoI2cPadsTermination[Index] = SerialIoConfig->I2cPadsTermination[Index];
+  }
+
+  FspsUpd->FspsConfig.SerialIoDebugUartNumber          = (UINT8)SerialIoConfig->DebugUartNumber;
+  FspsUpd->FspsConfig.SerialIoEnableDebugUartAfterPost = (UINT8)SerialIoConfig->EnableDebugUartAfterPost;
+  FspsUpd->FspsConfig.SerialIoUart0PinMuxing           = (UINT8)SerialIoConfig->Uart0PinMuxing;
+
+  //
+  // Update Interrupt policies
+  //
+  FspsUpd->FspsConfig.DevIntConfigPtr = (UINT32)InterruptConfig->DevIntConfig;
+  FspsUpd->FspsConfig.NumOfDevIntConfig = InterruptConfig->NumOfDevIntConfig;
+  for (Index = 0; Index < PCH_MAX_PXRC_CONFIG; Index ++) {
+    FspsUpd->FspsConfig.PxRcConfig[Index] = (UINT8)InterruptConfig->PxRcConfig[Index];
+  }
+  FspsUpd->FspsConfig.GpioIrqRoute = (UINT8)InterruptConfig->GpioIrqRoute;
+  FspsUpd->FspsConfig.SciIrqSelect = (UINT8)InterruptConfig->SciIrqSelect;
+  FspsUpd->FspsConfig.TcoIrqSelect = (UINT8)InterruptConfig->TcoIrqSelect;
+  FspsUpd->FspsConfig.TcoIrqEnable = (UINT8)InterruptConfig->TcoIrqEnable;
+
+  //
+  // Update LockDown policies
+  //
+  FspsUpd->FspsTestConfig.PchLockDownGlobalSmi     = (UINT8)LockDownConfig->GlobalSmi;
+  FspsUpd->FspsTestConfig.PchLockDownBiosInterface = (UINT8)LockDownConfig->BiosInterface;
+  FspsUpd->FspsConfig.PchLockDownBiosLock          = (UINT8)LockDownConfig->BiosLock;
+  FspsUpd->FspsConfig.PchLockDownRtcMemoryLock     = (UINT8)LockDownConfig->RtcMemoryLock;
+  FspsUpd->FspsTestConfig.PchUnlockGpioPads        = (UINT8)LockDownConfig->UnlockGpioPads;
+
+  //
+  // Update Dmi policies
+  //
+  FspsUpd->FspsConfig.PchPwrOptEnable = (UINT8)DmiConfig->PwrOptEnable;
+  FspsUpd->FspsConfig.PchDmiAspmCtrl = (UINT8)DmiConfig->DmiAspmCtrl;
+
+  //
+  // Update Flash Protection policies
+  //
+  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; Index ++) {
+    FspsUpd->FspsConfig.PchWriteProtectionEnable[Index] = (UINT8)FlashProtectionConfig->ProtectRange[Index].WriteProtectionEnable;
+    FspsUpd->FspsConfig.PchReadProtectionEnable[Index]  = (UINT8)FlashProtectionConfig->ProtectRange[Index].ReadProtectionEnable;
+    FspsUpd->FspsConfig.PchProtectedRangeLimit[Index]  = (UINT16)FlashProtectionConfig->ProtectRange[Index].ProtectedRangeLimit;
+    FspsUpd->FspsConfig.PchProtectedRangeBase[Index]   = (UINT16)FlashProtectionConfig->ProtectRange[Index].ProtectedRangeBase;
+  }
+
+  //
+  // Update IO Apic policies
+  //
+  FspsUpd->FspsConfig.PchIoApicEntry24_119       = (UINT8)IoApicConfig->IoApicEntry24_119;
+  FspsUpd->FspsConfig.Enable8254ClockGating      = (UINT8)IoApicConfig->Enable8254ClockGating;
+  FspsUpd->FspsConfig.Enable8254ClockGatingOnS3  = (UINT8)IoApicConfig->Enable8254ClockGatingOnS3;
+  FspsUpd->FspsConfig.PchIoApicId                = (UINT8)IoApicConfig->IoApicId;
+
+  //
+  // Update P2sb policies
+  //
+  FspsUpd->FspsTestConfig.PchSbAccessUnlock  = (UINT8)P2sbConfig->SbAccessUnlock;
+
+  //
+  // Update Pch General policies
+  //
+  FspsUpd->FspsConfig.PchCrid               = (UINT8)PchGeneralConfig->Crid;
+  FspsUpd->FspsConfig.PchLegacyIoLowLatency = (UINT8)PchGeneralConfig->LegacyIoLowLatency;
+
+  //
+  // Update Pm policies
+  //
+  FspsUpd->FspsConfig.PchPmPmeB0S5Dis         = (UINT8)PmConfig->WakeConfig.PmeB0S5Dis;
+  FspsUpd->FspsConfig.PchPmWolEnableOverride  = (UINT8)PmConfig->WakeConfig.WolEnableOverride;
+  FspsUpd->FspsConfig.PchPmPcieWakeFromDeepSx = (UINT8)PmConfig->WakeConfig.PcieWakeFromDeepSx;
+  FspsUpd->FspsConfig.PchPmWoWlanEnable       = (UINT8)PmConfig->WakeConfig.WoWlanEnable;
+  FspsUpd->FspsConfig.PchPmWoWlanDeepSxEnable = (UINT8)PmConfig->WakeConfig.WoWlanDeepSxEnable;
+  FspsUpd->FspsConfig.PchPmLanWakeFromDeepSx  = (UINT8)PmConfig->WakeConfig.LanWakeFromDeepSx;
+
+  FspsUpd->FspsConfig.PchPmDeepSxPol          = (UINT8)PmConfig->PchDeepSxPol;
+  FspsUpd->FspsConfig.PchPmSlpS3MinAssert     = (UINT8)PmConfig->PchSlpS3MinAssert;
+  FspsUpd->FspsConfig.PchPmSlpS4MinAssert     = (UINT8)PmConfig->PchSlpS4MinAssert;
+  FspsUpd->FspsConfig.PchPmSlpSusMinAssert    = (UINT8)PmConfig->PchSlpSusMinAssert;
+  FspsUpd->FspsConfig.PchPmSlpAMinAssert      = (UINT8)PmConfig->PchSlpAMinAssert;
+  FspsUpd->FspsConfig.PchPmLpcClockRun        = (UINT8)PmConfig->LpcClockRun;
+  FspsUpd->FspsConfig.PchPmSlpStrchSusUp      = (UINT8)PmConfig->SlpStrchSusUp;
+  FspsUpd->FspsConfig.PchPmSlpLanLowDc        = (UINT8)PmConfig->SlpLanLowDc;
+  FspsUpd->FspsConfig.PchPmPwrBtnOverridePeriod = (UINT8)PmConfig->PwrBtnOverridePeriod;
+  FspsUpd->FspsTestConfig.PchPmDisableEnergyReport  = (UINT8)PmConfig->DisableEnergyReport;
+  FspsUpd->FspsConfig.PchPmDisableDsxAcPresentPulldown = (UINT8)PmConfig->DisableDsxAcPresentPulldown;
+  FspsUpd->FspsConfig.PchPmDisableNativePowerButton    = (UINT8)PmConfig->DisableNativePowerButton;
+  FspsUpd->FspsConfig.PmcPowerButtonDebounce  = PmConfig->PowerButtonDebounce;
+  FspsUpd->FspsConfig.PchPmSlpS0Enable        = (UINT8)PmConfig->SlpS0Enable;
+  FspsUpd->FspsConfig.PchPmMeWakeSts          = (UINT8)PmConfig->MeWakeSts;
+  FspsUpd->FspsConfig.PchPmWolOvrWkSts        = (UINT8)PmConfig->WolOvrWkSts;
+  FspsUpd->FspsConfig.EnableTcoTimer          = (UINT8)PmConfig->EnableTcoTimer;
+  FspsUpd->FspsConfig.PchPmVrAlert            = (UINT8)PmConfig->VrAlert;
+  FspsUpd->FspsConfig.PchPmPwrCycDur          = (UINT8)PmConfig->PchPwrCycDur;
+  FspsUpd->FspsConfig.PchPmPciePllSsc         = (UINT8)PmConfig->PciePllSsc;
+  FspsUpd->FspsConfig.PchPmSlpS0VmRuntimeControl = (UINT8)PmConfig->SlpS0VmRuntimeControl;
+  FspsUpd->FspsConfig.PchPmSlpS0Vm070VSupport   = (UINT8)PmConfig->SlpS0Vm070VSupport;
+  FspsUpd->FspsConfig.PchPmSlpS0Vm075VSupport   = (UINT8)PmConfig->SlpS0Vm075VSupport;
+  FspsUpd->FspsConfig.SlpS0Override             = (UINT8)PmConfig->SlpS0Override;
+  FspsUpd->FspsConfig.SlpS0DisQForDebug         = (UINT8)PmConfig->SlpS0DisQForDebug;
+  FspsUpd->FspsConfig.PmcDbgMsgEn               = (UINT8)PmConfig->PmcDbgMsgEn;
+  FspsUpd->FspsConfig.PsOnEnable                = (UINT8)PmConfig->PsOnEnable;
+  FspsUpd->FspsConfig.PmcCpuC10GatePinEnable    = (UINT8)PmConfig->CpuC10GatePinEnable;
+  FspsUpd->FspsConfig.PmcModPhySusPgEnable      = (UINT8)PmConfig->ModPhySusPgEnable;
+  FspsUpd->FspsConfig.SlpS0WithGbeSupport       = (UINT8)PmConfig->SlpS0WithGbeSupport;
+  //
+  // Update Pch Serial IRQ policies
+  //
+  FspsUpd->FspsConfig.PchSirqEnable       = (UINT8)PchSerialIrqConfig->SirqEnable;
+  FspsUpd->FspsConfig.PchSirqMode         = (UINT8)PchSerialIrqConfig->SirqMode;
+  FspsUpd->FspsConfig.PchStartFramePulse  = (UINT8)PchSerialIrqConfig->StartFramePulse;
+  //
+  // Update Pch Thermal policies
+  //
+  FspsUpd->FspsConfig.PchTsmicLock        = (UINT8)PchThermalConfig->TsmicLock;
+  FspsUpd->FspsConfig.PchHotEnable        = (UINT8)PchThermalConfig->PchHotEnable;
+
+  FspsUpd->FspsConfig.PchT0Level          = (UINT16)PchThermalConfig->TTLevels.T0Level;
+  FspsUpd->FspsConfig.PchT1Level          = (UINT16)PchThermalConfig->TTLevels.T1Level;
+  FspsUpd->FspsConfig.PchT2Level          = (UINT16)PchThermalConfig->TTLevels.T2Level;
+  FspsUpd->FspsConfig.PchTTEnable         = (UINT8)PchThermalConfig->TTLevels.TTEnable;
+  FspsUpd->FspsConfig.PchTTState13Enable  = (UINT8)PchThermalConfig->TTLevels.TTState13Enable;
+  FspsUpd->FspsConfig.PchTTLock           = (UINT8)PchThermalConfig->TTLevels.TTLock;
+  FspsUpd->FspsConfig.TTSuggestedSetting  = (UINT8)PchThermalConfig->TTLevels.SuggestedSetting;
+  FspsUpd->FspsConfig.TTCrossThrottling   = (UINT8)PchThermalConfig->TTLevels.PchCrossThrottling;
+
+  FspsUpd->FspsConfig.PchDmiTsawEn        = (UINT8)PchThermalConfig->DmiHaAWC.DmiTsawEn;
+  FspsUpd->FspsConfig.DmiSuggestedSetting = (UINT8)PchThermalConfig->DmiHaAWC.SuggestedSetting;
+  FspsUpd->FspsConfig.DmiTS0TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS0TW;
+  FspsUpd->FspsConfig.DmiTS1TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS1TW;
+  FspsUpd->FspsConfig.DmiTS2TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS2TW;
+  FspsUpd->FspsConfig.DmiTS3TW            = (UINT8)PchThermalConfig->DmiHaAWC.TS3TW;
+
+  FspsUpd->FspsConfig.PchMemoryThrottlingEnable    = (UINT8)PchThermalConfig->MemoryThrottling.Enable;
+  FspsUpd->FspsConfig.PchMemoryPmsyncEnable[0]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].PmsyncEnable;
+  FspsUpd->FspsConfig.PchMemoryPmsyncEnable[1]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].PmsyncEnable;
+  FspsUpd->FspsConfig.PchMemoryC0TransmitEnable[0] = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].C0TransmitEnable;
+  FspsUpd->FspsConfig.PchMemoryC0TransmitEnable[1] = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].C0TransmitEnable;
+  FspsUpd->FspsConfig.PchMemoryPinSelection[0]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].PinSelection;
+  FspsUpd->FspsConfig.PchMemoryPinSelection[1]     = (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].PinSelection;
+
+  FspsUpd->FspsConfig.PchTemperatureHotLevel = (UINT16)PchThermalConfig->PchHotLevel;
+
+  //
+  // Update Pch CNVi policies
+  //
+  FspsUpd->FspsConfig.PchCnviMode        = (UINT8)CnviConfig->Mode;
+  FspsUpd->FspsConfig.PchCnviMfUart1Type = (UINT8)CnviConfig->MfUart1Type;
+
+  //
+  // Update Pch HSIO policies
+  //
+  FspsUpd->FspsConfig.ChipsetInitBinPtr = HsioConfig->ChipsetInitBinPtr;
+  FspsUpd->FspsConfig.ChipsetInitBinLen = HsioConfig->ChipsetInitBinLen;
+
+  //
+  // Update Pch Espi policies
+  //
+  FspsUpd->FspsConfig.PchEspiLgmrEnable = (UINT8)EspiConfig->LgmrEnable;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c
new file mode 100644
index 0000000000..ce34325781
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c
@@ -0,0 +1,223 @@
+/** @file
+  Instance of Fsp Policy Initialization Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Library/SpiLib.h>
+
+VOID
+EFIAPI
+FspPolicyInitPreMem(
+  IN FSPM_UPD           *FspmUpdDataPtr
+);
+
+VOID *
+EFIAPI
+SiliconPolicyInitPreMem(
+  IN OUT VOID    *FspmUpd
+)
+{
+  FspPolicyInitPreMem((FSPM_UPD *)FspmUpd);
+  return FspmUpd;
+}
+
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePreMem(
+  IN VOID *FspmUpd
+)
+{
+  EFI_STATUS         Status;
+
+  Status = SpiServiceInit();
+  ASSERT_EFI_ERROR(Status);
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Performs FSP PEI Policy Pre-memory initialization.
+
+  @param[in] FspmUpdDataPtr       Pointer to FSPM UPD data.
+**/
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+  IN FSPM_UPD           *FspmUpdDataPtr
+  )
+{
+  EFI_STATUS            Status;
+
+  //
+  // SI Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSiPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // PCH Pei Fsp Policy Initialization
+  //
+  Status = PeiFspPchPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - PCH Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Cpu Pei Fsp Policy Initialization
+  //
+  Status = PeiFspCpuPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Security Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSecurityPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - Security Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // ME Pei Fsp Policy Initialization
+  //
+  Status = PeiFspMePolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - ME Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // SystemAgent Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSaPolicyInitPreMem (FspmUpdDataPtr);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy in Pre-Memory Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Other Upd Initialization
+  //
+  Status = PeiFspMiscUpdInitPreMem (FspmUpdDataPtr);
+
+}
+
+/**
+  Performs FSP PEI Policy initialization.
+
+  @param[in][out] FspsUpd  Pointer UPD data region
+
+**/
+VOID
+EFIAPI
+FspPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS            Status;
+
+  //
+  // SI Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSiPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy iInitialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // PCH Pei Fsp Policy Initialization
+  //
+  Status = PeiFspPchPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - PCH Pei Fsp Policy iInitialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // ME Pei Fsp Policy Initialization
+  //
+  Status = PeiFspMePolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - ME Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // SystemAgent Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSaPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Cpu Pei Fsp Policy Initialization
+  //
+  Status = PeiFspCpuPolicyInit (FspsUpd);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+  //
+  // Security Pei Fsp Policy Initialization
+  //
+  Status = PeiFspSecurityPolicyInit(FspsUpd);
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "ERROR - Security Pei Fsp Policy Initialization fail, Status = %r\n", Status));
+  }
+
+}
+
+/**
+Performs silicon post-mem policy initialization.
+
+The meaning of Policy is defined by silicon code.
+It could be the raw data, a handle, a PPI, etc.
+
+The returned data must be used as input data for SiliconPolicyDonePostMem(),
+and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
+
+1) In FSP path, the input Policy should be FspsUpd.
+Value of FspsUpd has been initialized by FSP binary default value.
+Only a subset of FspsUpd needs to be updated for different silicon sku.
+The return data is same FspsUpd.
+
+2) In non-FSP path, the input policy could be NULL.
+The return data is the initialized policy.
+
+@param[in, out] Policy       Pointer to policy.
+
+@return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPostMem(
+  IN OUT VOID    *FspsUpd
+)
+{
+  FspPolicyInit((FSPS_UPD *)FspsUpd);
+  return FspsUpd;
+}
+
+/*
+The silicon post-mem policy is finalized.
+Silicon code can do initialization based upon the policy data.
+
+The input Policy must be returned by SiliconPolicyInitPostMem().
+
+@param[in] Policy       Pointer to policy.
+
+@retval EFI_SUCCESS The policy is handled consumed by silicon code.
+*/
+EFI_STATUS
+EFIAPI
+SiliconPolicyDonePostMem(
+  IN OUT VOID    *FspsUpd
+)
+{
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
new file mode 100644
index 0000000000..0bfc379386
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
@@ -0,0 +1,848 @@
+/** @file
+  Implementation of Fsp SA Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+
+#include <Ppi/SiPolicy.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmbusLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <PchAccess.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Core/Pei/PeiMain.h>
+
+#define MAX_SPD_PAGE_COUNT           (2)
+#define MAX_SPD_PAGE_SIZE            (256)
+#define MAX_SPD_SIZE                 (MAX_SPD_PAGE_SIZE * MAX_SPD_PAGE_COUNT)
+#define SPD_PAGE_ADDRESS_0           (0x6C)
+#define SPD_PAGE_ADDRESS_1           (0x6E)
+#define SPD_DDR3_SDRAM_TYPE_OFFSET   (0x02)
+#define SPD_DDR3_SDRAM_TYPE_NUMBER   (0x0B)
+#define SPD_DDR4_SDRAM_TYPE_NUMBER   (0x0C)
+#define SPD_LPDDR3_SDRAM_TYPE_NUMBER (0xF1)
+#define SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER (0x0F)
+#define XMP_ID_STRING                (0x4A0C)
+#define SPD3_MANUF_START             (117)
+#define SPD3_MANUF_END               (127)
+#define SPD4_MANUF_START             (320)
+#define SPD4_MANUF_END               (328)
+#define SPDLP_MANUF_START            (320)
+#define SPDLP_MANUF_END              (328)
+
+GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdDdr3Table[] = {
+  {   0,               1,             (1 << SpdCold),},
+  {   2,               2,             (1 << SpdCold) | (1 << SpdFast),},
+  {   3,              41,             (1 << SpdCold),},
+  {  60,              63,             (1 << SpdCold),},
+  { SPD3_MANUF_START, SPD3_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
+  { 128,             145,             (1 << SpdCold),},
+  {  39,              59,             (1 << SpdCold),},
+  {  64,             125,             (1 << SpdCold),},
+  { 176,             179,             (1 << SpdCold),},
+  { 180,             184,             (1 << SpdCold),},
+  { 185,             215,             (1 << SpdCold),},
+  { 220,             250,             (1 << SpdCold),},
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdDdr4Table[] = {
+  {   0,               1,             (1 << SpdCold),},
+  {   2,               2,             (1 << SpdCold) | (1 << SpdFast),},
+  {   3,              40,             (1 << SpdCold),},
+  { 117,             131,             (1 << SpdCold),},
+  { SPD4_MANUF_START, SPD4_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
+  { 329,             348,             (1 << SpdCold),},
+  {  32,             119,             (1 << SpdCold),},
+  { 126,             255,             (1 << SpdCold),},
+  { 349,             383,             (1 << SpdCold),},
+  { 384,             387,             (1 << SpdCold),},
+  { 388,             389,             (1 << SpdCold),},
+  { 393,             431,             (1 << SpdCold),},
+  { 440,             478,             (1 << SpdCold),},
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdLpddrTable[] = {
+  {   0,               1,               (1 << SpdCold),},
+  {   2,               2,               (1 << SpdCold) | (1 << SpdFast),},
+  {   3,              32,               (1 << SpdCold),},
+  { 120,             130,               (1 << SpdCold),},
+  { SPDLP_MANUF_START, SPDLP_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
+  { 329,             348,               (1 << SpdCold),},
+  {  31,             121,               (1 << SpdCold),},
+  { 126,             255,               (1 << SpdCold),},
+  { 349,             383,               (1 << SpdCold),},
+  { 384,             387,               (1 << SpdCold),},
+  { 388,             389,               (1 << SpdCold),},
+  { 393,             431,               (1 << SpdCold),},
+  { 440,             478,               (1 << SpdCold),},
+};
+
+
+/**
+  Update Spd Data
+
+  @param[in][out] FspmUpd              Pointer to FSP UPD Data.
+  @param[in]      MemConfigNoCrc       Pointer to Mem Config No Crc.
+  @param[in]      MiscPeiPreMemConfig  Pointer to Misc Config.
+
+  @retval         EFI_SUCCESS          The function completes successfully
+  @retval         Other                The function fail
+**/
+VOID
+EFIAPI
+InternalUpdateSpdInfo (
+  IN OUT FSPM_UPD               *FspmUpd,
+  IN MEMORY_CONFIG_NO_CRC       *MemConfigNoCrc,
+  IN SA_MISC_PEI_PREMEM_CONFIG  *MiscPeiPreMemConfig
+  )
+{
+
+  DEBUG ((DEBUG_INFO, "Updating UPD:Memory Spd Pointers...\n"));
+  if ((FspmUpd == NULL) || (MemConfigNoCrc == NULL) || (MiscPeiPreMemConfig == NULL)) {
+    DEBUG ((DEBUG_ERROR, "EFI_INVALID_PARAMETER.\n"));
+    DEBUG ((DEBUG_ERROR, "Fail to access SPD from SiPolicyPpi\n"));
+    return;
+  }
+
+  //
+  // Update MemorySpdPtrXX if SpdAddressTable is zero
+  //
+  if (MiscPeiPreMemConfig->SpdAddressTable[0] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr00 = (UINT32)MemConfigNoCrc->SpdData->SpdData;
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[0] = MiscPeiPreMemConfig->SpdAddressTable[0];
+  }
+
+  if (MiscPeiPreMemConfig->SpdAddressTable[1] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr01 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (1 * SA_MC_MAX_SPD_SIZE);
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[1] = MiscPeiPreMemConfig->SpdAddressTable[1];
+  }
+
+  if (MiscPeiPreMemConfig->SpdAddressTable[2] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr10 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (2 * SA_MC_MAX_SPD_SIZE);
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[2] = MiscPeiPreMemConfig->SpdAddressTable[2];
+  }
+
+  if (MiscPeiPreMemConfig->SpdAddressTable[3] == 0x0) {
+    FspmUpd->FspmConfig.MemorySpdPtr11 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (3 * SA_MC_MAX_SPD_SIZE);
+  } else {
+    FspmUpd->FspmConfig.SpdAddressTable[3] = MiscPeiPreMemConfig->SpdAddressTable[3];
+  }
+
+  DEBUG ((DEBUG_INFO, "UPD:MemorySpdPtr Updated\n"));
+}
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32               *Size
+  )
+{
+  EFI_STATUS  Status;
+  EFI_PEI_FIRMWARE_VOLUME_PPI          *FvPpi;
+  EFI_FV_FILE_INFO                     FvFileInfo;
+  PEI_CORE_INSTANCE                    *PrivateData;
+  UINTN                                CurrentFv;
+  PEI_CORE_FV_HANDLE                   *CoreFvHandle;
+  EFI_PEI_FILE_HANDLE                  VbtFileHandle;
+  EFI_GUID                             *VbtGuid;
+  EFI_COMMON_SECTION_HEADER            *Section;
+  CONST EFI_PEI_SERVICES               **PeiServices;
+
+  PeiServices = GetPeiServicesTablePointer ();
+
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+  Status = PeiServicesLocatePpi (
+            &gEfiFirmwareFileSystem2Guid,
+            0,
+            NULL,
+            (VOID **) &FvPpi
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  CurrentFv = PrivateData->CurrentPeimFvCount;
+  CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+  Status = FvPpi->FindFileByName (FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+  if (!EFI_ERROR(Status) && VbtFileHandle != NULL) {
+
+  DEBUG ((DEBUG_INFO, "Find SectionByType \n"));
+
+    Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **) &VbtGuid);
+    if (!EFI_ERROR (Status)) {
+
+    DEBUG ((DEBUG_INFO, "GetFileInfo \n"));
+
+      Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo);
+      Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
+
+      if (IS_SECTION2 (Section)) {
+        ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
+        *Size = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+      } else {
+        *Size = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP SA PEI Policy initialization in pre-memory.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                  Status;
+  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
+  MEMORY_CONFIGURATION        *MemConfig;
+  MEMORY_CONFIG_NO_CRC        *MemConfigNoCrc;
+  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
+  PCIE_PEI_PREMEM_CONFIG      *PciePeiPreMemConfig;
+  SWITCHABLE_GRAPHICS_CONFIG  *SgGpioData;
+  GRAPHICS_PEI_PREMEM_CONFIG  *GtPreMemConfig;
+  OVERCLOCKING_PREMEM_CONFIG  *OcPreMemConfig;
+  VTD_CONFIG                  *Vtd;
+  IPU_PREMEM_CONFIG           *IpuPreMemPolicy;
+  UINT8                       Index;
+  VOID                        *Buffer;
+
+  SiPreMemPolicyPpi   = NULL;
+  MiscPeiPreMemConfig = NULL;
+  MemConfig           = NULL;
+  MemConfigNoCrc      = NULL;
+  PciePeiPreMemConfig = NULL;
+  SgGpioData          = NULL;
+  GtPreMemConfig      = NULL;
+  OcPreMemConfig      = NULL;
+  Vtd                 = NULL;
+  IpuPreMemPolicy     = NULL;
+
+
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  Status = PeiServicesLocatePpi(
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+  if ((Status == EFI_SUCCESS) && (SiPreMemPolicyPpi != NULL)) {
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *) &SgGpioData);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gVtdConfigGuid, (VOID *) &Vtd);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
+    ASSERT_EFI_ERROR (Status);
+    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
+    ASSERT_EFI_ERROR (Status);
+
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Byte Map and DQS Byte Swizzling Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh0, Buffer, 12);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh1, (UINT8*) Buffer + 12, 12);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh0, Buffer, 8);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh1, (UINT8*) Buffer + 8, 8);
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Pins Interleaved,Rcomp Resistor & Rcomp Target Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompResistor, Buffer, 6);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompTarget, Buffer, 10);
+  }
+
+  //
+  // Update UPD:MemorySpdPtrXX and SpdAddressTable
+  //
+  InternalUpdateSpdInfo (FspmUpd, MemConfigNoCrc, MiscPeiPreMemConfig);
+
+  //
+  // Update UPD:MemorySpdDataLen
+  //
+  FspmUpd->FspmConfig.MemorySpdDataLen = SA_MC_MAX_SPD_SIZE;
+
+  if (MemConfigNoCrc != NULL) {
+    //
+    // Update UPD:PlatformMemorySize
+    //
+    //
+    // @todo: This value is used since #183932. Revisit.
+    //
+    FspmUpd->FspmConfig.PlatformMemorySize  = MemConfigNoCrc->PlatformMemorySize;
+    FspmUpd->FspmConfig.CleanMemory         = (UINT8) MemConfigNoCrc->CleanMemory;
+    FspmUpd->FspmConfig.MemTestOnWarmBoot   = (UINT8) MemConfigNoCrc->MemTestOnWarmBoot;
+  }
+
+  if (MemConfig != NULL) {
+    //
+    // Update UPD:DqPinsInterleaved
+    //
+    FspmUpd->FspmConfig.DqPinsInterleaved     = (UINT8) MemConfig->DqPinsInterleaved;
+
+    FspmUpd->FspmConfig.ProbelessTrace        = MemConfig->ProbelessTrace;
+    FspmUpd->FspmConfig.GdxcIotSize           = MemConfig->GdxcIotSize;
+    FspmUpd->FspmConfig.GdxcMotSize           = MemConfig->GdxcMotSize;
+    FspmUpd->FspmConfig.DualDimmPerChannelBoardType =(UINT8) MemConfig->DualDimmPerChannelBoardType;
+    FspmUpd->FspmConfig.Ddr4MixedUDimm2DpcLimit     =(UINT8) MemConfig->Ddr4MixedUDimm2DpcLimit;
+    //
+    // Update UPD:CaVrefConfig
+    //
+    FspmUpd->FspmConfig.CaVrefConfig          = MemConfig->CaVrefConfig;
+    FspmUpd->FspmConfig.SaGv                  = MemConfig->SaGv;
+    FspmUpd->FspmConfig.FreqSaGvLow           = MemConfig->FreqSaGvLow;
+    FspmUpd->FspmConfig.FreqSaGvMid           = MemConfig->FreqSaGvMid;
+    FspmUpd->FspmConfig.RMT                   = (UINT8) MemConfig->RMT;
+    FspmUpd->FspmConfig.DdrFreqLimit          = MemConfig->DdrFreqLimit;
+
+    FspmUpd->FspmConfig.SpdProfileSelected    = MemConfig->SpdProfileSelected;
+    FspmUpd->FspmConfig.VddVoltage            = MemConfig->VddVoltage;
+    FspmUpd->FspmConfig.RefClk                = MemConfig->RefClk;
+    FspmUpd->FspmConfig.Ratio                 = MemConfig->Ratio;
+    FspmUpd->FspmConfig.OddRatioMode          = (UINT8) MemConfig->OddRatioMode;
+    FspmUpd->FspmConfig.tCL                   = (UINT8) MemConfig->tCL;
+    FspmUpd->FspmConfig.tCWL                  = (UINT8) MemConfig->tCWL;
+    FspmUpd->FspmConfig.tFAW                  = MemConfig->tFAW;
+    FspmUpd->FspmConfig.tRAS                  = MemConfig->tRAS;
+    FspmUpd->FspmConfig.tRCDtRP               = (UINT8) MemConfig->tRCDtRP;
+    FspmUpd->FspmConfig.tREFI                 = MemConfig->tREFI;
+    FspmUpd->FspmConfig.tRFC                  = MemConfig->tRFC;
+    FspmUpd->FspmConfig.tRRD                  = (UINT8) MemConfig->tRRD;
+    FspmUpd->FspmConfig.tRTP                  = (UINT8) MemConfig->tRTP;
+    FspmUpd->FspmConfig.tWR                   = (UINT8) MemConfig->tWR;
+    FspmUpd->FspmConfig.tWTR                  = (UINT8) MemConfig->tWTR;
+    FspmUpd->FspmConfig.NModeSupport          = MemConfig->NModeSupport;
+    FspmUpd->FspmConfig.DllBwEn0              = MemConfig->DllBwEn0;
+    FspmUpd->FspmConfig.DllBwEn1              = MemConfig->DllBwEn1;
+    FspmUpd->FspmConfig.DllBwEn2              = MemConfig->DllBwEn2;
+    FspmUpd->FspmConfig.DllBwEn3              = MemConfig->DllBwEn3;
+    FspmUpd->FspmConfig.MrcSafeConfig         = (UINT8) MemConfig->MrcSafeConfig; // Typecasting as MrcSafeConfig is of UINT32 in MEMORY_CONFIGURATION
+    FspmUpd->FspmConfig.LpDdrDqDqsReTraining  = (UINT8) MemConfig->Lp4DqsOscEn;
+    FspmUpd->FspmConfig.RmtPerTask            = (UINT8) MemConfig->RmtPerTask;
+    FspmUpd->FspmConfig.TrainTrace            = (UINT8) MemConfig->TrainTrace;
+    FspmUpd->FspmConfig.ScramblerSupport      = (UINT8) MemConfig->ScramblerSupport;
+    FspmUpd->FspmConfig.SafeMode              = (UINT8) MemConfig->SafeMode;
+
+    //
+    // Update UPD:SmramMask and DisableDimmChannel
+    //
+    FspmUpd->FspmConfig.SmramMask               = MemConfig->SmramMask;
+    FspmUpd->FspmConfig.DisableDimmChannel0     = MemConfig->DisableDimmChannel[0];
+    FspmUpd->FspmConfig.DisableDimmChannel1     = MemConfig->DisableDimmChannel[1];
+    FspmUpd->FspmConfig.HobBufferSize           = MemConfig->HobBufferSize;
+
+    FspmUpd->FspmConfig.ECT                     = (UINT8) MemConfig->ECT;
+    FspmUpd->FspmConfig.SOT                     = (UINT8) MemConfig->SOT;
+    FspmUpd->FspmConfig.ERDMPRTC2D              = (UINT8) MemConfig->ERDMPRTC2D;
+    FspmUpd->FspmConfig.RDMPRT                  = (UINT8) MemConfig->RDMPRT;
+    FspmUpd->FspmConfig.RCVET                   = (UINT8) MemConfig->RCVET;
+    FspmUpd->FspmConfig.JWRL                    = (UINT8) MemConfig->JWRL;
+    FspmUpd->FspmConfig.EWRTC2D                 = (UINT8) MemConfig->EWRTC2D;
+    FspmUpd->FspmConfig.ERDTC2D                 = (UINT8) MemConfig->ERDTC2D;
+    FspmUpd->FspmConfig.WRTC1D                  = (UINT8) MemConfig->WRTC1D;
+    FspmUpd->FspmConfig.WRVC1D                  = (UINT8) MemConfig->WRVC1D;
+    FspmUpd->FspmConfig.RDTC1D                  = (UINT8) MemConfig->RDTC1D;
+    FspmUpd->FspmConfig.DIMMODTT                = (UINT8) MemConfig->DIMMODTT;
+    FspmUpd->FspmConfig.DIMMRONT                = (UINT8) MemConfig->DIMMRONT;
+    FspmUpd->FspmConfig.WRSRT                   = (UINT8) MemConfig->WRSRT;
+    FspmUpd->FspmConfig.RDODTT                  = (UINT8) MemConfig->RDODTT;
+    FspmUpd->FspmConfig.RDEQT                   = (UINT8) MemConfig->RDEQT;
+    FspmUpd->FspmConfig.RDAPT                   = (UINT8) MemConfig->RDAPT;
+    FspmUpd->FspmConfig.WRTC2D                  = (UINT8) MemConfig->WRTC2D;
+    FspmUpd->FspmConfig.RDTC2D                  = (UINT8) MemConfig->RDTC2D;
+    FspmUpd->FspmConfig.WRVC2D                  = (UINT8) MemConfig->WRVC2D;
+    FspmUpd->FspmConfig.RDVC2D                  = (UINT8) MemConfig->RDVC2D;
+    FspmUpd->FspmConfig.CMDVC                   = (UINT8) MemConfig->CMDVC;
+    FspmUpd->FspmConfig.LCT                     = (UINT8) MemConfig->LCT;
+    FspmUpd->FspmConfig.RTL                     = (UINT8) MemConfig->RTL;
+    FspmUpd->FspmConfig.TAT                     = (UINT8) MemConfig->TAT;
+    FspmUpd->FspmConfig.RCVENC1D                = (UINT8) MemConfig->RCVENC1D;
+    FspmUpd->FspmConfig.RMT                     = (UINT8) MemConfig->RMT;
+    FspmUpd->FspmConfig.MEMTST                  = (UINT8) MemConfig->MEMTST;
+    FspmUpd->FspmConfig.ALIASCHK                = (UINT8) MemConfig->ALIASCHK;
+    FspmUpd->FspmConfig.RMC                     = (UINT8) MemConfig->RMC;
+    FspmUpd->FspmConfig.WRDSUDT                 = (UINT8) MemConfig->WRDSUDT;
+    FspmUpd->FspmConfig.EnBER                   = (UINT8) MemConfig->EnBER;
+    FspmUpd->FspmConfig.EccSupport              = (UINT8) MemConfig->EccSupport;
+    FspmUpd->FspmConfig.RemapEnable             = (UINT8) MemConfig->RemapEnable;
+    FspmUpd->FspmConfig.ScramblerSupport        = (UINT8) MemConfig->ScramblerSupport;
+    FspmUpd->FspmConfig.MrcFastBoot             = (UINT8) MemConfig->MrcFastBoot;
+    FspmUpd->FspmConfig.RankInterleave          = (UINT8) MemConfig->RankInterleave;
+    FspmUpd->FspmConfig.EnhancedInterleave      = (UINT8) MemConfig->EnhancedInterleave;
+    FspmUpd->FspmConfig.MemoryTrace             = (UINT8) MemConfig->MemoryTrace;
+    FspmUpd->FspmConfig.ChHashEnable            = (UINT8) MemConfig->ChHashEnable;
+    FspmUpd->FspmConfig.EnableExtts             = (UINT8) MemConfig->EnableExtts;
+    FspmUpd->FspmConfig.EnableCltm              = (UINT8) MemConfig->EnableCltm;
+    FspmUpd->FspmConfig.EnableOltm              = (UINT8) MemConfig->EnableOltm;
+    FspmUpd->FspmConfig.EnablePwrDn             = (UINT8) MemConfig->EnablePwrDn;
+    FspmUpd->FspmConfig.EnablePwrDnLpddr        = (UINT8) MemConfig->EnablePwrDnLpddr;
+    FspmUpd->FspmConfig.UserPowerWeightsEn      = (UINT8) MemConfig->UserPowerWeightsEn;
+    FspmUpd->FspmConfig.RaplLim2Lock            = (UINT8) MemConfig->RaplLim2Lock;
+    FspmUpd->FspmConfig.RaplLim2Ena             = (UINT8) MemConfig->RaplLim2Ena;
+    FspmUpd->FspmConfig.RaplLim1Ena             = (UINT8) MemConfig->RaplLim1Ena;
+    FspmUpd->FspmConfig.SrefCfgEna              = (UINT8) MemConfig->SrefCfgEna;
+    FspmUpd->FspmConfig.ThrtCkeMinDefeatLpddr   = (UINT8) MemConfig->ThrtCkeMinDefeatLpddr;
+    FspmUpd->FspmConfig.ThrtCkeMinDefeat        = (UINT8) MemConfig->ThrtCkeMinDefeat;
+    FspmUpd->FspmConfig.RhPrevention            = (UINT8) MemConfig->RhPrevention;
+    FspmUpd->FspmConfig.ExitOnFailure           = (UINT8) MemConfig->ExitOnFailure;
+    FspmUpd->FspmConfig.DdrThermalSensor        = (UINT8) MemConfig->DdrThermalSensor;
+    FspmUpd->FspmConfig.Ddr4DdpSharedClock      = (UINT8) MemConfig->Ddr4DdpSharedClock;
+    FspmUpd->FspmConfig.Ddr4DdpSharedZq         = (UINT8) MemConfig->SharedZqPin;
+    FspmUpd->FspmConfig.BClkFrequency           = MemConfig->BClkFrequency;
+    FspmUpd->FspmConfig.ChHashInterleaveBit     = MemConfig->ChHashInterleaveBit;
+    FspmUpd->FspmConfig.ChHashMask              = MemConfig->ChHashMask;
+    FspmUpd->FspmConfig.EnergyScaleFact         = MemConfig->EnergyScaleFact;
+    FspmUpd->FspmConfig.Idd3n                   = MemConfig->Idd3n;
+    FspmUpd->FspmConfig.Idd3p                   = MemConfig->Idd3p;
+    FspmUpd->FspmConfig.CMDSR                   = (UINT8) MemConfig->CMDSR;
+    FspmUpd->FspmConfig.CMDDSEQ                 = (UINT8) MemConfig->CMDDSEQ;
+    FspmUpd->FspmConfig.CMDNORM                 = (UINT8) MemConfig->CMDNORM;
+    FspmUpd->FspmConfig.EWRDSEQ                 = (UINT8) MemConfig->EWRDSEQ;
+    FspmUpd->FspmConfig.FreqSaGvLow             = MemConfig->FreqSaGvLow;
+    FspmUpd->FspmConfig.RhActProbability        = MemConfig->RhActProbability;
+    FspmUpd->FspmConfig.RaplLim2WindX           = MemConfig->RaplLim2WindX;
+    FspmUpd->FspmConfig.RaplLim2WindY           = MemConfig->RaplLim2WindY;
+    FspmUpd->FspmConfig.RaplLim1WindX           = MemConfig->RaplLim1WindX;
+    FspmUpd->FspmConfig.RaplLim1WindY           = MemConfig->RaplLim1WindY;
+    FspmUpd->FspmConfig.RaplLim2Pwr             = MemConfig->RaplLim2Pwr;
+    FspmUpd->FspmConfig.RaplLim1Pwr             = MemConfig->RaplLim1Pwr;
+    FspmUpd->FspmConfig.WarmThresholdCh0Dimm0   = MemConfig->WarmThresholdCh0Dimm0;
+    FspmUpd->FspmConfig.WarmThresholdCh0Dimm1   = MemConfig->WarmThresholdCh0Dimm1;
+    FspmUpd->FspmConfig.WarmThresholdCh1Dimm0   = MemConfig->WarmThresholdCh1Dimm0;
+    FspmUpd->FspmConfig.WarmThresholdCh1Dimm1   = MemConfig->WarmThresholdCh1Dimm1;
+    FspmUpd->FspmConfig.HotThresholdCh0Dimm0    = MemConfig->HotThresholdCh0Dimm0;
+    FspmUpd->FspmConfig.HotThresholdCh0Dimm1    = MemConfig->HotThresholdCh0Dimm1;
+    FspmUpd->FspmConfig.HotThresholdCh1Dimm0    = MemConfig->HotThresholdCh1Dimm0;
+    FspmUpd->FspmConfig.HotThresholdCh1Dimm1    = MemConfig->HotThresholdCh1Dimm1;
+    FspmUpd->FspmConfig.WarmBudgetCh0Dimm0      = MemConfig->WarmBudgetCh0Dimm0;
+    FspmUpd->FspmConfig.WarmBudgetCh0Dimm1      = MemConfig->WarmBudgetCh0Dimm1;
+    FspmUpd->FspmConfig.WarmBudgetCh1Dimm0      = MemConfig->WarmBudgetCh1Dimm0;
+    FspmUpd->FspmConfig.WarmBudgetCh1Dimm1      = MemConfig->WarmBudgetCh1Dimm1;
+    FspmUpd->FspmConfig.HotBudgetCh0Dimm0       = MemConfig->HotBudgetCh0Dimm0;
+    FspmUpd->FspmConfig.HotBudgetCh0Dimm1       = MemConfig->HotBudgetCh0Dimm1;
+    FspmUpd->FspmConfig.HotBudgetCh1Dimm0       = MemConfig->HotBudgetCh1Dimm0;
+    FspmUpd->FspmConfig.HotBudgetCh1Dimm1       = MemConfig->HotBudgetCh1Dimm1;
+    FspmUpd->FspmConfig.IdleEnergyCh0Dimm0      = MemConfig->IdleEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.IdleEnergyCh0Dimm1      = MemConfig->IdleEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.IdleEnergyCh1Dimm0      = MemConfig->IdleEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.IdleEnergyCh1Dimm1      = MemConfig->IdleEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.PdEnergyCh0Dimm0        = MemConfig->PdEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.PdEnergyCh0Dimm1        = MemConfig->PdEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.PdEnergyCh1Dimm0        = MemConfig->PdEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.PdEnergyCh1Dimm1        = MemConfig->PdEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.ActEnergyCh0Dimm0       = MemConfig->ActEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.ActEnergyCh0Dimm1       = MemConfig->ActEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.ActEnergyCh1Dimm0       = MemConfig->ActEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.ActEnergyCh1Dimm1       = MemConfig->ActEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.RdEnergyCh0Dimm0        = MemConfig->RdEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.RdEnergyCh0Dimm1        = MemConfig->RdEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.RdEnergyCh1Dimm0        = MemConfig->RdEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.RdEnergyCh1Dimm1        = MemConfig->RdEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.WrEnergyCh0Dimm0        = MemConfig->WrEnergyCh0Dimm0;
+    FspmUpd->FspmConfig.WrEnergyCh0Dimm1        = MemConfig->WrEnergyCh0Dimm1;
+    FspmUpd->FspmConfig.WrEnergyCh1Dimm0        = MemConfig->WrEnergyCh1Dimm0;
+    FspmUpd->FspmConfig.WrEnergyCh1Dimm1        = MemConfig->WrEnergyCh1Dimm1;
+    FspmUpd->FspmConfig.ThrtCkeMinTmr           = MemConfig->ThrtCkeMinTmr;
+    FspmUpd->FspmConfig.CkeRankMapping          = MemConfig->CkeRankMapping;
+    FspmUpd->FspmConfig.CaVrefConfig            = MemConfig->CaVrefConfig;
+    FspmUpd->FspmConfig.RaplPwrFlCh1            = MemConfig->RaplPwrFlCh1;
+    FspmUpd->FspmConfig.RaplPwrFlCh0            = MemConfig->RaplPwrFlCh0;
+    FspmUpd->FspmConfig.EnCmdRate               = MemConfig->EnCmdRate;
+    FspmUpd->FspmConfig.Refresh2X               = MemConfig->Refresh2X;
+    FspmUpd->FspmConfig.EpgEnable               = MemConfig->EpgEnable;
+    FspmUpd->FspmConfig.RhSolution              = MemConfig->RhSolution;
+    FspmUpd->FspmConfig.UserThresholdEnable     = MemConfig->UserThresholdEnable;
+    FspmUpd->FspmConfig.UserBudgetEnable        = MemConfig->UserBudgetEnable;
+    FspmUpd->FspmConfig.TsodTcritMax            = MemConfig->TsodTcritMax;
+    FspmUpd->FspmConfig.TsodEventMode           = MemConfig->TsodEventMode;
+    FspmUpd->FspmConfig.TsodEventPolarity       = MemConfig->TsodEventPolarity;
+    FspmUpd->FspmConfig.TsodCriticalEventOnly   = MemConfig->TsodCriticalEventOnly;
+    FspmUpd->FspmConfig.TsodEventOutputControl  = MemConfig->TsodEventOutputControl;
+    FspmUpd->FspmConfig.TsodAlarmwindowLockBit  = MemConfig->TsodAlarmwindowLockBit;
+    FspmUpd->FspmConfig.TsodCriticaltripLockBit = MemConfig->TsodCriticaltripLockBit;
+    FspmUpd->FspmConfig.TsodShutdownMode        = MemConfig->TsodShutdownMode;
+    FspmUpd->FspmConfig.TsodThigMax             = MemConfig->TsodThigMax;
+    FspmUpd->FspmConfig.TsodManualEnable        = MemConfig->TsodManualEnable;
+    FspmUpd->FspmConfig.IsvtIoPort              = MemConfig->IsvtIoPort;
+    FspmUpd->FspmConfig.ForceOltmOrRefresh2x    = MemConfig->ForceOltmOrRefresh2x;
+    FspmUpd->FspmConfig.PwdwnIdleCounter        = MemConfig->PwdwnIdleCounter;
+    FspmUpd->FspmConfig.CmdRanksTerminated      = MemConfig->CmdRanksTerminated;
+    FspmUpd->FspmConfig.GdxcEnable              = MemConfig->GdxcEnable;
+    FspmUpd->FspmConfig.RMTLoopCount            = MemConfig->RMTLoopCount;
+
+    // DDR4 Memory Timings
+    FspmUpd->FspmTestConfig.tRRD_L = (UINT8) MemConfig->tRRD_L;
+    FspmUpd->FspmTestConfig.tRRD_S = (UINT8) MemConfig->tRRD_S;
+    FspmUpd->FspmTestConfig.tWTR_L = (UINT8) MemConfig->tWTR_L;
+    FspmUpd->FspmTestConfig.tWTR_S = (UINT8) MemConfig->tWTR_S;
+
+    // TurnAround Timing
+    // Read-to-Read
+    FspmUpd->FspmTestConfig.tRd2RdSG = MemConfig->tRd2RdSG;
+    FspmUpd->FspmTestConfig.tRd2RdDG = MemConfig->tRd2RdDG;
+    FspmUpd->FspmTestConfig.tRd2RdDR = MemConfig->tRd2RdDR;
+    FspmUpd->FspmTestConfig.tRd2RdDD = MemConfig->tRd2RdDD;
+    // Write-to-Read
+    FspmUpd->FspmTestConfig.tWr2RdSG = MemConfig->tWr2RdSG;
+    FspmUpd->FspmTestConfig.tWr2RdDG = MemConfig->tWr2RdDG;
+    FspmUpd->FspmTestConfig.tWr2RdDR = MemConfig->tWr2RdDR;
+    FspmUpd->FspmTestConfig.tWr2RdDD = MemConfig->tWr2RdDD;
+    // Write-to-Write
+    FspmUpd->FspmTestConfig.tWr2WrSG = MemConfig->tWr2WrSG;
+    FspmUpd->FspmTestConfig.tWr2WrDG = MemConfig->tWr2WrDG;
+    FspmUpd->FspmTestConfig.tWr2WrDR = MemConfig->tWr2WrDR;
+    FspmUpd->FspmTestConfig.tWr2WrDD = MemConfig->tWr2WrDD;
+    // Read-to-Write
+    FspmUpd->FspmTestConfig.tRd2WrSG = MemConfig->tRd2WrSG;
+    FspmUpd->FspmTestConfig.tRd2WrDG = MemConfig->tRd2WrDG;
+    FspmUpd->FspmTestConfig.tRd2WrDR = MemConfig->tRd2WrDR;
+    FspmUpd->FspmTestConfig.tRd2WrDD = MemConfig->tRd2WrDD;
+  }
+
+  if (MiscPeiPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.IedSize               = MiscPeiPreMemConfig->IedSize;
+    FspmUpd->FspmConfig.UserBd                = MiscPeiPreMemConfig->UserBd;
+    FspmUpd->FspmConfig.SgDelayAfterPwrEn     = MiscPeiPreMemConfig->SgDelayAfterPwrEn;
+    FspmUpd->FspmConfig.SgDelayAfterHoldReset = MiscPeiPreMemConfig->SgDelayAfterHoldReset;
+    FspmUpd->FspmConfig.MmioSize              = MiscPeiPreMemConfig->MmioSize;
+    FspmUpd->FspmConfig.MmioSizeAdjustment    = MiscPeiPreMemConfig->MmioSizeAdjustment;
+    FspmUpd->FspmConfig.TsegSize              = MiscPeiPreMemConfig->TsegSize;
+
+    FspmUpd->FspmTestConfig.SkipExtGfxScan           = (UINT8) MiscPeiPreMemConfig->SkipExtGfxScan;
+    FspmUpd->FspmTestConfig.BdatEnable               = (UINT8) MiscPeiPreMemConfig->BdatEnable;
+    FspmUpd->FspmTestConfig.BdatTestType             = (UINT8) MiscPeiPreMemConfig->BdatTestType;
+    FspmUpd->FspmTestConfig.ScanExtGfxForLegacyOpRom = (UINT8) MiscPeiPreMemConfig->ScanExtGfxForLegacyOpRom;
+    FspmUpd->FspmTestConfig.LockPTMregs              = (UINT8) MiscPeiPreMemConfig->LockPTMregs;
+  }
+
+  if (Vtd != NULL) {
+    FspmUpd->FspmConfig.X2ApicOptOut = (UINT8) Vtd->X2ApicOptOut;
+    FspmUpd->FspmConfig.VtdBaseAddress[0] = Vtd->BaseAddress[0];
+    FspmUpd->FspmConfig.VtdBaseAddress[1] = Vtd->BaseAddress[1];
+    FspmUpd->FspmConfig.VtdBaseAddress[2] = Vtd->BaseAddress[2];
+    FspmUpd->FspmTestConfig.VtdDisable = (UINT8) Vtd->VtdDisable;
+  }
+
+  if (PciePeiPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.DmiGen3ProgramStaticEq = (UINT8) PciePeiPreMemConfig->DmiGen3ProgramStaticEq;
+    FspmUpd->FspmConfig.Peg0Enable = (UINT8) PciePeiPreMemConfig->Peg0Enable;
+    FspmUpd->FspmConfig.Peg1Enable = (UINT8) PciePeiPreMemConfig->Peg1Enable;
+    FspmUpd->FspmConfig.Peg2Enable = (UINT8) PciePeiPreMemConfig->Peg2Enable;
+    FspmUpd->FspmConfig.Peg3Enable = (UINT8) PciePeiPreMemConfig->Peg3Enable;
+    FspmUpd->FspmConfig.Peg0MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg0MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg1MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg1MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg2MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg2MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg3MaxLinkSpeed = (UINT8) PciePeiPreMemConfig->Peg3MaxLinkSpeed;
+    FspmUpd->FspmConfig.Peg0MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg0MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg1MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg1MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg2MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg2MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg3MaxLinkWidth = (UINT8) PciePeiPreMemConfig->Peg3MaxLinkWidth;
+    FspmUpd->FspmConfig.Peg0PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg0PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.Peg1PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg1PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.Peg2PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg2PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.Peg3PowerDownUnusedLanes = (UINT8) PciePeiPreMemConfig->Peg3PowerDownUnusedLanes;
+    FspmUpd->FspmConfig.InitPcieAspmAfterOprom = (UINT8) PciePeiPreMemConfig->InitPcieAspmAfterOprom;
+    FspmUpd->FspmConfig.PegDisableSpreadSpectrumClocking = (UINT8) PciePeiPreMemConfig->PegDisableSpreadSpectrumClocking;
+    for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
+      FspmUpd->FspmConfig.DmiGen3RootPortPreset[Index] = PciePeiPreMemConfig->DmiGen3RootPortPreset[Index];
+      FspmUpd->FspmConfig.DmiGen3EndPointPreset[Index] = PciePeiPreMemConfig->DmiGen3EndPointPreset[Index];
+      FspmUpd->FspmConfig.DmiGen3EndPointHint[Index] = PciePeiPreMemConfig->DmiGen3EndPointHint[Index];
+    }
+    for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
+      FspmUpd->FspmConfig.DmiGen3RxCtlePeaking[Index] = PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index];
+    }
+    for (Index = 0; Index < SA_PEG_MAX_BUNDLE ; Index++) {
+      FspmUpd->FspmConfig.PegGen3RxCtlePeaking[Index] = PciePeiPreMemConfig->PegGen3RxCtlePeaking[Index];
+    }
+    FspmUpd->FspmConfig.PegDataPtr = (UINT32) PciePeiPreMemConfig->PegDataPtr;
+    CopyMem((VOID *)FspmUpd->FspmConfig.PegGpioData, &PciePeiPreMemConfig->PegGpioData, sizeof (PEG_GPIO_DATA));
+    FspmUpd->FspmConfig.DmiDeEmphasis = PciePeiPreMemConfig->DmiDeEmphasis;
+
+    for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+      FspmUpd->FspmConfig.PegRootPortHPE[Index] = PciePeiPreMemConfig->PegRootPortHPE[Index];
+    }
+    FspmUpd->FspmTestConfig.DmiMaxLinkSpeed     = (UINT8) PciePeiPreMemConfig->DmiMaxLinkSpeed;
+    FspmUpd->FspmTestConfig.DmiGen3EqPh2Enable  = (UINT8) PciePeiPreMemConfig->DmiGen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.DmiGen3EqPh3Method  = (UINT8) PciePeiPreMemConfig->DmiGen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg0Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg0Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg1Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg1Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg2Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg2Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg3Gen3EqPh2Enable = (UINT8) PciePeiPreMemConfig->Peg3Gen3EqPh2Enable;
+    FspmUpd->FspmTestConfig.Peg0Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg0Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg1Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg1Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg2Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg2Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.Peg3Gen3EqPh3Method = (UINT8) PciePeiPreMemConfig->Peg3Gen3EqPh3Method;
+    FspmUpd->FspmTestConfig.PegGen3ProgramStaticEq = (UINT8) PciePeiPreMemConfig->PegGen3ProgramStaticEq;
+    FspmUpd->FspmTestConfig.Gen3SwEqAlwaysAttempt = (UINT8) PciePeiPreMemConfig->Gen3SwEqAlwaysAttempt;
+    FspmUpd->FspmTestConfig.Gen3SwEqNumberOfPresets = (UINT8) PciePeiPreMemConfig->Gen3SwEqNumberOfPresets;
+    FspmUpd->FspmTestConfig.Gen3SwEqEnableVocTest = (UINT8) PciePeiPreMemConfig->Gen3SwEqEnableVocTest;
+    FspmUpd->FspmTestConfig.PegRxCemTestingMode = (UINT8) PciePeiPreMemConfig->PegRxCemTestingMode;
+    FspmUpd->FspmTestConfig.PegRxCemLoopbackLane = (UINT8) PciePeiPreMemConfig->PegRxCemLoopbackLane;
+    FspmUpd->FspmTestConfig.PegGenerateBdatMarginTable = (UINT8) PciePeiPreMemConfig->PegGenerateBdatMarginTable;
+    FspmUpd->FspmTestConfig.PegRxCemNonProtocolAwareness = (UINT8) PciePeiPreMemConfig->PegRxCemNonProtocolAwareness;
+    FspmUpd->FspmTestConfig.PegGen3RxCtleOverride = (UINT8) PciePeiPreMemConfig->PegGen3RxCtleOverride;
+    for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
+      FspmUpd->FspmTestConfig.PegGen3RootPortPreset[Index] = PciePeiPreMemConfig->PegGen3RootPortPreset[Index];
+      FspmUpd->FspmTestConfig.PegGen3EndPointPreset[Index] = PciePeiPreMemConfig->PegGen3EndPointPreset[Index];
+      FspmUpd->FspmTestConfig.PegGen3EndPointHint[Index] = PciePeiPreMemConfig->PegGen3EndPointHint[Index];
+    }
+    FspmUpd->FspmTestConfig.Gen3SwEqJitterDwellTime = PciePeiPreMemConfig->Gen3SwEqJitterDwellTime;
+    FspmUpd->FspmTestConfig.Gen3SwEqJitterErrorTarget = PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget;
+    FspmUpd->FspmTestConfig.Gen3SwEqVocDwellTime = PciePeiPreMemConfig->Gen3SwEqVocDwellTime;
+    FspmUpd->FspmTestConfig.Gen3SwEqVocErrorTarget = PciePeiPreMemConfig->Gen3SwEqVocErrorTarget;
+  }
+
+  if (GtPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.PrimaryDisplay = (UINT8) GtPreMemConfig->PrimaryDisplay;
+    FspmUpd->FspmConfig.InternalGfx = (UINT8) GtPreMemConfig->InternalGraphics;
+    FspmUpd->FspmConfig.IgdDvmt50PreAlloc = (UINT8) GtPreMemConfig->IgdDvmt50PreAlloc;
+    FspmUpd->FspmConfig.ApertureSize = (UINT8) GtPreMemConfig->ApertureSize;
+    FspmUpd->FspmConfig.GttMmAdr = GtPreMemConfig->GttMmAdr;
+    FspmUpd->FspmConfig.GmAdr = GtPreMemConfig->GmAdr;
+    FspmUpd->FspmConfig.GttSize = GtPreMemConfig->GttSize;
+    FspmUpd->FspmConfig.PsmiRegionSize = (UINT8) GtPreMemConfig->PsmiRegionSize;
+    FspmUpd->FspmConfig.GtPsmiSupport = (UINT8)GtPreMemConfig->GtPsmiSupport;
+    FspmUpd->FspmTestConfig.PanelPowerEnable = (UINT8) GtPreMemConfig->PanelPowerEnable;
+    FspmUpd->FspmTestConfig.DeltaT12PowerCycleDelayPreMem = (UINT16) GtPreMemConfig->DeltaT12PowerCycleDelayPreMem;
+  }
+
+  if (SgGpioData != NULL) {
+    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie0Gpio, &SgGpioData->SaRtd3Pcie0Gpio, sizeof (SA_PCIE_RTD3_GPIO));
+    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie1Gpio, &SgGpioData->SaRtd3Pcie1Gpio, sizeof (SA_PCIE_RTD3_GPIO));
+    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie2Gpio, &SgGpioData->SaRtd3Pcie2Gpio, sizeof (SA_PCIE_RTD3_GPIO));
+    FspmUpd->FspmConfig.RootPortIndex = SgGpioData->RootPortIndex;
+  }
+
+  if (IpuPreMemPolicy != NULL) {
+    FspmUpd->FspmConfig.SaIpuEnable = (UINT8) IpuPreMemPolicy->SaIpuEnable;
+    FspmUpd->FspmConfig.SaIpuImrConfiguration = (UINT8) IpuPreMemPolicy->SaIpuImrConfiguration;
+  }
+
+  if (OcPreMemConfig != NULL) {
+    FspmUpd->FspmConfig.SaOcSupport = (UINT8) OcPreMemConfig->OcSupport;
+    FspmUpd->FspmConfig.RealtimeMemoryTiming = (UINT8) OcPreMemConfig->RealtimeMemoryTiming;
+    FspmUpd->FspmConfig.GtVoltageMode = (UINT8) OcPreMemConfig->GtVoltageMode;
+    FspmUpd->FspmConfig.GtMaxOcRatio = OcPreMemConfig->GtMaxOcRatio;
+    FspmUpd->FspmConfig.GtVoltageOffset = OcPreMemConfig->GtVoltageOffset;
+    FspmUpd->FspmConfig.GtVoltageOverride = OcPreMemConfig->GtVoltageOverride;
+    FspmUpd->FspmConfig.GtExtraTurboVoltage = OcPreMemConfig->GtExtraTurboVoltage;
+    FspmUpd->FspmConfig.SaVoltageOffset = OcPreMemConfig->SaVoltageOffset;
+    FspmUpd->FspmConfig.GtusMaxOcRatio = OcPreMemConfig->GtusMaxOcRatio;
+    FspmUpd->FspmConfig.GtusVoltageMode = (UINT8) OcPreMemConfig->GtusVoltageMode;
+    FspmUpd->FspmConfig.GtusVoltageOffset = OcPreMemConfig->GtusVoltageOffset;
+    FspmUpd->FspmConfig.GtusVoltageOverride = OcPreMemConfig->GtusVoltageOverride;
+    FspmUpd->FspmConfig.GtusExtraTurboVoltage = OcPreMemConfig->GtusExtraTurboVoltage;
+  }
+
+
+
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs FSP SA PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_POLICY_PPI             *SiPolicyPpi;
+  SA_MISC_PEI_CONFIG        *MiscPeiConfig;
+  GRAPHICS_PEI_CONFIG       *GtConfig;
+  PCIE_PEI_CONFIG           *PciePeiConfig;
+  GNA_CONFIG                *GnaConfig;
+  UINT8                     Index;
+  EFI_BOOT_MODE             BootMode;
+
+  MiscPeiConfig = NULL;
+  GtConfig      = NULL;
+  PciePeiConfig = NULL;
+  GnaConfig     = NULL;
+
+  //
+  // @todo This could be cleared up after FSP provides ExitBootServices NotifyPhase.
+  //
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate SiPolicyPpi
+  //
+  SiPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi(
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **)&SiPolicyPpi
+             );
+  if ((Status == EFI_SUCCESS) && (SiPolicyPpi != NULL)) {
+    MiscPeiConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid, (VOID *) &MiscPeiConfig);
+    ASSERT_EFI_ERROR (Status);
+
+    GtConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *) &GtConfig);
+    ASSERT_EFI_ERROR (Status);
+
+    GnaConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGnaConfigGuid, (VOID *) &GnaConfig);
+    ASSERT_EFI_ERROR (Status);
+
+    PciePeiConfig = NULL;
+    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID *) &PciePeiConfig);
+    ASSERT_EFI_ERROR (Status);
+
+  }
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Wrapper UpdatePeiSaPolicy\n"));
+
+
+  if (MiscPeiConfig != NULL) {
+    FspsUpd->FspsConfig.Device4Enable = (UINT8) MiscPeiConfig->Device4Enable;
+    FspsUpd->FspsConfig.CridEnable = (UINT8) MiscPeiConfig->CridEnable;
+    FspsUpd->FspsTestConfig.ChapDeviceEnable = (UINT8) MiscPeiConfig->ChapDeviceEnable;
+    FspsUpd->FspsTestConfig.SkipPamLock = (UINT8) MiscPeiConfig->SkipPamLock;
+    FspsUpd->FspsTestConfig.EdramTestMode = (UINT8) MiscPeiConfig->EdramTestMode;
+  }
+
+  if (PciePeiConfig != NULL) {
+    FspsUpd->FspsConfig.DmiAspm = (UINT8) PciePeiConfig->DmiAspm;
+    FspsUpd->FspsTestConfig.DmiExtSync = (UINT8) PciePeiConfig->DmiExtSync;
+    FspsUpd->FspsTestConfig.DmiIot = (UINT8) PciePeiConfig->DmiIot;
+    for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+      FspsUpd->FspsConfig.PegDeEmphasis[Index] = PciePeiConfig->PegDeEmphasis[Index];
+      FspsUpd->FspsConfig.PegSlotPowerLimitValue[Index] = PciePeiConfig->PegSlotPowerLimitValue[Index];
+      FspsUpd->FspsConfig.PegSlotPowerLimitScale[Index] = PciePeiConfig->PegSlotPowerLimitScale[Index];
+      FspsUpd->FspsConfig.PegPhysicalSlotNumber[Index] = PciePeiConfig->PegPhysicalSlotNumber[Index];
+      FspsUpd->FspsTestConfig.PegMaxPayload[Index] = PciePeiConfig->PegMaxPayload[Index];
+    }
+  }
+
+  if (GtConfig != NULL) {
+    FspsUpd->FspsConfig.PavpEnable = (UINT8) GtConfig->PavpEnable;
+    FspsUpd->FspsConfig.CdClock = (UINT8) GtConfig->CdClock;
+    FspsUpd->FspsTestConfig.RenderStandby = (UINT8) GtConfig->RenderStandby;
+    FspsUpd->FspsTestConfig.PmSupport = (UINT8) GtConfig->PmSupport;
+    FspsUpd->FspsTestConfig.CdynmaxClampEnable = (UINT8) GtConfig->CdynmaxClampEnable;
+    FspsUpd->FspsTestConfig.GtFreqMax = (UINT8) GtConfig->GtFreqMax;
+    FspsUpd->FspsTestConfig.DisableTurboGt = (UINT8) GtConfig->DisableTurboGt;
+    FspsUpd->FspsConfig.SkipS3CdClockInit = (UINT8)GtConfig->SkipS3CdClockInit;
+
+    //
+    // For FSP, FspsUpd->FspsConfig.PeiGraphicsPeimInit is always enabled as default.
+    //
+    FspsUpd->FspsConfig.PeiGraphicsPeimInit = (UINT8) GtConfig->PeiGraphicsPeimInit; // SA: InternalOnly: For Internal validation we still need to enable both Enable/Disable Cases
+
+    //
+    // Update UPD: VBT & LogoPtr
+    //
+    if (BootMode == BOOT_ON_S3_RESUME) {
+      FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) NULL;
+    } else {
+      FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) GtConfig->GraphicsConfigPtr;
+    }
+    DEBUG(( DEBUG_INFO, "VbtPtr from GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.GraphicsConfigPtr));
+
+    FspsUpd->FspsConfig.LogoPtr  = (UINT32) GtConfig->LogoPtr;
+    FspsUpd->FspsConfig.LogoSize = GtConfig->LogoSize;
+    DEBUG(( DEBUG_INFO, "LogoPtr from PeiFspSaPolicyInit GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoPtr));
+    DEBUG(( DEBUG_INFO, "LogoSize from PeiFspSaPolicyInit GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoSize));
+
+    FspsUpd->FspsConfig.BltBufferAddress  = (UINT32) GtConfig->BltBufferAddress;
+    FspsUpd->FspsConfig.BltBufferSize     = (UINT32) GtConfig->BltBufferSize;
+
+    //
+    // Update DDI/DDC configuration
+    //
+    FspsUpd->FspsConfig.DdiPortEdp = GtConfig->DdiConfiguration.DdiPortEdp;
+    FspsUpd->FspsConfig.DdiPortBHpd = GtConfig->DdiConfiguration.DdiPortBHpd;
+    FspsUpd->FspsConfig.DdiPortCHpd = GtConfig->DdiConfiguration.DdiPortCHpd;
+    FspsUpd->FspsConfig.DdiPortDHpd = GtConfig->DdiConfiguration.DdiPortDHpd;
+    FspsUpd->FspsConfig.DdiPortFHpd = GtConfig->DdiConfiguration.DdiPortFHpd;
+    FspsUpd->FspsConfig.DdiPortBDdc = GtConfig->DdiConfiguration.DdiPortBDdc;
+    FspsUpd->FspsConfig.DdiPortCDdc = GtConfig->DdiConfiguration.DdiPortCDdc;
+    FspsUpd->FspsConfig.DdiPortDDdc = GtConfig->DdiConfiguration.DdiPortDDdc;
+    FspsUpd->FspsConfig.DdiPortFDdc = GtConfig->DdiConfiguration.DdiPortFDdc;
+
+  }
+
+  if (GnaConfig != NULL) {
+    FspsUpd->FspsConfig.GnaEnable = (UINT8) GnaConfig->GnaEnable;
+#ifdef TESTMENU_FLAG
+#endif // TESTMENU_FLAG
+  }
+
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c
new file mode 100644
index 0000000000..80d20d74a9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c
@@ -0,0 +1,70 @@
+/** @file
+  Implementation of Fsp Security Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SiPolicy.h>
+
+/**
+  Performs FSP Security PEI Policy initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                    Status;
+  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi;
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SecurityPolicy Pre-Mem Start\n"));
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  SiPreMemPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SecurityPolicy Pre-Mem End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP Security PEI Policy post memory initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSecurityPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
new file mode 100644
index 0000000000..98658782aa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
@@ -0,0 +1,95 @@
+/** @file
+  Implementation of Fsp SI Policy Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PeiFspPolicyInitLib.h>
+#include <Ppi/SiPolicy.h>
+
+/**
+  Performs FSP SI PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInitPreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                Status;
+  SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi;
+
+  //
+  // Locate SiPreMemPolicyPpi
+  //
+  SiPreMemPolicyPpi = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Performs FSP SI PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSiPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  EFI_STATUS                   Status;
+  SI_POLICY_PPI                *SiPolicy;
+  SI_CONFIG                    *SiConfig;
+
+  //
+  // Locate SiPolicyPpi
+  //
+  SiPolicy = NULL;
+  Status = PeiServicesLocatePpi (
+             &gSiPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPolicy
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update SiConfig policies
+  //
+  FspsUpd->FspsConfig.SiCsmFlag                = (UINT8)SiConfig->CsmFlag;
+  FspsUpd->FspsConfig.SiSsidTablePtr           = (UINT32)(UINTN)SiConfig->SsidTablePtr;
+  FspsUpd->FspsConfig.SiNumberOfSsidTableEntry = (UINT16)SiConfig->NumberOfSsidTableEntry;
+  FspsUpd->FspsConfig.TraceHubMemBase          =  SiConfig->TraceHubMemBase;
+
+  return EFI_SUCCESS;
+}
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
new file mode 100644
index 0000000000..a341a58930
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
@@ -0,0 +1,100 @@
+/** @file
+  Implementation of Fsp Misc UPD Initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeiLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PeiServicesLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <Library/PciLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <PchAccess.h>
+
+#include "PeiMiscPolicyUpdate.h"
+
+/**
+  Performs FSP Misc UPD initialization.
+
+  @param[in,out]    FspmUpd                 Pointer to FSPM_UPD Data.
+
+  @retval           EFI_SUCCESS             FSP UPD Data is updated.
+  @retval           EFI_NOT_FOUND           An instance of gEfiPeiReadOnlyVariable2PpiGuid
+                                            could not be located.
+  @retval           EFI_OUT_OF_RESOURCES    Insufficent resources to allocate a memory buffer.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspMiscUpdUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariableServices;
+  UINTN                             VariableSize;
+  VOID                              *MemorySavedData;
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiReadOnlyVariable2PpiGuid,
+             0,
+             NULL,
+             (VOID **) &VariableServices
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  VariableSize = 0;
+  MemorySavedData = NULL;
+  Status = VariableServices->GetVariable (
+                               VariableServices,
+                               L"MemoryConfig",
+                               &gFspNonVolatileStorageHobGuid,
+                               NULL,
+                               &VariableSize,
+                               MemorySavedData
+                               );
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    MemorySavedData = AllocatePool (VariableSize);
+    if (MemorySavedData == NULL) {
+      ASSERT (MemorySavedData != NULL);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    DEBUG ((DEBUG_INFO, "VariableSize is 0x%x\n", VariableSize));
+    Status = VariableServices->GetVariable (
+                                 VariableServices,
+                                 L"MemoryConfig",
+                                 &gFspNonVolatileStorageHobGuid,
+                                 NULL,
+                                 &VariableSize,
+                                 MemorySavedData
+                                 );
+    if (Status == EFI_SUCCESS) {
+      FspmUpd->FspmArchUpd.NvsBufferPtr = MemorySavedData;
+    } else {
+      DEBUG ((DEBUG_ERROR, "Fail to retrieve Variable:\"MemoryConfig\" gMemoryConfigVariableGuid, Status = %r\n", Status));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+  FspmUpd->FspmArchUpd.NvsBufferPtr = MemorySavedData;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
new file mode 100644
index 0000000000..5119e934a2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
@@ -0,0 +1,124 @@
+/** @file
+  Provide FSP wrapper platform related function.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/SiliconPolicyUpdateLib.h>
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#include "PeiMiscPolicyUpdate.h"
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyUpdate (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+VOID
+InternalPrintVariableData (
+  IN UINT8   *Data8,
+  IN UINTN   DataSize
+  )
+{
+  UINTN      Index;
+
+  for (Index = 0; Index < DataSize; Index++) {
+    if (Index % 0x10 == 0) {
+      DEBUG ((DEBUG_INFO, "\n%08X:", Index));
+    }
+    DEBUG ((DEBUG_INFO, " %02X", *Data8++));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+/**
+  Performs silicon pre-mem policy update.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+
+  The input Policy must be returned by SiliconPolicyDonePreMem().
+
+  1) In FSP path, the input Policy should be FspmUpd.
+  A platform may use this API to update the FSPM UPD policy initialized
+  by the silicon module or the default UPD data.
+  The output of FSPM UPD data from this API is the final UPD data.
+
+  2) In non-FSP path, the board may use additional way to get
+  the silicon policy data field based upon the input Policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePreMem (
+  IN OUT VOID    *FspmUpd
+  )
+{
+  FSPM_UPD              *FspmUpdDataPtr;
+
+  FspmUpdDataPtr = FspmUpd;
+
+  PeiFspMiscUpdUpdatePreMem (FspmUpdDataPtr);
+  InternalPrintVariableData ((VOID *) FspmUpdDataPtr, sizeof (FSPM_UPD));
+
+  return FspmUpd;
+}
+
+/**
+  Performs silicon post-mem policy update.
+
+  The meaning of Policy is defined by silicon code.
+  It could be the raw data, a handle, a PPI, etc.
+
+  The input Policy must be returned by SiliconPolicyDonePostMem().
+
+  1) In FSP path, the input Policy should be FspsUpd.
+  A platform may use this API to update the FSPS UPD policy initialized
+  by the silicon module or the default UPD data.
+  The output of FSPS UPD data from this API is the final UPD data.
+
+  2) In non-FSP path, the board may use additional way to get
+  the silicon policy data field based upon the input Policy.
+
+  @param[in, out] Policy       Pointer to policy.
+
+  @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePostMem (
+  IN OUT VOID    *FspsUpd
+  )
+{
+  FSPS_UPD              *FspsUpdDataPtr;
+
+  FspsUpdDataPtr = FspsUpd;
+
+  PeiFspPchPolicyUpdate (FspsUpd);
+  InternalPrintVariableData ((VOID * )FspsUpdDataPtr, sizeof (FSPS_UPD));
+
+  return FspsUpd;
+}
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c
new file mode 100644
index 0000000000..455467dc25
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/PchGbeLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchHsioLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <GpioConfig.h>
+#include <GpioPinsSklH.h>
+#include <Library/DebugLib.h>
+#include <Library/PchGbeLib.h>
+#include <PcieDeviceOverrideTable.h>
+
+/**
+  Performs FSP PCH PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyUpdate (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  FspsUpd->FspsConfig.PchPcieDeviceOverrideTablePtr = (UINT32) mPcieDeviceTable;
+
+  AddPlatformVerbTables (
+    PchHdaCodecPlatformOnboard,
+    &(FspsUpd->FspsConfig.PchHdaVerbTableEntryNum),
+    &(FspsUpd->FspsConfig.PchHdaVerbTablePtr)
+    );
+
+DEBUG_CODE_BEGIN();
+if ((PcdGet8 (PcdSerialIoUartDebugEnable) == 1) &&
+      FspsUpd->FspsConfig.SerialIoDevMode[PchSerialIoIndexUart0 + PcdGet8 (PcdSerialIoUartNumber)] == PchSerialIoDisabled ) {
+    FspsUpd->FspsConfig.SerialIoDevMode[PchSerialIoIndexUart0 + PcdGet8 (PcdSerialIoUartNumber)] = PchSerialIoHidden;
+  }
+DEBUG_CODE_END();
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..cbb818c875
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
@@ -0,0 +1,39 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchHsioLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <PchHsioPtssTables.h>
+#include <Library/DebugLib.h>
+
+/**
+  Performs FSP PCH PEI Policy pre mem initialization.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspPchPolicyUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c
new file mode 100644
index 0000000000..2114479030
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c
@@ -0,0 +1,85 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <Guid/MemoryTypeInformation.h>
+#include <Library/HobLib.h>
+#include <PchAccess.h>
+#include <SaAccess.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/PeiLib.h>
+
+/**
+  Performs FSP SA PEI Policy initialization.
+
+  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyUpdate (
+  IN OUT FSPS_UPD    *FspsUpd
+  )
+{
+  VOID                            *Buffer;
+  VOID                            *MemBuffer;
+  UINT32                          Size;
+
+  DEBUG((DEBUG_INFO, "\nUpdating SA Policy in Post Mem\n"));
+
+    FspsUpd->FspsConfig.PeiGraphicsPeimInit = 1;
+
+    Size   = 0;
+    Buffer = NULL;
+    PeiGetSectionFromAnyFv (PcdGetPtr (PcdGraphicsVbtGuid), EFI_SECTION_RAW, 0, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_WARN, "Could not locate VBT\n"));
+    } else {
+      MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+      if ((MemBuffer != NULL) && (Buffer != NULL)) {
+        CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+        FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32)(UINTN)MemBuffer;
+      } else {
+        DEBUG((DEBUG_WARN, "Error in locating / copying VBT.\n"));
+        FspsUpd->FspsConfig.GraphicsConfigPtr = 0;
+      }
+    }
+    DEBUG((DEBUG_INFO, "Vbt Pointer from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.GraphicsConfigPtr));
+    DEBUG((DEBUG_INFO, "Vbt Size from PeiGetSectionFromFv is 0x%x\n", Size));
+
+    Size   = 0;
+    Buffer = NULL;
+    PeiGetSectionFromAnyFv (&gTianoLogoGuid, EFI_SECTION_RAW, 0, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_WARN, "Could not locate Logo\n"));
+    } else {
+      MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+      if ((MemBuffer != NULL) && (Buffer != NULL)) {
+        CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+        FspsUpd->FspsConfig.LogoPtr = (UINT32)(UINTN)MemBuffer;
+        FspsUpd->FspsConfig.LogoSize = Size;
+      } else {
+        DEBUG((DEBUG_WARN, "Error in locating / copying LogoPtr.\n"));
+        FspsUpd->FspsConfig.LogoPtr = 0;
+        FspsUpd->FspsConfig.LogoSize = 0;
+      }
+    }
+    DEBUG((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.LogoPtr));
+    DEBUG((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", FspsUpd->FspsConfig.LogoSize));
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..946182864e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
@@ -0,0 +1,87 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <CpuRegs.h>
+#include <Library/CpuPlatformLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Library/HobLib.h>
+#include <PchAccess.h>
+#include <SaAccess.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklH.h>
+
+
+/**
+  Performs FSP SA PEI Policy initialization in pre-memory.
+
+  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
+
+  @retval          EFI_SUCCESS         FSP UPD Data is updated.
+  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
+  @retval          Other               FSP UPD Data update process fail.
+**/
+EFI_STATUS
+EFIAPI
+PeiFspSaPolicyUpdatePreMem (
+  IN OUT FSPM_UPD    *FspmUpd
+  )
+{
+  VOID                        *Buffer;
+
+  //
+  // If SpdAddressTable are not all 0, it means DIMM slots implemented and
+  // MemorySpdPtr* already updated by reading SPD from DIMM in SiliconPolicyInitPreMem.
+  //
+  // If SpdAddressTable all 0, this is memory down design and hardcoded SpdData
+  // should be applied to MemorySpdPtr*.
+  //
+  if ((PcdGet8 (PcdMrcSpdAddressTable0) == 0) && (PcdGet8 (PcdMrcSpdAddressTable1) == 0)
+      && (PcdGet8 (PcdMrcSpdAddressTable2) == 0) && (PcdGet8 (PcdMrcSpdAddressTable3) == 0)) {
+    DEBUG ((DEBUG_INFO, "Overriding SPD data for down memory.\n"));
+    CopyMem (
+      (VOID *) (UINTN) FspmUpd->FspmConfig.MemorySpdPtr00,
+      (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData),
+      PcdGet16 (PcdMrcSpdDataSize)
+      );
+    CopyMem (
+      (VOID *) (UINTN) FspmUpd->FspmConfig.MemorySpdPtr10,
+      (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData),
+      PcdGet16 (PcdMrcSpdDataSize)
+      );
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Byte Map and DQS Byte Swizzling Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh0, Buffer, 12);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh1, (UINT8*) Buffer + 12, 12);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh0, Buffer, 8);
+    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh1, (UINT8*) Buffer + 8, 8);
+  }
+
+  DEBUG((DEBUG_INFO, "Updating Dq Pins Interleaved,Rcomp Resistor & Rcomp Target Settings...\n"));
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompResistor, Buffer, 6);
+  }
+  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget);
+  if (Buffer) {
+    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompTarget, Buffer, 10);
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
new file mode 100644
index 0000000000..a767289bc5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
@@ -0,0 +1,163 @@
+/** @file
+  Provide FSP wrapper platform sec related function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Ppi/TopOfTemporaryRam.h>
+#include <Guid/FirmwareFileSystem2.h>
+
+#include <Library/LocalApicLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param[in]     PeiServices               Pointer to the PEI Services Table.
+  @param[in,out] StructureSize             Pointer to the variable describing size of the input buffer.
+  @param[out]    PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  );
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval EFI_SUCCESS  The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  );
+
+PEI_SEC_PERFORMANCE_PPI  mSecPerformancePpi = {
+  SecGetPerformance
+};
+
+EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gTopOfTemporaryRamPpiGuid,
+    NULL // To be patched later.
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gPeiSecPerformancePpiGuid,
+    &mSecPerformancePpi
+  },
+};
+
+#define LEGACY_8259_MASK_REGISTER_MASTER                  0x21
+#define LEGACY_8259_MASK_REGISTER_SLAVE                   0xA1
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER  0x4D0
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE   0x4D1
+
+/**
+  Write to mask and edge/level triggered registers of master and slave 8259 PICs.
+
+  @param[in]  Mask       low byte for master PIC mask register,
+                         high byte for slave PIC mask register.
+  @param[in]  EdgeLevel  low byte for master PIC edge/level triggered register,
+                         high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259WriteMask (
+  IN UINT16  Mask,
+  IN UINT16  EdgeLevel
+  )
+{
+  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, (UINT8) Mask);
+  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8) (Mask >> 8));
+  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8) EdgeLevel);
+  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8) (EdgeLevel >> 8));
+}
+
+/**
+  A developer supplied function to perform platform specific operations.
+
+  It's a developer supplied function to perform any operations appropriate to a
+  given platform. It's invoked just before passing control to PEI core by SEC
+  core. Platform developer may modify the SecCoreData passed to PEI Core.
+  It returns a platform specific PPI list that platform wishes to pass to PEI core.
+  The Generic SEC core module will merge this list to join the final list passed to
+  PEI core.
+
+  @param[in,out] SecCoreData           The same parameter as passing to PEI core. It
+                                       could be overridden by this function.
+
+  @return The platform specific PPI list to be passed to PEI core or
+          NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
+  )
+{
+  EFI_PEI_PPI_DESCRIPTOR      *PpiList;
+
+  DEBUG ((DEBUG_INFO, "FSP Wrapper BootFirmwareVolumeBase - 0x%x\n", SecCoreData->BootFirmwareVolumeBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper BootFirmwareVolumeSize - 0x%x\n", SecCoreData->BootFirmwareVolumeSize));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper TemporaryRamBase       - 0x%x\n", SecCoreData->TemporaryRamBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper TemporaryRamSize       - 0x%x\n", SecCoreData->TemporaryRamSize));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper PeiTemporaryRamBase    - 0x%x\n", SecCoreData->PeiTemporaryRamBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper PeiTemporaryRamSize    - 0x%x\n", SecCoreData->PeiTemporaryRamSize));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper StackBase              - 0x%x\n", SecCoreData->StackBase));
+  DEBUG ((DEBUG_INFO, "FSP Wrapper StackSize              - 0x%x\n", SecCoreData->StackSize));
+
+  InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
+
+  //
+  // Set all 8259 interrupts to edge triggered and disabled
+  //
+  Interrupt8259WriteMask (0xFFFF, 0x0000);
+
+  //
+  // Use middle of Heap as temp buffer, it will be copied by caller.
+  // Do not use Stack, because it will cause wrong calculation on stack by PeiCore
+  //
+  PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize/2);
+  CopyMem (PpiList, mPeiSecPlatformPpi, sizeof(mPeiSecPlatformPpi));
+
+  //
+  // Patch TopOfTemporaryRamPpi
+  //
+  PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize);
+
+  return PpiList;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c
new file mode 100644
index 0000000000..06ca63c19a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c
@@ -0,0 +1,54 @@
+/** @file
+  Provide platform init function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/SecBoardInitLib.h>
+#include <Library/TestPointCheckLib.h>
+#include <Register/PchRegsPmc.h>
+#include <Library/IoLib.h>
+
+/**
+  Platform initialization.
+
+  @param[in] FspHobList   HobList produced by FSP.
+  @param[in] StartOfRange Start of temporary RAM.
+  @param[in] EndOfRange   End of temporary RAM.
+**/
+VOID
+EFIAPI
+PlatformInit (
+  IN VOID                 *FspHobList,
+  IN VOID                 *StartOfRange,
+  IN VOID                 *EndOfRange
+  )
+{
+  ///
+  /// Halt the TCO timer as early as possible
+  ///
+  IoWrite16 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO1_CNT, B_TCO_IO_TCO1_CNT_TMR_HLT);
+
+  //
+  // Platform initialization
+  // Enable Serial port here
+  //
+  if (PcdGetBool(PcdSecSerialPortDebugEnable)) {
+    SerialPortInitialize ();
+  }
+
+  DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in PlatformInit\n"));
+  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
+  DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
+  DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
+
+  BoardAfterTempRamInit ();
+
+  TestPointTempMemoryFunction (StartOfRange, EndOfRange);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c
new file mode 100644
index 0000000000..67bdd232bb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c
@@ -0,0 +1,90 @@
+/** @file
+  Sample to provide SecGetPerformance function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPerformance.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval EFI_SUCCESS  The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  )
+{
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  UINT64      Ticker;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // |--------------| <- TopOfTemporaryRam - BL
+  // |   List Ptr   |
+  // |--------------|
+  // | BL RAM Start |
+  // |--------------|
+  // |  BL RAM End  |
+  // |--------------|
+  // |Number of BSPs|
+  // |--------------|
+  // |     BIST     |
+  // |--------------|
+  // |     ....     |
+  // |--------------|
+  // |  TSC[63:32]  |
+  // |--------------|
+  // |  TSC[31:00]  |
+  // |--------------|
+  //
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  Count             = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));
+  Size              = Count * sizeof (UINT32);
+
+  Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2);
+  Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
new file mode 100644
index 0000000000..e05daa8784
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
@@ -0,0 +1,79 @@
+/** @file
+  Provide SecPlatformInformation function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param[in]     PeiServices               Pointer to the PEI Services Table.
+  @param[in,out] StructureSize             Pointer to the variable describing size of the input buffer.
+  @param[out]    PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  )
+{
+  UINT32      *Bist;
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // The entries of BIST information, together with the number of them,
+  // reside in the bottom of stack, left untouched by normal stack operation.
+  // This routine copies the BIST information to the buffer pointed by
+  // PlatformInformationRecord for output.
+  //
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  Count             = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32)));
+  Size              = Count * sizeof (IA32_HANDOFF_STATUS);
+
+  if ((*StructureSize) < (UINT64) Size) {
+    *StructureSize = Size;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *StructureSize  = Size;
+  Bist            = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);
+
+  CopyMem (PlatformInformationRecord, Bist, Size);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c
new file mode 100644
index 0000000000..04f12a9438
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c
@@ -0,0 +1,37 @@
+/** @file
+  Provide TempRamInitParams data.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/PcdLib.h>
+#include <FspEas.h>
+#include "FsptCoreUpd.h"
+
+typedef struct {
+  FSP_UPD_HEADER    FspUpdHeader;
+  FSPT_CORE_UPD     FsptCoreUpd;
+} FSPT_UPD_CORE_DATA;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA FsptUpdDataPtr = {
+  {
+    0x4450555F54505346,
+    0x00,
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+  },
+  {
+    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicrocodeOffset)),
+    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicrocodeOffset)),
+    0,          // Set CodeRegionBase as 0, so that caching will be 4GB-(CodeRegionSize > LLCSize ? LLCSize : CodeRegionSize) will be used.
+    FixedPcdGet32 (PcdFlashCodeCacheSize),
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+  }
+};
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c
new file mode 100644
index 0000000000..6d65d7d23f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c
@@ -0,0 +1,48 @@
+/** @file
+  Provide SecTemporaryRamDone function.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/TemporaryRamDone.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/FspWrapperPlatformLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/BoardInitLib.h>
+
+/**
+This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *TempRamExitParam;
+
+  DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n"));
+
+  Status = BoardInitBeforeTempRamExit ();
+  ASSERT_EFI_ERROR (Status);
+
+  TempRamExitParam = UpdateTempRamExitParam ();
+  Status = CallTempRamExit (TempRamExitParam);
+  DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
+  ASSERT_EFI_ERROR(Status);
+
+  Status = BoardInitAfterTempRamExit ();
+  ASSERT_EFI_ERROR (Status);
+
+  return ;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
new file mode 100644
index 0000000000..7bdb3943e5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
@@ -0,0 +1,48 @@
+/** @file
+  ACPI Timer implements one instance of Timer Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+
+/**
+  Calculate TSC frequency.
+
+  The TSC counting frequency is determined by comparing how far it counts
+  during a 101.4 us period as determined by the ACPI timer.
+  The ACPI timer is used because it counts at a known frequency.
+  The TSC is sampled, followed by waiting 363 counts of the ACPI timer,
+  or 101.4 us. The TSC is then sampled again. The difference multiplied by
+  9861 is the TSC frequency. There will be a small error because of the
+  overhead of reading the ACPI timer. An attempt is made to determine and
+  compensate for this error.
+
+  @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+  VOID
+  );
+
+/**
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+InternalGetPerformanceCounterFrequency (
+  VOID
+  )
+{
+  return InternalCalculateTscFrequency ();
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
new file mode 100644
index 0000000000..8498952888
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
@@ -0,0 +1,310 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/GpioExpanderLib.h>
+#include <Library/I2cAccessLib.h>
+
+//
+// Addresses of registers inside expander
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mInputRegister[3]    = {0x0,0x1,0x2};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mOutputRegister[3]   = {0x4,0x5,0x6};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mConfigRegister[3]   = {0xC,0xD,0xE};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mPolarityRegister[3] = {0x8,0x9,0xA};
+
+#define PCH_SERIAL_IO_I2C4                 4
+#define TCA6424_I2C_ADDRESS 0x22
+#define PINS_PER_REGISTER                  8
+#define GPIO_EXP_PIN_DIRECTION_OUT         1
+#define GPIO_EXP_PIN_DIRECTION_IN          0
+#define GPIO_EXP_PIN_POLARITY_NORMAL       0
+#define GPIO_EXP_PIN_POLARITY_INVERTED     1
+#define GPIO_EXP_SET_OUTPUT                0
+#define GPIO_EXP_SET_DIR                   1
+#define GPIO_EXP_GET_INPUT                 2
+#define GPIO_EXP_SET_POLARITY              3
+#define AUTO_INCREMENT 0x80
+
+/**
+  Returns the Controller on which GPIO expander is present.
+
+  This function returns the Controller value
+
+  @param[out] Controller              Pointer to a Controller value on
+                                      which I2C expander is configured.
+
+  @retval     EFI_SUCCESS              non.
+**/
+EFI_STATUS
+GpioExpGetController (
+  OUT UINT8 *Controller
+  )
+{
+  *Controller = PCH_SERIAL_IO_I2C4;
+  return EFI_SUCCESS;
+}
+
+/**
+  Returns the data from register value giving in the input.
+
+  This function is to get the data from the Expander
+  Registers by following the I2C Protocol communication
+
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+
+  @retval     UINT8      Value returned from the register
+**/
+UINT8
+GpioExpGetRegister (
+  IN UINTN Bar0,
+  IN UINT8 Address,
+  IN UINT8 Register
+  )
+{
+  EFI_STATUS Status;
+  UINT8 WriBuf[1];
+  UINT8 ReBuf[1] = {0};
+
+  WriBuf[0] = Register;
+  Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 1, WriBuf, 1, ReBuf, WAIT_1_SECOND);
+
+  return ReBuf[0];
+}
+/**
+  Set the input register to a give value mentioned in the function.
+
+  This function is to Programm the data value to the Expander
+  Register by following the I2C Protocol communication.
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+  @param[in]  Value      Value to set in the mentioned the register
+**/
+VOID
+GpioExpSetRegister (
+  IN UINTN Bar0,
+  IN UINT8 Address,
+  IN UINT8 Register,
+  IN UINT8 Value
+  )
+{
+  EFI_STATUS Status;
+  UINT8 WriBuf[2];
+
+  WriBuf[0] = Register;
+  WriBuf[1] = Value;
+  Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 2, WriBuf, 0, NULL, WAIT_1_SECOND);
+
+}
+/**
+  Set the input register to a give value mentioned in the function.
+
+  This function is to update the status of the Gpio Expander
+  pin based on the input Operation value of the caller.This
+  function calculates the exact address of the register with
+  the help of the Register Bank
+
+  @param[in]  Controller  SerialIo Controller value
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+  @param[in]  Operation   Type of operation (Setoutput/Setdirection
+                          /Getinput/Setpolarity)
+  @retval     UINT8       Final Value returned from the register
+**/
+UINT8
+GpioExpDecodeRegAccess (
+  IN UINT8 Controller,
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value,
+  IN UINT8 Operation
+  )
+{
+  UINT8* RegisterBank;
+  UINT8 OldValue;
+  UINT8 NewValue;
+  UINT8 RegisterAddress;
+  UINT8 PinNumber;
+  UINT8 ReturnValue = 0;
+
+  DEBUG ((DEBUG_INFO, "GpioExpDecodeRegAccess() %x:%x:%x:%x:%x\n", Controller, Expander, Pin, Value, Operation));
+  ASSERT(Controller<6);
+  ASSERT(Expander<2);
+  ASSERT(Pin<24);
+  ASSERT(Value<2);
+  ASSERT(Operation<4);
+  //
+  // Find the register Address value based on the OPeration
+  //
+  switch(Operation) {
+    case GPIO_EXP_SET_OUTPUT:
+      RegisterBank = mOutputRegister;
+      break;
+    case GPIO_EXP_SET_DIR:
+      RegisterBank = mConfigRegister;
+      break;
+    case GPIO_EXP_GET_INPUT:
+      RegisterBank = mInputRegister;
+      break;
+    case GPIO_EXP_SET_POLARITY:
+      RegisterBank = mPolarityRegister;
+      break;
+    default:
+      ASSERT(FALSE);
+      return 0;
+    }
+  //
+  // Each bit of register represents each Pin
+  // calaulate the register address and Pinnumber(offset with in register)
+  //
+  if (Pin >= 24) {
+    //
+    // Avoid out-of-bound usage of RegisterBank
+    //
+    return 0;
+  }
+
+  RegisterAddress = RegisterBank[(Pin/PINS_PER_REGISTER)];
+  PinNumber = Pin%PINS_PER_REGISTER;
+
+  OldValue = GpioExpGetRegister(FindSerialIoBar(Controller, 0), Expander, RegisterAddress);
+  //
+  // If it to get the data ,just returned otherwise mark the input value and write the register
+  //
+  if (Operation == GPIO_EXP_GET_INPUT) {
+    ReturnValue = 0x1 & (OldValue>>PinNumber);
+  } else {
+    NewValue = OldValue;
+    NewValue &= ~(BIT0<<PinNumber);
+    NewValue |= (Value<<PinNumber);
+    if(NewValue!=OldValue) {
+      GpioExpSetRegister(FindSerialIoBar(Controller, 0), Expander, RegisterAddress, NewValue);
+    }
+  }
+  return ReturnValue;
+}
+/**
+  Set the Output value for the given Expander Gpio pin.
+
+  This function is to Set the Output value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetOutput (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  )
+{
+  UINT8 Controller;
+  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+    GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_OUTPUT);
+  }
+}
+/**
+  Set the Direction value for the given Expander Gpio pin.
+
+  This function is to Set the direction value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+**/
+VOID
+GpioExpSetDirection (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  )
+{
+
+  UINT8 Controller;
+  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+    GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_DIR);
+  }
+}
+
+
+/**
+  Get the input value for the given Expander Gpio pin.
+
+  This function is to get the input value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+
+  @retval     UINT8       Final Value returned from the register
+**/
+UINT8
+GpioExpGetInput (
+  IN UINT8 Expander,
+  IN UINT8 Pin
+  )
+{
+  UINT8 Controller;
+  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+    return GpioExpDecodeRegAccess(Controller,Expander,Pin,0,GPIO_EXP_GET_INPUT);
+  }
+  return 0;
+}
+
+/**
+  Configures all registers of a single IO Expander in one go.
+
+  @param[in]  Expander    Expander number (0/1)
+  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc. 0=output, 1=input
+  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0, etc. 0=normal, 1=inversion
+  @param[in]  Output      Bit-encoded output state, ignores polarity, only applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
+
+**/
+VOID
+GpioExpBulkConfig (
+  IN UINT8  Expander,
+  IN UINT32 Direction,
+  IN UINT32 Polarity,
+  IN UINT32 Output
+  )
+{
+  UINT8 WriteBuf[4];
+  UINT8 Controller;
+
+  GpioExpGetController(&Controller);
+
+  WriteBuf[0] = mOutputRegister[0] + AUTO_INCREMENT;
+  WriteBuf[1] = Output & 0xFF;
+  WriteBuf[2] = (Output>>8) & 0xFF;
+  WriteBuf[3] = (Output>>16) & 0xFF;
+  I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+  WriteBuf[0] = mPolarityRegister[0] + AUTO_INCREMENT;
+  WriteBuf[1] = Polarity & 0xFF;
+  WriteBuf[2] = (Polarity>>8) & 0xFF;
+  WriteBuf[3] = (Polarity>>16) & 0xFF;
+  I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+  WriteBuf[0] = mConfigRegister[0] + AUTO_INCREMENT;
+  WriteBuf[1] = Direction & 0xFF;
+  WriteBuf[2] = (Direction>>8) & 0xFF;
+  WriteBuf[3] = (Direction>>16) & 0xFF;
+  I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c
new file mode 100644
index 0000000000..b8afd791f0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c
@@ -0,0 +1,132 @@
+/** @file
+  This file is SampleCode of the library for Intel HD Audio Verb Table configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <ConfigBlock.h>
+#include <PlatformBoardId.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include "PchHdaVerbTables.h"
+
+/**
+  Add verb table helper function.
+  This function calculates verbtable number and shows verb table information.
+
+  @param[in,out] VerbTableEntryNum      Input current VerbTable number and output the number after adding new table
+  @param[in,out] VerbTableArray         Pointer to array of VerbTable
+  @param[in]     VerbTable              VerbTable which is going to add into array
+**/
+STATIC
+VOID
+InternalAddVerbTable (
+  IN OUT  UINT8                   *VerbTableEntryNum,
+  IN OUT  UINT32                  *VerbTableArray,
+  IN      HDAUDIO_VERB_TABLE      *VerbTable
+  )
+{
+  if (VerbTable == NULL) {
+    DEBUG ((DEBUG_INFO, "InternalAddVerbTable wrong input: VerbTable == NULL\n"));
+    return;
+  }
+
+  VerbTableArray[*VerbTableEntryNum] = (UINT32) VerbTable;
+  *VerbTableEntryNum += 1;
+
+  DEBUG ((DEBUG_INFO,
+    "HDA: Add verb table for vendor = 0x%04X devId = 0x%04X (size = %d DWords)\n",
+    VerbTable->Header.VendorId,
+    VerbTable->Header.DeviceId,
+    VerbTable->Header.DataDwords)
+    );
+}
+
+/**
+  Add verb table function.
+  This function update the verb table number and verb table ptr of policy.
+
+  @param[in]  HdAudioConfig            HD Audio config block
+  @param[out] VerbTableEntryNum        Number of verb table entries
+  @param[out] HdaVerbTablePtr          Pointer to the verb table
+**/
+VOID
+AddPlatformVerbTables (
+  IN   UINT8              CodecType,
+  OUT  UINT8              *VerbTableEntryNum,
+  OUT  UINT32             *HdaVerbTablePtr
+  )
+{
+  UINT8                   VerbTableEntries;
+  UINT32                  VerbTableArray[6];
+  UINT32                  *VerbTablePtr;
+
+  VerbTableEntries = 0;
+
+  InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdDisplayAudioHdaVerbTable));
+
+  if (CodecType == PchHdaCodecPlatformOnboard) {
+    DEBUG ((DEBUG_INFO, "HDA Policy: Onboard codec selected\n"));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdHdaVerbTable));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdHdaVerbTable2));
+  } else {
+    DEBUG ((DEBUG_INFO, "HDA Policy: External codec kit selected\n"));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdCommonHdaVerbTable1));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdCommonHdaVerbTable2));
+    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN) PcdGet32 (PcdCommonHdaVerbTable3));
+  }
+
+  *VerbTableEntryNum = VerbTableEntries;
+
+  VerbTablePtr = (UINT32 *) AllocateZeroPool (sizeof (UINT32) * VerbTableEntries);
+  CopyMem (VerbTablePtr, VerbTableArray, sizeof (UINT32) * VerbTableEntries);
+  *HdaVerbTablePtr = (UINT32) VerbTablePtr;
+}
+
+/**
+  HDA VerbTable init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+HdaVerbTableInit (
+  IN UINT16 BoardId
+  )
+{
+  HDAUDIO_VERB_TABLE *VerbTable;
+  HDAUDIO_VERB_TABLE *VerbTable2;
+
+  VerbTable = NULL;
+  VerbTable2 = NULL;
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      VerbTable = &WhlHdaVerbTableAlc700;
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "HDA: Init default verb tables (Realtek ALC700 and ALC701)\n"));
+      VerbTable = &HdaVerbTableAlc700;
+      VerbTable2 = &HdaVerbTableAlc701;
+      break;
+  }
+
+  PcdSet32S (PcdHdaVerbTable, (UINT32) VerbTable);
+  PcdSet32S (PcdHdaVerbTable2, (UINT32) VerbTable2);
+  PcdSet32S (PcdDisplayAudioHdaVerbTable, (UINT32) &HdaVerbTableDisplayAudio);
+
+  // Codecs - Realtek ALC700, ALC701, ALC274 (external - connected via HDA header)
+  PcdSet32S (PcdCommonHdaVerbTable1, (UINT32) &HdaVerbTableAlc700);
+  PcdSet32S (PcdCommonHdaVerbTable2, (UINT32) &HdaVerbTableAlc701);
+  PcdSet32S (PcdCommonHdaVerbTable3, (UINT32) &HdaVerbTableAlc274);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
new file mode 100644
index 0000000000..70f531daca
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
@@ -0,0 +1,115 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/I2cAccessLib.h>
+
+EFI_STATUS
+I2cWriteRead (
+  IN UINTN  MmioBase,
+  IN UINT8  SlaveAddress,
+  IN UINT8  WriteLength,
+  IN UINT8  *WriteBuffer,
+  IN UINT8  ReadLength,
+  IN UINT8  *ReadBuffer,
+  IN UINT64  TimeBudget
+  //TODO: add Speed parameter
+  )
+{
+  UINT8 ReadsNeeded = ReadLength;
+  UINT64 CutOffTime;
+
+  if ((WriteLength == 0 && ReadLength == 0) ||
+      (WriteLength != 0 && WriteBuffer == NULL) ||
+      (ReadLength != 0 && ReadBuffer == NULL) ) {
+    DEBUG ((DEBUG_ERROR, "I2cWR Invalid Parameters\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Sanity checks to verify the I2C controller is alive
+  // Conveniently, ICON register's values of 0 or FFFFFFFF indicate
+  // I2c controller is out-of-order: either disabled, in D3 or in reset.
+  //
+  if (MmioRead32(MmioBase+R_IC_CON) == 0xFFFFFFFF || MmioRead32(MmioBase+R_IC_CON) == 0x0) {
+    DEBUG ((DEBUG_ERROR, "I2cWR Device Error\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  MmioWrite32(MmioBase+R_IC_ENABLE, 0x0);
+  MmioRead32(MmioBase+0x40);
+  MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
+  MmioWrite32(MmioBase+R_IC_SDA_HOLD, 0x001C001C);
+  //
+  // Set I2C Bus Speed at 400 kHz for GPIO Expander
+  //
+  MmioWrite32(MmioBase + R_IC_FS_SCL_HCNT, 128);
+  MmioWrite32(MmioBase + R_IC_FS_SCL_LCNT, 160);
+  MmioWrite32(MmioBase + R_IC_TAR, SlaveAddress);
+  MmioWrite32(MmioBase + R_IC_CON, B_IC_MASTER_MODE | V_IC_SPEED_FAST | B_IC_RESTART_EN | B_IC_SLAVE_DISABLE );
+  MmioWrite32(MmioBase+R_IC_ENABLE, 0x1);
+  CutOffTime = AsmReadTsc() + TimeBudget;
+
+  while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==0 ) {
+    if (AsmReadTsc() > CutOffTime) {
+      DEBUG ((DEBUG_ERROR, "I2cWR timeout\n"));
+      return EFI_TIMEOUT;
+    }
+  }
+
+  while(1) {
+    if(MmioRead32(MmioBase+R_IC_INTR_STAT) & B_IC_INTR_TX_ABRT) {
+      DEBUG ((DEBUG_ERROR, "I2cWR Transfer aborted, reason = 0x%08x\n",MmioRead32(MmioBase+R_IC_TX_ABRT_SOURCE)));
+      MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
+      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+      return EFI_DEVICE_ERROR;
+    }
+    if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_TFNF) {
+      if (WriteLength > 1) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
+        WriteBuffer++;
+        WriteLength--;
+      } else if (WriteLength==1 && ReadLength != 0) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
+        WriteBuffer++;
+        WriteLength--;
+      } else if (WriteLength==1 && ReadLength == 0) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer | B_IC_CMD_STOP);
+        WriteBuffer++;
+        WriteLength--;
+      } else if (ReadLength > 1) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ);
+        ReadLength--;
+      } else if (ReadLength == 1) {
+        MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ|B_IC_CMD_STOP);
+        ReadLength--;
+      }
+    }
+
+    if (ReadsNeeded) {
+      if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_RFNE) {
+        *ReadBuffer = (UINT8)MmioRead32(MmioBase+R_IC_DATA_CMD);
+        ReadBuffer++;
+        ReadsNeeded--;
+      }
+    }
+    if (WriteLength==0 && ReadsNeeded==0 && !(MmioRead32(MmioBase+R_IC_STATUS)&B_IC_STATUS_ACTIVITY)) {
+      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+      DEBUG ((DEBUG_INFO, "I2cWR success\n"));
+      return EFI_SUCCESS;
+    }
+    if (AsmReadTsc() > CutOffTime) {
+      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+      DEBUG ((DEBUG_ERROR, "I2cWR wrong ENST value\n"));
+      return EFI_TIMEOUT;
+    }
+
+  }
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c
new file mode 100644
index 0000000000..7b9a32b3f5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c
@@ -0,0 +1,88 @@
+/** @file
+  This file is the library for CPU DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DxeCpuPolicyUpdateLib.h>
+
+/**
+  This function prints the CPU DXE phase policy.
+
+  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
+**/
+VOID
+CpuDxePrintPolicyProtocol (
+  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU Policy (DXE) print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : %x\n", DxeCpuPolicy->Revision));
+  ASSERT (DxeCpuPolicy->Revision == DXE_CPU_POLICY_PROTOCOL_REVISION);
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU_DXE_CONFIG -----------------\n"));
+  DEBUG ((DEBUG_INFO, "EnableDts : %x\n", DxeCpuPolicy->EnableDts));
+  DEBUG ((DEBUG_INFO, "\n------------------------ CPU Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+}
+
+/**
+  Get data for CPU policy from setup options.
+
+  @param[in] DxeCpuPolicy              The pointer to get CPU Policy protocol instance
+
+  @retval EFI_SUCCESS                  Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSiCpuPolicy (
+  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
+  )
+{
+  EFI_STATUS            Status;
+
+  ///
+  /// Print CPU DXE Policy
+  ///
+  CpuDxePrintPolicyProtocol(DxeCpuPolicy);
+
+  ///
+  /// Install the DXE_CPU_POLICY_PROTOCOL interface
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gDxeCpuPolicyProtocolGuid,
+                  DxeCpuPolicy,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c
new file mode 100644
index 0000000000..863df3328c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c
@@ -0,0 +1,105 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeMePolicyUpdate.h"
+
+//
+// Record version
+//
+#define RECORD_REVISION_1              0x01
+#define MAX_FW_UPDATE_BIOS_SELECTIONS  2
+
+//
+// Function implementations executed during policy initialization phase
+//
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   Initialization complete.
+  @retval 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
+UpdateDxeMePolicy (
+  IN OUT  ME_POLICY_PROTOCOL            *DxeMePolicy
+  )
+{
+  EFI_STATUS              Status;
+  EFI_EVENT               EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "UpdateDxeMePolicy\n"));
+  UpdateMePolicyFromSetup (DxeMePolicy);
+  UpdateMePolicyFromMeSetup (DxeMePolicy);
+
+  //
+  // Register End of DXE event
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UpdateMeSetupCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+/**
+  Update ME Policy while MePlatformProtocol is installed.
+
+  @param[in] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromMeSetup (
+  IN ME_POLICY_PROTOCOL           *MePolicyInstance
+  )
+{
+
+}
+
+/**
+  Update ME Policy if Setup variable exists.
+
+  @param[in, out] MePolicyInstance     Instance of ME Policy Protocol
+
+**/
+VOID
+UpdateMePolicyFromSetup (
+  IN OUT ME_POLICY_PROTOCOL     *MePolicyInstance
+  )
+{
+
+}
+
+/**
+  Functions performs HECI exchange with FW to update MePolicy settings.
+
+  @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
+UpdateMeSetupCallback (
+  IN  EFI_EVENT                   Event,
+  IN  VOID                        *Context
+  )
+{
+  gBS->CloseEvent (Event);
+
+  return;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c
new file mode 100644
index 0000000000..7945986aaa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c
@@ -0,0 +1,39 @@
+/** @file
+  This file is the library for PCH DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <PchAccess.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/HdAudioConfig.h>
+
+/**
+  Get data for PCH policy from setup options.
+
+  @param[in] PchPolicy                 The pointer to get PCH Policy protocol instance
+
+  @retval EFI_SUCCESS                  Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxePchPolicy (
+  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
+  )
+{
+  EFI_STATUS              Status;
+  PCH_HDAUDIO_DXE_CONFIG  *HdAudioDxeConfig;
+
+  Status = GetConfigBlock ((VOID *)PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdAudioDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
new file mode 100644
index 0000000000..af4c76bcd0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
@@ -0,0 +1,57 @@
+/** @file
+  This file is the library for SA DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <DxeSaPolicyUpdate.h>
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] SaPolicy                  The pointer to get SA Policy protocol instance
+
+  @retval EFI_SUCCESS                  Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicy (
+  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
+  )
+{
+  EFI_STATUS                Status;
+  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
+  PCIE_DXE_CONFIG           *PcieDxeConfig;
+  MISC_DXE_CONFIG           *MiscDxeConfig;
+  MEMORY_DXE_CONFIG         *MemoryDxeConfig;
+
+  GraphicsDxeConfig = NULL;
+  PcieDxeConfig = NULL;
+  MiscDxeConfig = NULL;
+  MemoryDxeConfig = NULL;
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gMiscDxeConfigGuid, (VOID *)&MiscDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  PcieDxeConfig->PegAspmL0s[0] = 3;
+  PcieDxeConfig->PegAspmL0s[1] = 3;
+  PcieDxeConfig->PegAspmL0s[2] = 3;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c
new file mode 100644
index 0000000000..93be38a832
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c
@@ -0,0 +1,65 @@
+/** @file
+  This file is SampleCode for Intel PEI Platform Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyInit.h"
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in] PeiServices            General purpose services available to every PEIM.
+  @param[in] FirmwareConfiguration  It uses to skip specific policy init that depends
+                                    on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInit (
+  IN UINT8                     FirmwareConfiguration
+  )
+{
+  EFI_STATUS                   Status;
+  SI_POLICY_PPI                *SiPolicyPpi;
+
+  //
+  // Call SiCreateConfigBlocks to initialize Silicon Policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = SiCreateConfigBlocks (&SiPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return;
+  }
+
+  if (PcdGetBool (PcdDumpDefaultSiliconPolicy)) {
+    DEBUG ((DEBUG_INFO, "Dump Default Silicon Policy...\n"));
+    DumpSiPolicy (SiPolicyPpi);
+  }
+
+  //
+  // Update policy by board configuration
+  //
+  UpdatePeiSiPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiPchPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiSaPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiCpuPolicyBoardConfig (SiPolicyPpi);
+  UpdatePeiMePolicyBoardConfig (SiPolicyPpi);
+
+  UpdatePeiSiPolicy(SiPolicyPpi);
+  UpdatePeiPchPolicy(SiPolicyPpi);
+  UpdatePeiSaPolicy(SiPolicyPpi);
+  UpdatePeiCpuPolicy(SiPolicyPpi);
+  UpdatePeiMePolicy(SiPolicyPpi);
+
+  //
+  // Install SiPolicyPpi.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SiInstallPolicyPpi (SiPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
new file mode 100644
index 0000000000..9f8014b72a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode for Intel PEI Platform Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyInit.h"
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that depends
+                                     on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInitPreMem (
+  IN UINT8                     FirmwareConfiguration
+  )
+{
+  EFI_STATUS                   Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in Pre-Memory...\n"));
+  //
+  // Call SiCreatePreMemConfigBlocks to initialize platform policy structure
+  // and get all intel default policy settings.
+  //
+  Status = SiCreatePreMemConfigBlocks (&SiPreMemPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update policy by board configuration
+  //
+  UpdatePeiPchPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+  UpdatePeiMePolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+  UpdatePeiSaPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+  UpdatePeiCpuPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
+
+  //
+  // Update and override all platform related and customized settings below.
+  //
+  UpdatePeiPchPolicyPreMem (SiPreMemPolicyPpi);
+  UpdatePeiMePolicyPreMem (SiPreMemPolicyPpi);
+  UpdatePeiSaPolicyPreMem (SiPreMemPolicyPpi);
+  UpdatePeiCpuPolicyPreMem (SiPreMemPolicyPpi);
+
+  //
+  // Install SiPreMemPolicyPpi.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SiPreMemInstallPolicyPpi (SiPreMemPolicyPpi);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in Pre-Memory\n"));
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
new file mode 100644
index 0000000000..922bcd135f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
@@ -0,0 +1,114 @@
+/** @file
+  This file is SampleCode for Intel SA PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyInit.h"
+
+
+/**
+  PcieCardResetWorkAround performs PCIe Card reset on root port
+
+  @param[in out] SiPreMemPolicyPpi SI_PREMEM_POLICY_PPI
+
+  @retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+  PcieCardResetWorkAround (
+  IN OUT   SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  SA_MISC_PEI_PREMEM_CONFIG       *MiscPeiPreMemConfig;
+  SWITCHABLE_GRAPHICS_CONFIG      *SgGpioData;
+
+  Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *)&MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *)&SgGpioData);
+  ASSERT_EFI_ERROR(Status);
+
+  if (SgGpioData->SaRtd3Pcie0Gpio.GpioSupport != NotSupported) {
+    ///
+    /// dGPU is present.
+    ///      If PCIe Mode or SG Muxless
+    ///              Power on MXM
+    ///              Configure GPIOs to drive MXM in PCIe mode or SG Muxless
+    ///      else
+    ///              Do Nothing
+    ///
+    if ((MiscPeiPreMemConfig->SgMode == SgModeMuxless) ||
+        (MiscPeiPreMemConfig->SgMode == SgModeDgpu)) {
+      DEBUG((DEBUG_INFO, "Configure GPIOs for driving the dGPU.\n"));
+      ///
+      ///  Drive DGPU HOLD RST Enable to make sure we hold reset
+      ///
+      PcieGpioWrite (
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo,
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active,
+        GP_ENABLE
+        );
+      ///
+      /// wait 100ms
+      ///
+      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) * STALL_ONE_MILLI_SECOND);
+
+      ///
+      /// Drive DGPU PWR EN to Power On MXM
+      ///
+      PcieGpioWrite (
+        SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.GpioNo,
+        SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.Active,
+        GP_ENABLE
+        );
+      ///
+      /// wait 300ms
+      ///
+      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterPwrEn) * STALL_ONE_MILLI_SECOND);
+
+      ///
+      /// Drive DGPU HOLD RST Disabled to remove reset
+      ///
+      PcieGpioWrite (
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo,
+        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active,
+        GP_DISABLE
+        );
+      ///
+      /// wait 100ms
+      ///
+      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) * STALL_ONE_MILLI_SECOND);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  PCIe GPIO Write
+
+  @param[in] Gpio        - GPIO Number
+  @param[in] Active      - GPIO Active Information; High/Low
+  @param[in] Level       - Write GPIO value (0/1)
+
+**/
+VOID
+PcieGpioWrite (
+  IN  UINT32                Gpio,
+  IN  BOOLEAN               Active,
+  IN  BOOLEAN               Level
+  )
+{
+  EFI_STATUS  Status;
+
+  if (Active == 0) {
+    Level = (~Level) & 0x1;
+  }
+  Status = GpioSetOutputValue(Gpio, (UINT32)Level);
+  if (Status != EFI_SUCCESS) {
+    return;
+  }
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
new file mode 100644
index 0000000000..144480a83d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
@@ -0,0 +1,80 @@
+/** @file
+  CPU PEI Policy Update & initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyUpdate.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CpuPlatformLib.h>
+
+/**
+  This function performs CPU PEI Policy initialization.
+
+  @param[in] SiPolicyPpi           The SI Policy PPI instance
+
+  @retval EFI_SUCCESS              The PPI is installed and initialized.
+  @retval EFI ERRORS               The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES     Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+  IN OUT  SI_POLICY_PPI   *SiPolicyPpi
+  )
+{
+  EFI_STATUS                       Status;
+  CPU_CONFIG                       *CpuConfig;
+  CPU_POWER_MGMT_BASIC_CONFIG      *CpuPowerMgmtBasicConfig;
+  SI_PREMEM_POLICY_PPI             *SiPreMemPolicyPpi;
+  CPU_POWER_MGMT_CUSTOM_CONFIG     *CpuPowerMgmtCustomConfig;
+  CPU_POWER_MGMT_TEST_CONFIG      *CpuPowerMgmtTestConfig;
+  CPU_TEST_CONFIG                 *CpuTestConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *)&CpuPowerMgmtCustomConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuTestConfigGuid, (VOID *)&CpuTestConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = PeiServicesLocatePpi (
+                &gSiPreMemPolicyPpiGuid,
+                0,
+                NULL,
+                (VOID **) &SiPreMemPolicyPpi
+                );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *)&CpuPowerMgmtTestConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Init Power Management Policy Variables
+  //
+  CpuPowerMgmtBasicConfig->HwpInterruptControl = 1;
+  CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio = 0x4;
+  CpuPowerMgmtBasicConfig->OneCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->TwoCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->FourCoreRatioLimit = 0x22;
+  CpuPowerMgmtBasicConfig->FiveCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->SixCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->SevenCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->EightCoreRatioLimit = 0;
+  CpuPowerMgmtBasicConfig->Hwp = 0x1;
+  CpuTestConfig->CpuWakeUpTimer = 1;
+  CpuPowerMgmtTestConfig->AutoThermalReporting = 0;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..bce02a9c5a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
@@ -0,0 +1,108 @@
+/** @file
+  This file is SampleCode of the library for Intel CPU PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyUpdate.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SpiLib.h>
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval True if SGX supported or FALSE if not
+**/
+BOOLEAN
+IsSgxCapSupported (
+  VOID
+  )
+{
+  EFI_CPUID_REGISTER CpuidRegs;
+
+  ///
+  /// Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
+  ///
+  AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.RegEdx);
+
+  ///
+  /// SGX feature is supported only on WHL and later,
+  /// with CPUID.(EAX=7,ECX=0):EBX[2]=1
+  /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
+  ///
+  if ((CpuidRegs.RegEbx & BIT2) && (AsmReadMsr64 (MSR_IA32_MTRRCAP) & BIT12)) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  This function performs CPU PEI Policy initialization in Pre-memory.
+
+  @param[in] SiPreMemPolicyPpi     The SI Pre-Mem Policy PPI instance
+
+  @retval EFI_SUCCESS              The PPI is installed and initialized.
+  @retval EFI ERRORS               The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES     Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_BOOT_MODE                   BootMode;
+  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
+  CPU_OVERCLOCKING_PREMEM_CONFIG  *CpuOverClockingPreMemConfig;
+  UINT32                          PchSpiBar0;
+  UINT32                          MaxLogicProcessors;
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverClockingPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiCpuPolicyPreMem Start\n"));
+
+  //
+  // Get current boot mode
+  //
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  SpiServiceInit ();
+
+  PchSpiBar0 = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
+                                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                                   DEFAULT_PCI_BUS_NUMBER_PCH,
+                                   PCI_DEVICE_NUMBER_PCH_SPI,
+                                   PCI_FUNCTION_NUMBER_PCH_SPI,
+                                   R_SPI_CFG_BAR0
+                                   ));
+  PchSpiBar0 &= ~(B_SPI_CFG_BAR0_MASK);
+
+  if (PchSpiBar0 == 0) {
+    DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
+    ASSERT (FALSE);
+  }
+
+  CpuConfigLibPreMemConfig->PeciC10Reset = 0;
+  CpuConfigLibPreMemConfig->CpuRatio = 0;
+  ///
+  /// Set PcdCpuMaxLogicalProcessorNumber to max number of logical processors enabled
+  /// Read MSR_CORE_THREAD_COUNT (0x35) to check the total active Threads
+  ///
+  MaxLogicProcessors = (UINT32) (AsmReadMsr64 (MSR_CORE_THREAD_COUNT) & B_THREAD_COUNT_MASK);
+  DEBUG ((DEBUG_INFO, "MaxLogicProcessors = %d\n", MaxLogicProcessors));
+  PcdSet32S (PcdCpuMaxLogicalProcessorNumber, MaxLogicProcessors);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c
new file mode 100644
index 0000000000..e557f04971
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c
@@ -0,0 +1,49 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiMePolicyUpdate.h"
+#include <ConfigBlock/MePeiConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PmcLib.h>
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPolicyPpi     The pointer to SiPolicyPpi
+
+  @retval EFI_SUCCESS             Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicy (
+  IN OUT SI_POLICY_PPI            *SiPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  ME_PEI_CONFIG                   *MePeiConfig;
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiMePolicy\n"));
+
+  Status = EFI_SUCCESS;
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (!PmcIsRtcBatteryGood ()) {
+    //
+    // For non coin battery design, this can be skipped.
+    //
+    MePeiConfig->MeUnconfigOnRtcClear   = 2;
+  }
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c
new file mode 100644
index 0000000000..de9849b807
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c
@@ -0,0 +1,32 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiMePolicyUpdate.h"
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  Update the ME Policy Library
+
+  @param[in] SiPreMemPolicyPpi  The pointer to SiPreMemPolicyPpi
+
+  @retval EFI_SUCCESS           Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicyPreMem (
+  IN OUT SI_PREMEM_POLICY_PPI     *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+
+  DEBUG ((DEBUG_INFO, "UpdatePeiMePolicyPreMem\n"));
+
+  Status = EFI_SUCCESS;
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c
new file mode 100644
index 0000000000..3e44c6cc29
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c
@@ -0,0 +1,523 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/PchGbeLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Ppi/Spi.h>
+#include <GpioConfig.h>
+#include <Library/DebugLib.h>
+#include <Library/PchGbeLib.h>
+#include <PlatformBoardConfig.h>
+#include <Library/CnviLib.h>
+#include <Register/PchRegsLpcCnl.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <PcieDeviceOverrideTable.h>
+
+VOID
+UpdatePcieClockInfo (
+  PCH_PCIE_CONFIG  *PcieRpConfig,
+  UINTN            Index,
+  UINT64           Data
+  )
+{
+  PCD64_BLOB Pcd64;
+
+  Pcd64.Blob = Data;
+  DEBUG ((DEBUG_INFO, "UpdatePcieClockInfo ClkIndex %x ClkUsage %x, Supported %x\n", Index, Pcd64.PcieClock.ClockUsage, Pcd64.PcieClock.ClkReqSupported));
+
+  PcieRpConfig->PcieClock[Index].Usage = (UINT8)Pcd64.PcieClock.ClockUsage;
+  if (Pcd64.PcieClock.ClkReqSupported) {
+    PcieRpConfig->PcieClock[Index].ClkReq = (UINT8)Index;
+  } else {
+    PcieRpConfig->PcieClock[Index].ClkReq = 0xFF;
+  }
+}
+
+/**
+  This is helper function for getting I2C Pads Internal Termination settings from Pcd
+
+  @param[in]  Index            I2C Controller Index
+**/
+UINT8
+GetSerialIoI2cPadsTerminationFromPcd (
+  IN UINT8 Index
+)
+{
+  switch (Index) {
+    case 0:
+      return PcdGet8 (PcdPchSerialIoI2c0PadInternalTerm);
+    case 1:
+      return PcdGet8 (PcdPchSerialIoI2c1PadInternalTerm);
+    case 2:
+      return PcdGet8 (PcdPchSerialIoI2c2PadInternalTerm);
+    case 3:
+      return PcdGet8 (PcdPchSerialIoI2c3PadInternalTerm);
+    case 4:
+      return PcdGet8 (PcdPchSerialIoI2c4PadInternalTerm);
+    case 5:
+      return PcdGet8 (PcdPchSerialIoI2c5PadInternalTerm);
+    default:
+      ASSERT (FALSE); // Invalid I2C Controller Index
+  }
+  return 0;
+}
+/**
+  This is a helper function for updating USB Policy according to Blob data
+
+  @param[in]  UsbConfig        Pointer to USB_CONFIG data buffer
+  @param[in]  PortIndex        USB Port index
+  @param[in]  Data32           Blob containing USB2 Afe (PCD32_BLOB) data
+**/
+VOID
+UpdateUsb20AfePolicy (
+  IN USB_CONFIG                 *UsbConfig,
+  IN UINT8                      PortIndex,
+  UINT32                        Data32
+)
+{
+  PCD32_BLOB Pcd32;
+  Pcd32.Blob = Data32;
+
+  if (PortIndex < MAX_USB2_PORTS && Pcd32.Info.Petxiset != 0) {
+    UsbConfig->PortUsb20[PortIndex].Afe.Petxiset     = Pcd32.Info.Petxiset;
+    UsbConfig->PortUsb20[PortIndex].Afe.Txiset       = Pcd32.Info.Txiset;
+    UsbConfig->PortUsb20[PortIndex].Afe.Predeemp     = Pcd32.Info.Predeemp;
+    UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit    = Pcd32.Info.Pehalfbit;
+  }
+}
+
+/**
+  This function updates USB Policy per port OC Pin number
+
+  @param[in]  PchUsbConfig     Pointer to USB_CONFIG data buffer
+  @param[in]  PortIndex        USB Port index
+  @param[in]  Pin              OverCurrent pin number
+**/
+VOID
+UpdateUsb20OverCurrentPolicy (
+  IN USB_CONFIG                 *UsbConfig,
+  IN UINT8                      PortIndex,
+  UINT8                         Pin
+)
+{
+  if (PortIndex < MAX_USB2_PORTS && ((Pin < UsbOverCurrentPinMax) || (Pin == UsbOverCurrentPinSkip))) {
+    UsbConfig->PortUsb20[PortIndex].OverCurrentPin = Pin;
+  } else {
+    if (PortIndex >= MAX_USB2_PORTS) {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb20OverCurrentPolicy: USB2 port number %d is not a valid USB2 port number\n", PortIndex));
+    } else {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb20OverCurrentPolicy: Invalid OverCurrent pin specified USB2 port %d\n", PortIndex));
+    }
+  }
+}
+
+/**
+  This function updates USB Policy per port OC Pin number
+
+  @param[in]  PchUsbConfig     Pointer to USB_CONFIG data buffer
+  @param[in]  PortIndex        USB Port index
+  @param[in]  Pin              OverCurrent pin number
+**/
+VOID
+UpdateUsb30OverCurrentPolicy (
+  IN USB_CONFIG                 *UsbConfig,
+  IN UINT8                      PortIndex,
+  UINT8                         Pin
+)
+{
+  if (PortIndex < MAX_USB3_PORTS && ((Pin < UsbOverCurrentPinMax) || (Pin == UsbOverCurrentPinSkip))) {
+    UsbConfig->PortUsb30[PortIndex].OverCurrentPin = Pin;
+  } else {
+    if (PortIndex >= MAX_USB2_PORTS) {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb30OverCurrentPolicy: USB3 port number %d is not a valid USB3 port number\n", PortIndex));
+    } else {
+      DEBUG ((DEBUG_ERROR, "UpdateUsb30OverCurrentPolicy: Invalid OverCurrent pin specified USB3 port %d\n", PortIndex));
+    }
+  }
+}
+
+/**
+  This function performs PCH USB Platform Policy initialization
+
+  @param[in] PchUsbConfig         Pointer to USB_CONFIG data buffer
+  @param[in] PchSetup             Pointer to PCH_SETUP data buffer
+**/
+VOID
+UpdatePchUsbConfig (
+  IN USB_CONFIG                *UsbConfig
+  )
+{
+  UINTN              PortIndex;
+
+  UsbConfig->OverCurrentEnable = TRUE;
+
+  for (PortIndex = 0; PortIndex < GetPchUsb2MaxPhysicalPortNum (); PortIndex++) {
+      UsbConfig->PortUsb20[PortIndex].Enable = TRUE;
+  }
+  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+      UsbConfig->PortUsb30[PortIndex].Enable = TRUE;
+  }
+
+  UsbConfig->XdciConfig.Enable = FALSE;
+
+
+  //
+  // USB2 AFE settings.
+  //
+  UpdateUsb20AfePolicy (UsbConfig, 0, PcdGet32 (PcdUsb20Port0Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 1, PcdGet32 (PcdUsb20Port1Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 2, PcdGet32 (PcdUsb20Port2Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 3, PcdGet32 (PcdUsb20Port3Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 4, PcdGet32 (PcdUsb20Port4Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 5, PcdGet32 (PcdUsb20Port5Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 6, PcdGet32 (PcdUsb20Port6Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 7, PcdGet32 (PcdUsb20Port7Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 8, PcdGet32 (PcdUsb20Port8Afe));
+  UpdateUsb20AfePolicy (UsbConfig, 9, PcdGet32 (PcdUsb20Port9Afe));
+  UpdateUsb20AfePolicy (UsbConfig,10, PcdGet32 (PcdUsb20Port10Afe));
+  UpdateUsb20AfePolicy (UsbConfig,11, PcdGet32 (PcdUsb20Port11Afe));
+  UpdateUsb20AfePolicy (UsbConfig,12, PcdGet32 (PcdUsb20Port12Afe));
+  UpdateUsb20AfePolicy (UsbConfig,13, PcdGet32 (PcdUsb20Port13Afe));
+  UpdateUsb20AfePolicy (UsbConfig,14, PcdGet32 (PcdUsb20Port14Afe));
+  UpdateUsb20AfePolicy (UsbConfig,15, PcdGet32 (PcdUsb20Port15Afe));
+
+  //
+  // Platform Board programming per the layout of each port.
+  //
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 0, PcdGet8 (PcdUsb20OverCurrentPinPort0));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 1, PcdGet8 (PcdUsb20OverCurrentPinPort1));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 2, PcdGet8 (PcdUsb20OverCurrentPinPort2));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 3, PcdGet8 (PcdUsb20OverCurrentPinPort3));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 4, PcdGet8 (PcdUsb20OverCurrentPinPort4));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 5, PcdGet8 (PcdUsb20OverCurrentPinPort5));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 6, PcdGet8 (PcdUsb20OverCurrentPinPort6));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 7, PcdGet8 (PcdUsb20OverCurrentPinPort7));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 8, PcdGet8 (PcdUsb20OverCurrentPinPort8));
+  UpdateUsb20OverCurrentPolicy (UsbConfig, 9, PcdGet8 (PcdUsb20OverCurrentPinPort9));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,10, PcdGet8 (PcdUsb20OverCurrentPinPort10));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,11, PcdGet8 (PcdUsb20OverCurrentPinPort11));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,12, PcdGet8 (PcdUsb20OverCurrentPinPort12));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,13, PcdGet8 (PcdUsb20OverCurrentPinPort13));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,14, PcdGet8 (PcdUsb20OverCurrentPinPort14));
+  UpdateUsb20OverCurrentPolicy (UsbConfig,15, PcdGet8 (PcdUsb20OverCurrentPinPort15));
+
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 0, PcdGet8 (PcdUsb30OverCurrentPinPort0));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 1, PcdGet8 (PcdUsb30OverCurrentPinPort1));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 2, PcdGet8 (PcdUsb30OverCurrentPinPort2));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 3, PcdGet8 (PcdUsb30OverCurrentPinPort3));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 4, PcdGet8 (PcdUsb30OverCurrentPinPort4));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 5, PcdGet8 (PcdUsb30OverCurrentPinPort5));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 6, PcdGet8 (PcdUsb30OverCurrentPinPort6));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 7, PcdGet8 (PcdUsb30OverCurrentPinPort7));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 8, PcdGet8 (PcdUsb30OverCurrentPinPort8));
+  UpdateUsb30OverCurrentPolicy (UsbConfig, 9, PcdGet8 (PcdUsb30OverCurrentPinPort9));
+
+}
+
+/**
+  Return if input ImageGuid belongs to system FMP GUID list.
+
+  @param[in] ImageGuid A pointer to GUID
+
+  @retval TRUE  ImageGuid is in the list of PcdSystemFmpCapsuleImageTypeIdGuid
+  @retval FALSE ImageGuid is not in the list of PcdSystemFmpCapsuleImageTypeIdGuid
+**/
+BOOLEAN
+IsSystemFmpGuid (
+  IN GUID   *ImageGuid
+  )
+{
+  GUID      *Guid;
+  UINTN     Count;
+  UINTN     Index;
+
+  Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
+  Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof (GUID);
+
+  for (Index = 0; Index < Count; Index++, Guid++) {
+    if (CompareGuid (ImageGuid, Guid)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicy (
+  IN OUT      SI_POLICY_PPI     *SiPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT8                           Index;
+  DMI_HW_WIDTH_CONTROL            *DmiHaAWC;
+  UINT16                          LpcDid;
+  PCH_GENERAL_CONFIG              *PchGeneralConfig;
+  PCH_PCIE_CONFIG                 *PcieRpConfig;
+  PCH_SATA_CONFIG                 *SataConfig;
+  PCH_IOAPIC_CONFIG               *IoApicConfig;
+  PCH_DMI_CONFIG                  *DmiConfig;
+  PCH_FLASH_PROTECTION_CONFIG     *FlashProtectionConfig;
+  PCH_HDAUDIO_CONFIG              *HdAudioConfig;
+  PCH_INTERRUPT_CONFIG            *InterruptConfig;
+  PCH_ISH_CONFIG                  *IshConfig;
+  PCH_LAN_CONFIG                  *LanConfig;
+  PCH_LOCK_DOWN_CONFIG            *LockDownConfig;
+  PCH_PM_CONFIG                   *PmConfig;
+  PCH_SCS_CONFIG                  *ScsConfig;
+  PCH_SERIAL_IO_CONFIG            *SerialIoConfig;
+  PCH_LPC_SIRQ_CONFIG             *SerialIrqConfig;
+  PCH_THERMAL_CONFIG              *ThermalConfig;
+  USB_CONFIG                      *UsbConfig;
+  PCH_ESPI_CONFIG                 *EspiConfig;
+  PCH_CNVI_CONFIG                 *CnviConfig;
+  PEI_TBT_POLICY                  *PeiTbtPolicy;
+  SI_PREMEM_POLICY_PPI            *SiPreMemPolicyPpi;
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *) &SataConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIoApicConfigGuid, (VOID *) &IoApicConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gDmiConfigGuid, (VOID *) &DmiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gHdAudioConfigGuid, (VOID *) &HdAudioConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gInterruptConfigGuid, (VOID *) &InterruptConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gIshConfigGuid, (VOID *) &IshConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLanConfigGuid, (VOID *) &LanConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gLockDownConfigGuid, (VOID *) &LockDownConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *) &PmConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gScsConfigGuid, (VOID *) &ScsConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIoConfigGuid, (VOID *) &SerialIoConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIrqConfigGuid, (VOID *) &SerialIrqConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gThermalConfigGuid, (VOID *) &ThermalConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gUsbConfigGuid, (VOID *) &UsbConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gEspiConfigGuid, (VOID *) &EspiConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gCnviConfigGuid, (VOID *) &CnviConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesLocatePpi (
+                &gSiPreMemPolicyPpiGuid,
+                0,
+                NULL,
+                (VOID **) &SiPreMemPolicyPpi
+                );
+  ASSERT_EFI_ERROR (Status);
+
+  PeiTbtPolicy = NULL;
+  LpcDid = PchGetLpcDid ();
+
+  DmiConfig->PwrOptEnable = TRUE;
+  PmConfig->PchSlpS3MinAssert = 0;
+  PmConfig->PchSlpS4MinAssert = 0;
+  PmConfig->PchSlpSusMinAssert = 0;
+  PmConfig->PchSlpAMinAssert = 0;
+
+  SataConfig->ThermalThrottling.P1T3M = 3;
+  SataConfig->ThermalThrottling.P1T2M = 2;
+  SataConfig->ThermalThrottling.P1T1M = 1;
+  SataConfig->ThermalThrottling.P0T3M = 3;
+  SataConfig->ThermalThrottling.P0T2M = 2;
+  SataConfig->ThermalThrottling.P0T1M = 1;
+
+  UpdatePcieClockInfo (PcieRpConfig, 0, PcdGet64  (PcdPcieClock0));
+  UpdatePcieClockInfo (PcieRpConfig, 1, PcdGet64  (PcdPcieClock1));
+  UpdatePcieClockInfo (PcieRpConfig, 2, PcdGet64  (PcdPcieClock2));
+  UpdatePcieClockInfo (PcieRpConfig, 3, PcdGet64  (PcdPcieClock3));
+  UpdatePcieClockInfo (PcieRpConfig, 4, PcdGet64  (PcdPcieClock4));
+  UpdatePcieClockInfo (PcieRpConfig, 5, PcdGet64  (PcdPcieClock5));
+  UpdatePcieClockInfo (PcieRpConfig, 6, PcdGet64  (PcdPcieClock6));
+  UpdatePcieClockInfo (PcieRpConfig, 7, PcdGet64  (PcdPcieClock7));
+  UpdatePcieClockInfo (PcieRpConfig, 8, PcdGet64  (PcdPcieClock8));
+  UpdatePcieClockInfo (PcieRpConfig, 9, PcdGet64  (PcdPcieClock9));
+  UpdatePcieClockInfo (PcieRpConfig, 10, PcdGet64 (PcdPcieClock10));
+  UpdatePcieClockInfo (PcieRpConfig, 11, PcdGet64 (PcdPcieClock11));
+  UpdatePcieClockInfo (PcieRpConfig, 12, PcdGet64 (PcdPcieClock12));
+  UpdatePcieClockInfo (PcieRpConfig, 13, PcdGet64 (PcdPcieClock13));
+  UpdatePcieClockInfo (PcieRpConfig, 14, PcdGet64 (PcdPcieClock14));
+  UpdatePcieClockInfo (PcieRpConfig, 15, PcdGet64 (PcdPcieClock15));
+
+  PcieRpConfig->PcieDeviceOverrideTablePtr = (UINT32) mPcieDeviceTable;
+  PcieRpConfig->RootPort[0].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[1].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[2].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[3].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[4].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[5].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[6].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[7].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[8].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[9].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[10].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[11].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[12].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[13].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[14].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[15].ClkReqDetect = TRUE;
+  PcieRpConfig->RootPort[0].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[1].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[2].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[3].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[4].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[5].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[6].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[7].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[8].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[9].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[10].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[11].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[12].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[13].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[14].AdvancedErrorReporting = TRUE;
+  PcieRpConfig->RootPort[15].AdvancedErrorReporting = TRUE;
+
+  //
+  // Install HDA Link/iDisplay Codec Verb Table
+  //
+  AddPlatformVerbTables (
+    PchHdaCodecPlatformOnboard,
+    &(HdAudioConfig->VerbTableEntryNum),
+    &(HdAudioConfig->VerbTablePtr)
+    );
+
+  LockDownConfig->BiosLock = FALSE;
+  LockDownConfig->BiosInterface = FALSE;
+
+  //
+  // IOAPIC Config
+  //
+//  IoApicConfig->IoApicEntry24_119     = PchSetup.PchIoApic24119Entries;
+  //
+  // To support SLP_S0, it's required to disable 8254 timer.
+  // Note that CSM may require this option to be disabled for correct operation.
+  // Once 8254 timer disabled, some legacy OPROM and legacy OS will fail while using 8254 timer.
+  // For some OS environment that it needs to set 8254CGE in late state it should
+  // set this policy to FALSE and use PmcSet8254ClockGateState (TRUE) in SMM later.
+  // This is also required during S3 resume.
+  //
+  // The Enable8254ClockGatingOnS3 is only applicable when Enable8254ClockGating is disabled.
+  // If Enable8254ClockGating is enabled, RC will do 8254 CGE programming on S3 as well.
+  // else, RC will do the programming on S3 when Enable8254ClockGatingOnS3 is enabled.
+  // This avoids the SMI requirement for the programming.
+  //
+  // If S0ix is not enabled, then disable 8254CGE for leagcy boot case.
+  //
+  IoApicConfig->Enable8254ClockGating     = FALSE;
+  IoApicConfig->Enable8254ClockGatingOnS3 = FALSE;
+
+  //
+  // SerialIo Config
+  //
+  SerialIoConfig->DevMode[0] = 1;
+  SerialIoConfig->DevMode[1] = 1;
+  SerialIoConfig->DevMode[2] = 0;
+  SerialIoConfig->DevMode[3] = 0;
+  SerialIoConfig->DevMode[4] = 1;
+  SerialIoConfig->DevMode[5] = 0;
+  SerialIoConfig->DevMode[6] = 0;
+  SerialIoConfig->DevMode[7] = 0;
+  SerialIoConfig->DevMode[8] = 0;
+  SerialIoConfig->DevMode[9] = 0;
+  SerialIoConfig->DevMode[10] = 0;
+  SerialIoConfig->DevMode[11] = 3;
+
+  SerialIoConfig->Uart0PinMuxing = 1;
+  SerialIoConfig->SpiCsPolarity[0] = 1;
+  SerialIoConfig->SpiCsPolarity[1] = 0;
+  SerialIoConfig->SpiCsPolarity[2] = 0;
+
+  SerialIoConfig->UartHwFlowCtrl[0] = 1;
+  SerialIoConfig->UartHwFlowCtrl[1] = 1;
+  SerialIoConfig->UartHwFlowCtrl[2] = 1;
+  //
+  // I2C4 and I2C5 don't exist in SPT-H chipset
+  //
+  if (IsPchH ()) {
+    SerialIoConfig->DevMode[PchSerialIoIndexI2C4] = PchSerialIoDisabled;
+    SerialIoConfig->DevMode[PchSerialIoIndexI2C5] = PchSerialIoDisabled;
+  }
+
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    SerialIoConfig->I2cPadsTermination[Index] = GetSerialIoI2cPadsTerminationFromPcd (Index);
+  }
+
+  PmConfig->SlpS0Override                         = 2; //PchSetup.SlpS0Override;
+  PmConfig->SlpS0DisQForDebug                     = 3;  //PchSetup.SlpS0DisQForDebug;
+  PmConfig->SlpS0Vm075VSupport                    = 1; // PcdGetBool(PcdSlpS0Vm075VSupport);
+  PmConfig->CpuC10GatePinEnable                   = 1;
+
+  //
+  // Thermal Config
+  //
+  ThermalConfig->TsmicLock           = TRUE;
+  ThermalConfig->PchHotEnable        = PcdGetBool (PcdPchThermalHotEnable);
+
+  DmiHaAWC = &ThermalConfig->DmiHaAWC;
+  DmiHaAWC->TS3TW = 0;
+  DmiHaAWC->TS2TW = 1;
+  DmiHaAWC->TS1TW = 2;
+  DmiHaAWC->TS0TW = 3;
+  //
+  // Update Pch Usb Config
+  //
+  UpdatePchUsbConfig (
+    UsbConfig
+    );
+
+  ScsConfig->ScsUfsEnabled = 0;
+  ScsConfig->ScsEmmcHs400Enabled = 1;
+  ScsConfig->ScsEmmcHs400TuningRequired = TRUE;
+
+  IshConfig->I2c0GpioAssign = 1;
+  IshConfig->I2c1GpioAssign = 1;
+  IshConfig->Gp0GpioAssign = 1;
+  IshConfig->Gp1GpioAssign = 1;
+  IshConfig->Gp2GpioAssign = 1;
+  IshConfig->Gp3GpioAssign = 1;
+  IshConfig->Gp4GpioAssign = 1;
+  IshConfig->Gp5GpioAssign = 1;
+  IshConfig->Gp6GpioAssign = 1;
+
+  return Status;
+}
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..968df0f55c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c
@@ -0,0 +1,113 @@
+/** @file
+  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPchPolicyUpdate.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HobLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PchPolicyLib.h>
+
+//
+// Sawtooth Peak
+// Single SPD EEPROM at 0xA2 serves both C0D0 and C1D0 (LPDDR is 1DPC only)
+//
+#define DIMM_SMB_SPD_P0C0D0_STP 0xA2
+#define DIMM_SMB_SPD_P0C0D1_STP 0xA0
+#define DIMM_SMB_SPD_P0C1D0_STP 0xA2
+#define DIMM_SMB_SPD_P0C1D1_STP 0xA0
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusSTPRsvdAddresses[] = {
+  DIMM_SMB_SPD_P0C0D0_STP,
+  DIMM_SMB_SPD_P0C0D1_STP,
+  DIMM_SMB_SPD_P0C1D0_STP,
+  DIMM_SMB_SPD_P0C1D1_STP
+};
+
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPreMemPolicy  The SI PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT8                           *SmBusReservedTable;
+  UINT8                           SmBusReservedNum;
+
+  PCH_GENERAL_PREMEM_CONFIG       *PchGeneralPreMemConfig;
+  PCH_TRACE_HUB_PREMEM_CONFIG     *PchTraceHubPreMemConfig;
+  PCH_SMBUS_PREMEM_CONFIG         *SmbusPreMemConfig;
+  PCH_LPC_PREMEM_CONFIG           *LpcPreMemConfig;
+  PCH_WDT_PREMEM_CONFIG           *WatchDogPreMemConfig;
+  PCH_DCI_PREMEM_CONFIG           *DciPreMemConfig;
+  PCH_PCIE_RP_PREMEM_CONFIG       *PcieRpPreMemConfig;
+  PCH_HDAUDIO_PREMEM_CONFIG       *HdaPreMemConfig;
+  PCH_ISH_PREMEM_CONFIG           *IshPreMemConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gWatchDogPreMemConfigGuid, (VOID *) &WatchDogPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicy, &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DciPreMemConfig->DciUsb3TypecUfpDbg = 2;
+  PchTraceHubPreMemConfig->MemReg0Size = 3;
+  PchTraceHubPreMemConfig->MemReg1Size = 3;
+  //
+  // SMBUS
+  //
+  SmbusPreMemConfig->Enable = TRUE;
+  SmbusPreMemConfig->SmbAlertEnable = PcdGetBool (PcdSmbusAlertEnable);
+  //
+  // SMBUS reserved addresses
+  //
+  SmBusReservedTable = NULL;
+  SmBusReservedNum   = 0;
+  SmbusPreMemConfig->SmbusIoBase = PcdGet16 (PcdSmbusBaseAddress);
+  SmBusReservedTable = mSmbusSTPRsvdAddresses;
+  SmBusReservedNum   = sizeof (mSmbusSTPRsvdAddresses);
+
+  if (SmBusReservedTable != NULL) {
+    SmbusPreMemConfig->NumRsvdSmbusAddresses = SmBusReservedNum;
+    CopyMem (
+      SmbusPreMemConfig->RsvdSmbusAddressTable,
+      SmBusReservedTable,
+      SmBusReservedNum
+      );
+  }
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
new file mode 100644
index 0000000000..c1ac7d890f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
@@ -0,0 +1,242 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <Protocol/GraphicsOutput.h>
+#include <IndustryStandard/Bmp.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Library/HobLib.h>
+#include <Platform.h>
+#include <Ppi/FirmwareVolume.h>
+#include <Pi/PiFirmwareFile.h>
+#include <Pi/PiPeiCis.h>
+#include <Core/Pei/PeiMain.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+
+/**
+  UpdatePeiSaPolicy performs SA PEI Policy initialization
+
+  @param[in out] SiPolicyPpi     - SI_POLICY PPI
+
+  @retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+UpdatePeiSaPolicy (
+  IN OUT   SI_POLICY_PPI      *SiPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_GUID                        FileGuid;
+  VOID                            *Buffer;
+  UINT8                           SaDisplayConfigTable[9] = {0};
+  VOID                            *MemBuffer;
+  BMP_IMAGE_HEADER                *BmpHeader;
+  UINT64                          BltBufferSize;
+  UINT32                          Size;
+  GRAPHICS_PEI_CONFIG             *GtConfig;
+  GNA_CONFIG                      *GnaConfig;
+  WDT_PPI                         *gWdtPei;
+  PCIE_PEI_CONFIG                 *PciePeiConfig;
+  SA_MISC_PEI_CONFIG              *MiscPeiConfig;
+  EFI_BOOT_MODE                   BootMode;
+
+  DEBUG((DEBUG_INFO, "\nUpdating SA Policy in Post Mem\n"));
+
+  Size = 0;
+  MemBuffer = NULL;
+  BmpHeader = NULL;
+  BltBufferSize = 0;
+  GtConfig = NULL;
+  GnaConfig = NULL;
+
+  Status = GetConfigBlock((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *)&GtConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPolicyPpi, &gGnaConfigGuid, (VOID *)&GnaConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID *)&PciePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid, (VOID *)&MiscPeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Locate WDT_PPI (ICC WDT PPI)
+  //
+  gWdtPei = NULL;
+  Status = PeiServicesLocatePpi(
+             &gWdtPpiGuid,
+             0,
+             NULL,
+             (VOID **) &gWdtPei
+             );
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  if (!EFI_ERROR (Status)) {
+    Buffer = NULL;
+
+    CopyMem(&FileGuid, PcdGetPtr(PcdIntelGraphicsVbtFileGuid), sizeof(FileGuid));
+    PeiGetSectionFromFv(FileGuid, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_ERROR, "Could not locate VBT\n"));
+    }
+
+    MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+    if ((MemBuffer != NULL) && (Buffer != NULL)) {
+      CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+      GtConfig->GraphicsConfigPtr = MemBuffer;
+    } else {
+      DEBUG((DEBUG_WARN, "Error in locating / copying VBT.\n"));
+      GtConfig->GraphicsConfigPtr = NULL;
+    }
+
+    GtConfig->PeiGraphicsPeimInit = 1;
+
+    DEBUG((DEBUG_INFO, "Vbt Pointer from PeiGetSectionFromFv is 0x%x\n", GtConfig->GraphicsConfigPtr));
+    DEBUG((DEBUG_INFO, "Vbt Size from PeiGetSectionFromFv is 0x%x\n", Size));
+
+    PeiGetSectionFromFv (gTianoLogoGuid, &Buffer, &Size);
+    if (Buffer == NULL) {
+      DEBUG((DEBUG_WARN, "Could not locate Logo\n"));
+    }
+
+    MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
+    if ((MemBuffer != NULL) && (Buffer != NULL)) {
+      CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
+      GtConfig->LogoPtr = MemBuffer;
+      GtConfig->LogoSize = Size;
+
+      //
+      // Calculate the BltBuffer needed size.
+      //
+      BmpHeader = (BMP_IMAGE_HEADER *) GtConfig->LogoPtr;
+
+      if (BmpHeader->CharB == 'B' && BmpHeader->CharM == 'M') {
+        BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+        if (BltBufferSize < DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+          BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+          GtConfig->BltBufferSize    = (UINT32) BltBufferSize;
+          GtConfig->BltBufferAddress = (VOID *) AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)GtConfig->BltBufferSize));
+        } else {
+          DEBUG ((DEBUG_ERROR, "Blt Buffer Size overflow.\n"));
+          ASSERT (FALSE);
+        }
+      } else {
+        DEBUG ((DEBUG_ERROR, "Wrong Bmp Image Header.\n"));
+        ASSERT (FALSE);
+      }
+
+    } else {
+      DEBUG((DEBUG_WARN, "Error in locating / copying LogoPtr.\n"));
+      GtConfig->LogoPtr = NULL;
+      GtConfig->LogoSize = 0;
+    }
+
+    DEBUG((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n", GtConfig->LogoPtr));
+    DEBUG((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n", GtConfig->LogoSize));
+
+    //
+    // Display DDI Initialization ( default Native GPIO as per board during AUTO case)
+    //
+    if (PcdGet32 (PcdSaDisplayConfigTable) != 0) {
+      CopyMem (SaDisplayConfigTable, (VOID *) (UINTN) PcdGet32 (PcdSaDisplayConfigTable), (UINTN)PcdGet16 (PcdSaDisplayConfigTableSize));
+      GtConfig->DdiConfiguration.DdiPortEdp     = SaDisplayConfigTable[0];
+      GtConfig->DdiConfiguration.DdiPortBHpd    = SaDisplayConfigTable[1];
+      GtConfig->DdiConfiguration.DdiPortCHpd    = SaDisplayConfigTable[2];
+      GtConfig->DdiConfiguration.DdiPortDHpd    = SaDisplayConfigTable[3];
+      GtConfig->DdiConfiguration.DdiPortFHpd    = SaDisplayConfigTable[4];
+      GtConfig->DdiConfiguration.DdiPortBDdc    = SaDisplayConfigTable[5];
+      GtConfig->DdiConfiguration.DdiPortCDdc    = SaDisplayConfigTable[6];
+      GtConfig->DdiConfiguration.DdiPortDDdc    = SaDisplayConfigTable[7];
+      GtConfig->DdiConfiguration.DdiPortFDdc    = SaDisplayConfigTable[8];
+    }
+  }
+
+  PciePeiConfig->DmiAspm = 0x3;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
+
+  @param[in] NameGuid              - File GUID
+  @param[out] Address              - Pointer to the File Address
+  @param[out] Size                 - Pointer to File Size
+
+  @retval EFI_SUCCESS                Successfull in reading the section from FV
+**/
+EFI_STATUS
+EFIAPI
+PeiGetSectionFromFv (
+  IN CONST  EFI_GUID        NameGuid,
+  OUT VOID                  **Address,
+  OUT UINT32                *Size
+  )
+{
+  EFI_STATUS                           Status;
+  EFI_PEI_FIRMWARE_VOLUME_PPI          *FvPpi;
+  EFI_FV_FILE_INFO                     FvFileInfo;
+  PEI_CORE_INSTANCE                    *PrivateData;
+  UINTN                                CurrentFv;
+  PEI_CORE_FV_HANDLE                   *CoreFvHandle;
+  EFI_PEI_FILE_HANDLE                  VbtFileHandle;
+  EFI_GUID                             *VbtGuid;
+  EFI_COMMON_SECTION_HEADER            *Section;
+  CONST EFI_PEI_SERVICES               **PeiServices;
+
+  PeiServices = GetPeiServicesTablePointer();
+
+  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+  Status = PeiServicesLocatePpi(
+             &gEfiFirmwareFileSystem2Guid,
+             0,
+             NULL,
+             (VOID **)&FvPpi
+             );
+  ASSERT_EFI_ERROR(Status);
+
+  CurrentFv = PrivateData->CurrentPeimFvCount;
+  CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
+
+  Status = FvPpi->FindFileByName(FvPpi, &NameGuid, &CoreFvHandle->FvHandle, &VbtFileHandle);
+  if (!EFI_ERROR(Status) && VbtFileHandle != NULL) {
+
+    DEBUG((DEBUG_INFO, "Find SectionByType \n"));
+
+    Status = FvPpi->FindSectionByType(FvPpi, EFI_SECTION_RAW, VbtFileHandle, (VOID **)&VbtGuid);
+    if (!EFI_ERROR(Status)) {
+
+      DEBUG((DEBUG_INFO, "GetFileInfo \n"));
+
+      Status = FvPpi->GetFileInfo(FvPpi, VbtFileHandle, &FvFileInfo);
+      Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
+
+      if (IS_SECTION2(Section)) {
+        ASSERT(SECTION2_SIZE(Section) > 0x00FFFFFF);
+        *Size = SECTION2_SIZE(Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+      } else {
+        *Size = SECTION_SIZE(Section) - sizeof (EFI_COMMON_SECTION_HEADER);
+        *Address = ((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c
new file mode 100644
index 0000000000..3dc455ab29
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c
@@ -0,0 +1,221 @@
+/** @file
+Do Platform Stage System Agent initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSaPolicyUpdate.h"
+#include <CpuRegs.h>
+#include <Register/Cpuid.h>
+#include <Library/CpuPlatformLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Library/HobLib.h>
+#include <Platform.h>
+#include <PlatformBoardConfig.h>
+#include <Library/SiPolicyLib.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/GpioLib.h>
+
+///
+/// Memory Reserved should be between 125% to 150% of the Current required memory
+/// otherwise BdsMisc.c would do a reset to make it 125% to avoid s4 resume issues.
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+  { EfiACPIReclaimMemory,   FixedPcdGet32 (PcdPlatformEfiAcpiReclaimMemorySize) },  // ASL
+  { EfiACPIMemoryNVS,       FixedPcdGet32 (PcdPlatformEfiAcpiNvsMemorySize) },      // ACPI NVS (including S3 related)
+  { EfiReservedMemoryType,  FixedPcdGet32 (PcdPlatformEfiReservedMemorySize) },     // BIOS Reserved (including S3 related)
+  { EfiRuntimeServicesData, FixedPcdGet32 (PcdPlatformEfiRtDataMemorySize) },       // Runtime Service Data
+  { EfiRuntimeServicesCode, FixedPcdGet32 (PcdPlatformEfiRtCodeMemorySize) },       // Runtime Service Code
+  { EfiMaxMemoryType, 0 }
+};
+
+
+/**
+  UpdatePeiSaPolicyPreMem performs SA PEI Policy initialization
+
+  @param[in out] SiPreMemPolicyPpi - SI_PREMEM_POLICY PPI
+
+  @retval EFI_SUCCESS              The policy is installed and initialized.
+**/
+EFI_STATUS
+UpdatePeiSaPolicyPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                      Status;
+  SA_MISC_PEI_PREMEM_CONFIG       *MiscPeiPreMemConfig = NULL;
+  MEMORY_CONFIG_NO_CRC            *MemConfigNoCrc = NULL;
+  SA_MEMORY_RCOMP                 *RcompData;
+  WDT_PPI                         *gWdtPei;
+  UINT8                           Index;
+  UINTN                           DataSize;
+  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType + 1];
+  EFI_BOOT_MODE                   BootMode;
+  UINT8                           MorControl;
+  UINT32                          TraceHubTotalMemSize;
+  GRAPHICS_PEI_PREMEM_CONFIG      *GtPreMemConfig = NULL;
+  MEMORY_CONFIGURATION            *MemConfig = NULL;
+  PCIE_PEI_PREMEM_CONFIG          *PciePeiPreMemConfig = NULL;
+  SWITCHABLE_GRAPHICS_CONFIG      *SgGpioData = NULL;
+  IPU_PREMEM_CONFIG               *IpuPreMemPolicy = NULL;
+  OVERCLOCKING_PREMEM_CONFIG      *OcPreMemConfig = NULL;
+  VTD_CONFIG                      *Vtd = NULL;
+  UINT32                          ProcessorTraceTotalMemSize;
+  UINT16                          AdjustedMmioSize;
+  CPU_FAMILY                      CpuFamilyId;
+  CPU_STEPPING                    CpuStepping;
+
+  TraceHubTotalMemSize = 0;
+  ProcessorTraceTotalMemSize = 0;
+  AdjustedMmioSize = PcdGet16 (PcdSaMiscMmioSizeAdjustment);
+  CpuFamilyId = GetCpuFamily();
+  CpuStepping = GetCpuStepping();
+
+  DEBUG((DEBUG_INFO, "Entering Get Config Block function call from UpdatePeiSaPolicyPreMem\n"));
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *) &SgGpioData);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gVtdConfigGuid, (VOID *)&Vtd);
+  ASSERT_EFI_ERROR(Status);
+
+
+  RcompData = MemConfigNoCrc->RcompData;
+
+  //
+  // Locate WDT_PPI (ICC WDT PPI)
+  //
+  gWdtPei = NULL;
+  Status = PeiServicesLocatePpi(
+             &gWdtPpiGuid,
+             0,
+             NULL,
+             (VOID **) &gWdtPei
+             );
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  MiscPeiPreMemConfig->S3DataPtr = NULL;
+  MorControl = 0;
+  MiscPeiPreMemConfig->UserBd = 0; // It's a CRB mobile board by default (btCRBMB)
+
+  PcdSetBoolS (PcdMobileDramPresent, (BOOLEAN) (MemConfig->MobilePlatform));
+  MiscPeiPreMemConfig->SpdAddressTable[0] = PcdGet8 (PcdMrcSpdAddressTable0);
+  MiscPeiPreMemConfig->SpdAddressTable[1] = PcdGet8 (PcdMrcSpdAddressTable1);
+  MiscPeiPreMemConfig->SpdAddressTable[2] = PcdGet8 (PcdMrcSpdAddressTable2);
+  MiscPeiPreMemConfig->SpdAddressTable[3] = PcdGet8 (PcdMrcSpdAddressTable3);
+  MemConfig->CaVrefConfig                 = PcdGet8 (PcdMrcCaVrefConfig);
+  MemConfig->DualDimmPerChannelBoardType  = PcdGetBool (PcdDualDimmPerChannelBoardType);
+  if (PcdGet32 (PcdMrcRcompResistor)) {
+    CopyMem((VOID *)RcompData->RcompResistor, (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor), sizeof (RcompData->RcompResistor));
+  }
+  if (PcdGet32 (PcdMrcRcompTarget)) {
+    CopyMem((VOID *)RcompData->RcompTarget, (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget), sizeof (RcompData->RcompTarget));
+  }
+  if (PcdGet32 (PcdMrcDqByteMap)) {
+    CopyMem((VOID *)MemConfigNoCrc->DqByteMap, (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap), sizeof (UINT8)* SA_MC_MAX_CHANNELS * SA_MRC_ITERATION_MAX * 2);
+  }
+  if (PcdGet32 (PcdMrcDqsMapCpu2Dram)) {
+    CopyMem((VOID *)MemConfigNoCrc->DqsMap, (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram), sizeof (UINT8)* SA_MC_MAX_CHANNELS * SA_MC_MAX_BYTES_NO_ECC);
+  }
+  if (PcdGetBool (PcdMrcDqPinsInterleavedControl)) {
+    MemConfig->DqPinsInterleaved = PcdGetBool (PcdMrcDqPinsInterleaved);
+  }
+  if (PcdGet32 (PcdMrcSpdData)) {
+    CopyMem((VOID *)MemConfigNoCrc->SpdData->SpdData[0][0], (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData), SPD_DATA_SIZE);
+    CopyMem((VOID *)MemConfigNoCrc->SpdData->SpdData[1][0], (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData), SPD_DATA_SIZE);
+  }
+
+  MiscPeiPreMemConfig->MchBar   = (UINTN) PcdGet64 (PcdMchBaseAddress);
+  MiscPeiPreMemConfig->DmiBar   = (UINTN) PcdGet64 (PcdDmiBaseAddress);
+  MiscPeiPreMemConfig->EpBar    = (UINTN) PcdGet64 (PcdEpBaseAddress);
+  MiscPeiPreMemConfig->EdramBar = (UINTN) PcdGet64 (PcdEdramBaseAddress);
+  MiscPeiPreMemConfig->SmbusBar = PcdGet16(PcdSmbusBaseAddress);
+  MiscPeiPreMemConfig->TsegSize = PcdGet32(PcdTsegSize);
+  MiscPeiPreMemConfig->UserBd   = PcdGet8 (PcdSaMiscUserBd);
+  MiscPeiPreMemConfig->MmioSizeAdjustment = PcdGet16 (PcdSaMiscMmioSizeAdjustment);
+  if (PcdGetBool (PcdPegGpioResetControl)) {
+    PciePeiPreMemConfig->PegGpioData.GpioSupport = PcdGetBool (PcdPegGpioResetSupoort);
+  } else {
+
+  }
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad = PcdGet32 (PcdPeg0ResetGpioPad);
+  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active  = PcdGetBool (PcdPeg0ResetGpioActive);
+
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad = PcdGet32 (PcdPeg3ResetGpioPad);
+  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active  = PcdGetBool (PcdPeg3ResetGpioActive);
+
+  MemConfig->CkeRankMapping = 0xAA;
+  ///
+  /// Initialize the VTD Configuration
+  ///
+  Vtd->VtdDisable = 0;
+
+  MemConfig->RMT = 1;
+  MemConfig->UserPowerWeightsEn = 0;
+  MemConfig->RaplLim2WindY = 0x0A;
+  MemConfig->ExitOnFailure = 1;
+
+  MemConfigNoCrc->PlatformMemorySize = PEI_MIN_MEMORY_SIZE + TraceHubTotalMemSize + ProcessorTraceTotalMemSize;
+  DataSize = sizeof (mDefaultMemoryTypeInformation);
+  CopyMem(MemoryData, mDefaultMemoryTypeInformation, DataSize);
+
+  if (BootMode != BOOT_IN_RECOVERY_MODE) {
+    for (Index = 0; Index < DataSize / sizeof (EFI_MEMORY_TYPE_INFORMATION); Index++) {
+      MemConfigNoCrc->PlatformMemorySize += MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE;
+    }
+
+    OcPreMemConfig->GtMaxOcRatio = 0;
+    OcPreMemConfig->GtVoltageMode = 0;
+    OcPreMemConfig->GtVoltageOverride = 0;
+    OcPreMemConfig->GtExtraTurboVoltage = 0;
+    OcPreMemConfig->GtVoltageOffset = 0;
+    OcPreMemConfig->SaVoltageOffset = 0;
+    OcPreMemConfig->GtusMaxOcRatio = 0;
+    OcPreMemConfig->GtusVoltageMode = 0;
+    OcPreMemConfig->GtusVoltageOverride = 0;
+    OcPreMemConfig->GtusExtraTurboVoltage = 0;
+    OcPreMemConfig->GtusVoltageOffset = 0;
+
+    ///
+    /// Build the GUID'd HOB for DXE
+    ///
+    BuildGuidDataHob (
+      &gEfiMemoryTypeInformationGuid,
+      MemoryData,
+      DataSize
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
new file mode 100644
index 0000000000..3efbe2ccbd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
@@ -0,0 +1,168 @@
+/** @file
+  This file is SampleCode of the library for Intel Silicon PEI
+  Platform Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiSiPolicyUpdate.h"
+#include <MeChipset.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/SiPolicyLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+STATIC SVID_SID_INIT_ENTRY mCdfSsidTablePtr[] = {
+  //
+  // SA Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    SA_MC_FUN,        SA_MC_DEV,        SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG0_FUN_NUM,  SA_PEG0_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG1_FUN_NUM,  SA_PEG1_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG2_FUN_NUM,  SA_PEG2_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IGD_FUN_0,     SA_IGD_DEV,       SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IPU_FUN_NUM,   SA_IPU_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_GNA_FUN_NUM,   SA_GNA_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  //
+  // PCH Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LPC,               PCI_DEVICE_NUMBER_PCH_LPC,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_P2SB,              PCI_DEVICE_NUMBER_PCH_P2SB,          DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_PMC,               PCI_DEVICE_NUMBER_PCH_PMC,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_HDA,               PCI_DEVICE_NUMBER_PCH_HDA,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1,        PCI_DEVICE_NUMBER_CDF_PCH_SATA_1,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2,        PCI_DEVICE_NUMBER_CDF_PCH_SATA_2,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3,        PCI_DEVICE_NUMBER_CDF_PCH_SATA_3,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SMBUS,             PCI_DEVICE_NUMBER_PCH_SMBUS,         DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SPI,               PCI_DEVICE_NUMBER_PCH_SPI,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_TRACE_HUB,         PCI_DEVICE_NUMBER_PCH_TRACE_HUB,     DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_XHCI,              PCI_DEVICE_NUMBER_PCH_XHCI,          DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_XDCI,              PCI_DEVICE_NUMBER_PCH_XDCI,          DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_THERMAL,           PCI_DEVICE_NUMBER_PCH_THERMAL,       DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,    PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+};
+
+STATIC SVID_SID_INIT_ENTRY mSsidTablePtr[] = {
+  //
+  // SA Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    SA_MC_FUN,        SA_MC_DEV,        SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG0_FUN_NUM,  SA_PEG0_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG1_FUN_NUM,  SA_PEG1_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{R_SA_PEG_SS_OFFSET, SA_PEG2_FUN_NUM,  SA_PEG2_DEV_NUM,  SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IGD_FUN_0,     SA_IGD_DEV,       SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_IPU_FUN_NUM,   SA_IPU_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    SA_GNA_FUN_NUM,   SA_GNA_DEV_NUM,   SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
+  //
+  // PCH Device(s)
+  //
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LPC,     PCI_DEVICE_NUMBER_PCH_LPC,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_P2SB,    PCI_DEVICE_NUMBER_PCH_P2SB,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_PMC,     PCI_DEVICE_NUMBER_PCH_PMC,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_HDA,     PCI_DEVICE_NUMBER_PCH_HDA,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SATA,    PCI_DEVICE_NUMBER_PCH_SATA,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SMBUS,   PCI_DEVICE_NUMBER_PCH_SMBUS,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SPI,     PCI_DEVICE_NUMBER_PCH_SPI,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  //
+  // Skip PCH LAN controller
+  // PCH LAN SVID/SID may be loaded automatically from the NVM Word 0Ch/0Bh upon power up or reset
+  // depending on the "Load Subsystem ID" bit field in NVM word 0Ah
+  //
+  //{{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LAN,     PCI_DEVICE_NUMBER_PCH_LAN,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_TRACE_HUB,       PCI_DEVICE_NUMBER_PCH_TRACE_HUB,        DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0, PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1, PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,   DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_CNL_SCS_SDCARD, PCI_DEVICE_NUMBER_PCH_CNL_SCS_SDCARD, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_XHCI,       PCI_DEVICE_NUMBER_PCH_XHCI,       DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_XDCI,       PCI_DEVICE_NUMBER_PCH_XDCI,       DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_THERMAL,    PCI_DEVICE_NUMBER_PCH_THERMAL,    DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_ISH,               PCI_DEVICE_NUMBER_PCH_ISH,           DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9,  PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_13, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_14, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_15, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_16, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_17, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_18, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_19, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_20, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_21, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_22, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_23, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{R_PCH_PCIE_CFG_SVID,  PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_24, PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2, PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4,  PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,  DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  //
+  // ME Device(s)
+  //
+  {{{PCI_SVID_OFFSET,  HECI_FUNCTION_NUMBER,  ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  HECI2_FUNCTION_NUMBER, ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  IDER_FUNCTION_NUMBER,  ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  SOL_FUNCTION_NUMBER,   ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  HECI3_FUNCTION_NUMBER, ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
+  {{{PCI_SVID_OFFSET,  HECI4_FUNCTION_NUMBER, ME_DEVICE_NUMBER, DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0}
+};
+
+/**
+  This function performs Silicon PEI Policy initialization.
+
+  @param[in] SiPolicy  The Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS  The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicy (
+  IN OUT SI_POLICY_PPI *SiPolicy
+  )
+{
+  EFI_STATUS                         Status;
+  SI_CONFIG                          *SiConfig;
+
+  Status = GetConfigBlock ((VOID *) SiPolicy, &gSiConfigGuid, (VOID *) &SiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  SiConfig->CsmFlag       = 0;
+
+  if (IsCdfPch ()) {
+    SiConfig->SsidTablePtr = (UINT32*)(UINTN) mCdfSsidTablePtr;
+    SiConfig->NumberOfSsidTableEntry = (sizeof (mCdfSsidTablePtr) / sizeof (SVID_SID_INIT_ENTRY));
+  } else {
+    SiConfig->SsidTablePtr = (UINT32*)(UINTN) mSsidTablePtr;
+    SiConfig->NumberOfSsidTableEntry = (sizeof (mSsidTablePtr) / sizeof (SVID_SID_INIT_ENTRY));
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
new file mode 100644
index 0000000000..5c5b788085
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
@@ -0,0 +1,130 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;  PeiCoreEntry.nasm
+;
+; Abstract:
+;
+;   Find and call SecStartup
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(SecStartup)
+extern ASM_PFX(PlatformInit)
+
+global ASM_PFX(CallPeiCoreEntryPoint)
+ASM_PFX(CallPeiCoreEntryPoint):
+  ;
+  ; Obtain the hob list pointer
+  ;
+  mov     eax, [esp+4]
+  ;
+  ; Obtain the stack information
+  ;   ECX: start of range
+  ;   EDX: end of range
+  ;
+  mov     ecx, [esp+8]
+  mov     edx, [esp+0xC]
+
+  ;
+  ; Platform init
+  ;
+  pushad
+  push edx
+  push ecx
+  push eax
+  call ASM_PFX(PlatformInit)
+  pop  eax
+  pop  eax
+  pop  eax
+  popad
+
+  ;
+  ; Set stack top pointer
+  ;
+  mov     esp, edx
+
+  ;
+  ; Push the hob list pointer
+  ;
+  push    eax
+
+  ;
+  ; Save the value
+  ;   ECX: start of range
+  ;   EDX: end of range
+  ;
+  mov     ebp, esp
+  push    ecx
+  push    edx
+
+  ;
+  ; Push processor count to stack first, then BIST status (AP then BSP)
+  ;
+  mov     eax, 1
+  cpuid
+  shr     ebx, 16
+  and     ebx, 0xFF
+  cmp     bl, 1
+  jae     PushProcessorCount
+
+  ;
+  ; Some processors report 0 logical processors.  Effectively 0 = 1.
+  ; So we fix up the processor count
+  ;
+  inc     ebx
+
+PushProcessorCount:
+  push    ebx
+
+  ;
+  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST
+  ; for all processor threads
+  ;
+  xor     ecx, ecx
+  mov     cl, bl
+PushBist:
+  movd    eax, mm0
+  push    eax
+  loop    PushBist
+
+  ; Save Time-Stamp Counter
+  movd eax, mm5
+  push eax
+
+  movd eax, mm6
+  push eax
+
+  ;
+  ; Pass entry point of the PEI core
+  ;
+  mov     edi, 0xFFFFFFE0
+  push    DWORD [edi]
+
+  ;
+  ; Pass BFV into the PEI Core
+  ;
+  mov     edi, 0xFFFFFFFC
+  push    DWORD [edi]
+
+  ;
+  ; Pass stack size into the PEI Core
+  ;
+  mov     ecx, [ebp - 4]
+  mov     edx, [ebp - 8]
+  push    ecx       ; RamBase
+
+  sub     edx, ecx
+  push    edx       ; RamSize
+
+  ;
+  ; Pass Control into the PEI Core
+  ;
+  call ASM_PFX(SecStartup)
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..7f6d771e41
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
@@ -0,0 +1,361 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+; Module Name:
+;
+;  SecEntry.nasm
+;
+; Abstract:
+;
+;  This is the code that goes from real-mode to protected mode.
+;  It consumes the reset vector, calls TempRamInit API from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+#include "Fsp.h"
+
+SECTION .text
+
+extern   ASM_PFX(CallPeiCoreEntryPoint)
+extern   ASM_PFX(FsptUpdDataPtr)
+extern   ASM_PFX(BoardBeforeTempRamInit)
+; Pcds
+extern   ASM_PFX(PcdGet32 (PcdFspTemporaryRamSize))
+extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    _ModuleEntryPoint
+;
+; Input:        None
+;
+; Output:       None
+;
+; Destroys:     Assume all registers
+;
+; Description:
+;
+;   Transition to non-paged flat-model protected mode from a
+;   hard-coded GDT that provides exactly two descriptors.
+;   This is a bare bones transition to protected mode only
+;   used for a while in PEI and possibly DXE.
+;
+;   After enabling protected mode, a far jump is executed to
+;   transfer to PEI using the newly loaded GDT.
+;
+; Return:       None
+;
+;  MMX Usage:
+;              MM0 = BIST State
+;              MM5 = Save time-stamp counter value high32bit
+;              MM6 = Save time-stamp counter value low32bit.
+;
+;----------------------------------------------------------------------------
+
+BITS 16
+align 4
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  fninit                                ; clear any pending Floating point exceptions
+  ;
+  ; Store the BIST value in mm0
+  ;
+  movd    mm0, eax
+  cli
+
+  ;
+  ; Check INIT# is asserted by port 0xCF9
+  ;
+  mov dx, 0CF9h
+  in  al, dx
+  cmp al, 04h
+  jnz NotWarmStart
+
+
+  ;
+  ; @note Issue warm reset, since if CPU only reset is issued not all MSRs are restored to their defaults
+  ;
+  mov dx, 0CF9h
+  mov al, 06h
+  out dx, al
+
+NotWarmStart:
+  ;
+  ; Save time-stamp counter value
+  ; rdtsc load 64bit time-stamp counter to EDX:EAX
+  ;
+  rdtsc
+  movd    mm5, edx
+  movd    mm6, eax
+
+  ;
+  ; Load the GDT table in GdtDesc
+  ;
+  mov     esi,  GdtDesc
+  DB      66h
+  lgdt    [cs:si]
+
+  ;
+  ; Transition to 16 bit protected mode
+  ;
+  mov     eax, cr0                   ; Get control register 0
+  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)
+  mov     cr0, eax                   ; Activate protected mode
+
+  mov     eax, cr4                   ; Get control register 4
+  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+  mov     cr4, eax
+
+  ;
+  ; Now we're in 16 bit protected mode
+  ; Set up the selectors for 32 bit protected mode entry
+  ;
+  mov     ax, SYS_DATA_SEL
+  mov     ds, ax
+  mov     es, ax
+  mov     fs, ax
+  mov     gs, ax
+  mov     ss, ax
+
+  ;
+  ; Transition to Flat 32 bit protected mode
+  ; The jump to a far pointer causes the transition to 32 bit mode
+  ;
+  mov esi, ProtectedModeEntryLinearAddress
+  jmp   dword far  [cs:si]
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    ProtectedModeEntryPoint
+;
+; Input:        None
+;
+; Output:       None
+;
+; Destroys:     Assume all registers
+;
+; Description:
+;
+; This function handles:
+;   Call two basic APIs from FSP binary
+;   Initializes stack with some early data (BIST, PEI entry, etc)
+;
+; Return:       None
+;
+;----------------------------------------------------------------------------
+
+BITS 32
+align 4
+ProtectedModeEntryPoint:
+  ;
+  ; Early board hooks
+  ;
+  mov     esp, BoardBeforeTempRamInitRet
+  jmp     ASM_PFX(BoardBeforeTempRamInit)
+
+BoardBeforeTempRamInitRet:
+
+  ; Find the fsp info header
+  mov  edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]
+
+  mov  eax, dword [edi + FVH_SIGINATURE_OFFSET]
+  cmp  eax, FVH_SIGINATURE_VALID_VALUE
+  jnz  FspHeaderNotFound
+
+  xor  eax, eax
+  mov  ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]
+  cmp  ax, 0
+  jnz  FspFvExtHeaderExist
+
+  xor  eax, eax
+  mov  ax, word [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header
+  add  edi, eax
+  jmp  FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+  add  edi, eax
+  mov  eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv Header
+  add  edi, eax
+
+  ; Round up to 8 byte alignment
+  mov  eax, edi
+  and  al,  07h
+  jz   FspCheckFfsHeader
+
+  and  edi, 0FFFFFFF8h
+  add  edi, 08h
+
+FspCheckFfsHeader:
+  ; Check the ffs guid
+  mov  eax, dword [edi]
+  cmp  eax, FSP_HEADER_GUID_DWORD1
+  jnz  FspHeaderNotFound
+
+  mov  eax, dword [edi + 4]
+  cmp  eax, FSP_HEADER_GUID_DWORD2
+  jnz  FspHeaderNotFound
+
+  mov  eax, dword [edi + 8]
+  cmp  eax, FSP_HEADER_GUID_DWORD3
+  jnz  FspHeaderNotFound
+
+  mov  eax, dword [edi + 0Ch]
+  cmp  eax, FSP_HEADER_GUID_DWORD4
+  jnz  FspHeaderNotFound
+
+  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header
+
+  ; Check the section type as raw section
+  mov  al, byte [edi + SECTION_HEADER_TYPE_OFFSET]
+  cmp  al, 019h
+  jnz FspHeaderNotFound
+
+  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
+  jmp FspHeaderFound
+
+FspHeaderNotFound:
+  jmp  $
+
+FspHeaderFound:
+  ; Get the fsp TempRamInit Api address
+  mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]
+  add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
+
+  ; Setup the hardcode stack
+  mov esp, TempRamInitStack
+
+  ; Call the fsp TempRamInit Api
+  jmp eax
+
+TempRamInitDone:
+  cmp eax, 8000000Eh      ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.
+  je  CallSecFspInit      ;If microcode not found, don't hang, but continue.
+
+  cmp eax, 0              ;Check if EFI_SUCCESS retuned.
+  jnz FspApiFailed
+
+  ;   ECX: start of range
+  ;   EDX: end of range
+CallSecFspInit:
+  sub     edx, [ASM_PFX(PcdGet32 (PcdFspTemporaryRamSize))] ; TemporaryRam for FSP
+  xor     eax, eax
+  mov     esp, edx
+
+  ; Align the stack at DWORD
+  add  esp,  3
+  and  esp, 0FFFFFFFCh
+
+  push    edx
+  push    ecx
+  push    eax ; zero - no hob list yet
+  call    ASM_PFX(CallPeiCoreEntryPoint)
+
+FspApiFailed:
+  jmp $
+
+align 10h
+TempRamInitStack:
+    DD  TempRamInitDone
+    DD  ASM_PFX(FsptUpdDataPtr); TempRamInitParams
+
+;
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase
+;
+align 16
+global  ASM_PFX(BootGdtTable)
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]
+GDT_BASE:
+ASM_PFX(BootGdtTable):
+                    DD  0
+                    DD  0
+;
+; Linear data segment descriptor
+;
+LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  092h                            ; present, ring 0, data, expand-up, writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  09Bh                            ; present, ring 0, data, expand-up, not-writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+
+;
+; System code segment descriptor
+;
+SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  09Ah                            ; present, ring 0, data, expand-up, writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; Spare segment descriptor
+;
+SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0Eh                             ; Changed from F000 to E000.
+    DB  09Bh                            ; present, ring 0, code, expand-up, writable
+    DB  00h                             ; byte-granular, 16-bit
+    DB  0
+;
+; Spare segment descriptor
+;
+SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]
+    DW  0FFFFh                          ; limit 0xFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable
+    DB  00h                             ; byte-granular, 16-bit
+    DB  0
+
+;
+; Spare segment descriptor
+;
+SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]
+    DW  0                               ; limit 0
+    DW  0                               ; base 0
+    DB  0
+    DB  0                               ; present, ring 0, data, expand-up, writable
+    DB  0                               ; page-granular, 32-bit
+    DB  0
+GDT_SIZE            EQU $ - GDT_BASE    ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc:                                ; GDT descriptor
+    DW  GDT_SIZE - 1                    ; GDT limit
+    DD  GDT_BASE                        ; GDT base address
+
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinear:
+  DD      ProtectedModeEntryPoint  ; Offset of our 32 bit code
+  DW      LINEAR_CODE_SEL
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
new file mode 100644
index 0000000000..47db32d64c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
@@ -0,0 +1,72 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+; Abstract:
+;
+;   Switch the stack from temporary memory to permanent memory.
+;
+;------------------------------------------------------------------------------
+
+    SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; SecSwitchStack (
+;   UINT32   TemporaryMemoryBase,
+;   UINT32   PermanentMemoryBase
+;   );
+;------------------------------------------------------------------------------
+global ASM_PFX(SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+    ;
+    ; Save three register: eax, ebx, ecx
+    ;
+    push  eax
+    push  ebx
+    push  ecx
+    push  edx
+
+    ;
+    ; !!CAUTION!! this function address's is pushed into stack after
+    ; migration of whole temporary memory, so need save it to permanent
+    ; memory at first!
+    ;
+
+    mov   ebx, [esp + 20]          ; Save the first parameter
+    mov   ecx, [esp + 24]          ; Save the second parameter
+
+    ;
+    ; Save this function's return address into permanent memory at first.
+    ; Then, Fixup the esp point to permanent memory
+    ;
+    mov   eax, esp
+    sub   eax, ebx
+    add   eax, ecx
+    mov   edx, dword [esp]         ; copy pushed register's value to permanent memory
+    mov   dword [eax], edx
+    mov   edx, dword [esp + 4]
+    mov   dword [eax + 4], edx
+    mov   edx, dword [esp + 8]
+    mov   dword [eax + 8], edx
+    mov   edx, dword [esp + 12]
+    mov   dword [eax + 12], edx
+    mov   edx, dword [esp + 16]    ; Update this function's return address into permanent memory
+    mov   dword [eax + 16], edx
+    mov   esp, eax                     ; From now, esp is pointed to permanent memory
+
+    ;
+    ; Fixup the ebp point to permanent memory
+    ;
+    mov   eax, ebp
+    sub   eax, ebx
+    add   eax, ecx
+    mov   ebp, eax                ; From now, ebp is pointed to permanent memory
+
+    pop   edx
+    pop   ecx
+    pop   ebx
+    pop   eax
+    ret
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
new file mode 100644
index 0000000000..33b4be68db
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
@@ -0,0 +1,15 @@
+/** @file
+  Base ACPI Timer Library
+  Provides basic timer support using the ACPI timer hardware.  The performance
+  counter features are provided by the processors time stamp counter.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#string STR_MODULE_ABSTRACT             #language en-US "ACPI Timer Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Provides basic timer support using the ACPI timer hardware."
+
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:17   ` Chiu, Chasel
  2019-08-17 20:08   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances

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

WhiskeylakeURvp library instances.

* BaseFuncLib - Board-specific VBT update routines.
* BaseGpioCheckConflictLib - Identifies GPIO pad conflicts.
* BaseGpioCheckConflictLibNull - NULL library instance.
* BasePlatformHookLib - Serial port initialization support.
* DxePolicyBoardConfigLib - Board-specific silicon policy configuration
  in DXE.
* PeiBoardInitPostMemLib - PEI post-memory board-specific initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiBoardInitPreMemLib - PEI pre-memory board-specific initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiMultiBoardInitPostMemLib - PEI post-memory multi-board initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiMultiBoardInitPreMemLib - PEI pre-memory multi-board initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiPlatformHookLib - PEI board instance-specifc GPIO init.
* PeiPolicyBoardConfigLib - Board instance-specific policy init in PEI.
* SmmBoardAcpiEnableLib - Board instance-specific SMM ACPI enable support.
* SmmMultiBoardAcpiSupportLib - Multi-board ACPI support in SMM.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf                                   |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf         |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf                   |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf                        |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf                  |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf                       |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf                        |  116 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf                  |  202 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf                   |  296 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf                     |   94 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf           |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h                                      |   18 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h                                   |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h                            |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h                               |  225 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h                              |  284 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h                        |   59 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h                               | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h                      |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h                |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h                |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c                                             |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c           |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c   |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c                     |  156 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c                          |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c                    |   82 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c                        |  170 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c                |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c                                      |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c                                  |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c                            |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c                          |  398 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c                           |  282 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c                         |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c                          |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c                    |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c                     |   83 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c                       |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c               |  432 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c                |  636 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c                  |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c                       |  299 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c             |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c       |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c             |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c       |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c              |   27 +
 55 files changed, 8499 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
new file mode 100644
index 0000000000..0ccc73b99f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component information file for Board Functions Library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseBoardFuncInitLib
+  FILE_GUID                      = 7ad17b6c-b9b6-4d88-85c4-7366a2bd12a3
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL|PEIM
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+
+[Packages]
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  Gop.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
new file mode 100644
index 0000000000..5014faf664
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component information file for BaseGpioCheckConflictLib.
+#
+#
+#  Copyright (c) 2019, 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
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLib.c
+
+[Guids]
+  gGpioCheckConflictHobGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
new file mode 100644
index 0000000000..d9b242b3fc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
@@ -0,0 +1,32 @@
+## @file
+# Component information file for BaseGpioCheckConflictLib.
+#
+#
+#  Copyright (c) 2019, 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
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLibNull.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
new file mode 100644
index 0000000000..143bb89c63
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BasePlatformHookLib
+  FILE_GUID                      = E22ADCC6-ED90-4A90-9837-C8E7FF9E963D
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = PlatformHookLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciSegmentLib
+  PchCycleDecodingLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort                 ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort  ## CONSUMES
+
+[FixedPcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding            ## CONSUMES
+
+[Sources]
+  BasePlatformHookLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
new file mode 100644
index 0000000000..8ad32a55dc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmBoardAcpiEnableLib
+  FILE_GUID                      = 549E69AE-D3B3-485B-9C17-AF16E20A58AD
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = BoardAcpiEnableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciLib
+  MmPciLib
+  PchCycleDecodingLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
+
+[Protocols]
+
+[Sources]
+  SmmWhiskeylakeURvpAcpiEnableLib.c
+  SmmSiliconAcpiEnableLib.c
+  SmmBoardAcpiEnableLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
new file mode 100644
index 0000000000..27001c3b7f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmWhiskeylakeURvpMultiBoardAcpiSupportLib
+  FILE_GUID                      = 8929A54E-7ED8-4AB3-BEBB-C0367BDBBFF5
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciLib
+  PmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
+
+[Protocols]
+
+[Sources]
+  SmmWhiskeylakeURvpAcpiEnableLib.c
+  SmmSiliconAcpiEnableLib.c
+  SmmMultiBoardAcpiSupportLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..a8c4869e96
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Component information file for WhiskeylakeURvpInitLib in PEI post memory phase.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiBoardPostMemInitLib
+  FILE_GUID                      = 7fcc3900-d38d-419f-826b-72481e8b5509
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  HdaVerbTableLib
+  MemoryAllocationLib
+  GpioExpanderLib
+  PcdLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPostMemLib.c
+  PeiBoardInitPostMemLib.c
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
+
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
+
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..9361c3df3e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,116 @@
+## @file
+# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiBoardInitPreMemLib
+  FILE_GUID                      = ec3675bc-1470-417d-826e-37378140213d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  PcdLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpDetect.c
+  PeiWhiskeylakeURvpInitPreMemLib.c
+  WhiskeylakeURvpHsioPtssTables.c
+  PeiBoardInitPreMemLib.c
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
+
+  # PCH-LP HSIO PTSS Table
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
+
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..4831735dc5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
@@ -0,0 +1,202 @@
+## @file
+# Component information file for WhiskeylakeURvpInitLib in PEI post memory phase.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitLib
+  FILE_GUID                      = C7D39F17-E5BA-41D9-8DFE-FF9017499280
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = PeiWhiskeylakeURvpMultiBoardInitLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  GpioExpanderLib
+  PcdLib
+  MultiBoardInitSupportLib
+  HdaVerbTableLib
+  PeiPlatformHookLib
+  PeiPolicyInitLib
+  PchInfoLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPostMemLib.c
+  PeiMultiBoardInitPostMemLib.c
+  BoardFunc.c
+  BoardFuncInit.c
+
+[FixedPcd]
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
+
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
+
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
+
+  #===========================================================
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase
+  # Board Init Table List
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # WWAN Full Card Power Off and reset pins
+  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## PRODUCES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## PRODUCES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
+
+  # Pch PmConfig Policy
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
+
+
+  gBoardModuleTokenSpaceGuid.PcdSpdPresent
+  gBoardModuleTokenSpaceGuid.PcdBoardRev
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable
+  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable
+  # TPM interrupt
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
+
+[Guids]
+  gAttemptUsbFirstHotkeyInfoHobGuid             ## CONSUMES
+  gCnlPchLpChipsetInitTableDxGuid               ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..6affc3180e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
@@ -0,0 +1,296 @@
+## @file
+# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitPreMemLib
+  FILE_GUID                      = EA05BD43-136F-45EE-BBBA-27D75817574F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  PcdLib
+  MultiBoardInitSupportLib
+  StallPpiLib
+  PchResetLib
+  PeiPlatformHookLib
+  PlatformHookLib
+  PeiPolicyInitLib
+  OcWdtLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPreMemLib.c
+  WhiskeylakeURvpHsioPtssTables.c
+  PeiMultiBoardInitPreMemLib.c
+  PeiWhiskeylakeURvpDetect.c
+  BoardSaInitPreMemLib.c
+  BoardPchInitPreMemLib.c
+  BoardFuncInitPreMem.c
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid
+  gEfiPeiMemoryDiscoveredPpiGuid                ## CONSUMES
+  gEfiPeiResetPpiGuid                           ## PRODUCES
+
+[Guids]
+  gPchGeneralPreMemConfigGuid      ## CONSUMES
+  gTcoWdtHobGuid                                ## CONSUMES
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
+
+  # PCH-LP HSIO PTSS Table
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  # PCH-H HSIO PTSS Table
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
+
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+
+  #===========================================================
+  # Board Init Table List
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # WWAN Full Card Power Off and reset pins
+  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## PRODUCES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## PRODUCES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
+
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
+
+  # Pch PmConfig Policy
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
+
+
+  gBoardModuleTokenSpaceGuid.PcdSpdPresent
+  gBoardModuleTokenSpaceGuid.PcdBoardRev
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
+  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround    ## PRODUCES
+  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
+
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdMchBaseAddress              ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdMchMmioSize                 ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize        ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpMmioSize         ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize       ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize  ## CONSUMES
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
new file mode 100644
index 0000000000..2c9af5b9a3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Module Information file for DxePolicyBoardConfigLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = DxePolicyBoardConfigLib
+  FILE_GUID                      = 17836E9F-7188-4640-80A3-B4441585FFE9
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  DxeSaPolicyBoardConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseLib
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  HobLib
+  ConfigBlockLib
+
+[Guids]
+  gMemoryDxeConfigGuid                          ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
new file mode 100644
index 0000000000..079fb70ecb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
@@ -0,0 +1,94 @@
+## @file
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPlatformHookLib
+  FILE_GUID                      = AD901798-B0DA-4B20-B90C-283F886E76D0
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPlatformHookLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  IoLib
+  HobLib
+  PcdLib
+  TimerLib
+  PchCycleDecodingLib
+  GpioLib
+  CpuPlatformLib
+  PeiServicesLib
+  ConfigBlockLib
+  PeiSaPolicyLib
+  GpioExpanderLib
+  PmcLib
+  PchPcrLib
+  PciSegmentLib
+  GpioCheckConflictLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel          ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2              ## CONSUMES
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable                ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
+  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround
+
+[Sources]
+  PeiPlatformHooklib.c
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+
+[Guids]
+  gSaDataHobGuid                                ## CONSUMES
+  gEfiGlobalVariableGuid                        ## CONSUMES
+  gGpioCheckConflictHobGuid                     ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
new file mode 100644
index 0000000000..65e66ccb62
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
@@ -0,0 +1,70 @@
+## @file
+# Module Information file for PeiPolicyBoardConfigLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyBoardConfigLib
+  FILE_GUID                      = B1E959E3-9DCA-4D6F-938C-420C3BF5D820
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyBoardConfigLib|PEIM PEI_CORE SEC
+
+[Sources]
+  PeiCpuPolicyBoardConfigPreMem.c
+  PeiCpuPolicyBoardConfig.c
+  PeiMePolicyBoardConfigPreMem.c
+  PeiMePolicyBoardConfig.c
+  PeiPchPolicyBoardConfigPreMem.c
+  PeiPchPolicyBoardConfig.c
+  PeiSaPolicyBoardConfigPreMem.c
+  PeiSaPolicyBoardConfig.c
+  PeiSiPolicyBoardConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  DebugLib
+  HobLib
+  ConfigBlockLib
+  IoLib
+  BaseCryptLib
+  BaseMemoryLib
+
+[Guids]
+  gCpuSecurityPreMemConfigGuid                  ## CONSUMES
+  gMePeiPreMemConfigGuid                        ## CONSUMES
+  gPchGeneralPreMemConfigGuid                   ## CONSUMES
+  gSaMiscPeiPreMemConfigGuid                    ## CONSUMES
+  gCpuConfigGuid                                ## CONSUMES
+  gPchGeneralConfigGuid                         ## CONSUMES
+  gEfiTpmDeviceInstanceTpm20DtpmGuid
+  gEfiTpmDeviceInstanceTpm12Guid
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
+
+[FixedPcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize                             ## CONSUMES
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
new file mode 100644
index 0000000000..eca492e72d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
@@ -0,0 +1,18 @@
+/** @file
+  Header file for Board Hook function intance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BOARD_FUNC_H_
+#define _BOARD_FUNC_H_
+
+EFI_STATUS
+PeiBoardSpecificInitPostMemNull (
+  VOID
+  );
+
+#endif // _BOARD_FUNC_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
new file mode 100644
index 0000000000..5435b4a6e3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
@@ -0,0 +1,20 @@
+/** @file
+ Header file for board Init function for Post Memory Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_BOARD_INIT_LIB_H_
+#define _PEI_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+
+#endif // _PEI_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
new file mode 100644
index 0000000000..41c798a082
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
@@ -0,0 +1,90 @@
+/** @file
+  PEI Boards Configurations for PreMem phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BOARD_SA_CONFIG_PRE_MEM_H_
+#define _BOARD_SA_CONFIG_PRE_MEM_H_
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>               // for MRC Configuration
+#include <ConfigBlock/SwitchableGraphicsConfig.h>   // for PCIE RTD3 GPIO
+#include <GpioPinsCnlLp.h>                          // for GPIO definition
+#include <GpioPinsCnlH.h>
+#include <SaAccess.h>                               // for Root Port number
+#include <PchAccess.h>                              // for Root Port number
+
+//
+// The following section contains board-specific CMD/CTL/CLK and DQ/DQS mapping, needed for LPDDR3/LPDDR4
+//
+
+//
+// DQByteMap[0] - ClkDQByteMap:
+//   If clock is per rank, program to [0xFF, 0xFF]
+//   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+//   If clock is shared by 2 ranks but does not go to all bytes,
+//           Entry[i] defines which DQ bytes Group i services
+// DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+// DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+// DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+//                For DDR, DQByteMap[3:1] = [0xFF, 0]
+// DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+//                               Variable only exists to make the code easier to use
+// DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+//                               Variable only exists to make the code easier to use
+//
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for WHL RVP3, WHL SDS - used by WHL/WHL MRC
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapWhlUDdr4Rvp[2][6][2] = {
+  // Channel 0:
+  {
+    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  },
+  // Channel 1:
+  {
+    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  }
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqsMapCpu2DramWhlUDdr4Rvp[2][8] = {
+  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
+  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 DqsMapCpu2DramWhlUmDvp[2][8] = {
+  { 0, 3, 1, 2, 7, 5, 6, 4 }, // Channel 0
+  { 0, 2, 1, 3, 6, 4, 7, 5 }  // Channel 1
+};
+
+//
+// Reference RCOMP resistors on motherboard
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorCflUDdr4Interposer[SA_MRC_MAX_RCOMP] = { 121, 81, 100 };
+
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetWhlUDdr4Interposer[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 20, 20, 26 };
+
+#endif // _BOARD_SA_CONFIG_PRE_MEM_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
new file mode 100644
index 0000000000..a943d5bd04
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
@@ -0,0 +1,225 @@
+/** @file
+  GPIO definition table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_TABLE_DEFAULT_H_
+#define _GPIO_TABLE_DEFAULT_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+#define END_OF_GPIO_TABLE 0xFFFFFFFF
+
+//
+// CNL U DRR4 Board GPIO table configuration is used as default
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG mGpioTableDefault[] =
+{
+//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,  GPIRoutConfig,  PadRstCfg,  Term,
+  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_0
+  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_1
+  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CSB
+  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
+  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
+  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
+  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //WWAN_WAKE_N
+  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2, GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault, GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
+  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset, GpioTermNone } },  //DGPU_SEL_SLOT1
+  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
+  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPKR_PD_N
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WFCAM_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //ACCEL_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //ALS_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //HALL_SENSOR_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_WAKE
+  //(RC control) {GPIO_CNL_LP_GPP_A23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //SHARED_INT
+  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock } },  //BT_UART_WAKE
+  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock }},  //FORCE_PAD_INT
+  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone , GpioPadConfigUnlock} },  //BT_DISABLE_N
+  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
+  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
+  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
+  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //TCH_PNL_PWR_EN
+  //(CSME Pad) {GPIO_CNL_LP_GPP_B15,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //NFC_DFU
+  { GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
+  { GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock} },  //FPS_RESET_N
+  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},  //TBT_CIO_PWR_EN
+  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
+  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone}},  //EC_SLP_S0_CS_N
+  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
+  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,  GpioTermNone }},  //WIFI_RF_KILL_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
+  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIFI_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermWpu20K } },  //CODEC_INT_N
+  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
+  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone}},  //TBT_FORCE_PWR
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_PWREN_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
+  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
+  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
+  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
+  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL2_RST_N
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SLOT1_WAKE_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //NFC_RST_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,  GpioTermNone }},  //WWAN_PWREN
+  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL_RST_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //NFC_INT_N
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
+  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
+  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
+  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
+  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
+  {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
+  {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
+  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
+  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
+  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
+  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,  GpioTermWpu20K}},  //Reserved for SATA HP val
+  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,  GpioTermNone}},  //EC_SMI_N
+  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
+  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SSD_DEVSLP
+  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //HDD_DEVSLP
+  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL_INT_N
+  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
+  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
+  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
+  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
+  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
+  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
+  //(Not used){GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F0_COEX3
+  {GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},  //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_HDD_PWREN
+  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WF_CLK_EN
+  //(RC control) {GPIO_CNL_LP_GPP_F4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_BRI_DT_UART0_RTSB
+  //(RC control) {GPIO_CNL_LP_GPP_F5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_BRI_RSP_UART0_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_F6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_RGI_DT_UART0_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_F7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_RGI_RSP_UART0_CTSB
+  {GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_MFUART2_RXD
+  {GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_MFUART2_TXD
+
+  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be used at IsRecoveryMode()
+  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone}},  //BIOS_REC
+
+  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
+  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
+  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
+  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
+  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
+  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
+  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
+  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
+  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
+  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_F_23
+  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
+  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
+  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
+  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
+  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
+  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
+  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpd20K }},  //GPP_G_7_SD3_WP
+  //{GPIO_CNL_LP_GPP_H0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_0_SSP2_SCLK
+  //{GPIO_CNL_LP_GPP_H1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_1_SSP2_SFRM
+  //{GPIO_CNL_LP_GPP_H2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_2_SSP2_TXD
+  //{GPIO_CNL_LP_GPP_H3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_3_SSP2_RXD
+  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
+  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_PWREN
+  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_RECOVERY
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IRIS_STROBE
+  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL0
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
+  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_KEY
+  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
+  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
+  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
+  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL1
+  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
+  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H21
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WF_CAM_RST
+  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H23
+  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
+  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //BC_ACOK
+  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
+  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
+  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
+  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SLP_A_N
+  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPD_7
+  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SUS_CLK
+  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
+  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
+  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpd20K }}, // 20K PD for PECI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG mGpioTablePreMemDefault[] =
+{
+  {END_OF_GPIO_TABLE,  {GpioPadModeGpio,    GpioHostOwnGpio, GpioDirNone,  GpioOutDefault, GpioIntDis, GpioDswReset,  GpioTermNone}},//Marking End of Table
+};
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
new file mode 100644
index 0000000000..86b7cb3717
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
@@ -0,0 +1,284 @@
+/** @file
+  GPIO definition table for WhiskeyLake U Ddr4 RVP
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+#define _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4_0[] =
+{
+//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,  GPIRoutConfig,  PadRstCfg,  Term,
+  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_0
+  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_1
+  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CSB
+  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
+  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
+  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //WWAN_WAKE_N
+  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2, GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault, GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
+  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset, GpioTermNone } },  //DGPU_SEL_SLOT1
+  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
+  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPKR_PD_N
+  {GPIO_CNL_LP_GPP_A16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutLow, GpioIntDefault, GpioPlatformReset, GpioTermWpu20K, GpioPadUnlock }},  //WFCAM_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
+  //A18-A23 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_A18,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //ACCEL_INT
+  {GPIO_CNL_LP_GPP_A19,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //ALS_INT
+  {GPIO_CNL_LP_GPP_A20,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
+  {GPIO_CNL_LP_GPP_A21,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //HALL_SENSOR_INT
+  {GPIO_CNL_LP_GPP_A22,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //IVCAM_WAKE
+  {GPIO_CNL_LP_GPP_A23,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //SHARED_INT
+  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermNone, GpioPadUnlock } },  //BT_UART_WAKE
+  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadUnlock }},  //FORCE_PAD_INT
+  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone , GpioOutputStateUnlock} },  //BT_DISABLE_N
+  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
+  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
+  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
+  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //TCH_PNL_PWR_EN
+  //B15 -Unused pin -> Under GPIO table for GPIO Termination - Input sensing disable
+  {GPIO_CNL_LP_GPP_B15, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,  GpioTermNone }},  //Former NFC_DFU
+  {GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
+  {GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock} },  //FPS_RESET_N
+  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},  //TBT_CIO_PWR_EN
+  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
+  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone, GpioPadUnlock }},  //EC_SLP_S0_CS_N
+  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
+  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,  GpioTermNone, GpioOutputStateUnlock }},  //WIFI_RF_KILL_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
+  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIFI_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi , GpioDirIn , GpioOutDefault , GpioIntLevel | GpioIntApic , GpioPlatformReset, GpioTermWpu20K } },  //CODEC_INT_N
+  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
+  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //TBT_FORCE_PWR
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
+  //move to premem phase for early power turn on
+  //  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  //  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_PWREN_N
+  //  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_PWREN_N
+  //  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+
+  //Only clear Reset pins in Post-Mem
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+
+  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
+  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
+  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
+  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
+  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL2_RST_N
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SLOT1_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //Former NFC_RST_N
+  //{GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,  GpioTermNone }},  //WWAN_PWREN
+  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL_RST_N
+  //(Not used) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //Former NFC_INT_N
+  //{GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
+  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
+  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
+  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
+  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
+  //(CSME control) {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
+  //(CSME control) {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
+  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
+  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
+  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
+  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,  GpioTermWpu20K}},  //Reserved for SATA HP val
+  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock}},  //EC_SMI_N
+  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
+  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SSD_DEVSLP
+  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //HDD_DEVSLP
+  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL_INT_N
+  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
+  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
+  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
+  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
+  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
+  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
+   //F0- unused pin-Input Sensing disable F4-F7 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,  GpioTermNone }},  //GPP_F0_COEX3
+  //{GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},  //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K }},  //SATA_HDD_PWREN
+  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K, GpioPadUnlock }},  //WF_CLK_EN
+  {GPIO_CNL_LP_GPP_F4,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_BRI_DT_UART0_RTSB
+  {GPIO_CNL_LP_GPP_F5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_BRI_RSP_UART0_RXD
+  {GPIO_CNL_LP_GPP_F6,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_RGI_DT_UART0_TXD
+  {GPIO_CNL_LP_GPP_F7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_RGI_RSP_UART0_CTSB
+  //{GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_MFUART2_RXD
+  //{GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_MFUART2_TXD
+
+  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be used at IsRecoveryMode()
+  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K}},  //BIOS_REC
+
+  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
+  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
+  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
+  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
+  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
+  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
+  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
+  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
+  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
+  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_F_23
+  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
+  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
+  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
+  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
+  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
+  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
+  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpd20K }},  //GPP_G_7_SD3_WP
+  //H0-H3 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_H0,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_0_SSP2_SCLK
+  {GPIO_CNL_LP_GPP_H1,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_1_SSP2_SFRM
+  {GPIO_CNL_LP_GPP_H2,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_2_SSP2_TXD
+  {GPIO_CNL_LP_GPP_H3,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_3_SSP2_RXD
+  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
+  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_PWREN
+  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_RECOVERY
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IRIS_STROBE
+  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL0
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
+  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_KEY
+  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
+  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
+  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
+  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL1
+  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
+  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H21
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //WF_CAM_RST
+  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H23
+  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
+  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //BC_ACOK
+  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
+  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
+  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
+  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SLP_A_N
+  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPD_7
+  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SUS_CLK
+  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
+  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
+  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpd20K }}, // 20K PD for PECI
+};
+
+static GPIO_INIT_CONFIG mGpioTableCflUDdr4[] = {
+  //                       Pmode,                GPI_IS,             GpioDir,        GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
+  // WiGig start
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioHostDeepReset,  GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,      GpioHostOwnGpio,   GpioDirInInv,    GpioOutHigh, GpioIntLevel | GpioIntSci,    GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_PEWAKE_R_N / WF_CAM_RST on CNL U
+  //WiGig end
+  // Camera start
+  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio,      GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
+  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio,      GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  // Camera end
+  // Touch start
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,      GpioHostOwnGpio,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
+  // Touch end
+  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio,      GpioHostOwnAcpi,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,    GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,      GpioHostOwnAcpi,     GpioDirOut,    GpioOutHigh, GpioIntDis,                   GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio,      GpioHostOwnGpio,      GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock } },  //SPI_TPM_INT_N                                                                                                                                          // Unused start
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermWpu20K }}, //Unused so disabled / WF_CLK_EN on CNL U
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / Not used on CNL U
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}  //Unused so disabled / Not used on CNL U
+  // Unused end
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4[] = {
+  //                       Pmode,                GPI_IS,             GpioDir,        GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
+  // WiGig start
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioHostDeepReset,  GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
+  // WiGig end
+  // Camera start
+  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio, GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
+  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  // Camera end
+  // Touch start
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio, GpioHostOwnGpio,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio, GpioHostOwnAcpi,     GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,  GpioTermNone}},    //SLOT1_RST_N
+  // Touch end
+  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio, GpioHostOwnAcpi,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K,  GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
+  // TBT start
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }},  //TBT_CIO_PWR_EN
+  // TBT end
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio, GpioHostOwnGpio,      GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},         //SPI_TPM_INT_N
+  // Unused start
+  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermWpu20K }}  //Unused so disabled / WF_CLK_EN on CNL U
+  // Unused end
+};
+
+
+#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
new file mode 100644
index 0000000000..01a6599564
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
@@ -0,0 +1,59 @@
+/** @file
+  GPIO definition table for WhiskeyLake U Ddr4 RVP Pre-Memory
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+#define _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4PreMem[] =
+{
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_RST_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_PWREN_N
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlTbtRvpPreMem[] =
+{
+  // do not reset SLOT1 due to TR AIC card cannot be reset in S3/S4 resume.
+  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_RST_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_PWREN_N
+};
+
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOnEarlyPreMem[] =
+{
+  // Turn on WWAN power and de-assert reset pins by default
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioPlatformReset, GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
+  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOffEarlyPreMem[] =
+{
+  // Assert reset pins and then turn off WWAN power
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
+  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioPlatformReset, GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
+};
+
+#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
new file mode 100644
index 0000000000..0d26e8ad7a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
@@ -0,0 +1,3014 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_VERB_TABLES_H_
+#define _PCH_HDA_VERB_TABLES_H_
+
+#include <Ppi/SiPolicy.h>
+
+HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: CFL Display Audio Codec
+  //  Revision ID = 0xFF
+  //  Codec Vendor: 0x8086280B
+  //
+  0x8086, 0x280B,
+  0xFF, 0xFF,
+  //
+  // Display Audio Verb Table
+  //
+  // For GEN9, the Vendor Node ID is 08h
+  // Port to be exposed to the inbox driver in the vanilla mode: PORT C - BIT[7:6] = 01b
+  0x00878140,
+  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
+  0x00571C10,
+  0x00571D00,
+  0x00571E56,
+  0x00571F18,
+  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
+  0x00671C20,
+  0x00671D00,
+  0x00671E56,
+  0x00671F18,
+  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
+  0x00771C30,
+  0x00771D00,
+  0x00771E56,
+  0x00771F18,
+  // Disable the third converter and third Pin (NID 08h)
+  0x00878140
+);
+
+//
+//codecs verb tables
+//
+HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40622005
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D20,
+  0x01D71E62,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B,
+
+
+  //Widget node 0X20 for ALC1305   20160603 update
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+  //
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204800F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02044848,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050000,
+  0x02043330,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050000,
+  0x02043333,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x020402EC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02044909,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x020440B0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040047,
+  0x02050028,
+  0x02040C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040048,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040049,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004A,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040001,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024
+); // HdaVerbTableAlc700
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC701)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0701
+  //
+  0x10EC, 0x0701,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC701
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40610041
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC1124
+  0x00172024,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C41,
+  0x01D71D00,
+  0x01D71E61,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B
+); // HdaVerbTableAlc701
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC274)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0274
+  //
+  0x10EC, 0x0274,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC274
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
+  //The number of verb command block : 16
+
+  //    NID 0x12 : 0x40000000
+  //    NID 0x13 : 0x411111F0
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x411111F0
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11020
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40451B05
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211010
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //,DA Codec Subsystem ID  : 0x10EC10F6
+  0x001720F6,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371CF0,
+  0x01371D11,
+  0x01371E11,
+  0x01371F41,
+  //Pin widget 0x14 - NPC
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S_OUT2
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S_OUT1
+  0x01771CF0,
+  0x01771D11,
+  0x01771E11,
+  0x01771F41,
+  //Pin widget 0x18 - I2S_IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C20,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D1B,
+  0x01D71E45,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C10,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205006F,
+  0x02042C0B,
+  //Widget node 0x20 - 1 :
+  0x02050035,
+  0x02048968,
+  0x05B50001,
+  0x05B48540,
+  //Widget node 0x20 - 2 :
+  0x05850000,
+  0x05843888,
+  0x05850000,
+  0x05843888,
+  //Widget node 0x20 - 3 :
+  0x0205004A,
+  0x0204201B,
+  0x0205004A,
+  0x0204201B
+); //HdaVerbTableAlc274
+
+//
+// CFL S Audio Codec
+//
+STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) CFL S RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x90A60130
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x03011010
+  //    NID 0x17 : 0x90170120
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A1103E
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x03A11040
+  //    NID 0x1D : 0x40600001
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x0421102F
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC112C
+  0x0017202C,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C30,
+  0x01271D01,
+  0x01271EA6,
+  0x01271F90,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671C10,
+  0x01671D10,
+  0x01671E01,
+  0x01671F03,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C20,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C3E,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71C40,
+  0x01B71D10,
+  0x01B71EA1,
+  0x01B71F03,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C01,
+  0x01D71D00,
+  0x01D71E60,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C2F,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
+  0x0205006B,
+  0x02044260,
+  0x0205006B,
+  0x02044260,
+  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent control
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 4   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+
+  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove ALC1305 EQ setting
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x02042213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+);
+
+
+//
+// WHL codecs verb tables
+//
+HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) WHL RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table for WHL PCH boards
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x02A19040
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40638029
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x02211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271CF0,
+  0x01271D11,
+  0x01271E11,
+  0x01271F41,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C40,
+  0x01971D90,
+  0x01971EA1,
+  0x01971F02,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C29,
+  0x01D71D80,
+  0x01D71E63,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F02,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+
+  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass DAC02 DRE(NID5B bit14)
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+
+  //Widget node 0x20 -2:
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+
+  //Widget node 0x20 - 3   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+
+  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x0204E213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204422E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+); // WhlHdaVerbTableAlc700
+
+#endif // _PCH_HDA_VERB_TABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
new file mode 100644
index 0000000000..89c780cc0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
+#define _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Ppi/SiPolicy.h>
+#include <PchHsioPtssTables.h>
+#include <IoExpander.h>
+
+#include <WhiskeylakeURvpId.h>
+
+extern const UINT8 mDqByteMapSklRvp3[2][6][2];
+extern const UINT8 mDqsMapCpu2DramSklRvp3[2][8];
+extern const UINT8 mSkylakeRvp3Spd110[];
+extern const UINT16 mSkylakeRvp3Spd110Size;
+extern HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[];
+extern UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size;
+extern HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[];
+extern UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size;
+
+extern GPIO_INIT_CONFIG mGpioTableLpddr3Rvp3UcmcDevice[];
+extern UINT16 mGpioTableLpddr3Rvp3UcmcDeviceSize;
+
+extern IO_EXPANDER_GPIO_CONFIG mGpioTableIoExpander[];
+extern UINT16 mGpioTableIoExpanderSize;
+extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3Touchpanel;
+extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3[];
+extern UINT16 mGpioTableLpDdr3Rvp3Size;
+
+#endif // _PEI_Whiskeylake_RVP3_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
new file mode 100644
index 0000000000..a6d48e906d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
@@ -0,0 +1,20 @@
+/** @file
+ Header file for DxePolicyBoardConfig library instance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_POLICY_BOARD_CONFIG_H_
+#define _DXE_POLICY_BOARD_CONFIG_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/DxePolicyBoardConfigLib.h>
+
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
new file mode 100644
index 0000000000..03c27f2a41
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
@@ -0,0 +1,23 @@
+/** @file
+ Header file for PeiPolicyBoardConfig library instance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_BOARD_CONFIG_H_
+#define _PEI_POLICY_BOARD_CONFIG_H_
+
+#include <PiPei.h>
+#include <ConfigBlock/MePeiConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
new file mode 100644
index 0000000000..01b3df984a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
@@ -0,0 +1,41 @@
+/** @file
+  Others Board's PCD function hook.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <GopConfigLib.h>
+
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+EFIAPI
+GopVbtSpecificUpdateNull (
+  IN CHILD_STRUCT **ChildStructPtr
+  )
+{
+  return;
+}
+
+//
+// for CFL U DDR4
+//
+VOID
+EFIAPI
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+)
+{
+  ChildStructPtr[1]->DeviceClass = DISPLAY_PORT_ONLY;
+  ChildStructPtr[1]->DVOPort     = DISPLAY_PORT_B;
+  ChildStructPtr[2]->DeviceClass = DISPLAY_PORT_HDMI_DVI_COMPATIBLE;
+  ChildStructPtr[2]->DVOPort     = DISPLAY_PORT_C;
+  ChildStructPtr[2]->AUX_Channel = AUX_CHANNEL_C;
+  ChildStructPtr[3]->DeviceClass = NO_DEVICE;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
new file mode 100644
index 0000000000..7ebf8f8fdc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
@@ -0,0 +1,137 @@
+/** @file
+  Implementation of BaseGpioCheckConflictLib.
+
+
+  Copyright (c) 2019, 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 <Private/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 Hob Check] Can't find Gpio Hob.\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, "[Hob 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 Check] Identified conflict on pad %a\n", GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad)));
+        }
+      }
+      //
+      // 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 UINT16                    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 how big size the Hob Data needs
+      //
+      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 {
+      GpioCheckConflictHobData[GpioIndex].GpioPad = GpioDefinition[Index].GpioPad;
+      GpioCheckConflictHobData[GpioIndex].GpioPadMode = GpioDefinition[Index].GpioConfig.PadMode;
+      GpioIndex++;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n"));
+  return;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
new file mode 100644
index 0000000000..178ce1a124
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
@@ -0,0 +1,37 @@
+/** @file
+  Implementation of BaseGpioCheckConflicLibNull.
+
+
+  Copyright (c) 2019, 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 UINT16                    GpioTableCount
+  )
+{
+  return;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
new file mode 100644
index 0000000000..24c6fa6277
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
@@ -0,0 +1,156 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PlatformHookLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <SystemAgent/Include/SaAccess.h>
+#include <SioRegs.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Register/PchRegsLpc.h>
+#include <PchAccess.h>
+
+#define LPC_SIO_INDEX_DEFAULT_PORT_2              0x2E
+#define LPC_SIO_DATA_DEFAULT_PORT_2               0x2F
+
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_0           0x87
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_1           0x01
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_2           0x55
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_3           0x55
+#define IT8628_EXIT_CONFIG                        0x2
+#define IT8628_CHIPID_BYTE1                       0x86
+#define IT8628_CHIPID_BYTE2                       0x28
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Value;
+} EFI_SIO_TABLE;
+
+//
+// IT8628
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioIt8628TableSerialPort[] = {
+  {0x023, 0x09}, // Clock Selection register
+  {0x007, 0x01}, // Com1 Logical Device Number select
+  {0x061, 0xF8}, // Serial Port 1 Base Address MSB Register
+  {0x060, 0x03}, // Serial Port 1 Base Address LSB Register
+  {0x070, 0x04}, // Serial Port 1 Interrupt Level Select
+  {0x030, 0x01}, // Serial Port 1 Activate
+  {0x007, 0x02}, // Com1 Logical Device Number select
+  {0x061, 0xF8}, // Serial Port 2 Base Address MSB Register
+  {0x060, 0x02}, // Serial Port 2 Base Address MSB Register
+  {0x070, 0x03}, // Serial Port 2 Interrupt Level Select
+  {0x030, 0x01}  // Serial Port 2 Activate
+};
+
+/**
+  Check whether the IT8628 SIO present on LPC. If yes, enable its serial ports
+**/
+STATIC
+VOID
+It8628SioSerialPortInit (
+  VOID
+  )
+{
+  UINT8   ChipId0;
+  UINT8   ChipId1;
+  UINT16  LpcIoDecondeRangeSet;
+  UINT16  LpcIoDecoodeSet;
+  UINT8   Index;
+  UINT64  LpcBaseAddr;
+
+  ChipId0              = 0;
+  ChipId1              = 0;
+  LpcIoDecondeRangeSet = 0;
+  LpcIoDecoodeSet      = 0;
+
+  //
+  // Enable I/O decoding for COM1 (3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh.
+  //
+  LpcBaseAddr = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPC,
+                  PCI_FUNCTION_NUMBER_PCH_LPC,
+                  0
+                  );
+
+  LpcIoDecondeRangeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOD);
+  LpcIoDecoodeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOE);
+  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOD), (LpcIoDecondeRangeSet | ((V_LPC_CFG_IOD_COMB_2F8 << 4) | V_LPC_CFG_IOD_COMA_3F8)));
+  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOE), (LpcIoDecoodeSet | (B_LPC_CFG_IOE_SE | B_LPC_CFG_IOE_CBE | B_LPC_CFG_IOE_CAE|B_LPC_CFG_IOE_KE)));
+
+  //
+  // Enter MB PnP Mode
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_0);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_1);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_2);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_3);
+
+  //
+  // Read Chip Id of SIO IT8628 (registers 0x20 and 0x21)
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x20);
+  ChipId0 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
+
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x21);
+  ChipId1 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
+
+  //
+  // Enable Serial Port 1, Port 2
+  //
+  if ((ChipId0 == IT8628_CHIPID_BYTE1) && (ChipId1 == IT8628_CHIPID_BYTE2)) {
+    for (Index = 0; Index < sizeof (mSioIt8628TableSerialPort) / sizeof (EFI_SIO_TABLE); Index++) {
+      IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Register);
+      IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Value);
+    }
+  }
+
+  //
+  // Exit MB PnP Mode
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
+  IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
+
+  return;
+}
+
+/**
+  Performs platform specific initialization required for the CPU to access
+  the hardware associated with a SerialPortLib instance.  This function does
+  not initialize the serial port hardware itself.  Instead, it initializes
+  hardware devices that are required for the CPU to access the serial port
+  hardware.  This function may be called more than once.
+
+  @retval RETURN_SUCCESS       The platform specific initialization succeeded.
+  @retval RETURN_DEVICE_ERROR  The platform specific initialization could not be completed.
+
+**/
+RETURN_STATUS
+EFIAPI
+PlatformHookSerialPortInitialize (
+  VOID
+  )
+{
+  //
+  // Enable I/O decoding for COM1(3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh, 4Eh/4Fh, 60h/64Fh and 62h/66h.
+  //
+  PchLpcIoDecodeRangesSet (PcdGet16 (PcdLpcIoDecodeRange));
+  PchLpcIoEnableDecodingSet (PcdGet16 (PchLpcIoEnableDecoding));
+
+  // Configure Sio IT8628
+  It8628SioSerialPortInit ();
+
+  return RETURN_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
new file mode 100644
index 0000000000..e7acbda03a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
@@ -0,0 +1,63 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+BoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  SiliconEnableAcpi (EnableSci);
+  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
+}
+
+EFI_STATUS
+EFIAPI
+BoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  SiliconDisableAcpi (DisableSci);
+  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
+}
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
new file mode 100644
index 0000000000..978e367cda
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
@@ -0,0 +1,82 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/MultiBoardAcpiSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  SiliconEnableAcpi (EnableSci);
+  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  SiliconDisableAcpi (DisableSci);
+  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
+}
+
+BOARD_ACPI_ENABLE_FUNC  mWhiskeylakeURvpBoardAcpiEnableFunc = {
+  WhiskeylakeURvpMultiBoardEnableAcpi,
+  WhiskeylakeURvpMultiBoardDisableAcpi,
+};
+
+EFI_STATUS
+EFIAPI
+SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor (
+  VOID
+  )
+{
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    return RegisterBoardAcpiEnableFunc (&mWhiskeylakeURvpBoardAcpiEnableFunc);
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
new file mode 100644
index 0000000000..9daceaa25c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
@@ -0,0 +1,170 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <PchAccess.h>
+#include <Library/MmPciLib.h>
+#include <Library/PmcLib.h>
+
+/**
+  Clear Port 80h
+
+  SMI handler to enable ACPI mode
+
+  Dispatched on reads from APM port with value EFI_ACPI_ENABLE_SW_SMI
+
+  Disables the SW SMI Timer.
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then enabled.
+
+  Clear SLP SMI status
+  Enable SLP SMI
+
+  Disable SW SMI Timer
+
+  Clear all ACPI event status and disable all ACPI events
+
+  Disable PM sources except power button
+  Clear status bits
+
+  Disable GPE0 sources
+  Clear status bits
+
+  Disable GPE1 sources
+  Clear status bits
+
+  Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+
+  Enable SCI
+**/
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+
+  UINT32                              OutputValue;
+  UINT32                              SmiEn;
+  UINT32                              SmiSts;
+  UINT32                              ULKMC;
+  UINTN                               LpcBaseAddress;
+  UINT16                              AcpiBaseAddr;
+  UINT32                              Pm1Cnt;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
+    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    0
+    );
+  //
+  // Get the ACPI Base Address
+  //
+  AcpiBaseAddr = PmcGetAcpiBase();
+  //
+  // BIOS must also ensure that CF9GR is cleared and locked before handing control to the
+  // OS in order to prevent the host from issuing global resets and resetting ME
+  //
+  // EDK2: To match PCCG current BIOS behavior, do not lock CF9 Global Reset
+  // MmioWrite32 (
+  //     PmcBaseAddress + R_PCH_PMC_ETR3),
+  //     PmInit);
+
+  //
+  // Clear Port 80h
+  //
+  IoWrite8 (0x80, 0);
+
+  //
+  // Disable SW SMI Timer and clean the status
+  //
+  SmiEn = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN);
+  SmiEn &= ~(B_ACPI_IO_SMI_EN_LEGACY_USB2 | B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB);
+  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN, SmiEn);
+
+  SmiSts = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS);
+  SmiSts |= B_ACPI_IO_SMI_EN_LEGACY_USB2 | B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB;
+  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS, SmiSts);
+
+  //
+  // Disable port 60/64 SMI trap if they are enabled
+  //
+  ULKMC = MmioRead32 (LpcBaseAddress + R_LPC_CFG_ULKMC) & ~(B_LPC_CFG_ULKMC_60REN | B_LPC_CFG_ULKMC_60WEN | B_LPC_CFG_ULKMC_64REN | B_LPC_CFG_ULKMC_64WEN | B_LPC_CFG_ULKMC_A20PASSEN);
+  MmioWrite32 (LpcBaseAddress + R_LPC_CFG_ULKMC, ULKMC);
+
+  //
+  // Disable PM sources except power button
+  //
+  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_EN, B_ACPI_IO_PM1_EN_PWRBTN);
+
+  //
+  // Clear PM status except Power Button status for RapidStart Resume
+  //
+  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_STS, 0xFEFF);
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+  //
+  IoWrite8 (R_RTC_IO_INDEX_ALT, R_RTC_IO_REGD);
+  IoWrite8 (R_RTC_IO_TARGET_ALT, 0x0);
+
+  //
+  // Write ALT_GPI_SMI_EN to disable GPI1 (SMC_EXTSMI#)
+  //
+  OutputValue = IoRead32 (AcpiBaseAddr + 0x38);
+  OutputValue = OutputValue & ~(1 << (UINTN) PcdGet8 (PcdSmcExtSmiBitPosition));
+  IoWrite32 (AcpiBaseAddr + 0x38, OutputValue);
+
+  //
+  // Enable SCI
+  //
+  if (EnableSci) {
+    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
+    Pm1Cnt |= B_ACPI_IO_PM1_CNT_SCI_EN;
+    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+
+  UINT16                              AcpiBaseAddr;
+  UINT32                              Pm1Cnt;
+
+  //
+  // Get the ACPI Base Address
+  //
+  AcpiBaseAddr = PmcGetAcpiBase();
+  //
+  // Disable SCI
+  //
+  if (DisableSci) {
+    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
+    Pm1Cnt &= ~B_ACPI_IO_PM1_CNT_SCI_EN;
+    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
new file mode 100644
index 0000000000..97a3fae51b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
@@ -0,0 +1,40 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  // enable additional board register
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  // enable additional board register
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
new file mode 100644
index 0000000000..7a2fed9904
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
@@ -0,0 +1,19 @@
+/** @file
+  Board's PCD function hook.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+EFI_STATUS
+PeiBoardSpecificInitPostMemNull (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
new file mode 100644
index 0000000000..5104329825
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
@@ -0,0 +1,27 @@
+/** @file
+  Source code for the board configuration init function in Post Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include "BoardFunc.h"
+
+/**
+  Board's PCD function hook init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardFunctionInit (
+  IN UINT16 BoardId
+)
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
new file mode 100644
index 0000000000..3a42a9bd03
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
@@ -0,0 +1,41 @@
+/** @file
+  Source code for the board configuration init function in Post Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <GopConfigLib.h>
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+GopVbtSpecificUpdateNull(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+//
+// for CFL U DDR4
+//
+VOID
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+/**
+  Board's PCD function hook init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardFunctionInitPreMem (
+  IN UINT16 BoardId
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
new file mode 100644
index 0000000000..458a73f892
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
@@ -0,0 +1,398 @@
+/** @file
+ Source code for the board PCH configuration Pcd init functions for Pre-Mmeory Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <PlatformBoardConfig.h>        // for USB 20 AFE & Root Port Clk Info.
+#include "GpioTableWhlUDdr4PreMem.h"
+#include <Library/BaseMemoryLib.h>
+
+/**
+  Board Root Port Clock Info configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+RootPortClkInfoInit (
+  IN UINT16 BoardId
+  )
+{
+  PCD64_BLOB                      *Clock;
+  UINT32                          Index;
+
+  Clock = AllocateZeroPool (16 * sizeof (PCD64_BLOB));
+  ASSERT (Clock != NULL);
+  if (Clock == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // The default clock assignment will be FREE_RUNNING, which corresponds to PchClockUsageUnspecified
+  // This is safe but power-consuming setting. If Platform code doesn't contain port-clock map for a given board,
+  // the clocks will keep on running anyway, allowing PCIe devices to operate. Downside is that clocks will
+  // continue to draw power. To prevent this, remember to provide port-clock map for every board.
+  //
+  for (Index = 0; Index < 16; Index++) {
+    Clock[Index].PcieClock.ClkReqSupported = TRUE;
+    Clock[Index].PcieClock.ClockUsage = FREE_RUNNING;
+  }
+
+  ///
+  /// Assign ClkReq signal to root port. (Base 0)
+  /// For LP, Set 0 - 5
+  /// For H,  Set 0 - 15
+  /// Note that if GbE is enabled, ClkReq assigned to GbE will not be available for Root Port.
+  ///
+  switch (BoardId) {
+    // CLKREQ
+    case BoardIdWhiskeyLakeRvp:
+      Clock[0].PcieClock.ClockUsage = PCIE_PCH + 1;
+      Clock[1].PcieClock.ClockUsage = PCIE_PCH + 8;
+      Clock[2].PcieClock.ClockUsage = LAN_CLOCK;
+      Clock[3].PcieClock.ClockUsage = PCIE_PCH + 13;
+      Clock[4].PcieClock.ClockUsage = PCIE_PCH + 4;
+      Clock[5].PcieClock.ClockUsage = PCIE_PCH + 14;
+      break;
+
+    default:
+      break;
+  }
+
+  PcdSet64S (PcdPcieClock0,  Clock[ 0].Blob);
+  PcdSet64S (PcdPcieClock1,  Clock[ 1].Blob);
+  PcdSet64S (PcdPcieClock2,  Clock[ 2].Blob);
+  PcdSet64S (PcdPcieClock3,  Clock[ 3].Blob);
+  PcdSet64S (PcdPcieClock4,  Clock[ 4].Blob);
+  PcdSet64S (PcdPcieClock5,  Clock[ 5].Blob);
+  PcdSet64S (PcdPcieClock6,  Clock[ 6].Blob);
+  PcdSet64S (PcdPcieClock7,  Clock[ 7].Blob);
+  PcdSet64S (PcdPcieClock8,  Clock[ 8].Blob);
+  PcdSet64S (PcdPcieClock9,  Clock[ 9].Blob);
+  PcdSet64S (PcdPcieClock10, Clock[10].Blob);
+  PcdSet64S (PcdPcieClock11, Clock[11].Blob);
+  PcdSet64S (PcdPcieClock12, Clock[12].Blob);
+  PcdSet64S (PcdPcieClock13, Clock[13].Blob);
+  PcdSet64S (PcdPcieClock14, Clock[14].Blob);
+  PcdSet64S (PcdPcieClock15, Clock[15].Blob);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board USB related configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+UsbConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  PCD32_BLOB *UsbPort20Afe;
+
+  UsbPort20Afe = AllocateZeroPool (PCH_MAX_USB2_PORTS * sizeof (PCD32_BLOB));
+  ASSERT (UsbPort20Afe != NULL);
+  if (UsbPort20Afe == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // USB2 AFE settings.
+  //
+  UsbPort20Afe[0].Info.Petxiset   = 7;
+  UsbPort20Afe[0].Info.Txiset     = 5;
+  UsbPort20Afe[0].Info.Predeemp   = 3;
+  UsbPort20Afe[0].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[1].Info.Petxiset   = 7;
+  UsbPort20Afe[1].Info.Txiset     = 5;
+  UsbPort20Afe[1].Info.Predeemp   = 3;
+  UsbPort20Afe[1].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[2].Info.Petxiset   = 7;
+  UsbPort20Afe[2].Info.Txiset     = 5;
+  UsbPort20Afe[2].Info.Predeemp   = 3;
+  UsbPort20Afe[2].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[3].Info.Petxiset   = 7;
+  UsbPort20Afe[3].Info.Txiset     = 5;
+  UsbPort20Afe[3].Info.Predeemp   = 3;
+  UsbPort20Afe[3].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[4].Info.Petxiset   = 7;
+  UsbPort20Afe[4].Info.Txiset     = 5;
+  UsbPort20Afe[4].Info.Predeemp   = 3;
+  UsbPort20Afe[4].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[5].Info.Petxiset   = 7;
+  UsbPort20Afe[5].Info.Txiset     = 5;
+  UsbPort20Afe[5].Info.Predeemp   = 3;
+  UsbPort20Afe[5].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[6].Info.Petxiset   = 7;
+  UsbPort20Afe[6].Info.Txiset     = 5;
+  UsbPort20Afe[6].Info.Predeemp   = 3;
+  UsbPort20Afe[6].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[7].Info.Petxiset   = 7;
+  UsbPort20Afe[7].Info.Txiset     = 5;
+  UsbPort20Afe[7].Info.Predeemp   = 3;
+  UsbPort20Afe[7].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[8].Info.Petxiset   = 7;
+  UsbPort20Afe[8].Info.Txiset     = 5;
+  UsbPort20Afe[8].Info.Predeemp   = 3;
+  UsbPort20Afe[8].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[9].Info.Petxiset   = 7;
+  UsbPort20Afe[9].Info.Txiset     = 5;
+  UsbPort20Afe[9].Info.Predeemp   = 3;
+  UsbPort20Afe[9].Info.Pehalfbit  = 0;
+
+  //
+  // USB Port Over Current Pin
+  //
+  PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinMax);
+
+  PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinMax);
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinSkip);
+
+      PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinSkip);
+
+      // USB2.0 AFE settings
+      UsbPort20Afe[0].Info.Petxiset   = 6;
+      UsbPort20Afe[0].Info.Txiset     = 0;
+      UsbPort20Afe[0].Info.Predeemp   = 3;
+      UsbPort20Afe[0].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[1].Info.Petxiset   = 6;
+      UsbPort20Afe[1].Info.Txiset     = 0;
+      UsbPort20Afe[1].Info.Predeemp   = 3;
+      UsbPort20Afe[1].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[2].Info.Petxiset   = 6;
+      UsbPort20Afe[2].Info.Txiset     = 0;
+      UsbPort20Afe[2].Info.Predeemp   = 3;
+      UsbPort20Afe[2].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[3].Info.Petxiset   = 6;
+      UsbPort20Afe[3].Info.Txiset     = 0;
+      UsbPort20Afe[3].Info.Predeemp   = 3;
+      UsbPort20Afe[3].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[4].Info.Petxiset   = 6;
+      UsbPort20Afe[4].Info.Txiset     = 0;
+      UsbPort20Afe[4].Info.Predeemp   = 3;
+      UsbPort20Afe[4].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[5].Info.Petxiset   = 6;
+      UsbPort20Afe[5].Info.Txiset     = 0;
+      UsbPort20Afe[5].Info.Predeemp   = 3;
+      UsbPort20Afe[5].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[6].Info.Petxiset   = 6;
+      UsbPort20Afe[6].Info.Txiset     = 0;
+      UsbPort20Afe[6].Info.Predeemp   = 3;
+      UsbPort20Afe[6].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[7].Info.Petxiset   = 6;
+      UsbPort20Afe[7].Info.Txiset     = 0;
+      UsbPort20Afe[7].Info.Predeemp   = 3;
+      UsbPort20Afe[7].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[8].Info.Petxiset   = 6;
+      UsbPort20Afe[8].Info.Txiset     = 0;
+      UsbPort20Afe[8].Info.Predeemp   = 3;
+      UsbPort20Afe[8].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[9].Info.Petxiset   = 6;
+      UsbPort20Afe[9].Info.Txiset     = 0;
+      UsbPort20Afe[9].Info.Predeemp   = 3;
+      UsbPort20Afe[9].Info.Pehalfbit  = 0;
+      break;
+  }
+
+  //
+  // Save USB2.0 AFE blobs
+  //
+  PcdSet32S (PcdUsb20Port0Afe,  UsbPort20Afe[ 0].Blob);
+  PcdSet32S (PcdUsb20Port1Afe,  UsbPort20Afe[ 1].Blob);
+  PcdSet32S (PcdUsb20Port2Afe,  UsbPort20Afe[ 2].Blob);
+  PcdSet32S (PcdUsb20Port3Afe,  UsbPort20Afe[ 3].Blob);
+  PcdSet32S (PcdUsb20Port4Afe,  UsbPort20Afe[ 4].Blob);
+  PcdSet32S (PcdUsb20Port5Afe,  UsbPort20Afe[ 5].Blob);
+  PcdSet32S (PcdUsb20Port6Afe,  UsbPort20Afe[ 6].Blob);
+  PcdSet32S (PcdUsb20Port7Afe,  UsbPort20Afe[ 7].Blob);
+  PcdSet32S (PcdUsb20Port8Afe,  UsbPort20Afe[ 8].Blob);
+  PcdSet32S (PcdUsb20Port9Afe,  UsbPort20Afe[ 9].Blob);
+  PcdSet32S (PcdUsb20Port10Afe, UsbPort20Afe[10].Blob);
+  PcdSet32S (PcdUsb20Port11Afe, UsbPort20Afe[11].Blob);
+  PcdSet32S (PcdUsb20Port12Afe, UsbPort20Afe[12].Blob);
+  PcdSet32S (PcdUsb20Port13Afe, UsbPort20Afe[13].Blob);
+  PcdSet32S (PcdUsb20Port14Afe, UsbPort20Afe[14].Blob);
+  PcdSet32S (PcdUsb20Port15Afe, UsbPort20Afe[15].Blob);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board GPIO Group Tier configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+GpioGroupTierInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // GPIO Group Tier
+  //
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdGpioGroupToGpeDw0, GPIO_CNL_LP_GROUP_GPP_G);
+      PcdSet32S (PcdGpioGroupToGpeDw1, GPIO_CNL_LP_GROUP_SPI);
+      PcdSet32S (PcdGpioGroupToGpeDw2, GPIO_CNL_LP_GROUP_GPP_E);
+      break;
+
+    default:
+      PcdSet32S (PcdGpioGroupToGpeDw0, 0);
+      PcdSet32S (PcdGpioGroupToGpeDw1, 0);
+      PcdSet32S (PcdGpioGroupToGpeDw2, 0);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  GPIO init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+GpioTablePreMemInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // GPIO Table Init.
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdBoardGpioTablePreMem, (UINTN) mGpioTableWhlUDdr4PreMem);
+      PcdSet16S (PcdBoardGpioTablePreMemSize, sizeof (mGpioTableWhlUDdr4PreMem) / sizeof (GPIO_INIT_CONFIG));
+      PcdSet32S (PcdBoardGpioTableWwanOnEarlyPreMem, (UINTN) mGpioTableWhlUDdr4WwanOnEarlyPreMem);
+      PcdSet16S (PcdBoardGpioTableWwanOnEarlyPreMemSize, sizeof (mGpioTableWhlUDdr4WwanOnEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
+      PcdSet32S (PcdBoardGpioTableWwanOffEarlyPreMem, (UINTN) mGpioTableWhlUDdr4WwanOffEarlyPreMem);
+      PcdSet16S (PcdBoardGpioTableWwanOffEarlyPreMemSize, sizeof (mGpioTableWhlUDdr4WwanOffEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PmConfig init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+PchPmConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update PmCofig policy: output voltage of VCCPRIMCORE RAIL when SLP_S0# is asserted based on board HW design
+  // 1) Discete VR or Non Premium PMIC: 0.75V (PcdSlpS0Vm075VSupport)
+  // 2) Premium PMIC: runtime control for voltage (PcdSlpS0VmRuntimeControl)
+  // Only applys to board with PCH-LP. Board with Discrete PCH doesn't need this setting.
+  //
+  switch (BoardId) {
+    // Discrete VR solution
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm075VSupport, TRUE);
+      break;
+
+    default:
+      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm075VSupport, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
new file mode 100644
index 0000000000..17f12c117d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
@@ -0,0 +1,282 @@
+/** @file
+ Source code for the board SA configuration Pcd init functions in Pre-Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include "BoardSaConfigPreMem.h"
+#include <PlatformBoardConfig.h>
+#include <Library/CpuPlatformLib.h>
+#include "SaPolicyCommon.h"
+
+//
+// Display DDI settings for WHL ERB
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mWhlErbRowDisplayDdiConfig[9] = {
+  DdiPortAEdp,     // DDI Port A Config : DdiPortADisabled = Disabled, DdiPortAEdp = eDP, DdiPortAMipiDsi = MIPI DSI
+  DdiHpdEnable,    // DDI Port B HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdEnable,    // DDI Port C HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdDisable,   // DDI Port D HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdDisable,   // DDI Port F HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiDdcEnable,    // DDI Port B DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDdcEnable,    // DDI Port C DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDdcEnable,    // DDI Port D DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDisable       // DDI Port F DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+};
+
+/**
+  MRC configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaMiscConfigInit (
+  IN UINT16         BoardId
+  )
+{
+  //
+  // UserBd
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // Assign UserBd to 5 which is assigned to MrcInputs->BoardType btUser4 for ULT platforms.
+      // This is required to skip Memory voltage programming based on GPIO's in MRC
+      //
+      PcdSet8S (PcdSaMiscUserBd, 5); // MrcBoardType btUser4 for ULT platform
+      break;
+
+    default:
+      // MiscPeiPreMemConfig.UserBd = 0 by default.
+      break;
+  }
+
+  PcdSet16S (PcdSaDdrFreqLimit, 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board Memory Init related configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+MrcConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  CPU_FAMILY    CpuFamilyId;
+  CPU_STEPPING  CpuStepping;
+
+  CpuFamilyId = GetCpuFamily();
+  CpuStepping = GetCpuStepping();
+
+  if (CpuFamilyId == EnumCpuCflDtHalo) {
+    PcdSetBoolS (PcdDualDimmPerChannelBoardType, TRUE);
+  } else {
+    PcdSetBoolS (PcdDualDimmPerChannelBoardType, FALSE);
+  }
+
+  //
+  // Example policy for DIMM slots implementation boards:
+  // 1. Assign Smbus address of DIMMs and SpdData will be updated later
+  //    by reading from DIMM SPD.
+  // 2. No need to apply hardcoded SpdData buffers here for such board.
+  //
+  //  Whiskey Lake U RVP has removable DIMM slots.
+  //  So assign all Smbus address of DIMMs and leave PcdMrcSpdData set to 0.
+  //   Example:
+  //   PcdMrcSpdData = 0
+  //   PcdMrcSpdDataSize = 0
+  //   PcdMrcSpdAddressTable0 = 0xA0
+  //   PcdMrcSpdAddressTable1 = 0xA2
+  //   PcdMrcSpdAddressTable2 = 0xA4
+  //   PcdMrcSpdAddressTable3 = 0xA6
+  //
+  //  If a board has soldered down memory. It should use the following settings.
+  //   Example:
+  //   PcdMrcSpdAddressTable0 = 0
+  //   PcdMrcSpdAddressTable1 = 0
+  //   PcdMrcSpdAddressTable2 = 0
+  //   PcdMrcSpdAddressTable3 = 0
+  //   PcdMrcSpdData = static data buffer
+  //   PcdMrcSpdDataSize = sizeof (static data buffer)
+  //
+
+  //
+  // SPD Address Table
+  //
+  PcdSet32S (PcdMrcSpdData, 0);
+  PcdSet16S (PcdMrcSpdDataSize, 0);
+  PcdSet8S (PcdMrcSpdAddressTable0, 0xA0);
+  PcdSet8S (PcdMrcSpdAddressTable1, 0xA2);
+  PcdSet8S (PcdMrcSpdAddressTable2, 0xA4);
+  PcdSet8S (PcdMrcSpdAddressTable3, 0xA6);
+
+  //
+  // DRAM SPD Data & related configuration
+  //
+  // Setting the PCD's to default value (WHL RVP3). It will be overriden to board specific settings below.
+  PcdSet32S (PcdMrcDqByteMap, (UINTN) mDqByteMapWhlUDdr4Rvp);
+  PcdSet16S (PcdMrcDqByteMapSize, sizeof (mDqByteMapWhlUDdr4Rvp));
+  PcdSet32S (PcdMrcDqsMapCpu2Dram, (UINTN) mDqsMapCpu2DramWhlUDdr4Rvp);
+  PcdSet16S (PcdMrcDqsMapCpu2DramSize, sizeof (mDqsMapCpu2DramWhlUDdr4Rvp));
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdMrcRcompResistor, (UINTN) RcompResistorCflUDdr4Interposer);
+      PcdSet32S (PcdMrcRcompTarget, (UINTN) RcompTargetWhlUDdr4Interposer);
+      PcdSetBoolS (PcdMrcDqPinsInterleavedControl, TRUE);
+      PcdSetBoolS (PcdMrcDqPinsInterleaved, TRUE);
+      break;
+
+    default:
+      break;
+  }
+
+  //
+  // CA Vref routing: board-dependent
+  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
+  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
+  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdMrcCaVrefConfig, 2); // DDR4 boards
+      break;
+
+    default:
+      PcdSet8S (PcdMrcCaVrefConfig, 0); // All DDR3L/LPDDR3/LPDDR4 boards
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board SA related GPIO configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaGpioConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update board's GPIO for PEG slot reset
+  //
+  PcdSetBoolS (PcdPegGpioResetControl, TRUE);
+  PcdSetBoolS (PcdPegGpioResetSupoort, FALSE);
+  PcdSet32S (PcdPeg0ResetGpioPad, 0);
+  PcdSetBoolS (PcdPeg0ResetGpioActive, FALSE);
+  PcdSet32S (PcdPeg3ResetGpioPad, 0);
+  PcdSetBoolS (PcdPeg3ResetGpioActive, FALSE);
+
+  //
+  // PCIE RTD3 GPIO
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S(PcdRootPortIndex, 4);
+      PcdSet8S (PcdPcie0GpioSupport, PchGpio);
+      PcdSet32S (PcdPcie0WakeGpioNo, 0);
+      PcdSet8S (PcdPcie0HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie0HoldRstGpioNo, GPIO_CNL_LP_GPP_C15);
+      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
+      PcdSet8S (PcdPcie0PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie0PwrEnableGpioNo, GPIO_CNL_LP_GPP_C14);
+      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie1WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie2WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
+      break;
+
+    default:
+      PcdSet8S(PcdRootPortIndex, 0xFF);
+      PcdSet8S  (PcdPcie0GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie0WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie0HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie0HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie0PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie0PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie1WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie2WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  SA Display DDI configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId       An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaDisplayConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update Display DDI Config
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdSaDisplayConfigTable, (UINTN) mWhlErbRowDisplayDdiConfig);
+      PcdSet16S (PcdSaDisplayConfigTableSize, sizeof (mWhlErbRowDisplayDdiConfig));
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..c52d4eceed
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
@@ -0,0 +1,40 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardInitBeforeSiliconInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..1283a4c80a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,106 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  );
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+BoardDetect (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDetect ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDebugInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+  VOID
+  )
+{
+  return WhiskeylakeURvpBoardBootModeDetect ();
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardInitBeforeMemoryInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..965110a5a5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
@@ -0,0 +1,41 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/MultiBoardInitSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  );
+
+BOARD_POST_MEM_INIT_FUNC  mWhiskeylakeURvpBoardInitFunc = {
+  WhiskeylakeURvpBoardInitBeforeSiliconInit,
+  NULL, // BoardInitAfterSiliconInit
+};
+
+EFI_STATUS
+EFIAPI
+PeiWhiskeylakeURvpMultiBoardInitLibConstructor (
+  VOID
+  )
+{
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    return RegisterBoardPostMemInit (&mWhiskeylakeURvpBoardInitFunc);
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..a2a6efe506
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
@@ -0,0 +1,83 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/MultiBoardInitSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDetect (
+  VOID
+  );
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  );
+
+BOARD_DETECT_FUNC  mWhiskeylakeURvpBoardDetectFunc = {
+  WhiskeylakeURvpMultiBoardDetect
+};
+
+BOARD_PRE_MEM_INIT_FUNC  mWhiskeylakeURvpBoardPreMemInitFunc = {
+  WhiskeylakeURvpBoardDebugInit,
+  WhiskeylakeURvpBoardBootModeDetect,
+  WhiskeylakeURvpBoardInitBeforeMemoryInit,
+  NULL, // BoardInitAfterMemoryInit
+  NULL, // BoardInitBeforeTempRamExit
+  NULL, // BoardInitAfterTempRamExit
+};
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDetect (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDetect ();
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    RegisterBoardPreMemInit (&mWhiskeylakeURvpBoardPreMemInitFunc);
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor (
+  VOID
+  )
+{
+  return RegisterBoardDetect (&mWhiskeylakeURvpBoardDetectFunc);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
new file mode 100644
index 0000000000..0adbed7f53
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
@@ -0,0 +1,63 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+
+#include "PeiWhiskeylakeURvpInitLib.h"
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>
+
+BOOLEAN
+WhiskeylakeURvp(
+  VOID
+  )
+{
+  return TRUE;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  )
+{
+  if (LibPcdGetSku () != 0) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((EFI_D_INFO, "WhiskeylakeURvpDetectionCallback\n"));
+
+  if (WhiskeylakeURvp()) {
+    LibPcdSetSku (BoardIdWhiskeyLakeRvp);
+
+    DEBUG ((DEBUG_INFO, "SKU_ID: 0x%x\n", LibPcdGetSku()));
+    ASSERT (LibPcdGetSku() == BoardIdWhiskeyLakeRvp);
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
new file mode 100644
index 0000000000..80b0a97612
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
@@ -0,0 +1,432 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+#include <IoExpander.h>
+#include "PeiWhiskeylakeURvpInitLib.h"
+#include "GpioTableDefault.h"
+#include "GpioTableWhlUDdr4.h"
+#include <AttemptUsbFirst.h>
+#include <PeiPlatformHookLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Library/PchInfoLib.h>
+#include <FirwmareConfigurations.h>
+
+EFI_STATUS
+BoardFunctionInit(
+  IN UINT16 BoardId
+);
+
+/**
+GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardGpioInit(
+  IN UINT16 BoardId
+)
+{
+  //
+  // GPIO Table Init.
+  //
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableWhlUDdr4_0);
+      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableWhlUDdr4_0) / sizeof(GPIO_INIT_CONFIG));
+      PcdSet32S(PcdBoardGpioTable2, (UINTN)mGpioTableWhlUDdr4);
+      PcdSet16S(PcdBoardGpioTable2Size, sizeof(mGpioTableWhlUDdr4) / sizeof(GPIO_INIT_CONFIG));
+      break;
+
+    default:
+      DEBUG((DEBUG_INFO, "For Unknown Board ID..Use Default GPIO Table...\n"));
+      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableDefault);
+      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableDefault) / sizeof(GPIO_INIT_CONFIG));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+Touch panel GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+TouchPanelGpioInit(
+  IN UINT16 BoardId
+)
+{
+  switch (BoardId) {
+    default:
+      PcdSet32S(PcdBoardGpioTableTouchPanel, 0);
+    break;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+Misc. init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInit(
+  IN UINT16 BoardId
+)
+{
+  PcdSetBoolS(PcdDebugUsbUartEnable, FALSE);
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+
+      PcdSetBoolS(PcdMipiCamGpioEnable, TRUE);
+      break;
+
+    default:
+      PcdSetBoolS(PcdMipiCamGpioEnable, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+Security GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardSecurityInit (
+  IN UINT16 BoardId
+)
+{
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+
+      // TPM interrupt connects to GPIO_CNL_H_GPP_A_7
+      PcdSet32S (PcdTpm2CurrentIrqNum, 0x1F);
+      break;
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+WhiskeyLake board configuration init function for PEI post memory phase.
+
+@param[in]  Content  pointer to the buffer contain init information for board init.
+
+@retval EFI_SUCCESS             The function completed successfully.
+@retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+BoardConfigInit(
+  VOID
+)
+{
+  EFI_STATUS  Status;
+  UINT16      BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = BoardGpioInit(BoardId);
+  Status = TouchPanelGpioInit(BoardId);
+  Status = HdaVerbTableInit(BoardId);
+  Status = BoardMiscInit(BoardId);
+  Status = BoardFunctionInit(BoardId);
+  Status = BoardSecurityInit(BoardId);
+
+  return EFI_SUCCESS;
+}
+
+//@todo Review this functionality and if it is required for WHL SDS
+/**
+Create the HOB for hotkey status for 'Attempt USB First' feature
+
+@retval  EFI_SUCCESS  HOB Creating successful.
+@retval  Others       HOB Creating failed.
+**/
+EFI_STATUS
+CreateAttemptUsbFirstHotkeyInfoHob(
+  VOID
+)
+{
+  EFI_STATUS                     Status;
+  ATTEMPT_USB_FIRST_HOTKEY_INFO  AttemptUsbFirstHotkeyInfo;
+
+  Status = EFI_SUCCESS;
+
+  ZeroMem(
+    &AttemptUsbFirstHotkeyInfo,
+    sizeof(AttemptUsbFirstHotkeyInfo)
+  );
+
+  AttemptUsbFirstHotkeyInfo.RevisonId = 0;
+  AttemptUsbFirstHotkeyInfo.HotkeyTriggered = FALSE;
+
+  ///
+  /// Build HOB for Attempt USB First feature
+  ///
+  BuildGuidDataHob(
+    &gAttemptUsbFirstHotkeyInfoHobGuid,
+    &(AttemptUsbFirstHotkeyInfo),
+    sizeof(ATTEMPT_USB_FIRST_HOTKEY_INFO)
+  );
+
+  return Status;
+}
+
+/**
+Search and identify the physical address of a
+file module inside the FW_BINARIES_FV_SIGNED FV
+
+@retval  EFI_SUCCESS  If address has been found
+@retval  Others       If address has not been found
+**/
+EFI_STATUS
+FindModuleInFlash2(
+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
+  IN EFI_GUID                   *GuidPtr,
+  IN OUT UINT32                 *ModulePtr,
+  IN OUT UINT32                 *ModuleSize
+)
+{
+  EFI_FFS_FILE_HEADER        *FfsHeader;
+  EFI_FV_FILE_INFO           FileInfo;
+  EFI_PEI_FILE_HANDLE        FileHandle;
+  EFI_COMMON_SECTION_HEADER  *SectionHeader;
+  VOID                       *FileBuffer;
+  EFI_STATUS                 Status;
+
+  FfsHeader = NULL;
+  FileHandle = NULL;
+  SectionHeader = NULL;
+  FileBuffer = NULL;
+
+  while (TRUE) {
+    //
+    // Locate FV_IMAGE file type in the FW_BINARIES_FV_SIGNED firmware volume
+    //
+    Status = PeiServicesFfsFindNextFile(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, FvHeader, &FileHandle);
+    if (EFI_ERROR(Status)) {
+      // unable to find FV_IMAGE file in this FV
+      break;
+    }
+
+    FfsHeader = (EFI_FFS_FILE_HEADER*)FileHandle;
+    DEBUG((DEBUG_INFO, "FfsHeader 0x%X:\n", FfsHeader));
+    DEBUG((DEBUG_INFO, " Name = 0x%g\n", &FfsHeader->Name));
+    DEBUG((DEBUG_INFO, " Type = 0x%X\n", FfsHeader->Type));
+    if (IS_FFS_FILE2(FfsHeader)) {
+      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE2_SIZE(FfsHeader)));
+    }
+    else {
+      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE_SIZE(FfsHeader)));
+    }
+
+    //
+    // Locate FW_BINARIES_FV FV_IMAGE Section
+    //
+    Status = PeiServicesFfsFindSectionData(EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FileHandle, &FileBuffer);
+    if (EFI_ERROR(Status)) {
+      // continue to search for the next FV_IMAGE file
+      DEBUG((DEBUG_INFO, "FW_BINARIES_FV section not found. Status = %r\n", Status));
+      continue;
+    }
+
+    SectionHeader = (EFI_COMMON_SECTION_HEADER *)FileBuffer;
+    DEBUG((DEBUG_INFO, "GUIDED SectionHeader 0x%X:\n",
+    (UINT32)(UINT8 *)SectionHeader));
+    if (IS_SECTION2(SectionHeader)) {
+      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
+        &((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->SectionDefinitionGuid));
+      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
+        ((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->DataOffset));
+    }
+    else {
+      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
+        &((EFI_GUID_DEFINED_SECTION *)SectionHeader)->SectionDefinitionGuid));
+      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
+        ((EFI_GUID_DEFINED_SECTION *)SectionHeader)->DataOffset));
+    }
+    DEBUG((DEBUG_INFO, " Type      = 0x%X\n", SectionHeader->Type));
+
+    //
+    // Locate Firmware File System file within Firmware Volume
+    //
+    Status = PeiServicesFfsFindFileByName(GuidPtr, FileBuffer, (VOID **)&FfsHeader);
+    if (EFI_ERROR(Status)) {
+      // continue to search for the next FV_IMAGE file
+      DEBUG((DEBUG_INFO, "Module not found. Status = %r\n", Status));
+      continue;
+    }
+
+    *ModulePtr = (UINT32)((UINT8 *)FfsHeader + sizeof(EFI_FFS_FILE_HEADER));
+
+    //
+    // Get File Information
+    //
+    Status = PeiServicesFfsGetFileInfo(FfsHeader, &FileInfo);
+    if (!EFI_ERROR(Status)) {
+      *ModuleSize = (UINT32)FileInfo.BufferSize;
+      DEBUG((DEBUG_INFO, "Module {0x%g} found at = 0x%X, Size = 0x%X\n",
+        &FfsHeader->Name, *ModulePtr, *ModuleSize));
+      return Status;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+Get the ChipsetInit Binary pointer.
+
+@retval EFI_SUCCESS               - ChipsetInit Binary found.
+@retval EFI_NOT_FOUND             - ChipsetInit Binary not found.
+**/
+EFI_STATUS
+UpdateChipsetInitPtr(
+  VOID
+)
+{
+  EFI_STATUS                    Status;
+  PCH_STEPPING                  PchStep;
+  EFI_FIRMWARE_VOLUME_HEADER    *FvHeader;
+  EFI_GUID                      *ChipsetInitBinaryGuidPtr;
+  SI_POLICY_PPI                 *SiPolicyPpi;
+  PCH_HSIO_CONFIG               *HsioConfig;
+  UINT32                        ModuleAddr;
+  UINT32                        ModuleSize;
+
+  ModuleAddr = 0;
+  ModuleSize = 0;
+  PchStep = PchStepping();
+
+  Status = PeiServicesLocatePpi(
+    &gSiPolicyPpiGuid,
+    0,
+    NULL,
+    (VOID **)&SiPolicyPpi
+  );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gHsioConfigGuid, (VOID *)&HsioConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  ChipsetInitBinaryGuidPtr = NULL;
+  if (IsPchLp()) {
+    switch (PchStep) {
+      case PCH_D0:
+      case PCH_D1:
+        ChipsetInitBinaryGuidPtr = &gCnlPchLpChipsetInitTableDxGuid;
+        DEBUG((DEBUG_INFO, "Using CnlPchLpChipsetInitTable_Dx table \n"));
+        break;
+      default:
+        return EFI_NOT_FOUND;
+    }
+  }
+  else {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Locate Firmware Volume header
+  //
+  //	FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)GetFvBinaryBase();
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FixedPcdGet32(PcdFlashFvPostMemoryBase);
+  Status = FindModuleInFlash2(FvHeader, ChipsetInitBinaryGuidPtr, &ModuleAddr, &ModuleSize);
+  //
+  // Get ChipsetInit Binary Pointer
+  //
+  HsioConfig->ChipsetInitBinPtr = ModuleAddr;
+
+  //
+  // Get File Size
+  //
+  HsioConfig->ChipsetInitBinLen = ModuleSize;
+
+  DEBUG((DEBUG_INFO, "ChipsetInit Binary Location: %x\n", HsioConfig->ChipsetInitBinPtr));
+  DEBUG((DEBUG_INFO, "ChipsetInit Binary Size: %x\n", HsioConfig->ChipsetInitBinLen));
+
+  return Status;
+}
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  UINT8                            FwConfig;
+
+  BoardConfigInit();
+  //
+  // Configure GPIO and SIO
+  //
+  Status = BoardInit();
+  ASSERT_EFI_ERROR(Status);
+
+  FwConfig = FwConfigProduction;
+  PeiPolicyInit(FwConfig);
+
+  //
+  // Create USB Boot First hotkey information HOB
+  //
+  CreateAttemptUsbFirstHotkeyInfoHob();
+
+  //
+  // Initializing Platform Specific Programming
+  //
+  Status = PlatformSpecificInit();
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Update ChipsetInitPtr
+  //
+  Status = UpdateChipsetInitPtr();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
new file mode 100644
index 0000000000..519a5be216
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
@@ -0,0 +1,636 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+
+#include "PeiWhiskeylakeURvpInitLib.h"
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Library/PchResetLib.h>
+#include <Register/PchRegsLpc.h>
+#include <Library/StallPpiLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Ppi/Reset.h>
+#include <PlatformBoardConfig.h>
+#include <GpioPinsCnlLp.h>
+#include <Library/PmcLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PeiPlatformHookLib.h>
+#include <FirwmareConfigurations.h>
+#include <Guid/TcoWdtHob.h>
+#include <Library/OcWdtLib.h>
+
+///
+/// Reset Generator I/O Port
+///
+#define RESET_GENERATOR_PORT           0xCF9
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS    BaseAddress;
+  UINT64                  Length;
+} MEMORY_MAP;
+
+//
+// Reference RCOMP resistors on motherboard - for WHL RVP1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
+
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for WHL RVP1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
+
+GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_MAP MmioMap[] = {
+  { FixedPcdGet64(PcdApicLocalAddress), FixedPcdGet32(PcdApicLocalMmioSize) },
+  { FixedPcdGet64(PcdMchBaseAddress), FixedPcdGet32(PcdMchMmioSize) },
+  { FixedPcdGet64(PcdDmiBaseAddress), FixedPcdGet32(PcdDmiMmioSize) },
+  { FixedPcdGet64(PcdEpBaseAddress), FixedPcdGet32(PcdEpMmioSize) },
+  { FixedPcdGet64(PcdGdxcBaseAddress), FixedPcdGet32(PcdGdxcMmioSize) }
+};
+
+EFI_STATUS
+MrcConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+SaGpioConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+  SaMiscConfigInit(
+IN UINT16         BoardId
+);
+
+EFI_STATUS
+  RootPortClkInfoInit(
+IN UINT16 BoardId
+);
+
+EFI_STATUS
+  UsbConfigInit(
+IN UINT16 BoardId
+);
+
+EFI_STATUS
+GpioGroupTierInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+GpioTablePreMemInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+PchPmConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+SaDisplayConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+BoardFunctionInitPreMem(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemCallBack(
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN VOID                        *Ppi
+);
+
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotify(
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN VOID                        *Ppi
+);
+
+EFI_STATUS
+EFIAPI
+PchReset(
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+);
+
+static EFI_PEI_RESET_PPI mResetPpi = {
+  PchReset
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPreMemPpiList[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiResetPpiGuid,
+    &mResetPpi
+  }
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mPreMemNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiReadOnlyVariable2PpiGuid,
+  (EFI_PEIM_NOTIFY_ENTRY_POINT)PlatformInitPreMemCallBack
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mMemDiscoveredNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiMemoryDiscoveredPpiGuid,
+  (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotify
+};
+
+/**
+Board misc init function for PEI pre-memory phase.
+
+@param[in]  BoardId   An unsigned integer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInitPreMem(
+  IN UINT16 BoardId
+)
+{
+  PCD64_BLOB PcdData;
+
+  //
+  // RecoveryMode GPIO
+  //
+  PcdData.Blob = 0;
+  PcdData.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdData.BoardGpioConfig.Type = BoardGpioTypePch;
+      PcdData.BoardGpioConfig.u.Pin = GPIO_CNL_LP_GPP_F10;
+    break;
+
+    default:
+      break;
+  }
+
+  //
+  // Configure WWAN Full Card Power Off and reset pins
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // According to board default settings, GPP_D16 is used to enable/disable modem
+      // power. An alternative way to contol modem power is to toggle FCP_OFF via GPP_D13
+      // but board rework is required.
+      //
+      PcdSet32S(PcdWwanFullCardPowerOffGpio, GPIO_CNL_LP_GPP_D16);
+      PcdSet32S(PcdWwanBbrstGpio, GPIO_CNL_LP_GPP_F1);
+      PcdSet32S(PcdWwanPerstGpio, GPIO_CNL_LP_GPP_E15);
+      PcdSet8S(PcdWwanPerstGpioPolarity, 1);
+      break;
+
+    default:
+      break;
+  }
+
+  PcdSet64S(PcdRecoveryModeGpio, PcdData.Blob);
+
+  //
+  // Pc8374SioKbc Present
+  //
+  PcdSetBoolS(PcdPc8374SioKbcPresent, FALSE);
+
+  return EFI_SUCCESS;
+}
+
+//@todo it should be moved to Si Pkg.
+/**
+Early Platform PCH initialization
+**/
+VOID
+EarlyPlatformPchInit(
+  VOID
+)
+{
+  UINT8        Data8;
+  UINT8        TcoRebootHappened;
+  TCO_WDT_HOB  *TcoWdtHobPtr;
+  EFI_STATUS   Status;
+
+  ///
+  /// Read the Second TO status bit
+  ///
+  Data8 = IoRead8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS);
+  if ((Data8 & B_TCO_IO_TCO2_STS_SECOND_TO) == B_TCO_IO_TCO2_STS_SECOND_TO) {
+    TcoRebootHappened = 1;
+    DEBUG((DEBUG_INFO, "PlatformInitPreMem - TCO Second TO status bit is set. This might be a TCO reboot\n"));
+  }
+  else {
+    TcoRebootHappened = 0;
+  }
+
+  ///
+  /// Create HOB
+  ///
+  Status = PeiServicesCreateHob(EFI_HOB_TYPE_GUID_EXTENSION, sizeof(TCO_WDT_HOB), (VOID **)&TcoWdtHobPtr);
+  if (!EFI_ERROR(Status)) {
+    TcoWdtHobPtr->Header.Name = gTcoWdtHobGuid;
+    TcoWdtHobPtr->TcoRebootHappened = TcoRebootHappened;
+  }
+
+  ///
+  /// Clear the Second TO status bit
+  ///
+  IoWrite8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS, B_TCO_IO_TCO2_STS_SECOND_TO);
+}
+
+/**
+Board init function for PEI pre-memory phase.
+
+@param  Content  pointer to the buffer contain init information for board init.
+
+@retval EFI_SUCCESS             The function completed successfully.
+@retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+BoardConfigInitPreMem(
+  VOID
+)
+{
+  EFI_STATUS Status;
+  UINT16 BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = MrcConfigInit(BoardId);
+  Status = SaGpioConfigInit(BoardId);
+  Status = SaMiscConfigInit(BoardId);
+  Status = RootPortClkInfoInit(BoardId);
+  Status = UsbConfigInit(BoardId);
+  Status = GpioGroupTierInit(BoardId);
+  Status = GpioTablePreMemInit(BoardId);
+  Status = PchPmConfigInit(BoardId);
+  Status = BoardMiscInitPreMem(BoardId);
+  Status = SaDisplayConfigInit(BoardId);
+  Status = BoardFunctionInitPreMem(BoardId);
+
+  return EFI_SUCCESS;
+}
+
+/**
+This function handles PlatformInit task after PeiReadOnlyVariable2 PPI produced
+
+@param[in]  PeiServices   Pointer to PEI Services Table.
+@param[in]  NotifyDesc    Pointer to the descriptor for the Notification event that
+                          caused this function to execute.
+@param[in]  Ppi           Pointer to the PPI data associated with this function.
+
+@retval     EFI_SUCCESS  The function completes successfully
+@retval     others
+**/
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemCallBack(
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+)
+{
+  EFI_STATUS                        Status;
+  UINT16                            ABase;
+  UINT8                             FwConfig;
+  UINT8                             SynchDelay;
+
+  //
+  // Init Board Config Pcd.
+  //
+  BoardConfigInitPreMem();
+
+  DEBUG((DEBUG_ERROR, "Fail to get System Configuration and set the configuration to production mode!\n"));
+  FwConfig = FwConfigProduction;
+  SynchDelay = 0;
+  PcdSetBoolS(PcdPcieWwanEnable, FALSE);
+  PcdSetBoolS(PcdWwanResetWorkaround, FALSE);
+
+  //
+  // Early Board Configuration before memory is ready.
+  //
+  Status = BoardInitEarlyPreMem();
+  ASSERT_EFI_ERROR(Status);
+
+  ///
+  /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
+  /// clear unexpected reset status and enforce expiration. This is to inform Firmware
+  /// which has no access to unexpected reset status bit, that something went wrong.
+  ///
+  OcWdtResetCheck();
+
+  Status = OcWdtInit();
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Initialize Intel PEI Platform Policy
+  //
+  PeiPolicyInitPreMem(FwConfig);
+
+  ///
+  /// Configure GPIO and SIO
+  ///
+  Status = BoardInitPreMem();
+  ASSERT_EFI_ERROR(Status);
+
+  ABase = PmcGetAcpiBase();
+
+  ///
+  /// Clear all pending SMI. On S3 clear power button enable so it will not generate an SMI.
+  ///
+  IoWrite16(ABase + R_ACPI_IO_PM1_EN, 0);
+  IoWrite32(ABase + R_ACPI_IO_GPE0_EN_127_96, 0);
+
+  ///
+  /// Install Pre Memory PPIs
+  ///
+  Status = PeiServicesInstallPpi(&mPreMemPpiList[0]);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
+/**
+Provide hard reset PPI service.
+To generate full hard reset, write 0x0E to PCH RESET_GENERATOR_PORT (0xCF9).
+
+@param[in]  PeiServices       General purpose services available to every PEIM.
+
+@retval     Not return        System reset occured.
+@retval     EFI_DEVICE_ERROR  Device error, could not reset the system.
+**/
+EFI_STATUS
+EFIAPI
+PchReset(
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+)
+{
+  DEBUG((DEBUG_INFO, "Perform Cold Reset\n"));
+  IoWrite8(RESET_GENERATOR_PORT, 0x0E);
+
+  CpuDeadLoop();
+
+  ///
+  /// System reset occured, should never reach at this line.
+  ///
+  ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
+
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+Install Firmware Volume Hob's once there is main memory
+
+@param[in]  PeiServices       General purpose services available to every PEIM.
+@param[in]  NotifyDescriptor  Notify that this module published.
+@param[in]  Ppi               PPI that was installed.
+
+@retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotify(
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+)
+{
+  EFI_STATUS                    Status;
+  EFI_BOOT_MODE                 BootMode;
+  UINTN                         Index;
+  UINT8                         PhysicalAddressBits;
+  UINT32                        RegEax;
+  MEMORY_MAP                    PcieMmioMap;
+
+  Index = 0;
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  AsmCpuid(0x80000000, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= 0x80000008) {
+    AsmCpuid(0x80000008, &RegEax, NULL, NULL, NULL);
+    PhysicalAddressBits = (UINT8)RegEax;
+  }
+  else {
+    PhysicalAddressBits = 36;
+  }
+
+  ///
+  /// Create a CPU hand-off information
+  ///
+  BuildCpuHob(PhysicalAddressBits, 16);
+
+  ///
+  /// Build Memory Mapped IO Resource which is used to build E820 Table in LegacyBios.
+  ///
+  PcieMmioMap.BaseAddress = FixedPcdGet64(PcdPciExpressBaseAddress);
+  PcieMmioMap.Length = PcdGet32(PcdPciExpressRegionLength);
+
+  BuildResourceDescriptorHob(
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    PcieMmioMap.BaseAddress,
+    PcieMmioMap.Length
+  );
+  BuildMemoryAllocationHob(
+    PcieMmioMap.BaseAddress,
+    PcieMmioMap.Length,
+    EfiMemoryMappedIO
+  );
+  for (Index = 0; Index < sizeof(MmioMap) / (sizeof(MEMORY_MAP)); Index++) {
+    BuildResourceDescriptorHob(
+      EFI_RESOURCE_MEMORY_MAPPED_IO,
+      (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+      MmioMap[Index].BaseAddress,
+      MmioMap[Index].Length
+    );
+    BuildMemoryAllocationHob(
+      MmioMap[Index].BaseAddress,
+      MmioMap[Index].Length,
+      EfiMemoryMappedIO
+    );
+  }
+
+  //
+  // Report resource HOB for flash FV
+  //
+  BuildResourceDescriptorHob(
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
+  );
+  BuildMemoryAllocationHob(
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize),
+    EfiMemoryMappedIO
+  );
+
+  BuildFvHob(
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
+  );
+
+  return Status;
+}
+
+
+/**
+  Board configuration init function for PEI pre-memory phase.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpInitPreMem (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  ///
+  /// Install Stall PPI
+  ///
+  Status = InstallStallPpi();
+  ASSERT_EFI_ERROR(Status);
+
+  ///@todo it should be moved to Si Pkg.
+  ///
+  /// Do Early PCH init
+  ///
+  EarlyPlatformPchInit();
+
+  //
+  // Install PCH RESET PPI and EFI RESET2 PeiService
+  //
+  Status = PchInitializeReset();
+  ASSERT_EFI_ERROR(Status);
+
+  ///
+  /// Performing PlatformInitPreMemCallBack after PeiReadOnlyVariable2 PPI produced
+  ///
+  Status = PeiServicesNotifyPpi(&mPreMemNotifyList);
+
+  ///
+  /// After code reorangized, memorycallback will run because the PPI is already
+  /// installed when code run to here, it is supposed that the InstallEfiMemory is
+  /// done before.
+  ///
+  Status = PeiServicesNotifyPpi(&mMemDiscoveredNotifyList);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure GPIO and SIO before memory ready
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpInitPreMem ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  )
+{
+  UINT64                            LpcBaseAddress;
+
+  ///
+  /// LPC I/O Configuration
+  ///
+  PchLpcIoDecodeRangesSet(
+    (V_LPC_CFG_IOD_LPT_378 << N_LPC_CFG_IOD_LPT) |
+    (V_LPC_CFG_IOD_COMB_3E8 << N_LPC_CFG_IOD_COMB) |
+    (V_LPC_CFG_IOD_COMA_3F8 << N_LPC_CFG_IOD_COMA)
+  );
+
+  PchLpcIoEnableDecodingSet(
+    B_LPC_CFG_IOE_ME2 |
+    B_LPC_CFG_IOE_SE |
+    B_LPC_CFG_IOE_ME1 |
+    B_LPC_CFG_IOE_KE |
+    B_LPC_CFG_IOE_HGE |
+    B_LPC_CFG_IOE_LGE |
+    B_LPC_CFG_IOE_FDE |
+    B_LPC_CFG_IOE_PPE |
+    B_LPC_CFG_IOE_CBE |
+    B_LPC_CFG_IOE_CAE
+  );
+
+  ///
+  /// Enable LPC IO decode for EC access
+  ///
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
+    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    0
+  );
+
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
new file mode 100644
index 0000000000..8d8ca835bc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
@@ -0,0 +1,32 @@
+/** @file
+    WhiskeylakeURvp HSIO PTSS H File
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+#define WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+
+#include <PchHsioPtssTables.h>
+
+#ifndef HSIO_PTSS_TABLE_SIZE
+#define HSIO_PTSS_TABLE_SIZE(A) A##_Size = sizeof (A) / sizeof (HSIO_PTSS_TABLES)
+#endif
+
+//BoardId WhiskeylakeURvp
+HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[] = {
+  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0}
+};
+
+UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size = sizeof(PchLpHsioPtss_Cx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
+
+HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[] = {
+  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0},
+};
+
+UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size = sizeof(PchLpHsioPtss_Bx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
+
+#endif // WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
new file mode 100644
index 0000000000..d2c26eb163
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel DXE SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxePolicyBoardConfig.h"
+
+/**
+  This function performs DXE SA Policy update by board configuration.
+
+  @param[in, out] DxeSaPolicy    DXE SA Policy
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicyBoardConfig (
+  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
+  )
+{
+  EFI_STATUS                         Status;
+  MEMORY_DXE_CONFIG                  *MemoryDxeConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in DXE\n"));
+
+  Status = GetConfigBlock ((VOID *)DxeSaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
new file mode 100644
index 0000000000..c495a3a401
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
@@ -0,0 +1,299 @@
+/** @file
+  PEI Library Functions. Initialize GPIOs
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <PeiPlatformHookLib.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <PchAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Library/PchInfoLib.h>
+#include <Library/CnviLib.h>
+#include <SioRegs.h>
+#include <PlatformBoardConfig.h>
+#include <Library/PchPcrLib.h>
+#include <Library/GpioCheckConflictLib.h>
+
+#define SIO_RUNTIME_REG_BASE_ADDRESS                          0x0680
+
+#define RECOVERY_MODE_GPIO_PIN                    0                    // Platform specific @todo use PCD
+
+#define MANUFACTURE_MODE_GPIO_PIN                 0                    // Platform specific @todo use PCD
+
+/**
+  Configures GPIO
+
+  @param[in]  GpioTable       Point to Platform Gpio table
+  @param[in]  GpioTableCount  Number of Gpio table entries
+
+**/
+VOID
+ConfigureGpio (
+  IN GPIO_INIT_CONFIG                 *GpioDefinition,
+  IN UINT16                           GpioTableCount
+  )
+{
+  DEBUG ((DEBUG_INFO, "ConfigureGpio() Start\n"));
+
+
+  CreateGpioCheckConflictHob (GpioDefinition, GpioTableCount);
+
+
+  GpioConfigurePads (GpioTableCount, GpioDefinition);
+
+  DEBUG ((DEBUG_INFO, "ConfigureGpio() End\n"));
+}
+
+/**
+  Configure GPIO group GPE tier.
+
+  @retval     none.
+**/
+VOID
+GpioGroupTierInitHook(
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook Start\n"));
+
+  if (PcdGet32 (PcdGpioGroupToGpeDw0)) {
+    GpioSetGroupToGpeDwX (PcdGet32 (PcdGpioGroupToGpeDw0),
+                          PcdGet32 (PcdGpioGroupToGpeDw1),
+                          PcdGet32 (PcdGpioGroupToGpeDw2));
+  }
+  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook End\n"));
+}
+
+/**
+  Configure single GPIO pad for touchpanel interrupt
+**/
+VOID
+TouchpanelGpioInit (
+  VOID
+  )
+{
+  GPIO_INIT_CONFIG*     TouchpanelPad;
+  GPIO_PAD_OWN          PadOwnVal;
+
+  PadOwnVal = 0;
+  TouchpanelPad = (VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableTouchPanel);
+  if (TouchpanelPad != NULL) {
+    GpioGetPadOwnership (TouchpanelPad->GpioPad, &PadOwnVal);
+    if (PadOwnVal == GpioPadOwnHost) {
+      GpioConfigurePads (1, TouchpanelPad);
+    }
+  }
+}
+
+/**
+  Configure GPIO Before Memory is not ready.
+
+**/
+VOID
+GpioInitPreMem (
+  VOID
+  )
+{
+  if (PcdGet32 (PcdBoardGpioTablePreMem) != 0 && PcdGet16 (PcdBoardGpioTablePreMemSize) != 0) {
+    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTablePreMem), (UINTN) PcdGet16 (PcdBoardGpioTablePreMemSize));
+  }
+}
+
+/**
+  Basic GPIO configuration before memory is ready
+
+**/
+VOID
+GpioInitEarlyPreMem (
+  VOID
+  )
+{
+  GPIO_CONFIG                     BbrstConfig;
+  UINT32                          WwanBbrstGpio;
+
+  WwanBbrstGpio = PcdGet32 (PcdWwanBbrstGpio);
+
+  if (WwanBbrstGpio) {
+    //
+    // BIOS needs to put modem in OFF state for the two scenarios below.
+    // 1. Modem RESET# is not asserted via PLTRST# in the previous sleep state
+    // 2. Modem is disabled via setup option
+    //
+    GpioGetPadConfig (WwanBbrstGpio, &BbrstConfig);
+    if ((PcdGetBool (PcdPcieWwanEnable) == FALSE) ||
+        (PcdGetBool (PcdWwanResetWorkaround) == TRUE &&
+        BbrstConfig.Direction == GpioDirOut &&
+        BbrstConfig.OutputState == GpioOutHigh)) {
+      //
+      // Assert FULL_CARD_POWER_OFF#, RESET# and PERST# GPIOs
+      //
+      if (PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize) != 0) {
+        ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize));
+      }
+      if (PcdGetBool (PcdPcieWwanEnable) == TRUE && PcdGetBool (PcdWwanResetWorkaround) == TRUE) {
+        MicroSecondDelay (1 * 1000); // Delay by 1ms
+      }
+    }
+
+    //
+    // Turn ON modem power and de-assert RESET# and PERST# GPIOs
+    //
+    if (PcdGetBool (PcdPcieWwanEnable) == TRUE) {
+      if (PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize) != 0) {
+        ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize));
+      }
+    }
+  }
+}
+
+/**
+  Configure GPIO
+
+**/
+VOID
+GpioInit (
+  VOID
+  )
+{
+  ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable), (UINTN) PcdGet16 (PcdBoardGpioTableSize));
+
+  if (PcdGet32 (PcdBoardGpioTable2)) {
+    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable2), (UINTN) PcdGet16 (PcdBoardGpioTable2Size));
+  }
+
+  TouchpanelGpioInit();
+
+  //
+  // Lock pads after initializing platform GPIO.
+  // Pads which were requested to be unlocked during configuration
+  // will not be locked.
+  //
+  GpioLockPads ();
+
+  return;
+}
+
+/**
+  Configure Super IO
+
+**/
+VOID
+SioInit (
+  VOID
+  )
+{
+  //
+  // Program and Enable Default Super IO Configuration Port Addresses and range
+  //
+  PchLpcGenIoRangeSet (PcdGet16 (PcdLpcSioConfigDefaultPort) & (~0xF), 0x10);
+
+    PchLpcGenIoRangeSet (SIO_RUNTIME_REG_BASE_ADDRESS  & (~0x7F), 0x10);
+  return;
+}
+
+/**
+  Configure GPIO and SIO before memory ready
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInitPreMem (
+  VOID
+  )
+{
+  //
+  // Obtain Platform Info from HOB.
+  //
+  GpioInitPreMem ();
+  GpioGroupTierInitHook ();
+  SioInit ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInit (
+  VOID
+  )
+{
+
+  GpioInit ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Do platform specific programming post-memory.
+
+  @retval  EFI_SUCCESS       The function completed successfully.
+**/
+
+EFI_STATUS
+PlatformSpecificInit (
+  VOID
+  )
+{
+  GPIO_CONFIG                     GpioConfig;
+
+  if (IsCnlPch ()) {
+
+    //
+    // Tristate unused pins by audio link mode.
+    //
+    ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
+    GpioConfig.PadMode = GpioPadModeGpio;
+    GpioConfig.HostSoftPadOwn = GpioHostOwnGpio;
+    GpioConfig.Direction = GpioDirNone;
+    GpioConfig.OutputState = GpioOutDefault;
+    GpioConfig.InterruptConfig = GpioIntDis;
+    GpioConfig.PowerConfig = GpioPlatformReset;
+    GpioConfig.ElectricalConfig = GpioTermNone;
+
+    GpioSetPadConfig (GPIO_CNL_LP_SSP1_SFRM, &GpioConfig);
+    GpioSetPadConfig (GPIO_CNL_LP_SSP1_TXD, &GpioConfig);
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Early Board Configuration before memory is ready
+
+  @retval  EFI_SUCCESS  Operation success.
+**/
+EFI_STATUS
+BoardInitEarlyPreMem (
+  VOID
+  )
+{
+  GpioInitEarlyPreMem ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
new file mode 100644
index 0000000000..e437814b10
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
@@ -0,0 +1,48 @@
+/** @file
+ Intel PEI CPU Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI CPU Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                  Status;
+  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
+  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
+  CPU_CONFIG                  *CpuConfig;
+
+  DEBUG((DEBUG_INFO, "Updating CPU Policy by board config in Post Mem\n"));
+
+  Status = PeiServicesLocatePpi(
+      &gSiPreMemPolicyPpiGuid,
+      0,
+      NULL,
+      (VOID **)&SiPreMemPolicyPpi
+      );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..3797df0856
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
@@ -0,0 +1,29 @@
+/** @file
+ Intel PEI CPU Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function performs PEI CPU Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
new file mode 100644
index 0000000000..843fe4accd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI ME Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI ME Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  ME_PEI_CONFIG                      *MePeiConfig;
+
+  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..79c93455a6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI ME Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI ME Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
new file mode 100644
index 0000000000..5dbc412879
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI PCH Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI PCH Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  PCH_GENERAL_CONFIG                 *PchGeneralConfig;
+
+  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..1080015029
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI PCH Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI PCH Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  PCH_GENERAL_PREMEM_CONFIG          *PchGeneralPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
new file mode 100644
index 0000000000..d1d964aea7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SA Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  GRAPHICS_PEI_CONFIG                *GtConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *)&GtConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..34fca7fac3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI SA Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SA Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  SA_MISC_PEI_PREMEM_CONFIG          *MiscPeiPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
new file mode 100644
index 0000000000..f5f38910a8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
@@ -0,0 +1,27 @@
+/** @file
+ Intel PEI SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SI Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  return EFI_SUCCESS;
+}
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
  2019-08-17 20:11   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files

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

Adds the DSC and build files necessary to build the
WhiskeylakeURvp board instance.

Key files
=========
* build_config.cfg - Board-specific build configuration file.
* OpenBoardPkg.dsc - The WhiskeylakeURvp board description file.
* OpenBoardPkgConfig.dsc - Used for feature-related PCD
  customization.
* OpenBoardPkgPcd.dsc - Used for other PCD customization.
* OpenBoardPkg.fdf - The WhiskeylakeURvp board flash file.
* FlashMapInclude.fdf - The WhiskeylakeURvp board flash map.
* OpenBoardPkgBuildOption.dsc - Sets build options Based
  on PCD values.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc                | 385 +++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc     | 154 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc          | 128 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc             | 245 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf |  49 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf                | 706 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg                |  33 +
 7 files changed, 1700 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
new file mode 100644
index 0000000000..eea809140c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
@@ -0,0 +1,385 @@
+## @file
+#  Platform description.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  #
+  # Set platform specific package/folder name, same as passed from PREBUILD script.
+  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package build folder
+  # DEFINE only takes effect at R9 DSC and FDF.
+  #
+  DEFINE      PLATFORM_PACKAGE          = MinPlatformPkg
+  DEFINE      PLATFORM_SI_PACKAGE       = CoffeelakeSiliconPkg
+  DEFINE      PLATFORM_SI_BIN_PACKAGE   = CoffeelakeSiliconBinPkg
+  DEFINE      PLATFORM_FSP_BIN_PACKAGE  = CoffeeLakeFspBinPkg
+  DEFINE      PLATFORM_BOARD_PACKAGE    = WhiskeylakeOpenBoardPkg
+  DEFINE      BOARD                     = WhiskeylakeURvp
+  DEFINE      PROJECT                   = $(PLATFORM_BOARD_PACKAGE)/$(BOARD)
+
+  #
+  # Platform On/Off features are defined here
+  #
+  !include OpenBoardPkgConfig.dsc
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                       = $(PLATFORM_PACKAGE)
+  PLATFORM_GUID                       = 84D0F5BD-0EF3-4CC0-9B09-F2D0F2AA5C5E
+  PLATFORM_VERSION                    = 0.1
+  DSC_SPECIFICATION                   = 0x00010005
+  OUTPUT_DIRECTORY                    = Build/$(PROJECT)
+  SUPPORTED_ARCHITECTURES             = IA32|X64
+  BUILD_TARGETS                       = DEBUG|RELEASE
+  SKUID_IDENTIFIER                    = ALL
+
+
+  FLASH_DEFINITION                    = $(PROJECT)/OpenBoardPkg.fdf
+
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
+  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
+
+  #
+  # Default value for OpenBoardPkg.fdf use
+  #
+  DEFINE BIOS_SIZE_OPTION = SIZE_70
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+  0x60|WhiskeylakeURvp
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreCommonLib.dsc
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiLib.dsc
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeLib.dsc
+
+[LibraryClasses.common]
+
+  PeiLib|$(PLATFORM_PACKAGE)/Library/PeiLib/PeiLib.inf
+  ReportFvLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/PeiReportFvLib/PeiReportFvLib.inf
+
+  PciHostBridgeLib|$(PLATFORM_PACKAGE)/Pci/Library/PciHostBridgeLibSimple/PciHostBridgeLibSimple.inf
+  PciSegmentInfoLib|$(PLATFORM_PACKAGE)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
+  PlatformBootManagerLib|$(PLATFORM_PACKAGE)/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf
+  I2cAccessLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
+  GpioExpanderLib|$(PLATFORM_BOARD_PACKAGE)/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
+
+  PlatformHookLib|$(PROJECT)/Library/BasePlatformHookLib/BasePlatformHookLib.inf
+
+  FspWrapperHobProcessLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperHobProcessLib/PeiFspWrapperHobProcessLib.inf
+  PlatformSecLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
+
+  FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
+  FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
+
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf
+  SiliconPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
+
+  ConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/BoardInitLibNull/BoardInitLibNull.inf
+  TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    TbtCommonLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
+  !endif
+  DxeTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
+  PchHsioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
+  MmPciLib|$(PLATFORM_SI_PACKAGE)/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
+  PchPmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
+
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.IA32]
+  #
+  # PEI phase common
+  #
+  SiliconPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/PeiTestPointLib.inf
+  MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  HdaVerbTableLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    PeiTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
+    PeiDTbtInitLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
+  !endif
+
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
+    PeiPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
+    PeiPolicyBoardConfigLib|$(PROJECT)/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
+    PeiPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
+    PeiPlatformHookLib|$(PROJECT)/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
+  !if $(TARGET) == DEBUG
+    GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
+  !else
+    GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
+  !endif
+
+[LibraryClasses.IA32.SEC]
+  TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf
+  SecBoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/SecBoardInitLibNull/SecBoardInitLibNull.inf
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.X64]
+  #
+  # DXE phase common
+  #
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/DxeFspWrapperPlatformLib/DxeFspWrapperPlatformLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/DxeTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/DxeTestPointLib.inf
+  MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
+  MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
+  BoardAcpiTableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
+
+  DxePolicyBoardConfigLib|$(PROJECT)/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
+  DxePolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxeLib.dsc
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  SpiFlashCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SmmTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/SmmTestPointLib.inf
+  MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
+  BoardAcpiEnableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+
+[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
+  ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  !include OpenBoardPkgPcd.dsc
+
+[Components.IA32]
+  #
+  # Common
+  #
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiInclude.dsc
+
+  #
+  # FSP wrapper SEC Core
+  #
+  UefiCpuPkg/SecCore/SecCore.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  #
+  # Silicon
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgPei.dsc
+
+  #
+  # Platform
+  #
+  $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
+      !endif
+      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
+  }
+  IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+      SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
+      !endif
+  }
+  IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
+#to do  $(PLATFORM_PACKAGE)/FspWrapper/FspWrapperPeim/FspWrapperPeim.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+      SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+
+  #
+  # Security
+  #
+
+  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
+  !endif
+
+  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+  IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+  !endif
+
+[Components.X64]
+
+  #
+  # Common
+  #
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeInclude.dsc
+
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # Shell
+  #
+  ShellPkg/Application/Shell/Shell.inf {
+   <PcdsFixedAtBuild>
+     gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+   <LibraryClasses>
+     NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+     ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+     HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+     BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+     ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+     ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  }
+
+  #
+  # Silicon
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxe.dsc
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+    $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+  !endif
+
+  #
+  # Platform
+  #
+  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf{
+    <LibraryClasses>
+      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
+  }
+
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+	  SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
+
+  $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+
+  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
+  $(PLATFORM_PACKAGE)/Test/TestPointDumpApp/TestPointDumpApp.inf
+
+  #
+  # OS Boot
+  #
+  !if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+    $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
+  $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
+  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardAcpiEnableLib|$(PROJECT)/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
+      !endif
+  }
+
+  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
+    <LibraryClasses>
+      !if $(TARGET) == DEBUG
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !endif
+  }
+
+  !endif
+
+  #
+  # Security
+  #
+  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
+
+  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
+  !endif
+
+  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
+
+  #
+  # Other
+  #
+  $(PLATFORM_SI_BIN_PACKAGE)/Microcode/MicrocodeUpdates.inf
+
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
+  !include OpenBoardPkgBuildOption.dsc
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
new file mode 100644
index 0000000000..be1d47c719
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
@@ -0,0 +1,154 @@
+## @file
+# platform build option configuration file.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[BuildOptions]
+# Define Build Options both for EDK and EDKII drivers.
+
+
+  DEFINE DSC_S3_BUILD_OPTIONS =
+
+  DEFINE DSC_CSM_BUILD_OPTIONS =
+
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+  DEFINE DSC_ACPI_BUILD_OPTIONS = -DACPI_SUPPORT=1
+!else
+  DEFINE DSC_ACPI_BUILD_OPTIONS =
+!endif
+
+  DEFINE BIOS_GUARD_BUILD_OPTIONS =
+
+  DEFINE OVERCLOCKING_BUILD_OPTION =
+
+  DEFINE FSP_BINARY_BUILD_OPTIONS =
+
+  DEFINE FSP_WRAPPER_BUILD_OPTIONS = -DFSP_WRAPPER_FLAG
+
+  DEFINE SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS =
+
+  DEFINE RESTRICTED_OPTION =
+
+
+  DEFINE SV_BUILD_OPTIONS =
+
+  DEFINE TEST_MENU_BUILD_OPTION =
+
+!if gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable == FALSE
+  DEFINE OPTIMIZE_DISABLE_OPTIONS = -Od -GL-
+!else
+  DEFINE OPTIMIZE_DISABLE_OPTIONS =
+!endif
+
+  DEFINE UP_SERVER_SUPPORT_BUILD_OPTIONS =
+
+
+  DEFINE TPM_BUILD_OPTION =
+
+  DEFINE TPM2_BUILD_OPTION =
+
+  DEFINE DSC_TBT_BUILD_OPTIONS =
+
+  DEFINE DSC_DCTT_BUILD_OPTIONS =
+
+  DEFINE EMB_BUILD_OPTIONS =
+
+  DEFINE DSC_MEMORY_DOWN_BUILD_OPTIONS = -DMEM_DOWN_FLAG=1
+
+  DEFINE DSC_KBCEMUL_BUILD_OPTIONS =
+
+  DEFINE BOOT_GUARD_BUILD_OPTIONS =
+
+  DEFINE SECURE_BOOT_BUILD_OPTIONS =
+
+  DEFINE USBTYPEC_BUILD_OPTION =
+
+  DEFINE CAPSULE_BUILD_OPTIONS =
+
+  DEFINE PERFORMANCE_BUILD_OPTION =
+
+  DEFINE DEBUGUSEUSB_BUILD_OPTION =
+
+  DEFINE DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION = -DDISABLE_NEW_DEPRECATED_INTERFACES=1
+
+  DEFINE SINITBIN_BUILD_OPTION =
+
+  DEFINE MINTREE_FLAG_BUILD_OPTION = -DMINTREE_FLAG=1
+
+  DEFINE CPUTYPE_BUILD_OPTION = -DCPU_CFL=1
+
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)  $(OVERCLOCKING_BUILD_OPTION) $(PERFORMANCE_BUILD_OPTION) $(EMB_BUILD_OPTIONS) $(BIOS_GUARD_BUILD_OPTIONS) $(DSC_TBT_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(BOOT_GUARD_BUILD_OPTIONS) $(DSC_MEMORY_DOWN_BUILD_OPTIONS) $(DEBUGUSEUSB_BUILD_OPTION) $(DSC_S3_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(FSP_BINARY_BUILD_OPTIONS) $(FSP_WRAPPER_BUILD_OPTIONS) $(SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_KBCEMUL_BUILD_OPTIONS) $(CAPSULE_BUILD_OPTIONS) $(SECURE_BOOT_BUILD_OPTIONS) $(DSC_CSM_BUILD_OPTIONS) $(DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(TPM2_BUILD_OPTION) $(TPM_BUILD_OPTION) $(DSC_DCTT_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS) $(UP_SERVER_SUPPORT_BUILD_OPTIONS) $(USBTYPEC_BUILD_OPTION) $(SINITBIN_BUILD_OPTION) $(MINTREE_FLAG_BUILD_OPTION)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(CPUTYPE_BUILD_OPTION)
+[BuildOptions.Common.EDKII]
+
+#
+# For IA32 Global Build Flag
+#
+       *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+       *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_NASM_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+#
+# For IA32 Specific Build Flag
+#
+GCC:   *_*_IA32_PP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_ASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+MSFT:  *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+
+#
+# For X64 Global Build Flag
+#
+       *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+       *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_NASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+
+#
+# For X64 Specific Build Flag
+#
+GCC:   *_*_X64_PP_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASM_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+MSFT:  *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support MemoryAttribute table
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support NX protection
+[BuildOptions.common.EDKII.DXE_DRIVER, BuildOptions.common.EDKII.DXE_CORE, BuildOptions.common.EDKII.UEFI_DRIVER, BuildOptions.common.EDKII.UEFI_APPLICATION]
+  #MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  #GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
new file mode 100644
index 0000000000..c68fecf50e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
@@ -0,0 +1,128 @@
+## @file
+#  Platform configuration file.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[PcdsFixedAtBuild]
+  #
+  # Please select BootStage here.
+  # Stage 1 - enable debug (system deadloop after debug init)
+  # Stage 2 - mem init (system deadloop after mem init)
+  # Stage 3 - boot to shell only
+  # Stage 4 - boot to OS
+  # Stage 5 - boot to OS with security boot enabled
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4
+
+[PcdsFeatureFlag]
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 1
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 2
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 3
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 4
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 5
+  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
+!endif
+
+  gBoardModuleTokenSpaceGuid.PcdTbtEnable|FALSE
+  #
+  # More fine granularity control below:
+  #
+
+  gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport|TRUE
+
+#
+# TRUE is ENABLE. FALSE is DISABLE.
+#
+#
+# BIOS build switches configuration
+#
+  gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+
+# CPU
+  gSiPkgTokenSpaceGuid.PcdSourceDebugEnable|FALSE
+
+# SA
+  gSiPkgTokenSpaceGuid.PcdIgdEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPegEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSgEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSaDmiEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSaOcEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdVtdEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable|TRUE
+
+# ME
+  gSiPkgTokenSpaceGuid.PcdAtaEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPttEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdJhiEnable|TRUE
+
+  gSiPkgTokenSpaceGuid.PcdAcpiEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdBdatEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSiCsmEnable|FALSE
+  gSiPkgTokenSpaceGuid.PcdTraceHubEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPpmEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdS3Enable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSmbiosEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSmmVariableEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdUseHpetTimer|TRUE                       # TRUE - HPET / FALSE - 8254 timer is used.
+  gSiPkgTokenSpaceGuid.PcdOcWdtEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable|FALSE
+
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdCflCpuEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdIpuEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdGnaEnable|TRUE
+
+#
+# Override some PCDs for specific build requirements.
+#
+  #
+  # Disable USB debug message when Source Level Debug is enabled
+  # because they cannot be enabled at the same time.
+  #
+
+    gSiPkgTokenSpaceGuid.PcdPttEnable|FALSE
+
+  !if $(TARGET) == DEBUG
+    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+  !else
+    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+  !endif
+
+  !if $(TARGET) == DEBUG
+    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE
+  !else
+    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE
+  !endif
+
+    gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
new file mode 100644
index 0000000000..96d65133ae
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
@@ -0,0 +1,245 @@
+## @file
+#  Platform description.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport|TRUE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+!if $(TARGET) == RELEASE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable|TRUE
+
+[PcdsFixedAtBuild.common]
+  gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode|TRUE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|140
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1
+!endif
+
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|2
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|8
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|1
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
+  gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
+  gSiPkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+  gSiPkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF00000
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
+
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize        | 0x00026000
+
+  gSiPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x5000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe|TRUE
+
+#
+# 8MB Default
+#
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000
+
+#
+# 16MB TSEG in Debug build only.
+#
+!if $(TARGET) == DEBUG
+  gSiPkgTokenSpaceGuid.PcdTsegSize|0x1000000
+!endif
+
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber|0x0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber|0x1F
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber|0x2
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x44
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask|0x80
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset|0x00
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress|0x1800
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset|0x08
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask|0xFFFC
+
+  !if $(TARGET) == RELEASE
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x402
+  !else
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x188B
+  !endif
+
+
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize|0x4b
+  !if $(TARGET) == RELEASE
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0x70
+  !else
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0xE0
+  !endif
+
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress|0xFFEAC000
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress|0xFFDC0000
+
+  ## Specifies the size of the microcode Region.
+  # @Prompt Microcode Region size.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0
+
+  ## Specifies timeout value in microseconds for the BSP to detect all APs for the first time.
+  # @Prompt Timeout for the BSP to detect all APs for the first time.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|1000
+
+  ## 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
+
+
+  #
+  # The PCDs are used to control the Windows SMM Security Mitigations Table - Protection Flags
+  #
+  # BIT0: If set, expresses that for all synchronous SMM entries,SMM will validate that input and output buffers lie entirely within the expected fixed memory regions.
+  # BIT1: If set, expresses that for all synchronous SMM entries, SMM will validate that input and output pointers embedded within the fixed communication buffer only refer to address ranges \
+  #       that lie entirely within the expected fixed memory regions.
+  # BIT2: Firmware setting this bit is an indication that it will not allow reconfiguration of system resources via non-architectural mechanisms.
+  # BIT3-31: Reserved
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags|0x07
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 1
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 2
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 3
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x03, 0x05, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 4
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x03, 0x05, 0x1F, 0x00, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 5
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 6
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+[PcdsFixedAtBuild.IA32]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00148
+  gMinPlatformPkgTokenSpaceGuid.PcdPeiPhaseStackTop|0xA0000
+  gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x3800000
+
+[PcdsFixedAtBuild.X64]
+  # Default platform supported RFC 4646 languages: (American) English
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en-US"
+
+
+[PcdsPatchableInModule.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+
+!if $(TARGET) == DEBUG
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable|1
+!endif
+
+[PcdsDynamicHii.X64.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout"
+  gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"Timeout"
+!endif
+
+[PcdsDynamicDefault]
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0xFFD50000
+  # Platform will pre-allocate UPD buffer and pass it to FspWrapper
+  # Those dummy address will be patched before FspWrapper executing
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress|0x0
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress|0x0
+
+  ## Specifies max supported number of Logical Processors.
+  # @Prompt Configure max supported number of Logical Processors
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|16
+
+[PcdsDynamicDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAtaSmartEnable|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE
+  #
+  #  Set video to native resolution as Windows 8 WHCK requirement.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0x0
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum|0x00
+
+[PcdsDynamicDefault.common.DEFAULT]
+
+  # Tbt
+  gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad | 13
+  gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad | 0x02010011
+  gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport | 0x0
+  gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq| 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtAspm | 0x0
+  gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch | 0x0
+
+  gBoardModuleTokenSpaceGuid.PcdRtd3Tbt | 0x1
+  gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax | 26
+  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd | 100
+  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax | 28
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
new file mode 100644
index 0000000000..9209b9e88a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
@@ -0,0 +1,49 @@
+## @file
+#  FDF file of Platform.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+#=================================================================================#
+# 8 M BIOS - for FSP wrapper
+#=================================================================================#
+DEFINE FLASH_BASE                                                   = 0xFF800000  #
+DEFINE FLASH_SIZE                                                   = 0x00800000  #
+DEFINE FLASH_BLOCK_SIZE                                             = 0x00010000  #
+DEFINE FLASH_NUM_BLOCKS                                             = 0x00000080  #
+#=================================================================================#
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageOffset           = 0x00000000  # Flash addr (0xFF800000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize             = 0x00040000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset   = 0x00000000  # Flash addr (0xFF800000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize    = 0x0001E000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset = 0x0001E000  # Flash addr (0xFF81E000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize  = 0x00002000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset   = 0x00020000  # Flash addr (0xFF820000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize    = 0x00020000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset          = 0x00040000  # Flash addr (0xFF840000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            = 0x00060000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset          = 0x000A0000  # Flash addr (0xFF8A0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            = 0x00070000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset            = 0x00110000  # Flash addr (0xFF910000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              = 0x00090000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset          = 0x001A0000  # Flash addr (0xFF9A0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            = 0x00190000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset        = 0x00330000  # Flash addr (0xFFB30000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          = 0x00170000  #
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset                  = 0x004A0000  # Flash addr (0xFFCA0000)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                    = 0x000B0000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset              = 0x00550000  # Flash addr (0xFFD50000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize                = 0x00070000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset              = 0x005C0000  # Flash addr (0xFFDC0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                = 0x000EC000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset              = 0x006AC000  # Flash addr (0xFFEAC000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                = 0x00014000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset         = 0x006C0000  # Flash addr (0xFFEC0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           = 0x00140000  #
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
new file mode 100644
index 0000000000..611078e4b4
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
@@ -0,0 +1,706 @@
+## @file
+#  FDF file of Platform.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+   !include $(PROJECT)/Include/Fdf/FlashMapInclude.fdf
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.WhiskeylakeURvp]
+#
+# FD Tokens, BaseAddress, Size, ErasePolarity, BlockSize, and NumBlocks, cannot be
+# assigned with PCD values. Instead, it uses the definitions for its variety, which
+# are FLASH_BASE, FLASH_SIZE, FLASH_BLOCK_SIZE and FLASH_NUM_BLOCKS.
+#
+BaseAddress   = $(FLASH_BASE) | gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress      #The base address of the FLASH Device.
+Size          = $(FLASH_SIZE) | gSiPkgTokenSpaceGuid.PcdBiosSize             #The size in bytes of the FLASH Device
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCK_SIZE)
+NumBlocks     = $(FLASH_NUM_BLOCKS)
+
+DEFINE SIPKG_DXE_SMM_BIN  = INF
+DEFINE SIPKG_PEI_BIN      = INF
+
+# Set FLASH_REGION_FV_RECOVERY_OFFSET to PcdNemCodeCacheBase, because macro expression is not supported.
+# So, PlatformSecLib uses PcdBiosAreaBaseAddress + PcdNemCodeCacheBase to get the real CodeCache base address.
+SET gSiPkgTokenSpaceGuid.PcdNemCodeCacheBase = $(gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase = $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) + $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase) + 0x60
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize) - 0x60
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) + $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset = 0x60
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase    = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize    = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeOffset  = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress = gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize    = gSiPkgTokenSpaceGuid.PcdBiosSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress    = gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize           = gSiPkgTokenSpaceGuid.PcdBiosSize
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+# Fv Size can be adjusted
+#
+################################################################################
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x40000
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5F, 0x46, 0x56, 0x48, 0xFF, 0xFE, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  #
+  # Be careful on CheckSum field.
+  #
+  0x48, 0x00, 0x32, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 4 Blocks  0x10000 Bytes / Block
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+!if gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable == TRUE
+  #  Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+  #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+  #Size: 0x1E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x1DFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xDF, 0x01, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+FV = FvAdvanced
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+FV = FvSecurity
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+FV = FvOsBoot
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+FV = FvUefiBoot
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+FV = FvPostMemory
+
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase|gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+#Microcode
+FV = FvMicrocode
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+# FSP_S Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_S.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+# FSP_M Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_M.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+# FSP_T Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_T.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+FV = FvPreMemory
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FvMicrocode]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = FALSE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = FALSE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
+  $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/X64/MicrocodeUpdates.bin
+}
+
+[FV.FvPreMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = FC8FE6B5-CD9B-411E-BD8F-31824D0CDE3D
+
+INF  UefiCpuPkg/SecCore/SecCore.inf
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePreMemoryInclude.fdf
+
+INF $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+INF IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+
+[FV.FvPostMemoryUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 7C4DCFC6-AECA-4707-85B9-FD4B2EEA49E7
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePostMemoryInclude.fdf
+
+# Init Board Config PCD
+INF $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+INF IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+
+FILE RAW = C9505BC0-AA3D-4056-9995-870C8DE8594E {
+    $(PLATFORM_SI_BIN_PACKAGE)/ChipsetInit/CnlPchLpChipsetInitTable_Dx.bin
+  }
+!if gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable == TRUE
+FILE FREEFORM =PCD(gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid) {
+  SECTION RAW = $(PLATFORM_FSP_BIN_PACKAGE)/SampleCode/Vbt/Vbt.bin
+  SECTION UI  = "Vbt"
+}
+FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D {
+  SECTION RAW = MdeModulePkg/Logo/Logo.bmp
+}
+!endif # PcdPeiDisplayEnable
+
+
+[FV.FvPostMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 9DFE49DB-8EF0-4D9C-B273-0036144DE917
+
+FILE FV_IMAGE = 244FAAF4-FAE1-4892-8B7D-7EF84CBFA709 {
+      SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+        SECTION FV_IMAGE = FvPostMemoryUncompact
+      }
+}
+
+[FV.FvUefiBootUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreUefiBootInclude.fdf
+INF  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
+
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF  MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+INF  ShellPkg/Application/Shell/Shell.inf
+
+INF  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf
+INF  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf
+INF  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
+
+INF  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
+
+
+[FV.FvUefiBoot]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 0496D33D-EA79-495C-B65D-ABF607184E3B
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvUefiBootUncompact
+       }
+     }
+
+[FV.FvOsBootUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A0F04529-B715-44C6-BCA4-2DEBDD01EEEC
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreOsBootInclude.fdf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+INF  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+INF  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+
+INF  $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
+INF  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf
+
+INF  RuleOverride = DRIVER_ACPITABLE $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
+INF  $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+
+!endif
+
+[FV.FvLateSilicon]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 97F09B89-9E83-4DDC-A3D1-10C4AF539D1E
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
+
+INF  RuleOverride = ACPITABLE $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
+INF  RuleOverride = ACPITABLE $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
+
+!endif
+
+[FV.FvOsBoot]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 13BF8810-75FD-4B1A-91E6-E16C4201F80A
+
+FILE FV_IMAGE = B9020753-84A8-4BB6-947C-CE7D41F5CE39 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvOsBootUncompact
+       }
+     }
+
+FILE FV_IMAGE = D4632741-510C-44E3-BE21-C3D6D7881485 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvLateSilicon
+       }
+     }
+
+[FV.FvSecurityPreMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 9B7FA59D-71C6-4A36-906E-9725EA6ADD5B
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
+
+INF  IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+
+INF  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+
+[FV.FvSecurityPostMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 4199E560-54AE-45E5-91A4-F7BC3804E14A
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPostMemoryInclude.fdf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+INF $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
+!endif
+
+[FV.FvSecurityLate]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = F753FE9A-EEFD-485B-840B-E032D538102C
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityLateInclude.fdf
+INF  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+INF  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
+!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+INF  $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
+!endif
+!endif
+
+[FV.FvSecurity]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 5A9A8B4E-149A-4CB2-BDC7-C8D62DE2C8CF
+
+FILE FV_IMAGE = 757CC075-1428-423D-A73C-22639706C119 {
+       SECTION FV_IMAGE = FvSecurityPreMemory
+     }
+
+FILE FV_IMAGE = 80BB8482-44D5-4BEC-82B5-8D87A933830B {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvSecurityPostMemory
+       }
+     }
+
+FILE FV_IMAGE = C83522D9-80A1-4D95-8C25-3F1370497406 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvSecurityLate
+       }
+     }
+
+[FV.FvAdvancedPreMem]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 6053D78A-457E-4490-A237-31D0FBE2F305
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+!endif
+
+[FV.FvAdvancedPostMem]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = BE3DF86F-E464-44A3-83F7-0D27E6B88C27
+
+[FV.FvAdvancedLate]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 11F6E304-43F9-4B2F-90AB-B8FFEAD6205D
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+!endif
+
+[FV.FvAdvanced]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B23E7388-9953-45C7-9201-0473DDE5487A
+
+FILE FV_IMAGE = 35E7406A-5842-4F2B-BC62-19022C12AF74 {
+       SECTION FV_IMAGE = FvAdvancedPreMem
+     }
+
+FILE FV_IMAGE = F5DCB34F-27EA-48AC-9406-C894F6D587CA {
+       SECTION FV_IMAGE = FvAdvancedPostMem
+     }
+
+FILE FV_IMAGE = 5248467B-B87B-4E74-AC02-398AF4BCB712 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvAdvancedLate
+       }
+     }
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/RuleInclude.fdf
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
new file mode 100644
index 0000000000..1b0619bc1c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
@@ -0,0 +1,33 @@
+# @ build_config.cfg
+# This is the WhiskeylakeURvp board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN =
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = WhiskeylakeOpenBoardPkg
+PROJECT = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp
+BOARD = WhiskeylakeURvp
+FLASH_MAP_FDF = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = CoffeeLakeFspBinPkg
+FSP_PKG_NAME = CoffeelakeSiliconPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:17   ` Chiu, Chasel
  2019-08-17 20:00   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation

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

* Adds the WhiskeylakeURvp board as a build option in build.cfg so it
  it is listed as a valid build target.
* Updates relevant Readme.md files to include instructions for
  WhiskeylakeOpenBoardPkg.
* Adds the maintainers for WhiskeylakeOpenBoardPkg to maintainers.txt.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Maintainers.txt          |  5 +++
 Platform/Intel/Readme.md | 44 +++++++++++++-------  Platform/Intel/build.cfg |  4 +-
 Readme.md                |  1 +
 4 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/Maintainers.txt b/Maintainers.txt index bc8cbd6458..b16432bf87 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -98,6 +98,11 @@ M: Shifei A Lu <shifei.a.lu@intel.com>
 M: Xiaohu Zhou <bowen.zhou@intel.com>
 M: Isaac W Oram <isaac.w.oram@intel.com>
 
+Platform/Intel/WhiskeylakeOpenBoardPkg
+M: Chasel Chiu <chasel.chiu@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
+M: Nate DeSimone <nathaniel.l.desimone@intel.com>
+
 Platform/Intel/Tools
 M: Bob Feng <bob.c.feng@intel.com>
 M: Liming Gao <liming.gao@intel.com>
diff --git a/Platform/Intel/Readme.md b/Platform/Intel/Readme.md index 00f42985a2..aaf6ef4d3e 100644
--- a/Platform/Intel/Readme.md
+++ b/Platform/Intel/Readme.md
@@ -53,9 +53,10 @@ A UEFI firmware implementation using MinPlatformPkg is constructed using the fol
 
 
 ## Board Support
+* The `ClevoOpenBoardPkg` contains board implementations for Clevo systems.
 * The `KabylakeOpenBoardPkg` contains board implementations for Kaby Lake systems.
 * The `PurleyOpenBoardPkg` contains board implementations for Purley systems.
-* The `ClevoOpenBoardPkg` contains board implementations for Clevo systems.
+* The `WhiskeylakeOpenBoardPkg` contains board implementations for Whiskey Lake systems.
 
 ## Board Package Organization
 The board package follows the standard EDK II package structure with the following additional elements and guidelines:
@@ -189,7 +190,12 @@ return back to the minimum platform caller.
           |       |        |                |---build_config.cfg: BoardMtOlympus specific
           |       |        |                |                     build settings, environment variables.
           |       |        |                |---build_board.py: Optional board-specific pre-build,
-          |       |        |                |                   build, post-build and clean functions.
+          |       |        |                                    build, post-build and clean functions.
+          |       |        |
+          |       |        |------WhiskeylakeOpenBoardPkg
+          |       |        |        |------WhiskeylakeURvp
+          |       |        |                |---build_config.cfg: WhiskeylakeURvp specific build
+          |       |        |                                      settings environment variables.
           |------FSP
   </pre>
 
@@ -222,19 +228,6 @@ Users can also flash the UEFI firmware image to the highest area of the flash re
 
 ### **Known limitations**
 
-**KabylakeOpenBoardPkg**
-1. This firmware project has only been tested on the Intel KabylakeRvp3 board.
-2. This firmware project has only been tested booting to Microsoft Windows 10 x64 with AHCI mode and Integrated Graphic
-  Device.
-3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
-4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
-5. The build was tested with NASM version 2.11.08.
-
-**PurleyOpenBoardPkg**
-1. This firmware project has only been tested on the Microsoft MtOlympus board.
-2. This firmware project has only been tested booting to Microsoft Windows Server 2016 with NVME on M.2 slot.
-3. This firmware project build has only been tested using the Microsoft Visual Studio 2015 compiler.
-
 **ClevoOpenBoardPkg**
 1. Currently, support is only being added for the N1xxWU series of boards.
 2. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015 compiler.
@@ -244,6 +237,27 @@ Users can also flash the UEFI firmware image to the highest area of the flash re  6. The firmware project applies to all Clevo supported board configurations but is only being tested on System 76 Galago
   Pro devices.
 
+**KabylakeOpenBoardPkg**
+1. This firmware project has only been tested on the Intel KabylakeRvp3 board.
+2. This firmware project has only been tested booting to Microsoft 
+Windows 10 x64 with AHCI mode and Integrated Graphic
+  Device.
+3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
+4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
+5. The build was tested with NASM version 2.11.08.
+
+**PurleyOpenBoardPkg**
+1. This firmware project has only been tested on the Microsoft MtOlympus board.
+2. This firmware project has only been tested booting to Microsoft Windows Server 2016 with NVME on M.2 slot.
+3. This firmware project build has only been tested using the Microsoft Visual Studio 2015 compiler.
+
+**WhiskeylakeOpenBoardPkg**
+1. This firmware project has only been tested on the Intel WhiskeylakeURvp board.
+2. This firmware project has only been tested booting to Microsoft 
+Windows 10 x64 with AHCI mode and Integrated Graphic
+  Device.
+3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
+4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
+5. The build was tested with NASM version 2.11.08.
+
 ### **Planned Activities**
 * Replace the batch build scripts with cross-platform Python build scripts.
 * Publish a Minimum Platform specification to describe the architecture and interfaces in more detail.
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index fc6e4fe824..b6d32ada49 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -51,6 +51,8 @@ NUMBER_OF_PROCESSORS = 0
 
 [PLATFORMS]
 # board_name = path_to_board_build_config.cfg
+BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
-BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+WhiskeylakeURvp = 
+WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
+
diff --git a/Readme.md b/Readme.md
index 1befd0b544..e4f211eee6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -228,6 +228,7 @@ they will be documented with the platform.
 * [Clevo](Platform/Intel/ClevoOpenBoardPkg)
 * [Kaby Lake](Platform/Intel/KabylakeOpenBoardPkg)
 * [Purley](Platform/Intel/PurleyOpenBoardPkg)
+* [Whiskey Lake](Platform/Intel/WhiskeylakeOpenBoardPkg)
 
 For more information, see the
 [EDK II Minimum Platform Specification](https://edk2-docs.gitbooks.io/edk-ii-minimum-platform-specification).
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
@ 2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:17   ` Chiu, Chasel
  2019-08-17  7:50   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Nate DeSimone @ 2019-08-17  0:54 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

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

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules

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

Modules shared across board instances.

* BoardAcpiDxe - Performs DXE board ACPI initialization.
* PciHotPlug - Performs PCI-e resource configuration.
* PeiTbtInit - Initializes Thunderbolt policy in PEI.
* PolicyInitDxe - Initializes policy in DXE.
* TbtDxe - Performs Thunderbolt initialization in DXE.
* TbtSmm - Performs Thunderbolt initialization in SMM.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf          |   71 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf          |   62 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf         |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf     |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf         |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf      |  176 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h            |  130 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h    |  180 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h         |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h     |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h     |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h     |   52 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h        |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h      |   56 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c            |   96 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c            |  290 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c            |  353 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c           |  228 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c       |  211 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c    | 1609 +++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c           | 1765 ++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c         |  394 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c         |  612 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c     |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c     |  174 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c     |   55 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c        |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c      |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl           |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL             |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl          |  516 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl          |  309 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl         |   76 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl     |  405 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl             | 1877 ++++++++++++++++++++
 37 files changed, 10365 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
new file mode 100644
index 0000000000..2bbc3cb9e2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
@@ -0,0 +1,71 @@
+## @file
+#  Component information file for AcpiPlatform module
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BoardAcpiDxe
+  FILE_GUID                      = E269E77D-6163-4F5D-8E59-21EAF114D307
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InstallAcpiBoard
+
+[Sources.common]
+  BoardAcpiDxe.c
+  AcpiGnvsInit.c
+  Dsdt/DSDT.ASL
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  HobLib
+  AslUpdateLib
+  BoardAcpiTableLib
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     ## CONSUMES
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gEfiMpServiceProtocolGuid                     ## CONSUMES
+  gEfiGlobalNvsAreaProtocolGuid
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress
+
+  gBoardModuleTokenSpaceGuid.PcdAcpiSleepState
+  gBoardModuleTokenSpaceGuid.PcdAcpiHibernate
+  gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle
+  gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints
+  gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints
+  gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints
+
+[Depex]
+  gEfiAcpiTableProtocolGuid           AND
+  gEfiFirmwareVolume2ProtocolGuid     AND
+  gEfiPciRootBridgeIoProtocolGuid     AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiVariableWriteArchProtocolGuid
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
new file mode 100644
index 0000000000..dd4e41a409
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
@@ -0,0 +1,62 @@
+## @file
+# This module will perform specific PCI-Express devices
+# resource configuration.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PciHotPlug
+  FILE_GUID                      = 3022E512-B94A-4F12-806D-7EF1177899D8
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = PciHotPlug
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DevicePathLib
+  DebugLib
+  UefiLib
+  HobLib
+  PchPcieRpLib
+  ConfigBlockLib
+  TbtCommonLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PciHotPlug.c
+  PciHotPlug.h
+
+[Protocols]
+  gEfiPciHotPlugInitProtocolGuid                ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+
+[Guids]
+  gEfiHobListGuid                               ## CONSUMES
+  gPcieRpConfigGuid                  ## CONSUMES
+
+[Pcd]
+
+[Depex]
+  gDxeTbtPolicyProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
new file mode 100644
index 0000000000..5160bb1dbb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
@@ -0,0 +1,51 @@
+## @file
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtDxe
+  FILE_GUID                      = 19C9762C-3A88-41B0-906F-8C4C2895A887
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = TbtDxeEntryPoint
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  HobLib
+  UefiLib
+  TbtCommonLib
+  DxeTbtPolicyLib
+  AslUpdateLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  TbtDxe.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Depex]
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
new file mode 100644
index 0000000000..07962ffa10
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
@@ -0,0 +1,47 @@
+## @file
+# Component information file for the TBT Init PEI module.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiTbtInit
+  FILE_GUID                      = 90BF2BFB-F998-4cbc-AD72-008D4D047A4B
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = TbtInitEntryPoint
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  HobLib
+  PeiServicesLib
+  PeiTbtPolicyLib
+  PeiDTbtInitLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiTbtInit.c
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Ppis]
+  gEfiEndOfPeiSignalPpiGuid                     ## CONSUMES
+  gPeiTbtPolicyBoardInitDonePpiGuid             ## CONSUMES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
new file mode 100644
index 0000000000..3d4e6ceea0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
@@ -0,0 +1,80 @@
+## @file
+# Component information file for the ThunderBolt Smm module.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtSmm
+  FILE_GUID                      = 5BDCD685-D80A-42E6-9867-A84CCE7F828E
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  PI_SPECIFICATION_VERSION       = 1.10
+  ENTRY_POINT                    = TbtSmmEntryPoint
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  IoLib
+  PciExpressLib
+  HobLib
+  ReportStatusCodeLib
+  PciSegmentLib
+  UefiLib
+  SmmServicesTableLib
+  GpioLib
+  PchInfoLib
+  TbtCommonLib
+  PchPmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+#  gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength      ## CONSUMES
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress       ## CONSUMES
+
+[Sources]
+  TbtSmiHandler.h
+  TbtSmiHandler.c
+  TbtSmm.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gEfiSmmSxDispatch2ProtocolGuid                ## CONSUMES
+  gEfiSmmSwDispatch2ProtocolGuid                ## CONSUMES
+  gEfiSmmVariableProtocolGuid                   ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+
+[Depex]
+  gEfiSmmBase2ProtocolGuid            AND
+  gEfiSmmSxDispatch2ProtocolGuid      AND
+  gEfiSmmSwDispatch2ProtocolGuid      AND
+  gEfiGlobalNvsAreaProtocolGuid       AND
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiSmmVariableProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
new file mode 100644
index 0000000000..65c531a532
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
@@ -0,0 +1,176 @@
+## @file
+# Module Information file for the PolicyInit DXE driver.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PolicyInitDxe
+  FILE_GUID                      = 490D0119-4448-440D-8F5C-F58FB53EE057
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = PolicyInitDxeEntryPoint
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CpuPlatformLib
+  DebugLib
+  DxeServicesTableLib
+  IoLib
+  MemoryAllocationLib
+  DxeSaPolicyLib
+  DxePchPolicyLib
+  PcdLib
+  DxePolicyBoardConfigLib
+  DxePolicyUpdateLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+  ConfigBlockLib
+  DevicePathLib
+  DxeTbtPolicyLib
+  PchPcieRpLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                          ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable
+  gBoardModuleTokenSpaceGuid.PcdPlatformFlavor
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdEcPresent
+  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid
+  gBoardModuleTokenSpaceGuid.PcdTbtEnable
+  gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable                   ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication                  ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
+  gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport
+  gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport
+  gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin
+  gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature
+  gBoardModuleTokenSpaceGuid.PcdBatteryPresent
+
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support
+
+  #
+  # PSS Board Configuration.
+  #
+  gBoardModuleTokenSpaceGuid.PcdPssReadSN
+  gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber
+  gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress
+
+  gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature
+  gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile
+  gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio
+  gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdGnssResetGpio
+  gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio
+
+  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
+  gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber
+  gBoardModuleTokenSpaceGuid.PcdEcSmiGpio
+  gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio
+  gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad
+  gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck
+  gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride
+  gBoardModuleTokenSpaceGuid.PcdDDISelection
+  gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties
+  gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed
+  gPlatformModuleTokenSpaceGuid.PcdH8S2113Present
+  gPlatformModuleTokenSpaceGuid.PcdNat87393Present
+  gPlatformModuleTokenSpaceGuid.PcdNct677FPresent
+  gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport
+  gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin
+  gBoardModuleTokenSpaceGuid.PcdRealBattery1Control
+  gBoardModuleTokenSpaceGuid.PcdRealBattery2Control
+  gBoardModuleTokenSpaceGuid.PcdDimmPopulationError
+  gBoardModuleTokenSpaceGuid.PcdBtIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio
+  gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable
+  gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported
+  gBoardModuleTokenSpaceGuid.PcdMipiCamSensor
+  gBoardModuleTokenSpaceGuid.PcdH8S2113SIO
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON
+  gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable
+  gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate
+
+[Sources]
+  PolicyInitDxe.c
+  SaPolicyInitDxe.c
+  SiliconPolicyInitDxe.c
+  GopPolicyInitDxe.c
+  PchPolicyInitDxe.c
+  CpuPolicyInitDxe.c
+  BoardInitLib.c
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gDxeMePolicyGuid                              ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+  gPchPolicyProtocolGuid                        ## CONSUMES
+  gDxeSiPolicyProtocolGuid                      ## PRODUCES
+  gGopPolicyProtocolGuid                        ## PRODUCES
+  gDxeCpuPolicyProtocolGuid                     ## PRODUCES
+
+[Guids]
+  gCpuSmmGuid                                   ## CONSUMES
+  gSiMemoryInfoDataGuid
+
+[Depex]
+  gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
new file mode 100644
index 0000000000..f57bfb8c26
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
@@ -0,0 +1,130 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCI_HOT_PLUG_H_
+#define _PCI_HOT_PLUG_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <Base.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Acpi10.h>
+#include <Protocol/PciHotPlugInit.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+#include <Protocol/SaPolicy.h>
+
+#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U', 'L', 'P')
+
+#define ACPI \
+  { \
+    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 \
+  }
+
+#define PCI(device, function) \
+  { \
+    { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \
+      (UINTN) function, (UINTN) device \
+  }
+
+#define END \
+  { \
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
+  }
+
+#define LPC(eisaid, function) \
+  { \
+    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid), function \
+  }
+
+typedef struct PCIE_HOT_PLUG_DEVICE_PATH {
+  ACPI_HID_DEVICE_PATH      PciRootBridgeNode;
+  PCI_DEVICE_PATH           PciRootPortNode;
+  EFI_DEVICE_PATH_PROTOCOL  EndDeviceNode;
+} PCIE_HOT_PLUG_DEVICE_PATH;
+
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle; // Handle for protocol this driver installs on
+  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  HotPlugInitProtocol;
+} PCI_HOT_PLUG_INSTANCE;
+
+/**
+  This procedure returns a list of Root Hot Plug controllers that require
+  initialization during boot process
+
+  @param[in]  This      The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[out] HpcCount  The number of Root HPCs returned.
+  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+  @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
+  OUT UINTN                             *PhpcCount,
+  OUT EFI_HPC_LOCATION                  **PhpcList
+  );
+
+/**
+  This procedure Initializes one Root Hot Plug Controller
+  This process may casue initialization of its subordinate buses
+
+  @param[in]  This            The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[in]  HpcDevicePath   The Device Path to the HPC that is being initialized.
+  @param[in]  HpcPciAddress   The address of the Hot Plug Controller function on the PCI bus.
+  @param[in]  Event           The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+  @param[out] HpcState        The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+  @retval   EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
+  IN  UINT64                          PhpcPciAddress,
+  IN  EFI_EVENT                       Event, OPTIONAL
+  OUT EFI_HPC_STATE                   *PhpcState
+  );
+
+/**
+  Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+  @param[in]  This           The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
+  @param[in]  HpcPciAddress  The address of the Hot Plug Controller function on the PCI bus.
+  @param[out] HpcState       The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+  @param[out] Padding        This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+  @param[out] Attribute      Describes how padding is accounted for.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
+  IN  UINT64                          PhpcPciAddress,
+  OUT EFI_HPC_STATE                   *PhpcState,
+  OUT VOID                            **Padding,
+  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
new file mode 100644
index 0000000000..b91b0f14bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
@@ -0,0 +1,180 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_SMI_HANDLER_H_
+#define _TBT_SMI_HANDLER_H_
+
+#include <Library/TbtCommonLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/Pci.h>
+
+#ifdef PROGRESS_CODE
+#undef PROGRESS_CODE
+#endif
+
+#define MAX_TBT_DEPTH         6
+
+#define P2P_BRIDGE            (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define BAR_ALIGN(v, a)       ((((v) - 1) | (a)) + 1)
+
+#define CMD_BUS_MASTER        BIT2
+#define CMD_BM_IO             (CMD_BUS_MASTER | BIT0)
+#define CMD_BM_MEM            (CMD_BUS_MASTER | BIT1)
+#define CMD_BM_MEM_IO         (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DEF_CACHE_LINE_SIZE   0x20
+#define DEF_RES_IO_PER_DEV    4
+#define DEF_RES_MEM_PER_DEV   32
+#define DEF_RES_PMEM_PER_DEV  32
+
+#define DOCK_BUSSES           8
+
+#define DISBL_IO_REG1C        0x01F1
+#define DISBL_MEM32_REG20     0x0000FFF0
+#define DISBL_PMEM_REG24      0x0001FFF1
+
+#define count(x)              (sizeof (x) / sizeof ((x)[0]))
+
+#define PCIE_CAP_ID_SSID_SSVID 0x0D
+#define INVALID_PCI_DEVICE    0xFFFFFFFF
+#define PCI_TBT_VESC_REG2     0x510
+
+typedef struct _PortInfo {
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+  UINT8   BusNumLimit;
+  UINT8   ConfedEP;
+} PORT_INFO;
+
+typedef struct _MEM_REGS {
+  UINT32  Base;
+  UINT32  Limit;
+} MEM_REGS;
+
+typedef struct _PMEM_REGS {
+  UINT64  Base64;
+  UINT64  Limit64;
+} PMEM_REGS;
+
+typedef struct _IO_REGS {
+  UINT16  Base;
+  UINT16  Limit;
+} IO_REGS;
+
+typedef struct _BRDG_RES_CONFIG {
+  UINT8   Cmd;
+  UINT8   Cls;
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+} BRDG_RES_CONFIG;
+
+typedef struct _BRDG_CONFIG {
+  DEV_ID          DevId;
+  UINT8           PBus;
+  UINT8           SBus;
+  UINT8           SubBus;
+  BOOLEAN         IsDSBridge;
+  BRDG_RES_CONFIG Res;
+} BRDG_CONFIG;
+
+enum {
+  HR_US_PORT,
+  HR_DS_PORT0,
+  HR_DS_PORT3,
+  HR_DS_PORT4,
+  HR_DS_PORT5,
+  HR_DS_PORT6,
+  MAX_CFG_PORTS
+};
+
+enum {
+  HR_DS_PORT1   = HR_DS_PORT3
+};
+
+//
+// Alpine Ridge
+//
+enum {
+  AR_DS_PORT1 = HR_DS_PORT3,
+  AR_DS_PORT2,
+  AR_DS_PORT3,
+  AR_DS_PORT4
+};
+
+typedef struct _HR_CONFIG {
+  UINT16  DeviceId;
+  UINT8   HRBus;
+  UINT8   MinDSNumber;
+  UINT8   MaxDSNumber;
+  UINT8   BridgeLoops;
+} HR_CONFIG;
+
+STATIC const BRDG_RES_CONFIG  NOT_IN_USE_BRIDGE = {
+  CMD_BUS_MASTER,
+  0,
+  DISBL_IO_REG1C & 0xFF,
+  DISBL_IO_REG1C >> 8,
+  DISBL_MEM32_REG20 & 0xFFFF,
+  DISBL_MEM32_REG20 >> 16,
+  DISBL_PMEM_REG24 & 0xFFFF,
+  DISBL_PMEM_REG24 >> 16
+};
+
+typedef union _BRDG_CIO_MAP_REG {
+  UINT32  AB_REG;
+  struct {
+    UINT32  NumOfDSPorts : 5;
+    UINT32  CioPortMap : 27;
+  } Bits;
+} BRDG_CIO_MAP_REG;
+
+//
+// Functions
+//
+VOID
+ThunderboltCallback (
+  IN UINT8 Type
+  );
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+  IN UINT8 Type
+  );
+
+VOID
+EndOfThunderboltCallback(
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+);
+
+VOID
+ConfigureTbtAspm(
+  IN UINT8       Type,
+  IN UINT16      Aspm
+);
+
+UINT8
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
new file mode 100644
index 0000000000..ac13acc27d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
@@ -0,0 +1,32 @@
+/** @file
+ Header file for board Init function for DXE Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_BOARD_INIT_LIB_H_
+#define _DXE_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+#include <Register/PchRegs.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Platform.h>
+
+EFI_STATUS
+EFIAPI
+BoardConfigInit (
+   VOID
+  );
+
+#endif // _DXE_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
new file mode 100644
index 0000000000..5d0e2777d8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_INIT_DXE_H_
+#define _CPU_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+#include <Protocol/CpuPolicyProtocol.h>
+#include <Library/DxeCpuPolicyUpdateLib.h>
+
+
+/**
+  Initialize Intel CPU DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @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
+CpuPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
new file mode 100644
index 0000000000..ff975efae0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
@@ -0,0 +1,41 @@
+/** @file
+Header file for the GopPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GOP_POLICY_INIT_DXE_H_
+#define _GOP_POLICY_INIT_DXE_H_
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+#include <Library/PcdLib.h>
+
+/**
+Initialize GOP DXE Policy
+
+@param[in] ImageHandle          Image handle of this driver.
+
+@retval EFI_SUCCESS             Initialization complete.
+@retval 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
+GopPolicyInitDxe(
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
new file mode 100644
index 0000000000..1055fed7c8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
@@ -0,0 +1,52 @@
+/** @file
+  Header file for the PchPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_POLICY_INIT_DXE_H_
+#define _PCH_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <FirwmareConfigurations.h>
+#include <Protocol/PchPolicy.h>
+#include <Library/DxePchPolicyLib.h>
+#include <Library/DxePchPolicyUpdateLib.h>
+
+extern UINT8 mFirmwareConfiguration;
+
+/**
+  <b>PCH DXE Policy Driver Entry Point</b> \n
+  - <b>Introduction</b> \n
+    Pch DXE drivers behavior can be controlled by platform policy without modifying reference code directly.
+    Platform policy Protocol is initialized with default settings in this funciton.
+    This policy Protocol has to be initialized prior to PCH initialization DXE drivers execution.
+
+  - @pre
+    - Runtime variable service should be ready if policy initialization required.
+
+  - @result
+    PCH_POLICY_PROTOCOL will be installed successfully and ready for Pch reference code use.
+
+  - <b>Porting Recommendations</b> \n
+    Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+  @param[in] ImageHandle - Image handle of this driver.
+
+  @retval EFI_SUCCESS           Initialization complete.
+  @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
+PchPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
new file mode 100644
index 0000000000..d2aac9823e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
@@ -0,0 +1,45 @@
+/** @file
+  Header file for the PolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POLICY_INIT_DXE_H_
+#define _POLICY_INIT_DXE_H_
+
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include "SaPolicyInitDxe.h"
+#include "PchPolicyInitDxe.h"
+#include "SiliconPolicyInitDxe.h"
+#include "GopPolicyInitDxe.h"
+#include "CpuPolicyInitDxe.h"
+
+#include <Library/DxeTbtPolicyLib.h>
+/**
+  Initialize DXE Platform Policy
+
+  @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
+PolicyInitDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
new file mode 100644
index 0000000000..0f86711e6a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
@@ -0,0 +1,56 @@
+/** @file
+  Header file for the SaPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_INIT_DXE_H_
+#define _SA_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <FirwmareConfigurations.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/DxeSaPolicyLib.h>
+#include <Library/DxePolicyBoardConfigLib.h>
+#include <Library/DxeSaPolicyUpdateLib.h>
+
+#include <SaAccess.h>
+
+extern UINT8 mFirmwareConfiguration;
+
+/**
+  <b>SA DXE Policy Driver Entry Point</b> \n
+  - <b>Introduction</b> \n
+    System Agent DXE drivers behavior can be controlled by platform policy without modifying reference code directly.
+    Platform policy Protocol is initialized with default settings in this funciton.
+    This policy Protocol has to be initialized prior to System Agent initialization DXE drivers execution.
+
+  - @pre
+    - Runtime variable service should be ready if policy initialization required.
+
+  - @result
+    SA_POLICY_PROTOCOL will be installed successfully and ready for System Agent reference code use.
+
+  - <b>Porting Recommendations</b> \n
+    Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+  @param[in] ImageHandle - Image handle of this driver.
+
+  @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
+SaPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
new file mode 100644
index 0000000000..a2c5f548fa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SILICON_POLICY_INIT_DXE_H_
+#define _SILICON_POLICY_INIT_DXE_H_
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Protocol/SiPolicyProtocol.h>
+
+/**
+  Initilize Intel CPU DXE Policy
+
+  @param[in] ImageHandle             Image handle of this driver.
+
+  @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
+SiliconPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
new file mode 100644
index 0000000000..1ff129c307
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
@@ -0,0 +1,96 @@
+/** @file
+  Acpi Gnvs Init Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <PchAccess.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/MpService.h>
+
+/**
+@brief
+  Global NVS initialize.
+
+  @param[in] GlobalNvs         - Pointer of Global NVS area
+
+  @retval EFI_SUCCESS          - Allocate Global NVS completed.
+  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGnvsInit (
+  IN OUT VOID                   **GlobalNvs
+  )
+{
+  UINTN                         Pages;
+  EFI_PHYSICAL_ADDRESS          Address;
+  EFI_STATUS                    Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GNVS;
+  EFI_MP_SERVICES_PROTOCOL      *MpService;
+  UINTN                         NumberOfCPUs;
+  UINTN                         NumberOfEnabledCPUs;
+
+  Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
+  Address = 0xffffffff; // allocate address below 4G.
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Locate the MP services protocol
+  // Find the MP Protocol. This is an MP platform, so MP protocol must be there.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiMpServiceProtocolGuid,
+                  NULL,
+                  (VOID **) &MpService
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Determine the number of processors
+  //
+  MpService->GetNumberOfProcessors (
+              MpService,
+              &NumberOfCPUs,
+              &NumberOfEnabledCPUs
+              );
+
+  *GlobalNvs = (VOID *) (UINTN) Address;
+  SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
+
+  //
+  // GNVS default value init here...
+  //
+  GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
+
+  GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
+
+  //
+  // Miscellaneous
+  //
+  GNVS->Area->PL1LimitCS = 0;
+  GNVS->Area->PL1LimitCSValue = 4500;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
new file mode 100644
index 0000000000..cb5f328a39
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
@@ -0,0 +1,290 @@
+/** @file
+  ACPI Platform Driver
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/AcpiTable.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL              mGlobalNvsArea;
+
+/**
+@brief
+  Global NVS initialize.
+
+  @param[in] GlobalNvs         - Pointer of Global NVS area
+
+  @retval EFI_SUCCESS          - Allocate Global NVS completed.
+  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGnvsInit (
+  IN OUT VOID                   **GlobalNvs
+  );
+
+//
+// Function implementations
+//
+
+/**
+  Locate the first instance of a protocol.  If the protocol requested is an
+  FV protocol, then it will return the first FV that contains the ACPI table
+  storage file.
+
+  @param[in] Protocol           The protocol to find.
+  @param[in] Instance           Return pointer to the first instance of the protocol.
+  @param[in] Type               TRUE if the desired protocol is a FV protocol.
+
+  @retval EFI_SUCCESS           The function completed successfully.
+  @retval EFI_NOT_FOUND         The protocol could not be located.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
+**/
+EFI_STATUS
+LocateSupportProtocol (
+  IN     EFI_GUID                      *Protocol,
+  IN     EFI_GUID                      *gEfiAcpiMultiTableStorageGuid,
+     OUT VOID                          **Instance,
+  IN     BOOLEAN                       Type
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *HandleBuffer;
+  UINTN                   NumberOfHandles;
+  EFI_FV_FILETYPE         FileType;
+  UINT32                  FvStatus;
+  EFI_FV_FILE_ATTRIBUTES  Attributes;
+  UINTN                   Size;
+  UINTN                   Index;
+
+  //
+  // Locate protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  Protocol,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // Defined errors at this time are not found and out of resources.
+    //
+    return Status;
+  }
+
+  //
+  // Looking 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],
+                    Protocol,
+                    Instance
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    if (!Type) {
+
+      //
+      // Not looking for the FV protocol, so find the first instance of the
+      // protocol.  There should not be any errors because our handle buffer
+      // should always contain at least one or LocateHandleBuffer would have
+      // returned not found.
+      //
+      break;
+    }
+    //
+    // See if it has the ACPI storage file
+    //
+    Size      = 0;
+    FvStatus  = 0;
+    Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile (
+                                                              *Instance,
+                                                              gEfiAcpiMultiTableStorageGuid,
+                                                              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);
+
+  return Status;
+}
+
+EFI_STATUS
+PublishAcpiTablesFromFv (
+  IN EFI_GUID *gEfiAcpiMultiTableStorageGuid
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+  UINTN                         TableHandle;
+  INTN                          Instance;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+
+  Instance      = 0;
+  TableHandle   = 0;
+  CurrentTable  = NULL;
+  FwVol         = NULL;
+
+  //
+  // Find the AcpiSupport protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiMultiTableStorageGuid,
+            (VOID **) &AcpiTable,
+            FALSE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiAcpiMultiTableStorageGuid,
+            (VOID **) &FwVol,
+            TRUE
+            );
+
+  //
+  // Read tables from the storage file.
+  //
+
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      gEfiAcpiMultiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // Add the table
+      //
+      TableHandle = 0;
+
+      Status = AcpiTable->InstallAcpiTable (
+                            AcpiTable,
+                            CurrentTable,
+                            CurrentTable->Length,
+                            &TableHandle
+                            );
+
+
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Increment the instance
+      //
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  //
+  // Finished
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+  ACPI Platform driver installation function.
+
+  @param[in] ImageHandle     Handle for this drivers loaded image protocol.
+  @param[in] SystemTable     EFI system table.
+
+  @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
+EFIAPI
+InstallAcpiBoard (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS   Status;
+  EFI_HANDLE   Handle;
+
+  AcpiGnvsInit((VOID **) &mGlobalNvsArea.Area);
+
+  //
+  // This PCD set must be done before PublishAcpiTablesFromFv.
+  // The PCD data will be used there.
+  //
+  PcdSet64S (PcdAcpiGnvsAddress, (UINT64)(UINTN)mGlobalNvsArea.Area);
+
+  //
+  // Platform ACPI Tables
+  //
+  PublishAcpiTablesFromFv (&gEfiCallerIdGuid);
+
+  //
+  // This protocol publish must be done after PublishAcpiTablesFromFv.
+  // The NVS data is be updated there.
+  //
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  &mGlobalNvsArea,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
new file mode 100644
index 0000000000..2b36475c53
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
@@ -0,0 +1,353 @@
+/** @file
+  Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
+  Devics resource configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "PciHotPlug.h"
+#include <Ppi/SiPolicy.h>
+#include <TbtBoardInfo.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+
+#define PCIE_NUM  (20)
+#define PEG_NUM   (3)
+#define PADDING_BUS (1)
+#define PADDING_NONPREFETCH_MEM (1)
+#define PADDING_PREFETCH_MEM (1)
+#define PADDING_IO (1)
+#define PADDING_NUM (PADDING_BUS + PADDING_NONPREFETCH_MEM + PADDING_PREFETCH_MEM + PADDING_IO)
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HPC_LOCATION          mPcieLocation[PCIE_NUM + PEG_NUM];
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mHpcCount = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_HOT_PLUG_DEVICE_PATH mHotplugPcieDevicePathTemplate = {
+  ACPI,
+  PCI(0xFF, 0xFF), // Dummy Device no & Function no
+  END
+};
+
+/**
+  Entry point for the driver.
+
+  This routine reads the PlatformType GPI on FWH and produces a protocol
+  to be consumed by the chipset driver to effect those settings.
+
+  @param[in]  ImageHandle    An image handle.
+  @param[in]  SystemTable    A pointer to the system table.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+PciHotPlug (
+  IN EFI_HANDLE                   ImageHandle,
+  IN EFI_SYSTEM_TABLE             *SystemTable
+  )
+{
+  EFI_STATUS                       Status;
+  PCI_HOT_PLUG_INSTANCE            *PciHotPlug;
+  UINTN                            Index;
+  UINTN                            RpDev;
+  UINTN                            RpFunc;
+  PCIE_HOT_PLUG_DEVICE_PATH       *HotplugPcieDevicePath;
+  UINT32                           PcieRootPortHpeData = 0;
+
+  DEBUG ((DEBUG_INFO, "PciHotPlug Entry\n"));
+
+  PcieRootPortHpeData = PcdGet32 (PcdPchPcieRootPortHpe);
+  //
+  // PCH Rootports Hotplug device path creation
+  //
+  for (Index = 0; Index < PCIE_NUM; Index++) {
+    if (((PcieRootPortHpeData >> Index) & BIT0) == BIT0) { // Check the Rootport no's hotplug is set
+      Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFunc); // Get the actual device/function no corresponding to the Rootport no provided
+      ASSERT_EFI_ERROR (Status);
+
+      HotplugPcieDevicePath = NULL;
+      HotplugPcieDevicePath = AllocatePool (sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
+      ASSERT (HotplugPcieDevicePath != NULL);
+      if (HotplugPcieDevicePath == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      CopyMem (HotplugPcieDevicePath, &mHotplugPcieDevicePathTemplate, sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
+      HotplugPcieDevicePath->PciRootPortNode.Device = (UINT8) RpDev; // Update real Device no
+      HotplugPcieDevicePath->PciRootPortNode.Function = (UINT8) RpFunc; // Update real Function no
+
+      mPcieLocation[mHpcCount].HpcDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
+      mPcieLocation[mHpcCount].HpbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
+      mHpcCount++;
+
+      DEBUG ((DEBUG_INFO, "(%02d) PciHotPlug (PCH RP#) : Bus 0x00, Device 0x%x, Function 0x%x is added to the Hotplug Device Path list \n", mHpcCount, RpDev, RpFunc));
+    }
+  }
+
+
+  PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE));
+  ASSERT (PciHotPlug != NULL);
+  if (PciHotPlug == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize driver private data.
+  //
+  ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE));
+
+  PciHotPlug->Signature                               = PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE;
+  PciHotPlug->HotPlugInitProtocol.GetRootHpcList      = GetRootHpcList;
+  PciHotPlug->HotPlugInitProtocol.InitializeRootHpc   = InitializeRootHpc;
+  PciHotPlug->HotPlugInitProtocol.GetResourcePadding  = GetResourcePadding;
+
+  Status = gBS->InstallProtocolInterface (
+                  &PciHotPlug->Handle,
+                  &gEfiPciHotPlugInitProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &PciHotPlug->HotPlugInitProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure returns a list of Root Hot Plug controllers that require
+  initialization during boot process
+
+  @param[in]  This      The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[out] HpcCount  The number of Root HPCs returned.
+  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+  @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
+  OUT UINTN                            *HpcCount,
+  OUT EFI_HPC_LOCATION                 **HpcList
+  )
+{
+  *HpcCount = mHpcCount;
+  *HpcList  = mPcieLocation;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure Initializes one Root Hot Plug Controller
+  This process may casue initialization of its subordinate buses
+
+  @param[in]  This            The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[in]  HpcDevicePath   The Device Path to the HPC that is being initialized.
+  @param[in]  HpcPciAddress   The address of the Hot Plug Controller function on the PCI bus.
+  @param[in]  Event           The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+  @param[out] HpcState        The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+  @retval   EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL      *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL            *HpcDevicePath,
+  IN  UINT64                              HpcPciAddress,
+  IN  EFI_EVENT                           Event, OPTIONAL
+  OUT EFI_HPC_STATE                       *HpcState
+  )
+{
+  if (Event) {
+    gBS->SignalEvent (Event);
+  }
+
+  *HpcState = EFI_HPC_STATE_INITIALIZED;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+  @param[in]  This           The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
+  @param[in]  HpcPciAddress  The address of the Hot Plug Controller function on the PCI bus.
+  @param[out] HpcState       The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+  @param[out] Padding        This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+  @param[out] Attribute      Describes how padding is accounted for.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *HpcDevicePath,
+  IN  UINT64                          HpcPciAddress,
+  OUT EFI_HPC_STATE                   *HpcState,
+  OUT VOID                            **Padding,
+  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
+  EFI_STATUS                        Status;
+  UINT8                             RsvdExtraBusNum = 0;
+  UINT16                            RsvdPcieMegaMem = 10;
+  UINT8                             PcieMemAddrRngMax = 0;
+  UINT16                            RsvdPciePMegaMem = 10;
+  UINT8                             PciePMemAddrRngMax = 0;
+  UINT8                             RsvdTbtExtraBusNum = 0;
+  UINT16                            RsvdTbtPcieMegaMem = 10;
+  UINT8                             TbtPcieMemAddrRngMax = 0;
+  UINT16                            RsvdTbtPciePMegaMem = 10;
+  UINT8                             TbtPciePMemAddrRngMax = 0;
+  UINT8                             RsvdPcieKiloIo = 4;
+  BOOLEAN                           SetResourceforTbt = FALSE;
+  UINTN                             RpIndex;
+  UINTN                             RpDev;
+  UINTN                             RpFunc;
+
+DEBUG ((DEBUG_INFO, "GetResourcePadding : Start \n"));
+
+  PaddingResource = AllocatePool (PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  ASSERT (PaddingResource != NULL);
+  if (PaddingResource == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *Padding = (VOID *) PaddingResource;
+
+  RpDev = (UINTN) ((HpcPciAddress >> 16) & 0xFF);
+  RpFunc = (UINTN) ((HpcPciAddress >> 8) & 0xFF);
+
+  // Get the actual Rootport no corresponding to the device/function no provided
+  if (RpDev == SA_PEG_DEV_NUM) {
+    // PEG
+    RpIndex = PCIE_NUM + RpFunc;
+    DEBUG ((DEBUG_INFO, "GetResourcePadding : PEG Rootport no %02d Bus 0x00, Device 0x%x, Function 0x%x \n", (RpIndex-PCIE_NUM), RpDev, RpFunc));
+  } else {
+    // PCH
+    Status = GetPchPcieRpNumber (RpDev, RpFunc, &RpIndex);
+    DEBUG ((DEBUG_INFO, "GetResourcePadding : PCH Rootport no %02d Bus 0x00, Device 0x%x, Function 0x%x \n", RpIndex, RpDev, RpFunc));
+  }
+
+  GetRootporttoSetResourcesforTbt(RpIndex, &RsvdTbtExtraBusNum, &RsvdTbtPcieMegaMem ,&TbtPcieMemAddrRngMax ,&RsvdTbtPciePMegaMem ,&TbtPciePMemAddrRngMax, &SetResourceforTbt);
+    if (SetResourceforTbt) {
+      RsvdExtraBusNum = RsvdTbtExtraBusNum;
+      RsvdPcieMegaMem = RsvdTbtPcieMegaMem;
+      PcieMemAddrRngMax = TbtPcieMemAddrRngMax;
+      RsvdPciePMegaMem = RsvdTbtPciePMegaMem;
+      PciePMemAddrRngMax = TbtPciePMemAddrRngMax;
+    }
+
+  //
+  // Padding for bus
+  //
+  ZeroMem (PaddingResource, PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  *Attributes                   = EfiPaddingPciBus;
+
+  PaddingResource->Desc         = 0x8A;
+  PaddingResource->Len          = 0x2B;
+  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_BUS;
+  PaddingResource->GenFlag      = 0x0;
+  PaddingResource->SpecificFlag = 0;
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrRangeMax = 0;
+  PaddingResource->AddrLen      = RsvdExtraBusNum;
+
+  //
+  // Padding for non-prefetchable memory
+  //
+  PaddingResource++;
+  PaddingResource->Desc                 = 0x8A;
+  PaddingResource->Len                  = 0x2B;
+  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+  PaddingResource->GenFlag              = 0x0;
+    if (SetResourceforTbt) {
+    PaddingResource->AddrSpaceGranularity = 32;
+  } else {
+    PaddingResource->AddrSpaceGranularity = 32;
+  }
+  PaddingResource->SpecificFlag         = 0;
+  //
+  // Pad non-prefetchable
+  //
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
+  if (SetResourceforTbt) {
+    PaddingResource->AddrRangeMax = (1 << PcieMemAddrRngMax) - 1;
+  } else {
+    PaddingResource->AddrRangeMax = 1;
+  }
+
+  //
+  // Padding for prefetchable memory
+  //
+  PaddingResource++;
+  PaddingResource->Desc                 = 0x8A;
+  PaddingResource->Len                  = 0x2B;
+  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+  PaddingResource->GenFlag              = 0x0;
+    if (SetResourceforTbt) {
+    PaddingResource->AddrSpaceGranularity = 32;
+  } else {
+    PaddingResource->AddrSpaceGranularity = 32;
+  }
+  PaddingResource->SpecificFlag         = 06;
+  //
+  // Padding for prefetchable memory
+  //
+  PaddingResource->AddrRangeMin = 0;
+  if (SetResourceforTbt) {
+    PaddingResource->AddrLen      = RsvdPciePMegaMem * 0x100000;
+  } else {
+    PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
+  }
+  //
+  // Pad 16 MB of MEM
+  //
+  if (SetResourceforTbt) {
+    PaddingResource->AddrRangeMax = (1 << PciePMemAddrRngMax) - 1;
+  } else {
+    PaddingResource->AddrRangeMax = 1;
+  }
+  //
+  // Alignment
+  //
+  // Padding for I/O
+  //
+  PaddingResource++;
+  PaddingResource->Desc         = 0x8A;
+  PaddingResource->Len          = 0x2B;
+  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_IO;
+  PaddingResource->GenFlag      = 0x0;
+  PaddingResource->SpecificFlag = 0;
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrLen      = RsvdPcieKiloIo * 0x400;
+  //
+  // Pad 4K of IO
+  //
+  PaddingResource->AddrRangeMax = 1;
+  //
+  // Alignment
+  //
+  // Terminate the entries.
+  //
+  PaddingResource++;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc     = ACPI_END_TAG_DESCRIPTOR;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0;
+
+  *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
new file mode 100644
index 0000000000..c670f23320
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
@@ -0,0 +1,228 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/DxeTbtPolicyLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Protocol/TbtNvsArea.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/PcdLib.h>
+#include <Library/AslUpdateLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL                     mTbtNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB                              *gTbtInfoHob = NULL;
+
+/**
+  TBT NVS Area Initialize
+
+**/
+
+VOID
+TbtNvsAreaInit (
+  IN  VOID              **mTbtNvsAreaPtr
+  )
+{
+  UINTN                         Pages;
+  EFI_PHYSICAL_ADDRESS          Address;
+  EFI_STATUS                    Status;
+  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
+  DXE_TBT_POLICY_PROTOCOL       *DxeTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit Start\n"));
+  Status = gBS->LocateProtocol (
+              &gDxeTbtPolicyProtocolGuid,
+              NULL,
+              (VOID **) &DxeTbtConfig
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  Pages = EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA));
+  Address = 0xffffffff; // allocate address below 4G.
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  ASSERT_EFI_ERROR (Status);
+
+  *mTbtNvsAreaPtr = (VOID *) (UINTN) Address;
+  SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0);
+
+  //
+  // TBTNvsAreaProtocol default value init here
+  //
+  TbtNvsAreaProtocol = (TBT_NVS_AREA_PROTOCOL *) &Address;
+
+  //
+  // Initialize default values
+  //
+  TbtNvsAreaProtocol->Area->WAKFinished             = 0;
+  TbtNvsAreaProtocol->Area->DiscreteTbtSupport      = ((gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1 ) ? TRUE : FALSE);
+  TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport   = 0;
+  TbtNvsAreaProtocol->Area->TbtGpioFilter           = (UINT8) DxeTbtConfig->TbtCommonConfig.Gpio5Filter;
+//  TbtNvsAreaProtocol->Area->TrOsup                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TrA0OsupWa;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrEn             = gTbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr;
+  TbtNvsAreaProtocol->Area->TbtAspm                 = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAspm;
+//  TbtNvsAreaProtocol->Area->TbtL1SubStates          = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtL1SubStates;
+  TbtNvsAreaProtocol->Area->TbtSetClkReq            = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtSetClkReq;
+  TbtNvsAreaProtocol->Area->TbtLtr                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtLtr;
+//  TbtNvsAreaProtocol->Area->TbtPtm                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtPtm;
+  TbtNvsAreaProtocol->Area->TbtWakeupSupport        = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport;
+  TbtNvsAreaProtocol->Area->TbtAcDcSwitch           = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch;
+  TbtNvsAreaProtocol->Area->Rtd3TbtSupport          = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3Tbt;             // TBT RTD3 Enable.
+  TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay         = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay;    // TBT RTD3 Off delay in ms.
+  TbtNvsAreaProtocol->Area->Rtd3TbtClkReq           = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq;       // TBT RTD3 ClkReq Mask Enable.
+  TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay      = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq mask delay in ms.
+  TbtNvsAreaProtocol->Area->TbtWin10Support         = (UINT8) DxeTbtConfig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode
+
+  //
+  // DTBT Controller 1
+  //
+  TbtNvsAreaProtocol->Area->DTbtControllerEn0       = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+  TbtNvsAreaProtocol->Area->RootportSelected0       = gTbtInfoHob-> DTbtControllerConfig.PcieRpNumber;
+  TbtNvsAreaProtocol->Area->RootportSelected0Type   = gTbtInfoHob-> DTbtControllerConfig.Type;
+  TbtNvsAreaProtocol->Area->RootportEnabled0        = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0        = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0     = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+  TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0  = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0       = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0    = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+  TbtNvsAreaProtocol->Area->TBtCommonGpioSupport    = gTbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+
+  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit End\n"));
+}
+
+/**
+  This function gets registered as a callback to patch TBT ASL code
+
+  @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.
+  can we put this also in read me
+**/
+VOID
+EFIAPI
+TbtAcpiEndOfDxeCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Address;
+  UINT16                                Length;
+  UINT32                                Signature;
+
+  Status = InitializeAslUpdateLib ();
+  ASSERT_EFI_ERROR (Status);
+
+  Address = (UINT32) (UINTN) mTbtNvsAreaProtocol.Area;
+  Length  = (UINT16) sizeof (TBT_NVS_AREA);
+  DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x Length %x\n", Address, Length));
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address, sizeof (Address));
+  ASSERT_EFI_ERROR (Status);
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length, sizeof (Length));
+  ASSERT_EFI_ERROR (Status);
+
+  if (gTbtInfoHob != NULL) {
+    if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1) {
+      if (gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting == TRUE) {
+        DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n"));
+        Signature = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+        Status  = UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'), &Signature, sizeof (Signature));
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+
+  return;
+}
+
+/**
+  Initialize Thunderbolt(TM) SSDT ACPI tables
+
+  @retval EFI_SUCCESS    ACPI tables are initialized successfully
+  @retval EFI_NOT_FOUND  ACPI tables not found
+**/
+
+EFI_STATUS
+EFIAPI
+TbtDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              Handle;
+ // EFI_EVENT               EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "TbtDxeEntryPoint \n"));
+
+  //
+  // Get TBT INFO HOB
+  //
+  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+  if (gTbtInfoHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  InstallTbtPolicy (ImageHandle);
+  //
+  // Update DXE TBT Policy
+  //
+  UpdateTbtPolicyCallback ();
+
+  //
+  // Print DXE TBT Policy
+  //
+  TbtPrintDxePolicyConfig ();
+
+  //
+  // Initialize Tbt Nvs Area
+  //
+  TbtNvsAreaInit ((VOID **) &mTbtNvsAreaProtocol.Area);
+
+
+  //
+  // [ACPI] Thunderbolt ACPI table
+  //
+
+
+  Handle = NULL;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gTbtNvsAreaProtocolGuid,
+                  &mTbtNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register an end of DXE event for TBT ACPI to do some patch can be put as description
+  //
+  /**
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  TbtAcpiEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+**/
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
new file mode 100644
index 0000000000..bdd8de0cfd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
@@ -0,0 +1,211 @@
+/** @file
+  Source code file for TBT Init PEI module
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <TbtBoardInfo.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+/*
+/**
+  This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDone
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+
+/**
+  This function pass PEI TBT Policy to Hob at the end of PEI
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+
+EFI_STATUS
+EFIAPI
+PassTbtPolicyToHob (
+VOID
+  )
+{
+  EFI_STATUS            Status;
+  EFI_BOOT_MODE         BootMode;
+  TBT_INFO_HOB          *TbtInfoHob;
+  PEI_TBT_POLICY        *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "PassTbtPolicyToHob\n"));
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+  if (BootMode == BOOT_ON_S3_RESUME ) {
+    return EFI_SUCCESS;
+  }
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Create HOB for TBT Data
+  //
+  Status = PeiServicesCreateHob (
+             EFI_HOB_TYPE_GUID_EXTENSION,
+             sizeof (TBT_INFO_HOB),
+             (VOID **) &TbtInfoHob
+             );
+  DEBUG ((DEBUG_INFO, "TbtInfoHob Created \n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize the TBT INFO HOB data.
+  //
+  TbtInfoHob->EfiHobGuidType.Name = gTbtInfoHobGuid;
+
+  //
+  // Update DTBT Policy
+  //
+  TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn = PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn;
+  TbtInfoHob-> DTbtControllerConfig.Type = PeiTbtConfig-> DTbtControllerConfig.Type;
+  TbtInfoHob-> DTbtControllerConfig.PcieRpNumber = PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber;
+  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting;
+  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+  TbtInfoHob->DTbtCommonConfig.TbtBootOn = PeiTbtConfig->DTbtCommonConfig.TbtBootOn;
+  TbtInfoHob->DTbtCommonConfig.TbtUsbOn = PeiTbtConfig->DTbtCommonConfig.TbtUsbOn;
+  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr;
+  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly;
+  TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration = PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+  TbtInfoHob->DTbtCommonConfig.PcieRstSupport = PeiTbtConfig->DTbtCommonConfig.PcieRstSupport;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function handles TbtInit task at the end of PEI
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+EFI_STATUS
+EFIAPI
+TbtInitEndOfPei (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  BOOLEAN         DTbtExisted;
+  PEI_TBT_POLICY  *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtInitEndOfPei Entry\n"));
+
+  Status       = EFI_SUCCESS;
+  PeiTbtConfig = NULL;
+  DTbtExisted  = FALSE;
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+    if (PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn == 1) {
+      DTbtExisted = TRUE;
+  }
+
+  if (DTbtExisted == TRUE) {
+    //
+    // Call Init function
+    //
+   Status = TbtInit ();
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  TBT Init PEI module entry point
+
+  @param[in]  FileHandle           Not used.
+  @param[in]  PeiServices          General purpose services available to every PEIM.
+
+  @retval     EFI_SUCCESS          The function completes successfully
+  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+EFIAPI
+TbtInitEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS     Status;
+
+  DEBUG ((DEBUG_INFO, "TBT PEI EntryPoint\n"));
+
+  //
+  // Install PEI TBT Policy
+  //
+  Status = InstallPeiTbtPolicy ();
+  ASSERT_EFI_ERROR (Status);
+
+
+  UpdatePeiTbtPolicy ();
+
+  TbtPrintPeiPolicyConfig ();
+  //
+  // Performing PassTbtPolicyToHob and TbtInitEndOfPei
+  //
+  Status = PassTbtPolicyToHob ();
+
+  Status = TbtInitEndOfPei ();
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
new file mode 100644
index 0000000000..a6bdc6ef9f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
@@ -0,0 +1,1609 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "TbtSmiHandler.h"
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SmmVariable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/PciSegmentLib.h>
+#define MEM_PER_SLOT  (DEF_RES_MEM_PER_DEV << 4)
+#define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
+#define IO_PER_SLOT   (DEF_RES_IO_PER_DEV << 2)
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN                 gDeviceBaseAddress;
+//
+//US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG           HrConfigs[MAX_CFG_PORTS];
+
+extern UINT8                      gCurrentDiscreteTbtRootPort;
+extern UINT8                      gCurrentDiscreteTbtRootPortType;
+
+BOOLEAN isLegacyDevice          = FALSE;
+STATIC UINT8 TbtSegment         = 0;
+
+STATIC
+VOID
+PortInfoInit (
+  IN  OUT PORT_INFO *PortInfo
+  )
+{
+  PortInfo->BusNumLimit = 4;
+}
+
+STATIC
+VOID
+UnsetVesc (
+  IN       UINT8     Bus,
+  IN       UINT8     Dev,
+  IN       UINT8     Fun
+  )
+{
+  UINT8 Dbus;
+  UINT32 Data32;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+
+  //
+  // Check for abcence of DS bridge
+  //
+  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+    return;
+  }
+
+  //
+  // Unset vesc_reg2[23] bit (to have an option to access below DS)
+  //
+  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+  Data32 &= 0xFF7FFFFF;
+  PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+  //
+  // Go to Device behind DS
+  //
+  Dbus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
+  //
+  // Check if there is something behind this Downstream Port (Up or Ep)
+  // If there nothing  behind Downstream Port Set vesc_reg2[23] bit -> this will flush all future MemWr
+  //
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus, 0x00, 0x00, 0);
+  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET))
+  {
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+  Data32 |= 0x00800000;
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+  }
+}// Unset_VESC_REG2
+
+STATIC
+UINT16
+MemPerSlot (
+  IN    UINT16 CurrentUsage
+  )
+{
+  if (CurrentUsage == 0) {
+    return 0;
+  }
+
+  if (CurrentUsage <= 16) {
+    return 16;
+  }
+
+  if (CurrentUsage <= 64) {
+    return 64;
+  }
+
+  if (CurrentUsage <= 128) {
+    return 128;
+  }
+
+  if (CurrentUsage <= 256) {
+    return 256;
+  }
+
+  if (CurrentUsage <= 512) {
+    return 512;
+  }
+
+  if (CurrentUsage <= 1024) {
+    return 1024;
+  }
+
+  return CurrentUsage;
+} // MemPerSlot
+
+STATIC
+UINT64
+PMemPerSlot (
+  IN    UINT64 CurrentUsage
+  )
+{
+  if (CurrentUsage == 0) {
+    return 0;
+  }
+
+  if (CurrentUsage <= 1024ULL) {
+    return 1024ULL;
+  }
+
+  if (CurrentUsage <= 4096ULL) {
+    return 4096ULL;
+  }
+
+  return CurrentUsage;
+} // PMemPerSlot
+
+STATIC
+VOID
+SetPhyPortResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      SubBus,
+  IN       INT8       Depth,
+  IN       PORT_INFO  *CurrentPi,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8   Cmd;
+  UINT16  DeltaMem;
+  UINT64  DeltaPMem;
+
+  Cmd               = CMD_BUS_MASTER;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0x00, 0);
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+  DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
+  if (isLegacyDevice) {
+    if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
+      PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
+    }
+  } else {
+    if (DeltaMem < MemPerSlot (DeltaMem)) {
+      PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
+    }
+  }
+
+  if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase - 0x10) <= PortInfo->MemLimit) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), CurrentPi->MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+    PortInfo->MemBase = CurrentPi->MemBase;
+  }
+
+  DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
+  if (isLegacyDevice) {
+    if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
+      PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
+    }
+  } else {
+    if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
+      PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
+    }
+  }
+
+  if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 && (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10) & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10) >> 16));
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+    PortInfo->PMemBase64 = CurrentPi->PMemBase64;
+  }
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetPhyPortResources
+
+STATIC
+UINT32
+SaveSetGetRestoreBar (
+  IN  UINTN  Bar
+  )
+{
+  UINT32  BarReq;
+  UINT32  OrigBar;
+
+  OrigBar = PciSegmentRead32(Bar);     // Save BAR
+  PciSegmentWrite32(Bar, 0xFFFFFFFF);  // Set BAR
+  BarReq = PciSegmentRead32(Bar);      // Get BAR
+  PciSegmentWrite32(Bar, OrigBar);     // Restore BAR
+
+  return BarReq;
+} // SaveSetGetRestoreBar
+
+STATIC
+VOID
+SetIoBar (
+  IN            UINTN    BAR,
+  IN            UINT32   BarReq,
+  IN  OUT       UINT8    *Cmd,
+  IN  OUT       IO_REGS  *IoReg
+  )
+{
+  UINT16  Alignment;
+  UINT16  Size;
+  UINT16  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFC);
+  Size      = Alignment + 1;
+
+  if (IoReg->Base > IoReg->Limit || !Size) {
+    return ;
+
+  }
+
+  NewBase = BAR_ALIGN (IoReg->Base, Alignment);
+  if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
+    return ;
+
+  }
+  PciSegmentWrite16(BAR, NewBase);
+  IoReg->Base = NewBase + Size; // Advance to new position
+  *Cmd      |= CMD_BM_IO; // Set Io Space Enable
+} // SetIoBar
+
+STATIC
+VOID
+SetMemBar (
+  IN            UINTN     BAR,
+  IN            UINT32    BarReq,
+  IN  OUT       UINT8     *Cmd,
+  IN  OUT       MEM_REGS  *MemReg
+  )
+{
+  UINT32  Alignment;
+  UINT32  Size;
+  UINT32  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFFFFF0);
+  Size      = Alignment + 1;
+
+  if (MemReg->Base > MemReg->Limit || !Size) {
+    return ;
+
+  }
+
+  NewBase = BAR_ALIGN (MemReg->Base, Alignment);
+  if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
+    return ;
+
+  }
+
+  PciSegmentWrite32(BAR, NewBase);
+  MemReg->Base = NewBase + Size; // Advance to new position
+  *Cmd       |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetMemBar
+
+STATIC
+VOID
+SetPMem64Bar (
+  IN              UINTN      BAR,
+  IN              BOOLEAN    IsMaxBar,
+  IN              UINT32     BarReq,
+  IN    OUT       UINT8      *Cmd,
+  IN    OUT       PMEM_REGS  *MemReg
+  )
+{
+  UINT32  Alignment;
+  UINT32  Size;
+  UINT64  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFFFFF0);
+  Size      = Alignment + 1;
+
+  if (MemReg->Base64 > MemReg->Limit64 || !Size) {
+    return ;
+  }
+
+  NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
+  if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64) {
+    return ;
+  }
+  PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
+  if (!IsMaxBar) {
+    BAR++;
+    PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
+  }
+  MemReg->Base64 = NewBase + Size; // Advance to new position
+  *Cmd         |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetPMem64Bar
+
+STATIC
+VOID
+SetDevResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      MaxFun,  // PCI_MAX_FUNC for devices, 1 for bridge
+  IN       UINT8      MaxBar,     // PCI_BAR5 for devices, PCI_BAR1 for bridge
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8     Fun;
+  UINT8     Reg;
+  UINT32    BarReq;
+  IO_REGS   Io;
+  MEM_REGS  Mem;
+  PMEM_REGS PMem;
+  UINT8     Cmd;
+
+  Io.Base       = PortInfo->IoBase << 8;
+  Io.Limit      = (PortInfo->IoLimit << 8) | 0xFF;
+  Mem.Base      = PortInfo->MemBase << 16;
+  Mem.Limit     = (PortInfo->MemLimit << 16) | 0xFFFF;
+  PMem.Base64   = PortInfo->PMemBase64 << 16;
+  PMem.Limit64  = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
+
+  for (Fun = 0; Fun < MaxFun; ++Fun) {
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+    Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+
+    }
+
+    for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
+      BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform BAR sizing
+
+      if (BarReq & BIT0) {
+        //
+        // I/O BAR
+        //
+        SetIoBar (
+         (gDeviceBaseAddress + Reg),
+          BarReq,
+          &Cmd,
+          &Io
+          );
+        continue;
+      }
+
+      if (BarReq & BIT3) {
+        //
+        // P-Memory BAR
+        //
+        SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq, &Cmd, &PMem);
+      } else {
+        SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
+      }
+
+      if (BIT2 == (BarReq & (BIT2 | BIT1))) {
+        //
+        // Base address is 64 bits wide
+        //
+        Reg += 4;
+        if (!(BarReq & BIT3)) {
+          //
+          // 64-bit memory bar
+          //
+          PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
+        }
+      }
+    }
+
+    if (Cmd & BIT1) {
+      //
+      // If device uses I/O and MEM mapping use only MEM mepping
+      //
+      Cmd &= ~BIT0;
+    }
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+  }
+  //
+  // Update PortInfo if any changes
+  //
+  if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
+    PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
+  }
+
+  if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
+    PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
+  }
+
+  if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
+    PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
+  }
+} // SetDevResources
+
+STATIC
+VOID
+InitARHRConfigs(
+  IN HR_CONFIG *Hr_Config,
+  IN UINT8 BusNumLimit,
+  IN OUT BRDG_RES_CONFIG* HrResConf
+)
+{
+  UINT8 i,j;
+
+  //
+  // DS port for USB device
+  //
+  HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
+  HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
+  HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
+  HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+  HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+  //
+  // CIO port
+  //
+  HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
+  HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
+  HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
+  HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
+  HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
+
+  switch(Hr_Config->DeviceId)
+  {
+    //
+    // HR with 1 DS and 1 USB
+    //
+    case AR_HR_2C:
+    case AR_HR_LP:
+    case AR_HR_C0_2C:
+    case TR_HR_2C:
+      Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
+      Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
+      Hr_Config->BridgeLoops = 4;
+      break;
+    //
+    // HR with 2 DS and 1 USB
+    //
+    case AR_HR_4C:
+    case TR_HR_4C:
+    case AR_HR_C0_4C:
+      Hr_Config->MinDSNumber = 1;
+      Hr_Config->MaxDSNumber = 4;
+      Hr_Config->BridgeLoops = 6;
+      for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i)
+      {
+        HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+        HrConfigs[j].DevId.Dev = i;
+        HrConfigs[j].DevId.Fun = 0;
+        HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
+        HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
+      }
+    break;
+  }
+}//InitARHRConfigs
+
+
+STATIC
+VOID
+InitCommonHRConfigs (
+  IN       HR_CONFIG        *Hr_Config,
+  IN       UINT8            BusNumLimit,
+  IN  OUT  BRDG_RES_CONFIG  *HrResConf
+  )
+{
+  UINT8 i;
+
+  UINT8 j;
+  for(i = 0; i < count(HrConfigs); ++i) {
+    HrConfigs[i].IsDSBridge = TRUE;
+  }
+  //
+  // US(HRBus:0:0)
+  //
+  HrConfigs[HR_US_PORT].DevId.Bus   = Hr_Config->HRBus;
+  HrConfigs[HR_US_PORT].DevId.Dev   = 0;
+  HrConfigs[HR_US_PORT].DevId.Fun   = 0;
+  HrConfigs[HR_US_PORT].Res         = *HrResConf;
+  HrConfigs[HR_US_PORT].Res.IoBase  = 0xF1;
+  HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
+  HrConfigs[HR_US_PORT].PBus        = HrConfigs[HR_US_PORT].DevId.Bus;
+  HrConfigs[HR_US_PORT].SBus        = HrConfigs[HR_US_PORT].PBus + 1;
+  HrConfigs[HR_US_PORT].SubBus      = BusNumLimit;
+  HrConfigs[HR_US_PORT].IsDSBridge  = FALSE;
+
+  //
+  // HIA resides here
+  //
+  HrConfigs[HR_DS_PORT0].DevId.Bus    = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[HR_DS_PORT0].DevId.Dev    = 0;
+  HrConfigs[HR_DS_PORT0].DevId.Fun    = 0;
+  HrConfigs[HR_DS_PORT0].Res          = NOT_IN_USE_BRIDGE;
+  HrConfigs[HR_DS_PORT0].Res.MemBase  = HrResConf->MemLimit;
+  HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
+  HrResConf->MemLimit                -= 0x10; //This 1 MB chunk will be used by HIA
+  HrConfigs[HR_DS_PORT0].Res.Cmd      = CMD_BM_MEM;
+  HrConfigs[HR_DS_PORT0].Res.Cls      = DEF_CACHE_LINE_SIZE;
+  HrConfigs[HR_DS_PORT0].PBus         = HrConfigs[HR_DS_PORT0].DevId.Bus;
+  HrConfigs[HR_DS_PORT0].SBus         = HrConfigs[HR_DS_PORT0].PBus + 1;
+  HrConfigs[HR_DS_PORT0].SubBus       = HrConfigs[HR_DS_PORT0].PBus + 1;
+
+  switch (Hr_Config->DeviceId) {
+  //
+  // Alpine Ridge
+  //
+  case AR_HR_2C:
+  case AR_HR_C0_2C:
+  case AR_HR_LP:
+  case AR_HR_4C:
+  case AR_HR_C0_4C:
+  //
+  // Titan Ridge
+  //
+  case TR_HR_2C:
+  case TR_HR_4C:
+    InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
+    break;
+
+  default:
+    //
+    // DS(HRBus+2:3-6:0)
+    //
+    Hr_Config->MinDSNumber  = 3;
+    Hr_Config->MaxDSNumber  = 6;
+    Hr_Config->BridgeLoops  = count (HrConfigs);
+
+    for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i) {
+      HrConfigs[j].DevId.Bus  = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+      HrConfigs[j].DevId.Dev  = i;
+      HrConfigs[j].DevId.Fun  = 0;
+      HrConfigs[j].PBus       = HrConfigs[j].DevId.Bus;
+      HrConfigs[j].Res.Cls    = DEF_CACHE_LINE_SIZE;
+    }
+  }
+} // InitCommonHRConfigs
+
+STATIC
+VOID
+InitHRDSPort_Disable (
+  IN       UINT8        id,
+  IN  OUT  BRDG_CONFIG  *BrdgConf
+  )
+{
+  HrConfigs[id].Res     = NOT_IN_USE_BRIDGE;
+  HrConfigs[id].SBus    = BrdgConf->SBus;
+  HrConfigs[id].SubBus  = BrdgConf->SBus;
+
+  BrdgConf->SBus++;
+} // InitHRDSPort_Disable
+
+//AR only
+
+STATIC
+VOID
+InitARDSPort_1Port(
+  IN  OUT  BRDG_CONFIG* BrdgConf
+)
+{
+  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
+  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
+
+  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+  HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
+  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+}//InitARDSPort_1Port
+
+STATIC
+VOID
+InitARDSPort_2Port(
+  IN OUT BRDG_CONFIG* BrdgConf
+)
+{
+  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
+  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
+
+  // Busses are split between ports 1 and 4
+  BusRange /= 2;
+
+  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+  HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
+  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
+  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
+  HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
+  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+
+
+  HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
+  HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
+  HrConfigs[AR_DS_PORT4].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+  HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
+}//InitARDSPort_2Port
+
+
+STATIC
+BOOLEAN
+CheckLimits (
+  IN    BOOLEAN          Is2PortDev,
+  IN    BRDG_RES_CONFIG  *HrResConf,
+  IN    UINT8            BusRange
+  )
+{
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+
+  MemBase     = HrResConf->MemBase & 0xFFF0;
+  MemLimit    = HrResConf->MemLimit & 0xFFF0;
+  PMemBase64  = HrResConf->PMemBase64 & 0xFFF0;
+  PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
+  //
+  // Check memoty alignment
+  //
+  if (MemBase & 0x3FF) {
+    DEBUG((DEBUG_INFO, "M alig\n"));
+    return FALSE;
+  }
+
+  if (PMemBase64 & 0xFFF) {
+    DEBUG((DEBUG_INFO, "PM alig\n"));
+    return FALSE;
+  }
+
+  if (Is2PortDev) {
+    //
+    // Check mem size
+    //
+    if (MemLimit + 0x10 - MemBase < 0x2E00) {
+      DEBUG((DEBUG_INFO, "M size\n"));
+      return FALSE;
+    }
+    //
+    // Check P-mem size
+    //
+    if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
+      DEBUG((DEBUG_INFO, "PM size\n"));
+      return FALSE;
+    }
+    //
+    // Check bus range
+    //
+    if (BusRange < 106) {
+      DEBUG((DEBUG_INFO, "Bus range\n"));
+      return FALSE;
+    }
+  } else {
+    //
+    // Check mem size
+    //
+    if (MemLimit + 0x10 - MemBase < 0x1600) {
+      DEBUG((DEBUG_INFO, "M size\n"));
+      return FALSE;
+    }
+    //
+    // Check P-mem size
+    //
+    if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
+      DEBUG((DEBUG_INFO, "PM size\n"));
+      return FALSE;
+    }
+    //
+    // Check bus range
+    //
+    if (BusRange < 56) {
+      DEBUG((DEBUG_INFO, "Bus range\n"));
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+} // CheckLimits
+
+STATIC
+BOOLEAN
+InitHRResConfigs (
+  IN  OUT HR_CONFIG      *Hr_Config,
+  IN    UINT8            BusNumLimit,
+  IN  OUT BRDG_RES_CONFIG*HrResConf
+  )
+{
+  BRDG_CONFIG  BrdgConf = { { 0 } };
+
+  InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
+  BrdgConf.PBus   = Hr_Config->HRBus + 2;// Take into account busses
+  BrdgConf.SBus   = Hr_Config->HRBus + 3;// for US and DS of HIA
+  BrdgConf.SubBus = BusNumLimit;
+  BrdgConf.Res    = *HrResConf;
+  while (TRUE) {
+    switch (Hr_Config->DeviceId) {
+    case AR_HR_4C:
+    case TR_HR_4C:
+    case AR_HR_C0_4C:
+      //
+      // 2 Port host
+      //
+      if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
+
+
+          InitARDSPort_2Port(&BrdgConf);
+          DEBUG((DEBUG_INFO, "AR2\n"));
+
+        return TRUE;
+      } else {
+       return FALSE;
+      }
+    // AR only
+  case AR_HR_2C: // 1 port host
+  case AR_HR_C0_2C:
+  case AR_HR_LP:
+  case TR_HR_2C:
+    DEBUG((DEBUG_INFO, "AR1\n"));
+    InitARDSPort_1Port(&BrdgConf);
+    return TRUE;
+
+    default:
+      InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
+      return FALSE;
+    }
+  }
+} // InitHRResConfigs
+
+STATIC
+BOOLEAN
+InitializeHostRouter (
+  OUT  HR_CONFIG  *Hr_Config,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8           BusNumLimit;
+  BRDG_RES_CONFIG HrResConf = { 0 };
+  UINT8           i;
+  BOOLEAN         Ret;
+
+  Ret = TRUE;
+
+  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  Hr_Config->HRBus    = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, Hr_Config->HRBus, 0x00, 0x00, 0);
+  Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
+    return FALSE;
+  }
+  TbtSegment = (UINT8)RpSegment;
+
+  HrResConf.Cmd          = CMD_BM_MEM;
+  HrResConf.Cls          = DEF_CACHE_LINE_SIZE;
+  gDeviceBaseAddress      = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  HrResConf.IoBase       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+  HrResConf.IoLimit      = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+  HrResConf.MemBase      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+  HrResConf.MemLimit     = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+  HrResConf.PMemBase64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
+  HrResConf.PMemLimit64  = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
+  HrResConf.PMemBase64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+  HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+  BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+
+  Ret         = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
+
+  for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+    UINT8 Bus;
+    UINT8 Dev;
+    UINT8 Fun;
+    Bus               = HrConfigs[i].DevId.Bus;
+    Dev               = HrConfigs[i].DevId.Dev;
+    Fun               = HrConfigs[i].DevId.Fun;
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, HrConfigs[i].Res.Cls);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64 >> 16));
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), HrConfigs[i].Res.IoBase);
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, HrConfigs[i].Res.Cmd);
+  }
+  if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C || Hr_Config->DeviceId == AR_HR_LP) {
+    for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+      if(HrConfigs[i].IsDSBridge) {
+        UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev, HrConfigs[i].DevId.Fun);
+      }
+    }
+  }
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+  return Ret;
+} // InitializeHostRouter
+STATIC
+UINT8
+ConfigureSlot (
+  IN       UINT8      Bus,
+  IN       UINT8      MAX_DEVICE,
+  IN       INT8       Depth,
+  IN       BOOLEAN    ArPcie,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8      Device;
+  UINT8      SBus;
+  UINT8      UsedBusNumbers;
+  UINT8      RetBusNum;
+  PORT_INFO  CurrentSlot;
+
+  RetBusNum = 0;
+
+  for (Device = 0; Device < MAX_DEVICE; Device++) {
+    //
+    // Continue if device is absent
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, 0x00, 0);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+
+    }
+
+    if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+      SetDevResources (
+        Bus,
+        Device,
+        PCI_MAX_FUNC,
+        PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
+        PortInfo
+        );
+      continue;
+    }
+    //
+    // Else Bridge
+    //
+    CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
+
+    ++RetBusNum; // UP Bridge
+    SBus = Bus + RetBusNum; // DS Bridge
+
+    if (SBus + 1 >= PortInfo->BusNumLimit) {
+      continue;
+
+    }
+
+    SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), PortInfo);
+
+    //
+    // Init UP Bridge to reach DS Bridge
+    //
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+
+  if(ArPcie) {
+    UnsetVesc(Bus, Device, 0x00);
+  }
+
+  UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+  RetBusNum += UsedBusNumbers;
+
+    SetPhyPortResources (
+      Bus,
+      Device,
+      SBus + UsedBusNumbers,
+      Depth,
+      &CurrentSlot,
+      PortInfo
+      );
+  }
+  //
+  // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
+  //
+  return RetBusNum;
+} // ConfigureSlot
+
+STATIC
+VOID
+SetCioPortResources (
+  IN       UINT8     Bus,
+  IN       UINT8     Dev,
+  IN       UINT8     SBus,
+  IN       UINT8     SubBus,
+  IN       PORT_INFO  *portInfoBeforeChange,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8 Cmd;
+  Cmd               = CMD_BUS_MASTER;
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, 0x00, 0);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+  if (PortInfo->IoBase <= PortInfo->IoLimit) {
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), PortInfo->IoBase);
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), PortInfo->IoLimit);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+    Cmd |= CMD_BM_IO;
+  } else {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+  }
+
+  if (PortInfo->MemBase <= PortInfo->MemLimit) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), PortInfo->MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemLimit);
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+  }
+
+  if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+  }
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetCioPortResources
+
+STATIC
+VOID
+SetSlotsAsUnused (
+  IN       UINT8      Bus,
+  IN       UINT8      MaxSlotNum,
+  IN       UINT8      CioSlot,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8 Slot;
+  for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot, 0x00, 0);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+    }
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+    PortInfo->BusNumLimit--;
+  }
+} // SetSlotsAsUnused
+
+STATIC
+UINT16
+FindVendorSpecificHeader(
+  IN  UINT8  Bus
+)
+{
+  PCI_EXP_EXT_HDR   *ExtHdr;
+  UINT32            ExtHdrValue;
+  UINT16            ExtendedRegister;
+
+  ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
+  ExtendedRegister  = 0x100;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  while (ExtendedRegister) {
+    ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress + ExtendedRegister);
+    if (ExtHdr->CapabilityId == 0xFFFF) {
+      return 0x0000; // No Vendor-Specific Extended Capability header
+    }
+
+    if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID == ExtHdr->CapabilityId) {
+      return ExtendedRegister;
+    }
+
+    ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
+  }
+  return 0x0000; // No Vendor-Specific Extended Capability header
+}
+
+STATIC
+UINT8
+FindSsid_SsvidHeader (
+  IN    UINT8  Bus
+  )
+{
+  UINT8 CapHeaderId;
+  UINT8 CapHeaderOffset;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  CapHeaderOffset   = PciSegmentRead8 (gDeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+
+  while (CapHeaderOffset != 0) {
+    CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset);
+
+    if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
+      return CapHeaderOffset;
+    }
+
+    CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset + 1);
+  }
+
+  DEBUG((DEBUG_INFO, "SID0\n"));
+  return 0;
+} // FindSsid_SsvidHeader
+
+STATIC
+BOOLEAN
+GetCioSlotByDevId (
+  IN   UINT8  Bus,
+  OUT  UINT8  *CioSlot,
+  OUT  UINT8  *MaxSlotNum,
+  OUT  BOOLEAN *ArPcie
+  )
+{
+  UINT16            VSECRegister;
+  BRDG_CIO_MAP_REG  BridgMap;
+  UINT32            BitScanRes;
+  UINT16            DevId;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00, 0x00, 0);
+  DevId             = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+
+  //
+  // Init out params in case device is not recognised
+  //
+  *CioSlot    = 4;
+  *MaxSlotNum = 7;
+  *ArPcie     = FALSE;
+
+  switch (DevId) {
+    //
+    // For known device IDs
+    //
+    case 0x1578:
+      *ArPcie = TRUE;
+  }
+
+  switch (DevId) {
+  //
+  // For known device IDs
+  //
+  case 0x1513:
+  case 0x151A:
+  case 0x151B:
+  case 0x1547:
+  case 0x1548:
+    return TRUE; // Just return
+  case 0x1549:
+    return FALSE; // Just return
+  }
+
+  VSECRegister = FindVendorSpecificHeader(Bus);
+  if (!VSECRegister) {
+    return TRUE; // Just return
+  }
+  //
+  // Go to Bridge/CIO map register
+  //
+  VSECRegister += 0x18;
+  BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress + VSECRegister);
+  //
+  // Check for range
+  //
+  if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
+    return TRUE;
+  //
+  // Not a valid register
+  //
+  }
+  //
+  // Set OUT params
+  //
+  *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
+
+#ifdef _MSC_VER
+  if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS bridge which is CIO port
+    return FALSE;
+  }
+#else
+#ifdef __GNUC__
+  if (BridgMap.Bits.CioPortMap == 0) {
+    return FALSE;
+  }
+  BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
+#else
+#error Unsupported Compiler
+#endif
+#endif
+
+  *CioSlot = (UINT8)BitScanRes;
+  return TRUE;
+} // GetCioSlotByDevId
+
+#define TBT_LEGACY_SUB_SYS_ID 0x11112222
+
+STATIC
+BOOLEAN
+IsLegacyDevice (
+  IN    UINT8  Bus
+  )
+{
+  UINT32  Sid;
+  UINT8   SidRegister;
+  UINT16  DevId;
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  DevId             = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  switch (DevId) {
+  //
+  // For known device IDs
+  //
+  case 0x1513:
+  case 0x151A:
+  case 0x151B:
+    DEBUG((DEBUG_INFO, "Legacy "));
+    DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
+    return TRUE;
+    //
+    // Legacy device by Device Id
+    //
+  }
+
+  SidRegister = FindSsid_SsvidHeader(Bus);
+
+  if (!SidRegister) {
+    return TRUE; // May be absent for legacy devices
+  }
+  //
+  // Go to register
+  //
+  SidRegister += 0x4;
+  Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
+  DEBUG((DEBUG_INFO, "SID"));
+  DEBUG((DEBUG_INFO, " = %d\n", Sid));
+
+return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
+} // IsLegacyDevice
+
+STATIC
+VOID
+UnsetVescEp(
+  IN  UINT8     Bus,
+  IN  UINT8     MaxSlotNum
+  )
+{
+  UINT8 i;
+
+  for (i = 0; i <= MaxSlotNum; ++i)
+  {
+    UnsetVesc(Bus, i, 0);
+  }
+}// Unset_VESC_REG2_EP
+
+STATIC
+BOOLEAN
+ConfigureEP (
+  IN       INT8      Depth,
+  IN  OUT  UINT8     *Bus,
+  IN  OUT  PORT_INFO *PortInfo
+  )
+{
+  UINT8      SBus;
+  UINT8      CioSlot;
+  UINT8      MaxSlotNum;
+  BOOLEAN    ArPcie;
+  UINT8      MaxPHYSlots;
+  UINT8      UsedBusNumbers;
+  UINT8      cmd;
+  BOOLEAN    CioSlotPresent;
+  BOOLEAN    Continue;
+  PORT_INFO  PortInfoOrg;
+  UINT8      CioBus;
+
+  CioSlot     = 4;
+  MaxSlotNum  = 7;
+  CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus, 0x00, 0x00, 0);
+  cmd               = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+  // AR ONLY
+  // Endpoint on CIO slot, but not a bridge device
+  if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+    DEBUG((DEBUG_INFO, "UEP\n"));
+    // Check whether EP already configured by examining CMD register
+    if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
+    {
+      DEBUG((DEBUG_INFO, "BMF\n"));
+      return FALSE;
+    }
+    // Configure it as regular PCIe device
+    ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+
+    return FALSE;
+  }
+
+  //
+  // Based on Device ID assign Cio slot and max number of PHY slots to scan
+  //
+  CioSlotPresent  =  GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum, &ArPcie);
+  MaxPHYSlots     = MaxSlotNum;
+  //
+  // Check whether EP already configured by examining CMD register
+  //
+
+  if (cmd & CMD_BUS_MASTER) {
+    //
+    // Yes no need to touch this EP, just move to next one in chain
+    //
+    CioBus = *Bus + 1;
+    if(ArPcie){
+      UnsetVescEp(CioBus, MaxSlotNum);
+    }
+    if (!CioSlotPresent) {
+      //
+      // Cio slot is not present in EP, just return FALSE
+      //
+      DEBUG((DEBUG_INFO, "BMF\n"));
+      return FALSE;
+    }
+    //
+    // Take all resources from Cio slot and return
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus, CioSlot, 0x00, 0);
+    PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+    PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+    PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+    PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+    PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+    PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+    PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+    PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+    PortInfo->PMemLimit64  |= 0xF;
+    //
+    // Jump to next EP
+    //
+    *Bus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    //
+    // Should we continue?
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+    Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+    return Continue;
+  }
+  //
+  // Set is legacy dvice
+  //
+  isLegacyDevice = IsLegacyDevice (*Bus);
+
+  SetCioPortResources (
+    *Bus,
+    0, // Assign all available resources to US port of EP
+    *Bus + 1,
+    PortInfo->BusNumLimit,
+    0,
+    PortInfo
+    );
+
+  SBus = *Bus + 1;// Jump to DS port
+
+  if (CioSlotPresent) {
+    MaxPHYSlots = CioSlot;
+  }
+
+  UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie, PortInfo);
+  if (!CioSlotPresent) {
+    return FALSE;
+    //
+    // Stop resource assignment on this chain
+    //
+  }
+  //
+  // Set rest of slots us unused
+  //
+  SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
+
+  SetCioPortResources (
+    SBus,
+    CioSlot,
+    SBus + UsedBusNumbers + 1,
+    PortInfo->BusNumLimit,
+    &PortInfoOrg,
+    PortInfo
+    );
+  *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
+  if(ArPcie) {
+    UnsetVesc(SBus, CioSlot, 0x00);
+  }
+  if (*Bus > PortInfo->BusNumLimit - 2) {
+    //
+    // In case of bus numbers are exhausted stop enumeration
+    //
+    return FALSE;
+  }
+  //
+  // Check whether we should continue on this chain
+  //
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+  Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  return Continue;
+} // ConfigureEP
+
+STATIC
+VOID
+GetPortResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      Fun,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+  PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+  PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
+  PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
+  PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
+  PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
+  PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+  PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+  PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+  PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+  PortInfo->IoLimit |= 0xF;
+  PortInfo->MemLimit |= 0xF;
+  PortInfo->PMemLimit64 |= 0xF;
+} // GetPortResources
+
+STATIC
+VOID
+ConfigurePort (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      Fun,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  INT8  i;
+  UINT8 USBusNum;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+  USBusNum          = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, USBusNum, 0x00, 0x00, 0);
+  if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+    //
+    // Nothing to do if TBT device is not connected
+    //
+    return ;
+  }
+
+  GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from DS port
+  //
+  // Assign resources to EPs
+  //
+  for (i = 0; i < MAX_TBT_DEPTH; ++i) {
+    PortInfo->ConfedEP++;
+    if (!ConfigureEP (i, &USBusNum, PortInfo)) {
+      return ;
+    }
+  }
+} // ConfigurePort
+
+VOID
+ThunderboltCallback (
+  IN UINT8 Type
+  )
+{
+  PORT_INFO                     PortInfoOrg  = { 0 };
+  HR_CONFIG                     HrConfig  = { 0 };
+  UINT8                         i;
+  UINTN                         Segment = 0;
+  UINTN                         Bus = 0;
+  UINTN                         Device;
+  UINTN                         Function;
+
+  DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
+
+  DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
+  PortInfoInit (&PortInfoOrg);
+  if(Type == DTBT_CONTROLLER) {
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+      return;
+    }
+    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+    DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
+    if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
+      return ;
+    }
+  //
+  // Configure DS ports
+  //
+  for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
+    DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
+    ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
+  }
+
+  DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
+  EndOfThunderboltCallback (Segment, Bus, Device, Function);
+
+  }
+  DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
+} // ThunderboltCallback
+
+VOID
+DisablePCIDevicesAndBridges (
+  IN UINT8 MinBus,
+  IN UINT8 MaxBus
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RegVal;
+  //
+  //  Disable PCI device First, and then Disable PCI Bridge
+  //
+  for (Bus = MaxBus; Bus > MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+          if (Fun == 0) {
+            break;
+
+          }
+
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
+          //
+          // ********     Disable PCI Device   ********
+          // BIT0  I/O Space Enabled    BIT1  Memory Space Enabled
+          // BIT2  Bus Master Enabled   BIT4  Memory Write and Invalidation Enable
+          //
+          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
+        }
+      }
+    }
+  }
+  //
+  // now no more PCI dev on another side of PCI Bridge can safty disable PCI Bridge
+  //
+  for (Bus = MaxBus; Bus > MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+          if (Fun == 0) {
+            break;
+          }
+
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
+          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+        }
+      } // for ( Fun .. )
+    } // for ( Dev ... )
+  } // for ( Bus ... )
+} // DisablePCIDevicesAndBridges
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+  IN UINT8 Type
+  )
+{
+  UINTN         Segment = 0;
+  UINTN         Bus = 0;
+  UINTN         Device;
+  UINTN         Function;
+  UINT8         MinBus;
+  UINT8         MaxBus;
+  UINT16        DeviceId;
+
+  MinBus = 1;
+  if(Type == DTBT_CONTROLLER) {
+    //
+    // for(Dev = 0; Dev < 8; ++Dev)
+    // {
+    // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
+    // gBS->Stall(2000);      // 2msec
+    // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
+    // }
+    // gBS->Stall(200 * 1000);        // 200 msec
+    //
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+      return;
+    }
+    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+    MinBus            = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    MaxBus            = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus, 0x00, 0x00, 0);
+    DeviceId          = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+    if (!(IsTbtHostRouter (DeviceId))) {
+      return;
+    }
+    TbtSegment = (UINT8)Segment;
+    MinBus++;
+    //
+    // @todo : Move this out when we dont have Loop for ITBT
+    //
+    DisablePCIDevicesAndBridges(MinBus, MaxBus);
+
+  }
+} // DisablePCIDevicesAndBridges
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
new file mode 100644
index 0000000000..721438c718
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
@@ -0,0 +1,1765 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Module specific Includes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/TbtNvsArea.h>
+#include <PchAccess.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Guid/HobList.h>
+#include "TbtSmiHandler.h"
+#include <PcieRegs.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Library/PchPmcLib.h>
+#define P2P_BRIDGE                    (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define CMD_BM_MEM_IO                 (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DISBL_IO_REG1C                0x01F1
+#define DISBL_MEM32_REG20             0x0000FFF0
+#define DISBL_PMEM_REG24              0x0001FFF1
+
+#define DOCK_BUSSES                   8
+
+#define PCI_CAPABILITY_ID_PCIEXP      0x10
+#define PCI_CAPBILITY_POINTER_OFFSET  0x34
+
+#define LTR_MAX_SNOOP_LATENCY_VALUE             0x0846    ///< Intel recommended maximum value for Snoop Latency  can we put like this ?
+#define LTR_MAX_NON_SNOOP_LATENCY_VALUE         0x0846    ///< Intel recommended maximum value for Non-Snoop Latency can we put like this ?
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA                *mTbtNvsAreaPtr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gCurrentDiscreteTbtRootPort;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gCurrentDiscreteTbtRootPortType;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                      TbtLtrMaxSnoopLatency;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                      TbtLtrMaxNoSnoopLatency;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gDTbtPcieRstSupport;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB                *gTbtInfoHob = NULL;
+STATIC UINTN                                              mPciExpressBaseAddress;
+STATIC UINT8                TbtSegment        = 0;
+VOID
+GpioWrite (
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+  )
+{
+  GpioSetOutputValue (GpioNumber, (UINT32)Value);
+}
+
+/**
+  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] 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   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+
+  ///
+  /// 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 = 0x100;
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    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;
+}
+
+/**
+  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] 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
+  )
+{
+  UINT8   CapHeaderOffset;
+  UINT8   CapHeaderId;
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+
+  if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) & EFI_PCI_STATUS_CAPABILITY) == 0x00) {
+    ///
+    /// Function has no capability pointer
+    ///
+    return 0;
+  }
+
+  ///
+  /// 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 = 0x14;
+  } else {
+    ///
+    /// Otherwise, start at Offset 0x34
+    ///
+    CapHeaderOffset = 0x34;
+  }
+  ///
+  /// 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) {
+    CapHeaderId = PciSegmentRead8 (DeviceBase + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+    ///
+    /// 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 = PciSegmentRead8 (DeviceBase + CapHeaderOffset + 1) & ((UINT8) ~(BIT0 | BIT1));
+  }
+
+  return 0;
+}
+/**
+  This function configures the L1 Substates.
+  It can be used for Rootport and endpoint devices.
+
+  @param[in] DownstreamPort               Indicates if the device about to be programmed is a downstream port
+  @param[in] DeviceBase                   Device PCI configuration base address
+  @param[in] L1SubstateExtCapOffset       Pointer to L1 Substate Capability Structure
+  @param[in] PortL1SubstateCapSupport     L1 Substate capability setting
+  @param[in] PortCommonModeRestoreTime    Common Mode Restore Time
+  @param[in] PortTpowerOnValue            Tpower_on Power On Wait Time
+  @param[in] PortTpowerOnScale            Tpower-on Scale
+
+  @retval none
+**/
+VOID
+ConfigureL1s (
+  IN UINTN                              DeviceBase,
+  IN UINT16                             L1SubstateExtCapOffset,
+  IN UINT32                             PortL1SubstateCapSupport,
+  IN UINT32                             PortCommonModeRestoreTime,
+  IN UINT32                             PortTpowerOnValue,
+  IN UINT32                             PortTpowerOnScale,
+  IN UINT16                             MaxLevel
+  )
+{
+
+  PciSegmentAndThenOr32 (
+    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+    (UINT32) ~(0xFF00),
+    (UINT32) PortCommonModeRestoreTime << 8
+    );
+
+  PciSegmentAnd32(DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL2_OFFSET, 0xFFFFFF04);
+
+  PciSegmentOr32(DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL2_OFFSET,(UINT32) ((PortTpowerOnValue << N_PCIE_EX_L1SCTL2_POWT) | PortTpowerOnScale));
+
+  PciSegmentAndThenOr32 (
+    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+    (UINT32) ~(0xE3FF0000),
+    (UINT32) (BIT30 | BIT23 | BIT21)
+    );
+
+}
+
+VOID
+RootportL1sSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT16  RootL1SubstateExtCapOffset,
+  IN UINT16  MaxL1Level
+  )
+{
+  UINTN       ComponentABaseAddress;
+  UINTN       ComponentBBaseAddress;
+  UINT8       SecBus;
+  UINT32      PortL1SubstateCapSupport;
+  UINT32      PortCommonModeRestoreTime;
+  UINT32      PortTpowerOnValue;
+  UINT32      PortTpowerOnScale;
+  UINT16      ComponentBL1SubstateExtCapOffset;
+  UINT32      ComponentBL1Substates;
+  UINT32      ComponentBCommonModeRestoreTime;
+  UINT32      ComponentBTpowerOnValue;
+  UINT32      ComponentBTpowerOnScale;
+  UINT32      Data32;
+
+  PortL1SubstateCapSupport  = 0;
+  PortCommonModeRestoreTime = 0;
+  PortTpowerOnValue = 0;
+  PortTpowerOnScale = 0;
+  Data32 = 0;
+
+  ComponentABaseAddress  = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  if (RootL1SubstateExtCapOffset != 0) {
+    Data32 = PciSegmentRead32 (ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+    PortL1SubstateCapSupport  = (Data32) & 0x0F;
+    PortCommonModeRestoreTime = (Data32 >> 8) & 0xFF;
+    PortTpowerOnScale         = (Data32 >> 16) & 0x3;
+    PortTpowerOnValue         = (Data32 >> 19) & 0x1F;
+  } else {
+    MaxL1Level                = 0; // If L1 Substates from Root Port side is disable, then Disable from Device side also.
+  }
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+    ComponentBL1SubstateExtCapOffset = PcieFindExtendedCapId (
+                                  SecBus,
+                                  0,
+                                  0,
+                                  V_PCIE_EX_L1S_CID
+                                  );
+    if (ComponentBL1SubstateExtCapOffset != 0) {
+      ComponentBL1Substates = PciSegmentRead32 (ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+      ComponentBCommonModeRestoreTime = (ComponentBL1Substates >> 8) & 0xFF;
+      ComponentBTpowerOnScale         = (ComponentBL1Substates >> 16) & 0x3;
+      ComponentBTpowerOnValue         = (ComponentBL1Substates >> 19) & 0x1F;
+
+      if (MaxL1Level == 3) {
+        if (Data32 >= ComponentBL1Substates) {
+          if (~(Data32 | BIT2)) {
+            MaxL1Level = 1;
+          }
+        }
+        else {
+          if (~(ComponentBL1Substates | BIT2)) {
+          MaxL1Level = 1;
+        }
+      }
+    }
+
+      if (MaxL1Level == 3) {
+        ConfigureL1s (
+          ComponentABaseAddress,
+          RootL1SubstateExtCapOffset,
+          PortL1SubstateCapSupport,
+          ComponentBCommonModeRestoreTime,
+          ComponentBTpowerOnValue,
+          ComponentBTpowerOnScale,
+          MaxL1Level
+          );
+
+      ConfigureL1s (
+          ComponentBBaseAddress,
+          ComponentBL1SubstateExtCapOffset,
+          ComponentBL1Substates,
+          PortCommonModeRestoreTime,
+          PortTpowerOnValue,
+          PortTpowerOnScale,
+          MaxL1Level
+          );
+      }
+
+      if (MaxL1Level == 1) {
+        PciSegmentOr32 (
+          ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+          (UINT32) (BIT3 | BIT1)
+          );
+
+        PciSegmentOr32 (
+          ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+          (UINT32) (BIT3 | BIT1)
+          );
+      }
+      else {
+        if (RootL1SubstateExtCapOffset != 0) {
+          PciSegmentOr32 (
+            ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT3 | BIT1)
+            );
+
+          PciSegmentOr32 (
+            ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT2 | BIT0)
+            );
+        }
+        if (ComponentBL1SubstateExtCapOffset != 0) {
+          PciSegmentOr32 (
+            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT3 | BIT1)
+           );
+
+          PciSegmentOr32 (
+            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT2 | BIT0)
+            );
+        }
+      }
+    }
+  }
+}
+
+VOID
+MultiFunctionDeviceAspm (
+  IN UINT8   Bus,
+  IN UINT8   Dev
+  )
+{
+  UINT16  LowerAspm;
+  UINT16  AspmVal;
+  UINT8   Fun;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+
+  LowerAspm = 3; // L0s and L1 Supported
+  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+    //
+    // Check for Device availability
+    //
+    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+      // Device not present
+      continue;
+    }
+
+    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+
+    AspmVal = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+    if (LowerAspm > AspmVal) {
+      LowerAspm = AspmVal;
+    }
+  } //Fun
+
+  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+    //
+    // Check for Device availability
+    //
+    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+      //
+      // Device not present
+      //
+      continue;
+    }
+
+    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+
+    PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, LowerAspm);
+  } //Fun
+}
+
+UINT16
+LimitAspmLevel (
+  IN UINT16  SelectedAspm,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  SelectedAspm = SelectedAspm & MaxAspmLevel;
+
+  return SelectedAspm;
+}
+
+UINT16
+FindOptimalAspm (
+  IN UINT16   ComponentAaspm,
+  IN UINT16   ComponentBaspm
+  )
+{
+  UINT16  SelectedAspm;
+
+  SelectedAspm = ComponentAaspm & ComponentBaspm;
+
+  return SelectedAspm;
+}
+
+UINT16
+FindComponentBaspm (
+  IN UINT8   Bus,
+  IN UINT8   MaxBus
+  )
+{
+  UINT8   BusNo;
+  UINT8   DevNo;
+  UINT8   FunNo;
+  UINT64  DevBaseAddress;
+  UINT8   RegVal;
+  UINT8   SecBusNo;
+  UINT16  SelectedAspm; // No ASPM Support
+  UINT8   CapHeaderOffset_B;
+  BOOLEAN AspmFound;
+
+  SelectedAspm  = 0;
+  AspmFound     = FALSE;
+
+  for (BusNo = MaxBus; (BusNo != 0xFF) && (!AspmFound); --BusNo) {
+    for (DevNo = 0; (DevNo <= PCI_MAX_DEVICE) && (!AspmFound); ++DevNo) {
+      for (FunNo = 0; (FunNo <= PCI_MAX_FUNC) && (!AspmFound); ++FunNo) {
+        //
+        // Check for Device availability
+        //
+        DevBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, BusNo, DevNo, FunNo, 0);
+        if (PciSegmentRead16 (DevBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (DevBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if ((RegVal & (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6)) != 0x01) {
+          //
+          // Not a PCI-to-PCI bridges device
+          //
+          continue;
+        }
+
+        SecBusNo = PciSegmentRead8 (DevBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+
+        if (SecBusNo == Bus) {
+          //
+          // This is the Rootbridge for the given 'Bus' device
+          //
+          CapHeaderOffset_B = PcieFindCapId (TbtSegment, BusNo, DevNo, FunNo, 0x10);
+          SelectedAspm      = (PciSegmentRead16 (DevBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+          AspmFound         = TRUE;
+        }
+      } //FunNo
+    } //DevNo
+  } //BusNo
+
+  return (SelectedAspm);
+}
+
+VOID
+NoAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset
+  )
+{
+  UINT64 DeviceBaseAddress;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, 0x00);
+}
+
+VOID
+EndpointAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT8   MaxBus,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
+  SelectedAspm      = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+UpstreamAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT8   MaxBus,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
+  SelectedAspm      = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+DownstreamAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  ComponentABaseAddress;
+  UINT64  ComponentBBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+  UINT8   SecBus;
+  UINT8   CapHeaderOffset_B;
+
+  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+  ComponentBaspm        = 0; // No ASPM Support
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
+    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
+    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+  }
+
+  SelectedAspm = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+RootportAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  ComponentABaseAddress;
+  UINT64  ComponentBBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+  UINT8   SecBus;
+  UINT8   CapHeaderOffset_B;
+
+  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+  ComponentBaspm        = 0; // No ASPM Support
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
+    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
+    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+  }
+
+  SelectedAspm = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+ThunderboltEnableAspmWithoutLtr (
+  IN   UINT16     MaxAspmLevel,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RootBus;
+  UINT8   RootDev;
+  UINT8   RootFun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   RegVal;
+  UINT8   CapHeaderOffset;
+  UINT16  DevicePortType;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+
+  RootBus = (UINT8)RpBus;
+  RootDev = (UINT8)RpDevice;
+  RootFun = (UINT8)RpFunction;
+
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      //
+      // Check for Device availability
+      //
+      DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0, 0);
+      if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+        //
+        // Device not present
+        //
+        continue;
+      }
+
+      RegVal = PciSegmentRead8 (DeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+      if ((RegVal & BIT7) == 0) {
+        //
+        // Not a multi-function device
+        //
+        continue;
+      }
+
+      MultiFunctionDeviceAspm(Bus, Dev);
+    } //Dev
+  } //Bus
+
+
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x002) >> 4) & 0xF;
+        if(PciSegmentRead8 (DeviceBaseAddress + PCI_CLASSCODE_OFFSET) == PCI_CLASS_SERIAL) {
+          MaxAspmLevel = (UINT16) 0x1;
+        }
+
+        switch (DevicePortType) {
+        case 0:
+          //
+          // PCI Express Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 1:
+          //
+          // Legacy PCI Express Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 4:
+          //
+          // Root Port of PCI Express Root Complex
+          //
+          RootportAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLevel);
+          break;
+
+        case 5:
+          //
+          // Upstream Port of PCI Express Switch
+          //
+          UpstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 6:
+          //
+          // Downstream Port of PCI Express Switch
+          //
+          DownstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLevel);
+          break;
+
+        case 7:
+          //
+          // PCI Express to PCI/PCI-X Bridge
+          //
+          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
+          break;
+
+        case 8:
+          //
+          // PCI/PCI-X to PCI Express Bridge
+          //
+          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
+          break;
+
+        case 9:
+          //
+          // Root Complex Integrated Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 10:
+          //
+          // Root Complex Event Collector
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        default:
+          break;
+        }
+        //
+        // switch(DevicePortType)
+        //
+      }
+      //
+      // Fun
+      //
+    }
+    //
+    // Dev
+    //
+  }
+  //
+  // Bus
+  //
+  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun, 0x10);
+  RootportAspmSupport (RootBus, RootDev, RootFun, CapHeaderOffset, MaxAspmLevel);
+}
+
+
+
+VOID
+ThunderboltEnableL1Sub (
+  IN   UINT16     MaxL1Level,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT16  CapHeaderOffsetExtd;
+
+  RpBus   = 0;
+
+  CapHeaderOffsetExtd = PcieFindExtendedCapId ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, V_PCIE_EX_L1S_CID);
+  RootportL1sSupport ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, CapHeaderOffsetExtd, MaxL1Level);
+}
+
+VOID
+ThunderboltDisableAspmWithoutLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RootBus;
+  UINT8   RootDev;
+  UINT8   RootFun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  RootBus = (UINT8)RpBus;
+  RootDev = (UINT8)RpDevice;
+  RootFun = (UINT8)RpFunction;
+
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, 0x00);
+      } //Fun
+    } //Dev
+  } //Bus
+
+  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun, 0x10);
+  NoAspmSupport(RootBus, RootDev, RootFun, CapHeaderOffset);
+}
+
+VOID
+TbtProgramClkReq (
+  IN        UINT8  Bus,
+  IN        UINT8  Device,
+  IN        UINT8  Function,
+  IN        UINT8  ClkReqSetup
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+  UINT16  Data16;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function, 0x10);
+
+  //
+  // Check if CLKREQ# is supported
+  //
+  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x0C) & BIT18) != 0) {
+    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x010);
+
+    if (ClkReqSetup) {
+      Data16 = Data16 | BIT8; // Enable Clock Power Management
+    } else {
+      Data16 =  Data16 & (UINT16)(~BIT8); // Disable Clock Power Management
+    }
+
+    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x010, Data16);
+  }
+}
+VOID
+TbtProgramPtm(
+   IN        UINT8  Bus,
+   IN        UINT8  Device,
+   IN        UINT8  Function,
+   IN        UINT8  PtmSetup,
+   IN        BOOLEAN IsRoot
+)
+{
+   UINT64  DeviceBaseAddress;
+   UINT16  CapHeaderOffset;
+   UINT16  PtmControlRegister;
+   UINT16  PtmCapabilityRegister;
+
+   DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS(TbtSegment, Bus, Device, Function, 0);
+   CapHeaderOffset = PcieFindExtendedCapId(Bus, Device, Function, 0x001F /*V_PCIE_EX_PTM_CID*/);
+   if(CapHeaderOffset != 0) {
+      PtmCapabilityRegister = PciSegmentRead16(DeviceBaseAddress + CapHeaderOffset + 0x04);
+     //
+     // Check if PTM Requester/ Responder capability for the EP/Down stream etc
+     //
+     if ((PtmCapabilityRegister & (BIT1 | BIT0)) != 0) {
+        PtmControlRegister = PciSegmentRead16(DeviceBaseAddress + CapHeaderOffset + 0x08);
+
+        if (PtmSetup) {
+           PtmControlRegister = PtmControlRegister | BIT0; // Enable PTM
+           if(IsRoot) {
+             PtmControlRegister = PtmControlRegister | BIT1; // Enable PTM
+           }
+           PtmControlRegister = PtmControlRegister | (PtmCapabilityRegister & 0xFF00); // Programm Local Clock Granularity
+        } else {
+           PtmControlRegister = PtmControlRegister & (UINT16)(~(BIT0 | BIT1)); // Disable Clock Power Management
+        }
+
+        PciSegmentWrite16(DeviceBaseAddress + CapHeaderOffset + 0x08, PtmControlRegister);
+     }
+   }
+}
+
+VOID
+ConfigureTbtPm (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction,
+  IN   UINT8      Configuration    // 1- Clk Request , 2- PTM ,
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  if ((Configuration != 1) && (Configuration != 2)) {
+    return;
+  }
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MaxBus; Bus >= MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          if (Fun == 0) {
+            //
+            // IF Fun is zero, stop enumerating other functions of the particular bridge
+            //
+            break;
+          }
+          //
+          // otherwise, just skip checking for CLKREQ support
+          //
+          continue;
+        }
+        switch (Configuration) {
+          case 1:
+            TbtProgramClkReq (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtSetClkReq);
+            break;
+          case 2:
+            TbtProgramPtm (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtPtm, FALSE);
+            TbtProgramPtm((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, (UINT8) mTbtNvsAreaPtr->TbtPtm, TRUE);
+            break;
+          default:
+            break;
+        }
+      } //Fun
+    } // Dev
+  } // Bus
+}
+
+/**
+  1) Check LTR support in device capabilities 2 register (bit 11).
+  2) If supported enable LTR in device control 2 register (bit 10).
+
+**/
+VOID
+TbtProgramLtr (
+  IN        UINT8  Bus,
+  IN        UINT8  Device,
+  IN        UINT8  Function,
+  IN        UINT8  LtrSetup
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+  UINT16  Data16;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function, 0x10);
+
+  //
+  // Check if LTR# is supported
+  //
+  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x24) & BIT11) != 0) {
+    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x028);
+
+    if (LtrSetup) {
+      Data16 = Data16 | BIT10; // LTR Mechanism Enable
+    } else {
+      Data16 =  Data16 & (UINT16)(~BIT10); // LTR Mechanism Disable
+    }
+
+    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x028, Data16);
+  }
+}
+
+VOID
+ConfigureLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          if (Fun == 0) {
+            //
+            // IF Fun is zero, stop enumerating other functions of the particular bridge
+            //
+            break;
+          }
+          //
+          // otherwise, just skip checking for LTR support
+          //
+          continue;
+        }
+
+        TbtProgramLtr (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtLtr);
+
+      } //Fun
+    } // Dev
+  } // Bus
+  TbtProgramLtr ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, (UINT8) mTbtNvsAreaPtr->TbtLtr);
+}
+
+/*
+  US ports and endpoints which declare support must also have the LTR capability structure (cap ID 18h).
+  In this structure you need to enter the max snoop latency and max non-snoop latency in accordance with the format specified in the PCIe spec.
+  The latency value itself is platform specific so you'll need to get it from the platform architect or whatever.
+*/
+VOID
+ThunderboltGetLatencyLtr (
+  VOID
+  )
+{
+  PCH_SERIES       PchSeries;
+
+  PchSeries = GetPchSeries ();
+
+  if(gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PEG) {
+  // PEG selector
+  TbtLtrMaxSnoopLatency = LTR_MAX_SNOOP_LATENCY_VALUE;
+  TbtLtrMaxNoSnoopLatency = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+  } else if (gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PCH) {
+  // PCH selector
+
+    if (PchSeries == PchLp) {
+      TbtLtrMaxSnoopLatency = 0x1003;
+      TbtLtrMaxNoSnoopLatency = 0x1003;
+    }
+    if (PchSeries == PchH) {
+      TbtLtrMaxSnoopLatency = 0x0846;
+      TbtLtrMaxNoSnoopLatency = 0x0846;
+    }
+  }
+}
+
+VOID
+SetLatencyLtr (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT16  CapHeaderOffsetExtd,
+  IN UINT16  LtrMaxSnoopLatency,
+  IN UINT16  LtrMaxNoSnoopLatency
+  )
+{
+  UINT64 DeviceBaseAddress;
+  if(CapHeaderOffsetExtd == 0) {
+    return;
+  }
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x004, LtrMaxSnoopLatency);
+  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x006, LtrMaxNoSnoopLatency);
+}
+
+VOID
+ThunderboltSetLatencyLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffsetStd;
+  UINT16  CapHeaderOffsetExtd;
+  UINT16  DevicePortType;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffsetStd = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffsetStd + 0x002) >> 4) & 0xF;
+
+        CapHeaderOffsetExtd = PcieFindExtendedCapId (Bus, Dev, Fun, 0x0018);
+
+        switch (DevicePortType) {
+        case 0:
+          //
+          // PCI Express Endpoint
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 1:
+          //
+          // Legacy PCI Express Endpoint
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 4:
+          //
+          // Root Port of PCI Express Root Complex
+          //
+          // Do-nothing
+          break;
+
+        case 5:
+          //
+          // Upstream Port of PCI Express Switch
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 6:
+          //
+          // Downstream Port of PCI Express Switch
+          //
+          // Do-nothing
+          break;
+
+        case 7:
+          //
+          // PCI Express to PCI/PCI-X Bridge
+          //
+          // Do-nothing
+          break;
+
+        case 8:
+          //
+          // PCI/PCI-X to PCI Express Bridge
+          //
+          // Do-nothing
+          break;
+
+        case 9:
+          //
+          // Root Complex Integrated Endpoint
+          //
+          // Do-nothing
+          break;
+
+        case 10:
+          //
+          // Root Complex Event Collector
+          //
+          // Do-nothing
+          break;
+
+        default:
+          break;
+        }
+        //
+        // switch(DevicePortType)
+        //
+      }
+      //
+      // Fun
+      //
+    }
+    //
+    // Dev
+    //
+  }
+  //
+  // Bus
+  //
+}
+
+static
+VOID
+Stall (
+  UINTN     Usec
+  )
+{
+  UINTN   Index;
+  UINT32  Data32;
+  UINT32  PrevData;
+  UINTN   Counter;
+
+  Counter = (UINTN) ((Usec * 10) / 3);
+  //
+  // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+  // periods, thus attempting to ensure Microseconds of stall time.
+  //
+  if (Counter != 0) {
+
+    PrevData = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_TMR);
+    for (Index = 0; Index < Counter;) {
+      Data32 = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_TMR);
+      if (Data32 < PrevData) {
+        //
+        // Reset if there is a overlap
+        //
+        PrevData = Data32;
+        continue;
+      }
+
+      Index += (Data32 - PrevData);
+      PrevData = Data32;
+    }
+  }
+
+  return ;
+}
+/**
+  Called during Sx entry, initates TbtSetPcie2TbtCommand HandShake to set GO2SX_NO_WAKE
+  for Tbt devices if WakeupSupport is not present.
+
+  @param[in] DispatchHandle         - The unique handle assigned to this handler by SmiHandlerRegister().
+  @param[in] DispatchContext        - 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 successfully.
+**/
+EFI_STATUS
+EFIAPI
+SxDTbtEntryCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer OPTIONAL,
+  IN  UINTN                         *CommBufferSize OPTIONAL
+  )
+{
+  UINT16          DeviceId;
+  UINT8           CableConnected;
+  UINT8           RootportSelected;
+  UINT8           HoustRouteBus;
+  volatile UINT32 *PowerState;
+  UINT32          PowerStatePrev;
+  BOOLEAN         SecSubBusAssigned;
+  UINT64          DeviceBaseAddress;
+  UINT8           CapHeaderOffset;
+  UINTN           RpDev;
+  UINTN           RpFunc;
+  EFI_STATUS      Status;
+  UINT32          Timeout;
+  UINT32          RegisterValue;
+  UINT64          Tbt2Pcie;
+  UINTN           Index;
+  UINT32          TbtCioPlugEventGpioNo;
+  UINT32          TbtFrcPwrGpioNo;
+  UINT8           TbtFrcPwrGpioLevel;
+  UINT32          TbtPcieRstGpioNo;
+  UINT8           TbtPcieRstGpioLevel;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryDispatchContext;
+
+  CableConnected    = 0;
+  HoustRouteBus     = 3;
+  SecSubBusAssigned = FALSE;
+  Timeout = 600;
+  RootportSelected      = 0;
+  TbtCioPlugEventGpioNo = 0;
+  TbtFrcPwrGpioNo       = 0;
+  TbtFrcPwrGpioLevel    = 0;
+  TbtPcieRstGpioNo      = 0;
+  TbtPcieRstGpioLevel   = 0;
+  Index = 0;
+
+  EntryDispatchContext = (EFI_SMM_SX_REGISTER_CONTEXT*) DispatchContext;
+
+//  CableConnected = GetTbtHostRouterStatus ();
+  //SaveTbtHostRouterStatus (CableConnected & 0xF0);
+  //
+  // Get the Power State and Save
+  //
+  if (((mTbtNvsAreaPtr->DTbtControllerEn0 == 0) && (Index == 0)))  {
+
+  RootportSelected      = mTbtNvsAreaPtr->RootportSelected0;
+  TbtCioPlugEventGpioNo = mTbtNvsAreaPtr->TbtCioPlugEventGpioNo0;
+  TbtFrcPwrGpioNo       = mTbtNvsAreaPtr->TbtFrcPwrGpioNo0;
+  TbtFrcPwrGpioLevel    = mTbtNvsAreaPtr->TbtFrcPwrGpioLevel0;
+  TbtPcieRstGpioNo      = mTbtNvsAreaPtr->TbtPcieRstGpioNo0;
+  TbtPcieRstGpioLevel   = mTbtNvsAreaPtr->TbtPcieRstGpioLevel0;
+  }
+
+  Status = GetDTbtRpDevFun (gCurrentDiscreteTbtRootPortType, RootportSelected - 1, &RpDev, &RpFunc);
+  ASSERT_EFI_ERROR (Status);
+  CapHeaderOffset = PcieFindCapId (TbtSegment, 0x00, (UINT8)RpDev, (UINT8)RpFunc, 0x01);
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, 0x00, (UINT32)RpDev, (UINT32)RpFunc, 0);
+  PowerState        = &*((volatile UINT32 *) (mPciExpressBaseAddress + DeviceBaseAddress + CapHeaderOffset + 4)); //PMCSR
+  PowerStatePrev    = *PowerState;
+  *PowerState &= 0xFFFFFFFC;
+
+  HoustRouteBus = PciSegmentRead8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  //
+  // Check the Subordinate bus .If it is Zero ,assign temporary bus to
+  // find the device presence .
+  //
+  if (HoustRouteBus == 0) {
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0xF0);
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0xF0);
+    HoustRouteBus     = 0xF0;
+    SecSubBusAssigned = TRUE;
+  }
+  //
+  // Clear Interrupt capability of TBT CIO Plug Event Pin to make sure no SCI is getting generated,
+  // This GPIO will be reprogrammed while resuming as part of Platform GPIO Programming.
+  //
+  GpioSetPadInterruptConfig (TbtCioPlugEventGpioNo, GpioIntDis);
+  //
+  // Read the TBT Host router DeviceID
+  //
+  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (TbtSegment, HoustRouteBus, 0, 0, PCI_DEVICE_ID_OFFSET));
+
+  //
+  // Check For HostRouter Presence
+  //
+  if (IsTbtHostRouter (DeviceId)) {
+    //    CableConnected = GetTbtHostRouterStatus ();
+    if (!((CableConnected & (DTBT_SAVE_STATE_OFFSET << Index)) == (DTBT_SAVE_STATE_OFFSET << Index))) {
+      CableConnected = CableConnected | (DTBT_SAVE_STATE_OFFSET << Index);
+   //     SaveTbtHostRouterStatus (CableConnected);
+    }
+  }
+
+  //
+  // Check value of Tbt2Pcie reg, if Tbt is not present, bios needs to apply force power prior to sending mailbox command
+  //
+  GET_TBT2PCIE_REGISTER_ADDRESS(TbtSegment, HoustRouteBus, 0x00, 0x00, Tbt2Pcie)
+  RegisterValue = PciSegmentRead32 (Tbt2Pcie);
+  if (0xFFFFFFFF == RegisterValue) {
+
+    GpioWrite (TbtFrcPwrGpioNo,TbtFrcPwrGpioLevel);
+
+    while (Timeout -- > 0) {
+      RegisterValue = PciSegmentRead32 (Tbt2Pcie);
+      if (0xFFFFFFFF != RegisterValue) {
+        break;
+      }
+      Stall(1* (UINTN)1000);
+    }
+    //
+    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox command for AIC.
+    // However BIOS shall not execute go2sx mailbox command on S5/reboot cycle.
+    //
+
+    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type == SxS4))
+    {
+      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
+        //Wake Disabled, GO2SX_NO_WAKE Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      } else {
+        //Wake Enabled, GO2SX Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      }
+    }
+    if (mTbtNvsAreaPtr->TbtFrcPwrEn == 0) {
+      GpioWrite (TbtFrcPwrGpioNo,!(TbtFrcPwrGpioLevel));
+    }
+  } else {
+    //
+    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox command for AIC.
+    // However BIOS shall not execute go2sx mailbox command on S5/reboot cycle.
+    //
+    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type == SxS4))
+    {
+      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
+        //Wake Disabled, GO2SX_NO_WAKE Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      } else {
+        //Wake Enabled, GO2SX Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      }
+    }
+  }
+  *PowerState = PowerStatePrev;
+  //
+  // Restore the bus number in case we assigned temporarily
+  //
+  if (SecSubBusAssigned) {
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0x00);
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0x00);
+  }
+  if (gDTbtPcieRstSupport) {
+    GpioWrite (TbtPcieRstGpioNo,TbtPcieRstGpioLevel);
+  }
+  return EFI_SUCCESS;
+}
+
+VOID
+ThunderboltSwSmiCallback (
+  IN UINT8 Type
+  )
+{
+  UINT8 ThunderboltSmiFunction;
+
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Entry\n"));
+  ThunderboltSmiFunction = mTbtNvsAreaPtr->ThunderboltSmiFunction;
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback. ThunderboltSmiFunction=%d\n", ThunderboltSmiFunction));
+  if (Type == DTBT_CONTROLLER) {
+    gCurrentDiscreteTbtRootPort     = mTbtNvsAreaPtr->CurrentDiscreteTbtRootPort;
+    gCurrentDiscreteTbtRootPortType = mTbtNvsAreaPtr->CurrentDiscreteTbtRootPortType;
+  }
+
+  switch (ThunderboltSmiFunction) {
+  case 21:
+    ThunderboltCallback (Type);
+    break;
+
+  case 22:
+    TbtDisablePCIDevicesAndBridges (Type);
+    break;
+
+  case 23:
+    ConfigureTbtAspm (Type, (UINT16) 0x02);
+    break;
+
+  case 24:
+    ConfigureTbtAspm (Type, (UINT16) 0x01);
+    break;
+
+  default:
+    break;
+  }
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Exit.\n"));
+}
+STATIC
+EFI_STATUS
+EFIAPI
+DiscreteThunderboltSwSmiCallback (
+  IN EFI_HANDLE                     DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer OPTIONAL,
+  IN  UINTN                         *CommBufferSize OPTIONAL
+  )
+{
+  ThunderboltSwSmiCallback(DTBT_CONTROLLER);
+  return EFI_SUCCESS;
+}
+EFI_STATUS
+TbtRegisterHandlers (
+  IN BOOLEAN Type
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         SmiInputValue;
+  EFI_SMM_HANDLER_ENTRY_POINT2   SxHandler;
+  EFI_SMM_HANDLER_ENTRY_POINT2   SwHandler;
+  EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatchProtocol;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+  EFI_SMM_SX_REGISTER_CONTEXT   EntryDispatchContext;
+  EFI_SMM_SW_REGISTER_CONTEXT   SwContext;
+  EFI_HANDLE                    SwDispatchHandle;
+  EFI_HANDLE                    S3DispatchHandle;
+  EFI_HANDLE                    S4DispatchHandle;
+  EFI_HANDLE                    S5DispatchHandle;
+
+  Status = EFI_UNSUPPORTED;
+
+  if(Type == DTBT_CONTROLLER) {
+    SxHandler = SxDTbtEntryCallback;
+    SwHandler = DiscreteThunderboltSwSmiCallback;
+    SmiInputValue = PcdGet8 (PcdSwSmiDTbtEnumerate);
+    gDTbtPcieRstSupport = gTbtInfoHob->DTbtCommonConfig.PcieRstSupport;
+    Status = EFI_SUCCESS;
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SwDispatchHandle        = NULL;
+  S3DispatchHandle        = NULL;
+  S4DispatchHandle        = NULL;
+  S5DispatchHandle        = NULL;
+
+   Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSxDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &SxDispatchProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S3 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS3;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S3DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S4 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS4;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S4DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S5 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS5;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S5DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Locate the SMM SW dispatch protocol
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSwDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &SwDispatch
+                    );
+
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register SWSMI handler
+  //
+  SwContext.SwSmiInputValue = SmiInputValue;
+  Status = SwDispatch->Register (
+                        SwDispatch,
+                        SwHandler,
+                        &SwContext,
+                        &SwDispatchHandle
+                        );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+EFI_STATUS
+InSmmFunction (
+  IN  EFI_HANDLE        ImageHandle,
+  IN  EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                    Status;
+
+  Status = EFI_SUCCESS;
+
+  Status = TbtRegisterHandlers(DTBT_CONTROLLER);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+TbtSmmEntryPoint (
+  IN EFI_HANDLE               ImageHandle,
+  IN EFI_SYSTEM_TABLE         *SystemTable
+  )
+{
+  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
+  EFI_STATUS                    Status;
+
+  DEBUG ((DEBUG_INFO, "TbtSmmEntryPoint\n"));
+
+  mPciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
+  //
+  // Locate Tbt shared data area
+  //
+  Status = gBS->LocateProtocol (&gTbtNvsAreaProtocolGuid, NULL, (VOID **) &TbtNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+  mTbtNvsAreaPtr = TbtNvsAreaProtocol->Area;
+
+  //
+  // Get TBT INFO HOB
+  //
+  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+  if (gTbtInfoHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  return InSmmFunction (ImageHandle, SystemTable);
+}
+
+VOID
+EndOfThunderboltCallback (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  if(mTbtNvsAreaPtr->TbtL1SubStates != 0) {
+    ThunderboltEnableL1Sub (mTbtNvsAreaPtr->TbtL1SubStates, RpSegment, RpBus, RpDevice, RpFunction);
+  }
+  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 1);
+  if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
+    ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  } else { //Aspm enable case
+    ThunderboltEnableAspmWithoutLtr ((UINT16)mTbtNvsAreaPtr->TbtAspm, RpSegment, RpBus, RpDevice, RpFunction);
+  }
+
+  if (mTbtNvsAreaPtr->TbtLtr) {
+    ThunderboltGetLatencyLtr ();
+    ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  }
+  ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 2);
+} // EndOfThunderboltCallback
+
+VOID
+ConfigureTbtAspm (
+  IN UINT8        Type,
+  IN UINT16       Aspm
+  )
+{
+  UINTN                         RpSegment = 0;
+  UINTN                         RpBus = 0;
+  UINTN                         RpDevice;
+  UINTN                         RpFunction;
+
+  if(Type == DTBT_CONTROLLER) {
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      return;
+    }
+    GetDTbtRpDevFun(DTBT_CONTROLLER, gCurrentDiscreteTbtRootPort - 1, &RpDevice, &RpFunction);
+
+    ConfigureTbtPm (RpSegment, RpBus, RpDevice, RpFunction, 1);
+    if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
+      ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunction);
+    } else { //Aspm enable case
+      ThunderboltEnableAspmWithoutLtr ((UINT16) Aspm, RpSegment, RpBus, RpDevice, RpFunction);
+    }
+
+  if (mTbtNvsAreaPtr->TbtLtr) {
+      ThunderboltGetLatencyLtr ();
+      ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
+    }
+    ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  } // EndOfThunderboltCallback
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
new file mode 100644
index 0000000000..ec06eee73f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -0,0 +1,394 @@
+/** @file
+  ACPI Timer implements one instance of Timer Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Acpi.h>
+//
+// OVERRIDE: OverrideBegin
+//
+#include <Register/Cpuid.h>
+//
+// OVERRIDE: OverrideEnd
+//
+
+
+/**
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+InternalGetPerformanceCounterFrequency (
+  VOID
+  );
+
+/**
+  The constructor function enables ACPI IO space.
+
+  If ACPI I/O space not enabled, this function will enable it.
+  It will always return RETURN_SUCCESS.
+
+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+AcpiTimerLibConstructor (
+  VOID
+  )
+{
+  UINTN   Bus;
+  UINTN   Device;
+  UINTN   Function;
+  UINTN   EnableRegister;
+  UINT8   EnableMask;
+
+  //
+  // ASSERT for the invalid PCD values. They must be configured to the real value.
+  //
+  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);
+  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);
+
+  //
+  // If the register offset to the BAR for the ACPI I/O Port Base Address is 0x0000, then
+  // no PCI register programming is required to enable access to the the ACPI registers
+  // specified by PcdAcpiIoPortBaseAddress
+  //
+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {
+    return RETURN_SUCCESS;
+  }
+
+  //
+  // ASSERT for the invalid PCD values. They must be configured to the real value.
+  //
+  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);
+  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);
+  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);
+
+  //
+  // Retrieve the PCD values for the PCI configuration space required to program the ACPI I/O Port Base Address
+  //
+  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);
+  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);
+  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);
+  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);
+  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);
+
+  //
+  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and enable it.
+  //
+  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister)) & EnableMask) != EnableMask) {
+    PciWrite16 (
+      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16 (PcdAcpiIoPciBarRegisterOffset)),
+      PcdGet16 (PcdAcpiIoPortBaseAddress)
+      );
+    PciOr8 (
+      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),
+      EnableMask
+      );
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Internal function to retrieve the ACPI I/O Port Base Address.
+
+  Internal function to retrieve the ACPI I/O Port Base Address.
+
+  @return The 16-bit ACPI I/O Port Base Address.
+
+**/
+UINT16
+InternalAcpiGetAcpiTimerIoPort (
+  VOID
+  )
+{
+  UINT16  Port;
+
+  Port = PcdGet16 (PcdAcpiIoPortBaseAddress);
+
+  //
+  // If the register offset to the BAR for the ACPI I/O Port Base Address is not 0x0000, then
+  // read the PCI register for the ACPI BAR value in case the BAR has been programmed to a
+  // value other than PcdAcpiIoPortBaseAddress
+  //
+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {
+    Port = PciRead16 (PCI_LIB_ADDRESS (
+                        PcdGet8  (PcdAcpiIoPciBusNumber),
+                        PcdGet8  (PcdAcpiIoPciDeviceNumber),
+                        PcdGet8  (PcdAcpiIoPciFunctionNumber),
+                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)
+                        ));
+  }
+
+  return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16 (PcdAcpiPm1TmrOffset);
+}
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+VOID
+InternalAcpiDelay (
+  IN UINT32  Delay
+  )
+{
+  UINT16   Port;
+  UINT32   Ticks;
+  UINT32   Times;
+
+  Port   = InternalAcpiGetAcpiTimerIoPort ();
+  Times  = Delay >> 22;
+  Delay &= BIT22 - 1;
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks = IoBitFieldRead32 (Port, 0, 23) + Delay;
+    Delay = BIT22;
+    //
+    // Wait until time out
+    // Delay >= 2^23 could not be handled by this function
+    // Timer wrap-arounds are handled correctly by this function
+    //
+    while (((Ticks - IoBitFieldRead32 (Port, 0, 23)) & BIT23) == 0) {
+      CpuPause ();
+    }
+  } while (Times-- > 0);
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN UINTN  MicroSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                MicroSeconds,
+                ACPI_TIMER_FREQUENCY
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN UINTN  NanoSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                NanoSeconds,
+                ACPI_TIMER_FREQUENCY
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  Retrieves the current value of a 64-bit free running performance counter. The
+  counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return AsmReadTsc ();
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT UINT64  *StartValue,  OPTIONAL
+  OUT UINT64  *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 0xffffffffffffffffULL;
+  }
+  return InternalGetPerformanceCounterFrequency ();
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN UINT64  Ticks
+  )
+{
+  UINT64  Frequency;
+  UINT64  NanoSeconds;
+  UINT64  Remainder;
+  INTN    Shift;
+  Frequency = GetPerformanceCounterProperties (NULL, NULL);
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
+
+  //
+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
+  // i.e. highest bit set in Remainder should <= 33.
+  //
+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);
+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);
+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);
+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
+
+  return NanoSeconds;
+}
+
+//
+// OVERRIDE: OverrideBegin
+//
+/**
+  Calculate TSC frequency.
+
+  The TSC counting frequency is determined by using CPUID leaf 0x15 that is the preferred
+  method for Skylake and beyond.  Frequency in MHz = Core XTAL frequency * EBX/EAX.
+  In newer flavors of the CPU, core xtal frequency is returned in ECX (or 0 if not
+  supported).  If ECX is 0, 24MHz is assumed.
+  @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+  VOID
+  )
+{
+  UINT64      TscFrequency;
+  UINT64      CoreXtalFrequency;
+  UINT32      RegEax;
+  UINT32      RegEbx;
+  UINT32      RegEcx;
+
+  //
+  // Use CPUID leaf 0x15.
+  // TSC frequency = (Core Xtal Frequency) * EBX/EAX.  EBX returns 0 if not
+  // supported. ECX, if non zero, provides Core Xtal Frequency in hertz
+  // (SDM Dec 2016).
+  //
+  AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL);
+  ASSERT (RegEbx != 0);
+
+  //
+  // If core xtal frequency (ECX) returns 0, it is safe to use 24MHz for post
+  // Skylake client CPU's.
+  //
+  if (RegEcx == 0) {
+    CoreXtalFrequency = 24000000ul;
+  } else {
+    CoreXtalFrequency = (UINT64)RegEcx;
+  }
+
+  //
+  // Calculate frequency.  For integer division, round up/down result
+  // correctly by adding denominator/2 to the numerator prior to division.
+  //
+  TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UINT64)(RegEax >> 1), RegEax);
+
+  return TscFrequency;
+}
+//
+// OVERRIDE: OverrideEnd
+//
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
new file mode 100644
index 0000000000..2bba58eed3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
@@ -0,0 +1,612 @@
+/** @file
+  Source code for the board configuration init function in DXE init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <Library/HobLib.h>
+#include <MemInfoHob.h>
+#include <Library/PchSerialIoLib.h>
+#include <PlatformBoardConfig.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchEspiLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <TbtBoardInfo.h>
+#include <Library/CpuPlatformLib.h>
+#include <GopConfigLib.h>
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+GopVbtSpecificUpdateNull(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+
+//
+// for CFL U DDR4
+//
+VOID
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+
+/**
+  Updates DIMM slots status for Desktop,server and workstation boards
+
+**/
+VOID
+UpdateDimmPopulationConfig(
+  VOID
+  )
+{
+  MEMORY_INFO_DATA_HOB    *MemInfo;
+  UINT8                   Slot0;
+  UINT8                   Slot1;
+  UINT8                   Slot2;
+  UINT8                   Slot3;
+  CONTROLLER_INFO         *ControllerInfo;
+  EFI_HOB_GUID_TYPE       *GuidHob;
+
+  GuidHob = NULL;
+  MemInfo = NULL;
+
+  GuidHob = GetFirstGuidHob (&gSiMemoryInfoDataGuid);
+  ASSERT (GuidHob != NULL);
+  if (GuidHob != NULL) {
+    MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA (GuidHob);
+  }
+  if (MemInfo != NULL) {
+    if (PcdGet8 (PcdPlatformFlavor) == FlavorDesktop ||
+        PcdGet8 (PcdPlatformFlavor) == FlavorUpServer ||
+        PcdGet8 (PcdPlatformFlavor) == FlavorWorkstation) {
+      ControllerInfo = &MemInfo->Controller[0];
+      Slot0 = ControllerInfo->ChannelInfo[0].DimmInfo[0].Status;
+      Slot1 = ControllerInfo->ChannelInfo[0].DimmInfo[1].Status;
+      Slot2 = ControllerInfo->ChannelInfo[1].DimmInfo[0].Status;
+      Slot3 = ControllerInfo->ChannelInfo[1].DimmInfo[1].Status;
+
+      //
+      // Channel 0          Channel 1
+      // Slot0   Slot1      Slot0   Slot1      - Population            AIO board
+      // 0          0          0          0          - Invalid        - Invalid
+      // 0          0          0          1          - Valid          - Invalid
+      // 0          0          1          0          - Invalid        - Valid
+      // 0          0          1          1          - Valid          - Valid
+      // 0          1          0          0          - Valid          - Invalid
+      // 0          1          0          1          - Valid          - Invalid
+      // 0          1          1          0          - Invalid        - Invalid
+      // 0          1          1          1          - Valid          - Invalid
+      // 1          0          0          0          - Invalid        - Valid
+      // 1          0          0          1          - Invalid        - Invalid
+      // 1          0          1          0          - Invalid        - Valid
+      // 1          0          1          1          - Invalid        - Valid
+      // 1          1          0          0          - Valid          - Valid
+      // 1          1          0          1          - Valid          - Invalid
+      // 1          1          1          0          - Invalid        - Valid
+      // 1          1          1          1          - Valid          - Valid
+      //
+
+      if ((Slot0 && (Slot1 == 0)) || (Slot2 && (Slot3 == 0))) {
+        PcdSetBoolS (PcdDimmPopulationError, TRUE);
+      }
+    }
+  }
+}
+
+/**
+  Init Misc Platform Board Config Block.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInit (
+  IN UINT16 BoardId
+  )
+{
+//  PcdSet64S (PcdFuncBoardHookPlatformSetupOverride, (UINT64) (UINTN) BoardHookPlatformSetup);
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdPssReadSN, TRUE);
+      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
+      PcdSet8S (PcdPssI2cBusNumber, 0x04);
+      break;
+    default:
+      PcdSetBoolS (PcdPssReadSN, FALSE);
+      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
+      PcdSet8S (PcdPssI2cBusNumber, 0x04);
+      break;
+  }
+
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init Platform Board Config Block for ACPI platform.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+InitAcpiPlatformPcd (
+  IN UINT16 BoardId
+  )
+{
+  TBT_INFO_HOB  *TbtInfoHob = NULL;
+
+  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+
+  //
+  // Update OEM table ID
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      if ((TbtInfoHob != NULL) && (TbtInfoHob->DTbtControllerConfig[0].DTbtControllerEn == 1)) {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h', 'l', 't', '4'));
+      } else {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h', 'l', 'd', '4'));
+      }
+      break;
+    default:
+      PcdSet64S (PcdXhciAcpiTableSignature, 0);
+      break;
+  }
+
+  //
+  // Modify Preferred_PM_Profile field based on Board SKU's. Default is set to Mobile
+  //
+  PcdSet8S (PcdPreferredPmProfile, EFI_ACPI_2_0_PM_PROFILE_MOBILE);
+
+  //
+  // Assign FingerPrint, Gnss, TouchPanel, Audio related GPIO.
+  //
+  switch(BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdFingerPrintSleepGpio, GPIO_CNL_LP_GPP_B17);
+      PcdSet32S (PcdFingerPrintIrqGpio,   GPIO_CNL_LP_GPP_B16);
+      //
+      // Configure WWAN Reset pin
+      //
+      PcdSet32S (PcdGnssResetGpio,      GPIO_CNL_LP_GPP_F1);
+      PcdSet32S (PcdTouchpanelIrqGpio,  GPIO_CNL_LP_GPP_D10);
+      PcdSet32S (PcdTouchpadIrqGpio,    GPIO_CNL_LP_GPP_B3);
+      PcdSet32S (PcdHdaI2sCodecIrqGpio, GPIO_CNL_LP_GPP_C8);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Configure GPIOs for discrete USB BT module
+  //
+  switch(BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdBtIrqGpio,    GPIO_CNL_LP_GPP_B2);
+      PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Board Specific Init
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS(PcdWhlErbRtd3TableEnable, TRUE);
+      PcdSet8S (PcdHdaI2sCodecI2cBusNumber, 0); // I2S Audio Codec conntected to I2C0
+      PcdSet8S (PcdBleUsbPortNumber, 9);
+      break;
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init Common Platform Board Config Block.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+InitCommonPlatformPcd (
+  IN UINT16 BoardId
+  )
+{
+  PCD64_BLOB Data64;
+  TBT_INFO_HOB  *TbtInfoHob = NULL;
+
+  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+
+
+  //
+  // Enable EC SMI# for SMI
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdEcSmiGpio, GPIO_CNL_LP_GPP_E3);
+      PcdSet32S (PcdEcLowPowerExitGpio, GPIO_CNL_LP_GPP_B23);
+      break;
+  };
+
+  //
+  // HID I2C Interrupt GPIO.
+  //
+  switch (BoardId) {
+    default:
+      // on all supported boards interrupt input is on same GPIO pad. How convenient.
+      PcdSet32S (PcdHidI2cIntPad, GPIO_CNL_LP_GPP_D10);
+      break;
+  }
+
+  //
+  // PS2 KB Specific Init for Sds Serial platform.
+  //
+  if (BoardId == BoardIdWhiskeyLakeRvp) {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE);
+  } else {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck,  FALSE);
+  }
+
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdSpdAddressOverride, FALSE);
+      break;
+  }
+
+  //
+  // DDISelection
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdDDISelection, 1);
+      break;
+    default:
+      PcdSet8S (PcdDDISelection, 0);
+      break;
+  }
+
+  //
+  // GFX Detect
+  //
+  switch (BoardId) {
+    default:
+      // Not all the boards support GFX_CRB_DET. This is not an error.
+      Data64.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
+      break;
+  }
+
+  PcdSet64S (PcdGfxCrbDetectGpio, Data64.Blob);
+
+  //
+  // USB Type-C
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS(PcdUsbTypeCSupport, TRUE);
+      // Discete Ports
+      PcdSet8S(PcdTypeCPortsSupported, 2);
+      // TBT Port 1  mapping and properties [TBT AIC]
+      PcdSet8S(PcdUsbTypeCPort1, 1);
+      PcdSet8S(PcdUsbTypeCPort1Pch, 5);
+      // TBT Port 2  mapping and properties [TBT AIC]
+      PcdSet8S(PcdUsbTypeCPort2, 2);
+      PcdSet8S(PcdUsbTypeCPort2Pch, 7);
+      break;
+    default:
+      PcdSetBoolS (PcdUsbTypeCSupport, FALSE);
+      break;
+  }
+
+  //
+  // Battery Present
+  //
+  switch (BoardId) {
+  default:
+    PcdSet8S (PcdBatteryPresent, BOARD_REAL_BATTERY_SUPPORTED | BOARD_VIRTUAL_BATTERY_SUPPORTED);
+    break;
+  }
+
+  //
+  // TS-on-DIMM temperature
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdTsOnDimmTemperature, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdTsOnDimmTemperature, FALSE);
+      break;
+  }
+  //
+  // Real Battery 1 Control & Real Battery 2 Control
+  //
+  PcdSet8S (PcdRealBattery1Control, 1);
+  PcdSet8S (PcdRealBattery2Control, 2);
+
+  //
+  // Mipi Camera Sensor
+  //
+  PcdSetBoolS (PcdMipiCamSensor, FALSE);
+  //
+  // Mipi Camera Sensor Link Used
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdMipiCam0LinkUsed, 3);
+      PcdSet8S (PcdMipiCam1LinkUsed, 6);
+      PcdSet8S (PcdMipiCam2LinkUsed, 9);
+      PcdSet8S (PcdMipiCam3LinkUsed, 7);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // H8S2113 SIO
+  //
+  switch(BoardId) {
+    default:
+    PcdSetBoolS (PcdH8S2113SIO, FALSE);
+    break;
+  }
+
+
+  //
+  // NCT6776F COM, SIO & HWMON
+  //
+  PcdSetBoolS (PcdNCT6776FCOM, FALSE);
+  PcdSetBoolS (PcdNCT6776FSIO, FALSE);
+  PcdSetBoolS (PcdNCT6776FHWMON, FALSE);
+
+  //
+  // SMC Runtime Sci Pin
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdSmcRuntimeSciPin, (UINT32) GPIO_CNL_LP_GPP_E16);
+      break;
+    default:
+      PcdSet32S (PcdSmcRuntimeSciPin, 0x00);
+      break;
+  }
+
+  //
+  // Convertable Dock Support
+  //
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdConvertableDockSupport, FALSE);
+      break;
+  }
+
+  //
+  // Ec Hotkey F3, F4, F5, F6, F7 and F8 Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdEcHotKeyF3Support, 1);
+      PcdSet8S (PcdEcHotKeyF4Support, 1);
+      PcdSet8S (PcdEcHotKeyF5Support, 1);
+      PcdSet8S (PcdEcHotKeyF6Support, 1);
+      PcdSet8S (PcdEcHotKeyF7Support, 1);
+      PcdSet8S (PcdEcHotKeyF8Support, 1);
+      break;
+    default:
+      PcdSet8S (PcdEcHotKeyF3Support, 0);
+      PcdSet8S (PcdEcHotKeyF4Support, 0);
+      PcdSet8S (PcdEcHotKeyF5Support, 0);
+      PcdSet8S (PcdEcHotKeyF6Support, 0);
+      PcdSet8S (PcdEcHotKeyF7Support, 0);
+      PcdSet8S (PcdEcHotKeyF8Support, 0);
+      break;
+  }
+
+  //
+  // Virtual Button Volume Up & Done Support
+  // Virtual Button Home Button Support
+  // Virtual Button Rotation Lock Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, TRUE);
+      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, TRUE);
+      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
+      break;
+    default:
+      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
+      break;
+  }
+
+  //
+  // Slate Mode Switch Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdSlateModeSwitchSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdSlateModeSwitchSupport, FALSE);
+      break;
+  }
+
+  //
+  // Ac Dc Auto Switch Support
+  //
+  switch (BoardId) {
+  default:
+    PcdSetBoolS (PcdAcDcAutoSwitchSupport, TRUE);
+    break;
+  }
+
+  //
+  // Pm Power Button Gpio Pin
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3);
+      break;
+    default:
+      PcdSet32S (PcdPmPowerButtonGpioPin, 0x00);
+      break;
+  }
+
+  //
+  // Acpi Enable All Button Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // Acpi Hid Driver Button Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // USB Type C EC less
+  //
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdUsbTypeCEcLess, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check if given rootport has device connected and enable wake capability
+
+  @param[in]  RpNum           An unsigned integer represent the root port number.
+
+  @retval                     TRUE if endpoint was connected
+  @retval                     FALSE if no endpoint was detected
+**/
+BOOLEAN
+IsPcieEndPointPresent (
+  IN UINT8 RpNum
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         RpDev;
+  UINTN         RpFun;
+  UINT64        RpBaseAddress;
+
+  Status = GetPchPcieRpDevFun (RpNum, &RpDev, &RpFun);
+  if (!EFI_ERROR (Status)) {
+    //
+    // check if device is present
+    //
+    RpBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      RpDev,
+                      RpFun,
+                      0
+                      );
+
+    if ((PciSegmentRead16 (RpBaseAddress) != 0xFFFF) &&
+        (PciSegmentRead16 (RpBaseAddress + R_PCH_PCIE_CFG_SLSTS) & B_PCIE_SLSTS_PDS)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+
+}
+
+/**
+  Enable Tier2 GPIO Sci wake capability.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+Tier2GpioWakeSupport (
+  IN UINT16 BoardId
+  )
+{
+  BOOLEAN Tier2GpioWakeEnable;
+
+  Tier2GpioWakeEnable = FALSE;
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // Root port #14: M.2 WLAN
+      //
+      if (IsPcieEndPointPresent (13)) {
+        Tier2GpioWakeEnable = TRUE;
+      }
+      break;
+    default:
+      break;
+  }
+  PcdSetBoolS (PcdGpioTier2WakeEnable, Tier2GpioWakeEnable);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board configuration init function for DXE phase.
+
+  @param  Content  pointer to the buffer contain init information for board init.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+BoardConfigInit (
+    VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT16     BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = InitAcpiPlatformPcd (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = InitCommonPlatformPcd (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = BoardMiscInit (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = Tier2GpioWakeSupport (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
new file mode 100644
index 0000000000..eb7c3bbea0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <CpuPolicyInitDxe.h>
+
+DXE_CPU_POLICY_PROTOCOL mCpuPolicyData;
+
+/**
+  Initialize Intel CPU DXE Platform Policy
+
+  @param[in] ImageHandle        Image handle of this driver.
+
+  @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
+CpuPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS                Status;
+
+  ZeroMem(&mCpuPolicyData, sizeof (DXE_CPU_POLICY_PROTOCOL));
+  mCpuPolicyData.Revision                         = DXE_CPU_POLICY_PROTOCOL_REVISION;
+
+  UpdateDxeSiCpuPolicy(&mCpuPolicyData);
+
+  //
+  // Install CpuInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = CpuInstallPolicyProtocol(ImageHandle, &mCpuPolicyData);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
new file mode 100644
index 0000000000..66aab2d198
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
@@ -0,0 +1,174 @@
+/** @file
+  This file initialises and Installs GopPolicy Protocol.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GopPolicyInitDxe.h"
+#include <Protocol/GopPolicy.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL        mGOPPolicy;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32                     mVbtSize = 0;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS       mVbtAddress = 0;
+
+//
+// Function implementations
+//
+
+/**
+
+  @param[out] CurrentLidStatus
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_UNSUPPORTED
+**/
+
+EFI_STATUS
+EFIAPI
+GetPlatformLidStatus (
+  OUT LID_STATUS *CurrentLidStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  @param[out] CurrentDockStatus
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_UNSUPPORTED
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformDockStatus (
+  OUT DOCK_STATUS  CurrentDockStatus
+  )
+{
+    return EFI_UNSUPPORTED;
+}
+
+
+/**
+
+  @param[out] VbtAddress
+  @param[out] VbtSize
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_FOUND
+**/
+EFI_STATUS
+EFIAPI
+GetVbtData (
+  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
+  OUT UINT32               *VbtSize
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         FvProtocolCount;
+  EFI_HANDLE                    *FvHandles;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  UINTN                         Index;
+  UINT32                        AuthenticationStatus;
+  UINT8                         *Buffer;
+  UINTN                         VbtBufferSize;
+
+  Status = EFI_NOT_FOUND;
+  if ( mVbtAddress == 0) {
+    Fv           = NULL;
+    Buffer       = 0;
+    FvHandles    = NULL;
+    Status = gBS->LocateHandleBuffer (
+                    ByProtocol,
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    NULL,
+                    &FvProtocolCount,
+                    &FvHandles
+                    );
+    if (!EFI_ERROR (Status)) {
+      for (Index = 0; Index < FvProtocolCount; Index++) {
+        Status = gBS->HandleProtocol (
+                        FvHandles[Index],
+                        &gEfiFirmwareVolume2ProtocolGuid,
+                        (VOID **) &Fv
+                        );
+        VbtBufferSize = 0;
+        Status = Fv->ReadSection (
+                       Fv,
+                       PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
+                       EFI_SECTION_RAW,
+                       0,
+                       (VOID **) &Buffer,
+                       &VbtBufferSize,
+                       &AuthenticationStatus
+                       );
+        if (!EFI_ERROR (Status)) {
+          *VbtAddress = (EFI_PHYSICAL_ADDRESS)Buffer;
+          *VbtSize = (UINT32)VbtBufferSize;
+          mVbtAddress = *VbtAddress;
+          mVbtSize = *VbtSize;
+          Status = EFI_SUCCESS;
+          break;
+        }
+      }
+    } else {
+      Status = EFI_NOT_FOUND;
+    }
+
+    if (FvHandles != NULL) {
+      FreePool (FvHandles);
+      FvHandles = NULL;
+    }
+  } else {
+    *VbtAddress = mVbtAddress;
+    *VbtSize = mVbtSize;
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+/**
+Initialize GOP DXE Policy
+
+@param[in] ImageHandle          Image handle of this driver.
+
+@retval EFI_SUCCESS             Initialization complete.
+@retval 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
+GopPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Initialize the EFI Driver Library
+  //
+  SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0);
+
+  mGOPPolicy.Revision                = GOP_POLICY_PROTOCOL_REVISION_03;
+  mGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
+  mGOPPolicy.GetVbtData              = GetVbtData;
+  mGOPPolicy.GetPlatformDockStatus   = GetPlatformDockStatus;
+
+  //
+  // Install protocol to allow access to this Policy.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gGopPolicyProtocolGuid,
+                  &mGOPPolicy,
+                  NULL
+                  );
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
new file mode 100644
index 0000000000..2a1604fa13
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
@@ -0,0 +1,55 @@
+/** @file
+  This file is SampleCode for PCH DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchPolicyInitDxe.h"
+
+//
+// Function implementations
+//
+
+/**
+  Initialize PCH DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @retval EFI_SUCCESS             Initialization complete.
+  @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
+PchPolicyInitDxe (
+  IN EFI_HANDLE                   ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+  PCH_POLICY_PROTOCOL      *PchPolicy;
+
+  //
+  // Call CreatePchDxeConfigBlocks to create & initialize platform policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = CreatePchDxeConfigBlocks (&PchPolicy);
+  DEBUG((DEBUG_INFO, "PchPolicy->TableHeader.NumberOfBlocks = 0x%x\n", PchPolicy->TableHeader.NumberOfBlocks));
+  ASSERT_EFI_ERROR (Status);
+
+  if (mFirmwareConfiguration != FwConfigDefault) {
+    UpdateDxePchPolicy (PchPolicy);
+  }
+
+  //
+  // Install PchInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = PchInstallPolicyProtocol (ImageHandle, PchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
new file mode 100644
index 0000000000..ccaa57ce16
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
@@ -0,0 +1,88 @@
+/** @file
+  This file is a wrapper for Platform Policy driver. Get Setup
+  Value to initialize Intel DXE Platform Policy.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PolicyInitDxe.h"
+#include <CpuSmm.h>
+#include "BoardInitLib.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8            mFirmwareConfiguration = 0;
+
+/**
+  Initialize  DXE Platform Policy
+
+  @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
+PolicyInitDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS           Status;
+
+  Status = BoardConfigInit();
+
+  mFirmwareConfiguration = FwConfigProduction;
+  //
+  // SystemAgent Dxe Platform Policy Initialization
+  //
+  Status = SaPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "SystemAgent Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // PCH Dxe Platform Policy Initialization
+  //
+  Status = PchPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "PCH Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Silicon Dxe Platform Policy Initialization
+  //
+  Status = SiliconPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "Silicon Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // CPU DXE Platform Policy Initialization
+  //
+  Status = CpuPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "Cpu Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+
+  if (PcdGetBool(PcdIntelGopEnable)) {
+    //
+    // GOP Dxe Policy Initialization
+    //
+    Status = GopPolicyInitDxe(ImageHandle);
+    DEBUG((DEBUG_INFO, "GOP Dxe Policy Initialization done\n"));
+    ASSERT_EFI_ERROR(Status);
+  }
+  if (PcdGetBool(PcdTbtEnable)) {
+    //
+    // Update TBT Policy
+    //
+    Status = InstallTbtPolicy (ImageHandle);
+    DEBUG ((DEBUG_INFO, "Install Tbt Policy done\n"));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
new file mode 100644
index 0000000000..c0095c09c3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode for SA DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaPolicyInitDxe.h"
+
+
+//
+// Function implementations
+//
+
+/**
+  Initialize SA DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @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
+SaPolicyInitDxe (
+  IN EFI_HANDLE                   ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+  SA_POLICY_PROTOCOL       *SaPolicy;
+
+  //
+  // Call CreateSaDxeConfigBlocks to create & initialize platform policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = CreateSaDxeConfigBlocks(&SaPolicy);
+  DEBUG((DEBUG_INFO, "SaPolicy->TableHeader.NumberOfBlocks = 0x%x\n ", SaPolicy->TableHeader.NumberOfBlocks));
+  ASSERT_EFI_ERROR(Status);
+
+  UpdateDxeSaPolicyBoardConfig (SaPolicy);
+
+  if (mFirmwareConfiguration != FwConfigDefault) {
+
+    UpdateDxeSaPolicy (SaPolicy);
+  }
+
+  //
+  // Install SaInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SaInstallPolicyProtocol (ImageHandle, SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
new file mode 100644
index 0000000000..15adca5cdd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <SiliconPolicyInitDxe.h>
+#include <Library/BaseLib.h>
+
+DXE_SI_POLICY_PROTOCOL mSiPolicyData  = { 0 };
+
+/**
+  Initilize Intel Cpu DXE Platform Policy
+
+  @param[in] ImageHandle        Image handle of this driver.
+
+  @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
+SiliconPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS Status;
+
+  mSiPolicyData.Revision                         = DXE_SI_POLICY_PROTOCOL_REVISION;
+
+  ///
+  /// Install the DXE_SI_POLICY_PROTOCOL interface
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gDxeSiPolicyProtocolGuid,
+                  &mSiPolicyData,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
new file mode 100644
index 0000000000..7e44f5585a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
@@ -0,0 +1,20 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+///////////////////////////////////////////////////////////////////////////////////
+//Values are set like this to have ASL compiler reserve enough space for objects
+///////////////////////////////////////////////////////////////////////////////////
+//
+// Available Sleep states
+//
+Name(SS1,0)
+Name(SS2,0)
+Name(SS3,1)
+Name(SS4,1)
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
new file mode 100644
index 0000000000..dd85f07bd2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
@@ -0,0 +1,37 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformBoardId.h"
+
+DefinitionBlock (
+  "DSDT.aml",
+  "DSDT",
+  0x02, // DSDT revision.
+        // A Revision field value greater than or equal to 2 signifies that integers
+        // declared within the Definition Block are to be evaluated as 64-bit values
+  "INTEL",   // OEM ID (6 byte string)
+  "WHL     ",// OEM table ID  (8 byte string)
+  0x0 // OEM version of DSDT table (4 byte Integer)
+)
+
+// BEGIN OF ASL SCOPE
+{
+  // Miscellaneous services enabled in Project
+  Include ("AMLUPD.asl")
+  Include ("PciTree.asl")
+  Include ("Platform.asl")
+
+  Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state
+  if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})}
+  if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})}
+  if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})}
+  Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state
+
+}// End of ASL File
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
new file mode 100644
index 0000000000..aa302b6e3b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
@@ -0,0 +1,516 @@
+/** @file
+  This file contains the SystemAgent PCI Configuration space
+  definition.
+  It defines various System Agent PCI Configuration Space registers
+  which will be used to dynamically produce all resources in the Host Bus.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x40),   // EPBAR (0:0:0:40)
+  EPEN, 1,        // Enable
+      , 11,
+  EPBR, 20,       // EPBAR [31:12]
+
+  Offset(0x48),   // MCHBAR (0:0:0:48)
+  MHEN, 1,        // Enable
+      , 14,
+  MHBR, 17,       // MCHBAR [31:15]
+
+  Offset(0x50),   // GGC (0:0:0:50)
+  GCLK, 1,        // GGCLCK
+
+  Offset(0x54),   // DEVEN (0:0:0:54)
+  D0EN, 1,        // DEV0 Enable
+  D1F2, 1,        // DEV1 FUN2 Enable
+  D1F1, 1,        // DEV1 FUN1 Enable
+  D1F0, 1,        // DEV1 FUN0 Enable
+
+  Offset(0x60),   // PCIEXBAR (0:0:0:60)
+  PXEN, 1,        // Enable
+  PXSZ, 2,        // PCI Express Size
+      , 23,
+  PXBR, 6,        // PCI Express BAR [31:26]
+
+  Offset(0x68),   // DMIBAR (0:0:0:68)
+  DIEN, 1,        // Enable
+      , 11,
+  DIBR, 20,       // DMIBAR [31:12]
+
+  Offset(0x70),   // MESEG_BASE (0:0:0:70)
+      , 20,
+  MEBR, 12,       // MESEG_BASE [31:20]
+
+  Offset(0x80),   // PAM0 Register (0:0:0:80)
+  PMLK, 1,        // PAM Lock bit.
+      , 3,
+  PM0H, 2,        // PAM 0, High Nibble
+      , 2,
+
+  Offset(0x81),   // PAM1 Register (0:0:0:81)
+  PM1L, 2,        // PAM1, Low  Nibble
+      , 2,
+  PM1H, 2,        // PAM1, High Nibble
+      , 2,
+
+  Offset(0x82),   // PAM2 Register (0:0:0:82)
+  PM2L, 2,        // PAM2, Low  Nibble
+      , 2,
+  PM2H, 2,        // PAM2, High Nibble
+      , 2,
+
+  Offset(0x83),   // PAM3 Register (0:0:0:83)
+  PM3L, 2,        // PAM3, Low  Nibble
+      , 2,
+  PM3H, 2,        // PAM3, High Nibble
+      , 2,
+
+  Offset(0x84),   // PAM4 Register (0:0:0:84)
+  PM4L, 2,        // PAM4, Low  Nibble
+      , 2,
+  PM4H, 2,        // PAM4, High Nibble
+      , 2,
+
+  Offset(0x85),   // PAM5 Register (0:0:0:85)
+  PM5L, 2,        // PAM5, Low  Nibble
+      , 2,
+  PM5H, 2,        // PAM5, High Nibble
+      , 2,
+
+  Offset(0x86),   // PAM6 Register (0:0:0:86)
+  PM6L, 2,        // PAM6, Low  Nibble
+      , 2,
+  PM6H, 2,        // PAM6, High Nibble
+      , 2,
+
+  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
+      , 20,
+  TUUD, 19,       // TOUUD [38:20]
+
+  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
+      , 20,
+  TLUD, 12,       // TOLUD [31:20]
+
+  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
+      , 7,
+  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus.  This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+  //
+  // Bus Number Allocation: Bus 0 to 0xFF
+  //
+  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+    0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+  //
+  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+  //
+  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+  //
+  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+  //
+  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+  //
+  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+  //
+  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+  //
+  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+  //
+  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+  //
+  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+  //
+  // BIOS Area ( 0xF0000 - 0xFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+//  //
+//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+//  //
+//  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+  //
+  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+  //
+  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+  // (This is dummy range for OS compatibility, will patch it in _CRS)
+  //
+  QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+  if(LEqual(EP_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+  }
+  Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+  if(LEqual(MH_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+  }
+  Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+  if(LEqual(PC_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+  }
+  Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+  if(LEqual(PC_L,0)) {
+    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+  }
+  Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+  if(LEqual(DM_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+  }
+  Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+  //
+  // Fix up Max Bus Number and Length
+  //
+  Store(\_SB.PCI0.GPCL(),Local0)
+  CreateWordField(BUF0, ^PB00._MAX, PBMX)
+  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+  CreateWordField(BUF0, ^PB00._LEN, PBLN)
+  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+  //
+  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+  //
+  If(PM1L)  // \_SB.PCI0
+  {
+    // PAMx != 0.  Set length = 0.
+
+    CreateDwordField(BUF0, ^C000._LEN,C0LN)
+    Store(Zero,C0LN)
+  }
+
+  If(LEqual(PM1L,1))
+  {
+    CreateBitField(BUF0, ^C000._RW,C0RW)
+    Store(Zero,C0RW)
+  }
+
+  If(PM1H)
+  {
+    CreateDwordField(BUF0, ^C400._LEN,C4LN)
+    Store(Zero,C4LN)
+  }
+
+  If(LEqual(PM1H,1))
+  {
+    CreateBitField(BUF0, ^C400._RW,C4RW)
+    Store(Zero,C4RW)
+  }
+
+  If(PM2L)
+  {
+    CreateDwordField(BUF0, ^C800._LEN,C8LN)
+    Store(Zero,C8LN)
+  }
+
+  If(LEqual(PM2L,1))
+  {
+    CreateBitField(BUF0, ^C800._RW,C8RW)
+    Store(Zero,C8RW)
+  }
+
+  If(PM2H)
+  {
+    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+    Store(Zero,CCLN)
+  }
+
+  If(LEqual(PM2H,1))
+  {
+    CreateBitField(BUF0, ^CC00._RW,CCRW)
+    Store(Zero,CCRW)
+  }
+
+  If(PM3L)
+  {
+    CreateDwordField(BUF0, ^D000._LEN,D0LN)
+    Store(Zero,D0LN)
+  }
+
+  If(LEqual(PM3L,1))
+  {
+    CreateBitField(BUF0, ^D000._RW,D0RW)
+    Store(Zero,D0RW)
+  }
+
+  If(PM3H)
+  {
+    CreateDwordField(BUF0, ^D400._LEN,D4LN)
+    Store(Zero,D4LN)
+  }
+
+  If(LEqual(PM3H,1))
+  {
+    CreateBitField(BUF0, ^D400._RW,D4RW)
+    Store(Zero,D4RW)
+  }
+
+  If(PM4L)
+  {
+    CreateDwordField(BUF0, ^D800._LEN,D8LN)
+    Store(Zero,D8LN)
+  }
+
+  If(LEqual(PM4L,1))
+  {
+    CreateBitField(BUF0, ^D800._RW,D8RW)
+    Store(Zero,D8RW)
+  }
+
+  If(PM4H)
+  {
+    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+    Store(Zero,DCLN)
+  }
+
+  If(LEqual(PM4H,1))
+  {
+    CreateBitField(BUF0, ^DC00._RW,DCRW)
+    Store(Zero,DCRW)
+  }
+
+  If(PM5L)
+  {
+    CreateDwordField(BUF0, ^E000._LEN,E0LN)
+    Store(Zero,E0LN)
+  }
+
+  If(LEqual(PM5L,1))
+  {
+    CreateBitField(BUF0, ^E000._RW,E0RW)
+    Store(Zero,E0RW)
+  }
+
+  If(PM5H)
+  {
+    CreateDwordField(BUF0, ^E400._LEN,E4LN)
+    Store(Zero,E4LN)
+  }
+
+  If(LEqual(PM5H,1))
+  {
+    CreateBitField(BUF0, ^E400._RW,E4RW)
+    Store(Zero,E4RW)
+  }
+
+  If(PM6L)
+  {
+    CreateDwordField(BUF0, ^E800._LEN,E8LN)
+    Store(Zero,E8LN)
+  }
+
+  If(LEqual(PM6L,1))
+  {
+    CreateBitField(BUF0, ^E800._RW,E8RW)
+    Store(Zero,E8RW)
+  }
+
+  If(PM6H)
+  {
+    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+    Store(Zero,ECLN)
+  }
+
+  If(LEqual(PM6H,1))
+  {
+    CreateBitField(BUF0, ^EC00._RW,ECRW)
+    Store(Zero,ECRW)
+  }
+
+  If(PM0H)
+  {
+    CreateDwordField(BUF0, ^F000._LEN,F0LN)
+    Store(Zero,F0LN)
+  }
+
+  If(LEqual(PM0H,1))
+  {
+    CreateBitField(BUF0, ^F000._RW,F0RW)
+    Store(Zero,F0RW)
+  }
+
+  //
+  // Create pointers to Memory Sizing values.
+  //
+  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+  //
+  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+  // TOM, so shift these bits into the correct position and fix up
+  // the Memory Region available to PCI.
+  //
+  Store (0x50800000, M1LN)
+  Store (0x8F800000, M1MN)
+  Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+  //
+  // Create pointers to Memory Sizing values.
+  // Patch PM02 range basing on memory size and OS type
+  //
+  CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+  //
+  // Set resource length to 0
+  //
+  Store (0, MSLN)
+
+  D8XH (0, 0xC5)
+  D8XH (1, 0xAA)
+
+  Return(BUF0)
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
new file mode 100644
index 0000000000..ff3b0dbe08
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
@@ -0,0 +1,309 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Scope(\_SB) {
+  Name(PD00, Package(){
+// If the setting changed in PCH PxRcConfig policy, platform should also update static assignment here.
+// PCI Bridge
+// D31: cAVS, SMBus, GbE, Nothpeak
+    Package(){0x001FFFFF, 0, 0, 11 },
+    Package(){0x001FFFFF, 1, 0, 10 },
+    Package(){0x001FFFFF, 2, 0, 11 },
+    Package(){0x001FFFFF, 3, 0, 11 },
+// D30: SerialIo and SCS - can't use PIC
+// D29: PCI Express Port 9-16
+    Package(){0x001DFFFF, 0, 0, 11 },
+    Package(){0x001DFFFF, 1, 0, 10 },
+    Package(){0x001DFFFF, 2, 0, 11 },
+    Package(){0x001DFFFF, 3, 0, 11 },
+// D28: PCI Express Port 1-8
+    Package(){0x001CFFFF, 0, 0, 11 },
+    Package(){0x001CFFFF, 1, 0, 10 },
+    Package(){0x001CFFFF, 2, 0, 11 },
+    Package(){0x001CFFFF, 3, 0, 11 },
+// D27: PCI Express Port 17-20
+    Package(){0x001BFFFF, 0, 0, 11 },
+    Package(){0x001BFFFF, 1, 0, 10 },
+    Package(){0x001BFFFF, 2, 0, 11 },
+    Package(){0x001BFFFF, 3, 0, 11 },
+// D25: SerialIo - can't use PIC
+// D23: SATA controller
+    Package(){0x0017FFFF, 0, 0, 11 },
+// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
+    Package(){0x0016FFFF, 0, 0, 11 },
+    Package(){0x0016FFFF, 1, 0, 10 },
+    Package(){0x0016FFFF, 2, 0, 11 },
+    Package(){0x0016FFFF, 3, 0, 11 },
+// D21: SerialIo - can't use PIC
+// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
+// D20: xHCI, OTG, CNVi WiFi, SDcard
+    Package(){0x0014FFFF, 0, 0, 11 },
+    Package(){0x0014FFFF, 1, 0, 10 },
+    Package(){0x0014FFFF, 2, 0, 11 },
+    Package(){0x0014FFFF, 3, 0, 11 },
+// D19: Integrated Sensor Hub - can't use PIC
+// D18: Thermal, UFS, SerialIo SPI2 - can't use PIC
+    Package(){0x0012FFFF, 0, 0, 11 },
+    Package(){0x0012FFFF, 1, 0, 10 },
+    Package(){0x0012FFFF, 2, 0, 11 },
+    Package(){0x0012FFFF, 3, 0, 11 },
+
+// Host Bridge
+// P.E.G. Root Port D1F0
+    Package(){0x0001FFFF, 0, 0, 11 },
+    Package(){0x0001FFFF, 1, 0, 10 },
+    Package(){0x0001FFFF, 2, 0, 11 },
+    Package(){0x0001FFFF, 3, 0, 11 },
+// P.E.G. Root Port D1F1
+// P.E.G. Root Port D1F2
+// SA IGFX Device
+    Package(){0x0002FFFF, 0, 0, 11 },
+// SA Thermal Device
+    Package(){0x0004FFFF, 0, 0, 11 },
+// SA IPU Device
+    Package(){0x0005FFFF, 0, 0, 11 },
+// SA GNA Device
+    Package(){0x0008FFFF, 0, 0, 11 },
+  })
+  Name(AR00, Package(){
+// PCI Bridge
+// D31: cAVS, SMBus, GbE, Nothpeak
+    Package(){0x001FFFFF, 0, 0, 16 },
+    Package(){0x001FFFFF, 1, 0, 17 },
+    Package(){0x001FFFFF, 2, 0, 18 },
+    Package(){0x001FFFFF, 3, 0, 19 },
+// D30: SerialIo and SCS
+    Package(){0x001EFFFF, 0, 0, 20 },
+    Package(){0x001EFFFF, 1, 0, 21 },
+    Package(){0x001EFFFF, 2, 0, 22 },
+    Package(){0x001EFFFF, 3, 0, 23 },
+// D29: PCI Express Port 9-16
+    Package(){0x001DFFFF, 0, 0, 16 },
+    Package(){0x001DFFFF, 1, 0, 17 },
+    Package(){0x001DFFFF, 2, 0, 18 },
+    Package(){0x001DFFFF, 3, 0, 19 },
+// D28: PCI Express Port 1-8
+    Package(){0x001CFFFF, 0, 0, 16 },
+    Package(){0x001CFFFF, 1, 0, 17 },
+    Package(){0x001CFFFF, 2, 0, 18 },
+    Package(){0x001CFFFF, 3, 0, 19 },
+// D27: PCI Express Port 17-20
+    Package(){0x001BFFFF, 0, 0, 16 },
+    Package(){0x001BFFFF, 1, 0, 17 },
+    Package(){0x001BFFFF, 2, 0, 18 },
+    Package(){0x001BFFFF, 3, 0, 19 },
+// D26: eMMC
+    Package(){0x001AFFFF, 0, 0, 16 },
+    Package(){0x001AFFFF, 1, 0, 17 },
+    Package(){0x001AFFFF, 2, 0, 18 },
+    Package(){0x001AFFFF, 3, 0, 19 },
+// D25: SerialIo
+    Package(){0x0019FFFF, 0, 0, 32 },
+    Package(){0x0019FFFF, 1, 0, 33 },
+    Package(){0x0019FFFF, 2, 0, 34 },
+// D23: SATA controller
+    Package(){0x0017FFFF, 0, 0, 16 },
+// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
+    Package(){0x0016FFFF, 0, 0, 16 },
+    Package(){0x0016FFFF, 1, 0, 17 },
+    Package(){0x0016FFFF, 2, 0, 18 },
+    Package(){0x0016FFFF, 3, 0, 19 },
+// D21: SerialIo
+    Package(){0x0015FFFF, 0, 0, 16 },
+    Package(){0x0015FFFF, 1, 0, 17 },
+    Package(){0x0015FFFF, 2, 0, 18 },
+    Package(){0x0015FFFF, 3, 0, 19 },
+// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
+// D20: xHCI, OTG, CNVi WiFi, SDcard
+    Package(){0x0014FFFF, 0, 0, 16 },
+    Package(){0x0014FFFF, 1, 0, 17 },
+    Package(){0x0014FFFF, 2, 0, 18 },
+    Package(){0x0014FFFF, 3, 0, 19 },
+// D19: Integrated Sensor Hub
+    Package(){0x0013FFFF, 0, 0, 20 },
+// D18: Thermal, UFS, SerialIo SPI 2
+    Package(){0x0012FFFF, 0, 0, 16 },
+    Package(){0x0012FFFF, 1, 0, 24 },
+    Package(){0x0012FFFF, 2, 0, 18 },
+    Package(){0x0012FFFF, 3, 0, 19 },
+
+// Host Bridge
+// P.E.G. Root Port D1F0
+    Package(){0x0001FFFF, 0, 0, 16 },
+    Package(){0x0001FFFF, 1, 0, 17 },
+    Package(){0x0001FFFF, 2, 0, 18 },
+    Package(){0x0001FFFF, 3, 0, 19 },
+// P.E.G. Root Port D1F1
+// P.E.G. Root Port D1F2
+// SA IGFX Device
+    Package(){0x0002FFFF, 0, 0, 16 },
+// SA Thermal Device
+    Package(){0x0004FFFF, 0, 0, 16 },
+// SA IPU Device
+    Package(){0x0005FFFF, 0, 0, 16 },
+// SA GNA Device
+    Package(){0x0008FFFF, 0, 0, 16 },
+  })
+  Name(PD04, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR04, Package(){
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD05, Package(){
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR05, Package(){
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD06, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR06, Package(){
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+  Name(PD07, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 10 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR07, Package(){
+    Package(){0x0000FFFF, 0, 0, 19 },
+    Package(){0x0000FFFF, 1, 0, 16 },
+    Package(){0x0000FFFF, 2, 0, 17 },
+    Package(){0x0000FFFF, 3, 0, 18 },
+  })
+  Name(PD08, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR08, Package(){
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD09, Package(){
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR09, Package(){
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD0E, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR0E, Package(){
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+  Name(PD0F, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 10 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR0F, Package(){
+    Package(){0x0000FFFF, 0, 0, 19 },
+    Package(){0x0000FFFF, 1, 0, 16 },
+    Package(){0x0000FFFF, 2, 0, 17 },
+    Package(){0x0000FFFF, 3, 0, 18 },
+  })
+  Name(PD02, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR02, Package(){
+// P.E.G. Port Slot x16
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD0A, Package(){
+// P.E.G. Port Slot x8
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR0A, Package(){
+// P.E.G. Port Slot x8
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD0B, Package(){
+// P.E.G. Port Slot x4
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR0B, Package(){
+// P.E.G. Port Slot x4
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+
+//---------------------------------------------------------------------------
+// Begin PCI tree object scope
+//---------------------------------------------------------------------------
+  Device(PCI0) { // PCI Bridge "Host Bridge"
+    Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2 host hierarchy
+    Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't understand the new HID
+    Name(_SEG, 0)
+    Name(_ADR, 0x00000000)
+    Method(^BN00, 0){ return(0x0000) }  // Returns default Bus number for Peer PCI busses. Name can be overriden with control method placed directly under Device scope
+    Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root PCI Bus
+    Name(_UID, 0x0000)  // Unique Bus ID, optional
+    Method(_PRT,0) {
+      If(PICM) {Return(AR00)} // APIC mode
+      Return (PD00) // PIC Mode
+    } // end _PRT
+
+  Include("HostBus.asl")
+  } // end PCI0 Bridge "Host Bridge"
+} // end _SB scope
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
new file mode 100644
index 0000000000..951c01455f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
@@ -0,0 +1,76 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+// Define Port 80 as an ACPI Operating Region to use for debugging.  Please
+// note that the Intel CRBs have the ability to ouput a Word to
+// Port 80h for debugging purposes, so the model implemented here may not be
+// able to be used on OEM Designs.
+
+OperationRegion(PRT0,SystemIO,0x80,2)
+Field(PRT0,WordAcc,Lock,Preserve)
+{
+  P80B, 16
+}
+
+// Port 80h Update:
+//    Update 2 bytes of Port 80h.
+//
+//  Arguments:
+//    Arg0: 0 = Write Port 80h
+//          1 = Write Port 81h
+//    Arg1: 8-bit Value to write
+//
+//  Return Value:
+//    None
+
+Name(P80T, 0) // temp buffer for P80
+
+Method(D8XH,2,Serialized)
+{
+  If(LEqual(Arg0,0))    // Write Port 80h
+  {
+    Store(Or(And(P80T,0xFF00),Arg1),P80T)
+  }
+  If(LEqual(Arg0,1))    // Write Port 81h
+  {
+    Store(Or(And(P80T,0x00FF),ShiftLeft(Arg1,8)),P80T)
+  }
+  Store(P80T,P80B)
+}
+
+//
+// Define SW SMI port as an ACPI Operating Region to use for generate SW SMI.
+//
+OperationRegion(SPRT,SystemIO, 0xB2,2)
+Field (SPRT, ByteAcc, Lock, Preserve) {
+  SSMP, 8
+}
+
+// The _PIC Control Method is optional for ACPI design.  It allows the
+// OS to inform the ASL code which interrupt controller is being used,
+// the 8259 or APIC.  The reference code in this document will address
+// PCI IRQ Routing and resource allocation for both cases.
+//
+// The values passed into _PIC are:
+//   0 = 8259
+//   1 = IOAPIC
+
+Method(\_PIC,1)
+{
+  Store(Arg0,PICM)
+}
+
+Scope (\)
+{
+  //
+  // Global Name, returns current Interrupt controller mode;
+  // updated from _PIC control method
+  //
+  Name(PICM, 0)
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
new file mode 100644
index 0000000000..38d60d6dbd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
@@ -0,0 +1,405 @@
+/** @file
+  ACPI RTD3 SSDT table for SPT PCIe
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#define PID_ICC                                   0xDC
+#define R_PCH_PCR_ICC_MSKCKRQ                     0x100C                  ///< Mask Control CLKREQ
+
+External(PCRA,MethodObj)
+External(PCRO,MethodObj)
+External(\MMRP, MethodObj)
+External(\MMTB, MethodObj)
+External(\TRDO, IntObj)
+External(\TRD3, IntObj)
+External(\TBPE, IntObj)
+External(\TOFF, IntObj)
+External(\TBSE, IntObj)
+External(\TBOD, IntObj)
+External(\TBRP, IntObj)
+External(\TBHR, IntObj)
+External(\RTBC, IntObj)
+External(\TBCD, IntObj)
+
+Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
+
+Name(WKEN, 0)
+
+  Method(_S0W, 0)
+  {
+  /// This method returns the lowest D-state supported by PCIe root port during S0 state
+
+   ///- PMEs can be generated from D3hot for ULT
+      Return(4)
+
+  /** @defgroup pcie_s0W PCIE _S0W **/
+  } // End _S0W
+
+  Method (_DSD, 0) {
+    Return (
+      Package () {
+        ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
+        Package () {
+          Package (2) {"HotPlugSupportInD3", 1},
+        }
+      }
+    ) // End of Return ()
+  }
+
+    Method(_DSW, 3)
+    {
+    /// This method is used to enable/disable wake from PCIe (WKEN)
+      If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE# from generating runtime PME
+                                    /// Also set 2 to TOFF.
+        Store(0, WKEN)
+        Store (2, TOFF)
+      } Else {  /// If Staying in S0
+        If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
+        { ///- Set PME
+          Store(1, WKEN)
+          Store (1, TOFF)
+        } Else { ///- Disable runtime PME, either because staying in D0 or disabling wake
+          Store(0, WKEN)
+          Store(0, TOFF)
+        }
+      }
+
+    /** @defgroup pcie_dsw PCIE _DSW **/
+    } // End _DSW
+
+
+    PowerResource(PXP, 0, 0)
+    {
+    /// Define the PowerResource for PCIe slot
+    /// Method: _STA(), _ON(), _OFF()
+    /** @defgroup pcie_pxp PCIE Power Resource **/
+
+      Method(_STA, 0)
+      {
+          Return(PSTA())
+      }  /** @defgroup pcie_sta PCIE _STA method **/
+
+      Method(_ON) /// Turn on core power to PCIe Slot
+      {
+        Store(1, TRDO)
+        PON()
+        Store(0, TRDO)
+      } /** @defgroup pcie_on PCIE _ON method **/
+
+      Method(_OFF) /// Turn off core power to PCIe Slot
+      {
+        Store(1, TRD3)
+        POFF()
+        Store(0, TRD3)
+      } // End of Method_OFF
+    } // End PXP
+
+    Method(PSTA, 0)
+    {
+    /// Returns the status of PCIe slot core power
+      // detect power pin status
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) {
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          if(LEqual(\_SB.GGOV(DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // GPIO mode
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // IOEX mode
+      }
+      // detect reset pin status
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) {
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          if(LEqual(\_SB.GGOV(DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // GPIO mode
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2))  { // IOEX mode
+          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // IOEX mode
+      }
+      Return (0)
+    }  /** @defgroup pcie_sta PCIE _STA method **/
+
+    Method (SXEX, 0, Serialized) {
+
+      Store(\MMTB(TBSE), Local7)
+      OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(100, Local1)
+      Store(0x09, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT
+      While (LGreater(Local1, 0)) {
+
+        Store(Subtract(Local1, 1), Local1)
+        Store(TB2P, Local2)
+        If (LEqual(Local2, 0xFFFFFFFF)) { // Device gone
+          Return()
+        }
+        If (And(Local2, 1)) { // Done
+          break
+        }
+        Sleep(5)
+      }
+      Store(0x0, P2TB) // Write 0 to PCIe2TBT
+
+      // Fast Link bring-up flow
+      Store(500, Local1)
+      While (LGreater(Local1, 0)) {
+        Store(Subtract(Local1, 1), Local1)
+        Store(TB2P, Local2)
+        If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
+          Return()
+        }
+        If (LNotEqual(DIVI, 0xFFFFFFFF)) {
+          break
+        }
+        Sleep(10)
+      }
+    } // End of Method(SXEX, 0, Serialized)
+
+    Method(PON) /// Turn on core power to PCIe Slot
+    {
+
+      Store(\MMRP(\TBSE), Local7)
+      OperationRegion(L23P,SystemMemory,Local7,0xE4)
+      Field(L23P,WordAcc, NoLock, Preserve)
+      {
+        Offset(0xA4),// PMCSR
+        PSD0, 2, // PowerState
+        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+        , 2,
+        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
+        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+      }
+
+      Store(\MMTB(\TBSE), Local6)
+      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0xA4),
+        TBPS, 2, // PowerState of TBT
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(0, TOFF)
+      // Check RTD3 power enable, if already ON, no need to execute sx_exit
+      If (TBPE) {
+        Return()
+      }
+
+      Store(0,G2SD)
+      If (\RTBC) {
+        /// de-assert CLK_REQ MSK
+        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+          PCRA(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,Not(DeRefOf(Index(SCLK, 1))))  // And ~SCLK to clear bit
+        }
+        Sleep(\TBCD)
+      }
+
+      /// Turn ON Power for PCIe Slot
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+          Store(1, TBPE)
+          Sleep(PEP0)     /// Sleep for programmable delay
+        }
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+          Store(1, TBPE)
+          Sleep(PEP0)     /// Sleep for programmable delay
+        }
+      }
+
+      /// De-Assert Reset Pin
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+        }
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+        }
+      }
+
+      /// Clear DLSULPPGE, then set L23_Rdy to Detect Transition  (L23R2DT)
+      Store(0, DPGE)
+      Store(1, L2TR)
+      Sleep(16)
+      Store(0, Local0)
+      /// Wait up to 12 ms for transition to Detect
+      While(L2TR) {
+        If(Lgreater(Local0, 4))    // Debug - Wait for 5 ms
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      /// 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(1, DPGE)
+      Store(0, Local0)
+      While(LEqual(LASX,0)) {
+        If(Lgreater(Local0, 8))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(0, LEDM) /// Set PCIEDBG.DMIL1EDM (324[3]) = 0
+
+      // TBT special sleep.
+      Store(PSD0, Local1)
+      Store(0, PSD0)// D0
+      Store(20, Local2) // Poll for TBT, up to 200 ms
+
+      While (LGreater(Local2, 0)) {
+        Store(Subtract(Local2, 1), Local2)
+        Store(TB2P, Local3)
+        If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
+          break
+        }
+        Sleep(10)
+      }
+
+      If (LLessEqual(Local2, 0)) {
+      }
+      SXEX()
+      Store(Local1, PSD0) // Back to Local1
+    } /** @defgroup pcie_on PCIE _ON method **/
+
+    Method(POFF) { /// Turn off core power to PCIe Slot
+      If (LEqual(TOFF, 0)) {
+        Return()
+      }
+      Store(\MMRP(\TBSE), Local7)
+      OperationRegion(L23P, SystemMemory, Local7, 0xE4)
+      Field(L23P,WordAcc, NoLock, Preserve)
+      {
+        Offset(0xA4),// PMCSR
+        PSD0, 2, // PowerState
+        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+        , 2,
+        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
+        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+      }
+
+      Store(\MMTB(TBSE), Local6)
+      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0xA4),
+        TBPS, 2, // PowerState of TBT
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(PSD0, Local1)
+      Store(0, PSD0)// D0
+
+      Store(P2TB, Local3)
+
+      If (Lgreater(TOFF, 1)) {
+        Sleep(10)
+        Store(Local1, PSD0) // Back to Local1
+        Return()
+      }
+      Store(0, TOFF)
+
+      Store(Local1, PSD0) // Back to Local1
+
+      /// Set L23_Rdy Entry Request (L23ER)
+      Store(1, L2TE)
+      Sleep(16)
+      Store(0, Local0)
+      While(L2TE) {
+        If(Lgreater(Local0, 4))    /// Debug - Wait for 5 ms
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(1, LEDM) /// PCIEDBG.DMIL1EDM (324[3]) = 1
+
+      /// Assert Reset Pin
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+        }
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+        }
+      }
+      If (\RTBC) {
+        /// assert CLK_REQ MSK
+        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+          PCRO(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,DeRefOf(Index(SCLK, 1)))    // Or SCLK to set bit
+          Sleep(16)
+        }
+      }
+
+      /// Power OFF for TBT
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+        }
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+        }
+      }
+
+      Store(0, TBPE)
+
+      Store(1, LDIS) /// Set Link Disable
+      Store(0, LDIS) /// Toggle link disable
+
+      /// enable WAKE
+      If (WKEN) {
+        If (LNotEqual(DeRefOf(Index(WAKG, 0)),0)) { // if power gating enabled
+          If (LEqual(DeRefOf(Index(WAKG, 0)),1)) { // GPIO mode
+            \_SB.SGOV(DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+            \_SB.SHPO(DeRefOf(Index(WAKG, 2)), 0) // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+          }
+          If (LEqual(DeRefOf(Index(WAKG, 0)),2))  { // IOEX mode
+            \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG, 1)),DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+          }
+        }
+      }
+      Sleep(\TBOD)
+      /** @defgroup pcie_off PCIE _OFF method **/
+    } // End of Method_OFF
+
+    Name(_PR0, Package(){PXP})
+    Name(_PR3, Package(){PXP})
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
new file mode 100644
index 0000000000..66584c21c5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
@@ -0,0 +1,1877 @@
+/** @file
+ Thunderbolt ACPI methods
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#define DTBT_CONTROLLER                   0x00
+#define DTBT_TYPE_PCH                     0x01
+#define DTBT_TYPE_PEG                     0x02
+#define DTBT_SMI_HANDLER_NUMBER           0xF7
+#define TBT_SMI_ENUMERATION_FUNCTION      21
+#define TBT_SMI_RESET_SWITCH_FUNCTION     22
+#define TBT_SMI_DISABLE_MSI_FUNCTION      23
+#ifndef  BIT29
+#define  BIT29    0x20000000
+#endif
+
+Name(LDLY, 300) //300 ms
+Name (TNVB, 0xFFFF0000)  // TBT NVS Base address
+Name (TNVL, 0xAA55)      // TBT NVS Length
+Include ("Acpi/TbtNvs.asl")
+
+External(\_SB.PCI0.RP02.L23D, MethodObj)
+External(\_SB.PCI0.RP03.L23D, MethodObj)
+External(\_SB.PCI0.RP04.L23D, MethodObj)
+External(\_SB.PCI0.RP05.L23D, MethodObj)
+External(\_SB.PCI0.RP06.L23D, MethodObj)
+External(\_SB.PCI0.RP07.L23D, MethodObj)
+External(\_SB.PCI0.RP08.L23D, MethodObj)
+External(\_SB.PCI0.RP09.L23D, MethodObj)
+External(\_SB.PCI0.RP10.L23D, MethodObj)
+External(\_SB.PCI0.RP11.L23D, MethodObj)
+External(\_SB.PCI0.RP12.L23D, MethodObj)
+External(\_SB.PCI0.RP13.L23D, MethodObj)
+External(\_SB.PCI0.RP14.L23D, MethodObj)
+External(\_SB.PCI0.RP15.L23D, MethodObj)
+External(\_SB.PCI0.RP16.L23D, MethodObj)
+External(\_SB.PCI0.RP17.L23D, MethodObj)
+External(\_SB.PCI0.RP18.L23D, MethodObj)
+External(\_SB.PCI0.RP19.L23D, MethodObj)
+External(\_SB.PCI0.RP20.L23D, MethodObj)
+External(\_SB.PCI0.RP21.L23D, MethodObj)
+External(\_SB.PCI0.RP22.L23D, MethodObj)
+External(\_SB.PCI0.RP23.L23D, MethodObj)
+External(\_SB.PCI0.RP24.L23D, MethodObj)
+
+External(\_SB.PCI0.RP01.DL23, MethodObj)
+External(\_SB.PCI0.RP02.DL23, MethodObj)
+External(\_SB.PCI0.RP03.DL23, MethodObj)
+External(\_SB.PCI0.RP04.DL23, MethodObj)
+External(\_SB.PCI0.RP05.DL23, MethodObj)
+External(\_SB.PCI0.RP06.DL23, MethodObj)
+External(\_SB.PCI0.RP07.DL23, MethodObj)
+External(\_SB.PCI0.RP08.DL23, MethodObj)
+External(\_SB.PCI0.RP09.DL23, MethodObj)
+External(\_SB.PCI0.RP10.DL23, MethodObj)
+External(\_SB.PCI0.RP11.DL23, MethodObj)
+External(\_SB.PCI0.RP12.DL23, MethodObj)
+External(\_SB.PCI0.RP13.DL23, MethodObj)
+External(\_SB.PCI0.RP14.DL23, MethodObj)
+External(\_SB.PCI0.RP15.DL23, MethodObj)
+External(\_SB.PCI0.RP16.DL23, MethodObj)
+External(\_SB.PCI0.RP17.DL23, MethodObj)
+External(\_SB.PCI0.RP18.DL23, MethodObj)
+External(\_SB.PCI0.RP19.DL23, MethodObj)
+External(\_SB.PCI0.RP20.DL23, MethodObj)
+External(\_SB.PCI0.RP21.DL23, MethodObj)
+External(\_SB.PCI0.RP22.DL23, MethodObj)
+External(\_SB.PCI0.RP23.DL23, MethodObj)
+External(\_SB.PCI0.RP24.DL23, MethodObj)
+
+External(\_SB.PCI0.RTEN, MethodObj)
+External(\_SB.PCI0.RTDS, MethodObj)
+External(\_SB.PCI0.RP01.PON, MethodObj)
+External(\_SB.PCI0.RP02.PON, MethodObj)
+External(\_SB.PCI0.RP03.PON, MethodObj)
+External(\_SB.PCI0.RP04.PON, MethodObj)
+External(\_SB.PCI0.RP05.PON, MethodObj)
+External(\_SB.PCI0.RP06.PON, MethodObj)
+External(\_SB.PCI0.RP07.PON, MethodObj)
+External(\_SB.PCI0.RP08.PON, MethodObj)
+External(\_SB.PCI0.RP09.PON, MethodObj)
+External(\_SB.PCI0.RP10.PON, MethodObj)
+External(\_SB.PCI0.RP11.PON, MethodObj)
+External(\_SB.PCI0.RP12.PON, MethodObj)
+External(\_SB.PCI0.RP13.PON, MethodObj)
+External(\_SB.PCI0.RP14.PON, MethodObj)
+External(\_SB.PCI0.RP15.PON, MethodObj)
+External(\_SB.PCI0.RP16.PON, MethodObj)
+External(\_SB.PCI0.RP17.PON, MethodObj)
+External(\_SB.PCI0.RP18.PON, MethodObj)
+External(\_SB.PCI0.RP19.PON, MethodObj)
+External(\_SB.PCI0.RP20.PON, MethodObj)
+External(\_SB.PCI0.RP21.PON, MethodObj)
+External(\_SB.PCI0.RP22.PON, MethodObj)
+External(\_SB.PCI0.RP23.PON, MethodObj)
+External(\_SB.PCI0.RP24.PON, MethodObj)
+External(\_SB.PCI0.PEG0.PG00._ON, MethodObj)
+External(\_SB.PCI0.PEG1.PG01._ON, MethodObj)
+External(\_SB.PCI0.PEG2.PG02._ON, MethodObj)
+
+Name(TRDO, 0) // 1 during TBT RTD3 _ON
+Name(TRD3, 0) // 1 during TBT RTD3 _OFF
+Name(TBPE, 0) // Reflects RTD3_PWR_EN value
+Name(TOFF, 0) // param to TBT _OFF method
+
+  Method (TBON, 0, Serialized) {
+    // TBT On process before entering Sx state.
+    Store(1, TRDO)
+    Switch (ToInteger(\RPS0)) { // TBT Root port Selector
+      Case (1) {
+        If (CondRefOf(\_SB.PCI0.RP01.PON)) {
+          \_SB.PCI0.RP01.PON()
+        }
+      }
+      Case (2) {
+        If (CondRefOf(\_SB.PCI0.RP02.PON)) {
+          \_SB.PCI0.RP02.PON()
+        }
+      }
+      Case (3) {
+        If (CondRefOf(\_SB.PCI0.RP03.PON)) {
+          \_SB.PCI0.RP03.PON()
+        }
+      }
+      Case (4) {
+        If (CondRefOf(\_SB.PCI0.RP04.PON)) {
+          \_SB.PCI0.RP04.PON()
+        }
+      }
+      Case (5) {
+        If (CondRefOf(\_SB.PCI0.RP05.PON)) {
+          \_SB.PCI0.RP05.PON()
+        }
+      }
+      Case (6) {
+        If (CondRefOf(\_SB.PCI0.RP06.PON)) {
+          \_SB.PCI0.RP06.PON()
+        }
+      }
+      Case (7) {
+        If (CondRefOf(\_SB.PCI0.RP07.PON)) {
+          \_SB.PCI0.RP07.PON()
+        }
+      }
+      Case (8) {
+        If (CondRefOf(\_SB.PCI0.RP08.PON)) {
+          \_SB.PCI0.RP08.PON()
+        }
+      }
+      Case (9) {
+        If (CondRefOf(\_SB.PCI0.RP09.PON)) {
+          \_SB.PCI0.RP09.PON()
+        }
+      }
+      Case (10) {
+        If (CondRefOf(\_SB.PCI0.RP10.PON)) {
+          \_SB.PCI0.RP10.PON()
+        }
+      }
+      Case (11) {
+        If (CondRefOf(\_SB.PCI0.RP11.PON)) {
+          \_SB.PCI0.RP11.PON()
+        }
+      }
+      Case (12) {
+        If (CondRefOf(\_SB.PCI0.RP12.PON)) {
+          \_SB.PCI0.RP12.PON()
+        }
+      }
+      Case (13) {
+        If (CondRefOf(\_SB.PCI0.RP13.PON)) {
+          \_SB.PCI0.RP13.PON()
+        }
+      }
+      Case (14) {
+        If (CondRefOf(\_SB.PCI0.RP14.PON)) {
+          \_SB.PCI0.RP14.PON()
+        }
+      }
+      Case (15) {
+        If (CondRefOf(\_SB.PCI0.RP15.PON)) {
+          \_SB.PCI0.RP15.PON()
+        }
+      }
+      Case (16) {
+        If (CondRefOf(\_SB.PCI0.RP16.PON)) {
+          \_SB.PCI0.RP16.PON()
+        }
+      }
+      Case (17) {
+        If (CondRefOf(\_SB.PCI0.RP17.PON)) {
+          \_SB.PCI0.RP17.PON()
+        }
+      }
+      Case (18) {
+        If (CondRefOf(\_SB.PCI0.RP18.PON)) {
+          \_SB.PCI0.RP18.PON()
+        }
+      }
+      Case (19) {
+        If (CondRefOf(\_SB.PCI0.RP19.PON)) {
+          \_SB.PCI0.RP19.PON()
+        }
+      }
+      Case (20) {
+        If (CondRefOf(\_SB.PCI0.RP20.PON)) {
+          \_SB.PCI0.RP20.PON()
+        }
+      }
+      Case (21) {
+        If (CondRefOf(\_SB.PCI0.RP21.PON)) {
+          \_SB.PCI0.RP21.PON()
+        }
+      }
+      Case (22) {
+        If (CondRefOf(\_SB.PCI0.RP22.PON)) {
+          \_SB.PCI0.RP22.PON()
+        }
+      }
+      Case (23) {
+        If (CondRefOf(\_SB.PCI0.RP23.PON)) {
+          \_SB.PCI0.RP23.PON()
+        }
+      }
+      Case (24) {
+        If (CondRefOf(\_SB.PCI0.RP24.PON)) {
+          \_SB.PCI0.RP24.PON()
+        }
+      }
+    }//Switch(ToInteger(RPS0)) // TBT Selector
+    Store(0, TRDO)
+  } // End of TBON
+  //
+  // Name: TBTD
+  // Description: Function to return the TBT RP# device no
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: TBT RP# device no
+  //
+  Method(TBTD,2)
+  {
+    ADBG("TBTD")
+    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (Package () {1, 2, 3, 4, 5, 6, 7, 8})
+        {
+          Store(0x1C, Local0) //Device28-Function0...Function7 = 11100.000...111
+        }
+        Case (Package () {9, 10, 11, 12, 13, 14, 15, 16})
+        {
+          Store(0x1D, Local0) //Device29-Function0...Function7 = 11101.000...111
+        }
+        Case (Package () {17, 18, 19, 20, 21, 22, 23, 24})
+        {
+          Store(0x1B, Local0) //Device27-Function0...Function3 = 11011.000...011
+        }
+      }
+    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (Package () {1, 2, 3})
+        {
+          Store(0x1, Local0) //Device1-Function0...Function2 = 00001.000...010
+        }
+      }
+    } Else {
+      Store(0xFF, Local0)
+    }
+
+    ADBG("Device no")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(TBTD,1)
+
+  //
+  // Name: TBTF
+  // Description: Function to return the TBT RP# function no
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: TBT RP# function no
+  //
+  Method(TBTF,2)
+  {
+    ADBG("TBTF")
+    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (1)
+        {
+          Store(And(\RPA1,0xF), Local0) //Device28-Function0 = 11100.000
+        }
+        Case (2)
+        {
+          Store(And(\RPA2,0xF), Local0) //Device28-Function1 = 11100.001
+        }
+        Case (3)
+        {
+          Store(And(\RPA3,0xF), Local0) //Device28-Function2 = 11100.010
+        }
+        Case (4)
+        {
+          Store(And(\RPA4,0xF), Local0) //Device28-Function3 = 11100.011
+        }
+        Case (5)
+        {
+          Store(And(\RPA5,0xF), Local0) //Device28-Function4 = 11100.100
+        }
+        Case (6)
+        {
+          Store(And(\RPA6,0xF), Local0) //Device28-Function5 = 11100.101
+        }
+        Case (7)
+        {
+          Store(And(\RPA7,0xF), Local0) //Device28-Function6 = 11100.110
+        }
+        Case (8)
+        {
+          Store(And(\RPA8,0xF), Local0) //Device28-Function7 = 11100.111
+        }
+        Case (9)
+        {
+          Store(And(\RPA9,0xF), Local0) //Device29-Function0 = 11101.000
+        }
+        Case (10)
+        {
+          Store(And(\RPAA,0xF), Local0) //Device29-Function1 = 11101.001
+        }
+        Case (11)
+        {
+          Store(And(\RPAB,0xF), Local0) //Device29-Function2 = 11101.010
+        }
+        Case (12)
+        {
+          Store(And(\RPAC,0xF), Local0) //Device29-Function3 = 11101.011
+        }
+        Case (13)
+        {
+          Store(And(\RPAD,0xF), Local0) //Device29-Function4 = 11101.100
+        }
+        Case (14)
+        {
+          Store(And(\RPAE,0xF), Local0) //Device29-Function5 = 11101.101
+        }
+        Case (15)
+        {
+          Store(And(\RPAF,0xF), Local0) //Device29-Function6 = 11101.110
+        }
+        Case (16)
+        {
+          Store(And(\RPAG,0xF), Local0) //Device29-Function7 = 11101.111
+        }
+        Case (17)
+        {
+          Store(And(\RPAH,0xF), Local0) //Device27-Function0 = 11011.000
+        }
+        Case (18)
+        {
+          Store(And(\RPAI,0xF), Local0) //Device27-Function1 = 11011.001
+        }
+        Case (19)
+        {
+          Store(And(\RPAJ,0xF), Local0) //Device27-Function2 = 11011.010
+        }
+        Case (20)
+        {
+          Store(And(\RPAK,0xF), Local0) //Device27-Function3 = 11011.011
+        }
+        Case (21)
+        {
+          Store(And(\RPAL,0xF), Local0) //Device27-Function4 = 11011.100
+        }
+        Case (22)
+        {
+          Store(And(\RPAM,0xF), Local0) //Device27-Function5 = 11011.101
+        }
+        Case (23)
+        {
+          Store(And(\RPAN,0xF), Local0) //Device27-Function6 = 11011.110
+        }
+        Case (24)
+        {
+          Store(And(\RPAO,0xF), Local0) //Device27-Function7 = 11011.111
+        }
+      }
+    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (1)
+        {
+          Store(0x0, Local0) //Device1-Function0 = 00001.000
+        }
+        Case (2)
+        {
+          Store(0x1, Local0) //Device1-Function1 = 00001.001
+        }
+        Case (3)
+        {
+          Store(0x2, Local0) //Device1-Function2 = 00001.010
+        }
+      }
+    } Else {
+      Store(0xFF, Local0)
+    }
+
+    ADBG("Function no")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(TBTF,1)
+
+  //
+  // Name: MMRP
+  // Description: Function to return the Pci base address of TBT rootport
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(MMRP, 2, Serialized)
+  {
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    Return(Local0)
+  } // End of Method(MMRP)
+
+  //
+  // Name: MMRP
+  // Description: Function to return the Pci base address of TBT Up stream port
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+  Method(MMTB, 2, Serialized)
+  {
+    ADBG("MMTB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x19),
+      SBUS, 8
+    }
+    Store(SBUS, Local2)
+    Store(\_SB.PCI0.GPCB(), Local0)
+    Multiply(Local2, 0x100000, Local2)
+    Add(Local2, Local0, Local0) // TBT HR US port
+
+    ADBG("TBT-US-ADR")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(MMTB, 1, Serialized)
+  //
+  // Name: FFTB
+  // Description: Function to  Check for FFFF in TBT PCIe
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: 1 if TBT PCIe space has value FFFF, 0 if not
+  //
+  Method(FFTB, 2, Serialized)
+  {
+    ADBG("FFTB")
+
+    Add(MMTB(Arg0, Arg1), 0x548, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x08)
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      TB2P, 32,
+      P2TB, 32
+    }
+
+    Store(TB2P, Local1)
+
+    If(LEqual(Local1, 0xFFFFFFFF))
+    {
+      ADBG("FFTb 1")
+      Return (1)
+    }
+    Else
+    {
+      ADBG("FFTb 0")
+      Return (0)
+    }
+  } // End of Method(FFTB)
+
+Name(TDMA, 0x80000000) // Address of Thunderbolt(TM) debug memory buffer, fixed up during POST
+
+Scope(\_GPE)
+{
+  //
+  //
+  //OS up Mail Box command execution to host router upstream port each time
+  //exiting from Sx State .Avoids intermediate
+  //PCIe Scan by OS during resorce allocation
+  // Arg0 : PCIe Base address
+  // Arg1 : Controller Type 0x00 : DTBT
+  //Developer notes: Called twice
+  // 1. During OS INIT (booting to OS from S3-S5/Reboot)
+  // 2. Up on Hot plug
+  //
+  Method(OSUP, 2, Serialized)
+  {
+    ADBG("OSUP")
+
+    Add(Arg0, 0x540, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x10)
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      IT2P, 32,
+      IP2T, 32,
+      DT2P, 32,
+      DP2T, 32
+    }
+
+    Store(100, Local1)
+    Store(0x0D, DP2T) // Write OS_Up to PCIe2TBT
+
+    While(LGreater(Local1, 0))
+    {
+      Store(Subtract(Local1, 1), Local1)
+      Store(DT2P, Local2)
+
+      If(LAnd(LEqual(Local2, 0xFFFFFFFF),LEqual(Arg1, DTBT_CONTROLLER)))// Device gone
+      {
+        ADBG("Dev gone")
+        Return(2)
+      }
+      If(And(Local2, 1)) // Done
+      {
+        ADBG("Cmd acknowledged")
+        break
+      }
+      Sleep(50)
+    }
+    If(LEqual(TRWA,1))
+    {
+      Store(0xC, DP2T) // Write OSUP to PCIe2TBT
+    }
+    Else
+    {
+      Store(0x0, DP2T) // Write 0 to PCIe2TBT
+    }
+
+    //Store(0x00, P2TB) // Write 0 to PCIe2TBT
+
+    ADBG("End-of-OSUP")
+
+    Return(1)
+  } // End of Method(OSUP, 1, Serialized)
+
+  //
+  // Check for FFFF in TBT
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TBFF, 2, Serialized)
+  {
+    ADBG("TBFF")
+
+    Store(MMTB(Arg0, Arg1), Local0)
+    OperationRegion (PXVD, SystemMemory, Local0, 0x8)
+    Field (PXVD, DWordAcc, NoLock, Preserve) {
+      VEDI, 32, // Vendor/Device ID
+      CMDR, 32 // CMD register
+    }
+
+    Store(VEDI, Local1)
+
+    If (LEqual(Local1, 0xFFFFFFFF)) {
+      If (LNotEqual(\TWIN, 0)) { // TBT Enumeration is Native mode?
+        If (LEqual(CMDR, 0xFFFFFFFF)) { // Device Gone
+          Return (2)// Notify only
+        }
+        Return (1)// Exit w/o notify
+      } Else {
+        Return (OSUP(Local0, DTBT_CONTROLLER))
+      }
+    } Else
+    {
+      ADBG("Dev Present")
+      Return (0)
+    }
+  } // End of Method(TBFF, 1, Serialized)
+
+  //
+  // Secondary bus of TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TSUB, 2, Serialized)
+  {
+    ADBG("TSUB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    ADBG("ADR")
+    ADBG(Local0)
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x19),
+      SBUS, 8
+    }
+
+    ADBG("Sec Bus")
+    ADBG(SBUS)
+
+    Return(SBUS)
+  } // End of Method(TSUB, 0, Serialized)
+
+  //
+  // Pmem of TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TSUP, 2, Serialized)
+  {
+    ADBG("TSUB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    ADBG("ADR:")
+    ADBG(Local0)
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x30)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      CMDS, 32,
+      Offset(0x19),
+      SBUS, 8,
+      SBU5, 8,
+      Offset(0x1C),
+      SEIO, 32,
+      MMBL, 32,
+      PMBL, 32,
+
+    }
+
+    ADBG("Pmem of TBT RP:")
+    ADBG(PMBL)
+
+    Return(PMBL)
+  } // End of Method(TSUP, 0, Serialized)
+
+  //
+  // Wait for secondary bus in TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(WSUB, 2, Serialized)
+  {
+    ADBG(Concatenate("WSUB=", ToHexString(Arg0)))
+    ADBG(ToHexString(Timer))
+
+    Store(0, Local0)
+    Store(0, Local1)
+    While(1)
+    {
+      Store(TSUP(Arg0, Arg1), Local1)
+      If(LGreater(Local1, 0x1FFF1))
+      {
+        ADBG("WSUB-Finished")
+        Break
+      }
+      Else
+      {
+        Add(Local0, 1, Local0)
+        If(LGreater(Local0, 1000))
+        {
+          Sleep(1000)
+          ADBG("WSUB-Deadlock")
+        }
+        Else
+        {
+          Sleep(16)
+        }
+      }
+    }
+     ADBG(Concatenate("WSUb=", ToHexString(Local1)))
+  } // End of Method(WSUB)
+
+  // Wait for _WAK finished
+  Method(WWAK)
+  {
+    ADBG("WWAK")
+
+    Wait(WFEV, 0xFFFF)
+    Signal(WFEV) // Set it, to enter on next HP
+  } // End of Method(WWAK)
+
+  Method(NTFY, 2, Serialized)
+  {
+    ADBG("NTFY")
+
+    If(LEqual(NOHP,1))
+    {
+      If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+        Switch(ToInteger(Arg0)) // TBT Selector
+        {
+          Case (1)
+          {
+            ADBG("Notify RP01")
+            Notify(\_SB.PCI0.RP01,0)
+          }
+          Case (2)
+          {
+            ADBG("Notify RP02")
+            Notify(\_SB.PCI0.RP02,0)
+          }
+          Case (3)
+          {
+            ADBG("Notify RP03")
+            Notify(\_SB.PCI0.RP03,0)
+          }
+          Case (4)
+          {
+            ADBG("Notify RP04")
+            Notify(\_SB.PCI0.RP04,0)
+          }
+          Case (5)
+          {
+            ADBG("Notify RP05")
+            Notify(\_SB.PCI0.RP05,0)
+          }
+          Case (6)
+          {
+            ADBG("Notify RP06")
+            Notify(\_SB.PCI0.RP06,0)
+          }
+          Case (7)
+          {
+            ADBG("Notify RP07")
+            Notify(\_SB.PCI0.RP07,0)
+          }
+          Case (8)
+          {
+            ADBG("Notify RP08")
+            Notify(\_SB.PCI0.RP08,0)
+          }
+          Case (9)
+          {
+            ADBG("Notify RP09")
+            Notify(\_SB.PCI0.RP09,0)
+          }
+          Case (10)
+          {
+            ADBG("Notify RP10")
+            Notify(\_SB.PCI0.RP10,0)
+          }
+          Case (11)
+          {
+            ADBG("Notify RP11")
+            Notify(\_SB.PCI0.RP11,0)
+          }
+          Case (12)
+          {
+            ADBG("Notify RP12")
+            Notify(\_SB.PCI0.RP12,0)
+          }
+          Case (13)
+          {
+            ADBG("Notify RP13")
+            Notify(\_SB.PCI0.RP13,0)
+          }
+          Case (14)
+          {
+            ADBG("Notify RP14")
+            Notify(\_SB.PCI0.RP14,0)
+          }
+          Case (15)
+          {
+            ADBG("Notify RP15")
+            Notify(\_SB.PCI0.RP15,0)
+          }
+          Case (16)
+          {
+            ADBG("Notify RP16")
+            Notify(\_SB.PCI0.RP16,0)
+          }
+          Case (17)
+          {
+            ADBG("Notify RP17")
+            Notify(\_SB.PCI0.RP17,0)
+          }
+          Case (18)
+          {
+            ADBG("Notify RP18")
+            Notify(\_SB.PCI0.RP18,0)
+          }
+          Case (19)
+          {
+            ADBG("Notify RP19")
+            Notify(\_SB.PCI0.RP19,0)
+          }
+          Case (20)
+          {
+            ADBG("Notify RP20")
+            Notify(\_SB.PCI0.RP20,0)
+          }
+          Case (21)
+          {
+            ADBG("Notify RP21")
+            Notify(\_SB.PCI0.RP21,0)
+          }
+          Case (22)
+          {
+            ADBG("Notify RP22")
+            Notify(\_SB.PCI0.RP22,0)
+          }
+          Case (23)
+          {
+            ADBG("Notify RP23")
+            Notify(\_SB.PCI0.RP23,0)
+          }
+          Case (24)
+          {
+            ADBG("Notify RP24")
+            Notify(\_SB.PCI0.RP24,0)
+          }
+        }//Switch(ToInteger(TBSS)) // TBT Selector
+      } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+        Switch(ToInteger(Arg0))
+        {
+          Case (1)
+          {
+            ADBG("Notify PEG0")
+            Notify(\_SB.PCI0.PEG0,0)
+          }
+          Case (2)
+          {
+            ADBG("Notify PEG1")
+            Notify(\_SB.PCI0.PEG1,0)
+          }
+          Case (3)
+          {
+            ADBG("Notify PEG2")
+            Notify(\_SB.PCI0.PEG2,0)
+          }
+        }
+      }//Switch(ToInteger(TBSS)) // TBT Selector
+    }//If(NOHP())
+    P8XH(0,0xC2)
+    P8XH(1,0xC2)
+  }// End of Method(NTFY)
+
+//
+//  TBT BIOS, GPIO 5 filtering,
+//  Hot plug of 12V USB devices, into TBT host router, cause electrical noise on PCH GPIOs,
+//  This noise cause false hot-plug events, and negatively influence BIOS assisted hot-plug.
+//  WHL-PCH GPIO does not implement Glitch Filter logic (refer to GPIO HAS) on any GPIO pad. Native functions have to implement their own digital glitch-filter logic
+//  if needed. As HW filter was not implemented on WHL PCH, because of that SW workaround should be implemented in BIOS.
+//  Register 0x544(Bios mailbox) bit 0 definition:
+//  if BIOS reads bit as 1, BIOS will clear the bit and continue normal flow, if bit is 0 BIOS will exit from method
+//
+
+  Method(GNIS,2, Serialized)
+  {
+
+    ADBG("GNIS")
+    If(LEqual(GP5F, 0))
+    {
+      ADBG("GNIS_Dis=0")
+      Return(0)
+    }
+    //
+    // BIOS mailbox command for GPIO filter
+    //
+    Add(MMTB(Arg0, Arg1), 0x544, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x08)
+
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      HPFI, 1,
+      Offset(0x4),
+      TB2P, 32
+    }
+    Store(TB2P, Local1)
+    ADBG(Concatenate("TB2P=", ToHexString(Local1)))
+    If(LEqual(Local1, 0xFFFFFFFF)) // Disconnect?
+    {
+      ADBG("GNIS=0")
+      Return(0)
+    }
+    Store(HPFI, Local2)
+    ADBG(Concatenate("HPFI=", ToHexString(Local2)))
+    If(LEqual(Local2, 0x01))
+    {
+      Store(0x00, HPFI)
+      ADBG("GNIS=0")
+      Return(0)
+    }
+    // Any other values treated as a GPIO noise
+    ADBG("GNIS=1")
+    Return(1)
+  }
+
+  Method(CHKP,2, Serialized)
+  {
+    Add(MMTB(Arg0, Arg1), 0x544, Local0)
+    OperationRegion(PXVE,SystemMemory,Local0,0x08)
+
+    Field(PXVE,DWordAcc, NoLock, Preserve)
+    {
+      HPFI, 1,
+      Offset(0x4),
+      TB2P, 32
+    }
+    Store(TB2P, Local1)
+    And(Local1,BIT29,Local1)
+    ADBG(Concatenate("Local1=", ToHexString(Local1)))
+    //ADBG(Concatenate("BIT29=", ToHexString(LAnd(Local1,BIT29))))
+    If(LEqual(Local1, BIT29))
+    {
+      Return(1)
+    }
+    Else
+    {
+      Return(0)
+    }
+  }
+
+  //
+  // Method to Handle enumerate PCIe structure through
+  // SMI for Thunderbolt(TM) devices
+  //
+  Method(XTBT,2, Serialized)
+  {
+    ADBG("XTBT")
+    ADBG("RP :")
+    ADBG(Arg0)
+    Store(Arg0, DTCP) // Root port to enumerate
+    Store(Arg1, DTPT)   // Root port Type
+    If(LEqual(Arg0, RPS0)) {
+      Store (1, Local0)
+    } ElseIf (LEqual(Arg0, RPS1)) {
+      Store (2, Local0)
+    } Else {
+      Store (0, Local0)
+      Return ()
+    }
+
+    If (TRDO) {
+      ADBG("Durng TBT_ON")
+      Return ()
+    }
+
+    If (TRD3) {
+      ADBG("During TBT_OFF")
+      Return ()
+    }
+    WWAK()
+    WSUB(Arg0, Arg1)
+    If(GNIS(Arg0, Arg1))
+    {
+      Return()
+    }
+
+    OperationRegion(SPRT,SystemIO, 0xB2,2)
+    Field (SPRT, ByteAcc, Lock, Preserve)
+    {
+      SSMP, 8
+    }
+
+    ADBG("TBT-HP-Handler")
+
+    Acquire(OSUM, 0xFFFF)
+    Store(TBFF(Arg0, Arg1), Local1)
+    If(LEqual(Local1, 1))// Only HR
+    {
+      Sleep(16)
+      Release(OSUM)
+      ADBG("OS_Up_Received")
+      Return ()
+    }
+    If(LEqual(Local1, 2)) // Disconnect
+    {
+      NTFY(Arg0, Arg1)
+      Sleep(16)
+      Release(OSUM)
+      ADBG("Disconnect")
+      Return ()
+    }
+
+    // HR and EP
+    If(LEqual(SOHP, 1))
+    {
+      // Trigger SMI to enumerate PCIe Structure
+      ADBG("TBT SW SMI")
+      Store(21, TBSF)
+      Store(0xF7, SSMP)
+    }
+    NTFY(Arg0, Arg1)
+    Sleep(16)
+    Release(OSUM)
+
+    ADBG("End-of-XTBT")
+  } // End of Method(XTBT)
+
+  //
+  // Calling Method to Handle enumerate PCIe structure through
+  // SMI for Thunderbolt(TM) devices for Tier 1 GPIOs
+  // Used in Two ways ,
+  // If CIO GPIO(1 Tier) is Different for the Controllers, this will be used as 1 Tier GPIO Handler for 1st controller
+  // If CIO GPIO(1 Tier) is Same for all the controllers, this will be used as 1 Tier GPIO Handler for All the controllers
+  //
+  Method(ATBT)
+  {
+    ADBG("ATBT")
+    //
+    // Calling Method to Handle enumerate PCIe structure through
+    //
+    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
+      If(LEqual(RPN0,1))
+      {
+        XTBT(RPS0, RPT0)
+      }
+    } Else {
+      If(LEqual(RPN0,1))
+      {
+        XTBT(RPS0, RPT0)
+      }
+      ElseIf(LEqual(RPN1,1))
+      {
+        XTBT(RPS1, RPT1)
+      }
+    }
+    ADBG("End-of-ATBT")
+  } // End of Method(ATBT)
+
+  Method(BTBT)
+  {
+    ADBG("BTBT")
+    //
+    // Calling Method to Handle enumerate PCIe structure through
+    //
+    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
+      If(LEqual(RPN1,1))
+      {
+        XTBT(RPS1, RPT1)
+      }
+    }
+    ADBG("End-of-BTBT")
+  } // End of Method(BTBT)
+  //
+  // Method to call OSPU Mail box command
+  // Arg0 : Controller type 0x00 : Discrete 0x80 : Integrated TBT
+  // Arg1 : TBT RP Selector / DMA
+  // Arg2 : TBT Type (PCH or PEG)
+  //
+  Method(TINI, 3, Serialized)
+  {
+    ADBG("TINI")
+    If(Lequal (Arg0, DTBT_CONTROLLER))
+    {
+      //ADBG("DTBT")
+    Store(MMRP(Arg1, Arg2), Local0)
+      OperationRegion(RP_X,SystemMemory,Local0,0x20)
+      Field(RP_X,DWordAcc, NoLock, Preserve)
+      {
+        REG0, 32,
+        REG1, 32,
+        REG2, 32,
+        REG3, 32,
+        REG4, 32,
+        REG5, 32,
+        REG6, 32,
+        REG7, 32
+      }
+      Store(REG6, Local1)
+      Store(0x00F0F000, REG6)
+      Store(MMTB(Arg1, Arg2), Local2)
+      OSUP(Local2, DTBT_CONTROLLER)
+      Store(Local1, REG6)
+    }
+    ADBG("End-of-TINI")
+  }
+
+} // End of Scope (\_GPE)
+
+Scope (\_SB)
+{
+  //
+  // The code needs to be executed for TBT Hotplug Handler event (2-tier GPI GPE event architecture) is presented here
+  //
+  Method(THDR, 3, Serialized)
+  {
+    ADBG("THDR")
+    \_SB.CAGS(Arg0)
+    \_GPE.XTBT(Arg1, Arg2)
+  } // End of Method(THDR, 3, Serialized)
+} // End of Scope(\_SB)
+
+Scope (\_SB)
+{
+  //
+  // Name: CGWR [Combined GPIO Write]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> GpioPad / Expander pin
+  //        Arg1 -> Value
+  // Return: Nothing
+  //
+  Method(CGWR, 2, Serialized)
+  {
+    // PCH
+    If (CondRefOf(\_SB.SGOV))
+    {
+      \_SB.SGOV(Arg0, Arg1)
+    }
+  } // End of Method(CGWR, 4, Serialized)
+
+  //
+  // Name: CGRD [Combined GPIO Read]
+  // Description: Function to read from GPIO
+  // Input: Arg0 -> GpioPad / Expander pin
+  //        Arg1 -> 0: GPO [GPIO TX State]
+  //                1: GPI [GPIO RX State]
+  // Return: Value
+  //
+  Method(CGRD, 2, Serialized)
+  {
+    Store(1, Local0)
+    // PCH
+    If (LEqual(Arg1, 0))
+    {
+      // GPIO TX State
+      If (CondRefOf(\_SB.GGOV))
+      {
+        Store(\_SB.GGOV(Arg0), Local0)
+      }
+    }
+    ElseIf (LEqual(Arg1, 1))
+    {
+      // GPIO RX State
+      If (CondRefOf(\_SB.GGIV))
+      {
+        Store(\_SB.GGIV(Arg0), Local0)
+      }
+    }
+    Return(Local0)
+  } // End of Method(CGRD, 4, Serialized)
+  //
+  // Name: WRGP [GPIO Write]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
+  //        Arg1 -> Value
+  // Return: Nothing
+  //
+  Method(WRGP, 2, Serialized)
+  {
+    Store(Arg0, Local0)
+    Store(Arg0, Local1)
+    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
+    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
+    If (LEqual(And(Local0, 0xFF), 1))
+    {
+      // PCH
+      \_SB.CGWR(Local1, Arg1)
+    }
+  } // End of Method(WRGP, 2, Serialized)
+
+  //
+  // Name: RDGP [GPIO Read]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
+  //        Arg1 -> In case of PCH Gpio Read {GPIO TX(0)/RX(1) State indicator}
+  // Return: Value
+  //
+  Method(RDGP, 2, Serialized)
+  {
+    Store(1, Local7)
+    Store(Arg0, Local0)
+    Store(Arg0, Local1)
+    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
+    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
+    If (LEqual(And(Local0, 0xFF), 1))
+    {
+      // PCH
+      Store(\_SB.CGRD(Local1, Arg1), Local7)
+    }
+    Return(Local7)
+  } // End of Method(RDGP, 2, Serialized)
+
+} // End of Scope(\_SB)
+
+Scope(\_SB)
+{
+  // Asserts/De-asserts TBT force power
+  Method(TBFP, 2)
+  {
+    If(Arg0)
+    {
+      // Implementation dependent way to assert TBT force power
+      If(LEqual(Arg1, 1)) {
+        CGWR(FPG0, FP0L)
+      }
+      Else {
+        CGWR(FPG1, FP1L)
+      }
+    }
+    Else
+    {
+      // Implementation dependent way to de-assert TBT force power
+      If(LEqual(Arg1, 1)) {
+        CGWR(FPG0, LNot(FP0L))
+      }
+      Else {
+        CGWR(FPG1, LNot(FP1L))
+      }
+    }
+  }
+
+  // WMI ACPI device to control TBT force power
+  Device(WMTF)
+  {
+    // pnp0c14 is pnp id assigned to WMI mapper
+    Name(_HID, "PNP0C14")
+    Name(_UID, "TBFP")
+
+    Name(_WDG, Buffer() {
+      // {86CCFD48-205E-4A77-9C48-2021CBEDE341}
+      0x48, 0xFD, 0xCC, 0x86,
+      0x5E, 0x20,
+      0x77, 0x4A,
+      0x9C, 0x48,
+      0x20, 0x21, 0xCB, 0xED, 0xE3, 0x41,
+      84, 70,    // Object Id (TF)
+      1,         // Instance Count
+      0x02       // Flags (WMIACPI_REGFLAG_METHOD)
+    })
+
+    // Set TBT force power
+    // Arg2 is force power value
+    Method(WMTF, 3)
+    {
+      CreateByteField(Arg2,0,FP)
+
+      If(FP)
+      {
+        TBFP(1, 1)
+      }
+      Else
+      {
+        TBFP(0, 1)
+      }
+    }
+  }
+} // End of Scope(\_SB)
+
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 1),LEqual(RPS1, 1))))
+{
+  Scope(\_SB.PCI0.RP01)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP01)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 2),LEqual(RPS1, 2))))
+{
+  Scope(\_SB.PCI0.RP02)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP02)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 3),LEqual(RPS1, 3))))
+{
+  Scope(\_SB.PCI0.RP03)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP03)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 4),LEqual(RPS1, 4))))
+{
+  Scope(\_SB.PCI0.RP04)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP04)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 5),LEqual(RPS1, 5))))
+{
+  Scope(\_SB.PCI0.RP05)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP05)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 6),LEqual(RPS1, 6))))
+{
+  Scope(\_SB.PCI0.RP06)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP06)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 7),LEqual(RPS1, 7))))
+{
+  Scope(\_SB.PCI0.RP07)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP07)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 8),LEqual(RPS1, 8))))
+{
+  Scope(\_SB.PCI0.RP08)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP08)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 9),LEqual(RPS1, 9))))
+{
+  Scope(\_SB.PCI0.RP09)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP09)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 10),LEqual(RPS1, 10))))
+{
+  Scope(\_SB.PCI0.RP10)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP10)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 11),LEqual(RPS1, 11))))
+{
+  Scope(\_SB.PCI0.RP11)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP11)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 12),LEqual(RPS1, 12))))
+{
+  Scope(\_SB.PCI0.RP12)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP12)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 13),LEqual(RPS1, 13))))
+{
+  Scope(\_SB.PCI0.RP13)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP13)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 14),LEqual(RPS1, 14))))
+{
+  Scope(\_SB.PCI0.RP14)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP14)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 15),LEqual(RPS1, 15))))
+{
+  Scope(\_SB.PCI0.RP15)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP15)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 16),LEqual(RPS1, 16))))
+{
+  Scope(\_SB.PCI0.RP16)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP16)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 17),LEqual(RPS1, 17))))
+{
+  Scope(\_SB.PCI0.RP17)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP17)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 18),LEqual(RPS1, 18))))
+{
+  Scope(\_SB.PCI0.RP18)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP18)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 19),LEqual(RPS1, 19))))
+{
+  Scope(\_SB.PCI0.RP19)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP19)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 20),LEqual(RPS1, 20))))
+{
+  Scope(\_SB.PCI0.RP20)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP20)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 21),LEqual(RPS1, 21))))
+{
+  Scope(\_SB.PCI0.PEG0)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG0)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 22),LEqual(RPS1, 22))))
+{
+  Scope(\_SB.PCI0.PEG1)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG1)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 23),LEqual(RPS1, 23))))
+{
+  Scope(\_SB.PCI0.PEG2)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG2)
+}
+
+Scope(\_SB)
+{
+    //
+    // Name: PERB
+    // Description: Function to read a Byte from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Byte data read from PCIE-MMIO
+    //
+    Method(PERB,5,Serialized)
+    {
+      ADBG("PERB")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 1)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 8
+      }
+
+      Return(TEMP)
+    } // End of Method(PERB,5,Serialized)
+
+    //
+    // Name: PEWB
+    // Description: Function to write a Byte into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWB,6,Serialized)
+    {
+      ADBG("PEWB")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 1)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 8
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWB,6,Serialized)
+
+    //
+    // Name: PERW
+    // Description: Function to read a Word from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Word data read from PCIE-MMIO
+    //
+    Method(PERW,5,Serialized)
+    {
+      ADBG("PERW")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 2)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 16
+      }
+
+      Return(TEMP)
+    } // End of Method(PERW,5,Serialized)
+
+    //
+    // Name: PEWW
+    // Description: Function to write a Word into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWW,6,Serialized)
+    {
+      ADBG("PEWW")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 2)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 16
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWW,6,Serialized)
+
+    //
+    // Name: PERD
+    // Description: Function to read a Dword from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Dword data read from PCIE-MMIO
+    //
+    Method(PERD,5,Serialized)
+    {
+      ADBG("PERD")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 4)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 32
+      }
+
+      Return(TEMP)
+    } // End of Method(PERD,5,Serialized)
+
+    //
+    // Name: PEWD
+    // Description: Function to write a Dword into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWD,6,Serialized)
+    {
+      ADBG("PEWD")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 4)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 32
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWD,6,Serialized)
+
+    //
+    // Name: STDC
+    // Description: Function to get Standard Capability Register Offset
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Capability ID
+    // Return: Capability Register Offset data
+    //
+    Method(STDC,5,Serialized)
+    {
+      ADBG("STDC")
+
+      //Check for Referenced device is present or not
+      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x00), Local7) //Vendor ID register
+      If(LEqual(Local7, 0xFFFF))
+      {
+        ADBG("Referenced device is not present")
+        Return(0)
+      }
+
+      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x06), Local0) //Device Status register
+      If (LEqual(And(Local0, 16), 0)) //Bit4 - Capabilities List
+      {
+        //No Capabilities linked list is available
+        ADBG("No Capabilities linked list is available")
+        Return(0)
+      }
+
+      //Local1 is for storing CapabilityID
+      //Local2 is for storing CapabilityPtr
+      Store(PERB(Arg0, Arg1, Arg2, Arg3, 0x34), Local2) //CapabilityPtr
+
+      While(1)
+      {
+        And(Local2, 0xFC, Local2) //Each capability must be DWORD aligned
+
+        If(LEqual(Local2, 0)) //A pointer value of 00h is used to indicate the last capability in the list
+        {
+          ADBG("Capability ID is not found")
+          Return(0)
+        }
+
+        Store(PERB(Arg0, Arg1, Arg2, Arg3, Local2), Local1) //CapabilityID
+
+        If(LEqual(Arg4, Local1)) //CapabilityID match
+        {
+          ADBG("Capability ID is found")
+          ADBG("Capability Offset : ")
+          ADBG(Local2)
+          Return(Local2)
+        }
+        Store(PERB(Arg0, Arg1, Arg2, Arg3, Add(Local2, 1)), Local2) //CapabilityPtr
+        Return(0)
+      }
+    } // End of Method(STDC,5,Serialized)
+
+} // End Scope(\_SB)
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  1:18   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:08 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>

> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:15 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package
> and Include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Create the CoffeelakeSiliconPkg to provide an initial package for
> silicon initialization code for Coffee Lake (CFL) and Whiskey Lake
> (WHL) generation products.
> 
> * Major areas of functionality are categorized into CPU, Management
>   Engine (ME), 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: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec                              | 714
> ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h                  |  53
> ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h         |
> 89 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h        |
> 291 ++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h         |
> 157 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h       |
> 64 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h             |  28
> +
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h |
> 123 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h     |
> 58 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h          | 110
> +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h          |  22
> +
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h               |  34
> +
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h                     | 319
> +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h                 |  29 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h  |
> 26 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h   |
> 71 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h    |
> 60 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h             |  55
> ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h                  |  19 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h               |  65
> ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
> |  23 +
>  21 files changed, 2410 insertions(+)
> 
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
> new file mode 100644
> index 0000000000..fa8c11e93d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
> @@ -0,0 +1,714 @@
> +## @file
> +# Component description file for the Silicon Reference Code.
> +#
> +# Copyright (c) 2019 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]
> +  Include
> +  SampleCode/Include
> +  SampleCode/MdeModulePkg/Include
> +  SampleCode/IntelFrameworkPkg/Include
> +  #
> +  # SystemAgent
> +  #
> +  SystemAgent/Include
> +  SystemAgent/MemoryInit/Include
> +  SystemAgent/AcpiTables
> +  #
> +  # Cpu
> +  #
> +  Cpu/Include
> +  #
> +  # Me
> +  #
> +  Me/Include
> +  #
> +  # Pch
> +  #
> +  Pch/Include
> +
> +[Guids.common.Private]
> +  #
> +  # PCH
> +  #
> +  gPchDeviceTableHobGuid       = { 0xb3e123d0, 0x7a1e, 0x4db4, { 0xaf, 0x66,
> 0xbe, 0xd4, 0x1e, 0x9c, 0x66, 0x38 }}
> +  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 }}
> +
> +[Guids]
> +##
> +## 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}}
> +
> +##
> +## IntelFrameworkPkg
> +##
> +gEfiSmmPeiSmramMemoryReserveGuid =  {0x6dadf1d1, 0xd4cc, 0x4910,
> {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d}}
> +
> +##
> +## Common
> +##
> +## Include/ConfigBlock/SiConfig.h
> +gSiConfigGuid = {0x4ed6d282, 0x22f3, 0x4fe1, {0xa6, 0x61, 0x6, 0x1a, 0x97,
> 0x38, 0x59, 0xd8 }}
> +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}}
> +
> +##
> +## System Agent
> +##
> +gSaAcpiTableStorageGuid  =  {0x3c0ed5e2, 0x91ea, 0x4b94, { 0x82, 0xd, 0x9d,
> 0xaf, 0x9a, 0x3b, 0xb4, 0xa2}}
> +gSaDataHobGuid  =  {0xe07d0bda, 0xbf90, 0x46a9, { 0xb0, 0x0e, 0xb2, 0xc4,
> 0x4a, 0x0e, 0xd6, 0xd0}}
> +gSaConfigHobGuid  = {0x762fa2e6, 0xea3b, 0x41c8, { 0x8c, 0x52, 0x63, 0x76,
> 0x6d, 0x70, 0x39, 0xe0}}
> +gSaPegHobGuid  = {0x440ab2e5, 0xa3ea, 0x466f, { 0x84, 0x96, 0xdf, 0xb1,
> 0x3b, 0x75, 0x29, 0x95}}
> +gSgAcpiTableStorageGuid  =  {0x8de8964f, 0x2939, 0x4b49, { 0xa3, 0x48, 0xf6,
> 0xb2, 0xb2, 0xde, 0x4a, 0x42}}
> +gSaSsdtAcpiTableStorageGuid  =  {0xca89914d, 0x2317, 0x452e, { 0xb2, 0x45,
> 0x36, 0xc6, 0xfb, 0x77, 0xa9, 0xc6}}
> +gPegSsdtAcpiTableStorageGuid  =  {0xE05B8635, 0xE5C0, 0x4D88, { 0xB6,
> 0x29, 0x19, 0xD6, 0xA2, 0xC6, 0xE9, 0x2E}}
> +gSgAcpiTablePchStorageGuid  =  {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}}
> +gSaPciePeiPreMemConfigGuid  =  { 0x81baf3c9, 0xf295, 0x4572, { 0x8b, 0x21,
> 0x79, 0x3f, 0xa3, 0x1b, 0xa5, 0xdb}}
> +gSaPciePeiConfigGuid  =  { 0xdaa929a9, 0x5ec9, 0x486a, { 0xb0, 0xf7, 0x82,
> 0x3a, 0x55, 0xc7, 0xb5, 0xb3}}
> +gGraphicsPeiPreMemConfigGuid  =  { 0x0319c56b, 0xc43a, 0x42f1, { 0x80,
> 0xbe, 0xca, 0x5b, 0xd1, 0xd5, 0xc9, 0x28}}
> +gGraphicsPeiConfigGuid  =  { 0x04249ac0, 0x0088, 0x439f, { 0xa7, 0x4e, 0xa7,
> 0x04, 0x2a, 0x06, 0x2f, 0x5d}}
> +gSwitchableGraphicsConfigGuid  =  { 0xc7956998, 0xc065, 0x46c4, { 0x8e,
> 0x2f, 0x58, 0x2b, 0x67, 0xeb, 0xbe, 0x2f}}
> +gCpuTraceHubConfigGuid =  { 0xf2e17477, 0x93f3, 0x430d, { 0x9e, 0x08, 0x3c,
> 0xcc, 0x6e, 0x2f, 0x6c, 0x4b}}
> +gMemoryConfigGuid  =  { 0x26cf084c, 0xc9db, 0x41bb, { 0x92, 0xc6, 0xd1,
> 0x97, 0xb8, 0xa1, 0xe4, 0xbf}}
> +gMemoryConfigNoCrcGuid  =  { 0xc56c73d0, 0x1cdb, 0x4c0c, { 0xa9, 0x57,
> 0xea, 0x62, 0xa9, 0xe6, 0xf5, 0x0c}}
> +gIpuPreMemConfigGuid  =  { 0x830a222b, 0x3ff5, 0x432e, { 0x9d, 0xd5, 0x4e,
> 0xe3, 0xfc, 0xa2, 0xaa, 0xa2}}
> +gGnaConfigGuid  =  { 0x53e0ef18, 0xb8a8, 0x4795, { 0xa6, 0x6d, 0xe4, 0x77,
> 0x2c, 0xc3, 0xae, 0x82}}
> +gVtdConfigGuid  =  { 0x03e5cf63, 0xbebb, 0x4041, { 0xb7, 0xe7, 0xbf, 0x54,
> 0x61, 0x20, 0xf1, 0xc5}}
> +gGraphicsDxeConfigGuid  =  {0x34d93161, 0xf78e, 0x4915, {0xad, 0xc4, 0xdb,
> 0x67, 0x16, 0x42, 0x39, 0x24}}
> +gMiscDxeConfigGuid  =  {0x7ce5f5ef, 0x4ef1, 0x4f9f, {0x8e, 0x29, 0x5f, 0xf4,
> 0x5f, 0x2f, 0xd8, 0xaf}}
> +gPcieDxeConfigGuid  =  {0x1ed2d6f1, 0xa9d2, 0x476e, {0x8e, 0x74, 0xad,
> 0xd9, 0x5b, 0x5,  0x10, 0x82}}
> +gMemoryDxeConfigGuid  =  {0xa5c7dda8, 0x686b, 0x404f, {0x86, 0x40, 0xf8,
> 0x2,  0xd,  0x84, 0x4c, 0x94}}
> +gVbiosDxeConfigGuid  =  {0x8df0f30a, 0x8156, 0x4897, {0xa2, 0x18, 0x1f,
> 0xd3, 0x91, 0xbc, 0x46, 0x26}}
> +gSaOverclockingPreMemConfigGuid  =  { 0x09ecc29d, 0xdbbe, 0x49fb, { 0xa6,
> 0x49, 0x4b, 0xf6, 0x40, 0xe2, 0xeb, 0xd6}}
> +gFspReservedMemoryResourceHobTsegGuid  =  { 0xd038747c, 0xd00c,
> 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}}
> +
> +## 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}}
> +
> +## 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 }}
> +
> +##
> +## 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}}
> +gHtBistHobGuid  =  {0xbe644001, 0xe7d4, 0x48b1, {0xb0, 0x96, 0x8b, 0xa0,
> 0x47, 0xbc, 0x7a, 0xe7}}
> +gCpuInitDataHobGuid  =  {0x266e31cc, 0x13c5, 0x4807, {0xb9, 0xdc, 0x39,
> 0xa6, 0xba, 0x88, 0xff, 0x1a}}
> +gEpcBiosDataGuid  =  {0xc60aa7f6, 0xe8d6, 0x4956, {0x8b, 0xa1, 0xfe, 0x26,
> 0x29, 0x8f, 0x5e, 0x87}}
> +gCpuSecurityPreMemConfigGuid = {0xfd5c346, 0x8260, 0x4067, {0x94, 0x69,
> 0xcf, 0x91, 0x68, 0xa3, 0x42, 0x90}}
> +gCpuConfigLibPreMemConfigGuid = {0xfc1c0ec2, 0xc6b4, 0x4f05, {0xbb, 0x85,
> 0xc8, 0x0, 0x8d, 0x5b, 0x4a, 0xb7}}
> +gCpuSgxConfigGuid = {0xc30bc5ac, 0x828a, 0x45ae, {0x83, 0x1b, 0x8e, 0xb,
> 0x73, 0x9a, 0xb2, 0xf2}}
> +gCpuTestConfigGuid = {0xd4dba957, 0xd9c, 0x4af2, {0x9d, 0x40, 0x35, 0xa8,
> 0x44, 0xe4, 0x93, 0xad}}
> +gCpuConfigGuid = {0x48c3aac9, 0xd66c, 0x42e4, {0x9b, 0x1d, 0x39, 0x4, 0x5f,
> 0x46, 0x53, 0x41}}
> +gCpuOverclockingPreMemConfigGuid = {0x396223b6, 0x6088, 0x44e7, {0x99,
> 0xcb, 0xfa, 0x8b, 0x99, 0x3d, 0xed, 0x4c}}
> +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}}
> +gCpuPowerMgmtTestConfigGuid = {0x5161ed3d, 0x90bf, 0x436f, {0xb8, 0x33,
> 0xd7, 0x17, 0x89, 0xb3, 0x48, 0xc1}}
> +
> +##
> +## Me
> +##
> +gMePeiPreMemConfigGuid  =  {0x67ed113b, 0xd4ab, 0x43f5, {0x9c, 0x3c,
> 0x35, 0x44, 0x15, 0xaa, 0x47, 0x5c}}
> +gMePeiConfigGuid  =  {0x9bad5628, 0x657b, 0x48e3, {0xb1, 0x11, 0xc3, 0xb9,
> 0xeb, 0xea, 0xee, 0x17}}
> +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}}
> +
> +##
> +## 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 = {0x8c7ee32c, 0x0870, 0x4bfa, {0x84, 0x79, 0x5b, 0xa5,
> 0x67, 0xc4, 0xae, 0x5b}}
> +
> +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}}
> +gTraceHubPreMemConfigGuid  =  {0xC26AC3F6, 0xDAD0, 0x4E91, {0xB6,
> 0xD6, 0xD8, 0x51, 0x6F, 0x8F, 0x9B, 0x7B}}
> +gPchTraceHubPreMemConfigGuid  = {0x8456c11, 0xdb85, 0x4914, {0x8d,
> 0x1a, 0xe5, 0xac, 0x64, 0x37, 0xe8, 0x96}}
> +gPcieRpPreMemConfigGuid  =  {0x8377AB38, 0xF8B0, 0x476A, { 0x9C, 0xA1,
> 0x68, 0xEA, 0x78, 0x57, 0xD8, 0x2A}}
> +gHpetPreMemConfigGuid  =  {0x7C75C0F1, 0xA20F, 0x42EB, {0x83, 0xDE,
> 0xE8, 0x58, 0xAB, 0x81, 0xC5, 0xDC}}
> +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}}
> +gHsioPreMemConfigGuid  =  {0xbc9e5787, 0x3ddb, 0x4916, {0x8c, 0xcc, 0x82,
> 0xb8, 0x9, 0x43, 0xe2, 0xf0}} #deprecated
> +
> +gPchGeneralConfigGuid  =  {0x6ED94C8C, 0x25F7, 0x4686, {0xB2, 0x46, 0xCA,
> 0x4D, 0xE2, 0x95, 0x4B, 0x5D}}
> +gPcieRpConfigGuid  =  {0x0A53B507, 0x988B, 0x475C, {0xBF, 0x76, 0x33, 0xDE,
> 0x10, 0x6D, 0x94, 0x84}}
> +gSataConfigGuid  =  {0xF5F87B4F, 0xCC3C, 0x408D, {0x89, 0xE3, 0x61, 0xC5,
> 0x9C, 0x54, 0x07, 0xC4}}
> +gIoApicConfigGuid  =  {0x2873D0F1, 0x00F6, 0x40AB, {0xAC, 0x36, 0x9A, 0x68,
> 0xBA, 0x87, 0x3E, 0x6C}}
> +gCio2ConfigGuid  =  {0xFBC4C192, 0x789D, 0x4038, {0x90, 0xE1, 0x5E, 0x6D,
> 0xFD, 0x52, 0xAF, 0x8A}}
> +gDmiConfigGuid  =  {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}}
> +gLanConfigGuid  =  {0x4B2DE99E, 0x7517, 0x4D04, {0x8C, 0x02, 0xF1, 0x1A,
> 0x59, 0x2B, 0x14, 0x2F}}
> +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}}
> +gPort61ConfigGuid  =  {0x59913475, 0x1960, 0x4099, {0x80, 0xEC, 0xAF, 0xC7,
> 0xCF, 0x5F, 0x9F, 0xAC}}
> +gScsConfigGuid  =  {0xF4DE6D52, 0xB5C9, 0x48C0, {0xA0, 0x4A, 0x68, 0x54,
> 0x20, 0x94, 0x05, 0xD0}}
> +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}}
> +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}}
> +
> +##
> +## 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 }}
> +gTpmDeviceInstanceTpm20PttGuid        =  {0x72cd3a7b, 0xfea5, 0x4f5e,
> {0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}}
> +gTpmDeviceInstanceTpm20PttPtpGuid     =  {0x93d66f66, 0x55da, 0x4f03,
> {0x9b, 0x5f, 0x32, 0xcf, 0x9e, 0x54, 0x3b, 0x3a}}
> +gEfiTrEEPhysicalPresenceGuid          =  {0xf24643c2, 0xc622, 0x494e, {0x8a,
> 0x0d, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b}}
> +gTcoWdtHobGuid                        = { 0x3e405418, 0x0d8c, 0x4f1a, { 0xb0,
> 0x55, 0xbe, 0xf9, 0x08, 0x41, 0x46, 0x8d }}
> +
> +##
> +## Pre-Memory 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}}
> +
> +##
> +## Post-Memory 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}}
> +
> +[Protocols.common.Private]
> +  #
> +  # SA
> +  #
> +  gSaIotrapSmiProtocolGuid        = { 0x1861e089, 0xcaa3, 0x473e, { 0x84,
> 0x32, 0xdc, 0x1f, 0x94, 0xc6, 0xc1, 0xa6 }}
> +
> +  #
> +  # CPU
> +  #
> +  gPchPcieIoTrapProtocolGuid      = { 0xd66a1cf,  0x79ad, 0x494b, { 0x97,
> 0x8b, 0xb2, 0x59, 0x81, 0x68, 0x93, 0x34 }}
> +
> +[Protocols]
> +##
> +## IntelFrameworkPkg
> +##
> +gEfiLegacyBiosProtocolGuid  =  {0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b,
> 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d}}
> +gEfiLegacyInterruptProtocolGuid  =  {0x31ce593d, 0x108a, 0x485d, {0xad,
> 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}}
> +gEfiDataHubProtocolGuid  =  {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7,
> 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}
> +
> +##
> +## MdeModulePkg
> +##
> +gEfiSmmVariableProtocolGuid  =  {0xed32d533, 0x99e6, 0x4209, {0x9c, 0xc0,
> 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7}}
> +
> +##
> +## 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}}
> +gGopComponentName2ProtocolGuid  =  {0x651b7ebd, 0xce13, 0x41d0,
> {0x82, 0xe5, 0xa0, 0x63, 0xab, 0xbe, 0x9b, 0xb6}}
> +gGopOverrideProtocolGuid        =  {0x4a89a16e, 0x67b8, 0x4429, {0x8c,
> 0x47, 0x43, 0x67, 0x90, 0xf2, 0xf2, 0x69}}
> +
> +##
> +## AcpiTables
> +##
> +gEfiGlobalNvsAreaProtocolGuid  =  {0x074e1e48, 0x8132, 0x47a1, {0x8c,
> 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc}}
> +
> +##
> +## Cpu
> +##
> +gCpuInfoProtocolGuid  =  {0xe223cf65, 0xf6ce, 0x4122, {0xb3, 0xaf, 0x4b,
> 0xd1, 0x8a, 0xff, 0x40, 0xa1}}
> +gCpuNvsAreaProtocolGuid  =  {0xb9cf3f43, 0xbe3e, 0x4e45, {0xa0, 0xbe,
> 0x1a, 0x4, 0x89, 0xdf, 0x1a, 0xc9}}
> +gDxeCpuPolicyProtocolGuid  =  {0x8282b977, 0x22f9, 0x4134, {0x99, 0x43,
> 0x7b, 0xcc, 0x5f, 0x40, 0x33, 0x52}}
> +
> +##
> +## Me
> +##
> +gDxeMePolicyGuid                 = {0xa0b5dc52, 0x4f34, 0x3990, {0xd4, 0x91,
> 0x10, 0x8b, 0xe8, 0xba, 0x75, 0x42}}
> +
> +##
> +## PCH
> +##
> +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}}
> +gPchResetCallbackProtocolGuid  =  {0x3a3300ab, 0xc929, 0x487d, {0xab,
> 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0}}
> +gPchNvsAreaProtocolGuid  =  {0x2e058b2b, 0xedc1, 0x4431, {0x87, 0xd9,
> 0xc6, 0xc4, 0xea, 0x10, 0x2b, 0xe3}}
> +gPchEmmcTuningProtocolGuid  =  {0x10fe7e3b, 0xdbe5, 0x4cfa, {0x90, 0x25,
> 0x40, 0x02, 0xcf, 0xdd, 0xbb, 0x89}}
> +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}}
> +gPchSraProtocolGuid = {0x7AE12E27, 0x5087, 0x46C8, {0xBF, 0xF0, 0x83, 0x9C,
> 0x53, 0x7B, 0x25, 0xEB}}
> +
> +##
> +## 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 }}
> +
> +[Ppis.common.Private]
> +
> +[Ppis]
> +##
> +## MdeModulePkg
> +##
> +gPeiCapsulePpiGuid  =  {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54,
> 0xd2, 0xe1, 0x32, 0x3d}}
> +gPeiSmmAccessPpiGuid  =  {0x268f33a9, 0xcccd, 0x48be, {0x88, 0x17, 0x86,
> 0x05, 0x3a, 0xc3, 0x2e, 0xd6}}
> +gPeiSmmControlPpiGuid  =  {0x61c68702, 0x4d7e, 0x4f43, {0x8d, 0xef, 0xa7,
> 0x43, 0x05, 0xce, 0x74, 0xc5}}
> +
> +##
> +## SecurityPkg
> +##
> +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}}
> +
> +##
> +## 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}}
> +
> +##
> +## Cpu
> +##
> +gPeiCachePpiGuid  =  {0x09be4bc2, 0x790e, 0x4dea, {0x8b, 0xdc, 0x38, 0x05,
> 0x16, 0x98, 0x39, 0x44}}
> +
> +##
> +## Me
> +##
> +gMeDidSentPpiGuid = {0x45dc3106, 0xef67, 0x4c71, {0xb0, 0xf0, 0x97, 0x15,
> 0x9c, 0x7d, 0xbb, 0x7c}}
> +
> +##
> +## 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}}
> +gPchResetCallbackPpiGuid  =  {0x17865dc0, 0x0b8b, 0x4da8, {0x8b, 0x42,
> 0x7c, 0x46, 0xb8, 0x5c, 0xca, 0x4d}}
> +
> +[LibraryClasses]
> +##
> +## Common
> +##
> +AslUpdateLib|Include/Library/AslUpdateLib.h
> +SiPolicyLib|Include/Library/SiPolicyLib.h
> +UsbLib|Include/Library/UsbLib.h
> +UsbInitLib|Include/Private/Library/UsbInitLib.h
> +
> +##
> +## CPU
> +##
> +CpuMailboxLib|Cpu/Include/Library/CpuMailboxLib.h
> +CpuPlatformLib|Cpu/Include/Library/CpuPlatformLib.h
> +CpuPolicyLib|Cpu/Include/Library/CpuPolicyLib.h
> +
> +##
> +## Me
> +##
> +PeiMePolicyLib|Me/Include/Library/PeiMePolicyLib.h
> +
> +##
> +## Pch
> +##
> +GpioLib|Pch/Include/Library/GpioLib.h
> +GpioLib|Pch/Include/Library/GpioNativeLib.h
> +PchCycleDecodingLib|Pch/Include/Library/PchCycleDecodingLib.h
> +PchEspiLib|Pch/Include/Library/PchEspiLib.h
> +PchGbeLib|Pch/Include/Library/PchGbeLib.h
> +GbeMdiLib|Pch/Include/Library/GbeMdiLib.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
> +PchPmcLib|Pch/Include/Library/PchPmcLib.h
> +PchPolicyLib|Pch/Include/Library/PchPolicyLib.h
> +PchSbiAccessLib|Pch/Include/Library/PchSbiAccessLib.h
> +PchSerialIoLib|Pch/Include/Library/PchSerialIoLib.h
> +PchSerialIoUartLib|Pch/Include/Library/PchSerialIoUartLib.h
> +SecPchLib|Pch/Include/Library/SecPchLib.h
> +PchTraceHubLib|Pch/Include/Private/Library/PchTraceHubLib.h
> +PchSmmControlLib|Pch/IncludePrivate/Library/PchSmmControlLib.h
> +PchWdtCommonLib|Pch/Include/Library/PchWdtCommonLib.h
> +OcWdtLib|Pch/Include/Library/OcWdtLib.h
> +PchResetLib|Pch/Include/Library/PchResetLib.h
> +DxePchPolicyLib|Pch/Include/Library/DxePchPolicyLib.h
> +GpioNameBufferLib|Pch/IncludePrivate/Library/GpioNameBufferLib.h
> +
> +##
> +## Sa
> +##
> +DxeSaPolicyLib|SystemAgent/Include/Library/DxeSaPolicyLib.h
> +PeiSaPolicyLib|SystemAgent/Include/Library/PeiSaPolicyLib.h
> +SaPlatformLib|SystemAgent/Include/Library/SaPlatformLib.h
> +
> +##
> +## Memory
> +##
> +
> +[PcdsFixedAtBuild]
> +## From MdeModulePkg.dec
> +## Progress Code for S3 Suspend end.
> +## PROGRESS_CODE_S3_SUSPEND_END   = (EFI_SOFTWARE_SMM_DRIVER |
> (EFI_OEM_SPECIFIC | 0x00000001))    = 0x03078001
> +gSiPkgTokenSpaceGuid.PcdProgressCodeS3SuspendEnd|0x03078001|UINT3
> 2|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|0x200
> 00009
> +
> +##
> +## 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|0x10
> 000001
> +gSiPkgTokenSpaceGuid.PcdBiosSize|0x00800000|UINT32|0x10000002
> +gSiPkgTokenSpaceGuid.PcdTemporaryRamBase|0xfef00000|UINT32|0x0001
> 0028
> +gSiPkgTokenSpaceGuid.PcdTemporaryRamSize|0x2000|UINT32|0x00010029
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase|0xFFE60000|UINT32|0x3
> 0000004
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize|0x000A0000|UINT32|0x30
> 000005
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|0x00660000|UINT32|0x
> 30000006
> +
> +##
> +## 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
> +
> +gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi|0x55|UINT8|0x0010005
> +gSiPkgTokenSpaceGuid.PcdHwpSmi|0x27|UINT8|0x40000001
> +gSiPkgTokenSpaceGuid.PcdItbmSmi|0x29|UINT8|0x40000002
> +
> +gSiPkgTokenSpaceGuid.PcdAbove4GBMmioBase|0x0000004000000000|UIN
> T64|0x40000003
> +gSiPkgTokenSpaceGuid.PcdAbove4GBMmioSize|0x0000004000000000|UINT
> 64|0x40000004
> +
> +[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|U
> INT64|0x30001035
> +## Default OEM Revision for ACPI table creation.
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000002|UINT32|0
> x30001036
> +## Default Creator ID for ACPI table creation.
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x20202020|UINT32|0x30
> 001037
> +## Default Creator Revision for ACPI table creation.
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x01000013|UINT32
> |0x30001038
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> +## Maximun number of performance log entries during PEI phase.
> +gSiPkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|40|UINT8|0x0001
> 002f
> +## This value is used to set the base address of MCH
> +gSiPkgTokenSpaceGuid.PcdMchBaseAddress|0xFED10000|UINT64|0x000100
> 30
> +## This value is used to set the base address of PCH devices
> +gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress|0x0000EFA0|UINT16|0x0001
> 0031
> +gSiPkgTokenSpaceGuid.PcdTcoBaseAddress|0x0400|UINT16|0x00010034
> +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress|0x1800|UINT16|0x00010035
> +
> +## 32KB window
> +gSiPkgTokenSpaceGuid.PcdMchMmioSize|0x8000|UINT32|0x50000000
> +
> +## Stack size in the temporary RAM.
> +## 0 means half of TemporaryRamSize.
> +gSiPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0|UINT32|0x000100
> 36
> +##
> +## 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
> +
> +##
> +## Default 8MB TSEG
> +##
> +gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000|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
> +##
> +
> +##Major:To represent code generation
> +gSiPkgTokenSpaceGuid.PcdSiliconInitVersionMajor
> |0x07|UINT8|0x00010049
> +
> +##Revision:Weekly build number
> +gSiPkgTokenSpaceGuid.PcdSiliconInitVersionRevision|0x57|UINT8|0x000100
> 51
> +
> +##Build[7:4]:Daily build number.
> +##Build[3:0]:Patch build number.
> +gSiPkgTokenSpaceGuid.PcdSiliconInitVersionBuild
> |0x40|UINT8|0x00010052
> +
> +
> +##
> +## 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.PcdHpetBaseAddress
> |0xFED00000|UINT32|0x00010057
> +gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress
> |0xFED00000|UINT32|0x00010060
> +##
> +## This PCD specifies the base address of the IO APIC.
> +## The acceptable values are 0xFECxx000.
> +##
> +#gSiPkgTokenSpaceGuid.PcdIoApicBaseAddress
> |0xFEC00000|UINT32|0x00010058
> +##
> +## Regbar Base Address
> +##
> +gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress|0xFC000000|UINT32|0x0001
> 0059
> +
> +## 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*|0x
> 00000008
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
> +##
> +## SerialIo Uart Configuration
> +##
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable |0      |UINT8
> |0x00100001 # 0:Disable, 1:Enable and Initialize, 2:Enable without Initializing
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber      |2      |UINT8
> |0x00100002
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartInputClock
> |1843200|UINT32|0x00100003
> +gSiPkgTokenSpaceGuid.PcdSerialIoUart0PinMuxing  |0      |UINT8
> |0x00100009 # 0: default pins, 1: pins muxed with CNV_BRI/RGI
> +##
> +## PCI Express MMIO region length
> +## Valid settings: 0x10000000/256MB, 0x8000000/128MB, 0x4000000/64MB
> +##
> +gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000|UINT32|0x
> 0010004
> +
> +## Indidates if SMM Save State saved in MSRs.
> +#  if enabled, SMM Save State will use the MSRs instead of the
> memory.<BR><BR>
> +#   TRUE  - SMM Save State will use the MSRs.<BR>
> +#   FALSE - SMM Save State will use the memory.<BR>
> +# @Prompt SMM Save State uses MSRs.
> +gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable|FALSE|BOOLEAN|0
> x20000001
> +[PcdsDynamic]
> +
> +## Indidates if SMM Delay feature is supported.<BR><BR>
> +#   TRUE  - SMM Delay feature is supported.<BR>
> +#   FALSE - SMM Delay feature is not supported.<BR>
> +# @Prompt SMM Delay feature.
> +gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication|TRUE|BOOLEAN|0x
> 0010009
> +
> +## Indidates if SMM Block feature is supported.<BR><BR>
> +#   TRUE  - SMM Block feature is supported.<BR>
> +#   FALSE - SMM Block feature is not supported.<BR>
> +# @Prompt SMM Block feature.
> +gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication|TRUE|BOOLEAN|0x
> 001000A
> +
> +## Indidates if SMM Enable/Disable feature is supported.<BR><BR>
> +#   TRUE  - SMM Enable/Disable feature is supported.<BR>
> +#   FALSE - SMM Enable/Disable feature is not supported.<BR>
> +# @Prompt SMM Enable/Disable feature.
> +gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication|TRUE|BOOLE
> AN|0x001000B
> +
> +## 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|TRUE|BOOLEAN
> |0x001000C
> +
> +## 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|BOOLEA
> N|0x001000D
> +
> +[PcdsFeatureFlag]
> +##
> +## Those PCDs are used to control build process.
> +##
> +gSiPkgTokenSpaceGuid.PcdTraceHubEnable
> |FALSE|BOOLEAN|0xF0000001
> +gSiPkgTokenSpaceGuid.PcdSmmVariableEnable
> |FALSE|BOOLEAN|0xF0000002
> +gSiPkgTokenSpaceGuid.PcdAtaEnable
> |FALSE|BOOLEAN|0xF0000004
> +gSiPkgTokenSpaceGuid.PcdSiCsmEnable
> |FALSE|BOOLEAN|0xF0000005
> +gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE
> |BOOLEAN|0xF0000006
> +gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE
> |BOOLEAN|0xF0000008
> +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.PcdSmbiosEnable                 |TRUE
> |BOOLEAN|0xF0000014
> +gSiPkgTokenSpaceGuid.PcdS3Enable                     |TRUE
> |BOOLEAN|0xF0000015
> +gSiPkgTokenSpaceGuid.PcdOverclockEnable
> |FALSE|BOOLEAN|0xF0000016
> +gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable
> |FALSE|BOOLEAN|0xF0000017
> +gSiPkgTokenSpaceGuid.PcdIgdEnable                    |TRUE
> |BOOLEAN|0xF000001A
> +gSiPkgTokenSpaceGuid.PcdPegEnable                    |TRUE
> |BOOLEAN|0xF000001B
> +gSiPkgTokenSpaceGuid.PcdSaDmiEnable                  |TRUE
> |BOOLEAN|0xF000001C
> +gSiPkgTokenSpaceGuid.PcdIpuEnable                    |TRUE
> |BOOLEAN|0xF000001D
> +gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE
> |BOOLEAN|0xF000001E
> +gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE
> |BOOLEAN|0xF000001F
> +gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE
> |BOOLEAN|0xF0000020
> +gSiPkgTokenSpaceGuid.PcdBdatEnable
> |FALSE|BOOLEAN|0xF0000023
> +gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE
> |BOOLEAN|0xF0000024
> +gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE
> |BOOLEAN|0xF0000025
> +gSiPkgTokenSpaceGuid.PcdCflCpuEnable
> |FALSE|BOOLEAN|0xF0000027
> +gSiPkgTokenSpaceGuid.PcdOcWdtEnable
> |FALSE|BOOLEAN|0xF0000029
> +gSiPkgTokenSpaceGuid.PcdMinTreeEnable
> |FALSE|BOOLEAN|0xF000002A  # To separate modules used in mininal source
> tree and advanced features
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable
> |FALSE|BOOLEAN|0xF0000033
> +gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable
> |FALSE|BOOLEAN|0xF0000034
> +
> +gSiPkgTokenSpaceGuid.PcdEdk2MasterEnable
> |FALSE|BOOLEAN|0xF0000035
> +gSiPkgTokenSpaceGuid.PcdPpamEnable                   |TRUE
> |BOOLEAN|0xF0000036
> +
> +#This PCD is used to enable WDT for debug purposes in OverClocking.
> +gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug
> |FALSE|BOOLEAN|0xF0000037
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
> new file mode 100644
> index 0000000000..d0e3d94418
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  Header file for Config Block Lib implementation
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
> new file mode 100644
> index 0000000000..27b5a9440e
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
> @@ -0,0 +1,89 @@
> +/** @file
> +  Si Config Block
> +
> +  Copyright (c) 2019 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  3
> +
> +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
> +  <b>Revision 3</b>
> +  - Deprecated SkipPostBootSai
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;  ///< Offset 0 - 27 Config Block Header
> +  //
> +  // Platform specific common policies that used by several silicon
> components.
> +  //
> +  UINT32 CsmFlag          :  1;  ///< Offset 44 BIT0: CSM status flag.
> +  /**
> +    @deprecated since revision 3
> +  **/
> +  UINT32 SkipPostBootSai  :  1;
> +  UINT32 RsvdBits         : 30;  ///< Reserved
> +  UINT32 *SsidTablePtr;          // Offset 48
> +  UINT16 NumberOfSsidTableEntry; // Offset 52
> +  UINT16 Reserved;               // Offset 54
> +  /**
> +    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
> +} SI_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#define DEFAULT_SSVID    0x8086
> +#define DEFAULT_SSDID    0x7270
> +#define 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 {
> +      UINT64  Register:12;
> +      UINT64  Function:3;
> +      UINT64  Device:5;
> +      UINT64  Bus:8;
> +      UINT64  Reserved1:4;
> +      UINT64  Segment:16;
> +      UINT64  Reserved2:16;
> +    } Bits;
> +    UINT64    SegBusDevFuncRegister;
> +  } Address;
> +  SVID_SID_VALUE SvidSidValue;
> +  UINT32 Reserved;
> +} SVID_SID_INIT_ENTRY;
> +
> +#endif // _SI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
> new file mode 100644
> index 0000000000..8b51e2d47a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
> @@ -0,0 +1,291 @@
> +/** @file
> +  Common USB policy shared between PCH and CPU
> +  Contains general features settings for xHCI and xDCI
> +
> +  Copyright (c) 2019 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 3
> +extern EFI_GUID gUsbConfigGuid;
> +
> +#define MAX_USB2_PORTS  16
> +#define MAX_USB3_PORTS  10
> +
> +#pragma pack (push,1)
> +
> +#define PCH_USB_OC_PINS_MAX  8  ///< Maximal possible number of USB
> Over Current pins
> +
> +///
> +/// Overcurrent pins, the values match the setting of EDS, please refer to EDS
> for more details
> +///
> +typedef enum {
> +  UsbOverCurrentPin0 = 0,
> +  UsbOverCurrentPin1,
> +  UsbOverCurrentPin2,
> +  UsbOverCurrentPin3,
> +  UsbOverCurrentPin4,
> +  UsbOverCurrentPin5,
> +  UsbOverCurrentPin6,
> +  UsbOverCurrentPin7,
> +  UsbOverCurrentPinMax,
> +  UsbOverCurrentPinSkip = 0xFF
> +} USB_OVERCURRENT_PIN;
> +
> +/**
> +  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;
> +} USB20_AFE;
> +
> +/**
> +  This structure configures per USB2 port physical settings.
> +  It allows to setup the port location and port length, and configures the port
> strength accordingly.
> +**/
> +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 (see: USB_OVERCURRENT_PIN).
> +  **/
> +  UINT32     OverCurrentPin     :  8;
> +  UINT32     Enable             :  1;     ///< 0: Disable; <b>1: Enable</b>.
> +  UINT32     RsvdBits0          : 23;     ///< Reserved bits
> +  /**
> +    Changing this policy values from default ones may require disabling USB2
> PHY Sus Well Power Gating
> +    through Usb2PhySusPgEnable on PCH-LP
> +  **/
> +  USB20_AFE  Afe;                         ///< USB2 AFE settings
> +} USB20_PORT_CONFIG;
> +
> +/**
> +  This structure describes whether the USB3 Port N is enabled by platform
> modules.
> +**/
> +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 (see: USB_OVERCURRENT_PIN).
> +  **/
> +  UINT32  OverCurrentPin            :  8;
> +
> +  /**
> +    USB 3.0 TX Output Downscale Amplitude Adjustment (orate01margin)
> +    HSIO_TX_DWORD8[21:16]
> +    <b>Default = 00h</b>
> +  **/
> +  UINT32  HsioTxDownscaleAmp        :  8;
> +  /**
> +    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)
> +  **/
> +  UINT32  HsioTxDeEmph              :  8;
> +
> +  UINT32  Enable                    :  1; ///< 0: Disable; <b>1: Enable</b>.
> +  UINT32  HsioTxDeEmphEnable        :  1; ///< Enable the write to USB 3.0 TX
> Output -3.5dB De-Emphasis Adjustment, <b>0: Disable</b>; 1: Enable.
> +  UINT32  HsioTxDownscaleAmpEnable  :  1; ///< Enable the write to USB 3.0
> TX Output Downscale Amplitude Adjustment, <b>0: Disable</b>; 1: Enable.
> +  UINT32  RsvdBits0                 :  5; ///< Reserved bits
> +} USB30_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;
> +
> +//
> +// Below defines are for proper UPD construction and values syncing between
> UPD and policy
> +//
> +#define B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN      BIT0  ///< Enable
> the write to Signed Magnatude number added to the CTLE code bit
> +#define B_XHCI_HSIO_FILTER_SELECT_N_EN            BIT1  ///< Enable the
> write to LFPS filter select for n
> +#define B_XHCI_HSIO_FILTER_SELECT_P_EN            BIT2  ///< Enable the
> write to LFPS filter select for p
> +#define B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN    BIT3  ///< Enable
> the write to olfpscfgpullupdwnres
> +#define N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG     3
> +#define N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES   0
> +#define N_XHCI_UPD_HSIO_FILTER_SELECT_P           0
> +#define N_XHCI_UPD_HSIO_FILTER_SELECT_N           4
> +
> +typedef struct {
> +  /**
> +    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>
> +  **/
> +  UINT32  HsioCtrlAdaptOffsetCfg      :  5;
> +  /**
> +    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>
> +  **/
> +  UINT32  HsioFilterSelN              :  3;
> +  /**
> +    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>
> +  **/
> +  UINT32  HsioFilterSelP              :  3;
> +  /**
> +    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>
> +  **/
> +  UINT32  HsioOlfpsCfgPullUpDwnRes    :  3;
> +
> +  UINT32  HsioCtrlAdaptOffsetCfgEnable    :  1; ///< Enable the write to
> Signed Magnatude number added to the CTLE code, <b>0: Disable</b>; 1:
> Enable.
> +  UINT32  HsioFilterSelNEnable            :  1; ///< Enable the write to LFPS
> filter select for n, <b>0: Disable</b>; 1: Enable.
> +  UINT32  HsioFilterSelPEnable            :  1; ///< Enable the write to LFPS
> filter select for p, <b>0: Disable</b>; 1: Enable.
> +  UINT32  HsioOlfpsCfgPullUpDwnResEnable  :  1; ///< Enable the write to
> olfpscfgpullupdwnres, <b>0: Disable</b>; 1: Enable.
> +  UINT32  RsvdBits0                       : 14; ///< Reserved bits
> +} USB30_HSIO_RX_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>:
> +  - Added Usb2PhySusPgEnable - for enabling/disabling USB2 PHY SUS Well
> Power Gating
> +  <b>Revision 3</b>:
> +    Added HSIO Rx tuning policy options structure USB30_HSIO_RX_CONFIG
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
> +  /**
> +    This policy setting controls state of Compliance Mode enabling.
> +    Compliance Mode can be enabled for testing through this option but
> defualt setting is Disabled.
> +    <b>0:Disable</b>, 1: Enable
> +  **/
> +  UINT32                  EnableComplianceMode         :  1;
> +  /**
> +    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;
> +  /**
> +    <b>(Test)</b>
> +    This policy option enables USB2 PHY SUS Well Power Gating functionality.
> +    Please note this is ignored on PCH H
> +    <b>0: disable USB2 PHY SUS Well Power Gating</b>
> +    1: enable USB2 PHY SUS Well Power Gating
> +  **/
> +  UINT32                  Usb2PhySusPgEnable           :  1;
> +  UINT32                  RsvdBits0                    : 27;     ///< Reserved bits
> +  /**
> +    These members describe whether the USB2 Port N of PCH is enabled by
> platform modules.
> +  **/
> +  USB20_PORT_CONFIG       PortUsb20[MAX_USB2_PORTS];
> +  /**
> +    These members describe whether the USB3 Port N of PCH is enabled by
> platform modules.
> +  **/
> +  USB30_PORT_CONFIG       PortUsb30[MAX_USB3_PORTS];
> +  /**
> +    This member describes whether or not the xDCI controller should be
> enabled.
> +  **/
> +  XDCI_CONFIG             XdciConfig;
> +  /**
> +    This member describes policy options for RX signal tuning in ModPHY
> +  **/
> +  USB30_HSIO_RX_CONFIG    PortUsb30HsioRx[MAX_USB3_PORTS];
> +} USB_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _USB_CONFIG_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..39baa6c03a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,157 @@
> +/** @file
> +  ASL dynamic update library definitions.
> +  This library provides dymanic update to various ASL structures.
> +  There may be different libraries for different environments (PEI, BS, RT,
> SMM).
> +  Make sure you meet the requirements for the library (protocol
> dependencies, use
> +  restrictions, etc).
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _ASL_UPDATE_LIB_H_
> +#define _ASL_UPDATE_LIB_H_
> +
> +//
> +// Include files
> +//
> +#include <IndustryStandard/Acpi.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +//
> +// AML parsing definitions
> +//
> +#define AML_RESRC_TEMP_END_TAG  0x0079
> +
> +//
> +// ASL PSS package structure layout
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
> +  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
> +  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
> +  UINT8     DwordPrefix1;     // 0Ch
> +  UINT32    CoreFrequency;    // 00h
> +  UINT8     DwordPrefix2;     // 0Ch
> +  UINT32    Power;            // 00h
> +  UINT8     DwordPrefix3;     // 0Ch
> +  UINT32    TransLatency;     // 00h
> +  UINT8     DwordPrefix4;     // 0Ch
> +  UINT32    BmLatency;        // 00h
> +  UINT8     DwordPrefix5;     // 0Ch
> +  UINT32    Control;          // 00h
> +  UINT8     DwordPrefix6;     // 0Ch
> +  UINT32    Status;           // 00h
> +} PSS_PACKAGE_LAYOUT;
> +#pragma pack()
> +
> +/**
> +  Initialize the ASL update library state.
> +  This must be called prior to invoking other library functions.
> +
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +InitializeAslUpdateLib (
> +  VOID
> +  );
> +
> +/**
> +  This procedure will update immediate value assigned to a Name
> +
> +  @param[in] AslSignature               The signature of Operation Region that
> we want to update.
> +  @param[in] Buffer                     source of data to be written over original
> aml
> +  @param[in] Length                     length of data to be overwritten
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +UpdateNameAslCode(
> +  IN     UINT32                        AslSignature,
> +  IN     VOID                          *Buffer,
> +  IN     UINTN                         Length
> +  );
> +
> +/**
> +  This procedure will update the name of ASL Method
> +
> +  @param[in] AslSignature      - The signature of Operation Region that we
> want to update.
> +  @param[in] Buffer            - source of data to be written over original aml
> +  @param[in] Length            - length of data to be overwritten
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
> +**/
> +EFI_STATUS
> +UpdateMethodAslCode (
> +  IN     UINT32                        AslSignature,
> +  IN     VOID                          *Buffer,
> +  IN     UINTN                         Length
> +  );
> +
> +/**
> +  This function uses the ACPI support protocol to locate an ACPI table using
> the .
> +  It is really only useful for finding tables that only have a single instance,
> +  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
> +  Matches are determined by finding the table with ACPI table that has
> +  a matching signature and version.
> +
> +  @param[in] Signature                  Pointer to an ASCII string containing the
> Signature to match
> +  @param[in, out] Table                 Updated with a pointer to the table
> +  @param[in, out] Handle                AcpiSupport protocol table handle for
> the table found
> +  @param[in, out] Version               On input, the version of the table
> desired,
> +                                        on output, the versions the table belongs to
> +                                        @see AcpiSupport protocol for details
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  );
> +
> +/**
> +  This function uses the ACPI support protocol to locate an ACPI SSDT table.
> +  The table is located by searching for a matching OEM Table ID field.
> +  Partial match searches are supported via the TableIdSize parameter.
> +
> +  @param[in] TableId                    Pointer to an ASCII string containing the
> OEM Table ID from the ACPI table header
> +  @param[in] TableIdSize                Length of the TableId to match.  Table ID
> are 8 bytes long, this function
> +                                        will consider it a match if the first TableIdSize
> bytes match
> +  @param[in, out] Table                 Updated with a pointer to the table
> +  @param[in, out] Handle                AcpiSupport protocol table handle for
> the table found
> +  @param[in, out] Version               See AcpiSupport protocol, GetAcpiTable
> function for use
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +LocateAcpiTableByOemTableId (
> +  IN      UINT8                         *TableId,
> +  IN      UINT8                         TableIdSize,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  );
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer                     Pointer to buffer to checksum
> +  @param[in] Size                       Number of bytes to checksum
> +  @param[in] ChecksumOffset             Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
> new file mode 100644
> index 0000000000..9a3bf373a6
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
> @@ -0,0 +1,64 @@
> +/** @file
> +  Header file for Config Block Lib implementation
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
> new file mode 100644
> index 0000000000..858f8ac5e6
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
> @@ -0,0 +1,28 @@
> +/** @file
> +  Get Pci Express address library implementation.
> +
> +  Copyright (c) 2019 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
> +MmPciBase (
> +  IN UINT32                       Bus,
> +  IN UINT32                       Device,
> +  IN UINT32                       Function
> +);
> +
> +#endif // _PEI_DXE_SMM_MM_PCI_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
> new file mode 100644
> index 0000000000..c6eb70f6e2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
> @@ -0,0 +1,123 @@
> +/** @file
> +  Header file for PEI SiPolicyUpdate Library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SI_POLICY_UPDATE_LIB_H_
> +#define _PEI_SI_POLICY_UPDATE_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  This function performs Silicon PEI Policy initialization.
> +
> +  @param[in, out] SiPolicy The Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS      The function completed successfully
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSiPolicy (
> +  IN OUT SI_POLICY_PPI *SiPolicy
> +  );
> +
> +/**
> +  This function performs CPU PEI Policy initialization in Post-memory.
> +
> +  @param[in, out] SiPolicyPpi     The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +  @retval EFI ERRORS              The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicy (
> +  IN OUT  SI_POLICY_PPI *SiPolicyPpi
> +  );
> +
> +/**
> +  This function performs SI PEI Policy initialization.
> +
> +  @param[in, out] SiPolicyPpi     The SA Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSaPolicy (
> +  IN OUT   SI_POLICY_PPI  *SiPolicyPpi
> +  );
> +
> +
> +/**
> +This function performs SA PEI Policy initialization for PreMem.
> +
> +@param[in, out] SiPreMemPolicyPpi   The SI PreMem Policy PPI instance
> +
> +@retval EFI_SUCCESS             Update complete.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSaPolicyPreMem (
> +IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicyPpi
> +);
> +
> +/**
> +  This function performs PCH PEI Policy initialization.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +  @retval EFI ERRORS              The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicy (
> +  IN OUT  SI_POLICY_PPI         *SiPolicy
> +  );
> +
> +/**
> +  This function performs PCH PEI Policy initialization.
> +
> +  @param[in, out] SiPreMemPolicy  The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +  @retval EFI ERRORS              The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicyPreMem (
> +  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
> +  );
> +
> +/**
> +  Update the ME Policy Library
> +
> +  @param[in, out] SiPolicy       The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS            Update complete.
> +**/
> +EFI_STATUS
> +UpdatePeiMePolicy (
> +  IN OUT  SI_POLICY_PPI         *SiPolicy
> +  );
> +
> +/**
> +  Update the ME Policy Library
> +
> +  @param[in, out] SiPreMemPolicy The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS            Update complete.
> +**/
> +EFI_STATUS
> +UpdatePeiMePolicyPreMem (
> +  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
> new file mode 100644
> index 0000000000..fd8582b981
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Prototype of the SiConfigBlockLib library.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
> new file mode 100644
> index 0000000000..5633e2892c
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
> @@ -0,0 +1,110 @@
> +/** @file
> +  Prototype of the SiPolicyLib library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SI_POLICY_LIB_H_
> +#define _SI_POLICY_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Print whole SI_PREMEM_POLICY_PPI and serial out.
> +
> +  @param[in] SiPreMemPolicyPpi          The RC PREMEM Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +SiPreMemPrintPolicyPpi (
> +  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  Print whole SI_POLICY_PPI and serial out.
> +
> +  @param[in] SiPolicyPpi          The RC Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +SiPrintPolicyPpi (
> +  IN  SI_POLICY_PPI          *SiPolicyPpi
> +  );
> +
> +/**
> +  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon Policy.
> +  It allocates and zero out buffer, and fills in the Intel default settings.
> +
> +  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon PREMEM
> Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiCreatePreMemConfigBlocks (
> +  OUT  SI_PREMEM_POLICY_PPI         **SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
> +  It allocates and zero out buffer, and fills in the Intel default settings.
> +
> +  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiCreateConfigBlocks (
> +  OUT  SI_POLICY_PPI         **SiPolicyPpi
> +  );
> +
> +/**
> +  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
> +  While installed, RC assumes the Policy is ready and finalized. So please
> update and override
> +  any setting before calling this function.
> +
> +  @param[in] SiPreMemPolicyPpi   The pointer to Silicon PREMEM Policy PPI
> instance
> +
> +  @retval EFI_SUCCESS            The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiPreMemInstallPolicyPpi (
> +  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  SiInstallPolicyPpi installs SiPolicyPpi.
> +  While installed, RC assumes the Policy is ready and finalized. So please
> update and override
> +  any setting before calling this function.
> +
> +  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS            The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiInstallPolicyPpi (
> +  IN  SI_POLICY_PPI          *SiPolicyPpi
> +  );
> +
> +/**
> +  Print out all silicon policy information.
> +
> +  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
> +
> +  @retval none
> +**/
> +VOID
> +DumpSiPolicy (
> +  IN  SI_POLICY_PPI *SiPolicyPpi
> +  );
> +
> +#endif // _SI_PREMEM_POLICY_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
> new file mode 100644
> index 0000000000..cab5342c54
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
> @@ -0,0 +1,22 @@
> +/** @file
> +  Header file for a library to install StallPpi.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _STALL_PPI_LIB_H_
> +#define _STALL_PPI_LIB_H_
> +
> +/**
> +  This function is to install StallPpi
> +
> +  @retval  EFI_SUCCESS if Ppi is installed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallStallPpi(
> +  VOID
> +  );
> +#endif //_STALL_PPI_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
> new file mode 100644
> index 0000000000..a7cd305c62
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
> @@ -0,0 +1,34 @@
> +/** @file
> +  Header file of available functions in general USB Library
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _USB_LIB_H_
> +#define _USB_LIB_H_
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +/*
> +  Disables requested ports through Port Disable Override register
> programming
> +
> +  @param[in]  XhciMmioBase        xHCI Memory BAR0 address
> +  @param[in]  Usb2DisabledPorts   Disabled ports bitmask with a bit for
> each USB2 port
> +                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
> +  @param[in]  Usb3DisabledPorts   Disabled ports bitmask with a bit for
> each USB3 port
> +                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
> +
> +  @retval EFI_SUCCESS             Programming ended successfully and no
> errors occured
> +          EFI_ACCESS_DENIED       Port Disable Override register was locked
> and write
> +                                  didn't go through. Platform may require restart to
> unlock.
> +*/
> +EFI_STATUS
> +UsbDisablePorts (
> +  IN  UINTN   XhciMmioBase,
> +  IN  UINT32  Usb2DisabledPorts,
> +  IN  UINT32  Usb3DisabledPorts
> +  );
> +
> +#endif // _USB_LIB_H
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
> new file mode 100644
> index 0000000000..86bed53c6f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
> @@ -0,0 +1,319 @@
> +/** @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) 2019 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_PI_OFFSET                           0x09
> +#define R_PCI_SCC_OFFSET                          0x0A
> +#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
> +#define B_PCI_BRIDGE_BNUM_PBN                     0x000000FF ///< Primary
> Bus Number
> +#define B_PCI_BRIDGE_BNUM_SBBN_SCBN
> (B_PCI_BRIDGE_BNUM_SBBN | B_PCI_BRIDGE_BNUM_SCBN)
> +
> +#define R_PCI_BRIDGE_IOBL                         0x1C ///< I/O Base and Limit
> Register
> +
> +#define R_PCI_BRIDGE_MBL                          0x20 ///< Memory Base and
> Limit Register
> +#define B_PCI_BRIDGE_MBL_ML                       0xFFF00000 ///< Memory
> Limit
> +#define B_PCI_BRIDGE_MBL_MB                       0x0000FFF0 ///< Memory
> Base
> +
> +#define R_PCI_BRIDGE_PMBL                         0x24 ///< Prefetchable
> Memory Base and Limit Register
> +#define B_PCI_BRIDGE_PMBL_PML                     0xFFF00000 ///<
> Prefetchable Memory Limit
> +#define B_PCI_BRIDGE_PMBL_I64L                    0x000F0000 ///< 64-bit
> Indicator
> +#define B_PCI_BRIDGE_PMBL_PMB                     0x0000FFF0 ///<
> Prefetchable Memory Base
> +#define B_PCI_BRIDGE_PMBL_I64B                    0x0000000F ///< 64-bit
> Indicator
> +
> +#define R_PCI_BRIDGE_PMBU32                       0x28 ///< Prefetchable
> Memory Base Upper 32-Bit Register
> +#define B_PCI_BRIDGE_PMBU32                       0xFFFFFFFF
> +
> +#define R_PCI_BRIDGE_PMLU32                       0x2C ///< Prefetchable
> Memory Limit Upper 32-Bit Register
> +#define B_PCI_BRIDGE_PMLU32                       0xFFFFFFFF
> +
> +//
> +// PCIE capabilities register
> +//
> +#define R_PCIE_CAP_ID_OFFSET                      0x00 ///< Capability ID
> +#define R_PCIE_CAP_NEXT_PRT_OFFSET                0x01 ///< Next Capability
> Capability ID Pointer
> +
> +//
> +// PCI Express Capability List Register (CAPID:10h)
> +//
> +#define R_PCIE_XCAP_OFFSET                        0x02 ///< PCI Express
> Capabilities Register (Offset 02h)
> +#define S_PCIE_XCAP                               2
> +#define B_PCIE_XCAP_SI                            BIT8 ///< Slot Implemented
> +#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 S_PCIE_DCAP                               4
> +#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 B_PCIE_DCTL_URE                           BIT3 ///< Unsupported
> Request Reporting Enable
> +#define B_PCIE_DCTL_FEE                           BIT2 ///< Fatal Error Reporting
> Enable
> +#define B_PCIE_DCTL_NFE                           BIT1 ///< Non-Fatal Error
> Reporting Enable
> +#define B_PCIE_DCTL_CEE                           BIT0 ///< Correctable Error
> Reporting Enable
> +
> +#define R_PCIE_DSTS_OFFSET                        0x0A ///< Device Status
> Register (Offset 0Ah)
> +#define B_PCIE_DSTS_TDP                           BIT5 ///< Transactions Pending
> +#define B_PCIE_DSTS_APD                           BIT4 ///< AUX Power Detected
> +#define B_PCIE_DSTS_URD                           BIT3 ///< Unsupported
> Request Detected
> +#define B_PCIE_DSTS_FED                           BIT2 ///< Fatal Error Detected
> +#define B_PCIE_DSTS_NFED                          BIT1 ///< Non-Fatal Error
> Detected
> +#define B_PCIE_DSTS_CED                           BIT0 ///< Correctable Error
> Detected
> +
> +#define R_PCIE_LCAP_OFFSET                        0x0C ///< Link Capabilities
> Register (Offset 0Ch)
> +#define B_PCIE_LCAP_ASPMOC                        BIT22 ///< ASPM Optionality
> Compliance
> +#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                          (BIT11 | BIT10) ///< Active
> State Power Management (ASPM) Support
> +#define B_PCIE_LCAP_APMS_L0S                      BIT10
> +#define B_PCIE_LCAP_APMS_L1                       BIT11
> +#define N_PCIE_LCAP_APMS                          10
> +#define B_PCIE_LCAP_MLW                           0x000003F0 ///< Maximum
> Link Width
> +#define N_PCIE_LCAP_MLW                           4
> +#define B_PCIE_LCAP_MLS                           (BIT3 | BIT2 | BIT1 | BIT0) ///<
> Max Link Speed
> +#define V_PCIE_LCAP_MLS_GEN3                      3
> +
> +#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_ES                            BIT7 ///< Extended Synch
> +#define B_PCIE_LCTL_CCC                           BIT6 ///< Common Clock
> Configuration
> +#define B_PCIE_LCTL_RL                            BIT5 ///< Retrain Link
> +#define B_PCIE_LCTL_LD                            BIT4 ///< Link Disable
> +#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 V_PCIE_LSTS_NLW_1                         0x0010
> +#define V_PCIE_LSTS_NLW_2                         0x0020
> +#define V_PCIE_LSTS_NLW_4                         0x0040
> +#define B_PCIE_LSTS_CLS                           0x000F ///< Current Link Speed
> +#define V_PCIE_LSTS_CLS_GEN1                      1
> +#define V_PCIE_LSTS_CLS_GEN2                      2
> +#define V_PCIE_LSTS_CLS_GEN3                      3
> +
> +#define R_PCIE_SLCAP_OFFSET                       0x14 ///< Slot Capabilities
> Register (Offset 14h)
> +#define S_PCIE_SLCAP                              4
> +#define B_PCIE_SLCAP_PSN                          0xFFF80000 ///< Physical Slot
> Number
> +#define B_PCIE_SLCAP_SLS                          0x00018000 ///< Slot Power
> Limit Scale
> +#define B_PCIE_SLCAP_SLV                          0x00007F80 ///< Slot Power
> Limit Value
> +#define B_PCIE_SLCAP_HPC                          BIT6 ///< Hot-Plug Capable
> +#define B_PCIE_SLCAP_HPS                          BIT5 ///< Hot-Plug Surprise
> +
> +#define R_PCIE_SLCTL_OFFSET                       0x18 ///< Slot Control
> Register (Offset 18h)
> +#define S_PCIE_SLCTL                              2
> +#define B_PCIE_SLCTL_HPE                          BIT5 ///< Hot Plug Interrupt
> Enable
> +#define B_PCIE_SLCTL_PDE                          BIT3 ///< Presence Detect
> Changed Enable
> +
> +#define R_PCIE_SLSTS_OFFSET                       0x1A ///< Slot Status Register
> (Offset 1Ah)
> +#define S_PCIE_SLSTS                              2
> +#define B_PCIE_SLSTS_PDS                          BIT6 ///< Presence Detect State
> +#define B_PCIE_SLSTS_PDC                          BIT3 ///< Presence Detect
> Changed
> +
> +#define R_PCIE_RCTL_OFFSET                        0x1C ///< Root Control
> Register (Offset 1Ch)
> +#define S_PCIE_RCTL                               2
> +#define B_PCIE_RCTL_PIE                           BIT3 ///< PME Interrupt Enable
> +#define B_PCIE_RCTL_SFE                           BIT2 ///< System Error on Fatal
> Error Enable
> +#define B_PCIE_RCTL_SNE                           BIT1 ///< System Error on
> Non-Fatal Error Enable
> +#define B_PCIE_RCTL_SCE                           BIT0 ///< System Error on
> Correctable Error Enable
> +
> +#define R_PCIE_RSTS_OFFSET                        0x20 ///< Root Status Register
> (Offset 20h)
> +#define S_PCIE_RSTS                               4
> +
> +#define R_PCIE_DCAP2_OFFSET                       0x24 ///< Device Capabilities
> 2 Register (Offset 24h)
> +#define B_PCIE_DCAP2_OBFFS                        (BIT19 | BIT18) ///< OBFF
> Supported
> +#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_OBFFEN                       (BIT14 | BIT13) ///< OBFF
> Enable
> +#define N_PCIE_DCTL2_OBFFEN                       13
> +#define V_PCIE_DCTL2_OBFFEN_DIS                   0 ///< Disabled
> +#define V_PCIE_DCTL2_OBFFEN_WAKE                  3 ///< Enabled using
> WAKE# signaling
> +#define B_PCIE_DCTL2_LTREN                        BIT10 ///< LTR Mechanism
> Enable
> +#define B_PCIE_DCTL2_CTD                          BIT4 ///< Completion Timeout
> Disable
> +#define B_PCIE_DCTL2_CTV                          (BIT3 | BIT2 | BIT1 | BIT0) ///<
> Completion Timeout Value
> +#define V_PCIE_DCTL2_CTV_DEFAULT                  0x0
> +#define V_PCIE_DCTL2_CTV_40MS_50MS                0x5
> +#define V_PCIE_DCTL2_CTV_160MS_170MS              0x6
> +#define V_PCIE_DCTL2_CTV_400MS_500MS              0x9
> +#define V_PCIE_DCTL2_CTV_1P6S_1P7S                0xA
> +
> +#define R_PCIE_LCTL2_OFFSET                       0x30 ///< Link Control 2
> Register (Offset 30h)
> +#define B_PCIE_LCTL2_SD                           BIT6 ///< Selectable
> de-emphasis (0 = -6dB, 1 = -3.5dB)
> +#define B_PCIE_LCTL2_TLS                          (BIT3 | BIT2 | BIT1 | BIT0) ///<
> Target Link Speed
> +#define V_PCIE_LCTL2_TLS_GEN1                     1
> +#define V_PCIE_LCTL2_TLS_GEN2                     2
> +#define V_PCIE_LCTL2_TLS_GEN3                     3
> +
> +#define R_PCIE_LSTS2_OFFSET                       0x32 ///< Link Status 2
> Register (Offset 32h)
> +#define B_PCIE_LSTS2_LER                          BIT5 ///< Link Equalization
> Request
> +#define B_PCIE_LSTS2_EQP3S                        BIT4 ///< Equalization Phase 3
> Successful
> +#define B_PCIE_LSTS2_EQP2S                        BIT3 ///< Equalization Phase 2
> Successful
> +#define B_PCIE_LSTS2_EQP1S                        BIT2 ///< Equalization Phase 1
> Successful
> +#define B_PCIE_LSTS2_EC                           BIT1 ///< Equalization
> Complete
> +#define B_PCIE_LSTS2_CDL                          BIT0 ///< Current De-emphasis
> Level
> +
> +//
> +// PCI Power Management Capability (CAPID:01h)
> +//
> +#define R_PCIE_PMC_OFFSET                         0x02 ///< Power
> Management Capabilities Register
> +#define S_PCIE_PMC                                2
> +#define B_PCIE_PMC_PMES                           (BIT15 | BIT14 | BIT13 | BIT12
> | BIT11) ///< PME Support
> +#define B_PCIE_PMC_PMEC                           BIT3 ///< PME Clock
> +
> +#define R_PCIE_PMCS_OFFST                         0x04 ///< Power
> Management Status/Control Register
> +#define S_PCIE_PMCS                               4
> +#define B_PCIE_PMCS_BPCE                          BIT23 ///< Bus Power/Clock
> Control Enable
> +#define B_PCIE_PMCS_B23S                          BIT22 ///< B2/B3 Support
> +#define B_PCIE_PMCS_PMES                          BIT15 ///< PME_Status
> +#define B_PCIE_PMCS_PMEE                          BIT8 ///< PME Enable
> +#define B_PCIE_PMCS_NSR                           BIT3 ///< No Soft Reset
> +#define B_PCIE_PMCS_PS                            (BIT1 | BIT0) ///< Power State
> +#define V_PCIE_PMCS_PS_D0                         0
> +#define V_PCIE_PMCS_PS_D3H                        3
> +
> +//
> +// PCIE Extension Capability Register
> +//
> +#define B_PCIE_EXCAP_NCO                          0xFFF00000 ///< Next
> Capability Offset
> +#define N_PCIE_EXCAP_NCO                          20
> +#define V_PCIE_EXCAP_NCO_LISTEND                  0
> +#define B_PCIE_EXCAP_CV                           0x000F0000 ///< Capability
> Version
> +#define N_PCIE_EXCAP_CV                           16
> +#define B_PCIE_EXCAP_CID                          0x0000FFFF ///< Capability ID
> +
> +//
> +// Advanced Error Reporting Capability (CAPID:0001h)
> +//
> +#define V_PCIE_EX_AEC_CID                         0x0001 ///< Capability ID
> +#define R_PCIE_EX_UEM_OFFSET                      0x08 ///< Uncorrectable
> Error Mask Register
> +#define B_PCIE_EX_UEM_CT                          BIT14 ///< Completion
> Timeout Mask
> +#define B_PCIE_EX_UEM_UC                          BIT16 ///< Unexpected
> Completion
> +
> +//
> +// ACS Extended Capability (CAPID:000Dh)
> +//
> +#define V_PCIE_EX_ACS_CID                         0x000D ///< Capability ID
> +#define R_PCIE_EX_ACSCAPR_OFFSET                  0x04 ///< ACS Capability
> Register
> +//#define R_PCIE_EX_ACSCTLR_OFFSET                  0x08 ///< ACS Control
> Register (NOTE: register size in PCIE spce is not match the PCH register size)
> +
> +
> +//
> +// Latency Tolerance Reporting Extended Capability Registers (CAPID:0018h)
> +//
> +#define R_PCH_PCIE_LTRECH_CID                     0x0018
> +#define R_PCH_PCIE_LTRECH_MSLR_OFFSET             0x04
> +#define N_PCH_PCIE_LTRECH_MSLR_VALUE              0
> +#define N_PCH_PCIE_LTRECH_MSLR_SCALE              10
> +#define R_PCH_PCIE_LTRECH_MNSLR_OFFSET            0x06
> +#define N_PCH_PCIE_LTRECH_MNSLR_VALUE             0
> +#define N_PCH_PCIE_LTRECH_MNSLR_SCALE             10
> +//
> +// Secondary PCI Express Extended Capability Header (CAPID:0019h)
> +//
> +#define V_PCIE_EX_SPE_CID                         0x0019 ///< Capability ID
> +#define R_PCIE_EX_LCTL3_OFFSET                    0x04 ///< Link Control 3
> Register
> +#define B_PCIE_EX_LCTL3_PE                        BIT0 ///< Perform
> Equalization
> +#define R_PCIE_EX_LES_OFFSET                      0x08 ///< Lane Error Status
> +#define R_PCIE_EX_L01EC_OFFSET                    0x0C ///< Lane 0 and Lan 1
> Equalization Control Register (Offset 0Ch)
> +#define B_PCIE_EX_L01EC_UPL1TP                    0x0F000000 ///< Upstream
> Port Lane 1 Transmitter Preset
> +#define N_PCIE_EX_L01EC_UPL1TP                    24
> +#define B_PCIE_EX_L01EC_DPL1TP                    0x000F0000 ///<
> Downstream Port Lane 1 Transmitter Preset
> +#define N_PCIE_EX_L01EC_DPL1TP                    16
> +#define B_PCIE_EX_L01EC_UPL0TP                    0x00000F00 ///< Upstream
> Port Transmitter Preset
> +#define N_PCIE_EX_L01EC_UPL0TP                    8
> +#define B_PCIE_EX_L01EC_DPL0TP                    0x0000000F ///<
> Downstream Port Transmitter Preset
> +#define N_PCIE_EX_L01EC_DPL0TP                    0
> +
> +#define R_PCIE_EX_L23EC_OFFSET                    0x10 ///< Lane 2 and Lane 3
> Equalization Control Register (Offset 10h)
> +#define B_PCIE_EX_L23EC_UPL3TP                    0x0F000000 ///< Upstream
> Port Lane 3 Transmitter Preset
> +#define N_PCIE_EX_L23EC_UPL3TP                    24
> +#define B_PCIE_EX_L23EC_DPL3TP                    0x000F0000 ///<
> Downstream Port Lane 3 Transmitter Preset
> +#define N_PCIE_EX_L23EC_DPL3TP                    16
> +#define B_PCIE_EX_L23EC_UPL2TP                    0x00000F00 ///< Upstream
> Port Lane 2 Transmitter Preset
> +#define N_PCIE_EX_L23EC_UPL2TP                    8
> +#define B_PCIE_EX_L23EC_DPL2TP                    0x0000000F ///<
> Downstream Port Lane 2 Transmitter Preset
> +#define N_PCIE_EX_L23EC_DPL2TP                    0
> +
> +
> +//
> +// 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  V_PCIE_EX_L1SCAP_PTPOS_2us               0
> +#define  V_PCIE_EX_L1SCAP_PTPOS_10us              1
> +#define  V_PCIE_EX_L1SCAP_PTPOS_100us             2
> +#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 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
> +
> +//
> +// Base Address Offset
> +//
> +#define R_BASE_ADDRESS_OFFSET_0                   0x0010 ///< Base Address
> Register 0
> +#define R_BASE_ADDRESS_OFFSET_1                   0x0014 ///< Base Address
> Register 1
> +#define R_BASE_ADDRESS_OFFSET_2                   0x0018 ///< Base Address
> Register 2
> +#define R_BASE_ADDRESS_OFFSET_3                   0x001C ///< Base Address
> Register 3
> +#define R_BASE_ADDRESS_OFFSET_4                   0x0020 ///< Base Address
> Register 4
> +#define R_BASE_ADDRESS_OFFSET_5                   0x0024 ///< Base Address
> Register 5
> +#define B_PCI_BAR_MEMORY_TYPE_MASK                (BIT1 | BIT2)
> +#define B_PCI_BAR_MEMORY_TYPE_64                  BIT2
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
> new file mode 100644
> index 0000000000..ac270e24fb
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
> @@ -0,0 +1,29 @@
> +/** @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) 2019 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 <PchAccess.h>
> +#include <PchPolicyCommon.h>
> +#include <PchPreMemPolicyCommon.h>
> +#include <SaPolicyCommon.h>
> +#include <CpuPolicyCommon.h>
> +
> +extern EFI_GUID gSiPreMemPolicyPpiGuid;
> +extern EFI_GUID gSiPolicyPpiGuid;
> +
> +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/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
> new file mode 100644
> index 0000000000..fe676f8519
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
> @@ -0,0 +1,26 @@
> +/** @file
> +  PCIe Initialization Library header file
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIE_INIT_LIB_H_
> +#define _PCIE_INIT_LIB_H_
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PostCodeLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/GpioLib.h>
> +#include <SaRegs.h>
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
> new file mode 100644
> index 0000000000..f05cf0fdea
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
> @@ -0,0 +1,71 @@
> +/** @file
> +  Header file for USB initialization library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _USB_INIT_LIB_H_
> +#define _USB_INIT_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Common entry point for PCH and CPU xDCI controller
> +
> +  @param[in]  UsbConfig           The USB_CONFIG policy instance
> +  @param[in]  XdciPciMmBase       xDCI PCI config space address
> +**/
> +VOID
> +XdciConfigure (
> +  IN  USB_CONFIG      *UsbConfig,
> +  IN  UINT64          XhciPciMmBase
> +  );
> +
> +/**
> +  Common entry point for PCH and CPU xHCI controller
> +
> +  @param[in]  UsbConfig           The USB_CONFIG policy instance
> +  @param[in]  XhciPciMmBase       xHCI PCI config space address
> +**/
> +VOID
> +XhciConfigure (
> +  IN  USB_CONFIG      *UsbConfig,
> +  IN  UINT64          XhciPciMmBase
> +  );
> +
> +/**
> +  Configure xHCI after initialization
> +
> +  @param[in]  UsbConfig           The USB_CONFIG policy instance
> +  @param[in]  XhciPciMmBase       XHCI PCI CFG Base Address
> +**/
> +VOID
> +XhciConfigureAfterInit (
> +  IN  USB_CONFIG      *UsbConfig,
> +  IN  UINT64          XhciPciMmBase
> +  );
> +
> +/**
> +  Locks xHCI configuration by setting the proper lock bits in controller
> +
> +  @param[in]  UsbConfig           The USB_CONFIG policy instance
> +  @param[in]  XhciPciBase         xHCI PCI config space address
> +**/
> +VOID
> +XhciLockConfiguration (
> +  IN  USB_CONFIG      *UsbConfig,
> +  IN  UINT64          XhciPciBase
> +  );
> +
> +/**
> +  Tune the USB 2.0 high-speed signals quality.
> +
> +  @param[in]  UsbConfig           The USB_CONFIG policy instance
> +**/
> +VOID
> +Usb2AfeProgramming (
> +  IN  USB_CONFIG      *UsbConfig
> +  );
> +#endif // _USB_INIT_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
> new file mode 100644
> index 0000000000..671e94b3bc
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
> @@ -0,0 +1,60 @@
> +/** @file
> +  Protocol used for specifying platform related Silicon information and policy
> setting.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SI_POLICY_PROTOCOL_H_
> +#define _SI_POLICY_PROTOCOL_H_
> +
> +#include <IndustryStandard/Hsti.h>
> +
> +//
> +// DXE_SI_POLICY_PROTOCOL revisions
> +//
> +#define DXE_SI_POLICY_PROTOCOL_REVISION 2
> +
> +extern EFI_GUID gDxeSiPolicyProtocolGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  The protocol allows the platform code to publish a set of configuration
> information that the
> +  Silicon drivers will use to configure the processor in the DXE phase.
> +  This Policy Protocol needs to be initialized for Silicon configuration.
> +  @note The Protocol has to be published before processor DXE drivers are
> dispatched.
> +**/
> +typedef struct {
> +  /**
> +  This member specifies the revision of the Si Policy protocol. This field is used
> to indicate backward
> +  compatible changes to the protocol. Any such changes to this protocol will
> result in an update in the revision number.
> +
> +  <b>Revision 1</b>:
> +   - Initial version
> +  <b>Revision 2</b>:
> +   - Added SmbiosOemTypeFirmwareVersionInfo to determines the SMBIOS
> OEM type
> +  **/
> +  UINT8                          Revision;
> +  /**
> +    SmbiosOemTypeFirmwareVersionInfo 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.
> +  **/
> +  UINT8                          SmbiosOemTypeFirmwareVersionInfo;
> +  UINT8                          ReservedByte[6];  ///< Reserved bytes, align to
> multiple 8.
> +  /**
> +    This member describes a pointer to Hsti results from previous boot. In
> order to mitigate the large performance cost
> +    of performing all of the platform security tests on each boot, we can save
> the results across boots and retrieve
> +    and point this policy to them prior to the launch of HstiSiliconDxe. Logic
> should be implemented to not populate this
> +    upon major platform changes (i.e changes to setup option or platform
> hw)to ensure that results accurately reflect the
> +    configuration of the platform.
> +  **/
> +  ADAPTER_INFO_PLATFORM_SECURITY *Hsti;    ///< This is a pointer to Hsti
> results from previous boot
> +  UINTN                          HstiSize; ///< Size of results, if setting Hsti policy to
> point to previous results
> +} DXE_SI_POLICY_PROTOCOL;
> +
> +#pragma pack (pop)
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
> new file mode 100644
> index 0000000000..58a185c8fd
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
> @@ -0,0 +1,55 @@
> +/** @file
> +  Register names for USB Host and device controller
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _REGS_USB_H_
> +#define _REGS_USB_H_
> +
> +//
> +// USB3 (XHCI) related definitions
> +// @todo: Add CPU PCI defs for xHCI
> +//
> +#define PCI_BUS_NUMBER_PCH_XHCI             0
> +#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
> +#endif // _REGS_USB_H_
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
> new file mode 100644
> index 0000000000..b5aeccbe5d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
> @@ -0,0 +1,19 @@
> +/** @file
> +  Silicon Config HOB is used for gathering platform
> +  related Intel silicon information and config setting.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
> new file mode 100644
> index 0000000000..da16aad257
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
> @@ -0,0 +1,65 @@
> +/** @file
> +  Intel reference code configuration policies.
> +
> +  Copyright (c) 2019 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/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;
> +/*
> +  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;
> +/*
> +  Individual Config Block Structures are added here in memory as part of
> AddConfigBlock()
> +*/
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
> new file mode 100644
> index 0000000000..7e056a25af
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
> @@ -0,0 +1,23 @@
> +/** @file
> + Common configurations for CPU and PCH trace hub
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TRACE_HUB_COMMON_CONFIG_H_
> +#define _TRACE_HUB_COMMON_CONFIG_H_
> +
> +///
> +/// The TRACE_HUB_ENABLE_MODE describes the desired TraceHub mode of
> operation
> +///
> +typedef enum {
> +  TraceHubModeDisabled       = 0,       ///< TraceHub Disabled
> +  TraceHubModeTargetDebugger = 1,       ///< TraceHub Target Debugger
> mode, debug on target device itself, config to PCI mode
> +  TraceHubModeHostDebugger   = 2,       ///< TraceHub Host Debugger
> mode, debugged by host with cable attached, config to ACPI mode
> +  TraceHubModeMax
> +} TRACE_HUB_ENABLE_MODE;
> +
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  7:04   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:08 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:15 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add
> Include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds header files common to ME modules.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h |
> 124 ++++++++++++++
> Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h  |
> 59 +++++++
> Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h  |
> 87 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h               | 172
> ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h             |  17
> ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h                |  19
> +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h       |
> 41 +++++
>  7 files changed, 519 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
> new file mode 100644
> index 0000000000..102fb43bd1
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiCon
> +++ fig.h
> @@ -0,0 +1,124 @@
> +/** @file
> +  ME config block for PEI phase
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _ME_PEI_CONFIG_H_
> +#define _ME_PEI_CONFIG_H_
> +
> +#include <ConfigBlock.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>:
> +  - Change DidInitStat bit width.
> +**/
> +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>(Test)</b> 0: Disable;
> <b>1: Enable</b> - Enable/Disable to send DID message.
> +  /**
> +    <b>(Test)</b>
> +    <b>0: Set to 0 to enable retry mechanism for HECI APIs</b>
> +       1: Set to 1 will disable retry mechanism for HECI APIs
> +  **/
> +  UINT32 DisableHeciRetry                 : 1;
> +  /**
> +    <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 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 2
> +extern EFI_GUID gMePeiConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  ME Pei Post-Memory Configuration Structure.
> +
> +  <b>Revision 1:</b>
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Add MctpBroadcastCycle test setting.
> +**/
> +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.
> +  /**
> +    HECI3 state from Mbp for reference in S3 path only
> +    <b>0: Disabled</b>; 1: Enabled
> +  **/
> +  UINT32 Heci3Enabled                     : 1;
> +  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 RsvdBits                         : 25;  ///< Reserved for future use &
> Config block alignment
> +} ME_PEI_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _ME_PEI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
> new file mode 100644
> index 0000000000..46f7f86021
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyL
> +++ ib.h
> @@ -0,0 +1,59 @@
> +/** @file
> +  Prototype of the DxeMePolicyLib library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _DXE_ME_POLICY_LIB_H_
> +#define _DXE_ME_POLICY_LIB_H_
> +
> +#include <Protocol/MePolicy.h>
> +
> +/**
> +  This function prints the ME DXE phase policy.
> +
> +  @param[in] DxeMePolicy - ME DXE Policy protocol **/ VOID
> +MePrintPolicyProtocol (
> +  IN  ME_POLICY_PROTOCOL             *DxeMePolicy
> +  );
> +
> +/**
> +  MeCreatePolicyDefaults creates the default setting of ME Policy.
> +  It allocates and zero out buffer, and fills in the Intel default settings.
> +
> +  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MeCreatePolicyDefaults (
> +  IN OUT  ME_POLICY_PROTOCOL            **DxeMePolicy
> +  );
> +
> +/**
> +  MeInstallPolicyProtocol installs ME 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] DxeMePolicy                The pointer to ME Policy Protocol
> instance
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MeInstallPolicyProtocol (
> +  IN  EFI_HANDLE                    ImageHandle,
> +  IN  ME_POLICY_PROTOCOL            *DxeMePolicy
> +  );
> +
> +#endif // _DXE_ME_POLICY_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
> new file mode 100644
> index 0000000000..5db4714346
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyL
> +++ ib.h
> @@ -0,0 +1,87 @@
> +/** @file
> +  Prototype of the MePolicyLibPei library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _PEI_ME_POLICY_LIB_H_
> +#define _PEI_ME_POLICY_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +#include <Library/ConfigBlockLib.h>
> +
> +/**
> +  This function prints the PEI phase PreMem policy.
> +
> +  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI
> instance
> +**/
> +VOID
> +EFIAPI
> +MePrintPolicyPpiPreMem (
> +  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
> +  );
> +
> +/**
> +  This function prints the PEI phase policy.
> +
> +  @param[in] SiPolicyPpi              The RC Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +MePrintPolicyPpi (
> +  IN  SI_POLICY_PPI     *SiPolicyPpi
> +  );
> +
> +/**
> +  Get Me config block table total size.
> +
> +  @retval     Size of Me config block table
> +**/
> +UINT16
> +EFIAPI
> +MeGetConfigBlockTotalSize (
> +  VOID
> +  );
> +
> +/**
> +  Get ME config block table total size.
> +
> +  @retval      Size of ME config block table
> +**/
> +UINT16
> +EFIAPI
> +MeGetConfigBlockTotalSizePreMem (
> +  VOID
> +  );
> +
> +/**
> +  MeAddConfigBlocksPreMem add all ME config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add ME config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +MeAddConfigBlocksPreMem (
> +  IN VOID           *ConfigBlockTableAddress
> +  );
> +
> +/**
> +  MeAddConfigBlocks add all ME config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add ME config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +MeAddConfigBlocks (
> +  IN VOID           *ConfigBlockTableAddress
> +  );
> +
> +#endif // _PEI_ME_POLICY_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
> new file mode 100644
> index 0000000000..f29f9bc8bd
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
> @@ -0,0 +1,172 @@
> +/** @file
> +  Chipset definition for ME Devices.
> +
> +  Conventions:
> +
> +  - 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
> +  - Registers / bits that are different between PCH generations are denoted by
> +    "_ME_[generation_name]_" in register/bit names.
> +  - Registers / bits that are specific to PCH-H denoted by "PCH_H_" in
> register/bit names.
> +    Registers / bits that are specific to PCH-LP denoted by "PCH_LP_" in
> register/bit names.
> +    e.g., "_ME_PCH_H_", "_ME_PCH_LP_"
> +    Registers / bits names without _PCH_H_ or _PCH_LP_ apply for both H and
> 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 "_ME_" without [generation_name] inserted.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _ME_CHIPSET_H_
> +#define _ME_CHIPSET_H_
> +
> +#define ME_SEGMENT            0
> +#define ME_BUS                0
> +#define ME_DEVICE_NUMBER      22
> +#define HECI_MIN_FUNC         0
> +#define HECI_MAX_FUNC         5
> +
> +#define HECI_FUNCTION_NUMBER  0x00
> +#define HECI2_FUNCTION_NUMBER 0x01
> +#define IDER_FUNCTION_NUMBER  0x02
> +#define SOL_FUNCTION_NUMBER   0x03
> +#define HECI3_FUNCTION_NUMBER 0x04
> +#define HECI4_FUNCTION_NUMBER 0x05
> +
> +#define IDER_BUS_NUMBER       ME_BUS
> +#define IDER_DEVICE_NUMBER    ME_DEVICE_NUMBER
> +#define SOL_BUS_NUMBER        ME_BUS
> +#define SOL_DEVICE_NUMBER     ME_DEVICE_NUMBER
> +
> + ///
> +/// Convert to HECI# defined in BWG from Fun# /// #define
> +HECI_NAME_MAP(a) ((a < 2) ? (a + 1) : (a - 1))
> +
> +///
> +/// ME-related Chipset Definition
> +///
> +#define HeciEnable()    MeDeviceControl (HECI1, Enabled);
> +#define Heci2Enable()   MeDeviceControl (HECI2, Enabled);
> +#define Heci3Enable()   MeDeviceControl (HECI3, Enabled);
> +#define Heci4Enable()   MeDeviceControl (HECI4, Enabled);
> +#define IderEnable()    MeDeviceControl (IDER, Enabled);
> +#define SolEnable()     MeDeviceControl (SOL, Enabled);
> +
> +#define HeciDisable()   MeDeviceControl (HECI1, Disabled);
> +#define Heci2Disable()  MeDeviceControl (HECI2, Disabled); #define
> +Heci3Disable()  MeDeviceControl (HECI3, Disabled);
> +#define IderDisable()   MeDeviceControl (IDER, Disabled);
> +#define SolDisable()    MeDeviceControl (SOL, Disabled);
> +
> +#define DisableAllMeDevices() \
> +  HeciDisable (); \
> +  Heci2Disable (); \
> +  Heci3Disable (); \
> +  IderDisable (); \
> +  SolDisable ();
> +
> +///
> +/// HECI Device Id Definitions
> +///
> + #define IS_PCH_H_HECI_DEVICE_ID(DeviceId) \
> +     (  \
> +       (DeviceId == V_ME_PCH_H_HECI_DEVICE_ID) \
> +     )
> +
> + #define IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
> +     (  \
> +       (DeviceId == V_ME_PCH_LP_HECI_DEVICE_ID) \
> +     )
> +
> + #define IS_HECI_DEVICE_ID(DeviceId) \
> +     ( \
> +       IS_PCH_H_HECI_DEVICE_ID(DeviceId) || \
> +       IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
> +     )
> +
> +///
> +/// HECI2 Device Id Definitions
> +///
> +#define IS_PCH_H_HECI2_DEVICE_ID(DeviceId) \
> +     (  \
> +       (DeviceId == V_ME_PCH_H_HECI2_DEVICE_ID) \
> +     )
> +
> +#define IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
> +     (  \
> +       (DeviceId == V_ME_PCH_LP_HECI2_DEVICE_ID) \
> +     )
> +
> +#define IS_HECI2_DEVICE_ID(DeviceId) \
> +     ( \
> +       IS_PCH_H_HECI2_DEVICE_ID(DeviceId) || \
> +       IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
> +     )
> +
> +///
> +/// HECI3 Device Id Definitions
> +///
> +#define IS_PCH_H_HECI3_DEVICE_ID(DeviceId) \
> +    (  \
> +      (DeviceId == V_ME_PCH_H_HECI3_DEVICE_ID) \
> +    )
> +
> +#define IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
> +    (  \
> +      (DeviceId == V_ME_PCH_LP_HECI3_DEVICE_ID) \
> +    )
> +
> +#define IS_HECI3_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_HECI3_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
> +    )
> +
> +///
> +/// HECI4 Device Id Definitions
> +///
> +#define IS_PCH_H_HECI4_DEVICE_ID(DeviceId) \
> +    (  \
> +      (DeviceId == V_ME_PCH_H_HECI4_DEVICE_ID) \
> +    )
> +
> +#define IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
> +    (  \
> +      (DeviceId == V_ME_PCH_LP_HECI4_DEVICE_ID) \
> +    )
> +
> +#define IS_HECI4_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_HECI4_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
> +    )
> +
> +///
> +/// SoL Device Id Definitions
> +///
> +#define IS_PCH_H_SOL_DEVICE_ID(DeviceId) \
> +    (  \
> +      (DeviceId == V_ME_PCH_H_SOL_DEVICE_ID) \
> +    )
> +
> +#define IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
> +    (  \
> +      (DeviceId == V_ME_PCH_LP_SOL_DEVICE_ID) \
> +    )
> +
> +#define IS_PCH_SOL_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_SOL_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
> +    )
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
> new file mode 100644
> index 0000000000..a24973ce32
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
> @@ -0,0 +1,17 @@
> +/** @file
> +  This file contains definitions of ME Policy HOB.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _ME_POLICY_HOB_H_
> +#define _ME_POLICY_HOB_H_
> +
> +#include <MePolicyCommon.h>
> +
> +extern EFI_GUID gMePolicyHobGuid;
> +extern EFI_GUID gMePreMemPolicyHobGuid;
> +
> +#endif // _ME_POLICY_HOB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
> new file mode 100644
> index 0000000000..2d8ef1cf7a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
> @@ -0,0 +1,19 @@
> +/** @file
> +  MKHI Messages
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _MKHI_MSGS_H
> +#define _MKHI_MSGS_H
> +
> +///
> +/// End of Post
> +///
> +#define EOP_DISABLED    0
> +#define EOP_SEND_IN_PEI 1
> +#define EOP_SEND_IN_DXE 2
> +
> +#endif // _MKHI_MSGS_H
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
> new file mode 100644
> index 0000000000..518041cb58
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
> @@ -0,0 +1,41 @@
> +/** @file
> +  Interface definition details between ME and platform drivers during DXE
> phase.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _ME_POLICY_H_
> +#define _ME_POLICY_H_
> +
> +#include <ConfigBlock.h>
> +
> +/**
> +  ME Policy Protocol.
> +  All ME Policy Protocol change history listed here.
> +
> +**/
> +#define ME_POLICY_PROTOCOL_REVISION  1
> +
> +extern EFI_GUID gDxeMePolicyGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  ME policy provided by platform for DXE phase
> +  This protocol provides an interface to get Intel ME Configuration
> +information
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +typedef struct _ME_POLICY_PROTOCOL {
> +  CONFIG_BLOCK_TABLE_HEADER      TableHeader;
> +/*
> +  Individual Config Block Structures are added here in memory as part
> +of AddConfigBlock() */ } ME_POLICY_PROTOCOL;
> +
> +#pragma pack (pop)
> +
> +#endif // _ME_POLICY_H_
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:08   ` Chiu, Chasel
  2019-08-17  6:58   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:08 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:15 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add
> Include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds header files common to CPU modules.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
> |  45 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPre
> MemConfig.h | 106 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclocking
> Config.h    | 141 +++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfi
> g.h         |  54 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmt
> BasicConfig.h  | 179 ++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmt
> CustomConfig.h |  78 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmt
> TestConfig.h   | 149 +++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
> |  66 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
> |  16 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
> | 113 +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
> |  88 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
> |  23 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
> | 100 ++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
> | 261 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
> |  90 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
> | 118 +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
> |  84 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
> | 123 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
> |  50 ++++
>  19 files changed, 1884 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
> new file mode 100644
> index 0000000000..47a98131d0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
> @@ -0,0 +1,45 @@
> +/** @file
> +  CPU Config Block.
> +
> +  Copyright (c) 2019 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>:
> +  - Deprecate and move SkipMpInit to CpuConfigLibPreMemConfig.
> +  <b>Revision 3</b>:
> +  - Move DebugInterfaceEnable from CPU_TEST_CONFIG.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +  /**
> +    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;
> +  UINT32 SkipMpInit               : 1;            ///< @deprecated since revision 2.
> For Fsp only, Silicon Initialization will skip MP Initialization (including BSP) if
> enabled. For non-FSP, this should always be 0.
> +  UINT32 DebugInterfaceEnable     : 1;            ///< Enable or Disable
> processor debug features; <b>0: Disable</b>; 1: Enable.
> +  UINT32 RsvdBits                 : 28;           ///< Reserved for future use
> +  EFI_PHYSICAL_ADDRESS MicrocodePatchAddress;     ///< Pointer to
> microcode patch that is suitable for this processor.
> +} CPU_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _CPU_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibP
> reMemConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibP
> reMemConfig.h
> new file mode 100644
> index 0000000000..ce965a7510
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibP
> reMemConfig.h
> @@ -0,0 +1,106 @@
> +/** @file
> +  CPU Security PreMemory Config Block.
> +
> +  Copyright (c) 2019 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 5
> +
> +extern EFI_GUID gCpuConfigLibPreMemConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  CPU Config Library PreMemory Configuration Structure.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Update for JTAG Power Gate comment.
> +  <b>Revision 3</b>:
> +  - Add PeciSxReset and PeciC10Reset
> +  <b>Revision 4</b>:
> +  - Add SkipMpInit
> +  <b>Revision 5</b>:
> +  - Add DpSscMarginEnable
> +**/
> +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.
> +   - <b>1: Maximum non-turbo performance</b>.
> +   - 2: Turbo performance.
> +  @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;
> +  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;
> +  /**
> +    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>0: Disable</b> for CNL, and <b>1: Enable</b> for
> all other CPU's
> +    - 0: Disable
> +    - 1: Enable
> +  **/
> +  UINT32 PeciC10Reset               : 1;
> +  /**
> +    For Fsp only, Silicon Initialization will skip MP Initialization
> +    (including BSP) if enabled. For non-FSP, this should always be 0.
> +    - <b>0: Disable</b>
> +    - 1: Enable
> +  **/
> +  UINT32 SkipMpInit                 : 1;
> +  /**
> +    Enable DisplayPort SSC range reduction
> +    @note This should only be used on systems that exceeds allowed SSC
> modulation range as defined in VESA's spec.
> +    - <b>0: Disable</b>
> +    - 1: Enable
> +  **/
> +  UINT32 DpSscMarginEnable          : 1;
> +  UINT32 RsvdBits                   : 17;
> +  /**
> +    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;
> +  UINT8  Reserved[3];                    ///< Reserved for alignment
> +} CPU_CONFIG_LIB_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclocki
> ngConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclocki
> ngConfig.h
> new file mode 100644
> index 0000000000..a0b8a208e6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclocki
> ngConfig.h
> @@ -0,0 +1,141 @@
> +/** @file
> +  CPU Overclocking Config Block.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
> +#define _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
> +
> +#define CPU_OVERCLOCKING_CONFIG_REVISION 4
> +
> +extern EFI_GUID gCpuOverclockingPreMemConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  CPU Overclocking Configuration Structure.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>
> +  - Deprecate RingMinOcRatio
> +  <b>Revision 3</b>
> +  - Change RingDownBin default to 'Enabled'
> +  <b>Revision 4</b>
> +  - Add TvbRatioClipping, TvbVoltageOptimization
> +
> +**/
> +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.;
> <b>0: Disable</b>; 1: Enable (Lock).
> +  /**
> +  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 RsvdBits             :  10;              ///< 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-255. Max range varies by CPU
> sku.
> +  **/
> +  UINT8  CoreMaxOcRatio;
> +  /**
> +  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;
> +  /**
> +  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-255. Max range varies by CPU
> sku.
> +  **/
> +  UINT8  RingMaxOcRatio;
> +  /**
> +  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;
> +  UINT8  RingMinOcRatio;                          ///< Deprecated since rev 2.
> Minimum ring ratio override. <b>0: Hardware defaults.</b> Range: 0-83.
> +  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.
> +  /**
> +  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 RsvdBits1              :  6;
> +  /**
> +  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 0 to 63.
> +  **/
> +  UINT8  TjMaxOffset;
> +} CPU_OVERCLOCKING_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _CPU_OVERCLOCKING_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestCo
> nfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestCo
> nfig.h
> new file mode 100644
> index 0000000000..e45f335ff9
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestCo
> nfig.h
> @@ -0,0 +1,54 @@
> +/** @file
> +  CPU PID Config Block.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtBasicConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtBasicConfig.h
> new file mode 100644
> index 0000000000..2ad474b7e9
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtBasicConfig.h
> @@ -0,0 +1,179 @@
> +/** @file
> +  CPU Power Management Basic Config Block.
> +
> +  Copyright (c) 2019 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 2
> +
> +extern EFI_GUID gCpuPowerMgmtBasicConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  CPU Power Management Basic Configuration Structure.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Added MinRingRatioLimit
> +  - Added MaxRingRatioLimit
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +  /**
> +  Sets the boot frequency starting from reset vector.
> +   - 0: Maximum battery performance.
> +   - <b>1: Maximum non-turbo performance</b>.
> +   - 2: Turbo performance.
> +  @note If Turbo is selected BIOS will start in max non-turbo mode and switch
> to Turbo mode.
> +  **/
> +  UINT32 BootFrequency                  : 2;
> +  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; <b>0:
> Disabled</b>; 1: Enabled (Lock).
> +  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 RsvdBits                       : 9;      ///< 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 255.
> +     - 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 255.
> +     - 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 255.
> +     - 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 255.
> +     - 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 255.
> +     - 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 255.
> +     - 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 255.
> +     - 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 255.
> +     - 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>15</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.
> +  0: Disable; <b>1: Enable;</b>
> +  **/
> +  UINT8  EnableItbm                     : 1;
> +  /**
> +  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;
> +  UINT8  ReservedBits1                  : 6;      ///< 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.
> +  Default: <b>0 - AUTO</b>, auto will program 28 seconds.
> +  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;
> +} CPU_POWER_MGMT_BASIC_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _CPU_POWER_MGMT_BASIC_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtCustomConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtCustomConfig.h
> new file mode 100644
> index 0000000000..7eb91fa3ee
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtCustomConfig.h
> @@ -0,0 +1,78 @@
> +/** @file
> +  CPU Power Managment Custom Config Block.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtTestConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtTestConfig.h
> new file mode 100644
> index 0000000000..cb9b20249f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMg
> mtTestConfig.h
> @@ -0,0 +1,149 @@
> +/** @file
> +  CPU Power Management Test Config Block.
> +
> +  Copyright (c) 2019 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 3
> +
> +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,
> +  PpmIrmPairFixedPriority,
> +  PpmIrmPairRoundRobin,
> +  PpmIrmPairHashVector,
> +  PpmIrmNoChange
> +} PPM_IRM_SETTING;
> +
> +/**
> +  CPU Power Management Test Configuration Structure.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Update PkgCStateDemotion and PkgCStateUnDemotion to be Disable.
> +  <b>Revision 3</b>:
> +  - Add  CstateLatencyControl0TimeUnit for CFL only
> +  - Add  CstateLatencyControl0Irtl for CFL only
> +**/
> +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 AutoThermalReporting          : 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. [Cannonlake Y] 0: Disable; <b>1: Enable</b>
> [CoffeeLake] <b>Disable</b>; 1: Enable
> +  UINT32 PkgCStateUnDemotion           : 1;        ///<              Enable or
> Disable Package Cstate UnDemotion.  0: [Cannonlake Y] 0: Disable; <b>1:
> Enable</b> [CoffeeLake] <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;        ///<              Configuration for
> boot TDP selection; <b>0: TDP Nominal</b>; 1: TDP Down; 2: TDP Up.
> +  UINT16 CstateLatencyControl1Irtl;                ///< Offset 32-33 Interrupt
> Response Time Limit of LatencyContol1 MSR 0x60B[9:0].
> +  UINT16 CstateLatencyControl2Irtl;                ///< Offset 34-35 Interrupt
> Response Time Limit of LatencyContol2 MSR 0x60C[9:0].
> +  UINT16 CstateLatencyControl3Irtl;                ///< Offset 36-37 Interrupt
> Response Time Limit of LatencyContol3 MSR 0x633[9:0].
> +  UINT16 CstateLatencyControl4Irtl;                ///< Offset 38-39 Interrupt
> Response Time Limit of LatencyContol4 MSR 0x634[9:0].
> +  UINT16 CstateLatencyControl5Irtl;                ///< Offset 40-41 Interrupt
> Response Time Limit of LatencyContol5 MSR 0x635[9:0].
> +  UINT16 CstateLatencyControl0Irtl;                ///< Offset 42-43 Interrupt
> Response Time Limit of LatencyContol1 MSR 0x60A[9:0].
> +  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 CstateLatencyControl0TimeUnit; ///< Offset 45
> TimeUnit for Latency Control0 MSR 0x60A[12:10]; (CFL)2: 1024ns
> +  C_STATE_TIME_UNIT CstateLatencyControl1TimeUnit; ///< Offset 46
> TimeUnit for Latency Control1 MSR 0x60B[12:10]; (CFL)2: 1024ns, (CNL)3:
> 32768ns
> +  C_STATE_TIME_UNIT CstateLatencyControl2TimeUnit; ///< Offset 47
> TimeUnit for Latency Control2 MSR 0x60C[12:10]; (CFL)2: 1024ns, (CNL)3:
> 32768ns
> +  C_STATE_TIME_UNIT CstateLatencyControl3TimeUnit; ///< Offset 48
> TimeUnit for Latency Control3 MSR 0x633[12:10]; (CFL)2: 1024ns, (CNL)3:
> 32768ns
> +  C_STATE_TIME_UNIT CstateLatencyControl4TimeUnit; ///< Offset 49
> TimeUnit for Latency Control4 MSR 0x634[12:10]; (CFL)2: 1024ns, (CNL)3:
> 32768ns
> +  C_STATE_TIME_UNIT CstateLatencyControl5TimeUnit; ///< Offset 50
> TimeUnit for Latency Control5 MSR 0x635[12:10]; (CFL)2: 1024ns, (CNL)3:
> 32768ns
> +  /**
> +  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.
> +   - 1: Round robin.
> +   - 2: Hash vector.
> +   - 4: PAIR with fixed priority.
> +   - 5: PAIR with round robin.
> +   - 6: PAIR with hash vector.
> +   - 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig
> .h
> new file mode 100644
> index 0000000000..b94eb5e263
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig
> .h
> @@ -0,0 +1,66 @@
> +/** @file
> +  CPU Test Config Block.
> +
> +  Copyright (c) 2019 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 4
> +
> +extern EFI_GUID gCpuTestConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  CPU Test Configuration Structure.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Fixed RsvdBits incorrect value.
> +  <b>Revision 3</b>:
> +  - Added CpuWakeUpTimer
> +  <b>Revision 4</b>:
> +  - Deprecate and move DebugInterfaceEnable to CPU_CONFIG.
> +**/
> +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                DebugInterfaceEnable            : 1;     ///< @deprecated
> Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
> +  UINT32                DebugInterfaceLockEnable        : 1;     ///< Lock or
> Unlock debug interface features; 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.
> +  /**
> +    This policy should be used to enable or disable Voltage Optimization
> feature.
> +    Recommended defaults:
> +     Enable  - For Mobile SKUs(U/Y)
> +     Disable - Rest of all SKUs other than Mobile.
> +  **/
> +  UINT32                VoltageOptimization             : 1;
> +  UINT32                CpuWakeUpTimer                  : 1;      ///< Enable or
> Disable long CPU wake up timer. 0: Disabled (8s); <b>1: Enabled (180s)</b>.
> +  UINT32                RsvdBits                        : 21;     ///< 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;
> +} CPU_TEST_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _CPU_TEST_CONFIG_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
> new file mode 100644
> index 0000000000..48fdbdd012
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
> @@ -0,0 +1,16 @@
> +/** @file
> +  Macros to simplify and abstract the interface to CPU configuration.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPUACCESS_H_
> +#define _CPUACCESS_H_
> +
> +#include "CpuRegs.h"
> +#include "CpuDataStruct.h"
> +#include "CpuPowerMgmt.h"
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
> new file mode 100644
> index 0000000000..2382e60dca
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
> @@ -0,0 +1,113 @@
> +/** @file
> +  This file declares various data structures used in CPU reference code.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_DATA_STRUCT_H
> +#define _CPU_DATA_STRUCT_H
> +
> +//
> +// The reason for changing the state of the processor Only applies to Disabling
> processors.
> +// In future, we can add add/remove support
> +//
> +#define CPU_CAUSE_NOT_DISABLED      0x0000
> +#define CPU_CAUSE_INTERNAL_ERROR    0x0001
> +#define CPU_CAUSE_THERMAL_ERROR     0x0002
> +#define CPU_CAUSE_SELFTEST_FAILURE  0x0004
> +#define CPU_CAUSE_PREBOOT_TIMEOUT   0x0008
> +#define CPU_CAUSE_FAILED_TO_START   0x0010
> +#define CPU_CAUSE_CONFIG_ERROR      0x0020
> +#define CPU_CAUSE_USER_SELECTION    0x0080
> +#define CPU_CAUSE_BY_ASSOCIATION    0x0100
> +#define CPU_CAUSE_UNSPECIFIED       0x8000
> +
> +typedef UINT32 CPU_STATE_CHANGE_CAUSE;
> +
> +///
> +/// 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;
> +
> +///
> +/// Structure to describe microcode header
> +///
> +typedef struct {
> +  UINT32 HeaderVersion;  ///< Version number of the update header.
> +  UINT32 UpdateRevision; ///< Unique version number for the update.
> +  UINT32 Date;           ///< Date of the update creation.
> +  UINT32 ProcessorId;    ///< Signature of the processor that requires this
> update.
> +  UINT32 Checksum;       ///< Checksum of update data and header.
> +  UINT32 LoaderRevision; ///< Version number of the microcode loader
> program.
> +  UINT32 ProcessorFlags; ///< Lower 4 bits denoting platform type
> information.
> +  UINT32 DataSize;       ///< Size of encoded data in bytes.
> +  UINT32 TotalSize;      ///< Total size of microcode update in bytes.
> +  UINT8  Reserved[12];   ///< Reserved bits.
> +} CPU_MICROCODE_HEADER;
> +
> +///
> +/// Structure to describe the extended signature table header of the
> microcode update
> +///
> +typedef struct {
> +  UINT32 ExtendedSignatureCount; ///< Number of extended signature
> structures.
> +  UINT32 ExtendedTableChecksum;  ///< Checksum of update extended
> processor signature table.
> +  UINT8  Reserved[12];           ///< Reserved bits.
> +} CPU_MICROCODE_EXTENDED_TABLE_HEADER;
> +
> +///
> +/// Structure to describe the data of the extended table of the microcode
> update
> +///
> +typedef struct {
> +  UINT32 ProcessorSignature; ///< Extended signature of the processor that
> requires this update
> +  UINT32 ProcessorFlag;      ///< Lower 4 bits denoting platform type
> information
> +  UINT32 ProcessorChecksum;  ///< checksum of each of the extended
> update
> +} CPU_MICROCODE_EXTENDED_TABLE;
> +
> +#pragma pack(1)
> +///
> +/// MSR_REGISTER definition as a Union of QWORDS, DWORDS and BYTES
> +///
> +typedef union _MSR_REGISTER {
> +  UINT64  Qword;       ///< MSR value in 64 bit QWORD.
> +
> +  ///
> +  /// MSR value represented in two DWORDS
> +  ///
> +  struct {
> +    UINT32  Low;       ///< Lower DWORD of the 64 bit MSR value.
> +    UINT32  High;      ///< Higher DWORD of the 64 bit MSR value.
> +  } Dwords;
> +
> +  ///
> +  /// MSR value represented in eight bytes.
> +  ///
> +  struct {
> +    UINT8 FirstByte;   ///< First byte of the 64 bit MSR value.
> +    UINT8 SecondByte;  ///< Second byte of the 64 bit MSR value.
> +    UINT8 ThirdByte;   ///< Third byte of the 64 bit MSR value.
> +    UINT8 FouthByte;   ///< Fourth byte of the 64 bit MSR value.
> +    UINT8 FifthByte;   ///< Fifth byte of the 64 bit MSR value.
> +    UINT8 SixthByte;   ///< Sixth byte of the 64 bit MSR value.
> +    UINT8 SeventhByte; ///< Seventh byte of the 64 bit MSR value.
> +    UINT8 EighthByte;  ///< Eigth byte of the 64 bit MSR value.
> +  } Bytes;
> +} MSR_REGISTER;
> +
> +///
> +/// Store BIST data for BSP.
> +///
> +typedef struct {
> +  UINT32 ApicId;    ///< APIC ID
> +  UINT32 Health;    ///< BIST result
> +} BIST_HOB_DATA;
> +
> +#pragma pack()
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
> new file mode 100644
> index 0000000000..4862d62975
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
> @@ -0,0 +1,88 @@
> +/** @file
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  //
> +  // Define CPU NVS Area operation region.
> +  //
> +
> +#ifndef _CPU_NVS_AREA_DEF_H_
> +#define _CPU_NVS_AREA_DEF_H_
> +
> +#pragma pack (push,1)
> +typedef struct {
> +  UINT8    Revision;                                ///< Offset 0       CPU GlobalNvs
> Revision
> +  UINT32   PpmFlags;                                ///< Offset 1       PPM Flags
> Values
> +  UINT8    Reserved0[1];                            ///< Offset 5:5
> +  UINT8    AutoCriticalTripPoint;                   ///< Offset 6       Auto Critical
> Trip Point
> +  UINT8    AutoPassiveTripPoint;                    ///< Offset 7       Auto
> Passive Trip Point
> +  UINT8    AutoActiveTripPoint;                     ///< Offset 8       Auto Active
> Trip Point
> +  UINT32   Cpuid;                                   ///< Offset 9       CPUID
> +  UINT8    ConfigurablePpc;                         ///< Offset 13      Boot Mode
> vlues for _PPC
> +  UINT8    CtdpLevelsSupported;                     ///< Offset 14      ConfigTdp
> Number Of Levels
> +  UINT8    ConfigTdpBootModeIndex;                  ///< Offset 15      CTDP
> Boot Mode Index
> +  UINT16   CtdpPowerLimit1[3];                      ///< Offset 16      CTDP Level
> 0 Power Limit1
> +                                                    ///< Offset 18      CTDP Level 1 Power
> Limit1
> +                                                    ///< Offset 20      CTDP Level 2 Power
> Limit1
> +  UINT16   CtdpPowerLimit2[3];                      ///< Offset 22      CTDP Level
> 0 Power Limit2
> +                                                    ///< Offset 24      CTDP Level 1 Power
> Limit2
> +                                                    ///< Offset 26      CTDP Level 2 Power
> Limit2
> +  UINT8    CtdpPowerLimitWindow[3];                 ///< Offset 28      CTDP
> Level 0 Power Limit1 Time Window
> +                                                    ///< Offset 29      CTDP Level 1 Power
> Limit1 Time Window
> +                                                    ///< Offset 30      CTDP Level 2 Power
> Limit1 Time Window
> +  UINT8    CtdpCtc[3];                              ///< Offset 31      CTDP Level 0
> CTC
> +                                                    ///< Offset 32      CTDP Level 1 CTC
> +                                                    ///< Offset 33      CTDP Level 2 CTC
> +  UINT8    CtdpTar[3];                              ///< Offset 34      CTDP Level 0
> TAR
> +                                                    ///< Offset 35      CTDP Level 1 TAR
> +                                                    ///< Offset 36      CTDP Level 2 TAR
> +  UINT8    CtdpPpc[3];                              ///< Offset 37      CTDP Level 0
> PPC
> +                                                    ///< Offset 38      CTDP Level 1 PPC
> +                                                    ///< Offset 39      CTDP Level 2 PPC
> +  UINT8    Reserved1[1];                            ///< Offset 40:40
> +  UINT8    C6MwaitValue;                            ///< Offset 41      Mwait Hint
> value for C6
> +  UINT8    C7MwaitValue;                            ///< Offset 42      Mwait Hint
> value for C7/C7s
> +  UINT8    CDMwaitValue;                            ///< Offset 43      Mwait Hint
> value for C7/C8/C9/C10
> +  UINT8    Reserved2[2];                            ///< Offset 44:45
> +  UINT16   C6Latency;                               ///< Offset 46      Latency Value
> for C6
> +  UINT16   C7Latency;                               ///< Offset 48      Latency Value
> for C7/C7S
> +  UINT16   CDLatency;                               ///< Offset 50      Latency Value
> for C8/C9/C10
> +  UINT16   CDIOLevel;                               ///< Offset 52      IO LVL value
> for C8/C9/C10
> +  UINT16   CDPowerValue;                            ///< Offset 54      Power value
> for C8/C9/C10
> +  UINT8    MiscPowerManagementFlags;                ///< Offset 56
> MiscPowerManagementFlags
> +  UINT8    EnableDigitalThermalSensor;              ///< Offset 57      Digital
> Thermal Sensor Enable
> +  UINT8    BspDigitalThermalSensorTemperature;      ///< Offset 58
> Digital Thermal Sensor 1 Readingn for BSP
> +  UINT8    ApDigitalThermalSensorTemperature;       ///< Offset 59
> Digital Thermal Sensor 2 Reading for AP1
> +  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 60      DTS
> SMI Function Call via DTS IO Trap
> +  UINT8    PackageDTSTemperature;                   ///< Offset 61      Package
> Temperature
> +  UINT8    IsPackageTempMSRAvailable;               ///< Offset 62
> Package Temperature MSR available
> +  UINT8    Ap2DigitalThermalSensorTemperature;      ///< Offset 63
> Digital Thermal Sensor 3 Reading for AP2
> +  UINT8    Ap3DigitalThermalSensorTemperature;      ///< Offset 64
> Digital Thermal Sensor 4 Reading for AP3
> +  UINT64   BiosGuardMemAddress;                     ///< Offset 65      BIOS
> Guard Memory Address for Tool Interface
> +  UINT8    BiosGuardMemSize;                        ///< Offset 73      BIOS
> Guard Memory Size for Tool Interface
> +  UINT16   BiosGuardIoTrapAddress;                  ///< Offset 74      BIOS
> Guard IoTrap Address for Tool Interface
> +  UINT16   BiosGuardIoTrapLength;                   ///< Offset 76      BIOS
> Guard IoTrap Length for Tool Interface
> +  UINT16   DtsIoTrapAddress;                        ///< Offset 78      DTS IO trap
> Address
> +  UINT8    DtsIoTrapLength;                         ///< Offset 80      DTS IO trap
> Length
> +  UINT8    DtsAcpiEnable;                           ///< Offset 81      DTS is in ACPI
> Mode Enabled
> +  UINT8    SgxStatus;                               ///< Offset 82      SGX Status
> +  UINT64   EpcBaseAddress;                          ///< Offset 83      EPC Base
> Address
> +  UINT64   EpcLength;                               ///< Offset 91      EPC Length
> +  UINT8    HwpVersion;                              ///< Offset 99      HWP Version
> +  UINT8    HwpInterruptStatus;                      ///< Offset 100     HWP
> Interrupt Status
> +  UINT8    DtsInterruptStatus;                      ///< Offset 101     DTS
> Interrupt Status
> +  UINT8    HwpSmi;                                  ///< Offset 102     SMI to setup
> HWP LVT tables
> +  UINT8    LowestMaxPerf;                           ///< Offset 103     Max ratio of
> the slowest core.
> +  UINT8    EnableItbm;                              ///< Offset 104
> Enable/Disable Intel Turbo Boost Max Technology 3.0.
> +  UINT8    EnableItbmDriver;                        ///< Offset 105
> Enable/Disable Intel Turbo Boost Max Technology 3.0 Driver.
> +  UINT8    ItbmInterruptStatus;                     ///< Offset 106     Intel Turbo
> Boost Max Technology 3.0 interrupt status.
> +  UINT8    ItbmSmi;                                 ///< Offset 107     SMI to resume
> periodic SMM for Intel Turbo Boost Max Technology 3.0.
> +  UINT8    OcBins;                                  ///< Offset 108     Indicates bins
> of Oc support. MSR 194h FLEX_RATIO Bits (19:17)
> +  UINT8    C3MwaitValue;                            ///< Offset 109     Mwait Hint
> value for C3 (CFL only)
> +  UINT16   C3Latency;                               ///< Offset 110     Latency Value
> for C3 (CFL only)
> +} CPU_NVS_AREA;
> +
> +#pragma pack(pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
> new file mode 100644
> index 0000000000..a9abd426f9
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  CPU Policy structure definition which will contain several config blocks
> during runtime.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_POLICY_COMMON_H_
> +#define _CPU_POLICY_COMMON_H_
> +
> +#include "CpuPowerMgmt.h"
> +#include <ConfigBlock.h>
> +#include <ConfigBlock/CpuOverclockingConfig.h>
> +#include <ConfigBlock/CpuConfig.h>
> +#include <ConfigBlock/CpuPidTestConfig.h>
> +#include <ConfigBlock/CpuPowerMgmtBasicConfig.h>
> +#include <ConfigBlock/CpuPowerMgmtCustomConfig.h>
> +#include <ConfigBlock/CpuPowerMgmtTestConfig.h>
> +#include <ConfigBlock/CpuTestConfig.h>
> +#include <ConfigBlock/CpuConfigLibPreMemConfig.h>
> +
> +#endif // _CPU_POLICY_COMMON_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
> new file mode 100644
> index 0000000000..af1f70b34f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
> @@ -0,0 +1,100 @@
> +/** @file
> +  This file contains define definitions specific to processor
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _POWER_MGMT_DEFINITIONS_H_
> +#define _POWER_MGMT_DEFINITIONS_H_
> +
> +#define CSTATE_SUPPORTED          0x1
> +#define ENHANCED_CSTATE_SUPPORTED 0x2
> +#define C6_C7_SHORT_LATENCY_SUPPORTED 0x01
> +#define C6_C7_LONG_LATENCY_SUPPORTED  0x02
> +#define C7s_SHORT_LATENCY_SUPPORTED   0x03
> +#define C7s_LONG_LATENCY_SUPPORTED    0x04
> +//
> +// Voltage offset definitions
> +//
> +#define OC_LIB_OFFSET_ADAPTIVE  0
> +#define OC_LIB_OFFSET_OVERRIDE  1
> +//
> +// Platform Power Management Flags Bit Definitions:
> +//   These defines are also used in CPU0CST.ASL to check platform
> configuration
> +//   and build C-state table accordingly.
> +//
> +#define PPM_EIST                BIT0   ///< Enhanced Intel Speed Step
> Technology.
> +#define PPM_C1                  BIT1   ///< C1 enabled, supported.
> +#define PPM_C1E                 BIT2   ///< C1E enabled.
> +#define PPM_C3                  BIT3   ///< C3 enabled, supported.
> +#define PPM_C6                  BIT4   ///< C6 enabled, supported.
> +#define PPM_C7                  BIT5   ///< C7 enabled, supported.
> +#define PPM_C7S                 BIT6   ///< C7S enabled, supported
> +#define PPM_TM                  BIT7   ///< Adaptive Thermal Monitor.
> +#define PPM_TURBO               BIT8   ///< Long duration turbo mode
> +#define PPM_CMP                 BIT9   ///< CMP.
> +#define PPM_TSTATES             BIT10  ///< CPU throttling states
> +#define PPM_MWAIT_EXT           BIT11  ///< MONITIOR/MWAIT Extensions
> supported.
> +#define PPM_EEPST               BIT12  ///< Energy efficient P-State Feature
> enabled
> +#define PPM_TSTATE_FINE_GRAINED BIT13  ///< Fine grained CPU Throttling
> states
> +#define PPM_CD                  BIT14  ///< Deep Cstate - C8/C9/C10
> +#define PPM_TIMED_MWAIT         BIT15  ///< Timed Mwait support
> +#define C6_LONG_LATENCY_ENABLE  BIT16  ///< 1=C6 Long and Short,0=C6
> Short only
> +#define C7_LONG_LATENCY_ENABLE  BIT17  ///< 1=C7 Long and Short,0=C7
> Short only
> +#define C7s_LONG_LATENCY_ENABLE BIT18  ///< 1=C7s Long and
> Short,0=C7s Short only
> +#define PPM_C8                  BIT19  ///< 1= C8 enabled/supported
> +#define PPM_C9                  BIT20  ///< 1= C9 enabled/supported
> +#define PPM_C10                 BIT21  ///< 1= C10 enabled/supported
> +#define PPM_HWP                 BIT22  ///< 1= HWP enabled/supported
> +#define PPM_HWP_LVT             BIT23  ///< 1= HWP LVT enabled/supported
> +#define PPM_OC_UNLOCKED         BIT24  ///< 1= Overclocking fully unlocked
> +
> +#define PPM_C_STATES            0x7A    ///< PPM_C1 + PPM_C3 + PPM_C6 +
> PPM_C7 + PPM_C7S
> +#define C3_LATENCY              0x4E
> +#define C6_C7_SHORT_LATENCY     0x76
> +#define C6_C7_LONG_LATENCY      0x94
> +#define C8_LATENCY              0xFA
> +#define C9_LATENCY              0x14C
> +#define C10_LATENCY             0x3F2
> +
> +//
> +// The following definitions are based on assumed location for the  ACPI
> +// Base Address.  Modify as necessary base on platform-specific
> requirements.
> +//
> +#define PCH_ACPI_PBLK 0x1810
> +#define PCH_ACPI_LV2  0x1814
> +#define PCH_ACPI_LV3  0x1815
> +#define PCH_ACPI_LV4  0x1816
> +#define PCH_ACPI_LV6  0x1818
> +#define PCH_ACPI_LV5  0x1817
> +#define PCH_ACPI_LV7  0x1819
> +
> +//
> +// C-State Latency (us) and Power (mW) for C1
> +//
> +#define C1_LATENCY                        1
> +#define C1_POWER                          0x3E8
> +#define C3_POWER                          0x1F4
> +#define C6_POWER                          0x15E
> +#define C7_POWER                          0xC8
> +#define C8_POWER                          0xC8
> +#define C9_POWER                          0xC8
> +#define C10_POWER                         0xC8
> +
> +
> +#define PID_DOMAIN_KP                     0
> +#define PID_DOMAIN_KI                     1
> +#define PID_DOMAIN_KD                     2
> +#define MAILBOX_PARAM_1_OFFSET            8
> +
> +///
> +///  VR Domain Definitions
> +///
> +#define CPU_VR_DOMAIN_SA           0x0
> +#define CPU_VR_DOMAIN_IA           0x1
> +#define CPU_VR_DOMAIN_RING         0x2
> +#define CPU_VR_DOMAIN_GT           0x3
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
> new file mode 100644
> index 0000000000..68f2c019e2
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
> @@ -0,0 +1,261 @@
> +/** @file
> +  Register names for CPU registers
> +
> +  <b>Conventions</b>
> +  - Definitions beginning with "MSR_" are MSRs
> +  - 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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_REGS_H_
> +#define _CPU_REGS_H_
> +
> +#define MSR_CORE_THREAD_COUNT
> 0x00000035
> +#define B_THREAD_COUNT_MASK                                           0xFFFF
> +#define MSR_SPCL_CHIPSET_USAGE_ADDR
> 0x000001FE
> +///
> +/// Arch-specific MSR defines in SDM
> +/// @{
> +
> +#define MSR_PLATFORM_INFO                                             0x000000CE
> +#define N_PLATFORM_INFO_MIN_RATIO                                     40
> +#define B_PLATFORM_INFO_RATIO_MASK                                    0xFF
> +#define N_PLATFORM_INFO_MAX_RATIO                                     8
> +#define B_MSR_PLATFORM_INFO_BIOSGUARD_AVAIL
> BIT35
> +#define N_MSR_PLATFORM_INFO_CONFIG_TDP_NUM_LEVELS_OFFSET
> 33
> +#define V_CONFIG_TDP_NUM_LEVELS_MASK                                  (BIT34
> | BIT33)
> +#define B_PLATFORM_INFO_TDC_TDP_LIMIT                                 BIT29
> +#define N_PLATFORM_INFO_RATIO_LIMIT                                   28
> +#define B_PLATFORM_INFO_RATIO_LIMIT                                   BIT28
> +#define B_PLATFORM_INFO_SAMPLE_PART                                   BIT27
> +#define B_PLATFORM_INFO_SMM_SAVE_CONTROL
> BIT16
> +#define N_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET
> 30
> +#define B_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET
> BIT30
> +#define B_PLATFORM_INFO_TIMED_MWAIT_SUPPORTED
> BIT37
> +#define B_PLATFORM_INFO_EDRAM_EN                                      BIT57
> +
> +//
> +// MSR_BROADWELL_PKG_CST_CONFIG_CONTROL: related defines
> +//
> +#define B_TIMED_MWAIT_ENABLE                                          BIT31 ///<
> @todo Remove when bitfield definition is available.
> +#define V_CSTATE_LIMIT_C1                                             0x01
> +#define V_CSTATE_LIMIT_C3                                             0x02
> +#define V_CSTATE_LIMIT_C6                                             0x03
> +#define V_CSTATE_LIMIT_C7                                             0x04
> +#define V_CSTATE_LIMIT_C7S                                            0x05
> +#define V_CSTATE_LIMIT_C8                                             0x06
> +#define V_CSTATE_LIMIT_C9                                             0x07
> +#define V_CSTATE_LIMIT_C10                                            0x08
> +
> +#define MSR_PMG_IO_CAPTURE_BASE
> 0x000000E4
> +#define B_MSR_PMG_CST_RANGE                                           (BIT18 |
> BIT17 | BIT16)
> +#define V_IO_CAPT_LVL2                                                (0x0 << 16)   ///<
> C3
> +#define V_IO_CAPT_LVL3                                                (0x1 << 16)   ///<
> C6
> +#define V_IO_CAPT_LVL4                                                (0x2 << 16)   ///<
> C7
> +#define V_IO_CAPT_LVL5                                                (0x3 << 16)   ///<
> C8
> +#define V_IO_CAPT_LVL6                                                (0x4 << 16)   ///<
> C9
> +#define V_IO_CAPT_LVL7                                                (0x5 << 16)   ///<
> C10
> +#define V_IO_CAPT_LVL2_BASE_ADDR_MASK                                 0xFFFF
> +
> +#define MSR_TEMPERATURE_TARGET
> 0x000001A2
> +#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LOCK
> BIT31
> +#define N_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LIMIT
> 24
> +#define V_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_OFFSET_MASK
> 0x3F
> +#define
> N_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_OFFSET
> (16)
> +#define
> B_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_MASK
> (0xFF << 16)
> +#define N_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET
> 8
> +#define B_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET
> (0xFF << 8)
> +#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_TIME_WINDOW
> (0x7F)
> +#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_MASK
> 0xFF
> +#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_CLAMP_BIT
> BIT7
> +
> +
> +#define MSR_TURBO_RATIO_LIMIT
> 0x000001AD
> +#define N_MSR_TURBO_RATIO_LIMIT_1C                                    0
> +#define B_MSR_TURBO_RATIO_LIMIT_1C                                    (0xFF <<
> 0)
> +#define N_MSR_TURBO_RATIO_LIMIT_2C                                    8
> +#define B_MSR_TURBO_RATIO_LIMIT_2C                                    (0xFF <<
> 8)
> +#define N_MSR_TURBO_RATIO_LIMIT_3C                                    16
> +#define B_MSR_TURBO_RATIO_LIMIT_3C                                    (0xFF <<
> 16)
> +#define N_MSR_TURBO_RATIO_LIMIT_4C                                    24
> +#define B_MSR_TURBO_RATIO_LIMIT_4C                                    (0xFF <<
> 24)
> +#define N_MSR_TURBO_RATIO_LIMIT_5C                                    32
> +#define B_MSR_TURBO_RATIO_LIMIT_5C                                    (0xFF <<
> 32)
> +#define N_MSR_TURBO_RATIO_LIMIT_6C                                    40
> +#define B_MSR_TURBO_RATIO_LIMIT_6C                                    (0xFF <<
> 40)
> +#define N_MSR_TURBO_RATIO_LIMIT_7C                                    48
> +#define B_MSR_TURBO_RATIO_LIMIT_7C                                    (0xFF <<
> 48)
> +#define N_MSR_TURBO_RATIO_LIMIT_8C                                    56
> +#define B_MSR_TURBO_RATIO_LIMIT_8C                                    (0xFF <<
> 56)
> +
> +#define MSR_IA32_FEATURE_CONFIG
> 0x0000013C
> +#define B_IA32_FEATURE_CONFIG_AES_DIS                                 BIT1
> +#define B_IA32_FEATURE_CONFIG_LOCK                                    BIT0
> +
> +//
> +// MSRs for SMM State Save Register
> +//
> +#define MSR_SMM_MCA_CAP
> 0x0000017D
> +#define B_TARGETED_SMI                                                BIT56
> +#define N_TARGETED_SMI                                                56
> +#define B_SMM_CPU_SVRSTR                                              BIT57
> +#define N_SMM_CPU_SVRSTR                                              57
> +#define B_SMM_CODE_ACCESS_CHK                                         BIT58
> +#define N_SMM_CODE_ACCESS_CHK                                         58
> +#define B_LONG_FLOW_INDICATION                                        BIT59
> +#define N_LONG_FLOW_INDICATION                                        59
> +#define MSR_SMM_FEATURE_CONTROL
> 0x000004E0
> +#define B_SMM_FEATURE_CONTROL_LOCK                                    BIT0
> +#define B_SMM_CPU_SAVE_EN                                             BIT1
> +#define B_SMM_CODE_CHK_EN                                             BIT2
> +
> +/// @}
> +
> +
> +///
> +/// Bit defines for MSRs defined in
> UefiCpuPkg/Include/Register/ArchitecturalMsr.h.
> +/// @{
> +
> +//
> +// Number of fixed MTRRs
> +//
> +#define V_FIXED_MTRR_NUMBER                                           11
> +
> +//
> +// Number of variable MTRRs
> +//
> +#define V_MAXIMUM_VARIABLE_MTRR_NUMBER                                10
> +
> +//
> +// Bit defines for MSR_IA32_MTRR_DEF_TYPE
> +//
> +#define B_CACHE_MTRR_VALID                                            BIT11
> +#define B_CACHE_FIXED_MTRR_VALID                                      BIT10
> +
> +//
> +// Bit defines for MSR_IA32_DEBUG_INTERFACE
> +//
> +#define B_DEBUG_INTERFACE_ENABLE                                      BIT0
> +#define B_DEBUG_INTERFACE_LOCK                                        BIT30
> +#define B_DEBUG_INTERFACE_DEBUG_STATUS                                BIT31
> +
> +/// @}
> +
> +///
> +/// Other defines
> +///
> +#ifndef TRIGGER_MODE_EDGE
> +#define TRIGGER_MODE_EDGE             0x00
> +#endif
> +#ifndef TRIGGER_MODE_LEVEL
> +#define TRIGGER_MODE_LEVEL            0x01
> +#endif
> +
> +#ifndef CPU_FEATURE_DISABLE
> +#define CPU_FEATURE_DISABLE  0
> +#endif
> +#ifndef CPU_FEATURE_ENABLE
> +#define CPU_FEATURE_ENABLE   1
> +#endif
> +
> +#define CACHE_UNCACHEABLE               0
> +#define CACHE_WRITECOMBINING            1
> +#define CACHE_WRITETHROUGH              4
> +#define CACHE_WRITEPROTECTED            5
> +#define CACHE_WRITEBACK                 6
> +
> +
> +//
> +// Processor Definitions
> +//
> +#define CPUID_FULL_STEPPING                      0x0000000F
> +#define CPUID_FULL_FAMILY_MODEL                  0x0FFF0FF0
> +#define CPUID_FULL_FAMILY_MODEL_STEPPING         0x0FFF0FFF
> +#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX 0x000806E0
> +#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO 0x000906E0
> +#define CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO 0x00060670
> +
> +#ifndef STALL_ONE_MICRO_SECOND
> +#define STALL_ONE_MICRO_SECOND 1
> +#endif
> +#ifndef STALL_ONE_MILLI_SECOND
> +#define STALL_ONE_MILLI_SECOND 1000
> +#endif
> +
> +#define BITS(x) (1 << (x))
> +
> +/**
> +Notes :
> +  1.  Bit position always starts at 0.
> +  2.  Following macros are applicable only for Word aligned integers.
> +**/
> +#define BIT(Pos, Value)               (1 << (Pos) & (Value))
> +#define BITRANGE(From, Width, Value)  (((Value) >> (From)) & ((1 << (Width))
> - 1))
> +
> +///
> +/// Enums for CPU Family IDs
> +///
> +typedef enum {
> +  EnumCpuCflUltUlx    =
> CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
> +  EnumCpuCflDtHalo    =
> CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO,
> +  EnumCpuCnlDtHalo    =
> CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO,
> +  EnumCpuMax          = CPUID_FULL_FAMILY_MODEL
> +} CPU_FAMILY;
> +
> +///
> +/// Enums for CPU Stepping IDs
> +///
> +typedef enum {
> +  ///
> +  /// Coffeelake ULX/ULT Steppings
> +  ///
> +  EnumKblH0         = 9,
> +  EnumCflD0         = 0xA,
> +
> +  /// Whiskey Lake ULT Steppings
> +  EnumCflW0         = 0xB,
> +  EnumCflV0         = 0xC,
> +
> +  EnumCflMaxUltUlxStep = EnumCflV0,
> +
> +  ///
> +  /// Coffeelake DT/Halo Steppings
> +  ///
> +  EnumCflU0         = 0xA,
> +  EnumCflB0         = 0xB,
> +  EnumCflP0         = 0xC,
> +  EnumCflR0         = 0xD,
> +  EnumCflMaxDtHaloStep = EnumCflR0,
> +
> +  ///
> +  /// Max Stepping
> +  ///
> +  EnumCpuSteppingMax  = CPUID_FULL_STEPPING
> +} CPU_STEPPING;
> +
> +///
> +/// Enums for CPU SKU IDs
> +///
> +typedef enum {
> +  EnumCpuUlt        = 0,
> +  EnumCpuTrad,
> +  EnumCpuUlx,
> +  EnumCpuHalo,
> +  EnumCpuUnknown
> +} CPU_SKU;
> +
> +///
> +/// Enums for CPU Generation
> +///
> +typedef enum {
> +  EnumCflCpu  = 0,
> +  EnumCpuUnknownGeneration = 255
> +} CPU_GENERATION;
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
> new file mode 100644
> index 0000000000..79dff36783
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
> @@ -0,0 +1,90 @@
> +/** @file
> +  Header file for Cpu Mailbox Lib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_MAILBOX_LIB_H_
> +#define _CPU_MAILBOX_LIB_H_
> +
> +//
> +//  Mailbox Related Definitions
> +//
> +
> +/**
> +  Generic Mailbox function for mailbox write commands. This function will
> +  poll the mailbox interface for control, issue the write request, poll
> +  for completion, and verify the write was succussful.
> +
> +  @param[in]  MailboxType     The type of mailbox interface to read. The
> Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
> +  @param[in]  MailboxCommand  Overclocking mailbox command data
> +  @param[in]  MailboxData     Overclocking mailbox interface data
> +  @param[out] *MailboxStatus  Pointer to the mailbox status returned from
> pcode. Possible mailbox status values are:
> +                              - SUCCESS (0)               Command succeeded.
> +                              - OC_LOCKED (1)             Overclocking is locked.
> Service is read-only.
> +                              - INVALID_DOMAIN (2)        Invalid Domain ID provided
> in command data.
> +                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum
> overclocking limits.
> +                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input
> VR's max voltage.
> +                              - OC_NOT_SUPPORTED (5)      Domain does not
> support overclocking.
> +
> +  @retval EFI_STATUS
> +          - EFI_SUCCESS           Command succeeded.
> +          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
> +          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxWrite (
> +  IN UINT32  MailboxType,
> +  IN UINT32  MailboxCommand,
> +  IN UINT32  MailboxData,
> +  OUT UINT32 *MailboxStatus
> +  );
> +
> +/**
> +  Generic Mailbox function for mailbox read commands. This function will
> write
> +  the read request from MailboxType, and populate the read results in the
> MailboxDataPtr.
> +
> +  @param[in]  MailboxType     The type of mailbox interface to read. The
> Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
> +  @param[in]  MailboxCommand  Overclocking mailbox command data
> +  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox
> interface data
> +  @param[out] *MailboxStatus  Pointer to the mailbox status returned from
> pcode. Possible mailbox status are
> +                              - SUCCESS (0)               Command succeeded.
> +                              - OC_LOCKED (1)             Overclocking is locked.
> Service is read-only.
> +                              - INVALID_DOMAIN (2)        Invalid Domain ID provided
> in command data.
> +                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum
> overclocking limits.
> +                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input
> VR's max voltage.
> +                              - OC_NOT_SUPPORTED (5)      Domain does not
> support overclocking.
> +
> +  @retval EFI_STATUS
> +          - EFI_SUCCESS           Command succeeded.
> +          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
> +          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxRead (
> +  IN UINT32  MailboxType,
> +  IN UINT32  MailboxCommand,
> +  OUT UINT32 *MailboxDataPtr,
> +  OUT UINT32 *MailboxStatus
> +  );
> +
> +/**
> +  Poll the run/busy bit of the mailbox until available or timeout expires.
> +
> +  @param[in]  MailboxType
> +
> +  @retval EFI_STATUS
> +          - EFI_SUCCESS           Command succeeded.
> +          - EFI_TIMEOUT           Command timeout.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PollMailboxReady (
> +  IN UINT32 MailboxType
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
> new file mode 100644
> index 0000000000..a2dc83efb5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
> @@ -0,0 +1,118 @@
> +/** @file
> +  Header file for CpuPlatform Lib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_PLATFORM_LIB_H_
> +#define _CPU_PLATFORM_LIB_H_
> +
> +#include <CpuRegs.h>
> +#include <CpuDataStruct.h>
> +#include <CpuPowerMgmt.h>
> +
> +/**
> +  Check CPU Type of the platform
> +
> +  @retval CPU_FAMILY              CPU type
> +**/
> +CPU_FAMILY
> +EFIAPI
> +GetCpuFamily (
> +  VOID
> +  );
> +
> +/**
> +  Return Cpu stepping type
> +
> +  @retval CPU_STEPPING                   Cpu stepping type
> +**/
> +CPU_STEPPING
> +EFIAPI
> +GetCpuStepping (
> +  VOID
> +  );
> +
> +/**
> +  Return CPU Sku
> +
> +  @retval UINT8              CPU Sku
> +**/
> +UINT8
> +EFIAPI
> +GetCpuSku (
> +  VOID
> +  );
> +
> +/**
> +  Returns the processor microcode revision of the processor installed in the
> system.
> +
> +  @retval Processor Microcode Revision
> +**/
> +UINT32
> +GetCpuUcodeRevision (
> +  VOID
> +  );
> +
> +/**
> +  Check if this microcode is correct one for processor
> +
> +  @param[in] Cpuid               - processor CPUID
> +  @param[in] MicrocodeEntryPoint - entry point of microcode
> +  @param[in] Revision            - revision of microcode
> +
> +  @retval CorrectMicrocode if this microcode is correct
> +**/
> +BOOLEAN
> +CheckMicrocode (
> +  IN UINT32               Cpuid,
> +  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
> +  IN UINT32               *Revision
> +  );
> +
> +/**
> +  Check on the processor if SGX is supported.
> +
> +  @retval True if SGX supported or FALSE if not
> +**/
> +BOOLEAN
> +IsSgxSupported (
> +  VOID
> +  );
> +
> +/**
> +  Get processor generation
> +
> +  @retval CPU_GENERATION  Returns the executing thread's processor
> generation.
> +**/
> +CPU_GENERATION
> +GetCpuGeneration (
> +  VOID
> +  );
> +
> +/**
> +  Check if Disable CPU Debug (DCD) bit is set from FIT CPU Debugging
> [Disabled].
> +  If it is set, CPU probe mode is disabled.
> +
> +  @retval TRUE    DCD is set
> +  @retval FALSE   DCD is clear
> +**/
> +BOOLEAN
> +IsCpuDebugDisabled (
> +  VOID
> +  );
> +
> +/**
> +  Is Whiskey Lake CPU.
> +
> +  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
> +  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
> +**/
> +BOOLEAN
> +IsWhlCpu (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
> new file mode 100644
> index 0000000000..88f4353e91
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
> @@ -0,0 +1,84 @@
> +/** @file
> +  Prototype of the CpuPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_POLICY_LIB_H_
> +#define _CPU_POLICY_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Print whole CPU related config blocks of SI_PREMEM_POLICY_PPI and serial
> out.
> +
> +  @param[in] SiPreMemPolicyPpi             The Si PreMem Policy PPI instance
> +**/
> +VOID
> +CpuPreMemPrintPolicy (
> +IN  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
> +);
> +
> +/**
> +  Get CPU PREMEM config block table total size.
> +
> +  @retval Size of CPU PREMEM config block table
> +**/
> +UINT16
> +EFIAPI
> +CpuGetPreMemConfigBlockTotalSize (
> +  VOID
> +  );
> +
> +/**
> +  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM
> config blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuAddPreMemConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  );
> +
> +/**
> +  Print whole CPU config blocks of SiPolicyPpi and serial out.
> +
> +  @param[in] SiPolicyPpi             The SI Policy PPI instance
> +**/
> +VOID
> +CpuPrintPolicy (
> +  IN  SI_POLICY_PPI                 *SiPolicyPpi
> +  );
> +
> +/**
> +  Get CPU config block table total size.
> +
> +  @retval Size of CPU config block table
> +**/
> +UINT16
> +EFIAPI
> +CpuGetConfigBlockTotalSize (
> +  VOID
> +  );
> +
> +/**
> +  CpuAddConfigBlocks add all Cpu config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add CPU config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuAddConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  );
> +
> +#endif // _PEI_CPU_POLICY_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
> new file mode 100644
> index 0000000000..67f88ce987
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
> @@ -0,0 +1,123 @@
> +/** @file
> +  Protocol used to report CPU information
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_INFO_H_
> +#define _CPU_INFO_H_
> +
> +#include <CpuDataStruct.h>
> +
> +typedef struct _CPU_INFO_PROTOCOL CPU_INFO_PROTOCOL;
> +
> +
> +extern EFI_GUID gCpuInfoProtocolGuid;
> +
> +//
> +// DXE_CPU_INFO_PROTOCOL revisions
> +//
> +#define CPU_INFO_PROTOCOL_REVISION 1
> +
> +//
> +// Processor feature definitions.
> +//
> +#define TXT_SUPPORT        BIT0
> +#define VMX_SUPPORT        BIT1
> +#define XD_SUPPORT         BIT2
> +#define DCA_SUPPORT        BIT3
> +#define X2APIC_SUPPORT     BIT4
> +#define AES_SUPPORT        BIT5
> +#define HT_SUPPORT         BIT6
> +#define DEBUG_SUPPORT      BIT7
> +#define DEBUG_LOCK_SUPPORT BIT8
> +#define PROC_TRACE_SUPPORT BIT9
> +#define HDC_SUPPORT        BIT10
> +
> +
> +#pragma pack(1)
> +///
> +/// Cache descriptor information
> +///
> +typedef struct {
> +  UINT8   Desc;                                    ///< Cache Descriptor
> +  UINT8   Level;                                   ///< Cache Level
> +  UINT8   Type;                                    ///< Cache Type. 0: Data, 1:
> Instruction, 3: Unified
> +  UINT32  Size;                                    ///< Cache Size.
> +  UINT16  Associativity;                           ///< Cache Ways of Associativity.
> +} CACHE_DESCRIPTOR_INFO;
> +
> +///
> +/// Processor information
> +///
> +typedef struct {
> +  UINT32                CpuSignature;               ///< Processor signature and
> version information.
> +  UINT64                Features;                   ///< Features availability in the
> CPU based on reading ECX after doing Asmcpuid(EAX=1).
> +  CHAR8                 *BrandString;               ///< Processor Brand String.
> +  UINT8                 NumSupportedCores;          ///< Total Number of
> Supported Cores in CPU Package. If Dual core, 2 cores.
> +  UINT8                 NumSupportedThreadsPerCore; ///< Number of
> Supported Threads per Core.
> +  UINT8                 NumCores;                   ///< Number of Enabled or
> Active Cores.
> +  UINT8                 NumHts;                     ///< Number of Enabled Threads
> per Core. This will be 1 or 2.
> +  UINT32                IntendedFreq;               ///< Maximum non turbo ratio
> in MHz
> +  UINT32                ActualFreq;                 ///< Actual frequency in MHz
> +  UINT32                Voltage;                    ///< Current operating voltage.
> +  CACHE_DESCRIPTOR_INFO *CacheInfo;                 ///< Cache descriptor
> information.
> +  UINT8                 MaxCacheSupported;          ///< Maximum cache
> supported.
> +  UINT8                 SmmbaseSwSmiNumber;         ///< Software SMI
> Number from Smbase. @Note: This is unused.
> +  UINT16                NumberOfPStates;            ///< Number of P-States.
> +} CPU_INFO;
> +
> +///
> +/// This HOB is data structure representing two different address location in
> SMRAM to hold SMRAM CPU DATA.
> +///
> +typedef struct {
> +  EFI_PHYSICAL_ADDRESS LockBoxData;  ///< First location (address) of
> SMRAM CPU DATA.
> +  EFI_PHYSICAL_ADDRESS SmramCpuData; ///< Second location (Address) of
> SMRAM CPU DATA.
> +  UINT64               LockBoxSize;  ///< Size of SMRAM CPU DATA.
> +} SMRAM_CPU_INFO;
> +
> +///
> +/// SGX Information
> +///
> +typedef struct {
> +  UINT64  SgxSinitNvsData;  ///< Sinit SE SVN Version saved and passed back
> in next boot
> +} SGX_INFO;
> +
> +#pragma pack()
> +
> +///
> +/// This protocol provides information about the common features available
> in this CPU.
> +///
> +struct _CPU_INFO_PROTOCOL {
> +  /**
> +  Revision for the protocol structure.
> +  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>:
> +   -  Initial version
> +  **/
> +  UINT8  Revision;
> +  /**
> +  CPU Supported Feature.
> +   - BIT0:  If set then processor supports TXT.
> +   - BIT1:  If set then processor supports virtual mode extensions.
> +   - BIT2:  If set then processor supports execute disable bit.
> +   - BIT3:  If set then processor supports DCA.
> +   - BIT4:  If set then processor supports X2APIC.
> +   - BIT5:  If set then processor supports Advanced Encryption Standard.
> +   - BIT6:  If set then processor supports hyperthreading.
> +   - BIT7:  If set then processor supports debug interface.
> +   - BIT8:  If set then processor supports debug interface lock.
> +   - BIT9:  If set then processor supports processor trace.
> +   - BIT10: If Set then processor supports supports HDC.
> +  **/
> +  UINT64         CpuCommonFeatures;
> +  CPU_INFO       *CpuInfo;      ///< Processor Basic Information
> +  SMRAM_CPU_INFO *SmramCpuInfo; ///< SMRAM CPU Information
> +  SGX_INFO       *SgxInfo;      ///< SGX Information
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtoco
> l.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtoco
> l.h
> new file mode 100644
> index 0000000000..ed056025b7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtoco
> l.h
> @@ -0,0 +1,50 @@
> +/** @file
> +  Protocol used for specifying platform related CPU information and policy
> setting.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_POLICY_PROTOCOL_H_
> +#define _CPU_POLICY_PROTOCOL_H_
> +
> +//
> +// DXE_CPU_POLICY_PROTOCOL revisions
> +//
> +#define DXE_CPU_POLICY_PROTOCOL_REVISION 1
> +
> +extern EFI_GUID gDxeCpuPolicyProtocolGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  The protocol allows the platform code to publish a set of configuration
> information that the
> +  CPU drivers will use to configure the processor in the DXE phase.
> +  This Policy Protocol needs to be initialized for CPU configuration.
> +  @note The Protocol has to be published before processor DXE drivers are
> dispatched.
> +**/
> +typedef struct {
> +  /**
> +  This member specifies the revision of the Cpu Policy protocol. This field is
> used to indicate backward
> +  compatible changes to the protocol. Any such changes to this protocol will
> result in an update in the revision number.
> +
> +  <b>Revision 1</b>:
> +   - Initial version
> +  **/
> +  /**
> +  Policies to obtain CPU temperature.
> +   - <b>0: ACPI thermal management uses EC reported temperature
> values</b>.
> +   - 1: ACPI thermal management uses DTS SMM mechanism to obtain CPU
> temperature values.
> +   - 2: ACPI Thermal Management uses EC reported temperature values and
> DTS SMM is used to handle Out of Spec condition.
> +  **/
> +  UINT32                         EnableDts           : 2;
> +  UINT32                         RsvdBit             : 30;  ///< Reserved bits, align to
> multiple 32;
> +
> +  UINT8                          Revision;                  ///< Current revision of
> policy.
> +  UINT8                          ReservedByte[3];           ///< Reserved bytes,
> align to multiple 8.
> +} DXE_CPU_POLICY_PROTOCOL;
> +
> +#pragma pack (pop)
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:08   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:08 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add
> include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds Pch/Include headers.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h               |
> 135 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h               | 326
> +++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h             |
> 381 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h            |
> 340 +++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h             |
> 241 +++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h            |
> 200 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h                |  54
> +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h                   |  38
> ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h               |
> 80 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h                |  53
> +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
> |  47 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h          |
> 47 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
> |  59 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
> |  53 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h |
> 23 ++
>  15 files changed, 2077 insertions(+)
> 
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
> new file mode 100644
> index 0000000000..91222fd54d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
> @@ -0,0 +1,135 @@
> +/** @file
> +  Header file for DxePchHdaNhltLib - NHLT structure definitions.
> +
> +  Copyright (c) 2019 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
> +#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_DEVICE_TYPE
> +{
> +  HdaNhltDeviceBt   = 0,
> +  HdaNhltDeviceDmic = 1,
> +  HdaNhltDeviceI2s  = 4,
> +  HdaNhltDeviceInvalid
> +};
> +
> +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_HDA_NHLT_H_
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
> new file mode 100644
> index 0000000000..babbf1ce3a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
> @@ -0,0 +1,326 @@
> +/** @file
> +  Header file for GpioConfig structure used by GPIO library.
> +
> +  Copyright (c) 2019 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;
> +
> +
> +///
> +/// 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 {
> +  GpioPadModeGpio     = 0x1,
> +  GpioPadModeNative1  = 0x3,
> +  GpioPadModeNative2  = 0x5,
> +  GpioPadModeNative3  = 0x7,
> +  GpioPadModeNative4  = 0x9,
> +  GpioPadModeNative5  = 0xB
> +} 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
> +} 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/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
> new file mode 100644
> index 0000000000..524328d3e3
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
> @@ -0,0 +1,381 @@
> +/** @file
> +  GPIO pins,
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_PINS_CNL_H_H_
> +#define _GPIO_PINS_CNL_H_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_CNL_H_CHIPSET_ID       0x3
> +
> +///
> +/// Use below for functions from PCH GPIO Lib which
> +/// require GpioGroup as argument
> +///
> +#define GPIO_CNL_H_GROUP_GPP_A  0x0300
> +#define GPIO_CNL_H_GROUP_GPP_B  0x0301
> +#define GPIO_CNL_H_GROUP_GPP_C  0x0302
> +#define GPIO_CNL_H_GROUP_GPP_D  0x0303
> +#define GPIO_CNL_H_GROUP_GPP_E  0x0304
> +#define GPIO_CNL_H_GROUP_GPP_F  0x0305
> +#define GPIO_CNL_H_GROUP_GPP_G  0x0306
> +#define GPIO_CNL_H_GROUP_GPP_H  0x0307
> +#define GPIO_CNL_H_GROUP_GPP_I  0x0308
> +#define GPIO_CNL_H_GROUP_GPP_J  0x0309
> +#define GPIO_CNL_H_GROUP_GPP_K  0x030A
> +#define GPIO_CNL_H_GROUP_GPD    0x030B
> +#define GPIO_CNL_H_GROUP_VGPIO  0x030C
> +#define GPIO_CNL_H_GROUP_SPI    0x030D
> +#define GPIO_CNL_H_GROUP_AZA    0x030E
> +#define GPIO_CNL_H_GROUP_CPU    0x030F
> +#define GPIO_CNL_H_GROUP_JTAG   0x0310
> +
> +///
> +/// 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_CNL_H_GPP_A0               0x03000000
> +#define GPIO_CNL_H_GPP_A1               0x03000001
> +#define GPIO_CNL_H_GPP_A2               0x03000002
> +#define GPIO_CNL_H_GPP_A3               0x03000003
> +#define GPIO_CNL_H_GPP_A4               0x03000004
> +#define GPIO_CNL_H_GPP_A5               0x03000005
> +#define GPIO_CNL_H_GPP_A6               0x03000006
> +#define GPIO_CNL_H_GPP_A7               0x03000007
> +#define GPIO_CNL_H_GPP_A8               0x03000008
> +#define GPIO_CNL_H_GPP_A9               0x03000009
> +#define GPIO_CNL_H_GPP_A10              0x0300000A
> +#define GPIO_CNL_H_GPP_A11              0x0300000B
> +#define GPIO_CNL_H_GPP_A12              0x0300000C
> +#define GPIO_CNL_H_GPP_A13              0x0300000D
> +#define GPIO_CNL_H_GPP_A14              0x0300000E
> +#define GPIO_CNL_H_GPP_A15              0x0300000F
> +#define GPIO_CNL_H_GPP_A16              0x03000010
> +#define GPIO_CNL_H_GPP_A17              0x03000011
> +#define GPIO_CNL_H_GPP_A18              0x03000012
> +#define GPIO_CNL_H_GPP_A19              0x03000013
> +#define GPIO_CNL_H_GPP_A20              0x03000014
> +#define GPIO_CNL_H_GPP_A21              0x03000015
> +#define GPIO_CNL_H_GPP_A22              0x03000016
> +#define GPIO_CNL_H_GPP_A23              0x03000017
> +#define GPIO_CNL_H_ESPI_CLK_LOOPBK      0x03000018
> +
> +#define GPIO_CNL_H_GPP_B0               0x03010000
> +#define GPIO_CNL_H_GPP_B1               0x03010001
> +#define GPIO_CNL_H_GPP_B2               0x03010002
> +#define GPIO_CNL_H_GPP_B3               0x03010003
> +#define GPIO_CNL_H_GPP_B4               0x03010004
> +#define GPIO_CNL_H_GPP_B5               0x03010005
> +#define GPIO_CNL_H_GPP_B6               0x03010006
> +#define GPIO_CNL_H_GPP_B7               0x03010007
> +#define GPIO_CNL_H_GPP_B8               0x03010008
> +#define GPIO_CNL_H_GPP_B9               0x03010009
> +#define GPIO_CNL_H_GPP_B10              0x0301000A
> +#define GPIO_CNL_H_GPP_B11              0x0301000B
> +#define GPIO_CNL_H_GPP_B12              0x0301000C
> +#define GPIO_CNL_H_GPP_B13              0x0301000D
> +#define GPIO_CNL_H_GPP_B14              0x0301000E
> +#define GPIO_CNL_H_GPP_B15              0x0301000F
> +#define GPIO_CNL_H_GPP_B16              0x03010010
> +#define GPIO_CNL_H_GPP_B17              0x03010011
> +#define GPIO_CNL_H_GPP_B18              0x03010012
> +#define GPIO_CNL_H_GPP_B19              0x03010013
> +#define GPIO_CNL_H_GPP_B20              0x03010014
> +#define GPIO_CNL_H_GPP_B21              0x03010015
> +#define GPIO_CNL_H_GPP_B22              0x03010016
> +#define GPIO_CNL_H_GPP_B23              0x03010017
> +#define GPIO_CNL_H_GSPI0_CLK_LOOPBK     0x03010018
> +#define GPIO_CNL_H_GSPI1_CLK_LOOPBK     0x03010019
> +
> +#define GPIO_CNL_H_GPP_C0               0x03020000
> +#define GPIO_CNL_H_GPP_C1               0x03020001
> +#define GPIO_CNL_H_GPP_C2               0x03020002
> +#define GPIO_CNL_H_GPP_C3               0x03020003
> +#define GPIO_CNL_H_GPP_C4               0x03020004
> +#define GPIO_CNL_H_GPP_C5               0x03020005
> +#define GPIO_CNL_H_GPP_C6               0x03020006
> +#define GPIO_CNL_H_GPP_C7               0x03020007
> +#define GPIO_CNL_H_GPP_C8               0x03020008
> +#define GPIO_CNL_H_GPP_C9               0x03020009
> +#define GPIO_CNL_H_GPP_C10              0x0302000A
> +#define GPIO_CNL_H_GPP_C11              0x0302000B
> +#define GPIO_CNL_H_GPP_C12              0x0302000C
> +#define GPIO_CNL_H_GPP_C13              0x0302000D
> +#define GPIO_CNL_H_GPP_C14              0x0302000E
> +#define GPIO_CNL_H_GPP_C15              0x0302000F
> +#define GPIO_CNL_H_GPP_C16              0x03020010
> +#define GPIO_CNL_H_GPP_C17              0x03020011
> +#define GPIO_CNL_H_GPP_C18              0x03020012
> +#define GPIO_CNL_H_GPP_C19              0x03020013
> +#define GPIO_CNL_H_GPP_C20              0x03020014
> +#define GPIO_CNL_H_GPP_C21              0x03020015
> +#define GPIO_CNL_H_GPP_C22              0x03020016
> +#define GPIO_CNL_H_GPP_C23              0x03020017
> +
> +#define GPIO_CNL_H_GPP_D0               0x03030000
> +#define GPIO_CNL_H_GPP_D1               0x03030001
> +#define GPIO_CNL_H_GPP_D2               0x03030002
> +#define GPIO_CNL_H_GPP_D3               0x03030003
> +#define GPIO_CNL_H_GPP_D4               0x03030004
> +#define GPIO_CNL_H_GPP_D5               0x03030005
> +#define GPIO_CNL_H_GPP_D6               0x03030006
> +#define GPIO_CNL_H_GPP_D7               0x03030007
> +#define GPIO_CNL_H_GPP_D8               0x03030008
> +#define GPIO_CNL_H_GPP_D9               0x03030009
> +#define GPIO_CNL_H_GPP_D10              0x0303000A
> +#define GPIO_CNL_H_GPP_D11              0x0303000B
> +#define GPIO_CNL_H_GPP_D12              0x0303000C
> +#define GPIO_CNL_H_GPP_D13              0x0303000D
> +#define GPIO_CNL_H_GPP_D14              0x0303000E
> +#define GPIO_CNL_H_GPP_D15              0x0303000F
> +#define GPIO_CNL_H_GPP_D16              0x03030010
> +#define GPIO_CNL_H_GPP_D17              0x03030011
> +#define GPIO_CNL_H_GPP_D18              0x03030012
> +#define GPIO_CNL_H_GPP_D19              0x03030013
> +#define GPIO_CNL_H_GPP_D20              0x03030014
> +#define GPIO_CNL_H_GPP_D21              0x03030015
> +#define GPIO_CNL_H_GPP_D22              0x03030016
> +#define GPIO_CNL_H_GPP_D23              0x03030017
> +
> +#define GPIO_CNL_H_GPP_E0               0x03040000
> +#define GPIO_CNL_H_GPP_E1               0x03040001
> +#define GPIO_CNL_H_GPP_E2               0x03040002
> +#define GPIO_CNL_H_GPP_E3               0x03040003
> +#define GPIO_CNL_H_GPP_E4               0x03040004
> +#define GPIO_CNL_H_GPP_E5               0x03040005
> +#define GPIO_CNL_H_GPP_E6               0x03040006
> +#define GPIO_CNL_H_GPP_E7               0x03040007
> +#define GPIO_CNL_H_GPP_E8               0x03040008
> +#define GPIO_CNL_H_GPP_E9               0x03040009
> +#define GPIO_CNL_H_GPP_E10              0x0304000A
> +#define GPIO_CNL_H_GPP_E11              0x0304000B
> +#define GPIO_CNL_H_GPP_E12              0x0304000C
> +
> +#define GPIO_CNL_H_GPP_F0               0x03050000
> +#define GPIO_CNL_H_GPP_F1               0x03050001
> +#define GPIO_CNL_H_GPP_F2               0x03050002
> +#define GPIO_CNL_H_GPP_F3               0x03050003
> +#define GPIO_CNL_H_GPP_F4               0x03050004
> +#define GPIO_CNL_H_GPP_F5               0x03050005
> +#define GPIO_CNL_H_GPP_F6               0x03050006
> +#define GPIO_CNL_H_GPP_F7               0x03050007
> +#define GPIO_CNL_H_GPP_F8               0x03050008
> +#define GPIO_CNL_H_GPP_F9               0x03050009
> +#define GPIO_CNL_H_GPP_F10              0x0305000A
> +#define GPIO_CNL_H_GPP_F11              0x0305000B
> +#define GPIO_CNL_H_GPP_F12              0x0305000C
> +#define GPIO_CNL_H_GPP_F13              0x0305000D
> +#define GPIO_CNL_H_GPP_F14              0x0305000E
> +#define GPIO_CNL_H_GPP_F15              0x0305000F
> +#define GPIO_CNL_H_GPP_F16              0x03050010
> +#define GPIO_CNL_H_GPP_F17              0x03050011
> +#define GPIO_CNL_H_GPP_F18              0x03050012
> +#define GPIO_CNL_H_GPP_F19              0x03050013
> +#define GPIO_CNL_H_GPP_F20              0x03050014
> +#define GPIO_CNL_H_GPP_F21              0x03050015
> +#define GPIO_CNL_H_GPP_F22              0x03050016
> +#define GPIO_CNL_H_GPP_F23              0x03050017
> +
> +#define GPIO_CNL_H_GPP_G0               0x03060000
> +#define GPIO_CNL_H_GPP_G1               0x03060001
> +#define GPIO_CNL_H_GPP_G2               0x03060002
> +#define GPIO_CNL_H_GPP_G3               0x03060003
> +#define GPIO_CNL_H_GPP_G4               0x03060004
> +#define GPIO_CNL_H_GPP_G5               0x03060005
> +#define GPIO_CNL_H_GPP_G6               0x03060006
> +#define GPIO_CNL_H_GPP_G7               0x03060007
> +
> +#define GPIO_CNL_H_GPP_H0               0x03070000
> +#define GPIO_CNL_H_GPP_H1               0x03070001
> +#define GPIO_CNL_H_GPP_H2               0x03070002
> +#define GPIO_CNL_H_GPP_H3               0x03070003
> +#define GPIO_CNL_H_GPP_H4               0x03070004
> +#define GPIO_CNL_H_GPP_H5               0x03070005
> +#define GPIO_CNL_H_GPP_H6               0x03070006
> +#define GPIO_CNL_H_GPP_H7               0x03070007
> +#define GPIO_CNL_H_GPP_H8               0x03070008
> +#define GPIO_CNL_H_GPP_H9               0x03070009
> +#define GPIO_CNL_H_GPP_H10              0x0307000A
> +#define GPIO_CNL_H_GPP_H11              0x0307000B
> +#define GPIO_CNL_H_GPP_H12              0x0307000C
> +#define GPIO_CNL_H_GPP_H13              0x0307000D
> +#define GPIO_CNL_H_GPP_H14              0x0307000E
> +#define GPIO_CNL_H_GPP_H15              0x0307000F
> +#define GPIO_CNL_H_GPP_H16              0x03070010
> +#define GPIO_CNL_H_GPP_H17              0x03070011
> +#define GPIO_CNL_H_GPP_H18              0x03070012
> +#define GPIO_CNL_H_GPP_H19              0x03070013
> +#define GPIO_CNL_H_GPP_H20              0x03070014
> +#define GPIO_CNL_H_GPP_H21              0x03070015
> +#define GPIO_CNL_H_GPP_H22              0x03070016
> +#define GPIO_CNL_H_GPP_H23              0x03070017
> +
> +#define GPIO_CNL_H_GPP_I0               0x03080000
> +#define GPIO_CNL_H_GPP_I1               0x03080001
> +#define GPIO_CNL_H_GPP_I2               0x03080002
> +#define GPIO_CNL_H_GPP_I3               0x03080003
> +#define GPIO_CNL_H_GPP_I4               0x03080004
> +#define GPIO_CNL_H_GPP_I5               0x03080005
> +#define GPIO_CNL_H_GPP_I6               0x03080006
> +#define GPIO_CNL_H_GPP_I7               0x03080007
> +#define GPIO_CNL_H_GPP_I8               0x03080008
> +#define GPIO_CNL_H_GPP_I9               0x03080009
> +#define GPIO_CNL_H_GPP_I10              0x0308000A
> +#define GPIO_CNL_H_GPP_I11              0x0308000B
> +#define GPIO_CNL_H_GPP_I12              0x0308000C
> +#define GPIO_CNL_H_GPP_I13              0x0308000D
> +#define GPIO_CNL_H_GPP_I14              0x0308000E
> +#define GPIO_CNL_H_SYS_PWROK            0x0308000F
> +#define GPIO_CNL_H_SYS_RESETB           0x03080010
> +#define GPIO_CNL_H_MLK_RSTB             0x03080011
> +
> +#define GPIO_CNL_H_GPP_J0               0x03090000
> +#define GPIO_CNL_H_GPP_J1               0x03090001
> +#define GPIO_CNL_H_GPP_J2               0x03090002
> +#define GPIO_CNL_H_GPP_J3               0x03090003
> +#define GPIO_CNL_H_GPP_J4               0x03090004
> +#define GPIO_CNL_H_GPP_J5               0x03090005
> +#define GPIO_CNL_H_GPP_J6               0x03090006
> +#define GPIO_CNL_H_GPP_J7               0x03090007
> +#define GPIO_CNL_H_GPP_J8               0x03090008
> +#define GPIO_CNL_H_GPP_J9               0x03090009
> +#define GPIO_CNL_H_GPP_J10              0x0309000A
> +#define GPIO_CNL_H_GPP_J11              0x0309000B
> +
> +#define GPIO_CNL_H_GPP_K0               0x030A0000
> +#define GPIO_CNL_H_GPP_K1               0x030A0001
> +#define GPIO_CNL_H_GPP_K2               0x030A0002
> +#define GPIO_CNL_H_GPP_K3               0x030A0003
> +#define GPIO_CNL_H_GPP_K4               0x030A0004
> +#define GPIO_CNL_H_GPP_K5               0x030A0005
> +#define GPIO_CNL_H_GPP_K6               0x030A0006
> +#define GPIO_CNL_H_GPP_K7               0x030A0007
> +#define GPIO_CNL_H_GPP_K8               0x030A0008
> +#define GPIO_CNL_H_GPP_K9               0x030A0009
> +#define GPIO_CNL_H_GPP_K10              0x030A000A
> +#define GPIO_CNL_H_GPP_K11              0x030A000B
> +#define GPIO_CNL_H_GPP_K12              0x030A000C
> +#define GPIO_CNL_H_GPP_K13              0x030A000D
> +#define GPIO_CNL_H_GPP_K14              0x030A000E
> +#define GPIO_CNL_H_GPP_K15              0x030A000F
> +#define GPIO_CNL_H_GPP_K16              0x030A0010
> +#define GPIO_CNL_H_GPP_K17              0x030A0011
> +#define GPIO_CNL_H_GPP_K18              0x030A0012
> +#define GPIO_CNL_H_GPP_K19              0x030A0013
> +#define GPIO_CNL_H_GPP_K20              0x030A0014
> +#define GPIO_CNL_H_GPP_K21              0x030A0015
> +#define GPIO_CNL_H_GPP_K22              0x030A0016
> +#define GPIO_CNL_H_GPP_K23              0x030A0017
> +
> +#define GPIO_CNL_H_GPD0                 0x030B0000
> +#define GPIO_CNL_H_GPD1                 0x030B0001
> +#define GPIO_CNL_H_GPD2                 0x030B0002
> +#define GPIO_CNL_H_GPD3                 0x030B0003
> +#define GPIO_CNL_H_GPD4                 0x030B0004
> +#define GPIO_CNL_H_GPD5                 0x030B0005
> +#define GPIO_CNL_H_GPD6                 0x030B0006
> +#define GPIO_CNL_H_GPD7                 0x030B0007
> +#define GPIO_CNL_H_GPD8                 0x030B0008
> +#define GPIO_CNL_H_GPD9                 0x030B0009
> +#define GPIO_CNL_H_GPD10                0x030B000A
> +#define GPIO_CNL_H_GPD11                0x030B000B
> +#define GPIO_CNL_H_SLP_LANB             0x030B000C
> +#define GPIO_CNL_H_SLP_SUSB             0x030B000D
> +#define GPIO_CNL_H_SLP_WAKEB            0x030B000E
> +#define GPIO_CNL_H_SLP_DRAM_RESETB      0x030B000F
> +
> +#define GPIO_CNL_H_VGPIO0               0x030C0000
> +#define GPIO_CNL_H_VGPIO1               0x030C0001
> +#define GPIO_CNL_H_VGPIO2               0x030C0002
> +#define GPIO_CNL_H_VGPIO3               0x030C0003
> +#define GPIO_CNL_H_VGPIO4               0x030C0004
> +#define GPIO_CNL_H_VGPIO5               0x030C0005
> +#define GPIO_CNL_H_VGPIO6               0x030C0006
> +#define GPIO_CNL_H_VGPIO7               0x030C0007
> +#define GPIO_CNL_H_VGPIO8               0x030C0008
> +#define GPIO_CNL_H_VGPIO9               0x030C0009
> +#define GPIO_CNL_H_VGPIO10              0x030C000A
> +#define GPIO_CNL_H_VGPIO11              0x030C000B
> +#define GPIO_CNL_H_VGPIO12              0x030C000C
> +#define GPIO_CNL_H_VGPIO13              0x030C000D
> +#define GPIO_CNL_H_VGPIO14              0x030C000E
> +#define GPIO_CNL_H_VGPIO15              0x030C000F
> +#define GPIO_CNL_H_VGPIO16              0x030C0010
> +#define GPIO_CNL_H_VGPIO17              0x030C0011
> +#define GPIO_CNL_H_VGPIO18              0x030C0012
> +#define GPIO_CNL_H_VGPIO19              0x030C0013
> +#define GPIO_CNL_H_VGPIO20              0x030C0014
> +#define GPIO_CNL_H_VGPIO21              0x030C0015
> +#define GPIO_CNL_H_VGPIO22              0x030C0016
> +#define GPIO_CNL_H_VGPIO23              0x030C0017
> +#define GPIO_CNL_H_VGPIO24              0x030C0018
> +#define GPIO_CNL_H_VGPIO25              0x030C0019
> +#define GPIO_CNL_H_VGPIO26              0x030C001A
> +#define GPIO_CNL_H_VGPIO27              0x030C001B
> +#define GPIO_CNL_H_VGPIO28              0x030C001C
> +#define GPIO_CNL_H_VGPIO29              0x030C001D
> +#define GPIO_CNL_H_VGPIO30              0x030C001E
> +#define GPIO_CNL_H_VGPIO31              0x030C001F
> +#define GPIO_CNL_H_VGPIO32              0x030C0020
> +#define GPIO_CNL_H_VGPIO33              0x030C0021
> +#define GPIO_CNL_H_VGPIO34              0x030C0022
> +#define GPIO_CNL_H_VGPIO35              0x030C0023
> +#define GPIO_CNL_H_VGPIO36              0x030C0024
> +#define GPIO_CNL_H_VGPIO37              0x030C0025
> +#define GPIO_CNL_H_VGPIO38              0x030C0026
> +#define GPIO_CNL_H_VGPIO39              0x030C0027
> +
> +#define GPIO_CNL_H_SPI0_IO_2            0x030D0000
> +#define GPIO_CNL_H_SPI0_IO_3            0x030D0001
> +#define GPIO_CNL_H_SPI0_MOSI_IO_0       0x030D0002
> +#define GPIO_CNL_H_SPI0_MOSI_IO_1       0x030D0003
> +#define GPIO_CNL_H_SPI0_TPM_CSB         0x030D0004
> +#define GPIO_CNL_H_SPI0_FLASH_0_CSB     0x030D0005
> +#define GPIO_CNL_H_SPI0_FLASH_1_CSB     0x030D0006
> +#define GPIO_CNL_H_SPI0_CLK             0x030D0007
> +#define GPIO_CNL_H_SPI0_CLK_LOOPBK      0x030D0008
> +
> +#define GPIO_CNL_H_HDA_BCLK             0x030E0000
> +#define GPIO_CNL_H_HDA_RSTB             0x030E0001
> +#define GPIO_CNL_H_HDA_SYNC             0x030E0002
> +#define GPIO_CNL_H_HDA_SDO              0x030E0003
> +#define GPIO_CNL_H_HDA_SDI_0            0x030E0004
> +#define GPIO_CNL_H_HDA_SDI_1            0x030E0005
> +#define GPIO_CNL_H_SSP1_SFRM            0x030E0006
> +#define GPIO_CNL_H_SSP1_TXD             0x030E0007
> +
> +#define GPIO_CNL_H_HDACPU_SDI           0x030F0000
> +#define GPIO_CNL_H_HDACPU_SDO           0x030F0001
> +#define GPIO_CNL_H_HDACPU_SCLK          0x030F0002
> +#define GPIO_CNL_H_PM_SYNC              0x030F0003
> +#define GPIO_CNL_H_PECI                 0x030F0004
> +#define GPIO_CNL_H_CPUPWRGD             0x030F0005
> +#define GPIO_CNL_H_THRMTRIPB            0x030F0006
> +#define GPIO_CNL_H_PLTRST_CPUB          0x030F0007
> +#define GPIO_CNL_H_PM_DOWN              0x030F0008
> +#define GPIO_CNL_H_TRIGGER_IN           0x030F0009
> +#define GPIO_CNL_H_TRIGGER_OUT          0x030F000A
> +
> +#define GPIO_CNL_H_JTAG_TDO             0x03100000
> +#define GPIO_CNL_H_JTAGX                0x03100001
> +#define GPIO_CNL_H_PRDYB                0x03100002
> +#define GPIO_CNL_H_PREQB                0x03100003
> +#define GPIO_CNL_H_CPU_TRSTB            0x03100004
> +#define GPIO_CNL_H_JTAG_TDI             0x03100005
> +#define GPIO_CNL_H_JTAG_TMS             0x03100006
> +#define GPIO_CNL_H_JTAG_TCK             0x03100007
> +#define GPIO_CNL_H_ITP_PMODE            0x03100008
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
> new file mode 100644
> index 0000000000..9ce5875ca5
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
> @@ -0,0 +1,340 @@
> +/** @file
> +  GPIO pins,
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_PINS_CNL_LP_H_
> +#define _GPIO_PINS_CNL_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_CNL_LP_CHIPSET_ID      0x4
> +
> +///
> +/// Use below for functions from PCH GPIO Lib which
> +/// require GpioGroup as argument
> +///
> +#define GPIO_CNL_LP_GROUP_GPP_A  0x0400
> +#define GPIO_CNL_LP_GROUP_GPP_B  0x0401
> +#define GPIO_CNL_LP_GROUP_GPP_C  0x0402
> +#define GPIO_CNL_LP_GROUP_GPP_D  0x0403
> +#define GPIO_CNL_LP_GROUP_GPP_E  0x0404
> +#define GPIO_CNL_LP_GROUP_GPP_F  0x0405
> +#define GPIO_CNL_LP_GROUP_GPP_G  0x0406
> +#define GPIO_CNL_LP_GROUP_GPP_H  0x0407
> +#define GPIO_CNL_LP_GROUP_GPD    0x0408
> +#define GPIO_CNL_LP_GROUP_VGPIO  0x0409
> +#define GPIO_CNL_LP_GROUP_SPI    0x040A
> +#define GPIO_CNL_LP_GROUP_AZA    0x040B
> +#define GPIO_CNL_LP_GROUP_CPU    0x040C
> +#define GPIO_CNL_LP_GROUP_JTAG   0x040D
> +#define GPIO_CNL_LP_GROUP_HVMOS  0x040E
> +
> +///
> +/// 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_CNL_LP_GPP_A0               0x04000000
> +#define GPIO_CNL_LP_GPP_A1               0x04000001
> +#define GPIO_CNL_LP_GPP_A2               0x04000002
> +#define GPIO_CNL_LP_GPP_A3               0x04000003
> +#define GPIO_CNL_LP_GPP_A4               0x04000004
> +#define GPIO_CNL_LP_GPP_A5               0x04000005
> +#define GPIO_CNL_LP_GPP_A6               0x04000006
> +#define GPIO_CNL_LP_GPP_A7               0x04000007
> +#define GPIO_CNL_LP_GPP_A8               0x04000008
> +#define GPIO_CNL_LP_GPP_A9               0x04000009
> +#define GPIO_CNL_LP_GPP_A10              0x0400000A
> +#define GPIO_CNL_LP_GPP_A11              0x0400000B
> +#define GPIO_CNL_LP_GPP_A12              0x0400000C
> +#define GPIO_CNL_LP_GPP_A13              0x0400000D
> +#define GPIO_CNL_LP_GPP_A14              0x0400000E
> +#define GPIO_CNL_LP_GPP_A15              0x0400000F
> +#define GPIO_CNL_LP_GPP_A16              0x04000010
> +#define GPIO_CNL_LP_GPP_A17              0x04000011
> +#define GPIO_CNL_LP_GPP_A18              0x04000012
> +#define GPIO_CNL_LP_GPP_A19              0x04000013
> +#define GPIO_CNL_LP_GPP_A20              0x04000014
> +#define GPIO_CNL_LP_GPP_A21              0x04000015
> +#define GPIO_CNL_LP_GPP_A22              0x04000016
> +#define GPIO_CNL_LP_GPP_A23              0x04000017
> +#define GPIO_CNL_LP_ESPI_CLK_LOOPBK      0x04000018
> +
> +#define GPIO_CNL_LP_GPP_B0               0x04010000
> +#define GPIO_CNL_LP_GPP_B1               0x04010001
> +#define GPIO_CNL_LP_GPP_B2               0x04010002
> +#define GPIO_CNL_LP_GPP_B3               0x04010003
> +#define GPIO_CNL_LP_GPP_B4               0x04010004
> +#define GPIO_CNL_LP_GPP_B5               0x04010005
> +#define GPIO_CNL_LP_GPP_B6               0x04010006
> +#define GPIO_CNL_LP_GPP_B7               0x04010007
> +#define GPIO_CNL_LP_GPP_B8               0x04010008
> +#define GPIO_CNL_LP_GPP_B9               0x04010009
> +#define GPIO_CNL_LP_GPP_B10              0x0401000A
> +#define GPIO_CNL_LP_GPP_B11              0x0401000B
> +#define GPIO_CNL_LP_GPP_B12              0x0401000C
> +#define GPIO_CNL_LP_GPP_B13              0x0401000D
> +#define GPIO_CNL_LP_GPP_B14              0x0401000E
> +#define GPIO_CNL_LP_GPP_B15              0x0401000F
> +#define GPIO_CNL_LP_GPP_B16              0x04010010
> +#define GPIO_CNL_LP_GPP_B17              0x04010011
> +#define GPIO_CNL_LP_GPP_B18              0x04010012
> +#define GPIO_CNL_LP_GPP_B19              0x04010013
> +#define GPIO_CNL_LP_GPP_B20              0x04010014
> +#define GPIO_CNL_LP_GPP_B21              0x04010015
> +#define GPIO_CNL_LP_GPP_B22              0x04010016
> +#define GPIO_CNL_LP_GPP_B23              0x04010017
> +#define GPIO_CNL_LP_GSPI0_CLK_LOOPBK     0x04010018
> +#define GPIO_CNL_LP_GSPI1_CLK_LOOPBK     0x04010019
> +
> +#define GPIO_CNL_LP_GPP_C0               0x04020000
> +#define GPIO_CNL_LP_GPP_C1               0x04020001
> +#define GPIO_CNL_LP_GPP_C2               0x04020002
> +#define GPIO_CNL_LP_GPP_C3               0x04020003
> +#define GPIO_CNL_LP_GPP_C4               0x04020004
> +#define GPIO_CNL_LP_GPP_C5               0x04020005
> +#define GPIO_CNL_LP_GPP_C6               0x04020006
> +#define GPIO_CNL_LP_GPP_C7               0x04020007
> +#define GPIO_CNL_LP_GPP_C8               0x04020008
> +#define GPIO_CNL_LP_GPP_C9               0x04020009
> +#define GPIO_CNL_LP_GPP_C10              0x0402000A
> +#define GPIO_CNL_LP_GPP_C11              0x0402000B
> +#define GPIO_CNL_LP_GPP_C12              0x0402000C
> +#define GPIO_CNL_LP_GPP_C13              0x0402000D
> +#define GPIO_CNL_LP_GPP_C14              0x0402000E
> +#define GPIO_CNL_LP_GPP_C15              0x0402000F
> +#define GPIO_CNL_LP_GPP_C16              0x04020010
> +#define GPIO_CNL_LP_GPP_C17              0x04020011
> +#define GPIO_CNL_LP_GPP_C18              0x04020012
> +#define GPIO_CNL_LP_GPP_C19              0x04020013
> +#define GPIO_CNL_LP_GPP_C20              0x04020014
> +#define GPIO_CNL_LP_GPP_C21              0x04020015
> +#define GPIO_CNL_LP_GPP_C22              0x04020016
> +#define GPIO_CNL_LP_GPP_C23              0x04020017
> +
> +#define GPIO_CNL_LP_GPP_D0               0x04030000
> +#define GPIO_CNL_LP_GPP_D1               0x04030001
> +#define GPIO_CNL_LP_GPP_D2               0x04030002
> +#define GPIO_CNL_LP_GPP_D3               0x04030003
> +#define GPIO_CNL_LP_GPP_D4               0x04030004
> +#define GPIO_CNL_LP_GPP_D5               0x04030005
> +#define GPIO_CNL_LP_GPP_D6               0x04030006
> +#define GPIO_CNL_LP_GPP_D7               0x04030007
> +#define GPIO_CNL_LP_GPP_D8               0x04030008
> +#define GPIO_CNL_LP_GPP_D9               0x04030009
> +#define GPIO_CNL_LP_GPP_D10              0x0403000A
> +#define GPIO_CNL_LP_GPP_D11              0x0403000B
> +#define GPIO_CNL_LP_GPP_D12              0x0403000C
> +#define GPIO_CNL_LP_GPP_D13              0x0403000D
> +#define GPIO_CNL_LP_GPP_D14              0x0403000E
> +#define GPIO_CNL_LP_GPP_D15              0x0403000F
> +#define GPIO_CNL_LP_GPP_D16              0x04030010
> +#define GPIO_CNL_LP_GPP_D17              0x04030011
> +#define GPIO_CNL_LP_GPP_D18              0x04030012
> +#define GPIO_CNL_LP_GPP_D19              0x04030013
> +#define GPIO_CNL_LP_GPP_D20              0x04030014
> +#define GPIO_CNL_LP_GPP_D21              0x04030015
> +#define GPIO_CNL_LP_GPP_D22              0x04030016
> +#define GPIO_CNL_LP_GPP_D23              0x04030017
> +
> +#define GPIO_CNL_LP_GPP_E0               0x04040000
> +#define GPIO_CNL_LP_GPP_E1               0x04040001
> +#define GPIO_CNL_LP_GPP_E2               0x04040002
> +#define GPIO_CNL_LP_GPP_E3               0x04040003
> +#define GPIO_CNL_LP_GPP_E4               0x04040004
> +#define GPIO_CNL_LP_GPP_E5               0x04040005
> +#define GPIO_CNL_LP_GPP_E6               0x04040006
> +#define GPIO_CNL_LP_GPP_E7               0x04040007
> +#define GPIO_CNL_LP_GPP_E8               0x04040008
> +#define GPIO_CNL_LP_GPP_E9               0x04040009
> +#define GPIO_CNL_LP_GPP_E10              0x0404000A
> +#define GPIO_CNL_LP_GPP_E11              0x0404000B
> +#define GPIO_CNL_LP_GPP_E12              0x0404000C
> +#define GPIO_CNL_LP_GPP_E13              0x0404000D
> +#define GPIO_CNL_LP_GPP_E14              0x0404000E
> +#define GPIO_CNL_LP_GPP_E15              0x0404000F
> +#define GPIO_CNL_LP_GPP_E16              0x04040010
> +#define GPIO_CNL_LP_GPP_E17              0x04040011
> +#define GPIO_CNL_LP_GPP_E18              0x04040012
> +#define GPIO_CNL_LP_GPP_E19              0x04040013
> +#define GPIO_CNL_LP_GPP_E20              0x04040014
> +#define GPIO_CNL_LP_GPP_E21              0x04040015
> +#define GPIO_CNL_LP_GPP_E22              0x04040016
> +#define GPIO_CNL_LP_GPP_E23              0x04040017
> +
> +#define GPIO_CNL_LP_GPP_F0               0x04050000
> +#define GPIO_CNL_LP_GPP_F1               0x04050001
> +#define GPIO_CNL_LP_GPP_F2               0x04050002
> +#define GPIO_CNL_LP_GPP_F3               0x04050003
> +#define GPIO_CNL_LP_GPP_F4               0x04050004
> +#define GPIO_CNL_LP_GPP_F5               0x04050005
> +#define GPIO_CNL_LP_GPP_F6               0x04050006
> +#define GPIO_CNL_LP_GPP_F7               0x04050007
> +#define GPIO_CNL_LP_GPP_F8               0x04050008
> +#define GPIO_CNL_LP_GPP_F9               0x04050009
> +#define GPIO_CNL_LP_GPP_F10              0x0405000A
> +#define GPIO_CNL_LP_GPP_F11              0x0405000B
> +#define GPIO_CNL_LP_GPP_F12              0x0405000C
> +#define GPIO_CNL_LP_GPP_F13              0x0405000D
> +#define GPIO_CNL_LP_GPP_F14              0x0405000E
> +#define GPIO_CNL_LP_GPP_F15              0x0405000F
> +#define GPIO_CNL_LP_GPP_F16              0x04050010
> +#define GPIO_CNL_LP_GPP_F17              0x04050011
> +#define GPIO_CNL_LP_GPP_F18              0x04050012
> +#define GPIO_CNL_LP_GPP_F19              0x04050013
> +#define GPIO_CNL_LP_GPP_F20              0x04050014
> +#define GPIO_CNL_LP_GPP_F21              0x04050015
> +#define GPIO_CNL_LP_GPP_F22              0x04050016
> +#define GPIO_CNL_LP_GPP_F23              0x04050017
> +
> +#define GPIO_CNL_LP_GPP_G0               0x04060000
> +#define GPIO_CNL_LP_GPP_G1               0x04060001
> +#define GPIO_CNL_LP_GPP_G2               0x04060002
> +#define GPIO_CNL_LP_GPP_G3               0x04060003
> +#define GPIO_CNL_LP_GPP_G4               0x04060004
> +#define GPIO_CNL_LP_GPP_G5               0x04060005
> +#define GPIO_CNL_LP_GPP_G6               0x04060006
> +#define GPIO_CNL_LP_GPP_G7               0x04060007
> +
> +#define GPIO_CNL_LP_GPP_H0               0x04070000
> +#define GPIO_CNL_LP_GPP_H1               0x04070001
> +#define GPIO_CNL_LP_GPP_H2               0x04070002
> +#define GPIO_CNL_LP_GPP_H3               0x04070003
> +#define GPIO_CNL_LP_GPP_H4               0x04070004
> +#define GPIO_CNL_LP_GPP_H5               0x04070005
> +#define GPIO_CNL_LP_GPP_H6               0x04070006
> +#define GPIO_CNL_LP_GPP_H7               0x04070007
> +#define GPIO_CNL_LP_GPP_H8               0x04070008
> +#define GPIO_CNL_LP_GPP_H9               0x04070009
> +#define GPIO_CNL_LP_GPP_H10              0x0407000A
> +#define GPIO_CNL_LP_GPP_H11              0x0407000B
> +#define GPIO_CNL_LP_GPP_H12              0x0407000C
> +#define GPIO_CNL_LP_GPP_H13              0x0407000D
> +#define GPIO_CNL_LP_GPP_H14              0x0407000E
> +#define GPIO_CNL_LP_GPP_H15              0x0407000F
> +#define GPIO_CNL_LP_GPP_H16              0x04070010
> +#define GPIO_CNL_LP_GPP_H17              0x04070011
> +#define GPIO_CNL_LP_GPP_H18              0x04070012
> +#define GPIO_CNL_LP_GPP_H19              0x04070013
> +#define GPIO_CNL_LP_GPP_H20              0x04070014
> +#define GPIO_CNL_LP_GPP_H21              0x04070015
> +#define GPIO_CNL_LP_GPP_H22              0x04070016
> +#define GPIO_CNL_LP_GPP_H23              0x04070017
> +
> +#define GPIO_CNL_LP_GPD0                 0x04080000
> +#define GPIO_CNL_LP_GPD1                 0x04080001
> +#define GPIO_CNL_LP_GPD2                 0x04080002
> +#define GPIO_CNL_LP_GPD3                 0x04080003
> +#define GPIO_CNL_LP_GPD4                 0x04080004
> +#define GPIO_CNL_LP_GPD5                 0x04080005
> +#define GPIO_CNL_LP_GPD6                 0x04080006
> +#define GPIO_CNL_LP_GPD7                 0x04080007
> +#define GPIO_CNL_LP_GPD8                 0x04080008
> +#define GPIO_CNL_LP_GPD9                 0x04080009
> +#define GPIO_CNL_LP_GPD10                0x0408000A
> +#define GPIO_CNL_LP_GPD11                0x0408000B
> +#define GPIO_CNL_LP_SLP_LANB             0x0408000C
> +#define GPIO_CNL_LP_SLP_SUSB             0x0408000D
> +#define GPIO_CNL_LP_SLP_WAKEB            0x0408000E
> +#define GPIO_CNL_LP_SLP_DRAM_RESETB      0x0408000F
> +
> +#define GPIO_CNL_LP_VGPIO0               0x04090000
> +#define GPIO_CNL_LP_VGPIO1               0x04090001
> +#define GPIO_CNL_LP_VGPIO2               0x04090002
> +#define GPIO_CNL_LP_VGPIO3               0x04090003
> +#define GPIO_CNL_LP_VGPIO4               0x04090004
> +#define GPIO_CNL_LP_VGPIO5               0x04090005
> +#define GPIO_CNL_LP_VGPIO6               0x04090006
> +#define GPIO_CNL_LP_VGPIO7               0x04090007
> +#define GPIO_CNL_LP_VGPIO8               0x04090008
> +#define GPIO_CNL_LP_VGPIO9               0x04090009
> +#define GPIO_CNL_LP_VGPIO10              0x0409000A
> +#define GPIO_CNL_LP_VGPIO11              0x0409000B
> +#define GPIO_CNL_LP_VGPIO12              0x0409000C
> +#define GPIO_CNL_LP_VGPIO13              0x0409000D
> +#define GPIO_CNL_LP_VGPIO14              0x0409000E
> +#define GPIO_CNL_LP_VGPIO15              0x0409000F
> +#define GPIO_CNL_LP_VGPIO16              0x04090010
> +#define GPIO_CNL_LP_VGPIO17              0x04090011
> +#define GPIO_CNL_LP_VGPIO18              0x04090012
> +#define GPIO_CNL_LP_VGPIO19              0x04090013
> +#define GPIO_CNL_LP_VGPIO20              0x04090014
> +#define GPIO_CNL_LP_VGPIO21              0x04090015
> +#define GPIO_CNL_LP_VGPIO22              0x04090016
> +#define GPIO_CNL_LP_VGPIO23              0x04090017
> +#define GPIO_CNL_LP_VGPIO24              0x04090018
> +#define GPIO_CNL_LP_VGPIO25              0x04090019
> +#define GPIO_CNL_LP_VGPIO26              0x0409001A
> +#define GPIO_CNL_LP_VGPIO27              0x0409001B
> +#define GPIO_CNL_LP_VGPIO28              0x0409001C
> +#define GPIO_CNL_LP_VGPIO29              0x0409001D
> +#define GPIO_CNL_LP_VGPIO30              0x0409001E
> +#define GPIO_CNL_LP_VGPIO31              0x0409001F
> +#define GPIO_CNL_LP_VGPIO32              0x04090020
> +#define GPIO_CNL_LP_VGPIO33              0x04090021
> +#define GPIO_CNL_LP_VGPIO34              0x04090022
> +#define GPIO_CNL_LP_VGPIO35              0x04090023
> +#define GPIO_CNL_LP_VGPIO36              0x04090024
> +#define GPIO_CNL_LP_VGPIO37              0x04090025
> +#define GPIO_CNL_LP_VGPIO38              0x04090026
> +#define GPIO_CNL_LP_VGPIO39              0x04090027
> +
> +#define GPIO_CNL_LP_SPI0_IO_2            0x040A0000
> +#define GPIO_CNL_LP_SPI0_IO_3            0x040A0001
> +#define GPIO_CNL_LP_SPI0_MOSI_IO_0       0x040A0002
> +#define GPIO_CNL_LP_SPI0_MOSI_IO_1       0x040A0003
> +#define GPIO_CNL_LP_SPI0_TPM_CSB         0x040A0004
> +#define GPIO_CNL_LP_SPI0_FLASH_0_CSB     0x040A0005
> +#define GPIO_CNL_LP_SPI0_FLASH_1_CSB     0x040A0006
> +#define GPIO_CNL_LP_SPI0_CLK             0x040A0007
> +#define GPIO_CNL_LP_SPI0_CLK_LOOPBK      0x040A0008
> +
> +#define GPIO_CNL_LP_HDA_BCLK             0x040B0000
> +#define GPIO_CNL_LP_HDA_RSTB             0x040B0001
> +#define GPIO_CNL_LP_HDA_SYNC             0x040B0002
> +#define GPIO_CNL_LP_HDA_SDO              0x040B0003
> +#define GPIO_CNL_LP_HDA_SDI_0            0x040B0004
> +#define GPIO_CNL_LP_HDA_SDI_1            0x040B0005
> +#define GPIO_CNL_LP_SSP1_SFRM            0x040B0006
> +#define GPIO_CNL_LP_SSP1_TXD             0x040B0007
> +
> +#define GPIO_CNL_LP_HDACPU_SDI           0x040C0000
> +#define GPIO_CNL_LP_HDACPU_SDO           0x040C0001
> +#define GPIO_CNL_LP_HDACPU_SCLK          0x040C0002
> +#define GPIO_CNL_LP_PM_SYNC              0x040C0003
> +#define GPIO_CNL_LP_PECI                 0x040C0004
> +#define GPIO_CNL_LP_CPUPWRGD             0x040C0005
> +#define GPIO_CNL_LP_THRMTRIPB            0x040C0006
> +#define GPIO_CNL_LP_PLTRST_CPUB          0x040C0007
> +#define GPIO_CNL_LP_PM_DOWN              0x040C0008
> +#define GPIO_CNL_LP_TRIGGER_IN           0x040C0009
> +#define GPIO_CNL_LP_TRIGGER_OUT          0x040C000A
> +
> +#define GPIO_CNL_LP_JTAG_TDO             0x040D0000
> +#define GPIO_CNL_LP_JTAGX                0x040D0001
> +#define GPIO_CNL_LP_PRDYB                0x040D0002
> +#define GPIO_CNL_LP_PREQB                0x040D0003
> +#define GPIO_CNL_LP_CPU_TRSTB            0x040D0004
> +#define GPIO_CNL_LP_JTAG_TDI             0x040D0005
> +#define GPIO_CNL_LP_JTAG_TMS             0x040D0006
> +#define GPIO_CNL_LP_JTAG_TCK             0x040D0007
> +#define GPIO_CNL_LP_ITP_PMODE            0x040D0008
> +
> +#define GPIO_CNL_LP_HVMOS_L_BKLTEN       0x040E0000
> +#define GPIO_CNL_LP_HVMOS_L_BKLTCTL      0x040E0001
> +#define GPIO_CNL_LP_HVMOS_L_VDDEN        0x040E0002
> +#define GPIO_CNL_LP_HVMOS_SYS_PWROK      0x040E0003
> +#define GPIO_CNL_LP_HVMOS_SYS_RESETB     0x040E0004
> +#define GPIO_CNL_LP_HVMOS_MLK_RSTB       0x040E0005
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
> new file mode 100644
> index 0000000000..d3aad4172f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
> @@ -0,0 +1,241 @@
> +/** @file
> +  GPIO pins
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_PINS_SKL_H_H_
> +#define _GPIO_PINS_SKL_H_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
> +///
> +///
> +/// Use below for functions from PCH GPIO Lib which
> +/// require GpioGroup as argument
> +///
> +#define GPIO_SKL_H_GROUP_GPP_A  0x0100
> +#define GPIO_SKL_H_GROUP_GPP_B  0x0101
> +#define GPIO_SKL_H_GROUP_GPP_C  0x0102
> +#define GPIO_SKL_H_GROUP_GPP_D  0x0103
> +#define GPIO_SKL_H_GROUP_GPP_E  0x0104
> +#define GPIO_SKL_H_GROUP_GPP_F  0x0105
> +#define GPIO_SKL_H_GROUP_GPP_G  0x0106
> +#define GPIO_SKL_H_GROUP_GPP_H  0x0107
> +#define GPIO_SKL_H_GROUP_GPP_I  0x0108
> +#define GPIO_SKL_H_GROUP_GPD    0x0109
> +
> +///
> +/// 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_SKL_H_GPP_A0       0x01000000
> +#define GPIO_SKL_H_GPP_A1       0x01000001
> +#define GPIO_SKL_H_GPP_A2       0x01000002
> +#define GPIO_SKL_H_GPP_A3       0x01000003
> +#define GPIO_SKL_H_GPP_A4       0x01000004
> +#define GPIO_SKL_H_GPP_A5       0x01000005
> +#define GPIO_SKL_H_GPP_A6       0x01000006
> +#define GPIO_SKL_H_GPP_A7       0x01000007
> +#define GPIO_SKL_H_GPP_A8       0x01000008
> +#define GPIO_SKL_H_GPP_A9       0x01000009
> +#define GPIO_SKL_H_GPP_A10      0x0100000A
> +#define GPIO_SKL_H_GPP_A11      0x0100000B
> +#define GPIO_SKL_H_GPP_A12      0x0100000C
> +#define GPIO_SKL_H_GPP_A13      0x0100000D
> +#define GPIO_SKL_H_GPP_A14      0x0100000E
> +#define GPIO_SKL_H_GPP_A15      0x0100000F
> +#define GPIO_SKL_H_GPP_A16      0x01000010
> +#define GPIO_SKL_H_GPP_A17      0x01000011
> +#define GPIO_SKL_H_GPP_A18      0x01000012
> +#define GPIO_SKL_H_GPP_A19      0x01000013
> +#define GPIO_SKL_H_GPP_A20      0x01000014
> +#define GPIO_SKL_H_GPP_A21      0x01000015
> +#define GPIO_SKL_H_GPP_A22      0x01000016
> +#define GPIO_SKL_H_GPP_A23      0x01000017
> +#define GPIO_SKL_H_GPP_B0       0x01010000
> +#define GPIO_SKL_H_GPP_B1       0x01010001
> +#define GPIO_SKL_H_GPP_B2       0x01010002
> +#define GPIO_SKL_H_GPP_B3       0x01010003
> +#define GPIO_SKL_H_GPP_B4       0x01010004
> +#define GPIO_SKL_H_GPP_B5       0x01010005
> +#define GPIO_SKL_H_GPP_B6       0x01010006
> +#define GPIO_SKL_H_GPP_B7       0x01010007
> +#define GPIO_SKL_H_GPP_B8       0x01010008
> +#define GPIO_SKL_H_GPP_B9       0x01010009
> +#define GPIO_SKL_H_GPP_B10      0x0101000A
> +#define GPIO_SKL_H_GPP_B11      0x0101000B
> +#define GPIO_SKL_H_GPP_B12      0x0101000C
> +#define GPIO_SKL_H_GPP_B13      0x0101000D
> +#define GPIO_SKL_H_GPP_B14      0x0101000E
> +#define GPIO_SKL_H_GPP_B15      0x0101000F
> +#define GPIO_SKL_H_GPP_B16      0x01010010
> +#define GPIO_SKL_H_GPP_B17      0x01010011
> +#define GPIO_SKL_H_GPP_B18      0x01010012
> +#define GPIO_SKL_H_GPP_B19      0x01010013
> +#define GPIO_SKL_H_GPP_B20      0x01010014
> +#define GPIO_SKL_H_GPP_B21      0x01010015
> +#define GPIO_SKL_H_GPP_B22      0x01010016
> +#define GPIO_SKL_H_GPP_B23      0x01010017
> +#define GPIO_SKL_H_GPP_C0       0x01020000
> +#define GPIO_SKL_H_GPP_C1       0x01020001
> +#define GPIO_SKL_H_GPP_C2       0x01020002
> +#define GPIO_SKL_H_GPP_C3       0x01020003
> +#define GPIO_SKL_H_GPP_C4       0x01020004
> +#define GPIO_SKL_H_GPP_C5       0x01020005
> +#define GPIO_SKL_H_GPP_C6       0x01020006
> +#define GPIO_SKL_H_GPP_C7       0x01020007
> +#define GPIO_SKL_H_GPP_C8       0x01020008
> +#define GPIO_SKL_H_GPP_C9       0x01020009
> +#define GPIO_SKL_H_GPP_C10      0x0102000A
> +#define GPIO_SKL_H_GPP_C11      0x0102000B
> +#define GPIO_SKL_H_GPP_C12      0x0102000C
> +#define GPIO_SKL_H_GPP_C13      0x0102000D
> +#define GPIO_SKL_H_GPP_C14      0x0102000E
> +#define GPIO_SKL_H_GPP_C15      0x0102000F
> +#define GPIO_SKL_H_GPP_C16      0x01020010
> +#define GPIO_SKL_H_GPP_C17      0x01020011
> +#define GPIO_SKL_H_GPP_C18      0x01020012
> +#define GPIO_SKL_H_GPP_C19      0x01020013
> +#define GPIO_SKL_H_GPP_C20      0x01020014
> +#define GPIO_SKL_H_GPP_C21      0x01020015
> +#define GPIO_SKL_H_GPP_C22      0x01020016
> +#define GPIO_SKL_H_GPP_C23      0x01020017
> +#define GPIO_SKL_H_GPP_D0       0x01030000
> +#define GPIO_SKL_H_GPP_D1       0x01030001
> +#define GPIO_SKL_H_GPP_D2       0x01030002
> +#define GPIO_SKL_H_GPP_D3       0x01030003
> +#define GPIO_SKL_H_GPP_D4       0x01030004
> +#define GPIO_SKL_H_GPP_D5       0x01030005
> +#define GPIO_SKL_H_GPP_D6       0x01030006
> +#define GPIO_SKL_H_GPP_D7       0x01030007
> +#define GPIO_SKL_H_GPP_D8       0x01030008
> +#define GPIO_SKL_H_GPP_D9       0x01030009
> +#define GPIO_SKL_H_GPP_D10      0x0103000A
> +#define GPIO_SKL_H_GPP_D11      0x0103000B
> +#define GPIO_SKL_H_GPP_D12      0x0103000C
> +#define GPIO_SKL_H_GPP_D13      0x0103000D
> +#define GPIO_SKL_H_GPP_D14      0x0103000E
> +#define GPIO_SKL_H_GPP_D15      0x0103000F
> +#define GPIO_SKL_H_GPP_D16      0x01030010
> +#define GPIO_SKL_H_GPP_D17      0x01030011
> +#define GPIO_SKL_H_GPP_D18      0x01030012
> +#define GPIO_SKL_H_GPP_D19      0x01030013
> +#define GPIO_SKL_H_GPP_D20      0x01030014
> +#define GPIO_SKL_H_GPP_D21      0x01030015
> +#define GPIO_SKL_H_GPP_D22      0x01030016
> +#define GPIO_SKL_H_GPP_D23      0x01030017
> +#define GPIO_SKL_H_GPP_E0       0x01040000
> +#define GPIO_SKL_H_GPP_E1       0x01040001
> +#define GPIO_SKL_H_GPP_E2       0x01040002
> +#define GPIO_SKL_H_GPP_E3       0x01040003
> +#define GPIO_SKL_H_GPP_E4       0x01040004
> +#define GPIO_SKL_H_GPP_E5       0x01040005
> +#define GPIO_SKL_H_GPP_E6       0x01040006
> +#define GPIO_SKL_H_GPP_E7       0x01040007
> +#define GPIO_SKL_H_GPP_E8       0x01040008
> +#define GPIO_SKL_H_GPP_E9       0x01040009
> +#define GPIO_SKL_H_GPP_E10      0x0104000A
> +#define GPIO_SKL_H_GPP_E11      0x0104000B
> +#define GPIO_SKL_H_GPP_E12      0x0104000C
> +#define GPIO_SKL_H_GPP_F0       0x01050000
> +#define GPIO_SKL_H_GPP_F1       0x01050001
> +#define GPIO_SKL_H_GPP_F2       0x01050002
> +#define GPIO_SKL_H_GPP_F3       0x01050003
> +#define GPIO_SKL_H_GPP_F4       0x01050004
> +#define GPIO_SKL_H_GPP_F5       0x01050005
> +#define GPIO_SKL_H_GPP_F6       0x01050006
> +#define GPIO_SKL_H_GPP_F7       0x01050007
> +#define GPIO_SKL_H_GPP_F8       0x01050008
> +#define GPIO_SKL_H_GPP_F9       0x01050009
> +#define GPIO_SKL_H_GPP_F10      0x0105000A
> +#define GPIO_SKL_H_GPP_F11      0x0105000B
> +#define GPIO_SKL_H_GPP_F12      0x0105000C
> +#define GPIO_SKL_H_GPP_F13      0x0105000D
> +#define GPIO_SKL_H_GPP_F14      0x0105000E
> +#define GPIO_SKL_H_GPP_F15      0x0105000F
> +#define GPIO_SKL_H_GPP_F16      0x01050010
> +#define GPIO_SKL_H_GPP_F17      0x01050011
> +#define GPIO_SKL_H_GPP_F18      0x01050012
> +#define GPIO_SKL_H_GPP_F19      0x01050013
> +#define GPIO_SKL_H_GPP_F20      0x01050014
> +#define GPIO_SKL_H_GPP_F21      0x01050015
> +#define GPIO_SKL_H_GPP_F22      0x01050016
> +#define GPIO_SKL_H_GPP_F23      0x01050017
> +#define GPIO_SKL_H_GPP_G0       0x01060000
> +#define GPIO_SKL_H_GPP_G1       0x01060001
> +#define GPIO_SKL_H_GPP_G2       0x01060002
> +#define GPIO_SKL_H_GPP_G3       0x01060003
> +#define GPIO_SKL_H_GPP_G4       0x01060004
> +#define GPIO_SKL_H_GPP_G5       0x01060005
> +#define GPIO_SKL_H_GPP_G6       0x01060006
> +#define GPIO_SKL_H_GPP_G7       0x01060007
> +#define GPIO_SKL_H_GPP_G8       0x01060008
> +#define GPIO_SKL_H_GPP_G9       0x01060009
> +#define GPIO_SKL_H_GPP_G10      0x0106000A
> +#define GPIO_SKL_H_GPP_G11      0x0106000B
> +#define GPIO_SKL_H_GPP_G12      0x0106000C
> +#define GPIO_SKL_H_GPP_G13      0x0106000D
> +#define GPIO_SKL_H_GPP_G14      0x0106000E
> +#define GPIO_SKL_H_GPP_G15      0x0106000F
> +#define GPIO_SKL_H_GPP_G16      0x01060010
> +#define GPIO_SKL_H_GPP_G17      0x01060011
> +#define GPIO_SKL_H_GPP_G18      0x01060012
> +#define GPIO_SKL_H_GPP_G19      0x01060013
> +#define GPIO_SKL_H_GPP_G20      0x01060014
> +#define GPIO_SKL_H_GPP_G21      0x01060015
> +#define GPIO_SKL_H_GPP_G22      0x01060016
> +#define GPIO_SKL_H_GPP_G23      0x01060017
> +#define GPIO_SKL_H_GPP_H0       0x01070000
> +#define GPIO_SKL_H_GPP_H1       0x01070001
> +#define GPIO_SKL_H_GPP_H2       0x01070002
> +#define GPIO_SKL_H_GPP_H3       0x01070003
> +#define GPIO_SKL_H_GPP_H4       0x01070004
> +#define GPIO_SKL_H_GPP_H5       0x01070005
> +#define GPIO_SKL_H_GPP_H6       0x01070006
> +#define GPIO_SKL_H_GPP_H7       0x01070007
> +#define GPIO_SKL_H_GPP_H8       0x01070008
> +#define GPIO_SKL_H_GPP_H9       0x01070009
> +#define GPIO_SKL_H_GPP_H10      0x0107000A
> +#define GPIO_SKL_H_GPP_H11      0x0107000B
> +#define GPIO_SKL_H_GPP_H12      0x0107000C
> +#define GPIO_SKL_H_GPP_H13      0x0107000D
> +#define GPIO_SKL_H_GPP_H14      0x0107000E
> +#define GPIO_SKL_H_GPP_H15      0x0107000F
> +#define GPIO_SKL_H_GPP_H16      0x01070010
> +#define GPIO_SKL_H_GPP_H17      0x01070011
> +#define GPIO_SKL_H_GPP_H18      0x01070012
> +#define GPIO_SKL_H_GPP_H19      0x01070013
> +#define GPIO_SKL_H_GPP_H20      0x01070014
> +#define GPIO_SKL_H_GPP_H21      0x01070015
> +#define GPIO_SKL_H_GPP_H22      0x01070016
> +#define GPIO_SKL_H_GPP_H23      0x01070017
> +#define GPIO_SKL_H_GPP_I0       0x01080000
> +#define GPIO_SKL_H_GPP_I1       0x01080001
> +#define GPIO_SKL_H_GPP_I2       0x01080002
> +#define GPIO_SKL_H_GPP_I3       0x01080003
> +#define GPIO_SKL_H_GPP_I4       0x01080004
> +#define GPIO_SKL_H_GPP_I5       0x01080005
> +#define GPIO_SKL_H_GPP_I6       0x01080006
> +#define GPIO_SKL_H_GPP_I7       0x01080007
> +#define GPIO_SKL_H_GPP_I8       0x01080008
> +#define GPIO_SKL_H_GPP_I9       0x01080009
> +#define GPIO_SKL_H_GPP_I10      0x0108000A
> +#define GPIO_SKL_H_GPD0         0x01090000
> +#define GPIO_SKL_H_GPD1         0x01090001
> +#define GPIO_SKL_H_GPD2         0x01090002
> +#define GPIO_SKL_H_GPD3         0x01090003
> +#define GPIO_SKL_H_GPD4         0x01090004
> +#define GPIO_SKL_H_GPD5         0x01090005
> +#define GPIO_SKL_H_GPD6         0x01090006
> +#define GPIO_SKL_H_GPD7         0x01090007
> +#define GPIO_SKL_H_GPD8         0x01090008
> +#define GPIO_SKL_H_GPD9         0x01090009
> +#define GPIO_SKL_H_GPD10        0x0109000A
> +#define GPIO_SKL_H_GPD11        0x0109000B
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
> new file mode 100644
> index 0000000000..8d430afd14
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
> @@ -0,0 +1,200 @@
> +/** @file
> +  GPIO pins
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_PINS_SKL_LP_H_
> +#define _GPIO_PINS_SKL_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
> +///
> +
> +///
> +/// Use below for functions from PCH GPIO Lib which
> +/// require GpioGroup as argument
> +///
> +#define GPIO_SKL_LP_GROUP_GPP_A  0x0200
> +#define GPIO_SKL_LP_GROUP_GPP_B  0x0201
> +#define GPIO_SKL_LP_GROUP_GPP_C  0x0202
> +#define GPIO_SKL_LP_GROUP_GPP_D  0x0203
> +#define GPIO_SKL_LP_GROUP_GPP_E  0x0204
> +#define GPIO_SKL_LP_GROUP_GPP_F  0x0205
> +#define GPIO_SKL_LP_GROUP_GPP_G  0x0206
> +#define GPIO_SKL_LP_GROUP_GPD    0x0207
> +
> +///
> +/// 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_SKL_LP_GPP_A0      0x02000000
> +#define GPIO_SKL_LP_GPP_A1      0x02000001
> +#define GPIO_SKL_LP_GPP_A2      0x02000002
> +#define GPIO_SKL_LP_GPP_A3      0x02000003
> +#define GPIO_SKL_LP_GPP_A4      0x02000004
> +#define GPIO_SKL_LP_GPP_A5      0x02000005
> +#define GPIO_SKL_LP_GPP_A6      0x02000006
> +#define GPIO_SKL_LP_GPP_A7      0x02000007
> +#define GPIO_SKL_LP_GPP_A8      0x02000008
> +#define GPIO_SKL_LP_GPP_A9      0x02000009
> +#define GPIO_SKL_LP_GPP_A10     0x0200000A
> +#define GPIO_SKL_LP_GPP_A11     0x0200000B
> +#define GPIO_SKL_LP_GPP_A12     0x0200000C
> +#define GPIO_SKL_LP_GPP_A13     0x0200000D
> +#define GPIO_SKL_LP_GPP_A14     0x0200000E
> +#define GPIO_SKL_LP_GPP_A15     0x0200000F
> +#define GPIO_SKL_LP_GPP_A16     0x02000010
> +#define GPIO_SKL_LP_GPP_A17     0x02000011
> +#define GPIO_SKL_LP_GPP_A18     0x02000012
> +#define GPIO_SKL_LP_GPP_A19     0x02000013
> +#define GPIO_SKL_LP_GPP_A20     0x02000014
> +#define GPIO_SKL_LP_GPP_A21     0x02000015
> +#define GPIO_SKL_LP_GPP_A22     0x02000016
> +#define GPIO_SKL_LP_GPP_A23     0x02000017
> +#define GPIO_SKL_LP_GPP_B0      0x02010000
> +#define GPIO_SKL_LP_GPP_B1      0x02010001
> +#define GPIO_SKL_LP_GPP_B2      0x02010002
> +#define GPIO_SKL_LP_GPP_B3      0x02010003
> +#define GPIO_SKL_LP_GPP_B4      0x02010004
> +#define GPIO_SKL_LP_GPP_B5      0x02010005
> +#define GPIO_SKL_LP_GPP_B6      0x02010006
> +#define GPIO_SKL_LP_GPP_B7      0x02010007
> +#define GPIO_SKL_LP_GPP_B8      0x02010008
> +#define GPIO_SKL_LP_GPP_B9      0x02010009
> +#define GPIO_SKL_LP_GPP_B10     0x0201000A
> +#define GPIO_SKL_LP_GPP_B11     0x0201000B
> +#define GPIO_SKL_LP_GPP_B12     0x0201000C
> +#define GPIO_SKL_LP_GPP_B13     0x0201000D
> +#define GPIO_SKL_LP_GPP_B14     0x0201000E
> +#define GPIO_SKL_LP_GPP_B15     0x0201000F
> +#define GPIO_SKL_LP_GPP_B16     0x02010010
> +#define GPIO_SKL_LP_GPP_B17     0x02010011
> +#define GPIO_SKL_LP_GPP_B18     0x02010012
> +#define GPIO_SKL_LP_GPP_B19     0x02010013
> +#define GPIO_SKL_LP_GPP_B20     0x02010014
> +#define GPIO_SKL_LP_GPP_B21     0x02010015
> +#define GPIO_SKL_LP_GPP_B22     0x02010016
> +#define GPIO_SKL_LP_GPP_B23     0x02010017
> +#define GPIO_SKL_LP_GPP_C0      0x02020000
> +#define GPIO_SKL_LP_GPP_C1      0x02020001
> +#define GPIO_SKL_LP_GPP_C2      0x02020002
> +#define GPIO_SKL_LP_GPP_C3      0x02020003
> +#define GPIO_SKL_LP_GPP_C4      0x02020004
> +#define GPIO_SKL_LP_GPP_C5      0x02020005
> +#define GPIO_SKL_LP_GPP_C6      0x02020006
> +#define GPIO_SKL_LP_GPP_C7      0x02020007
> +#define GPIO_SKL_LP_GPP_C8      0x02020008
> +#define GPIO_SKL_LP_GPP_C9      0x02020009
> +#define GPIO_SKL_LP_GPP_C10     0x0202000A
> +#define GPIO_SKL_LP_GPP_C11     0x0202000B
> +#define GPIO_SKL_LP_GPP_C12     0x0202000C
> +#define GPIO_SKL_LP_GPP_C13     0x0202000D
> +#define GPIO_SKL_LP_GPP_C14     0x0202000E
> +#define GPIO_SKL_LP_GPP_C15     0x0202000F
> +#define GPIO_SKL_LP_GPP_C16     0x02020010
> +#define GPIO_SKL_LP_GPP_C17     0x02020011
> +#define GPIO_SKL_LP_GPP_C18     0x02020012
> +#define GPIO_SKL_LP_GPP_C19     0x02020013
> +#define GPIO_SKL_LP_GPP_C20     0x02020014
> +#define GPIO_SKL_LP_GPP_C21     0x02020015
> +#define GPIO_SKL_LP_GPP_C22     0x02020016
> +#define GPIO_SKL_LP_GPP_C23     0x02020017
> +#define GPIO_SKL_LP_GPP_D0      0x02030000
> +#define GPIO_SKL_LP_GPP_D1      0x02030001
> +#define GPIO_SKL_LP_GPP_D2      0x02030002
> +#define GPIO_SKL_LP_GPP_D3      0x02030003
> +#define GPIO_SKL_LP_GPP_D4      0x02030004
> +#define GPIO_SKL_LP_GPP_D5      0x02030005
> +#define GPIO_SKL_LP_GPP_D6      0x02030006
> +#define GPIO_SKL_LP_GPP_D7      0x02030007
> +#define GPIO_SKL_LP_GPP_D8      0x02030008
> +#define GPIO_SKL_LP_GPP_D9      0x02030009
> +#define GPIO_SKL_LP_GPP_D10     0x0203000A
> +#define GPIO_SKL_LP_GPP_D11     0x0203000B
> +#define GPIO_SKL_LP_GPP_D12     0x0203000C
> +#define GPIO_SKL_LP_GPP_D13     0x0203000D
> +#define GPIO_SKL_LP_GPP_D14     0x0203000E
> +#define GPIO_SKL_LP_GPP_D15     0x0203000F
> +#define GPIO_SKL_LP_GPP_D16     0x02030010
> +#define GPIO_SKL_LP_GPP_D17     0x02030011
> +#define GPIO_SKL_LP_GPP_D18     0x02030012
> +#define GPIO_SKL_LP_GPP_D19     0x02030013
> +#define GPIO_SKL_LP_GPP_D20     0x02030014
> +#define GPIO_SKL_LP_GPP_D21     0x02030015
> +#define GPIO_SKL_LP_GPP_D22     0x02030016
> +#define GPIO_SKL_LP_GPP_D23     0x02030017
> +#define GPIO_SKL_LP_GPP_E0      0x02040000
> +#define GPIO_SKL_LP_GPP_E1      0x02040001
> +#define GPIO_SKL_LP_GPP_E2      0x02040002
> +#define GPIO_SKL_LP_GPP_E3      0x02040003
> +#define GPIO_SKL_LP_GPP_E4      0x02040004
> +#define GPIO_SKL_LP_GPP_E5      0x02040005
> +#define GPIO_SKL_LP_GPP_E6      0x02040006
> +#define GPIO_SKL_LP_GPP_E7      0x02040007
> +#define GPIO_SKL_LP_GPP_E8      0x02040008
> +#define GPIO_SKL_LP_GPP_E9      0x02040009
> +#define GPIO_SKL_LP_GPP_E10     0x0204000A
> +#define GPIO_SKL_LP_GPP_E11     0x0204000B
> +#define GPIO_SKL_LP_GPP_E12     0x0204000C
> +#define GPIO_SKL_LP_GPP_E13     0x0204000D
> +#define GPIO_SKL_LP_GPP_E14     0x0204000E
> +#define GPIO_SKL_LP_GPP_E15     0x0204000F
> +#define GPIO_SKL_LP_GPP_E16     0x02040010
> +#define GPIO_SKL_LP_GPP_E17     0x02040011
> +#define GPIO_SKL_LP_GPP_E18     0x02040012
> +#define GPIO_SKL_LP_GPP_E19     0x02040013
> +#define GPIO_SKL_LP_GPP_E20     0x02040014
> +#define GPIO_SKL_LP_GPP_E21     0x02040015
> +#define GPIO_SKL_LP_GPP_E22     0x02040016
> +#define GPIO_SKL_LP_GPP_E23     0x02040017
> +#define GPIO_SKL_LP_GPP_F0      0x02050000
> +#define GPIO_SKL_LP_GPP_F1      0x02050001
> +#define GPIO_SKL_LP_GPP_F2      0x02050002
> +#define GPIO_SKL_LP_GPP_F3      0x02050003
> +#define GPIO_SKL_LP_GPP_F4      0x02050004
> +#define GPIO_SKL_LP_GPP_F5      0x02050005
> +#define GPIO_SKL_LP_GPP_F6      0x02050006
> +#define GPIO_SKL_LP_GPP_F7      0x02050007
> +#define GPIO_SKL_LP_GPP_F8      0x02050008
> +#define GPIO_SKL_LP_GPP_F9      0x02050009
> +#define GPIO_SKL_LP_GPP_F10     0x0205000A
> +#define GPIO_SKL_LP_GPP_F11     0x0205000B
> +#define GPIO_SKL_LP_GPP_F12     0x0205000C
> +#define GPIO_SKL_LP_GPP_F13     0x0205000D
> +#define GPIO_SKL_LP_GPP_F14     0x0205000E
> +#define GPIO_SKL_LP_GPP_F15     0x0205000F
> +#define GPIO_SKL_LP_GPP_F16     0x02050010
> +#define GPIO_SKL_LP_GPP_F17     0x02050011
> +#define GPIO_SKL_LP_GPP_F18     0x02050012
> +#define GPIO_SKL_LP_GPP_F19     0x02050013
> +#define GPIO_SKL_LP_GPP_F20     0x02050014
> +#define GPIO_SKL_LP_GPP_F21     0x02050015
> +#define GPIO_SKL_LP_GPP_F22     0x02050016
> +#define GPIO_SKL_LP_GPP_F23     0x02050017
> +#define GPIO_SKL_LP_GPP_G0      0x02060000
> +#define GPIO_SKL_LP_GPP_G1      0x02060001
> +#define GPIO_SKL_LP_GPP_G2      0x02060002
> +#define GPIO_SKL_LP_GPP_G3      0x02060003
> +#define GPIO_SKL_LP_GPP_G4      0x02060004
> +#define GPIO_SKL_LP_GPP_G5      0x02060005
> +#define GPIO_SKL_LP_GPP_G6      0x02060006
> +#define GPIO_SKL_LP_GPP_G7      0x02060007
> +#define GPIO_SKL_LP_GPD0        0x02070000
> +#define GPIO_SKL_LP_GPD1        0x02070001
> +#define GPIO_SKL_LP_GPD2        0x02070002
> +#define GPIO_SKL_LP_GPD3        0x02070003
> +#define GPIO_SKL_LP_GPD4        0x02070004
> +#define GPIO_SKL_LP_GPD5        0x02070005
> +#define GPIO_SKL_LP_GPD6        0x02070006
> +#define GPIO_SKL_LP_GPD7        0x02070007
> +#define GPIO_SKL_LP_GPD8        0x02070008
> +#define GPIO_SKL_LP_GPD9        0x02070009
> +#define GPIO_SKL_LP_GPD10       0x0207000A
> +#define GPIO_SKL_LP_GPD11       0x0207000B
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
> new file mode 100644
> index 0000000000..6730b3baf9
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
> @@ -0,0 +1,54 @@
> +/** @file
> +  Macros that simplify accessing PCH devices's PCI registers.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_ACCESS_H_
> +#define _PCH_ACCESS_H_
> +
> +#include "PchLimits.h"
> +#include "PchReservedResources.h"
> +
> +#ifndef STALL_ONE_MICRO_SECOND
> +#define STALL_ONE_MICRO_SECOND 1
> +#endif
> +#ifndef STALL_ONE_SECOND
> +#define STALL_ONE_SECOND 1000000
> +#endif
> +
> +//
> +// Include device register definitions
> +//
> +#include "PcieRegs.h"
> +#include "Register/PchRegs.h"
> +#include "Register/PchRegsPcr.h"
> +#include "Register/PchRegsP2sb.h"
> +#include "Register/PchRegsHda.h"
> +#include "Register/PchRegsHsio.h"
> +#include "Register/PchRegsLan.h"
> +#include "Register/PchRegsLpc.h"
> +#include "Register/PchRegsPmc.h"
> +#include "Register/PchRegsPcie.h"
> +#include "Register/PchRegsSata.h"
> +#include "Register/PchRegsSmbus.h"
> +#include "Register/PchRegsSpi.h"
> +#include <Register/RegsUsb.h>
> +#include "Register/PchRegsGpio.h"
> +#include "Register/PchRegsThermalCnl.h"
> +#include "Register/PchRegsGpioCnl.h"
> +#include "Register/PchRegsSerialIoCnl.h"
> +#include "Register/PchRegsSerialIo.h"
> +#include "Register/PchRegsTraceHub.h"
> +#include "Register/PchRegsScsCnl.h"
> +#include "Register/PchRegsIsh.h"
> +#include "Register/PchRegsDmi.h"
> +#include "Register/PchRegsItss.h"
> +#include "Register/PchRegsPsth.h"
> +#include "Register/PchRegsFia.h"
> +#include "Register/PchRegsDci.h"
> +
> +#endif
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
> new file mode 100644
> index 0000000000..3b8e5147db
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
> @@ -0,0 +1,38 @@
> +/** @file
> +  Header file for HD Audio configuration.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HDA_H_
> +#define _PCH_HDA_H_
> +
> +
> +enum PCH_HDAUDIO_DMIC_TYPE {
> +  PchHdaDmicDisabled = 0,
> +  PchHdaDmic2chArray = 1,
> +  PchHdaDmic4chArray = 2,
> +  PchHdaDmic1chArray = 3
> +};
> +
> +typedef enum {
> +  PchHdaLinkFreq6MHz  = 0,
> +  PchHdaLinkFreq12MHz = 1,
> +  PchHdaLinkFreq24MHz = 2,
> +  PchHdaLinkFreq48MHz = 3,
> +  PchHdaLinkFreq96MHz = 4,
> +  PchHdaLinkFreqInvalid
> +} PCH_HDAUDIO_LINK_FREQUENCY;
> +
> +typedef enum  {
> +  PchHdaIDispMode2T  = 0,
> +  PchHdaIDispMode1T  = 1,
> +  PchHdaIDispMode4T  = 2,
> +  PchHdaIDispMode8T  = 3,
> +  PchHdaIDispMode16T = 4,
> +  PchHdaIDispTModeInvalid
> +} PCH_HDAUDIO_IDISP_TMODE;
> +
> +#endif // _PCH_HDA_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
> new file mode 100644
> index 0000000000..743dd84b2b
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
> @@ -0,0 +1,80 @@
> +/** @file
> +  This file contains definitions of PCH Info HOB.
> +
> +  Copyright (c) 2019 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  2
> +
> +#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>:
> +  - Added LaneReversal Field
> +**/
> +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];
> +
> +  /**
> +    GbE over PCIe port number when GbE is enabled
> +    >0 - Root port number (1-based)
> +    0  - GbE over PCIe disabled
> +    This information needs to be passed through HOB as FIA registers
> +    are not accessible with POSTBOOT_SAI
> +  **/
> +  UINT8        GbePciePortNumber;
> +  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;
> +  /**
> +    This member specifies if lane reversal is enabled on the specific
> +    Pcie Root port controller.
> +  **/
> +  UINT8        PcieControllerLaneReversal[6];
> +} PCH_INFO_HOB;
> +
> +#pragma pack (pop)
> +
> +#endif // _PCH_INFO_HOB_H_
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
> new file mode 100644
> index 0000000000..929f9f02d4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  Build time limits of PCH resources.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_LIMITS_H_
> +#define _PCH_LIMITS_H_
> +
> +//
> +// 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
> +
> +//
> +// USB limits
> +//
> +#define PCH_MAX_USB2_PORTS                  16
> +#define PCH_MAX_USB3_PORTS                  10
> +
> +//
> +// SerialIo limits
> +//
> +#define PCH_MAX_SERIALIO_CONTROLLERS         12
> +#define PCH_MAX_SERIALIO_I2C_CONTROLLERS      6
> +#define PCH_MAX_SERIALIO_SPI_CONTROLLERS      3
> +#define PCH_MAX_SERIALIO_UART_CONTROLLERS     3
> +
> +//
> +// Number of eSPI slaves
> +//
> +#define PCH_MAX_ESPI_SLAVES                  2
> +
> +#endif // _PCH_LIMITS_H_
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
> new file mode 100644
> index 0000000000..1097e58332
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
> @@ -0,0 +1,47 @@
> +/** @file
> +  Definitions required to create PcieStorageInfoHob
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_PCIE_STORAGE_DETECT_HOB_
> +#define _PCH_PCIE_STORAGE_DETECT_HOB_
> +
> +#include "PchLimits.h"
> +
> +#define PCIE_STORAGE_INFO_HOB_REVISION              1
> +
> +extern EFI_GUID gPchPcieStorageDetectHobGuid;
> +
> +typedef enum {
> +  RstLinkWidthX1 = 1,
> +  RstLinkWidthX2 = 2,
> +  RstLinkWidthX4 = 4
> +} RST_LINK_WIDTH;
> +
> +//
> +//  Stores information about connected PCIe storage devices used later by
> BIOS setup and RST remapping
> +//
> +#pragma pack(1)
> +typedef struct {
> +  UINT8  Revision;
> +
> +  //
> +  // Stores the number of root ports occupied by a connected storage device,
> values from RST_LINK_WIDTH are supported
> +  //
> +  UINT8  PcieStorageLinkWidth[PCH_MAX_PCIE_ROOT_PORTS];
> +
> +  //
> +  // Programming interface value for a given device, 0x02 - NVMe or RAID, 0x1
> - AHCI storage, 0x0 - no device connected
> +  //
> +  UINT8  PcieStorageProgrammingInterface[PCH_MAX_PCIE_ROOT_PORTS];
> +
> +  //
> +  // Stores information about cycle router number under a given PCIe
> controller
> +  //
> +  UINT8  RstCycleRouterMap[PCH_MAX_PCIE_CONTROLLERS];
> +} PCIE_STORAGE_INFO_HOB;
> +#pragma pack()
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
> new file mode 100644
> index 0000000000..213ca91d2d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
> @@ -0,0 +1,47 @@
> +/** @file
> +  PCH configuration based on PCH policy
> +
> +  Copyright (c) 2019 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 <ConfigBlock/UsbConfig.h>
> +
> +#include "PchLimits.h"
> +#include "ConfigBlock/PchGeneralConfig.h"
> +#include "ConfigBlock/PcieRpConfig.h"
> +#include "ConfigBlock/SataConfig.h"
> +#include "ConfigBlock/IoApicConfig.h"
> +#include "ConfigBlock/DmiConfig.h"
> +#include "ConfigBlock/FlashProtectionConfig.h"
> +#include "ConfigBlock/HdAudioConfig.h"
> +#include "ConfigBlock/InterruptConfig.h"
> +#include "ConfigBlock/IshConfig.h"
> +#include "ConfigBlock/LanConfig.h"
> +#include "ConfigBlock/LockDownConfig.h"
> +#include "ConfigBlock/P2sbConfig.h"
> +#include "ConfigBlock/PmConfig.h"
> +#include "ConfigBlock/ScsConfig.h"
> +#include "ConfigBlock/SerialIoConfig.h"
> +#include "ConfigBlock/SerialIrqConfig.h"
> +#include "ConfigBlock/ThermalConfig.h"
> +#include "ConfigBlock/EspiConfig.h"
> +#include "ConfigBlock/CnviConfig.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/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.
> h
> new file mode 100644
> index 0000000000..37b2301770
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.
> h
> @@ -0,0 +1,59 @@
> +/** @file
> +  PCH configuration based on PCH policy
> +
> +  Copyright (c) 2019 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 "ConfigBlock/DciConfig.h"
> +#include "ConfigBlock/WatchDogConfig.h"
> +#include "ConfigBlock/PchTraceHubConfig.h"
> +#include "ConfigBlock/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/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
> new file mode 100644
> index 0000000000..f5106ffebb
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  PCH preserved MMIO resource definitions.
> +
> +  Copyright (c) 2019 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                      |
> +  | 88 KB       | 0xFE020000  | 0xFE035FFF  | SerialIo BAR in ACPI mode     |
> +  | 488 KB      | 0xFE036000  | 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     ///< 28MB
> +#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         0x00016000     ///< 88KB
> +#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_
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
> new file mode 100644
> index 0000000000..8e1495d16f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  PCH Reset Platform Specific definitions.
> +
> +  Copyright (c) 2019 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_
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:09 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add
> ConfigBlock headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds header files to Pch/Include/ConfigBlock.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
> |  69 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
> |  56 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
> |  43 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
> |  40 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionC
> onfig.h |  54 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
> |  39 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
> | 178 ++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
> |  57 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
> |  58 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
> |  66 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.
> h       |  58 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
> |  68 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
> |  57 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
> |  35 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.
> h        |  70 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
> |  34 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
> |  49 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfi
> g.h      |  71 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubCon
> fig.h     |  36 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
> | 429 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
> | 311 ++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
> | 230 +++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
> |  63 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
> |  96 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
> |  43 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
> |  52 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
> | 139 +++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.
> h        |  33 ++
>  28 files changed, 2534 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
> new file mode 100644
> index 0000000000..35fa125ba3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
> @@ -0,0 +1,69 @@
> +/** @file
> +  CNVI policy
> +
> +  Copyright (c) 2019 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 2
> +extern EFI_GUID gCnviConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  CNVi Mode options
> +**/
> +typedef enum {
> +  CnviModeDisabled = 0,
> +  CnviModeAuto
> +} CNVI_MODE;
> +
> +/**
> +  CNVi MfUart1 connection options
> +**/
> +typedef enum {
> +  CnviMfUart1Ish = 0,
> +  CnviMfUart1SerialIo,
> +  CnviBtUart1ExtPads,
> +  CnviBtUart1NotConnected
> +} CNVI_MFUART1_TYPE;
> +
> +
> +/**
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Remove BtInterface and BtUartType.
> +
> +**/
> +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;
> +  /**
> +    <b>(Test)</b> This option configures Uart type which connects to MfUart1
> +    For production configuration ISH is the default, for tests SerialIO Uart0 or
> external pads can be used
> +    Use CNVI_MFUART1_TYPE enum for selection
> +    <b>CnviMfUart1Ish = MfUart1 over ISH Uart0</b>,
> +    CnviMfUart1SerialIo = MfUart1 over SerialIO Uart2,
> +    CnviBtUart1ExtPads = MfUart1 over exteranl pads,
> +    CnviBtUart1NotConnected = MfUart1 not connected
> +  **/
> +  UINT32 MfUart1Type           :  2;
> +  UINT32 RsvdBits              : 29;
> +} PCH_CNVI_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _CNVI_CONFIG_H_
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
> new file mode 100644
> index 0000000000..791546bdfe
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
> @@ -0,0 +1,56 @@
> +/** @file
> +  Dci policy
> +
> +  Copyright (c) 2019 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 1
> +extern EFI_GUID gDciPreMemConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +typedef enum {
> +  ProbeTypeDisabled   = 0x0,
> +  ProbeTypeDciOobDbc  = 0x1,
> +  ProbeTypeDciOob     = 0x2,
> +  ProbeTypeUsb3Dbc    = 0x3,
> +  ProbeTypeXdp3       = 0x4,
> +  ProbeTypeUsb2Dbc    = 0x5,
> +  ProbeTypeMax
> +} PLATFORM_DEBUG_CONSENT_PROBE_TYPE;
> +
> +/**
> +  The PCH_DCI_PREMEM_CONFIG block describes policies related to Direct
> Connection Interface (DCI)
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
> +  /**
> +    Platform Debug Consent
> +    As a master switch to enable platform debug capability and relevant
> settings with specified probe type.
> +    Note: DCI OOB (aka BSSB) uses CCA probe; [DCI OOB+DbC] and [USB2 DbC]
> have the same setting.
> +    Refer to definition of PLATFORM_DEBUG_CONSENT_PROBE_TYPE
> +    <b>0:Disabled</b>; 1:DCI OOB+DbC; 2:DCI OOB; 3:USB3 DbC;
> 4:XDP3/MIPI60 5:USB2 DbC;
> +  **/
> +  UINT32    PlatformDebugConsent  :  3;
> +  /**
> +    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>
> +  **/
> +  UINT32    DciUsb3TypecUfpDbg    :  2;
> +  UINT32    RsvdBits              : 27;       ///< Reserved bits
> +} PCH_DCI_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _DCI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
> new file mode 100644
> index 0000000000..03f83d9bf8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
> @@ -0,0 +1,43 @@
> +/** @file
> +  DMI policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DMI_CONFIG_H_
> +#define _DMI_CONFIG_H_
> +
> +#define DMI_CONFIG_REVISION 3
> +extern EFI_GUID gDmiConfigGuid;
> +
> +
> +#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>:
> +  - Deprecate DmiAspm and add DmiAspmCtrl
> +  <b>Revision 3</b>
> +  - Added policy to enable/disable Central Write Buffer feature
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
> +  /**
> +    @deprecated since revision 2
> +  **/
> +
> +  UINT32     DmiAspm           :  1;
> +  UINT32     PwrOptEnable      :  1;    ///< <b>0: Disable</b>; 1: Enable DMI
> Power Optimizer on PCH side.
> +  UINT32     DmiAspmCtrl       :  8;    ///< ASPM configuration
> (PCH_PCIE_ASPM_CONTROL) on the PCH side of the DMI/OPI Link. Default is
> <b>PchPcieAspmAutoConfig</b>
> +  UINT32     CwbEnable         :  1;    ///< <b>0: Disable</b>; Central Write
> Buffer feature configurable and disabled by default
> +  UINT32     Rsvdbits          : 21;    ///< Reserved bits
> +} PCH_DMI_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _DMI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
> new file mode 100644
> index 0000000000..5de9b73397
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
> @@ -0,0 +1,40 @@
> +/** @file
> +  Espi policy
> +
> +  Copyright (c) 2019 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 1
> +extern EFI_GUID gEspiConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  This structure contains the policies which are related to ESPI.
> +**/
> +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;
> +  UINT32    RsvdBits              : 30;     ///< Reserved bits
> +} PCH_ESPI_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _ESPI_CONFIG_H_
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectio
> nConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectio
> nConfig.h
> new file mode 100644
> index 0000000000..2a6c19de7e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectio
> nConfig.h
> @@ -0,0 +1,54 @@
> +/** @file
> +  FlashProtection policy
> +
> +  Copyright (c) 2019 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
> +
> +/**
> +  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 {
> +  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;
> +
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +  PROTECTED_RANGE       ProtectRange[PCH_FLASH_PROTECTED_RANGES];
> +} PCH_FLASH_PROTECTION_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _FLASH_PROTECTION_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig
> .h
> new file mode 100644
> index 0000000000..2b32a21f54
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig
> .h
> @@ -0,0 +1,39 @@
> +/** @file
> +  GPIO device policy
> +
> +  Copyright (c) 2019 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
> +
> +} PCH_GPIO_DXE_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _PCH_GPIO_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfi
> g.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfi
> g.h
> new file mode 100644
> index 0000000000..a810d4f1fc
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfi
> g.h
> @@ -0,0 +1,178 @@
> +/** @file
> +  HDAUDIO policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _HDAUDIO_CONFIG_H_
> +#define _HDAUDIO_CONFIG_H_
> +
> +#include <PchHda.h>
> +
> +#define HDAUDIO_PREMEM_CONFIG_REVISION 1
> +#define HDAUDIO_CONFIG_REVISION 2
> +#define HDAUDIO_DXE_CONFIG_REVISION 2
> +
> +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 (PCH_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.
> +} PCH_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  {
> +  PCH_HDA_VERB_TABLE_HEADER  Header;
> +  UINT32 Data[];
> +} HDAUDIO_VERB_TABLE;
> +#ifdef _MSC_VER
> +#pragma warning (pop)
> +#endif
> +
> +/**
> +  This structure contains the policies which are related to HD Audio device
> (cAVS).
> +
> +  <b>Revision 1:</b>
> +  - Inital version.
> +  <b>Revision 2:</b>
> +  - Move DspEndpointDmic, DspEndpointBluetooth, DspEndpointI2s and
> DspFeatureMask to PCH_HDAUDIO_DXE_CONFIG
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
> +  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1:
> Enable</b>
> +  UINT32  Pme                   :  1;    ///< Azalia wake-on-ring, <b>0:
> Disable</b>; 1: Enable
> +  UINT32  VcType                :  1;    ///< Virtual Channel Type Select: <b>0:
> VC0</b>, 1: VC1
> +  UINT32  HdAudioLinkFrequency  :  4;    ///< HDA-Link frequency
> (PCH_HDAUDIO_LINK_FREQUENCY enum): <b>2: 24MHz</b>, 1: 12MHz, 0:
> 6MHz
> +  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
> +  /**
> +    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  IDispCodecDisconnect  :  1;    ///< iDisplay Audio Codec
> disconnection, <b>0: Not disconnected, enumerable</b>; 1: Disconnected SDI,
> not enumerable
> +  UINT32  CodecSxWakeCapability :  1;    ///< Capability to detect wake
> initiated by a codec in Sx (eg by modem codec), <b>0: Disable</b>; 1: Enable
> +  /**
> +    Audio Link Mode configuration bitmask.
> +    Allows to configure enablement of the following interfaces: HDA-Link,
> DMIC, SSP, SoundWire.
> +  **/
> +  UINT32  AudioLinkHda          :  1;    ///< HDA-Link enablement: 0: Disable;
> <b>1: Enable</b>. Muxed with SSP0/SSP1/SNDW1
> +  UINT32  AudioLinkDmic0        :  1;    ///< DMIC0 link enablement: 0:
> Disable; <b>1: Enable</b>. Muxed with SNDW4
> +  UINT32  AudioLinkDmic1        :  1;    ///< DMIC1 link enablement: 0:
> Disable; <b>1: Enable</b>. Muxed with SNDW3
> +  UINT32  AudioLinkSsp0         :  1;    ///< I2S/SSP0 link enablement: <b>0:
> Disable</b>; 1: Enable. Muxed with HDA SDI0
> +  UINT32  AudioLinkSsp1         :  1;    ///< I2S/SSP1 link enablement: <b>0:
> Disable</b>; 1: Enable. Muxed with HDA SDI1/SNDW2
> +  /**
> +    I2S/SSP2 link enablement: <b>0: Disable</b>; 1: Enable.
> +    @note Since the I2S/SSP2 pin set contains pads which are also used for
> CNVi purpose, enabling AudioLinkSsp2
> +    is exclusive with CNVi is present.
> +  **/
> +  UINT32  AudioLinkSsp2         :  1;
> +  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
> +  /**
> +    Soundwire Clock Buffer GPIO RCOMP adjustments based on bus topology:
> +    <b>0: non-ACT</b> - 50 Ohm driver impedance when bus topology does
> not have the external AC termination;
> +       1: ACT - 8 Ohm driver impedance when bus topology has the external AC
> termination.
> +  **/
> +  UINT32  SndwBufferRcomp       :  1;
> +  UINT32  RsvdBits0             :  4;    ///< Reserved bits 0
> +  UINT16  ResetWaitTimer;               ///< <b>(Test)</b> The delay timer
> after Azalia reset, the value is number of microseconds. Default is <b>600</b>.
> +  UINT8   Rsvd0;                        ///< Reserved bytes, align to multiple 4
> +  /**
> +    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;
> +  /**
> +    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;
> +} PCH_HDAUDIO_CONFIG;
> +
> +/**
> +  This structure contains the premem 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  Enable                : 1;     ///< Intel HD Audio (Azalia) enablement:
> 0: Disable, <b>1: Enable</b>
> +  UINT32  RsvdBits              : 31;    ///< Reserved bits 0
> +} PCH_HDAUDIO_PREMEM_CONFIG;
> +
> +/**
> +  This structure contains the DXE policies which are related to HD Audio
> device (cAVS).
> +
> +  <b>Revision 1:</b>
> +  - Inital version.
> +  <b>Revision 2:</b>
> +  - Add NhltDefaultFlow option for disabling NHLT flow from Si code.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
> +  /**
> +    AudioDSP/iSST endpoints configuration exposed via NHLT ACPI table:
> +  **/
> +  UINT32  DspEndpointDmic       :  2;    ///< DMIC Select
> (PCH_HDAUDIO_DMIC_TYPE enum): 0: Disable; 1: 2ch array; <b>2: 4ch
> array</b>; 3: 1ch array
> +  UINT32  DspEndpointBluetooth  :  1;    ///< Bluetooth enablement: <b>0:
> Disable</b>; 1: Enable
> +  UINT32  DspEndpointI2s        :  1;    ///< I2S enablement: <b>0:
> Disable</b>; 1: Enable
> +  UINT32  NhltDefaultFlow       :  1;    ///< Default Nhlt flow: 0: Disable, <b>1:
> Enable</b>
> +  UINT32  RsvdBits1             : 27;    ///< Reserved bits 1
> +  /**
> +    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;
> +} PCH_HDAUDIO_DXE_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _HDAUDIO_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
> new file mode 100644
> index 0000000000..8c3186153c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
> @@ -0,0 +1,57 @@
> +/** @file
> +  HSIO policy
> +
> +  Copyright (c) 2019 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
> +#define HSIO_CONFIG_REVISION 1
> +extern EFI_GUID gHsioPreMemConfigGuid; //@deprecated
> +extern EFI_GUID gHsioConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  The PCH_HSIO_PREMEM_CONFIG block provides HSIO message related
> settings. //@deprecated
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
> //@deprecated
> +
> +  /**
> +  <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 //@deprecated
> +  **/
> +  UINT32    ChipsetInitMessage :  1;
> +  /**
> +  <b>(Test)</b>
> +  <b>0- Disable</b>
> +  1- Enable When enabled, this is used to bypass the reset after ChipsetInit
> HECI message. //@deprecated
> +  **/
> +  UINT32    BypassPhySyncReset :  1;
> +  UINT32    RsvdBits           : 30;
> +} 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig
> .h
> new file mode 100644
> index 0000000000..93131ea07a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig
> .h
> @@ -0,0 +1,58 @@
> +/** @file
> +  HSIO pcie policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _HSIO_PCIE_CONFIG_H_
> +#define _HSIO_PCIE_CONFIG_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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfi
> g.h
> new file mode 100644
> index 0000000000..a79542d657
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfi
> g.h
> @@ -0,0 +1,66 @@
> +/** @file
> +  Hsio Sata policy
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfi
> g.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfi
> g.h
> new file mode 100644
> index 0000000000..788931b83d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfi
> g.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Interrupt policy
> +
> +  Copyright (c) 2019 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  64       ///< Number of all
> PCH devices
> +#define PCH_MAX_PXRC_CONFIG              8        ///< Number of PXRC
> registers in ITSS
> +
> +///
> +/// 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                        PxRcConfig[PCH_MAX_PXRC_CONFIG];
> ///< Array which stores interrupt routing for 8259 controller
> +  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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
> new file mode 100644
> index 0000000000..ce1d8f746d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
> @@ -0,0 +1,68 @@
> +/** @file
> +  IoApic policy
> +
> +  Copyright (c) 2019 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 2
> +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.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Add Enable8254ClockGatingOnS3.
> +
> +**/
> +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 PmcSet8254ClockGateState (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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
> new file mode 100644
> index 0000000000..d03ef377ce
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
> @@ -0,0 +1,57 @@
> +/** @file
> +  ISH policy
> +
> +  Copyright (c) 2019 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)
> +
> +///
> +/// The PCH_ISH_CONFIG block describes Integrated Sensor Hub device.
> +///
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;     ///< Config Block Header
> +  UINT32    SpiGpioAssign   :  1;   ///< ISH SPI GPIO pins assigned: <b>0:
> False</b> 1: True
> +  UINT32    Uart0GpioAssign :  1;   ///< ISH UART0 GPIO pins assigned: <b>0:
> False</b> 1: True
> +  UINT32    Uart1GpioAssign :  1;   ///< ISH UART1 GPIO pins assigned: <b>0:
> False</b> 1: True
> +  UINT32    I2c0GpioAssign  :  1;   ///< ISH I2C0 GPIO pins assigned: <b>0:
> False</b> 1: True
> +  UINT32    I2c1GpioAssign  :  1;   ///< ISH I2C1 GPIO pins assigned: <b>0:
> False</b> 1: True
> +  UINT32    I2c2GpioAssign  :  1;   ///< ISH I2C2 GPIO pins assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp0GpioAssign   :  1;   ///< ISH GP_0 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp1GpioAssign   :  1;   ///< ISH GP_1 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp2GpioAssign   :  1;   ///< ISH GP_2 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp3GpioAssign   :  1;   ///< ISH GP_3 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp4GpioAssign   :  1;   ///< ISH GP_4 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp5GpioAssign   :  1;   ///< ISH GP_5 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp6GpioAssign   :  1;   ///< ISH GP_6 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    Gp7GpioAssign   :  1;   ///< ISH GP_7 GPIO pin assigned: <b>0:
> False</b> 1: True
> +  UINT32    PdtUnlock       :  1;   ///< ISH PDT Unlock Msg: <b>0: False</b> 1:
> True
> +  UINT32    RsvdBits0       : 17;   ///< Reserved Bits
> +} PCH_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
> +} PCH_ISH_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _ISH_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
> new file mode 100644
> index 0000000000..6bf34f8fe7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
> @@ -0,0 +1,35 @@
> +/** @file
> +  Lan policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _LAN_CONFIG_H_
> +#define _LAN_CONFIG_H_
> +
> +#define LAN_CONFIG_REVISION 1
> +extern EFI_GUID gLanConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  PCH intergrated LAN controller configuration settings.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;  ///< Config Block Header
> +  /**
> +    Determines if enable PCH internal LAN, 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 register, 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
> +} PCH_LAN_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _LAN_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConf
> ig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConf
> ig.h
> new file mode 100644
> index 0000000000..a3a08c3cf6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConf
> ig.h
> @@ -0,0 +1,70 @@
> +/** @file
> +  Lock down policy
> +
> +  Copyright (c) 2019 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 RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the
> upper
> +    and lower 128-byte bank of RTC RAM. 0: Disable; <b>1: Enable</b>.
> +  **/
> +  UINT32  RtcMemoryLock  :  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;
> +  /**
> +    <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      : 27;             ///< Reserved bits
> +} PCH_LOCK_DOWN_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _LOCK_DOWN_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
> new file mode 100644
> index 0000000000..6ee9fe2d75
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
> @@ -0,0 +1,34 @@
> +/** @file
> +  Lpc policy
> +
> +  Copyright (c) 2019 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;
> +  UINT32    RsvdBits                    : 31;     ///< Reserved bits
> +} PCH_LPC_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _LPC_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
> new file mode 100644
> index 0000000000..5e1971cb9c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
> @@ -0,0 +1,49 @@
> +/** @file
> +  P2sb policy
> +
> +  Copyright (c) 2019 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 2
> +extern EFI_GUID gP2sbConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  This structure contains the policies which are related to P2SB device.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Deprecate SbiUnlock policy.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +  /**
> +    @deprecated from REVISION 2.
> +    <b>(Test)</b>
> +    This unlock the SBI lock bit to allow SBI after post time.
> +    For CFL: <b>0: Lock SBI</b>; 1: Unlock SBI.
> +    NOTE: Do not change this policy "SbiUnlock" unless its necessary.
> +  **/
> +  UINT32    SbiUnlock         :  1;
> +  /**
> +    <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          : 30;    ///< Reserved bits
> +} PCH_P2SB_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _P2SB_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralCo
> nfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralCo
> nfig.h
> new file mode 100644
> index 0000000000..67f9a121ca
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralCo
> nfig.h
> @@ -0,0 +1,71 @@
> +/** @file
> +  PCH General policy
> +
> +  Copyright (c) 2019 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 3
> +#define PCH_GENERAL_PREMEM_CONFIG_REVISION 1
> +
> +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 postmem general config block.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Remove SubSystemVendorId and SubSystemId.
> +  <b>Revision 3</b>:
> +  - Add LegacyIoLowLatency support.
> +**/
> +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 premem general config block.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +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    RsvdBits0       : 31;       ///< Reserved bits
> +} PCH_GENERAL_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _PCH_GENERAL_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubC
> onfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubC
> onfig.h
> new file mode 100644
> index 0000000000..36527a5af3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubC
> onfig.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  PCH Trace Hub policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_TRACEHUB_CONFIG_H_
> +#define _PCH_TRACEHUB_CONFIG_H_
> +
> +#define PCH_TRACEHUB_PREMEM_CONFIG_REVISION 1
> +extern EFI_GUID gPchTraceHubPreMemConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +///
> +/// The PCH_TRACE_HUB_CONFIG block describes TraceHub settings for PCH.
> +///
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
> +  UINT32  EnableMode         :  2;       ///< <b>0 = Disable</b>; 1 = Target
> Debugger mode; 2 = Host Debugger mode
> +  /**
> +  Pch Trace hub memory buffer region size policy.
> +  The avaliable memory size options are: <b>0:0MB (none)</b>, 1:1MB,
> 2:8MB, 3:64MB, 4:128MB, 5:256MB, 6:512MB.
> +  Refer to TRACE_BUFFER_SIZE in TraceHubCommon.h for supported
> settings.
> +  Note : Limitation of total buffer size (CPU + PCH) is 512MB.
> +  **/
> +  UINT32  MemReg0Size        :  8;
> +  UINT32  MemReg1Size        :  8;
> +  UINT32  RsvdBits0          : 14;       ///< Reserved bits
> +} PCH_TRACE_HUB_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _TRACEHUB_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
> new file mode 100644
> index 0000000000..7d23fcd15f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
> @@ -0,0 +1,429 @@
> +/** @file
> +  Pcie root port policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_PCIE_CONFIG_H_
> +#define _PCH_PCIE_CONFIG_H_
> +
> +#include <PchLimits.h>
> +
> +#define PCIE_RP_CONFIG_REVISION 3
> +#define PCIE_RP_PREMEM_CONFIG_REVISION 1
> +
> +extern EFI_GUID gPcieRpConfigGuid;
> +extern EFI_GUID gPcieRpPreMemConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +#define PCH_PCIE_SWEQ_COEFFS_MAX    5
> +
> +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;
> +
> +enum PCH_PCIE_SPEED {
> +  PchPcieAuto,
> +  PchPcieGen1,
> +  PchPcieGen2,
> +  PchPcieGen3
> +};
> +
> +///
> +/// 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
> +};
> +
> +enum PCH_PCIE_COMPLETION_TIMEOUT {
> +  PchPcieCompletionTO_Default,
> +  PchPcieCompletionTO_50_100us,
> +  PchPcieCompletionTO_1_10ms,
> +  PchPcieCompletionTO_16_55ms,
> +  PchPcieCompletionTO_65_210ms,
> +  PchPcieCompletionTO_260_900ms,
> +  PchPcieCompletionTO_1_3P5s,
> +  PchPcieCompletionTO_4_13s,
> +  PchPcieCompletionTO_17_64s,
> +  PchPcieCompletionTO_Disabled
> +};
> +
> +typedef enum {
> +  PchPcieEqDefault      = 0,  ///< @deprecated since revision 3. Behaves as
> PchPcieEqHardware.
> +  PchPcieEqHardware     = 1,  ///< Hardware equalization
> +  PchPcieEqStaticCoeff  = 4   ///< Fixed equalization (requires Coefficient
> settings per lane)
> +} PCH_PCIE_EQ_METHOD;
> +
> +/**
> +  Represent lane specific PCIe Gen3 equalization parameters.
> +**/
> +typedef struct {
> +  UINT8   Cm;                 ///< Coefficient C-1
> +  UINT8   Cp;                 ///< Coefficient C+1
> +  UINT8   Rsvd0[2];           ///< Reserved bytes
> +} PCH_PCIE_EQ_LANE_PARAM, PCH_PCIE_EQ_PARAM;
> +
> +
> +/**
> +  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 {
> +  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  ExtSync                         :  1;   ///< Indicate whether the
> extended synch is enabled. <b>0: Disable</b>; 1: Enable.
> +  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>.
> +  UINT32  RsvdBits0                       : 11;   ///< Reserved bits.
> +  /**
> +    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;
> +  //
> +  // 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
> PCH_PCIE_MAX_PAYLOAD
> +    Changes Max Payload Size Supported field in Device Capabilities of the
> root port.
> +  **/
> +  UINT32  MaxPayload                      :  2;
> +  UINT32  RsvdBits1                       :  1;   ///< Reserved fields for future
> expansion w/o protocol change
> +  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  RsvdBits3                       :  1;   ///< Placeholder for deleted field
> +  /**
> +    Determines each PCIE Port speed capability.
> +    <b>0: Auto</b>; 1: Gen1; 2: Gen2; 3: Gen3 (see: PCH_PCIE_SPEED)
> +  **/
> +  UINT8   PcieSpeed;
> +  /**
> +    PCIe Gen3 Equalization Phase 3 Method (see PCH_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: PCH_PCIE_COMPLETION_TIMEOUT).
> Default is <b>PchPcieCompletionTO_Default</b>.
> +  /**
> +    The PCH pin assigned to device PERST# signal if available, zero otherwise.
> +    This entry is used mainly in Gen3 software equalization flow. It is necessary
> for some devices
> +    (mainly some graphic adapters) to successfully complete the software
> equalization flow.
> +    See also DeviceResetPadActiveHigh
> +  **/
> +  UINT32  RsvdBytes0[2];                          ///< Reserved bytes
> +  //
> +  // Power Management
> +  //
> +  UINT8   Aspm;                                   ///< The ASPM configuration of the
> root port (see: PCH_PCIE_ASPM_CONTROL). Default is
> <b>PchPcieAspmAutoConfig</b> for CNP-LP B1 it is limited to
> <b>PchPcieAspmL1</b>.
> +  UINT8   L1Substates;                            ///< The L1 Substates
> configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL).
> Default is <b>PchPcieL1SubstatesL1_1_2</b>.
> +  UINT8   LtrEnable;                              ///< Latency Tolerance Reporting
> Mechanism. <b>0: Disable</b>; 1: Enable.
> +  UINT8   LtrConfigLock;                          ///< <b>0: Disable</b>; 1: Enable.
> +  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.
> +  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>.
> +  //
> +  // Gen3 Equalization settings
> +  //
> +  UINT32  Uptp                :  4;               ///< <b>(Test)</b> Upstream Port
> Transmitter Preset used during Gen3 Link Equalization. Used for all lanes.
> Default is <b>5</b>.
> +  UINT32  Dptp                :  4;               ///< <b>(Test)</b> Downstream
> Port Transmiter Preset used during Gen3 Link Equalization. Used for all lanes.
> Default is <b>7</b>.
> +  /**
> +    <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
> +  **/
> +  UINT32  ForceLtrOverride                :  1;
> +  UINT32  EnableCpm                       :  1;               ///< Enables Clock
> Power Management; even if disabled, CLKREQ# signal can still be controlled by
> L1 PM substates mechanism
> +  UINT32  PtmEnabled                      :  1;               ///< Enables PTM
> capability
> +  UINT32  PcieRootPortGen2PllL1CgDisable  :  1;               ///< Disables
> Gen2PLL shutdown and L1 state controller power gating
> +  UINT32  RsvdBits2                       :  6;               ///< Reserved Bits
> +  /**
> +    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;
> +  UINT16  RsvdBytes1[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>:
> +  - Init version
> +  <b>Revision 2</b>:
> +  - Add policy PcieRootPortGen2PllL1CgDisable in
> PCH_PCIE_ROOT_PORT_CONFIG.
> +  <b>Revision 3</b>:
> +  - Deleted all items related to PCIe Gen3 software equalization:
> +      DeviceResetPad, DeviceResetPadActiveHigh policies and two values from
> PCH_PCIE_EQ_METHOD enum used for Gen3EqPh3Method field
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +  ///
> +  /// These members describe the configuration of each PCH PCIe root port.
> +  ///
> +  PCH_PCIE_ROOT_PORT_CONFIG
> RootPort[PCH_MAX_PCIE_ROOT_PORTS];
> +  ///
> +  /// Configuration of PCIe source clocks
> +  ///
> +  PCH_PCIE_CLOCK                    PcieClock[PCH_MAX_PCIE_CLOCKS];
> +  ///
> +  /// 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).
> +  ///
> +  PCH_PCIE_EQ_LANE_PARAM
> EqPh3LaneParam[PCH_MAX_PCIE_ROOT_PORTS];
> +  ///
> +  /// List of coefficients used during equalization (applicable to both software
> and hardware EQ)
> +  ///
> +  PCH_PCIE_EQ_PARAM
> SwEqCoeffList[PCH_PCIE_SWEQ_COEFFS_MAX];
> +  PCH_PCIE_EQ_PARAM                 Rsvd0[3];
> +  ///
> +  /// <b>(Test)</b> This member describes whether PCIE root port Port 8xh
> Decode is enabled. <b>0: Disable</b>; 1: Enable.
> +  ///
> +  UINT32  EnablePort8xhDecode              :  1;
> +  ///
> +  /// <b>(Test)</b> The Index of PCIe Port that is selected for Port8xh Decode
> (0 Based)
> +  ///
> +  UINT32  PchPciePort8xhDecodePortIndex    :  5;
> +  ///
> +  /// 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  DisableRootPortClockGating       :  1;
> +  ///
> +  /// This member describes whether Peer Memory Writes are enabled on the
> platform. <b>0: Disable</b>; 1: Enable.
> +  ///
> +  UINT32  EnablePeerMemoryWrite            :  1;
> +  /**
> +    Compliance Test Mode shall be enabled when using Compliance Load
> Board.
> +    <b>0: Disable</b>, 1: Enable
> +  **/
> +  UINT32  ComplianceTestMode               :  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;
> +
> +  UINT32  RsvdBits0                        : 22;
> +  /**
> +    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:
> +    PCH_PCIE_DEVICE_OVERRIDE *PcieDeviceOverrideTablePtr;
> +  **/
> +  UINT32  PcieDeviceOverrideTablePtr;
> +
> +} PCH_PCIE_CONFIG;
> +
> +/**
> +  The PCH_PCIE_RP_PREMEM_CONFIG block describes early configuration of
> the PCH PCI Express controllers
> +  <b>Revision 1</b>:
> +  - Init version
> +  - Add RpEnable in premem phase.
> +**/
> +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;
> +  UINT16                PcieImrSize;                           ///< PCIe IMR size in
> megabytes
> +  UINT8                 PcieImrEnabled;                        ///< PCIe IMR. <b>0:
> Disable</b>; 1: Enable.
> +  UINT8                 ImrRpSelection;                        ///< Index of PCIe root
> port that is selected for IMR (0 based)
> +} PCH_PCIE_RP_PREMEM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _PCH_PCIE_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
> new file mode 100644
> index 0000000000..8748db5e1a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
> @@ -0,0 +1,311 @@
> +/** @file
> +  Power Management policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PM_CONFIG_H_
> +#define _PM_CONFIG_H_
> +
> +#define PM_CONFIG_REVISION 5
> +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,
> +} 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,
> +  S0ixDisQAuto,
> +  S0ixDisQMax,
> +} S0IX_DISQ_PROBE_TYPE;
> +
> +typedef enum {
> +  SlpS0OverrideDisabled  = 0x0,
> +  SlpS0OverrideEnabled   = 0x1,
> +  SlpS0OverrideAuto      = 0x2,
> +  SlpS0OverrideMax
> +} SLP_S0_OVERRIDE;
> +
> +/**
> +  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>:
> +  - Add PsOnEnable and PowerButtonDebounce.
> +  <b>Revision 3</b>:
> +  - Add CpuC10GatePinEnable in PCH_PM_CONFIG.
> +  <b>Revision 4</b>:
> +  - Add PmcDbgMsgEn.
> +  - Removed PmcReadDisable in PCH_PM_CONFIG.
> +  <b>Revision 5</b>:
> +  - Add ModPhySusPgEnable
> +  <b>Revision 6</b>:
> +  - Add SlpS0WithGbeSupport
> +**/
> +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. 0: Disable; <b>1: Enable</b>
> +  **/
> +  UINT32                  LpcClockRun          :  1;         /// 0: Disable; <b>1:
> Enable</b>
> +  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;
> +  /**
> +    Indicates whether SLP_S0# is to be asserted when PCH reaches idle state.
> +    When set to one SLP_S0# will be asserted in idle state.
> +    When set to zero SLP_S0# will not toggle and is always drivern high.
> +    0:Disable, <b>1:Enable</b>
> +
> +    If a platform is using SLP_S0 to lower PCH voltage the below policy must be
> disabled.
> +  **/
> +  UINT32                  SlpS0Enable                  :  1;
> +  /**
> +    SLP_S0 Voltage Margining Runtime Control.
> +    PCH VCCPRIM_CORE Voltage Margining is under ACPI control. Software in
> runtime
> +    may change VCCPRIM_CORE supply voltage based on conditions like
> HDAudio power state
> +    after SLP_S0# assertion. Enable VM runtime control requires ACPI VMON
> method
> +    which will allow configuring VCCPRIM_CORE supply voltage. If this
> configuration is used
> +    ACPI VMON method needs to be provided as it is not implemented in RC.
> +    This setting is dependent on PMIC/VR type used on the platform.
> +    <b>0: Disable</b>; 1: Enable.
> +  **/
> +  UINT32                  SlpS0VmRuntimeControl        :  1;
> +  /**
> +    SLP_S0 0.70V Voltage Margining Support.
> +    Indicates whether SLP_S0# Voltage Margining supports setting PCH
> VCCPRIM_CORE down to 0.70V.
> +    This setting is dependent on PMIC/VR type used on the platform.
> +    <b>0: Disable</b>; 1: Enable.
> +  **/
> +  UINT32                  SlpS0Vm070VSupport           :  1;
> +  /**
> +    SLP_S0 0.75V Voltage Margining Support.
> +    Indicates whether SLP_S0# Voltage Margining supports setting PCH
> VCCPRIM_CORE down to 0.75V.
> +    This setting is dependent on PMIC/VR type used on the platform.
> +    <b>0: Disable</b>; 1: Enable.
> +  **/
> +  UINT32                  SlpS0Vm075VSupport           :  1;
> +  /**
> +    Decide if SLP_S0# needs to be overriden (de-asserted) when system is in
> debug mode. This is available since CNP-B0.
> +    Select 'Auto', it will be auto-configured according to probe type. Select
> 'Enabled' will disable SLP_S0# assertion whereas 'Disabled' will enable SLP_S0#
> assertion when debug is enabled.
> +    This policy should keep 'Auto', other options are intended for advanced
> configuration only.
> +    please refer to SLP_S0_OVERRIDE
> +    0: Disable; 1: Enable; <b>2:Auto</b>
> +  **/
> +  UINT32                  SlpS0Override                :  2;
> +  /**
> +    SLP_S0# disqualify for debug prode
> +    used to configure power management setting per debug probe to be
> disqualified from S0ix.
> +    Reminder: USB3 DbC supports S0 only. DCI OOB (aka BSSB) uses CCA probe
> +    Select 'Auto', it will be auto-configured according to probe type. 'No
> Change' will keep PMC default settings. Or select the desired debug probe type
> for S0ix Override settings.\nReminder: USB3 DbC supports S0 only. DCI OOB
> (aka BSSB) uses CCA probe.
> +    Note: This policy should keep 'Auto', other options are intended for
> advanced configuration only.
> +    please refer to S0IX_DISQ_PROBE_TYPE
> +    0: No Probe; 1: DCI OOB; 2: USB2 DbC; <b>3:Auto</b>
> +  **/
> +  UINT32                  SlpS0DisQForDebug            :  3;
> +  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;
> +  /**
> +    Enable/Disable SLP_S0 with GBE Support. This policy is ignored when GbE
> is not present.
> +    0: Disable; <b>1: Enable</b>.
> +    Default is 0 when paired with WHL V0 stepping CPU and 1 for all other
> CPUs.
> +  **/
> +  UINT32                  SlpS0WithGbeSupport          :  1;
> +
> +  UINT32                  RsvdBits1                    :  5;
> +  /*
> +    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;
> +  UINT8                   Rsvd0[2];                             ///< Reserved bytes
> +
> +} PCH_PM_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _PM_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
> new file mode 100644
> index 0000000000..ce1013b05e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
> @@ -0,0 +1,230 @@
> +/** @file
> +  Sata policy
> +
> +  Copyright (c) 2019 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 2
> +extern EFI_GUID gSataConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +typedef enum  {
> +  PchSataModeAhci,
> +  PchSataModeRaid,
> +  PchSataModeMax
> +} PCH_SATA_MODE;
> +
> +typedef enum {
> +  PchSataOromDelay2sec,
> +  PchSataOromDelay4sec,
> +  PchSataOromDelay6sec,
> +  PchSataOromDelay8sec
> +} PCH_SATA_OROM_DELAY;
> +
> +typedef enum {
> +  PchSataSpeedDefault,
> +  PchSataSpeedGen1,
> +  PchSataSpeedGen2,
> +  PchSataSpeedGen3
> +} PCH_SATA_SPEED;
> +
> +typedef enum {
> +  PchSataRstMsix,
> +  PchSataRstMsi,
> +  PchSataRstLegacy
> +} PCH_SATA_RST_INTERRUPT;
> +
> +typedef enum {
> +  PchSataRaidClient,
> +  PchSataRaidAlternate,
> +  PchSataRaidServer
> +} PCH_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  RsvdBits0        :  9;                  ///< Reserved fields for future
> expansion w/o protocol change
> +} PCH_SATA_PORT_CONFIG;
> +
> +/**
> +  Rapid Storage Technology settings.
> +**/
> +typedef struct {
> +  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  : PCH_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
> +  /**
> +    This option allows to configure SATA controller device ID while in RAID
> mode.
> +    Refer to PCH_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
> +  **/
> +  UINT32  RaidDeviceId       :  2;
> +  /**
> +    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>
> +  **/
> +  UINT32  SataRstInterrupt   :  2;
> +  UINT32  RsvdBits0          : 13;         ///< Reserved Bits
> +} PCH_SATA_RST_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;
> +
> +/**
> +  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, the assignments are as below:
> +    i.)   RST PCIe Storage Cycle Router 2 -> RP5 - RP8
> +    ii.)  RST PCIe Storage Cycle Router 3 -> RP9 - RP12
> +
> +    i.)   RST PCIe Storage Cycle Router 1 -> RP9  - RP12
> +    ii.)  RST PCIe Storage Cycle Router 2 -> RP13 - RP16
> +    iii.) RST PCIe Storage Cycle Router 3 -> RP17 - RP20
> +  **/
> +  UINT32   RstPcieStoragePort     :  5;
> +  UINT32   RsvdBits0              :  2; ///< Reserved bit
> +  /**
> +    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   RsvdBits1              : 16; ///< Reserved bits
> +
> +  UINT32   Rsvd0[2];                    ///< Reserved bytes
> +} PCH_RST_PCIE_STORAGE_CONFIG;
> +
> +/**
> +  The PCH_SATA_CONFIG block describes the expected configuration of the
> SATA controllers.
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Add CpuAttachedStorage in PCH_SATA_RST_CONFIG.
> +**/
> +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>.
> +  ///
> +  UINT32                        Enable          :  1;
> +  UINT32                        TestMode        :  1;       ///< <b>(Test)</b> <b>0:
> Disable</b>; 1: Allow entrance to the PCH SATA test modes
> +  UINT32                        SalpSupport     :  1;       ///< 0: Disable; <b>1:
> Enable</b> Aggressive Link Power Management
> +  UINT32                        PwrOptEnable    :  1;       ///< 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
> +  **/
> +  UINT32                        EsataSpeedLimit :  1;
> +  UINT32                        LedEnable       :  1;       ///< SATA LED indicates
> SATA controller activity. 0: Disable; <b>1: Enable</b> SATA LED.
> +  UINT32                        RsvdBits0       : 26;       ///< Reserved bits
> +
> +  /**
> +    Determines the system will be configured to which SATA mode
> (PCH_SATA_MODE). Default is <b>PchSataModeAhci</b>.
> +  **/
> +  PCH_SATA_MODE                 SataMode;
> +  /**
> +    Indicates the maximum speed the SATA controller can support
> +    <b>0h: PchSataSpeedDefault</b>; 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2);
> 3h: 6 Gb/s (Gen 1)
> +  **/
> +  PCH_SATA_SPEED                SpeedLimit;
> +  /**
> +    This member configures the features, property, and capability for each
> SATA port.
> +  **/
> +  PCH_SATA_PORT_CONFIG          PortSettings[PCH_MAX_SATA_PORTS];
> +  PCH_SATA_RST_CONFIG           Rst;                        ///< Setting
> applicable to Rapid Storage Technology
> +  /**
> +    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
> +  **/
> +  PCH_RST_PCIE_STORAGE_CONFIG
> RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
> +  /**
> +    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;
> +} PCH_SATA_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _SATA_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
> new file mode 100644
> index 0000000000..1e91143b93
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
> @@ -0,0 +1,63 @@
> +/** @file
> +  Scs policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SCS_CONFIG_H_
> +#define _SCS_CONFIG_H_
> +
> +#include <ConfigBlock.h>
> +
> +#define SCS_CONFIG_REVISION 2
> +extern EFI_GUID gScsConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +typedef enum {
> +  DriverStrength33Ohm = 0,
> +  DriverStrength40Ohm,
> +  DriverStrength50Ohm
> +} PCH_SCS_EMMC_DRIVER_STRENGTH;
> +
> +/**
> +  The PCH_SCS_CONFIG block describes Storage and Communication
> Subsystem (SCS) settings for PCH.
> +
> +  <b>Revision 1</b>:
> +  - Initial version
> +  <b>Revision 2</b>:
> +  - Add policy SdCardPowerEnableActiveHigh
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +
> +  UINT32    ScsEmmcEnabled                :  2;   ///< Determine if eMMC is
> enabled - 0: Disabled, <b>1: Enabled</b>.
> +  UINT32    ScsEmmcHs400Enabled           :  1;   ///< Determine eMMC
> HS400 Mode if ScsEmmcEnabled - <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    ScsEmmcHs400TuningRequired    :  1;
> +  UINT32    ScsEmmcHs400DllDataValid      :  1;   ///< Set if HS400 Tuning
> Data Valid
> +  UINT32    ScsEmmcHs400RxStrobeDll1      :  7;   ///< Rx Strobe Delay
> Control - Rx Strobe Delay DLL 1 (HS400 Mode)
> +  UINT32    ScsEmmcHs400TxDataDll         :  7;   ///< Tx Data Delay Control 1
> - Tx Data Delay (HS400 Mode)
> +  UINT32    ScsEmmcHs400DriverStrength    :  3;   ///< I/O driver strength: 0
> - 33 Ohm, <b>1 - 40 Ohm</b>, 2 - 50 Ohm
> +  /**
> +    Sd Card Controler 0: Disable; <b>1: Enable</b>.
> +    For Desktop sku, the SD Card Controller POR should be disabled. <b>
> 0:Disable </b>.
> +  **/
> +  UINT32    ScsSdcardEnabled              :  1;
> +  UINT32    ScsUfsEnabled                 :  1;   ///< Determine if Ufs is enabled
> 0: Disabled 1: Enabled
> +  UINT32    SdCardPowerEnableActiveHigh   :  1;   ///< Determine
> SD_PWREN# polarity 0: Active low, <b>1: Active high</b>
> +  UINT32    RsvdBits                      :  7;
> +  UINT32    Rsvd0;                                ///< Reserved bytes
> +} PCH_SCS_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _SCS_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.
> h
> new file mode 100644
> index 0000000000..73dfd17c47
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.
> h
> @@ -0,0 +1,96 @@
> +/** @file
> +  Serial IO policy
> +
> +  Copyright (c) 2019 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 2
> +extern EFI_GUID gSerialIoConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +/**
> +  The PCH_SERIAL_IO_CONFIG block provides the configurations to set the
> Serial IO controllers
> +
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Add I2cPadsTermination
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                             ///< Config Block
> Header
> +  /**
> +       0: Disabled;
> +          - Device is placed in D3
> +          - Gpio configuration is skipped
> +          - Device will be disabled in PSF
> +          - !important! If given device is Function 0 and not all other LPSS
> functions on given device
> +                        are disabled, then 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: Pci</b>;
> +          - Gpio pin configuration in native mode for each assigned pin
> +            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
> +          - Device will be enabled in PSF
> +          - Only Bar 0 will be enabled
> +       2: Acpi;
> +          - Gpio pin configuration in native mode for each assigned pin
> +            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
> +          - Device will be hidden in PSF and not available to PCI enumerator
> +          - Both BARs are enabled, BAR1 becomes devices Pci config Space
> +    @note Intel does not provide Windows SerialIo drivers for this mode
> +       3: Hidden;
> +          Designated for Kernel Debug and Legacy UART configuartion, might
> also be used for IO Expander on I2C
> +          - Device is placed in D0
> +          - Gpio pin configuration in native mode for each assigned pin
> +            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
> +          - Device will be hidden in PSF and not available to PCI enumerator
> +          - Both BARs are enabled, BAR1 becomes devices Pci config Space
> +          - !important! In this mode UART will work in 16550 Legacy 8BIT Mode,
> it's resources will be assigned to mother board through ACPI (PNP0C02)
> +    @note Considering the PcdSerialIoUartDebugEnable and
> PcdSerialIoUartNumber for all SerialIo UARTx,
> +          the PCD is more meaningful to represent the board design. It means,
> if PcdSerialIoUartDebugEnable is not 0,
> +          the board is designed to use the SerialIo UART for debug message and
> the PcdSerialIoUartNumber is dedicated
> +          to be Debug UART usage. Therefore, it should grayout the option from
> setup menu since no other options
> +          available for this UART controller on this board, and also override the
> policy default accordingly.
> +          While PcdSerialIoUartDebugEnable is 0, then it's allowed to configure
> the UART controller by policy.
> +  **/
> +  UINT8  DevMode[PCH_MAX_SERIALIO_CONTROLLERS];
> +  UINT8  SpiCsPolarity[PCH_MAX_SERIALIO_SPI_CONTROLLERS];   ///<
> Selects SPI ChipSelect signal polarity, <b>0=active low</b>.
> +  UINT8  UartHwFlowCtrl[PCH_MAX_SERIALIO_UART_CONTROLLERS]; ///<
> Enables UART hardware flow control, CTS and RTS lines, <b>0:disabled</b>,
> 1:enabled
> +  /**
> +    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  I2cPadsTermination[PCH_MAX_SERIALIO_I2C_CONTROLLERS];
> +  /**
> +    UART device for debug purpose. 0:UART0, 1: UART1, <b>2:UART2</b>
> +    @note If CNVi solution is on the platform and UART0 is selected as BT Core
> interface,
> +          UART0 cannot be used for debug purpose.
> +  **/
> +  UINT32 DebugUartNumber           :  2;
> +  UINT32 EnableDebugUartAfterPost  :  1;                    ///< Enable debug
> UART controller after post. 0: diabled, <b>1: enabled</b>
> +  /**
> +    <b>0: default pins</b>; 1: pins muxed with CNV_BRI/RGI
> +    UART0 can be configured to use two different sets of pins:
> +    This setting gives flexibility to use UART0 functionality on other pins when
> +    default ones are used for a different purpose.
> +    @note Since the second pin set contains pads which are also used for CNVi
> purpose, setting Uart0PinMuxing
> +    is exclusive with CNVi being enabled.
> +  **/
> +  UINT32 Uart0PinMuxing            :  1;
> +  UINT32 RsvdBits0                 : 28;
> +} PCH_SERIAL_IO_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _SERIAL_IO_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig
> .h
> new file mode 100644
> index 0000000000..7ccfe65428
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig
> .h
> @@ -0,0 +1,43 @@
> +/** @file
> +  Serial IRQ policy
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SERIAL_IRQ_CONFIG_H_
> +#define _SERIAL_IRQ_CONFIG_H_
> +
> +#define SERIAL_IRQ_CONFIG_REVISION 1
> +extern EFI_GUID gSerialIrqConfigGuid;
> +
> +#pragma pack (push,1)
> +
> +typedef enum {
> +  PchQuietMode,
> +  PchContinuousMode
> +} PCH_SIRQ_MODE;
> +///
> +/// Refer to PCH EDS for the details of Start Frame Pulse Width in Continuous
> and Quiet mode
> +///
> +typedef enum {
> +  PchSfpw4Clk,
> +  PchSfpw6Clk,
> +  PchSfpw8Clk
> +} PCH_START_FRAME_PULSE;
> +
> +///
> +/// The PCH_LPC_SIRQ_CONFIG block describes the expected configuration of
> the PCH for Serial IRQ.
> +///
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
> +  UINT32                SirqEnable      :  1;     ///< Determines if enable Serial
> IRQ. 0: Disable; <b>1: Enable</b>.
> +  UINT32                SirqMode        :  2;     ///< Serial IRQ Mode Select. Refer
> to PCH_SIRQ_MODE for each value. <b>0: quiet mode</b> 1: continuous
> mode.
> +  UINT32                StartFramePulse :  3;     ///< Start Frame Pulse Width.
> Refer to PCH_START_FRAME_PULSE for each value. Default is
> <b>PchSfpw4Clk</b>.
> +  UINT32                RsvdBits0       : 26;     ///< Reserved bits
> +} PCH_LPC_SIRQ_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _SERIAL_IRQ_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
> new file mode 100644
> index 0000000000..d96cf9f6cd
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
> @@ -0,0 +1,52 @@
> +/** @file
> +  Smbus policy
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig
> .h
> new file mode 100644
> index 0000000000..d3ea563f95
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig
> .h
> @@ -0,0 +1,139 @@
> +/** @file
> +  Thermal policy
> +
> +  Copyright (c) 2019 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;
> +
> +/**
> +  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
> +  **/
> +  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 PCH_THERMAL_CONFIG block describes the expected configuration of
> the PCH for Thermal.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
> +  /**
> +    This locks down "SMI Enable on Alert Thermal Sensor Trip". 0: Disabled, 1:
> <b>Enabled</b>.
> +  **/
> +  UINT32  TsmicLock               :  1;
> +  UINT32  PchHotEnable            :  1; ///< Enable PCHHOT# pin assertion
> when temperature is higher than PchHotLevel. 0: <b>Disabled<b>, 1: Enabled.
> +  UINT32  RsvdBits0               : 30;
> +  /**
> +    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;
> +  /**
> +    This field decides the temperature, default is <b>0x154</b>.
> +    The recommendation is the same as Cat Trip point.
> +  **/
> +  UINT16                    PchHotLevel;
> +  UINT8                     Rsvd0[6];
> +} PCH_THERMAL_CONFIG;
> +
> +#pragma pack (pop)
> +
> +#endif // _THERMAL_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConf
> ig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConf
> ig.h
> new file mode 100644
> index 0000000000..78e4497d90
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConf
> ig.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  WatchDog policy
> +
> +  Copyright (c) 2019 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_
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:09 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add
> Library include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the following header files:
>  * Pch/Include/library
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h         |
> 27 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h             |
> 24 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
> |  58 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
> | 265 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h             |
> 788 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
> | 166 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h            |
> 33 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.
> h | 371 +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h          |
> 141 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h           |
> 36 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h          |
> 109 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h          |
> 407 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
> | 105 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h           |
> 226 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h           |
> 45 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h        |
> 114 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h         |
> 24 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
> | 116 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h      |
> 240 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
> | 111 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
> |  23 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
> | 121 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h              |
> 207 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h             |
> 76 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h           |
> 22 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
> |  98 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h              |
> 23 +
>  27 files changed, 3976 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
> new file mode 100644
> index 0000000000..ee77334ecb
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
> @@ -0,0 +1,27 @@
> +/** @file
> +  Header file for BiosLockLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _BIOSLOCK_LIB_H_
> +#define _BIOSLOCK_LIB_H_
> +
> +/**
> +  Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable In
> SMM.STS).
> +  When this is set, attempts to write the WPD (Write Protect Disable) bit in
> PCH
> +  will cause a SMI which will allow the BIOS to verify that the write is from a
> valid source.
> +
> +  Bios should always enable LockDownConfig.BiosLock policy to set Bios Lock
> bit in FRC.
> +  If capsule udpate is enabled, it's expected to not do BiosLock by setting
> BiosLock policy disable
> +  so it can udpate BIOS region.
> +  After flash update, it should utilize this lib to do BiosLock for security.
> +**/
> +VOID
> +BiosLockEnable (
> +  VOID
> +  );
> +
> +#endif // _BIOSLOCK_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
> new file mode 100644
> index 0000000000..f406e0d929
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
> @@ -0,0 +1,24 @@
> +/** @file
> +  Header file for CnviLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CNVI_LIB_H_
> +#define _CNVI_LIB_H_
> +
> +/**
> +  Check if CNVi is present.
> +
> +  @retval TRUE                    CNVi is enabled
> +  @retval FALSE                   CNVi is disabled
> +
> +**/
> +BOOLEAN
> +CnviIsPresent (
> +  VOID
> +  );
> +
> +#endif // _CNVI_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
> new file mode 100644
> index 0000000000..4d1ed91f7e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Prototype of the DxePchPolicyLib library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_PCH_POLICY_LIB_H_
> +#define _DXE_PCH_POLICY_LIB_H_
> +
> +#include <Protocol/PchPolicy.h>
> +
> +/**
> +  This function prints the DXE phase policy.
> +
> +  @param[in] PchPolicy    - PCH DXE Policy protocol
> +**/
> +VOID
> +PchPrintPolicyProtocol (
> +  IN  PCH_POLICY_PROTOCOL         *PchPolicy
> +  );
> +
> +/**
> +  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 Policy 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      **PchPolicy
> +  );
> +
> +/**
> +  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] PchPolicy                  The pointer to PCH 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
> +  );
> +
> +#endif // _DXE_PCH_POLICY_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
> new file mode 100644
> index 0000000000..a6ce032eba
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
> @@ -0,0 +1,265 @@
> +/** @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_H_", "_PCH_LP_"
> +    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GBE_MDI_LIB_H_
> +#define _GBE_MDI_LIB_H_
> +
> +//
> +//
> +//      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)
> +#define MDI_REG_SHIFT(x)                              (x << 16)
> +#define R_PHY_MDI_PHY_REG_DATA_READ_WRITE             0x00120000
> +// LAN PHY MDI registers and bits
> +//
> +
> +//
> +// Page 769 Port Control Registers
> +// 6020h (769 * 32)
> +//
> +#define PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS        769
> +
> +//
> +//  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/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
> new file mode 100644
> index 0000000000..25def24fca
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
> @@ -0,0 +1,788 @@
> +/** @file
> +  Header file for GpioLib.
> +  All function in this library is available for PEI, DXE, and SMM
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_LIB_H_
> +#define _GPIO_LIB_H_
> +
> +#include <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 Host Software Pad Ownership for certain group
> +
> +  @param[in]  Group               GPIO group
> +  @param[in]  DwNum               Host Ownership register number for
> current group.
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @param[out] HostSwRegVal        Value of Host Software Pad Ownership
> register
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter
> number
> +**/
> +EFI_STATUS
> +GpioGetHostSwOwnershipForGroupDw (
> +  IN  GPIO_GROUP                  Group,
> +  IN  UINT32                      DwNum,
> +  OUT UINT32                      *HostSwRegVal
> +  );
> +
> +/**
> +  This procedure will get GPIO Host Software Pad Ownership for certain group
> +
> +  @param[in]  Group               GPIO group
> +  @param[in]  DwNum               Host Ownership register number for
> current group
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @param[in]  HostSwRegVal        Value of Host Software Pad Ownership
> register
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter
> number
> +**/
> +EFI_STATUS
> +GpioSetHostSwOwnershipForGroupDw (
> +  IN GPIO_GROUP                   Group,
> +  IN UINT32                       DwNum,
> +  IN UINT32                       HostSwRegVal
> +  );
> +
> +/**
> +  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 set 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 GpioSetGroupDwToGpeDwX()
> +
> +  @param[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
> +  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
> +  @param[in]  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
> +GpioSetGroupToGpeDwX (
> +  IN GPIO_GROUP                GroupToGpeDw0,
> +  IN GPIO_GROUP                GroupToGpeDw1,
> +  IN GPIO_GROUP                GroupToGpeDw2
> +  );
> +
> +/**
> +  This procedure will set 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[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
> +  @param[in]  GroupDwForGpeDw0    DW of pins to be mapped to
> GPE_DW0
> +  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
> +  @param[in]  GroupDwForGpeDw1    DW of pins to be mapped to
> GPE_DW1
> +  @param[in]  GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
> +  @param[in]  GroupDwForGpeDw2    DW of pins to be mapped to
> GPE_DW2
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
> +**/
> +EFI_STATUS
> +GpioSetGroupDwToGpeDwX (
> +  IN GPIO_GROUP                GroupToGpeDw0,
> +  IN UINT32                    GroupDwForGpeDw0,
> +  IN GPIO_GROUP                GroupToGpeDw1,
> +  IN UINT32                    GroupDwForGpeDw1,
> +  IN GPIO_GROUP                GroupToGpeDw2,
> +  IN 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] Data                GPE STS data
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
> +**/
> +EFI_STATUS
> +GpioGetGpiGpeSts (
> +  IN GPIO_PAD                  GpioPad,
> +  OUT UINT32*                  Data
> +  );
> +
> +/**
> +  This procedure is used to lock all GPIO pads except the ones
> +  which were requested during their configuration to be left unlocked.
> +  This function must be called before BIOS_DONE - before POSTBOOT_SAI is
> enabled.
> +    FSP - call this function from wrapper before transition to FSP-S
> +    UEFI/EDK - call this function before EndOfPei event
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
> +**/
> +EFI_STATUS
> +GpioLockPads (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +#endif // _GPIO_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
> new file mode 100644
> index 0000000000..9956c60dd5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
> @@ -0,0 +1,166 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_NATIVE_LIB_H_
> +#define _GPIO_NATIVE_LIB_H_
> +
> +#include <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
> +  );
> +
> +/**
> +  This function checks if SATA GP pin is enabled
> +
> +  @param[in]  SataCtrlIndex       SATA Controller Index
> +  @param[in]  SataPort            SATA port number
> +
> +  @retval TRUE                    SATA GPx is enabled (pad is in required native
> mode)
> +          FALSE                   SATA GPx is not enabled
> +**/
> +BOOLEAN
> +GpioIsSataGpEnabled (
> +  IN  UINT32          SataCtrlIndex,
> +  IN  UINTN           SataPort
> +  );
> +
> +#endif // _GPIO_NATIVE_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
> new file mode 100644
> index 0000000000..6ef0d08774
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  Header file for OC WDT Library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _OC_WDT_LIB_H_
> +#define _OC_WDT_LIB_H_
> +
> +/**
> +  Check for unexpected reset.
> +  If there was an unexpected reset, enforces WDT expiration.
> +  Stops watchdog.
> +**/
> +VOID
> +OcWdtResetCheck (
> +  VOID
> +  );
> +
> +/**
> +  This function install WDT PPI
> +
> +  @retval EFI_STATUS  Results of the installation of the WDT PPI
> +**/
> +EFI_STATUS
> +EFIAPI
> +OcWdtInit (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLi
> b.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLi
> b.h
> new file mode 100644
> index 0000000000..7b6c82d390
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLi
> b.h
> @@ -0,0 +1,371 @@
> +/** @file
> +  Header file for PchCycleDecodingLib.
> +
> +  Copyright (c) 2019 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_
> +
> +/**
> +  Set PCH TCO base address.
> +  This cycle decoding is allowed to set when DMIC.SRL is 0.
> +  Programming steps:
> +  1. set Smbus PCI offset 54h [8] to enable TCO base address.
> +  2. program Smbus PCI offset 50h [15:5] to TCO base address.
> +  3. set Smbus PCI offset 54h [8] to enable TCO base address.
> +  4. program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [Smbus PCI
> offset 50h[15:5], 1].
> +
> +  @param[in] Address                    Address for TCO base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +**/
> +EFI_STATUS
> +PchTcoBaseSet (
> +  IN  UINT16                            Address
> +  );
> +
> +/**
> +  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
> +#define PCH_H_ESPI_GEN_IO_RANGE_MAX
> PCH_LPC_GEN_IO_RANGE_MAX  // @deprecated. Keep it here for backward
> compatibility.
> +
> +///
> +/// 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 eSPI CS1# generic IO range decoding.
> +  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 eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enable.
> +  2. Program eSPI Generic IO Range in DMI
> +
> +  @param[in] Address                    Address for generic IO range decoding.
> +  @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               eSPI secondary slave not supported
> +**/
> +EFI_STATUS
> +PchEspiCs1GenIoRangeSet (
> +  IN  UINT16                            Address,
> +  IN  UINTN                             Length
> +  );
> +
> +/**
> +  Get PCH LPC/eSPI generic IO range list.
> +  This function returns a list of base address, length, and enable for all
> LPC/eSPI generic IO range registers.
> +
> +  @param[out] LpcGenIoRangeList         Return all LPC/eSPI generic IO range
> register status.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +**/
> +EFI_STATUS
> +PchLpcGenIoRangeGet (
> +  OUT PCH_LPC_GEN_IO_RANGE_LIST         *LpcGenIoRangeList
> +  );
> +
> +/**
> +  Get PCH eSPI CS1# generic IO range list.
> +  This function returns a list of base address, length, and enable for all eSPI
> CS1# generic IO range registers.
> +
> +  @param[out] GenIoRangeList            eSPI generic IO range registers.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
> +**/
> +EFI_STATUS
> +PchEspiCs1GenIoRangeGet (
> +  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  @deprecated. Keep this for backward compatibility.
> +  It's replaced by PchEspiCs1MemRangeSet.
> +**/
> +EFI_STATUS
> +PchEspiMemRange2Set (
> +  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
> +  );
> +
> +/**
> +  Set PCH IO port 80h cycle decoding to PCIE root port.
> +  System BIOS is likely to do this very soon after reset before PCI bus
> enumeration, it must ensure that
> +  the IO Base Address field (PCIe:1Ch[7:4]) contains a value greater than the IO
> Limit field (PCIe:1Ch[15:12])
> +  before setting the IOSE bit. Otherwise the bridge will positively decode IO
> range 000h - FFFh by its default
> +  IO range values.
> +  This cycle decoding is allowed to set when DMIC.SRL is 0.
> +  Programming steps:
> +  1. Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest ID of
> RP.
> +  2. Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'. Use byte
> write on GCS+1 and leave the BILD bit which is RWO.
> +  3. Program IOSE bit of PCIE:Reg04h[0] to '1'  for PCH to send such IO cycles to
> PCIe bus for subtractive decoding.
> +
> +  @param[in] RpPhyNumber                PCIE root port physical number.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +**/
> +EFI_STATUS
> +PchIoPort80DecodeSet (
> +  IN  UINTN                             RpPhyNumber
> +  );
> +
> +/**
> +  Get IO APIC registers base address.
> +
> +  @param[out] IoApicBase                Buffer of IO APIC register 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/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
> new file mode 100644
> index 0000000000..c1d3c50ead
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
> @@ -0,0 +1,141 @@
> +/** @file
> +  Header file for PchEspiLib.
> +  All function in this library is available for PEI, DXE, and SMM,
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_ESPI_LIB_H_
> +#define _PCH_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 // _PEI_DXE_SMM_PCH_ESPI_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
> new file mode 100644
> index 0000000000..2a4dc986f4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  Header file for PchGbeLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_GBE_LIB_H_
> +#define _PCH_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
> +PchIsGbeRegionValid (
> +  VOID
> +  );
> +
> +
> +/**
> +  Check whether LAN controller is enabled in the platform.
> +
> +  @retval TRUE                    GbE is enabled
> +  @retval FALSE                   GbE is disabled
> +**/
> +BOOLEAN
> +PchIsGbePresent (
> +  VOID
> +  );
> +
> +#endif // _PCH_GBE_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
> new file mode 100644
> index 0000000000..4f93f44120
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
> @@ -0,0 +1,109 @@
> +/** @file
> +  Header file for PchHsioLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HSIO_LIB_H_
> +#define _PCH_HSIO_LIB_H_
> +
> +/**
> +  Represents HSIO lane
> +**/
> +typedef struct {
> +  UINT8        Index; ///< Lane index
> +  UINT8        Pid;   ///< Sideband ID
> +  UINT16       Base;  ///< Sideband base address
> +} HSIO_LANE;
> +
> +/**
> +  The function returns the Port Id and lane owner for the specified lane
> +
> +  @param[in]  PhyMode             Phymode that needs to be checked
> +  @param[out] Pid                 Common Lane End Point ID
> +  @param[out] LaneOwner           Lane Owner
> +
> +  @retval EFI_SUCCESS             Read success
> +  @retval EFI_INVALID_PARAMETER   Invalid lane number
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchGetLaneInfo (
> +  IN  UINT32                            LaneNum,
> +  OUT UINT8                             *PortId,
> +  OUT UINT8                             *LaneOwner
> +  );
> +
> +/**
> +  Get HSIO lane representation needed to perform any operation on the lane.
> +
> +  @param[in]  LaneIndex  Number of the HSIO lane
> +  @param[out] HsioLane   HSIO lane representation
> +**/
> +VOID
> +HsioGetLane (
> +  IN   UINT8       LaneIndex,
> +  OUT  HSIO_LANE   *HsioLane
> +  );
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[in]  PcieLaneIndex             PCIE Root Port Lane Index
> +  @param[out] LaneNum                   Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetPcieLaneNum (
> +  UINT32              PcieLaneIndex,
> +  UINT8               *LaneNum
> +  );
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[in]  SataLaneIndex             Sata Lane Index
> +  @param[out] LaneNum                   Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetSataLaneNum (
> +  UINT32              SataLaneIndex,
> +  UINT8               *LaneNum
> +  );
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[in]  Usb3LaneIndex             USB3 Lane Index
> +  @param[out] LaneNum                   Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetUsb3LaneNum (
> +  UINT32              Usb3LaneIndex,
> +  UINT8               *LaneNum
> +  );
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[out] LaneNum                   GBE Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetGbeLaneNum (
> +  UINT8               *LaneNum
> +  );
> +
> +#endif // _PCH_HSIO_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
> new file mode 100644
> index 0000000000..94a8204fa5
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
> @@ -0,0 +1,407 @@
> +/** @file
> +  Header file for PchInfoLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_INFO_LIB_H_
> +#define _PCH_INFO_LIB_H_
> +
> +#include <PchHda.h>
> +
> +typedef UINT8 PCH_STEPPING;
> +#define PCH_A0                0x00
> +#define PCH_A1                0x01
> +#define PCH_B0                0x10
> +#define PCH_B1                0x11
> +#define PCH_C0                0x20
> +#define PCH_C1                0x21
> +#define PCH_D0                0x30
> +#define PCH_D1                0x31
> +#define PCH_STEPPING_MAX      0xFF
> +
> +typedef UINT8 PCH_SERIES;
> +#define PCH_H                   1
> +#define PCH_LP                  2
> +#define PCH_SERVER              0x80
> +#define PCH_UNKNOWN_SERIES      0xFF
> +
> +typedef UINT8 PCH_GENERATION;
> +#define CNL_PCH                 3
> +#define CDF_PCH                 0x80
> +#define PCH_UNKNOWN_GENERATION  0xFF
> +
> +typedef enum {
> +  RstUnsupported  = 0,
> +  RstPremium,
> +  RstOptane,
> +  RstMaxMode
> +} RST_MODE;
> +
> +/**
> +  Return LPC Device Id
> +
> +  @retval PCH_LPC_DEVICE_ID         PCH Lpc Device ID
> +**/
> +UINT16
> +PchGetLpcDid (
> +  VOID
> +  );
> +
> +/**
> +  Return Pch stepping type
> +
> +  @retval PCH_STEPPING            Pch stepping type
> +**/
> +PCH_STEPPING
> +PchStepping (
> +  VOID
> +  );
> +
> +/**
> +  Determine if PCH is supported
> +
> +  @retval TRUE                    PCH is supported
> +  @retval FALSE                   PCH is not supported
> +**/
> +BOOLEAN
> +IsPchSupported (
> +  VOID
> +  );
> +
> +/**
> +  Return Pch Series
> +
> +  @retval PCH_SERIES                Pch Series
> +**/
> +PCH_SERIES
> +PchSeries (
> +  VOID
> +  );
> +
> +/**
> +  Check if this is PCH LP series
> +
> +  @retval TRUE                It's PCH LP series
> +  @retval FALSE               It's not PCH LP series
> +**/
> +BOOLEAN
> +IsPchLp (
> +  VOID
> +  );
> +
> +/**
> +  Check if this is PCH H series
> +
> +  @retval TRUE                It's PCH H series
> +  @retval FALSE               It's not PCH H series
> +**/
> +BOOLEAN
> +IsPchH (
> +  VOID
> +  );
> +
> +/**
> +  Check if this is Server PCH
> +
> +  @retval TRUE                It's a Server PCH
> +  @retval FALSE               It's not a Server PCH
> +**/
> +BOOLEAN
> +IsPchServer (
> +  VOID
> +  );
> +
> +/**
> +  Return Pch Generation
> +
> +  @retval PCH_GENERATION            Pch Generation
> +**/
> +PCH_GENERATION
> +PchGeneration (
> +  VOID
> +  );
> +
> +/**
> +  Check if this is CDF PCH generation
> +
> +  @retval TRUE                It's CDF PCH
> +  @retval FALSE               It's not CDF PCH
> +**/
> +BOOLEAN
> +IsCdfPch (
> +  VOID
> +  );
> +
> +/**
> +  @retval TRUE                It's CNL PCH
> +  @retval FALSE               It's not CNL PCH
> +**/
> +BOOLEAN
> +IsCnlPch (
> +  VOID
> +  );
> +
> +/**
> +  Check if this is Server SKU
> +
> +  @retval TRUE                It's PCH Server SKU
> +  @retval FALSE               It's not PCH Server SKU
> +**/
> +BOOLEAN
> +IsPchServerSku (
> +  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 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 Maximum Usb3 Port Number of XHCI Controller
> +
> +  @retval Pch Maximum Usb3 Port Number of XHCI Controller
> +**/
> +UINT8
> +GetPchXhciMaxUsb3PortNum (
> +  VOID
> +  );
> +
> +/**
> +  Get Pch Maximum Serial IO controllers number
> +
> +  @retval Pch Maximum Serial IO controllers number
> +**/
> +UINT8
> +GetPchMaxSerialIoControllersNum (
> +  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
> +  );
> +
> +#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 (
> +  );
> +
> +/**
> +  Get PCH Sku ASCII string
> +  The return string is zero terminated.
> +
> +  @retval Static ASCII string of PCH Sku
> +**/
> +CHAR8*
> +PchGetSkuStr (
> +  VOID
> +  );
> +
> +/**
> +  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 UFS controller
> +
> +  @retval BOOLEAN  TRUE if supported, FALSE otherwise
> +**/
> +BOOLEAN
> +IsPchUfsSupported  (
> +  VOID
> +  );
> +
> +/**
> +  Gets the maximum number of UFS controller supported by this chipset.
> +
> +  @return Number of supported UFS controllers
> +**/
> +UINT8
> +PchGetMaxUfsNum (
> +  VOID
> +  );
> +
> +/**
> +  Get RST mode supported by the silicon
> +
> +  @retval RST_MODE    RST mode supported by silicon
> +**/
> +RST_MODE
> +PchGetSupportedRstMode (
> +  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 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 PCH_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
> +  );
> +
> +#endif // _PCH_INFO_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
> new file mode 100644
> index 0000000000..7c26f6939e
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
> @@ -0,0 +1,105 @@
> +/** @file
> +  Header file for PchPcieRpLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_PCIERP_LIB_H_
> +#define _PCH_PCIERP_LIB_H_
> +
> +#define RST_PCIE_STORAGE_CR_1                       0
> +#define RST_PCIE_STORAGE_CR_2                       1
> +#define RST_PCIE_STORAGE_CR_3                       2
> +#define RST_PCIE_STORAGE_CR_INVALID                 99
> +
> +typedef struct {
> +  UINT8 DevNum;
> +  UINT8 Pid;
> +  UINT8 RpNumBase;
> +} PCH_PCIE_CONTROLLER_INFO;
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Check the RST PCIe Storage Cycle Router number according to the root port
> number and PCH type
> +
> +  @param[in] RootPortNum  Root Port Number
> +
> +  @return  The RST PCIe Storage Cycle Router Number
> +**/
> +UINT8
> +RstGetCycleRouterNumber (
> +  IN  UINT32                   RootPortNum
> +  );
> +
> +#endif // _PCH_PCIERP_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
> new file mode 100644
> index 0000000000..2d57087c6b
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
> @@ -0,0 +1,226 @@
> +/** @file
> +  Header file for PchPcrLib.
> +
> +  Copyright (c) 2019 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 base address (defined in PchReservedResources.h)
> +///
> +//#define PCH_PCR_BASE_ADDRESS            0xFD000000
> +//#define PCH_PCR_MMIO_SIZE               0x01000000
> +/**
> +  Definition for PCR address
> +  The PCR address is used to the PCR MMIO programming
> +**/
> +#define PCH_PCR_ADDRESS(Pid, Offset)    (PCH_PCR_BASE_ADDRESS |
> ((UINT8)(Pid) << 16) | (UINT16)(Offset))
> +
> +/**
> +  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
> +  );
> +
> +#endif // _PCH_PCR_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
> new file mode 100644
> index 0000000000..36a0adb56f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
> @@ -0,0 +1,45 @@
> +/** @file
> +  Header file for PchPmcLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_PMC_LIB_H_
> +#define _PCH_PMC_LIB_H_
> +
> +typedef enum {
> +  WarmBoot          = 1,
> +  ColdBoot,
> +  PwrFlr,
> +  PwrFlrSys,
> +  PwrFlrPch,
> +  PchPmStatusMax
> +} PCH_PM_STATUS;
> +
> +/**
> +  Query PCH to determine the Pm Status
> +
> +  @param[in] PmStatus - The Pch Pm Status to be probed
> +
> +  @retval Status TRUE if Status querried is Valid or FALSE if otherwise
> +**/
> +BOOLEAN
> +GetPchPmStatus (
> +  PCH_PM_STATUS PmStatus
> +  );
> +
> +/**
> +  Funtion to check if Battery lost or CMOS cleared.
> +
> +  @reval TRUE  Battery is always present.
> +  @reval FALSE CMOS is cleared.
> +**/
> +BOOLEAN
> +EFIAPI
> +PchIsRtcBatteryGood (
> +  VOID
> +  );
> +
> +#endif // _PCH_PMC_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
> new file mode 100644
> index 0000000000..acd7a16e48
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
> @@ -0,0 +1,114 @@
> +/** @file
> +  Prototype of the PeiPchPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_PCH_POLICY_LIB_H_
> +#define _PEI_PCH_POLICY_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Print whole PCH_PREMEM_POLICY_PPI and serial out.
> +
> +  @param[in] SiPreMemPolicyPpi       The RC PREMEM Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +PchPreMemPrintPolicyPpi (
> +  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  Print whole SI_POLICY_PPI and serial out.
> +
> +  @param[in] SiPolicyPpi               The RC Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +PchPrintPolicyPpi (
> +  IN  SI_POLICY_PPI           *SiPolicyPpi
> +  );
> +
> +/**
> +  Get PCH PREMEM config block table total size.
> +
> +  @retval                               Size of PCH PREMEM config block table
> +**/
> +UINT16
> +EFIAPI
> +PchGetPreMemConfigBlockTotalSize (
> +  VOID
> +  );
> +
> +/**
> +  Get PCH config block table total size.
> +
> +  @retval                               Size of PCH config block table
> +**/
> +UINT16
> +EFIAPI
> +PchGetConfigBlockTotalSize (
> +  VOID
> +  );
> +
> +/**
> +  PchAddPreMemConfigBlocks add all PCH config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add PCH config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchAddPreMemConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  );
> +
> +/**
> +  PchAddConfigBlocks add all PCH config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add PCH config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchAddConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  );
> +
> +/**
> +  Get Sata Config Policy
> +
> +  @param[in]  SiPolicy            The RC Policy PPI instance
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval     SataConfig          Pointer to Sata Config Policy
> +**/
> +PCH_SATA_CONFIG *
> +GetPchSataConfig (
> +  IN SI_POLICY_PPI      *SiPolicy,
> +  IN UINT32             SataCtrlIndex
> +  );
> +
> +/**
> +  Get Hsio Sata Pre Mem Config Policy
> +
> +  @param[in]  SiPolicy            The RC Policy PPI instance
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval     Pointer to Hsio Sata Pre Mem Config Policy
> +**/
> +PCH_HSIO_SATA_PREMEM_CONFIG *
> +GetPchHsioSataPreMemConfig (
> +  IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy,
> +  IN UINT32               SataCtrlIndex
> +  );
> +
> +#endif // _PEI_PCH_POLICY_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
> new file mode 100644
> index 0000000000..ca2da4cfc1
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
> @@ -0,0 +1,24 @@
> +/** @file
> +  Header file for PCH RESET Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_RESET_LIB_H_
> +#define _PCH_RESET_LIB_H_
> +
> +/**
> +  Initialize PCH Reset APIs
> +
> +  @retval EFI_SUCCESS             APIs are installed successfully
> +  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchInitializeReset (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
> new file mode 100644
> index 0000000000..779aac2d2a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
> @@ -0,0 +1,116 @@
> +/** @file
> +  Header file for PchSbiAccessLib.
> +
> +  Copyright (c) 2019 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
> +EFIAPI
> +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
> +EFIAPI
> +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/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
> new file mode 100644
> index 0000000000..4962c67a7c
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
> @@ -0,0 +1,240 @@
> +/** @file
> +  Header file for PCH Serial IO Lib implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SERIAL_IO_LIB_H_
> +#define _PCH_SERIAL_IO_LIB_H_
> +
> +typedef enum {
> +  PchSerialIoIndexI2C0,
> +  PchSerialIoIndexI2C1,
> +  PchSerialIoIndexI2C2,
> +  PchSerialIoIndexI2C3,
> +  PchSerialIoIndexI2C4,
> +  PchSerialIoIndexI2C5,
> +  PchSerialIoIndexSpi0,
> +  PchSerialIoIndexSpi1,
> +  PchSerialIoIndexSpi2,
> +  PchSerialIoIndexUart0,
> +  PchSerialIoIndexUart1,
> +  PchSerialIoIndexUart2,
> +  PchSerialIoIndexMax
> +} PCH_SERIAL_IO_CONTROLLER;
> +
> +typedef enum {
> +  PchSerialIoDisabled,
> +  PchSerialIoPci,
> +  PchSerialIoAcpi,
> +  PchSerialIoHidden
> +} PCH_SERIAL_IO_MODE;
> +
> +typedef enum  {
> +  SERIAL_IO_UNKNOWN = 0,
> +  SERIAL_IO_I2C,
> +  SERIAL_IO_SPI,
> +  SERIAL_IO_UART
> +} PCH_SERIAL_IO_CONTROLLER_TYPE;
> +
> +enum PCH_LP_SERIAL_IO_CS_POLARITY {
> +  PchSerialIoCsActiveLow = 0,
> +  PchSerialIoCsActiveHigh = 1
> +};
> +enum PCH_LP_SERIAL_IO_HW_FLOW_CTRL {
> +  PchSerialIoHwFlowCtrlDisabled = 0,
> +  PchSerialIoHwFlowControlEnabled = 1
> +};
> +
> +#define SERIALIO_HID_LENGTH 8 // including null terminator
> +#define SERIALIO_UID_LENGTH 1
> +#define SERIALIO_CID_LENGTH 1
> +#define SERIALIO_TOTAL_ID_LENGTH
> SERIALIO_HID_LENGTH+SERIALIO_UID_LENGTH+SERIALIO_CID_LENGTH
> +
> +/**
> +  Returns index of the last i2c controller
> +
> +  @param[in] Number  Number of SerialIo controller
> +
> +  @retval            Index of I2C controller
> +**/
> +PCH_SERIAL_IO_CONTROLLER
> +GetMaxI2cNumber (
> +  VOID
> +  );
> +
> +/**
> +  Returns string with AcpiHID assigned to selected SerialIo controller
> +
> +  @param[in] Number  Number of SerialIo controller
> +
> +  @retval            pointer to 8-byte string
> +**/
> +CHAR8*
> +GetSerialIoAcpiHid (
> +  IN PCH_SERIAL_IO_CONTROLLER Number
> +  );
> +
> +/**
> +  Checks if given Serial IO Controller Function equals 0
> +
> +  @param[in] SerialIoNumber             Serial IO device
> +
> +  @retval                               TRUE if SerialIO Function is equal to 0
> +                                        FALSE if Function is higher then 0
> +**/
> +BOOLEAN
> +IsSerialIoFunctionZero (
> +  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
> +  );
> +
> +/**
> +  Checks if Device with given PciDeviceId is one of SerialIo controllers
> +  If yes, its number is returned through Number parameter, otherwise
> Number is not updated
> +
> +  @param[in]  PciDevId  Device ID
> +  @param[out] Number    Number of SerialIo controller
> +
> +  @retval TRUE          Yes it is a SerialIo controller
> +  @retval FALSE         No it isn't a SerialIo controller
> +**/
> +BOOLEAN
> +IsSerialIoPciDevId (
> +  IN  UINT16                    PciDevId,
> +  OUT PCH_SERIAL_IO_CONTROLLER  *Number
> +  );
> +
> +/**
> +  Checks if Device with given AcpiHID string is one of SerialIo controllers
> +  If yes, its number is returned through Number parameter, otherwise
> Number is not updated
> +
> +  @param[in]  AcpiHid   String
> +  @param[out] Number    Number of SerialIo controller
> +
> +  @retval TRUE          yes it is a SerialIo controller
> +  @retval FALSE         no it isn't a SerialIo controller
> +**/
> +BOOLEAN
> +IsSerialIoAcpiHid (
> +  IN CHAR8                      *AcpiHid,
> +  OUT PCH_SERIAL_IO_CONTROLLER  *Number
> +  );
> +
> +/**
> +  Configures Serial IO Controller
> +
> +  @param[in] Controller    Serial IO controller number
> +  @param[in] DeviceMode    Device operation mode
> +  @param[in] PsfDisable    Disable device at PSF level
> +
> +  @retval None
> +**/
> +VOID
> +ConfigureSerialIoController (
> +  IN PCH_SERIAL_IO_CONTROLLER Controller,
> +  IN PCH_SERIAL_IO_MODE       DeviceMode,
> +  IN BOOLEAN                  PsfDisable
> +  );
> +
> +/**
> +  Returns Serial IO Controller Type I2C, SPI or UART
> +
> +  @param[in] Number  Number of SerialIo controller
> +
> +  @retval            I2C, SPI or UART
> +  @retval            UNKNOWN - in case if undefined controller
> +**/
> +PCH_SERIAL_IO_CONTROLLER_TYPE
> +GetSerialIoControllerType (
> +  IN PCH_SERIAL_IO_CONTROLLER  Controller
> +  );
> +
> +/**
> +  Finds PCI Device Number of SerialIo devices.
> +  SerialIo devices' BDF is configurable
> +
> +  @param[in] SerialIoNumber             Serial IO device
> +
> +  @retval                               SerialIo device number
> +**/
> +UINT8
> +GetSerialIoDeviceNumber (
> +  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
> +  );
> +
> +/**
> +  Finds PCI Function Number of SerialIo devices.
> +  SerialIo devices' BDF is configurable
> +
> +  @param[in] SerialIoNumber             Serial IO device
> +
> +  @retval                               SerialIo funciton number
> +**/
> +UINT8
> +GetSerialIoFunctionNumber (
> +  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
> +  );
> +
> +/**
> +  Finds BAR values of SerialIo devices.
> +  SerialIo devices can be configured to not appear on PCI so traditional
> method of reading BAR might not work.
> +
> +  @param[in] SerialIoDevice             Serial IO device
> +  @param[in] BarNumber                  0=BAR0, 1=BAR1
> +
> +  @retval                               SerialIo Bar value
> +**/
> +UINTN
> +FindSerialIoBar (
> +  IN PCH_SERIAL_IO_CONTROLLER           SerialIoDevice,
> +  IN UINT8                              BarNumber
> +  );
> +
> +/**
> +  Checks if given device corresponds to any of LPSS Devices
> +
> +  @param[in] DeviceNumber               device number
> +  @param[in] FunctionNumber             function number
> +
> +  @retval                               TRUE if SerialIO Device/Function Number is
> equal to any of LPSS devices
> +                                        FALSE Device/Function is not in Serial IO scope
> +**/
> +BOOLEAN
> +IsSerialIoDevice (
> +  IN UINT8  DeviceNumber,
> +  IN UINT8  FunctionNumber
> +  );
> +
> +/**
> +  Checks if given Serial IO Controller is enabled or not
> +
> +  @param[in] DeviceNumber               device number
> +  @param[in] FunctionNumber             function number
> +
> +  @retval TRUE                          TRUE if given serial io device is enabled.
> +  @retval FALSE                         FALSE if given serial io device is disabled.
> +**/
> +BOOLEAN
> +IsSerialIoDeviceEnabled (
> +  IN UINT8  DeviceNumber,
> +  IN UINT8  FunctionNumber
> +  );
> +
> +/**
> +  Gets Pci Config control offset
> +
> +  @param[in] DeviceNumber               device number
> +  @param[in] FunctionNumber             function number
> +
> +  @retval    CfgCtrAddr                 Offset of Pci config control
> +                                        0 if Device and Function do not correspond to
> Serial IO
> +**/
> +UINT16
> +GetSerialIoConfigControlOffset (
> +  IN UINT8  DeviceNumber,
> +  IN UINT8  FunctionNumber
> +  );
> +
> +#endif // _PEI_DXE_SMM_PCH_SERIAL_IO_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.
> h
> new file mode 100644
> index 0000000000..f97051e97c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.
> h
> @@ -0,0 +1,111 @@
> +/** @file
> +  Header file for PCH Serial IO UART Lib implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SERIAL_IO_UART_LIB_H_
> +#define _PCH_SERIAL_IO_UART_LIB_H_
> +
> +typedef enum {
> +  AccessMode8bit,
> +  AccessMode32bit
> +} UART_ACCESS_MODE;
> +
> +/**
> +  Returns UART's currently active access mode, 8 or 32 bit
> +
> +  @param[in]  MmioBase    Base address of UART MMIO space
> +
> +  @retval     AccessMode8bit
> +  @retval     AccessMode32bit
> +**/
> +UART_ACCESS_MODE
> +DetectAccessMode (
> +  IN UINTN  MmioBase
> +  );
> +
> +/**
> +  Initialize selected SerialIo UART.
> +
> +  @param[in]  UartNumber           Selects Serial IO UART device (0-2)
> +  @param[in]  FifoEnable           When TRUE, enables 64-byte FIFOs.
> +  @param[in]  BaudRate             Baud rate.
> +  @param[in]  LineControl          Data length, parity, stop bits.
> +  @param[in]  HardwareFlowControl  Automated hardware flow control. If
> TRUE, hardware automatically checks CTS when sending data, and sets RTS
> when receiving data.
> +**/
> +VOID
> +EFIAPI
> +PchSerialIoUartInit (
> +  IN UINT8   UartNumber,
> +  IN BOOLEAN FifoEnable,
> +  IN UINT32  BaudRate,
> +  IN UINT8   LineControl,
> +  IN BOOLEAN HardwareFlowControl
> +  );
> +
> +
> +/**
> +  Write data to serial device.
> +
> +  If the buffer is NULL, then return 0;
> +  if NumberOfBytes is zero, then return 0.
> +
> +  @param[in]  UartNumber       Selects Serial IO UART device (0-2)
> +  @param[in]  Buffer           Point of data buffer which need to be writed.
> +  @param[in]  NumberOfBytes    Number of output bytes which are cached
> in Buffer.
> +
> +  @retval                  Actual number of bytes writed to serial device.
> +**/
> +UINTN
> +EFIAPI
> +PchSerialIoUartOut (
> +  IN UINT8  UartNumber,
> +  IN UINT8  *Buffer,
> +  IN UINTN  NumberOfBytes
> +);
> +
> +/*
> +  Read data from serial device and save the datas in buffer.
> +
> +  If the buffer is NULL, then return 0;
> +  if NumberOfBytes is zero, then return 0.
> +
> +  @param[in]   UartNumber           Selects Serial IO UART device (0-2)
> +  @param[out]  Buffer               Point of data buffer which need to be
> writed.
> +  @param[in]   NumberOfBytes        Number of output bytes which are
> cached in Buffer.
> +  @param[in]   WaitUntilBufferFull  When TRUE, function waits until whole
> buffer is filled. When FALSE, function returns as soon as no new characters are
> available.
> +
> +  @retval                      Actual number of bytes raed from serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +PchSerialIoUartIn (
> +  IN  UINT8     UartNumber,
> +  OUT UINT8     *Buffer,
> +  IN  UINTN     NumberOfBytes,
> +  IN  BOOLEAN   WaitUntilBufferFull
> +);
> +
> +/**
> +  Polls a serial device to see if there is any data waiting to be read.
> +  If there is data waiting to be read from the serial device, then TRUE is
> returned.
> +  If there is no data waiting to be read from the serial device, then FALSE is
> returned.
> +
> +  @param[in]  UartNumber       Selects Serial IO UART device (0-2)
> +
> +  @retval TRUE             Data is waiting to be read from the serial device.
> +  @retval FALSE            There is no data waiting to be read from the serial
> device.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +PchSerialIoUartPoll (
> +  IN  UINT8     UartNumber
> +  );
> +
> +
> +#endif // _PEI_DXE_SMM_PCH_SERIAL_IO_UART_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.
> h
> new file mode 100644
> index 0000000000..34b9867c34
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.
> h
> @@ -0,0 +1,23 @@
> +/** @file
> +  Header file for SMM Control PEI Library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SMM_CONTROL_LIB_H_
> +#define _PCH_SMM_CONTROL_LIB_H_
> +
> +/**
> +  This function install PEI SMM Control PPI
> +
> +  @retval EFI_STATUS  Results of the installation of the SMM Control PPI
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchSmmControlInit (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib
> .h
> new file mode 100644
> index 0000000000..69b9c1cdb7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib
> .h
> @@ -0,0 +1,121 @@
> +/** @file
> +  Library that contains common parts of WdtPei and WdtDxe. Not a
> standalone module.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_WDT_COMMON_LIB_H_
> +#define _PCH_WDT_COMMON_LIB_H_
> +
> +extern UINT8    mAllowExpectedReset;
> +
> +/**
> +  Reads LPC bridge to get Watchdog Timer address
> +
> +
> +  @retval UINT32                  Watchdog's address
> +**/
> +UINT32
> +WdtGetAddress (
> +  VOID
> +  );
> +
> +/**
> +  Reloads WDT with new timeout value and starts it. Also sets Unexpected
> Reset bit, which
> +  causes the next reset to be treated as watchdog expiration - unless
> AllowKnownReset()
> +  function was called too.
> +
> +  @param[in] TimeoutValue         Time in seconds before WDT times out.
> Supported range = 1 - 1024.
> +
> +  @retval EFI_SUCCESS             if everything's OK
> +  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
> +**/
> +EFI_STATUS
> +EFIAPI
> +WdtReloadAndStart (
> +  IN  UINT32  TimeoutValue
> +  );
> +
> +/**
> +  Disables WDT timer.
> +
> +
> +**/
> +VOID
> +EFIAPI
> +WdtDisable (
> +  VOID
> +  );
> +
> +/**
> +  Returns WDT failure status.
> +
> +
> +  @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE   If there was WDT
> expiration or unexpected reset
> +  @retval V_PCH_OC_WDT_CTL_STATUS_OK        Otherwise
> +**/
> +UINT8
> +EFIAPI
> +WdtCheckStatus (
> +  VOID
> +  );
> +
> +/**
> +  Normally, each reboot performed while watchdog runs is considered a
> failure.
> +  This function allows platform to perform expected reboots with WDT
> running,
> +  without being interpreted as failures.
> +  In DXE phase, it is enough to call this function any time before reset.
> +  In PEI phase, between calling this function and performing reset,
> ReloadAndStart()
> +  must not be called.
> +
> +
> +**/
> +VOID
> +EFIAPI
> +WdtAllowKnownReset (
> +  VOID
> +  );
> +
> +/**
> +  Returns information if WDT coverage for the duration of BIOS execution
> +  was requested by an OS application
> +
> +
> +  @retval TRUE                    if WDT was requested
> +  @retval FALSE                   if WDT was not requested
> +**/
> +UINT8
> +EFIAPI
> +IsWdtRequired (
> +  VOID
> +  );
> +
> +/**
> +  Returns WDT enabled/disabled status.
> +
> +
> +  @retval TRUE                    if WDT is enabled
> +  @retval FALSE                   if WDT is disabled
> +**/
> +UINT8
> +EFIAPI
> +IsWdtEnabled (
> +  VOID
> +  );
> +
> +/**
> +  Returns WDT locked status.
> +
> +
> +  @retval TRUE                    if WDT is locked
> +  @retval FALSE                   if WDT is unlocked
> +**/
> +UINT8
> +EFIAPI
> +IsWdtLocked (
> +  VOID
> +  );
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
> new file mode 100644
> index 0000000000..f1a2600216
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
> @@ -0,0 +1,207 @@
> +/** @file
> +  Header file for PmcLib.
> +
> +  Copyright (c) 2019 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 {
> +  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;
> +
> +#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 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 RTC 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
> +  );
> +
> +/**
> +  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 checks if SMI Lock is set
> +
> +  @retval SMI Lock state
> +**/
> +BOOLEAN
> +PmcIsSmiLockSet (
> +  VOID
> +  );
> +
> +/**
> +  Check global SMI enable is set
> +
> +  @retval TRUE  Global SMI enable is set
> +          FALSE Global SMI enable is not set
> +**/
> +BOOLEAN
> +PmcIsGblSmiEn (
> +  VOID
> +  );
> +
> +#endif // _PMC_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
> new file mode 100644
> index 0000000000..047d543009
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
> @@ -0,0 +1,76 @@
> +/** @file
> +  Header file for PchSataLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SATA_LIB_H_
> +#define _PCH_SATA_LIB_H_
> +
> +#define SATA_1_CONTROLLER_INDEX             0
> +#define SATA_2_CONTROLLER_INDEX             1
> +#define SATA_3_CONTROLLER_INDEX             2
> +
> +/**
> +  Get Pch Maximum Sata Port Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval Pch Maximum Sata Port Number
> +**/
> +UINT8
> +GetPchMaxSataPortNum (
> +  IN UINT32     SataCtrlIndex
> +  );
> +
> +/**
> +  Gets Maximum Sata Controller Number
> +
> +  @param[in] None
> +
> +  @retval Maximum Sata Controller Number
> +**/
> +UINT8
> +GetPchMaxSataControllerNum (
> +  VOID
> +  );
> +
> +/**
> +  Gets SATA controller PCIe Device Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe Device Number
> +**/
> +UINT8
> +GetSataPcieDeviceNum (
> +  IN UINT32 SataCtrlIndex
> +  );
> +
> +/**
> +  Gets SATA controller PCIe Function Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe Function Number
> +**/
> +UINT8
> +GetSataPcieFunctionNum (
> +  IN UINT32 SataCtrlIndex
> +  );
> +
> +/**
> +  Gets SATA controller PCIe config space base address
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe config space base address
> +**/
> +UINT64
> +GetSataRegBase (
> +  IN UINT32 SataCtrlIndex
> +  );
> +
> +#endif // _PCH_SATA_LIB_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
> new file mode 100644
> index 0000000000..53283597e7
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
> @@ -0,0 +1,22 @@
> +/** @file
> +  Header file for SEC PCH Lib.
> +  All function in this library is available for SEC
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SEC_PCH_LIB_H_
> +#define _SEC_PCH_LIB_H_
> +
> +/**
> +  This function do the PCH cycle decoding initialization.
> +**/
> +VOID
> +EFIAPI
> +EarlyCycleDecoding (
> +  VOID
> +  );
> +
> +#endif // _SEC_PCH_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLi
> b.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLi
> b.h
> new file mode 100644
> index 0000000000..53c11bb59a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLi
> b.h
> @@ -0,0 +1,98 @@
> +/** @file
> +  The header file includes the common header files, defines
> +  internal structure and functions used by SpiFlashCommonLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SPI_FLASH_COMMON_LIB_H__
> +#define __SPI_FLASH_COMMON_LIB_H__
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#define SECTOR_SIZE_4KB   0x1000      // Common 4kBytes sector size
> +/**
> +  Enable block protection on the Serial Flash device.
> +
> +  @retval     EFI_SUCCESS       Opertion is successful.
> +  @retval     EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashLock (
> +  VOID
> +  );
> +
> +/**
> +  Read NumBytes bytes of data from the address specified by
> +  PAddress into Buffer.
> +
> +  @param[in]      Address       The starting physical address of the read.
> +  @param[in,out]  NumBytes      On input, the number of bytes to read. On
> output, the number
> +                                of bytes actually read.
> +  @param[out]     Buffer        The destination data buffer for the read.
> +
> +  @retval         EFI_SUCCESS       Opertion is successful.
> +  @retval         EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashRead (
> +  IN     UINTN                        Address,
> +  IN OUT UINT32                       *NumBytes,
> +     OUT UINT8                        *Buffer
> +  );
> +
> +/**
> +  Write NumBytes bytes of data from Buffer to the address specified by
> +  PAddresss.
> +
> +  @param[in]      Address         The starting physical address of the write.
> +  @param[in,out]  NumBytes        On input, the number of bytes to write.
> On output,
> +                                  the actual number of bytes written.
> +  @param[in]      Buffer          The source data buffer for the write.
> +
> +  @retval         EFI_SUCCESS       Opertion is successful.
> +  @retval         EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashWrite (
> +  IN     UINTN                      Address,
> +  IN OUT UINT32                     *NumBytes,
> +  IN     UINT8                      *Buffer
> +  );
> +
> +/**
> +  Erase the block starting at Address.
> +
> +  @param[in]  Address         The starting physical address of the block to be
> erased.
> +                              This library assume that caller garantee that the
> PAddress
> +                              is at the starting address of this block.
> +  @param[in]  NumBytes        On input, the number of bytes of the logical
> block to be erased.
> +                              On output, the actual number of bytes erased.
> +
> +  @retval     EFI_SUCCESS.      Opertion is successful.
> +  @retval     EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashBlockErase (
> +  IN    UINTN                     Address,
> +  IN    UINTN                     *NumBytes
> +  );
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
> new file mode 100644
> index 0000000000..e56f3139d7
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  Header file for Spi Library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SPI_LIB_H_
> +#define _SPI_LIB_H_
> +
> +/**
> +  This function Initial SPI services
> +
> +  @retval EFI_STATUS  Results of the installation of the SPI services
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiServiceInit (
> +  VOID
> +  );
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:09 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI
> and Protocol include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the following header files:
>  * Pch/Include/Ppi
>  * Pch/Include/Protocol
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
> |  42 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
> |  27 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
> |  28 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
> | 186 ++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch
> .h         | 136 +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
> |  68 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.
> h         | 146 ++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.
> h         | 132 +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
> |  42 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
> |  42 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
> | 134 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapContr
> ol.h        |  67 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTim
> erControl.h |  67 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.
> h          | 152 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
> |  15 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
> | 295 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
> | 113 ++++++++
>  17 files changed, 1692 insertions(+)
> 
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
> new file mode 100644
> index 0000000000..840a2355f1
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  PCH Reset PPI
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_RESET_PPI_H_
> +#define _PCH_RESET_PPI_H_
> +
> +//
> +// Member functions
> +//
> +/**
> +  Execute call back function for Pch Reset.
> +
> +  @param[in] ResetType            Reset Types which includes GlobalReset.
> +  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset
> Type Guid.
> +
> +  @retval EFI_SUCCESS             The callback function has been done
> successfully
> +  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback ppi. Or,
> none of
> +                                  callback ppi is installed.
> +  @retval Others                  Do not do any reset from PCH
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PCH_RESET_CALLBACK) (
> +  IN  EFI_RESET_TYPE    ResetType,
> +  IN  EFI_GUID          *ResetTypeGuid
> +  );
> +
> +/**
> +  This ppi is used to execute PCH Reset from the host controller.
> +  If drivers need to run their callback function right before issuing the PCH
> Reset,
> +  they can install PCH Reset Callback PPI before PCH Reset PEI driver to
> achieve that.
> +**/
> +typedef struct {
> +  PCH_RESET_CALLBACK  ResetCallback;
> +} PCH_RESET_CALLBACK_PPI;
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
> new file mode 100644
> index 0000000000..d3ff152742
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
> @@ -0,0 +1,27 @@
> +/** @file
> +  This file defines the PCH SPI PPI which implements the
> +  Intel(R) PCH SPI Host Controller Compatibility Interface.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SPI_PPI_H_
> +#define _PCH_SPI_PPI_H_
> +
> +#include <Protocol/Spi.h>
> +
> +//
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID           gPchSpiPpiGuid;
> +
> +/**
> +  Reuse the PCH_SPI_PROTOCOL definitions
> +  This is possible becaues the PPI implementation does not rely on a
> PeiService pointer,
> +  as it uses EDKII Glue Lib to do IO accesses
> +**/
> +typedef PCH_SPI_PROTOCOL PCH_SPI_PPI;
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
> new file mode 100644
> index 0000000000..59a9f0f251
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
> @@ -0,0 +1,28 @@
> +/** @file
> +  Watchdog Timer PPI
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_WDT_H_
> +#define _PEI_WDT_H_
> +
> +#include <Protocol/Wdt.h>
> +//
> +// MRC takes a lot of time to execute in debug mode
> +//
> +#define WDT_TIMEOUT_BETWEEN_PEI_DXE 60
> +
> +//
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID       gWdtPpiGuid;
> +
> +///
> +/// Reuse WDT_PROTOCOL definition
> +///
> +typedef WDT_PROTOCOL  WDT_PPI;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.
> h
> new file mode 100644
> index 0000000000..4f14065bd1
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.
> h
> @@ -0,0 +1,186 @@
> +/** @file
> +  PCH IO TrapEx Dispatch Protocol
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispat
> ch.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispat
> ch.h
> new file mode 100644
> index 0000000000..f3e788a2e1
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispat
> ch.h
> @@ -0,0 +1,136 @@
> +/** @file
> +  APIs of PCH ACPI SMI Dispatch Protocol.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
> new file mode 100644
> index 0000000000..45fae6e2d5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
> @@ -0,0 +1,68 @@
> +/** @file
> +  PCH eMMC HS400 Tuning Protocol
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_EMMC_TUNING_PROTOCOL_H_
> +#define _PCH_EMMC_TUNING_PROTOCOL_H_
> +
> +#define PCH_EMMC_TUNING_PROTOCOL_REVISION 1
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID  gPchEmmcTuningProtocolGuid;
> +
> +//
> +// Forward declaration for PCH_EMMC_TUNING_PROTOCOL
> +//
> +typedef struct _PCH_EMMC_TUNING_PROTOCOL
> PCH_EMMC_TUNING_PROTOCOL;
> +
> +/**
> +  This structure decribes the required Emmc info for HS400 tuning
> +**/
> +typedef struct {
> +  EFI_HANDLE                PartitionHandle;    ///< eMMC partition handle for
> block read/write
> +  EFI_LBA                   Lba;                ///< Logical Block Address for HS400
> Tuning block read/write
> +  UINT32                    RelativeDevAddress; ///< Device system address,
> dynamically assigned by the host during initialization.
> +  UINT8                     HS200BusWidth;      ///< The value to be
> programmed for BUS_WIDTH[183] byte
> +} EMMC_INFO;
> +
> +///
> +/// This structure describes the return value after HS400 tuning
> +///
> +typedef struct {
> +  UINT8       Hs400DataValid;     ///< Set if Hs400 Tuning Data is valid after
> tuning
> +  UINT8       Hs400RxStrobe1Dll;  ///< Rx Strobe Delay Control - Rx Strobe
> Delay DLL 1 (HS400 Mode)
> +  UINT8       Hs400TxDataDll;     ///< Tx Data Delay Control 1 - Tx Data Delay
> (HS400 Mode)
> +} EMMC_TUNING_DATA;
> +
> +///
> +/// EMMC HS400 TUNING INTERFACE
> +///
> +typedef EFI_STATUS (EFIAPI *EMMC_TUNE) (
> +  IN   PCH_EMMC_TUNING_PROTOCOL         *This,              ///< This
> pointer to PCH_EMMC_TUNING_PROTOCOL
> +  /**
> +    Revision parameter is used to verify the layout of EMMC_INFO and
> TUNINGDATA.
> +    If the revision is not matched, means the revision of EMMC_INFO and
> TUNINGDATA is not matched.
> +    And function will return immediately.
> +  **/
> +  IN   UINT8                            Revision,
> +  IN   EMMC_INFO                        *EmmcInfo,          ///< Pointer to
> EMMC_INFO
> +  OUT  EMMC_TUNING_DATA                 *EmmcTuningData     ///< Pointer
> to EMMC_TUNING_DATA
> +);
> +
> +/**
> +  PCH EMMC TUNING PROTOCOL INTERFACE
> +  Platform code uses this protocol to configure Emmc Hs400 mode, by passing
> the EMMC_INFO information.
> +  PCH will setting EMMC controller based on EMMC_INFO and return
> EMMC_TUNING_DATA to platform code.
> +  Platform should keep values of EMMC_TUNING_DATA and uses to configure
> EMMC through policies, to
> +  prevent from doing EMMC tuning every boot.
> +**/
> +struct _PCH_EMMC_TUNING_PROTOCOL {
> +  EMMC_TUNE  EmmcTune;  ///< Emmc Hs400 Tuning Interface
> +};
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispat
> ch.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispat
> ch.h
> new file mode 100644
> index 0000000000..9a180b4285
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispat
> ch.h
> @@ -0,0 +1,146 @@
> +/** @file
> +  SmmEspiDispatch Protocol
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatc
> h.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispat
> ch.h
> new file mode 100644
> index 0000000000..c5e8bc3f28
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispat
> ch.h
> @@ -0,0 +1,132 @@
> +/** @file
> +  APIs of PCH PCIE SMI Dispatch Protocol.
> +
> +  Copyright (c) 2019 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;
> +
> +//
> +// 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 to PCH PCIE Root Port 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
> new file mode 100644
> index 0000000000..ff35b43b61
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  Interface definition details between Pch and platform drivers during DXE
> phase.
> +
> +  Copyright (c) 2019 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 <Private/PchConfigHob.h>
> +#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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
> new file mode 100644
> index 0000000000..4c49d082fc
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  PCH Reset Protocol
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_RESET_PROTOCOL_H_
> +#define _PCH_RESET_PROTOCOL_H_
> +
> +//
> +// Member functions
> +//
> +/**
> +  Execute call back function for Pch Reset.
> +
> +  @param[in] ResetType            Reset Types which includes GlobalReset.
> +  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset
> Type Guid.
> +
> +  @retval EFI_SUCCESS             The callback function has been done
> successfully
> +  @retval EFI_NOT_FOUND           Failed to find Pch Reset Callback protocol.
> Or, none of
> +                                  callback protocol is installed.
> +  @retval Others                  Do not do any reset from PCH
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PCH_RESET_CALLBACK) (
> +  IN  EFI_RESET_TYPE    ResetType,
> +  IN  EFI_GUID          *ResetTypeGuid
> +  );
> +
> +/**
> +  This protocol is used to execute PCH Reset from the host controller.
> +  If drivers need to run their callback function right before issuing the PCH
> Reset,
> +  they can install PCH Reset Callback Protocol before PCH Reset DXE driver to
> achieve that.
> +**/
> +typedef struct {
> +  PCH_RESET_CALLBACK  ResetCallback;
> +} PCH_RESET_CALLBACK_PROTOCOL;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
> new file mode 100644
> index 0000000000..6fdfed1de7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
> @@ -0,0 +1,134 @@
> +/** @file
> +  APIs of PCH SMI Dispatch Protocol.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapCo
> ntrol.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapCo
> ntrol.h
> new file mode 100644
> index 0000000000..73386a570e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapCo
> ntrol.h
> @@ -0,0 +1,67 @@
> +/** @file
> +  PCH SMM IO Trap Control Protocol
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTi
> merControl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTi
> merControl.h
> new file mode 100644
> index 0000000000..06ddc3e1cd
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTi
> merControl.h
> @@ -0,0 +1,67 @@
> +/** @file
> +  PCH SMM Periodic Timer Control Protocol
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatc
> h.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatc
> h.h
> new file mode 100644
> index 0000000000..d397712092
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatc
> h.h
> @@ -0,0 +1,152 @@
> +/** @file
> +  APIs of PCH TCO SMI Dispatch Protocol.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
> new file mode 100644
> index 0000000000..ece65cd729
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
> @@ -0,0 +1,15 @@
> +/** @file
> +  SmmSmbus Protocol
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __EFI_SMM_SMBUS_PROTOCOL_H__
> +#define __EFI_SMM_SMBUS_PROTOCOL_H__
> +
> +extern EFI_GUID               gEfiSmmSmbusProtocolGuid;
> +
> +#endif
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
> new file mode 100644
> index 0000000000..22df7fe351
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
> @@ -0,0 +1,295 @@
> +/** @file
> +  This file defines the PCH SPI Protocol which implements the
> +  Intel(R) PCH SPI Host Controller Compatibility Interface.
> +
> +  Copyright (c) 2019 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,
> +  FlashRegionEC = 8,
> +  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
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
> new file mode 100644
> index 0000000000..67554e526f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
> @@ -0,0 +1,113 @@
> +/** @file
> +  Watchdog Timer protocol
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_WDT_H_
> +#define _DXE_WDT_H_
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID               gWdtProtocolGuid;
> +//
> +// Forward reference for ANSI C compatibility
> +//
> +typedef struct _WDT_PROTOCOL  WDT_PROTOCOL;
> +
> +/**
> +  Reloads WDT with new timeout value and starts it. Also sets Unexpected
> Reset bit, which
> +  causes the next reset to be treated as watchdog expiration - unless
> AllowKnownReset()
> +  function was called too.
> +
> +  @param[in] TimeoutValue         Time in seconds before WDT times out.
> Supported range = 1 - 1024.
> +
> +  @retval EFI_SUCCESS             if everything's OK
> +  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *WDT_RELOAD_AND_START) (
> +  UINT32 TimeoutValue
> +  );
> +
> +/**
> +  Returns WDT failure status.
> +
> +  @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE   If there was WDT
> expiration or unexpected reset
> +  @retval V_PCH_OC_WDT_CTL_STATUS_OK        Otherwise
> +**/
> +typedef
> +UINT8
> +(EFIAPI *WDT_CHECK_STATUS) (
> +  VOID
> +  );
> +
> +/**
> +  Returns information if WDT coverage for the duration of BIOS execution
> +  was requested by an OS application.
> +
> +  @retval TRUE                    if WDT was requested
> +  @retval FALSE                   if WDT was not requested
> +**/
> +typedef
> +UINT8
> +(EFIAPI *IS_WDT_REQUIRED) (
> +  VOID
> +  );
> +
> +/**
> +  Returns WDT enabled/disabled status.
> +
> +  @retval TRUE                    if WDT is enabled
> +  @retval FALSE                   if WDT is disabled
> +**/
> +typedef
> +UINT8
> +(EFIAPI *IS_WDT_ENABLED) (
> +  VOID
> +  );
> +
> +/**
> +  Disables WDT timer.
> +**/
> +typedef
> +VOID
> +(EFIAPI *WDT_DISABLE) (
> +  VOID
> +  );
> +
> +/**
> +  Normally, each reboot performed while watchdog runs is considered a
> failure.
> +  This function allows platform to perform expected reboots with WDT
> running,
> +  without being interpreted as failures.
> +  In DXE phase, it is enough to call this function any time before reset.
> +  In PEI phase, between calling this function and performing reset,
> ReloadAndStart()
> +  must not be called.
> +**/
> +typedef
> +VOID
> +(EFIAPI *WDT_ALLOW_KNOWN_RESET) (
> +  VOID
> +  );
> +
> +/**
> +  These protocols and PPI allow a platform module to perform watch dog
> timer operations
> +  through the Intel PCH LPC Host Controller Interface. The WDT protocol and
> WDT PPI
> +  implement the Intel (R) Watch Dog timer for DXE, and PEI environments,
> respectively.
> +  WDT_PROTOCOL referenced hereafter represents both WDT_PROTOCOL
> and WDT_PPI, as they
> +  share the identical data structure.
> +**/
> +struct _WDT_PROTOCOL {
> +  WDT_RELOAD_AND_START  ReloadAndStart;   ///< Reloads WDT with new
> timeout value and starts it.
> +  WDT_CHECK_STATUS      CheckStatus;      ///< Returns WDT failure status.
> +  WDT_DISABLE           Disable;          ///< Disables WDT timer.
> +  WDT_ALLOW_KNOWN_RESET AllowKnownReset;  ///< Perform expected
> reboots with WDT running, without being interpreted as failures.
> +  IS_WDT_REQUIRED       IsWdtRequired;    ///< Returns information if WDT
> coverage for the duration of BIOS execution was requested by an OS
> application.
> +  IS_WDT_ENABLED        IsWdtEnabled;     ///< Returns WDT
> enabled/disabled status.
> +};
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:09 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add
> Register include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the following header files:
>  * Pch/Include/Register
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h            |
> 54 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
> |  57 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
> | 122 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
> |  54 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
> |  62 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
> |  90 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
> | 273 ++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
> | 694 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
> | 204 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
> | 170 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
> |  79 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h        |
> 103 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
> |  58 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
> | 360 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
> |  61 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
> | 116 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
> | 484 ++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
> |  73 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
> | 670 +++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
> |  72 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
> | 104 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
> | 113 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
> |  77 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
> | 668 +++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
> |  52 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
> |  48 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
> | 232 +++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
> | 138 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
> | 151 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
> | 295 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.
> h  |  49 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
> | 134 ++++
>  32 files changed, 5917 insertions(+)
> 
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
> new file mode 100644
> index 0000000000..10fcb316fc
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
> @@ -0,0 +1,54 @@
> +/** @file
> +  Generic register definitions for PCH.
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 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
> +
> +//
> +// Default Vendor ID and Subsystem ID
> +//
> +#define V_PCH_INTEL_VENDOR_ID   0x8086      ///< Default Intel PCH
> Vendor ID
> +#define V_PCH_DEFAULT_SID       0x7270      ///< Default Intel PCH
> Subsystem ID
> +#define V_PCH_DEFAULT_SVID_SID  (V_INTEL_VENDOR_ID +
> (V_PCH_DEFAULT_SID << 16))   ///< Default INTEL PCH Vendor ID and
> Subsystem ID
> +
> +#endif //_PCH_REGS_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
> new file mode 100644
> index 0000000000..47dd73215e
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
> @@ -0,0 +1,57 @@
> +/** @file
> +  Register names for PCH DCI device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_DCI_H_
> +#define _PCH_REGS_DCI_H_
> +
> +//
> +// DCI PCR Registers
> +//
> +
> +#define R_DCI_PCR_ECTRL                       0x04            ///< DCI Control
> Register
> +
> +#define B_DCI_PCR_ECTRL_HDCIEN_LOCK           BIT0            ///< Host DCI
> Enable Lock
> +#define B_DCI_PCR_ECTRL_HDCIEN                BIT4            ///< Host DCI
> Enable
> +
> +#define R_DCI_PCR_ECKPWRCTL                   0x08            ///< DCI Power
> Control
> +// CNP-A0 (DCI Gen2) and backwards
> +#define R_DCI_PCR_PCE                         0x30            ///< DCI Power
> Control Enable Register
> +#define B_DCI_PCR_PCE_HAE                     BIT5            ///< Hardware
> Autonomous Enable
> +#define B_DCI_PCR_PCE_D3HE                    BIT2            ///< D3-Hot
> Enable
> +#define B_DCI_PCR_PCE_I3E                     BIT1            ///< I3 Enable
> +#define B_DCI_PCR_PCE_PMCRE                   BIT0            ///< PMC
> Request Enable
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
> new file mode 100644
> index 0000000000..44f708dd92
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
> @@ -0,0 +1,122 @@
> +/** @file
> +  Register names for DMI and OP-DMI
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_DMI_H_
> +#define _PCH_REGS_DMI_H_
> +
> +//
> +// DMI Chipset Configuration Registers (PID:DMI)
> +//
> +
> +//
> +// VC Configuration (Common)
> +//
> +#define B_PCH_DMI_PCR_V0CTL_EN               BIT31
> +#define B_PCH_DMI_PCR_V0CTL_ID               (7 << 24)                   ///<
> Bit[26:24]
> +#define N_PCH_DMI_PCR_V0CTL_ID               24
> +#define V_PCH_DMI_PCR_V0CTL_ETVM_MASK        0xFC00
> +#define V_PCH_DMI_PCR_V0CTL_TVM_MASK         0x7E
> +#define B_PCH_DMI_PCR_V0STS_NP               BIT1
> +#define B_PCH_DMI_PCR_V1CTL_EN               BIT31
> +#define B_PCH_DMI_PCR_V1CTL_ID               (0x0F << 24)                ///<
> Bit[27:24]
> +#define N_PCH_DMI_PCR_V1CTL_ID               24
> +#define V_PCH_DMI_PCR_V1CTL_ETVM_MASK        0xFC00
> +#define V_PCH_DMI_PCR_V1CTL_TVM_MASK         0xFE
> +#define B_PCH_DMI_PCR_V1STS_NP               BIT1
> +
> +
> +//
> +// DMI Source Decode PCRs (Common)
> +//
> +#define R_PCH_DMI_PCR_PCIEPAR1E         0x2700                ///< PCIE Port
> IOxAPIC Range 1 Enable
> +#define R_PCH_DMI_PCR_PCIEPAR2E         0x2704                ///< PCIE Port
> IOxAPIC Range 2 Enable
> +#define R_PCH_DMI_PCR_PCIEPAR3E         0x2708                ///< PCIE Port
> IOxAPIC Range 3 Enable
> +#define R_PCH_DMI_PCR_PCIEPAR4E         0x270C                ///< PCIE Port
> IOxAPIC Range 4 Enable
> +#define R_PCH_DMI_PCR_PCIEPAR1DID       0x2710                ///< PCIE
> Port IOxAPIC Range 1 Destination ID
> +#define R_PCH_DMI_PCR_PCIEPAR2DID       0x2714                ///< PCIE
> Port IOxAPIC Range 2 Destination ID
> +#define R_PCH_DMI_PCR_PCIEPAR3DID       0x2718                ///< PCIE
> Port IOxAPIC Range 3 Destination ID
> +#define R_PCH_DMI_PCR_PCIEPAR4DID       0x271C                ///< PCIE
> Port IOxAPIC Range 4 Destination ID
> +#define R_PCH_DMI_PCR_P2SBIOR           0x2720                ///< P2SB IO
> Range
> +#define R_PCH_DMI_PCR_TTTBARB           0x2724                ///< Thermal
> Throttling BIOS Assigned Thermal Base Address
> +#define R_PCH_DMI_PCR_TTTBARBH          0x2728                ///< Thermal
> Throttling BIOS Assigned Thermal Base High Address
> +#define R_PCH_DMI_PCR_LPCLGIR1          0x2730                ///< LPC
> Generic I/O Range 1
> +#define R_PCH_DMI_PCR_LPCLGIR2          0x2734                ///< LPC
> Generic I/O Range 2
> +#define R_PCH_DMI_PCR_LPCLGIR3          0x2738                ///< LPC
> Generic I/O Range 3
> +#define R_PCH_DMI_PCR_LPCLGIR4          0x273C                ///< LPC
> Generic I/O Range 4
> +#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_RPRDID            0xFFFF0000            ///< RPR
> Destination ID
> +#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_IOT2              0x2758                ///< I/O Trap
> Register 2
> +#define R_PCH_DMI_PCR_IOT3              0x2760                ///< I/O Trap
> Register 3
> +#define R_PCH_DMI_PCR_IOT4              0x2768                ///< I/O Trap
> Register 4
> +#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
> +#define R_PCH_DMI_PCR_GPMR2             0x2784                ///< General
> Purpose Memory Range 2
> +#define R_PCH_DMI_PCR_GPMR2DID          0x2788                ///< General
> Purpose Memory Range 2 Destination ID
> +#define R_PCH_DMI_PCR_GPMR3             0x278C                ///< General
> Purpose Memory Range 3
> +#define R_PCH_DMI_PCR_GPMR3DID          0x2790                ///< General
> Purpose Memory Range 3 Destination ID
> +#define R_PCH_DMI_PCR_GPIOR1            0x2794                ///< General
> Purpose I/O Range 1
> +#define R_PCH_DMI_PCR_GPIOR1DID         0x2798                ///< General
> Purpose I/O Range 1 Destination ID
> +#define R_PCH_DMI_PCR_GPIOR2            0x279C                ///< General
> Purpose I/O Range 2
> +#define R_PCH_DMI_PCR_GPIOR2DID         0x27A0                ///< General
> Purpose I/O Range 2 Destination ID
> +#define R_PCH_DMI_PCR_GPIOR3            0x27A4                ///< General
> Purpose I/O Range 3
> +#define R_PCH_DMI_PCR_GPIOR3DID         0x27A8                ///< General
> Purpose I/O Range 3 Destination ID
> +
> +//
> +// Opi PHY registers
> +//
> +#define R_PCH_OPIPHY_PCR_0110           0x0110
> +#define R_PCH_OPIPHY_PCR_0118           0x0118
> +#define R_PCH_OPIPHY_PCR_011C           0x011C
> +#define R_PCH_OPIPHY_PCR_0354           0x0354
> +#define R_PCH_OPIPHY_PCR_B104           0xB104
> +#define R_PCH_OPIPHY_PCR_B10C           0xB10C
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
> new file mode 100644
> index 0000000000..36c0054d63
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
> @@ -0,0 +1,54 @@
> +/** @file
> +  Register names for DMI SIP14
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_DMI14_H_
> +#define _PCH_REGS_DMI14_H_
> +
> +//
> +// DMI Chipset Configuration Registers (PID:DMI)
> +//
> +
> +//
> +// DMI Control
> +//
> +#define R_PCH_DMI14_PCR_DMIC                   0x2234
> ///< DMI Control
> +#define B_PCH_DMI14_PCR_DMIC_SRL               BIT31
> ///< Secured register lock
> +#define B_PCH_DMI14_PCR_DMIC_DMICGEN           (BIT4 | BIT3 | BIT2 |
> BIT1 | BIT0)  ///< DMI Clock Gate Enable
> +
> +#define R_PCH_DMI14_PCR_2314                   0x2314
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
> new file mode 100644
> index 0000000000..c885fdd34d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
> @@ -0,0 +1,62 @@
> +/** @file
> +  Register names for DMI and OP-DMI
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_DMI15_H_
> +#define _PCH_REGS_DMI15_H_
> +
> +#define R_PCH_DMI15_PCR_MPC                 0x20D8                       ///<
> Miscellaneous Port Configuration
> +#define B_PCH_DMI15_PCR_MPC_SRL             BIT23                        ///<
> Secured register lock
> +#define R_PCH_DMI15_PCR_V0CTL               0x2284                       ///<
> Virtual channel 0 resource control
> +#define R_PCH_DMI15_PCR_V0STS               0x228A                       ///<
> Virtual channel 0 status
> +
> +#define R_PCH_DMI15_PCR_V1CTL               0x2290                       ///<
> Virtual channel 1 resource control
> +#define R_PCH_DMI15_PCR_V1STS               0x2296                       ///<
> Virtual channel 1 status
> +
> +#define R_PCH_DMI15_PCR_VMCTL               0x22B0                       ///<
> ME Virtual Channel (VCm) resource control
> +
> +#define R_PCH_DMI15_PCR_UPHWAWC             0x249C
> ///< Upstream Port HW Autonomous Width Control
> +#define B_PCH_DMI15_PCR_UPHWAWC_TS3TW       (BIT15 | BIT14 | BIT13)
> ///< Thermal Sensor 3 Target Width
> +#define N_PCH_DMI15_PCR_UPHWAWC_TS3TW       13
> ///< Thermal Sensor 3 Target Width
> +#define B_PCH_DMI15_PCR_UPHWAWC_TS2TW       (BIT12 | BIT11 | BIT10)
> ///< Thermal Sensor 2 Target Width
> +#define N_PCH_DMI15_PCR_UPHWAWC_TS2TW       10
> ///< Thermal Sensor 2 Target Width
> +#define B_PCH_DMI15_PCR_UPHWAWC_TS1TW       (BIT9 | BIT8 | BIT7)
> ///< Thermal Sensor 1 Target Width
> +#define N_PCH_DMI15_PCR_UPHWAWC_TS1TW       7
> ///< Thermal Sensor 1 Target Width
> +#define B_PCH_DMI15_PCR_UPHWAWC_TS0TW       (BIT6 | BIT5 | BIT4)
> ///< Thermal Sensor 0 Target Width
> +#define N_PCH_DMI15_PCR_UPHWAWC_TS0TW       4
> ///< Thermal Sensor 0 Target Width
> +#define B_PCH_DMI15_PCR_UPHWAWC_TSAWEN      BIT0
> ///< Thermal Sensor Autonomous Width Enable
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
> new file mode 100644
> index 0000000000..837fdc5609
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
> @@ -0,0 +1,90 @@
> +/** @file
> +  Register definition for FIA component
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_FIA_H_
> +#define _PCH_REGS_FIA_H_
> +
> +
> +//
> +// Private chipset register (Memory space) offset definition
> +// The PCR register defines is used for PCR MMIO programming and PCH SBI
> programming as well.
> +//
> +
> +//
> +// PCH FIA lane owner encoding
> +//
> +#define V_PCH_FIA_PCR_LANE_OWN_PCIEDMI                    0x0
> +#define V_PCH_FIA_PCR_LANE_OWN_USB3                       0x1
> +#define V_PCH_FIA_PCR_LANE_OWN_SATA                       0x2
> +#define V_PCH_FIA_PCR_LANE_OWN_GBE                        0x3
> +#define V_PCH_FIA_PCR_LANE_OWN_MOBEXP                     0x4
> +#define V_PCH_FIA_PCR_LANE_OWN_SSIC                       0x5
> +#define V_PCH_FIA_PCR_LANE_OWN_CSI3                       0x6
> +#define V_PCH_FIA_PCR_LANE_OWN_UFS                        0x7
> +
> +#define B_PCH_FIA_PCR_L0O                                 (BIT3 | BIT2 | BIT1 |
> BIT0)
> +#define B_PCH_FIA_PCR_L1O                                 (BIT7 | BIT6 | BIT5 |
> BIT4)
> +#define B_PCH_FIA_PCR_L2O                                 (BIT11 | BIT10 | BIT9 |
> BIT8)
> +#define B_PCH_FIA_PCR_L3O                                 (BIT15 | BIT14 | BIT13 |
> BIT12)
> +#define B_PCH_FIA_PCR_L4O                                 (BIT19 | BIT18 | BIT17 |
> BIT16)
> +#define B_PCH_FIA_PCR_L5O                                 (BIT23 | BIT22 | BIT21 |
> BIT20)
> +#define B_PCH_FIA_PCR_L6O                                 (BIT27 | BIT26 | BIT25 |
> BIT24)
> +#define B_PCH_FIA_PCR_L7O                                 (BIT31 | BIT30 | BIT29 |
> BIT28)
> +#define B_PCH_FIA_PCR_L8O                                 (BIT3 | BIT2 | BIT1 |
> BIT0)
> +#define B_PCH_FIA_PCR_L9O                                 (BIT7 | BIT6 | BIT5 |
> BIT4)
> +#define B_PCH_FIA_PCR_L10O                                (BIT11 | BIT10 | BIT9 |
> BIT8)
> +#define B_PCH_FIA_PCR_L11O                                (BIT15 | BIT14 | BIT13 |
> BIT12)
> +#define B_PCH_FIA_PCR_L12O                                (BIT19 | BIT18 | BIT17 |
> BIT16)
> +#define B_PCH_FIA_PCR_L13O                                (BIT23 | BIT22 | BIT21 |
> BIT20)
> +#define B_PCH_FIA_PCR_L14O                                (BIT27 | BIT26 | BIT25 |
> BIT24)
> +#define B_PCH_FIA_PCR_L15O                                (BIT31 | BIT30 | BIT29 |
> BIT28)
> +#define B_PCH_FIA_PCR_L16O                                (BIT3 | BIT2 | BIT1 |
> BIT0)
> +#define B_PCH_FIA_PCR_L17O                                (BIT7 | BIT6 | BIT5 |
> BIT4)
> +#define B_PCH_FIA_PCR_L18O                                (BIT11 | BIT10 | BIT9 |
> BIT8)
> +#define B_PCH_FIA_PCR_L19O                                (BIT15 | BIT14 | BIT13 |
> BIT12)
> +#define B_PCH_FIA_PCR_L20O                                (BIT19 | BIT18 | BIT17 |
> BIT16)
> +#define B_PCH_FIA_PCR_L21O                                (BIT23 | BIT22 | BIT21 |
> BIT20)
> +#define B_PCH_FIA_PCR_L22O                                (BIT27 | BIT26 | BIT25 |
> BIT24)
> +#define B_PCH_FIA_PCR_L23O                                (BIT31 | BIT30 | BIT29 |
> BIT28)
> +#define B_PCH_FIA_PCR_L24O                                (BIT3 | BIT2 | BIT1 |
> BIT0)
> +#define B_PCH_FIA_PCR_L25O                                (BIT7 | BIT6 | BIT5 |
> BIT4)
> +#define B_PCH_FIA_PCR_L26O                                (BIT11 | BIT10 | BIT9 |
> BIT8)
> +#define B_PCH_FIA_PCR_L27O                                (BIT15 | BIT14 | BIT13 |
> BIT12)
> +#define B_PCH_FIA_PCR_L28O                                (BIT19 | BIT18 | BIT17 |
> BIT16)
> +#define B_PCH_FIA_PCR_L29O                                (BIT23 | BIT22 | BIT21 |
> BIT20)
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
> new file mode 100644
> index 0000000000..3f614ba002
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
> @@ -0,0 +1,273 @@
> +/** @file
> +  Register names for PCH GPIO
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_GPIO_H_
> +#define _PCH_REGS_GPIO_H_
> +
> +//
> +// GPIO Common Private Configuration Registers
> +//
> +#define R_GPIO_PCR_REV_ID               0x00
> +#define R_GPIO_PCR_CAP_LIST             0x04
> +#define R_GPIO_PCR_FAMBAR               0x08
> +#define R_GPIO_PCR_PADBAR               0x0C
> +#define B_GPIO_PCR_PADBAR               0x0000FFFF
> +#define R_GPIO_PCR_MISCCFG              0x10
> +#define B_GPIO_PCR_MISCCFG_IRQ_ROUTE    0xFF000000
> +#define N_GPIO_PCR_MISCCFG_IRQ_ROUTE    24
> +#define B_GPIO_PCR_MISCCFG_GPE0_DW2     (BIT19 | BIT18 | BIT17 | BIT16)
> +#define N_GPIO_PCR_MISCCFG_GPE0_DW2     16
> +#define B_GPIO_PCR_MISCCFG_GPE0_DW1     (BIT15 | BIT14 | BIT13 | BIT12)
> +#define N_GPIO_PCR_MISCCFG_GPE0_DW1     12
> +#define B_GPIO_PCR_MISCCFG_GPE0_DW0     (BIT11 | BIT10 | BIT9 | BIT8)
> +#define N_GPIO_PCR_MISCCFG_GPE0_DW0     8
> +#define B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN    BIT5
> +#define B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN  BIT4
> +#define B_GPIO_PCR_MISCCFG_GPRTCDLCGEN     BIT3
> +#define B_GPIO_PCR_MISCCFG_GPDPCGEN     BIT1
> +#define B_GPIO_PCR_MISCCFG_GPDLCGEN     BIT0
> +
> +//
> +// GPIO SerialBlink/PWM registers
> +//
> +#define R_GPIO_PCR_CAP_LIST_1_PWM         0x0200
> +#define R_GPIO_PCR_PWMC                   0x0204
> +#define R_GPIO_PCR_CAP_LIST_2_SER_BLINK   0x0208
> +#define R_GPIO_PCR_GP_SER_BLINK           0x020C
> +#define B_GPIO_PCR_GP_SER_BLINK           0x1F
> +#define R_GPIO_PCR_GP_SER_CMDSTS          0x0210
> +#define B_GPIO_PCR_GP_SER_CMDSTS_DLS      (BIT23 | BIT22)
> +#define N_GPIO_PCR_GP_SER_CMDSTS_DLS      22
> +#define B_GPIO_PCR_GP_SER_CMDSTS_DRS      0x003F0000
> +#define N_GPIO_PCR_GP_SER_CMDSTS_DRS      16
> +#define B_GPIO_PCR_GP_SER_CMDSTS_BUSY     BIT8
> +#define B_GPIO_PCR_GP_SER_CMDSTS_GO       BIT0
> +#define R_GPIO_PCR_GP_SER_DATA            0x0210
> +
> +//
> +// 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 Pad State Select
> +#define B_GPIO_PCR_RX_PAD_STATE         BIT29
> +#define N_GPIO_PCR_RX_PAD_STATE         29
> +#define V_GPIO_PCR_RX_PAD_STATE_RAW     0x00
> +#define V_GPIO_PCR_RX_PAD_STATE_INT     0x01
> +
> +//RX Raw Overrride to 1
> +#define B_GPIO_PCR_RX_RAW1              BIT28
> +#define N_GPIO_PCR_RX_RAW1              28
> +#define V_GPIO_PCR_RX_RAW1_DIS          0x00
> +#define V_GPIO_PCR_RX_RAW1_EN           0x01
> +
> +//RX Level/Edge Configuration
> +#define B_GPIO_PCR_RX_LVL_EDG           (BIT26 | BIT25)
> +#define N_GPIO_PCR_RX_LVL_EDG           25
> +#define V_GPIO_PCR_RX_LVL_EDG_LVL       0x00
> +#define V_GPIO_PCR_RX_LVL_EDG_EDG       0x01
> +#define V_GPIO_PCR_RX_LVL_EDG_0         0x02
> +#define V_GPIO_PCR_RX_LVL_EDG_RIS_FAL   0x03
> +
> +//RX Invert
> +#define B_GPIO_PCR_RXINV                BIT23
> +#define N_GPIO_PCR_RXINV                23
> +#define V_GPIO_PCR_RXINV_NO             0x00
> +#define V_GPIO_PCR_RXINV_YES            0x01
> +
> +//GPIO Input Route IOxAPIC
> +#define B_GPIO_PCR_RX_APIC_ROUTE        BIT20
> +#define N_GPIO_PCR_RX_APIC_ROUTE        20
> +#define V_GPIO_PCR_RX_APIC_ROUTE_DIS    0x00
> +#define V_GPIO_PCR_RX_APIC_ROUTE_EN     0x01
> +
> +//GPIO Input Route SCI
> +#define B_GPIO_PCR_RX_SCI_ROUTE         BIT19
> +#define N_GPIO_PCR_RX_SCI_ROUTE         19
> +#define V_GPIO_PCR_RX_SCI_ROUTE_DIS     0x00
> +#define V_GPIO_PCR_RX_SCI_ROUTE_EN      0x01
> +
> +//GPIO Input Route SMI
> +#define B_GPIO_PCR_RX_SMI_ROUTE         BIT18
> +#define N_GPIO_PCR_RX_SMI_ROUTE         18
> +#define V_GPIO_PCR_RX_SMI_ROUTE_DIS     0x00
> +#define V_GPIO_PCR_RX_SMI_ROUTE_EN      0x01
> +
> +//GPIO Input Route NMI
> +#define B_GPIO_PCR_RX_NMI_ROUTE         BIT17
> +#define N_GPIO_PCR_RX_NMI_ROUTE         17
> +#define V_GPIO_PCR_RX_NMI_ROUTE_DIS     0x00
> +#define V_GPIO_PCR_RX_NMI_ROUTE_EN      0x01
> +
> +//GPIO Pad Mode
> +#define B_GPIO_PCR_PAD_MODE             (BIT12 | BIT11 | BIT10)
> +#define N_GPIO_PCR_PAD_MODE             10
> +#define V_GPIO_PCR_PAD_MODE_GPIO        0
> +#define V_GPIO_PCR_PAD_MODE_NAT_1       1
> +#define V_GPIO_PCR_PAD_MODE_NAT_2       2
> +#define V_GPIO_PCR_PAD_MODE_NAT_3       3
> +#define V_GPIO_PCR_PAD_MODE_NAT_4       4 // SPT-H only
> +
> +//GPIO RX Disable
> +#define B_GPIO_PCR_RXDIS                BIT9
> +#define N_GPIO_PCR_RXDIS                9
> +#define V_GPIO_PCR_RXDIS_EN             0x00
> +#define V_GPIO_PCR_RXDIS_DIS            0x01
> +
> +//GPIO TX Disable
> +#define B_GPIO_PCR_TXDIS                BIT8
> +#define N_GPIO_PCR_TXDIS                8
> +#define V_GPIO_PCR_TXDIS_EN             0x00
> +#define V_GPIO_PCR_TXDIS_DIS            0x01
> +
> +//GPIO RX State
> +#define B_GPIO_PCR_RX_STATE             BIT1
> +#define N_GPIO_PCR_RX_STATE             1
> +#define V_GPIO_PCR_RX_STATE_LOW         0x00
> +#define V_GPIO_PCR_RX_STATE_HIGH        0x01
> +
> +//GPIO TX State
> +#define B_GPIO_PCR_TX_STATE             BIT0
> +#define N_GPIO_PCR_TX_STATE             0
> +#define V_GPIO_PCR_TX_STATE_LOW         0x00
> +#define V_GPIO_PCR_TX_STATE_HIGH        0x01
> +
> +//
> +// Pad Configuration Register DW1
> +//
> +
> +//Padtol
> +#define B_GPIO_PCR_PADTOL               BIT25
> +#define N_GPIO_PCR_PADTOL               25
> +#define V_GPIO_PCR_PADTOL_NONE          0x00
> +#define V_GPIO_PCR_PADTOL_CLEAR         0x00
> +#define V_GPIO_PCR_PADTOL_SET           0x01
> +
> +//Termination
> +#define B_GPIO_PCR_TERM                (BIT13 | BIT12 | BIT11 | BIT10)
> +#define N_GPIO_PCR_TERM                 10
> +#define V_GPIO_PCR_TERM_WPD_NONE        0x00
> +#define V_GPIO_PCR_TERM_WPD_5K          0x02
> +#define V_GPIO_PCR_TERM_WPD_20K         0x04
> +#define V_GPIO_PCR_TERM_WPU_NONE        0x08
> +#define V_GPIO_PCR_TERM_WPU_1K          0x09
> +#define V_GPIO_PCR_TERM_WPU_2K          0x0B
> +#define V_GPIO_PCR_TERM_WPU_5K          0x0A
> +#define V_GPIO_PCR_TERM_WPU_20K         0x0C
> +#define V_GPIO_PCR_TERM_WPU_1K_2K       0x0D
> +#define V_GPIO_PCR_TERM_NATIVE          0x0F
> +
> +//Interrupt number
> +#define B_GPIO_PCR_INTSEL               0x7F
> +#define N_GPIO_PCR_INTSEL               0
> +
> +//
> +//Debounce
> +#define B_GPIO_PCR_DEBOUNCE             (BIT4 | BIT3 | BIT2 | BIT1)
> +#define N_GPIO_PCR_DEBOUNCE              1
> +
> +//Debounce Enable
> +#define B_GPIO_PCR_DEBEN                 BIT0
> +#define N_GPIO_PCR_DEBEN                 0
> +
> +//
> +// Ownership
> +//
> +#define V_GPIO_PCR_OWN_GPIO             0x01
> +#define V_GPIO_PCR_OWN_ACPI             0x00
> +
> +//
> +// GPE
> +//
> +#define V_GPIO_PCR_GPE_EN               0x01
> +#define V_GPIO_PCR_GPE_DIS              0x00
> +//
> +// SMI
> +//
> +#define V_GPIO_PCR_SMI_EN               0x01
> +#define V_GPIO_PCR_SMI_DIS              0x00
> +//
> +// NMI
> +//
> +#define V_GPIO_PCR_NMI_EN               0x01
> +#define V_GPIO_PCR_NMI_DIS              0x00
> +
> +//
> +// GPIO native features pins data
> +//
> +#define PCH_GPIO_HDA_LINK_NUMBER_OF_PINS     6
> +#define PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS     2
> +#define PCH_GPIO_HDA_SSP_NUMBER_OF_PINS      4
> +#define PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS     2
> +#define PCH_GPIO_SMBUS_NUMBER_OF_PINS        2
> +#define PCH_GPIO_CPU_GP_NUMBER_OF_PINS       4
> +#define PCH_GPIO_EDP_NUMBER_OF_PINS          4
> +#define PCH_GPIO_DDSP_HPD_NUMBER_OF_PINS     4
> +#define PCH_GPIO_DDP_NUMBER_OF_INTERFACES    4
> +#define PCH_GPIO_DDP_NUMBER_OF_PINS          2
> +#define PCH_GPIO_CNVI_UART_NUMBER_OF_PINS    4
> +#define PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS     4
> +#define PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS 4
> +
> +
> +///
> +/// 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_EN                4
> +#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
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
> new file mode 100644
> index 0000000000..140c758730
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
> @@ -0,0 +1,694 @@
> +/** @file
> +  Register names for GPIO
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_GPIO_CNL_H_
> +#define _PCH_REGS_GPIO_CNL_H_
> +
> +//
> +// PCH-LP GPIO
> +//
> +#define CNL_PCH_LP_GPIO_GROUP_MAX             15
> +
> +#define CNL_PCH_LP_GPIO_GPP_A_PAD_MAX         25
> +#define CNL_PCH_LP_GPIO_GPP_B_PAD_MAX         26
> +#define CNL_PCH_LP_GPIO_GPP_C_PAD_MAX         24
> +#define CNL_PCH_LP_GPIO_GPP_D_PAD_MAX         24
> +#define CNL_PCH_LP_GPIO_GPP_E_PAD_MAX         24
> +#define CNL_PCH_LP_GPIO_GPP_F_PAD_MAX         24
> +#define CNL_PCH_LP_GPIO_GPP_G_PAD_MAX         8
> +#define CNL_PCH_LP_GPIO_GPP_H_PAD_MAX         24
> +#define CNL_PCH_LP_GPIO_GPD_PAD_MAX           16
> +#define CNL_PCH_LP_GPIO_VGPIO_PAD_MAX         40
> +#define CNL_PCH_LP_GPIO_SPI_PAD_MAX           9
> +#define CNL_PCH_LP_GPIO_AZA_PAD_MAX           8
> +#define CNL_PCH_LP_GPIO_CPU_PAD_MAX           11
> +#define CNL_PCH_LP_GPIO_JTAG_PAD_MAX          9
> +#define CNL_PCH_LP_GPIO_HVMOS_PAD_MAX         6
> +
> +//
> +// PCH-H GPIO
> +//
> +#define CNL_PCH_H_GPIO_GROUP_MAX              17
> +
> +#define CNL_PCH_H_GPIO_GPP_A_PAD_MAX          25
> +#define CNL_PCH_H_GPIO_GPP_B_PAD_MAX          26
> +#define CNL_PCH_H_GPIO_GPP_C_PAD_MAX          24
> +#define CNL_PCH_H_GPIO_GPP_D_PAD_MAX          24
> +#define CNL_PCH_H_GPIO_GPP_E_PAD_MAX          13
> +#define CNL_PCH_H_GPIO_GPP_F_PAD_MAX          24
> +#define CNL_PCH_H_GPIO_GPP_G_PAD_MAX          8
> +#define CNL_PCH_H_GPIO_GPP_H_PAD_MAX          24
> +#define CNL_PCH_H_GPIO_GPP_I_PAD_MAX          18
> +#define CNL_PCH_H_GPIO_GPP_J_PAD_MAX          12
> +#define CNL_PCH_H_GPIO_GPP_K_PAD_MAX          24
> +#define CNL_PCH_H_GPIO_GPD_PAD_MAX            16
> +#define CNL_PCH_H_GPIO_VGPIO_PAD_MAX          40
> +#define CNL_PCH_H_GPIO_SPI_PAD_MAX            9
> +#define CNL_PCH_H_GPIO_AZA_PAD_MAX            8
> +#define CNL_PCH_H_GPIO_CPU_PAD_MAX            11
> +#define CNL_PCH_H_GPIO_JTAG_PAD_MAX           9
> +
> +//
> +// PCH-LP GPIO registers
> +//
> +//
> +// GPIO Community Common Private Configuration Registers
> +//
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A     0x0
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B     0x1
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C     0xC
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D     0x4
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E     0xD
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F     0x5
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G     0x2
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H     0x6
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD       0x9
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO     0x7
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI       0x3
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA       0xA
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_CPU       0xB
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG      0xE
> +#define V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_HVMOS     0xF
> +
> +//
> +// GPIO Community 0 Private Configuration Registers
> +//
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN        0x20
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN        0x30
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN        0x40
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN          0x44
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK     0x80
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX   0x84
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK     0x88
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX   0x8C
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK     0x90
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX   0x94
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK       0x98
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX     0x9C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN     0xB0
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN     0xB4
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN     0xB8
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN       0xBC
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS         0x0100
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS         0x0104
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS         0x0108
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS           0x010C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE         0x0120
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE         0x0124
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE         0x0128
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE           0x012C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS    0x0140
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS    0x0144
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS    0x0148
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS      0x014C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN     0x0160
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN     0x0164
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN     0x0168
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN       0x016C
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_SMI_STS        0x0180  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS        0x0184
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_SMI_STS        0x0188  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_SPI_SMI_STS          0x018C  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_SMI_EN         0x01A0  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN         0x01A4
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_SMI_EN         0x01A8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_SPI_SMI_EN           0x01AC  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_NMI_STS        0x01C0  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS        0x01C4
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_NMI_STS        0x01C8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_SPI_NMI_STS          0x01CC  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_NMI_EN         0x01E0  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN         0x01E4
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_NMI_EN         0x01E8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_SPI_NMI_EN           0x01EC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET  0x600
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET  0x790
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET  0x930
> +#define R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET    0x9B0
> +
> +//
> +// GPIO Community 1 Private Configuration Registers
> +//
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN        0x20
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN        0x30
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN        0x3C
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN        0x48
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK     0x80
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX   0x84
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK     0x88
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX   0x8C
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK     0x90
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX   0x94
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK   0x98
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX 0x9C
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_1_PADCFGLOCK   0xA0
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_1_PADCFGLOCKTX 0xA4
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN     0xB0
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN     0xB4
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN     0xB8
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN     0xBC
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS         0x0100
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS         0x0104
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS         0x0108
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS         0x010C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE         0x0120
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE         0x0124
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE         0x0128
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE         0x012C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS    0x0140
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS    0x0144
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS    0x0148
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS    0x014C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN     0x0160
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN     0x0164
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN     0x0168
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN     0x016C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS        0x0180
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_SMI_STS        0x0184  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_SMI_STS        0x0188  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_SMI_STS        0x018C  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN         0x01A0
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_SMI_EN         0x01A4  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_SMI_EN         0x01A8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_SMI_EN         0x01AC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS        0x01C0
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_NMI_STS        0x01C4  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_NMI_STS        0x01C8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_NMI_STS        0x01CC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN         0x01E0
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_NMI_EN         0x01E4  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_NMI_EN         0x01E8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_NMI_EN         0x01EC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET  0x600
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET  0x790
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET  0x910
> +#define R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET  0xA90
> +
> +//
> +// GPIO Community 2 Private Configuration Registers
> +//
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN          0x20
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK       0x80
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX     0x84
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN       0xB0
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS           0x0100
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE           0x0120
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS      0x0140
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN       0x0160
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPD_SMI_STS        0x0180  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPD_SMI_EN         0x01A0  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPD_NMI_STS        0x01C0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_GPD_NMI_EN         0x01E0  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET    0x600
> +
> +//
> +// GPIO Community 3 Private Configuration Registers
> +//
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN          0x20
> +#define R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN          0x24
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK       0x80
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX     0x84
> +#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK       0x88
> +#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX     0x8C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN       0xB0
> +#define R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN       0xB4
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS           0x0100
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_IS           0x0104  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE           0x0120
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_IE           0x0124  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS      0x0140
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_GPE_STS      0x0144  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN       0x0160
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_GPI_GPE_EN       0x0164  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_AZA_SMI_STS          0x0180  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_SMI_STS          0x0184  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_AZA_SMI_EN           0x01A0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_SMI_EN           0x01A4  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_AZA_NMI_STS          0x01C0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_NMI_STS          0x01C4  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_LP_GPIO_PCR_AZA_NMI_EN           0x01E0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_CPU_NMI_EN           0x01E4  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET    0x600
> +#define R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET    0x680
> +
> +//
> +// GPIO Community 4 Private Configuration Registers
> +//
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN        0x20
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN        0x2C
> +#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN         0x38
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN        0x40
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK     0x80
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX   0x84
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK     0x88
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX   0x8C
> +#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK      0x90
> +#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX    0x94
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK     0x98
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX   0x9C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN     0xB0
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN     0xB4
> +#define R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN      0xB8
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN     0xBC
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS         0x0100
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS         0x0104
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_IS          0x0108  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS         0x010C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE         0x0120
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE         0x0124
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_IE          0x0128  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE         0x012C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS    0x0140
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS    0x0144
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_GPE_STS     0x0148  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS    0x014C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN     0x0160
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN     0x0164
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_GPI_GPE_EN      0x0168  // Not
> supported setting for this group
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN     0x016C
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS        0x0180
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS        0x0184
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_SMI_STS         0x0188  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_SMI_STS        0x018C  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN         0x01A0
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN         0x01A4
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_SMI_EN          0x01A8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_SMI_EN         0x01AC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS        0x01C0
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS        0x01C4
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_NMI_STS         0x01C8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_NMI_STS        0x01CC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN         0x01E0
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN         0x01E4
> +//#define R_CNL_PCH_LP_GPIO_PCR_JTAG_NMI_EN          0x01E8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_NMI_EN         0x01EC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET  0x600
> +#define R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET  0x780
> +#define R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET   0x900
> +#define R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET  0x990
> +
> +//
> +// PCH-H GPIO registers
> +//
> +//
> +// GPIO Community Common Private Configuration Registers
> +//
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A      0x0
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B      0x1
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C      0x2
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D      0x3
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E      0x6
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F      0x7
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G      0x4
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H      0x8
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K      0x9
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I      0xA
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J      0xB
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD        0x5
> +#define V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO      0xD
> +
> +//
> +// GPIO Community 0 Private Configuration Registers
> +//
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN         0x20
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN         0x30
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK      0x80
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX    0x84
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK      0x88
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX    0x8C
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN      0xC0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN      0xC4
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS          0x0100
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS          0x0104
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE          0x0120
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE          0x0124
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS     0x0140
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS     0x0144
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN      0x0160
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN      0x0164
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_SMI_STS         0x0180  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS         0x0184
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_SMI_EN          0x01A0  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN          0x01A4
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_NMI_STS         0x01C0  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS         0x01C4
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_A_NMI_EN          0x01E0  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN          0x01E4
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET   0x600
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET   0x790
> +
> +//
> +// GPIO Community 1 Private Configuration Registers
> +//
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN         0x20
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN         0x2C
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN         0x38
> +#define R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN           0x3C
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN         0x40
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK      0x80
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX    0x84
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK      0x88
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX    0x8C
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK      0x90
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX    0x94
> +#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK        0x98
> +#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX      0x9C
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK    0xA0
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX  0xA4
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_1_PADCFGLOCK    0xA8
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_1_PADCFGLOCKTX  0xAC
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN      0xC0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN      0xC4
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN      0xC8
> +#define R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN        0xCC
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN      0xD0
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS          0x0100
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS          0x0104
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS          0x0108
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_IS            0x010C  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS          0x0110
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE          0x0120
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE          0x0124
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE          0x0128
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_IE            0x012C  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE          0x0130
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS     0x0140
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS     0x0144
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS     0x0148
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_GPE_STS       0x014C  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS     0x0150
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN      0x0160
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN      0x0164
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN      0x0168
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_GPI_GPE_EN        0x016C  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN      0x0170
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS         0x0180
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS         0x0184
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS         0x0188
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_SMI_STS           0x018C  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_SMI_STS         0x0190  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN          0x01A0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN          0x01A4
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN          0x01A8
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_SMI_EN            0x01AC  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_SMI_EN          0x01B0  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS         0x01C0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS         0x01C4
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_G_NMI_STS         0x01C8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_NMI_STS           0x01CC  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_NMI_STS         0x01D0  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN          0x01E0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN          0x01E4
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_G_NMI_EN          0x01E8  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_AZA_NMI_EN            0x01EC  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_VGPIO_NMI_EN          0x01F0  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET   0x600
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET   0x780
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET   0x900
> +#define R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET     0x980
> +#define R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET   0xA00
> +
> +//
> +// GPIO Community 2 Private Configuration Registers
> +//
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN           0x20
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK        0x80
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX      0x84
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN        0xB0
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS            0x0100
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE            0x0120
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS       0x0140
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN        0x0160
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPD_SMI_STS         0x0180  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPD_SMI_EN          0x01A0  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPD_NMI_STS         0x01C0  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPD_NMI_EN          0x01E0  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET     0x600
> +
> +//
> +// GPIO Community 3 Private Configuration Registers
> +//
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN         0x20
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN         0x2C
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN         0x38
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN         0x40
> +#define R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN           0x4C
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK      0x80
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX    0x84
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK      0x88
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX    0x8C
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK      0x90
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX    0x94
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK      0x98
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX    0x9C
> +#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK        0xA0
> +#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX      0xA4
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN      0xC0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN      0xC4
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN      0xC8
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN      0xCC
> +#define R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN        0xD0
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS          0x0100
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS          0x0104
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS          0x0108
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS          0x010C
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_IS            0x0110  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE          0x0120
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE          0x0124
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE          0x0128
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE          0x012C
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_IE            0x0130  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS     0x0140
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS     0x0144
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS     0x0148
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS     0x014C
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_GPE_STS       0x0150  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN      0x0160
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN      0x0164
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN      0x0168
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN      0x016C
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_GPI_GPE_EN        0x0170  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_SMI_STS         0x0180  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_SMI_STS         0x0184  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS         0x0188
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_SMI_STS         0x018C  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_SMI_STS           0x0190  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_SMI_EN          0x01A0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_SMI_EN          0x01A4  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN          0x01A8
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_SMI_EN          0x01AC  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_SMI_EN            0x01B0  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_NMI_STS         0x01C0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_NMI_STS         0x01C4  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS         0x01C8
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_NMI_STS         0x01CC  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_NMI_STS           0x01D0  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_K_NMI_EN          0x01E0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_H_NMI_EN          0x01E4  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN          0x01E8
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_F_NMI_EN          0x01EC  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_SPI_NMI_EN            0x01F0  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET   0x600
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET   0x780
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET   0x900
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET   0x9D0
> +#define R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET     0xB50
> +
> +//
> +// GPIO Community 4 Private Configuration Registers
> +//
> +#define R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN           0x20
> +#define R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN          0x28
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN         0x30
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN         0x3C
> +
> +#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK        0x80
> +#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX      0x84
> +#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK       0x88
> +#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX     0x8C
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK      0x90
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX    0x94
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK      0x98
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX    0x9C
> +
> +#define R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN        0xC0
> +#define R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN       0xC4
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN      0xC8
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN      0xCC
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_IS            0x0100  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_IS           0x0104  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS          0x0108
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS          0x010C
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_IE            0x0120  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_IE           0x0124  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE          0x0128
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE          0x012C
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_GPE_STS       0x0140  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_GPE_STS      0x0144  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS     0x0148
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS     0x014C
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_GPI_GPE_EN        0x0160  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_GPI_GPE_EN       0x0164  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN      0x0168
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN      0x016C
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_SMI_STS           0x0180  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_SMI_STS          0x0184  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS         0x0188
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_SMI_STS         0x018C  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_SMI_EN            0x01A0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_SMI_EN           0x01A4  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN          0x01A8
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_SMI_EN          0x01AC  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_NMI_STS           0x01C0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_NMI_STS          0x01C4  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS         0x01C8
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_NMI_STS         0x01CC  // Not
> supported setting for this group
> +
> +//#define R_CNL_PCH_H_GPIO_PCR_CPU_NMI_EN            0x01E0  // Not
> supported setting for this group
> +//#define R_CNL_PCH_H_GPIO_PCR_JTAG_NMI_EN           0x01E4  // Not
> supported setting for this group
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN          0x01E8
> +//#define R_CNL_PCH_H_GPIO_PCR_GPP_J_NMI_EN          0x01EC  // Not
> supported setting for this group
> +
> +#define R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET     0x600
> +#define R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET    0x6B0
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET   0x740
> +#define R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET   0x860
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
> new file mode 100644
> index 0000000000..bc099d9662
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
> @@ -0,0 +1,204 @@
> +/** @file
> +  Register names for PCH High Definition Audio device.
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_HDA_H_
> +#define _PCH_REGS_HDA_H_
> +
> +//
> +// HD-A Controller Registers (D31:F3)
> +//
> +// PCI Configuration Space Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_HDA               31
> +#define PCI_FUNCTION_NUMBER_PCH_HDA             3
> +
> +#define R_HDA_CFG_PI                            0x09
> +#define V_HDA_CFG_PI_ADSP_UAA                   0x80
> +#define R_HDA_CFG_SCC                           0x0A
> +#define V_HDA_CFG_SCC_ADSP                      0x01
> +#define R_HDA_CFG_HDALBA                        0x10
> +#define B_HDA_CFG_HDALBA_LBA                    0xFFFFC000
> +#define V_HDA_CFG_HDBAR_SIZE                    (1 << 14)
> +#define R_HDA_CFG_HDAUBA                        0x14
> +#define B_HDA_CFG_HDAUBA_UBA                    0xFFFFFFFF
> +#define R_HDA_CFG_CGCTL                         0x48
> +#define B_HDA_CFG_CGCTL_RSMTCGE                 BIT18
> +#define B_HDA_CFG_CGCTL_MISCBDCGE               BIT6
> +#define R_HDA_CFG_PC                            0x52
> +#define V_HDA_CFG_PC_PMES                       0x18
> +#define N_HDA_CFG_PC_PMES                       11
> +#define R_HDA_CFG_PCS                           0x54
> +#define B_HDA_CFG_PCS_PMEE                      BIT8
> +#define B_HDA_CFG_PCS_PS                        (BIT1 | BIT0)
> +#define R_HDA_CFG_MMC                           0x62
> +#define B_HDA_CFG_MMC_ME                        BIT0
> +#define R_HDA_CFG_DEVC                          0x78
> +#define B_HDA_CFG_DEVC_NSNPEN                   BIT11
> +#define R_HDA_CFG_SEM1                          0xC0
> +#define B_HDA_CFG_SEM1_LFLCS                    BIT24
> +#define B_HDA_CFG_SEM1_BLKC3DIS                 BIT17
> +#define B_HDA_CFG_SEM1_TMODE                    BIT12
> +#define B_HDA_CFG_SEM1_FIFORDYSEL               (BIT10 | BIT9)
> +#define R_HDA_CFG_SEM2                          0xC4
> +#define B_HDA_CFG_SEM2_BSMT                     (BIT27 | BIT26)
> +#define V_HDA_CFG_SEM2_BSMT                     0x1
> +#define N_HDA_CFG_SEM2_BSMT                     26
> +#define B_HDA_CFG_SEM2_VC0SNR                   BIT24
> +#define B_HDA_CFG_SEM2_DUM                      BIT23
> +#define R_HDA_CFG_SEM3L                         0xC8
> +#define B_HDA_CFG_SEM3L_ISL1EXT2                (BIT21 | BIT20)
> +#define V_HDA_CFG_SEM3L_ISL1EXT2                0x2
> +#define N_HDA_CFG_SEM3L_ISL1EXT2                20
> +#define R_HDA_CFG_SEM4L                         0xD0
> +#define B_HDA_CFG_SEM4L_OSL1EXT2                (BIT21 | BIT20)
> +#define V_HDA_CFG_SEM4L_OSL1EXT2                0x3
> +#define N_HDA_CFG_SEM4L_OSL1EXT2                20
> +
> +//
> +// Memory Space Registers
> +//
> +//
> +// Resides in 'HD Audio Global Registers' (0000h)
> +//
> +#define R_HDA_MEM_GCAP                        0x00
> +#define R_HDA_MEM_GCTL                        0x08
> +#define B_HDA_MEM_GCTL_CRST                   BIT0
> +
> +#define R_HDA_MEM_OUTPAY                      0x04
> +#define R_HDA_MEM_INPAY                       0x06
> +#define V_HDA_MEM_INPAY_DEFAULT               0x1C
> +
> +#define R_HDA_MEM_WAKEEN                      0x0C
> +#define B_HDA_MEM_WAKEEN_SDI_3                BIT3
> +#define B_HDA_MEM_WAKEEN_SDI_2                BIT2
> +#define B_HDA_MEM_WAKEEN_SDI_1                BIT1
> +#define B_HDA_MEM_WAKEEN_SDI_0                BIT0
> +
> +#define R_HDA_MEM_WAKESTS                     0x0E
> +#define B_HDA_MEM_WAKESTS_SDIN3               BIT3
> +#define B_HDA_MEM_WAKESTS_SDIN2               BIT2
> +#define B_HDA_MEM_WAKESTS_SDIN1               BIT1
> +#define B_HDA_MEM_WAKESTS_SDIN0               BIT0
> +
> +//
> +// Resides in 'HD Audio Controller Registers' (0030h)
> +//
> +#define R_HDA_MEM_IC                          0x60
> +#define R_HDA_MEM_IR                          0x64
> +#define R_HDA_MEM_ICS                         0x68
> +#define B_HDA_MEM_ICS_IRV                     BIT1
> +#define B_HDA_MEM_ICS_ICB                     BIT0
> +
> +//
> +// Resides in 'HD Audio Processing Pipe Capability Structure' (0800h)
> +//
> +#define R_HDA_MEM_PPC                         0x0800 // Processing Pipe
> Capability Structure (Memory Space, offset 0800h)
> +#define R_HDA_MEM_PPCTL                       (R_HDA_MEM_PPC + 0x04)
> +#define B_HDA_MEM_PPCTL_GPROCEN               BIT30
> +
> +//
> +// Resides in 'HD Audio Multiple Links Capability Structure' (0C00h)
> +//
> +#define HDA_HDALINK_INDEX                     0
> +#define HDA_IDISPLINK_INDEX                   1
> +
> +#define R_HDA_MEM_MLC                         0x0C00 // Multiple Links
> Capability Structure (Memory Space, offset 0C00h)
> +#define R_HDA_MEM_LCTLX(x)                    (R_HDA_MEM_MLC + (0x40 +
> (0x40 * (x)) + 0x04)) // x - Link index: 0 - HDA Link, 1 - iDisp Link
> +#define B_HDA_MEM_LCTLX_CPA                   BIT23
> +#define B_HDA_MEM_LCTLX_SPA                   BIT16
> +#define N_HDA_MEM_LCTLX_SCF                   0
> +#define V_HDA_MEM_LCTLX_SCF_6MHZ              0x0
> +#define V_HDA_MEM_LCTLX_SCF_12MHZ             0x1
> +#define V_HDA_MEM_LCTLX_SCF_24MHZ             0x2
> +#define V_HDA_MEM_LCTLX_SCF_48MHZ             0x3
> +#define V_HDA_MEM_LCTLX_SCF_96MHZ             0x4
> +
> +//
> +// Resides in 'HD Audio Vendor Specific Registers' (1000h)
> +//
> +#define R_HDA_MEM_LTRC                        0x1048
> +#define V_HDA_MEM_LTRC_GB                     0x29
> +#define N_HDA_MEM_LTRC_GB                     0
> +#define R_HDA_MEM_PCE                         0x104B
> +#define B_HDA_MEM_PCE_D3HE                    BIT2
> +
> +//
> +// Private Configuration Space Registers
> +//
> +//
> +// Resides in IOSF & Fabric Configuration Registers (000h)
> +//
> +#define R_HDA_PCR_TTCCFG                    0xE4
> +#define B_HDA_PCR_TTCCFG_HCDT               BIT1
> +
> +//
> +// Resides in PCI & Codec Configuration Registers (500h)
> +//
> +#define R_HDA_PCR_PCICDCCFG                 0x500 // PCI & Codec
> Configuration Registers (PCR, offset 500h)
> +#define B_HDA_PCR_PCICDCCFG_ACPIIN          0x0000FF00
> +#define N_HDA_PCR_PCICDCCFG_ACPIIN          8
> +#define R_HDA_PCR_FNCFG                     (R_HDA_PCR_PCICDCCFG + 0x30)
> +#define B_HDA_PCR_FNCFG_PGD                 BIT5
> +#define B_HDA_PCR_FNCFG_BCLD                BIT4
> +#define B_HDA_PCR_FNCFG_CGD                 BIT3
> +#define B_HDA_PCR_FNCFG_ADSPD               BIT2
> +#define B_HDA_PCR_FNCFG_HDASD               BIT0
> +#define R_HDA_PCR_CDCCFG                    (R_HDA_PCR_PCICDCCFG +
> 0x34)
> +#define B_HDA_PCR_CDCCFG_DIS_SDIN2          BIT2
> +
> +//
> +// Resides in Power Management & EBB Configuration Registers (600h)
> +//
> +#define R_HDA_PCR_PWRMANCFG                 0x600 // Power Management
> & EBB Configuration Registers (PCR, offset 600h)
> +#define R_HDA_PCR_APLLP0                    (R_HDA_PCR_PWRMANCFG +
> 0x10)
> +#define V_HDA_PCR_APLLP0                    0xFC1E0000
> +#define R_HDA_PCR_APLLP1                    (R_HDA_PCR_PWRMANCFG +
> 0x14)
> +#define V_HDA_PCR_APLLP1                    0x00003F00
> +#define R_HDA_PCR_APLLP2                    (R_HDA_PCR_PWRMANCFG +
> 0x18)
> +#define V_HDA_PCR_APLLP2                    0x0000011D
> +#define R_HDA_PCR_IOBCTL                    (R_HDA_PCR_PWRMANCFG +
> 0x1C)
> +#define B_HDA_PCR_IOBCTL_OSEL               (BIT9 | BIT8)
> +#define V_HDA_PCR_IOBCTL_OSEL_HDALINK       0
> +#define V_HDA_PCR_IOBCTL_OSEL_HDALINK_I2S   1
> +#define V_HDA_PCR_IOBCTL_OSEL_I2S           3
> +#define N_HDA_PCR_IOBCTL_OSEL               8
> +#define B_HDA_PCR_IOBCTL_VSEL               BIT1
> +#define R_HDA_PCR_PTDC                      (R_HDA_PCR_PWRMANCFG +
> 0x28)
> +#define B_HDA_PCR_PTDC_SRMIW                (BIT6 | BIT5 | BIT4)
> +
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
> new file mode 100644
> index 0000000000..0cd69eb299
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
> @@ -0,0 +1,170 @@
> +/** @file
> +  Register definition for HSIO
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_HSIO_H_
> +#define _PCH_REGS_HSIO_H_
> +
> +#define B_HSIO_PCR_ACCESS_TYPE                          (BIT15 | BIT14)
> +#define N_HSIO_PCR_ACCESS_TYPE                          14
> +#define V_HSIO_PCR_ACCESS_TYPE_BDCAST                   (BIT15 | BIT14)
> +#define V_HSIO_PCR_ACCESS_TYPE_MULCAST                  BIT15
> +#define B_HSIO_PCR_LANE_GROUP_NO                        (BIT13 | BIT12 |
> BIT11 | BIT10 | BIT9)
> +#define B_HSIO_PCR_FUNCTION_NO                          (BIT8  | BIT7)
> +#define N_HSIO_PCR_FUNCTION_NO                          7
> +#define B_HSIO_PCR_REG_OFFSET                           (BIT6  | BIT5  | BIT4  |
> BIT3  | BIT2  | BIT1  | BIT0)
> +
> +#define V_HSIO_PCR_ACCESS_TYPE_BCAST                    0x03
> +#define V_HSIO_PCR_ACCESS_TYPE_MCAST                    0x02
> +#define V_HSIO_PCR_ACCESS_TYPE_UCAST                    0x00
> +
> +#define V_HSIO_PCR_LANE_GROUP_NO_CMN_LANE               0x00
> +
> +#define V_HSIO_PCR_FUNCTION_NO_PCS                      0x00
> +#define V_HSIO_PCR_FUNCTION_NO_TX                       0x01
> +#define V_HSIO_PCR_FUNCTION_NO_RX                       0x02
> +
> +#define V_HSIO_PCR_FUNCTION_NO_CMNDIG                   0x00
> +#define V_HSIO_PCR_FUNCTION_NO_CMNANA                   0x01
> +#define V_HSIO_PCR_FUNCTION_NO_PLL                      0x02
> +
> +#define R_HSIO_PCR_PCS_DWORD4                           0x10
> +
> +#define R_HSIO_PCR_PCS_DWORD8                           0x20
> +#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_PTR_INIT_4_0
> 0x1F000000
> +#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_LOWATER_4_0
> 0x001F0000
> +#define N_HSIO_PCR_PCS_DWORD8_CRI_RXEB_LOWATER_4_0      16
> +#define B_HSIO_PCR_PCS_DWORD8_CRI_RXEB_HIWATER_4_0
> 0x00001F00
> +#define N_HSIO_PCR_PCS_DWORD8_CRI_RXEB_HIWATER_4_0      8
> +
> +#define R_HSIO_PCR_PCS_DWORD9                           0x24
> +#define B_HSIO_PCR_PCS_DWORD9_REG_ENABLE_PWR_GATING     BIT29
> +
> +#define R_HSIO_PCR_RX_DWORD8                            0x220
> +#define B_HSIO_PCR_RX_DWORD8_ICFGDFETAP3_EN             BIT10
> +
> +#define R_HSIO_PCR_RX_DWORD9                            0x224
> +#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP4_OVERRIDE_EN     BIT24
> +#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP3_OVERRIDE_EN     BIT26
> +#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP2_OVERRIDE_EN     BIT28
> +#define B_HSIO_PCR_RX_DWORD9_CFGDFETAP1_OVERRIDE_EN     BIT30
> +
> +#define R_HSIO_PCR_RX_DWORD12                           0x230
> +#define B_HSIO_PCR_RX_DWORD12_O_CFGEWMARGINSEL          BIT14
> +
> +#define R_HSIO_PCR_RX_DWORD20                               0x250
> +#define B_HSIO_PCR_RX_DWORD20_ICFGCTLEDATATAP_FULLRATE_5_0
> (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
> +#define N_HSIO_PCR_RX_DWORD20_ICFGCTLEDATATAP_FULLRATE_5_0  24
> +
> +#define R_HSIO_PCR_RX_DWORD21                               0x254
> +#define B_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_QUATRATE_5_0
> (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
> +#define N_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_QUATRATE_5_0  8
> +#define B_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_HALFRATE_5_0
> (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
> +#define N_HSIO_PCR_RX_DWORD21_ICFGCTLEDATATAP_HALFRATE_5_0  0
> +
> +#define R_HSIO_PCR_RX_DWORD23                               0x25C
> +#define B_HSIO_PCR_RX_DWORD23_ICFGVGABLWTAP_OVERRIDE_EN
> BIT2
> +#define B_HSIO_PCR_RX_DWORD23_CFGVGATAP_ADAPT_OVERRIDE_EN
> BIT4
> +
> +#define R_HSIO_PCR_RX_DWORD25                            0x264
> +#define B_HSIO_PCR_RX_DWORD25_RX_TAP_CFG_CTRL            BIT3
> +#define B_HSIO_PCR_RX_DWORD25_CTLE_ADAPT_OFFSET_CFG_4_0
> 0x1F0000
> +#define N_HSIO_PCR_RX_DWORD25_CTLE_ADAPT_OFFSET_CFG_4_0  16
> +
> +#define R_HSIO_PCR_RX_DWORD26                           0x268
> +#define B_HSIO_PCR_RX_DWORD26_SATA_EQ_DIS               BIT16
> +
> +#define R_HSIO_PCR_RX_DWORD34                           0x288
> +#define B_HSIO_PCR_RX_DWORD34_MM_PH_OFC_SCALE_2_0       (BIT14 |
> BIT13 | BIT12)
> +#define N_HSIO_PCR_RX_DWORD34_MM_PH_OFC_SCALE_2_0       12
> +
> +#define R_HSIO_PCR_RX_DWORD44                           0x2B0
> +#define B_HSIO_PCR_RX_DWORD44_0_DFE_DATASUMCAL0_7_0
> 0xFF0000
> +#define N_HSIO_PCR_RX_DWORD44_0_DFE_DATASUMCAL0_7_0     16
> +
> +#define R_HSIO_PCR_RX_DWORD56                           0x2E0
> +#define B_HSIO_PCR_RX_DWORD56_ICFGPIDACCFGVALID         BIT16
> +
> +#define R_HSIO_PCR_RX_DWORD57                           0x2E4
> +#define B_HSIO_PCR_RX_DWORD57_JIM_COURSE                BIT30
> +#define B_HSIO_PCR_RX_DWORD57_JIM_ENABLE                BIT29
> +#define B_HSIO_PCR_RX_DWORD57_JIMMODE                   BIT28
> +#define B_HSIO_PCR_RX_DWORD57_JIMNUMCYCLES_3_0
> 0x0F000000
> +#define N_HSIO_PCR_RX_DWORD57_JIMNUMCYCLES_3_0          24
> +#define B_HSIO_PCR_RX_DWORD57_ICFGMARGINEN              BIT0
> +
> +#define R_HSIO_PCR_RX_DWORD59                           0x2EC
> +#define R_HSIO_PCR_RX_DWORD60                           0x2F0
> +
> +#define R_HSIO_PCR_TX_DWORD5                            0x154
> +#define B_HSIO_PCR_TX_DWORD5_OW2TAPGEN2DEEMPH3P5_5_0    (BIT21
> | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
> +#define N_HSIO_PCR_TX_DWORD5_OW2TAPGEN2DEEMPH3P5_5_0    16
> +#define B_HSIO_PCR_TX_DWORD5_OW2TAPGEN1DEEMPH3P5_5_0    (BIT13
> | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
> +#define N_HSIO_PCR_TX_DWORD5_OW2TAPGEN1DEEMPH3P5_5_0    8
> +
> +#define R_HSIO_PCR_TX_DWORD6                            0x158
> +#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN3DEEMPH6P0_5_0    (BIT21
> | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
> +#define N_HSIO_PCR_TX_DWORD6_OW2TAPGEN3DEEMPH6P0_5_0    16
> +#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN2DEEMPH6P0_5_0    (BIT13
> | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
> +#define N_HSIO_PCR_TX_DWORD6_OW2TAPGEN2DEEMPH6P0_5_0    8
> +#define B_HSIO_PCR_TX_DWORD6_OW2TAPGEN1DEEMPH6P0_5_0    (BIT5
> | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
> +
> +#define R_HSIO_PCR_TX_DWORD8                            0x160
> +#define B_HSIO_PCR_TX_DWORD8_ORATE10MARGIN_5_0          (BIT29 |
> BIT28 | BIT27 | BIT26 | BIT25 | BIT24)
> +#define N_HSIO_PCR_TX_DWORD8_ORATE10MARGIN_5_0          24
> +#define B_HSIO_PCR_TX_DWORD8_ORATE01MARGIN_5_0          (BIT21 |
> BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
> +#define N_HSIO_PCR_TX_DWORD8_ORATE01MARGIN_5_0          16
> +#define B_HSIO_PCR_TX_DWORD8_ORATE00MARGIN_5_0          (BIT13 |
> BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
> +#define N_HSIO_PCR_TX_DWORD8_ORATE00MARGIN_5_0          8
> +
> +#define R_HSIO_PCR_TX_DWORD19                           0x18C
> +
> +#define R_HSIO_PCR_CLANE0_CMN_ANA_DWORD2                0x80C8
> +#define
> B_HSIO_PCR_CLANE0_CMN_ANA_DWORD2_O_DTPLL1_lC_PLLEN_H_OVRDEN
> BIT5
> +#define
> B_HSIO_PCR_CLANE0_CMN_ANA_DWORD2_O_DTPLL1_lC_FULLCALRESET_L_
> OVERDEN        BIT3
> +
> +#define R_HSIO_PCR_PLL_SSC_DWORD2                       0x8188
> +#define B_HSIO_PCR_PLL_SSC_DWORD2_SSCSTEPSIZE_7_0       (BIT23 |
> BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
> +#define N_HSIO_PCR_PLL_SSC_DWORD2_SSCSTEPSIZE_7_0       16
> +#define B_HSIO_PCR_PLL_SSC_DWORD2_SSCSEN                BIT10
> +#define N_HSIO_PCR_PLL_SSC_DWORD2_SSCSEN                10
> +
> +#define R_HSIO_PCR_PLL_SSC_DWORD3                       0x818C
> +#define B_HSIO_PCR_PLL_SSC_DWORD3_SSC_PROPAGATE         BIT0
> +
> +
> +#endif //_PCH_REGS_HSIO_H_
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
> new file mode 100644
> index 0000000000..5b4e23c43f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
> @@ -0,0 +1,79 @@
> +/** @file
> +  Register names for PCH Integrated Sensor Hub (ISH3.0)
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_ISH_H_
> +#define _PCH_REGS_ISH_H_
> +
> +//
> +// ISH Controller Registers
> +//
> +// D19:F0
> +#define PCI_DEVICE_NUMBER_PCH_ISH             19
> +#define PCI_FUNCTION_NUMBER_PCH_ISH           0
> +
> +// PCI Configuration Space Registers
> +#define R_ISH_CFG_BAR0_LOW                    0x10
> +#define R_ISH_CFG_BAR0_HIGH                   0x14
> +#define V_ISH_CFG_BAR0_SIZE                   0x100000
> +#define N_ISH_CFG_BAR0_ALIGNMENT              20
> +#define R_ISH_CFG_BAR1_LOW                    0x18
> +#define R_ISH_CFG_BAR1_HIGH                   0x1C
> +#define V_ISH_CFG_BAR1_SIZE                   0x1000
> +#define N_ISH_CFG_BAR1_ALIGNMENT              12
> +
> +//
> +// ISH Private Configuration Space Registers (IOSF2OCP)
> +// (PID:ISH)
> +//
> +#define R_ISH_PCR_PMCTL                   0x1D0                         ///< Power
> Management
> +#define R_ISH_PCR_PCICFGCTRL              0x200                         ///< PCI
> Configuration Control
> +#define B_ISH_PCR_PCICFGCTR_PCI_IRQ       0x0FF00000                    ///<
> PCI IRQ number
> +#define N_ISH_PCR_PCICFGCTR_PCI_IRQ       20
> +#define B_ISH_PCR_PCICFGCTR_ACPI_IRQ      0x000FF000                    ///<
> ACPI IRQ number
> +#define N_ISH_PCR_PCICFGCTR_ACPI_IRQ      12
> +#define B_ISH_PCR_PCICFGCTR_IPIN1         (BIT11 | BIT10 | BIT9 | BIT8) ///<
> Interrupt Pin
> +#define N_ISH_PCR_PCICFGCTR_IPIN1         8
> +#define B_ISH_PCR_PCICFGCTRL_BAR1DIS      BIT7                          ///<
> BAR1 Disable
> +
> +//
> +// Number of pins used by ISH controllers
> +//
> +#define PCH_ISH_PINS_PER_I2C_CONTROLLER               2
> +#define PCH_ISH_PINS_PER_UART_CONTROLLER              4
> +#define PCH_ISH_PINS_PER_SPI_CONTROLLER               4
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
> new file mode 100644
> index 0000000000..8d7c3f9015
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
> @@ -0,0 +1,103 @@
> +/** @file
> +  Register names for ITSS
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_ITSS_H_
> +#define _PCH_REGS_ITSS_H_
> +
> +//
> +// ITSS PCRs (PID:ITSS)
> +//
> +#define R_ITSS_PCR_PIRQA_ROUT             0x3100          ///< PIRQA
> Routing Control register
> +#define R_ITSS_PCR_PIRQB_ROUT             0x3101          ///< PIRQB Routing
> Control register
> +#define R_ITSS_PCR_PIRQC_ROUT             0x3102          ///< PIRQC Routing
> Control register
> +#define R_ITSS_PCR_PIRQD_ROUT             0x3103          ///< PIRQD
> Routing Control register
> +#define R_ITSS_PCR_PIRQE_ROUT             0x3104          ///< PIRQE Routing
> Control register
> +#define R_ITSS_PCR_PIRQF_ROUT             0x3105          ///< PIRQF Routing
> Control register
> +#define R_ITSS_PCR_PIRQG_ROUT             0x3106          ///< PIRQG
> Routing Control register
> +#define R_ITSS_PCR_PIRQH_ROUT             0x3107          ///< PIRQH
> Routing Control register
> +#define B_ITSS_PCR_PIRQX_ROUT_REN         0x80            ///< Interrupt
> Routing Enable
> +#define B_ITSS_PCR_PIRQX_ROUT_IR          0x0F            ///< IRQ Routng
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_3       0x03            ///< Route PIRQx
> to IRQ3
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_4       0x04            ///< Route PIRQx
> to IRQ4
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_5       0x05            ///< Route PIRQx
> to IRQ5
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_6       0x06            ///< Route PIRQx
> to IRQ6
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_7       0x07            ///< Route PIRQx
> to IRQ7
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_9       0x09            ///< Route PIRQx
> to IRQ9
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_10      0x0A            ///< Route
> PIRQx to IRQ10
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_11      0x0B            ///< Route
> PIRQx to IRQ11
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_12      0x0C            ///< Route
> PIRQx to IRQ12
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_14      0x0E            ///< Route
> PIRQx to IRQ14
> +#define V_ITSS_PCR_PIRQX_ROUT_IRQ_15      0x0F            ///< Route PIRQx
> to IRQ15
> +
> +#define R_ITSS_PCR_PIR0                   0x3140          ///< PCI Interrupt
> Route 0
> +#define R_ITSS_PCR_PIR1                   0x3142          ///< PCI Interrupt
> Route 1
> +#define R_ITSS_PCR_PIR2                   0x3144          ///< PCI Interrupt
> Route 2
> +#define R_ITSS_PCR_PIR3                   0x3146          ///< PCI Interrupt
> Route 3
> +#define R_ITSS_PCR_PIR4                   0x3148          ///< PCI Interrupt
> Route 4
> +#define R_ITSS_PCR_PIR5                   0x314A          ///< PCI Interrupt
> Route 5
> +#define R_ITSS_PCR_PIR6                   0x314C          ///< PCI Interrupt
> Route 6
> +#define R_ITSS_PCR_PIR7                   0x314E          ///< PCI Interrupt
> Route 7
> +#define R_ITSS_PCR_PIR8                   0x3150          ///< PCI Interrupt
> Route 8
> +#define R_ITSS_PCR_PIR9                   0x3152          ///< PCI Interrupt
> Route 9
> +#define R_ITSS_PCR_PIR10                  0x3154          ///< PCI Interrupt
> Route 10
> +#define R_ITSS_PCR_PIR11                  0x3156          ///< PCI Interrupt
> Route 11
> +#define R_ITSS_PCR_PIR12                  0x3158          ///< PCI Interrupt
> Route 12
> +
> +#define R_ITSS_PCR_GIC                    0x31FC          ///< General Interrupt
> Control
> +#define B_ITSS_PCR_GIC_MAX_IRQ_24         BIT9            ///< Max IRQ
> entry size, 1 = 24 entry size, 0 = 120 entry size
> +#define B_ITSS_PCR_GIC_AME                BIT17           ///< Alternate Access
> Mode Enable
> +#define B_ITSS_PCR_GIC_SPS                BIT16           ///< Shutdown Policy
> Select
> +#define R_ITSS_PCR_IPC0                   0x3200          ///< Interrupt Polarity
> Control 0
> +#define R_ITSS_PCR_IPC1                   0x3204          ///< Interrupt Polarity
> Control 1
> +#define R_ITSS_PCR_IPC2                   0x3208          ///< Interrupt Polarity
> Control 2
> +#define R_ITSS_PCR_IPC3                   0x320C          ///< Interrupt Polarity
> Control 3
> +#define R_ITSS_PCR_ITSSPRC                0x3300          ///< ITSS Power
> Reduction Control
> +#define B_ITSS_PCR_ITSSPRC_PGCBDCGE       BIT4            ///< PGCB
> Dynamic Clock Gating Enable
> +#define B_ITSS_PCR_ITSSPRC_HPETDCGE       BIT3            ///< HPET
> Dynamic Clock Gating Enable
> +#define B_ITSS_PCR_ITSSPRC_8254CGE        BIT2            ///< 8254 Static
> Clock Gating Enable
> +#define B_ITSS_PCR_ITSSPRC_IOSFICGE       BIT1            ///< IOSF-Sideband
> Interface Clock Gating Enable
> +#define B_ITSS_PCR_ITSSPRC_ITSSCGE        BIT0            ///< ITSS Clock Gate
> Enable
> +#define R_ITSS_PCR_NMI                    0x3330          ///< NMI Control
> +#define N_ITSS_PCR_NMI_NMI2SMI_STS        3               ///< NMI2SMI
> Status
> +#define N_ITSS_PCR_NMI_NMI2SMI_EN         2               ///< NMI2SMI
> Enable
> +#define B_ITSS_PCR_NMI_NMI2SMI_EN         BIT2            ///< NMI2SMI
> Enable
> +#define B_ITSS_PCR_NMI_NMI_NOW_STS        BIT1            ///<
> NMI_NOW_STS
> +#define B_ITSS_PCR_NMI_NMI_NOW            BIT0            ///< NMI_NOW
> +#define R_ITSS_PCR_MMC                    0x3334          ///< Master Message
> Control
> +#define B_ITSS_PCR_MMC_MSTRMSG_EN         BIT0            ///< Master
> Message Enable
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
> new file mode 100644
> index 0000000000..f649873f67
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Register names for PCH LAN device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_LAN_H_
> +#define _PCH_REGS_LAN_H_
> +
> +//
> +// Gigabit LAN Controller configuration registers (D31:F6)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LAN     31
> +#define PCI_FUNCTION_NUMBER_PCH_LAN   6
> +
> +#define R_LAN_CFG_MBARA               0x10
> +#define N_LAN_CFG_MBARA_ALIGN         17
> +#define R_LAN_CFG_PMCS                0xCC
> +#define B_LAN_CFG_PMCS_PS             (BIT1 | BIT0)
> +#define V_LAN_CFG_PMCS_PS0            0x00
> +#define R_LAN_MEM_CSR_RAL                  0x5400
> +#define R_LAN_MEM_CSR_RAH                  0x5404
> +#define B_LAN_MEM_CSR_RAH_RAH              0x0000FFFF
> +#define R_LAN_MEM_CSR_WUC                  0x5800
> +#define B_LAN_MEM_CSR_WUC_APME             BIT0
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
> new file mode 100644
> index 0000000000..34fc3c4dd2
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
> @@ -0,0 +1,360 @@
> +/** @file
> +  Register names for PCH LPC/eSPI device
> +
> +Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 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 (D31:F0)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_LPC       31
> +#define PCI_FUNCTION_NUMBER_PCH_LPC     0
> +
> +#define V_LPC_CFG_VENDOR_ID                       V_PCH_INTEL_VENDOR_ID
> +
> +
> +#define R_LPC_CFG_SERIRQ_CNT                      0x64
> +#define B_LPC_CFG_SERIRQ_CNT_SIRQEN               BIT7
> +#define B_LPC_CFG_SERIRQ_CNT_SIRQMD               BIT6
> +#define B_LPC_CFG_SERIRQ_CNT_SIRQSZ               (BIT5 | BIT4 | BIT3 | BIT2)
> +#define N_LPC_CFG_SERIRQ_CNT_SIRQSZ               2
> +#define B_LPC_CFG_SERIRQ_CNT_SFPW                 (BIT1 | BIT0)
> +#define N_LPC_CFG_SERIRQ_CNT_SFPW                 0
> +#define V_LPC_CFG_SERIRQ_CNT_SFPW_4CLK            0x00
> +#define V_LPC_CFG_SERIRQ_CNT_SFPW_6CLK            0x01
> +#define V_LPC_CFG_SERIRQ_CNT_SFPW_8CLK            0x02
> +
> +#define R_LPC_CFG_IOD                             0x80
> +#define B_LPC_CFG_IOD_FDD                         BIT12
> +#define N_LPC_CFG_IOD_FDD                         12
> +#define V_LPC_CFG_IOD_FDD_3F0                     0
> +#define V_LPC_CFG_IOD_FDD_370                     1
> +#define B_LPC_CFG_IOD_LPT                         (BIT9 | BIT8)
> +#define N_LPC_CFG_IOD_LPT                         8
> +#define V_LPC_CFG_IOD_LPT_378                     0
> +#define V_LPC_CFG_IOD_LPT_278                     1
> +#define V_LPC_CFG_IOD_LPT_3BC                     2
> +#define B_LPC_CFG_IOD_COMB                        (BIT6 | BIT5 |BIT4)
> +#define N_LPC_CFG_IOD_COMB                        4
> +#define V_LPC_CFG_IOD_COMB_3F8                    0
> +#define V_LPC_CFG_IOD_COMB_2F8                    1
> +#define V_LPC_CFG_IOD_COMB_220                    2
> +#define V_LPC_CFG_IOD_COMB_228                    3
> +#define V_LPC_CFG_IOD_COMB_238                    4
> +#define V_LPC_CFG_IOD_COMB_2E8                    5
> +#define V_LPC_CFG_IOD_COMB_338                    6
> +#define V_LPC_CFG_IOD_COMB_3E8                    7
> +#define B_LPC_CFG_IOD_COMA                        (BIT2 | BIT1 | BIT0)
> +#define N_LPC_CFG_IOD_COMA                        0
> +#define V_LPC_CFG_IOD_COMA_3F8                    0
> +#define V_LPC_CFG_IOD_COMA_2F8                    1
> +#define V_LPC_CFG_IOD_COMA_220                    2
> +#define V_LPC_CFG_IOD_COMA_228                    3
> +#define V_LPC_CFG_IOD_COMA_238                    4
> +#define V_LPC_CFG_IOD_COMA_2E8                    5
> +#define V_LPC_CFG_IOD_COMA_338                    6
> +#define V_LPC_CFG_IOD_COMA_3E8                    7
> +#define R_LPC_CFG_IOE                             0x82
> +#define B_LPC_CFG_IOE_ME2                         BIT13           ///<
> Microcontroller Enable #2, Enables decoding of I/O locations 4Eh and 4Fh to
> LPC
> +#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_ME1                         BIT11           ///<
> Microcontroller Enable #1, Enables decoding of I/O locations 62h and 66h 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_HGE                         BIT9            ///< High
> Gameport Enable, Enables decoding of the I/O locations 208h to 20Fh to LPC.
> +#define B_LPC_CFG_IOE_LGE                         BIT8            ///< Low
> Gameport Enable, Enables decoding of the I/O locations 200h to 207h to LPC.
> +#define B_LPC_CFG_IOE_FDE                         BIT3            ///< Floppy
> Drive Enable, Enables decoding of the FDD range to LPC. Range is selected by
> LIOD.FDE
> +#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_GEN1_DEC                        0x84
> +#define R_LPC_CFG_GEN2_DEC                        0x88
> +#define R_LPC_CFG_GEN3_DEC                        0x8C
> +#define R_LPC_CFG_GEN4_DEC                        0x90
> +#define B_LPC_CFG_GENX_DEC_IODRA                  0x00FC0000
> +#define B_LPC_CFG_GENX_DEC_IOBAR                  0x0000FFFC
> +#define B_LPC_CFG_GENX_DEC_EN                     0x00000001
> +#define R_LPC_CFG_ULKMC                           0x94
> +#define B_LPC_CFG_ULKMC_SMIBYENDPS                BIT15
> +#define B_LPC_CFG_ULKMC_TRAPBY64W                 BIT11
> +#define B_LPC_CFG_ULKMC_TRAPBY64R                 BIT10
> +#define B_LPC_CFG_ULKMC_TRAPBY60W                 BIT9
> +#define B_LPC_CFG_ULKMC_TRAPBY60R                 BIT8
> +#define B_LPC_CFG_ULKMC_SMIATENDPS                BIT7
> +#define B_LPC_CFG_ULKMC_PSTATE                    BIT6
> +#define B_LPC_CFG_ULKMC_A20PASSEN                 BIT5
> +#define B_LPC_CFG_ULKMC_USBSMIEN                  BIT4
> +#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_CS1IORE_DPCS1RE                BIT14
> +#define R_ESPI_CFG_CS1GIR1                        0xA4
> +#define R_ESPI_CFG_CS1GMR1                        0xA8
> +
> +#define R_LPC_CFG_FWH_BIOS_SEL                    0xD0
> +#define B_LPC_CFG_FWH_BIOS_SEL_F8                 0xF0000000
> +#define B_LPC_CFG_FWH_BIOS_SEL_F0                 0x0F000000
> +#define B_LPC_CFG_FWH_BIOS_SEL_E8                 0x00F00000
> +#define B_LPC_CFG_FWH_BIOS_SEL_E0                 0x000F0000
> +#define B_LPC_CFG_FWH_BIOS_SEL_D8                 0x0000F000
> +#define B_LPC_CFG_FWH_BIOS_SEL_D0                 0x00000F00
> +#define B_LPC_CFG_FWH_BIOS_SEL_C8                 0x000000F0
> +#define B_LPC_CFG_FWH_BIOS_SEL_C0                 0x0000000F
> +#define R_LPC_CFG_FWH_BIOS_SEL2                   0xD4
> +#define B_LPC_CFG_FWH_BIOS_SEL2_70                0xF000
> +#define B_LPC_CFG_FWH_BIOS_SEL2_60                0x0F00
> +#define B_LPC_CFG_FWH_BIOS_SEL2_50                0x00F0
> +#define B_LPC_CFG_FWH_BIOS_SEL2_40                0x000F
> +#define R_LPC_CFG_BDE                             0xD8                          ///<
> BIOS decode enable
> +#define B_LPC_CFG_BDE_F8                          BIT15
> +#define B_LPC_CFG_BDE_F0                          BIT14
> +#define B_LPC_CFG_BDE_E8                          BIT13
> +#define B_LPC_CFG_BDE_E0                          BIT12
> +#define B_LPC_CFG_BDE_D8                          BIT11
> +#define B_LPC_CFG_BDE_D0                          BIT10
> +#define B_LPC_CFG_BDE_C8                          BIT9
> +#define B_LPC_CFG_BDE_C0                          BIT8
> +#define B_LPC_CFG_BDE_LEG_F                       BIT7
> +#define B_LPC_CFG_BDE_LEG_E                       BIT6
> +#define B_LPC_CFG_BDE_70                          BIT3
> +#define B_LPC_CFG_BDE_60                          BIT2
> +#define B_LPC_CFG_BDE_50                          BIT1
> +#define B_LPC_CFG_BDE_40                          BIT0
> +#define R_LPC_CFG_PCC                             0xE0
> +#define B_LPC_CFG_PCC_CLKRUN_EN                   BIT0
> +
> +#define B_LPC_CFG_FVEC0_USB_PORT_CAP              (BIT11 | BIT10)
> +#define V_LPC_CFG_FVEC0_USB_14_PORT               0x00000000
> +#define V_LPC_CFG_FVEC0_USB_12_PORT               0x00000400
> +#define V_LPC_CFG_FVEC0_USB_10_PORT               0x00000800
> +#define B_LPC_CFG_FVEC0_SATA_RAID_CAP             BIT7
> +#define B_LPC_CFG_FVEC0_SATA_PORT23_CAP           BIT6
> +#define B_LPC_CFG_FVEC0_SATA_PORT1_6GB_CAP        BIT3
> +#define B_LPC_CFG_FVEC0_SATA_PORT0_6GB_CAP        BIT2
> +#define B_LPC_CFG_FVEC0_PCI_CAP                   BIT1
> +#define R_LPC_CFG_FVEC1                           0x01
> +#define B_LPC_CFG_FVEC1_USB_R_CAP                 BIT22
> +#define R_LPC_CFG_FVEC2                           0x02
> +#define V_LPC_CFG_FVEC2_PCIE_PORT78_CAP           0x00200000
> +#define V_LPC_CFG_FVEC2_PCH_IG_SUPPORT_CAP        0x00020000 ///<
> PCH Integrated Graphics Support Capability
> +#define R_LPC_CFG_FVEC3                           0x03
> +#define B_LPC_CFG_FVEC3_DCMI_CAP                  BIT13      ///< Data
> Center Manageability Interface (DCMI) Capability
> +#define B_LPC_CFG_FVEC3_NM_CAP                    BIT12      ///< Node
> Manager Capability
> +
> +#define R_LPC_CFG_MDAP                            0xC0
> +#define B_LPC_CFG_MDAP_POLICY_EN                  BIT31
> +#define B_LPC_CFG_MDAP_PDMA_EN                    BIT30
> +#define B_LPC_CFG_MDAP_VALUE                      0x0001FFFF
> +
> +//
> +// 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 B_LPC_CFG_BC_BILD                         BIT7            ///< BIOS
> Interface Lock-Down
> +#define B_LPC_CFG_BC_BBS                          BIT6            ///< Boot BIOS
> strap
> +#define N_LPC_CFG_BC_BBS                          6
> +#define V_LPC_CFG_BC_BBS_SPI                      0               ///< Boot BIOS
> strapped to SPI
> +#define V_LPC_CFG_BC_BBS_LPC                      1               ///< Boot BIOS
> strapped to LPC
> +#define B_LPC_CFG_BC_EISS                         BIT5            ///< Enable
> InSMM.STS
> +#define B_LPC_CFG_BC_TS                           BIT4            ///< Top Swap
> +#define B_LPC_CFG_BC_LE                           BIT1            ///< Lock Enable
> +#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 N_ESPI_CFG_PCBC_BWRE                      11              ///< BIOS
> Write Report Enable bit position
> +#define B_ESPI_CFG_PCBC_BWRS                      BIT10           ///< BIOS
> Write Report Status
> +#define N_ESPI_CFG_PCBC_BWRS                      10              ///< BIOS
> Write Report Status bit position
> +#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 R_ESPI_SLAVE_CHA_0_CAP_AND_CONF           0x10            ///<
> Channel 0 Capabilities and Configurations
> +#define B_ESPI_SLAVE_BME                          BIT2            ///< Bus Master
> Enable
> +
> +//
> +// Processor interface registers
> +//
> +#define R_PCH_IO_NMI_SC                              0x61
> +#define B_PCH_IO_NMI_SC_SERR_NMI_STS                 BIT7
> +#define B_PCH_IO_NMI_SC_IOCHK_NMI_STS                BIT6
> +#define B_PCH_IO_NMI_SC_TMR2_OUT_STS                 BIT5
> +#define B_PCH_IO_NMI_SC_REF_TOGGLE                   BIT4
> +#define B_PCH_IO_NMI_SC_IOCHK_NMI_EN                 BIT3
> +#define B_PCH_IO_NMI_SC_PCI_SERR_EN                  BIT2
> +#define B_PCH_IO_NMI_SC_SPKR_DAT_EN                  BIT1
> +#define B_PCH_IO_NMI_SC_TIM_CNT2_EN                  BIT0
> +#define R_PCH_IO_NMI_EN                              0x70
> +#define B_PCH_IO_NMI_EN_NMI_EN                       BIT7
> +
> +//
> +// Reset Generator I/O Port
> +//
> +#define R_PCH_IO_RST_CNT                             0xCF9
> +#define B_PCH_IO_RST_CNT_FULL_RST                    BIT3
> +#define B_PCH_IO_RST_CNT_RST_CPU                     BIT2
> +#define B_PCH_IO_RST_CNT_SYS_RST                     BIT1
> +#define V_PCH_IO_RST_CNT_FULLRESET                   0x0E
> +#define V_PCH_IO_RST_CNT_HARDRESET                   0x06
> +#define V_PCH_IO_RST_CNT_SOFTRESET                   0x04
> +#define V_PCH_IO_RST_CNT_HARDSTARTSTATE              0x02
> +#define V_PCH_IO_RST_CNT_SOFTSTARTSTATE              0x00
> +
> +//
> +// RTC register
> +//
> +#define R_RTC_IO_INDEX                           0x70
> +#define R_RTC_IO_TARGET                          0x71
> +#define R_RTC_IO_EXT_INDEX                       0x72
> +#define R_RTC_IO_EXT_TARGET                      0x73
> +#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_EXT_TARGET_ALT                  0x77
> +#define R_RTC_IO_REGA                            0x0A
> +#define B_RTC_IO_REGA_UIP                        BIT7
> +#define R_RTC_IO_REGB                            0x0B
> +#define B_RTC_IO_REGB_SET                        0x80
> +#define B_RTC_IO_REGB_PIE                        0x40
> +#define B_RTC_IO_REGB_AIE                        0x20
> +#define B_RTC_IO_REGB_UIE                        0x10
> +#define B_RTC_IO_REGB_DM                         0x04
> +#define B_RTC_IO_REGB_HOURFORM                   0x02
> +#define R_RTC_IO_REGC                            0x0C
> +#define R_RTC_IO_REGD                            0x0D
> +
> +//
> +// Private Configuration Register
> +// RTC PCRs (PID:RTC)
> +//
> +#define R_RTC_PCR_CONF                        0x3400               ///< RTC
> Configuration register
> +#define B_RTC_PCR_CONF_BILD                   BIT31                ///< BIOS
> Interface Lock-Down
> +#define B_RTC_PCR_CONF_HPM_HW_DIS             BIT6                 ///< RTC
> High Power Mode HW Disable
> +#define B_RTC_PCR_CONF_UCMOS_LOCK             BIT4                 ///<
> Upper 128 Byte Lock
> +#define B_RTC_PCR_CONF_LCMOS_LOCK             BIT3                 ///<
> Lower 128 Byte Lock
> +#define B_RTC_PCR_CONF_UCMOS_EN               BIT2                 ///<
> Upper CMOS bank enable
> +#define R_RTC_PCR_BUC                         0x3414               ///< Backed Up
> Control
> +#define B_RTC_PCR_BUC_DSO                     BIT4                 ///< Daylight
> Savings Override
> +#define B_RTC_PCR_BUC_TS                      BIT0                 ///< Top Swap
> +#define R_RTC_PCR_RTCDCG                      0x3418               ///< RTC
> Dynamic Clock Gating Control
> +#define R_RTC_PCR_RTCDCG_RTCPGCBDCGEN         BIT2                 ///<
> pgcb_clk (12Mhz) Dynamic Clock Gate Enable
> +#define R_RTC_PCR_RTCDCG_RTCPCICLKDCGEN       BIT1                 ///<
> ipciclk_clk (24 MHz) Dynamic Clock Gate Enable
> +#define R_RTC_PCR_RTCDCG_RTCROSIDEDCGEN       BIT0                 ///<
> rosc_side_clk (120 MHz) Dynamic Clock Gate Enable
> +#define R_RTC_PCR_PG1_CP_LO                   0x3428
> +#define R_RTC_PCR_PG1_AC_LO                   0x3438
> +#define R_RTC_PCR_3F00                        0x3F00
> +#define R_RTC_PCR_UIPSMI                      0x3F04               ///< RTC
> Update In Progress SMI Control
> +
> +//
> +// LPC PCR Registers
> +//
> +#define R_LPC_PCR_HVMTCTL                     0x3410
> +#define R_LPC_PCR_GCFD                        0x3418
> +#define B_LPC_PCR_GCFD_SRVR_CLKRUN_EN         BIT2                 ///<
> Enables the CLKRUN# logic to stop the PCI clocks
> +#define R_LPC_PCR_PRC                         0x341C
> +#define R_LPC_PCR_PCT                         0x3420
> +#define R_LPC_PCR_SCT                         0x3424
> +#define R_LPC_PCR_LPCCT                       0x3428
> +#define R_LPC_PCR_ULTOR                       0x3500
> +
> +//
> +// 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 V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_RD    0                       ///<
> Slave Configuration register read from address SCRA[11:0]
> +#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_WR    1                       ///<
> Slave Configuration register write to address SCRA[11:0]
> +#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_STS   2                       ///<
> Slave Status register read
> +#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRT_RS    3                       ///<
> In-Band reset
> +#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_PCERR_SLV1                 0x4024          ///< Peripheral
> Channel Error for Slave 1
> +#define R_ESPI_PCR_VWERR_SLV0                 0x4030          ///< Virtual
> Wire Channel Error for Slave 0
> +#define R_ESPI_PCR_VWERR_SLV1                 0x4034          ///< Virtual
> Wire Channel Error for Slave 1
> +#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 R_ESPI_PCR_SOFTSTRAPS_CS1_EN          BIT12           ///< CS1#
> Enable
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
> new file mode 100644
> index 0000000000..74789a87ce
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
> @@ -0,0 +1,61 @@
> +/** @file
> +  Register names for PCH LPC/eSPI device
> +
> +  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_H_", "_PCH_LP_"
> +    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_LPC_CNL_H_
> +#define _PCH_REGS_LPC_CNL_H_
> +
> +#define V_LPC_CFG_DID_CNL_H                       0xA300
> +#define V_LPC_CFG_DID_CNL_LP                      0x9D80
> +
> +//
> +// PCH-LP Device IDs
> +//
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU   0x9D80
> ///< PCH LP Mobile
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0           0x9D81
> ///< PCH LP Mobile (U)
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1           0x9D82
> ///< PCH LP Mobile Locked
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2           0x9D83
> ///< PCH LP Mobile (Y)
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3           0x9D84
> ///< PCH LP Mobile (U)
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4           0x9D85
> ///< PCH LP Mobile (U)
> +#define V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5           0x9D86
> ///< PCH LP Mobile (Y)
> +
> +//
> +// PCH-H Desktop LPC Device IDs
> +//
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU        0xA300
> ///< LPC/eSPI Controller
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU        0xA303
> ///< PCH H Mobile H310
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU        0xA304
> ///< PCH H Mobile H370
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU        0xA305
> ///< PCH H Mobile Z390
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU        0xA306
> ///< PCH H Mobile Q370
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU        0xA309
> ///< PCH H Mobile C246
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU        0xA30A
> ///< PCH H Mobile C242
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU        0xA30B
> ///< PCH H Mobile X399
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU        0xA30C
> ///< PCH H Mobile QM370
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU        0xA30D
> ///< PCH H Mobile HM370
> +#define V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU        0xA30E
> ///< PCH H Mobile CM246
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
> new file mode 100644
> index 0000000000..db6a8c4e95
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
> @@ -0,0 +1,116 @@
> +/** @file
> +  Register names for PCH P2SB device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_P2SB_H_
> +#define _PCH_REGS_P2SB_H_
> +
> +//
> +// PCI to P2SB Bridge Registers (D31:F1)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_P2SB                 31
> +#define PCI_FUNCTION_NUMBER_PCH_P2SB               1
> +
> +#define V_P2SB_CFG_VENDOR_ID
> V_PCH_INTEL_VENDOR_ID
> +#define R_P2SB_CFG_SBREG_BAR                       0x10
> +#define B_P2SB_CFG_SBREG_RBA                       0xFF000000
> +#define R_P2SB_CFG_SBREG_BARH                      0x14
> +#define B_P2SB_CFG_SBREG_RBAH                      0xFFFFFFFF
> +#define R_P2SB_CFG_VBDF                            0x50
> +#define B_P2SB_CFG_VBDF_BUS                        0xFF00
> +#define B_P2SB_CFG_VBDF_DEV                        0x00F8
> +#define B_P2SB_CFG_VBDF_FUNC                       0x0007
> +#define R_P2SB_CFG_ESMBDF                          0x52
> +#define B_P2SB_CFG_ESMBDF_BUS                      0xFF00
> +#define B_P2SB_CFG_ESMBDF_DEV                      0x00F8
> +#define B_P2SB_CFG_ESMBDF_FUNC                     0x0007
> +#define R_P2SB_CFG_RCFG                            0x54
> +#define B_P2SB_CFG_RCFG_RPRID                      0x0000FF00
> +#define B_P2SB_CFG_RCFG_RSE                        BIT0
> +#define R_P2SB_CFG_HPTC                            0x60
> +#define B_P2SB_CFG_HPTC_AE                         BIT7
> +#define B_P2SB_CFG_HPTC_AS                         0x0003
> +#define N_HPET_ADDR_ASEL                           12
> +#define R_P2SB_CFG_IOAC                            0x64
> +#define B_P2SB_CFG_IOAC_AE                         BIT8
> +#define B_P2SB_CFG_IOAC_ASEL                       0x00FF
> +#define N_IO_APIC_ASEL                             12
> +#define R_IO_APIC_INDEX_OFFSET                     0x00
> +#define R_IO_APIC_DATA_OFFSET                      0x10
> +#define R_IO_APIC_EOI_OFFSET                       0x40
> +#define R_P2SB_CFG_IBDF                            0x6C
> +#define B_P2SB_CFG_IBDF_BUS                        0xFF00
> +#define B_P2SB_CFG_IBDF_DEV                        0x00F8
> +#define B_P2SB_CFG_IBDF_FUNC                       0x0007
> +#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 B_P2SB_CFG_SBIADDR_DESTID                  0xFF000000
> +#define B_P2SB_CFG_SBIADDR_RS                      0x000F0000
> +#define B_P2SB_CFG_SBIADDR_OFFSET                  0x0000FFFF
> +#define R_P2SB_CFG_SBIDATA                         0xD4
> +#define B_P2SB_CFG_SBIDATA_DATA                    0xFFFFFFFF
> +#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 B_P2SB_CFG_SBIRID_FBE                      0xF000
> +#define B_P2SB_CFG_SBIRID_BAR                      0x0700
> +#define B_P2SB_CFG_SBIRID_FID                      0x00FF
> +#define R_P2SB_CFG_SBIEXTADDR                      0xDC
> +#define B_P2SB_CFG_SBIEXTADDR_ADDR                 0xFFFFFFFF
> +
> +//
> +// Others
> +//
> +#define R_P2SB_CFG_E0                              0xE0
> +#define R_P2SB_CFG_E4                              0xE4
> +#define R_P2SB_CFG_E8                              0xE8
> +#define R_P2SB_CFG_EA                              0xEA
> +#define R_P2SB_CFG_F4                              0xF4
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
> new file mode 100644
> index 0000000000..af19b93e2d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
> @@ -0,0 +1,484 @@
> +/** @file
> +  Register names for PCH PCI-E root port devices
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_PCIE_H_
> +#define _PCH_REGS_PCIE_H_
> +
> +//
> +// Number of PCIe ports per PCIe controller
> +//
> +#define PCH_PCIE_CONTROLLER_PORTS                 4u
> +
> +//
> +// PCH PCI Express Root Ports (D28:F0..7, D29:F0..7, D27:F0..7)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1       28
> +#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2       29
> +#define PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3       27
> +#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS     28
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1  0
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2  1
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3  2
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4  3
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5  4
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6  5
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7  6
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8  7
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9  0
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10 1
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11 2
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12 3
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_13 4
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_14 5
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_15 6
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_16 7
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_17 0
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_18 1
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_19 2
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_20 3
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_21 4
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_22 5
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_23 6
> +#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_24 7
> +
> +#define V_PCH_PCIE_CFG_VENDOR_ID
> V_PCH_INTEL_VENDOR_ID
> +
> +
> +#define R_PCH_PCIE_CFG_CLIST                          0x40
> +#define R_PCH_PCIE_CFG_XCAP                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_XCAP_OFFSET)
> +#define R_PCH_PCIE_CFG_DCAP                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_DCAP_OFFSET)
> +#define R_PCH_PCIE_CFG_DCTL                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_DCTL_OFFSET)
> +#define R_PCH_PCIE_CFG_DSTS                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_DSTS_OFFSET)
> +#define R_PCH_PCIE_CFG_LCAP                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_LCAP_OFFSET)
> +#define B_PCH_PCIE_CFG_LCAP_PN                        0xFF000000
> +#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_SLCTL                          (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_SLCTL_OFFSET)
> +#define R_PCH_PCIE_CFG_SLSTS                          (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_SLSTS_OFFSET)
> +#define R_PCH_PCIE_CFG_RCTL                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_RCTL_OFFSET)
> +#define R_PCH_PCIE_CFG_RSTS                           (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_RSTS_OFFSET)
> +#define R_PCH_PCIE_CFG_DCAP2
> (R_PCH_PCIE_CFG_CLIST + R_PCIE_DCAP2_OFFSET)
> +#define R_PCH_PCIE_CFG_DCTL2                          (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_DCTL2_OFFSET)
> +#define R_PCH_PCIE_CFG_LCTL2                          (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_LCTL2_OFFSET)
> +#define R_PCH_PCIE_CFG_LSTS2                          (R_PCH_PCIE_CFG_CLIST
> + R_PCIE_LSTS2_OFFSET)
> +
> +#define R_PCH_PCIE_CFG_MID                            0x80
> +#define S_PCH_PCIE_CFG_MID                            2
> +#define R_PCH_PCIE_CFG_MC                             0x82
> +#define S_PCH_PCIE_CFG_MC                             2
> +#define R_PCH_PCIE_CFG_MA                             0x84
> +#define S_PCH_PCIE_CFG_MA                             4
> +#define R_PCH_PCIE_CFG_MD                             0x88
> +#define S_PCH_PCIE_CFG_MD                             2
> +
> +#define R_PCH_PCIE_CFG_SVCAP                          0x90
> +#define S_PCH_PCIE_CFG_SVCAP                          2
> +#define R_PCH_PCIE_CFG_SVID                           0x94
> +#define S_PCH_PCIE_CFG_SVID                           4
> +
> +#define R_PCH_PCIE_CFG_PMCAP                          0xA0
> +#define R_PCH_PCIE_CFG_PMCS
> (R_PCH_PCIE_CFG_PMCAP + R_PCIE_PMCS_OFFST)
> +
> +#define R_PCH_PCIE_CFG_CCFG                           0xD0
> +#define B_PCH_PCIE_CFG_CCFG_UNRS                      (BIT6 | BIT5 | BIT4)
> +#define N_PCH_PCIE_CFG_CCFG_UNRS                      4
> +
> +#define R_PCH_PCIE_CFG_MPC2                           0xD4
> +#define S_PCH_PCIE_CFG_MPC2                           4
> +#define B_PCH_PCIE_CFG_MPC2_PTNFAE                    BIT12
> +#define B_PCH_PCIE_CFG_MPC2_LSTP                      BIT6
> +#define B_PCH_PCIE_CFG_MPC2_IEIME                     BIT5
> +#define B_PCH_PCIE_CFG_MPC2_ASPMCOEN                  BIT4
> +#define B_PCH_PCIE_CFG_MPC2_ASPMCO                    (BIT3 | BIT2)
> +#define V_PCH_PCIE_CFG_MPC2_ASPMCO_DISABLED           0
> +#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L0S                (1 << 2)
> +#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L1                 (2 << 2)
> +#define V_PCH_PCIE_CFG_MPC2_ASPMCO_L0S_L1             (3 << 2)
> +#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_HPCE                       BIT30
> +#define B_PCH_PCIE_CFG_MPC_MMBNCE                     BIT27
> +#define B_PCH_PCIE_CFG_MPC_P8XDE                      BIT26
> +#define B_PCH_PCIE_CFG_MPC_IRRCE                      BIT25
> +#define B_PCH_PCIE_CFG_MPC_SRL                        BIT23
> +#define B_PCH_PCIE_CFG_MPC_UCEL                       (BIT20 | BIT19 | BIT18)
> +#define N_PCH_PCIE_CFG_MPC_UCEL                       18
> +#define B_PCH_PCIE_CFG_MPC_CCEL                       (BIT17 | BIT16 | BIT15)
> +#define N_PCH_PCIE_CFG_MPC_CCEL                       15
> +#define B_PCH_PCIE_CFG_MPC_PCIESD                     (BIT14 | BIT13)
> +#define N_PCH_PCIE_CFG_MPC_PCIESD                     13
> +#define V_PCH_PCIE_CFG_MPC_PCIESD_GEN1                1
> +#define V_PCH_PCIE_CFG_MPC_PCIESD_GEN2                2
> +#define B_PCH_PCIE_CFG_MPC_MCTPSE                     BIT3
> +#define B_PCH_PCIE_CFG_MPC_HPME                       BIT1
> +#define N_PCH_PCIE_CFG_MPC_HPME                       1
> +#define B_PCH_PCIE_CFG_MPC_PMME                       BIT0
> +
> +#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
> +
> +#define R_PCH_PCIE_CFG_RPDCGEN                        0xE1
> +#define S_PCH_PCIE_CFG_RPDCGEN                        1
> +#define B_PCH_PCIE_CFG_RPDCGEN_RPSCGEN                BIT7
> +#define B_PCH_PCIE_CFG_RPDCGEN_PTOCGE                 BIT6
> +#define B_PCH_PCIE_CFG_RPDCGEN_LCLKREQEN              BIT5
> +#define B_PCH_PCIE_CFG_RPDCGEN_BBCLKREQEN             BIT4
> +#define B_PCH_PCIE_CFG_RPDCGEN_SRDBCGEN               BIT2
> +#define B_PCH_PCIE_CFG_RPDCGEN_RPDLCGEN               BIT1
> +#define B_PCH_PCIE_CFG_RPDCGEN_RPDBCGEN               BIT0
> +
> +
> +#define R_PCH_PCIE_CFG_PWRCTL                         0xE8
> +#define B_PCH_PCIE_CFG_PWRCTL_LTSSMRTC                BIT20
> +#define B_PCH_PCIE_CFG_PWRCTL_WPDMPGEP                BIT17
> +#define B_PCH_PCIE_CFG_PWRCTL_DBUPI                   BIT15
> +#define B_PCH_PCIE_CFG_PWRCTL_TXSWING                 BIT13
> +#define B_PCH_PCIE_CFG_PWRCTL_RPL1SQPOL               BIT1
> +#define B_PCH_PCIE_CFG_PWRCTL_RPDTSQPOL               BIT0
> +
> +#define R_PCH_PCIE_CFG_DC                             0xEC
> +#define B_PCH_PCIE_CFG_DC_PCIBEM                      BIT2
> +
> +#define R_PCH_PCIE_CFG_PHYCTL2                        0xF5
> +#define B_PCH_PCIE_CFG_PHYCTL2_TDFT                   (BIT7 | BIT6)
> +#define B_PCH_PCIE_CFG_PHYCTL2_TXCFGCHGWAIT           (BIT5 | BIT4)
> +#define N_PCH_PCIE_CFG_PHYCTL2_TXCFGCHGWAIT           4
> +#define B_PCH_PCIE_CFG_PHYCTL2_PXPG3PLLOFFEN          BIT1
> +#define B_PCH_PCIE_CFG_PHYCTL2_PXPG2PLLOFFEN          BIT0
> +
> +#define R_PCH_PCIE_CFG_IOSFSBCS                       0xF7
> +#define B_PCH_PCIE_CFG_IOSFSBCS_SCPTCGE               BIT6
> +#define B_PCH_PCIE_CFG_IOSFSBCS_SIID                  (BIT3 | BIT2)
> +
> +#define R_PCH_PCIE_CFG_STRPFUSECFG                    0xFC
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_PXIP               (BIT27 | BIT26 |
> BIT25 | BIT24)
> +#define N_PCH_PCIE_CFG_STRPFUSECFG_PXIP               24
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_RPC                (BIT15 | BIT14)
> +#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_1_1_1_1        0
> +#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_2_1_1          1
> +#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_2_2            2
> +#define V_PCH_PCIE_CFG_STRPFUSECFG_RPC_4              3
> +#define N_PCH_PCIE_CFG_STRPFUSECFG_RPC                14
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_MODPHYIOPMDIS      BIT9
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_PLLSHTDWNDIS       BIT8
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_STPGATEDIS         BIT7
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_ASPMDIS            BIT6
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_LDCGDIS            BIT5
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_LTCGDIS            BIT4
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_CDCGDIS            BIT3
> +#define B_PCH_PCIE_CFG_STRPFUSECFG_DESKTOPMOB         BIT2
> +
> +//
> +//PCI Express Extended Capability Registers
> +//
> +
> +#define R_PCH_PCIE_CFG_EXCAP_OFFSET                   0x100
> +
> +#define R_PCH_PCIE_CFG_EX_AECH                        0x100 ///< Advanced
> Error Reporting Capability Header
> +#define V_PCH_PCIE_CFG_EX_AEC_CV                      0x1
> +#define R_PCH_PCIE_CFG_EX_UEM
> (R_PCH_PCIE_CFG_EX_AECH + R_PCIE_EX_UEM_OFFSET) // Uncorrectable
> Error Mask
> +
> +#define R_PCH_PCIE_CFG_EX_CES                         0x110 ///< Correctable
> Error Status
> +#define B_PCH_PCIE_CFG_EX_CES_BD                      BIT7  ///< Bad DLLP
> Status
> +#define B_PCH_PCIE_CFG_EX_CES_BT                      BIT6  ///< Bad TLP
> Status
> +#define B_PCH_PCIE_CFG_EX_CES_RE                      BIT0  ///< Receiver
> Error Status
> +
> +
> +//CES.RE, CES.BT, CES.BD
> +
> +#define R_PCH_PCIE_CFG_EX_ACSECH                      0x140 ///< ACS
> Extended Capability Header
> +#define V_PCH_PCIE_CFG_EX_ACS_CV                      0x1
> +#define R_PCH_PCIE_CFG_EX_ACSCAPR
> (R_PCH_PCIE_CFG_EX_ACSECH + R_PCIE_EX_ACSCAPR_OFFSET)
> +
> +#define R_PCH_PCIE_CFG_EX_L1SECH                      0x200 ///< L1
> Sub-States Extended Capability Header
> +#define V_PCH_PCIE_CFG_EX_L1S_CV                      0x1
> +#define R_PCH_PCIE_CFG_EX_L1SCAP
> (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCAP_OFFSET)
> +#define R_PCH_PCIE_CFG_EX_L1SCTL1
> (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCTL1_OFFSET)
> +#define R_PCH_PCIE_CFG_EX_L1SCTL2
> (R_PCH_PCIE_CFG_EX_L1SECH + R_PCIE_EX_L1SCTL2_OFFSET)
> +
> +#define R_PCH_PCIE_CFG_EX_SPEECH                      0x220 ///< Secondary
> PCI Express Extended Capability Header
> +#define V_PCH_PCIE_CFG_EX_SPEECH_CV                   0x1
> +#define R_PCH_PCIE_CFG_EX_LCTL3
> (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LCTL3_OFFSET)
> +#define R_PCH_PCIE_CFG_EX_LES
> (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LES_OFFSET)
> +#define R_PCH_PCIE_CFG_EX_LECTL
> (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L01EC_OFFSET)
> +#define B_PCH_PCIE_CFG_EX_LECTL_UPTPH                 (BIT14 | BIT13 |
> BIT12)
> +#define N_PCH_PCIE_CFG_EX_LECTL_UPTPH                 12
> +#define B_PCH_PCIE_CFG_EX_LECTL_UPTP                  0x0F00
> +#define N_PCH_PCIE_CFG_EX_LECTL_UPTP                  8
> +#define B_PCH_PCIE_CFG_EX_LECTL_DPTPH                 (BIT6 | BIT5 | BIT4)
> +#define N_PCH_PCIE_CFG_EX_LECTL_DPTPH                 4
> +#define B_PCH_PCIE_CFG_EX_LECTL_DPTP                  0x000F
> +#define N_PCH_PCIE_CFG_EX_LECTL_DPTP                  0
> +
> +#define R_PCH_PCIE_CFG_EX_L01EC
> (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L01EC_OFFSET)
> +#define R_PCH_PCIE_CFG_EX_L23EC
> (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_L23EC_OFFSET)
> +
> +#define R_PCH_PCIE_CFG_PCIERTP1                       0x300
> +#define R_PCH_PCIE_CFG_PCIERTP2                       0x304
> +#define R_PCH_PCIE_CFG_PCIENFTS                       0x314
> +#define R_PCH_PCIE_CFG_PCIEL0SC                       0x318
> +
> +#define R_PCH_PCIE_CFG_PCIECFG2                       0x320
> +#define B_PCH_PCIE_CFG_PCIECFG2_LBWSSTE               BIT30
> +#define B_PCH_PCIE_CFG_PCIECFG2_RLLG3R                BIT27
> +#define B_PCH_PCIE_CFG_PCIECFG2_CROAOV                BIT24
> +#define B_PCH_PCIE_CFG_PCIECFG2_CROAOE                BIT23
> +#define B_PCH_PCIE_CFG_PCIECFG2_CRSREN                BIT22
> +#define B_PCH_PCIE_CFG_PCIECFG2_PMET                  (BIT21 | BIT20)
> +#define V_PCH_PCIE_CFG_PCIECFG2_PMET                  1
> +#define N_PCH_PCIE_CFG_PCIECFG2_PMET                  20
> +
> +#define R_PCH_PCIE_CFG_PCIEDBG                        0x324
> +#define B_PCH_PCIE_CFG_PCIEDBG_LBWSSTE                BIT30
> +#define B_PCH_PCIE_CFG_PCIEDBG_USSP                   (BIT27 | BIT26)
> +#define B_PCH_PCIE_CFG_PCIEDBG_LGCLKSQEXITDBTIMERS    (BIT25 |
> BIT24)
> +#define B_PCH_PCIE_CFG_PCIEDBG_CTONFAE                BIT14
> +#define B_PCH_PCIE_CFG_PCIEDBG_SQOL0                  BIT7
> +#define B_PCH_PCIE_CFG_PCIEDBG_SPCE                   BIT5
> +#define B_PCH_PCIE_CFG_PCIEDBG_LR                     BIT4
> +
> +#define R_PCH_PCIE_CFG_PCIESTS1                              0x328
> +#define B_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE                    0xFF000000
> +#define N_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE                    24
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DETRDY             0x01
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DETRDYECINP1CG     0x0E
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_L0                 0x33
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DISWAIT            0x5E
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_DISWAITPG          0x60
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_RECOVERYSPEEDREADY
> 0x6C
> +#define V_PCH_PCIE_CFG_PCIESTS1_LTSMSTATE_RECOVERYLNK2DETECT
> 0x6F
> +
> +
> +#define B_PCH_PCIE_CFG_PCIESTS1_LNKSTAT               (BIT22 | BIT21 |
> BIT20 | BIT19)
> +#define N_PCH_PCIE_CFG_PCIESTS1_LNKSTAT               19
> +#define V_PCH_PCIE_CFG_PCIESTS1_LNKSTAT_L0            0x7
> +
> +#define R_PCH_PCIE_CFG_PCIESTS2                       0x32C
> +#define B_PCH_PCIE_CFG_PCIESTS2_P4PNCCWSSCMES         BIT31
> +#define B_PCH_PCIE_CFG_PCIESTS2_P3PNCCWSSCMES         BIT30
> +#define B_PCH_PCIE_CFG_PCIESTS2_P2PNCCWSSCMES         BIT29
> +#define B_PCH_PCIE_CFG_PCIESTS2_P1PNCCWSSCMES         BIT28
> +#define B_PCH_PCIE_CFG_PCIESTS2_CLRE                  0x0000F000
> +#define N_PCH_PCIE_CFG_PCIESTS2_CLRE                  12
> +
> +#define R_PCH_PCIE_CFG_PCIEALC                        0x338
> +#define B_PCH_PCIE_CFG_PCIEALC_ITLRCLD                BIT29
> +#define B_PCH_PCIE_CFG_PCIEALC_ILLRCLD                BIT28
> +#define B_PCH_PCIE_CFG_PCIEALC_BLKDQDA                BIT26
> +
> +
> +#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_PHYCTL4                        0x408
> +#define B_PCH_PCIE_CFG_PHYCTL4_SQDIS                  BIT27
> +
> +#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_PCIEPMECTL2                    0x424
> +#define B_PCH_PCIE_CFG_PCIEPMECTL2_PHYCLPGE           BIT11
> +#define B_PCH_PCIE_CFG_PCIEPMECTL2_FDCPGE             BIT8
> +#define B_PCH_PCIE_CFG_PCIEPMECTL2_DETSCPGE           BIT7
> +#define B_PCH_PCIE_CFG_PCIEPMECTL2_L23RDYSCPGE        BIT6
> +#define B_PCH_PCIE_CFG_PCIEPMECTL2_DISSCPGE           BIT5
> +#define B_PCH_PCIE_CFG_PCIEPMECTL2_L1SCPGE            BIT4
> +
> +#define R_PCH_PCIE_CFG_PCE                            0x428
> +#define B_PCH_PCIE_CFG_PCE_HAE                        BIT5
> +#define B_PCH_PCIE_CFG_PCE_PMCRE                      BIT0
> +
> +#define R_PCH_PCIE_CFG_EQCFG1                         0x450
> +#define S_PCH_PCIE_CFG_EQCFG1                         4
> +#define B_PCH_PCIE_CFG_EQCFG1_REC                     0xFF000000
> +#define N_PCH_PCIE_CFG_EQCFG1_REC                     24
> +#define B_PCH_PCIE_CFG_EQCFG1_REIFECE                 BIT23
> +#define N_PCH_PCIE_CFG_EQCFG1_LERSMIE                 21
> +#define B_PCH_PCIE_CFG_EQCFG1_LEP23B                  BIT18
> +#define B_PCH_PCIE_CFG_EQCFG1_LEP3B                   BIT17
> +#define B_PCH_PCIE_CFG_EQCFG1_RTLEPCEB                BIT16
> +#define B_PCH_PCIE_CFG_EQCFG1_RTPCOE                  BIT15
> +#define B_PCH_PCIE_CFG_EQCFG1_HPCMQE                  BIT13
> +#define B_PCH_PCIE_CFG_EQCFG1_HAED                    BIT12
> +#define B_PCH_PCIE_CFG_EQCFG1_EQTS2IRRC               BIT7
> +#define B_PCH_PCIE_CFG_EQCFG1_TUPP                    BIT1
> +
> +#define R_PCH_PCIE_CFG_RTPCL1                         0x454
> +#define B_PCH_PCIE_CFG_RTPCL1_PCM                     BIT31
> +#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL2PL4             0x3F000000
> +#define B_PCH_PCIE_CFG_RTPCL1_RTPOSTCL1PL3            0xFC0000
> +#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL1PL2             0x3F000
> +#define B_PCH_PCIE_CFG_RTPCL1_RTPOSTCL0PL1            0xFC0
> +#define B_PCH_PCIE_CFG_RTPCL1_RTPRECL0PL0             0x3F
> +
> +#define R_PCH_PCIE_CFG_RTPCL2                         0x458
> +#define B_PCH_PCIE_CFG_RTPCL2_RTPOSTCL3PL             0x3F000
> +#define B_PCH_PCIE_CFG_RTPCL2_RTPRECL3PL6             0xFC0
> +#define B_PCH_PCIE_CFG_RTPCL2_RTPOSTCL2PL5            0x3F
> +
> +#define R_PCH_PCIE_CFG_RTPCL3                         0x45C
> +#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL7                0x3F000000
> +#define B_PCH_PCIE_CFG_RTPCL3_RTPOSTCL6               0xFC0000
> +#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL6                0x3F000
> +#define B_PCH_PCIE_CFG_RTPCL3_RTPOSTCL5               0xFC0
> +#define B_PCH_PCIE_CFG_RTPCL3_RTPRECL5PL10            0x3F
> +
> +#define R_PCH_PCIE_CFG_RTPCL4                         0x460
> +#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL9               0x3F000000
> +#define B_PCH_PCIE_CFG_RTPCL4_RTPRECL9                0xFC0000
> +#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL8               0x3F000
> +#define B_PCH_PCIE_CFG_RTPCL4_RTPRECL8                0xFC0
> +#define B_PCH_PCIE_CFG_RTPCL4_RTPOSTCL7               0x3F
> +
> +#define R_PCH_PCIE_CFG_FOMS                           0x464
> +#define B_PCH_PCIE_CFG_FOMS_I                         (BIT30 | BIT29)
> +#define N_PCH_PCIE_CFG_FOMS_I                         29
> +#define B_PCH_PCIE_CFG_FOMS_LN                        0x1F000000
> +#define N_PCH_PCIE_CFG_FOMS_LN                        24
> +#define B_PCH_PCIE_CFG_FOMS_FOMSV                     0x00FFFFFF
> +#define B_PCH_PCIE_CFG_FOMS_FOMSV0                    0x000000FF
> +#define N_PCH_PCIE_CFG_FOMS_FOMSV0                    0
> +#define B_PCH_PCIE_CFG_FOMS_FOMSV1                    0x0000FF00
> +#define N_PCH_PCIE_CFG_FOMS_FOMSV1                    8
> +#define B_PCH_PCIE_CFG_FOMS_FOMSV2                    0x00FF0000
> +#define N_PCH_PCIE_CFG_FOMS_FOMSV2                    16
> +
> +#define R_PCH_PCIE_CFG_HAEQ                           0x468
> +#define B_PCH_PCIE_CFG_HAEQ_HAPCCPI                   (BIT31 | BIT30 |
> BIT29 | BIT28)
> +#define N_PCH_PCIE_CFG_HAEQ_HAPCCPI                   28
> +#define B_PCH_PCIE_CFG_HAEQ_MACFOMC                   BIT19
> +
> +#define R_PCH_PCIE_CFG_LTCO1                          0x470
> +#define B_PCH_PCIE_CFG_LTCO1_L1TCOE                   BIT25
> +#define B_PCH_PCIE_CFG_LTCO1_L0TCOE                   BIT24
> +#define B_PCH_PCIE_CFG_LTCO1_L1TPOSTCO                0xFC0000
> +#define N_PCH_PCIE_CFG_LTCO1_L1TPOSTCO                18
> +#define B_PCH_PCIE_CFG_LTCO1_L1TPRECO                 0x3F000
> +#define N_PCH_PCIE_CFG_LTCO1_L1TPRECO                 12
> +#define B_PCH_PCIE_CFG_LTCO1_L0TPOSTCO                0xFC0
> +#define N_PCH_PCIE_CFG_LTCO1_L0TPOSTCO                6
> +#define B_PCH_PCIE_CFG_LTCO1_L0TPRECO                 0x3F
> +#define N_PCH_PCIE_CFG_LTCO1_L0TPRECO                 0
> +
> +#define R_PCH_PCIE_CFG_LTCO2                          0x474
> +#define B_PCH_PCIE_CFG_LTCO2_L3TCOE                   BIT25
> +#define B_PCH_PCIE_CFG_LTCO2_L2TCOE                   BIT24
> +#define B_PCH_PCIE_CFG_LTCO2_L3TPOSTCO                0xFC0000
> +#define B_PCH_PCIE_CFG_LTCO2_L3TPRECO                 0x3F000
> +#define B_PCH_PCIE_CFG_LTCO2_L2TPOSTCO                0xFC0
> +#define B_PCH_PCIE_CFG_LTCO2_L2TPRECO                 0x3F
> +
> +#define R_PCH_PCIE_CFG_G3L0SCTL                       0x478
> +#define B_PCH_PCIE_CFG_G3L0SCTL_G3UCNFTS              0x0000FF00
> +#define B_PCH_PCIE_CFG_G3L0SCTL_G3CCNFTS              0x000000FF
> +
> +#define R_PCH_PCIE_CFG_EQCFG2                         0x47C
> +#define B_PCH_PCIE_CFG_EQCFG2_NTIC                    0xFF000000
> +#define B_PCH_PCIE_CFG_EQCFG2_EMD                     BIT23
> +#define B_PCH_PCIE_CFG_EQCFG2_NTSS                    (BIT22 | BIT21 |
> BIT20)
> +#define B_PCH_PCIE_CFG_EQCFG2_PCET                    (BIT19 | BIT18 | BIT17
> | BIT16)
> +#define N_PCH_PCIE_CFG_EQCFG2_PCET                    16
> +#define B_PCH_PCIE_CFG_EQCFG2_HAPCSB                  (BIT15 | BIT14 |
> BIT13 | BIT12)
> +#define N_PCH_PCIE_CFG_EQCFG2_HAPCSB                  12
> +#define B_PCH_PCIE_CFG_EQCFG2_NTEME                   BIT11
> +#define B_PCH_PCIE_CFG_EQCFG2_MPEME                   BIT10
> +#define B_PCH_PCIE_CFG_EQCFG2_REWMETM                 (BIT9 | BIT8)
> +#define B_PCH_PCIE_CFG_EQCFG2_REWMET                  0xFF
> +
> +#define R_PCH_PCIE_CFG_MM                             0x480
> +#define B_PCH_PCIE_CFG_MM_MSST                        0xFFFFFF00
> +#define N_PCH_PCIE_CFG_MM_MSST                        8
> +#define B_PCH_PCIE_CFG_MM_MSS                         0xFF
> +
> +//
> +// 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 B_SPX_PCR_PCD_RP1CH                   BIT3                    ///< Port 1
> config hide
> +#define B_SPX_PCR_PCD_RP2FN                   (BIT6 | BIT5 | BIT4)    ///< Port
> 2 Function Number
> +#define B_SPX_PCR_PCD_RP2CH                   BIT7                    ///< Port 2
> config hide
> +#define B_SPX_PCR_PCD_RP3FN                   (BIT10 | BIT9 | BIT8)   ///< Port
> 3 Function Number
> +#define B_SPX_PCR_PCD_RP3CH                   BIT11                   ///< Port 3
> config hide
> +#define B_SPX_PCR_PCD_RP4FN                   (BIT14 | BIT13 | BIT12) ///<
> Port 4 Function Number
> +#define B_SPX_PCR_PCD_RP4CH                   BIT15                   ///< Port 4
> config hide
> +#define S_SPX_PCR_PCD_RP_FIELD                4                       ///< 4 bits
> for each RP FN
> +#define B_SPX_PCR_PCD_P1D                     BIT16                   ///< Port 1
> disable
> +#define B_SPX_PCR_PCD_P2D                     BIT17                   ///< Port 2
> disable
> +#define B_SPX_PCR_PCD_P3D                     BIT18                   ///< Port 3
> disable
> +#define B_SPX_PCR_PCD_P4D                     BIT19                   ///< Port 4
> disable
> +#define B_SPX_PCR_PCD_SRL                     BIT31                   ///< Secured
> Register Lock
> +
> +#define R_SPX_PCR_PCIEHBP                     0x0004                  ///< PCI
> Express high-speed bypass
> +#define B_SPX_PCR_PCIEHBP_PCIEHBPME           BIT0                    ///<
> PCIe HBP mode enable
> +#define B_SPX_PCR_PCIEHBP_PCIEGMO             (BIT2 | BIT1)           ///<
> PCIe gen mode override
> +#define B_SPX_PCR_PCIEHBP_PCIETIL0O           BIT3                    ///< PCIe
> transmitter-in-L0 override
> +#define B_SPX_PCR_PCIEHBP_PCIERIL0O           BIT4                    ///< PCIe
> receiver-in-L0 override
> +#define B_SPX_PCR_PCIEHBP_PCIELRO             BIT5                    ///< PCIe
> link recovery override
> +#define B_SPX_PCR_PCIEHBP_PCIELDO             BIT6                    ///< PCIe
> link down override
> +#define B_SPX_PCR_PCIEHBP_PCIESSM             BIT7                    ///< PCIe
> SKP suppression mode
> +#define B_SPX_PCR_PCIEHBP_PCIESST             BIT8                    ///< PCIe
> suppress SKP transmission
> +#define B_SPX_PCR_PCIEHBP_PCIEHBPPS           (BIT13 | BIT12)         ///<
> PCIe HBP port select
> +#define B_SPX_PCR_PCIEHBP_CRCSEL              (BIT15 | BIT14)         ///<
> CRC select
> +#define B_SPX_PCR_PCIEHBP_PCIEHBPCRC          0xFFFF0000              ///<
> PCIe HBP CRC
> +
> +//
> +// ICC PCR (PID: ICC)
> +//
> +#define R_ICC_PCR_TMCSRCCLK                   0x1000                  ///<
> Timing Control SRC Clock Register
> +#define R_ICC_PCR_TMCSRCCLK2                  0x1004                  ///<
> Timing Control SRC Clock Register 2
> +#define R_ICC_PCR_MSKCKRQ                     0x100C                  ///< Mask
> Control CLKREQ
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
> new file mode 100644
> index 0000000000..ed1668300a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
> @@ -0,0 +1,73 @@
> +/** @file
> +  Register names for PCH private chipset 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
> +  - 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_H_", "_PCH_LP_"
> +    Registers / bits names without _H_ or _LP_ apply for both H and 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) 2019 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_OPIPHY     0xAC
> +#define PID_MODPHY0    0xAB
> +#define PID_MODPHY1    0xAA
> +#define PID_USB2       0xCA
> +#define PID_DMI        0x88
> +#define PID_PSTH       0x89
> +#define PID_DSP        0xD7
> +#define PID_ESPISPI    0x72
> +#define PID_FIA        0xCF
> +#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_SERIALIO   0xCB
> +#define PID_LPC        0xC7
> +#define PID_SMB        0xC6
> +#define PID_ITSS       0xC4
> +#define PID_RTC_HOST   0xC3
> +#define PID_PSF6       0x7F
> +#define PID_PSF7       0x7E
> +#define PID_PSF8       0x7D
> +#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_CSME12     0x9C
> +
> +#define PID_CSME0      0x90
> +#define PID_CSME_PSF   0x8F
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
> new file mode 100644
> index 0000000000..dcecc633a1
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
> @@ -0,0 +1,670 @@
> +/** @file
> +  Register names for PCH PMC device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_PMC_H_
> +#define _PCH_REGS_PMC_H_
> +
> +//
> +// PMC Registers (D31:F2)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_PMC                31
> +#define PCI_FUNCTION_NUMBER_PCH_PMC              2
> +
> +#define R_PMC_CFG_BASE                           0x10
> +#define B_PMC_CFG_PWRM_BASE_MASK                 0xFFFF0000
> ///< PWRM must be 64KB alignment to align the source decode.
> +
> +//
> +// 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_BM                     BIT4
> +#define B_ACPI_IO_PM1_STS_TMROF                  BIT0
> +#define N_ACPI_IO_PM1_STS_WAK                    15
> +#define N_ACPI_IO_PM1_STS_PCIEXP_WAKE_STS        14
> +#define N_ACPI_IO_PM1_STS_PRBTNOR                11
> +#define N_ACPI_IO_PM1_STS_RTC                    10
> +#define N_ACPI_IO_PM1_STS_PWRBTN                 8
> +#define N_ACPI_IO_PM1_STS_GBL                    5
> +#define N_ACPI_IO_PM1_STS_BM                     4
> +#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_RTC                     BIT10
> +#define B_ACPI_IO_PM1_EN_PWRBTN                  BIT8
> +#define B_ACPI_IO_PM1_EN_GBL                     BIT5
> +#define B_ACPI_IO_PM1_EN_TMROF                   BIT0
> +#define N_ACPI_IO_PM1_EN_RTC                     10
> +#define N_ACPI_IO_PM1_EN_PWRBTN                  8
> +#define N_ACPI_IO_PM1_EN_GBL                     5
> +#define N_ACPI_IO_PM1_EN_TMROF                   0
> +
> +#define R_ACPI_IO_PM1_CNT                        0x04
> +#define S_ACPI_IO_PM1_CNT                        4
> +#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_GBL_RLS                BIT2
> +#define B_ACPI_IO_PM1_CNT_BM_RLD                 BIT1
> +#define B_ACPI_IO_PM1_CNT_SCI_EN                 BIT0
> +
> +#define R_ACPI_IO_PM1_TMR                        0x08
> +#define V_ACPI_IO_PM1_TMR_FREQUENCY              3579545
> +#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_USB3                  BIT31
> +#define B_ACPI_IO_SMI_EN_GPIO_UNLOCK_SMI              BIT27
> +#define B_ACPI_IO_SMI_EN_LEGACY_USB2                  BIT17
> +#define B_ACPI_IO_SMI_EN_PERIODIC                     BIT14
> +#define B_ACPI_IO_SMI_EN_TCO                          BIT13
> +#define B_ACPI_IO_SMI_EN_MCSMI                        BIT11
> +#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_ON_SLP_EN                    BIT4
> +#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_GPIO_UNLOCK                  27
> +#define N_ACPI_IO_SMI_EN_INTEL_USB2                   18
> +#define N_ACPI_IO_SMI_EN_LEGACY_USB2                  17
> +#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_BIOS_RLS                     7
> +#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 N_ACPI_IO_SMI_EN_BIOS                         2
> +#define N_ACPI_IO_SMI_EN_EOS                          1
> +#define N_ACPI_IO_SMI_EN_GBL_SMI                      0
> +
> +#define R_ACPI_IO_SMI_STS                             0x34
> +#define S_ACPI_IO_SMI_STS                             4
> +#define B_ACPI_IO_SMI_STS_LEGACY_USB3                 BIT31
> +#define B_ACPI_IO_SMI_STS_GPIO_UNLOCK                 BIT27
> +#define B_ACPI_IO_SMI_STS_SPI                         BIT26
> +#define B_ACPI_IO_SMI_STS_MONITOR                     BIT21
> +#define B_ACPI_IO_SMI_STS_PCI_EXP                     BIT20
> +#define B_ACPI_IO_SMI_STS_PATCH                       BIT19
> +#define B_ACPI_IO_SMI_STS_INTEL_USB2                  BIT18
> +#define B_ACPI_IO_SMI_STS_LEGACY_USB2                 BIT17
> +#define B_ACPI_IO_SMI_STS_SMBUS                       BIT16
> +#define B_ACPI_IO_SMI_STS_SERIRQ                      BIT15
> +#define B_ACPI_IO_SMI_STS_PERIODIC                    BIT14
> +#define B_ACPI_IO_SMI_STS_TCO                         BIT13
> +#define B_ACPI_IO_SMI_STS_DEVMON                      BIT12
> +#define B_ACPI_IO_SMI_STS_MCSMI                       BIT11
> +#define B_ACPI_IO_SMI_STS_GPIO_SMI                    BIT10
> +#define B_ACPI_IO_SMI_STS_GPE0                        BIT9
> +#define B_ACPI_IO_SMI_STS_PM1_STS_REG                 BIT8
> +#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_LEGACY_USB                  BIT3
> +#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_GPIO_UNLOCK                 27
> +#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_PATCH                       19
> +#define N_ACPI_IO_SMI_STS_INTEL_USB2                  18
> +#define N_ACPI_IO_SMI_STS_LEGACY_USB2                 17
> +#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_DEVMON                      12
> +#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 N_ACPI_IO_SMI_STS_BIOS                        2
> +
> +#define R_ACPI_IO_GPE_CNTL                            0x40
> +#define B_ACPI_IO_GPE_CNTL_SWGPE_CTRL                 BIT17
> +
> +#define R_ACPI_IO_DEVACT_STS                          0x44
> +#define S_ACPI_IO_DEVACT_STS                          2
> +#define B_ACPI_IO_DEVACT_STS_MASK                     0x13E1
> +#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 B_ACPI_IO_DEVACT_STS_D0_TRP                   BIT0
> +#define N_ACPI_IO_DEVACT_STS_KBC                      12
> +#define N_ACPI_IO_DEVACT_STS_PIRQDH                   9
> +#define N_ACPI_IO_DEVACT_STS_PIRQCG                   8
> +#define N_ACPI_IO_DEVACT_STS_PIRQBF                   7
> +#define N_ACPI_IO_DEVACT_STS_PIRQAE                   6
> +
> +#define R_ACPI_IO_PM2_CNT                             0x50
> +#define B_ACPI_IO_PM2_CNT_ARB_DIS                     BIT0
> +
> +#define R_ACPI_IO_OC_WDT_CTL                          0x54
> +#define B_ACPI_IO_OC_WDT_CTL_RLD                      BIT31
> +#define B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS              BIT25
> +#define B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS           BIT24
> +#define B_ACPI_IO_OC_WDT_CTL_FORCE_ALL                BIT15
> +#define B_ACPI_IO_OC_WDT_CTL_EN                       BIT14
> +#define B_ACPI_IO_OC_WDT_CTL_ICCSURV                  BIT13
> +#define B_ACPI_IO_OC_WDT_CTL_LCK                      BIT12
> +#define B_ACPI_IO_OC_WDT_CTL_TOV_MASK                 0x3FF
> +#define B_ACPI_IO_OC_WDT_CTL_FAILURE_STS              BIT23
> +#define B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS           BIT22
> +#define B_ACPI_IO_OC_WDT_CTL_AFTER_POST               0x3F0000
> +#define V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE           1
> +#define V_ACPI_IO_OC_WDT_CTL_STATUS_OK                0
> +
> +#define R_ACPI_IO_GPE0_STS_31_0                    0x60
> +#define R_ACPI_IO_GPE0_STS_63_32                   0x64
> +#define R_ACPI_IO_GPE0_STS_95_64                   0x68
> +#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_GPIO_TIER_2      BIT15
> +#define B_ACPI_IO_GPE0_STS_127_96_PME_B0           BIT13
> +#define B_ACPI_IO_GPE0_STS_127_96_ME_SCI           BIT12
> +#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_PCI_EXP          BIT9
> +#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_TC0SCI           BIT6
> +#define B_ACPI_IO_GPE0_STS_127_96_SWGPE            BIT2
> +#define B_ACPI_IO_GPE0_STS_127_96_HOT_PLUG         BIT1
> +#define N_ACPI_IO_GPE0_STS_127_96_PME_B0           13
> +#define N_ACPI_IO_GPE0_STS_127_96_PME              11
> +#define N_ACPI_IO_GPE0_STS_127_96_BATLOW           10
> +#define N_ACPI_IO_GPE0_STS_127_96_PCI_EXP          9
> +#define N_ACPI_IO_GPE0_STS_127_96_RI               8
> +#define N_ACPI_IO_GPE0_STS_127_96_SMB_WAK          7
> +#define N_ACPI_IO_GPE0_STS_127_96_TC0SCI           6
> +#define N_ACPI_IO_GPE0_STS_127_96_SWGPE            2
> +#define N_ACPI_IO_GPE0_STS_127_96_HOT_PLUG         1
> +
> +#define R_ACPI_IO_GPE0_EN_31_0                     0x70
> +#define R_ACPI_IO_GPE0_EN_63_32                    0x74
> +#define R_ACPI_IO_GPE0_EN_95_64                    0x78
> +#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_USB_CON_DSX_EN    BIT17
> +#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_PCI_EXP           BIT9
> +#define B_ACPI_IO_GPE0_EN_127_96_RI                BIT8
> +#define B_ACPI_IO_GPE0_EN_127_96_TC0SCI            BIT6
> +#define B_ACPI_IO_GPE0_EN_127_96_SWGPE             BIT2
> +#define B_ACPI_IO_GPE0_EN_127_96_HOT_PLUG          BIT1
> +#define N_ACPI_IO_GPE0_EN_127_96_PME_B0            13
> +#define N_ACPI_IO_GPE0_EN_127_96_USB3              12
> +#define N_ACPI_IO_GPE0_EN_127_96_PME               11
> +#define N_ACPI_IO_GPE0_EN_127_96_BATLOW            10
> +#define N_ACPI_IO_GPE0_EN_127_96_PCI_EXP           9
> +#define N_ACPI_IO_GPE0_EN_127_96_RI                8
> +#define N_ACPI_IO_GPE0_EN_127_96_TC0SCI            6
> +#define N_ACPI_IO_GPE0_EN_127_96_SWGPE             2
> +#define N_ACPI_IO_GPE0_EN_127_96_HOT_PLUG          1
> +
> +
> +//
> +// TCO register I/O map
> +//
> +#define R_TCO_IO_RLD                                 0x0
> +#define R_TCO_IO_DAT_IN                              0x2
> +#define R_TCO_IO_DAT_OUT                             0x3
> +#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 R_TCO_IO_TCO2_STS                            0x06
> +#define S_TCO_IO_TCO2_STS                            2
> +#define B_TCO_IO_TCO2_STS_SMLINK_SLV_SMI             BIT4
> +#define B_TCO_IO_TCO2_STS_BAD_BIOS                   BIT3
> +#define B_TCO_IO_TCO2_STS_BOOT                       BIT2
> +#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 B_TCO_IO_TCO1_CNT_TMR_HLT                    BIT11
> +#define B_TCO_IO_TCO1_CNT_NR_MSUS                    BIT0  //NO_REBOOT
> +
> +#define R_TCO_IO_TCO2_CNT                            0x0A
> +#define S_TCO_IO_TCO2_CNT                            2
> +#define B_TCO_IO_TCO2_CNT_OS_POLICY                  0x0030
> +#define B_TCO_IO_TCO2_CNT_GPI11_ALERT_DISABLE        0x0008
> +#define B_TCO_IO_TCO2_CNT_INTRD_SEL                  0x0006
> +#define N_TCO_IO_TCO2_CNT_INTRD_SEL                  2
> +
> +#define R_TCO_IO_MESSAGE1                            0x0C
> +#define R_TCO_IO_MESSAGE2                            0x0D
> +#define R_TCO_IO_TWDS                                0x0E           ///<
> TCO_WDSTATUS register.
> +#define R_TCO_IO_LE                                  0x10           ///<
> LEGACY_ELIM register
> +#define B_TCO_IO_LE_IRQ12_CAUSE                      BIT1
> +#define B_TCO_IO_LE_IRQ1_CAUSE                       BIT0
> +#define R_TCO_IO_TMR                                 0x12
> +
> +//
> +// PWRM Registers for IPC interface
> +//
> +#define R_PMC_PWRM_IPC_CMD                                  0x00
> ///< IPC command
> +#define N_PMC_PWRM_IPC_CMD_CMD_ID                           12
> ///< IPC command.cmd.ID
> +#define N_PMC_PWRM_IPC_CMD_SIZE                             16
> ///< IPC command.size
> +#define B_PMC_PWRM_IPC_CMD_SIZE_MASK                        0x00FF0000
> ///< IPC command.size mask Bits[23:16]
> +#define N_PMC_PWRM_IPC_CMD_COMMAND                          0
> ///< IPC command.cmd.Command
> +#define B_PMC_PWRM_IPC_CMD_COMMAND_MASK
> 0x000000FF                  ///< IPC command.size mask Bits[07:00]
> +#define V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL                 0xA1
> ///< IPC commmand to control S0ix policies RCOMP
> +#define V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE                0xA4
> ///< IPC commmand to control NPK Power State
> +#define V_PMC_PWRM_IPC_CMD_COMMAND_PROXY                    0xAA
> ///< Proxy access to SOC registers
> +#define V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ                   0
> ///< Read command
> +#define V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE                  1
> ///< Write command
> +#define V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI                     2
> ///< parameter to access NMI control register
> +#define R_PMC_PWRM_IPC_STS                                  0x04
> ///< IPC Status
> +#define B_PMC_PWRM_IPC_STS_BUSY                             BIT0
> ///< IPC Status Busy Bit
> +#define B_PMC_PWRM_IPC_STS_ERROR                            BIT1
> ///< IPC Status Error Bit
> +#define N_PMC_PWRM_IPC_STS_ERR_CODE                         BIT16
> ///< IPC Status Error status
> +#define B_PMC_PWRM_IPC_STS_ERR_CODE_MASK
> 0x00FF0000                  ///< IPC Status Error status mask[23:16]
> +#define R_PMC_PWRM_IPC_SPTR                                 0x08
> ///< IPC Source Pointer
> +#define R_PMC_PWRM_IPC_DPTR                                 0x0C
> ///< IPC Destination Pointer
> +#define R_PMC_PWRM_IPC_WBUF0                                0x80
> ///< IPC Write Buffer
> +#define R_PMC_PWRM_IPC_WBUF1                                0x84
> ///< IPC Write Buffer
> +#define R_PMC_PWRM_IPC_WBUF2                                0x88
> ///< IPC Write Buffer
> +#define R_PMC_PWRM_IPC_WBUF3                                0x8C
> ///< IPC Write Buffer
> +#define R_PMC_PWRM_IPC_RBUF0                                0x90
> ///< IPC Read Buffer
> +#define R_PMC_PWRM_IPC_RBUF1                                0x94
> ///< IPC Read Buffer
> +#define R_PMC_PWRM_IPC_RBUF2                                0x98
> ///< IPC Read Buffer
> +#define R_PMC_PWRM_IPC_RBUF3                                0x9C
> ///< IPC Read Buffer
> +//
> +// PWRM Registers
> +//
> +#define R_PMC_PWRM_GEN_PMCON_A                              0x1020
> +#define B_PMC_PWRM_GEN_PMCON_A_DC_PP_DIS                    BIT30
> +#define B_PMC_PWRM_GEN_PMCON_A_DSX_PP_DIS                   BIT29
> +#define B_PMC_PWRM_GEN_PMCON_A_AG3_PP_EN                    BIT28
> +#define B_PMC_PWRM_GEN_PMCON_A_SX_PP_EN                     BIT27
> +#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_ICLK_PLL               BIT26
> +#define B_PMC_PWRM_GEN_PMCON_A_MPHY_CRICLK_GATE_OVR
> BIT25
> +#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_OPI_PLL_SD_INC0
> BIT22
> +#define B_PMC_PWRM_GEN_PMCON_A_MEM_SR                       BIT21
> +#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_SPXB_CG_INC0
> BIT20
> +#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_ALLOW_L1LOW_OPI_ON
> BIT17
> +#define B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR                  BIT16
> +#define B_PMC_PWRM_GEN_PMCON_A_PME_B0_S5_DIS                BIT15
> +#define B_PMC_PWRM_GEN_PMCON_A_PWR_FLR                      BIT14
> +#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_L1LOW_BCLKREQ_ON
> BIT13
> +#define B_PMC_PWRM_GEN_PMCON_A_DISABLE_SX_STRETCH
> BIT12
> +#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_SLP_S4_ASE                   BIT3
> +#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_WOL_EN_OVRD                  BIT13
> +#define B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN              BIT10
> +#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 B_PMC_PWRM_CRID_RID_SEL                             (BIT0 | BIT1)
> ///< RID Select
> +#define V_PMC_PWRM_CRID_RID_SEL_REVISIONID                  0
> +#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          ///<
> this is PWRM register
> +#define B_PMC_PWRM_ETR3_CF9LOCK                             BIT31
> ///< CF9h Lockdown
> +#define B_PMC_PWRM_ETR3_LATCH_EVENTS_C10_EXIT               BIT30
> +#define B_PMC_PWRM_ETR3_USB_CACHE_DIS                       BIT21
> +#define B_PMC_PWRM_ETR3_CF9GR                               BIT20
> ///< CF9h Global Reset
> +#define B_PMC_PWRM_ETR3_SKIP_HOST_RST_HS                    BIT19
> +#define B_PMC_PWRM_ETR3_CWORWRE                             BIT18
> +#define B_PMC_PWRM_THROT_1_VR_ALERT                         BIT0
> +
> +#define R_PMC_PWRM_SSML                                     0x104C           ///<
> Set Strap Msg Lock
> +#define B_PMC_PWRM_SSML_SSL                                 BIT0             ///<
> Set_Strap Lock
> +#define R_PMC_PWRM_SSMC                                     0x1050           ///<
> Set Strap Msg Control
> +#define B_PMC_PWRM_SSMC_SSMS                                BIT0
> ///< Set_Strap Mux Select
> +#define R_PMC_PWRM_SSMD                                     0x1054           ///<
> Set Strap Msg Data
> +
> +#define R_PMC_PWRM_MODPHY_PM_CFG5                           0x10D0
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2
> BIT26
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_DMI
> BIT25
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E3
> BIT24
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E2
> BIT23
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E1
> BIT22
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_E0
> BIT21
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D3
> BIT20
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D2
> BIT19
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D1
> BIT18
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0
> BIT17
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS
> BIT16    ///< UFS ModPHY SPD RT Request
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI
> BIT15    ///< xDCI ModPHY SPD RT Request
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI
> BIT14    ///< xHCI ModPHY SPD RT Request
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE
> BIT13    ///< GbE ModPHY SPD RT Request
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA
> BIT12    ///< SATA ModPHY SPD RT Request
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C3
> BIT11
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C2
> BIT10
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C1              BIT9
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_C0              BIT8
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B3              BIT7
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B2              BIT6
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B1              BIT5
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_B0              BIT4
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A3              BIT3
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A2              BIT2
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A1              BIT1
> +#define B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0              BIT0
> +#define R_PMC_PWRM_WADT_AC                                  0x1800
> +#define R_PMC_PWRM_PRSTS                                    0x1810
> ///< Power and Reset Status
> +#define B_PMC_PWRM_PRSTS_VE_WD_TMR_STS                      BIT7
> ///< VE Watchdog Timer Status
> +#define B_PMC_PWRM_PRSTS_WOL_OVR_WK_STS                     BIT5
> +#define B_PMC_PWRM_PRSTS_FIELD_1                            BIT4
> +#define B_PMC_PWRM_PRSTS_ME_WAKE_STS                        BIT0
> +
> +#define R_PMC_PWRM_1814                                     0x1814
> +#define R_PMC_PWRM_CFG                                      0x1818
> ///< Power Management Configuration
> +#define B_PMC_PWRM_CFG_ALLOW_24_OSC_SD                      BIT29
> ///< Allow 24MHz Crystal Oscillator Shutdown
> +#define B_PMC_PWRM_CFG_DBG_MODE_LOCK                        BIT27
> ///< Debug Mode Lock
> +#define B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG                   BIT25
> ///< Allow USB2 Core Power Gating
> +#define B_PMC_PWRM_CFG_ER_LOCK                              BIT24
> ///< Energy Reporting Lock
> +#define B_PMC_PWRM_CFG_EN_PMC_UNC_ERR                       BIT23
> ///< Enable Global Reset on Uncorrectable Parity Error on PMC SRAM Interface
> +#define B_PMC_PWRM_CFG_PMCREAD_DISABLE                      BIT22
> ///< Disable Reads to PMC
> +#define B_PMC_PWRM_CFG_RTC_DS_WAKE_DIS                      BIT21
> ///< RTC Wake from Deep S4/S5 Disable
> +#define B_PMC_PWRM_CFG_SSMAW_MASK                           (BIT19 |
> BIT18)             ///< SLP_SUS# Min Assertion Width
> +#define V_PMC_PWRM_CFG_SSMAW_4S                             (BIT19 | BIT18)
> ///< 4 seconds
> +#define V_PMC_PWRM_CFG_SSMAW_1S                             BIT19
> ///< 1 second
> +#define V_PMC_PWRM_CFG_SSMAW_0_5S                           BIT18
> ///< 0.5 second (500ms)
> +#define V_PMC_PWRM_CFG_SSMAW_0S                             0
> ///< 0 second
> +#define B_PMC_PWRM_CFG_SAMAW_MASK                           (BIT17 |
> BIT16)             ///< SLP_A# Min Assertion Width
> +#define V_PMC_PWRM_CFG_SAMAW_2S                             (BIT17 | BIT16)
> ///< 2 seconds
> +#define V_PMC_PWRM_CFG_SAMAW_98ms                           BIT17
> ///< 98ms
> +#define V_PMC_PWRM_CFG_SAMAW_4S                             BIT16
> ///< 4 seconds
> +#define V_PMC_PWRM_CFG_SAMAW_0S                             0
> ///< 0 second
> +#define B_PMC_PWRM_CFG_RPCD_MASK                            (BIT9 | BIT8)
> ///< Reset Power Cycle Duration
> +#define V_PMC_PWRM_CFG_RPCD_1S                              (BIT9 | BIT8)
> ///< 1-2 seconds
> +#define V_PMC_PWRM_CFG_RPCD_2S                              BIT9
> ///< 2-3 seconds
> +#define V_PMC_PWRM_CFG_RPCD_3S                              BIT8
> ///< 3-4 seconds
> +#define V_PMC_PWRM_CFG_RPCD_4S                              0
> ///< 4-5 seconds (Default)
> +#define B_PMC_PWRM_CFG_COCS                                 BIT5
> ///< CPU OC Strap
> +#define B_PMC_PWRM_CFG_ER_EN                                BIT2
> ///< Energy Reporting Enable
> +#define B_PMC_PWRM_CFG_TIMING_TPCH25                        (BIT1 | BIT0)
> ///< tPCH25 timing
> +
> +#define R_PMC_PWRM_S3_PWRGATE_POL                           0x1828
> ///< S3 Power Gating Policies
> +#define B_PMC_PWRM_S3_PWRGATE_POL_S3DC_GATE_SUS             BIT1
> ///< Deep S3 Enable in DC Mode
> +#define B_PMC_PWRM_S3_PWRGATE_POL_S3AC_GATE_SUS             BIT0
> ///< Deep S3 Enable in AC Mode
> +
> +#define R_PMC_PWRM_S4_PWRGATE_POL                           0x182C
> ///< Deep S4 Power Policies
> +#define B_PMC_PWRM_S4_PWRGATE_POL_S4DC_GATE_SUS             BIT1
> ///< Deep S4 Enable in DC Mode
> +#define B_PMC_PWRM_S4_PWRGATE_POL_S4AC_GATE_SUS             BIT0
> ///< Deep S4 Enable in AC Mode
> +
> +#define R_PMC_PWRM_S5_PWRGATE_POL                           0x1830
> ///< Deep S5 Power Policies
> +#define B_PMC_PWRM_S5_PWRGATE_POL_S5DC_GATE_SUS             BIT15
> ///< Deep S5 Enable in DC Mode
> +#define B_PMC_PWRM_S5_PWRGATE_POL_S5AC_GATE_SUS             BIT14
> ///< Deep S5 Enable in AC Mode
> +
> +#define R_PMC_PWRM_DSX_CFG                                  0x1834
> ///< Deep SX Configuration
> +#define B_PMC_PWRM_DSX_CFG_WAKE_PIN_DSX_EN                  BIT2
> ///< WAKE# Pin DeepSx Enable
> +#define B_PMC_PWRM_DSX_CFG_ACPRES_PD_DSX_DIS                BIT1
> ///< AC_PRESENT pin pulldown in DeepSx disable
> +#define B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN                      BIT0
> ///< LAN_WAKE Pin DeepSx Enable
> +
> +#define R_PMC_PWRM_CFG2                                     0x183C
> ///< Power Management Configuration Reg 2
> +#define B_PMC_PWRM_CFG2_PBOP                                (BIT31 | BIT30 |
> BIT29)     ///< Power Button Override Period (PBOP)
> +#define N_PMC_PWRM_CFG2_PBOP                                29
> ///< Power Button Override Period (PBOP)
> +#define B_PMC_PWRM_CFG2_PB_DIS                              BIT28
> ///< Power Button Native Mode Disable (PB_DIS)
> +#define B_PMC_PWRM_CFG2_EN_DBG_MSG                          BIT27
> ///< Enable PMC Debug Messages
> +#define B_PMC_PWRM_CFG2_DRAM_RESET_CTL                      BIT26
> ///< DRAM RESET# control
> +#define N_PMC_PWRM_CFG2_DRAM_RESET_CTL                      26
> +
> +#define R_PMC_PWRM_EN_SN_SLOW_RING                          0x1848
> ///< Enable Snoop Request to SLOW_RING
> +#define R_PMC_PWRM_EN_SN_SLOW_RING2                         0x184C
> ///< Enable Snoop Request to SLOW_RING 2nd Reg
> +#define R_PMC_PWRM_EN_SN_SA                                 0x1850
> ///< Enable Snoop Request to SA
> +#define R_PMC_PWRM_EN_SN_SA2                                0x1854
> ///< Enable Snoop Request to SA 2nd Reg
> +#define R_PMC_PWRM_EN_SN_SLOW_RING_CF                       0x1858
> ///< Enable Snoop Request to SLOW_RING_CF
> +#define R_PMC_PWRM_EN_NS_SA                                 0x1868
> ///< Enable Non-Snoop Request to SA
> +#define R_PMC_PWRM_EN_CW_SLOW_RING                          0x1880
> ///< Enable Clock Wake to SLOW_RING
> +#define R_PMC_PWRM_EN_CW_SLOW_RING2                         0x1884
> ///< Enable Clock Wake to SLOW_RING 2nd Reg
> +#define R_PMC_PWRM_EN_CW_SA                                 0x1888
> ///< Enable Clock Wake to SA
> +#define R_PMC_PWRM_EN_CW_SA2                                0x188C
> ///< Enable Clock Wake to SA 2nd Reg
> +#define R_PMC_PWRM_EN_CW_SLOW_RING_CF                       0x1898
> ///< Enable Clock Wake to SLOW_RING_CF
> +#define R_PMC_PWRM_EN_PA_SLOW_RING                          0x18A8
> ///< Enable Pegged Active to SLOW_RING
> +#define R_PMC_PWRM_EN_PA_SLOW_RING2                         0x18AC
> ///< Enable Pegged Active to SLOW_RING 2nd Reg
> +#define R_PMC_PWRM_EN_PA_SA                                 0x18B0
> ///< Enable Pegged Active to SA
> +#define R_PMC_PWRM_EN_PA_SA2                                0x18B4
> ///< Enable Pegged Active to SA 2nd Reg
> +#define R_PMC_PWRM_EN_MISC_EVENT                            0x18C0
> ///< Enable Misc PM_SYNC Events
> +#define R_PMC_PWRM_PMSYNC_TPR_CONFIG                        0x18C4
> +#define B_PMC_PWRM_PMSYNC_TPR_CONFIG_LOCK                   BIT31
> +#define B_PMC_PWRM_PMSYNC_PCH2CPU_TT_EN                     BIT26
> +#define B_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE                  (BIT25 |
> BIT24)
> +#define N_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE                  24
> +#define V_PMC_PWRM_PMSYNC_PCH2CPU_TT_STATE_1                1
> +#define B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK                      BIT15
> ///< PM_SYNC Configuration Lock
> +#define B_PMC_PWRM_PMSYNC_GPIO_D_SEL                        BIT11
> +#define B_PMC_PWRM_PMSYNC_GPIO_C_SEL                        BIT10
> +
> +#define R_PMC_PWRM_PM_SYNC_STATE_HYS                        0x18D0
> ///< PM_SYNC State Hysteresis
> +#define R_PMC_PWRM_PM_SYNC_MODE                             0x18D4
> ///< PM_SYNC Pin Mode
> +
> +#define R_PMC_PWRM_CFG3                                     0x18E0
> ///< Power Management Configuration Reg 3
> +#define B_PMC_PWRM_CFG3_HOST_WLAN_PP_EN                     BIT17
> ///< Host Wireless LAN Phy Power Enable
> +#define B_PMC_PWRM_CFG3_DSX_WLAN_PP_EN                      BIT16
> ///< Deep-Sx WLAN Phy Power Enable
> +
> +#define R_PMC_PWRM_PM_DOWN_PPB_CFG                          0x18E4
> ///< PM_DOWN PCH_POWER_BUDGET CONFIGURATION
> +
> +#define R_PMC_PWRM_CFG4                                     0x18E8
> ///< Power Management Configuration Reg 4
> +#define B_PMC_PWRM_CFG4_U2_PHY_PG_EN                        BIT30
> ///< USB2 PHY SUS Well Power Gating Enable
> +#define B_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR
> (0x000001FF)                ///< CPU I/O VR Ramp Duration, [8:0]
> +#define N_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR                   0
> +#define V_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR_70US              0x007
> +#define V_PMC_PWRM_CFG4_CPU_IOVR_RAMP_DUR_240US
> 0x018
> +
> +#define R_PMC_PWRM_CPU_EPOC                                 0x18EC
> +
> +#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_CS_SD_CTL1                               0x1BE8
> ///< Clock Source Shutdown Control Reg 1
> +#define B_PMC_PWRM_CS_SD_CTL1_CS5_CTL_CFG                   (BIT22 |
> BIT21 | BIT20)    ///< Clock Source 5 Control Configuration
> +#define N_PMC_PWRM_CS_SD_CTL1_CS5_CTL_CFG                   20
> +#define B_PMC_PWRM_CS_SD_CTL1_CS1_CTL_CFG                   (BIT2 | BIT1
> | BIT0)       ///< Clock Source 1 Control Configuration
> +#define N_PMC_PWRM_CS_SD_CTL1_CS1_CTL_CFG                   0
> +
> +#define R_PMC_PWRM_CS_SD_CTL2                               0x1BEC ///<
> Clock Source Shutdown Control Reg 2
> +
> +#define R_PMC_PWRM_HSWPGCR1                                 0x1DD0
> +#define B_PMC_PWRM_SW_PG_CTRL_LOCK                          BIT31
> +#define B_PMC_PWRM_NPK_VNN_SW_PG_CTRL                       BIT0
> +
> +#define R_PMC_PWRM_1E00                                     0x1E00
> +#define R_PMC_PWRM_1E04                                     0x1E04
> +
> +#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_CNVI_FDIS_PMC           BIT1
> ///< CNVi Function Disable (PMC Version) (CNVI_FDIS_PMC)
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK              BIT31
> ///< Static Function Disable Lock (ST_FDIS_LK)
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_CAM_FDIS_PMC            BIT6
> ///< Camera Function Disable (PMC Version) (CAM_FDIS_PMC)
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC            BIT5
> ///< SH Function Disable (PMC Version) (ISH_FDIS_PMC)
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC            BIT0
> ///< GBE Function Disable (PMC Version) (GBE_FDIS_PMC)
> +
> +#define R_PMC_PWRM_ST_PG_FDIS_PMC_2                         0x1E24 ///<
> Static Function Disable Control Register 2
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI2_FDIS_PMC
> BIT11 ///< SerialIo Controller GSPI Device 2 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI1_FDIS_PMC
> BIT10 ///< SerialIo Controller GSPI Device 1 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI0_FDIS_PMC
> BIT9  ///< SerialIo Controller GSPI Device 0 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART2_FDIS_PMC
> BIT8  ///< SerialIo Controller UART Device 2 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART1_FDIS_PMC
> BIT7  ///< SerialIo Controller UART Device 1 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART0_FDIS_PMC
> BIT6  ///< SerialIo Controller UART Device 0 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C5_FDIS_PMC
> BIT5  ///< SerialIo Controller I2C Device 5 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C4_FDIS_PMC
> BIT4  ///< SerialIo Controller I2C Device 4 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C3_FDIS_PMC
> BIT3  ///< SerialIo Controller I2C Device 3 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C2_FDIS_PMC
> BIT2  ///< SerialIo Controller I2C Device 2 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C1_FDIS_PMC
> BIT1  ///< SerialIo Controller I2C Device 1 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C0_FDIS_PMC
> BIT0  ///< SerialIo Controller I2C Device 0 Function Disable
> +#define B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO                0xFFF
> ///< SerialIo Devices Disable Mask
> +
> +#define R_PMC_PWRM_NST_PG_FDIS_1                            0x1E28
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F3_FDIS_PMC
> BIT31  ///< PCIe Controller F Port 3 Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F2_FDIS_PMC
> BIT30  ///< PCIe Controller F Port 2 Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F1_FDIS_PMC
> BIT29  ///< PCIe Controller F Port 1 Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC
> BIT28  ///< PCIe Controller F Port 0 Function Disable
> +#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC
> BIT29  ///< SD Card Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC
> BIT27  ///< SD Card Function Disable
> +#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC
> BIT28  ///< eMMC Function Disable
> +#define B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC        BIT27
> ///< UFS Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC              BIT26
> ///< XDCI Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_SMBUS_FDIS_PMC             BIT25
> ///< Smbus Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC              BIT23
> ///< ADSP Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC              BIT22
> ///< SATA Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E3_FDIS_PMC
> BIT21  ///< PCIe Controller E Port 3 Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E2_FDIS_PMC
> BIT20  ///< PCIe Controller E Port 2 Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E1_FDIS_PMC
> BIT19  ///< PCIe Controller E Port 1 Function Disable
> +#define B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_E0_FDIS_PMC
> BIT18  ///< PCIe Controller E Port 0 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D3_FDIS_PMC           BIT17
> ///< PCIe Controller D Port 3 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D2_FDIS_PMC           BIT16
> ///< PCIe Controller D Port 2 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D1_FDIS_PMC           BIT15
> ///< PCIe Controller D Port 1 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_D0_FDIS_PMC           BIT14
> ///< PCIe Controller D Port 0 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C3_FDIS_PMC           BIT13
> ///< PCIe Controller C Port 3 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C2_FDIS_PMC           BIT12
> ///< PCIe Controller C Port 2 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C1_FDIS_PMC           BIT11
> ///< PCIe Controller C Port 1 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_C0_FDIS_PMC           BIT10
> ///< PCIe Controller C Port 0 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B3_FDIS_PMC           BIT9
> ///< PCIe Controller B Port 3 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B2_FDIS_PMC           BIT8
> ///< PCIe Controller B Port 2 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B1_FDIS_PMC           BIT7
> ///< PCIe Controller B Port 1 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_B0_FDIS_PMC           BIT6
> ///< PCIe Controller B Port 0 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A3_FDIS_PMC           BIT5
> ///< PCIe Controller A Port 3 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A2_FDIS_PMC           BIT4
> ///< PCIe Controller A Port 2 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A1_FDIS_PMC           BIT3
> ///< PCIe Controller A Port 1 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC           BIT2
> ///< PCIe Controller A Port 0 Function Disable
> +#define B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC              BIT0
> ///< XHCI Function Disable
> +
> +#define R_PMC_PWRM_FUSE_DIS_RD_2                            0x1E44 ///<
> Fuse Disable Read 2 Register
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SPC_SS_DIS                 BIT25 ///<
> SPC Fuse Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SPB_SS_DIS                 BIT24 ///<
> SPB Fuse Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SPA_SS_DIS                 BIT23 ///<
> SPA Fuse Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_PSTH_FUSE_SS_DIS           BIT21
> ///< PSTH Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_DMI_FUSE_SS_DIS            BIT20
> ///< DMI Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS            BIT19
> ///< OTG Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_XHCI_SS_DIS                BIT18 ///<
> XHCI Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_FIA_FUSE_SS_DIS            BIT17
> ///< FIA Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_DSP_FUSE_SS_DIS            BIT16
> ///< DSP Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS           BIT15
> ///< SATA Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_ICC_FUSE_SS_DIS            BIT14
> ///< ICC Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_LPC_FUSE_SS_DIS            BIT13
> ///< LPC Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_RTC_FUSE_SS_DIS            BIT12
> ///< RTC Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_P2S_FUSE_SS_DIS            BIT11
> ///< P2S Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_TRSB_FUSE_SS_DIS           BIT10
> ///< TRSB Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SMB_FUSE_SS_DIS            BIT9
> ///< SMB Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_ITSS_FUSE_SS_DIS           BIT8
> ///< ITSS Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_UFSX2_FUSE_SS_DIS          BIT7
> ///< UFSX2 Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS       BIT6
> ///< SerialIo Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_EMMC_FUSE_SS_DIS           BIT5
> ///< EMMC Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_CNVI_FUSE_SS_DIS           BIT4
> ///< CNVi Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_P2D_FUSE_SS_DIS            BIT3
> ///< P2D Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_SDX_FUSE_SS_DIS            BIT2
> ///< SD Conroller Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS            BIT1
> ///< ISH Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS            BIT0
> ///< GBE Fuse or Soft Strap Disable
> +
> +#define R_PMC_PWRM_FUSE_DIS_RD_3                            0x1E48 ///<
> Static PG Fuse and Soft Strap Disable Read Register 3
> +#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA3_FUSE_SS_DIS         BIT3
> ///< PNCRA3 Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA2_FUSE_SS_DIS         BIT2
> ///< PNCRA2 Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA1_FUSE_SS_DIS         BIT1
> ///< PNCRA1 Fuse or Soft Strap Disable
> +#define B_PMC_PWRM_FUSE_DIS_RD_3_PNCRA_FUSE_SS_DIS          BIT0
> ///< PNCRA Fuse or Soft Strap Disable
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
> new file mode 100644
> index 0000000000..bd0c2574f2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
> @@ -0,0 +1,72 @@
> +/** @file
> +  Register names for PCH PMC device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_PMC_CNL_H_
> +#define _PCH_REGS_PMC_CNL_H_
> +
> +//
> +// PWRM Registers
> +//
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A
> 0x0
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B
> 0x1
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C
> 0xD
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D
> 0x4
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E
> 0xE
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F
> 0x5
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G
> 0x2
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H
> 0x6
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD                          0xA
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO
> 0x7
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI                          0x3
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA                          0xB
> +#define V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG                         0xF
> +
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A
> 0x0
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B
> 0x1
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C
> 0x2
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D
> 0x3
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E
> 0xA
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F
> 0xB
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G
> 0x4
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H
> 0x9
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I
> 0xC
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J
> 0xD
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K
> 0x8
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD                           0x7
> +#define V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO
> 0x5
> +
> +#endif // _PCH_REGS_PMC_CNL_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
> new file mode 100644
> index 0000000000..5c4d583904
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
> @@ -0,0 +1,104 @@
> +/** @file
> +  Register definition for PSF component
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_PSF_H_
> +#define _PCH_REGS_PSF_H_
> +
> +//
> +// Private chipset register (Memory space) offset definition
> +// The PCR register defines is used for PCR MMIO programming and PCH SBI
> programming as well.
> +//
> +
> +//
> +// PSFx segment registers
> +//
> +#define R_PCH_PSF_PCR_GLOBAL_CONFIG                     0x4000
> ///< PSF Segment Global Configuration Register
> +#define B_PCH_PSF_PCR_ROOTSPACE_CONFIG_RSX_ENADDRP2P    BIT1
> +#define B_PCH_PSF_PCR_ROOTSPACE_CONFIG_RSX_VTDEN        BIT0
> +
> +#define S_PCH_PSFX_PCR_DEV_GNTCNT_RELOAD_DGCR                4
> +#define S_PCH_PSFX_PCR_TARGET_GNTCNT_RELOAD                  4
> +#define
> B_PCH_PSFX_PCR_DEV_GNTCNT_RELOAD_DGCR_GNT_CNT_RELOAD 0x1F
> +#define B_PCH_PSFX_PCR_TARGET_GNTCNT_RELOAD_GNT_CNT_RELOAD
> 0x1F
> +
> +#define N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC          1
> +#define B_PCH_PSFX_PCR_MC_CONTROL_MCASTX_MULTCEN        BIT0
> +
> +//
> +// PSFx PCRs definitions
> +//
> +#define R_PCH_PSFX_PCR_T0_SHDW_BAR0                     0
> ///< PCI BAR0
> +#define R_PCH_PSFX_PCR_T0_SHDW_BAR1                     0x04
> ///< PCI BAR1
> +#define R_PCH_PSFX_PCR_T0_SHDW_BAR2                     0x08
> ///< PCI BAR2
> +#define R_PCH_PSFX_PCR_T0_SHDW_BAR3                     0x0C
> ///< PCI BAR3
> +#define R_PCH_PSFX_PCR_T0_SHDW_BAR4                     0x10
> ///< PCI BAR4
> +#define R_PCH_PSFX_PCR_T0_SHDW_PCIEN                    0x1C
> ///< PCI configuration space enable bits
> +#define N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS            16
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR0DIS            BIT16
> ///< Disable BAR0
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR1DIS            BIT17
> ///< Disable BAR1
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR2DIS            BIT18
> ///< Disable BAR2
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR3DIS            BIT19
> ///< Disable BAR3
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR4DIS            BIT20
> ///< Disable BAR4
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_BAR5DIS            BIT21
> ///< Disable BAR5
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS             BIT8
> ///< Function disable
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_MEMEN              BIT1
> ///< Memory decoding enable
> +#define B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN               BIT0
> ///< IO decoding enable
> +#define R_PCH_PSFX_PCR_T0_SHDW_PMCSR                    0x20
> ///< PCI power management configuration
> +#define B_PCH_PSFX_PCR_T0_SHDW_PMCSR_PWRST              (BIT1 | BIT0)
> ///< Power status
> +#define R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS                  0x38
> ///< PCI configuration disable
> +#define B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS           BIT0
> ///< config disable
> +
> +#define R_PCH_PSFX_PCR_T1_SHDW_PCIEN                    0x3C
> ///< PCI configuration space enable bits
> +#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_FUNDIS             BIT8
> ///< Function disable
> +#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_MEMEN              BIT1
> ///< Memory decoding enable
> +#define B_PCH_PSFX_PCR_T1_SHDW_PCIEN_IOEN               BIT0
> ///< IO decoding enable
> +
> +#define B_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_DEVICE    0x01F0
> ///< device number
> +#define N_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_DEVICE    4
> +#define B_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_FUNCTION  (BIT3
> | BIT2 | BIT1)   ///< function number
> +#define N_PCH_PSFX_PCR_TX_AGENT_FUNCTION_CONFIG_FUNCTION  1
> +
> +#define B_PCH_PSFX_PCR_TARGET_CHANNELID                 0xFF
> +#define B_PCH_PSFX_PCR_TARGET_PORTID                    0x7F00
> +#define N_PCH_PSFX_PCR_TARGET_PORTID                    8
> +#define B_PCH_PSFX_PCR_TARGET_PORTGROUPID               BIT15
> +#define N_PCH_PSFX_PCR_TARGET_PORTGROUPID               15
> +#define B_PCH_PSFX_PCR_TARGET_PSFID                     0xFF0000
> +#define N_PCH_PSFX_PCR_TARGET_PSFID                     16
> +#define B_PCH_PSFX_PCR_TARGET_CHANMAP                   BIT31
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
> new file mode 100644
> index 0000000000..9a5e536f18
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
> @@ -0,0 +1,113 @@
> +/** @file
> +  Register definition for PSF component
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_PSF_CNL_H_
> +#define _PCH_REGS_PSF_CNL_H_
> +
> +//PSF 1 Multicast Message Configuration
> +#define R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI
> 0x404C      ///< Multicast Control Register
> +#define R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI
> 0x4064      ///< Destination ID
> +#define R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI
> 0x403C      ///< Multicast Control Register
> +#define R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI
> 0x4054      ///< Destination ID
> +
> +//
> +// PSF3 PCRs (PID:PSF3)
> +//
> +// PSF3 PCH-LP Specific Base Address
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE         0x0100
> ///< D18F6 PSF base address (SerialIo: SPI2)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_ISH_REG_BASE          0x0200
> ///< D19F0 PSF base address (ISH)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_CNVI_REG_BASE
> 0x0400                  ///< D20F3 PSF base address (CNVi)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SDCARD_REG_BASE
> 0x0500                  ///< D20F5 PSF base address (SCC: SDCard)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE         0x0600
> ///< D21F0 PSF base address (SerialIo: I2C0)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE         0x0700
> ///< D21F1 PSF base address (SerialIo: I2C1)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE         0x0800
> ///< D21F2 PSF base address (SerialIo: I2C2)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE         0x0900
> ///< D21F3 PSF base address (SerialIo: I2C3)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE         0x0A00
> ///< D25F0 PSF base address (SerialIo: I2C4)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE         0x0B00
> ///< D25F1 PSF base address (SerialIo: I2C5)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE
> 0x0C00                  ///< D25F2 PSF base address (SerialIo: UART2)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE
> 0x0D00                  ///< D30F0 PSF base address (SerialIo: UART0)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE
> 0x0E00                  ///< D30F1 PSF base address (SerialIo: UART1)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE         0x0F00
> ///< D30F2 PSF base address (SerialIo: SPI0)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE         0x1000
> ///< D30F3 PSF base address (SerialIo: SPI1)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_LPC_REG_BASE          0x1100
> ///< D31F0 PSF base address (LPC)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_P2SB_REG_BASE
> 0x1300                  ///< D31F1 PSF base address (P2SB)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE
> 0x1400                  ///< D31F2 PSF base address (PMC)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_AUD_REG_BASE
> 0x1500                  ///< D31F3 PSF base address (HDA, ADSP)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SMBUS_REG_BASE
> 0x1600                  ///< D31F4 PSF base address (SMBUS)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI_SPI_REG_BASE
> 0x1700                  ///< D31F5 PSF base address (SPI SPI)
> +#define R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_GBE_REG_BASE
> 0x1800                  ///< D31F6 PSF base address (GBE)
> +// PSF3 PCH-H Specific Base Address
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE          0x0100
> ///< D18F6 PSF base address (SerialIo: SPI2)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_ISH_REG_BASE           0x0180
> ///< D19F0 PSF base address (ISH)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_CNVI_REG_BASE
> 0x0280                  ///< D20F3 PSF base address (CNVi)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SDCARD_REG_BASE
> 0x0300                  ///< D20F5 PSF base address (SCC: SDCard)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE          0x0380
> ///< D21F0 PSF base address (SerialIo: I2C0)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE          0x0400
> ///< D21F1 PSF base address (SerialIo: I2C1)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE          0x0480
> ///< D21F2 PSF base address (SerialIo: I2C2)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE          0x0500
> ///< D21F3 PSF base address (SerialIo: I2C3)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE
> 0x0580                  ///< D25F2 PSF base address (SerialIo: UART2)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE
> 0x0600                  ///< D30F0 PSF base address (SerialIo: UART0)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE
> 0x0680                  ///< D30F1 PSF base address (SerialIo: UART1)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE          0x0700
> ///< D30F2 PSF base address (SerialIo: SPI0)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE          0x0780
> ///< D30F3 PSF base address (SerialIo: SPI1)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_LPC_REG_BASE           0x0800
> ///< D31F0 PSF base address (LPC)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_P2SB_REG_BASE
> 0x0900                  ///< D31F1 PSF base address (P2SB)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE
> 0x0980                  ///< D31F2 PSF base address (PMC)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_AUD_REG_BASE
> 0x0A00                  ///< D31F3 PSF base address (HDA, ADSP)H
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SMBUS_REG_BASE
> 0x0A80                  ///< D31F4 PSF base address (SMBUS)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI_SPI_REG_BASE
> 0x0B00                  ///< D31F5 PSF base address (SPI SPI)
> +#define R_CNL_PCH_H_PSF3_PCR_T0_SHDW_GBE_REG_BASE
> 0x0B80                  ///< D31F6 PSF base address (GBE)
> +
> +// Other PSF3 PCRs definition
> +#define R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI
> 0x4058                  ///< Multicast Control Register  // LP&H
> +#define R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI
> 0x4064                  ///< Destination ID  // LP&H
> +
> +#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI
> 0x4030          ///< Multicast Control Register
> +#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI
> 0x4048          ///< Destination ID
> +#define R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1
> 0x403C          ///< Multicast Control Register
> +#define
> R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1
> 0x4070          ///< Destination ID
> +
> +#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI
> 0x4030          ///< Multicast Control Register
> +#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI
> 0x4048          ///< Destination ID
> +#define R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1
> 0x403C          ///< Multicast Control Register
> +#define
> R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1
> 0x4070          ///< Destination ID
> +
> +#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI
> 0x4030          ///< Multicast Control Register
> +#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI
> 0x4048          ///< Destination ID
> +#define R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST1_RS0_MCTP1
> 0x403C          ///< Multicast Control Register
> +#define
> R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST1_RS0_TGT0_MCTP1
> 0x4070          ///< Destination ID
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
> new file mode 100644
> index 0000000000..d6030ed10d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
> @@ -0,0 +1,77 @@
> +/** @file
> +  Register definition for PSTH component
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 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 register (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 B_PSTH_PCR_PSTHIOSFSTCGE    BIT1                  ///< PSTH IOSF
> sideband trunk clock gating enable
> +#define B_PSTH_PCR_PSTHDCGE         BIT0                  ///< PSTH dynamic
> clock gating enable
> +#define R_PSTH_PCR_TRPST            0x1E00                ///< Trap status
> register
> +#define B_PSTH_PCR_TRPST_CTSS       0x0000000F            ///< Cycle Trap
> SMI# Status mask
> +#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 B_PSTH_PCR_TRPD_IOD         0x00000000FFFFFFFF    ///< Trap cycle
> I/O 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 B_PSTH_PCR_TRPREG_BEM       0x000000F000000000    ///< Byte
> enable mask
> +#define N_PSTH_PCR_TRPREG_BE        32
> +#define B_PSTH_PCR_TRPREG_BE        0x0000000F00000000    ///< Byte
> enable
> +#define B_PSTH_PCR_TRPREG_AM        0x0000000000FC0000    ///< IO
> Address mask
> +#define B_PSTH_PCR_TRPREG_AD        0x000000000000FFFC    ///< IO
> Address
> +#define B_PSTH_PCR_TRPREG_TSE       BIT0                  ///< Trap and SMI#
> Enable
> +
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
> new file mode 100644
> index 0000000000..d98ce39df6
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
> @@ -0,0 +1,668 @@
> +/** @file
> +  Register names for PCH SATA controllers
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_SATA_H_
> +#define _PCH_REGS_SATA_H_
> +
> +//
> +//  SATA Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SATA          23
> +#define PCI_FUNCTION_NUMBER_PCH_SATA        0
> +
> +#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_1    7
> +#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1  0
> +
> +#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_2    8
> +#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2  0
> +
> +#define PCI_DEVICE_NUMBER_CDF_PCH_SATA_3    14
> +#define PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3  0
> +
> +//
> +//  PCH-LP SATA Device ID's
> +//
> +#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_AHCI         0x9DD3  ///<
> SATA Controller (AHCI) - Mobile
> +#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID         0x9DD5  ///<
> SATA Controller (RAID 0/1/5/10) - NOT premium - Mobile
> +#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_PREM    0x9DD7
> ///< SATA Controller (RAID 0/1/5/10) - premium - Mobile
> +#define V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_IBC     0x282A  ///<
> SATA Controller (RAID 0/1/5/10) - In-box compatible - Mobile
> +
> +//
> +//  PCH-H SATA Device ID's
> +//
> +#define V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_ALTDIS   0x2822  ///<
> SATA Controller (RAID 0/1/5/10) - premium - Alternate ID
> +#define V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_RSTE     0x2826  ///< SATA
> Controller (RAID 0/1/5/10) - RSTe of Server SKU
> +
> +//
> +//  PCH-H SATA Device ID's
> +//
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_AHCI         0xA352  ///<
> SATA Controller (AHCI) Desktop/Server
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_AHCI        0xA353  ///<
> SATA Controller (AHCI) Mobile Halo
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID         0xA354  ///<
> SATA Controller (RAID 0/1/5/10) - NOT premium Desktop/Server
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID        0xA355  ///<
> SATA Controller (RAID 0/1/5/10) - NOT premium Mobile Halo
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_PREM    0xA356
> ///< SATA Controller (RAID 0/1/5/10) - premium Desktop/Server
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID_PREM   0xA357
> ///< SATA Controller (RAID 0/1/5/10) - premium Mobile Halo
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_OP_AHCI      0xA35E  ///<
> SATA Controller (AHCI) Optane Caching - Desktop
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC     0x2822  ///<
> SATA Controller (RAID 0/1/5/10) - In-box compatible
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_RST 0x2826  ///<
> SATA Controller (RAID 0/1/5/10) - In-box compatible (RSTe)
> +#define V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_2   0x282A  ///<
> SATA Controller (RAID 0/1/5/10) - In-box compatible (Alternate)
> +
> +
> +//
> +//  SATA Controller common Registers
> +//
> +#define V_SATA_CFG_SUB_CLASS_CODE_AHCI      0x06
> +#define V_SATA_CFG_SUB_CLASS_CODE_RAID      0x04
> +#define R_SATA_CFG_AHCI_BAR                 0x24
> +#define B_SATA_CFG_AHCI_BAR_BA              0xFFFFF800
> +#define V_SATA_CFG_AHCI_BAR_LENGTH          0x800
> +#define N_SATA_CFG_AHCI_BAR_ALIGNMENT       11
> +#define V_SATA_CFG_AHCI_BAR_LENGTH_512K     0x80000
> +#define N_SATA_CFG_AHCI_BAR_ALIGNMENT_512K  19
> +#define B_SATA_CFG_AHCI_BAR_PF              BIT3
> +#define B_SATA_CFG_AHCI_BAR_TP              (BIT2 | BIT1)
> +#define B_SATA_CFG_AHCI_BAR_RTE             BIT0
> +#define R_SATA_CFG_PID                      0x70
> +#define B_SATA_CFG_PID_NEXT                 0xFF00
> +#define V_SATA_CFG_PID_NEXT_0               0xB000
> +#define V_SATA_CFG_PID_NEXT_1               0xA800
> +#define B_SATA_CFG_PID_CID                  0x00FF
> +#define R_SATA_CFG_PC                       0x72
> +#define S_SATA_CFG_PC                       2
> +#define B_SATA_CFG_PC_PME                   (BIT15 | BIT14 | BIT13 | BIT12 |
> BIT11)
> +#define V_SATA_CFG_PC_PME_0                 0x0000
> +#define V_SATA_CFG_PC_PME_1                 0x4000
> +#define B_SATA_CFG_PC_D2_SUP                BIT10
> +#define B_SATA_CFG_PC_D1_SUP                BIT9
> +#define B_SATA_CFG_PC_AUX_CUR               (BIT8 | BIT7 | BIT6)
> +#define B_SATA_CFG_PC_DSI                   BIT5
> +#define B_SATA_CFG_PC_PME_CLK               BIT3
> +#define B_SATA_CFG_PC_VER                   (BIT2 | BIT1 | BIT0)
> +#define R_SATA_CFG_PMCS                     0x74
> +#define B_SATA_CFG_PMCS_PMES                BIT15
> +#define B_SATA_CFG_PMCS_PMEE                BIT8
> +#define B_SATA_CFG_PMCS_NSFRST              BIT3
> +#define V_SATA_CFG_PMCS_NSFRST_1            0x01
> +#define V_SATA_CFG_PMCS_NSFRST_0            0x00
> +#define B_SATA_CFG_PMCS_PS                  (BIT1 | BIT0)
> +#define V_SATA_CFG_PMCS_PS_3                0x03
> +#define V_SATA_CFG_PMCS_PS_0                0x00
> +#define R_SATA_CFG_MID                      0x80
> +#define B_SATA_CFG_MID_NEXT                 0xFF00
> +#define B_SATA_CFG_MID_CID                  0x00FF
> +#define R_SATA_CFG_MC                       0x82
> +#define B_SATA_CFG_MC_C64                   BIT7
> +#define B_SATA_CFG_MC_MME                   (BIT6 | BIT5 | BIT4)
> +#define V_SATA_CFG_MC_MME_4                 0x04
> +#define V_SATA_CFG_MC_MME_2                 0x02
> +#define V_SATA_CFG_MC_MME_1                 0x01
> +#define V_SATA_CFG_MC_MME_0                 0x00
> +#define B_SATA_CFG_MC_MMC                   (BIT3 | BIT2 | BIT1)
> +#define V_SATA_CFG_MC_MMC_4                 0x04
> +#define V_SATA_CFG_MC_MMC_0                 0x00
> +#define B_SATA_CFG_MC_MSIE                  BIT0
> +#define V_SATA_CFG_MC_MSIE_1                0x01
> +#define V_SATA_CFG_MC_MSIE_0                0x00
> +#define R_SATA_CFG_MA                       0x84
> +#define B_SATA_CFG_MA                       0xFFFFFFFC
> +#define R_SATA_CFG_MD                       0x88
> +#define B_SATA_CFG_MD_MSIMD                 0xFFFF
> +
> +#define R_SATA_CFG_MAP                      0x90
> +#define B_SATA_CFG_MAP_PCD                  0xFF
> +#define N_SATA_CFG_MAP_SPD                  16
> +#define B_SATA_CFG_MAP_SPD7                 BIT23
> +#define B_SATA_CFG_MAP_SPD6                 BIT22
> +#define B_SATA_CFG_MAP_SPD5                 BIT21
> +#define B_SATA_CFG_MAP_SPD4                 BIT20
> +#define B_SATA_CFG_MAP_SPD3                 BIT19
> +#define B_SATA_CFG_MAP_SPD2                 BIT18
> +#define B_SATA_CFG_MAP_SPD1                 BIT17
> +#define B_SATA_CFG_MAP_SPD0                 BIT16
> +#define B_SATA_CFG_MAP_PORT7_PCD            BIT7
> +#define B_SATA_CFG_MAP_PORT6_PCD            BIT6
> +#define B_SATA_CFG_MAP_PORT5_PCD            BIT5
> +#define B_SATA_CFG_MAP_PORT4_PCD            BIT4
> +#define B_SATA_CFG_MAP_PORT3_PCD            BIT3
> +#define B_SATA_CFG_MAP_PORT2_PCD            BIT2
> +#define B_SATA_CFG_MAP_PORT1_PCD            BIT1
> +#define B_SATA_CFG_MAP_PORT0_PCD            BIT0
> +#define R_SATA_CFG_PCS                      0x94
> +#define B_SATA_CFG_PCS_P7P                  BIT23
> +#define B_SATA_CFG_PCS_P6P                  BIT22
> +#define B_SATA_CFG_PCS_P5P                  BIT21
> +#define B_SATA_CFG_PCS_P4P                  BIT20
> +#define B_SATA_CFG_PCS_P3P                  BIT19
> +#define B_SATA_CFG_PCS_P2P                  BIT18
> +#define B_SATA_CFG_PCS_P1P                  BIT17
> +#define B_SATA_CFG_PCS_P0P                  BIT16
> +#define B_SATA_CFG_PCS_P7E                  BIT7
> +#define B_SATA_CFG_PCS_P6E                  BIT6
> +#define B_SATA_CFG_PCS_P5E                  BIT5
> +#define B_SATA_CFG_PCS_P4E                  BIT4
> +#define B_SATA_CFG_PCS_P3E                  BIT3
> +#define B_SATA_CFG_PCS_P2E                  BIT2
> +#define B_SATA_CFG_PCS_P1E                  BIT1
> +#define B_SATA_CFG_PCS_P0E                  BIT0
> +#define R_SATA_CFG_SATAGC                   0x9C
> +#define B_SATA_CFG_SATAGC_SMS_MASK          BIT16
> +#define N_SATA_CFG_SATAGC_SMS_MASK          16
> +#define V_SATA_CFG_SATAGC_SMS_AHCI          0x0
> +#define V_SATA_CFG_SATAGC_SMS_RAID          0x1
> +#define B_SATA_CFG_SATAGC_AIE               BIT7
> +#define B_SATA_CFG_SATAGC_AIES              BIT6
> +#define B_SATA_CFG_SATAGC_MSS               (BIT4 | BIT3)
> +#define V_SATA_CFG_SATAGC_MSS_8K            0x2
> +#define N_SATA_CFG_SATAGC_MSS               3
> +#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
> +
> +#define R_SATA_CFG_SIRI                     0xA0
> +#define R_SATA_CFG_STRD                     0xA4
> +#define R_SATA_CFG_SIR_0C                   0x0C
> +#define R_SATA_CFG_SIR_50                   0x50
> +#define R_SATA_CFG_SIR_54                   0x54
> +#define R_SATA_CFG_SIR_58                   0x58
> +#define R_SATA_CFG_SIR_5C                   0x5C
> +#define R_SATA_CFG_SIR_60                   0x60
> +#define R_SATA_CFG_SIR_64                   0x64
> +#define R_SATA_CFG_SIR_68                   0x68
> +#define R_SATA_CFG_SIR_6C                   0x6C
> +#define R_SATA_CFG_SIR_70                   0x70
> +#define R_SATA_CFG_SIR_80                   0x80
> +#define R_SATA_CFG_SIR_84                   0x84
> +#define R_SATA_CFG_SIR_8C                   0x8C
> +#define R_SATA_CFG_SIR_90                   0x90
> +#define R_SATA_CFG_SIR_98                   0x98
> +#define R_SATA_CFG_SIR_9C                   0x9C
> +#define R_SATA_CFG_SIR_A0                   0xA0
> +#define R_SATA_CFG_SIR_A4                   0xA4
> +#define R_SATA_CFG_SIR_A8                   0xA8
> +#define R_SATA_CFG_SIR_C8                   0xC8
> +#define R_SATA_CFG_SIR_CC                   0xCC
> +#define R_SATA_CFG_SIR_D0                   0xD0
> +#define R_SATA_CFG_SIR_D4                   0xD4
> +#define B_SATA_CFG_STRD_DTA                 0xFFFFFFFF
> +#define R_SATA_CFG_CR0                      0xA8
> +#define B_SATA_CFG_CR0_MAJREV               0x00F00000
> +#define B_SATA_CFG_CR0_MINREV               0x000F0000
> +#define B_SATA_CFG_CR0_NEXT                 0x0000FF00
> +#define B_SATA_CFG_CR0_CAP                  0x000000FF
> +#define R_SATA_CFG_CR1                      0xAC
> +#define B_SATA_CFG_CR1_BAROFST              0xFFF0
> +#define B_SATA_CFG_CR1_BARLOC               0x000F
> +#define R_SATA_CFG_FLR_CID                  0xB0
> +#define B_SATA_CFG_FLR_CID_NEXT             0xFF00
> +#define B_SATA_CFG_FLR_CID                  0x00FF
> +#define V_SATA_CFG_FLR_CID_1                0x0009
> +#define V_SATA_CFG_FLR_CID_0                0x0013
> +#define R_SATA_CFG_FLR_CLV                  0xB2
> +#define B_SATA_CFG_FLR_CLV_FLRC_FLRCSSEL_0  BIT9
> +#define B_SATA_CFG_FLR_CLV_TXPC_FLRCSSEL_0  BIT8
> +#define B_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL_0 0x00FF
> +#define B_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL_1 0x00FF
> +#define V_SATA_CFG_FLR_CLV_VSCID_FLRCSSEL   0x0006
> +#define R_SATA_CFG_FLRC                     0xB4
> +#define B_SATA_CFG_FLRC_TXP                 BIT8
> +#define B_SATA_CFG_FLRC_INITFLR             BIT0
> +#define R_SATA_CFG_SP                       0xC0
> +#define B_SATA_CFG_SP                       0xFFFFFFFF
> +#define R_SATA_CFG_MXID                     0xD0
> +#define N_SATA_CFG_MXID_NEXT                8
> +
> +#define R_SATA_CFG_BFCS                     0xE0
> +#define B_SATA_CFG_BFCS_P7BFI               BIT17
> +#define B_SATA_CFG_BFCS_P6BFI               BIT16
> +#define B_SATA_CFG_BFCS_P5BFI               BIT15
> +#define B_SATA_CFG_BFCS_P4BFI               BIT14
> +#define B_SATA_CFG_BFCS_P3BFI               BIT13
> +#define B_SATA_CFG_BFCS_P2BFI               BIT12
> +#define B_SATA_CFG_BFCS_P2BFS               BIT11
> +#define B_SATA_CFG_BFCS_P2BFF               BIT10
> +#define B_SATA_CFG_BFCS_P1BFI               BIT9
> +#define B_SATA_CFG_BFCS_P0BFI               BIT8
> +#define B_SATA_CFG_BFCS_BIST_FIS_T          BIT7
> +#define B_SATA_CFG_BFCS_BIST_FIS_A          BIT6
> +#define B_SATA_CFG_BFCS_BIST_FIS_S          BIT5
> +#define B_SATA_CFG_BFCS_BIST_FIS_L          BIT4
> +#define B_SATA_CFG_BFCS_BIST_FIS_F          BIT3
> +#define B_SATA_CFG_BFCS_BIST_FIS_P          BIT2
> +#define R_SATA_CFG_BFTD1                    0xE4
> +#define B_SATA_CFG_BFTD1                    0xFFFFFFFF
> +#define R_SATA_CFG_BFTD2                    0xE8
> +#define B_SATA_CFG_BFTD2                    0xFFFFFFFF
> +
> +#define R_SATA_CFG_VS_CAP                   0xA4
> +#define B_SATA_CFG_VS_CAP_NRMBE             BIT0                            ///<
> NVM Remap Memory BAR Enable
> +#define B_SATA_CFG_VS_CAP_MSL               0x1FFE                          ///<
> Memory Space Limit
> +#define N_SATA_CFG_VS_CAP_MSL               1
> +#define V_SATA_CFG_VS_CAP_MSL               0x1EF                           ///<
> Memory Space Limit Field Value
> +#define B_SATA_CFG_VS_CAP_NRMO              0xFFF0000
> ///< NVM Remapped Memory Offset
> +#define N_SATA_CFG_VS_CAP_NRMO              16
> +#define V_SATA_CFG_VS_CAP_NRMO              0x10                            ///<
> NVM Remapped Memory Offset Field Value
> +
> +//
> +// RST PCIe Storage Remapping Registers
> +//
> +#define R_SATA_CFG_RST_PCIE_STORAGE_RCR                 0x800
> ///< Remap Capability Register
> +#define B_SATA_CFG_RST_PCIE_STORAGE_RCR_NRS
> (BIT2|BIT1|BIT0)                ///< Number of Remapping Supported
> +#define B_SATA_CFG_RST_PCIE_STORAGE_RCR_NRS_CR1         BIT0
> ///< Number of Remapping Supported (RST PCIe Storage Cycle Router #1)
> +#define R_SATA_CFG_RST_PCIE_STORAGE_SPR                 0x80C
> ///< Scratch Pad Register
> +#define R_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC             0x880
> ///< CR#1 Device Class Code
> +#define N_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_SCC         8
> +#define N_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_BCC         16
> +#define B_SATA_CFG_RST_PCIE_STORAGE_CR1_DCC_DT          BIT31
> ///< Device Type
> +#define V_SATA_CFG_RST_PCIE_STORAGE_REMAP_CONFIG_CR     0x80
> ///< Remapped Configuration for RST PCIe Storage Cycle Router #n
> +#define V_SATA_CFG_RST_PCIE_STORAGE_REMAP_RP_OFFSET     0x100
> ///< Remapped Root Port Offset Value
> +#define R_SATA_CFG_RST_PCIE_STORAGE_CCFG                0x1D0
> ///< Port Configuration Register
> +//
> +// AHCI BAR Area related Registers
> +//
> +#define R_SATA_MEM_AHCI_CAP                 0x0
> +#define B_SATA_MEM_AHCI_CAP_S64A            BIT31
> +#define B_SATA_MEM_AHCI_CAP_SCQA            BIT30
> +#define B_SATA_MEM_AHCI_CAP_SSNTF           BIT29
> +#define B_SATA_MEM_AHCI_CAP_SMPS            BIT28 ///< Supports
> Interlock Switch
> +#define B_SATA_MEM_AHCI_CAP_SSS             BIT27 ///< Supports Stagger
> Spin-up
> +#define B_SATA_MEM_AHCI_CAP_SALP            BIT26
> +#define B_SATA_MEM_AHCI_CAP_SAL             BIT25
> +#define B_SATA_MEM_AHCI_CAP_SCLO            BIT24 ///< Supports
> Command List Override
> +#define B_SATA_MEM_AHCI_CAP_ISS_MASK        (BIT23 | BIT22 | BIT21 |
> BIT20)
> +#define N_SATA_MEM_AHCI_CAP_ISS             20    ///< Interface Speed
> Support
> +#define V_SATA_MEM_AHCI_CAP_ISS_1_5_G       0x01
> +#define V_SATA_MEM_AHCI_CAP_ISS_3_0_G       0x02
> +#define V_SATA_MEM_AHCI_CAP_ISS_6_0_G       0x03
> +#define B_SATA_MEM_AHCI_CAP_SNZO            BIT19
> +#define B_SATA_MEM_AHCI_CAP_SAM             BIT18
> +#define B_SATA_MEM_AHCI_CAP_SPM             BIT17 ///< Supports Port
> Multiplier
> +#define B_SATA_MEM_AHCI_CAP_PMD             BIT15 ///< PIO Multiple DRQ
> Block
> +#define B_SATA_MEM_AHCI_CAP_SSC             BIT14
> +#define B_SATA_MEM_AHCI_CAP_PSC             BIT13
> +#define B_SATA_MEM_AHCI_CAP_NCS             0x1F00
> +#define B_SATA_MEM_AHCI_CAP_CCCS            BIT7
> +#define B_SATA_MEM_AHCI_CAP_EMS             BIT6
> +#define B_SATA_MEM_AHCI_CAP_SXS             BIT5  ///< External SATA is
> supported
> +#define B_SATA_MEM_AHCI_CAP_NPS             0x001F
> +
> +#define R_SATA_MEM_AHCI_GHC                 0x04
> +#define B_SATA_MEM_AHCI_GHC_AE              BIT31
> +#define B_SATA_MEM_AHCI_GHC_MRSM            BIT2
> +#define B_SATA_MEM_AHCI_GHC_IE              BIT1
> +#define B_SATA_MEM_AHCI_GHC_HR              BIT0
> +
> +#define R_SATA_MEM_AHCI_IS                  0x08
> +#define B_SATA_MEM_AHCI_IS_PORT7            BIT7
> +#define B_SATA_MEM_AHCI_IS_PORT6            BIT6
> +#define B_SATA_MEM_AHCI_IS_PORT5            BIT5
> +#define B_SATA_MEM_AHCI_IS_PORT4            BIT4
> +#define B_SATA_MEM_AHCI_IS_PORT3            BIT3
> +#define B_SATA_MEM_AHCI_IS_PORT2            BIT2
> +#define B_SATA_MEM_AHCI_IS_PORT1            BIT1
> +#define B_SATA_MEM_AHCI_IS_PORT0            BIT0
> +#define R_SATA_MEM_AHCI_PI                  0x0C
> +#define B_SATA_MEM_AHCI_PI_PORT_MASK        0xFF
> +#define B_SATA_MEM_PORT7_IMPLEMENTED        BIT7
> +#define B_SATA_MEM_PORT6_IMPLEMENTED        BIT6
> +#define B_SATA_MEM_PORT5_IMPLEMENTED        BIT5
> +#define B_SATA_MEM_PORT4_IMPLEMENTED        BIT4
> +#define B_SATA_MEM_PORT3_IMPLEMENTED        BIT3
> +#define B_SATA_MEM_PORT2_IMPLEMENTED        BIT2
> +#define B_SATA_MEM_PORT1_IMPLEMENTED        BIT1
> +#define B_SATA_MEM_PORT0_IMPLEMENTED        BIT0
> +#define R_SATA_MEM_AHCI_VS                  0x10
> +#define B_SATA_MEM_AHCI_VS_MJR              0xFFFF0000
> +#define B_SATA_MEM_AHCI_VS_MNR              0x0000FFFF
> +#define R_SATA_MEM_AHCI_EM_LOC              0x1C
> +#define B_SATA_MEM_AHCI_EM_LOC_OFST         0xFFFF0000
> +#define B_SATA_MEM_AHCI_EM_LOC_SZ           0x0000FFFF
> +#define R_SATA_MEM_AHCI_EM_CTRL             0x20
> +#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_ALHD   BIT26
> +#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_XMT    BIT25
> +#define B_SATA_MEM_AHCI_EM_CTRL_ATTR_SMB    BIT24
> +#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SGPIO  BIT19
> +#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SES2   BIT18
> +#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_SAFTE  BIT17
> +#define B_SATA_MEM_AHCI_EM_CTRL_SUPP_LED    BIT16
> +#define B_SATA_MEM_AHCI_EM_CTRL_RST         BIT9
> +#define B_SATA_MEM_AHCI_EM_CTRL_CTL_TM      BIT8
> +#define B_SATA_MEM_AHCI_EM_CTRL_STS_MR      BIT0
> +#define R_SATA_MEM_AHCI_CAP2                0x24
> +#define B_SATA_MEM_AHCI_CAP2_DESO           BIT5
> +#define B_SATA_MEM_AHCI_CAP2_SADM           BIT4
> +#define B_SATA_MEM_AHCI_CAP2_SDS            BIT3
> +#define B_SATA_MEM_AHCI_CAP2_APST           BIT2  ///< Automatic Partial
> to Slumber Transitions
> +#define R_SATA_MEM_AHCI_VSP                 0xA0
> +#define B_SATA_MEM_AHCI_VSP_SLPD            BIT0
> +#define R_SATA_MEM_AHCI_SFM                 0xC8  ///< RST Feature
> Capabilities
> +#define B_SATA_MEM_AHCI_SFM_LEGACY          BIT12
> +#define B_SATA_MEM_AHCI_SFM_OUD             (BIT11 | BIT10)
> +#define N_SATA_MEM_AHCI_SFM_OUD             10
> +#define B_SATA_MEM_AHCI_SFM_SEREQ           BIT9
> +#define B_SATA_MEM_AHCI_SFM_IROES           BIT8
> +#define B_SATA_MEM_AHCI_SFM_LEDL            BIT7
> +#define B_SATA_MEM_AHCI_SFM_HDDLK           BIT6
> +#define B_SATA_MEM_AHCI_SFM_IRSTOROM        BIT5
> +#define B_SATA_MEM_AHCI_SFM_RSTE            BIT4
> +#define B_SATA_MEM_AHCI_SFM_R5E             BIT3
> +#define B_SATA_MEM_AHCI_SFM_R10E            BIT2
> +#define B_SATA_MEM_AHCI_SFM_R1E             BIT1
> +#define B_SATA_MEM_AHCI_SFM_R0E             BIT0
> +#define B_SATA_MEM_AHCI_SFM_LOWBYTES        0x1FF
> +#define R_SATA_MEM_AHCI_P0CLB               0x100
> +#define R_SATA_MEM_AHCI_P1CLB               0x180
> +#define R_SATA_MEM_AHCI_P2CLB               0x200
> +#define R_SATA_MEM_AHCI_P3CLB               0x280
> +#define R_SATA_MEM_AHCI_P4CLB               0x300
> +#define R_SATA_MEM_AHCI_P5CLB               0x380
> +#define R_SATA_MEM_AHCI_P6CLB               0x400
> +#define R_SATA_MEM_AHCI_P7CLB               0x480
> +#define B_SATA_MEM_AHCI_PXCLB               0xFFFFFC00
> +#define R_SATA_MEM_AHCI_P0CLBU              0x104
> +#define R_SATA_MEM_AHCI_P1CLBU              0x184
> +#define R_SATA_MEM_AHCI_P2CLBU              0x204
> +#define R_SATA_MEM_AHCI_P3CLBU              0x284
> +#define R_SATA_MEM_AHCI_P4CLBU              0x304
> +#define R_SATA_MEM_AHCI_P5CLBU              0x384
> +#define R_SATA_MEM_AHCI_P6CLBU              0x404
> +#define R_SATA_MEM_AHCI_P7CLBU              0x484
> +#define B_SATA_MEM_AHCI_PXCLBU              0xFFFFFFFF
> +#define R_SATA_MEM_AHCI_P0FB                0x108
> +#define R_SATA_MEM_AHCI_P1FB                0x188
> +#define R_SATA_MEM_AHCI_P2FB                0x208
> +#define R_SATA_MEM_AHCI_P3FB                0x288
> +#define R_SATA_MEM_AHCI_P4FB                0x308
> +#define R_SATA_MEM_AHCI_P5FB                0x388
> +#define R_SATA_MEM_AHCI_P6FB                0x408
> +#define R_SATA_MEM_AHCI_P7FB                0x488
> +#define B_SATA_MEM_AHCI_PXFB                0xFFFFFF00
> +#define R_SATA_MEM_AHCI_P0FBU               0x10C
> +#define R_SATA_MEM_AHCI_P1FBU               0x18C
> +#define R_SATA_MEM_AHCI_P2FBU               0x20C
> +#define R_SATA_MEM_AHCI_P3FBU               0x28C
> +#define R_SATA_MEM_AHCI_P4FBU               0x30C
> +#define R_SATA_MEM_AHCI_P5FBU               0x38C
> +#define R_SATA_MEM_AHCI_P6FBU               0x40C
> +#define R_SATA_MEM_AHCI_P7FBU               0x48C
> +#define B_SATA_MEM_AHCI_PXFBU               0xFFFFFFFF
> +#define R_SATA_MEM_AHCI_P0IS                0x110
> +#define R_SATA_MEM_AHCI_P1IS                0x190
> +#define R_SATA_MEM_AHCI_P2IS                0x210
> +#define R_SATA_MEM_AHCI_P3IS                0x290
> +#define R_SATA_MEM_AHCI_P4IS                0x310
> +#define R_SATA_MEM_AHCI_P5IS                0x390
> +#define R_SATA_MEM_AHCI_P6IS                0x410
> +#define R_SATA_MEM_AHCI_P7IS                0x490
> +#define B_SATA_MEM_AHCI_PXIS_CPDS           BIT31
> +#define B_SATA_MEM_AHCI_PXIS_TFES           BIT30
> +#define B_SATA_MEM_AHCI_PXIS_HBFS           BIT29
> +#define B_SATA_MEM_AHCI_PXIS_HBDS           BIT28
> +#define B_SATA_MEM_AHCI_PXIS_IFS            BIT27
> +#define B_SATA_MEM_AHCI_PXIS_INFS           BIT26
> +#define B_SATA_MEM_AHCI_PXIS_OFS            BIT24
> +#define B_SATA_MEM_AHCI_PXIS_IPMS           BIT23
> +#define B_SATA_MEM_AHCI_PXIS_PRCS           BIT22
> +#define B_SATA_MEM_AHCI_PXIS_DIS            BIT7
> +#define B_SATA_MEM_AHCI_PXIS_PCS            BIT6
> +#define B_SATA_MEM_AHCI_PXIS_DPS            BIT5
> +#define B_SATA_MEM_AHCI_PXIS_UFS            BIT4
> +#define B_SATA_MEM_AHCI_PXIS_SDBS           BIT3
> +#define B_SATA_MEM_AHCI_PXIS_DSS            BIT2
> +#define B_SATA_MEM_AHCI_PXIS_PSS            BIT1
> +#define B_SATA_MEM_AHCI_PXIS_DHRS           BIT0
> +#define R_SATA_MEM_AHCI_P0IE                0x114
> +#define R_SATA_MEM_AHCI_P1IE                0x194
> +#define R_SATA_MEM_AHCI_P2IE                0x214
> +#define R_SATA_MEM_AHCI_P3IE                0x294
> +#define R_SATA_MEM_AHCI_P4IE                0x314
> +#define R_SATA_MEM_AHCI_P5IE                0x394
> +#define R_SATA_MEM_AHCI_P6IE                0x414
> +#define R_SATA_MEM_AHCI_P7IE                0x494
> +#define B_SATA_MEM_AHCI_PXIE_CPDE           BIT31
> +#define B_SATA_MEM_AHCI_PXIE_TFEE           BIT30
> +#define B_SATA_MEM_AHCI_PXIE_HBFE           BIT29
> +#define B_SATA_MEM_AHCI_PXIE_HBDE           BIT28
> +#define B_SATA_MEM_AHCI_PXIE_IFE            BIT27
> +#define B_SATA_MEM_AHCI_PXIE_INFE           BIT26
> +#define B_SATA_MEM_AHCI_PXIE_OFE            BIT24
> +#define B_SATA_MEM_AHCI_PXIE_IPME           BIT23
> +#define B_SATA_MEM_AHCI_PXIE_PRCE           BIT22
> +#define B_SATA_MEM_AHCI_PXIE_DIE            BIT7
> +#define B_SATA_MEM_AHCI_PXIE_PCE            BIT6
> +#define B_SATA_MEM_AHCI_PXIE_DPE            BIT5
> +#define B_SATA_MEM_AHCI_PXIE_UFIE           BIT4
> +#define B_SATA_MEM_AHCI_PXIE_SDBE           BIT3
> +#define B_SATA_MEM_AHCI_PXIE_DSE            BIT2
> +#define B_SATA_MEM_AHCI_PXIE_PSE            BIT1
> +#define B_SATA_MEM_AHCI_PXIE_DHRE           BIT0
> +#define R_SATA_MEM_AHCI_P0CMD               0x118
> +#define R_SATA_MEM_AHCI_P1CMD               0x198
> +#define R_SATA_MEM_AHCI_P2CMD               0x218
> +#define R_SATA_MEM_AHCI_P3CMD               0x298
> +#define R_SATA_MEM_AHCI_P4CMD               0x318
> +#define R_SATA_MEM_AHCI_P5CMD               0x398
> +#define R_SATA_MEM_AHCI_P6CMD               0x418
> +#define R_SATA_MEM_AHCI_P7CMD               0x498
> +#define B_SATA_MEM_AHCI_PxCMD_ESP           BIT21 ///< Used with an
> external SATA device
> +#define B_SATA_MEM_AHCI_PxCMD_MPSP          BIT19 ///< Mechanical
> Switch Attached to Port
> +#define B_SATA_MEM_AHCI_PxCMD_HPCP          BIT18 ///< Hotplug
> capable
> +#define B_SATA_MEM_AHCI_PxCMD_CR            BIT15
> +#define B_SATA_MEM_AHCI_PxCMD_FR            BIT14
> +#define B_SATA_MEM_AHCI_PxCMD_ISS           BIT13
> +#define B_SATA_MEM_AHCI_PxCMD_CCS           0x00001F00
> +#define B_SATA_MEM_AHCI_PxCMD_FRE           BIT4
> +#define B_SATA_MEM_AHCI_PxCMD_CLO           BIT3
> +#define B_SATA_MEM_AHCI_PxCMD_POD           BIT2
> +#define B_SATA_MEM_AHCI_PxCMD_SUD           BIT1
> +#define B_SATA_MEM_AHCI_PxCMD_ST            BIT0
> +#define R_SATA_MEM_AHCI_P0TFD               0x120
> +#define R_SATA_MEM_AHCI_P1TFD               0x1A0
> +#define R_SATA_MEM_AHCI_P2TFD               0x220
> +#define R_SATA_MEM_AHCI_P3TFD               0x2A0
> +#define R_SATA_MEM_AHCI_P4TFD               0x320
> +#define R_SATA_MEM_AHCI_P5TFD               0x3A0
> +#define R_SATA_MEM_AHCI_P6TFD               0x420
> +#define B_SATA_MEM_AHCI_PXTFD_ERR           0x0000FF00
> +#define B_SATA_MEM_AHCI_PXTFD_STS           0x000000FF
> +#define R_SATA_MEM_AHCI_P0SIG               0x124
> +#define R_SATA_MEM_AHCI_P1SIG               0x1A4
> +#define R_SATA_MEM_AHCI_P2SIG               0x224
> +#define R_SATA_MEM_AHCI_P3SIG               0x2A4
> +#define R_SATA_MEM_AHCI_P4SIG               0x324
> +#define R_SATA_MEM_AHCI_P5SIG               0x3A4
> +#define R_SATA_MEM_AHCI_P6SIG               0x424
> +#define B_SATA_MEM_AHCI_PXSIG_LBA_HR        0xFF000000
> +#define B_SATA_MEM_AHCI_PXSIG_LBA_MR        0x00FF0000
> +#define B_SATA_MEM_AHCI_PXSIG_LBA_LR        0x0000FF00
> +#define B_SATA_MEM_AHCI_PXSIG_SCR           0x000000FF
> +#define R_SATA_MEM_AHCI_P0SSTS              0x128
> +#define R_SATA_MEM_AHCI_P1SSTS              0x1A8
> +#define R_SATA_MEM_AHCI_P2SSTS              0x228
> +#define R_SATA_MEM_AHCI_P3SSTS              0x2A8
> +#define R_SATA_MEM_AHCI_P4SSTS              0x328
> +#define R_SATA_MEM_AHCI_P5SSTS              0x3A8
> +#define R_SATA_MEM_AHCI_P6SSTS              0x428
> +#define B_SATA_MEM_AHCI_PXSSTS_IPM_0        0x00000000
> +#define B_SATA_MEM_AHCI_PXSSTS_IPM_1        0x00000100
> +#define B_SATA_MEM_AHCI_PXSSTS_IPM_2        0x00000200
> +#define B_SATA_MEM_AHCI_PXSSTS_IPM_6        0x00000600
> +#define B_SATA_MEM_AHCI_PXSSTS_SPD_0        0x00000000
> +#define B_SATA_MEM_AHCI_PXSSTS_SPD_1        0x00000010
> +#define B_SATA_MEM_AHCI_PXSSTS_SPD_2        0x00000020
> +#define B_SATA_MEM_AHCI_PXSSTS_SPD_3        0x00000030
> +#define B_SATA_MEM_AHCI_PXSSTS_DET_0        0x00000000
> +#define B_SATA_MEM_AHCI_PXSSTS_DET_1        0x00000001
> +#define B_SATA_MEM_AHCI_PXSSTS_DET_3        0x00000003
> +#define B_SATA_MEM_AHCI_PXSSTS_DET_4        0x00000004
> +#define R_SATA_MEM_AHCI_P0SCTL              0x12C
> +#define R_SATA_MEM_AHCI_P1SCTL              0x1AC
> +#define R_SATA_MEM_AHCI_P2SCTL              0x22C
> +#define R_SATA_MEM_AHCI_P3SCTL              0x2AC
> +#define R_SATA_MEM_AHCI_P4SCTL              0x32C
> +#define R_SATA_MEM_AHCI_P5SCTL              0x3AC
> +#define R_SATA_MEM_AHCI_P6SCTL              0x42C
> +#define B_SATA_MEM_AHCI_PXSCTL_IPM          0x00000F00
> +#define V_SATA_MEM_AHCI_PXSCTL_IPM_0        0x00000000
> +#define V_SATA_MEM_AHCI_PXSCTL_IPM_1        0x00000100
> +#define V_SATA_MEM_AHCI_PXSCTL_IPM_2        0x00000200
> +#define V_SATA_MEM_AHCI_PXSCTL_IPM_3        0x00000300
> +#define B_SATA_MEM_AHCI_PXSCTL_SPD          0x000000F0
> +#define V_SATA_MEM_AHCI_PXSCTL_SPD_0        0x00000000
> +#define V_SATA_MEM_AHCI_PXSCTL_SPD_1        0x00000010
> +#define V_SATA_MEM_AHCI_PXSCTL_SPD_2        0x00000020
> +#define V_SATA_MEM_AHCI_PXSCTL_SPD_3        0x00000030
> +#define B_SATA_MEM_AHCI_PXSCTL_DET          0x0000000F
> +#define V_SATA_MEM_AHCI_PXSCTL_DET_0        0x00000000
> +#define V_SATA_MEM_AHCI_PXSCTL_DET_1        0x00000001
> +#define V_SATA_MEM_AHCI_PXSCTL_DET_4        0x00000004
> +#define R_SATA_MEM_AHCI_P0SERR              0x130
> +#define R_SATA_MEM_AHCI_P1SERR              0x1B0
> +#define R_SATA_MEM_AHCI_P2SERR              0x230
> +#define R_SATA_MEM_AHCI_P3SERR              0x2B0
> +#define R_SATA_MEM_AHCI_P4SERR              0x330
> +#define R_SATA_MEM_AHCI_P5SERR              0x3B0
> +#define R_SATA_MEM_AHCI_P6SERR              0x430
> +#define B_SATA_MEM_AHCI_PXSERR_EXCHG        BIT26
> +#define B_SATA_MEM_AHCI_PXSERR_UN_FIS_TYPE  BIT25
> +#define B_SATA_MEM_AHCI_PXSERR_TRSTE_24     BIT24
> +#define B_SATA_MEM_AHCI_PXSERR_TRSTE_23     BIT23
> +#define B_SATA_MEM_AHCI_PXSERR_HANDSHAKE    BIT22
> +#define B_SATA_MEM_AHCI_PXSERR_CRC_ERROR    BIT21
> +#define B_SATA_MEM_AHCI_PXSERR_10B8B_DECERR BIT19
> +#define B_SATA_MEM_AHCI_PXSERR_COMM_WAKE    BIT18
> +#define B_SATA_MEM_AHCI_PXSERR_PHY_ERROR    BIT17
> +#define B_SATA_MEM_AHCI_PXSERR_PHY_RDY_CHG  BIT16
> +#define B_SATA_MEM_AHCI_PXSERR_INTRNAL_ERR  BIT11
> +#define B_SATA_MEM_AHCI_PXSERR_PROTOCOL_ERR BIT10
> +#define B_SATA_MEM_AHCI_PXSERR_PCDIE        BIT9
> +#define B_SATA_MEM_AHCI_PXSERR_TDIE         BIT8
> +#define B_SATA_MEM_AHCI_PXSERR_RCE          BIT1
> +#define B_SATA_MEM_AHCI_PXSERR_RDIE         BIT0
> +#define R_SATA_MEM_AHCI_P0SACT              0x134
> +#define R_SATA_MEM_AHCI_P1SACT              0x1B4
> +#define R_SATA_MEM_AHCI_P2SACT              0x234
> +#define R_SATA_MEM_AHCI_P3SACT              0x2B4
> +#define R_SATA_MEM_AHCI_P4SACT              0x334
> +#define R_SATA_MEM_AHCI_P5SACT              0x3B4
> +#define R_SATA_MEM_AHCI_P6SACT              0x434
> +#define B_SATA_MEM_AHCI_PXSACT_DS           0xFFFFFFFF
> +#define R_SATA_MEM_AHCI_P0CI                0x138
> +#define R_SATA_MEM_AHCI_P1CI                0x1B8
> +#define R_SATA_MEM_AHCI_P2CI                0x238
> +#define R_SATA_MEM_AHCI_P3CI                0x2B8
> +#define R_SATA_MEM_AHCI_P4CI                0x338
> +#define R_SATA_MEM_AHCI_P5CI                0x3B8
> +#define R_SATA_MEM_AHCI_P6CI                0x438
> +#define B_SATA_MEM_AHCI_PXCI                0xFFFFFFFF
> +
> +//
> +//  SATA AHCI Device ID macros
> +//
> +#define IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_AHCI) || \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_AHCI) || \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_OP_AHCI) \
> +    )
> +
> +#define IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_AHCI) \
> +    )
> +
> +#define IS_PCH_SATA_AHCI_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) \
> +    )
> +
> +//
> +//  SATA RAID Device ID macros
> +//
> +#define IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID) || \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID) || \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_PREM) || \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_MH_RAID_PREM) ||
> \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC) || \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_RST) ||
> \
> +      (DeviceId == V_CNL_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_IBC_2) || \
> +      (DeviceId == V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_ALTDIS) || \
> +      (DeviceId == V_PCH_H_SATA_CFG_DEVICE_ID_D_RAID_RSTE) \
> +    )
> +
> +#define IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
> +    ( \
> +      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID) || \
> +      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_PREM) || \
> +      (DeviceId == V_CNL_PCH_LP_SATA_CFG_DEVICE_ID_M_RAID_IBC) \
> +    )
> +
> +#define IS_PCH_SATA_RAID_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
> +    )
> +
> +//
> +//  Combined SATA IDE/AHCI/RAID Device ID macros
> +//
> +#define IS_PCH_H_SATA_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_SATA_AHCI_DEVICE_ID(DeviceId) || \
> +      IS_PCH_H_SATA_RAID_DEVICE_ID(DeviceId) \
> +    )
> +
> +#define IS_PCH_LP_SATA_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_LP_SATA_AHCI_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_SATA_RAID_DEVICE_ID(DeviceId) \
> +    )
> +#define IS_PCH_SATA_DEVICE_ID(DeviceId) \
> +    ( \
> +      IS_PCH_H_SATA_DEVICE_ID(DeviceId) || \
> +      IS_PCH_LP_SATA_DEVICE_ID(DeviceId) \
> +    )
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
> new file mode 100644
> index 0000000000..00e7881408
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
> @@ -0,0 +1,52 @@
> +/** @file
> +  Register names for PCH Storage and Communication Subsystem
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_SCS_H_
> +#define _PCH_REGS_SCS_H_
> +
> +//
> +// SCS Devices proprietary PCI Config Space Registers
> +//
> +#define R_SCS_CFG_PCS                     0x84                          ///< PME
> Control Status
> +#define B_SCS_CFG_PCS_PMESTS              BIT15                         ///< PME
> Status
> +#define B_SCS_CFG_PCS_PMEEN               BIT8                          ///< PME
> Enable
> +#define B_SCS_CFG_PCS_NSS                 BIT3                          ///< No Soft
> Reset
> +#define B_SCS_CFG_PCS_PS                  (BIT1 | BIT0)                 ///< Power
> State
> +#define B_SCS_CFG_PCS_PS_D3HOT            (BIT1 | BIT0)                 ///<
> Power State: D3Hot State
> +#define R_SCS_CFG_PG_CONFIG               0xA2                          ///< PG
> Config
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
> new file mode 100644
> index 0000000000..c18e1ef38c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
> @@ -0,0 +1,48 @@
> +/** @file
> +  Project specific SCS register definitions.
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_SCS_CNL_H_
> +#define _PCH_REGS_SCS_CNL_H_
> +
> +//
> +//  SCS SDCARD Controller PCI config
> +//
> +#define PCI_DEVICE_NUMBER_PCH_CNL_SCS_SDCARD      20
> +#define PCI_FUNCTION_NUMBER_PCH_CNL_SCS_SDCARD    5
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
> new file mode 100644
> index 0000000000..449335b073
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
> @@ -0,0 +1,232 @@
> +/** @file
> +  Register names for PCH Serial IO Controllers
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_SERIAL_IO_
> +#define _PCH_REGS_SERIAL_IO_
> +
> +//
> +// Serial IO Controllers General PCI Configuration Registers
> +// registers accessed using PciD21FxRegBase + offset
> +//
> +#define R_SERIAL_IO_CFG_BAR0_LOW                        0x10
> +#define B_SERIAL_IO_CFG_BAR0_LOW_BAR                    0xFFFFF000
> +#define R_SERIAL_IO_CFG_BAR0_HIGH                       0x14
> +#define R_SERIAL_IO_CFG_BAR1_LOW                        0x18
> +#define B_SERIAL_IO_CFG_BAR1_LOW_BAR                    0xFFFFF000
> +#define R_SERIAL_IO_CFG_BAR1_HIGH                       0x1C
> +#define V_SERIAL_IO_CFG_BAR_SIZE                        (4 * 1024)
> +#define N_SERIAL_IO_CFG_BAR_ALIGNMENT                   12
> +
> +#define R_SERIAL_IO_CFG_PME_CTRL_STS                    0x84
> +#define B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST             (BIT1| BIT0)
> +
> +#define R_SERIAL_IO_CFG_D0I3MAXDEVPG                    0xA0
> +#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_PMCRE              BIT16
> +#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_I3E                BIT17
> +#define B_SERIAL_IO_CFG_D0I3MAXDEVPG_PGE                BIT18
> +
> +#define R_SERIAL_IO_CFG_INTERRUPTREG                    0x3C
> +#define B_SERIAL_IO_CFG_INTERRUPTREG_INTLINE            0x000000FF
> +
> +//
> +// Serial IO Controllers MMIO Registers
> +// registers accessed : BAR0 + offset
> +//
> +#define R_SERIAL_IO_MEM_SSCR1                           0x4
> +#define B_SERIAL_IO_MEM_SSCR1_IFS                       BIT16
> +
> +#define R_SERIAL_IO_MEM_PPR_CLK                         0x200
> +#define B_SERIAL_IO_MEM_PPR_CLK_EN                      BIT0
> +#define B_SERIAL_IO_MEM_PPR_CLK_UPDATE                  BIT31
> +#define V_SERIAL_IO_MEM_PPR_CLK_M_DIV                   0x30
> +#define V_SERIAL_IO_MEM_PPR_CLK_N_DIV                   0xC35
> +
> +#define R_SERIAL_IO_MEM_PPR_RESETS                      0x204
> +#define B_SERIAL_IO_MEM_PPR_RESETS_FUNC                 BIT0
> +#define B_SERIAL_IO_MEM_PPR_RESETS_APB                  BIT1
> +#define B_SERIAL_IO_MEM_PPR_RESETS_IDMA                 BIT2
> +
> +#define R_SERIAL_IO_MEM_ACTIVE_LTR                      0x210
> +#define R_SERIAL_IO_MEM_IDLE_LTR                        0x214
> +#define B_SERIAL_IO_MEM_LTR_SNOOP_VALUE                 0x000003FF
> +#define B_SERIAL_IO_MEM_LTR_SNOOP_SCALE                 0x00001C00
> +#define B_SERIAL_IO_MEM_LTR_SNOOP_REQUIREMENT           BIT15
> +
> +#define R_SERIAL_IO_MEM_SPI_CS_CONTROL                  0x224
> +#define B_SERIAL_IO_MEM_SPI_CS_CONTROL_STATE            BIT1
> +#define B_SERIAL_IO_MEM_SPI_CS_CONTROL_MODE             BIT0
> +
> +#define R_SERIAL_IO_MEM_REMAP_ADR_LOW                   0x240
> +#define R_SERIAL_IO_MEM_REMAP_ADR_HIGH                  0x244
> +
> +#define R_SERIAL_IO_MEM_I2C_SDA_HOLD                    0x7C
> +#define V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE              0x002C002C
> +
> +//
> +// I2C Controller
> +// Registers accessed through BAR0 + offset
> +//
> +#define    R_IC_CON                            0x00 // I2c Control
> +#define    B_IC_MASTER_MODE                    BIT0
> +#define    B_IC_RESTART_EN                     BIT5
> +#define    B_IC_SLAVE_DISABLE                  BIT6
> +#define    V_IC_SPEED_STANDARD                 0x02
> +#define    V_IC_SPEED_FAST                     0x04
> +#define    V_IC_SPEED_HIGH                     0x06
> +
> +#define    R_IC_TAR                            0x04 // I2c Target Address
> +#define    B_IC_TAR_10BITADDR_MASTER           BIT12
> +
> +#define    R_IC_DATA_CMD                       0x10  // I2c Rx/Tx Data Buffer
> and Command
> +#define    B_IC_CMD_READ                       BIT8    // 1 = read, 0 = write
> +#define    B_IC_CMD_STOP                       BIT9    // 1 = STOP
> +#define    B_IC_CMD_RESTART                    BIT10   // 1 = IC_RESTART_EN
> +#define    V_IC_WRITE_CMD_MASK                 0xFF
> +
> +#define    R_IC_SS_SCL_HCNT                    0x14 // Standard Speed I2c Clock
> SCL High Count
> +#define    R_IC_SS_SCL_LCNT                    0x18 // Standard Speed I2c Clock
> SCL Low Count
> +#define    R_IC_FS_SCL_HCNT                    0x1C // Full Speed I2c Clock SCL
> High Count
> +#define    R_IC_FS_SCL_LCNT                    0x20 // Full Speed I2c Clock SCL
> Low Count
> +#define    R_IC_HS_SCL_HCNT                    0x24 // High Speed I2c Clock SCL
> High Count
> +#define    R_IC_HS_SCL_LCNT                    0x28 // High Speed I2c Clock SCL
> Low Count
> +#define    R_IC_INTR_STAT                      0x2C // I2c Inetrrupt Status
> +#define    R_IC_INTR_MASK                      0x30 // I2c Interrupt Mask
> +#define    B_IC_INTR_GEN_CALL                  BIT11  // General call received
> +#define    B_IC_INTR_START_DET                 BIT10
> +#define    B_IC_INTR_STOP_DET                  BIT9
> +#define    B_IC_INTR_ACTIVITY                  BIT8
> +#define    B_IC_INTR_TX_ABRT                   BIT6   // Set on NACK
> +#define    B_IC_INTR_TX_EMPTY                  BIT4
> +#define    B_IC_INTR_TX_OVER                   BIT3
> +#define    B_IC_INTR_RX_FULL                   BIT2   // Data bytes in RX FIFO
> over threshold
> +#define    B_IC_INTR_RX_OVER                   BIT1
> +#define    B_IC_INTR_RX_UNDER                  BIT0
> +#define    R_IC_RAW_INTR_STAT                ( 0x34) // I2c Raw Interrupt
> Status
> +#define    R_IC_RX_TL                        ( 0x38) // I2c Receive FIFO Threshold
> +#define    R_IC_TX_TL                        ( 0x3C) // I2c Transmit FIFO Threshold
> +#define    R_IC_CLR_INTR                     ( 0x40) // Clear Combined and
> Individual Interrupts
> +#define    R_IC_CLR_RX_UNDER                 ( 0x44) // Clear RX_UNDER
> Interrupt
> +#define    R_IC_CLR_RX_OVER                  ( 0x48) // Clear
> RX_OVERinterrupt
> +#define    R_IC_CLR_TX_OVER                  ( 0x4C) // Clear TX_OVER
> interrupt
> +#define    R_IC_CLR_RD_REQ                   ( 0x50) // Clear RD_REQ interrupt
> +#define    R_IC_CLR_TX_ABRT                  ( 0x54) // Clear TX_ABRT interrupt
> +#define    R_IC_CLR_RX_DONE                  ( 0x58) // Clear RX_DONE
> interrupt
> +#define    R_IC_CLR_ACTIVITY                 ( 0x5C) // Clear ACTIVITY interrupt
> +#define    R_IC_CLR_STOP_DET                 ( 0x60) // Clear STOP_DET
> interrupt
> +#define    R_IC_CLR_START_DET                ( 0x64) // Clear START_DET
> interrupt
> +#define    R_IC_CLR_GEN_CALL                 ( 0x68) // Clear GEN_CALL
> interrupt
> +#define    R_IC_ENABLE                       ( 0x6C) // I2c Enable
> +
> +#define    R_IC_STATUS                         0x70  // I2c Status
> +#define    B_IC_STATUS_RFF                     BIT4   // RX FIFO is completely
> full
> +#define    B_IC_STATUS_RFNE                    BIT3   // RX FIFO is not empty
> +#define    B_IC_STATUS_TFE                     BIT2   // TX FIFO is completely
> empty
> +#define    B_IC_STATUS_TFNF                    BIT1   // TX FIFO is not full
> +#define    B_IC_STATUS_ACTIVITY                BIT0   // Controller Activity
> Status.
> +
> +#define    R_IC_TXFL R                       ( 0x74) // Transmit FIFO Level Register
> +#define    R_IC_RXFLR                        ( 0x78) // Receive FIFO Level Register
> +#define    R_IC_SDA_HOLD                     ( 0x7C)
> +#define    R_IC_TX_ABRT_SOURCE               ( 0x80) // I2c Transmit Abort
> Status Register
> +#define    B_IC_TX_ABRT_7B_ADDR_NACK          BIT0 // NACK on 7-bit
> address
> +
> +#define    R_IC_SDA_SETUP                    ( 0x94) // I2c SDA Setup Register
> +#define    R_IC_ACK_GENERAL_CALL             ( 0x98) // I2c ACK General Call
> Register
> +#define    R_IC_ENABLE_STATUS                ( 0x9C) // I2c Enable Status
> Register
> +#define    B_IC_EN                            BIT0   // I2c enable status
> +
> +#define    R_IC_CLK_GATE                     ( 0xC0)
> +#define    R_IC_COMP_PARAM                   ( 0xF4) // Component
> Parameter Register
> +#define    R_IC_COMP_VERSION                 ( 0xF8) // Component Version ID
> +#define    R_IC_COMP_TYPE                    ( 0xFC) // Component Type
> +
> +//
> +// Bridge Private Configuration Registers
> +// accessed only through SB messaging. SB access = SerialIo IOSF2OCP Bridge
> Port ID + offset
> +//
> +#define R_SERIAL_IO_PCR_PMCTL                        0x1D0
> +#define V_SERIAL_IO_PCR_PMCTL_PWR_GATING             0x3F
> +
> +#define R_SERIAL_IO_PCR_PCICFGCTRLx                 0x200
> +#define V_SERIAL_IO_PCR_PCICFGCTRL_N_OFFS           0x04
> +#define R_SERIAL_IO_PCR_PCICFGCTRL1                 0x200 //I2C0
> +#define R_SERIAL_IO_PCR_PCICFGCTRL2                 0x204 //I2C1
> +#define R_SERIAL_IO_PCR_PCICFGCTRL3                 0x208 //I2C2
> +#define R_SERIAL_IO_PCR_PCICFGCTRL4                 0x20C //I2C3
> +#define R_SERIAL_IO_PCR_PCICFGCTRL5                 0x210 //I2C4
> +#define R_SERIAL_IO_PCR_PCICFGCTRL6                 0x214 //I2C5
> +#define R_SERIAL_IO_PCR_PCICFGCTRL9                 0x218 //UA00
> +#define R_SERIAL_IO_PCR_PCICFGCTRL10                0x21C //UA01
> +#define R_SERIAL_IO_PCR_PCICFGCTRL11                0x220 //UA02
> +#define R_SERIAL_IO_PCR_PCICFGCTRL13                0x224 //SPI0
> +#define R_SERIAL_IO_PCR_PCICFGCTRL14                0x228 //SPI1
> +
> +#define B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS      BIT0
> +#define B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN     BIT1
> +#define B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS         BIT7
> +#define B_SERIAL_IO_PCR_PCICFGCTRL_INT_PIN          (BIT11 | BIT10 | BIT9
> | BIT8)
> +#define N_SERIAL_IO_PCR_PCICFGCTRL_INT_PIN          8
> +#define V_SERIAL_IO_PCR_PCICFGCTRL_INTA             0x01
> +#define V_SERIAL_IO_PCR_PCICFGCTRL_INTB             0x02
> +#define V_SERIAL_IO_PCR_PCICFGCTRL_INTC             0x03
> +#define V_SERIAL_IO_PCR_PCICFGCTRL_INTD             0x04
> +#define B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_IRQ         0x000FF000
> +#define N_SERIAL_IO_PCR_PCICFGCTRL_ACPI_IRQ         12
> +#define B_SERIAL_IO_PCR_PCICFGCTRL_PCI_IRQ          0x0FF00000
> +#define N_SERIAL_IO_PCR_PCICFGCTRL_PCI_IRQ          20
> +
> +#define R_SERIAL_IO_PCR_GPPRVRW2                            0x604
> +#define B_SERIAL_IO_PCR_GPPRVRW2_PGCB_FRC_CLK_CP_EN         BIT1
> +#define B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CG_EN         BIT5
> +#define B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CLKREQ_CTL_EN
> BIT11
> +#define V_SERIAL_IO_PCR_GPPRVRW2_CLK_GATING
> (B_SERIAL_IO_PCR_GPPRVRW2_PGCB_FRC_CLK_CP_EN |
> B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CG_EN |
> B_SERIAL_IO_PCR_GPPRVRW2_CDC_SIDE_CFG_CLKREQ_CTL_EN)
> +
> +
> +#define R_SERIAL_IO_PCR_GPPRVRW7                    0x618
> +#define B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN BIT0
> +#define B_SERIAL_IO_PCR_GPPRVRW7_UART1_BYTE_ADDR_EN BIT1
> +#define B_SERIAL_IO_PCR_GPPRVRW7_UART2_BYTE_ADDR_EN BIT2
> +
> +//
> +// Number of pins used by SerialIo controllers
> +//
> +#define PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER               2
> +#define PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER              4
> +#define PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL 2
> +#define PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER               4
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCn
> l.h
> new file mode 100644
> index 0000000000..62b859dc99
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCn
> l.h
> @@ -0,0 +1,138 @@
> +/** @file
> +  Device IDs for PCH Serial IO Controllers for PCH
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_SERIAL_IO_CNL_
> +#define _PCH_REGS_SERIAL_IO_CNL_
> +
> +//
> +//  Serial IO I2C0 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0            21
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0          0
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID       0x9DE8
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID        0xA368
> +
> +//
> +//  Serial IO I2C1 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1            21
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1          1
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID       0x9DE9
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID        0xA369
> +
> +//
> +//  Serial IO I2C2 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2            21
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2          2
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID       0x9DEA
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID        0xA36A
> +
> +//
> +//  Serial IO I2C3 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3            21
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3          3
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID       0x9DEB
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID        0xA36B
> +
> +//
> +//  Serial IO I2C4 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4            25
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4          0
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID       0x9DC5
> +
> +//
> +//  Serial IO I2C5 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5            25
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5          1
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID       0x9DC6
> +
> +//
> +//  Serial IO SPI0 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0            30
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0          2
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID       0x9DAA
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID        0xA32A
> +
> +//
> +//  Serial IO SPI1 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1            30
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1          3
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID       0x9DAB
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID        0xA32B
> +
> +//
> +//  Serial IO UART0 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0           30
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0         0
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID      0x9DA8
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID       0xA328
> +
> +//
> +//  Serial IO UART1 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1           30
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1         1
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID      0x9DA9
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID       0xA329
> +
> +//
> +//  Serial IO UART2 Controller Registers
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2           25
> +#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2         2
> +
> +#define V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID      0x9DC7
> +#define V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID       0xA347
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
> new file mode 100644
> index 0000000000..e571a6a127
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
> @@ -0,0 +1,151 @@
> +/** @file
> +  Register names for PCH Smbus Device.
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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 .
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 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 (D31:F4)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_SMBUS           31
> +#define PCI_FUNCTION_NUMBER_PCH_SMBUS         4
> +#define R_SMBUS_CFG_BASE                      0x20
> +#define V_SMBUS_CFG_BASE_SIZE                 (1 << 5)
> +#define B_SMBUS_CFG_BASE_BAR                  0x0000FFE0
> +#define R_SMBUS_CFG_HOSTC                     0x40
> +#define B_SMBUS_CFG_HOSTC_SPDWD               BIT4
> +#define B_SMBUS_CFG_HOSTC_SSRESET             BIT3
> +#define B_SMBUS_CFG_HOSTC_I2C_EN              BIT2
> +#define B_SMBUS_CFG_HOSTC_SMI_EN              BIT1
> +#define B_SMBUS_CFG_HOSTC_HST_EN              BIT0
> +#define R_SMBUS_CFG_TCOBASE                   0x50
> +#define B_SMBUS_CFG_TCOBASE_BAR               0x0000FFE0
> +#define R_SMBUS_CFG_TCOCTL                    0x54
> +#define B_SMBUS_CFG_TCOCTL_TCO_BASE_EN        BIT8
> +#define B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK      BIT0
> +#define R_SMBUS_CFG_64                        0x64
> +#define R_SMBUS_CFG_80                        0x80
> +
> +//
> +// SMBus I/O Registers
> +//
> +#define R_SMBUS_IO_HSTS                  0x00  ///< Host Status Register R/W
> +#define B_SMBUS_IO_HBSY                  0x01
> +#define B_SMBUS_IO_INTR                  0x02
> +#define B_SMBUS_IO_DERR                  0x04
> +#define B_SMBUS_IO_BERR                  0x08
> +#define B_SMBUS_IO_FAIL                  0x10
> +#define B_SMBUS_IO_SMBALERT_STS          0x20
> +#define B_SMBUS_IO_IUS                   0x40
> +#define B_SMBUS_IO_BYTE_DONE_STS         0x80
> +#define B_SMBUS_IO_ERROR                 (B_SMBUS_IO_DERR |
> B_SMBUS_IO_BERR | B_SMBUS_IO_FAIL)
> +#define B_SMBUS_IO_HSTS_ALL              0xFF
> +#define R_SMBUS_IO_HCTL                  0x02  ///< Host Control Register
> R/W
> +#define B_SMBUS_IO_INTREN                0x01
> +#define B_SMBUS_IO_KILL                  0x02
> +#define B_SMBUS_IO_SMB_CMD               0x1C
> +#define V_SMBUS_IO_SMB_CMD_QUICK         0x00
> +#define V_SMBUS_IO_SMB_CMD_BYTE          0x04
> +#define V_SMBUS_IO_SMB_CMD_BYTE_DATA     0x08
> +#define V_SMBUS_IO_SMB_CMD_WORD_DATA     0x0C
> +#define V_SMBUS_IO_SMB_CMD_PROCESS_CALL  0x10
> +#define V_SMBUS_IO_SMB_CMD_BLOCK         0x14
> +#define V_SMBUS_IO_SMB_CMD_IIC_READ      0x18
> +#define V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS 0x1C
> +#define B_SMBUS_IO_LAST_BYTE             0x20
> +#define B_SMBUS_IO_START                 0x40
> +#define B_SMBUS_IO_PEC_EN                0x80
> +#define R_SMBUS_IO_HCMD                  0x03  ///< Host Command Register
> R/W
> +#define R_SMBUS_IO_TSA                   0x04  ///< Transmit Slave Address
> Register R/W
> +#define B_SMBUS_IO_RW_SEL                0x01
> +#define B_SMBUS_IO_READ                  0x01  // RW
> +#define B_SMBUS_IO_WRITE                 0x00  // RW
> +#define B_SMBUS_IO_ADDRESS               0xFE
> +#define R_SMBUS_IO_HD0                   0x05  ///< Data 0 Register R/W
> +#define R_SMBUS_IO_HD1                   0x06  ///< Data 1 Register R/W
> +#define R_SMBUS_IO_HBD                   0x07  ///< Host Block Data Register
> R/W
> +#define R_SMBUS_IO_PEC                   0x08  ///< Packet Error Check Data
> Register R/W
> +#define R_SMBUS_IO_RSA                   0x09  ///< Receive Slave Address
> Register R/W
> +#define B_SMBUS_IO_SLAVE_ADDR            0x7F
> +#define R_SMBUS_IO_SD                    0x0A  ///< Receive Slave Data
> Register R/W
> +#define R_SMBUS_IO_AUXS                  0x0C  ///< Auxiliary Status Register
> R/WC
> +#define B_SMBUS_IO_CRCE                  0x01
> +#define B_SMBUS_IO_STCO                  0x02  ///< SMBus TCO Mode
> +#define R_SMBUS_IO_AUXC                  0x0D  ///< Auxiliary Control
> Register R/W
> +#define B_SMBUS_IO_AAC                   0x01
> +#define B_SMBUS_IO_E32B                  0x02
> +#define R_SMBUS_IO_SMLC                  0x0E  ///< SMLINK Pin Control
> Register R/W
> +#define B_SMBUS_IO_SMLINK0_CUR_STS       0x01
> +#define B_SMBUS_IO_SMLINK1_CUR_STS       0x02
> +#define B_SMBUS_IO_SMLINK_CLK_CTL        0x04
> +#define R_SMBUS_IO_SMBC                  0x0F  ///< SMBus Pin Control
> Register R/W
> +#define B_SMBUS_IO_SMBCLK_CUR_STS        0x01
> +#define B_SMBUS_IO_SMBDATA_CUR_STS       0x02
> +#define B_SMBUS_IO_SMBCLK_CTL            0x04
> +#define R_SMBUS_IO_SSTS                  0x10  ///< Slave Status Register
> R/WC
> +#define B_SMBUS_IO_HOST_NOTIFY_STS       0x01
> +#define R_SMBUS_IO_SCMD                  0x11  ///< Slave Command Register
> R/W
> +#define B_SMBUS_IO_HOST_NOTIFY_INTREN    0x01
> +#define B_SMBUS_IO_HOST_NOTIFY_WKEN      0x02
> +#define B_SMBUS_IO_SMBALERT_DIS          0x04
> +#define R_SMBUS_IO_NDA                   0x14  ///< Notify Device Address
> Register RO
> +#define B_SMBUS_IO_DEVICE_ADDRESS        0xFE
> +#define R_SMBUS_IO_NDLB                  0x16  ///< Notify Data Low Byte
> Register RO
> +#define R_SMBUS_IO_NDHB                  0x17  ///< Notify Data High Byte
> Register RO
> +
> +//
> +// SMBus Private Config Registers
> +// (PID:SMB)
> +//
> +#define R_SMBUS_PCR_TCOCFG                0x00                        ///< TCO
> Configuration register
> +#define B_SMBUS_PCR_TCOCFG_IE             BIT7                        ///< TCO
> IRQ Enable
> +#define B_SMBUS_PCR_TCOCFG_IS             (BIT2 | BIT1 | BIT0)        ///<
> TCO IRQ Select
> +#define V_SMBUS_PCR_TCOCFG_IRQ_9          0x00
> +#define V_SMBUS_PCR_TCOCFG_IRQ_10         0x01
> +#define V_SMBUS_PCR_TCOCFG_IRQ_11         0x02
> +#define V_SMBUS_PCR_TCOCFG_IRQ_20         0x04                        ///<
> only if APIC enabled
> +#define V_SMBUS_PCR_TCOCFG_IRQ_21         0x05                        ///<
> only if APIC enabled
> +#define V_SMBUS_PCR_TCOCFG_IRQ_22         0x06                        ///<
> only if APIC enabled
> +#define V_SMBUS_PCR_TCOCFG_IRQ_23         0x07                        ///<
> only if APIC enabled
> +#define R_SMBUS_PCR_SMBTM                 0x04                        ///<
> SMBus Test Mode
> +#define B_SMBUS_PCR_SMBTM_SMBCT           BIT1                        ///<
> SMBus Counter
> +#define B_SMBUS_PCR_SMBTM_SMBDG           BIT0                        ///<
> SMBus Deglitch
> +#define R_SMBUS_PCR_SCTM                  0x08                        ///< Short
> Counter Test Mode
> +#define B_SMBUS_PCR_SCTM_SSU              BIT31                       ///<
> Simulation Speed-Up
> +#define R_SMBUS_PCR_GC                    0x0C                        ///< General
> Control
> +#define B_SMBUS_PCR_GC_FD                 BIT0                        ///<
> Function Disable
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
> new file mode 100644
> index 0000000000..013603ca25
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
> @@ -0,0 +1,295 @@
> +/** @file
> +  Register names for PCH SPI device.
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_SPI_H_
> +#define _PCH_REGS_SPI_H_
> +
> +//
> +// SPI Registers (D31:F5)
> +//
> +
> +#define PCI_DEVICE_NUMBER_PCH_SPI           31
> +#define PCI_FUNCTION_NUMBER_PCH_SPI         5
> +
> +#define R_SPI_CFG_BAR0                      0x10
> +#define B_SPI_CFG_BAR0_MASK                 0x0FFF
> +
> +#define R_SPI_CFG_BDE                       0xD8
> +#define B_SPI_CFG_BDE_F8                    0x8000
> +#define B_SPI_CFG_BDE_F0                    0x4000
> +#define B_SPI_CFG_BDE_E8                    0x2000
> +#define B_SPI_CFG_BDE_E0                    0x1000
> +#define B_SPI_CFG_BDE_D8                    0x0800
> +#define B_SPI_CFG_BDE_D0                    0x0400
> +#define B_SPI_CFG_BDE_C8                    0x0200
> +#define B_SPI_CFG_BDE_C0                    0x0100
> +#define B_SPI_CFG_BDE_LEG_F                 0x0080
> +#define B_SPI_CFG_BDE_LEG_E                 0x0040
> +#define B_SPI_CFG_BDE_70                    0x0008
> +#define B_SPI_CFG_BDE_60                    0x0004
> +#define B_SPI_CFG_BDE_50                    0x0002
> +#define B_SPI_CFG_BDE_40                    0x0001
> +
> +#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 B_SPI_CFG_BC_OSFH                   BIT9            ///< OS Function
> Hide
> +#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 V_SPI_CFG_BC_BBS_LPC                1               ///< Boot BIOS
> strapped to LPC
> +#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_EN_CACHE_EN   0x02            ///<
> Prefetching and Caching enabled
> +#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS 0x01            ///< No
> prefetching and no caching
> +#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_EN  0x00            ///< No
> prefetching, but caching enabled
> +#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_BFPR                      0x00                          ///< BIOS
> Flash Primary Region Register(32bits), which is RO and contains the same value
> from FREG1
> +#define B_SPI_MEM_BFPR_PRL                  0x7FFF0000                    ///<
> BIOS Flash Primary Region Limit mask
> +#define N_SPI_MEM_BFPR_PRL                  16                            ///< BIOS
> Flash Primary Region Limit bit position
> +#define B_SPI_MEM_BFPR_PRB                  0x00007FFF                    ///<
> BIOS Flash Primary Region Base mask
> +#define N_SPI_MEM_BFPR_PRB                  0                             ///< BIOS
> Flash Primary Region Base bit position
> +#define R_SPI_MEM_HSFSC                     0x04                          ///<
> Hardware Sequencing Flash Status and Control Register(32bits)
> +#define B_SPI_MEM_HSFSC_FSMIE               BIT31                         ///<
> Flash SPI SMI# Enable
> +#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_PRR34_LOCKDN        BIT12
> ///< PRR3 PRR4 Lock-Down
> +#define B_SPI_MEM_HSFSC_WRSDIS              BIT11                         ///<
> Write Status Disable
> +#define B_SPI_MEM_HSFSC_SAF_CE              BIT8                          ///<
> SAF ctype error
> +#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_SAF_LE              BIT6                          ///<
> SAF link error
> +#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_FDATA01                   0x14                          ///< SPI
> Data 01
> +#define R_SPI_MEM_FDATA02                   0x18                          ///< SPI
> Data 02
> +#define R_SPI_MEM_FDATA03                   0x1C                          ///< SPI
> Data 03
> +#define R_SPI_MEM_FDATA04                   0x20                          ///< SPI
> Data 04
> +#define R_SPI_MEM_FDATA05                   0x24                          ///< SPI
> Data 05
> +#define R_SPI_MEM_FDATA06                   0x28                          ///< SPI
> Data 06
> +#define R_SPI_MEM_FDATA07                   0x2C                          ///< SPI
> Data 07
> +#define R_SPI_MEM_FDATA08                   0x30                          ///< SPI
> Data 08
> +#define R_SPI_MEM_FDATA09                   0x34                          ///< SPI
> Data 09
> +#define R_SPI_MEM_FDATA10                   0x38                          ///< SPI
> Data 10
> +#define R_SPI_MEM_FDATA11                   0x3C                          ///< SPI
> Data 11
> +#define R_SPI_MEM_FDATA12                   0x40                          ///< SPI
> Data 12
> +#define R_SPI_MEM_FDATA13                   0x44                          ///< SPI
> Data 13
> +#define R_SPI_MEM_FDATA14                   0x48                          ///< SPI
> Data 14
> +#define R_SPI_MEM_FDATA15                   0x4C                          ///< SPI
> Data 15
> +#define R_SPI_MEM_FRAP                      0x50                          ///< Flash
> Region Access Permisions 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_FREG1_BIOS                0x58                          ///<
> Flash Region 1(BIOS)(32bits)
> +#define R_SPI_MEM_FREG2_ME                  0x5C                          ///<
> Flash Region 2(ME)(32bits)
> +#define R_SPI_MEM_FREG3_GBE                 0x60                          ///<
> Flash Region 3(GbE)(32bits)
> +#define R_SPI_MEM_FREG4_PLATFORM_DATA       0x64
> ///< Flash Region 4(Platform Data)(32bits)
> +#define R_SPI_MEM_FREG5_DER                 0x68                          ///<
> Flash Region 5(Device Expansion Region)(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 R_SPI_MEM_PR1                       0x88                          ///<
> Protected Region 1 Register
> +#define R_SPI_MEM_PR2                       0x8C                          ///<
> Protected Region 2 Register
> +#define R_SPI_MEM_PR3                       0x90                          ///<
> Protected Region 3 Register
> +#define R_SPI_MEM_PR4                       0x94                          ///<
> Protected Region 4 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_SFRAP                     0xB0                          ///<
> Secondary Flash Regions Access Permisions Register
> +#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_REGN            0x2000
> ///< Region
> +#define V_SPI_MEM_FDOC_FDSS_MSTR            0x3000
> ///< Master
> +#define V_SPI_MEM_FDOC_FDSS_PCHS            0x4000                        ///<
> PCH soft straps
> +#define V_SPI_MEM_FDOC_FDSS_SFDP            0x5000                        ///<
> SFDP Parameter Table
> +#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 B_SPI_MEM_SFDPX_VSCCX_EO_4K         BIT28
> ///< 4k Erase valid (EO_4k_valid)
> +#define B_SPI_MEM_SFDPX_VSCCX_RPMC          BIT27
> ///< RPMC Supported
> +#define B_SPI_MEM_SFDPX_VSCCX_DPD           BIT26                         ///<
> Deep Powerdown Supported
> +#define B_SPI_MEM_SFDPX_VSCCX_SUSRES        BIT25
> ///< Suspend/Resume Supported
> +#define B_SPI_MEM_SFDPX_VSCCX_SOFTRES       BIT24
> ///< Soft Reset Supported
> +#define B_SPI_MEM_SFDPX_VSCCX_64k_EO_MASK   0x00FF0000
> ///< 64k Erase Opcode (EO_64k)
> +#define B_SPI_MEM_SFDPX_VSCCX_4k_EO_MASK    0x0000FF00
> ///< 4k Erase Opcode (EO_4k)
> +#define B_SPI_MEM_SFDPX_VSCCX_QER           (BIT7 | BIT6 | BIT5)
> ///< Quad Enable Requirements
> +#define B_SPI_MEM_SFDPX_VSCCX_WEWS          BIT4
> ///< Write Enable on Write Status
> +#define B_SPI_MEM_SFDPX_VSCCX_WSR           BIT3                          ///<
> Write Status Required
> +#define B_SPI_MEM_SFDPX_VSCCX_WG_64B        BIT2
> ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
> +#define R_SPI_MEM_SFDP1_VSCC1               0xC8                          ///<
> Vendor Specific Component Capabilities Register(32 bits)
> +#define R_SPI_MEM_PINTX                     0xCC                          ///<
> Parameter Table Index
> +#define N_SPI_MEM_PINTX_SPT                 14
> +#define V_SPI_MEM_PINTX_SPT_CPT0            0x0                           ///<
> Component 0 Property Parameter Table
> +#define V_SPI_MEM_PINTX_SPT_CPT1            0x1                           ///<
> Component 1 Property Parameter Table
> +#define N_SPI_MEM_PINTX_HORD                12
> +#define V_SPI_MEM_PINTX_HORD_SFDP           0x0                           ///<
> SFDP Header
> +#define V_SPI_MEM_PINTX_HORD_PT             0x1                           ///<
> Parameter Table Header
> +#define V_SPI_MEM_PINTX_HORD_DATA           0x2                           ///<
> Data
> +#define R_SPI_MEM_PTDATA                    0xD0                          ///<
> Parameter Table Data
> +#define R_SPI_MEM_SBRS                      0xD4                          ///< SPI
> Bus Requester Status
> +
> +//
> +// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
> +//
> +#define R_SPI_FLASH_FDBAR_FLVALSIG            0x00                          ///<
> Flash Valid Signature
> +#define V_SPI_FLASH_FDBAR_FLVALSIG            0x0FF0A55A
> +#define R_SPI_FLASH_FDBAR_FLASH_MAP0          0x04
> +#define B_SPI_FLASH_FDBAR_FCBA                0x000000FF
> ///< Flash Component Base Address
> +#define B_SPI_FLASH_FDBAR_NC                  0x00000300
> ///< Number Of Components
> +#define N_SPI_FLASH_FDBAR_NC                  8                             ///<
> Number Of Components
> +#define V_SPI_FLASH_FDBAR_NC_1                0x00000000
> +#define V_SPI_FLASH_FDBAR_NC_2                0x00000100
> +#define B_SPI_FLASH_FDBAR_FRBA                0x00FF0000
> ///< Flash Region Base Address
> +#define B_SPI_FLASH_FDBAR_NR                  0x07000000
> ///< Number Of Regions
> +#define R_SPI_FLASH_FDBAR_FLASH_MAP1          0x08
> +#define B_SPI_FLASH_FDBAR_FMBA                0x000000FF
> ///< Flash Master Base Address
> +#define B_SPI_FLASH_FDBAR_NM                  0x00000700
> ///< Number Of Masters
> +#define B_SPI_FLASH_FDBAR_FPSBA               0x00FF0000
> ///< PCH Strap Base Address, [23:16] represents [11:4]
> +#define N_SPI_FLASH_FDBAR_FPSBA               16                            ///<
> PCH Strap base Address bit position
> +#define N_SPI_FLASH_FDBAR_FPSBA_REPR          4                             ///<
> PCH Strap base Address bit represents position
> +#define B_SPI_FLASH_FDBAR_PCHSL               0xFF000000
> ///< PCH Strap Length, [31:24] represents number of Dwords
> +#define N_SPI_FLASH_FDBAR_PCHSL               24                            ///<
> PCH Strap Length bit position
> +#define R_SPI_FLASH_FDBAR_FLASH_MAP2          0x0C
> +#define B_SPI_FLASH_FDBAR_FCPUSBA             0x000000FF
> ///< CPU Strap Base Address, [7:0] represents [11:4]
> +#define N_SPI_FLASH_FDBAR_FCPUSBA             0                             ///<
> CPU Strap Base Address bit position
> +#define N_SPI_FLASH_FDBAR_FCPUSBA_REPR        4
> ///< CPU Strap Base Address bit represents position
> +#define B_SPI_FLASH_FDBAR_CPUSL               0x0000FF00
> ///< CPU Strap Length, [15:8] represents number of Dwords
> +#define N_SPI_FLASH_FDBAR_CPUSL               8                             ///<
> CPU Strap Length bit position
> +//
> +// Flash Component Base Address (FCBA) from Flash Region 0
> +//
> +#define R_SPI_FLASH_FCBA_FLCOMP               0x00                          ///<
> Flash Components Register
> +#define B_SPI_FLASH_FLCOMP_RIDS_FREQ          (BIT29 | BIT28 | BIT27)
> ///< Read ID and Read Status Clock Frequency
> +#define B_SPI_FLASH_FLCOMP_WE_FREQ            (BIT26 | BIT25 | BIT24)
> ///< Write and Erase Clock Frequency
> +#define B_SPI_FLASH_FLCOMP_FRCF_FREQ          (BIT23 | BIT22 | BIT21)
> ///< Fast Read Clock Frequency
> +#define B_SPI_FLASH_FLCOMP_FR_SUP             BIT20                         ///<
> Fast Read Support.
> +#define B_SPI_FLASH_FLCOMP_RC_FREQ            (BIT19 | BIT18 | BIT17)
> ///< Read Clock Frequency.
> +#define V_SPI_FLASH_FLCOMP_FREQ_48MHZ         0x02
> +#define V_SPI_FLASH_FLCOMP_FREQ_30MHZ         0x04
> +#define V_SPI_FLASH_FLCOMP_FREQ_17MHZ         0x06
> +#define B_SPI_FLASH_FLCOMP_COMP1_MASK         0xF0
> ///< Flash Component 1 Size MASK
> +#define N_SPI_FLASH_FLCOMP_COMP1              4                             ///<
> Flash Component 1 Size bit position
> +#define B_SPI_FLASH_FLCOMP_COMP0_MASK         0x0F
> ///< Flash Component 0 Size MASK
> +#define V_SPI_FLASH_FLCOMP_COMP_512KB         0x80000
> +//
> +// Descriptor Upper Map Section from Flash Region 0
> +//
> +#define R_SPI_FLASH_UMAP1                     0xEFC                         ///<
> Flash Upper Map 1
> +#define B_SPI_FLASH_UMAP1_VTBA                0x000000FF
> ///< VSCC Table Base Address
> +#define B_SPI_FLASH_UMAP1_VTL                 0x0000FF00
> ///< VSCC Table Length
> +
> +//
> +// SPI Private Configuration Space Registers
> +//
> +#define R_SPI_PCR_CLK_CTL               0xC004
> +#define R_SPI_PCR_PWR_CTL               0xC008
> +#define R_SPI_PCR_ESPI_SOFTSTRAPS       0xC210
> +#define B_SPI_PCR_ESPI_SLAVE            BIT12
> +
> +//
> +// MMP0
> +//
> +#define R_PCH_SPI_STRP_MMP0                 0xC4    ///< MMP0 Soft strap
> offset
> +#define B_PCH_SPI_STRP_MMP0                 0x10    ///< MMP0 Soft strap
> bit
> +
> +
> +#define R_PCH_SPI_STRP_SFDP                 0xF0    ///< PCH Soft Strap SFDP
> +#define B_PCH_SPI_STRP_SFDP_QIORE           BIT3    ///< Quad IO Read
> Enable
> +#define B_PCH_SPI_STRP_SFDP_QORE            BIT2    ///< Quad Output
> Read Enable
> +#define B_PCH_SPI_STRP_SFDP_DIORE           BIT1    ///< Dual IO Read
> Enable
> +#define B_PCH_SPI_STRP_SFDP_DORE            BIT0    ///< Dual Output Read
> Enable
> +
> +//
> +// Descriptor Record 0
> +//
> +#define R_PCH_SPI_STRP_DSCR_0               0x00    ///< PCH Soft Strap 0
> +#define B_PCH_SPI_STRP_DSCR_0_PTT_SUPP      BIT22   ///< PTT Supported
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalC
> nl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalC
> nl.h
> new file mode 100644
> index 0000000000..fb93a62364
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalC
> nl.h
> @@ -0,0 +1,49 @@
> +/** @file
> +  Register names for PCH Thermal Device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_THERMAL_H_
> +#define _PCH_REGS_THERMAL_H_
> +
> +//
> +//  Thermal Device Registers (D18:0)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_THERMAL   18
> +#define PCI_FUNCTION_NUMBER_PCH_THERMAL 0
> +#define R_THERMAL_CFG_MEM_TBAR              0x10
> +#define B_THERMAL_CFG_MEM_TBAR_MASK         0xFFFFF000
> +#define R_THERMAL_CFG_MEM_TBARH             0x14
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.
> h
> new file mode 100644
> index 0000000000..21f9839546
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.
> h
> @@ -0,0 +1,134 @@
> +/** @file
> +  Register names for PCH TraceHub device
> +
> +  Conventions:
> +
> +  - Register definition format:
> +
> Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpa
> ce_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
> +    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 -H denoted by "_PCH_H_" in component name.
> +    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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_REGS_TRACE_HUB_H_
> +#define _PCH_REGS_TRACE_HUB_H_
> +
> +//
> +// TraceHub Registers (D31:F7)
> +//
> +#define PCI_DEVICE_NUMBER_PCH_TRACE_HUB               31
> +#define PCI_FUNCTION_NUMBER_PCH_TRACE_HUB             7
> +
> +#define R_TRACE_HUB_CFG_CSR_MTB_LBAR                  0x10
> +#define B_TRACE_HUB_CFG_CSR_MTB_RBAL                  0xFFF00000
> +#define R_TRACE_HUB_CFG_CSR_MTB_UBAR                  0x14
> +#define B_TRACE_HUB_CFG_CSR_MTB_RBAU                  0xFFFFFFFF
> +#define R_TRACE_HUB_CFG_SW_LBAR                       0x18
> +#define R_TRACE_HUB_CFG_SW_UBAR                       0x1C
> +#define B_TRACE_HUB_CFG_SW_RBAU                       0xFFFFFFFF
> +#define R_TRACE_HUB_CFG_RTIT_LBAR                     0x20
> +#define B_TRACE_HUB_CFG_RTIT_RBAL                     0xFFFFFF00
> +#define R_TRACE_HUB_CFG_RTIT_UBAR                     0x24
> +#define B_TRACE_HUB_CFG_RTIT_RBAU                     0xFFFFFFFF
> +#define R_TRACE_HUB_CFG_MSICID                        0x40
> +#define R_TRACE_HUB_CFG_MSINCP                        0x41
> +#define R_TRACE_HUB_CFG_MSIMC                         0x42
> +#define R_TRACE_HUB_CFG_MSILMA                        0x44
> +#define R_TRACE_HUB_CFG_MSIUMA                        0x48
> +#define R_TRACE_HUB_CFG_MSIMD                         0x4C
> +#define B_TRACE_HUB_CFG_FW_RBAU                       0xFFFFFFFF
> +#define R_TRACE_HUB_CFG_DSC                           0x80
> +#define B_TRACE_HUB_CFG_BYP                           BIT0 //< TraceHub
> Bypass
> +#define R_TRACE_HUB_CFG_DSS                           0x81
> +#define R_TRACE_HUB_CFG_ISTOT                         0x84
> +#define R_TRACE_HUB_CFG_ICTOT                         0x88
> +#define R_TRACE_HUB_CFG_IPAD                          0x8C
> +#define R_TRACE_HUB_CFG_DSD                           0x90
> +
> +//
> +// Offsets from CSR_MTB_BAR
> +//
> +#define R_TRACE_HUB_MEM_MTB_GTHOPT0                   0x00
> +#define B_TRACE_HUB_MEM_MTB_GTHOPT0_P0FLUSH           BIT7
> +#define B_TRACE_HUB_MEM_MTB_GTHOPT0_P1FLUSH           BIT15
> +#define V_TRACE_HUB_MEM_MTB_SWDEST_PTI                0x0A
> +#define V_TRACE_HUB_MEM_MTB_SWDEST_MEMEXI             0x08
> +#define V_TRACE_HUB_MEM_MTB_SWDEST_DISABLE            0x00
> +#define R_TRACE_HUB_MEM_MTB_SWDEST_1                  0x0C
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_1              0x0000000F
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_2              0x000000F0
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_CSE_3              0x00000F00
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_1              0x0000F000
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_2              0x000F0000
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_ISH_3              0x00F00000
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_AUDIO              0x0F000000
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_PMC                0xF0000000
> +#define R_TRACE_HUB_MEM_MTB_SWDEST_2                  0x10
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_FTH                0x0000000F
> +#define R_TRACE_HUB_MEM_MTB_SWDEST_3                  0x14
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_MAESTRO            0x00000F00
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_MIPICAM            0x0F000000
> +#define B_TRACE_HUB_MEM_MTB_SWDEST_AET                0xF0000000
> +#define R_TRACE_HUB_MEM_MTB_SWDEST_4                  0x18
> +#define R_TRACE_HUB_MEM_MTB_MSC0CTL                   0xA0100
> +#define R_TRACE_HUB_MEM_MTB_MSC1CTL                   0xA0200
> +#define V_TRACE_HUB_MEM_MTB_MSCNMODE_DCI              0x2
> +#define V_TRACE_HUB_MEM_MTB_MSCNMODE_DEBUG            0x3
> +#define B_TRACE_HUB_MEM_MTB_MSCNLEN                   (BIT10 | BIT9 |
> BIT8)
> +#define B_TRACE_HUB_MEM_MTB_MSCNMODE                  (BIT5 | BIT4)
> +#define N_TRACE_HUB_MEM_MTB_MSCNMODE                  0x4
> +#define B_TRACE_HUB_MEM_MTB_MSCN_RD_HDR_OVRD          BIT2
> +#define B_TRACE_HUB_MEM_MTB_WRAPENN                   BIT1
> +#define B_TRACE_HUB_MEM_MTB_MSCNEN                    BIT0
> +#define R_TRACE_HUB_MEM_MTB_GTHSTAT                   0xD4
> +#define R_TRACE_HUB_MEM_MTB_SCR2                      0xD8
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FCD                  BIT0
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF2              BIT2
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF3              BIT3
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF4              BIT4
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF5              BIT5
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF6              BIT6
> +#define B_TRACE_HUB_MEM_MTB_SCR2_FSEOFF7              BIT7
> +#define R_TRACE_HUB_MEM_MTB_MSC0BAR                   0xA0108
> +#define R_TRACE_HUB_MEM_MTB_MSC0SIZE                  0xA010C
> +#define R_TRACE_HUB_MEM_MTB_MSC1BAR                   0xA0208
> +#define R_TRACE_HUB_MEM_MTB_MSC1SIZE                  0xA020C
> +#define R_TRACE_HUB_MEM_MTB_STREAMCFG1                0xA1000
> +#define R_TRACE_HUB_MEM_MTB_SCR                       0xC8
> +#define R_TRACE_HUB_MEM_MTB_GTH_FREQ                  0xCC
> +#define V_TRACE_HUB_MEM_MTB_SCR                       0x00130000
> +#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0           0xE0
> +#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD1           0xE4
> +#define R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD10          0xE40
> +#define R_TRACE_HUB_MEM_MTB_CTPGCS                    0x1C14
> +#define B_TRACE_HUB_MEM_MTB_CTPEN                     BIT0
> +#define V_TRACE_HUB_MEM_MTB_CHLCNT                    0x80
> +#define R_TRACE_HUB_MEM_CSR_MTB_TSUCTRL               0x2000
> +#define B_TRACE_HUB_MEM_CSR_MTB_TSUCTRL_CTCRESYNC     BIT0
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:09   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:09 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add
> Private/Library include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the following header files:
>  * Pch/Include/Private/Library
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNh
> lt.h           |  134 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLi
> b.h          |   97 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBuf
> ferLib.h       |   25 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLi
> b.h          | 1061 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCo
> mmonLib.h      |  288 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
> |  344 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
> |   56 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitComm
> onLib.h        |  100 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpress
> HelpersLib.h |  371 +++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivate
> Lib.h        |  578 +++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCo
> mmonLib.h       |   98 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiComm
> onLib.h         |  366 +++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.
> h            |   25 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib
> .h           |  706 +++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleRes
> etLib.h      |   48 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivat
> eLib.h        |   28 +
>  16 files changed, 4325 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHda
> Nhlt.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHda
> Nhlt.h
> new file mode 100644
> index 0000000000..9d8e34eb0d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHda
> Nhlt.h
> @@ -0,0 +1,134 @@
> +/** @file
> +  Header file for DxePchHdaLib - NHLT structure definitions.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_PCH_HDA_NHLT_H_
> +#define _DXE_PCH_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_DEVICE_TYPE
> +{
> +  HdaNhltDeviceBt   = 0,
> +  HdaNhltDeviceDmic = 1,
> +  HdaNhltDeviceI2s  = 4,
> +  HdaNhltDeviceInvalid
> +};
> +
> +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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelper
> sLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelper
> sLib.h
> new file mode 100644
> index 0000000000..9e0658331f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelper
> sLib.h
> @@ -0,0 +1,97 @@
> +/** @file
> +  Header file for GPIO Helpers Lib implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_HELPERS_LIB_H_
> +#define _GPIO_HELPERS_LIB_H_
> +
> +#include <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
> +  );
> +#endif // _GPIO_HELPERS_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameB
> ufferLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioName
> BufferLib.h
> new file mode 100644
> index 0000000000..a6ab42e4d5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioName
> BufferLib.h
> @@ -0,0 +1,25 @@
> +/** @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) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivate
> Lib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivate
> Lib.h
> new file mode 100644
> index 0000000000..245618ff6d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivate
> Lib.h
> @@ -0,0 +1,1061 @@
> +/** @file
> +  Header file for GpioPrivateLib.
> +  All function in this library is available for PEI, DXE, and SMM,
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_PRIVATE_LIB_H_
> +#define _GPIO_PRIVATE_LIB_H_
> +
> +#include <GpioConfig.h>
> +#include <Library/PchPcrLib.h>
> +
> +//
> +// Structure for native pin data
> +//
> +typedef struct {
> +  GPIO_PAD       Pad;
> +  GPIO_PAD_MODE  Mode;
> +} GPIO_PAD_NATIVE_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
> +
> +//
> +// 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
> +
> +/**
> +  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,GroupUniqueNamesTabl
> e) \
> +  {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
> +  );
> +
> +/**
> +  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 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;
> +  UINT8       GpioGpeDwxVal;
> +} 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 set 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
> +GpioSetPadMode (
> +  IN GPIO_PAD                GpioPad,
> +  IN GPIO_PAD_MODE           PadModeValue
> +  );
> +
> +/**
> +  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 sets SerialIo I2C controller pins into native mode
> +
> +  @param[in]  SerialIoI2cControllerNumber   I2C controller
> +  @param[in]  GpioTermination               GPIO termination type
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSerialIoI2c (
> +  IN  UINT32                  SerialIoI2cControllerNumber,
> +  IN  GPIO_ELECTRICAL_CONFIG  GpioTermination
> +  );
> +
> +/**
> +  This function sets SerialIo UART controller pins into native mode
> +
> +  @param[in]  SerialIoUartControllerNumber   UART controller
> +  @param[in]  HardwareFlowControl            Hardware Flow control
> +  @param[in]  PinMuxing                      UART controller pin muxing
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSerialIoUart (
> +  IN  UINT32            SerialIoUartControllerNumber,
> +  IN  BOOLEAN           HardwareFlowControl,
> +  IN  UINT32            PinMuxing
> +  );
> +
> +/**
> +  This function sets SerialIo SPI controller pins into native mode
> +
> +  @param[in]  SerialIoSpiControllerNumber   SPI controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSerialIoSpi (
> +  IN  UINT32            SerialIoSpiControllerNumber
> +  );
> +
> +/**
> +  This function sets ISH I2C controller pins into native mode
> +
> +  @param[in]  IshI2cControllerNumber   I2C controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshI2c (
> +  IN  UINT32            IshI2cControllerNumber
> +  );
> +
> +/**
> +  This function sets ISH UART controller pins into native mode
> +
> +  @param[in]  IshUartControllerNumber   UART controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshUart (
> +  IN  UINT32            IshUartControllerNumber
> +  );
> +
> +/**
> +  This function sets ISH SPI controller pins into native mode
> +
> +  @param[in]  IshSpiControllerNumber   SPI controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshSpi (
> +  IN  UINT32            IshSpiControllerNumber
> +  );
> +
> +/**
> +  This function sets ISH GP pin into native mode
> +
> +  @param[in]  IshGpPinNumber   ISH GP pin number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshGpPin (
> +  IN  UINT32            IshGpPinNumber
> +  );
> +
> +/**
> +  This function sets SCS SD card controller pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableScsSdCard (
> +  VOID
> +  );
> +
> +/**
> +  This function enables SCS SD Card controller card detect pin
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableScsSdCardDetect (
> +  VOID
> +  );
> +
> +/**
> +  This function sets SCS eMMC controller pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableScsEmmc (
> +  VOID
> +  );
> +
> +/**
> +  This function sets HDA Link pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaLink (
> +  VOID
> +  );
> +
> +/**
> +  This function sets HDA DMIC pins into native mode
> +
> +  @param[in]  DmicNumber   DMIC number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaDmic (
> +  IN  UINT32            DmicNumber
> +  );
> +
> +/**
> +  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]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaSspMasterClock (
> +  VOID
> +  );
> +
> +/**
> +  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 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 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 sets SATA DevSlp pins into native mode
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +  @param[in]  SataPort            SATA port number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSataDevSlpPin (
> +  IN  UINT32  SataCtrlIndex,
> +  IN  UINTN   SataPort
> +  );
> +
> +/**
> +  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]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSataLed (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +//
> +// DDSP_HPD pins
> +//
> +typedef enum {
> +  GpioDdspHpd0 = 0x00,
> +  GpioDdspHpd1 = 0x01,
> +  GpioDdspHpd2 = 0x02,
> +  GpioDdspHpd3 = 0x03,
> +  GpioDdspHpd4 = 0x04,
> +  GpioDdspHpdA = 0x10,
> +  GpioDdspHpdB = 0x11,
> +  GpioDdspHpdC = 0x12
> +} GPIO_DDSP_HPD;
> +
> +/**
> +  This function sets DDSP_HPDx pin into native mode
> +
> +  @param[in]  DdspHpdPin     DDSP_HPDx pin
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableDpHotPlugDetect (
> +  IN GPIO_DDSP_HPD  DdspHpdPin
> +  );
> +
> +/**
> +  This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode
> for eDP Panel
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableEdpPins (
> +  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
> +  );
> +
> +/**
> +  This function configures GPIO connection between CNVi and CRF
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviCrfConnection (
> +  VOID
> +  );
> +
> +/**
> +  This function enables CNVi RF Reset pin
> +**/
> +VOID
> +GpioEnableCnviRfResetPin (
> +  VOID
> +  );
> +
> +/**
> +  This function enables CNVi MODEM CLKREQ pin
> +**/
> +VOID
> +GpioEnableCnviModemClkReqPin (
> +  VOID
> +  );
> +
> +/**
> +  CNVi Bluetooth UART connection options
> +**/
> +typedef enum {
> +  GpioCnviBtUartNotConnected,
> +  GpioCnviBtUartToSerialIoUart0,
> +  GpioCnviBtUartToIshUart0,
> +  GpioCnviBtUartToExternalPads
> +} VGPIO_CNVI_BT_UART_CONNECTION_TYPE;
> +
> +/**
> +  This function configures virtual GPIO connection for CNVi Bluetooth UART
> +
> +  @param[in]  ConnectionType
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviBtUartConnection (
> +  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType
> +  );
> +
> +/**
> +  CNVi Bluetooth I2S connection options
> +**/
> +typedef enum {
> +  GpioCnviBtI2sNotConnected,
> +  GpioCnviBtI2sToSsp0,
> +  GpioCnviBtI2sToSsp1,
> +  GpioCnviBtI2sToSsp2,
> +  GpioCnviBtI2sToExternalPads
> +} VGPIO_CNVI_BT_I2S_CONNECTION_TYPE;
> +
> +/**
> +  This function configures virtual GPIO connection for CNVi Bluetooth I2S
> +
> +  @param[in]  ConnectionType
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviBtI2sConnection (
> +  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType
> +  );
> +
> +/**
> +  CNVi MultiFunction UART connection options
> +**/
> +typedef enum {
> +  GpioCnviMfUart1NotConnected,
> +  GpioCnviMfUart1ToSerialIoUart2,
> +  GpioCnviMfUart1ToIshUart0,
> +  GpioCnviMfUart1ToExternalPads
> +} VGPIO_CNVI_MF_UART1_CONNECTION_TYPE;
> +
> +/**
> +  This function configures virtual GPIO connection for CNVi MFUART1
> +
> +  @param[in]  ConnectionType
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviMfUart1Connection (
> +  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType
> +  );
> +
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  CNVi Bluetooth UART connection options
> +**/
> +typedef enum {
> +  GpioCnviBtIfUart = 0,
> +  GpioCnviBtIfUsb,
> +} VGPIO_CNVI_BT_INTERFACE;
> +
> +/**
> +  This function sets CNVi Bluetooth main host interface
> +
> +  @param[in] BtInterface          CNVi BT Interface Select value
> +                                  GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioSetCnviBtInterface (
> +  IN  VGPIO_CNVI_BT_INTERFACE  BtInterface
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  CNVi WiFi mode
> +**/
> +typedef enum {
> +  GpioCnviWiFiEnabled,
> +  GpioCnviWiFiAuto
> +} VGPIO_CNVI_WIFI_MODE;
> +
> +/**
> +  This function sets CNVi WiFi mode
> +
> +  @param[in] Value                CNVi WiFi Mode value
> +                                  GpioCnviWiFiAuto: WiFi is automatically
> enabled/disabled by WiFi core
> +                                  GpioCnviWiFiEnabled: WiFi is enabled regardless of
> WiFi core decision
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioSetCnviWifiMode (
> +  IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
> +  );
> +
> +/**
> +  This function enables IMGU CLKOUT native pin
> +
> +  @param[in] None
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableImguClkOut (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Configure LPC GPIO
> +**/
> +VOID
> +LpcConfigureGpio (
> +  VOID
> +  );
> +
> +#endif // _GPIO_PRIVATE_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterC
> ommonLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterC
> ommonLib.h
> new file mode 100644
> index 0000000000..a4bd42f420
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterC
> ommonLib.h
> @@ -0,0 +1,288 @@
> +/** @file
> + Implement the I2C port control.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _I2C_MASTER_COMMON_LIB_H_
> +#define _I2C_MASTER_COMMON_LIB_H_
> +
> +///
> +/// Each I2C port instance uses an I2C_MASTER_CONTEXT structure
> +/// to maintain its context.
> +///
> +typedef struct {
> +  EFI_I2C_CONTROLLER_CAPABILITIES Capabilities;
> +  //
> +  // I2C master's mmio addresses cached to speed up operation
> +  //
> +  UINTN                           MmioAddress;
> +  UINTN                           ConfigAddress;
> +  //
> +  // copy of all pointers and data provided in StartRequest call
> +  // if transfer didn't finish in one go, those will be needed to continue it
> +  //
> +  EFI_I2C_REQUEST_PACKET          *Request;
> +  //
> +  // Internal copy of Transfer status, to be returned from StartRequest()
> +  //
> +  EFI_STATUS                      TransferStatus;
> +  //
> +  // Index (Operation:Postition in Buffer) of next operation to be performed
> +  // Write is for both R/W operations as both need to be put in fifo
> +  // Read is for Read only, for filling buffer with data retrieved from bus
> +  //
> +  UINTN                           WriteOp;
> +  UINTN                           WritePos;
> +  UINTN                           ReadOp;
> +  UINTN                           ReadPos;
> +  BOOLEAN                         TransferInProgress;
> +} I2C_MASTER_CONTEXT;
> +
> +/**
> +  Prepare I2c controller for use: enable its mmio range, put in D0, get out of
> reset
> +  Verifies I2C Line SDA and SCL states
> +
> +  @param[in] Context - driver context
> +
> +  @retval EFI_SUCCESS         Controller prepared
> +  @retval EFI_DEVICE_ERROR    SCL and/or SDA lines are not pulled up
> +**/
> +EFI_STATUS
> +PrepareController (
> +  I2C_MASTER_CONTEXT  *Context
> +  );
> +
> +/**
> +  Determine the state of the I2C controller
> +
> +  @param[in] Context - driver context
> +
> +  @retval TRUE              The I2C controller is active
> +  @retval FALSE             The I2C controller is idle
> +**/
> +BOOLEAN
> +IsHardwareActive (
> +  I2C_MASTER_CONTEXT  *Context
> +  );
> +
> +/**
> +  Updates WriteOperation and WritePosition, two variables that determine
> +  which part of Request is being committed to I2C bus.
> +  This iterates over both Read and Write operations from a request, because
> +  things that need to be written to WriteFifo are both I2c bus writes
> +  and I2c bus reads (the command to perform bus read needs to be put into
> Write Fifo)
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +UpdateWritePosition (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  FindReadOp checks if current Operation is of Read type. If so, returns.
> +  If not, increases ReadOp until it finds one or goes beyond Request's
> OperationCount
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +FindReadOp (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  Updates ReadOperation and ReadPosition, two variables that determine
> +  which part of Request is being filled with data incoming from I2C reads.
> +  This iterates only over Read operations from a request.
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +UpdateReadPosition (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  ValidateRequest checks if Request is valid and can be started
> +
> +  @param[in] Context            driver context
> +  @param[in] RequestPacket      content of I2C request package
> +
> +  @retval EFI_SUCCESS           Request is valid and can be started
> +  @retval EFI_ALREADY_STARTED   The controller is busy with another
> transfer
> +  @retval EFI_BAD_BUFFER_SIZE   Transfer size too big
> +  @retval EFI_INVALID_PARAMETER RequestPacket is NULL, invalid Operation
> flags
> +  @retval EFI_UNSUPPORTED       10bit I2C address or "ping" operation
> attempted (0-byte transfer, address byte not followed by any data)
> +**/
> +EFI_STATUS
> +ValidateRequest (
> +  I2C_MASTER_CONTEXT           *Context,
> +  CONST EFI_I2C_REQUEST_PACKET *RequestPacket
> +  );
> +
> +/**
> +  IsLastFromRequest checks if WritePos and WriteOp point to the last byte of
> the request
> +
> +  @param[in] Context - driver context
> +**/
> +BOOLEAN
> +IsLastFromRequest (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  IsLastFromRequest checks if WritePos and WriteOp point to the first byte of
> an operation
> +
> +  @param[in] Context - driver context
> +
> +  @retval Boolean
> +**/
> +BOOLEAN
> +IsFirstFromOperation (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  InitializeTransfer checks if HW is ready to accept new transfer.
> +  If so, sets up slave address
> +
> +  @param[in] Context - driver context
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +InitializeTransfer (
> +  I2C_MASTER_CONTEXT           *Context,
> +  UINTN                        SlaveAddress,
> +  CONST EFI_I2C_REQUEST_PACKET *RequestPacket
> +  );
> +
> +/**
> +  WriteFifo writes to I2c controller's transmit Fifo. Data written to Fifo could
> be
> +  - data bytes to be written to an I2C slave
> +  - read requests that trigger I2C bus reads
> +  First transfer from each operation adds Restart bit which triggers Restart
> condition on bus
> +  Last transfer from the whole Request adds Stop bit which triggers Stop
> condtion on bus
> +  Driver keeps track of which parts of Request were already committed to
> hardware using
> +  pointer consisting of WritePosition and WriteOperation variables. This
> pointer is updated
> +  every time data byte/read request is committed to FIFO
> +  WriteFifo executes while there's anything more to write and the write fifo
> isn't full
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +WriteFifo (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  ReadFifo reads from I2c controller's receive Fifo. It contains data retrieved
> +  from slave device as a result of executing read transfers, which were
> +  triggered by putting read requests into Write Fifo. Retrieved data is copied
> into buffers
> +  pointed to by Request structure.
> +  Driver keeps track where to copy incoming data using pointer consisting of
> +  ReadPosition and ReadOperation variables. This pointer is updated
> +  every time data was retrieved from hardware
> +  ReadFifo executes while there's data available and receive buffers were not
> filled
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +ReadFifo (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  CheckErrors checks if there were any transfer errors.
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +CheckErrors (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  Transfer is finished when all requested operations were placed in fifo,
> +  all read requests were filled and hardware is inactive
> +  The last part is necessary for write-only transfers where after
> +  placing all writes in fifo sw needs to wait until they flush down the bus
> +
> +  @param[in] Context - driver context
> +
> +  @retval Boolean
> +**/
> +BOOLEAN
> +IsTransferFinished (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  Clean up Hw activity and errors
> +  Return status to Request's submitter and signal the event that tells
> +  it that the request is complete
> +  Clear up Sw context to allow new request to start
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +FinishTransfer (
> +  I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  PerformTransfer. For synchronous transfer this function is called in a loop
> +  and for asynchronous transfers, as a timer callback. It writes data and/or
> +  read requests to hadrware, copies read data to destination buffers. When
> +  transfer completes, it cleans up Sw context and Hw registers in preparation
> +  for new transfer
> +
> +  @param[in] Context - driver context
> +**/
> +VOID
> +PerformTransfer (
> +  IN I2C_MASTER_CONTEXT *Context
> +  );
> +
> +/**
> +  Set the I2C controller bus clock frequency.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +
> +  The software and controller do a best case effort of using the specified
> +  frequency for the I2C bus.  If the frequency does not match exactly then
> +  the controller will use lower frequency for the I2C to avoid exceeding
> +  the operating conditions for any of the I2C devices on the bus.
> +  For example if 400 KHz was specified and the controller's divide network
> +  only supports 402 KHz or 398 KHz then the controller would be set to 398
> +  KHz.
> +
> +  @param[in] MmioAddress    Address of I2C controller
> +  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
> +
> +  @retval EFI_SUCCESS       The bus frequency was set successfully.
> +  @retval EFI_UNSUPPORTED   The controller does not support this
> frequency.
> +**/
> +
> +EFI_STATUS
> +FrequencySet (
> +  IN UINTN     MmioAddress,
> +  IN OUT UINTN *BusClockHertz
> +  );
> +
> +/**
> +  Reset the I2C controller
> +
> +  @param[in] MmioAddress    Address of I2C controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +I2cReset (
> +  IN UINTN     MmioAddress
> +  );
> +
> +#endif // _I2C_MASTER_COMMON_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.
> h
> new file mode 100644
> index 0000000000..d17b65c598
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.
> h
> @@ -0,0 +1,344 @@
> +/** @file
> +  Header file for PchDmiLib.
> +
> +  Copyright (c) 2019 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
> +  );
> +
> +/**
> +  Set ACPI base address decoding in DMI
> +
> +  @param[in] Address                    Address for ACPI base.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiSetAcpiBase (
> +  IN  UINT16                            Address
> +  );
> +
> +/**
> +  Set PWRM base address decoding in DMI
> +
> +  @param[in] Address                    Address for PWRM base.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiSetPwrmBase (
> +  IN  UINT32                            Address
> +  );
> +
> +/**
> +  Set PCH TCO base address decoding in DMI
> +
> +  @param[in] Address                    Address for TCO base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiSetTcoBase (
> +  IN  UINT16                            Address
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Clear PCH LPC/eSPI generic IO range decoding in DMI
> +
> +  @param[in] RangeIndex                 Index of chosen range
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiClearLpcGenIoRange (
> +  IN  UINTN                             RangeIndex
> +  );
> +
> +/**
> +  Clear PCH eSPI CS1# generic IO range decoding in DMI
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiClearEspiCs1GenIoRange (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Set PCH IO port 80h cycle decoding to PCIE root port in DMI
> +
> +  @param[in] RpNumber                   PCIE root port physical number.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +**/
> +EFI_STATUS
> +PchDmiSetIoPort80Decode (
> +  IN  UINTN                             RpNumber
> +  );
> +
> +/**
> +  Set DMI thermal throttling to recommended configuration
> +**/
> +VOID
> +PchDmiSetRecommendedThermalThrottling (
> +  VOID
> +  );
> +
> +//
> +// Thermal Sensor Target Width structure
> +// Look at DMI_THERMAL_SENSOR_TARGET_WIDTH for possible values
> +//
> +typedef struct {
> +  UINT32  ThermalSensor0TargetWidth :3;
> +  UINT32  ThermalSensor1TargetWidth :3;
> +  UINT32  ThermalSensor2TargetWidth :3;
> +  UINT32  ThermalSensor3TargetWidth :3;
> +  UINT32  Rsvd                      :20;
> +} DMI_THERMAL_THROTTLING;
> +
> +/**
> +  Set DMI thermal throttling to custom configuration.
> +  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
> +  DMI Thermal Sensor Autonomous Width Enable.
> +
> +  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
> +**/
> +VOID
> +PchDmiSetCustomThermalThrottling (
> +  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
> +  );
> +
> +/**
> +  Determines where to send the reserved page registers
> +  Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Port
> +  with the destination ID specified in GCS.RPRDID using DMI source decode.
> +**/
> +VOID
> +PchDmiSetReservedPageRegToPcieRootPort (
> +  VOID
> +  );
> +
> +/**
> +  Determines where to send the reserved page registers
> +  DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cycles
> hitting these ranges will
> +  end up in P2SB which will then forward the cycle to LPC or eSPI through IOSF
> Sideband.
> +**/
> +VOID
> +PchDmiSetReservedPageRegToLpc (
> +  VOID
> +  );
> +
> +/**
> +  uCode Patch Region Enable (UPRE). Enables memory access targeting the
> uCode patch region (0xFEF00000 to 0xFEFFFFFF)
> +  to be forwarded to SPI Flash. This can only be set if the boot flash is on SPI.
> +**/
> +VOID
> +PchDmiEnableUCodePatchRegion (
> +  VOID
> +  );
> +
> +/**
> +  Enable PCIe Relaxed Order
> +**/
> +VOID
> +PchDmiEnablePcieRelaxedOrder (
> +  VOID
> +  );
> +
> +/**
> +  This function will switch SAI value to be driven to IOSF Primary Fabric
> +  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
> +  To be used when PCH is paired with CFL CPU.
> +**/
> +VOID
> +PchDmiEnablePostBootSai (
> +  VOID
> +  );
> +
> +/**
> +  This function will do necessary configuration after platform
> +  should have switched to POSTBOOT_SAI. It needs to be called even if
> +  POSTBOOT_SAI was not set.
> +**/
> +VOID
> +PchDmiConfigAfterPostBootSai (
> +  VOID
> +  );
> +
> +/**
> +  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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.
> h
> new file mode 100644
> index 0000000000..e53ed881df
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.
> h
> @@ -0,0 +1,56 @@
> +/** @file
> +  This library provides PCH HD Audio functions.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HDA_LIB_H_
> +#define _PCH_HDA_LIB_H_
> +
> +#include <Private/Library/DxePchHdaNhlt.h>
> +#include <Private/PchHdaEndpoints.h>
> +
> +/**
> +  Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload
> Engine Driver) Configuration Table).
> +
> +  @param[in] *NhltAcpiTable    The NHLT table to print
> +**/
> +VOID
> +NhltAcpiTableDump(
> +  IN NHLT_ACPI_TABLE           *NhltTable
> +  );
> +
> +/**
> +  Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
> +
> +  @param[in][out] *NhltTable            NHLT table for which header will be
> created
> +  @param[in]      NhltTableSize         Size of NHLT table
> +
> +  @retval None
> +**/
> +VOID
> +NhltAcpiHeaderConstructor (
> +  IN OUT NHLT_ACPI_TABLE        *NhltTable,
> +  IN UINT32                     NhltTableSize
> +  );
> +
> +/**
> +  Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
> +
> +  @param[in]      *EndpointTable List of endpoints for NHLT
> +  @param[in][out] **NhltTable    NHLT table to be created
> +  @param[in][out] *NhltTableSize Size of created NHLT table
> +
> +  @retval EFI_SUCCESS            NHLT created successfully
> +  @retval EFI_BAD_BUFFER_SIZE    Not enough resources to allocate NHLT
> +**/
> +EFI_STATUS
> +NhltConstructor(
> +  IN PCH_HDA_NHLT_ENDPOINTS    *EndpointTable,
> +  IN OUT NHLT_ACPI_TABLE       **NhltTable,
> +  IN OUT UINT32                *NhltTableSize
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCom
> monLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCom
> monLib.h
> new file mode 100644
> index 0000000000..6d71504772
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCom
> monLib.h
> @@ -0,0 +1,100 @@
> +/** @file
> +  Header file for PCH Init Common Lib
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_INIT_COMMON_LIB_H_
> +#define _PCH_INIT_COMMON_LIB_H_
> +
> +#include <Library/PchPcrLib.h>
> +
> +/**
> +  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] RpPort             Root Port Number
> +
> +  @retval PCH_SBI_PID    Returns PID for SBI Access
> +**/
> +PCH_SBI_PID
> +GetRpSbiPid (
> +  IN  UINTN  RpPort
> +  );
> +
> +/**
> +  Calculate root port device number based on physical port index.
> +
> +  @param[in]  RpIndex              Root port index (0-based).
> +
> +  @retval     Root port device number.
> +**/
> +UINT32
> +PchGetPcieRpDevice (
> +  IN  UINT32   RpIndex
> +  );
> +
> +/**
> +  This function reads Pci Config register via SBI Access
> +
> +  @param[in]  RpIndex             Root Port Index (0-based)
> +  @param[in]  Offset              Offset of Config register
> +  @param[out] *Data32             Value of Config register
> +
> +  @retval EFI_SUCCESS             SBI Read successful.
> +**/
> +EFI_STATUS
> +PchSbiRpPciRead32 (
> +  IN    UINT32  RpIndex,
> +  IN    UINT32  Offset,
> +  OUT   UINT32  *Data32
> +  );
> +
> +/**
> +  This function And then Or Pci Config register via SBI Access
> +
> +  @param[in]  RpIndex             Root Port Index (0-based)
> +  @param[in]  Offset              Offset of Config register
> +  @param[in]  Data32And           Value of Config register to be And-ed
> +  @param[in]  Data32AOr           Value of Config register to be Or-ed
> +
> +  @retval EFI_SUCCESS             SBI Read and Write successful.
> +**/
> +EFI_STATUS
> +PchSbiRpPciAndThenOr32 (
> +  IN  UINT32  RpIndex,
> +  IN  UINT32  Offset,
> +  IN  UINT32  Data32And,
> +  IN  UINT32  Data32Or
> +  );
> +
> +/**
> +  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
> +PrintRegisters (
> +  IN  UINTN        PrintMmioBase,
> +  IN  UINT32       PrintSize,
> +  IN  UINT32       OffsetFromBase
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpre
> ssHelpersLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpre
> ssHelpersLib.h
> new file mode 100644
> index 0000000000..b0e4eb64c2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpre
> ssHelpersLib.h
> @@ -0,0 +1,371 @@
> +/** @file
> +  Header file for PCH PCI Express helpers library
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_PCI_EXPRESS_HELPERS_LIB_H_
> +#define _PCH_PCI_EXPRESS_HELPERS_LIB_H_
> +
> +#include <PchPolicyCommon.h>
> +
> +typedef enum {
> +  TpoScale2us,
> +  TpoScale10us,
> +  TpoScale100us,
> +  TpoScaleMax
> +} T_PO_SCALE;
> +
> +typedef struct {
> +  UINT32     Value;
> +  T_PO_SCALE Scale;
> +} T_POWER_ON;
> +
> +//
> +// Function prototypes
> +//
> +
> +/**
> +  Get PCIe port number for enabled port.
> +  @param[in] RpBase    Root Port pci segment base address
> +  @return 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
> +  );
> +
> +/**
> +  Translate PCIe Port/Lane pair to 0-based PCIe lane number.
> +
> +  @param[in] RpIndex    Root Port index
> +  @param[in] RpLane     Root Port Lane (0-3)
> +
> +  @retval PCIe lane number (0-based)
> +**/
> +UINT32
> +PchPciePhysicalLane (
> +  UINT32 RpIndex,
> +  UINT32 RpLane
> +  );
> +
> +/**
> +  Checks if lane reversal is enabled on a given root port
> +
> +  @param[in] RpIndex  Root port index (0-based)
> +
> +  @retval TRUE if lane reversal is enbabled, FALSE otherwise
> +**/
> +BOOLEAN
> +IsPcieLaneReversalEnabled (
> +  IN     UINT32  RpIndex
> +  );
> +
> +/**
> +  Calculates the index of the first port on the same controller.
> +
> +  @param[in] RpIndex     Root Port Number (0-based)
> +
> +  @retval Index of the first port on the first controller.
> +**/
> +UINT32
> +PchGetPcieFirstPortIndex (
> +  IN     UINT32  RpIndex
> +  );
> +
> +/*
> +  Returns Tpower_on capability of device
> +
> +  @param[in] DeviceBase       device's PCI segment base address
> +  @param[in] L1ssCapOffset    offset to L1substates capability in device's
> extended config space
> +
> +  @retval                     structure containing Tpoweron scale and value
> +*/
> +T_POWER_ON
> +GetTpoCapability (
> +  UINT64 DeviceBase,
> +  UINT32 L1ssCapOffset
> +  );
> +
> +/*
> +  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
> +  );
> +
> +/**
> +  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
> +
> +  @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] 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
> +*/
> +VOID
> +RetrainLink (
> +  UINT64  Base,
> +  UINT8   PcieCapOffset,
> +  BOOLEAN WaitUntilDone
> +  );
> +
> +/*
> +  Checks if device at given address exists
> +
> +  @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
> +  );
> +
> +/*
> +  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
> +  );
> +
> +/*
> +  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] 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,
> +  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
> +  UINT32                    AspmOverrideTableSize,
> +  PCH_PCIE_DEVICE_OVERRIDE  *AspmOverrideTable
> +  );
> +
> +/**
> +  Get current PCIe link speed.
> +
> +  @param[in] RpBase    Root Port base address
> +  @return Link speed
> +**/
> +UINT32
> +GetLinkSpeed (
> +  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
> +GetMaxLinkSpeed (
> +  UINT64 RpBase
> +  );
> +
> +/**
> +  PCIe controller configuration.
> +**/
> +typedef enum {
> +  Pcie4x1      = 0,
> +  Pcie1x2_2x1  = 1,
> +  Pcie2x2      = 2,
> +  Pcie1x4      = 3
> +} PCIE_CONTROLLER_CONFIG;
> +
> +#endif // _PEI_DXE_SMM_PCH_PCI_EXPRESS_HELPERS_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPriva
> teLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPriva
> teLib.h
> new file mode 100644
> index 0000000000..9e68615717
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPriva
> teLib.h
> @@ -0,0 +1,578 @@
> +/** @file
> +  Header file for PchPsfPrivateLib.
> +
> +  Copyright (c) 2019 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/PchRegsPcr.h>
> +
> +//
> +// 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
> +  );
> +
> +/**
> +  Return PSF_PORT for SerialIO I2C device
> +
> +  @param[in] I2cNum  Serial IO I2C device (I2C0, I2C1, ....)
> +
> +  @retval  PsfPort   PSF PORT structure for SerialIO I2C device
> +**/
> +PSF_PORT
> +PsfSerialIoI2cPort (
> +  IN UINT32  I2cNum
> +  );
> +
> +/**
> +  Return PSF_PORT for SerialIO SPI device
> +
> +  @param[in] SpiNum  Serial IO SPI device (SPI0, SPI1, ....)
> +
> +  @retval  PsfPort   PSF PORT structure for SerialIO SPI device
> +**/
> +PSF_PORT
> +PsfSerialIoSpiPort (
> +  IN UINT32  SpiNum
> +  );
> +
> +/**
> +  Return PSF_PORT for SerialIO UART device
> +
> +  @param[in] UartNum  Serial IO UART device (UART0, UART1, ....)
> +
> +  @retval  PsfPort    PSF PORT structure for SerialIO UART device
> +**/
> +PSF_PORT
> +PsfSerialIoUartPort (
> +  IN UINT32  UartNum
> +  );
> +
> +/**
> +  This procedure will set BARx value for TraceHub ACPI device at PSF level
> +
> +  @param[in] BarNum          BAR Number (0:BAR0, 1:BAR1)
> +  @param[in] BarValue        32bit BAR value
> +**/
> +VOID
> +PsfSetTraceHubAcpiDeviceBarValue (
> +  IN UINT8   BarNum,
> +  IN UINT32  BarValue
> +  );
> +
> +/**
> +  This procedure will enable MSE for TraceHub ACPI device at PSF level
> +**/
> +VOID
> +PsfEnableTraceHubAcpiDeviceMemorySpace (
> +  VOID
> +  );
> +
> +/**
> +  Enable HECI device at PSF level
> +
> +  @param[in] HeciDevice       HECIx Device (HECI1-4)
> +**/
> +VOID
> +PsfEnableHeciDevice (
> +  IN UINT8      HeciDevice
> +  );
> +
> +/**
> +  Disable HECI device at PSF level
> +
> +  @param[in] HeciDevice       HECIx Device (HECI1-4)
> +**/
> +VOID
> +PsfDisableHeciDevice (
> +  IN UINT8      HeciDevice
> +  );
> +
> +/**
> +  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 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 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
> +  );
> +
> +typedef enum {
> +  PsfPcieCtrl4x1,
> +  PsfPcieCtrl1x2_2x1,
> +  PsfPcieCtrl2x2,
> +  PsfPcieCtrl1x4
> +} 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
> +  );
> +
> +/**
> +  Program PSF EOI Multicast configuration for ITSS
> +**/
> +VOID
> +PsfConfigurEoiForItss (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Configure PSF power management.
> +  Must be called after all PSF configuration is completed.
> +**/
> +VOID
> +PsfConfigurePowerManagement (
> +  VOID
> +  );
> +
> +/**
> +  Enable VTd support in PSF.
> +**/
> +VOID
> +PchPsfEnableVtd (
> +  VOID
> +  );
> +
> +/**
> +  Disable PSF address-based peer-to-peer decoding.
> +**/
> +VOID
> +PchPsfDisableP2pDecoding (
> +  VOID
> +  );
> +
> +/**
> +  Perform registers programming required for
> +  Management Component Transport Protocol Broadcast Cycle.
> +
> +  Agent Destination Addresses are being programmed only when adequate
> +  PCIe root port controllers are function enabled.
> +
> +  Function sets CSME PMT as a message broadcaster and programs the targets
> +  of the message in registers only if adequate PCIe root port controllers
> +  are function enabled. Conditionally, if the CPU PEG exist and is function
> +  enabled, DMI is also a target.
> +**/
> +VOID
> +PsfConfigureMctpCycle (
> +  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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusC
> ommonLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusC
> ommonLib.h
> new file mode 100644
> index 0000000000..313b13060f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusC
> ommonLib.h
> @@ -0,0 +1,98 @@
> +/** @file
> +  PCH Smbus Protocol
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SMBUS_COMMON_LIB_H
> +#define _PCH_SMBUS_COMMON_LIB_H
> +
> +//
> +// Definitions
> +//
> +#define SMBUS_NUM_RESERVED          38      ///< Number of device
> addresses that are reserved by the SMBus spec.
> +#define SMBUS_ADDRESS_ARP           0xC2 >> 1
> +#define SMBUS_DATA_PREPARE_TO_ARP   0x01
> +#define SMBUS_DATA_RESET_DEVICE     0x02
> +#define SMBUS_DATA_GET_UDID_GENERAL 0x03
> +#define SMBUS_DATA_ASSIGN_ADDRESS   0x04
> +#define SMBUS_GET_UDID_LENGTH       17      ///< 16 byte UDID + 1 byte
> address
> +//
> +// Private data and functions
> +//
> +
> +#define PCH_SMBUS_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('p', 's', 'm',
> 'b')
> +
> +/**
> +  This function provides a standard way to read PCH Smbus IO registers.
> +
> +  @param[in] Offset               Register offset from Smbus base IO address.
> +
> +  @retval UINT8                   Returns data read from IO.
> +**/
> +UINT8
> +SmbusIoRead (
> +  IN      UINT8           Offset
> +  );
> +
> +/**
> +  This function provides a standard way to write PCH Smbus IO registers.
> +
> +  @param[in] Offset               Register offset from Smbus base IO address.
> +  @param[in] Data                 Data to write to register.
> +
> +**/
> +VOID
> +SmbusIoWrite (
> +  IN      UINT8           Offset,
> +  IN      UINT8           Data
> +  );
> +
> +/**
> +  This function provides a standard way to execute Smbus protocols
> +  as defined in the SMBus Specification. The data can either be of
> +  the Length byte, word, or a block of data. The resulting transaction will be
> +  either the SMBus Slave Device accepts this transaction or this function
> +  returns with an error
> +
> +  @param[in] SlaveAddress         Smbus Slave device the command is
> directed at
> +  @param[in] Command              Slave Device dependent
> +  @param[in] Operation            Which SMBus protocol will be used
> +  @param[in] PecCheck             Defines if Packet Error Code Checking is to be
> used
> +  @param[in, out] Length          How many bytes to read. Must be 0 <=
> Length <= 32 depending on Operation
> +                                  It will contain the actual number of bytes
> read/written.
> +  @param[in, out] Buffer          Contain the data read/written.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @exception EFI_UNSUPPORTED      The operation is unsupported.
> +
> +  @retval EFI_INVALID_PARAMETER   Length or Buffer is NULL for any
> operation besides
> +                                  quick read or quick write.
> +  @retval EFI_TIMEOUT             The transaction did not complete within an
> internally
> +                                  specified timeout period, or the controller is not
> +                                  available for use.
> +  @retval EFI_DEVICE_ERROR        There was an Smbus error (NACK) during
> the operation.
> +                                  This could indicate the slave device is not present
> +                                  or is in a hung condition.
> +**/
> +EFI_STATUS
> +SmbusExec (
> +  IN      EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
> +  IN      EFI_SMBUS_DEVICE_COMMAND  Command,
> +  IN      EFI_SMBUS_OPERATION       Operation,
> +  IN      BOOLEAN                   PecCheck,
> +  IN OUT  UINTN                     *Length,
> +  IN OUT  VOID                      *Buffer
> +  );
> +
> +/**
> +  This function initializes the Smbus Registers.
> +
> +**/
> +VOID
> +InitializeSmbusRegisters (
> +  VOID
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCom
> monLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCom
> monLib.h
> new file mode 100644
> index 0000000000..0a973a77a3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCom
> monLib.h
> @@ -0,0 +1,366 @@
> +/** @file
> +  Header file for the PCH SPI Common Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SPI_COMMON_LIB_H_
> +#define _PCH_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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLi
> b.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiL
> ib.h
> new file mode 100644
> index 0000000000..301ec3dd48
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiL
> ib.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  This file contains PEI DMI methods
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_PCH_DMI_LIB_H_
> +#define _PEI_PCH_DMI_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +//
> +// Data structure definitions
> +//
> +typedef enum {
> +  DmiVcTypeVc0,
> +  DmiVcTypeVc1,
> +  DmiVcTypeVcm,
> +  DmiVcTypeMax
> +} PCH_DMI_VC_TYPE;
> +
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateL
> ib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivate
> Lib.h
> new file mode 100644
> index 0000000000..44e7567e0f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivate
> Lib.h
> @@ -0,0 +1,706 @@
> +/** @file
> +  Header file for private PmcLib.
> +
> +  Copyright (c) 2019 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/PchRegsPmc.h>
> +
> +/**
> +  Send PMC IPC1 Normal Read/Write command
> +
> +  @param[in]  Command           Command to be issued to PMC IPC 1
> interface
> +  @param[in]  SubCmdId          SUB_CMD_ID for provided Command
> +  @param[in]  CmdSize           Total size in byte to be sent via PMC IPC 1
> interface
> +  @param[in]  WriteBufPtr       Pointer to Structure of 4 DWORDs to be
> issued to PMC IPC 1 interface
> +  @param[out] ReadBufPtr        Pointer to Structure of 4 DWORDs to be
> filled by PMC IPC 1 interface
> +
> +  @retval EFI_SUCCESS             Command was executed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid command size
> +  @retval EFI_DEVICE_ERROR        IPC command failed with an error
> +  @retval EFI_TIMEOUT             IPC command did not complete after 1s
> +**/
> +EFI_STATUS
> +PmcSendCommand (
> +  IN  UINT8                    Command,
> +  IN  UINT8                    SubCmdId,
> +  IN  UINT8                    CmdSize,
> +  IN  PMC_IPC_COMMAND_BUFFER   *WriteBufPtr,
> +  OUT PMC_IPC_COMMAND_BUFFER   *ReadBufPtr
> +  );
> +
> +/**
> +  Set PCH ACPI base address.
> +  The Address should not be 0 and should be 256 bytes alignment, and it is IO
> space, so must not exceed 0xFFFF.
> +
> +  @param[in] Address                    Address for ACPI base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +**/
> +EFI_STATUS
> +PmcSetAcpiBase (
> +  IN  UINT16                            Address
> +  );
> +
> +/**
> +  Set PCH PWRM base address.
> +  Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for
> PWRMBASE
> +
> +  @param[in] Address                    Address for PWRM base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PmcSetPwrmBase (
> +  IN  UINT32                            Address
> +  );
> +
> +/**
> +  This function checks if function disable (static and non-static power gating)
> +  configuration is locked
> +
> +  @retval lock state
> +**/
> +BOOLEAN
> +PmcIsFunctionDisableConfigLocked (
> +  VOID
> +  );
> +
> +/**
> +  This function locks static power gating configuration with S3 Boot Script
> programming
> +**/
> +VOID
> +PmcLockFunctionDisableConfigWithS3BootScript (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if ISH is function disabled
> +  by static power gating
> +
> +  @retval ISH device state
> +**/
> +BOOLEAN
> +PmcIsIshFunctionDisabled (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if ISH device is supported (not disabled by fuse)
> +
> +  @retval ISH support state
> +**/
> +BOOLEAN
> +PmcIsIshSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function disables ISH device by static power gating
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableIsh (
> +  VOID
> +  );
> +
> +/**
> +  This function enables ISH device by disabling static power gating
> +**/
> +VOID
> +PmcEnableIsh (
> +  VOID
> +  );
> +
> +/**
> +  This function enables GBE ModPHY SPD gating.
> +**/
> +VOID
> +PmcGbeModPhyPowerGating (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if GbE is function disabled
> +  by static power gating
> +
> +  @retval GbE device state
> +**/
> +BOOLEAN
> +PmcIsGbeFunctionDisabled (
> +  VOID
> +  );
> +
> +/**
> +  This function disables GbE device by static power gating
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableGbe (
> +  VOID
> +  );
> +
> +/**
> +  This function enables GbE device by disabling static power gating
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableGbe (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if GbE device is supported (not disabled by fuse)
> +
> +  @retval GbE support state
> +**/
> +BOOLEAN
> +PmcIsGbeSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function enables all SerailIo devices
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableSerialIo (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (static power gating) all SerailIo devices.
> +  For SerialIo controllers they can be power gated only if all of them are to be
> disabled.
> +  They cannot be statically power gated separately.
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableSerialIo (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if all SerialIo devices are statically disabled (static
> power gating)
> +
> +  @retval SerialIo disable state
> +**/
> +BOOLEAN
> +PmcIsSerialIoStaticallyDisabled (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if SerialIo device is supported (not disabled by fuse)
> +
> +  @retval SerialIo support state
> +**/
> +BOOLEAN
> +PmcIsSerialIoSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (non-static power gating) HDA device
> +**/
> +VOID
> +PmcDisableHda (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if Cnvi device is supported (not disabled by fuse)
> +
> +  @retval Cnvi support state
> +**/
> +BOOLEAN
> +PmcIsCnviSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if CNVi is function disabled
> +  by static power gating
> +
> +  @retval GbE device state
> +**/
> +BOOLEAN
> +PmcIsCnviFunctionDisabled (
> +  VOID
> +  );
> +
> +/**
> +  This function enables CNVi device by disabling static power gating.
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableCnvi (
> +  VOID
> +  );
> +
> +/**
> +  This function disables CNVi device by static power gating
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableCnvi (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (non-static power gating) PCIe Root Port
> +
> +  @param[in] RpIndex        PCIe Root Port Index (0 based)
> +**/
> +VOID
> +PmcDisablePcieRootPort (
> +  IN UINT32  RpIndex
> +  );
> +
> +/**
> +  This function disables (non-static power gating) SATA
> +
> +  @param[in]  SataCtrlIndex     SATA controller index
> +**/
> +VOID
> +PmcDisableSata (
> +  IN UINT32     SataCtrlIndex
> +  );
> +
> +/**
> +  This function checks if SATA device is supported (not disabled by fuse)
> +
> +  @param[in] SataCtrlIndex SATA controller index
> +
> +  @retval SATA support state
> +**/
> +BOOLEAN
> +PmcIsSataSupported (
> +  IN UINT32  SataCtrlIndex
> +  );
> +
> +/**
> +  This function gets NMI regsiter.
> +
> +  @retval  NMI register setting
> +**/
> +UINT32
> +PmcGetNmiControl (
> +  VOID
> +  );
> +
> +/**
> +  This function sets the NMI register
> +
> +  @param[in]  NmiRegister    The whole NMI register
> +**/
> +VOID
> +PmcSetNmiControl (
> +  UINT32   NmiRegister
> +  );
> +
> +/**
> +  This function disables (non-static power gating) xHCI
> +**/
> +VOID
> +PmcDisableXhci (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (non-static power gating) XDCI
> +**/
> +VOID
> +PmcDisableXdci (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if XDCI device is supported (not disabled by fuse)
> +
> +  @retval XDCI support state
> +**/
> +BOOLEAN
> +PmcIsXdciSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (non-static power gating) SCS eMMC controller and
> enables ModPHY SPD gating (PCH-LP only).
> +**/
> +VOID
> +PmcDisableScsEmmc (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (non-static power gating) SCS SD Card controller and
> enables ModPHY SPD gating (PCH-LP only).
> +**/
> +VOID
> +PmcDisableScsSdCard (
> +  VOID
> +  );
> +
> +/**
> +  This function disables (non-static power gating) SCS UFS controller and
> enables ModPHY SPD gating (PCH-LP only).
> +
> +  @param[in] UfsNum     SCS UFS Device
> +**/
> +VOID
> +PmcDisableScsUfs (
> +  IN UINT32   UfsNum
> +  );
> +
> +/**
> +  This function checks if SCS eMMC device is supported (not disabled by fuse)
> +
> +  @retval SCS device support state
> +**/
> +BOOLEAN
> +PmcIsScsEmmcSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if SCS SD Card device is supported (not disabled by fuse)
> +
> +  @retval SCS device support state
> +**/
> +BOOLEAN
> +PmcIsScsSdCardSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if SCS UFS device is supported (not disabled by fuse)
> +
> +  @param[in] UfsNum     SCS UFS Device
> +
> +  @retval SCS device support state
> +**/
> +BOOLEAN
> +PmcIsScsUfsSupported (
> +  IN UINT32   UfsNum
> +  );
> +
> +
> +/**
> +  This function locks HOST SW power gating control
> +**/
> +VOID
> +PmcLockHostSwPgCtrl (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if HOST SW Power Gating Control is locked
> +
> +  @retval lock state
> +**/
> +BOOLEAN
> +PmcIsHostSwPgCtrlLocked (
> +  VOID
> +  );
> +
> +/**
> +  This function disables Trace Hub by enabling power gating
> +**/
> +VOID
> +PmcDisableTraceHub (
> +  VOID
> +  );
> +
> +/**
> +  This function enables Trace Hub by disabling power gating
> +**/
> +VOID
> +PmcEnableTraceHub (
> +  VOID
> +  );
> +
> +/**
> +  This function checks if LAN wake from DeepSx is enabled
> +
> +  @retval Lan Wake state
> +**/
> +BOOLEAN
> +PmcIsLanDeepSxWakeEnabled (
> +  VOID
> +  );
> +
> +/**
> +  This function locks down PMC (DebugModeLock)
> +**/
> +VOID
> +PmcLockWithS3BootScript (
> +  VOID
> +  );
> +
> +/**
> +  Checks if conditions for proper USB2 PHY AFE programming are met
> +**/
> +VOID
> +PmcUsb2CorePhyPowerGatingDisable (
> +  VOID
> +  );
> +
> +/**
> +  This function reads CPU Early Power-on Configuration (EPOC)
> +
> +  @retval CPU EPOC value
> +**/
> +UINT32
> +PmcGetCpuEpoc (
> +  VOID
> +  );
> +
> +/**
> +  This function sets CPU Early Power-on Configuration (EPOC)
> +
> +  @param[in] CpuEpocValue      CPU EPOC value
> +**/
> +VOID
> +PmcSetCpuEpoc (
> +  IN UINT32     CpuEpocValue
> +  );
> +
> +/**
> +  This function sets DRAM_RESET# Control Pin value
> +
> +  @param[in] DramResetVal      0: Pin output is low
> +                               1: Pin output is tri-stated
> +**/
> +VOID
> +PmcSetDramResetCtlState (
> +  IN UINT32     DramResetVal
> +  );
> +
> +/**
> +  This function enables triggering Global Reset of both
> +  the Host and the ME partitions after CF9h write of 6h or Eh
> +**/
> +VOID
> +PmcEnableCf9GlobalReset (
> +  VOID
> +  );
> +
> +/**
> +  This function disables triggering Global Reset of both
> +  the Host and the ME partitions after CF9h write of 6h or Eh.
> +**/
> +VOID
> +PmcDisableCf9GlobalReset (
> +  VOID
> +  );
> +
> +/**
> +  This 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
> +PmcDisableCf9GlobalResetWithLock (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  This function disables CF9 reset without Resume Well reset.
> +  Cf9 0x6/0xE reset will also reset resume well logic.
> +**/
> +VOID
> +PmcDisableCf9ResetWithoutResumeWell (
> +  VOID
> +  );
> +
> +/**
> +  This function locks PMC Set Strap Message interface with S3 Boot Script
> programming
> +**/
> +VOID
> +PmcLockSetStrapMsgInterfaceWithS3BootScript (
> +  VOID
> +  );
> +
> +/**
> +  This function clears RTC Power Failure status (RTC_PWR_FLR)
> +**/
> +VOID
> +PmcClearRtcPowerFailureStatus (
> +  VOID
> +  );
> +
> +/**
> +  This function enables PCI Express* PME events
> +**/
> +VOID
> +PmcEnablePciExpressPmeEvents (
> +  VOID
> +  );
> +
> +/**
> +  This function sets SLP_SX Stretching Policy and adds
> +  lock setting to S3 Boot Script
> +**/
> +VOID
> +PmcLockSlpSxStretchingPolicyWithS3BootScript (
> +  VOID
> +  );
> +
> +/**
> +  This function sets SMI Lock with S3 Boot Script programming
> +**/
> +VOID
> +PmcLockSmiWithS3BootScript (
> +  VOID
> +  );
> +
> +/**
> +  This function sets eSPI SMI Lock
> +**/
> +VOID
> +PmcLockEspiSmi (
> +  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
> +  );
> +
> +/**
> +  This function sets 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
> +PmcSetGpioGpe (
> +  IN UINT32    GpeDw0Value,
> +  IN UINT32    GpeDw1Value,
> +  IN UINT32    GpeDw2Value
> +  );
> +
> +/**
> +  This function checks if SCI interrupt is enabled
> +
> +  @retval SCI Enable state
> +**/
> +BOOLEAN
> +PmcIsSciEnabled (
> +  VOID
> +  );
> +
> +/**
> +  This function triggers Software GPE
> +**/
> +VOID
> +PmcTriggerSwGpe (
> +  VOID
> +  );
> +
> +/**
> +  Disable SLP_S0# assertion when system is in debug mode
> +**/
> +VOID
> +PmcDisableSlpS0AssertionInDebugMode (
> +  VOID
> +  );
> +
> +/**
> +  Enable SLP_S0# assertion even when system is in debug mode
> +**/
> +VOID
> +PmcEnableSlpS0AssertionInDebugMode (
> +  VOID
> +  );
> +
> +#endif // _PMC_PRIVATE_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleR
> esetLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiSchedule
> ResetLib.h
> new file mode 100644
> index 0000000000..af5734b74b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiSchedule
> ResetLib.h
> @@ -0,0 +1,48 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPri
> vateLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPri
> vateLib.h
> new file mode 100644
> index 0000000000..f074e0073a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPri
> vateLib.h
> @@ -0,0 +1,28 @@
> +/** @file
> +  Header file for private PCH SMM Lib.
> +
> +  Copyright (c) 2019 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_
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:10   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:10 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add
> Private/Protocol include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the following header files:
>  * Pch/Include/Private/Protocol
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.
> h | 31 ++++++++++++++++
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h
> | 37 ++++++++++++++++++++
>  2 files changed, 68 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsAr
> ea.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsAr
> ea.h
> new file mode 100644
> index 0000000000..75003c82ad
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/Pc
> +++ hNvsArea.h
> @@ -0,0 +1,31 @@
> +/** @file
> +  This file defines the PCH NVS Area Protocol.
> +
> +  Copyright (c) 2019 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 <Private/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/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap
> .h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap
> .h
> new file mode 100644
> index 0000000000..2cd6b85d29
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/Pc
> +++ ieIoTrap.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  This file defines the PCH PCIE IoTrap Protocol.
> +
> +  Copyright (c) 2019 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 {
> +  PciePmTrap,
> +  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
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
@ 2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:12 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add
> Private include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the following header files:
>  * Pch/Include/Private
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
> |  16 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
> | 273 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
> | 115 +++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h            |
> 92 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
> | 269 +++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h          |
> 58 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.
> h |  25 ++
>  7 files changed, 848 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
> new file mode 100644
> index 0000000000..6c9d10e928
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
> @@ -0,0 +1,16 @@
> +/** @file
> +    CnlPchLp Dx HSIO Header File
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CNL_PCH_LP_HSIO_DX_H_
> +#define _CNL_PCH_LP_HSIO_DX_H_
> +
> +#define CNL_PCH_LP_HSIO_VER_DX   0x7
> +
> +
> +extern UINT8                      CnlPchLpChipsetInitTable_Dx[5072];
> +extern UINT8                      CnlPchLpChipsetInitTable_eDBC_Dx[4612];
> +#endif //_CNL_PCH_LP_HSIO_DX_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
> new file mode 100644
> index 0000000000..5569da670d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
> @@ -0,0 +1,273 @@
> +/** @file
> +  The GUID definition for PchConfigHob
> +
> +  Copyright (c) 2019 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 <ConfigBlock/SmbusConfig.h>
> +#include <ConfigBlock/InterruptConfig.h>
> +#include <ConfigBlock/PcieRpConfig.h>
> +#include <ConfigBlock/SataConfig.h>
> +#include <ConfigBlock/FlashProtectionConfig.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];
> +  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 describes interrupt settings for PCH HOB.
> +///
> +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
> +  UINT8                        PxRcConfig[PCH_MAX_PXRC_CONFIG];
> ///< PCI interrupt routing for 8259 PIC controller
> +} INTERRUPT_HOB;
> +
> +///
> +/// The CNVI_HOB block describes CNVi device.
> +///
> +typedef struct {
> +  UINT32 Mode                      :  1;         ///< 0: Disabled, <b>1: Auto</b>
> +  UINT32 RsvdBits0                 : 31;
> +} CNVI_HOB;
> +
> +/**
> +  The SERIAL_IO block provides the configurations to set the Serial IO
> controllers
> +**/
> +typedef struct {
> +  /**
> +       0: Disabled;
> +          - Device is placed in D3
> +          - Gpio configuration is skipped
> +          - Device will be disabled in PSF
> +          - !important! If given device is Function 0 and not all other LPSS
> functions on given device
> +                        are disabled, then 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: Pci</b>;
> +          - Gpio pin configuration in native mode for each assigned pin
> +            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
> +          - Device will be enabled in PSF
> +          - Only Bar 0 will be enabled
> +       2: Acpi;
> +          - Gpio pin configuration in native mode for each assigned pin
> +            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
> +          - Device will be hidden in PSF and not available to PCI enumerator
> +          - Both BARs are enabled, BAR1 becomes devices Pci config Space
> +    @note Intel does not provide Windows SerialIo drivers for this mode
> +       3: Hidden;
> +          Designated for Kernel Debug and Legacy UART configuartion, might
> also be used for IO Expander on I2C
> +          - Device is placed in D0
> +          - Gpio pin configuration in native mode for each assigned pin
> +            RX/TX or RX/TX/CTS/RTS in case of UART depending UartHwFlowCtrl
> +          - Device will be hidden in PSF and not available to PCI enumerator
> +          - Both BARs are enabled, BAR1 becomes devices Pci config Space
> +          - !important! In this mode UART will work in 16550 Legacy 8BIT Mode,
> it's resources will be assigned to mother board through ACPI (PNP0C02)
> +    @note Considering the PcdSerialIoUartDebugEnable and
> PcdSerialIoUartNumber for all SerialIo UARTx,
> +          the PCD is more meaningful to represent the board design. It means,
> if PcdSerialIoUartDebugEnable is not 0,
> +          the board is designed to use the SerialIo UART for debug message and
> the PcdSerialIoUartNumber is dedicated
> +          to be Debug UART usage. Therefore, it should grayout the option from
> setup menu since no other options
> +          available for this UART controller on this board, and also override the
> policy default accordingly.
> +          While PcdSerialIoUartDebugEnable is 0, then it's allowed to configure
> the UART controller by policy.
> +  **/
> +  UINT8  DevMode[PCH_MAX_SERIALIO_CONTROLLERS];
> +  UINT32 DebugUartNumber           :  2;                    ///< UART number for
> debug purpose. 0:UART0, 1: UART1, <b>2:UART2</b>
> +  UINT32 EnableDebugUartAfterPost  :  1;                    ///< Enable debug
> UART controller after post. 0: disabled, <b>1: enabled</b>
> +  UINT32 RsvdBits0                 : 29;
> +} SERIAL_IO_HOB;
> +
> +
> +///
> +/// The PCH_PCIE_CONFIG 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];
> +  /**
> +    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;
> +} PCIERP_HOB;
> +
> +typedef struct {
> +  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1:
> Enable</b>
> +  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  RsvdBits0             : 26;    ///< Reserved bits
> +} HDAUDIO_HOB;
> +
> +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];
> +  /**
> +    This member describes the details of implementation of Intel RST for PCIe
> Storage remapping (Intel RST Driver is required)
> +  **/
> +  PCH_RST_PCIE_STORAGE_CONFIG
> RstPcieStorageRemap[PCH_MAX_RST_PCIE_STORAGE_CR];
> +} SATA_HOB;
> +
> +///
> +/// The SCS_HOB block describes Storage and Communication Subsystem
> (SCS) settings for PCH.
> +///
> +typedef struct {
> +  UINT32  ScsEmmcEnabled                      :  2;  ///< Determine if eMMC is
> enabled - 0: Disabled, <b>1: Enabled</b>.
> +  UINT32  ScsEmmcHs400Enabled                 :  1;  ///< Determine eMMC
> HS400 Mode if ScsEmmcEnabled - <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  ScsEmmcHs400TuningRequired          :  1;
> +  UINT32  ScsEmmcHs400DllDataValid            :  1;  ///< Set if HS400 Tuning
> Data Valid
> +  UINT32  ScsEmmcHs400DriverStrength          :  3;  ///< I/O driver strength:
> <b>0 - 33 Ohm</b>, 1 - 40 Ohm, 2 - 50 Ohm
> +  UINT32  ScsSdPowerEnableActiveHigh          :  1;  ///< Sd PWREN# active
> high
> +  UINT32  ScsSdCardEnabled                    :  1;  ///< Sd card enabled
> +  UINT32  RsvdBits                            : 22;
> +} SCS_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 RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the
> upper
> +    and lower 128-byte bank of RTC RAM. 0: Disable; <b>1: Enable</b>.
> +  **/
> +  UINT32  RtcMemoryLock   :  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        : 28;
> +} 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                  SlpS0VmRuntimeControl        :  1;     /// < SLP_S0
> Voltage Margining Runtime Control. <b>0: Disable</b>; 1: Enable.
> +  UINT32                  SlpS0Vm070VSupport           :  1;     /// < SLP_S0
> 0.70V Voltage Margining Support. <b>0: Disable</b>; 1: Enable.
> +  UINT32                  SlpS0Vm075VSupport           :  1;     /// < SLP_S0
> 0.75V Voltage Margining Support. <b>0: Disable</b>; 1: Enable.
> +  UINT32                  PsOnEnable                   :  1;     /// < Indicates if
> PS_ON support has been enabled, <b>0: Disable</b>; 1: Enable.
> +  UINT32                  RsvdBits1                    : 28;
> +} PM_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 bytes
> +} PCH_TRACEHUB_HOB;
> +
> +/**
> +  PCH eSPI HOB settings.
> +**/
> +typedef struct {
> +  UINT32  BmeMasterSlaveEnabled :  1; // <b>0 = BME disable</b>; 1 = BME
> enable
> +  UINT32  RsvdBits              : 31;
> +} PCH_ESPI_HOB;
> +
> +
> +///
> +/// Pch Config Hob
> +///
> +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
> +  SCS_HOB            Scs;                ///< Scs HOB definition
> +  CNVI_HOB           Cnvi;               ///< Cnvi 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
> +  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
> +
> +} PCH_CONFIG_HOB;
> +#pragma pack (pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
> new file mode 100644
> index 0000000000..faaff9f497
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
> @@ -0,0 +1,115 @@
> +/** @file
> +  Header file for PchHdaLib Endpoint descriptors.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HDA_ENDPOINTS_H_
> +#define _PCH_HDA_ENDPOINTS_H_
> +
> +#include <Private/Library/DxePchHdaNhlt.h>
> +
> +typedef enum {
> +  HdaDmicX1       = 0,
> +  HdaDmicX2,
> +  HdaDmicX4,
> +  HdaBtRender,
> +  HdaBtCapture,
> +  HdaI2sRender1,
> +  HdaI2sRender2,
> +  HdaI2sCapture,
> +  HdaEndpointMax
> +} NHLT_ENDPOINT;
> +
> +typedef struct {
> +  NHLT_ENDPOINT EndpointType;
> +  UINT32        EndpointFormatsBitmask;
> +  UINT32        EndpointDevicesBitmask;
> +  BOOLEAN       Enable;
> +} PCH_HDA_NHLT_ENDPOINTS;
> +
> +#define PCH_HDA_NHLT_TABLE_SIZE 0x2000
> +
> +// Format bitmask
> +#define B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT                BIT0
> +#define B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT                BIT1
> +#define B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT                BIT2
> +#define B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT                BIT3
> +#define B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT                BIT4
> +#define B_HDA_BT_NARROWBAND_FORMAT                       BIT5
> +#define B_HDA_BT_WIDEBAND_FORMAT                         BIT6
> +#define B_HDA_BT_A2DP_FORMAT                             BIT7
> +#define B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT   BIT8
> +#define B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT  BIT9
> +#define V_HDA_FORMAT_MAX                                 10
> +
> +// Formats
> +extern CONST WAVEFORMATEXTENSIBLE Ch1_48kHz16bitFormat;
> +extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz16bitFormat;
> +extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz24bitFormat;
> +extern CONST WAVEFORMATEXTENSIBLE Ch2_48kHz32bitFormat;
> +extern CONST WAVEFORMATEXTENSIBLE Ch4_48kHz16bitFormat;
> +extern CONST WAVEFORMATEXTENSIBLE Ch4_48kHz32bitFormat;
> +extern CONST WAVEFORMATEXTENSIBLE NarrowbandFormat;
> +extern CONST WAVEFORMATEXTENSIBLE WidebandFormat;
> +extern CONST WAVEFORMATEXTENSIBLE A2dpFormat;
> +
> +// Format Config
> +extern CONST UINT32 DmicStereo16BitFormatConfig[];
> +extern CONST UINT32 DmicStereo16BitFormatConfigSize;
> +extern CONST UINT32 DmicStereo32BitFormatConfig[];
> +extern CONST UINT32 DmicStereo32BitFormatConfigSize;
> +extern CONST UINT32 DmicQuad16BitFormatConfig[];
> +extern CONST UINT32 DmicQuad16BitFormatConfigSize;
> +extern CONST UINT32 DmicQuad32BitFormatConfig[];
> +extern CONST UINT32 DmicQuad32BitFormatConfigSize;
> +extern CONST UINT32 DmicMono16BitFormatConfig[];
> +extern CONST UINT32 DmicMono16BitFormatConfigSize;
> +
> +extern CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfig[];
> +extern CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfigSize;
> +extern CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfig[];
> +extern CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
> +extern CONST UINT32 BtFormatConfig[];
> +extern CONST UINT32 BtFormatConfigSize;
> +
> +// Endpoints
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX1;
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX2;
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointDmicX4;
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointBtRender;
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointBtCapture;
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointI2sRender;
> +extern ENDPOINT_DESCRIPTOR  HdaEndpointI2sCapture;
> +
> +// Endpoint Config
> +extern CONST UINT8  DmicX1Config[];
> +extern CONST UINT32 DmicX1ConfigSize;
> +extern CONST UINT8  DmicX2Config[];
> +extern CONST UINT32 DmicX2ConfigSize;
> +extern CONST UINT8  DmicX4Config[];
> +extern CONST UINT32 DmicX4ConfigSize;
> +extern CONST UINT8  BtConfig[];
> +extern CONST UINT32 BtConfigSize;
> +extern CONST UINT8  I2sRender1Config[];
> +extern CONST UINT32 I2sRender1ConfigSize;
> +extern CONST UINT8  I2sRender2Config[];
> +extern CONST UINT32 I2sRender2ConfigSize;
> +extern CONST UINT8  I2sCaptureConfig[];
> +extern CONST UINT32 I2sCaptureConfigSize;
> +
> +// Device Info bitmask
> +#define B_HDA_I2S_RENDER_DEVICE_INFO  BIT0
> +#define B_HDA_I2S_CAPTURE_DEVICE_INFO BIT1
> +
> +// Device Info
> +extern CONST DEVICE_INFO I2sRenderDeviceInfo;
> +extern CONST DEVICE_INFO I2sCaptureDeviceInfo;
> +
> +// Oed Configuration
> +extern CONST UINT32 NhltConfiguration[];
> +extern CONST UINT32 NhltConfigurationSize;
> +
> +#endif // _PCH_HDA_ENDPOINTS_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
> new file mode 100644
> index 0000000000..860ed89f0d
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
> @@ -0,0 +1,92 @@
> +/** @file
> +  Header file with all common HSIO information
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HSIO_H_
> +#define _PCH_HSIO_H_
> +
> +#define PCH_LANE_OWN_COMMON                      0x10
> +#define PCH_LANE_BDCAST                          0x11
> +#define PCH_HSIO_LANE_GROUP_NO                   0x09
> +#define PCH_HSIO_LANE_GROUP_COMMON_LANE          0x00
> +#define PCH_HSIO_LANE_GROUP_PCIE                 0x01
> +#define PCH_HSIO_LANE_GROUP_DMI                  0x02
> +#define PCH_HSIO_LANE_GROUP_GBE                  0x03
> +#define PCH_HSIO_LANE_GROUP_USB3                 0x04
> +#define PCH_HSIO_LANE_GROUP_SATA                 0x05
> +#define PCH_HSIO_LANE_GROUP_SSIC                 0x06
> +
> +
> +/**
> +  PCH HSIO ChipsetInit Version Information
> +**/
> +typedef struct {
> +  UINT16 BaseCrc;
> +  UINT16 SusCrc;
> +  UINT16 OemCrc;
> +  UINT8  Version;
> +  UINT8  Product;
> +  UINT8  MetalLayer : 4;
> +  UINT8  BaseLayer : 4;
> +  UINT8  OemVersion;
> +  UINT16 DebugMode : 1;
> +  UINT16 OemCrcValid : 1;
> +  UINT16 SusCrcValid : 1;
> +  UINT16 BaseCrcValid : 1;
> +  UINT16 Reserved : 12;
> +} PCH_HSIO_VER_INFO;
> +
> +#define PMC_DATA_CMD_SIZE   ((12/sizeof(UINT16))-1)
> +#define PMC_DATA_DELAY_CMD_SIZE ((4/sizeof(UINT16))-1)
> +
> +#define RECORD_OFFSET(X, Y)  ((X << 4) | Y)
> +/**
> +  PCH HSIO ChipsetInit Command Field
> +**/
> +typedef struct {
> +  UINT8 Command : 3;
> +  UINT8 Size : 5;
> +  UINT8 Pid;
> +  UINT8 OpCode; //PrivateControlWrite
> +  UINT8 Bar; //0
> +  UINT8 Fbe; //First Byte Enable  : 0x0F
> +  UINT8 Fid; //0
> +  UINT16 Offset;
> +  UINT32 Value;
> +} PCH_HSIO_CMD_FIELD;
> +
> +/**
> +PCH HSIO Delay XRAM Data
> +**/
> +typedef struct {
> +  UINT8 Command : 3;
> +  UINT8 Size : 5;
> +  UINT8 DelayPeriod; //(00h = 1us, 01h = 10us, 02h = 100us, ..., 07h = 10s;
> others reserved)
> +  UINT8 DelayCount; //(0 - 255); total delay = Delay period * Delay count
> +  UINT8 Padding;
> +} PCH_HSIO_DELAY_CMD_FIELD;
> +
> +typedef enum {
> +  Delay1us = 0x0,
> +  Delay10us,
> +  Delay100us,
> +  Delay1ms,
> +  Delay10ms,
> +  Delay100ms,
> +  Delay1s,
> +  Delay10s
> +} PCH_HSIO_DELAY;
> +
> +/**
> +PCH PCIE PLL SSC Data
> +**/
> +#define MAX_PCIE_PLL_SSC_PERCENT  20
> +
> +#include <Private/CnlPchLpHsioDx.h>
> +
> +#endif //_PCH_HSIO_H_
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
> new file mode 100644
> index 0000000000..4617a01c0b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
> @@ -0,0 +1,269 @@
> +/** @file
> +  Copyright (c) 2019 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[24];                           ///< 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
> +  UINT64   NHLA;                                    ///< Offset 102     HD-Audio
> NHLT ACPI address
> +  UINT32   NHLL;                                    ///< Offset 110     HD-Audio NHLT
> ACPI length
> +  UINT32   ADFM;                                    ///< Offset 114     HD-Audio DSP
> Feature Mask
> +  UINT8    SWQ0;                                    ///< Offset 118     HD-Audio
> SoundWire Link #1 quirk mask
> +  UINT8    SWQ1;                                    ///< Offset 119     HD-Audio
> SoundWire Link #2 quirk mask
> +  UINT8    SWQ2;                                    ///< Offset 120     HD-Audio
> SoundWire Link #3 quirk mask
> +  UINT8    SWQ3;                                    ///< Offset 121     HD-Audio
> SoundWire Link #4 quirk mask
> +  UINT32   DSPM;                                    ///< Offset 122     HD-Audio DSP
> Stolen Memory Base Address
> +  UINT32   SBRG;                                    ///< Offset 126     SBREG_BAR
> +  UINT8    GEI0;                                    ///< Offset 130     GPIO
> GroupIndex mapped to GPE_DW0
> +  UINT8    GEI1;                                    ///< Offset 131     GPIO
> GroupIndex mapped to GPE_DW1
> +  UINT8    GEI2;                                    ///< Offset 132     GPIO
> GroupIndex mapped to GPE_DW2
> +  UINT8    GED0;                                    ///< Offset 133     GPIO DW part
> of group mapped to GPE_DW0
> +  UINT8    GED1;                                    ///< Offset 134     GPIO DW part
> of group mapped to GPE_DW1
> +  UINT8    GED2;                                    ///< Offset 135     GPIO DW part
> of group mapped to GPE_DW2
> +  UINT16   PcieLtrMaxSnoopLatency[24];              ///< Offset 136     PCIE
> LTR max snoop Latency 1
> +                                                    ///< Offset 138     PCIE LTR max snoop
> Latency 2
> +                                                    ///< Offset 140     PCIE LTR max snoop
> Latency 3
> +                                                    ///< Offset 142     PCIE LTR max snoop
> Latency 4
> +                                                    ///< Offset 144     PCIE LTR max snoop
> Latency 5
> +                                                    ///< Offset 146     PCIE LTR max snoop
> Latency 6
> +                                                    ///< Offset 148     PCIE LTR max snoop
> Latency 7
> +                                                    ///< Offset 150     PCIE LTR max snoop
> Latency 8
> +                                                    ///< Offset 152     PCIE LTR max snoop
> Latency 9
> +                                                    ///< Offset 154     PCIE LTR max snoop
> Latency 10
> +                                                    ///< Offset 156     PCIE LTR max snoop
> Latency 11
> +                                                    ///< Offset 158     PCIE LTR max snoop
> Latency 12
> +                                                    ///< Offset 160     PCIE LTR max snoop
> Latency 13
> +                                                    ///< Offset 162     PCIE LTR max snoop
> Latency 14
> +                                                    ///< Offset 164     PCIE LTR max snoop
> Latency 15
> +                                                    ///< Offset 166     PCIE LTR max snoop
> Latency 16
> +                                                    ///< Offset 168     PCIE LTR max snoop
> Latency 17
> +                                                    ///< Offset 170     PCIE LTR max snoop
> Latency 18
> +                                                    ///< Offset 172     PCIE LTR max snoop
> Latency 19
> +                                                    ///< Offset 174     PCIE LTR max snoop
> Latency 20
> +                                                    ///< Offset 176     PCIE LTR max snoop
> Latency 21
> +                                                    ///< Offset 178     PCIE LTR max snoop
> Latency 22
> +                                                    ///< Offset 180     PCIE LTR max snoop
> Latency 23
> +                                                    ///< Offset 182     PCIE LTR max snoop
> Latency 24
> +  UINT16   PcieLtrMaxNoSnoopLatency[24];            ///< Offset 184     PCIE
> LTR max no snoop Latency 1
> +                                                    ///< Offset 186     PCIE LTR max no
> snoop Latency 2
> +                                                    ///< Offset 188     PCIE LTR max no
> snoop Latency 3
> +                                                    ///< Offset 190     PCIE LTR max no
> snoop Latency 4
> +                                                    ///< Offset 192     PCIE LTR max no
> snoop Latency 5
> +                                                    ///< Offset 194     PCIE LTR max no
> snoop Latency 6
> +                                                    ///< Offset 196     PCIE LTR max no
> snoop Latency 7
> +                                                    ///< Offset 198     PCIE LTR max no
> snoop Latency 8
> +                                                    ///< Offset 200     PCIE LTR max no
> snoop Latency 9
> +                                                    ///< Offset 202     PCIE LTR max no
> snoop Latency 10
> +                                                    ///< Offset 204     PCIE LTR max no
> snoop Latency 11
> +                                                    ///< Offset 206     PCIE LTR max no
> snoop Latency 12
> +                                                    ///< Offset 208     PCIE LTR max no
> snoop Latency 13
> +                                                    ///< Offset 210     PCIE LTR max no
> snoop Latency 14
> +                                                    ///< Offset 212     PCIE LTR max no
> snoop Latency 15
> +                                                    ///< Offset 214     PCIE LTR max no
> snoop Latency 16
> +                                                    ///< Offset 216     PCIE LTR max no
> snoop Latency 17
> +                                                    ///< Offset 218     PCIE LTR max no
> snoop Latency 18
> +                                                    ///< Offset 220     PCIE LTR max no
> snoop Latency 19
> +                                                    ///< Offset 222     PCIE LTR max no
> snoop Latency 20
> +                                                    ///< Offset 224     PCIE LTR max no
> snoop Latency 21
> +                                                    ///< Offset 226     PCIE LTR max no
> snoop Latency 22
> +                                                    ///< Offset 228     PCIE LTR max no
> snoop Latency 23
> +                                                    ///< Offset 230     PCIE LTR max no
> snoop Latency 24
> +  UINT8    XHPC;                                    ///< Offset 232     Number of
> HighSpeed ports implemented in XHCI controller
> +  UINT8    XRPC;                                    ///< Offset 233     Number of
> USBR ports implemented in XHCI controller
> +  UINT8    XSPC;                                    ///< Offset 234     Number of
> SuperSpeed ports implemented in XHCI controller
> +  UINT8    XSPA;                                    ///< Offset 235     Address of 1st
> SuperSpeed port
> +  UINT32   HPTB;                                    ///< Offset 236     HPET base
> address
> +  UINT8    HPTE;                                    ///< Offset 240     HPET enable
> +  //SerialIo block
> +  UINT8    SMD[12];                                 ///< Offset 241     SerialIo
> controller 0 mode
> +                                                    ///< Offset 242     SerialIo controller 1
> mode
> +                                                    ///< Offset 243     SerialIo controller 2
> mode
> +                                                    ///< Offset 244     SerialIo controller 3
> mode
> +                                                    ///< Offset 245     SerialIo controller 4
> mode
> +                                                    ///< Offset 246     SerialIo controller 5
> mode
> +                                                    ///< Offset 247     SerialIo controller 6
> mode
> +                                                    ///< Offset 248     SerialIo controller 7
> mode
> +                                                    ///< Offset 249     SerialIo controller 8
> mode
> +                                                    ///< Offset 250     SerialIo controller 9
> mode
> +                                                    ///< Offset 251     SerialIo controller A
> mode
> +                                                    ///< Offset 252     SerialIo controller B
> mode
> +  UINT8    SIR[12];                                 ///< Offset 253     SerialIo
> controller 0 irq number
> +                                                    ///< Offset 254     SerialIo controller 1
> irq number
> +                                                    ///< Offset 255     SerialIo controller 2
> irq number
> +                                                    ///< Offset 256     SerialIo controller 3
> irq number
> +                                                    ///< Offset 257     SerialIo controller 4
> irq number
> +                                                    ///< Offset 258     SerialIo controller 5
> irq number
> +                                                    ///< Offset 259     SerialIo controller 6
> irq number
> +                                                    ///< Offset 260     SerialIo controller 7
> irq number
> +                                                    ///< Offset 261     SerialIo controller 8
> irq number
> +                                                    ///< Offset 262     SerialIo controller 9
> irq number
> +                                                    ///< Offset 263     SerialIo controller A
> irq number
> +                                                    ///< Offset 264     SerialIo controller B
> irq number
> +  UINT64   SB0[12];                                 ///< Offset 265     SerialIo
> controller 0 BAR0
> +                                                    ///< Offset 273     SerialIo controller 1
> BAR0
> +                                                    ///< Offset 281     SerialIo controller 2
> BAR0
> +                                                    ///< Offset 289     SerialIo controller 3
> BAR0
> +                                                    ///< Offset 297     SerialIo controller 4
> BAR0
> +                                                    ///< Offset 305     SerialIo controller 5
> BAR0
> +                                                    ///< Offset 313     SerialIo controller 6
> BAR0
> +                                                    ///< Offset 321     SerialIo controller 7
> BAR0
> +                                                    ///< Offset 329     SerialIo controller 8
> BAR0
> +                                                    ///< Offset 337     SerialIo controller 9
> BAR0
> +                                                    ///< Offset 345     SerialIo controller A
> BAR0
> +                                                    ///< Offset 353     SerialIo controller B
> BAR0
> +  UINT64   SB1[12];                                 ///< Offset 361     SerialIo
> controller 0 BAR1
> +                                                    ///< Offset 369     SerialIo controller 1
> BAR1
> +                                                    ///< Offset 377     SerialIo controller 2
> BAR1
> +                                                    ///< Offset 385     SerialIo controller 3
> BAR1
> +                                                    ///< Offset 393     SerialIo controller 4
> BAR1
> +                                                    ///< Offset 401     SerialIo controller 5
> BAR1
> +                                                    ///< Offset 409     SerialIo controller 6
> BAR1
> +                                                    ///< Offset 417     SerialIo controller 7
> BAR1
> +                                                    ///< Offset 425     SerialIo controller 8
> BAR1
> +                                                    ///< Offset 433     SerialIo controller 9
> BAR1
> +                                                    ///< Offset 441     SerialIo controller A
> BAR1
> +                                                    ///< Offset 449     SerialIo controller B
> BAR1
> +  //end of SerialIo block
> +  UINT8    SGIR;                                    ///< Offset 457     GPIO IRQ
> +  UINT8    GPHD;                                    ///< Offset 458     Hide GPIO ACPI
> device
> +  UINT8    RstPcieStorageInterfaceType[3];          ///< Offset 459     RST PCIe
> Storage Cycle Router#1 Interface Type
> +                                                    ///< Offset 460     RST PCIe Storage
> Cycle Router#2 Interface Type
> +                                                    ///< Offset 461     RST PCIe Storage
> Cycle Router#3 Interface Type
> +  UINT8    RstPcieStoragePmCapPtr[3];               ///< Offset 462     RST PCIe
> Storage Cycle Router#1 Power Management Capability Pointer
> +                                                    ///< Offset 463     RST PCIe Storage
> Cycle Router#2 Power Management Capability Pointer
> +                                                    ///< Offset 464     RST PCIe Storage
> Cycle Router#3 Power Management Capability Pointer
> +  UINT8    RstPcieStoragePcieCapPtr[3];             ///< Offset 465     RST PCIe
> Storage Cycle Router#1 PCIe Capabilities Pointer
> +                                                    ///< Offset 466     RST PCIe Storage
> Cycle Router#2 PCIe Capabilities Pointer
> +                                                    ///< Offset 467     RST PCIe Storage
> Cycle Router#3 PCIe Capabilities Pointer
> +  UINT16   RstPcieStorageL1ssCapPtr[3];             ///< Offset 468     RST PCIe
> Storage Cycle Router#1 L1SS Capability Pointer
> +                                                    ///< Offset 470     RST PCIe Storage
> Cycle Router#2 L1SS Capability Pointer
> +                                                    ///< Offset 472     RST PCIe Storage
> Cycle Router#3 L1SS Capability Pointer
> +  UINT8    RstPcieStorageEpL1ssControl2[3];         ///< Offset 474     RST
> PCIe Storage Cycle Router#1 Endpoint L1SS Control Data2
> +                                                    ///< Offset 475     RST PCIe Storage
> Cycle Router#2 Endpoint L1SS Control Data2
> +                                                    ///< Offset 476     RST PCIe Storage
> Cycle Router#3 Endpoint L1SS Control Data2
> +  UINT32   RstPcieStorageEpL1ssControl1[3];         ///< Offset 477     RST
> PCIe Storage Cycle Router#1 Endpoint L1SS Control Data1
> +                                                    ///< Offset 481     RST PCIe Storage
> Cycle Router#2 Endpoint L1SS Control Data1
> +                                                    ///< Offset 485     RST PCIe Storage
> Cycle Router#3 Endpoint L1SS Control Data1
> +  UINT16   RstPcieStorageLtrCapPtr[3];              ///< Offset 489     RST PCIe
> Storage Cycle Router#1 LTR Capability Pointer
> +                                                    ///< Offset 491     RST PCIe Storage
> Cycle Router#2 LTR Capability Pointer
> +                                                    ///< Offset 493     RST PCIe Storage
> Cycle Router#3 LTR Capability Pointer
> +  UINT32   RstPcieStorageEpLtrData[3];              ///< Offset 495     RST PCIe
> Storage Cycle Router#1 Endpoint LTR Data
> +                                                    ///< Offset 499     RST PCIe Storage
> Cycle Router#2 Endpoint LTR Data
> +                                                    ///< Offset 503     RST PCIe Storage
> Cycle Router#3 Endpoint LTR Data
> +  UINT16   RstPcieStorageEpLctlData16[3];           ///< Offset 507     RST
> PCIe Storage Cycle Router#1 Endpoint LCTL Data
> +                                                    ///< Offset 509     RST PCIe Storage
> Cycle Router#2 Endpoint LCTL Data
> +                                                    ///< Offset 511     RST PCIe Storage
> Cycle Router#3 Endpoint LCTL Data
> +  UINT16   RstPcieStorageEpDctlData16[3];           ///< Offset 513     RST
> PCIe Storage Cycle Router#1 Endpoint DCTL Data
> +                                                    ///< Offset 515     RST PCIe Storage
> Cycle Router#2 Endpoint DCTL Data
> +                                                    ///< Offset 517     RST PCIe Storage
> Cycle Router#3 Endpoint DCTL Data
> +  UINT16   RstPcieStorageEpDctl2Data16[3];          ///< Offset 519     RST
> PCIe Storage Cycle Router#1 Endpoint DCTL2 Data
> +                                                    ///< Offset 521     RST PCIe Storage
> Cycle Router#2 Endpoint DCTL2 Data
> +                                                    ///< Offset 523     RST PCIe Storage
> Cycle Router#3 Endpoint DCTL2 Data
> +  UINT16   RstPcieStorageRpDctl2Data16[3];          ///< Offset 525     RST
> PCIe Storage Cycle Router#1 RootPort DCTL2 Data
> +                                                    ///< Offset 527     RST PCIe Storage
> Cycle Router#2 RootPort DCTL2 Data
> +                                                    ///< Offset 529     RST PCIe Storage
> Cycle Router#3 RootPort DCTL2 Data
> +  UINT32   RstPcieStorageUniqueTableBar[3];         ///< Offset 531     RST
> PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR
> +                                                    ///< Offset 535     RST PCIe Storage
> Cycle Router#2 Endpoint unique MSI-X Table BAR
> +                                                    ///< Offset 539     RST PCIe Storage
> Cycle Router#3 Endpoint unique MSI-X Table BAR
> +  UINT32   RstPcieStorageUniqueTableBarValue[3];    ///< Offset 543     RST
> PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR value
> +                                                    ///< Offset 547     RST PCIe Storage
> Cycle Router#2 Endpoint unique MSI-X Table BAR value
> +                                                    ///< Offset 551     RST PCIe Storage
> Cycle Router#3 Endpoint unique MSI-X Table BAR value
> +  UINT32   RstPcieStorageUniquePbaBar[3];           ///< Offset 555     RST
> PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR
> +                                                    ///< Offset 559     RST PCIe Storage
> Cycle Router#2 Endpoint unique MSI-X PBA BAR
> +                                                    ///< Offset 563     RST PCIe Storage
> Cycle Router#3 Endpoint unique MSI-X PBA BAR
> +  UINT32   RstPcieStorageUniquePbaBarValue[3];      ///< Offset 567     RST
> PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR value
> +                                                    ///< Offset 571     RST PCIe Storage
> Cycle Router#2 Endpoint unique MSI-X PBA BAR value
> +                                                    ///< Offset 575     RST PCIe Storage
> Cycle Router#3 Endpoint unique MSI-X PBA BAR value
> +  UINT32   RstPcieStorageRootPortNum[3];            ///< Offset 579     RST
> PCIe Storage Cycle Router#1 Root Port number
> +                                                    ///< Offset 583     RST PCIe Storage
> Cycle Router#2 Root Port number
> +                                                    ///< Offset 587     RST PCIe Storage
> Cycle Router#3 Root Port number
> +  UINT8    EMH4;                                    ///< Offset 591     eMMC HS400
> mode enabled
> +  UINT8    EMDS;                                    ///< Offset 592     eMMC Driver
> Strength
> +  UINT8    CpuSku;                                  ///< Offset 593     CPU SKU
> +  UINT16   IoTrapAddress[4];                        ///< Offset 594
> +  UINT8    IoTrapStatus[4];                         ///< Offset 602
> +  UINT16   PMBS;                                    ///< Offset 606     ACPI IO BASE
> address
> +  UINT32   PWRM;                                    ///< Offset 608     PWRM MEM
> BASE address
> +  // Cnvi specific
> +  UINT8    CnviMode;                                ///< Offset 612     CNVi mode
> +  UINT32   RmrrCsmeBaseAddress;                     ///< Offset 613     RMRR
> CSME Base Address
> +  //Voltage Margining
> +  UINT8    SlpS0VmRuntimeControl;                   ///< Offset 617     SLP_S0
> Voltage Margining Runtime Control
> +  UINT8    SlpS0Vm070VSupport;                      ///< Offset 618     SLP_S0
> 0.70V Voltage Margining Support
> +  UINT8    SlpS0Vm075VSupport;                      ///< Offset 619     SLP_S0
> 0.75V Voltage Margining Support
> +  // PCH Trace Hub
> +  UINT8    PchTraceHubMode;                         ///< Offset 620     PCH Trace
> Hub Mode
> +  // PCH PS_ON support
> +  UINT8    PsOnEnable;                              ///< Offset 621     PCH PS_ON
> enable
> +  UINT32   TempRsvdMemBase;                         ///< Offset 622
> Reserved memory base address for Temp MBAR
> +  //
> +  // These are for PchApciTablesSelfTest use
> +  //
> +  UINT8    LtrEnable[24];                           ///< Offset 626     Latency
> Tolerance Reporting Enable
> +                                                    ///< Offset 627     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 628     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 629     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 630     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 631     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 632     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 633     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 634     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 635     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 636     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 637     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 638     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 639     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 640     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 641     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 642     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 643     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 644     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 645     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 646     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 647     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 648     Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 649     Latency Tolerance
> Reporting Enable
> +  UINT8    GBES;                                    ///< Offset 650     GbE Support
> +  UINT8    SataPortPresence;                        ///< Offset 651     Holds
> information from SATA PCS register about SATA ports which recieved COMINIT
> from connected devices.
> +  UINT8    SdPowerEnableActiveHigh;                 ///< Offset 652     SD
> PWREN# active high indication
> +  UINT8    EmmcEnabled;                             ///< Offset 653     Set to
> indicate that eMMC is enabled
> +  UINT8    SdCardEnabled;                           ///< Offset 654     Set to
> indicate that SD card is enabled
> +} PCH_NVS_AREA;
> +
> +#pragma pack(pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
> new file mode 100644
> index 0000000000..94a5e0fad2
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Definitions required to create RstHob
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHo
> b.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHo
> b.h
> new file mode 100644
> index 0000000000..7a92a509b4
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHo
> b.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  This file contains definitions of Si Schedule Reset HOB.
> +
> +  Copyright (c) 2019 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_
> +
> +#include <PchResetPlatformSpecific.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.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:12 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode:
> Add Include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds header files common to silicon Sample Code.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformL
> ib.h                     |   82 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/
> Guid/SmramMemoryReserve.h  |   51 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/
> Protocol/LegacyBios.h      | 1513 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/
> Protocol/LegacyInterrupt.h |  118 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Gui
> d/AcpiS3Context.h            |   65 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Gui
> d/ConsoleOutDevice.h         |   17 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Gui
> d/MemoryTypeInformation.h    |   30 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Libr
> ary/ResetSystemLib.h        |   80 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/
> SmmAccess.h                 |  137 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/
> SmmControl.h                |   87 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Pro
> tocol/SmmVariable.h          |   33 +
>  11 files changed, 2213 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatfor
> mLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatfor
> mLib.h
> new file mode 100644
> index 0000000000..829d1190fc
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatfor
> mLib.h
> @@ -0,0 +1,82 @@
> +/** @file
> +  Prototype of SEC Platform hook library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef  _SEC_PLATFORM_LIB_H_
> +#define  _SEC_PLATFORM_LIB_H_
> +
> +#include <Ppi/SecPlatformInformation.h>
> +#include <Ppi/SecPerformance.h>
> +
> +/**
> +  A developer supplied function to perform platform specific operations.
> +
> +  It's a developer supplied function to perform any operations appropriate to
> a
> +  given platform. It's invoked just before passing control to PEI core by SEC
> +  core. Platform developer may modify the SecCoreData passed to PEI Core.
> +  It returns a platform specific PPI list that platform wishes to pass to PEI core.
> +  The Generic SEC core module will merge this list to join the final list passed
> to
> +  PEI core.
> +
> +  @param  SecCoreData           The same parameter as passing to PEI core. It
> +                                could be overridden by this function.
> +
> +  @return The platform specific PPI list to be passed to PEI core or
> +          NULL if there is no need of such platform specific PPI list.
> +
> +**/
> +EFI_PEI_PPI_DESCRIPTOR *
> +EFIAPI
> +SecPlatformMain (
> +  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
> +  );
> +
> +
> +/**
> +  This interface conveys state information out of the Security (SEC) phase into
> PEI.
> +
> +  @param  PeiServices               Pointer to the PEI Services Table.
> +  @param  StructureSize             Pointer to the variable describing size of
> the input buffer.
> +  @param  PlatformInformationRecord Pointer to the
> EFI_SEC_PLATFORM_INFORMATION_RECORD.
> +
> +  @retval EFI_SUCCESS           The data was successfully returned.
> +  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecPlatformInformation (
> +  IN CONST EFI_PEI_SERVICES                     **PeiServices,
> +  IN OUT   UINT64                               *StructureSize,
> +     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD
> *PlatformInformationRecord
> +  );
> +
> +/**
> +  This interface conveys performance information out of the Security (SEC)
> phase into PEI.
> +
> +  This service is published by the SEC phase. The SEC phase handoff has an
> optional
> +  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> from SEC into the
> +  PEI Foundation. As such, if the platform supports collecting performance
> data in SEC,
> +  this information is encapsulated into the data structure abstracted by this
> service.
> +  This information is collected for the boot-strap processor (BSP) on IA-32.
> +
> +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> +  @param[in]  This         The pointer to this instance of the
> PEI_SEC_PERFORMANCE_PPI.
> +  @param[out] Performance  The pointer to performance data collected in
> SEC phase.
> +
> +  @retval     EFI_SUCCESS  The data was successfully returned.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecGetPerformance (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN       PEI_SEC_PERFORMANCE_PPI   *This,
> +  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
> +  );
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Guid/SmramMemoryReserve.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Guid/SmramMemoryReserve.h
> new file mode 100644
> index 0000000000..862a7c8aea
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Guid/SmramMemoryReserve.h
> @@ -0,0 +1,51 @@
> +/** @file
> +  Definition of GUIDed HOB for reserving SMRAM regions.
> +
> +  This file defines:
> +  * the GUID used to identify the GUID HOB for reserving SMRAM regions.
> +  * the data structure of SMRAM descriptor to describe SMRAM candidate
> regions
> +  * values of state of SMRAM candidate regions
> +  * the GUID specific data structure of HOB for reserving SMRAM regions.
> +  This GUIDed HOB can be used to convey the existence of the T-SEG
> reservation and H-SEG usage
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_
> +#define _EFI_SMM_PEI_SMRAM_MEMORY_RESERVE_H_
> +
> +#define EFI_SMM_PEI_SMRAM_MEMORY_RESERVE \
> +  { \
> +    0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d }
> \
> +  }
> +
> +/**
> +* GUID specific data structure of HOB for reserving SMRAM regions.
> +*
> +* Inconsistent with specification here:
> +* EFI_HOB_SMRAM_DESCRIPTOR_BLOCK has been changed to
> EFI_SMRAM_HOB_DESCRIPTOR_BLOCK.
> +* This inconsistency is kept in code in order for backward compatibility.
> +**/
> +typedef struct {
> +  ///
> +  /// Designates the number of possible regions in the system
> +  /// that can be usable for SMRAM.
> +  ///
> +  /// Inconsistent with specification here:
> +  /// In Framework SMM CIS 0.91 specification, it defines the field type as
> UINTN.
> +  /// However, HOBs are supposed to be CPU neutral, so UINT32 should be
> used instead.
> +  ///
> +  UINT32                NumberOfSmmReservedRegions;
> +  ///
> +  /// Used throughout this protocol to describe the candidate
> +  /// regions for SMRAM that are supported by this platform.
> +  ///
> +  EFI_SMRAM_DESCRIPTOR  Descriptor[1];
> +} EFI_SMRAM_HOB_DESCRIPTOR_BLOCK;
> +
> +extern EFI_GUID gEfiSmmPeiSmramMemoryReserveGuid;
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Protocol/LegacyBios.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Protocol/LegacyBios.h
> new file mode 100644
> index 0000000000..6ba23381b0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Protocol/LegacyBios.h
> @@ -0,0 +1,1513 @@
> +/** @file
> +  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage
> +  under EFI and Legacy OS boot.  This file also includes all the related
> +  COMPATIBILIY16 structures and defintions.
> +
> +  Note: The names for EFI_IA32_REGISTER_SET elements were picked to
> follow
> +  well known naming conventions.
> +
> +  Thunk is the code that switches from 32-bit protected environment into the
> 16-bit real-mode
> +  environment. Reverse thunk is the code that does the opposite.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _EFI_LEGACY_BIOS_H_
> +#define _EFI_LEGACY_BIOS_H_
> +
> +///
> +///
> +///
> +#pragma pack(1)
> +
> +typedef UINT8                       SERIAL_MODE;
> +typedef UINT8                       PARALLEL_MODE;
> +
> +#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E',
> '$')
> +
> +///
> +/// There is a table located within the traditional BIOS in either the
> 0xF000:xxxx or 0xE000:xxxx
> +/// physical address range. It is located on a 16-byte boundary and provides
> the physical address of the
> +/// entry point for the Compatibility16 functions. These functions provide the
> platform-specific
> +/// information that is required by the generic EfiCompatibility code. The
> functions are invoked via
> +/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the
> 32-bit physical
> +/// entry point.
> +///
> +typedef struct {
> +  ///
> +  /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0
> is "I," byte
> +  /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a
> DWORD or UINT32.
> +  ///
> +  UINT32                            Signature;
> +
> +  ///
> +  /// The value required such that byte checksum of TableLength equals zero.
> +  ///
> +  UINT8                             TableChecksum;
> +
> +  ///
> +  /// The length of this table.
> +  ///
> +  UINT8                             TableLength;
> +
> +  ///
> +  /// The major EFI revision for which this table was generated.
> +  ///
> +  UINT8                             EfiMajorRevision;
> +
> +  ///
> +  /// The minor EFI revision for which this table was generated.
> +  ///
> +  UINT8                             EfiMinorRevision;
> +
> +  ///
> +  /// The major revision of this table.
> +  ///
> +  UINT8                             TableMajorRevision;
> +
> +  ///
> +  /// The minor revision of this table.
> +  ///
> +  UINT8                             TableMinorRevision;
> +
> +  ///
> +  /// Reserved for future usage.
> +  ///
> +  UINT16                            Reserved;
> +
> +  ///
> +  /// The segment of the entry point within the traditional BIOS for
> Compatibility16 functions.
> +  ///
> +  UINT16                            Compatibility16CallSegment;
> +
> +  ///
> +  /// The offset of the entry point within the traditional BIOS for
> Compatibility16 functions.
> +  ///
> +  UINT16                            Compatibility16CallOffset;
> +
> +  ///
> +  /// The segment of the entry point within the traditional BIOS for
> EfiCompatibility
> +  /// to invoke the PnP installation check.
> +  ///
> +  UINT16                            PnPInstallationCheckSegment;
> +
> +  ///
> +  /// The Offset of the entry point within the traditional BIOS for
> EfiCompatibility
> +  /// to invoke the PnP installation check.
> +  ///
> +  UINT16                            PnPInstallationCheckOffset;
> +
> +  ///
> +  /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the
> IntelPlatform
> +  ///Innovation Framework for EFI Driver Execution Environment Core
> Interface Specification (DXE CIS).
> +  ///
> +  UINT32                            EfiSystemTable;
> +
> +  ///
> +  /// The address of an OEM-provided identifier string. The string is null
> terminated.
> +  ///
> +  UINT32                            OemIdStringPointer;
> +
> +  ///
> +  /// The 32-bit physical address where ACPI RSD PTR is stored within the
> traditional
> +  /// BIOS. The remained of the ACPI tables are located at their EFI addresses.
> The size
> +  /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the
> ACPI
> +  /// RSD PTR with either the ACPI 1.0b or 2.0 values.
> +  ///
> +  UINT32                            AcpiRsdPtrPointer;
> +
> +  ///
> +  /// The OEM revision number. Usage is undefined but provided for OEM
> module usage.
> +  ///
> +  UINT16                            OemRevision;
> +
> +  ///
> +  /// The 32-bit physical address where INT15 E820 data is stored within the
> traditional
> +  /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy
> the
> +  /// data to the indicated area.
> +  ///
> +  UINT32                            E820Pointer;
> +
> +  ///
> +  /// The length of the E820 data and is filled in by the EfiCompatibility code.
> +  ///
> +  UINT32                            E820Length;
> +
> +  ///
> +  /// The 32-bit physical address where the $PIR table is stored in the
> traditional BIOS.
> +  /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value
> and
> +  /// copy the data to the indicated area.
> +  ///
> +  UINT32                            IrqRoutingTablePointer;
> +
> +  ///
> +  /// The length of the $PIR table and is filled in by the EfiCompatibility code.
> +  ///
> +  UINT32                            IrqRoutingTableLength;
> +
> +  ///
> +  /// The 32-bit physical address where the MP table is stored in the
> traditional BIOS.
> +  /// The EfiCompatibility code will fill in the MpTablePtr value and copy the
> data
> +  /// to the indicated area.
> +  ///
> +  UINT32                            MpTablePtr;
> +
> +  ///
> +  /// The length of the MP table and is filled in by the EfiCompatibility code.
> +  ///
> +  UINT32                            MpTableLength;
> +
> +  ///
> +  /// The segment of the OEM-specific INT table/code.
> +  ///
> +  UINT16                            OemIntSegment;
> +
> +  ///
> +  /// The offset of the OEM-specific INT table/code.
> +  ///
> +  UINT16                            OemIntOffset;
> +
> +  ///
> +  /// The segment of the OEM-specific 32-bit table/code.
> +  ///
> +  UINT16                            Oem32Segment;
> +
> +  ///
> +  /// The offset of the OEM-specific 32-bit table/code.
> +  ///
> +  UINT16                            Oem32Offset;
> +
> +  ///
> +  /// The segment of the OEM-specific 16-bit table/code.
> +  ///
> +  UINT16                            Oem16Segment;
> +
> +  ///
> +  /// The offset of the OEM-specific 16-bit table/code.
> +  ///
> +  UINT16                            Oem16Offset;
> +
> +  ///
> +  /// The segment of the TPM binary passed to 16-bit CSM.
> +  ///
> +  UINT16                            TpmSegment;
> +
> +  ///
> +  /// The offset of the TPM binary passed to 16-bit CSM.
> +  ///
> +  UINT16                            TpmOffset;
> +
> +  ///
> +  /// A pointer to a string identifying the independent BIOS vendor.
> +  ///
> +  UINT32                            IbvPointer;
> +
> +  ///
> +  /// This field is NULL for all systems not supporting PCI Express. This field is
> the base
> +  /// value of the start of the PCI Express memory-mapped configuration
> registers and
> +  /// must be filled in prior to EfiCompatibility code issuing the
> Compatibility16 function
> +  /// Compatibility16InitializeYourself().
> +  /// Compatibility16InitializeYourself() is defined in Compatability16
> +  /// Functions.
> +  ///
> +  UINT32                            PciExpressBase;
> +
> +  ///
> +  /// Maximum PCI bus number assigned.
> +  ///
> +  UINT8                             LastPciBus;
> +
> +  ///
> +  /// Start Address of Upper Memory Area (UMA) to be set as Read/Write. If
> +  /// UmaAddress is a valid address in the shadow RAM, it also indicates that
> the region
> +  /// from 0xC0000 to (UmaAddress - 1) can be used for Option ROM.
> +  ///
> +  UINT32                            UmaAddress;
> +
> +  ///
> +  /// Upper Memory Area size in bytes to be set as Read/Write. If zero, no
> UMA region
> +  /// will be set as Read/Write (i.e. all Shadow RAM is set as Read-Only).
> +  ///
> +  UINT32                            UmaSize;
> +
> +  ///
> +  /// Start Address of high memory that can be used for permanent allocation.
> If zero,
> +  /// high memory is not available for permanent allocation.
> +  ///
> +  UINT32                            HiPermanentMemoryAddress;
> +
> +  ///
> +  /// Size of high memory that can be used for permanent allocation in bytes.
> If zero,
> +  /// high memory is not available for permanent allocation.
> +  ///
> +  UINT32                            HiPermanentMemorySize;
> +} EFI_COMPATIBILITY16_TABLE;
> +
> +///
> +/// Functions provided by the CSM binary which communicate between the
> EfiCompatibility
> +/// and Compatability16 code.
> +///
> +/// Inconsistent with the specification here:
> +/// The member's name started with "Compatibility16" [defined in Intel
> Framework
> +/// Compatibility Support Module Specification / 0.97 version]
> +/// has been changed to "Legacy16" since keeping backward compatible.
> +///
> +typedef enum {
> +  ///
> +  /// Causes the Compatibility16 code to do any internal initialization
> required.
> +  /// Input:
> +  ///   AX = Compatibility16InitializeYourself
> +  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE
> +  /// Return:
> +  ///   AX = Return Status codes
> +  ///
> +  Legacy16InitializeYourself    = 0x0000,
> +
> +  ///
> +  /// Causes the Compatibility16 BIOS to perform any drive number
> translations to match the boot sequence.
> +  /// Input:
> +  ///   AX = Compatibility16UpdateBbs
> +  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
> +  /// Return:
> +  ///   AX = Returned status codes
> +  ///
> +  Legacy16UpdateBbs             = 0x0001,
> +
> +  ///
> +  /// Allows the Compatibility16 code to perform any final actions before
> booting. The Compatibility16
> +  /// code is read/write.
> +  /// Input:
> +  ///   AX = Compatibility16PrepareToBoot
> +  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure
> +  /// Return:
> +  ///   AX = Returned status codes
> +  ///
> +  Legacy16PrepareToBoot         = 0x0002,
> +
> +  ///
> +  /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is
> Read/Only.
> +  /// Input:
> +  ///   AX = Compatibility16Boot
> +  /// Output:
> +  ///   AX = Returned status codes
> +  ///
> +  Legacy16Boot                  = 0x0003,
> +
> +  ///
> +  /// Allows the Compatibility16 code to get the last device from which a boot
> was attempted. This is
> +  /// stored in CMOS and is the priority number of the last attempted boot
> device.
> +  /// Input:
> +  ///   AX = Compatibility16RetrieveLastBootDevice
> +  /// Output:
> +  ///   AX = Returned status codes
> +  ///   BX = Priority number of the boot device.
> +  ///
> +  Legacy16RetrieveLastBootDevice = 0x0004,
> +
> +  ///
> +  /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19
> after dispatching a legacy OpROM.
> +  /// Input:
> +  ///   AX = Compatibility16DispatchOprom
> +  ///   ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE
> +  /// Output:
> +  ///   AX = Returned status codes
> +  ///   BX = Number of non-BBS-compliant devices found. Equals 0 if BBS
> compliant.
> +  ///
> +  Legacy16DispatchOprom         = 0x0005,
> +
> +  ///
> +  /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length
> and returns the address
> +  /// of that region.
> +  /// Input:
> +  ///   AX = Compatibility16GetTableAddress
> +  ///   BX = Allocation region
> +  ///       00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.
> +  ///       Bit 0 = 1 Allocate from 0xF0000 64 KB block
> +  ///       Bit 1 = 1 Allocate from 0xE0000 64 KB block
> +  ///   CX = Requested length in bytes.
> +  ///   DX = Required address alignment. Bit mapped. First non-zero bit from
> the right is the alignment.
> +  /// Output:
> +  ///   AX = Returned status codes
> +  ///   DS:BX = Address of the region
> +  ///
> +  Legacy16GetTableAddress       = 0x0006,
> +
> +  ///
> +  /// Enables the EfiCompatibility module to do any nonstandard processing
> of keyboard LEDs or state.
> +  /// Input:
> +  ///   AX = Compatibility16SetKeyboardLeds
> +  ///   CL = LED status.
> +  ///     Bit 0  Scroll Lock 0 = Off
> +  ///     Bit 1  NumLock
> +  ///     Bit 2  Caps Lock
> +  /// Output:
> +  ///     AX = Returned status codes
> +  ///
> +  Legacy16SetKeyboardLeds       = 0x0007,
> +
> +  ///
> +  /// Enables the EfiCompatibility module to install an interrupt handler for
> PCI mass media devices that
> +  /// do not have an OpROM associated with them. An example is SATA.
> +  /// Input:
> +  ///   AX = Compatibility16InstallPciHandler
> +  ///   ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure
> +  /// Output:
> +  ///   AX = Returned status codes
> +  ///
> +  Legacy16InstallPciHandler     = 0x0008
> +} EFI_COMPATIBILITY_FUNCTIONS;
> +
> +
> +///
> +/// EFI_DISPATCH_OPROM_TABLE
> +///
> +typedef struct {
> +  UINT16  PnPInstallationCheckSegment;  ///< A pointer to the
> PnpInstallationCheck data structure.
> +  UINT16  PnPInstallationCheckOffset;   ///< A pointer to the
> PnpInstallationCheck data structure.
> +  UINT16  OpromSegment;                 ///< The segment where the OpROM
> was placed. Offset is assumed to be 3.
> +  UINT8   PciBus;                       ///< The PCI bus.
> +  UINT8   PciDeviceFunction;            ///< The PCI device * 0x08 | PCI
> function.
> +  UINT8   NumberBbsEntries;             ///< The number of valid BBS table
> entries upon entry and exit. The IBV code may
> +                                        ///< increase this number, if BBS-compliant
> devices also hook INTs in order to force the
> +                                        ///< OpROM BIOS Setup to be executed.
> +  UINT32  BbsTablePointer;              ///< A pointer to the BBS table.
> +  UINT16  RuntimeSegment;               ///< The segment where the OpROM
> can be relocated to. If this value is 0x0000, this
> +                                        ///< means that the relocation of this run time
> code is not supported.
> +                                        ///< Inconsistent with specification here:
> +                                        ///< The member's name
> "OpromDestinationSegment" [defined in Intel Framework Compatibility
> Support Module Specification / 0.97 version]
> +                                        ///< has been changed to "RuntimeSegment"
> since keeping backward compatible.
> +
> +} EFI_DISPATCH_OPROM_TABLE;
> +
> +///
> +/// EFI_TO_COMPATIBILITY16_INIT_TABLE
> +///
> +typedef struct {
> +  ///
> +  /// Starting address of memory under 1 MB. The ending address is assumed
> to be 640 KB or 0x9FFFF.
> +  ///
> +  UINT32                            BiosLessThan1MB;
> +
> +  ///
> +  /// The starting address of the high memory block.
> +  ///
> +  UINT32                            HiPmmMemory;
> +
> +  ///
> +  /// The length of high memory block.
> +  ///
> +  UINT32                            HiPmmMemorySizeInBytes;
> +
> +  ///
> +  /// The segment of the reverse thunk call code.
> +  ///
> +  UINT16                            ReverseThunkCallSegment;
> +
> +  ///
> +  /// The offset of the reverse thunk call code.
> +  ///
> +  UINT16                            ReverseThunkCallOffset;
> +
> +  ///
> +  /// The number of E820 entries copied to the Compatibility16 BIOS.
> +  ///
> +  UINT32                            NumberE820Entries;
> +
> +  ///
> +  /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory.
> +  ///
> +  UINT32                            OsMemoryAbove1Mb;
> +
> +  ///
> +  /// The start of thunk code in main memory. Memory cannot be used by
> BIOS or PMM.
> +  ///
> +  UINT32                            ThunkStart;
> +
> +  ///
> +  /// The size of the thunk code.
> +  ///
> +  UINT32                            ThunkSizeInBytes;
> +
> +  ///
> +  /// Starting address of memory under 1 MB.
> +  ///
> +  UINT32                            LowPmmMemory;
> +
> +  ///
> +  /// The length of low Memory block.
> +  ///
> +  UINT32                            LowPmmMemorySizeInBytes;
> +} EFI_TO_COMPATIBILITY16_INIT_TABLE;
> +
> +///
> +/// DEVICE_PRODUCER_SERIAL.
> +///
> +typedef struct {
> +  UINT16                            Address;    ///< I/O address assigned to the
> serial port.
> +  UINT8                             Irq;        ///< IRQ assigned to the serial port.
> +  SERIAL_MODE                       Mode;       ///< Mode of serial port. Values
> are defined below.
> +} DEVICE_PRODUCER_SERIAL;
> +
> +///
> +/// DEVICE_PRODUCER_SERIAL's modes.
> +///@{
> +#define DEVICE_SERIAL_MODE_NORMAL               0x00
> +#define DEVICE_SERIAL_MODE_IRDA                 0x01
> +#define DEVICE_SERIAL_MODE_ASK_IR               0x02
> +#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00
> +#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10
> +///@)
> +
> +///
> +/// DEVICE_PRODUCER_PARALLEL.
> +///
> +typedef struct {
> +  UINT16                            Address;  ///< I/O address assigned to the
> parallel port.
> +  UINT8                             Irq;      ///< IRQ assigned to the parallel port.
> +  UINT8                             Dma;      ///< DMA assigned to the parallel port.
> +  PARALLEL_MODE                     Mode;     ///< Mode of the parallel port.
> Values are defined below.
> +} DEVICE_PRODUCER_PARALLEL;
> +
> +///
> +/// DEVICE_PRODUCER_PARALLEL's modes.
> +///@{
> +#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00
> +#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01
> +#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02
> +#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03
> +///@}
> +
> +///
> +/// DEVICE_PRODUCER_FLOPPY
> +///
> +typedef struct {
> +  UINT16                            Address;          ///< I/O address assigned to the
> floppy.
> +  UINT8                             Irq;              ///< IRQ assigned to the floppy.
> +  UINT8                             Dma;              ///< DMA assigned to the floppy.
> +  UINT8                             NumberOfFloppy;   ///< Number of floppies in
> the system.
> +} DEVICE_PRODUCER_FLOPPY;
> +
> +///
> +/// LEGACY_DEVICE_FLAGS
> +///
> +typedef struct {
> +  UINT32                            A20Kybd : 1;      ///< A20 controller by
> keyboard controller.
> +  UINT32                            A20Port90 : 1;    ///< A20 controlled by port
> 0x92.
> +  UINT32                            Reserved : 30;    ///< Reserved for future usage.
> +} LEGACY_DEVICE_FLAGS;
> +
> +///
> +/// DEVICE_PRODUCER_DATA_HEADER
> +///
> +typedef struct {
> +  DEVICE_PRODUCER_SERIAL            Serial[4];      ///< Data for serial port x.
> Type DEVICE_PRODUCER_SERIAL is defined below.
> +  DEVICE_PRODUCER_PARALLEL          Parallel[3];    ///< Data for parallel
> port x. Type DEVICE_PRODUCER_PARALLEL is defined below.
> +  DEVICE_PRODUCER_FLOPPY            Floppy;         ///< Data for floppy.
> Type DEVICE_PRODUCER_FLOPPY is defined below.
> +  UINT8                             MousePresent;   ///< Flag to indicate if mouse is
> present.
> +  LEGACY_DEVICE_FLAGS               Flags;          ///< Miscellaneous Boolean
> state information passed to CSM.
> +} DEVICE_PRODUCER_DATA_HEADER;
> +
> +///
> +/// ATAPI_IDENTIFY
> +///
> +typedef struct {
> +  UINT16                            Raw[256];     ///< Raw data from the IDE
> IdentifyDrive command.
> +} ATAPI_IDENTIFY;
> +
> +///
> +/// HDD_INFO
> +///
> +typedef struct {
> +  ///
> +  /// Status of IDE device. Values are defined below. There is one HDD_INFO
> structure
> +  /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and
> index
> +  /// 1 is slave.
> +  ///
> +  UINT16                            Status;
> +
> +  ///
> +  /// PCI bus of IDE controller.
> +  ///
> +  UINT32                            Bus;
> +
> +  ///
> +  /// PCI device of IDE controller.
> +  ///
> +  UINT32                            Device;
> +
> +  ///
> +  /// PCI function of IDE controller.
> +  ///
> +  UINT32                            Function;
> +
> +  ///
> +  /// Command ports base address.
> +  ///
> +  UINT16                            CommandBaseAddress;
> +
> +  ///
> +  /// Control ports base address.
> +  ///
> +  UINT16                            ControlBaseAddress;
> +
> +  ///
> +  /// Bus master address.
> +  ///
> +  UINT16                            BusMasterAddress;
> +
> +  UINT8                             HddIrq;
> +
> +  ///
> +  /// Data that identifies the drive data; one per possible attached drive.
> +  ///
> +  ATAPI_IDENTIFY                    IdentifyDrive[2];
> +} HDD_INFO;
> +
> +///
> +/// HDD_INFO status bits
> +///
> +#define HDD_PRIMARY               0x01
> +#define HDD_SECONDARY             0x02
> +#define HDD_MASTER_ATAPI_CDROM    0x04
> +#define HDD_SLAVE_ATAPI_CDROM     0x08
> +#define HDD_MASTER_IDE            0x20
> +#define HDD_SLAVE_IDE             0x40
> +#define HDD_MASTER_ATAPI_ZIPDISK  0x10
> +#define HDD_SLAVE_ATAPI_ZIPDISK   0x80
> +
> +///
> +/// BBS_STATUS_FLAGS;\.
> +///
> +typedef struct {
> +  UINT16                            OldPosition : 4;    ///< Prior priority.
> +  UINT16                            Reserved1 : 4;      ///< Reserved for future use.
> +  UINT16                            Enabled : 1;        ///< If 0, ignore this entry.
> +  UINT16                            Failed : 1;         ///< 0 = Not known if boot
> failure occurred.
> +                                                        ///< 1 = Boot attempted failed.
> +
> +  ///
> +  /// State of media present.
> +  ///   00 = No bootable media is present in the device.
> +  ///   01 = Unknown if a bootable media present.
> +  ///   10 = Media is present and appears bootable.
> +  ///   11 = Reserved.
> +  ///
> +  UINT16                            MediaPresent : 2;
> +  UINT16                            Reserved2 : 4;      ///< Reserved for future use.
> +} BBS_STATUS_FLAGS;
> +
> +///
> +/// BBS_TABLE, device type values & boot priority values.
> +///
> +typedef struct {
> +  ///
> +  /// The boot priority for this boot device. Values are defined below.
> +  ///
> +  UINT16                            BootPriority;
> +
> +  ///
> +  /// The PCI bus for this boot device.
> +  ///
> +  UINT32                            Bus;
> +
> +  ///
> +  /// The PCI device for this boot device.
> +  ///
> +  UINT32                            Device;
> +
> +  ///
> +  /// The PCI function for the boot device.
> +  ///
> +  UINT32                            Function;
> +
> +  ///
> +  /// The PCI class for this boot device.
> +  ///
> +  UINT8                             Class;
> +
> +  ///
> +  /// The PCI Subclass for this boot device.
> +  ///
> +  UINT8                             SubClass;
> +
> +  ///
> +  /// Segment:offset address of an ASCIIZ description string describing the
> manufacturer.
> +  ///
> +  UINT16                            MfgStringOffset;
> +
> +  ///
> +  /// Segment:offset address of an ASCIIZ description string describing the
> manufacturer.
> +  ///
> +  UINT16                            MfgStringSegment;
> +
> +  ///
> +  /// BBS device type. BBS device types are defined below.
> +  ///
> +  UINT16                            DeviceType;
> +
> +  ///
> +  /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below.
> +  ///
> +  BBS_STATUS_FLAGS                  StatusFlags;
> +
> +  ///
> +  /// Segment:Offset address of boot loader for IPL devices or install INT13
> handler for
> +  /// BCV devices.
> +  ///
> +  UINT16                            BootHandlerOffset;
> +
> +  ///
> +  /// Segment:Offset address of boot loader for IPL devices or install INT13
> handler for
> +  /// BCV devices.
> +  ///
> +  UINT16                            BootHandlerSegment;
> +
> +  ///
> +  /// Segment:offset address of an ASCIIZ description string describing this
> device.
> +  ///
> +  UINT16                            DescStringOffset;
> +
> +  ///
> +  /// Segment:offset address of an ASCIIZ description string describing this
> device.
> +  ///
> +  UINT16                            DescStringSegment;
> +
> +  ///
> +  /// Reserved.
> +  ///
> +  UINT32                            InitPerReserved;
> +
> +  ///
> +  /// The use of these fields is IBV dependent. They can be used to flag that an
> OpROM
> +  /// has hooked the specified IRQ. The OpROM may be BBS compliant as
> some SCSI
> +  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS
> Setup
> +  ///
> +  UINT32                            AdditionalIrq13Handler;
> +
> +  ///
> +  /// The use of these fields is IBV dependent. They can be used to flag that an
> OpROM
> +  /// has hooked the specified IRQ. The OpROM may be BBS compliant as
> some SCSI
> +  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS
> Setup
> +  ///
> +  UINT32                            AdditionalIrq18Handler;
> +
> +  ///
> +  /// The use of these fields is IBV dependent. They can be used to flag that an
> OpROM
> +  /// has hooked the specified IRQ. The OpROM may be BBS compliant as
> some SCSI
> +  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS
> Setup
> +  ///
> +  UINT32                            AdditionalIrq19Handler;
> +
> +  ///
> +  /// The use of these fields is IBV dependent. They can be used to flag that an
> OpROM
> +  /// has hooked the specified IRQ. The OpROM may be BBS compliant as
> some SCSI
> +  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS
> Setup
> +  ///
> +  UINT32                            AdditionalIrq40Handler;
> +  UINT8                             AssignedDriveNumber;
> +  UINT32                            AdditionalIrq41Handler;
> +  UINT32                            AdditionalIrq46Handler;
> +  UINT32                            IBV1;
> +  UINT32                            IBV2;
> +} BBS_TABLE;
> +
> +///
> +/// BBS device type values
> +///@{
> +#define BBS_FLOPPY              0x01
> +#define BBS_HARDDISK            0x02
> +#define BBS_CDROM               0x03
> +#define BBS_PCMCIA              0x04
> +#define BBS_USB                 0x05
> +#define BBS_EMBED_NETWORK       0x06
> +#define BBS_BEV_DEVICE          0x80
> +#define BBS_UNKNOWN             0xff
> +///@}
> +
> +///
> +/// BBS boot priority values
> +///@{
> +#define BBS_DO_NOT_BOOT_FROM    0xFFFC
> +#define BBS_LOWEST_PRIORITY     0xFFFD
> +#define BBS_UNPRIORITIZED_ENTRY 0xFFFE
> +#define BBS_IGNORE_ENTRY        0xFFFF
> +///@}
> +
> +///
> +/// SMM_ATTRIBUTES
> +///
> +typedef struct {
> +  ///
> +  /// Access mechanism used to generate the soft SMI. Defined types are
> below. The other
> +  /// values are reserved for future usage.
> +  ///
> +  UINT16                            Type : 3;
> +
> +  ///
> +  /// The size of "port" in bits. Defined values are below.
> +  ///
> +  UINT16                            PortGranularity : 3;
> +
> +  ///
> +  /// The size of data in bits. Defined values are below.
> +  ///
> +  UINT16                            DataGranularity : 3;
> +
> +  ///
> +  /// Reserved for future use.
> +  ///
> +  UINT16                            Reserved : 7;
> +} SMM_ATTRIBUTES;
> +
> +///
> +/// SMM_ATTRIBUTES type values.
> +///@{
> +#define STANDARD_IO       0x00
> +#define STANDARD_MEMORY   0x01
> +///@}
> +
> +///
> +/// SMM_ATTRIBUTES port size constants.
> +///@{
> +#define PORT_SIZE_8       0x00
> +#define PORT_SIZE_16      0x01
> +#define PORT_SIZE_32      0x02
> +#define PORT_SIZE_64      0x03
> +///@}
> +
> +///
> +/// SMM_ATTRIBUTES data size constants.
> +///@{
> +#define DATA_SIZE_8       0x00
> +#define DATA_SIZE_16      0x01
> +#define DATA_SIZE_32      0x02
> +#define DATA_SIZE_64      0x03
> +///@}
> +
> +///
> +/// SMM_FUNCTION & relating constants.
> +///
> +typedef struct {
> +  UINT16                            Function : 15;
> +  UINT16                            Owner : 1;
> +} SMM_FUNCTION;
> +
> +///
> +/// SMM_FUNCTION Function constants.
> +///@{
> +#define INT15_D042        0x0000
> +#define GET_USB_BOOT_INFO 0x0001
> +#define DMI_PNP_50_57     0x0002
> +///@}
> +
> +///
> +/// SMM_FUNCTION Owner constants.
> +///@{
> +#define STANDARD_OWNER    0x0
> +#define OEM_OWNER         0x1
> +///@}
> +
> +///
> +/// This structure assumes both port and data sizes are 1. SmmAttribute must
> be
> +/// properly to reflect that assumption.
> +///
> +typedef struct {
> +  ///
> +  /// Describes the access mechanism, SmmPort, and SmmData sizes. Type
> +  /// SMM_ATTRIBUTES is defined below.
> +  ///
> +  SMM_ATTRIBUTES                    SmmAttributes;
> +
> +  ///
> +  /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below.
> +  ///
> +  SMM_FUNCTION                      SmmFunction;
> +
> +  ///
> +  /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to
> 16 bytes.
> +  ///
> +  UINT8                             SmmPort;
> +
> +  ///
> +  /// SmmData size depends upon SmmAttributes and ranges from2 bytes to
> 16 bytes.
> +  ///
> +  UINT8                             SmmData;
> +} SMM_ENTRY;
> +
> +///
> +/// SMM_TABLE
> +///
> +typedef struct {
> +  UINT16                            NumSmmEntries;    ///< Number of entries
> represented by SmmEntry.
> +  SMM_ENTRY                         SmmEntry;         ///< One entry per
> function. Type SMM_ENTRY is defined below.
> +} SMM_TABLE;
> +
> +///
> +/// UDC_ATTRIBUTES
> +///
> +typedef struct {
> +  ///
> +  /// This bit set indicates that the ServiceAreaData is valid.
> +  ///
> +  UINT8                             DirectoryServiceValidity : 1;
> +
> +  ///
> +  /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA)
> only if
> +  /// DirectoryServiceValidity is 0.
> +  ///
> +  UINT8                             RabcaUsedFlag : 1;
> +
> +  ///
> +  /// This bit set indicates to execute hard disk diagnostics.
> +  ///
> +  UINT8                             ExecuteHddDiagnosticsFlag : 1;
> +
> +  ///
> +  /// Reserved for future use. Set to 0.
> +  ///
> +  UINT8                             Reserved : 5;
> +} UDC_ATTRIBUTES;
> +
> +///
> +/// UD_TABLE
> +///
> +typedef struct {
> +  ///
> +  /// This field contains the bit-mapped attributes of the PARTIES information.
> Type
> +  /// UDC_ATTRIBUTES is defined below.
> +  ///
> +  UDC_ATTRIBUTES                    Attributes;
> +
> +  ///
> +  /// This field contains the zero-based device on which the selected
> +  /// ServiceDataArea is present. It is 0 for master and 1 for the slave device.
> +  ///
> +  UINT8                             DeviceNumber;
> +
> +  ///
> +  /// This field contains the zero-based index into the BbsTable for the parent
> device.
> +  /// This index allows the user to reference the parent device information
> such as PCI
> +  /// bus, device function.
> +  ///
> +  UINT8                             BbsTableEntryNumberForParentDevice;
> +
> +  ///
> +  /// This field contains the zero-based index into the BbsTable for the boot
> entry.
> +  ///
> +  UINT8                             BbsTableEntryNumberForBoot;
> +
> +  ///
> +  /// This field contains the zero-based index into the BbsTable for the HDD
> diagnostics entry.
> +  ///
> +  UINT8                             BbsTableEntryNumberForHddDiag;
> +
> +  ///
> +  /// The raw Beer data.
> +  ///
> +  UINT8                             BeerData[128];
> +
> +  ///
> +  /// The raw data of selected service area.
> +  ///
> +  UINT8                             ServiceAreaData[64];
> +} UD_TABLE;
> +
> +#define EFI_TO_LEGACY_MAJOR_VERSION 0x02
> +#define EFI_TO_LEGACY_MINOR_VERSION 0x00
> +#define MAX_IDE_CONTROLLER          8
> +
> +///
> +/// EFI_TO_COMPATIBILITY16_BOOT_TABLE
> +///
> +typedef struct {
> +  UINT16                            MajorVersion;                 ///< The
> EfiCompatibility major version number.
> +  UINT16                            MinorVersion;                 ///< The
> EfiCompatibility minor version number.
> +  UINT32                            AcpiTable;                    ///< The location of
> the RSDT ACPI table. < 4G range.
> +  UINT32                            SmbiosTable;                  ///< The location of
> the SMBIOS table in EFI memory. < 4G range.
> +  UINT32                            SmbiosTableLength;
> +  //
> +  // Legacy SIO state
> +  //
> +  DEVICE_PRODUCER_DATA_HEADER       SioData;                      ///<
> Standard traditional device information.
> +  UINT16                            DevicePathType;               ///< The default
> boot type.
> +  UINT16                            PciIrqMask;                   ///< Mask of which
> IRQs have been assigned to PCI.
> +  UINT32                            NumberE820Entries;            ///< Number of
> E820 entries. The number can change from the
> +                                                                  ///<
> Compatibility16InitializeYourself() function.
> +  //
> +  // Controller & Drive Identify[2] per controller information
> +  //
> +  HDD_INFO                          HddInfo[MAX_IDE_CONTROLLER];  ///< Hard
> disk drive information, including raw Identify Drive data.
> +  UINT32                            NumberBbsEntries;             ///< Number of
> entries in the BBS table
> +  UINT32                            BbsTable;                     ///< A pointer to the
> BBS table. Type BBS_TABLE is defined below.
> +  UINT32                            SmmTable;                     ///< A pointer to the
> SMM table. Type SMM_TABLE is defined below.
> +  UINT32                            OsMemoryAbove1Mb;             ///< The
> amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can
> +                                                                  ///< differ from the value in
> EFI_TO_COMPATIBILITY16_INIT_TABLE as more
> +                                                                  ///< memory may have been
> discovered.
> +  UINT32                            UnconventionalDeviceTable;    ///<
> Information to boot off an unconventional device like a PARTIES partition. Type
> +                                                                  ///< UD_TABLE is defined
> below.
> +} EFI_TO_COMPATIBILITY16_BOOT_TABLE;
> +
> +///
> +/// EFI_LEGACY_INSTALL_PCI_HANDLER
> +///
> +typedef struct {
> +  UINT8                             PciBus;             ///< The PCI bus of the device.
> +  UINT8                             PciDeviceFun;       ///< The PCI device in bits 7:3
> and function in bits 2:0.
> +  UINT8                             PciSegment;         ///< The PCI segment of the
> device.
> +  UINT8                             PciClass;           ///< The PCI class code of the
> device.
> +  UINT8                             PciSubclass;        ///< The PCI subclass code of
> the device.
> +  UINT8                             PciInterface;       ///< The PCI interface code of
> the device.
> +  //
> +  // Primary section
> +  //
> +  UINT8                             PrimaryIrq;         ///< The primary device IRQ.
> +  UINT8                             PrimaryReserved;    ///< Reserved.
> +  UINT16                            PrimaryControl;     ///< The primary device
> control I/O base.
> +  UINT16                            PrimaryBase;        ///< The primary device I/O
> base.
> +  UINT16                            PrimaryBusMaster;   ///< The primary device
> bus master I/O base.
> +  //
> +  // Secondary Section
> +  //
> +  UINT8                             SecondaryIrq;       ///< The secondary device
> IRQ.
> +  UINT8                             SecondaryReserved;  ///< Reserved.
> +  UINT16                            SecondaryControl;   ///< The secondary device
> control I/O base.
> +  UINT16                            SecondaryBase;      ///< The secondary device
> I/O base.
> +  UINT16                            SecondaryBusMaster; ///< The secondary
> device bus master I/O base.
> +} EFI_LEGACY_INSTALL_PCI_HANDLER;
> +
> +//
> +// Restore default pack value
> +//
> +#pragma pack()
> +
> +#define EFI_LEGACY_BIOS_PROTOCOL_GUID \
> +  { \
> +    0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e,
> 0x2d } \
> +  }
> +
> +typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL;
> +
> +///
> +/// Flags returned by CheckPciRom().
> +///
> +#define NO_ROM            0x00
> +#define ROM_FOUND         0x01
> +#define VALID_LEGACY_ROM  0x02
> +#define ROM_WITH_CONFIG   0x04     ///< Not defined in the Framework
> CSM Specification.
> +
> +///
> +/// The following macros do not appear in the Framework CSM Specification
> and
> +/// are kept for backward compatibility only.  They convert 32-bit address
> (_Adr)
> +/// to Segment:Offset 16-bit form.
> +///
> +///@{
> +#define EFI_SEGMENT(_Adr)     (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) &
> 0xf000)
> +#define EFI_OFFSET(_Adr)      (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)
> +///@}
> +
> +#define CARRY_FLAG            0x01
> +
> +///
> +/// EFI_EFLAGS_REG
> +///
> +typedef struct {
> +  UINT32 CF:1;
> +  UINT32 Reserved1:1;
> +  UINT32 PF:1;
> +  UINT32 Reserved2:1;
> +  UINT32 AF:1;
> +  UINT32 Reserved3:1;
> +  UINT32 ZF:1;
> +  UINT32 SF:1;
> +  UINT32 TF:1;
> +  UINT32 IF:1;
> +  UINT32 DF:1;
> +  UINT32 OF:1;
> +  UINT32 IOPL:2;
> +  UINT32 NT:1;
> +  UINT32 Reserved4:2;
> +  UINT32 VM:1;
> +  UINT32 Reserved5:14;
> +} EFI_EFLAGS_REG;
> +
> +///
> +/// EFI_DWORD_REGS
> +///
> +typedef struct {
> +    UINT32           EAX;
> +    UINT32           EBX;
> +    UINT32           ECX;
> +    UINT32           EDX;
> +    UINT32           ESI;
> +    UINT32           EDI;
> +    EFI_EFLAGS_REG   EFlags;
> +    UINT16           ES;
> +    UINT16           CS;
> +    UINT16           SS;
> +    UINT16           DS;
> +    UINT16           FS;
> +    UINT16           GS;
> +    UINT32           EBP;
> +    UINT32           ESP;
> +} EFI_DWORD_REGS;
> +
> +///
> +/// EFI_FLAGS_REG
> +///
> +typedef struct {
> +  UINT16     CF:1;
> +  UINT16     Reserved1:1;
> +  UINT16     PF:1;
> +  UINT16     Reserved2:1;
> +  UINT16     AF:1;
> +  UINT16     Reserved3:1;
> +  UINT16     ZF:1;
> +  UINT16     SF:1;
> +  UINT16     TF:1;
> +  UINT16     IF:1;
> +  UINT16     DF:1;
> +  UINT16     OF:1;
> +  UINT16     IOPL:2;
> +  UINT16     NT:1;
> +  UINT16     Reserved4:1;
> +} EFI_FLAGS_REG;
> +
> +///
> +/// EFI_WORD_REGS
> +///
> +typedef struct {
> +    UINT16           AX;
> +    UINT16           ReservedAX;
> +    UINT16           BX;
> +    UINT16           ReservedBX;
> +    UINT16           CX;
> +    UINT16           ReservedCX;
> +    UINT16           DX;
> +    UINT16           ReservedDX;
> +    UINT16           SI;
> +    UINT16           ReservedSI;
> +    UINT16           DI;
> +    UINT16           ReservedDI;
> +    EFI_FLAGS_REG    Flags;
> +    UINT16           ReservedFlags;
> +    UINT16           ES;
> +    UINT16           CS;
> +    UINT16           SS;
> +    UINT16           DS;
> +    UINT16           FS;
> +    UINT16           GS;
> +    UINT16           BP;
> +    UINT16           ReservedBP;
> +    UINT16           SP;
> +    UINT16           ReservedSP;
> +} EFI_WORD_REGS;
> +
> +///
> +/// EFI_BYTE_REGS
> +///
> +typedef struct {
> +    UINT8   AL, AH;
> +    UINT16  ReservedAX;
> +    UINT8   BL, BH;
> +    UINT16  ReservedBX;
> +    UINT8   CL, CH;
> +    UINT16  ReservedCX;
> +    UINT8   DL, DH;
> +    UINT16  ReservedDX;
> +} EFI_BYTE_REGS;
> +
> +///
> +/// EFI_IA32_REGISTER_SET
> +///
> +typedef union {
> +  EFI_DWORD_REGS  E;
> +  EFI_WORD_REGS   X;
> +  EFI_BYTE_REGS   H;
> +} EFI_IA32_REGISTER_SET;
> +
> +/**
> +  Thunk to 16-bit real mode and execute a software interrupt with a vector
> +  of BiosInt. Regs will contain the 16-bit register context on entry and
> +  exit.
> +
> +  @param[in]     This      The protocol instance pointer.
> +  @param[in]     BiosInt   The processor interrupt vector to invoke.
> +  @param[in,out] Reg       Register contexted passed into (and returned)
> from thunk to
> +                           16-bit mode.
> +
> +  @retval TRUE                Thunk completed with no BIOS errors in the target
> code. See Regs for status.
> +  @retval FALSE                  There was a BIOS error in the target code.
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *EFI_LEGACY_BIOS_INT86)(
> +  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN     UINT8                     BiosInt,
> +  IN OUT EFI_IA32_REGISTER_SET     *Regs
> +  );
> +
> +/**
> +  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the
> +  16-bit register context on entry and exit. Arguments can be passed on
> +  the Stack argument
> +
> +  @param[in] This        The protocol instance pointer.
> +  @param[in] Segment     The segemnt of 16-bit mode call.
> +  @param[in] Offset      The offset of 16-bit mdoe call.
> +  @param[in] Reg         Register contexted passed into (and returned) from
> thunk to
> +                         16-bit mode.
> +  @param[in] Stack       The caller allocated stack used to pass arguments.
> +  @param[in] StackSize   The size of Stack in bytes.
> +
> +  @retval FALSE                 Thunk completed with no BIOS errors in the
> target code.                                See Regs for status.  @retval TRUE
> There was a BIOS error in the target code.
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *EFI_LEGACY_BIOS_FARCALL86)(
> +  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN UINT16                    Segment,
> +  IN UINT16                    Offset,
> +  IN EFI_IA32_REGISTER_SET     *Regs,
> +  IN VOID                      *Stack,
> +  IN UINTN                     StackSize
> +  );
> +
> +/**
> +  Test to see if a legacy PCI ROM exists for this device. Optionally return
> +  the Legacy ROM instance for this PCI device.
> +
> +  @param[in]  This        The protocol instance pointer.
> +  @param[in]  PciHandle   The PCI PC-AT OPROM from this devices ROM BAR
> will be loaded
> +  @param[out] RomImage    Return the legacy PCI ROM for this device.
> +  @param[out] RomSize     The size of ROM Image.
> +  @param[out] Flags       Indicates if ROM found and if PC-AT. Multiple bits
> can be set as follows:
> +                            - 00 = No ROM.
> +                            - 01 = ROM Found.
> +                            - 02 = ROM is a valid legacy ROM.
> +
> +  @retval EFI_SUCCESS       The Legacy Option ROM available for this device
> +  @retval EFI_UNSUPPORTED   The Legacy Option ROM is not supported.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM)(
> +  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN  EFI_HANDLE                PciHandle,
> +  OUT VOID                      **RomImage, OPTIONAL
> +  OUT UINTN                     *RomSize, OPTIONAL
> +  OUT UINTN                     *Flags
> +  );
> +
> +/**
> +  Load a legacy PC-AT OPROM on the PciHandle device. Return information
> +  about how many disks were added by the OPROM and the shadow address
> and
> +  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:
> +
> +  @param[in]  This               The protocol instance pointer.
> +  @param[in]  PciHandle          The PCI PC-AT OPROM from this devices ROM
> BAR will be loaded.
> +                                 This value is NULL if RomImage is non-NULL. This is
> the normal
> +                                 case.
> +  @param[in]  RomImage           A PCI PC-AT ROM image. This argument is
> non-NULL if there is
> +                                 no hardware associated with the ROM and thus no
> PciHandle,
> +                                 otherwise is must be NULL.
> +                                 Example is PXE base code.
> +  @param[out] Flags              The type of ROM discovered. Multiple bits can
> be set, as follows:
> +                                   - 00 = No ROM.
> +                                   - 01 = ROM found.
> +                                   - 02 = ROM is a valid legacy ROM.
> +  @param[out] DiskStart          The disk number of first device hooked by the
> ROM. If DiskStart
> +                                 is the same as DiskEnd no disked were hooked.
> +  @param[out] DiskEnd            disk number of the last device hooked by the
> ROM.
> +  @param[out] RomShadowAddress   Shadow address of PC-AT ROM.
> +  @param[out] RomShadowSize      Size of RomShadowAddress in bytes.
> +
> +  @retval EFI_SUCCESS             Thunk completed, see Regs for status.
> +  @retval EFI_INVALID_PARAMETER   PciHandle not found
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM)(
> +  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN  EFI_HANDLE                PciHandle,
> +  IN  VOID                      **RomImage,
> +  OUT UINTN                     *Flags,
> +  OUT UINT8                     *DiskStart, OPTIONAL
> +  OUT UINT8                     *DiskEnd, OPTIONAL
> +  OUT VOID                      **RomShadowAddress, OPTIONAL
> +  OUT UINT32                    *ShadowedRomSize OPTIONAL
> +  );
> +
> +/**
> +  This function attempts to traditionally boot the specified BootOption. If the
> EFI context has
> +  been compromised, this function will not return. This procedure is not used
> for loading an EFI-aware
> +  OS off a traditional device. The following actions occur:
> +  - Get EFI SMBIOS data structures, convert them to a traditional format, and
> copy to
> +    Compatibility16.
> +  - Get a pointer to ACPI data structures and copy the Compatibility16 RSD
> PTR to F0000 block.
> +  - Find the traditional SMI handler from a firmware volume and register the
> traditional SMI
> +    handler with the EFI SMI handler.
> +  - Build onboard IDE information and pass this information to the
> Compatibility16 code.
> +  - Make sure all PCI Interrupt Line registers are programmed to match 8259.
> +  - Reconfigure SIO devices from EFI mode (polled) into traditional mode
> (interrupt driven).
> +  - Shadow all PCI ROMs.
> +  - Set up BDA and EBDA standard areas before the legacy boot.
> +  - Construct the Compatibility16 boot memory map and pass it to the
> Compatibility16 code.
> +  - Invoke the Compatibility16 table function
> Compatibility16PrepareToBoot(). This
> +    invocation causes a thunk into the Compatibility16 code, which sets all
> appropriate internal
> +    data structures. The boot device list is a parameter.
> +  - Invoke the Compatibility16 Table function Compatibility16Boot(). This
> invocation
> +    causes a thunk into the Compatibility16 code, which does an INT19.
> +  - If the Compatibility16Boot() function returns, then the boot failed in a
> graceful
> +    manner--meaning that the EFI code is still valid. An ungraceful boot failure
> causes a reset because the state
> +    of EFI code is unknown.
> +
> +  @param[in] This             The protocol instance pointer.
> +  @param[in] BootOption       The EFI Device Path from BootXXXX variable.
> +  @param[in] LoadOptionSize   The size of LoadOption in size.
> +  @param[in] LoadOption       LThe oadOption from BootXXXX variable.
> +
> +  @retval EFI_DEVICE_ERROR      Failed to boot from any boot device and
> memory is uncorrupted.                                Note: This function normally
> does not returns. It will either boot the                                OS or reset the
> system if memory has been "corrupted" by loading                                a
> boot sector and passing control to it.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_BOOT)(
> +  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN BBS_BBS_DEVICE_PATH       *BootOption,
> +  IN UINT32                    LoadOptionsSize,
> +  IN VOID                      *LoadOptions
> +  );
> +
> +/**
> +  This function takes the Leds input parameter and sets/resets the BDA
> accordingly.
> +  Leds is also passed to Compatibility16 code, in case any special processing
> is required.
> +  This function is normally called from EFI Setup drivers that handle
> user-selectable
> +  keyboard options such as boot with NUM LOCK on/off. This function does
> not
> +  touch the keyboard or keyboard LEDs but only the BDA.
> +
> +  @param[in] This   The protocol instance pointer.
> +  @param[in] Leds   The status of current Scroll, Num & Cap lock LEDS:
> +                      - Bit 0 is Scroll Lock 0 = Not locked.
> +                      - Bit 1 is Num Lock.
> +                      - Bit 2 is Caps Lock.
> +
> +  @retval EFI_SUCCESS   The BDA was updated successfully.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)(
> +  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN UINT8                     Leds
> +  );
> +
> +/**
> +  Retrieve legacy BBS info and assign boot priority.
> +
> +  @param[in]     This       The protocol instance pointer.
> +  @param[out]    HddCount   The number of HDD_INFO structures.
> +  @param[out]    HddInfo    Onboard IDE controller information.
> +  @param[out]    BbsCount   The number of BBS_TABLE structures.
> +  @param[in,out] BbsTable   Points to List of BBS_TABLE.
> +
> +  @retval EFI_SUCCESS   Tables were returned.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO)(
> +  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  OUT    UINT16                    *HddCount,
> +  OUT    HDD_INFO                  **HddInfo,
> +  OUT    UINT16                    *BbsCount,
> +  IN OUT BBS_TABLE                 **BbsTable
> +  );
> +
> +/**
> +  Assign drive number to legacy HDD drives prior to booting an EFI
> +  aware OS so the OS can access drives without an EFI driver.
> +
> +  @param[in]  This       The protocol instance pointer.
> +  @param[out] BbsCount   The number of BBS_TABLE structures
> +  @param[out] BbsTable   List of BBS entries
> +
> +  @retval EFI_SUCCESS   Drive numbers assigned.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)(
> +  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  OUT UINT16                    *BbsCount,
> +  OUT BBS_TABLE                 **BbsTable
> +  );
> +
> +/**
> +  To boot from an unconventional device like parties and/or execute
> +  HDD diagnostics.
> +
> +  @param[in]  This              The protocol instance pointer.
> +  @param[in]  Attributes        How to interpret the other input parameters.
> +  @param[in]  BbsEntry          The 0-based index into the BbsTable for the
> parent
> +                                device.
> +  @param[in]  BeerData          A pointer to the 128 bytes of ram BEER data.
> +  @param[in]  ServiceAreaData   A pointer to the 64 bytes of raw Service
> Area data. The
> +                                caller must provide a pointer to the specific Service
> +                                Area and not the start all Service Areas.
> +
> +  @retval EFI_INVALID_PARAMETER   If error. Does NOT return if no error.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)(
> +  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN UDC_ATTRIBUTES            Attributes,
> +  IN UINTN                     BbsEntry,
> +  IN VOID                      *BeerData,
> +  IN VOID                      *ServiceAreaData
> +  );
> +
> +/**
> +  Shadow all legacy16 OPROMs that haven't been shadowed.
> +  Warning: Use this with caution. This routine disconnects all EFI
> +  drivers. If used externally, then  the caller must re-connect EFI
> +  drivers.
> +
> +  @param[in]  This   The protocol instance pointer.
> +
> +  @retval EFI_SUCCESS   OPROMs were shadowed.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)(
> +  IN EFI_LEGACY_BIOS_PROTOCOL  *This
> +  );
> +
> +/**
> +  Get a region from the LegacyBios for S3 usage.
> +
> +  @param[in]  This                  The protocol instance pointer.
> +  @param[in]  LegacyMemorySize      The size of required region.
> +  @param[in]  Region                The region to use.
> +                                    00 = Either 0xE0000 or 0xF0000 block.
> +                                      - Bit0 = 1 0xF0000 block.
> +                                      - Bit1 = 1 0xE0000 block.
> +  @param[in]  Alignment             Address alignment. Bit mapped. The first
> non-zero
> +                                    bit from right is alignment.
> +  @param[out] LegacyMemoryAddress   The Region Assigned
> +
> +  @retval EFI_SUCCESS           The Region was assigned.
> +  @retval EFI_ACCESS_DENIED     The function was previously invoked.
> +  @retval Other                 The Region was not assigned.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION)(
> +  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN  UINTN                     LegacyMemorySize,
> +  IN  UINTN                     Region,
> +  IN  UINTN                     Alignment,
> +  OUT VOID                      **LegacyMemoryAddress
> +  );
> +
> +/**
> +  Get a region from the LegacyBios for Tiano usage. Can only be invoked once.
> +
> +  @param[in]  This                        The protocol instance pointer.
> +  @param[in]  LegacyMemorySize            The size of data to copy.
> +  @param[in]  LegacyMemoryAddress         The Legacy Region destination
> address.
> +                                          Note: must be in region assigned by
> +                                          LegacyBiosGetLegacyRegion.
> +  @param[in]  LegacyMemorySourceAddress   The source of the data to
> copy.
> +
> +  @retval EFI_SUCCESS           The Region assigned.
> +  @retval EFI_ACCESS_DENIED     Destination was outside an assigned
> region.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION)(
> +  IN EFI_LEGACY_BIOS_PROTOCOL  *This,
> +  IN UINTN                     LegacyMemorySize,
> +  IN VOID                      *LegacyMemoryAddress,
> +  IN VOID                      *LegacyMemorySourceAddress
> +  );
> +
> +///
> +/// Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot()
> +/// member function allows the BDS to support booting a traditional OS.
> +/// EFI thunks drivers that make EFI bindings for BIOS INT services use
> +/// all the other member functions.
> +///
> +struct _EFI_LEGACY_BIOS_PROTOCOL {
> +  ///
> +  /// Performs traditional software INT. See the Int86() function description.
> +  ///
> +  EFI_LEGACY_BIOS_INT86                       Int86;
> +
> +  ///
> +  /// Performs a far call into Compatibility16 or traditional OpROM code.
> +  ///
> +  EFI_LEGACY_BIOS_FARCALL86                   FarCall86;
> +
> +  ///
> +  /// Checks if a traditional OpROM exists for this device.
> +  ///
> +  EFI_LEGACY_BIOS_CHECK_ROM                   CheckPciRom;
> +
> +  ///
> +  /// Loads a traditional OpROM in traditional OpROM address space.
> +  ///
> +  EFI_LEGACY_BIOS_INSTALL_ROM                 InstallPciRom;
> +
> +  ///
> +  /// Boots a traditional OS.
> +  ///
> +  EFI_LEGACY_BIOS_BOOT                        LegacyBoot;
> +
> +  ///
> +  /// Updates BDA to reflect the current EFI keyboard LED status.
> +  ///
> +  EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS
> UpdateKeyboardLedStatus;
> +
> +  ///
> +  /// Allows an external agent, such as BIOS Setup, to get the BBS data.
> +  ///
> +  EFI_LEGACY_BIOS_GET_BBS_INFO                GetBbsInfo;
> +
> +  ///
> +  /// Causes all legacy OpROMs to be shadowed.
> +  ///
> +  EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS
> ShadowAllLegacyOproms;
> +
> +  ///
> +  /// Performs all actions prior to boot. Used when booting an EFI-aware OS
> +  /// rather than a legacy OS.
> +  ///
> +  EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI         PrepareToBootEfi;
> +
> +  ///
> +  /// Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block.
> +  ///
> +  EFI_LEGACY_BIOS_GET_LEGACY_REGION           GetLegacyRegion;
> +
> +  ///
> +  /// Allows EFI to copy data to the area specified by GetLegacyRegion.
> +  ///
> +  EFI_LEGACY_BIOS_COPY_LEGACY_REGION          CopyLegacyRegion;
> +
> +  ///
> +  /// Allows the user to boot off an unconventional device such as a PARTIES
> partition.
> +  ///
> +  EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE
> BootUnconventionalDevice;
> +};
> +
> +extern EFI_GUID gEfiLegacyBiosProtocolGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Protocol/LegacyInterrupt.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Protocol/LegacyInterrupt.h
> new file mode 100644
> index 0000000000..1d776793d2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Includ
> e/Protocol/LegacyInterrupt.h
> @@ -0,0 +1,118 @@
> +/** @file
> +  This protocol abstracts the PIRQ programming from the generic EFI
> Compatibility Support Modules (CSMs).
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _EFI_LEGACY_INTERRUPT_H_
> +#define _EFI_LEGACY_INTERRUPT_H_
> +
> +
> +#define EFI_LEGACY_INTERRUPT_PROTOCOL_GUID \
> +  { \
> +    0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66,
> 0xbe } \
> +  }
> +
> +typedef struct _EFI_LEGACY_INTERRUPT_PROTOCOL
> EFI_LEGACY_INTERRUPT_PROTOCOL;
> +
> +/**
> +  Get the number of PIRQs this hardware supports.
> +
> +  @param  This                  The protocol instance pointer.
> +  @param  NumberPirsq           The number of PIRQs that are supported.
> +
> +  @retval EFI_SUCCESS           The number of PIRQs was returned
> successfully.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS)(
> +  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,
> +  OUT UINT8                                   *NumberPirqs
> +  );
> +
> +/**
> +  Gets the PCI location associated with this protocol.
> +
> +  @param  This                  The Protocol instance pointer.
> +  @param  Bus                   The PCI Bus.
> +  @param  Device                The PCI Device.
> +  @param  Function              The PCI Function.
> +
> +  @retval EFI_SUCCESS           The Bus, Device, and Function were returned
> successfully.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_INTERRUPT_GET_LOCATION)(
> +  IN EFI_LEGACY_INTERRUPT_PROTOCOL            *This,
> +  OUT UINT8                                   *Bus,
> +  OUT UINT8                                   *Device,
> +  OUT UINT8                                   *Function
> +  );
> +
> +/**
> +  Read the PIRQ register and return the data
> +
> +  @param  This                  The protocol instance pointer.
> +  @param  PirqNumber            The PIRQ register to read.
> +  @param  PirqData              The data read.
> +
> +  @retval EFI_SUCCESS           The data was read.
> +  @retval EFI_INVALID_PARAMETER Invalid PIRQ number.
> +  @retval EFI_DEVICE_ERROR      Operation was unsuccessful
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_INTERRUPT_READ_PIRQ)(
> +  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,
> +  IN  UINT8                                  PirqNumber,
> +  OUT UINT8                                  *PirqData
> +  );
> +
> +/**
> +  Write the specified PIRQ register with the given data.
> +
> +  @param  This                  The protocol instance pointer.
> +  @param  PirqNumber            A PIRQ register to read.
> +  @param  PirqData              The data to write.
> +
> +  @retval EFI_SUCCESS           The PIRQ was programmed.
> +  @retval EFI_INVALID_PARAMETER Invalid PIRQ number.
> +  @retval EFI_DEVICE_ERROR      Operation was unsuccessful
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_INTERRUPT_WRITE_PIRQ)(
> +  IN EFI_LEGACY_INTERRUPT_PROTOCOL           *This,
> +  IN  UINT8                                  PirqNumber,
> +  IN UINT8                                   PirqData
> +  );
> +
> +struct _EFI_LEGACY_INTERRUPT_PROTOCOL {
> +  ///
> +  ///   Gets the number of PIRQs supported.
> +  ///
> +  EFI_LEGACY_INTERRUPT_GET_NUMBER_PIRQS GetNumberPirqs;
> +
> +  ///
> +  /// Gets the PCI bus, device, and function that is associated with this
> protocol.
> +  ///
> +  EFI_LEGACY_INTERRUPT_GET_LOCATION     GetLocation;
> +
> +  ///
> +  /// Reads the indicated PIRQ register.
> +  ///
> +  EFI_LEGACY_INTERRUPT_READ_PIRQ        ReadPirq;
> +
> +  ///
> +  /// Writes to the indicated PIRQ register.
> +  ///
> +  EFI_LEGACY_INTERRUPT_WRITE_PIRQ       WritePirq;
> +};
> +
> +extern EFI_GUID gEfiLegacyInterruptProtocolGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/AcpiS3Context.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/AcpiS3Context.h
> new file mode 100644
> index 0000000000..c1d1fc89ec
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/AcpiS3Context.h
> @@ -0,0 +1,65 @@
> +/** @file
> +  Definitions for data structures used in S3 resume.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _ACPI_S3_DATA_H_
> +#define _ACPI_S3_DATA_H_
> +
> +#include <Library/BaseLib.h>
> +
> +#define SMM_S3_RESUME_SMM_32 SIGNATURE_64
> ('S','M','M','S','3','_','3','2')
> +#define SMM_S3_RESUME_SMM_64 SIGNATURE_64
> ('S','M','M','S','3','_','6','4')
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT64                Signature;
> +  EFI_PHYSICAL_ADDRESS  SmmS3ResumeEntryPoint;
> +  EFI_PHYSICAL_ADDRESS  SmmS3StackBase;
> +  UINT64                SmmS3StackSize;
> +  UINT64                SmmS3Cr0;
> +  UINT64                SmmS3Cr3;
> +  UINT64                SmmS3Cr4;
> +  UINT16                ReturnCs;
> +  EFI_PHYSICAL_ADDRESS  ReturnEntryPoint;
> +  EFI_PHYSICAL_ADDRESS  ReturnContext1;
> +  EFI_PHYSICAL_ADDRESS  ReturnContext2;
> +  EFI_PHYSICAL_ADDRESS  ReturnStackPointer;
> +  EFI_PHYSICAL_ADDRESS  Smst;
> +} SMM_S3_RESUME_STATE;
> +
> +
> +typedef struct {
> +  EFI_PHYSICAL_ADDRESS  AcpiFacsTable;
> +  EFI_PHYSICAL_ADDRESS  IdtrProfile;
> +  EFI_PHYSICAL_ADDRESS  S3NvsPageTableAddress;
> +  EFI_PHYSICAL_ADDRESS  BootScriptStackBase;
> +  UINT64                BootScriptStackSize;
> +  EFI_PHYSICAL_ADDRESS  S3DebugBufferAddress;
> +} ACPI_S3_CONTEXT;
> +
> +typedef struct {
> +  UINT16                ReturnCs;
> +  UINT64                ReturnStatus;
> +  EFI_PHYSICAL_ADDRESS  ReturnEntryPoint;
> +  EFI_PHYSICAL_ADDRESS  ReturnStackPointer;
> +  EFI_PHYSICAL_ADDRESS  AsmTransferControl;
> +  IA32_DESCRIPTOR       Idtr;
> +} PEI_S3_RESUME_STATE;
> +
> +#pragma pack()
> +
> +#define EFI_ACPI_S3_CONTEXT_GUID \
> +  { \
> +    0xef98d3a, 0x3e33, 0x497a, {0xa4, 0x1, 0x77, 0xbe, 0x3e, 0xb7, 0x4f, 0x38}
> \
> +  }
> +
> +extern EFI_GUID gEfiAcpiS3ContextGuid;
> +
> +extern EFI_GUID gEfiAcpiVariableGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/ConsoleOutDevice.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/ConsoleOutDevice.h
> new file mode 100644
> index 0000000000..c770101b38
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/ConsoleOutDevice.h
> @@ -0,0 +1,17 @@
> +/** @file
> +  This GUID can be installed to the device handle to specify that the device is
> the console-out device.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __CONSOLE_OUT_DEVICE_H__
> +#define __CONSOLE_OUT_DEVICE_H__
> +
> +#define EFI_CONSOLE_OUT_DEVICE_GUID    \
> +    { 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1,
> 0x4d } }
> +
> +extern EFI_GUID gEfiConsoleOutDeviceGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/MemoryTypeInformation.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/MemoryTypeInformation.h
> new file mode 100644
> index 0000000000..bf4b3cdeca
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/G
> uid/MemoryTypeInformation.h
> @@ -0,0 +1,30 @@
> +/** @file
> +  This file defines:
> +  * Memory Type Information GUID for HOB and Variable.
> +  * Memory Type Information Variable Name.
> +  * Memory Type Information GUID HOB data structure.
> +
> +  The memory type information HOB and variable can
> +  be used to store the information for each memory type in Variable or HOB.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __MEMORY_TYPE_INFORMATION_GUID_H__
> +#define __MEMORY_TYPE_INFORMATION_GUID_H__
> +
> +#define EFI_MEMORY_TYPE_INFORMATION_GUID \
> +  { 0x4c19049f,0x4137,0x4dd3, { 0x9c,0x10,0x8b,0x97,0xa8,0x3f,0xfd,0xfa } }
> +
> +#define EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME
> L"MemoryTypeInformation"
> +
> +extern EFI_GUID gEfiMemoryTypeInformationGuid;
> +
> +typedef struct {
> +  UINT32  Type;             ///< EFI memory type defined in UEFI specification.
> +  UINT32  NumberOfPages;    ///< The pages of this type memory.
> +} EFI_MEMORY_TYPE_INFORMATION;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Li
> brary/ResetSystemLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Li
> brary/ResetSystemLib.h
> new file mode 100644
> index 0000000000..754865943e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Li
> brary/ResetSystemLib.h
> @@ -0,0 +1,80 @@
> +/** @file
> +  System reset Library Services.  This library class defines a set of
> +  methods that reset the whole system.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> pi/SmmAccess.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> pi/SmmAccess.h
> new file mode 100644
> index 0000000000..565d35b654
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> pi/SmmAccess.h
> @@ -0,0 +1,137 @@
> +/** @file
> +  EFI SMM Access PPI definition.
> +
> +  This PPI is used to control the visibility of the SMRAM on the platform.
> +  It abstracts the location and characteristics of SMRAM.  The expectation is
> +  that the north bridge or memory controller would publish this PPI.
> +
> +  The principal functionality found in the memory controller includes the
> following:
> +  - Exposing the SMRAM to all non-SMM agents, or the "open" state
> +  - Shrouding the SMRAM to all but the SMM agents, or the "closed" state
> +  - Preserving the system integrity, or "locking" the SMRAM, such that the
> settings cannot be
> +    perturbed by either boot service or runtime agents
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMM_ACCESS_PPI_H_
> +#define _SMM_ACCESS_PPI_H_
> +
> +#define PEI_SMM_ACCESS_PPI_GUID \
> +  { 0x268f33a9, 0xcccd, 0x48be, { 0x88, 0x17, 0x86, 0x5, 0x3a, 0xc3, 0x2e,
> 0xd6 }}
> +
> +typedef struct _PEI_SMM_ACCESS_PPI  PEI_SMM_ACCESS_PPI;
> +
> +/**
> +  Opens the SMRAM area to be accessible by a PEIM driver.
> +
> +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> The function should
> +  return EFI_UNSUPPORTED if the hardware does not support hiding of
> SMRAM. The function
> +  should return EFI_DEVICE_ERROR if the SMRAM configuration is locked.
> +
> +  @param  PeiServices            General purpose services available to every
> PEIM.
> +  @param  This                   The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex        The region of SMRAM to Open.
> +
> +  @retval EFI_SUCCESS            The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR       The region could not be opened because
> locked by chipset.
> +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_OPEN)(
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  );
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function "closes" SMRAM so that it is not visible while outside of SMM.
> The function should
> +  return EFI_UNSUPPORTED if the hardware does not support hiding of
> SMRAM.
> +
> +  @param  PeiServices              General purpose services available to every
> PEIM.
> +  @param  This                     The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex          The region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS              The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR         The region could not be closed because
> locked by chipset.
> +  @retval EFI_INVALID_PARAMETER    The descriptor index was out of
> bounds.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_CLOSE)(
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  );
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function prohibits access to the SMRAM region.  This function is
> usually implemented such
> +  that it is a write-once operation.
> +
> +  @param  PeiServices              General purpose services available to every
> PEIM.
> +  @param  This                     The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex          The region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS            The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR       The region could not be locked because at
> least
> +                                 one range is still open.
> +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_LOCK)(
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  );
> +
> +/**
> +  Queries the memory controller for the possible regions that will support
> SMRAM.
> +
> +  @param  PeiServices           General purpose services available to every
> PEIM.
> +  @param This                   The pointer to the SmmAccessPpi Interface.
> +  @param SmramMapSize           The pointer to the variable containing size
> of the
> +                                buffer to contain the description information.
> +  @param SmramMap               The buffer containing the data describing
> the Smram
> +                                region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_CAPABILITIES)(
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  );
> +
> +///
> +///  EFI SMM Access PPI is used to control the visibility of the SMRAM on the
> platform.
> +///  It abstracts the location and characteristics of SMRAM.  The expectation
> is
> +///  that the north bridge or memory controller would publish this PPI.
> +///
> +struct _PEI_SMM_ACCESS_PPI {
> +  PEI_SMM_OPEN          Open;
> +  PEI_SMM_CLOSE         Close;
> +  PEI_SMM_LOCK          Lock;
> +  PEI_SMM_CAPABILITIES  GetCapabilities;
> +  BOOLEAN               LockState;
> +  BOOLEAN               OpenState;
> +};
> +
> +extern EFI_GUID gPeiSmmAccessPpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> pi/SmmControl.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> pi/SmmControl.h
> new file mode 100644
> index 0000000000..e982c00bf4
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> pi/SmmControl.h
> @@ -0,0 +1,87 @@
> +/** @file
> +  EFI SMM Control PPI definition.
> +
> +  This PPI is used to initiate SMI/PMI activations. This protocol could be
> published by either:
> +  - A processor driver to abstract the SMI/PMI IPI
> +  - The driver that abstracts the ASIC that is supporting the APM port, such as
> the ICH in an
> +  Intel chipset
> +  Because of the possibility of performing SMI or PMI IPI transactions, the
> ability to generate this
> +  event from a platform chipset agent is an optional capability for both IA-32
> and Itanium-based
> +  systems.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMM_CONTROL_PPI_H_
> +#define _SMM_CONTROL_PPI_H_
> +
> +#define PEI_SMM_CONTROL_PPI_GUID \
> +  { 0x61c68702, 0x4d7e, 0x4f43, 0x8d, 0xef, 0xa7, 0x43, 0x5, 0xce, 0x74, 0xc5 }
> +
> +typedef struct _PEI_SMM_CONTROL_PPI  PEI_SMM_CONTROL_PPI;
> +
> +/**
> +  Invokes SMI activation from either the preboot or runtime environment.
> +
> +  @param  PeiServices           General purpose services available to every
> PEIM.
> +  @param  This                  The PEI_SMM_CONTROL_PPI instance.
> +  @param  ArgumentBuffer        The optional sized data to pass into the
> protocol activation.
> +  @param  ArgumentBufferSize    The optional size of the data.
> +  @param  Periodic              An optional mechanism to periodically repeat
> activation.
> +  @param  ActivationInterval    An optional parameter to repeat at this
> period one
> +                                time or, if the Periodic Boolean is set, periodically.
> +
> +  @retval EFI_SUCCESS           The SMI/PMI has been engendered.
> +  @retval EFI_DEVICE_ERROR      The timing is unsupported.
> +  @retval EFI_INVALID_PARAMETER The activation period is unsupported.
> +  @retval EFI_NOT_STARTED       The SMM base service has not been
> initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_ACTIVATE) (
> +  IN EFI_PEI_SERVICES                                **PeiServices,
> +  IN PEI_SMM_CONTROL_PPI                             * This,
> +  IN OUT INT8                                        *ArgumentBuffer OPTIONAL,
> +  IN OUT UINTN                                       *ArgumentBufferSize OPTIONAL,
> +  IN BOOLEAN                                         Periodic OPTIONAL,
> +  IN UINTN                                           ActivationInterval OPTIONAL
> +  );
> +
> +/**
> +  Clears any system state that was created in response to the Active call.
> +
> +  @param  PeiServices           General purpose services available to every
> PEIM.
> +  @param  This                  The PEI_SMM_CONTROL_PPI instance.
> +  @param  Periodic              Optional parameter to repeat at this period
> one
> +                                time or, if the Periodic Boolean is set, periodically.
> +
> +  @retval EFI_SUCCESS           The SMI/PMI has been engendered.
> +  @retval EFI_DEVICE_ERROR      The source could not be cleared.
> +  @retval EFI_INVALID_PARAMETER The service did not support the Periodic
> input argument.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *PEI_SMM_DEACTIVATE) (
> +  IN EFI_PEI_SERVICES                      **PeiServices,
> +  IN PEI_SMM_CONTROL_PPI                   * This,
> +  IN BOOLEAN                               Periodic OPTIONAL
> +  );
> +
> +///
> +///  PEI SMM Control PPI is used to initiate SMI/PMI activations. This protocol
> could be published by either:
> +///  - A processor driver to abstract the SMI/PMI IPI
> +///  - The driver that abstracts the ASIC that is supporting the APM port, such
> as the ICH in an
> +///  Intel chipset
> +///
> +struct _PEI_SMM_CONTROL_PPI {
> +  PEI_SMM_ACTIVATE    Trigger;
> +  PEI_SMM_DEACTIVATE  Clear;
> +};
> +
> +extern EFI_GUID gPeiSmmControlPpiGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> rotocol/SmmVariable.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> rotocol/SmmVariable.h
> new file mode 100644
> index 0000000000..4aaa715d77
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/P
> rotocol/SmmVariable.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  EFI SMM Variable Protocol is related to EDK II-specific implementation of
> variables
> +  and intended for use as a means to store data in the EFI SMM environment.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SMM_VARIABLE_H__
> +#define __SMM_VARIABLE_H__
> +
> +#define EFI_SMM_VARIABLE_PROTOCOL_GUID \
> +  { \
> +    0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98,
> 0xa7 } \
> +  }
> +
> +typedef struct _EFI_SMM_VARIABLE_PROTOCOL
> EFI_SMM_VARIABLE_PROTOCOL;
> +
> +///
> +/// EFI SMM Variable Protocol is intended for use as a means
> +/// to store data in the EFI SMM environment.
> +///
> +struct _EFI_SMM_VARIABLE_PROTOCOL {
> +  EFI_GET_VARIABLE            SmmGetVariable;
> +  EFI_GET_NEXT_VARIABLE_NAME  SmmGetNextVariableName;
> +  EFI_SET_VARIABLE            SmmSetVariable;
> +  EFI_QUERY_VARIABLE_INFO     SmmQueryVariableInfo;
> +};
> +
> +extern EFI_GUID gEfiSmmVariableProtocolGuid;
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:12 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package
> common library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds package-level library class instances.
> 
> * BaseConfigBlockLib - Library functions for config block management.
> * BaseSiConfigBlockLib - Library functions for managing component
>   config blocks.
> * DxeAslUpdateLib - Services to update ACPI tables.
> * PeiDxeSmmMmPciLib - Services to manage PCI Express addresses.
> * PeiStallPpiLib - Installs an instance of EFI_PEI_STALL_PPI.
> * PeiSiPolicyLib - Installs an instance of the Silicon Policy PPI.
>   Prints the Silicon Policy PPI values when DEBUG prints are enabled.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlo
> ckLib.inf     |  29 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfig
> BlockLib.inf |  33 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib
> .inf           |  40 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdat
> eLibNull.inf   |  30 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmm
> MmPciLib.inf       |  35 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.
> inf      |  31 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
> |  51 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
> |  35 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlo
> ckLib.c       | 146 +++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfig
> BlockLib.c   |  87 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib
> .c             | 403 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdat
> eLibNull.c     | 126 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmm
> MmPciLib.c         |  32 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.
> c        |  78 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
> | 214 +++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMe
> m.c         | 122 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
> |  36 ++
>  17 files changed, 1528 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigB
> lockLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigB
> lockLib.inf
> new file mode 100644
> index 0000000000..a7def2481d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigB
> lockLib.inf
> @@ -0,0 +1,29 @@
> +## @file
> +# Component INF file for the BaseConfigBlock library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseConfigBlockLib
> +FILE_GUID = 1EC07EA8-7808-4e06-9D79-309AE331D2D5
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = ConfigBlockLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +BaseConfigBlockLib.c
> +
> +[LibraryClasses]
> +DebugLib
> +BaseMemoryLib
> +MemoryAllocationLib
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiCon
> figBlockLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiCon
> figBlockLib.inf
> new file mode 100644
> index 0000000000..b04dc3cfa4
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiCon
> figBlockLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +# Component description file for the BaseSiConfigBlockLib library.
> +#
> +# Copyright (c) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +BaseSiConfigBlockLib.c
> +
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> Lib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> Lib.inf
> new file mode 100644
> index 0000000000..658caccb43
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> Lib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Provides services to update ASL tables.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxeAslUpdateLib
> +FILE_GUID = 8621697D-4E3A-4bf2-ADB0-3E2FF06559CA
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = AslUpdateLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +PcdLib
> +BaseMemoryLib
> +UefiLib
> +MemoryAllocationLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +DxeAslUpdateLib.c
> +
> +
> +[Protocols]
> +gEfiAcpiTableProtocolGuid ## CONSUMES
> +gEfiAcpiSdtProtocolGuid ## CONSUMES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUp
> dateLibNull.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUp
> dateLibNull.inf
> new file mode 100644
> index 0000000000..ae78a8e8f9
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUp
> dateLibNull.inf
> @@ -0,0 +1,30 @@
> +## @file
> +# Provides services to update ASL tables.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxeAslUpdateLibNull
> +FILE_GUID = C7A3725F-6146-4FAB-B2EF-B4CED222DA52
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = AslUpdateLib
> +
> +
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +DxeAslUpdateLibNull.c
> +
> +
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSm
> mMmPciLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSm
> mMmPciLib.inf
> new file mode 100644
> index 0000000000..fdf376bc70
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSm
> mMmPciLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +# Component description file for the PeiDxeSmmMmPciLib
> +#
> +# Copyright (c) 2019 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
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Sources]
> +PeiDxeSmmMmPciLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLi
> b.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLi
> b.inf
> new file mode 100644
> index 0000000000..2e07a90406
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLi
> b.inf
> @@ -0,0 +1,31 @@
> +## @file
> +# Library description file for Stall Ppi installation
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiStallPpiLib
> +FILE_GUID = 73E3DD0E-B2C1-4429-B0B8-F8C2BD64F8CE
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = StallPpiLib
> +
> +[Sources]
> +PeiStallPpiLib.c
> +
> +[LibraryClasses]
> +BaseLib
> +DebugLib
> +TimerLib
> +PeiServicesLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +
> +[Ppis]
> +gEfiPeiStallPpiGuid ## PRODUCES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
> new file mode 100644
> index 0000000000..c5945c3129
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# Component description file for the PeiSiPolicyLib library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiSiPolicyLib
> +FILE_GUID = 97584FAE-9299-4202-9889-2D339E4BFA5B
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = SiPolicyLib
> +
> +
> +[LibraryClasses]
> +DebugLib
> +IoLib
> +PeiServicesLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +ConfigBlockLib
> +CpuPolicyLib
> +PchPolicyLib
> +PeiSaPolicyLib
> +PeiMePolicyLib
> +PcdLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PeiSiPolicyLib.c
> +PeiSiPolicyLibrary.h
> +SiPrintPolicy.c
> +PeiSiPolicyLibPreMem.c
> +
> +
> +[Guids]
> +gSiConfigGuid        ## CONSUMES
> +
> +
> +[Ppis]
> +gSiPolicyPpiGuid       ## PRODUCES
> +gSiPreMemPolicyPpiGuid ## PRODUCES
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.
> h
> new file mode 100644
> index 0000000000..cb6b14fdd1
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.
> h
> @@ -0,0 +1,35 @@
> +/** @file
> +  Header file for the PeiSiPolicyLib library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SI_POLICY_LIBRARY_H_
> +#define _PEI_SI_POLICY_LIBRARY_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/SiPolicyLib.h>
> +#include <Library/PchPolicyLib.h>
> +#include <Library/PeiMePolicyLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <PchAccess.h>
> +#include <Library/CpuPolicyLib.h>
> +
> +#define TEMP_MEM_BASE_ADDRESS 0xFE600000
> +#define TEMP_IO_BASE_ADDRESS  0xD000
> +
> +//
> +// IO/MMIO resource limits
> +//
> +#define TEMP_MEM_SIZE         V_PCH_XDCI_MEM_LENGTH
> +#define TEMP_IO_SIZE          0x10
> +
> +#endif // _PEI_SI_POLICY_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigB
> lockLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigB
> lockLib.c
> new file mode 100644
> index 0000000000..369dab97ee
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigB
> lockLib.c
> @@ -0,0 +1,146 @@
> +/** @file
> +  Library functions for Config Block management.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <ConfigBlock.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.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
> +  )
> +{
> +  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
> +  UINT32                    ConfigBlkTblHdrSize;
> +
> +  ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
> +
> +  if (TotalSize <= (ConfigBlkTblHdrSize + sizeof (CONFIG_BLOCK_HEADER))) {
> +    DEBUG ((DEBUG_ERROR, "Invalid Parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER *)AllocateZeroPool
> (TotalSize);
> +  if (ConfigBlkTblAddrPtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Could not allocate memory.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  ConfigBlkTblAddrPtr->NumberOfBlocks = 0;
> +  ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength = TotalSize;
> +  ConfigBlkTblAddrPtr->AvailableSize = TotalSize - ConfigBlkTblHdrSize;
> +
> +  *ConfigBlockTableAddress = (VOID *)ConfigBlkTblAddrPtr;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  CONFIG_BLOCK              *TempConfigBlk;
> +  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
> +  CONFIG_BLOCK              *ConfigBlkAddrPtr;
> +  UINT16                    ConfigBlkSize;
> +
> +  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER
> *)ConfigBlockTableAddress;
> +  ConfigBlkAddrPtr = (CONFIG_BLOCK *)(*ConfigBlockAddress);
> +  ConfigBlkSize = ConfigBlkAddrPtr->Header.GuidHob.Header.HobLength;
> +  DEBUG ((DEBUG_INFO, "Config Block GUID: %g / Config Block Size: 0x%x
> bytes\n", &(ConfigBlkAddrPtr->Header.GuidHob.Name), ConfigBlkSize));
> +  if ((ConfigBlkSize % 4) != 0) {
> +    DEBUG ((DEBUG_ERROR, "Config Block must be multiples of 4 bytes\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  if (ConfigBlkTblAddrPtr->AvailableSize < ConfigBlkSize) {
> +    DEBUG ((DEBUG_ERROR, "Config Block Table is full and cannot add new
> Config Block.\n"));
> +    DEBUG ((DEBUG_ERROR, "Available Config Block Size: 0x%x bytes /
> Requested Config Block Size: 0x%x bytes\n",
> ConfigBlkTblAddrPtr->AvailableSize, ConfigBlkSize));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr +
> (UINTN)(ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength -
> ConfigBlkTblAddrPtr->AvailableSize));
> +  CopyMem (&TempConfigBlk->Header, &ConfigBlkAddrPtr->Header,
> sizeof(CONFIG_BLOCK_HEADER));
> +
> +  ConfigBlkTblAddrPtr->NumberOfBlocks++;
> +  ConfigBlkTblAddrPtr->AvailableSize = ConfigBlkTblAddrPtr->AvailableSize -
> ConfigBlkSize;
> +
> +  *ConfigBlockAddress = (VOID *) TempConfigBlk;
> +  DEBUG ((DEBUG_INFO, "Config Block Address: 0x%x / Available Config Block
> Size: 0x%x bytes\n", (UINT32)(UINTN)*ConfigBlockAddress,
> ConfigBlkTblAddrPtr->AvailableSize));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINT16                    OffsetIndex;
> +  CONFIG_BLOCK              *TempConfigBlk;
> +  CONFIG_BLOCK_TABLE_HEADER *ConfigBlkTblAddrPtr;
> +  UINT32                    ConfigBlkTblHdrSize;
> +  UINT32                    ConfigBlkOffset;
> +  UINT16                    NumOfBlocks;
> +
> +  ConfigBlkTblHdrSize = (UINT32)(sizeof (CONFIG_BLOCK_TABLE_HEADER));
> +  ConfigBlkTblAddrPtr = (CONFIG_BLOCK_TABLE_HEADER
> *)ConfigBlockTableAddress;
> +  NumOfBlocks = ConfigBlkTblAddrPtr->NumberOfBlocks;
> +
> +  ConfigBlkOffset = 0;
> +  for (OffsetIndex = 0; OffsetIndex < NumOfBlocks; OffsetIndex++) {
> +    if ((ConfigBlkTblHdrSize + ConfigBlkOffset) >
> (ConfigBlkTblAddrPtr->Header.GuidHob.Header.HobLength)) {
> +      break;
> +    }
> +    TempConfigBlk = (CONFIG_BLOCK *)((UINTN)ConfigBlkTblAddrPtr +
> (UINTN)ConfigBlkTblHdrSize + (UINTN)ConfigBlkOffset);
> +    if (CompareGuid (&(TempConfigBlk->Header.GuidHob.Name),
> ConfigBlockGuid)) {
> +      *ConfigBlockAddress = (VOID *)TempConfigBlk;
> +      return EFI_SUCCESS;
> +    }
> +    ConfigBlkOffset = ConfigBlkOffset +
> TempConfigBlk->Header.GuidHob.Header.HobLength;
> +  }
> +  DEBUG ((DEBUG_ERROR, "Could not find the config block.\n"));
> +  return EFI_NOT_FOUND;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiCon
> figBlockLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiCon
> figBlockLib.c
> new file mode 100644
> index 0000000000..16a14b3245
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiCon
> figBlockLib.c
> @@ -0,0 +1,87 @@
> +/** @file
> +  This file is BaseSiConfigBlockLib library is used to add config blocks
> +  to config block header.
> +
> +  Copyright (c) 2019 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++) {
> +    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/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> Lib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> Lib.c
> new file mode 100644
> index 0000000000..04cf66fd2f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> Lib.c
> @@ -0,0 +1,403 @@
> +/** @file
> +  Boot service DXE ASL update library implementation.
> +
> +  These functions in this file can be called during DXE and cannot be called
> during runtime
> +  or in SMM which should use a RT or SMM library.
> +
> +  This library uses the ACPI Support protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +#include <Library/AslUpdateLib.h>
> +
> +//
> +// Function implemenations
> +//
> +static EFI_ACPI_SDT_PROTOCOL      *mAcpiSdt = NULL;
> +static EFI_ACPI_TABLE_PROTOCOL    *mAcpiTable = NULL;
> +
> +/**
> +  Initialize the ASL update library state.
> +  This must be called prior to invoking other library functions.
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +**/
> +EFI_STATUS
> +InitializeAslUpdateLib (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  ///
> +  /// Locate ACPI tables
> +  ///
> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)
> &mAcpiSdt);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &mAcpiTable);
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> +
> +/**
> +  This procedure will update immediate value assigned to a Name
> +
> +  @param[in] AslSignature      - The signature of Operation Region that we
> want to update.
> +  @param[in] Buffer            - source of data to be written over original aml
> +  @param[in] Length            - length of data to be overwritten
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
> +**/
> +EFI_STATUS
> +UpdateNameAslCode (
> +  IN     UINT32                        AslSignature,
> +  IN     VOID                          *Buffer,
> +  IN     UINTN                         Length
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_ACPI_DESCRIPTION_HEADER *Table;
> +  UINT8                       *CurrPtr;
> +  UINT32                      *Signature;
> +  UINT8                       *DsdtPointer;
> +  UINTN                       Handle;
> +  UINT8                       DataSize;
> +
> +  if (mAcpiTable == NULL) {
> +    InitializeAslUpdateLib ();
> +    if (mAcpiTable == NULL) {
> +      return EFI_NOT_READY;
> +    }
> +  }
> +
> +  ///
> +  /// Locate table with matching ID
> +  ///
> +  Handle = 0;
> +  Status = LocateAcpiTableBySignature (
> +
> EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> +             (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
> +             &Handle
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  ///
> +  /// Point to the beginning of the DSDT table
> +  ///
> +  CurrPtr = (UINT8 *) Table;
> +  if (CurrPtr == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ///
> +  /// Loop through the ASL looking for values that we must fix up.
> +  ///
> +  for (DsdtPointer = CurrPtr; DsdtPointer < (CurrPtr +
> ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
> +    ///
> +    /// Get a pointer to compare for signature
> +    ///
> +    Signature = (UINT32 *) DsdtPointer;
> +    ///
> +    /// Check if this is the Device Object signature we are looking for
> +    ///
> +    if ((*Signature) == AslSignature) {
> +      ///
> +      /// Look for Name Encoding
> +      ///
> +      if (*(DsdtPointer-1) == AML_NAME_OP) {
> +        ///
> +        /// Check if size of new and old data is the same
> +        ///
> +        DataSize = *(DsdtPointer+4);
> +        if ((Length == 1 && DataSize == 0xA) ||
> +            (Length == 2 && DataSize == 0xB) ||
> +            (Length == 4 && DataSize == 0xC)) {
> +          CopyMem (DsdtPointer+5, Buffer, Length);
> +        } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) ==
> 1) && (DataSize == 0 || DataSize == 1)) {
> +          CopyMem (DsdtPointer+4, Buffer, Length);
> +        } else {
> +          FreePool (Table);
> +          return EFI_BAD_BUFFER_SIZE;
> +        }
> +        Status = mAcpiTable->UninstallAcpiTable (
> +                               mAcpiTable,
> +                               Handle
> +                               );
> +        Handle = 0;
> +        Status = mAcpiTable->InstallAcpiTable (
> +                               mAcpiTable,
> +                               Table,
> +                               Table->Length,
> +                               &Handle
> +                               );
> +        FreePool (Table);
> +        return Status;
> +      }
> +    }
> +  }
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  This procedure will update the name of ASL Method
> +
> +  @param[in] AslSignature      - The signature of Operation Region that we
> want to update.
> +  @param[in] Buffer            - source of data to be written over original aml
> +  @param[in] Length            - length of data to be overwritten
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
> +**/
> +EFI_STATUS
> +UpdateMethodAslCode (
> +  IN     UINT32                        AslSignature,
> +  IN     VOID                          *Buffer,
> +  IN     UINTN                         Length
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_ACPI_DESCRIPTION_HEADER *Table;
> +  UINT8                       *CurrPtr;
> +  UINT32                      *Signature;
> +  UINT8                       *DsdtPointer;
> +  UINTN                       Handle;
> +
> +  if (mAcpiTable == NULL) {
> +    InitializeAslUpdateLib ();
> +    if (mAcpiTable == NULL) {
> +      return EFI_NOT_READY;
> +    }
> +  }
> +
> +  ///
> +  /// Locate table with matching ID
> +  ///
> +  Handle = 0;
> +  Status = LocateAcpiTableBySignature (
> +
> EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> +             (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
> +             &Handle
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  ///
> +  /// Point to the beginning of the DSDT table
> +  ///
> +  CurrPtr = (UINT8 *) Table;
> +  if (CurrPtr == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ///
> +  /// Loop through the ASL looking for values that we must fix up.
> +  ///
> +  for (DsdtPointer = CurrPtr; DsdtPointer < (CurrPtr +
> ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
> +    ///
> +    /// Get a pointer to compare for signature
> +    ///
> +    Signature = (UINT32 *) DsdtPointer;
> +    ///
> +    /// Check if this is the Device Object signature we are looking for
> +    ///
> +    if ((*Signature) == AslSignature) {
> +      ///
> +      /// Look for Name Encoding
> +      ///
> +      if ((*(DsdtPointer-3) == AML_METHOD_OP)
> +         || (*(DsdtPointer-2) == AML_METHOD_OP)
> +         )
> +      {
> +        CopyMem (DsdtPointer, Buffer, Length);
> +        Status = mAcpiTable->UninstallAcpiTable (
> +                               mAcpiTable,
> +                               Handle
> +                               );
> +        Handle = 0;
> +        Status = mAcpiTable->InstallAcpiTable (
> +                               mAcpiTable,
> +                               Table,
> +                               Table->Length,
> +                               &Handle
> +                               );
> +        FreePool (Table);
> +        return Status;
> +      }
> +    }
> +  }
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  This function uses the ACPI SDT protocol to locate an ACPI table.
> +  It is really only useful for finding tables that only have a single instance,
> +  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
> +
> +  @param[in] Signature           - Pointer to an ASCII string containing the
> OEM Table ID from the ACPI table header
> +  @param[in, out] Table          - Updated with a pointer to the table
> +  @param[in, out] Handle         - AcpiSupport protocol table handle for the
> table found
> +  @param[in, out] Version        - The version of the table desired
> +
> +  @retval EFI_SUCCESS            - The function completed successfully.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  INTN                        Index;
> +  EFI_ACPI_TABLE_VERSION      Version;
> +  EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
> +
> +  if (mAcpiSdt == NULL) {
> +    InitializeAslUpdateLib ();
> +    if (mAcpiSdt == NULL) {
> +      return EFI_NOT_READY;
> +    }
> +  }
> +
> +  ///
> +  /// Locate table with matching ID
> +  ///
> +  Version = 0;
> +  Index = 0;
> +  do {
> +    Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER
> **)&OrgTable, &Version, Handle);
> +    if (Status == EFI_NOT_FOUND) {
> +      break;
> +    }
> +    ASSERT_EFI_ERROR (Status);
> +    Index++;
> +  } while (OrgTable->Signature != Signature);
> +
> +  if (Status != EFI_NOT_FOUND) {
> +    *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
> +    ASSERT (*Table);
> +  }
> +
> +  ///
> +  /// If we found the table, there will be no error.
> +  ///
> +  return Status;
> +}
> +
> +/**
> +  This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
> +
> +  @param[in] TableId           - Pointer to an ASCII string containing the OEM
> Table ID from the ACPI table header
> +  @param[in] TableIdSize       - Length of the TableId to match.  Table ID are
> 8 bytes long, this function
> +                                 will consider it a match if the first TableIdSize bytes
> match
> +  @param[in, out] Table        - Updated with a pointer to the table
> +  @param[in, out] Handle       - AcpiSupport protocol table handle for the
> table found
> +  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable
> function for use
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +**/
> +EFI_STATUS
> +LocateAcpiTableByOemTableId (
> +  IN      UINT8                         *TableId,
> +  IN      UINT8                         TableIdSize,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  INTN                        Index;
> +  EFI_ACPI_TABLE_VERSION      Version;
> +  EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
> +
> +  if (mAcpiSdt == NULL) {
> +    InitializeAslUpdateLib ();
> +    if (mAcpiSdt == NULL) {
> +      return EFI_NOT_READY;
> +    }
> +  }
> +  ///
> +  /// Locate table with matching ID
> +  ///
> +  Version = 0;
> +  Index = 0;
> +  do {
> +    Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER
> **)&OrgTable, &Version, Handle);
> +    if (Status == EFI_NOT_FOUND) {
> +      break;
> +    }
> +    ASSERT_EFI_ERROR (Status);
> +    Index++;
> +  } while (CompareMem (&(OrgTable->OemTableId), TableId, TableIdSize));
> +
> +  if (Status != EFI_NOT_FOUND) {
> +    *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
> +    ASSERT (*Table);
> +  }
> +
> +  ///
> +  /// If we found the table, there will be no error.
> +  ///
> +  return Status;
> +}
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer          Pointer to buffer to checksum
> +  @param[in] Size            Number of bytes to checksum
> +  @param[in] ChecksumOffset  Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  )
> +{
> +  UINT8 Sum;
> +  UINT8 *Ptr;
> +
> +  Sum = 0;
> +  ///
> +  /// Initialize pointer
> +  ///
> +  Ptr = Buffer;
> +
> +  ///
> +  /// set checksum to 0 first
> +  ///
> +  Ptr[ChecksumOffset] = 0;
> +
> +  ///
> +  /// add all content of buffer
> +  ///
> +  while (Size--) {
> +    Sum = (UINT8) (Sum + (*Ptr++));
> +  }
> +  ///
> +  /// set checksum
> +  ///
> +  Ptr                 = Buffer;
> +  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUp
> dateLibNull.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUp
> dateLibNull.c
> new file mode 100644
> index 0000000000..a7ce92b7c3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUp
> dateLibNull.c
> @@ -0,0 +1,126 @@
> +/** @file
> +  Boot service DXE ASL update library implementation.
> +
> +  These functions in this file can be called during DXE and cannot be called
> during runtime
> +  or in SMM which should use a RT or SMM library.
> +
> +  This library uses the ACPI Support protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +#include <Library/AslUpdateLib.h>
> +
> +//
> +// Function implemenations
> +//
> +
> +/**
> +  Initialize the ASL update library state.
> +  This must be called prior to invoking other library functions.
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +**/
> +EFI_STATUS
> +InitializeAslUpdateLib (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This procedure will update immediate value assigned to a Name
> +
> +  @param[in] AslSignature      - The signature of Operation Region that we
> want to update.
> +  @param[in] Buffer            - source of data to be written over original aml
> +  @param[in] Length            - length of data to be overwritten
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +**/
> +EFI_STATUS
> +UpdateNameAslCode (
> +  IN     UINT32                        AslSignature,
> +  IN     VOID                          *Buffer,
> +  IN     UINTN                         Length
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function uses the ACPI SDT protocol to locate an ACPI table.
> +  It is really only useful for finding tables that only have a single instance,
> +  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
> +
> +  @param[in] Signature           - Pointer to an ASCII string containing the
> OEM Table ID from the ACPI table header
> +  @param[in, out] Table          - Updated with a pointer to the table
> +  @param[in, out] Handle         - AcpiSupport protocol table handle for the
> table found
> +  @param[in, out] Version        - The version of the table desired
> +
> +  @retval EFI_SUCCESS            - The function completed successfully.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
> +
> +  @param[in] TableId           - Pointer to an ASCII string containing the OEM
> Table ID from the ACPI table header
> +  @param[in] TableIdSize       - Length of the TableId to match.  Table ID are
> 8 bytes long, this function
> +                                 will consider it a match if the first TableIdSize bytes
> match
> +  @param[in, out] Table        - Updated with a pointer to the table
> +  @param[in, out] Handle       - AcpiSupport protocol table handle for the
> table found
> +  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable
> function for use
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +**/
> +EFI_STATUS
> +LocateAcpiTableByOemTableId (
> +  IN      UINT8                         *TableId,
> +  IN      UINT8                         TableIdSize,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer          Pointer to buffer to checksum
> +  @param[in] Size            Number of bytes to checksum
> +  @param[in] ChecksumOffset  Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSm
> mMmPciLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSm
> mMmPciLib.c
> new file mode 100644
> index 0000000000..5085f29d6d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSm
> mMmPciLib.c
> @@ -0,0 +1,32 @@
> +/** @file
> +  This file contains routines that get PCI Express Address
> +
> +  Copyright (c) 2019 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
> +MmPciBase (
> +  IN UINT32                       Bus,
> +  IN UINT32                       Device,
> +  IN UINT32                       Function
> +  )
> +{
> +  ASSERT ((Bus <= 0xFF) && (Device <= 0x1F) && (Function <= 0x7));
> +
> +  return ((UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (UINTN) (Bus << 20)
> + (UINTN) (Device << 15) + (UINTN) (Function << 12));
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLi
> b.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLi
> b.c
> new file mode 100644
> index 0000000000..d462aef407
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLi
> b.c
> @@ -0,0 +1,78 @@
> +/** @file
> +  Library to install StallPpi.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Ppi/Stall.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/PeiServicesLib.h>
> +
> +#define PEI_STALL_RESOLUTION   1
> +
> +/**
> +  This function provides a blocking stall for reset at least the given number of
> microseconds
> +  stipulated in the final argument.
> +
> +  @param  PeiServices General purpose services available to every PEIM.
> +  @param  this Pointer to the local data for the interface.
> +  @param  Microseconds number of microseconds for which to stall.
> +
> +  @retval  EFI_SUCCESS the function provided at least the required stall.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI  *This,
> +  IN UINTN                    Microseconds
> +  );
> +
> +
> +EFI_PEI_STALL_PPI   mStallPpi = {
> +  PEI_STALL_RESOLUTION,
> +  Stall
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR    mPeiInstallStallPpi = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiStallPpiGuid,
> +  &mStallPpi
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +Stall (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN CONST EFI_PEI_STALL_PPI  *This,
> +  IN UINTN                    Microseconds
> +  )
> +{
> +  MicroSecondDelay (Microseconds);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function will install the StallPpi.
> +
> +  @retval EFI_SUCCESS if StallPpi is installed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallStallPpi (
> +  VOID
> +  )
> +{
> +  EFI_STATUS   Status;
> +
> +  DEBUG((DEBUG_INFO, "Installing StallPpi \n"));
> +
> +  Status = PeiServicesInstallPpi (&mPeiInstallStallPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
> new file mode 100644
> index 0000000000..de8d9745d3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
> @@ -0,0 +1,214 @@
> +/** @file
> +  This file is PeiSiPolicyLib library creates default settings of RC
> +  Policy and installs RC Policy PPI.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSiPolicyLibrary.h"
> +#include <Library/PcdLib.h>
> +
> +/**
> +  Get Si config block table total size.
> +
> +  @retval                               Size of PCH config block table
> +**/
> +UINT16
> +EFIAPI
> +SiGetConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return (UINT16) sizeof (SI_CONFIG);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LoadSiConfigBlockDefault (
> +  IN VOID *ConfigBlockPointer
> +  )
> +{
> +  SI_CONFIG                         *SiConfig;
> +
> +  SiConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Name = %g\n",
> &SiConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", SiConfig->Header.GuidHob.Header.HobLength));
> +
> +  SiConfig->Header.Revision = SI_CONFIG_REVISION;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SiAddConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  )
> +{
> +  VOID                 *ConfigBlockPointer;
> +  EFI_STATUS           Status;
> +  CONFIG_BLOCK_HEADER  SiBlock;
> +
> +  //
> +  // Initalize SiBlock
> +  //
> +  CopyMem (&(SiBlock.GuidHob.Name), &gSiConfigGuid, sizeof (EFI_GUID));
> +  SiBlock.GuidHob.Header.HobLength = sizeof (SI_CONFIG);
> +  SiBlock.Revision                 = SI_CONFIG_REVISION;
> +  //
> +  // Initialize ConfigBlockPointer
> +  //
> +  ConfigBlockPointer = (VOID *)&SiBlock;
> +  //
> +  // Add config block fro SiBlock
> +  //
> +  DEBUG ((DEBUG_INFO, "gSiConfigGuid = %g\n", &gSiConfigGuid));
> +  DEBUG ((DEBUG_INFO, "SiConfig->Header.GuidHob.Name = %g\n",
> &(SiBlock.GuidHob.Name)));
> +  Status = AddConfigBlock (ConfigBlockTableAddress, (VOID *)
> &ConfigBlockPointer);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  LoadSiConfigBlockDefault ((VOID *) ConfigBlockPointer);
> +
> +  return Status;
> +}
> +
> +/**
> +  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
> +  It allocates and zero out buffer, and fills in the Intel default settings.
> +
> +  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiCreateConfigBlocks (
> +  OUT  SI_POLICY_PPI **SiPolicyPpi
> +  )
> +{
> +  UINT16        TotalBlockSize;
> +  EFI_STATUS    Status;
> +  SI_POLICY_PPI *SiPolicy;
> +  UINT16        RequiredSize;
> +
> +  SiPolicy = NULL;
> +  //
> +  // TotalBlockSize = Si, Pch, ME, SA and CPU config block size.
> +  //
> +  TotalBlockSize = SiGetConfigBlockTotalSize () +
> +                   PchGetConfigBlockTotalSize () +
> +                   MeGetConfigBlockTotalSize () +
> +                   SaGetConfigBlockTotalSize () +
> +                   CpuGetConfigBlockTotalSize ();
> +  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
> +
> +  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
> +
> +  Status = CreateConfigBlockTable (RequiredSize, (VOID *) &SiPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // General initialization
> +  //
> +  SiPolicy->TableHeader.Header.Revision = SI_POLICY_REVISION;
> +  //
> +  // Add config blocks.
> +  //
> +  Status = SiAddConfigBlocks ((VOID *) SiPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = PchAddConfigBlocks ((VOID *) SiPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = MeAddConfigBlocks ((VOID *) SiPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = SaAddConfigBlocks ((VOID *) SiPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = CpuAddConfigBlocks ((VOID *) SiPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Assignment for returning SaInitPolicy config block base address
> +  //
> +  *SiPolicyPpi = SiPolicy;
> +  return Status;
> +}
> +
> +/**
> +  Print out all silicon policy information.
> +
> +  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
> +
> +  @retval none
> +**/
> +VOID
> +DumpSiPolicy (
> +  IN  SI_POLICY_PPI *SiPolicyPpi
> +  )
> +{
> +  //
> +  // Print SI config blocks and serial out.
> +  //
> +  SiPrintPolicyPpi (SiPolicyPpi);
> +  //
> +  // Print PCH config blocks and serial out.
> +  //
> +  PchPrintPolicyPpi (SiPolicyPpi);
> +  //
> +  // Print ME config blocks and serial out.
> +  //
> +  MePrintPolicyPpi (SiPolicyPpi);
> +  //
> +  // Print SA config blocks and serial out.
> +  //
> +  SaPrintPolicyPpi (SiPolicyPpi);
> +  //
> +  // Print CPU config block and serial out.
> +  //
> +  CpuPrintPolicy (SiPolicyPpi);
> +}
> +
> +/**
> +  SiInstallPolicyPpi installs SiPolicyPpi.
> +  While installed, RC assumes the Policy is ready and finalized. So please
> update and override
> +  any setting before calling this function.
> +
> +  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS            The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiInstallPolicyPpi (
> +  IN  SI_POLICY_PPI *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS             Status;
> +  EFI_PEI_PPI_DESCRIPTOR *SiPolicyPpiDesc;
> +  SI_CONFIG              *SiConfig;
> +
> +  SiPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof
> (EFI_PEI_PPI_DESCRIPTOR));
> +  if (SiPolicyPpiDesc == NULL) {
> +    ASSERT (FALSE);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SiPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  SiPolicyPpiDesc->Guid  = &gSiPolicyPpiGuid;
> +  SiPolicyPpiDesc->Ppi   = SiPolicyPpi;
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSiConfigGuid, (VOID *)
> &SiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "Dump Silicon Policy update by Platform...\n"));
> +  DumpSiPolicy (SiPolicyPpi);
> +
> +  //
> +  // Install Silicon Policy PPI
> +  //
> +  Status = PeiServicesInstallPpi (SiPolicyPpiDesc);
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPre
> Mem.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPre
> Mem.c
> new file mode 100644
> index 0000000000..499f895e8e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPre
> Mem.c
> @@ -0,0 +1,122 @@
> +/** @file
> +  This file is PeiSiPolicyLib library creates default settings of RC
> +  Policy and installs RC Policy PPI.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSiPolicyLibrary.h"
> +#include <Base.h>
> +
> +/**
> +  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon PREMEM
> Policy.
> +  It allocates and zero out buffer, and fills in the Intel default settings.
> +
> +  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon Policy PPI
> instance
> +
> +  @retval EFI_SUCCESS             The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiCreatePreMemConfigBlocks (
> +  OUT  SI_PREMEM_POLICY_PPI **SiPreMemPolicyPpi
> +  )
> +{
> +  UINT16               TotalBlockSize;
> +  EFI_STATUS           Status;
> +  SI_PREMEM_POLICY_PPI *SiPreMemPolicy;
> +  UINT16               RequiredSize;
> +
> +  SiPreMemPolicy = NULL;
> +  //
> +  // TotalBlockSize = Pch , SA, ME and CPU config block size.
> +  //
> +  TotalBlockSize = PchGetPreMemConfigBlockTotalSize () +
> +                   MeGetConfigBlockTotalSizePreMem () +
> +                   SaGetConfigBlockTotalSizePreMem () +
> +                   CpuGetPreMemConfigBlockTotalSize ();
> +  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
> +
> +  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
> +
> +  Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SiPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // General initialization
> +  //
> +  SiPreMemPolicy->TableHeader.Header.Revision =
> SI_PREMEM_POLICY_REVISION;
> +  //
> +  // Add config blocks.
> +  //
> +  Status = PchAddPreMemConfigBlocks ((VOID *) SiPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = MeAddConfigBlocksPreMem ((VOID *) SiPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = SaAddConfigBlocksPreMem ((VOID *) SiPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = CpuAddPreMemConfigBlocks ((VOID *) SiPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Assignment for returning SaInitPolicy config block base address
> +  //
> +  *SiPreMemPolicyPpi = SiPreMemPolicy;
> +  return Status;
> +}
> +
> +/**
> +  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
> +  While installed, RC assumes the Policy is ready and finalized. So please
> update and override
> +  any setting before calling this function.
> +
> +  @param[in] SiPreMemPolicyPpi   The pointer to Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS            The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiPreMemInstallPolicyPpi (
> +  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
> +  )
> +{
> +  EFI_STATUS             Status;
> +  EFI_PEI_PPI_DESCRIPTOR *SiPolicyPreMemPpiDesc;
> +
> +  SiPolicyPreMemPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool
> (sizeof (EFI_PEI_PPI_DESCRIPTOR));
> +  if (SiPolicyPreMemPpiDesc == NULL) {
> +    ASSERT (FALSE);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SiPolicyPreMemPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  SiPolicyPreMemPpiDesc->Guid  = &gSiPreMemPolicyPpiGuid;
> +  SiPolicyPreMemPpiDesc->Ppi   = SiPolicyPreMemPpi;
> +
> +  //
> +  // Print whole PCH_POLICY_PPI and serial out.
> +  //
> +  PchPreMemPrintPolicyPpi (SiPolicyPreMemPpi);
> +  //
> +  // Print ME config blocks and serial out.
> +  //
> +  MePrintPolicyPpiPreMem (SiPolicyPreMemPpi);
> +  //
> +  // Print whole SI_POLICY_PPI and serial out.
> +  //
> +  SaPrintPolicyPpiPreMem (SiPolicyPreMemPpi);
> +  //
> +  // Print whole CPU of SI_PREMEM_POLICY_PPI and serial out.
> +  //
> +  CpuPreMemPrintPolicy (SiPolicyPreMemPpi);
> +  //
> +  // Install Silicon Policy PPI
> +  //
> +  Status = PeiServicesInstallPpi (SiPolicyPreMemPpiDesc);
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
> new file mode 100644
> index 0000000000..cf7e1b2308
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file is PeiSiPolicyLib library for printing Policy settings.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSiPolicyLibrary.h"
> +
> +/**
> +  Print whole SI_POLICY_PPI and serial out.
> +
> +  @param[in] SiPolicyPpi The RC Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +SiPrintPolicyPpi (
> +  IN  SI_POLICY_PPI          *SiPolicyPpi
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  SI_CONFIG     *SiConfig;
> +  EFI_STATUS    Status;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSiConfigGuid, (VOID *)
> &SiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ Silicon Print Policy Start
> ------------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CsmFlag= %x\n", SiConfig->CsmFlag));
> +  DEBUG ((DEBUG_INFO, " TraceHubMemBase = 0x%08x\n",
> SiConfig->TraceHubMemBase));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ Silicon Print Policy End
> --------------------------\n"));
> +  DEBUG_CODE_END ();
> +}
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:12 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent:
> Add Include headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds header files common to System Agent (SA) modules.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaCo
> nfig.h                |  33 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Graphic
> sDxeConfig.h        |  53 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Graphic
> sPeiConfig.h        |  96 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Graphic
> sPeiPreMemConfig.h  |  70 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPre
> MemConfig.h          |  46 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Memor
> yConfig.h             | 534 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Memor
> yDxeConfig.h          |  61 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDx
> eConfig.h            |  33 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverCl
> ockingConfig.h       |  51 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxe
> Config.h            | 135 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePei
> Config.h            |  60 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePei
> PreMemConfig.h      | 354 +++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMisc
> PeiConfig.h          |  61 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMisc
> PeiPreMemConfig.h    | 103 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Switcha
> bleGraphicsConfig.h |  63 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosD
> xeConfig.h           |  39 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdCon
> fig.h                |  42 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTabl
> e.h                    |  77 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyL
> ib.h               |  60 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLi
> b.h               |  87 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLi
> b.h                |  88 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
> | 259 ++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Gra
> phicsInitLib.h      |  15 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Lega
> cyRegion.h         |  33 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiC
> puTraceHubLib.h    |  23 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPc
> ieLib.h            |  70 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaI
> otrapSmi.h         |  36 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/Sa
> NvsArea.h           |  31 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHo
> b.h                  |  89 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaD
> ef.h                 | 151 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComp
> onentName2.h           |  63 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.
> h                   |  73 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegi
> on.h                 |  24 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
> | 132 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
> |  66 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna
> .h                   |  32 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHos
> tBridge.h            | 214 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.
> h                   |  50 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.
> h                   |  37 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.
> h                   |  64 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
> | 106 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitio
> ns.h                  |  23 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
> |  25 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
> |  51 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
> |  32 ++
>  45 files changed, 3845 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaC
> onfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaC
> onfig.h
> new file mode 100644
> index 0000000000..020a4aeab5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaC
> onfig.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  Policy definition for GNA Config Block
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsDxeConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsDxeConfig.h
> new file mode 100644
> index 0000000000..cc337a83f3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsDxeConfig.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  Graphics DXE Policy definitions
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_DXE_CONFIG_H_
> +#define _GRAPHICS_DXE_CONFIG_H_
> +
> +#pragma pack(push, 1)
> +
> +#define GRAPHICS_DXE_CONFIG_REVISION 2
> +
> +#define MAX_BCLM_ENTRIES    20
> +
> +/**
> +  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.
> +  <b>Revision 2</b>:
> +  - Adding BCLM[MAX_BCLM_ENTRIES]
> +**/
> +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_DXE_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsPeiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsPeiConfig.h
> new file mode 100644
> index 0000000000..276289ae81
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsPeiConfig.h
> @@ -0,0 +1,96 @@
> +/** @file
> +  Policy definition for Internal Graphics Config Block (PostMem)
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_PEI_CONFIG_H_
> +#define _GRAPHICS_PEI_CONFIG_H_
> +#pragma pack(push, 1)
> +
> +#define GRAPHICS_PEI_CONFIG_REVISION 4
> +#define DDI_DEVICE_NUMBER 4
> +
> +//
> +// DDI defines
> +//
> +typedef enum {
> +  DdiDisable       = 0x00,
> +  DdiDdcEnable     = 0x01,
> +  DdiTbtLsxEnable  = 0x02,
> +} DDI_DDC_TBT_VAL;
> +
> +typedef enum {
> +  DdiHpdDisable  = 0x00,
> +  DdiHpdEnable   = 0x01,
> +} DDI_HPD_VAL;
> +
> +typedef enum {
> +  DdiPortADisabled = 0x00,
> +  DdiPortAEdp      = 0x01,
> +  DdiPortAMipiDsi  = 0x02,
> +} DDI_PORTA_SETTINGS;
> +/**
> +  This structure configures the Native GPIOs for DDI port per VBT settings.
> +**/
> +typedef struct {
> +  UINT8 DdiPortEdp;    /// The setting of eDP port, this settings must match
> VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortBHpd;   /// The HPD setting of DDI Port B, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortCHpd;   /// The HPD setting of DDI Port C, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortDHpd;   /// The HPD setting of DDI Port D, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortFHpd;   /// The HPD setting of DDI Port F, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortBDdc;   /// The DDC setting of DDI Port B, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortCDdc;   /// The DDC setting of DDI Port C, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortDDdc;   /// The DDC setting of DDI Port D, this settings must
> match VBT's settings. 0- Disable, <b>1- Enable</b>
> +  UINT8 DdiPortFDdc;   /// The DDC setting of DDI Port F, this settings must
> match VBT's settings. <b>0- Disable</b>, 1- Enable
> +  UINT8 Rsvd[3];       ///< Reserved for 4 bytes alignment
> +} DDI_CONFIGURATION;
> +
> +/**
> +  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>:
> +  - Added SkipS3CdClockInit.
> +  <b>Revision 3</b>:
> +  - Added DeltaT12PowerCycleDelay, BltBufferAddress, BltBufferSize.
> +  <b>Revision 4</b>:
> +  - Deprecated DeltaT12PowerCycleDelay.
> +
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config
> Block Header
> +  UINT32                RenderStandby     : 1;    ///< Offset 28:0 :<b>(Test)</b>
> This field is used to enable or disable RC6 (Render Standby): 0=FALSE,
> <b>1=TRUE</b>
> +  UINT32                PmSupport         : 1;    ///< Offset 28:1 :<b>(Test)</b>
> IGD PM Support TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
> +  UINT32                PavpEnable        : 1;    ///< Offset 28:2 :IGD PAVP
> TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
> +  /**
> +    Offset 28:3
> +    CdClock Frequency select\n
> +    CFL\n
> +    0   = 337.5 Mhz, 1 = 450 Mhz,\n
> +    2   = 540 Mhz,<b> 3 = 675 Mhz</b>,\n
> +
> +  **/
> +  UINT32                CdClock            : 3;
> +  UINT32                PeiGraphicsPeimInit: 1;   ///< Offset 28:6 : This policy is
> used to enable/disable Intel Gfx PEIM.<b>0- Disable</b>, 1- Enable
> +  UINT32                CdynmaxClampEnable : 1;   ///< Offset 28:7 : This policy
> is used to enable/disable CDynmax Clamping Feature (CCF) <b>1- Enable</b>,
> 0- Disable
> +  UINT32                GtFreqMax          : 8;   ///< Offset 28:8 : <b>(Test)</b>
> Max GT frequency limited by user in multiples of 50MHz: Default value which
> indicates normal frequency is <b>0xFF</b>
> +  UINT32                DisableTurboGt     : 1;   ///< Offset 28:9 : This policy is
> used to enable/disable DisableTurboGt <b>0- Disable</b>, 1- Enable
> +  UINT32                RsvdBits0          : 15;  ///< Offser 28:15 :Reserved for
> future use
> +  VOID*                 LogoPtr;                  ///< Offset 32 Address of Intel Gfx
> PEIM Logo to be displayed
> +  UINT32                LogoSize;                 ///< Offset 36 Intel Gfx PEIM Logo
> Size
> +  VOID*                 GraphicsConfigPtr;        ///< Offset 40 Address of the
> Graphics Configuration Table
> +  DDI_CONFIGURATION     DdiConfiguration;         ///< Offset 44 DDI
> configuration, need to match with VBT settings.
> +  UINT32                SkipS3CdClockInit  : 1;   ///< Offset 56 SKip full CD clock
> initialization being done during S3 resume.<b>0- Disable<\b>, 1- Enable
> +  UINT32                ReservedBits       : 31;  ///< Offset 56: 1 : Reserved for
> future use.
> +  UINT16                DeltaT12PowerCycleDelay;  ///< Offset 60 @deprecated
> Power Cycle Delay required for eDP as per VESA standard.<b>0 - 0 ms<\b>,
> 0xFFFF - Auto calculate to max 500 ms
> +  UINT8                 Reserved[2];              ///< Offset 62 Reserved for future
> use.
> +  VOID*                 BltBufferAddress;         ///< Offset 64 Address of Blt
> buffer for PEIM Logo use
> +  UINT32                BltBufferSize;            ///< Offset 68 The size for Blt
> Buffer, calculating by PixelWidth * PixelHeight * 4 bytes (the size of
> EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
> +} GRAPHICS_PEI_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _GRAPHICS_PEI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsPeiPreMemConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsPeiPreMemConfig.h
> new file mode 100644
> index 0000000000..4986fdab60
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Grap
> hicsPeiPreMemConfig.h
> @@ -0,0 +1,70 @@
> +/** @file
> +  Policy definition for Internal Graphics Config Block (PreMem)
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_PEI_PREMEM_CONFIG_H_
> +#define _GRAPHICS_PEI_PREMEM_CONFIG_H_
> +#pragma pack(push, 1)
> +
> +#define GRAPHICS_PEI_PREMEM_CONFIG_REVISION 2
> +
> +
> +/**
> +  This Configuration block is to configure GT related PreMem
> data/variables.\n
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Added DeltaT12PowerCycleDelayPreMem.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config
> Block Header
> +  /**
> +    Offset 28:0
> +    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
> +  **/
> +  UINT32                PrimaryDisplay    : 3;
> +  /**
> +    Offset 28:3
> +    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.
> +  **/
> +  UINT32                InternalGraphics  : 2;
> +  /**
> +    Offset 28:5
> +    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>
> +  **/
> +  UINT32                IgdDvmt50PreAlloc : 8;
> +  UINT32                PanelPowerEnable  : 1;          ///< Offset
> 28:13 :<b>(Test)</b> Control for enabling/disabling VDD force bit (Required
> only for early enabling of eDP panel): 0=FALSE, <b>1=TRUE</b>
> +  UINT32                ApertureSize      : 7;          ///< Offser 28:14 :Graphics
> aperture size (256MB is the recommended size as per BWG) : 0=128MB,
> <b>1=256MB</b>, 3=512MB, 7=1024MB, 15=2048MB.
> +  UINT32                GtPsmiSupport     : 1;          ///< Offser 28:21 :PSMI
> support On/Off: <b>0=FALSE</b>, 1=TRUE
> +  UINT32                PsmiRegionSize    : 3;          ///< Offser 28:22 :Psmi
> region size: <b>0=32MB</b>, 1=288MB, 2=544MB, 3=800MB, 4=1056MB
> +  UINT32                RsvdBits0         : 7;          ///< Offser 28:25 :Reserved
> for future use
> +  UINT32                GttMmAdr;                       ///< Offset 32 Temp Address
> of System Agent GTTMMADR : Default is <b>0xCF000000< / b>
> +  UINT16                GttSize;                        ///< Offset 36 Selection of iGFX
> GTT Memory size: 1=2MB, 2=4MB, <b>3=8MB</b>
> +  UINT8                 Rsvd1[2];                       ///< Offset 38 Reserved for
> DWORD alignment
> +  UINT32                GmAdr;                          ///< Offset 40 Temp Address
> of System Agent GMADR : Default is <b>0xD0000000< / b>
> +  UINT16                DeltaT12PowerCycleDelayPreMem;  ///< Offset 44
> Power Cycle Delay required for eDP as per VESA standard.<b>0 - 0 ms<\b>,
> 0xFFFF - Auto calculate to max 500 ms
> +  UINT8                 Reserved[2];                    ///< Offset 46 Reserved for
> future use.
> +} GRAPHICS_PEI_PREMEM_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _GRAPHICS_PEI_PREMEM_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPr
> eMemConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPr
> eMemConfig.h
> new file mode 100644
> index 0000000000..79025d16fe
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPr
> eMemConfig.h
> @@ -0,0 +1,46 @@
> +/** @file
> +  IPU policy definitions (PreMem)
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _IPU_CONFIG_PREMEM_H_
> +#define _IPU_CONFIG_PREMEM_H_
> +
> +#pragma pack(push, 1)
> +
> +#define IPU_PREMEM_CONFIG_REVISION 1
> +
> +#define SA_IMR_IPU_CAMERA   0
> +#define SA_IMR_IPU_GEN      1
> +
> +/**
> + IPU PreMem configuration\n
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER  Header;           ///< Offset  0-27 Config Block
> Header
> +  /**
> +  Offset 28:0 :
> +  <b>(Test)</b> It enables the SA IPU Device if supported and not fused off.
> +  If FALSE, all other policies in this config block will be ignored.
> +  <b>1=TRUE</b>;
> +  0=FALSE.
> +  **/
> +  UINT32    SaIpuEnable:1;
> +  /**
> +  Offset 28:1 :
> +  <b>(Test)</b> It configure the IPU IMR to IPU Camera or IPU Gen when IPU
> is enabled.
> +  If FALSE, all other policies in this config block will be ignored.
> +  <b>0=IPU Camera</b>;
> +  1=IPU Gen
> +  **/
> +  UINT32    SaIpuImrConfiguration:1;
> +  UINT32    RsvdBits0:30;                     /// Offset 28:2 :Reserved for future
> use.
> +} IPU_PREMEM_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _IPU_PREMEM_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Mem
> oryConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Mem
> oryConfig.h
> new file mode 100644
> index 0000000000..8374ff5f68
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Mem
> oryConfig.h
> @@ -0,0 +1,534 @@
> +/** @file
> +  Policy definition of Memory Config Block
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MEMORY_CONFIG_H_
> +#define _MEMORY_CONFIG_H_
> +
> +#include <SaRegs.h>
> +
> +#pragma pack(push, 1)
> +
> +#define SA_MRC_ITERATION_MAX      (6)
> +#define SA_MRC_MAX_RCOMP          (3)
> +#define SA_MRC_MAX_RCOMP_TARGETS  (5)
> +
> +#define MEMORY_CONFIG_REVISION 3
> +
> +///
> +/// 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;
> +
> +typedef struct {
> +  UINT8
> SpdData[SA_MC_MAX_CHANNELS][SA_MC_MAX_SLOTS][SA_MC_MAX_SPD_S
> IZE];
> +//Next Field Offset 2048
> +} SPD_DATA_BUFFER;
> +
> +typedef struct {
> +  UINT8
> DqByteMap[SA_MC_MAX_CHANNELS][SA_MRC_ITERATION_MAX][2];
> +//Next Field Offset 24
> +} SA_MEMORY_DQ_MAPPING;
> +
> +typedef struct {
> +  UINT8
> DqsMapCpu2Dram[SA_MC_MAX_CHANNELS][SA_MC_MAX_BYTES_NO_ECC];
> +//Next Field Offset 16
> +} SA_MEMORY_DQS_MAPPING;
> +
> +typedef struct {
> +  UINT16  RcompResistor[SA_MRC_MAX_RCOMP];       ///< Offset 0:
> Reference RCOMP resistors on motherboard
> +  UINT16  RcompTarget[SA_MRC_MAX_RCOMP_TARGETS]; ///< Offset 6:
> RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
> +//Next Field Offset 16
> +} SA_MEMORY_RCOMP;
> +
> +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);
> +typedef UINT16     (EFIAPI * SA_IO_READ_16)              (UINTN IoAddress);
> +typedef UINT32     (EFIAPI * SA_IO_READ_32)              (UINTN IoAddress);
> +typedef UINT8      (EFIAPI * SA_IO_WRITE_8)              (UINTN IoAddress,
> UINT8 Value);
> +typedef UINT16     (EFIAPI * SA_IO_WRITE_16)             (UINTN IoAddress,
> UINT16 Value);
> +typedef UINT32     (EFIAPI * SA_IO_WRITE_32)             (UINTN IoAddress,
> UINT32 Value);
> +typedef UINT8      (EFIAPI * SA_MMIO_READ_8)             (UINTN Address);
> +typedef UINT16     (EFIAPI * SA_MMIO_READ_16)            (UINTN Address);
> +typedef UINT32     (EFIAPI * SA_MMIO_READ_32)            (UINTN Address);
> +typedef UINT64     (EFIAPI * SA_MMIO_READ_64)            (UINTN Address);
> +typedef UINT8      (EFIAPI * SA_MMIO_WRITE_8)            (UINTN Address,
> UINT8 Value);
> +typedef UINT16     (EFIAPI * SA_MMIO_WRITE_16)           (UINTN Address,
> UINT16 Value);
> +typedef UINT32     (EFIAPI * SA_MMIO_WRITE_32)           (UINTN Address,
> UINT32 Value);
> +typedef UINT64     (EFIAPI * SA_MMIO_WRITE_64)           (UINTN Address,
> UINT64 Value);
> +typedef UINT8      (EFIAPI * SA_SMBUS_READ_8)            (UINTN Address,
> RETURN_STATUS *Status);
> +typedef UINT16     (EFIAPI * SA_SMBUS_READ_16)           (UINTN Address,
> RETURN_STATUS *Status);
> +typedef UINT8      (EFIAPI * SA_SMBUS_WRITE_8)           (UINTN Address,
> UINT8 Value, RETURN_STATUS *Status);
> +typedef UINT16     (EFIAPI * SA_SMBUS_WRITE_16)          (UINTN Address,
> UINT16 Value, RETURN_STATUS *Status);
> +typedef UINT32     (EFIAPI * SA_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus,
> UINT8 Device, UINT8 Function, UINT8 Offset);
> +typedef UINT32     (EFIAPI * SA_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus,
> UINT8 Device, UINT8 Function, UINT8 Offset);
> +typedef VOID       (EFIAPI * SA_GET_RTC_TIME)            (UINT8 *Second,
> UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
> +typedef UINT64     (EFIAPI * SA_GET_CPU_TIME)            (VOID
> *GlobalData);
> +typedef VOID *     (EFIAPI * SA_MEMORY_COPY)             (VOID *Destination,
> CONST VOID *Source, UINTN NumBytes);
> +typedef VOID *     (EFIAPI * SA_MEMORY_SET_BYTE)         (VOID *Buffer,
> UINTN NumBytes, UINT8 Value);
> +typedef VOID *     (EFIAPI * SA_MEMORY_SET_WORD)         (VOID *Buffer,
> UINTN NumWords, UINT16 Value);
> +typedef VOID *     (EFIAPI * SA_MEMORY_SET_DWORD)        (VOID *Buffer,
> UINTN NumDwords, UINT32 Value);
> +typedef UINT64     (EFIAPI * SA_LEFT_SHIFT_64)           (UINT64 Data, UINTN
> NumBits);
> +typedef UINT64     (EFIAPI * SA_RIGHT_SHIFT_64)          (UINT64 Data,
> UINTN NumBits);
> +typedef UINT64     (EFIAPI * SA_MULT_U64_U32)            (UINT64
> Multiplicand, UINT32 Multiplier);
> +typedef UINT64     (EFIAPI * SA_DIV_U64_U64)             (UINT64 Dividend,
> UINT64 Divisor, UINT64 *Remainder);
> +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);
> +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);
> +typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_READ)        (UINT32 Type,
> UINT32 Command, UINT32 *Value, UINT32 *Status);
> +typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_WRITE)       (UINT32 Type,
> UINT32 Command, UINT32 Value, UINT32 *Status);
> +typedef UINT32     (EFIAPI * SA_GET_MEMORY_VDD)          (VOID
> *GlobalData, UINT32 DefaultVdd);
> +typedef UINT32     (EFIAPI * SA_SET_MEMORY_VDD)          (VOID
> *GlobalData, UINT32 DefaultVdd, UINT32 Value);
> +typedef UINT32     (EFIAPI * SA_CHECKPOINT)              (VOID *GlobalData,
> UINT32 CheckPoint, VOID *Scratch);
> +typedef VOID       (EFIAPI * SA_DEBUG_HOOK)              (VOID *GlobalData,
> UINT16 DisplayDebugNumber);
> +typedef UINT8      (EFIAPI * SA_CHANNEL_EXIST)           (VOID *Outputs,
> UINT8 Channel);
> +typedef INT32      (EFIAPI * SA_PRINTF)                  (VOID *Debug, UINT32
> Level, char *Format, ...);
> +typedef VOID       (EFIAPI * SA_DEBUG_PRINT)             (VOID *String);
> +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);
> +typedef UINT8      (EFIAPI * SA_SIGN_EXTEND)             (UINT8 Value, UINT8
> OldMsb, UINT8 NewMsb);
> +typedef VOID       (EFIAPI * SA_SHIFT_PI_COMMAND_TRAIN)  (VOID
> *GlobalData, UINT8 Channel, UINT8 Iteration, UINT8 RankMask, UINT8
> GroupMask, INT32 NewValue, UINT8 UpdateHost);
> +typedef VOID       (EFIAPI * SA_UPDATE_VREF)             (VOID *GlobalData,
> UINT8 Channel, UINT8 RankMask, UINT16 DeviceMask, UINT8 VrefType, INT32
> Offset, BOOLEAN UpdateMrcData, BOOLEAN PDAmode, BOOLEAN SkipWait);
> +typedef UINT8      (EFIAPI * SA_GET_RTC_CMOS)            (UINT8 Location);
> +typedef UINT64     (EFIAPI * SA_MSR_READ_64)             (UINT32 Location);
> +typedef UINT64     (EFIAPI * SA_MSR_WRITE_64)            (UINT32 Location,
> UINT64 Data);
> +typedef UINT32     (EFIAPI * SA_THERMAL_OVERRIDES)       (VOID
> *GlobalData);
> +typedef VOID       (EFIAPI * SA_MRC_RETURN_FROM_SMC)     (VOID
> *GlobalData, UINT32 MrcStatus);
> +typedef VOID       (EFIAPI * SA_MRC_DRAM_RESET)          (UINT32
> PciEBaseAddress, UINT32 ResetValue);
> +typedef VOID       (EFIAPI * SA_SET_LOCK_PRMRR)          (UINT32
> 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_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>:
> + - Removed GearType.
> + - Added Lp4DqsOscEn, RMTLoopCount, EnBER,
> DualDimmPerChannelBoardType.
> + <b>Revision 3</b>:
> + - Removed EvLoader, EvLoaderDelay.
> +**/
> +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 DIMM Ecc Support
> option - for Desktop only: 0=Disable, <b>1=Enable</b>
> +  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RemapEnable:1;                  ///<  - This option is used to control
> whether to enable/disable memory remap above 4GB: 0=Disable,
> <b>1=Enable</b>.
> +  UINT32  ScramblerSupport:1;             ///<  - Memory scrambler support:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set
> option: 0=Set A, <b>1=Set B</b>
> +  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bit 7-8 Reserved
> +  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  Ddr4DdpSharedClock:1;           ///<  - Select if CLK0 is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> +  UINT32  SharedZqPin:1;                  ///<  - Select if ZQ pin is shared
> between Rank ranks.  For CFL, this option only works for DDR4.  the option
> works for LPDDR4 and DDR4. <b>0=Not shared</b>, 1=Shared
> +  // Thermal Management
> +  UINT32  ThermalManagement:1;            ///<  - <CFL> Memory Thermal
> Management Support: <b>0=Disable</b>, 1=Enable.
> +  UINT32  PeciInjectedTemp:1;             ///<  - <CFL> Enable/Disable
> memory temperatures to be injected to the processor via PECI:
> <b>0=Disable</b>, 1=Enable.
> +  UINT32  ExttsViaTsOnBoard:1;            ///<  - <CFL> Enable/Disable routing
> TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH:
> <b>0=Disable</b>, 1=Enable.
> +  UINT32  ExttsViaTsOnDimm:1;             ///<  - <CFL> Enable/Disable
> routing TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>,
> 1=Enable.
> +  UINT32  VirtualTempSensor:1;            ///<  - <CFL> Enable/Disable Virtual
> Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
> +  UINT32  Lp4DqsOscEn :1;                 ///<  - <CNL> LpDdrDqDqsReTraining -
> DqDqsReTraining Enable: 0=Disable, <b>1=Enable</b>
> +  UINT32  DualDimmPerChannelBoardType:1;  ///<  - <CFL>
> DualDimmPerChannelBoardType - Option to indicate if the Memory Design for
> the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>,
> 1=Dual DIMM Design
> +  UINT32  ReservedBits1:13;
> +  /**
> +   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[SA_MC_MAX_CHANNELS]; ///< Offset 68
> +  /**
> +   Selects the ratio to multiply the reference clock by for the DDR frequency\n
> +   When RefClk is 133MHz\n
> +   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are
> invalid\n
> +   When RefClk is 100MHz\n
> +   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are
> invalid\n
> +  **/
> +  UINT8   Ratio;                  ///< Offset 70
> +  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace:
> <b>0=Disabled</b>, <b>1=Enabled</b>
> +  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in
> Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz,
> 250000000=250Hz
> +  /**
> +     - 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 76 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   EnergyScaleFact;        ///< Offset 77 Energy Scale Factor. 0=Minimal,
> 7=Maximum, <b>4=Default</b>
> +  BOOLEAN PerBankRefresh;         ///< <CNL> Offset 78 Enables and Disables
> the per bank refresh.  This only impacts memory technologies that support
> PBR: LPDDR3, LPDDR4.  FALSE=Disabled, <b>TRUE=Enabled</b>
> +  UINT8   McLock;                 ///< <CFL> Offset 79 Enable/Disable memory
> configuration register locking: 0=Disable, <b>1=Enable</b>.
> +  // Training Algorithms 1
> +  UINT32 ECT:1;                   ///< Offset 80 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;                   ///<  - 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;            ///<  - 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;                ///<  - 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;                 ///<  - 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;                  ///<  - 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;               ///<  - 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;               ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;              ///<  - 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;              ///<  - 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;               ///<  - 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;                 ///<  - 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;                ///<  - 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;                 ///<  - 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;                 ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;                ///<  - 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;                 ///<  - 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;                   ///<  - 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;                   ///<  - 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;                   ///<  - 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;                   ///<  - Enable/Disable Rank Margin Tool
> function: <b>0=Disable</b>, 1=Enable.
> +  UINT32 MEMTST:1;                ///<  - Enable/Disable Memory Test function:
> <b>0=Disable</b>, 1=Enable.
> +  UINT32 ALIASCHK:1;              ///<  - Enable/Disable DIMM SPD Alias Check:
> 0=Disable, <b>1=Enable</b>
> +  UINT32 RCVENC1D:1;              ///<  - 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;                   ///<  - 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;               ///<  - 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
> +  UINT32  CMDSR    : 1;           ///< <CFL> Offset 84 - Enable/Disable CMD
> Slew Rate Training: 0=Disable, <b>1=Enable</b>.
> +  UINT32  CMDDSEQ  : 1;           ///< <CFL>  - Enable/Disable CMD Drive
> Strength and Tx Equalization: 0=Disable, <b>1=Enable</b>.
> +  UINT32  CMDNORM  : 1;           ///< <CFL>  - Enable/Disable CMD
> Normalization: 0=Disable, <b>1=Enable</b>.
> +  UINT32  EWRDSEQ  : 1;           ///< <CFL>  - Enable/Disable Early DQ Write
> Drive Strength and Equalization Training: 0=Disable, <b>1=Enable</b>.
> +  UINT32  RDVC1D   : 1;           ///< <CNL>  - Enable/Disable Read Voltage
> Centering 1D
> +  UINT32  TXTCO    : 1;           ///< <CNL>  - Enable/Disable Write TCO Comp
> Training
> +  UINT32  CLKTCO   : 1;           ///< <CNL>  - Enable/Disable Clock TCO Comp
> Training
> +  UINT32  ReservedBits2 :25;
> +
> +  UINT32  OddRatioMode:1;             ///< Offset 88 If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  MrcTimeMeasure:1;           ///<  - Enables serial debug level to
> display the MRC execution times only: <b>0=Disable</b>, 1=Enable
> +  UINT32  MrcFastBoot:1;              ///<  - Enables the MRC fast boot path
> for faster cold boot execution: 0=Disable, <b>1=Enable</b>
> +  UINT32  DqPinsInterleaved:1;        ///<  - Interleaving mode of DQ/DQS
> pins for HSW_ULT which depends on board routing: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  RankInterleave:1;           ///<  - Rank Interleave Mode: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  EnhancedInterleave:1;       ///<  - Enhanced Interleave Mode:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  WeaklockEn:1;               ///<  - Weak Lock Enable: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  CmdTriStateDis:1;           ///<  - CMD Tri-State Support:
> <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if
> Command RTT is not present on the platform.
> +  UINT32  MemoryTrace:1;              ///<  - Memory Trace to second DDR
> channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
> +  UINT32  ChHashEnable:1;             ///<  - Channel Hash Enable: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  EnableExtts:1;              ///<  - Enable Extts: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  EnableCltm:1;               ///<  - Enable Closed Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> +  UINT32  EnableOltm:1;               ///<  - Enable Open Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> +  UINT32  EnablePwrDn:1;              ///<  - Enable Power Down control for
> DDR: 0=PCODE control, <b>1=BIOS control</b>
> +  UINT32  EnablePwrDnLpddr:1;         ///<  - Enable Power Down for LPDDR:
> 0=PCODE control, <b>1=BIOS control</b>
> +  UINT32  LockPTMregs:1;              ///<  - Lock PCU Thermal Management
> registers: 0=Disable, <b>1=Enable</b>
> +  UINT32  UserPowerWeightsEn:1;       ///<  - Allows user to explicitly set
> power weight, scale factor, and channel power floor values: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  RaplLim2Lock:1;             ///<  - Lock DDR_RAPL_LIMIT register:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RaplLim2Ena:1;              ///<  - Enable Power Limit 2:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RaplLim1Ena:1;              ///<  - Enable Power Limit 1:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  SrefCfgEna:1;               ///<  - Enable Self Refresh: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  ThrtCkeMinDefeatLpddr:1;    ///<  - Throttler CKE min defeature
> for LPDDR: 0=Disable, <b>1=Enable</b>
> +  UINT32  ThrtCkeMinDefeat:1;         ///<  - Throttler CKE min defeature:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  AutoSelfRefreshSupport:1;   ///<  - FALSE = No auto self refresh
> support, <b>TRUE = auto self refresh support</b>
> +  UINT32  ExtTemperatureSupport:1;    ///<  - FALSE = No extended
> temperature support, <b>TRUE = extended temperature support</b>
> +  UINT32  MobilePlatform:1;           ///<  - Memory controller device id
> indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be
> auto-detected and updated.
> +  UINT32  Force1Dpc:1;                ///<  - TRUE means force one DIMM per
> channel, <b>FALSE means no limit</b>
> +  UINT32  ForceSingleRank:1;          ///<  - TRUE means use Rank0 only (in
> each DIMM): <b>0=Disable</b>, 1=Enable
> +  UINT32  RhPrevention:1;             ///<  - RH Prevention Enable/Disable:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  VttTermination:1;           ///<  - Vtt Termination for Data ODT:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  VttCompForVsshi:1;          ///<  - Enable/Disable Vtt Comparator
> For Vsshi: <b>0=Disable</b>, 1=Enable
> +  UINT32  ExitOnFailure:1;            ///<  - MRC option for exit on failure or
> continue on failure: 0=Disable, <b>1=Enable</b>
> +
> +  UINT32  VddSettleWaitTime;      ///< Offset 92 Amount of time in
> microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec:
> <b>Default=0</b>
> +  UINT16  FreqSaGvLow;            ///< Offset 96 SA GV: 0 is Auto/default,
> otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333,
> 1400, 1600, 1800, 1867.
> +  UINT16  SrefCfgIdleTmr;         ///< Offset 98 Self Refresh idle timer:
> <b>512=Minimal</b>, 65535=Maximum
> +  UINT8   RhActProbability;       ///< Offset 100 Activation probability for
> Hardware RHP
> +  UINT8   SmramMask;              ///< Offset 101 Reserved memory ranges for
> SMRAM
> +  UINT16  Vc1ReadMeterThreshold;  ///< <CFL> Offset 102 VC1 Read Meter
> Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum,
> <b>0x118=Default</b>
> +  UINT32  Vc1ReadMeterTimeWindow; ///< <CFL> Offset 104 VC1 Read Meter
> Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
> +  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es):
> <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
> +
> +  UINT16  ChHashMask;             ///< Offset 140 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 142 Memory Frequency setting:
> 3=1067, 5=1333, 7=1600, 9=1867, 11=2133, 13=2400, <b>15=2667</b>
> +  UINT8   RaplLim2WindX;          ///< Offset 144 Power Limit 2 Time Window
> X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> +  UINT8   RaplLim2WindY;          ///< Offset 145 Power Limit 2 Time Window
> Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> +  UINT8   RaplLim1WindX;          ///< Offset 146 Power Limit 1 Time Window
> X value: <b>0=Minimal</b>, 3=Maximum
> +  UINT8   RaplLim1WindY;          ///< Offset 147 Power Limit 1 Time Window
> Y value: <b>0=Minimal</b>, 31=Maximum
> +  UINT16  RaplLim2Pwr;            ///< Offset 148  Power Limit 2: 0=Minimal,
> 16383=Maximum, <b>222=Default</b>
> +  UINT16  RaplLim1Pwr;            ///< Offset 150  Power Limit 1:
> <b>0=Minimal</b>, 16383=Maximum
> +  UINT8   WarmThresholdCh0Dimm0;  ///< Offset 152 Warm Threshold
> (Channel 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmThresholdCh0Dimm1;  ///< Offset 153 Warm Threshold
> (Channel 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmThresholdCh1Dimm0;  ///< Offset 154 Warm Threshold
> (Channel 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmThresholdCh1Dimm1;  ///< Offset 155 Warm Threshold
> (Channel 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotThresholdCh0Dimm0;   ///< Offset 156 Hot Threshold (Channel
> 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotThresholdCh0Dimm1;   ///< Offset 157 Hot Threshold (Channel
> 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotThresholdCh1Dimm0;   ///< Offset 158 Hot Threshold (Channel
> 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotThresholdCh1Dimm1;   ///< Offset 159 Hot Threshold (Channel
> 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmBudgetCh0Dimm0;     ///< Offset 160 Warm Budget (Channel
> 0, Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmBudgetCh0Dimm1;     ///< Offset 161 Warm Budget (Channel
> 0, Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmBudgetCh1Dimm0;     ///< Offset 162 Warm Budget (Channel
> 1, Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   WarmBudgetCh1Dimm1;     ///< Offset 163 Warm Budget (Channel
> 1, Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotBudgetCh0Dimm0;      ///< Offset 164 Hot Budget (Channel 0,
> Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotBudgetCh0Dimm1;      ///< Offset 165 Hot Budget (Channel 0,
> Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotBudgetCh1Dimm0;      ///< Offset 166 Hot Budget (Channel 1,
> Dimm 0): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   HotBudgetCh1Dimm1;      ///< Offset 167 Hot Budget (Channel 1,
> Dimm 1): 0=Minimal, <b>255=Maximum</b>
> +  UINT8   IdleEnergyCh0Dimm0;     ///< Offset 168 Idle Energy (Channel 0,
> Dimm 0): 0=Minimal, 63=Maximum, <b>10=Default</b>
> +  UINT8   IdleEnergyCh0Dimm1;     ///< Offset 169 Idle Energy (Channel 0,
> Dimm 1): 0=Minimal, 63=Maximum, <b>10=Default</b>
> +  UINT8   IdleEnergyCh1Dimm0;     ///< Offset 170 Idle Energy (Channel 1,
> Dimm 0): 0=Minimal, 63=Maximum, <b>10=Default</b>
> +  UINT8   IdleEnergyCh1Dimm1;     ///< Offset 171 Idle Energy (Channel 1,
> Dimm 1): 0=Minimal, 63=Maximum, <b>10=Default</b>
> +  UINT8   PdEnergyCh0Dimm0;       ///< Offset 172 Power Down Energy
> (Channel 0, Dimm 0): 0=Minimal, 63=Maximum, <b>6=Default</b>
> +  UINT8   PdEnergyCh0Dimm1;       ///< Offset 173 Power Down Energy
> (Channel 0, Dimm 1): 0=Minimal, 63=Maximum, <b>6=Default</b>
> +  UINT8   PdEnergyCh1Dimm0;       ///< Offset 174 Power Down Energy
> (Channel 1, Dimm 0): 0=Minimal, 63=Maximum, <b>6=Default</b>
> +  UINT8   PdEnergyCh1Dimm1;       ///< Offset 175 Power Down Energy
> (Channel 1, Dimm 1): 0=Minimal, 63=Maximum, <b>6=Default</b>
> +  UINT8   ActEnergyCh0Dimm0;      ///< Offset 176 Activation Energy
> (Channel 0, Dimm 0): 0=Minimal, 255=Maximum, <b>172=Default</b>
> +  UINT8   ActEnergyCh0Dimm1;      ///< Offset 177 Activation Energy
> (Channel 0, Dimm 1): 0=Minimal, 255=Maximum, <b>172=Default</b>
> +  UINT8   ActEnergyCh1Dimm0;      ///< Offset 178 Activation Energy
> (Channel 1, Dimm 0): 0=Minimal, 255=Maximum, <b>172=Default</b>
> +  UINT8   ActEnergyCh1Dimm1;      ///< Offset 179 Activation Energy
> (Channel 1, Dimm 1): 0=Minimal, 255=Maximum, <b>172=Default</b>
> +  UINT8   RdEnergyCh0Dimm0;       ///< Offset 180 Read Energy (Channel 0,
> Dimm 0): 0=Minimal, 255=Maximum, <b>212=Default</b>
> +  UINT8   RdEnergyCh0Dimm1;       ///< Offset 181 Read Energy (Channel 0,
> Dimm 1): 0=Minimal, 255=Maximum, <b>212=Default</b>
> +  UINT8   RdEnergyCh1Dimm0;       ///< Offset 182 Read Energy (Channel 1,
> Dimm 0): 0=Minimal, 255=Maximum, <b>212=Default</b>
> +  UINT8   RdEnergyCh1Dimm1;       ///< Offset 183 Read Energy (Channel 1,
> Dimm 1): 0=Minimal, 255=Maximum, <b>212=Default</b>
> +  UINT8   WrEnergyCh0Dimm0;       ///< Offset 184 Write Energy (Channel 0,
> Dimm 0): 0=Minimal, 255=Maximum, <b>221=Default</b>
> +  UINT8   WrEnergyCh0Dimm1;       ///< Offset 185 Write Energy (Channel 0,
> Dimm 1): 0=Minimal, 255=Maximum, <b>221=Default</b>
> +  UINT8   WrEnergyCh1Dimm0;       ///< Offset 186 Write Energy (Channel 1,
> Dimm 0): 0=Minimal, 255=Maximum, <b>221=Default</b>
> +  UINT8   WrEnergyCh1Dimm1;       ///< Offset 187 Write Energy (Channel 1,
> Dimm 1): 0=Minimal, 255=Maximum, <b>221=Default</b>
> +
> +
> +  UINT8   MaxRttWr;               ///< Offset 188 Maximum DIMM RTT_WR to
> use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
> +  UINT8   ThrtCkeMinTmr;          ///< Offset 189 Throttler CKE min timer:
> 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
> +  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 Throttler CKE min timer
> for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
> +  UINT8   BerEnable;              ///< Offset 191 BER Enable and # of Addresses
> passed in: <b>0=Minimal</b>, 8=Maximum
> +  UINT8   CkeRankMapping;         ///< Offset 192 Bits [7:4] - Channel 1, bits
> [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes
> to.
> +  UINT8   StrongWkLeaker;         ///< Offset 193 Strong Weak Leaker:
> 1=Minimal, <b>7=Maximum</b>
> +  UINT8   CaVrefConfig;           ///< Offset 194 0=VREF_CA goes to both CH_A
> and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to CH_A,
> VREF_DQ_B to CH_B</b>
> +  UINT8   SaGv;                   ///< Offset 195 SA GV: 0=Disabled; 1=FixedLow;
> CFL: 2=FixedHigh, CNL: 2=FixedMid; <b>CFL: 3=Enabled</b> CNL: 3=FixedHigh;
> <b>CNL: 4=Enabled</b>
> +  UINT8   RaplPwrFlCh1;           ///< Offset 196 Power Channel 1 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> +  UINT8   RaplPwrFlCh0;           ///< Offset 197 Power Channel 0 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> +  UINT8   NModeSupport;           ///< Offset 198 Memory N Mode Support -
> Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
> +  UINT8   RefClk;                 ///< Offset 199 Selects the DDR base reference
> clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
> +  UINT8   EnCmdRate;              ///< Offset 200 CMD Rate Enable: 0=Disable,
> 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7
> CMDs
> +  UINT8   Refresh2X;              ///< Offset 201 Refresh 2x: <b>0=Disable</b>,
> 1=Enable for WARM or HOT, 2=Enable for HOT only
> +  UINT8   EpgEnable;              ///< Offset 202 Enable Energy Performance
> Gain.
> +  UINT8   RhSolution;             ///< Offset 203 Type of solution to be used for
> RHP - 0/1 = HardwareRhp/Refresh2x
> +  UINT8   UserThresholdEnable;    ///< Offset 204 Flag to manually select the
> DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   UserBudgetEnable;       ///< Offset 205 Flag to manually select the
> Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable,
> <b>0=Default</b>
> +  UINT8   TsodTcritMax;           ///< Offset 206 TSOD Tcrit Maximum Value
> to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
> +
> +  UINT8   TsodEventMode;          ///< Offset 207 Flag to Enable Event Mode
> Interruption in TSOD Configuration Register, 0=Disable,  1=Enable,
> <b>1=Default</b>
> +  UINT8   TsodEventPolarity;      ///< Offset 208 Event Signal Polarity in TSOD
> Configuration Register, 0=Low,  1=High, <b>0=Default</b>
> +  UINT8   TsodCriticalEventOnly;  ///< Offset 209 Critical Trigger Only in TSOD
> Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
> +  UINT8   TsodEventOutputControl; ///< Offset 210 Event Output Control in
> TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
> +  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 Alarm Windows Lock Bit
> in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
> +  UINT8   TsodCriticaltripLockBit;///< Offset 212 Critical Trip Lock Bit in TSOD
> Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
> +  UINT8   TsodShutdownMode;       ///< Offset 213 Shutdown Mode TSOD
> Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
> +  UINT8   TsodThigMax;            ///< Offset 214 Thigh Max Value In the  for
> CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   TsodManualEnable;       ///< Offset 215 Flag to manually select the
> TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   DllBwEn0;               ///< Offset 216 DllBwEn value for 1067
> +  UINT8   DllBwEn1;               ///< Offset 217 DllBwEn value for 1333
> +  UINT8   DllBwEn2;               ///< Offset 218 DllBwEn value for 1600
> +  UINT8   DllBwEn3;               ///< Offset 219 DllBwEn value for 1867 and up
> +  UINT8   RetrainOnFastFail;      ///< Offset 220 Restart MRC in Cold mode if
> SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
> +  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 Force OLTM or 2X Refresh
> when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
> +  UINT8   PowerDownMode;          ///< Offset 222 CKE Power Down Mode:
> <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
> +  UINT8   PwdwnIdleCounter;       ///< Offset 223 CKE Power Down Mode
> Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
> +  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal,
> 0xFF=Maximum, <b>0x99=Default</b>
> +  UINT8   CmdRanksTerminated;     ///< <CNL> Offset 225 LPDDR4: Bitmask
> of ranks that have CA bus terminated. <b>0x01=Default, Rank0 is terminating
> and Rank1 is non-terminating</b>
> +  UINT8   GdxcEnable;             ///< <CFL> Offset 226 GDXC  MOT enable
> +  UINT8   GdxcIotSize;            ///< <CFL> Offset 227 IOT size in multiples of
> 8MEG
> +  UINT8   GdxcMotSize;            ///< <CFL> Offset 228 MOT size in multiples
> of 8MEG
> +  UINT8   RMTLoopCount;           ///< Offset 229 Indicates the Loop Count to
> be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO,
> <b>0=Default</b>
> +  UINT16  FreqSaGvMid;            ///< Offset 230 SA GV: 0 is Auto/default,
> otherwise holds the frequency value expressed as an integer:
> <b>0=Default</b>, 1600, 1800, 1867, 2000, 2133, etc.
> +
> +  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool
> Per Task. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  TrainTrace:1;                 ///< Offset 232 Bit 1: Trained state tracing
> debug. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  SafeMode:1;                   ///< Offset 232 Bit 2: Define if safe mode
> is enabled for MC/IO
> +  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is
> enabled for Rank Margin Tool
> +  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4:
> Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm
> 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
> +  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable
> RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Force MRC
> training on warm boot : <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy
> Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
> +
> +  // TurnAround Timing
> +  UINT8   tRd2RdSG;               ///< Offset 236 - Read-to-Read   Same Group
> Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tRd2RdDG;               ///< Offset 237 - Read-to-Read   Different
> Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same
> Group and Different Group Timings must be the same for Non-DDR4 memory.
> +  UINT8   tRd2RdDR;               ///< Offset 238 - Read-to-Read   Different
> Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tRd2RdDD;               ///< Offset 239 - Read-to-Read   Different
> DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tRd2WrSG;               ///< Offset 240 - Read-to-Write  Same Group
> Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tRd2WrDG;               ///< Offset 241 - Read-to-Write  Different
> Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same
> Group and Different Group Timings must be the same for Non-DDR4 memory.
> +  UINT8   tRd2WrDR;               ///< Offset 242 - Read-to-Write  Different
> Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tRd2WrDD;               ///< Offset 243 - Read-to-Write  Different
> DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tWr2RdSG;               ///< Offset 244 - Write-to-Read  Same Group
> Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 86=Maximum.
> +  UINT8   tWr2RdDG;               ///< Offset 245 - Write-to-Read  Different
> Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same
> Group and Different Group Timings must be the same for Non-DDR4 memory.
> +  UINT8   tWr2RdDR;               ///< Offset 246 - Write-to-Read  Different
> Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tWr2RdDD;               ///< Offset 247 - Write-to-Read  Different
> DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tWr2WrSG;               ///< Offset 248 - Write-to-Write Same Group
> Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tWr2WrDG;               ///< Offset 249 - Write-to-Write Different
> Group Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum. Same
> Group and Different Group Timings must be the same for Non-DDR4 memory.
> +  UINT8   tWr2WrDR;               ///< Offset 250 - Write-to-Write Different
> Rank  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT8   tWr2WrDD;               ///< Offset 251 - Write-to-Write Different
> DIMM  Turn Around Timing: <b>0=AUTO</b>, 4=Minimal, 64=Maximum.
> +  UINT16  tRRD_L;                 ///< <CFL> Offset 252 - User defined DDR4
> Memory Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> +  UINT16  tRRD_S;                 ///< <CFL> Offset 254 - User defined DDR4
> Memory Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> +  UINT16  tWTR_L;                 ///< <CFL> Offset 266 - User defined DDR4
> Memory Timing tWTR_L value,  valid when MemoryProfile is
> CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
> +  UINT16  tWTR_S;                 ///< <CFL> Offset 268 - User defined DDR4
> Memory Timing tWTR_S value,  valid when MemoryProfile is
> CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
> +
> +} MEMORY_CONFIGURATION;
> +
> +/// Memory Configuration
> +/// The contents of this structure are not CRC'd by the MRC for option change
> detection.
> +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 200  Function
> calls into the MRC.
> +  SPD_DATA_BUFFER          *SpdData;            ///< Offset 236  Memory SPD
> data, will be used by the MRC when SPD SmBus address is zero.
> +  SA_MEMORY_DQ_MAPPING     *DqByteMap;          ///< Offset 240
> LPDDR3 DQ byte mapping to CMD/CTL/CLK, from the CPU side.
> +  SA_MEMORY_DQS_MAPPING    *DqsMap;             ///< Offset 244
> LPDDR3 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 260  Ask MRC to
> clear memory content: <b>FALSE=Do not Clear Memory</b>; TRUE=Clear
> Memory
> +  UINT32                   MemTestOnWarmBoot:1; ///< Offset 260  Run Base
> Memory Test On WarmBoot:  0=Disabled, <b>1=Enabled</b>
> +  UINT32                   ReservedBits5:30;
> +  /**
> +   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 264
> +  UINT8   Reserved11[3];                        ///< Offset 265  Reserved
> +} MEMORY_CONFIG_NO_CRC;
> +#pragma pack(pop)
> +
> +#endif // _MEMORY_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Mem
> oryDxeConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Mem
> oryDxeConfig.h
> new file mode 100644
> index 0000000000..9f01c172f2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Mem
> oryDxeConfig.h
> @@ -0,0 +1,61 @@
> +/** @file
> +  Memory DXE Policy definitions
> +
> +  Copyright (c) 2019 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
> +
> +/**
> +  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.
> +**/
> +typedef struct {
> +  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;
> +  UINT8                 MrcTimeMeasure;   ///< Offset 38: MRC execution time
> measurement: <b>0=Disable</b>, 1=Enable
> +  UINT8                 MrcFastBoot;      ///< Offset 39: Fast boot: 0=Disable,
> <b>1=Enable</b>
> +} MEMORY_DXE_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _MEMORY_DXE_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Misc
> DxeConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Misc
> DxeConfig.h
> new file mode 100644
> index 0000000000..7a8894a5c0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Misc
> DxeConfig.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  MISC DXE policy definitions
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MISC_DXE_CONFIG_H_
> +#define _MISC_DXE_CONFIG_H_
> +
> +#pragma pack(push, 1)
> +
> +#define MISC_DXE_CONFIG_REVISION 2
> +
> +/**
> +  This data structure includes miscellaneous configuration variables such SA
> thermal device
> +  control. The data elements should be initialized by a Platform Module.\n
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2:</b>
> +  - Added RmrrCsmeBaseAddress fields.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER   Header;                    ///< Offset 0-27 Config
> Block Header
> +  EFI_PHYSICAL_ADDRESS  *RmrrUsbBaseAddress;       ///< Offset 28 The
> field is used to describe the platform USB Reserved memory for Intel VT-d
> support. Platform code should provide this information for Intel VT-d DXE
> driver use
> +  UINT32                EnableAbove4GBMmio : 1;    ///< Offset 29:0
> Enable/disable above 4GB MMIO resource support: <b>0=Disable</b>,
> 1=Enable
> +  UINT32                RsvdBits0          : 31;   ///< Offset 29:1 Reserved bits.
> +  EFI_PHYSICAL_ADDRESS  *RmrrCsmeBaseAddress;      ///< The field is used
> to describe the CSME Reserved memory.
> +} MISC_DXE_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _MISC_DXE_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Over
> ClockingConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Over
> ClockingConfig.h
> new file mode 100644
> index 0000000000..b623f14c15
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Over
> ClockingConfig.h
> @@ -0,0 +1,51 @@
> +/** @file
> +  Policy definition for System Agent overclocking Config Block
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _OVERCLOCKING_PREMEM_CONFIG__H_
> +#define _OVERCLOCKING_PREMEM_CONFIG__H_
> +#pragma pack(push, 1)
> +
> +#define SA_OVERCLOCKING_CONFIG_REVISION 2
> +
> +/**
> + Defines the overclocking configuration parameters for System Agent.\n
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - Add GT unslice support.
> +
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER  Header;    ///< Offset 0-27 Config Block Header
> +  /**
> +  Offset 28:0 :
> +  Enable disable of SA overclocking mailbox commands.
> +  If disabled, or if PcdSaOcEnable is disabled, all other policies in this config
> block are ignored.
> +  <b>0=Disable</b>,
> +  1=Enable
> +  **/
> +  UINT32  OcSupport             : 1;
> +  UINT32  GtVoltageMode         : 1;    ///< Offset 28:1 :Specifies whether GT
> voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>,
> 1=Override
> +  UINT32  RealtimeMemoryTiming  : 1;    ///< Offset 28:2 :Enable/Disable
> the message sent to the CPU to allow realtime memory timing changes after
> MRC_DONE. <b>0=Disable</b>, 1=Enable
> +  UINT32  GtusVoltageMode       : 1;    ///< Offset 28:3 :Specifies whether GT
> unslice voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>,
> 1=Override
> +  UINT32  RsvdBits0             : 28;   ///< Offset 28:4 - 31 :Reserved for future
> use
> +  UINT8   GtMaxOcRatio;                 ///< Offset 32 Maximum GT turbo ratio
> override: 0=Minimal, 255=Maximum, <b>0=AUTO</b>
> +  UINT8   Rsvd0;                        ///< Offset 33 Reserved for DWORD
> alignment
> +  INT16   GtVoltageOffset;              ///< Offset 34 The voltage offset applied
> to GT slice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>,
> 1000=Maximum
> +  UINT16  GtVoltageOverride;            ///< Offset 36 The GT voltage override
> which is applied to the entire range of GT frequencies <b>0=Default</b>
> +  UINT16  GtExtraTurboVoltage;          ///< Offset 38 The adaptive voltage
> applied during turbo frequencies. Valid range from 0 to 2000mV:
> <b>0=Minimal</b>, 2000=Maximum
> +  INT16   SaVoltageOffset;              ///< Offset 40 The voltage offset applied
> to the SA. Valid range from -1000mv to 1000mv: <b>0=Default</b>
> +  INT16   GtusVoltageOffset;            ///< Offset 42 The voltage offset applied
> to GT unslice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>,
> 1000=Maximum
> +  UINT16  GtusVoltageOverride;          ///< Offset 44 The GT unslice voltage
> override which is applied to the entire range of GT frequencies:
> <b>0=Default</b>
> +  UINT16  GtusExtraTurboVoltage;        ///< Offset 46 The adaptive voltage
> applied during turbo frequencies. Valid range from 0 to 2000mV:
> <b>0=Default</b>
> +  UINT8   GtusMaxOcRatio;               ///< Offset 48 Maximum GTus turbo
> ratio override: 0=Minimal, 6=Maximum, <b>0=AUTO</b>
> +  UINT8   Rsvd1[3];                     ///< Offset 49-51 Reserved for DWORD
> alignment
> +} OVERCLOCKING_PREMEM_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _OVERCLOCKING_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieD
> xeConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieD
> xeConfig.h
> new file mode 100644
> index 0000000000..f0b9670f64
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieD
> xeConfig.h
> @@ -0,0 +1,135 @@
> +/** @file
> +  PCIE DXE policy definitions
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIE_DXE_CONFIG_H_
> +#define _PCIE_DXE_CONFIG_H_
> +
> +#pragma pack(push, 1)
> +
> +#define PCIE_DXE_CONFIG_REVISION 1
> +
> +///
> +/// Device List for special ASPM override
> +///
> +typedef struct {
> +  UINT16  VendorId;         ///< Offset 0 PCI Configuration space offset 0
> +  UINT16  DeviceId;         ///< Offset 2 PCI Configuration space offset 2
> +  UINT8   RevId;            ///< Offset 4 PCI Configuration space offset 8; 0xFF
> means all steppings
> +  UINT8   RootApmcMask;     ///< Offset 5 Root ASPM override bit mask
> <b>0=No override</b>
> +  UINT8   EndpointApmcMask; ///< Offset 6 Endpoint ASPM override bit
> mask <b>0=No override</b>
> +  UINT8   Rsvd;             ///< Offset 7 Reserved
> +} PCIE_ASPM_OVERRIDE_LIST;
> +
> +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
> +} SA_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.
> +**/
> +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: This field is used to describe the PEG L0s advanced control
> +  0=ASPM L0s disabled, 1=ASPM L0s enabled on RP, 2=ASPM L0s enabled on EP,
> <b>3=ASPM L0s enabled on both RP and EP</b>
> +**/
> +  UINT8                    PegAspmL0s[SA_PEG_MAX_FUN];
> +/**
> +  Offset 36: 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];
> +/**
> +  Offset 40: This field is used as a pointer to the ASPM device override table,
> default points to an\n
> +  existing table mPcieAspmDevsOverride\n
> +  Refer to DxeSaPolicyLib.c for the usage.
> +  Note:  This exclusion list helps avoid potential system hangs.
> +**/
> +  PCIE_ASPM_OVERRIDE_LIST  *PcieAspmDevsOverride;
> +/**
> +  Offset 48: This field is used as a pointer to the LTR device override table,
> default points to an existing
> +  table mPcieLtrDevsOverride.\n
> +  Refer to DxeSaPolicyLib.c for the usage.
> +**/
> +  PCIE_LTR_DEV_INFO        *PcieLtrDevsOverride;
> +  SA_PCIE_PWR_OPT          PegPwrOpt[SA_PEG_MAX_FUN];     ///< Offset
> 60: This field is used to describe the PCIe LTR/OBFF relevant settings
> +  UINT8                    Rsvd1[3];                      /// Reserved for future use
> +} PCIE_DXE_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _PCIE_DXE_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieP
> eiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieP
> eiConfig.h
> new file mode 100644
> index 0000000000..7899504865
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieP
> eiConfig.h
> @@ -0,0 +1,60 @@
> +/** @file
> +  Policy definition for PCIe Config Block
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIE_PEI_CONFIG_H_
> +#define _PCIE_PEI_CONFIG_H_
> +
> +#include <Library/GpioLib.h>
> +#include <SaAccess.h>
> +
> +#pragma pack(push, 1)
> +
> +#define SA_PCIE_PEI_CONFIG_REVISION 1
> +
> +/**
> + PCI Express and DMI controller configuration - PostMem\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 Extended Sync Control
> +  - <b>Disabled</b> (0x0)  : Disable DMI Extended Sync (Default)
> +  - Enabled         (0x1)  : Enable DMI Extended Sync
> +  **/
> +  UINT32                 DmiExtSync                      :  1;
> +  /**
> +    Offset 28:1
> +   <b>(Test)</b>DMI IOT Control
> +  - <b>Disabled</b> (0x0)  : Disable DMI IOT (Default)
> +  - Enabled         (0x1)  : Enable DMI IOT
> +  **/
> +  UINT32                 DmiIot                          :  1;
> +  UINT32                 RsvdBits1                       :  30;       ///< Offset
> 28:2-31 :Reserved for future use.
> +  UINT8                  DmiAspm;                                     ///< Offset 32 This
> field is used to describe the ASPM control for DMI: <b>3=PcieAspmL0sL1</b>,
> 2=PcieAspmL1, 1=PcieAspmL0s, 0=PcieAspmDisabled.
> +  UINT8                  Rsvd1[3];                                    ///< Offset 33 to 35
> +  UINT8                  PegDeEmphasis[SA_PEG_MAX_FUN];               ///<
> Offset 36 This field is used to describe the DeEmphasis control for PEG (-6 dB
> and -3.5 dB are the options)SA_PEG_MAX_FUN = 3 for CFL and
> SA_PEG_MAX_FUN = 4 for CNL, offsets are adjusted accordingly
> +  UINT8                  PegMaxPayload[SA_PEG_MAX_FUN];               ///<
> <b>(Test)</b> Offset 39/40 This field is used to describe the PEG Max Pay Load
> Size (0xFF: Auto, 0:128B, 1:256B)
> +  /**
> +   PCIe Slot Power Capabilities. SlotPowerLimitValue in combination with
> SlotPowerLimitScale specifies the upper limit on power supplied by slot.
> +  **/
> +  UINT8                  PegSlotPowerLimitValue[SA_PEG_MAX_FUN];      ///<
> Offset 42/44 8 bit value
> +  UINT8                  PegSlotPowerLimitScale[SA_PEG_MAX_FUN];      ///<
> Offset 45/48 2 bit value: <b>00 = 1.0x</b>, 01 = 0.1x, 10 = 0.01x and 11 = 0.001x
> +  /**
> +   Offset 48/52
> +   PCIe Physical Slot Number (13 bit value). Indicates the physical slot number
> attached to the port.
> +  **/
> +  UINT16                 PegPhysicalSlotNumber[SA_PEG_MAX_FUN];
> +  UINT8                  Rsvd2[2];
> +} PCIE_PEI_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _PCIE_PEI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieP
> eiPreMemConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieP
> eiPreMemConfig.h
> new file mode 100644
> index 0000000000..a53bf3c7bd
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieP
> eiPreMemConfig.h
> @@ -0,0 +1,354 @@
> +/** @file
> +  Policy definition for PCIe Config Block
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIE_PEI_PREMEM_CONFIG_H_
> +#define _PCIE_PEI_PREMEM_CONFIG_H_
> +
> +#include <Library/GpioLib.h>
> +#include <SaAccess.h>
> +
> +#pragma pack(push, 1)
> +
> +#define SA_PCIE_PEI_PREMEM_CONFIG_REVISION 3
> +
> +///
> +/// SA GPIO Data Structure
> +///
> +typedef struct {
> +  GPIO_PAD      GpioPad;        ///< Offset 0: GPIO Pad
> +  UINT8         Value;          ///< Offset 4: GPIO Value
> +  UINT8         Rsvd0[3];       ///< Offset 5: Reserved for 4 bytes alignment
> +  UINT32        Active  :1;     ///< Offset 8: 0=Active Low; 1=Active High
> +  UINT32        RsvdBits0:31;
> +} SA_GPIO_INFO_PCIE;
> +
> +///
> +/// SA Board PEG GPIO Info
> +///
> +typedef struct {
> +  SA_GPIO_INFO_PCIE  SaPeg0ResetGpio;    ///< Offset 0:  PEG0 PERST#
> GPIO assigned, must be a PCH GPIO pin
> +  SA_GPIO_INFO_PCIE  SaPeg3ResetGpio;    ///< Offset 12: PEG3 PERST#
> GPIO assigned, must be a PCH GPIO pin
> +  BOOLEAN            GpioSupport;        ///< Offset 24: 1=Supported; 0=Not
> Supported
> +  UINT8              Rsvd0[3];           ///< Offset 25: Reserved for 4 bytes
> alignment
> +} PEG_GPIO_DATA;
> +
> +
> +/**
> + 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.
> +  <b>Revision 2</b>:
> +  - Change PegGen3RxCtleOverride of PCIE_PEI_PREMEM_CONFIG from one
> bit to UINT8
> +  - Change DmiGen3RxCtlePeaking default to 0
> +  <b>Revision 3</b>:
> +  - Added PEG IMR support
> +  - Added UINT8 PegImrEnable
> +  - Added UINT16 PegImrSize
> +  - Added UINT8 ImrRpSelection
> +**/
> +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;
> +
> +  /**
> +   Offset 28:8 to 28:15 :
> +   <b>(Test)</b> PEG Enable Control
> +  - Disabled    (0x0)  : Disable PEG Port
> +  - Enabled     (0x1)  : Enable PEG Port (If Silicon SKU permits it)
> +  - <b>Auto</b> (0x2)  : If an endpoint is present, enable the PEG Port,
> Disable otherwise (Default)
> +  **/
> +  UINT32                 Peg0Enable                      :  2;        ///<
> Enable/Disable PEG 0:1:0 Root Port
> +  UINT32                 Peg1Enable                      :  2;        ///<
> <b>(Test)</b> Enable/Disable PEG 0:1:1 Root Port
> +  UINT32                 Peg2Enable                      :  2;        ///<
> <b>(Test)</b> Enable/Disable PEG 0:1:2 Root Port
> +  UINT32                 Peg3Enable                      :  2;        ///<
> <b>(Test)</b> Enable/Disable PEG 0:6:0 Root Port.
> +
> +  /**
> +   Offset 28:16 :
> +   <b>(Test)</b> PCIe 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                 Peg0MaxLinkSpeed                :  2;        ///< PCIe Link
> Speed Control for PEG 0:1:0 Root Port.
> +  UINT32                 Peg1MaxLinkSpeed                :  2;        ///<
> <b>(Test)</b> PCIe Link Speed Control for PEG 0:1:1 Root Port.
> +  UINT32                 Peg2MaxLinkSpeed                :  2;        ///<
> <b>(Test)</b> PCIe Link Speed Control for PEG 0:1:2 Root Port.
> +  UINT32                 Peg3MaxLinkSpeed                :  2;        ///<
> <b>(Test)</b> PCIe Link Speed Control for PEG 0:6:0 Root Port.
> +  UINT32                 RsvdBits0                       :  8;        ///< Offset
> 28:24 :Reserved for future use
> +
> +  /**
> +   Offset 32:0 :
> +   <b>(Test)</b> PCIe Link Width Control
> +  - <b>Auto</b> (0x0)  : Maximum possible Link width (Default)
> +  - X1          (0x1)  : Limit Link to X1 Width
> +  - X2          (0x2)  : Limit Link to X2 Width
> +  - X4          (0x3)  : Limit Link to X4 Width
> +  - X8          (0x4)  : Limit Link to X8 Width
> +  **/
> +  UINT32                 Peg0MaxLinkWidth                :  3;        ///< PCIe Link
> Width Control for PEG 0:1:0 Root Port.
> +  UINT32                 Peg1MaxLinkWidth                :  3;        ///<
> <b>(Test)</b> PCIe Link Width Control for PEG 0:1:1 Root Port.
> +  UINT32                 Peg2MaxLinkWidth                :  3;        ///<
> <b>(Test)</b> PCIe Link Width Control for PEG 0:1:2 Root Port.
> +  UINT32                 Peg3MaxLinkWidth                :  3;        ///<
> <b>(Test)</b> PCIe Link Width Control for PEG 0:6:0 Root Port.
> +  /**
> +    Offset 32:12 to 32:15 :
> +    Power down unused lanes on the PEG Root Port.
> +  - Disabled     (0x0) : No power saving.
> +  - <b>Auto</b>  (0x1) : Bios will power down unused lanes based on the max
> possible link width
> +  **/
> +  UINT32                 Peg0PowerDownUnusedLanes        :  1;        ///<
> Power down unused lanes on the PEG 0:1:0 Root Port.
> +  UINT32                 Peg1PowerDownUnusedLanes        :  1;        ///<
> Power down unused lanes on the PEG 0:1:1 Root Port.
> +  UINT32                 Peg2PowerDownUnusedLanes        :  1;        ///<
> Power down unused lanes on the PEG 0:1:2 Root Port.
> +  UINT32                 Peg3PowerDownUnusedLanes        :  1;        ///<
> Power down unused lanes on the PEG 0:6:0 Root Port.
> +
> +  /**
> +   Offset 32:16 to 32:23 :
> +   <b>(Test)</b> PCIe 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                 Peg0Gen3EqPh2Enable             :  2;        ///< Phase2
> EQ enable on the PEG 0:1:0 Root Port.
> +  UINT32                 Peg1Gen3EqPh2Enable             :  2;        ///<
> <b>(Test)</b> Phase2 EQ enable on the PEG 0:1:1 Root Port.
> +  UINT32                 Peg2Gen3EqPh2Enable             :  2;        ///<
> <b>(Test)</b> Phase2 EQ enable on the PEG 0:1:2 Root Port.
> +  UINT32                 Peg3Gen3EqPh2Enable             :  2;        ///<
> <b>(Test)</b> Phase2 EQ enable on the PEG 0:6:0 Root Port.
> +  UINT32                 RsvdBits1                       :  8;        ///< Offset
> 32:24 :Reserved for future use
> +  /**
> +   Offset 36:0 to 36:11 :
> +   <b>(Test)</b> Select the method for performing Phase3 of Gen3
> Equalization.
> +  - <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 PegGen3EndPointPreset
> array for Phase1 AND Phase3 (Instead of just Phase1)
> +  - Disabled    (0x4)  : Bypass Equalization Phase 3
> +  **/
> +  UINT32                 Peg0Gen3EqPh3Method             :  3;        ///< Phase3
> EQ method on the PEG 0:1:0 Root Port.
> +  UINT32                 Peg1Gen3EqPh3Method             :  3;        ///<
> <b>(Test)</b> Phase3 EQ method on the PEG 0:1:1 Root Port.
> +  UINT32                 Peg2Gen3EqPh3Method             :  3;        ///<
> <b>(Test)</b> Phase3 EQ method on the PEG 0:1:2 Root Port.
> +  UINT32                 Peg3Gen3EqPh3Method             :  3;        ///<
> <b>(Test)</b> Phase3 EQ method on the PEG 0:6:0 Root Port.
> +  /**
> +   Offset 36:12 :
> +   <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;
> +  /**
> +   Offset 36:13 :
> +   <b>(Test)</b> Always Attempt Gen3 Software Equalization
> +
> +   When enabled, Gen3 Software Equalization will be executed every boot.
> When disabled, it will be only executed if the CPU
> +   or EP is changed, otherwise it is skipped and the previous EQ value will be
> re-used.
> +
> +   This setting will only have an effect if Software Equalization is enabled and
> OEM Platform Code implements
> +   save/restore of the PegDataPtr data (see below).  If PegDataPtr is not
> saved/restored RC forces this to be enabled.
> +
> +  - <b>Disabled</b> (0x0)  : Reuse EQ settings saved/restored from NVRAM
> whenever possible (Default)
> +  - Enabled         (0x1)  : Re-test and generate new EQ values every boot, not
> recommended
> +  **/
> +  UINT32                 Gen3SwEqAlwaysAttempt           :  1;
> +  /**
> +   Offset 36:14 to 36:16 :
> +   <b>(Test)</b> Select number of TxEq presets to test in the PCIe/DMI
> Software Equalization Algorithm
> +  - P7,P3,P5,P8 (0x0)  : Test Presets 7, 3, 5, and 8
> +  - P0-P9       (0x1)  : Test Presets 0-9
> +  - <b>Auto</b> (0x2)  : Use the current default method (Default)
> +  Auto will test Presets 7, 3, 5, and 8.  It is possible for this default to change
> over time;
> +  using "Auto" will ensure Reference Code always uses the latest default
> settings.
> +  @warning Do not change from the default.  Hard to detect issues are likely.
> +  **/
> +  UINT32                 Gen3SwEqNumberOfPresets         :  3;
> +  /**
> +   Offset 36:17 to 36:18:
> +   <b>(Test)</b> Offset 36 Enable use of the Voltage Offset and Centering Test
> in the PCIe Software Equalization Algorithm
> +  - Disabled     (0x0) : Disable VOC Test
> +  - Enabled      (0x1) : Enable VOC Test
> +  - <b>Auto</b>  (0x2) : Use the current default (Default)
> +  **/
> +  UINT32                 Gen3SwEqEnableVocTest           :  2;
> +  /**
> +    Offset 36:19 :
> +    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;
> +  /**
> +   Offset 36:20 :
> +   <b>(Test)</b> PCIe Rx Compliance Testing Mode
> +  - <b>Disabled</b> (0x0) : Normal Operation             - Disable PCIe Rx
> Compliance testing (Default)
> +  - Enabled         (0x1) : PCIe Rx Compliance Test Mode - PEG controller is in
> Rx Compliance Testing Mode; it should only be set when doing PCIe compliance
> testing
> +  **/
> +  UINT32                 PegRxCemTestingMode             :  1;
> +
> +  /**
> +    Offset 36:21 to 36:24 :
> +    <b>(Test)</b> PCIe Rx Compliance Loopback Lane
> +
> +    When PegRxCemTestingMode is Enabled, the specificied Lane (0 - 15) will
> be
> +    used for RxCEMLoopback.
> +
> +    Default is Lane 0.
> +  **/
> +  UINT32                 PegRxCemLoopbackLane            :  4;
> +  /**
> +   Offset 36:25 to 36:28 :
> +   <b>(Test)</b> Generate PCIe BDAT Margin Table. Set this policy to enable
> the generation and addition of PCIe margin data to the BDAT table.
> +  - <b>Disabled</b> (0x0) : Normal Operation          - Disable PCIe BDAT
> margin data generation (Default)
> +  - PortData        (0x1) : Port Data                 - Generate PCIe BDAT margin
> data
> +  **/
> +  UINT32                 PegGenerateBdatMarginTable      :  4;
> +   /**
> +   Offset 36:29 :
> +   <b>(Test)</b> PCIe Non-Protocol Awareness for Rx Compliance Testing
> +  - <b>Disabled</b> (0x0) : Normal Operation                - Disable
> non-protocol awareness (Default)
> +  - Enabled         (0x1) : Non-Protocol Awareness Enabled  - Enable
> non-protocol awareness for compliance testing
> +  **/
> +  UINT32                 PegRxCemNonProtocolAwareness    :  1;
> +   /**
> +   Offset 36:30 :
> +   <b>(Test)</b> PCIe Disable Spread Spectrum Clocking. This feature should
> be TRUE only for compliance testing
> +  - <b>False</b>          (0x0) : Normal Operation                 - SSC enabled
> (Default)
> +  - True                  (0x1) : Disable SSC                      - Disable SSC for
> compliance testing
> +  **/
> +  UINT32                 PegDisableSpreadSpectrumClocking :  1;
> +
> +  UINT32                 RsvdBits2                        :  1;
> +
> +  UINT8                  DmiGen3RootPortPreset[SA_DMI_MAX_LANE];      ///<
> Offset 40 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 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 48 Hint value per lane for the DMI Gen3 End Point. Range: 0-6, 2 is
> default for each lane
> +  /**
> +   Offset 52 :
> +   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 0.
> +  **/
> +
> +  UINT8                  DmiGen3RxCtlePeaking[SA_DMI_MAX_BUNDLE];
> +
> +  UINT8                  PegGen3RootPortPreset[SA_PEG_MAX_LANE];      ///<
> Offset 54 <b>(Test)</b> Used for programming PEG Gen3 preset values per
> lane. Range: 0-9, 8 is default for each lane
> +  UINT8                  PegGen3EndPointPreset[SA_PEG_MAX_LANE];      ///<
> Offset 70 <b>(Test)</b> Used for programming PEG Gen3 preset values per
> lane. Range: 0-9, 7 is default for each lane
> +  UINT8                  PegGen3EndPointHint[SA_PEG_MAX_LANE];        ///<
> Offset 86 <b>(Test)</b> Hint value per lane for the PEG Gen3 End Point. Range:
> 0-6, 2 is default for each lane
> +  /**
> +   Offset 102:
> +   PCIe 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                  PegGen3RxCtlePeaking[SA_PEG_MAX_BUNDLE];
> +  /**
> +  Offset 110:
> +  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535,
> default is 1000.
> +  @warning Do not change from the default.  Hard to detect issues are likely.
> +  @note An attack on this policy could result in an apparent hang,
> +    but the system will eventually boot.  This variable should be protected.
> +  **/
> +  UINT16                 Gen3SwEqJitterDwellTime;
> +  /**
> +   Offset 112:
> +   This is a memory data pointer for saved preset search results. The reference
> code will store
> +   the Gen3 Preset Search results in the SaPegHob. In order to skip the Gen3
> +   preset search on boots where the PEG card configuration has not changed
> since the previous boot,
> +   platform code can save the contents of the SaPegHob in DXE (When it
> present and for size reported by Header.HobLength)
> +   and provide a pointer to a restored copy of that data. Default value is NULL,
> which results in a full
> +   preset search every boot.
> +
> +   @note An attack on this policy could prevent the PCIe display from working
> until a boot when
> +   PegDataPtr is NULL or Gen3SwEqAlwaysAttempt is enabled.  The variable
> used to save the
> +   preset search results should be protected in a way that it can only be
> modified by the
> +   platform manufacturer.
> +  **/
> +  VOID                   *PegDataPtr;
> +  /**
> +  Offset 116:
> +  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535,
> default is 1.
> +  @warning Do not change from the default.  Hard to detect issues are likely.
> +  **/
> +  UINT16                 Gen3SwEqJitterErrorTarget;
> +
> +  /**
> +  Offset 118:
> +  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535,
> default is 10000.
> +  @warning Do not change from the default.  Hard to detect issues are likely.
> +  @note An attack on this policy could result in an apparent hang,
> +    but the system will eventually boot.  This variable should be protected.
> +  **/
> +  UINT16                 Gen3SwEqVocDwellTime;
> +
> +  /**
> +  Offset 120:
> +  <b>(Test)</b>Used for PCIe Gen3 Software Equalization. Range: 0-65535,
> default is 2.
> +  @warning Do not change from the default.  Hard to detect issues are likely.
> +  **/
> +  UINT16                 Gen3SwEqVocErrorTarget;
> +  /**
> +  Offset 122:
> +    PCIe Hot Plug Enable/Disable. It has 2 policies.
> +  - Disabled (0x0)     : No hotplug.
> +  - Enabled (0x1)      : Bios assist hotplug.
> +  **/
> +  UINT8                  PegRootPortHPE[SA_PEG_MAX_FUN];
> +  UINT8                  DmiDeEmphasis;                               ///< Offset 125
> This field is used to describe the DeEmphasis control for DMI (-6 dB and -3.5 dB
> are the options)
> +  UINT8                  Rsvd0[2];                                    ///< Offset 126
> +  /**
> +   Offset 128:
> +   This contains the PCIe PERST# GPIO information.  This structure is required
> +   for PCIe Gen3 operation. The reference code will use the information in this
> structure in
> +   order to reset PCIe Gen3 devices during equalization, if necessary.  Refer to
> the Platform
> +   Developer's Guide (PDG) for additional details.
> +  **/
> +  PEG_GPIO_DATA          PegGpioData;
> +
> +   /**
> +   Offset 156
> +   <b>(Test)</b> PCIe Override RxCTLE. This feature should only be true to
> disable RxCTLE adaptive behavior for compliance testing
> +  - <b>False</b>          (0x0) : Normal Operation                 - RxCTLE
> adaptive behavior enabled  (Default)
> +  - True                  (0x1) : Override RxCTLE                  - Disable RxCTLE
> adaptive behavior to keep the configured RxCTLE peak values unmodified
> +  From CFL onwards, modularity is introduced to this setup option so that the
> RxCTLE adaptive behavior could be controlled at the controller level.
> +  Making this variable a UINT8 to accomodate the values of all controllers as
> bit definition
> +  **/
> +  UINT8                 PegGen3RxCtleOverride;
> +  UINT8                 Reserved1;
> +  UINT16                Reserved2;
> +
> +} PCIE_PEI_PREMEM_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _PCIE_PEI_PREMEM_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMi
> scPeiConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMi
> scPeiConfig.h
> new file mode 100644
> index 0000000000..12648b836b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMi
> scPeiConfig.h
> @@ -0,0 +1,61 @@
> +/** @file
> +  Policy details for miscellaneous configuration in System Agent
> +
> +  Copyright (c) 2019 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)
> +
> +#ifndef SA_MC_MAX_SOCKETS
> +#define SA_MC_MAX_SOCKETS 4
> +#endif
> +
> +#define SA_MISC_PEI_CONFIG_REVISION 1
> +
> +///
> +/// Subsystem Vendor ID / Subsystem ID
> +///
> +typedef struct _SA_DEFAULT_SVID_SID{
> +  UINT16         SubSystemVendorId;
> +  UINT16         SubSystemId;
> +} SA_DEFAULT_SVID_SID;
> +
> +/**
> +  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
> +  /**
> +  Offset 28:0
> +  This policy is used to control enable or disable System Agent Thermal device
> (0,4,0).
> +  The default value is <b>1: TRUE</b> for WHL, and <b>0: FALSE</b> for all
> other CPU's
> +  **/
> +  UINT32  Device4Enable:1;
> +  /**
> +  Offset 28:1
> +  <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.
> +  **/
> +  UINT32  ChapDeviceEnable:1;
> +  /**
> +  Offset 28:2
> +  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  CridEnable:1;
> +  UINT32  SkipPamLock:1;                     ///< Offset 28:3 :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.
> +  UINT32  EdramTestMode:2;                   ///< Offset 28:4 :EDRAM Test
> Mode. For EDRAM stepping - 0- EDRAM SW Disable, 1- EDRAM SW Enable, <b>
> 2- EDRAM HW Mode</b>
> +  UINT32  RsvdBits0          :26;            ///< Offset 28:7 :Reserved for future
> use
> +} SA_MISC_PEI_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _SA_MISC_PEI_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMi
> scPeiPreMemConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMi
> scPeiPreMemConfig.h
> new file mode 100644
> index 0000000000..2c831404ef
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMi
> scPeiPreMemConfig.h
> @@ -0,0 +1,103 @@
> +/** @file
> +  Policy details for miscellaneous configuration in System Agent
> +
> +  Copyright (c) 2019 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 SA_MC_MAX_SOCKETS
> +#define SA_MC_MAX_SOCKETS 4
> +#endif
> +
> +#define SA_MISC_PEI_PREMEM_CONFIG_REVISION 3
> +
> +/**
> +  This configuration block is to configure SA Miscellaneous variables during
> PEI Pre-Mem phase like programming
> +  different System Agent BARs, TsegSize, IedSize, MmioSize required etc.
> +  <b>Revision 1</b>:
> +  - Initial version.
> +  <b>Revision 2</b>:
> +  - add BdatTestType, default is RMT
> +  <b>Revision 3</b>:
> +  - Remove SgSubSystemId.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block
> Header
> +  UINT8   SpdAddressTable[SA_MC_MAX_SOCKETS];///< Offset 28 Memory
> DIMMs' SPD address for reading SPD data. <b>example:
> SpdAddressTable[0]=0xA2(C0D0), SpdAddressTable[1]=0xA0(C0D1),
> SpdAddressTable[2]=0xA2(C1D0), SpdAddressTable[3]=0xA0(C1D1)</b>
> +  VOID    *S3DataPtr;                        ///< Offset 32 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  MchBar;                            ///< Offset 36 Address of System
> Agent MCHBAR: <b>0xFED10000</b>
> +  UINT32  DmiBar;                            ///< Offset 40 Address of System
> Agent DMIBAR: <b>0xFED18000</b>
> +  UINT32  EpBar;                             ///< Offset 44 Address of System Agent
> EPBAR: <b>0xFED19000</b>
> +  UINT32  SmbusBar;                          ///< Offset 48 Address of System
> Agent SMBUS BAR: <b>0xEFA0</b>
> +  UINT32  GdxcBar;                           ///< Offset 52 Address of System
> Agent GDXCBAR: <b>0xFED84000</b>
> +  /**
> +    Offset 56 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;
> +  UINT32  EdramBar;                          ///< Offset 60 Address of System
> Agent EDRAMBAR: <b>0xFED80000</b>
> +  /**
> +    Offset 64
> +    <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>
> +  **/
> +  UINT32  IedSize;
> +  UINT8   UserBd;                            ///< Offset 68 <b>0=Mobile/Mobile
> Halo</b>, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile Halo, 7=UP Server
> +  UINT8   SgMode;                            ///< Offset 69 SgMode:
> <b>0=Disabled</b>, 1=SG Muxed, 2=SG Muxless, 3=PEG
> +  UINT16  SgDelayAfterPwrEn;                 ///< Offset 70 Dgpu Delay after
> Power enable using Setup option: 0=Minimal, 1000=Maximum, <b>300=300
> microseconds</b>
> +  UINT16  SgDelayAfterHoldReset;             ///< Offset 72 Dgpu Delay after
> Hold Reset using Setup option: 0=Minimal, 1000=Maximum, <b>100=100
> microseconds</b>
> +  UINT32  SkipExtGfxScan:1;                  ///< <b>(Test)</b> OFfset
> 74: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 74:1 :This field enables
> the generation of the BIOS DATA ACPI Tables: <b>0=FALSE</b>, 1=TRUE.
> +  UINT32  TxtImplemented:1;                  ///< OFfset 74: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 74: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.  If the primary graphics
> device only implements legacy VBIOS, then the
> +   LegacyOnlyVgaOpRomDetected field in the SA_DATA_HOB will be set to 1.
> +
> +   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 74:4 :Reserved for future
> use
> +  UINT8   LockPTMregs;                       ///< <b>(Test)</b> Offset 78 Lock
> PCU Thermal Management registers: 0=FALSE, <b>1=TRUE</b>
> +  UINT8   BdatTestType;                      ///< Offset 79 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   Rsvd1[4];                          ///< Offset 80 Reserved for future use
> +  /**
> +    Offset 84 :
> +    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.
> +  **/
> +  UINT16  MmioSize;
> +  INT16   MmioSizeAdjustment;                ///< Offset 86 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>
> +  UINT64  AcpiReservedMemoryBase;            ///< Offset 88 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 96 Total system
> memory length from previous boot, this is required for S3 resume. Originally it
> is retrieved from AcpiVariableCompatibility variable.
> +  UINT32  AcpiReservedMemorySize;            ///< Offset 104 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
> 108 Temporary address to MMIO map OpROMs during VGA scanning.  Used for
> ScanExtGfxForLegacyOpRom feature.  MUST BE 16MB ALIGNED!
> +  UINT32  OpRomScanTempMmioLimit;            ///< <b>(Test)</b> Offset
> 112 Limit address for OpROM MMIO range.  Used for
> ScanExtGfxForLegacyOpRom feature. (OpROMScanTempMmioLimit -
> OpRomScanTempMmioBar) MUST BE >= 16MB!
> +
> +  // 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/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Switc
> hableGraphicsConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Switc
> hableGraphicsConfig.h
> new file mode 100644
> index 0000000000..cc6179a61c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Switc
> hableGraphicsConfig.h
> @@ -0,0 +1,63 @@
> +/** @file
> +  Switchable Graphics policy definitions
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SWITCHABLE_GRAPHICS_CONFIG_H_
> +#define _SWITCHABLE_GRAPHICS_CONFIG_H_
> +
> +#define SWITCHABLE_GRAPHICS_CONFIG_REVISION 1
> +
> +#define GP_ENABLE   1
> +#define GP_DISABLE  0
> +
> +#pragma pack(push, 1)
> +///
> +/// GPIO Support
> +///
> +typedef enum {
> +  NotSupported = 0,
> +  PchGpio,
> +  I2CGpio,
> +} GPIO_SUPPORT;
> +
> +///
> +/// SA 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
> +} SA_GPIO_INFO;
> +
> +/**
> + SA PCIE RTD3 GPIO Data Structure
> +**/
> +typedef struct {
> +  SA_GPIO_INFO  HoldRst;      ///< Offset 0 This field contain PCIe HLD RESET
> GPIO value and level information
> +  SA_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
> +} SA_PCIE_RTD3_GPIO;
> +
> +/**
> +  This Configuration block configures SA PCI Express 0/1/2 RTD3 GPIOs & Root
> Port.
> +  Swithable Gfx/Hybrid Gfx uses the same GPIOs & Root port as PCI Express
> 0/1/2 RTD3.
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER Header;             ///< Offset 0-27 Config Block
> Header
> +  SA_PCIE_RTD3_GPIO   SaRtd3Pcie0Gpio;    ///< Offset 28 RTD3 GPIOs used
> for PCIe0
> +  SA_PCIE_RTD3_GPIO   SaRtd3Pcie1Gpio;    ///< Offset 52 RTD3 GPIOs used
> for PCIe1
> +  SA_PCIE_RTD3_GPIO   SaRtd3Pcie2Gpio;    ///< Offset 76 RTD3 GPIOs used
> for PCIe2
> +  UINT8               RootPortIndex;      ///< Offset 124 Root Port Index
> number used for SG
> +  UINT8               Rsvd0[3];           ///< Offset 125 Reserved for DWORD
> Alignment
> +} SWITCHABLE_GRAPHICS_CONFIG;
> +#pragma pack(pop)
> +#endif // _SWITCHABLE_GRAPHICS_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Vbios
> DxeConfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Vbios
> DxeConfig.h
> new file mode 100644
> index 0000000000..690ad8630a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/Vbios
> DxeConfig.h
> @@ -0,0 +1,39 @@
> +/** @file
> +  VBIOS DXE policy definitions
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _VBIOS_DXE_CONFIG_H_
> +#define _VBIOS_DXE_CONFIG_H_
> +
> +#pragma pack(push, 1)
> +
> +#define VBIOS_DXE_CONFIG_REVISION 1
> +
> +/**
> +  This data structure includes Switchable Graphics VBIOS configuration.
> +  If Switchable Graphics/Hybrid Gfaphics feature is not supported, all the
> policies in this configuration block can 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
> +  UINT8                 LoadVbios    : 1;    ///< Offset 28:0 :This field is used to
> describe if the dGPU VBIOS needs to be loaded: <b>0=Not load</b>, 1=Load
> +  UINT8                 ExecuteVbios : 1;    ///< Offset 28:1 :This field is used to
> describe if the dGPU VBIOS need to be executed: <b>0=Not execute</b>,
> 1=Execute
> +/**
> +  Offset 28:2 :
> +  This field is used to identify the source location of dGPU VBIOS\n
> +  <b>1 = secondary display device VBIOS Source is PCI Card</b>\n
> +  0 = secondary display device VBIOS Source is FW Volume\n
> +**/
> +  UINT8                 VbiosSource  : 1;
> +  UINT8                 RsvdBits0    : 5;    ///< Offset 28:3 Reserved for future
> use
> +  UINT8                 Rsvd[3];             ///< Offset 29 : Reserved for DWORD
> alignment
> +} VBIOS_DXE_CONFIG;
> +#pragma pack(pop)
> +
> +#endif // _VBIOS_DXE_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdC
> onfig.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdC
> onfig.h
> new file mode 100644
> index 0000000000..adde1f836b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdC
> onfig.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  VT-d policy definitions.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _VTD_CONFIG_H_
> +#define _VTD_CONFIG_H_
> +
> +#pragma pack(push, 1)
> +
> +#define VTD_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.
> +  <b>Revision 2</b>:
> +  - Add DMA_CONTROL_GUARANTEE bit in the DMAR table
> +**/
> +typedef struct {
> +  CONFIG_BLOCK_HEADER  Header;                      ///< Offset 0-27 Config
> Block Header
> +  /**
> +    Offset 28:0 :
> +    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.
> +  **/
> +  UINT32        VtdDisable               : 1;
> +  UINT32        X2ApicOptOut             : 1;       ///< Offset 28:1 :This field is
> used to enable the X2APIC_OPT_OUT bit in the DMAR table. 1=Enable/Set and
> <b>0=Disable/Clear</b>
> +  UINT32        DmaControlGuarantee      : 1;       ///< Offset 28:2 :This field
> is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table.
> 1=Enable/Set and <b>0=Disable/Clear</b>
> +  UINT32        RsvdBits0                : 29;      ///< Offset 28:3 :Reserved bits
> for future use
> +  UINT32        BaseAddress[SA_VTD_ENGINE_NUMBER];  ///< Offset 32: This
> field is used to describe the base addresses for VT-d function:
> <b>BaseAddress[0]=0xFED90000, BaseAddress[1]=0xFED92000,
> BaseAddress[2]=0xFED91000 </b>
> +} VTD_CONFIG;
> +#pragma pack(pop)
> +
> +#endif   //  _VTD_CONFIG_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTa
> ble.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTa
> ble.h
> new file mode 100644
> index 0000000000..a1d88cb5a2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTa
> ble.h
> @@ -0,0 +1,77 @@
> +/** @file
> +  This code defines ACPI DMA Remapping table related definitions.
> +  See the System Agent BIOS specification for definition of the table.
> +
> +  Copyright (c) 2019 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>
> +
> +#pragma pack(1)
> +///
> +/// DMAR table signature
> +///
> +#define EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE   0x52414D44  ///<
> "DMAR"
> +#define EFI_ACPI_DMAR_TABLE_REVISION        1
> +#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];    // CSME
> +} EFI_ACPI_RMRR_CSME_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_USB_STRUC       RmrrUsb;
> +  EFI_ACPI_RMRR_IGD_STRUC       RmrrIgd;
> +  EFI_ACPI_RMRR_CSME_STRUC      RmrrCsme;
> +} EFI_ACPI_DMAR_TABLE;
> +
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPoli
> cyLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPoli
> cyLib.h
> new file mode 100644
> index 0000000000..663b0f2202
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPoli
> cyLib.h
> @@ -0,0 +1,60 @@
> +/** @file
> +  Prototype of the DxeSaPolicyLib library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_SA_POLICY_LIB_H_
> +#define _DXE_SA_POLICY_LIB_H_
> +
> +#include <Protocol/SaPolicy.h>
> +
> +/**
> +  This function prints the DXE phase policy.
> +
> +  @param[in] SaPolicy    - SA DXE Policy protocol
> +**/
> +VOID
> +SaPrintPolicyProtocol (
> +  IN  SA_POLICY_PROTOCOL         *SaPolicy
> +  )
> +;
> +
> +/**
> +  CreateSaDxeConfigBlocks generates the config blocksg 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 Policy 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
> +);
> +
> +/**
> +  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
> +  )
> +;
> +
> +#endif // _DXE_SA_POLICY_LIB_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolic
> yLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolic
> yLib.h
> new file mode 100644
> index 0000000000..c29d67a305
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolic
> yLib.h
> @@ -0,0 +1,87 @@
> +/** @file
> +  Prototype of the PeiSaPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SA_POLICY_LIB_H_
> +#define _PEI_SA_POLICY_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +#include <Library/ConfigBlockLib.h>
> +
> +/**
> +  This function prints the PEI phase PreMem policy.
> +
> +  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI
> instance
> +**/
> +VOID
> +EFIAPI
> +SaPrintPolicyPpiPreMem (
> +  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
> +  );
> +
> +/**
> +  This function prints the PEI phase policy.
> +
> +  @param[in] SiPolicyPpi              The RC Policy PPI instance
> +**/
> +VOID
> +EFIAPI
> +SaPrintPolicyPpi (
> +  IN  SI_POLICY_PPI     *SiPolicyPpi
> +  );
> +
> +/**
> +  Get SA config block table total size.
> +
> +  @retval     Size of SA config block table
> +**/
> +UINT16
> +EFIAPI
> +SaGetConfigBlockTotalSize (
> +  VOID
> +  );
> +
> +/**
> +  Get SA config block table total size.
> +
> +  @retval      Size of SA config block table
> +**/
> +UINT16
> +EFIAPI
> +SaGetConfigBlockTotalSizePreMem (
> +  VOID
> +  );
> +
> +/**
> +  SaAddConfigBlocksPreMem add all SA config blocks.
> +
> +  @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
> +SaAddConfigBlocksPreMem (
> +  IN VOID           *ConfigBlockTableAddress
> +  );
> +
> +/**
> +  SaAddConfigBlocks add all SA config blocks.
> +
> +  @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
> +SaAddConfigBlocks (
> +  IN VOID           *ConfigBlockTableAddress
> +  );
> +
> +#endif // _PEI_SA_POLICY_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatfor
> mLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatfor
> mLib.h
> new file mode 100644
> index 0000000000..a1289abe81
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatfor
> mLib.h
> @@ -0,0 +1,88 @@
> +/** @file
> +  Header file for SaPlatformLib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_PLATFORM_LIB_H_
> +#define _SA_PLATFORM_LIB_H_
> +
> +#include <SaAccess.h>
> +#include <CpuAccess.h>
> +
> +/**
> +  Determine if PCH Link is DMI/OPI
> +
> +  @param[in] CpuModel             CPU model
> +
> +  @retval TRUE                    DMI
> +  @retval FALSE                   OPI
> +**/
> +BOOLEAN
> +IsPchLinkDmi (
> +  IN CPU_FAMILY  CpuModel
> +  );
> +
> +/**
> +  Returns the number of DMI lanes for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxDmiLanes (
> +  );
> +
> +
> +/**
> +  Returns the number of DMI bundles for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxDmiBundles (
> +  );
> +
> +
> +/**
> +  Returns the function numbers for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxPegFuncs (
> +  );
> +
> +
> +/**
> +  Returns the number of DMI lanes for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxPegLanes (
> +  );
> +
> +
> +/**
> +  Returns the number of DMI bundles for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxPegBundles (
> +  );
> +
> +/**
> +  Checks if PEG port is present
> +
> +  @retval TRUE     PEG is presented
> +  @retval FALSE    PEG is not presented
> +**/
> +BOOLEAN
> +IsPegPresent (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
> new file mode 100644
> index 0000000000..da285bbcba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
> @@ -0,0 +1,259 @@
> +/** @file
> +  This file contains definitions required for creation of
> +  Memory S3 Save data, Memory Info data and Memory Platform
> +  data hobs.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MEM_INFO_HOB_H_
> +#define _MEM_INFO_HOB_H_
> +
> +#include <Uefi/UefiMultiPhase.h>
> +#include <Pi/PiBootMode.h>
> +#include <Pi/PiHob.h>
> +
> +#pragma pack (push, 1)
> +
> +extern EFI_GUID gSiMemoryS3DataGuid;
> +extern EFI_GUID gSiMemoryInfoDataGuid;
> +extern EFI_GUID gSiMemoryPlatformDataGuid;
> +
> +#define MAX_NODE        1
> +#define MAX_CH          2
> +#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 MrcChannelSts enum in MRC
> +//
> +#ifndef CHANNEL_NOT_PRESENT
> +#define CHANNEL_NOT_PRESENT     0  // There is no channel present on the
> controller.
> +#endif
> +#ifndef CHANNEL_DISABLED
> +#define CHANNEL_DISABLED     1  // There is a channel present but it is
> disabled.
> +#endif
> +#ifndef CHANNEL_PRESENT
> +#define CHANNEL_PRESENT     2  // There is a channel present and it is
> enabled.
> +#endif
> +
> +//
> +// 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 bmCold
> +#define bmCold 0            // Cold boot
> +#endif
> +#ifndef bmWarm
> +#define bmWarm 1            // Warm boot
> +#endif
> +#ifndef bmS3
> +#define bmS3   2            // S3 resume
> +#endif
> +#ifndef bmFast
> +#define bmFast 3            // Fast boot
> +#endif
> +
> +//
> +// 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_UNKNOWN
> +#define MRC_DDR_TYPE_UNKNOWN  3
> +#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;
> +
> +typedef struct {
> +  UINT8 SG;         ///< Number of tCK cycles between transactions in the
> same bank group.
> +  UINT8 DG;         ///< Number of tCK cycles between transactions when
> switching bank groups.
> +  UINT8 DR;         ///< Number of tCK cycles between transactions when
> switching between Ranks (in the same DIMM).
> +  UINT8 DD;         ///< Number of tCK cycles between transactions when
> switching between DIMMs.
> +} MRC_TA_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.
> +} 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.
> +  MRC_TA_TIMING    tRd2Rd;                  ///< Read-to-Read   Turn Around
> Timings
> +  MRC_TA_TIMING    tRd2Wr;                  ///< Read-to-Write  Turn Around
> Timings
> +  MRC_TA_TIMING    tWr2Rd;                  ///< Write-to-Read  Turn Around
> Timings
> +  MRC_TA_TIMING    tWr2Wr;                  ///< Write-to-Write Turn Around
> Timings
> +} 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.
> +  MRC_TA_TIMING    tRd2Rd;                   ///< Deprecated and moved to
> CHANNEL_INFO. Read-to-Read   Turn Around Timings
> +  MRC_TA_TIMING    tRd2Wr;                   ///< Deprecated and moved to
> CHANNEL_INFO. Read-to-Write  Turn Around Timings
> +  MRC_TA_TIMING    tWr2Rd;                   ///< Deprecated and moved to
> CHANNEL_INFO. Write-to-Read  Turn Around Timings
> +  MRC_TA_TIMING    tWr2Wr;                   ///< Deprecated and moved to
> CHANNEL_INFO. Write-to-Write Turn Around Timings
> +} CONTROLLER_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;
> +  UINT32            PrmrrBase;
> +  UINT32            GttBase;
> +  UINT32            MmioSize;
> +  UINT32            PciEBaseAddress;
> +  UINT32            GdxcIotBase;
> +  UINT32            GdxcIotSize;
> +  UINT32            GdxcMotBase;
> +  UINT32            GdxcMotSize;
> +} 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/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Gr
> aphicsInitLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Gr
> aphicsInitLib.h
> new file mode 100644
> index 0000000000..ff7cfa838f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Gr
> aphicsInitLib.h
> @@ -0,0 +1,15 @@
> +/** @file
> +  Graphics header file
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_INIT_H_
> +#define _GRAPHICS_INIT_H_
> +
> +#include <SaPolicyCommon.h>
> +#include <Ppi/SiPolicy.h>
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Le
> gacyRegion.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Le
> gacyRegion.h
> new file mode 100644
> index 0000000000..497c860824
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Le
> gacyRegion.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  This code supports a private implementation of the Legacy Region protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _LEGACY_REGION_H_
> +#define _LEGACY_REGION_H_
> +
> +#include <Uefi.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Protocol/LegacyRegion2.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/Cpu.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <SaAccess.h>
> +
> +/**
> +  Install Driver to produce Legacy Region protocol.
> +
> +  @param[in] ImageHandle             Handle for the image of this driver
> +
> +  @retval EFI_SUCCESS - Legacy Region protocol installed
> +  @retval Other       - No protocol installed, unload driver.
> +**/
> +EFI_STATUS
> +LegacyRegionInstall (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Pe
> iCpuTraceHubLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Pe
> iCpuTraceHubLib.h
> new file mode 100644
> index 0000000000..8bf46528ab
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Pe
> iCpuTraceHubLib.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  Header file for North TraceHub Lib.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _NORTH_TRACEHUB_LIB_H_
> +#define _NORTH_TRACEHUB_LIB_H_
> +
> +#include <SaPolicyCommon.h>
> +#include <SaAccess.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/MtrrLib.h>
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Sa
> PcieLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Sa
> PcieLib.h
> new file mode 100644
> index 0000000000..19dd634a35
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/Sa
> PcieLib.h
> @@ -0,0 +1,70 @@
> +/** @file
> +  Defines and prototypes for the System Agent PCIe library module
> +  This library is expected to share between DXE and SMM drivers.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_PCIE_LIB_H_
> +#define _SA_PCIE_LIB_H_
> +
> +#include <Library/S3BootScriptLib.h>
> +#include <Protocol/SaPolicy.h>
> +
> +#define MAX_SUPPORTED_ROOT_BRIDGE_NUMBER  3
> +#define MAX_SUPPORTED_DEVICE_NUMBER       192
> +
> +/**
> +  Enumerate all end point devices connected to root bridge ports and record
> their MMIO base address
> +
> +  @exception EFI_UNSUPPORTED      PCIe capability structure not found
> +  @retval    EFI_SUCCESS          All done successfully
> +**/
> +EFI_STATUS
> +EnumerateAllPcieDevices (
> +  VOID
> +  );
> +
> +/**
> +  Sets Common Clock, TCx-VC0 mapping, and Max Payload for PCIe
> +**/
> +VOID
> +SaPcieConfigBeforeOpRom (
> +  VOID
> +  );
> +
> +/**
> +  This function does all SA ASPM initialization
> +**/
> +VOID
> +SaAspm (
> +  VOID
> +  );
> +
> +/**
> +  This function checks PEG end point device for extended tag capability and
> enables them if they are.
> +**/
> +VOID
> +EnableExtendedTag (
> +  VOID
> +  );
> +
> +/**
> +  This function handles SA S3 resume
> +**/
> +VOID
> +SaS3Resume (
> +  VOID
> +  );
> +
> +/**
> +  Wrapper function for all SA S3 resume tasks which can be a callback
> function.
> +**/
> +VOID
> +SaS3ResumeCallback (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/
> SaIotrapSmi.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/
> SaIotrapSmi.h
> new file mode 100644
> index 0000000000..2c765b09b8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/
> SaIotrapSmi.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SA Iotrap SMI Protocol to provide the
> +  I/O address for registered Iotrap SMI.
> +
> +  Copyright (c) 2019 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;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/
> SaNvsArea.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/
> SaNvsArea.h
> new file mode 100644
> index 0000000000..1bae2d95e5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/
> SaNvsArea.h
> @@ -0,0 +1,31 @@
> +/** @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) 2019 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 <Private/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/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigH
> ob.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigH
> ob.h
> new file mode 100644
> index 0000000000..f1b72488ca
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigH
> ob.h
> @@ -0,0 +1,89 @@
> +/** @file
> +  The GUID definition for SaConfigHob
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_CONFIG_HOB_H_
> +#define _SA_CONFIG_HOB_H_
> +
> +#include <SaAccess.h>
> +#include <Base.h>
> +
> +extern EFI_GUID gSaConfigHobGuid;
> +
> +#pragma pack (push,1)
> +///
> +#define DPR_DIRECTORY_MAX               2         ///< 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;
> +
> +///
> +/// The data elements should be initialized by a Platform Module.
> +/// The data structure is for VT-d driver initialization
> +///
> +typedef struct {
> +  BOOLEAN               VtdDisable;                        ///< 1 = Avoids
> programming Vtd bars, Vtd overrides and DMAR table
> +  UINT32                BaseAddress[SA_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               InterruptRemappingSupport;         ///< This field is
> used to indicate Interrupt Remapping supported or not
> +} SA_VTD_CONFIGURATION_HOB;
> +
> +///
> +/// SA GPIO Data Structure
> +///
> +typedef struct {
> +  UINT8   ExpanderNo; ///< =Expander No For I2C based GPIO
> +  UINT32  GpioNo;     ///< GPIO pad
> +  BOOLEAN Active;     ///< 0=Active Low; 1=Active High
> +} SA_GPIO;
> +
> +///
> +/// SA PCIE RTD3 GPIO Data Structure
> +///
> +typedef struct {
> +  UINT8              GpioSupport;      ///< 0=Not Supported; 1=PCH based;
> 2=I2C Based
> +  SA_GPIO            HoldRst;          ///< Offset 8 This field contain PCIe HLD
> RESET GPIO value and level information
> +  SA_GPIO            PwrEnable;        ///< This field contain PCIe PWR Enable
> GPIO value and level information
> +  UINT32             WakeGpioNo;       ///< This field contain PCIe RTD3 Device
> Wake GPIO number
> +} PCIE_RTD3_GPIO;
> +
> +///
> +/// SG Info HOB
> +///
> +typedef struct {
> +  SG_MODE           SgMode;
> +  UINT8             RootPortIndex;
> +  PCIE_RTD3_GPIO    Rtd3Pcie0Gpio;
> +  PCIE_RTD3_GPIO    Rtd3Pcie1Gpio;
> +  PCIE_RTD3_GPIO    Rtd3Pcie2Gpio;
> +  UINT16            DelayAfterPwrEn;
> +  UINT16            DelayAfterHoldReset;
> +} SA_RTD3;
> +
> +///
> +/// 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
> +  BOOLEAN                  InitPcieAspmAfterOprom;                   ///<
> 1=initialize PCIe ASPM after Oprom; 0=before (This will be set basing on policy)
> +  SA_RTD3                  SaRtd3;                                   ///< SG Info HOB
> +  UINT8                    ApertureSize;                             ///< Aperture size
> value
> +  UINT8                    IpuAcpiMode;                              ///< IPU ACPI
> mode: 0=Disabled, 1=IGFX Child device, 2=ACPI device
> +  SA_VTD_CONFIGURATION_HOB VtdData;                                  ///< VT-d
> Data HOB
> +  BOOLEAN                  CridEnable;                               ///< This field
> inidicates if CRID is enabled or disabled (to support Intel(R) SIPP)
> +  BOOLEAN                  SkipPamLock;                              ///< 0=All PAM
> registers will be locked in System Agent code, 1=Do not lock PAM registers in
> System Agent code.
> +  UINT8                    PowerDownUnusedBundles[SA_PEG_MAX_FUN];
> ///< PCIe power down unused bundles support
> +  UINT8                    PegMaxPayload[SA_PEG_MAX_FUN];            ///< PEG
> Max Pay Load Size (0xFF: Auto, 0:128B, 1:256B)
> +} SA_CONFIG_HOB;
> +#pragma pack (pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAre
> aDef.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAre
> aDef.h
> new file mode 100644
> index 0000000000..095942d483
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAre
> aDef.h
> @@ -0,0 +1,151 @@
> +/** @file
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  //
> +  // Define SA NVS Area operatino 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    SgMode;                                  ///< Offset 136     SG Mode
> (0=Disabled, 1=SG Muxed, 2=SG Muxless, 3=DGPU Only)
> +  UINT8    SgFeatureList;                           ///< Offset 137     SG 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
> +  UINT16   DelayAfterPwrEn;                         ///< Offset 177     Delay after
> power enable for PCIe
> +  UINT16   DelayAfterHoldReset;                     ///< Offset 179     Delay
> after Hold Reset for PCIe
> +  UINT8    Pcie0EpCapOffset;                        ///< Offset 181     PCIe0
> Endpoint Capability Structure Offset
> +  UINT32   XPcieCfgBaseAddress;                     ///< Offset 182     Any
> Device's PCIe Config Space Base Address
> +  UINT16   GpioBaseAddress;                         ///< Offset 186     GPIO Base
> Address
> +  UINT32   NvIgOpRegionAddress;                     ///< Offset 188     NVIG
> opregion address
> +  UINT32   NvHmOpRegionAddress;                     ///< Offset 192     NVHM
> opregion address
> +  UINT32   ApXmOpRegionAddress;                     ///< Offset 196     AMDA
> opregion address
> +  UINT8    Peg0LtrEnable;                           ///< Offset 200     Latency
> Tolerance Reporting Enable
> +  UINT8    Peg0ObffEnable;                          ///< Offset 201     Optimized
> Buffer Flush and Fill
> +  UINT8    Peg1LtrEnable;                           ///< Offset 202     Latency
> Tolerance Reporting Enable
> +  UINT8    Peg1ObffEnable;                          ///< Offset 203     Optimized
> Buffer Flush and Fill
> +  UINT8    Peg2LtrEnable;                           ///< Offset 204     Latency
> Tolerance Reporting Enable
> +  UINT8    Peg2ObffEnable;                          ///< Offset 205     Optimized
> Buffer Flush and Fill
> +  UINT8    Peg3LtrEnable;                           ///< Offset 206     Latency
> Tolerance Reporting Enable
> +  UINT8    Peg3ObffEnable;                          ///< Offset 207     Optimized
> Buffer Flush and Fill
> +  UINT16   PegLtrMaxSnoopLatency;                   ///< Offset 208     SA Peg
> Latency Tolerance Reporting Max Snoop Latency
> +  UINT16   PegLtrMaxNoSnoopLatency;                 ///< Offset 210     SA Peg
> Latency Tolerance Reporting Max No Snoop Latency
> +  UINT8    Peg0PowerDownUnusedBundles;              ///< Offset 212
> Peg0 Unused Bundle Control
> +  UINT8    Peg1PowerDownUnusedBundles;              ///< Offset 213
> Peg1 Unused Bundle Control
> +  UINT8    Peg2PowerDownUnusedBundles;              ///< Offset 214
> Peg2 Unused Bundle Control
> +  UINT8    Peg3PowerDownUnusedBundles;              ///< Offset 215
> Peg3 Unused Bundle Control
> +  UINT8    PackageCstateLimit;                      ///< Offset 216     The lowest
> C-state for the package
> +  UINT8    PwrDnBundlesGlobalEnable;                ///< Offset 217     Pegx
> Unused Bundle Control Global Enable (0=Disabled, 1=Enabled)
> +  UINT64   Mmio64Base;                              ///< Offset 218     Base of
> above 4GB MMIO resource
> +  UINT64   Mmio64Length;                            ///< Offset 226     Length of
> above 4GB MMIO resource
> +  UINT32   CpuIdInfo;                               ///< Offset 234     CPU ID info to
> get Family Id or Stepping
> +  UINT8    Pcie1EpCapOffset;                        ///< Offset 238     PCIe1
> Endpoint Capability Structure Offset
> +  UINT8    Pcie2EpCapOffset;                        ///< Offset 239     PCIe2
> Endpoint Capability Structure Offset
> +  UINT8    Pcie0SecBusNum;                          ///< Offset 240     PCIe0
> Secondary Bus Number (PCIe0 Endpoint Bus Number)
> +  UINT8    Pcie1SecBusNum;                          ///< Offset 241     PCIe1
> Secondary Bus Number (PCIe0 Endpoint Bus Number)
> +  UINT8    Pcie2SecBusNum;                          ///< Offset 242     PCIe2
> Secondary Bus Number (PCIe0 Endpoint Bus Number)
> +  UINT32   Mmio32Base;                              ///< Offset 243     Base of
> below 4GB MMIO resource
> +  UINT32   Mmio32Length;                            ///< Offset 247     Length of
> below 4GB MMIO resource
> +  UINT32   Pcie0WakeGpioNo;                         ///< Offset 251     PCIe0
> RTD3 Device Wake GPIO Number
> +  UINT32   Pcie1WakeGpioNo;                         ///< Offset 255     PCIe1
> RTD3 Device Wake GPIO Number
> +  UINT32   Pcie2WakeGpioNo;                         ///< Offset 259     PCIe2
> RTD3 Device Wake GPIO Number
> +  UINT8    VtdDisable;                              ///< Offset 263     VT-d
> Enable/Disable
> +  UINT32   VtdBaseAddress1;                         ///< Offset 264     VT-d Base
> Address 1
> +  UINT32   VtdBaseAddress2;                         ///< Offset 268     VT-d Base
> Address 2
> +  UINT32   VtdBaseAddress3;                         ///< Offset 272     VT-d Base
> Address 3
> +  UINT16   VtdEngine1Vid;                           ///< Offset 276     VT-d
> Engine#1 Vendor ID
> +  UINT16   VtdEngine2Vid;                           ///< Offset 278     VT-d
> Engine#2 Vendor ID
> +  UINT8    Pcie3SecBusNum;                          ///< Offset 280     PCIe3
> Secondary Bus Number (PCIe3 Endpoint Bus Number)
> +  UINT8    Pcie3GpioSupport;                        ///< Offset 281     PCIe3 GPIO
> Support (0=Disabled, 1=PCH Based, 2=I2C Based)
> +  UINT8    Pcie3HoldRstExpanderNo;                  ///< Offset 282     PCIe3
> HLD RST IO Expander Number
> +  UINT32   Pcie3HoldRstGpioNo;                      ///< Offset 283     PCIe3
> HLD RST GPIO Number
> +  UINT8    Pcie3HoldRstActiveInfo;                  ///< Offset 287     PCIe3 HLD
> RST GPIO Active Information
> +  UINT8    Pcie3PwrEnExpanderNo;                    ///< Offset 288     PCIe3
> PWR Enable IO Expander Number
> +  UINT32   Pcie3PwrEnGpioNo;                        ///< Offset 289     PCIe3
> PWR Enable GPIO Number
> +  UINT8    Pcie3PwrEnActiveInfo;                    ///< Offset 293     PCIe3 PWR
> Enable GPIO Active Information
> +  UINT32   Pcie3WakeGpioNo;                         ///< Offset 294     PCIe3
> RTD3 Device Wake GPIO Number
> +  UINT8    Pcie3EpCapOffset;                        ///< Offset 298     PCIe3
> Endpoint Capability Structure Offset
> +  UINT8    RootPortIndex;                           ///< Offset 299     RootPort
> Number
> +  UINT32   RootPortAddress;                         ///< Offset 300
> RootPortAddress
> +  UINT8    Reserved0[196];                          ///< Offset 304:499
> +} SYSTEM_AGENT_NVS_AREA;
> +
> +#pragma pack(pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopCom
> ponentName2.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopCom
> ponentName2.h
> new file mode 100644
> index 0000000000..a9db25404f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopCom
> ponentName2.h
> @@ -0,0 +1,63 @@
> +/** @file
> +  Protocol to retrieve the GOP driver version
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolic
> y.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPoli
> cy.h
> new file mode 100644
> index 0000000000..866f60b9c2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPoli
> cy.h
> @@ -0,0 +1,73 @@
> +/** @file
> +  Interface definition for GopPolicy Protocol.
> +
> +  Copyright (c) 2019 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 gIntelGraphicsVbtGuid;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRe
> gion.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRe
> gion.h
> new file mode 100644
> index 0000000000..ef2edfe122
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRe
> gion.h
> @@ -0,0 +1,24 @@
> +/** @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) 2019 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/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInf
> o.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInf
> o.h
> new file mode 100644
> index 0000000000..031e55b9b4
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInf
> o.h
> @@ -0,0 +1,132 @@
> +/** @file
> +  This protocol provides the memory information data, such as
> +  total physical memory size, memory frequency, memory size
> +  of each dimm and rank.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MEM_INFO_PROTOCOL_H_
> +#define _MEM_INFO_PROTOCOL_H_
> +
> +
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gMemInfoProtocolGuid;
> +
> +//
> +// Protocol definitions
> +//
> +#define NODE_NUM  1
> +#define CH_NUM    2
> +#define DIMM_NUM  2
> +#define RANK_NUM  2
> +#define SLOT_NUM  (CH_NUM * DIMM_NUM)
> +#define PROFILE_NUM 4 // number of memory profiles supported
> +#define XMP_PROFILE_NUM 2 // number of XMP profiles supported
> +
> +//
> +// 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_UNKNOWN
> +#define MRC_DDR_TYPE_UNKNOWN  3
> +#endif
> +
> +//
> +// 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
> +
> +#pragma pack(1)
> +///
> +/// Memory timing Structure
> +///
> +typedef struct {
> +  UINT32 tCK;     ///< Offset 0 Memory cycle time, in femtoseconds.
> +  UINT16 NMode;   ///< Offset 4 Number of tCK cycles for the channel DIMM's
> command rate mode.
> +  UINT16 tCL;     ///< Offset 6 Number of tCK cycles for the channel DIMM's
> CAS latency.
> +  UINT16 tCWL;    ///< Offset 8 Number of tCK cycles for the channel DIMM's
> minimum CAS write latency time.
> +  UINT16 tFAW;    ///< Offset 10 Number of tCK cycles for the channel DIMM's
> minimum four activate window delay time.
> +  UINT16 tRAS;    ///< Offset 12 Number of tCK cycles for the channel DIMM's
> minimum active to precharge delay time.
> +  UINT16 tRCDtRP; ///< Offset 14 Number of tCK cycles for the channel DIMM's
> minimum RAS# to CAS# delay time and Row Precharge delay time
> +  UINT16 tREFI;   ///< Offset 16 Number of tCK cycles for the channel DIMM's
> minimum Average Periodic Refresh Interval.
> +  UINT16 tRFC;    ///< Offset 18 Number of tCK cycles for the channel DIMM's
> minimum refresh recovery delay time.
> +  UINT16 tRPab;   ///< Offset 20 Number of tCK cycles for the channel DIMM's
> minimum row precharge delay time for all banks.
> +  UINT16 tRRD;    ///< Offset 22 Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time.
> +  UINT16 tRTP;    ///< Offset 24 Number of tCK cycles for the channel DIMM's
> minimum internal read to precharge command delay time.
> +  UINT16 tWR;     ///< Offset 26 Number of tCK cycles for the channel DIMM's
> minimum write recovery time.
> +  UINT16 tWTR;    ///< Offset 28 Number of tCK cycles for the channel DIMM's
> minimum internal write to read command delay time.
> +  UINT16 tRRD_L;  ///< Offset 30 Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time for same bank groups.
> +  UINT16 tRRD_S;  ///< Offset 32 Number of tCK cycles for the channel DIMM's
> minimum row active to row active delay time for different bank groups.
> +  UINT16 tWTR_L;  ///< Offset 34 Number of tCK cycles for the channel
> DIMM's minimum internal write to read command delay time for same bank
> groups.
> +  UINT16 tWTR_S;  ///< Offset 36 Number of tCK cycles for the channel
> DIMM's minimum internal write to read command delay time for different
> bank groups.
> +  UINT8  Rsvd[2]; ///< Offset 38
> +} MEMORY_TIMING;
> +
> +typedef struct {
> +  UINT8 SG;       ///< Number of tCK cycles between transactions in the same
> bank group.
> +  UINT8 DG;       ///< Number of tCK cycles between transactions when
> switching bank groups.
> +  UINT8 DR;       ///< Number of tCK cycles between transactions when
> switching between Ranks (in the same DIMM).
> +  UINT8 DD;       ///< Number of tCK cycles between transactions when
> switching between DIMMs
> +} TURNAROUND_TIMING;
> +
> +// @todo use the MemInfoHob data instead of duplicate structure.
> +///
> +/// Memory information Data Structure
> +///
> +typedef struct {
> +  MEMORY_TIMING Timing[PROFILE_NUM];                   ///< Offset 0
> Timming information for the DIMM
> +  UINT32  memSize;                                     ///< Offset 128 Total physical
> memory size
> +  UINT16  ddrFreq;                                     ///< Offset 132 DDR Current
> Frequency
> +  UINT16  ddrFreqMax;                                  ///< Offset 134 DDR
> Maximum Frequency
> +  UINT16  dimmSize[NODE_NUM * CH_NUM * DIMM_NUM];      ///< Offset
> 136 Size of each DIMM
> +  UINT16  VddVoltage[PROFILE_NUM];                     ///< Offset 144 The
> voltage setting for the DIMM
> +  UINT8   DimmStatus[NODE_NUM * CH_NUM * DIMM_NUM];    ///< Offset
> 152 The enumeration value from MrcDimmSts
> +  UINT8   RankInDimm[NODE_NUM * CH_NUM * DIMM_NUM];    ///< Offset
> 156 No. of ranks in a dimm
> +  UINT8   *DimmsSpdData[NODE_NUM * CH_NUM * DIMM_NUM]; ///<
> Offset 160 SPD data of each DIMM
> +  UINT8   RefClk;                                      ///< Offset 192 Reference Clock
> +  UINT8   Ratio;                                       ///< Offset 193 Clock Multiplier
> +  BOOLEAN EccSupport;                                  ///< Offset 194 ECC
> supported or not
> +  UINT8   Profile;                                     ///< Offset 195 Currently running
> memory profile
> +  UINT8   XmpProfileEnable;                            ///< Offset 196: 0 = no XMP
> DIMMs in system
> +  UINT8   DdrType;                                     ///< Offset 197: Current DDR
> type, see DDR_TYPE_xxx defines above
> +  UINT8   Reserved[2];                                 ///< Offset 198 Reserved bytes
> for future use
> +  UINT32  DefaultXmptCK[XMP_PROFILE_NUM];              ///< Offset 200
> The Default XMP tCK values read from SPD.
> +  TURNAROUND_TIMING tRd2Rd[CH_NUM];                    ///<
> Read-to-Read   Turn Around Timings
> +  TURNAROUND_TIMING tRd2Wr[CH_NUM];                    ///<
> Read-to-Write  Turn Around Timings
> +  TURNAROUND_TIMING tWr2Rd[CH_NUM];                    ///<
> Write-to-Read  Turn Around Timings
> +  TURNAROUND_TIMING tWr2Wr[CH_NUM];                    ///<
> Write-to-Write Turn Around Timings
> +} MEMORY_INFO_DATA;
> +#pragma pack()
> +
> +///
> +/// Memory information Protocol definition
> +///
> +typedef struct {
> +  MEMORY_INFO_DATA  MemInfoData; ///< Memory Information Data
> Structure
> +} MEM_INFO_PROTOCOL;
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.
> h
> new file mode 100644
> index 0000000000..7b68f3072b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.
> h
> @@ -0,0 +1,66 @@
> +/** @file
> +  Interface definition details between System Agent and platform drivers
> during DXE phase.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_POLICY_H_
> +#define _SA_POLICY_H_
> +
> +#include <SaAccess.h>
> +#include <ConfigBlock.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <ConfigBlock/GraphicsDxeConfig.h>
> +#include <ConfigBlock/MemoryDxeConfig.h>
> +#include <ConfigBlock/MiscDxeConfig.h>
> +#include <ConfigBlock/PcieDxeConfig.h>
> +#include <ConfigBlock/VbiosDxeConfig.h>
> +
> +///
> +/// Extern the GUID for protocol users.
> +///
> +extern EFI_GUID gSaPolicyProtocolGuid;
> +extern EFI_GUID gGraphicsDxeConfigGuid;
> +extern EFI_GUID gMiscDxeConfigGuid;
> +extern EFI_GUID gPcieDxeConfigGuid;
> +extern EFI_GUID gMemoryDxeConfigGuid;
> +extern EFI_GUID gVbiosDxeConfigGuid;
> +
> +/**
> +  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 SA_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
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsG
> na.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsG
> na.h
> new file mode 100644
> index 0000000000..6f3541e3e9
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsG
> na.h
> @@ -0,0 +1,32 @@
> +/** @file
> +  Register names for GNA 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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_REGS_GNA_H_
> +#define _SA_REGS_GNA_H_
> +
> +//
> +// Device 8 Equates
> +//
> +#define SA_GNA_BUS_NUM    0x00
> +#define SA_GNA_DEV_NUM    0x08
> +#define SA_GNA_FUN_NUM    0x00
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsH
> ostBridge.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsH
> ostBridge.h
> new file mode 100644
> index 0000000000..2cc0e5be68
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsH
> ostBridge.h
> @@ -0,0 +1,214 @@
> +/** @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) 2019 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_
> +
> +//
> +// 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
> +
> +///
> +/// Maximum number of SDRAM channels supported by the memory
> controller
> +///
> +#define SA_MC_MAX_CHANNELS 2
> +
> +///
> +/// Maximum number of DIMM sockets supported by each channel
> +///
> +#define SA_MC_MAX_SLOTS 2
> +
> +///
> +/// Maximum number of sides supported per DIMM
> +///
> +#define SA_MC_MAX_SIDES 2
> +
> +///
> +/// Maximum number of DIMM sockets supported by the memory controller
> +///
> +#define SA_MC_MAX_SOCKETS (SA_MC_MAX_CHANNELS *
> SA_MC_MAX_SLOTS)
> +
> +///
> +/// Maximum number of rows supported by the memory controller
> +///
> +#define SA_MC_MAX_RANKS (SA_MC_MAX_SOCKETS * SA_MC_MAX_SIDES)
> +
> +///
> +/// Maximum number of rows supported by the memory controller
> +///
> +#define SA_MC_MAX_ROWS (SA_MC_MAX_SIDES * SA_MC_MAX_SOCKETS)
> +
> +///
> +/// Maximum memory supported by the memory controller
> +/// 4 GB in terms of KB
> +///
> +#define SA_MC_MAX_MEM_CAPACITY (4 * 1024 * 1024)
> +
> +///
> +/// Define the maximum number of data bytes on a system with no ECC
> memory support.
> +///
> +#define SA_MC_MAX_BYTES_NO_ECC (8)
> +
> +///
> +/// Define the maximum number of SPD data bytes on a DIMM.
> +///
> +#define SA_MC_MAX_SPD_SIZE (512)
> +//
> +// Maximum DMI lanes and bundles supported (x8 and 4 lanes)
> +//
> +#define SA_DMI_MAX_LANE                      0x04
> +#define SA_DMI_MAX_BUNDLE                    0x02
> +
> +#define SA_DMI_CFL_MAX_LANE                  0x04
> +#define SA_DMI_CFL_MAX_BUNDLE                0x02
> +//
> +// KabyLake CPU Mobile SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_KBL_MB_ULT_1 0x5904   ///< Kabylake Ult (OPI)
> (2+1F/1.5F/2F/3/3E) Mobile SA DID
> +//
> +// KabyLake CPU Halo SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_KBL_HALO_2   0x5910   ///< Kabylake Halo
> (4+2/4E/3FE) SA DID
> +//
> +// KabyLake CPU Desktop SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_KBL_DT_2     0x591F   ///< Kabylake Desktop
> (4+1.5F/2/4) SA DID
> +//
> +// KabyLake CPU Server SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_KBL_SVR_2    0x5918   ///< Kabylake Server
> (4+1/2/4E) SA DID
> +
> +//
> +// CoffeeLake CPU Mobile SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_CFL_ULT_1        0x3ED0   ///< CoffeeLake Mobile
> (CFL-U 4+3e) SA DID
> +#define V_SA_DEVICE_ID_CFL_ULT_2        0x3ECC   ///< CoffeeLake Mobile
> (CFL-U 2+3e) SA DID
> +#define V_SA_DEVICE_ID_CFL_ULT_3        0x3E34   ///< CoffeeLake Mobile
> (CFL-U 4+(1 or 2)) SA DID
> +#define V_SA_DEVICE_ID_CFL_ULT_4        0x3E35   ///< CoffeeLake Mobile
> (CFL-U 2+(1 or 2)) SA DID
> +#define V_SA_DEVICE_ID_CFL_ULT_6        0x3ECC   ///< CoffeeLake Mobile
> (CFL-U 2+3e) SA DID
> +
> +//
> +// CoffeeLake CPU Desktop SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_CFL_DT_1         0x3EC2   ///< CoffeeLake Desktop
> (6+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_DT_2         0x3E1F   ///< CoffeeLake Desktop
> (4+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_DT_3         0x3E0F   ///< CoffeeLake Desktop
> (2+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_DT_4         0x3E30   ///< CoffeeLake Desktop
> (8+2) SA DID
> +
> +//
> +// CoffeeLake CPU Halo SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_CFL_HALO_1       0x3EC4   ///< CoffeeLake Halo
> (6+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_HALO_2       0x3E10   ///< CoffeeLake Halo
> (4+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_HALO_3       0x3E20   ///< CoffeeLake Halo
> (8+2) SA DID
> +
> +//
> +// CoffeeLake CPU WS SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_CFL_WS_1         0x3EC6   ///< CoffeeLake
> WorkStation (6+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_WS_2         0x3E18   ///< CoffeeLake
> WrokStation (4+2) SA DID
> +#define V_SA_DEVICE_ID_CFL_WS_3         0x3E31   ///< CoffeeLake
> WrokStation (8+2) SA DID
> +
> +//
> +// CPU Server SA Device IDs B0:D0:F0
> +//
> +#define V_SA_DEVICE_ID_CFL_SVR_1        0x3ECA   ///< CoffeeLake Server
> (6+0) SA DID
> +#define V_SA_DEVICE_ID_CFL_SVR_2        0x3E32   ///< CoffeeLake Server
> (8+0) SA DID
> +#define V_SA_DEVICE_ID_CFL_SVR_3        0x3E33   ///< CoffeeLake Server
> (4+0) SA DID
> +/**
> + <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)
> +#define N_SA_GGC_GMS_OFFSET  (0x8)
> +#define B_SA_GGC_GMS_MASK    (0xff00)
> +#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)
> +#define B_SA_DEVEN_D2EN_MASK     (0x10)
> +/**
> + Description:
> +  This is the base address for the PCI Express configuration space.  This
> window of addresses contains the 4KB of configuration space for each PCI
> Express device that can potentially be part of the PCI Express Hierarchy
> associated with the Uncore.  There is no actual physical memory within this
> window of up to 256MB that can be addressed.  The actual size of this range
> is determined by a field in this register.
> +  Each PCI Express Hierarchy requires a PCI Express BASE register.  The Uncore
> supports one PCI Express Hierarchy.  The region reserved by this register does
> not alias to any PCI2.3 compliant memory mapped space.  For example, the
> range reserved for MCHBAR is outside of PCIEXBAR space.
> +  On reset, this register is disabled and must be enabled by writing a 1 to the
> enable field in this register.  This base address shall be assigned on a boundary
> consistent with the number of buses (defined by the length field in this
> register), above TOLUD and still within 39-bit addressable memory space.
> +  The PCI Express Base Address cannot be less than the maximum address
> written to the Top of physical memory register (TOLUD).  Software must
> guarantee that these ranges do not overlap with known ranges located above
> TOLUD.
> +  Software must ensure that the sum of the length of the enhanced
> configuration region + TOLUD + any other known ranges reserved above TOLUD
> is not greater than the 39-bit addessable limit of 512GB.  In general, system
> implementation and the number of PCI/PCI Express/PCI-X buses supported in
> the hierarchy will dictate the length of the region.
> +  All the bits in this register are locked in LT mode.
> +**/
> +#define R_SA_PCIEXBAR  (0x60)
> +
> +/**
> + Description:
> + - This register controls the read, write and shadowing attributes of the BIOS
> range from F_0000h to F_FFFFh.  The Uncore allows programmable memory
> attributes on 13 legacy memory segments of various sizes in the 768KB to 1MB
> address range.  Seven Programmable Attribute Map (PAM) registers are used
> to support these features.  Cacheability of these areas is controlled via the
> MTRR register in the core.
> + - Two bits are used to specify memory attributes for each memory segment.
> These bits apply to host accesses to the PAM areas.  These attributes are:
> + - RE - Read Enable.  When RE=1, the host read accesses to the corresponding
> memory segment are claimed by the Uncore and directed to main memory.
> Conversely, when RE=0, the host read accesses are directed to DMI.
> + - WE - Write Enable.  When WE=1, the host write accesses to the
> corresponding memory segment are claimed by the Uncore and directed to
> main memory.  Conversely, when WE=0, the host read accesses are directed to
> DMI.
> + - The RE and WE attributes permit a memory segment to be Read Only, Write
> Only, Read/Write or Disabled.  For example, if a memory segment has RE=1
> and WE=0, the segment is Read Only.
> +**/
> +#define R_SA_PAM0  (0x80)
> +
> +///
> +/// 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)
> +#define B_SA_SMRAMC_D_LCK_MASK     (0x10)
> +#define B_SA_SMRAMC_D_CLS_MASK     (0x20)
> +#define B_SA_SMRAMC_D_OPEN_MASK    (0x40)
> +///
> +/// Description:
> +///  This register contains the Top of low memory address.
> +///
> +#define R_SA_TOLUD (0xbc)
> +#define R_SA_MC_CAPID0_A_OFFSET    0xE4
> +//
> +// MCHBAR IO Register Offset Equates
> +//
> +#define R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET          0x5DA8
> +
> +#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)
> +///
> +/// Vt-d Engine base address.
> +///
> +#define R_SA_MCHBAR_VTD1_OFFSET                 0x5400  ///< HW UNIT1
> for IGD
> +#define R_SA_MCHBAR_VTD3_OFFSET      0x5410  ///< HW UNIT3 for all
> other - PEG, USB, SATA etc
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIg
> d.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIg
> d.h
> new file mode 100644
> index 0000000000..f8b794a9fb
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIg
> d.h
> @@ -0,0 +1,50 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_REGS_IGD_H_
> +#define _SA_REGS_IGD_H_
> +
> +///
> +/// Device 2 Register Equates
> +///
> +//
> +// The following equates must be reviewed and revised when the
> specification is ready.
> +//
> +#define SA_IGD_BUS           0x00
> +#define SA_IGD_DEV           0x02
> +#define SA_IGD_FUN_0         0x00
> +#define SA_IGD_DEV_FUN       (SA_IGD_DEV << 3)
> +#define SA_IGD_BUS_DEV_FUN   (SA_MC_BUS << 8) + SA_IGD_DEV_FUN
> +
> +#define V_SA_IGD_VID         0x8086
> +#define SA_GT_APERTURE_SIZE_256MB    1      ///< 256MB is the
> recommanded GT Aperture Size as per BWG.
> +
> +#define V_SA_PCI_DEV_2_GT2_CFL_ULT_1_ID   0x3EA0 ///< Dev2 CFL-U GT2
> +#define V_SA_PCI_DEV_2_GT1_CFL_ULT_1_ID   0x3EA1 ///< Dev2 CFL-U GT1
> +#define R_SA_IGD_VID               0x00
> +#define R_SA_IGD_DID               0x02
> +#define R_SA_IGD_CMD               0x04
> +
> +#define R_SA_IGD_SWSCI_OFFSET      0x00E8
> +#define R_SA_IGD_ASLS_OFFSET       0x00FC  ///< ASL Storage
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIp
> u.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIp
> u.h
> new file mode 100644
> index 0000000000..b26c79ec95
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIp
> u.h
> @@ -0,0 +1,37 @@
> +/** @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
> +  - 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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_REGS_IPU_H_
> +#define _SA_REGS_IPU_H_
> +
> +//
> +// Device 5 Equates
> +//
> +#define SA_IPU_BUS_NUM    0x00
> +#define SA_IPU_DEV_NUM    0x05
> +#define SA_IPU_FUN_NUM    0x00
> +
> +//
> +// GPIO native features pins data
> +//
> +#define SA_GPIO_IMGUCLK_NUMBER_OF_PINS     2
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPe
> g.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsP
> eg.h
> new file mode 100644
> index 0000000000..b7e9416fc6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsP
> eg.h
> @@ -0,0 +1,64 @@
> +/** @file
> +  Register names for PEG 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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_REGS_PEG_H_
> +#define _SA_REGS_PEG_H_
> +//
> +// Device 1 Memory Mapped IO Register Offset Equates
> +//
> +#define SA_PEG_BUS_NUM     0x00
> +#define SA_PEG_DEV_NUM     0x01
> +#define SA_PEG0_DEV_NUM    SA_PEG_DEV_NUM
> +#define SA_PEG0_FUN_NUM    0x00
> +#define SA_PEG1_DEV_NUM    SA_PEG_DEV_NUM
> +#define SA_PEG1_FUN_NUM    0x01
> +#define SA_PEG2_DEV_NUM    SA_PEG_DEV_NUM
> +#define SA_PEG2_FUN_NUM    0x02
> +//
> +// Temporary Device & Function Number used for Switchable Graphics DGPU
> +//
> +#define SA_TEMP_DGPU_DEV   0x00
> +#define SA_TEMP_DGPU_FUN   0x00
> +
> +//
> +// SA PCI Express* Port configuration
> +//
> +#define SA_PEG_MAX_FUN     0x03
> +#define SA_PEG_MAX_LANE    0x10
> +#define SA_PEG_MAX_BUNDLE  0x08
> +
> +//
> +// Silicon and SKU- specific MAX defines
> +//
> +#define SA_PEG_CNL_H_MAX_FUN           SA_PEG_MAX_FUN      // CNL-H-
> SKU supports 4 controllers with 20 PEG lanes and 10 bundles
> +#define SA_PEG_CNL_H_MAX_LANE          SA_PEG_MAX_LANE
> +#define SA_PEG_CNL_H_MAX_BUNDLE        SA_PEG_MAX_BUNDLE
> +#define SA_PEG_NON_CNL_H_MAX_FUN       0x03                // All
> non-CNL-H- SKU supports 3 controllers with 16 PEG lanes and 8 bundles
> +#define SA_PEG_NON_CNL_H_MAX_LANE      0x10
> +#define SA_PEG_NON_CNL_H_MAX_BUNDLE    0x08
> +
> +
> +
> +#define R_SA_PEG_VID_OFFSET            0x00  ///< Vendor ID
> +#define R_SA_PEG_DID_OFFSET            0x02  ///< Device ID
> +#define R_SA_PEG_SS_OFFSET             0x8C  ///< Subsystem ID
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
> new file mode 100644
> index 0000000000..b98f1732ba
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
> @@ -0,0 +1,106 @@
> +/** @file
> +  Macros to simplify and abstract the interface to PCI configuration.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SAACCESS_H_
> +#define _SAACCESS_H_
> +
> +#include "SaRegs.h"
> +#include "SaCommonDefinitions.h"
> +
> +///
> +/// SystemAgent Base Address definition
> +///
> +#ifndef STALL_ONE_MICRO_SECOND
> +#define STALL_ONE_MICRO_SECOND  1
> +#endif
> +#ifndef STALL_ONE_MILLI_SECOND
> +#define STALL_ONE_MILLI_SECOND  1000
> +#endif
> +
> +//
> +// SA Segement Number
> +//
> +#define SA_SEG_NUM         0x00
> +
> +#define V_SA_DEVICE_ID_INVALID 0xFFFF
> +
> +
> +///
> +/// 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
> +} SA_PCIE_ASPM_CONFIG;
> +
> +///
> +/// SgMode settings
> +///
> +typedef enum {
> +  SgModeDisabled = 0,
> +  SgModeReserved,
> +  SgModeMuxless,
> +  SgModeDgpu,
> +  SgModeMax
> +} SG_MODE;
> +
> +//
> +// Macros that judge which type a device ID belongs to
> +//
> +#define IS_SA_DEVICE_ID_MOBILE(DeviceId) \
> +    ( \
> +      (DeviceId == V_SA_DEVICE_ID_KBL_MB_ULT_1) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_1) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_3) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_ULT_4) \
> +    )
> +
> +///
> +/// Device IDs that are Desktop specific B0:D0:F0
> +///
> +#define IS_SA_DEVICE_ID_DESKTOP(DeviceId) \
> +    ( \
> +      (DeviceId == V_SA_DEVICE_ID_KBL_DT_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_DT_1) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_DT_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_DT_3) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_DT_4) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_WS_1) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_WS_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_WS_3) \
> +    )
> +
> +///
> +/// Device IDS that are Server specific B0:D0:F0
> +///
> +#define IS_SA_DEVICE_ID_SERVER(DeviceId) \
> +    ( \
> +      (DeviceId == V_SA_DEVICE_ID_KBL_SVR_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_1) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_SVR_3) \
> +    )
> +
> +///
> +/// Device IDs that are Halo specific B0:D0:F0
> +///
> +#define IS_SA_DEVICE_ID_HALO(DeviceId) \
> +    ( \
> +      (DeviceId == V_SA_DEVICE_ID_KBL_HALO_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_1) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_2) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_3) || \
> +      (DeviceId == V_SA_DEVICE_ID_CFL_HALO_IOT_1) \
> +    )
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinit
> ions.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinit
> ions.h
> new file mode 100644
> index 0000000000..ab9224e573
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinit
> ions.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  This header file provides common definitions just for System Agent using to
> avoid including extra module's file.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_COMMON_DEFINITIONS_H_
> +#define _SA_COMMON_DEFINITIONS_H_
> +
> +#define ERROR_BY_16     (0xEE15)
> +#define ERROR_NOT_BY_16 (0xED15)
> +
> +#define MAX_PCIE_ASPM_OVERRIDE       500
> +#define MAX_PCIE_LTR_OVERRIDE        500
> +
> +#define DISABLED  0
> +#define ENABLED   1
> +
> +#define SA_VTD_ENGINE_NUMBER        3
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
> new file mode 100644
> index 0000000000..87aa105df2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  Header file for the PCI Express library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_PCI_EXPRESS_LIB_H_
> +#define _SA_PCI_EXPRESS_LIB_H_
> +
> +
> +/**
> +  Gets the base address of PCI Express.
> +
> +  This internal functions retrieves PCI Express Base Address.
> +
> +  @return The base address of PCI Express.
> +**/
> +VOID*
> +GetPciExpressBaseAddress (
> +  VOID
> +);
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.
> h
> new file mode 100644
> index 0000000000..086c60bfed
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.
> h
> @@ -0,0 +1,51 @@
> +/** @file
> +  Main System Agent Policy structure definition which will contain several
> config blocks during runtime.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_POLICY_COMMON_H_
> +#define _SA_POLICY_COMMON_H_
> +
> +#include <Uefi.h>
> +#include <Library/SmbusLib.h>
> +#include <SaAccess.h>
> +#include <ConfigBlock.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <ConfigBlock/SwitchableGraphicsConfig.h>
> +#include <ConfigBlock/MemoryConfig.h>
> +#include <ConfigBlock/GraphicsPeiPreMemConfig.h>
> +#include <ConfigBlock/PciePeiPreMemConfig.h>
> +#include <ConfigBlock/IpuPreMemConfig.h>
> +#include <ConfigBlock/SaMiscPeiPreMemConfig.h>
> +#include <ConfigBlock/GnaConfig.h>
> +#include <ConfigBlock/GraphicsPeiConfig.h>
> +#include <ConfigBlock/SaMiscPeiConfig.h>
> +#include <ConfigBlock/OverClockingConfig.h>
> +#include <ConfigBlock/VtdConfig.h>
> +#include <ConfigBlock/PciePeiConfig.h>
> +
> +
> +//
> +// Extern the GUID for PPI users.
> +//
> +extern EFI_GUID gSiPolicyPpiGuid;
> +extern EFI_GUID gSaMiscPeiConfigGuid;
> +extern EFI_GUID gGraphicsPeiConfigGuid;
> +extern EFI_GUID gSaPciePeiConfigGuid;
> +extern EFI_GUID gGnaConfigGuid;
> +extern EFI_GUID gVtdConfigGuid;
> +extern EFI_GUID gSaOverclockingPreMemConfigGuid;
> +extern EFI_GUID gSiPreMemPolicyPpiGuid;
> +extern EFI_GUID gSaMiscPeiPreMemConfigGuid;
> +extern EFI_GUID gSaPciePeiPreMemConfigGuid;
> +extern EFI_GUID gGraphicsPeiPreMemConfigGuid;
> +extern EFI_GUID gIpuPreMemConfigGuid;
> +extern EFI_GUID gSwitchableGraphicsConfigGuid;
> +extern EFI_GUID gCpuTraceHubConfigGuid;
> +extern EFI_GUID gMemoryConfigGuid;
> +extern EFI_GUID gMemoryConfigNoCrcGuid;
> +
> +#endif // _SA_POLICY_COMMON_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
> new file mode 100644
> index 0000000000..593b907d2a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
> @@ -0,0 +1,32 @@
> +/** @file
> +  Register names for System Agent (SA) registers
> +  <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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_REGS_H_
> +#define _SA_REGS_H_
> +
> +#include <Register/SaRegsHostBridge.h>
> +#include <Register/SaRegsIgd.h>
> +#include <Register/SaRegsPeg.h>
> +#include <Register/SaRegsIpu.h>
> +#include <Register/SaRegsGna.h>
> +
> +#endif
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:12   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:12 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit


Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: Add
> library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds ME library class instances.
> 
> * PeiMePolicyLib - PEI ME policy configuration services.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLi
> b.inf   |  44 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLi
> brary.h |  25 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLi
> b.c     | 251 ++++++++++++++++++++
>  3 files changed, 320 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicy
> Lib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicy
> Lib.inf
> new file mode 100644
> index 0000000000..85a227f950
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMe
> +++ PolicyLib.inf
> @@ -0,0 +1,44 @@
> +## @file
> +# Component description file for the PeiMePolicyLib libbrary.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiMePolicyLib
> +FILE_GUID = 2655FA94-4559-F393-B0B1-85A8E79C1532
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = PeiMePolicyLib
> +
> +
> +[LibraryClasses]
> +DebugLib
> +IoLib
> +PeiServicesLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +ConfigBlockLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +PeiMePolicyLib.c
> +PeiMePolicyLibrary.h
> +
> +
> +[Ppis]
> +gSiPolicyPpiGuid       ## PRODUCES
> +gSiPreMemPolicyPpiGuid ## PRODUCES
> +
> +
> +[Guids]
> +gMePeiPreMemConfigGuid
> +gMePeiConfigGuid
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicy
> Library.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicy
> Library.h
> new file mode 100644
> index 0000000000..3ac6a639e9
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMe
> +++ PolicyLibrary.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  Header file for the PeiMePolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _PEI_ME_POLICY_LIBRARY_H_
> +#define _PEI_ME_POLICY_LIBRARY_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h> #include <Ppi/SiPolicy.h>
> +#include <Library/PeiMePolicyLib.h> #include <ConfigBlock.h> #include
> +<ConfigBlock/MePeiConfig.h> #include <Library/ConfigBlockLib.h>
> +#include <Library/SiConfigBlockLib.h> #include <MkhiMsgs.h>
> +
> +#endif // _PEI_ME_POLICY_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicy
> Lib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicy
> Lib.c
> new file mode 100644
> index 0000000000..6f3d70b841
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMe
> +++ PolicyLib.c
> @@ -0,0 +1,251 @@
> +/** @file
> +  This file is PeiMePolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include "PeiMePolicyLibrary.h"
> +
> +/**
> +  Load default settings for ME config block in pre-mem phase.
> +
> +  @param[in] ConfigBlockPointer                 The pointer to the config block
> +**/
> +VOID
> +LoadMePeiPreMemDefault (
> +  IN VOID                           *ConfigBlockPointer
> +  );
> +
> +/**
> +  Load default settings for ME config block in PEI phase.
> +
> +  @param[in] ConfigBlockPointer                 The pointer to the config block
> +**/
> +VOID
> +LoadMePeiDefault (
> +  IN VOID                           *ConfigBlockPointer
> +  );
> +
> +STATIC COMPONENT_BLOCK_ENTRY  mMeCompontBlockPreMemBlocks [] = {
> +  {&gMePeiPreMemConfigGuid, sizeof (ME_PEI_PREMEM_CONFIG),
> +ME_PEI_PREMEM_CONFIG_REVISION,  LoadMePeiPreMemDefault} };
> +
> +STATIC COMPONENT_BLOCK_ENTRY  mMeCompontBlockBlocks [] = {
> +  {&gMePeiConfigGuid,       sizeof (ME_PEI_CONFIG),
> ME_PEI_CONFIG_REVISION,         LoadMePeiDefault}
> +};
> +
> +/**
> +  Load default settings for ME config block in pre-mem phase.
> +
> +  @param[in] ConfigBlockPointer                 The pointer to the config block
> +**/
> +VOID
> +LoadMePeiPreMemDefault (
> +  IN VOID                           *ConfigBlockPointer
> +  )
> +{
> +  ME_PEI_PREMEM_CONFIG *MePeiPreMemConfig;
> +  MePeiPreMemConfig = ConfigBlockPointer;
> +
> +  MePeiPreMemConfig->HeciTimeouts                  = 1;
> +
> +  MePeiPreMemConfig->Heci1BarAddress               = 0xFED1A000;
> +  MePeiPreMemConfig->Heci2BarAddress               = 0xFED1B000;
> +  MePeiPreMemConfig->Heci3BarAddress               = 0xFED1C000;
> +
> +  //
> +  // Test policies
> +  //
> +  MePeiPreMemConfig->SendDidMsg                    = 1;
> +
> +  MePeiPreMemConfig->KtDeviceEnable                = 1;
> +}
> +
> +/**
> +  Load default settings for ME config block in PEI phase.
> +
> +  @param[in] ConfigBlockPointer                 The pointer to the config block
> +**/
> +VOID
> +LoadMePeiDefault (
> +  IN VOID                           *ConfigBlockPointer
> +  )
> +{
> +  ME_PEI_CONFIG *MePeiConfig;
> +  MePeiConfig = ConfigBlockPointer;
> +
> +  MePeiConfig->EndOfPostMessage     = EOP_SEND_IN_DXE;
> +  MePeiConfig->MeUnconfigOnRtcClear = 1; }
> +
> +/**
> +  Dump values of ME config block in pre-mem phase.
> +
> +  @param[in] MePeiPreMemConfig                     The pointer to the config
> block
> +**/
> +VOID
> +EFIAPI
> +PrintMePeiPreMemConfig (
> +  IN ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  DEBUG ((DEBUG_INFO, "------------------------ ME_PEI_PREMEM_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision                  : 0x%x\n",
> MePeiPreMemConfig->Header.Revision));
> +  ASSERT (MePeiPreMemConfig->Header.Revision ==
> +ME_PEI_PREMEM_CONFIG_REVISION);
> +
> +  DEBUG ((DEBUG_INFO, " HeciTimeouts              : 0x%x\n",
> MePeiPreMemConfig->HeciTimeouts));
> +  DEBUG ((DEBUG_INFO, " DidInitStat               : 0x%x\n",
> MePeiPreMemConfig->DidInitStat));
> +  DEBUG ((DEBUG_INFO, " DisableCpuReplacedPolling : 0x%x\n",
> MePeiPreMemConfig->DisableCpuReplacedPolling));
> +  DEBUG ((DEBUG_INFO, " SendDidMsg                : 0x%x\n",
> MePeiPreMemConfig->SendDidMsg));
> +  DEBUG ((DEBUG_INFO, " DisableHeciRetry          : 0x%x\n",
> MePeiPreMemConfig->DisableHeciRetry));
> +  DEBUG ((DEBUG_INFO, " DisableMessageCheck       : 0x%x\n",
> MePeiPreMemConfig->DisableMessageCheck));
> +  DEBUG ((DEBUG_INFO, " SkipMbpHob                : 0x%x\n",
> MePeiPreMemConfig->SkipMbpHob));
> +  DEBUG ((DEBUG_INFO, " HeciCommunication2        : 0x%x\n",
> MePeiPreMemConfig->HeciCommunication2));
> +  DEBUG ((DEBUG_INFO, " KtDeviceEnable            : 0x%x\n",
> MePeiPreMemConfig->KtDeviceEnable));
> +  DEBUG ((DEBUG_INFO, " Heci1BarAddress           : 0x%x\n",
> MePeiPreMemConfig->Heci1BarAddress));
> +  DEBUG ((DEBUG_INFO, " Heci2BarAddress           : 0x%x\n",
> MePeiPreMemConfig->Heci2BarAddress));
> +  DEBUG ((DEBUG_INFO, " Heci3BarAddress           : 0x%x\n",
> MePeiPreMemConfig->Heci3BarAddress));
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Dump values of ME config block in PEI phase.
> +
> +  @param[in] MePeiConfig                    The pointer to the config block
> +**/
> +VOID
> +EFIAPI
> +PrintMePeiConfig (
> +  IN ME_PEI_CONFIG              *MePeiConfig
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  DEBUG ((DEBUG_INFO, "------------------------ ME_PEI_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision                  : 0x%x\n",
> MePeiConfig->Header.Revision));
> +  ASSERT (MePeiConfig->Header.Revision == ME_PEI_CONFIG_REVISION);
> +
> +  DEBUG ((DEBUG_INFO, " MctpBroadcastCycle        : 0x%x\n",
> MePeiConfig->MctpBroadcastCycle));
> +  DEBUG ((DEBUG_INFO, " EndOfPostMessage          : 0x%x\n",
> MePeiConfig->EndOfPostMessage));
> +  DEBUG ((DEBUG_INFO, " Heci3Enabled              : 0x%x\n",
> MePeiConfig->Heci3Enabled));
> +  DEBUG ((DEBUG_INFO, " DisableD0I3SettingForHeci : 0x%x\n",
> MePeiConfig->DisableD0I3SettingForHeci));
> +  DEBUG ((DEBUG_INFO, " MeUnconfigOnRtcClear      : 0x%x\n",
> MePeiConfig->MeUnconfigOnRtcClear));
> +
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Print PEI ME config block
> +
> +  @param[in] SiPolicyPpiPreMem The RC Policy PPI instance **/ VOID
> +EFIAPI MePrintPolicyPpiPreMem (
> +  IN  SI_PREMEM_POLICY_PPI *SiPolicyPpiPreMem
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  EFI_STATUS                        Status;
> +  ME_PEI_PREMEM_CONFIG              *MePeiPreMemConfig;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpiPreMem,
> + &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
> + ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Pre-Mem
> +Print Begin -----------------\n"));
> +  PrintMePeiPreMemConfig (MePeiPreMemConfig);
> +  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Pre-Mem
> +Print End -------------------\n"));
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Print PEI ME config block
> +
> +  @param[in] SiPolicyPpi The RC Policy PPI instance **/ VOID EFIAPI
> +MePrintPolicyPpi (
> +  IN  SI_POLICY_PPI *SiPolicyPpi
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  EFI_STATUS                        Status;
> +  ME_PEI_CONFIG                     *MePeiConfig;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid,
> + (VOID *) &MePeiConfig);  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Print
> +Begin -----------------\n"));
> +  PrintMePeiConfig (MePeiConfig);
> +  DEBUG ((DEBUG_INFO, "\n---------------------- Me Config Block Print
> +End -------------------\n"));
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Get ME config block table total size.
> +
> +  @retval        Size of ME config block table
> +**/
> +UINT16
> +EFIAPI
> +MeGetConfigBlockTotalSizePreMem (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize
> +(&mMeCompontBlockPreMemBlocks[0], sizeof
> (mMeCompontBlockPreMemBlocks)
> +/ sizeof (COMPONENT_BLOCK_ENTRY)); }
> +
> +/**
> +  Get ME config block table total size.
> +
> +  @retval        Size of ME config block table
> +**/
> +UINT16
> +EFIAPI
> +MeGetConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize
> (&mMeCompontBlockBlocks[0],
> +sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)); }
> +
> +/**
> +  MeAddConfigBlocksPreMem add all config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +MeAddConfigBlocksPreMem (
> +  IN VOID           *ConfigBlockTableAddress
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "Me AddConfigBlocks. TotalBlockCount = 0x%x\n",
> +sizeof (mMeCompontBlockPreMemBlocks) / sizeof
> +(COMPONENT_BLOCK_ENTRY)));
> +
> +  return AddComponentConfigBlocks (ConfigBlockTableAddress,
> +&mMeCompontBlockPreMemBlocks[0], sizeof
> (mMeCompontBlockPreMemBlocks) /
> +sizeof (COMPONENT_BLOCK_ENTRY)); }
> +
> +/**
> +  MeAddConfigBlocks add all config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +MeAddConfigBlocks (
> +  IN VOID           *ConfigBlockTableAddress
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "ME AddConfigBlocks. TotalBlockCount = 0x%x\n",
> +sizeof (mMeCompontBlockBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
> +
> +  return AddComponentConfigBlocks (ConfigBlockTableAddress,
> +&mMeCompontBlockBlocks[0], sizeof (mMeCompontBlockBlocks) / sizeof
> +(COMPONENT_BLOCK_ENTRY)); }
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:13 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE
> library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH DXE library class instances.
> 
> * DxePchPolicyLib
> * DxeResetSystemLib
> * DxeRuntimeResetSystemLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicy
> Lib.inf                   |  41 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetS
> ystemLib.inf               |  49 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/D
> xeRuntimeResetSystemLib.inf |  52 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicy
> Lib.c                     | 218 +++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetS
> ystemLib.c                 | 310 +++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/D
> xeRuntimeResetSystemLib.c   | 323 ++++++++++++++++++++
>  6 files changed, 993 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPoli
> cyLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPoli
> cyLib.inf
> new file mode 100644
> index 0000000000..8845ab796c
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/Dxe
> +++ PchPolicyLib.inf
> @@ -0,0 +1,41 @@
> +## @file
> +# Component description file for the PeiPchPolicy library.
> +#
> +# Copyright (c) 2019 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
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +DxePchPolicyLib.c
> +
> +
> +[Guids]
> +gHdAudioDxeConfigGuid
> +gGpioDxeConfigGuid
> +
> +[Protocols]
> +gPchPolicyProtocolGuid ## PRODUCES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeRes
> etSystemLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeRes
> etSystemLib.inf
> new file mode 100644
> index 0000000000..0bb2d6e247
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/D
> +++ xeResetSystemLib.inf
> @@ -0,0 +1,49 @@
> +## @file
> +# Component description file for Intel Ich7 Reset System Library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxeResetSystemLib
> +FILE_GUID = 239383BC-499E-4DC5-8CDC-F85AF27B1BC4
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +UEFI_SPECIFICATION_VERSION = 2.00
> +LIBRARY_CLASS = ResetSystemLib
> +CONSTRUCTOR = DxeResetSystemLibConstructor # # The following
> +information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +IoLib
> +BaseLib
> +DebugLib
> +TimerLib
> +BaseMemoryLib
> +UefiBootServicesTableLib
> +PmcLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +DxeResetSystemLib.c
> +
> +
> +[Protocols]
> +gPchResetCallbackProtocolGuid ## CONSUMES
> +
> +
> +[Guids]
> +gPchGlobalResetGuid
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib
> /DxeRuntimeResetSystemLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib
> /DxeRuntimeResetSystemLib.inf
> new file mode 100644
> index 0000000000..a1777293ab
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSyst
> +++ emLib/DxeRuntimeResetSystemLib.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# Component description file for Intel Ich7 Reset System Library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxeRuntimeResetSystemLib
> +FILE_GUID = 1026813A-E46F-43D1-B709-FF1F996F2E72
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_RUNTIME_DRIVER
> +UEFI_SPECIFICATION_VERSION = 2.00
> +LIBRARY_CLASS = ResetSystemLib
> +CONSTRUCTOR = DxeRuntimeResetSystemLibConstructor
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +IoLib
> +BaseLib
> +DebugLib
> +TimerLib
> +BaseMemoryLib
> +UefiRuntimeLib
> +DxeServicesTableLib
> +UefiBootServicesTableLib
> +PmcLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +DxeRuntimeResetSystemLib.c
> +
> +
> +[Protocols]
> +gPchResetCallbackProtocolGuid ## CONSUMES
> +
> +
> +[Guids]
> +gPchGlobalResetGuid
> +gEfiEventVirtualAddressChangeGuid
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPoli
> cyLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPoli
> cyLib.c
> new file mode 100644
> index 0000000000..62c8a91eb9
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/Dxe
> +++ PchPolicyLib.c
> @@ -0,0 +1,218 @@
> +/** @file
> +  This file provide services for DXE phase policy default
> +initialization
> +
> +  Copyright (c) 2019 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 <ConfigBlock/HdAudioConfig.h>
> +#include <ConfigBlock/GpioDevConfig.h>
> +
> +/**
> +  Load DXE Config block default for HD Audio
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadHdAudioDxeConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_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));
> +
> +  HdAudioDxeConfig->DspEndpointDmic = PchHdaDmic4chArray;
> +  HdAudioDxeConfig->NhltDefaultFlow = TRUE; }
> +
> +/**
> +  Load DXE Config block default for GPIO
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadGpioDxeConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_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; }
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY
> mPchDxeIpBlocks []
> += {
> +  {&gHdAudioDxeConfigGuid, sizeof (PCH_HDAUDIO_DXE_CONFIG),
> +HDAUDIO_DXE_CONFIG_REVISION, LoadHdAudioDxeConfigDefault},
> +  {&gGpioDxeConfigGuid, sizeof (PCH_GPIO_DXE_CONFIG),
> +GPIO_DXE_CONFIG_REVISION, LoadGpioDxeConfigDefault} };
> +
> +/**
> +  Print PCH_HDAUDIO_DXE_CONFIG.
> +
> +  @param[in] HdaDxeConfig         Pointer to a PCH_HDAUDIO_DXE_CONFIG
> that provides the HD Audio settings
> +**/
> +VOID
> +PchPrintHdAudioDxeConfig (
> +  IN CONST PCH_HDAUDIO_DXE_CONFIG   *HdaDxeConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio DXE Config
> +------------------\n"));
> +  DEBUG ((DEBUG_INFO, " DSP Endpoint: DMIC : %d\n",
> +HdaDxeConfig->DspEndpointDmic));
> +  DEBUG ((DEBUG_INFO, " DSP Endpoint: I2S  : %d\n",
> HdaDxeConfig->DspEndpointI2s));
> +  DEBUG ((DEBUG_INFO, " DSP Endpoint: BT   : %d\n",
> HdaDxeConfig->DspEndpointBluetooth));
> +  DEBUG ((DEBUG_INFO, " DSP Feature Mask   : 0x%x\n",
> HdaDxeConfig->DspFeatureMask));
> +  DEBUG ((DEBUG_INFO, " Nhlt Default Flow  : %d\n",
> +HdaDxeConfig->NhltDefaultFlow)); }
> +
> +/**
> +  Print PCH_GPIO_DXE_CONFIG.
> +
> +  @param[in] GpioDxeConfig         Pointer to a PCH_GPIO_DXE_CONFIG that
> provides the GPIO settings
> +**/
> +VOID
> +PchPrintGpioDxeConfig (
> +  IN CONST PCH_GPIO_DXE_CONFIG   *GpioDxeConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH GPIO DXE Config
> +------------------\n"));
> +  DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n",
> +GpioDxeConfig->HideGpioAcpiDevice));
> +}
> +
> +/**
> +  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;
> +  PCH_HDAUDIO_DXE_CONFIG     *HdaDxeConfig;
> +  PCH_GPIO_DXE_CONFIG        *GpioDxeConfig;
> +
> +  //
> +  // Get requisite IP Config Blocks which needs to be used here  //
> + Status = GetConfigBlock ((VOID *) PchPolicy, &gHdAudioDxeConfigGuid,
> + (VOID *)&HdaDxeConfig);  ASSERT_EFI_ERROR (Status);  Status =
> + GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (VOID
> + *)&GpioDxeConfig);  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print
> + Start ------------------------\n"));  DEBUG ((DEBUG_INFO, " Revision :
> + %x\n", PchPolicy->TableHeader.Header.Revision));
> +
> +  PchPrintHdAudioDxeConfig (HdaDxeConfig);  PchPrintGpioDxeConfig
> + (GpioDxeConfig);
> +
> +  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));
> +
> +  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);
> +
> +  //
> +  // 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/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeRes
> etSystemLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeRes
> etSystemLib.c
> new file mode 100644
> index 0000000000..fd3c280605
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/D
> +++ xeResetSystemLib.c
> @@ -0,0 +1,310 @@
> +/** @file
> +  System reset library services.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/ResetSystemLib.h>
> +#include <Library/PmcLib.h>
> +#include <Protocol/PchReset.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsPmc.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT32
> mDxeResetSystemPwrmBase;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16
> mDxeResetSystemABase;
> +
> +/**
> +  Dump reset message for debug build readability **/ VOID
> +DumpResetMessage (
> +  VOID
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  UINTN       Index;
> +  //
> +  // ******************************
> +  // **    SYSTEM REBOOT !!!     **
> +  // ******************************
> +  //
> +  for (Index = 0; Index < 30; Index++) {
> +    DEBUG ((DEBUG_INFO, "*"));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
> +  for (Index = 0; Index < 30; Index++) {
> +    DEBUG ((DEBUG_INFO, "*"));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Execute call back function for Pch Reset.
> +
> +  @param[in] ResetType            Reset Types which includes GlobalReset.
> +  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset
> Type Guid.
> +**/
> +VOID
> +EFIAPI
> +PchResetCallback (
> +  IN  EFI_RESET_TYPE          ResetType,
> +  IN  EFI_GUID                *ResetTypeGuid
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  UINTN                       NumHandles;
> +  EFI_HANDLE                  *HandleBuffer;
> +  UINTN                       Index;
> +  PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
> +
> +  ///
> +  /// Retrieve all instances of Pch Reset Callback protocol  ///
> + Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gPchResetCallbackProtocolGuid,
> +                  NULL,
> +                  &NumHandles,
> +                  &HandleBuffer
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    ///
> +    /// Those drivers that need to install Pch Reset Callback protocol have the
> responsibility
> +    /// to make sure themselves execute before Pch Reset Runtime driver.
> +    ///
> +    if (Status == EFI_NOT_FOUND) {
> +      DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback
> protocol is installed.\n"));
> +    }
> +    return;
> +  }
> +
> +  for (Index = 0; Index < NumHandles; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gPchResetCallbackProtocolGuid,
> +                    (VOID **) &PchResetCallback
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    if (!EFI_ERROR (Status)) {
> +      PchResetCallback->ResetCallback (ResetType, ResetTypeGuid);
> +    }
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol
> +  //
> +  PchResetCallback (EfiResetCold, NULL);
> +
> +  DumpResetMessage ();
> +
> +  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
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol
> +  //
> +  PchResetCallback (EfiResetWarm, NULL);
> +
> +  DumpResetMessage ();
> +  //
> +  // In case there are pending capsules to process, need to flush the cache.
> +  //
> +  AsmWbinvd ();
> +
> +  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
> +  )
> +{
> +  UINT32         Data32;
> +
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol  //
> + PchResetCallback (EfiResetShutdown, NULL);
> +
> +  ///
> +  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up
> + the system from S5  ///
> +  IoWrite32 (mDxeResetSystemABase + 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 (mDxeResetSystemABase + R_ACPI_IO_PM1_STS,
> + B_ACPI_IO_PM1_STS_PWRBTN);
> +
> +  ///
> +  /// Finally, transform system into S5 sleep state  ///
> +  Data32 = IoRead32 (mDxeResetSystemABase + 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 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
> +
> +  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
> +
> +  DumpResetMessage ();
> +
> +  IoWrite32 (mDxeResetSystemABase + R_ACPI_IO_PM1_CNT, Data32);
> +
> +  return;
> +}
> +
> +/**
> +  Internal function to execute the required HECI command for
> +GlobalReset,
> +  if failed will use PCH Reest.
> +
> +**/
> +STATIC
> +VOID
> +PchGlobalReset (
> +  VOID
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol
> +  //
> +  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
> +
> +  //
> +  // PCH BIOS Spec Section 4.6 GPIO Reset Requirement  //
> +  MmioOr32 (
> +    mDxeResetSystemPwrmBase + R_PMC_PWRM_ETR3,
> +    (UINT32) B_PMC_PWRM_ETR3_CF9GR
> +    );
> +
> +  DumpResetMessage ();
> +
> +  //
> +  // ME Global Reset should fail after EOP is sent. Go to use PCH Reset.
> +  //
> +  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); }
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_GUID            *GuidPtr;
> +
> +  if (ResetData == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[DxeResetSystemLib] ResetData is not
> available.\n"));
> +    return;
> +  }
> +  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof
> +(EFI_GUID));
> +  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
> +    PchGlobalReset();
> +  } else {
> +    return;
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  The library constructuor.
> +
> +  The function does the necessary initialization work for this library DXE
> instance.
> +
> +  @param[in]  ImageHandle       The firmware allocated handle for the UEFI
> image.
> +  @param[in]  SystemTable       A pointer to the EFI system table.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +                                It will ASSERT on error for debug version.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeResetSystemLibConstructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  mDxeResetSystemABase    = PmcGetAcpiBase ();
> +  mDxeResetSystemPwrmBase = PmcGetPwrmBase ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib
> /DxeRuntimeResetSystemLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib
> /DxeRuntimeResetSystemLib.c
> new file mode 100644
> index 0000000000..a39e171804
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSyst
> +++ emLib/DxeRuntimeResetSystemLib.c
> @@ -0,0 +1,323 @@
> +/** @file
> +  System reset library services.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Library/DxeServicesTableLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Library/ResetSystemLib.h>
> +#include <Library/PmcLib.h>
> +#include <Protocol/PchReset.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsPmc.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT32
> mDxeRuntimeResetSystemPwrmBase;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16
> mDxeRuntimeResetSystemABase;
> +
> +/**
> +  Dump reset message for debug build readability **/ VOID
> +DumpResetMessage (
> +  VOID
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  UINTN       Index;
> +  //
> +  // ******************************
> +  // **    SYSTEM REBOOT !!!     **
> +  // ******************************
> +  //
> +  if (!EfiAtRuntime ()) {
> +    for (Index = 0; Index < 30; Index++) {
> +      DEBUG ((DEBUG_INFO, "*"));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
> +    for (Index = 0; Index < 30; Index++) {
> +      DEBUG ((DEBUG_INFO, "*"));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Execute call back function for Pch Reset.
> +
> +  @param[in] ResetType            Reset Types which includes GlobalReset.
> +  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset
> Type Guid.
> +**/
> +VOID
> +EFIAPI
> +PchResetCallback (
> +  IN  EFI_RESET_TYPE          ResetType,
> +  IN  EFI_GUID                *ResetTypeGuid
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  UINTN                       NumHandles;
> +  EFI_HANDLE                  *HandleBuffer;
> +  UINTN                       Index;
> +  PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
> +
> +  if (!EfiAtRuntime ()) {
> +    ///
> +    /// Retrieve all instances of Pch Reset Callback protocol
> +    ///
> +    Status = gBS->LocateHandleBuffer (
> +                    ByProtocol,
> +                    &gPchResetCallbackProtocolGuid,
> +                    NULL,
> +                    &NumHandles,
> +                    &HandleBuffer
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      ///
> +      /// Those drivers that need to install Pch Reset Callback protocol have
> the responsibility
> +      /// to make sure themselves execute before Pch Reset Runtime driver.
> +      ///
> +      if (Status == EFI_NOT_FOUND) {
> +        DEBUG ((DEBUG_ERROR | DEBUG_INFO, "None of Pch Reset Callback
> protocol is installed.\n"));
> +      }
> +      return;
> +    }
> +
> +    for (Index = 0; Index < NumHandles; Index++) {
> +      Status = gBS->HandleProtocol (
> +                      HandleBuffer[Index],
> +                      &gPchResetCallbackProtocolGuid,
> +                      (VOID **) &PchResetCallback
> +                      );
> +      ASSERT_EFI_ERROR (Status);
> +
> +      if (!EFI_ERROR (Status)) {
> +        PchResetCallback->ResetCallback (ResetType, ResetTypeGuid);
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol
> +  //
> +  PchResetCallback (EfiResetCold, NULL);
> +
> +  DumpResetMessage ();
> +
> +  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
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol
> +  //
> +  PchResetCallback (EfiResetWarm, NULL);
> +
> +  DumpResetMessage ();
> +  //
> +  // In case there are pending capsules to process, need to flush the cache.
> +  //
> +  AsmWbinvd ();
> +
> +  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
> +  )
> +{
> +  UINT32         Data32;
> +
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol  //
> + PchResetCallback (EfiResetShutdown, NULL);
> +
> +  ///
> +  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up
> + the system from S5  ///
> +  IoWrite32 (mDxeRuntimeResetSystemABase +
> 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 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_STS,
> + B_ACPI_IO_PM1_STS_PWRBTN);
> +
> +  ///
> +  /// Finally, transform system into S5 sleep state  ///
> +  Data32 = IoRead32 (mDxeRuntimeResetSystemABase +
> 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 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT,
> Data32);
> +
> +  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
> +
> +  DumpResetMessage ();
> +
> +  IoWrite32 (mDxeRuntimeResetSystemABase + R_ACPI_IO_PM1_CNT,
> Data32);
> +
> +  return;
> +}
> +
> +/**
> +  Internal function to execute the required HECI command for
> +GlobalReset,
> +  if failed will use PCH Reest.
> +
> +**/
> +STATIC
> +VOID
> +PchGlobalReset (
> +  VOID
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback Protocol
> +  //
> +  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
> +
> +  DumpResetMessage ();
> +
> +  //
> +  // Let ME do global reset if Me Fw is available  //  if
> + (!EfiAtRuntime ()) {
> +    //
> +    // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
> +    //
> +    MmioOr32 (
> +      mDxeRuntimeResetSystemPwrmBase + R_PMC_PWRM_ETR3,
> +      (UINT32) B_PMC_PWRM_ETR3_CF9GR
> +      );
> +  }
> +
> +  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); }
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_GUID            *GuidPtr;
> +
> +  if (ResetData == NULL) {
> +    if (!EfiAtRuntime ()) {
> +      DEBUG ((DEBUG_ERROR, "[DxeRuntimeResetSystemLib] ResetData is not
> available.\n"));
> +    }
> +    return;
> +  }
> +  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof
> +(EFI_GUID));
> +  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
> +    PchGlobalReset ();
> +  } else {
> +    return;
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  The library constructuor.
> +
> +  The function does the necessary initialization work for this library instance.
> +
> +  The PMC PCI configuration and PWRM space memory ranges are converted
> + into EFI_RUNTIME_XXX  in PciHostBridgeEntryPoint
> +
> +  @param[in]  ImageHandle       The firmware allocated handle for the UEFI
> image.
> +  @param[in]  SystemTable       A pointer to the EFI system table.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +                                It will ASSERT on error for debug version.
> +  @retval     EFI_ERROR         Please reference LocateProtocol for error code
> details.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeRuntimeResetSystemLibConstructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  mDxeRuntimeResetSystemABase    = PmcGetAcpiBase ();
> +  mDxeRuntimeResetSystemPwrmBase = PmcGetPwrmBase ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:13 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add
> Base library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH Base library class instances.
> 
> * BaseResetSystemLib
> * BaseSmbusLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseRes
> etSystemLib.inf |  38 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.
> inf             |  39 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseRes
> etSystemLib.c   | 153 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.
> c               | 993 ++++++++++++++++++++
>  4 files changed, 1223 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR
> esetSystemLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR
> esetSystemLib.inf
> new file mode 100644
> index 0000000000..8d68f2dd83
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/
> +++ BaseResetSystemLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# Component description file for Intel Ich7 Reset System Library.
> +#
> +# Copyright (c) 2019 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
> +DebugLib
> +PmcLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +BaseResetSystemLib.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi
> b.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi
> b.inf
> new file mode 100644
> index 0000000000..f3388a2624
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSm
> +++ busLib.inf
> @@ -0,0 +1,39 @@
> +## @file
> +# Component description file for PCH Smbus Library.
> +#
> +# SMBUS Library that layers on top of the I/O Library to directly #
> +access a standard SMBUS host controller.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseSmbusLib
> +FILE_GUID = 5C4D0430-F81B-42D3-BB88-4A6CD2796FF8
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = SmbusLib
> +CONSTRUCTOR = BaseSmbusLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC #
> +
> +[LibraryClasses]
> +BaseLib
> +DebugLib
> +IoLib
> +PciSegmentLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +BaseSmbusLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR
> esetSystemLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR
> esetSystemLib.c
> new file mode 100644
> index 0000000000..a603f5e794
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/
> +++ BaseResetSystemLib.c
> @@ -0,0 +1,153 @@
> +/** @file
> +  System reset library services.
> +
> +  Copyright (c) 2019 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 <Register/PchRegsLpc.h>
> +#include <Register/PchRegsPmc.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
> +  )
> +{
> +  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/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi
> b.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi
> b.c
> new file mode 100644
> index 0000000000..3d6386d433
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSm
> +++ busLib.c
> @@ -0,0 +1,993 @@
> +/** @file
> +  PCH SMBUS library implementation built upon I/O library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Base.h>
> +#include <Library/SmbusLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsSmbus.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mSmbusIoBase = 0;
> +
> +/**
> +  Gets Io port base address of Smbus Host Controller.
> +
> +  @retval The Io port base address of Smbus host controller.
> +
> +**/
> +UINT16
> +InternalGetSmbusIoPortBaseAddress (
> +  VOID
> +  )
> +{
> +  UINT64    SmbusPciBase;
> +  UINT16    IoPortBaseAddress;
> +
> +  if (mSmbusIoBase != 0) {
> +    return mSmbusIoBase;
> +  }
> +
> +  SmbusPciBase = PCI_SEGMENT_LIB_ADDRESS (
> +                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_SMBUS,
> +                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
> +                   0
> +                   );
> +  IoPortBaseAddress = (UINT16) PciSegmentRead32 (SmbusPciBase +
> + R_SMBUS_CFG_BASE);
> +
> +  //
> +  // Make sure that the IO port base address has been properly set.
> +  //
> +  if ((IoPortBaseAddress == 0) || (IoPortBaseAddress == 0xFFFF)) {
> +    ASSERT (FALSE);
> +    return 0;
> +  }
> +
> +  IoPortBaseAddress &= B_SMBUS_CFG_BASE_BAR;  mSmbusIoBase =
> + IoPortBaseAddress;
> +
> +  return IoPortBaseAddress;
> +}
> +
> +
> +/**
> +  Acquires the ownership of SMBUS.
> +
> +  This internal function reads the host state register.
> +  If the SMBUS is not available, RETURN_TIMEOUT is returned;
> + Otherwise, it performs some basic initializations and returns
> + RETURN_SUCCESS.
> +
> +  @param[in]  IoPortBaseAddress The Io port base address of Smbus Host
> controller.
> +
> +  @retval     RETURN_SUCCESS    The SMBUS command was executed
> successfully.
> +  @retval     RETURN_TIMEOUT    A timeout occurred while executing the
> SMBUS command.
> +
> +**/
> +RETURN_STATUS
> +InternalSmBusAcquire (
> +  IN UINT16                   IoPortBaseAddress
> +  )
> +{
> +  UINT8   HostStatus;
> +
> +  HostStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);  if
> + ((HostStatus & B_SMBUS_IO_IUS) != 0) {
> +    return RETURN_TIMEOUT;
> +  } else if ((HostStatus & B_SMBUS_IO_HBSY) != 0) {
> +    //
> +    // Clear host status register and exit.
> +    //
> +    IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS,
> B_SMBUS_IO_HSTS_ALL);
> +    return RETURN_TIMEOUT;
> +  }
> +  //
> +  // Clear out any odd status information (Will Not Clear In Use).
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, HostStatus);
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Starts the SMBUS transaction and waits until the end.
> +
> +  This internal function start the SMBUS transaction and waits until
> + the transaction  of SMBUS is over by polling the INTR bit of Host status
> register.
> +  If the SMBUS is not available, RETURN_TIMEOUT is returned;
> + Otherwise, it performs some basic initializations and returns
> + RETURN_SUCCESS.
> +
> +  @param[in]  IoPortBaseAddress   The Io port base address of Smbus Host
> controller.
> +  @param[in]  HostControl         The Host control command to start SMBUS
> transaction.
> +
> +  @retval     RETURN_SUCCESS      The SMBUS command was executed
> successfully.
> +  @retval     RETURN_CRC_ERROR    The checksum is not correct (PEC is
> incorrect).
> +  @retval     RETURN_DEVICE_ERROR The request was not completed
> because a failure reflected
> +                                  in the Host Status Register bit.  Device errors are
> +                                  a result of a transaction collision, illegal command
> field,
> +                                  unclaimed cycle (host initiated), or bus errors
> (collisions).
> +
> +**/
> +RETURN_STATUS
> +InternalSmBusStart (
> +  IN  UINT16                  IoPortBaseAddress,
> +  IN  UINT8                   HostControl
> +  )
> +{
> +  UINT8   HostStatus;
> +  UINT8   AuxiliaryStatus;
> +
> +  //
> +  // Set Host Control Register (Initiate Operation, Interrupt disabled).
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCTL, (UINT8)(HostControl +
> + B_SMBUS_IO_START));
> +
> +  do {
> +    //
> +    // Poll INTR bit of Host Status Register.
> +    //
> +    HostStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);  }
> + while ((HostStatus & (B_SMBUS_IO_INTR | B_SMBUS_IO_ERROR |
> + B_SMBUS_IO_BYTE_DONE_STS)) == 0);
> +
> +  if ((HostStatus & B_SMBUS_IO_ERROR) == 0) {
> +    return RETURN_SUCCESS;
> +  }
> +  //
> +  // Clear error bits of Host Status Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_ERROR);
> //
> + // Read Auxiliary Status Register to judge CRC error.
> +  //
> +  AuxiliaryStatus = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_AUXS);  if
> + ((AuxiliaryStatus & B_SMBUS_IO_CRCE) != 0) {
> +    return RETURN_CRC_ERROR;
> +  }
> +
> +  return RETURN_DEVICE_ERROR;
> +}
> +
> +/**
> +  Executes an SMBUS quick, byte or word command.
> +
> +  This internal function executes an SMBUS quick, byte or word commond.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +
> +  @param[in]  HostControl     The value of Host Control Register to set.
> +  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave
> Address,
> +                              SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  Value           The byte/word write to the SMBUS.
> +  @param[out] Status          Return status for the executed command.
> +                              This is an optional parameter and may be NULL.
> +
> +  @retval The byte/word read from the SMBUS.
> +
> +**/
> +UINT16
> +InternalSmBusNonBlock (
> +  IN  UINT8                     HostControl,
> +  IN  UINTN                     SmBusAddress,
> +  IN  UINT16                    Value,
> +  OUT RETURN_STATUS             *Status
> +  )
> +{
> +  RETURN_STATUS                 ReturnStatus;
> +  UINT16                        IoPortBaseAddress;
> +  UINT8                         AuxiliaryControl;
> +
> +  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
> +
> +  //
> +  // Try to acquire the ownership of SMBUS.
> +  //
> +  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);  if
> + (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +  //
> +  // Set the appropriate Host Control Register and auxiliary Control Register.
> +  //
> +  AuxiliaryControl = 0;
> +  if (SMBUS_LIB_PEC (SmBusAddress)) {
> +    AuxiliaryControl |= B_SMBUS_IO_AAC;  }  //  // Set Host Commond
> + Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8)
> + SMBUS_LIB_COMMAND (SmBusAddress));  //  // Write value to Host Data 0
> + and Host Data 1 Registers.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) Value);
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD1, (UINT8) (Value >> 8));
> + //  // Set Auxiliary Control Regiester.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl);  //
> + // Set SMBUS slave address for the device to send/receive from.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress);
> + //  // Start the SMBUS transaction and wait for the end.
> +  //
> +  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
> + //  // Read value from Host Data 0 and Host Data 1 Registers.
> +  //
> +  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD1) << 8);
> + Value = (UINT16)(Value | IoRead8 (IoPortBaseAddress +
> + R_SMBUS_IO_HD0));  //  // Clear Host Status Register and Auxiliary
> + Status Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS,
> B_SMBUS_IO_HSTS_ALL);
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE);
> +
> +Done:
> +  if (Status != NULL) {
> +    *Status = ReturnStatus;
> +  }
> +
> +  return Value;
> +}
> +
> +/**
> +  Executes an SMBUS quick read command.
> +
> +  Executes an SMBUS quick read command on the SMBUS device specified by
> SmBusAddress.
> +  Only the SMBUS slave address field of SmBusAddress is required.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If PEC is set in SmBusAddress, then ASSERT().
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +**/
> +VOID
> +EFIAPI
> +SmBusQuickRead (
> +  IN  UINTN                     SmBusAddress,
> +  OUT RETURN_STATUS             *Status       OPTIONAL
> +  )
> +{
> +  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if (SMBUS_LIB_PEC (SmBusAddress)           ||
> +    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return;
> +  }
> +
> +  InternalSmBusNonBlock (
> +    V_SMBUS_IO_SMB_CMD_QUICK,
> +    SmBusAddress | B_SMBUS_IO_READ,
> +    0,
> +    Status
> +    );
> +}
> +
> +/**
> +  Executes an SMBUS quick write command.
> +
> +  Executes an SMBUS quick write command on the SMBUS device specified by
> SmBusAddress.
> +  Only the SMBUS slave address field of SmBusAddress is required.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If PEC is set in SmBusAddress, then ASSERT().
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +**/
> +VOID
> +EFIAPI
> +SmBusQuickWrite (
> +  IN  UINTN                     SmBusAddress,
> +  OUT RETURN_STATUS             *Status       OPTIONAL
> +  )
> +{
> +  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if (SMBUS_LIB_PEC (SmBusAddress)           ||
> +    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return;
> +  }
> +
> +  InternalSmBusNonBlock (
> +    V_SMBUS_IO_SMB_CMD_QUICK,
> +    SmBusAddress | B_SMBUS_IO_WRITE,
> +    0,
> +    Status
> +    );
> +}
> +
> +/**
> +  Executes an SMBUS receive byte command.
> +
> +  Executes an SMBUS receive byte command on the SMBUS device specified
> by SmBusAddress.
> +  Only the SMBUS slave address field of SmBusAddress is required.
> +  The byte received from the SMBUS is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The byte received from the SMBUS.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusReceiveByte (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return (UINT8) InternalSmBusNonBlock (
> +                   V_SMBUS_IO_SMB_CMD_BYTE,
> +                   SmBusAddress | B_SMBUS_IO_READ,
> +                   0,
> +                   Status
> +                   );
> +}
> +
> +/**
> +  Executes an SMBUS send byte command.
> +
> +  Executes an SMBUS send byte command on the SMBUS device specified by
> SmBusAddress.
> +  The byte specified by Value is sent.
> +  Only the SMBUS slave address field of SmBusAddress is required.  Value is
> returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Command in SmBusAddress is not zero, then ASSERT().
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  Value         The 8-bit value to send.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The parameter of Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusSendByte (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT8          Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return (UINT8) InternalSmBusNonBlock (
> +                   V_SMBUS_IO_SMB_CMD_BYTE,
> +                   SmBusAddress | B_SMBUS_IO_WRITE,
> +                   Value,
> +                   Status
> +                   );
> +}
> +
> +/**
> +  Executes an SMBUS read data byte command.
> +
> +  Executes an SMBUS read data byte command on the SMBUS device specified
> by SmBusAddress.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  The 8-bit value read from the SMBUS is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave
> Address,
> +                              SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Status          Return status for the executed command.
> +                              This is an optional parameter and may be NULL.
> +
> +  @retval The byte read from the SMBUS.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusReadDataByte (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return (UINT8) InternalSmBusNonBlock (
> +                   V_SMBUS_IO_SMB_CMD_BYTE_DATA,
> +                   SmBusAddress | B_SMBUS_IO_READ,
> +                   0,
> +                   Status
> +                   );
> +}
> +
> +/**
> +  Executes an SMBUS write data byte command.
> +
> +  Executes an SMBUS write data byte command on the SMBUS device
> specified by SmBusAddress.
> +  The 8-bit value specified by Value is written.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  Value is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  Value         The 8-bit value to write.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The parameter of Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusWriteDataByte (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT8          Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return (UINT8) InternalSmBusNonBlock (
> +                   V_SMBUS_IO_SMB_CMD_BYTE_DATA,
> +                   SmBusAddress | B_SMBUS_IO_WRITE,
> +                   Value,
> +                   Status
> +                   );
> +}
> +
> +/**
> +  Executes an SMBUS read data word command.
> +
> +  Executes an SMBUS read data word command on the SMBUS device
> specified by SmBusAddress.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  The 16-bit value read from the SMBUS is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The byte read from the SMBUS.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusReadDataWord (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return InternalSmBusNonBlock (
> +           V_SMBUS_IO_SMB_CMD_WORD_DATA,
> +           SmBusAddress | B_SMBUS_IO_READ,
> +           0,
> +           Status
> +           );
> +}
> +
> +/**
> +  Executes an SMBUS write data word command.
> +
> +  Executes an SMBUS write data word command on the SMBUS device
> specified by SmBusAddress.
> +  The 16-bit value specified by Value is written.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  Value is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  Value         The 16-bit value to write.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The parameter of Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusWriteDataWord (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT16         Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return InternalSmBusNonBlock (
> +           V_SMBUS_IO_SMB_CMD_WORD_DATA,
> +           SmBusAddress | B_SMBUS_IO_WRITE,
> +           Value,
> +           Status
> +           );
> +}
> +
> +/**
> +  Executes an SMBUS process call command.
> +
> +  Executes an SMBUS process call command on the SMBUS device specified by
> SmBusAddress.
> +  The 16-bit value specified by Value is written.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  The 16-bit value returned by the process call command is returned.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  Value         The 16-bit value to write.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The 16-bit value returned by the process call command.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusProcessCall (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT16         Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return InternalSmBusNonBlock (
> +           V_SMBUS_IO_SMB_CMD_PROCESS_CALL,
> +           SmBusAddress | B_SMBUS_IO_WRITE,
> +           Value,
> +           Status
> +           );
> +}
> +
> +/**
> +  Executes an SMBUS block command.
> +
> +  Executes an SMBUS block read, block write and block write-block read
> + command  on the SMBUS device specified by SmBusAddress.
> +  Bytes are read from the SMBUS and stored in Buffer.
> +  The number of bytes read is returned, and will never return a value larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  It is the caller's responsibility to make sure Buffer is large enough for the
> total number of bytes read.
> +  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not
> need to be any larger than 32 bytes.
> +
> +  @param[in]  HostControl     The value of Host Control Register to set.
> +  @param[in]  SmBusAddress    Address that encodes the SMBUS Slave
> Address,
> +                              SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  WriteBuffer     Pointer to the buffer of bytes to write to the
> SMBUS.
> +  @param[out] ReadBuffer      Pointer to the buffer of bytes to read from the
> SMBUS.
> +  @param[out] Status          Return status for the executed command.
> +                              This is an optional parameter and may be NULL.
> +
> +  @retval The number of bytes read from the SMBUS.
> +
> +**/
> +UINTN
> +InternalSmBusBlock (
> +  IN  UINT8                     HostControl,
> +  IN  UINTN                     SmBusAddress,
> +  IN  UINT8                     *WriteBuffer,
> +  OUT UINT8                     *ReadBuffer,
> +  OUT RETURN_STATUS             *Status
> +  )
> +{
> +  RETURN_STATUS                 ReturnStatus;
> +  UINTN                         Index;
> +  UINTN                         BytesCount;
> +  UINT16                        IoPortBaseAddress;
> +  UINT8                         AuxiliaryControl;
> +
> +  IoPortBaseAddress = InternalGetSmbusIoPortBaseAddress ();
> +
> +  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
> +
> +  //
> +  // Try to acquire the ownership of SMBUS.
> +  //
> +  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);  if
> + (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +  //
> +  // Set the appropriate Host Control Register and auxiliary Control Register.
> +  //
> +  AuxiliaryControl = B_SMBUS_IO_E32B;
> +  if (SMBUS_LIB_PEC (SmBusAddress)) {
> +    AuxiliaryControl |= B_SMBUS_IO_AAC;  }  //  // Set Host Command
> + Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8)
> + SMBUS_LIB_COMMAND (SmBusAddress));  //  // Set Auxiliary Control
> + Regiester.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl);  //
> + // Clear byte pointer of 32-byte buffer.
> +  //
> +  IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HCTL);
> +
> +  if (WriteBuffer != NULL) {
> +    //
> +    // Write the number of block to Host Block Data Byte Register.
> +    //
> +    IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) BytesCount);
> +    //
> +    // Write data block to Host Block Data Register.
> +    //
> +    for (Index = 0; Index < BytesCount; Index++) {
> +      IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HBD, WriteBuffer[Index]);
> +    }
> +  }
> +  //
> +  // Set SMBUS slave address for the device to send/receive from.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress);
> + //  // Start the SMBUS transaction and wait for the end.
> +  //
> +  ReturnStatus = InternalSmBusStart (IoPortBaseAddress, HostControl);
> + if (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +
> +  if (ReadBuffer != NULL) {
> +    //
> +    // Read the number of block from host block data byte register.
> +    //
> +    BytesCount = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD0);
> +    //
> +    // Write data block from Host Block Data Register.
> +    //
> +    for (Index = 0; Index < BytesCount; Index++) {
> +      ReadBuffer[Index] = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HBD);
> +    }
> +  }
> +
> +Done:
> +  //
> +  // Clear Host Status Register and Auxiliary Status Register.
> +  //
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS,
> B_SMBUS_IO_HSTS_ALL);
> +  IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE);
> +
> +  if (Status != NULL) {
> +    *Status = ReturnStatus;
> +  }
> +
> +  return BytesCount;
> +}
> +
> +/**
> +  Executes an SMBUS read block command.
> +
> +  Executes an SMBUS read block command on the SMBUS device specified by
> SmBusAddress.
> +  Only the SMBUS slave address and SMBUS command fields of
> SmBusAddress are required.
> +  Bytes are read from the SMBUS and stored in Buffer.
> +  The number of bytes read is returned, and will never return a value larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  It is the caller's responsibility to make sure Buffer is large enough for the
> total number of bytes read.
> +  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not
> need to be any larger than 32 bytes.
> +  If Length in SmBusAddress is not zero, then ASSERT().
> +  If Buffer is NULL, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Buffer        Pointer to the buffer to store the bytes read from
> the SMBUS.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The number of bytes read.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusReadBlock (
> +  IN  UINTN          SmBusAddress,
> +  OUT VOID           *Buffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (Buffer != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((Buffer == NULL)                         ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return InternalSmBusBlock (
> +           V_SMBUS_IO_SMB_CMD_BLOCK,
> +           SmBusAddress | B_SMBUS_IO_READ,
> +           NULL,
> +           Buffer,
> +           Status
> +           );
> +}
> +
> +/**
> +  Executes an SMBUS write block command.
> +
> +  Executes an SMBUS write block command on the SMBUS device specified by
> SmBusAddress.
> +  The SMBUS slave address, SMBUS command, and SMBUS length fields of
> SmBusAddress are required.
> +  Bytes are written to the SMBUS from Buffer.
> +  The number of bytes written is returned, and will never return a value larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
> +  If Buffer is NULL, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[out] Buffer        Pointer to the buffer to store the bytes read from
> the SMBUS.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The number of bytes written.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusWriteBlock (
> +  IN  UINTN          SmBusAddress,
> +  OUT VOID           *Buffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (Buffer != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((Buffer == NULL)                         ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return InternalSmBusBlock (
> +           V_SMBUS_IO_SMB_CMD_BLOCK,
> +           SmBusAddress | B_SMBUS_IO_WRITE,
> +           Buffer,
> +           NULL,
> +           Status
> +           );
> +}
> +
> +/**
> +  Executes an SMBUS block process call command.
> +
> +  Executes an SMBUS block process call command on the SMBUS device
> specified by SmBusAddress.
> +  The SMBUS slave address, SMBUS command, and SMBUS length fields of
> SmBusAddress are required.
> +  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from
> the SMBUS into ReadBuffer.
> +  If Status is not NULL, then the status of the executed command is returned
> in Status.
> +  It is the caller's responsibility to make sure ReadBuffer is large enough for
> the total number of bytes read.
> +  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not
> need to be any larger than 32 bytes.
> +  If Length in SmBusAddress is zero or greater than 32, then ASSERT().
> +  If WriteBuffer is NULL, then ASSERT().
> +  If ReadBuffer is NULL, then ASSERT().
> +  If any reserved bits of SmBusAddress are set, then ASSERT().
> +
> +  @param[in]  SmBusAddress  Address that encodes the SMBUS Slave
> Address,
> +                            SMBUS Command, SMBUS Data Length, and PEC.
> +  @param[in]  WriteBuffer   Pointer to the buffer of bytes to write to the
> SMBUS.
> +  @param[out] ReadBuffer    Pointer to the buffer of bytes to read from the
> SMBUS.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The number of bytes written.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusBlockProcessCall (
> +  IN  UINTN          SmBusAddress,
> +  IN  VOID           *WriteBuffer,
> +  OUT VOID           *ReadBuffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (WriteBuffer != NULL);
> +  ASSERT (ReadBuffer  != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((WriteBuffer == NULL)                    ||
> +      (ReadBuffer  == NULL)                    ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = RETURN_INVALID_PARAMETER;
> +    }
> +    return 0;
> +  }
> +
> +  return InternalSmBusBlock (
> +           V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS,
> +           SmBusAddress | B_SMBUS_IO_WRITE,
> +           WriteBuffer,
> +           ReadBuffer,
> +           Status
> +           );
> +}
> +
> +/**
> +  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.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +BaseSmbusLibConstructor (
> +  VOID
> +  )
> +{
> +  UINT64    SmbusPciBase;
> +  UINT16    IoPortBaseAddress;
> +
> +  //
> +  // Init mSmbusIoBase variable.
> +  //
> +  SmbusPciBase = PCI_SEGMENT_LIB_ADDRESS (
> +                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_SMBUS,
> +                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
> +                   0
> +                   );
> +  IoPortBaseAddress = (UINT16) PciSegmentRead32 (SmbusPciBase +
> + R_SMBUS_CFG_BASE);
> +
> +  if ((IoPortBaseAddress != 0) && (IoPortBaseAddress != 0xFFFF)) {
> +    mSmbusIoBase = IoPortBaseAddress & B_SMBUS_CFG_BASE_BAR;  }
> +
> +  return RETURN_SUCCESS;
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:13 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI
> library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH PEI library class instances. These libraries may also be
> compatible in other boot phases as indicated by the library type.
> 
> * PeiDxeSmmBiosLockLib
> * PeiDxeSmmGpioLib
> * PeiDxeSmmPchCycleDecodingLib
> * PeiDxeSmmPchDmiWithS3Lib
> * PeiDxeSmmPchEspiLib
> * PeiDxeSmmPchGbeLib
> * PeiDxeSmmPchHsioLib
> * PeiDxeSmmPchInfoLib
> * PeiDxeSmmPchPcieRpLib
> * PeiDxeSmmPchPcrLib
> * PeiDxeSmmPchPmcLib
> * PeiDxeSmmPchSbiAccessLib
> * PeiDxeSmmPchSerialIoLib
> * PeiDxeSmmPchSerialIoUartLib
> * PeiDxeSmmPchWdtCommonLib
> * PeiDxeSmmPmcLib
> * PeiDxeSmmSataLib
> * PeiOcWdtLib
> * PeiOcWdtLibNull
> * PeiPchPolicyLib
> * PeiPchResetLib
> * PeiResetSystemLib
> * PeiSpiLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDx
> eSmmBiosLockLib.inf                 |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSm
> mGpioLib.inf                         |   48 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingL
> ib/PeiDxeSmmPchCycleDecodingLib.inf |   42 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxe
> SmmPchEspiLib.inf                   |   38 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxe
> SmmPchGbeLib.inf                     |   38 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxe
> SmmPchHsioLib.inf                   |   37 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxe
> SmmPchInfoLibCnl.inf                |   42 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiD
> xeSmmPchPcieRpLib.inf               |   37 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeS
> mmPchPcrLib.inf                     |   35 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxe
> SmmPchPmcLib.inf                     |   36 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/P
> eiDxeSmmPchSbiAccessLib.inf         |   35 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pei
> DxeSmmPchSerialIoLibCnl.inf        |   39 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib
> /PeiDxeSmmPchSerialIoUartLib.inf   |   35 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLi
> b/PeiDxeSmmPchWdtCommonLib.inf         |   31 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSm
> mPmcLib.inf                           |   43 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSm
> mSataLibCnl.inf                      |   32 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
> |   39 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLib
> Null.inf                           |   24 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLi
> bCnl.inf                        |   86 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLi
> b.inf                             |   41 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSy
> stemLib.inf                       |   49 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
> |   42 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibra
> ry.h                                |  117 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfo
> LibPrivate.h                       |   45 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pch
> SerialIoLibInternal.h              |   16 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLi
> brary.h                         |   35 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLo
> ckLib.c                            |   98 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
> |  553 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
> | 2710 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNam
> es.c                                  |   87 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativ
> eLib.c                              |  234 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingL
> ib/PchCycleDecodingLib.c            | 1136 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEsp
> iLib.c                              |  505 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGb
> eLib.c                                |   82 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsi
> oLib.c                              |  127 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfo
> Lib.c                              |  272 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfo
> LibClient.c                        |   87 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfo
> LibCnl.c                           |  386 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchP
> cieRpLib.c                          |  183 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLi
> b.c                                |  279 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPm
> cLib.c                                |  101 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/P
> chSbiAccessLib.c                    |  270 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pch
> SerialIoLib.c                      |  516 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pch
> SerialIoLibCnl.c                   |  181 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib
> /PeiDxeSmmPchSerialIoUartLib.c     |  372 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLi
> b/WdtCommon.c                          |  242 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
> |  330 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
> |   41 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf
> .c                                 |  101 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl
> .c                                 |   88 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
> |  130 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLib
> Null.c                             |   23 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPr
> intPolicy.c                        |  307 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy
> .c                              |  778 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLi
> b.c                             |  739 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLi
> bCnl.c                          |  169 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMe
> mPolicyLib.c                       |  318 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
> |  109 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSy
> stemLib.c                         |  257 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
> |  217 ++
>  60 files changed, 13130 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Pei
> DxeSmmBiosLockLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Pei
> DxeSmmBiosLockLib.inf
> new file mode 100644
> index 0000000000..6db81f6cf3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Pei
> DxeSmmBiosLockLib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# BIOS LOCK library.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmBiosLockLib
> +FILE_GUID = 64EBA6B1-CC36-4C2E-A0F5-D90199432E6C
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = BiosLockLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +DebugLib
> +PcdLib
> +PciSegmentLib
> +S3BootScriptLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +BiosLockLib.c
> +
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS
> mmGpioLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS
> mmGpioLib.inf
> new file mode 100644
> index 0000000000..00d06591fc
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS
> mmGpioLib.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# Component description file for the PeiDxeSmmGpioLib
> +#
> +# Copyright (c) 2019 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
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +GpioLib.c
> +GpioLibrary.h
> +GpioNativeLib.c
> +GpioInit.c
> +GpioNames.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi
> ngLib/PeiDxeSmmPchCycleDecodingLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi
> ngLib/PeiDxeSmmPchCycleDecodingLib.inf
> new file mode 100644
> index 0000000000..2a53f42004
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi
> ngLib/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) 2019 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
> +PchEspiLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +PcAtChipsetPkg/PcAtChipsetPkg.dec
> +
> +[Sources]
> +PchCycleDecodingLib.c
> +
> +[Pcd]
> +gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress          ## CONSUMES
> +gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress        ## CONSUMES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiD
> xeSmmPchEspiLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiD
> xeSmmPchEspiLib.inf
> new file mode 100644
> index 0000000000..a775210984
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiD
> xeSmmPchEspiLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# Component description file for the PeiDxeSmmPchEspiLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchEspiLib
> +FILE_GUID = 7F25F990-7989-4413-B414-1EDE557E9389
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchEspiLib
> +#
> +# 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
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchEspiLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiD
> xeSmmPchGbeLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiD
> xeSmmPchGbeLib.inf
> new file mode 100644
> index 0000000000..a685104249
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiD
> xeSmmPchGbeLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# PCH Gbe Library.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchGbeLib
> +FILE_GUID = FC022ED0-6EB3-43E1-A740-0BA27CBBD010
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchGbeLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +PciSegmentLib
> +PchInfoLib
> +PchPcrLib
> +PchCycleDecodingLib
> +PmcPrivateLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchGbeLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiD
> xeSmmPchHsioLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiD
> xeSmmPchHsioLib.inf
> new file mode 100644
> index 0000000000..7c67e0fa20
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiD
> xeSmmPchHsioLib.inf
> @@ -0,0 +1,37 @@
> +## @file
> +# PCH HSIO Library.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchHsioLib
> +FILE_GUID = 6B2D3D0D-9A04-4E7C-AE84-1C2EF2E00E2E
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchHsioLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +MmPciLib
> +PchInfoLib
> +PchPcrLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchHsioLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDx
> eSmmPchInfoLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiD
> xeSmmPchInfoLibCnl.inf
> new file mode 100644
> index 0000000000..b9781de810
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiD
> xeSmmPchInfoLibCnl.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# PCH information library for PCH.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchInfoLibCnl
> +FILE_GUID = 455CD363-0E78-46B7-8DD3-634003F1614F
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchInfoLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +PrintLib
> +PciSegmentLib
> +PchPcrLib
> +PmcPrivateLib
> +PcdLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchInfoLib.c
> +PchInfoLibClient.c
> +PchInfoLibCnl.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pe
> iDxeSmmPchPcieRpLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pe
> iDxeSmmPchPcieRpLib.inf
> new file mode 100644
> index 0000000000..b1ee095423
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pe
> iDxeSmmPchPcieRpLib.inf
> @@ -0,0 +1,37 @@
> +## @file
> +# PCH 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) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchPcieRpLib
> +FILE_GUID = B4129C2C-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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchPcieRpLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDx
> eSmmPchPcrLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDx
> eSmmPchPcrLib.inf
> new file mode 100644
> index 0000000000..0244e1c0c8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDx
> eSmmPchPcrLib.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) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchPcrLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiD
> xeSmmPchPmcLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiD
> xeSmmPchPmcLib.inf
> new file mode 100644
> index 0000000000..3b1f1e467b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiD
> xeSmmPchPmcLib.inf
> @@ -0,0 +1,36 @@
> +## @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) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchPmcLib
> +FILE_GUID = 9D60C364-5086-41E3-BC9D-C62AB7233DBF
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchPmcLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +MmPciLib
> +PchCycleDecodingLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchPmcLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib
> /PeiDxeSmmPchSbiAccessLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib
> /PeiDxeSmmPchSbiAccessLib.inf
> new file mode 100644
> index 0000000000..ceb109168b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib
> /PeiDxeSmmPchSbiAccessLib.inf
> @@ -0,0 +1,35 @@
> +## @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) 2019 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
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchSbiAccessLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> eiDxeSmmPchSerialIoLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> eiDxeSmmPchSerialIoLibCnl.inf
> new file mode 100644
> index 0000000000..3bfada0b22
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> eiDxeSmmPchSerialIoLibCnl.inf
> @@ -0,0 +1,39 @@
> +## @file
> +# Component description file for PEI/DXE/SMM PCH Serial IO Lib.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchSerialIoLibCnl
> +FILE_GUID = 613A22A2-5736-40f8-909B-DF10EA389C72
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchSerialIoLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +PcdLib
> +PciSegmentLib
> +GpioPrivateLib
> +PchPcrLib
> +PchSerialIoUartLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchSerialIoLib.c
> +PchSerialIoLibCnl.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartL
> ib/PeiDxeSmmPchSerialIoUartLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartL
> ib/PeiDxeSmmPchSerialIoUartLib.inf
> new file mode 100644
> index 0000000000..1becfc7a96
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartL
> ib/PeiDxeSmmPchSerialIoUartLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +# Component description file for PCH Serial IO UART Lib.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchSerialIoUartLib
> +FILE_GUID = 55463A54-FD0D-4e8e-8D57-D54FAAEFDC2F
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchSerialIoUartLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +PchSerialIoLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PeiDxeSmmPchSerialIoUartLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo
> nLib/PeiDxeSmmPchWdtCommonLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo
> nLib/PeiDxeSmmPchWdtCommonLib.inf
> new file mode 100644
> index 0000000000..8a01a749bf
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo
> nLib/PeiDxeSmmPchWdtCommonLib.inf
> @@ -0,0 +1,31 @@
> +## @file
> +#  Component description file for the PchWdtCommonLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiDxeSmmPchWdtCommonLib
> +  FILE_GUID                      = 171F78D2-0A52-4692-8830-AB693791EA23
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PchWdtCommonLib
> +
> +[Sources]
> +  WdtCommon.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  IoLib
> +  DebugLib
> +  PmcLib
> +
> +[Pcd]
> +  gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug           ## CONSUMES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeS
> mmPmcLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeS
> mmPmcLib.inf
> new file mode 100644
> index 0000000000..78e212eeb0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeS
> mmPmcLib.inf
> @@ -0,0 +1,43 @@
> +## @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) 2019 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
> +PmcPrivateLib
> +BaseMemoryLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
> +
> +
> +[Sources]
> +PmcLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeS
> mmSataLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeS
> mmSataLibCnl.inf
> new file mode 100644
> index 0000000000..128b348b3d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeS
> mmSataLibCnl.inf
> @@ -0,0 +1,32 @@
> +## @file
> +# PEI/DXE/SMM PCH SATA library for Cannon Lake PCH.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchSataLibCnl
> +FILE_GUID = 5163ECE3-5372-47E1-B057-2282E753DD55
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = SataLib
> +
> +[LibraryClasses]
> +BaseLib
> +PciSegmentLib
> +PchInfoLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +SataLib.c
> +SataLibCnl.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.i
> nf
> new file mode 100644
> index 0000000000..37d0c80ea4
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.i
> nf
> @@ -0,0 +1,39 @@
> +## @file
> +# Component Description File for OcWdt Support.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiOcWdtLib
> +FILE_GUID = D5207C23-3632-4078-A671-3B5C364B2BDB
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = OcWdtLib
> +
> +
> +[LibraryClasses]
> +IoLib
> +DebugLib
> +PeiServicesLib
> +PchWdtCommonLib
> +PmcLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PeiOcWdtLib.c
> +
> +
> +[Ppis]
> +gWdtPpiGuid  ## PRODUCES
> +
> +[Pcd]
> +gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug           ## CONSUMES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt
> LibNull.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt
> LibNull.inf
> new file mode 100644
> index 0000000000..68ff41ef7f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt
> LibNull.inf
> @@ -0,0 +1,24 @@
> +## @file
> +# Component Description File for OcWdt Support.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiOcWdtLib
> +FILE_GUID = DB65B36B-E276-4A2b-AB20-61764889E483
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = OcWdtLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +
> +
> +[Sources]
> +PeiOcWdtLibNull.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibCnl.inf
> new file mode 100644
> index 0000000000..49e63cfc51
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibCnl.inf
> @@ -0,0 +1,86 @@
> +## @file
> +# Component description file for the PeiPchPolicy libbrary.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiPchPolicyLibCnl
> +FILE_GUID = BB1AC992-B2CA-4744-84B7-915C185576C5
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = PchPolicyLib
> +
> +
> +[LibraryClasses]
> +DebugLib
> +IoLib
> +PcdLib
> +PeiServicesLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +PchInfoLib
> +ConfigBlockLib
> +SiConfigBlockLib
> +SataLib
> +PchPcieRpLib
> +CpuPlatformLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber
> +
> +
> +[Sources]
> +PeiPchPolicyLib.c
> +PeiPchPolicyLibCnl.c
> +PeiPchPolicyLibrary.h
> +PeiPchPreMemPolicyLib.c
> +PchPrintPolicy.c
> +PchPreMemPrintPolicy.c
> +
> +[Guids]
> +gPchGeneralConfigGuid              ## CONSUMES
> +gPcieRpConfigGuid                  ## CONSUMES
> +gSataConfigGuid                    ## CONSUMES
> +gIoApicConfigGuid                  ## CONSUMES
> +gDmiConfigGuid                     ## CONSUMES
> +gFlashProtectionConfigGuid         ## CONSUMES
> +gHdAudioConfigGuid                 ## CONSUMES
> +gInterruptConfigGuid               ## CONSUMES
> +gIshConfigGuid                     ## CONSUMES
> +gLanConfigGuid                     ## CONSUMES
> +gLockDownConfigGuid                ## CONSUMES
> +gP2sbConfigGuid                    ## CONSUMES
> +gPmConfigGuid                      ## CONSUMES
> +gScsConfigGuid                     ## CONSUMES
> +gSerialIoConfigGuid                ## CONSUMES
> +gSerialIrqConfigGuid               ## CONSUMES
> +gThermalConfigGuid                 ## CONSUMES
> +gUsbConfigGuid                     ## CONSUMES
> +gEspiConfigGuid                    ## CONSUMES
> +gCnviConfigGuid                    ## CONSUMES
> +gHsioConfigGuid                    ## CONSUMES
> +gPchGeneralPreMemConfigGuid        ## COMSUMES
> +gDciPreMemConfigGuid               ## CONSUMES
> +gWatchDogPreMemConfigGuid          ## CONSUMES
> +gPchTraceHubPreMemConfigGuid       ## CONSUMES
> +gSmbusPreMemConfigGuid             ## CONSUMES
> +gLpcPreMemConfigGuid               ## CONSUMES
> +gHsioPciePreMemConfigGuid          ## CONSUMES
> +gHsioSataPreMemConfigGuid          ## CONSUMES
> +gPcieRpPreMemConfigGuid            ## CONSUMES
> +gHdAudioPreMemConfigGuid           ## CONSUMES
> +gIshPreMemConfigGuid               ## CONSUMES
> +
> +[Ppis]
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchReset
> Lib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchReset
> Lib.inf
> new file mode 100644
> index 0000000000..41e339a2e8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchReset
> Lib.inf
> @@ -0,0 +1,41 @@
> +## @file
> +# Component description file for PCH Reset Lib Pei Phase
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiPchResetLib
> +FILE_GUID = DB91FFF0-5B99-4A88-9EC8-183A2106DCA2
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = PchResetLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +DebugLib
> +PeiServicesLib
> +PeiServicesTablePointerLib
> +MemoryAllocationLib
> +ResetSystemLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchReset.c
> +
> +[Ppis]
> +gEfiPeiReset2PpiGuid ## PRODUCES
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset
> SystemLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset
> SystemLib.inf
> new file mode 100644
> index 0000000000..f8f8bf1b66
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset
> SystemLib.inf
> @@ -0,0 +1,49 @@
> +## @file
> +# Component description file for Intel Ich7 Reset System Library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiResetSystemLib
> +FILE_GUID = D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +UEFI_SPECIFICATION_VERSION = 2.00
> +LIBRARY_CLASS = ResetSystemLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +IoLib
> +DebugLib
> +BaseMemoryLib
> +PeiServicesLib
> +PmcLib
> +PmcPrivateLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PeiResetSystemLib.c
> +
> +
> +[Ppis]
> +gMeDidSentPpiGuid ## CONSUMES
> +gPchResetCallbackPpiGuid ## CONSUMES
> +
> +
> +[Guids]
> +gPchGlobalResetGuid
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
> new file mode 100644
> index 0000000000..fb2fad78d3
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# Component description file for PCH Reset Lib Pei Phase
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiSpiLib
> +FILE_GUID = 4998447D-7948-448F-AB75-96E24E18FF23
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = SpiLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF
> +#
> +
> +[LibraryClasses]
> +DebugLib
> +PeiServicesLib
> +PeiServicesTablePointerLib
> +MemoryAllocationLib
> +PciSegmentLib
> +PchSpiCommonLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchSpi.c
> +
> +
> +[Ppis]
> +gPchSpiPpiGuid ## PRODUCES
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib
> rary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib
> rary.h
> new file mode 100644
> index 0000000000..7a480b6cad
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib
> rary.h
> @@ -0,0 +1,117 @@
> +/** @file
> +  Header file for GPIO Lib implementation.
> +
> +  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PchSbiAccessLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Private/Library/GpioHelpersLib.h>
> +#include <Register/PchRegsGpio.h>
> +
> +// BIT15-0  - pad number
> +// BIT31-16 - group info
> +//   BIT23- 16 - group index
> +//   BIT31- 24 - chipset ID
> +#define PAD_INFO_MASK          0x0000FFFF
> +#define GROUP_INFO_POSITION    16
> +#define GROUP_INFO_MASK        0xFFFF0000
> +#define GROUP_INDEX_MASK       0x00FF0000
> +#define UNIQUE_ID_MASK         0xFF000000
> +#define UNIQUE_ID_POSITION     24
> +
> +#define GPIO_PAD_DEF(Group,Pad)               (UINT32)(((Group) << 16) +
> (Pad))
> +#define GPIO_GROUP_DEF(Index,ChipsetId)       ((Index) | ((ChipsetId) << 8))
> +#define GPIO_GET_GROUP_INDEX(Group)           ((Group) & 0xFF)
> +#define GPIO_GET_GROUP_FROM_PAD(Pad)          ((Pad) >> 16)
> +#define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad)
> GPIO_GET_GROUP_INDEX (((Pad) >> 16))
> +#define GPIO_GET_PAD_NUMBER(Pad)              ((Pad) & 0xFFFF)
> +#define GPIO_GET_CHIPSET_ID(Pad)              ((Pad) >> 24)
> +
> +#define GPIO_GET_PAD_POSITION(PadNumber)      ((PadNumber) % 32)
> +#define GPIO_GET_DW_NUM(PadNumber)            ((PadNumber) / 32u)
> +
> +//
> +// 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
> +**/
> +VOID
> +GpioPadCfgRegValueFromGpioConfig (
> +  IN  GPIO_PAD           GpioPad,
> +  IN  CONST GPIO_CONFIG  *GpioConfig,
> +  OUT UINT32             *PadCfgDwReg,
> +  OUT UINT32             *PadCfgDwRegMask
> +  );
> +
> +/**
> +  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_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchIn
> foLibPrivate.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLibPrivate.h
> new file mode 100644
> index 0000000000..79e03fef44
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLibPrivate.h
> @@ -0,0 +1,45 @@
> +/** @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) 2019 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;
> +};
> +
> +extern struct PCH_SKU_STRING mSkuStrs[];
> +
> +/**
> +  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
> +  );
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLibInternal.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLibInternal.h
> new file mode 100644
> index 0000000000..17e4bb863a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLibInternal.h
> @@ -0,0 +1,16 @@
> +/** @file
> +  Header file for PchSerialIoLibInternal.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_SERIAL_IO_LIB_INTERNAL_H_
> +#define _PCH_SERIAL_IO_LIB_INTERNAL_H_
> +
> +typedef struct {
> +  UINT8  DevNum;
> +  UINT8  FuncNum;
> +} SERIAL_IO_BDF_NUMBERS;
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibrary.h
> new file mode 100644
> index 0000000000..abd7e63365
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibrary.h
> @@ -0,0 +1,35 @@
> +/** @file
> +  Header file for the PeiPchPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_PCH_POLICY_LIBRARY_H_
> +#define _PEI_PCH_POLICY_LIBRARY_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/SiConfigBlockLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchPolicyLib.h>
> +
> +/**
> +  Adds interrupt configuration for device
> +
> +  @param[in/out] InterruptConfig         Pointer to interrupt config
> +**/
> +VOID
> +LoadDeviceInterruptConfig (
> +  IN OUT  PCH_INTERRUPT_CONFIG  *InterruptConfig
> +  );
> +
> +#endif // _PEI_PCH_POLICY_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Bios
> LockLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Bios
> LockLib.c
> new file mode 100644
> index 0000000000..20c024e893
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Bios
> LockLib.c
> @@ -0,0 +1,98 @@
> +/** @file
> +  Bios Lock library.
> +
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsSpi.h>
> +
> +/**
> +  Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable In
> SMM.STS).
> +  When this is set, attempts to write the WPD (Write Protect Disable) bit in
> PCH
> +  will cause a SMI which will allow the BIOS to verify that the write is from a
> valid source.
> +
> +  Bios should always enable LockDownConfig.BiosLock policy to set Bios Lock
> bit in FRC.
> +  If capsule udpate is enabled, it's expected to not do BiosLock by setting
> BiosLock policy disable
> +  so it can udpate BIOS region.
> +  After flash update, it should utilize this lib to do BiosLock for security.
> +**/
> +VOID
> +BiosLockEnable (
> +  VOID
> +  )
> +{
> +  UINT64  LpcBaseAddress;
> +  UINT64  SpiBaseAddress;
> +
> +  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_LPC,
> +                     PCI_FUNCTION_NUMBER_PCH_LPC,
> +                     0
> +                     );
> +  SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_SPI,
> +                     PCI_FUNCTION_NUMBER_PCH_SPI,
> +                     0
> +                     );
> +
> +  ///
> +  /// 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.
> +  ///
> +  PciSegmentOr8 (SpiBaseAddress + R_SPI_CFG_BC, B_SPI_CFG_BC_EISS |
> B_SPI_CFG_BC_LE);
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint8,
> +    PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC,
> +    1,
> +    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress
> + R_SPI_CFG_BC)
> +    );
> +  PciSegmentOr8 (LpcBaseAddress + R_LPC_CFG_BC, B_LPC_CFG_BC_EISS |
> B_LPC_CFG_BC_LE);
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint8,
> +    PcdGet64 (PcdPciExpressBaseAddress) + LpcBaseAddress +
> R_LPC_CFG_BC,
> +    1,
> +    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) +
> LpcBaseAddress + R_LPC_CFG_BC)
> +    );
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioIni
> t.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioIni
> t.c
> new file mode 100644
> index 0000000000..76eb3a9b81
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioIni
> t.c
> @@ -0,0 +1,553 @@
> +/** @file
> +  This file contains routines for GPIO initialization
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GpioLibrary.h"
> +#include <Register/PchRegsPcr.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.
> +//
> +// For Cannonlake only vGPIO group has >32 pads but those pads
> +// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be
> 1
> +//
> +#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.
> +**/
> +STATIC
> +VOID
> +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
> +          );
> +      }
> +    }
> +
> +  }
> +}
> +
> +/**
> +  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);
> +  GpioClearAllGpioInterrupts ();
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib
> .c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib
> .c
> new file mode 100644
> index 0000000000..0be50f75df
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib
> .c
> @@ -0,0 +1,2710 @@
> +/** @file
> +  This file contains routines for GPIO
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GpioLibrary.h"
> +#include <Register/PchRegsPcr.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
> +**/
> +STATIC
> +VOID
> +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) {
> +    *ReadVal = 0;
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // 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));
> +}
> +
> +/**
> +  This function determines if the group is SMI capable.
> +
> +  @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                    The function completed successfully
> +  @retval FALSE                   Setting SMI for a group is not supported
> +**/
> +STATIC
> +BOOLEAN
> +GpioIsSmiSupportedByGroupDw (
> +  IN GPIO_GROUP             Group,
> +  IN UINT32                 Dw
> +  )
> +{
> +  UINT32                 RegOffset;
> +  UINT32                 GroupIndex;
> +  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
> +  UINT32                 GpioGroupInfoLength;
> +
> +  GroupIndex = GpioGetGroupIndexFromGroup (Group);
> +
> +  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
> +
> +  RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
> +
> +  //
> +  // Check if selected register exists
> +  //
> +  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  This function determines if the group is NMI capable.
> +
> +  @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                    The function completed successfully
> +  @retval FALSE                   Setting NMI for a group is not supported
> +**/
> +STATIC
> +BOOLEAN
> +GpioIsNmiSupportedByGroupDw (
> +  IN GPIO_GROUP             Group,
> +  IN UINT32                 Dw
> +  )
> +{
> +  UINT32                 RegOffset;
> +  UINT32                 GroupIndex;
> +  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
> +  UINT32                 GpioGroupInfoLength;
> +
> +  GroupIndex = GpioGetGroupIndexFromGroup (Group);
> +
> +  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
> +
> +  RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
> +
> +  //
> +  // Check if selected register exists
> +  //
> +  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  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
> +**/
> +STATIC
> +VOID
> +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;
> +  EFI_STATUS             Status;
> +
> +  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;
> +  }
> +
> +  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
> +        //
> +        Status = GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
> +        if (EFI_ERROR (Status)) {
> +          ASSERT (FALSE);
> +          return;
> +        }
> +      } 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
> +    //
> +    Status = GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT (FALSE);
> +      return;
> +    }
> +  }
> +}
> +
> +/**
> +  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;
> +
> +  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;
> +
> +  Status = PchSbiExecutionEx (
> +             GpioGroupInfo[GroupIndex].Community,
> +             RegOffset,
> +             GpioLockUnlock,
> +             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  GppPadRstCfgToGpioResetConfigMap[] = {
> +                              GpioResumeReset,
> +                              GpioHostDeepReset,
> +                              GpioPlatformReset};
> +  static GPIO_RESET_CONFIG  GpdPadRstCfgToGpioResetConfigMap[] = {
> +                              GpioDswReset,
> +                              GpioHostDeepReset,
> +                              GpioPlatformReset,
> +                              GpioResumeReset};
> +
> +  Group = GpioGetGroupFromGpioPad (GpioPad);
> +
> +  if (GpioIsDswGroup (Group) && PadRstCfg < 4) {
> +    return GpdPadRstCfgToGpioResetConfigMap[PadRstCfg];
> +  } else if (PadRstCfg < 3) {
> +    return GppPadRstCfgToGpioResetConfigMap[PadRstCfg];
> +  } else {
> +    ASSERT (FALSE);
> +    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) | 0x1;
> +
> +  //
> +  // Read PADCFGLOCKTX register
> +  //
> +  GpioReadReg (
> +    GpioPadLockOutputRegister,
> +    Group,
> +    GPIO_GET_DW_NUM (PadNumber),
> +    &RegVal
> +    );
> +
> +  //
> +  // Get Pad Configuration Lock Tx state
> +  //
> +  GpioData->LockConfig |= ((!((RegVal >> PadBitPosition) & 0x1)) << 2) | 0x1;
> +
> +  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
> +**/
> +VOID
> +GpioPadCfgRegValueFromGpioConfig (
> +  IN  GPIO_PAD           GpioPad,
> +  IN  CONST GPIO_CONFIG  *GpioConfig,
> +  OUT UINT32             *PadCfgDwReg,
> +  OUT UINT32             *PadCfgDwRegMask
> +  )
> +{
> +  UINT32               PadRstCfg;
> +  EFI_STATUS           Status;
> +
> +  //
> +  // Configure Reset Type (PadRstCfg)
> +  // Reset configuration depends on group type.
> +  // This field requires support for new and deprecated settings.
> +  //
> +  Status = GpioPadRstCfgFromResetConfig (
> +             GpioPad,
> +             GpioConfig->PowerConfig,
> +             &PadRstCfg
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  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);
> +}
> +
> +/**
> +  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;
> +
> +  Status = EFI_SUCCESS;
> +  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;
> +
> +  if (GpioIsNmiSupportedByGroupDw (Group, DwNum)) {
> +    GpioWriteReg (
> +      GpioNmiEnableRegister,
> +      Group,
> +      DwNum,
> +      ~GpiNmiEnRegMask,
> +      GpiNmiEnReg
> +      );
> +  } else {
> +    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 EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Update value to be programmed in GPI_SMI_EN register
> +  //
> +  GpiSmiEnRegMask = (GpioData->InterruptConfig & 0x1) << PadBitPosition;
> +  GpiSmiEnReg = ((GpioData->InterruptConfig & GpioIntSmi) >> 2) <<
> PadBitPosition;
> +
> +  if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) {
> +    GpioWriteReg (
> +      GpioSmiEnableRegister,
> +      Group,
> +      DwNum,
> +      ~GpiSmiEnRegMask,
> +      GpiSmiEnReg
> +      );
> +  } else {
> +    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 EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // 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;
> +  BOOLEAN     IsNmiSupported;
> +  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;
> +    }
> +
> +    IsNmiSupported = GpioIsNmiSupportedByGroupDw (
> +                       GpioGetGroupFromGpioPad (GpioPad),
> +                       GPIO_GET_DW_NUM (PadNumber)
> +                       );
> +    if (IsNmiSupported) {
> +      GpioWriteReg (
> +        GpioNmiEnableRegister,
> +        GpioGetGroupFromGpioPad (GpioPad),
> +        GPIO_GET_DW_NUM (PadNumber),
> +        ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
> +        NmiEnable << GPIO_GET_PAD_POSITION (PadNumber)
> +        );
> +    } else {
> +      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 (FALSE);
> +      }
> +    }
> +  }
> +
> +  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;
> +  EFI_STATUS  Status;
> +
> +  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.
> +    //
> +    Status = GpioPadRstCfgFromResetConfig (
> +               GpioPad,
> +               Value,
> +               &PadRstCfg
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    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 Host Software Pad Ownership for certain group
> +
> +  @param[in]  Group               GPIO group
> +  @param[in]  DwNum               Host Ownership register number for
> current group.
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @param[out] HostSwRegVal        Value of Host Software Pad Ownership
> register
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter
> number
> +**/
> +EFI_STATUS
> +GpioGetHostSwOwnershipForGroupDw (
> +  IN  GPIO_GROUP                  Group,
> +  IN  UINT32                      DwNum,
> +  OUT UINT32                      *HostSwRegVal
> +  )
> +{
> +  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  GpioReadReg (
> +    GpioHostOwnershipRegister,
> +    Group,
> +    DwNum,
> +    HostSwRegVal
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This procedure will get GPIO Host Software Pad Ownership for certain group
> +
> +  @param[in]  Group               GPIO group
> +  @param[in]  DwNum               Host Ownership register number for
> current group
> +                                  For group which has less then 32 pads per group
> DwNum must be 0.
> +  @param[in]  HostSwRegVal        Value of Host Software Pad Ownership
> register
> +                                  Bit position - PadNumber
> +                                  Bit value - 0: ACPI Mode, 1: GPIO Driver mode
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter
> number
> +**/
> +EFI_STATUS
> +GpioSetHostSwOwnershipForGroupDw (
> +  IN GPIO_GROUP                   Group,
> +  IN UINT32                       DwNum,
> +  IN UINT32                       HostSwRegVal
> +  )
> +{
> +  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  GpioWriteReg (
> +    GpioHostOwnershipRegister,
> +    Group,
> +    DwNum,
> +    0,
> +    HostSwRegVal
> +    );
> +  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);
> +
> +  GpioWriteReg (
> +    GpioHostOwnershipRegister,
> +    GpioGetGroupFromGpioPad (GpioPad),
> +    GPIO_GET_DW_NUM (PadNumber),
> +    (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
> +    PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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;
> +  }
> +
> +  GpioReadReg (
> +    GpioPadConfigLockRegister,
> +    Group,
> +    DwNum,
> +    PadCfgLockRegVal
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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;
> +  }
> +
> +  GpioReadReg (
> +    GpioPadLockOutputRegister,
> +    Group,
> +    DwNum,
> +    PadCfgLockTxRegVal
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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 set 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 GpioSetGroupDwToGpeDwX()
> +
> +  @param[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
> +  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
> +  @param[in]  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
> +GpioSetGroupToGpeDwX (
> +  IN GPIO_GROUP                GroupToGpeDw0,
> +  IN GPIO_GROUP                GroupToGpeDw1,
> +  IN GPIO_GROUP                GroupToGpeDw2
> +  )
> +{
> +  return GpioSetGroupDwToGpeDwX (
> +           GroupToGpeDw0,
> +           0,
> +           GroupToGpeDw1,
> +           0,
> +           GroupToGpeDw2,
> +           0
> +           );
> +}
> +
> +/**
> +  This procedure will set 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[in]  GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
> +  @param[in]  GroupDwForGpeDw0    DW of pins to be mapped to
> GPE_DW0
> +  @param[in]  GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
> +  @param[in]  GroupDwForGpeDw1    DW of pins to be mapped to
> GPE_DW1
> +  @param[in]  GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
> +  @param[in]  GroupDwForGpeDw2    DW of pins to be mapped to
> GPE_DW2
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
> +**/
> +EFI_STATUS
> +GpioSetGroupDwToGpeDwX (
> +  IN GPIO_GROUP                GroupToGpeDw0,
> +  IN UINT32                    GroupDwForGpeDw0,
> +  IN GPIO_GROUP                GroupToGpeDw1,
> +  IN UINT32                    GroupDwForGpeDw1,
> +  IN GPIO_GROUP                GroupToGpeDw2,
> +  IN UINT32                    GroupDwForGpeDw2
> +  )
> +{
> +  UINT32                     Data32Or;
> +  UINT32                     Data32And;
> +  PCH_SBI_PID                *GpioComSbiIds;
> +  UINT32                     NoOfGpioComs;
> +  UINT32                     GpioComIndex;
> +  UINT32                     GpioGpeDwx[3];
> +  UINT32                     PmcGpeDwx[3];
> +  GPIO_GROUP                 GroupToGpeDwX[3];
> +  UINT32                     GroupDwForGpeDwX[3];
> +  UINT8                      GpeDwXIndex;
> +  UINT32                     Index;
> +  GPIO_GROUP_TO_GPE_MAPPING  *GpioGpeMap;
> +  UINT32                     GpioGpeMapLength;
> +
> +  ZeroMem (GpioGpeDwx, sizeof (GpioGpeDwx));
> +  ZeroMem (PmcGpeDwx, sizeof (PmcGpeDwx));
> +  //
> +  // Check if each group number is unique
> +  //
> +  if ((GroupToGpeDw0 == GroupToGpeDw1) ||
> +      (GroupToGpeDw0 == GroupToGpeDw2) ||
> +      (GroupToGpeDw1 == GroupToGpeDw2)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  GroupToGpeDwX[0] = GroupToGpeDw0;
> +  GroupDwForGpeDwX[0] = GroupDwForGpeDw0;
> +  GroupToGpeDwX[1] = GroupToGpeDw1;
> +  GroupDwForGpeDwX[1] = GroupDwForGpeDw1;
> +  GroupToGpeDwX[2] = GroupToGpeDw2;
> +  GroupDwForGpeDwX[2] = GroupDwForGpeDw2;
> +
> +  GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength);
> +
> +  for (GpeDwXIndex = 0; GpeDwXIndex < 3; GpeDwXIndex++) {
> +    for (Index = 0; Index < GpioGpeMapLength; Index++) {
> +
> +      if ((GpioGpeMap[Index].Group == GroupToGpeDwX[GpeDwXIndex]) &&
> +          (GpioGpeMap[Index].GroupDw ==
> GroupDwForGpeDwX[GpeDwXIndex])) {
> +        PmcGpeDwx[GpeDwXIndex] = GpioGpeMap[Index].PmcGpeDwxVal;
> +        GpioGpeDwx[GpeDwXIndex] = GpioGpeMap[Index].GpioGpeDwxVal;
> +        break;
> +      }
> +    }
> +
> +    if (Index == GpioGpeMapLength) {
> +      ASSERT (FALSE);
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  //
> +  // Program GPE configuration in PMC register
> +  //
> +  PmcSetGpioGpe (
> +    PmcGpeDwx[0],
> +    PmcGpeDwx[1],
> +    PmcGpeDwx[2]
> +    );
> +
> +  //
> +  // Program GPE configuration in GPIO registers
> +  //
> +  Data32And = (UINT32) ~(B_GPIO_PCR_MISCCFG_GPE0_DW2 |
> B_GPIO_PCR_MISCCFG_GPE0_DW1 | B_GPIO_PCR_MISCCFG_GPE0_DW0);
> +  Data32Or = (UINT32) ((GpioGpeDwx[2] <<
> N_GPIO_PCR_MISCCFG_GPE0_DW2) |
> +                       (GpioGpeDwx[1] << N_GPIO_PCR_MISCCFG_GPE0_DW1) |
> +                       (GpioGpeDwx[0] << N_GPIO_PCR_MISCCFG_GPE0_DW0));
> +
> +  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
> +
> +  //
> +  // Program MISCCFG register for each community
> +  //
> +  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++)
> {
> +    MmioAndThenOr32 (
> +      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex],
> R_GPIO_PCR_MISCCFG),
> +      Data32And,
> +      Data32Or
> +      );
> +  }
> +
> +  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;
> +  EFI_STATUS           Status;
> +
> +  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
> +  //
> +  Status = GpioGetGroupDwToGpeDwX (
> +             &GroupToGpeDwX[0], &GroupDw[0],
> +             &GroupToGpeDwX[1], &GroupDw[1],
> +             &GroupToGpeDwX[2], &GroupDw[2]
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // 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'
> +  //
> +  GpioWriteReg (
> +    GpioSmiStatusRegister,
> +    Group,
> +    DwNum,
> +    0u,
> +    (UINT32) (BIT0 << PadBitPosition)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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++) {
> +      if (GpioIsSmiSupportedByGroupDw(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++) {
> +      if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) {
> +        SmiEnRegVal = 0;
> +        //
> +        // 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;
> +  EFI_STATUS           Status;
> +
> +  Status = GpioGetGpeNumber (GpioPad, &Data32);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG (( DEBUG_ERROR, "GpioCheckFor2Tier: Failed to get GPE number.
> Status: %r\n", Status ));
> +    return FALSE;
> +  }
> +
> +  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'
> +  //
> +  GpioWriteReg (
> +    GpioGpeStatusRegister,
> +    Group,
> +    DwNum,
> +    0u,
> +    (UINT32) (BIT0 << PadBitPosition)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This procedure is used to read GPE STS for a specified Pad
> +
> +  @param[in]  GpioPad             GPIO pad
> +  @param[out] Data                GPE STS data
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
> +**/
> +EFI_STATUS
> +GpioGetGpiGpeSts (
> +  IN GPIO_PAD                  GpioPad,
> +  OUT UINT32                   *Data
> +  )
> +{
> +  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
> +    );
> +
> +  *Data = (GpeStsRegVal >> PadBitPosition) & 0x1;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This procedure is used to lock all GPIO pads except the ones
> +  which were requested during their configuration to be left unlocked.
> +  This function must be called before BIOS_DONE - before POSTBOOT_SAI is
> enabled.
> +    FSP - call this function from wrapper before transition to FSP-S
> +    UEFI/EDK - call this function before EndOfPei event
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
> +**/
> +EFI_STATUS
> +GpioLockPads (
> +  VOID
> +  )
> +{
> +  UINT32         DwNum;
> +  GPIO_GROUP     Group;
> +  GPIO_GROUP     GroupMin;
> +  GPIO_GROUP     GroupMax;
> +  UINT32         UnlockedPads;
> +  EFI_STATUS     Status;
> +
> +  GroupMin = GpioGetLowestGroup ();
> +  GroupMax = GpioGetHighestGroup ();
> +
> +  for (Group = GroupMin; Group <= GroupMax; Group++) {
> +    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup
> (Group)); DwNum++) {
> +
> +      UnlockedPads = GpioGetGroupDwUnlockPadConfigMask
> (GpioGetGroupIndexFromGroup (Group), DwNum);
> +
> +      Status = GpioLockPadCfgForGroupDw (Group, DwNum,
> (UINT32)~UnlockedPads);
> +      if (EFI_ERROR (Status)) {
> +        ASSERT (FALSE);
> +        return Status;
> +      }
> +
> +      UnlockedPads = GpioGetGroupDwUnlockOutputMask
> (GpioGetGroupIndexFromGroup (Group), DwNum);
> +
> +      Status = GpioLockPadCfgTxForGroupDw (Group, DwNum,
> (UINT32)~UnlockedPads);
> +      if (EFI_ERROR (Status)) {
> +        ASSERT (FALSE);
> +        return Status;
> +      }
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa
> mes.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa
> mes.c
> new file mode 100644
> index 0000000000..ec33d06156
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa
> mes.c
> @@ -0,0 +1,87 @@
> +/** @file
> +  This file contains GPIO name library implementation
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa
> tiveLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa
> tiveLib.c
> new file mode 100644
> index 0000000000..9b71cb1d95
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa
> tiveLib.c
> @@ -0,0 +1,234 @@
> +/** @file
> +  This file contains routines for GPIO native and chipset specific usage
> +
> +  Copyright (c) 2019 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
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_PAD_DEF (Group,PadNumber);
> +  } else {
> +    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);
> +}
> +
> +/**
> +  This function checks if SATA GP pin is enabled
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +  @param[in]  SataPort            SATA port number
> +
> +  @retval TRUE                    SATA GPx is enabled (pad is in required native
> mode)
> +          FALSE                   SATA GPx is not enabled
> +**/
> +BOOLEAN
> +GpioIsSataGpEnabled (
> +  IN  UINT32          SataCtrlIndex,
> +  IN  UINTN           SataPort
> +  )
> +{
> +  EFI_STATUS                Status;
> +  GPIO_PAD_NATIVE_FUNCTION  SataGpGpio;
> +  GPIO_PAD_MODE             GpioMode;
> +
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  GpioGetSataGpPin (
> +    SataCtrlIndex,
> +    SataPort,
> +    &SataGpGpio
> +    );
> +
> +  Status =  GpioGetPadMode (SataGpGpio.Pad, &GpioMode);
> +  if ((EFI_ERROR (Status)) || (GpioMode != SataGpGpio.Mode)) {
> +    return FALSE;
> +  } else {
> +    return TRUE;
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi
> ngLib/PchCycleDecodingLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi
> ngLib/PchCycleDecodingLib.c
> new file mode 100644
> index 0000000000..24afbbf712
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi
> ngLib/PchCycleDecodingLib.c
> @@ -0,0 +1,1136 @@
> +/** @file
> +  PCH cycle deocding configuration and query library.
> +
> +  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PchEspiLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsSpi.h>
> +#include <Register/PchRegsSmbus.h>
> +
> +typedef enum {
> +  SlaveLpcEspiCS0,
> +  SlaveEspiCS1,
> +  SlaveId_Max
> +} SLAVE_ID_INDEX;
> +
> +/**
> +  Set PCH TCO base address.
> +  This cycle decoding is required also on DMI side
> +  Programming steps:
> +  1. set Smbus PCI offset 54h [8] to enable TCO base address.
> +  2. program Smbus PCI offset 50h [15:5] to TCO base address.
> +  3. set Smbus PCI offset 54h [8] to enable TCO base address.
> +  4. program "TCO Base Address" in DMI
> +
> +  @param[in] Address                    Address for TCO base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchTcoBaseSet (
> +  IN  UINT16                            Address
> +  )
> +{
> +  UINT64                                SmbusBase;
> +  EFI_STATUS                            Status;
> +
> +  if ((Address & ~B_SMBUS_CFG_TCOBASE_BAR) != 0) {
> +    DEBUG ((DEBUG_ERROR, "PchTcoBaseSet Error. Invalid Address: %x.\n",
> Address));
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = PchDmiSetTcoBase (Address);
> +  if (EFI_ERROR (Status)) {
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +
> +  SmbusBase = PCI_SEGMENT_LIB_ADDRESS (
> +                DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                DEFAULT_PCI_BUS_NUMBER_PCH,
> +                PCI_DEVICE_NUMBER_PCH_SMBUS,
> +                PCI_FUNCTION_NUMBER_PCH_SMBUS,
> +                0
> +                );
> +  if (PciSegmentRead16 (SmbusBase) == 0xFFFF) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +  //
> +  // Verify TCO base is not locked.
> +  //
> +  if ((PciSegmentRead8 (SmbusBase + R_SMBUS_CFG_TCOCTL) &
> B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK) != 0) {
> +    ASSERT (FALSE);
> +    return EFI_DEVICE_ERROR;
> +  }
> +  //
> +  // Disable TCO in SMBUS Device first before changing base address.
> +  // Byte access to not touch the TCO_BASE_LOCK bit
> +  //
> +  PciSegmentAnd8 (
> +    SmbusBase + R_SMBUS_CFG_TCOCTL + 1,
> +    (UINT8) ~(B_SMBUS_CFG_TCOCTL_TCO_BASE_EN >> 8)
> +    );
> +  //
> +  // Program TCO in SMBUS Device
> +  //
> +  PciSegmentAndThenOr16 (
> +    SmbusBase + R_SMBUS_CFG_TCOBASE,
> +    (UINT16) (~B_SMBUS_CFG_TCOBASE_BAR),
> +    Address
> +    );
> +  //
> +  // Enable TCO in SMBUS Device and lock TCO BASE
> +  //
> +  PciSegmentOr16 (
> +    SmbusBase + R_SMBUS_CFG_TCOCTL,
> +    B_SMBUS_CFG_TCOCTL_TCO_BASE_EN |
> B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK
> +    );
> +
> +  return Status;
> +}
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  Returns PCH LPC device PCI base address.
> +
> +  @retval                   PCH LPC PCI base address.
> +**/
> +STATIC
> +UINT64
> +LpcPciBase (
> +  VOID
> +  )
> +{
> +  return PCI_SEGMENT_LIB_ADDRESS (
> +           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +           DEFAULT_PCI_BUS_NUMBER_PCH,
> +           PCI_DEVICE_NUMBER_PCH_LPC,
> +           PCI_FUNCTION_NUMBER_PCH_LPC,
> +           0
> +           );
> +}
> +
> +/**
> +  Function checks if passed Generic LPC IO Address and Length meets
> requirements.
> +
> +  @param[in] Address                    Address for generic IO range decoding.
> +  @param[in] Length                     Length of generic IO range.
> +
> +  @retval TRUE                          Passed IO range meets requirements
> +  @retval FALSE                         Passed IO range does not meets
> requirements.
> +**/
> +STATIC
> +BOOLEAN
> +IsLpcIoRangeValid (
> +  IN  UINT32                            Address,
> +  IN  UINT32                            Length
> +  )
> +{
> +  UINT32            Index;
> +  UINT32            NumRanges;
> +
> +  STATIC struct EXCEPT_RANGE {
> +    UINT8 Start;
> +    UINT8 Length;
> +  } ExceptRanges[] = { {0x00, 0x20}, {0x44, 0x08}, {0x54, 0x0C}, {0x68, 0x08},
> {0x80, 0x10}, {0xC0, 0x40} };
> +
> +  NumRanges = ARRAY_SIZE (ExceptRanges);
> +  //
> +  // For generic IO range, the base address must align to 4 and less than
> 0xFFFF,
> +  // the length must be power of 2 and less than or equal to 256, and the
> address must be length aligned.
> +  // 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
> +  //
> +  if (((Length & (Length - 1)) != 0)  ||
> +      ((Address & (UINT16) ~B_LPC_CFG_GENX_DEC_IOBAR) != 0) ||
> +      (Length > 256)) {
> +    return FALSE;
> +  }
> +  if (Address < 0x100) {
> +    for (Index = 0; Index < NumRanges; Index++) {
> +      if ((Address >= ExceptRanges[Index].Start) &&
> +          ((Address + Length) <= ((UINTN) ExceptRanges[Index].Start + (UINTN)
> ExceptRanges[Index].Length))) {
> +        break;
> +      }
> +    }
> +    if (Index >= NumRanges) {
> +      return FALSE;
> +    }
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +  Function checks if passed Generic LPC IO Range is already in Gen IO Range list
> +
> +  @param[in] Address                    Address for generic IO range decoding.
> +  @param[in] Length                     Length of generic IO range.
> +  @param[in] GenIoRangeList             Pointer to Generic IO Ranges List
> +
> +  @retval TRUE                          Passed IO range alredy covered
> +  @retval FALSE                         Passed IO range NOT covered
> +**/
> +STATIC
> +BOOLEAN
> +IsRangeInList (
> +  IN  UINT32                      Address,
> +  IN  UINT32                      Length,
> +  IN  PCH_LPC_GEN_IO_RANGE_LIST   *GenIoRangeList
> +  )
> +{
> +  UINT32                                CurrentBaseAddr;
> +  UINT32                                CurrentLength;
> +  UINT32                                Index;
> +
> +  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
> +    CurrentBaseAddr = GenIoRangeList->Range[Index].BaseAddr;
> +    CurrentLength   = GenIoRangeList->Range[Index].Length;
> +    if (GenIoRangeList->Range[Index].Enable == 0) {
> +      continue;
> +    }
> +    if ((Address >= CurrentBaseAddr) && ((Address + Length) <=
> (CurrentBaseAddr + CurrentLength))) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Function checks if passed Generic LPC IO Range overlaps with existing range
> +
> +  @param[in] Address                    Address for generic IO range base
> address.
> +  @param[in] Length                     Length of generic IO range.
> +  @param[in] GenIoRangeList             Pointer to Generic IO Ranges List
> +
> +  @retval TRUE                          Passed LPC IO range overlaps with existing
> range
> +  @retval FALSE                         Passed LPC IO range NOT overlaps
> +**/
> +STATIC
> +BOOLEAN
> +FindOverlappingGenIoRange (
> +  IN  UINT32                          Address,
> +  IN  UINT32                          Length,
> +  IN  PCH_LPC_GEN_IO_RANGE_LIST       *GenIoRangeList
> +  )
> +{
> +  UINT32                              Index;
> +  UINT32                              CurrentBaseAddr;
> +  UINT32                              CurrentLength;
> +
> +  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
> +    CurrentBaseAddr = GenIoRangeList->Range[Index].BaseAddr;
> +    CurrentLength = GenIoRangeList->Range[Index].Length;
> +    if (GenIoRangeList->Range[Index].Enable == 0) {
> +      continue;
> +    }
> +
> +    if ((Address >= CurrentBaseAddr) &&
> +        (Address <= (CurrentBaseAddr + CurrentLength))) {
> +      return TRUE;
> +    } else if (((Address + Length) >= CurrentBaseAddr) &&
> +              ((Address + Length) <= (CurrentBaseAddr + CurrentLength))) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Function look for empty Generic IO range register.
> +  If found return range index.
> +
> +  @param[in]      GenIoRangeList        Pointer to Generic IO Ranges List
> +  @param[in]      ListLength            Length of passed list
> +  @param[out]     RangeIndex            Generic IO Range Index
> +
> +  @retval TRUE                          Empty range found
> +  @retval FALSE                         NOT found empty range
> +**/
> +STATIC
> +BOOLEAN
> +FindEmptyGenIoRange (
> +  IN  PCH_LPC_GEN_IO_RANGE_LIST   *GenIoRangeList,
> +  IN  UINT32                      ListLength,
> +  OUT UINT32                      *RangeIndex
> +  )
> +{
> +  UINT32                          Index;
> +
> +  for (Index = 0; Index < ListLength; Index++) {
> +    if (GenIoRangeList->Range[Index].Enable == 0) {
> +      *RangeIndex = Index;
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Get PCH LPC/eSPI and eSPI CS1# generic IO range list.
> +  This function returns a list of base address, length, and enable for all
> LPC/eSPI or eSPI CS1# generic IO range registers.
> +
> +  @param[in]  RangeIndex                Slave ID (refer to SLAVE_ID_INDEX)
> +  @param[out] GenIoRangeList            LPC/eSPI or eSPI CS1# generic IO
> range registers.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +**/
> +EFI_STATUS
> +LpcEspiGenIoRangeGetHelper (
> +  IN  SLAVE_ID_INDEX                    SlaveId,
> +  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
> +  )
> +{
> +  UINT32                                Index;
> +  UINT64                                LpcBase;
> +  UINT32                                Data32;
> +  UINT32                                GenIoReg;
> +
> +  if ((GenIoRangeList == NULL) || (SlaveId >= SlaveId_Max)) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  LpcBase = LpcPciBase ();
> +
> +  if (SlaveId == SlaveEspiCS1) {
> +    GenIoReg = R_ESPI_CFG_CS1GIR1;
> +  } else {
> +    GenIoReg = R_LPC_CFG_GEN1_DEC;
> +  }
> +
> +  for (Index = 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) {
> +    if ((SlaveId == SlaveEspiCS1) &&
> +        (Index > 0)) {
> +      // For eSPI CS1# we have only one range. Reset remaining entries to zero.
> +      GenIoRangeList->Range[Index].BaseAddr = 0;
> +      GenIoRangeList->Range[Index].Enable = 0;
> +      GenIoRangeList->Range[Index].Length = 0;
> +      continue;
> +    }
> +    Data32 = PciSegmentRead32 (LpcBase + GenIoReg + Index * 4);
> +    GenIoRangeList->Range[Index].BaseAddr = Data32 &
> B_LPC_CFG_GENX_DEC_IOBAR;
> +    GenIoRangeList->Range[Index].Length   = ((Data32 &
> B_LPC_CFG_GENX_DEC_IODRA) >> 16) + 4;
> +    GenIoRangeList->Range[Index].Enable   = Data32 &
> B_LPC_CFG_GENX_DEC_EN;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Function checks if passed Generic LPC IO Range colliding
> +  with range alredy defined for other eSPI chiselect (CS)
> +
> +  @param[in] Address                    Address for generic IO range base
> address.
> +  @param[in] Length                     Length of generic IO range.
> +  @param[in] SlaveId                    Slave ID (refer to SLAVE_ID_INDEX)
> +
> +  @retval TRUE                          Passed IO range conflicting
> +  @retval FALSE                         There is no conflict
> +**/
> +STATIC
> +BOOLEAN
> +IsRangeColliding (
> +  IN  UINT32                      Address,
> +  IN  UINT32                      Length,
> +  IN  SLAVE_ID_INDEX              SlaveId
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  PCH_LPC_GEN_IO_RANGE_LIST       GenIoRangeList;
> +
> +  if (SlaveId == SlaveEspiCS1) {
> +    Status  = LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0,
> &GenIoRangeList);
> +    if (!EFI_ERROR (Status)) {
> +      if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) ||
> +          IsRangeInList (Address, Length, &GenIoRangeList)) {
> +        return TRUE;
> +      }
> +    }
> +  } else {
> +    Status  = LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, &GenIoRangeList);
> +    if (!EFI_ERROR (Status)) {
> +      if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) ||
> +          IsRangeInList (Address, Length, &GenIoRangeList)) {
> +        return TRUE;
> +      }
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  PCH_LPC_GEN_IO_RANGE_LIST             GenIoRangeList;
> +  UINT32                                RangeIndex;
> +  UINT32                                Data32;
> +  UINT32                                GenIoReg;
> +  UINT32                                ListLength;
> +
> +  //
> +  // Check if pasesed Address and Length meets all requirements
> +  //
> +  if(!IsLpcIoRangeValid (Address, Length) || (SlaveId >= SlaveId_Max)) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Read current Generic IO configuration
> +  //
> +  Status  = LpcEspiGenIoRangeGetHelper (SlaveId, &GenIoRangeList);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Check if passed Generic IO range is already covered in current
> configuration
> +  //
> +  if (IsRangeInList (Address, Length, &GenIoRangeList)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Check if passed Generic IO range conflicting with other eSPI CS decoding
> +  //
> +  if (IsRangeColliding (Address, Length, SlaveId)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (SlaveId == SlaveEspiCS1) {
> +    GenIoReg = R_ESPI_CFG_CS1GIR1;
> +    ListLength = ESPI_CS1_GEN_IO_RANGE_MAX;
> +  } else {
> +    GenIoReg = R_LPC_CFG_GEN1_DEC;
> +    ListLength = PCH_LPC_GEN_IO_RANGE_MAX;
> +  }
> +
> +  RangeIndex = ListLength;
> +  //
> +  // Check if there is an empty Generic IO range register
> +  //
> +  if (FindEmptyGenIoRange (&GenIoRangeList, ListLength, &RangeIndex) ==
> FALSE) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Program decoding in DMI and LPC/eSPI registers
> +  //
> +  if (SlaveId == SlaveEspiCS1) {
> +    ASSERT (RangeIndex == 0);
> +    Status = PchDmiSetEspiCs1GenIoRange (Address, Length);
> +  } else {
> +    Status = PchDmiSetLpcGenIoRange (Address, Length, RangeIndex);
> +  }
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Program LPC/eSPI generic IO range register accordingly.
> +  //
> +  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
> +  Data32 |= (UINT32) Address;
> +  Data32 |= B_LPC_CFG_GENX_DEC_EN;
> +
> +  //
> +  // Program LPC/eSPI PCI Offset 84h ~ 93h (LPC, eSPI CS0#) or A4h (eSPI CS1#)
> of Mask, Address, and Enable.
> +  //
> +  PciSegmentWrite32 (
> +    LpcPciBase () + GenIoReg + RangeIndex * 4,
> +    Data32
> +    );
> +
> +  return Status;
> +}
> +
> +/**
> +  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 eSPI CS1# generic IO range decoding.
> +
> +  Steps of programming generic IO range:
> +  1. Program eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enable.
> +  2. Program eSPI Generic IO Range in DMI
> +
> +  @param[in] Address                    Address for generic IO range decoding.
> +  @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               eSPI secondary slave not supported
> +**/
> +EFI_STATUS
> +PchEspiCs1GenIoRangeSet (
> +  IN  UINT16                            Address,
> +  IN  UINTN                             Length
> +  )
> +{
> +  if (!IsEspiSecondSlaveSupported ()) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return LpcEspiGenIoRangeSetHelper ((UINT32)Address, (UINT32)Length,
> SlaveEspiCS1);
> +}
> +
> +/**
> +  Get PCH LPC/eSPI generic IO range list.
> +  This function returns a list of base address, length, and enable for all
> LPC/eSPI generic IO range registers.
> +
> +  @param[out] LpcGenIoRangeList         Return all LPC/eSPI generic IO range
> register status.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +**/
> +EFI_STATUS
> +PchLpcGenIoRangeGet (
> +  OUT PCH_LPC_GEN_IO_RANGE_LIST         *LpcGenIoRangeList
> +  )
> +{
> +  return LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0,
> LpcGenIoRangeList);
> +}
> +
> +/**
> +  Get PCH eSPI CS1# generic IO range list.
> +  This function returns a list of base address, length, and enable for all eSPI
> CS1# generic IO range registers.
> +
> +  @param[out] GenIoRangeList            eSPI generic IO range registers.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
> +**/
> +EFI_STATUS
> +PchEspiCs1GenIoRangeGet (
> +  OUT PCH_LPC_GEN_IO_RANGE_LIST         *GenIoRangeList
> +  )
> +{
> +  if (!IsEspiSecondSlaveSupported ()) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, GenIoRangeList);
> +}
> +
> +/**
> +  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.
> +**/
> +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, "PchLpcEspiMemRangeSet Error. Invalid Address:
> %x or invalid SlaveId\n", Address));
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  LpcBase = LpcPciBase ();
> +
> +  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);
> +}
> +
> +/**
> +  @deprecated. Keep this for backward compatibility.
> +  It's replaced by PchEspiCs1MemRangeSet.
> +**/
> +EFI_STATUS
> +PchEspiMemRange2Set (
> +  IN  UINT32                            Address
> +  )
> +{
> +  return PchEspiCs1MemRangeSet (Address);
> +}
> +
> +/**
> +  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
> +**/
> +EFI_STATUS
> +LpcEspiMemRangeGetHelper (
> +  IN  SLAVE_ID_INDEX                    SlaveId,
> +  OUT UINT32                            *Address
> +  )
> +{
> +  UINT32                                GenMemReg;
> +
> +  if ((Address == NULL) || (SlaveId >= SlaveId_Max)) {
> +    DEBUG ((DEBUG_ERROR, "PchLpcEspiMemRangeGet Error. Invalid pointer
> or SlaveId.\n"));
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (SlaveId == SlaveEspiCS1) {
> +    GenMemReg = R_ESPI_CFG_CS1GMR1;
> +  } else {
> +    GenMemReg = R_LPC_CFG_LGMR;
> +  }
> +  *Address = PciSegmentRead32 (LpcPciBase () + 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 = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_SPI,
> +                 PCI_FUNCTION_NUMBER_PCH_SPI,
> +                 0
> +                 );
> +    //
> +    // Read SPI CFG cycle before write SPI CFG cycle
> +    PciSegmentRead16 (BaseAddr + R_SPI_CFG_BDE);
> +    //
> +    // If SPI, Program SPI offset D8h to BiosDecodeEnable.
> +    //
> +    PciSegmentWrite16 (BaseAddr + R_SPI_CFG_BDE, BiosDecodeEnable);
> +  } else {
> +    BaseAddr = LpcPciBase ();
> +    //
> +    // 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  = LpcPciBase ();
> +
> +  //
> +  // 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 = LpcPciBase ();
> +
> +  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);
> +}
> +
> +/**
> +  Set PCH IO port 80h cycle decoding to PCIE root port.
> +  System BIOS is likely to do this very soon after reset before PCI bus
> enumeration.
> +  This cycle decoding is allowed to set when DMI is unlocked
> +
> +  @param[in] RpNumber                PCIE root port physical number.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +**/
> +EFI_STATUS
> +PchIoPort80DecodeSet (
> +  IN  UINTN                             RpNumber
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = PchDmiSetIoPort80Decode (RpNumber);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +/**
> +  Get IO APIC registers base address.
> +
> +  @param[out] IoApicBase                Buffer of IO APIC register address
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +**/
> +EFI_STATUS
> +PchIoApicBaseGet (
> +  OUT UINT32                            *IoApicBase
> +  )
> +{
> +  *IoApicBase = PcdGet32 (PcdIoApicBaseAddress);
> +  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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchE
> spiLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchE
> spiLib.c
> new file mode 100644
> index 0000000000..1bbecc71ed
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchE
> spiLib.c
> @@ -0,0 +1,505 @@
> +/** @file
> +  This file contains routines for eSPI
> +
> +  Copyright (c) 2019 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/PchEspiLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/TimerLib.h>
> +#include <PchLimits.h>
> +#include <Register/PchRegsPcr.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 (IsPchH () && ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAPS)
> & R_ESPI_PCR_SOFTSTRAPS_CS1_EN) != 0));
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINT32      Data32;
> +  UINT8       SupportedChannels;
> +
> +  Status = PchEspiSlaveGetConfig (SlaveId, R_ESPI_SLAVE_GENCAP, &Data32);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  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 a PCH_H
> +  //
> +  if ((SlaveId == 1) && (IsPchLp ())) {
> +    DEBUG ((DEBUG_ERROR, "eSPI Slave ID of 1 is only available on PCH_H
> \n"));
> +    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);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = 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;
> +  EFI_STATUS  Status;
> +
> +  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) {
> +    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    if ((Data32 & B_ESPI_SLAVE_BME) != 0) {
> +      Data32 &= ~(B_ESPI_SLAVE_BME);
> +      Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +      SlaveBmeSet = TRUE;
> +    }
> +  }
> +
> +  // Disable channel
> +  Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Data32 &= ~(B_ESPI_SLAVE_CHACAP_CHEN);
> +  Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  // Enable channel
> +  Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Data32 |= B_ESPI_SLAVE_CHACAP_CHEN;
> +  Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  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)) {
> +    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    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) {
> +    Status = PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    Data32 |= B_ESPI_SLAVE_BME;
> +    Status = PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchG
> beLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchG
> beLib.c
> new file mode 100644
> index 0000000000..652a47ebaf
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchG
> beLib.c
> @@ -0,0 +1,82 @@
> +/** @file
> +  PCH Gbe Library.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsSpi.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
> +PchIsGbeRegionValid (
> +  VOID
> +  )
> +{
> +  UINT32  SpiBar;
> +  SpiBar = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
> +                               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                               DEFAULT_PCI_BUS_NUMBER_PCH,
> +                               PCI_DEVICE_NUMBER_PCH_SPI,
> +                               PCI_FUNCTION_NUMBER_PCH_SPI,
> +                               R_SPI_CFG_BAR0)) & ~B_SPI_CFG_BAR0_MASK;
> +  ASSERT (SpiBar != 0);
> +  if (MmioRead32 (SpiBar + R_SPI_MEM_FREG3_GBE) !=
> B_SPI_MEM_FREGX_BASE_MASK) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +
> +/**
> +  Check whether LAN controller is enabled in the platform.
> +
> +  @retval TRUE                    GbE is enabled
> +  @retval FALSE                   GbE is disabled
> +**/
> +BOOLEAN
> +PchIsGbePresent (
> +  VOID
> +  )
> +{
> +  //
> +  // Check PCH Support
> +  //
> +  if (!PchIsGbeSupported ()) {
> +    return FALSE;
> +  }
> +  //
> +  // Check PMC strap/fuse
> +  //
> +  if (!PmcIsGbeSupported ()) {
> +    return FALSE;
> +  }
> +  //
> +  // Check GbE NVM
> +  //
> +  if (PchIsGbeRegionValid () == FALSE) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/Pch
> HsioLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/Pch
> HsioLib.c
> new file mode 100644
> index 0000000000..2be8e8ed49
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/Pch
> HsioLib.c
> @@ -0,0 +1,127 @@
> +/** @file
> +  PCH HSIO Library.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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 <PchAccess.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchHsioLib.h>
> +
> +/**
> +  The function returns the Port Id and lane owner for the specified lane
> +
> +  @param[in]  PhyMode             Phymode that needs to be checked
> +  @param[out] PortId              Common Lane End Point ID
> +  @param[out] LaneOwner           Lane Owner
> +
> +  @retval EFI_SUCCESS             Read success
> +  @retval EFI_INVALID_PARAMETER   Invalid lane number
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchGetLaneInfo (
> +  IN  UINT32                            LaneNum,
> +  OUT UINT8                             *PortId,
> +  OUT UINT8                             *LaneOwner
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[out] LaneNum                   GBE Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetGbeLaneNum (
> +  UINT8               *LaneNum
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[in]  Usb3LaneIndex             USB3 Lane Index
> +  @param[out] LaneNum                   Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetUsb3LaneNum (
> +  UINT32              Usb3LaneIndex,
> +  UINT8               *LaneNum
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[in]  SataLaneIndex             Sata Lane Index
> +  @param[out] LaneNum                   Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetSataLaneNum (
> +  UINT32              SataLaneIndex,
> +  UINT8               *LaneNum
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Determine the lane number of a specified port
> +
> +  @param[in]  PcieLaneIndex             PCIE Root Port Lane Index
> +  @param[out] LaneNum                   Lane Number
> +
> +  @retval EFI_SUCCESS                   Lane number valid.
> +  @retval EFI_UNSUPPORTED               Incorrect input device port
> +**/
> +EFI_STATUS
> +PchGetPcieLaneNum (
> +  UINT32              PcieLaneIndex,
> +  UINT8               *LaneNum
> +  )
> +{
> +
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Get HSIO lane representation needed to perform any operation on the lane.
> +
> +  @param[in]  LaneIndex  Number of the HSIO lane
> +  @param[out] HsioLane   HSIO lane representation
> +**/
> +VOID
> +HsioGetLane (
> +  IN   UINT8       LaneIndex,
> +  OUT  HSIO_LANE   *HsioLane
> +  )
> +{
> +
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchIn
> foLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLib.c
> new file mode 100644
> index 0000000000..7c3ade49b6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLib.c
> @@ -0,0 +1,272 @@
> +/** @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) 2019 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 <Register/PchRegsPcie.h>
> +#include <IndustryStandard/Pci30.h>
> +
> +/**
> +  Return LPC Device Id
> +
> +  @retval PCH_LPC_DEVICE_ID         PCH Lpc Device ID
> +**/
> +UINT16
> +PchGetLpcDid (
> +  VOID
> +  )
> +{
> +  UINT64  LpcBaseAddress;
> +
> +  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_LPC,
> +                     PCI_FUNCTION_NUMBER_PCH_LPC,
> +                     0
> +                     );
> +
> +  return PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET);
> +}
> +
> +/**
> +  Return Pch Series
> +
> +  @retval PCH_SERIES            Pch Series
> +**/
> +PCH_SERIES
> +PchSeries (
> +  VOID
> +  )
> +{
> +  PCH_SERIES        PchSer;
> +  static PCH_SERIES PchSeries = PCH_UNKNOWN_SERIES;
> +
> +  if (PchSeries != PCH_UNKNOWN_SERIES) {
> +    return PchSeries;
> +  }
> +
> +  PchSer = PchSeriesFromLpcDid (PchGetLpcDid ());
> +
> +  PchSeries = PchSer;
> +
> +  return PchSer;
> +}
> +
> +/**
> +  Return Pch stepping type
> +
> +  @retval PCH_STEPPING            Pch stepping type
> +**/
> +PCH_STEPPING
> +PchStepping (
> +  VOID
> +  )
> +{
> +  UINT8                RevId;
> +  UINT64               LpcBaseAddress;
> +  static PCH_STEPPING  PchStepping = PCH_STEPPING_MAX;
> +
> +  if (PchStepping != PCH_STEPPING_MAX) {
> +    return PchStepping;
> +  }
> +
> +  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_LPC,
> +                     PCI_FUNCTION_NUMBER_PCH_LPC,
> +                     0
> +                     );
> +  RevId = PciSegmentRead8 (LpcBaseAddress + PCI_REVISION_ID_OFFSET);
> +
> +  PchStepping = RevId;
> +
> +  return RevId;
> +}
> +
> +/**
> +  Determine if PCH is supported
> +
> +  @retval TRUE                    PCH is supported
> +  @retval FALSE                   PCH is not supported
> +**/
> +BOOLEAN
> +IsPchSupported (
> +  VOID
> +  )
> +{
> +  UINT16         LpcDeviceId;
> +  UINT16         LpcVendorId;
> +  UINT64         LpcBaseAddress;
> +
> +  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_LPC,
> +                     PCI_FUNCTION_NUMBER_PCH_LPC,
> +                     0
> +                     );
> +
> +  LpcDeviceId = PciSegmentRead16 (LpcBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  LpcVendorId = PciSegmentRead16 (LpcBaseAddress +
> PCI_VENDOR_ID_OFFSET);
> +
> +  ///
> +  /// Verify that this is a supported chipset
> +  ///
> +  if ((LpcVendorId == V_LPC_CFG_VENDOR_ID) && (PchSeries () !=
> PCH_UNKNOWN_SERIES)) {
> +    return TRUE;
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "PCH code doesn't support the LpcDeviceId:
> 0x%04x!\n", LpcDeviceId));
> +    return FALSE;
> +  }
> +}
> +
> +/**
> +  Check if this is PCH LP series
> +
> +  @retval TRUE                It's PCH LP series
> +  @retval FALSE               It's not PCH LP series
> +**/
> +BOOLEAN
> +IsPchLp (
> +  VOID
> +  )
> +{
> +  return (PchSeries () == PCH_LP);
> +}
> +
> +/**
> +  Check if this is PCH H series
> +
> +  @retval TRUE                It's PCH H series
> +  @retval FALSE               It's not PCH H series
> +**/
> +BOOLEAN
> +IsPchH (
> +  VOID
> +  )
> +{
> +  return (PchSeries () == PCH_H);
> +}
> +
> +/**
> +  Check if this is CDF PCH generation
> +
> +  @retval TRUE                It's CDF PCH
> +  @retval FALSE               It's not CDF PCH
> +**/
> +BOOLEAN
> +IsCdfPch (
> +  VOID
> +  )
> +{
> +  return (PchGeneration () == CDF_PCH);
> +}
> +
> +/**
> +  Check if this is PCH generation
> +
> +  @retval TRUE                It's CNL PCH
> +  @retval FALSE               It's not CNL PCH
> +**/
> +BOOLEAN
> +IsCnlPch (
> +  VOID
> +  )
> +{
> +  return (PchGeneration () == CNL_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;
> +  }
> +
> +  AsciiSPrint (Buffer, BufferSize, "%c%c", 'A' + (PchStep >> 4), '0' + (PchStep &
> 0xF));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get PCH Sku ASCII string
> +  The return string is zero terminated.
> +
> +  @retval Static ASCII string of PCH Sku
> +**/
> +CHAR8*
> +PchGetSkuStr (
> +  VOID
> +  )
> +{
> +  UINTN          Index;
> +  UINT16         LpcDid;
> +
> +  LpcDid = PchGetLpcDid ();
> +
> +  for (Index = 0; mSkuStrs[Index].Id != 0xFFFF; Index++) {
> +    if (LpcDid == mSkuStrs[Index].Id) {
> +      return mSkuStrs[Index].String;
> +    }
> +  }
> +
> +  return "Undefined SKU";
> +}
> +
> +/**
> +  Get Pch Maximum Pcie Controller Number
> +
> +  @retval Pch Maximum Pcie Root Port Number
> +**/
> +UINT8
> +GetPchMaxPcieControllerNum (
> +  VOID
> +  )
> +{
> +  return GetPchMaxPciePortNum () / PCH_PCIE_CONTROLLER_PORTS;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchIn
> foLibClient.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLibClient.c
> new file mode 100644
> index 0000000000..7b09a2dbb9
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLibClient.c
> @@ -0,0 +1,87 @@
> +/** @file
> +  Common Pch information library for Client PCH silicon.
> +
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PchInfoLib.h>
> +
> +/**
> +  Get Pch Maximum Pcie Clock Number
> +
> +  @retval Pch Maximum Pcie Clock Number
> +**/
> +UINT8
> +GetPchMaxPcieClockNum (
> +  VOID
> +  )
> +{
> +  if (IsPchH ()) {
> +    return 16;
> +  } else {
> +    return 6;
> +  }
> +}
> +
> +/**
> +  Get Pch Maximum Serial IO controllers number
> +
> +  @retval Pch Maximum Serial IO controllers number
> +**/
> +UINT8
> +GetPchMaxSerialIoControllersNum (
> +  VOID
> +  )
> +{
> +  return 12;
> +}
> +
> +/**
> +  Get Pch Maximum Serial IO I2C controllers number
> +
> +  @retval Pch Maximum Serial IO I2C controllers number
> +**/
> +UINT8
> +GetPchMaxSerialIoI2cControllersNum (
> +  VOID
> +  )
> +{
> +  if (IsPchH ()) {
> +    return 4;
> +  } else {
> +    return 6;
> +  }
> +}
> +
> +/**
> +  Get Pch Maximum Serial IO SPI controllers number
> +
> +  @retval Pch Maximum Serial IO SPI controllers number
> +**/
> +UINT8
> +GetPchMaxSerialIoSpiControllersNum (
> +  VOID
> +  )
> +{
> +  return 3;
> +}
> +
> +/**
> +  Get Pch Maximum Serial IO UART controllers number
> +
> +  @retval Pch Maximum Serial IO UART controllers number
> +**/
> +UINT8
> +GetPchMaxSerialIoUartControllersNum (
> +  VOID
> +  )
> +{
> +  return 3;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchIn
> foLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLibCnl.c
> new file mode 100644
> index 0000000000..431b1470c2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI
> nfoLibCnl.c
> @@ -0,0 +1,386 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Register/PchRegsLpcCnl.h>
> +#include "PchInfoLibPrivate.h"
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Register/PchRegsLpc.h>
> +
> +/**
> +  Determine Pch Series based on Device Id
> +
> +  @param[in] LpcDeviceId      Lpc Device Id
> +
> +  @retval PCH_SERIES          Pch Series
> +**/
> +PCH_SERIES
> +PchSeriesFromLpcDid (
> +  IN UINT16 LpcDeviceId
> +  )
> +{
> +  switch (LpcDeviceId & B_LPC_CFG_DID) {
> +
> +    case V_LPC_CFG_DID_CNL_H:
> +      return PCH_H;
> +
> +    case V_LPC_CFG_DID_CNL_LP:
> +      return PCH_LP;
> +
> +    default:
> +      return PCH_UNKNOWN_SERIES;
> +  }
> +}
> +
> +/**
> +  Return Pch Generation
> +
> +  @retval PCH_GENERATION            Pch Generation
> +**/
> +PCH_GENERATION
> +PchGeneration (
> +  VOID
> +  )
> +{
> +  return CNL_PCH;
> +}
> +
> +/**
> +  Check if this is Server PCH
> +
> +  @retval TRUE                It's a Server PCH
> +  @retval FALSE               It's not a Server PCH
> +**/
> +BOOLEAN
> +IsPchServer (
> +  VOID
> +  )
> +{
> +  return FALSE;
> +}
> +
> +/**
> +  Get RST mode supported by the silicon
> +
> +  @retval RST_MODE    RST mode supported by silicon
> +**/
> +RST_MODE
> +PchGetSupportedRstMode (
> +  VOID
> +  )
> +{
> +  switch (PchGetLpcDid ()) {
> +
> +    case V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4:
> +    case V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU:
> +      return RstUnsupported;
> +      break;
> +
> +    default:
> +      return RstPremium;
> +      break;
> +  }
> +}
> +
> +/**
> +  Check if this is Server SKU
> +
> +  @retval TRUE                It's PCH Server SKU
> +  @retval FALSE               It's not PCH Server SKU
> +**/
> +BOOLEAN
> +IsPchServerSku (
> +  VOID
> +  )
> +{
> +  UINT16 LpcDid;
> +
> +  LpcDid = PchGetLpcDid ();
> +
> +  if (LpcDid == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU) {
> +    return TRUE;
> +  } else {
> +    return FALSE;
> +  }
> +}
> +
> +/**
> +  Get PCH series ASCII string.
> +
> +  @retval PCH Series string
> +**/
> +CHAR8*
> +PchGetSeriesStr (
> +  VOID
> +  )
> +{
> +  switch (PchSeries ()) {
> +
> +    case PCH_LP:
> +      return "CNL PCH-LP";
> +
> +    case PCH_H:
> +      return "CNL PCH-H";
> +
> +    default:
> +      return NULL;
> +  }
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +struct PCH_SKU_STRING mSkuStrs[] = {
> +  //
> +  // PCH LP Mobile LPC Device IDs
> +  //
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU, "Super SKU"},
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0, "(U) Super SKU"},
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1, "Super SKU (locked)"},
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2, "(Y) Premium SKU"},
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3, "(U) Premium  SKU"},
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4, "(U) Base/Mainstream SKU"},
> +  {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5, "(Y) Super SKU"},
> +  //
> +  // PCH H LPC Device IDs
> +  //
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU, "CNL PCH-H SKU A300"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU, "H310"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU, "H370"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU, "Z390"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU, "Q370"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU, "C246"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU, "C242"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU, "X399"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU, "QM370"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU, "HM370"},
> +  {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU, "CM246"},
> +  {0xFFFF, NULL}
> +};
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  Get Pch Maximum Pcie Root Port Number
> +
> +  @retval Pch Maximum Pcie Root Port Number
> +**/
> +UINT8
> +GetPchMaxPciePortNum (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return 16;
> +  } else {
> +    return 24;
> +  }
> +}
> +
> +/**
> +  Get Pch Usb2 Maximum Physical Port Number
> +
> +  @retval Pch Usb2 Maximum Physical Port Number
> +**/
> +UINT8
> +GetPchUsb2MaxPhysicalPortNum (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return 10;
> +  } else {
> +    return 14;
> +  }
> +}
> +
> +/**
> +  Get Pch Maximum Usb2 Port Number of XHCI Controller
> +
> +  @retval Pch Maximum Usb2 Port Number of XHCI Controller
> +**/
> +UINT8
> +GetPchXhciMaxUsb2PortNum (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return 12;
> +  } else {
> +    return 16;
> +  }
> +}
> +
> +/**
> +  Get Pch Maximum Usb3 Port Number of XHCI Controller
> +
> +  @retval Pch Maximum Usb3 Port Number of XHCI Controller
> +**/
> +UINT8
> +GetPchXhciMaxUsb3PortNum (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return 6;
> +  } else {
> +    return 10;
> +  }
> +}
> +
> +/**
> +  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 PCH_HDAUDIO_IDISP_TMODE Tmode
> +  )
> +{
> +  //
> +  // iDisplay Audio Link T-mode support per PCH Generation/Series:
> +  // 1. 1T  - CNP-LP
> +  // 2. 2T  - CNP-LP/H (default)
> +  //
> +  switch (Tmode) {
> +    case PchHdaIDispMode1T:
> +      return IsPchLp ();
> +    case PchHdaIDispMode2T:
> +      return TRUE;
> +    case PchHdaIDispMode4T:
> +    case PchHdaIDispMode8T:
> +    case PchHdaIDispMode16T:
> +    default:
> +      return FALSE;
> +  }
> +}
> +
> +/**
> +  Gets the maximum number of UFS controller supported by this chipset.
> +
> +  @return Number of supported UFS controllers
> +**/
> +UINT8
> +PchGetMaxUfsNum (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return 1;
> +  } else {
> +    return 0;
> +  }
> +}
> +
> +/**
> +  Check if this chipset supports eMMC controller
> +
> +  @retval BOOLEAN  TRUE if supported, FALSE otherwise
> +**/
> +BOOLEAN
> +IsPchEmmcSupported (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Check if this chipset supports SD controller
> +
> +  @retval BOOLEAN  TRUE if supported, FALSE otherwise
> +**/
> +BOOLEAN
> +IsPchSdCardSupported (
> +  VOID
> +  )
> +{
> +  return TRUE;
> +}
> +
> +/**
> +  Check if this chipset supports UFS controller
> +
> +  @retval BOOLEAN  TRUE if supported, FALSE otherwise
> +**/
> +BOOLEAN
> +IsPchUfsSupported (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  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 IsPchH ();
> +}
> +
> +/**
> +  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 !IsPchH ();
> +}
> +
> +/**
> +  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;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pc
> hPcieRpLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pc
> hPcieRpLib.c
> new file mode 100644
> index 0000000000..9997c3612b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pc
> hPcieRpLib.c
> @@ -0,0 +1,183 @@
> +/** @file
> +  PCH 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) 2019 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 <Register/PchRegsPcie.h>
> +#include <Register/PchRegsPcr.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_PCIE_CONTROLLER_INFO
> mPchPcieControllerInfo[] = {
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPA,  0 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPB,  4 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPC,  8 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPD, 12 },
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPE, 16 }, // PCH-H only
> +  { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPF, 20 }  // PCH-H only
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> mPchPcieControllerInfoSize = sizeof (mPchPcieControllerInfo) / sizeof
> (mPchPcieControllerInfo[0]);
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> mPchLpRstPcieStorageSupportedPort[] = {
> +  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,
> RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   //
> RP1..RP4
> +  RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,
> RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,         // RP5..RP8
> +  RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,
> RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,         // RP9..RP12
> +  RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,
> RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3          //
> RP13..RP16
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> mPchHRstPcieStorageSupportedPort[] = {
> +  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,
> RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   //
> RP1..RP4
> +  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,
> RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   //
> RP5..RP8
> +  RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,
> RST_PCIE_STORAGE_CR_1,       RST_PCIE_STORAGE_CR_1,         // RP9..RP12
> +  RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,
> RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID,   //
> RP13..RP16
> +  RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,
> RST_PCIE_STORAGE_CR_3,       RST_PCIE_STORAGE_CR_3,         //
> RP17..RP20
> +  RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2,
> RST_PCIE_STORAGE_CR_2,       RST_PCIE_STORAGE_CR_2          //
> RP21..RP24
> +};
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINTN       RpDevice;
> +  UINTN       RpFunction;
> +
> +  GetPchPcieRpDevFun (RpIndex, &RpDevice, &RpFunction);
> +
> +  return PCI_SEGMENT_LIB_ADDRESS
> (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH,
> (UINT32) RpDevice, (UINT32) RpFunction, 0);
> +}
> +
> +/**
> +  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 ();
> +}
> +
> +/**
> +  Check the RST PCIe Storage Cycle Router number according to the root port
> number and PCH type
> +
> +  @param[in] RootPortNum  Root Port Number
> +
> +  @return  The RST PCIe Storage Cycle Router Number
> +**/
> +UINT8
> +RstGetCycleRouterNumber (
> +  IN  UINT32                   RootPortNum
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (RootPortNum < ARRAY_SIZE (mPchLpRstPcieStorageSupportedPort)) {
> +      return mPchLpRstPcieStorageSupportedPort[RootPortNum];
> +    }
> +  } else if (IsPchH ()) {
> +    if (RootPortNum < ARRAY_SIZE (mPchHRstPcieStorageSupportedPort)) {
> +      return mPchHRstPcieStorageSupportedPort[RootPortNum];
> +    }
> +  }
> +  return RST_PCIE_STORAGE_CR_INVALID;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPc
> rLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPc
> rLib.c
> new file mode 100644
> index 0000000000..6f70733fe7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPc
> rLib.c
> @@ -0,0 +1,279 @@
> +/** @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) 2019 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 <Register/PchRegsPcr.h>
> +
> +#ifndef MDEPKG_NDEBUG
> +/**
> +  Checks if the offset is valid for a given memory access width
> +
> +  @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 (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFF)) {
> +    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);
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchP
> mcLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchP
> mcLib.c
> new file mode 100644
> index 0000000000..2654a76983
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchP
> mcLib.c
> @@ -0,0 +1,101 @@
> +/** @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) 2019 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/MmPciLib.h>
> +#include <PchAccess.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PchPmcLib.h>
> +
> +/**
> +  Query PCH to determine the Pm Status
> +  NOTE:
> +  It's matter when did platform code use this library, since some status could
> be cleared by write one clear.
> +  Therefore this funciton is not always return the same result in one boot.
> +  It's suggested that platform code read this status in the beginning of post.
> +  For the ColdBoot case, this function only returns one case of the cold boot.
> Some cold boot case might
> +  depends on the power cycle scenario and should check with different
> condtion.
> +
> +  @param[in] PmStatus - The Pch Pm Status to be probed
> +
> +  @retval Return TRUE if Status querried is Valid or FALSE if otherwise
> +**/
> +BOOLEAN
> +GetPchPmStatus (
> +  PCH_PM_STATUS PmStatus
> +  )
> +{
> +  UINTN  PmcRegBase;
> +  UINT32 GblRst0;
> +
> +  PmcRegBase = MmPciBase (
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_PMC,
> +                 PCI_FUNCTION_NUMBER_PCH_PMC
> +                 );
> +
> +  switch (PmStatus) {
> +    case WarmBoot:
> +      break;
> +
> +    case PwrFlr:
> +      break;
> +
> +    case PwrFlrSys:
> +      if (GblRst0 & BIT12) {
> +        return TRUE;
> +      }
> +      break;
> +
> +    case PwrFlrPch:
> +      if (GblRst0 & BIT11) {
> +        return TRUE;
> +      }
> +      break;
> +
> +    case ColdBoot:
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Funtion to check if Battery lost or CMOS cleared.
> +
> +  @reval TRUE  Battery is always present.
> +  @reval FALSE CMOS is cleared.
> +**/
> +BOOLEAN
> +EFIAPI
> +PchIsRtcBatteryGood (
> +  VOID
> +  )
> +{
> +  UINTN    PmcBaseAddress;
> +
> +  //
> +  // Check if the CMOS battery is present
> +  // Checks RTC_PWR_STS bit in the GEN_PMCON_3 register
> +  //
> +  PmcBaseAddress = MmPciBase (
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_PMC,
> +                     PCI_FUNCTION_NUMBER_PCH_PMC
> +                     );
> +  return FALSE;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib
> /PchSbiAccessLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib
> /PchSbiAccessLib.c
> new file mode 100644
> index 0000000000..43690e2409
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib
> /PchSbiAccessLib.c
> @@ -0,0 +1,270 @@
> +/** @file
> +  PCH SBI access library.
> +
> +  Copyright (c) 2019 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 <Register/PchRegs.h>
> +#include <Register/PchRegsP2sb.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
> +EFIAPI
> +PchSbiExecution (
> +  IN     PCH_SBI_PID                    Pid,
> +  IN     UINT64                         Offset,
> +  IN     PCH_SBI_OPCODE                 Opcode,
> +  IN     BOOLEAN                        Posted,
> +  IN OUT UINT32                         *Data32,
> +  OUT    UINT8                          *Response
> +  )
> +{
> +  //
> +  // Check address valid
> +  //
> +  if (((UINT32) Offset & 0x3) != 0) {
> +    //
> +    // Warning message for the address not DWORD alignment.
> +    //
> +    DEBUG ((DEBUG_INFO, "PchSbiExecution: Address is not DWORD
> aligned.\n"));
> +  }
> +
> +  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
> +EFIAPI
> +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 = PCI_SEGMENT_LIB_ADDRESS (
> +               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +               DEFAULT_PCI_BUS_NUMBER_PCH,
> +               PCI_DEVICE_NUMBER_PCH_P2SB,
> +               PCI_FUNCTION_NUMBER_PCH_P2SB,
> +               0
> +               );
> +  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 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 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 {
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLib.c
> new file mode 100644
> index 0000000000..0e79d83a12
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLib.c
> @@ -0,0 +1,516 @@
> +/** @file
> +  PCH Serial IO Lib implementation.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <SaAccess.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PcdLib.h>
> +#include <Private/Library/GpioPrivateLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchSerialIoUartLib.h>
> +#include <Include/PcieRegs.h>
> +#include <Private/Library/PchPsfPrivateLib.h>
> +#include <PchLimits.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsSerialIo.h>
> +
> +#define PCIEX_BAR_ADDR_MASK  0x0000007FFC000000
> +
> +typedef struct {
> +  UINT32 Bar0;
> +  UINT32 Bar1;
> +} SERIAL_IO_CONTROLLER_DESCRIPTOR;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR
> mSerialIoAcpiAddress [PCH_MAX_SERIALIO_CONTROLLERS] =
> +{
> +  {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},
> +  {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}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchSerialIoPciCfgCtrAddr
> [PCH_MAX_SERIALIO_CONTROLLERS] =
> +{
> +  R_SERIAL_IO_PCR_PCICFGCTRL1,
> +  R_SERIAL_IO_PCR_PCICFGCTRL2,
> +  R_SERIAL_IO_PCR_PCICFGCTRL3,
> +  R_SERIAL_IO_PCR_PCICFGCTRL4,
> +  R_SERIAL_IO_PCR_PCICFGCTRL5,
> +  R_SERIAL_IO_PCR_PCICFGCTRL6,
> +  R_SERIAL_IO_PCR_PCICFGCTRL13,
> +  R_SERIAL_IO_PCR_PCICFGCTRL14,
> +  R_SERIAL_IO_PCR_PCICFGCTRL9,
> +  R_SERIAL_IO_PCR_PCICFGCTRL10,
> +  R_SERIAL_IO_PCR_PCICFGCTRL11
> +};
> +
> +/**
> +  Returns Serial IO Controller Type  I2C, SPI or UART
> +
> +  @param[in] Number  Number of SerialIo controller
> +
> +  @retval            I2C, SPI or UART
> +  @retval            UNKNOWN - in case if undefined controller
> +**/
> +PCH_SERIAL_IO_CONTROLLER_TYPE
> +GetSerialIoControllerType (
> +  IN PCH_SERIAL_IO_CONTROLLER  Controller
> +  )
> +{
> +  if (Controller >= PchSerialIoIndexI2C0 && Controller <= GetMaxI2cNumber
> ()) {
> +    return SERIAL_IO_I2C;
> +  } else if (Controller >= PchSerialIoIndexSpi0 && Controller <
> (PchSerialIoIndexSpi0 + GetPchMaxSerialIoSpiControllersNum ())) {
> +    return SERIAL_IO_SPI;
> +  } else if (Controller >= PchSerialIoIndexUart0 && Controller <=
> PchSerialIoIndexUart2) {
> +    return SERIAL_IO_UART;
> +  }
> +  return SERIAL_IO_UNKNOWN;
> +}
> +
> +/**
> +  Checks if given Serial IO Controller Function equals 0
> +
> +  @param[in] SerialIoNumber             Serial IO device
> +
> +  @retval                               TRUE if SerialIO Function is equal to 0
> +                                        FALSE if Function is higher then 0
> +**/
> +BOOLEAN
> +IsSerialIoFunctionZero (
> +  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
> +  )
> +{
> +  if (GetSerialIoFunctionNumber (SerialIoNumber) > 0) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> +
> +/**
> +  Checks if given Serial IO Controller is enabled or not
> +
> +  @param[in] DeviceNumber               device number
> +  @param[in] FunctionNumber             function number
> +
> +  @retval TRUE                          TRUE if given serial io device is enabled.
> +  @retval FALSE                         FALSE if given serial io device is disabled.
> +**/
> +BOOLEAN
> +IsSerialIoDeviceEnabled (
> +  IN UINT8  DeviceNumber,
> +  IN UINT8  FunctionNumber
> +  )
> +{
> +  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS
> (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH,
> DeviceNumber, FunctionNumber, PCI_DEVICE_ID_OFFSET)) != 0xFFFF) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Checks if given device corresponds to any of LPSS Devices
> +
> +  @param[in] DeviceNumber               device number
> +  @param[in] FunctionNumber             function number
> +
> +  @retval                               TRUE if SerialIO Device/Function Number is
> equal to any of LPSS devices
> +                                        FALSE Device/Function is not in Serial IO scope
> +**/
> +BOOLEAN
> +IsSerialIoDevice (
> +  IN UINT8  DeviceNumber,
> +  IN UINT8  FunctionNumber
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER  Controller;
> +  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
> +
> +  ControllerMax = GetPchMaxSerialIoControllersNum ();
> +
> +  for (Controller = 0; Controller < ControllerMax; Controller++) {
> +    if ((DeviceNumber == GetSerialIoDeviceNumber (Controller)) &&
> +        (FunctionNumber == GetSerialIoFunctionNumber (Controller))) {
> +      return TRUE;
> +    }
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Gets Pci Config control offset
> +
> +  @param[in] DeviceNumber               device number
> +  @param[in] FunctionNumber             function number
> +
> +  @retval    CfgCtrAddr                 Offset of Pci config control
> +                                        0 if Device and Function do not correspond to
> Serial IO
> +**/
> +UINT16
> +GetSerialIoConfigControlOffset (
> +  IN UINT8  DeviceNumber,
> +  IN UINT8  FunctionNumber
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER  Controller;
> +  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
> +
> +  ControllerMax = GetPchMaxSerialIoControllersNum ();
> +
> +  for (Controller = 0; Controller < ControllerMax; Controller++) {
> +    if ((DeviceNumber == GetSerialIoDeviceNumber (Controller)) &&
> +        (FunctionNumber == GetSerialIoFunctionNumber (Controller))) {
> +      return mPchSerialIoPciCfgCtrAddr[Controller];
> +    }
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  Checks if Device with given AcpiHid string is one of SerialIo controllers
> +  If yes, its number is returned through Number parameter, otherwise
> Number is not updated
> +
> +  @param[in]  AcpiHid                   String
> +  @param[out] Number                    Number of SerialIo controller
> +
> +  @retval TRUE                          yes it is a SerialIo controller
> +  @retval FALSE                         no it isn't a SerialIo controller
> +**/
> +BOOLEAN
> +IsSerialIoAcpiHid (
> +  IN CHAR8                      *AcpiHid,
> +  OUT PCH_SERIAL_IO_CONTROLLER  *Number
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER Controller;
> +  PCH_SERIAL_IO_CONTROLLER  ControllerMax;
> +
> +  ControllerMax = GetPchMaxSerialIoControllersNum ();
> +
> +  for (Controller = 0; Controller < ControllerMax; Controller++) {
> +    if (!AsciiStrCmp ((const CHAR8 *) AcpiHid, GetSerialIoAcpiHid(Controller)))
> {
> +      *Number = Controller;
> +      return TRUE;
> +    }
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Finds BAR values of SerialIo devices.
> +  SerialIo devices can be configured to not appear on PCI so traditional
> method of reading BAR might not work.
> +  If the SerialIo device is in PCI mode, a request for BAR1 will return its PCI CFG
> space instead
> +
> +  @param[in] SerialIoDevice             Serial IO device
> +  @param[in] BarNumber                  0=BAR0, 1=BAR1
> +
> +  @retval                               SerialIo Bar value
> +**/
> +UINTN
> +FindSerialIoBar (
> +  IN PCH_SERIAL_IO_CONTROLLER           SerialIoDevice,
> +  IN UINT8                              BarNumber
> +  )
> +{
> +  UINT64   Bar;
> +  UINT64   PcieBase;
> +  UINT64   PciSegBase;
> +  UINT16   VenId;
> +  UINT32   Device;
> +  UINT32   Function;
> +
> +  Device   = GetSerialIoDeviceNumber (SerialIoDevice);
> +  Function = GetSerialIoFunctionNumber (SerialIoDevice);
> +
> +  PcieBase = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_PCIEXBAR)); // S0:B0:D0:F0:R60
> +  PcieBase = (PcieBase & PCIEX_BAR_ADDR_MASK) + LShiftU64
> (DEFAULT_PCI_BUS_NUMBER_PCH, 20) + LShiftU64 (Device, 15) + LShiftU64
> (Function, 12);
> +
> +  PciSegBase = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 Device,
> +                 Function,
> +                 0
> +                 );
> +
> +  VenId = PciSegmentRead16 (PciSegBase + PCI_VENDOR_ID_OFFSET) &
> 0xFFFF;
> +  if (VenId == V_PCH_INTEL_VENDOR_ID) {
> +    if (BarNumber == 1) {
> +      return ((UINTN) PcieBase);
> +    }
> +    Bar = PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET);
> +    // For 64-Bit Memory Space BARs ((BAR[x] & 0xFFFFFFF0) + ((BAR[x+1] &
> 0xFFFFFFFF) << 32)
> +    if ((Bar & B_PCI_BAR_MEMORY_TYPE_MASK) ==
> B_PCI_BAR_MEMORY_TYPE_64) {
> +      Bar = (Bar & 0xFFFFF000) + (UINTN) ((UINT64) LShiftU64
> ((PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET + 4) &
> 0xFFFFFFFF), 32));
> +      return (UINTN) Bar;
> +    }
> +    return (UINTN) (Bar & 0xFFFFF000);
> +  }
> +  //PCI mode failed? Try hardcoded addresses from ACPI
> +  if (BarNumber == 0) {
> +    Bar = mSerialIoAcpiAddress[SerialIoDevice].Bar0;
> +  } else {
> +    Bar = mSerialIoAcpiAddress[SerialIoDevice].Bar1;
> +  }
> +  return (UINTN) Bar;
> +}
> +
> +/**
> +  Get PSF_PORT for a given Serial IO Controller
> +
> +  @param[in] Controller    Serial IO controller number
> +**/
> +STATIC
> +PSF_PORT
> +SerialIoPsfPort (
> +  IN PCH_SERIAL_IO_CONTROLLER Controller
> +  )
> +{
> +  switch (GetSerialIoControllerType (Controller)) {
> +    case SERIAL_IO_I2C:
> +      return PsfSerialIoI2cPort (Controller - PchSerialIoIndexI2C0);
> +    case SERIAL_IO_SPI:
> +      return PsfSerialIoSpiPort (Controller - PchSerialIoIndexSpi0);
> +    case SERIAL_IO_UART:
> +      return PsfSerialIoUartPort (Controller - PchSerialIoIndexUart0);
> +    case SERIAL_IO_UNKNOWN:
> +    default:
> +      return (PSF_PORT){0};
> +  }
> +}
> +
> +/**
> +  Configures Serial IO Controller
> +
> +  @param[in] Controller    Serial IO controller number
> +  @param[in] DeviceMode    Device operation mode
> +  @param[in] PsfDisable    Disable device at PSF level
> +
> +  @retval None
> +**/
> +VOID
> +ConfigureSerialIoController (
> +  IN PCH_SERIAL_IO_CONTROLLER Controller,
> +  IN PCH_SERIAL_IO_MODE       DeviceMode,
> +  IN BOOLEAN                  PsfDisable
> +  )
> +{
> +  UINT64          PciCfgBase;
> +  UINT32          Data32And;
> +  UINT32          Data32Or;
> +  UINT16          *SerialIoPciCfgCtrAddr;
> +  UINT8           Uart8BitLoop;
> +
> +/*
> +  Please do not add DEBUG message here because this routine is configuring
> SerialIoUart.
> +  Printing DEBUG message before SerialIoUart initialization may cause system
> hang (in Debug build).
> +*/
> +
> +  //
> +  // This is to prevent from overflow of array access.
> +  //
> +  if (Controller >= PCH_MAX_SERIALIO_CONTROLLERS) {
> +    return;
> +  }
> +
> +  if (GetSerialIoControllerType (Controller) == SERIAL_IO_UNKNOWN) {
> +    return;
> +  }
> +
> +  PciCfgBase = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 GetSerialIoDeviceNumber (Controller),
> +                 GetSerialIoFunctionNumber (Controller),
> +                 0
> +                 );
> +  //
> +  // Do not modify a device that has already been disabled/hidden
> +  //
> +  if (PciSegmentRead16 (PciCfgBase + PCI_VENDOR_ID_OFFSET) !=
> V_PCH_INTEL_VENDOR_ID) {
> +    return;
> +  }
> +
> +  ///
> +  /// Step 0. set Bit 16,17,18.
> +  ///
> +  PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_D0I3MAXDEVPG, BIT18 |
> BIT17 | BIT16);
> +
> +  SerialIoPciCfgCtrAddr = mPchSerialIoPciCfgCtrAddr;
> +
> +  switch (DeviceMode) {
> +    case PchSerialIoDisabled:
> +      ///
> +      /// Step 1. Put device in D3
> +      /// Step 2. Function Disable in PSF
> +      ///
> +      PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 |
> BIT0);
> +
> +      if (PsfDisable) {
> +        PsfDisableDevice (SerialIoPsfPort (Controller));
> +      }
> +      break;
> +    case PchSerialIoAcpi:
> +    case PchSerialIoHidden:
> +      ///
> +      /// reenable BAR1 in case it was disabled earlier
> +      /// Read back is needed to enforce the sideband and primary ordering.
> +      ///
> +      PchPcrAndThenOr32WithReadback (
> +        PID_SERIALIO,
> +        SerialIoPciCfgCtrAddr[Controller],
> +        (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS),
> +        0
> +        );
> +      PsfEnableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2);
> +      ///
> +      /// Step 1. Assign BAR0
> +      /// Step 2. Assign BAR1
> +      ///
> +      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,
> mSerialIoAcpiAddress[Controller].Bar0);
> +      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
> +      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_LOW,
> mSerialIoAcpiAddress[Controller].Bar1);
> +      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_HIGH, 0x0);
> +      ///
> +      /// Step 3. Set Memory space Enable
> +      ///
> +      PciSegmentOr32 (PciCfgBase + PCI_COMMAND_OFFSET,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> +      ///
> +      /// Step 4. Disable device's PciCfg and enable ACPI interrupts
> +      ///         Read back is needed to enforce the sideband and primary
> ordering.
> +      ///
> +      PchPcrAndThenOr32WithReadback (
> +        PID_SERIALIO,
> +        SerialIoPciCfgCtrAddr[Controller],
> +        ~0u,
> +        (B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS |
> B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN)
> +        );
> +      ///
> +      /// Step 5. Disable device's PciCfg in PSF
> +      ///
> +      PsfHideDevice (SerialIoPsfPort (Controller));
> +      ///
> +      /// get controller out of reset
> +      ///
> +      MmioOr32 (
> +        mSerialIoAcpiAddress[Controller].Bar0 +
> R_SERIAL_IO_MEM_PPR_RESETS,
> +        B_SERIAL_IO_MEM_PPR_RESETS_FUNC |
> B_SERIAL_IO_MEM_PPR_RESETS_APB |
> B_SERIAL_IO_MEM_PPR_RESETS_IDMA
> +        );
> +      break;
> +    case PchSerialIoPci:
> +      //
> +      //  Check If device is already initialized
> +      //
> +      if (PciSegmentRead32 (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET) &
> 0xFFFFF000) {
> +        return;
> +      }
> +      ///
> +      /// reenable PciCfg in case it was disabled earlier
> +      /// Read back is needed to enforce the sideband and primary ordering.
> +      ///
> +      PchPcrAndThenOr32WithReadback (
> +        PID_SERIALIO,
> +        SerialIoPciCfgCtrAddr[Controller],
> +        (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS |
> B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN),
> +        0
> +        );
> +      PsfUnhideDevice (SerialIoPsfPort (Controller));
> +      ///
> +      /// Disable Bar1
> +      /// Disable Bar1 in PSF
> +      /// Read back is needed to enforce the sideband and primary ordering.
> +      ///
> +      PchPcrAndThenOr32WithReadback (
> +        PID_SERIALIO,
> +        SerialIoPciCfgCtrAddr[Controller],
> +        ~0u,
> +        B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS
> +        );
> +      PsfDisableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2);
> +
> +      //
> +      // Assign BAR0 and Set Memory space Enable
> +      //
> +      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW,
> mSerialIoAcpiAddress[Controller].Bar0);
> +      PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
> +      PciSegmentOr32    (PciCfgBase + PCI_COMMAND_OFFSET,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> +      ///
> +      /// get controller out of reset
> +      ///
> +      MmioOr32 (
> +        mSerialIoAcpiAddress[Controller].Bar0 +
> R_SERIAL_IO_MEM_PPR_RESETS,
> +        B_SERIAL_IO_MEM_PPR_RESETS_FUNC |
> B_SERIAL_IO_MEM_PPR_RESETS_APB |
> B_SERIAL_IO_MEM_PPR_RESETS_IDMA
> +        );
> +      break;
> +    default:
> +      return;
> +  }
> +
> +  ///
> +  /// Step X. Program clock dividers for UARTs
> +  /// Step Y. Enable Byte addressing for UARTs in legacy mode
> +  ///
> +  if ((Controller >= PchSerialIoIndexUart0 && Controller <=
> PchSerialIoIndexUart2) && (DeviceMode != PchSerialIoDisabled)) {
> +    MmioWrite32 (mSerialIoAcpiAddress[Controller].Bar0 +
> R_SERIAL_IO_MEM_PPR_CLK,
> +      (B_SERIAL_IO_MEM_PPR_CLK_UPDATE |
> (V_SERIAL_IO_MEM_PPR_CLK_N_DIV << 16) |
> +       (V_SERIAL_IO_MEM_PPR_CLK_M_DIV << 1) |
> B_SERIAL_IO_MEM_PPR_CLK_EN )
> +      );
> +
> +    Data32And = (UINT32)
> (~(B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << (Controller -
> PchSerialIoIndexUart0)));
> +    Data32Or = 0x0;
> +    if (DeviceMode == PchSerialIoHidden) {
> +      Data32Or = (B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN <<
> (Controller - PchSerialIoIndexUart0));
> +    }
> +    PchPcrAndThenOr32 (PID_SERIALIO,
> R_SERIAL_IO_PCR_GPPRVRW7,Data32And,Data32Or);
> +    //
> +    // Dummy read after setting any of GPPRVRW7.
> +    // Required for UART 16550 8-bit Legacy mode to become active
> +    //
> +    MmioRead32 (mSerialIoAcpiAddress[Controller].Bar0 +
> R_SERIAL_IO_MEM_PPR_CLK);
> +    //
> +    // Loop until Uart has successfuly moved to 8 bit mode
> +    //
> +    if (DeviceMode == PchSerialIoHidden) {
> +      Uart8BitLoop = 10;
> +      while (Uart8BitLoop > 0) {
> +        if (DetectAccessMode (mSerialIoAcpiAddress[Controller].Bar0) ==
> AccessMode8bit) {
> +          return;
> +        }
> +        Uart8BitLoop--;
> +      }
> +    }
> +  }
> +
> +  ///
> +  /// Step Z. Program I2C SDA hold registers
> +  ///
> +  if (Controller >= PchSerialIoIndexI2C0 && Controller <= GetMaxI2cNumber
> ()) {
> +    if (DeviceMode != PchSerialIoDisabled) {
> +      MmioOr32 (mSerialIoAcpiAddress[Controller].Bar0 +
> R_SERIAL_IO_MEM_I2C_SDA_HOLD,
> V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE);
> +    }
> +  }
> +
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLibCnl.c
> new file mode 100644
> index 0000000000..28ccd626af
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/P
> chSerialIoLibCnl.c
> @@ -0,0 +1,181 @@
> +/** @file
> +  PCH Serial IO Lib implementation Cannon Lake specific.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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 <IndustryStandard/Pci30.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PcdLib.h>
> +#include <Private/Library/GpioPrivateLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Private/Library/PchPsfPrivateLib.h>
> +
> +#include <PchLimits.h>
> +#include <Register/PchRegsSerialIoCnl.h>
> +#include "PchSerialIoLibInternal.h"
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CHAR8
> mCnlAcpiHid[PCH_MAX_SERIALIO_CONTROLLERS][SERIALIO_HID_LENGTH] =
> +{
> +  "INT34B2",
> +  "INT34B3",
> +  "INT34B4",
> +  "INT34B5",
> +  "INT34B6",
> +  "INT34B7",
> +  "INT34B0",
> +  "INT34B1",
> +  "INT34BC",
> +  "INT34B8",
> +  "INT34B9",
> +  "INT34BA"
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchLpSerialIoId
> [PCH_MAX_SERIALIO_CONTROLLERS] =
> +{
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID,
> +  V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchHSerialIoId
> [PCH_MAX_SERIALIO_CONTROLLERS] =
> +{
> +  V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID,
> +                                         0,
> +                                         0,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID,
> +  V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_BDF_NUMBERS
> mSerialIoBdf [PCH_MAX_SERIALIO_CONTROLLERS] =
> +{
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1},
> +  {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2,
> PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2}
> +};
> +
> +
> +/**
> +  Returns index of the last i2c controller
> +
> +  @param[in] Number                     Number of SerialIo controller
> +
> +  @retval                               Index of I2C controller
> +**/
> +PCH_SERIAL_IO_CONTROLLER
> +GetMaxI2cNumber (
> +  VOID
> +  )
> +{
> +  if (IsPchH ()) {
> +    return PchSerialIoIndexI2C3;
> +  } else {
> +    return PchSerialIoIndexI2C5;
> +  }
> +}
> +
> +/**
> +  Checks if Device with given PciDeviceId is one of SerialIo controllers
> +  If yes, its number is returned through Number parameter, otherwise
> Number is not updated
> +
> +  @param[in]  PciDevId                  Device ID
> +  @param[out] Number                    Number of SerialIo controller
> +
> +  @retval TRUE                          Yes it is a SerialIo controller
> +  @retval FALSE                         No it isn't a SerialIo controller
> +**/
> +BOOLEAN
> +IsSerialIoPciDevId (
> +  IN  UINT16                    PciDevId,
> +  OUT PCH_SERIAL_IO_CONTROLLER  *Number
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER Controller;
> +
> +  for (Controller = 0; Controller < GetPchMaxSerialIoControllersNum ();
> Controller++) {
> +    if ((IsPchLp () && (PciDevId == mCnlPchLpSerialIoId[Controller])) ||
> +        (IsPchH () && (PciDevId == mCnlPchHSerialIoId[Controller])))
> +    {
> +      *Number = Controller;
> +      return TRUE;
> +    }
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Finds PCI Device Number of SerialIo devices.
> +
> +  @param[in] SerialIoNumber             Serial IO device
> +
> +  @retval                               SerialIo device number
> +**/
> +UINT8
> +GetSerialIoDeviceNumber (
> +  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
> +  )
> +{
> +  return mSerialIoBdf[SerialIoNumber].DevNum;
> +}
> +
> +/**
> +  Finds PCI Function Number of SerialIo devices.
> +
> +  @param[in] SerialIoNumber             Serial IO device
> +
> +  @retval                               SerialIo funciton number
> +**/
> +UINT8
> +GetSerialIoFunctionNumber (
> +  IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
> +  )
> +{
> +  return mSerialIoBdf[SerialIoNumber].FuncNum;
> +}
> +
> +/**
> +  Returns string with AcpiHid assigned to selected SerialIo controller
> +
> +  @param[in] Number                     Number of SerialIo controller
> +
> +  @retval                               pointer to 8-byte string
> +**/
> +CHAR8*
> +GetSerialIoAcpiHid (
> +  IN PCH_SERIAL_IO_CONTROLLER Number
> +  )
> +{
> +  return mCnlAcpiHid[Number];
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartL
> ib/PeiDxeSmmPchSerialIoUartLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartL
> ib/PeiDxeSmmPchSerialIoUartLib.c
> new file mode 100644
> index 0000000000..621a473cfa
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartL
> ib/PeiDxeSmmPchSerialIoUartLib.c
> @@ -0,0 +1,372 @@
> +/** @file
> +  PCH Serial IO UART Lib implementation.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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/PchPcrLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchSerialIoUartLib.h>
> +#include <IndustryStandard/Pci30.h>
> +
> +#define MAX_BAUD_RATE      115200
> +
> +#define R_PCH_SERIAL_IO_8BIT_UART_RXBUF      0x00
> +#define R_PCH_SERIAL_IO_8BIT_UART_TXBUF      0x00
> +#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW   0x00
> +#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH  0x01
> +#define R_PCH_SERIAL_IO_8BIT_UART_FCR        0x02
> +#define R_PCH_SERIAL_IO_8BIT_UART_IIR        0x02
> +#define R_PCH_SERIAL_IO_8BIT_UART_LCR        0x03
> +#define R_PCH_SERIAL_IO_8BIT_UART_MCR        0x04
> +#define R_PCH_SERIAL_IO_8BIT_UART_LSR        0x05
> +#define R_PCH_SERIAL_IO_8BIT_UART_USR        0x1F
> +#define R_PCH_SERIAL_IO_32BIT_UART_CTR       0xFC //Component Type
> Register contains identification code
> +#define UART_COMPONENT_IDENTIFICATION_CODE   0x44570110
> +
> +#define B_PCH_SERIAL_IO_UART_IIR_FIFOSE   BIT7|BIT6
> +#define B_PCH_SERIAL_IO_UART_LSR_RXDA     BIT0
> +#define B_PCH_SERIAL_IO_UART_LSR_BI       BIT4
> +#define B_PCH_SERIAL_IO_UART_LSR_TXRDY    BIT5
> +#define B_PCH_SERIAL_IO_UART_LCR_DLAB     BIT7
> +#define B_PCH_SERIAL_IO_UART_FCR_FCR      BIT0
> +#define B_PCH_SERIAL_IO_UART_MCR_RTS      BIT1
> +#define B_PCH_SERIAL_IO_UART_MCR_AFCE     BIT5
> +#define B_PCH_SERIAL_IO_UART_USR_TFNF     BIT1
> +
> +/**
> +  Returns UART's currently active access mode, 8 or 32 bit
> +
> +  @param[in]  MmioBase    Base address of UART MMIO space
> +
> +  @retval     AccessMode8bit
> +  @retval     AccessMode32bit
> +**/
> +UART_ACCESS_MODE
> +DetectAccessMode (
> +  IN UINTN  MmioBase
> +  )
> +{
> +  if (MmioRead32 (MmioBase + R_PCH_SERIAL_IO_32BIT_UART_CTR) ==
> UART_COMPONENT_IDENTIFICATION_CODE) {
> +    return AccessMode32bit;
> +  } else {
> +    return AccessMode8bit;
> +  }
> +}
> +
> +
> +/**
> +  Register access helper. Depending on SerialIO UART mode,
> +  its registers are aligned to 1 or 4 bytes and have 8 or 32bit size
> +
> +  @param[in]  AccessMode     Selects between 8bit access to 1-byte aligned
> registers or 32bit access to 4-byte algined
> +  @param[in]  BaseAddress    Base address of UART MMIO space
> +  @param[in]  Offset         Register offset in 8bit mode
> +  @param[in]  Data           Data to be written
> +**/
> +STATIC
> +VOID
> +WriteRegister (
> +  IN UART_ACCESS_MODE AccessMode,
> +  IN UINTN            BaseAddress,
> +  IN UINTN            Offset,
> +  IN UINT8            Data
> +  )
> +{
> +  if (AccessMode == AccessMode32bit) {
> +    MmioWrite32 (BaseAddress + 4*Offset, Data);
> +  } else {
> +    MmioWrite8 (BaseAddress + Offset, Data);
> +  }
> +}
> +
> +/**
> +  Register access helper. Depending on SerialIO UART mode,
> +  its registers are aligned to 1 or 4 bytes and have 8 or 32bit size
> +
> +  @param[in]  AccessMode     Selects between 8bit access to 1-byte aligned
> registers or 32bit access to 4-byte algined
> +  @param[in]  BaseAddress    Base address of UART MMIO space
> +  @param[in]  Offset         Register offset in 8bit mode
> +  @retval                    retrieved register value, always 8bit regardless of
> access mode
> +**/
> +STATIC
> +UINT8
> +ReadRegister (
> +  IN UART_ACCESS_MODE AccessMode,
> +  IN UINTN            BaseAddress,
> +  IN UINTN            Offset
> +  )
> +{
> +  if (AccessMode == AccessMode32bit) {
> +    return (UINT8) (0xFF & MmioRead32 (BaseAddress + 4*Offset));
> +  } else {
> +    return MmioRead8 (BaseAddress + Offset);
> +  }
> +}
> +
> +/**
> +  SerialIo UART in PCI mode will become unavailable when PCI enumerator
> +  disables its memory space. This function re-enables it
> +
> +  @param[in]  UartNumber           Selects Serial IO UART device (0-2)
> +**/
> +STATIC
> +VOID
> +EnablePciMse (
> +  IN UINT8  UartNumber
> +  )
> +{
> +  UINTN  CfgSpace;
> +
> +  CfgSpace = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 1);
> +  if (MmioRead16 (CfgSpace + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
> +    return;
> +  }
> +  if ((MmioRead16 (CfgSpace + PCI_COMMAND_OFFSET) &
> EFI_PCI_COMMAND_MEMORY_SPACE) !=
> EFI_PCI_COMMAND_MEMORY_SPACE) {
> +    if ((MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) &
> 0xFFFFF000) != 0x0 &&
> +        (MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) &
> 0xFFFFF000) != 0xFFFFF000 ) {
> +      MmioOr8 (CfgSpace + PCI_COMMAND_OFFSET,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> +    }
> +  }
> +}
> +
> +/**
> +  Initialize selected SerialIo UART.
> +  This init function MUST be used prior any SerialIo UART functions to init
> serial io controller if platform is going use serialio UART as debug output.
> +
> +  @param  UartNumber           Selects Serial IO UART device (0-2)
> +  @param  FifoEnable           When TRUE, enables 64-byte FIFOs.
> +  @param  BaudRate             Baud rate.
> +  @param  LineControl          Data length, parity, stop bits.
> +  @param  HardwareFlowControl  Automated hardware flow control. If
> TRUE, hardware automatically checks CTS when sending data, and sets RTS
> when receiving data.
> +**/
> +VOID
> +EFIAPI
> +PchSerialIoUartInit (
> +  UINT8            UartNumber,
> +  BOOLEAN          FifoEnable,
> +  UINT32           BaudRate,
> +  UINT8            LineControl,
> +  BOOLEAN          HardwareFlowControl
> +  )
> +{
> +  UINTN            Base;
> +  UINTN            Divisor;
> +  UART_ACCESS_MODE AccessMode;
> +
> +  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
> +  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
> +    //
> +    // Base is not programmed, skip it.
> +    //
> +    return;
> +  }
> +  EnablePciMse (UartNumber);
> +  AccessMode = DetectAccessMode (Base);
> +
> +  Divisor = MAX_BAUD_RATE / BaudRate;
> +
> +  //
> +  // Configure baud rate
> +  //
> +  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR,
> B_PCH_SERIAL_IO_UART_LCR_DLAB);
> +  WriteRegister (AccessMode, Base,
> R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
> +  WriteRegister (AccessMode, Base,
> R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
> +  //
> +  //  Configure Line control and switch back to bank 0
> +  //
> +  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR,
> LineControl & 0x1F);
> +  //
> +  // Enable and reset FIFOs
> +  //
> +  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_FCR,
> FifoEnable?B_PCH_SERIAL_IO_UART_FCR_FCR:0 );
> +  //
> +  // Put Modem Control Register(MCR) into its reset state of 0x00.
> +  //
> +  WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_MCR,
> B_PCH_SERIAL_IO_UART_MCR_RTS |
> (HardwareFlowControl?B_PCH_SERIAL_IO_UART_MCR_AFCE:0));
> +}
> +
> +/**
> +  Write data to serial device.
> +
> +  If the buffer is NULL, then return 0;
> +  if NumberOfBytes is zero, then return 0.
> +
> +  @param  UartNumber       Selects Serial IO UART device (0-2)
> +  @param  Buffer           Point of data buffer which need to be writed.
> +  @param  NumberOfBytes    Number of output bytes which are cached in
> Buffer.
> +
> +  @retval                  Actual number of bytes writed to serial device.
> +**/
> +UINTN
> +EFIAPI
> +PchSerialIoUartOut (
> +  IN UINT8            UartNumber,
> +  IN UINT8            *Buffer,
> +  IN UINTN            NumberOfBytes
> +  )
> +{
> +  UINTN            BytesLeft;
> +  UINTN            Base;
> +  UART_ACCESS_MODE AccessMode;
> +
> +  if (NULL == Buffer) {
> +    return 0;
> +  }
> +
> +  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
> +  //
> +  // Sanity checks to avoid infinite loop when trying to print through
> uninitialized UART
> +  //
> +  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
> +    return 0;
> +  }
> +  EnablePciMse (UartNumber);
> +  AccessMode = DetectAccessMode (Base);
> +
> +  if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) ==
> 0xFF) {
> +    return 0;
> +  }
> +
> +  BytesLeft = NumberOfBytes;
> +
> +  while (BytesLeft != 0) {
> +    //
> +    // Write data while there's room in TXFIFO. If HW Flow Control was enabled,
> it happens automatically on hardware level.
> +    //
> +    if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR)
> & B_PCH_SERIAL_IO_UART_USR_TFNF) {
> +      WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_TXBUF,
> *Buffer);
> +      Buffer++;
> +      BytesLeft--;
> +    }
> +  }
> +
> +  return NumberOfBytes;
> +}
> +
> +/*
> +  Read data from serial device and save the datas in buffer.
> +
> +  If the buffer is NULL, then return 0;
> +  if NumberOfBytes is zero, then return 0.
> +
> +  @param  UartNumber           Selects Serial IO UART device (0-2)
> +  @param  Buffer               Point of data buffer which need to be writed.
> +  @param  NumberOfBytes        Number of output bytes which are cached
> in Buffer.
> +  @param  WaitUntilBufferFull  When TRUE, function waits until whole
> buffer is filled. When FALSE, function returns as soon as no new characters are
> available.
> +
> +  @retval                      Actual number of bytes raed to serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +PchSerialIoUartIn (
> +  IN  UINT8            UartNumber,
> +  OUT UINT8            *Buffer,
> +  IN  UINTN            NumberOfBytes,
> +  IN  BOOLEAN          WaitUntilBufferFull
> +  )
> +{
> +  UINTN            BytesReceived;
> +  UINTN            Base;
> +  UART_ACCESS_MODE AccessMode;
> +  UINT8            Lsr;
> +  UINT8            Byte;
> +
> +  if (NULL == Buffer) {
> +    return 0;
> +  }
> +
> +  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
> +  //
> +  // Sanity checks to avoid infinite loop when trying to print through
> uninitialized UART
> +  //
> +  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
> +    return 0;
> +  }
> +  EnablePciMse (UartNumber);
> +  AccessMode = DetectAccessMode (Base);
> +
> +  BytesReceived = 0;
> +
> +  while (BytesReceived != NumberOfBytes) {
> +    //
> +    // Read the line status register
> +    //
> +    Lsr = ReadRegister(AccessMode, Base,
> R_PCH_SERIAL_IO_8BIT_UART_LSR);
> +
> +    //
> +    // If there is data in the RX buffer, read it.
> +    //
> +    if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_RXDA) != 0) {
> +      Byte = ReadRegister (AccessMode, Base,
> R_PCH_SERIAL_IO_8BIT_UART_RXBUF);
> +      //
> +      // Check if the break interrupt bit is set. If set, the byte read from the
> +      // RX buffer is invalid and should be ignored. If not set, copy the byte into
> +      // the receive buffer.
> +      //
> +      if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_BI) == 0) {
> +        *Buffer = Byte;
> +        Buffer++;
> +        BytesReceived++;
> +      }
> +    } else {
> +      if (!WaitUntilBufferFull) {
> +        //
> +        // If there's no data and function shouldn't wait, exit early
> +        //
> +        return BytesReceived;
> +      }
> +    }
> +  }
> +  return BytesReceived;
> +}
> +
> +/**
> +  Polls a serial device to see if there is any data waiting to be read.
> +
> +  Polls a serial device to see if there is any data waiting to be read.
> +  If there is data waiting to be read from the serial device, then TRUE is
> returned.
> +  If there is no data waiting to be read from the serial device, then FALSE is
> returned.
> +
> +  @param  UartNumber       Selects Serial IO UART device (0-2)
> +
> +  @retval TRUE             Data is waiting to be read from the serial device.
> +  @retval FALSE            There is no data waiting to be read from the serial
> device.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +PchSerialIoUartPoll (
> +  IN  UINT8            UartNumber
> +  )
> +{
> +  UINTN Base;
> +  UART_ACCESS_MODE AccessMode;
> +
> +  Base = FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0);
> +  //
> +  // Sanity checks to avoid infinite loop when trying to print through
> uninitialized UART
> +  //
> +  if ((Base & 0xFFFFFF00) == 0x0 || (Base & 0xFFFFF000) == 0xFFFFF000) {
> +    return 0;
> +  }
> +  EnablePciMse (UartNumber);
> +  AccessMode = DetectAccessMode (Base);
> +
> +  //
> +  // Read the serial port status
> +  //
> +  if ((ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LSR) &
> B_PCH_SERIAL_IO_UART_LSR_RXDA) != 0) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo
> nLib/WdtCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo
> nLib/WdtCommon.c
> new file mode 100644
> index 0000000000..679dcae0ab
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo
> nLib/WdtCommon.c
> @@ -0,0 +1,242 @@
> +/** @file
> +  Library that contains common parts of WdtPei and WdtDxe. Not a
> standalone module.
> +
> +  Copyright (c) 2019 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/PmcLib.h>
> +#include <Register/PchRegsPmc.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8     mAllowExpectedReset = 0;
> +
> +/**
> +  Reads LPC bridge to get Watchdog Timer address
> +
> +
> +  @retval UINT32                  Watchdog's address
> +**/
> +UINT32
> +WdtGetAddress (
> +  VOID
> +  )
> +{
> +  return PmcGetAcpiBase () + R_ACPI_IO_OC_WDT_CTL;
> +}
> +
> +/**
> +  Reloads WDT with new timeout value and starts it. Also sets Unexpected
> Reset bit, which
> +  causes the next reset to be treated as watchdog expiration - unless
> AllowKnownReset()
> +  function was called too.
> +
> +  @param[in] TimeoutValue         Time in seconds before WDT times out.
> Supported range = 1 - 1024.
> +
> +  @retval EFI_SUCCESS             if everything's OK
> +  @retval EFI_INVALID_PARAMETER   if TimeoutValue parameter is wrong
> +**/
> +EFI_STATUS
> +EFIAPI
> +WdtReloadAndStart (
> +  IN  UINT32  TimeoutValue
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "\n(Wdt) ReloadAndStartTimer(%d)\n",
> TimeoutValue));
> +
> +  if ((TimeoutValue > B_ACPI_IO_OC_WDT_CTL_TOV_MASK) ||
> (TimeoutValue == 0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +  Readback |= (B_ACPI_IO_OC_WDT_CTL_EN |
> B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_ICCSURV);
> +  if (mAllowExpectedReset == 0) {
> +    Readback |= B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS;
> +  }
> +
> +  if (PcdGetBool (PcdOcEnableWdtforDebug) == FALSE) {
> +    ///
> +    /// WDT will not be turned on. This is to prevent platform reboots
> triggered
> +    /// by WDT expiration, which can be expected when processor is halted for
> debugging
> +    ///
> +    Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN |
> B_ACPI_IO_OC_WDT_CTL_FORCE_ALL |
> B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
> +    DEBUG ((DEBUG_INFO, "(Wdt) Wdt disabled in Debug BIOS\n"));
> +  }
> +
> +  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
> +  Readback |= ((TimeoutValue - 1) & B_ACPI_IO_OC_WDT_CTL_TOV_MASK);
> +  IoWrite32 (WdtGetAddress (), Readback);
> +  Readback |= B_ACPI_IO_OC_WDT_CTL_RLD;
> +  IoWrite32 (WdtGetAddress (), Readback);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Disables WDT timer.
> +
> +
> +**/
> +VOID
> +EFIAPI
> +WdtDisable (
> +  VOID
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) DisableTimer\n"));
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_EN |
> B_ACPI_IO_OC_WDT_CTL_FORCE_ALL |
> B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
> +  IoWrite32 (WdtGetAddress (), Readback);
> +}
> +
> +/**
> +  Returns WDT failure status.
> +
> +
> +  @retval V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE   If there was WDT
> expiration or unexpected reset
> +  @retval V_ACPI_IO_OC_WDT_CTL_STATUS_OK        Otherwise
> +**/
> +UINT8
> +EFIAPI
> +WdtCheckStatus (
> +  VOID
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) CheckTimerStatus\n"));
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) Readback = (%x)\n", Readback));
> +
> +  if (Readback & B_ACPI_IO_OC_WDT_CTL_FAILURE_STS) {
> +    DEBUG ((DEBUG_INFO, "(Wdt) Status = FAILURE\n"));
> +    return V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE;
> +  } else {
> +    return V_ACPI_IO_OC_WDT_CTL_STATUS_OK;
> +  }
> +}
> +
> +/**
> +  Normally, each reboot performed while watchdog runs is considered a
> failure.
> +  This function allows platform to perform expected reboots with WDT
> running,
> +  without being interpreted as failures.
> +  In DXE phase, it is enough to call this function any time before reset.
> +  In PEI phase, between calling this function and performing reset,
> ReloadAndStart()
> +  must not be called.
> +
> +
> +**/
> +VOID
> +EFIAPI
> +WdtAllowKnownReset (
> +  VOID
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) AllowKnownReset\n"));
> +
> +  mAllowExpectedReset = 1;
> +
> +  Readback  = IoRead32 (WdtGetAddress ());
> +  Readback &= ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS |
> B_ACPI_IO_OC_WDT_CTL_FORCE_ALL);
> +  IoWrite32 (WdtGetAddress (), Readback);
> +}
> +
> +/**
> +  Returns information if WDT coverage for the duration of BIOS execution
> +  was requested by an OS application
> +
> +
> +  @retval TRUE                    if WDT was requested
> +  @retval FALSE                   if WDT was not requested
> +**/
> +UINT8
> +EFIAPI
> +IsWdtRequired (
> +  VOID
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtRequired"));
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +
> +
> +  if ((Readback & B_ACPI_IO_OC_WDT_CTL_AFTER_POST) != 0) {
> +    DEBUG ((DEBUG_INFO, " - yes\n"));
> +    return TRUE;
> +  } else {
> +    DEBUG ((DEBUG_INFO, " - no\n"));
> +    return FALSE;
> +  }
> +
> +}
> +
> +/**
> +  Returns WDT enabled/disabled status.
> +
> +
> +  @retval TRUE                    if WDT is enabled
> +  @retval FALSE                   if WDT is disabled
> +**/
> +UINT8
> +EFIAPI
> +IsWdtEnabled (
> +  VOID
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtEnabled"));
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +
> +
> +  if ((Readback & B_ACPI_IO_OC_WDT_CTL_EN) != 0) {
> +    DEBUG ((DEBUG_INFO, " - yes\n"));
> +    return TRUE;
> +  } else {
> +    DEBUG ((DEBUG_INFO, " - no\n"));
> +    return FALSE;
> +  }
> +
> +}
> +
> +/**
> +  Returns WDT locked status.
> +
> +
> +  @retval TRUE                    if WDT is locked
> +  @retval FALSE                   if WDT is unlocked
> +**/
> +UINT8
> +EFIAPI
> +IsWdtLocked (
> +  VOID
> +  )
> +{
> +  UINT32  Readback;
> +
> +  DEBUG ((DEBUG_INFO, "(Wdt) IsWdtLocked"));
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +
> +
> +  if ((Readback & B_ACPI_IO_OC_WDT_CTL_LCK) != 0) {
> +    DEBUG ((DEBUG_INFO, " - yes\n"));
> +    return TRUE;
> +  } else {
> +    DEBUG ((DEBUG_INFO, " - no\n"));
> +    return FALSE;
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
> new file mode 100644
> index 0000000000..8e026b3ab6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
> @@ -0,0 +1,330 @@
> +/** @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) 2019 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 <Private/Library/PmcPrivateLib.h>
> +#include <PchReservedResources.h>
> +#include <Register/PchRegsPmc.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);
> +}
> +
> +/**
> +  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 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 RTC 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_B) &
> 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 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);
> +}
> +
> +/**
> +  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);
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.
> c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.
> c
> new file mode 100644
> index 0000000000..05557931c2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.
> c
> @@ -0,0 +1,41 @@
> +/** @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) 2019 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>
> +/**
> +  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
> +GetSataRegBase (
> +  IN UINT32  SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  return PCI_SEGMENT_LIB_ADDRESS (
> +           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +           DEFAULT_PCI_BUS_NUMBER_PCH,
> +           GetSataPcieDeviceNum (SataCtrlIndex),
> +           GetSataPcieFunctionNum (SataCtrlIndex),
> +           0
> +           );
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibC
> df.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib
> Cdf.c
> new file mode 100644
> index 0000000000..5cec818dd6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib
> Cdf.c
> @@ -0,0 +1,101 @@
> +/** @file
> +  Pch SATA library for CedarFork SouthCluster.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/PchInfoLib.h>
> +#include <PchLimits.h>
> +#include <Register/PchRegsSata.h>
> +#include <Library/SataLib.h>
> +
> +/**
> +  Get Maximum Sata Controller Number
> +
> +  @param[in] None
> +
> +  @retval Maximum Sata Controller Number
> +**/
> +UINT8
> +GetPchMaxSataControllerNum (
> +  VOID
> +  )
> +{
> +  return 3;
> +}
> +
> +/**
> +  Get Pch Maximum Sata Port Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval Pch Maximum Sata Port Number
> +**/
> +UINT8
> +GetPchMaxSataPortNum (
> +  IN UINT8      SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  return 8;
> +}
> +
> +/**
> +  Get SATA controller PCIe Device Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe Device Number
> +**/
> +UINT8
> +GetSataPcieDeviceNum (
> +  IN UINT8  SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
> +    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_1;
> +  } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
> +    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_2;
> +  } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
> +    return PCI_DEVICE_NUMBER_CDF_PCH_SATA_3;
> +  } else {
> +    ASSERT (FALSE);
> +    return 0;
> +  }
> +}
> +
> +/**
> +  Get SATA controller PCIe Function Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe Function Number
> +**/
> +UINT8
> +GetSataPcieFunctionNum (
> +  IN UINT8  SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
> +    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1;
> +  } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
> +    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2;
> +  } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
> +    return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3;
> +  } else {
> +    ASSERT (FALSE);
> +    return 0;
> +  }
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibC
> nl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib
> Cnl.c
> new file mode 100644
> index 0000000000..0eca692a74
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib
> Cnl.c
> @@ -0,0 +1,88 @@
> +/** @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) 2019 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/PchRegsSata.h>
> +#include <Library/SataLib.h>
> +
> +/**
> +  Get Maximum Sata Controller Number
> +
> +  @param[in] None
> +
> +  @retval Maximum Sata Controller Number
> +**/
> +UINT8
> +GetPchMaxSataControllerNum (
> +  VOID
> +  )
> +{
> +  return 1;
> +}
> +
> +/**
> +  Get Pch Maximum Sata Port Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval Pch Maximum Sata Port Number
> +**/
> +UINT8
> +GetPchMaxSataPortNum (
> +  IN UINT32      SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  if (IsPchLp ()) {
> +    return 3;
> +  } else {
> +    return 8;
> +  }
> +}
> +
> +/**
> +  Get SATA controller PCIe Device Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe Device Number
> +**/
> +UINT8
> +GetSataPcieDeviceNum (
> +  IN UINT32  SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  return PCI_DEVICE_NUMBER_PCH_SATA;
> +}
> +
> +/**
> +  Get SATA controller PCIe Function Number
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval SATA controller PCIe Function Number
> +**/
> +UINT8
> +GetSataPcieFunctionNum (
> +  IN UINT32  SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  return PCI_FUNCTION_NUMBER_PCH_SATA;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
> new file mode 100644
> index 0000000000..22f6fb215f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
> @@ -0,0 +1,130 @@
> +/** @file
> +  The PEI Library Implements OcWdt Support.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/Wdt.h>
> +#include <Library/PchWdtCommonLib.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/IoLib.h>
> +#include <Register/PchRegsPmc.h>
> +
> +static WDT_PPI mWdtPpi = {
> +  WdtReloadAndStart,
> +  WdtCheckStatus,
> +  WdtDisable,
> +  WdtAllowKnownReset,
> +  IsWdtRequired,
> +  IsWdtEnabled
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR  mInstallWdtPpi = {
> +  (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gWdtPpiGuid,
> +  &mWdtPpi
> +};
> +
> +/**
> +  Reads PCH registers to check if platform wakes from S3/S4
> +
> +  @retval TRUE                    if platfrom wakes from S3/S4
> +  @retval FALSE                   otherwise
> +**/
> +BOOLEAN
> +IsWakeFromS3S4 (
> +  VOID
> +  )
> +{
> +  PMC_SLEEP_STATE  SleepType;
> +
> +  SleepType = PmcGetSleepTypeAfterWake ();
> +  if ((SleepType == PmcS3SleepState) || (SleepType == PmcS4SleepState)) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +
> +}
> +
> +/**
> +  Check for unexpected reset.
> +  If there was an unexpected reset, enforces WDT expiration.
> +**/
> +VOID
> +OcWdtResetCheck (
> +  VOID
> +  )
> +{
> +  UINT32      Readback;
> +
> +  Readback = IoRead32 (WdtGetAddress ());
> +  DEBUG ((DEBUG_INFO, "(WDT) OcWdtResetCheck()\n"));
> +
> +  ///
> +  /// If there was a WDT expiration, set Failure Status and clear timeout status
> bits
> +  /// Timeout status bits are cleared by writing '1'
> +  ///
> +  if (Readback & (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS |
> B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS)) {
> +    DEBUG ((DEBUG_ERROR, "(WDT) Expiration detected.\n", Readback));
> +    Readback |= B_ACPI_IO_OC_WDT_CTL_FAILURE_STS;
> +    Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS |
> B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
> +    Readback &= ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
> +  } else {
> +    ///
> +    /// If there was unexpected reset but no WDT expiration and no resume
> from S3/S4,
> +    /// clear unexpected reset status and enforce expiration. This is to inform
> Firmware
> +    /// which has no access to unexpected reset status bit, that something
> went wrong.
> +    ///
> +    if ((Readback & B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS)
> && !IsWakeFromS3S4()) {
> +      if (PcdGetBool (PcdOcEnableWdtforDebug)) {
> +        DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected and
> ignored.\n"));
> +        Readback &= ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS |
> B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS);
> +        Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS |
> B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
> +      } else {
> +        DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected. Enforcing
> Wdt expiration.\n"));
> +        WdtReloadAndStart (1);
> +        ///
> +        /// wait for reboot caused by WDT expiration
> +        ///
> +        CpuDeadLoop ();
> +      }
> +    } else {
> +      ///
> +      /// No WDT expiration and no unexpected reset - clear Failure status
> +      ///
> +      DEBUG ((DEBUG_INFO, "(WDT) Status OK.\n", Readback));
> +      Readback &= ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS);
> +      Readback |= (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS |
> B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS);
> +    }
> +  }
> +
> +  IoWrite32 (WdtGetAddress (), Readback);
> +
> +  return;
> +}
> +
> +/**
> +  This function install WDT PPI
> +
> +  @retval EFI_STATUS  Results of the installation of the WDT PPI
> +**/
> +EFI_STATUS
> +EFIAPI
> +OcWdtInit (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = PeiServicesInstallPpi (&mInstallWdtPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt
> LibNull.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt
> LibNull.c
> new file mode 100644
> index 0000000000..182218ffcf
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt
> LibNull.c
> @@ -0,0 +1,23 @@
> +/** @file
> +  The Null PEI Library Implements OcWdt Support.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +/**
> +  This function install WDT PPI
> +
> +  @retval EFI_STATUS  Results of the installation of the WDT PPI
> +**/
> +EFI_STATUS
> +EFIAPI
> +OcWdtInit (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMem
> PrintPolicy.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMem
> PrintPolicy.c
> new file mode 100644
> index 0000000000..bd1e2711da
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMem
> PrintPolicy.c
> @@ -0,0 +1,307 @@
> +/** @file
> +  Print whole PCH_PREMEM_POLICY_PPI
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyLibrary.h"
> +
> +/**
> +  Print PCH_GENERAL_PREMEM_CONFIG and serial out.
> +
> +  @param[in] PchGeneralPreMemConfig     Pointer to a
> PCH_GENERAL_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintGeneralPreMemConfig (
> +  IN CONST PCH_GENERAL_PREMEM_CONFIG    *PchGeneralPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH General PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Port80Route= %x\n",
> PchGeneralPreMemConfig->Port80Route));
> +}
> +
> +/**
> +  Print PCH_DCI_PREMEM_CONFIG and serial out.
> +
> +  @param[in] DciPreMemConfig            Pointer to a
> PCH_DCI_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintDciPreMemConfig (
> +  IN CONST PCH_DCI_PREMEM_CONFIG        *DciPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH DCI PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "PlatformDebugConsent = %x\n",
> DciPreMemConfig->PlatformDebugConsent));
> +  DEBUG ((DEBUG_INFO, "DciUsb3TypecUfpDbg = %x\n",
> DciPreMemConfig->DciUsb3TypecUfpDbg));
> +}
> +
> +/**
> +  Print PCH_WDT_PREMEM_CONFIG and serial out.
> +
> +  @param[in] WdtPreMemConfig            Pointer to a
> PCH_WDT_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintWdtPreMemConfig (
> +  IN CONST PCH_WDT_PREMEM_CONFIG               *WdtPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH WDT PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "DisableAndLock= %x\n",
> WdtPreMemConfig->DisableAndLock));
> +}
> +
> +/**
> +  Print PCH_TRACE_HUB_CONFIG and serial out.
> +
> +  @param[in] TraceHubConfig             Pointer to a
> PCH_TRACE_HUB_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintTraceHubPreMemConfig (
> +  IN CONST PCH_TRACE_HUB_PREMEM_CONFIG
> *PchTraceHubPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH TraceHub PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "EnableMode= %x\n",
> PchTraceHubPreMemConfig->EnableMode));
> +  DEBUG ((DEBUG_INFO, "MemReg0Size= %x\n",
> PchTraceHubPreMemConfig->MemReg0Size));
> +  DEBUG ((DEBUG_INFO, "MemReg1Size= %x\n",
> PchTraceHubPreMemConfig->MemReg1Size));
> +}
> +
> +/**
> +  Print PCH_SMBUS_CONFIG and serial out.
> +
> +  @param[in] SmbusConfig         Pointer to a PCH_SMBUS_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintSmbusPreMemConfig (
> +  IN CONST PCH_SMBUS_PREMEM_CONFIG    *SmbusPreMemConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "------------------ PCH SMBUS PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Enable= %x\n", SmbusPreMemConfig->Enable));
> +  DEBUG ((DEBUG_INFO, " ArpEnable= %x\n",
> SmbusPreMemConfig->ArpEnable));
> +  DEBUG ((DEBUG_INFO, " DynamicPowerGating= %x\n",
> SmbusPreMemConfig->DynamicPowerGating));
> +  DEBUG ((DEBUG_INFO, " SpdWriteDisable= %x\n",
> SmbusPreMemConfig->SpdWriteDisable));
> +  DEBUG ((DEBUG_INFO, " SmbAlertEnable= %x\n",
> SmbusPreMemConfig->SmbAlertEnable));
> +  DEBUG ((DEBUG_INFO, " SmbusIoBase= %x\n",
> SmbusPreMemConfig->SmbusIoBase));
> +  DEBUG ((DEBUG_INFO, " NumRsvdSmbusAddresses= %x\n",
> SmbusPreMemConfig->NumRsvdSmbusAddresses));
> +  DEBUG ((DEBUG_INFO, " RsvdSmbusAddressTable= {"));
> +  for (Index = 0; Index < SmbusPreMemConfig->NumRsvdSmbusAddresses;
> ++Index) {
> +    DEBUG ((DEBUG_INFO, " %02xh",
> SmbusPreMemConfig->RsvdSmbusAddressTable[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, " }\n"));
> +}
> +
> +/**
> +  Print PCH_LPC_PREMEM_CONFIG and serial out.
> +
> +  @param[in] LpcPreMemConfig                  Pointer to a
> PCH_LPC_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintLpcPreMemConfig (
> +  IN CONST PCH_LPC_PREMEM_CONFIG              *LpcPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH LPC PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "EnhancePort8xhDecoding= %x\n",
> LpcPreMemConfig->EnhancePort8xhDecoding));
> +}
> +
> +/**
> +  Print PCH_HSIO_PCIE_PREMEM_CONFIG and serial out.
> +
> +  @param[in] HsioPciePreMemConfig     Pointer to a
> PCH_HSIO_PCIE_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintHsioPciePreMemConfig (
> +  IN CONST PCH_HSIO_PCIE_PREMEM_CONFIG *HsioPciePreMemConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "------------------ HSIO PCIE PreMem Config
> ------------------\n"));
> +  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtleEnable= %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtle= %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d]
> HsioTxGen1DownscaleAmpEnable= %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEnable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DownscaleAmp= %x\n",
> Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d]
> HsioTxGen2DownscaleAmpEnable= %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEnable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DownscaleAmp= %x\n",
> Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d]
> HsioTxGen3DownscaleAmpEnable= %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEnable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen3DownscaleAmp= %x\n",
> Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmphEnable= %x\n",
> Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmph= %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5Enable=
> %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5= %x\n",
> Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0Enable=
> %x\n", Index,
> HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0= %x\n",
> Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0));
> +  }
> +}
> +
> +/**
> +  Print PCH_HSIO_SATA_PREMEM_CONFIG and serial out.
> +
> +  @param[in] SataCtrlIndex            SATA controller index
> +  @param[in] HsioSataPreMemConfig     Pointer to a
> PCH_HSIO_SATA_PREMEM_CONFIG that provides the platform setting
> +**/
> +VOID
> +PchPrintHsioSataPreMemConfig (
> +  IN UINT8                             SataCtrlIndex,
> +  IN CONST PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "---------------- HSIO SATA PreMem Config for
> controller %d ----------------\n", SataCtrlIndex));
> +  for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d]
> HsioRxGen1EqBoostMagEnable= %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEnable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen1EqBoostMag=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d]
> HsioRxGen2EqBoostMagEnable= %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEnable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen2EqBoostMag=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d]
> HsioRxGen3EqBoostMagEnable= %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEnable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen3EqBoostMag=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d]
> HsioTxGen1DownscaleAmpEnable= %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmpEnable)
> );
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DownscaleAmp=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d]
> HsioTxGen2DownscaleAmpEnable= %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmpEnable)
> );
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DownscaleAmp=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d]
> HsioTxGen3DownscaleAmpEnable= %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmpEnable)
> );
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DownscaleAmp=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmphEnable=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmph= %x\n",
> Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmphEnable=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmph= %x\n",
> Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmphEnable=
> %x\n", Index,
> HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmph= %x\n",
> Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph));
> +  }
> +}
> +
> +/**
> +  Print PCH_PCIE_RP_PREMEM_CONFIG and serial out.
> +
> +  @param[in] PcieRpPreMemConfig        Pointer to a
> PCH_PCIE_RP_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintPcieRpPreMemConfig (
> +  IN CONST PCH_PCIE_RP_PREMEM_CONFIG    *PcieRpPreMemConfig
> +  )
> +{
> +  UINT32 Index;
> +  DEBUG ((DEBUG_INFO, "------------------ PCH PCIe RP PreMem Config
> ------------------\n"));
> +
> +  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " Port[%d] RpEnabled= %x\n", Index,
> (PcieRpPreMemConfig->RpEnabledMask & (UINT32) (1 << Index)) != 0 ));
> +  }
> +  DEBUG ((DEBUG_INFO, " PcieImrEnabled= %x\n",
> PcieRpPreMemConfig->PcieImrEnabled));
> +  DEBUG ((DEBUG_INFO, " PcieImrSize= %d MB\n",
> PcieRpPreMemConfig->PcieImrSize));
> +  DEBUG ((DEBUG_INFO, " ImrRpSelection= %d\n",
> PcieRpPreMemConfig->ImrRpSelection));
> +}
> +
> +/**
> +  Print PCH_HDAUDIO_PREMEM_CONFIG and serial out.
> +
> +  @param[in] LpcPreMemConfig                  Pointer to a
> PCH_HDAUDIO_PREMEM_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintHdAudioPreMemConfig (
> +  IN CONST PCH_HDAUDIO_PREMEM_CONFIG *HdaPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ HD Audio PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Enable= %x\n", HdaPreMemConfig->Enable));
> +}
> +
> +/**
> +  Print PCH_ISH_PREMEM_CONFIG  and serial out.
> +
> +  @param[in] IshPreMemConfig                  Pointer to a
> PCH_ISH_PREMEM_CONFIG  that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintIshPreMemConfig (
> +  IN CONST PCH_ISH_PREMEM_CONFIG *IshPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ ISH PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Enable= %x\n", IshPreMemConfig->Enable));
> +}
> +
> +
> +/**
> +  Print whole PCH_POLICY_PPI and serial out.
> +
> +  @param[in] SiPreMemPolicyPpi    The RC PREMEM Policy PPI instance
> +
> +**/
> +VOID
> +EFIAPI
> +PchPreMemPrintPolicyPpi (
> +  IN  SI_PREMEM_POLICY_PPI     *SiPreMemPolicyPpi
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  EFI_STATUS                      Status;
> +  PCH_GENERAL_PREMEM_CONFIG       *PchGeneralPreMemConfig;
> +  PCH_DCI_PREMEM_CONFIG           *DciPreMemConfig;
> +  PCH_WDT_PREMEM_CONFIG           *WdtPreMemConfig;
> +  PCH_TRACE_HUB_PREMEM_CONFIG     *PchTraceHubPreMemConfig;
> +  PCH_SMBUS_PREMEM_CONFIG         *SmbusPreMemConfig;
> +  PCH_LPC_PREMEM_CONFIG           *LpcPreMemConfig;
> +  PCH_HSIO_PCIE_PREMEM_CONFIG     *HsioPciePreMemConfig;
> +  PCH_HSIO_SATA_PREMEM_CONFIG     *HsioSataPreMemConfig;
> +  PCH_PCIE_RP_PREMEM_CONFIG       *PcieRpPreMemConfig;
> +  PCH_HDAUDIO_PREMEM_CONFIG       *HdaPreMemConfig;
> +  PCH_ISH_PREMEM_CONFIG           *IshPreMemConfig;
> +  UINT8                           SataCtrlIndex;
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy Start
> ------------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision= %x\n",
> SiPreMemPolicyPpi->TableHeader.Header.Revision));
> +
> +  PchPrintGeneralPreMemConfig (PchGeneralPreMemConfig);
> +  PchPrintDciPreMemConfig (DciPreMemConfig);
> +  PchPrintWdtPreMemConfig (WdtPreMemConfig);
> +  PchPrintTraceHubPreMemConfig (PchTraceHubPreMemConfig);
> +  PchPrintSmbusPreMemConfig (SmbusPreMemConfig);
> +  PchPrintLpcPreMemConfig (LpcPreMemConfig);
> +  PchPrintHsioPciePreMemConfig (HsioPciePreMemConfig);
> +  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum ();
> SataCtrlIndex++) {
> +    HsioSataPreMemConfig = GetPchHsioSataPreMemConfig
> (SiPreMemPolicyPpi, SataCtrlIndex);
> +    PchPrintHsioSataPreMemConfig (SataCtrlIndex, HsioSataPreMemConfig);
> +  }
> +  PchPrintPcieRpPreMemConfig (PcieRpPreMemConfig);
> +  PchPrintHdAudioPreMemConfig (HdaPreMemConfig);
> +  PchPrintIshPreMemConfig (IshPreMemConfig);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy End
> --------------------------\n"));
> +  DEBUG_CODE_END ();
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPoli
> cy.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPoli
> cy.c
> new file mode 100644
> index 0000000000..d9005b50ef
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPoli
> cy.c
> @@ -0,0 +1,778 @@
> +/** @file
> +  Print whole PCH_POLICY_PPI
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyLibrary.h"
> +#include <Private/PchHsio.h>
> +
> +/**
> +  Print USB_CONFIG and serial out.
> +
> +  @param[in] UsbConfig         Pointer to a USB_CONFIG that provides the
> platform setting
> +
> +**/
> +VOID
> +PchPrintUsbConfig (
> +  IN CONST USB_CONFIG     *UsbConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "------------------ PCH USB Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " EnableComplianceMode           = %x\n",
> UsbConfig->EnableComplianceMode));
> +  DEBUG ((DEBUG_INFO, " PdoProgramming                 = %x\n",
> UsbConfig->PdoProgramming));
> +  DEBUG ((DEBUG_INFO, " OverCurrentEnable              = %x\n",
> UsbConfig->OverCurrentEnable));
> +  DEBUG ((DEBUG_INFO, " XhciOcLock                     = %x\n",
> UsbConfig->XhciOcLock));
> +  DEBUG ((DEBUG_INFO, " Usb2PhySusPgEnable             = %x\n",
> UsbConfig->Usb2PhySusPgEnable));
> +
> +  for (Index = 0; Index < GetPchUsb2MaxPhysicalPortNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Enabled        = %x\n", Index,
> UsbConfig->PortUsb20[Index].Enable));
> +    DEBUG ((DEBUG_INFO, " PortUsb20[%d].OverCurrentPin = OC%x\n", Index,
> UsbConfig->PortUsb20[Index].OverCurrentPin));
> +    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Petxiset   = %x\n", Index,
> UsbConfig->PortUsb20[Index].Afe.Petxiset));
> +    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Txiset     = %x\n", Index,
> UsbConfig->PortUsb20[Index].Afe.Txiset));
> +    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Predeemp   = %x\n", Index,
> UsbConfig->PortUsb20[Index].Afe.Predeemp));
> +    DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Pehalfbit  = %x\n", Index,
> UsbConfig->PortUsb20[Index].Afe.Pehalfbit));
> +  }
> +
> +  for (Index = 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " PortUsb30[%d] Enabled                  = %x\n",
> Index, UsbConfig->PortUsb30[Index].Enable));
> +    DEBUG ((DEBUG_INFO, " PortUsb30[%d].OverCurrentPin           =
> OC%x\n", Index, UsbConfig->PortUsb30[Index].OverCurrentPin));
> +    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmphEnable       =
> %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable));
> +    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmph             = %x\n",
> Index, UsbConfig->PortUsb30[Index].HsioTxDeEmph));
> +    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmpEnable =
> %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable));
> +    DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmp       =
> %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp));
> +
> +    DEBUG ((DEBUG_INFO, "
> PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfgEnable    = %x\n", Index,
> UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable));
> +    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfg
> = %x\n", Index,
> UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg));
> +    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelNEnable
> = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable));
> +    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelN
> = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN));
> +    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelPEnable
> = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable));
> +    DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelP
> = %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP));
> +    DEBUG ((DEBUG_INFO, "
> PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnResEnable  = %x\n", Index,
> UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable));
> +    DEBUG ((DEBUG_INFO, "
> PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnRes        = %x\n", Index,
> UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes));
> +  }
> +
> +  DEBUG ((DEBUG_INFO, " XdciConfig.Enable= %x\n",
> UsbConfig->XdciConfig.Enable));
> +
> +}
> +
> +/**
> +  Print PCH_PCIE_CONFIG and serial out.
> +
> +  @param[in] PcieConfig         Pointer to a PCH_PCIE_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintPcieConfig (
> +  IN CONST PCH_PCIE_CONFIG      *PcieConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "------------------ PCH PCIE Config ------------------\n"));
> +  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] HotPlug= %x\n", Index,
> PcieConfig->RootPort[Index].HotPlug));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] PmSci= %x\n", Index,
> PcieConfig->RootPort[Index].PmSci));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] ExtSync= %x\n", Index,
> PcieConfig->RootPort[Index].ExtSync));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] ClkReqDetect= %x\n", Index,
> PcieConfig->RootPort[Index].ClkReqDetect));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] UnsupportedRequestReport=
> %x\n", Index, PcieConfig->RootPort[Index].UnsupportedRequestReport));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] FatalErrorReport= %x\n", Index,
> PcieConfig->RootPort[Index].FatalErrorReport));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] NoFatalErrorReport= %x\n", Index,
> PcieConfig->RootPort[Index].NoFatalErrorReport));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] CorrectableErrorReport= %x\n",
> Index, PcieConfig->RootPort[Index].CorrectableErrorReport));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnFatalError= %x\n",
> Index, PcieConfig->RootPort[Index].SystemErrorOnFatalError));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnNonFatalError=
> %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnNonFatalError));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnCorrectableError=
> %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnCorrectableError));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] MaxPayload= %x\n", Index,
> PcieConfig->RootPort[Index].MaxPayload));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotImplemented= %x\n", Index,
> PcieConfig->RootPort[Index].SlotImplemented));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] AcsEnabled= %x\n", Index,
> PcieConfig->RootPort[Index].AcsEnabled));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] PtmEnabled= %x\n", Index,
> PcieConfig->RootPort[Index].PtmEnabled));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] AdvancedErrorReporting= %x\n",
> Index, PcieConfig->RootPort[Index].AdvancedErrorReporting));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] TransmitterHalfSwing= %x\n",
> Index, PcieConfig->RootPort[Index].TransmitterHalfSwing));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] PcieSpeed= %x\n", Index,
> PcieConfig->RootPort[Index].PcieSpeed));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] Gen3EqPh3Method= %x\n", Index,
> PcieConfig->RootPort[Index].Gen3EqPh3Method));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] PhysicalSlotNumber= %x\n", Index,
> PcieConfig->RootPort[Index].PhysicalSlotNumber));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] CompletionTimeout= %x\n", Index,
> PcieConfig->RootPort[Index].CompletionTimeout));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] Aspm= %x\n", Index,
> PcieConfig->RootPort[Index].Aspm));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] L1Substates= %x\n", Index,
> PcieConfig->RootPort[Index].L1Substates));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrEnable= %x\n", Index,
> PcieConfig->RootPort[Index].LtrEnable));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrConfigLock= %x\n", Index,
> PcieConfig->RootPort[Index].LtrConfigLock));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxSnoopLatency= %x\n",
> Index, PcieConfig->RootPort[Index].LtrMaxSnoopLatency));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxNoSnoopLatency= %x\n",
> Index, PcieConfig->RootPort[Index].LtrMaxNoSnoopLatency));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMode=
> %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMode));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMultiplier=
> %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMultiplier));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideValue=
> %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideValue));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideMode=
> %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMode));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d]
> NonSnoopLatencyOverrideMultiplier= %x\n", Index,
> PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideValue=
> %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideValue));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] ForceLtrOverride= %x\n", Index,
> PcieConfig->RootPort[Index].ForceLtrOverride));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] DetectTimeoutMs= %x\n", Index,
> PcieConfig->RootPort[Index].DetectTimeoutMs));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitScale= %x\n", Index,
> PcieConfig->RootPort[Index].SlotPowerLimitScale));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitValue= %x\n", Index,
> PcieConfig->RootPort[Index].SlotPowerLimitValue));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] Uptp= %x\n", Index,
> PcieConfig->RootPort[Index].Uptp));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] Dptp= %x\n", Index,
> PcieConfig->RootPort[Index].Dptp));
> +    DEBUG ((DEBUG_INFO, " RootPort[%d] EnableCpm= %x\n", Index,
> PcieConfig->RootPort[Index].EnableCpm));
> +
> +  }
> +  for (Index = 0; Index < GetPchMaxPcieClockNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " Clock[%d] Usage= %x\n", Index,
> PcieConfig->PcieClock[Index].Usage));
> +    DEBUG ((DEBUG_INFO, " Clock[%d] ClkReq= %x\n", Index,
> PcieConfig->PcieClock[Index].ClkReq));
> +  }
> +  for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index++) {
> +    DEBUG ((DEBUG_INFO, " SwEqCoeffCm[%d] = %x\n", Index,
> PcieConfig->SwEqCoeffList[Index].Cm));
> +    DEBUG ((DEBUG_INFO, " SwEqCoeffCp[%d] = %x\n", Index,
> PcieConfig->SwEqCoeffList[Index].Cp));
> +  }
> +  DEBUG ((DEBUG_INFO, " EnablePort8xhDecode= %x\n",
> PcieConfig->EnablePort8xhDecode));
> +  DEBUG ((DEBUG_INFO, " PchPciePort8xhDecodePortIndex= %x\n",
> PcieConfig->PchPciePort8xhDecodePortIndex));
> +  DEBUG ((DEBUG_INFO, " DisableRootPortClockGating= %x\n",
> PcieConfig->DisableRootPortClockGating));
> +  DEBUG ((DEBUG_INFO, " EnablePeerMemoryWrite= %x\n",
> PcieConfig->EnablePeerMemoryWrite));
> +  DEBUG ((DEBUG_INFO, " ComplianceTestMode= %x\n",
> PcieConfig->ComplianceTestMode));
> +  DEBUG ((DEBUG_INFO, " RpFunctionSwap= %x\n",
> PcieConfig->RpFunctionSwap));
> +  DEBUG ((DEBUG_INFO, " PcieDeviceOverrideTablePtr= %x\n",
> PcieConfig->PcieDeviceOverrideTablePtr));
> +}
> +
> +/**
> +  Print PCH_SATA_CONFIG and serial out.
> +
> +  @param[in]  SataCtrlIndex     SATA controller index
> +  @param[in]  SataConfig        Pointer to a PCH_SATA_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintSataConfig (
> +  IN UINT32                     SataCtrlIndex,
> +  IN CONST PCH_SATA_CONFIG      *SataConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "--------------- PCH SATA Config for controller %d
> -----------\n", SataCtrlIndex));
> +  DEBUG ((DEBUG_INFO, " Enable= %x\n", SataConfig->Enable));
> +  DEBUG ((DEBUG_INFO, " SataMode= %x\n", SataConfig->SataMode));
> +
> +  for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] Enabled= %x\n", Index,
> SataConfig->PortSettings[Index].Enable));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] HotPlug= %x\n", Index,
> SataConfig->PortSettings[Index].HotPlug));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] InterlockSw= %x\n", Index,
> SataConfig->PortSettings[Index].InterlockSw));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] External= %x\n", Index,
> SataConfig->PortSettings[Index].External));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] SpinUp= %x\n", Index,
> SataConfig->PortSettings[Index].SpinUp));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] SolidStateDrive= %x\n", Index,
> SataConfig->PortSettings[Index].SolidStateDrive));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] DevSlp= %x\n", Index,
> SataConfig->PortSettings[Index].DevSlp));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] EnableDitoConfig= %x\n", Index,
> SataConfig->PortSettings[Index].EnableDitoConfig));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] DmVal= %x\n", Index,
> SataConfig->PortSettings[Index].DmVal));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] DitoVal= %x\n", Index,
> SataConfig->PortSettings[Index].DitoVal));
> +    DEBUG ((DEBUG_INFO, " PortSettings[%d] ZpOdd= %x\n", Index,
> SataConfig->PortSettings[Index].ZpOdd));
> +  }
> +
> +  DEBUG ((DEBUG_INFO, " RaidDeviceId= %x\n",
> SataConfig->Rst.RaidDeviceId));
> +  DEBUG ((DEBUG_INFO, " Sata interrupt mode =  %x\n",
> SataConfig->Rst.SataRstInterrupt));
> +  DEBUG ((DEBUG_INFO, " Raid0= %x\n", SataConfig->Rst.Raid0));
> +  DEBUG ((DEBUG_INFO, " Raid1= %x\n", SataConfig->Rst.Raid1));
> +  DEBUG ((DEBUG_INFO, " Raid10= %x\n", SataConfig->Rst.Raid10));
> +  DEBUG ((DEBUG_INFO, " Raid5= %x\n", SataConfig->Rst.Raid5));
> +  DEBUG ((DEBUG_INFO, " Irrt= %x\n", SataConfig->Rst.Irrt));
> +  DEBUG ((DEBUG_INFO, " OromUiBanner= %x\n",
> SataConfig->Rst.OromUiBanner));
> +  DEBUG ((DEBUG_INFO, " OromUiDelay= %x\n",
> SataConfig->Rst.OromUiDelay));
> +  DEBUG ((DEBUG_INFO, " HddUnlock= %x\n", SataConfig->Rst.HddUnlock));
> +  DEBUG ((DEBUG_INFO, " LedLocate= %x\n", SataConfig->Rst.LedLocate));
> +  DEBUG ((DEBUG_INFO, " IrrtOnly= %x\n", SataConfig->Rst.IrrtOnly));
> +  DEBUG ((DEBUG_INFO, " SmartStorage= %x\n",
> SataConfig->Rst.SmartStorage));
> +  DEBUG ((DEBUG_INFO, " LegacyOrom= %x\n",
> SataConfig->Rst.LegacyOrom));
> +  DEBUG ((DEBUG_INFO, " OptaneMemory= %x\n",
> SataConfig->Rst.OptaneMemory));
> +  DEBUG ((DEBUG_INFO, " CpuAttachedStorage= %x\n",
> SataConfig->Rst.CpuAttachedStorage));
> +
> +  DEBUG ((DEBUG_INFO, " SpeedSupport= %x\n", SataConfig->SpeedLimit));
> +  DEBUG ((DEBUG_INFO, " EsataSpeedLimit= %x\n",
> SataConfig->EsataSpeedLimit));
> +  DEBUG ((DEBUG_INFO, " LedEnable= %x\n", SataConfig->LedEnable));
> +  DEBUG ((DEBUG_INFO, " TestMode= %x\n", SataConfig->TestMode));
> +  DEBUG ((DEBUG_INFO, " SalpSupport= %x\n", SataConfig->SalpSupport));
> +  DEBUG ((DEBUG_INFO, " PwrOptEnable= %x\n",
> SataConfig->PwrOptEnable));
> +
> +  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
> +    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].Enable                  =
> %x\n", Index, SataConfig->RstPcieStorageRemap[Index].Enable));
> +    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].RstPcieStoragePort
> = %x\n", Index,
> SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort));
> +    DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].DeviceResetDelay
> = %x\n", Index, SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay));
> +  }
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T1M %x\n",
> SataConfig->ThermalThrottling.P0T1M));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T2M %x\n",
> SataConfig->ThermalThrottling.P0T2M));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P0T3M %x\n",
> SataConfig->ThermalThrottling.P0T3M));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDisp %x\n",
> SataConfig->ThermalThrottling.P0TDisp));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P0Tinact %x\n",
> SataConfig->ThermalThrottling.P0Tinact));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDispFinit %x\n",
> SataConfig->ThermalThrottling.P0TDispFinit));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T1M %x\n",
> SataConfig->ThermalThrottling.P1T1M));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T2M %x\n",
> SataConfig->ThermalThrottling.P1T2M));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P1T3M %x\n",
> SataConfig->ThermalThrottling.P1T3M));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDisp %x\n",
> SataConfig->ThermalThrottling.P1TDisp));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P1Tinact %x\n",
> SataConfig->ThermalThrottling.P1Tinact));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDispFinit %x\n",
> SataConfig->ThermalThrottling.P1TDispFinit));
> +  DEBUG ((DEBUG_INFO, " ThermalThrottling SuggestedSetting %x\n",
> SataConfig->ThermalThrottling.SuggestedSetting));
> +}
> +
> +/**
> +  Print PCH_IOAPIC_CONFIG and serial out.
> +
> +  @param[in] IoApicConfig         Pointer to a PCH_IOAPIC_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintIoApicConfig (
> +  IN CONST PCH_IOAPIC_CONFIG   *IoApicConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH IOAPIC Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " IoApicEntry24_119= %x\n",
> IoApicConfig->IoApicEntry24_119));
> +  DEBUG ((DEBUG_INFO, " Enable8254ClockGating= %x\n",
> IoApicConfig->Enable8254ClockGating));
> +  DEBUG ((DEBUG_INFO, " Enable8254ClockGatingOnS3= %x\n",
> IoApicConfig->Enable8254ClockGatingOnS3));
> +  DEBUG ((DEBUG_INFO, " IoApicId= %x\n", IoApicConfig->IoApicId));
> +}
> +
> +/**
> +  Print PCH_LOCK_DOWN_CONFIG and serial out.
> +
> +  @param[in] LockDownConfig         Pointer to a PCH_LOCK_DOWN_CONFIG
> that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintLockDownConfig (
> +  IN CONST PCH_LOCK_DOWN_CONFIG   *LockDownConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH Lock Down Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " GlobalSmi= %x\n", LockDownConfig->GlobalSmi));
> +  DEBUG ((DEBUG_INFO, " BiosInterface= %x\n",
> LockDownConfig->BiosInterface));
> +  DEBUG ((DEBUG_INFO, " RtcMemoryLock= %x\n",
> LockDownConfig->RtcMemoryLock));
> +  DEBUG ((DEBUG_INFO, " BiosLock= %x\n", LockDownConfig->BiosLock));
> +  DEBUG ((DEBUG_INFO, " UnlockGpioPads= %x\n",
> LockDownConfig->UnlockGpioPads));
> +}
> +
> +/**
> +  Print PCH_HDAUDIO_CONFIG and serial out.
> +
> +  @param[in] HdaConfig         Pointer to a PCH_HDAUDIO_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintHdAudioConfig (
> +  IN CONST PCH_HDAUDIO_CONFIG   *HdaConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " DSP Enable               = %x\n",
> HdaConfig->DspEnable));
> +  DEBUG ((DEBUG_INFO, " DSP UAA Compliance       = %x\n",
> HdaConfig->DspUaaCompliance));
> +  DEBUG ((DEBUG_INFO, " iDisp Codec Disconnect   = %x\n",
> HdaConfig->IDispCodecDisconnect));
> +  DEBUG ((DEBUG_INFO, " Pme                      = %x\n", HdaConfig->Pme));
> +  DEBUG ((DEBUG_INFO, " Codec Sx Wake Capability = %x\n",
> HdaConfig->CodecSxWakeCapability));
> +  DEBUG ((DEBUG_INFO, " VC Type                  = %x\n",
> HdaConfig->VcType));
> +  DEBUG ((DEBUG_INFO, " HD-A Link Frequency      = %x\n",
> HdaConfig->HdAudioLinkFrequency));
> +  DEBUG ((DEBUG_INFO, " iDisp Link Frequency     = %x\n",
> HdaConfig->IDispLinkFrequency));
> +  DEBUG ((DEBUG_INFO, " iDisp Link T-Mode        = %x\n",
> HdaConfig->IDispLinkTmode));
> +  DEBUG ((DEBUG_INFO, " Audio Link: HDA Link     = %x\n",
> HdaConfig->AudioLinkHda));
> +  DEBUG ((DEBUG_INFO, " Audio Link: DMIC#0       = %x\n",
> HdaConfig->AudioLinkDmic0));
> +  DEBUG ((DEBUG_INFO, " Audio Link: DMIC#1       = %x\n",
> HdaConfig->AudioLinkDmic1));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SSP#0        = %x\n",
> HdaConfig->AudioLinkSsp0));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SSP#1        = %x\n",
> HdaConfig->AudioLinkSsp1));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SSP#2        = %x\n",
> HdaConfig->AudioLinkSsp1));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#1  = %x\n",
> HdaConfig->AudioLinkSndw1));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#2  = %x\n",
> HdaConfig->AudioLinkSndw2));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#3  = %x\n",
> HdaConfig->AudioLinkSndw3));
> +  DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#4  = %x\n",
> HdaConfig->AudioLinkSndw4));
> +  DEBUG ((DEBUG_INFO, " SoundWire Buffer RCOMP   = %x\n",
> HdaConfig->SndwBufferRcomp));
> +  DEBUG ((DEBUG_INFO, " ResetWaitTimer           = %x\n",
> HdaConfig->ResetWaitTimer));
> +  DEBUG ((DEBUG_INFO, " VerbTableEntryNum        = %x\n",
> HdaConfig->VerbTableEntryNum));
> +  DEBUG ((DEBUG_INFO, " VerbTablePtr             = %x\n",
> HdaConfig->VerbTablePtr));
> +}
> +
> +/**
> +  Print PCH_PM_CONFIG and serial out.
> +
> +  @param[in] PmConfig         Pointer to a PCH_PM_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintPmConfig (
> +  IN CONST PCH_PM_CONFIG   *PmConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH PM Config ------------------\n"));
> +
> +  DEBUG ((DEBUG_INFO, " WakeConfig PmeB0S5Dis               = %x\n",
> PmConfig->WakeConfig.PmeB0S5Dis));
> +  DEBUG ((DEBUG_INFO, " WakeConfig WolEnableOverride        = %x\n",
> PmConfig->WakeConfig.WolEnableOverride));
> +  DEBUG ((DEBUG_INFO, " WakeConfig LanWakeFromDeepSx        = %x\n",
> PmConfig->WakeConfig.LanWakeFromDeepSx));
> +  DEBUG ((DEBUG_INFO, " WakeConfig PcieWakeFromDeepSx       = %x\n",
> PmConfig->WakeConfig.PcieWakeFromDeepSx));
> +  DEBUG ((DEBUG_INFO, " WakeConfig WoWlanEnable             = %x\n",
> PmConfig->WakeConfig.WoWlanEnable));
> +  DEBUG ((DEBUG_INFO, " WakeConfig WoWlanDeepSxEnable       = %x\n",
> PmConfig->WakeConfig.WoWlanDeepSxEnable));
> +
> +  DEBUG ((DEBUG_INFO, " PchDeepSxPol                        = %x\n",
> PmConfig->PchDeepSxPol));
> +  DEBUG ((DEBUG_INFO, " PchSlpS3MinAssert                   = %x\n",
> PmConfig->PchSlpS3MinAssert));
> +  DEBUG ((DEBUG_INFO, " PchSlpS4MinAssert                   = %x\n",
> PmConfig->PchSlpS4MinAssert));
> +  DEBUG ((DEBUG_INFO, " PchSlpSusMinAssert                  = %x\n",
> PmConfig->PchSlpSusMinAssert));
> +  DEBUG ((DEBUG_INFO, " PchSlpAMinAssert                    = %x\n",
> PmConfig->PchSlpAMinAssert));
> +  DEBUG ((DEBUG_INFO, " LpcClockRun                         = %x\n",
> PmConfig->LpcClockRun));
> +  DEBUG ((DEBUG_INFO, " SlpStrchSusUp                       = %x\n",
> PmConfig->SlpStrchSusUp));
> +  DEBUG ((DEBUG_INFO, " SlpLanLowDc                         = %x\n",
> PmConfig->SlpLanLowDc));
> +  DEBUG ((DEBUG_INFO, " PwrBtnOverridePeriod                = %x\n",
> PmConfig->PwrBtnOverridePeriod));
> +  DEBUG ((DEBUG_INFO, " DisableEnergyReport                 = %x\n",
> PmConfig->DisableEnergyReport));
> +  DEBUG ((DEBUG_INFO, " DisableDsxAcPresentPulldown         = %x\n",
> PmConfig->DisableDsxAcPresentPulldown));
> +  DEBUG ((DEBUG_INFO, " PchPwrCycDur                        = %x\n",
> PmConfig->PchPwrCycDur));
> +  DEBUG ((DEBUG_INFO, " PciePllSsc                          = %x\n",
> PmConfig->PciePllSsc));
> +  DEBUG ((DEBUG_INFO, " DisableNativePowerButton            = %x\n",
> PmConfig->DisableNativePowerButton));
> +  DEBUG ((DEBUG_INFO, " SlpS0Enabled                        = %x\n",
> PmConfig->SlpS0Enable));
> +  DEBUG ((DEBUG_INFO, " MeWakeSts                           = %x\n",
> PmConfig->MeWakeSts));
> +  DEBUG ((DEBUG_INFO, " WolOvrWkSts                         = %x\n",
> PmConfig->WolOvrWkSts));
> +  DEBUG ((DEBUG_INFO, " EnableTcoTimer                      = %x\n",
> PmConfig->EnableTcoTimer));
> +  DEBUG ((DEBUG_INFO, " VrAlert                             = %x\n",
> PmConfig->VrAlert));
> +  DEBUG ((DEBUG_INFO, " PowerButtonDebounce                 = %x\n",
> PmConfig->PowerButtonDebounce));
> +  DEBUG ((DEBUG_INFO, " SlpS0VmRuntimeControl               = %x\n",
> PmConfig->SlpS0VmRuntimeControl));
> +  DEBUG ((DEBUG_INFO, " SlpS0Vm070VSupport                  = %x\n",
> PmConfig->SlpS0Vm070VSupport));
> +  DEBUG ((DEBUG_INFO, " SlpS0Vm075VSupport                  = %x\n",
> PmConfig->SlpS0Vm075VSupport));
> +  DEBUG ((DEBUG_INFO, " SlpS0Override                       = %x\n",
> PmConfig->SlpS0Override));
> +  DEBUG ((DEBUG_INFO, " SlpS0DisQForDebug                   = %x\n",
> PmConfig->SlpS0DisQForDebug));
> +  DEBUG ((DEBUG_INFO, " PsOnEnable                          = %x\n",
> PmConfig->PsOnEnable));
> +  DEBUG ((DEBUG_INFO, " CpuC10GatePinEnable                 = %x\n",
> PmConfig->CpuC10GatePinEnable));
> +  DEBUG ((DEBUG_INFO, " PmcDbgMsgEn                         = %x\n",
> PmConfig->PmcDbgMsgEn));
> +  DEBUG ((DEBUG_INFO, " ModPhySusPgEnable                   = %x\n",
> PmConfig->ModPhySusPgEnable));
> +  DEBUG ((DEBUG_INFO, " SlpS0WithGbeSupport                 = %x\n",
> PmConfig->SlpS0WithGbeSupport));
> +}
> +
> +/**
> +  Print PCH_DMI_CONFIG and serial out.
> +
> +  @param[in] DmiConfig         Pointer to a PCH_DMI_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintDmiConfig (
> +  IN CONST PCH_DMI_CONFIG   *DmiConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH DMI Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " PwrOptEnable= %x\n",
> DmiConfig->PwrOptEnable));
> +  DEBUG ((DEBUG_INFO, " DmiAspmCtrl= %x\n", DmiConfig->DmiAspmCtrl));
> +}
> +/**
> +  Print PCH_LPC_SIRQ_CONFIG and serial out.
> +
> +  @param[in] SerialIrqConfig         Pointer to a PCH_LPC_SIRQ_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintSerialIrqConfig (
> +  IN CONST PCH_LPC_SIRQ_CONFIG   *SerialIrqConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH LPC SIRQ Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " SirqEnable= %x\n", SerialIrqConfig->SirqEnable));
> +  DEBUG ((DEBUG_INFO, " SirqMode= %x\n", SerialIrqConfig->SirqMode));
> +  DEBUG ((DEBUG_INFO, " StartFramePulse= %x\n",
> SerialIrqConfig->StartFramePulse));
> +}
> +/**
> +  Print PCH_THERMAL_CONFIG and serial out.
> +
> +  @param[in] ThermalConfig         Pointer to a PCH_THERMAL_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintThermalConfig (
> +  IN CONST PCH_THERMAL_CONFIG   *ThermalConfig
> +  )
> +{
> +  UINTN Index;
> +
> +  DEBUG ((DEBUG_INFO, "------------------ PCH Thermal Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " TsmicLock= %x\n", ThermalConfig->TsmicLock));
> +  DEBUG ((DEBUG_INFO, " TTLevels T0Level %x centigrade degree\n",
> ThermalConfig->TTLevels.T0Level));
> +  DEBUG ((DEBUG_INFO, " TTLevels T1Level %x centigrade degree\n",
> ThermalConfig->TTLevels.T1Level));
> +  DEBUG ((DEBUG_INFO, " TTLevels T2Level %x centigrade degree\n",
> ThermalConfig->TTLevels.T2Level));
> +  DEBUG ((DEBUG_INFO, " TTLevels TTEnable %x\n",
> ThermalConfig->TTLevels.TTEnable));
> +  DEBUG ((DEBUG_INFO, " TTLevels TTState13Enable %x\n",
> ThermalConfig->TTLevels.TTState13Enable));
> +  DEBUG ((DEBUG_INFO, " TTLevels TTLock %x\n",
> ThermalConfig->TTLevels.TTLock));
> +  DEBUG ((DEBUG_INFO, " TTLevels SuggestedSetting %x\n",
> ThermalConfig->TTLevels.SuggestedSetting));
> +  DEBUG ((DEBUG_INFO, " TTLevels PchCrossThrottling %x\n",
> ThermalConfig->TTLevels.PchCrossThrottling));
> +
> +  DEBUG ((DEBUG_INFO, " DmiHaAWC DmiTsawEn %x\n",
> ThermalConfig->DmiHaAWC.DmiTsawEn));
> +  DEBUG ((DEBUG_INFO, " DmiHaAWC TS0TW %x\n",
> ThermalConfig->DmiHaAWC.TS0TW));
> +  DEBUG ((DEBUG_INFO, " DmiHaAWC TS1TW %x\n",
> ThermalConfig->DmiHaAWC.TS1TW));
> +  DEBUG ((DEBUG_INFO, " DmiHaAWC TS2TW %x\n",
> ThermalConfig->DmiHaAWC.TS2TW));
> +  DEBUG ((DEBUG_INFO, " DmiHaAWC TS3TW %x\n",
> ThermalConfig->DmiHaAWC.TS3TW));
> +  DEBUG ((DEBUG_INFO, " DmiHaAWC SuggestedSetting %x\n",
> ThermalConfig->DmiHaAWC.SuggestedSetting));
> +
> +  DEBUG ((DEBUG_INFO, " MemoryThrottling Enable= %x\n",
> ThermalConfig->MemoryThrottling.Enable));
> +  for (Index = 0; Index < MaxTsGpioPin; Index++) {
> +    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting
> PmsyncEnable= %x\n",
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PmsyncEnable));
> +    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting
> C0TransmitEnable= %x\n",
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].C0TransmitEnabl
> e));
> +    DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting
> PinSelection= %x\n",
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PinSelection));
> +  }
> +  DEBUG ((DEBUG_INFO, " PchHotEnable = %x\n",
> ThermalConfig->PchHotEnable));
> +  DEBUG ((DEBUG_INFO, " PchHotLevel = %x\n",
> ThermalConfig->PchHotLevel));
> +}
> +
> +/**
> +  Print PCH_GENERAL_CONFIG and serial out.
> +
> +  @param[in] PchGeneralConfig   Pointer to a PCH_GENERAL_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintGeneralConfig (
> +  IN CONST PCH_GENERAL_CONFIG   *PchGeneralConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH General Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Crid= %x\n", PchGeneralConfig->Crid));
> +  DEBUG ((DEBUG_INFO, " LegacyIoLowLatency = %x\n",
> PchGeneralConfig->LegacyIoLowLatency));
> +}
> +
> +/**
> +  Print PCH_LAN_CONFIG and serial out.
> +
> +  @param[in] LanConfig         Pointer to a PCH_LAN_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintLanConfig (
> +  IN CONST PCH_LAN_CONFIG   *LanConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH LAN Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Enable= %x\n", LanConfig->Enable));
> +  DEBUG ((DEBUG_INFO, " LtrEnable= %x\n", LanConfig->LtrEnable));
> +}
> +
> +/**
> +  Print PCH_SERIAL_IO_CONFIG and serial out.
> +
> +  @param[in] SerialIoConfig         Pointer to a PCH_SERIAL_IO_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintSerialIoConfig (
> +  IN CONST PCH_SERIAL_IO_CONFIG   *SerialIoConfig
> +  )
> +{
> +  UINTN Index;
> +#ifndef MDEPKG_NDEBUG
> +  static UINT8 DeviceName[PCH_MAX_SERIALIO_CONTROLLERS][5] =
> {"I2C0","I2C1","I2C2","I2C3","I2C4","I2C5","SPI0","SPI1","SPI2","UA00","UA01"
> ,"UA02"};
> +#endif
> +
> +  DEBUG ((DEBUG_INFO, "------------------ PCH Serial IO Config
> ------------------\n"));
> +  DEBUG_CODE_BEGIN ();
> +  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " SerialIoController %a: Mode 0x%x\n",
> DeviceName[Index], SerialIoConfig->DevMode[Index]));
> +  }
> +  DEBUG_CODE_END ();
> +  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " SpiCsPolarity[%d] = 0x%x\n", Index,
> SerialIoConfig->SpiCsPolarity[Index]));
> +  }
> +  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
> +    DEBUG ((DEBUG_INFO, " UartHwFlowCtrl[%d] = 0x%x\n", Index,
> SerialIoConfig->UartHwFlowCtrl[Index]));
> +  }
> +  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index ++) {
> +    DEBUG ((DEBUG_INFO, " I2cPadsTermination[%d] = 0x%x\n", Index,
> SerialIoConfig->I2cPadsTermination[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, " DebugUartNumber = 0x%x\n",
> SerialIoConfig->DebugUartNumber));
> +  DEBUG ((DEBUG_INFO, " EnableDebugUartAfterPost = 0x%x\n",
> SerialIoConfig->EnableDebugUartAfterPost));
> +  DEBUG ((DEBUG_INFO, " Uart0PinMuxing = 0x%x\n",
> SerialIoConfig->Uart0PinMuxing));
> +}
> +
> +/**
> +  Print PCH_INTERRUPT_CONFIG and serial out
> +
> +  @param[in] InterruptConfig        Pointer to Interrupt Configuration
> structure
> +
> +**/
> +VOID
> +PchPrintInterruptConfig (
> +  IN CONST PCH_INTERRUPT_CONFIG     *InterruptConfig
> +  )
> +{
> +  UINTN Index;
> +  //
> +  // Print interrupt information
> +  //
> +  DEBUG ((DEBUG_INFO, "------------------ PCH Interrupt Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Interrupt assignment:\n"));
> +  DEBUG ((DEBUG_INFO, "  Dxx:Fx INTx IRQ\n"));
> +  for (Index = 0; Index < InterruptConfig->NumOfDevIntConfig; Index++) {
> +    DEBUG ((DEBUG_INFO, "  D%02d:F%d    %d %03d\n",
> +            InterruptConfig->DevIntConfig[Index].Device,
> +            InterruptConfig->DevIntConfig[Index].Function,
> +            InterruptConfig->DevIntConfig[Index].IntX,
> +            InterruptConfig->DevIntConfig[Index].Irq));
> +  }
> +  DEBUG ((DEBUG_INFO, " Legacy PIC interrupt routing:\n"));
> +  DEBUG ((DEBUG_INFO, "  PIRQx    IRQx\n"));
> +  for (Index = 0; Index < PCH_MAX_PXRC_CONFIG; Index++) {
> +    DEBUG ((DEBUG_INFO, "  PIRQ%c -> IRQ%d\n", Index + 65,
> InterruptConfig->PxRcConfig[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, " Other interrupt configuration:\n"));
> +  DEBUG ((DEBUG_INFO, "  GpioIrqRoute= %d\n",
> InterruptConfig->GpioIrqRoute));
> +  DEBUG ((DEBUG_INFO, "  SciIrqSelect= %d\n",
> InterruptConfig->SciIrqSelect));
> +  DEBUG ((DEBUG_INFO, "  TcoIrqEnable= %d\n",
> InterruptConfig->TcoIrqEnable));
> +  DEBUG ((DEBUG_INFO, "  TcoIrqSelect= %d\n",
> InterruptConfig->TcoIrqSelect));
> +}
> +
> +/**
> +  Print PCH_SCS_CONFIG and serial out.
> +
> +  @param[in] ScsConfig         Pointer to a PCH_SCS_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintScsConfig (
> +  IN CONST PCH_SCS_CONFIG   *ScsConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH SCS Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcEnabled = %x\n",
> ScsConfig->ScsEmmcEnabled));
> +  DEBUG ((DEBUG_INFO, " ScsSdcardEnabled = %x\n",
> ScsConfig->ScsSdcardEnabled));
> +  DEBUG ((DEBUG_INFO, " SdCardPowerEnableActiveHigh = %x\n",
> ScsConfig->SdCardPowerEnableActiveHigh));
> +  DEBUG ((DEBUG_INFO, " ScsUfsEnabled = %x\n",
> ScsConfig->ScsUfsEnabled));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcHs400Enabled = %x\n",
> ScsConfig->ScsEmmcHs400Enabled));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcHs400TuningRequired = %x\n",
> ScsConfig->ScsEmmcHs400TuningRequired));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcHs400DllDataValid = %x\n",
> ScsConfig->ScsEmmcHs400DllDataValid));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcHs400RxStrobeDll1 = %x\n",
> ScsConfig->ScsEmmcHs400RxStrobeDll1));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcHs400TxDataDll = %x\n",
> ScsConfig->ScsEmmcHs400TxDataDll));
> +  DEBUG ((DEBUG_INFO, " ScsEmmcHs400DriverStrength = %x\n",
> ScsConfig->ScsEmmcHs400DriverStrength));
> +}
> +
> +/**
> +  Print PCH_ISH_CONFIG and serial out.
> +
> +  @param[in] IshConfig         Pointer to a PCH_ISH_CONFIG that provides
> the platform setting
> +
> +**/
> +VOID
> +PchPrintIshConfig (
> +  IN CONST PCH_ISH_CONFIG   *IshConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH ISH Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " SPI GPIO Assigned   = %x\n",
> IshConfig->SpiGpioAssign));
> +  DEBUG ((DEBUG_INFO, " UART0 GPIO Assigned = %x\n",
> IshConfig->Uart0GpioAssign));
> +  DEBUG ((DEBUG_INFO, " UART1 GPIO Assigned = %x\n",
> IshConfig->Uart1GpioAssign));
> +  DEBUG ((DEBUG_INFO, " I2C0 GPIO Assigned  = %x\n",
> IshConfig->I2c0GpioAssign));
> +  DEBUG ((DEBUG_INFO, " I2C1 GPIO Assigned  = %x\n",
> IshConfig->I2c1GpioAssign));
> +  DEBUG ((DEBUG_INFO, " I2C2 GPIO Assigned  = %x\n",
> IshConfig->I2c2GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_0 GPIO Assigned  = %x\n",
> IshConfig->Gp0GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_1 GPIO Assigned  = %x\n",
> IshConfig->Gp1GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_2 GPIO Assigned  = %x\n",
> IshConfig->Gp2GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_3 GPIO Assigned  = %x\n",
> IshConfig->Gp3GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_4 GPIO Assigned  = %x\n",
> IshConfig->Gp4GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_5 GPIO Assigned  = %x\n",
> IshConfig->Gp5GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_6 GPIO Assigned  = %x\n",
> IshConfig->Gp6GpioAssign));
> +  DEBUG ((DEBUG_INFO, " GP_7 GPIO Assigned  = %x\n",
> IshConfig->Gp7GpioAssign));
> +}
> +
> +/**
> +  Print PCH_FLASH_PROTECTION_CONFIG and serial out.
> +
> +  @param[in] FlashProtectConfig  Pointer to a
> PCH_FLASH_PROTECTION_CONFIG that provides the platform setting
> +
> +**/
> +VOID
> +PchPrintFlashProtectionConfig (
> +  IN CONST PCH_FLASH_PROTECTION_CONFIG   *FlashProtectConfig
> +  )
> +{
> +  UINT32 Index;
> +
> +  DEBUG ((DEBUG_INFO, "------------------ PCH Flash Protection Config
> ------------------\n"));
> +  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; ++Index) {
> +    DEBUG ((DEBUG_INFO, " WriteProtectionEnable[%d] = %x\n", Index,
> FlashProtectConfig->ProtectRange[Index].WriteProtectionEnable));
> +    DEBUG ((DEBUG_INFO, " ReadProtectionEnable[%d]  = %x\n", Index,
> FlashProtectConfig->ProtectRange[Index].ReadProtectionEnable));
> +    DEBUG ((DEBUG_INFO, " ProtectedRangeLimit[%d]   = %x\n", Index,
> FlashProtectConfig->ProtectRange[Index].ProtectedRangeLimit));
> +    DEBUG ((DEBUG_INFO, " ProtectedRangeBase[%d]    = %x\n", Index,
> FlashProtectConfig->ProtectRange[Index].ProtectedRangeBase));
> +  }
> +}
> +
> +/**
> +  Print PCH_P2SB_CONFIG and serial out.
> +
> +  @param[in] P2sbConfig                 Pointer to a PCH_P2SB_CONFIG that
> provides the platform setting
> +
> +**/
> +VOID
> +PchPrintP2sbConfig (
> +  IN CONST PCH_P2SB_CONFIG              *P2sbConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH P2SB Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "SbAccessUnlock= %x\n",
> P2sbConfig->SbAccessUnlock));
> +}
> +
> +/**
> +  Print PCH_ESPI_CONFIG.
> +
> +  @param[in] EspiConfig         Pointer to a PCH_ESPI_CONFIG that provides
> the eSPI setting
> +
> +**/
> +VOID
> +PchPrintEspiConfig (
> +  IN CONST PCH_ESPI_CONFIG   *EspiConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH eSPI Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " LGMR Enable %x\n", EspiConfig->LgmrEnable));
> +  DEBUG ((DEBUG_INFO, " BME for Master and Slave Enabled %x\n",
> EspiConfig->BmeMasterSlaveEnabled));
> +}
> +
> +/**
> +  Print PCH_CNVI_CONFIG.
> +
> +  @param[in] CnviConfig         Pointer to a PCH_CNVI_CONFIG that provides
> the CNVi settings
> +
> +**/
> +VOID
> +PchPrintCnviConfig (
> +  IN CONST PCH_CNVI_CONFIG   *CnviConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ PCH CNVi Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "CNVi Mode = %x\n", CnviConfig->Mode));
> +  DEBUG ((DEBUG_INFO, "CNVi MfUart1 type = %x\n",
> CnviConfig->MfUart1Type));
> +}
> +
> +/**
> +  Print PCH_HSIO_CONFIG.
> +
> +  @param[in] HsioConfig         Pointer to a PCH_HSIO_CONFIG that provides
> the eSPI setting
> +
> +**/
> +VOID
> +PchPrintHsioConfig (
> +  IN CONST PCH_HSIO_CONFIG   *HsioConfig
> +  )
> +{
> +  PCH_HSIO_VER_INFO             *BiosChipsetInitVerInfoPtr;
> +  DEBUG ((DEBUG_INFO, "------------------ PCH HSIO Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " ChipsetInit Binary Pointer            = %x\n",
> HsioConfig->ChipsetInitBinPtr));
> +  DEBUG ((DEBUG_INFO, " ChipsetInit Binary Length             = %x\n",
> HsioConfig->ChipsetInitBinLen));
> +  BiosChipsetInitVerInfoPtr = (PCH_HSIO_VER_INFO *)
> HsioConfig->ChipsetInitBinPtr;
> +  if (HsioConfig->ChipsetInitBinPtr && HsioConfig->ChipsetInitBinLen) {
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC           = %x\n",
> BiosChipsetInitVerInfoPtr->BaseCrc));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC            = %x\n",
> BiosChipsetInitVerInfoPtr->OemCrc));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC            = %x\n",
> BiosChipsetInitVerInfoPtr->SusCrc));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Version            = %x\n",
> BiosChipsetInitVerInfoPtr->Version));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Product            = %x\n",
> BiosChipsetInitVerInfoPtr->Product));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Metal Layer        = %x\n",
> BiosChipsetInitVerInfoPtr->MetalLayer));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base Layer         = %x\n",
> BiosChipsetInitVerInfoPtr->BaseLayer));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM Version        = %x\n",
> BiosChipsetInitVerInfoPtr->OemVersion));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Debug Mode         = %x\n",
> BiosChipsetInitVerInfoPtr->DebugMode));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC Valid      = %x\n",
> BiosChipsetInitVerInfoPtr->OemCrcValid));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC Valid      = %x\n",
> BiosChipsetInitVerInfoPtr->SusCrcValid));
> +    DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC Valid     = %x\n",
> BiosChipsetInitVerInfoPtr->BaseCrcValid));
> +  }
> +}
> +
> +/**
> +  Print whole PCH config blocks and serial out.
> +
> +  @param[in] SiPolicyPpi    The RC Policy PPI instance
> +
> +**/
> +VOID
> +EFIAPI
> +PchPrintPolicyPpi (
> +  IN  SI_POLICY_PPI     *SiPolicyPpi
> +  )
> +{
> +DEBUG_CODE_BEGIN();
> +  EFI_STATUS                      Status;
> +  PCH_GENERAL_CONFIG              *PchGeneralConfig;
> +  PCH_PCIE_CONFIG                 *PcieRpConfig;
> +  PCH_SATA_CONFIG                 *SataConfig;
> +  PCH_IOAPIC_CONFIG               *IoApicConfig;
> +  PCH_DMI_CONFIG                  *DmiConfig;
> +  PCH_FLASH_PROTECTION_CONFIG     *FlashProtectionConfig;
> +  PCH_HDAUDIO_CONFIG              *HdAudioConfig;
> +  PCH_INTERRUPT_CONFIG            *InterruptConfig;
> +  PCH_ISH_CONFIG                  *IshConfig;
> +  PCH_LAN_CONFIG                  *LanConfig;
> +  PCH_P2SB_CONFIG                 *P2sbConfig;
> +  PCH_LOCK_DOWN_CONFIG            *LockDownConfig;
> +  PCH_PM_CONFIG                   *PmConfig;
> +  PCH_SCS_CONFIG                  *ScsConfig;
> +  PCH_SERIAL_IO_CONFIG            *SerialIoConfig;
> +  PCH_LPC_SIRQ_CONFIG             *SerialIrqConfig;
> +  PCH_THERMAL_CONFIG              *ThermalConfig;
> +  USB_CONFIG                      *UsbConfig;
> +  PCH_ESPI_CONFIG                 *EspiConfig;
> +  PCH_CNVI_CONFIG                 *CnviConfig;
> +  PCH_HSIO_CONFIG                 *HsioConfig;
> +  UINT32                          SataCtrlIndex;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid,
> (VOID *) &PchGeneralConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPcieRpConfigGuid, (VOID *)
> &PcieRpConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gIoApicConfigGuid, (VOID *)
> &IoApicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gDmiConfigGuid, (VOID *)
> &DmiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gFlashProtectionConfigGuid,
> (VOID *) &FlashProtectionConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHdAudioConfigGuid, (VOID
> *) &HdAudioConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gInterruptConfigGuid, (VOID
> *) &InterruptConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gIshConfigGuid, (VOID *)
> &IshConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gLanConfigGuid, (VOID *)
> &LanConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gLockDownConfigGuid,
> (VOID *) &LockDownConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gP2sbConfigGuid, (VOID *)
> &P2sbConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPmConfigGuid, (VOID *)
> &PmConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gScsConfigGuid, (VOID *)
> &ScsConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIoConfigGuid, (VOID *)
> &SerialIoConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIrqConfigGuid, (VOID
> *) &SerialIrqConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gThermalConfigGuid, (VOID
> *) &ThermalConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gUsbConfigGuid, (VOID *)
> &UsbConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gEspiConfigGuid, (VOID *)
> &EspiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCnviConfigGuid, (VOID *)
> &CnviConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gHsioConfigGuid, (VOID *)
> &HsioConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ PCH Print Policy Start
> ------------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision= %x\n",
> SiPolicyPpi->TableHeader.Header.Revision));
> +
> +  PchPrintGeneralConfig (PchGeneralConfig);
> +  PchPrintPcieConfig (PcieRpConfig);
> +  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum ();
> SataCtrlIndex++) {
> +    SataConfig = GetPchSataConfig (SiPolicyPpi, SataCtrlIndex);
> +    PchPrintSataConfig (SataCtrlIndex, SataConfig);
> +  }
> +  PchPrintUsbConfig (UsbConfig);
> +  PchPrintIoApicConfig (IoApicConfig);
> +  PchPrintHdAudioConfig (HdAudioConfig);
> +  PchPrintLanConfig (LanConfig);
> +  PchPrintLockDownConfig (LockDownConfig);
> +  PchPrintThermalConfig (ThermalConfig);
> +  PchPrintPmConfig (PmConfig);
> +  PchPrintDmiConfig (DmiConfig);
> +  PchPrintSerialIrqConfig (SerialIrqConfig);
> +  PchPrintSerialIoConfig (SerialIoConfig);
> +  PchPrintInterruptConfig (InterruptConfig);
> +  PchPrintScsConfig (ScsConfig);
> +  PchPrintIshConfig (IshConfig);
> +  PchPrintFlashProtectionConfig (FlashProtectionConfig);
> +  PchPrintP2sbConfig (P2sbConfig);
> +  PchPrintEspiConfig (EspiConfig);
> +  PchPrintCnviConfig (CnviConfig);
> +  PchPrintHsioConfig (HsioConfig);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ PCH Print Platform Protocol End
> --------------------------\n"));
> +DEBUG_CODE_END();
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLib.c
> new file mode 100644
> index 0000000000..2a1da20667
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLib.c
> @@ -0,0 +1,739 @@
> +/** @file
> +  This file is PeiPchPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyLibrary.h"
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Register/PchRegsLpcCnl.h>
> +
> +/**
> +  mPxRcConfig[] table contains data for 8259 routing (how PIRQx is mapped to
> IRQy).
> +  This information is used by systems which choose to use legacy PIC
> +  interrupt controller. Only IRQ3-7,9-12,14,15 are valid. Values from this table
> +  will be programmed into ITSS.PxRC registers.
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPxRcConfig[] = {
> +  11,  // PARC: PIRQA -> IRQ11
> +  10,  // PBRC: PIRQB -> IRQ10
> +  11,  // PCRC: PIRQC -> IRQ11
> +  11,  // PDRC: PIRQD -> IRQ11
> +  11,  // PERC: PIRQE -> IRQ11
> +  11,  // PFRC: PIRQF -> IRQ11
> +  11,  // PGRC: PIRQG -> IRQ11
> +  11   // PHRC: PIRQH -> IRQ11
> +};
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadPchGeneralConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_GENERAL_CONFIG  *PchGeneralConfig;
> +  PchGeneralConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "PchGeneralConfig->Header.GuidHob.Name =
> %g\n", &PchGeneralConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PchGeneralConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PchGeneralConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    PCH general configuration
> +  ********************************/
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadPcieRpConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  UINTN            Index;
> +  PCH_PCIE_CONFIG  *PcieRpConfig;
> +
> +  PcieRpConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "PcieRpConfig->Header.GuidHob.Name = %g\n",
> &PcieRpConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PcieRpConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PcieRpConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    PCI Express related settings
> +  ********************************/
> +  PcieRpConfig->RpFunctionSwap = TRUE;
> +
> +  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
> +    PcieRpConfig->RootPort[Index].Aspm                   =
> PchPcieAspmAutoConfig;
> +    PcieRpConfig->RootPort[Index].PmSci                  = TRUE;
> +    PcieRpConfig->RootPort[Index].AcsEnabled             = TRUE;
> +    PcieRpConfig->RootPort[Index].PtmEnabled             = TRUE;
> +    PcieRpConfig->RootPort[Index].DpcEnabled             = TRUE;
> +    PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled = TRUE;
> +    PcieRpConfig->RootPort[Index].MaxPayload             =
> PchPcieMaxPayload256;
> +    PcieRpConfig->RootPort[Index].SlotImplemented        = TRUE;
> +    PcieRpConfig->RootPort[Index].PhysicalSlotNumber     = (UINT8) Index;
> +    PcieRpConfig->RootPort[Index].L1Substates            =
> PchPcieL1SubstatesL1_1_2;
> +    PcieRpConfig->RootPort[Index].EnableCpm              = TRUE;
> +    PcieRpConfig->RootPort[Index].Gen3EqPh3Method        =
> PchPcieEqHardware;
> +
> +    //
> +    // PCIe LTR Configuration.
> +    //
> +    PcieRpConfig->RootPort[Index].LtrEnable             = TRUE;
> +
> +    PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency               = 0x1003;
> +    PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency             =
> 0x1003;
> +
> +    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode           = 2;
> +    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier     = 2;
> +    PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue          = 60;
> +    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode        =
> 2;
> +    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier  =
> 2;
> +    PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue       =
> 60;
> +
> +    PcieRpConfig->RootPort[Index].Uptp                               = 5;
> +    PcieRpConfig->RootPort[Index].Dptp                               = 7;
> +
> +    PcieRpConfig->EqPh3LaneParam[Index].Cm                           = 6;
> +    PcieRpConfig->EqPh3LaneParam[Index].Cp                           = 2;
> +  }
> +
> +  PcieRpConfig->SwEqCoeffList[0].Cm = 4;
> +  PcieRpConfig->SwEqCoeffList[0].Cp = 8;
> +  PcieRpConfig->SwEqCoeffList[1].Cm = 6;
> +  PcieRpConfig->SwEqCoeffList[1].Cp = 2;
> +  PcieRpConfig->SwEqCoeffList[2].Cm = 8;
> +  PcieRpConfig->SwEqCoeffList[2].Cp = 6;
> +  PcieRpConfig->SwEqCoeffList[3].Cm = 10;
> +  PcieRpConfig->SwEqCoeffList[3].Cp = 8;
> +  PcieRpConfig->SwEqCoeffList[4].Cm = 12;
> +  PcieRpConfig->SwEqCoeffList[4].Cp = 2;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadSataConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  UINTN            PortIndex;
> +  UINTN            Index;
> +  UINT32           SataCtrlIndex;
> +  PCH_SATA_CONFIG  *SataConfig;
> +
> +  SataConfig = (PCH_SATA_CONFIG *)ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Name = %g\n",
> &SataConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", SataConfig->Header.GuidHob.Header.HobLength));
> +
> +  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum ();
> SataCtrlIndex++, SataConfig++) {
> +    /********************************
> +      SATA related settings
> +    ********************************/
> +    SataConfig->Enable               = TRUE;
> +    SataConfig->SalpSupport          = TRUE;
> +    SataConfig->SataMode             = PchSataModeAhci;
> +
> +    for (PortIndex = 0; PortIndex < GetPchMaxSataPortNum (SataCtrlIndex);
> PortIndex++) {
> +      SataConfig->PortSettings[PortIndex].Enable           = TRUE;
> +      SataConfig->PortSettings[PortIndex].DmVal            = 15;
> +      SataConfig->PortSettings[PortIndex].DitoVal          = 625;
> +    }
> +
> +    SataConfig->Rst.Raid0              = TRUE;
> +    SataConfig->Rst.Raid1              = TRUE;
> +    SataConfig->Rst.Raid10             = TRUE;
> +    SataConfig->Rst.Raid5              = TRUE;
> +    SataConfig->Rst.Irrt               = TRUE;
> +    SataConfig->Rst.OromUiBanner       = TRUE;
> +    SataConfig->Rst.OromUiDelay        = PchSataOromDelay2sec;
> +    SataConfig->Rst.HddUnlock          = TRUE;
> +    SataConfig->Rst.LedLocate          = TRUE;
> +    SataConfig->Rst.IrrtOnly           = TRUE;
> +    SataConfig->Rst.SmartStorage       = TRUE;
> +    SataConfig->Rst.OptaneMemory       = TRUE;
> +    SataConfig->Rst.CpuAttachedStorage = TRUE;
> +
> +    for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
> +      SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay             =
> 100;
> +    }
> +
> +    SataConfig->PwrOptEnable     = TRUE;
> +    SataConfig->ThermalThrottling.SuggestedSetting = TRUE;
> +  }
> +}
> +
> +/**
> +  Get Sata Config Policy
> +
> +  @param[in]  SiPolicy            The RC Policy PPI instance
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval     SataConfig          Pointer to Sata Config Policy
> +**/
> +PCH_SATA_CONFIG *
> +GetPchSataConfig (
> +  IN SI_POLICY_PPI      *SiPolicy,
> +  IN UINT32             SataCtrlIndex
> +  )
> +{
> +  PCH_SATA_CONFIG     *SataConfig;
> +  EFI_STATUS          Status;
> +
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *)
> &SataConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SataConfig += SataCtrlIndex;
> +
> +  return SataConfig;
> +}
> +
> +/**
> +  Load Config block default
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadIoApicConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_IOAPIC_CONFIG  *IoApicConfig;
> +  IoApicConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Name = %g\n",
> &IoApicConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Header.HobLength
> = 0x%x\n", IoApicConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Io Apic configuration
> +  ********************************/
> +  IoApicConfig->IoApicId                   = 0x02;
> +  IoApicConfig->IoApicEntry24_119          = TRUE;
> +  IoApicConfig->Enable8254ClockGating      = TRUE;
> +  IoApicConfig->Enable8254ClockGatingOnS3  = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadDmiConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_DMI_CONFIG  *DmiConfig;
> +  DmiConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Name = %g\n",
> &DmiConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", DmiConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    DMI related settings
> +  ********************************/
> +  DmiConfig->DmiAspmCtrl = PchPcieAspmAutoConfig;
> +}
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadFlashProtectionConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_FLASH_PROTECTION_CONFIG  *FlashProtectionConfig;
> +  FlashProtectionConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "FlashProtectionConfig->Header.GuidHob.Name =
> %g\n", &FlashProtectionConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "FlashProtectionConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> FlashProtectionConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadHdAudioConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_HDAUDIO_CONFIG  *HdAudioConfig;
> +  HdAudioConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "HdAudioConfig->Header.GuidHob.Name = %g\n",
> &HdAudioConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "HdAudioConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> HdAudioConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    HD-Audio configuration
> +  ********************************/
> +  HdAudioConfig->DspEnable            = TRUE;
> +  HdAudioConfig->HdAudioLinkFrequency = PchHdaLinkFreq24MHz;
> +  HdAudioConfig->IDispLinkFrequency   = PchHdaLinkFreq96MHz;
> +  HdAudioConfig->IDispLinkTmode       = PchHdaIDispMode2T;
> +  HdAudioConfig->ResetWaitTimer       = 600; // Must be at least 521us (25
> frames)
> +  HdAudioConfig->AudioLinkHda         = TRUE;
> +  HdAudioConfig->AudioLinkDmic0       = TRUE;
> +  HdAudioConfig->AudioLinkDmic1       = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadInterruptConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_INTERRUPT_CONFIG  *InterruptConfig;
> +  InterruptConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "InterruptConfig->Header.GuidHob.Name = %g\n",
> &InterruptConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "InterruptConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> InterruptConfig->Header.GuidHob.Header.HobLength));
> +
> +  LoadDeviceInterruptConfig (InterruptConfig);
> +
> +  ASSERT ((sizeof (mPxRcConfig) / sizeof (UINT8)) <=
> PCH_MAX_PXRC_CONFIG);
> +  CopyMem (
> +    InterruptConfig->PxRcConfig,
> +    mPxRcConfig,
> +    sizeof (mPxRcConfig)
> +    );
> +
> +  InterruptConfig->GpioIrqRoute = 14;
> +  InterruptConfig->SciIrqSelect = 9;
> +  InterruptConfig->TcoIrqSelect = 9;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadIshConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_ISH_CONFIG  *IshConfig;
> +  IshConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Name = %g\n",
> &IshConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", IshConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadLanConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_LAN_CONFIG  *LanConfig;
> +  UINT16          LpcDid;
> +
> +  LanConfig = ConfigBlockPointer;
> +  LpcDid    = PchGetLpcDid ();
> +
> +  DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Name = %g\n",
> &LanConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", LanConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Lan configuration
> +  ********************************/
> +  LanConfig->Enable = TRUE;
> +  LanConfig->LtrEnable = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadLockDownConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_LOCK_DOWN_CONFIG  *LockDownConfig;
> +  LockDownConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "LockDownConfig->Header.GuidHob.Name = %g\n",
> &LockDownConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "LockDownConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> LockDownConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Lockdown configuration
> +  ********************************/
> +  LockDownConfig->GlobalSmi       = TRUE;
> +  LockDownConfig->BiosInterface   = TRUE;
> +  LockDownConfig->RtcMemoryLock   = TRUE;
> +  LockDownConfig->BiosLock        = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadP2sbConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_P2SB_CONFIG  *P2sbConfig;
> +  P2sbConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Name = %g\n",
> &P2sbConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", P2sbConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadPmConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_PM_CONFIG  *PmConfig;
> +  PmConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Name = %g\n",
> &PmConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", PmConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    MiscPm Configuration
> +  ********************************/
> +  PmConfig->MeWakeSts                            = TRUE;
> +  PmConfig->WolOvrWkSts                          = TRUE;
> +
> +  PmConfig->WakeConfig.WolEnableOverride         = TRUE;
> +  PmConfig->WakeConfig.LanWakeFromDeepSx         = TRUE;
> +
> +  PmConfig->PchSlpS3MinAssert                    = PchSlpS350ms;
> +  PmConfig->PchSlpS4MinAssert                    = PchSlpS41s;
> +  PmConfig->PchSlpSusMinAssert                   = PchSlpSus4s;
> +  PmConfig->PchSlpAMinAssert                     = PchSlpA2s;
> +
> +  PmConfig->SlpLanLowDc                          = TRUE;
> +  PmConfig->PciePllSsc                           = 0xFF;
> +  PmConfig->LpcClockRun                          = TRUE;
> +  PmConfig->SlpS0Enable                          = TRUE;
> +  PmConfig->CpuC10GatePinEnable                  = TRUE;
> +  if (IsWhlCpu () && (GetCpuStepping () == EnumCflV0)) {
> +    PmConfig->SlpS0WithGbeSupport                  = FALSE;
> +  } else {
> +    PmConfig->SlpS0WithGbeSupport                  = TRUE;
> +  }
> +
> +  if (IsPchLp ()) {
> +    PmConfig->ModPhySusPgEnable                  = TRUE;
> +  }
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadScsConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_SCS_CONFIG  *ScsConfig;
> +  ScsConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Name = %g\n",
> &ScsConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", ScsConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    SCS Configuration
> +  ********************************/
> +  ScsConfig->ScsEmmcEnabled   = IsPchLp () ? TRUE : FALSE; // eMMC present
> on PCH-LP only
> +  ScsConfig->ScsEmmcHs400DriverStrength = DriverStrength40Ohm;
> +  //Enable Sd Card controller for Non-Desktop sku platforms
> +  if (GetCpuSku () != EnumCpuTrad) {
> +    ScsConfig->ScsSdcardEnabled = TRUE;
> +  }
> +  ScsConfig->SdCardPowerEnableActiveHigh = TRUE;
> +  ScsConfig->ScsUfsEnabled    = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadSerialIoConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  UINTN                 Index;
> +  PCH_SERIAL_IO_CONFIG  *SerialIoConfig;
> +  SerialIoConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SerialIoConfig->Header.GuidHob.Name = %g\n",
> &SerialIoConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "SerialIoConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> SerialIoConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    SerialIo Configuration
> +  ********************************/
> +  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
> +    SerialIoConfig->DevMode[Index]         = PchSerialIoPci;
> +  }
> +  SerialIoConfig->DebugUartNumber          = PcdGet8
> (PcdSerialIoUartNumber);
> +}
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadSerialIrqConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_LPC_SIRQ_CONFIG  *SerialIrqConfig;
> +  SerialIrqConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SerialIrqConfig->Header.GuidHob.Name = %g\n",
> &SerialIrqConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "SerialIrqConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> SerialIrqConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Serial IRQ Configuration
> +  ********************************/
> +  SerialIrqConfig->SirqEnable       = TRUE;
> +  SerialIrqConfig->SirqMode         = PchQuietMode;
> +  SerialIrqConfig->StartFramePulse  = PchSfpw4Clk;
> +}
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadThermalConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_THERMAL_CONFIG  *ThermalConfig;
> +  ThermalConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "ThermalConfig->Header.GuidHob.Name = %g\n",
> &ThermalConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "ThermalConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> ThermalConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Thermal configuration.
> +  ********************************/
> +  ThermalConfig->TsmicLock                   = TRUE;
> +  ThermalConfig->PchHotLevel                 = 0x154;
> +  ThermalConfig->TTLevels.SuggestedSetting   = TRUE;
> +  ThermalConfig->TTLevels.PchCrossThrottling = TRUE;
> +  ThermalConfig->DmiHaAWC.SuggestedSetting   = TRUE;
> +
> +
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].PmsyncEnable
> = TRUE;
> +
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].C0TransmitEn
> able = TRUE;
> +
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].PmsyncEnable
> = TRUE;
> +
> ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].C0TransmitEn
> able = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadUsbConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  UINTN           PortIndex;
> +  USB_CONFIG      *UsbConfig;
> +  UsbConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Name = %g\n",
> &UsbConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", UsbConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    USB related configuration
> +  ********************************/
> +  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++)
> {
> +    UsbConfig->PortUsb20[PortIndex].Enable  = TRUE;
> +  }
> +
> +  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++)
> {
> +    UsbConfig->PortUsb30[PortIndex].Enable  = TRUE;
> +  }
> +
> +  //
> +  // BIOS should program PDO in PEI phase by default
> +  //
> +  UsbConfig->PdoProgramming = TRUE;
> +
> +  //
> +  // Default values of USB2 AFE settings.
> +  //
> +  UsbConfig->Usb2PhySusPgEnable = TRUE;
> +  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortIndex++)
> {
> +    UsbConfig->PortUsb20[PortIndex].Afe.Petxiset  = 3;
> +    UsbConfig->PortUsb20[PortIndex].Afe.Txiset    = 2;
> +    UsbConfig->PortUsb20[PortIndex].Afe.Predeemp  = 1;
> +    UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit = 1;
> +  }
> +
> +  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++)
> {
> +    UsbConfig->PortUsb30HsioRx[PortIndex].HsioOlfpsCfgPullUpDwnRes = 3;
> +  }
> +
> +  UsbConfig->XhciOcLock = TRUE;
> +
> +  //
> +  // xDCI configuration
> +  //
> +  UsbConfig->XdciConfig.Enable = FALSE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadEspiConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_ESPI_CONFIG  *EspiConfig;
> +  EspiConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Name = %g\n",
> &EspiConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", EspiConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Espi configuration.
> +  ********************************/
> +  EspiConfig->BmeMasterSlaveEnabled = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCnviConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_CNVI_CONFIG  *CnviConfig;
> +  CnviConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Name = %g\n",
> &CnviConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", CnviConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    Cnvi configuration.
> +  ********************************/
> +  CnviConfig->Mode = CnviModeAuto; // Automatic detection
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadHsioConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_HSIO_CONFIG  *HsioConfig;
> +  HsioConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Name = %g\n",
> &HsioConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", HsioConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY
> mPchIpBlocks [] = {
> +  {&gPchGeneralConfigGuid,       sizeof (PCH_GENERAL_CONFIG),
> PCH_GENERAL_CONFIG_REVISION,       LoadPchGeneralConfigDefault},
> +  {&gPcieRpConfigGuid,           sizeof (PCH_PCIE_CONFIG),
> PCIE_RP_CONFIG_REVISION,           LoadPcieRpConfigDefault},
> +  {&gSataConfigGuid,             sizeof (PCH_SATA_CONFIG),
> SATA_CONFIG_REVISION,              LoadSataConfigDefault},
> +  {&gIoApicConfigGuid,           sizeof (PCH_IOAPIC_CONFIG),
> IOAPIC_CONFIG_REVISION,            LoadIoApicConfigDefault},
> +  {&gDmiConfigGuid,              sizeof (PCH_DMI_CONFIG),
> DMI_CONFIG_REVISION,               LoadDmiConfigDefault},
> +  {&gFlashProtectionConfigGuid,  sizeof (PCH_FLASH_PROTECTION_CONFIG),
> FLASH_PROTECTION_CONFIG_REVISION,  LoadFlashProtectionConfigDefault},
> +  {&gHdAudioConfigGuid,          sizeof (PCH_HDAUDIO_CONFIG),
> HDAUDIO_CONFIG_REVISION,           LoadHdAudioConfigDefault},
> +  {&gInterruptConfigGuid,        sizeof (PCH_INTERRUPT_CONFIG),
> INTERRUPT_CONFIG_REVISION,         LoadInterruptConfigDefault},
> +  {&gIshConfigGuid,              sizeof (PCH_ISH_CONFIG),
> ISH_CONFIG_REVISION,               LoadIshConfigDefault},
> +  {&gLanConfigGuid,              sizeof (PCH_LAN_CONFIG),
> LAN_CONFIG_REVISION,               LoadLanConfigDefault},
> +  {&gLockDownConfigGuid,         sizeof (PCH_LOCK_DOWN_CONFIG),
> LOCK_DOWN_CONFIG_REVISION,         LoadLockDownConfigDefault},
> +  {&gP2sbConfigGuid,             sizeof (PCH_P2SB_CONFIG),
> P2SB_CONFIG_REVISION,              LoadP2sbConfigDefault},
> +  {&gPmConfigGuid,               sizeof (PCH_PM_CONFIG),
> PM_CONFIG_REVISION,                LoadPmConfigDefault},
> +  {&gScsConfigGuid,              sizeof (PCH_SCS_CONFIG),
> SCS_CONFIG_REVISION,               LoadScsConfigDefault},
> +  {&gSerialIoConfigGuid,         sizeof (PCH_SERIAL_IO_CONFIG),
> SERIAL_IO_CONFIG_REVISION,         LoadSerialIoConfigDefault},
> +  {&gSerialIrqConfigGuid,        sizeof (PCH_LPC_SIRQ_CONFIG),
> SERIAL_IRQ_CONFIG_REVISION,        LoadSerialIrqConfigDefault},
> +  {&gThermalConfigGuid,          sizeof (PCH_THERMAL_CONFIG),
> THERMAL_CONFIG_REVISION,           LoadThermalConfigDefault},
> +  {&gUsbConfigGuid,              sizeof (USB_CONFIG),
> USB_CONFIG_REVISION,               LoadUsbConfigDefault},
> +  {&gEspiConfigGuid,             sizeof (PCH_ESPI_CONFIG),
> ESPI_CONFIG_REVISION,              LoadEspiConfigDefault},
> +  {&gCnviConfigGuid,             sizeof (PCH_CNVI_CONFIG),
> CNVI_CONFIG_REVISION,              LoadCnviConfigDefault},
> +  {&gHsioConfigGuid,             sizeof (PCH_HSIO_CONFIG),
> HSIO_CONFIG_REVISION,              LoadHsioConfigDefault},
> +};
> +
> +/**
> +  Get PCH config block table total size.
> +
> +  @retval                               Size of PCH config block table
> +**/
> +UINT16
> +EFIAPI
> +PchGetConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize (&mPchIpBlocks[0], sizeof
> (mPchIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> +
> +/**
> +  PchAddConfigBlocks add all PCH config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add PCH config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchAddConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "PCH AddConfigBlocks\n"));
> +
> +  return AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mPchIpBlocks[0], sizeof (mPchIpBlocks) / sizeof
> (COMPONENT_BLOCK_ENTRY));
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibCnl.c
> new file mode 100644
> index 0000000000..d19692ff2c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolic
> yLibCnl.c
> @@ -0,0 +1,169 @@
> +/** @file
> +  This file is PeiPchPolicy library Cannon Lake specific.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyLibrary.h"
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/CpuPlatformLib.h>
> +
> +/**
> +  mDevIntConfig[] table contains data on INTx and IRQ for each device.
> +  IRQ value for devices which use ITSS INTx->PIRQx mapping need to be set in
> a way
> +  that for each multifunctional Dxx:Fy same interrupt pins must map to the
> same IRQ.
> +  Those IRQ values will be used to update ITSS.PIRx register.
> +  In APIC relationship between PIRQs and IRQs is:
> +  PIRQA -> IRQ16
> +  PIRQB -> IRQ17
> +  PIRQC -> IRQ18
> +  PIRQD -> IRQ19
> +  PIRQE -> IRQ20
> +  PIRQF -> IRQ21
> +  PIRQG -> IRQ22
> +  PIRQH -> IRQ23
> +
> +  Devices which use INTx->PIRQy mapping are: cAVS(in PCI mode), SMBus, GbE,
> TraceHub, PCIe,
> +  SATA, HECI, IDE-R, KT Redirection, xHCI, Thermal Subsystem, Camera IO Host
> Controller
> +
> +  PCI Express Root Ports mapping should be programmed only with values as
> in below table (D27/28/29)
> +  otherwise _PRT methods in ACPI for RootPorts would require additional
> patching as
> +  PCIe Endpoint Device Interrupt is further subjected to INTx to PIRQy
> Mapping
> +
> +  Configured IRQ values are not used if an OS chooses to be in PIC instead of
> APIC mode
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG
> mDevIntConfig[] = {
> +//  {31, 0, PchNoInt, 0}, // LPC/eSPI Interface, doesn't use interrupts
> +//  {31, 1, PchNoInt, 0}, // P2SB, doesn't use interrupts
> +//  {31, 2, PchNoInt, 0}, // PMC , doesn't use interrupts
> +  {31, 3, PchIntA, 16}, // cAVS(Audio, Voice, Speach), INTA is default,
> programmed in PciCfgSpace 3Dh
> +  {31, 4, PchIntA, 16}, // SMBus Controller, no default value, programmed in
> PciCfgSpace 3Dh
> +//  {31, 5, PchNoInt, 0}, // SPI , doesn't use interrupts
> +  {31, 7, PchIntA, 16}, // TraceHub, INTA is default, RO register
> +  {30, 0, PchIntA, 20}, // SerialIo: UART #0, INTA is default, programmed in
> PCR[SERIALIO] + PCICFGCTRL[7]
> +  {30, 1, PchIntB, 21}, // SerialIo: UART #1, INTA is default, programmed in
> PCR[SERIALIO] + PCICFGCTRL[8]
> +  {30, 2, PchIntC, 22}, // SerialIo: SPI #0, INTA is default, programmed in
> PCR[SERIALIO] + PCICFGCTRL[10]
> +  {30, 3, PchIntD, 23}, // SerialIo: SPI #1, INTA is default, programmed in
> PCR[SERIALIO] + PCICFGCTRL[11]
> +  {28, 0, PchIntA, 16}, // PCI Express Port 1, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 1, PchIntB, 17}, // PCI Express Port 2, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 2, PchIntC, 18}, // PCI Express Port 3, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 3, PchIntD, 19}, // PCI Express Port 4, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 4, PchIntA, 16}, // PCI Express Port 5, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 5, PchIntB, 17}, // PCI Express Port 6, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 6, PchIntC, 18}, // PCI Express Port 7, INT is default, programmed in
> PciCfgSpace + FCh
> +  {28, 7, PchIntD, 19}, // PCI Express Port 8, INT is default, programmed in
> PciCfgSpace + FCh
> +  {25, 2, PchIntC, 34}, // SerialIo UART Controller #2, INTA is default,
> programmed in PCR[SERIALIO] + PCICFGCTRL[9]
> +//  {24, 0, 0, 0}, // Reserved (used by RST PCIe Storage Cycle Router)
> +  {23, 0, PchIntA, 16}, // SATA Controller, INTA is default, programmed in
> PciCfgSpace + 3Dh
> +  {22, 0, PchIntA, 16}, // CSME: HECI #1
> +  {22, 1, PchIntB, 17}, // CSME: HECI #2
> +  {22, 4, PchIntA, 16}, // CSME: HECI #3
> +//  {22, 7, PchNoInt, 0}, // CSME: WLAN
> +  {21, 0, PchIntA, 16}, // SerialIo I2C Controller #0, INTA is default,
> programmed in PCR[SERIALIO] + PCICFGCTRL[1]
> +  {21, 1, PchIntB, 17}, // SerialIo I2C Controller #1, INTA is default, programmed
> in PCR[SERIALIO] + PCICFGCTRL[2]
> +  {21, 2, PchIntC, 18}, // SerialIo I2C Controller #2, INTA is default, programmed
> in PCR[SERIALIO] + PCICFGCTRL[3]
> +  {21, 3, PchIntD, 19}, // SerialIo I2C Controller #3, INTA is default, programmed
> in PCR[SERIALIO] + PCICFGCTRL[4]
> +  {20, 0, PchIntA, 16}, // USB 3.0 xHCI Controller, no default value,
> programmed in PciCfgSpace 3Dh
> +  {20, 1, PchIntB, 17}, // USB Device Controller (OTG)
> +  //{20, 2, PchNoInt, 0}, // Shared SRAM, no interrupts
> +  {20, 3, PchIntA, 16}, // CNVi WiFir
> +//  {20, 4, 0, 0}, // TraceHub Phantom (ACPI) Function
> +  {20, 5, PchIntD, 19}, // SCS: SDCard
> +//  {18, 0, PchNoInt, 0}, // CSME: KVMcc,  doesn't use interrupts
> +//  {18, 1, PchNoInt, 0}, // CSME: Clink,  doesn't use interrupts
> +//  {18, 2, PchNoInt, 0}, // CSME: PMT,  doesn't use interrupts
> +//  {18, 3, 0, 0}, // CSME: CSE UMA
> +//  {18, 4, 0, 0}  // CSME: fTPM DMA
> +  {18, 5, PchIntA, 16}  // SCS: UFS
> +};
> +
> +//
> +// mCnlPchLpOnlyDevIntConfig[] table contains data on INTx and IRQ for
> devices that exist on PCH-LP
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG
> mPchLpOnlyDevIntConfig[] = {
> +  {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed in
> PciCfgSpace 3Dh
> +  {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programmed in
> PciCfgSpace + FCh
> +  {26, 0, PchIntA, 16}, // SCS: eMMC
> +  {25, 0, PchIntA, 32}, // SerialIo I2C Controller #4, INTA is default,
> programmed in PCR[SERIALIO] + PCICFGCTRL[5]
> +  {25, 1, PchIntB, 33}, // SerialIo I2C Controller #5, INTA is default, programmed
> in PCR[SERIALIO] + PCICFGCTRL[6]
> +  {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R)
> +  {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection
> +  {19, 0, PchIntA, 20}, // Integrated Sensor Hub
> +  {18, 0, PchIntA, 16}, // Thermal Subsystem
> +  {18, 6, PchIntB, 24}  // SerialIo: SPI #2, INTA is default, programmed in
> PCR[SERIALIO] + PCICFGCTRL[12]
> +};
> +
> +//
> +// mPchHOnlyDevIntConfig[] table contains data on INTx and IRQ for devices
> that exist on PCH-H
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG
> mPchHOnlyDevIntConfig[] = {
> +  {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed in
> PciCfgSpace 3Dh
> +  {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programmed in
> PciCfgSpace + FCh
> +  {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programmed in
> PciCfgSpace + FCh
> +  {27, 0, PchIntA, 16}, // PCI Express Port 17, INT is default, programmed in
> PciCfgSpace + FCh
> +  {27, 1, PchIntB, 17}, // PCI Express Port 18, INT is default, programmed in
> PciCfgSpace + FCh
> +  {27, 2, PchIntC, 18}, // PCI Express Port 19, INT is default, programmed in
> PciCfgSpace + FCh
> +  {27, 3, PchIntD, 19}, // PCI Express Port 20, INT is default, programmed in
> PciCfgSpace + FCh
> +  {27, 4, PchIntA, 16}, // PCI Express Port 21
> +  {27, 5, PchIntB, 17}, // PCI Express Port 22
> +  {27, 6, PchIntC, 18}, // PCI Express Port 23
> +  {27, 7, PchIntD, 19}, // PCI Express Port 24
> +  {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R)
> +  {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection
> +  {19, 0, PchIntA, 20}, // Integrated Sensor Hub
> +  {18, 0, PchIntA, 16}, // Thermal Subsystem
> +  {18, 6, PchIntB, 24}  // SerialIo: SPI #2, INTA is default, programmed in
> PCR[SERIALIO] + PCICFGCTRL[12]
> +};
> +
> +/**
> +  Adds interrupt configuration for device
> +
> +  @param[in/out] InterruptConfig         Pointer to interrupt config
> +**/
> +VOID
> +LoadDeviceInterruptConfig (
> +  IN OUT  PCH_INTERRUPT_CONFIG  *InterruptConfig
> +  )
> +{
> +  UINT8                 IntConfigTableEntries;
> +
> +  IntConfigTableEntries = ARRAY_SIZE (mDevIntConfig);
> +  ASSERT (IntConfigTableEntries <= PCH_MAX_DEVICE_INTERRUPT_CONFIG);
> +  InterruptConfig->NumOfDevIntConfig = IntConfigTableEntries;
> +  CopyMem (
> +    InterruptConfig->DevIntConfig,
> +    mDevIntConfig,
> +    sizeof (mDevIntConfig)
> +    );
> +
> +  if (IsPchLp ()) {
> +    CopyMem (
> +
> &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]),
> +      mPchLpOnlyDevIntConfig,
> +      sizeof (mPchLpOnlyDevIntConfig)
> +      );
> +    InterruptConfig->NumOfDevIntConfig += ARRAY_SIZE
> (mPchLpOnlyDevIntConfig);
> +  } else if (IsPchH ()) {
> +    CopyMem (
> +
> &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]),
> +      mPchHOnlyDevIntConfig,
> +      sizeof (mPchHOnlyDevIntConfig)
> +      );
> +    InterruptConfig->NumOfDevIntConfig += ARRAY_SIZE
> (mPchHOnlyDevIntConfig);
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreM
> emPolicyLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreM
> emPolicyLib.c
> new file mode 100644
> index 0000000000..dfab5d29c2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreM
> emPolicyLib.c
> @@ -0,0 +1,318 @@
> +/** @file
> +  This file is PeiPchPreMemPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyLibrary.h"
> +#include <Library/CpuPlatformLib.h>
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadPchGeneralPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_GENERAL_PREMEM_CONFIG  *PchGeneralPreMemConfig;
> +  PchGeneralPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO,
> "PchGeneralPreMemConfig->Header.GuidHob.Name = %g\n",
> &PchGeneralPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    PCH general premem configuration
> +  ********************************/
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadDciPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_DCI_PREMEM_CONFIG  *DciPreMemConfig;
> +  DciPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "DciPreMemConfig->Header.GuidHob.Name =
> %g\n", &DciPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "DciPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> DciPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    DCI Configuration
> +  ********************************/
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadWatchDogPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_WDT_PREMEM_CONFIG       *WdtPreMemConfig;
> +  WdtPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "WdtPreMemConfig->Header.GuidHob.Name =
> %g\n", &WdtPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "WdtPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> WdtPreMemConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadPchTraceHubPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_TRACE_HUB_PREMEM_CONFIG  *PchTraceHubPreMemConfig;
> +  PchTraceHubPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO,
> "PchTraceHubPreMemConfig->Header.GuidHob.Name = %g\n",
> &PchTraceHubPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusRsvdAddresses[] = {
> +  0xA0,
> +  0xA2,
> +  0xA4,
> +  0xA6
> +};
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadSmbusPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_SMBUS_PREMEM_CONFIG  *SmbusPreMemConfig;
> +  SmbusPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SmbusPreMemConfig->Header.GuidHob.Name =
> %g\n", &SmbusPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "SmbusPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> SmbusPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    SMBus configuration
> +  ********************************/
> +  SmbusPreMemConfig->Enable                = TRUE;
> +  SmbusPreMemConfig->DynamicPowerGating    = TRUE;
> +  SmbusPreMemConfig->SpdWriteDisable       = TRUE;
> +  SmbusPreMemConfig->SmbusIoBase           = PcdGet16
> (PcdSmbusBaseAddress);
> +  ASSERT (sizeof (mSmbusRsvdAddresses) <=
> PCH_MAX_SMBUS_RESERVED_ADDRESS);
> +  SmbusPreMemConfig->NumRsvdSmbusAddresses = sizeof
> (mSmbusRsvdAddresses);
> +  CopyMem (
> +    SmbusPreMemConfig->RsvdSmbusAddressTable,
> +    mSmbusRsvdAddresses,
> +    sizeof (mSmbusRsvdAddresses)
> +    );
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadLpcPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_LPC_PREMEM_CONFIG  *LpcPreMemConfig;
> +  LpcPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "LpcPreMemConfig->Header.GuidHob.Name =
> %g\n", &LpcPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "LpcPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> LpcPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    LPC Configuration
> +  ********************************/
> +  LpcPreMemConfig->EnhancePort8xhDecoding     = TRUE;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadHsioPciePreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_HSIO_PCIE_PREMEM_CONFIG  *HsioPciePreMemConfig;
> +  HsioPciePreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "HsioPciePreMemConfig->Header.GuidHob.Name =
> %g\n", &HsioPciePreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "HsioPciePreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> HsioPciePreMemConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadHsioSataPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_HSIO_SATA_PREMEM_CONFIG  *HsioSataPreMemConfig;
> +  HsioSataPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "HsioSataPreMemConfig->Header.GuidHob.Name =
> %g\n", &HsioSataPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "HsioSataPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> HsioSataPreMemConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +/**
> +  Get Hsio Sata Pre Mem Config Policy
> +
> +  @param[in]  SiPolicy            The RC Policy PPI instance
> +  @param[in]  SataCtrlIndex       SATA controller index
> +
> +  @retval     Pointer to Hsio Sata Pre Mem Config Policy
> +**/
> +PCH_HSIO_SATA_PREMEM_CONFIG *
> +GetPchHsioSataPreMemConfig (
> +  IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy,
> +  IN UINT32               SataCtrlIndex
> +  )
> +{
> +  PCH_HSIO_SATA_PREMEM_CONFIG     *HsioSataPreMemConfig;
> +  EFI_STATUS                      Status;
> +
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  HsioSataPreMemConfig += SataCtrlIndex;
> +
> +  return HsioSataPreMemConfig;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadPcieRpPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_PCIE_RP_PREMEM_CONFIG  *PcieRpPreMemConfig;
> +  UINT32                     RpIndex;
> +
> +  PcieRpPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name =
> %g\n", &PcieRpPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PcieRpPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  for (RpIndex = 0; RpIndex < GetPchMaxPciePortNum (); RpIndex ++) {
> +    PcieRpPreMemConfig->RpEnabledMask |= (UINT32) (1 << RpIndex);
> +  }
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadHdAudioPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_HDAUDIO_PREMEM_CONFIG  *HdaPreMemConfig;
> +  HdaPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name =
> %g\n", &HdaPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> HdaPreMemConfig->Header.GuidHob.Header.HobLength));
> +  HdaPreMemConfig->Enable = 1;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadIshPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  PCH_ISH_PREMEM_CONFIG  *IshPreMemConfig;
> +  IshPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name =
> %g\n", &IshPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> IshPreMemConfig->Header.GuidHob.Header.HobLength));
> +  //Enable ISH controller for Non-Desktop sku platforms
> +  if (GetCpuSku () != EnumCpuTrad) {
> +    IshPreMemConfig->Enable = TRUE;
> +  }
> +}
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY
> mPchIpBlocksPreMem [] = {
> +  {&gPchGeneralPreMemConfigGuid,     sizeof
> (PCH_GENERAL_PREMEM_CONFIG),
> PCH_GENERAL_PREMEM_CONFIG_REVISION,
> LoadPchGeneralPreMemConfigDefault},
> +  {&gDciPreMemConfigGuid,            sizeof (PCH_DCI_PREMEM_CONFIG),
> DCI_PREMEM_CONFIG_REVISION,                LoadDciPreMemConfigDefault},
> +  {&gWatchDogPreMemConfigGuid,       sizeof
> (PCH_WDT_PREMEM_CONFIG),
> WATCH_DOG_PREMEM_CONFIG_REVISION,
> LoadWatchDogPreMemConfigDefault},
> +  {&gPchTraceHubPreMemConfigGuid,    sizeof
> (PCH_TRACE_HUB_PREMEM_CONFIG),
> PCH_TRACEHUB_PREMEM_CONFIG_REVISION,
> LoadPchTraceHubPreMemConfigDefault},
> +  {&gSmbusPreMemConfigGuid,          sizeof
> (PCH_SMBUS_PREMEM_CONFIG),      SMBUS_PREMEM_CONFIG_REVISION,
> LoadSmbusPreMemConfigDefault},
> +  {&gLpcPreMemConfigGuid,            sizeof (PCH_LPC_PREMEM_CONFIG),
> LPC_PREMEM_CONFIG_REVISION,                LoadLpcPreMemConfigDefault},
> +  {&gHsioPciePreMemConfigGuid,       sizeof
> (PCH_HSIO_PCIE_PREMEM_CONFIG),
> HSIO_PCIE_PREMEM_CONFIG_REVISION,
> LoadHsioPciePreMemConfigDefault},
> +  {&gHsioSataPreMemConfigGuid,       sizeof
> (PCH_HSIO_SATA_PREMEM_CONFIG),
> HSIO_SATA_PREMEM_CONFIG_REVISION,
> LoadHsioSataPreMemConfigDefault},
> +  {&gPcieRpPreMemConfigGuid,         sizeof
> (PCH_PCIE_RP_PREMEM_CONFIG),    PCIE_RP_PREMEM_CONFIG_REVISION,
> LoadPcieRpPreMemConfigDefault},
> +  {&gHdAudioPreMemConfigGuid,        sizeof
> (PCH_HDAUDIO_PREMEM_CONFIG),
> HDAUDIO_PREMEM_CONFIG_REVISION,
> LoadHdAudioPreMemConfigDefault},
> +  {&gIshPreMemConfigGuid,            sizeof (PCH_ISH_PREMEM_CONFIG),
> ISH_PREMEM_CONFIG_REVISION,                LoadIshPreMemConfigDefault},
> +};
> +
> +/**
> +  Get PCH PREMEM config block table total size.
> +
> +  @retval                               Size of PCH PREMEM config block table
> +**/
> +UINT16
> +EFIAPI
> +PchGetPreMemConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize (&mPchIpBlocksPreMem[0],
> sizeof (mPchIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> +
> +/**
> +  PchAddPreMemConfigBlocks add all PCH PREMEM config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add PCH PREMEM
> config blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchAddPreMemConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "PCH AddPreMemConfigBlocks\n"));
> +
> +  return AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mPchIpBlocksPreMem[0], sizeof (mPchIpBlocksPreMem) / sizeof
> (COMPONENT_BLOCK_ENTRY));
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
> new file mode 100644
> index 0000000000..2210344462
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
> @@ -0,0 +1,109 @@
> +/** @file
> +  PCH RESET PEIM DRIVER.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Ppi/Reset2.h>
> +#include <Ppi/PchReset.h>
> +#include <Library/PchResetLib.h>
> +#include <Library/ResetSystemLib.h>
> +
> +
> +/**
> +  Resets the entire platform.
> +
> +  @param[in] ResetType            UEFI defined reset type.
> +  @param[in] ResetStatus          The status code for the reset.
> +  @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
> +ResetSystem (
> +  IN EFI_RESET_TYPE     ResetType,
> +  IN EFI_STATUS         ResetStatus,
> +  IN UINTN              DataSize,
> +  IN VOID               *ResetData OPTIONAL
> +  )
> +{
> +  switch (ResetType) {
> +  case EfiResetWarm:
> +    ResetWarm ();
> +    break;
> +
> +  case EfiResetCold:
> +    ResetCold ();
> +    break;
> +
> +  case EfiResetShutdown:
> +    ResetShutdown ();
> +    return;
> +
> +  case EfiResetPlatformSpecific:
> +    ResetPlatformSpecific (DataSize, ResetData);
> +    return;
> +
> +  default:
> +    return;
> +  }
> +
> +  //
> +  // Given we should have reset getting here would be bad
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop();
> +}
> +
> +/**
> +  Initialize PCH Reset APIs
> +
> +  @retval EFI_SUCCESS             APIs are installed successfully
> +  @retval EFI_OUT_OF_RESOURCES    Can't allocate pool
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchInitializeReset (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_PEI_RESET2_PPI        *EfiPeiReset2Ppi;
> +  EFI_PEI_PPI_DESCRIPTOR    *EfiPeiReset2Descriptor;
> +
> +  DEBUG ((DEBUG_INFO, "PchInitializeReset() Start\n"));
> +
> +
> +  EfiPeiReset2Descriptor = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool
> (sizeof (EFI_PEI_PPI_DESCRIPTOR));
> +  EfiPeiReset2Ppi = (EFI_PEI_RESET2_PPI *) AllocateZeroPool (sizeof
> (EFI_PEI_RESET2_PPI));
> +  if ((EfiPeiReset2Descriptor == NULL) ||
> +      (EfiPeiReset2Ppi == NULL)) {
> +    ASSERT (FALSE);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  ///
> +  /// Initialize the EFI Reset2 ppi instance
> +  ///
> +  EfiPeiReset2Ppi->ResetSystem  = ResetSystem;
> +
> +  EfiPeiReset2Descriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  EfiPeiReset2Descriptor->Guid  = &gEfiPeiReset2PpiGuid;
> +  EfiPeiReset2Descriptor->Ppi   = EfiPeiReset2Ppi;
> +
> +  Status = PeiServicesInstallPpi (EfiPeiReset2Descriptor);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "PchInitializeReset() End\n"));
> +
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset
> SystemLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset
> SystemLib.c
> new file mode 100644
> index 0000000000..58f2d86103
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset
> SystemLib.c
> @@ -0,0 +1,257 @@
> +/** @file
> +  System reset library services.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PchResetLib.h>
> +#include <Library/ResetSystemLib.h>
> +#include <Library/PmcLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Ppi/PchReset.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsPmc.h>
> +
> +/**
> +  Dump reset message for debug build readability
> +**/
> +VOID
> +DumpResetMessage (
> +  VOID
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  UINTN       Index;
> +  //
> +  // ******************************
> +  // **    SYSTEM REBOOT !!!     **
> +  // ******************************
> +  //
> +  for (Index = 0; Index < 30; Index++) {
> +    DEBUG ((DEBUG_INFO, "*"));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n**    SYSTEM REBOOT !!!     **\n"));
> +  for (Index = 0; Index < 30; Index++) {
> +    DEBUG ((DEBUG_INFO, "*"));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +  DEBUG_CODE_END ();
> +}
> +/**
> +  Execute call back function for Pch Reset.
> +
> +  @param[in] ResetType            Reset Types which includes GlobalReset.
> +  @param[in] ResetTypeGuid        Pointer to an EFI_GUID, which is the Reset
> Type Guid.
> +**/
> +VOID
> +PchResetCallback (
> +  IN  EFI_RESET_TYPE      ResetType,
> +  IN  EFI_GUID            *ResetTypeGuid
> +  )
> +{
> +  EFI_STATUS              Status;
> +  UINTN                   Instance;
> +  PCH_RESET_CALLBACK_PPI  *PchResetCallbackPpi;
> +
> +  Instance = 0;
> +  do {
> +    Status = PeiServicesLocatePpi (
> +               &gPchResetCallbackPpiGuid,
> +               Instance,
> +               NULL,
> +               (VOID **) &PchResetCallbackPpi
> +               );
> +
> +    switch (Status) {
> +      case EFI_SUCCESS:
> +        PchResetCallbackPpi->ResetCallback (ResetType, ResetTypeGuid);
> +        break;
> +      case EFI_NOT_FOUND:
> +        break;
> +      default:
> +        ASSERT_EFI_ERROR (Status);
> +        break;
> +    }
> +    ++Instance;
> +  } while (Status == EFI_SUCCESS);
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback PPI
> +  //
> +  PchResetCallback (EfiResetCold, NULL);
> +  DumpResetMessage ();
> +
> +  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
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback PPI
> +  //
> +  PchResetCallback (EfiResetWarm, NULL);
> +  DumpResetMessage ();
> +
> +  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;
> +
> +  //
> +  // Loop through callback functions of PchResetCallback PPI
> +  //
> +  PchResetCallback (EfiResetShutdown, NULL);
> +
> +  ABase = PmcGetAcpiBase ();
> +  ///
> +  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the
> system from S5
> +  ///
> +  IoWrite32 ((UINTN) (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 ((UINTN) (ABase + R_ACPI_IO_PM1_STS),
> B_ACPI_IO_PM1_STS_PWRBTN);
> +
> +  ///
> +  /// Finally, transform system into S5 sleep state
> +  ///
> +  Data32 = IoRead32 ((UINTN) (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 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32);
> +
> +  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
> +
> +  DumpResetMessage ();
> +
> +  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32);
> +
> +  return;
> +}
> +
> +/**
> +  Internal function to execute the required HECI command for GlobalReset,
> +  if failed will use PCH Reest.
> +
> +**/
> +STATIC
> +VOID
> +PchGlobalReset (
> +  VOID
> +  )
> +{
> +  //
> +  // Loop through callback functions of PchResetCallback PPI
> +  //
> +  PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid);
> +
> +  //
> +  // PCH BIOS Spec Section 4.6 GPIO Reset Requirement
> +  //
> +  PmcEnableCf9GlobalReset ();
> +
> +  DumpResetMessage ();
> +
> +  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_GUID            *GuidPtr;
> +
> +  if (ResetData == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[PeiResetSystemLib] ResetData is not
> available.\n"));
> +    return;
> +  }
> +  GuidPtr = (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI_GUID));
> +  if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) {
> +    PchGlobalReset();
> +  } else {
> +    return;
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  ASSERT (FALSE);
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
> new file mode 100644
> index 0000000000..1a5db7f24a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
> @@ -0,0 +1,217 @@
> +/** @file
> +  PCH SPI PEI Library implements the SPI Host Controller Compatibility
> Interface.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Ppi/Spi.h>
> +#include <Private/Library/PchSpiCommonLib.h>
> +#include <PchReservedResources.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsSpi.h>
> +
> +typedef struct {
> +  EFI_PEI_PPI_DESCRIPTOR  PpiDescriptor;
> +  SPI_INSTANCE            SpiInstance;
> +} PEI_SPI_INSTANCE;
> +
> +/**
> +  PCI Enumeratuion is not done till later in DXE
> +  Initlialize SPI BAR0 to a default value till enumeration is done
> +  also enable memory space decoding for SPI
> +
> +**/
> +VOID
> +InitSpiBar0 (
> +  VOID
> +  )
> +{
> +  UINT64       PchSpiBase;
> +  PchSpiBase = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_SPI,
> +                 PCI_FUNCTION_NUMBER_PCH_SPI,
> +                 0
> +                 );
> +  PciSegmentAnd8 (PchSpiBase + PCI_COMMAND_OFFSET, (UINT8)
> ~EFI_PCI_COMMAND_MEMORY_SPACE);
> +  PciSegmentWrite32 (PchSpiBase + R_SPI_CFG_BAR0,
> PCH_SPI_BASE_ADDRESS);
> +  PciSegmentOr8 (PchSpiBase + PCI_COMMAND_OFFSET,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> +}
> +
> +/**
> +  This function Initial SPI services
> +
> +  @retval EFI_STATUS  Results of the installation of the SPI services
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiServiceInit (
> +  VOID
> +  )
> +{
> +  EFI_STATUS        Status;
> +  PEI_SPI_INSTANCE  *PeiSpiInstance;
> +  SPI_INSTANCE      *SpiInstance;
> +  PCH_SPI_PPI       *SpiPpi;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPchSpiPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **)&SpiPpi
> +             );
> +
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_INFO, "SpiServiceInit() Start\n"));
> +
> +    //
> +    // PCI Enumeratuion is not done till later in DXE
> +    // Initlialize SPI BAR0 to a default value till enumeration is done
> +    // also enable memory space decoding for SPI
> +    //
> +    InitSpiBar0 ();
> +
> +    PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof
> (PEI_SPI_INSTANCE));
> +    if (NULL == PeiSpiInstance) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    SpiInstance = &(PeiSpiInstance->SpiInstance);
> +    SpiProtocolConstructor (SpiInstance);
> +
> +    PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +    PeiSpiInstance->PpiDescriptor.Guid = &gPchSpiPpiGuid;
> +    PeiSpiInstance->PpiDescriptor.Ppi = &(SpiInstance->SpiProtocol);
> +
> +    ///
> +    /// Install the SPI PPI
> +    ///
> +    DEBUG ((DEBUG_INFO, "SPI PPI Installed\n"));
> +    Status = PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    DEBUG ((DEBUG_INFO, "SpiServiceInit() End\n"));
> +  }
> +  else {
> +    DEBUG ((DEBUG_INFO, "SPI PPI already installed\n"));
> +  }
> +  return Status;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  return PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) &
> ~(B_SPI_CFG_BAR0_MASK);
> +}
> +
> +/**
> +  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 = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_SPI,
> +                     PCI_FUNCTION_NUMBER_PCH_SPI,
> +                     0
> +                     );
> +  if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) &
> B_SPI_CFG_BC_EISS) != 0) {
> +    return EFI_ACCESS_DENIED;
> +  }
> +  ///
> +  /// Enable the access to the BIOS space for both read and write cycles
> +  ///
> +  PciSegmentOr8 (
> +    SpiBaseAddress + R_SPI_CFG_BC,
> +    B_SPI_CFG_BC_WPD
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function is a hook for Spi to enable BIOS Write Protect
> +
> +
> +**/
> +VOID
> +EFIAPI
> +EnableBiosWriteProtect (
> +  VOID
> +  )
> +{
> +  UINT64           SpiBaseAddress;
> +
> +  SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_SPI,
> +                     PCI_FUNCTION_NUMBER_PCH_SPI,
> +                     0
> +                     );
> +  ///
> +  /// Disable the access to the BIOS space for write cycles
> +  ///
> +  PciSegmentAnd8 (
> +    SpiBaseAddress + R_SPI_CFG_BC,
> +    (UINT8) (~B_SPI_CFG_BC_WPD)
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  return TRUE;
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:13 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add
> Base library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds Pch/Library/Private Base library class instances.
> 
> * BaseGpioHelpersLibNull
> * BasePchSpiCommonlib
> * BaseSiScheduleResetLib
> * BaseSiScheduleResetLibFsp
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibN
> ull/BaseGpioHelpersLibNull.inf     |   26 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLi
> b/BasePchSpiCommonLib.inf           |   28 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLib.inf     |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLibFsp.inf  |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibN
> ull/BaseGpioHelpersLibNull.c       |  108 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLi
> b/SpiCommon.c                       | 1081 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLib.c       |   70 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLibCommon.c |  125 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLi
> b/BaseSiScheduleResetLibFsp.c    |   61 ++
>  9 files changed, 1579 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.inf
> new file mode 100644
> index 0000000000..5502af824f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.inf
> @@ -0,0 +1,26 @@
> +## @file
> +# Component description file for the NULL GpioHelpersLib
> +#
> +# Copyright (c) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +BaseGpioHelpersLibNull.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommon
> Lib/BasePchSpiCommonLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/BasePchSpiCommonLib.inf
> new file mode 100644
> index 0000000000..ea23e628c8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/BasePchSpiCommonLib.inf
> @@ -0,0 +1,28 @@
> +## @file
> +#  Component description file for the PchSpiCommonLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BasePchSpiCommonLib
> +  FILE_GUID                      = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PchSpiCommonLib
> +
> +[Sources]
> +  SpiCommon.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  IoLib
> +  DebugLib
> +  PmcLib
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.inf
> new file mode 100644
> index 0000000000..de7f6eeb73
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Component description file for Si Reset Schedule Library.
> +#
> +# Copyright (c) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Guids]
> +gSiScheduleResetHobGuid
> +gPchConfigHobGuid
> +
> +[Sources]
> +BaseSiScheduleResetLibCommon.c
> +BaseSiScheduleResetLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.inf
> new file mode 100644
> index 0000000000..c8fe9e6079
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# Component description file for Si Reset Schedule Library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseSiScheduleResetLibFsp
> +FILE_GUID = 1478D005-8DEC-4A6E-9619-309C6A7F313A
> +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
> +PeiServicesTablePointerLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Guids]
> +gSiScheduleResetHobGuid
> +gPchConfigHobGuid
> +
> +[Sources]
> +BaseSiScheduleResetLibCommon.c
> +BaseSiScheduleResetLibFsp.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.c
> new file mode 100644
> index 0000000000..46390eeca1
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLib
> Null/BaseGpioHelpersLibNull.c
> @@ -0,0 +1,108 @@
> +/** @file
> +  This file contains NULL implementation for GPIO Helpers Lib
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <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;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommon
> Lib/SpiCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/SpiCommon.c
> new file mode 100644
> index 0000000000..bc84a4f27f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommo
> nLib/SpiCommon.c
> @@ -0,0 +1,1081 @@
> +/** @file
> +  PCH SPI Common Driver implements the SPI Host Controller Compatibility
> Interface.
> +
> +  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsSpi.h>
> +#include <Register/PchRegsPmc.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;
> +
> +  //
> +  // 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 = PCI_SEGMENT_LIB_ADDRESS (
> +                              DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                              DEFAULT_PCI_BUS_NUMBER_PCH,
> +                              PCI_DEVICE_NUMBER_PCH_SPI,
> +                              PCI_FUNCTION_NUMBER_PCH_SPI,
> +                              0
> +                              );
> +
> +  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_SPI_FLASH_FDBAR_FLASH_MAP0)
> +    );
> +
> +  //
> +  // Copy Zero based Number Of Components
> +  //
> +  SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16 (PchSpiBar0
> + R_SPI_MEM_FDOD) & B_SPI_FLASH_FDBAR_NC) >>
> N_SPI_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_SPI_FLASH_FCBA_FLCOMP)
> +    );
> +
> +  //
> +  // Copy Component 0 Density
> +  //
> +  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
> +  if (SpiInstance->NumberOfComponents > 0) {
> +    SpiInstance->Component1StartAddr =
> V_SPI_FLASH_FLCOMP_COMP_512KB <<
> +      (Data32 & B_SPI_FLASH_FLCOMP_COMP0_MASK);
> +    DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n",
> SpiInstance->Component1StartAddr));
> +    SpiInstance->TotalFlashSize = SpiInstance->Component1StartAddr +
> +      (V_SPI_FLASH_FLCOMP_COMP_512KB <<
> +      ((Data32 & B_SPI_FLASH_FLCOMP_COMP1_MASK) >>
> +      N_SPI_FLASH_FLCOMP_COMP1));
> +  } else {
> +    SpiInstance->TotalFlashSize = V_SPI_FLASH_FLCOMP_COMP_512KB <<
> +      (Data32 & B_SPI_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_SPI_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_SPI_FLASH_FDBAR_FPSBA)
> +                                             >> N_SPI_FLASH_FDBAR_FPSBA)
> +                                            << N_SPI_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_SPI_FLASH_FDBAR_PCHSL)
> +                                         >> N_SPI_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_SPI_FLASH_FDBAR_FLASH_MAP2)
> +    );
> +  //
> +  // Align FPSBA with address bits for the PCH Strap portion of flash descriptor
> +  //
> +  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
> +  SpiInstance->CpuStrapBaseAddr = (UINT16) (((Data32 &
> B_SPI_FLASH_FDBAR_FCPUSBA)
> +                                             >> N_SPI_FLASH_FDBAR_FCPUSBA)
> +                                            << N_SPI_FLASH_FDBAR_FCPUSBA_REPR);
> +  DEBUG ((DEBUG_INFO, "CpuStrapBaseAddr : %0x\n",
> SpiInstance->CpuStrapBaseAddr));
> +  ASSERT (SpiInstance->CpuStrapBaseAddr != 0);
> +  //
> +  // CPU Strap Length, [15:8] represents number of Dwords
> +  //
> +  SpiInstance->CpuStrapSize = (UINT16) (((Data32 &
> B_SPI_FLASH_FDBAR_CPUSL)
> +                                         >> N_SPI_FLASH_FDBAR_CPUSL)
> +                                        * sizeof (UINT32));
> +  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 (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.
> +**/
> +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;
> +
> +  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.
> +**/
> +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;
> +
> +  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.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashWriteStatus (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT32             ByteCount,
> +  IN     UINT8              *StatusValue
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // 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.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiProtocolFlashReadStatus (
> +  IN     PCH_SPI_PROTOCOL   *This,
> +  IN     UINT32             ByteCount,
> +  OUT    UINT8              *StatusValue
> +  )
> +{
> +  EFI_STATUS        Status;
> +
> +  //
> +  // 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/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.c
> new file mode 100644
> index 0000000000..dfc49d9bf6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 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 <Private/Library/SiScheduleResetLib.h>
> +#include <Private/SiScheduleResetHob.h>
> +
> +/**
> +  This function returns SiScheduleResetHob for library use
> +**/
> +SI_SCHEDULE_RESET_HOB *
> +SiScheduleGetResetData (
> +  VOID
> +  );
> +
> +/**
> +  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/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibCommon.c
> new file mode 100644
> index 0000000000..e1d783b2e2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibCommon.c
> @@ -0,0 +1,125 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi.h>
> +#include <Pi/PiMultiPhase.h>
> +#include <Library/HobLib.h>
> +#include <Private/SiScheduleResetHob.h>
> +
> +/**
> +  This function returns SiScheduleResetHob for library use
> +**/
> +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;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.c
> new file mode 100644
> index 0000000000..15ac61a21b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleRese
> tLib/BaseSiScheduleResetLibFsp.c
> @@ -0,0 +1,61 @@
> +/** @file
> +  Reset scheduling library services
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi.h>
> +#include <Pi/PiMultiPhase.h>
> +#include <Pi/PiPeiCis.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Library/HobLib.h>
> +#include <Private/Library/SiScheduleResetLib.h>
> +#include <Private/SiScheduleResetHob.h>
> +
> +/**
> +  This function returns SiScheduleResetHob for library use
> +**/
> +SI_SCHEDULE_RESET_HOB *
> +SiScheduleGetResetData (
> +  VOID
> +  );
> +
> +/**
> +  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));
> +  if (SiScheduleResetHob->ResetType == EfiResetPlatformSpecific) {
> +    DataSize = sizeof (PCH_RESET_DATA);
> +    (*GetPeiServicesTablePointer ())->ResetSystem2
> (SiScheduleResetHob->ResetType, EFI_SUCCESS, DataSize,
> &SiScheduleResetHob->ResetData);
> +  } else {
> +    (*GetPeiServicesTablePointer ())->ResetSystem2
> (SiScheduleResetHob->ResetType, EFI_SUCCESS, 0, NULL);
> +  }
> +  //
> +  // Code should never reach here
> +  //
> +  ASSERT (FALSE);
> +  return TRUE;
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:13   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:13 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE
> private library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH DXE private library class instances.
> 
> * DxeGpioNameBufferLib
> * DxePchHdaLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLi
> b/DxeGpioNameBufferLib.inf |  32 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePch
> HdaLib.inf                 |  43 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLi
> b/GpioNameBufferDxe.c      |  20 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHd
> aEndpoints.c                | 333 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHd
> aLib.c                      | 886 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHd
> aNhltConfig.c               | 439 ++++++++++
>  6 files changed, 1753 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBuffe
> rLib/DxeGpioNameBufferLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBuffe
> rLib/DxeGpioNameBufferLib.inf
> new file mode 100644
> index 0000000000..0dc8f9749d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBuffe
> rLib/DxeGpioNameBufferLib.inf
> @@ -0,0 +1,32 @@
> +## @file
> +# Component description file for the DxeGpioMemLib
> +#
> +# Copyright (c) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +GpioNameBufferDxe.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxeP
> chHdaLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxeP
> chHdaLib.inf
> new file mode 100644
> index 0000000000..a8a3f60b53
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxeP
> chHdaLib.inf
> @@ -0,0 +1,43 @@
> +## @file
> +# Component information file for PCH HD Audio Library
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxePchHdaLib
> +FILE_GUID = DA915B7F-EE08-4C1D-B3D0-DE7C52AB155A
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchHdaLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +DebugLib
> +MemoryAllocationLib
> +BaseMemoryLib
> +PchInfoLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
> +  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
> +  gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> +  gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
> +  gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> +
> +
> +[Sources]
> +PchHdaLib.c
> +PchHdaEndpoints.c
> +PchHdaNhltConfig.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBuffe
> rLib/GpioNameBufferDxe.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBuffe
> rLib/GpioNameBufferDxe.c
> new file mode 100644
> index 0000000000..af53387faf
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBuffe
> rLib/GpioNameBufferDxe.c
> @@ -0,0 +1,20 @@
> +/** @file
> +  This file contains implementation of the GpioMemLib for DXE phase
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Private/Library/GpioNameBufferLib.h>
> +
> +STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];
> +
> +CHAR8*
> +GpioGetStaticNameBuffer (
> +  VOID
> +  )
> +{
> +  return mGpioNameBuffer;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daEndpoints.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daEndpoints.c
> new file mode 100644
> index 0000000000..ea04512501
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daEndpoints.c
> @@ -0,0 +1,333 @@
> +/** @file
> +  This file contains HD Audio NHLT Endpoints definitions
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Private/PchHdaEndpoints.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE Ch1_48kHz16bitFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    1,
> +    48000,
> +    96000,
> +    2,
> +    16,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {16},
> +  KSAUDIO_SPEAKER_MONO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE Ch2_48kHz16bitFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    2,
> +    48000,
> +    192000,
> +    4,
> +    16,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {16},
> +  KSAUDIO_SPEAKER_STEREO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE Ch2_48kHz24bitFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    2,
> +    48000,
> +    384000,
> +    8,
> +    32,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {24},
> +  KSAUDIO_SPEAKER_STEREO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE Ch2_48kHz32bitFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    2,
> +    48000,
> +    384000,
> +    8,
> +    32,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {32},
> +  KSAUDIO_SPEAKER_STEREO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE Ch4_48kHz16bitFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    4,
> +    48000,
> +    384000,
> +    8,
> +    16,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {16},
> +  KSAUDIO_SPEAKER_QUAD,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE Ch4_48kHz32bitFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    4,
> +    48000,
> +    384000,
> +    8,
> +    32,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {32},
> +  KSAUDIO_SPEAKER_QUAD,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE NarrowbandFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    1,
> +    8000,
> +    16000,
> +    2,
> +    16,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {16},
> +  KSAUDIO_SPEAKER_MONO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE WidebandFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    1,
> +    16000,
> +    32000,
> +    2,
> +    16,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {16},
> +  KSAUDIO_SPEAKER_MONO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST WAVEFORMATEXTENSIBLE A2dpFormat =
> +{
> +  {
> +    WAVE_FORMAT_EXTENSIBLE,
> +    2,
> +    48000,
> +    384000,
> +    8,
> +    32,
> +    sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX)
> +  },
> +  {24},
> +  KSAUDIO_SPEAKER_STEREO,
> +  KSDATAFORMAT_SUBTYPE_PCM
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointDmicX1 = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkDmic,   // LinkType
> +  0,                 // InstanceId
> +  0x8086,            // HwVendorId
> +  0xae20,            // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceDmic, // DeviceType
> +  1,                 // Direction
> +  0,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointDmicX2 = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkDmic,   // LinkType
> +  0,                 // InstanceId
> +  0x8086,           // HwVendorId
> +  0xae20,           // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceDmic, // DeviceType
> +  1,                 // Direction
> +  0,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointDmicX4 = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkDmic,   // LinkType
> +  0,                 // InstanceId
> +  0x8086,           // HwVendorId
> +  0xae20,           // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceDmic, // DeviceType
> +  1,                 // Direction
> +  0,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointBtRender = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkSsp,    // LinkType
> +  0,                 // InstanceId
> +  0x8086,           // HwVendorId
> +  0xae30,           // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceBt,   // DeviceType
> +  0,                 // Direction
> +  2,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointBtCapture = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkSsp,    // LinkType
> +  0,                 // InstanceId
> +  0x8086,           // HwVendorId
> +  0xae30,           // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceBt,   // DeviceType
> +  1,                 // Direction
> +  2,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointI2sRender = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkSsp,    // LinkType
> +  1,                 // InstanceId
> +  0x8086,           // HwVendorId
> +  0xae34,           // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceI2s,  // DeviceType
> +  0,                 // Direction
> +  0,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +ENDPOINT_DESCRIPTOR  HdaEndpointI2sCapture = {
> +  0,                 // EndpointDescriptorLength
> +  HdaNhltLinkSsp,    // LinkType
> +  1,                 // InstanceId
> +  0x8086,           // HwVendorId
> +  0xae34,           // HwDeviceId
> +  1,                 // HwRevisionId
> +  1,                 // HwSubsystemId
> +  HdaNhltDeviceI2s,  // DeviceType
> +  1,                 // Direction
> +  0,                 // VirtualBusId
> +  { 0 },             // EndpointConfig
> +  { 0 },             // FormatsConfig
> +  { 0 }              // DevicesInformation
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX1Config[] =
> +{
> +  0x00, // VirtualSlot
> +  0x00, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX1ConfigSize =
> sizeof (DmicX1Config);
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX2Config[] =
> +{
> +  0x00, // VirtualSlot
> +  0x01, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
> +  0x0A  // ArrayType
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX2ConfigSize =
> sizeof (DmicX2Config);
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DmicX4Config[] =
> +{
> +  0x00, // VirtualSlot
> +  0x01, // eIntcConfigTypeMicArray = 1 , eIntcConfigTypeGeneric = 0
> +  0x0D  // ArrayType
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 DmicX4ConfigSize =
> sizeof (DmicX4Config);
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  BtConfig[] = {0};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 BtConfigSize = 0;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sRender1Config[] =
> {0};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRender1ConfigSize =
> 0;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sRender2Config[] =
> {0x01};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sRender2ConfigSize =
> sizeof (I2sRender2Config);
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  I2sCaptureConfig[] =
> {0};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 I2sCaptureConfigSize =
> 0;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST DEVICE_INFO
> I2sRenderDeviceInfo =
> +{
> +  "INT34C2", // DeviceId
> +  0x00,      // DeviceInstanceId
> +  0x01       // DevicePortId
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST DEVICE_INFO
> I2sCaptureDeviceInfo =
> +{
> +  "INT34C2", // DeviceId
> +  0x00,      // DeviceInstanceId
> +  0x01       // DevicePortId
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 NhltConfiguration[] =
> { 0xEFBEADDE };
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 NhltConfigurationSize
> = sizeof (NhltConfiguration);
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daLib.c
> new file mode 100644
> index 0000000000..a87509de1b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daLib.c
> @@ -0,0 +1,886 @@
> +/** @file
> +  PCH HD Audio Library implementation.
> +
> +  Copyright (c) 2019 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 <Private/Library/PchHdaLib.h>
> +#include <Library/PchInfoLib.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               i;
> +  ENDPOINT_DESCRIPTOR *Endpoint;
> +  Endpoint = (ENDPOINT_DESCRIPTOR*) (NhltTable->EndpointDescriptors);
> +
> +  if (EndpointIndex > NhltTable->EndpointCount) {
> +    return NULL;
> +  }
> +
> +  for (i = 0; i < EndpointIndex; i++) {
> +    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          i;
> +  UINT32         Length;
> +  FORMATS_CONFIG *FormatsConfig;
> +  FORMAT_CONFIG  *Format;
> +
> +  Length = 0;
> +  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
> +  Format = FormatsConfig->FormatsConfiguration;
> +
> +  if (FormatIndex > FormatsConfig->FormatsCount) {
> +    return NULL;
> +  }
> +
> +  for (i = 0; i < FormatIndex; i++) {
> +    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) {
> +    return NULL;
> +  }
> +
> +  if (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 i;
> +
> +  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 (i = 0; i < (  Format->FormatConfiguration.CapabilitiesSize ) ; i++) {
> +    if (i % 16 == 0) {
> +      DEBUG ((DEBUG_VERBOSE, "\n"));
> +    }
> +    DEBUG ((DEBUG_VERBOSE, "0x%02x, ",
> Format->FormatConfiguration.Capabilities[i]));
> +  }
> +  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 i;
> +  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 (i = 0; i < (Endpoint->EndpointConfig.CapabilitiesSize ) ; i++) {
> +    if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
> +    DEBUG ((DEBUG_VERBOSE, "0x%02x, ",
> Endpoint->EndpointConfig.Capabilities[i]));
> +  }
> +
> +  FormatsConfigs = GetNhltEndpointFormatsConfig (Endpoint);
> +
> +  DEBUG ((DEBUG_INFO, "\n"));
> +  DEBUG ((DEBUG_INFO, " Endpoint->FormatsConfig.FormatsCount = %d\n",
> FormatsConfigs->FormatsCount));
> +  for (i = 0; i < FormatsConfigs->FormatsCount; i++) {
> +    Format = GetNhltEndpointFormat (Endpoint, i);
> +    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 (i = 0; i < DevicesInfo->DeviceInfoCount; i++) {
> +      DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, i);
> +      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 i;
> +
> +  DEBUG ((DEBUG_INFO, "-------------------------- OED CONFIGURATION
> -------------------------\n"));
> +  DEBUG ((DEBUG_INFO, " OedConfig->CapabilitiesSize = %d B\n",
> OedConfig->CapabilitiesSize));
> +  DEBUG ((DEBUG_VERBOSE, " OedConfig->Capabilities:"));
> +  for (i = 0; i < (OedConfig->CapabilitiesSize) ; i++) {
> +    if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
> +    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", OedConfig->Capabilities[i]));
> +  }
> +
> +  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 i;
> +
> +  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 (i = 0; i < NhltTable->EndpointCount; i++) {
> +    NhltEndpointDump (GetNhltEndpoint (NhltTable, i));
> +  }
> +
> +  NhltOedConfigDump (GetNhltOedConfig (NhltTable));
> +  DEBUG ((DEBUG_INFO,
> "----------------------------------------------------------------------\n"));
> +
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Constructs FORMATS_CONFIGS structure based on given formats list.
> +
> +  @param[in][out] *Endpoint     Endpoint for which format structures are
> created
> +  @param[in]      FormatBitmask Bitmask of formats supported for given
> endpoint
> +
> +  @retval                       Size of created FORMATS_CONFIGS structure
> +**/
> +UINT32
> +NhltFormatsConstructor (
> +  IN OUT ENDPOINT_DESCRIPTOR    *Endpoint,
> +  IN CONST UINT32               FormatsBitmask
> +  )
> +{
> +  FORMATS_CONFIG *FormatsConfig;
> +  FORMAT_CONFIG  *Format;
> +  UINT8          FormatIndex;
> +  UINT32         FormatsConfigLength;
> +
> +  DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() Start, FormatsBitmask =
> 0x%08x\n", FormatsBitmask));
> +
> +  FormatsConfig = NULL;
> +  FormatIndex = 0;
> +  FormatsConfigLength = 0;
> +
> +  if (!FormatsBitmask) {
> +    DEBUG ((DEBUG_WARN, "No supported format found!\n"));
> +    return 0;
> +  }
> +
> +  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
> +  FormatsConfig->FormatsCount = 0;
> +
> +  if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch2_48kHz16bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +      Format->FormatConfiguration.CapabilitiesSize =
> DmicStereo16BitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> DmicStereo16BitFormatConfig, DmicStereo16BitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch2_48kHz32bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize =
> DmicStereo32BitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> DmicStereo32BitFormatConfig, DmicStereo32BitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch4_48kHz16bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +      Format->FormatConfiguration.CapabilitiesSize =
> DmicQuad16BitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> DmicQuad16BitFormatConfig, DmicQuad16BitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch4_48kHz32bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize =
> DmicQuad32BitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> DmicQuad32BitFormatConfig, DmicQuad32BitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch1_48kHz16bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize =
> DmicMono16BitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> DmicMono16BitFormatConfig, DmicMono16BitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_BT_NARROWBAND_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_BT_NARROWBAND_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &NarrowbandFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig,
> BtFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_BT_WIDEBAND_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_WIDEBAND_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &WidebandFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig,
> BtFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask & B_HDA_BT_A2DP_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_A2DP_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &A2dpFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig,
> BtFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask &
> B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize =
> I2sRtk274Render4ch48kHz24bitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> I2sRtk274Render4ch48kHz24bitFormatConfig,
> I2sRtk274Render4ch48kHz24bitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  if (FormatsBitmask &
> B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT) {
> +    DEBUG ((DEBUG_INFO, "Format:
> B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT\n"));
> +
> +    Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
> +    if (Format != NULL) {
> +      CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof
> (WAVEFORMATEXTENSIBLE));
> +
> +      Format->FormatConfiguration.CapabilitiesSize =
> I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
> +      CopyMem (Format->FormatConfiguration.Capabilities,
> I2sRtk274Capture4ch48kHz24bitFormatConfig,
> I2sRtk274Capture4ch48kHz24bitFormatConfigSize);
> +
> +      FormatsConfigLength += sizeof (*Format)
> +        - sizeof (Format->FormatConfiguration.Capabilities)
> +        + Format->FormatConfiguration.CapabilitiesSize;
> +      FormatsConfig->FormatsCount++;
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() End, FormatsCount = %d,
> FormatsConfigLength = %d B\n", FormatsConfig->FormatsCount,
> FormatsConfigLength));
> +  return FormatsConfigLength;
> +}
> +
> +/**
> +  Constructs DEVICES_INFO structure based on given device info list.
> +
> +  @param[in][out] *Endpoint      Endpoint for which device info structures
> are created
> +  @param[in]      DevicesBitmask Bitmask of devices supported for given
> endpoint
> +
> +  @retval                        Size of created DEVICES_INFO structure
> +**/
> +UINT32
> +NhltDevicesInfoConstructor (
> +  IN OUT   ENDPOINT_DESCRIPTOR  *Endpoint,
> +  IN CONST UINT32               DevicesBitmask
> +  )
> +{
> +  DEVICES_INFO  *DevicesInfo;
> +  DEVICE_INFO   *DeviceInfo;
> +  UINT8         DeviceIndex;
> +  UINT32        DevicesInfoLength;
> +
> +  DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() Start,
> DevicesBitmask = 0x%08x\n", DevicesBitmask));
> +
> +  DevicesInfo = NULL;
> +  DeviceIndex = 0;
> +  DevicesInfoLength = 0;
> +
> +  if (!DevicesBitmask) {
> +    return 0;
> +  }
> +
> +  DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
> +  if (DevicesInfo == NULL) {
> +    return 0;
> +  }
> +  DevicesInfo->DeviceInfoCount = 0;
> +
> +  if (DevicesBitmask & B_HDA_I2S_RENDER_DEVICE_INFO) {
> +    DEBUG ((DEBUG_INFO, "DeviceInfo:
> B_HDA_I2S_RENDER_DEVICE_INFO\n"));
> +
> +    DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
> +    if (DeviceInfo != NULL) {
> +      CopyMem (DeviceInfo, &I2sRenderDeviceInfo, sizeof (DEVICE_INFO));
> +      DevicesInfo->DeviceInfoCount++;
> +    }
> +  } else if (DevicesBitmask & B_HDA_I2S_CAPTURE_DEVICE_INFO) {
> +    DEBUG ((DEBUG_INFO, "DeviceInfo:
> B_HDA_I2S_CAPTURE_DEVICE_INFO\n"));
> +
> +    DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
> +    if (DeviceInfo != NULL) {
> +      CopyMem (DeviceInfo, &I2sCaptureDeviceInfo, sizeof (DEVICE_INFO));
> +      DevicesInfo->DeviceInfoCount++;
> +    }
> +  }
> +
> +  DevicesInfoLength = DevicesInfo->DeviceInfoCount * sizeof (DEVICE_INFO);
> +
> +  DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() End, DevicesCount =
> %d, DevicesInfoLength = %d B\n", DevicesInfo->DeviceInfoCount,
> DevicesInfoLength));
> +  return DevicesInfoLength;
> +}
> +
> +/**
> +  Constructs NHLT_ENDPOINT structure based on given endpoint type.
> +
> +  @param[in][out] *NhltTable              NHLT table for which endpoint is
> created
> +  @param[in]      EndpointType            Type of endpoint to be created
> +  @param[in]      EndpointFormatsBitmask  Bitmask of formats supported
> by endpoint
> +  @param[in]      EndpointDevicesBitmask  Bitmask of device info for
> endpoint
> +  @param[in]      EndpointIndex           Endpoint index in NHLT table
> +
> +  @retval                       Size of created NHLT_ENDPOINT structure
> +**/
> +UINT32
> +NhltEndpointConstructor (
> +  IN OUT NHLT_ACPI_TABLE        *NhltTable,
> +  IN NHLT_ENDPOINT              EndpointType,
> +  IN UINT32                     EndpointFormatsBitmask,
> +  IN UINT32                     EndpointDevicesBitmask,
> +  IN UINT8                      EndpointIndex
> +  )
> +{
> +
> +  ENDPOINT_DESCRIPTOR *Endpoint;
> +  SPECIFIC_CONFIG     *EndpointConfig;
> +  CONST UINT8         *EndpointConfigBuffer;
> +  UINT32              EndpointConfigBufferSize;
> +  UINT32              EndpointDescriptorLength;
> +
> +  DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() Start, EndpointIndex =
> %d\n", EndpointIndex));
> +
> +  EndpointDescriptorLength = 0;
> +  Endpoint = GetNhltEndpoint (NhltTable, EndpointIndex);
> +  if (Endpoint == NULL) {
> +    return 0;
> +  }
> +  EndpointDescriptorLength = sizeof (ENDPOINT_DESCRIPTOR)
> +    - sizeof (SPECIFIC_CONFIG)
> +    - sizeof (FORMAT_CONFIG)
> +    - sizeof (DEVICE_INFO);
> +
> +  switch (EndpointType) {
> +    case HdaDmicX1:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX1\n"));
> +      CopyMem (Endpoint, &HdaEndpointDmicX1, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      EndpointConfigBuffer = DmicX1Config;
> +      EndpointConfigBufferSize = DmicX1ConfigSize;
> +      break;
> +    case HdaDmicX2:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX2\n"));
> +      CopyMem (Endpoint, &HdaEndpointDmicX2, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      EndpointConfigBuffer = DmicX2Config;
> +      EndpointConfigBufferSize = DmicX2ConfigSize;
> +      break;
> +    case HdaDmicX4:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX4\n"));
> +      CopyMem (Endpoint, &HdaEndpointDmicX4, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      EndpointConfigBuffer = DmicX4Config;
> +      EndpointConfigBufferSize = DmicX4ConfigSize;
> +      break;
> +    case HdaBtRender:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaBtRender\n"));
> +      CopyMem (Endpoint, &HdaEndpointBtRender, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      if (IsPchH ()) {
> +        Endpoint->VirtualBusId = 0;
> +      }
> +
> +      EndpointConfigBuffer = BtConfig;
> +      EndpointConfigBufferSize = BtConfigSize;
> +      break;
> +    case HdaBtCapture:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaBtCapture\n"));
> +      CopyMem (Endpoint, &HdaEndpointBtCapture, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      if (IsPchH ()) {
> +        Endpoint->VirtualBusId = 0;
> +      }
> +
> +      EndpointConfigBuffer = BtConfig;
> +      EndpointConfigBufferSize = BtConfigSize;
> +      break;
> +    case HdaI2sRender1:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender1\n"));
> +      CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      EndpointConfigBuffer = I2sRender1Config;
> +      EndpointConfigBufferSize = I2sRender1ConfigSize;
> +      break;
> +    case HdaI2sRender2:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender2\n"));
> +      CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      EndpointConfigBuffer = I2sRender2Config;
> +      EndpointConfigBufferSize = I2sRender2ConfigSize;
> +      break;
> +    case HdaI2sCapture:
> +      DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sCapture\n"));
> +      CopyMem (Endpoint, &HdaEndpointI2sCapture, sizeof
> (ENDPOINT_DESCRIPTOR));
> +      EndpointConfigBuffer = I2sCaptureConfig;
> +      EndpointConfigBufferSize = I2sCaptureConfigSize;
> +      break;
> +    default:
> +      DEBUG ((DEBUG_WARN, "Unknown endpoint!\n"));
> +      return 0;
> +  }
> +
> +  EndpointConfig = GetNhltEndpointDeviceCapabilities (Endpoint);
> +  EndpointConfig->CapabilitiesSize = EndpointConfigBufferSize;
> +  CopyMem (EndpointConfig->Capabilities, EndpointConfigBuffer,
> EndpointConfig->CapabilitiesSize);
> +  EndpointDescriptorLength += sizeof (*EndpointConfig)
> +    - sizeof (EndpointConfig->Capabilities)
> +    + EndpointConfig->CapabilitiesSize;
> +
> +  EndpointDescriptorLength += NhltFormatsConstructor (Endpoint,
> EndpointFormatsBitmask);
> +  EndpointDescriptorLength += NhltDevicesInfoConstructor (Endpoint,
> EndpointDevicesBitmask);
> +
> +  Endpoint->EndpointDescriptorLength = EndpointDescriptorLength;
> +
> +  DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() End,
> EndpointDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
> +  return Endpoint->EndpointDescriptorLength;
> +}
> +
> +/**
> +  Constructs SPECIFIC_CONFIG structure for OED configuration.
> +
> +  @param[in][out] *NhltTable    NHLT table for which OED config is created
> +
> +  @retval                       Size of created SPECIFIC_CONFIG structure
> +**/
> +UINT32
> +NhltOedConfigConstructor (
> +  IN OUT NHLT_ACPI_TABLE        *NhltTable
> +  )
> +{
> +  SPECIFIC_CONFIG *OedConfig;
> +  UINT32          OedConfigLength;
> +
> +  OedConfigLength = 0;
> +  OedConfig = GetNhltOedConfig (NhltTable);
> +
> +  OedConfig->CapabilitiesSize = NhltConfigurationSize;
> +  CopyMem (OedConfig->Capabilities, (UINT8*) NhltConfiguration,
> NhltConfigurationSize);
> +
> +  OedConfigLength = sizeof (*OedConfig)
> +    - sizeof (OedConfig->Capabilities)
> +    + OedConfig->CapabilitiesSize;
> +
> +  return OedConfigLength;
> +}
> +
> +/**
> +  Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
> +
> +  @param[in]      *EndpointTable List of endpoints for NHLT
> +  @param[in][out] **NhltTable    NHLT table to be created
> +  @param[in][out] *NhltTableSize Size of created NHLT table
> +
> +  @retval EFI_SUCCESS            NHLT created successfully
> +  @retval EFI_BAD_BUFFER_SIZE    Not enough resources to allocate NHLT
> +**/
> +EFI_STATUS
> +NhltConstructor (
> +  IN PCH_HDA_NHLT_ENDPOINTS     *EndpointTable,
> +  IN OUT NHLT_ACPI_TABLE        **NhltTable,
> +  IN OUT UINT32                 *NhltTableSize
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT8  Index;
> +  UINT32 TableSize;
> +  UINT32 EndpointDescriptorsLength;
> +  UINT32 OedConfigLength;
> +  NHLT_ACPI_TABLE *Table;
> +
> +
> +  Status = EFI_SUCCESS;
> +  TableSize = PCH_HDA_NHLT_TABLE_SIZE;
> +  EndpointDescriptorsLength = 0;
> +  OedConfigLength = 0;
> +
> +  Table = AllocateZeroPool (TableSize);
> +
> +  if (Table == NULL) {
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  Table->EndpointCount = 0;
> +
> +  for (Index = 0; Index < HdaEndpointMax; Index++) {
> +    if (EndpointTable[Index].Enable == TRUE) {
> +      EndpointDescriptorsLength += NhltEndpointConstructor (Table,
> +                                     EndpointTable[Index].EndpointType,
> +                                     EndpointTable[Index].EndpointFormatsBitmask,
> +                                     EndpointTable[Index].EndpointDevicesBitmask,
> +                                     Table->EndpointCount++);
> +    }
> +  }
> +  DEBUG ((DEBUG_INFO, "NhltConstructor: EndpointCount = %d, All
> EndpointDescriptorsLength = %d B\n", Table->EndpointCount,
> EndpointDescriptorsLength));
> +
> +  OedConfigLength = NhltOedConfigConstructor (Table);
> +  DEBUG ((DEBUG_INFO, "NhltConstructor: OedConfigLength = %d B\n",
> OedConfigLength));
> +
> +  TableSize = EndpointDescriptorsLength + OedConfigLength;
> +
> +  *NhltTableSize = TableSize;
> +  *NhltTable = Table;
> +
> +  return Status;
> +}
> +
> +/**
> +  Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
> +
> +  @param[in][out] *NhltTable            NHLT table for which header will be
> created
> +  @param[in]      NhltTableSize         Size of NHLT table
> +
> +  @retval None
> +**/
> +VOID
> +NhltAcpiHeaderConstructor (
> +  IN OUT NHLT_ACPI_TABLE        *NhltTable,
> +  IN UINT32                     NhltTableSize
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor() Start\n"));
> +
> +  // Header
> +  NhltTable->Header.Signature = NHLT_ACPI_TABLE_SIGNATURE;
> +  NhltTable->Header.Length = (UINT32) (NhltTableSize + sizeof
> (NHLT_ACPI_TABLE) - sizeof (ENDPOINT_DESCRIPTOR) - sizeof
> (SPECIFIC_CONFIG));
> +  NhltTable->Header.Revision = 0x0;
> +  NhltTable->Header.Checksum = 0x0;
> +
> +  CopyMem (NhltTable->Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId),
> sizeof (NhltTable->Header.OemId));
> +  NhltTable->Header.OemTableId      = PcdGet64
> (PcdAcpiDefaultOemTableId);
> +  NhltTable->Header.OemRevision     = PcdGet32
> (PcdAcpiDefaultOemRevision);
> +  NhltTable->Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
> +  NhltTable->Header.CreatorRevision = PcdGet32
> (PcdAcpiDefaultCreatorRevision);
> +
> +  DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor(),
> NhltAcpiTable->Header.Length = %d B\n", NhltTable->Header.Length));
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daNhltConfig.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daNhltConfig.c
> new file mode 100644
> index 0000000000..301b1f8d10
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchH
> daNhltConfig.c
> @@ -0,0 +1,439 @@
> +/** @file
> +  This file contains HD Audio NHLT Configuration BLOBs
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// CFL NHLT Configuration BLOBs
> +//
> +
> +//
> +// DMIC Configuration BLOBs
> +//
> +// DMIC Config 2 channels, 16 bits, 2.4Mhz BCLK
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 DmicStereo16BitFormatConfig[] =
> +{
> +  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
> +  3,
> +  3,
> +  0x00300003,
> +  0x00300003,
> +  0x3,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> DmicStereo16BitFormatConfigSize = sizeof (DmicStereo16BitFormatConfig);
> +
> +// DMIC Config 2 channels, 32 bits, 2.4Mhz BCLK
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 DmicStereo32BitFormatConfig[] =
> +{
> +  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
> +  3,
> +  3,
> +  0x00380003,
> +  0x00380003,
> +  0x3,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> DmicStereo32BitFormatConfigSize = sizeof (DmicStereo32BitFormatConfig);
> +
> +// DMIC Config 4 channels, 16 bits, 2.4Mhz BCLK
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 DmicQuad16BitFormatConfig[] =
> +{
> +  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
> +  3,
> +  3,
> +  0x00320003,
> +  0x00320003,
> +  0x3,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> DmicQuad16BitFormatConfigSize = sizeof (DmicQuad16BitFormatConfig);
> +
> +// DMIC Config 4 channels, 32 bits, 2.4Mhz BCLK
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 DmicQuad32BitFormatConfig[] =
> +{
> +  0x00000001,0xffff3210,0xffffff10,0xffffff32,0xffffffff,
> +  3,
> +  3,
> +  0x003A0003,
> +  0x003A0003,
> +  0x3,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
> +  0x1, 0x09001303, 0x0, 0x0303, 0, 0, 0, 0,
> +  0x11, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x11, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> DmicQuad32BitFormatConfigSize = sizeof (DmicQuad32BitFormatConfig);
> +
> +
> +// DMIC Config 1 channel, 16 bits
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 DmicMono16BitFormatConfig[] =
> +{
> +  0x00000000,
> +  0xfffffff0,0xfffffff0,0xfffffff0,0xfffffff0,
> +  3,
> +  3,
> +  0x00300003,
> +  0x00300003,
> +  0x3,
> +  0x0, 0x09001303, 0x0, 0x0301, 0, 0, 0, 0,
> +  0x10, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x10, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e,
> +  0x0, 0x09001303, 0x0, 0x0301, 0, 0, 0, 0,
> +  0x10, 0x402a0, 0, 0, 0, 0, 0, 0,
> +  0x10, 0xe03ae, 0, 0, 0, 0, 0, 0,
> +  0x00008, 0xfffae, 0xfff12, 0xffdfb, 0xffc61, 0xffa5a, 0xff82b, 0xff641, 0xff520,
> 0xff544, 0xff6f4, 0xffa25, 0xffe65,
> +  0x002e0, 0x0068f, 0x00876, 0x007f1, 0x004f5, 0x0002a, 0xffad4, 0xff68a,
> 0xff4bf, 0xff64f, 0xffb20,
> +  0x0020f, 0x00929, 0x00e2d, 0x00f40, 0x00b92, 0x003bf, 0xff9cd, 0xff0b0,
> 0xfeb6e, 0xfec2a, 0xff351,
> +  0xfff4f, 0x00ccd, 0x0179d, 0x01bfc, 0x017d7, 0x00ba3, 0xffa7e, 0xfe96f,
> 0xfddf5, 0xfdc4d, 0xfe5ee,
> +  0xff8ce, 0x00fb7, 0x023a8, 0x02df5, 0x02a74, 0x01910, 0xffe2c, 0xfe19c,
> 0xfcc64, 0xfc5ee, 0xfd17e,
> +  0xfecd4, 0x01071, 0x03198, 0x0457e, 0x044c9, 0x02e24, 0x00728, 0xfdb0e,
> 0xfb781, 0xfa86b, 0xfb408,
> +  0xfd884, 0x00c02, 0x03f37, 0x061e8, 0x06807, 0x04dc5, 0x01954, 0xfd98c,
> 0xfa1c8, 0xf840f, 0xf8b52,
> +  0xfb78c, 0xffd23, 0x047db, 0x080b1, 0x094e3, 0x07c08, 0x03b41, 0xfe45e,
> 0xf9101, 0xf5b1e, 0xf54f4,
> +  0xf8307, 0xfda0b, 0x0418f, 0x09ad0, 0x0c9d6, 0x0be16, 0x0780b, 0x009dd,
> 0xf92ba, 0xf3606, 0xf10ed,
> +  0xf315e, 0xf9135, 0x0172c, 0x09d83, 0x0fc9e, 0x11695, 0x0e05b, 0x065bf,
> 0xfc6ed, 0xf2ff4, 0xecc96,
> +  0xebbc9, 0xf0668, 0xf9be7, 0x05601, 0x1029e, 0x17140, 0x18065, 0x12728,
> 0x07874, 0xf9edb, 0xed202,
> +  0xe486c, 0xe294d, 0xe820f, 0xf424a, 0x03f29, 0x13d68, 0x1ff61, 0x253b2,
> 0x220fa, 0x16be1, 0x05638,
> +  0xf1798, 0xdf165, 0xd211a, 0xcd3f9, 0xd1eb5, 0xdfa89, 0xf4802, 0x0d656,
> 0x26d63, 0x3d808, 0x4ecc3,
> +  0x59315, 0x5c520, 0x58db6, 0x503d6, 0x444dd, 0x36ecb, 0x29b9a, 0x1de5d,
> 0x14234, 0x0cae0, 0x07669,
> +  0x03f40, 0x01e4e, 0x00c95, 0x0043b, 0x000f9,0xff961, 0x00823, 0x0084f,
> 0x00a39, 0x00d21, 0x010a8, 0x0149a, 0x018cc, 0x01d15, 0x0214d, 0x02543,
> 0x028c8, 0x02baa,
> +  0x02db8, 0x02ec6, 0x02eac, 0x02d4c, 0x02a90, 0x02672, 0x020f9, 0x01a3b,
> 0x0125c, 0x00994, 0x00025,
> +  0xff662, 0xfeca3, 0xfe34c, 0xfdabe, 0xfd364, 0xfcd94, 0xfc9a4, 0xfc7dd,
> 0xfc86b, 0xfcb6e, 0xfd0e6,
> +  0xfd8bb, 0xfe2b9, 0xfee8f, 0xffbd5, 0x00a0c, 0x018a3, 0x026fc, 0x03474,
> 0x04065, 0x04a36, 0x0515a,
> +  0x0555a, 0x055df, 0x052b2, 0x04bc3, 0x0412c, 0x03332, 0x02242, 0x00ef3,
> 0xff9fb, 0xfe430, 0xfce78,
> +  0xfb9c6, 0xfa70f, 0xf973a, 0xf8b1e, 0xf836e, 0xf80b7, 0xf8355, 0xf8b6e,
> 0xf98ea, 0xfab78, 0xfc288,
> +  0xfdd52, 0xffadf, 0x01a0a, 0x03992, 0x05823, 0x07465, 0x08d0c, 0x0a0e3,
> 0x0aedc, 0x0b61f, 0x0b614,
> +  0x0ae6b, 0x09f23, 0x0888d, 0x06b4c, 0x04850, 0x020d3, 0xff647, 0xfca4f,
> 0xf9eae, 0xf7533, 0xf4fa8,
> +  0xf2fc0, 0xf1702, 0xf06ba, 0xeffe6, 0xf032d, 0xf10d3, 0xf28b4, 0xf4a42,
> 0xf7486, 0xfa62a, 0xfdd81,
> +  0x01896, 0x0553d, 0x09128, 0x0c9fe, 0x0fd6f, 0x1294e, 0x14ba5, 0x162cb,
> 0x16d75, 0x16ac4, 0x15a52,
> +  0x13c38, 0x1110d, 0x0d9e9, 0x09856, 0x04e4a, 0xffe17, 0xfaa51, 0xf55c4,
> 0xf0350, 0xeb5d6, 0xe7020,
> +  0xe34c8, 0xe0620, 0xde61c, 0xdd64b, 0xdd7bd, 0xdeb03, 0xe102a, 0xe46b5,
> 0xe8dab, 0xee397, 0xf4699,
> +  0xfb479, 0x02ab3, 0x0a691, 0x1253c, 0x1a3d9, 0x21f98, 0x295cc, 0x30400,
> 0x36803, 0x3bff8, 0x40a63,
> +  0x44628, 0x4729b, 0x48f76, 0x49cd2, 0x49b35, 0x48b71, 0x46ea5, 0x44632,
> 0x413a6, 0x3d8b3, 0x3971b,
> +  0x350a6, 0x30716, 0x2bc15, 0x27131, 0x227cb, 0x1e11d, 0x19e2a, 0x15fc1,
> 0x1267c, 0x0f2c0, 0x0c4c2,
> +  0x09c8b, 0x079fb, 0x05cd2, 0x044b2, 0x0312d, 0x021c5, 0x015f4, 0x0135e
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> DmicMono16BitFormatConfigSize = sizeof (DmicMono16BitFormatConfig);
> +
> +//
> +// I2S/SSP Configuration BLOBs
> +// Audio Format and Configuration details
> +//
> +// Frequency: 48kHz, PCM resolution: 24 bits
> +// TDM slots: 4
> +// Codec: Realtek ALC274, mode: slave
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 I2sRtk274Render4ch48kHz24bitFormatConfig[]  = {0x0,
> 0xffffff10, 0xffffff32, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210, 0xffff3210,
> 0xffff3210, 0x83d00437, 0xc0700000, 0x0, 0x02010004, 0xf, 0xf, 0x4002, 0x4,
> 0x7070f00, 0x20, 0x00000001, 0x00000fff};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> I2sRtk274Render4ch48kHz24bitFormatConfigSize = sizeof
> (I2sRtk274Render4ch48kHz24bitFormatConfig);
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 I2sRtk274Capture4ch48kHz24bitFormatConfig[]  = {0x0,
> 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10, 0xffffff10,
> 0xffffff10, 0x83d00437, 0xc0700000, 0x0, 0x02010004, 0xf, 0xf, 0x4002, 0x4,
> 0x7070f00, 0x20, 0x00000001, 0x00000fff};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32
> I2sRtk274Capture4ch48kHz24bitFormatConfigSize = sizeof
> (I2sRtk274Capture4ch48kHz24bitFormatConfig);
> +
> +//
> +// BlueTooth Configuration BLOBs
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CONST UINT32 BtFormatConfig[] =
> +{
> +  0x0, 0xfffffff0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
> +  0x0, 0x80c0003f, 0xd3400000, 0x0, 0x02000005, 0x01, 0x01, 0x4002,
> +  0x0, 0x07020000, 0x0, 0x01, 0x0
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 BtFormatConfigSize =
> sizeof (BtFormatConfig);
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM private library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:14 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add
> SMM private library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH SMM private library class instances.
> 
> * SmmPchPrivateLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/Sm
> mPchPrivateLib.inf | 32 +++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/Sm
> mPchPrivateLib.c   | 58 ++++++++++++++++++++
>  2 files changed, 90 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/S
> mmPchPrivateLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/
> SmmPchPrivateLib.inf
> new file mode 100644
> index 0000000000..5cbad21fa5
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPriva
> +++ teLib/SmmPchPrivateLib.inf
> @@ -0,0 +1,32 @@
> +## @file
> +#  PCH SMM private lib.
> +#
> +# Copyright (c) 2019 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
> +CpuPlatformLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +SmmPchPrivateLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/S
> mmPchPrivateLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/
> SmmPchPrivateLib.c
> new file mode 100644
> index 0000000000..85a3086874
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPriva
> +++ teLib/SmmPchPrivateLib.c
> @@ -0,0 +1,58 @@
> +/** @file
> +  PCH SMM private lib.
> +
> +  Copyright (c) 2019 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/CpuPlatformLib.h>
> +#include <CpuRegs.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_ADDR, 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_ADDR, Data32 & (UINT32)
> +(~BIT0));
> +  ///
> +  /// Read FED30880h back to ensure the setting went through.
> +  ///
> +  Data32 = MmioRead32 (0xFED30880);
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:14 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent:
> Add library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds System Agent (SA) library class instances.
> 
> * DxeSaPolicyLib - DXE SA policy configuration services.
> * PeiDxeSmmSaPlatformLib - SA platform generation services.
> * PeiSaPolicyLib - PEI SA policy configuration services.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeS
> aPolicyLib.inf                 |  43 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatfor
> mLib/PeiDxeSmmSaPlatformLib.inf |  38 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSa
> PolicyLib.inf                 |  74 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeS
> aPolicyLibrary.h               |  37 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatfor
> mLib/SaPlatformLibrary.h        |  21 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcO
> emPlatform.h                   | 323 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSa
> PolicyLibrary.h               |  39 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeS
> aPolicyLib.c                   | 473 +++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatfor
> mLib/SaPlatformLibrary.c        | 128 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcO
> emPlatform.c                   | 745 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSa
> PolicyLib.c                   | 656 +++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSa
> PolicyLibSample.c             | 284 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPri
> ntPolicy.c                    | 559 +++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/
> MrcOemPlatform.S              | 114 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/
> MrcOemPlatform.asm            | 126 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/
> MrcOemPlatform.nasm           | 118 ++++
>  16 files changed, 3778 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLib.inf
> new file mode 100644
> index 0000000000..8a5092e199
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLib.inf
> @@ -0,0 +1,43 @@
> +## @file
> +# Component description file for the PeiSaPolicy library.
> +#
> +# Copyright (c) 2019 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
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +DxeSaPolicyLib.c
> +DxeSaPolicyLibrary.h
> +
> +[Guids]
> +gGraphicsDxeConfigGuid
> +gMiscDxeConfigGuid
> +gPcieDxeConfigGuid
> +gMemoryDxeConfigGuid
> +gVbiosDxeConfigGuid
> +
> +[Protocols]
> +gSaPolicyProtocolGuid ## PRODUCES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/PeiDxeSmmSaPlatformLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/PeiDxeSmmSaPlatformLib.inf
> new file mode 100644
> index 0000000000..ffc4043e7a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/PeiDxeSmmSaPlatformLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# Component description file for SA Platform Lib
> +#
> +# Copyright (c) 2019 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
> +CpuPlatformLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +
> +[Sources]
> +SaPlatformLibrary.h
> +SaPlatformLibrary.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLib.inf
> new file mode 100644
> index 0000000000..22d0f0c945
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLib.inf
> @@ -0,0 +1,74 @@
> +## @file
> +# Component description file for the PeiSaPolicy library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiSaPolicyLib
> +FILE_GUID = d7022865-ef1b-449d-8c3f-ac36488c408b
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = PeiSaPolicyLib
> +
> +
> +[LibraryClasses]
> +DebugLib
> +IoLib
> +PeiServicesLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +ConfigBlockLib
> +CpuMailboxLib
> +SiConfigBlockLib
> +RngLib
> +PmcPrivateLib
> +GpioLib
> +PchInfoLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +gSiPkgTokenSpaceGuid.PcdTsegSize
> +gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress
> +gSiPkgTokenSpaceGuid.PcdIpuEnable                   ## CONSUMES
> +
> +[Sources]
> +PeiSaPolicyLib.c
> +PeiSaPolicyLibrary.h
> +MrcOemPlatform.c
> +MrcOemPlatform.h
> +SaPrintPolicy.c
> +PeiSaPolicyLibSample.c
> +
> +[Sources.IA32]
> +Ia32/MrcOemPlatform.nasm
> +Ia32/MrcOemPlatform.S
> +
> +[Ppis]
> +gSiPreMemPolicyPpiGuid        ## CONSUMES
> +gSiPolicyPpiGuid              ## CONSUMES
> +
> +[Guids]
> +gSaMiscPeiPreMemConfigGuid    ## PRODUCES
> +gSaMiscPeiConfigGuid          ## PRODUCES
> +gSaPciePeiPreMemConfigGuid    ## PRODUCES
> +gSaPciePeiConfigGuid          ## PRODUCES
> +gGraphicsPeiPreMemConfigGuid  ## CONSUMES
> +gGraphicsPeiConfigGuid        ## CONSUMES
> +gSwitchableGraphicsConfigGuid ## PRODUCES
> +gCpuTraceHubConfigGuid        ## PRODUCES
> +gMemoryConfigGuid             ## PRODUCES
> +gMemoryConfigNoCrcGuid        ## PRODUCES
> +gIpuPreMemConfigGuid          ## PRODUCES
> +gGnaConfigGuid                ## PRODUCES
> +gVtdConfigGuid                ## PRODUCES
> +gSaOverclockingPreMemConfigGuid ## PRODUCES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLibrary.h
> new file mode 100644
> index 0000000000..449b67798c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLibrary.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  Header file for the DxeSaPolicy library.
> +
> +  Copyright (c) 2019 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 <Base.h>
> +#include <ConfigBlock.h>
> +#include <Library/HobLib.h>
> +#include <MkhiMsgs.h>
> +
> +#include <Protocol/SaPolicy.h>
> +
> +#define WORD_FIELD_VALID_BIT  BIT15
> +///
> +/// 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/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/SaPlatformLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/SaPlatformLibrary.h
> new file mode 100644
> index 0000000000..07d4c6e666
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/SaPlatformLibrary.h
> @@ -0,0 +1,21 @@
> +/** @file
> +  Header file for SA Platform Lib implementation.
> +
> +  Copyright (c) 2019 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 <SaAccess.h>
> +#include <CpuAccess.h>
> +#include <Library/SaPlatformLib.h>
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Mrc
> OemPlatform.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Mr
> cOemPlatform.h
> new file mode 100644
> index 0000000000..61a6e2a691
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Mr
> cOemPlatform.h
> @@ -0,0 +1,323 @@
> +/** @file
> +  This file contains functions that read the SPD data for each DIMM slot over
> +  the SMBus interface.
> +  This file is SampleCode for Intel SA PEI Policy initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyLibrary.h"
> +#include "MrcInterface.h"
> +
> +#define RTC_INDEX_REGISTER        (0x70)
> +#define RTC_TARGET_REGISTER       (0x71)
> +
> +#define RTC_INDEX_MASK            (0x7F)
> +#define RTC_BANK_SIZE             (0x80)
> +
> +#define RTC_SECONDS               (0x00)
> +#define RTC_MINUTES               (0x02)
> +#define RTC_HOURS                 (0x04)
> +#define RTC_DAY_OF_MONTH          (0x07)
> +#define RTC_MONTH                 (0x08)
> +#define RTC_YEAR                  (0x09)
> +#define CMOS_REGA                 (0x0A)
> +#define CMOS_REGB                 (0x0B)
> +#define CMOS_REGC                 (0x0C)
> +#define CMOS_REGD                 (0x0D)
> +
> +#define RTC_UPDATE_IN_PROGRESS    (0x80)
> +#define RTC_HOLD                  (0x80)
> +#define RTC_MODE_24HOUR           (0x02)
> +#define RTC_CLOCK_DIVIDER         (0x20)
> +#define RTC_RATE_SELECT           (0x06)
> +
> +#define BCD2BINARY(A)             (((((A) >> 4) & 0xF) * 10) + ((A) & 0xF))
> +#define CENTURY_OFFSET            (2000)
> +
> +/**
> +  Read the SPD data over the SMBus, at the given SmBus SPD address and copy
> the data to the data structure.
> +  The SPD data locations read is controlled by the current boot mode.
> +
> +  @param[in] BootMode           - The current MRC boot mode.
> +  @param[in] Address            - SPD SmBus address offset.
> +  @param[in] Buffer             - Buffer that contains the data read from the
> SPD.
> +  @param[in] SpdDdr3Table       - Indicates which SPD bytes to read.
> +  @param[in] SpdDdr3TableSize   - Size of SpdDdr3Table in bytes.
> +  @param[in] SpdDdr4Table       - Indicates which SPD bytes to read.
> +  @param[in] SpdDdr4TableSize   - Size of SpdDdr4Table in bytes.
> +  @param[in] SpdLpddrTable      - Indicates which SPD bytes to read.
> +  @param[in] SpdLpddrTableSize  - Size of SpdLpddrTable in bytes.
> +
> +  @retval TRUE if the read is successful, otherwise FALSE on error.
> +**/
> +BOOLEAN
> +GetSpdData (
> +  IN SPD_BOOT_MODE BootMode,
> +  IN UINT8         Address,
> +  IN OUT   UINT8   *Buffer,
> +  IN UINT8         *SpdDdr3Table,
> +  IN UINT32        SpdDdr3TableSize,
> +  IN UINT8         *SpdDdr4Table,
> +  IN UINT32        SpdDdr4TableSize,
> +  IN UINT8         *SpdLpddrTable,
> +  IN UINT32        SpdLpddrTableSize
> +  );
> +
> +/**
> +  Output a string to the debug stream/device.
> +
> +  @param[in] String     - The string to output.
> +**/
> +VOID
> +SaDebugPrint (
> +  VOID   *String
> +  );
> +
> +/**
> +  Calculate the PCI device address for the given Bus/Device/Function/Offset.
> +
> +  @param[in] Bus      - PCI bus
> +  @param[in] Device   - PCI device
> +  @param[in] Function - PCI function
> +  @param[in] Offset   - Offset
> +
> +  @retval The PCI device address.
> +**/
> +UINT32
> +GetPciDeviceAddress (
> +  IN const UINT8 Bus,
> +  IN const UINT8 Device,
> +  IN const UINT8 Function,
> +  IN const UINT8 Offset
> +  );
> +
> +/**
> +  Calculate the PCIE device address for the given Bus/Device/Function/Offset.
> +
> +  @param[in] Bus      - PCI bus
> +  @param[in] Device   - PCI device
> +  @param[in] Function - PCI function
> +  @param[in] Offset   - Offset
> +
> +   The PCIE device address.
> +
> +  @retval The PCIe device address
> +**/
> +UINT32
> +GetPcieDeviceAddress (
> +  IN const UINT8 Bus,
> +  IN const UINT8 Device,
> +  IN const UINT8 Function,
> +  IN const UINT8 Offset
> +  );
> +
> +/**
> +  Read specific RTC/CMOS RAM
> +
> +  @param[in] Location        Point to RTC/CMOS RAM offset for read
> +
> +  @retval The data of specific location in RTC/CMOS RAM.
> +**/
> +UINT8
> +PeiRtcRead (
> +  IN const UINT8 Location
> +  );
> +
> +/**
> +  Returns the current time, as determined by reading the Real Time Clock (RTC)
> on the platform.
> +  Since RTC time is stored in BCD, convert each value to binary.
> +
> +  @param[out] Seconds       - The current second (0-59).
> +  @param[out] Minutes       - The current minute (0-59).
> +  @param[out] Hours         - The current hour (0-23).
> +  @param[out] DayOfMonth    - The current day of the month (1-31).
> +  @param[out] Month         - The current month (1-12).
> +  @param[out] Year          - The current year (2000-2099).
> +**/
> +VOID
> +GetRtcTime (
> +  OUT UINT8  *const Seconds,
> +  OUT UINT8  *const Minutes,
> +  OUT UINT8  *const Hours,
> +  OUT UINT8  *const DayOfMonth,
> +  OUT UINT8  *const Month,
> +  OUT UINT16 *const Year
> +  );
> +
> +/**
> +  Gets CPU current time.
> +
> +  @param[in] GlobalData - Pointer to global MRC data struct.
> +
> +  @retval The current CPU time in milliseconds.
> +**/
> +UINT64
> +GetCpuTime (
> +  IN VOID     *GlobalData
> +  );
> +
> +/**
> +  Sets the specified number of memory words, a word at a time, at the
> +  specified destination.
> +
> +  @param[in, out] Dest     - Destination pointer.
> +  @param[in]      NumWords - The number of dwords to set.
> +  @param[in]      Value    - The value to set.
> +
> +  @retval Pointer to the buffer.
> +**/
> +VOID *
> +SetMemWord (
> +  IN OUT VOID     *Dest,
> +  IN UINTN        NumWords,
> +  IN const UINT16 Value
> +  );
> +
> +/**
> +  Sets the specified number of memory dwords, a dword at a time, at the
> +  specified destination.
> +
> +  @param[in, out] Dest      - Destination pointer.
> +  @param[in]      NumDwords - The number of dwords to set.
> +  @param[in]      Value     - The value to set.
> +
> +  @retval Pointer to the buffer.
> +**/
> +VOID *
> +SetMemDword (
> +  IN OUT VOID     *Dest,
> +  IN UINT32       NumDwords,
> +  IN const UINT32 Value
> +  );
> +
> +/**
> +  Read 64 bits from the Memory Mapped I/O space.
> +  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +
> +  @param[in] Address - Memory mapped I/O address.
> +**/
> +UINT64
> +SaMmioRead64 (
> +  IN  UINTN Address
> +  );
> +
> +/**
> +  Write 64 bits to the Memory Mapped I/O space.
> +  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +
> +  @param[in] Address - Memory mapped I/O address.
> +  @param[in] Value   - The value to write.
> +**/
> +UINT64
> +SaMmioWrite64 (
> +  IN UINTN Address,
> +  IN UINT64 Value
> +  );
> +
> +/**
> +  Intel Silicon View Technology check point interface based on IO port reading
> +
> +  @param CheckPoint        Check point AH value.
> +                           AH = 0x10:  End of MRC State
> +                           AH = 0x20:  End of DXE State
> +                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
> +                           AH = 0x40:  After OS booting, need a timer SMI trigger to
> implement (TBD)
> +
> +  @param PortReading       IO port reading address used for breakpoints
> +**/
> +VOID
> +EFIAPI
> +IsvtCheckPoint (
> +  IN UINT32          CheckPoint,
> +  IN UINT32          PortReading
> +  );
> +
> +/**
> +  Gets the current memory voltage (VDD).
> +
> +  @param[in] GlobalData - Pointer to global MRC data struct.
> +  @param[in] DefaultVdd - Default Vdd for the given platform.
> +
> +  @retval The current memory voltage (VDD), in millivolts. 0 means platform
> default.
> +**/
> +UINT32
> +GetMemoryVdd (
> +  IN VOID     *GlobalData,
> +  IN UINT32   DefaultVdd
> +  );
> +
> +/**
> +  Sets the memory voltage (VDD) to the specified value.
> +
> +  @param[in] GlobalData - Pointer to global MRC data struct.
> +  @param[in] DefaultVdd - Default Vdd for the given platform.
> +  @param[in] Voltage    - The new memory voltage to set.
> +
> +  @retval The actual memory voltage (VDD), in millivolts, that is closest to
> what the caller passed in.
> +**/
> +UINT32
> +SetMemoryVdd (
> +  IN VOID     *GlobalData,
> +  IN UINT32   DefaultVdd,
> +  IN UINT32   Voltage
> +  );
> +
> +/**
> +  Check point that is called at various points in the MRC.
> +
> +  @param[in] GlobalData - MRC global data.
> +  @param[in] Command    - OEM command.
> +  @param[in] Pointer    - Command specific data.
> +
> +  @retval MrcStatus value.
> +**/
> +UINT32
> +CheckPoint (
> +  VOID   *GlobalData,
> +  UINT32 Command,
> +  VOID   *Pointer
> +  );
> +
> +/**
> +  Typically used to display to the I/O port 80h.
> +
> +  @param[in] GlobalData         - Mrc Global Data
> +  @param[in] DisplayDebugNumber - the number to display on port 80.
> +
> +  @retval Nothing.
> +**/
> +VOID
> +DebugHook (
> +  VOID          *GlobalData,
> +  UINT16        DisplayDebugNumber
> +  );
> +
> +/**
> +  Hook to take any action after returning from
> MrcStartMemoryConfiguration()
> +  and prior to taking any action regarding MrcStatus.  Pre-populated with
> issuing
> +  Intel Silicon View Technology (ISVT) checkpoint 0x01.
> +
> +  @param[in] GlobalData         - Mrc Global Data
> +  @param[in] MrcStatus          - Mrc status variable
> +**/
> +VOID
> +ReturnFromSmc (
> +  VOID          *GlobalData,
> +  UINT32        MrcStatus
> +  );
> +
> +/**
> +  Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
> +
> +  @param[in] PciEBaseAddress  - PCI express base address.
> +  @param[in] ResetValue       - desired value of DRAM_RESET#. 1 - reset
> deasserted, 0 - reset asserted.
> +**/
> +VOID
> +SaDramReset (
> +  IN UINT32 PciEBaseAddress,
> +  IN UINT32 ResetValue
> +  );
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLibrary.h
> new file mode 100644
> index 0000000000..124ca6a57f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLibrary.h
> @@ -0,0 +1,39 @@
> +/** @file
> +  Header file for the PeiSaPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SA_POLICY_LIBRARY_H_
> +#define _PEI_SA_POLICY_LIBRARY_H_
> +
> +#include <CpuRegs.h>
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/SmbusLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/SiConfigBlockLib.h>
> +
> +/**
> +  SaLoadSamplePolicyPreMem - Load some policy default for reference
> board.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer for SA config blocks
> +
> +**/
> +VOID
> +SaLoadSamplePolicyPreMem (
> +  IN VOID           *ConfigBlockTableAddress
> +  );
> +#endif // _PEI_SA_POLICY_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLib.c
> new file mode 100644
> index 0000000000..0e8d518fe7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/Dx
> eSaPolicyLib.c
> @@ -0,0 +1,473 @@
> +/** @file
> +  This file provide services for DXE phase policy default initialization
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "DxeSaPolicyLibrary.h"
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PCIE_ASPM_OVERRIDE_LIST
> mPcieAspmDevsOverride[] = {
> +  {0x8086, 0x108b, 0xff, 2, 2},           ///< Tekoa w/o iAMT
> +  {0x8086, 0x108c, 0x00, 0, 0},           ///< Tekoa A2
> +  {0x8086, 0x108c, 0xff, 2, 2},           ///< Tekoa others
> +  {0x8086, 0x109a, 0xff, 2, 2},           ///< Vidalia
> +  {0x8086, 0x4222, 0xff, 2, 3},           ///< 3945ABG
> +  {0x8086, 0x4227, 0xff, 2, 3},           ///< 3945ABG
> +  {0x8086, 0x4228, 0xff, 2, 3},           ///< 3945ABG
> +  ///
> +  /// Place structures for known bad OEM/IHV devices here
> +  ///
> +  {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}  ///< End of table
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PCIE_LTR_DEV_INFO
> mPcieLtrDevsOverride[] = {
> +  ///
> +  /// Place holder for PCIe devices with correct LTR requirements
> +  ///
> +  {SA_PCIE_DEV_END_OF_TABLE, 0, 0, 0, 0}  ///< End of table
> +};
> +
> +extern EFI_GUID gGraphicsDxeConfigGuid;
> +extern EFI_GUID gMemoryDxeConfigGuid;
> +extern EFI_GUID gMiscDxeConfigGuid;
> +extern EFI_GUID gPcieDxeConfigGuid;
> +extern EFI_GUID gVbiosDxeConfigGuid;
> +
> +/**
> +  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;
> +  GRAPHICS_DXE_CONFIG         *GraphicsDxeConfig;
> +  PCIE_DXE_CONFIG             *PcieDxeConfig;
> +  MISC_DXE_CONFIG             *MiscDxeConfig;
> +  MEMORY_DXE_CONFIG           *MemoryDxeConfig;
> +  VBIOS_DXE_CONFIG            *VbiosDxeConfig;
> +
> +  //
> +  // Get requisite IP Config Blocks which needs to be used here
> +  //
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gMiscDxeConfigGuid, (VOID
> *)&MiscDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID
> *)&PcieDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID
> *)&MemoryDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gVbiosDxeConfigGuid, (VOID
> *)&VbiosDxeConfig);
> +  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] :", SA_MC_MAX_SOCKETS));
> +  for (i = 0; i < SA_MC_MAX_SOCKETS; 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, "------------------------ SA_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, " PegAspmL0s[%d] :", SA_PEG_MAX_FUN));
> +  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
> +    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspmL0s[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"));
> +
> +  if (PcieDxeConfig->PcieAspmDevsOverride != NULL) {
> +    DEBUG ((DEBUG_INFO, "------------------------ PCIE_ASPM_OVERRIDE_LIST
> -----------------\n"));
> +    DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId RootApmcMask
> EndpointApmcMask\n"));
> +    i = 0;
> +    while ((PcieDxeConfig->PcieAspmDevsOverride[i].VendorId !=
> SA_PCIE_DEV_END_OF_TABLE) &&
> +           (i < MAX_PCIE_ASPM_OVERRIDE)) {
> +      DEBUG ((DEBUG_INFO, " %04x     %04x     %02x    %01x
> %01x\n",
> +              PcieDxeConfig->PcieAspmDevsOverride[i].VendorId,
> +              PcieDxeConfig->PcieAspmDevsOverride[i].DeviceId,
> +              PcieDxeConfig->PcieAspmDevsOverride[i].RevId,
> +              PcieDxeConfig->PcieAspmDevsOverride[i].RootApmcMask,
> +              PcieDxeConfig->PcieAspmDevsOverride[i].EndpointApmcMask));
> +      i++;
> +    }
> +    DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE
> -----------------------\n"));
> +  }
> +  if (PcieDxeConfig->PcieLtrDevsOverride != NULL) {
> +    DEBUG ((DEBUG_INFO, "------------------------ PCIE_LTR_DEV_INFO
> -----------------\n"));
> +    DEBUG ((DEBUG_INFO, " VendorId DeviceId RevId SnoopLatency
> NonSnoopLatency\n"));
> +    i = 0;
> +    while ((PcieDxeConfig->PcieLtrDevsOverride[i].VendorId !=
> SA_PCIE_DEV_END_OF_TABLE) &&
> +           (i < MAX_PCIE_LTR_OVERRIDE)) {
> +      DEBUG ((DEBUG_INFO, " %04x     %04x     %02x    %01x
> %01x\n",
> +              PcieDxeConfig->PcieLtrDevsOverride[i].VendorId,
> +              PcieDxeConfig->PcieLtrDevsOverride[i].DeviceId,
> +              PcieDxeConfig->PcieLtrDevsOverride[i].RevId,
> +              PcieDxeConfig->PcieLtrDevsOverride[i].SnoopLatency,
> +              PcieDxeConfig->PcieLtrDevsOverride[i].NonSnoopLatency));
> +      i++;
> +    }
> +    DEBUG ((DEBUG_INFO, "------------------------ END_OF_TABLE
> ----------------------\n"));
> +  }
> +
> +  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
> +    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrEnable            : %x\n", i,
> PcieDxeConfig->PegPwrOpt[i].LtrEnable));
> +    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxSnoopLatency   : %x\n", i,
> PcieDxeConfig->PegPwrOpt[i].LtrMaxSnoopLatency));
> +    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].ObffEnable           : %x\n", i,
> PcieDxeConfig->PegPwrOpt[i].ObffEnable));
> +    DEBUG ((DEBUG_INFO, " PegPwrOpt[%d].LtrMaxNoSnoopLatency : %x\n",
> i, PcieDxeConfig->PegPwrOpt[i].LtrMaxNoSnoopLatency));
> +  }
> +
> +
> +  if (VbiosDxeConfig != NULL) {
> +    DEBUG ((DEBUG_INFO, "------------------------ SA_SG_VBIOS_CONFIGURATION
> -----------------\n"));
> +    DEBUG ((DEBUG_INFO, " LoadVbios    : %x\n",
> VbiosDxeConfig->LoadVbios));
> +    DEBUG ((DEBUG_INFO, " ExecuteVbios : %x\n",
> VbiosDxeConfig->ExecuteVbios));
> +    DEBUG ((DEBUG_INFO, " VbiosSource  : %x\n",
> VbiosDxeConfig->VbiosSource));
> +  }
> +
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_CONFIGURATION
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " EnableAbove4GBMmio : %x\n",
> MiscDxeConfig->EnableAbove4GBMmio));
> +  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END
> -----------------\n"));
> +  DEBUG_CODE_END ();
> +
> +  return;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +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%
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LoadPcieDxeDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +  UINT8                  pegFn;
> +  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 (pegFn = 0; pegFn < SA_PEG_MAX_FUN; pegFn++) {
> +    PcieDxeConfig->PegAspm[pegFn]       = PcieAspmAutoConfig;
> +    PcieDxeConfig->PegAspmL0s[pegFn]    = 0;
> +  }
> +
> +  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;
> +  }
> +
> +  PcieDxeConfig->PcieAspmDevsOverride = mPcieAspmDevsOverride;
> +  PcieDxeConfig->PcieLtrDevsOverride = mPcieLtrDevsOverride;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LoadMiscDxeDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +  MISC_DXE_CONFIG        *MiscDxeConfig;
> +
> +  MiscDxeConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "MiscDxeConfig->Header.GuidHob.Name = %g\n",
> &MiscDxeConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "MiscDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> MiscDxeConfig->Header.GuidHob.Header.HobLength));
> +  ///
> +  /// RMRR Base and Limit Address for USB
> +  ///
> +  MiscDxeConfig->RmrrUsbBaseAddress = AllocateZeroPool (sizeof
> (EFI_PHYSICAL_ADDRESS) * 2);
> +  ASSERT (MiscDxeConfig->RmrrUsbBaseAddress != NULL);
> +  if (MiscDxeConfig->RmrrUsbBaseAddress != NULL) {
> +    ///
> +    /// BIOS must update USB RMRR base address
> +    ///
> +    MiscDxeConfig->RmrrUsbBaseAddress[0] = 0;
> +    MiscDxeConfig->RmrrUsbBaseAddress[1] = 0;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +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;
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +LoadVbiosDxeDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +  VBIOS_DXE_CONFIG        *VbiosDxeConfig;
> +
> +  VbiosDxeConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "VbiosDxeConfig->Header.GuidHob.Name = %g\n",
> &VbiosDxeConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "VbiosDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> VbiosDxeConfig->Header.GuidHob.Header.HobLength));
> +  ///
> +  /// Initialize the SG VBIOS DXE Policies
> +  ///
> +  ///
> +  /// 1 = secondary display device VBIOS Source is PCI Card
> +  /// 0 = secondary display device VBIOS Source is FW Volume
> +  ///
> +  VbiosDxeConfig->VbiosSource = 1;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  LoadSaDxeConfigBlockDefault - Initialize default settings for each SA Config
> block
> +
> +  @param[in] ConfigBlockPointer         The buffer pointer that will be
> initialized as specific config block
> +  @param[in] BlockId                    Request to initialize defaults of specified
> config block by given Block ID
> +
> +  @retval EFI_SUCCESS                   The given buffer has contained the
> defaults of requested config block
> +  @retval EFI_NOT_FOUND                 Block ID is not defined so no default
> Config block will be initialized
> +**/
> +EFI_STATUS
> +EFIAPI
> +LoadSaDxeConfigBlockDefault (
> +  IN   VOID          *ConfigBlockPointer,
> +  IN   EFI_GUID      BlockGuid
> +  )
> +{
> +  if (CompareGuid (&BlockGuid, &gGraphicsDxeConfigGuid)) {
> +    LoadIgdDxeDefault (ConfigBlockPointer);
> +  } else if (CompareGuid (&BlockGuid, &gMiscDxeConfigGuid)) {
> +    LoadMiscDxeDefault (ConfigBlockPointer);
> +  } else if (CompareGuid (&BlockGuid, &gPcieDxeConfigGuid)) {
> +    LoadPcieDxeDefault (ConfigBlockPointer);
> +  } else if (CompareGuid (&BlockGuid, &gMemoryDxeConfigGuid)) {
> +    LoadMemoryDxeDefault (ConfigBlockPointer);
> +  } else if (CompareGuid (&BlockGuid, &gVbiosDxeConfigGuid)) {
> +    LoadVbiosDxeDefault (ConfigBlockPointer);
> +  } else {
> +    return EFI_NOT_FOUND;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  CreateSaDxeConfigBlocks generates the config blocksg 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;
> +  UINT16                            TotalBlockCount;
> +  UINT16                            BlockCount;
> +  VOID                              *ConfigBlockPointer;
> +  EFI_STATUS                        Status;
> +  SA_POLICY_PROTOCOL                *SaInitPolicy;
> +  UINT16                            RequiredSize;
> +  STATIC CONFIG_BLOCK_HEADER        SaDxeIpBlocks [] = {
> +       {{{0, sizeof (GRAPHICS_DXE_CONFIG),    0},  {0}},
> GRAPHICS_DXE_CONFIG_REVISION,           0, {0, 0}},
> +       {{{0, sizeof (MEMORY_DXE_CONFIG), 0},  {0}},
> MEMORY_DXE_CONFIG_REVISION,        0, {0, 0}},
> +       {{{0, sizeof (MISC_DXE_CONFIG),   0},  {0}},
> MISC_DXE_CONFIG_REVISION,          0, {0, 0}},
> +       {{{0, sizeof (PCIE_DXE_CONFIG),   0},  {0}},
> PCIE_DXE_CONFIG_REVISION,          0, {0, 0}},
> +       {{{0, sizeof (VBIOS_DXE_CONFIG),  0},  {0}},
> VBIOS_DXE_CONFIG_REVISION,         0, {0, 0}}
> +  };
> +
> +  SaInitPolicy = NULL;
> +  TotalBlockCount = sizeof (SaDxeIpBlocks) / sizeof (CONFIG_BLOCK_HEADER);
> +  DEBUG ((DEBUG_INFO, "TotalBlockCount = 0x%x\n", TotalBlockCount));
> +
> +  TotalBlockSize = 0;
> +  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
> +    TotalBlockSize += (UINT32)
> SaDxeIpBlocks[BlockCount].GuidHob.Header.HobLength;
> +    DEBUG ((DEBUG_INFO, "TotalBlockSize after adding  Block[0x%x]=
> 0x%x\n", BlockCount, TotalBlockSize));
> +  }
> +
> +  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
> +
> +  Status = CreateConfigBlockTable (RequiredSize, (VOID *)&SaInitPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Initalize SklSaIpBlocks table GUID
> +  //
> +  CopyMem (&SaDxeIpBlocks[0].GuidHob.Name,  &gGraphicsDxeConfigGuid,
> sizeof (EFI_GUID));
> +  CopyMem (&SaDxeIpBlocks[1].GuidHob.Name,  &gMemoryDxeConfigGuid,
> sizeof (EFI_GUID));
> +  CopyMem (&SaDxeIpBlocks[2].GuidHob.Name,  &gMiscDxeConfigGuid,
> sizeof (EFI_GUID));
> +  CopyMem (&SaDxeIpBlocks[3].GuidHob.Name,  &gPcieDxeConfigGuid,
> sizeof (EFI_GUID));
> +  CopyMem (&SaDxeIpBlocks[4].GuidHob.Name,  &gVbiosDxeConfigGuid,
> sizeof (EFI_GUID));
> +
> +  //
> +  // Initialize Policy Revision
> +  //
> +  SaInitPolicy->TableHeader.Header.Revision =
> SA_POLICY_PROTOCOL_REVISION;
> +  //
> +  // Initialize ConfigBlockPointer to NULL
> +  //
> +  ConfigBlockPointer = NULL;
> +  //
> +  // Loop to identify each config block from SaDxeIpBlocks[] Table and add
> each of them
> +  //
> +  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
> +    ConfigBlockPointer = (VOID *)&SaDxeIpBlocks[BlockCount];
> +    Status = AddConfigBlock ((VOID *) SaInitPolicy, (VOID
> *)&ConfigBlockPointer);
> +    ASSERT_EFI_ERROR (Status);
> +    LoadSaDxeConfigBlockDefault ((VOID *) ConfigBlockPointer,
> SaDxeIpBlocks[BlockCount].GuidHob.Name);
> +  }
> +  //
> +  // Assignment for returning SaPolicy config block base address
> +  //
> +  *SaPolicy = SaInitPolicy;
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  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);
> +
> +  ///
> +  /// 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/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/SaPlatformLibrary.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/SaPlatformLibrary.c
> new file mode 100644
> index 0000000000..fc6e469ae3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatf
> ormLib/SaPlatformLibrary.c
> @@ -0,0 +1,128 @@
> +/** @file
> +  SA Platform Lib implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaPlatformLibrary.h"
> +#include <Library/PciSegmentLib.h>
> +#include <SaRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +
> +/**
> +  Determine if PCH Link is DMI/OPI
> +
> +  @param[in] CpuModel             CPU model
> +
> +  @retval TRUE                    DMI
> +  @retval FALSE                   OPI
> +**/
> +BOOLEAN
> +IsPchLinkDmi (
> +  IN CPU_FAMILY  CpuModel
> +  )
> +{
> +  if ((CpuModel == EnumCpuCflDtHalo) || (CpuModel ==
> EnumCpuCnlDtHalo)) {
> +    return TRUE; // DMI
> +  }
> +  return FALSE;  // OPI
> +}
> +
> +
> +/**
> +  Returns the number of DMI lanes for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxDmiLanes (
> +  )
> +{
> +    return SA_DMI_CFL_MAX_LANE;
> +}
> +
> +
> +/**
> +  Returns the number of DMI bundles for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxDmiBundles (
> +  )
> +{
> +    return SA_DMI_CFL_MAX_BUNDLE;
> +}
> +
> +
> +/**
> +  Returns the function numbers for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxPegFuncs (
> +  )
> +{
> +  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
> +    return SA_PEG_CNL_H_MAX_FUN;
> +  } else {
> +    return SA_PEG_NON_CNL_H_MAX_FUN;
> +  }
> +}
> +
> +
> +/**
> +  Returns the number of PEG lanes for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxPegLanes (
> +  )
> +{
> +  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
> +    return SA_PEG_CNL_H_MAX_LANE;
> +  } else {
> +    return SA_PEG_NON_CNL_H_MAX_LANE;
> +  }
> +}
> +
> +
> +/**
> +  Returns the number of PEG bundles for current CPU
> +
> +  @retval UINT8
> +**/
> +UINT8
> +GetMaxPegBundles (
> +  )
> +{
> +  if (GetCpuFamily() == EnumCpuCnlDtHalo) {
> +    return  SA_PEG_CNL_H_MAX_BUNDLE;
> +  } else {
> +    return  SA_PEG_NON_CNL_H_MAX_BUNDLE;
> +  }
> +}
> +
> +/**
> +  Checks if PEG port is present
> +
> +  @retval TRUE     PEG is presented
> +  @retval FALSE    PEG is not presented
> +**/
> +BOOLEAN
> +IsPegPresent (
> +  VOID
> +  )
> +{
> +  UINT64  PegBaseAddress;
> +
> +  PegBaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, 0, 0);
> +  if (PciSegmentRead16 (PegBaseAddress) != 0xFFFF) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Mrc
> OemPlatform.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Mr
> cOemPlatform.c
> new file mode 100644
> index 0000000000..b7aec77842
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Mr
> cOemPlatform.c
> @@ -0,0 +1,745 @@
> +/** @file
> +  This file is SampleCode for Intel SA PEI Policy initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "MrcOemPlatform.h"
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/SmbusLib.h>
> +#include <PchAccess.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +
> +#pragma pack (push, 1)
> +typedef union {
> +  struct {
> +    UINT32                         : 8;
> +    UINT32 MAX_NON_TURBO_LIM_RATIO : 8;
> +    UINT32                         : 16;
> +    UINT32                         : 32;
> +  } Bits;
> +  UINT64 Data;
> +  UINT32 Data32[2];
> +  UINT16 Data16[4];
> +  UINT8  Data8[8];
> +} PCU_CR_PLATFORM_INFO_STRUCT;
> +
> +#pragma pack (pop)
> +
> +#define SA_SYSTEM_BCLK                (100)
> +#define PCU_CR_PLATFORM_INFO          (0xCE)
> +#define MRC_POST_CODE_LOW_BYTE_ADDR   (0x48)
> +#define MRC_POST_CODE_HIGH_BYTE_ADDR  (0x49)
> +#define MAX_SPD_PAGE_COUNT            (2)
> +#define MAX_SPD_PAGE_SIZE             (256)
> +#define MAX_SPD_DDR3_SIZE             (MAX_SPD_PAGE_SIZE * 1)
> +#define MAX_SPD_DDR4_SIZE             (MAX_SPD_PAGE_SIZE * 2)
> +#define MAX_SPD_SIZE                  (MAX_SPD_PAGE_SIZE *
> MAX_SPD_PAGE_COUNT)
> +#define SPD_PAGE_ADDRESS_0            (0x6C)
> +#define SPD_PAGE_ADDRESS_1            (0x6E)
> +#define SPD_DDR3_XMP_OFFSET           (176)
> +#define SPD_DDR4_XMP_OFFSET           (384)
> +#define SPD_DDR3_SDRAM_TYPE_OFFSET    (0x02)
> +#define SPD_DDR3_SDRAM_TYPE_NUMBER    (0x0B)
> +#define SPD_DDR4_SDRAM_TYPE_NUMBER    (0x0C)
> +#define SPD_LPDDR3_SDRAM_TYPE_NUMBER  (0x0F)
> +#define SPD_LPDDR4_SDRAM_TYPE_NUMBER  (0x10)
> +#define SPD_LPDDR4X_SDRAM_TYPE_NUMBER (0x11)
> +#define ISVT_END_OF_MRC_STATE         (0x10)
> +
> +/**
> +  Read the SPD data over the SMBus, at the specified SPD address, starting at
> +  the specified starting offset and read the given amount of data.
> +
> +  @param[in] SpdAddress  - SPD SMBUS address
> +  @param[in, out] Buffer - Buffer to store the data.
> +  @param[in] Start       - Starting SPD offset
> +  @param[in] Size        - The number of bytes of data to read and also the
> size of the buffer.
> +  @param[in, out] Page   - The final page that is being pointed to.
> +
> +  @retval RETURN_SUCCESS if the read is successful, otherwise error status.
> +**/
> +static
> +RETURN_STATUS
> +DoSpdRead (
> +  IN     const UINT8  SpdAddress,
> +  IN OUT UINT8        *const Buffer,
> +  IN     const UINT16 Start,
> +  IN           UINT16 Size,
> +  IN OUT UINT8        *const Page
> +  )
> +{
> +  RETURN_STATUS EfiStatus;
> +  BOOLEAN       PageUpdate;
> +  UINT16        Count;
> +  UINT16        Index;
> +
> +  EfiStatus = RETURN_DEVICE_ERROR;
> +  if ((Buffer != NULL) && (Start < MAX_SPD_SIZE) && ((Start + Size) <
> MAX_SPD_SIZE)) {
> +    Count = 0;
> +    PageUpdate = FALSE;
> +    while (Size--) {
> +      Index = Start + Count;
> +      if ((Index / MAX_SPD_PAGE_SIZE) != *Page) {
> +        *Page = (UINT8) (Index / MAX_SPD_PAGE_SIZE);
> +        PageUpdate = TRUE;
> +      }
> +      Index %= MAX_SPD_PAGE_SIZE;
> +      if (PageUpdate == TRUE) {
> +        PageUpdate = FALSE;
> +        SmBusWriteDataByte ((*Page == 0) ? SPD_PAGE_ADDRESS_0 :
> SPD_PAGE_ADDRESS_1, 0, &EfiStatus);
> +      }
> +      Buffer[Count] = SmBusReadDataByte (SpdAddress | ((UINT32) Index << 8),
> &EfiStatus);
> +      if (RETURN_SUCCESS != EfiStatus) {
> +        Buffer[Count] = 0;
> +        break;
> +      }
> +      Count++;
> +    }
> +    EfiStatus = RETURN_SUCCESS;
> +  }
> +  return (EfiStatus);
> +}
> +
> +/**
> +  See if there is valid XMP SPD data.
> +
> +  @param[in] Debug    - Mrc debug structure.
> +  @param[in, out] Spd - Mrc SPD structure.
> +  @param[in] XmpStart - The current offset in the SPD.
> +
> +  @retval TRUE if valid, FALSE in not.
> +**/
> +static
> +BOOLEAN
> +VerifyXmp (
> +  IN OUT MrcSpd *const Spd,
> +  IN const UINT16 XmpStart
> +  )
> +{
> +  SPD_EXTREME_MEMORY_PROFILE_HEADER      *Header1;
> +  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0  *Header2;
> +  BOOLEAN                                 Xmp;
> +
> +  Xmp = FALSE;
> +
> +  switch (((UINT8 *) Spd) [2]) {
> +    case SPD_DDR3_SDRAM_TYPE_NUMBER:
> +      Header1 = &Spd->Ddr3.Xmp.Header;
> +      if (XmpStart == ((UINT32) (Header1) - (UINT32) Spd)) {
> +        Xmp = TRUE;
> +        if ((Header1->XmpRevision.Data & 0xFE) == 0x12) {
> +          return (TRUE);
> +        } else {
> +          Header1->XmpId            = 0;
> +          Header1->XmpOrgConf.Data  = 0;
> +          Header1->XmpRevision.Data = 0;
> +        }
> +      }
> +      break;
> +    case SPD_DDR4_SDRAM_TYPE_NUMBER:
> +      Header2 = &Spd->Ddr4.EndUser.Xmp.Header;
> +      if (XmpStart == ((UINT32) (Header2) - (UINT32) Spd)) {
> +        Xmp = TRUE;
> +        if ((Header2->XmpRevision.Data) == 0x20) {
> +          return (TRUE);
> +        } else {
> +          Header2->XmpId            = 0;
> +          Header2->XmpOrgConf.Data  = 0;
> +          Header2->XmpRevision.Data = 0;
> +        }
> +      }
> +      break;
> +    case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
> +    case SPD_LPDDR4_SDRAM_TYPE_NUMBER:
> +    case SPD_LPDDR4X_SDRAM_TYPE_NUMBER:
> +      return (TRUE);
> +    default:
> +      return (FALSE);
> +  }
> +  if (!Xmp) {
> +    return (TRUE);
> +  }
> +  return (FALSE);
> +}
> +
> +/**
> +  Read the SPD data over the SMBus, at the given SmBus SPD address and copy
> the data to the data structure.
> +  The SPD data locations read is controlled by the current boot mode.
> +
> +  @param[in] BootMode           - The current MRC boot mode.
> +  @param[in] Address            - SPD SmBus address offset.
> +  @param[in] Buffer             - Buffer that contains the data read from the
> SPD.
> +  @param[in] SpdDdr3Table       - Indicates which SPD bytes to read.
> +  @param[in] SpdDdr3TableSize   - Size of SpdDdr3Table in bytes.
> +  @param[in] SpdDdr4Table       - Indicates which SPD bytes to read.
> +  @param[in] SpdDdr4TableSize   - Size of SpdDdr4Table in bytes.
> +  @param[in] SpdLpddrTable      - Indicates which SPD bytes to read.
> +  @param[in] SpdLpddrTableSize  - Size of SpdLpddrTable in bytes.
> +
> +  @retval TRUE if the read is successful, otherwise FALSE on error.
> +**/
> +BOOLEAN
> +GetSpdData (
> +  IN SPD_BOOT_MODE BootMode,
> +  IN UINT8         Address,
> +  IN OUT   UINT8   *Buffer,
> +  IN UINT8         *SpdDdr3Table,
> +  IN UINT32        SpdDdr3TableSize,
> +  IN UINT8         *SpdDdr4Table,
> +  IN UINT32        SpdDdr4TableSize,
> +  IN UINT8         *SpdLpddrTable,
> +  IN UINT32        SpdLpddrTableSize
> +  )
> +{
> +  const SPD_OFFSET_TABLE *Tbl;
> +  const SPD_OFFSET_TABLE *TableSelect;
> +  RETURN_STATUS          Status;
> +  UINT32                 Byte;
> +  UINT32                 Stop;
> +  UINT8                  Page;
> +
> +  Page   = (UINT8) (~0);
> +  Status = DoSpdRead (Address, &Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET],
> 2, 1, &Page);
> +  if (RETURN_SUCCESS == Status) {
> +    switch (Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET]) {
> +      case SPD_DDR3_SDRAM_TYPE_NUMBER:
> +      default:
> +        TableSelect = (SPD_OFFSET_TABLE *) SpdDdr3Table;
> +        Stop = (SpdDdr3TableSize / sizeof (SPD_OFFSET_TABLE));
> +        break;
> +      case SPD_DDR4_SDRAM_TYPE_NUMBER:
> +        TableSelect = (SPD_OFFSET_TABLE *) SpdDdr4Table;
> +        Stop = (SpdDdr4TableSize / sizeof (SPD_OFFSET_TABLE));
> +        break;
> +      case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
> +      case SPD_LPDDR4_SDRAM_TYPE_NUMBER:
> +      case SPD_LPDDR4X_SDRAM_TYPE_NUMBER:
> +        TableSelect = (SPD_OFFSET_TABLE *) SpdLpddrTable;
> +        Stop = (SpdLpddrTableSize / sizeof (SPD_OFFSET_TABLE));
> +        break;
> +    }
> +    for (Byte = 0; (RETURN_SUCCESS == Status) && (Byte < Stop); Byte++) {
> +      Tbl = &TableSelect[Byte];
> +      if ((1 << BootMode) & Tbl->BootMode) {
> +        Status = DoSpdRead (Address, &Buffer[Tbl->Start], Tbl->Start, Tbl->End
> - Tbl->Start + 1, &Page);
> +        if (Status == RETURN_SUCCESS) {
> +          if (SpdCold == BootMode) {
> +            if (FALSE == VerifyXmp ((MrcSpd *) Buffer, Tbl->Start)) {
> +              break;
> +            }
> +          }
> +        } else {
> +          break;
> +        }
> +      }
> +    }
> +  }
> +
> +  return ((RETURN_SUCCESS == Status) ? TRUE : FALSE);
> +}
> +
> +//
> +// This is from MdeModulePkg\Include\Guid\StatusCodeDataTypeDebug.h
> +// Might need to be adjusted for a particular BIOS core
> +//
> +#ifndef EFI_STATUS_CODE_DATA_MAX_SIZE
> +#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
> +#endif
> +
> +/**
> +  Output a string to the debug stream/device.
> +  If there is a '%' sign in the string, convert it to '%%', so that DEBUG() macro
> will print it properly.
> +
> +  @param[in] String     - The string to output.
> +
> +  @retval Nothing.
> +**/
> +VOID
> +SaDebugPrint (
> +  VOID   *String
> +  )
> +{
> +  CHAR8   Str[EFI_STATUS_CODE_DATA_MAX_SIZE];
> +  CHAR8   *InputStr;
> +  CHAR8   *OutputStr;
> +  UINT32  i;
> +
> +  InputStr = (CHAR8 *) String;
> +  OutputStr = Str;
> +  i = 0;
> +  while (*InputStr != 0) {
> +    if (i < (EFI_STATUS_CODE_DATA_MAX_SIZE - 2)) {
> +      *OutputStr++ = *InputStr;
> +      i++;
> +      if (*InputStr++ == '%') {
> +        *OutputStr++ = '%';
> +        i++;
> +      }
> +    }
> +  }
> +  *OutputStr = 0;  // Terminating NULL
> +  DEBUG ((DEBUG_INFO, Str));
> +  return;
> +}
> +
> +/**
> +  Calculate the PCI device address for the given Bus/Device/Function/Offset.
> +
> +  @param[in] Bus      - PCI bus
> +  @param[in] Device   - PCI device
> +  @param[in] Function - PCI function
> +  @param[in] Offset   - Offset
> +
> +  @retval The PCI device address.
> +**/
> +UINT32
> +GetPciDeviceAddress (
> +  IN const UINT8 Bus,
> +  IN const UINT8 Device,
> +  IN const UINT8 Function,
> +  IN const UINT8 Offset
> +  )
> +{
> +  return (
> +    ((UINT32) ((Bus)      & 0xFF) << 16) |
> +    ((UINT32) ((Device)   & 0x1F) << 11) |
> +    ((UINT32) ((Function) & 0x07) << 8)  |
> +    ((UINT32) ((Offset)   & 0xFF) << 0)  |
> +    (1UL << 31));
> +}
> +
> +/**
> +  Calculate the PCIE device address for the given Bus/Device/Function/Offset.
> +
> +  @param[in] Bus      - PCI bus
> +  @param[in] Device   - PCI device
> +  @param[in] Function - PCI function
> +  @param[in] Offset   - Offset
> +
> +   The PCIE device address.
> +
> +  @retval The PCIe device address
> +**/
> +UINT32
> +GetPcieDeviceAddress (
> +  IN const UINT8 Bus,
> +  IN const UINT8 Device,
> +  IN const UINT8 Function,
> +  IN const UINT8 Offset
> +  )
> +{
> +  return (
> +    ((UINT32) Bus << 20) +
> +    ((UINT32) Device << 15) +
> +    ((UINT32) Function << 12) +
> +    ((UINT32) Offset << 0));
> +}
> +
> +/**
> +  Read specific RTC/CMOS RAM
> +
> +  @param[in] Location        Point to RTC/CMOS RAM offset for read
> +
> +  @retval The data of specific location in RTC/CMOS RAM.
> +**/
> +UINT8
> +PeiRtcRead (
> +  IN const UINT8 Location
> +  )
> +{
> +  UINT8  RtcIndexPort;
> +  UINT8  RtcDataPort;
> +
> +  //
> +  // CMOS access registers (using alternative access not to handle NMI bit)
> +  //
> +  if (Location < RTC_BANK_SIZE) {
> +    //
> +    // First bank
> +    //
> +    RtcIndexPort  = R_RTC_IO_INDEX_ALT;
> +    RtcDataPort   = R_RTC_IO_TARGET_ALT;
> +  } else {
> +    //
> +    // Second bank
> +    //
> +    RtcIndexPort  = R_RTC_IO_EXT_INDEX_ALT;
> +    RtcDataPort   = R_RTC_IO_EXT_TARGET_ALT;
> +  }
> +
> +  IoWrite8 (RtcIndexPort, Location & RTC_INDEX_MASK);
> +  return IoRead8 (RtcDataPort);
> +}
> +
> +/**
> +  Returns the current time, as determined by reading the Real Time Clock (RTC)
> on the platform.
> +  Since RTC time is stored in BCD, convert each value to binary.
> +
> +  @param[out] Seconds       - The current second (0-59).
> +  @param[out] Minutes       - The current minute (0-59).
> +  @param[out] Hours         - The current hour (0-23).
> +  @param[out] DayOfMonth    - The current day of the month (1-31).
> +  @param[out] Month         - The current month (1-12).
> +  @param[out] Year          - The current year (2000-2099).
> +
> +  @retval Nothing.
> +**/
> +VOID
> +GetRtcTime (
> +  OUT UINT8  *const Seconds,
> +  OUT UINT8  *const Minutes,
> +  OUT UINT8  *const Hours,
> +  OUT UINT8  *const DayOfMonth,
> +  OUT UINT8  *const Month,
> +  OUT UINT16 *const Year
> +  )
> +{
> +  UINT32 Timeout;
> +
> +  //
> +  // Wait until RTC "update in progress" bit goes low.
> +  //
> +  Timeout = 0x0FFFFF;
> +  do {
> +    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
> +    if ((IoRead8 (RTC_TARGET_REGISTER) & RTC_UPDATE_IN_PROGRESS) !=
> RTC_UPDATE_IN_PROGRESS) {
> +      break;
> +    }
> +  } while (--Timeout > 0);
> +
> +  if (0 == Timeout) {
> +    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
> +    IoWrite8 (RTC_TARGET_REGISTER, RTC_HOLD | RTC_MODE_24HOUR);
> +
> +    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGA);
> +    IoWrite8 (RTC_TARGET_REGISTER, RTC_CLOCK_DIVIDER |
> RTC_RATE_SELECT);
> +
> +    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGC);
> +    IoRead8 (RTC_TARGET_REGISTER);
> +
> +    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGD);
> +    IoRead8 (RTC_TARGET_REGISTER);
> +
> +    IoWrite8 (RTC_INDEX_REGISTER, CMOS_REGB);
> +    IoWrite8 (RTC_TARGET_REGISTER, RTC_MODE_24HOUR);
> +  }
> +  //
> +  // Read seconds
> +  //
> +  IoWrite8 (RTC_INDEX_REGISTER, RTC_SECONDS);
> +  *Seconds = IoRead8 (RTC_TARGET_REGISTER);
> +
> +  //
> +  // Read minutes
> +  //
> +  IoWrite8 (RTC_INDEX_REGISTER, RTC_MINUTES);
> +  *Minutes = IoRead8 (RTC_TARGET_REGISTER);
> +
> +  //
> +  // Read hours
> +  //
> +  IoWrite8 (RTC_INDEX_REGISTER, RTC_HOURS);
> +  *Hours = IoRead8 (RTC_TARGET_REGISTER);
> +
> +  //
> +  // Read day of month
> +  //
> +  IoWrite8 (RTC_INDEX_REGISTER, RTC_DAY_OF_MONTH);
> +  *DayOfMonth = IoRead8 (RTC_TARGET_REGISTER);
> +
> +  //
> +  // Read month
> +  //
> +  IoWrite8 (RTC_INDEX_REGISTER, RTC_MONTH);
> +  *Month = IoRead8 (RTC_TARGET_REGISTER);
> +
> +  //
> +  // Read year and add current century.
> +  //
> +  IoWrite8 (RTC_INDEX_REGISTER, RTC_YEAR);
> +  *Year = IoRead8 (RTC_TARGET_REGISTER);
> +
> +  *Seconds    = BCD2BINARY (*Seconds);
> +  *Minutes    = BCD2BINARY (*Minutes);
> +  *Hours      = BCD2BINARY (*Hours);
> +  *DayOfMonth = BCD2BINARY (*DayOfMonth);
> +  *Month      = BCD2BINARY (*Month);
> +  *Year       = BCD2BINARY (*Year) + CENTURY_OFFSET;
> +}
> +
> +/**
> +  Gets CPU current time.
> +
> +  @param[in] GlobalData - Pointer to global MRC data struct.
> +
> +  @retval The current CPU time in milliseconds.
> +**/
> +UINT64
> +GetCpuTime (
> +  IN VOID         *GlobalData
> +  )
> +{
> +  MrcParameters               *MrcData;
> +  MrcInput                    *Inputs;
> +  PCU_CR_PLATFORM_INFO_STRUCT Msr;
> +  UINT32                      TimeBase;
> +
> +  MrcData   = (MrcParameters *) GlobalData;
> +  Inputs    = &MrcData->Inputs;
> +
> +  Msr.Data = AsmReadMsr64 (PCU_CR_PLATFORM_INFO);
> +  TimeBase = (Inputs->BClkFrequency / 1000) *
> Msr.Bits.MAX_NON_TURBO_LIM_RATIO; //In Millisec
> +  return ((TimeBase == 0) ? 0 : DivU64x32 (AsmReadTsc (), TimeBase));
> +}
> +
> +/**
> +  Sets the specified number of memory words, a word at a time, at the
> +  specified destination.
> +
> +  @param[in, out] Dest     - Destination pointer.
> +  @param[in]      NumWords - The number of dwords to set.
> +  @param[in]      Value    - The value to set.
> +
> +  @retval Pointer to the buffer.
> +**/
> +VOID *
> +SetMemWord (
> +  IN OUT VOID     *Dest,
> +  IN UINTN        NumWords,
> +  IN const UINT16 Value
> +  )
> +{
> +  UINT16 *Buffer;
> +
> +  Buffer = (UINT16 *) Dest;
> +  while (0 != NumWords--) {
> +    *Buffer++ = Value;
> +  }
> +
> +  return (Dest);
> +}
> +
> +/**
> +  Sets the specified number of memory dwords, a dword at a time, at the
> +  specified destination.
> +
> +  @param[in, out] Dest      - Destination pointer.
> +  @param[in]      NumDwords - The number of dwords to set.
> +  @param[in]      Value     - The value to set.
> +
> +  @retval Pointer to the buffer.
> +**/
> +VOID *
> +SetMemDword (
> +  IN OUT VOID     *Dest,
> +  IN UINT32       NumDwords,
> +  IN const UINT32 Value
> +  )
> +{
> +  UINT32 *Buffer;
> +
> +  Buffer = (UINT32 *) Dest;
> +  while (0 != NumDwords--) {
> +    *Buffer++ = Value;
> +  }
> +
> +  return (Dest);
> +}
> +
> +
> +/**
> +  Gets the current memory voltage (VDD).
> +
> +  @param[in] GlobalData - Pointer to global MRC data struct.
> +  @param[in] DefaultVdd - Default Vdd for the given platform.
> +
> +  @retval The current memory voltage (VDD), in millivolts. 0 means platform
> default.
> +**/
> +UINT32
> +GetMemoryVdd (
> +  IN VOID     *GlobalData,
> +  IN UINT32   DefaultVdd
> +  )
> +{
> +  UINT32          CurrentVoltage;
> +
> +  CurrentVoltage = DefaultVdd;
> +
> +  return CurrentVoltage;
> +}
> +
> +/**
> +  Sets the memory voltage (VDD) to the specified value.
> +
> +  @param[in] GlobalData - Pointer to global MRC data struct.
> +  @param[in] DefaultVdd - Default Vdd for the given platform.
> +  @param[in] Voltage    - The new memory voltage to set.
> +
> +  @retval The actual memory voltage (VDD), in millivolts, that is closest to
> what the caller passed in.
> +**/
> +UINT32
> +SetMemoryVdd (
> +  IN VOID     *GlobalData,
> +  IN UINT32   DefaultVdd,
> +  IN UINT32   Voltage
> +  )
> +{
> +
> +  return Voltage;
> +}
> +
> +/**
> +  This function is used by the OEM to do a dedicated task during the MRC.
> +
> +  @param[in] GlobalData        - include all the MRC data
> +  @param[in] OemStatusCommand  - A command that indicates the task to
> perform.
> +  @param[in] Pointer           - general ptr for general use.
> +
> +  @retval The status of the task.
> +**/
> +MrcStatus
> +CheckPoint (
> +  IN VOID                *GlobalData,
> +  IN MrcOemStatusCommand OemStatusCommand,
> +  IN VOID                *Pointer
> +  )
> +{
> +  MrcParameters                *MrcData;
> +  MrcInput                     *Inputs;
> +  MrcStatus                    Status;
> +  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
> +  MEMORY_CONFIG_NO_CRC         *MemConfigNoCrc;
> +  EFI_STATUS                   Status1;
> +
> +  //
> +  // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform
> data
> +  //
> +  Status1 = PeiServicesLocatePpi (
> +              &gSiPreMemPolicyPpiGuid,
> +              0,
> +              NULL,
> +              (VOID **) &SiPreMemPolicyPpi
> +              );
> +  ASSERT_EFI_ERROR (Status1);
> +
> +  Status1 = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
> +  ASSERT_EFI_ERROR (Status1);
> +  MrcData             = (MrcParameters *) GlobalData;
> +  Inputs              = &MrcData->Inputs;
> +  SiPreMemPolicyPpi = (SI_PREMEM_POLICY_PPI *)
> Inputs->SiPreMemPolicyPpi;
> +  Status              = mrcSuccess;
> +
> +  switch (OemStatusCommand) {
> +    default:
> +      break;
> +  }
> +
> +  return (Status);
> +}
> +
> +/**
> +  Typically used to display to the I/O port 80h.
> +
> +  @param[in] GlobalData         - Mrc Global Data
> +  @param[in] DisplayDebugNumber - the number to display on port 80.
> +
> +  @retval Nothing.
> +**/
> +VOID
> +DebugHook (
> +  IN VOID       *GlobalData,
> +  UINT16        DisplayDebugNumber
> +  )
> +{
> +  MrcParameters                *MrcData;
> +  MrcOutput                    *Outputs;
> +  MrcDebug                     *Debug;
> +  EFI_STATUS                   Status;
> +  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
> +  SA_MISC_PEI_PREMEM_CONFIG    *MiscPeiPreMemConfig;
> +
> +  MrcData = (MrcParameters *) GlobalData;
> +  Outputs = &MrcData->Outputs;
> +  Debug   = &Outputs->Debug;
> +
> +  Debug->PostCode[MRC_POST_CODE] = DisplayDebugNumber;
> +  IoWrite16 (0x80, DisplayDebugNumber);
> +  DEBUG ((DEBUG_INFO, "Post Code: %04Xh\n", DisplayDebugNumber));
> +
> +  //
> +  // Locate SiPreMemPolicyPpi to do a GetConfigBlock() to access platform
> data
> +  //
> +  Status = PeiServicesLocatePpi (&gSiPreMemPolicyPpiGuid, 0, NULL, (VOID **)
> &SiPreMemPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +  if (Status == EFI_SUCCESS) {
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
> +    if (Status == EFI_SUCCESS) {
> +      //
> +      // Put the Port80 code also here:
> +      // #define BIOS_POST_CODE_PCU_CNL_REG          (0x00005824)
> +      //
> +      MmioWrite16 (MiscPeiPreMemConfig->MchBar + 0x5824,
> DisplayDebugNumber);
> +    }
> +  }
> +  return;
> +}
> +
> +/**
> +  Hook to take any action after returning from
> MrcStartMemoryConfiguration()
> +  and prior to taking any action regarding MrcStatus.  Pre-populated with
> issuing
> +  Intel Silicon View Technology (ISVT) checkpoint 0x10.
> +
> +  @param[in] GlobalData         - Mrc Global Data
> +  @param[in] MrcStatus          - Mrc status variable
> +**/
> +void
> +ReturnFromSmc (
> +  IN VOID         *GlobalData,
> +  IN UINT32       MrcStatus
> +  )
> +{
> +  MrcInput        *Inputs;
> +  MrcParameters   *MrcData;
> +  UINT32          CheckPoint;
> +  UINT32          PortReading;
> +
> +  MrcData   = (MrcParameters *) GlobalData;
> +  Inputs    = &MrcData->Inputs;
> +
> +  DEBUG ((DEBUG_INFO, "Returned From MrcStartMemoryConfiguration().
> MrcStatus = %08Xh\n", MrcStatus));
> +
> +  //
> +  // Intel Silicon View Technology (ISVT) IO Reading port with EAX = 0x10 for
> End of MRC
> +  //
> +  CheckPoint = ISVT_END_OF_MRC_STATE;
> +  PortReading = (UINT32) Inputs->IsvtIoPort;
> +  IsvtCheckPoint (CheckPoint, PortReading);
> +
> +  return;
> +}
> +
> +/**
> +  Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
> +
> +  @param[in] PciEBaseAddress  - PCI express base address.
> +  @param[in] ResetValue       - desired value of DRAM_RESET#. 1 - reset
> deasserted, 0 - reset asserted.
> +**/
> +VOID
> +SaDramReset (
> +  IN UINT32 PciEBaseAddress,
> +  IN UINT32 ResetValue
> +  )
> +{
> +  PmcSetDramResetCtlState (ResetValue);
> +
> +  return;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLib.c
> new file mode 100644
> index 0000000000..2ac3543f93
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLib.c
> @@ -0,0 +1,656 @@
> +/** @file
> +  This file provides services for PEI policy default initialization
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyLibrary.h"
> +#include <Library/GpioLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include "MrcInterface.h"
> +#include <Library/PchInfoLib.h>
> +
> +#define DEFAULT_OPTION_ROM_TEMP_BAR            0x80000000
> +#define DEFAULT_OPTION_ROM_TEMP_MEM_LIMIT      0xC0000000
> +//
> +// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
> +//
> +#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)
> // 80MB + 256MB
> +
> +//
> +// Function call to Load defaults for Individial IP Blocks
> +//
> +VOID
> +LoadSaMiscPeiPreMemDefault (
> +  IN   VOID          *ConfigBlockPointer
> +  )
> +{
> +  SA_MISC_PEI_PREMEM_CONFIG            *MiscPeiPreMemConfig;
> +
> +  MiscPeiPreMemConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "MiscPeiPreMemConfig->Header.GuidHob.Name =
> %g\n", &MiscPeiPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> MiscPeiPreMemConfig->Header.GuidHob.Header.HobLength));
> +  //
> +  // Policy initialization commented out here is because it's the same with
> default 0 and no need to re-do again.
> +  //
> +  MiscPeiPreMemConfig->LockPTMregs                      = 1;
> +
> +  //
> +  // Initialize the Platform Configuration
> +  //
> +  MiscPeiPreMemConfig->MchBar              = 0xFED10000;
> +  MiscPeiPreMemConfig->DmiBar              = 0xFED18000;
> +  MiscPeiPreMemConfig->EpBar               = 0xFED19000;
> +  MiscPeiPreMemConfig->EdramBar            = 0xFED80000;
> +  MiscPeiPreMemConfig->SmbusBar            = 0xEFA0;
> +  MiscPeiPreMemConfig->TsegSize            = PcdGet32 (PcdTsegSize);
> +  MiscPeiPreMemConfig->GdxcBar             = 0xFED84000;
> +
> +  //
> +  // Initialize the Switchable Graphics Default Configuration
> +  //
> +  MiscPeiPreMemConfig->SgDelayAfterHoldReset = 100; //100ms
> +  MiscPeiPreMemConfig->SgDelayAfterPwrEn     = 300; //300ms
> +
> +  ///
> +  /// Initialize the DataPtr for S3 resume
> +  ///
> +  MiscPeiPreMemConfig->S3DataPtr = NULL;
> +  MiscPeiPreMemConfig->OpRomScanTempMmioBar      =
> DEFAULT_OPTION_ROM_TEMP_BAR;
> +  MiscPeiPreMemConfig->OpRomScanTempMmioLimit    =
> DEFAULT_OPTION_ROM_TEMP_MEM_LIMIT;
> +}
> +
> +VOID
> +LoadSaMiscPeiDefault (
> +  IN   VOID          *ConfigBlockPointer
> +  )
> +{
> +  SA_MISC_PEI_CONFIG        *MiscPeiConfig;
> +
> +  MiscPeiConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "MiscPeiConfig->Header.GuidHob.Name = %g\n",
> &MiscPeiConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "MiscPeiConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> MiscPeiConfig->Header.GuidHob.Header.HobLength));
> +
> +  ///
> +  /// EDRAM H/W Mode by default (0- EDRAM SW Disable, 1- EDRAM SW
> Enable, 2- EDRAM HW Mode)
> +  ///
> +  MiscPeiConfig->EdramTestMode = 2;
> +
> +  if (IsWhlCpu()) {
> +    MiscPeiConfig->Device4Enable = 1;
> +  }
> +}
> +
> +VOID
> +LoadVtdDefault (
> +  IN VOID   *ConfigBlockPointer
> +  )
> +{
> +  VTD_CONFIG   *Vtd;
> +
> +  Vtd = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Name = %g\n",
> &Vtd->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "Vtd->Header.GuidHob.Header.HobLength =
> 0x%x\n", Vtd->Header.GuidHob.Header.HobLength));
> +
> +  //
> +  // Initialize the Vtd Configuration
> +  //
> +  Vtd->VtdDisable      = 0;
> +  Vtd->BaseAddress[0]  = 0xFED90000;
> +  Vtd->BaseAddress[1]  = 0xFED92000;
> +  Vtd->BaseAddress[2]  = 0xFED91000;
> +}
> +
> +VOID
> +LoadIpuPreMemDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  IPU_PREMEM_CONFIG      *IpuPreMemPolicy;
> +
> +  IpuPreMemPolicy = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "IpuPreMemPolicy->Header.GuidHob.Name = %g\n",
> &IpuPreMemPolicy->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "IpuPreMemPolicy->Header.GuidHob.Header.HobLength = 0x%x\n",
> IpuPreMemPolicy->Header.GuidHob.Header.HobLength));
> +
> +}
> +
> +VOID
> +LoadPciePeiPreMemDefault (
> +  IN   VOID          *ConfigBlockPointer
> +  )
> +{
> +  UINT8                  Index;
> +  PCIE_PEI_PREMEM_CONFIG *PciePeiPreMemConfig;
> +
> +  PciePeiPreMemConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "PciePeiPreMemConfig->Header.GuidHob.Name =
> %g\n", &PciePeiPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PciePeiPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PciePeiPreMemConfig->Header.GuidHob.Header.HobLength));
> +  //
> +  // Initialize the PciExpress Configuration
> +  //
> +  PciePeiPreMemConfig->DmiGen3EqPh2Enable             = 2;
> +  PciePeiPreMemConfig->DmiGen3ProgramStaticEq         = 1;
> +  PciePeiPreMemConfig->Peg0Enable                     = 2;
> +  PciePeiPreMemConfig->Peg1Enable                     = 2;
> +  PciePeiPreMemConfig->Peg2Enable                     = 2;
> +  PciePeiPreMemConfig->Peg3Enable                     = 2;
> +  PciePeiPreMemConfig->Peg0PowerDownUnusedLanes       = 1;
> +  PciePeiPreMemConfig->Peg1PowerDownUnusedLanes       = 1;
> +  PciePeiPreMemConfig->Peg2PowerDownUnusedLanes       = 1;
> +  PciePeiPreMemConfig->Peg3PowerDownUnusedLanes       = 1;
> +  PciePeiPreMemConfig->Peg0Gen3EqPh2Enable            = 2;
> +  PciePeiPreMemConfig->Peg1Gen3EqPh2Enable            = 2;
> +  PciePeiPreMemConfig->Peg2Gen3EqPh2Enable            = 2;
> +  PciePeiPreMemConfig->Peg3Gen3EqPh2Enable            = 2;
> +  PciePeiPreMemConfig->PegGen3ProgramStaticEq         = 1;
> +  PciePeiPreMemConfig->Gen3SwEqNumberOfPresets        = 2;
> +  PciePeiPreMemConfig->Gen3SwEqEnableVocTest          = 2;
> +
> +  if (IsCnlPch() && IsPchH() && (PchStepping() == PCH_A0)) {
> +    PciePeiPreMemConfig->DmiMaxLinkSpeed = 1;
> +  }
> +
> +  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
> +    PciePeiPreMemConfig->DmiGen3RootPortPreset[Index] = 4;
> +    PciePeiPreMemConfig->DmiGen3EndPointPreset[Index] = 7;
> +    PciePeiPreMemConfig->DmiGen3EndPointHint[Index]   = 2;
> +  }
> +  for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
> +    ///
> +    /// Gen3 RxCTLE peaking default is 0 for DMI
> +    ///
> +    PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index]  = 0;
> +  }
> +  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
> +    PciePeiPreMemConfig->PegGen3RootPortPreset[Index] = 7;
> +    PciePeiPreMemConfig->PegGen3EndPointPreset[Index] = 7;
> +    PciePeiPreMemConfig->PegGen3EndPointHint[Index]   = 2;
> +  }
> +  PciePeiPreMemConfig->DmiDeEmphasis = 1;
> +  ///
> +  /// Gen3 Software Equalization Jitter Dwell Time:               1 msec
> +  /// Gen3 Software Equalization Jitter Error Target:             1
> +  /// Gen3 Software Equalization VOC    Dwell Time:               10 msec
> +  /// Gen3 Software Equalization VOC    Error Target:             2
> +  ///
> +  PciePeiPreMemConfig->Gen3SwEqJitterDwellTime        = 3 *
> STALL_ONE_MILLI_SECOND;
> +  PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget      = 2;
> +  PciePeiPreMemConfig->Gen3SwEqVocDwellTime           = 10 *
> STALL_ONE_MILLI_SECOND;
> +  PciePeiPreMemConfig->Gen3SwEqVocErrorTarget         = 2;
> +
> +  /**
> +  Parameters for PCIe Gen3 device reset
> +  @note Refer to the Platform Design Guide (PDG) for additional information
> about this GPIO.
> +  **/
> +  PciePeiPreMemConfig->PegGpioData.GpioSupport        = FALSE;
> +  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad = 0;
> +  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active  = FALSE;
> +  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad = 0;
> +  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active  = FALSE;
> +}
> +
> +VOID
> +LoadPciePeiDefault (
> +  IN   VOID          *ConfigBlockPointer
> +  )
> +{
> +  UINT8                Index;
> +  PCIE_PEI_CONFIG      *PciePeiConfig;
> +
> +  PciePeiConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "PciePeiConfig->Header.GuidHob.Name = %g\n",
> &PciePeiConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "PciePeiConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> PciePeiConfig->Header.GuidHob.Header.HobLength));
> +  //
> +  // Initialize the PciExpress Configuration
> +  //
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    PciePeiConfig->PegDeEmphasis[Index] = 1;
> +    PciePeiConfig->PegMaxPayload[Index] = 0xFF;
> +  }
> +  ///
> +  /// Slot Power Limit Value:   75 W
> +  /// Slot Power Limit Scale:   1.0x
> +  /// Physical Slot Number:     Peg Index + 1 (1,2,3)
> +  ///
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    PciePeiConfig->PegSlotPowerLimitValue[Index] = 75;
> +    PciePeiConfig->PegPhysicalSlotNumber[Index] =  Index + 1;
> +  }
> +
> +}
> +
> +VOID
> +LoadGraphichsPeiPreMemDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +  GRAPHICS_PEI_PREMEM_CONFIG                         *GtPreMemConfig;
> +
> +  GtPreMemConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "GtPreMemConfig->Header.GuidHob.Name = %g\n",
> &GtPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "GtPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> GtPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  ///
> +  /// Initialize Graphics Pre-Mem Configurations.
> +  ///
> +  GtPreMemConfig->GmAdr               = 0xD0000000;
> +  GtPreMemConfig->GttMmAdr            = 0xCF000000;
> +  GtPreMemConfig->GttSize             = 3;
> +  GtPreMemConfig->IgdDvmt50PreAlloc   = 1;
> +  GtPreMemConfig->InternalGraphics    = 2;
> +  GtPreMemConfig->PrimaryDisplay      = 3;
> +  GtPreMemConfig->ApertureSize        = SA_GT_APERTURE_SIZE_256MB;
> +  GtPreMemConfig->PanelPowerEnable    = 1;
> +}
> +
> +VOID
> +LoadGraphichsPeiDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +  GRAPHICS_PEI_CONFIG                         *GtConfig;
> +
> +  GtConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Name = %g\n",
> &GtConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "GtConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", GtConfig->Header.GuidHob.Header.HobLength));
> +
> +  //
> +  // Initialize the Graphics configuration
> +  //
> +  GtConfig->RenderStandby       = 1;
> +  GtConfig->PavpEnable          = 1;
> +  GtConfig->PmSupport           = 1;
> +  GtConfig->CdynmaxClampEnable  = 1;
> +  GtConfig->GtFreqMax           = 0xFF;
> +  //
> +  // Initialize the default VBT settings
> +  //
> +  GtConfig->DdiConfiguration.DdiPortEdp  = 1;
> +  GtConfig->DdiConfiguration.DdiPortBHpd = 1;
> +  GtConfig->DdiConfiguration.DdiPortCHpd = 1;
> +  GtConfig->DdiConfiguration.DdiPortDHpd = 1;
> +  GtConfig->DdiConfiguration.DdiPortFHpd = 0;
> +  GtConfig->DdiConfiguration.DdiPortBDdc = 1;
> +  GtConfig->DdiConfiguration.DdiPortCDdc = 1;
> +  GtConfig->DdiConfiguration.DdiPortDDdc = 1;
> +  GtConfig->DdiConfiguration.DdiPortFDdc = 0;
> +
> +  ///
> +  /// Initialize the CdClock to 675 Mhz
> +  ///
> +  GtConfig->CdClock             = 3;
> +}
> +
> +VOID
> +LoadSwitchableGraphichsDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +  SWITCHABLE_GRAPHICS_CONFIG        *SgConfig;
> +  SgConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "SgConfig->Header.GuidHob.Name = %g\n",
> &SgConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "SgConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", SgConfig->Header.GuidHob.Header.HobLength));
> +  SgConfig->SaRtd3Pcie0Gpio.GpioSupport    = NotSupported;
> +  SgConfig->SaRtd3Pcie1Gpio.GpioSupport    = NotSupported;
> +  SgConfig->SaRtd3Pcie2Gpio.GpioSupport    = NotSupported;
> +}
> +
> +VOID
> +LoadMemConfigNoCrcDefault (
> +  IN VOID    *ConfigBlockPointer
> +  )
> +{
> +
> +  MEMORY_CONFIG_NO_CRC                    *MemConfigNoCrc;
> +
> +  MemConfigNoCrc = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "MemConfigNoCrc->Header.GuidHob.Name =
> %g\n", &MemConfigNoCrc->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "MemConfigNoCrc->Header.GuidHob.Header.HobLength = 0x%x\n",
> MemConfigNoCrc->Header.GuidHob.Header.HobLength));
> +  //
> +  // Allocating memory space for pointer structures inside MemConfigNoCrc
> +  //
> +  MemConfigNoCrc->SpdData = (SPD_DATA_BUFFER *) AllocateZeroPool
> (sizeof (SPD_DATA_BUFFER));
> +  ASSERT (MemConfigNoCrc->SpdData != NULL);
> +  if (MemConfigNoCrc->SpdData == NULL) {
> +    return;
> +  }
> +
> +  MemConfigNoCrc->DqByteMap = (SA_MEMORY_DQ_MAPPING *)
> AllocateZeroPool (sizeof (SA_MEMORY_DQ_MAPPING));
> +  ASSERT (MemConfigNoCrc->DqByteMap != NULL);
> +  if (MemConfigNoCrc->DqByteMap == NULL) {
> +    return;
> +  }
> +
> +  MemConfigNoCrc->DqsMap = (SA_MEMORY_DQS_MAPPING *)
> AllocateZeroPool (sizeof (SA_MEMORY_DQS_MAPPING));
> +  ASSERT (MemConfigNoCrc->DqsMap != NULL);
> +  if (MemConfigNoCrc->DqsMap == NULL) {
> +    return;
> +  }
> +
> +  MemConfigNoCrc->RcompData = (SA_MEMORY_RCOMP *)
> AllocateZeroPool (sizeof (SA_MEMORY_RCOMP));
> +  ASSERT (MemConfigNoCrc->RcompData != NULL);
> +  if (MemConfigNoCrc->RcompData == NULL) {
> +    return;
> +  }
> +
> +  //
> +  // Set PlatformMemory Size
> +  //
> +
> +  MemConfigNoCrc->PlatformMemorySize = PEI_MIN_MEMORY_SIZE;
> +
> +  MemConfigNoCrc->SerialDebugLevel  = 3;  //< Enable MRC debug message
> +
> +  MemConfigNoCrc->MemTestOnWarmBoot = 1;  //< Enable to run
> BaseMemoryTest on warm boot by default
> +
> +}
> +
> +VOID
> +LoadGnaDefault (
> +  IN VOID *ConfigBlockPointer
> +  )
> +{
> +  GNA_CONFIG                        *GnaConfig;
> +  GnaConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "GnaConfig->Header.GuidHob.Name = %g\n",
> &GnaConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "GnaConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", GnaConfig->Header.GuidHob.Header.HobLength));
> +  GnaConfig->GnaEnable    = TRUE;
> +}
> +
> +VOID
> +LoadMemConfigDefault (
> +  IN VOID *ConfigBlockPointer
> +  )
> +{
> +  MEMORY_CONFIGURATION                    *MemConfig;
> +  CPU_FAMILY                              CpuFamily;
> +  UINT16                                  DeviceId;
> +
> +  CPU_SKU                                 CpuSku;
> +  CpuSku = GetCpuSku ();
> +  CpuFamily   = GetCpuFamily ();
> +  DeviceId    = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS
> (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_DEVICE_ID));
> +
> +  MemConfig = ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Name = %g\n",
> &MemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "MemConfig->Header.GuidHob.Header.HobLength
> = 0x%x\n", MemConfig->Header.GuidHob.Header.HobLength));
> +  //
> +  // Initialize the Memory Configuration
> +  //
> +  MemConfig->EnBER              = 1;
> +  MemConfig->EccSupport         = 1;
> +  MemConfig->ScramblerSupport   = 1;
> +  MemConfig->PowerDownMode      = 0xFF;
> +  MemConfig->RankInterleave     = TRUE;
> +  MemConfig->EnhancedInterleave = TRUE;
> +  MemConfig->EnCmdRate          = 3;
> +  MemConfig->AutoSelfRefreshSupport = TRUE;
> +  MemConfig->ExtTemperatureSupport  = TRUE;
> +  MemConfig->WeaklockEn = 1;
> +  MemConfig->Ddr4MixedUDimm2DpcLimit = 1;
> +
> +  MemConfig->DualDimmPerChannelBoardType = (CpuFamily ==
> EnumCpuCflDtHalo) ? TRUE : FALSE;
> +
> +  //
> +  // Channel Hash Configuration
> +  //
> +  MemConfig->ChHashEnable         = TRUE;
> +  MemConfig->ChHashMask           = 0;
> +  MemConfig->ChHashInterleaveBit  = 2;
> +  MemConfig->PerBankRefresh       = TRUE;
> +  //
> +  // Options for Thermal settings
> +  //
> +  MemConfig->EnablePwrDn            = 1;
> +  MemConfig->EnablePwrDnLpddr       = 1;
> +  MemConfig->DdrThermalSensor       = 1;
> +
> +  MemConfig->EnergyScaleFact        = 4;
> +  MemConfig->IdleEnergyCh0Dimm0     = 0xA;
> +  MemConfig->IdleEnergyCh0Dimm1     = 0xA;
> +  MemConfig->IdleEnergyCh1Dimm0     = 0xA;
> +  MemConfig->IdleEnergyCh1Dimm1     = 0xA;
> +  MemConfig->PdEnergyCh0Dimm0       = 0x6;
> +  MemConfig->PdEnergyCh0Dimm1       = 0x6;
> +  MemConfig->PdEnergyCh1Dimm0       = 0x6;
> +  MemConfig->PdEnergyCh1Dimm1       = 0x6;
> +  MemConfig->ActEnergyCh0Dimm0      = 0xAC;
> +  MemConfig->ActEnergyCh0Dimm1      = 0xAC;
> +  MemConfig->ActEnergyCh1Dimm0      = 0xAC;
> +  MemConfig->ActEnergyCh1Dimm1      = 0xAC;
> +  MemConfig->RdEnergyCh0Dimm0       = 0xD4;
> +  MemConfig->RdEnergyCh0Dimm1       = 0xD4;
> +  MemConfig->RdEnergyCh1Dimm0       = 0xD4;
> +  MemConfig->RdEnergyCh1Dimm1       = 0xD4;
> +  MemConfig->WrEnergyCh0Dimm0       = 0xDD;
> +  MemConfig->WrEnergyCh0Dimm1       = 0xDD;
> +  MemConfig->WrEnergyCh1Dimm0       = 0xDD;
> +  MemConfig->WrEnergyCh1Dimm1       = 0xDD;
> +  MemConfig->WarmThresholdCh0Dimm0  = 0xFF;
> +  MemConfig->WarmThresholdCh0Dimm1  = 0xFF;
> +  MemConfig->WarmThresholdCh1Dimm0  = 0xFF;
> +  MemConfig->WarmThresholdCh1Dimm1  = 0xFF;
> +  MemConfig->HotThresholdCh0Dimm0   = 0xFF;
> +  MemConfig->HotThresholdCh0Dimm1   = 0xFF;
> +  MemConfig->HotThresholdCh1Dimm0   = 0xFF;
> +  MemConfig->HotThresholdCh1Dimm1   = 0xFF;
> +  MemConfig->WarmBudgetCh0Dimm0     = 0xFF;
> +  MemConfig->WarmBudgetCh0Dimm1     = 0xFF;
> +  MemConfig->WarmBudgetCh1Dimm0     = 0xFF;
> +  MemConfig->WarmBudgetCh1Dimm1     = 0xFF;
> +  MemConfig->HotBudgetCh0Dimm0      = 0xFF;
> +  MemConfig->HotBudgetCh0Dimm1      = 0xFF;
> +  MemConfig->HotBudgetCh1Dimm0      = 0xFF;
> +  MemConfig->HotBudgetCh1Dimm1      = 0xFF;
> +
> +  MemConfig->SrefCfgEna             = 1;
> +  MemConfig->SrefCfgIdleTmr         = 0x200;
> +  MemConfig->ThrtCkeMinTmr          = 0x30;
> +  MemConfig->ThrtCkeMinDefeatLpddr  = 1;
> +  MemConfig->ThrtCkeMinTmrLpddr     = 0x40;
> +
> +  MemConfig->RaplLim2WindX = 1;
> +  MemConfig->RaplLim2WindY = 1;
> +  MemConfig->RaplLim2Pwr   = 0xDE;
> +
> +  //
> +  // CA Vref routing: board-dependent
> +  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
> +  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
> +  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
> +  //
> +  //MemConfig->CaVrefConfig = 0;
> +  MemConfig->VttTermination     = ((CpuSku == EnumCpuUlx) || (CpuSku ==
> EnumCpuUlt));
> +  MemConfig->VttCompForVsshi    = 0;
> +
> +#ifdef UP_SERVER_FLAG
> +  MemConfig->TsodTcritmax = 0x69;
> +  MemConfig->TsodThigMax  = 0x5D;
> +#endif
> +
> +
> +  //
> +  // MRC training steps
> +  //
> +  MemConfig->ECT                  = 1;
> +  MemConfig->ERDMPRTC2D           = 1;
> +  MemConfig->SOT                  = 1;
> +  MemConfig->RDMPRT               = 1;
> +  MemConfig->RCVET                = 1;
> +  MemConfig->JWRL                 = 1;
> +  MemConfig->EWRTC2D              = 1;
> +  MemConfig->ERDTC2D              = 1;
> +  MemConfig->WRTC1D               = 1;
> +  MemConfig->WRVC1D               = 1;
> +  MemConfig->RDTC1D               = 1;
> +  MemConfig->DIMMODTT             = 1;
> +  MemConfig->DIMMRONT             = 1;
> +  MemConfig->WRSRT                = 1;
> +  MemConfig->RDODTT               = 1;
> +  MemConfig->RDAPT                = 1;
> +  MemConfig->WRTC2D               = 1;
> +  MemConfig->RDTC2D               = 1;
> +  MemConfig->CMDVC                = 1;
> +  MemConfig->WRVC2D               = 1;
> +  MemConfig->RDVC2D               = 1;
> +  MemConfig->LCT                  = 1;
> +  MemConfig->RTL                  = 1;
> +  MemConfig->TAT                  = 1;
> +  MemConfig->ALIASCHK             = 1;
> +  MemConfig->RCVENC1D             = 1;
> +  MemConfig->RMC                  = 1;
> +  MemConfig->CMDSR                = 1;
> +  MemConfig->CMDDSEQ              = 1;
> +  MemConfig->CMDNORM              = 1;
> +  MemConfig->EWRDSEQ              = 1;
> +  MemConfig->McLock               = TRUE;
> +  MemConfig->GdxcIotSize          = 4;
> +  MemConfig->GdxcMotSize          = 12;
> +  MemConfig->RDEQT                = 1;
> +
> +  MemConfig->MrcFastBoot          = TRUE;
> +  MemConfig->MrcTrainOnWarm       = FALSE;
> +  MemConfig->RemapEnable          = TRUE;
> +  MemConfig->BClkFrequency        = 100 * 1000 * 1000;
> +
> +#ifdef EMBEDDED_FLAG
> +  MemConfig->Force1Dpc = TRUE;
> +#endif
> +  MemConfig->Vc1ReadMeter           = TRUE;
> +  MemConfig->Vc1ReadMeterTimeWindow = 0x320;
> +  MemConfig->Vc1ReadMeterThreshold  = 0x118;
> +  MemConfig->StrongWkLeaker         = 7;
> +
> +  MemConfig->MobilePlatform     = (IS_SA_DEVICE_ID_MOBILE (DeviceId)) ?
> TRUE : FALSE;
> +  MemConfig->PciIndex           = 0xCF8;
> +  MemConfig->PciData            = 0xCFC;
> +  MemConfig->CkeRankMapping     = 0xAA;
> +
> +  // This only affects ULX/ULT; otherwise SA GV is disabled.
> +  // CFL SA GV: 0 - Disabled, 1 - FixedLow, 2 - FixedHigh, 3 - Enabled
> +  MemConfig->SaGv             = 3;
> +  MemConfig->SimicsFlag       = 0;
> +
> +  MemConfig->Idd3n              = 26;
> +  MemConfig->Idd3p              = 11;
> +
> +  MemConfig->RhPrevention       = TRUE;         // Row Hammer prevention.
> +  MemConfig->RhSolution         = HardwareRhp;  // Type of solution to be
> used for RHP - 0/1 = HardwareRhp/Refresh2x
> +  MemConfig->RhActProbability   = OneIn2To11;    // Activation probability
> for Hardware RHP
> +
> +  MemConfig->LpddrMemWriteLatencySet = 1;  // Enable LPDDR3 WL Set B if
> supported by DRAM
> +
> +  MemConfig->DllBwEn1 = 1;
> +  MemConfig->DllBwEn2 = 2;
> +  MemConfig->DllBwEn3 = 2;
> +
> +  MemConfig->RetrainOnFastFail  = 1; //  Restart MRC in Cold mode if SW
> MemTest fails during Fast flow. 0 = Disabled, 1 = Enabled
> +  MemConfig->Lp4DqsOscEn        = 1;
> +  MemConfig->IsvtIoPort         = 0x99;
> +}
> +
> +
> +VOID
> +LoadOverClockConfigDefault (
> +  IN VOID   *ConfigBlockPointer
> +  )
> +{
> +  OVERCLOCKING_PREMEM_CONFIG    *OcPreMemConfig;
> +  OcPreMemConfig = (OVERCLOCKING_PREMEM_CONFIG
> *)ConfigBlockPointer;
> +  DEBUG ((DEBUG_INFO, "OcPreMemConfig->Header.GuidHob.Name = %g\n",
> &OcPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "OcPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> OcPreMemConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +static COMPONENT_BLOCK_ENTRY  mSaIpBlocksPreMem [] = {
> +  {&gSaMiscPeiPreMemConfigGuid,       sizeof
> (SA_MISC_PEI_PREMEM_CONFIG),
> SA_MISC_PEI_PREMEM_CONFIG_REVISION,  LoadSaMiscPeiPreMemDefault},
> +  {&gSaPciePeiPreMemConfigGuid,       sizeof (PCIE_PEI_PREMEM_CONFIG),
> SA_PCIE_PEI_PREMEM_CONFIG_REVISION,  LoadPciePeiPreMemDefault},
> +  {&gGraphicsPeiPreMemConfigGuid,     sizeof
> (GRAPHICS_PEI_PREMEM_CONFIG),
> GRAPHICS_PEI_PREMEM_CONFIG_REVISION,
> LoadGraphichsPeiPreMemDefault},
> +  {&gSwitchableGraphicsConfigGuid,    sizeof
> (SWITCHABLE_GRAPHICS_CONFIG),
> SWITCHABLE_GRAPHICS_CONFIG_REVISION,
> LoadSwitchableGraphichsDefault},
> +  {&gMemoryConfigGuid,                sizeof (MEMORY_CONFIGURATION),
> MEMORY_CONFIG_REVISION,              LoadMemConfigDefault},
> +  {&gMemoryConfigNoCrcGuid,           sizeof (MEMORY_CONFIG_NO_CRC),
> MEMORY_CONFIG_REVISION,              LoadMemConfigNoCrcDefault},
> +  {&gSaOverclockingPreMemConfigGuid,  sizeof
> (OVERCLOCKING_PREMEM_CONFIG), SA_OVERCLOCKING_CONFIG_REVISION,
> LoadOverClockConfigDefault},
> +  {&gVtdConfigGuid,                   sizeof (VTD_CONFIG),
> VTD_CONFIG_REVISION,                 LoadVtdDefault},
> +  {&gIpuPreMemConfigGuid,             sizeof (IPU_PREMEM_CONFIG),
> IPU_PREMEM_CONFIG_REVISION,          LoadIpuPreMemDefault}
> +};
> +
> +static COMPONENT_BLOCK_ENTRY  mSaIpBlocks [] = {
> +  {&gSaMiscPeiConfigGuid,       sizeof (SA_MISC_PEI_CONFIG),
> SA_MISC_PEI_CONFIG_REVISION,      LoadSaMiscPeiDefault},
> +  {&gSaPciePeiConfigGuid,       sizeof (PCIE_PEI_CONFIG),
> SA_PCIE_PEI_CONFIG_REVISION,      LoadPciePeiDefault},
> +  {&gGraphicsPeiConfigGuid,     sizeof (GRAPHICS_PEI_CONFIG),
> GRAPHICS_PEI_CONFIG_REVISION,     LoadGraphichsPeiDefault},
> +  {&gGnaConfigGuid,             sizeof (GNA_CONFIG),
> GNA_CONFIG_REVISION,              LoadGnaDefault}
> +};
> +
> +/**
> +  Get SA config block table total size.
> +
> +  @retval     Size of SA config block table
> +**/
> +UINT16
> +EFIAPI
> +SaGetConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize (&mSaIpBlocks[0], sizeof
> (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> +
> +/**
> +  Get SA config block table total size.
> +
> +  @retval      Size of SA config block table
> +**/
> +UINT16
> +EFIAPI
> +SaGetConfigBlockTotalSizePreMem (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize (&mSaIpBlocksPreMem[0],
> sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> +
> +/**
> +  SaAddConfigBlocksPreMem add all SA config blocks.
> +
> +  @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
> +SaAddConfigBlocksPreMem (
> +  IN VOID           *ConfigBlockTableAddress
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n",
> sizeof (mSaIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY)));
> +  Status = AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mSaIpBlocksPreMem[0], sizeof (mSaIpBlocksPreMem) / sizeof
> (COMPONENT_BLOCK_ENTRY));
> +  if (Status == EFI_SUCCESS) {
> +    SaLoadSamplePolicyPreMem (ConfigBlockTableAddress);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  SaAddConfigBlocks add all SA config blocks.
> +
> +  @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
> +SaAddConfigBlocks (
> +  IN VOID           *ConfigBlockTableAddress
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "SA AddConfigBlocks. TotalBlockCount = 0x%x\n",
> sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)));
> +
> +  return AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mSaIpBlocks[0], sizeof (mSaIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLibSample.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLibSample.c
> new file mode 100644
> index 0000000000..463e75702d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Pei
> SaPolicyLibSample.c
> @@ -0,0 +1,284 @@
> +/** @file
> +  This file provides services for Sample PEI policy default initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <SaPolicyCommon.h>
> +#include "PeiSaPolicyLibrary.h"
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/SmbusLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include "MrcOemPlatform.h"
> +#include <Library/GpioLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/RngLib.h>
> +#include <Library/CpuMailboxLib.h>
> +
> +//
> +// DQ byte mapping to CMD/CTL/CLK, from the CPU side
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapSkl[2][6][2]
> = {
> +  // Channel 0:
> +  {
> +    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package
> 1 - Bytes[7:4]
> +    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
> +    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
> +    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
> +    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
> +    { 0xFF, 0x00 }  // CA Vref is one for all bytes
> +  },
> +  // Channel 1:
> +  {
> +    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package
> 1 - Bytes[7:4]
> +    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
> +    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
> +    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
> +    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
> +    { 0xFF, 0x00 }  // CA Vref is one for all bytes
> +  }
> +};
> +
> +//
> +// DQS byte swizzling between CPU and DRAM
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8
> mDqsMapCpu2DramSklRvp[2][8] = {
> +  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
> +  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
> +};
> +
> +//
> +// Reference RCOMP resistors on motherboard
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT16
> mRcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
> +//
> +// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT16
> mRcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23,
> 40 };
> +
> +/**
> +  Hynix H9CCNNN8JTMLAR-NTM_178b_DDP LPDDR3, 4Gb die (128Mx32), x32
> +  or Elpida  EDF8132A1MC-GD-F
> +  or Samsung K4E8E304EB-EGCE
> +  1600, 12-15-15-34
> +  2 rank per channel, 2 SDRAMs per rank, 4x4Gb = 2GB total per channel
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSkylakeRvp3Spd[] = {
> +  0x24,                                 ///< 0   Number of Serial PD Bytes Written /
> SPD Device Size
> +  0x20,                                 ///< 1   SPD Revision
> +  0x0F,                                 ///< 2   DRAM Device Type
> +  0x0E,                                 ///< 3   Module Type
> +  0x14,                                 ///< 4   SDRAM Density and Banks: 8 Banks, 4
> Gb SDRAM density
> +  0x11,                                 ///< 5   SDRAM Addressing: 14 Rows, 10
> Columns
> +  0x90,                                 ///< 6   SDRAM Package Type: Non-Monolithic,
> DDP, 1 Channel per package
> +  0x00,                                 ///< 7   SDRAM Optional Features
> +  0x00,                                 ///< 8   SDRAM Thermal and Refresh Options
> +  0x00,                                 ///< 9   Other SDRAM Optional Features
> +  0x00,                                 ///< 10  Reserved - must be coded as 0x00
> +  0x03,                                 ///< 11  Module Nominal Voltage, VDD
> +  0x0B,                                 ///< 12  Module Organization, SDRAM width:
> 32 bits, 2 Ranks
> +  0x03,                                 ///< 13  Module Memory Bus Width: 1
> Channel, 64 bits channel width
> +  0x00,                                 ///< 14  Module Thermal Sensor
> +  0x00,                                 ///< 15  Extended Module Type
> +  0x00,                                 ///< 16  Reserved - must be coded as 0x00
> +  0x00,                                 ///< 17  Timebases
> +  0x0A,                                 ///< 18  SDRAM Minimum Cycle Time
> (tCKmin)
> +  0xFF,                                 ///< 19  SDRAM Minimum Cycle Time
> (tCKmax)
> +  0x54,                                 ///< 20  CAS Latencies Supported, First Byte
> (tCk): 12 10 8
> +  0x00,                                 ///< 21  CAS Latencies Supported, Second
> Byte
> +  0x00,                                 ///< 22  CAS Latencies Supported, Third Byte
> +  0x00,                                 ///< 23  CAS Latencies Supported, Fourth Byte
> +  0x78,                                 ///< 24  Minimum CAS Latency Time (tAAmin)
> +  0x00,                                 ///< 25  Read and Write Latency Set Options
> +  0x90,                                 ///< 26  Minimum RAS# to CAS# Delay Time
> (tRCDmin)
> +  0xA8,                                 ///< 27  Minimum Row Precharge Delay Time
> for all banks (tRPab)
> +  0x90,                                 ///< 28  Minimum Row Precharge Delay Time
> per bank (tRPpb)
> +  0x10,                                 ///< 29  Minimum Refresh Recovery Delay
> Time for all banks (tRFCab), Least Significant Byte
> +  0x04,                                 ///< 30  Minimum Refresh Recovery Delay
> Time for all banks (tRFCab), Most Significant Byte
> +  0xE0,                                 ///< 31  Minimum Refresh Recovery Delay
> Time for per bank (tRFCpb), Least Significant Byte
> +  0x01,                                 ///< 32  Minimum Refresh Recovery Delay
> Time for per bank (tRFCpb), Most Significant Byte
> +  0, 0, 0, 0, 0, 0, 0,                  ///< 33 - 39
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 40 - 49
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 50 - 59
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 60 - 69 Connector to SDRAM Bit Mapping
> +  0, 0, 0, 0, 0, 0, 0, 0,               ///< 70 - 77 Connector to SDRAM Bit Mapping
> +  0, 0,                                 ///< 78 - 79
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 80 - 89
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 90 - 99
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 100 - 109
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 110 - 119
> +  0x00,                                 ///< 120 Fine Offset for Minimum Row
> Precharge Delay Time per bank (tRPpb)
> +  0x00,                                 ///< 121 Fine Offset for Minimum Row
> Precharge Delay Time for all banks (tRPab)
> +  0x00,                                 ///< 122 Fine Offset for Minimum RAS# to
> CAS# Delay Time (tRCDmin)
> +  0x00,                                 ///< 123 Fine Offset for Minimum CAS Latency
> Time (tAAmin)
> +  0x7F,                                 ///< 124 Fine Offset for SDRAM Minimum Cycle
> Time (tCKmax)
> +  0x00,                                 ///< 125 Fine Offset for SDRAM Minimum
> Cycle Time (tCKmin)
> +  0x00,                                 ///< 126 CRC A
> +  0x00,                                 ///< 127 CRC B
> +  0, 0,                                 ///< 128 - 129
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 130 - 139
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 140 - 149
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 150 - 159
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 160 - 169
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 170 - 179
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 180 - 189
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 190 - 199
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 200 - 209
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 210 - 219
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 220 - 229
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 230 - 239
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 240 - 249
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 250 - 259
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 260 - 269
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 270 - 279
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 280 - 289
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 290 - 299
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 300 - 309
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 310 - 319
> +  0x00,                                 ///< 320 Module Manufacturer ID Code, Least
> Significant Byte
> +  0x00,                                 ///< 321 Module Manufacturer ID Code, Most
> Significant Byte
> +  0x00,                                 ///< 322 Module Manufacturing Location
> +  0x00,                                 ///< 323 Module Manufacturing Date Year
> +  0x00,                                 ///< 324 Module Manufacturing Date Week
> +  0x55,                                 ///< 325 Module Serial Number A
> +  0x00,                                 ///< 326 Module Serial Number B
> +  0x00,                                 ///< 327 Module Serial Number C
> +  0x00,                                 ///< 328 Module Serial Number D
> +  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 329 - 333 Module Part Number:
> Unused bytes coded as ASCII Blanks (0x20)
> +  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 334 - 338 Module Part Number
> +  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 339 - 343 Module Part Number
> +  0x20, 0x20, 0x20, 0x20, 0x20,         ///< 344 - 348 Module Part Number
> +  0x00,                                 ///< 349 Module Revision Code
> +  0x00,                                 ///< 350 DRAM Manufacturer ID Code, Least
> Significant Byte
> +  0x00,                                 ///< 351 DRAM Manufacturer ID Code, Most
> Significant Byte
> +  0x00,                                 ///< 352 DRAM Stepping
> +  0, 0, 0, 0, 0, 0, 0,                  ///< 353 - 359
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 360 - 369
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 370 - 379
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 380 - 389
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 390 - 399
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 400 - 409
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 410 - 419
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 420 - 429
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 430 - 439
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 440 - 449
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 450 - 459
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 460 - 469
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 470 - 479
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 480 - 489
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 490 - 499
> +  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         ///< 500 - 509
> +  0, 0                                  ///< 510 - 511
> +};
> +
> +#define SaIoRead8    IoRead8
> +#define SaIoRead16   IoRead16
> +#define SaIoRead32   IoRead32
> +#define SaIoWrite8   IoWrite8
> +#define SaIoWrite16  IoWrite16
> +#define SaIoWrite32  IoWrite32
> +#define SaCopyMem    CopyMem
> +#define SaSetMem     SetMem
> +#define SaLShiftU64  LShiftU64
> +#define SaRShiftU64  RShiftU64
> +#define SaMultU64x32 MultU64x32
> +
> +/**
> +  SaLoadSamplePolicyPreMem - Load some policy default for reference
> board.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer for SA config blocks
> +
> +**/
> +VOID
> +SaLoadSamplePolicyPreMem (
> +  IN VOID           *ConfigBlockTableAddress
> +  )
> +{
> +  SA_FUNCTION_CALLS     *MemCall;
> +  EFI_STATUS            Status;
> +  MEMORY_CONFIG_NO_CRC  *MemConfigNoCrc;
> +  CPU_FAMILY            CpuFamilyId;
> +  UINT8                 *DqByteMap;
> +  BOOLEAN               KblCpu;
> +
> +  MemConfigNoCrc = NULL;
> +  Status = GetConfigBlock (ConfigBlockTableAddress,
> &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (MemConfigNoCrc == NULL) {
> +    return;
> +  }
> +  CpuFamilyId = GetCpuFamily ();
> +  KblCpu = ((CpuFamilyId == EnumCpuCflUltUlx) || (CpuFamilyId ==
> EnumCpuCflDtHalo));
> +
> +  DEBUG ((DEBUG_INFO, "Applying Sample policy defaults for RVP3\n"));
> +  MemCall                       = &MemConfigNoCrc->SaCall;
> +  MemCall->IoRead8              = &SaIoRead8;
> +  MemCall->IoRead16             = &SaIoRead16;
> +  MemCall->IoRead32             = &SaIoRead32;
> +  MemCall->IoWrite8             = &SaIoWrite8;
> +  MemCall->IoWrite16            = &SaIoWrite16;
> +  MemCall->IoWrite32            = &SaIoWrite32;
> +  MemCall->MmioRead8            = &MmioRead8;
> +  MemCall->MmioRead16           = &MmioRead16;
> +  MemCall->MmioRead32           = &MmioRead32;
> +  MemCall->MmioRead64           = &SaMmioRead64;
> +  MemCall->MmioWrite8           = &MmioWrite8;
> +  MemCall->MmioWrite16          = &MmioWrite16;
> +  MemCall->MmioWrite32          = &MmioWrite32;
> +  MemCall->MmioWrite64          = &SaMmioWrite64;
> +  MemCall->SmbusRead8           = &SmBusReadDataByte;
> +  MemCall->SmbusRead16          = &SmBusReadDataWord;
> +  MemCall->SmbusWrite8          = &SmBusWriteDataByte;
> +  MemCall->SmbusWrite16         = &SmBusWriteDataWord;
> +  MemCall->GetPciDeviceAddress  = &GetPciDeviceAddress;
> +  MemCall->GetPcieDeviceAddress = &GetPcieDeviceAddress;
> +  MemCall->GetRtcTime           = &GetRtcTime;
> +  MemCall->GetCpuTime           = &GetCpuTime;
> +  MemCall->CopyMem              = &SaCopyMem;
> +  MemCall->SetMem               = &SaSetMem;
> +  MemCall->SetMemWord           = &SetMemWord;
> +  MemCall->SetMemDword          = &SetMemDword;
> +  MemCall->LeftShift64          = &SaLShiftU64;
> +  MemCall->RightShift64         = &SaRShiftU64;
> +  MemCall->MultU64x32           = &SaMultU64x32;
> +  MemCall->DivU64x64            = &DivU64x64Remainder;
> +  MemCall->GetSpdData           = &GetSpdData;
> +  MemCall->GetRandomNumber      = &GetRandomNumber32;
> +  MemCall->CpuMailboxRead       = &MailboxRead;
> +  MemCall->CpuMailboxWrite      = &MailboxWrite;
> +  MemCall->GetMemoryVdd         = &GetMemoryVdd;
> +  MemCall->SetMemoryVdd         = &SetMemoryVdd;
> +  MemCall->CheckPoint           = &CheckPoint;
> +  MemCall->DebugHook            = &DebugHook;
> +  MemCall->DebugPrint           = &SaDebugPrint;
> +  MemCall->GetRtcCmos           = &PeiRtcRead;
> +  MemCall->ReadMsr64            = &AsmReadMsr64;
> +  MemCall->WriteMsr64           = &AsmWriteMsr64;
> +  MemCall->MrcReturnFromSmc     = &ReturnFromSmc;
> +  MemCall->MrcDramReset         = &SaDramReset;
> +
> +  //
> +  // RCOMP resistors and target values: board-dependent
> +  //
> +  if (KblCpu) {
> +    CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompResistor,
> mRcompResistorSklRvp1, sizeof (mRcompResistorSklRvp1));
> +    CopyMem ((VOID *) MemConfigNoCrc->RcompData->RcompTarget,
> mRcompTargetSklRvp1,   sizeof (mRcompTargetSklRvp1));
> +  }
> +
> +  CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[0][0],
> mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
> +  CopyMem ((VOID *) MemConfigNoCrc->SpdData->SpdData[1][0],
> mSkylakeRvp3Spd, sizeof (mSkylakeRvp3Spd));
> +
> +  DqByteMap = (UINT8 *) mDqByteMapSkl;
> +
> +  CopyMem ((VOID *) MemConfigNoCrc->DqByteMap, DqByteMap, sizeof
> (UINT8) * SA_MC_MAX_CHANNELS * SA_MRC_ITERATION_MAX * 2);
> +  CopyMem ((VOID *) MemConfigNoCrc->DqsMap,
> mDqsMapCpu2DramSklRvp, sizeof (UINT8) * SA_MC_MAX_CHANNELS *
> SA_MC_MAX_BYTES_NO_ECC);
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaP
> rintPolicy.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaP
> rintPolicy.c
> new file mode 100644
> index 0000000000..ce3ef52733
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaP
> rintPolicy.c
> @@ -0,0 +1,559 @@
> +/** @file
> +  This file provides service for PEI phase policy printing
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyLibrary.h"
> +#include <Library/GpioNativeLib.h>
> +
> +/**
> +  This function prints the PEI phase PreMem policy.
> +
> +  @param[in] SiPolicyPreMemPpi - Instance of SI_PREMEM_POLICY_PPI
> +**/
> +VOID
> +EFIAPI
> +SaPrintPolicyPpiPreMem (
> +  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  INTN                                  Index;
> +  INTN                                  Index2;
> +  EFI_STATUS                            Status;
> +  SA_MISC_PEI_PREMEM_CONFIG             *MiscPeiPreMemConfig;
> +  GRAPHICS_PEI_PREMEM_CONFIG            *GtPreMemConfig;
> +  MEMORY_CONFIGURATION                  *MemConfig;
> +  PCIE_PEI_PREMEM_CONFIG                *PciePeiPreMemConfig;
> +  SWITCHABLE_GRAPHICS_CONFIG            *SgConfig;
> +  MEMORY_CONFIG_NO_CRC                  *MemConfigNoCrc;
> +  VTD_CONFIG                            *Vtd;
> +  OVERCLOCKING_PREMEM_CONFIG            *OcPreMemConfig;
> +  IPU_PREMEM_CONFIG                     *IpuPreMemPolicy;
> +
> +  //
> +  // Get requisite IP Config Blocks which needs to be used here
> +  //
> +  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi,
> &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi, &gVtdConfigGuid,
> (VOID *) &Vtd);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi,
> &gMemoryConfigGuid, (VOID *) &MemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi,
> &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi,
> &gSwitchableGraphicsConfigGuid, (VOID *) &SgConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SiPolicyPreMemPpi,
> &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi,
> &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPreMemPpi,
> &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print
> BEGIN -----------------\n"));
> +  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n",
> SiPolicyPreMemPpi->TableHeader.Header.Revision));
> +  ASSERT (SiPolicyPreMemPpi->TableHeader.Header.Revision ==
> SI_PREMEM_POLICY_REVISION);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_PREMEM_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> MiscPeiPreMemConfig->Header.Revision));
> +  ASSERT (MiscPeiPreMemConfig->Header.Revision ==
> SA_MISC_PEI_PREMEM_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", SA_MC_MAX_SOCKETS));
> +  for (Index = 0; Index < SA_MC_MAX_SOCKETS; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> MiscPeiPreMemConfig->SpdAddressTable[Index]));
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "\n MchBar : 0x%x\n",
> MiscPeiPreMemConfig->MchBar));
> +  DEBUG ((DEBUG_INFO, " DmiBar : 0x%x\n",
> MiscPeiPreMemConfig->DmiBar));
> +  DEBUG ((DEBUG_INFO, " EpBar : 0x%x\n", MiscPeiPreMemConfig->EpBar));
> +  DEBUG ((DEBUG_INFO, " SmbusBar : 0x%x\n",
> MiscPeiPreMemConfig->SmbusBar));
> +  DEBUG ((DEBUG_INFO, " GdxcBar : 0x%x\n",
> MiscPeiPreMemConfig->GdxcBar));
> +  DEBUG ((DEBUG_INFO, " TsegSize : 0x%x\n",
> MiscPeiPreMemConfig->TsegSize));
> +  DEBUG ((DEBUG_INFO, " UserBd : 0x%x\n",
> MiscPeiPreMemConfig->UserBd));
> +  DEBUG ((DEBUG_INFO, " EdramBar : 0x%x\n",
> MiscPeiPreMemConfig->EdramBar));
> +  DEBUG ((DEBUG_INFO, " MmioSize : %d MB\n",
> MiscPeiPreMemConfig->MmioSize));
> +  DEBUG ((DEBUG_INFO, " MmioSizeAdjustment : %d MB\n",
> MiscPeiPreMemConfig->MmioSizeAdjustment));
> +  DEBUG ((DEBUG_INFO, " SkipExtGfxScan: 0x%x\n",
> MiscPeiPreMemConfig->SkipExtGfxScan));
> +  DEBUG ((DEBUG_INFO, " S3DataPtr : 0x%x\n",
> MiscPeiPreMemConfig->S3DataPtr));
> +  DEBUG ((DEBUG_INFO, "------------------------ SG_DELAY_OPTIMIZATION_DATA
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " SaRtd3.SgDelayAfterHoldReset : 0x%x\n",
> MiscPeiPreMemConfig->SgDelayAfterHoldReset));
> +  DEBUG ((DEBUG_INFO, " SaRtd3.SgDelayAfterPwrEn     : 0x%x\n",
> MiscPeiPreMemConfig->SgDelayAfterPwrEn));
> +
> +  DEBUG ((DEBUG_INFO, " ScanExtGfxForLegacyOpRom : 0x%x\n",
> MiscPeiPreMemConfig->ScanExtGfxForLegacyOpRom));
> +  DEBUG ((DEBUG_INFO, " AcpiReservedMemoryBase : 0x%x\n",
> MiscPeiPreMemConfig->AcpiReservedMemoryBase));
> +  DEBUG ((DEBUG_INFO, " AcpiReservedMemorySize : 0x%x\n",
> MiscPeiPreMemConfig->AcpiReservedMemorySize));
> +  DEBUG ((DEBUG_INFO, " SystemMemoryLength : 0x%x\n",
> MiscPeiPreMemConfig->SystemMemoryLength));
> +  DEBUG ((DEBUG_INFO, " OpRomScanTempMmioBar : 0x%x\n",
> MiscPeiPreMemConfig->OpRomScanTempMmioBar));
> +  DEBUG ((DEBUG_INFO, " OpRomScanTempMmioLimit : 0x%x\n",
> MiscPeiPreMemConfig->OpRomScanTempMmioLimit));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------
> GRAPHICS_PEI_PREMEM_CONFIG -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> GtPreMemConfig->Header.Revision));
> +  ASSERT (GtPreMemConfig->Header.Revision ==
> GRAPHICS_PEI_PREMEM_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " PanelPowerEnable : 0x%x\n",
> GtPreMemConfig->PanelPowerEnable));
> +  DEBUG ((DEBUG_INFO, " GttSize : %d MB\n", GtPreMemConfig->GttSize));
> +  DEBUG ((DEBUG_INFO, " IgdDvmt50PreAlloc : 0x%x\n",
> GtPreMemConfig->IgdDvmt50PreAlloc));
> +  DEBUG ((DEBUG_INFO, " InternalGraphics : 0x%x\n",
> GtPreMemConfig->InternalGraphics));
> +  DEBUG ((DEBUG_INFO, " PrimaryDisplay : 0x%x\n",
> GtPreMemConfig->PrimaryDisplay));
> +  DEBUG ((DEBUG_INFO, " ApertureSize : 0x%x\n",
> GtPreMemConfig->ApertureSize));
> +  DEBUG ((DEBUG_INFO, " GtPsmiSupport : 0x%x\n",
> GtPreMemConfig->GtPsmiSupport));
> +  DEBUG ((DEBUG_INFO, " PsmiRegionSize : 0x%x\n",
> GtPreMemConfig->PsmiRegionSize));
> +  DEBUG ((DEBUG_INFO, " GttMmAdr : 0x%x\n",
> GtPreMemConfig->GttMmAdr));
> +  DEBUG ((DEBUG_INFO, " GmAdr : 0x%x\n", GtPreMemConfig->GmAdr));
> +  DEBUG ((DEBUG_INFO, " DeltaT12PowerCycleDelayPreMem : 0x%x\n",
> GtPreMemConfig->DeltaT12PowerCycleDelayPreMem));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ PCIE_PEI_PREMEM_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> PciePeiPreMemConfig->Header.Revision));
> +  ASSERT (PciePeiPreMemConfig->Header.Revision ==
> SA_PCIE_PEI_PREMEM_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " DmiMaxLinkSpeed : 0x%x\n",
> PciePeiPreMemConfig->DmiMaxLinkSpeed));
> +  DEBUG ((DEBUG_INFO, " DmiGen3EqPh2Enable : 0x%x\n",
> PciePeiPreMemConfig->DmiGen3EqPh2Enable));
> +  DEBUG ((DEBUG_INFO, " DmiGen3EqPh3Method : 0x%x\n",
> PciePeiPreMemConfig->DmiGen3EqPh3Method));
> +  DEBUG ((DEBUG_INFO, " DmiGen3ProgramStaticEq : 0x%x\n",
> PciePeiPreMemConfig->DmiGen3ProgramStaticEq));
> +  DEBUG ((DEBUG_INFO, " Peg0Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg0Enable));
> +  DEBUG ((DEBUG_INFO, " Peg1Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg1Enable));
> +  DEBUG ((DEBUG_INFO, " Peg2Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg2Enable));
> +  DEBUG ((DEBUG_INFO, " Peg3Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg3Enable));
> +  DEBUG ((DEBUG_INFO, " Peg0MaxLinkSpeed : 0x%x\n",
> PciePeiPreMemConfig->Peg0MaxLinkSpeed));
> +  DEBUG ((DEBUG_INFO, " Peg1MaxLinkSpeed : 0x%x\n",
> PciePeiPreMemConfig->Peg1MaxLinkSpeed));
> +  DEBUG ((DEBUG_INFO, " Peg2MaxLinkSpeed : 0x%x\n",
> PciePeiPreMemConfig->Peg2MaxLinkSpeed));
> +  DEBUG ((DEBUG_INFO, " Peg3MaxLinkSpeed : 0x%x\n",
> PciePeiPreMemConfig->Peg3MaxLinkSpeed));
> +  DEBUG ((DEBUG_INFO, " Peg0MaxLinkWidth : 0x%x\n",
> PciePeiPreMemConfig->Peg0MaxLinkWidth));
> +  DEBUG ((DEBUG_INFO, " Peg1MaxLinkWidth : 0x%x\n",
> PciePeiPreMemConfig->Peg1MaxLinkWidth));
> +  DEBUG ((DEBUG_INFO, " Peg2MaxLinkWidth : 0x%x\n",
> PciePeiPreMemConfig->Peg2MaxLinkWidth));
> +  DEBUG ((DEBUG_INFO, " Peg3MaxLinkWidth : 0x%x\n",
> PciePeiPreMemConfig->Peg3MaxLinkWidth));
> +  DEBUG ((DEBUG_INFO, " Peg0PowerDownUnusedLanes : 0x%x\n",
> PciePeiPreMemConfig->Peg0PowerDownUnusedLanes));
> +  DEBUG ((DEBUG_INFO, " Peg1PowerDownUnusedLanes : 0x%x\n",
> PciePeiPreMemConfig->Peg1PowerDownUnusedLanes));
> +  DEBUG ((DEBUG_INFO, " Peg2PowerDownUnusedLanes : 0x%x\n",
> PciePeiPreMemConfig->Peg2PowerDownUnusedLanes));
> +  DEBUG ((DEBUG_INFO, " Peg3PowerDownUnusedLanes : 0x%x\n",
> PciePeiPreMemConfig->Peg3PowerDownUnusedLanes));
> +  DEBUG ((DEBUG_INFO, " Peg0Gen3EqPh2Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg0Gen3EqPh2Enable));
> +  DEBUG ((DEBUG_INFO, " Peg1Gen3EqPh2Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg1Gen3EqPh2Enable));
> +  DEBUG ((DEBUG_INFO, " Peg2Gen3EqPh2Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg2Gen3EqPh2Enable));
> +  DEBUG ((DEBUG_INFO, " Peg3Gen3EqPh2Enable : 0x%x\n",
> PciePeiPreMemConfig->Peg3Gen3EqPh2Enable));
> +  DEBUG ((DEBUG_INFO, " Peg0Gen3EqPh3Method : 0x%x\n",
> PciePeiPreMemConfig->Peg0Gen3EqPh3Method));
> +  DEBUG ((DEBUG_INFO, " Peg1Gen3EqPh3Method : 0x%x\n",
> PciePeiPreMemConfig->Peg1Gen3EqPh3Method));
> +  DEBUG ((DEBUG_INFO, " Peg2Gen3EqPh3Method : 0x%x\n",
> PciePeiPreMemConfig->Peg2Gen3EqPh3Method));
> +  DEBUG ((DEBUG_INFO, " Peg3Gen3EqPh3Method : 0x%x\n",
> PciePeiPreMemConfig->Peg3Gen3EqPh3Method));
> +  DEBUG ((DEBUG_INFO, " PegGen3ProgramStaticEq : 0x%x\n",
> PciePeiPreMemConfig->PegGen3ProgramStaticEq));
> +  DEBUG ((DEBUG_INFO, " Gen3SwEqAlwaysAttempt : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqAlwaysAttempt));
> +  DEBUG ((DEBUG_INFO, " Gen3SwEqNumberOfPresets : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqNumberOfPresets));
> +  DEBUG ((DEBUG_INFO, " Gen3SwEqEnableVocTest : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqEnableVocTest));
> +  DEBUG ((DEBUG_INFO, " InitPcieAspmAfterOprom : 0x%x\n",
> PciePeiPreMemConfig->InitPcieAspmAfterOprom));
> +  DEBUG ((DEBUG_INFO, " PegRxCemTestingMode : 0x%x\n",
> PciePeiPreMemConfig->PegRxCemTestingMode));
> +  DEBUG ((DEBUG_INFO, " PegRxCemLoopbackLane : 0x%x\n",
> PciePeiPreMemConfig->PegRxCemLoopbackLane));
> +  DEBUG ((DEBUG_INFO, " PegRxCemNonProtocolAwareness : 0x%x\n",
> PciePeiPreMemConfig->PegRxCemNonProtocolAwareness));
> +  DEBUG ((DEBUG_INFO, " PegDisableSpreadSpectrumClocking : 0x%x\n",
> PciePeiPreMemConfig->PegDisableSpreadSpectrumClocking));
> +  DEBUG ((DEBUG_INFO, " PegGenerateBdatMarginTable : 0x%x\n",
> PciePeiPreMemConfig->PegGenerateBdatMarginTable));
> +  DEBUG ((DEBUG_INFO, " DmiGen3RootPortPreset[%d] :",
> SA_DMI_MAX_LANE));
> +  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->DmiGen3RootPortPreset[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n DmiGen3EndPointPreset[%d] :",
> SA_DMI_MAX_LANE));
> +  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->DmiGen3EndPointPreset[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n DmiGen3EndPointHint[%d] :",
> SA_DMI_MAX_LANE));
> +  for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->DmiGen3EndPointHint[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n DmiGen3RxCtlePeaking[%d] :",
> SA_DMI_MAX_BUNDLE));
> +  for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegGen3RootPortPreset[%d] :",
> SA_PEG_MAX_LANE));
> +  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->PegGen3RootPortPreset[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegRootPortHPE[%d] :", SA_PEG_MAX_FUN));
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->PegRootPortHPE[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegGen3EndPointPreset[%d] :",
> SA_PEG_MAX_LANE));
> +  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->PegGen3EndPointPreset[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegGen3EndPointHint[%d] :",
> SA_PEG_MAX_LANE));
> +  for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->PegGen3EndPointHint[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegGen3RxCtlePeaking[%d] :",
> SA_PEG_MAX_BUNDLE));
> +  for (Index = 0; Index < SA_PEG_MAX_BUNDLE; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiPreMemConfig->PegGen3RxCtlePeaking[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegGen3RxCtleOverride : 0x%x\n",
> PciePeiPreMemConfig->PegGen3RxCtleOverride));
> +  DEBUG ((DEBUG_INFO, " DmiDeEmphasis : 0x%x\n",
> PciePeiPreMemConfig->DmiDeEmphasis));
> +  DEBUG ((DEBUG_INFO, "\n Gen3SwEqJitterDwellTime : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqJitterDwellTime));
> +  DEBUG ((DEBUG_INFO, " Gen3SwEqJitterErrorTarget : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget));
> +  DEBUG ((DEBUG_INFO, " Gen3SwEqVocDwellTime : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqVocDwellTime));
> +  DEBUG ((DEBUG_INFO, " Gen3SwEqVocErrorTarget : 0x%x\n",
> PciePeiPreMemConfig->Gen3SwEqVocErrorTarget));
> +  DEBUG ((DEBUG_INFO, " PegDataPtr : %p\n",
> PciePeiPreMemConfig->PegDataPtr));
> +  DEBUG ((DEBUG_INFO, " PegGpioData->GpioSupport : 0x%x\n",
> PciePeiPreMemConfig->PegGpioData.GpioSupport));
> +  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg0ResetGpio.GpioPad
> Group:%d, PadNumber:%d\n", GpioGetGroupIndexFromGpioPad
> (PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad),
> GpioGetPadNumberFromGpioPad
> (PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad)));
> +  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg0ResetGpio.Active : 0x%x\n",
> PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active));
> +  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg3ResetGpio.GpioPad
> Group:%d, PadNumber:%d\n", GpioGetGroupIndexFromGpioPad
> (PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad),
> GpioGetPadNumberFromGpioPad
> (PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad)));
> +  DEBUG ((DEBUG_INFO, " PegGpioData.SaPeg3ResetGpio.Active : 0x%x\n",
> PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ VTD_CONFIG -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n", Vtd->Header.Revision));
> +  ASSERT (Vtd->Header.Revision == VTD_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " VtdDisable : 0x%x\n", Vtd->VtdDisable));
> +  DEBUG ((DEBUG_INFO, " X2ApicOptOut : 0x%x\n", Vtd->X2ApicOptOut));
> +  DEBUG ((DEBUG_INFO, " VtdBaseAddress[%d] :",
> SA_VTD_ENGINE_NUMBER));
> +  for (Index = 0; Index < SA_VTD_ENGINE_NUMBER; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x", Vtd->BaseAddress[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +  DEBUG ((DEBUG_INFO, "------------------------
> SWITCHABLE_GRAPHICS_CONFIG -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n", SgConfig->Header.Revision));
> +  ASSERT (SgConfig->Header.Revision ==
> SWITCHABLE_GRAPHICS_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " SgConfig->SaRtd3Pcie0Gpio.GpioSupport :
> 0x%x\n", SgConfig->SaRtd3Pcie0Gpio.GpioSupport));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ IPU_PREMEM_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> IpuPreMemPolicy->Header.Revision));
> +  ASSERT (IpuPreMemPolicy->Header.Revision ==
> IPU_PREMEM_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " SaIpuEnable : 0x%x\n",
> IpuPreMemPolicy->SaIpuEnable));
> +  DEBUG ((DEBUG_INFO, " SaIpuImrConfiguration : 0x%x\n",
> IpuPreMemPolicy->SaIpuImrConfiguration));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ MEMORY_CONFIG
> ------------------------------\n"));
> +  DEBUG ((DEBUG_INFO, " Guid                   : %g\n",
> &MemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, " Revision               : %d\n",
> MemConfig->Header.Revision));
> +  ASSERT (MemConfig->Header.Revision == MEMORY_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " Size                   : 0x%x\n",
> MemConfig->Header.GuidHob.Header.HobLength));
> +  DEBUG ((DEBUG_INFO, " HobBufferSize          : 0x%x\n",
> MemConfig->HobBufferSize));
> +  DEBUG ((DEBUG_INFO, " EccSupport             : 0x%x\n",
> MemConfig->EccSupport));
> +  DEBUG ((DEBUG_INFO, " DdrFreqLimit           : %d\n",
> MemConfig->DdrFreqLimit));
> +  DEBUG ((DEBUG_INFO, " SpdProfileSelected     : 0x%x\n",
> MemConfig->SpdProfileSelected));
> +  DEBUG ((DEBUG_INFO, " tCL                    : 0x%x\n", MemConfig->tCL));
> +  DEBUG ((DEBUG_INFO, " tRCDtRP                : 0x%x\n",
> MemConfig->tRCDtRP));
> +  DEBUG ((DEBUG_INFO, " tRAS                   : 0x%x\n", MemConfig->tRAS));
> +  DEBUG ((DEBUG_INFO, " tWR                    : 0x%x\n", MemConfig->tWR));
> +  DEBUG ((DEBUG_INFO, " tRFC                   : 0x%x\n", MemConfig->tRFC));
> +  DEBUG ((DEBUG_INFO, " tRRD                   : 0x%x\n", MemConfig->tRRD));
> +  DEBUG ((DEBUG_INFO, " tWTR                   : 0x%x\n",
> MemConfig->tWTR));
> +  DEBUG ((DEBUG_INFO, " tRTP                   : 0x%x\n", MemConfig->tRTP));
> +  DEBUG ((DEBUG_INFO, " tFAW                   : 0x%x\n", MemConfig->tFAW));
> +  DEBUG ((DEBUG_INFO, " tCWL                   : 0x%x\n", MemConfig->tCWL));
> +  DEBUG ((DEBUG_INFO, " tREFI                  : 0x%x\n", MemConfig->tREFI));
> +  DEBUG ((DEBUG_INFO, " NModeSupport           : 0x%x\n",
> MemConfig->NModeSupport));
> +  DEBUG ((DEBUG_INFO, " VddVoltage             : %d\n",
> MemConfig->VddVoltage));
> +
> +  DEBUG ((DEBUG_INFO, " DisableDimmChannel[%d] :",
> SA_MC_MAX_CHANNELS));
> +  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> MemConfig->DisableDimmChannel[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n RemapEnable            : 0x%x\n",
> MemConfig->RemapEnable));
> +  DEBUG ((DEBUG_INFO, " ScramblerSupport       : 0x%x\n",
> MemConfig->ScramblerSupport));
> +  DEBUG ((DEBUG_INFO, " SerialDebug            : 0x%x\n",
> MemConfigNoCrc->SerialDebugLevel));
> +  DEBUG ((DEBUG_INFO, " ProbelessTrace      : 0x%x\n",
> MemConfig->ProbelessTrace));
> +  DEBUG ((DEBUG_INFO, " ECT                    : 0x%x\n", MemConfig->ECT));
> +  DEBUG ((DEBUG_INFO, " SOT                    : 0x%x\n", MemConfig->SOT));
> +  DEBUG ((DEBUG_INFO, " ERDMPRTC2D             : 0x%x\n",
> MemConfig->ERDMPRTC2D));
> +  DEBUG ((DEBUG_INFO, " RDMPRT                 : 0x%x\n",
> MemConfig->RDMPRT));
> +  DEBUG ((DEBUG_INFO, " RCVET                  : 0x%x\n",
> MemConfig->RCVET));
> +  DEBUG ((DEBUG_INFO, " JWRL                   : 0x%x\n", MemConfig->JWRL));
> +  DEBUG ((DEBUG_INFO, " EWRTC2D                : 0x%x\n",
> MemConfig->EWRTC2D));
> +  DEBUG ((DEBUG_INFO, " ERDTC2D                : 0x%x\n",
> MemConfig->ERDTC2D));
> +  DEBUG ((DEBUG_INFO, " WRTC1D                 : 0x%x\n",
> MemConfig->WRTC1D));
> +  DEBUG ((DEBUG_INFO, " WRVC1D                 : 0x%x\n",
> MemConfig->WRVC1D));
> +  DEBUG ((DEBUG_INFO, " RDTC1D                 : 0x%x\n",
> MemConfig->RDTC1D));
> +  DEBUG ((DEBUG_INFO, " DIMMODTT               : 0x%x\n",
> MemConfig->DIMMODTT));
> +  DEBUG ((DEBUG_INFO, " DIMMRONT               : 0x%x\n",
> MemConfig->DIMMRONT));
> +  DEBUG ((DEBUG_INFO, " WRDSEQT                : 0x%x\n",
> MemConfig->WRDSEQT));
> +  DEBUG ((DEBUG_INFO, " WRSRT                  : 0x%x\n",
> MemConfig->WRSRT));
> +  DEBUG ((DEBUG_INFO, " RDODTT                 : 0x%x\n",
> MemConfig->RDODTT));
> +  DEBUG ((DEBUG_INFO, " RDEQT                  : 0x%x\n",
> MemConfig->RDEQT));
> +  DEBUG ((DEBUG_INFO, " RDAPT                  : 0x%x\n",
> MemConfig->RDAPT));
> +  DEBUG ((DEBUG_INFO, " WRTC2D                 : 0x%x\n",
> MemConfig->WRTC2D));
> +  DEBUG ((DEBUG_INFO, " RDTC2D                 : 0x%x\n",
> MemConfig->RDTC2D));
> +  DEBUG ((DEBUG_INFO, " WRVC2D                 : 0x%x\n",
> MemConfig->WRVC2D));
> +  DEBUG ((DEBUG_INFO, " RDVC2D                 : 0x%x\n",
> MemConfig->RDVC2D));
> +  DEBUG ((DEBUG_INFO, " CMDVC                  : 0x%x\n",
> MemConfig->CMDVC));
> +  DEBUG ((DEBUG_INFO, " LCT                    : 0x%x\n", MemConfig->LCT));
> +  DEBUG ((DEBUG_INFO, " RTL                    : 0x%x\n", MemConfig->RTL));
> +  DEBUG ((DEBUG_INFO, " TAT                    : 0x%x\n", MemConfig->TAT));
> +  DEBUG ((DEBUG_INFO, " RMT                    : 0x%x\n", MemConfig->RMT));
> +  DEBUG ((DEBUG_INFO, " MEMTST                 : 0x%x\n",
> MemConfig->MEMTST));
> +  DEBUG ((DEBUG_INFO, " ALIASCHK               : 0x%x\n",
> MemConfig->ALIASCHK));
> +  DEBUG ((DEBUG_INFO, " RCVENC1D               : 0x%x\n",
> MemConfig->RCVENC1D));
> +  DEBUG ((DEBUG_INFO, " RMC                    : 0x%x\n", MemConfig->RMC));
> +  DEBUG ((DEBUG_INFO, " WRDSUDT                : 0x%x\n",
> MemConfig->WRDSUDT));
> +
> +  DEBUG ((DEBUG_INFO, " VddSettleWaitTime      : 0x%x\n",
> MemConfig->VddSettleWaitTime));
> +  DEBUG ((DEBUG_INFO, " RefClk                 : 0x%x\n",
> MemConfig->RefClk));
> +  DEBUG ((DEBUG_INFO, " Ratio                  : 0x%x\n", MemConfig->Ratio));
> +  DEBUG ((DEBUG_INFO, " OddRatioMode           : 0x%x\n",
> MemConfig->OddRatioMode));
> +  DEBUG ((DEBUG_INFO, " MrcTimeMeasure         : 0x%x\n",
> MemConfig->MrcTimeMeasure));
> +  DEBUG ((DEBUG_INFO, " MrcFastBoot            : 0x%x\n",
> MemConfig->MrcFastBoot));
> +  DEBUG ((DEBUG_INFO, " DqPinsInterleaved      : 0x%x\n",
> MemConfig->DqPinsInterleaved));
> +  DEBUG ((DEBUG_INFO, " MrcSafeConfig          : 0x%x\n",
> MemConfig->MrcSafeConfig));
> +  DEBUG ((DEBUG_INFO, " SafeMode               : 0x%x\n",
> MemConfig->SafeMode));
> +  DEBUG ((DEBUG_INFO, " Lp4DqsOscEn            : 0x%x\n",
> MemConfig->Lp4DqsOscEn));
> +  DEBUG ((DEBUG_INFO, " EnBER                  : 0x%x\n",
> MemConfig->EnBER));
> +  DEBUG ((DEBUG_INFO, " Ddr4MixedUDimm2DpcLimit: 0x%x\n",
> MemConfig->Ddr4MixedUDimm2DpcLimit));
> +  DEBUG ((DEBUG_INFO, " PowerDownMode          : 0x%x\n",
> MemConfig->PowerDownMode));
> +  DEBUG ((DEBUG_INFO, " PwdwnIdleCounter       : 0x%x\n",
> MemConfig->PwdwnIdleCounter));
> +  DEBUG ((DEBUG_INFO, " RankInterleave         : 0x%x\n",
> MemConfig->RankInterleave));
> +  DEBUG ((DEBUG_INFO, " EnhancedInterleave     : 0x%x\n",
> MemConfig->EnhancedInterleave));
> +  DEBUG ((DEBUG_INFO, " WeaklockEn             : 0x%x\n",
> MemConfig->WeaklockEn));
> +  DEBUG ((DEBUG_INFO, " EnCmdRate              : 0x%x\n",
> MemConfig->EnCmdRate));
> +  DEBUG ((DEBUG_INFO, " CmdTriStateDis         : 0x%x\n",
> MemConfig->CmdTriStateDis));
> +  DEBUG ((DEBUG_INFO, " BClkFrequency          : 0x%x\n",
> MemConfig->BClkFrequency));
> +  DEBUG ((DEBUG_INFO, " MemoryTrace            : 0x%x\n",
> MemConfig->MemoryTrace));
> +  DEBUG ((DEBUG_INFO, " ChHashEnable           : 0x%x\n",
> MemConfig->ChHashEnable));
> +  DEBUG ((DEBUG_INFO, " ChHashMask             : 0x%x\n",
> MemConfig->ChHashMask));
> +  DEBUG ((DEBUG_INFO, " ChHashInterleaveBit    : 0x%x\n",
> MemConfig->ChHashInterleaveBit));
> +  DEBUG ((DEBUG_INFO, " PerBankRefresh         : 0x%x\n",
> MemConfig->PerBankRefresh));
> +  DEBUG ((DEBUG_INFO, " EnableExtts            : 0x%x\n",
> MemConfig->EnableExtts));
> +  DEBUG ((DEBUG_INFO, " EnableCltm             : 0x%x\n",
> MemConfig->EnableCltm));
> +  DEBUG ((DEBUG_INFO, " EnableOltm             : 0x%x\n",
> MemConfig->EnableOltm));
> +  DEBUG ((DEBUG_INFO, " EnablePwrDn            : 0x%x\n",
> MemConfig->EnablePwrDn));
> +  DEBUG ((DEBUG_INFO, " EnablePwrDnLpddr       : 0x%x\n",
> MemConfig->EnablePwrDnLpddr));
> +  DEBUG ((DEBUG_INFO, " Refresh2X              : 0x%x\n",
> MemConfig->Refresh2X));
> +  DEBUG ((DEBUG_INFO, " DdrThermalSensor       : 0x%x\n",
> MemConfig->DdrThermalSensor));
> +  DEBUG ((DEBUG_INFO, " LockPTMregs            : 0x%x\n",
> MemConfig->LockPTMregs));
> +  DEBUG ((DEBUG_INFO, " UserPowerWeightsEn     : 0x%x\n",
> MemConfig->UserPowerWeightsEn));
> +  DEBUG ((DEBUG_INFO, " EnergyScaleFact        : 0x%x\n",
> MemConfig->EnergyScaleFact));
> +  DEBUG ((DEBUG_INFO, " RaplPwrFlCh1           : 0x%x\n",
> MemConfig->RaplPwrFlCh1));
> +  DEBUG ((DEBUG_INFO, " RaplPwrFlCh0           : 0x%x\n",
> MemConfig->RaplPwrFlCh0));
> +  DEBUG ((DEBUG_INFO, " RaplLim2Lock           : 0x%x\n",
> MemConfig->RaplLim2Lock));
> +  DEBUG ((DEBUG_INFO, " RaplLim2WindX          : 0x%x\n",
> MemConfig->RaplLim2WindX));
> +  DEBUG ((DEBUG_INFO, " RaplLim2WindY          : 0x%x\n",
> MemConfig->RaplLim2WindY));
> +  DEBUG ((DEBUG_INFO, " RaplLim2Ena            : 0x%x\n",
> MemConfig->RaplLim2Ena));
> +  DEBUG ((DEBUG_INFO, " RaplLim2Pwr            : 0x%x\n",
> MemConfig->RaplLim2Pwr));
> +  DEBUG ((DEBUG_INFO, " RaplLim1WindX          : 0x%x\n",
> MemConfig->RaplLim1WindX));
> +  DEBUG ((DEBUG_INFO, " RaplLim1WindY          : 0x%x\n",
> MemConfig->RaplLim1WindY));
> +  DEBUG ((DEBUG_INFO, " RaplLim1Ena            : 0x%x\n",
> MemConfig->RaplLim1Ena));
> +  DEBUG ((DEBUG_INFO, " RaplLim1Pwr            : 0x%x\n",
> MemConfig->RaplLim1Pwr));
> +  DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm0  : 0x%x\n",
> MemConfig->WarmThresholdCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " WarmThresholdCh0Dimm1  : 0x%x\n",
> MemConfig->WarmThresholdCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm0  : 0x%x\n",
> MemConfig->WarmThresholdCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " WarmThresholdCh1Dimm1  : 0x%x\n",
> MemConfig->WarmThresholdCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm0   : 0x%x\n",
> MemConfig->HotThresholdCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " HotThresholdCh0Dimm1   : 0x%x\n",
> MemConfig->HotThresholdCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm0   : 0x%x\n",
> MemConfig->HotThresholdCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " HotThresholdCh1Dimm1   : 0x%x\n",
> MemConfig->HotThresholdCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm0     : 0x%x\n",
> MemConfig->WarmBudgetCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " WarmBudgetCh0Dimm1     : 0x%x\n",
> MemConfig->WarmBudgetCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm0     : 0x%x\n",
> MemConfig->WarmBudgetCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " WarmBudgetCh1Dimm1     : 0x%x\n",
> MemConfig->WarmBudgetCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm0      : 0x%x\n",
> MemConfig->HotBudgetCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " HotBudgetCh0Dimm1      : 0x%x\n",
> MemConfig->HotBudgetCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm0      : 0x%x\n",
> MemConfig->HotBudgetCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " HotBudgetCh1Dimm1      : 0x%x\n",
> MemConfig->HotBudgetCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm0     : 0x%x\n",
> MemConfig->IdleEnergyCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " IdleEnergyCh0Dimm1     : 0x%x\n",
> MemConfig->IdleEnergyCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm0     : 0x%x\n",
> MemConfig->IdleEnergyCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " IdleEnergyCh1Dimm1     : 0x%x\n",
> MemConfig->IdleEnergyCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm0       : 0x%x\n",
> MemConfig->PdEnergyCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " PdEnergyCh0Dimm1       : 0x%x\n",
> MemConfig->PdEnergyCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm0       : 0x%x\n",
> MemConfig->PdEnergyCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " PdEnergyCh1Dimm1       : 0x%x\n",
> MemConfig->PdEnergyCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm0      : 0x%x\n",
> MemConfig->ActEnergyCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " ActEnergyCh0Dimm1      : 0x%x\n",
> MemConfig->ActEnergyCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm0      : 0x%x\n",
> MemConfig->ActEnergyCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " ActEnergyCh1Dimm1      : 0x%x\n",
> MemConfig->ActEnergyCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm0       : 0x%x\n",
> MemConfig->RdEnergyCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " RdEnergyCh0Dimm1       : 0x%x\n",
> MemConfig->RdEnergyCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm0       : 0x%x\n",
> MemConfig->RdEnergyCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " RdEnergyCh1Dimm1       : 0x%x\n",
> MemConfig->RdEnergyCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm0       : 0x%x\n",
> MemConfig->WrEnergyCh0Dimm0));
> +  DEBUG ((DEBUG_INFO, " WrEnergyCh0Dimm1       : 0x%x\n",
> MemConfig->WrEnergyCh0Dimm1));
> +  DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm0       : 0x%x\n",
> MemConfig->WrEnergyCh1Dimm0));
> +  DEBUG ((DEBUG_INFO, " WrEnergyCh1Dimm1       : 0x%x\n",
> MemConfig->WrEnergyCh1Dimm1));
> +  DEBUG ((DEBUG_INFO, " SrefCfgEna             : 0x%x\n",
> MemConfig->SrefCfgEna));
> +  DEBUG ((DEBUG_INFO, " SrefCfgIdleTmr         : 0x%x\n",
> MemConfig->SrefCfgIdleTmr));
> +  DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeat       : 0x%x\n",
> MemConfig->ThrtCkeMinDefeat));
> +  DEBUG ((DEBUG_INFO, " ThrtCkeMinTmr          : 0x%x\n",
> MemConfig->ThrtCkeMinTmr));
> +  DEBUG ((DEBUG_INFO, " ThrtCkeMinDefeatLpddr  : 0x%x\n",
> MemConfig->ThrtCkeMinDefeatLpddr));
> +  DEBUG ((DEBUG_INFO, " ThrtCkeMinTmrLpddr     : 0x%x\n",
> MemConfig->ThrtCkeMinTmrLpddr));
> +  DEBUG ((DEBUG_INFO, " AutoSelfRefreshSupport : 0x%x\n",
> MemConfig->AutoSelfRefreshSupport));
> +  DEBUG ((DEBUG_INFO, " ExtTemperatureSupport  : 0x%x\n",
> MemConfig->ExtTemperatureSupport));
> +  DEBUG ((DEBUG_INFO, " MaxRttWr               : 0x%x\n",
> MemConfig->MaxRttWr));
> +  DEBUG ((DEBUG_INFO, " MobilePlatform         : 0x%x\n",
> MemConfig->MobilePlatform));
> +  DEBUG ((DEBUG_INFO, " Force1Dpc              : 0x%x\n",
> MemConfig->Force1Dpc));
> +
> +
> +  DEBUG ((DEBUG_INFO, " ForceSingleRank        : 0x%x\n",
> MemConfig->ForceSingleRank));
> +  DEBUG ((DEBUG_INFO, " PciIndex               : 0x%x\n",
> MemConfig->PciIndex));
> +  DEBUG ((DEBUG_INFO, " PciData                : 0x%x\n",
> MemConfig->PciData));
> +  DEBUG ((DEBUG_INFO, " CkeRankMapping         : 0x%x\n",
> MemConfig->CkeRankMapping));
> +  DEBUG ((DEBUG_INFO, " RhPrevention           : 0x%x\n",
> MemConfig->RhPrevention));
> +  DEBUG ((DEBUG_INFO, " RhSolution             : 0x%x\n",
> MemConfig->RhSolution));
> +  DEBUG ((DEBUG_INFO, " RhActProbability       : 0x%x\n",
> MemConfig->RhActProbability));
> +  DEBUG ((DEBUG_INFO, " VttTermination         : 0x%x\n",
> MemConfig->VttTermination));
> +  DEBUG ((DEBUG_INFO, " VttCompForVsshi        : 0x%x\n",
> MemConfig->VttCompForVsshi));
> +  DEBUG ((DEBUG_INFO, " BerEnable              : 0x%x\n",
> MemConfig->BerEnable));
> +  for (Index = 0; Index < 4; Index++) {
> +    DEBUG ((DEBUG_INFO, " BerAddress[%d]      : 0x%x\n",Index ,
> MemConfig->BerAddress[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, " CleanMemory            : 0x%x\n",
> MemConfigNoCrc->CleanMemory));
> +  DEBUG ((DEBUG_INFO, " MemTestOnWarmBoot      : 0x%x\n",
> MemConfigNoCrc->MemTestOnWarmBoot));
> +  DEBUG ((DEBUG_INFO, " ExitOnFailure          : 0x%x\n",
> MemConfig->ExitOnFailure));
> +  DEBUG ((DEBUG_INFO, " Vc1ReadMeter           : 0x%x\n",
> MemConfig->Vc1ReadMeter));
> +  DEBUG ((DEBUG_INFO, " SaGv                   : 0x%x\n", MemConfig->SaGv));
> +  DEBUG ((DEBUG_INFO, " FreqSaGvLow            : 0x%x\n
> FreqSaGvMid            : 0x%x\n",
> +          MemConfig->FreqSaGvLow, MemConfig->FreqSaGvMid));
> +  DEBUG ((DEBUG_INFO, " StrongWkLeaker         : 0x%x\n",
> MemConfig->StrongWkLeaker));
> +  DEBUG ((DEBUG_INFO, " CaVrefConfig           : 0x%x\n",
> MemConfig->CaVrefConfig));
> +  DEBUG ((DEBUG_INFO, " SimicsFlag             : 0x%x\n",
> MemConfig->SimicsFlag));
> +  DEBUG ((DEBUG_INFO, " PlatformMemorySize     : 0x%x\n",
> MemConfigNoCrc->PlatformMemorySize));
> +  DEBUG ((DEBUG_INFO, " SmramMask              : 0x%x\n",
> MemConfig->SmramMask));
> +  DEBUG ((DEBUG_INFO, " DllBwEn0: %d\n DllBwEn1: %d\n DllBwEn2: %d\n
> DllBwEn3: %d\n",
> +          MemConfig->DllBwEn0, MemConfig->DllBwEn1,
> MemConfig->DllBwEn2, MemConfig->DllBwEn3));
> +  DEBUG ((DEBUG_INFO, " RetrainOnFastFail: %d\n ForceOltmOrRefresh2x:
> %d\n",
> +          MemConfig->RetrainOnFastFail,
> MemConfig->ForceOltmOrRefresh2x));
> +  DEBUG ((DEBUG_INFO, " RmtPerTask: %u\n TrainTrace: %u\n",
> MemConfig->RmtPerTask, MemConfig->TrainTrace));
> +  DEBUG ((DEBUG_INFO, " tRd2RdSG               : 0x%x\n
> tRd2RdDG               : 0x%x\n", MemConfig->tRd2RdSG,
> MemConfig->tRd2RdDG));
> +  DEBUG ((DEBUG_INFO, " tRd2RdDR               : 0x%x\n
> tRd2RdDD               : 0x%x\n", MemConfig->tRd2RdDR,
> MemConfig->tRd2RdDD));
> +  DEBUG ((DEBUG_INFO, " tRd2WrSG               : 0x%x\n
> tRd2WrDG               : 0x%x\n", MemConfig->tRd2WrSG,
> MemConfig->tRd2WrDG));
> +  DEBUG ((DEBUG_INFO, " tRd2WrDR               : 0x%x\n
> tRd2WrDD               : 0x%x\n", MemConfig->tRd2WrDR,
> MemConfig->tRd2WrDD));
> +  DEBUG ((DEBUG_INFO, " tWr2RdSG               : 0x%x\n
> tWr2RdDG               : 0x%x\n", MemConfig->tWr2RdSG,
> MemConfig->tWr2RdDG));
> +  DEBUG ((DEBUG_INFO, " tWr2RdDR               : 0x%x\n
> tWr2RdDD               : 0x%x\n", MemConfig->tWr2RdDR,
> MemConfig->tWr2RdDD));
> +  DEBUG ((DEBUG_INFO, " tWr2WrSG               : 0x%x\n
> tWr2WrDG               : 0x%x\n", MemConfig->tWr2WrSG,
> MemConfig->tWr2WrDG));
> +  DEBUG ((DEBUG_INFO, " tWr2WrDR               : 0x%x\n
> tWr2WrDD               : 0x%x\n", MemConfig->tWr2WrDR,
> MemConfig->tWr2WrDD));
> +  DEBUG ((DEBUG_INFO, "------------------------ OVERCLOCKING_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> OcPreMemConfig->Header.Revision));
> +  ASSERT (OcPreMemConfig->Header.Revision ==
> SA_OVERCLOCKING_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " OcSupport : 0x%x\n",
> OcPreMemConfig->OcSupport));
> +  DEBUG ((DEBUG_INFO, " GtMaxOcRatio : 0x%x\n",
> OcPreMemConfig->GtMaxOcRatio));
> +  DEBUG ((DEBUG_INFO, " GtVoltageMode : 0x%x\n",
> OcPreMemConfig->GtVoltageMode));
> +  DEBUG ((DEBUG_INFO, " GtVoltageOffset : 0x%x\n",
> OcPreMemConfig->GtVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " GtVoltageOverride : 0x%x\n",
> OcPreMemConfig->GtVoltageOverride));
> +  DEBUG ((DEBUG_INFO, " GtExtraTurboVoltage : 0x%x\n",
> OcPreMemConfig->GtExtraTurboVoltage));
> +  DEBUG ((DEBUG_INFO, " SaVoltageOffset : 0x%x\n",
> OcPreMemConfig->SaVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " GtusMaxOcRatio : 0x%x\n",
> OcPreMemConfig->GtusMaxOcRatio));
> +  DEBUG ((DEBUG_INFO, " GtusVoltageMode : 0x%x\n",
> OcPreMemConfig->GtusVoltageMode));
> +  DEBUG ((DEBUG_INFO, " GtusVoltageOffset : 0x%x\n",
> OcPreMemConfig->GtusVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " GtusVoltageOverride : 0x%x\n",
> OcPreMemConfig->GtusVoltageOverride));
> +  DEBUG ((DEBUG_INFO, " GtusExtraTurboVoltage : 0x%x\n",
> OcPreMemConfig->GtusExtraTurboVoltage));
> +  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
> +    DEBUG ((DEBUG_INFO, " DqByteMapCh%d        : ", Index));
> +    for (Index2 = 0; Index2 < SA_MRC_ITERATION_MAX; Index2++) {
> +      DEBUG ((DEBUG_INFO, "0x%02x ",
> MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][0]));
> +      DEBUG ((DEBUG_INFO, "0x%02x ",
> MemConfigNoCrc->DqByteMap->DqByteMap[Index][Index2][1]));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +  for (Index = 0; Index < SA_MC_MAX_CHANNELS; Index++) {
> +    DEBUG ((DEBUG_INFO, " DqsMapCpu2DramCh%d   : ", Index));
> +    for (Index2 = 0; Index2 < SA_MC_MAX_BYTES_NO_ECC; Index2++) {
> +      DEBUG ((DEBUG_INFO, "%d ",
> MemConfigNoCrc->DqsMap->DqsMapCpu2Dram[Index][Index2]));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI PreMem) Print
> END -----------------\n"));
> +  DEBUG_CODE_END ();
> +  return;
> +}
> +
> +/**
> +  This function prints the PEI phase policy.
> +
> +  @param[in] SiPolicyPpi - Instance of SI_POLICY_PPI
> +**/
> +VOID
> +EFIAPI
> +SaPrintPolicyPpi (
> +  IN  SI_POLICY_PPI     *SiPolicyPpi
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  INTN                                  Index;
> +  EFI_STATUS                            Status;
> +  GRAPHICS_PEI_CONFIG                   *GtConfig;
> +  PCIE_PEI_CONFIG                       *PciePeiConfig;
> +  SA_MISC_PEI_CONFIG                    *MiscPeiConfig;
> +  //
> +  // Get requisite IP Config Blocks which needs to be used here
> +  //
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid,
> (VOID *) &GtConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID
> *) &PciePeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid,
> (VOID *) &MiscPeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print BEGIN
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n",
> SiPolicyPpi->TableHeader.Header.Revision));
> +  ASSERT (SiPolicyPpi->TableHeader.Header.Revision ==
> SI_POLICY_REVISION);
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ SA_MISC_PEI_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> MiscPeiConfig->Header.Revision));
> +  ASSERT (MiscPeiConfig->Header.Revision ==
> SA_MISC_PEI_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " ChapDeviceEnable : 0x%x\n",
> MiscPeiConfig->ChapDeviceEnable));
> +  DEBUG ((DEBUG_INFO, " Device4Enable : 0x%x\n",
> MiscPeiConfig->Device4Enable));
> +  DEBUG ((DEBUG_INFO, " CridEnable : 0x%x\n",
> MiscPeiConfig->CridEnable));
> +  DEBUG ((DEBUG_INFO, " SkipPamLock : 0x%x\n",
> MiscPeiConfig->SkipPamLock));
> +  DEBUG ((DEBUG_INFO, " EdramTestMode : 0x%x\n",
> MiscPeiConfig->EdramTestMode));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ GRAPHICS_PEI_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n", GtConfig->Header.Revision));
> +  ASSERT (GtConfig->Header.Revision == GRAPHICS_PEI_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " RenderStandby : 0x%x\n",
> GtConfig->RenderStandby));
> +  DEBUG ((DEBUG_INFO, " PmSupport : 0x%x\n", GtConfig->PmSupport));
> +  DEBUG ((DEBUG_INFO, " PavpEnable : 0x%x\n", GtConfig->PavpEnable));
> +  DEBUG ((DEBUG_INFO, " CdClock : 0x%x\n", GtConfig->CdClock));
> +  DEBUG ((DEBUG_INFO, " PeiGraphicsPeimInit : 0x%x\n",
> GtConfig->PeiGraphicsPeimInit));
> +  DEBUG ((DEBUG_INFO, " LogoPtr : 0x%x\n", GtConfig->LogoPtr));
> +  DEBUG ((DEBUG_INFO, " LogoSize : 0x%x\n", GtConfig->LogoSize));
> +  DEBUG ((DEBUG_INFO, " BltBufferAddress : 0x%x\n",
> GtConfig->BltBufferAddress));
> +  DEBUG ((DEBUG_INFO, " BltBufferSize : 0x%x\n", GtConfig->BltBufferSize));
> +  DEBUG ((DEBUG_INFO, " GraphicsConfigPtr : 0x%x\n",
> GtConfig->GraphicsConfigPtr));
> +  DEBUG ((DEBUG_INFO, " CdynmaxClampEnable : 0x%x\n",
> GtConfig->CdynmaxClampEnable));
> +  DEBUG ((DEBUG_INFO, " GtFreqMax : 0x%x\n", GtConfig->GtFreqMax));
> +  DEBUG ((DEBUG_INFO, " DisableTurboGt : 0x%x\n",
> GtConfig->DisableTurboGt));
> +  DEBUG ((DEBUG_INFO, " DdiPortEdp  : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortEdp));
> +  DEBUG ((DEBUG_INFO, " DdiPortBHpd : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortBHpd));
> +  DEBUG ((DEBUG_INFO, " DdiPortCHpd : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortCHpd));
> +  DEBUG ((DEBUG_INFO, " DdiPortDHpd : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortDHpd));
> +  DEBUG ((DEBUG_INFO, " DdiPortFHpd : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortFHpd));
> +  DEBUG ((DEBUG_INFO, " DdiPortBDdc : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortBDdc));
> +  DEBUG ((DEBUG_INFO, " DdiPortCDdc : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortCDdc));
> +  DEBUG ((DEBUG_INFO, " DdiPortDDdc : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortDDdc));
> +  DEBUG ((DEBUG_INFO, " DdiPortFDdc : 0x%x\n",
> GtConfig->DdiConfiguration.DdiPortFDdc));
> +  DEBUG ((DEBUG_INFO, " SkipS3CdClockInit : 0x%x\n",
> GtConfig->SkipS3CdClockInit));
> +
> +  DEBUG ((DEBUG_INFO, "------------------------ PCIE_PEI_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n",
> PciePeiConfig->Header.Revision));
> +  ASSERT (PciePeiConfig->Header.Revision ==
> SA_PCIE_PEI_CONFIG_REVISION);
> +  DEBUG ((DEBUG_INFO, " DmiExtSync : 0x%x\n",
> PciePeiConfig->DmiExtSync));
> +  DEBUG ((DEBUG_INFO, " DmiIot : 0x%x\n", PciePeiConfig->DmiIot));
> +  DEBUG ((DEBUG_INFO, " DmiAspm : 0x%x\n", PciePeiConfig->DmiAspm));
> +  DEBUG ((DEBUG_INFO, "\n PegSlotPowerLimitValue[%d] :",
> SA_PEG_MAX_FUN));
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiConfig->PegSlotPowerLimitValue[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegSlotPowerLimitScale[%d] :",
> SA_PEG_MAX_FUN));
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiConfig->PegSlotPowerLimitScale[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegPhysicalSlotNumber[%d] :",
> SA_PEG_MAX_FUN));
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x",
> PciePeiConfig->PegPhysicalSlotNumber[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegDeEmphasis[%d] :", SA_PEG_MAX_FUN));
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegDeEmphasis[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n PegMaxPayload[%d] :", SA_PEG_MAX_FUN));
> +  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +    DEBUG ((DEBUG_INFO, " 0x%x", PciePeiConfig->PegMaxPayload[Index]));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +
> +  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (PEI) Print END
> -----------------\n"));
> +  DEBUG_CODE_END ();
> +  return;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.S
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.S
> new file mode 100644
> index 0000000000..97b58c460f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.S
> @@ -0,0 +1,114 @@
> +## @file
> +//
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +//-----------------------------------------------------------------------------
> +//
> +//  Section:     SaMmioRead64
> +//
> +//  Description: Read 64 bits from the Memory Mapped I/O space.
> +//  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +//
> +//  @param[in] Address - Memory mapped I/O address.
> +//
> +//-----------------------------------------------------------------------------
> +//UINT64
> +//SaMmioRead64 (
> +//  IN  UINTN Address
> +//  )
> +
> +ASM_GLOBAL ASM_PFX(SaMmioRead64)
> +ASM_PFX(SaMmioRead64):
> +   subl    $16, %esp
> +   movq    %mm0, (%esp)       //Save mm0 on stack
> +   movl    20(%esp), %edx     //edx = Address
> +   movq    (%edx), %mm0       //mm0 = [Address]
> +   movq    %mm0, 8(%esp)      //Store mm0 on Stack
> +   movq    (%esp), %mm0       //Restore mm0
> +   emms
> +   movl    8(%esp), %eax      //eax = [Address][31:0]
> +   movl    12(%esp), %edx     //edx = [Address][64:32]
> +   addl    $16, %esp
> +   ret
> +
> +//-----------------------------------------------------------------------------
> +//
> +//  Section:     SaMmioWrite64
> +//
> +//  Description: Write 64 bits to the Memory Mapped I/O space.
> +//  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +//
> +//  @param[in] Address - Memory mapped I/O address.
> +//  @param[in] Value   - The value to write.
> +//
> +//-----------------------------------------------------------------------------
> +
> +//UINT64
> +//SaMmioWrite64 (
> +//  IN UINTN Address,
> +//  IN UINT64 Value
> +//  )
> +
> +ASM_GLOBAL ASM_PFX(SaMmioWrite64)
> +ASM_PFX(SaMmioWrite64):
> +   subl    $8, %esp
> +   movq    %mm0, (%esp)       //Save mm0 on Stack
> +   movl    12(%esp), %edx     //edx = Address
> +   movq    16(%esp), %mm0     //mm0 = Value
> +   movq    %mm0, (%edx)       //[Address] = Value
> +   movq    (%esp), %mm0       //Restore mm0
> +   emms
> +   movl     16(%esp), %eax    //eax = Value[31:0]
> +   movl     20(%esp), %edx    //edx = Value[64:32]
> +   addl     $8, %esp
> +   ret
> +
> +//-----------------------------------------------------------------------------
> +//  Intel Silicon View Technology check point interface based on IO port
> reading
> +//
> +//  @param CheckPoint        Check point AH value.
> +//                           AH = 0x10:  End of MRC State
> +//                           AH = 0x20:  End of DXE State
> +//                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
> +//                           AH = 0x40:  After OS booting, need a timer SMI trigger
> to implement (TBD);
> +//
> +//  @param PortReading       IO port reading address used for breakpoints
> +//-----------------------------------------------------------------------------
> +
> +//VOID
> +//EFIAPI
> +//IsvtCheckPoint (
> +//  IN UINT32          CheckPoint,
> +//  IN UINT32          PortReading
> +//  )
> +
> +ASM_GLOBAL ASM_PFX(IsvtCheckPoint)
> +ASM_PFX(IsvtCheckPoint):
> +   pushl    %eax
> +   pushl    %edx
> +
> +   // Stack layout at this point:
> +   //-------------
> +   // PortReading     ESP + 16
> +   //-------------
> +   // CheckPoint      ESP + 12
> +   //-------------
> +   // EIP             ESP + 8
> +   //-------------
> +   // EAX             ESP + 4
> +   //-------------
> +   // EDX         <-- ESP
> +   //-------------
> +
> +   mov      12(%esp), %ah    // CheckPoint
> +   mov      16(%esp), %dx    // PortReading
> +   in       %dx, %al         // signal debugger
> +
> +   popl     %edx
> +   popl     %eax
> +   ret
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.asm
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.asm
> new file mode 100644
> index 0000000000..288fe7a2fe
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.asm
> @@ -0,0 +1,126 @@
> +; @file
> +;  This file provides assembly 64-bit atomic reads/writes required for memory
> initialization.
> +;
> +; Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +.686p
> +.xmm
> +.model small, c
> +
> +.CODE
> +
> +;-----------------------------------------------------------------------------
> +;
> +;  Section:     SaMmioRead64
> +;
> +;  Description: Read 64 bits from the Memory Mapped I/O space.
> +;  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +;
> +;  @param[in] Address - Memory mapped I/O address.
> +;
> +;-----------------------------------------------------------------------------
> +
> +;UINT64
> +;SaMmioRead64 (
> +;  IN  UINTN Address
> +;  )
> +
> +SaMmioRead64    PROC    NEAR    PUBLIC
> +   sub     esp, 16
> +   movq    [esp], mm0         ;Save mm0 on stack
> +   mov     edx,  [esp + 20]   ;edx = Address
> +   movq    mm0, [edx]         ;mm0 = [Address]
> +   movq    [esp + 8], mm0     ;Store mm0 on Stack
> +   movq    mm0, [esp]         ;Restore mm0
> +   emms
> +   mov     eax, [esp + 8]     ;eax = [Address][31:0]
> +   mov     edx, [esp + 12]    ;edx = [Address][64:32]
> +   add     esp, 16
> +   ret
> +SaMmioRead64    ENDP
> +
> +;-----------------------------------------------------------------------------
> +;
> +;  Section:     SaMmioWrite64
> +;
> +;  Description: Write 64 bits to the Memory Mapped I/O space.
> +;  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +;
> +;  @param[in] Address - Memory mapped I/O address.
> +;  @param[in] Value   - The value to write.
> +;
> +;-----------------------------------------------------------------------------
> +
> +;UINT64
> +;SaMmioWrite64 (
> +;  IN UINTN Address,
> +;  IN UINT64 Value
> +;  )
> +
> +SaMmioWrite64    PROC    NEAR    PUBLIC
> +   sub     esp, 8
> +   movq    [esp], mm0          ;Save mm0 on Stack
> +   mov     edx, [esp + 12]     ;edx = Address
> +   movq    mm0, [esp + 16]     ;mm0 = Value
> +   movq    [edx], mm0          ;[Address] = Value
> +   movq    mm0, [esp]          ;Restore mm0
> +   emms
> +   mov     eax, [esp + 16]     ;eax = Value[31:0]
> +   mov     edx, [esp + 20]     ;edx = Value[64:32]
> +   add     esp, 8
> +   ret
> +SaMmioWrite64    ENDP
> +
> +
> +;-----------------------------------------------------------------------------
> +;  Intel Silicon View Technology check point interface based on IO port reading
> +;
> +;  @param CheckPoint        Check point AH value.
> +;                           AH = 0x10:  End of MRC State
> +;                           AH = 0x20:  End of DXE State
> +;                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
> +;                           AH = 0x40:  After OS booting, need a timer SMI trigger to
> implement (TBD);
> +;
> +;  @param PortReading       IO port reading address used for breakpoints
> +;-----------------------------------------------------------------------------
> +
> +;VOID
> +;EFIAPI
> +;IsvtCheckPoint (
> +;  IN UINT32          CheckPoint,
> +;  IN UINT32          PortReading
> +;  )
> +
> +IsvtCheckPoint    PROC    NEAR    PUBLIC
> +   push eax
> +   push edx
> +
> +   ; Stack layout at this point:
> +   ;-------------
> +   ; PortReading     ESP + 16
> +   ;-------------
> +   ; CheckPoint      ESP + 12
> +   ;-------------
> +   ; EIP             ESP + 8
> +   ;-------------
> +   ; EAX             ESP + 4
> +   ;-------------
> +   ; EDX         <-- ESP
> +   ;-------------
> +
> +   mov  ah, BYTE PTR [esp + 12]      ; CheckPoint
> +   mov  dx, WORD PTR [esp + 16]      ; PortReading
> +   in   al, dx                       ; signal debugger
> +
> +   pop  edx
> +   pop  eax
> +   ret
> +IsvtCheckPoint    ENDP
> +
> +
> +end
> +
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.nasm
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.nasm
> new file mode 100644
> index 0000000000..da7ef004ad
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia3
> 2/MrcOemPlatform.nasm
> @@ -0,0 +1,118 @@
> +; @file
> +;  This file provides assembly 64-bit atomic reads/writes required for memory
> initialization.
> +;
> +; Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +SECTION .text
> +
> +;-----------------------------------------------------------------------------
> +;
> +;  Section:     SaMmioRead64
> +;
> +;  Description: Read 64 bits from the Memory Mapped I/O space.
> +;  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +;
> +;  @param[in] Address - Memory mapped I/O address.
> +;
> +;-----------------------------------------------------------------------------
> +
> +;UINT64
> +;SaMmioRead64 (
> +;  IN  UINTN Address
> +;  )
> +
> +global ASM_PFX(SaMmioRead64)
> +ASM_PFX(SaMmioRead64):
> +   sub     esp, 16
> +   movq    [esp], mm0         ;Save mm0 on stack
> +   mov     edx,  [esp + 20]   ;edx = Address
> +   movq    mm0, [edx]         ;mm0 = [Address]
> +   movq    [esp + 8], mm0     ;Store mm0 on Stack
> +   movq    mm0, [esp]         ;Restore mm0
> +   emms
> +   mov     eax, [esp + 8]     ;eax = [Address][31:0]
> +   mov     edx, [esp + 12]    ;edx = [Address][64:32]
> +   add     esp, 16
> +   ret
> +
> +;-----------------------------------------------------------------------------
> +;
> +;  Section:     SaMmioWrite64
> +;
> +;  Description: Write 64 bits to the Memory Mapped I/O space.
> +;  Use MMX instruction for atomic access, because some MC registers have
> side effect.
> +;
> +;  @param[in] Address - Memory mapped I/O address.
> +;  @param[in] Value   - The value to write.
> +;
> +;-----------------------------------------------------------------------------
> +
> +;UINT64
> +;SaMmioWrite64 (
> +;  IN UINTN Address,
> +;  IN UINT64 Value
> +;  )
> +
> +global ASM_PFX(SaMmioWrite64)
> +ASM_PFX(SaMmioWrite64):
> +   sub     esp, 8
> +   movq    [esp], mm0          ;Save mm0 on Stack
> +   mov     edx, [esp + 12]     ;edx = Address
> +   movq    mm0, [esp + 16]     ;mm0 = Value
> +   movq    [edx], mm0          ;[Address] = Value
> +   movq    mm0, [esp]          ;Restore mm0
> +   emms
> +   mov     eax, [esp + 16]     ;eax = Value[31:0]
> +   mov     edx, [esp + 20]     ;edx = Value[64:32]
> +   add     esp, 8
> +   ret
> +
> +;-----------------------------------------------------------------------------
> +;  Intel Silicon View Technology check point interface based on IO port reading
> +;
> +;  @param CheckPoint        Check point AH value.
> +;                           AH = 0x10:  End of MRC State
> +;                           AH = 0x20:  End of DXE State
> +;                           AH = 0x30:  Ready to boot before INT-19h or UEFI boot
> +;                           AH = 0x40:  After OS booting, need a timer SMI trigger to
> implement (TBD);
> +;
> +;  @param PortReading       IO port reading address used for breakpoints
> +;-----------------------------------------------------------------------------
> +
> +;VOID
> +;EFIAPI
> +;IsvtCheckPoint (
> +;  IN UINT32          CheckPoint,
> +;  IN UINT32          PortReading
> +;  )
> +
> +global ASM_PFX(IsvtCheckPoint)
> +ASM_PFX(IsvtCheckPoint):
> +   push eax
> +   push edx
> +
> +   ; Stack layout at this point:
> +   ;-------------
> +   ; PortReading     ESP + 16
> +   ;-------------
> +   ; CheckPoint      ESP + 12
> +   ;-------------
> +   ; EIP             ESP + 8
> +   ;-------------
> +   ; EAX             ESP + 4
> +   ;-------------
> +   ; EDX         <-- ESP
> +   ;-------------
> +
> +   mov  ah, BYTE [esp + 12]      ; CheckPoint
> +   mov  dx, WORD [esp + 16]      ; PortReading
> +   in   al, dx                   ; signal debugger
> +
> +   pop  edx
> +   pop  eax
> +   ret
> +
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI private library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:14 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI
> private library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH PEI private library class instances. These library instances
> may be compatible with other boot phases as indicated by the library type.
> 
> * PeiDxeSmmGpioPrivateLibCnl
> * PeiDxeSmmPchDmiLib
> * PeiDxeSmmPchDmiWithS3Lib
> * PeiDxeSmmPchInitCommonLib
> * PeiDxeSmmPchPciExpressHelpersLib
> * PeiDxeSmmPchPsfPrivateLibCnl
> * PeiDxeSmmPmcPrivateLibCnl
> * PeiDxeSmmPmcPrivateLibWithS3
> * PeiGpioHelpersLib
> * PeiGpioNameBufferLib
> * PeiPmcPrivateLibCnl
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/PeiDxeSmmGpioPrivateLibCnl.inf                |   45 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PeiDxeSmmPchDmiLib.inf                             |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PeiDxeSmmPchDmiWithS3Lib.inf                       |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCo
> mmonLib/PeiDxeSmmPchInitCommonLib.inf               |   34 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpr
> essHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf |   42 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPriv
> ateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf            |   41 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PeiDxeSmmPmcPrivateLibCnl.inf                  |   48 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PeiDxeSmmPmcPrivateLibWithS3.inf               |   39 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PeiPmcPrivateLibCnl.inf                        |   40 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/Pei
> GpioHelpersLib.inf                               |   42 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLi
> b/PeiGpioNameBufferLib.inf                         |   35 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/GpioNativePrivateLibInternal.h                |  477 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PchDmi14.h                                         |   70 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PchDmi15.h                                         |  113 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpr
> essHelpersLib/PchPciExpressHelpersLibrary.h        |   42 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPriv
> ateLib/PchPsfPrivateLibInternal.h                  |  490 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PmcPrivateLibInternal.h                        |   47 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/GpioNamesCnl.c                                |  166 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/GpioNativePrivateLib.c                        | 1304 +++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/GpioNativePrivateLibCnl.c                     | 2275 ++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/GpioPrivateLib.c                              |  752 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivat
> eLib/GpioPrivateLibCnl.c                           |  225 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PchDmi14.c                                         |   67 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PchDmi15.c                                         |  113 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PchDmiLib.c                                        |  569 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib
> /PchDmiWithS3Lib.c                                  |   79 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCo
> mmonLib/PchInitCommon.c                             |  221 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpr
> essHelpersLib/PchPciExpressHelpersLibrary.c        | 2407
> ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPriv
> ateLib/PchPsfPrivateLib.c                          |  542 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPriv
> ateLib/PchPsfPrivateLibCnl.c                       |  338 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PeiPmcPrivateLib.c                             |   92 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PmcPrivateLib.c                                | 1033 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PmcPrivateLibClient.c                          |   73 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PmcPrivateLibCnl.c                             |  360 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivat
> eLib/PmcPrivateLibWithS3.c                          |  194 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/Pei
> GpioHelpersLib.c                                 |  356 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLi
> b/GpioNameBufferPei.c                              |   68 +
>  37 files changed, 12919 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/PeiDxeSmmGpioPrivateLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/PeiDxeSmmGpioPrivateLibCnl.inf
> new file mode 100644
> index 0000000000..318b54a99c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/PeiDxeSmmGpioPrivateLibCnl.inf
> @@ -0,0 +1,45 @@
> +## @file
> +#  Component description file for the PeiDxeSmmGpioPrivateLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION                    = 0x00010017
> +BASE_NAME                      = PeiDxeSmmGpioPrivateLibCnl
> +FILE_GUID                      = E078A734-BEA0-47CF-A476-3742316D01FC
> +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
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +  GpioPrivateLib.c
> +  GpioNativePrivateLib.c
> +  GpioPrivateLibCnl.c
> +  GpioNativePrivateLibCnl.c
> +  GpioNamesCnl.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PeiDxeSmmPchDmiLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PeiDxeSmmPchDmiLib.inf
> new file mode 100644
> index 0000000000..b36fc15901
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PeiDxeSmmPchDmiLib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +#  Component description file for the PeiDxeSmmPchDmiLib
> +#
> +# Copyright (c) 2019 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
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +  PchDmiLib.c
> +  PchDmi14.c
> +  PchDmi15.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PeiDxeSmmPchDmiWithS3Lib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PeiDxeSmmPchDmiWithS3Lib.inf
> new file mode 100644
> index 0000000000..1eda7cdba8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PeiDxeSmmPchDmiWithS3Lib.inf
> @@ -0,0 +1,40 @@
> +## @file
> +#  Component description file for the PeiDxeSmmPchDmiWithS3Lib
> +#
> +# Copyright (c) 2019 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
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +  PchDmiWithS3Lib.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitC
> ommonLib/PeiDxeSmmPchInitCommonLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitC
> ommonLib/PeiDxeSmmPchInitCommonLib.inf
> new file mode 100644
> index 0000000000..d81c428a1c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitC
> ommonLib/PeiDxeSmmPchInitCommonLib.inf
> @@ -0,0 +1,34 @@
> +## @file
> +#  Component description file for the PchInitCommonLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiDxeSmmPchInitCommonLib
> +  FILE_GUID                      = E9C4FE04-8A79-43FA-B3E0-603359C31B43
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PchInitCommonLib
> +
> +[Sources]
> +  PchInitCommon.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  IoLib
> +  DebugLib
> +  PciSegmentLib
> +  PchCycleDecodingLib
> +  PchPcieRpLib
> +  PchSbiAccessLib
> +  PchInfoLib
> +  SataLib
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
> new file mode 100644
> index 0000000000..16b1c019b8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# Component description file for the PeiDxeSmmPchPciExpressHelpersLib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPchPciExpressHelpersLib
> +FILE_GUID = 07E3F76D-6D26-419d-9053-58696A15B519
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PchPciExpressHelpersLib
> +#
> +# 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
> +PchInitCommonLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchPciExpressHelpersLibrary.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
> new file mode 100644
> index 0000000000..0ed9f30dcc
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
> @@ -0,0 +1,41 @@
> +## @file
> +#  PEI/DXE/SMM PCH PSF Private Lib for Cannon Lake PCH
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION                    = 0x00010017
> +BASE_NAME                      = PeiDxeSmmPchPsfPrivateLibCnl
> +FILE_GUID                      = 7A6C18CA-0353-433E-885D-DD68BFAD38BE
> +VERSION_STRING                 = 1.0
> +MODULE_TYPE                    = BASE
> +LIBRARY_CLASS                  = PchPsfPrivateLib
> +#
> +# 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
> +  SaPlatformLib
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +  PchPsfPrivateLib.c
> +  PchPsfPrivateLibCnl.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiDxeSmmPmcPrivateLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiDxeSmmPmcPrivateLibCnl.inf
> new file mode 100644
> index 0000000000..adb154dd14
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiDxeSmmPmcPrivateLibCnl.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# PEI/DXE/SMM PCH PMC Private Lib for Cannon Lake PCH.
> +#
> +# All function in this library is available for PEI, DXE, and SMM,
> +# But do not support UEFI RUNTIME environment call.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmPmcPrivateLibCnl
> +FILE_GUID = A1CB52AD-4FAB-4214-94A0-323E3BE4E934
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = PmcPrivateLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +TimerLib
> +PciSegmentLib
> +PchInfoLib
> +PchPcrLib
> +PmcLib
> +PchPsfPrivateLib
> +PchDmiLib
> +SataLib
> +BaseMemoryLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
> +
> +
> +[Sources]
> +PmcPrivateLib.c
> +PmcPrivateLibClient.c
> +PmcPrivateLibCnl.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
> new file mode 100644
> index 0000000000..cd1380dc43
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
> @@ -0,0 +1,39 @@
> +## @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) 2019 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
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PmcPrivateLibWithS3.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiPmcPrivateLibCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiPmcPrivateLibCnl.inf
> new file mode 100644
> index 0000000000..ab3645c61d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiPmcPrivateLibCnl.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# PEI PCH PMC Private Lib for Cannon Lake PCH.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiPmcPrivateLibCnl
> +FILE_GUID = 1DD4EA23-12F2-4F05-93AF-535476106D8C
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = PeiPmcPrivateLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +BaseMemoryLib
> +IoLib
> +DebugLib
> +PeiServicesLib
> +PciSegmentLib
> +ConfigBlockLib
> +PchInfoLib
> +PchPcrLib
> +PmcLib
> +PmcPrivateLib
> +PchEspiLib
> +GpioPrivateLib
> +PeiItssLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +PeiPmcPrivateLib.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/
> PeiGpioHelpersLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/
> PeiGpioHelpersLib.inf
> new file mode 100644
> index 0000000000..b6f786d80b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/
> PeiGpioHelpersLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# Component description file for the PeiGpioHelpersLib
> +#
> +# Copyright (c) 2019 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
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PeiGpioHelpersLib.c
> +
> +
> +[Guids]
> +gGpioLibUnlockHobGuid
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffer
> Lib/PeiGpioNameBufferLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffer
> Lib/PeiGpioNameBufferLib.inf
> new file mode 100644
> index 0000000000..3619a2e6a7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffer
> Lib/PeiGpioNameBufferLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +# Component description file for the PeiGpioMemLib
> +#
> +# Copyright (c) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +GpioNameBufferPei.c
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLibInternal.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLibInternal.h
> new file mode 100644
> index 0000000000..e081027c40
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLibInternal.h
> @@ -0,0 +1,477 @@
> +/** @file
> +  Header file for GPIO Private Lib Internal functions.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
> +#define _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
> +
> +#include <Private/Library/GpioPrivateLib.h>
> +
> +#define GPIO_PAD_NONE 0
> +
> +/**
> +  This function provides SerialIo I2C controller pins
> +
> +  @param[in]  SerialIoI2cControllerNumber    I2C controller
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetSerialIoI2cPins (
> +  IN  UINT32                      SerialIoI2cControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides SerialIo UART controller pins
> +
> +  @param[in]  SerialIoUartControllerNumber   UART controller
> +  @param[in]  HardwareFlowControl            Hardware Flow control
> +  @param[in]  PinMuxing                      UART controller pin muxing
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetSerialIoUartPins (
> +  IN  UINT32                      SerialIoUartControllerNumber,
> +  IN  BOOLEAN                     HardwareFlowControl,
> +  IN  UINT32                      PinMuxing,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides SerialIo SPI controller pins
> +
> +  @param[in]  SerialIoSpiControllerNumber   SPI controller
> +
> +  @param[out] NativePinsTable               Table with pins
> +  @param[out] NoOfNativePins                Number of pins
> +**/
> +VOID
> +GpioGetSerialIoSpiPins (
> +  IN  UINT32                      SerialIoSpiControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides ISH GP pin data
> +
> +  @param[in]  IshGpPinNumber        ISH GP pin number
> +
> +  @param[out] NativePin             ISH GP pin
> +**/
> +VOID
> +GpioGetIshGpPin (
> +  IN  UINT32                      IshGpPinNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
> +  );
> +
> +/**
> +  This function provides ISH UART controller pins
> +
> +  @param[in]  IshUartControllerNumber   ISH UART controller
> +
> +  @param[out] NativePinsTable           Table with pins
> +**/
> +VOID
> +GpioGetIshUartPins (
> +  IN  UINT32                      IshUartControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides ISH I2C controller pins
> +
> +  @param[in]  IshI2cControllerNumber   ISH I2C controller
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetIshI2cPins (
> +  IN  UINT32                      IshI2cControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides ISH SPI controller pins
> +
> +  @param[in]  IshSpiControllerNumber   SPI controller
> +  @param[out] NativePinsTable          Table with pins
> +  @param[out] NoOfNativePins           Number of pins
> +**/
> +VOID
> +GpioGetIshSpiPins (
> +  IN  UINT32                      IshSpiControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides SCS SD CARD controller pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetScsSdCardPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides SCS SD CARD detect pin
> +
> +  @retval GpioPin             SD CARD Detect pin
> +**/
> +GPIO_PAD
> +GpioGetScsSdCardDetectPin (
> +  VOID
> +  );
> +
> +/**
> +  This function provides SCS eMMC controller pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetScsEmmcPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides HD Audio Link pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetHdAudioLinkPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides DMIC interface pins
> +
> +  @param[in]  DmicNumber               DMIC interface
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetHdaDmicPins (
> +  IN  UINT32                      DmicNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides SSP/I2S interface pins
> +
> +  @param[in]  SspInterfaceNumber       SSP/I2S interface
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetHdaSspPins (
> +  IN  UINT32                      SspInterfaceNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides SNDW interface pins
> +
> +  @param[in]  SndwInterfaceNumber      SNDWx interface number
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetHdaSndwPins (
> +  IN  UINT32                      SndwInterfaceNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides SMBUS interface pins
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetSmbusPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides SATA DevSlp pin data
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +  @param[in]  SataPort            SATA port number
> +  @param[out] NativePin           SATA DevSlp pin
> +**/
> +VOID
> +GpioGetSataDevSlpPin (
> +  IN  UINT32                    SataCtrlIndex,
> +  IN  UINTN                     SataPort,
> +  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
> +  );
> +
> +/**
> +  This function provides PCIe CLKREQ pin data
> +
> +  @param[in]  ClkreqIndex        CLKREQ# number
> +  @param[out] NativePin          Native pin data
> +**/
> +VOID
> +GpioGetPcieClkReqPin (
> +  IN  UINT32                      ClkreqIndex,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
> +  );
> +
> +/**
> +  This function provides eDP pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetEdpPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides DDPx interface pins
> +
> +  @param[in]  DdpInterface   DDPx interface
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetDdpPins (
> +  IN  GPIO_DDP                    DdpInterface,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  );
> +
> +/**
> +  This function provides CNVi BT UART pins
> +
> +  @param[in]  ConnectionType           CNVi BT UART connection type
> +  @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
> +  @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
> +  @param[out] VUartForCnviBtPad        Table with vUART0 pads
> +  @param[out] VUartForCnviBtPadMode    vUART0 pad mode
> +**/
> +VOID
> +GpioGetCnviBtUartPins (
> +  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
> +  OUT GPIO_PAD                            **VCnviBtUartPad,
> +  OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
> +  OUT GPIO_PAD                            **VUartForCnviBtPad,
> +  OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
> +  );
> +
> +/**
> +  This function provides CNVi BT UART external pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnviBtUartExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  );
> +
> +/**
> +  This function provides CNVi BT I2S pins
> +
> +  @param[in]  ConnectionType          CNVi BT I2S connection type
> +  @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
> +  @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
> +  @param[out] VSspForCnviBtPad        Table with vSSP2 pads
> +  @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
> +**/
> +VOID
> +GpioGetCnviBtI2sPins (
> +  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
> +  OUT GPIO_PAD                 **VCnviBtI2sPad,
> +  OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
> +  OUT GPIO_PAD                 **VSspForCnviBtPad,
> +  OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
> +  );
> +
> +/**
> +  This function provides CNVi BT I2S external pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnviBtI2sExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  );
> +
> +/**
> +  This function provides CNVi MFUART1 pins
> +
> +  @param[in]  ConnectionType          CNVi MFUART1 connection type
> +  @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
> +  @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
> +  @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
> +  @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
> +**/
> +VOID
> +GpioGetCnviMfUart1Pins (
> +  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
> +  OUT GPIO_PAD                 **VCnviMfUart1Pad,
> +  OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
> +  OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
> +  OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
> +  );
> +
> +/**
> +  This function provides CNVi MFUART1 external pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnviMfUart1ExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  );
> +
> +/**
> +  This function provides CNVi Bluetooth Enable pad
> +
> +  @retval GpioPad           CNVi Bluetooth Enable pad
> +**/
> +GPIO_PAD
> +GpioGetCnviBtEnablePin (
> +  VOID
> +  );
> +
> +/**
> +  This function provides CNVi BRI RGI GPIO pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnvBriRgiPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  );
> +
> +/**
> +  This function provides CNVi MFUART2 external pins
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnvMfUart2ExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  );
> +
> +/**
> +  This function provides CNVi BT interface select pin
> +
> +  @retval GpioPad          GPIO pad for CNVi BT interface select
> +**/
> +GPIO_PAD
> +GpioGetCnviBtIfSelectPin (
> +  VOID
> +  );
> +
> +/**
> +  This function provides CNVi BT Charging pin
> +
> +  @retval GpioPad          GPIO pad for CNVi BT Charging select
> +**/
> +GPIO_PAD
> +GpioGetCnviBtChargingPin (
> +  VOID
> +  );
> +
> +/**
> +  This function provides CNVi A4WP pin
> +
> +  @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
> +**/
> +VOID
> +GpioGetCnviA4WpPin (
> +  OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
> +  );
> +
> +/**
> +  This function provides CNVi BT host wake int pin
> +
> +  @retval GpioPad          GPIO pad BT host wake int
> +**/
> +GPIO_PAD
> +GpioGetCnviBtHostWakeIntPin (
> +  VOID
> +  );
> +
> +/**
> +  This function provides IMGCLKOUT pins
> +
> +  @param[out] NativePinsTable          Table with pins
> +  @param[out] NoOfNativePins            Number of pins
> +**/
> +VOID
> +GpioGetImgClkOutPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
> +  OUT UINT32                   *NoOfNativePins
> +  );
> +
> +/**
> +  This function provides PWRBTN pin
> +
> +  @retval GpioPad          PWRTBTN pin
> +**/
> +GPIO_PAD
> +GpioGetPwrBtnPin (
> +  VOID
> +  );
> +
> +/**
> +  This procedure enables debounce feature on a selected pad configured in
> input mode
> +  Debounce time can be specified in microseconds. GPIO HW supports only
> certain values
> +  according to below formula:
> +   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 GPIO HW, function will round down
> +  to closest supported
> +
> +  @param[in] GpioPad              GPIO pad
> +  @param[in, out] DebounceTime    Debounce Time in microseconds
> +                                  If Debounce Time = 0, Debouncer feature will be
> disabled
> +                                  Function will set DebounceTime argument to
> rounded supported value
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid GpioPad or unsupported
> DebounceDuration value
> +  @retval EFI_UNSUPPORTED         GpioPad is not owned by host
> +**/
> +EFI_STATUS
> +GpioSetDebounceTimer (
> +  IN GPIO_PAD                  GpioPad,
> +  IN OUT UINT32                *DebounceTime
> +  );
> +
> +/**
> +  This function provides LPC pin
> +
> +  @retval GpioPad          LPC pin
> +**/
> +GPIO_PAD
> +GpioGetLpcPin (
> +  VOID
> +  );
> +
> +#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi14.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi14.h
> new file mode 100644
> index 0000000000..1d50c04b0f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi14.h
> @@ -0,0 +1,70 @@
> +/** @file
> +  Internal header file for PCH DMI library for SIP14
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __PCH_DMI_14_H__
> +#define __PCH_DMI_14_H__
> +
> +#include <Private/Library/PchDmiLib.h>
> +#include <Private/Library/PeiPchDmiLib.h>
> +
> +/**
> +  This function checks if DMI SIP14 Secured Register Lock (SRL) is set
> +
> +  @retval SRL state
> +**/
> +BOOLEAN
> +IsPchDmi14Locked (
> +  VOID
> +  );
> +
> +/**
> +  Enable PCIe Relaxed Order for DMI SIP14
> +**/
> +VOID
> +PchDmi14EnablePcieRelaxedOrder (
> +  VOID
> +  );
> +
> +/**
> +  This function will switch SAI value to be driven to IOSF Primary Fabric
> +  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
> +  To be used when PCH is paired with CFL CPU.
> +**/
> +VOID
> +PchDmi14EnablePostBootSai (
> +  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
> +  );
> +
> +/**
> +  Get PCH DMI SIP14 Virtual Channel Control and Status registers
> +
> +  @param[in]  Vc                   The virtual channel number for programing
> +  @param[out] DmiVcCtlAddress      DMI Virtual Channel Control register
> address
> +  @param[out] DmiVcStsAddress      DMI Virtual Channel Status register
> address
> +**/
> +VOID
> +PchDmi14VcRegs (
> +  IN   PCH_DMI_VC_TYPE  Vc,
> +  OUT  UINT16           *DmiVcCtlAddress,
> +  OUT  UINT16           *DmiVcStsAddress
> +  );
> +
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi15.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi15.h
> new file mode 100644
> index 0000000000..744a96fe14
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi15.h
> @@ -0,0 +1,113 @@
> +/** @file
> +  Internal header file for PCH DMI library for SIP15
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __PCH_DMI_15_H__
> +#define __PCH_DMI_15_H__
> +
> +#include <Private/Library/PchDmiLib.h>
> +#include <Private/Library/PeiPchDmiLib.h>
> +
> +/**
> +  This function checks if DMI SIP15 Secured Register Lock (SRL) is set
> +
> +  @retval SRL state
> +**/
> +BOOLEAN
> +IsPchDmi15Locked (
> +  VOID
> +  );
> +
> +/**
> +  Set DMI thermal throttling to recommended configuration.
> +  It's intended only for P-DMI SIP15.
> +**/
> +VOID
> +PchDmi15SetRecommendedThermalThrottling (
> +  VOID
> +  );
> +
> +/**
> +  Set DMI thermal throttling to custom configuration.
> +  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
> +  DMI Thermal Sensor Autonomous Width Enable.
> +  It's intended only for P-DMI SIP15.
> +
> +  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
> +**/
> +VOID
> +PchDmi15SetCustomThermalThrottling (
> +  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
> +  );
> +
> +/**
> +  Enable PCIe Relaxed Order for DMI SIP15
> +**/
> +VOID
> +PchDmi15EnablePcieRelaxedOrder (
> +  VOID
> +  );
> +
> +/**
> +  This function will switch SAI value to be driven to IOSF Primary Fabric
> +  for cycles with Core BDF from HOSTIA_BOOT_SAI to HOSTIA_POSTBOOT_SAI.
> +  To be used when PCH is paired with CFL CPU.
> +**/
> +VOID
> +PchDmi15EnablePostBootSai (
> +  VOID
> +  );
> +
> +/**
> +  This function will do necessary configuration after platform
> +  should have switched to POSTBOOT_SAI. It needs to be called even if
> +  POSTBOOT_SAI was not set.
> +**/
> +VOID
> +PchDmi15ConfigAfterPostBootSai (
> +  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
> +PchDmi15SrlRegData (
> +  OUT UINT16  *SrlRegOffset,
> +  OUT UINT32  *SrlRegMask
> +  );
> +
> +/**
> +  Get PCH DMI SIP15 Virtual Channel Control and Status registers
> +
> +  @param[in]  Vc                   The virtual channel number for programing
> +  @param[out] DmiVcCtlAddress      DMI Virtual Channel Control register
> address
> +  @param[out] DmiVcStsAddress      DMI Virtual Channel Status register
> address
> +**/
> +VOID
> +PchDmi15VcRegs (
> +  IN   PCH_DMI_VC_TYPE  Vc,
> +  OUT  UINT16           *DmiVcCtlAddress,
> +  OUT  UINT16           *DmiVcStsAddress
> +  );
> +
> +/**
> +  The function sets the Target Link Speed to GEN 3 in P-DMI SIP15.
> +
> +  @param[in] TargetLinkSpeed        Target Link Speed
> +                                    2: GEN2
> +                                    3: GEN3
> +**/
> +VOID
> +PchDmi15SetTargetLinkSpeed (
> +  IN  UINT8                 TargetLinkSpeed
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PchPciExpressHelpersLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PchPciExpressHelpersLibrary.h
> new file mode 100644
> index 0000000000..b14f24b18f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PchPciExpressHelpersLibrary.h
> @@ -0,0 +1,42 @@
> +/** @file
> +  Header file for PCH Pci Express helps library implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
> +#define _PCH_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 <Private/Library/PchPciExpressHelpersLib.h>
> +#include <Private/Library/PchPsfPrivateLib.h>
> +#include <Private/Library/PchInitCommonLib.h>
> +#include <PcieRegs.h>
> +#include <Register/PchRegsPcie.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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLibInternal.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLibInternal.h
> new file mode 100644
> index 0000000000..f633df0411
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLibInternal.h
> @@ -0,0 +1,490 @@
> +/** @file
> +  This file contains internal header for PSF lib usage
> +
> +  Copyright (c) 2019 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 <Private/Library/PchPsfPrivateLib.h>
> +#include <Register/PchRegsPcr.h>
> +
> +#define PSF_PORT_NULL ((PSF_PORT){0,0})
> +#define PSF_IS_PORT_NULL(PsfPort) ((PsfPort.PsfPid == 0) &&
> (PsfPort.RegBase == 0))
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Return PSF_PORT for HECI device
> +
> +  @param[in] HeciDevice      HECIx Device (HECI1-4)
> +
> +  @retval    PsfPort         PSF PORT structure for HECI device
> +**/
> +PSF_PORT
> +PsfHeciPort (
> +  IN UINT8      HeciDevice
> +  );
> +
> +/**
> +  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 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
> +
> +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
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  P2SB PSF port Destination ID (psf_id:port_group_id:port_id:channel_id)
> +
> +  @retval P2SB Destination ID
> +**/
> +PSF_PORT_DEST_ID
> +PsfP2sbDestinationId (
> +  VOID
> +  );
> +
> +/**
> +  DMI PSF port Destination ID (psf_id:port_group_id:port_id:channel_id)
> +
> +  @retval DMI Destination ID
> +**/
> +PSF_PORT_DEST_ID
> +PsfDmiDestinationId (
> +  VOID
> +  );
> +
> +/**
> +  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
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibInternal.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibInternal.h
> new file mode 100644
> index 0000000000..c08d1cf10d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibInternal.h
> @@ -0,0 +1,47 @@
> +/** @file
> +  Internal header file for PMC Private library
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PMC_PRIVATE_LIB_INTERNAL_H_
> +#define _PMC_PRIVATE_LIB_INTERNAL_H_
> +
> +/**
> +  Check if MODPHY SUS PG is supported
> +
> +  @retval  Status of MODPHY SUS PG support
> +**/
> +BOOLEAN
> +PmcIsModPhySusPgSupported (
> +  VOID
> +  );
> +
> +/**
> +  This function is part of PMC init and configures which clock wake signals
> should
> +  set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent
> up to the CPU/PCH
> +**/
> +VOID
> +PmcInitClockWakeEnable (
> +  VOID
> +  );
> +
> +/**
> +  This function configures PWRMBASE + 0x1E00 register
> +**/
> +VOID
> +PmcConfigureRegPwrm1E00 (
> +  VOID
> +  );
> +
> +/**
> +  This function configures Misc PM_SYNC events settings
> +**/
> +VOID
> +PmcConfigurePmSyncEventsSettings (
> +  VOID
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNamesCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNamesCnl.c
> new file mode 100644
> index 0000000000..5a4876bfeb
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNamesCnl.c
> @@ -0,0 +1,166 @@
> +/** @file
> +  This file contains GPIO name library implementation
> +
> +  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +
> +STATIC CONST CHAR8*  mGpioGppaNames[] = {
> +  "ESPI_CLK_LOOPBK"
> +};
> +
> +STATIC CONST CHAR8*  mGpioGppbNames[] = {
> +  "GSPI0_CLK_LOOPBK",
> +  "GSPI1_CLK_LOOPBK"
> +};
> +
> +STATIC CONST CHAR8*  mGpioGpdNames[] = {
> +  "SLP_LANB",
> +  "SLP_SUSB",
> +  "SLP_WAKEB",
> +  "SLP_DRAM_RESETB"
> +};
> +
> +STATIC CONST CHAR8*  mGpioGppiNames[] = {
> +  "SYS_PWROK",
> +  "SYS_RESETB",
> +  "MLK_RSTB"
> +};
> +
> +STATIC CONST CHAR8*  mGpioSpiNames[] = {
> +  "SPI0_IO_2",
> +  "SPI0_IO_3",
> +  "SPI0_MOSI_IO_0",
> +  "SPI0_MOSI_IO_1",
> +  "SPI0_TPM_CSB",
> +  "SPI0_FLASH_0_CSB",
> +  "SPI0_FLASH_1_CSB",
> +  "SPI0_CLK",
> +  "SPI0_CLK_LOOPBK"
> +};
> +
> +STATIC CONST CHAR8*  mGpioAzaNames[] = {
> +  "HDA_BCLK",
> +  "HDA_RSTB",
> +  "HDA_SYNC",
> +  "HDA_SDO",
> +  "HDA_SDI_0",
> +  "HDA_SDI_1",
> +  "SSP1_SFRM",
> +  "SSP1_TXD"
> +};
> +
> +STATIC CONST CHAR8*  mGpioJtagNames[] = {
> +  "JTAG_TDO",
> +  "JTAGX",
> +  "PRDYB",
> +  "PREQB",
> +  "CPU_TRSTB",
> +  "JTAG_TDI",
> +  "JTAG_TMS",
> +  "JTAG_TCK",
> +  "ITP_PMODE"
> +};
> +
> +STATIC CONST CHAR8*  mGpioHvmosNames[] = {
> +  "HVMOS_L_BKLTEN",
> +  "HVMOS_L_BKLCTL",
> +  "HVMOS_L_VDDEN",
> +  "HVMOS_SYS_PWROK",
> +  "HVMOS_SYS_RESETB",
> +  "HVMOS_MLK_RSTB"
> +};
> +
> +STATIC CONST CHAR8*  mGpioCpuNames[] = {
> +  "HDACPU_SDI",
> +  "HDACPU_SDO",
> +  "HDACPU_SCLK",
> +  "PM_SYNC",
> +  "PECI",
> +  "CPUPWRGD",
> +  "THRMTRIPB",
> +  "PLTRST_CPUB",
> +  "PM_DOWN",
> +  "TRIGGER_IN",
> +  "TRIGGER_OUT"
> +};
> +
> +STATIC CONST GPIO_GROUP_NAME_INFO  mPchLpGroupDescriptors[] = {
> +  GPIO_GROUP_NAME("GPP_A", GPIO_CNL_LP_ESPI_CLK_LOOPBK,
> mGpioGppaNames),
> +  GPIO_GROUP_NAME("GPP_B", GPIO_CNL_LP_GSPI0_CLK_LOOPBK,
> mGpioGppbNames),
> +  GPIO_GROUP_NAME_BASIC("GPP_C"),
> +  GPIO_GROUP_NAME_BASIC("GPP_D"),
> +  GPIO_GROUP_NAME_BASIC("GPP_E"),
> +  GPIO_GROUP_NAME_BASIC("GPP_F"),
> +  GPIO_GROUP_NAME_BASIC("GPP_G"),
> +  GPIO_GROUP_NAME_BASIC("GPP_H"),
> +  GPIO_GROUP_NAME("GPD", GPIO_CNL_LP_SLP_LANB, mGpioGpdNames),
> +  GPIO_GROUP_NAME_BASIC("VGPIO"),
> +  GPIO_GROUP_NAME("SPI", GPIO_CNL_LP_SPI0_IO_2, mGpioSpiNames),
> +  GPIO_GROUP_NAME("AZA", GPIO_CNL_LP_HDA_BCLK, mGpioAzaNames),
> +  GPIO_GROUP_NAME("CPU", GPIO_CNL_LP_HDACPU_SDI,
> mGpioCpuNames),
> +  GPIO_GROUP_NAME("JTAG", GPIO_CNL_LP_JTAG_TDO, mGpioJtagNames),
> +  GPIO_GROUP_NAME("HVMOS", GPIO_CNL_LP_HVMOS_L_BKLTEN,
> mGpioHvmosNames)
> +};
> +
> +STATIC CONST GPIO_GROUP_NAME_INFO  mPchHGroupDescriptors[] = {
> +  GPIO_GROUP_NAME("GPP_A", GPIO_CNL_H_ESPI_CLK_LOOPBK,
> mGpioGppaNames),
> +  GPIO_GROUP_NAME("GPP_B", GPIO_CNL_H_GSPI0_CLK_LOOPBK,
> mGpioGppbNames),
> +  GPIO_GROUP_NAME_BASIC("GPP_C"),
> +  GPIO_GROUP_NAME_BASIC("GPP_D"),
> +  GPIO_GROUP_NAME_BASIC("GPP_E"),
> +  GPIO_GROUP_NAME_BASIC("GPP_F"),
> +  GPIO_GROUP_NAME_BASIC("GPP_G"),
> +  GPIO_GROUP_NAME_BASIC("GPP_H"),
> +  GPIO_GROUP_NAME("GPP_I", GPIO_CNL_H_SYS_PWROK,
> mGpioGppiNames),
> +  GPIO_GROUP_NAME_BASIC("GPP_J"),
> +  GPIO_GROUP_NAME_BASIC("GPP_K"),
> +  GPIO_GROUP_NAME("GPD", GPIO_CNL_H_SLP_LANB, mGpioGpdNames),
> +  GPIO_GROUP_NAME_BASIC("VGPIO"),
> +  GPIO_GROUP_NAME("SPI", GPIO_CNL_H_SPI0_IO_2, mGpioSpiNames),
> +  GPIO_GROUP_NAME("AZA", GPIO_CNL_H_HDA_BCLK, mGpioAzaNames),
> +  GPIO_GROUP_NAME("CPU", GPIO_CNL_H_HDACPU_SDI,
> mGpioCpuNames),
> +  GPIO_GROUP_NAME("JTAG", GPIO_CNL_H_JTAG_TDO, mGpioJtagNames),
> +};
> +
> +/**
> +  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 (IsPchLp ()) {
> +    if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) {
> +      return &mPchLpGroupDescriptors[GroupIndex];
> +    } else {
> +      ASSERT (FALSE);
> +      return NULL;
> +    }
> +  } else {
> +    if (GroupIndex < ARRAY_SIZE (mPchHGroupDescriptors)) {
> +      return &mPchHGroupDescriptors[GroupIndex];
> +    } else {
> +      ASSERT (FALSE);
> +      return NULL;
> +    }
> +  }
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLib.c
> new file mode 100644
> index 0000000000..affecf9ec0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLib.c
> @@ -0,0 +1,1304 @@
> +/** @file
> +  This file contains routines for GPIO native and chipset specific purpose
> +  used by Reference Code only.
> +
> +  Copyright (c) 2019 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/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <SaAccess.h>
> +#include <Library/GpioLib.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Private/Library/GpioPrivateLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include "GpioNativePrivateLibInternal.h"
> +#include <Register/PchRegsGpio.h>
> +#include <Register/PchRegsSerialIo.h>
> +#include <Register/PchRegsIsh.h>
> +
> +/**
> +  This function sets SerialIo I2C controller pins into native mode
> +
> +  @param[in]  SerialIoI2cControllerNumber   I2C controller
> +  @param[in]  GpioTermination               GPIO termination type
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSerialIoI2c (
> +  IN  UINT32                  SerialIoI2cControllerNumber,
> +  IN  GPIO_ELECTRICAL_CONFIG  GpioTermination
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
> +  GPIO_CONFIG              GpioConfig;
> +
> +  GpioGetSerialIoI2cPins (
> +    SerialIoI2cControllerNumber,
> +    &I2cGpio
> +    );
> +
> +  if (I2cGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
> +  GpioConfig.ElectricalConfig = GpioTermination;
> +
> +  for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index++)
> {
> +    GpioConfig.PadMode          = I2cGpio[Index].Mode;
> +
> +    Status = GpioSetPadConfig(I2cGpio[Index].Pad, &GpioConfig);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets SerialIo UART controller pins into native mode
> +
> +  @param[in]  SerialIoUartControllerNumber   UART controller
> +  @param[in]  HardwareFlowControl            Hardware Flow control
> +  @param[in]  PinMuxing                      UART controller pin muxing
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSerialIoUart (
> +  IN  UINT32            SerialIoUartControllerNumber,
> +  IN  BOOLEAN           HardwareFlowControl,
> +  IN  UINT32            PinMuxing
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  UINT32                   PinsUsed;
> +  GPIO_PAD_NATIVE_FUNCTION *UartGpio;
> +
> +  GpioGetSerialIoUartPins (
> +    SerialIoUartControllerNumber,
> +    HardwareFlowControl,
> +    PinMuxing,
> +    &UartGpio,
> +    &PinsUsed
> +    );
> +
> +  if (UartGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PinsUsed; Index++) {
> +    Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +    GpioSetInputInversion (UartGpio[Index].Pad, 0);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets SerialIo SPI controller pins into native mode
> +
> +  @param[in]  SerialIoSpiControllerNumber   SPI controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSerialIoSpi (
> +  IN  UINT32            SerialIoSpiControllerNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
> +  UINT32                   NumOfSpiPins;
> +
> +  GpioGetSerialIoSpiPins (
> +    SerialIoSpiControllerNumber,
> +    &SpiGpio,
> +    &NumOfSpiPins
> +    );
> +
> +  if (SpiGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < NumOfSpiPins; Index++) {
> +    Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +    GpioSetInputInversion (SpiGpio[Index].Pad, 0);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets ISH I2C controller pins into native mode
> +
> +  @param[in]  IshI2cControllerNumber   I2C controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshI2c (
> +  IN  UINT32            IshI2cControllerNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
> +
> +  GpioGetIshI2cPins (
> +    IshI2cControllerNumber,
> +    &I2cGpio
> +    );
> +
> +  if (I2cGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_ISH_PINS_PER_I2C_CONTROLLER; Index++) {
> +    Status = GpioSetPadMode (I2cGpio[Index].Pad, I2cGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets ISH UART controller pins into native mode
> +
> +  @param[in]  IshUartControllerNumber   UART controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshUart (
> +  IN  UINT32            IshUartControllerNumber
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  GPIO_PAD_NATIVE_FUNCTION  *UartGpio;
> +
> +  GpioGetIshUartPins (
> +    IshUartControllerNumber,
> +    &UartGpio
> +    );
> +
> +  if (UartGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_ISH_PINS_PER_UART_CONTROLLER; Index++) {
> +    Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets ISH SPI controller pins into native mode
> +
> +  @param[in]  IshSpiControllerNumber   SPI controller
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshSpi (
> +  IN  UINT32            IshSpiControllerNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
> +  UINT32                   NumOfSpiPins;
> +
> +  GpioGetIshSpiPins (
> +    IshSpiControllerNumber,
> +    &SpiGpio,
> +    &NumOfSpiPins
> +    );
> +
> +  if (SpiGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < NumOfSpiPins; Index++) {
> +    Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets ISH GP pin into native mode
> +
> +  @param[in]  IshGpPinNumber   ISH GP pin number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableIshGpPin (
> +  IN  UINT32            IshGpPinNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  GPIO_PAD_NATIVE_FUNCTION IshGp;
> +
> +  GpioGetIshGpPin (
> +    IshGpPinNumber,
> +    &IshGp
> +    );
> +
> +  Status = GpioSetPadMode (IshGp.Pad, IshGp.Mode);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets SCS SD card controller pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableScsSdCard (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  GPIO_PAD_NATIVE_FUNCTION  *SdCardGpio;
> +  UINT32                    NumOfSdCardPins;
> +  GPIO_CONFIG               PwrEnConfig;
> +
> +  GpioGetScsSdCardPins (
> +    &SdCardGpio,
> +    &NumOfSdCardPins
> +    );
> +
> +  if (SdCardGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // We need to leave the PWREN#
> +  // GPIO pad unlocked since it is controlled at runtime
> +  // by ACPI code. It is a work around for our SD card
> +  // controller not respecting PWREN# invertion settings
> +  // during D3. Since this pad will be in GPIO mode when
> +  // SD controller is in D3 we need to set correct pad config.
> +  //
> +  GpioUnlockPadCfg (SdCardGpio[0].Pad);
> +  GpioGetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
> +  PwrEnConfig.PadMode = SdCardGpio[0].Mode;
> +  PwrEnConfig.Direction = GpioDirOut;
> +  PwrEnConfig.HostSoftPadOwn = GpioHostOwnAcpi;
> +  PwrEnConfig.InterruptConfig = GpioIntDis;
> +  PwrEnConfig.PowerConfig = GpioHostDeepReset;
> +  PwrEnConfig.LockConfig = GpioPadUnlock;
> +  GpioSetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
> +
> +  for (Index = 1; Index < NumOfSdCardPins; Index++) {
> +    Status = GpioSetPadMode (SdCardGpio[Index].Pad,
> SdCardGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    //
> +    // SD Card Pins GPP_G0 - G4 require Native Termination
> +    // Index in mPch[Lp/H]ScsSdCardGpio (depends on
> mPch[Lp/H]ScsSdCardGpio internal organization):
> +    // GPP_G0 = 1
> +    // GPP_G4 = 5
> +    //
> +    if (Index >= 1 && Index <= 5) {
> +      Status = GpioSetPadElectricalConfig (SdCardGpio[Index].Pad,
> GpioTermNative);
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function enables SCS Sd Card controller card detect pin
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableScsSdCardDetect (
> +  VOID
> +  )
> +{
> +  GPIO_CONFIG   PadConfig;
> +  GPIO_PAD      GpioPad;
> +
> +  ZeroMem (&PadConfig, sizeof (PadConfig));
> +
> +  ///
> +  /// vSD3_CD_B line is driven by GPPC_G_5_SD3_CDB
> +  /// and is used for interrupt for card detect event.
> +  /// GPPC_G_5_SD3_CDB cannot be used for interrupt because this pin
> +  /// is in native mode.
> +  ///
> +  GpioPad = GpioGetScsSdCardDetectPin ();
> +  PadConfig.PadMode         = GpioPadModeGpio;
> +  PadConfig.Direction       = GpioDirIn;
> +  PadConfig.HostSoftPadOwn  = GpioHostOwnGpio;
> +  PadConfig.InterruptConfig = GpioIntBothEdge;
> +  PadConfig.PowerConfig     = GpioHostDeepReset;
> +
> +  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver
> mode.
> +  GpioUnlockPadCfg (GpioPad);
> +
> +  return GpioSetPadConfig (GpioPad, &PadConfig);
> +}
> +
> +/**
> +  This function sets SCS eMMC controller pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableScsEmmc (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  GPIO_PAD_NATIVE_FUNCTION  *EmmcGpio;
> +  UINT32                    NumOfEmmcPins;
> +
> +  GpioGetScsEmmcPins (
> +    &EmmcGpio,
> +    &NumOfEmmcPins
> +    );
> +
> +  if (EmmcGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < NumOfEmmcPins; Index++) {
> +    Status = GpioSetPadMode (EmmcGpio[Index].Pad,
> EmmcGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets HDA Link pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaLink (
> +  VOID
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *HdaLinkGpio;
> +  UINT32                    NumOfHdaLinkPins;
> +
> +  GpioGetHdAudioLinkPins (
> +    &HdaLinkGpio,
> +    &NumOfHdaLinkPins
> +    );
> +
> +  if (HdaLinkGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < NumOfHdaLinkPins; Index++) {
> +    Status = GpioSetPadMode (HdaLinkGpio[Index].Pad,
> HdaLinkGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets HDA DMIC pins into native mode
> +
> +  @param[in]  DmicNumber   DMIC number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaDmic (
> +  IN  UINT32            DmicNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *DmicGpio;
> +
> +  GpioGetHdaDmicPins (
> +    DmicNumber,
> +    &DmicGpio
> +    );
> +
> +  if (DmicGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS; Index++)
> {
> +    Status = GpioSetPadMode (DmicGpio[Index].Pad,
> DmicGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets HDA SSP interface pins into native mode
> +
> +  @param[in]  SspInterfaceNumber   SSPx interface number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaSsp (
> +  IN  UINT32            SspInterfaceNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *SspGpio;
> +
> +  GpioGetHdaSspPins (
> +    SspInterfaceNumber,
> +    &SspGpio
> +    );
> +
> +  if (SspGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_GPIO_HDA_SSP_NUMBER_OF_PINS; Index++) {
> +    Status = GpioSetPadMode (SspGpio[Index].Pad, SspGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets HDA SoundWire interface pins into native mode
> +
> +  @param[in]  SndwInterfaceNumber   SNDWx interface number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaSndw (
> +  IN  UINT32            SndwInterfaceNumber
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *SndwGpio;
> +
> +  GpioGetHdaSndwPins (
> +    SndwInterfaceNumber,
> +    &SndwGpio
> +    );
> +
> +  if (SndwGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS; Index++)
> {
> +    Status = GpioSetPadMode (SndwGpio[Index].Pad,
> SndwGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets SMBUS controller pins into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSmbus (
> +  VOID
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *SmbusGpio;
> +
> +  GpioGetSmbusPins (&SmbusGpio);
> +
> +  if (SmbusGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_GPIO_SMBUS_NUMBER_OF_PINS; Index++) {
> +    Status = GpioSetPadMode (SmbusGpio[Index].Pad,
> SmbusGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets SATA DevSlp pins into native mode
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +  @param[in]  SataPort            SATA port number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSataDevSlpPin (
> +  IN  UINT32  SataCtrlIndex,
> +  IN  UINTN   SataPort
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  DevSlpGpio;
> +
> +  GpioGetSataDevSlpPin (
> +    SataCtrlIndex,
> +    SataPort,
> +    &DevSlpGpio
> +    );
> +
> +  GpioSetPadResetConfig (DevSlpGpio.Pad, GpioResumeReset);
> +
> +  return GpioSetPadMode (DevSlpGpio.Pad, DevSlpGpio.Mode);
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  DevSlpNativePad;
> +  GPIO_PAD_MODE             GpioMode;
> +  EFI_STATUS                Status;
> +
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  GpioGetSataDevSlpPin (
> +    SataCtrlIndex,
> +    SataPort,
> +    &DevSlpNativePad
> +    );
> +
> +  Status = GpioGetPadMode (DevSlpNativePad.Pad, &GpioMode);
> +
> +  if (EFI_ERROR (Status) || (GpioMode != DevSlpNativePad.Mode)) {
> +    if (DevSlpPad != NULL) {
> +      *DevSlpPad = GPIO_PAD_NONE;
> +    }
> +    return FALSE;
> +  } else {
> +    if (DevSlpPad != NULL) {
> +      *DevSlpPad = DevSlpNativePad.Pad;
> +    }
> +    return TRUE;
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  SataGpGpio;
> +
> +  GpioGetSataGpPin (
> +    SataCtrlIndex,
> +    SataPort,
> +    &SataGpGpio
> +    );
> +
> +  DEBUG_CODE_BEGIN ();
> +  GPIO_PAD_MODE  PadMode;
> +  GpioGetPadMode (SataGpGpio.Pad, &PadMode);
> +  if (PadMode == GpioPadModeNative1) {
> +    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Cannot enable SATAGP%d, %a
> already used for SATAXPCIE_%d\n",
> +        SataPort,
> +        GpioName (SataGpGpio.Pad),
> +        SataPort));
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +  DEBUG_CODE_END ();
> +
> +  return GpioSetPadMode (SataGpGpio.Pad, SataGpGpio.Mode);
> +}
> +
> +/**
> +  Returns a pad for given CLKREQ# index.
> +
> +  @param[in]  ClkreqIndex       CLKREQ# number
> +
> +  @return CLKREQ# pad.
> +**/
> +GPIO_PAD
> +GpioGetClkreqPad (
> +  IN     UINT32   ClkreqIndex
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  ClkReqGpio;
> +
> +  GpioGetPcieClkReqPin (
> +    ClkreqIndex,
> +    &ClkReqGpio
> +    );
> +
> +  return ClkReqGpio.Pad;
> +}
> +
> +/**
> +  Enables CLKREQ# pad in native mode.
> +
> +  @param[in]  ClkreqIndex       CLKREQ# number
> +
> +  @return none
> +**/
> +VOID
> +GpioEnableClkreq (
> +  IN     UINT32   ClkreqIndex
> +  )
> +{
> +  GPIO_CONFIG               PadConfig;
> +  GPIO_PAD_NATIVE_FUNCTION  ClkReqGpio;
> +
> +  ZeroMem (&PadConfig, sizeof (PadConfig));
> +
> +  GpioGetPcieClkReqPin (
> +    ClkreqIndex,
> +    &ClkReqGpio
> +    );
> +
> +  PadConfig.PadMode      = ClkReqGpio.Mode;
> +  PadConfig.Direction    = GpioDirNone;
> +  PadConfig.PowerConfig  = GpioHostDeepReset;
> +  DEBUG ((DEBUG_INFO, "Enabling CLKREQ%d\n", ClkreqIndex));
> +  GpioSetPadConfig (ClkReqGpio.Pad, &PadConfig);
> +}
> +
> +
> +/**
> +  This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode
> for eDP Panel
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableEdpPins (
> +  VOID
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  GPIO_PAD_NATIVE_FUNCTION *EdpPins;
> +  UINT32                   EdpPinsNumber;
> +
> +  GpioGetEdpPins (
> +    &EdpPins,
> +    &EdpPinsNumber
> +    );
> +
> +  if (EdpPins == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Configure HPD, VDD and BKLT Pins for eDP panel
> +  //
> +  for (Index = 0; Index < EdpPinsNumber; Index++) {
> +    Status = GpioSetPadMode (EdpPins[Index].Pad, EdpPins[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets DDP pins into native mode
> +
> +  @param[in]  DdpInterface   DDPx interface
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableDpInterface (
> +  IN  GPIO_DDP            DdpInterface
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINTN                    Index;
> +  GPIO_PAD_NATIVE_FUNCTION *DdpGpio;
> +
> +  GpioGetDdpPins (
> +    DdpInterface,
> +    &DdpGpio
> +    );
> +
> +  if (DdpGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < PCH_GPIO_DDP_NUMBER_OF_PINS; Index++) {
> +    Status = GpioSetPadMode (DdpGpio[Index].Pad, DdpGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function configures GPIO connection between CNVi and CRF
> +  @param[in]  None
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviCrfConnection (
> +  VOID
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  GPIO_PAD_NATIVE_FUNCTION *CnviBriRgiExternalPad;
> +
> +  GpioGetCnvBriRgiPins (&CnviBriRgiExternalPad);
> +
> +  if (CnviBriRgiExternalPad == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Configure CNVi BRI and RGI buses for high speed communication with CRF
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS;
> Index++) {
> +    Status = GpioSetPadMode (CnviBriRgiExternalPad[Index].Pad,
> CnviBriRgiExternalPad[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function configures virtual GPIO connection for CNVi Bluetooth UART
> +
> +  @param[in]  ConnectionType
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviBtUartConnection (
> +  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  GPIO_PAD                 *VCnviBtUartPad;
> +  GPIO_PAD_MODE            VCnviBtUartPadMode;
> +  GPIO_PAD                 *VUartForCnviBtPad;
> +  GPIO_PAD_MODE            VUartForCnviBtPadMode;
> +  GPIO_PAD_NATIVE_FUNCTION *CnviBtUartExternalPad;
> +
> +  GpioGetCnviBtUartPins (
> +    ConnectionType,
> +    &VCnviBtUartPad,
> +    &VCnviBtUartPadMode,
> +    &VUartForCnviBtPad,
> +    &VUartForCnviBtPadMode
> +    );
> +
> +  if ((VCnviBtUartPad == NULL) ||
> +      (VUartForCnviBtPad == NULL)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Configure CNVi Bluetooth UART for certain connection
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++)
> {
> +    Status = GpioSetPadMode (VCnviBtUartPad[Index],
> VCnviBtUartPadMode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Enable virtual connection for UART for Bluetooth
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++)
> {
> +    Status = GpioSetPadMode (VUartForCnviBtPad[Index],
> VUartForCnviBtPadMode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Enable CNVi BT UART on external pads
> +  //
> +  if (ConnectionType == GpioCnviBtUartToExternalPads) {
> +
> +    GpioGetCnviBtUartExternalPins (&CnviBtUartExternalPad);
> +
> +    if (CnviBtUartExternalPad == NULL) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++)
> {
> +      Status = GpioSetPadMode (CnviBtUartExternalPad[Index].Pad,
> CnviBtUartExternalPad[Index].Mode);
> +      if (EFI_ERROR (Status)) {
> +        ASSERT_EFI_ERROR (Status);
> +        return EFI_UNSUPPORTED;
> +      }
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function configures virtual GPIO connection for CNVi Bluetooth I2S
> +
> +  @param[in]  ConnectionType
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviBtI2sConnection (
> +  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  GPIO_PAD                 *VCnviBtI2sPad;
> +  GPIO_PAD_MODE            VCnviBtI2sPadMode;
> +  GPIO_PAD                 *VSspForCnviBtPad;
> +  GPIO_PAD_MODE            VSspForCnviBtPadMode;
> +  GPIO_PAD_NATIVE_FUNCTION *CnviBtI2sExternalPad;
> +
> +  GpioGetCnviBtI2sPins (
> +    ConnectionType,
> +    &VCnviBtI2sPad,
> +    &VCnviBtI2sPadMode,
> +    &VSspForCnviBtPad,
> +    &VSspForCnviBtPadMode
> +    );
> +
> +  if ((VCnviBtI2sPad == NULL) ||
> +      (VSspForCnviBtPad == NULL)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Configure CNVi Bluetooth I2S for certain connection
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
> +    Status = GpioSetPadMode (VCnviBtI2sPad[Index], VCnviBtI2sPadMode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Enable virtual connection for SSP for Bluetooth
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
> +    Status = GpioSetPadMode (VSspForCnviBtPad[Index],
> VSspForCnviBtPadMode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Enable CNV BT I2S on external pads
> +  //
> +  if (ConnectionType == (VGPIO_CNVI_BT_I2S_CONNECTION_TYPE)
> GpioCnviBtI2sToExternalPads) {
> +
> +    GpioGetCnviBtI2sExternalPins (&CnviBtI2sExternalPad);
> +
> +    if (CnviBtI2sExternalPad == NULL) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
> +      Status = GpioSetPadMode (CnviBtI2sExternalPad[Index].Pad,
> CnviBtI2sExternalPad[Index].Mode);
> +      if (EFI_ERROR (Status)) {
> +        ASSERT_EFI_ERROR (Status);
> +        return EFI_UNSUPPORTED;
> +      }
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function configures virtual GPIO connection for CNVi MFUART1
> +
> +  @param[in]  ConnectionType
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviMfUart1Connection (
> +  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT32                   Index;
> +  GPIO_PAD                 *VCnviMfUart1Pad;
> +  GPIO_PAD_MODE            VCnviMfUart1PadMode;
> +  GPIO_PAD                 *VUartForCnviMfUart1Pad;
> +  GPIO_PAD_MODE            VUartForCnviMfUart1PadMode;
> +  GPIO_PAD_NATIVE_FUNCTION *CnviMfUart1ExternalPad;
> +
> +  GpioGetCnviMfUart1Pins (
> +    ConnectionType,
> +    &VCnviMfUart1Pad,
> +    &VCnviMfUart1PadMode,
> +    &VUartForCnviMfUart1Pad,
> +    &VUartForCnviMfUart1PadMode
> +    );
> +
> +  if ((VCnviMfUart1Pad == NULL) ||
> +      (VUartForCnviMfUart1Pad == NULL)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Configure CNVi MFUART1 for certain connection
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++)
> {
> +    Status = GpioSetPadMode (VCnviMfUart1Pad[Index],
> VCnviMfUart1PadMode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Enable virtual connection for MFUART1
> +  //
> +  for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++)
> {
> +    Status = GpioSetPadMode (VUartForCnviMfUart1Pad[Index],
> VUartForCnviMfUart1PadMode);
> +    if (EFI_ERROR (Status)) {
> +      ASSERT_EFI_ERROR (Status);
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // Enable CNV MFUART1 on external pads
> +  //
> +  if (ConnectionType == GpioCnviMfUart1ToExternalPads) {
> +
> +    GpioGetCnviMfUart1ExternalPins (&CnviMfUart1ExternalPad);
> +
> +    if (CnviMfUart1ExternalPad == NULL) {
> +      return EFI_UNSUPPORTED;
> +    }
> +
> +    for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++)
> {
> +      Status = GpioSetPadMode (CnviMfUart1ExternalPad[Index].Pad,
> CnviMfUart1ExternalPad[Index].Mode);
> +      if (EFI_ERROR (Status)) {
> +        ASSERT_EFI_ERROR (Status);
> +        return EFI_UNSUPPORTED;
> +      }
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_STATUS  Status;
> +  GPIO_PAD    CnviBtEnPad;
> +  GPIO_CONFIG PadConfig;
> +
> +  ZeroMem (&PadConfig, sizeof (PadConfig));
> +
> +  PadConfig.PadMode        = GpioPadModeGpio;
> +  PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
> +  PadConfig.Direction      = GpioDirOut;
> +  if (Value == 1) {
> +    PadConfig.OutputState  = GpioOutHigh;
> +  } else {
> +    PadConfig.OutputState  = GpioOutLow;
> +  }
> +  CnviBtEnPad = GpioGetCnviBtEnablePin ();
> +
> +  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver
> mode and it is GPO
> +  GpioUnlockPadCfg (CnviBtEnPad);
> +  GpioUnlockPadCfgTx (CnviBtEnPad);
> +  Status = GpioSetPadConfig (CnviBtEnPad, &PadConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +/**
> +  This function sets CNVi Bluetooth main host interface
> +
> +  @param[in] BtInterface          CNVi BT Interface Select value
> +                                  GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioSetCnviBtInterface (
> +  IN  VGPIO_CNVI_BT_INTERFACE  BtInterface
> +  )
> +{
> +  EFI_STATUS  Status;
> +  GPIO_CONFIG PadConfig;
> +
> +  ZeroMem (&PadConfig, sizeof (PadConfig));
> +
> +  PadConfig.PadMode        = GpioPadModeGpio;
> +  PadConfig.Direction      = GpioDirOut;
> +  if (BtInterface == GpioCnviBtIfUsb) {
> +    PadConfig.OutputState  = GpioOutHigh;
> +  } else {
> +    PadConfig.OutputState  = GpioOutLow;
> +  }
> +
> +  Status = GpioSetPadConfig (GpioGetCnviBtIfSelectPin (), &PadConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_STATUS                Status;
> +  GPIO_CONFIG               CnviBtChargingPadConfig;
> +  GPIO_PAD_NATIVE_FUNCTION  A4WpPad;
> +
> +  ZeroMem (&CnviBtChargingPadConfig, sizeof (CnviBtChargingPadConfig));
> +
> +  CnviBtChargingPadConfig.PadMode        = GpioPadModeGpio;
> +  CnviBtChargingPadConfig.Direction      = GpioDirOut;
> +
> +  if (BtWirelessCharging == 1) {
> +    CnviBtChargingPadConfig.OutputState  = GpioOutHigh;
> +
> +    GpioGetCnviA4WpPin (&A4WpPad);
> +
> +    Status = GpioSetPadMode (A4WpPad.Pad, A4WpPad.Mode);
> +    ASSERT_EFI_ERROR (Status);
> +
> +  } else {
> +    CnviBtChargingPadConfig.OutputState  = GpioOutLow;
> +  }
> +
> +  Status = GpioSetPadConfig (GpioGetCnviBtChargingPin (),
> &CnviBtChargingPadConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function enables and configures CNVi Bluetooth Host wake-up
> interrupt
> +
> +  @param[in] None
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioConfigureCnviBtHostWakeInt (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +  GPIO_PAD    CnviBtHostWakeIntPad;
> +  GPIO_CONFIG PadConfig;
> +
> +  ZeroMem (&PadConfig, sizeof (PadConfig));
> +
> +  PadConfig.PadMode = GpioPadModeGpio;
> +  PadConfig.Direction = GpioDirIn;
> +  PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
> +  PadConfig.InterruptConfig = GpioIntEdge;
> +  PadConfig.PowerConfig  = GpioHostDeepReset;
> +  CnviBtHostWakeIntPad = GpioGetCnviBtHostWakeIntPin ();
> +
> +  // Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver
> mode.
> +  GpioUnlockPadCfg (CnviBtHostWakeIntPad);
> +  Status = GpioSetPadConfig (CnviBtHostWakeIntPad, &PadConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function enables IMGU CLKOUT native pin
> +
> +  @param[in] None
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableImguClkOut (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     Index;
> +  GPIO_PAD_NATIVE_FUNCTION  *ImguClkOutGpio;
> +  UINT32                    NoOfNativePins;
> +
> +  GpioGetImgClkOutPins (
> +    &ImguClkOutGpio,
> +    &NoOfNativePins
> +    );
> +
> +  if (ImguClkOutGpio == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  for (Index = 0; Index < NoOfNativePins; Index++) {
> +    Status = GpioSetPadMode (ImguClkOutGpio[Index].Pad,
> ImguClkOutGpio[Index].Mode);
> +    if (EFI_ERROR (Status)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  GpioSetDebounceTimer (GpioGetPwrBtnPin (), &DebounceTime);
> +}
> +
> +/**
> +  Configure LPC GPIO
> +**/
> +VOID
> +LpcConfigureGpio (
> +  VOID
> +  )
> +{
> +  GPIO_PAD      GpioPad;
> +  GpioPad = GpioGetLpcPin();
> +
> +  if (GpioPad == 0) {
> +    return;
> +  } else {
> +    GpioSetPadElectricalConfig (GpioPad, GpioTermWpu20K);
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLibCnl.c
> new file mode 100644
> index 0000000000..4cff00c27b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioNativePrivateLibCnl.c
> @@ -0,0 +1,2275 @@
> +/** @file
> +  This file contains specific GPIO information
> +
> +  Copyright (c) 2019 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 <SaAccess.h>
> +#include <Library/GpioLib.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include <Private/Library/GpioPrivateLib.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +#include <Register/PchRegsGpio.h>
> +#include <Register/PchRegsGpioCnl.h>
> +#include <Register/PchRegsSerialIo.h>
> +#include <Register/PchRegsIsh.h>
> +#include <Register/PchRegsScs.h>
> +#include <Register/PchRegsLpcCnl.h>
> +
> +#include "GpioNativePrivateLibInternal.h"
> +
> +//
> +// I2C controller pins
> +// I2C[controller number][pin: SDA/SCL]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
> +{
> +  {{GPIO_CNL_LP_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C17,
> GpioPadModeNative1}},
> +  {{GPIO_CNL_LP_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_C19,
> GpioPadModeNative1}},
> +  {{GPIO_CNL_LP_GPP_H4,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H5 ,
> GpioPadModeNative1}},
> +  {{GPIO_CNL_LP_GPP_H6,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H7 ,
> GpioPadModeNative1}},
> +  {{GPIO_CNL_LP_GPP_H8,  GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H9 ,
> GpioPadModeNative1}},
> +  {{GPIO_CNL_LP_GPP_H10, GpioPadModeNative1}, {GPIO_CNL_LP_GPP_H11,
> GpioPadModeNative1}}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHI2cGpio [][PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER]=
> +{
> +  {{GPIO_CNL_H_GPP_C16, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C17,
> GpioPadModeNative1}}, // I2C0
> +  {{GPIO_CNL_H_GPP_C18, GpioPadModeNative1}, {GPIO_CNL_H_GPP_C19,
> GpioPadModeNative1}}, // I2C1
> +  {{GPIO_CNL_H_GPP_D13, GpioPadModeNative3}, {GPIO_CNL_H_GPP_D14,
> GpioPadModeNative3}}, // I2C2
> +  {{GPIO_CNL_H_GPP_D4,  GpioPadModeNative2}, {GPIO_CNL_H_GPP_D23,
> GpioPadModeNative2}}  // I2C3
> +};
> +
> +
> +/**
> +  This function provides SerialIo I2C controller pins
> +
> +  @param[in]  SerialIoI2cControllerNumber    I2C controller
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetSerialIoI2cPins (
> +  IN  UINT32                      SerialIoI2cControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchLpI2cGpio)) {
> +      *NativePinsTable = mPchLpI2cGpio[SerialIoI2cControllerNumber];
> +      return;
> +    }
> +  } else {
> +    if (SerialIoI2cControllerNumber < ARRAY_SIZE (mPchHI2cGpio)) {
> +      *NativePinsTable = mPchHI2cGpio[SerialIoI2cControllerNumber];
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +//
> +// UART controller pins
> +// UART[controller number][pin: RXD/TXD/RTSB/CTSB]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
> +{
> +  { // UART0
> +    {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C10, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C11, GpioPadModeNative1}
> +  },
> +  { // UART1
> +    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative1}
> +  },
> +  { // UART2
> +    {GPIO_CNL_LP_GPP_C20, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C21, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C22, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_C23, GpioPadModeNative1},
> +  },
> +  { // UART0 (2nd pin set)
> +    {GPIO_CNL_LP_GPP_F5, GpioPadModeNative2},
> +    {GPIO_CNL_LP_GPP_F6, GpioPadModeNative2},
> +    {GPIO_CNL_LP_GPP_F4, GpioPadModeNative2},
> +    {GPIO_CNL_LP_GPP_F7, GpioPadModeNative2}
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHUartGpio [][PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER]=
> +{
> +  { // UART0
> +    {GPIO_CNL_H_GPP_C8,  GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C9,  GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C10, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C11, GpioPadModeNative1}
> +  },
> +  { // UART1
> +    {GPIO_CNL_H_GPP_C12, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C13, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C14, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C15, GpioPadModeNative1}
> +  },
> +  { // UART2
> +    {GPIO_CNL_H_GPP_C20, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C21, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C22, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_C23, GpioPadModeNative1}
> +  },
> +  { // UART0 (2nd pin set)
> +    {GPIO_CNL_H_GPP_J5, GpioPadModeNative2},
> +    {GPIO_CNL_H_GPP_J6, GpioPadModeNative2},
> +    {GPIO_CNL_H_GPP_J4, GpioPadModeNative2},
> +    {GPIO_CNL_H_GPP_J7, GpioPadModeNative2}
> +  }
> +};
> +
> +/**
> +  This function provides SerialIo UART controller pins
> +
> +  @param[in]  SerialIoUartControllerNumber   UART controller
> +  @param[in]  HardwareFlowControl            Hardware Flow control
> +  @param[in]  PinMuxing                      UART controller pin muxing
> +   @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetSerialIoUartPins (
> +  IN  UINT32                      SerialIoUartControllerNumber,
> +  IN  BOOLEAN                     HardwareFlowControl,
> +  IN  UINT32                      PinMuxing,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  UINTN                    UartGpioIndex;
> +
> +  UartGpioIndex = SerialIoUartControllerNumber;
> +
> +  if ((SerialIoUartControllerNumber == 0) && (PinMuxing == 1)) {
> +    // Last record is for UART0 second pin set
> +    if (IsPchLp ()) {
> +      UartGpioIndex = ARRAY_SIZE (mPchLpUartGpio) - 1;
> +    } else {
> +      UartGpioIndex = ARRAY_SIZE (mPchHUartGpio) - 1;
> +    }
> +  }
> +
> +  if (HardwareFlowControl) {
> +    *NoOfNativePins = PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER;
> +  } else {
> +    *NoOfNativePins =
> PCH_SERIAL_IO_PINS_PER_UART_CONTROLLER_NO_FLOW_CTRL;
> +  }
> +
> +  if (IsPchLp ()) {
> +    if (UartGpioIndex < ARRAY_SIZE (mPchLpUartGpio)) {
> +      *NativePinsTable = mPchLpUartGpio[UartGpioIndex];
> +      return;
> +    }
> +  } else {
> +    if (UartGpioIndex < ARRAY_SIZE (mPchHUartGpio)) {
> +      *NativePinsTable = mPchHUartGpio[UartGpioIndex];
> +      return;
> +    }
> +  }
> +
> +  *NativePinsTable = NULL;
> +  *NoOfNativePins = 0;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// SPI controller pins
> +// SPI[controller number][pin: CSB/CLK/MISO/MOSI]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
> +{
> +  { // SPI0
> +    {GPIO_CNL_LP_GPP_B15, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_B16, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_B17, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_B18, GpioPadModeNative1}
> +  },
> +  { // SPI1
> +    {GPIO_CNL_LP_GPP_B19, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_B20, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_B21, GpioPadModeNative1},
> +    {GPIO_CNL_LP_GPP_B22, GpioPadModeNative1}
> +  },
> +  { // SPI2
> +    {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative3},
> +    {GPIO_CNL_LP_GPP_D10, GpioPadModeNative3},
> +    {GPIO_CNL_LP_GPP_D11, GpioPadModeNative3},
> +    {GPIO_CNL_LP_GPP_D12, GpioPadModeNative3}
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHSpiGpio [][PCH_SERIAL_IO_PINS_PER_SPI_CONTROLLER]=
> +{
> +  { // SPI0
> +    {GPIO_CNL_H_GPP_B15, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_B16, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_B17, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_B18, GpioPadModeNative1}
> +  },
> +  { // SPI1
> +    {GPIO_CNL_H_GPP_B19, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_B20, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_B21, GpioPadModeNative1},
> +    {GPIO_CNL_H_GPP_B22, GpioPadModeNative1}
> +  },
> +  { // SPI2
> +    {GPIO_CNL_H_GPP_D9,  GpioPadModeNative3},
> +    {GPIO_CNL_H_GPP_D10, GpioPadModeNative3},
> +    {GPIO_CNL_H_GPP_D11, GpioPadModeNative3},
> +    {GPIO_CNL_H_GPP_D12, GpioPadModeNative3}
> +  }
> +};
> +
> +/**
> +  This function provides SerialIo SPI controller pins
> +
> +  @param[in]  SerialIoSpiControllerNumber   SPI controller
> +
> +  @param[out] NativePinsTable               Table with pins
> +  @param[out] NoOfNativePins                Number of pins
> +**/
> +VOID
> +GpioGetSerialIoSpiPins (
> +  IN  UINT32                      SerialIoSpiControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchLpSpiGpio)) {
> +      *NativePinsTable = mPchLpSpiGpio[SerialIoSpiControllerNumber];
> +      *NoOfNativePins =  ARRAY_SIZE
> (mPchLpSpiGpio[SerialIoSpiControllerNumber]);
> +      return;
> +    }
> +  } else {
> +    if (SerialIoSpiControllerNumber < ARRAY_SIZE (mPchHSpiGpio)) {
> +      *NativePinsTable = mPchHSpiGpio[SerialIoSpiControllerNumber];
> +      *NoOfNativePins =  ARRAY_SIZE
> (mPchHSpiGpio[SerialIoSpiControllerNumber]);
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  *NoOfNativePins = 0;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// ISH GP pin
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpIshGPGpio[] =
> +{
> +  {GPIO_CNL_LP_GPP_A18, GpioPadModeNative1},// ISH_GP_0
> +  {GPIO_CNL_LP_GPP_A19, GpioPadModeNative1},// ISH_GP_1
> +  {GPIO_CNL_LP_GPP_A20, GpioPadModeNative1},// ISH_GP_2
> +  {GPIO_CNL_LP_GPP_A21, GpioPadModeNative1},// ISH_GP_3
> +  {GPIO_CNL_LP_GPP_A22, GpioPadModeNative1},// ISH_GP_4
> +  {GPIO_CNL_LP_GPP_A23, GpioPadModeNative1},// ISH_GP_5
> +  {GPIO_CNL_LP_GPP_A12, GpioPadModeNative2},// ISH_GP_6
> +  {GPIO_CNL_LP_GPP_A17, GpioPadModeNative2} // ISH_GP_7
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHIshGPGpio[] =
> +{
> +  {GPIO_CNL_H_GPP_A18, GpioPadModeNative1},// ISH_GP_0
> +  {GPIO_CNL_H_GPP_A19, GpioPadModeNative1},// ISH_GP_1
> +  {GPIO_CNL_H_GPP_A20, GpioPadModeNative1},// ISH_GP_2
> +  {GPIO_CNL_H_GPP_A21, GpioPadModeNative1},// ISH_GP_3
> +  {GPIO_CNL_H_GPP_A22, GpioPadModeNative1},// ISH_GP_4
> +  {GPIO_CNL_H_GPP_A23, GpioPadModeNative1},// ISH_GP_5
> +  {GPIO_CNL_H_GPP_A12, GpioPadModeNative2},// ISH_GP_6
> +  {GPIO_CNL_H_GPP_A17, GpioPadModeNative2} // ISH_GP_7
> +};
> +
> +/**
> +  This function provides ISH GP pin data
> +
> +  @param[in]  IshGpPinNumber        ISH GP pin number
> +  @param[out] NativePin             ISH GP pin
> +**/
> +VOID
> +GpioGetIshGpPin (
> +  IN  UINT32                      IshGpPinNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (IshGpPinNumber < ARRAY_SIZE (mPchLpIshGPGpio)) {
> +      *NativePin = mPchLpIshGPGpio[IshGpPinNumber];
> +      return;
> +    }
> +  } else {
> +    if (IshGpPinNumber < ARRAY_SIZE (mPchHIshGPGpio)) {
> +      *NativePin = mPchHIshGPGpio[IshGpPinNumber];
> +      return;
> +    }
> +  }
> +  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// ISH UART controller pins
> +// ISH UART[controller number][pin: RXD/TXD/RTSB/CTSB]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
> +{
> +  { // UART0
> +    {GPIO_CNL_LP_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
> +    {GPIO_CNL_LP_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
> +    {GPIO_CNL_LP_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
> +    {GPIO_CNL_LP_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
> +  },
> +  { // UART1
> +    {GPIO_CNL_LP_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
> +    {GPIO_CNL_LP_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
> +    {GPIO_CNL_LP_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTSB
> +    {GPIO_CNL_LP_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTSB
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHIshUartGpio[][PCH_ISH_PINS_PER_UART_CONTROLLER] =
> +{
> +  { // UART0
> +    {GPIO_CNL_H_GPP_D13, GpioPadModeNative1},// ISH_UART0_RXD
> +    {GPIO_CNL_H_GPP_D14, GpioPadModeNative1},// ISH_UART0_TXD
> +    {GPIO_CNL_H_GPP_D15, GpioPadModeNative1},// ISH_UART0_RTS
> +    {GPIO_CNL_H_GPP_D16, GpioPadModeNative1} // ISH_UART0_CTS
> +  },
> +  { // UART1
> +    {GPIO_CNL_H_GPP_C12, GpioPadModeNative2},// ISH_UART1_RXD
> +    {GPIO_CNL_H_GPP_C13, GpioPadModeNative2},// ISH_UART1_TXD
> +    {GPIO_CNL_H_GPP_C14, GpioPadModeNative2},// ISH_UART1_RTS
> +    {GPIO_CNL_H_GPP_C15, GpioPadModeNative2} // ISH_UART1_CTS
> +  }
> +};
> +
> +/**
> +  This function provides ISH UART controller pins
> +
> +  @param[in]  IshUartControllerNumber   ISH UART controller
> +
> +  @param[out] NativePinsTable           Table with pins
> +**/
> +VOID
> +GpioGetIshUartPins (
> +  IN  UINT32                      IshUartControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (IshUartControllerNumber < ARRAY_SIZE (mPchLpIshUartGpio)) {
> +      *NativePinsTable = mPchLpIshUartGpio[IshUartControllerNumber];
> +      return;
> +    }
> +  } else {
> +    if (IshUartControllerNumber < ARRAY_SIZE (mPchHIshUartGpio)) {
> +      *NativePinsTable = mPchHIshUartGpio[IshUartControllerNumber];
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// ISH I2C controller pins
> +// ISH I2C[controller number][pin: SDA/SCL]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
> +{
> +  { // I2C0
> +    {GPIO_CNL_LP_GPP_D5,  GpioPadModeNative1},// ISH_I2C0_SDA
> +    {GPIO_CNL_LP_GPP_D6,  GpioPadModeNative1} // ISH_I2C0_SCL
> +  },
> +  { // I2C1
> +    {GPIO_CNL_LP_GPP_D7,  GpioPadModeNative1},// ISH_I2C1_SDA
> +    {GPIO_CNL_LP_GPP_D8,  GpioPadModeNative1} // ISH_I2C1_SCL
> +  },
> +  { // I2C2
> +    {GPIO_CNL_LP_GPP_H10, GpioPadModeNative2},// ISH_I2C2_SDA
> +    {GPIO_CNL_LP_GPP_H11, GpioPadModeNative2} // ISH_I2C2_SCL
> +  },
> +  { // I2C3
> +    {GPIO_CNL_LP_GPP_H4,  GpioPadModeNative2},// ISH_I2C3_SDA
> +    {GPIO_CNL_LP_GPP_H5,  GpioPadModeNative2} // ISH_I2C3_SCL
> +  },
> +  { // I2C4
> +    {GPIO_CNL_LP_GPP_H6,  GpioPadModeNative2},// ISH_I2C4_SDA
> +    {GPIO_CNL_LP_GPP_H7,  GpioPadModeNative2} // ISH_I2C4_SCL
> +  },
> +  { // I2C5
> +    {GPIO_CNL_LP_GPP_H8,  GpioPadModeNative2},// ISH_I2C5_SDA
> +    {GPIO_CNL_LP_GPP_H9,  GpioPadModeNative2} // ISH_I2C5_SCL
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHIshI2cGpio[][PCH_ISH_PINS_PER_I2C_CONTROLLER] =
> +{
> +  { // I2C0
> +    {GPIO_CNL_H_GPP_H19, GpioPadModeNative1},// ISH_I2C0_SDA
> +    {GPIO_CNL_H_GPP_H20, GpioPadModeNative1} // ISH_I2C0_SCL
> +  },
> +  { // I2C1
> +    {GPIO_CNL_H_GPP_H21, GpioPadModeNative1},// ISH_I2C1_SDA
> +    {GPIO_CNL_H_GPP_H22, GpioPadModeNative1} // ISH_I2C1_SCL
> +  },
> +  { // I2C2
> +    {GPIO_CNL_H_GPP_D4,  GpioPadModeNative1},// ISH_I2C2_SDA
> +    {GPIO_CNL_H_GPP_D23, GpioPadModeNative1} // ISH_I2C2_SCL
> +  }
> +};
> +
> +/**
> +  This function provides ISH I2C controller pins
> +
> +  @param[in]  IshI2cControllerNumber   ISH I2C controller
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetIshI2cPins (
> +  IN  UINT32                      IshI2cControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (IshI2cControllerNumber < ARRAY_SIZE (mPchLpIshI2cGpio)) {
> +      *NativePinsTable = mPchLpIshI2cGpio[IshI2cControllerNumber];
> +      return;
> +    }
> +  } else {
> +    if (IshI2cControllerNumber < ARRAY_SIZE (mPchHIshI2cGpio)) {
> +      *NativePinsTable = mPchHIshI2cGpio[IshI2cControllerNumber];
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// ISH SPI controller pins
> +// ISH SPI[pin: CSB/CLK/MISO/MOSI]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
> +{
> +  {GPIO_CNL_LP_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
> +  {GPIO_CNL_LP_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
> +  {GPIO_CNL_LP_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
> +  {GPIO_CNL_LP_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHIshSpiGpio[PCH_ISH_PINS_PER_SPI_CONTROLLER] =
> +{
> +  {GPIO_CNL_H_GPP_D9,  GpioPadModeNative1},// ISH_SPI_CSB
> +  {GPIO_CNL_H_GPP_D10, GpioPadModeNative1},// ISH_SPI_CLK
> +  {GPIO_CNL_H_GPP_D11, GpioPadModeNative1},// ISH_SPI_MISO
> +  {GPIO_CNL_H_GPP_D12, GpioPadModeNative1} // ISH_SPI_MOSI
> +};
> +
> +/**
> +  This function provides ISH SPI controller pins
> +
> +  @param[in]  IshSpiControllerNumber   SPI controller
> +  @param[out] NativePinsTable          Table with pins
> +  @param[out] NoOfNativePins           Number of pins
> +**/
> +VOID
> +GpioGetIshSpiPins (
> +  IN  UINT32                      IshSpiControllerNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (IshSpiControllerNumber < ARRAY_SIZE (mPchLpIshSpiGpio)) {
> +      *NativePinsTable = mPchLpIshSpiGpio;
> +      *NoOfNativePins = ARRAY_SIZE (mPchLpIshSpiGpio);
> +      return;
> +    }
> +  } else {
> +    if (IshSpiControllerNumber < ARRAY_SIZE (mPchHIshSpiGpio)) {
> +      *NativePinsTable = mPchHIshSpiGpio;
> +      *NoOfNativePins = ARRAY_SIZE (mPchHIshSpiGpio);
> +      return;
> +    }
> +  }
> +
> +  *NoOfNativePins = 0;
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// GPIO pins for SD controller
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpScsSdCardGpio[9] =
> +{
> +  {GPIO_CNL_LP_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
> +  {GPIO_CNL_LP_GPP_G0,  GpioPadModeNative1},// SD_CMD
> +  {GPIO_CNL_LP_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
> +  {GPIO_CNL_LP_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
> +  {GPIO_CNL_LP_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
> +  {GPIO_CNL_LP_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
> +  {GPIO_CNL_LP_GPP_G5,  GpioPadModeNative1},// SD_CDB
> +  {GPIO_CNL_LP_GPP_G6,  GpioPadModeNative1},// SD_CLK
> +  {GPIO_CNL_LP_GPP_G7,  GpioPadModeNative1} // SD_WP
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHScsSdCardGpio[9] =
> +{
> +  {GPIO_CNL_H_GPP_A17, GpioPadModeNative1},// SD_PWR_EN_B
> +  {GPIO_CNL_H_GPP_G0,  GpioPadModeNative1},// SD_CMD
> +  {GPIO_CNL_H_GPP_G1,  GpioPadModeNative1},// SD_DATA_0
> +  {GPIO_CNL_H_GPP_G2,  GpioPadModeNative1},// SD_DATA_1
> +  {GPIO_CNL_H_GPP_G3,  GpioPadModeNative1},// SD_DATA_2
> +  {GPIO_CNL_H_GPP_G4,  GpioPadModeNative1},// SD_DATA_3
> +  {GPIO_CNL_H_GPP_G5,  GpioPadModeNative1},// SD_CDB
> +  {GPIO_CNL_H_GPP_G6,  GpioPadModeNative1},// SD_CLK
> +  {GPIO_CNL_H_GPP_G7,  GpioPadModeNative1} // SD_WP
> +};
> +
> +/**
> +  This function provides SCS SD CARD controller pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetScsSdCardPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpScsSdCardGpio;
> +    *NoOfNativePins = ARRAY_SIZE (mPchLpScsSdCardGpio);
> +  } else {
> +    *NativePinsTable = mPchHScsSdCardGpio;
> +    *NoOfNativePins = ARRAY_SIZE (mPchHScsSdCardGpio);
> +  }
> +}
> +
> +/**
> +  This function provides SCS SD CARD detect pin
> +
> +  @retval GpioPin             SD CARD Detect pin
> +**/
> +GPIO_PAD
> +GpioGetScsSdCardDetectPin (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_VGPIO39;
> +  } else {
> +    return GPIO_CNL_H_VGPIO6;
> +  }
> +}
> +
> +//
> +// GPIO pins for eMMC controller
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpScsEmmcGpio[12] =
> +{
> +  {GPIO_CNL_LP_GPP_F11, GpioPadModeNative1},// EMMC_CMD
> +  {GPIO_CNL_LP_GPP_F12, GpioPadModeNative1},// EMMC_DATA_0
> +  {GPIO_CNL_LP_GPP_F13, GpioPadModeNative1},// EMMC_DATA_1
> +  {GPIO_CNL_LP_GPP_F14, GpioPadModeNative1},// EMMC_DATA_2
> +  {GPIO_CNL_LP_GPP_F15, GpioPadModeNative1},// EMMC_DATA_3
> +  {GPIO_CNL_LP_GPP_F16, GpioPadModeNative1},// EMMC_DATA_4
> +  {GPIO_CNL_LP_GPP_F17, GpioPadModeNative1},// EMMC_DATA_5
> +  {GPIO_CNL_LP_GPP_F18, GpioPadModeNative1},// EMMC_DATA_6
> +  {GPIO_CNL_LP_GPP_F19, GpioPadModeNative1},// EMMC_DATA_7
> +  {GPIO_CNL_LP_GPP_F20, GpioPadModeNative1},// EMMC_RCLK
> +  {GPIO_CNL_LP_GPP_F21, GpioPadModeNative1},// EMMC_CLK
> +  {GPIO_CNL_LP_GPP_F22, GpioPadModeNative1} // EMMC_RESETB
> +};
> +
> +/**
> +  This function provides SCS eMMC controller pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetScsEmmcPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpScsEmmcGpio;
> +    *NoOfNativePins = ARRAY_SIZE (mPchLpScsEmmcGpio);
> +  } else {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +}
> +
> +//
> +// GPIO pins for HD Audio Link [pin: BCLK/RSTB/SYNC/SDO/SDIx]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
> +  {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
> +  {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
> +  {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
> +  {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
> +  {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHHdaLinkGpio[PCH_GPIO_HDA_LINK_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative1},// HDA_BCLK
> +  {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative1},// HDA_RSTB
> +  {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative1},// HDA_SYNC
> +  {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative1},// HDA_SDO
> +  {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative1},// HDA_SDI_0
> +  {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative1} // HDA_SDI_1
> +};
> +
> +/**
> +  This function provides HD Audio Link pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetHdAudioLinkPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpHdaLinkGpio;
> +    *NoOfNativePins = ARRAY_SIZE (mPchLpHdaLinkGpio);
> +  } else {
> +    *NativePinsTable = mPchHHdaLinkGpio;
> +    *NoOfNativePins = ARRAY_SIZE (mPchHHdaLinkGpio);
> +  }
> +}
> +
> +//
> +// GPIO pins for HD Audio DMIC [DMIC number][pin: CLK/DATA]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
> +{
> +  { // DMIC0
> +    {GPIO_CNL_LP_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
> +    {GPIO_CNL_LP_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
> +  },
> +  { // DMIC1
> +    {GPIO_CNL_LP_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
> +    {GPIO_CNL_LP_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHHdaDmicGpio[][PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS] =
> +{
> +  { // DMIC0
> +    {GPIO_CNL_H_GPP_D19, GpioPadModeNative1},// DMIC_CLK_0
> +    {GPIO_CNL_H_GPP_D20, GpioPadModeNative1} // DMIC_DATA_0
> +  },
> +  { // DMIC1
> +    {GPIO_CNL_H_GPP_D17, GpioPadModeNative1},// DMIC_CLK_1
> +    {GPIO_CNL_H_GPP_D18, GpioPadModeNative1} // DMIC_DATA_1
> +  }
> +};
> +
> +/**
> +  This function provides DMIC interface pins
> +
> +  @param[in]  DmicNumber               DMIC interface
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetHdaDmicPins (
> +  IN  UINT32                      DmicNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (DmicNumber < ARRAY_SIZE (mPchLpHdaDmicGpio)) {
> +      *NativePinsTable = mPchLpHdaDmicGpio[DmicNumber];
> +      return;
> +    }
> +  } else {
> +    if (DmicNumber < ARRAY_SIZE (mPchHHdaDmicGpio)) {
> +      *NativePinsTable = mPchHHdaDmicGpio[DmicNumber];
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// GPIO pins for HD Audio SSPx/I2Sx interface [SSP number][pin:
> SCLK/SFRM/TXD/RXD]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
> +{
> +  { // SSP0/I2S0
> +    {GPIO_CNL_LP_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
> +    {GPIO_CNL_LP_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
> +    {GPIO_CNL_LP_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
> +    {GPIO_CNL_LP_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
> +  },
> +  { // SSP1/I2S1
> +    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
> +    {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
> +    {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
> +    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
> +  },
> +  { // SSP2/I2S2
> +    {GPIO_CNL_LP_GPP_H0, GpioPadModeNative1},// SSP2_SCLK
> +    {GPIO_CNL_LP_GPP_H1, GpioPadModeNative1},// SSP2_SFRM
> +    {GPIO_CNL_LP_GPP_H2, GpioPadModeNative1},// SSP2_TXD
> +    {GPIO_CNL_LP_GPP_H3, GpioPadModeNative1} // SSP2_RXD
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHHdaSspInterfaceGpio[][PCH_GPIO_HDA_SSP_NUMBER_OF_PINS] =
> +{
> +  { // SSP0/I2S0
> +    {GPIO_CNL_H_HDA_BCLK,  GpioPadModeNative2},// SSP0_SCLK
> +    {GPIO_CNL_H_HDA_SYNC,  GpioPadModeNative2},// SSP0_SFRM
> +    {GPIO_CNL_H_HDA_SDO,   GpioPadModeNative2},// SSP0_TXD
> +    {GPIO_CNL_H_HDA_SDI_0, GpioPadModeNative2} // SSP0_RXD
> +  },
> +  { // SSP1/I2S1
> +    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative2},// SSP1_SCLK
> +    {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative1},// SSP1_SFRM
> +    {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative1},// SSP1_TXD
> +    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative2} // SSP1_RXD
> +  },
> +  { // SSP2/I2S2
> +    {GPIO_CNL_H_GPP_D5, GpioPadModeNative1}, // SSP2_SFRM
> +    {GPIO_CNL_H_GPP_D6, GpioPadModeNative1}, // SSP2_TXD
> +    {GPIO_CNL_H_GPP_D7, GpioPadModeNative1}, // SSP2_RXD
> +    {GPIO_CNL_H_GPP_D8, GpioPadModeNative1}  // SSP2_SCLK
> +  }
> +};
> +
> +/**
> +  This function provides SSP/I2S interface pins
> +
> +  @param[in]  SspInterfaceNumber       SSP/I2S interface
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetHdaSspPins (
> +  IN  UINT32                      SspInterfaceNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (SspInterfaceNumber < ARRAY_SIZE (mPchLpHdaSspInterfaceGpio)) {
> +      *NativePinsTable = mPchLpHdaSspInterfaceGpio[SspInterfaceNumber];
> +      return;
> +    }
> +  } else {
> +    if (SspInterfaceNumber < ARRAY_SIZE (mPchHHdaSspInterfaceGpio)) {
> +      *NativePinsTable = mPchHHdaSspInterfaceGpio[SspInterfaceNumber];
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// GPIO Pin for HD Audio SSP_MCLK/I2S_MCLK
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpHdaSspMasterClockGpio = {GPIO_CNL_LP_GPP_D23,
> GpioPadModeNative1};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHHdaSspMasterClockGpio = {GPIO_CNL_H_GPP_B11,
> GpioPadModeNative1};
> +
> +/**
> +  This function sets HDA SSP Master Clock into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableHdaSspMasterClock (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GpioSetPadMode (mPchLpHdaSspMasterClockGpio.Pad,
> mPchLpHdaSspMasterClockGpio.Mode);
> +  } else {
> +    return GpioSetPadMode (mPchHHdaSspMasterClockGpio.Pad,
> mPchHHdaSspMasterClockGpio.Mode);
> +  }
> +}
> +
> +//
> +// GPIO pins for HD Audio SoundWire interface [SNDW number][pin:
> CLK/DATA]
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
> +{
> +  { // SNDW1
> +    {GPIO_CNL_LP_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
> +    {GPIO_CNL_LP_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
> +  },
> +  { // SNDW2
> +    {GPIO_CNL_LP_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
> +    {GPIO_CNL_LP_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
> +  },
> +  { // SNDW3
> +    {GPIO_CNL_LP_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
> +    {GPIO_CNL_LP_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
> +  },
> +  { // SNDW4
> +    {GPIO_CNL_LP_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
> +    {GPIO_CNL_LP_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHHdaSndwGpio[][PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS] =
> +{
> +  { // SNDW1
> +    {GPIO_CNL_H_HDA_RSTB,  GpioPadModeNative3},// SNDW1_CLK
> +    {GPIO_CNL_H_HDA_SDI_1, GpioPadModeNative3} // SNDW1_DATA
> +  },
> +  { // SNDW2
> +    {GPIO_CNL_H_SSP1_SFRM, GpioPadModeNative2},// SNDW2_CLK
> +    {GPIO_CNL_H_SSP1_TXD,  GpioPadModeNative2} // SNDW2_DATA
> +  },
> +  { // SNDW3
> +    {GPIO_CNL_H_GPP_D17,   GpioPadModeNative2},// SNDW3_CLK
> +    {GPIO_CNL_H_GPP_D18,   GpioPadModeNative2} // SNDW3_DATA
> +  },
> +  { // SNDW4
> +    {GPIO_CNL_H_GPP_D19,   GpioPadModeNative2},// SNDW4_CLK
> +    {GPIO_CNL_H_GPP_D20,   GpioPadModeNative2} // SNDW4_DATA
> +  }
> +};
> +
> +/**
> +  This function provides SNDW interface pins
> +
> +  @param[in]  SndwInterfaceNumber      SNDWx interface number
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetHdaSndwPins (
> +  IN  UINT32                      SndwInterfaceNumber,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (SndwInterfaceNumber < ARRAY_SIZE (mPchLpHdaSndwGpio)) {
> +      *NativePinsTable = mPchLpHdaSndwGpio[SndwInterfaceNumber];
> +      return;
> +    }
> +  } else {
> +    if (SndwInterfaceNumber < ARRAY_SIZE (mPchHHdaSndwGpio)) {
> +      *NativePinsTable = mPchHHdaSndwGpio[SndwInterfaceNumber];
> +      return;
> +    }
> +  }
> +  *NativePinsTable = NULL;
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// GPIO pins for SMBUS
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_GPP_C0, GpioPadModeNative1},// SMB_CLK
> +  {GPIO_CNL_LP_GPP_C1, GpioPadModeNative1} // SMB_DATA
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHSmbusGpio[PCH_GPIO_SMBUS_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_C0, GpioPadModeNative1}, // SMB_CLK
> +  {GPIO_CNL_H_GPP_C1, GpioPadModeNative1}  // SMB_DATA
> +};
> +
> +/**
> +  This function provides SMBUS interface pins
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetSmbusPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpSmbusGpio;
> +  } else {
> +    *NativePinsTable = mPchHSmbusGpio;
> +  }
> +}
> +
> +//
> +// SMBUS Alert pin
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpSmbusAlertGpio = {GPIO_CNL_LP_GPP_C2,  GpioPadModeNative1};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHSmbusAlertGpio = {GPIO_CNL_H_GPP_C2,  GpioPadModeNative1};
> +
> +/**
> +  This function sets SMBUS ALERT pin into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSmbusAlert (
> +  VOID
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION SmbusAlertGpio;
> +
> +  if (IsPchLp ()) {
> +    SmbusAlertGpio = mPchLpSmbusAlertGpio;
> +  } else {
> +    SmbusAlertGpio = mPchHSmbusAlertGpio;
> +  }
> +
> +  return GpioSetPadMode (SmbusAlertGpio.Pad, SmbusAlertGpio.Mode);
> +}
> +
> +//
> +// SATADevSlpPin to GPIO pin mapping
> +// SATA_DEVSLP_x -> GPIO pin y
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpSataDevSlpPinToGpioMap[] =
> +{
> +  {GPIO_CNL_LP_GPP_E4, GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_E5, GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_E6, GpioPadModeNative1}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHSataDevSlpPinToGpioMap[] =
> +{
> +  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F8, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F9, GpioPadModeNative1}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mCdfPchSata1DevSlpPinToGpioMap[] =
> +{
> +/// @todo SERVER- update for SATA 1
> +  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mCdfPchSata2DevSlpPinToGpioMap[] =
> +{
> +/// @todo SERVER- update for SATA 2
> +  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mCdfPchSata3DevSlpPinToGpioMap[] =
> +{
> +/// @todo SERVER- update for SATA 3
> +  {GPIO_CNL_H_GPP_E4, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_E6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F5, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F6, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_F7, GpioPadModeNative1}
> +};
> +
> +/**
> +  This function provides SATA DevSlp pin data
> +
> +  @param[in]  SataCtrlIndex       SATA controller index
> +  @param[in]  SataPort            SATA port number
> +  @param[out] NativePin           SATA DevSlp pin
> +**/
> +VOID
> +GpioGetSataDevSlpPin (
> +  IN  UINT32                    SataCtrlIndex,
> +  IN  UINTN                     SataPort,
> +  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
> +  )
> +{
> +  if (IsCdfPch ()) {
> +    if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
> +      if (SataPort < ARRAY_SIZE (mCdfPchSata1DevSlpPinToGpioMap)) {
> +        *NativePin = mCdfPchSata1DevSlpPinToGpioMap[SataPort];
> +        return;
> +      }
> +    } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
> +      if (SataPort < ARRAY_SIZE (mCdfPchSata2DevSlpPinToGpioMap)) {
> +        *NativePin = mCdfPchSata2DevSlpPinToGpioMap[SataPort];
> +        return;
> +      }
> +    } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
> +      if (SataPort < ARRAY_SIZE (mCdfPchSata3DevSlpPinToGpioMap)) {
> +        *NativePin = mCdfPchSata3DevSlpPinToGpioMap[SataPort];
> +        return;
> +      }
> +    }
> +  } else {
> +    if (IsPchLp ()) {
> +      if (SataPort < ARRAY_SIZE (mPchLpSataDevSlpPinToGpioMap)) {
> +        *NativePin = mPchLpSataDevSlpPinToGpioMap[SataPort];
> +        return;
> +      }
> +    } else {
> +      if (SataPort < ARRAY_SIZE (mPchHSataDevSlpPinToGpioMap)) {
> +        *NativePin = mPchHSataDevSlpPinToGpioMap[SataPort];
> +        return;
> +      }
> +    }
> +  }
> +  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// SATA reset port to GPIO pin mapping
> +// SATAGP_x -> GPIO pin y
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpSataGpToGpioMap[] =
> +{
> +  {GPIO_CNL_LP_GPP_E0, GpioPadModeNative2},
> +  {GPIO_CNL_LP_GPP_E1, GpioPadModeNative2},
> +  {GPIO_CNL_LP_GPP_E2, GpioPadModeNative2}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHSataGpToGpioMap[]  =
> +{
> +  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F3, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F4, GpioPadModeNative2}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mCdfPchSata1GpToGpioMap[]  =
> +{
> +/// @todo SERVER- update for SATA 1
> +  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mCdfPchSata2GpToGpioMap[]  =
> +{
> +/// @todo SERVER- update for SATA 2
> +  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mCdfPchSata3GpToGpioMap[]  =
> +{
> +/// @todo SERVER- update for SATA 3
> +  {GPIO_CNL_H_GPP_E0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_E2, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F0, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F1, GpioPadModeNative2},
> +  {GPIO_CNL_H_GPP_F2, GpioPadModeNative2}
> +};
> +
> +/**
> +  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
> +  )
> +{
> +  if (IsCdfPch ()) {
> +    if (SataCtrlIndex == SATA_1_CONTROLLER_INDEX) {
> +      if (SataPort < ARRAY_SIZE (mCdfPchSata1GpToGpioMap)) {
> +        *NativePin = mCdfPchSata1GpToGpioMap[SataPort];
> +        return;
> +      }
> +    } else if (SataCtrlIndex == SATA_2_CONTROLLER_INDEX) {
> +      if (SataPort < ARRAY_SIZE (mCdfPchSata2GpToGpioMap)) {
> +        *NativePin = mCdfPchSata2GpToGpioMap[SataPort];
> +        return;
> +      }
> +    } else if (SataCtrlIndex == SATA_3_CONTROLLER_INDEX) {
> +      if (SataPort < ARRAY_SIZE (mCdfPchSata3GpToGpioMap)) {
> +        *NativePin = mCdfPchSata3GpToGpioMap[SataPort];
> +        return;
> +      }
> +    }
> +  } else {
> +    if (IsPchLp ()) {
> +      if (SataPort < ARRAY_SIZE (mPchLpSataGpToGpioMap)) {
> +        *NativePin = mPchLpSataGpToGpioMap[SataPort];
> +        return;
> +      }
> +    } else {
> +      if (SataPort < ARRAY_SIZE (mPchHSataGpToGpioMap)) {
> +        *NativePin = mPchHSataGpToGpioMap[SataPort];
> +        return;
> +      }
> +    }
> +  }
> +  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// SATA LED pin
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpSataLedGpio = {GPIO_CNL_LP_GPP_E8, GpioPadModeNative1};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHSataLedGpio = {GPIO_CNL_H_GPP_E8, GpioPadModeNative1};
> +
> +/**
> +  This function sets SATA LED pin into native mode. SATA LED indicates
> +  SATA controller activity
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableSataLed (
> +  VOID
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  SataLedGpio;
> +
> +  if (IsPchLp ()) {
> +    SataLedGpio = mPchLpSataLedGpio;
> +  } else {
> +    SataLedGpio = mPchHSataLedGpio;
> +  }
> +
> +  return GpioSetPadMode (SataLedGpio.Pad, SataLedGpio.Mode);
> +}
> +
> +//
> +// USB2 OC pins
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpUsbOcGpioPins[] =
> +{
> +  {GPIO_CNL_LP_GPP_E9,  GpioPadModeNative1},// USB_OC_0
> +  {GPIO_CNL_LP_GPP_E10, GpioPadModeNative1},// USB_OC_1
> +  {GPIO_CNL_LP_GPP_E11, GpioPadModeNative1},// USB_OC_2
> +  {GPIO_CNL_LP_GPP_E12, GpioPadModeNative1} // USB_OC_3
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHUsbOcGpioPins[] =
> +{
> +  {GPIO_CNL_H_GPP_E9,  GpioPadModeNative1},// USB_OC_0
> +  {GPIO_CNL_H_GPP_E10, GpioPadModeNative1},// USB_OC_1
> +  {GPIO_CNL_H_GPP_E11, GpioPadModeNative1},// USB_OC_2
> +  {GPIO_CNL_H_GPP_E12, GpioPadModeNative1},// USB_OC_3
> +  {GPIO_CNL_H_GPP_F15, GpioPadModeNative1},// USB_OC_4
> +  {GPIO_CNL_H_GPP_F16, GpioPadModeNative1},// USB_OC_5
> +  {GPIO_CNL_H_GPP_F17, GpioPadModeNative1},// USB_OC_6
> +  {GPIO_CNL_H_GPP_F18, GpioPadModeNative1} // USB_OC_7
> +};
> +
> +/**
> +  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
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  OcGpio;
> +
> +  if (IsPchLp ()) {
> +    if (OcPinNumber >= ARRAY_SIZE (mPchLpUsbOcGpioPins)) {
> +      ASSERT(FALSE);
> +      return EFI_UNSUPPORTED;
> +    }
> +    OcGpio = mPchLpUsbOcGpioPins[OcPinNumber];
> +  } else {
> +    if (OcPinNumber >= ARRAY_SIZE (mPchHUsbOcGpioPins)) {
> +      ASSERT (FALSE);
> +      return EFI_UNSUPPORTED;
> +    }
> +    OcGpio = mPchHUsbOcGpioPins[OcPinNumber];
> +  }
> +
> +  return GpioSetPadMode (OcGpio.Pad, OcGpio.Mode);
> +}
> +
> +//
> +// GPIO pin for PCIE SCRCLKREQB
> +// SCRCLKREQB_x -> GPIO pin y
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpPcieSrcClkReqbPinToGpioMap[] =
> +{
> +  {GPIO_CNL_LP_GPP_B5,  GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_B6,  GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_B7,  GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_B8,  GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_B9,  GpioPadModeNative1},
> +  {GPIO_CNL_LP_GPP_B10, GpioPadModeNative1}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHPcieSrcClkReqbPinToGpioMap[]  =
> +{
> +  {GPIO_CNL_H_GPP_B5,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_B6,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_B7,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_B8,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_B9,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_B10, GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H0,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H1,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H2,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H3,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H4,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H5,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H6,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H7,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H8,  GpioPadModeNative1},
> +  {GPIO_CNL_H_GPP_H9,  GpioPadModeNative1}
> +};
> +
> +/**
> +  This function provides PCIe CLKREQ pin data
> +
> +  @param[in]  ClkreqIndex        CLKREQ# number
> +  @param[out] NativePin          Native pin data
> +**/
> +VOID
> +GpioGetPcieClkReqPin (
> +  IN  UINT32                      ClkreqIndex,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    *NativePin
> +  )
> +{
> +  if (IsPchLp ()) {
> +    if (ClkreqIndex < ARRAY_SIZE (mPchLpPcieSrcClkReqbPinToGpioMap)) {
> +      *NativePin = mPchLpPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
> +      return;
> +    }
> +  } else {
> +    if (ClkreqIndex < ARRAY_SIZE (mPchHPcieSrcClkReqbPinToGpioMap)) {
> +      *NativePin = mPchHPcieSrcClkReqbPinToGpioMap[ClkreqIndex];
> +      return;
> +    }
> +  }
> +  *NativePin = (GPIO_PAD_NATIVE_FUNCTION){0};
> +  ASSERT (FALSE);
> +}
> +
> +//
> +// PCHHOTB pin
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpPchHotbPin = {GPIO_CNL_LP_GPP_B23,  GpioPadModeNative2};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHPchHotbPin = {GPIO_CNL_H_GPP_B23,  GpioPadModeNative2};
> +
> +/**
> +  This function sets PCHHOT pin into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnablePchHot (
> +  VOID
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION PchHotbPin;
> +
> +  if (IsPchLp ()) {
> +    PchHotbPin = mPchLpPchHotbPin;
> +  } else {
> +    PchHotbPin = mPchHPchHotbPin;
> +  }
> +
> +  return GpioSetPadMode (PchHotbPin.Pad, PchHotbPin.Mode);
> +}
> +
> +//
> +// VRALERTB pin
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpVrAlertbPin = {GPIO_CNL_LP_GPP_B2, GpioPadModeNative1};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHVrAlertbPin = {GPIO_CNL_H_GPP_B2, GpioPadModeNative1};
> +
> +//
> +// CPU_C10_GATE pin
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpCpuC10GatePin = {GPIO_CNL_LP_GPP_H18, GpioPadModeNative1};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHCpuC10GatePin = {GPIO_CNL_H_GPP_J1, GpioPadModeNative2};
> +
> +/**
> +  This function sets VRALERTB pin into native mode
> +
> +  @param[in]  none
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableVrAlert (
> +  VOID
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  VrAlertGpio;
> +
> +  if (IsPchLp ()) {
> +    VrAlertGpio = mPchLpVrAlertbPin;
> +  } else {
> +    VrAlertGpio = mPchHVrAlertbPin;
> +  }
> +
> +  return GpioSetPadMode (VrAlertGpio.Pad, VrAlertGpio.Mode);
> +}
> +
> +/**
> +This function sets CPU C10 Gate pins into native mode
> +
> +@retval Status
> +**/
> +EFI_STATUS
> +GpioEnableCpuC10GatePin (
> +  VOID
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  CpuC10GateGpio;
> +
> +  if (IsPchLp ()) {
> +    CpuC10GateGpio = mPchLpCpuC10GatePin;
> +  } else {
> +    CpuC10GateGpio = mPchHCpuC10GatePin;
> +  }
> +
> +  return GpioSetPadMode (CpuC10GateGpio.Pad, CpuC10GateGpio.Mode);
> +}
> +
> +//
> +// CPU GP pins
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
> +  {GPIO_CNL_LP_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
> +  {GPIO_CNL_LP_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
> +  {GPIO_CNL_LP_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
> +};
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHCpuGpPinMap[PCH_GPIO_CPU_GP_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_E3, GpioPadModeNative1}, // CPU_GP_0
> +  {GPIO_CNL_H_GPP_E7, GpioPadModeNative1}, // CPU_GP_1
> +  {GPIO_CNL_H_GPP_B3, GpioPadModeNative1}, // CPU_GP_2
> +  {GPIO_CNL_H_GPP_B4, GpioPadModeNative1}, // CPU_GP_3
> +};
> +
> +/**
> +  This function sets CPU GP pins into native mode
> +
> +  @param[in]  CpuGpPinNum               CPU GP pin number
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableCpuGpPin (
> +  IN  UINT32                            CpuGpPinNum
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION CpuGpPin;
> +
> +  if (IsPchLp ()) {
> +    if (CpuGpPinNum >= ARRAY_SIZE (mPchLpCpuGpPinMap)) {
> +      ASSERT (FALSE);
> +      return EFI_UNSUPPORTED;
> +    }
> +    CpuGpPin = mPchLpCpuGpPinMap[CpuGpPinNum];
> +  } else {
> +    if (CpuGpPinNum >= ARRAY_SIZE (mPchHCpuGpPinMap)) {
> +      ASSERT(FALSE);
> +      return EFI_UNSUPPORTED;
> +    }
> +    CpuGpPin = mPchHCpuGpPinMap[CpuGpPinNum];
> +  }
> +
> +  return GpioSetPadMode (CpuGpPin.Pad, CpuGpPin.Mode);
> +}
> +
> +//
> +// DDSP_HPD pins
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpDdspHpdPins[] =
> +{
> +  {GPIO_CNL_LP_GPP_E13, GpioPadModeNative1},// DDSP_HPD_0
> +  {GPIO_CNL_LP_GPP_E14, GpioPadModeNative1},// DDSP_HPD_1
> +  {GPIO_CNL_LP_GPP_E15, GpioPadModeNative1},// DDSP_HPD_2
> +  {GPIO_CNL_LP_GPP_E16, GpioPadModeNative1} // DDSP_HPD_3
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHDdspHpdPins[] =
> +{
> +  {GPIO_CNL_H_GPP_I0, GpioPadModeNative1},// DDSP_HPD_0
> +  {GPIO_CNL_H_GPP_I1, GpioPadModeNative1},// DDSP_HPD_1
> +  {GPIO_CNL_H_GPP_I2, GpioPadModeNative1},// DDSP_HPD_2
> +  {GPIO_CNL_H_GPP_I3, GpioPadModeNative1} // DDSP_HPD_3
> +};
> +
> +/**
> +  This function sets DDSP_HPDx pin into native mode
> +
> +  @param[in]  DdspHpdPin     DDSP_HPDx pin
> +
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioEnableDpHotPlugDetect (
> +  IN GPIO_DDSP_HPD  DdspHpdPin
> +  )
> +{
> +  GPIO_PAD_NATIVE_FUNCTION  DdspHpdGpio;
> +  UINT32                    DdspHpdPinIndex;
> +
> +  if (DdspHpdPin > GpioDdspHpd3) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  DdspHpdPinIndex = DdspHpdPin - GpioDdspHpd0;
> +
> +  if (IsPchLp ()) {
> +    if (DdspHpdPinIndex >= ARRAY_SIZE (mPchLpDdspHpdPins)) {
> +      goto Error;
> +    }
> +    DdspHpdGpio = mPchLpDdspHpdPins[DdspHpdPinIndex];
> +  } else {
> +    if (DdspHpdPinIndex >= ARRAY_SIZE (mPchHDdspHpdPins)) {
> +      goto Error;
> +    }
> +    DdspHpdGpio = mPchHDdspHpdPins[DdspHpdPinIndex];
> +  }
> +
> +  return GpioSetPadMode (DdspHpdGpio.Pad, DdspHpdGpio.Mode);
> +Error:
> +  ASSERT (FALSE);
> +  return EFI_UNSUPPORTED;
> +}
> +
> +//
> +// EDP HPD, VDD and BKLT pins
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_GPP_E17,         GpioPadModeNative1},// EDP_HPD
> +  {GPIO_CNL_LP_HVMOS_L_VDDEN,   GpioPadModeNative1},// VDDEN
> +  {GPIO_CNL_LP_HVMOS_L_BKLTEN,  GpioPadModeNative1},// BKLTEN
> +  {GPIO_CNL_LP_HVMOS_L_BKLTCTL, GpioPadModeNative1} // BKLTCTL
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHEdpPins[PCH_GPIO_EDP_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_I4,  GpioPadModeNative1},// EDP_HPD
> +  {GPIO_CNL_H_GPP_F19, GpioPadModeNative1},// VDDEN
> +  {GPIO_CNL_H_GPP_F20, GpioPadModeNative1},// BKLTEN
> +  {GPIO_CNL_H_GPP_F21, GpioPadModeNative1} // BKLTCTL
> +};
> +
> +/**
> +  This function provides eDP pins
> +
> +  @param[out] NativePinsTable                Table with pins
> +  @param[out] NoOfNativePins                 Number of pins
> +**/
> +VOID
> +GpioGetEdpPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable,
> +  OUT UINT32                      *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpEdpPins;
> +    *NoOfNativePins = ARRAY_SIZE (mPchLpEdpPins);
> +  } else {
> +    *NativePinsTable = mPchHEdpPins;
> +    *NoOfNativePins = ARRAY_SIZE (mPchHEdpPins);
> +  }
> +}
> +
> +//
> +// DDPB/C/D/F  CTRLCLK and CTRLDATA pins
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_G
> PIO_DDP_NUMBER_OF_PINS] =
> +{
> +  {// DDPB
> +    {GPIO_CNL_LP_GPP_E18, GpioPadModeNative1},// DDPB_CTRLCLK
> +    {GPIO_CNL_LP_GPP_E19, GpioPadModeNative1} // DDPB_CTRLDATA
> +  },
> +  {// DDPC
> +    {GPIO_CNL_LP_GPP_E20, GpioPadModeNative1},// DDPC_CTRLCLK
> +    {GPIO_CNL_LP_GPP_E21, GpioPadModeNative1} // DDPC_CTRLDATA
> +  },
> +  {// DDPD
> +    {GPIO_CNL_LP_GPP_E22, GpioPadModeNative1},// DDPD_CTRLCLK
> +    {GPIO_CNL_LP_GPP_E23, GpioPadModeNative1} // DDPD_CTRLDATA
> +  },
> +  {// DDPF
> +    {GPIO_CNL_LP_GPP_H16, GpioPadModeNative1},// DDPF_CTRLCLK
> +    {GPIO_CNL_LP_GPP_H17, GpioPadModeNative1} // DDPF_CTRLDATA
> +  }
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHDdpInterfacePins[PCH_GPIO_DDP_NUMBER_OF_INTERFACES][PCH_GP
> IO_DDP_NUMBER_OF_PINS] =
> +{
> +  {// DDPB
> +    {GPIO_CNL_H_GPP_I5,  GpioPadModeNative1}, // DDPB_CTRLCLK
> +    {GPIO_CNL_H_GPP_I6,  GpioPadModeNative1}, // DDPB_CTRLDATA
> +  },
> +  {// DDPC
> +    {GPIO_CNL_H_GPP_I7,  GpioPadModeNative1}, // DDPC_CTRLCLK
> +    {GPIO_CNL_H_GPP_I8,  GpioPadModeNative1}, // DDPC_CTRLDATA
> +  },
> +  {// DDPD
> +    {GPIO_CNL_H_GPP_I9,  GpioPadModeNative1}, // DDPD_CTRLCLK
> +    {GPIO_CNL_H_GPP_I10, GpioPadModeNative1}, // DDPD_CTRLDATA
> +  },
> +  {// DDPF
> +    {GPIO_CNL_H_GPP_F22, GpioPadModeNative1}, // DDPF_CTRLCLK
> +    {GPIO_CNL_H_GPP_F23, GpioPadModeNative1}, // DDPF_CTRLDATA
> +  }
> +};
> +
> +/**
> +  This function provides DDPx interface pins
> +
> +  @param[in]  DdpInterface   DDPx interface
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetDdpPins (
> +  IN  GPIO_DDP                    DdpInterface,
> +  OUT GPIO_PAD_NATIVE_FUNCTION    **NativePinsTable
> +  )
> +{
> +  UINT32  DdpInterfaceIndex;
> +
> +  switch (DdpInterface) {
> +    case GpioDdpB:
> +    case GpioDdpC:
> +    case GpioDdpD:
> +      DdpInterfaceIndex = DdpInterface - GpioDdpB;
> +      break;
> +    case GpioDdpF:
> +      DdpInterfaceIndex = 3;
> +      break;
> +    default:
> +      goto Error;
> +  }
> +
> +  if (IsPchLp ()) {
> +    if (DdpInterfaceIndex < ARRAY_SIZE (mPchLpDdpInterfacePins)) {
> +      *NativePinsTable = mPchLpDdpInterfacePins[DdpInterfaceIndex];
> +      return;
> +    }
> +  } else {
> +    if (DdpInterfaceIndex < ARRAY_SIZE (mPchHDdpInterfacePins)) {
> +      *NativePinsTable = mPchHDdpInterfacePins[DdpInterfaceIndex];
> +      return;
> +    }
> +  }
> +Error:
> +  *NativePinsTable = NULL;
> +  ASSERT(FALSE);
> +}
> +
> +/**
> +  This function enables CNVi RF Reset pin
> +**/
> +VOID
> +GpioEnableCnviRfResetPin (
> +  VOID
> +  )
> +{
> +  EFI_STATUS      Status;
> +  GPIO_PAD        GpioPad;
> +  GPIO_PAD_MODE   PadMode;
> +
> +  if (IsPchLp ()) {
> +    GpioPad = GPIO_CNL_LP_GPP_H1;
> +    PadMode = GpioPadModeNative3;
> +  } else {
> +    GpioPad = GPIO_CNL_H_GPP_D5;
> +    PadMode = GpioPadModeNative3;
> +  }
> +
> +  Status = GpioSetPadMode (GpioPad, PadMode);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  This function enables CNVi MODEM CLKREQ pin
> +**/
> +VOID
> +GpioEnableCnviModemClkReqPin (
> +  VOID
> +  )
> +{
> +  EFI_STATUS      Status;
> +  GPIO_PAD        GpioPad;
> +  GPIO_PAD_MODE   PadMode;
> +
> +  if (IsPchLp ()) {
> +    GpioPad = GPIO_CNL_LP_GPP_H2;
> +    PadMode = GpioPadModeNative3;
> +  } else {
> +    GpioPad = GPIO_CNL_H_GPP_D6;
> +    PadMode = GpioPadModeNative3;
> +  }
> +
> +  Status = GpioSetPadMode (GpioPad, PadMode);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +
> +/**
> +  This function provides CNVi BT interface select pin
> +
> +  @retval GpioPad          GPIO pad for CNVi BT interface select
> +**/
> +GPIO_PAD
> +GpioGetCnviBtIfSelectPin (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_VGPIO5;
> +  } else {
> +    return GPIO_CNL_H_VGPIO7;
> +  }
> +}
> +
> +/**
> +  This function provides CNVi BT Charging pin
> +
> +  @retval GpioPad          GPIO pad for CNVi BT Charging select
> +**/
> +GPIO_PAD
> +GpioGetCnviBtChargingPin (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_VGPIO3;
> +  } else {
> +    return GPIO_CNL_H_VGPIO3;
> +  }
> +}
> +
> +/**
> +  This function provides CNVi A4WP pin
> +
> +  @param[out] GpioNativePad       GPIO native pad for CNVi A4WP
> +**/
> +VOID
> +GpioGetCnviA4WpPin (
> +  OUT GPIO_PAD_NATIVE_FUNCTION  *GpioNativePad
> +  )
> +{
> +  GpioNativePad->Mode = GpioPadModeNative1;
> +  if (IsPchLp ()) {
> +    GpioNativePad->Pad = GPIO_CNL_LP_GPP_F23;
> +  } else {
> +    GpioNativePad->Pad = GPIO_CNL_H_GPP_J11;
> +  }
> +}
> +
> +/**
> +  This function provides CNVi BT host wake int pin
> +
> +  @retval GpioPad          GPIO pad BT host wake int
> +**/
> +GPIO_PAD
> +GpioGetCnviBtHostWakeIntPin (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_VGPIO4;
> +  } else {
> +    return GPIO_CNL_H_VGPIO4;
> +  }
> +}
> +
> +//
> +// CNVi Bluetooth UART pads
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchLpVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_LP_VGPIO6, // vCNV_BT_UART_TXD
> +  GPIO_CNL_LP_VGPIO7, // vCNV_BT_UART_RXD
> +  GPIO_CNL_LP_VGPIO8, // vCNV_BT_UART_CTS_B
> +  GPIO_CNL_LP_VGPIO9  // vCNV_BT_UART_RTS_B
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchHVCnviBtUartGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_H_VGPIO8, // vCNV_BT_UART_TXD
> +  GPIO_CNL_H_VGPIO9, // vCNV_BT_UART_RXD
> +  GPIO_CNL_H_VGPIO10,// vCNV_BT_UART_CTS_B
> +  GPIO_CNL_H_VGPIO11 // vCNV_BT_UART_RTS_B
> +};
> +
> +//
> +// vUART for Bluetooth
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchLpVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS]
> =
> +{
> +  GPIO_CNL_LP_VGPIO18, // vUART0_TXD
> +  GPIO_CNL_LP_VGPIO19, // vUART0_RXD
> +  GPIO_CNL_LP_VGPIO20, // vUART0_CTS_B
> +  GPIO_CNL_LP_VGPIO21  // vUART0_RTS_B
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchHVUartForCnviBtGpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_H_VGPIO20, // vUART0_TXD
> +  GPIO_CNL_H_VGPIO21, // vUART0_RXD
> +  GPIO_CNL_H_VGPIO22, // vUART0_CTS_B
> +  GPIO_CNL_H_VGPIO23  // vUART0_RTS_B
> +};
> +
> +/**
> +  This function provides CNVi BT UART pins
> +
> +  @param[in]  ConnectionType           CNVi BT UART connection type
> +  @param[out] VCnviBtUartPad           Table with vCNV_BT_UARTx pads
> +  @param[out] VCnviBtUartPadMode       vCNV_BT_UARTx pad mode
> +  @param[out] VUartForCnviBtPad        Table with vUART0 pads
> +  @param[out] VUartForCnviBtPadMode    vUART0 pad mode
> +**/
> +VOID
> +GpioGetCnviBtUartPins (
> +  IN  VGPIO_CNVI_BT_UART_CONNECTION_TYPE  ConnectionType,
> +  OUT GPIO_PAD                            **VCnviBtUartPad,
> +  OUT GPIO_PAD_MODE                       *VCnviBtUartPadMode,
> +  OUT GPIO_PAD                            **VUartForCnviBtPad,
> +  OUT GPIO_PAD_MODE                       *VUartForCnviBtPadMode
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *VCnviBtUartPad = mPchLpVCnviBtUartGpioPad;
> +    *VUartForCnviBtPad = mPchLpVUartForCnviBtGpioPad;
> +  } else {
> +    *VCnviBtUartPad = mPchHVCnviBtUartGpioPad;
> +    *VUartForCnviBtPad = mPchHVUartForCnviBtGpioPad;
> +  }
> +
> +  switch (ConnectionType) {
> +    case GpioCnviBtUartToSerialIoUart0:
> +      *VCnviBtUartPadMode = GpioPadModeNative1;
> +      *VUartForCnviBtPadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviBtUartToIshUart0:
> +      *VCnviBtUartPadMode = GpioPadModeNative2;
> +      *VUartForCnviBtPadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviBtUartNotConnected:
> +    case GpioCnviBtUartToExternalPads:
> +      *VCnviBtUartPadMode = GpioPadModeGpio;
> +      *VUartForCnviBtPadMode = GpioPadModeGpio;
> +      break;
> +    default:
> +      ASSERT (FALSE);
> +      return;
> +  }
> +}
> +
> +//
> +// CNVi Bluetooth UART external pads
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS]
> =
> +{
> +  {GPIO_CNL_LP_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
> +  {GPIO_CNL_LP_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
> +  {GPIO_CNL_LP_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
> +  {GPIO_CNL_LP_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHCnviBtUartExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_C8,  GpioPadModeNative2}, // CNV_BT_UART_0_RXD
> +  {GPIO_CNL_H_GPP_C9,  GpioPadModeNative2}, // CNV_BT_UART_0_TXD
> +  {GPIO_CNL_H_GPP_C10, GpioPadModeNative2}, // CNV_BT_UART_0_RTS
> +  {GPIO_CNL_H_GPP_C11, GpioPadModeNative2}  // CNV_BT_UART_0_CTS
> +};
> +
> +/**
> +  This function provides CNVi BT UART external pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnviBtUartExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpCnviBtUartExternalPads;
> +  } else {
> +    *NativePinsTable = mPchHCnviBtUartExternalPads;
> +  }
> +}
> +
> +//
> +// CNVi Bluetooth I2S pads
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchLpVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_LP_VGPIO30, // vCNV_BT_I2S_BCLK
> +  GPIO_CNL_LP_VGPIO31, // vCNV_BT_I2S_WS_SYNC
> +  GPIO_CNL_LP_VGPIO32, // vCNV_BT_I2S_SDO
> +  GPIO_CNL_LP_VGPIO33  // vCNV_BT_I2S_SDI
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchHVCnviBtI2sGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_H_VGPIO32, // vCNV_BT_I2S_BCLK
> +  GPIO_CNL_H_VGPIO33, // vCNV_BT_I2S_WS_SYNC
> +  GPIO_CNL_H_VGPIO34, // vCNV_BT_I2S_SDO
> +  GPIO_CNL_H_VGPIO35  // vCNV_BT_I2S_SDI
> +};
> +
> +//
> +// vSSP for Bluetooth
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchLpVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_LP_VGPIO34, // vSSP2_SCLK
> +  GPIO_CNL_LP_VGPIO35, // vSSP2_SFRM
> +  GPIO_CNL_LP_VGPIO36, // vSSP2_TXD
> +  GPIO_CNL_LP_VGPIO37  // vSSP2_RXD
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchHVSspForCnviBtGpioPad[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_H_VGPIO36, // vSSP2_SCLK
> +  GPIO_CNL_H_VGPIO37, // vSSP2_SFRM
> +  GPIO_CNL_H_VGPIO38, // vSSP2_TXD
> +  GPIO_CNL_H_VGPIO39  // vSSP2_RXD
> +};
> +
> +/**
> +  This function provides CNVi BT I2S pins
> +
> +  @param[in]  ConnectionType          CNVi BT I2S connection type
> +  @param[out] VCnviBtI2sPad           Table with vCNV_BT_I2Sx pads
> +  @param[out] VCnviBtI2sPadMode       vCNV_BT_I2Sx pad mode
> +  @param[out] VSspForCnviBtPad        Table with vSSP2 pads
> +  @param[out] VSspForCnviBtPadMode    vSSP2 pad mode
> +**/
> +VOID
> +GpioGetCnviBtI2sPins (
> +  IN  VGPIO_CNVI_BT_I2S_CONNECTION_TYPE  ConnectionType,
> +  OUT GPIO_PAD                 **VCnviBtI2sPad,
> +  OUT GPIO_PAD_MODE            *VCnviBtI2sPadMode,
> +  OUT GPIO_PAD                 **VSspForCnviBtPad,
> +  OUT GPIO_PAD_MODE            *VSspForCnviBtPadMode
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *VCnviBtI2sPad = mPchLpVCnviBtI2sGpioPad;
> +    *VSspForCnviBtPad = mPchLpVSspForCnviBtGpioPad;
> +  } else {
> +    *VCnviBtI2sPad = mPchHVCnviBtI2sGpioPad;
> +    *VSspForCnviBtPad = mPchHVSspForCnviBtGpioPad;
> +  }
> +
> +  switch (ConnectionType) {
> +    case GpioCnviBtI2sToSsp0:
> +      *VCnviBtI2sPadMode = GpioPadModeNative1;
> +      *VSspForCnviBtPadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviBtI2sToSsp1:
> +      *VCnviBtI2sPadMode = GpioPadModeNative2;
> +      *VSspForCnviBtPadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviBtI2sToSsp2:
> +      *VCnviBtI2sPadMode = GpioPadModeNative3;
> +      *VSspForCnviBtPadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviBtI2sNotConnected:
> +    case GpioCnviBtI2sToExternalPads:
> +      *VCnviBtI2sPadMode = GpioPadModeGpio;
> +      *VSspForCnviBtPadMode = GpioPadModeGpio;
> +      break;
> +    default:
> +      ASSERT (FALSE);
> +      return;
> +  }
> +}
> +
> +//
> +// CNVi Bluetooth I2S external pads
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_GPP_H0, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
> +  {GPIO_CNL_LP_GPP_H1, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
> +  {GPIO_CNL_LP_GPP_H2, GpioPadModeNative2}, // CNV_BT_I2S_SDI
> +  {GPIO_CNL_LP_GPP_H3, GpioPadModeNative2}  // CNV_BT_I2S_SDO
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHCnviBtI2sExternalPads[PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_D8, GpioPadModeNative2}, // CNV_BT_I2S_WS_SYNC
> +  {GPIO_CNL_H_GPP_D5, GpioPadModeNative2}, // CNV_BT_I2S_BCLK
> +  {GPIO_CNL_H_GPP_D6, GpioPadModeNative2}, // CNV_BT_I2S_SDI
> +  {GPIO_CNL_H_GPP_D7, GpioPadModeNative2}  // CNV_BT_I2S_SDO
> +};
> +
> +/**
> +  This function provides CNVi BT I2S external pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnviBtI2sExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpCnviBtI2sExternalPads;
> +  } else {
> +    *NativePinsTable = mPchHCnviBtI2sExternalPads;
> +  }
> +}
> +
> +//
> +// CNVi MFUART1 pads
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchLpVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_LP_VGPIO10, // vCNV_MFUART1_TXD
> +  GPIO_CNL_LP_VGPIO11, // vCNV_MFUART1_RXD
> +  GPIO_CNL_LP_VGPIO12, // vCNV_MFUART1_CTS_B
> +  GPIO_CNL_LP_VGPIO13  // vCNV_MFUART1_RTS_B
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchHVCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS] =
> +{
> +  GPIO_CNL_H_VGPIO12, // vCNV_MFUART1_TXD
> +  GPIO_CNL_H_VGPIO13, // vCNV_MFUART1_RXD
> +  GPIO_CNL_H_VGPIO14, // vCNV_MFUART1_CTS_B
> +  GPIO_CNL_H_VGPIO15  // vCNV_MFUART1_RTS_B
> +};
> +
> +//
> +// vUART for MFUART1
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchLpVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_
> PINS] =
> +{
> +  GPIO_CNL_LP_VGPIO22, // vISH_UART0_TXD
> +  GPIO_CNL_LP_VGPIO23, // vISH_UART0_RXD
> +  GPIO_CNL_LP_VGPIO24, // vISH_UART0_CTS_B
> +  GPIO_CNL_LP_VGPIO25  // vISH_UART0_RTS_B
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD
> mPchHVUartForCnviMfUart1GpioPad[PCH_GPIO_CNVI_UART_NUMBER_OF_
> PINS] =
> +{
> +  GPIO_CNL_H_VGPIO24, // vISH_UART0_TXD
> +  GPIO_CNL_H_VGPIO25, // vISH_UART0_RXD
> +  GPIO_CNL_H_VGPIO26, // vISH_UART0_CTS_B
> +  GPIO_CNL_H_VGPIO27  // vISH_UART0_RTS_B
> +};
> +
> +/**
> +  This function provides CNVi MFUART1 pins
> +
> +  @param[in]  ConnectionType          CNVi MFUART1 connection type
> +  @param[out] VCnviBtI2sPad           Table with vCNV_MFUART1x pads
> +  @param[out] VCnviBtI2sPadMode       vCNV_MFUART1x pad mode
> +  @param[out] VSspForCnviBtPad        Table with vISH_UART0 pads
> +  @param[out] VSspForCnviBtPadMode    vISH_UART0 pad mode
> +**/
> +VOID
> +GpioGetCnviMfUart1Pins (
> +  IN  VGPIO_CNVI_MF_UART1_CONNECTION_TYPE  ConnectionType,
> +  OUT GPIO_PAD                 **VCnviMfUart1Pad,
> +  OUT GPIO_PAD_MODE            *VCnviMfUart1PadMode,
> +  OUT GPIO_PAD                 **VUartForCnviMfUart1Pad,
> +  OUT GPIO_PAD_MODE            *VUartForCnviMfUart1PadMode
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *VCnviMfUart1Pad = mPchLpVCnviMfUart1GpioPad;
> +    *VUartForCnviMfUart1Pad = mPchLpVUartForCnviMfUart1GpioPad;
> +  } else {
> +    *VCnviMfUart1Pad = mPchHVCnviMfUart1GpioPad;
> +    *VUartForCnviMfUart1Pad = mPchHVUartForCnviMfUart1GpioPad;
> +  }
> +
> +  switch (ConnectionType) {
> +    case GpioCnviMfUart1ToSerialIoUart2:
> +      *VCnviMfUart1PadMode = GpioPadModeNative2;
> +      *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviMfUart1ToIshUart0:
> +      *VCnviMfUart1PadMode = GpioPadModeNative1;
> +      *VUartForCnviMfUart1PadMode = GpioPadModeNative1;
> +      break;
> +    case GpioCnviMfUart1NotConnected:
> +    case GpioCnviMfUart1ToExternalPads:
> +      *VCnviMfUart1PadMode = GpioPadModeGpio;
> +      *VUartForCnviMfUart1PadMode = GpioPadModeGpio;
> +      break;
> +    default:
> +      ASSERT (FALSE);
> +      return;
> +  }
> +}
> +
> +//
> +// CNVi MFUART1 external pads
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS]
> =
> +{
> +  {GPIO_CNL_LP_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
> +  {GPIO_CNL_LP_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
> +  {GPIO_CNL_LP_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
> +  {GPIO_CNL_LP_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHCnviMfUart1ExternalPads[PCH_GPIO_CNVI_UART_NUMBER_OF_PINS]
> =
> +{
> +  {GPIO_CNL_H_GPP_C12, GpioPadModeNative3}, // CNV_MFUART1_RXD
> +  {GPIO_CNL_H_GPP_C13, GpioPadModeNative3}, // CNV_MFUART1_TXD
> +  {GPIO_CNL_H_GPP_C14, GpioPadModeNative3}, // CNV_MFUART1_RTS
> +  {GPIO_CNL_H_GPP_C15, GpioPadModeNative3}  // CNV_MFUART1_CTS
> +};
> +
> +/**
> +  This function provides CNVi MFUART1 external pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnviMfUart1ExternalPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpCnviMfUart1ExternalPads;
> +  } else {
> +    *NativePinsTable = mPchHCnviMfUart1ExternalPads;
> +  }
> +}
> +
> +/**
> +  This function provides CNVi Bluetooth Enable pad
> +
> +  @retval GpioPad           CNVi Bluetooth Enable pad
> +**/
> +GPIO_PAD
> +GpioGetCnviBtEnablePin (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_VGPIO0;
> +  } else {
> +    return GPIO_CNL_H_VGPIO0;
> +  }
> +}
> +
> +//
> +// CNVi BRI (Bluetooth Radio Interface) and RGI (Radio Generic Interface)
> buses from Pulsar to CRF (Companion RF)
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_GPP_F4, GpioPadModeNative1}, // CNV_BRI_DT
> +  {GPIO_CNL_LP_GPP_F5, GpioPadModeNative1}, // CNV_BRI_RSP
> +  {GPIO_CNL_LP_GPP_F6, GpioPadModeNative1}, // CNV_RGI_DT
> +  {GPIO_CNL_LP_GPP_F7, GpioPadModeNative1}  // CNV_RGI_RSP
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHCnviBriRgiGpioPad[PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_J4, GpioPadModeNative1}, // CNV_BRI_DT
> +  {GPIO_CNL_H_GPP_J5, GpioPadModeNative1}, // CNV_BRI_RSP
> +  {GPIO_CNL_H_GPP_J6, GpioPadModeNative1}, // CNV_RGI_DT
> +  {GPIO_CNL_H_GPP_J7, GpioPadModeNative1}  // CNV_RGI_RSP
> +};
> +
> +/**
> +  This function provides CNVi BRI RGI GPIO pads
> +
> +  @param[out] NativePinsTable          Table with pins
> +**/
> +VOID
> +GpioGetCnvBriRgiPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpCnviBriRgiGpioPad;
> +  } else {
> +    *NativePinsTable = mPchHCnviBriRgiGpioPad;
> +  }
> +}
> +
> +
> +/**
> +  This function sets CNVi WiFi mode
> +
> +  @param[in] Value                CNVi WiFi Mode value
> +                                  GpioCnviWiFiAuto: WiFi is automatically
> enabled/disabled by WiFi core
> +                                  GpioCnviWiFiEnabled: WiFi is enabled regardless of
> WiFi core decision
> +  @retval Status
> +**/
> +EFI_STATUS
> +GpioSetCnviWifiMode (
> +  IN  VGPIO_CNVI_WIFI_MODE  WiFiMode
> +  )
> +{
> +  EFI_STATUS  Status;
> +  GPIO_PAD    CnviWifiModePad;
> +  GPIO_CONFIG PadConfig;
> +
> +  ZeroMem (&PadConfig, sizeof (PadConfig));
> +
> +  PadConfig.PadMode = GpioPadModeGpio;
> +  PadConfig.Direction = GpioDirOut;
> +  if (WiFiMode == GpioCnviWiFiEnabled) {
> +    PadConfig.OutputState = GpioOutHigh;
> +  } else {
> +    PadConfig.OutputState = GpioOutLow;
> +  }
> +
> +  if (IsPchLp ()) {
> +    CnviWifiModePad = GPIO_CNL_LP_VGPIO2;
> +  } else {
> +    CnviWifiModePad = GPIO_CNL_H_VGPIO2;
> +  }
> +
> +  Status = GpioSetPadConfig (CnviWifiModePad, &PadConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchLpImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_LP_GPP_D4,  GpioPadModeNative1}, // IMGCLKOUT_0
> +  {GPIO_CNL_LP_GPP_H20, GpioPadModeNative1}, // IMGCLKOUT_1
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_PAD_NATIVE_FUNCTION
> mPchHImguClkOutGpioPad[SA_GPIO_IMGUCLK_NUMBER_OF_PINS] =
> +{
> +  {GPIO_CNL_H_GPP_K22, GpioPadModeNative1}, // IMGCLKOUT_0
> +  {GPIO_CNL_H_GPP_K23, GpioPadModeNative1}, // IMGCLKOUT_1
> +};
> +
> +/**
> +  This function provides IMGCLKOUT pins
> +
> +  @param[out] NativePinsTable          Table with pins
> +  @param[out] NoOfNativePins            Number of pins
> +**/
> +VOID
> +GpioGetImgClkOutPins (
> +  OUT GPIO_PAD_NATIVE_FUNCTION **NativePinsTable,
> +  OUT UINT32                   *NoOfNativePins
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *NativePinsTable = mPchLpImguClkOutGpioPad;
> +    *NoOfNativePins = ARRAY_SIZE (mPchLpImguClkOutGpioPad);
> +  } else {
> +    *NativePinsTable = mPchHImguClkOutGpioPad;
> +    *NoOfNativePins = ARRAY_SIZE (mPchHImguClkOutGpioPad);
> +  }
> +}
> +
> +/**
> +  This function provides PWRBTN pin
> +
> +  @retval GpioPad          PWRTBTN pin
> +**/
> +GPIO_PAD
> +GpioGetPwrBtnPin (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_GPD3;
> +  } else {
> +    return GPIO_CNL_H_GPD3;
> +  }
> +}
> +
> +/**
> +  This function provides LPC pin
> +
> +  @retval GpioPad          LPC pin
> +**/
> +GPIO_PAD
> +GpioGetLpcPin (
> +  VOID
> +  )
> +{
> +  if (PchGetLpcDid () == V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU) {
> +    return GPIO_CNL_H_GPP_A8;
> +  } else {
> +    return 0;
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioPrivateLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioPrivateLib.c
> new file mode 100644
> index 0000000000..2cf11c6da2
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioPrivateLib.c
> @@ -0,0 +1,752 @@
> +/** @file
> +  This file contains GPIO routines for RC usage
> +
> +  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
> +#include <Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h>
> +#include <Private/Library/GpioNameBufferLib.h>
> +#include <Register/PchRegsPcr.h>
> +
> +#include "GpioNativePrivateLibInternal.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 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
> +  )
> +{
> +  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
> +  UINT32                 GpioGroupInfoLength;
> +  UINT32                 GroupIndex;
> +
> +  GroupIndex = GpioGetGroupIndexFromGroup (Group);
> +  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
> +  //
> +  // Check if group argument exceeds GPIO GROUP INFO array
> +  //
> +  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *RegVal = MmioRead32 (PCH_PCR_ADDRESS
> (GpioGroupInfo[GroupIndex].Community, Offset));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
> +  UINT32                 GpioGroupInfoLength;
> +  UINT32                 GroupIndex;
> +
> +  GroupIndex = GpioGetGroupIndexFromGroup (Group);
> +  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
> +  //
> +  // Check if group argument exceeds GPIO GROUP INFO array
> +  //
> +  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  MmioWrite32 (PCH_PCR_ADDRESS
> (GpioGroupInfo[GroupIndex].Community, Offset), RegVal);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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 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
> +  )
> +{
> +  UINT32       Data32And;
> +  UINT32       Data32Or;
> +  PCH_SBI_PID  *GpioComSbiIds;
> +  UINT32       NoOfGpioComs;
> +  UINT32       GpioComIndex;
> +
> +  Data32And = (UINT32)~(B_GPIO_PCR_MISCCFG_IRQ_ROUTE);
> +  Data32Or  = (UINT32)Irq << N_GPIO_PCR_MISCCFG_IRQ_ROUTE;
> +
> +  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
> +
> +  //
> +  // Program MISCCFG register for each community
> +  //
> +  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++)
> {
> +    MmioAndThenOr32 (
> +      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex],
> R_GPIO_PCR_MISCCFG),
> +      Data32And,
> +      Data32Or
> +      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
> +  UINT32                 GpioGroupInfoLength;
> +  UINT32                 GroupIndex;
> +
> +  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
> +
> +  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
> +
> +  return GpioGroupInfo[GroupIndex].Community;
> +}
> +
> +/**
> +  This procedure will return PadCfg address from GpioPad
> +
> +  @param[in] GpioPad            GpioPad
> +
> +  @retval GpioPadCfgAddress     PadCfg Address of GpioPad
> +**/
> +UINT32
> +GpioGetGpioPadCfgAddressFromGpioPad (
> +  IN GPIO_PAD        GpioPad
> +  )
> +{
> +  UINT32                 PadCfgRegAddress;
> +  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
> +  //
> +  PadCfgRegAddress = GpioGroupInfo[GroupIndex].PadCfgOffset +
> S_GPIO_PCR_PADCFG * PadNumber;
> +
> +  return PadCfgRegAddress;
> +}
> +
> +
> +/**
> +  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;
> +
> +  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
> +  //
> +  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
> +  if (PadNumber >= GpioGroupInfo[GpioGetGroupIndexFromGpioPad
> (GpioPad)].PadPerGroup) {
> +    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible
> range for this group\n", PadNumber));
> +    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[out] 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;
> +
> +  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;
> +}
> +
> +/**
> +  The function performs GPIO Power Management programming.
> +**/
> +VOID
> +GpioConfigurePm (
> +  VOID
> +  )
> +{
> +  UINT32       Data32Or;
> +  UINT32       Data32And;
> +  PCH_SBI_PID  *GpioComSbiIds;
> +  UINT32       NoOfGpioComs;
> +  UINT32       GpioComIndex;
> +
> +  Data32And = (UINT32)~0,
> +  //
> +  // Enable MISCCFG.GPSIDEDPCGEn, MISCCFG.GPRCOMPCDLCGEn,
> MISCCFG.GPRTCDLCGEn,
> +  // MISCCFG.GPDLCGEn and MISCCFG.GPDPCGEn for GPIO communities
> +  //
> +  Data32Or = (B_GPIO_PCR_MISCCFG_GPSIDEDPCGEN |
> +              B_GPIO_PCR_MISCCFG_GPRCOMPCDLCGEN |
> +              B_GPIO_PCR_MISCCFG_GPRTCDLCGEN |
> +              B_GPIO_PCR_MISCCFG_GPDLCGEN |
> +              B_GPIO_PCR_MISCCFG_GPDPCGEN);
> +
> +  NoOfGpioComs = GpioGetComSbiPortIds (&GpioComSbiIds);
> +
> +  //
> +  // Configure Clock Gating in each community
> +  //
> +  for (GpioComIndex = 0; GpioComIndex < NoOfGpioComs; GpioComIndex++)
> {
> +    MmioAndThenOr32 (
> +      PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex],
> R_GPIO_PCR_MISCCFG),
> +      Data32And,
> +      Data32Or
> +      );
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINT32         DwNum;
> +  UINT32         GroupIndex;
> +  UINT32         NumberOfGroups;
> +  GPIO_GROUP     Group;
> +  UINT32         LockValue;
> +  EFI_STATUS     Status;
> +
> +  NumberOfGroups = GpioGetNumberOfGroups ();
> +
> +  for (GroupIndex = 0; GroupIndex < NumberOfGroups; GroupIndex++) {
> +    Group = GpioGetGroupFromGroupIndex (GroupIndex);
> +    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup
> (Group)); DwNum++) {
> +
> +      GpioGetPadCfgLockForGroupDw (Group, DwNum, &LockValue);
> +
> +      if (LockValue) {
> +        Status = GpioUnlockPadCfgForGroupDw (Group, DwNum, ~0u);
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +
> +      GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &LockValue);
> +
> +      if (LockValue) {
> +        Status = GpioUnlockPadCfgTxForGroupDw (Group, DwNum, ~0u);
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  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);
> +}
> +
> +
> +//
> +// For GPIO debounce feature glitch filter clock is used
> +// which is driven by RTC clock with f = 32kHz (T = 31.25us)
> +//
> +#define GPIO_DEB_CLK_PERIOD_IN_NS  31250
> +
> +/**
> +  This procedure enables debounce feature on a selected pad configured in
> input mode
> +  Debounce time can be specified in microseconds. GPIO HW supports only
> certain values
> +  according to below formula:
> +   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 GPIO HW, function will round down
> +  to closest supported
> +
> +  @param[in] GpioPad              GPIO pad
> +  @param[in, out] DebounceTime    Debounce Time in microseconds
> +                                  If Debounce Time = 0, Debouncer feature will be
> disabled
> +                                  Function will set DebounceTime argument to
> rounded supported value
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid GpioPad or unsupported
> DebounceDuration value
> +  @retval EFI_UNSUPPORTED         GpioPad is not owned by host
> +**/
> +EFI_STATUS
> +GpioSetDebounceTimer (
> +  IN GPIO_PAD                  GpioPad,
> +  IN OUT UINT32                *DebounceTime
> +  )
> +{
> +  UINT32   DebounceEnable;
> +  UINT32   DebounceValue;
> +  UINT32   InRangeDebounceTime;
> +  UINT32   SupportedDebounceTime;
> +  UINT32   Temp;
> +  BOOLEAN  SupportedValue;
> +
> +  if (!GpioIsPadValid (GpioPad)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (!GpioIsPadHostOwned (GpioPad)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (*DebounceTime > 1024000) {
> +    InRangeDebounceTime = 1024000;
> +    SupportedValue = FALSE;
> +  } else if ((*DebounceTime < 250) && (*DebounceTime > 0)) {
> +    InRangeDebounceTime = 0;
> +    SupportedValue = FALSE;
> +  } else {
> +    InRangeDebounceTime = *DebounceTime;
> +    SupportedValue = TRUE;
> +  }
> +
> +  //
> +  // DebounceValue = log2 (InRangeDebounceTime * f_deb_clk)
> +  //
> +  DebounceValue = 0;
> +  Temp = InRangeDebounceTime * 1000 / GPIO_DEB_CLK_PERIOD_IN_NS;
> +
> +  //
> +  // Check if any rounding occurred
> +  //
> +  if (InRangeDebounceTime != (Temp * GPIO_DEB_CLK_PERIOD_IN_NS / 1000))
> {
> +    SupportedValue = FALSE;
> +  }
> +
> +  //
> +  // Check if value is power of 2
> +  //
> +  if ((Temp != 0) && ((Temp & (Temp - 1)) != 0)) {
> +    SupportedValue = FALSE;
> +  }
> +
> +  //
> +  // DebounceValue = log2 (Temp)
> +  //
> +  while (Temp > 1) {
> +    Temp >>= 1;
> +    DebounceValue++;
> +  }
> +
> +  if (DebounceValue > 0) {
> +    DebounceEnable = B_GPIO_PCR_DEBEN;
> +    SupportedDebounceTime = (1 << DebounceValue) *
> GPIO_DEB_CLK_PERIOD_IN_NS / 1000;
> +  } else {
> +    DebounceEnable = 0;
> +    SupportedDebounceTime = 0;
> +  }
> +
> +  GpioWritePadCfgReg (
> +    GpioPad,
> +    2,
> +    (UINT32)~(B_GPIO_PCR_DEBOUNCE | B_GPIO_PCR_DEBEN),
> +    (DebounceValue << N_GPIO_PCR_DEBOUNCE) | DebounceEnable
> +    );
> +
> +  if (!SupportedValue) {
> +    DEBUG ((DEBUG_WARN, "GPIO WARNING: %a %dus debounce time
> rounded down to %dus\n",
> +            GpioName (GpioPad),
> +            *DebounceTime,
> +            SupportedDebounceTime));
> +  }
> +
> +  *DebounceTime = SupportedDebounceTime;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioPrivateLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioPrivateLibCnl.c
> new file mode 100644
> index 0000000000..a6d260f4ad
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPriv
> ateLib/GpioPrivateLibCnl.c
> @@ -0,0 +1,225 @@
> +/** @file
> +  This file contains specific GPIO information
> +
> +  Copyright (c) 2019 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 <Private/Library/GpioPrivateLib.h>
> +#include <Register/PchRegsGpioCnl.h>
> +#include <Register/PchRegsPmcCnl.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +#include <GpioConfig.h>
> +#include <Register/PchRegsPcr.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO
> mPchLpGpioGroupInfo[] = {
> +  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS,
> R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_A_PAD_MAX}, //CNL PCH-LP GPP_A
> +  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_SMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_NMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_B_PAD_MAX}, //CNL PCH-LP GPP_B
> +  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_SMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_NMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_C_PAD_MAX}, //CNL PCH-LP GPP_C
> +  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_SMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_NMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_D_PAD_MAX}, //CNL PCH-LP GPP_D
> +  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_SMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_NMI_EN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_E_PAD_MAX}, //CNL PCH-LP GPP_E
> +  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS,
> R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_F_PAD_MAX}, //CNL PCH-LP GPP_F
> +  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_GPP_G_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_G_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_G_PAD_MAX}, //CNL PCH-LP GPP_G
> +  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS,
> R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPP_H_PAD_MAX}, //CNL PCH-LP GPP_H
> +  {PID_GPIOCOM2, R_CNL_PCH_LP_GPIO_PCR_GPD_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS,
> R_CNL_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_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_GPD_PAD_MAX},   //CNL PCH-LP GPD
> +  {PID_GPIOCOM1, R_CNL_PCH_LP_GPIO_PCR_VGPIO_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_0_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_VGPIO_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_VGPIO_PAD_MAX}, //CNL PCH-LP vGPIO
> +  {PID_GPIOCOM0, R_CNL_PCH_LP_GPIO_PCR_SPI_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_SPI_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_SPI_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_SPI_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_SPI_PAD_MAX},   //CNL PCH-LP SPI
> +  {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_AZA_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_AZA_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_AZA_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_AZA_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_AZA_PAD_MAX},   //CNL PCH-LP AZA
> +  {PID_GPIOCOM3, R_CNL_PCH_LP_GPIO_PCR_CPU_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_CPU_HOSTSW_OWN,
> 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,
> R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_CPU_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_CPU_PAD_MAX},   //CNL PCH-LP CPU
> +  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_JTAG_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_JTAG_HOSTSW_OWN,
> 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,
> R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_JTAG_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_JTAG_PAD_MAX},  //CNL PCH-LP JTAG
> +  {PID_GPIOCOM4, R_CNL_PCH_LP_GPIO_PCR_HVMOS_PAD_OWN,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_HOSTSW_OWN,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IS,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_IE,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_STS,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCK,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFGLOCKTX,
> R_CNL_PCH_LP_GPIO_PCR_HVMOS_PADCFG_OFFSET,
> CNL_PCH_LP_GPIO_HVMOS_PAD_MAX}  //CNL PCH-LP HVMOS
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO
> mPchHGpioGroupInfo[] = {
> +  {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_A_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_A_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_A_PAD_MAX}, //CNL PCH-H GPP_A
> +  {PID_GPIOCOM0, R_CNL_PCH_H_GPIO_PCR_GPP_B_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_GPI_GPE_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_SMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_NMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_B_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_B_PAD_MAX}, //CNL PCH-H GPP_B
> +  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_C_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_GPI_GPE_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_SMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_NMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_C_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_C_PAD_MAX}, //CNL PCH-H GPP_C
> +  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_D_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_GPI_GPE_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_SMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_NMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_D_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_D_PAD_MAX}, //CNL PCH-H GPP_D
> +  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_E_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_GPI_GPE_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_SMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_NMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_E_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_E_PAD_MAX}, //CNL PCH-H GPP_E
> +  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_F_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_F_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_F_PAD_MAX}, //CNL PCH-H GPP_F
> +  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_GPP_G_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_GPI_GPE_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_SMI_EN, NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_G_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_G_PAD_MAX}, //CNL PCH-H GPP_G
> +  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_H_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_H_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_H_PAD_MAX}, //CNL PCH-H GPP_H
> +  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_I_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_GPI_GPE_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_SMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_NMI_EN,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_I_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_I_PAD_MAX}, //CNL PCH-H GPP_I
> +  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_GPP_J_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_J_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_J_PAD_MAX}, //CNL PCH-H GPP_J
> +  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_GPP_K_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPP_K_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPP_K_PAD_MAX}, //CNL PCH-H GPP_K
> +  {PID_GPIOCOM2, R_CNL_PCH_H_GPIO_PCR_GPD_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPD_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_GPD_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_GPD_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_GPD_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_GPD_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_GPD_PAD_MAX},   //CNL PCH-H GPD
> +  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_VGPIO_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_HOSTSW_OWN,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IS,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_IE,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_STS,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_GPI_GPE_EN,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_0_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_VGPIO_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_VGPIO_PAD_MAX}, //CNL PCH-H vGPIO
> +  {PID_GPIOCOM3, R_CNL_PCH_H_GPIO_PCR_SPI_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_SPI_HOSTSW_OWN,
> 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,
> R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_SPI_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_SPI_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_SPI_PAD_MAX},   //CNL PCH-H SPI
> +  {PID_GPIOCOM1, R_CNL_PCH_H_GPIO_PCR_AZA_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_AZA_HOSTSW_OWN,
> 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,
> R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_AZA_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_AZA_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_AZA_PAD_MAX},   //CNL PCH-H AZA
> +  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_CPU_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_CPU_HOSTSW_OWN,
> 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,
> R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_CPU_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_CPU_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_CPU_PAD_MAX},   //CNL PCH-H CPU
> +  {PID_GPIOCOM4, R_CNL_PCH_H_GPIO_PCR_JTAG_PAD_OWN,
> R_CNL_PCH_H_GPIO_PCR_JTAG_HOSTSW_OWN,
> 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,
> R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCK,
> R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFGLOCKTX,
> R_CNL_PCH_H_GPIO_PCR_JTAG_PADCFG_OFFSET,
> CNL_PCH_H_GPIO_JTAG_PAD_MAX}   //CNL PCH-H JTAG
> +};
> +
> +/**
> +  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
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *GpioGroupInfoTableLength = ARRAY_SIZE (mPchLpGpioGroupInfo);
> +    return mPchLpGpioGroupInfo;
> +  } else {
> +    *GpioGroupInfoTableLength = ARRAY_SIZE (mPchHGpioGroupInfo);
> +    return mPchHGpioGroupInfo;
> +  }
> +}
> +
> +/**
> +  Get GPIO Chipset ID specific to PCH generation and series
> +**/
> +UINT32
> +GpioGetThisChipsetId (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    return GPIO_CNL_LP_CHIPSET_ID;
> +  } else {
> +    return GPIO_CNL_H_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_CNL_LP_GROUP_GPD) || (Group ==
> GPIO_CNL_H_GROUP_GPD)) {
> +    return TRUE;
> +  } else {
> +    return FALSE;
> +  }
> +}
> +
> +/**
> +  This procedure will perform special handling of GPP_A_12.
> +
> +  @param[in]  None
> +
> +  @retval None
> +**/
> +VOID
> +GpioA12SpecialHandling (
> +  VOID
> +  )
> +{
> +  GPIO_PAD_OWN         PadOwnVal;
> +  GPIO_PAD             GpioPad;
> +
> +  //
> +  // PCH BWG 16.6. GPP_A_12 Special Handling
> +  //
> +  if (IsPchLp ()) {
> +    GpioPad = GPIO_CNL_LP_GPP_A12;
> +  } else {
> +    GpioPad = GPIO_CNL_H_GPP_A12;
> +  }
> +  GpioGetPadOwnership (GpioPad, &PadOwnVal);
> +
> +  //
> +  // If the pad is host-own, BIOS has to always lock this pad after being
> initialized
> +  //
> +  if (PadOwnVal == GpioPadOwnHost) {
> +    //
> +    // Set PadCfgLock for GPP_A_12
> +    //
> +    GpioLockPadCfg (GpioPad);
> +  }
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_SBI_PID mGpioComSbiIds[] =
> +{
> +  PID_GPIOCOM0, PID_GPIOCOM1, PID_GPIOCOM2, PID_GPIOCOM3,
> PID_GPIOCOM4
> +};
> +
> +/**
> +  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
> +  )
> +{
> +  *GpioComSbiIds = mGpioComSbiIds;
> +  return ARRAY_SIZE (mGpioComSbiIds);
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING
> mPchLpGpioGroupToGpeMapping[] = {
> +  {GPIO_CNL_LP_GROUP_GPP_A,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_A},
> +  {GPIO_CNL_LP_GROUP_GPP_B,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_B},
> +  {GPIO_CNL_LP_GROUP_GPP_C,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_C},
> +  {GPIO_CNL_LP_GROUP_GPP_D,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_D},
> +  {GPIO_CNL_LP_GROUP_GPP_E,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_E},
> +  {GPIO_CNL_LP_GROUP_GPP_F,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_F},
> +  {GPIO_CNL_LP_GROUP_GPP_G,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_G,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_G},
> +  {GPIO_CNL_LP_GROUP_GPP_H,  0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPP_H},
> +  {GPIO_CNL_LP_GROUP_GPD,    0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_GPD},
> +  {GPIO_CNL_LP_GROUP_VGPIO , 0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_VGPIO,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_VGPIO},
> +  {GPIO_CNL_LP_GROUP_SPI,    0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_SPI,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_SPI},
> +  {GPIO_CNL_LP_GROUP_AZA,    0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_AZA,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_AZA},
> +  {GPIO_CNL_LP_GROUP_JTAG,   0,
> V_CNL_PCH_LP_PMC_PWRM_GPIO_CFG_JTAG,
> V_CNL_PCH_LP_GPIO_PCR_MISCCFG_GPE0_JTAG}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING
> mPchHGpioGroupToGpeMapping[] = {
> +  {GPIO_CNL_H_GROUP_GPP_A,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_A,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_A},
> +  {GPIO_CNL_H_GROUP_GPP_B,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_B,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_B},
> +  {GPIO_CNL_H_GROUP_GPP_C,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_C,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_C},
> +  {GPIO_CNL_H_GROUP_GPP_D,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_D,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_D},
> +  {GPIO_CNL_H_GROUP_GPP_E,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_E,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_E},
> +  {GPIO_CNL_H_GROUP_GPP_F,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_F,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_F},
> +  {GPIO_CNL_H_GROUP_GPP_G,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_G,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_G},
> +  {GPIO_CNL_H_GROUP_GPP_H,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_H,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_H},
> +  {GPIO_CNL_H_GROUP_GPP_I,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_I,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_I},
> +  {GPIO_CNL_H_GROUP_GPP_J,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_J,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_J},
> +  {GPIO_CNL_H_GROUP_GPP_K,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPP_K,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPP_K},
> +  {GPIO_CNL_H_GROUP_GPD,    0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_GPD,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_GPD},
> +  {GPIO_CNL_H_GROUP_VGPIO,  0,
> V_CNL_PCH_H_PMC_PWRM_GPIO_CFG_VGPIO,
> V_CNL_PCH_H_GPIO_PCR_MISCCFG_GPE0_VGPIO}
> +};
> +
> +/**
> +  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
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *GpioGroupToGpeMapping = mPchLpGpioGroupToGpeMapping;
> +    *GpioGroupToGpeMappingLength = ARRAY_SIZE
> (mPchLpGpioGroupToGpeMapping);
> +  } else {
> +    *GpioGroupToGpeMapping = mPchHGpioGroupToGpeMapping;
> +    *GpioGroupToGpeMappingLength = ARRAY_SIZE
> (mPchHGpioGroupToGpeMapping);
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi14.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi14.c
> new file mode 100644
> index 0000000000..2f9b6a7e6f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi14.c
> @@ -0,0 +1,67 @@
> +/** @file
> +  This file contains functions for PCH DMI SIP14
> +
> +  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Register/PchRegsDmi.h>
> +#include <Register/PchRegsDmi14.h>
> +#include <Register/PchRegsPcr.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);
> +}
> +
> +/**
> +  Enable PCIe Relaxed Order for DMI SIP14
> +**/
> +VOID
> +PchDmi14EnablePcieRelaxedOrder (
> +  VOID
> +  )
> +{
> +  //
> +  // Enable Forced Relaxed Ordering to always allow downstream
> completions to pass posted writes.
> +  // Set Completion Relaxed Ordering Attribute Override Value
> +  // and Completion Relaxed Ordering Attribute Override Enable
> +  //
> +  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI14_PCR_2314, ~0u, (BIT31 |
> BIT7));
> +}
> +
> +/**
> + 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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi15.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi15.c
> new file mode 100644
> index 0000000000..c711b3de39
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmi15.c
> @@ -0,0 +1,113 @@
> +/** @file
> +  This file contains functions for PCH DMI SIP15
> +
> +  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Register/PchRegsDmi.h>
> +#include <Register/PchRegsDmi15.h>
> +#include <Register/PchRegsPcr.h>
> +
> +/**
> +  This function checks if DMI SIP15 Secured Register Lock (SRL) is set
> +
> +  @retval SRL state
> +**/
> +BOOLEAN
> +IsPchDmi15Locked (
> +  VOID
> +  )
> +{
> +  return ((PchPcrRead32 (PID_DMI, R_PCH_DMI15_PCR_MPC) &
> B_PCH_DMI15_PCR_MPC_SRL) != 0);
> +}
> +
> +/**
> +  Set DMI thermal throttling to recommended configuration.
> +  It's intended only for P-DMI SIP15.
> +**/
> +VOID
> +PchDmi15SetRecommendedThermalThrottling (
> +  VOID
> +  )
> +{
> +  UINT32  Data32And;
> +  UINT32  Data32Or;
> +  ///
> +  /// DMI recommended Thermal Sensor Target Width
> +  /// is the HW default configuration:
> +  ///  - Thermal Sensor 3 Target Width: 0 (x1)
> +  ///  - Thermal Sensor 2 Target Width: 1 (x2)
> +  ///  - Thermal Sensor 1 Target Width: 2 (x4)
> +  ///  - Thermal Sensor 0 Target Width: 3 (x8)
> +  /// Enable Thermal Sensor Autonomous Width
> +  ///
> +  Data32And = (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW |
> B_PCH_DMI15_PCR_UPHWAWC_TS2TW |
> +                        B_PCH_DMI15_PCR_UPHWAWC_TS1TW |
> B_PCH_DMI15_PCR_UPHWAWC_TS0TW);
> +  Data32Or  = (0 << N_PCH_DMI15_PCR_UPHWAWC_TS3TW) |
> +              (1 << N_PCH_DMI15_PCR_UPHWAWC_TS2TW) |
> +              (2 << N_PCH_DMI15_PCR_UPHWAWC_TS1TW) |
> +              (3 << N_PCH_DMI15_PCR_UPHWAWC_TS0TW) |
> +              B_PCH_DMI15_PCR_UPHWAWC_TSAWEN;
> +
> +  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC,
> Data32And, Data32Or);
> +}
> +
> +/**
> +  Set DMI thermal throttling to custom configuration.
> +  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
> +  DMI Thermal Sensor Autonomous Width Enable.
> +  It's intended only for P-DMI SIP15.
> +
> +  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
> +**/
> +VOID
> +PchDmi15SetCustomThermalThrottling (
> +  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
> +  )
> +{
> +  UINT32  Data32And;
> +  UINT32  Data32Or;
> +
> +  ///
> +  /// DMI Throttling action
> +  ///
> +  Data32And = (UINT32)~(B_PCH_DMI15_PCR_UPHWAWC_TS3TW |
> B_PCH_DMI15_PCR_UPHWAWC_TS2TW |
> +                        B_PCH_DMI15_PCR_UPHWAWC_TS1TW |
> B_PCH_DMI15_PCR_UPHWAWC_TS0TW);
> +  Data32Or  = (DmiThermalThrottling.ThermalSensor3TargetWidth <<
> N_PCH_DMI15_PCR_UPHWAWC_TS3TW) |
> +              (DmiThermalThrottling.ThermalSensor2TargetWidth <<
> N_PCH_DMI15_PCR_UPHWAWC_TS2TW) |
> +              (DmiThermalThrottling.ThermalSensor1TargetWidth <<
> N_PCH_DMI15_PCR_UPHWAWC_TS1TW) |
> +              (DmiThermalThrottling.ThermalSensor0TargetWidth <<
> N_PCH_DMI15_PCR_UPHWAWC_TS0TW) |
> +              B_PCH_DMI15_PCR_UPHWAWC_TSAWEN;
> +
> +  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI15_PCR_UPHWAWC,
> Data32And, Data32Or);
> +}
> +
> +
> +/**
> + Secure Register Lock data
> +
> + @param[out] SrlRegOffset        Register offset holding Secure Register Lock
> setting
> + @param[out] SrlRegMask          Mask for Secure Register Lock setting
> +**/
> +VOID
> +PchDmi15SrlRegData (
> +  OUT UINT16  *SrlRegOffset,
> +  OUT UINT32  *SrlRegMask
> +  )
> +{
> +  *SrlRegMask = B_PCH_DMI15_PCR_MPC_SRL;
> +  *SrlRegOffset = R_PCH_DMI15_PCR_MPC;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmiLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmiLib.c
> new file mode 100644
> index 0000000000..f1b2867659
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmiLib.c
> @@ -0,0 +1,569 @@
> +/** @file
> +  PCH DMI library.
> +
> +  Copyright (c) 2019 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 <Private/Library/PchDmiLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Private/Library/PchPsfPrivateLib.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsDmi.h>
> +
> +#include "PchDmi14.h"
> +#include "PchDmi15.h"
> +
> +/**
> +  This function checks if DMI Secured Register Lock (SRL) is set
> +
> +  @retval SRL state
> +**/
> +BOOLEAN
> +IsPchDmiLocked (
> +  VOID
> +  )
> +{
> +  if (IsPchWithPdmi ()) {
> +    return IsPchDmi15Locked ();
> +  } else {
> +    return IsPchDmi14Locked ();
> +  }
> +}
> +
> +/**
> +  Backward DMI library API compatibility
> +  ACPI base address programming is done in PSF
> +
> +  @param[in] Address                    Address for ACPI base.
> +
> +  @retval EFI_UNSUPPORTED               NOT supported programming.
> +**/
> +EFI_STATUS
> +PchDmiSetAcpiBase (
> +  IN  UINT16                            Address
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Backward DMI library API compatibility
> +  PWRMBASE is a standard BAR and doesn't require
> +  additional DMI base decoding programming
> +
> +  @param[in] Address                    Address for PWRM base.
> +
> +  @retval EFI_UNSUPPORTED               NOT supported programming.
> +**/
> +EFI_STATUS
> +PchDmiSetPwrmBase (
> +  IN  UINT32                            Address
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Set PCH TCO base address decoding in DMI
> +
> +  @param[in] Address                    Address for TCO base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiSetTcoBase (
> +  IN  UINT16                            Address
> +  )
> +{
> +  if (IsPchDmiLocked ()) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] to [SMBUS PCI
> offset 50h[15:5], 1].
> +  //
> +  PchPcrWrite16 (
> +    PID_DMI, R_PCH_DMI_PCR_TCOBASE,
> +    (Address | BIT1)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINT32                                Data32;
> +  //
> +  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
> +  //
> +  if (IsPchDmiLocked ()) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
> +  Data32 |= (UINT32) Address;
> +  Data32 |= B_LPC_CFG_GENX_DEC_EN;
> +  //
> +  // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the same
> value programmed in LPC/eSPI PCI Offset 84h~93h.
> +  //
> +  PchPcrWrite32 (
> +    PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4),
> +    Data32
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINT32                                Data32;
> +  //
> +  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
> +  //
> +  if (IsPchDmiLocked ()) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Data32 =  (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA);
> +  Data32 |= (UINT32) Address;
> +  Data32 |= B_LPC_CFG_GENX_DEC_EN;
> +  //
> +  // Program eSPI Generic IO Range #, PCR[DMI] + 27BCh to the same value
> programmed in eSPI PCI Offset A4h.
> +  //
> +  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, Data32);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Clear PCH LPC/eSPI generic IO range decoding in DMI
> +
> +  @param[in] RangeIndex                 Index of chosen range
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiClearLpcGenIoRange (
> +  IN  UINTN                             RangeIndex
> +  )
> +{
> +  //
> +  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
> +  //
> +  if (IsPchDmiLocked ()) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Program LPC Generic IO Range #, PCR[DMI] + 2730h ~ 273Fh to the same
> value programmed in LPC/eSPI PCI Offset 84h~93h.
> +  //
> +  PchPcrWrite32 (
> +    PID_DMI, (UINT16) (R_PCH_DMI_PCR_LPCLGIR1 + RangeIndex * 4),
> +    0
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Clear PCH eSPI CS1# generic IO range decoding in DMI
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PchDmiClearEspiCs1GenIoRange (
> +  VOID
> +  )
> +{
> +  //
> +  // This cycle decoding is only allowed to set when DMIC.SRL is 0.
> +  //
> +  if (IsPchDmiLocked ()) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +  //
> +  // Program LPC Generic IO Range #, PCR[DMI] + 27BCh to the same value
> programmed in eSPI PCI Offset A4h.
> +  //
> +  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_SEGIR, 0);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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, "PchDmiSetLpcMemRange Error. DMI is
> locked.\n"));
> +    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, "PchLpcMemRange2Set Error. DMI is locked.\n"));
> +    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;
> +}
> +
> +
> +/**
> +  Set PCH IO port 80h cycle decoding to PCIE root port in DMI
> +
> +  @param[in] RpNumber                   PCIE root port physical number.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +**/
> +EFI_STATUS
> +PchDmiSetIoPort80Decode (
> +  IN  UINTN                             RpNumber
> +  )
> +{
> +  UINT16            DmiRpDestinationId;
> +  PSF_PORT_DEST_ID  PsfRpDestinationId;
> +
> +  if (IsPchDmiLocked ()) {
> +    DEBUG ((DEBUG_ERROR, "PchIoPort80DecodeSet Error. DMI is
> locked.\n"));
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  ///
> +  /// IO port 80h is typically used by decoder/LED hardware for debug
> purposes.
> +  /// By default PCH will forward IO port 80h cycles to LPC bus. The Reserved
> Page Route (RPR) bit
> +  /// of General Control and Status register, located at PCR[DMI] + 274Ch[11] ,
> allows software to
> +  /// re-direct IO port 80h cycles to PCIe bus so that a target (for example, a
> debug card) on
> +  /// PCIe bus can receive and claim these cycles.
> +  /// The "RPR Destination ID", PCR[DMI] + 274Ch[31:16] need to be set
> accordingly to point
> +  /// to the root port that decode this range. Reading from Port 80h may not
> return valid values
> +  /// if the POST-card itself do not shadow the writes. Unlike LPC, PCIe does
> not shadow the Port 80 writes.
> +  ///
> +  PsfRpDestinationId = PsfPcieDestinationId ((UINT32)RpNumber);
> +
> +  DmiRpDestinationId = (UINT16)((0x2 << 12) |
> +                                (PsfRpDestinationId.Fields.PsfId << 8) |
> +                                (PsfRpDestinationId.Fields.PortGroupId << 7) |
> +                                (PsfRpDestinationId.Fields.PortId << 3) |
> +                                 PsfRpDestinationId.Fields.ChannelId);
> +
> +  //
> +  // Program "RPR Destination ID", PCR[DMI] + 274Ch[31:16] to the Dest ID of
> RP.
> +  //
> +  PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_GCS + 2, DmiRpDestinationId);
> +  //
> +  // Program "Reserved Page Route", PCR[DMI] + 274Ch[11] to '1'.
> +  // Use byte write on GCS+1 and leave the BILD bit which is RWO.
> +  //
> +  PchPcrAndThenOr8 (PID_DMI, R_PCH_DMI_PCR_GCS + 1, 0xFF,
> (B_PCH_DMI_PCR_RPR >> 8));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Set DMI thermal throttling to recommended configuration.
> +  It's intended only for P-DMI.
> +**/
> +VOID
> +PchDmiSetRecommendedThermalThrottling (
> +  VOID
> +  )
> +{
> +  if (IsPchWithPdmi ()) {
> +    PchDmi15SetRecommendedThermalThrottling ();
> +  }
> +}
> +
> +/**
> +  Set DMI thermal throttling to custom configuration.
> +  This function will configure Thermal Sensor 0/1/2/3 TargetWidth and set
> +  DMI Thermal Sensor Autonomous Width Enable.
> +  It's intended only for P-DMI.
> +
> +  @param[in] DmiThermalThrottling        DMI Thermal Throttling structure.
> +**/
> +VOID
> +PchDmiSetCustomThermalThrottling (
> +  IN DMI_THERMAL_THROTTLING      DmiThermalThrottling
> +  )
> +{
> +  if (IsPchWithPdmi ()) {
> +    PchDmi15SetCustomThermalThrottling (DmiThermalThrottling);
> +  }
> +}
> +
> +/**
> +  Determines where to send the reserved page registers
> +  Accesses to the I/O ranges 80h - 8Fh will be forwarded to PCIe Root Port
> +  with the destination ID specified in GCS.RPRDID using DMI source decode.
> +**/
> +VOID
> +PchDmiSetReservedPageRegToPcieRootPort (
> +  VOID
> +  )
> +{
> +  PchPcrAndThenOr8 (
> +    PID_DMI, R_PCH_DMI_PCR_GCS + 1,
> +    (UINT8) ~0,
> +    (UINT8) (B_PCH_DMI_PCR_RPR >> 8)
> +    );
> +}
> +
> +/**
> +  Determines where to send the reserved page registers
> +  DMI will not perform source decode on the I/O ranges 80h - 8Fh. The cycles
> hitting these ranges will
> +  end up in P2SB which will then forward the cycle to LPC or eSPI through IOSF
> Sideband.
> +**/
> +VOID
> +PchDmiSetReservedPageRegToLpc (
> +  VOID
> +  )
> +{
> +  PchPcrAndThenOr8 (
> +    PID_DMI, R_PCH_DMI_PCR_GCS + 1,
> +    (UINT8) (~(B_PCH_DMI_PCR_RPR >> 8)),
> +    0
> +    );
> +}
> +
> +/**
> +  uCode Patch Region Enable (UPRE). Enables memory access targeting the
> uCode patch region (0xFEF00000 to 0xFEFFFFFF)
> +  to be forwarded to SPI Flash. This can only be set if the boot flash is on SPI.
> +**/
> +VOID
> +PchDmiEnableUCodePatchRegion (
> +  VOID
> +  )
> +{
> +  ///
> +  /// Setup "uCode Patch Region Enable", PCR [DMI] + 2748h[0] to '0b'
> +  ///
> +  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI_PCR_UCPR, (UINT32)
> ~B_PCH_DMI_PCR_UCPR_UPRE, 0);
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmiWithS3Lib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmiWithS3Lib.c
> new file mode 100644
> index 0000000000..9778c9a252
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiL
> ib/PchDmiWithS3Lib.c
> @@ -0,0 +1,79 @@
> +/** @file
> +  PCH DMI library with S3 boot script support.
> +
> +  Copyright (c) 2019 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/PchRegsPcr.h>
> +#include <Register/PchRegsDmi.h>
> +
> +#include "PchDmi14.h"
> +#include "PchDmi15.h"
> +
> +/**
> +  Configure PCH DMI Lock
> +**/
> +VOID
> +PchDmiSetLockWithS3BootScript (
> +  VOID
> +  )
> +{
> +  UINT32  Data32Or;
> +  UINT32  Data32And;
> +  UINT16  Address;
> +
> +  Data32And = 0xFFFFFFFF;
> +  if (IsPchWithPdmi ()) {
> +    PchDmi15SrlRegData (&Address, &Data32Or);
> +  } else {
> +    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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitC
> ommonLib/PchInitCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitC
> ommonLib/PchInitCommon.c
> new file mode 100644
> index 0000000000..14bd51ec43
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitC
> ommonLib/PchInitCommon.c
> @@ -0,0 +1,221 @@
> +/** @file
> +  Pch common library for PCH INIT PEI/DXE/SMM modules
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <PchPolicyCommon.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/PchSbiAccessLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Register/PchRegsPcie.h>
> +
> +extern CONST PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[];
> +extern CONST UINT32 mPchPcieControllerInfoSize;
> +
> +#define PORT_PLS_TIMEOUT 100    ///< 100 * 10 us = 1ms timeout for USB3
> PortSC PLS polling
> +
> +/**
> +  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 < mPchPcieControllerInfoSize);
> +  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));
> +}
> +
> +/**
> +  Calculate root port device number based on physical port index.
> +
> +  @param[in]  RpIndex              Root port index (0-based).
> +
> +  @retval     Root port device number.
> +**/
> +UINT32
> +PchGetPcieRpDevice (
> +  IN  UINT32   RpIndex
> +  )
> +{
> +  UINTN ControllerIndex;
> +  ControllerIndex = RpIndex / PCH_PCIE_CONTROLLER_PORTS;
> +  ASSERT (ControllerIndex < mPchPcieControllerInfoSize);
> +  return mPchPcieControllerInfo[ControllerIndex].DevNum;
> +}
> +
> +/**
> +  This function reads Pci Config register via SBI Access
> +
> +  @param[in]  RpIndex             Root Port Index (0-based)
> +  @param[in]  Offset              Offset of Config register
> +  @param[out] *Data32             Value of Config register
> +
> +  @retval EFI_SUCCESS             SBI Read successful.
> +**/
> +EFI_STATUS
> +PchSbiRpPciRead32 (
> +  IN    UINT32  RpIndex,
> +  IN    UINT32  Offset,
> +  OUT   UINT32  *Data32
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINT32        RpDevice;
> +  UINT8         Response;
> +  UINT16        Fid;
> +
> +  RpDevice = PchGetPcieRpDevice (RpIndex);
> +  Fid = (UINT16) ((RpDevice << 3) | (RpIndex % 4 ));
> +  Status = PchSbiExecutionEx (
> +             GetRpSbiPid (RpIndex),
> +             Offset,
> +             PciConfigRead,
> +             FALSE,
> +             0xF,
> +             0,
> +             Fid,
> +             Data32,
> +             &Response
> +             );
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG((DEBUG_ERROR,"Sideband Read Failed of RpIndex %d Offset 0x%x.
> Device = %d Fid = 0x%x\n",RpIndex, Offset, RpDevice, Fid));
> +    ASSERT (FALSE);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  This function And then Or Pci Config register via SBI Access
> +
> +  @param[in]  RpIndex             Root Port Index (0-based)
> +  @param[in]  Offset              Offset of Config register
> +  @param[in]  Data32And           Value of Config register to be And-ed
> +  @param[in]  Data32AOr           Value of Config register to be Or-ed
> +
> +  @retval EFI_SUCCESS             SBI Read and Write successful.
> +**/
> +EFI_STATUS
> +PchSbiRpPciAndThenOr32 (
> +  IN  UINT32  RpIndex,
> +  IN  UINT32  Offset,
> +  IN  UINT32  Data32And,
> +  IN  UINT32  Data32Or
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINT32      RpDevice;
> +  UINT32      Data32;
> +  UINT8       Response;
> +  UINT16      Fid;
> +
> +  RpDevice = PchGetPcieRpDevice (RpIndex);
> +  Status = PchSbiRpPciRead32 (RpIndex, Offset, &Data32);
> +  if (Status == EFI_SUCCESS) {
> +    Data32 &= Data32And;
> +    Data32 |= Data32Or;
> +    Fid = (UINT16) ((RpDevice << 3) | (RpIndex % 4 ));
> +    Status = PchSbiExecutionEx (
> +               GetRpSbiPid (RpIndex),
> +               Offset,
> +               PciConfigWrite,
> +               FALSE,
> +               0xF,
> +               0,
> +               Fid,
> +               &Data32,
> +               &Response
> +               );
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG((DEBUG_ERROR,"Sideband Write Failed of RpIndex %d Offset
> 0x%x. Device = %d Fid = 0x%x\n",RpIndex, Offset, RpDevice, Fid));
> +      ASSERT (FALSE);
> +    }
> +  } else {
> +    ASSERT (FALSE);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  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
> +PrintRegisters (
> +  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
> +PrintPciRegisters (
> +  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"));
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PchPciExpressHelpersLibrary.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PchPciExpressHelpersLibrary.c
> new file mode 100644
> index 0000000000..dcb43285b7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciEx
> pressHelpersLib/PchPciExpressHelpersLibrary.c
> @@ -0,0 +1,2407 @@
> +/** @file
> +  This file contains routines that support PCI Express initialization
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchPciExpressHelpersLibrary.h"
> +#include <Library/BaseMemoryLib.h>
> +
> +#define ASPM_L1_NO_LIMIT 0xFF
> +#define ASPM_L0s_NO_LIMIT 0x7
> +
> +#define LINK_RETRAIN_WAIT_TIME 1000 // microseconds
> +//
> +// This structure conveniently keeps segment:bus:device:function
> coordinates of a PCIe device
> +// in a single variable. PcieCap is offset to PCI Express capabilities. Having it
> cached together
> +// with coordinates is an optimization feature, because code in this file uses
> it a lot
> +//
> +typedef struct {
> +  UINT32 Seg     : 8;
> +  UINT32 Bus     : 8;
> +  UINT32 Dev     : 5;
> +  UINT32 Func    : 3;
> +  UINT32 PcieCap : 8;
> +} SBDF;
> +
> +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;
> +
> +typedef struct {
> +  UINT32 MaxSnoopLatencyValue         : 10;
> +  UINT32 MaxSnoopLatencyScale         : 3;
> +  UINT32 MaxNoSnoopLatencyValue       : 10;
> +  UINT32 MaxNoSnoopLatencyScale       : 3;
> +} LTR_LIMIT;
> +
> +#define MSLV_BIT_OFFSET   0
> +#define MSLS_BIT_OFFSET  10
> +#define MNSLV_BIT_OFFSET 13
> +#define MNSLS_BIT_OFFSET 23
> +
> +
> +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);
> +}
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  Translate PCIe Port/Lane pair to 0-based PCIe lane number.
> +
> +  @param[in] RpIndex    Root Port index
> +  @param[in] RpLane     Root Port Lane (0-3)
> +
> +  @retval PCIe lane number (0-based)
> +**/
> +UINT32
> +PchPciePhysicalLane (
> +  UINT32 RpIndex,
> +  UINT32 RpLane
> +  )
> +{
> +  UINT32  ControllerIndex;
> +  UINT32  ControllerLane;
> +
> +  ASSERT (RpIndex < GetPchMaxPciePortNum ());
> +  ASSERT (((RpIndex % 4) + RpLane) < 4);
> +
> +  ControllerIndex = (RpIndex / 4);
> +  ControllerLane  = (RpIndex % 4) + RpLane;
> +  if (IsPcieLaneReversalEnabled (RpIndex)) {
> +    ControllerLane = 3 - ControllerLane;
> +  }
> +  return (ControllerIndex * 4) + ControllerLane;
> +}
> +
> +/**
> +  Checks if lane reversal is enabled on a given root port
> +
> +  @param[in] RpIndex  Root port index (0-based)
> +
> +  @retval TRUE if lane reversal is enbabled, FALSE otherwise
> +**/
> +BOOLEAN
> +IsPcieLaneReversalEnabled (
> +  IN     UINT32  RpIndex
> +  )
> +{
> +  UINT32  Data32;
> +  PchSbiRpPciRead32 (PchGetPcieFirstPortIndex (RpIndex),
> R_PCH_PCIE_CFG_PCIEDBG, &Data32);
> +  return !! (Data32 & B_PCH_PCIE_CFG_PCIEDBG_LR);
> +}
> +
> +/**
> +  Calculates the index of the first port on the same controller.
> +
> +  @param[in] RpIndex     Root Port Number (0-based)
> +
> +  @retval Index of the first port on the first controller.
> +**/
> +UINT32
> +PchGetPcieFirstPortIndex (
> +  IN     UINT32  RpIndex
> +  )
> +{
> +  UINT32  ControllerIndex;
> +
> +  ControllerIndex = RpIndex / PCH_PCIE_CONTROLLER_PORTS;
> +  return ControllerIndex * PCH_PCIE_CONTROLLER_PORTS;
> +}
> +
> +/*
> +  Returns Tpower_on capability of device
> +
> +  @param[in] DeviceBase       device's PCI segment base address
> +  @param[in] L1ssCapOffset    offset to L1substates capability in device's
> extended config space
> +
> +  @retval                     structure containing Tpoweron scale and value
> +*/
> +T_POWER_ON
> +GetTpoCapability (
> +  UINT64 DeviceBase,
> +  UINT32 L1ssCapOffset
> +  )
> +{
> +  T_POWER_ON Tpo;
> +  UINT32     L1ssCapabilities;
> +
> +  L1ssCapabilities = PciSegmentRead32 (DeviceBase + L1ssCapOffset +
> R_PCIE_EX_L1SCAP_OFFSET);
> +  Tpo.Scale = (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTPOS) >>
> N_PCIE_EX_L1SCAP_PTPOS;
> +  Tpo.Value = (L1ssCapabilities & B_PCIE_EX_L1SCAP_PTV) >>
> N_PCIE_EX_L1SCAP_PTV;
> +  return Tpo;
> +}
> +
> +/*
> +  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);
> +}
> +
> +/**
> +  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
> +          ///
> +          DEBUG ((DEBUG_INFO,"CapId %x,%x->%02x\n",
> ((UINT32)(DeviceBase&0xFFFFF000)>>12), CapId, CapHeaderOffset));
> +          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;
> +
> +  DEBUG ((DEBUG_INFO,"PcieFindCapId () SBDF %0x: %0x: %0x :%0x, CapId =
> %0x \n", Segment, Bus, Device, Function, CapId));
> +  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_PCH_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);
> +}
> +
> +/**
> +  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
> +**/
> +STATIC
> +BOOLEAN
> +PcieIsPhyLanePgEnabled (
> +  IN     UINT64  RpBase
> +  )
> +{
> +  UINT32 Data32;
> +  Data32 = PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL);
> +  return (Data32 & B_PCH_PCIE_CFG_PCIEPMECTL_DLSULPPGE) != 0;
> +}
> +
> +/**
> +  Get current PCIe link speed.
> +
> +  @param[in] RpBase    Root Port base address
> +  @retval Link speed
> +**/
> +UINT32
> +GetLinkSpeed (
> +  UINT64  RpBase
> +  )
> +{
> +  return PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_LSTS) &
> B_PCIE_LSTS_CLS;
> +}
> +
> +/**
> +  Get max PCIe link speed supported by the root port.
> +
> +  @param[in] RpBase    Root Port base address
> +  @retval Max link speed
> +**/
> +UINT32
> +GetMaxLinkSpeed (
> +  UINT64 RpBase
> +  )
> +{
> +  return PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) &
> B_PCIE_LCAP_MLS;
> +}
> +
> +/**
> +  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);
> +}
> +
> +/**
> +  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
> +**/
> +STATIC
> +BOOLEAN
> +IsLtrCapable (
> +  SBDF Sbdf
> +  )
> +{
> +  if (Sbdf.PcieCap == 0) {
> +    return FALSE;
> +  }
> +  return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap +
> R_PCIE_DCAP2_OFFSET) & B_PCIE_DCAP2_LTRMS);
> +}
> +
> +/**
> +  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);
> +}
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  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;
> +  }
> +}
> +
> +/**
> +  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;
> +}
> +
> +/**
> +  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
> +**/
> +STATIC
> +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};
> +
> +  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;
> +  }
> +  Result.ForceOverride = FALSE;
> +  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
> +**/
> +STATIC
> +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;
> +}
> +
> +/**
> +  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_PCH_PCIE_LTRECH_CID);
> +  if (LtrCapOffset == 0) {
> +    return;
> +  }
> +  Data16 = (UINT16)((Ltr.MaxSnoopLatencyValue <<
> N_PCH_PCIE_LTRECH_MSLR_VALUE) | (Ltr.MaxSnoopLatencyScale <<
> N_PCH_PCIE_LTRECH_MSLR_SCALE));
> +  PciSegmentWrite16(Base + LtrCapOffset +
> R_PCH_PCIE_LTRECH_MSLR_OFFSET, Data16);
> +
> +  Data16 = (UINT16)((Ltr.MaxNoSnoopLatencyValue <<
> N_PCH_PCIE_LTRECH_MNSLR_VALUE) | (Ltr.MaxNoSnoopLatencyScale <<
> N_PCH_PCIE_LTRECH_MNSLR_SCALE));
> +  PciSegmentWrite16(Base + LtrCapOffset +
> R_PCH_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
> +**/
> +STATIC
> +BOOLEAN
> +FindNextPcieChild (
> +  IN     PCI_DEV_TYPE ParentDevType,
> +  IN OUT SBDF   *Sbdf
> +  )
> +{
> +  while ( FindNextLegalSbdf (ParentDevType, Sbdf)) {
> +    if (IsPcieDevice (Sbdf)) {
> +      return TRUE;
> +    }
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Checks device's Slot Clock Configuration
> +
> +  @param[in] Base            device's base address
> +
> +  @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] 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] Sbdf           Device's Segment:Bus:Device:Function
> coordinates
> +  @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));
> +  }
> +}
> +
> +/**
> +  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] Base            device's base address
> +**/
> +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 == 0xFF)) {
> +      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) {
> +    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
> +  )
> +{
> +  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);
> +  }
> +  ///
> +  ///  Set L1.2 LTR threshold to 80us (value = 0x50, scale = 0x2 = 1024ns), in
> accordance to BWG
> +  ///  BUG BUG BUG  It shouldn't be hardcoded, it should consider Tpoweron,
> otherwise we risk situation where
> +  ///  BUG BUG BUG  threshold is lower than Tpo, and every L1 entry turns
> into L1.2 entry with no possibility
> +  ///  BUG BUG BUG  to exit before LTR elapses, because exit can take no less
> than Tpo
> +  ///
> +  Ctrl1Register |= (0x50 << N_PCIE_EX_L1SCTL1_L12LTRTLV);
> +  Ctrl1Register |= (2 << N_PCIE_EX_L1SCTL1_L12LTRTLSV);
> +
> +  Ctrl2Register |= (L1ss.TpoScale);
> +  Ctrl2Register |= (L1ss.TpoValue << N_PCIE_EX_L1SCTL2_POWT);
> +
> +  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
> +  //
> +  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;
> +
> +  DEBUG ((DEBUG_INFO, "RecursiveL1ssConfiguration %x:%x:%x\n", Sbdf.Bus,
> Sbdf.Dev, Sbdf.Func));
> +
> +  Base = SbdfToBase (Sbdf);
> +  //
> +  // 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);
> +        SetL1ss (ChildSbdf, CombinedCaps, Override);
> +      }
> +    }
> +  }
> +  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);
> +}
> +
> +/**
> +  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
> +**/
> +STATIC
> +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 rootport packet split.
> +
> +  @param[in] Segment,Bus,Device,Function    address of currently visited
> PCIe device
> +  @param[in] Mps                            maximum packet size
> +**/
> +STATIC
> +VOID
> +ConfigureRpPacketSplit (
> +  SBDF   RpSbdf,
> +  UINT8  Mps
> +  )
> +{
> +  UINT64 RpBase;
> +
> +  RpBase = SbdfToBase (RpSbdf);
> +  PciSegmentAndThenOr32 (RpBase + R_PCH_PCIE_CFG_CCFG, (UINT32)
> ~(B_PCH_PCIE_CFG_CCFG_UNRS), Mps << N_PCH_PCIE_CFG_CCFG_UNRS);
> +}
> +
> +/**
> +  Configures LTR override in rootport's proprietary registers.
> +
> +  @param[in] Segment,Bus,Device,Function    address of currently visited
> PCIe device
> +  @param[in] RpConfig                       rootport configuration
> +  @param[in] TreeLtr                        combination of LTR override values
> from all devices under this rootport
> +**/
> +STATIC
> +VOID
> +ConfigureRpLtrOverride (
> +  SBDF                      RpSbdf,
> +  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
> +  OVERRIDE_TABLE            *AspmOverride
> +  )
> +{
> +  UINT64       RpBase;
> +  UINT32       OvrEn;
> +  UINT32       OvrVal;
> +  LTR_OVERRIDE TreeLtr;
> +
> +  OvrEn = 0;
> +  OvrVal = 0;
> +  RpBase = SbdfToBase (RpSbdf);
> +  //
> +  // 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
> +  //
> +
> +  TreeLtr = RecursiveLtrOverrideCheck (RpSbdf, AspmOverride);
> +
> +  if (RpConfig->ForceLtrOverride || TreeLtr.ForceOverride) {
> +    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_FORCE_OVERRIDE;
> +  }
> +  if (RpConfig->LtrConfigLock == TRUE) {
> +    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LOCK;
> +  }
> +
> +  if (RpConfig->SnoopLatencyOverrideMode == 1) {
> +    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN;
> +    OvrVal |= RpConfig->SnoopLatencyOverrideValue;
> +    OvrVal |= RpConfig->SnoopLatencyOverrideMultiplier << 10;
> +    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRSROVR;
> +  } else if (RpConfig->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 (RpConfig->NonSnoopLatencyOverrideMode == 1) {
> +    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN;
> +    OvrVal |= RpConfig->NonSnoopLatencyOverrideValue << 16;
> +    OvrVal |= RpConfig->NonSnoopLatencyOverrideMultiplier << 26;
> +    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRNSROVR;
> +  } else if (RpConfig->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 %x:%x Val %x En %x\n",
> RpSbdf.Dev, RpSbdf.Func, 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] 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] IoApicPresent  TRUE if there's IoAPIC behind this rootprot
> +**/
> +VOID
> +ConfigureEoiForwarding (
> +  UINT8    RpSegment,
> +  UINT8    RpBus,
> +  UINT8    RpDevice,
> +  UINT8    RpFunction,
> +  BOOLEAN  IoApicPresent
> +  )
> +{
> +  UINT64 RpBase;
> +  UINT32 RpIndex;
> +
> +  RpBase = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice,
> RpFunction, 0);
> +  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
> +    /// accordingly to PCH 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 rootport
> +
> +  @param[in] RpSbdf   segment:bus:device:function coordinates of rootport
> +**/
> +STATIC
> +VOID
> +L1ssProprietaryConfiguration (
> +  SBDF RpSbdf
> +  )
> +{
> +  BOOLEAN ClkreqSupported;
> +  BOOLEAN L1ssEnabled;
> +  UINT16  PcieCapOffset;
> +  UINT32  Data32;
> +  BOOLEAN L1LowSupported;
> +  UINT64  RpBase;
> +
> +  RpBase = SbdfToBase (RpSbdf);
> +  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 && IsLtrCapable (RpSbdf)
> && !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 L1LOW)
> +    ///
> +    PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL,
> B_PCH_PCIE_CFG_PCIEPMECTL_L1FSOE);
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  UINT8      Mps;
> +  BOOLEAN    IoApicPresent;
> +  UINT64     RpBase;
> +  SBDF       RpSbdf;
> +  SBDF_TABLE BridgeCleanupList;
> +
> +  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);
> +  ConfigureRpPacketSplit (RpSbdf, Mps);
> +  IoApicPresent = RecursiveIoApicCheck (RpSbdf);
> +  ConfigureEoiForwarding (RpSegment, RpBus, RpDevice, RpFunction,
> IoApicPresent);
> +  RecursiveCccConfiguration (RpSbdf, TRUE);
> +
> +  ClearBusFromTable (&BridgeCleanupList);
> +}
> +
> +/**
> +  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] AspmOverrideTableSize    size of override array
> +  @param[in] AspmOverrideTable        array of device that need exceptions
> in configuration
> +  @param[in] PerformAspmConfiguration enables/disables ASPM
> programming
> +**/
> +VOID
> +RootportDownstreamPmConfiguration (
> +  UINT8                     RpSegment,
> +  UINT8                     RpBus,
> +  UINT8                     RpDevice,
> +  UINT8                     RpFunction,
> +  UINT8                     BusMin,
> +  UINT8                     BusMax,
> +  PCH_PCIE_ROOT_PORT_CONFIG *RpConfig,
> +  UINT32                    AspmOverrideTableSize,
> +  PCH_PCIE_DEVICE_OVERRIDE  *AspmOverrideTable
> +  )
> +{
> +  LTR_LIMIT      PolicyLtr;
> +  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 = (RpConfig->LtrMaxNoSnoopLatency &
> 0x1c00) >> 10;
> +  PolicyLtr.MaxNoSnoopLatencyValue = RpConfig->LtrMaxNoSnoopLatency &
> 0x3FF;
> +  PolicyLtr.MaxSnoopLatencyScale   = (RpConfig->LtrMaxSnoopLatency &
> 0x1c00) >> 10;
> +  PolicyLtr.MaxSnoopLatencyValue   = RpConfig->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);
> +  ConfigureRpLtrOverride (RpSbdf, RpConfig, &PmOverrideTable);
> +  if (RpConfig->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 (RpSbdf);
> +  RecursiveAspmConfiguration (RpSbdf, 0, &PmOverrideTable);
> +  ClearBusFromTable (&BridgeCleanupList);
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLib.c
> new file mode 100644
> index 0000000000..f2d20c625a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLib.c
> @@ -0,0 +1,542 @@
> +/** @file
> +  This file contains PSF routines for RC usage
> +
> +  Copyright (c) 2019 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/SaPlatformLib.h>
> +#include <Private/Library/PchPsfPrivateLib.h>
> +#include <PchLimits.h>
> +#include <Register/PchRegsPsf.h>
> +#include <Register/PchRegsPcie.h>
> +#include "PchPsfPrivateLibInternal.h"
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
> +    ~0u,
> +    B_PCH_PSFX_PCR_T0_SHDW_PCIEN_FUNDIS
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  // If there is PCI access right after the PSF hide device, the device might
> +  // still be accessible since the PSF cycle is not completed yet, and causes
> +  // the race condition between sideband and primary cycles.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS,
> +    ~0u,
> +    B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_CFG_DIS,
> +    (UINT32) ~(B_PCH_PSFX_PCR_T0_SHDW_CFG_DIS_CFGDIS),
> +    0
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // BAR0-5 supported
> +  //
> +  ASSERT (BarDisMask < BIT6);
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
> +    ~0u,
> +    BarDisMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // BAR0-5 supported
> +  //
> +  ASSERT (BarEnMask < BIT6);
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
> +    (UINT32)~(BarEnMask << N_PCH_PSFX_PCR_T0_SHDW_PCIEN_BARXDIS),
> +    0
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
> +    ~(UINT32)(B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN),
> +    0
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_PCIEN,
> +    ~0u,
> +    B_PCH_PSFX_PCR_T0_SHDW_PCIEN_IOEN
> +    );
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  ASSERT (BarNum < 6);
> +
> +  if (PSF_IS_PORT_NULL (PsfPort)) {
> +    ASSERT (FALSE);
> +    return;
> +  }
> +
> +  //
> +  // Read back is needed to enforce the sideband and primary ordering.
> +  //
> +  PchPcrAndThenOr32WithReadback (
> +    PsfPort.PsfPid,
> +    PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0 + BarNum * 0x4,
> +    0,
> +    BarValue
> +    );
> +}
> +
> +/**
> +  Hide PMC device at PSF level
> +**/
> +VOID
> +PsfHidePmcDevice (
> +  VOID
> +  )
> +{
> +  PsfHideDevice (PsfPmcPort ());
> +}
> +
> +/**
> +  Set PMC ABASE value in PSF
> +
> +  @param[in] Address     Address for ACPI base address.
> +**/
> +VOID
> +PsfSetPmcAbase (
> +  IN  UINT16       Address
> +  )
> +{
> +  PSF_PORT PsfPort;
> +
> +  PsfPort = PsfPmcPort ();
> +
> +  ASSERT (PchPcrRead32 (PsfPort.PsfPid, PsfPort.RegBase +
> R_PCH_PSFX_PCR_T0_SHDW_BAR4) != 0xFFFFFFFF);
> +
> +  //
> +  // Disable IOSpace before changing the address
> +  //
> +  PsfDisableDeviceIoSpace (PsfPort);
> +
> +  //
> +  // Program ABASE in PSF PMC space BAR4
> +  //
> +  PsfSetDeviceBarValue (PsfPort, 4, Address);
> +
> +  //
> +  // Enable IOSpace
> +  //
> +  PsfEnableDeviceIoSpace (PsfPort);
> +}
> +
> +/**
> +  Get PMC ABASE value from PSF
> +
> +  @retval Address     Address for ACPI base.
> +**/
> +UINT16
> +PsfGetPmcAbase (
> +  VOID
> +  )
> +{
> +  UINT16    Address;
> +  PSF_PORT  PsfPort;
> +
> +  PsfPort = PsfPmcPort ();
> +  //
> +  // Read ABASE from PSF PMC space BAR4
> +  //
> +  Address = PchPcrRead16 (
> +              PsfPort.PsfPid,
> +              PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR4
> +              );
> +
> +  ASSERT (Address != 0xFFFF);
> +
> +  return Address;
> +}
> +
> +/**
> +  Get PMC PWRMBASE value from PSF
> +
> +  @retval Address     Address for PWRM base.
> +**/
> +UINT32
> +PsfGetPmcPwrmBase (
> +  VOID
> +  )
> +{
> +  UINT32    Address;
> +  PSF_PORT  PsfPort;
> +
> +  PsfPort = PsfPmcPort ();
> +  //
> +  // Read PWRMBASE from PSF PMC space BAR0
> +  //
> +  Address = PchPcrRead32 (
> +              PsfPort.PsfPid,
> +              PsfPort.RegBase + R_PCH_PSFX_PCR_T0_SHDW_BAR0
> +              );
> +
> +  ASSERT (Address != 0xFFFFFFFF);
> +
> +  return Address;
> +}
> +
> +/**
> +  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 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/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLibCnl.c
> new file mode 100644
> index 0000000000..d1c87a9e84
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPr
> ivateLib/PchPsfPrivateLibCnl.c
> @@ -0,0 +1,338 @@
> +/** @file
> +  This file contains internal PSF routines for PCH PSF lib usage
> +
> +  Copyright (c) 2019 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 <Register/PchRegsPsfCnl.h>
> +#include <Register/PchRegsPcie.h>
> +#include "PchPsfPrivateLibInternal.h"
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoI2cPsfRegs[] =
> +{
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoI2cPsfRegs[] =
> +{
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE
> +};
> +
> +/**
> +  Return PSF_PORT for SerialIO I2C device
> +
> +  @param[in] I2cNum  Serial IO I2C device (I2C0, I2C1, ....)
> +
> +  @retval  PsfPort   PSF PORT structure for SerialIO I2C device
> +**/
> +PSF_PORT
> +PsfSerialIoI2cPort (
> +  IN UINT32  I2cNum
> +  )
> +{
> +  PSF_PORT PsfPort;
> +
> +  PsfPort.PsfPid = PID_PSF3;
> +
> +  if (IsPchLp ()) {
> +    if (I2cNum < ARRAY_SIZE(mPchLpSerialIoI2cPsfRegs)) {
> +      PsfPort.RegBase = mPchLpSerialIoI2cPsfRegs[I2cNum];
> +      return PsfPort;
> +    }
> +  } else {
> +    if (I2cNum < ARRAY_SIZE(mPchHSerialIoI2cPsfRegs)) {
> +      PsfPort.RegBase = mPchHSerialIoI2cPsfRegs[I2cNum];
> +      return PsfPort;
> +    }
> +  }
> +
> +  ASSERT(FALSE);
> +  return PSF_PORT_NULL;
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoSpiPsfRegs[] =
> +{
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoSpiPsfRegs[] =
> +{
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
> +};
> +
> +/**
> +  Return PSF_PORT for SerialIO SPI device
> +
> +  @param[in] SpiNum  Serial IO SPI device (SPI0, SPI1, ....)
> +
> +  @retval  PsfPort   PSF PORT structure for SerialIO SPI device
> +**/
> +PSF_PORT
> +PsfSerialIoSpiPort (
> +  IN UINT32  SpiNum
> +  )
> +{
> +  PSF_PORT PsfPort;
> +
> +  PsfPort.PsfPid = PID_PSF3;
> +
> +  if (IsPchLp ()) {
> +    if (SpiNum < ARRAY_SIZE(mPchLpSerialIoSpiPsfRegs)) {
> +      PsfPort.RegBase = mPchLpSerialIoSpiPsfRegs[SpiNum];
> +      return PsfPort;
> +    }
> +  } else {
> +    if (SpiNum < ARRAY_SIZE(mPchHSerialIoSpiPsfRegs)) {
> +      PsfPort.RegBase = mPchHSerialIoSpiPsfRegs[SpiNum];
> +      return PsfPort;
> +    }
> +  }
> +
> +  ASSERT(FALSE);
> +  return PSF_PORT_NULL;
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoUartPsfRegs[] =
> +{
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
> +  R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoUartPsfRegs[] =
> +{
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
> +  R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE
> +};
> +
> +/**
> +  Return PSF_PORT for SerialIO UART device
> +
> +  @param[in] UartNum  Serial IO UART device (UART0, UART1, ....)
> +
> +  @retval  PsfPort    PSF PORT structure for SerialIO UART device
> +**/
> +PSF_PORT
> +PsfSerialIoUartPort (
> +  IN UINT32  UartNum
> +  )
> +{
> +  PSF_PORT PsfPort;
> +
> +  PsfPort.PsfPid = PID_PSF3;
> +
> +  if (IsPchLp ()) {
> +    if (UartNum < ARRAY_SIZE(mPchLpSerialIoUartPsfRegs)) {
> +      PsfPort.RegBase = mPchLpSerialIoUartPsfRegs[UartNum];
> +      return PsfPort;
> +    }
> +  } else {
> +    if (UartNum < ARRAY_SIZE(mPchHSerialIoUartPsfRegs)) {
> +      PsfPort.RegBase = mPchHSerialIoUartPsfRegs[UartNum];
> +      return PsfPort;
> +    }
> +  }
> +
> +  ASSERT(FALSE);
> +  return PSF_PORT_NULL;
> +}
> +
> +/**
> +  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:
> +      if (IsPchLp ()) {
> +        *EoiTargetBase =
> R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
> +        *EoiControlBase =
> R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
> +        MaxTargets = 17;
> +      } else {
> +        *EoiTargetBase =
> R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
> +        *EoiControlBase =
> R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
> +        MaxTargets = 7;
> +      }
> +      break;
> +
> +    case 3:
> +      *EoiTargetBase =
> R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
> +      *EoiControlBase =
> R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI;
> +      MaxTargets = 1;
> +      break;
> +
> +    case 6:
> +      if (IsPchH ()) {
> +        *EoiTargetBase =
> R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
> +        *EoiControlBase =
> R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI;
> +        MaxTargets = 8;
> +      }
> +      break;
> +
> +    case 7:
> +      if (IsPchH ()) {
> +        *EoiTargetBase =
> R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
> +        *EoiControlBase =
> R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI;
> +        MaxTargets = 8;
> +      }
> +      break;
> +
> +    case 8:
> +      if (IsPchH ()) {
> +        *EoiTargetBase =
> R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
> +        *EoiControlBase =
> R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI;
> +        MaxTargets = 8;
> +      }
> +      break;
> +  }
> +  return MaxTargets;
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchLpRpDestId[] =
> +{
> +  {0x18000}, {0x18001}, {0x18002}, {0x18003}, // SPA: PSF1, PortID = 0
> +  {0x18200}, {0x18201}, {0x18202}, {0x18203}, // SPB: PSF1, PortID = 2
> +  {0x18400}, {0x18401}, {0x18402}, {0x18403}, // SPC: PSF1, PortID = 4
> +  {0x18600}, {0x18601}, {0x18602}, {0x18603}  // SPD: PSF1, PortID = 6
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchHRpDestId[] =
> +{
> +  {0x68000}, {0x68001}, {0x68002}, {0x68003}, // SPA: PSF6, PortID = 0
> +  {0x88000}, {0x88001}, {0x88002}, {0x88003}, // SPB: PSF8, PortID = 0
> +  {0x68100}, {0x68101}, {0x68102}, {0x68103}, // SPC: PSF6, PortID = 1
> +  {0x78000}, {0x78001}, {0x78002}, {0x78003}, // SPD: PSF7, PortID = 0
> +  {0x78100}, {0x78101}, {0x78102}, {0x78103}, // SPE: PSF7, PortID = 1
> +  {0x88100}, {0x88101}, {0x88102}, {0x88103}  // SPF: PSF8, PortID = 1
> +};
> +
> +/**
> +  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 (IsPchLp ()) {
> +    if (RpIndex < ARRAY_SIZE(PchLpRpDestId)) {
> +      return PchLpRpDestId[RpIndex];
> +    }
> +  } else {
> +    if (RpIndex < ARRAY_SIZE(PchHRpDestId)) {
> +      return PchHRpDestId[RpIndex];
> +    }
> +  }
> +  ASSERT (FALSE);
> +  return (PSF_PORT_DEST_ID){0};
> +}
> +
> +
> +/**
> +  Return PSF_PORT for PMC device
> +
> +  @retval    PsfPort         PSF PORT structure for PMC device
> +**/
> +PSF_PORT
> +PsfPmcPort (
> +  VOID
> +  )
> +{
> +  PSF_PORT PsfPort;
> +
> +  PsfPort.PsfPid = PID_PSF3;
> +
> +  if (IsPchLp ()) {
> +    PsfPort.RegBase = R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
> +  } else {
> +    PsfPort.RegBase = R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
> +  }
> +  return PsfPort;
> +}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchLpPsfTable[] =
> +{
> +  {1, PID_PSF1},
> +  {2, PID_PSF2},
> +  {3, PID_PSF3},
> +  {4, PID_PSF4},
> +  {5, PID_CSME_PSF}
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchHPsfTable[]  =
> +{
> +  {1, PID_PSF1},
> +  {2, PID_PSF2},
> +  {3, PID_PSF3},
> +  {4, PID_PSF4},
> +  {5, PID_CSME_PSF},
> +  {6, PID_PSF6},
> +  {7, PID_PSF7},
> +  {8, PID_PSF8}
> +};
> +
> +/**
> +  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
> +  )
> +{
> +  if (IsPchLp ()) {
> +    *PsfTable = mPchLpPsfTable;
> +    *PsfTableLength = ARRAY_SIZE(mPchLpPsfTable);
> +  } else {
> +    *PsfTable = mPchHPsfTable;
> +    *PsfTableLength = ARRAY_SIZE(mPchHPsfTable);
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiPmcPrivateLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiPmcPrivateLib.c
> new file mode 100644
> index 0000000000..f88febfa48
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PeiPmcPrivateLib.c
> @@ -0,0 +1,92 @@
> +/** @file
> +  PCH private PEI PMC Library for all PCH generations.
> +
> +  Copyright (c) 2019 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/PeiServicesLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchEspiLib.h>
> +#include <Private/Library/GpioPrivateLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsClk.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsLan.h>
> +#include "PmcPrivateLibInternal.h"
> +
> +/**
> +  Check if PCH PM Timer enabled based on platform policy
> +
> +  @retval TRUE       PCH PM Timer is enabled.
> +  @retval FALSE      PCH PM Timer is disabled.
> +**/
> +BOOLEAN
> +PmcIsPchPmTimerEnabled (
> +  VOID
> +  )
> +{
> +  BOOLEAN           PchPmTimerEnabled;
> +  EFI_STATUS        Status;
> +  SI_POLICY_PPI     *SiPolicy;
> +  PCH_PM_CONFIG     *PmConfig;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gSiPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **)&SiPolicy
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *)
> &PmConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  PchPmTimerEnabled = TRUE;
> +  if (!PmConfig->EnableTcoTimer) {
> +    PchPmTimerEnabled = FALSE;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "PmcIsPchPmTimerEnabled () = %x\n",
> PchPmTimerEnabled));
> +
> +  return PchPmTimerEnabled;
> +}
> +
> +/**
> +  Lock down PMC settings
> +
> +  @param[in] SiPolicy   The SI Policy PPI instance
> +**/
> +VOID
> +PmcLockSettings (
> +  IN  SI_POLICY_PPI     *SiPolicy
> +  )
> +{
> +
> +  UINT32         PchPwrmBase;
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  ///
> +  /// Set PWRMBASE Offset 0x1048 [24]
> +  ///
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ETR3, BIT24);
> +
> +  ///
> +  /// PM_SYNC_LOCK
> +  /// Set PWRMBASE Offset 0x18C8 [15]
> +  ///
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_PMSYNC_MISC_CFG,
> B_PMC_PWRM_PMSYNC_PM_SYNC_LOCK);
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLib.c
> new file mode 100644
> index 0000000000..a6ccf4b96b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLib.c
> @@ -0,0 +1,1033 @@
> +/** @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) 2019 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/TimerLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Private/Library/PchPsfPrivateLib.h>
> +#include <PchReservedResources.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsItss.h>
> +#include <IndustryStandard/Pci30.h>
> +
> +#include "PmcPrivateLibInternal.h"
> +
> +/**
> +  Send PMC IPC1 Normal Read/Write command
> +
> +  @param[in]  Command           Command to be issued to PMC IPC 1
> interface
> +  @param[in]  SubCmdId          SUB_CMD_ID for provided Command
> +  @param[in]  CmdSize           Total size in byte to be sent via PMC IPC 1
> interface
> +  @param[in]  WriteBufPtr       Pointer to Structure of 4 DWORDs to be
> issued to PMC IPC 1 interface
> +  @param[out] ReadBufPtr        Pointer to Structure of 4 DWORDs to be
> filled by PMC IPC 1 interface
> +
> +  @retval EFI_SUCCESS             Command was executed successfully
> +  @retval EFI_INVALID_PARAMETER   Invalid command size
> +  @retval EFI_DEVICE_ERROR        IPC command failed with an error
> +  @retval EFI_TIMEOUT             IPC command did not complete after 1s
> +**/
> +EFI_STATUS
> +PmcSendCommand (
> +  IN  UINT8                    Command,
> +  IN  UINT8                    SubCmdId,
> +  IN  UINT8                    CmdSize,
> +  IN  PMC_IPC_COMMAND_BUFFER   *WriteBufPtr,
> +  OUT PMC_IPC_COMMAND_BUFFER   *ReadBufPtr
> +  )
> +{
> +  EFI_STATUS             Status;
> +  UINT32                 PchPwrmBase;
> +  UINT32                 IpcSts;
> +  UINTN                  Timeout;
> +
> +  DEBUG ((DEBUG_INFO, "PmcSendCommand(): IPC_COMMAND=0x%02X,
> IPC_SUB_CMD = 0x%02X, IPC_SIZE=0x%02X \n", Command, SubCmdId,
> CmdSize));
> +  DEBUG ((DEBUG_INFO, "WBUF0=0x%08X, WBUF1=0x%08X, WBUF2=0x%08X,
> WBUF3=0x%08X \n", WriteBufPtr->Buf0, WriteBufPtr->Buf1,
> WriteBufPtr->Buf2, WriteBufPtr->Buf3));
> +
> +  if (CmdSize > 16) {
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Program the Write Buffer 0 with the Data that needs to be written to PMC
> +  //
> +  PchPwrmBase = PmcGetPwrmBase ();
> +  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF0),
> WriteBufPtr->Buf0);
> +  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF1),
> WriteBufPtr->Buf1);
> +  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF2),
> WriteBufPtr->Buf2);
> +  MmioWrite32 ((PchPwrmBase + R_PMC_PWRM_IPC_WBUF3),
> WriteBufPtr->Buf3);
> +  //
> +  // Program the command register with command and size
> +  //
> +  MmioWrite32 (
> +    PchPwrmBase + R_PMC_PWRM_IPC_CMD,
> +    (UINT32) ((CmdSize << N_PMC_PWRM_IPC_CMD_SIZE) |
> +      (SubCmdId << N_PMC_PWRM_IPC_CMD_CMD_ID) |
> +      (Command << N_PMC_PWRM_IPC_CMD_COMMAND))
> +    );
> +
> +  //
> +  // Read the IPC_STS register to get BUSY or Error status
> +  //
> +  Timeout = 0;
> +  Status = EFI_SUCCESS;
> +  while (TRUE) {
> +    IpcSts = MmioRead32 (PchPwrmBase + R_PMC_PWRM_IPC_STS);
> +    if ((IpcSts & B_PMC_PWRM_IPC_STS_BUSY) == 0) {
> +      break;
> +    }
> +
> +    if (Timeout > (1000 * 100)) {
> +      Status = EFI_TIMEOUT;
> +      break;
> +    }
> +    MicroSecondDelay (10);
> +    Timeout++;
> +  }
> +
> +  if ((IpcSts & B_PMC_PWRM_IPC_STS_ERROR) != 0) {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "PmcSendCommand() Error: IPC_STS=0x%08X\n",
> IpcSts));
> +    return Status;
> +  }
> +
> +  if (ReadBufPtr != NULL) {
> +    //
> +    // Fill the  ReadBuffer contents with the Data that needs to be read from
> PMC
> +    //
> +    ReadBufPtr->Buf0 = MmioRead32(PchPwrmBase +
> R_PMC_PWRM_IPC_RBUF0);
> +    ReadBufPtr->Buf1 = MmioRead32(PchPwrmBase +
> R_PMC_PWRM_IPC_RBUF1);
> +    ReadBufPtr->Buf2 = MmioRead32(PchPwrmBase +
> R_PMC_PWRM_IPC_RBUF2);
> +    ReadBufPtr->Buf3 = MmioRead32(PchPwrmBase +
> R_PMC_PWRM_IPC_RBUF3);
> +
> +    DEBUG ((DEBUG_INFO, "RBUF0=0x%08X, RBUF1=0x%08X, RBUF2=0x%08X,
> RBUF3=0x%08X \n", ReadBufPtr->Buf0, ReadBufPtr->Buf1, ReadBufPtr->Buf2,
> ReadBufPtr->Buf3));
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function checks if SCI interrupt is enabled
> +
> +  @retval SCI Enable state
> +**/
> +BOOLEAN
> +PmcIsSciEnabled (
> +  VOID
> +  )
> +{
> +  return ((IoRead8 (PmcGetAcpiBase () + R_ACPI_IO_PM1_CNT) &
> B_ACPI_IO_PM1_CNT_SCI_EN) != 0);
> +}
> +
> +/**
> +  This function triggers Software GPE
> +**/
> +VOID
> +PmcTriggerSwGpe (
> +  VOID
> +  )
> +{
> +  IoOr32 (PmcGetAcpiBase () + R_ACPI_IO_GPE_CNTL,
> B_ACPI_IO_GPE_CNTL_SWGPE_CTRL);
> +}
> +
> +/**
> +  Set PCH ACPI base address.
> +  The Address should not be 0 and should be 256 bytes aligned. It is IO space,
> so must not exceed 0xFFFF.
> +  Only address matching PcdAcpiBaseAddress is the acceptable value for ACPI
> IO Base
> +
> +  @param[in] Address                    Address for ACPI base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PmcSetAcpiBase (
> +  IN  UINT16                            Address
> +  )
> +{
> +
> +  if (Address != PcdGet16 (PcdAcpiBaseAddress)) {
> +    DEBUG ((DEBUG_ERROR, "PmcSetAcpiBase Error. Invalid Address: %x.\n",
> Address));
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PsfSetPmcAbase (Address);
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Set PCH PWRM base address.
> +  Only 0xFE000000 (PCH_PWRM_BASE_ADDRESS) is the acceptable value for
> PWRMBASE
> +
> +  @param[in] Address                    Address for PWRM base address.
> +
> +  @retval EFI_SUCCESS                   Successfully completed.
> +  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
> +**/
> +EFI_STATUS
> +PmcSetPwrmBase (
> +  IN  UINT32                            Address
> +  )
> +{
> +  UINT64                                PmcBase;
> +
> +  if (Address != PCH_PWRM_BASE_ADDRESS) {
> +    DEBUG ((DEBUG_ERROR, "PmcSetPwrmBase Error. Invalid Address: %x.\n",
> Address));
> +    ASSERT (FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PmcBase      = PCI_SEGMENT_LIB_ADDRESS (
> +                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_PMC,
> +                   PCI_FUNCTION_NUMBER_PCH_PMC,
> +                   0
> +                   );
> +  if (PciSegmentRead16 (PmcBase) == 0xFFFF) {
> +    ASSERT (FALSE);
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Disable PWRMBASE in PMC Device first before changing PWRM base
> address.
> +  //
> +  PciSegmentAnd16 (
> +    PmcBase + PCI_COMMAND_OFFSET,
> +    (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE
> +    );
> +
> +  //
> +  // Program PWRMBASE in PMC Device
> +  //
> +  PciSegmentAndThenOr32 (
> +    PmcBase + R_PMC_CFG_BASE,
> +    (UINT32) (~B_PMC_CFG_PWRM_BASE_MASK),
> +    Address
> +    );
> +
> +  //
> +  // Enable PWRMBASE in PMC Device
> +  //
> +  PciSegmentOr16 (
> +    PmcBase + PCI_COMMAND_OFFSET,
> +    EFI_PCI_COMMAND_MEMORY_SPACE
> +    );
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function checks if function disable (static and non-static power gating)
> +  configuration is locked
> +
> +  @retval lock state
> +**/
> +BOOLEAN
> +PmcIsFunctionDisableConfigLocked (
> +  VOID
> +  )
> +{
> +  return ((MmioRead32 (PmcGetPwrmBase () +
> R_PMC_PWRM_ST_PG_FDIS_PMC_1) &
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK) != 0);
> +}
> +
> +/**
> +  Check if MODPHY SUS PG is supported
> +
> +  @retval  Status of MODPHY SUS PG support
> +**/
> +BOOLEAN
> +PmcIsModPhySusPgSupported (
> +  VOID
> +  )
> +{
> +  if (IsPchLp ()) {
> +    //
> +    // MPHY SUS PG supported on PCH-LP only:
> +    //
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  This function checks if ISH is function disabled
> +  by static power gating
> +
> +  @retval ISH device state
> +**/
> +BOOLEAN
> +PmcIsIshFunctionDisabled (
> +  VOID
> +  )
> +{
> +  //
> +  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
> +  //
> +  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () +
> R_PMC_PWRM_ST_PG_FDIS_PMC_1)) &
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC) != 0);
> +}
> +
> +/**
> +  This function checks if ISH device is supported (not disabled by fuse)
> +
> +  @retval ISH support state
> +**/
> +BOOLEAN
> +PmcIsIshSupported (
> +  VOID
> +  )
> +{
> +  //
> +  // Get fuse info from PWRMBASE + FUSE_DIS_RD_2
> +  //
> +  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () +
> R_PMC_PWRM_FUSE_DIS_RD_2)) &
> B_PMC_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS) == 0);
> +}
> +
> +/**
> +  This function disables ISH device by static power gating.
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableIsh (
> +  VOID
> +  )
> +{
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] = 1b to statically disable ISH
> Controller
> +  //
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1,
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC);
> +}
> +
> +/**
> +  This function enables ISH device by disabling static power gating.
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableIsh (
> +  VOID
> +  )
> +{
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_1[5] = 0b to enable ISH controller
> +  //
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1,
> (UINT32) (~B_PMC_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC));
> +}
> +
> +/**
> +  This function checks if GbE is function disabled
> +  by static power gating
> +
> +  @retval GbE device state
> +**/
> +BOOLEAN
> +PmcIsGbeFunctionDisabled (
> +  VOID
> +  )
> +{
> +  //
> +  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
> +  //
> +  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () +
> R_PMC_PWRM_ST_PG_FDIS_PMC_1)) &
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC) != 0);
> +}
> +
> +/**
> +  This function disables GbE device by static power gating and enables
> ModPHY SPD gating (PCH-LP only).
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableGbe (
> +  VOID
> +  )
> +{
> +  UINT32 PchPwrmBase;
> +  PchPwrmBase = PmcGetPwrmBase ();
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] = 1b to statically disable GbE
> Controller
> +  //
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1,
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC);
> +
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // Set MSPDRTREQ:
> +    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[13] = 1 to enable ASL code
> trigger request for ModPHY SPD gating.
> +    //
> +    PmcGbeModPhyPowerGating ();
> +  }
> +}
> +
> +/**
> +  This function enables GbE device by disabling static power gating.
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableGbe (
> +  VOID
> +  )
> +{
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_1[0] = 0b to enable GbE controller
> +  //
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1,
> (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC);
> +}
> +
> +/**
> +  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 disables (non-static power gating) HDA device
> +**/
> +VOID
> +PmcDisableHda (
> +  VOID
> +  )
> +{
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1,
> B_PMC_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC);
> +}
> +
> +/**
> +  This function checks if Cnvi device is supported (not disabled by fuse)
> +
> +  @retval Cnvi support state
> +**/
> +BOOLEAN
> +PmcIsCnviSupported (
> +  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_CNVI_FUSE_SS_DIS) == 0);
> +}
> +
> +/**
> +  This function checks if CNVi is function disabled
> +  by static power gating
> +
> +  @retval GbE device state
> +**/
> +BOOLEAN
> +PmcIsCnviFunctionDisabled (
> +  VOID
> +  )
> +{
> +  //
> +  // Get PG info from PWRMBASE + ST_PG_FDIS_PMC_1
> +  //
> +  return ((MmioRead32 (PmcGetPwrmBase () +
> R_PMC_PWRM_ST_PG_FDIS_PMC_1) &
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC) != 0);
> +}
> +
> +/**
> +  This function enables CNVi device by disabling static power gating.
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableCnvi (
> +  VOID
> +  )
> +{
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_1 to enable CNVi controller
> +  //
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1,
> (UINT32) ~B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC);
> +}
> +
> +/**
> +  This function disables CNVi device by static power gating.
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableCnvi (
> +  VOID
> +  )
> +{
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_1,
> B_PMC_PWRM_ST_PG_FDIS_PMC_1_CNVI_FDIS_PMC);
> +}
> +
> +/**
> +  This function disables (non-static power gating) PCIe Root Port and enables
> ModPHY SPD gating (PCH-LP only).
> +
> +  @param[in] RpIndex        PCIe Root Port Index (0 based)
> +**/
> +VOID
> +PmcDisablePcieRootPort (
> +  IN UINT32  RpIndex
> +  )
> +{
> +  UINT32   NstPgFdis1Mask;
> +  UINT32   PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +  //
> +  // Set PchPwrmBase + NST_PG_FDIS_1 to function disable PCIE port in PMC
> +  //
> +  if (IsPchH () && RpIndex >= 20) {
> +    NstPgFdis1Mask =
> B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_PCIE_F0_FDIS_PMC << (RpIndex %
> 20);
> +  } else {
> +    NstPgFdis1Mask = B_PMC_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC
> << RpIndex;
> +  }
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1,
> NstPgFdis1Mask);
> +
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // Set MSPDRTREQ:
> +    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[26:0] = 1 to enable ASL
> code trigger request for ModPHY SPD gating.
> +    //
> +    if (RpIndex <= 11) {
> +      MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_A0 << RpIndex);
> +    } else {
> +      MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_D0 << (RpIndex - 12));
> +    }
> +  }
> +}
> +
> +/**
> +  This function disables (non-static power gating) xHCI and enables ModPHY
> SPD gating (PCH-LP only).
> +**/
> +VOID
> +PmcDisableXhci (
> +  VOID
> +  )
> +{
> +  UINT32   PchPwrmBase;
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  //
> +  // Set PWRMBASE + NST_PG_FDIS_1 [0] = 1b
> +  //
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1,
> B_PMC_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC);
> +
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // Set MSPDRTREQ:
> +    // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[14] = 1 to enable ASL
> code trigger request for ModPHY SPD gating.
> +    //
> +    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XHCI);
> +  }
> +}
> +
> +/**
> +  This function disables (non-static power gating) XDCI and enables ModPHY
> SPD gating (PCH-LP only).
> +**/
> +VOID
> +PmcDisableXdci (
> +  VOID
> +  )
> +{
> +  UINT32 PchPwrmBase;
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  //
> +  // Set PWRMBASE + NST_PG_FDIS_1 [26] = 1b to disable XDCI Controller in
> PMC
> +  //
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1,
> B_PMC_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC);
> +
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // Set MSPDRTREQ:
> +    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[15] = 1 to enable ASL code
> trigger request for ModPHY SPD gating.
> +    //
> +    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_XDCI);
> +  }
> +}
> +
> +/**
> +  This function checks if XDCI device is supported (not disabled by fuse)
> +
> +  @retval XDCI support state
> +**/
> +BOOLEAN
> +PmcIsXdciSupported (
> +  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_OTG_FUSE_SS_DIS) == 0);
> +}
> +
> +/**
> +  This function locks HOST SW power gating control
> +**/
> +VOID
> +PmcLockHostSwPgCtrl (
> +  VOID
> +  )
> +{
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1,
> B_PMC_PWRM_SW_PG_CTRL_LOCK);
> +}
> +
> +/**
> +  This function checks if HOST SW Power Gating Control is locked
> +
> +  @retval lock state
> +**/
> +BOOLEAN
> +PmcIsHostSwPgCtrlLocked (
> +  VOID
> +  )
> +{
> +  //
> +  // Get lock info from PWRMBASE + HSWPGCR1
> +  //
> +  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_HSWPGCR1)
> & B_PMC_PWRM_SW_PG_CTRL_LOCK) != 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);
> +}
> +
> +/**
> +  Disables USB2 Core PHY PowerGating during power on for Chipsetinit table
> update
> +**/
> +VOID
> +PmcUsb2CorePhyPowerGatingDisable (
> +  VOID
> +  )
> +{
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_CFG, (UINT32)
> ~B_PMC_PWRM_CFG_ALLOW_USB2_CORE_PG);
> +}
> +
> +
> +/**
> +  This function reads CPU Early Power-on Configuration (EPOC)
> +
> +  @retval CPU EPOC value
> +**/
> +UINT32
> +PmcGetCpuEpoc (
> +  VOID
> +  )
> +{
> +  return MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC);
> +}
> +
> +/**
> +  This function sets CPU Early Power-on Configuration (EPOC)
> +
> +  @param[in] CpuEpocValue      CPU EPOC value
> +**/
> +VOID
> +PmcSetCpuEpoc (
> +  IN UINT32     CpuEpocValue
> +  )
> +{
> +  MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_CPU_EPOC,
> CpuEpocValue);
> +}
> +
> +/**
> +  This function sets DRAM_RESET# Control Pin value
> +
> +  @param[in] DramResetVal      0: Pin output is low
> +                               1: Pin output is tri-stated
> +**/
> +VOID
> +PmcSetDramResetCtlState (
> +  IN UINT32     DramResetVal
> +  )
> +{
> +  ASSERT (DramResetVal < 2);
> +
> +  MmioAndThenOr32 (
> +    PmcGetPwrmBase () + R_PMC_PWRM_CFG2,
> +    (UINT32)~B_PMC_PWRM_CFG2_DRAM_RESET_CTL,
> +    DramResetVal << N_PMC_PWRM_CFG2_DRAM_RESET_CTL
> +    );
> +}
> +
> +/**
> +  This function enables triggering Global Reset of both
> +  the Host and the ME partitions after CF9h write of 6h or Eh
> +**/
> +VOID
> +PmcEnableCf9GlobalReset (
> +  VOID
> +  )
> +{
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32)
> (B_PMC_PWRM_ETR3_CF9GR));
> +}
> +
> +/**
> +  This function disables triggering Global Reset of both
> +  the Host and the ME partitions after CF9h write of 6h or Eh.
> +**/
> +VOID
> +PmcDisableCf9GlobalReset (
> +  VOID
> +  )
> +{
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32)
> ~B_PMC_PWRM_ETR3_CF9GR);
> +}
> +
> +/**
> +  This 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
> +PmcDisableCf9GlobalResetWithLock (
> +  VOID
> +  )
> +{
> +  MmioAndThenOr32 (
> +    PmcGetPwrmBase () + R_PMC_PWRM_ETR3,
> +    (UINT32) ~B_PMC_PWRM_ETR3_CF9GR,
> +    (UINT32) B_PMC_PWRM_ETR3_CF9LOCK
> +    );
> +}
> +
> +/**
> +  This function disables CF9 reset without Resume Well reset.
> +  Cf9 0x6/0xE reset will also reset resume well logic.
> +**/
> +VOID
> +PmcDisableCf9ResetWithoutResumeWell (
> +  VOID
> +  )
> +{
> +
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ETR3, (UINT32)
> ~B_PMC_PWRM_ETR3_CWORWRE);
> +}
> +
> +/**
> +  This function clears RTC Power Failure status (RTC_PWR_FLR)
> +**/
> +VOID
> +PmcClearRtcPowerFailureStatus (
> +  VOID
> +  )
> +{
> +  //
> +  // Set B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS to 0 to clear it.
> +  //
> +  MmioAnd8 ((UINTN) (PmcGetPwrmBase () +
> R_PMC_PWRM_GEN_PMCON_B), (UINT8)
> (~B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS));
> +}
> +
> +/**
> +  This function enables PCI Express* PME events
> +**/
> +VOID
> +PmcEnablePciExpressPmeEvents (
> +  VOID
> +  )
> +{
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B,
> B_PMC_PWRM_GEN_PMCON_B_BIOS_PCI_EXP_EN);
> +}
> +
> +/**
> +  This function sets eSPI SMI Lock
> +**/
> +VOID
> +PmcLockEspiSmi (
> +  VOID
> +  )
> +{
> +  MmioAndThenOr8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A
> + 1,
> +    (UINT8) ~((B_PMC_PWRM_GEN_PMCON_A_PWR_FLR |
> B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS) >> 8),
> +    B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK >> 8
> +    );
> +}
> +
> +/**
> +  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);
> +}
> +
> +/**
> +  This function sets 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
> +PmcSetGpioGpe (
> +  IN UINT32    GpeDw0Value,
> +  IN UINT32    GpeDw1Value,
> +  IN UINT32    GpeDw2Value
> +  )
> +{
> +  UINT32               Data32Or;
> +  UINT32               Data32And;
> +
> +  //
> +  // Program GPIO_CFG register
> +  //
> +  Data32And = (UINT32) ~(B_PMC_PWRM_GPIO_CFG_GPE0_DW2 |
> B_PMC_PWRM_GPIO_CFG_GPE0_DW1 |
> B_PMC_PWRM_GPIO_CFG_GPE0_DW0);
> +  Data32Or  = (UINT32) ((GpeDw2Value <<
> N_PMC_PWRM_GPIO_CFG_GPE0_DW2) |
> +                        (GpeDw1Value << N_PMC_PWRM_GPIO_CFG_GPE0_DW1)
> |
> +                        (GpeDw0Value <<
> N_PMC_PWRM_GPIO_CFG_GPE0_DW0));
> +
> +  MmioAndThenOr32 (
> +    (PmcGetPwrmBase () + R_PMC_PWRM_GPIO_CFG),
> +    Data32And,
> +    Data32Or
> +    );
> +}
> +
> +/**
> +  Disable SLP_S0# assertion when system is in debug mode
> +**/
> +VOID
> +PmcDisableSlpS0AssertionInDebugMode (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PMC_IPC_COMMAND_BUFFER    Wbuf;
> +
> +  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +
> +  Status = PmcSendCommand
> (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  Enable SLP_S0# assertion even when system is in debug mode
> +**/
> +VOID
> +PmcEnableSlpS0AssertionInDebugMode (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PMC_IPC_COMMAND_BUFFER    Wbuf;
> +
> +  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +
> +  Wbuf.Buf0 = 1;
> +  Status = PmcSendCommand
> (V_PMC_PWRM_IPC_CMD_COMMAND_SLP_CTRL, 0, 4, &Wbuf, NULL);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  This function gets NMI regsiter.
> +
> +  @retval  NMI register setting
> +**/
> +UINT32
> +PmcGetNmiControl (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PMC_IPC_COMMAND_BUFFER    Wbuf;
> +  PMC_IPC_COMMAND_BUFFER    Rbuf;
> +
> +  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +  ZeroMem (&Rbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +  //
> +  // WBUF0 = 2 for NMI delivery control and status register (entire register
> PCR[ITSS] 0x3330)
> +  //
> +  Wbuf.Buf0 = V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI;
> +  Status = PmcSendCommand (
> +             V_PMC_PWRM_IPC_CMD_COMMAND_PROXY,
> +             V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_READ,
> +             4,
> +             &Wbuf,
> +             &Rbuf
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +  return Rbuf.Buf0;
> +}
> +
> +/**
> +  This function sets the NMI register
> +
> +  @param[in]  NmiRegister    The whole NMI register
> +**/
> +VOID
> +PmcSetNmiControl (
> +  UINT32   NmiRegister
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PMC_IPC_COMMAND_BUFFER    Wbuf;
> +
> +  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +  //
> +  // WBUF0 = 2 for NMI delivery control and status register (entire register
> PCR[ITSS] 0x3330)
> +  //
> +  Wbuf.Buf0 = V_PMC_PWRM_IPC_CMD_WBUF0_PROXY_NMI;
> +  Wbuf.Buf1 = NmiRegister;
> +  Status = PmcSendCommand (
> +             V_PMC_PWRM_IPC_CMD_COMMAND_PROXY,
> +             V_PMC_PWRM_IPC_CMD_CMD_ID_PROXY_WRITE,
> +             8,
> +             &Wbuf,
> +             NULL
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  This function enables GBE ModPHY SPD gating.
> +**/
> +VOID
> +PmcGbeModPhyPowerGating (
> +  VOID
> +  )
> +{
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // Set B_PCH_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE ModPHY
> SPD RT Request
> +    //
> +    MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_GBE);
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibClient.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibClient.c
> new file mode 100644
> index 0000000000..2411a2be23
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibClient.c
> @@ -0,0 +1,73 @@
> +/** @file
> +  PCH PMC Private Library implementation for Cannon Lake PCH.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
> +#include <Library/SataLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Register/PchRegsPmc.h>
> +
> +#include "PmcPrivateLibInternal.h"
> +
> +/**
> +  This function disables (non-static power gating) SATA and enables ModPHY
> SPD gating (PCH-LP only).
> +
> +  @param[in]  SataCtrlIndex     SATA controller index
> +**/
> +VOID
> +PmcDisableSata (
> +  IN UINT32     SataCtrlIndex
> +  )
> +{
> +  UINT32 PchPwrmBase;
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  //
> +  // Set PWRMBASE + NST_PG_FDIS_1 [22] = 1b to disable SATA Controller in
> PMC
> +  //
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1,
> B_PMC_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC);
> +
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // MPHY SUS PG supported on PCH-LP only:
> +    //
> +    // Set MSPDRTREQ:
> +    // PWRMBASE + R_PWRM_MODPHY_PM_CFG5[12] = 1 to enable ASL code
> trigger request for ModPHY SPD gating.
> +    //
> +    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_SATA);
> +  }
> +}
> +
> +/**
> +  This function checks if SATA device is supported (not disabled by fuse)
> +
> +  @param[in] SataCtrlIndex SATA controller index
> +
> +  @retval SATA support state
> +**/
> +BOOLEAN
> +PmcIsSataSupported (
> +  UINT32  SataCtrlIndex
> +  )
> +{
> +  ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
> +
> +  //
> +  // 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_SATA_FUSE_SS_DIS) == 0);
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibCnl.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibCnl.c
> new file mode 100644
> index 0000000000..847be42937
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibCnl.c
> @@ -0,0 +1,360 @@
> +/** @file
> +  PCH PMC Private Library implementation for Cannon Lake PCH.
> +  All function in this library is available for PEI, DXE, and SMM,
> +  But do not support UEFI RUNTIME environment call.
> +
> +  Copyright (c) 2019 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 <Private/Library/PmcPrivateLib.h>
> +#include <Library/SataLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Register/PchRegsPmc.h>
> +
> +#include "PmcPrivateLibInternal.h"
> +
> +/**
> +  This function disables Trace Hub by enabling power gating
> +**/
> +VOID
> +PmcDisableTraceHub (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PMC_IPC_COMMAND_BUFFER    Wbuf;
> +
> +  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +
> +  Wbuf.Buf0 = BIT0;
> +  Status = PmcSendCommand
> (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  This function enables Trace Hub by disabling power gating
> +**/
> +VOID
> +PmcEnableTraceHub (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  PMC_IPC_COMMAND_BUFFER    Wbuf;
> +
> +  ZeroMem (&Wbuf, sizeof (PMC_IPC_COMMAND_BUFFER));
> +
> +  Wbuf.Buf0 = BIT1;
> +  Status = PmcSendCommand
> (V_PMC_PWRM_IPC_CMD_COMMAND_NPK_STATE, 0, 4, &Wbuf, NULL);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +/**
> +  This function is part of PMC init and configures which clock wake signals
> should
> +  set the SLOW_RING, SA, FAST_RING_CF and SLOW_RING_CF indication sent
> up to the CPU/PCH
> +**/
> +VOID
> +PmcInitClockWakeEnable (
> +  VOID
> +  )
> +{
> +  UINT32                    PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +  if (IsPchLp () && (PchStepping () < PCH_B0)) {
> +    ///
> +    /// PWRMBASE + 0x1880 = 0x0
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING,
> 0x0);
> +  } else {
> +    ///
> +    /// PWRMBASE + 0x1880 = 0x2F8FBB01
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING,
> 0x2F8FBB01);
> +  }
> +
> +  if (IsPchLp ()) {
> +    if (PchStepping () < PCH_B0) {
> +      ///
> +      /// PWRMBASE + 0x1884 = 0x0
> +      ///
> +      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2,
> 0x0);
> +    } else {
> +      ///
> +      /// PWRMBASE + 0x1884
> +      ///  PCH-LP: 0x0280C7E1
> +      ///
> +      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2,
> 0x0280C7E1);
> +    }
> +  } else {
> +    ///
> +    /// PWRMBASE + 0x1884
> +    ///  PCH-H:  0x0280D7E1
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING2,
> 0x0280D7E1);
> +  }
> +
> +  if (IsPchLp () && (PchStepping () < PCH_B0)) {
> +    ///
> +    /// PWRMBASE + 0x1888 = 0x0
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x0);
> +    ///
> +    /// PWRMBASE + 0x188C = 0x0
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2, 0x0);
> +  } else {
> +    ///
> +    /// PWRMBASE + 0x1888 = 0x2F8FAB01
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA, 0x2F8FAB01);
> +
> +    ///
> +    /// PWRMBASE + 0x188C
> +    ///  PCH-LP: 0x0280C7E1
> +    ///  PCH-H:  0x0280D7E1
> +    ///
> +    if (IsPchLp ()) {
> +      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2,
> 0x0280C7E1);
> +    } else {
> +      MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SA2,
> 0x0280D7E1);
> +    }
> +  }
> +
> +  if (IsPchLp () && (PchStepping () < PCH_B0)) {
> +    ///
> +    /// PWRMBASE + 0x1898 = 0x0
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF,
> 0x0);
> +  } else {
> +    ///
> +    /// PWRMBASE + 0x1898 = 0x00018000
> +    ///
> +    MmioWrite32 (PchPwrmBase + R_PMC_PWRM_EN_CW_SLOW_RING_CF,
> 0x00018000);
> +  }
> +}
> +
> +/**
> +  This function configures PWRMBASE + 0x1E00 register
> +**/
> +VOID
> +PmcConfigureRegPwrm1E00 (
> +  VOID
> +  )
> +{
> +  ///
> +  /// PWRMBASE + 0x1E00[31,30] = 1,1
> +  /// PWRMBASE + 0x1E00[29] = 0
> +  /// PWRMBASE + 0x1E00[10:6] = 0
> +  /// PWRMBASE + 0x1E00[3:0] = 2
> +  ///
> +  MmioAndThenOr32 (
> +    PmcGetPwrmBase () + R_PMC_PWRM_1E00,
> +    (UINT32) ~(BIT29 | (0x1F << 6) | 0xF),
> +    BIT31 | BIT30 | 2
> +    );
> +}
> +
> +/**
> +  This function configures Misc PM_SYNC events settings
> +**/
> +VOID
> +PmcConfigurePmSyncEventsSettings (
> +  VOID
> +  )
> +{
> +  ///
> +  /// PWRMBASE + 0x18C0 = 0x00000A20
> +  ///
> +  MmioWrite32 (PmcGetPwrmBase () + R_PMC_PWRM_EN_MISC_EVENT,
> 0x00000A20);
> +}
> +
> +/**
> +  This function enables all SerailIo devices.
> +  Static power gating disabling takes place after Global Reset, G3 or DeepSx
> transition.
> +**/
> +VOID
> +PmcEnableSerialIo (
> +  VOID
> +  )
> +{
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_2
> +  //
> +  MmioAnd32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2,
> (UINT32)~B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
> +}
> +
> +/**
> +  This function disables (static power gating) all SerailIo devices.
> +  For SerialIo controllers they can be power gated only if all of them are to be
> disabled.
> +  They cannot be statically power gated separately.
> +  For static power gating to take place Global Reset, G3 or DeepSx transition
> must happen.
> +**/
> +VOID
> +PmcStaticDisableSerialIo (
> +  VOID
> +  )
> +{
> +  //
> +  // Set PWRMBASE + ST_PG_FDIS_PMC_2
> +  //
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_ST_PG_FDIS_PMC_2,
> B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
> +}
> +
> +/**
> +  This function checks if all SerialIo devices are statically disabled (static
> power gating)
> +
> +  @retval SerialIo disable state
> +**/
> +BOOLEAN
> +PmcIsSerialIoStaticallyDisabled (
> +  VOID
> +  )
> +{
> +  //
> +  // Check if all SerialIo controllers are statically disabled in PMC
> +  //
> +  return ((MmioRead32 (PmcGetPwrmBase () +
> R_PMC_PWRM_ST_PG_FDIS_PMC_2) &
> B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO) ==
> B_PMC_PWRM_ST_PG_FDIS_PMC_2_SERIALIO);
> +}
> +
> +/**
> +  This function checks if SerialIo device is supported (not disabled by fuse)
> +
> +  @retval SerialIo support state
> +**/
> +BOOLEAN
> +PmcIsSerialIoSupported (
> +  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_SERIALIO_FUSE_SS_DIS) == 0);
> +}
> +
> +/**
> +  This function disables (non-static power gating) SCS eMMC controller and
> enables ModPHY SPD gating (PCH-LP only).
> +**/
> +VOID
> +PmcDisableScsEmmc (
> +  VOID
> +  )
> +{
> +  ASSERT (IsPchLp ());
> +
> +  //
> +  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
> +  //
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1,
> B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_EMMC_FDIS_PMC);
> +}
> +
> +/**
> +  This function disables (non-static power gating) SCS SD Card controller and
> enables ModPHY SPD gating (PCH-LP only).
> +**/
> +VOID
> +PmcDisableScsSdCard (
> +  VOID
> +  )
> +{
> +  UINT32        ScsDevicePgMask;
> +
> +  if (IsPchLp ()) {
> +    ScsDevicePgMask =
> B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC;
> +  } else {
> +    ScsDevicePgMask =
> B_PCH_H_PMC_PWRM_NST_PG_FDIS_1_SDCARD_FDIS_PMC;
> +  }
> +
> +  //
> +  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
> +  //
> +  MmioOr32 (PmcGetPwrmBase () + R_PMC_PWRM_NST_PG_FDIS_1,
> ScsDevicePgMask);
> +}
> +
> +/**
> +  This function disables (non-static power gating) SCS UFS controller and
> enables ModPHY SPD gating (PCH-LP only).
> +
> +  @param[in] UfsNum     SCS UFS Device
> +**/
> +VOID
> +PmcDisableScsUfs (
> +  IN UINT32   UfsNum
> +  )
> +{
> +  UINT32        PchPwrmBase;
> +
> +  ASSERT ((UfsNum == 0) && IsPchLp ());
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  //
> +  // Set PWRMBASE + NST_PG_FDIS_1 to disable SCS Controller in PMC
> +  //
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_NST_PG_FDIS_1,
> B_PCH_LP_PMC_PWRM_NST_PG_FDIS_1_UFS_FDIS_PMC);
> +
> +  if (PmcIsModPhySusPgSupported ()) {
> +    //
> +    // Set MSPDRTREQ:
> +    // PchPwrmBase + R_PWRM_MODPHY_PM_CFG5[16] = 1 to enable ASL
> code trigger request for ModPHY SPD gating.
> +    //
> +    MmioOr32 (PchPwrmBase + R_PMC_PWRM_MODPHY_PM_CFG5,
> B_PMC_PWRM_MODPHY_PM_CFG5_MSPDRTREQ_UFS2);
> +  }
> +}
> +
> +/**
> +  This function checks if SCS eMMC device is supported (not disabled by fuse)
> +
> +  @retval SCS device support state
> +**/
> +BOOLEAN
> +PmcIsScsEmmcSupported (
> +  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_EMMC_FUSE_SS_DIS) == 0);
> +}
> +
> +/**
> +  This function checks if SCS SD Card device is supported (not disabled by fuse)
> +
> +  @retval SCS device support state
> +**/
> +BOOLEAN
> +PmcIsScsSdCardSupported (
> +  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_SDX_FUSE_SS_DIS) == 0);
> +}
> +
> +/**
> +  This function checks if SCS UFS device is supported (not disabled by fuse)
> +
> +  @param[in] UfsNum     SCS UFS Device
> +
> +  @retval SCS device support state
> +**/
> +BOOLEAN
> +PmcIsScsUfsSupported (
> +  IN UINT32   UfsNum
> +  )
> +{
> +  //
> +  // 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_UFSX2_FUSE_SS_DIS) == 0);
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibWithS3.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibWithS3.c
> new file mode 100644
> index 0000000000..bbe944da5c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPriv
> ateLib/PmcPrivateLibWithS3.c
> @@ -0,0 +1,194 @@
> +/** @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) 2019 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 <Private/Library/PmcPrivateLib.h>
> +
> +/**
> +  This function locks down PMC (DebugModeLock)
> +**/
> +VOID
> +PmcLockWithS3BootScript (
> +  VOID
> +  )
> +{
> +
> +  UINT32 PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  //
> +  // Set PWRM_CFG[27] prior to OS.
> +  //
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_CFG,
> B_PMC_PWRM_CFG_DBG_MODE_LOCK);
> +
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint32,
> +    (PchPwrmBase + R_PMC_PWRM_CFG),
> +    1,
> +    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_CFG)
> +    );
> +
> +}
> +
> +/**
> +  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 SLP_SX Stretching Policy and adds
> +  lock setting to S3 Boot Script
> +**/
> +VOID
> +PmcLockSlpSxStretchingPolicyWithS3BootScript (
> +  VOID
> +  )
> +{
> +  UINT32  PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  MmioOr8 (
> +    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2),
> +    (UINT8) ((B_PMC_PWRM_GEN_PMCON_B_SLPSX_STR_POL_LOCK) >> 16)
> +    );
> +
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint8,
> +    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2),
> +    1,
> +    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B + 2)
> +    );
> +}
> +
> +/**
> +  This function sets SMI Lock with S3 Boot Script programming
> +**/
> +VOID
> +PmcLockSmiWithS3BootScript (
> +  VOID
> +  )
> +{
> +  UINT32  PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  MmioOr8 ((PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B),
> B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK);
> +
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint8,
> +    (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B),
> +    1,
> +    (VOID *) ((UINTN) PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B)
> +    );
> +}
> +
> +/**
> +  This function locks static power gating configuration with S3 Boot Script
> programming
> +**/
> +VOID
> +PmcLockFunctionDisableConfigWithS3BootScript (
> +  VOID
> +  )
> +{
> +  UINT32  PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  MmioOr32 (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1, (UINT32)
> (B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK));
> +
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint8,
> +    (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1),
> +    1,
> +    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_ST_PG_FDIS_PMC_1)
> +    );
> +}
> +
> +/**
> +  This function locks PMC Set Strap Message interface with S3 Boot Script
> programming
> +**/
> +VOID
> +PmcLockSetStrapMsgInterfaceWithS3BootScript (
> +  VOID
> +  )
> +{
> +  UINT32  PchPwrmBase;
> +
> +  PchPwrmBase = PmcGetPwrmBase ();
> +
> +  MmioOr32 ((UINTN) (PchPwrmBase + R_PMC_PWRM_SSML),
> B_PMC_PWRM_SSML_SSL);
> +
> +  S3BootScriptSaveMemWrite (
> +    S3BootScriptWidthUint8,
> +    (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML),
> +    1,
> +    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_SSML)
> +    );
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/
> PeiGpioHelpersLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/
> PeiGpioHelpersLib.c
> new file mode 100644
> index 0000000000..9c722bce07
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/
> PeiGpioHelpersLib.c
> @@ -0,0 +1,356 @@
> +/** @file
> +  This file contains routines for PEI GPIO Helpers Lib
> +
> +  Copyright (c) 2019 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 <Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h>
> +#include <Private/Library/GpioHelpersLib.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;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffer
> Lib/GpioNameBufferPei.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffer
> Lib/GpioNameBufferPei.c
> new file mode 100644
> index 0000000000..1b05378799
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBuffer
> Lib/GpioNameBufferPei.c
> @@ -0,0 +1,68 @@
> +/** @file
> +  This file contains GpioMemLib implementation for PEI phase
> +
> +  Copyright (c) 2019 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 <Private/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 ();
> +  }
> +}
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:14 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add
> modules
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> * PchInitDxeCnl - Generic DXE PCH initialization.
> * PchInitDxeFspCnl - Generic DXE PCH FSP initialization.
> * PchInitSmm - Generic SMM PCH initialization.
> * SmmControl - Produces an instance of EFI_SMM_CONTROL2_PROTOCOL.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
> |  99 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
> |  77 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
> | 101 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmContr
> ol.inf     |  54 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
> |  45 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h                    |
> 223 ++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
> | 187 +++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmContr
> olDriver.h | 132 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c                    |
> 451 ++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
> |  33 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
> | 323 ++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c                    |
> 554 ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
> | 382 ++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c                 |
> 85 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c                    |
> 89 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c                |
> 57 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
> | 156 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
> | 156 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
> | 179 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
> | 298 +++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
> | 436 +++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
> |  69 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmContr
> olDriver.c | 399 ++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c                         |
> 310 +++++++++++
>  24 files changed, 4895 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
> new file mode 100644
> index 0000000000..5e0cf06cb6
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
> @@ -0,0 +1,99 @@
> +## @file
> +# Component description file for Pch Initialization driver
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PchInitDxe
> +FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE823
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = PchInitEntryPointDxe
> +
> +
> +[LibraryClasses]
> +S3BootScriptLib
> +PchCycleDecodingLib
> +PchPcieRpLib
> +PchPcrLib
> +PchInfoLib
> +PchPciExpressHelpersLib
> +UefiBootServicesTableLib
> +DebugLib
> +IoLib
> +TimerLib
> +HobLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +UefiLib
> +DxeServicesTableLib
> +UefiDriverEntryPoint
> +UefiRuntimeServicesTableLib
> +AslUpdateLib
> +CpuPlatformLib
> +GpioLib
> +PchSerialIoLib
> +PchHdaLib
> +PchInitCommonLib
> +ConfigBlockLib
> +PmcLib
> +PmcPrivateLib
> +PmcPrivateLibWithS3
> +SataLib
> +PchDmiWithS3Lib
> +PchGbeLib
> +SiScheduleResetLib
> +BiosLockLib
> +DxeSaPolicyLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
> +
> +
> +[Sources]
> +PchInitDxe.c
> +PchInit.h
> +PchInit.c
> +PchSata.c
> +PchSerialIo.c
> +PchSerialIoDxe.c
> +PchHdaAcpi.c
> +PchCnviAcpi.c
> +PchAcpi.c
> +
> +[Protocols]
> +gPchNvsAreaProtocolGuid ## PRODUCES
> +gPchEmmcTuningProtocolGuid ## PRODUCES
> +gEfiPciIoProtocolGuid ## CONSUMES
> +gEfiAcpiTableProtocolGuid ## CONSUMES
> +gEfiBlockIoProtocolGuid ## CONSUMES
> +gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
> +gPchPcieIoTrapProtocolGuid ## CONSUMES
> +gPchPolicyProtocolGuid ## CONSUMES
> +
> +
> +[Guids]
> +gEfiEndOfDxeEventGroupGuid
> +gEfiAcpiTableGuid
> +gSiConfigHobGuid                 ## CONSUMES
> +gPchConfigHobGuid                ## CONSUMES
> +gPchRstHobGuid                   ## CONSUMES
> +gHdAudioDxeConfigGuid            ## CONSUMES
> +gGpioDxeConfigGuid               ## 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/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
> new file mode 100644
> index 0000000000..528cfd0296
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
> @@ -0,0 +1,77 @@
> +## @file
> +#  Component description file for Pch Initialization driver for FSP package
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION          = 0x00010005
> +BASE_NAME            = PchInitDxe
> +FILE_GUID            = 5AA5031E-4CB6-43D4-B219-FE50FF5D116C
> +MODULE_TYPE          = PEIM
> +VERSION_STRING       = 1.0
> +ENTRY_POINT          = PchInitEntryPointFsp
> +
> +
> +[LibraryClasses]
> +PeimEntryPoint
> +PchCycleDecodingLib
> +PchPcieRpLib
> +PchPcrLib
> +PchInfoLib
> +PchPciExpressHelpersLib
> +DebugLib
> +IoLib
> +TimerLib
> +HobLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +CpuPlatformLib
> +GpioLib
> +PchSerialIoLib
> +PchInitCommonLib
> +S3BootScriptLib  # NULL library
> +ConfigBlockLib
> +PmcLib
> +PmcPrivateLib
> +PmcPrivateLibWithS3
> +UsbInitLib
> +PchDmiWithS3Lib
> +PchGbeLib
> +SiScheduleResetLib
> +BiosLockLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +
> +[Sources]
> +PchInitFsp.c
> +PchInit.h
> +PchInit.c
> +PchSata.c
> +PchSerialIo.c
> +
> +
> +[Protocols]
> +gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
> +
> +
> +[Guids]
> +gEfiEventReadyToBootGuid
> +gSiConfigHobGuid                 ## CONSUMES
> +gPchConfigHobGuid                ## CONSUMES
> +
> +
> +[Depex]
> +  gEfiPeiMemoryDiscoveredPpiGuid
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
> new file mode 100644
> index 0000000000..308da65385
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
> @@ -0,0 +1,101 @@
> +## @file
> +# Component description file for PchInitSmm driver
> +#
> +# Copyright (c) 2019 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
> +PchPciExpressHelpersLib
> +SmmServicesTableLib
> +PciSegmentLib
> +HobLib
> +GpioLib
> +GpioPrivateLib
> +ReportStatusCodeLib
> +DevicePathLib
> +PmcLib
> +PchPcieRpLib
> +PchInfoLib
> +TimerLib
> +ConfigBlockLib
> +PmcPrivateLib
> +SataLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin
> +gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax
> +gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
> +gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemSize
> +
> +
> +[Sources]
> +PchInitSmm.c
> +PchPcieSmm.c
> +PchLanSxSmm.c
> +PchInitSmm.h
> +PchBiosWriteProtect.c
> +PchSpiAsync.c
> +
> +
> +[Protocols]
> +gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES
> +gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
> +gPchSmmIoTrapControlGuid ## CONSUMES
> +gEfiSmmCpuProtocolGuid ## CONSUMES
> +gPchNvsAreaProtocolGuid ## CONSUMES
> +gPchPcieSmiDispatchProtocolGuid ## CONSUMES
> +gPchTcoSmiDispatchProtocolGuid ## CONSUMES
> +gPchSmiDispatchProtocolGuid ## CONSUMES
> +gPchEspiSmiDispatchProtocolGuid ## CONSUMES
> +gPchPcieIoTrapProtocolGuid ## PRODUCES
> +
> +
> +[Guids]
> +gSiConfigHobGuid             ## CONSUMES
> +gPchConfigHobGuid            ## CONSUMES
> +gPchDeviceTableHobGuid
> +
> +
> +[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 # This is for SmmServicesTableLib
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trol.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trol.inf
> new file mode 100644
> index 0000000000..ff712f8635
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trol.inf
> @@ -0,0 +1,54 @@
> +## @file
> +# Component description file for SmmControl module
> +#
> +# Copyright (c) 2019 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
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +SmmControlDriver.h
> +SmmControlDriver.c
> +
> +
> +[Protocols]
> +gEfiSmmControl2ProtocolGuid ## PRODUCES
> +
> +
> +[Guids]
> +gEfiEventVirtualAddressChangeGuid
> +
> +
> +[Depex]
> +TRUE
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
> new file mode 100644
> index 0000000000..77bd3ad72b
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
> @@ -0,0 +1,45 @@
> +## @file
> +# Component description file for the SPI SMM driver.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PchSpiSmm
> +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
> +PchSpiCommonLib
> +SmmPchPrivateLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +PchSpi.c
> +
> +
> +[Protocols]
> +gPchSmmSpiProtocolGuid ## PRODUCES
> +gEfiSmmCpuProtocolGuid ## CONSUMES
> +
> +[Depex]
> +gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
> +gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
> new file mode 100644
> index 0000000000..b84c574a2e
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
> @@ -0,0 +1,223 @@
> +/** @file
> +  Header file for PCH Initialization Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_INIT_DXE_H_
> +#define _PCH_INIT_DXE_H_
> +
> +#include <Protocol/PchEmmcTuning.h>
> +#include <SiConfigHob.h>
> +#include <Private/PchConfigHob.h>
> +#include <Private/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
> +//
> +/**
> +  Initialize the PCH device according to the PCH Policy HOB
> +  and install PCH info instance.
> +
> +**/
> +VOID
> +InitializePchDevice (
> +  VOID
> +  );
> +
> +/**
> +  Common PchInit Module Entry Point
> +**/
> +VOID
> +PchInitEntryPointCommon (
> +  VOID
> +  );
> +
> +/**
> +  Common PCH initialization on PCI enumeration complete.
> +**/
> +VOID
> +PchOnPciEnumCompleteCommon (
> +  VOID
> +  );
> +
> +/**
> +  Configures Serial IO Controllers
> +
> +**/
> +EFI_STATUS
> +ConfigureSerialIoAtBoot (
> +  VOID
> +  );
> +
> +/**
> +  Creates device handles for SerialIo devices in ACPI mode
> +
> +**/
> +VOID
> +CreateSerialIoHandles (
> +  VOID
> +  );
> +
> +/**
> +  Mark memory used by SerialIo devices in ACPI mode as allocated
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +**/
> +EFI_STATUS
> +AllocateSerialIoMemory (
> +  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
> +  );
> +
> +/**
> +  Update ASL definitions for SerialIo devices.
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +**/
> +EFI_STATUS
> +UpdateSerialIoAcpiData (
> +  VOID
> +  );
> +
> +/**
> +  Initialize PCIE SRC clocks in ICC subsystem
> +
> +  @param[in] GbePortNumber        Number of PCIE rootport assigned to
> GbE adapter
> +
> +**/
> +VOID
> +ConfigurePchPcieClocks (
> +  IN UINTN                        GbePortNumber
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Configure eMMC in HS400 Mode
> +
> +  @param[in] This                         A pointer to
> PCH_EMMC_TUNING_PROTOCOL structure
> +  @param[in] Revision                     Revision parameter used to verify the
> layout of EMMC_INFO and TUNINGDATA.
> +  @param[in] EmmcInfo                     A pointer to EMMC_INFO structure
> +  @param[out] EmmcTuningData              A pointer to
> EMMC_TUNING_DATA structure
> +
> +  @retval EFI_SUCCESS                     The function completed successfully
> +  @retval EFI_NOT_FOUND                   The item was not found
> +  @retval EFI_OUT_OF_RESOURCES            The request could not be
> completed due to a lack of resources.
> +  @retval EFI_INVALID_PARAMETER           A parameter was incorrect.
> +  @retval EFI_DEVICE_ERROR                Hardware Error
> +  @retval EFI_NO_MEDIA                    No media
> +  @retval EFI_MEDIA_CHANGED               Media Change
> +  @retval EFI_BAD_BUFFER_SIZE             Buffer size is bad
> +  @retval EFI_CRC_ERROR                   Command or Data CRC Error
> +**/
> +EFI_STATUS
> +EFIAPI
> +ConfigureEmmcHs400Mode (
> +  IN  PCH_EMMC_TUNING_PROTOCOL          *This,
> +  IN  UINT8                             Revision,
> +  IN  EMMC_INFO                         *EmmcInfo,
> +  OUT EMMC_TUNING_DATA                  *EmmcTuningData
> +  );
> +
> +/**
> +  Get eMMC PCI cfg space address
> +
> +  @return UINT64  PCI base address
> +**/
> +UINT64
> +ScsGetEmmcBaseAddress (
> +  VOID
> +  );
> +
> +/**
> +  Perform the remaining configuration on PCH SATA to perform device
> detection,
> +  then set the SATA SPD and PxE corresponding, and set the Register Lock on
> PCH SATA
> +
> +  @retval None
> +**/
> +VOID
> +ConfigurePchSataOnEndOfDxe (
> +  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
> +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
> +  );
> +
> +/**
> +  Initialize PCH Nvs Area opeartion region.
> +
> +**/
> +VOID
> +PatchPchNvsAreaAddress (
> +  VOID
> +  );
> +
> +#endif // _PCH_INIT_DXE_H_
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
> new file mode 100644
> index 0000000000..693c5d3f50
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
> @@ -0,0 +1,187 @@
> +/** @file
> +  Header file for PCH Init SMM Handler
> +
> +  Copyright (c) 2019 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/PchEspiLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Private/Library/PchPciExpressHelpersLib.h>
> +#include <Protocol/PchPcieSmiDispatch.h>
> +#include <Protocol/PchTcoSmiDispatch.h>
> +#include <Protocol/PchSmiDispatch.h>
> +#include <Protocol/PchEspiSmiDispatch.h>
> +#include <Protocol/PchSmmIoTrapControl.h>
> +#include <Private/Protocol/PchNvsArea.h>
> +#include <Private/Protocol/PcieIoTrap.h>
> +#include <SiConfigHob.h>
> +#include <Private/PchConfigHob.h>
> +#include <Private/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
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trolDriver.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trolDriver.h
> new file mode 100644
> index 0000000000..08e64fa5a7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trolDriver.h
> @@ -0,0 +1,132 @@
> +/** @file
> +  Header file for SMM Control Driver.
> +
> +  Copyright (c) 2019 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
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
> new file mode 100644
> index 0000000000..bcbdb12dc3
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
> @@ -0,0 +1,451 @@
> +/** @file
> +  This is the driver that initializes the Intel PCH.
> +
> +  Copyright (c) 2019 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 <IndustryStandard/Pci.h>
> +
> +#include "PchInit.h"
> +#include <Protocol/PchPolicy.h>
> +#include <ConfigBlock/GpioDevConfig.h>
> +#include <ConfigBlock/ScsConfig.h>
> +#include <Library/AslUpdateLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/GpioLib.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchGbeLib.h>
> +#include <Private/PchRstHob.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/SataLib.h>
> +#include <Register/PchRegsSata.h>
> +#include <TraceHubCommonConfig.h>
> +#include <PchReservedResources.h>
> +#include <Register/PchRegsTraceHub.h>
> +
> +//
> +// Module variables
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA_PROTOCOL
> mPchNvsAreaProtocol;
> +
> +/**
> +  Retrieve interrupt information about a PCH device from policy
> +
> +  @param[in] Device                     PCI device number
> +
> +  @retval PCH_DEVICE_INTERRUPT_CONFIG   structure with device's
> interrupt information
> +**/
> +PCH_DEVICE_INTERRUPT_CONFIG
> +GetInterruptPolicy (
> +  IN PCH_SERIAL_IO_CONTROLLER  Device
> +  )
> +{
> +  PCH_DEVICE_INTERRUPT_CONFIG EmptyRecord;
> +  UINT8                       DevNum;
> +  UINT8                       FuncNum;
> +  UINT8                       Index;
> +
> +  ZeroMem (&EmptyRecord, sizeof (PCH_DEVICE_INTERRUPT_CONFIG));
> +  DevNum  = GetSerialIoDeviceNumber (Device);
> +  FuncNum = GetSerialIoFunctionNumber (Device);
> +
> +  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.
> +
> +  @retval EFI_SUCCESS                   The function completed successfully
> +**/
> +EFI_STATUS
> +UpdateSerialIoAcpiData (
> +  VOID
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER Index;
> +
> +  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
> +    mPchNvsAreaProtocol.Area->SMD[Index] =
> mPchConfigHob->SerialIo.DevMode[Index];
> +    mPchNvsAreaProtocol.Area->SIR[Index] = (GetInterruptPolicy (Index)).Irq;
> +    mPchNvsAreaProtocol.Area->SB0[Index] = (UINT32) FindSerialIoBar (Index,
> 0);
> +    mPchNvsAreaProtocol.Area->SB1[Index] = (UINT32) FindSerialIoBar (Index,
> 1);
> +  }
> +  if (IsPchH ()) {
> +    mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C4] =
> PchSerialIoDisabled;
> +    mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C5] =
> PchSerialIoDisabled;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Update NVS Area after RST PCIe Storage Remapping and before Boot
> +**/
> +VOID
> +PchUpdateNvsAreaAfterRemapping (
> +  VOID
> +  )
> +{
> +  UINTN                 Index;
> +  VOID                  *Hob;
> +  PCH_RST_HOB           *RstHob;
> +
> +  Hob = GetFirstGuidHob (&gPchRstHobGuid);
> +  if (Hob == NULL) {
> +    DEBUG (( DEBUG_INFO , "PchUpdateNvsAreaAfterRemapping: cannot
> fetch RstHob" ));
> +    return;
> +  }
> +
> +  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;
> +  }
> +}
> +
> +/**
> +  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
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  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 ();
> +
> +  //
> +  // Update Pch Nvs Area
> +  //
> +  Status = PchUpdateNvsArea ();
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  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
> +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 ();
> +
> +  //
> +  // 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 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;
> +  PCH_GPIO_DXE_CONFIG   *GpioDxeConfig;
> +
> +  ///
> +  /// 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++) {
> +    Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFun);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    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].LtrMaxSnoopLatency;
> +    mPchNvsAreaProtocol.Area->PcieLtrMaxNoSnoopLatency[Index] =
> mPchConfigHob->PcieRp.RootPort[Index].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 PMC ACPIBASE and PWRMBASE
> +  //
> +  mPchNvsAreaProtocol.Area->PMBS = PmcGetAcpiBase ();
> +
> +  mPchNvsAreaProtocol.Area->PWRM = PmcGetPwrmBase ();
> +
> +  //
> +  // 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
> +  //
> +  // Update eMMC HS400 mode enablement
> +  //
> +  mPchNvsAreaProtocol.Area->EMH4 = (UINT8)
> mPchConfigHob->Scs.ScsEmmcHs400Enabled;
> +  mPchNvsAreaProtocol.Area->EmmcEnabled = (UINT8)
> mPchConfigHob->Scs.ScsEmmcEnabled;
> +
> +  //
> +  // Update eMMC Driver Strength
> +  // Per eMMC 5.01 JEDEC Specification (JESD84-B50.1, Table 186)
> +  // Nominal Impedance - Driver Type Values:
> +  // 50 Ohm              0x0
> +  // 33 Ohm              0x1
> +  // 40 Ohm              0x4
> +  //
> +  switch (mPchConfigHob->Scs.ScsEmmcHs400DriverStrength) {
> +    case DriverStrength33Ohm:
> +      mPchNvsAreaProtocol.Area->EMDS = 0x1;
> +      break;
> +    case DriverStrength40Ohm:
> +      mPchNvsAreaProtocol.Area->EMDS = 0x4;
> +      break;
> +    case DriverStrength50Ohm:
> +    default:
> +      mPchNvsAreaProtocol.Area->EMDS = 0x0;
> +  }
> +
> +  mPchNvsAreaProtocol.Area->SdPowerEnableActiveHigh = (UINT8)
> mPchConfigHob->Scs.ScsSdPowerEnableActiveHigh;
> +  mPchNvsAreaProtocol.Area->SdCardEnabled           = (UINT8)
> mPchConfigHob->Scs.ScsSdCardEnabled;
> +
> +  //
> +  // SATA configuration.
> +  //
> +  if (PciSegmentRead16 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) +
> PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
> +    mPchNvsAreaProtocol.Area->SataPortPresence = 0;
> +  } else {
> +    mPchNvsAreaProtocol.Area->SataPortPresence = PciSegmentRead8
> (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + R_SATA_CFG_PCS + 2);
> +  }
> +
> +  //
> +  // CPU SKU
> +  //
> +  mPchNvsAreaProtocol.Area->CpuSku = GetCpuSku ();
> +
> +  mPchNvsAreaProtocol.Area->SlpS0VmRuntimeControl =
> (UINT8)mPchConfigHob->Pm.SlpS0VmRuntimeControl;
> +  mPchNvsAreaProtocol.Area->SlpS0Vm070VSupport    =
> (UINT8)mPchConfigHob->Pm.SlpS0Vm070VSupport;
> +  mPchNvsAreaProtocol.Area->SlpS0Vm075VSupport    =
> (UINT8)mPchConfigHob->Pm.SlpS0Vm075VSupport;
> +  mPchNvsAreaProtocol.Area->PsOnEnable            =
> (UINT8)mPchConfigHob->Pm.PsOnEnable;
> +
> +  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
> +    mPchNvsAreaProtocol.Area->LtrEnable[Index]  =
> (UINT8)mPchConfigHob->PcieRp.RootPort[Index].LtrEnable;
> +  }
> +
> +  mPchNvsAreaProtocol.Area->GBES = PchIsGbePresent ();
> +
> +  //
> +  // Update PCH Trace Hub Mode
> +  //
> +  mPchNvsAreaProtocol.Area->PchTraceHubMode     = (UINT8)
> mPchConfigHob->PchTraceHub.PchTraceHubMode;
> +  //
> +  // if SCRPD0[24] is set, force TH to be host debugger mode.
> +  //
> +  if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS) != 0xFFFFFFFF) {
> +    if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS +
> R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0) & BIT24) {
> +      mPchNvsAreaProtocol.Area->PchTraceHubMode =
> TraceHubModeHostDebugger;
> +    }
> +  }
> +
> +  //
> +  // Update TWMB, Temp memory base address
> +  //
> +  mPchNvsAreaProtocol.Area->TempRsvdMemBase = (UINT32) PcdGet32
> (PcdSiliconInitTempMemBaseAddr);
> +
> +  return Status;
> +}
> +
> +/**
> +  Initialize PCH Nvs Area opeartion region.
> +
> +**/
> +VOID
> +PatchPchNvsAreaAddress (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  UINT32                                Address;
> +  UINT16                                Length;
> +
> +  Status = InitializeAslUpdateLib ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Address = (UINT32) (UINTN) mPchNvsAreaProtocol.Area;
> +  Length  = (UINT16) sizeof (PCH_NVS_AREA);
> +  DEBUG ((DEBUG_INFO, "PatchPchNvsAreaAddress: PCH NVS Address %x
> Length %x\n", Address, Length));
> +  Status  = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','B'), &Address,
> sizeof (Address));
> +  ASSERT_EFI_ERROR (Status);
> +  Status  = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','L'), &Length,
> sizeof (Length));
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
> new file mode 100644
> index 0000000000..4e38db1027
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
> @@ -0,0 +1,33 @@
> +/** @file
> +  Initializes PCH CNVi device ACPI data.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include "PchInit.h"
> +#include <Library/DxeSaPolicyLib.h>
> +
> +/**
> +  Update ASL definitions for CNVi device.
> +
> +  @retval EFI_SUCCESS         The function completed successfully
> +**/
> +EFI_STATUS
> +UpdateCnviAcpiData (
> +  VOID
> +  )
> +{
> +
> +  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() Start\n"));
> +
> +  mPchNvsAreaProtocol.Area->CnviMode = (UINT8)
> mPchConfigHob->Cnvi.Mode;
> +
> +  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
> new file mode 100644
> index 0000000000..57f2e1dca0
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
> @@ -0,0 +1,323 @@
> +/** @file
> +  Initializes the PCH HD Audio ACPI Tables.
> +
> +  Copyright (c) 2019 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 "PchInit.h"
> +#include <Protocol/PchPolicy.h>
> +#include <ConfigBlock/HdAudioConfig.h>
> +#include <Private/PchConfigHob.h>
> +#include <Library/PchInfoLib.h>
> +#include <Private/Library/PchHdaLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsHda.h>
> +
> +PCH_HDA_NHLT_ENDPOINTS mPchHdaNhltEndpoints[HdaEndpointMax] =
> +{
> +  {HdaDmicX1,     B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT,
> 0, FALSE},
> +  {HdaDmicX2,     (B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT |
> B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT),        0, FALSE},
> +  {HdaDmicX4,     (B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT |
> B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT),        0, FALSE},
> +  {HdaBtRender,   (B_HDA_BT_NARROWBAND_FORMAT |
> B_HDA_BT_WIDEBAND_FORMAT | B_HDA_BT_A2DP_FORMAT), 0, FALSE},
> +  {HdaBtCapture,  (B_HDA_BT_NARROWBAND_FORMAT |
> B_HDA_BT_WIDEBAND_FORMAT),                        0, FALSE},
> +  {HdaI2sRender1,
> B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT,
> B_HDA_I2S_RENDER_DEVICE_INFO,      FALSE},
> +  {HdaI2sRender2,
> B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT,
> B_HDA_I2S_RENDER_DEVICE_INFO,      FALSE},
> +  {HdaI2sCapture,
> B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT,
> B_HDA_I2S_CAPTURE_DEVICE_INFO,    FALSE}
> +};
> +
> +#define DSP_FW_STOLEN_MEMORY_SIZE 0x400000 //4MB
> +/**
> +  Allocates 4MB of memory for DSP FW usage.
> +
> +  @retval EFI_PHYSICAL_ADDRESS  Allocated memory address
> +**/
> +EFI_PHYSICAL_ADDRESS
> +AllocateAudioDspStolenMemory (
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_PHYSICAL_ADDRESS DspStolenMemBaseAddress;
> +
> +  DspStolenMemBaseAddress = 0;
> +
> +  DEBUG ((DEBUG_INFO, "AllocateAudioDspStolenMemory()\n"));
> +
> +  //
> +  // Reserve memory to store Acpi Debug data.
> +  //
> +  DspStolenMemBaseAddress = 0xFFFFFFFF;
> +  Status = gBS->AllocatePages (
> +                  AllocateMaxAddress,
> +                  EfiReservedMemoryType,
> +                  EFI_SIZE_TO_PAGES (DSP_FW_STOLEN_MEMORY_SIZE),
> +                  &DspStolenMemBaseAddress
> +                  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  ZeroMem ((VOID *) (UINTN) DspStolenMemBaseAddress,
> DSP_FW_STOLEN_MEMORY_SIZE);
> +
> +  mPchNvsAreaProtocol.Area->DSPM = (UINT32)
> DspStolenMemBaseAddress;
> +  DEBUG ((DEBUG_INFO, "mPchNvsAreaProtocol.Area->DSPM = 0x%016x\n",
> mPchNvsAreaProtocol.Area->DSPM));
> +
> +  return DspStolenMemBaseAddress;
> +}
> +
> +/**
> +  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->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) {
> +      break;
> +    }
> +  }
> +
> +  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;
> +}
> +
> +/**
> +  Constructs and installs NHLT table.
> +
> +  @retval EFI_SUCCESS       ACPI Table installed successfully
> +  @retval EFI_UNSUPPORTED   ACPI Table protocol not found
> +**/
> +EFI_STATUS
> +PublishNhltAcpiTable (
> +  VOID
> +  )
> +{
> +  UINTN                                     AcpiTableKey;
> +  EFI_ACPI_TABLE_PROTOCOL                   *AcpiTable;
> +  NHLT_ACPI_TABLE                           *NhltTable;
> +  UINT32                                    TableLength;
> +  EFI_STATUS                                Status;
> +
> +  AcpiTable = NULL;
> +  NhltTable = NULL;
> +  AcpiTableKey = 0;
> +
> +  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n"));
> +
> +  //
> +  // Locate ACPI support protocol
> +  //
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +  if ( EFI_ERROR (Status) || AcpiTable == NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  NhltConstructor (mPchHdaNhltEndpoints, &NhltTable, &TableLength);
> +  NhltAcpiHeaderConstructor (NhltTable, TableLength);
> +
> +  Status = AcpiTable->InstallAcpiTable (AcpiTable, NhltTable,
> NhltTable->Header.Length, &AcpiTableKey);
> +
> +  DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n"));
> +  return Status;
> +}
> +
> +/**
> +  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 PCH_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->NHLA = NhltAcpiTableAddress;
> +  mPchNvsAreaProtocol.Area->NHLL = NhltAcpiTableLength;
> +  mPchNvsAreaProtocol.Area->ADFM =
> HdAudioDxeConfig->DspFeatureMask;
> +  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;
> +}
> +
> +/**
> +  Initialize and publish NHLT (Non-HDA Link Table), update NVS variables.
> +
> +  @param[in]                *HdAudioConfigHob
> +  @param[in]                *HdAudioDxeConfig
> +
> +  @retval EFI_SUCCESS    The function completed successfully
> +**/
> +EFI_STATUS
> +SetHdaAcpiTable (
> +  IN CONST HDAUDIO_HOB            *HdAudioConfigHob,
> +  IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
> +  )
> +{
> +  NHLT_ACPI_TABLE     *NhltTable;
> +  EFI_STATUS          Status;
> +  NhltTable = NULL;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (HdAudioDxeConfig->NhltDefaultFlow == TRUE) {
> +    switch (HdAudioDxeConfig->DspEndpointDmic) {
> +      case PchHdaDmic1chArray:
> +        mPchHdaNhltEndpoints[HdaDmicX1].Enable   = TRUE;
> +        break;
> +      case PchHdaDmic2chArray:
> +        mPchHdaNhltEndpoints[HdaDmicX2].Enable   = TRUE;
> +        break;
> +      case PchHdaDmic4chArray:
> +        mPchHdaNhltEndpoints[HdaDmicX4].Enable   = TRUE;
> +        break;
> +      case PchHdaDmicDisabled:
> +      default:
> +        mPchHdaNhltEndpoints[HdaDmicX2].Enable   = FALSE;
> +        mPchHdaNhltEndpoints[HdaDmicX4].Enable   = FALSE;
> +    }
> +
> +    if (HdAudioDxeConfig->DspEndpointBluetooth) {
> +      mPchHdaNhltEndpoints[HdaBtRender].Enable   = TRUE;
> +      mPchHdaNhltEndpoints[HdaBtCapture].Enable  = TRUE;
> +    }
> +
> +    if (HdAudioDxeConfig->DspEndpointI2s) {
> +      mPchHdaNhltEndpoints[HdaI2sRender1].Enable = TRUE;
> +      mPchHdaNhltEndpoints[HdaI2sRender2].Enable = TRUE;
> +      mPchHdaNhltEndpoints[HdaI2sCapture].Enable = TRUE;
> +    }
> +
> +    Status    = PublishNhltAcpiTable ();
> +  }
> +  NhltTable = LocateNhltAcpiTable ();
> +  if (NhltTable == NULL) {
> +    return EFI_LOAD_ERROR;
> +  }
> +
> +  UpdateHdaAcpiData ((UINT64) (UINTN) NhltTable, (UINT32)
> (NhltTable->Header.Length), HdAudioConfigHob, HdAudioDxeConfig);
> +
> +  if (IsPchLp () && (PchStepping () < PCH_B0)) {
> +    AllocateAudioDspStolenMemory ();
> +  }
> +
> +  DEBUG_CODE ( NhltAcpiTableDump (NhltTable); );
> +  return Status;
> +}
> +
> +/**
> +  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;
> +  PCH_HDAUDIO_DXE_CONFIG        *HdAudioDxeConfig;
> +
> +
> +  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 = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_HDA,
> +                 PCI_FUNCTION_NUMBER_PCH_HDA,
> +                 0
> +                 );
> +
> +  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;
> +  }
> +
> +  Status = SetHdaAcpiTable (HdAudioConfigHob, HdAudioDxeConfig);
> +
> +  DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", Status));
> +  return Status;
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
> new file mode 100644
> index 0000000000..55f1e086fb
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
> @@ -0,0 +1,554 @@
> +/** @file
> +  This is the Common driver that initializes the Intel PCH.
> +
> +  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Private/Library/PchDmiLib.h>
> +#include <Private/Library/SiScheduleResetLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/BiosLockLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsSpi.h>
> +#include <Register/PchRegsPsth.h>
> +#include <Register/PchRegsPmc.h>
> +
> +//
> +// Module variables
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB
> *mPchConfigHob;
> +GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA
> *mSiConfigHobData;
> +
> +//
> +// 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);
> +
> +  //
> +  // Get Silicon Config data HOB
> +  //
> +  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
> +  ASSERT (HobPtr.Guid != NULL);
> +  mSiConfigHobData = (SI_CONFIG_HOB_DATA *) 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   = PCI_SEGMENT_LIB_ADDRESS (
> +                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                      DEFAULT_PCI_BUS_NUMBER_PCH,
> +                      PCI_DEVICE_NUMBER_PCH_SPI,
> +                      PCI_FUNCTION_NUMBER_PCH_SPI,
> +                      0
> +                      );
> +
> +  //
> +  // Check for SPI controller presence before programming
> +  //
> +  if (PciSegmentRead32 (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);
> +
> +  //
> +  // 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)
> +    );
> +}
> +
> +/**
> +  Process all the lock downs
> +**/
> +VOID
> +ProcessAllLocks (
> +  VOID
> +  )
> +{
> +  UINT8         Data8;
> +  UINT16        Data16And;
> +  UINT16        Data16Or;
> +  UINT32        Data32And;
> +  UINT32        Data32Or;
> +  UINT64        PciLpcRegBase;
> +  UINT16        TcoBase;
> +  UINT64        PciSpiRegBase;
> +
> +  PciLpcRegBase   = PCI_SEGMENT_LIB_ADDRESS (
> +                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                      DEFAULT_PCI_BUS_NUMBER_PCH,
> +                      PCI_DEVICE_NUMBER_PCH_LPC,
> +                      PCI_FUNCTION_NUMBER_PCH_LPC,
> +                      0
> +                      );
> +  PciSpiRegBase   = PCI_SEGMENT_LIB_ADDRESS (
> +                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                      DEFAULT_PCI_BUS_NUMBER_PCH,
> +                      PCI_DEVICE_NUMBER_PCH_SPI,
> +                      PCI_FUNCTION_NUMBER_PCH_SPI,
> +                      0
> +                      );
> +
> +  PchTcoBaseGet (&TcoBase);
> +
> +  //
> +  // Lock function disable (ST and NST PG) register fields.
> +  //
> +  PmcLockFunctionDisableConfigWithS3BootScript ();
> +
> +  ///
> +  /// PCH BWG Additional PCH DMI and OP-DMI Programming Steps
> +  /// Lock DMI.
> +  ///
> +    PchDmiSetLockWithS3BootScript ();
> +
> +  //
> +  // Lock SPI register before boot.
> +  //
> +  LockSpiConfiguration ();
> +
> +  ///
> +  /// Additional Power Management Programming
> +  /// Step 3
> +  /// Lock configuration after stretch and ACPI base programming completed.
> +  ///
> +  PmcLockSlpSxStretchingPolicyWithS3BootScript ();
> +
> +  //
> +  // Set BiosLock.
> +  //
> +  if (mPchConfigHob->LockDown.BiosLock == TRUE) {
> +    BiosLockEnable ();
> +  }
> +
> +  ///
> +  /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
> +  /// 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]).
> +  /// 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 (mPchConfigHob->LockDown.BiosInterface == TRUE) {
> +    //
> +    // LPC
> +    //
> +    PciSegmentOr8 ((UINT64) (PciLpcRegBase + R_LPC_CFG_BC), (UINT32)
> B_LPC_CFG_BC_BILD);
> +    S3BootScriptSaveMemWrite (
> +      S3BootScriptWidthUint8,
> +      PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase +
> R_LPC_CFG_BC,
> +      1,
> +      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase
> + R_LPC_CFG_BC)
> +      );
> +
> +    //
> +    // Reads back for posted write to take effect
> +    //
> +    Data8 = PciSegmentRead8 ((UINTN) (PciLpcRegBase + R_LPC_CFG_BC));
> +    S3BootScriptSaveMemPoll  (
> +      S3BootScriptWidthUint8,
> +      PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase +
> R_LPC_CFG_BC,
> +      &Data8,  // BitMask
> +      &Data8,  // BitValue
> +      1,       // Duration
> +      1        // LoopTimes
> +      );
> +
> +    //
> +    // SPI
> +    //
> +    PciSegmentOr8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC), (UINT32)
> B_SPI_CFG_BC_BILD);
> +    S3BootScriptSaveMemWrite (
> +      S3BootScriptWidthUint8,
> +      PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
> +      1,
> +      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase
> + R_SPI_CFG_BC)
> +      );
> +
> +    //
> +    // Reads back for posted write to take effect
> +    //
> +    Data8 = PciSegmentRead8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC));
> +    S3BootScriptSaveMemPoll  (
> +      S3BootScriptWidthUint8,
> +      PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
> +      &Data8,     // BitMask
> +      &Data8,     // BitValue
> +      1,          // Duration
> +      1           // LoopTimes
> +      );
> +
> +    ///
> +    /// Set BIOS interface Lock-Down
> +    ///
> +    PchDmiSetBiosLockDownWithS3BootScript ();
> +  }
> +
> +  ///
> +  /// PCH BIOS Spec on using RTC RAM
> +  /// Regardless of BUC.TS being updated or not, BIOS must set RC.BILD bit
> PCR[RTC] + 3400h[31] before exit
> +  /// For Data integrity protection, set RTC Memory locks (Upper 128 Byte Lock
> and
> +  /// Lower 128 Byte Lock) at PCR[RTC] + 3400h[4] and PCR[RTC] + 3400h[3].
> +  /// Note once locked bytes 0x38 - 0x3F in each of the Upper and Lower Byte
> blocks, respectively,
> +  /// cannot be unlocked until next reset.
> +  ///
> +  Data32And = 0xFFFFFFFF;
> +  Data32Or = 0x0;
> +
> +  if (mPchConfigHob->LockDown.BiosInterface == TRUE) {
> +    Data32Or  = B_RTC_PCR_CONF_BILD;
> +  }
> +  if (mPchConfigHob->LockDown.RtcMemoryLock == TRUE) {
> +    Data32Or |= (B_RTC_PCR_CONF_UCMOS_LOCK |
> B_RTC_PCR_CONF_LCMOS_LOCK);
> +  }
> +  PchPcrAndThenOr32 (
> +    PID_RTC_HOST, R_RTC_PCR_CONF,
> +    Data32And,
> +    Data32Or
> +    );
> +  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
> +    S3BootScriptWidthUint32,
> +    PID_RTC_HOST, R_RTC_PCR_CONF,
> +    &Data32Or,
> +    &Data32And
> +    );
> +
> +  ///
> +  ///  Remove access to RTC PCRs
> +  ///
> +  Data32And = (UINT32)~(BIT0);
> +  Data32Or  = 0;
> +  PchPcrAndThenOr32 (
> +    PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
> +    Data32And,
> +    Data32Or
> +    );
> +  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
> +    S3BootScriptWidthUint32,
> +    PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
> +    &Data32Or,
> +    &Data32And
> +    );
> +  PchPcrAndThenOr32 (
> +    PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
> +    Data32And,
> +    Data32Or
> +    );
> +  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
> +    S3BootScriptWidthUint32,
> +    PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
> +    &Data32Or,
> +    &Data32And
> +    );
> +
> +  //
> +  // Lock Down TCO
> +  //
> +  Data16And = 0xFFFF;
> +  Data16Or  = B_TCO_IO_TCO1_CNT_LOCK;
> +  IoOr16 (TcoBase + R_TCO_IO_TCO1_CNT, Data16Or);
> +  S3BootScriptSaveIoReadWrite (
> +    S3BootScriptWidthUint16,
> +    (UINTN) (TcoBase + R_TCO_IO_TCO1_CNT),
> +    &Data16Or,  // Data to be ORed
> +    &Data16And  // Data to be ANDed
> +    );
> +
> +  ///
> +  /// PCH BIOS Spec Section 5.15.1 Additional Chipset Initialization
> +  /// Step 1
> +  /// Lock PMC Set Strap Message Interface
> +  ///
> +  PmcLockSetStrapMsgInterfaceWithS3BootScript ();
> +  //
> +  // Lock Down PMC
> +  //
> +  PmcLockWithS3BootScript ();
> +}
> +
> +/**
> +  Set eSPI BME bit
> +**/
> +VOID
> +ConfigureEspiBme (
> +  VOID
> +  )
> +{
> +  UINT64 EspiPciBase;
> +
> +  EspiPciBase = PCI_SEGMENT_LIB_ADDRESS (
> +                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                  DEFAULT_PCI_BUS_NUMBER_PCH,
> +                  PCI_DEVICE_NUMBER_PCH_LPC,
> +                  PCI_FUNCTION_NUMBER_PCH_LPC,
> +                  0
> +                  );
> +
> +  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);
> +  }
> +}
> +
> +/**
> +  Common PCH initialization before Boot Sript Table is closed
> +
> +**/
> +VOID
> +PchOnPciEnumCompleteCommon (
> +  VOID
> +  )
> +{
> +  UINT32                                    Data32Or;
> +  UINT32                                    Data32And;
> +  BOOLEAN                                   ResetStatus;
> +
> +  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() Start\n"));
> +
> +  if (SiScheduleResetIsRequired ()) {
> +    ResetStatus = SiScheduleResetPerformReset ();
> +    ASSERT (!ResetStatus);
> +  }
> +
> +  ProcessAllLocks ();
> +
> +  //
> +  // Perform remaining configuration for PCH SATA on End of DXE
> +  //
> +  ConfigurePchSataOnEndOfDxe ();
> +  //
> +  // PSTHCTL (0xD00h[2]) = 1, PSTH IOSF Primary Trunk Clock Gating Enable
> (PSTHIOSFPTCGE)
> +  //
> +  Data32And = 0xFFFFFFFF;
> +  Data32Or =  B_PSTH_PCR_PSTHIOSFPTCGE;
> +  PchPcrAndThenOr32 (PID_PSTH, R_PSTH_PCR_PSTHCTL, Data32And,
> Data32Or);
> +  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
> +    S3BootScriptWidthUint32,
> +    PID_PSTH, R_PSTH_PCR_PSTHCTL,
> +    &Data32Or,
> +    &Data32And
> +    );
> +
> +  //
> +  // Set eSPI BME after PCI enumeration
> +  //
> +  ConfigureEspiBme ();
> +
> +  ///
> +  /// Clear Global Reset Status, Power Failure and Host Reset Status bits
> +  ///
> +  PmcClearGlobalResetStatus ();
> +  PmcClearPowerFailureStatus ();
> +  PmcClearHostResetStatus ();
> +
> +  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() End\n"));
> +}
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
> new file mode 100644
> index 0000000000..b106c849e9
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
> @@ -0,0 +1,382 @@
> +/** @file
> +  This is the Uefi driver that initializes the Intel PCH.
> +
> +  Copyright (c) 2019 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 <Private/Protocol/PcieIoTrap.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Private/Library/PchPciExpressHelpersLib.h>
> +#include <PcieRegs.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPcie.h>
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsThermalCnl.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 = PciePmTrap;
> +    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;
> +  UINT64              ThermalPciBase;
> +
> +  ///
> +  /// 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);
> +
> +  //
> +  // Enable Thermal MSE
> +  //
> +  ThermalPciBase = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_THERMAL,
> +                     PCI_FUNCTION_NUMBER_PCH_THERMAL,
> +                     0
> +                     );
> +  if (PciSegmentRead16 (ThermalPciBase + PCI_VENDOR_ID_OFFSET) !=
> 0xFFFF) {
> +    if (((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBAR)
> & B_THERMAL_CFG_MEM_TBAR_MASK) != 0) ||
> +        ((PciSegmentRead32 (ThermalPciBase +
> R_THERMAL_CFG_MEM_TBARH) != 0))) {
> +      PciSegmentOr8 (ThermalPciBase + PCI_COMMAND_OFFSET,
> EFI_PCI_COMMAND_MEMORY_SPACE);
> +    }
> +  }
> +
> +  ReconfigurePciePowerManagementForS3 ();
> +  ProcessSmiLocks ();
> +#ifndef FSP_WRAPPER_FLAG
> +  PchOnPciEnumCompleteCommon ();
> +#endif
> +  ConfigureSerialIoAtS3Resume ();
> +}
> +
> +/**
> +  Register callback functions for PCH DXE.
> +**/
> +VOID
> +PchRegisterNotifications (
> +  VOID
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_EVENT   LegacyBootEvent;
> +  EFI_EVENT   ExitBootServicesEvent;
> +  VOID        *Registration;
> +
> +  ///
> +  /// Create PCI Enumeration Completed callback for PCH
> +  ///
> +  EfiCreateProtocolNotifyEvent (
> +    &gEfiPciEnumerationCompleteProtocolGuid,
> +    TPL_CALLBACK,
> +    PchOnPciEnumComplete,
> +    NULL,
> +    &Registration
> +    );
> +
> +  //
> +  // 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);
> +}
> +
> +/**
> +  Initialize the PCH device according to the PCH Policy HOB
> +  and install PCH info instance.
> +**/
> +VOID
> +InitializePchDevice (
> +  VOID
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "InitializePchDevice() Start\n"));
> +
> +  DEBUG ((DEBUG_INFO, "InitializePchDevice() End\n"));
> +}
> +/**
> +  <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 ();
> +
> +  InitializePchDevice ();
> +
> +  Status = PchAcpiInit (ImageHandle);
> +
> +  CreateSerialIoHandles ();
> +
> +  PchRegisterNotifications ();
> +
> +  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, PciePmTrap);
> +  } else {
> +    ASSERT (FALSE);
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() End\n"));
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
> new file mode 100644
> index 0000000000..15fe4628fb
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
> @@ -0,0 +1,85 @@
> +/** @file
> +  This is the FSP driver that initializes the Intel PCH.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include "PchInit.h"
> +
> +EFI_STATUS
> +EFIAPI
> +PchOnPciEnumCompleteFsp (
> +  IN  EFI_PEI_SERVICES            **PeiServices,
> +  IN  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
> +  IN  VOID                        *Ppi
> +  );
> +
> +STATIC
> +EFI_PEI_NOTIFY_DESCRIPTOR  mPchOnPciEnumCompleteNotifyList[] = {
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK  |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiPciEnumerationCompleteProtocolGuid,
> +    PchOnPciEnumCompleteFsp
> +  }
> +};
> +
> +/**
> +  <b>FSP PchInit Module Entry Point for FSP</b>\n
> +
> +  @param[in] FileHandle      PEIM's file handle
> +  @param[in] PeiServices     An indirect pointer to the EFI_PEI_SERVICES
> table published by the PEI Foundation
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchInitEntryPointFsp (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() Start\n"));
> +
> +  PchInitEntryPointCommon ();
> +
> +  Status = PeiServicesNotifyPpi (mPchOnPciEnumCompleteNotifyList);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() End\n"));
> +
> +  return Status;
> +}
> +
> +/**
> +  Fsp PCH initialization on PCI enumeration complete
> +
> +  @param[in]  PeiServices       An indirect pointer to the EFI_PEI_SERVICES
> table published by the PEI Foundation
> +  @param[in]  NotifyDescriptor  Address of the notification descriptor data
> structure.
> +  @param[in]  Ppi               Address of the PPI that was installed.
> +
> +  @retval EFI_SUCCESS             The function completed successfully
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchOnPciEnumCompleteFsp (
> +  IN  EFI_PEI_SERVICES            **PeiServices,
> +  IN  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
> +  IN  VOID                        *Ppi
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() Start\n"));
> +
> +  PchOnPciEnumCompleteCommon ();
> +
> +  DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
> new file mode 100644
> index 0000000000..6e30280fa7
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
> @@ -0,0 +1,89 @@
> +/** @file
> +  Perform related functions for PCH Sata in DXE phase
> +
> +  Copyright (c) 2019 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 <Register/PchRegsSata.h>
> +
> +/**
> +  Perform the remaining configuration on PCH SATA to perform device
> detection,
> +  then set the SATA SPD and PxE corresponding, and set the Register Lock on
> PCH SATA
> +
> +  @retval None
> +**/
> +VOID
> +ConfigurePchSataOnEndOfDxe (
> +  VOID
> +  )
> +{
> +  UINT64        PciSataRegBase;
> +  UINT16        SataPortsEnabled;
> +  UINT32        DwordReg;
> +  UINTN         Index;
> +  UINT32        SataCtrlIndex;
> +
> +  for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum ();
> 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    = GetSataRegBase (SataCtrlIndex);
> +    SataPortsEnabled  = 0;
> +
> +    DwordReg = PciSegmentRead32 (PciSataRegBase + R_SATA_CFG_PCS);
> +    for (Index = 0; Index < GetPchMaxSataPortNum (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 (PcdPciExpressBaseAddress) + PciSataRegBase +
> R_SATA_CFG_MAP,
> +      1,
> +      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) +
> 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 (PcdPciExpressBaseAddress) + PciSataRegBase +
> R_SATA_CFG_PCS,
> +      1,
> +      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) +
> 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 (PcdPciExpressBaseAddress) + PciSataRegBase +
> R_SATA_CFG_SATAGC,
> +      1,
> +      (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) +
> PciSataRegBase + R_SATA_CFG_SATAGC)
> +      );
> +  }
> +}
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
> new file mode 100644
> index 0000000000..d0f4b4fa56
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
> @@ -0,0 +1,57 @@
> +/** @file
> +  Initializes Serial IO Controllers.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include "PchInit.h"
> +#include <Library/PchSerialIoLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Register/PchRegsSerialIo.h>
> +
> +/**
> +  Puts all SerialIo controllers (except UARTs in debug mode) in D3
> +  Clears MemoryEnable for all PCI-mode controllers
> +**/
> +EFI_STATUS
> +ConfigureSerialIoAtBoot (
> +  VOID
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER Index;
> +  UINTN                    PciCfgBase;
> +
> +  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
> +    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
> +      if (IsSerialIoFunctionZero (Index)) {
> +        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index),
> GetSerialIoFunctionNumber (Index))) {
> +          PciCfgBase = FindSerialIoBar (Index,1);
> +          MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS,
> B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
> +        }
> +      }
> +      continue;
> +    }
> +    if ((Index >= PchSerialIoIndexUart0) &&
> +        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
> +        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index -
> PchSerialIoIndexUart0))) {
> +      continue;
> +    }
> +    PciCfgBase = FindSerialIoBar (Index,1);
> +    MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS,
> B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
> +    MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
> +    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
> +      MmioAnd32 (PciCfgBase + PCI_COMMAND_OFFSET,
> (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE |
> EFI_PCI_COMMAND_BUS_MASTER) );
> +      if (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index -
> PchSerialIoIndexUart0)) {
> +        continue;
> +      }
> +      MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, 0);
> +      MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0);
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
> new file mode 100644
> index 0000000000..5563d82076
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
> @@ -0,0 +1,156 @@
> +/** @file
> +  Initializes Serial IO Controllers.
> +
> +  Copyright (c) 2019 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/S3BootScriptLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +
> +#include "PchInit.h"
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Register/PchRegsSerialIo.h>
> +
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH          RootPort;
> +  ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
> +  CHAR8                         HidString[8];
> +  CHAR8                         UidString;
> +  CHAR8                         CidString;
> +  EFI_DEVICE_PATH_PROTOCOL      End;
> +} SERIALIO_DEVICE_PATH;
> +
> +#define gPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP,
> {(UINT8)(sizeof(ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
> +#define gAcpiDev
> {{ACPI_DEVICE_PATH,ACPI_EXTENDED_DP,{(UINT8)(sizeof(ACPI_EXTENDED_HI
> D_DEVICE_PATH)+SERIALIO_TOTAL_ID_LENGTH),0}},0,0,0}
> +#define gEndEntire
> {END_DEVICE_PATH_TYPE,END_ENTIRE_DEVICE_PATH_SUBTYPE,{END_DEVICE
> _PATH_LENGTH,0}}
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_DEVICE_PATH gSerialIoPath
> = {
> +  gPciRootBridge,
> +  gAcpiDev,
> +  "\0\0\0\0\0\0\0",
> +  '\0',
> +  '\0',
> +  gEndEntire
> +};
> +
> +/**
> +Mark memory used by SerialIo devices in ACPI mode as allocated
> +
> +@retval EFI_SUCCESS             The function completed successfully
> +**/
> +EFI_STATUS
> +AllocateSerialIoMemory (
> +  VOID
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER i;
> +  UINT8                    BarNumber;
> +  UINTN                    Bar;
> +  EFI_STATUS               Status;
> +
> +  for (i=0; i<PchSerialIoIndexMax; i++) {
> +    if (mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoHidden ||
> +        mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoAcpi) {
> +      for (BarNumber = 0; BarNumber<=1; BarNumber++) {
> +        Bar = FindSerialIoBar (i,BarNumber);
> +        Status = gDS->AddMemorySpace (
> +                        EfiGcdMemoryTypeReserved,
> +                        Bar,
> +                        V_SERIAL_IO_CFG_BAR_SIZE,
> +                        0
> +                        );
> +        ASSERT_EFI_ERROR (Status);
> +        if (EFI_ERROR (Status)) {
> +          return Status;
> +        }
> +        Status = gDS->AllocateMemorySpace (
> +                        EfiGcdAllocateAddress,
> +                        EfiGcdMemoryTypeReserved,
> +                        N_SERIAL_IO_CFG_BAR_ALIGNMENT,
> +                        V_SERIAL_IO_CFG_BAR_SIZE,
> +                        &Bar,
> +                        mImageHandle,
> +                        NULL
> +                        );
> +        ASSERT_EFI_ERROR (Status);
> +        if (EFI_ERROR (Status)) {
> +          return Status;
> +        }
> +      }
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +CreateSerialIoHandles (
> +  VOID
> +  )
> +{
> +  EFI_HANDLE NewHandle;
> +  EFI_DEVICE_PATH_PROTOCOL *NewPath;
> +  UINT32 Controller;
> +
> +  for (Controller = 0; Controller < PchSerialIoIndexMax; Controller++) {
> +    if (mPchConfigHob->SerialIo.DevMode[Controller] == PchSerialIoAcpi) {
> +      NewHandle = NULL;
> +      CopyMem (gSerialIoPath.HidString, GetSerialIoAcpiHid (Controller),
> SERIALIO_HID_LENGTH);
> +      NewPath = DuplicateDevicePath
> ((EFI_DEVICE_PATH_PROTOCOL*)&gSerialIoPath);
> +      gBS->InstallMultipleProtocolInterfaces (
> +             &NewHandle,
> +             &gEfiDevicePathProtocolGuid,
> +             NewPath,
> +             NULL );
> +    }
> +  }
> +}
> +
> +/**
> +  Puts all SerialIo controllers (except UARTs in debug mode) in D3.
> +  Clears MemoryEnable for all PCI-mode controllers on S3 resume
> +**/
> +VOID
> +ConfigureSerialIoAtS3Resume (
> +  VOID
> +  )
> +{
> +  PCH_SERIAL_IO_CONTROLLER Index;
> +  UINTN                    PciCfgBase;
> +  UINT32                   Data32;
> +
> +  for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
> +    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
> +      if (IsSerialIoFunctionZero (Index)) {
> +        if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index),
> GetSerialIoFunctionNumber (Index))) {
> +          PciCfgBase = FindSerialIoBar (Index,1);
> +          Data32 = MmioRead32 (PciCfgBase +
> R_SERIAL_IO_CFG_PME_CTRL_STS);
> +          Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
> +          S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase +
> R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
> +        }
> +      }
> +      continue;
> +    }
> +    if ((Index >= PchSerialIoIndexUart0) &&
> +        (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
> +        (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index -
> PchSerialIoIndexUart0))) {
> +      continue;
> +    }
> +    PciCfgBase = FindSerialIoBar (Index,1);
> +    Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
> +    Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
> +    S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase +
> R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
> +    if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
> +      Data32 = MmioRead32 (PciCfgBase + PCI_COMMAND_OFFSET);
> +      Data32 &= (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE |
> EFI_PCI_COMMAND_BUS_MASTER);
> +      S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase +
> PCI_COMMAND_OFFSET, 1, &Data32);
> +    }
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
> new file mode 100644
> index 0000000000..7fe1567c9f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
> @@ -0,0 +1,156 @@
> +/** @file
> +  PCH BIOS Write Protect Driver.
> +
> +  Copyright (c) 2019 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/PchRegsSpi.h>
> +
> +//
> +// Global variables
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED PCH_TCO_SMI_DISPATCH_PROTOCOL
> *mPchTcoSmiDispatchProtocol;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT64
> mSpiRegBase;
> +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
> +  )
> +{
> +  //
> +  // Disable BIOSWE bit to protect BIOS
> +  //
> +  PciSegmentAnd8 ((UINTN) (mSpiRegBase + R_SPI_CFG_BC), (UINT8)
> ~B_SPI_CFG_BC_WPD);
> +}
> +
> +/**
> +  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;
> +  }
> +
> +  mSpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
> +                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                  DEFAULT_PCI_BUS_NUMBER_PCH,
> +                  PCI_DEVICE_NUMBER_PCH_SPI,
> +                  PCI_FUNCTION_NUMBER_PCH_SPI,
> +                  0
> +                  );
> +
> +  mLpcRegBase = PCI_SEGMENT_LIB_ADDRESS (
> +                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_LPC,
> +                   PCI_FUNCTION_NUMBER_PCH_LPC,
> +                   0
> +                   );
> +
> +  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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
> new file mode 100644
> index 0000000000..e9f4c91ed4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
> @@ -0,0 +1,179 @@
> +/** @file
> +  PCH Init Smm module for PCH specific SMI handlers.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchInitSmm.h"
> +#include <Register/PchRegs.h>
> +#include <Register/RegsUsb.h>
> +#include <Register/PchRegsSmbus.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;
> +
> +//
> +// 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;
> +GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA
> *mSiConfigHobData;
> +
> +//
> +// 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 = PCI_SEGMENT_LIB_ADDRESS (
> +                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_SMBUS,
> +                   PCI_FUNCTION_NUMBER_PCH_SMBUS,
> +                   0
> +                   );
> +
> +  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);
> +}
> +
> +/**
> +  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);
> +
> +  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
> +  ASSERT (HobPtr.Guid != NULL);
> +  mSiConfigHobData = (SI_CONFIG_HOB_DATA *) GET_GUID_HOB_DATA
> (HobPtr.Guid);
> +
> +  mAcpiBaseAddr = PmcGetAcpiBase ();
> +
> +  AllocateReservedMmio ();
> +
> +  Status = InitializePchPcieSmm (ImageHandle, SystemTable);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = InstallPchBiosWriteProtect (ImageHandle, SystemTable);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = InstallPchSpiAsyncSmiHandler ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
> new file mode 100644
> index 0000000000..4a2d1f9cea
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
> @@ -0,0 +1,298 @@
> +/** @file
> +  PCH LAN Sx handler implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/TimerLib.h>
> +#include "PchInitSmm.h"
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Library/GbeMdiLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsLan.h>
> +
> +/**
> +  Checks if Lan is Enabled or Disabled
> +
> +  @retval  BOOLEAN    TRUE if device is enabled, FALSE otherwise.
> +**/
> +BOOLEAN
> +IsGbeEnabled (
> +  VOID
> +  )
> +{
> +  UINT64  GbePciBase;
> +
> +  GbePciBase = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_LAN,
> +                 PCI_FUNCTION_NUMBER_PCH_LAN,
> +                 0
> +                 );
> +
> +  if (PciSegmentRead32 (GbePciBase) != 0xFFFFFFFF) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +
> +/**
> +  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_LAN_MEM_CSR_RAL);
> +  RAH0 = MmioRead32 (GbeBar + R_LAN_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_LAN_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_LAN_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 = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_LAN,
> +                 PCI_FUNCTION_NUMBER_PCH_LAN,
> +                 0
> +                 );
> +
> +  if (PciSegmentRead16 (LanRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
> +    return;
> +  }
> +
> +  //
> +  // Check if GbE device is in D0
> +  //
> +  if ((PciSegmentRead16 (LanRegBase + R_LAN_CFG_PMCS) &
> B_LAN_CFG_PMCS_PS) != V_LAN_CFG_PMCS_PS0) {
> +    return;
> +  }
> +
> +  ASSERT (mResvMmioSize >= (1 << N_LAN_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_LAN_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_LAN_MEM_CSR_WUC) &
> B_LAN_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_LAN_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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
> new file mode 100644
> index 0000000000..eac2e1c3ec
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
> @@ -0,0 +1,436 @@
> +/** @file
> +  PCH Pcie SMM Driver Entry
> +
> +  Copyright (c) 2019 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/PchRegsPcie.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
> mPciePmTrapExecuted = 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
> +**/
> +STATIC
> +VOID
> +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;
> +  }
> +  //
> +  // 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;
> +      }
> +    }
> +    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
> +      );
> +    RootportDownstreamPmConfiguration (
> +      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +      DEFAULT_PCI_BUS_NUMBER_PCH,
> +      RpDevice,
> +      RpFunction,
> +      mTempRootPortBusNumMin,
> +      mTempRootPortBusNumMax,
> +      &mPcieRootPortConfig[PortIndex],
> +      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);
> +    }
> +  }
> +}
> +
> +/**
> +  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;
> +  UINTN                                     RpDevice;
> +  UINTN                                     RpFunction;
> +
> +  MaxPciePortNum                   = GetPchMaxPciePortNum ();
> +
> +  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
> +    GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
> +    RpBase = PCI_SEGMENT_LIB_ADDRESS
> (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH,
> (UINT32) RpDevice, (UINT32) RpFunction, 0);
> +
> +    if (PciSegmentRead16 (RpBase) != 0xFFFF) {
> +      RootportDownstreamPmConfiguration (
> +        DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +        DEFAULT_PCI_BUS_NUMBER_PCH,
> +        (UINT8)RpDevice,
> +        (UINT8)RpFunction,
> +        mTempRootPortBusNumMin,
> +        mTempRootPortBusNumMax,
> +        &mPcieRootPortConfig[PortIndex],
> +        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 == PciePmTrap) {
> +    if (mPciePmTrapExecuted == FALSE) {
> +      PchPciePmIoTrapSmiCallback ();
> +      mPciePmTrapExecuted = 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
> +  )
> +{
> +  mPciePmTrapExecuted = 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;
> +  UINTN                                 RpDevice;
> +  UINTN                                 RpFunction;
> +  EFI_HANDLE                            PcieHandle;
> +  PCH_PCIE_SMI_DISPATCH_PROTOCOL        *PchPcieSmiDispatchProtocol;
> +  EFI_HOB_GUID_TYPE*                    Hob;
> +  UINT32                                DevTableSize;
> +  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;
> +
> +  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)
> +    );
> +
> +  mDevAspmOverride                  = NULL;
> +  mNumOfDevAspmOverride             = 0;
> +
> +  Hob = GetFirstGuidHob (&gPchDeviceTableHobGuid);
> +  if (Hob != NULL) {
> +    DevTableSize = GET_GUID_HOB_DATA_SIZE (Hob);
> +    ASSERT ((DevTableSize % sizeof (PCH_PCIE_DEVICE_OVERRIDE)) == 0);
> +    mNumOfDevAspmOverride = DevTableSize / sizeof
> (PCH_PCIE_DEVICE_OVERRIDE);
> +    DEBUG ((DEBUG_INFO, "Found PcieDeviceTable HOB (%d entries)\n",
> mNumOfDevAspmOverride));
> +    Status = gSmst->SmmAllocatePool (
> +                      EfiRuntimeServicesData,
> +                      DevTableSize,
> +                      (VOID **) &mDevAspmOverride
> +                      );
> +    CopyMem (mDevAspmOverride, GET_GUID_HOB_DATA (Hob),
> DevTableSize);
> +  }
> +
> +  //
> +  // Throught all PCIE root port function and register the SMI Handler for
> enabled ports.
> +  //
> +  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
> +    GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
> +    RpBase = PCI_SEGMENT_LIB_ADDRESS
> (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH,
> (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_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;
> +      S3BootScriptSaveMemReadWrite (
> +        S3BootScriptWidthUint32,
> +        PcdGet64 (PcdPciExpressBaseAddress) + 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/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
> new file mode 100644
> index 0000000000..3c843616e4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
> @@ -0,0 +1,69 @@
> +/** @file
> +  PCH SPI Async SMI handler.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trolDriver.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trolDriver.c
> new file mode 100644
> index 0000000000..d843de3ad8
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmCon
> trolDriver.c
> @@ -0,0 +1,399 @@
> +/** @file
> +  This is the driver that publishes the SMM Control Protocol.
> +
> +  Copyright (c) 2019 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/PchRegsSpi.h>
> +#include <Register/PchRegsPmc.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_EVENT,
> +     "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_EVENT,
> +     "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_EVENT,
> +     "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_EVENT,
> +     "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_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)
> +      );
> +    //
> +    // Disable WADT_EN by default can avoid the WADT SMI during POST time
> when the WADT_STS is set as a wake source.
> +    // BIOS disable WADT_EN and keep WADT_STS into OS so OS can be aware
> of the wake source.
> +    //
> +    IoAnd32 ((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/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
> new file mode 100644
> index 0000000000..458d137e4f
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
> @@ -0,0 +1,310 @@
> +/** @file
> +  PCH SPI SMM Driver implements the SPI Host Controller Compatibility
> Interface.
> +
> +  Copyright (c) 2019 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 <Private/Library/PchSpiCommonLib.h>
> +#include <Private/Library/SmmPchPrivateLib.h>
> +#include <PchReservedResources.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsSpi.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 = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_SPI,
> +                     PCI_FUNCTION_NUMBER_PCH_SPI,
> +                     0
> +                     );
> +  // 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 = PCI_SEGMENT_LIB_ADDRESS (
> +                     DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                     DEFAULT_PCI_BUS_NUMBER_PCH,
> +                     PCI_DEVICE_NUMBER_PCH_SPI,
> +                     PCI_FUNCTION_NUMBER_PCH_SPI,
> +                     0
> +                     );
> +  ///
> +  /// 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;
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:14   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:14 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package
> DSC files
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc | 215
> ++++++++++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc     | 130
> ++++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc       |  69 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc             |  33 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc          |  37 ++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc             |  21 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc          |  44 ++++
>  7 files changed, 549 insertions(+)
> 
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
> new file mode 100644
> index 0000000000..37c77d8f63
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
> @@ -0,0 +1,215 @@
> +## @file
> +#  Component description file for the Coffee Lake silicon package DSC file.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[PcdsFeatureFlag]
> +gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE
> +gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |TRUE
> +gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE
> +gSiPkgTokenSpaceGuid.PcdSiCsmEnable                  |FALSE
> +gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE
> +gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE
> +gSiPkgTokenSpaceGuid.PcdAcpiEnable                   |FALSE
> +gSiPkgTokenSpaceGuid.PcdSourceDebugEnable            |FALSE
> +gSiPkgTokenSpaceGuid.PcdPpmEnable                    |TRUE
> +gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable        |FALSE
> +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.PcdIpuEnable                    |TRUE
> +gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE
> +gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE
> +gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE
> +gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE
> +gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE
> +gSiPkgTokenSpaceGuid.PcdCflCpuEnable                 |FALSE
> +gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |TRUE
> +gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |TRUE
> +gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE
> +
> +[PcdsFixedAtBuild.common]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress       |0xE0000000
> +gSiPkgTokenSpaceGuid.PcdTemporaryPciExpressRegionLength |0x10000000
> +
> +  gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin        |10
> +  gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax        |18
> +
> +[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 = CoffeelakeSiliconPkg
> +  PLATFORM_GUID = A45CA44C-AB04-4932-A77C-5A7179F66A22
> +  PLATFORM_VERSION = 0.4
> +  DSC_SPECIFICATION = 0x00010005
> +  OUTPUT_DIRECTORY = Build/CoffeelakeSiliconPkg
> +  SUPPORTED_ARCHITECTURES = IA32|X64
> +  BUILD_TARGETS = DEBUG|RELEASE
> +  SKUID_IDENTIFIER = DEFAULT
> +
> +  DEFINE   PLATFORM_SI_PACKAGE        = CoffeelakeSiliconPkg
> +
> +  #
> +  # Definition for Build Flag
> +  #
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
> +
> +[LibraryClasses.common]
> +  #
> +  # Entry point
> +  #
> +
> +PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.i
> n
> +f
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +
> +DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint
> .in
> +f
> +
> +UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntr
> +yPoint.inf
> +
> +UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/Uefi
> +ApplicationEntryPoint.inf
> +
> +PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BaseP
> e
> +CoffExtraActionLibNull.inf
> +
> +  #
> +  # Basic
> +  #
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +
> +
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRe
> pStr.i
> + nf  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +
> +
> PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci
> + .inf
> + PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
> +  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> +  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
> +
> +
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac
> heMa
> + intenanceLib.inf
> + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +
> +
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BaseP
> + eCoffGetEntryPointLib.inf
> +  #
> +  # UEFI & PI
> +  #
> +
> + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiB
> + ootServicesTableLib.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/PeiServicesTablePointerLibId
> + t/PeiServicesTablePointerLibIdt.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +
> + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTabl
> + eLib.inf
> +
> +
> + S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScrip
> + tLibNull.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/BaseSynchroni
> + zationLib.inf
> +
> +
> + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Bas
> + eDebugPrintErrorLevelLib.inf
> +
> SmiHandlerProfileLib|Edk2/MdePkg/Library/SmiHandlerProfileLibNull/SmiH
> + andlerProfileLibNull.inf
> +
> +  #
> +  # Misc
> +  #
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +
> +
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformance
> Li
> + bNull.inf  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +
> +
> TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemp
> l
> + ate.inf
> +
> PostCodeLib|MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDeb
> ug.i
> + nf
> +
> ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseR
> ep
> + ortStatusCodeLibNull.inf
> + MtrrLib|ClientSiliconPkg/Override/UefiCpuPkg/Library/MtrrLib/MtrrLib.i
> + nf  # CSPO-0012: RoyalParkOverrideContent
> + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
> +
> +###############################################################
> ########
> +##############################
> +
> +#
> +# Silicon Init Common Library
> +#
> +!include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
> +ConfigBlockLib|ClientSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBl
> +ConfigBlockLib|ockLib.inf
> +PchTraceHubInitLib|ClientSiliconPkg/Library/BasePchTraceHubInitLib/Base
> +PchTraceHubInitLib|PchTraceHubInitLib.inf
> +
> +[LibraryClasses.IA32]
> +#
> +# PEI phase common
> +#
> +  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +
> +MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemor
> yAllo
> +cationLib.inf
> +
> +ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiE
> x
> +tractGuidedSectionLib.inf
> +
> +###############################################################
> ########
> +##############################################################
> +
> +#
> +# Silicon Init Pei Library
> +#
> +!include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
> +
> +[LibraryClasses.IA32.SEC]
> +
> +[LibraryClasses.X64]
> + #
> + # DXE phase common
> + #
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> +MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMem
> oryAl
> +locationLib.inf
> +
> +ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/Dxe
> Ex
> +tractGuidedSectionLib.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/SmmServicesT
> able
> +Lib.inf
> +
> +MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe
> moryAllo
> +cationLib.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
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
> new file mode 100644
> index 0000000000..b6d2058669
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
> @@ -0,0 +1,130 @@
> +## @file
> +# Silicon build option configuration file.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[BuildOptions]
> +# Define Build Options both for EDK and EDKII drivers.
> +
> +# SA
> +!if gSiPkgTokenSpaceGuid.PcdPttEnable == TRUE
> +  DEFINE PTT_BUILD_OPTION = -DPTT_FLAG=1 !else
> +  DEFINE PTT_BUILD_OPTION =
> +!endif
> +
> +#
> +# System Agent
> +#
> +!if gSiPkgTokenSpaceGuid.PcdSgEnable == TRUE
> +  DEFINE DSC_SG_BUILD_OPTIONS = -DSG_SUPPORT=1 !else
> +  DEFINE DSC_SG_BUILD_OPTIONS =
> +!endif
> +
> +!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 =
> +
> +!if gSiPkgTokenSpaceGuid.PcdCflCpuEnable == TRUE
> +  DEFINE CPU_FLAGS = -DCPU_CFL
> +!else
> +  DEFINE CPU_FLAGS =
> +!endif
> +
> +
> +DEFINE DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(BDAT_BUILD_OPTION)
> +$(PTT_BUILD_OPTION) $(DEBUG_BUILD_OPTIONS) DEFINE
> +DSC_SIPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
> +$(DSC_SG_BUILD_OPTIONS) $(SIMICS_BUILD_OPTIONS) $(CPU_FLAGS)
> +$(HSLE_BUILD_OPTIONS) $(RELEASE_CATALOG_BUILD_OPTIONS)
> +$(DSC_TXT_BUILD_OPTIONS)
> +
> +!if gSiPkgTokenSpaceGuid.PcdSourceDebugEnable == TRUE
> +  *_*_X64_GENFW_FLAGS = --keepexceptiontable !endif
> +
> +[BuildOptions.Common.EDKII]
> +
> +#
> +# For IA32 Global Build Flag
> +#
> +       *_*_IA32_PP_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_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
> +#
> +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
> +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_PP_FLAGS       = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_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
> +#
> +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
> +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/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
> new file mode 100644
> index 0000000000..2df08c6d01
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
> @@ -0,0 +1,69 @@
> +## @file
> +#  Component description file for the Coffee Lake silicon package both PEI
> and DXE libraries DSC file.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +#
> +# Set PCH generation according PCD.
> +# The DEFINE will be used to select PCH library INF file corresponding
> +to PCH generation # DEFINE  PCH = Cnl
> +
> +#
> +# Cpu
> +#
> +
> CpuPlatformLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/PeiDxeSmmCpuPlatf
> orm
> + CpuPlatformLib|Lib/PeiDxeSmmCpuPlatformLib.inf
> +
> CpuMailboxLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/BaseCpuMailboxLib
> Null
> + CpuMailboxLib|/BaseCpuMailboxLibNull.inf
> +
> +#
> +# Me
> +#
> +
> +#
> +# Pch
> +#
> +
> PchCycleDecodingLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPch
> Cyc
> + PchCycleDecodingLib|leDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
> +
> PchGbeLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchGbeLib/Pe
> iDxe
> + PchGbeLib|SmmPchGbeLib.inf
> +
> PchInfoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchInfoLib/Pei
> D
> + PchInfoLib|xeSmmPchInfoLib$(PCH).inf
> +
> SataLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmSataLib/PeiDxeS
> mmS
> + SataLib|ataLib$(PCH).inf
> +
> PchPcieRpLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcieRpLi
> b/
> + PchPcieRpLib|PeiDxeSmmPchPcieRpLib.inf
> +
> PchPcrLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcrLib/PeiD
> xe
> + PchPcrLib|SmmPchPcrLib.inf
> +
> PmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSm
> mPmc
> + PmcLib|Lib.inf
> +
> +
> PchSbiAccessLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSbiA
> cce
> + PchSbiAccessLib|ssLib/PeiDxeSmmPchSbiAccessLib.inf
> +
> GpioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS
> mmG
> + GpioLib|pioLib.inf
> +!if gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable == TRUE
> +
> PchSerialIoUartLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSe
> ri
> + PchSerialIoUartLib|alIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
> +!else
> +
> PchSerialIoUartLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BasePchSerialIoU
> + PchSerialIoUartLib|artLibNull/BasePchSerialIoUartLibNull.inf
> +!endif
> +
> PchSerialIoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSerialI
> o
> + PchSerialIoLib|Lib/PeiDxeSmmPchSerialIoLibCnl.inf
> +
> PchEspiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchEspiLib/Pe
> iD
> + PchEspiLib|xeSmmPchEspiLib.inf
> +
> PchWdtCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPch
> WdtComm
> + PchWdtCommonLib|onLib/PeiDxeSmmPchWdtCommonLib.inf
> +
> ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseResetSystemLib
> /B
> + ResetSystemLib|aseResetSystemLib.inf
> +
> SmbusLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseSmbusLib/BaseSmbus
> Lib.
> + SmbusLib|inf
> +
> BiosLockLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmBiosLockLib/
> Pe
> + BiosLockLib|iDxeSmmBiosLockLib.inf
> + #private
> +
> PchPciExpressHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/Pei
> +
> PchPciExpressHelpersLib|DxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPc
> iE
> + PchPciExpressHelpersLib|xpressHelpersLib.inf
> +
> PchInitCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeS
> mmP
> + PchInitCommonLib|chInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
> +
> PchSpiCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BasePchS
> piC
> + PchSpiCommonLib|ommonLib/BasePchSpiCommonLib.inf
> +
> GpioPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmG
> pi
> + GpioPrivateLib|oPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
> +
> PchPsfPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmm
> P
> + PchPsfPrivateLib|chPsfPrivateLib/PeiDxeSmmPchPsfPrivateLib$(PCH).inf
> +
> PmcPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmP
> mcP
> + PmcPrivateLib|rivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
> +
> PmcPrivateLibWithS3|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxe
> S
> +
> PmcPrivateLibWithS3|mmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
> +
> PchDmiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSmmPchD
> miLi
> + PchDmiLib|b/PeiDxeSmmPchDmiLib.inf
> +
> PchDmiWithS3Lib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiDxeSm
> mPc
> + PchDmiWithS3Lib|hDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
> +
> SiScheduleResetLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BaseSiSc
> + SiScheduleResetLib|heduleResetLib/BaseSiScheduleResetLib.inf
> +
> +#
> +# SA
> +#
> +
> SaPlatformLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiDxeSmmS
> aPl
> + SaPlatformLib|atformLib/PeiDxeSmmSaPlatformLib.inf
> +
> +#
> +# Memory
> +#
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
> new file mode 100644
> index 0000000000..07677ece1a
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
> @@ -0,0 +1,33 @@
> +## @file
> +#  Component description file for the Coffee Lake silicon package DXE drivers.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +#
> +# Common
> +#
> +
> +#
> +# Pch
> +#
> +  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
> +  $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
> +
> +  $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
> +
> +
> $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.in
> f
> +  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
> +
> +#
> +# SystemAgent
> +#
> +  $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
> +
> +!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
> +  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
> +  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
> +!endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
> new file mode 100644
> index 0000000000..214de06d58
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
> @@ -0,0 +1,37 @@
> +## @file
> +#  Component description file for the Coffee Lake silicon package DXE
> libraries.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +#
> +# Silicon Init Dxe Library
> +#
> +
> +#
> +# Common
> +#
> +!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
> +
> AslUpdateLib|$(PLATFORM_SI_PACKAGE)/Library/DxeAslUpdateLib/DxeAslU
> pda
> + AslUpdateLib|teLib.inf
> +!else
> +
> AslUpdateLib|$(PLATFORM_SI_PACKAGE)/Library/DxeAslUpdateLibNull/DxeA
> sl
> + AslUpdateLib|UpdateLibNull.inf
> +!endif
> +
> SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/B
> + SiConfigBlockLib|aseSiConfigBlockLib.inf
> +
> +#
> +# Pch
> +#
> +
> PchHdaLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/DxePchHdaLib/Dx
> eP
> + PchHdaLib|chHdaLib.inf
> +
> ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeResetSystemLib/
> Dx
> + ResetSystemLib|eResetSystemLib.inf
> +
> DxePchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxePchPolicyLib/Dxe
> + DxePchPolicyLib|PchPolicyLib.inf
> +
> GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/BaseGpioHel
> p
> + GpioHelpersLib|ersLibNull/BaseGpioHelpersLibNull.inf
> +
> GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/DxeGpio
> Na
> + GpioNameBufferLib|meBufferLib/DxeGpioNameBufferLib.inf
> +
> SmmPchPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/SmmPchP
> riv
> + SmmPchPrivateLib|ateLib/SmmPchPrivateLib.inf
> +
> +#
> +# SystemAgent
> +#
> +
> DxeSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/DxeSaPolicy
> L
> + DxeSaPolicyLib|ib/DxeSaPolicyLib.inf
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
> new file mode 100644
> index 0000000000..f30c7e0ae1
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
> @@ -0,0 +1,21 @@
> +## @file
> +#  Component description file for theCoffee Lake silicon package PEI drivers.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +#
> +# Common
> +#
> +
> +#
> +# SystemAgent
> +#
> +
> +#
> +# Cpu
> +#
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
> b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
> new file mode 100644
> index 0000000000..6e244a6ded
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
> @@ -0,0 +1,44 @@
> +## @file
> +#  Component description file for the Coffee Lake silicon package PEI libraries.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +#
> +# Silicon Init Pei Library
> +#
> + SiPolicyLib|$(PLATFORM_SI_PACKAGE)/Library/PeiSiPolicyLib/PeiSiPolicyL
> + SiPolicyLib|ib.inf
> +
> SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/B
> + SiConfigBlockLib|aseSiConfigBlockLib.inf
> + StallPpiLib|$(PLATFORM_SI_PACKAGE)/Library/PeiInstallStallPpiLib/PeiSt
> + StallPpiLib|allPpiLib.inf
> +
> +#
> +# Pch
> +#
> +
> PchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiPchPolicyLib/PeiPch
> + PchPolicyLib|PolicyLibCnl.inf
> +!if gSiPkgTokenSpaceGuid.PcdOcWdtEnable == TRUE
> +
> OcWdtLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiOcWdtLib/PeiOcWdtLib
> .in
> + OcWdtLib|f
> +!else
> +
> OcWdtLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiOcWdtLibNull/PeiOcWd
> tLi
> + OcWdtLib|bNull.inf
> +!endif
> +
> ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiResetSystemLib/P
> e
> + ResetSystemLib|iResetSystemLib.inf
> +
> PchResetLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiPchResetLib/PeiPchR
> e
> + PchResetLib|setLib.inf
> + SpiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiSpiLib/PeiSpiLib.inf
> +
> GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiGpioHelp
> e
> + GpioHelpersLib|rsLib/PeiGpioHelpersLib.inf
> +
> GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/Private/PeiGpio
> Na
> + GpioNameBufferLib|meBufferLib/PeiGpioNameBufferLib.inf
> +
> +#
> +# Me
> +#
> +
> PeiMePolicyLib|$(PLATFORM_SI_PACKAGE)/Me/Library/PeiMePolicyLib/PeiM
> eP
> + PeiMePolicyLib|olicyLib.inf
> +
> +#
> +# SA
> +#
> +
> +PeiSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiSaPolicy
> Li
> +b/PeiSaPolicyLib.inf
> +#
> +# Cpu
> +#
> +
> CpuPolicyLib|$(PLATFORM_SI_PACKAGE)/Cpu/Library/PeiCpuPolicyLib/PeiCp
> u
> + CpuPolicyLib|PolicyLib.inf
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:15 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent:
> Add modules
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> * SaAcpiTables - SA (DMAR) ACPI tables.
> * SaSsdt - SA SSDT ACPI tables.
> * SaInitDxe - Generic DXE SA initialization.
> * SmmAccess - Produces an instance of EFI_SMM_ACCESS2_PROTOCOL.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
> |   50 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
> |   49 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> |  116 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> .inf                    |   48 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> |   25 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcCommonTypes.h |  230 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcInterface.h   | 1567 ++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcRmtData.h     |  203 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcSpdData.h     | 1167 ++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeel
> ake/MrcTypes.h       |  237 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInt
> erface.h              |   15 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> |   50 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.
> h                   |  193 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
> |   91 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> |   23 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> |   71 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> |  139 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraph
> icsInit.h            |   17 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> |   53 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> Driver.h                |  162 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> |  157 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.
> c                   |  570 +++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> |  171 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> |  171 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> |  496 ++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> |  179 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> |  122 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> |  717 +++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess
> Driver.c                |  356 +++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
> |  250 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> |  794 ++++++++++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> | 1666 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCom
> mon.asl               |  472 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.a
> sl                  |  369 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGb
> da.asl               |  129 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.
> asl                 |  296 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbc
> b.asl               |  262 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> |   87 +
>  Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> |   31 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
> |  147 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
> |   22 +
>  41 files changed, 11970 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> new file mode 100644
> index 0000000000..56ddc2957f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.i
> nf
> @@ -0,0 +1,50 @@
> +## @file
> +#  Component description file for the ACPI tables
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION          = 0x00010005
> +BASE_NAME            = SaAcpiTables
> +FILE_GUID            = 3c0ed5e2-91ea-4b94-820d-9daf9a3bb4a2
> +MODULE_TYPE          = USER_DEFINED
> +VERSION_STRING       = 1.0
> +
> +[Sources]
> +  Dmar/Dmar.aslc
> +  Dmar/Dmar.h
> +
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +###############################################################
> #################
> +#
> +# Library Class Section - list of Library Classes that are required for
> +#                         this module.
> +#
> +###############################################################
> #################
> +
> +[LibraryClasses]
> +
> +###############################################################
> #################
> +#
> +# Protocol C Name Section - list of Protocol and Protocol Notify C Names
> +#                           that this module uses or produces.
> +#
> +###############################################################
> #################
> +[Pcd]
> +
> +[Protocols]
> +
> +[PPIs]
> +
> +[Guids]
> +
> +[Depex]
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.i
> nf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> inf
> new file mode 100644
> index 0000000000..3588565aac
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> inf
> @@ -0,0 +1,49 @@
> +## @file
> +#  Component description file for the ACPI tables
> +#
> +# Copyright (c) 2019 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
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +###############################################################
> #################
> +#
> +# Library Class Section - list of Library Classes that are required for
> +#                         this module.
> +#
> +###############################################################
> #################
> +
> +[LibraryClasses]
> +
> +###############################################################
> #################
> +#
> +# Protocol C Name Section - list of Protocol and Protocol Notify C Names
> +#                           that this module uses or produces.
> +#
> +###############################################################
> #################
> +[Pcd]
> +
> +[Protocols]
> +
> +[PPIs]
> +
> +[Guids]
> +
> +[Depex]
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> new file mode 100644
> index 0000000000..9937fc60e5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> @@ -0,0 +1,116 @@
> +## @file
> +# Component description file for SystemAgent Initialization driver
> +#
> +# Copyright (c) 2019 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
> +TimerLib
> +PciCf8Lib
> +PciSegmentLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +CpuPlatformLib
> +IoLib
> +S3BootScriptLib
> +PmcLib
> +PchCycleDecodingLib
> +PchInfoLib
> +GpioLib
> +ConfigBlockLib
> +SaPlatformLib
> +PchPcieRpLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +PcAtChipsetPkg/PcAtChipsetPkg.dec
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> +gSiPkgTokenSpaceGuid.PcdMchBaseAddress
> +gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
> +
> +[Sources]
> +SaInitDxe.h
> +SaInitDxe.c
> +SaInit.h
> +SaInit.c
> +VTd.c
> +VTd.h
> +IgdOpRegionInit.h
> +IgdOpRegionInit.c
> +GraphicsInit.h
> +GraphicsInit.c
> +PciExpressInit.h
> +PciExpressInit.c
> +PcieComplex.c
> +PcieComplex.h
> +SaAcpi.c
> +
> +[Protocols]
> +gEfiAcpiTableProtocolGuid              ## CONSUMES
> +gSaNvsAreaProtocolGuid                 ## PRODUCES
> +gSaPolicyProtocolGuid                  ## CONSUMES
> +gEfiCpuArchProtocolGuid                ## CONSUMES
> +gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
> +gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
> +gEfiPciIoProtocolGuid                  ## CONSUMES
> +gIgdOpRegionProtocolGuid               ## PRODUCES
> +gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
> +gEfiLegacyBiosProtocolGuid             ## CONSUMES
> +gGopComponentName2ProtocolGuid         ## CONSUMES
> +gSaIotrapSmiProtocolGuid               ## CONSUMES
> +
> +[Guids]
> +gSaConfigHobGuid
> +gSgAcpiTablePchStorageGuid
> +gSaAcpiTableStorageGuid
> +gSgAcpiTableStorageGuid
> +gSaSsdtAcpiTableStorageGuid
> +gPegSsdtAcpiTableStorageGuid
> +gEfiEndOfDxeEventGroupGuid
> +gSiConfigHobGuid        ## CONSUMES
> +gMiscDxeConfigGuid
> +gGraphicsDxeConfigGuid
> +gMemoryDxeConfigGuid
> +gPcieDxeConfigGuid
> +gVbiosDxeConfigGuid
> +gPchInfoHobGuid
> +
> +[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/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> new file mode 100644
> index 0000000000..9356781c9e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ss.inf
> @@ -0,0 +1,48 @@
> +## @file
> +# Component description file for the SmmAccess module
> +#
> +# {1323C7F8-DAD5-4126-A54B-7A05FBF41515}
> +#
> +# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SmmAccess
> +FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SmmAccessDriverEntryPoint
> +
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +BaseLib
> +BaseMemoryLib
> +DebugLib
> +HobLib
> +PciLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Sources]
> +SmmAccessDriver.h
> +SmmAccessDriver.c
> +
> +
> +[Protocols]
> +gEfiSmmAccess2ProtocolGuid       ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmPeiSmramMemoryReserveGuid
> +
> +
> +[Depex]
> +TRUE
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> new file mode 100644
> index 0000000000..4339256bba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  This file describes the contents of the ACPI DMA address Remapping
> +  Some additional ACPI values are defined in Acpi1_0.h and Acpi2_0.h.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_DMAR_H_
> +#define _SA_DMAR_H_
> +
> +///
> +/// Include standard ACPI table definitions
> +///
> +#include <IndustryStandard/Acpi30.h>
> +#include <DmaRemappingTable.h>
> +
> +#pragma pack(1)
> +
> +#define EFI_ACPI_DMAR_OEM_TABLE_ID    0x20202020324B4445  ///<
> "EDK2    "
> +#define EFI_ACPI_DMAR_OEM_CREATOR_ID  0x4C544E49  ///< "INTL"
> +#pragma pack()
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> new file mode 100644
> index 0000000000..54cb69066d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcCommonTypes.h
> @@ -0,0 +1,230 @@
> +/** @file
> +  This file contains the definitions common to the MRC API and other APIs.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcCommonTypes_h_
> +#define _MrcCommonTypes_h_
> +
> +#define INT32_MIN                       (0x80000000)
> +#ifndef INT32_MAX  //INT32_MAX->Already defined
> +#define INT32_MAX                       (0x7FFFFFFF)
> +#endif
> +#define INT16_MIN                       (0x8000)
> +#define INT16_MAX                       (0x7FFF)
> +
> +///
> +/// System boot mode.
> +///
> +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.
> +} MrcBootMode;
> +
> +///
> +/// DIMM memory package
> +/// This enum matches SPD Module Type - SPD byte 3, bits [3:0]
> +/// Note that DDR4 have different encoding for some module types
> +///
> +typedef enum {
> +  RDimmMemoryPackage          = 1,
> +  UDimmMemoryPackage          = 2,
> +  SoDimmMemoryPackage         = 3,
> +  MicroDimmMemoryPackageDdr3  = 4,
> +  LrDimmMemoryPackageDdr4     = 4,
> +  MiniRDimmMemoryPackage      = 5,
> +  MiniUDimmMemoryPackage      = 6,
> +  MiniCDimmMemoryPackage      = 7,
> +  LpDimmMemoryPackage         = 7,
> +  SoUDimmEccMemoryPackageDdr3 = 8,
> +  SoRDimmEccMemoryPackageDdr4 = 8,
> +  SoRDimmEccMemoryPackageDdr3 = 9,
> +  SoUDimmEccMemoryPackageDdr4 = 9,
> +  SoCDimmEccMemoryPackage     = 10,
> +  LrDimmMemoryPackage         = 11,
> +  SoDimm16bMemoryPackage      = 12,
> +  SoDimm32bMemoryPackage      = 13,
> +  NonDimmMemoryPackage        = 14,
> +  MemoryPackageMax,                       ///< MEMORY_PACKAGE
> enumeration maximum value.
> +  MemoryPackageDelim = INT32_MAX          ///< This value ensures the
> enum size is consistent on both sides of the PPI.
> +} MEMORY_PACKAGE;
> +
> +///
> +/// Memory training I/O levels.
> +///
> +typedef enum {
> +  DdrLevel   = 0,                         ///< Refers to frontside of DIMM
> +  LrbufLevel = 1,                         ///< Refers to data level at backside of
> LRDIMM or AEP buffer
> +  RegALevel  = 2,                         ///< Refers to cmd level at backside of
> register - side A
> +  RegBLevel  = 3,                         ///< Refers to cmd level at backside of
> register - side B
> +  GsmLtMax,                               ///< GSM_LT enumeration maximum
> value.
> +  GsmLtDelim = INT32_MAX                  ///< This value ensures the enum
> size is consistent on both sides of the PPI.
> +} GSM_LT;
> +
> +///
> +/// Memory training margin group selectors.
> +///
> +typedef enum {
> +  RecEnDelay       = 0,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RCVEN sampling window later in time relative to
> the RX DQS strobes.
> +  RxDqsDelay       = 1,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe later in time relative to the RX DQ
> signal (i.e. toward the hold side of the eye).
> +  RxDqDelay        = 2,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQ byte/nibble/bitlane later in time relative
> to the RX DQS signal (i.e.closing the gap between DQ and DQS in the setup side
> of the eye).
> +  RxDqsPDelay      = 3,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe for "even" chunks later in time
> relative to the RX DQ signal. Even chunks are 0, 2, 4, 6 within the 0 to 7 chunks
> of an 8 burst length cacheline, for example.
> +  RxDqsNDelay      = 4,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe for "odd" chunks later in time
> relative to the RX DQ signal. Odd chunks are 1, 3, 5, 7 within the 0 to 7 chunks
> of an 8 burst length cacheline, for example.
> +  RxVref           = 5,                   ///< Linear increment (Vref ticks), where the
> positive increment moves the byte/nibble/bitlane RX Vref to a higher voltage.
> +  RxEq             = 6,                   ///< RX CTLE setting indicating a set of
> possible resistances, capacitance, current steering, etc. values, which may be a
> different set of values per product. The setting combinations are indexed by
> integer values.
> +  RxDqBitDelay     = 7,                   ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQ bitlane later in time relative to the RX DQS
> signal (i.e.closing the gap between DQ and DQS in the setup side of the eye).
> +  RxVoc            = 8,                   ///< Monotonic increment (Sense Amp
> setting), where the positive increment moves the byte/nibble/bitlane's
> effective switching point to a lower Vref value.
> +  RxOdt            = 9,                   ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  RxOdtUp          = 10,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  RxOdtDn          = 11,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  DramDrvStr       = 12,                  ///< Drive strength setting resistance
> setting within a set of possible resistances (or currents), which may be a
> different set of values per product. Indexed by integer values.
> +  McOdtDelay       = 13,                  ///<
> +  McOdtDuration    = 14,                  ///<
> +  SenseAmpDelay    = 15,                  ///< This may be used to indicate
> CmdToDiffAmpEn for SoC's.
> +  SenseAmpDuration = 16,                  ///<
> +  RoundTripDelay   = 17,                  ///< This may be used to indicate
> CmdToRdDataValid for SoC's.
> +  RxDqsBitDelay    = 18,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS within the bitlane later in time relative
> to the RX DQ signal (i.e.closing the gap between DQ and DQS in the hold side of
> the eye).
> +  RxDqDqsDelay     = 19,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS per strobe later in time relative to the RX
> DQ signal (i.e. closing the gap between DQS and DQ in the hold side of the eye.
> The difference between this parameter and RxDqsDelay is that both the DQ
> and DQS timings may be moved in order to increase the total range of DQDQS
> timings.
> +  WrLvlDelay       = 20,                  ///< Linear delay (PI ticks), where the
> positive increment moves both the TX DQS and TX DQ signals later in time
> relative to all other bus signals.
> +  TxDqsDelay       = 21,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQS strobe later in time relative to all other
> bus signals.
> +  TxDqDelay        = 22,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ byte/nibble/bitlane later in time relative
> to all other bus signals.
> +  TxVref           = 23,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the byte/nibble/bitlane TX Vref to a higher
> voltage. (Assuming this will abstract away from the range specifics for DDR4, for
> example.)
> +  TxEq             = 24,                  ///< TX EQ setting indicating a set of
> possible equalization levels, which may be a different set of values per product.
> The setting combinations are indexed by integer values.
> +  TxDqBitDelay     = 25,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ bitlane later in time relative to all other
> bus signals.
> +  TxRon            = 26,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxRonUp          = 27,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxRonDn          = 28,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxSlewRate       = 29,                  ///< Monotonic increment, where the
> positive increment moves the byte/nibble/bitlane's effective slew rate to a
> higher slope.
> +  TxImode          = 30,                  ///< TX I-Mode Boost setting indicating a
> set of possible current boost levels, which may be a different set of values per
> product. The setting combinations are indexed by integer values.
> +  WrOdt            = 31,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  NomOdt           = 32,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  ParkOdt          = 33,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +  TxTco            = 34,                  ///<
> +  RxCtleR          = 36,                  ///<
> +  RxCtleC          = 37,                  ///<
> +  RxDqsPBitDelay   = 38,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS bitlane timing for "even" chunks later in
> time relative to the RX DQ bitlane signal. Even chunks are 0, 2, 4, 6 within the
> 0 to 7 chunks of an 8 burst length cacheline, for example.
> +  RxDqsNBitDelay   = 39,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS bitlane timing for "odd" chunks later in
> time relative to the RX DQ bitlane signal. Odd chunks are 1, 3, 5, 7 within the 0
> to 7 chunks of an 8 burst length cacheline, for example.
> +  CmdAll           = 40,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_ALL category later in
> time relative to all other signals on the bus.
> +  CmdGrp0          = 41,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP0 category later
> in time relative to all other signals on the bus.
> +  CmdGrp1          = 42,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP1 category later
> in time relative to all other signals on the bus.
> +  CmdGrp2          = 43,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_GRP2 category later
> in time relative to all other signals on the bus.
> +  CtlAll           = 44,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_ALL category later in
> time relative to all other signals on the bus.
> +  CtlGrp0          = 45,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP0 category later
> in time relative to all other signals on the bus.
> +  CtlGrp1          = 46,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP1 category later
> in time relative to all other signals on the bus.
> +  CtlGrp2          = 47,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP2 category later
> in time relative to all other signals on the bus.
> +  CtlGrp3          = 48,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP3 category later
> in time relative to all other signals on the bus.
> +  CtlGrp4          = 49,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP4 category later
> in time relative to all other signals on the bus.
> +  CtlGrp5          = 50,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CTL_GRP5 category later
> in time relative to all other signals on the bus.
> +  CmdCtlAll        = 51,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CMD_CTL_ALL category
> later in time relative to all other signals on the bus.
> +  CkAll            = 52,                  ///< Linear delay (PI ticks), where the
> positive increment moves all signals assigned to the CK_ALL category later in
> time relative to all other signals on the bus.
> +  CmdVref          = 53,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the CMD Vref to a higher voltage.
> +  AlertVref        = 54,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the ALERT Vref to a higher voltage.
> +  CmdRon           = 55,                  ///< Resistance setting within a set of
> possible resistances, which may be a different set of values per product.
> Indexed by integer values.
> +
> +  EridDelay        = 60,                  ///< Linear delay (PI ticks), where the
> positive increment moves the ERID signals later in time relative to the internal
> sampling clock (i.e.closing the gap between ERID and internal sampling clock in
> the setup side of the eye). This group is applicable for DDRT DIMMs.
> +  EridVref         = 61,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the ERID Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> +  ErrorVref        = 62,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the ERROR Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> +  ReqVref          = 63,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the REQ Vref to a higher voltage. This group is
> applicable for DDRT DIMMs.
> +  RecEnOffset      = 64,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RCVEN sampling window later in time relative to
> the RX DQS strobes.
> +  RxDqsOffset      = 65,                  ///< Linear delay (PI ticks), where the
> positive increment moves the RX DQS strobe later in time relative to the RX DQ
> signal (i.e. toward the hold side of the eye).
> +  RxVrefOffset     = 66,                  ///< Linear increment (Vref ticks), where
> the positive increment moves the byte/nibble/bitlane RX Vref to a higher
> voltage.
> +  TxDqsOffset      = 67,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQS strobe later in time relative to all other
> bus signals.
> +  TxDqOffset       = 68,                  ///< Linear delay (PI ticks), where the
> positive increment moves the TX DQ byte/nibble/bitlane later in time relative
> to all other bus signals.
> +  GsmGtMax,                               ///< SSA_GSM_GT enumeration
> maximum value.
> +  GsmGtDelim = INT32_MAX                  ///< This value ensures the enum
> size is consistent on both sides of the PPI.
> +} GSM_GT;
> +
> +typedef enum {
> +  SigRasN   = 0,
> +  SigCasN   = 1,
> +  SigWeN    = 2,
> +  SigBa0    = 3,
> +  SigBa1    = 4,
> +  SigBa2    = 5,
> +  SigA0     = 6,
> +  SigA1     = 7,
> +  SigA2     = 8,
> +  SigA3     = 9,
> +  SigA4     = 10,
> +  SigA5     = 11,
> +  SigA6     = 12,
> +  SigA7     = 13,
> +  SigA8     = 14,
> +  SigA9     = 15,
> +  SigA10    = 16,
> +  SigA11    = 17,
> +  SigA12    = 18,
> +  SigA13    = 19,
> +  SigA14    = 20,
> +  SigA15    = 21,
> +  SigA16    = 22,
> +  SigA17    = 23,
> +  SigCs0N   = 24,
> +  SigCs1N   = 25,
> +  SigCs2N   = 26,
> +  SigCs3N   = 27,
> +  SigCs4N   = 28,
> +  SigCs5N   = 29,
> +  SigCs6N   = 30,
> +  SigCs7N   = 31,
> +  SigCs8N   = 32,
> +  SigCs9N   = 33,
> +  SigCke0   = 34,
> +  SigCke1   = 35,
> +  SigCke2   = 36,
> +  SigCke3   = 37,
> +  SigCke4   = 38,
> +  SigCke5   = 39,
> +  SigOdt0   = 40,     //could also be used for CA-ODT for LP4
> +  SigOdt1   = 41,     //could also be used for CA-ODT for LP4
> +  SigOdt2   = 42,
> +  SigOdt3   = 43,
> +  SigOdt4   = 44,
> +  SigOdt5   = 45,
> +  SigPar    = 46,
> +  SigAlertN = 47,
> +  SigBg0    = 48,
> +  SigBg1    = 49,
> +  SigActN   = 50,
> +  SigCid0   = 51,
> +  SigCid1   = 52,
> +  SigCid2   = 53,
> +  SigCk0    = 54,
> +  SigCk1    = 55,
> +  SigCk2    = 56,
> +  SigCk3    = 57,
> +  SigCk4    = 58,
> +  SigCk5    = 59,
> +  SigGnt0   = 60,
> +  SigGnt1   = 61,
> +  SigErid00 = 62,
> +  SigErid01 = 63,
> +  SigErid10 = 64,
> +  SigErid11 = 65,
> +  SigErr0   = 66,
> +  SigErr1   = 67,
> +  SigCa00   = 68,    // First instantiation of the CA bus for a given channel
> +  SigCa01   = 69,
> +  SigCa02   = 70,
> +  SigCa03   = 71,
> +  SigCa04   = 72,
> +  SigCa05   = 73,
> +  SigCa10   = 74,    // Second instantiation of the CA bus for a given channel
> +  SigCa11   = 75,
> +  SigCa12   = 76,
> +  SigCa13   = 77,
> +  SigCa14   = 78,
> +  SigCa15   = 79,
> +  GsmCsnMax,
> +  GsmCsnDelim = INT32_MAX
> +} GSM_CSN;
> +
> +
> +#endif // _MrcCommonTypes_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> new file mode 100644
> index 0000000000..635906cc2b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcInterface.h
> @@ -0,0 +1,1567 @@
> +/** @file
> +  This file includes all the data structures that the MRC considers "global
> data".
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcInterface_h_
> +#define _MrcInterface_h_
> +
> +#define MAX_CPU_SOCKETS          (1)       ///< The maximum number of
> CPUs per system.
> +#define MAX_CONTROLLERS          (1)       ///< The maximum number of
> memory controllers per CPU socket.
> +#define MAX_CHANNEL              (2)       ///< The maximum number of
> channels per memory controller.
> +#define MAX_DIMMS_IN_CHANNEL     (2)       ///< The maximum number of
> DIMMs per channel.
> +#define MAX_RANK_IN_DIMM         (2)       ///< The maximum number of
> ranks per DIMM.
> +#define MAX_RANK_IN_CHANNEL      (MAX_DIMMS_IN_CHANNEL *
> MAX_RANK_IN_DIMM) ///< The maximum number of ranks per channel.
> +#define MAX_SDRAM_IN_DIMM        (9)       ///< The maximum number of
> SDRAMs per DIMM when ECC is enabled.
> +#define MAX_MR_IN_DIMM           (7)       ///< Maximum number of mode
> registers in a DIMM.
> +#define MAX_DEVICES_IN_DDR4      (8)       ///< The maximum number of
> SDRAMs per DDR4 DIMM.
> +#define MAX_BITS                 (8)       ///< BITS per byte.
> +#define MAX_STROBE               (18)      ///< Number of strobe groups.
> +#define MAX_DQ                   (72)      ///< Number of Dq bits used by the
> rank.
> +#define CHAR_BITS                (8)       ///< Number of bits in a char.
> +#define PSMI_SIZE_MB             (64)      ///< Define the max size of PSMI
> needed in MB
> +#define BCLK_DEFAULT             (100 * 1000 * 1000) ///< BCLK default value,
> in Hertz.
> +#define MAX_COMMAND_GROUPS       (2)
> +#define MAX_EDGES                (2) ///< Maximum number of edges.
> +#define SUPPORT_DDR3             SUPPORT   ///< SUPPORT means that DDR3
> is supported by the MRC.
> +#define ULT_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that
> LPDDR3 is supported by the MRC.
> +#define TRAD_SUPPORT_LPDDR3      /*UN*/SUPPORT ///< SUPPORT means
> that LPDDR3 is supported by the MRC.
> +#define BDW_SUPPORT_LPDDR3       SUPPORT   ///< SUPPORT means that
> LPDDR3 is supported by the MRC.
> +#define JEDEC_SUPPORT_LPDDR      SUPPORT   ///< SUPPORT means that
> JEDEC SPD Spec for LPDDR3 is supported by the MRC.
> +#define SUPPORT_DDR4             SUPPORT   ///< SUPPORT means that DDR4
> is supported by the MRC.
> +#define SUPPORT_LPDDR3           (ULT_SUPPORT_LPDDR3 ||
> TRAD_SUPPORT_LPDDR3 || BDW_SUPPORT_LPDDR3 ||
> JEDEC_SUPPORT_LPDDR)
> +#define MRC_ALL_DDR_SUPPORTED    ((SUPPORT_DDR4 == SUPPORT) &&
> ((SUPPORT_DDR3 == SUPPORT) && (SUPPORT_LPDDR3 == SUPPORT)))
> +#define MRC_DDR3_LPDDR_SUPPORTED ((SUPPORT_DDR3 == SUPPORT) ||
> (SUPPORT_LPDDR3 == SUPPORT))
> +#define SPD3_MANUF_START       117         ///< The starting point for the
> SPD manufacturing data.
> +#define SPD3_MANUF_END         127         ///< The ending point for the
> SPD manufacturing data.
> +#if (SUPPORT_DDR4 == SUPPORT)
> +#define SPD4_MANUF_START       320         ///< The starting point for the
> SPD manufacturing data.
> +#define SPD4_MANUF_END         328         ///< The ending point for the
> SPD manufacturing data.
> +#endif
> +#if (JEDEC_SUPPORT_LPDDR == SUPPORT)
> +#define SPDLP_MANUF_START      320         ///< The starting point for the
> SPD manufacturing data.
> +#define SPDLP_MANUF_END        328         ///< The ending point for the
> SPD manufacturing data.
> +#endif
> +#include "MrcSpdData.h"
> +#include "MrcRmtData.h"
> +#include "MrcCommonTypes.h"
> +#pragma pack (push, 1)
> +
> +
> +///
> +//////////////////////////////////////////////////////////////////////////////
> ////////
> +///                           OEM platform  routines and types                      //
> +//////////////////////////////////////////////////////////////////////////////
> ////////
> +///
> +/// define the oem check points the OEM can define more point and locate
> them in the code.
> +///
> +typedef enum {
> +  OemFastBootPermitted,     ///<  before fast boot.
> +  OemRestoreNonTraining,
> +  OemPrintInputParameters,  ///<  before printing input parameters
> +  OemSpdProcessingRun,      ///<  before spd processing code
> +  OemSetOverridePreSpd,     ///<  before set overrides pre spd
> +  OemSetOverride,           ///<  before set overrides
> +  OemMcCapability,          ///<  before MC capability
> +  OemMcInitRun,             ///<  before mc init code
> +  OemMcMemoryMap,           ///<  before memory map
> +  OemMcResetRun,            ///<  before jedec reset
> +  OemPreTraining,           ///<  before the training.
> +  OemMcTrainingRun,         ///<  before training code
> +  OemEarlyCommandTraining,  ///<  before Early Command training
> +  OemJedecInitLpddr3,       ///<  before Jedec Init Lpddr3
> +  OemSenseAmpTraining,      ///<  before Sense Amp Training
> +  OemReadMprTraining,       ///<  before Read MPR Training
> +  OemReceiveEnable,         ///<  before Read Leveling
> +  OemJedecWriteLeveling,    ///<  before Jedec Write Leveling
> +  OemLpddrLatencySetB,      ///<  before LPDDR Latency Set B
> +  OemWriteDqDqs,            ///<  before Write Timing Centering
> +  OemWriteVoltage,          ///<  before Write Voltage Centering
> +  OemEarlyWriteDqDqs2D,     ///<  before Early Write Timing Centering 2D
> +  OemEarlyWrDsEq,           ///<  before Early Write Drive Strength /
> Equalization
> +  OemEarlyReadDqDqs2D,      ///<  before Early Read Timing Centering 2D
> +  OemEarlyReadMprDqDqs2D,   ///<  before Early MPR Read Timing
> Centering 2D
> +  OemReadDqDqs,             ///<  before Read Timing Centering
> +  OemDdr4Map,               ///<  before DDR4 PDA Mapping
> +  OemDimmRonTraining,       ///<  before DIMM Ron Training
> +  OemDimmODTTraining,       ///<  before DIMM ODT Training
> +  OemWriteDriveStrengthEq,  ///<  before Write Drive Strength/Equalization
> 2D Training
> +  OemWriteDriveUpDn,        ///<  before Write Drive Strength Up/Dn 2D
> Training
> +  OemWriteSlewRate,         ///<  before Write Slew Rate Training
> +  OemReadODTTraining,       ///<  before Read ODT algorithm.
> +  OemReadEQTraining,        ///<  before Read Equalization Training
> +  OemReadAmplifierPower,    ///<  before Read Amplifier Power
> +  OemOptimizeComp,          ///<  before Comp Optimization Training
> +  OemPowerSavingMeter,      ///<  before PowerSavingMeter step
> +  OemWriteDqDqs2D,          ///<  before Write Timing Centering 2D
> +  OemReadDqDqs2D,           ///<  before Read Timing Centering 2D
> +  OemCmdVoltCenterPreLct,   ///<  before Command Voltage Centering that
> runs pre-LCT
> +  OemCmdSlewRate,           ///<  before CMD Slew Rate
> +  OemCmdVoltCentering,      ///<  before Command Voltage Centering
> +  OemCmdDriveStrengthEq,    ///<  before Command Drive Strength
> Equalization
> +  OemWriteVoltCentering2D,  ///<  before Write Voltage Centering 2D
> +  OemReadVoltCentering2D,   ///<  before Read Voltage Centering 2D
> +  OemLateCommandTraining,   ///<  before Late Command training
> +  OemCmdNormalization,      ///<  before CMD Normalization
> +  OemRoundTripLatency,      ///<  before Round Trip Latency Traiing
> +  OemTurnAroundTimes,       ///<  before Turn Aorund Times.
> +  OemRcvEnCentering1D,      ///<  before Receive Enable Centring
> +  OemSaveMCValues,          ///<  before saving memory controller values
> +  OemRmt,                   ///<  before RMT crosser tool.
> +  OemMemTest,               ///<  before Memory testing
> +  OemRestoreTraining,       ///<  before Restoring Training Values
> +  OemJedecResetDdr4Fast,    ///<  before JEDEC reset for DDR4 in Fast flow
> +  OemSelfRefreshExit,       ///<  before Self Refresh Exit
> +  OemNormalMode,            ///<  before Normal Mode on non-cold boots.
> +  OemThermalConfig,         ///<  set Thermal config values.
> +  OemTxtAliasCheck,         ///<  before TxT Alias Check Call.
> +  OemAliasCheck,            ///<  before alias checking on cold boots.
> +  OemHwMemInit,
> +
> +  OemPostTraining,          ///<  after the training.
> +  OemForceOltm,             ///<  before MrcForceOltm
> +  OemMrcActivate,           ///<  before MrcActivate call.
> +  OemMrcRhPrevention,       ///<  before MrcRhPrevention
> +  OemSaGvSwitch,            ///<  before SA GV switch
> +  OemEngPerfGain,           ///<  before Energy Performance Gain.
> +  OemMrcDone,               ///<  call to MrcOemCheckPoint when MRC was
> done.
> +  OemFrequencySet,          ///<  do operation before frequency set.
> +  OemFrequencySetDone,      ///<  do operation after frequency set.
> +  OemStartMemoryConfiguration,
> +  OemBeforeNormalMode,      ///<  call to MrcOemCheckPoint before
> normal mode is enalbed
> +  OemAfterNormalMode,       ///<  call to MrcOemCheckPoint after normal
> mode is enalbed
> +  OemMrcFillBdat,
> +  OemRetrainMarginCheck,
> +  OemRmtPerBit,             ///< before Rank Margin Tool Per-Bit.
> +  OemUpdateSaveMCValues,    ///< before Updating memory controller
> values.
> +  ///
> +
> ///*************************************************************
> ********************
> +  ///
> +  OemNumOfCommands          ///<  Should always be last in the list!
> +} MrcOemStatusCommand;
> +
> +typedef UINT8 MrcIteration; ///< Mrc invocation sequence number, start with
> 0 and increment by one each time MRC library is called.
> +#define MRC_ITERATION_MAX ((1 << ((sizeof (MrcIteration) * 8) - 1)) + ((1 <<
> ((sizeof (MrcIteration) * 8) - 1)) - 1))
> +
> +#define MAX_RCOMP         (3)
> +#define MAX_RCOMP_TARGETS (5)
> +
> +///
> +/// Thermal Options
> +///
> +typedef struct {
> +  UINT8  RaplLim2WindX;                                    ///< Offset 110  - Power
> Limit 2 Time Window X value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> +  UINT8  RaplLim2WindY;                                    ///< Offset 111  - Power
> Limit 2 Time Window Y value: 0=Minimal, 3=Maximum, <b>1=Default</b>
> +  UINT8  RaplLim1WindX;                                    ///< Offset 112  - Power
> Limit 1 Time Window X value: <b>0=Minimal</b>, 3=Maximum
> +  UINT8  RaplLim1WindY;                                    ///< Offset 113  - Power
> Limit 1 Time Window Y value: <b>0=Minimal</b>, 31=Maximum
> +  UINT16 RaplLim2Pwr;                                      ///< Offset 114  - Power
> Limit 2: 0=Minimal, 16383=Maximum, <b>222=Default</b>
> +  UINT16 RaplLim1Pwr;                                      ///< Offset 116  - Power
> Limit 1: <b>0=Minimal</b>, 16383=Maximum
> +  UINT8  WarmThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL]; ///<
> Offset 118  - Warm Threshold (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  HotThreshold[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];  ///<
> Offset 122  - Hot Threshold (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  WarmBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];    ///<
> Offset 126  - Warm Budget (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  HotBudget[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];     ///<
> Offset 130  - Hot Budget (Channel 0, Dimm 0): 0=Minimal,
> <b>255=Maximum</b>
> +  UINT8  IdleEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  PdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  ActEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  RdEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +  UINT8  WrEnergy[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> +} ThermalMngmtEn;
> +
> +
> +typedef struct {
> +  UINT8      GdxcEnable;   ///< GDXC  MOT enable
> +  UINT8      GdxcIotSize;  ///< IOT size in multiples of 8MEG
> +  UINT8      GdxcMotSize;  ///< MOT size in multiples of 8MEG
> +} MrcGdxc;
> +
> +typedef struct {
> +  UINT32 ECT : 1;        ///< BIT0 - Early Command Training
> +  UINT32 SOT : 1;        ///< BIT1 - Sense Amp Offset Training
> +  UINT32 ERDMPRTC2D : 1; ///< BIT2 - Early ReadMPR Timing Centering 2D
> +  UINT32 RDMPRT : 1;     ///< BIT3 - Read MPR Training
> +  UINT32 RCVET : 1;      ///< BIT4 - Read Leveling Training (RcvEn)
> +  UINT32 JWRL : 1;       ///< BIT5 - Jedec Write Leveling
> +  UINT32 EWRTC2D : 1;    ///< BIT6 - Early Write Time Centering 2D
> +  UINT32 ERDTC2D : 1;    ///< BIT7  - Early Read Time Centering 2D
> +  UINT32 WRTC1D : 1;     ///< BIT8 - Write Timing Centering 1D
> +  UINT32 WRVC1D : 1;     ///< BIT9 - Write Voltage Centering 1D
> +  UINT32 RDTC1D : 1;     ///< BIT10 - Read Timing Centering 1D
> +  UINT32 DIMMODTT : 1;   ///< BIT11 - Dimm ODT Training
> +  UINT32 DIMMRONT : 1;   ///< BIT12 - Dimm Ron Training
> +  UINT32 WRDSEQT : 1;    ///< BIT13 - Write Drive Strength / Equalization
> Training 2D
> +  UINT32 WRSRT : 1;      ///< BIT14 - Write Slew Rate Training
> +  UINT32 RDODTT : 1;     ///< BIT15 - Read ODT Training
> +  UINT32 RDEQT : 1;      ///< BIT16 - Read Equalization Training
> +  UINT32 RDAPT : 1;      ///< BIT17 - Read Amplifier Power Training
> +  UINT32 WRTC2D : 1;     ///< BIT18 - Write Timing Centering 2D
> +  UINT32 RDTC2D : 1;     ///< BIT19 - Read Timing Centering 2D
> +  UINT32 WRVC2D : 1;     ///< BIT20 - Write Voltage Centering 2D
> +  UINT32 RDVC2D : 1;     ///< BIT21 - Read Voltage Centering 2D
> +  UINT32 CMDVC : 1;      ///< BIT22 - Command Voltage Centering
> +  UINT32 LCT : 1;        ///< BIT23 - Late Command Training
> +  UINT32 RTL : 1;        ///< BIT24 - Round Trip latency
> +  UINT32 TAT : 1;        ///< BIT25 - Turn Around Timing
> +  UINT32 RMT : 1;        ///< BIT26 - RMT Tool
> +  UINT32 MEMTST : 1;     ///< BIT27 - Memory Test
> +  UINT32 ALIASCHK: 1;    ///< BIT28 - SPD Alias Check
> +  UINT32 RCVENC1D: 1;    ///< BIT29 - Receive Enable Centering 1D
> +  UINT32 RMC : 1;        ///< BIT30 - Retrain Margin Check
> +  UINT32 WRDSUDT : 1;    ///< BIT31 - Write Drive Strength Up/Dn
> independently
> +} TrainingStepsEn;
> +
> +typedef struct {
> +  UINT32 CMDSR    : 1;   ///< BIT0  - CMD Slew Rate Training
> +  UINT32 CMDDSEQ  : 1;   ///< BIT1  - CMD Drive Strength and Tx Equalization
> +  UINT32 CMDNORM  : 1;   ///< BIT2  - CMD Normalization
> +  UINT32 EWRDSEQ  : 1;   ///< BIT3  - Early DQ Write Drive Strength and
> Equalization Training
> +  UINT32 TeRsv4   : 1;   ///< BIT4 - Reserved
> +  UINT32 TeRsv5   : 1;   ///< BIT5 - Reserved
> +  UINT32 TeRsv6   : 1;   ///< BIT6 - Reserved
> +  UINT32 RsvdBits :25;
> +} TrainingStepsEn2;
> +
> +///
> +/// Defines whether the MRC is executing in full or mini BIOS mode.
> +///
> +typedef enum {
> +  MrcModeFull,   ///< Select full BIOS MRC execution.
> +  MrcModeMini,   ///< Select mini BIOS MRC execution.
> +  MrcModeMaximum ///< Delimiter.
> +} MrcMode;
> +
> +typedef enum {
> +  MrcTmPower,
> +  MrcTmMargin,
> +  MrcTmMax
> +} TrainingModeType;
> +
> +typedef enum {
> +  LastRxV,
> +  LastRxT,
> +  LastTxV,
> +  LastTxT,
> +  LastRcvEna,
> +  LastWrLevel,
> +  LastCmdT,
> +  LastCmdV,
> +  MAX_RESULT_TYPE
> +} MrcMarginResult;
> +
> +typedef enum {
> +  MSG_LEVEL_NEVER,
> +  MSG_LEVEL_ERROR,
> +  MSG_LEVEL_WARNING,
> +  MSG_LEVEL_NOTE,
> +  MSG_LEVEL_EVENT,
> +  MSG_LEVEL_ALGO,
> +  MSG_LEVEL_MMIO,
> +  MSG_LEVEL_CSV,
> +  MSG_LEVEL_TIME,
> +  MSG_LEVEL_ALL = MRC_INT32_MAX
> +} MrcDebugMsgLevel;
> +
> +///
> +/// Define the frequencies that may be possible in the memory controller.
> +/// Note that not all these values may be supported.
> +///
> +#define fNoInit     (0)
> +#define f800        (800)
> +#define f1000       (1000)
> +#define f1100       (1100)
> +#define f1067       (1067)
> +#define f1200       (1200)
> +#define f1300       (1300)
> +#define f1333       (1333)
> +#define f1400       (1400)
> +#define f1467       (1467)
> +#define f1500       (1500)
> +#define f1600       (1600)
> +#define f1700       (1700)
> +#define f1733       (1733)
> +#define f1800       (1800)
> +#define f1867       (1867)
> +#define f1900       (1900)
> +#define f2000       (2000)
> +#define f2100       (2100)
> +#define f2133       (2133)
> +#define f2200       (2200)
> +#define f2267       (2267)
> +#define f2300       (2300)
> +#define f2400       (2400)
> +#define f2500       (2500)
> +#define f2533       (2533)
> +#define f2600       (2600)
> +#define f2667       (2667)
> +#define f2700       (2700)
> +#define f2800       (2800)
> +#define f2900       (2900)
> +#define f2933       (2933)
> +#define f3000       (3000)
> +#define f3067       (3067)
> +#define f3100       (3100)
> +#define f3200       (3200)
> +#define f3333       (3333)
> +#define f3467       (3467)
> +#define f3600       (3600)
> +#define f3733       (3733)
> +#define f3867       (3867)
> +#define f4000       (4000)
> +#define f4133       (4133)
> +#define fInvalid    (0x7FFFFFFF)
> +typedef UINT32 MrcFrequency;
> +
> +//
> +// Max supported frequency in OC mode
> +// RefClk133: 15*266 + 100 = 4133 (using Odd ratio mode)
> +// RefClk100: 15*200 + 100 = 3100 (using Odd ratio mode)
> +//
> +#define MAX_FREQ_OC_133   f4133
> +#define MAX_FREQ_OC_100   f3100
> +
> +//
> +// tCK value in femtoseconds for various frequencies
> +// If Freq is in MHz, then tCK[fs] = 10^9 * 1/(Freq/2)
> +//
> +#define MRC_DDR_800_TCK_MIN      2500000
> +#define MRC_DDR_1000_TCK_MIN     2000000
> +#define MRC_DDR_1067_TCK_MIN     1875000
> +#define MRC_DDR_1100_TCK_MIN     1818182
> +#define MRC_DDR_1200_TCK_MIN     1666667
> +#define MRC_DDR_1300_TCK_MIN     1538462
> +#define MRC_DDR_1333_TCK_MIN     1500000
> +#define MRC_DDR_1400_TCK_MIN     1428571
> +#define MRC_DDR_1467_TCK_MIN     1363636
> +#define MRC_DDR_1500_TCK_MIN     1333333
> +#define MRC_DDR_1600_TCK_MIN     1250000
> +#define MRC_DDR_1700_TCK_MIN     1176471
> +#define MRC_DDR_1733_TCK_MIN     1153846
> +#define MRC_DDR_1800_TCK_MIN     1111111
> +#define MRC_DDR_1867_TCK_MIN     1071429
> +#define MRC_DDR_1900_TCK_MIN     1052632
> +#define MRC_DDR_2000_TCK_MIN     1000000
> +#define MRC_DDR_2100_TCK_MIN     952381
> +#define MRC_DDR_2133_TCK_MIN     938000
> +#define MRC_DDR_2200_TCK_MIN     909091
> +#define MRC_DDR_2267_TCK_MIN     882353
> +#define MRC_DDR_2300_TCK_MIN     869565
> +#define MRC_DDR_2400_TCK_MIN     833333
> +#define MRC_DDR_2500_TCK_MIN     800000
> +#define MRC_DDR_2533_TCK_MIN     789474
> +#define MRC_DDR_2600_TCK_MIN     769231
> +#define MRC_DDR_2667_TCK_MIN     750000
> +#define MRC_DDR_2700_TCK_MIN     740741
> +#define MRC_DDR_2800_TCK_MIN     714286
> +#define MRC_DDR_2900_TCK_MIN     689655
> +#define MRC_DDR_2933_TCK_MIN     681818
> +#define MRC_DDR_3000_TCK_MIN     666667
> +#define MRC_DDR_3067_TCK_MIN     652174
> +#define MRC_DDR_3100_TCK_MIN     645161
> +#define MRC_DDR_3200_TCK_MIN     625000
> +#define MRC_DDR_3333_TCK_MIN     600000
> +#define MRC_DDR_3467_TCK_MIN     576923
> +#define MRC_DDR_3600_TCK_MIN     555556
> +#define MRC_DDR_3733_TCK_MIN     535714
> +#define MRC_DDR_3867_TCK_MIN     517241
> +#define MRC_DDR_4000_TCK_MIN     500000
> +#define MRC_DDR_4133_TCK_MIN     483871
> +
> +///
> +/// Define the memory nominal voltage (VDD).
> +/// Note that not all these values may be supported.
> +///
> +typedef enum {
> +  VDD_INVALID,
> +  VDD_1_00    = 1000,
> +  VDD_1_05    = 1050,
> +  VDD_1_10    = 1100,
> +  VDD_1_15    = 1150,
> +  VDD_1_20    = 1200,
> +  VDD_1_25    = 1250,
> +  VDD_1_30    = 1300,
> +  VDD_1_35    = 1350,
> +  VDD_1_40    = 1400,
> +  VDD_1_45    = 1450,
> +  VDD_1_50    = 1500,
> +  VDD_1_55    = 1550,
> +  VDD_1_60    = 1600,
> +  VDD_1_65    = 1650,
> +  VDD_1_70    = 1700,
> +  VDD_1_75    = 1750,
> +  VDD_1_80    = 1800,
> +  VDD_1_85    = 1850,
> +  VDD_1_90    = 1900,
> +  VDD_1_95    = 1950,
> +  VDD_2_00    = 2000,
> +  VDD_2_05    = 2050,
> +  VDD_2_10    = 2100,
> +  VDD_2_15    = 2150,
> +  VDD_2_20    = 2200,
> +  VDD_2_25    = 2250,
> +  VDD_2_30    = 2300,
> +  VDD_2_35    = 2350,
> +  VDD_2_40    = 2400,
> +  VDD_2_45    = 2450,
> +  VDD_2_50    = 2500,
> +  VDD_2_55    = 2550,
> +  VDD_2_60    = 2600,
> +  VDD_2_65    = 2650,
> +  VDD_2_70    = 2700,
> +  VDD_2_75    = 2750,
> +  VDD_2_80    = 2800,
> +  VDD_2_85    = 2850,
> +  VDD_2_90    = 2900,
> +  VDD_2_95    = 2950,
> +  VDD_MAXIMUM = 0x7FFFFFFF
> +} MrcVddSelect;
> +
> +///
> +/// SA GV points
> +///
> +typedef enum {
> +  MrcSaGvPointLow,
> +  MrcSaGvPointHigh,
> +} MrcSaGvPoint;
> +
> +///
> +/// SA GV modes
> +///  Disabled:  SA GV Disabled, run all MRC tasks
> +///  FixedLow:  SA GV Disabled, run only MRC tasks marked with
> MRC_PF_GV_LOW
> +///  FixedHigh: SA GV Disabled, run only MRC tasks marked with
> MRC_PF_GV_HIGH
> +///  Enabled:   SA GV Enabled
> +///
> +typedef enum {
> +  MrcSaGvDisabled,
> +  MrcSaGvFixedLow,
> +  MrcSaGvFixedHigh,
> +  MrcSaGvEnabled,
> +} MrcSaGv;
> +
> +///
> +/// DIMM SPD Security Status
> +///
> +typedef enum {
> +  MrcSpdStatusGood,      ///< Memory is in a secure state.
> +  MrcSpdStatusAliased,   ///< Memory is aliased.
> +  MrcSpdStatusLast       ///< Must be last in the list
> +} MrcSpdStatus;
> +
> +///
> +/// Define the virtual channel.
> +///
> +typedef enum {
> +  vcL,  ///< Virtual channel L
> +  vcS,  ///< Virtual channel S
> +} MrcVirtualChannel;
> +
> +///
> +/// Define the board types.
> +///
> +typedef enum {
> +  btCRBMB,    ///< 0 - CRB Mobile
> +  btCRBDT,    ///< 1 - CRB Desktop
> +  btUser1,    ///< 2 - SV Karkom
> +  btUser2,    ///< 3 - SV desktop
> +  btUser3,    ///< 4 - SV miniDVP
> +  btUser4,    ///< 5 - Ult
> +  btCRBEMB,   ///< 6 - CRB Embedded
> +  btUpServer, ///< 7 - Up Server
> +  btUnknown,  ///< 8 - Unknown
> +  btMaximum   ///< Delimiter
> +} MrcBoardType;
> +
> +///
> +/// Define the CPU family/model.
> +///
> +typedef enum {
> +  cmCFL_ULX_ULT   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
> ///< Coffeelake ULT/ULX
> +  cmCFL_DT_HALO   = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO
> ///< Coffeelake DT/Halo
> +} MrcCpuModel;
> +
> +///
> +/// Define the CPU Tick/Tock.
> +///
> +typedef enum {
> +  cfCfl    = 0,  ///< Coffeelake
> +  cfMax
> +} MrcCpuFamily;
> +
> +///
> +/// Define the CPU stepping number.
> +///
> +typedef enum {
> +  ///
> +  /// Coffeelake ULX/ULT
> +  ///
> +  csKblH0         = EnumKblH0,
> +  csCflD0         = EnumCflD0,
> +  csCflW0         = EnumCflW0,
> +  csCflV0         = EnumCflV0,
> +  csCflUlxUltLast = csCflV0,
> +
> +  ///
> +  /// Coffeelake DT/Halo
> +  ///
> +  csCflU0         = EnumCflU0,
> +  csCflB0         = EnumCflB0,
> +  csCflP0         = EnumCflP0,
> +  csCflR0         = EnumCflR0,
> +  csCflDtHaloLast = csCflR0,
> +} MrcCpuStepping;
> +
> +typedef enum {
> +  CONTROLLER_NOT_PRESENT, ///< There is no controller present in the
> system.
> +  CONTROLLER_DISABLED,    ///< There is a controller present but it is
> disabled.
> +  CONTROLLER_PRESENT,     ///< There is a controller present and it is
> enabled.
> +  MAX_CONTROLLER_STATUS   ///< Delimiter
> +} MrcControllerSts;
> +
> +typedef enum {
> +  CHANNEL_NOT_PRESENT,    ///< There is no channel present on the
> controller.
> +  CHANNEL_DISABLED,       ///< There is a channel present but it is disabled.
> +  CHANNEL_PRESENT,        ///< There is a channel present and it is enabled.
> +  MAX_CHANNEL_STATUS      ///< Delimiter
> +} MrcChannelSts;
> +
> +typedef enum {
> +  DIMM_ENABLED,           ///< DIMM/rank Pair is enabled, presence will be
> detected.
> +  DIMM_DISABLED,          ///< DIMM/rank Pair is disabled, regardless of
> presence.
> +  DIMM_PRESENT,           ///< There is a DIMM present in the slot/rank pair
> and it will be used.
> +  DIMM_NOT_PRESENT,       ///< There is no DIMM present in the slot/rank
> pair.
> +  MAX_DIMM_STATUS         ///< Delimiter
> +} MrcDimmSts;
> +
> +typedef enum {
> +  STD_PROFILE,            ///< Standard DIMM profile select.
> +  USER_PROFILE,           ///< User specifies various override values.
> +  XMP_PROFILE1,           ///< XMP enthusiast settings select (XMP profile #1).
> +  XMP_PROFILE2,           ///< XMP extreme settings select (XMP profile #2).
> +  MAX_PROFILE             ///< Delimiter
> +} MrcProfile;
> +
> +#define XMP_PROFILES_ENABLE   (0x3)
> +#define XMP1_PROFILE_ENABLE   (0x1)
> +#define XMP2_PROFILE_ENABLE   (0x2)
> +
> +typedef enum {
> +  MRC_REF_CLOCK_133,      ///< 133MHz reference clock
> +  MRC_REF_CLOCK_100,      ///< 100MHz reference clock
> +  MRC_REF_CLOCK_MAXIMUM   ///< Delimiter
> +} MrcRefClkSelect;        ///< This value times the MrcClockRatio determines
> the MrcFrequency.
> +
> +typedef enum {
> +  MRC_FREQ_INVALID       = 0,
> +  MRC_FREQ_133           = (MRC_BIT0 << MRC_REF_CLOCK_133), // Bit 0
> +  MRC_FREQ_100           = (MRC_BIT0 << MRC_REF_CLOCK_100), // Bit 1
> +  MRC_FREQ_133_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_133), // Bit
> 2
> +  MRC_FREQ_100_ODD_RATIO = (MRC_BIT2 << MRC_REF_CLOCK_100), // Bit
> 3
> +  MRC_FREQ_MAX                                              // Delimiter
> +} MrcFreqFlag;
> +
> +typedef UINT32 MrcBClkRef;   ///< Base clock, in Hertz, Default is 100MHz or
> leave at zero for default.
> +
> +//
> +// This encoding matches CFL SC_GS_CFG.DRAM_technology and
> MAD_INTER_CHANNEL.DDR_TYPE registers
> +//
> +typedef enum {
> +  MRC_DDR_TYPE_DDR4     = 0,
> +  MRC_DDR_TYPE_DDR3     = 1,
> +  MRC_DDR_TYPE_LPDDR3   = 2,
> +  MRC_DDR_TYPE_UNKNOWN  = 3,
> +  MAX_MRC_DDR_TYPE        ///< Delimiter
> +} MrcDdrType;
> +
> +typedef enum {
> +  MrcIterationClock,
> +  MrcIterationCmdN,
> +  MrcIterationCmdS,
> +  MrcIterationCke,
> +  MrcIterationCtl,
> +  MrcIterationCmdV,
> +  MrcIterationMax
> +} MrcIterationType;
> +
> +typedef enum {
> +  UpmLimit,
> +  PowerLimit,
> +  RetrainLimit,
> +  MarginLimitMax
> +} MRC_MARGIN_LIMIT_TYPE;
> +
> +
> +typedef enum {
> +  HardwareRhp,
> +  Refresh2x
> +} MrcRhpType;
> +
> +typedef enum {
> +  OneIn2To1 = 1,
> +  OneIn2To2,
> +  OneIn2To3,
> +  OneIn2To4,
> +  OneIn2To5,
> +  OneIn2To6,
> +  OneIn2To7,
> +  OneIn2To8,
> +  OneIn2To9,
> +  OneIn2To10,
> +  OneIn2To11,
> +  OneIn2To12,
> +  OneIn2To13,
> +  OneIn2To14,
> +  OneIn2To15
> +} MrcRhProbType;
> +
> +typedef enum {
> +  MRC_POST_CODE,
> +  MRC_POST_CODE_WRITE,
> +  MRC_POST_CODE_READ,
> +  MRC_POST_CODE_MAX
> +} MrcDebugPostCode;
> +
> +typedef struct {
> +  UINT32 MrcData;
> +  UINT32 Stream;
> +  UINT32 Start;
> +  UINT32 End;
> +  UINT32 Current;
> +  int Level;
> +  UINT16 PostCode[MRC_POST_CODE_MAX];
> +  UINT32 TopStackAddr;     ///< Initial stack address.
> +  UINT32 LowestStackAddr;  ///< Track the lowest stack address used through
> MrcPrintfVaList()
> +} MrcDebug;
> +
> +typedef UINT16 MrcPostCode;
> +typedef UINT8  MrcClockRatio;  ///< This value times the MrcRefClkSelect
> determines the MrcFrequency.
> +typedef UINT32 MrcGfxDataSize; ///< The size of the stolen graphics data
> memory, in MBytes.
> +typedef UINT32 MrcGfxGttSize;  ///< The size of the graphics translation
> table, in MBytes.
> +
> +
> +///
> +/// This data structure contains all the "DDR power saving data" values that
> are considered output by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> +  BOOLEAN    BaseFlag;      ///< Indicates if the base line of power was
> already calculated.
> +  UINT16     BaseSavingRd;  ///< Indicates the base line of power consume by
> the ddr on read.
> +  UINT16     BaseSavingWr;  ///< Indicates the base line of power consume
> by the ddr on write.
> +  UINT16     BaseSavingCmd; ///< Indicates the base line of power consume
> by the ddr on command.
> +  UINT16     MrcSavingRd;   ///< Indicates the power consume by the ddr on
> read at the end of MRC.
> +  UINT16     MrcSavingWr;   ///< Indicates the power consume by the ddr on
> write at the end of MRC.
> +  UINT16     MrcSavingCmd;  ///< Indicates the power consume by the ddr on
> command at the end of MRC.
> +} MrcOdtPowerSaving;
> +
> +///
> +/// The memory controller capabilities.
> +///
> +typedef union {
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} MrcCapabilityIdA;
> +
> +typedef union {
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} MrcCapabilityIdB;
> +
> +typedef union {
> +  UINT64 Data;
> +  struct {
> +    MrcCapabilityIdA A;
> +    MrcCapabilityIdB B;
> +  } Data32;
> +} MrcCapabilityId;
> +
> +///
> +/// MRC version description.
> +///
> +typedef struct {
> +  UINT8  Major;  ///< Major version number
> +  UINT8  Minor;  ///< Minor version number
> +  UINT8  Rev;    ///< Revision number
> +  UINT8  Build;  ///< Build number
> +} MrcVersion;
> +
> +///
> +/// Memory map configuration information.
> +///
> +typedef struct {
> +  UINT32     TomMinusMe;
> +  UINT32     ToludBase;
> +  UINT32     BdsmBase;
> +  UINT32     GttBase;
> +  UINT32     GraphicsControlRegister;
> +  UINT32     TsegBase;
> +  BOOLEAN    ReclaimEnable;
> +  UINT32     RemapBase;
> +  UINT32     RemapLimit;
> +  UINT32     TouudBase;
> +  UINT32     TotalPhysicalMemorySize;
> +  UINT32     MeStolenBase;
> +  UINT32     MeStolenSize;
> +  UINT32     GdxcMotBase;
> +  UINT32     GdxcMotSize;
> +  UINT32     GdxcIotBase;
> +  UINT32     GdxcIotSize;
> +  UINT32     DprSize;
> +  UINT32     PttStolenBase;
> +  UINT32     PrmrrBase;
> +  UINT32     LowestBase;
> +} MrcMemoryMap;
> +
> +///
> +/// Real time clock information.
> +///
> +typedef struct {
> +  UINT8  Seconds;    ///< Seconds, 0-59
> +  UINT8  Minutes;    ///< Minutes, 0-59
> +  UINT8  Hours;      ///< Hours, 0-23
> +  UINT8  DayOfMonth; ///< Day of the month, 1-31
> +  UINT8  Month;      ///< Month of the year, 1-12
> +  UINT16 Year;       ///< Year, 0-65535
> +} MrcBaseTime;
> +
> +///
> +/// 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.
> +} MrcTiming;
> +
> +typedef struct {
> +  UINT8 SG;       ///< Number of tCK cycles between transactions in the same
> bank group.
> +  UINT8 DG;       ///< Number of tCK cycles between transactions when
> switching bank groups.
> +  UINT8 DR;       ///< Number of tCK cycles between transactions when
> switching between Ranks (in the same DIMM).
> +  UINT8 DD;       ///< Number of tCK cycles between transactions when
> switching between DIMMs
> +} MrcTurnaroundTimes;
> +
> +typedef struct {
> +  INT32 Mtb;    ///< Medium time base.
> +  INT32 Ftb;    ///< Fine time base.
> +} MrcTimeBase;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the timing eye.
> +  UINT8  Center; ///< The center of the timing eye.
> +  UINT8  Right;  ///< The right side of the timing eye.
> +} MrcDqTimeMargin;
> +
> +typedef struct {
> +  UINT8  High;   ///< The high side of the Vref eye.
> +  UINT8  Center; ///< The center of the Vref eye.
> +  UINT8  Low;    ///< The low side of the Vref eye.
> +} MrcDqVrefMargin;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the command eye.
> +  UINT8  Right;  ///< The right side of the command eye.
> +  UINT8  High;   ///< The high side of the command eye.
> +  UINT8  Low;    ///< The low side of the command eye.
> +} MrcCommandMargin;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the receive enable eye.
> +  UINT8  Right;  ///< The right side of the receive enableeye.
> +} MrcRecvEnMargin;
> +
> +typedef struct {
> +  UINT8  Left;   ///< The left side of the write leveling eye.
> +  UINT8  Right;  ///< The right side of the write leveling eye.
> +} MrcWrLevelMargin;
> +
> +typedef struct {
> +  UINT8     SpdValid[sizeof (MrcSpd) / (CHAR_BITS * sizeof (UINT8))]; ///<
> Each valid bit maps to SPD byte.
> +  UINT8     MrcSpdString[3]; ///< The SPD data start marker. This must be
> located at the start of the SPD data structure. It includes this string plus the
> following flag.
> +  union {
> +    struct {
> +      UINT8   DimmNumber    : 4; ///< SPD zero based DIMM number.
> +      UINT8   ChannelNumber : 3; ///< SPD zero based channel number.
> +      UINT8   MdSocket      : 1; ///< 0 = memory down, 1 = socketed.
> +    } Bit;
> +    UINT8 Data;
> +  } Flag;
> +  MrcSpd Data;            ///< The SPD data for each DIMM. SPDGeneral field =
> 0 when absent.
> +} MrcSpdData;
> +
> +typedef UINT8        (*MRC_IO_READ_8)               (UINT32 IoAddress);
> +typedef UINT16       (*MRC_IO_READ_16)              (UINT32 IoAddress);
> +typedef UINT32       (*MRC_IO_READ_32)              (UINT32 IoAddress);
> +typedef void         (*MRC_IO_WRITE_8)              (UINT32 IoAddress, UINT8
> Value);
> +typedef void         (*MRC_IO_WRITE_16)             (UINT32 IoAddress,
> UINT16 Value);
> +typedef void         (*MRC_IO_WRITE_32)             (UINT32 IoAddress,
> UINT32 Value);
> +typedef UINT8        (*MRC_MMIO_READ_8)             (UINT32 Address);
> +typedef UINT16       (*MRC_MMIO_READ_16)            (UINT32 Address);
> +typedef UINT32       (*MRC_MMIO_READ_32)            (UINT32 Address);
> +typedef UINT64       (*MRC_MMIO_READ_64)            (UINT32 Address);
> +typedef UINT8        (*MRC_MMIO_WRITE_8)            (UINT32 Address,
> UINT8 Value);
> +typedef UINT16       (*MRC_MMIO_WRITE_16)           (UINT32 Address,
> UINT16 Value);
> +typedef UINT32       (*MRC_MMIO_WRITE_32)           (UINT32 Address,
> UINT32 Value);
> +typedef UINT64       (*MRC_MMIO_WRITE_64)           (UINT32 Address,
> UINT64 Value);
> +typedef UINT8        (*MRC_SMBUS_READ_8)            (UINT32 Address,
> UINT32 *Status);
> +typedef UINT16       (*MRC_SMBUS_READ_16)           (UINT32 Address,
> UINT32 *Status);
> +typedef UINT8        (*MRC_SMBUS_WRITE_8)           (UINT32 Address,
> UINT8 Value, UINT32 *Status);
> +typedef UINT16       (*MRC_SMBUS_WRITE_16)          (UINT32 Address,
> UINT16 Value, UINT32 *Status);
> +typedef UINT32       (*MRC_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8
> Device, UINT8 Function, UINT8 Offset);
> +typedef UINT32       (*MRC_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8
> Device, UINT8 Function, UINT8 Offset);
> +typedef void         (*MRC_GET_RTC_TIME)            (UINT8 *Second, UINT8
> *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);
> +typedef UINT64       (*MRC_GET_CPU_TIME)            (void *MrcData);
> +typedef void *       (*MRC_MEMORY_COPY)             (UINT8 *Destination,
> UINT8 *Source, UINT32 NumBytes);
> +typedef void *       (*MRC_MEMORY_SET_BYTE)         (UINT8 *Destination,
> UINT32 NumBytes, UINT8 Value);
> +typedef void *       (*MRC_MEMORY_SET_WORD)         (UINT16
> *Destination, UINT32 NumWords, UINT16 Value);
> +typedef void *       (*MRC_MEMORY_SET_DWORD)        (UINT32
> *Destination, UINT32 NumDwords, UINT32 Value);
> +typedef UINT64       (*MRC_LEFT_SHIFT_64)           (UINT64 Data, UINT32
> NumBits);
> +typedef UINT64       (*MRC_RIGHT_SHIFT_64)          (UINT64 Data, UINT32
> NumBits);
> +typedef UINT64       (*MRC_MULT_U64_U32)            (UINT64 Multiplicand,
> UINT32 Multiplier);
> +typedef UINT64       (*MRC_DIV_U64_U64)             (UINT64 Dividend,
> UINT64 Divisor, UINT64 *Remainder);
> +typedef BOOLEAN      (*MRC_GET_SPD_DATA)            (UINT8 BootMode,
> UINT8 SpdAddress, UINT8 *SpdData, UINT8 *Ddr3Table, UINT32 Ddr3TableSize,
> UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32
> LpddrTableSize);
> +typedef BOOLEAN      (*MRC_GET_RANDOM_NUMBER)       (UINT32
> *Rand);
> +typedef UINT32       (*MRC_CPU_MAILBOX_READ)        (UINT32 Type,
> UINT32 Command, UINT32 *Value, UINT32 *Status);
> +typedef UINT32       (*MRC_CPU_MAILBOX_WRITE)       (UINT32 Type,
> UINT32 Command, UINT32 Value, UINT32 *Status);
> +typedef UINT32       (*MRC_GET_MEMORY_VDD)          (void *MrcData,
> UINT32 DefaultVdd);
> +typedef UINT32       (*MRC_SET_MEMORY_VDD)          (void *MrcData,
> UINT32 DefaultVdd, UINT32 Value);
> +typedef UINT32       (*MRC_CHECKPOINT)              (void *MrcData, UINT32
> CheckPoint, void *Scratch);
> +typedef void         (*MRC_DEBUG_HOOK)              (void *GlobalData,
> UINT16 DisplayDebugNumber);
> +typedef void         (*MRC_PRINT_STRING)            (void *String);
> +typedef UINT8        (*MRC_GET_RTC_CMOS)            (UINT8 Location);
> +typedef UINT64       (*MRC_MSR_READ_64)             (UINT32 Location);
> +typedef UINT64       (*MRC_MSR_WRITE_64)            (UINT32 Location,
> UINT64 Data);
> +typedef void         (*MRC_RETURN_FROM_SMC)         (void *GlobalData,
> UINT32 MrcStatus);
> +typedef void         (*MRC_DRAM_RESET)              (UINT32
> PciEBaseAddress, UINT32 ResetValue);
> +typedef void         (*MRC_SET_LOCK_PRMRR)          (UINT32 PrmrrBase,
> UINT32 PrmrrSize);
> +typedef void         (*MRC_TXT_ACHECK)              (void);
> +
> +///
> +/// Function calls that are called external to the MRC.
> +///   This structure needs to be aligned with SA_FUNCTION_CALLS.  All
> functions that are
> +///   not apart of SA_FUNCTION_CALLS need to be at the end of the structure.
> +///
> +typedef struct {
> +  MRC_IO_READ_8               MrcIoRead8;
> +  MRC_IO_READ_16              MrcIoRead16;
> +  MRC_IO_READ_32              MrcIoRead32;
> +  MRC_IO_WRITE_8              MrcIoWrite8;
> +  MRC_IO_WRITE_16             MrcIoWrite16;
> +  MRC_IO_WRITE_32             MrcIoWrite32;
> +  MRC_MMIO_READ_8             MrcMmioRead8;
> +  MRC_MMIO_READ_16            MrcMmioRead16;
> +  MRC_MMIO_READ_32            MrcMmioRead32;
> +  MRC_MMIO_READ_64            MrcMmioRead64;
> +  MRC_MMIO_WRITE_8            MrcMmioWrite8;
> +  MRC_MMIO_WRITE_16           MrcMmioWrite16;
> +  MRC_MMIO_WRITE_32           MrcMmioWrite32;
> +  MRC_MMIO_WRITE_64           MrcMmioWrite64;
> +  MRC_SMBUS_READ_8            MrcSmbusRead8;
> +  MRC_SMBUS_READ_16           MrcSmbusRead16;
> +  MRC_SMBUS_WRITE_8           MrcSmbusWrite8;
> +  MRC_SMBUS_WRITE_16          MrcSmbusWrite16;
> +  MRC_GET_PCI_DEVICE_ADDRESS  MrcGetPciDeviceAddress;
> +  MRC_GET_PCIE_DEVICE_ADDRESS MrcGetPcieDeviceAddress;
> +  MRC_GET_RTC_TIME            MrcGetRtcTime;
> +  MRC_GET_CPU_TIME            MrcGetCpuTime;
> +  MRC_MEMORY_COPY             MrcCopyMem;
> +  MRC_MEMORY_SET_BYTE         MrcSetMem;
> +  MRC_MEMORY_SET_WORD         MrcSetMemWord;
> +  MRC_MEMORY_SET_DWORD        MrcSetMemDword;
> +  MRC_LEFT_SHIFT_64           MrcLeftShift64;
> +  MRC_RIGHT_SHIFT_64          MrcRightShift64;
> +  MRC_MULT_U64_U32            MrcMultU64x32;
> +  MRC_DIV_U64_U64             MrcDivU64x64;
> +  MRC_GET_SPD_DATA            MrcGetSpdData;
> +  MRC_GET_RANDOM_NUMBER       MrcGetRandomNumber;
> +  MRC_CPU_MAILBOX_READ        MrcCpuMailboxRead;
> +  MRC_CPU_MAILBOX_WRITE       MrcCpuMailboxWrite;
> +  MRC_GET_MEMORY_VDD          MrcGetMemoryVdd;
> +  MRC_SET_MEMORY_VDD          MrcSetMemoryVdd;
> +  MRC_CHECKPOINT              MrcCheckpoint;
> +  MRC_DEBUG_HOOK              MrcDebugHook;
> +  MRC_PRINT_STRING            MrcPrintString;
> +  MRC_GET_RTC_CMOS            MrcRtcCmos;
> +  MRC_MSR_READ_64             MrcReadMsr64;
> +  MRC_MSR_WRITE_64            MrcWriteMsr64;
> +  MRC_RETURN_FROM_SMC         MrcReturnFromSmc;
> +  MRC_DRAM_RESET              MrcDramReset;
> +  MRC_SET_LOCK_PRMRR          MrcSetLockPrmrr;
> +  MRC_TXT_ACHECK              MrcTxtAcheck;
> +} MRC_FUNCTION;
> +
> +///
> +///*****************************************
> +/// Output related "global data" structures.
> +///*****************************************
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are SDRAM level definitions. All ranks on a rank are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +} MrcSdramOut;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are rank level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +//MrcSdramOut     Sdram[MAX_SDRAM_IN_DIMM];         ///< The
> following are SDRAM level definitions.
> +  UINT16             MR[MAX_MR_IN_DIMM];            ///< DRAM mode
> register value.
> +  UINT16             MR11;                          ///< LPDDR3 ODT MR
> +  UINT8              Ddr4PdaMr6[MAX_SDRAM_IN_DIMM]; ///< DDR4 MR6[6:0]
> for per-DRAM VrefDQ (PDA)
> +#if (SUPPORT_DDR4 == SUPPORT)
> +  UINT8              Device[MAX_SDRAM_IN_DIMM];     ///< Which Bytes are
> tied to which Device where BIT0 set means Byte 0
> +#endif //SUPPORT_DDR4
> +} MrcRankOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are DIMM level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +  MrcDimmSts     Status;                    ///< See MrcDimmSts for the
> definition of this field.
> +  MrcTiming      Timing[MAX_PROFILE];       ///< The DIMMs timing values.
> +  MrcVddSelect   VddVoltage[MAX_PROFILE];   ///< The voltage (VDD) setting
> for this DIMM, per profile.
> +  BOOLEAN        EccSupport;                ///< TRUE if ECC is enabled and
> supported on this DIMM.
> +  BOOLEAN        IgnoreNonEccDimm;          ///< TRUE if a DIMM without
> ECC capability should be ignored.
> +  BOOLEAN        AddressMirrored;           ///< TRUE if the DIMM is address
> mirrored.
> +  BOOLEAN        SelfRefreshTemp;           ///< TRUE if the DIMM supports
> self refresh extended operating temperature range (SRT).
> +  BOOLEAN        AutoSelfRefresh;           ///< TRUE if the DIMM supports
> automatic self refresh (ASR).
> +  BOOLEAN        PartialSelfRefresh;        ///< TRUE if the DIMM supports
> Partial Array Self Refresh (PASR).
> +  BOOLEAN        OnDieThermalSensor;        ///< TRUE if the DIMM supports
> On-die Thermal Sensor (ODTS) Readout.
> +  BOOLEAN        ExtendedTemperRange;       ///< TRUE if the DIMM
> supports Extended Temperature Range (ETR).
> +  BOOLEAN        ExtendedTemperRefresh;     ///< TRUE if the DIMM
> supports 1x Extended Temperature Refresh rate, FALSE = 2x.
> +  MrcDdrType     DdrType;                   ///< DDR type: DDR3 or LPDDR3
> +  MEMORY_PACKAGE ModuleType;                ///< Module type: UDIMM,
> SO-DIMM, etc.
> +  UINT32         SdramCount;                ///< The number of SDRAM
> components on a DIMM.
> +  UINT32         DimmCapacity;              ///< DIMM size in MBytes.
> +  UINT32         RowSize;                   ///< The DIMMs row address size.
> +  UINT16         ColumnSize;                ///< The DIMMs column address size.
> +  UINT16         Crc;                       ///< Calculated CRC16 of the DIMM's
> provided SPD. Can be used to detect DIMM change.
> +  UINT8          RankInDimm;                ///< The number of ranks in this
> DIMM.
> +  UINT8          Banks;                     ///< Number of banks the DIMM
> contains.
> +  UINT8          BankGroups;                ///< Number of bank groups the
> DIMM contains.
> +  UINT8          PrimaryBusWidth;           ///< DIMM primary bus width.
> +  UINT8          SdramWidth;                ///< DIMM SDRAM width.
> +  UINT8          SdramWidthIndex;           ///< DIMM SDRAM width index (0 =
> x4, 1 = x8, 2 = x16, 3 = x32).
> +  UINT8          DensityIndex;              ///< Total SDRAM capacity index (0 =
> 256Mb, 1 = 512Mb, 2 = 1Gb, etc).
> +  UINT8          tMAC;                      ///< Maximum Activate Count for pTRR.
> +  UINT8          ReferenceRawCard;          ///< Indicates which JEDEC
> reference design raw card was used as the basis for the module assembly.
> +  UINT8          ReferenceRawCardRevision;  ///< Indicates which JEDEC
> reference design raw card revision.
> +  UINT8          XmpSupport;                ///< Indicates if XMP profiles are
> supported. 0 = None, 1 = XMP1 only, 2 = XMP2 only, 3 = All.
> +  UINT8          XmpRevision;               ///< Indicates the XMP revision of this
> DIMM. 0 = None, 12h = 1.2, 13h = 1.3.
> +  MrcFrequency   Speed;                     ///< Max DIMM speed in the current
> profile - needed for SMBIOS.
> +  MrcRankOut     Rank[MAX_RANK_IN_DIMM];    ///< The following are rank
> level definitions.
> +} MrcDimmOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are channel level definitions. All DIMMs on a memory
> channel are set to these values.
> +///
> +typedef struct {
> +  MrcChannelSts       Status;                                                       ///<
> Indicates whether this channel should be used.
> +  MrcVirtualChannel   VirtualChannel;
> ///< define the virtual channel type A or B.
> +  MrcTiming           Timing[MAX_PROFILE];
> ///< The channel timing values.
> +  MrcTimeBase         TimeBase[MAX_DIMMS_IN_CHANNEL][MAX_PROFILE];
> ///< Medium and fine timebases for each DIMM in the channel and each
> memory profile.
> +  UINT32              Capacity;                                                     ///<
> Amount of memory in this channel, in MBytes.
> +  UINT32              DimmCount;                                                    ///<
> Number of valid DIMMs that exist in the channel.
> +  UINT32              DataOffsetTrain[MAX_SDRAM_IN_DIMM];
> ///< DataOffsetTrain CR
> +  UINT32              DataCompOffset[MAX_SDRAM_IN_DIMM];
> ///< DataCompOffset CR
> +  UINT32              CkeCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CKE  CmdPiCode CR, per group
> +  UINT32              CmdsCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CmdS CmdPiCode CR, per group
> +  UINT32              CmdnCmdPiCode[MAX_COMMAND_GROUPS];
> ///< CmdN CmdPiCode CR, per group
> +  UINT16
> TxDqs[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///<
> TxDQS PI Code
> +  UINT16
> TxDq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                 ///<
> TxDQ Pi Code
> +  UINT16
> RcvEn[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];                ///<
> RcvEn PI Code
> +  UINT16
> WlDelay[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];              ///<
> WlDelay PI Code
> +  UINT8               ClkPiCode[MAX_RANK_IN_CHANNEL];
> ///< Clk Pi Code
> +  UINT8               CtlPiCode[MAX_RANK_IN_CHANNEL];
> ///< Ctl Pi Code
> +  UINT8               CkePiCode[MAX_RANK_IN_CHANNEL];
> ///< Ctl Pi Code
> +  UINT8               TxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];
> ///< TxEq setting
> +  MrcCommandMargin    Command[MAX_RANK_IN_CHANNEL];
> ///< Cmd setting
> +  MrcDqTimeMargin
> RxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Pi Code
> +  MrcDqTimeMargin
> TxDqPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Tx PerBit Pi Code
> +  MrcDqVrefMargin
> RxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Vref
> +  MrcDqVrefMargin
> TxDqVrefPb[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM][MAX_BITS];
> ///< Rx PerBit Vref
> +  MrcRecvEnMargin     ReceiveEnable[MAX_RANK_IN_CHANNEL];
> ///< Receive enable per rank
> +  MrcWrLevelMargin    WriteLevel[MAX_RANK_IN_CHANNEL];
> ///< Write leveling per rank
> +  UINT8               IoLatency[MAX_RANK_IN_CHANNEL];
> ///< IOLatency
> +  UINT8               RTLatency[MAX_RANK_IN_CHANNEL];
> ///< RoundTripLatency
> +  UINT32              RTIoComp;                                                     ///<
> RoundTrip IO Compensation of the Channel
> +  UINT8               RxVref[MAX_SDRAM_IN_DIMM];
> ///< RX Vref in steps of 7.9 mv
> +  UINT8               RxEq[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];
> ///< RxEQ Setting
> +  UINT8
> RxDqsP[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///<
> RxDQSP PI Code
> +  UINT8
> RxDqsN[MAX_RANK_IN_CHANNEL][MAX_SDRAM_IN_DIMM];               ///<
> RxDQSN PI Code
> +  UINT8               ValidRankBitMask;                                             ///<
> Bit map of the populated ranks per channel
> +  UINT8               ValidCkeBitMask;                                              ///< Bit
> map of the used CKE pins per channel
> +  MrcDimmOut          Dimm[MAX_DIMMS_IN_CHANNEL];
> ///< DIMM specific output variables.
> +  MrcTurnaroundTimes  tRd2Rd;
> ///< The system's minimal delay timings for Read  command followed by Read
> command.
> +  MrcTurnaroundTimes  tRd2Wr;
> ///< The system's minimal delay timings for Read  command followed by Write
> command.
> +  MrcTurnaroundTimes  tWr2Rd;
> ///< The system's minimal delay timings for Write command followed by Read
> command.
> +  MrcTurnaroundTimes  tWr2Wr;
> ///< The system's minimal delay timings for Write command followed by Write
> command.
> +} MrcChannelOut;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered output by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> +  MrcControllerSts 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.
> +  MrcChannelOut    Channel[MAX_CHANNEL]; ///< The following are
> channel level definitions.
> +} MrcControllerOut;
> +
> +///
> +///********************************************
> +/// Saved data related "global data" structures.
> +///********************************************
> +///
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are DIMM level definitions.
> +///
> +typedef struct {
> +  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.
> +} MrcDimmSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are channel level definitions.
> +///
> +typedef struct {
> +  MrcChannelSts Status;                               ///< Indicates whether this
> channel should be used.
> +  UINT32        DimmCount;                            ///< Number of valid DIMMs
> that exist in the channel.
> +  UINT8         ValidRankBitMask;                     ///< Bit map of the
> populated ranks per channel
> +  MrcTiming     Timing[MAX_PROFILE];                  ///< The channel timing
> values.
> +  MrcDimmOut    Dimm[MAX_DIMMS_IN_CHANNEL];           ///< Save the
> DIMM output characteristics.
> +  MrcDimmSave   DimmSave[MAX_DIMMS_IN_CHANNEL];       ///< Save SPD
> information needed for SMBIOS structure creation.
> +} MrcChannelSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are controller level definitions.
> +///
> +typedef struct {
> +  MrcControllerSts  Status;               ///< Indicates whether this controller
> should be used.
> +  UINT8             ChannelCount;         ///< Number of valid channels that
> exist on the controller.
> +  MrcChannelSave    Channel[MAX_CHANNEL]; ///< The following are
> channel level definitions.
> +} MrcContSave;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered to be needed
> +/// by the MRC between power state transitions (S0->S3->S0) and also fast
> and warm boot modes.
> +/// The following are system level definitions.
> +///
> +typedef struct {
> +  UINT32 Crc;                  ///< The CRC-32 of the data in this structure.
> +} MrcSaveHeader;
> +
> +//
> +// ------- IMPORTANT NOTE --------
> +// MRC_MC_REGISTER_COUNT in MrcInterface.h should match the table in
> MrcSaveRestore.c.
> +// Update this define whenever you add/remove registers from this table.
> +//
> +#define MRC_REGISTER_COUNT_COMMON (1376 / sizeof (UINT32)) ///< The
> number of MC registers that need to be saved (common)
> +#define MRC_REGISTER_COUNT_SAGV   (1528 / sizeof (UINT32)) ///< The
> number of MC registers that need to be saved (per SA GV point)
> +
> +typedef struct {
> +  MrcCapabilityId McCapId;                                   ///< The memory
> controller's capabilities.
> +  UINT32          RegSaveCommon[MRC_REGISTER_COUNT_COMMON];
> ///< The MC registers that are common to both SA GV points
> +  UINT32          RegSaveLow[MRC_REGISTER_COUNT_SAGV];       ///< The
> MC registers for the Low SA GV point
> +  UINT32          RegSaveHigh[MRC_REGISTER_COUNT_SAGV];      ///< The
> MC registers for the High SA GV point, or for SA GV Disabled case
> +  UINT32          MeStolenSize;                              ///< The managebility
> engine memory size, in Mbyte units.
> +  MrcCpuStepping  CpuStepping;                               ///< The last cold
> boot happended with this CPU stepping.
> +  MrcCpuModel     CpuModel;                                  ///< The last cold
> boot happended with this CPU model.
> +  MrcCpuFamily    CpuFamily;                                 ///< CPU is Coffeelake
> +  MrcVersion      Version;                                   ///< The last cold boot
> happended with this MRC version.
> +  UINT32          SaMemCfgCrc;                               ///< The CRC32 of the
> system agent memory configuration structure.
> +  MrcContSave     Controller[MAX_CONTROLLERS];               ///< The
> following are controller level definitions.
> +  MrcFrequency    FreqMax;                                   ///< The system's
> requested maximum frequency.
> +  MrcFrequency    Frequency;                                 ///< The system's
> common memory controller frequency.
> +  UINT32          MemoryClock;                               ///< The system's
> common memory controller clock, in femtoseconds.
> +  BOOLEAN         OddRatioModeLow;                           ///< If Odd Ratio
> Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for
> SAGV Low point.
> +  BOOLEAN         OddRatioModeHigh;                          ///< If Odd Ratio
> Mode is enabled, QCLK frequency has an addition of 133/100 MHz. This is for
> SAGV High point, or SAGV disabled / fixed high / fixed low
> +  MrcRefClkSelect RefClk;                                    ///< The memory
> controller is going to use this reference clock.
> +  MrcClockRatio   Ratio;                                     ///< Request for this
> memory controller to use this clock ratio.
> +  MrcVddSelect    VddVoltage[MAX_PROFILE];                   ///< The voltage
> (VDD) setting for all DIMMs in the system, per profile.
> +  BOOLEAN         EccSupport;                                ///< TRUE if ECC is
> enabled and supported on this controller.
> +  MrcDdrType      DdrType;                                   ///< DDR type: DDR3,
> DDR4, or LPDDR3
> +  UINT32          DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1]; ///< The
> Default XMP tCK values read from SPD.
> +  UINT8           XmpProfileEnable;                          ///< If XMP capable
> DIMMs are detected, this will indicate which XMP Profiles are common among
> all DIMMs.
> +  BOOLEAN         BinnedLpddrDevices;                        ///< Binned LPDDR3
> devices (6Gb/12Gb/etc)
> +  BOOLEAN         TCRSensitiveHynixDDR4;                     ///< TCR sensitive
> Hynix DDR4 in the system
> +  BOOLEAN         TCRSensitiveMicronDDR4;                    ///< TCR sensitive
> Micron DDR4 in the system
> +  BOOLEAN         LpddrEctDone;                       ///< Set to TRUE once Early
> Command Training on LPDDR is done, and we can run JEDEC Init
> +  UINT8           BerEnable;                          ///< BER Enable (and # of
> Addresses)
> +  UINT64          BerAddress[4];                      ///< BER Addresses
> +  BOOLEAN         DmfcLimitedBoard;                   ///< Indicates if the
> system has 2DPC Memory Configuration which should be DMFC limited.
> +  BOOLEAN         DmfcLimited;                        ///< Indicates if the system
> has DMFC limited. Should only be set if DmfcLImitedBoard is TRUE.
> +  BOOLEAN         MixedUDimmConfig2Dpc;               ///< Indicates if the
> system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
> +  BOOLEAN         ExtendedDdrOverclock;               ///< Indicates if MC is
> capable of extended Overclock Memory frequencies.
> +} MrcSaveData;
> +
> +typedef struct {
> +  UINT32              Size;                        ///< The size of this structure, in
> bytes. Must be the first entry in this structure.
> +  MrcDebug            Debug;                       ///< MRC debug related
> variables used for serial output and debugging purposes.
> +  MrcVersion          Version;                     ///< The memory reference code
> version.
> +  MrcFrequency        FreqMax;                     ///< The requested maximum
> valid frequency.
> +  MrcFrequency        Frequency;                   ///< The system's common
> memory controller frequency.
> +  UINT32              MemoryClockMax;              ///< The system's common
> memory controller maximum clock, in femtoseconds.
> +  UINT32              MemoryClock;                 ///< The system's common
> memory controller clock, in femtoseconds.
> +  MrcRefClkSelect     RefClk;                      ///< The memory controller is
> going to use this reference clock.
> +  MrcClockRatio       Ratio;                       ///< Request for this memory
> controller to use this clock ratio.
> +  MrcMemoryMap        MemoryMapData;               ///< The system's
> memory map data.
> +  MrcGfxDataSize      GraphicsStolenSize;          ///< Graphics Data Stolen
> Memory size in MB
> +  MrcGfxGttSize       GraphicsGttSize;             ///< GTT graphics stolen
> memory size in MB
> +  MrcVddSelect        VddVoltage[MAX_PROFILE];     ///< The currently
> running voltage (VDD) setting for all DIMMs in the system, per profile.
> +  MrcGdxc             Gdxc;                        ///< GDXC enable and size.
> +  BOOLEAN             VddVoltageDone;              ///< To determine if
> VddVoltageDone update has been done already
> +  BOOLEAN             EccSupport;                  ///< TRUE if ECC is enabled and
> supported on this controller.
> +  BOOLEAN             EnDumRd;                     ///< Enable/Disable Logic
> Analyzer
> +  BOOLEAN             RestoreMRs;                  ///< Enable/Disable restoring
> +  BOOLEAN             LpddrEctDone;                ///< Set to TRUE once Early
> Command Training on LPDDR is done, and we can run JEDEC Init
> +  BOOLEAN             LpddrWLUpdated;              ///< Set to TRUE once
> LPDDR WL Memory Set has been updated
> +  BOOLEAN             JedecInitDone;               ///< Set to TRUE once JEDEC
> Init on LPDDR/DDR4 is done
> +  UINT32              DefaultXmptCK[MAX_PROFILE - XMP_PROFILE1];
> ///< The Default XMP tCK values read from SPD.
> +  UINT8               XmpProfileEnable;            ///< If XMP capable DIMMs are
> detected, this will indicate which XMP Profiles are common among all DIMMs.
> +  BOOLEAN             Capable100;                  ///< The MC is capable of 100
> reference clock (0 = no, 1 = yes).
> +  BOOLEAN             AutoSelfRefresh;             ///< Indicates ASR is
> supported for all the DIMMS for 2xRefresh
> +  MrcDdrType          DdrType;                     ///< Current memory type:
> DDR3, DDR4, or LPDDR3
> +  MrcSpdStatus        SpdSecurityStatus;           ///< Status variable to
> inform BIOS that memory contains an alias.
> +  UINT32              MrcTotalChannelLimit;        ///< The maximum allowed
> memory size per channel, in MBytes.
> +  UINT8               SdramCount;                  ///< The number of SDRAM
> components on a DIMM.
> +  UINT16              Qclkps;                      ///< Qclk period in pS
> +  UINT8               DQPat;                       ///< Global Variables storing the
> current DQPat REUT Test
> +  INT8                DQPatLC;                     ///< Global Variables storing the
> current DQPat Loopcount
> +  UINT16              NumCL;                       ///< Global Variables storing the
> current number of Cachelines
> +  UINT8               ValidRankMask;               ///< Rank bit map - includes
> both channels
> +  UINT8               ValidChBitMask;              ///< Channel bit map of the
> populated channels
> +  BOOLEAN             UpmPwrRetrainFlag;           ///< A flag that indicates if
> training with higher UPM/PWR limits.
> +  UINT32
> MarginResult[MAX_RESULT_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHANNE
> L][MAX_SDRAM_IN_DIMM][MAX_EDGES]; ///< Stores last margin
> measurement.
> +  BOOLEAN
> MarginSignReversed[MAX_RANK_IN_CHANNEL][MAX_CHANNEL][MAX_SDRA
> M_IN_DIMM][MAX_EDGES]; ///< Indicates if the Margin Sign is Reversed
> +  MrcOdtPowerSaving   OdtPowerSavingData;          ///< ODT power savings
> data.
> +  BOOLEAN             TxDIMMVref[MAX_CHANNEL];     ///< Whether Write
> DIMM Vref is enabled based on Channel
> +  UINT32              MchBarWriteCount;            ///< The number of MMIO
> writes performed during MRC execution.
> +  UINT32              MchBarReadCount;             ///< The number of MMIO
> reads performed during MRC execution.
> +  UINT8               BerEnable;                   ///< BER Enable (and # of
> Addresses)
> +  UINT64              BerAddress[4];               ///< BER Addresses
> +  UINT8               CmdVLoop;                    ///< Keeps track of the # of
> CmdV training step runned
> +  UINT8               CmdVLoopStatus;              ///< Keeps the last status of
> the CmdV training step
> +  UINT8               tMAC;                        ///< Maximum Activate Count for
> pTRR.
> +  UINT8               LpddrMemWriteLatencySet;     ///< 0 = Set A (WL), 1 = Set
> B (WL) if supported
> +  BOOLEAN             Ddr4PdaEnable;               ///< Current status of PDA - if
> true all the Mr6 operations need to use PDA mode.
> +  BOOLEAN             BinnedLpddrDevices;          ///< Binned LPDDR3 devices
> (6Gb/12Gb/etc)
> +  MrcControllerOut    Controller[MAX_CONTROLLERS]; ///< The following
> are controller level definitions.
> +  BOOLEAN             TCRSensitiveHynixDDR4;       ///< TCR sensitive Hynix
> DDR4 in the system
> +  BOOLEAN             TCRSensitiveMicronDDR4;      ///< TCR sensitive Micron
> DDR4 in the system
> +  BOOLEAN             OddRatioMode;                ///< If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz
> +  BOOLEAN             LpddrDramOdt;                ///< Indicates if LPDDR
> DRAM ODT is used - Only used for 2133+
> +  BOOLEAN             ExtendedDdrOverclock;        ///< Indicates if MC is
> capable of extended Overclock Memory frequencies.
> +  BOOLEAN             DmfcLimitedBoard;            ///< Indicates if the system
> has 2DPC Memory Configuration which should be DMFC limited.
> +  BOOLEAN             DmfcLimited;                 ///< Indicates if the system has
> DMFC has been limited. Should only be set if DmfcLImitedBoard is TRUE.
> +  BOOLEAN             MixedUDimmConfig2Dpc;        ///< Indicates if the
> system has 2DPC Memory Configuration with Mixed U-DIMM Part Numbers
> +#ifdef BDAT_SUPPORT
> +  union {
> +    MRC_BDAT_SCHEMA_LIST_HOB *Pointer;             ///< Pointer to the
> BDAT schema list.
> +    UINT64                   Data;
> +  } BdatSchemasHob;
> +  union {
> +    BDAT_MEMORY_DATA_HOB *Pointer;                 ///< Pointer to the BDAT
> memory data HOB.
> +    UINT64               Data;
> +  } BdatMemoryHob[MAX_SCHEMA_LIST_LENGTH];
> +  UINT8
> Margin2DResult[MAX_2D_EYE_TYPE][MAX_RANK_IN_CHANNEL][MAX_CHAN
> NEL][MAX_2D_EYE_OFFSETS][MAX_EDGES]; ///< Stores the 2D Eye Margin
> +#endif
> +
> +#ifdef UP_SERVER_FLAG
> +  UINT8              ThermOffset[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
> ///< TSOD Thermal Offset
> +#endif
> +} MrcOutput;
> +
> +///
> +///****************************************
> +/// Input related "global data" structures.
> +///****************************************
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are SDRAM level definitions. All ranks on a rank are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +  UINT8  Placeholder;  ///< TODO: Is there anything that needs to go in here?
> +} MrcSdramIn;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are rank level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +/* Commented out until needed, in order to save space.
> +typedef struct {
> +  MrcSdramIn  Sdram[MAX_SDRAM_IN_DIMM]; ///< The following are
> SDRAM level definitions.
> +} MrcRankIn;
> +*/
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are DIMM level definitions. All ranks on a DIMM are set to
> these values.
> +///
> +typedef struct {
> +  MrcDimmSts  Status;                 ///< Indicates whether this DIMM should
> be used.
> +  MrcSpdData  Spd;                    ///< The SPD data for each DIMM.
> SPDGeneral field = 0 when absent.
> +  MrcTiming   Timing;                 ///< The DIMMs requested timing
> overrides.
> +  UINT8       SpdAddress;             ///< The SMBus address for the DIMM's
> SPD data.
> +//MrcRankIn   Rank[MAX_RANK_IN_DIMM]; ///< The following are rank level
> definitions.
> +} MrcDimmIn;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are channel level definitions. All DIMMs on a memory
> channel are set to these values.
> +///
> +typedef struct {
> +  MrcChannelSts Status;                        ///< Indicates whether this channel
> should be used.
> +  UINT32        DimmCount;                     ///< The maximum number of
> DIMMs on this channel.
> +  MrcDimmIn     Dimm[MAX_DIMMS_IN_CHANNEL];    ///< The following
> are DIMM level definitions.
> +  UINT8         DqsMapCpu2Dram[8];             ///< Mapping from CPU DQS
> pins to SDRAM DQS pins
> +  UINT8         DqMapCpu2Dram[8][MAX_BITS];    ///< Mapping from CPU
> DQ pins to SDRAM DQ pins
> +  UINT8         DQByteMap[MrcIterationMax][2]; ///< Maps which PI clocks
> are used by what LPDDR DQ Bytes (from CPU side), per group
> +                                               ///< DQByteMap[0] - ClkDQByteMap:
> +                                               ///<   If clock is per rank, program to [0xFF,
> 0xFF]
> +                                               ///<   If clock is shared by 2 ranks, program
> to [0xFF, 0] or [0, 0xFF]
> +                                               ///<   If clock is shared by 2 ranks but does
> not go to all bytes,
> +                                               ///<           Entry[i] defines which DQ
> bytes Group i services
> +                                               ///< DQByteMap[1] - CmdNDQByteMap:
> Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
> +                                               ///< DQByteMap[2] - CmdSDQByteMap:
> Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
> +                                               ///< DQByteMap[3] - CkeDQByteMap :
> Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
> +                                               ///<                For DDR, DQByteMap[3:1]
> = [0xFF, 0]
> +                                               ///< DQByteMap[4] - CtlDQByteMap :
> Always program to [0xFF, 0] since we have 1 CTL / rank
> +                                               ///<                               Variable only
> exists to make the code easier to use
> +                                               ///< DQByteMap[5] - CmdVDQByteMap:
> Always program to [0xFF, 0] since we have 1 CA Vref
> +                                               ///<                               Variable only
> exists to make the code easier to use
> +} MrcChannelIn;
> +
> +///
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are memory controller level definitions. All channels on a
> controller are set to these values.
> +///
> +typedef struct {
> +  MrcControllerSts  Status;               ///< Indicates whether this controller
> should be used.
> +  UINT8             ChannelCount;         ///< Number of valid channels that
> are requested on the controller.
> +  MrcChannelIn      Channel[MAX_CHANNEL]; ///< The following are channel
> level definitions.
> +} MrcControllerIn;
> +
> +/// This data structure contains all the "global data" values that are
> considered input by the MRC.
> +/// The following are system level definitions. All memory controllers in the
> system are set to these values.
> +typedef struct {
> +  // Start of synchronization to the SA MEMORY_CONFIGURATION structure.
> +  // Alignment of this block must be maintained and field offsets must match.
> +  UINT8   Header[28];             ///< 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
> +  UINT8   MemoryProfile;          ///< 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 MemoryProfile is
> UserDefined (CUSTOM PROFILE)
> +  UINT16  tCL;                    ///< Offset 32 User defined Memory Timing tCL
> value,   valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 31=Maximum.
> +  UINT16  tRCDtRP;                ///< Offset 34 User defined Memory Timing
> tRCD value (same as tRP), valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 63=Maximum.
> +  UINT16  tRAS;                   ///< Offset 36 User defined Memory Timing
> tRAS value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 64=Maximum.
> +  UINT16  tWR;                    ///< Offset 38 User defined Memory Timing
> tWR value,   valid when MemoryProfile 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 MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 1023=Maximum.
> +  UINT16  tRRD;                   ///< Offset 42 User defined Memory Timing
> tRRD value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 15=Maximum.
> +  UINT16  tWTR;                   ///< Offset 44 User defined Memory Timing
> tWTR value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 28=Maximum.
> +  UINT16  tRTP;                   ///< Offset 46 User defined Memory Timing
> tRTP value,  valid when MemoryProfile 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 MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 63=Maximum.
> +  UINT16  tCWL;                   ///< Offset 50 User defined Memory Timing
> tCWL value,  valid when MemoryProfile is CUSTOM_PROFILE: <b>0=AUTO</b>,
> 20=Maximum.
> +  UINT16  tREFI;                  ///< Offset 52 User defined Memory Timing
> tREFI value, valid when MemoryProfile 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 DIMM Ecc Support
> option - for Desktop only: 0=Disable, <b>1=Enable</b>
> +  UINT32  MrcSafeConfig:1;                ///<  - MRC Safe Mode:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RemapEnable:1;                  ///<  - This option is used to control
> whether to enable/disable memory remap above 4GB: 0=Disable,
> <b>1=Enable</b>.
> +  UINT32  ScramblerEnable:1;              ///<  - Memory scrambler support:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  Vc1ReadMeter:1;                 ///<  - VC1 Read Metering Enable:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  DdrThermalSensor:1;             ///<  - Ddr Thermal Sensor:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  LpddrMemWriteLatencySet:1;      ///<  - LPDDR3 Write Latency Set
> option: 0=Set A, <b>1=Set B</b>
> +  UINT32  Off64Bits7to8Rsvd:2;            ///<  - Bits 7-8 Reserved
> +  UINT32  SimicsFlag:1;                   ///<  - Option to Enable SIMICS:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  Ddr4DdpSharedClock:1;           ///<  - New Select if CLK0 is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> +  UINT32  Ddr4DdpSharedZq:1;              ///<  - Select if ZQ pin is shared
> between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>,
> 1=Shared
> +  // Thermal Management
> +  UINT32  ThermalManagement:1;            ///<  - Memory Thermal
> Management Support: <b>0=Disable</b>, 1=Enable.
> +  UINT32  PeciInjectedTemp:1;             ///<  - Enable/Disable memory
> temperatures to be injected to the processor via PECI: <b>0=Disable</b>,
> 1=Enable.
> +  UINT32  ExttsViaTsOnBoard:1;            ///<  - Enable/Disable routing
> TS-on-Board's ALERT# and THERM# to EXTTS# pins on the PCH:
> <b>0=Disable</b>, 1=Enable.
> +  UINT32  ExttsViaTsOnDimm:1;             ///<  - Enable/Disable routing
> TS-on-DIMM's ALERT# to EXTTS# pin on the PCH: <b>0=Disable</b>, 1=Enable.
> +  UINT32  VirtualTempSensor:1;            ///<  - Enable/Disable Virtual
> Temperature Sensor (VTS): <b>0=Disable</b>, 1=Enable.
> +  UINT32  Lp4DqsOscEn:1;                  ///<  - DqDqsReTraining support:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  DualDimmPerChannelBoardType:1;  ///<  -
> DualDimmPerChannelBoardType: Option to indicate if the Memory Design for
> the board includes two DIMMs per channel: <b>0=Single DIMM Design</b>,
> 1=Dual DIMM Design
> +  UINT32  ReservedBits1:13;
> +  /**
> +   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[MAX_CHANNEL];  ///< Offset 68
> +  /**
> +   Selects the ratio to multiply the reference clock by for the DDR frequency\n
> +   When RefClk is 133MHz\n
> +   <b>0x00 = Auto</b>, 0x03 through 0x0C are valid values, all others are
> invalid\n
> +   When RefClk is 100MHz\n
> +   <b>0x00 = Auto</b>, 0x06 through 0x10 are valid values, all others are
> invalid\n
> +  **/
> +  UINT8   Ratio;                  ///< Offset 70
> +  UINT8   ProbelessTrace;         ///< Offset 71 Probeless Trace:
> <b>0=Disabled</b>, <b>1=Enabled</b>
> +  UINT32  BClkFrequency;          ///< Offset 72 Base reference clock value, in
> Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz,
> 250000000=250Hz
> +  /**
> +     - Channel Hash Enable.\n
> +    NOTE: BIT7 will interleave the channels at a 2 cacheline granularity, BIT8 at
> 4 and BIT9 at 8\n
> +    0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
> +  **/
> +  UINT8   ChHashInterleaveBit;    ///< Offset 76
> +  UINT8   EnergyScaleFact;        ///< Offset 77 - Energy Scale Factor.
> 0=Minimal, 7=Maximum, <b>4=Default</b>
> +  UINT8   Reserved0;              ///< Offset 78 - Reserved for future use.
> +  UINT8   McLock;                 ///< Offset 79 - Enable/Disable memory
> configuration register locking: 0=Disable, <b>1=Enable</b>.
> +  // Training Algorithms
> +  TrainingStepsEn TrainingEnables;    ///< Offset 80 - Options to Enable
> individual training steps
> +  TrainingStepsEn2 TrainingEnables2;  ///< Offset 84 - Options to Enable
> individual training steps
> +
> +  UINT32  OddRatioMode:1;             ///< Offset 88 - If Odd Ratio Mode is
> enabled, QCLK frequency has an addition of 133/100 MHz: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  MrcTimeMeasure:1;           ///< - Enables serial debug level to
> display the MRC execution times only: <b>0=Disable</b>, 1=Enable
> +  UINT32  MrcFastBoot:1;              ///< - Enables the MRC fast boot path for
> faster cold boot execution: 0=Disable, <b>1=Enable</b>
> +  UINT32  DqPinsInterleaved:1;        ///< - Interleaving mode of DQ/DQS pins
> for HSW_ULT which depends on board routing: <b>0=Disable</b>, 1=Enable
> +  UINT32  RankInterleave:1;           ///< - Rank Interleave Mode: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  EnhancedInterleave:1;       ///< - Enhanced Interleave Mode:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  WeaklockEn:1;               ///< - Weak Lock Enable: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  CmdTriStateDis:1;           ///< - CMD Tri-State Support:
> <b>0=Enable</b>, 1=Disable. Note: This should be set to 1 (Disable) if
> Command RTT is not present on the platform.
> +  UINT32  MemoryTrace:1;              ///< - Memory Trace to second DDR
> channel using Stacked Mode: <b>0=Disable</b>, 1=Enable
> +  UINT32  ChHashEnable:1;             ///< - Channel Hash Enable: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  EnableExtts:1;              ///< - Enable Extts: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  EnableCltm:1;               ///< - Enable Closed Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> +  UINT32  EnableOltm:1;               ///< - Enable Open Loop Thermal
> Management: <b>0=Disable</b>, 1=Enable
> +  UINT32  EnablePwrDn:1;              ///< - Enable Power Down control for
> DDR: 0=PCODE control, <b>1=BIOS control</b>
> +  UINT32  EnablePwrDnLpddr:1;         ///< - Enable Power Down for LPDDR:
> 0=PCODE control, <b>1=BIOS control</b>
> +  UINT32  LockPTMregs:1;              ///< - Lock PCU Thermal Management
> registers: 0=Disable, <b>1=Enable</b>
> +  UINT32  UserPowerWeightsEn:1;       ///< - Allows user to explicitly set
> power weight, scale factor, and channel power floor values: <b>0=Disable</b>,
> 1=Enable
> +  UINT32  RaplLim2Lock:1;             ///< - Lock DDR_RAPL_LIMIT register:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RaplLim2Ena:1;              ///< - Enable Power Limit 2:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  RaplLim1Ena:1;              ///< - Enable Power Limit 1:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  SrefCfgEna:1;               ///< - Enable Self Refresh: 0=Disable,
> <b>1=Enable</b>
> +  UINT32  ThrtCkeMinDefeatLpddr:1;    ///< - Throttler CKE min defeature for
> LPDDR: 0=Disable, <b>1=Enable</b>
> +  UINT32  ThrtCkeMinDefeat:1;         ///< - Throttler CKE min defeature:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  AutoSelfRefreshSupport:1;   ///< - FALSE = No auto self refresh
> support, <b>TRUE = auto self refresh support</b>
> +  UINT32  ExtTemperatureSupport:1;    ///< - FALSE = No extended
> temperature support, <b>TRUE = extended temperature support</b>
> +  UINT32  MobilePlatform:1;           ///< - Memory controller device id
> indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be
> auto-detected and updated.
> +  UINT32  Force1Dpc:1;                ///< - TRUE means force one DIMM per
> channel, <b>FALSE means no limit</b>
> +  UINT32  ForceSingleRank:1;          ///< - TRUE means use Rank0 only (in
> each DIMM): <b>0=Disable</b>, 1=Enable
> +  UINT32  RhPrevention:1;             ///< - RH Prevention Enable/Disable:
> 0=Disable, <b>1=Enable</b>
> +  UINT32  VttTermination:1;           ///< - Vtt Termination for Data ODT:
> <b>0=Disable</b>, 1=Enable
> +  UINT32  VttCompForVsshi:1;          ///< - Enable/Disable Vtt Comparator
> For Vsshi: <b>0=Disable</b>, 1=Enable
> +  UINT32  ExitOnFailure:1;            ///< - MRC option for exit on failure or
> continue on failure: 0=Disable, <b>1=Enable</b>
> +
> +  UINT32  VddSettleWaitTime;      ///< Offset 92 - Amount of time in
> microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec:
> <b>Default=0</b>
> +  UINT16  FreqSaGvLow;            ///< Offset 96 - SA GV: 0 is Auto/default,
> otherwise holds the frequency value: <b>0=Default</b>, 1067, 1200, 1333,
> 1400, 1600, 1800, 1867.
> +  UINT16  SrefCfgIdleTmr;         ///< Offset 98 - Self Refresh idle timer:
> <b>512=Minimal</b>, 65535=Maximum
> +  UINT8   RhActProbability;       ///< Offset 100 - Activation probability for
> Hardware RHP
> +  UINT8   SmramMask;              ///< Offset 101 - Reserved memory ranges
> for SMRAM
> +  UINT16  Vc1ReadMeterThreshold;  ///< Offset 102 - VC1 Read Meter
> Threshold (within Time Window): 0=Minimal, 0xFFFF=Maximum,
> <b>0x118=Default</b>
> +  UINT32  Vc1ReadMeterTimeWindow; ///< Offset 104 - VC1 Read Meter
> Time Window: 0=Minimal, 0x1FFFF=Maximum, <b>0x320=Default</b>
> +  UINT64  BerAddress[4];          ///< Offset 108 - 139 BER Address(es):
> <b>0=Minimal</b>, 0xFFFFFFFFFFFFFFFF=Maximum (step is 0x40)
> +
> +  UINT16  ChHashMask;             ///< Offset 140 - 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 142 - Memory Frequency Limit:
> <b>0=Auto (limited by SPD/CPU capability)</b>, for valid values see
> MrcFrequency in MrcInterface.h
> +  ThermalMngmtEn  ThermalEnables; ///< Offset 144 - 187
> +
> +  UINT8   MaxRttWr;               ///< Offset 188 - Maximum DIMM RTT_WR to
> use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
> +  UINT8   ThrtCkeMinTmr;          ///< Offset 189 - Throttler CKE min timer:
> 0=Minimal, 0xFF=Maximum, <b>0x30=Default</b>
> +  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 190 - Throttler CKE min timer
> for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x40=Default</b>
> +  UINT8   BerEnable;              ///< Offset 191 - BER Enable and # of
> Addresses passed in: <b>0=Minimal</b>, 8=Maximum
> +  UINT8   CkeRankMapping;         ///< Offset 192 - Bits [7:4] - Channel 1, bits
> [3:0] - Channel 0. <b>0xAA=Default</b> Bit [i] specifies which rank CKE[i] goes
> to.
> +  UINT8   StrongWkLeaker;         ///< Offset 193 - Strong Weak Leaker:
> 1=Minimal, <b>7=Maximum</b>
> +  UINT8   CaVrefConfig;           ///< Offset 194 - 0=VREF_CA goes to both
> CH_A and CH_B, 1=VREF_CA to CH_A, VREF_DQ_A to CH_B, <b>2=VREF_CA to
> CH_A, VREF_DQ_B to CH_B</b>
> +  UINT8   SaGv;                   ///< Offset 195 - SA GV: <b>0=Disabled</b>,
> 1=FixedLow, 2=FixedHigh, 3=Enabled
> +  UINT8   RaplPwrFlCh1;           ///< Offset 196 - Power Channel 1 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> +  UINT8   RaplPwrFlCh0;           ///< Offset 197 - Power Channel 0 Floor value:
> <b>0=Minimal</b>, 255=Maximum
> +  UINT8   NModeSupport;           ///< Offset 198 - Memory N Mode Support
> - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
> +  UINT8   RefClk;                 ///< Offset 199 - Selects the DDR base reference
> clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
> +  UINT8   EnCmdRate;              ///< Offset 200 - CMD Rate Enable: 0=Disable,
> 1=1 CMD, 2=2 CMDs, <b>3=3 CMDs</b>, 4=4 CMDs, 5=5 CMDs, 6=6 CMDs, 7=7
> CMDs
> +  UINT8   Refresh2X;              ///< Offset 201 - Refresh 2x: <b>0=Disable</b>,
> 1=Enable for WARM or HOT, 2=Enable for HOT only
> +  UINT8   EpgEnable;              ///< Offset 202 - Enable Energy Performance
> Gain.
> +  UINT8   RhSolution;             ///< Offset 203 - Type of solution to be used
> for RHP - 0/1 = HardwareRhp/Refresh2x
> +  UINT8   UserThresholdEnable;    ///< Offset 204 - Flag to manually select
> the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   UserBudgetEnable;       ///< Offset 205 - Flag to manually select the
> Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable,
> <b>0=Default</b>
> +  UINT8   TsodTcritMax;           ///< Offset 206 - TSOD Tcrit Maximum Value
> to be Configure , 0=Minimal, 128=Maximum, , <b>105=Default</b>
> +
> +  UINT8   TsodEventMode;          ///< Offset 207 - Flag to Enable Event Mode
> Interruption in TSOD Configuration Register, 0=Disable,  1=Enable,
> <b>1=Default</b>
> +  UINT8   TsodEventPolarity;      ///< Offset 208 - Event Signal Polarity in
> TSOD Configuration Register, 0=Low,  1=High, <b>0=Default</b>
> +  UINT8   TsodCriticalEventOnly;  ///< Offset 209 - Critical Trigger Only in
> TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
> +  UINT8   TsodEventOutputControl; ///< Offset 210 - Event Output Control in
> TSOD Configuration Register,0=Disable,  1=Enable, <b>1=Default</b>
> +  UINT8   TsodAlarmwindowLockBit; ///< Offset 211 - Alarm Windows Lock Bit
> in TSOD Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
> +  UINT8   TsodCriticaltripLockBit;///< Offset 212 - Critical Trip Lock Bit in TSOD
> Configuration Register,0=Unlock,  1=Lock, <b>0=Default</b>
> +  UINT8   TsodShutdownMode;       ///< Offset 213 - Shutdown Mode TSOD
> Configuration Register,0=Enable,  1=Disable, <b>0=Default</b>
> +  UINT8   TsodThigMax;            ///< Offset 214 - Thigh Max Value In the  for
> CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   TsodManualEnable;       ///< Offset 215 - Flag to manually select
> the TSOD Register Values , 0=Disable,  1=Enable, <b>0=Default</b>
> +  UINT8   DllBwEn0;               ///< Offset 216 - DllBwEn value for 1067
> +  UINT8   DllBwEn1;               ///< Offset 217 - DllBwEn value for 1333
> +  UINT8   DllBwEn2;               ///< Offset 218 - DllBwEn value for 1600
> +  UINT8   DllBwEn3;               ///< Offset 219 - DllBwEn value for 1867 and
> up
> +  UINT8   RetrainOnFastFail;      ///< Offset 220 - Restart MRC in Cold mode if
> SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
> +  UINT8   ForceOltmOrRefresh2x;   ///< Offset 221 - Force OLTM or 2X Refresh
> when needed. <b>0 = Force OLTM</b>, 1 = Force 2x Refresh
> +  UINT8   PowerDownMode;          ///< Offset 222 - CKE Power Down Mode:
> <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
> +  UINT8   PwdwnIdleCounter;       ///< Offset 223 - CKE Power Down Mode
> Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
> +  UINT8   IsvtIoPort;             ///< Offset 224 ISVT IO Port Address: 0=Minimal,
> 0xFF=Maximum, <b>0x99=Default</b>
> +  UINT8   Reserved3;              ///< Offset 225 -  ConfigBlock size must be a
> multiple of DWORDs
> +  MrcGdxc Gdxc;                   ///< Offset 226 - 228 - GDXC enable and size.
> +  UINT8   RMTLoopCount;           ///< Offset 229 - Indicates the Loop Count
> to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO,
> <b>0=Default</b>
> +  UINT8   Reserved4[2];           ///< Offset 230 - 231 Reserved for DWORD
> alignment.
> +  UINT32  RmtPerTask:1;                 ///< Offset 232 Bit 0: Rank Margin Tool
> Per Task. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  Off232Bit1Rsvd:2;             ///< Offset 232 Bit 1-2: Reserved
> +  UINT32  EnBER:1;                      ///< Offset 232 Bit 3: Define if EnBER is
> enabled for Rank Margin Tool
> +  UINT32  Ddr4MixedUDimm2DpcLimit:1;    ///< Offset 232 Bit 4:
> Enable/Disable 2667 Frequency Limitation for DDR4 U-DIMM Mixed Dimm
> 2DPC population. 0 = Disabled, <b>1 = Enabled</b>
> +  UINT32  FastBootRmt:1;                ///< Offset 232 Bit 5: Enable/Disable
> RMT on FastBoot. <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  MrcTrainOnWarm:1;             ///< Offset 232 Bit 6: Enalbes MRC
> trainin on warm boot : <b>0=Disable</b>, 1 = Enabled
> +  UINT32  LongFlyByModeEnabled:1;       ///< Offset 232 Bit 7: Long FlyBy
> Mode Enabled : <b>0 = Disabled</b>, 1 = Enabled
> +  UINT32  Off232RsvdBits:24;            ///< Offset 232 Bit 8-31: Reserved
> +
> +  //
> +  // TurnAround Timing
> +  //
> +  MrcTurnaroundTimes tRd2Rd;      ///< Offset 236 - User-defined overrides
> for Read-to-Read   Turn Around Timings. <b>0 = AUTO</b>
> +  MrcTurnaroundTimes tRd2Wr;      ///< Offset 240 - User-defined overrides
> for Read-to-Write  Turn Around Timings. <b>0 = AUTO</b>
> +  MrcTurnaroundTimes tWr2Rd;      ///< Offset 244 - User-defined overrides
> for Write-to-Read  Turn Around Timings. <b>0 = AUTO</b>
> +  MrcTurnaroundTimes tWr2Wr;      ///< Offset 248 - User-defined overrides
> for Write-to-Write Turn Around Timings. <b>0 = AUTO</b>
> +  UINT16  tRRD_L;                 ///< Offset 252 - User defined DDR4 Memory
> Timing tRRD_L value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> +  UINT16  tRRD_S;                 ///< Offset 254 - User defined DDR4 Memory
> Timing tRRD_S value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 15=Maximum.
> +  UINT16  tWTR_L;                 ///< Offset 266 - User defined DDR4 Memory
> Timing tWTR_L value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 28=Maximum.
> +  UINT16  tWTR_S;                 ///< Offset 268 - User defined DDR4 Memory
> Timing tWTR_S value,  valid when MemoryProfile is CUSTOM_PROFILE:
> <b>0=AUTO</b>, 28=Maximum.
> +
> +  //
> +  // End of synchronization to the SA MEMORY_CONFIGURATION structure.
> +  //
> +  MrcFrequency     FreqMax;                     ///< The requested maximum
> valid frequency.
> +  MrcBoardType     BoardType;                   ///< Define the board type
> (CRBMB,CRBDT,User1,User2). the OEM can add more boards.
> +  MrcCpuStepping   CpuStepping;                 ///< Define the CPU stepping.
> +  MrcCpuModel      CpuModel;                    ///< Define the CPU model.
> +  MrcCpuFamily     CpuFamily;                   ///< CPU is Coffeelake
> +  MrcGfxDataSize   GraphicsStolenSize;          ///< Graphics Data Stolen
> Memory size in MB
> +  MrcGfxGttSize    GraphicsGttSize;             ///< GTT graphics stolen
> memory size in MB
> +  MrcBaseTime      BaseTime;                    ///< RTC base time.
> +  MrcIteration     Iteration;                   ///< Number of iterations thru the
> MRC core call table.
> +  MrcMode          MrcMode;                     ///< The control for full or
> MiniBIOS MRC.
> +  MrcBootMode      BootMode;                    ///< The requested memory
> controller boot mode.
> +  BOOLEAN          TxtFlag;                     ///< Trusted eXecution Technology
> flag.
> +  BOOLEAN          SetRxDqs32;                  ///< Set DQS Delay to 32 control.
> +  BOOLEAN          GfxIsVersatileAcceleration;  ///< iGFX engines are in
> Versatile Acceleration
> +  BOOLEAN          DDR4MAP;                     ///< DDR4 PDA Mapping training
> control.
> +  POINTER_STRUCT   SaMemCfgAddress;             ///< Starting address of
> the input parameters to CRC.
> +  UINT32           SaMemCfgSize;                ///< The size of the input
> parameters to CRC.
> +  UINT32           PciEBaseAddress;             ///< define the PciE base
> address.
> +  UINT32           MchBarBaseAddress;           ///< define the MCH bar base
> address.
> +  UINT32           SmbusBaseAddress;            ///< This field defines the
> smbus base address.
> +  UINT32           GdxcBaseAddress;             ///< This field defines the GDXC
> base address.
> +  UINT32           HpetBaseAddress;             ///< This field defines the hpet
> base address.
> +  UINT32           MeStolenSize;                ///< define the size that the ME
> need in MB.
> +  UINT32           MmioSize;                    ///< define the MMIO size in MB.
> +  UINT32           TsegSize;                    ///< TSEG size that require by the
> system in MB.
> +  UINT32           IedSize;                     ///< IED size that require by the
> system in MB.
> +  UINT32           DprSize;                     ///< DPR size required by system in
> MB.
> +  UINT32           PrmrrSize;                   ///< Prmrr size required by the
> system in MB.
> +  POINTER_STRUCT   SerialBuffer;                ///< Pointer to the start of the
> serial buffer.
> +  UINT32           SerialBufferSize;            ///< The size of the serial buffer, in
> bytes.
> +  UINT32           DebugStream;                 ///< The debug port pointer.
> +  INT32            DebugLevel;                  ///< Indicates the level of debug
> messaging.
> +  UINT16           VccIomV;                     ///< VccIO logic voltage in mV.
> +  MrcControllerIn  Controller[MAX_CONTROLLERS]; ///< The following are
> controller level definitions.
> +  UINT32           HeapBase;                    ///< Starting address of the heap
> space.
> +  UINT32           HeapSize;                    ///< Size of the heap space, in
> bytes.
> +  UINT32           MrcStackTop;                 ///< Top of the stack at the
> beginning of MRC, for stack usage calculations.
> +  BOOLEAN          BdatEnable;                  ///< Option to enable output of
> training results into BDAT.
> +  UINT8            BdatTestType;                ///< When BdatEnable is set to
> TRUE, this option selects the type of training results data which will be
> populated into BDAT: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
> +  BOOLEAN          LpddrDramOdt;                ///< TRUE if LPDDR DRAM ODT
> is used - depends on board design
> +  BOOLEAN          Ddr3DramOdt;                 ///< TRUE if DDR3  DRAM ODT
> is used - depends on board design
> +  BOOLEAN          Ddr4DramOdt;                 ///< TRUE if DDR4  DRAM ODT
> is used - depends on board design
> +  BOOLEAN          EnableVrefPwrDn;             ///< Setting this limits VrefGen
> to be off only during CKEPowerDown
> +  BOOLEAN          TxEqDis;                     ///< Disable TX Equalization
> +  BOOLEAN          EnVttOdt;                    ///< Enable VTT Termination for
> Data ODT
> +  UINT32           CpuidModel;                  ///< Unique CPU identifier.
> +  UINT8            CpuidStepping;               ///< Revision of the CPU.
> +  UINT8            CpuidSku;                    ///< SKU of the CPU.
> +  UINT32           SiPreMemPolicyPpi;
> +  TrainingModeType PowerTrainingMode;           ///< 0 - Power Training. 1 -
> Margin Training.
> +  union {
> +    MRC_FUNCTION  *Func;                        ///< External to MRC function
> pointers
> +    UINT64        Data;
> +  } Call;
> +  UINT16          RcompResistor[MAX_RCOMP];     ///< Reference RCOMP
> resistors on motherboard
> +  UINT16          RcompTarget[MAX_RCOMP_TARGETS]; ///< RCOMP target
> values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
> +  UINT32          CleanMemory:1;                ///< TRUE to request a memory
> clean
> +  UINT32          OcSupport:1;                  ///< TRUE if Overclocking is
> enabled in BIOS
> +  UINT32          RsvdBits5:30;
> +  /**
> +   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;
> +} MrcInput;
> +
> +typedef struct {
> +  UINT32        Size;   ///< The size of this structure, in bytes. Must be the first
> entry in this structure.
> +  MrcSaveHeader Header; ///< The header portion of the MRC saved data.
> +  MrcSaveData   Data;   ///< The data portion of the MRC saved data.
> +} MrcSave;
> +
> +typedef struct {
> +  // Global variables that will be copied to the HOB follow.
> +  UINT8        MrcDataString[4]; ///< Beginning of global data marker, starts
> with "MRC". Must be the first entry in this structure.
> +  UINT32       MrcDataSize;      ///< The size of the MRC global data area, in
> bytes. Must be the second entry in this structure.
> +  MrcSave      Save;             ///< System specific save variables.
> +  MrcInput     Inputs;           ///< System specific input variables.
> +  MrcOutput    Outputs;          ///< System specific output variables.
> +
> +  // Global variables that will remain internal to the MRC library follow.
> +  union {
> +    void   *Internal; ///< System specific output variables that remain internal
> to the library.
> +    UINT64 Data;
> +  } IntOutputs;
> +} MrcParameters;
> +
> +#pragma pack (pop)
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> new file mode 100644
> index 0000000000..9dd9b096ba
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcRmtData.h
> @@ -0,0 +1,203 @@
> +/** @file
> +  Copies the memory related timing and configuration information into the
> +  Compatible BIOS data (BDAT) table.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcRmtData_h_
> +#define _MrcRmtData_h_
> +
> +#include "MrcTypes.h"
> +
> +#define VDD_1_350             1350                      ///< VDD in millivolts
> +#define VDD_1_500             1500                      ///< VDD in millivolts
> +#define PI_STEP_BASE          2048                      ///< Magic number from
> spec
> +#define PI_STEP_INTERVAL      128                       ///< tCK is split into this
> amount of intervals
> +#define PI_STEP               ((PI_STEP_BASE) / (PI_STEP_INTERVAL))
> +#define VREF_STEP_BASE        100                       ///< Magic number from
> spec
> +#define TX_VREF_STEP          7800                      ///< TX Vref step in
> microvolts
> +#define TX_VREF(VDD)          (((TX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +#define RX_VREF_STEP          8000                      ///< TX Vref step in
> microvolts
> +#define RX_VREF(VDD)          (((RX_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +#define CA_VREF_STEP          8000                      ///< TX Vref step in
> microvolts
> +#define CA_VREF(VDD)          (((CA_VREF_STEP) * (VREF_STEP_BASE)) / (VDD))
> ///< VDD passed in is in millivolts
> +
> +#define MAX_SPD_RMT           512                       ///< The maximum
> amount of data, in bytes, in an SPD structure.
> +#define RMT_PRIMARY_VERSION   4                         ///< The BDAT
> structure that is currently supported.
> +#define RMT_SECONDARY_VERSION 0                         ///< The BDAT
> structure that is currently supported.
> +#define MAX_MODE_REGISTER     7                         ///< Number of mode
> registers
> +#define MAX_DRAM_DEVICE       9                         ///< Maximum number
> of memory devices
> +#define MAX_2D_EYE_TYPE       2                         ///< Maximum number
> of supported Margin 2D Eye Types
> +#define MAX_2D_EYE_OFFSETS    7                         ///< Number of 2D Eye
> Offsets
> +
> +//
> +// Warning: Bdat4.h has its own copy of this #define
> +// make sure to change it in both places
> +//
> +#define MAX_SCHEMA_LIST_LENGTH (10)
> +
> +
> +#ifdef BDAT_SUPPORT
> +/*
> +  BSSA result Memory Schema GUID
> +  {8F4E928-0F5F-46D4-8410-479FDA279DB6}
> +*/
> +extern EFI_GUID gSsaBiosResultsGuid;
> +/*
> +  RMT Results Metadata GUID
> +  {02CB1552-D659-4232-B51F-CAB1E11FCA87}
> +*/
> +extern EFI_GUID gRmtResultMetadataGuid;
> +/*
> +  RMT Results Columns GUID
> +  {0E60A1EB-331F-42A1-9DE7-453E84761154}
> +*/
> +extern EFI_GUID gRmtResultColumnsGuid;
> +
> +/*
> +Margin2D Results Metadata GUID
> +{48265582-8E49-4AC7-AA06-E1B9A74C9716}
> +*/
> +extern EFI_GUID gMargin2DResultMetadataGuid;
> +/*
> +Margin2D Results Columns GUID
> +{91A449EC-8A4A-4736-AD71-A3F6F6D752D9}
> +*/
> +extern EFI_GUID gMargin2DResultColumnsGuid;
> +
> +#endif
> +/*
> + GUID for Schema List HOB
> + This is private GUID used by MemoryInit internally.
> + {3047C2AC-5E8E-4C55-A1CB-EAAD0A88861B}
> +*/
> +extern EFI_GUID gMrcSchemaListHobGuid;
> +
> +#pragma pack(push, 1)
> +
> +
> +///
> +/// SSA results buffer header.
> +///
> +typedef struct {
> +  UINT32  Revision;
> +  BOOLEAN TransferMode;
> +  struct {
> +    UINT32   Reserved;
> +    UINT32   MetadataSize;
> +    EFI_GUID MetadataType;
> +  } MdBlock;
> +  struct {
> +    UINT32   Reserved;
> +    EFI_GUID ResultType;
> +    UINT32   ResultElementSize;
> +    INT32    ResultCapacity;
> +    INT32    ResultElementCount;
> +  } RsBlock;
> +} RESULTS_DATA_HDR;
> +
> +// start auto-generated by the BSSA CCK sourced from the result xml files.
> +typedef enum {
> +  DisableScrambler = 0,
> +  EnableScrambler = 1,
> +  DontTouchScrambler = 2,
> +  SCRAMBLER_OVERRIDE_MODE_DELIM = MRC_INT32_MAX
> +} SCRAMBLER_OVERRIDE_MODE;
> +
> +typedef struct _RMT_RESULT_METADATA {
> +  BOOLEAN EnableCtlAllMargin;
> +  UINT16 SinglesBurstLength;
> +  UINT32 SinglesLoopCount;
> +  UINT16 TurnaroundsBurstLength;
> +  UINT32 TurnaroundsLoopCount;
> +  SCRAMBLER_OVERRIDE_MODE ScramblerOverrideMode;
> +  UINT8 PiStepUnit[2];
> +  UINT16 RxVrefStepUnit[2];
> +  UINT16 TxVrefStepUnit[2][2];
> +  UINT16 CmdVrefStepUnit[2][2];
> +  UINT8 MajorVer;
> +  UINT8 MinorVer;
> +  UINT8 RevVer;
> +  UINT32 BuildVer;
> +  UINT16 ResultEleCount;
> +} RMT_RESULT_METADATA;
> +
> +
> +typedef struct _RMT_RESULT_ROW_HEADER {
> +  UINT32 ResultType : 5;
> +  UINT32 Socket : 3;
> +  UINT32 Controller : 2;
> +  UINT32 Channel : 3;
> +  UINT32 DimmA : 1;
> +  UINT32 RankA : 3;
> +  UINT32 DimmB : 1;
> +  UINT32 RankB : 3;
> +  UINT32 Lane : 8;
> +  UINT32 IoLevel : 1;
> +  UINT32 Reserved : 2;
> +} RMT_RESULT_ROW_HEADER;
> +
> +typedef struct _RMT_RESULT_COLUMNS {
> +  RMT_RESULT_ROW_HEADER Header;
> +  UINT8 Margin[4][2];
> +} RMT_RESULT_COLUMNS;
> +
> +// end of auto-generated by the BSSA CCK sourced from the result xml files.
> +
> +typedef struct _BASE_RMT_RESULT {
> +  RESULTS_DATA_HDR              ResultsHeader;
> +  RMT_RESULT_METADATA           Metadata;
> +  RMT_RESULT_COLUMNS            Rows[1];
> +} BASE_RMT_RESULT;
> +
> +
> +typedef struct {
> +  UINT32                      Data1;
> +  UINT16                      Data2;
> +  UINT16                      Data3;
> +  UINT8                       Data4[8];
> +} BDAT_EFI_GUID;
> +
> +typedef struct {
> +  UINT16  HobType;
> +  UINT16  HobLength;
> +  UINT32  Reserved;
> +} BDAT_HOB_GENERIC_HEADER;
> +
> +typedef struct {
> +  BDAT_HOB_GENERIC_HEADER  Header;
> +  BDAT_EFI_GUID            Name;
> +  ///
> +  /// Guid specific data goes here
> +  ///
> +} BDAT_HOB_GUID_TYPE;
> +
> +typedef struct {
> +  BDAT_EFI_GUID               SchemaId;                         ///< The GUID
> uniquely identifies the format of the data contained within the structure.
> +  UINT32                      DataSize;                         ///< The total size of the
> memory block, including both the header as well as the schema specific data.
> +  UINT16                      Crc16;                            ///< Crc16 is computed in
> the same manner as the field in the BDAT_HEADER_STRUCTURE.
> +} MRC_BDAT_SCHEMA_HEADER_STRUCTURE;
> +
> +typedef struct {
> +  MRC_BDAT_SCHEMA_HEADER_STRUCTURE SchemaHeader;
> ///< The schema header.
> +  BASE_RMT_RESULT          RMT_RESULTS_WITH_META_COLUMNS;
> +} BDAT_MEMORY_DATA_STRUCTURE;
> +
> +typedef struct {
> +  BDAT_HOB_GUID_TYPE          HobGuidType;
> +  BDAT_MEMORY_DATA_STRUCTURE  MemorySchema;
> +} BDAT_MEMORY_DATA_HOB;
> +
> +#pragma pack (pop)
> +
> +typedef struct {
> +  BDAT_HOB_GUID_TYPE          HobGuidType;
> +  UINT16                      SchemaHobCount;
> +  UINT16                      Reserved;
> +  BDAT_EFI_GUID
> SchemaHobGuids[MAX_SCHEMA_LIST_LENGTH];
> +} MRC_BDAT_SCHEMA_LIST_HOB;
> +
> +#endif //_MrcRmtData_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> new file mode 100644
> index 0000000000..45de5084c0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcSpdData.h
> @@ -0,0 +1,1167 @@
> +/** @file
> +  SPD data format header file.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MrcSpdData_h_
> +#define _MrcSpdData_h_
> +#pragma pack (push, 1)
> +
> +#include "MrcTypes.h"
> +
> +#define MAX_XMP_PROFILES  (2)
> +#define SPD3_MANUF_SIZE   (SPD3_MANUF_END - SPD3_MANUF_START + 1)
> ///< The size of the SPD manufacturing data.
> +#define SPD4_MANUF_SIZE   (SPD4_MANUF_END - SPD4_MANUF_START + 1)
> ///< The size of the SPD manufacturing data.
> +#define SPDLP_MANUF_SIZE  (SPDLP_MANUF_END - SPDLP_MANUF_START +
> 1) ///< The size of the SPD manufacturing data
> +
> +typedef union {
> +  struct {
> +    UINT8  BytesUsed                           :  4; ///< Bits 3:0
> +    UINT8  BytesTotal                          :  3; ///< Bits 6:4
> +    UINT8  CrcCoverage                         :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_DEVICE_DESCRIPTION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Minor                               :  4; ///< Bits 3:0
> +    UINT8  Major                               :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_REVISION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Type                                :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_DRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ModuleType                          :  4; ///< Bits 3:0
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Density                             :  4; ///< Bits 3:0
> +    UINT8  BankAddress                         :  3; ///< Bits 6:4
> +    UINT8                                      :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ColumnAddress                       :  3; ///< Bits 2:0
> +    UINT8  RowAddress                          :  3; ///< Bits 5:3
> +    UINT8                                      :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_ADDRESSING_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  OperationAt1_50                     :  1; ///< Bits 0:0
> +    UINT8  OperationAt1_35                     :  1; ///< Bits 1:1
> +    UINT8  OperationAt1_25                     :  1; ///< Bits 2:2
> +    UINT8                                      :  5; ///< Bits 7:3
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  SdramDeviceWidth                    :  3; ///< Bits 2:0
> +    UINT8  RankCount                           :  3; ///< Bits 5:3
> +    UINT8                                      :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_ORGANIZATION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  PrimaryBusWidth                     :  3; ///< Bits 2:0
> +    UINT8  BusWidthExtension                   :  2; ///< Bits 4:3
> +    UINT8                                      :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Divisor                             :  4; ///< Bits 3:0
> +    UINT8  Dividend                            :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_FINE_TIMEBASE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Dividend                            :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Divisor                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT;
> +
> +typedef struct {
> +  SPD_MEDIUM_TIMEBASE_DIVIDEND_STRUCT Dividend; ///< Medium
> Timebase (MTB) Dividend
> +  SPD_MEDIUM_TIMEBASE_DIVISOR_STRUCT  Divisor;  ///< Medium
> Timebase (MTB) Divisor
> +} SPD_MEDIUM_TIMEBASE;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCKmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TCK_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16 CL4                                 :  1; ///< Bits 0:0
> +    UINT16 CL5                                 :  1; ///< Bits 1:1
> +    UINT16 CL6                                 :  1; ///< Bits 2:2
> +    UINT16 CL7                                 :  1; ///< Bits 3:3
> +    UINT16 CL8                                 :  1; ///< Bits 4:4
> +    UINT16 CL9                                 :  1; ///< Bits 5:5
> +    UINT16 CL10                                :  1; ///< Bits 6:6
> +    UINT16 CL11                                :  1; ///< Bits 7:7
> +    UINT16 CL12                                :  1; ///< Bits 8:8
> +    UINT16 CL13                                :  1; ///< Bits 9:9
> +    UINT16 CL14                                :  1; ///< Bits 10:10
> +    UINT16 CL15                                :  1; ///< Bits 11:11
> +    UINT16 CL16                                :  1; ///< Bits 12:12
> +    UINT16 CL17                                :  1; ///< Bits 13:13
> +    UINT16 CL18                                :  1; ///< Bits 14:14
> +    UINT16                                     :  1; ///< Bits 15:15
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tAAmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TAA_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tWRmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TWR_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRCDmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRCD_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRRDmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRRD_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRPmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRP_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRPab                               :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRP_AB_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRPabFine                            :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRP_AB_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRPpb                               :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRP_PB_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRPpbFine                            :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRP_PB_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16  tRFCab                             :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TRFC_AB_MTB_STRUCT;
> +
> +typedef union {
> +struct {
> +    UINT16  tRFCpb                             :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TRFC_PB_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRASminUpper                        :  4; ///< Bits 3:0
> +    UINT8  tRCminUpper                         :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRAS_TRC_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRASmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRAS_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRCmin                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRC_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16 tRFCmin                             :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TRFC_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tWTRmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TWTR_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tRTPmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TRTP_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tFAWminUpper                        :  4; ///< Bits 3:0
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TFAW_MIN_MTB_UPPER_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tFAWmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TFAW_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCWLmin                             :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_TCWL_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  NMode                               :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SYSTEM_COMMAND_RATE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT16 tREFImin                            :  16; ///< Bits 15:0
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_TREFI_MIN_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  RZQ6                                :  1; ///< Bits 0:0
> +    UINT8  RZQ7                                :  1; ///< Bits 1:1
> +    UINT8                                      :  5; ///< Bits 6:2
> +    UINT8  DllOff                              :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_OPTIONAL_FEATURES_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ExtendedTemperatureRange            :  1; ///< Bits 0:0
> +    UINT8  ExtendedTemperatureRefreshRate      :  1; ///< Bits 1:1
> +    UINT8  AutoSelfRefresh                     :  1; ///< Bits 2:2
> +    UINT8  OnDieThermalSensor                  :  1; ///< Bits 3:3
> +    UINT8                                      :  3; ///< Bits 6:4
> +    UINT8  PartialArraySelfRefresh             :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ThermalSensorAccuracy               :  7; ///< Bits 6:0
> +    UINT8  ThermalSensorPresence               :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_MODULE_THERMAL_SENSOR_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  NonStandardDeviceDescription        :  7; ///< Bits 6:0
> +    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_SDRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8                                      :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_AUTO_SELF_REFRESH_PERF_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tCKminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TCK_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tAAminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TAA_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRCDminFine                          :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRCD_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRPminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRP_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRCminFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRC_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tMACencoding                        :  4; ///< Bits 3:0
> +    UINT8  tMAWencoding                        :  2; ///< Bits 5:4
> +    UINT8  Reserved                            :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_PTRR_SUPPORT_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tRRDminFine                          :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_TRRD_MIN_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  FrontThickness                      :  4; ///< Bits 3:0
> +    UINT8  BackThickness                       :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_MODULE_NOMINAL_THICKNESS;
> +
> +typedef union {
> +  struct {
> +    UINT8  Card                                :  5; ///< Bits 4:0
> +    UINT8  Revision                            :  2; ///< Bits 6:5
> +    UINT8  Extension                           :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_REFERENCE_RAW_CARD;
> +
> +typedef union {
> +  struct {
> +    UINT8  MappingRank1                        :  1; ///< Bits 0:0
> +    UINT8                                      :  7; ///< Bits 7:1
> +  } Bits;
> +  UINT8  Data;
> +} SPD_UNBUF_ADDRESS_MAPPING;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8                                      :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  FrontThickness                      :  4; ///< Bits 3:0
> +    UINT8  BackThickness                       :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_MODULE_NOMINAL_THICKNESS;
> +
> +typedef union {
> +  struct {
> +    UINT8  Card                                :  5; ///< Bits 4:0
> +    UINT8  Revision                            :  2; ///< Bits 6:5
> +    UINT8  Extension                           :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_REFERENCE_RAW_CARD;
> +
> +typedef union {
> +  struct {
> +    UINT8  RegisterCount                       :  2; ///< Bits 1:0
> +    UINT8  DramRowCount                        :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_RDIMM_MODULE_ATTRIBUTES;
> +
> +typedef union {
> +  struct {
> +    UINT16 ContinuationCount                   :  7; ///< Bits 6:0
> +    UINT16 ContinuationParity                  :  1; ///< Bits 7:7
> +    UINT16 LastNonZeroByte                     :  8; ///< Bits 15:8
> +  } Bits;
> +  UINT16 Data;
> +  UINT8  Data8[2];
> +} SPD_MANUFACTURER_ID_CODE;
> +
> +typedef struct {
> +  UINT8  Year;                                 ///< Year represented in BCD (00h =
> 2000)
> +  UINT8  Week;                                 ///< Year represented in BCD (47h =
> week 47)
> +} SPD_MANUFACTURING_DATE;
> +
> +typedef union {
> +  UINT32 Data;
> +  UINT16 SerialNumber16[2];
> +  UINT8  SerialNumber8[4];
> +} SPD_MANUFACTURER_SERIAL_NUMBER;
> +
> +typedef struct {
> +  UINT8 Location;                              ///< Module Manufacturing Location
> +} SPD_MANUFACTURING_LOCATION;
> +
> +typedef struct {
> +  SPD_MANUFACTURER_ID_CODE            IdCode;                   ///< Module
> Manufacturer ID Code
> +  SPD_MANUFACTURING_LOCATION          Location;                 ///<
> Module Manufacturing Location
> +  SPD_MANUFACTURING_DATE              Date;                     ///< Module
> Manufacturing Year, in BCD (range: 2000-2255)
> +  SPD_MANUFACTURER_SERIAL_NUMBER      SerialNumber;             ///<
> Module Serial Number
> +} SPD_UNIQUE_MODULE_ID;
> +
> +typedef union {
> +  UINT16 Crc[1];
> +  UINT8  Data8[2];
> +} SPD_CYCLIC_REDUNDANCY_CODE;
> +
> +typedef union {
> +  struct {
> +    UINT8  ProfileEnable1                :  1;                     ///< Bits 0:0
> +    UINT8  ProfileEnable2                :  1;                     ///< Bits 1:1
> +    UINT8  ProfileConfig1                :  2;                     ///< Bits 3:2
> +    UINT8  ProfileConfig2                :  2;                     ///< Bits 5:4
> +    UINT8                                :  2;                     ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_XMP_ORG_CONFIG;
> +
> +typedef struct {
> +  UINT16                              XmpId;                    ///< 176-177 XMP
> Identification String
> +  SPD_XMP_ORG_CONFIG                  XmpOrgConf;               ///< 178 XMP
> Organization & Configuration
> +  SPD_REVISION_STRUCT                 XmpRevision;              ///< 179 XMP
> Revision
> +  SPD_MEDIUM_TIMEBASE
> MediumTimeBase[MAX_XMP_PROFILES]; ///< 180-183 Medium Timebase
> (MTB)
> +  SPD_FINE_TIMEBASE_STRUCT            FineTimeBase;             ///< 184
> Fine Timebase (FTB) Dividend / Divisor
> +} SPD_EXTREME_MEMORY_PROFILE_HEADER;
> +
> +typedef union {
> +  struct {
> +    UINT8  Decimal : 5;
> +    UINT8  Integer : 2;
> +    UINT8          : 1;
> +  } Bits;
> +  UINT8 Data;
> +} SPD_VDD_VOLTAGE_LEVEL_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Decimal : 7;
> +    UINT8  Integer : 1;
> +  } Bits;
> +  UINT8 Data;
> +} SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0;
> +
> +typedef union {
> +  struct {
> +    UINT8  Fine                                :  2; ///< Bits 1:0
> +    UINT8  Medium                              :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_TIMEBASE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT32 CL7                                 :  1; ///< Bits 0:0
> +    UINT32 CL8                                 :  1; ///< Bits 1:1
> +    UINT32 CL9                                 :  1; ///< Bits 2:2
> +    UINT32 CL10                                :  1; ///< Bits 3:3
> +    UINT32 CL11                                :  1; ///< Bits 4:4
> +    UINT32 CL12                                :  1; ///< Bits 5:5
> +    UINT32 CL13                                :  1; ///< Bits 6:6
> +    UINT32 CL14                                :  1; ///< Bits 7:7
> +    UINT32 CL15                                :  1; ///< Bits 8:8
> +    UINT32 CL16                                :  1; ///< Bits 9:9
> +    UINT32 CL17                                :  1; ///< Bits 10:10
> +    UINT32 CL18                                :  1; ///< Bits 11:11
> +    UINT32 CL19                                :  1; ///< Bits 12:12
> +    UINT32 CL20                                :  1; ///< Bits 13:13
> +    UINT32 CL21                                :  1; ///< Bits 14:14
> +    UINT32 CL22                                :  1; ///< Bits 15:15
> +    UINT32 CL23                                :  1; ///< Bits 16:16
> +    UINT32 CL24                                :  1; ///< Bits 17:17
> +    UINT32                                     :  14; ///< Bits 31:18
> +  } Bits;
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} SPD4_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef struct {
> +  SPD_VDD_VOLTAGE_LEVEL_STRUCT        Vdd;                      ///< 185, 220
> XMP Module VDD Voltage Level
> +  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 186, 221
> XMP SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 187, 222
> XMP Minimum CAS Latency Time (tAAmin)
> +  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///<
> 188-189, 223-224 XMP CAS Latencies Supported, Least Significant Byte
> +  SPD_TCWL_MIN_MTB_STRUCT             tCWLmin;                  ///< 190,
> 225 XMP Minimum CAS Write Latency Time (tCWLmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 191, 226
> XMP Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 192,
> 227 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 193,
> 228 XMP Minimum Write Recovery Time (tWRmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 194, 229 XMP Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 195, 230
> XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 196, 231
> XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant
> Byte
> +  SPD_TREFI_MIN_MTB_STRUCT            tREFImin;                 ///< 197-198,
> 232-233 XMP Maximum tREFI Time (Average Periodic Refresh Interval), Least
> Significant Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 199-200,
> 234-235 XMP Minimum Refresh Recovery Delay Time (tRFCmin), Least
> Significant Byte
> +  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 201, 236
> XMP Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 202,
> 237 XMP Minimum Row Active to Row Active Delay Time (tRRDmin)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 203, 238 XMP Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 204,
> 239 XMP Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 205,
> 240 XMP Minimum Internal Write to Read Command Delay Time (tWTRmin)
> +  UINT8                               Reserved1[207 - 206 + 1]; ///< 206-207, 241-242
> XMP Reserved
> +  SPD_SYSTEM_COMMAND_RATE_STRUCT      SystemCmdRate;            ///<
> 208, 243 XMP System ADD/CMD Rate (1N or 2N mode)
> +  SPD_AUTO_SELF_REFRESH_PERF_STRUCT   AsrPerf;                  ///< 209,
> 244 XMP SDRAM Auto Self Refresh Performance (Sub 1x Refresh and IDD6
> impact)
> +  UINT8                               VoltageLevel;             ///< 210, 245 XMP
> Memory Controller Voltage Level
> +  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 211, 246
> XMP Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 212, 247
> XMP Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 213, 248
> XMP Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 214,
> 249 XMP Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 215, 250
> XMP Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  UINT8                               Reserved2[218 - 216 + 1]; ///< 216-218, 251-253
> XMP Reserved
> +  UINT8                               VendorPersonality;        ///< 219, 254 XMP
> Vendor Personality
> +} SPD_EXTREME_MEMORY_PROFILE_DATA;
> +
> +typedef struct {
> +  SPD_EXTREME_MEMORY_PROFILE_HEADER   Header;                   ///<
> 176-184 XMP header
> +  SPD_EXTREME_MEMORY_PROFILE_DATA     Data[MAX_XMP_PROFILES];
> ///< 185-254 XMP profiles
> +} SPD_EXTREME_MEMORY_PROFILE;
> +
> +typedef struct {
> +  UINT16                              XmpId;                        ///< 384-385 XMP
> Identification String
> +  SPD_XMP_ORG_CONFIG                  XmpOrgConf;                   ///< 386
> XMP Organization & Configuration
> +  SPD_REVISION_STRUCT                 XmpRevision;                  ///< 387
> XMP Revision
> +  SPD4_TIMEBASE_STRUCT                TimeBase[MAX_XMP_PROFILES];
> ///< 388-389 Medium and Fine Timebase
> +  UINT8                               Reserved[392 - 390 + 1];     ///< 390-392
> Reserved
> +} SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0;
> +
> +typedef struct {
> +  SPD_VDD_VOLTAGE_LEVEL_STRUCT_2_0    Vdd;                      ///< 393,
> 440 XMP Module VDD Voltage Level
> +  UINT8                               Reserved1[395 - 394 + 1]; ///< 394-395, 441-442
> XMP Reserved
> +  SPD_TCK_MIN_MTB_STRUCT              tCKAVGmin;                ///< 396,
> 443 XMP SDRAM Minimum Cycle Time (tCKAVGmin)
> +  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///<
> 397-400, 444-447 XMP CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 401, 448
> XMP Minimum CAS Latency Time (tAAmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 402,
> 449 XMP Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 403, 450
> XMP Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 404, 451 XMP Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 405, 452
> XMP Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 406, 453
> XMP Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant
> Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 407-408,
> 454-455 XMP Minimum Refresh Recovery Delay Time (tRFC1min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 409-410,
> 456-457 XMP Minimum Refresh Recovery Delay Time (tRFC2min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 411-412,
> 458-459 XMP Minimum Refresh Recovery Delay Time (tRFC4min)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 413, 460 Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 414,
> 461 Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 415,
> 462 Minimum Activate to Activate Delay Time (tRRD_Smin), different bank
> group
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 416,
> 463 Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
> +  UINT8                               Reserved2[424 - 417 + 1]; ///< 417-424, 464-471
> XMP Reserved
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 425,
> 472 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin),
> different bank group
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 426,
> 473 Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin),
> same bank group
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 427, 474
> Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 428, 475
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 429,
> 476 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 430, 477
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_TCK_MIN_FTB_STRUCT              tCKAVGminFine;            ///< 431,
> 478 Fine Offset for SDRAM Maximum Cycle Time (tCKAVGmin)
> +  UINT8                               Reserved3[439 - 432 + 1]; ///< 432-439, 479-486
> XMP Reserved
> +} SPD_EXTREME_MEMORY_PROFILE_DATA_2_0;
> +
> +typedef struct {
> +  SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0      Header;
> ///< 384-392 XMP header
> +  SPD_EXTREME_MEMORY_PROFILE_DATA_2_0
> Data[MAX_XMP_PROFILES];   ///< 393-486 XMP profiles
> +} SPD_EXTREME_MEMORY_PROFILE_2_0;
> +
> +typedef struct {
> +  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> +  SPD_REVISION_STRUCT                 Revision;                 ///< 1   SPD
> Revision
> +  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2
> DRAM Device Type
> +  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3
> Module Type
> +  SPD_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;
> ///< 4   SDRAM Density and Banks
> +  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5
> SDRAM Addressing
> +  SPD_MODULE_NOMINAL_VOLTAGE_STRUCT   ModuleNominalVoltage;
> ///< 6   Module Nominal Voltage, VDD
> +  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///<
> 7   Module Organization
> +  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;
> ///< 8   Module Memory Bus Width
> +  SPD_FINE_TIMEBASE_STRUCT            FineTimebase;             ///< 9   Fine
> Timebase (FTB) Dividend / Divisor
> +  SPD_MEDIUM_TIMEBASE                 MediumTimebase;           ///< 10-11
> Medium Timebase (MTB) Dividend
> +  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 12
> SDRAM Minimum Cycle Time (tCKmin)
> +  UINT8                               Reserved1;                ///< 13  Reserved
> +  SPD_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;             ///<
> 14-15 CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 16
> Minimum CAS Latency Time (tAAmin)
> +  SPD_TWR_MIN_MTB_STRUCT              tWRmin;                   ///< 17
> Minimum Write Recovery Time (tWRmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 18
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRDmin;                  ///< 19
> Minimum Row Active to Row Active Delay Time (tRRDmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 20
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 21  Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 22
> Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 23
> Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFCmin;                  ///< 24-25
> Minimum Refresh Recovery Delay Time (tRFCmin)
> +  SPD_TWTR_MIN_MTB_STRUCT             tWTRmin;                  ///< 26
> Minimum Internal Write to Read Command Delay Time (tWTRmin)
> +  SPD_TRTP_MIN_MTB_STRUCT             tRTPmin;                  ///< 27
> Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 28  Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 29
> Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_SDRAM_OPTIONAL_FEATURES_STRUCT  SdramOptionalFeatures;
> ///< 30  SDRAM Optional Features
> +  SPD_SDRAM_THERMAL_REFRESH_STRUCT    ThermalAndRefreshOptions;
> ///< 31  SDRAMThermalAndRefreshOptions
> +  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;
> ///< 32  Module Thermal Sensor
> +  SPD_SDRAM_DEVICE_TYPE_STRUCT        SdramDeviceType;          ///< 33
> SDRAM Device Type
> +  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 34  Fine
> Offset for SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 35  Fine
> Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 36
> Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 37
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 38  Fine
> Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  SPD_TRP_AB_MTB_STRUCT               tRPab;                    ///< 39
> Minimum Row Precharge Delay Time for all banks (tRPab)
> +  SPD_TRP_AB_FTB_STRUCT               tRPabFine;                ///< 40  Fine
> Offset for Minimum Row Precharge Delay Time for all banks (tRPab)
> +  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 41 -
> pTRR support with TMAC value
> +  UINT8                               Reserved3[59 - 42 + 1];   ///< 42 - 59 Reserved
> +} SPD_GENERAL_SECTION;
> +
> +typedef struct {
> +  SPD_UNBUF_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;
> ///< 60 Module Nominal Height
> +  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 61 Module Maximum Thickness
> +  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 62 Reference Raw Card Used
> +  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;
> ///< 63 Address Mapping from Edge Connector to DRAM
> +  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
> +} SPD_MODULE_UNBUFFERED;
> +
> +typedef struct {
> +  SPD_RDIMM_MODULE_NOMINAL_HEIGHT     ModuleNominalHeight;
> ///< 60 Module Nominal Height
> +  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 61 Module Maximum Thickness
> +  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 62 Reference Raw Card Used
> +  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///<
> 63 DIMM Module Attributes
> +  UINT8                               Reserved[116 - 64 + 1];   ///< 64-116 Reserved
> +} SPD_MODULE_REGISTERED;
> +
> +typedef union {
> +  SPD_MODULE_UNBUFFERED               Unbuffered;
> +  SPD_MODULE_REGISTERED               Registered;
> +} SPD_MODULE_SPECIFIC;
> +
> +typedef struct {
> +  UINT8                          ModulePartNumber[145 - 128 + 1];        ///<
> 128-145 Module Part Number
> +} SPD_MODULE_PART_NUMBER;
> +
> +typedef struct {
> +  UINT8                          ModuleRevisionCode[147 - 146 + 1];      ///<
> 146-147 Module Revision Code
> +} SPD_MODULE_REVISION_CODE;
> +
> +typedef struct {
> +  UINT8                          ManufactureSpecificData[175 - 150 + 1]; ///<
> 150-175 Manufacturer's Specific Data
> +} SPD_MANUFACTURE_SPECIFIC;
> +
> +///
> +/// DDR3 Serial Presence Detect structure
> +///
> +typedef struct {
> +  SPD_GENERAL_SECTION         General;                                ///< 0-59
> General Section
> +  SPD_MODULE_SPECIFIC         Module;                                 ///< 60-116
> Module-Specific Section
> +  SPD_UNIQUE_MODULE_ID        ModuleId;                               ///<
> 117-125 Unique Module ID
> +  SPD_CYCLIC_REDUNDANCY_CODE  Crc;                                    ///<
> 126-127 Cyclical Redundancy Code (CRC)
> +  SPD_MODULE_PART_NUMBER      ModulePartNumber;
> ///< 128-145 Module Part Number
> +  SPD_MODULE_REVISION_CODE    ModuleRevisionCode;
> ///< 146-147 Module Revision Code
> +  SPD_MANUFACTURER_ID_CODE    DramIdCode;                             ///<
> 148-149 Dram Manufacturer ID Code
> +  SPD_MANUFACTURE_SPECIFIC    ManufactureSpecificData;                ///<
> 150-175 Manufacturer's Specific Data
> +  SPD_EXTREME_MEMORY_PROFILE  Xmp;                                    ///<
> 176-254 Intel(r) Extreme Memory Profile support
> +  UINT8                       Reserved;                               ///< 255 Reserved
> +} MrcSpdDdr3;
> +
> +typedef union {
> +  struct {
> +    UINT8  Density                             :  4; ///< Bits 3:0
> +    UINT8  BankAddress                         :  2; ///< Bits 5:4
> +    UINT8  BankGroup                           :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  SignalLoading                       :  2; ///< Bits 1:0
> +    UINT8                                      :  2; ///< Bits 3:2
> +    UINT8  DieCount                            :  3; ///< Bits 6:4
> +    UINT8  SdramDeviceType                     :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_SDRAM_DEVICE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
> +    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
> +    UINT8                                      :  6; ///< Bits 7:2
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCKmax                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_TCK_MAX_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tCKmaxFine                          :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD4_TCK_MAX_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8                                      :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD4_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef struct {
> +  SPD_DEVICE_DESCRIPTION_STRUCT       Description;              ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> +  SPD_REVISION_STRUCT                 Revision;                 ///< 1       SPD
> Revision
> +  SPD_DRAM_DEVICE_TYPE_STRUCT         DramDeviceType;           ///< 2
> DRAM Device Type
> +  SPD_MODULE_TYPE_STRUCT              ModuleType;               ///< 3
> Module Type
> +  SPD4_SDRAM_DENSITY_BANKS_STRUCT     SdramDensityAndBanks;
> ///< 4       SDRAM Density and Banks
> +  SPD_SDRAM_ADDRESSING_STRUCT         SdramAddressing;          ///< 5
> SDRAM Addressing
> +  SPD4_SDRAM_DEVICE_TYPE_STRUCT       SdramDeviceType;          ///< 6
> SDRAM Device Type
> +  SPD_PTRR_SUPPORT_STRUCT             pTRRsupport;              ///< 7
> pTRR support with TMAC value
> +  SPD4_SDRAM_THERMAL_REFRESH_STRUCT   ThermalAndRefreshOptions;
> ///< 8       SDRAM Thermal and Refresh Options
> +  UINT8                               Reserved0[10 - 9 + 1];    ///< 9-10    Reserved
> +  SPD4_MODULE_NOMINAL_VOLTAGE_STRUCT  ModuleNominalVoltage;
> ///< 11      Module Nominal Voltage, VDD
> +  SPD_MODULE_ORGANIZATION_STRUCT      ModuleOrganization;       ///<
> 12      Module Organization
> +  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT  ModuleMemoryBusWidth;
> ///< 13      Module Memory Bus Width
> +  SPD_MODULE_THERMAL_SENSOR_STRUCT    ModuleThermalSensor;
> ///< 14      Module Thermal Sensor
> +  UINT8                               Reserved1[16 - 15 + 1];   ///< 15-16   Reserved
> +  SPD4_TIMEBASE_STRUCT                Timebase;                 ///< 17
> Timebases
> +  SPD_TCK_MIN_MTB_STRUCT              tCKmin;                   ///< 18
> SDRAM Minimum Cycle Time (tCKmin)
> +  SPD4_TCK_MAX_MTB_STRUCT             tCKmax;                   ///< 19
> SDRAM Maximum Cycle Time (tCKmax)
> +  SPD4_CAS_LATENCIES_SUPPORTED_STRUCT CasLatencies;             ///<
> 20-23   CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT              tAAmin;                   ///< 24
> Minimum CAS Latency Time (tAAmin)
> +  SPD_TRCD_MIN_MTB_STRUCT             tRCDmin;                  ///< 25
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_MIN_MTB_STRUCT              tRPmin;                   ///< 26
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRAS_TRC_MIN_MTB_STRUCT         tRASMintRCMinUpper;       ///<
> 27      Upper Nibbles for tRAS and tRC
> +  SPD_TRAS_MIN_MTB_STRUCT             tRASmin;                  ///< 28
> Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
> +  SPD_TRC_MIN_MTB_STRUCT              tRCmin;                   ///< 29
> Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC1min;                 ///< 30-31
> Minimum Refresh Recovery Delay Time (tRFC1min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC2min;                 ///< 32-33
> Minimum Refresh Recovery Delay Time (tRFC2min)
> +  SPD_TRFC_MIN_MTB_STRUCT             tRFC4min;                 ///< 34-35
> Minimum Refresh Recovery Delay Time (tRFC4min)
> +  SPD_TFAW_MIN_MTB_UPPER_STRUCT       tFAWMinUpper;             ///<
> 36      Upper Nibble for tFAW
> +  SPD_TFAW_MIN_MTB_STRUCT             tFAWmin;                  ///< 37
> Minimum Four Activate Window Delay Time (tFAWmin)
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Smin;                ///< 38
> Minimum Activate to Activate Delay Time (tRRD_Smin), different bank group
> +  SPD_TRRD_MIN_MTB_STRUCT             tRRD_Lmin;                ///< 39
> Minimum Activate to Activate Delay Time (tRRD_Lmin), same bank group
> +  UINT8                               Reserved2[117 - 40 + 1];  ///< 40-117
> Reserved
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_LminFine;            ///< 118
> Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Lmin),
> different bank group
> +  SPD_TRRD_MIN_FTB_STRUCT             tRRD_SminFine;            ///< 119
> Fine Offset for Minimum Activate to Activate Delay Time (tRRD_Smin), same
> bank group
> +  SPD_TRC_MIN_FTB_STRUCT              tRCminFine;               ///< 120
> Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
> +  SPD_TRP_MIN_FTB_STRUCT              tRPminFine;               ///< 121
> Minimum Row Precharge Delay Time (tRPmin)
> +  SPD_TRCD_MIN_FTB_STRUCT             tRCDminFine;              ///< 122
> Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TAA_MIN_FTB_STRUCT              tAAminFine;               ///< 123
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD4_TCK_MAX_FTB_STRUCT             tCKmaxFine;               ///< 124
> Fine Offset for SDRAM Minimum Cycle Time (tCKmax)
> +  SPD_TCK_MIN_FTB_STRUCT              tCKminFine;               ///< 125
> Fine Offset for SDRAM Maximum Cycle Time (tCKmin)
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 126-127
> Cyclical Redundancy Code (CRC)
> +} SPD4_BASE_SECTION;
> +
> +typedef struct {
> +  SPD4_UNBUF_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;
> ///< 128     Module Nominal Height
> +  SPD_UNBUF_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 129     Module Maximum Thickness
> +  SPD_UNBUF_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 130     Reference Raw Card Used
> +  SPD_UNBUF_ADDRESS_MAPPING           AddressMappingEdgeConn;
> ///< 131     Address Mapping from Edge Connector to DRAM
> +  UINT8                               Reserved[253 - 132 + 1];  ///< 132-253
> Reserved
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255
> Cyclical Redundancy Code (CRC)
> +} SPD4_MODULE_UNBUFFERED;
> +
> +typedef struct {
> +  SPD4_RDIMM_MODULE_NOMINAL_HEIGHT    ModuleNominalHeight;
> ///< 128     Module Nominal Height
> +  SPD_RDIMM_MODULE_NOMINAL_THICKNESS  ModuleMaximumThickness;
> ///< 129     Module Maximum Thickness
> +  SPD_RDIMM_REFERENCE_RAW_CARD        ReferenceRawCardUsed;
> ///< 130     Reference Raw Card Used
> +  SPD_RDIMM_MODULE_ATTRIBUTES         DimmModuleAttributes;     ///<
> 131     DIMM Module Attributes
> +  UINT8                               Reserved[253 - 132 + 1];  ///< 253-132
> Reserved
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 254-255
> Cyclical Redundancy Code (CRC)
> +} SPD4_MODULE_REGISTERED;
> +
> +typedef union {
> +  SPD4_MODULE_UNBUFFERED              Unbuffered;               ///<
> 128-255 Unbuffered Memory Module Types
> +  SPD4_MODULE_REGISTERED              Registered;               ///< 128-255
> Registered Memory Module Types
> +} SPD4_MODULE_SPECIFIC;
> +
> +typedef struct {
> +  UINT8                               ModulePartNumber[348 - 329 + 1]; ///<
> 329-348 Module Part Number
> +} SPD4_MODULE_PART_NUMBER;
> +
> +typedef struct {
> +  UINT8                               ManufactureSpecificData[381 - 353 + 1]; ///<
> 353-381 Manufacturer's Specific Data
> +} SPD4_MANUFACTURE_SPECIFIC;
> +
> +typedef UINT8                         SPD4_MODULE_REVISION_CODE;///< 349
> Module Revision Code
> +typedef UINT8                         SPD4_DRAM_STEPPING;       ///< 352
> Dram Stepping
> +
> +typedef struct {
> +  SPD_UNIQUE_MODULE_ID                ModuleId;                 ///< 320-328
> Unique Module ID
> +  SPD4_MODULE_PART_NUMBER             ModulePartNumber;         ///<
> 329-348 Module Part Number
> +  SPD4_MODULE_REVISION_CODE           ModuleRevisionCode;       ///<
> 349     Module Revision Code
> +  SPD_MANUFACTURER_ID_CODE            DramIdCode;               ///<
> 350-351 Dram Manufacturer ID Code
> +  SPD4_DRAM_STEPPING                  DramStepping;             ///< 352
> Dram Stepping
> +  SPD4_MANUFACTURE_SPECIFIC           ManufactureSpecificData;  ///<
> 353-381 Manufacturer's Specific Data
> +  SPD_CYCLIC_REDUNDANCY_CODE          Crc;                      ///< 382-383
> Cyclical Redundancy Code (CRC)
> +} SPD4_MANUFACTURING_DATA;
> +
> +typedef union {
> +  SPD_EXTREME_MEMORY_PROFILE_2_0      Xmp;                      ///<
> 384-463 Intel(r) Extreme Memory Profile support
> +  UINT8                               Reserved0[511 - 384 + 1]; ///< 384-511
> Unbuffered Memory Module Types
> +} SPD4_END_USER_SECTION;
> +
> +///
> +/// DDR4 Serial Presence Detect structure
> +///
> +typedef struct {
> +  SPD4_BASE_SECTION                   Base;                     ///< 0-127   Base
> Configuration and DRAM Parameters
> +  SPD4_MODULE_SPECIFIC                Module;                   ///< 128-255
> Module-Specific Section
> +  UINT8                               Reserved0[319 - 256 + 1]; ///< 256-319
> Reserved
> +  SPD4_MANUFACTURING_DATA             ManufactureInfo;          ///<
> 320-383 Manufacturing Information
> +  SPD4_END_USER_SECTION               EndUser;                  ///< 384-511
> End User Programmable
> +} MrcSpdDdr4;
> +
> +typedef union {
> +  struct {
> +    UINT8  Fine                                :  2; ///< Bits 1:0
> +    UINT8  Medium                              :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_TIMEBASE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT32 CL3                                 :  1;  ///< Bits 0:0
> +    UINT32 CL6                                 :  1;  ///< Bits 1:1
> +    UINT32 CL8                                 :  1;  ///< Bits 2:2
> +    UINT32 CL9                                 :  1;  ///< Bits 3:3
> +    UINT32 CL10                                :  1;  ///< Bits 4:4
> +    UINT32 CL11                                :  1;  ///< Bits 5:5
> +    UINT32 CL12                                :  1;  ///< Bits 6:6
> +    UINT32 CL14                                :  1;  ///< Bits 7:7
> +    UINT32 CL16                                :  1;  ///< Bits 8:8
> +    UINT32                                     :  1;  ///< Bits 9:9
> +    UINT32 CL20                                :  1;  ///< Bits 10:10
> +    UINT32 CL22                                :  1;  ///< Bits 11:11
> +    UINT32 CL24                                :  1;  ///< Bits 12:12
> +    UINT32                                     :  1;  ///< Bits 13:13
> +    UINT32 CL28                                :  1;  ///< Bits 14:14
> +    UINT32                                     :  1;  ///< Bits 15:15
> +    UINT32 CL32                                :  1;  ///< Bits 16:16
> +    UINT32                                     :  1;  ///< Bits 17:17
> +    UINT32 CL36                                :  1;  ///< Bits 18:18
> +    UINT32                                     :  1;  ///< Bits 19:19
> +    UINT32 CL40                                :  1;  ///< Bits 20:20
> +    UINT32                                     :  11; ///< Bits 31:21
> +  } Bits;
> +  UINT32 Data;
> +  UINT16 Data16[2];
> +  UINT8  Data8[4];
> +} SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Density                             :  4; ///< Bits 3:0
> +    UINT8  BankAddress                         :  2; ///< Bits 5:4
> +    UINT8  BankGroup                           :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  SignalLoading                       :  2; ///< Bits 1:0
> +    UINT8  ChannelsPerDie                      :  2; ///< Bits 3:2
> +    UINT8  DieCount                            :  3; ///< Bits 6:4
> +    UINT8  SdramPackageType                    :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  OperationAt1_20                     :  1; ///< Bits 0:0
> +    UINT8  EndurantAt1_20                      :  1; ///< Bits 1:1
> +    UINT8  OperationAt1_10                     :  1; ///< Bits 2:2
> +    UINT8  EndurantAt1_10                      :  1; ///< Bits 3:3
> +    UINT8  OperationAtTBD2V                    :  1; ///< Bits 4:4
> +    UINT8  EndurantAtTBD2V                     :  1; ///< Bits 5:5
> +    UINT8                                      :  2; ///< Bits 7:6
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  tCKmax                              :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_TCK_MAX_MTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  ReadLatencyMode                     :  2; ///< Bits 1:0
> +    UINT8  WriteLatencySet                     :  2; ///< Bits 3:2
> +    UINT8                                      :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_RW_LATENCY_OPTION_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT8  tCKmaxFine                           :  8; ///< Bits 7:0
> +  } Bits;
> +  INT8  Data;
> +} SPD_LPDDR_TCK_MAX_FTB_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8                                      :  8; ///< Bits 7:0
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_UNBUF_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_RDIMM_MODULE_NOMINAL_HEIGHT;
> +
> +typedef struct {
> +  SPD_DEVICE_DESCRIPTION_STRUCT             Description;              ///< 0
> Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
> +  SPD_REVISION_STRUCT                       Revision;                 ///< 1
> SPD Revision
> +  SPD_DRAM_DEVICE_TYPE_STRUCT               DramDeviceType;           ///<
> 2       DRAM Device Type
> +  SPD_MODULE_TYPE_STRUCT                    ModuleType;               ///< 3
> Module Type
> +  SPD_LPDDR_SDRAM_DENSITY_BANKS_STRUCT      SdramDensityAndBanks;
> ///< 4       SDRAM Density and Banks
> +  SPD_SDRAM_ADDRESSING_STRUCT               SdramAddressing;
> ///< 5       SDRAM Addressing
> +  SPD_LPDDR_SDRAM_PACKAGE_TYPE_STRUCT       SdramPackageType;
> ///< 6       SDRAM Package Type
> +  SPD_PTRR_SUPPORT_STRUCT                   pTRRsupport;              ///< 7
> pTRR support with TMAC value - SDRAM Optional Features
> +  SPD_LPDDR_SDRAM_THERMAL_REFRESH_STRUCT
> ThermalAndRefreshOptions; ///< 8       SDRAM Thermal and Refresh Options
> +  UINT8                                     Reserved0[10 - 9 + 1];    ///< 9-10
> Reserved
> +  SPD_LPDDR_MODULE_NOMINAL_VOLTAGE_STRUCT
> ModuleNominalVoltage;     ///< 11      Module Nominal Voltage, VDD
> +  SPD_MODULE_ORGANIZATION_STRUCT            ModuleOrganization;
> ///< 12      Module Organization
> +  SPD_MODULE_MEMORY_BUS_WIDTH_STRUCT
> ModuleMemoryBusWidth;     ///< 13      Module Memory Bus Width
> +  SPD_MODULE_THERMAL_SENSOR_STRUCT          ModuleThermalSensor;
> ///< 14      Module Thermal Sensor
> +  UINT8                                     Reserved1[16 - 15 + 1];   ///< 15-16
> Reserved
> +  SPD_LPDDR_TIMEBASE_STRUCT                 Timebase;                 ///< 17
> Timebases
> +  SPD_TCK_MIN_MTB_STRUCT                    tCKmin;                   ///< 18
> SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_LPDDR_TCK_MAX_MTB_STRUCT              tCKmax;                   ///<
> 19      SDRAM Maximum Cycle Time (tCKmax)
> +  SPD_LPDDR_CAS_LATENCIES_SUPPORTED_STRUCT  CasLatencies;
> ///< 20-23   CAS Latencies Supported
> +  SPD_TAA_MIN_MTB_STRUCT                    tAAmin;                   ///< 24
> Minimum CAS Latency Time (tAAmin)
> +  SPD_LPDDR_RW_LATENCY_OPTION_STRUCT        LatencySetOptions;
> ///< 25      Read and Write Latency Set Options
> +  SPD_TRCD_MIN_MTB_STRUCT                   tRCDmin;                  ///< 26
> Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TRP_AB_MTB_STRUCT                     tRPab;                    ///< 27
> Minimum Row Precharge Delay Time (tRPab), all banks
> +  SPD_TRP_PB_MTB_STRUCT                     tRPpb;                    ///< 28
> Minimum Row Precharge Delay Time (tRPpb), per bank
> +  SPD_TRFC_AB_MTB_STRUCT                    tRFCab;                   ///< 29-30
> Minimum Refresh Recovery Delay Time (tRFCab), all banks
> +  SPD_TRFC_PB_MTB_STRUCT                    tRFCpb;                   ///< 31-32
> Minimum Refresh Recovery Delay Time (tRFCpb), per bank
> +  UINT8                                     Reserved2[119 - 33 + 1];  ///< 33-119
> Reserved
> +  SPD_TRP_PB_FTB_STRUCT                     tRPpbFine;                ///< 120
> Fine Offset for Minimum Row Precharge Delay Time (tRPpbFine), per bank
> +  SPD_TRP_AB_FTB_STRUCT                     tRPabFine;                ///< 121
> Fine Offset for Minimum Row Precharge Delay Time (tRPabFine), all ranks
> +  SPD_TRCD_MIN_FTB_STRUCT                   tRCDminFine;              ///<
> 122     Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
> +  SPD_TAA_MIN_FTB_STRUCT                    tAAminFine;               ///< 123
> Fine Offset for Minimum CAS Latency Time (tAAmin)
> +  SPD_LPDDR_TCK_MAX_FTB_STRUCT              tCKmaxFine;               ///<
> 124     Fine Offset for SDRAM Maximum Cycle Time (tCKmax)
> +  SPD_TCK_MIN_FTB_STRUCT                    tCKminFine;               ///< 125
> Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
> +  SPD_CYCLIC_REDUNDANCY_CODE                Crc;                      ///<
> 126-127 Cyclical Redundancy Code (CRC)
> +} SPD_LPDDR_BASE_SECTION;
> +
> +typedef union {
> +  struct {
> +    UINT8  FrontThickness                      :  4; ///< Bits 3:0
> +    UINT8  BackThickness                       :  4; ///< Bits 7:4
> +  } Bits;
> +  UINT8 Data;
> +} SPD_LPDDR_MODULE_MAXIMUM_THICKNESS;
> +
> +typedef union {
> +  struct {
> +    UINT8  Height                              :  5; ///< Bits 4:0
> +    UINT8  RawCardExtension                    :  3; ///< Bits 7:5
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_MODULE_NOMINAL_HEIGHT;
> +
> +typedef union {
> +  struct {
> +    UINT8  Card                                :  5; ///< Bits 4:0
> +    UINT8  Revision                            :  2; ///< Bits 6:5
> +    UINT8  Extension                           :  1; ///< Bits 7:7
> +  } Bits;
> +  UINT8  Data;
> +} SPD_LPDDR_REFERENCE_RAW_CARD;
> +
> +typedef struct {
> +  SPD_LPDDR_MODULE_NOMINAL_HEIGHT         ModuleNominalHeight;
> ///< 128     Module Nominal Height
> +  SPD_LPDDR_MODULE_MAXIMUM_THICKNESS
> ModuleMaximumThickness;   ///< 129     Module Maximum Thickness
> +  SPD_LPDDR_REFERENCE_RAW_CARD            ReferenceRawCardUsed;
> ///< 130     Reference Raw Card Used
> +  UINT8                                   Reserved[253 - 131 + 1];  ///< 131-253
> Reserved
> +  SPD_CYCLIC_REDUNDANCY_CODE              Crc;                      ///<
> 254-255 Cyclical Redundancy Code (CRC)
> +} SPD_LPDDR_MODULE_LPDIMM;
> +
> +typedef union {
> +  SPD_LPDDR_MODULE_LPDIMM                 LpDimm;                   ///<
> 128-255 Unbuffered Memory Module Types
> +} SPD_LPDDR_MODULE_SPECIFIC;
> +
> +typedef struct {
> +  UINT8                                   ModulePartNumber[348 - 329 + 1]; ///<
> 329-348 Module Part Number
> +} SPD_LPDDR_MODULE_PART_NUMBER;
> +
> +typedef struct {
> +  UINT8                                   ManufactureSpecificData[381 - 353 + 1];
> ///< 353-381 Manufacturer's Specific Data
> +} SPD_LPDDR_MANUFACTURE_SPECIFIC;
> +
> +typedef UINT8
> SPD_LPDDR_MODULE_REVISION_CODE;///< 349     Module Revision Code
> +typedef UINT8                             SPD_LPDDR_DRAM_STEPPING;       ///<
> 352     Dram Stepping
> +
> +typedef struct {
> +  SPD_UNIQUE_MODULE_ID                    ModuleId;                 ///<
> 320-328 Unique Module ID
> +  SPD_LPDDR_MODULE_PART_NUMBER            ModulePartNumber;
> ///< 329-348 Module Part Number
> +  SPD_LPDDR_MODULE_REVISION_CODE          ModuleRevisionCode;
> ///< 349     Module Revision Code
> +  SPD_MANUFACTURER_ID_CODE                DramIdCode;               ///<
> 350-351 Dram Manufacturer ID Code
> +  SPD_LPDDR_DRAM_STEPPING                 DramStepping;             ///< 352
> Dram Stepping
> +  SPD_LPDDR_MANUFACTURE_SPECIFIC          ManufactureSpecificData;
> ///< 353-381 Manufacturer's Specific Data
> +  UINT8                                   Reserved[383 - 382 + 1];  ///< 382-383
> Reserved
> +} SPD_LPDDR_MANUFACTURING_DATA;
> +
> +typedef union {
> +  UINT8                                   Reserved0[511 - 384 + 1]; ///< 384-511 End
> User Programmable
> +} SPD_LPDDR_END_USER_SECTION;
> +
> +typedef struct {
> +  SPD_LPDDR_BASE_SECTION                  Base;                     ///< 0-127
> Base Configuration and DRAM Parameters
> +  SPD_LPDDR_MODULE_SPECIFIC               Module;                   ///<
> 128-255 Module-Specific Section
> +  UINT8                                   Reserved0[319 - 256 + 1]; ///< 256-319
> Reserved
> +  SPD_LPDDR_MANUFACTURING_DATA            ManufactureInfo;          ///<
> 320-383 Manufacturing Information
> +  SPD_LPDDR_END_USER_SECTION              EndUser;                  ///<
> 384-511 End User Programmable
> +} MrcSpdLpDdr;
> +
> +typedef union {
> +  MrcSpdDdr3  Ddr3;
> +  MrcSpdDdr4  Ddr4;
> +  MrcSpdLpDdr Lpddr;
> +} MrcSpd;
> +
> +#ifndef MAX_SPD_SAVE
> +#define MAX_SPD_SAVE (sizeof (SPD_MANUFACTURER_ID_CODE) + \
> +                      sizeof (SPD_MANUFACTURING_LOCATION) + \
> +                      sizeof (SPD_MANUFACTURING_DATE) + \
> +                      sizeof (SPD_MANUFACTURER_SERIAL_NUMBER) + \
> +                      sizeof (SPD4_MODULE_PART_NUMBER))
> +#endif
> +
> +#pragma pack (pop)
> +#endif // _MrcSpdData_h_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> new file mode 100644
> index 0000000000..b267315f36
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffe
> elake/MrcTypes.h
> @@ -0,0 +1,237 @@
> +/** @file
> +  Include the the general MRC types
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _MRC_TYPES_H
> +#define _MRC_TYPES_H
> +
> +#ifdef MRC_MINIBIOS_BUILD
> +#include "MrcMiniBiosEfiDefs.h"
> +#else
> +#include <Base.h>
> +#endif // MRC_MINIBIOS_BUILD
> +
> +//
> +// Data Types
> +//
> +typedef union {
> +  struct {
> +    UINT32  Low;
> +    UINT32  High;
> +  } Data32;
> +  UINT64 Data;
> +} UINT64_STRUCT;
> +
> +typedef union {
> +  struct {
> +    INT32  Low;
> +    INT32  High;
> +  } Data32;
> +  INT64 Data;
> +} INT64_STRUCT;
> +
> +typedef union {
> +  VOID    *Ptr;
> +  UINTN   DataN;
> +  UINT64  Data64;
> +} POINTER_STRUCT;
> +
> +#define UNSUPPORT 0
> +#define SUPPORT   1
> +
> +typedef enum {
> +  mrcSuccess,
> +  mrcFail,
> +  mrcWrongInputParameter,
> +  mrcCasError,
> +  mrcTimingError,
> +  mrcSenseAmpErr,
> +  mrcReadMPRErr,
> +  mrcReadLevelingError,
> +  mrcWriteLevelingError,
> +  mrcDataTimeCentering1DErr,
> +  mrcWriteVoltage2DError,
> +  mrcReadVoltage2DError,
> +  mrcMiscTrainingError,
> +  mrcWrError,
> +  mrcDimmNotSupport,
> +  mrcChannelNotSupport,
> +  mrcPiSettingError,
> +  mrcDqsPiSettingError,
> +  mrcDeviceBusy,
> +  mrcFrequencyChange,
> +  mrcReutSequenceError,
> +  mrcCrcError,
> +  mrcFrequencyError,
> +  mrcDimmNotExist,
> +  mrcColdBootRequired,
> +  mrcRoundTripLatencyError,
> +  mrcMixedDimmSystem,
> +  mrcAliasDetected,
> +  mrcRetrain,
> +  mrcRtpError,
> +  mrcUnsupportedTechnology,
> +  mrcMappingError,
> +  mrcSocketNotSupported,
> +  mrcControllerNotSupported,
> +  mrcRankNotSupported,
> +  mrcTurnAroundTripError
> +} MrcStatus;
> +
> +//
> +// general  macros
> +//
> +#ifndef MIN
> +#define MIN(a, b) (((a) < (b)) ? (a) : (b))
> +#endif
> +
> +#ifndef MAX
> +#define MAX(a, b) (((a) > (b)) ? (a) : (b))
> +#endif
> +
> +#ifndef ABS
> +#define ABS(x)  (((x) < 0) ? (-(x)) : (x))
> +#endif
> +
> +//
> +// Make sure x is inside the range of [a..b]
> +//
> +#ifndef RANGE
> +#define RANGE(x, a, b) (MIN ((b), MAX ((x), (a))))
> +#endif
> +
> +#ifndef DIVIDECEIL
> +#define DIVIDECEIL(a, b)   (((a) + (b) - 1) / (b))
> +#endif
> +
> +#ifndef DIVIDEROUND
> +#define DIVIDEROUND(a, b)  (((a) * (b) > 0) ? ((a) + (b) / 2) / (b) : ((a) - (b) / 2)
> / (b))
> +#endif
> +
> +#ifndef DIVIDEFLOOR
> +#define DIVIDEFLOOR(a, b)  ((a) / (b))
> +#endif
> +
> +//
> +// Number of elements in a 1D array
> +//
> +#ifndef ARRAY_COUNT
> +#define ARRAY_COUNT(a) (sizeof (a) / sizeof (a[0]))
> +#endif
> +
> +//
> +//  use for ignore parames
> +//
> +// #define MRC_IGNORE_PARAM(x) ((x) = (x))
> +//
> +#if _MSC_EXTENSIONS
> +//
> +// Disable warning that make it impossible to compile at /W4
> +// This only works for Microsoft* tools
> +//
> +//
> +// Disabling bitfield type checking warnings.
> +//
> +#pragma warning (disable : 4214)
> +//
> +// Unreferenced formal parameter - We are object oriented, so we pass
> parameters even
> +//  if we don't need them.
> +//
> +#pragma warning (disable : 4100)
> +//
> +// ASSERT(FALSE) or while (TRUE) are legal constructs so supress this warning
> +//
> +#pragma warning(disable : 4127)
> +//
> +// The given function was selected for inline expansion, but the compiler did
> not perform the inlining.
> +//
> +#pragma warning(disable : 4710)
> +
> +#endif // _MSC_EXTENSIONS
> +#define MRC_BIT0          0x00000001
> +#define MRC_BIT1          0x00000002
> +#define MRC_BIT2          0x00000004
> +#define MRC_BIT3          0x00000008
> +#define MRC_BIT4          0x00000010
> +#define MRC_BIT5          0x00000020
> +#define MRC_BIT6          0x00000040
> +#define MRC_BIT7          0x00000080
> +#define MRC_BIT8          0x00000100
> +#define MRC_BIT9          0x00000200
> +#define MRC_BIT10         0x00000400
> +#define MRC_BIT11         0x00000800
> +#define MRC_BIT12         0x00001000
> +#define MRC_BIT13         0x00002000
> +#define MRC_BIT14         0x00004000
> +#define MRC_BIT15         0x00008000
> +#define MRC_BIT16         0x00010000
> +#define MRC_BIT17         0x00020000
> +#define MRC_BIT18         0x00040000
> +#define MRC_BIT19         0x00080000
> +#define MRC_BIT20         0x00100000
> +#define MRC_BIT21         0x00200000
> +#define MRC_BIT22         0x00400000
> +#define MRC_BIT23         0x00800000
> +#define MRC_BIT24         0x01000000
> +#define MRC_BIT25         0x02000000
> +#define MRC_BIT26         0x04000000
> +#define MRC_BIT27         0x08000000
> +#define MRC_BIT28         0x10000000
> +#define MRC_BIT29         0x20000000
> +#define MRC_BIT30         0x40000000
> +#define MRC_BIT31         0x80000000
> +#define MRC_BIT32        0x100000000ULL
> +#define MRC_BIT33        0x200000000ULL
> +#define MRC_BIT34        0x400000000ULL
> +#define MRC_BIT35        0x800000000ULL
> +#define MRC_BIT36       0x1000000000ULL
> +#define MRC_BIT37       0x2000000000ULL
> +#define MRC_BIT38       0x4000000000ULL
> +#define MRC_BIT39       0x8000000000ULL
> +#define MRC_BIT40      0x10000000000ULL
> +#define MRC_BIT41      0x20000000000ULL
> +#define MRC_BIT42      0x40000000000ULL
> +#define MRC_BIT43      0x80000000000ULL
> +#define MRC_BIT44     0x100000000000ULL
> +#define MRC_BIT45     0x200000000000ULL
> +#define MRC_BIT46     0x400000000000ULL
> +#define MRC_BIT47     0x800000000000ULL
> +#define MRC_BIT48    0x1000000000000ULL
> +#define MRC_BIT49    0x2000000000000ULL
> +#define MRC_BIT50    0x4000000000000ULL
> +#define MRC_BIT51    0x8000000000000ULL
> +#define MRC_BIT52   0x10000000000000ULL
> +#define MRC_BIT53   0x20000000000000ULL
> +#define MRC_BIT54   0x40000000000000ULL
> +#define MRC_BIT55   0x80000000000000ULL
> +#define MRC_BIT56  0x100000000000000ULL
> +#define MRC_BIT57  0x200000000000000ULL
> +#define MRC_BIT58  0x400000000000000ULL
> +#define MRC_BIT59  0x800000000000000ULL
> +#define MRC_BIT60 0x1000000000000000ULL
> +#define MRC_BIT61 0x2000000000000000ULL
> +#define MRC_BIT62 0x4000000000000000ULL
> +#define MRC_BIT63 0x8000000000000000ULL
> +
> +#define MRC_DEADLOOP() { volatile int __iii; __iii = 1; while (__iii); }
> +
> +#ifndef ASM
> +#define ASM __asm
> +#endif
> +
> +///
> +/// Type Max/Min Values
> +///
> +#define MRC_INT32_MAX   (0x7FFFFFFF)
> +#define MRC_INT32_MIN   (0x80000000)
> +#define MRC_INT64_MAX   (0x7FFFFFFFFFFFFFFFLL)
> +#define MRC_INT64_MIN   (0x8000000000000000LL)
> +#define MRC_UINT32_MAX  (0xFFFFFFFF)
> +#define MRC_UINT64_MAX  (0xFFFFFFFFFFFFFFFFULL)
> +#define MRC_UINT_MIN    (0x0)
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> new file mode 100644
> index 0000000000..d444e937d6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcI
> nterface.h
> @@ -0,0 +1,15 @@
> +/** @file
> +  This file includes all the data structures that the MRC considers "global
> data".
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _UNIFIED_MrcInterface_h_
> +#define _UNIFIED_MrcInterface_h_
> +
> +#include "Coffeelake/MrcInterface.h"
> +
> +#endif
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> new file mode 100644
> index 0000000000..82d798b783
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
> @@ -0,0 +1,50 @@
> +/** @file
> +  Header file for initialization of GT PowerManagement
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GRAPHICS_INIT_H_
> +#define _GRAPHICS_INIT_H_
> +
> +#include <Library/DxeServicesTableLib.h>
> +#include <Guid/DxeServices.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Library/PciSegmentLib.h>
> +#include <SaAccess.h>
> +#include <Protocol/SaPolicy.h>
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <PchAccess.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> new file mode 100644
> index 0000000000..0e95db3d02
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.h
> @@ -0,0 +1,193 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _IGD_OPREGION_INIT_H_
> +#define _IGD_OPREGION_INIT_H_
> +
> +///
> +/// Statements that include other header files.
> +///
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <PchAccess.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PmcLib.h>
> +#include <SaAccess.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <CpuRegs.h>
> +#include <SaInit.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <SiConfigHob.h>
> +
> +///
> +/// Driver Consumed Protocol Prototypes
> +///
> +#include <Protocol/PciIo.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/SaPolicy.h>
> +
> +
> +#include <Private/Protocol/SaNvsArea.h>
> +
> +///
> +/// Driver Produced Protocol Prototypes
> +///
> +#include <Protocol/IgdOpRegion.h>
> +
> +///
> +///
> +/// OpRegion (Miscellaneous) defines.
> +///
> +/// OpRegion Header defines.
> +///
> +typedef UINT16  STRING_REF;
> +#define HEADER_SIGNATURE            "IntelGraphicsMem"
> +#define HEADER_SIZE                 0x2000
> +#define HEADER_OPREGION_VER         0x0200
> +#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 BLC_ENABLE            BIT1
> +#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
> +///
> +#pragma pack(1)
> +typedef struct {
> +  UINT16  Signature;  /// 0xAA55
> +  UINT8   Size512;
> +  UINT8   Reserved[21];
> +  UINT16  PcirOffset;
> +  UINT16  VbtOffset;
> +} INTEL_VBIOS_OPTION_ROM_HEADER;
> +#pragma pack()
> +
> +#pragma pack(1)
> +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;
> +#pragma pack()
> +
> +#pragma pack(1)
> +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()
> +///
> +/// 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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> new file mode 100644
> index 0000000000..34a2809f80
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.
> h
> @@ -0,0 +1,91 @@
> +/** @file
> +  Header file for PciExpress Initialization Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCIEXPRESS_INITIALIZATION_DRIVER_H_
> +#define _PCIEXPRESS_INITIALIZATION_DRIVER_H_
> +
> +#include <Library/HobLib.h>
> +#include <IndustryStandard/Pci30.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/S3BootScriptLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Register/Msr.h>
> +#include <SaAccess.h>
> +#include <PchAccess.h>
> +#include <Private/SaConfigHob.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/Protocol/SaNvsArea.h>
> +
> +#define GEN1      1
> +#define GEN2      2
> +
> +///
> +/// Function prototypes
> +///
> +/**
> +  PCI Express Dxe Initialization.
> +  Run before PCI Bus Init, where assignment of Bus, Memory,
> +    and I/O Resources are assigned.
> +
> +  @param[in] SaPolicy    -     SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS        - Pci Express successfully started and ready to be
> used
> +  @exception EFI_UNSUPPORTED - Pci Express can't be initialized
> +**/
> +EFI_STATUS
> +PciExpressInit (
> +  IN SA_POLICY_PROTOCOL *SaPolicy
> +  );
> +
> +/**
> +  Find the Offset to a given 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 fo
> +
> +  @retval 0       - CAPID not found
> +  @retval Other   - CAPID found, Offset of desired CAPID
> +**/
> +UINT32
> +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
> +
> +  @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
> +**/
> +UINT32
> +PcieFindExtendedCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT16  CapId
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> new file mode 100644
> index 0000000000..73af27e9d7
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  This is header file for SA PCIE Root Complex initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +EFI_STATUS
> +PegInitBeforeEndOfDxe (
> +  VOID
> +  );
> +
> +/**
> +  This function performs SA registers Saving/Restoring in EndOfDxe callback
> +
> +  @retval EFI_SUCCESS     - Save/restore has done
> +  @retval EFI_UNSUPPORTED - Save/restore not done successfully
> +**/
> +EFI_STATUS
> +SaSaveRestore (
> +  VOID
> +  );
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> new file mode 100644
> index 0000000000..d7e2423ffd
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
> @@ -0,0 +1,71 @@
> +/** @file
> +  Header file for SA Common Initialization Driver.
> +
> +  Copyright (c) 2019 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 <CpuRegs.h>
> +#include <SaAccess.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/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
> +  );
> +
> +/**
> +  Common function locks the PAM register as part of the SA Security
> requirements.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +VOID
> +SaPamLock (
> +  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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> new file mode 100644
> index 0000000000..1991fd82c4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
> @@ -0,0 +1,139 @@
> +/** @file
> +  Header file for SA Initialization Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_INITIALIZATION_DXE_DRIVER_H_
> +#define _SA_INITIALIZATION_DXE_DRIVER_H_
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/AcpiTable.h>
> +#include "VTd.h"
> +#include "PcieComplex.h"
> +#include "IgdOpRegionInit.h"
> +#include <Private/Library/LegacyRegion.h>
> +#include "GraphicsInit.h"
> +#include "PciExpressInit.h"
> +#include "SwitchableGraphicsInit.h"
> +#include <Library/CpuPlatformLib.h>
> +
> +///
> +/// Driver Consumed Protocol Prototypes
> +///
> +#include <Protocol/SaPolicy.h>
> +
> +extern EFI_GUID gSaAcpiTableStorageGuid;
> +extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
> +extern EFI_GUID gPegSsdtAcpiTableStorageGuid;
> +
> +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 SA 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.
> +
> +  @retval EFI_SUCCESS   - Always.
> +
> +**/
> +VOID
> +EFIAPI
> +SaPciEnumCompleteCallback (
> +  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
> +  );
> +
> +/**
> +  This function locks the PAM register as part of the SA Security requirements.
> +
> +  @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 EFI_SUCCESS   - Always.
> +**/
> +VOID
> +EFIAPI
> +SaPamLockDxe (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  );
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> new file mode 100644
> index 0000000000..2b1b4c5880
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGra
> phicsInit.h
> @@ -0,0 +1,17 @@
> +/** @file
> +  Header file for the SwitchableGraphics Dxe driver.
> +  This driver loads SwitchableGraphics ACPI tables.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SWITCHABLE_GRAPHICS_DXE_H_
> +#define _SWITCHABLE_GRAPHICS_DXE_H_
> +
> +
> +#include <Protocol/FirmwareVolume2.h>
> +
> +
> +#endif
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> new file mode 100644
> index 0000000000..c4bc47f7fe
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
> @@ -0,0 +1,53 @@
> +/** @file
> +  This code provides a initialization of intel VT-d (Virtualization Technology
> for Directed I/O).
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _VT_D_H_
> +#define _VT_D_H_
> +
> +///
> +/// Include files
> +///
> +#include <DmaRemappingTable.h>
> +#include <SaAccess.h>
> +#include <PchAccess.h>
> +#include <Uefi.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Private/PchConfigHob.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +
> +#define VTD_ECAP_REG  0x10
> +#define IR            BIT3
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  PciEnumerationComplete routine for update DMAR
> +**/
> +VOID
> +UpdateDmarPciEnumCompleteCallback (
> +  VOID
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> new file mode 100644
> index 0000000000..02c74c0672
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.h
> @@ -0,0 +1,162 @@
> +/** @file
> +  Header file for SMM Access Driver.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SMM_ACCESS_DRIVER_H_
> +#define _SMM_ACCESS_DRIVER_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Uefi/UefiBaseType.h>
> +
> +#include <Guid/SmramMemoryReserve.h>
> +#include <Protocol/SmmAccess2.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <SaAccess.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's',
> 'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      Handle;
> +  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
> +
> +  ///
> +  /// Local Data for SMM Access interface goes here
> +  ///
> +  UINTN                           NumberRegions;
> +  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> +  CR (a, \
> +      SMM_ACCESS_PRIVATE_DATA, \
> +      SmmAccess, \
> +      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> +      )
> +
> +//
> +// Prototypes
> +// Driver model protocol interface
> +//
> +/**
> +  <b>SMM Access Driver Entry Point</b>
> +  This driver installs an SMM Access Protocol
> +  - <b>Introduction</b> \n
> +    This module publishes the SMM access protocol.  The protocol is used by
> the SMM Base driver to access the SMRAM region when the processor is not in
> SMM.
> +    The SMM Base driver uses the services provided by the SMM access
> protocol to open SMRAM during post and copy the SMM handler.
> +    SMM access protocol is also used to close the SMRAM region once the
> copying is done.
> +    Finally, the SMM access protocol provides services to "Lock" the SMRAM
> region.
> +    Please refer the SMM Protocols section in the attached SMM CIS
> Specification version 0.9 for further details.
> +    This driver is required if SMM is supported. Proper configuration of SMM
> registers is recommended even if SMM is not supported.
> +
> +  - @result
> +    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System
> Management Mode Core Interface Specification, available at the URL:
> http://www.intel.com/technology/framework/spec.htm
> +
> +  - <b>Porting Recommendations</b> \n
> +    No modification of this module is recommended.  Any modification
> should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL
> protocol definition.
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS     - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED - Protocol was not installed
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all boot-service
> +  and SMM agents.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM agents,
> +  not from BS or RT code.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by
> +                            chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  );
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                          one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size
> of the
> +                            buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing
> the Smram
> +                            region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                   *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
> +  );
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> new file mode 100644
> index 0000000000..5daa2367e6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
> @@ -0,0 +1,157 @@
> +/** @file
> +  DXE driver for Initializing SystemAgent Graphics ACPI table initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GraphicsInit.h"
> +#include "SaInit.h"
> +#include <Protocol/LegacyBios.h>
> +#include <Protocol/GopComponentName2.h>
> +#include <SiConfigHob.h>
> +
> +typedef union {
> +  struct {
> +    UINT32  Low;
> +    UINT32  High;
> +  } Data32;
> +  UINT64 Data;
> +} UINT64_STRUCT;
> +
> +extern SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT64
> mGttMmAdr;
> +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_LEGACY_BIOS_PROTOCOL  *LegacyBios;
> +  EFI_STATUS                Status;
> +  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
> +  EFI_PEI_HOB_POINTERS      HobPtr;
> +  SI_CONFIG_HOB_DATA        *SiConfigHobData;
> +
> +  ///
> +  /// Get the platform setup policy.
> +  ///
> +  DriverVersion = NULL;
> +  LegacyBios = NULL;
> +  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)
> &mSaPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Get Silicon Config data HOB
> +  //
> +  HobPtr.Guid   = GetFirstGuidHob (&gSiConfigHobGuid);
> +  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA
> (HobPtr.Guid);
> +
> +  if (SiConfigHobData->CsmFlag == 1) {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiLegacyBiosProtocolGuid,
> +                    NULL,
> +                    (VOID **) &LegacyBios
> +                    );
> +  }
> +
> +  if (LegacyBios == NULL) {
> +    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;
> +
> +  mGttMmAdr               = 0;
> +  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);
> +
> +  ///
> +  /// Update IGD SA Global NVS
> +  ///
> +  DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
> +
> +  mSaNvsAreaProtocol.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) {
> +    mSaNvsAreaProtocol.Area->IgdState = 1;
> +  } else {
> +    mSaNvsAreaProtocol.Area->IgdState = 0;
> +  }
> +
> +  mSaNvsAreaProtocol.Area->BrightnessPercentage         = 100;
> +  mSaNvsAreaProtocol.Area->IgdBootType                  =
> GraphicsDxeConfig->IgdBootType;
> +  mSaNvsAreaProtocol.Area->IgdPanelType                 =
> GraphicsDxeConfig->IgdPanelType;
> +  mSaNvsAreaProtocol.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.
> +  ///
> +  mSaNvsAreaProtocol.Area->IgdDvmtMemSize               =
> GraphicsDxeConfig->IgdDvmtMemSize;
> +  mSaNvsAreaProtocol.Area->IgdFunc1Enable               = 0;
> +  mSaNvsAreaProtocol.Area->IgdHpllVco                   = MmioRead8
> (mMchBarBase.Data + 0xC0F) & 0x07;
> +  mSaNvsAreaProtocol.Area->IgdSciSmiMode                = 0;
> +  mSaNvsAreaProtocol.Area->GfxTurboIMON                 =
> GraphicsDxeConfig->GfxTurboIMON;
> +
> +  mSaNvsAreaProtocol.Area->EdpValid                     = 0;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> new file mode 100644
> index 0000000000..6ec0691074
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionIni
> t.c
> @@ -0,0 +1,570 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "IgdOpRegionInit.h"
> +
> +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;
> +
> +  ///
> +  /// Get the SA policy.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaPolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mSaPolicy
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &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_PCIR_STRUCTURE    *PcirBlockPtr;
> +  UINT32                        PcirBlockAddress;
> +  UINT16                        PciVenderId;
> +  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
> +  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
> +  EFI_LEGACY_BIOS_PROTOCOL      *LegacyBios;
> +  EFI_STATUS                    Status;
> +  VBIOS_VBT_STRUCTURE           *VbtFileBuffer;
> +  UINTN                         Index;
> +  UINT8                         LegacyVbtFound;
> +  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
> +  EFI_PEI_HOB_POINTERS          HobPtr;
> +  SI_CONFIG_HOB_DATA            *SiConfigHobData;
> +
> +  VbtFileBuffer = NULL;
> +  LegacyVbtFound = 1;
> +
> +  ///
> +  /// Get the SA policy.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaPolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &mSaPolicy
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gGraphicsDxeConfigGuid,
> (VOID *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  LegacyBios = NULL;
> +  VBiosPtr = NULL;
> +  //
> +  // Get Silicon Config data HOB
> +  //
> +  HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
> +  SiConfigHobData = (SI_CONFIG_HOB_DATA *)GET_GUID_HOB_DATA
> (HobPtr.Guid);
> +  if (SiConfigHobData->CsmFlag == 1) {
> +    Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID
> **) &LegacyBios);
> +
> +    if (LegacyBios) {
> +      VBiosPtr      = (INTEL_VBIOS_OPTION_ROM_HEADER *) (UINTN)
> (VBIOS_LOCATION_PRIMARY);
> +      PcirBlockAddress = VBIOS_LOCATION_PRIMARY + VBiosPtr->PcirOffset;
> +      PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) (UINTN)
> (PcirBlockAddress);
> +      PciVenderId   = PcirBlockPtr->VendorId;
> +      ///
> +      /// If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
> +      /// the integrated Intel video BIOS (must be uncompressed).
> +      ///
> +      if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId !=
> V_SA_MC_VID)) {
> +        GetIntegratedIntelVBiosPtr (&VBiosPtr);
> +        if (VBiosPtr != NULL) {
> +          ///
> +          /// Video BIOS found.
> +          ///
> +          PcirBlockPtr  = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosPtr
> + VBiosPtr->PcirOffset);
> +          PciVenderId   = PcirBlockPtr->VendorId;
> +
> +          if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) ||
> (PciVenderId != V_SA_MC_VID)) {
> +            ///
> +            /// Intel video BIOS not found.
> +            ///
> +            VBiosVbtPtr = NULL;
> +            LegacyVbtFound = 0;
> +          }
> +        }
> +      }
> +    }
> +  }
> +  if ((LegacyBios == NULL) || (LegacyVbtFound == 0)) {
> +    ///
> +    /// No Video BIOS found, 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"));
> +      for (Index = 0; (GraphicsDxeConfig->GopVersion[Index] != '\0'); Index++) {
> +      }
> +      Index = (Index+1)*2;
> +      CopyMem (mIgdOpRegion.OpRegion->Header.DVER,
> GraphicsDxeConfig->GopVersion, Index);
> +      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;
> +
> +  ///
> +  /// 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);
> +  ///
> +  ///  Locate the SA Global NVS Protocol.
> +  ///
> +  Status = gBS->LocateProtocol (
> +                  &gSaNvsAreaProtocolGuid,
> +                  NULL,
> +                  (VOID **) &SaNvsAreaProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
> +  /// the first 1K, and set the IGD OpRegion pointer in the Global NVS
> +  /// area structure.
> +  ///
> +  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof
> (IGD_OPREGION_STRUCTURE), (VOID **) &mIgdOpRegion.OpRegion);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE),
> 0);
> +  SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN)
> (mIgdOpRegion.OpRegion);
> +
> +  ///
> +  /// If IGD is disabled return
> +  ///
> +  IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 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, 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/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> new file mode 100644
> index 0000000000..bbdf0d0fab
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
> @@ -0,0 +1,171 @@
> +/** @file
> +  This driver does SA PCI Express ACPI table initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PciExpressInit.h"
> +
> +extern SYSTEM_AGENT_NVS_AREA_PROTOCOL   mSaNvsAreaProtocol;
> +extern SA_CONFIG_HOB                    *mSaConfigHob;
> +
> +/**
> +  PCI Express Dxe Initialization.
> +  Run before PCI Bus Init, where assignment of Bus, Memory,
> +    and I/O Resources are assigned.
> +
> +  @param[in] SaPolicy     -     SA DXE Policy protocol
> +
> +  @retval EFI_SUCCESS     - Pci Express successfully started and ready to be
> used
> +**/
> +EFI_STATUS
> +PciExpressInit (
> +  IN SA_POLICY_PROTOCOL *SaPolicy
> +  )
> +{
> +  EFI_STATUS                                    Status;
> +  PCIE_DXE_CONFIG                               *PcieDxeConfig;
> +  MSR_BROADWELL_PKG_CST_CONFIG_CONTROL_REGISTER Msr;
> +
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID
> *)&PcieDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  Msr.Uint64 = AsmReadMsr64
> (MSR_BROADWELL_PKG_CST_CONFIG_CONTROL);
> +  mSaNvsAreaProtocol.Area->PackageCstateLimit  = (UINT8) Msr.Bits.Limit;
> +
> +  mSaNvsAreaProtocol.Area->PwrDnBundlesGlobalEnable  = 0;
> +
> +  if (mSaConfigHob != NULL) {
> +    mSaNvsAreaProtocol.Area->Peg0PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[0];
> +    mSaNvsAreaProtocol.Area->Peg1PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[1];
> +    mSaNvsAreaProtocol.Area->Peg2PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[2];
> +    if (SA_PEG_MAX_FUN > 3) {
> +      mSaNvsAreaProtocol.Area->Peg3PowerDownUnusedBundles  =
> mSaConfigHob->PowerDownUnusedBundles[3];
> +    }
> +  }
> +  ///
> +  /// LTR/OBFF
> +  ///
> +  mSaNvsAreaProtocol.Area->Peg0LtrEnable                =
> PcieDxeConfig->PegPwrOpt[0].LtrEnable;
> +  mSaNvsAreaProtocol.Area->Peg0ObffEnable               =
> PcieDxeConfig->PegPwrOpt[0].ObffEnable;
> +  mSaNvsAreaProtocol.Area->Peg1LtrEnable                =
> PcieDxeConfig->PegPwrOpt[1].LtrEnable;
> +  mSaNvsAreaProtocol.Area->Peg1ObffEnable               =
> PcieDxeConfig->PegPwrOpt[1].ObffEnable;
> +  mSaNvsAreaProtocol.Area->Peg2LtrEnable                =
> PcieDxeConfig->PegPwrOpt[2].LtrEnable;
> +  mSaNvsAreaProtocol.Area->Peg2ObffEnable               =
> PcieDxeConfig->PegPwrOpt[2].ObffEnable;
> +  mSaNvsAreaProtocol.Area->PegLtrMaxSnoopLatency        =
> LTR_MAX_SNOOP_LATENCY_VALUE;
> +  mSaNvsAreaProtocol.Area->PegLtrMaxNoSnoopLatency      =
> LTR_MAX_NON_SNOOP_LATENCY_VALUE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  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
> +**/
> +UINT32
> +PcieFindCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT8   CapId
> +  )
> +{
> +  UINT64 DeviceBaseAddress;
> +  UINT8  CapHeader;
> +
> +  ///
> +  /// Always start at Offset 0x34
> +  ///
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> +  CapHeader         = PciSegmentRead8 (DeviceBaseAddress +
> PCI_CAPBILITY_POINTER_OFFSET);
> +  if (CapHeader == 0xFF) {
> +    return 0;
> +  }
> +
> +  while (CapHeader != 0) {
> +    ///
> +    /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
> +    ///
> +    CapHeader &= ~(BIT1 + BIT0);
> +    ///
> +    /// Search for desired CapID
> +    ///
> +    if (PciSegmentRead8 (DeviceBaseAddress + CapHeader) == CapId) {
> +      return CapHeader;
> +    }
> +
> +    CapHeader = PciSegmentRead8 (DeviceBaseAddress + CapHeader + 1);
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  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
> +**/
> +UINT32
> +PcieFindExtendedCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT16  CapId
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT16  CapHeaderOffset;
> +  UINT16  CapHeaderId;
> +
> +  ///
> +  /// Start to search at Offset 0x100
> +  /// Get Capability Header
> +  ///
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> +  CapHeaderId     = 0;
> +  CapHeaderOffset = 0x100;
> +
> +  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
> +    ///
> +    /// Search for desired CapID
> +    ///
> +    CapHeaderId = PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset);
> +    if (CapHeaderId == CapId) {
> +      return CapHeaderOffset;
> +    }
> +
> +    CapHeaderOffset = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 2) >> 4);
> +  }
> +
> +  return 0;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> new file mode 100644
> index 0000000000..1dc37334ae
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
> @@ -0,0 +1,171 @@
> +/** @file
> +  This file will perform SA PCIE Root Complex initialization.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PciExpressInit.h"
> +#include <Private/Library/SaPcieLib.h>
> +#include "PcieComplex.h"
> +#include <Private/Protocol/SaIotrapSmi.h>
> +#include "SaInit.h"
> +
> +///
> +/// Global variables
> +///
> +UINT16                                 mSaIotrapSmiAddress;
> +extern SA_CONFIG_HOB                   *mSaConfigHob;
> +
> +///
> +/// Functions
> +///
> +/**
> +    This function gets registered as a callback to perform all SA late
> initialization
> +
> +    @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
> +SaLateInitSmiCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS                 Status;
> +  SA_IOTRAP_SMI_PROTOCOL     *SaIotrapSmiProtocol;
> +
> +  if (mSaIotrapSmiAddress == 0) {
> +    //
> +    // Use global variable instead of protocol data since it maybe tampered in
> unsecure environment
> +    // Get IOTrap address when first time this routine calling
> (gEfiPciEnumerationCompleteProtocolGuid callback)
> +    //
> +    SaIotrapSmiProtocol = NULL;
> +    Status = gBS->LocateProtocol (&gSaIotrapSmiProtocolGuid, NULL, (VOID **)
> &SaIotrapSmiProtocol);
> +    ASSERT_EFI_ERROR (Status);
> +    if (SaIotrapSmiProtocol != NULL) {
> +      mSaIotrapSmiAddress = SaIotrapSmiProtocol->SaIotrapSmiAddress;
> +    }
> +  }
> +
> +  ASSERT (mSaIotrapSmiAddress != 0);
> +  if (mSaIotrapSmiAddress != 0) {
> +    //
> +    // Generate IOTRAP SMI immediately
> +    //
> +    DEBUG ((DEBUG_INFO, "[SA] Issue IOTRAP SMI %X\n",
> mSaIotrapSmiAddress));
> +    IoWrite8 (mSaIotrapSmiAddress, 0);
> +  }
> +  if (Event != NULL) {
> +    gBS->CloseEvent (Event);
> +  }
> +  return;
> +}
> +
> +/**
> +  This function performs Peg initialization before EndOfDxe.
> +  @note This function will be executed as
> gEfiPciEnumerationCompleteProtocolGuid protocol callback and assumed SA
> DXE/SMM drivers have been dispatched.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +EFI_STATUS
> +PegInitBeforeEndOfDxe (
> +  VOID
> +  )
> +{
> +  EFI_EVENT                       ReadyToBoot;
> +  EFI_STATUS                      Status;
> +  BOOLEAN                         AspmHasBeenHandled;
> +
> +  DEBUG ((DEBUG_INFO, "[SA] Pcie before EndOfDxe callback.\n"));
> +  AspmHasBeenHandled = FALSE;
> +  ///
> +  /// SMM mode ASPM handling
> +  /// Check if supported and enabled
> +  ///
> +  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom
> == TRUE)) {
> +    ///
> +    /// Do the Phase 1 SMI callback
> +    /// This will enumerate PCIe downstream devices
> +    ///
> +    SaLateInitSmiCallback (NULL, NULL);
> +
> +    if (mSaIotrapSmiAddress != 0) {
> +      ///
> +      /// Create an ReadyToBoot call back event to do the Phase 3 SMI callback
> +      /// This will handle PEG ASPM programming after OROM execution
> +      /// Note: Phase 2 SMI callback will be triggered in EndOfDxe callback
> +      ///       to initialize rest of PCIe settings prior to OPROM
> +      ///
> +      Status = EfiCreateEventReadyToBootEx (
> +                 TPL_NOTIFY,
> +                 (EFI_EVENT_NOTIFY) SaLateInitSmiCallback,
> +                 NULL,
> +                 &ReadyToBoot
> +                 );
> +      ASSERT_EFI_ERROR (Status);
> +      AspmHasBeenHandled = TRUE;
> +    }
> +  }
> +
> +  ///
> +  /// DXE mode ASPM handling
> +  /// Check if SMM mode already taken care all things
> +  /// TRUE to skip DXE mode task. Otherwise do DXE mode ASPM initialization
> +  ///
> +  if (AspmHasBeenHandled == FALSE) {
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function performs SA registers Saving/Restoring in EndOfDxe callback
> +
> +  @retval EFI_SUCCESS     - Save/restore has done
> +  @retval EFI_UNSUPPORTED - Save/restore not done successfully
> +**/
> +EFI_STATUS
> +SaSaveRestore (
> +  VOID
> +  )
> +{
> +  BOOLEAN                         SaveRestoreHasBeenHandled;
> +  UINT8                           SmiData;
> +
> +  SaveRestoreHasBeenHandled = FALSE;
> +
> +  if ((mSaConfigHob != NULL) && (mSaConfigHob->InitPcieAspmAfterOprom
> == TRUE)) {
> +    ///
> +    /// Generate the Phase 2 of SA SMI to do SA chipset save/restore and
> security lock
> +    ///
> +    SaLateInitSmiCallback (NULL, NULL);
> +
> +    if (mSaIotrapSmiAddress != 0) {
> +      ///
> +      /// Store IOTRAP SMI address into Boot Script save table
> +      /// This is required to trigger this IOTRAP during S3 resume to restore all
> settings
> +      ///
> +      SmiData = 0;
> +      S3BootScriptSaveIoWrite (
> +        S3BootScriptWidthUint8,
> +        (UINTN) mSaIotrapSmiAddress,
> +        1,
> +        &SmiData
> +        );
> +      SaveRestoreHasBeenHandled = TRUE;
> +    }
> +  }
> +
> +  ///
> +  /// Check if SMM mode already taken care this task
> +  ///
> +  if (SaveRestoreHasBeenHandled == TRUE) {
> +    return EFI_SUCCESS;
> +  } else {
> +    return EFI_UNSUPPORTED;
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> new file mode 100644
> index 0000000000..d5a63785b4
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
> @@ -0,0 +1,496 @@
> +/** @file
> +  This is the driver that initializes the Intel System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <Private/SaConfigHob.h>
> +#include <Private/Protocol/SaNvsArea.h>
> +#include <Library/PchInfoLib.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;
> +
> +/**
> +  Initialize System Agent SSDT ACPI tables
> +
> +  @retval EFI_SUCCESS    ACPI tables are initialized successfully
> +  @retval EFI_NOT_FOUND  ACPI tables not found
> +**/
> +EFI_STATUS
> +InitializeSaSsdtAcpiTables (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_HANDLE                    *HandleBuffer;
> +  UINTN                         NumberOfHandles;
> +  EFI_FV_FILETYPE               FileType;
> +  UINT32                        FvStatus;
> +  EFI_FV_FILE_ATTRIBUTES        Attributes;
> +  UINTN                         Size;
> +  UINTN                         i;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> +  INTN                          Instance;
> +  EFI_ACPI_COMMON_HEADER        *CurrentTable;
> +  UINTN                         AcpiTableKey;
> +  UINT8                         *CurrPtr;
> +  UINT8                         *EndPtr;
> +  UINT32                        *Signature;
> +  EFI_ACPI_DESCRIPTION_HEADER   *SaAcpiTable;
> +  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
> +
> +  FwVol       = NULL;
> +  SaAcpiTable = NULL;
> +
> +  ///
> +  /// Locate ACPI Table protocol
> +  ///
> +  DEBUG ((DEBUG_INFO, "Init SA SSDT table\n"));
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)
> &AcpiTable);
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_WARN, "Fail to locate EfiAcpiTableProtocol.\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ///
> +  /// 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,
> +                      &gSaSsdtAcpiTableStorageGuid,
> +                      NULL,
> +                      &Size,
> +                      &FileType,
> +                      &Attributes,
> +                      &FvStatus
> +                      );
> +
> +    ///
> +    /// If we found it, then we are done
> +    ///
> +    if (Status == EFI_SUCCESS) {
> +      break;
> +    }
> +  }
> +  ///
> +  /// Free any allocated buffers
> +  ///
> +  FreePool (HandleBuffer);
> +
> +  ///
> +  /// Sanity check that we found our data file
> +  ///
> +  ASSERT (FwVol != NULL);
> +  if (FwVol == NULL) {
> +    DEBUG ((DEBUG_INFO, "SA Global NVS table not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +  ///
> +  /// Our exit status is determined by the success of the previous operations
> +  /// If the protocol was found, Instance already points to it.
> +  /// Read tables from the storage file.
> +  ///
> +  Instance      = 0;
> +  CurrentTable  = NULL;
> +  while (Status == EFI_SUCCESS) {
> +    Status = FwVol->ReadSection (
> +                      FwVol,
> +                      &gSaSsdtAcpiTableStorageGuid,
> +                      EFI_SECTION_RAW,
> +                      Instance,
> +                      (VOID **) &CurrentTable,
> +                      &Size,
> +                      &FvStatus
> +                      );
> +
> +    if (!EFI_ERROR (Status)) {
> +      ///
> +      /// Check the table ID to modify the table
> +      ///
> +      if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId ==
> SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0)) {
> +        SaAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> +        ///
> +        /// Locate the SSDT package
> +        ///
> +        CurrPtr = (UINT8 *) SaAcpiTable;
> +        EndPtr  = CurrPtr + SaAcpiTable->Length;
> +
> +        for (; CurrPtr <= EndPtr; CurrPtr++) {
> +          Signature = (UINT32 *) (CurrPtr + 3);
> +          if (*Signature == SIGNATURE_32 ('S', 'A', 'N', 'V')) {
> +            ASSERT (*(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) ==
> 0xFFFF0000);
> +            ASSERT (*(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof
> (UINT32) + 1) == 0xAA55);
> +            ///
> +            /// SA Global NVS Area address
> +            ///
> +            *(UINT32 *) (CurrPtr + 3 + sizeof (*Signature) + 2) = (UINT32) (UINTN)
> mSaNvsAreaProtocol.Area;
> +            ///
> +            /// SA Global NVS Area size
> +            ///
> +            *(UINT16 *) (CurrPtr + 3 + sizeof (*Signature) + 2 + sizeof (UINT32) +
> 1) =
> +              sizeof (SYSTEM_AGENT_NVS_AREA);
> +
> +            AcpiTableKey = 0;
> +            Status = AcpiTable->InstallAcpiTable (
> +                                  AcpiTable,
> +                                  SaAcpiTable,
> +                                  SaAcpiTable->Length,
> +                                  &AcpiTableKey
> +                                  );
> +            ASSERT_EFI_ERROR (Status);
> +            return EFI_SUCCESS;
> +          }
> +        }
> +      }
> +      ///
> +      /// Increment the instance
> +      ///
> +      Instance++;
> +      CurrentTable = NULL;
> +    }
> +  }
> +
> +  return Status;
> +
> +}
> +
> +/**
> +  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 SwitchableGraphics 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,
> SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 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,
> SA_MC_BUS, 2, 0, R_SA_IGD_VID)) != 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;
> +  CPU_FAMILY                CpuFamilyId;
> +  EFI_EVENT                 EndOfDxeEvent;
> +
> +  CpuFamilyId = GetCpuFamily();
> +  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
> (PcdPciExpressBaseAddress));
> +  mSaNvsAreaProtocol.Area->CpuIdInfo            = CpuidRegs.RegEax;
> +  if (mSaConfigHob != NULL) {
> +    mSaNvsAreaProtocol.Area->IpuAcpiMode =
> mSaConfigHob->IpuAcpiMode;
> +  }
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gSaNvsAreaProtocolGuid,
> +                  &mSaNvsAreaProtocol,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// PciExpress Dxe Initialization
> +  ///
> +  DEBUG ((DEBUG_INFO, "Initializing PciExpress (Dxe)\n"));
> +  PciExpressInit (mSaPolicy);
> +
> +  ///
> +  /// GtPostInit Initialization
> +  ///
> +  DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
> +
> +  GraphicsInit (ImageHandle, mSaPolicy);
> +
> +  /// 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 = InitializeSaSsdtAcpiTables ();
> +
> +  ///
> +  /// Install PEG SSDT table only if PEG port is present
> +  ///
> +  if (IsPchLinkDmi (CpuFamilyId)) {
> +    if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM,
> R_SA_PEG_DID_OFFSET)) != V_SA_DEVICE_ID_INVALID) {
> +      Status = InstallSsdtAcpiTable (gPegSsdtAcpiTableStorageGuid,
> SIGNATURE_64 ('P','e','g','S','s','d','t',0));
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> new file mode 100644
> index 0000000000..40bb107ad0
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
> @@ -0,0 +1,179 @@
> +/** @file
> +  This is the Common driver that initializes the Intel System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInit.h"
> +#include <Library/PciSegmentLib.h>
> +#include <Private/SaConfigHob.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +
> +//
> +// Declare I/O Ports used to perform PCI Confguration Cycles
> +//
> +#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8
> +#define PCI_CONFIGURATION_DATA_PORT     0xCFC
> +
> +/**
> +  Convert a PCI Library address to PCI CF8 formatted address.
> +
> +  Declare macro to convert PCI Library address to PCI CF8 formatted address.
> +  Bit fields of PCI Library and CF8 formatted address is as follows:
> +  PCI Library formatted address    CF8 Formatted Address
> + =============================    ======================
> +    Bits 00..11  Register           Bits 00..07  Register
> +    Bits 12..14  Function           Bits 08..10  Function
> +    Bits 15..19  Device             Bits 11..15  Device
> +    Bits 20..27  Bus                Bits 16..23  Bus
> +    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)
> +                                    Bits 31..31  Must be 1
> +
> +  @param  A The address to convert.
> +
> +  @retval The coverted address.
> +
> +**/
> +#define PCI_TO_CF8_ADDRESS(A) \
> +  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
> +
> +///
> +/// 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 SaPcieInitPolicy().
> +*/
> +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
> +  )
> +{
> +  ///
> +  /// Get SaConfigHob HOB
> +  ///
> +  mSaConfigHob              = NULL;
> +  mSaConfigHob              = (SA_CONFIG_HOB *) GetFirstGuidHob
> (&gSaConfigHobGuid);
> +  if (mSaConfigHob != NULL) {
> +    mSkipPamLock = mSaConfigHob->SkipPamLock;
> +  }
> +
> +  return;
> +}
> +
> +
> +
> +/**
> +  Common function locks the PAM register as part of the SA Security
> requirements.
> +
> +  @retval EFI_SUCCESS   - Always.
> +**/
> +
> +VOID
> +SaPamLock (
> +  VOID
> +  )
> +{
> +  UINT64 BaseAddress;
> +  UINT32 Data32Or;
> +
> +  if (mSkipPamLock == FALSE) {
> +    //
> +    // Lock PAM by PAM Lock Bit
> +    //
> +    BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, 0, 0, 0);
> +    Data32Or    = BIT0;
> +    DEBUG ((DEBUG_INFO, "PAM_LOCK!!\n"));
> +    PciSegmentOr32 (BaseAddress + R_SA_PAM0, Data32Or);
> +  }
> +}
> +
> +/**
> +  This function does SA security lock
> +**/
> +VOID
> +SaSecurityLock (
> +  VOID
> +  )
> +{
> +  UINT8           Index;
> +  UINT32          RegOffset;
> +  UINT32          Data32Or;
> +  UINT32          Data32;
> +  UINT8           Data8;
> +
> +  ///
> +  /// 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++) {
> +    RegOffset   = mSaSecurityRegisters[Index].Offset;
> +    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);
> +      Data8 = PciCf8Read8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV,
> SA_MC_FUN, R_SA_SMRAMC));
> +      Data32 = PCI_TO_CF8_ADDRESS (PCI_CF8_LIB_ADDRESS (SA_MC_BUS,
> SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC));
> +      S3BootScriptSaveIoWrite (
> +        S3BootScriptWidthUint32,
> +        (UINTN) (PCI_CONFIGURATION_ADDRESS_PORT),
> +        1,
> +        &Data32
> +        );
> +      S3BootScriptSaveIoWrite (
> +        S3BootScriptWidthUint8,
> +        (UINTN) (PCI_CONFIGURATION_DATA_PORT),
> +        1,
> +        &Data8
> +        );
> +    }
> +  }
> +}
> +
> +/**
> +  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
> (PcdPciExpressBaseAddress);
> +    }
> +  }
> +  SaSecurityLock ();
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> new file mode 100644
> index 0000000000..d646e60618
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
> @@ -0,0 +1,122 @@
> +/** @file
> +  This is the driver that initializes the Intel System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include <Private/SaConfigHob.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +#include <MemInfoHob.h>
> +
> +///
> +/// 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;
> +
> +  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
> +
> +  SaInitEntryPoint ();
> +
> +  Status = SaAcpiInit (ImageHandle);
> +
> +  ///
> +  /// Create PCI Enumeration Completed callback for SA
> +  ///
> +  EfiCreateProtocolNotifyEvent (
> +    &gEfiPciEnumerationCompleteProtocolGuid,
> +    TPL_CALLBACK,
> +    SaPciEnumCompleteCallback,
> +    NULL,
> +    &Registration
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function gets registered as a callback to perform SA 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
> +SaPciEnumCompleteCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS          Status;
> +  VOID                *ProtocolPointer;
> +
> +  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback 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);
> +
> +  Status = PegInitBeforeEndOfDxe ();
> +  if (EFI_SUCCESS != Status) {
> +    DEBUG ((DEBUG_WARN, "[SA] Pcie initialization before EndOfDxe Error,
> Status = %r \n", Status));
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  SaSaveRestore ();
> +  SaSecurityInit ();
> +  UpdateDmarPciEnumCompleteCallback ();
> +
> +  DEBUG ((DEBUG_INFO, "SaPciEnumCompleteCallback End\n"));
> +  return;
> +}
> +
> +/**
> +  This function locks the PAM register as part of the SA Security requirements.
> +
> +  @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
> +SaPamLockDxe (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "SaPamLockDxe Start\n"));
> +
> +  SaPamLock ();
> +
> +  DEBUG ((DEBUG_INFO, "SaPamLockDxe End\n"));
> +}
> diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> new file mode 100644
> index 0000000000..acbf6b7aab
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
> @@ -0,0 +1,717 @@
> +/** @file
> +  This code provides a initialization of intel VT-d (Virtualization Technology
> for Directed I/O).
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaInitDxe.h"
> +#include "SaInit.h"
> +#include "VTd.h"
> +#include <CpuRegs.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <PchInfoHob.h>
> +#include <PchAccess.h>
> +
> +
> +extern SA_CONFIG_HOB                                          *mSaConfigHob;
> +
> +/**
> +  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}, {0x1400, 0x80}, {0x1401, 0x80},
> {0x1607, 0x8F}};
> +
> +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 < sizeof (mDevEnMap) / 4; 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 (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 (PcdIoApicBaseAddress);
> +  ///
> +  /// Get current IO APIC ID
> +  ///
> +  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_INDEX_OFFSET), 0);
> +  IoApicId = MmioRead32 ((UINTN) (IoApicAddress +
> R_IO_APIC_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.StartBusNum
> ber = Bus;
> +        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> +        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> +        //
> +        // Update APIC ID
> +        //
> +
> DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationI
> d = 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.StartBusNum
> ber = 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) {
> +      NeedRemove = FALSE;
> +    }
> +    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;
> +  UINTN               MchBar;
> +  UINT16              IgdMode;
> +  UINT16              GttMode;
> +  UINT32              IgdMemSize;
> +  UINT32              GttMemSize;
> +  EFI_STATUS          Status;
> +  MISC_DXE_CONFIG     *MiscDxeConfig;
> +
> +  IgdMemSize  = 0;
> +  GttMemSize  = 0;
> +  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
> +
> +  Status = GetConfigBlock ((VOID *) mSaPolicy, &gMiscDxeConfigGuid, (VOID
> *)&MiscDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
> +  ///
> +  if (mInterruptRemappingSupport) {
> +    DmarTable->DmarHeader.Flags |= BIT0;
> +  }
> +
> +  if (mSaConfigHob->VtdData.X2ApicOptOut == 1) {
> +    DmarTable->DmarHeader.Flags |= BIT1;
> +  } else {
> +    DmarTable->DmarHeader.Flags &= 0xFD;
> +  }
> +
> +  ///
> +  /// 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);
> +  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR)
> & ~BIT0;
> +  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);
> +  }
> +
> +  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   =
> (PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & ~(0x01)) -
> IgdMemSize - GttMemSize;
> +  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));
> +
> +  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> = MiscDxeConfig->RmrrUsbBaseAddress[0];
> +  DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> = MiscDxeConfig->RmrrUsbBaseAddress[1];
> +
> +  ///
> +  /// Convert to 4KB alignment.
> +  ///
> +  if
> (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress !=
> 0x0) {
> +    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
> +    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> &= (EFI_PHYSICAL_ADDRESS) ~0xFFF;
> +    DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress
> += 0x1000-1;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "RMRR Base  address USB %016lX\n",
> DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress));
> +  DEBUG ((DEBUG_INFO, "RMRR Limit address USB %016lX\n",
> DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +
> +  if (DmarTable->RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress
> == 0) {
> +    DEBUG ((DEBUG_WARN, "WARNING:
> RmrrUsb.RmrrHeader.ReservedMemoryRegionBaseAddress is 0.\n"));
> +  }
> +
> +  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress
> = MiscDxeConfig->RmrrCsmeBaseAddress[0];
> +  DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress
> = MiscDxeConfig->RmrrCsmeBaseAddress[1];
> +  DEBUG ((DEBUG_INFO, "RMRR Base  address CSME %016lX\n",
> DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionBaseAddress));
> +  DEBUG ((DEBUG_INFO, "RMRR Limit address CSME %016lX\n",
> DmarTable->RmrrCsme.RmrrHeader.ReservedMemoryRegionLimitAddress));
> +  ///
> +  /// Update DRHD structures of DmarTable
> +  ///
> +  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress =
> (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
> +  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress =
> (MmioRead32 (MchBar + R_SA_MCHBAR_VTD3_OFFSET) &~1);
> +
> +  DEBUG ((DEBUG_INFO, "VTD base address1 %x\n",
> DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
> +  DEBUG ((DEBUG_INFO, "VTD base address3 %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);
> +
> +  ///
> +  /// Update RMRR structures of temp DMAR table
> +  ///
> +  UpdateRmrr ((VOID *) &TempDmarTable.RmrrUsb);
> +  UpdateRmrr ((VOID *) &TempDmarTable.RmrrIgd);
> +  UpdateRmrr ((VOID *) &TempDmarTable.RmrrCsme);
> +
> +  ///
> +  /// 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.RmrrUsb.RmrrHeader.Header.Length != 0) {
> +    StructureLen = TempDmarTable.RmrrUsb.RmrrHeader.Header.Length;
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrUsb,
> TempDmarTable.RmrrUsb.RmrrHeader.Header.Length);
> +    Offset += StructureLen;
> +  }
> +  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;
> +  }
> +  if (TempDmarTable.RmrrCsme.RmrrHeader.Header.Length != 0) {
> +    StructureLen = TempDmarTable.RmrrCsme.RmrrHeader.Header.Length;
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrCsme,
> TempDmarTable.RmrrCsme.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);
> +}
> +
> +/**
> +  PciEnumerationComplete routine for update DMAR
> +**/
> +VOID
> +UpdateDmarPciEnumCompleteCallback (
> +  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, "UpdateDmarPciEnumCompleteCallback \n"));
> +
> +
> +  ///
> +  /// Fix DMAR Table always created, skip install when disabled
> +  ///
> +  if ((mSaConfigHob->VtdData.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
> +      ///
> +      switch (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature) {
> +
> +        case EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE:
> +          VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> +          DmarTableUpdate (VtdAcpiTable, &Version);
> +          break;
> +
> +        default:
> +          break;
> +      }
> +      ///
> +      /// Increment the instance
> +      ///
> +      Instance++;
> +      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;
> +  UINTN                           MchBar;
> +  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
> +
> +  mInterruptRemappingSupport  = FALSE;
> +  mSaConfigHob       = NULL;
> +  mSaConfigHob = GetFirstGuidHob (&gSaConfigHobGuid);
> +  if (mSaConfigHob != NULL) {
> +    mInterruptRemappingSupport  =
> mSaConfigHob->VtdData.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,
> SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, 0);
> +  mSaPolicy        = SaPolicy;
> +  MchBar           = PciSegmentRead32(McD0BaseAddress + R_SA_MCHBAR)
> & ~BIT0;
> +
> +  if (mSaConfigHob != NULL) {
> +    SaNvsAreaProtocol->Area->VtdDisable =
> mSaConfigHob->VtdData.VtdDisable;
> +  }
> +  SaNvsAreaProtocol->Area->VtdBaseAddress1 = (MmioRead32(MchBar +
> R_SA_MCHBAR_VTD1_OFFSET) &~1);
> +  SaNvsAreaProtocol->Area->VtdBaseAddress3 = (MmioRead32(MchBar +
> R_SA_MCHBAR_VTD3_OFFSET) &~1);
> +  SaNvsAreaProtocol->Area->VtdEngine1Vid =
> PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
> +
> +  if (mSaConfigHob != NULL) {
> +    if ((mSaConfigHob->VtdData.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/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> new file mode 100644
> index 0000000000..08fd9266c6
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAcce
> ssDriver.c
> @@ -0,0 +1,356 @@
> +/** @file
> +  This is the driver that publishes the SMM Access Protocol
> +  instance for System Agent.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SmmAccessDriver.h"
> +
> +static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
> +
> +
> +/**
> +  This is the standard EFI driver point that
> +  installs an SMM Access Protocol
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS           - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED    - Protocol was not installed
> +  @retval EFI_NOT_FOUND         - Protocol can't be found.
> +  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough
> resources to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           Index;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  EFI_PEI_HOB_POINTERS            *Hob;
> +
> +  ///
> +  /// --cr-- INITIALIZE_SCRIPT (ImageHandle, SystemTable);
> +  ///
> +  /// Initialize Global variables
> +  ///
> +  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
> +
> +  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> +  mSmmAccess.Handle           = NULL;
> +
> +  ///
> +  /// Get Hob list
> +  ///
> +  Hob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid);
> +  if (Hob == NULL) {
> +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
> +
> +  ///
> +  /// Alloc space for mSmmAccess.SmramDesc
> +  ///
> +  mSmmAccess.SmramDesc = AllocateZeroPool
> ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof
> (EFI_SMRAM_DESCRIPTOR));
> +  if (mSmmAccess.SmramDesc == NULL) {
> +    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
> +
> +  ///
> +  /// Use the HOB to publish SMRAM capabilities
> +  ///
> +  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions;
> Index++) {
> +    mSmmAccess.SmramDesc[Index].PhysicalStart =
> DescriptorBlock->Descriptor[Index].PhysicalStart;
> +    mSmmAccess.SmramDesc[Index].CpuStart      =
> DescriptorBlock->Descriptor[Index].CpuStart;
> +    mSmmAccess.SmramDesc[Index].PhysicalSize  =
> DescriptorBlock->Descriptor[Index].PhysicalSize;
> +    mSmmAccess.SmramDesc[Index].RegionState   =
> DescriptorBlock->Descriptor[Index].RegionState;
> +  }
> +
> +  mSmmAccess.NumberRegions              = Index;
> +  mSmmAccess.SmmAccess.Open             = Open;
> +  mSmmAccess.SmmAccess.Close            = Close;
> +  mSmmAccess.SmmAccess.Lock             = Lock;
> +  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
> +  mSmmAccess.SmmAccess.LockState        = FALSE;
> +  mSmmAccess.SmmAccess.OpenState        = FALSE;
> +
> +  ///
> +  /// Install our protocol interfaces on the device's handle
> +  ///
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mSmmAccess.Handle,
> +                  &gEfiSmmAccess2ProtocolGuid,
> +                  &mSmmAccess.SmmAccess,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned
> %r\n", Status));
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all boot-service
> +  and SMM agents.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINT64                  Address;
> +  UINT8                   SmramControl;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  ///
> +  /// BEGIN CHIPSET SPECIFIC CODE
> +  ///
> +  ///
> +  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> +  ///
> +  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> +  SmramControl = PciRead8 (Address);
> +  ///
> +  ///  Is SMRAM locked?
> +  ///
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
> +      ///
> +      /// Cannot Open a locked region
> +      ///
> +      SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +  ///
> +  /// Open SMRAM region
> +  ///
> +  SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
> +  SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
> +
> +  PciWrite8 (Address, SmramControl);
> +  ///
> +  /// END CHIPSET SPECIFIC CODE
> +  ///
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> EFI_SMRAM_OPEN;
> +  }
> +  SmmAccess->SmmAccess.OpenState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM agents,
> +  not from BS or RT code.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINT64                  Address;
> +  UINT8                   SmramControl;
> +  BOOLEAN                 OpenState;
> +  UINT8                   Index;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +      continue;
> +    }
> +
> +    ///
> +    /// BEGIN CHIPSET SPECIFIC CODE
> +    ///
> +    ///
> +    /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> +    ///
> +    Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> +    SmramControl = PciRead8 (Address);
> +    ///
> +    ///  Is SMRAM locked?
> +    ///
> +    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
> +      ///
> +      /// Cannot Close a locked region
> +      ///
> +      SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +    ///
> +    /// Close SMRAM region
> +    ///
> +    SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
> +
> +    PciWrite8 (Address, SmramControl);
> +    ///
> +    /// END CHIPSET SPECIFIC CODE
> +    ///
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~EFI_SMRAM_OPEN;
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +  }
> +
> +  ///
> +  /// Find out if any regions are still open
> +  ///
> +  OpenState = FALSE;
> +  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
> +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) ==
> EFI_SMRAM_OPEN) {
> +      OpenState = TRUE;
> +    }
> +  }
> +
> +  SmmAccess->SmmAccess.OpenState = OpenState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                                  one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINT64                  Address;
> +  UINT8                   SmramControl;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  if (SmmAccess->SmmAccess.OpenState) {
> +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are
> still open\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> EFI_SMRAM_LOCKED;
> +  }
> +  SmmAccess->SmmAccess.LockState = TRUE;
> +
> +  ///
> +  /// BEGIN CHIPSET SPECIFIC CODE
> +  ///
> +  ///
> +  /// SMRAM register is PCI 0:0:0:88, SMRAMC (8 bit)
> +  ///
> +  Address = PCI_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_SMRAMC);
> +
> +  SmramControl = PciRead8 (Address);
> +  ///
> +  /// Lock the SMRAM
> +  ///
> +  SmramControl |= B_SA_SMRAMC_D_LCK_MASK;
> +
> +  PciWrite8 (Address, SmramControl);
> +  ///
> +  /// END CHIPSET SPECIFIC CODE
> +  ///
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size
> of the
> +                                     buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing
> the Smram
> +                                     region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  EFI_STATUS              Status;
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   NecessaryBufferSize;
> +
> +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> (EFI_SMRAM_DESCRIPTOR);
> +
> +  if (*SmramMapSize < NecessaryBufferSize) {
> +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> +    Status = EFI_BUFFER_TOO_SMALL;
> +  } else {
> +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  *SmramMapSize = NecessaryBufferSize;
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> new file mode 100644
> index 0000000000..c864a0ca8f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.asl
> c
> @@ -0,0 +1,250 @@
> +/** @file
> +  This file describes the contents of the ACPI DMA address Remapping
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "Dmar.h"
> +#include <Register/PchRegsP2sb.h>
> +
> +EFI_ACPI_DMAR_TABLE DmarTable = {
> +  //
> +  // EFI_ACPI_DMAR_HEADER
> +  //
> +  {
> +    //
> +    // EFI_ACPI_DESCRIPTION_HEADER
> +    //
> +    {
> +      EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE,
> +      sizeof (EFI_ACPI_DMAR_TABLE),
> +      EFI_ACPI_DMAR_TABLE_REVISION,
> +
> +      //
> +      // Checksum will be updated at runtime
> +      //
> +      0x00,
> +
> +      //
> +      // It is expected that these values will be programmed at runtime
> +      //
> +      { 'I', 'N', 'T', 'E', 'L', ' ' },
> +      EFI_ACPI_DMAR_OEM_TABLE_ID,
> +      0x1,
> +      EFI_ACPI_DMAR_OEM_CREATOR_ID,
> +      1
> +    },
> +
> +    //
> +    // DMAR table specific entries below:
> +    //
> +
> +    //
> +    // 39-bit addressing Host Address Width
> +    //
> +    38,
> +
> +    //
> +    // Flags
> +    //
> +    0,
> +
> +    //
> +    // Reserved fields
> +    //
> +    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
> +  },
> +
> +  //
> +  // First DRHD structure, VT-d Engine #1
> +  //
> +  {
> +    //
> +    // EFI_ACPI_DMAR_DRHD_HEADER
> +    //
> +    {
> +      {0,                                         // Type = 0 (DRHD)
> +      sizeof (EFI_ACPI_DRHD_ENGINE1_STRUCT)},     // Length of structure
> +      0,                                          // Flag - Do not include all
> +      0,                                          // Reserved fields
> +      0,                                          // Segment
> +      0                                           // Base address of DMA-remapping
> hardware - Updated at boot time
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                     // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),  // Length
> +        0,                                      // Segment number
> +        0,                                      // Reserved
> +        0},                                     // Start bus number
> +        {2, 0}                                  // PCI path
> +      }
> +    }
> +  },
> +
> +  //
> +  //Third DRHD structure VT-d Engine# 3
> +  //
> +  {
> +    //
> +    // EFI_ACPI_DMAR_DRHD_HEADER
> +    //
> +    {
> +      {0,                                        // Type = 0 (DRHD)
> +      sizeof (EFI_ACPI_DRHD_ENGINE3_STRUCT)},    // Length of strucure.
> +      1,                                         // Flag - Include all
> +      0,                                         // Reserved
> +      0,                                         // Segment Number
> +      0                                          // Base address of DMA-remapping
> hardware.
> +    },
> +    {
> +      //
> +      // Device Scopes
> +      //
> +      {
> +        {3,                                          // Type=IO APIC
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
> +        0,                                           // Reserved
> +        2,                                           // Enumeration ID
> +        V_P2SB_CFG_IBDF_BUS},                        // Start bus number
> +        {V_P2SB_CFG_IBDF_DEV, V_P2SB_CFG_IBDF_FUNC}  // PCI path
> +      },
> +      //
> +      // Device Scopes
> +      //
> +      {
> +        {4,                                          // Type=HPET
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE),       // Length
> +        0,                                           // Reserved
> +        0,                                           // Enumeration ID
> +        V_P2SB_CFG_HBDF_BUS},                        // Start bus number
> +        {V_P2SB_CFG_HBDF_DEV, V_P2SB_CFG_HBDF_FUNC}  // PCI path
> +      }
> +    }
> +  },
> +  //RMRR structure for USB devices.
> +  {
> +    //
> +    // EFI_ACPI_DMAR_RMRR_HEADER
> +    //
> +    {
> +      {
> +        0x1,                                     // Type 1 - RMRR structure
> +        sizeof(EFI_ACPI_RMRR_USB_STRUC)          // Length
> +      },
> +      { 0x00, 0x00 },                            // Reserved
> +      0x0000,                                    // Segment Num
> +      0x00000000000E0000,                        // RMRR Base address - Updated
> in runtime.
> +      0x00000000000EFFFF                         // RMRR Limit address - Updated
> in runtime.
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                    // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                     // Reserved
> +        0,                                     // Enum ID
> +        0},                                    // Start bus number
> +        {20, 0}                                // PCI path
> +      },
> +      {
> +        {1,                                    // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                     // Reserved
> +        0,                                     // Enum ID
> +        0},                                    // Start bus number
> +        {20, 1}                                // PCI path
> +      }
> +    }
> +  },
> +
> +  //RMRR structure for IGD device.
> +  {
> +    //
> +    // EFI_ACPI_DMAR_RMRR_HEADER
> +    //
> +    {
> +      {1,                                       // Type 1 - RMRR structure
> +      sizeof (EFI_ACPI_RMRR_IGD_STRUC)},        // Length
> +      {0x0000},                                 // Reserved
> +      0x0000,                                   // Segment Num
> +      0x0000000000000000,                       // RMRR Base address - Updated
> in runtime.
> +      0x0000000000000000                        // RMRR Limit address - Updated
> in runtime.
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                   // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                    // Reserved
> +        0,                                    // Enum ID
> +        0},                                   // Start bus number
> +        {2, 0}                                // PCI path
> +      }
> +    }
> +  },
> +
> +  // RMRR structure for WiAMT DMA access.
> +  // Keep this device in end of RMRR queue.
> +  {
> +    //
> +    // EFI_ACPI_DMAR_RMRR_HEADER
> +    //
> +    {
> +      {1,                                       // Type 1 - RMRR structure
> +      sizeof (EFI_ACPI_RMRR_CSME_STRUC)},       // Length
> +      {0x0000},                                 // Reserved
> +      0x0000,                                   // Segment Num
> +      0x0000000000000000,                       // RMRR Base address - Updated
> in runtime.
> +      0x0000000000000000                        // RMRR Limit address - Updated
> in runtime.
> +    },
> +    //
> +    // Device Scopes
> +    //
> +    {
> +      {
> +        {1,                                   // Type
> +        sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE), // Length
> +        0,                                    // Reserved
> +        0,                                    // Enum ID
> +        0},                                   // Start bus number
> +        {22, 7}                               // PCI path
> +      }
> +    }
> +  }
> +};
> +
> +//
> +// Dummy function required for build tools
> +//
> +#if defined (__GNUC__)
> +VOID*
> +ReferenceAcpiTable (
> +  VOID
> +  )
> +
> +{
> +  //
> +  // Reference the table being generated to prevent the optimizer from
> removing the
> +  // data structure from the exeutable
> +  //
> +  return (VOID*)&DmarTable;
> +}
> +#else
> +int
> +main (
> +  VOID
> +  )
> +{
> +  return 0;
> +}
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> new file mode 100644
> index 0000000000..b431a77f05
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
> @@ -0,0 +1,794 @@
> +/** @file
> +  This file contains the SystemAgent PCI Configuration space
> +  definition.
> +  It defines various System Agent PCI Configuration Space registers
> +  which will be used to dynamically produce all resources in the Host Bus.
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(M64B)
> +External(M64L)
> +External(M32B)
> +External(M32L)
> +
> +//
> +// Define various System Agent (SA) PCI Configuration Space
> +// registers which will be used to dynamically produce all
> +// resources in the Host Bus _CRS.
> +//
> +OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
> +Field (HBUS, DWordAcc, NoLock, Preserve)
> +{
> +  Offset(0x40),   // EPBAR (0:0:0:40)
> +  EPEN, 1,        // Enable
> +      , 11,
> +  EPBR, 20,       // EPBAR [31:12]
> +
> +  Offset(0x48),   // MCHBAR (0:0:0:48)
> +  MHEN, 1,        // Enable
> +      , 14,
> +  MHBR, 17,       // MCHBAR [31:15]
> +
> +  Offset(0x50),   // GGC (0:0:0:50)
> +  GCLK, 1,        // GGCLCK
> +
> +  Offset(0x54),   // DEVEN (0:0:0:54)
> +  D0EN, 1,        // DEV0 Enable
> +  D1F2, 1,        // DEV1 FUN2 Enable
> +  D1F1, 1,        // DEV1 FUN1 Enable
> +  D1F0, 1,        // DEV1 FUN0 Enable
> +
> +  Offset(0x60),   // PCIEXBAR (0:0:0:60)
> +  PXEN, 1,        // Enable
> +  PXSZ, 2,        // PCI Express Size
> +      , 23,
> +  PXBR, 6,        // PCI Express BAR [31:26]
> +
> +  Offset(0x68),   // DMIBAR (0:0:0:68)
> +  DIEN, 1,        // Enable
> +      , 11,
> +  DIBR, 20,       // DMIBAR [31:12]
> +
> +  Offset(0x70),   // MESEG_BASE (0:0:0:70)
> +      , 20,
> +  MEBR, 12,       // MESEG_BASE [31:20]
> +
> +  Offset(0x80),   // PAM0 Register (0:0:0:80)
> +  PMLK, 1,        // PAM Lock bit.
> +      , 3,
> +  PM0H, 2,        // PAM 0, High Nibble
> +      , 2,
> +
> +  Offset(0x81),   // PAM1 Register (0:0:0:81)
> +  PM1L, 2,        // PAM1, Low  Nibble
> +      , 2,
> +  PM1H, 2,        // PAM1, High Nibble
> +      , 2,
> +
> +  Offset(0x82),   // PAM2 Register (0:0:0:82)
> +  PM2L, 2,        // PAM2, Low  Nibble
> +      , 2,
> +  PM2H, 2,        // PAM2, High Nibble
> +      , 2,
> +
> +  Offset(0x83),   // PAM3 Register (0:0:0:83)
> +  PM3L, 2,        // PAM3, Low  Nibble
> +      , 2,
> +  PM3H, 2,        // PAM3, High Nibble
> +      , 2,
> +
> +  Offset(0x84),   // PAM4 Register (0:0:0:84)
> +  PM4L, 2,        // PAM4, Low  Nibble
> +      , 2,
> +  PM4H, 2,        // PAM4, High Nibble
> +      , 2,
> +
> +  Offset(0x85),   // PAM5 Register (0:0:0:85)
> +  PM5L, 2,        // PAM5, Low  Nibble
> +      , 2,
> +  PM5H, 2,        // PAM5, High Nibble
> +      , 2,
> +
> +  Offset(0x86),   // PAM6 Register (0:0:0:86)
> +  PM6L, 2,        // PAM6, Low  Nibble
> +      , 2,
> +  PM6H, 2,        // PAM6, High Nibble
> +      , 2,
> +
> +  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
> +      , 20,
> +  TUUD, 19,       // TOUUD [38:20]
> +
> +  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
> +      , 20,
> +  TLUD, 12,       // TOLUD [31:20]
> +
> +  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
> +      , 7,
> +  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
> +}
> +//
> +// Define a buffer that will store all the bus, memory, and IO information
> +// relating to the Host Bus.  This buffer will be dynamically altered in
> +// the _CRS and passed back to the OS.
> +//
> +Name(BUF0,ResourceTemplate()
> +{
> +  //
> +  // Bus Number Allocation: Bus 0 to 0xFF
> +  //
> +  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
> +    0x0000,0x00FF,0x00,0x0100,,,PB00)
> +
> +  //
> +  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
> +
> +  //
> +  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
> +  //
> +  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
> +
> +  //
> +  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
> +
> +  //
> +  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
> +
> +  //
> +  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
> +
> +  //
> +  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
> +
> +  //
> +  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
> +
> +  //
> +  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
> +
> +  //
> +  // BIOS Area ( 0xF0000 - 0xFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
> +
> +//  //
> +//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
> +//  //
> +//
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
> +
> +  //
> +  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
> +
> +  //
> +  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
> +  // (This is dummy range for OS compatibility, will patch it in _CRS)
> +  //
> +
> QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
> +
> +  //
> +  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
> +})
> +
> +  //
> +  // SA reserved resources
> +  //
> +  Device(SRRE) {
> +    Name(_HID,EISAID("PNP0C02")) // motherboard resource
> +    Name(_UID,"SARESV")
> +    Method(_STA,0,Serialized) // device present and decodes its resources,
> but not to be displayed in OSPM
> +    {
> +      If(LGreaterEqual(TLUD, 0x404)) {
> +        Return (3)
> +      } Else {
> +        Return (0)
> +      }
> +    }
> +
> +    Method(_CRS,0,Serialized)
> +    {
> +      Name(BUF0,ResourceTemplate(){
> +        //
> +        // Reserve the 0x40000000 ~ 0x403FFFFF to prevent other driver use this
> memory range
> +        //
> +        Memory32Fixed(ReadOnly,0x40000000,0x400000)
> +      })
> +      If(LGreaterEqual(TLUD, 0x404)) {
> +        Return (BUF0)
> +      } Else {
> +        Return (Buffer(){})
> +      }
> +    }
> +  }
> +
> +Name(EP_B, 0) // to store EP BAR
> +Name(MH_B, 0) // to store MCH BAR
> +Name(PC_B, 0) // to store PCIe BAR
> +Name(PC_L, 0) // to store PCIe BAR Length
> +Name(DM_B, 0) // to store DMI BAR
> +
> +//
> +// Get EP BAR
> +//
> +Method(GEPB,0,Serialized)
> +{
> +  if(LEqual(EP_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
> +  }
> +  Return(EP_B)
> +}
> +
> +//
> +// Get MCH BAR
> +//
> +Method(GMHB,0,Serialized)
> +{
> +  if(LEqual(MH_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
> +  }
> +  Return(MH_B)
> +}
> +
> +//
> +// Get PCIe BAR
> +//
> +Method(GPCB,0,Serialized)
> +{
> +  if(LEqual(PC_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
> +  }
> +  Return(PC_B)
> +}
> +
> +//
> +// Get PCIe Length
> +//
> +Method(GPCL,0,Serialized)
> +{
> +  if(LEqual(PC_L,0)) {
> +    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
> +  }
> +  Return(PC_L)
> +}
> +
> +//
> +// Get DMI BAR
> +//
> +Method(GDMB,0,Serialized)
> +{
> +  if(LEqual(DM_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
> +  }
> +  Return(DM_B)
> +}
> +
> +
> +Method(_CRS,0,Serialized)
> +{
> +  //
> +  // Fix up Max Bus Number and Length
> +  //
> +  Store(\_SB.PCI0.GPCL(),Local0)
> +  CreateWordField(BUF0, ^PB00._MAX, PBMX)
> +  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
> +  CreateWordField(BUF0, ^PB00._LEN, PBLN)
> +  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
> +  //
> +  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
> +  //
> +  If(PM1L)  // \_SB.PCI0
> +  {
> +    // PAMx != 0.  Set length = 0.
> +
> +    CreateDwordField(BUF0, ^C000._LEN,C0LN)
> +    Store(Zero,C0LN)
> +  }
> +
> +  If(LEqual(PM1L,1))
> +  {
> +    CreateBitField(BUF0, ^C000._RW,C0RW)
> +    Store(Zero,C0RW)
> +  }
> +
> +  If(PM1H)
> +  {
> +    CreateDwordField(BUF0, ^C400._LEN,C4LN)
> +    Store(Zero,C4LN)
> +  }
> +
> +  If(LEqual(PM1H,1))
> +  {
> +    CreateBitField(BUF0, ^C400._RW,C4RW)
> +    Store(Zero,C4RW)
> +  }
> +
> +  If(PM2L)
> +  {
> +    CreateDwordField(BUF0, ^C800._LEN,C8LN)
> +    Store(Zero,C8LN)
> +  }
> +
> +  If(LEqual(PM2L,1))
> +  {
> +    CreateBitField(BUF0, ^C800._RW,C8RW)
> +    Store(Zero,C8RW)
> +  }
> +
> +  If(PM2H)
> +  {
> +    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
> +    Store(Zero,CCLN)
> +  }
> +
> +  If(LEqual(PM2H,1))
> +  {
> +    CreateBitField(BUF0, ^CC00._RW,CCRW)
> +    Store(Zero,CCRW)
> +  }
> +
> +  If(PM3L)
> +  {
> +    CreateDwordField(BUF0, ^D000._LEN,D0LN)
> +    Store(Zero,D0LN)
> +  }
> +
> +  If(LEqual(PM3L,1))
> +  {
> +    CreateBitField(BUF0, ^D000._RW,D0RW)
> +    Store(Zero,D0RW)
> +  }
> +
> +  If(PM3H)
> +  {
> +    CreateDwordField(BUF0, ^D400._LEN,D4LN)
> +    Store(Zero,D4LN)
> +  }
> +
> +  If(LEqual(PM3H,1))
> +  {
> +    CreateBitField(BUF0, ^D400._RW,D4RW)
> +    Store(Zero,D4RW)
> +  }
> +
> +  If(PM4L)
> +  {
> +    CreateDwordField(BUF0, ^D800._LEN,D8LN)
> +    Store(Zero,D8LN)
> +  }
> +
> +  If(LEqual(PM4L,1))
> +  {
> +    CreateBitField(BUF0, ^D800._RW,D8RW)
> +    Store(Zero,D8RW)
> +  }
> +
> +  If(PM4H)
> +  {
> +    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
> +    Store(Zero,DCLN)
> +  }
> +
> +  If(LEqual(PM4H,1))
> +  {
> +    CreateBitField(BUF0, ^DC00._RW,DCRW)
> +    Store(Zero,DCRW)
> +  }
> +
> +  If(PM5L)
> +  {
> +    CreateDwordField(BUF0, ^E000._LEN,E0LN)
> +    Store(Zero,E0LN)
> +  }
> +
> +  If(LEqual(PM5L,1))
> +  {
> +    CreateBitField(BUF0, ^E000._RW,E0RW)
> +    Store(Zero,E0RW)
> +  }
> +
> +  If(PM5H)
> +  {
> +    CreateDwordField(BUF0, ^E400._LEN,E4LN)
> +    Store(Zero,E4LN)
> +  }
> +
> +  If(LEqual(PM5H,1))
> +  {
> +    CreateBitField(BUF0, ^E400._RW,E4RW)
> +    Store(Zero,E4RW)
> +  }
> +
> +  If(PM6L)
> +  {
> +    CreateDwordField(BUF0, ^E800._LEN,E8LN)
> +    Store(Zero,E8LN)
> +  }
> +
> +  If(LEqual(PM6L,1))
> +  {
> +    CreateBitField(BUF0, ^E800._RW,E8RW)
> +    Store(Zero,E8RW)
> +  }
> +
> +  If(PM6H)
> +  {
> +    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
> +    Store(Zero,ECLN)
> +  }
> +
> +  If(LEqual(PM6H,1))
> +  {
> +    CreateBitField(BUF0, ^EC00._RW,ECRW)
> +    Store(Zero,ECRW)
> +  }
> +
> +  If(PM0H)
> +  {
> +    CreateDwordField(BUF0, ^F000._LEN,F0LN)
> +    Store(Zero,F0LN)
> +  }
> +
> +  If(LEqual(PM0H,1))
> +  {
> +    CreateBitField(BUF0, ^F000._RW,F0RW)
> +    Store(Zero,F0RW)
> +  }
> +
> +  // Enable the 1MB region between 15-16MB if HENA = 1.
> +  //
> +  // If( MCHC.HENA)
> +  // {
> +  // CreateDwordField(BUF0, HOLE._LEN,H0LN)
> +  // Store(0x100000,H0LN)
> +  // }
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  //
> +  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
> +  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
> +  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
> +
> +  //
> +  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
> +  // TOM, so shift these bits into the correct position and fix up
> +  // the Memory Region available to PCI.
> +  //
> +  Store (M32L, M1LN)
> +  Store (M32B, M1MN)
> +  Subtract (Add (M1MN, M1LN), 1, M1MX)
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  // Patch PM02 range basing on memory size and OS type
> +  //
> +  If (LEqual(M64L, 0)) {
> +    CreateQwordField(BUF0, ^PM02._LEN,MSLN)
> +    //
> +    // Set resource length to 0
> +    //
> +    Store (0, MSLN)
> +  }
> +  Else {
> +    CreateQwordField(BUF0, ^PM02._LEN,M2LN)
> +    CreateQwordField(BUF0, ^PM02._MIN,M2MN)
> +    CreateQwordField(BUF0, ^PM02._MAX,M2MX)
> +    //
> +    // Set 64bit MMIO resource Base and Length
> +    //
> +    Store (M64L, M2LN)
> +    Store (M64B, M2MN)
> +    Subtract (Add (M2MN, M2LN), 1, M2MX)
> +  }
> +  Return(BUF0)
> +}
> +
> +//
> +//Name(GUID,UUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))
> +//
> +Name(GUID,Buffer(){0x5b, 0x4d, 0xdb, 0x33,
> +          0xf7, 0x1f,
> +          0x1c, 0x40,
> +          0x96, 0x57,
> +          0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66})
> +
> +
> +Name(SUPP,0)  // PCI _OSC Support Field value
> +Name(CTRL,0)  // PCI _OSC Control Field value
> +Name(XCNT, 0) // Variable used in _OSC for counting
> +
> +Method(_OSC,4,Serialized)
> +{
> +  //
> +  // Check for proper UUID
> +  // Save the capabilities buffer
> +  //
> +  Store(Arg3,Local0)
> +
> +  //
> +  // Create DWord-adressable fields from the Capabilties Buffer
> +  //
> +  CreateDWordField(Local0,0,CDW1)
> +  CreateDWordField(Local0,4,CDW2)
> +  CreateDWordField(Local0,8,CDW3)
> +
> +
> +  //
> +  // Check for proper UUID
> +  //
> +  If(LEqual(Arg0,GUID))
> +  {
> +    // Save Capabilities DWord2 & 3
> +    Store(CDW2,SUPP)
> +    Store(CDW3,CTRL)
> +
> +    //
> +    // You can clear bits in CTRL here if you don't want OS to take
> +    // control
> +    //
> +    If(LNot(NEXP))
> +    {
> +      And(CTRL, 0xFFFFFFF8, CTRL)       // disable Native hot plug, PME
> +    }
> +
> +    If(LEqual(TBTS, 1)) {
> +      // \_OSC disallow only Advanced Error Reporting control
> +      And(CTRL, 0xFFFFFFF7, CTRL)
> +    }
> +
> +    If(Not(And(CDW1,1)))  // Query flag clear?
> +    { // Disable GPEs for features granted native control.
> +      If(And(CTRL,0x01))
> +      {
> +        NHPG()
> +      }
> +      If(And(CTRL,0x04))  // PME control granted?
> +      {
> +        NPME()
> +      }
> +    }
> +
> +    If(LNotEqual(Arg1,One))
> +    {
> +      //
> +      // Unknown revision
> +      //
> +      Or(CDW1,0x08,CDW1)
> +    }
> +
> +    If(LNotEqual(CDW3,CTRL))
> +    {
> +      //
> +      // Capabilities bits were masked
> +      //
> +      Or(CDW1,0x10,CDW1)
> +    }
> +    //
> +    // Update DWORD3 in the buffer
> +    //
> +    Store(CTRL,CDW3)
> +    Store(CTRL,OSCC)
> +    Return(Local0)
> +  } Else {
> +    Or(CDW1,4,CDW1)   // Unrecognized UUID
> +    Return(Local0)
> +  }
> +} // End _OSC
> +
> +//
> +// Added code for Dual IRQ support. Two set of ACPI IRQ tables were
> generated.
> +// Code has been added to select the appropriate IRQ table by checking the
> CPUID.
> +//
> +Scope(\_SB.PCI0)
> +{
> +  Method(AR00) {
> +    Return(\_SB.AR00)
> +  }
> +
> +  Method(PD00) {
> +    Return(\_SB.PD00)
> +  }
> +
> +  Method(AR02) {
> +    Return(\_SB.AR02)
> +  }
> +
> +  Method(PD02) {
> +    Return(\_SB.PD02)
> +  }
> +
> +  Method(AR04) {
> +    Return(\_SB.AR04)
> +  }
> +
> +  Method(PD04) {
> +    Return(\_SB.PD04)
> +  }
> +
> +  Method(AR05) {
> +    Return(\_SB.AR05)
> +  }
> +
> +  Method(PD05) {
> +    Return(\_SB.PD05)
> +  }
> +
> +  Method(AR06) {
> +    Return(\_SB.AR06)
> +  }
> +
> +  Method(PD06) {
> +    Return(\_SB.PD06)
> +  }
> +
> +  Method(AR07) {
> +    Return(\_SB.AR07)
> +  }
> +
> +  Method(PD07) {
> +    Return(\_SB.PD07)
> +  }
> +
> +  Method(AR08) {
> +    Return(\_SB.AR08)
> +  }
> +
> +  Method(PD08) {
> +    Return(\_SB.PD08)
> +  }
> +
> +  Method(AR09) {
> +    Return(\_SB.AR09)
> +  }
> +
> +  Method(PD09) {
> +    Return(\_SB.PD09)
> +  }
> +
> +  Method(AR0A) {
> +    Return(\_SB.AR0A)
> +  }
> +
> +  Method(PD0A) {
> +    Return(\_SB.PD0A)
> +  }
> +
> +  Method(AR0B) {
> +    Return(\_SB.AR0B)
> +  }
> +
> +  Method(PD0B) {
> +    Return(\_SB.PD0B)
> +  }
> +
> +  //
> +  // Add device scope definition for System Agent
> +  // P.E.G. Root Port D1F0
> +  //
> +  Device(PEG0) {
> +    Name(_ADR, 0x00010000)
> +    Device(PEGP) { // P.E.G. Port Slot x16
> +      Name(_ADR, 0x00000000)
> +    }
> +  }
> +  //
> +  // P.E.G. Root Port D1F1
> +  //
> +  Device(PEG1) {
> +    Name(_ADR, 0x00010001)
> +    Device(PEGP) { // P.E.G. Port Slot x8
> +      Name(_ADR, 0x00000000)
> +    }
> +  }
> +  //
> +  // P.E.G. Root Port D1F2
> +  //
> +  Device(PEG2) {
> +    Name(_ADR, 0x00010002)
> +    Device(PEGP) { // P.E.G. Port Slot x4
> +      Name(_ADR, 0x00000000)
> +    }
> +  }
> +  //
> +  // I.G.D
> +  //
> +  Device(GFX0) {
> +    Name(_ADR, 0x00020000)
> +  }
> +  //
> +  // SA Thermal Device
> +  //
> +  Device(B0D4) {
> +    Method(_DSM,4,serialized){if(PCIC(Arg0))
> { return(PCID(Arg0,Arg1,Arg2,Arg3)) }; Return(Buffer() {0})}
> +    Name(_ADR, 0x00040000)
> +  }
> +  //
> +  // Device IPU0 is the IPU PCI device
> +  //
> +  Device(IPU0) {
> +    Name(_ADR, 0x00050000)
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> new file mode 100644
> index 0000000000..e7a797c973
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
> @@ -0,0 +1,1666 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +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)
> +
> +Name(TMP1,Package() {0xFFFFFFFF})
> +Name(TMP2,Package() {0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP3,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP4,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP5,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +Name(TMP6,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP7,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMP8,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF})
> +Name(TMP9,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPA,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF })
> +Name(TMPB,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPC,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPD,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF})
> +Name(TMPE,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF})
> +Name(TMPF,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF})
> +Name(TMPG,Package() {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
> 0xFFFFFFFF, 0xFFFFFFFF,
> +                     0xFFFFFFFF, 0xFFFFFFFF})
> +
> +// 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)
> +{
> +  If (LEqual(IPTP,1)) {
> +    //
> +    // Increment number of devices if IPU is enabled
> +    //
> +    Store(1, NDID)
> +  } Else {
> +    Store(0, 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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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))
> +  {
> +    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(SGMD,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))
> +    {
> +      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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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(SGMD,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.PCI0.GFX0.AINT(1, Arg0)
> +      Store(Arg0,BRTL)  // Store Brightness Level.
> +    }
> +  }
> +
> +  //
> +  // Brightness Query Current level.
> +  //
> +  Method (_BQC,0)
> +  {
> +    Return(BRTL)
> +  }
> +}
> +
> +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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> new file mode 100644
> index 0000000000..7edbe45e2e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCo
> mmon.asl
> @@ -0,0 +1,472 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +/**************************************************************
> **********;
> +;* 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.PCI0.GFX0, Arg1)
> +  }
> +
> +  If(CondRefOf(HNOT))
> +  {
> +    HNOT(Arg0)  //Notification handler for Switchable graphics
> +  }
> +  Else
> +  {
> +    Notify(\_SB.PCI0.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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> new file mode 100644
> index 0000000000..e7b3c92cda
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDs
> m.asl
> @@ -0,0 +1,369 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// _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
> +    //
> +    //
> +    // 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 (0x1E7FF)   // bit 11 and 12 is not supported
> +        }
> +      }
> +
> +      //
> +      // 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> new file mode 100644
> index 0000000000..26e560a358
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Gbda.asl
> @@ -0,0 +1,129 @@
> +/** @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) 2019 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpR
> n.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Rn.asl
> new file mode 100644
> index 0000000000..a26cbdb00c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOp
> Rn.asl
> @@ -0,0 +1,296 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//  Define an OperationRegion to cover the GMCH PCI configuration space as
> +//  described in the IGD OpRegion specificiation.
> +//
> +Scope(\_SB.PCI0)
> +{
> +  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
> +  //
> +  // 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.PCI0.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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> new file mode 100644
> index 0000000000..0167d922ff
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpS
> bcb.asl
> @@ -0,0 +1,262 @@
> +/** @file
> +  This file contains the system BIOS call back functionality for the
> +  OpRegion/Software SCI mechanism.
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> new file mode 100644
> index 0000000000..e4e47ddf1e
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
> @@ -0,0 +1,87 @@
> +/** @file
> +  This file contains the device definition of the System Agent
> +  ACPI reference code.
> +  Currently defines the device objects for the
> +  System Agent IPU device
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Device IPUA is the IPU AVStream virtual device and it appears under GFX0
> +//
> +Scope (\_SB.PCI0.GFX0)
> +{
> +  Device(IPUA) // IPU AVStream virtual device name
> +  {
> +    /*
> +      The identifier for this device (Same as in
> +      _DOD above). This is required so GFX driver can
> +      associate a matching device ID for the AVStream
> +      driver and provide it to PnP (this device ID
> +      should appear in the INF file of the AVStream
> +      driver).
> +    */
> +    Name(_ADR, 0x00003480)
> +    /*
> +      The following is a technique that may be used (per OEM needs) to
> prevent
> +      the load of the camera device in one of the following cases:
> +      - Camera device is fused out
> +      - If the platform setup requires that in a secured boot the camera device
> +      should not be enabled
> +    */
> +    Method (_STA, 0, NotSerialized) {
> +      If(LEqual(IPTP,1)){ // IGFX need report IPU AVStream virtual device as
> GFX0 child
> +        Return (0xF)
> +      } Else { // IGFX should NOT report IPU AVStream virtual device as GFX0
> child
> +        Return (0x0)
> +      }
> +    }
> +  } // End SKC0
> +} // end I.G.D
> +
> +Scope(\_SB.PCI0.IPU0)
> +{
> +//----------------------------------------------------------------------------------------
> +//  Intel Proprietary Passing LTR information from BIOS to IPU Driver. DSM
> Method
> +//
> +//  Method(_DSM, 0x4, Serialized, 0, {IntObj, BuffObj}, {BuffObj, IntObj,
> IntObj, PkgObj})
> +//  Arguments:
> +//  Arg0: GUID: "9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90"
> +//  Arg1: Integer Revision Level (Current revision is 0)
> +//  Arg2: Integer Function Index
> +//                0x1 - return UINT 32bit LTR values
> +//                0x2 - return UINT 32bit Fill Time
> +//
> +//-----------------------------------------------------------------------------------------
> +Method (_DSM, 4, NotSerialized) { // _DSM: Device-Specific Method
> +    If (LEqual(Arg0, ToUUID("9A9E6AB4-E3FC-475D-AD1C-C4789E4CFE90")))
> +    {
> +      // Function 0 : Query Function
> +      If (LEqual(Arg2, 0))
> +      {
> +        // Revision 0
> +        If (LEqual(Arg1, 0)) // The current revision is 0
> +        {
> +          Return(Buffer() { 0x07 }) // There are 2 function defined other than
> Query.
> +        } Else {
> +          Return(0) // Revision mismatch
> +        }
> +      }
> +      // Function 1 : Return UINT 32bit LTR values
> +      If(LEqual(Arg2, 1))
> +      {
> +        Return(0x64503C19)
> +      }
> +      // Function 2 : Return UINT 32bit Fill Time
> +      If(LEqual(Arg2, 2))
> +      {
> +        Return(0xFFF0783C)
> +      }
> +    }
> +
> +    Return(0) // Function number or GUID mismatch but normal return.
> +  }
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> new file mode 100644
> index 0000000000..4817968240
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
> @@ -0,0 +1,31 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +External(\_SB.PCI0, DeviceObj)
> +External(\_SB.PCI0.GFX0, DeviceObj)
> +External(\_SB.PCI0.IPU0, DeviceObj)
> +External(\_SB.PCI0.B0D3, DeviceObj)
> +External(\_SB.PCI0.PCIC, MethodObj)
> +External(\_SB.PCI0.PCID, MethodObj)
> +
> +
> +///
> +/// I.G.D
> +///
> +Scope (\_SB.PCI0.GFX0)
> +{
> +  include("Igfx.asl")
> +} // end I.G.D
> +
> +///
> +/// IPU Device
> +///
> +include("Ipu.asl")
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.a
> sl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.
> asl
> new file mode 100644
> index 0000000000..09d36ade53
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.
> asl
> @@ -0,0 +1,147 @@
> +/** @file
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  //
> +  // Define SA NVS Area operatino region.
> +  //
> +
> +
> +
> +  OperationRegion(SANV,SystemMemory, 0xFFFF0000,0xAA55)
> +  Field(SANV,AnyAcc,Lock,Preserve)
> +  {  Offset(0),      ASLB, 32, // Offset(0),     IGD OpRegion base address
> +  Offset(4),      IMON, 8,  // Offset(4),     IMON Current Value
> +  Offset(5),      IGDS, 8,  // Offset(5),     IGD State (Primary Display = 1)
> +  Offset(6),      IBTT, 8,  // Offset(6),     IGD Boot Display Device
> +  Offset(7),      IPAT, 8,  // Offset(7),     IGD Panel Type CMOS option
> +  Offset(8),      IPSC, 8,  // Offset(8),     IGD Panel Scaling
> +  Offset(9),      IBIA, 8,  // Offset(9),     IGD BIA Configuration
> +  Offset(10),     ISSC, 8,  // Offset(10),    IGD SSC Configuration
> +  Offset(11),     IDMS, 8,  // Offset(11),    IGD DVMT Memory Size
> +  Offset(12),     IF1E, 8,  // Offset(12),    IGD Function 1 Enable
> +  Offset(13),     HVCO, 8,  // Offset(13),    HPLL VCO
> +  Offset(14),     GSMI, 8,  // Offset(14),    GMCH SMI/SCI mode (0=SCI)
> +  Offset(15),     PAVP, 8,  // Offset(15),    IGD PAVP data
> +  Offset(16),     CADL, 8,  // Offset(16),    Current Attached Device List
> +  Offset(17),     CSTE, 16, // Offset(17),    Current Display State
> +  Offset(19),     NSTE, 16, // Offset(19),    Next Display State
> +  Offset(21),     NDID, 8,  // Offset(21),    Number of Valid Device IDs
> +  Offset(22),     DID1, 32, // Offset(22),    Device ID 1
> +  Offset(26),     DID2, 32, // Offset(26),    Device ID 2
> +  Offset(30),     DID3, 32, // Offset(30),    Device ID 3
> +  Offset(34),     DID4, 32, // Offset(34),    Device ID 4
> +  Offset(38),     DID5, 32, // Offset(38),    Device ID 5
> +  Offset(42),     DID6, 32, // Offset(42),    Device ID 6
> +  Offset(46),     DID7, 32, // Offset(46),    Device ID 7
> +  Offset(50),     DID8, 32, // Offset(50),    Device ID 8
> +  Offset(54),     DID9, 32, // Offset(54),    Device ID 9
> +  Offset(58),     DIDA, 32, // Offset(58),    Device ID 10
> +  Offset(62),     DIDB, 32, // Offset(62),    Device ID 11
> +  Offset(66),     DIDC, 32, // Offset(66),    Device ID 12
> +  Offset(70),     DIDD, 32, // Offset(70),    Device ID 13
> +  Offset(74),     DIDE, 32, // Offset(74),    Device ID 14
> +  Offset(78),     DIDF, 32, // Offset(78),    Device ID 15
> +  Offset(82),     DIDX, 32, // Offset(82),    Device ID for eDP device
> +  Offset(86),     NXD1, 32, // Offset(86),    Next state DID1 for _DGS
> +  Offset(90),     NXD2, 32, // Offset(90),    Next state DID2 for _DGS
> +  Offset(94),     NXD3, 32, // Offset(94),    Next state DID3 for _DGS
> +  Offset(98),     NXD4, 32, // Offset(98),    Next state DID4 for _DGS
> +  Offset(102),    NXD5, 32, // Offset(102),   Next state DID5 for _DGS
> +  Offset(106),    NXD6, 32, // Offset(106),   Next state DID6 for _DGS
> +  Offset(110),    NXD7, 32, // Offset(110),   Next state DID7 for _DGS
> +  Offset(114),    NXD8, 32, // Offset(114),   Next state DID8 for _DGS
> +  Offset(118),    NXDX, 32, // Offset(118),   Next state DID for eDP
> +  Offset(122),    LIDS, 8,  // Offset(122),   Lid State (Lid Open = 1)
> +  Offset(123),    KSV0, 32, // Offset(123),   First four bytes of AKSV
> (manufacturing mode)
> +  Offset(127),    KSV1, 8,  // Offset(127),   Fifth byte of AKSV (manufacturing
> mode)
> +  Offset(128),    BRTL, 8,  // Offset(128),   Brightness Level Percentage
> +  Offset(129),    ALSE, 8,  // Offset(129),   Ambient Light Sensor Enable
> +  Offset(130),    ALAF, 8,  // Offset(130),   Ambient Light Adjusment Factor
> +  Offset(131),    LLOW, 8,  // Offset(131),   LUX Low Value
> +  Offset(132),    LHIH, 8,  // Offset(132),   LUX High Value
> +  Offset(133),    ALFP, 8,  // Offset(133),   Active LFP
> +  Offset(134),    IPTP, 8,  // Offset(134),   IPU ACPI device type (0=Disabled,
> 1=AVStream virtual device as child of GFX)
> +  Offset(135),    EDPV, 8,  // Offset(135),   Check for eDP display device
> +  Offset(136),    SGMD, 8,  // Offset(136),   SG Mode (0=Disabled, 1=SG
> Muxed, 2=SG Muxless, 3=DGPU Only)
> +  Offset(137),    SGFL, 8,  // Offset(137),   SG Feature List
> +  Offset(138),    SGGP, 8,  // Offset(138),   PCIe0 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(139),    HRE0, 8,  // Offset(139),   PCIe0 HLD RST IO Expander
> Number
> +  Offset(140),    HRG0, 32, // Offset(140),   PCIe0 HLD RST GPIO Number
> +  Offset(144),    HRA0, 8,  // Offset(144),   PCIe0 HLD RST GPIO Active
> Information
> +  Offset(145),    PWE0, 8,  // Offset(145),   PCIe0 PWR Enable IO Expander
> Number
> +  Offset(146),    PWG0, 32, // Offset(146),   PCIe0 PWR Enable GPIO Number
> +  Offset(150),    PWA0, 8,  // Offset(150),   PCIe0 PWR Enable GPIO Active
> Information
> +  Offset(151),    P1GP, 8,  // Offset(151),   PCIe1 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(152),    HRE1, 8,  // Offset(152),   PCIe1 HLD RST IO Expander
> Number
> +  Offset(153),    HRG1, 32, // Offset(153),   PCIe1 HLD RST GPIO Number
> +  Offset(157),    HRA1, 8,  // Offset(157),   PCIe1 HLD RST GPIO Active
> Information
> +  Offset(158),    PWE1, 8,  // Offset(158),   PCIe1 PWR Enable IO Expander
> Number
> +  Offset(159),    PWG1, 32, // Offset(159),   PCIe1 PWR Enable GPIO Number
> +  Offset(163),    PWA1, 8,  // Offset(163),   PCIe1 PWR Enable GPIO Active
> Information
> +  Offset(164),    P2GP, 8,  // Offset(164),   PCIe2 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(165),    HRE2, 8,  // Offset(165),   PCIe2 HLD RST IO Expander
> Number
> +  Offset(166),    HRG2, 32, // Offset(166),   PCIe2 HLD RST GPIO Number
> +  Offset(170),    HRA2, 8,  // Offset(170),   PCIe2 HLD RST GPIO Active
> Information
> +  Offset(171),    PWE2, 8,  // Offset(171),   PCIe2 PWR Enable IO Expander
> Number
> +  Offset(172),    PWG2, 32, // Offset(172),   PCIe2 PWR Enable GPIO Number
> +  Offset(176),    PWA2, 8,  // Offset(176),   PCIe2 PWR Enable GPIO Active
> Information
> +  Offset(177),    DLPW, 16, // Offset(177),   Delay after power enable for PCIe
> +  Offset(179),    DLHR, 16, // Offset(179),   Delay after Hold Reset for PCIe
> +  Offset(181),    EECP, 8,  // Offset(181),   PCIe0 Endpoint Capability
> Structure Offset
> +  Offset(182),    XBAS, 32, // Offset(182),   Any Device's PCIe Config Space
> Base Address
> +  Offset(186),    GBAS, 16, // Offset(186),   GPIO Base Address
> +  Offset(188),    NVGA, 32, // Offset(188),   NVIG opregion address
> +  Offset(192),    NVHA, 32, // Offset(192),   NVHM opregion address
> +  Offset(196),    AMDA, 32, // Offset(196),   AMDA opregion address
> +  Offset(200),    LTRX, 8,  // Offset(200),   Latency Tolerance Reporting Enable
> +  Offset(201),    OBFX, 8,  // Offset(201),   Optimized Buffer Flush and Fill
> +  Offset(202),    LTRY, 8,  // Offset(202),   Latency Tolerance Reporting Enable
> +  Offset(203),    OBFY, 8,  // Offset(203),   Optimized Buffer Flush and Fill
> +  Offset(204),    LTRZ, 8,  // Offset(204),   Latency Tolerance Reporting Enable
> +  Offset(205),    OBFZ, 8,  // Offset(205),   Optimized Buffer Flush and Fill
> +  Offset(206),    LTRW, 8,  // Offset(206),   Latency Tolerance Reporting
> Enable
> +  Offset(207),    OBFA, 8,  // Offset(207),   Optimized Buffer Flush and Fill
> +  Offset(208),    SMSL, 16, // Offset(208),   SA Peg Latency Tolerance
> Reporting Max Snoop Latency
> +  Offset(210),    SNSL, 16, // Offset(210),   SA Peg Latency Tolerance Reporting
> Max No Snoop Latency
> +  Offset(212),    P0UB, 8,  // Offset(212),   Peg0 Unused Bundle Control
> +  Offset(213),    P1UB, 8,  // Offset(213),   Peg1 Unused Bundle Control
> +  Offset(214),    P2UB, 8,  // Offset(214),   Peg2 Unused Bundle Control
> +  Offset(215),    P3UB, 8,  // Offset(215),   Peg3 Unused Bundle Control
> +  Offset(216),    PCSL, 8,  // Offset(216),   The lowest C-state for the package
> +  Offset(217),    PBGE, 8,  // Offset(217),   Pegx Unused Bundle Control
> Global Enable (0=Disabled, 1=Enabled)
> +  Offset(218),    M64B, 64, // Offset(218),   Base of above 4GB MMIO resource
> +  Offset(226),    M64L, 64, // Offset(226),   Length of above 4GB MMIO
> resource
> +  Offset(234),    CPEX, 32, // Offset(234),   CPU ID info to get Family Id or
> Stepping
> +  Offset(238),    EEC1, 8,  // Offset(238),   PCIe1 Endpoint Capability
> Structure Offset
> +  Offset(239),    EEC2, 8,  // Offset(239),   PCIe2 Endpoint Capability
> Structure Offset
> +  Offset(240),    SBN0, 8,  // Offset(240),   PCIe0 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> +  Offset(241),    SBN1, 8,  // Offset(241),   PCIe1 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> +  Offset(242),    SBN2, 8,  // Offset(242),   PCIe2 Secondary Bus Number
> (PCIe0 Endpoint Bus Number)
> +  Offset(243),    M32B, 32, // Offset(243),   Base of below 4GB MMIO resource
> +  Offset(247),    M32L, 32, // Offset(247),   Length of below 4GB MMIO
> resource
> +  Offset(251),    P0WK, 32, // Offset(251),   PCIe0 RTD3 Device Wake GPIO
> Number
> +  Offset(255),    P1WK, 32, // Offset(255),   PCIe1 RTD3 Device Wake GPIO
> Number
> +  Offset(259),    P2WK, 32, // Offset(259),   PCIe2 RTD3 Device Wake GPIO
> Number
> +  Offset(263),    VTDS, 8,  // Offset(263),   VT-d Enable/Disable
> +  Offset(264),    VTB1, 32, // Offset(264),   VT-d Base Address 1
> +  Offset(268),    VTB2, 32, // Offset(268),   VT-d Base Address 2
> +  Offset(272),    VTB3, 32, // Offset(272),   VT-d Base Address 3
> +  Offset(276),    VE1V, 16, // Offset(276),   VT-d Engine#1 Vendor ID
> +  Offset(278),    VE2V, 16, // Offset(278),   VT-d Engine#2 Vendor ID
> +  Offset(280),    SBN3, 8,  // Offset(280),   PCIe3 Secondary Bus Number
> (PCIe3 Endpoint Bus Number)
> +  Offset(281),    P3GP, 8,  // Offset(281),   PCIe3 GPIO Support (0=Disabled,
> 1=PCH Based, 2=I2C Based)
> +  Offset(282),    HRE3, 8,  // Offset(282),   PCIe3 HLD RST IO Expander
> Number
> +  Offset(283),    HRG3, 32, // Offset(283),   PCIe3 HLD RST GPIO Number
> +  Offset(287),    HRA3, 8,  // Offset(287),   PCIe3 HLD RST GPIO Active
> Information
> +  Offset(288),    PWE3, 8,  // Offset(288),   PCIe3 PWR Enable IO Expander
> Number
> +  Offset(289),    PWG3, 32, // Offset(289),   PCIe3 PWR Enable GPIO Number
> +  Offset(293),    PWA3, 8,  // Offset(293),   PCIe3 PWR Enable GPIO Active
> Information
> +  Offset(294),    P3WK, 32, // Offset(294),   PCIe3 RTD3 Device Wake GPIO
> Number
> +  Offset(298),    EEC3, 8,  // Offset(298),   PCIe3 Endpoint Capability
> Structure Offset
> +  Offset(299),    RPIN, 8,  // Offset(299),   RootPort Number
> +  Offset(300),    RPBA, 32, // Offset(300),   RootPortAddress
> +  Offset (500),             // Offset(304) : Offset(499), Reserved bytes
> +  }
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> new file mode 100644
> index 0000000000..0db354901d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.
> asl
> @@ -0,0 +1,22 @@
> +/** @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) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +DefinitionBlock (
> +  "SaSsdt.aml",
> +  "SSDT",
> +  0x02,
> +  "SaSsdt",
> +  "SaSsdt ",
> +  0x3000
> +  )
> +{
> +  include ("SaNvs.asl")
> +  include ("Sa.asl")
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
  2019-08-17  0:52   ` Nate DeSimone
@ 2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:15 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add
> library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds CPU library class instances.
> 
> * BaseCpuMailboxLibNull - Generic CPU mailbox interaction services.
> * PeiCpuPolicyLib - CPU policy configuration services.
> * PeiCpuPolicyLibPreMem - CPU policy pre-memory configuration services.
> * PeiDxeSmmCpuPlatformLib - CPU platform services.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Base
> CpuMailboxLibNull.inf     |  22 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicy
> Lib.inf                 |  65 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicy
> LibPreMem.inf           |  43 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/P
> eiDxeSmmCpuPlatformLib.inf |  39 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicy
> Library.h               |  30 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/C
> puPlatformLibrary.h        |  28 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Base
> CpuMailboxLibNull.c       |  90 ++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPoli
> cy.c                    | 293 +++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPoli
> cyPreMem.c              | 108 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicy
> Lib.c                   | 434 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicy
> LibPreMem.c             | 160 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/C
> puPlatformLibrary.c        | 415 +++++++++++++++++++
>  12 files changed, 1727 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Ba
> seCpuMailboxLibNull.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Ba
> seCpuMailboxLibNull.inf
> new file mode 100644
> index 0000000000..4fcfca4670
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Ba
> seCpuMailboxLibNull.inf
> @@ -0,0 +1,22 @@
> +## @file
> +# Component description file for Cpu Mailbox Null Lib
> +#
> +# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseCpuMailboxLibNull
> +FILE_GUID = 74F470BC-1769-4732-B9C0-EE9AB0B12411
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = CpuMailboxLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +
> +[Sources]
> +BaseCpuMailboxLibNull.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLib.inf
> new file mode 100644
> index 0000000000..c986e35360
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLib.inf
> @@ -0,0 +1,65 @@
> +## @file
> +# Component description file for the PeiCpuPolicyLib library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiCpuPolicyLib
> +FILE_GUID = 5baafc8f-25c6-4d19-b141-585757509372
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = CpuPolicyLib
> +
> +
> +[LibraryClasses]
> +DebugLib
> +IoLib
> +PeiServicesLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +CpuPlatformLib
> +PciSegmentLib
> +SaPlatformLib
> +SiConfigBlockLib
> +PostCodeLib
> +PcdLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +PeiCpuPolicyLib.c
> +PeiCpuPolicyLibrary.h
> +CpuPrintPolicy.c
> +PeiCpuPolicyLibPreMem.c
> +CpuPrintPolicyPreMem.c
> +
> +[Ppis]
> +gSiPolicyPpiGuid                    ## CONSUMES
> +gSiPreMemPolicyPpiGuid              ## CONSUMES
> +
> +[FixedPcd]
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
> +
> +[Pcd]
> +gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode  ## Produces
> +
> +[Guids]
> +gCpuConfigGuid                      ## PRODUCES
> +gCpuSgxConfigGuid                   ## PRODUCES
> +gCpuPowerMgmtBasicConfigGuid        ## PRODUCES
> +gCpuPowerMgmtCustomConfigGuid       ## PRODUCES
> +gCpuTestConfigGuid                  ## PRODUCES
> +gCpuPidTestConfigGuid               ## PRODUCES
> +gCpuPowerMgmtTestConfigGuid         ## PRODUCES
> +gCpuConfigLibPreMemConfigGuid       ## PRODUCES
> +gCpuSecurityPreMemConfigGuid        ## PRODUCES
> +gCpuOverclockingPreMemConfigGuid    ## CONSUMES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibPreMem.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibPreMem.inf
> new file mode 100644
> index 0000000000..52dc989f74
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibPreMem.inf
> @@ -0,0 +1,43 @@
> +## @file
> +# Component description file for the PeiCpuPolicyLibPreMem library.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiCpuPolicyLibPreMem
> +FILE_GUID = 5F4C2CF1-9DFE-4D99-9318-98FD31C8517D
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = CpuPolicyLibPreMem
> +
> +[LibraryClasses]
> +DebugLib
> +IoLib
> +PeiServicesLib
> +BaseMemoryLib
> +MemoryAllocationLib
> +CpuPlatformLib
> +SiConfigBlockLib
> +PostCodeLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +PeiCpuPolicyLib.c
> +PeiCpuPolicyLibrary.h
> +CpuPrintPolicy.c
> +
> +[Ppis]
> +gSiPreMemPolicyPpiGuid         ## CONSUMES
> +
> +[Guids]
> +gCpuSecurityPreMemConfigGuid      ## PRODUCES
> +gCpuOverclockingPreMemConfigGuid  ## PRODUCES
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /PeiDxeSmmCpuPlatformLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /PeiDxeSmmCpuPlatformLib.inf
> new file mode 100644
> index 0000000000..0a56e42817
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /PeiDxeSmmCpuPlatformLib.inf
> @@ -0,0 +1,39 @@
> +## @file
> +# Component description file for CPU Platform Lib
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiDxeSmmCpuPlatformLib
> +FILE_GUID = 11647130-6AA4-41A4-A3A8-5FA296ABD977
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = CpuPlatformLib
> +
> +[LibraryClasses]
> +BaseLib
> +BaseMemoryLib
> +DebugLib
> +IoLib
> +PcdLib
> +CpuLib
> +TimerLib
> +SynchronizationLib
> +PciSegmentLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +UefiCpuPkg/UefiCpuPkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Sources]
> +CpuPlatformLibrary.h
> +CpuPlatformLibrary.c
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibrary.h
> new file mode 100644
> index 0000000000..6e993053fc
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibrary.h
> @@ -0,0 +1,30 @@
> +/** @file
> +  Header file for the PeiCpuPolicyLib library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_CPU_POLICY_LIBRARY_H_
> +#define _PEI_CPU_POLICY_LIBRARY_H_
> +
> +#include <PiPei.h>
> +#include <CpuAccess.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/CpuPolicyLib.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/SiConfigBlockLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Register/Cpuid.h>
> +#include <Library/PcdLib.h>
> +
> +#define MAX_MICROCODE_PATCH_SIZE 0x20000
> +
> +#endif // _PEI_CPU_POLICY_LIBRARY_H_
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /CpuPlatformLibrary.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /CpuPlatformLibrary.h
> new file mode 100644
> index 0000000000..0b780acd22
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /CpuPlatformLibrary.h
> @@ -0,0 +1,28 @@
> +/** @file
> +  Header file for Cpu Platform Lib implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
> +#define _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/CpuLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/SynchronizationLib.h>
> +
> +#include <Register/Cpuid.h>
> +#include <Register/Msr.h>
> +#include <CpuAccess.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/PciSegmentLib.h>
> +
> +#endif
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Ba
> seCpuMailboxLibNull.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Ba
> seCpuMailboxLibNull.c
> new file mode 100644
> index 0000000000..2af11ce8d0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/Ba
> seCpuMailboxLibNull.c
> @@ -0,0 +1,90 @@
> +/** @file
> +  Mailbox Library.
> +
> +  Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +
> +/**
> +  Generic Mailbox function for mailbox write commands. This function will
> +  poll the mailbox interface for control, issue the write request, poll
> +  for completion, and verify the write was successful.
> +
> +  @param[in]  MailboxType     The type of mailbox interface to read. The
> Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
> +  @param[in]  MailboxCommand  Overclocking mailbox command data
> +  @param[in]  MailboxData     Overclocking mailbox interface data
> +  @param[out] *MailboxStatus  Pointer to the mailbox status returned from
> pcode. Possible mailbox status values are:
> +                              - SUCCESS (0)               Command succeeded.
> +                              - OC_LOCKED (1)             Overclocking is locked.
> Service is read-only.
> +                              - INVALID_DOMAIN (2)        Invalid Domain ID provided
> in command data.
> +                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum
> overclocking limits.
> +                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input
> VR's max voltage.
> +                              - OC_NOT_SUPPORTED (5)      Domain does not
> support overclocking.
> +
> +  @retval    EFI_SUCCESS           Command succeeded.
> +  @retval    EFI_INVALID_PARAMETER Invalid read data detected from
> pcode.
> +  @retval    EFI_UNSUPPORTED       Unsupported MailboxType parameter.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxWrite (
> +  IN UINT32  MailboxType,
> +  IN UINT32  MailboxCommand,
> +  IN UINT32  MailboxData,
> +  OUT UINT32 *MailboxStatus
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Generic Mailbox function for mailbox read commands. This function will
> write
> +  the read request from MailboxType, and populate the read results in the
> MailboxDataPtr.
> +
> +  @param[in]  MailboxType     The type of mailbox interface to read. The
> Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
> +  @param[in]  MailboxCommand  Overclocking mailbox command data
> +  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox
> interface data
> +  @param[out] *MailboxStatus  Pointer to the mailbox status returned from
> pcode. Possible mailbox status are
> +                              - SUCCESS (0)               Command succeeded.
> +                              - OC_LOCKED (1)             Overclocking is locked.
> Service is read-only.
> +                              - INVALID_DOMAIN (2)        Invalid Domain ID provided
> in command data.
> +                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum
> overclocking limits.
> +                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input
> VR's max voltage.
> +                              - OC_NOT_SUPPORTED (5)      Domain does not
> support overclocking.
> +
> +  @retval EFI_SUCCESS           Command succeeded.
> +  @retval EFI_INVALID_PARAMETER Invalid read data detected from pcode.
> +  @retval EFI_UNSUPPORTED       Unsupported MailboxType parameter.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxRead (
> +  IN UINT32  MailboxType,
> +  IN UINT32  MailboxCommand,
> +  OUT UINT32 *MailboxDataPtr,
> +  OUT UINT32 *MailboxStatus
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Poll the run/busy bit of the mailbox until available or timeout expires.
> +
> +  @param[in]  MailboxType
> +
> +  @retval EFI_SUCCESS           Command succeeded.
> +  @retval EFI_TIMEOUT           Command timeout.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PollMailboxReady (
> +  IN UINT32 MailboxType
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintP
> olicy.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintP
> olicy.c
> new file mode 100644
> index 0000000000..38cf383e8d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintP
> olicy.c
> @@ -0,0 +1,293 @@
> +/** @file
> +  This file is PeiCpuPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiCpuPolicyLibrary.h"
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PcdLib.h>
> +
> +/**
> +  Print CPU_CONFIG and serial out.
> +
> +  @param[in] CpuConfig   Pointer to a CPU_CONFIG
> +**/
> +VOID
> +CpuConfigPrint (
> +  IN CONST CPU_CONFIG   *CpuConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ CPU Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CPU_CONFIG : AesEnable : 0x%x\n",
> CpuConfig->AesEnable));
> +  DEBUG ((DEBUG_INFO, " CPU_CONFIG : MicrocodePatchAddress : 0x%x\n",
> CpuConfig->MicrocodePatchAddress));
> +  DEBUG ((DEBUG_INFO, " CPU_CONFIG : DebugInterfaceEnable : 0x%X\n",
> CpuConfig->DebugInterfaceEnable));
> +}
> +
> +/**
> +  Print CPU_POWER_MGMT_BASIC_CONFIG and serial out.
> +
> +  @param[in] CpuPowerMgmtBasicConfig   Pointer to a
> CPU_POWER_MGMT_BASIC_CONFIG
> +**/
> +VOID
> +CpuPowerMgmtBasicConfigPrint (
> +  IN CONST CPU_POWER_MGMT_BASIC_CONFIG
> *CpuPowerMgmtBasicConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Basic Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG :
> OneCoreRatioLimit : 0x%X , TwoCoreRatioLimit = 0x%X , ThreeCoreRatioLimit =
> 0x%X , FourCoreRatioLimit = 0x%X, FiveCoreRatioLimit = 0x%X,
> SixCoreRatioLimit = 0x%X, SevenCoreRatioLimit = 0x%X, EightCoreRatioLimit =
> 0x%X \n",  CpuPowerMgmtBasicConfig->OneCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->TwoCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->FourCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->FiveCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->SixCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->SevenCoreRatioLimit, \
> +          CpuPowerMgmtBasicConfig->EightCoreRatioLimit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: Hwp :
> 0x%x\n", CpuPowerMgmtBasicConfig->Hwp));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> SkipSetBootPState : 0x%x\n",
> CpuPowerMgmtBasicConfig->SkipSetBootPState));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HdcControl :
> 0x%X\n", CpuPowerMgmtBasicConfig->HdcControl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: (Intel Turbo
> Boost Max Technology 3.0)EnableItbm : 0x%X\n",
> CpuPowerMgmtBasicConfig->EnableItbm));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> EnableItbmDriver : 0x%X\n",
> CpuPowerMgmtBasicConfig->EnableItbmDriver));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit2 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> TurboPowerLimitLock : 0x%x\n",
> CpuPowerMgmtBasicConfig->TurboPowerLimitLock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit3DutyCycle : 0x%x\n",
> CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit3Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Lock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit4Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4Lock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> TccOffsetClamp : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetClamp));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> TccOffsetLock : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetLock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboMode :
> 0x%x\n", CpuPowerMgmtBasicConfig->TurboMode));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> TccActivationOffset : 0x%X\n",
> CpuPowerMgmtBasicConfig->TccActivationOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit1 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit2Power : 0x%x\n",
> CpuPowerMgmtBasicConfig->PowerLimit2Power));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit3 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit4 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit1Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1Time));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> PowerLimit3Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Time));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> TccOffsetTimeWindowForRatl : 0x%X\n",
> CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> HwpInterruptControl : 0x%x\n",
> CpuPowerMgmtBasicConfig->HwpInterruptControl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> MinRingRatioLimit : 0x%x\n",
> CpuPowerMgmtBasicConfig->MinRingRatioLimit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG:
> MaxRingRatioLimit : 0x%x\n",
> CpuPowerMgmtBasicConfig->MaxRingRatioLimit));
> +}
> +
> +/**
> +  Print CPU_POWER_MGMT_CUSTOM_CONFIG and serial out.
> +
> +  @param[in] CpuPowerMgmtCustomConfig   Pointer to a
> CPU_POWER_MGMT_CUSTOM_CONFIG
> +**/
> +VOID
> +CpuPowerMgmtCustomConfigPrint (
> +  IN CONST CPU_POWER_MGMT_CUSTOM_CONFIG
> *CpuPowerMgmtCustomConfig
> +  )
> +{
> +  UINT32 Index = 0;
> +  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Custom Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "\n CustomRatioTable... \n"));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG:
> VidNumber : 0x%x\n",
> CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidCpuid :
> 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG:
> VidMaxRatio : 0x%x\n",
> CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio));
> +  for (Index = 0; Index < MAX_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
> +    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG:
> StateRatio[%d] : 0x%x\n", Index,
> CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index]));
> +  }
> +  for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
> +    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG:
> StateRatioMax16[%d] : 0x%x\n", Index,
> CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index]))
> ;
> +  }
> +  for (Index = 0; Index < MAX_CUSTOM_CTDP_ENTRIES; Index++) {
> +    DEBUG (
> +            (DEBUG_INFO,
> +             " CPU_POWER_MGMT_CUSTOM_CONFIG:
> CustomConfigTdpTable[%d] CustomPowerLimit1 : 0x%x\n",
> +
> Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].Custom
> PowerLimit1)
> +            );
> +    DEBUG (
> +            (DEBUG_INFO,
> +             " CPU_POWER_MGMT_CUSTOM_CONFIG:
> CustomConfigTdpTable[%d] CustomPowerLimit2 : 0x%x\n",
> +
> Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].Custom
> PowerLimit2)
> +            );
> +    DEBUG (
> +            (DEBUG_INFO,
> +             " CPU_POWER_MGMT_CUSTOM_CONFIG:
> CustomConfigTdpTable[%d] CustomPowerLimit1Time : 0x%x\n",
> +
> Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].Custom
> PowerLimit1Time)
> +            );
> +    DEBUG (
> +            (DEBUG_INFO,
> +             " CPU_POWER_MGMT_CUSTOM_CONFIG:
> CustomConfigTdpTable[%d] CustomTurboActivationRatio : 0x%x\n",
> +
> Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].Custom
> TurboActivationRatio)
> +            );
> +  }
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG:
> ConfigTdpLock : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpLock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG:
> ConfigTdpBios : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpBios));
> +}
> +
> +/**
> +  Print CPU_TEST_CONFIG and serial out.
> +
> +  @param[in] CpuTestConfig   Pointer to a CPU_TEST_CONFIG
> +**/
> +VOID
> +CpuTestConfigPrint (
> +  IN CONST CPU_TEST_CONFIG   *CpuTestConfig
> +  )
> +{
> +  UINT8 PcdCpuApLoopMode;
> +
> +  PcdCpuApLoopMode = PcdGet8 (PcdCpuApLoopMode);
> +
> +  DEBUG ((DEBUG_INFO, "------------------ CPU Test Config ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcStreamerPrefetcher :
> 0x%X\n", CpuTestConfig->MlcStreamerPrefetcher));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcSpatialPrefetcher :
> 0x%X\n", CpuTestConfig->MlcSpatialPrefetcher));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MonitorMwaitEnable :
> 0x%X\n", CpuTestConfig->MonitorMwaitEnable));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MachineCheckEnable :
> 0x%X\n", CpuTestConfig->MachineCheckEnable));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: DebugInterfaceLockEnable :
> 0x%X\n", CpuTestConfig->DebugInterfaceLockEnable));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceOutputScheme :
> 0x%X\n", CpuTestConfig->ProcessorTraceOutputScheme));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceEnable :
> 0x%X\n", CpuTestConfig->ProcessorTraceEnable));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemBase :
> 0x%llX\n", CpuTestConfig->ProcessorTraceMemBase));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemLength :
> 0x%X\n", CpuTestConfig->ProcessorTraceMemLength));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ThreeStrikeCounterDisable :
> 0x%X\n", CpuTestConfig->ThreeStrikeCounterDisable));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: VoltageOptimization : 0x%X\n",
> CpuTestConfig->VoltageOptimization));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: CpuWakeUpTimer : 0x%X\n",
> CpuTestConfig->CpuWakeUpTimer));
> +  DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: PcdCpuApLoopMode:
> 0x%X\n", PcdCpuApLoopMode));
> +}
> +
> +/**
> +  Print CPU_PID_TEST_CONFIG and serial out.
> +
> +  @param[in] CpuPidTestConfig   Pointer to a CPU_PID_TEST_CONFIG
> +**/
> +VOID
> +CpuPidTestConfigPrint (
> +  IN CONST CPU_PID_TEST_CONFIG   *CpuPidTestConfig
> +  )
> +{
> +  UINT32 Index = 0;
> +  DEBUG ((DEBUG_INFO, "------------------ CPU PID Test Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PidTuning : 0x%X\n",
> Index,  CpuPidTestConfig->PidTuning));
> +  if ( CpuPidTestConfig->PidTuning == 1) {
> +    for (Index = PID_DOMAIN_KP; Index <= PID_DOMAIN_KD; Index++) {
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : Ratl[%X] : 0x%X\n",
> Index,  CpuPidTestConfig->Ratl[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr0[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr0[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr1[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr1[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr2[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr2[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr3[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->VrTdcVr3[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1Msr[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl1Msr[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG :
> PbmPsysPl1MmioPcs[%X] : 0x%X\n", Index,
> CpuPidTestConfig->PbmPsysPl1MmioPcs[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2Msr[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->PbmPsysPl2Msr[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG :
> PbmPsysPl2MmioPcs[%X] : 0x%X\n", Index,
> CpuPidTestConfig->PbmPsysPl2MmioPcs[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1Msr[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl1Msr[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG :
> PbmPkgPl1MmioPcs[%X] : 0x%X\n", Index,
> CpuPidTestConfig->PbmPkgPl1MmioPcs[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2Msr[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->PbmPkgPl2Msr[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG :
> PbmPkgPl2MmioPcs[%X] : 0x%X\n", Index,
> CpuPidTestConfig->PbmPkgPl2MmioPcs[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1Msr[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->DdrPl1Msr[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1MmioPcs[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->DdrPl1MmioPcs[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2Msr[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->DdrPl2Msr[Index]));
> +        DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2MmioPcs[%X] :
> 0x%X\n", Index,  CpuPidTestConfig->DdrPl2MmioPcs[Index]));
> +    }
> +  }
> +}
> +
> +/**
> +  Print CPU_POWER_MGMT_TEST_CONFIG and serial out.
> +
> +  @param[in] CpuPowerMgmtTestConfig   Pointer to a
> CPU_POWER_MGMT_TEST_CONFIG
> +**/
> +VOID
> +CpuPowerMgmtTestConfigPrint (
> +  IN CONST CPU_POWER_MGMT_TEST_CONFIG
> *CpuPowerMgmtTestConfig
> +  )
> +{
> +  CPU_GENERATION CpuGeneration;
> +  CpuGeneration = GetCpuGeneration();
> +  DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Test Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Eist : 0x%x\n",
> CpuPowerMgmtTestConfig->Eist));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> EnergyEfficientPState : 0x%x\n",
> CpuPowerMgmtTestConfig->EnergyEfficientPState));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> EnergyEfficientTurbo : 0x%x\n",
> CpuPowerMgmtTestConfig->EnergyEfficientTurbo));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TStates :
> 0x%x\n", CpuPowerMgmtTestConfig->TStates));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: BiProcHot :
> 0x%x\n", CpuPowerMgmtTestConfig->BiProcHot));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> DisableProcHotOut : 0x%x\n",
> CpuPowerMgmtTestConfig->DisableProcHotOut));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> ProcHotResponse : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotResponse));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> DisableVrThermalAlert : 0x%x\n",
> CpuPowerMgmtTestConfig->DisableVrThermalAlert));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> AutoThermalReporting : 0x%x\n",
> CpuPowerMgmtTestConfig->AutoThermalReporting));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> ThermalMonitor : 0x%x\n", CpuPowerMgmtTestConfig->ThermalMonitor));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Cx : 0x%x\n",
> CpuPowerMgmtTestConfig->Cx));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> PmgCstCfgCtrlLock : 0x%x\n",
> CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1e : 0x%x\n",
> CpuPowerMgmtTestConfig->C1e));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> C1Autodemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1AutoDemotion));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> C1Undemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1UnDemotion));
> +  if(CpuGeneration == EnumCflCpu){
> +    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> C3AutoDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3AutoDemotion));
> +    DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> C3UnDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3UnDemotion));
> +  }
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCState
> Demotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateDemotion));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> PkgCstateUndemotion : 0x%x\n",
> CpuPowerMgmtTestConfig->PkgCStateUnDemotion));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CStatePreWake : 0x%x\n", CpuPowerMgmtTestConfig->CStatePreWake));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TimedMwait :
> 0x%x\n", CpuPowerMgmtTestConfig->TimedMwait));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstCfgCtrIoMwaitRedirection : 0x%x\n",
> CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotLock :
> 0x%x\n", CpuPowerMgmtTestConfig->ProcHotLock));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> ConfigTdpLevel : 0x%x\n", CpuPowerMgmtTestConfig->ConfigTdpLevel));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: RaceToHalt  :
> 0x%x\n",  CpuPowerMgmtTestConfig->RaceToHalt));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl0Irtl : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl0TimeUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl1Irtl : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl2Irtl : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl3Irtl : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl4Irtl : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl5Irtl : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> PkgCStateLimit : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateLimit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl1TimeUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl2TimeUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl3TimeUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl4TimeUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CstateLatencyControl5TimeUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit));
> +  DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG:
> CustomPowerUnit : 0x%x\n",
> CpuPowerMgmtTestConfig->CustomPowerUnit));
> +  DEBUG ((DEBUG_INFO, " PpmIrmSetting : 0x%x\n",
> CpuPowerMgmtTestConfig->PpmIrmSetting));
> +}
> +/**
> +  Print whole CPU config blocks of SI_POLICY_PPI and serial out in PostMem.
> +
> +  @param[in] SiPolicyPpi The SI Policy PPI instance
> +**/
> +VOID
> +CpuPrintPolicy (
> +  IN  SI_POLICY_PPI       *SiPolicyPpi
> +  )
> +{
> +DEBUG_CODE_BEGIN();
> +  EFI_STATUS                       Status;
> +  CPU_CONFIG                       *CpuConfig;
> +  CPU_POWER_MGMT_BASIC_CONFIG      *CpuPowerMgmtBasicConfig;
> +  CPU_POWER_MGMT_CUSTOM_CONFIG
> *CpuPowerMgmtCustomConfig;
> +  CPU_TEST_CONFIG                  *CpuTestConfig;
> +  CPU_PID_TEST_CONFIG              *CpuPidTestConfig;
> +  CPU_POWER_MGMT_TEST_CONFIG       *CpuPowerMgmtTestConfig;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *)
> &CpuConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtCustomConfigGuid, (VOID *)
> &CpuPowerMgmtCustomConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID
> *) &CpuTestConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPidTestConfigGuid,
> (VOID *) &CpuPidTestConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print Begin in
> PostMem----------------- \n"));
> +  DEBUG ((DEBUG_INFO, " Revision= %x\n",
> SiPolicyPpi->TableHeader.Header.Revision));
> +
> +  CpuConfigPrint(CpuConfig);
> +  CpuPowerMgmtBasicConfigPrint(CpuPowerMgmtBasicConfig);
> +  CpuPowerMgmtCustomConfigPrint(CpuPowerMgmtCustomConfig);
> +  CpuTestConfigPrint(CpuTestConfig);
> +  CpuPidTestConfigPrint(CpuPidTestConfig);
> +  CpuPowerMgmtTestConfigPrint(CpuPowerMgmtTestConfig);
> +  DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print End in
> PostMem ----------------- \n\n"));
> +DEBUG_CODE_END();
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintP
> olicyPreMem.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintP
> olicyPreMem.c
> new file mode 100644
> index 0000000000..0bcb34c99c
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintP
> olicyPreMem.c
> @@ -0,0 +1,108 @@
> +/** @file
> +  This file is PeiCpuPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiCpuPolicyLibrary.h"
> +#include <Library/ConfigBlockLib.h>
> +
> +/**
> +  Print CPU_CONFIG_LIB_PREMEM_CONFIG and serial out.
> +
> +  @param[in] CpuConfigLibPreMemConfig     Pointer to a
> CPU_CONFIG_LIB_PREMEM_CONFIG
> +
> +**/
> +VOID
> +CpuConfigLibPreMemConfigPrint (
> +  IN CONST CPU_CONFIG_LIB_PREMEM_CONFIG
> *CpuConfigLibPreMemConfig
> +  )
> +{
> +  CPU_GENERATION CpuGeneration;
> +  CpuGeneration = GetCpuGeneration();
> +  DEBUG ((DEBUG_INFO, "------------------ CPU Config Lib PreMem Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> HyperThreading = 0x%x\n", CpuConfigLibPreMemConfig->HyperThreading));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> BootFrequency = 0x%x\n", CpuConfigLibPreMemConfig->BootFrequency));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> ActiveCoreCount = 0x%x\n", CpuConfigLibPreMemConfig->ActiveCoreCount));
> +  if(CpuGeneration == EnumCflCpu){
> +    DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> FClkFrequency = 0x%x\n", CpuConfigLibPreMemConfig->FClkFrequency));
> +  }
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> JtagC10PowerGateDisable = 0x%x\n",
> CpuConfigLibPreMemConfig->JtagC10PowerGateDisable));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BistOnReset
> = 0x%x\n", CpuConfigLibPreMemConfig->BistOnReset));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : VmxEnable =
> 0x%x\n", CpuConfigLibPreMemConfig->VmxEnable));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : CpuRatio =
> 0x%x\n", CpuConfigLibPreMemConfig->CpuRatio));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciSxReset
> = 0x%x\n", CpuConfigLibPreMemConfig->PeciSxReset));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> PeciC10Reset = 0x%x\n", CpuConfigLibPreMemConfig->PeciC10Reset));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : SkipMpInit =
> 0x%x\n", CpuConfigLibPreMemConfig->SkipMpInit));
> +  DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG :
> DpSscMarginEnable = 0x%x\n",
> CpuConfigLibPreMemConfig->DpSscMarginEnable));
> +}
> +
> +/**
> +  Print CPU_OVERCLOCKING_PREMEM_CONFIG and serial out.
> +
> +  @param[in] CpuOverClockingConfig   Pointer to a
> CPU_OVERCLOCKING_CONFIG
> +**/
> +VOID
> +CpuOverClockingPreMemConfigPrint (
> +  IN CONST CPU_OVERCLOCKING_PREMEM_CONFIG
> *CpuOverClockingPreMemConfig
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "------------------ CPU OverClocking Config
> ------------------\n"));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> OcSupport : 0x%X\n", CpuOverClockingPreMemConfig->OcSupport));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcLock :
> 0x%X\n", CpuOverClockingPreMemConfig->OcLock));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> CoreVoltageMode : 0x%X\n",
> CpuOverClockingPreMemConfig->CoreVoltageMode));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> CoreMaxOcRatio  : 0x%X\n",
> CpuOverClockingPreMemConfig->CoreMaxOcRatio));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> CoreVoltageOverride : 0x%X\n",
> CpuOverClockingPreMemConfig->CoreVoltageOverride));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> CoreVoltageAdaptive : 0x%X\n",
> CpuOverClockingPreMemConfig->CoreVoltageAdaptive));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> CoreVoltageOffset : 0x%X\n",
> CpuOverClockingPreMemConfig->CoreVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingVoltageMode : 0x%X\n",
> CpuOverClockingPreMemConfig->RingVoltageMode));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingVoltageOverride : 0x%X\n",
> CpuOverClockingPreMemConfig->RingVoltageOverride));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingVoltageAdaptive : 0x%X\n",
> CpuOverClockingPreMemConfig->RingVoltageAdaptive));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingVoltageOffset : 0x%X\n",
> CpuOverClockingPreMemConfig->RingVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingMaxOcRatio  : 0x%X\n",
> CpuOverClockingPreMemConfig->RingMaxOcRatio));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingDownBin     : 0x%X\n", CpuOverClockingPreMemConfig->RingDownBin));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> Avx2RatioOffset : 0x%X\n",
> CpuOverClockingPreMemConfig->Avx2RatioOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> Avx3RatioOffset : 0x%X\n",
> CpuOverClockingPreMemConfig->Avx3RatioOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> BclkAdaptiveVoltage  : 0x%X\n",
> CpuOverClockingPreMemConfig->BclkAdaptiveVoltage));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> CorePllVoltageOffset : 0x%X\n",
> CpuOverClockingPreMemConfig->CorePllVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> GtPllVoltageOffset   : 0x%X\n",
> CpuOverClockingPreMemConfig->GtPllVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> RingPllVoltageOffset : 0x%X\n",
> CpuOverClockingPreMemConfig->RingPllVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> SaPllVoltageOffset   : 0x%X\n",
> CpuOverClockingPreMemConfig->SaPllVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> McPllVoltageOffset   : 0x%X\n",
> CpuOverClockingPreMemConfig->McPllVoltageOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> TjMaxOffset          : 0x%X\n",
> CpuOverClockingPreMemConfig->TjMaxOffset));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> TvbRatioClipping     : 0x%X\n",
> CpuOverClockingPreMemConfig->TvbRatioClipping));
> +  DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG::
> TvbVoltageOptimization : 0x%X\n",
> CpuOverClockingPreMemConfig->TvbVoltageOptimization));
> +}
> +
> +
> +/**
> +  Print whole CPU Config blocks of SI_PREMEM_POLICY_PPI and serial out in
> PreMem.
> +
> +  @param[in] SiPreMemPolicyPpi The SI Pre-Mem Policy PPI instance
> +**/
> +VOID
> +CpuPreMemPrintPolicy (
> +  IN  SI_PREMEM_POLICY_PPI       *SiPreMemPolicyPpi
> +  )
> +{
> +DEBUG_CODE_BEGIN();
> +  EFI_STATUS                      Status;
> +  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
> +  CPU_OVERCLOCKING_PREMEM_CONFIG
> *CpuOverclockingPreMemConfig;
> +
> +  DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print
> Begin in PreMem -----------------\n"));
> +
> +  DEBUG ((DEBUG_INFO, " Revision= %x\n",
> SiPreMemPolicyPpi->TableHeader.Header.Revision));
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gCpuOverclockingPreMemConfigGuid, (VOID *)
> &CpuOverclockingPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  CpuConfigLibPreMemConfigPrint(CpuConfigLibPreMemConfig);
> +  CpuOverClockingPreMemConfigPrint(CpuOverclockingPreMemConfig);
> +
> +  DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print
> End -----------------\n\n"));
> +DEBUG_CODE_END();
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLib.c
> new file mode 100644
> index 0000000000..181b72fec5
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLib.c
> @@ -0,0 +1,434 @@
> +/** @file
> +  This file is PeiCpuPolicy library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiCpuPolicyLibrary.h"
> +#include <SaAccess.h>
> +#include <CpuAccess.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/SaPlatformLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PostCodeLib.h>
> +#include <Library/PcdLib.h>
> +
> +#ifndef FSP_FLAG
> +/**
> +  Get the next microcode patch pointer.
> +
> +  @param[in, out] MicrocodeData - Input is a pointer to the last microcode
> patch address found,
> +                                  and output points to the next patch address found.
> +
> +  @retval EFI_SUCCESS           - Patch found.
> +  @retval EFI_NOT_FOUND         - Patch not found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RetrieveMicrocode (
> +  IN OUT CPU_MICROCODE_HEADER **MicrocodeData
> +  )
> +{
> +  UINTN                MicrocodeStart;
> +  UINTN                MicrocodeEnd;
> +  UINTN                TotalSize;
> +
> +  if ((FixedPcdGet32 (PcdFlashMicrocodeFvBase) == 0) || (FixedPcdGet32
> (PcdFlashMicrocodeFvSize) == 0)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ///
> +  /// Microcode binary in SEC
> +  ///
> +  MicrocodeStart = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) +
> +          ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FixedPcdGet32
> (PcdFlashMicrocodeFvBase))->HeaderLength +
> +          sizeof (EFI_FFS_FILE_HEADER);
> +
> +  MicrocodeEnd = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) +
> (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvSize);
> +
> +  if (*MicrocodeData == NULL) {
> +    *MicrocodeData = (CPU_MICROCODE_HEADER *) (UINTN)
> MicrocodeStart;
> +  } else {
> +    if (*MicrocodeData < (CPU_MICROCODE_HEADER *) (UINTN)
> MicrocodeStart) {
> +      DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData < MicrocodeStart
> \n"));
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    TotalSize = (UINTN) ((*MicrocodeData)->TotalSize);
> +    if (TotalSize == 0) {
> +      TotalSize = 2048;
> +    }
> +
> +    *MicrocodeData = (CPU_MICROCODE_HEADER *)
> ((UINTN)*MicrocodeData + TotalSize);
> +    if (*MicrocodeData >= (CPU_MICROCODE_HEADER *) (UINTN)
> (MicrocodeEnd) || (*MicrocodeData)->TotalSize == (UINT32) -1) {
> +      DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData >= MicrocodeEnd
> \n"));
> +      return EFI_NOT_FOUND;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get the microcode patch pointer.
> +
> +  @retval EFI_PHYSICAL_ADDRESS - Address of the microcode patch, or NULL
> if not found.
> +**/
> +EFI_PHYSICAL_ADDRESS
> +PlatformCpuLocateMicrocodePatch (
> +  VOID
> +  )
> +{
> +  EFI_STATUS           Status;
> +  CPU_MICROCODE_HEADER *MicrocodeData;
> +  EFI_CPUID_REGISTER   Cpuid;
> +  UINT32               UcodeRevision;
> +  UINTN                MicrocodeBufferSize;
> +  VOID                 *MicrocodeBuffer = NULL;
> +
> +  AsmCpuid (
> +    CPUID_VERSION_INFO,
> +    &Cpuid.RegEax,
> +    &Cpuid.RegEbx,
> +    &Cpuid.RegEcx,
> +    &Cpuid.RegEdx
> +    );
> +
> +  UcodeRevision = GetCpuUcodeRevision ();
> +  MicrocodeData = NULL;
> +  while (TRUE) {
> +    ///
> +    /// Find the next patch address
> +    ///
> +    Status = RetrieveMicrocode (&MicrocodeData);
> +    DEBUG ((DEBUG_INFO, "MicrocodeData = %x\n", MicrocodeData));
> +
> +    if (Status != EFI_SUCCESS) {
> +      break;
> +    } else if (CheckMicrocode (Cpuid.RegEax, MicrocodeData,
> &UcodeRevision)) {
> +      break;
> +    }
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +    return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
> +  }
> +
> +  ///
> +  /// Check that microcode patch size is <= 128K max size,
> +  /// then copy the patch from FV to temp buffer for faster access.
> +  ///
> +  MicrocodeBufferSize = (UINTN) MicrocodeData->TotalSize;
> +
> +  if (MicrocodeBufferSize <= MAX_MICROCODE_PATCH_SIZE) {
> +    MicrocodeBuffer = AllocatePages (EFI_SIZE_TO_PAGES
> (MicrocodeBufferSize));
> +    if (MicrocodeBuffer != NULL) {
> +      DEBUG(( DEBUG_INFO, "Copying Microcode to temp buffer.\n"));
> +      CopyMem (MicrocodeBuffer, MicrocodeData, MicrocodeBufferSize);
> +
> +      return (EFI_PHYSICAL_ADDRESS) (UINTN) MicrocodeBuffer;
> +    } else {
> +      DEBUG(( DEBUG_ERROR, "Failed to allocate enough memory for
> Microcode Patch.\n"));
> +    }
> +  } else {
> +    DEBUG(( DEBUG_ERROR, "Microcode patch size is greater than max
> allowed size of 128K.\n"));
> +  }
> +  return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
> +}
> +#endif
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_CONFIG  *CpuConfig;
> +  CpuConfig  = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Name = %g\n",
> &CpuConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n", CpuConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    CPU configuration
> +  ********************************/
> +  CpuConfig->AesEnable             = CPU_FEATURE_ENABLE;
> +#ifndef FSP_FLAG
> +  CpuConfig->MicrocodePatchAddress = PlatformCpuLocateMicrocodePatch
> ();
> +#endif //FSP_FLAG
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuSgxConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +
> +  /********************************
> +    CPU SGX configuration
> +  ********************************/
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuPowerMgmtBasicConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_POWER_MGMT_BASIC_CONFIG  *CpuPowerMgmtBasicConfig;
> +  CPU_SKU      CpuSku;
> +  MSR_REGISTER TempMsr;
> +
> +  CpuPowerMgmtBasicConfig = ConfigBlockPointer;
> +  CpuSku                  = GetCpuSku();
> +
> +  DEBUG ((DEBUG_INFO,
> "CpuPowerMgmtBasicConfig->Header.GuidHob.Name = %g\n",
> &CpuPowerMgmtBasicConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    CPU Power Management Basic configuration
> +  ********************************/
> +  CpuPowerMgmtBasicConfig->Hwp                          = TRUE;
> +  CpuPowerMgmtBasicConfig->HdcControl                   = TRUE;
> +  CpuPowerMgmtBasicConfig->PowerLimit2                  = TRUE;
> +  CpuPowerMgmtBasicConfig->PowerLimit3Lock              = TRUE;
> +  CpuPowerMgmtBasicConfig->TccOffsetLock                = FALSE;
> +  CpuPowerMgmtBasicConfig->EnableItbm                   = TRUE;
> +  CpuPowerMgmtBasicConfig->EnableItbmDriver             = FALSE;
> +
> +  ///
> +  /// Initialize RATL (Runtime Average Temperature Limit) Config for ULX.
> +  ///
> +  if (CpuSku == EnumCpuUlx) {
> +    CpuPowerMgmtBasicConfig->TccActivationOffset        = 15;
> +    CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl = 5000; // 5
> sec
> +    CpuPowerMgmtBasicConfig->TccOffsetClamp             =
> CPU_FEATURE_ENABLE;
> +  }
> +  CpuPowerMgmtBasicConfig->TurboMode                    = TRUE;
> +
> +  TempMsr.Qword = AsmReadMsr64 (MSR_TURBO_RATIO_LIMIT);
> +  CpuPowerMgmtBasicConfig->OneCoreRatioLimit =
> TempMsr.Bytes.FirstByte;
> +  CpuPowerMgmtBasicConfig->TwoCoreRatioLimit =
> TempMsr.Bytes.SecondByte;
> +  CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit =
> TempMsr.Bytes.ThirdByte;
> +  CpuPowerMgmtBasicConfig->FourCoreRatioLimit =
> TempMsr.Bytes.FouthByte;
> +  CpuPowerMgmtBasicConfig->FiveCoreRatioLimit =
> TempMsr.Bytes.FifthByte;
> +  CpuPowerMgmtBasicConfig->SixCoreRatioLimit =
> TempMsr.Bytes.SixthByte;
> +  CpuPowerMgmtBasicConfig->SevenCoreRatioLimit =
> TempMsr.Bytes.SeventhByte;
> +  CpuPowerMgmtBasicConfig->EightCoreRatioLimit =
> TempMsr.Bytes.EighthByte;
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuPowerMgmtCustomConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_POWER_MGMT_CUSTOM_CONFIG  *CpuPowerMgmtCustomConfig;
> +  CpuPowerMgmtCustomConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO,
> "CpuPowerMgmtCustomConfig->Header.GuidHob.Name = %g\n",
> &CpuPowerMgmtCustomConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n",
> CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    CPU Power Management Custom configuration
> +  ********************************/
> +  CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid = (UINT16)
> ((GetCpuFamily() | GetCpuStepping()) & (0x0FFF));
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuTestConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_TEST_CONFIG  *CpuTestConfig;
> +  CPU_SKU          CpuSku;
> +  CpuTestConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Name = %g\n",
> &CpuTestConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> CpuTestConfig->Header.GuidHob.Header.HobLength));
> +
> +  CpuSku = GetCpuSku();
> +  /********************************
> +    CPU Test configuration
> +  ********************************/
> +
> +  CpuTestConfig->MlcStreamerPrefetcher    = CPU_FEATURE_ENABLE;
> +  CpuTestConfig->MlcSpatialPrefetcher     = CPU_FEATURE_ENABLE;
> +  CpuTestConfig->MonitorMwaitEnable       = CPU_FEATURE_ENABLE;
> +  CpuTestConfig->MachineCheckEnable       = CPU_FEATURE_ENABLE;
> +  CpuTestConfig->DebugInterfaceLockEnable = CPU_FEATURE_ENABLE;
> +
> +  if ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt)){
> +    /**
> +    This policy should be used to enable or disable Voltage Optimization
> feature. Recommended defaults:
> +     Enable  - For Mobile SKUs(U/Y)
> +     Disable - Rest of all SKUs other than Mobile.
> +    **/
> +    CpuTestConfig->VoltageOptimization      = CPU_FEATURE_ENABLE;
> +  }
> +  else {
> +    CpuTestConfig->VoltageOptimization      = CPU_FEATURE_DISABLE;
> +  }
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuPidTestConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_PID_TEST_CONFIG  *CpuPidTestConfig;
> +  CpuPidTestConfig = ConfigBlockPointer;
> +
> +  DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Name = %g\n",
> &CpuPidTestConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuPidTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> CpuPidTestConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    CPU PID Test configuration
> +  ********************************/
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuPowerMgmtTestConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_POWER_MGMT_TEST_CONFIG  *CpuPowerMgmtTestConfig;
> +  CPU_GENERATION              CpuGeneration;
> +  UINT16                      CpuDid;
> +
> +  CpuPowerMgmtTestConfig = ConfigBlockPointer;
> +  CpuDid    = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS
> (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN,
> R_SA_MC_DEVICE_ID));
> +
> +  DEBUG ((DEBUG_INFO,
> "CpuPowerMgmtTestConfig->Header.GuidHob.Name = %g\n",
> &CpuPowerMgmtTestConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    CPU Power Management Test configuration
> +  ********************************/
> +  CpuPowerMgmtTestConfig->Eist                          = TRUE;
> +  CpuPowerMgmtTestConfig->EnergyEfficientPState         = TRUE;
> +  CpuPowerMgmtTestConfig->EnergyEfficientTurbo          = TRUE;
> +  if ((CpuDid == V_SA_DEVICE_ID_CFL_DT_1) || (CpuDid ==
> V_SA_DEVICE_ID_CFL_DT_2)
> +     || (CpuDid == V_SA_DEVICE_ID_CFL_DT_3) || (CpuDid ==
> V_SA_DEVICE_ID_CFL_DT_4)) {
> +    ///
> +    /// CFL-S 6+2, CFL S 8+2, CFl S 4+2, CFL S 2+2
> +    ///
> +    CpuPowerMgmtTestConfig->EnergyEfficientTurbo      = FALSE;
> +  }
> +  CpuPowerMgmtTestConfig->BiProcHot                     = TRUE;
> +  CpuPowerMgmtTestConfig->DisableProcHotOut             = TRUE;
> +  CpuPowerMgmtTestConfig->AutoThermalReporting          = TRUE;
> +  CpuPowerMgmtTestConfig->ThermalMonitor                = TRUE;
> +  CpuPowerMgmtTestConfig->Cx                            = TRUE;
> +  CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock             = TRUE;
> +  CpuPowerMgmtTestConfig->C1e                           = TRUE;
> +  CpuPowerMgmtTestConfig->C1AutoDemotion                = TRUE;
> +  CpuPowerMgmtTestConfig->C1UnDemotion                  = TRUE;
> +  CpuGeneration = GetCpuGeneration();
> +  if(CpuGeneration == EnumCflCpu){
> +    CpuPowerMgmtTestConfig->C3AutoDemotion                = TRUE;
> +    CpuPowerMgmtTestConfig->C3UnDemotion                  = TRUE;
> +  }
> +
> +  CpuPowerMgmtTestConfig->CStatePreWake                 = TRUE;
> +  CpuPowerMgmtTestConfig->RaceToHalt                    = TRUE;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit =
> TimeUnit1024ns;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit =
> TimeUnit1024ns;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit =
> TimeUnit1024ns;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit =
> TimeUnit1024ns;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit =
> TimeUnit1024ns;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit =
> TimeUnit1024ns;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl     = C3_LATENCY;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl     =
> C6_C7_SHORT_LATENCY;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl     =
> C6_C7_LONG_LATENCY;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl     = C8_LATENCY;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl     = C9_LATENCY;
> +  CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl     = C10_LATENCY;
> +
> +  CpuPowerMgmtTestConfig->PkgCStateLimit                = PkgAuto;
> +  CpuPowerMgmtTestConfig->CustomPowerUnit               =
> PowerUnit125MilliWatts;
> +  CpuPowerMgmtTestConfig->PpmIrmSetting                 =
> PpmIrmPairFixedPriority;
> +}
> +
> +static COMPONENT_BLOCK_ENTRY  mCpuIpBlocks [] = {
> +  {&gCpuConfigGuid,                     sizeof (CPU_CONFIG),
> CPU_CONFIG_REVISION,                        LoadCpuConfigDefault},
> +  {&gCpuPowerMgmtBasicConfigGuid,       sizeof
> (CPU_POWER_MGMT_BASIC_CONFIG),
> CPU_POWER_MGMT_BASIC_CONFIG_REVISION,
> LoadCpuPowerMgmtBasicConfigDefault},
> +  {&gCpuPowerMgmtCustomConfigGuid,      sizeof
> (CPU_POWER_MGMT_CUSTOM_CONFIG),
> CPU_POWER_MGMT_CUSTOM_CONFIG_REVISION,
> LoadCpuPowerMgmtCustomConfigDefault},
> +  {&gCpuTestConfigGuid,                 sizeof (CPU_TEST_CONFIG),
> CPU_TEST_CONFIG_REVISION,                   LoadCpuTestConfigDefault},
> +  {&gCpuPidTestConfigGuid,              sizeof (CPU_PID_TEST_CONFIG),
> CPU_PID_TEST_CONFIG_REVISION,               LoadCpuPidTestConfigDefault},
> +  {&gCpuPowerMgmtTestConfigGuid,        sizeof
> (CPU_POWER_MGMT_TEST_CONFIG),
> CPU_POWER_MGMT_TEST_CONFIG_REVISION,
> LoadCpuPowerMgmtTestConfigDefault},
> +};
> +
> +/**
> +  Get CPU config block table total size.
> +
> +  @retval Size of CPU config block table
> +**/
> +UINT16
> +EFIAPI
> +CpuGetConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize (&mCpuIpBlocks[0], sizeof
> (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> +
> +/**
> +  CpuAddConfigBlocks add all Cpu config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add CPU config
> blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuAddConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  )
> +{
> +  EFI_STATUS Status;
> +  DEBUG((DEBUG_INFO, "CPU Post-Mem Entry \n"));
> +  PostCode (0xC00);
> +
> +  Status = AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof
> (COMPONENT_BLOCK_ENTRY));
> +  DEBUG ((DEBUG_INFO, "CpuAddConfigBlocks Done \n"));
> +  PostCode (0xC09);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibPreMem.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibPreMem.c
> new file mode 100644
> index 0000000000..7d45e10236
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPoli
> cyLibPreMem.c
> @@ -0,0 +1,160 @@
> +/** @file
> +  This file is PeiCpuPolicyLibPreMem library.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiCpuPolicyLibrary.h"
> +#include <Library/PciSegmentLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PostCodeLib.h>
> +#include <Library/SaPlatformLib.h>
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuSecurityPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +
> +}
> +
> +/**
> +  Load Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuConfigLibPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_GENERATION  CpuGeneration;
> +  CPU_CONFIG_LIB_PREMEM_CONFIG  *CpuConfigLibPreMemConfig;
> +  CPU_FAMILY      CpuFamily;
> +  CPU_SKU         CpuSku;
> +  BOOLEAN         PegDisabled;
> +  UINT64          MchBar;
> +  UINT64          SaPciBase;
> +
> +  CpuConfigLibPreMemConfig = ConfigBlockPointer;
> +  CpuFamily  = GetCpuFamily();
> +  CpuSku     = GetCpuSku();
> +
> +  DEBUG ((DEBUG_INFO,
> "CpuConfigLibPreMemConfig->Header.GuidHob.Name = %g\n",
> &CpuConfigLibPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n",
> CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength));
> +
> +  /********************************
> +    CPU Config Lib PreMem configuration
> +  ********************************/
> +  CpuConfigLibPreMemConfig->HyperThreading          =
> CPU_FEATURE_ENABLE;
> +  CpuConfigLibPreMemConfig->BootFrequency           = 1;    // Maximum
> non-turbo Performance
> +  CpuConfigLibPreMemConfig->ActiveCoreCount         = 0;    // All cores
> active
> +  CpuConfigLibPreMemConfig->JtagC10PowerGateDisable =
> CPU_FEATURE_DISABLE;
> +  CpuConfigLibPreMemConfig->BistOnReset             =
> CPU_FEATURE_DISABLE;
> +  CpuConfigLibPreMemConfig->VmxEnable               =
> CPU_FEATURE_ENABLE;
> +  CpuConfigLibPreMemConfig->CpuRatio = (RShiftU64 (AsmReadMsr64
> (MSR_PLATFORM_INFO), N_PLATFORM_INFO_MAX_RATIO) &
> B_PLATFORM_INFO_RATIO_MASK);
> +
> +  CpuGeneration = GetCpuGeneration();
> +  if(CpuGeneration == EnumCflCpu){
> +    ///
> +    /// FCLK Frequency
> +    ///
> +
> +    SaPciBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS,
> SA_MC_DEV, SA_MC_FUN, 0);
> +    PciSegmentReadBuffer (SaPciBase + R_SA_MCHBAR, sizeof (MchBar),
> &MchBar);
> +    MchBar &= ((UINT64) ~BIT0);
> +    if (IsPchLinkDmi (CpuFamily) && (PciSegmentRead16
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM,
> SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, PCI_VENDOR_ID_OFFSET)) !=
> 0xFFFF)) {
> +      PegDisabled = MmioRead32 ((UINTN) MchBar +
> R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET) & BIT3;
> +    } else {
> +      PegDisabled = 1;
> +    }
> +
> +    ///
> +    /// DT/Halo FCLK = 1GHz
> +    /// Ulx/Ult FCLK = 800MHz
> +    ///
> +    if (((CpuSku == EnumCpuHalo) && (!PegDisabled)) || (CpuSku ==
> EnumCpuTrad)) {
> +      CpuConfigLibPreMemConfig->FClkFrequency = 1;  // 1Ghz
> +    }
> +    else {
> +      CpuConfigLibPreMemConfig->FClkFrequency = 0;  // 800MHz
> +    }
> +    ///
> +    /// Disable Peci Reset on C10 exit on CFL based CPU's
> +    /// Setting to 1 will activate the message that disables peci reset.
> +    ///
> +    CpuConfigLibPreMemConfig->PeciC10Reset = 1;
> +  }
> +}
> +
> +/**
> +  Load Overclocking pre-mem Config block default
> +
> +  @param[in] ConfigBlockPointer         Pointer to config block
> +**/
> +VOID
> +LoadCpuOverclockingPreMemConfigDefault (
> +  IN VOID          *ConfigBlockPointer
> +  )
> +{
> +  CPU_OVERCLOCKING_PREMEM_CONFIG
> *CpuOverclockingPreMemConfig;
> +  CpuOverclockingPreMemConfig = ConfigBlockPointer;
> +
> +  /********************************
> +    CPU Overclocking PreMem configuration
> +  ********************************/
> +  DEBUG ((DEBUG_INFO,
> "CpuOverclockingPreMemConfig->Header.GuidHob.Name = %g\n",
> &CpuOverclockingPreMemConfig->Header.GuidHob.Name));
> +  DEBUG ((DEBUG_INFO,
> "CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength =
> 0x%x\n",
> CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength));
> +}
> +
> +static COMPONENT_BLOCK_ENTRY  mCpuIpBlocksPreMem [] = {
> +  {&gCpuConfigLibPreMemConfigGuid,    sizeof
> (CPU_CONFIG_LIB_PREMEM_CONFIG),
> CPU_CONFIG_LIB_PREMEM_CONFIG_REVISION,
> LoadCpuConfigLibPreMemConfigDefault},
> +  {&gCpuOverclockingPreMemConfigGuid, sizeof
> (CPU_OVERCLOCKING_PREMEM_CONFIG),
> CPU_OVERCLOCKING_CONFIG_REVISION,
> LoadCpuOverclockingPreMemConfigDefault},
> +};
> +
> +/**
> +  Get CPU PREMEM config block table total size.
> +
> +  @retval Size of CPU PREMEM config block table
> +**/
> +UINT16
> +EFIAPI
> +CpuGetPreMemConfigBlockTotalSize (
> +  VOID
> +  )
> +{
> +  return GetComponentConfigBlockTotalSize (&mCpuIpBlocksPreMem[0],
> sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
> +}
> +
> +/**
> +  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
> +
> +  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM
> config blocks
> +
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuAddPreMemConfigBlocks (
> +  IN     VOID      *ConfigBlockTableAddress
> +  )
> +{
> +  EFI_STATUS Status;
> +  DEBUG((DEBUG_INFO, "CPU Pre-Mem Entry \n"));
> +  PostCode (0xC00);
> +
> +  Status = AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof
> (COMPONENT_BLOCK_ENTRY));
> +  DEBUG((DEBUG_INFO, "CpuAddPreMemConfigBlocks Done \n"));
> +  PostCode (0xC0F);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /CpuPlatformLibrary.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /CpuPlatformLibrary.c
> new file mode 100644
> index 0000000000..18f2028fa9
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib
> /CpuPlatformLibrary.c
> @@ -0,0 +1,415 @@
> +/** @file
> +  CPU Platform Lib implementation.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "CpuPlatformLibrary.h"
> +#include <SaAccess.h>
> +#include <MeChipset.h>
> +
> +#define SKIP_MICROCODE_CHECKSUM_CHECK 1
> +#define C6DRAM_ENABLE 1
> +#define C6DRAM_DISABLE 0
> +
> +/**
> +  Return CPU Family ID
> +
> +  @retval CPU_FAMILY              CPU Family ID
> +**/
> +CPU_FAMILY
> +EFIAPI
> +GetCpuFamily (
> +  VOID
> +  )
> +{
> +  EFI_CPUID_REGISTER Cpuid;
> +  ///
> +  /// Read the CPUID information
> +  ///
> +  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx,
> &Cpuid.RegEcx, &Cpuid.RegEdx);
> +  return ((CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL));
> +}
> +
> +/**
> +  Return Cpu stepping type
> +
> +  @retval UINT8                   Cpu stepping type
> +**/
> +CPU_STEPPING
> +EFIAPI
> +GetCpuStepping (
> +  VOID
> +  )
> +{
> +  EFI_CPUID_REGISTER Cpuid;
> +  ///
> +  /// Read the CPUID information
> +  ///
> +  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx,
> &Cpuid.RegEcx, &Cpuid.RegEdx);
> +  return ((CPU_STEPPING) (Cpuid.RegEax & CPUID_FULL_STEPPING));
> +}
> +
> +/**
> +  Return CPU Sku
> +
> +  @retval UINT8              CPU Sku
> +**/
> +UINT8
> +EFIAPI
> +GetCpuSku (
> +  VOID
> +  )
> +{
> +  UINT8              CpuType;
> +  UINT16             CpuDid;
> +  UINT32             CpuFamilyModel;
> +  EFI_CPUID_REGISTER Cpuid;
> +  BOOLEAN            SkuFound;
> +
> +  SkuFound  = TRUE;
> +  CpuType   = EnumCpuUnknown;
> +
> +  ///
> +  /// Read the CPUID & DID information
> +  ///
> +  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx,
> &Cpuid.RegEcx, &Cpuid.RegEdx);
> +  CpuFamilyModel = Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL;
> +  CpuDid = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
> +
> +  switch (CpuFamilyModel) {
> +    case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX:
> +      switch (CpuDid) {
> +        case V_SA_DEVICE_ID_KBL_MB_ULT_1:    // KBL ULT OPI
> +        case V_SA_DEVICE_ID_CFL_ULT_1:       // CFL ULT
> +        case V_SA_DEVICE_ID_CFL_ULT_2:       // CFL ULT
> +        case V_SA_DEVICE_ID_CFL_ULT_3:       // CFL ULT
> +        case V_SA_DEVICE_ID_CFL_ULT_4:       // CFL ULT
> +          CpuType = EnumCpuUlt;
> +          break;
> +
> +        default:
> +          SkuFound = FALSE;
> +          break;
> +      }
> +      break;
> +
> +    case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO:
> +      switch (CpuDid) {
> +
> +        case V_SA_DEVICE_ID_KBL_DT_2:      // DT
> +        case V_SA_DEVICE_ID_KBL_SVR_2:     // Server
> +        case V_SA_DEVICE_ID_CFL_DT_1:      // DT
> +        case V_SA_DEVICE_ID_CFL_DT_2:      // DT
> +        case V_SA_DEVICE_ID_CFL_DT_3:      // DT
> +        case V_SA_DEVICE_ID_CFL_DT_4:      // DT
> +        case V_SA_DEVICE_ID_CFL_WS_1:      // WorkStation
> +        case V_SA_DEVICE_ID_CFL_WS_2:      // Workstation
> +        case V_SA_DEVICE_ID_CFL_WS_3:      // Workstation
> +        case V_SA_DEVICE_ID_CFL_SVR_1:     // Server
> +        case V_SA_DEVICE_ID_CFL_SVR_2:     // Server
> +        case V_SA_DEVICE_ID_CFL_SVR_3:     // Server
> +          CpuType = EnumCpuTrad;
> +          break;
> +
> +        case V_SA_DEVICE_ID_KBL_HALO_2:    // Halo
> +        case V_SA_DEVICE_ID_CFL_HALO_1:    // Halo
> +        case V_SA_DEVICE_ID_CFL_HALO_2:    // Halo
> +        case V_SA_DEVICE_ID_CFL_HALO_3:    // Halo
> +          CpuType = EnumCpuHalo;
> +          break;
> +
> +        default:
> +          SkuFound = FALSE;
> +          break;
> +      }
> +      break;
> +
> +    default:
> +      SkuFound = FALSE;
> +      break;
> +  }
> +#ifdef CFL_SIMICS
> +  CpuType = EnumCpuTrad;
> +#else
> +  if (!SkuFound) {
> +    DEBUG ((DEBUG_ERROR, "Unsupported CPU SKU, Device ID: 0x%02X,
> CPUID: 0x%08X!\n", CpuDid, CpuFamilyModel));
> +    ASSERT (FALSE);
> +  }
> +#endif
> +
> +  return CpuType;
> +}
> +
> +/**
> +  Returns the processor microcode revision of the processor installed in the
> system.
> +
> +  @retval Processor Microcode Revision
> +**/
> +UINT32
> +GetCpuUcodeRevision (
> +  VOID
> +  )
> +{
> +  AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
> +  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
> +  return (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32);
> +}
> +
> +/**
> +  Verify the DWORD type checksum
> +
> +  @param[in] ChecksumAddr  - The start address to be checkumed
> +  @param[in] ChecksumLen   - The length of data to be checksumed
> +
> +  @retval EFI_SUCCESS           - Checksum correct
> +  @retval EFI_CRC_ERROR         - Checksum incorrect
> +**/
> +EFI_STATUS
> +Checksum32Verify (
> +  IN UINT32 *ChecksumAddr,
> +  IN UINT32 ChecksumLen
> +  )
> +{
> +#if SKIP_MICROCODE_CHECKSUM_CHECK
> +  return EFI_SUCCESS;
> +#else
> +  UINT32 Checksum;
> +  UINT32 Index;
> +
> +  Checksum = 0;
> +
> +  for (Index = 0; Index < ChecksumLen; Index++) {
> +    Checksum += ChecksumAddr[Index];
> +  }
> +
> +  return (Checksum == 0) ? EFI_SUCCESS : EFI_CRC_ERROR;
> +#endif
> +}
> +
> +/**
> +  This function checks the MCU revision to decide if BIOS needs to load
> +  microcode.
> +
> +  @param[in] MicrocodePointer - Microcode in memory
> +  @param[in] Revision         - Current CPU microcode revision
> +
> +  @retval EFI_SUCCESS - BIOS needs to load microcode
> +  @retval EFI_ABORTED - Don't need to update microcode
> +**/
> +EFI_STATUS
> +CheckMcuRevision (
> +  IN CPU_MICROCODE_HEADER *MicrocodePointer,
> +  IN UINT32               Revision
> +  )
> +{
> +  EFI_STATUS Status;
> +  Status = EFI_ABORTED;
> +
> +  if ((MicrocodePointer->UpdateRevision & 0x80000000) ||
> +      (MicrocodePointer->UpdateRevision > Revision) ||
> +      (Revision == 0)) {
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Check if this microcode is correct one for processor
> +
> +  @param[in] Cpuid               - processor CPUID
> +  @param[in] MicrocodeEntryPoint - entry point of microcode
> +  @param[in] Revision            - revision of microcode
> +
> +  @retval CorrectMicrocode if this microcode is correct
> +**/
> +BOOLEAN
> +CheckMicrocode (
> +  IN UINT32               Cpuid,
> +  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
> +  IN UINT32               *Revision
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  UINT8                               ExtendedIndex;
> +  MSR_IA32_PLATFORM_ID_REGISTER       Msr;
> +  UINT32                              ExtendedTableLength;
> +  UINT32                              ExtendedTableCount;
> +  BOOLEAN                             CorrectMicrocode;
> +  CPU_MICROCODE_EXTENDED_TABLE        *ExtendedTable;
> +  CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
> +
> +  Status              = EFI_NOT_FOUND;
> +  ExtendedTableLength = 0;
> +  CorrectMicrocode    = FALSE;
> +
> +  if (MicrocodeEntryPoint == NULL) {
> +    return FALSE;
> +  }
> +
> +  Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
> +
> +  ///
> +  /// Check if the microcode is for the Cpu and the version is newer
> +  /// and the update can be processed on the platform
> +  ///
> +  if ((MicrocodeEntryPoint->HeaderVersion == 0x00000001) &&
> +      !EFI_ERROR (CheckMcuRevision (MicrocodeEntryPoint, *Revision))
> +      ) {
> +    if ((MicrocodeEntryPoint->ProcessorId == Cpuid) &&
> (MicrocodeEntryPoint->ProcessorFlags & (1 << (UINT8) Msr.Bits.PlatformId))) {
> +      if (MicrocodeEntryPoint->DataSize == 0) {
> +        Status = Checksum32Verify ((UINT32 *) MicrocodeEntryPoint, 2048 /
> sizeof (UINT32));
> +      } else {
> +        Status = Checksum32Verify (
> +                   (UINT32 *) MicrocodeEntryPoint,
> +                   (MicrocodeEntryPoint->DataSize + sizeof
> (CPU_MICROCODE_HEADER)) / sizeof (UINT32)
> +                   );
> +      }
> +
> +      if (!EFI_ERROR (Status)) {
> +        CorrectMicrocode = TRUE;
> +      }
> +    } else if ((MicrocodeEntryPoint->DataSize != 0)) {
> +      ///
> +      /// Check the  Extended Signature if the entended signature exist
> +      /// Only the data size != 0 the extended signature may exist
> +      ///
> +      ExtendedTableLength = MicrocodeEntryPoint->TotalSize -
> (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
> +      if (ExtendedTableLength != 0) {
> +        ///
> +        /// Extended Table exist, check if the CPU in support list
> +        ///
> +        ExtendedTableHeader =
> (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *)
> (MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + 48);
> +        ///
> +        /// Calulate Extended Checksum
> +        ///
> +        if ((ExtendedTableLength % 4) == 0) {
> +          Status = Checksum32Verify ((UINT32 *) ExtendedTableHeader,
> ExtendedTableLength / sizeof (UINT32));
> +          if (!EFI_ERROR (Status)) {
> +            ///
> +            /// Checksum correct
> +            ///
> +            ExtendedTableCount  =
> ExtendedTableHeader->ExtendedSignatureCount;
> +            ExtendedTable       = (CPU_MICROCODE_EXTENDED_TABLE *)
> (ExtendedTableHeader + 1);
> +            for (ExtendedIndex = 0; ExtendedIndex < ExtendedTableCount;
> ExtendedIndex++) {
> +              ///
> +              /// Verify Header
> +              ///
> +              if ((ExtendedTable->ProcessorSignature == Cpuid) &&
> (ExtendedTable->ProcessorFlag & (1 << (UINT8) Msr.Bits.PlatformId))) {
> +                Status = Checksum32Verify (
> +                           (UINT32 *) ExtendedTable,
> +                           sizeof (CPU_MICROCODE_EXTENDED_TABLE) / sizeof
> (UINT32)
> +                           );
> +                if (!EFI_ERROR (Status)) {
> +                  ///
> +                  /// Find one
> +                  ///
> +                  CorrectMicrocode = TRUE;
> +                  break;
> +                }
> +              }
> +
> +              ExtendedTable++;
> +            }
> +          }
> +        }
> +      }
> +    }
> +  }
> +
> +  return CorrectMicrocode;
> +}
> +
> +/**
> +  Check on the processor if SGX is supported.
> +
> +  @retval TRUE  if SGX supported
> +  @retval FALSE if SGX is not supported
> +**/
> +BOOLEAN
> +IsSgxSupported (
> +  VOID
> +  )
> +{
> +  EFI_CPUID_REGISTER CpuidRegs;
> +
> +  //
> +  // Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
> +  //
> +  AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0,
> &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.Re
> gEdx);
> +
> +  ///
> +  /// SGX feature is supported with CPUID.(EAX=7,ECX=0):EBX[2]=1
> +  /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
> +  ///
> +  if (((CpuidRegs.RegEbx & BIT2)) && (AsmReadMsr64 (MSR_IA32_MTRRCAP)
> & BIT12)) {
> +    return TRUE;
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Get processor generation
> +
> +  @retval CPU_GENERATION  Returns the executing thread's processor
> generation.
> +**/
> +CPU_GENERATION
> +GetCpuGeneration (
> +  VOID
> +  )
> +{
> +  EFI_CPUID_REGISTER Cpuid;
> +  CPU_FAMILY         CpuFamilyModel;
> +  CPU_GENERATION     CpuGeneration;
> +
> +  CpuGeneration = EnumCflCpu;
> +  ///
> +  /// Read the CPUID information
> +  ///
> +  AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx,
> &Cpuid.RegEcx, &Cpuid.RegEdx);
> +  CpuFamilyModel = (CPU_FAMILY) (Cpuid.RegEax &
> CPUID_FULL_FAMILY_MODEL);
> +
> +  switch (CpuFamilyModel) {
> +    case EnumCpuCflUltUlx:
> +    case EnumCpuCflDtHalo:
> +      CpuGeneration = EnumCflCpu;
> +      break;
> +
> +    default:
> +      CpuGeneration = EnumCpuUnknownGeneration;
> +      ASSERT (FALSE);
> +      break;
> +  }
> +
> +  return CpuGeneration;
> +}
> +
> +/**
> +  Is Whiskey Lake CPU.
> +
> +  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
> +  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
> +**/
> +BOOLEAN
> +IsWhlCpu (
> +  VOID
> +  )
> +{
> +  CPU_FAMILY    CpuFamily;
> +  CPU_STEPPING  CpuStepping;
> +
> +  CpuFamily   = GetCpuFamily ();
> +  CpuStepping = GetCpuStepping ();
> +
> +  //
> +  // Check if it is Whiskey Lake CPU
> +  //
> +  if ((CpuFamily == EnumCpuCflUltUlx) && ((CpuStepping == EnumCflW0) ||
> (CpuStepping == EnumCflV0))) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:15 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add
> PchSmiDispatcher
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds the PchSmiDispatcher module. Dispatches PCH SMIs to appropriate
> SMI handlers registered in various SMM modules.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispat
> cher.inf  |  109 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
> |  228 ++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
> | 1031 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.
> h          |  342 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelp
> ers.h       |  157 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHel
> pers.h      |  105 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
> | 1264 ++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispat
> ch.c      | 2452 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore
> .c          |  911 ++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.
> c          | 1595 +++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
> |  254 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelp
> ers.c       |  358 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPerio
> dicTimer.c |  675 ++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPow
> erButton.c   |   83 +
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
> |  385 +++
>  Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
> |  229 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.
> c           |  231 ++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHel
> pers.c      |  764 ++++++
>  18 files changed, 11173 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDisp
> atcher.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDis
> patcher.inf
> new file mode 100644
> index 0000000000..38d5dbeebf
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDis
> patcher.inf
> @@ -0,0 +1,109 @@
> +## @file
> +# Component description file for the Pch SMI Dispatch Handlers module
> +#
> +# Copyright (c) 2019 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
> +PchEspiLib
> +S3BootScriptLib
> +ConfigBlockLib
> +PmcPrivateLib
> +PmcLib
> +SmiHandlerProfileLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +# 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
> +
> +
> +[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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
> new file mode 100644
> index 0000000000..9d6a459ff3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
> @@ -0,0 +1,228 @@
> +/** @file
> +  Defines and prototypes for the IoTrap SMM driver
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
> new file mode 100644
> index 0000000000..1906e32b5a
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
> @@ -0,0 +1,1031 @@
> +/** @file
> +  Prototypes and defines for the PCH SMM Dispatcher.
> +
> +  Copyright (c) 2019 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/PchEspiLib.h>
> +#include <Private/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 \
> +  }
> +
> +///
> +/// 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_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 union {
> +  UINTN ElapsedTime;
> +} 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 CONST 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEs
> pi.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEs
> pi.h
> new file mode 100644
> index 0000000000..193eed6bac
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEs
> pi.h
> @@ -0,0 +1,342 @@
> +/** @file
> +  eSPI SMI Dispatch header
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHe
> lpers.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHe
> lpers.h
> new file mode 100644
> index 0000000000..24e0975025
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHe
> lpers.h
> @@ -0,0 +1,157 @@
> +/** @file
> +  Helper functions for PCH SMM
> +
> +  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmH
> elpers.h
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmH
> elpers.h
> new file mode 100644
> index 0000000000..ba7ad42c9d
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmH
> elpers.h
> @@ -0,0 +1,105 @@
> +/** @file
> +  This driver is responsible for the registration of child drivers
> +  and the abstraction of the PCH SMI sources.
> +
> +  Copyright (c) 2019 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.
> +**/
> +VOID
> +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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
> new file mode 100644
> index 0000000000..ddab2fc378
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
> @@ -0,0 +1,1264 @@
> +/** @file
> +  Main implementation source file for the Io Trap SMM driver
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Private/Protocol/PchNvsArea.h>
> +#include <Library/SmiHandlerProfileLib.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsPsth.h>
> +#include <Register/PchRegsDmi.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), NULL, 0);
> +  }
> +  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
> (&gEfiSmmIoTrapDispatch2ProtocolGuid, RecordToDelete->IoTrapCallback,
> NULL, 0);
> +  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), NULL, 0);
> +  }
> +  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, NULL, 0);
> +  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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDisp
> atch.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDis
> patch.c
> new file mode 100644
> index 0000000000..2b70008fee
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDis
> patch.c
> @@ -0,0 +1,2452 @@
> +/** @file
> +  This function handle the register/unregister of PCH specific SMI events.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Library/SmiHandlerProfileLib.h>
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsSpi.h>
> +#include <Register/PchRegsPcie.h>
> +#include <Register/PchRegsPsth.h>
> +#include <Register/PchRegsItss.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,
> +  {
> +    {
> +      {
> +        PCR_ADDR_TYPE,
> +        {PCH_PCR_ADDRESS (PID_ITSS, R_ITSS_PCR_NMI)}
> +      },
> +      4,
> +      N_ITSS_PCR_NMI_NMI2SMI_EN
> +    },
> +    NULL_BIT_DESC_INITIALIZER
> +  },
> +  {
> +    {
> +      {
> +        PCR_ADDR_TYPE,
> +        {PCH_PCR_ADDRESS (PID_ITSS, R_ITSS_PCR_NMI)}
> +      },
> +      4,
> +      N_ITSS_PCR_NMI_NMI2SMI_STS
> +    }
> +  },
> +  {
> +    {
> +      ACPI_ADDR_TYPE,
> +      {R_ACPI_IO_SMI_STS}
> +    },
> +    S_ACPI_IO_SMI_STS,
> +    N_ACPI_IO_SMI_STS_TCO
> +  }
> +};
> +
> +/**
> +  Enable the Nmi2Smi source
> +**/
> +VOID
> +PchNmi2SmiEnableSource (
> +  VOID
> +  )
> +{
> +  //
> +  // The PCR[ITSS].NMI register can only be accessed with BOOT_SAI and
> SMM_SAI.
> +  // Since in CFL there is no SMM_SAI it needs PMC assistance to access this
> register.
> +  //
> +  UINT32  ItssNmi;
> +  ItssNmi = PmcGetNmiControl ();
> +  PmcSetNmiControl (ItssNmi | B_ITSS_PCR_NMI_NMI2SMI_EN);
> +}
> +
> +/**
> +  Clear the NMI status bit after the SMI handling is done
> +
> +  @param[in] SrcDesc                    Pointer to the PCH SMI source
> description table
> +**/
> +VOID
> +EFIAPI
> +PchNmi2SmiClearSource (
> +  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
> +  )
> +{
> +  // No need to clear NMI2SMI_STS since it's cleared when NMI source is
> cleared.
> +  // Clear TCO status only.
> +  PchSmmClearSource (&mDescSrcTcoSts);
> +}
> +
> +/**
> +  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);
> +    //
> +    // Since the NMI2SMI status and enable bit are at the same register,
> +    // it needs separate function to handle the source enable and clear.
> +    //
> +    Record->ClearSource = PchNmi2SmiClearSource;
> +    PchNmi2SmiEnableSource ();
> +    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 = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_SPI,
> +                 PCI_FUNCTION_NUMBER_PCH_SPI,
> +                 0
> +                 );
> +  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);
> +}
> +
> +/**
> +  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.
> +    //
> +    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.
> +    //
> +    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 ==
> PCI_DEVICE_NUMBER_PCH_SPI) &&
> +      (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc ==
> PCI_FUNCTION_NUMBER_PCH_SPI) &&
> +      (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 ==
> PCI_DEVICE_NUMBER_PCH_LPC) &&
> +             (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc ==
> PCI_FUNCTION_NUMBER_PCH_LPC) &&
> +             (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                   Indicate the RP index (0-based)
> +  @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;
> +
> +  //
> +  // 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;
> +  }
> +
> +  GetPchPcieRpDevFun (RpIndex, &RpDev, &RpFun);
> +  //
> +  // Patch the RP device number and function number of srcdesc.
> +  //
> +  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)) {
> +    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid,
> (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction,
> (UINTN)RETURN_ADDRESS (0), NULL, 0);
> +  }
> +  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                   Indicate the RP index (0-based)
> +  @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;
> +
> +  //
> +  // 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;
> +  }
> +
> +  GetPchPcieRpDevFun (RpIndex, &RpDev, &RpFun);
> +  //
> +  // Patch the RP device number and function number of srcdesc.
> +  //
> +  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)) {
> +    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid,
> (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction,
> (UINTN)RETURN_ADDRESS (0), NULL, 0);
> +  }
> +  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                   Indicate the RP index (0-based)
> +  @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;
> +
> +  //
> +  // 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;
> +  }
> +
> +  GetPchPcieRpDevFun (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)) {
> +    SmiHandlerProfileRegisterHandler (&gPchPcieSmiDispatchProtocolGuid,
> (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
> +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, NULL, 0);
> +  }
> +  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 = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_SPI,
> +                 PCI_FUNCTION_NUMBER_PCH_SPI,
> +                 0
> +                 );
> +  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;
> +  SpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
> +                 DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                 DEFAULT_PCI_BUS_NUMBER_PCH,
> +                 PCI_DEVICE_NUMBER_PCH_SPI,
> +                 PCI_FUNCTION_NUMBER_PCH_SPI,
> +                 0
> +                 );
> +  PciSegmentAndThenOr32 (
> +    SpiRegBase + R_SPI_CFG_BC,
> +    (UINT32) ~B_SPI_CFG_BC_SYNC_SS,
> +    B_SPI_CFG_BC_ASE_BWP
> +    );
> +
> +  //
> +  // 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 ==
> PCI_DEVICE_NUMBER_PCH_SPI) &&
> +      (Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Fnc ==
> PCI_FUNCTION_NUMBER_PCH_SPI) &&
> +      (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 = PCI_SEGMENT_LIB_ADDRESS (
> +                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                   PCI_DEVICE_NUMBER_PCH_SPI,
> +                   PCI_FUNCTION_NUMBER_PCH_SPI,
> +                   0
> +                   );
> +    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;
> +      GetPchPcieRpNumber (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]);
> +  if (!EFI_ERROR (Status)) {
> +    SmiHandlerProfileRegisterHandler
> (&gEfiSmmIoTrapDispatch2ProtocolGuid,
> (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] 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
> +  )
> +{
> +  DATABASE_RECORD                   *RecordToDelete;
> +  EFI_STATUS                        Status;
> +
> +  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
> +  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
> +  if (!EFI_ERROR (Status)) {
> +    SmiHandlerProfileUnregisterHandler
> (&gEfiSmmIoTrapDispatch2ProtocolGuid, RecordToDelete->Callback, NULL, 0);
> +  }
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCo
> re.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCo
> re.c
> new file mode 100644
> index 0000000000..9c36103396
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCo
> re.c
> @@ -0,0 +1,911 @@
> +/** @file
> +  This driver is responsible for the registration of child drivers
> +  and the abstraction of the PCH SMI sources.
> +
> +  Copyright (c) 2019 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/PchRegsGpio.h>
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsLpc.h>
> +
> +//
> +// 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 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;
> +
> +  //
> +  // 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, NULL, 0);
> +  }
> +  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.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_EN_127_96) &
> B_ACPI_IO_GPE0_EN_127_96_WADT) &&
> +        (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 {
> +                  //
> +                  // 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEs
> pi.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEs
> pi.c
> new file mode 100644
> index 0000000000..9eb61947a3
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEs
> pi.c
> @@ -0,0 +1,1595 @@
> +/** @file
> +  eSPI SMI implementation
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmEspi.h"
> +#include <Private/Library/PmcPrivateLib.h>
> +#include <Library/PchEspiLib.h>
> +#include <Library/SmiHandlerProfileLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsLpc.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 = PCI_SEGMENT_LIB_ADDRESS (
> +                         DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                         DEFAULT_PCI_BUS_NUMBER_PCH,
> +                         PCI_DEVICE_NUMBER_PCH_LPC,
> +                         PCI_FUNCTION_NUMBER_PCH_LPC,
> +                         0
> +                         );
> +      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.
> +  //
> +  PmcLockEspiSmi ();
> +  //
> +  // 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;
> +    default:
> +      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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGp
> i.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGp
> i.c
> new file mode 100644
> index 0000000000..43277f0938
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGp
> i.c
> @@ -0,0 +1,254 @@
> +/** @file
> +  File to contain all the hardware specific stuff for the Smm Gpi dispatch
> protocol.
> +
> +  Copyright (c) 2019 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/PchRegsGpio.h>
> +#include <Register/PchRegsPmc.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 CONST 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), (void *)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, NULL, 0);
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHe
> lpers.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHe
> lpers.c
> new file mode 100644
> index 0000000000..f6413921eb
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHe
> lpers.c
> @@ -0,0 +1,358 @@
> +/** @file
> +  Helper functions for PCH SMM dispatcher.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Register/PchRegsItss.h>
> +#include <Private/Library/PmcPrivateLib.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;
> +    }
> +  }
> +
> +  //
> +  // Special handling for NMI bit since it requires PMC IPC command.
> +  // Do w/a here instead of in ReadBitDesc to reduce the PMC IPC command
> usage.
> +  //
> +  // The PCR[ITSS].NMI register can only be accessed with BOOT_SAI and
> SMM_SAI.
> +  // Since in CFL there is no SMM_SAI it needs PMC assistance to access this
> register.
> +  //
> +  if ((Src->En[0].Reg.Data.Pcr.Fields.Pid == PID_ITSS) &&
> +      (Src->En[0].Reg.Data.Pcr.Fields.Offset == R_ITSS_PCR_NMI))
> +  {
> +    UINT32  ItssNmi;
> +    ItssNmi = PmcGetNmiControl ();
> +    if ((ItssNmi & (BIT0 << Src->En[0].Bit)) &&
> +        (ItssNmi & (BIT0 << Src->Sts[0].Bit)))
> +    {
> +      return TRUE;
> +    } else {
> +      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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPe
> riodicTimer.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPe
> riodicTimer.c
> new file mode 100644
> index 0000000000..9a5ae464e0
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPe
> riodicTimer.c
> @@ -0,0 +1,675 @@
> +/** @file
> +  File to contain all the hardware specific stuff for the Periodical Timer
> dispatch protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Protocol/PchSmmPeriodicTimerControl.h>
> +#include <Private/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.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) {
> +      ///
> +      /// 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;
> +
> +  if (SmiTickInterval == NULL) {
> +    ASSERT(FALSE);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  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;
> +  TIMER_INTERVAL                        *TimerInterval;
> +
> +  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
> +  TimerInterval = NULL;
> +  TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
> +  if (TimerInterval == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  PchSmmDisableSource
> (&mTimerSourceDesc[TimerInterval->AssociatedTimer]);
> +  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;
> +  TIMER_INTERVAL                        *TimerInterval;
> +
> +  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
> +  TimerInterval = NULL;
> +  TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
> +  if (TimerInterval == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  PchSmmEnableSource
> (&mTimerSourceDesc[TimerInterval->AssociatedTimer]);
> +  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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPo
> werButton.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPo
> werButton.c
> new file mode 100644
> index 0000000000..17898b899b
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPo
> werButton.c
> @@ -0,0 +1,83 @@
> +/** @file
> +  File to contain all the hardware specific stuff for the Smm Power Button
> dispatch protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PchSmmHelpers.h>
> +#include <Private/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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw
> .c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw
> .c
> new file mode 100644
> index 0000000000..35ecfe5238
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw
> .c
> @@ -0,0 +1,385 @@
> +/** @file
> +  File to contain all the hardware specific stuff for the Smm Sw dispatch
> protocol.
> +
> +  Copyright (c) 2019 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/PchRegsPmc.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++) {
> +      Status = SmiInputValueDuplicateCheck (Index);
> +      if (!EFI_ERROR (Status)) {
> +        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;
> +  }
> +
> +  Status = SmiInputValueDuplicateCheck
> (DispatchContext->SwSmiInputValue);
> +  if (EFI_ERROR (Status)) {
> +    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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.
> c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.
> c
> new file mode 100644
> index 0000000000..52bb906315
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.
> c
> @@ -0,0 +1,229 @@
> +/** @file
> +  File to contain all the hardware specific stuff for the Smm Sx dispatch
> protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Register/PchRegsPmc.h>
> +#include <Register/PchRegsPcie.h>
> +
> +#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 = PchPcieBase (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 ();
> +
> +  ///
> +  /// Flush cache into memory before we go to sleep. It is necessary for S3
> sleep
> +  /// because we may update memory in SMM Sx sleep handlers -- the
> updates are in cache now
> +  ///
> +  AsmWbinvd ();
> +
> +  ///
> +  /// 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);
> +
> +    ///
> +    /// Flush cache into memory before we go 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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUs
> b.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUs
> b.c
> new file mode 100644
> index 0000000000..061dbe4300
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUs
> b.c
> @@ -0,0 +1,231 @@
> +/** @file
> +  File to contain all the hardware specific stuff for the Smm USB dispatch
> protocol.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Register/RegsUsb.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsPmc.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/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmH
> elpers.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmH
> elpers.c
> new file mode 100644
> index 0000000000..4ac00b831f
> --- /dev/null
> +++
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmH
> elpers.c
> @@ -0,0 +1,764 @@
> +/** @file
> +  This driver is responsible for the registration of child drivers
> +  and the abstraction of the PCH SMI sources.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchSmmHelpers.h"
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsPmc.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.
> +**/
> +VOID
> +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 &= (UINT32)~(B_ACPI_IO_GPE0_STS_127_96_WADT);
> +
> +    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);
> +}
> +
> +/**
> +  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;
> +  }
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:15   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:15 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>
> Subject: [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add
> CoffeelakeSiliconPkg maintainers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Maintainers.txt | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt index 876ae5612a..bc8cbd6458
> 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -125,9 +125,14 @@ Silicon/Intel/Vlv2DeviceRefCodePkg
>  M: Zailiang Sun <zailiang.sun@intel.com>
>  M: Yi Qian <yi.qian@intel.com>
> 
> +Silicon/Intel/CoffeelakeSiliconPkg
> +M: Chasel Chiu <chasel.chiu@intel.com>
> +M: Michael Kubacki <michael.a.kubacki@intel.com>
> +M: Sai Chaganty <rangasai.v.chaganty@intel.com>
> +
>  Silicon/Intel/KabylakeSiliconPkg
>  M: Chasel Chiu <chasel.chiu@intel.com>
> -M: Michael A Kubacki <michael.a.kubacki@intel.com>
> +M: Michael Kubacki <michael.a.kubacki@intel.com>
>  M: Sai Chaganty <rangasai.v.chaganty@intel.com>
> 
>  Silicon/Intel/LewisburgPkg
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:16   ` Chiu, Chasel
  2019-08-19 18:09   ` Sinha, Ankit
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:16 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add
> package and headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> Create the WhiskeylakeOpenBoardPkg to provide board support code. The
> package may support Coffee Lake (CFL) and Whiskey Lake (WHL) boards. The
> package serves as a board support package in the EDK II Minimum Platform
> design. Silicon support for this package is provided in CoffeeLakeFspBinPkg
> in the FSP repository and CoffeelakeSiliconPkg in the edk2-platforms
> repository.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> |  565 +++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Dxe
> CheckIommuSupportLib.h     |   43 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Dxe
> TbtPolicyLib.h             |   49 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Dxe
> TbtSecurityLib.h           |  131 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Pei
> CheckIommuSupportLib.h     |   21 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Pei
> TbtPolicyLib.h             |   43 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Pei
> TbtTaskDispatchLib.h       |   61 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/Tbt
> CommonLib.h                |  261 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbt
> Policy.h                    |   31 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Lib
> rary/PeiDTbtInitLib.h      |  130 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Lib
> rary/PeiTbtCommonInitLib.h |   51 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/Di
> sableBmeProtocol.h         |   36 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/D
> xeTbtPolicy.h               |  137 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/T
> btNvsArea.h                 |   50 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardIn
> fo.h                        |   23 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAre
> aDef.h                       |   68 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyC
> ommonDefinition.h           |   84 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
> |  118 ++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
> |   51 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
> |   57 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.
> h                           |   20 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
> | 1766 ++++++++++++++++++++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
> |   41 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
> |   68 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpd
> ateLib.h                    |   75 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpd
> ateLib.h                     |   27 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpd
> ateLib.h                    |   25 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardC
> onfigLib.h                  |   30 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpda
> teLib.h                     |   25 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
> |   29 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflic
> tLib.h                     |   46 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib
> .h                          |  123 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.
> h                          |   48 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
> |   34 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
> |   40 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardCo
> nfigLib.h                  |  141 ++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
> |   38 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
> |   23 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
> |   51 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.
> h                          |  106 ++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
> |   33 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
> |   29 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.
> h                           |   47 +
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
> |  144 ++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
> |  157 ++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
> |  112 ++
>  46 files changed, 5288 insertions(+)
> 
> diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> new file mode 100644
> index 0000000000..9d56f0e841
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> @@ -0,0 +1,565 @@
> +## @file
> +# Module describe the entire platform configuration.
> +#
> +# The DEC files are used by the utilities that parse DSC and
> +# INF files to generate AutoGen.c and AutoGen.h files
> +# for the build infrastructure.
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +
> +[Defines]
> +DEC_SPECIFICATION = 0x00010017
> +PACKAGE_NAME = OpenBoardPkg
> +PACKAGE_VERSION = 0.1
> +PACKAGE_GUID = 0A8BA6E8-C8AC-4AC1-87AC-52772FA6AE5E
> +
> +[Includes]
> +Include
> +WhiskeylakeURvp\Include
> +Features\Tbt\Include
> +
> +[Guids]
> +
> +gBoardModuleTokenSpaceGuid            =  {0x72d1fff7, 0xa42a, 0x4219,
> {0xb9, 0x95, 0x5a, 0x67, 0x53, 0x6e, 0xa4, 0x2a}}
> +
> +gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A,
> 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
> +
> +gTbtInfoHobGuid                       =  {0x74a81eaa, 0x033c, 0x4783, {0xbe,
> 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}}
> +
> +gPlatformModuleTokenSpaceGuid         =  {0x69d13bf0, 0xaf91, 0x4d96,
> {0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0}}
> +
> +gMeInfoSetupGuid                      =  {0x78259433, 0x7b6d, 0x4db3, {0x9a,
> 0xe8, 0x36, 0xc4, 0xc2, 0xc3, 0xa1, 0x7d}}
> +gRealModeFileGuid                     =  {0xdf84ed23, 0x5d53, 0x423f, {0xaa,
> 0x81, 0x0f, 0x0e, 0x6f, 0x55, 0xc6, 0x9b}}
> +gVirtualKeyboardDriverImageGuid       =  {0xe4735aac, 0x9c27, 0x493f, {0x86,
> 0xea, 0x9e, 0xff, 0x43, 0xd7, 0xad, 0xcd}}
> +gPegConfigVariableGuid                =  {0xb414caf8, 0x8225, 0x4d6f, {0xb9,
> 0x18, 0xcd, 0xe5, 0xcb, 0x84, 0xcf, 0x0b}}
> +gSaSetupVariableGuid                  =  {0x72c5e28c, 0x7783, 0x43a1, {0x87,
> 0x67, 0xfa, 0xd7, 0x3f, 0xcc, 0xaf, 0xa4}}
> +gMeSetupVariableGuid                  =  {0x5432122d, 0xd034, 0x49d2, {0xa6,
> 0xde, 0x65, 0xa8, 0x29, 0xeb, 0x4c, 0x74}}
> +gCpuSetupVariableGuid                 =  {0xb08f97ff, 0xe6e8, 0x4193, {0xa9,
> 0x97, 0x5e, 0x9e, 0x9b, 0xa,  0xdb, 0x32}}
> +gCpuSmmGuid                           =  {0x90d93e09, 0x4e91, 0x4b3d, {0x8c,
> 0x77, 0xc8, 0x2f, 0xf1, 0xe,  0x3c, 0x81}}
> +gPchSetupVariableGuid                 =  {0x4570b7f1, 0xade8, 0x4943, {0x8d,
> 0xc3, 0x40, 0x64, 0x72, 0x84, 0x23, 0x84}}
> +gSiSetupVariableGuid                  =  {0xAAF8E719, 0x48F8, 0x4099, {0xA6,
> 0xF7, 0x64, 0x5F, 0xBD, 0x69, 0x4C, 0x3D}}
> +gDebugConfigVariableGuid              =  {0xDE0A5E74, 0x4E3E, 0x3D96, {0xA4,
> 0x40, 0x2C, 0x96, 0xEC, 0xBD, 0x3C, 0x97}}
> +gDebugConfigHobGuid                   =  {0x2f6a6bb7, 0x9dc7, 0x4bf6, {0x94,
> 0x04, 0x22, 0x70, 0xc0, 0xe3, 0xbe, 0x2f}}
> +gChassisIntrudeDetHobGuid             =  {0xdea43de2, 0x756b, 0x4b3b,
> {0x75, 0x1c, 0xad, 0xeb, 0x8d, 0xff, 0x56, 0xa3}}
> +
> +gGpioCheckConflictHobGuid             =  {0x5603f872, 0xefac, 0x40ae, {0xb9,
> 0x7e, 0x13, 0xb2, 0xf8, 0x07, 0x80, 0x21}}
> +
> +gAttemptUsbFirstHotkeyInfoHobGuid     =  {0x38b8e214, 0x1468, 0x4bb7,
> {0x95, 0xb1, 0x74, 0x59, 0x1e, 0x4c, 0x6e, 0x1d}}
> +gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A,
> 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
> +##
> +## ChipsetInitBinary
> +##
> +gCnlPchLpChipsetInitTableDxGuid          =  {0xc9505bc0, 0xaa3d, 0x4056,
> {0x99, 0x95, 0x87, 0x0c, 0x8d, 0xe8, 0x59, 0x4e}}
> +
> +
> +[Protocols]
> +gTbtNvsAreaProtocolGuid               =  {0x4d6a54d1, 0xcd56, 0x47f3, {0x93,
> 0x6e, 0x7e, 0x51, 0xd9, 0x31, 0x15, 0x4f}}
> +gDxeTbtPolicyProtocolGuid             =  {0x196bf9e3, 0x20d7, 0x4b7b, {0x89,
> 0xf9, 0x31, 0xc2, 0x72, 0x08, 0xc9, 0xb9}}
> +
> +[Ppis]
> +gPeiTbtPolicyPpiGuid                  =  {0xd7e7e1e6, 0xcbec, 0x4f5f, {0xae,
> 0xd3, 0xfd, 0xc0, 0xa8, 0xb0, 0x7e, 0x25}}
> +gPeiTbtPolicyBoardInitDonePpiGuid     =  {0x970f9c60, 0x8547, 0x49d7,
> { 0xa4, 0xb, 0x1e, 0xc4, 0xbc, 0x4e, 0xe8, 0x9b}}
> +
> +[LibraryClasses]
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> +
> +[PcdsFixedAtBuild]
> +
> +gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange|0x0010|UINT16|0x1
> 0001004
> +gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding|0x3c03|UINT16|0
> x10001005
> +
> +gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress|0xFED18000|UINT6
> 4|0x90000003
> +gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize|0x1000|UINT32|0x900
> 00004
> +gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress|0xFED19000|UINT64|
> 0x90000005
> +gPlatformModuleTokenSpaceGuid.PcdEpMmioSize|0x1000|UINT32|0x9000
> 0006
> +gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress|0xFED84000|UINT
> 64|0x90000007
> +gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize|0x1000|UINT32|0x90
> 000008
> +gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress|0xFED80000|UIN
> T64|0x90000009
> +gPlatformModuleTokenSpaceGuid.PcdEdramMmioSize|0x4000|UINT32|0x9
> 000000A
> +gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress|0xFEE00000|UINT6
> 4|0x9000000B
> +gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize|0x1000|UINT32|
> 0x9000000C
> +gPlatformModuleTokenSpaceGuid.PcdApicIoAddress|0xFEC00000|UINT64|
> 0x9000000D
> +gPlatformModuleTokenSpaceGuid.PcdApicIoMmioSize|0x1000|UINT32|0x9
> 000000E
> +gPlatformModuleTokenSpaceGuid.PcdGttMmAddress|0xCF000000|UINT64|
> 0x9000000F
> +gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress|0xD0000000|UINT64|
> 0x90000010
> +gPlatformModuleTokenSpaceGuid.PcdAcpiEnableSwSmi|0xF0|UINT8|0x900
> 00012
> +gPlatformModuleTokenSpaceGuid.PcdAcpiDisableSwSmi|0xF1|UINT8|0x900
> 00013
> +gPlatformModuleTokenSpaceGuid.PcdPcieDockBridgeResourcePatchSmi|0x
> 4D|UINT8|0x90000014
> +gPlatformModuleTokenSpaceGuid.PcdCmosFastBootDefaultValue|0x01|UIN
> T8|0x90000016
> +gPlatformModuleTokenSpaceGuid.PcdCmosDebugPrintErrorLevelDefaultVal
> ue|0x80000046|UINT32|0x90000017
> +gPlatformModuleTokenSpaceGuid.PcdOverClockingInterfaceSwSmi|0x72|UI
> NT8|0x90000019
> +gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort|0x2F|
> UINT16|0x9000001A
> +gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort|0x2E
> |UINT16|0x9000001B
> +gPlatformModuleTokenSpaceGuid.PcdApicIoIdPch|0x02|UINT8|0x9000001E
> +gPlatformModuleTokenSpaceGuid.PcdRuntimeUpdateFvHeaderLength|0x4
> 8|UINT8|0x90000020
> +gPlatformModuleTokenSpaceGuid.PcdEcExtraIoBase|0x6A0|UINT16|0x2000
> 0505
> +gPlatformModuleTokenSpaceGuid.PcdFspTemporaryRamSize|0x1000|UINT3
> 2|0x10001003
> +
> +gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition|0x01|UINT8|0x90
> 000015
> +gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort|0x4e|UINT16|0x90000
> 018
> +gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort|0x164E|UINT1
> 6|0x9000001C
> +gBoardModuleTokenSpaceGuid.PcdSioBaseAddress|0x0680|UINT16|0x9000
> 001D
> +gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort|0x4f|UINT16|0x900000
> 1F
> +gBoardModuleTokenSpaceGuid.PcdLpcSioIndexDefaultPort|0x164E|UINT16
> |0x90000021
> +gBoardModuleTokenSpaceGuid.PcdLpcSioDataDefaultPort|0x164F|UINT16|
> 0x90000022
> +
> +[PcdsDynamic]
> +# Board GPIO Table
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTable|0|UINT32|0x00000040
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize|0|UINT16|0x00000
> 041
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2|0|UINT32|0x0000004
> 2
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size|0|UINT16|0x0000
> 0043
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem|0|UINT32|0x0
> 00000113
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize|0|UINT16|
> 0x000000114
> +
> +# Board Expander GPIO Table
> +gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable|0|UINT32|0x00000
> 044
> +gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize|0|UINT16|0x00
> 000045
> +gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2|0|UINT32|0x0000
> 0046
> +gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size|0|UINT16|0x0
> 0000047
> +
> +# TouchPanel & SDHC CD GPIO Table
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel|0|UINT32|0
> x00000048
> +
> +# PCH-LP HSIO PTSS Table
> +gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1|0|UINT32|0x
> 0000004A
> +gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2|0|UINT32|0x
> 0000004B
> +gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size|0|UINT16
> |0x0000004C
> +gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size|0|UINT16
> |0x0000004D
> +gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1|0|UINT32|0x0
> 000004E
> +gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2|0|UINT32|0x0
> 000004F
> +gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size|0|UINT16|
> 0x00000050
> +gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size|0|UINT16|
> 0x00000051
> +
> +# PCH-H HSIO PTSS Table
> +gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1|0|UINT32|0x0
> 0000052
> +gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2|0|UINT32|0x0
> 0000053
> +gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size|0|UINT16|
> 0x00000054
> +gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size|0|UINT16|
> 0x00000055
> +gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1|0|UINT32|0x00
> 000056
> +gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2|0|UINT32|0x00
> 000057
> +gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size|0|UINT16|
> 0x00000058
> +gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size|0|UINT16|
> 0x00000059
> +
> +# HDA Verb Table
> +gBoardModuleTokenSpaceGuid.PcdHdaVerbTable|0|UINT32|0x0000005A
> +gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2|0|UINT32|0x0000005B
> +gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable|0|UINT32|0x0000005
> C
> +gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1|0|UINT32|0x0
> 000005D
> +gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2|0|UINT32|0x0
> 000005E
> +gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3|0|UINT32|0x0
> 000005F
> +gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable|0|UINT32|0
> x00000060
> +
> +# SA Misc Configuration
> +gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd|0|UINT8|0x00000066
> +gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment|0|UINT16|
> 0x00000067
> +gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit|0|UINT16|0x00000101
> +
> +# DRAM Configuration
> +gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor|0|UINT32|0x000000
> 68
> +gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget|0|UINT32|0x00000069
> +gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap|0|UINT32|0x0000006A
> +gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize|0|UINT16|0x00000
> 06B
> +gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram|0|UINT32|0x000
> 0006C
> +gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize|0|UINT16|0
> x0000006D
> +gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl|FALSE|BO
> OLEAN|0x0000006E
> +gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved|FALSE|BOOLEAN
> |0x0000006F
> +gBoardModuleTokenSpaceGuid.PcdMrcSpdData|0|UINT32|0x00000070
> +gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize|0|UINT16|0x00000071
> +
> +# PEG RESET GPIO
> +gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl|FALSE|BOOLEAN|
> 0x00000072
> +gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort|FALSE|BOOLEAN|
> 0x00000073
> +gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo|0|UINT32|0x000000
> 79
> +gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo|0|UINT8|0x0
> 000007A
> +gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo|0|UINT32|0x0000
> 007B
> +gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive|FALSE|BOOLEAN|0x
> 0000007C
> +gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo|0|UINT8|0
> x0000007D
> +gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo|0|UINT32|0x00
> 00007E
> +gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive|FALSE|BOOLEAN|
> 0x0000007F
> +
> +# SPD Address Table
> +gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0|0|UINT8|0x0000
> 0099
> +gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1|0|UINT8|0x0000
> 009A
> +gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2|0|UINT8|0x0000
> 009B
> +gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3|0|UINT8|0x0000
> 009C
> +
> +# CA Vref Configuration
> +gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig|0|UINT8|0x0000009D
> +
> +# USB 2.0 Port AFE
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe|0|UINT32|0x000000BF
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe|0|UINT32|0x000000C0
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe|0|UINT32|0x000000C1
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe|0|UINT32|0x000000C2
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe|0|UINT32|0x000000C3
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe|0|UINT32|0x000000C4
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe|0|UINT32|0x000000C5
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe|0|UINT32|0x000000C6
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe|0|UINT32|0x000000C7
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe|0|UINT32|0x000000C8
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe|0|UINT32|0x000000C9
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe|0|UINT32|0x000000CA
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe|0|UINT32|0x000000CB
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe|0|UINT32|0x000000CC
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe|0|UINT32|0x000000CD
> +gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe|0|UINT32|0x000000CE
> +
> +# USB 2.0 Port Over Current Pin
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0|0|UINT8|0x
> 000000CF
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1|0|UINT8|0x
> 000000D0
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2|0|UINT8|0x
> 000000D1
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3|0|UINT8|0x
> 000000D2
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4|0|UINT8|0x
> 000000D3
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5|0|UINT8|0x
> 000000D4
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6|0|UINT8|0x
> 000000D5
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7|0|UINT8|0x
> 000000D6
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8|0|UINT8|0x
> 000000D7
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9|0|UINT8|0x
> 000000D8
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10|0|UINT8|0
> x000000D9
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11|0|UINT8|0
> x000000DA
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12|0|UINT8|0
> x000000DB
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13|0|UINT8|0
> x000000DC
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14|0|UINT8|0
> x000000DD
> +gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15|0|UINT8|0
> x000000DE
> +
> +# USB 3.0 Port Over Current Pin
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0|0|UINT8|0x
> 000000DF
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1|0|UINT8|0x
> 000000E0
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2|0|UINT8|0x
> 000000E1
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3|0|UINT8|0x
> 000000E2
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4|0|UINT8|0x
> 000000E3
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5|0|UINT8|0x
> 000000E4
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6|0|UINT8|0x
> 000000E5
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7|0|UINT8|0x
> 000000E6
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8|0|UINT8|0x
> 000000E7
> +gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9|0|UINT8|0x
> 000000E8
> +
> +# Misc
> +gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent|FALSE|BOOLEAN|0x
> 000000EC
> +
> +# TBT
> +gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel
> |0|BOOLEAN|0x000000F3
> +gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad
> |0|UINT32|0x000000F4
> +gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad
> |0|UINT32|0x000000F5
> +gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport
> |0|UINT8|0x000000FA
> +gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI |0|UINT8|0x000000FB
> +gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify |0|UINT8|0x000000FC
> +gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq|0|UINT8|0x000000FD
> +gBoardModuleTokenSpaceGuid.PcdDTbtAspm |0|UINT8|0x000000FE
> +gBoardModuleTokenSpaceGuid.PcdDTbtLtr | 0 | UINT8| 0x00000116
> +gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch |0|UINT8|0x000000FF
> +gBoardModuleTokenSpaceGuid.PcdRtd3Tbt |0|UINT8|0x00000100
> +gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq |0|UINT8|0x0000010A
> +gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax
> |0|UINT8|0x00000107
> +gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd
> |0|UINT16|0x00000108
> +gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax
> |0|UINT8|0x00000109
> +
> +# UCMC GPIO Table
> +gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable|0|UINT32|0x0000
> 00111
> +gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize|0|UINT16|0x
> 000000112
> +
> +gBoardModuleTokenSpaceGuid.PcdAcpiSleepState|1|UINT8|0x40000002
> +gBoardModuleTokenSpaceGuid.PcdAcpiHibernate|1|UINT8|0x40000003
> +gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle|0|UINT8|0x40000004
> +gBoardModuleTokenSpaceGuid.PcdPciExpNative|0|UINT8|0x40000005
> +gBoardModuleTokenSpaceGuid.PcdNativeAspmEnable|1|UINT8|0x4000000
> 6
> +gBoardModuleTokenSpaceGuid.PcdPs2KbMsEnable|0|UINT8|0x40000009
> +gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints|1|UINT8|0x400
> 0000A
> +gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints|0|UINT8|0x40
> 00000B
> +gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints|1|UINT8|0x40
> 00000C
> +
> +# 0: Type-C
> +# 1: Stacked-Jack
> +gBoardModuleTokenSpaceGuid.PcdAudioConnector|0|UINT8|0x40000012
> +
> +gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress|0|UINT64|0x4000001
> 3
> +
> +# gIntelPeiGraphicsVbtGuid =  {0x4ad46122, 0xffeb, 0x4a52, {0xbf, 0xb0, 0x51,
> 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}}
> +gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid|{0x22, 0x61, 0xd4,
> 0x4a, 0xeb, 0xff, 0x52, 0x4a, 0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d,
> 0xb0}|VOID*|0x40000014
> +#==============================================================
> +#
> +# The PCD which indicates the Memory Slot Population.
> +#
> +gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType|FALSE|
> BOOLEAN|0x00101027
> +gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate|0|UINT
> 64|0x00000010
> +
> +# Board GPIO Table
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem|
> 0|UINT32|0x001000115
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSi
> ze|0|UINT16|0x001000116
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem|
> 0|UINT32|0x001000117
> +gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSi
> ze|0|UINT16|0x001000118
> +gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio|0x0|UINT3
> 2|0x0010020C
> +gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity|0x0|UINT8|0x0
> 010022E
> +gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio|0x0|UINT32|0x001002
> 2F
> +gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio|0x0|UINT32|0x001002
> 30
> +gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable|FALSE|BOOLEAN|0x00
> 100231
> +gBoardModuleTokenSpaceGuid.PcdWlanWakeGpio|0x0|UINT32|0x0010023
> 4
> +gBoardModuleTokenSpaceGuid.PcdWlanRootPortNumber|0x0|UINT8|0x00
> 100235
> +gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround|FALSE|BOOLEA
> N|0x00100236
> +
> +# UCMC GPIO Table
> +gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable|0|UINT32|0x0010
> 0033
> +gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize|0|UINT16|0x0
> 0100034
> +
> +# PEG RESET GPIO
> +gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad|0|UINT32|0x000000
> 74
> +gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive|FALSE|BOOLEAN|
> 0x00000075
> +gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad|0|UINT32|0x000001
> 05
> +gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive|FALSE|BOOLEAN|
> 0x00000106
> +
> +# PCIE RTD3 GPIO
> +gBoardModuleTokenSpaceGuid.PcdRootPortDev|0xFF|UINT8|0x00000076
> +gBoardModuleTokenSpaceGuid.PcdRootPortFunc|0xFF|UINT8|0x00000077
> +gBoardModuleTokenSpaceGuid.PcdRootPortIndex|0xFF|UINT8|0x00000104
> +gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport|0|UINT8|0x00000078
> +
> +gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport|0|UINT8|0x00000080
> +gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo|0|UINT32|0x000000
> 81
> +gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo|0|UINT8|0x0
> 0000082
> +gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo|0|UINT32|0x0000
> 0083
> +gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive|FALSE|BOOLEAN|0x
> 00000084
> +gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo|0|UINT8|0
> x00000085
> +gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo|0|UINT32|0x00
> 000086
> +gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive|FALSE|BOOLEAN|
> 0x00000087
> +
> +gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport|0|UINT8|0x00000088
> +gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo|0|UINT32|0x000000
> 89
> +gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo|0|UINT8|0x0
> 000008A
> +gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo|0|UINT32|0x0000
> 008B
> +gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive|FALSE|BOOLEAN|0x
> 0000008C
> +gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo|0|UINT8|0
> x0000008D
> +gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo|0|UINT32|0x00
> 00008E
> +gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive|FALSE|BOOLEAN|
> 0x0000008F
> +gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport|0|UINT8|0x00000130
> +gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo|0|UINT32|0x000001
> 31
> +gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo|0|UINT8|0x0
> 0000132
> +gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo|0|UINT32|0x0000
> 0133
> +gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive|FALSE|BOOLEAN|0x
> 00000134
> +gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo|0|UINT8|0
> x00000135
> +gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo|0|UINT32|0x00
> 000136
> +gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive|FALSE|BOOLEAN|
> 0x00000137
> +
> +# Root Port Clock Info
> +gBoardModuleTokenSpaceGuid.PcdPcieClock0|0|UINT64|0x0000009E
> +gBoardModuleTokenSpaceGuid.PcdPcieClock1|0|UINT64|0x0000009F
> +gBoardModuleTokenSpaceGuid.PcdPcieClock2|0|UINT64|0x000000A0
> +gBoardModuleTokenSpaceGuid.PcdPcieClock3|0|UINT64|0x000000A1
> +gBoardModuleTokenSpaceGuid.PcdPcieClock4|0|UINT64|0x000000A2
> +gBoardModuleTokenSpaceGuid.PcdPcieClock5|0|UINT64|0x000000A3
> +gBoardModuleTokenSpaceGuid.PcdPcieClock6|0|UINT64|0x000000A4
> +gBoardModuleTokenSpaceGuid.PcdPcieClock7|0|UINT64|0x000000A5
> +gBoardModuleTokenSpaceGuid.PcdPcieClock8|0|UINT64|0x000000A6
> +gBoardModuleTokenSpaceGuid.PcdPcieClock9|0|UINT64|0x000000A7
> +gBoardModuleTokenSpaceGuid.PcdPcieClock10|0|UINT64|0x000000A8
> +gBoardModuleTokenSpaceGuid.PcdPcieClock11|0|UINT64|0x000000A9
> +gBoardModuleTokenSpaceGuid.PcdPcieClock12|0|UINT64|0x000000AA
> +gBoardModuleTokenSpaceGuid.PcdPcieClock13|0|UINT64|0x000000AB
> +gBoardModuleTokenSpaceGuid.PcdPcieClock14|0|UINT64|0x000000AC
> +gBoardModuleTokenSpaceGuid.PcdPcieClock15|0|UINT64|0x000000AD
> +
> +# GPIO Group Tier
> +gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0|0|UINT32|0x000
> 000E9
> +gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1|0|UINT32|0x000
> 000EA
> +gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2|0|UINT32|0x000
> 000EB
> +
> +# Board related PCH PmConfig
> +gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl|FALSE|BOOLEA
> N|0x000000F6
> +gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport|FALSE|BOOLEAN|
> 0x000000F7
> +gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport|FALSE|BOOLEAN|
> 0x000000F8
> +
> +# Misc
> +gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent|FALSE|BOOLEAN|
> 0x000000ED
> +gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable|FALSE|BOOLEAN|0
> x000000EE
> +gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent|FALSE|BOOLEAN|0x00
> 0000EF
> +gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio|0|UINT64|0x00000
> 0F0
> +gBoardModuleTokenSpaceGuid.PcdMobileDramPresent|FALSE|BOOLEAN|0
> x000000F1
> +gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable|FALSE|BOOLEAN|0x0
> 00000F2
> +gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable|FALSE|BOOLEAN
> |0x000000F9
> +#gBoardModuleTokenSpaceGuid.PcdxxxNotInUse|FALSE|BOOLEAN|0x0000
> 00FC
> +
> +#PlatformInfoPcd
> +gBoardModuleTokenSpaceGuid.PcdEnableVoltageMargining|FALSE|BOOLEA
> N|0x00101000
> +gBoardModuleTokenSpaceGuid.PcdGfxCrbDetect|FALSE|BOOLEAN|0x00101
> 001
> +gBoardModuleTokenSpaceGuid.PcdHsioBoardPresent|FALSE|BOOLEAN|0x0
> 0101002
> +gBoardModuleTokenSpaceGuid.PcdHsioBoardType|0x0|UINT8|0x00101003
> +gBoardModuleTokenSpaceGuid.PcdWakeupType|0x0|UINT8|0x00101004
> +gBoardModuleTokenSpaceGuid.PcdMfgMode|FALSE|BOOLEAN|0x00101005
> +gBoardModuleTokenSpaceGuid.PcdBoardName|L"0123456789ABCDEF0123
> 456789ABCDEF"|VOID*|0x00101007
> +gBoardModuleTokenSpaceGuid.PcdEcMajorRevision|0x0|UINT8|0x0010100
> 8
> +gBoardModuleTokenSpaceGuid.PcdEcMinorRevision|0x0|UINT8|0x0010100
> 9
> +gBoardModuleTokenSpaceGuid.PcdBiosVersion|L"012345678901234567890
> 1234567890123456789"|VOID*|0x0010100E
> +gBoardModuleTokenSpaceGuid.PcdReleaseDate|L"01234567890123456789"
> |VOID*|0x0010100F
> +gBoardModuleTokenSpaceGuid.PcdReleaseTime|L"01234567890123456789
> "|VOID*|0x00101010
> +gBoardModuleTokenSpaceGuid.PcdPlatformGeneration|0x0|UINT8|0x0010
> 1011
> +gBoardModuleTokenSpaceGuid.PcdSpdPresent|FALSE|BOOLEAN|0x0010101
> 2
> +gBoardModuleTokenSpaceGuid.PcdDockAttached|FALSE|BOOLEAN|0x0010
> 1013
> +gBoardModuleTokenSpaceGuid.PcdPlatformType|0x0|UINT8|0x00101014
> +gBoardModuleTokenSpaceGuid.PcdPlatformFlavor|0x0|UINT8|0x00101015
> +gBoardModuleTokenSpaceGuid.PcdBoardRev|0x0|UINT8|0x00101016
> +gBoardModuleTokenSpaceGuid.PcdBoardBomId|0x0|UINT8|0x00101017
> +gBoardModuleTokenSpaceGuid.PcdBoardId|0x0|UINT8|0x00101018
> +gBoardModuleTokenSpaceGuid.PcdBoardType|0x0|UINT8|0x00101019
> +gBoardModuleTokenSpaceGuid.PcdEcPresent|FALSE|BOOLEAN|0x0010101A
> +
> +# PCH Misc Configuration
> +gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable|FALSE|BOOLEAN|
> 0x00000061
> +gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable|FALSE|BOOLEAN|0
> x00000065
> +gBoardModuleTokenSpaceGuid.PcdSmbiosFabBoardName|0|UINT64|0x000
> 00102
> +gBoardModuleTokenSpaceGuid.PcdSmbiosMainSlotEntry|0|UINT64|0x0000
> 0103
> +gBoardModuleTokenSpaceGuid.PcdUsbcEcPdNegotiation|FALSE|BOOLEAN|
> 0x00000110
> +
> +# Control PCD to dump default silicon policy
> +gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy|FALSE|BOO
> LEAN|0x00010064
> +
> +# Pch SerialIo I2c Pads Termination
> +gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm|0x1|UI
> NT8|0x00000020
> +gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm|0x1|UI
> NT8|0x00000021
> +gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm|0x1|UI
> NT8|0x00000022
> +gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm|0x1|UI
> NT8|0x00000023
> +gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm|0x1|UI
> NT8|0x00000030
> +gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm|0x1|UI
> NT8|0x00000031
> +#
> +# The PCD which holds the pointer of Smbios Platform Info table
> +#
> +gBoardModuleTokenSpaceGuid.PcdSmbiosPlatformInfo|0|UINT64|0x00101
> 01B
> +#
> +# The PCD which used to enable / disable the code to use RVP Smbios Board
> Info
> +#
> +gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfoEnable|FALSE|BOOLEA
> N|0x0010101C
> +#
> +# The PCD which holds the pointer of RVP Smbios Board Info
> +#
> +gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfo|0|UINT64|0x0010101
> D
> +#
> +# CoEngineering Custom Defaults PCD
> +#
> +gBoardModuleTokenSpaceGuid.PcdCoEngEnableCustomDefaults|0x0|UINT
> 8|0x00100227
> +#
> +# The PCD which is defined to enable/disable the SMBus Alert function.
> +#
> +gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable|FALSE|BOOLEAN|0x0
> 010101E
> +#
> +# The PCD which is defined to enable/disable the SATA LED function.
> +#
> +gBoardModuleTokenSpaceGuid.PcdSataLedEnable|FALSE|BOOLEAN|0x0010
> 101F
> +#
> +# The PCD which is defined to enable/disable the VR Alert function.
> +#
> +gBoardModuleTokenSpaceGuid.PcdVrAlertEnable|FALSE|BOOLEAN|0x0010
> 1020
> +#
> +# The PCD which is defined to enable/disable the PCH thermal hot threshold
> function.
> +#
> +gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable|FALSE|BOOLEAN
> |0x00101021
> +#
> +# The PCD which is defined to enable/disable the memory thermal sensor
> GPIO C/D function.
> +#
> +gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEn
> able|TRUE|BOOLEAN|0x00101022
> +gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEn
> able|TRUE|BOOLEAN|0x00101023
> +#
> +# The PCD defines the I2C bus number to which PSS chip connected.
> +#
> +gBoardModuleTokenSpaceGuid.PcdPssReadSN|FALSE|BOOLEAN|0x0010102
> 4
> +gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber|0x04|UINT8|0x00101
> 025
> +gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress|0x6E|UINT8|0x0010
> 1026
> +#
> +# The PCD defines the USB port number to which BLE connected.
> +#
> +gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber
> |0x0|UINT8|0x00101028
> +gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support
> |0x00|UINT8|0x00100113
> +gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support
> |0x00|UINT8|0x00100114
> +gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support
> |0x00|UINT8|0x00100115
> +gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support
> |0x00|UINT8|0x00100116
> +gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support
> |0x00|UINT8|0x00100117
> +gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support
> |0x00|UINT8|0x00100118
> +gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
> |FALSE|BOOLEAN|0x00100119
> +gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
> |FALSE|BOOLEAN|0x0010011A
> +gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
> |FALSE|BOOLEAN|0x0010011B
> +gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
> |FALSE|BOOLEAN|0x0010011C
> +gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport
> |FALSE|BOOLEAN|0x0010011D
> +gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport
> |FALSE|BOOLEAN|0x0010011F
> +gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin
> |0x00|UINT32|0x00100120
> +gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
> |FALSE|BOOLEAN|0x00100121
> +gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
> |FALSE|BOOLEAN|0x00100122
> +gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature
> |FALSE|BOOLEAN|0x00100123
> +gBoardModuleTokenSpaceGuid.PcdBatteryPresent
> |0x0|UINT8|0x00100124
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport|FALSE|BOOLEAN|0x0
> 0100212
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess|FALSE|BOOLEAN|0x001
> 00213
> +gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature|0x0|UINT64|0x
> 00100204
> +gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile|0x0|UINT8|0x00100
> 205
> +gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio|0x0|UINT32|0x00
> 100209
> +gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio|0x0|UINT32|0x0010
> 020A
> +gBoardModuleTokenSpaceGuid.PcdGnssResetGpio|0x0|UINT32|0x0010020
> B
> +gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio|0x0|UINT32|0x00100
> 20F
> +gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio|0x0|UINT32|0x0010
> 0210
> +
> +gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
> |0x0|UINT32|0x00100126
> +gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
> |0x0|UINT8|0x00100127
> +gBoardModuleTokenSpaceGuid.PcdEcSmiGpio|0x0|UINT32|0x00100200
> +gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio
> |0x0|UINT32|0x00100125
> +gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad|0x0|UINT32|0x00100201
> +gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck|FALSE|BOOLEA
> N|0x00100202
> +gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride|FALSE|BOOLEAN|0
> x00100203
> +gBoardModuleTokenSpaceGuid.PcdDDISelection|0x0|UINT8|0x00100215
> +gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio|0x0|UINT64|0x00100
> 217
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1|0x00|UINT8|0x0010003
> 9
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch|0x00|UINT8|0x0010
> 003A
> +gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties|0x00|UINT8|0x001
> 0003B
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2|0x00|UINT8|0x0010003
> C
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch|0x00|UINT8|0x0010
> 003D
> +gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties|0x00|UINT8|0x001
> 0003E
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3|0x00|UINT8|0x0010003
> F
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch|0x00|UINT8|0x0010
> 0040
> +gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties|0x00|UINT8|0x001
> 00041
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4|0x00|UINT8|0x0010004
> 2
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch|0x00|UINT8|0x0010
> 0043
> +gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties|0x00|UINT8|0x001
> 00044
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5|0x00|UINT8|0x0010004
> 5
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch|0x00|UINT8|0x0010
> 0046
> +gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties|0x00|UINT8|0x001
> 00047
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6|0x00|UINT8|0x0010004
> 8
> +gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch|0x00|UINT8|0x0010
> 0049
> +gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties|0x00|UINT8|0x001
> 0004A
> +gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed
> |0x0|UINT8|0x00100128
> +gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed
> |0x0|UINT8|0x00100129
> +gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed
> |0x0|UINT8|0x0010012A
> +gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed
> |0x0|UINT8|0x0010012B
> +
> +# Super IO Pcd
> +gPlatformModuleTokenSpaceGuid.PcdH8S2113Present|TRUE|BOOLEAN|0xF
> 0000100
> +gPlatformModuleTokenSpaceGuid.PcdNat87393Present|TRUE|BOOLEAN|0x
> F0000104
> +gPlatformModuleTokenSpaceGuid.PcdNct677FPresent|TRUE|BOOLEAN|0xF
> 0000105
> +gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport
> |FALSE|BOOLEAN|0x00100112
> +gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin
> |0x00|UINT32|0x00100111
> +gBoardModuleTokenSpaceGuid.PcdRealBattery1Control
> |0x00|UINT8|0x00100103
> +gBoardModuleTokenSpaceGuid.PcdRealBattery2Control
> |0x00|UINT8|0x00100104
> +
> +gBoardModuleTokenSpaceGuid.PcdDimmPopulationError|FALSE|BOOLEAN|
> 0x00100221
> +gBoardModuleTokenSpaceGuid.PcdBtIrqGpio|0x0|UINT32|0x0010020E
> +gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio|0x0|UINT32|0x0010020D
> +gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable|FALSE|BOOLEA
> N|0x0010022C
> +gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported|0x00|UINT8|0x00
> 10004B
> +gBoardModuleTokenSpaceGuid.PcdMipiCamSensor
> |FALSE|BOOLEAN|0x00100105
> +gBoardModuleTokenSpaceGuid.PcdH8S2113SIO
> |FALSE|BOOLEAN|0x0010010A
> +gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM
> |FALSE|BOOLEAN|0x00100107
> +gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO
> |FALSE|BOOLEAN|0x00100108
> +gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON
> |FALSE|BOOLEAN|0x00100109
> +
> +[PcdsDynamicEx]
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +
> +[PcdsPatchableInModule]
> +
> +[PcdsFeatureFlag]
> +gBoardModuleTokenSpaceGuid.PcdIntelGopEnable
> |TRUE|BOOLEAN|0xF0000062
> +gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport
> |TRUE|BOOLEAN|0xF0000000
> +gBoardModuleTokenSpaceGuid.PcdTbtEnable
> |FALSE|BOOLEAN|0x000000115
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeCheckIommuSupportLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeCheckIommuSupportLib.h
> new file mode 100644
> index 0000000000..4aae18cac4
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeCheckIommuSupportLib.h
> @@ -0,0 +1,43 @@
> +/** @file
> +  Header file for the DxeCheckIommuSupport library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
> +#define _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
> +
> +/**
> +  Detect ME FW and Board Type and return the result via IommuSkuCheck.
> +
> +  IommuSkuCheck
> +  BIT0: Indicate system has a Corporate CSME firmware
> +  BIT1: Indicate BIOS is running on a WHL RVP
> +  BIT2: Indicate BIOS is running on a CFL-H RVP
> +  BIT3: Indicate BIOS is running on a CFL-S 8+2 RVP
> +
> +  @retval Return 0 means not support, otherwise value is defined by
> IommuSkuCheck
> +**/
> +UINT8
> +DetectMeAndBoard (
> +  VOID
> +  );
> +
> +/**
> +  DxeCheckIommuSupport
> +
> +  Only WHL/CFL-H/CFL-S 8+2 Crop SKUs support Iommu.
> +  This function will save sku information to PcdIommuSkuCheck.
> +  BIOS will use PcdIommuSkuCheck and other factors to set
> PcdVTdPolicyPropertyMask on the next boot in PEI phase
> +
> +  This function might perform a system reset.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DxeCheckIommuSupport (
> +  VOID
> +  );
> +#endif // _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeTbtPolicyLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeTbtPolicyLib.h
> new file mode 100644
> index 0000000000..167cc8af83
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeTbtPolicyLib.h
> @@ -0,0 +1,49 @@
> +/** @file
> +  Prototype of the DxeTbtPolicyLib library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_TBT_POLICY_LIB_H_
> +#define _DXE_TBT_POLICY_LIB_H_
> +
> +
> +/**
> +  Install TBT Policy.
> +
> +  @param[in] ImageHandle                Image handle of this driver.
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallTbtPolicy (
> +  IN  EFI_HANDLE                    ImageHandle
> +  );
> +
> +/**
> +  Update Tbt Policy Callback.
> +
> +  @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
> +UpdateTbtPolicyCallback (
> +  VOID
> +  );
> +
> +/**
> +  Print DXE TBT Policy
> +**/
> +VOID
> +TbtPrintDxePolicyConfig (
> +  VOID
> +  );
> +#endif // _DXE_TBT_POLICY_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeTbtSecurityLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeTbtSecurityLib.h
> new file mode 100644
> index 0000000000..17337ceb0b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/D
> xeTbtSecurityLib.h
> @@ -0,0 +1,131 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_SECURITY_LIB_H_
> +#define _TBT_SECURITY_LIB_H_
> +
> +#include <Protocol/Tcg2Protocol.h>
> +#include <Protocol/AcpiTable.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/AslUpdateLib.h>
> +#include <Library/UefiLib.h>
> +#include <Uefi.h>
> +#include <SetupVariable.h>
> +#include <OemSetup.h>
> +#include <DmaRemappingTable.h>
> +#include <PcieRegs.h>
> +#include <Tcg2ConfigNvData.h>
> +#include <TbtPolicyCommonDefinition.h>
> +#include <Library/TbtCommonLib.h>
> +
> +#define TBT_SECURITY_EVENT_STRING                 "DMA Protection
> Disabled"
> +#define TBT_SECURITY_EVENT_STRING_LEN             (sizeof
> (TBT_SECURITY_EVENT_STRING) - 1)
> +
> +#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING      "Security Level is
> Downgraded to 0"
> +#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING_LEN  (sizeof
> (TBT_SECURITY_LEVEL_DOWNGRADED_STRING) - 1)
> +
> +#define GET_TBT_SECURITY_MODE    0
> +#define SET_TBT_SECURITY_MODE    1
> +
> +typedef struct {
> +  UINT8       EnableVtd;
> +  BOOLEAN     SLDowngrade;
> +} PCR7_DATA;
> +
> +/**
> +  TBT Security ExtendPCR7 CallBackFunction
> +  If the firmware/BIOS has an option to enable and disable DMA protections
> via a VT-d switch in BIOS options, then the shipping configuration must be with
> VT-d protection enabled.
> +  On every boot where VT-d/DMA protection is disabled, or will be disabled,
> or configured to a lower security state, and a platform has a TPM enabled, then
> the platform SHALL extend an EV_EFI_ACTION event into PCR[7] before
> enabling external DMA.
> +  The event string SHALL be "DMA Protection Disabled". The platform
> firmware MUST log this measurement in the event log using the string "DMA
> Protection Disabled" for the Event Data.
> +  Measure and log launch of TBT Security, and extend the measurement result
> into a specific PCR.
> +  Extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA.
> The event string SHALL be "DMA Protection Disabled". The platform firmware
> MUST log this measurement in the event log using the string "DMA Protection
> Disabled" for the Event Data.
> +
> +  @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
> +ExtendPCR7CallBackFunction (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  );
> +
> +/**
> +  TBT Security DisableBme CallBackFunction
> +
> +  BIOS will disable BME and tear down the Thunderbolt DMAR tables at
> ExitBootServices
> +  in order to hand off security of TBT hierarchies to the OS.
> +  The BIOS is expected to either: Disable BME from power on till the OS starts
> configuring the devices and enabling BME Enable BME only for devices that can
> be protected by VT-d in preboot environment,
> +  but disable BME and tear down any Thunderbolt DMAR tables at
> ExitBootServices()
> +
> +  @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
> +TbtDisableBmeCallBackFunction (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  );
> +
> +/**
> +  TBT Security SetDmarOptIn CallBackFunction
> +
> +  A new security feature will be supported to protect against Physical DMA
> attacks over Thunderbolt connects.
> +  In order to do this, they need a new flag added to the DMAR tables that a
> DMA is only permitted into RMRR at ExitBootServices().  With this flag
> available, OS can then Bug Check if any DMA is requested outside of the RMRR
> before OS supported device drivers are started.
> +  ReadyToBoot callback routine to update DMAR BIT2
> +  Bit definition: DMA_CONTROL_GUARANTEE
> +  If Set, the platform supports blocking all DMA outside of the regions defined
> in the RMRR structures from ExitBootServices() until OS supported device
> drivers are started.
> +
> +  @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
> +SetDmarOptInCallBackFunction (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  );
> +
> +
> +/**
> +  The function install DisableBme protocol for TBT Shell validation
> +**/
> +VOID
> +InstallDisableBmeProtocol (
> +  VOID
> +  );
> +
> +/**
> +  Get or set Thunderbolt(TM) security mode
> +
> +  @param[in]  DelayTime           - The delay time after do ForcePwr
> +  @param[in]  SecurityMode        - TBT Security Level
> +  @param[in]  Gpio3ForcePwrEn     - Force GPIO to power on or not
> +  @param[in]  DTbtController      - Enable/Disable DTbtController
> +  @param[in]  MaxControllerNumber - Number of contorller
> +  @param[in]  Action              - 0 = get, 1 = set
> +
> +  @retval                         - Return security level
> +**/
> +UINT8
> +EFIAPI
> +GetSetSecurityMode (
> +  IN UINTN                       DelayTime,
> +  IN UINT8                       SecurityMode,
> +  IN UINT8                       Gpio3ForcePwrEn,
> +  IN UINT8                       *DTbtController,
> +  IN UINT8                       MaxControllerNumber,
> +  IN UINT8                       Action
> +);
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiCheckIommuSupportLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiCheckIommuSupportLib.h
> new file mode 100644
> index 0000000000..9afb36f011
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiCheckIommuSupportLib.h
> @@ -0,0 +1,21 @@
> +/** @file
> +  Header file for the PeiCheckIommuSupport library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
> +#define _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
> +
> +/**
> +  Check Iommu Ability base on SKU type, CSME FW type, Vtd and setup
> options.
> +**/
> +VOID
> +PeiCheckIommuSupport (
> +  VOID
> +  );
> +
> +#endif // _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiTbtPolicyLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiTbtPolicyLib.h
> new file mode 100644
> index 0000000000..45bd8f38ed
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiTbtPolicyLib.h
> @@ -0,0 +1,43 @@
> +/** @file
> +  Prototype of the PeiTbtPolicyLib library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_TBT_POLICY_LIB_H_
> +#define _PEI_TBT_POLICY_LIB_H_
> +
> +/**
> +  Install Tbt Policy
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallPeiTbtPolicy (
> +  VOID
> +  );
> +
> +/**
> +  Update PEI TBT Policy Callback
> +**/
> +VOID
> +EFIAPI
> +UpdatePeiTbtPolicyCallback (
> +  VOID
> +  );
> +
> +/**
> +  Print PEI TBT Policy
> +**/
> +VOID
> +EFIAPI
> +TbtPrintPeiPolicyConfig (
> +  VOID
> +  );
> +#endif // _DXE_TBT_POLICY_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiTbtTaskDispatchLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiTbtTaskDispatchLib.h
> new file mode 100644
> index 0000000000..44ae01a3f7
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/P
> eiTbtTaskDispatchLib.h
> @@ -0,0 +1,61 @@
> +/** @file
> +  PEI TBT Task Dispatch library Header file
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __PEI_TBT_TASK_DISPATCH_LIB_H__
> +#define __PEI_TBT_TASK_DISPATCH_LIB_H__
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/GpioLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Ppi/PeiTbtPolicy.h>
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *TBT_TASK) (
> +  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +typedef enum {
> +  TBT_NULL,                ///< All policy flags turned off.
> +  TBT_NORMAL   = (1 << 0), ///< Execute TBT function on cold reset.
> +  TBT_S3       = (1 << 1), ///< Execute TBT function on S3 exit.
> +  TBT_S4       = (1 << 2), ///< Execute TBT function on S4 exit.
> +  TBT_ALL      = MAX_UINTN ///< Execute TBT function always.
> +} TBT_BOOT_MODE;
> +
> +typedef struct {
> +  TBT_TASK      TbtTask;         ///< Ptr to function to execute, with parameter
> list.
> +  TBT_BOOT_MODE TbtBootModeFlag; ///< Call table base on
> TbtBootModeFlag
> +  CHAR8         *String;         ///< Output string describing this task.
> +} TBT_CALL_TABLE_ENTRY;
> +
> +/**
> +  Covert the current EFI_BOOT_MODE to TBT_BOOT_MODE
> +**/
> +TBT_BOOT_MODE
> +TbtGetBootMode (
> +  VOID
> +);
> +
> +/**
> +  TbtTaskDistpach: Dispatch the TBT tasks according to
> TBT_CALL_TABLE_ENTRY
> +
> +  @param[in] TBT_CALL_TABLE_ENTRY   TbtCallTable
> +
> +**/
> +VOID
> +TbtTaskDistpach (
> +  IN TBT_CALL_TABLE_ENTRY *TbtCallTable
> +);
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/T
> btCommonLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/T
> btCommonLib.h
> new file mode 100644
> index 0000000000..3e9e7c4b76
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/T
> btCommonLib.h
> @@ -0,0 +1,261 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_COMMON_LIB_H_
> +#define _TBT_COMMON_LIB_H_
> +
> +#include <Library/BaseLib.h>
> +#include <Library/PciSegmentLib.h>
> +
> +#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_RP     0 // @todo : Update
> when once finalized
> +#define DEFAULT_PCI_BUS_NUMBER_ITBT_RP         0
> +#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_RP      0x07
> +
> +#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_DMA0   0
> +#define DEFAULT_PCI_BUS_NUMBER_ITBT_DMA0       0
> +#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_DMA0    0x0D
> +#define DEFAULT_PCI_FUNCTION_NUMBER_ITBT_DMA0  0x02
> +
> +#define DTBT_CONTROLLER                   0x00
> +#define DTBT_TYPE_PCH                     0x01
> +#define DTBT_TYPE_PEG                     0x02
> +#define ITBT_CONTROLLER                   0x80
> +#define TBT2PCIE_ITBT_R                   0xEC
> +#define PCIE2TBT_ITBT_R                   0xF0
> +#define TBT2PCIE_DTBT_R                   0x548
> +#define PCIE2TBT_DTBT_R                   0x54C
> +
> +#define INVALID_RP_CONTROLLER_TYPE        0xFF
> +
> +//
> +//  Thunderbolt FW OS capability
> +//
> +#define NO_OS_NATIVE_SUPPORT    0
> +#define OS_NATIVE_SUPPORT_ONLY  1
> +#define OS_NATIVE_SUPPORT_RTD3  2
> +
> +#define ITBT_SAVE_STATE_OFFSET  BIT4 // Bits 4-7 is for ITBT
> (HIA0/1/2/Reserved)
> +#define DTBT_SAVE_STATE_OFFSET  BIT0 // Bits 0-3 is for DTBT (only bit 0 is in
> use)
> +/**
> +Get Tbt2Pcie Register Offset
> +
> +@param[in]  Type      ITBT (0x80) or DTBT (0x00)
> +@retval     Register  Register Variable
> +**/
> +
> +#define GET_TBT2PCIE_REGISTER_ADDRESS(Type, Segment, Bus, Device,
> Function, RegisterAddress) \
> +  if (Type == ITBT_CONTROLLER) { \
> +    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device,
> Function, TBT2PCIE_ITBT_R); \
> +  } else { \
> +    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device,
> Function, TBT2PCIE_DTBT_R); \
> +  }
> +
> +/**
> +Get Pcie2Tbt Register Offset
> +
> +@param[in]  Type      ITBT (0x80) or DTBT (0x00)
> +@retval     Register  Register Variable
> +**/
> +
> +#define GET_PCIE2TBT_REGISTER_ADDRESS(Type, Segment, Bus, Device,
> Function, RegisterAddress) \
> +  if (Type == ITBT_CONTROLLER) { \
> +    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device,
> Function, PCIE2TBT_ITBT_R); \
> +  } else { \
> +    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device,
> Function, PCIE2TBT_DTBT_R); \
> +  }
> +
> +#define PCIE2TBT_VLD_B                    BIT0
> +#define TBT2PCIE_DON_R                    BIT0
> +#define TBT_MAIL_BOX_DELAY                (100*1000)
> +#define TBT_5S_TIMEOUT                    50
> +#define TBT_1S_TIMEOUT                    10
> +#define TBT_3S_TIMEOUT                    30
> +
> +#define PCIE2TBT_GO2SX                    (0x02 << 1)
> +#define PCIE2TBT_GO2SX_NO_WAKE            (0x03 << 1)
> +#define PCIE2TBT_SX_EXIT_TBT_CONNECTED    (0x04 << 1)
> +#define PCIE2TBT_SX_EXIT_NO_TBT_CONNECTED (0x05 << 1)
> +#define PCIE2TBT_OS_UP                    (0x06 << 1)
> +#define PCIE2TBT_SET_SECURITY_LEVEL       (0x08 << 1)
> +#define PCIE2TBT_GET_SECURITY_LEVEL       (0x09 << 1)
> +#define PCIE2TBT_CM_AUTH_MODE_ENTER       (0x10 << 1)
> +#define PCIE2TBT_CM_AUTH_MODE_EXIT        (0x11 << 1)
> +#define PCIE2TBT_BOOT_ON                  (0x18 << 1)
> +#define PCIE2TBT_BOOT_OFF                 (0x19 << 1)
> +#define PCIE2TBT_USB_ON                   (0x19 << 1)
> +#define PCIE2TBT_GET_ENUMERATION_METHOD   (0x1A << 1)
> +#define PCIE2TBT_SET_ENUMERATION_METHOD   (0x1B << 1)
> +#define PCIE2TBT_POWER_CYCLE              (0x1C << 1)
> +#define PCIE2TBT_PREBOOTACL               (0x1E << 1)
> +#define CONNECT_TOPOLOGY_COMMAND          (0x1F << 1)
> +
> +#define RESET_HR_BIT                      BIT0
> +#define ENUMERATE_HR_BIT                  BIT1
> +#ifndef AUTO
> +#define AUTO                              0x0
> +#endif
> +
> +//
> +//Thunder Bolt Device IDs
> +//
> +
> +//
> +// Alpine Ridge HR device IDs
> +//
> +#define AR_HR_2C  0x1576
> +#define AR_HR_4C  0x1578
> +#define AR_XHC    0x15B5
> +#define AR_XHC_4C 0x15B6
> +#define AR_HR_LP  0x15C0
> +//
> +// Alpine Ridge C0 HR device IDs
> +//
> +#define AR_HR_C0_2C  0x15DA
> +#define AR_HR_C0_4C  0x15D3
> +//
> +// Titan Ridge HR device IDs
> +//
> +#define TR_HR_2C  0x15E7
> +#define TR_HR_4C  0x15EA
> +//
> +//End of Thunderbolt(TM) Device IDs
> +//
> +
> +typedef struct _DEV_ID {
> +  UINT8 Segment;
> +  UINT8 Bus;
> +  UINT8 Dev;
> +  UINT8 Fun;
> +} DEV_ID;
> +
> +//@todo Seems to only be used by Platform/TBT/Smm/TbtSmm.inf
> +//@todo should refactor this to only be present in that driver
> +//@todo also definitions like this should never be in a .h file anyway
> +//@todo this is a quick hack to get things compiling for now
> +#ifdef __GNUC__
> +#pragma GCC diagnostic warning "-Wunused-variable"
> +#endif
> +
> +/**
> +Based on the Security Mode Selection, BIOS drives FORCE_PWR.
> +
> +@param[in]  GpioNumber
> +@param[in]  Value
> +**/
> +VOID
> +ForceDtbtPower(
> +  IN  UINT32         GpioNumber,
> +  IN  BOOLEAN        Value
> +);
> +
> +/**
> +  Get Security Level.
> +  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
> +  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
> +  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
> +  @param[in]  Function  Function number for HIA (ITBT) or Host Router
> (DTBT)
> +  @param[in]  Timeout   Time out with 100 ms garnularity
> +**/
> +UINT8
> +GetSecLevel (
> +  IN    BOOLEAN                 Type,
> +  IN    UINT8                   Bus,
> +  IN    UINT8                   Device,
> +  IN    UINT8                   Function,
> +  IN    UINT8                   Command,
> +  IN    UINT32                  Timeout
> +  );
> +
> +/**
> +  Set Security Level.
> +  @param[in]  Data      Security State
> +  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
> +  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
> +  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
> +  @param[in]  Function  Function number for HIA (ITBT) or Host Router
> (DTBT)
> +  @param[in]  Timeout   Time out with 100 ms garnularity
> +**/
> +BOOLEAN
> +SetSecLevel (
> +  IN    UINT8                   Data,
> +  IN    BOOLEAN                 Type,
> +  IN    UINT8                   Bus,
> +  IN    UINT8                   Device,
> +  IN    UINT8                   Function,
> +  IN    UINT8                   Command,
> +  IN    UINT32                  Timeout
> +  );
> +
> +/**
> +Execute TBT Mail Box Command
> +
> +@param[in]  Command   TBT Command
> +@param[in]  Type      ITBT (0x80) or DTBT (0x00)
> +@param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
> +@param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
> +@param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
> +@param[in]  Timeout   Time out with 100 ms garnularity
> +@Retval     true      if command executes succesfully
> +**/
> +BOOLEAN
> +TbtSetPcie2TbtCommand(
> +  IN    UINT8                   Command,
> +  IN    BOOLEAN                 Type,
> +  IN    UINT8                   Bus,
> +  IN    UINT8                   Device,
> +  IN    UINT8                   Function,
> +  IN    UINT32                  Timeout
> +);
> +/**
> +  Check connected TBT controller is supported or not by DeviceID
> +
> +  @param[in]  DeviceID              DeviceID of of TBT controller
> +
> +
> +  @retval     TRUE                  Valid DeviceID
> +  @retval     FALSE                 Invalid DeviceID
> +**/
> +
> +BOOLEAN
> +IsTbtHostRouter (
> +  IN    UINT16  DeviceID
> +  );
> +
> +/**
> +  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDTbtRpDevFun(
> +  IN  BOOLEAN Type,
> +  IN  UINTN   RpNumber,
> +  OUT UINTN   *RpDev,
> +  OUT UINTN   *RpFunc
> +  );
> +
> +/**
> +  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
> +  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
> +  @param[in]  TimeOut                   Time out with 100 ms garnularity
> +  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to
> Clear/Set)
> +  @param[out] *Tbt2PcieValue Function   Register value
> +**/
> +BOOLEAN
> +InternalWaitforCommandCompletion (
> +  IN  UINT64   CommandOffsetAddress,
> +  IN  UINT32   TimeOut,
> +  IN  BOOLEAN  Tbt2PcieDone,
> +  OUT UINT32   *Tbt2PcieValue
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiT
> btPolicy.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiT
> btPolicy.h
> new file mode 100644
> index 0000000000..17d8a62f66
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiT
> btPolicy.h
> @@ -0,0 +1,31 @@
> +/** @file
> +TBT PEI Policy
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_TBT_POLICY_H_
> +#define _PEI_TBT_POLICY_H_
> +
> +#include <TbtPolicyCommonDefinition.h>
> +
> +#pragma pack(push, 1)
> +
> +#define PEI_TBT_POLICY_REVISION 1
> +
> +/**
> + TBT PEI configuration\n
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +typedef struct _PEI_TBT_POLICY {
> +  DTBT_COMMON_CONFIG     DTbtCommonConfig;
> ///< dTbt Common Configuration
> +  DTBT_CONTROLLER_CONFIG DTbtControllerConfig
> [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
> +} PEI_TBT_POLICY;
> +
> +#pragma pack(pop)
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/L
> ibrary/PeiDTbtInitLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/L
> ibrary/PeiDTbtInitLib.h
> new file mode 100644
> index 0000000000..bb30c2c0ec
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/L
> ibrary/PeiDTbtInitLib.h
> @@ -0,0 +1,130 @@
> +/** @file
> +  PEI DTBT Init Dispatch library Header file
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __PEI_DTBT_INIT_LIB_H__
> +#define __PEI_DTBT_INIT_LIB_H__
> +
> +#include <Private/Library/PeiTbtCommonInitLib.h>
> +#include <Library/PeiTbtTaskDispatchLib.h>
> +
> +extern TBT_CALL_TABLE_ENTRY DTbtCallTable[];
> +
> +/**
> +  Get Thunderbolt(TM) (TBT) PEI Policy Data.
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtGetPeiTbtPolicyData (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  Toggle related GPIO pin for DTBT.
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtToggleGPIO (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  set tPCH25 Timing to 10 ms for DTBT.
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtSetTPch25Timing (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  Do ForcePower for DTBT Controller
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtForcePower (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  Clear VGA Registers for DTBT.
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtClearVgaRegisters (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  Exectue Mail box command "Boot On".
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtBootOn (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  Exectue Mail box command "USB On".
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtUsbOn (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +/**
> +  Exectue Mail box command "Sx Exit".
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtSxExitFlow (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +);
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/L
> ibrary/PeiTbtCommonInitLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/L
> ibrary/PeiTbtCommonInitLib.h
> new file mode 100644
> index 0000000000..0ed13fd300
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/L
> ibrary/PeiTbtCommonInitLib.h
> @@ -0,0 +1,51 @@
> +/** @file
> +  PEI TBT Common Init Dispatch library Header file
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __PEI_TBT_COMMON_INIT_LIB_H__
> +#define __PEI_TBT_COMMON_INIT_LIB_H__
> +
> +#include <Library/PeiServicesLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiTbtTaskDispatchLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/GpioLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/TbtCommonLib.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/PmcLib.h>
> +#include <PlatformNvRamHookLib.h>
> +
> +BOOLEAN
> +IsHostRouterPresentBeforeSleep(
> +IN  UINT8        ControllerType,
> +IN  UINT8        Controller
> +);
> +
> +VOID
> +TbtSetSxMode(
> +IN    BOOLEAN                 Type,
> +IN    UINT8                   Bus,
> +IN    UINT8                   Device,
> +IN    UINT8                   Function,
> +IN    UINT8                   TbtBootOn
> +);
> +
> +VOID
> +TbtClearVgaRegisters(
> +IN    UINTN                   Segment,
> +IN    UINTN                   Bus,
> +IN    UINTN                   Device,
> +IN    UINTN                   Function
> +);
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/
> DisableBmeProtocol.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol
> /DisableBmeProtocol.h
> new file mode 100644
> index 0000000000..1948c252f0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol
> /DisableBmeProtocol.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  Definitions for DisableBmeProtocol
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DISABLE_TBT_BME_PROTOCOL_H_
> +#define _DISABLE_TBT_BME_PROTOCOL_H_
> +
> +typedef struct EFI_DISABLE_BME_PROTOCOL
> EFI_DISABLE_TBT_BME_PROTOCOL;
> +
> +/**
> +  This is for disable TBT BME bit under shell environment
> +
> +  @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.
> +**/
> +typedef
> +VOID
> +(EFIAPI *DISABLE_BUS_MASTER_ENABLE) (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  );
> +
> +
> +struct EFI_DISABLE_BME_PROTOCOL {
> +  DISABLE_BUS_MASTER_ENABLE DisableBme;
> +};
> +
> +extern EFI_GUID gDxeDisableTbtBmeProtocolGuid;
> +
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/
> DxeTbtPolicy.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol
> /DxeTbtPolicy.h
> new file mode 100644
> index 0000000000..437f6a8401
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol
> /DxeTbtPolicy.h
> @@ -0,0 +1,137 @@
> +/** @file
> +TBT DXE Policy
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_TBT_POLICY_H_
> +#define _DXE_TBT_POLICY_H_
> +
> +#include <TbtPolicyCommonDefinition.h>
> +
> +#pragma pack(push, 1)
> +
> +#define DXE_TBT_POLICY_REVISION 1
> +
> +//
> +// TBT Common Data Structure
> +//
> +typedef struct _TBT_COMMON_CONFIG{
> +  /**
> +    TBT Security Level
> +    <b>0: SL0 No Security</b>, 1: SL1 User Authorization, 2: SL2 Secure Connect,
> 3: SL3 Display Port and USB
> +  **/
> +  UINT32   SecurityMode      : 3;
> +  /**
> +    BIOS W/A for Hot plug of 12V USB devices cause electrical noise on PCH
> GPIOs
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   Gpio5Filter       : 1;
> +  /**
> +     WA for TR A0 OS_UP Command, it is only needed for TR A0 stepping
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TrA0OsupWa        : 1;
> +  /**
> +    Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtWakeupSupport  : 1;
> +  /**
> +    SMI TBT enumeration
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtHotSMI         : 1;
> +  /**
> +    Notify PCIe RP after Hot-Plug/Hot-Unplug occurred.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtHotNotify      : 1;
> +  /**
> +    CLK REQ for all the PCIe device in TBT daisy chain.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtSetClkReq      : 1;
> +  /**
> +    ASPM setting for all the PCIe device in TBT daisy chain.
> +    <b>0: Disabled</b>, 1: L0s, 2: L1, 3: L0sL1
> +  **/
> +  UINT32   TbtAspm           : 2;
> +  /**
> +    L1 SubState for for all the PCIe device in TBT daisy chain.
> +    <b>0: Disabled</b>, 1: L1.1, 2: L1.1 & L1.2
> +  **/
> +  UINT32   TbtL1SubStates    : 2;
> +  /**
> +    LTR for for all the PCIe device in TBT daisy chain.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtLtr            : 1;
> +  /**
> +    PTM for for all the PCIe device in TBT daisy chain.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtPtm            : 1;
> +  /**
> +    TBT Dynamic AC/DC L1.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtAcDcSwitch     : 1;
> +  /**
> +    TBT RTD3 Support.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   Rtd3Tbt           : 1;
> +  /**
> +    TBT ClkReq for RTD3 Flow.
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   Rtd3TbtClkReq     : 1;
> +  /**
> +    TBT Win10support for Tbt FW execution mode.
> +    <b>0: Disabled</b>, 1: Native, 2: Native + RTD3
> +  **/
> +  UINT32   Win10Support      : 2;
> +  /**
> +    TbtVtdBaseSecurity
> +    <b>0: Disabled</b>, 1: Enabled
> +  **/
> +  UINT32   TbtVtdBaseSecurity: 1;
> +  /**
> +    Control Iommu behavior in pre-boot
> +    <b>0: Disabled Iommu</b>, 1: Enable Iommu, Disable exception list, 2:
> Enable Iommu, Enable exception list
> +  **/
> +  UINT32   ControlIommu      : 3;
> +  UINT32   Rsvd0             : 8; ///< Reserved bits
> +  UINT16   Rtd3TbtClkReqDelay;
> +  UINT16   Rtd3TbtOffDelay;
> +} TBT_COMMON_CONFIG;
> +
> +//
> +// dTBT Resource Data Structure
> +//
> +typedef struct _DTBT_RESOURCE_CONFIG{
> +  UINT8  DTbtPcieExtraBusRsvd;     ///< Preserve Bus resource for PCIe RP
> that connect to dTBT Host Router
> +  UINT16 DTbtPcieMemRsvd;          ///< Preserve MEM resource for PCIe RP
> that connect to dTBT Host Router
> +  UINT8  DTbtPcieMemAddrRngMax;    ///< Alignment of Preserve MEM
> resource for PCIe RP that connect to dTBT Host Router
> +  UINT16 DTbtPciePMemRsvd;         ///< Preserve PMEM resource for PCIe RP
> that connect to dTBT Host Router
> +  UINT8  DTbtPciePMemAddrRngMax;   ///< Alignment of Preserve PMEM
> resource for PCIe RP that connect to dTBT Host Router
> +  UINT8  Reserved[1];      ///< Reserved for DWORD alignment
> +} DTBT_RESOURCE_CONFIG;
> +
> +/**
> + TBT DXE configuration\n
> +  <b>Revision 1</b>:
> +  - Initial version.
> +**/
> +typedef struct _DXE_TBT_POLICY_PROTOCOL {
> +  TBT_COMMON_CONFIG      TbtCommonConfig;
> ///< Tbt Common Information
> +  DTBT_RESOURCE_CONFIG
> DTbtResourceConfig[MAX_DTBT_CONTROLLER_NUMBER];   ///< dTbt
> Resource Configuration
> +} DXE_TBT_POLICY_PROTOCOL;
> +
> +#pragma pack(pop)
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/
> TbtNvsArea.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol
> /TbtNvsArea.h
> new file mode 100644
> index 0000000000..e6654b4094
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol
> /TbtNvsArea.h
> @@ -0,0 +1,50 @@
> +/** @file
> +  This file defines the TBT NVS Area Protocol.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_NVS_AREA_H_
> +#define _TBT_NVS_AREA_H_
> +
> +//
> +// Platform NVS Area definition
> +//
> +#include <TbtNvsAreaDef.h>
> +
> +//
> +// Includes
> +//
> +#define TBT_NVS_DEVICE_ENABLE 1
> +#define TBT_NVS_DEVICE_DISABLE 0
> +
> +//
> +// Forward reference for pure ANSI compatibility
> +//
> +typedef struct _TBT_NVS_AREA_PROTOCOL TBT_NVS_AREA_PROTOCOL;
> +
> +///
> +/// Extern the GUID for protocol users.
> +///
> +extern EFI_GUID gTbtNvsAreaProtocolGuid;
> +
> +/**
> + Making any TBT_NVS_AREA 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.\n
> +  <b>Revision 2</b>:   - Adding TBT NVS AREA Revision, Deprecated
> DTbtControllerEn0, DTbtControllerEn1.\n
> +**/
> +#define TBT_NVS_AREA_REVISION       2
> +
> +//
> +// Platform NVS Area Protocol
> +//
> +typedef struct _TBT_NVS_AREA_PROTOCOL {
> +  TBT_NVS_AREA     *Area;
> +} TBT_NVS_AREA_PROTOCOL;
> +
> +#endif // _TBT_NVS_AREA_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoard
> Info.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoar
> dInfo.h
> new file mode 100644
> index 0000000000..bd5e577fbe
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoar
> dInfo.h
> @@ -0,0 +1,23 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_INFO_GUID_H_
> +#define _TBT_INFO_GUID_H_
> +#include <TbtPolicyCommonDefinition.h>
> +
> +#pragma pack(1)
> +//
> +// TBT Info HOB
> +//
> +typedef struct _TBT_INFO_HOB {
> +  EFI_HOB_GUID_TYPE      EfiHobGuidType;
> +  DTBT_COMMON_CONFIG     DTbtCommonConfig;
> ///< dTbt Common Configuration
> +  DTBT_CONTROLLER_CONFIG DTbtControllerConfig
> [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
> +} TBT_INFO_HOB;
> +#pragma pack()
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAr
> eaDef.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAr
> eaDef.h
> new file mode 100644
> index 0000000000..21e17b4609
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAr
> eaDef.h
> @@ -0,0 +1,68 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  //
> +  // Define TBT NVS Area operation region.
> +  //
> +
> +#ifndef _TBT_NVS_AREA_DEF_H_
> +#define _TBT_NVS_AREA_DEF_H_
> +
> +#pragma pack (push,1)
> +typedef struct {
> +  UINT8    ThunderboltSmiFunction;                  ///< Offset 0
> Thunderbolt(TM) SMI Function Number
> +  UINT8    ThunderboltHotSmi;                       ///< Offset 1       SMI on Hot
> Plug for TBT devices
> +  UINT8    TbtWin10Support;                         ///< Offset 2
> TbtWin10Support
> +  UINT8    TbtGpioFilter;                           ///< Offset 3       Gpio filter to
> detect USB Hotplug event
> +  UINT8    ThunderboltHotNotify;                    ///< Offset 4       Notify on
> Hot Plug for TBT devices
> +  UINT8    TbtSelector;                             ///< Offset 5
> Thunderbolt(TM) Root port selector
> +  UINT8    WAKFinished;                             ///< Offset 6       WAK Finished
> +  UINT8    DiscreteTbtSupport;                      ///< Offset 7
> Thunderbolt(TM) support
> +  UINT8    TbtAcpiRemovalSupport;                   ///< Offset 8
> TbtAcpiRemovalSupport
> +  UINT32   TbtFrcPwrEn;                             ///< Offset 9       TbtFrcPwrEn
> +  UINT32   TbtFrcPwrGpioNo0;                        ///< Offset 13
> TbtFrcPwrGpioNo
> +  UINT8    TbtFrcPwrGpioLevel0;                     ///< Offset 17
> TbtFrcPwrGpioLevel
> +  UINT32   TbtCioPlugEventGpioNo0;                  ///< Offset 18
> TbtCioPlugEventGpioNo
> +  UINT32   TbtPcieRstGpioNo0;                       ///< Offset 22
> TbtPcieRstGpioNo
> +  UINT8    TbtPcieRstGpioLevel0;                    ///< Offset 26
> TbtPcieRstGpioLevel
> +  UINT8    CurrentDiscreteTbtRootPort;              ///< Offset 27      Current
> Port that has plug event
> +  UINT8    RootportSelected0;                       ///< Offset 28      Root port
> Selected by the User
> +  UINT8    RootportSelected0Type;                   ///< Offset 29      Root port
> Type
> +  UINT8    RootportSelected1;                       ///< Offset 30      Root port
> Selected by the User
> +  UINT8    RootportSelected1Type;                   ///< Offset 31      Root port
> Type
> +  UINT8    RootportEnabled0;                        ///< Offset 32      Root port
> Enabled by the User
> +  UINT8    RootportEnabled1;                        ///< Offset 33      Root port
> Enabled by the User
> +  UINT32   TbtFrcPwrGpioNo1;                        ///< Offset 34
> TbtFrcPwrGpioNo
> +  UINT8    TbtFrcPwrGpioLevel1;                     ///< Offset 38
> TbtFrcPwrGpioLevel
> +  UINT32   TbtCioPlugEventGpioNo1;                  ///< Offset 39
> TbtCioPlugEventGpioNo
> +  UINT32   TbtPcieRstGpioNo1;                       ///< Offset 43
> TbtPcieRstGpioNo
> +  UINT8    TbtPcieRstGpioLevel1;                    ///< Offset 47
> TbtPcieRstGpioLevel
> +  UINT8    TBtCommonGpioSupport;                    ///< Offset 48      Set if
> Single GPIO is used for Multi/Different Controller Hot plug support
> +  UINT8    CurrentDiscreteTbtRootPortType;          ///< Offset 49      Root
> Port type for which SCI Triggered
> +  UINT8    TrOsup;                                  ///< Offset 50      Titan Ridge
> Osup command
> +  UINT8    TbtAcDcSwitch;                           ///< Offset 51      TBT Dynamic
> AcDc L1
> +  UINT8    DTbtControllerEn0;                       ///< Offset 52
> DTbtController0 is enabled or not.  @deprecated since revision 2
> +  UINT8    DTbtControllerEn1;                       ///< Offset 53
> DTbtController1 is enabled or not.  @deprecated since revision 2
> +  UINT8    TbtAspm;                                 ///< Offset 54      ASPM setting
> for all the PCIe device in TBT daisy chain.
> +  UINT8    TbtL1SubStates;                          ///< Offset 55      L1 SubState
> for for all the PCIe device in TBT daisy chain.
> +  UINT8    TbtSetClkReq;                            ///< Offset 56      CLK REQ for
> all the PCIe device in TBT daisy chain.
> +  UINT8    TbtLtr;                                  ///< Offset 57      LTR for for all the
> PCIe device in TBT daisy chain.
> +  UINT8    TbtPtm;                                  ///< Offset 58      PTM for for all
> the PCIe device in TBT daisy chain.
> +  UINT8    TbtWakeupSupport;                        ///< Offset 59      Send
> Go2SxNoWake or GoSxWake according to TbtWakeupSupport
> +  UINT16   Rtd3TbtOffDelay;                         ///< Offset 60
> Rtd3TbtOffDelay TBT RTD3 Off Delay
> +  UINT8    TbtSxWakeSwitchLogicEnable;              ///< Offset 62
> TbtSxWakeSwitchLogicEnable Set True if TBT_WAKE_N will be routed to PCH
> WakeB at Sx entry point. HW logic is required.
> +  UINT8    Rtd3TbtSupport;                          ///< Offset 63      Enable Rtd3
> support for TBT. Corresponding to Rtd3Tbt in Setup.
> +  UINT8    Rtd3TbtClkReq;                           ///< Offset 64      Enable TBT
> RTD3 CLKREQ mask.
> +  UINT16   Rtd3TbtClkReqDelay;                      ///< Offset 65      TBT RTD3
> CLKREQ mask delay.
> +  //
> +  // Revision Field:
> +  //
> +  UINT8    TbtRevision;                             ///< Offset 67      Revison of
> TbtNvsArea
> +} TBT_NVS_AREA;
> +
> +#pragma pack(pop)
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicy
> CommonDefinition.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicy
> CommonDefinition.h
> new file mode 100644
> index 0000000000..7771fc7a95
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicy
> CommonDefinition.h
> @@ -0,0 +1,84 @@
> +/** @file
> +TBT Policy Common definition.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_POLICY_COMMON_H_
> +#define _TBT_POLICY_COMMON_H_
> +
> +#include <Library/GpioLib.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#define MAX_DTBT_CONTROLLER_NUMBER 2
> +
> +#define TYPE_PCIE           0x01
> +#define TYPE_PEG            0x02
> +
> +#pragma pack(push, 1)
> +
> +//
> +// dTBT Force Power GPIO Data Structure
> +//
> +typedef struct _DTBT_FORCE_POWER_GPIO_CONFIG {
> +  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
> +  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
> +  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
> +} DTBT_FORCE_POWER_GPIO_CONFIG;
> +
> +//
> +// dTBT CIO Plug Event GPIO Data Structure
> +//
> +typedef struct _DTBT_CIO_PLUG_EVENT_GPIO_CONFIG {
> +  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
> +  UINT32         AcpiGpeSignature;        ///< AcpiPlatform driver will change
> the XTBT method to the _Lxx or _Exx that we assign in this item.
> +  BOOLEAN        AcpiGpeSignaturePorting; ///< 0 = No porting required(for
> 2-tier GPI GPE event architecture), 1 = Porting required(for 1-tier GPI GPE event
> architecture)
> +  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
> +} DTBT_CIO_PLUG_EVENT_GPIO_CONFIG;
> +
> +//
> +// dTBT PCIE Reset GPIO Data Structure
> +//
> +typedef struct _DTBT_PCIE_RESET_GPIO_CONFIG {
> +  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
> +  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
> +  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
> +} DTBT_PCIE_RESET_GPIO_CONFIG;
> +
> +//
> +// dTBT Controller Data Structure
> +//
> +typedef struct _DTBT_CONTROLLER_CONFIG {
> +  UINT8                           DTbtControllerEn; ///< Enable/Disable
> DTbtController.
> +  UINT8                           Type;             ///< 01-Pcie RP, 02- PEG,Reserved.
> <Specific according to Board Design>
> +  UINT8                           PcieRpNumber;     ///< RP Number/ PEG Port
> (0,1,2) that connecet to dTBT controller. <Specific according to Board Design>
> +  DTBT_FORCE_POWER_GPIO_CONFIG    ForcePwrGpio;     ///< The GPIO
> pin that can force dTBT Power On. <Specific according to Board Design>
> +  DTBT_CIO_PLUG_EVENT_GPIO_CONFIG CioPlugEventGpio; ///< The GPIO
> pin that can generate Hot-Plug event. <Specific according to Board Design>
> +  DTBT_PCIE_RESET_GPIO_CONFIG     PcieRstGpio;      ///< The GPIO pin
> that is use to perform Reset when platform enters to Sx, it is required for
> platforms where PCI_RST pin connected to Tbt is controlled with GPIO <Specific
> according to Board Design>
> +  GPIO_PAD                        PdResetGpioPad;   ///< PD HRESET GPIO Pad
> Number
> +  GPIO_PAD                        PdSxEntryGpioPad; ///< PD SX Entry GPIO Pad
> Number
> +  GPIO_PAD                        PdSxAckGpioPad;   ///< PD SX Ack GPIO Pad
> Number
> +  UINT8                           Reserved[1];      ///< Reserved for DWORD
> alignment
> +} DTBT_CONTROLLER_CONFIG;
> +
> +//
> +// dTBT Controller Data Structure
> +//
> +typedef struct _DTBT_COMMON_CONFIG {
> +  UINT8            TbtBootOn;                    ///< Send BootOn Mailbox
> command when TbtBootOn is enabled.
> +  UINT8            TbtUsbOn;                     ///< Send UsbOn Mailbox
> command when TbtBootOn is enabled.
> +  UINT8            Gpio3ForcePwr;                ///< Force GPIO to power on or
> not
> +  UINT16           Gpio3ForcePwrDly;             ///< The delay time after do
> ForcePwr
> +  BOOLEAN          DTbtSharedGpioConfiguration;  ///< Multiple DTBT
> controllers share the same GPIO pin <Specific according to Board Design>
> +  BOOLEAN          PcieRstSupport;               ///< 0 = Not Support, 1 =
> Supported. it is required for platforms where PCI_RST pin connected to Tbt is
> controlled with GPIO
> +  UINT8            SecurityMode;                 ///< 0: SL0 No Security, 1: SL1 User
> Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
> +  UINT8            ControlIommu;                 ///< Control Iommu behavior in
> pre-boot, 0: Disabled Iommu, 1: Enable Iommu, Disable exception list, 2:
> Enable Iommu, Enable exception list
> +  UINT8            Reserved[3];                  ///< Reserved for DWORD
> alignment
> +} DTBT_COMMON_CONFIG;
> +
> +#pragma pack(pop)
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef
> .h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDe
> f.h
> new file mode 100644
> index 0000000000..d8021e8c22
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDe
> f.h
> @@ -0,0 +1,118 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  // Define a Global region of ACPI NVS Region that may be used for any
> +  // type of implementation.  The starting offset and size will be fixed
> +  // up by the System BIOS during POST.  Note that the Size must be a word
> +  // in size to be fixed up correctly.
> +
> +
> +#ifndef _GLOBAL_NVS_AREA_DEF_H_
> +#define _GLOBAL_NVS_AREA_DEF_H_
> +
> +#pragma pack (push,1)
> +typedef struct {
> +  //
> +  // Miscellaneous Dynamic Registers:
> +  //
> +  UINT16   OperatingSystem;                         ///< Offset 0       Operating
> System
> +  UINT8    SmiFunction;                             ///< Offset 2       SMI Function
> Call (ASL to SMI via I/O Trap)
> +  UINT32   Port80DebugValue;                        ///< Offset 3       Port 80
> Debug Port Value
> +  UINT8    PowerState;                              ///< Offset 7       Power State
> (AC Mode = 1)
> +  //
> +  // Thermal Policy Registers:
> +  //
> +  UINT8    EnableDigitalThermalSensor;              ///< Offset 8       Digital
> Thermal Sensor Enable
> +  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 9       DTS
> SMI Function Call
> +  //
> +  // CPU Identification Registers:
> +  //
> +  UINT8    ApicEnable;                              ///< Offset 10      APIC Enabled
> by SBIOS (APIC Enabled = 1)
> +  UINT8    ThreadCount;                             ///< Offset 11      Number of
> Enabled Threads
> +  //
> +  // PCIe Hot Plug
> +  //
> +  UINT8    PcieOSCControl;                          ///< Offset 12      PCIE OSC
> Control
> +  UINT8    NativePCIESupport;                       ///< Offset 13      Native PCIE
> Setup Value
> +  //
> +  // Global Variables
> +  //
> +  UINT8    DisplaySupportFlag;                      ///< Offset 14      _DOS
> Display Support Flag.
> +  UINT8    InterruptModeFlag;                       ///< Offset 15      Global
> IOAPIC/8259 Interrupt Mode Flag.
> +  UINT8    L01Counter;                              ///< Offset 16      Global L01
> Counter.
> +  UINT8    LtrEnable[24];                           ///< Offset 17      Latency
> Tolerance Reporting Enable
> +                                                    ///< Offset 18      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 19      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 20      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 21      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 22      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 23      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 24      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 25      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 26      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 27      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 28      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 29      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 30      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 31      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 32      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 33      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 34      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 35      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 36      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 37      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 38      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 39      Latency Tolerance
> Reporting Enable
> +                                                    ///< Offset 40      Latency Tolerance
> Reporting Enable
> +  UINT8    ObffEnable[24];                          ///< Offset 41      Optimized
> Buffer Flush and Fill
> +                                                    ///< Offset 42      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 43      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 44      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 45      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 46      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 47      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 48      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 49      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 50      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 51      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 52      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 53      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 54      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 55      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 56      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 57      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 58      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 59      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 60      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 61      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 62      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 63      Optimized Buffer
> Flush and Fill
> +                                                    ///< Offset 64      Optimized Buffer
> Flush and Fill
> +  UINT8    Rtd3Support;                             ///< Offset 65      Runtime D3
> support.
> +  UINT8    LowPowerS0Idle;                          ///< Offset 66      Low Power
> S0 Idle Enable
> +  UINT8    VirtualGpioButtonSxBitmask;              ///< Offset 67      Virtual
> GPIO button Notify Sleep State Change
> +  UINT8    PstateCapping;                           ///< Offset 68      P-state
> Capping
> +  UINT8    Ps2MouseEnable;                          ///< Offset 69      Ps2 Mouse
> Enable
> +  UINT8    Ps2KbMsEnable;                           ///< Offset 70      Ps2
> Keyboard and Mouse Enable
> +  //
> +  // Driver Mode
> +  //
> +  UINT32   GpioIrqRoute;                            ///< Offset 71      GPIO IRQ
> +  UINT8    PL1LimitCS;                              ///< Offset 75      set PL1 limit
> when entering CS
> +  UINT16   PL1LimitCSValue;                         ///< Offset 76      PL1 limit
> value
> +  UINT8    TenSecondPowerButtonEnable;              ///< Offset 78      10sec
> Power button support
> +  UINT8    PciDelayOptimizationEcr;                 ///< Offset 79      Pci Delay
> Optimization Ecr
> +  UINT8    TbtSupport;                              ///< Offset 80
> Thunderbolt(TM) support
> +  UINT8    TbtNativeOsHotPlug;                      ///< Offset 81
> TbtNativeOsHotPlug
> +  UINT8    TbtSelector;                             ///< Offset 82
> Thunderbolt(TM) Root port selector
> +  UINT8    TbtSelector1;                            ///< Offset 83
> Thunderbolt(TM) Root port selector
> +} EFI_GLOBAL_NVS_AREA;
> +
> +#pragma pack(pop)
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
> new file mode 100644
> index 0000000000..bbdeb71da5
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
> @@ -0,0 +1,51 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _ATTEMPT_USB_FIRST_H_
> +#define _ATTEMPT_USB_FIRST_H_
> +
> +#pragma pack(1)
> +typedef struct _ATTEMPT_USB_FIRST_HOTKEY_INFO {
> +  UINT8 RevisonId;         // Structure Revision ID
> +  UINT8 HotkeyTriggered;   // Hot key status
> +} ATTEMPT_USB_FIRST_HOTKEY_INFO;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct _ATTEMPT_USB_FIRST_VARIABLE {
> +  UINT8 UsbBootPrior;
> +} ATTEMPT_USB_FIRST_VARIABLE;
> +#pragma pack()
> +
> +//
> +// Volatile variable definition for Attempt USB first features
> +//
> +#pragma pack(1)
> +typedef struct _ATTEMPT_USB_FIRST_RUNTIME_VARIABLE {
> +  UINT8 RevisonId;        // Structure Revision ID
> +  UINT8 UsbFirstEnable;   // Attempt USB First is enabled or not
> +} ATTEMPT_USB_FIRST_RUNTIME_VARIABLE;
> +#pragma pack()
> +
> +//
> +// Volatile variable definition for third party Default Enabling via UEFI
> Variable.
> +//
> +#pragma pack(1)
> +typedef struct _ENABLE_CUSTOM_DEFAULTS{
> +  UINT32 EnableCustomDefaults;
> +} ENABLE_CUSTOM_DEFAULTS;
> +#pragma pack()
> +
> +#define COENG_DEFAULTS_UNKNOWN   0
> +#define COENG_DEFAULTS_SUPPORTED 1
> +#define COENG_DEFAULTS_VAR_EXITS 2
> +#define COENG_DEFAULTS_VAR_SET   4
> +#define COENG_DEFAULTS_AVAILABLE (COENG_DEFAULTS_SUPPORTED |
> COENG_DEFAULTS_VAR_EXITS |COENG_DEFAULTS_VAR_SET)
> +
> +extern EFI_GUID gAttemptUsbFirstHotkeyInfoHobGuid;
> +extern EFI_GUID gAttemptUsbFirstRuntimeVarInfoGuid;
> +#endif
> +
> diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
> new file mode 100644
> index 0000000000..17ccd56373
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
> @@ -0,0 +1,57 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPUSMM_H_
> +#define _CPUSMM_H_
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#define CPUSMM_GUID { 0x90d93e09, 0x4e91, 0x4b3d, { 0x8c, 0x77, 0xc8,
> 0x2f, 0xf1, 0xe, 0x3c, 0x81 }}
> +#define CPUSMM_SETUP_NAME             L"CpuSmm"
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT8     CpuSmmMsrSaveStateEnable;
> +  UINT8     CpuSmmCodeAccessCheckEnable;
> +  UINT8     CpuSmmUseDelayIndication;
> +  UINT8     CpuSmmUseBlockIndication;
> +  UINT8     CpuSmmUseSmmEnableIndication;
> +  UINT8     CpuSmmProcTraceEnable;
> +} CPU_SMM;
> +#pragma pack()
> +
> +#ifndef OFFSET_OF
> +#ifdef __GNUC__
> +#if __GNUC__ >= 4
> +#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
> +#endif
> +#endif
> +#endif
> +
> +#ifndef OFFSET_OF
> +#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
> +#endif
> +
> +#define VERIFY_OFFSET(TYPE, Field, Offset) extern UINT8
> _VerifyOffset##TYPE##Field[(OFFSET_OF(TYPE, Field) == Offset) /
> (OFFSET_OF(TYPE, Field) == Offset)]
> +
> +//
> +// If TpmSupport/MorStae isn't in this offset, build failure (0 size array or
> divided by 0) will be generated.
> +// Platform DSC file maps the two field to HII PCD so the offset value is critical.
> +//
> +VERIFY_OFFSET (CPU_SMM, CpuSmmMsrSaveStateEnable, 0x0);
> +VERIFY_OFFSET (CPU_SMM, CpuSmmCodeAccessCheckEnable, 0x1);
> +VERIFY_OFFSET (CPU_SMM, CpuSmmUseDelayIndication, 0x2);
> +VERIFY_OFFSET (CPU_SMM, CpuSmmUseBlockIndication, 0x3);
> +VERIFY_OFFSET (CPU_SMM, CpuSmmUseSmmEnableIndication, 0x4);
> +VERIFY_OFFSET (CPU_SMM, CpuSmmProcTraceEnable, 0x5);
> +
> +/****** DO NOT WRITE BELOW THIS LINE *******/
> +#ifdef __cplusplus
> +}
> +#endif
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfiguration
> s.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfiguration
> s.h
> new file mode 100644
> index 0000000000..b7202a6b4a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfiguration
> s.h
> @@ -0,0 +1,20 @@
> +/** @file
> +  This header file provides definitions of firmware configuration.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _FIRMWARE_CONFIGURATION_H_
> +#define _FIRMWARE_CONFIGURATION_H_
> +
> +typedef enum {
> +  FwConfigDefault = 0,
> +  FwConfigProduction,
> +  FwConfigTest,
> +  FwConfigMax
> +} FW_CONFIG;
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
> new file mode 100644
> index 0000000000..ed63b28adf
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
> @@ -0,0 +1,1766 @@
> +/** @file
> +Header file for GOP Configuration Library
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GOP_CONFIG_LIB_H_
> +#define _GOP_CONFIG_LIB_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#pragma pack(1)
> +#define GOP_CONFIG_VBT_REVISION 0xC1
> +
> +#define ChildStruct_MAX                       8         ///< Maximum number of
> child structures in VBT
> +#define CompressionStruct_MAX                 2         ///< Maximum number
> of compression parameter structures in VBT.
> +#define NO_DEVICE                             0x00      ///< Defines a null display
> class.
> +#define DISPLAY_PORT_ONLY                     0x68C6    ///< Defines a display
> class of Integrated Display Port Only
> +#define DISPLAY_PORT_HDMI_DVI_COMPATIBLE      0x60D6    ///< Defines a
> display class of Integrated DisplayPort with HDMI/DVI Compatible
> +#define DISPLAY_PORT_DVI_COMPATIBLE           0x68D6    ///< Defines a
> display class of Integrated DisplayPort with DVI Compatible
> +#define HDMI_DVI                              0x60D2    ///< Defines a display
> class of Integrated HDMI/DVI
> +#define DVI_ONLY                              0x68D2    ///< Defines a display class
> of Integrated DVI Only
> +#define MIPI_ONLY                             0x1400
> +#define eDP_ONLY                              0x1806    ///< Defines a display class
> of eDP only
> +#define AUX_CHANNEL_A                         0x40
> +#define AUX_CHANNEL_B                         0x10
> +#define AUX_CHANNEL_C                         0x20
> +#define AUX_CHANNEL_D                         0x30
> +#define NO_PORT                               0x00      ///< Defines a output port
> NA
> +#define HDMI_B                                0x01      ///< Defines a output port
> HDMI-B
> +#define HDMI_C                                0x02      ///< Defines a output port
> HDMI-C
> +#define HDMI_D                                0x03      ///< Defines a output port
> HDMI-D
> +#define HDMI_F                                0x0E      ///< Defines a output port
> HDMI-D
> +#define DISPLAY_PORT_A                        0x0A      ///< Defines a output
> port DisplayPort A
> +#define DISPLAY_PORT_B                        0x07      ///< Defines a output
> port DisplayPort B
> +#define DISPLAY_PORT_C                        0x08      ///< Defines a output
> port DisplayPort C
> +#define DISPLAY_PORT_D                        0x09      ///< Defines a output
> port DisplayPort D
> +#define DISPLAY_PORT_E                        0x0B      ///< Defines a output
> port DisplayPort E
> +#define DISPLAY_PORT_F                        0x0D      ///< Defines a output
> port DisplayPort F
> +#define PORT_MIPI_A                           0x15      ///< Mipi Port A
> +#define PORT_MIPI_C                           0x17      ///< Mipi Port C
> +
> +typedef struct {
> +  UINT16  Dclk;                         // DClk in 10 KHz
> +  UINT8   HActive;                      // HActive [7:0]
> +  UINT8   HBlank;                       // HBlank [7:0]
> +  UINT8   HA_HB_UpperNibble;            // Upper nibble = HActive [11:8]
> +  UINT8   VActive;                      // VActive [7:0]
> +  UINT8   VBlank;                       // VBlank [7:0]
> +  UINT8   VA_VB_UpperNibble;            // Upper nibble = VActive [11:8]
> +  UINT8   HSyncOffset;                  // HSync offset from blank start LSB
> +  UINT8   HPulseWidth;                  // HSync Pulse Width, LSB
> +  UINT8   VsyncOffset_VpulseWidth_LSB;  // Bits 7:4 = VSync offset [3:0]
> +  UINT8   HSO_HSPW_V_High;              // Bits 7:6 = HSync Offset [9:8]
> +  UINT8   HorImageSize;                 // Horizontal Image Size
> +  UINT8   VerImageSize;                 // Vertical Image Size
> +  UINT8   HIS_VIS_High;                 // UpperLmtH_V Upper limits of H. and V.
> image size
> +  UINT8   HBorder;                      // Horizontal Border
> +  UINT8   VBorder;                      // Vertical Border
> +  UINT8   Flags;                        // Flags
> +} DTD_STRUCTURE;                        // 18 Bytes
> +
> +typedef struct {
> +  UINT16  XRes;
> +  UINT16  YRes;
> +  UINT32  SerialNo;
> +  UINT8   Week;
> +  UINT8   Year;
> +} PID_DATA;                             // 10 Bytes
> +
> +//
> +// VBT Header
> +//
> +/**
> +  This structure defines the VBT Header.
> +**/
> +typedef struct {
> +  UINT8   Product_String[20]; ///< "$VBT_Cannonlake" is the product string
> +  UINT16  Version_Num;        ///< Defines the VBT Header version number.
> +  UINT16  Header_Size;        ///< Defines the size of VBT Header.
> +  UINT16  Table_Size;         ///< Defines the size of complete VBT.
> +  UINT8   Checksum;           ///< Defines the checksum of entire VBT
> +  UINT8   Reserved1;          ///< Reserved field 1 of 1 byte.
> +  UINT32  Bios_Data_Offset;   ///< Defines the offset of VBT Data block.
> +  UINT32  Aim_Data_Offset[4]; ///< 4 reserved pointers to VBT data blocks.
> +} VBT_HEADER;
> +
> +/**
> +  This structure defines the VBT BIOS Data Block Header
> +**/
> +typedef struct {
> +  UINT8   BDB_Signature[16];  ///< Defines the Bios Data Block signature
> "BIOS_DATA_BLOCK".
> +  UINT16  BDB_Version;        ///< Defines the VBT (data) version.
> +  UINT16  BDB_Header_Size;    ///< Defines the size of VBT Bios data block
> header.
> +  UINT16  BDB_Size;           ///< Defines the size of Bios data block.
> +} VBT_BIOS_DATA_HEADER;
> +
> +/**
> +  This structure defines the BMP Signon Message and Copyright Message
> Structure
> +**/
> +typedef struct {
> +  UINT8   BlockId;            ///< Defines Block ID : 254
> +  UINT16  BlockSize;          ///< Defines the size of BMP Signon block.
> +
> +  UINT16  Bmp_BIOS_Size;      ///< Defines the BIOS size 32k/48k/64k.
> +  UINT8   BIOS_Type;          ///< Defines the type of BIOS desktop or mobile.
> +  UINT8   RelStatus;          ///< Defines the release status of the current GOP
> driver.
> +  UINT8   BIOS_HW;            ///< Defines the Hardware i.e. Cannonlake.
> +  UINT8   INT_HW;             ///< Defines the integrated hardware supported
> eDP/HDMI/DP.
> +  UINT8   Build_Number[4];    ///< Defines the build number string.
> +  UINT8   SignOn[155];        ///< Defines the sign on message.
> +  UINT8   CopyRight[61];      ///< Defines the copyright message.
> +} BMP_STRUCTURE_SIGNON;
> +
> +/**
> +  This structure defines the BMP General Bits
> +**/
> +typedef struct {
> +  UINT16  bmp_BIOS_CS;          ///< Defines the start of BIOS code segment
> +  UINT8   bmp_DOS_Boot_Mode;    ///< Defines the mode number to set
> when DOS is boot
> +  UINT8   bmp_BW_Percent;       ///< Set percentage of total memory BW
> +  UINT8   bmp_Popup_Mem_Size;   ///< Default Popup memory size in KB
> +  UINT8   bmp_Resize_PCI_BIOS;  ///< BIOS size granularity in 0.5 KB
> +  UINT8   Switch_CRT_To_DDC2;   ///< Obsolete field: Is the CRT already
> switched to DDC2
> +  UINT8   bmp_Allow_Config;     ///< Bit 1 : 1, Enable aspect ratio for DOS
> +                                ///< Bit 0 : 1, Allow boot to DVI even if it is not
> attached.
> +} BMPGEN;
> +
> +/**
> +  This structure defines Block 254 (BMP structure)
> +**/
> +typedef struct {
> +  BMP_STRUCTURE_SIGNON    bmp_Signon_Message;   ///< Instance of
> signon and copyright message structure
> +  BMPGEN                  bmp_General_Bytes;    ///< Instance of BMP General
> Bits structure.
> +} BLOCK254_BMP_Structure;
> +
> +/**
> +  This structure defines Block 1 (General Bytes Definitions)
> +**/
> +typedef struct {
> +  UINT8   BlockId;        ///< Defines the Block ID (1)
> +  UINT16  BlockSize;      ///< Defines the size of General bytes definition
> block.
> +
> +  /**
> +  BMP General Bit Definitions 1\n
> +  Bit 7 = DVO A color flip bit
> +    = 0, No DVO A color flip
> +    = 1, Flip DVO A color
> +  Bits 6:4 = Clear screen (CLS) after Signon
> +      = 000, No CLS
> +      = 001, 0.5 sec pause and then CLS
> +      = 010, 1.0 sec pause and then CLS
> +      = 011, 1.5 sec pause and then CLS
> +      = 100, 2.0 sec pause and then CLS
> +      = 101, 2.5 sec pause and then CLS
> +      = 110, 3.0 sec pause and then CLS
> +      = 111, 3.5 sec pause and then CLS
> +  Bit 3 = 1  Enable Display Signon
> +  Bit 2 = 1  Enable Flex-aim Support
> +  Bits 1:0 = Flat panel fitting enabling
> +      = 00, Centering
> +      = 01, Reserved
> +      = 10, Aspect scaling
> +      = 11, Fullscreen
> +  **/
> +  union {
> +    UINT8  Value;
> +    struct {
> +      UINT8 PanelFitterEnabling:2;
> +      UINT8 FlexAimSupportEnable:1;
> +      UINT8 DisplaySignonEnable:1;
> +      UINT8 ClearScreenTime:3;
> +      UINT8 DvoAColorFlipEnable:1;
> +    } Bits;
> +  } bmp_Bits_1;
> +
> +  /**
> +  BMP General Bit Definitions\n
> +  Bit 7 = Hot plug support
> +    = 0, Hot plug disabled
> +    = 1, Hot plug enabled
> +  Bit 6 = Dynamic CD clock feature
> +    = 0, Dynamic CD clock feature is disabled
> +    = 1, Dynamic CD clock feature is enabled
> +  Bit 5 = Underscan support for VGA timings
> +  Bit 4 = Disable SSC in Dual Display Twin Mode. (This field is obsolete now.
> Kept for VBIOS only.)
> +    = 0, No
> +    = 1, Yes
> +  Bit 3 = LFP power state on override by 5f64h,08h
> +    = 0, No Override
> +    = 1, Override
> +  Bit 2 = Internal LVDS SSC frequency. (This field is obsolete now. Kept for
> VBIOS only.)
> +    = 0, 96/120MHz
> +    = 1, 100MHz
> +  Bit 1 = internal LVDS SSC (Spread Spectrum Clock) (This field is obsolete now.
> Kept for VBIOS only.)
> +    = 0, Disabled
> +    = 1, Enabled
> +  Bit 0 = KvmrSessionEnable.
> +    = 0, Disabled
> +    = 1, Enabled
> +  **/
> +  union {
> +    UINT8 Value;
> +    struct {
> +      UINT8 KvmrSessionEnable:1;
> +      UINT8 Reserved_1:5;
> +      UINT8 DynamicCdClockEnable:1;
> +      UINT8 HotPlugEnable:1;
> +    } Bits;
> +  } bmp_Bits_2;
> +
> +  /**
> +  BMP General Bit Definitions 3\n
> +  Bit 7 = Ignore strap status
> +      = 0 Do not ignore
> +      = 1 Ignore
> +  Bit 6 = Panel Timing algorithm
> +      = 0 Preferred timings
> +      = 1 Best fit timings
> +  Bit 5 Copy iLFP DTD to SDVO LVDS DTD
> +      = 0 Don't copy DTD
> +      = 1 Copy DTD to
> +  Bit 4 = VBIOS normal/extd. DT mode
> +      = 0 Normal mode
> +      = 1 DUAL mode
> +  Bit 3 = FDI RX Polarity
> +      = 0 Normal
> +      = 1 Inverted
> +  Bit 2 = Enable 180 Degree Rotation
> +      = 0  Disable
> +      = 1  Enable
> +  Bit 1 = Single DVI-I connector for CRT and DVI display: Obsolete field
> +      = 0 Disabled
> +      = 1 Enabled
> +  Bit 0 = Smooth Vision
> +      = 0  Disabled
> +      = 1  Enabled
> +  **/
> +  union {
> +    UINT8 Value;
> +    struct {
> +      UINT8 Reserved1:1;
> +      UINT8 SingleDviiCrtConnector:1;
> +      UINT8 Enable180DegRotation:1;
> +      UINT8 FdiRxPolarity:1;
> +      UINT8 Reserved2:4;
> +    } Bits;
> +  } bmp_Bits_3;
> +
> +  UINT8   Reserved;     ///< Reserved field. It was Legacy_Monitor_Detect in
> previous platforms.
> +
> +  /**
> +  Integrated display device support\n
> +  Bits 7:6 = Reserved
> +  Bit 5 = DP SSC Dongle Enable/Disable
> +  Bit 4 = DP SSC Frequency. (This field is obsolete now. Kept for VBIOS only.)
> +    = 0, 96 MHz
> +    = 1, 100 MHz
> +  Bit 3 = DP SSC Enable
> +    = 0, Disable
> +    = 1, Enable
> +  Bit 2 = Integrated EFP support
> +    = 0, Disable
> +    = 1, Enable
> +  Bit 1 = Integrated TV support. (This field is obsolete now. Kept for VBIOS
> only.)
> +    = 0, Disable
> +    = 1, Enable
> +  Bit 0 = Integrated CRT support: Obsolete field
> +    = 0, Disable
> +    = 1, Enable
> +  **/
> +  union {
> +    UINT8 Value;
> +    struct {
> +      UINT8 CrtSupported:1;
> +      UINT8 TvSupported:1;
> +      UINT8 EfpSupported:1;
> +      UINT8 DpSscEnable:1;
> +      UINT8 DpSscFrequency:1;
> +      UINT8 DpDongleSscEnable:1;
> +      UINT8 Reserved1:2;
> +    } Bits;
> +  } Int_Displays_Support;
> +} VBT_GENERAL1_INFO;
> +
> +/**
> +  This defines the Structure of PRD Boot Table Entry
> +**/
> +typedef struct {
> +  UINT8 AttachBits;     ///< Bitmap representing the displays attached
> currently.
> +  UINT8 BootDev_PipeA;  ///< Bitmap representing the display to boot on
> Pipe A.
> +  UINT8 BootDev_PipeB;  ///< Bitmap representing the display to boot on
> Pipe B.
> +} PRD_TABLE;
> +
> +/**
> +  This defines the structure of Block 254 (PRD Boot Table/Child Device List)
> +**/
> +typedef struct {
> +  UINT8     BlockId;    ///< Defines the Block ID (254)
> +  UINT16    BlockSize;  ///< Defines the size of Block 254
> +
> +  PRD_TABLE PRDTable[16];                     ///< Defines the Child device list
> for enumerating child handles.
> +  UINT16    PRD_Boot_Table_Number_Of_Entries; ///< Number of entries in
> child device list.
> +} PRD_BOOT_TABLE;
> +
> +/**
> +  This defines the Structure for a CHILD_STRUCT (used for all the displays).
> +**/
> +typedef struct {
> +  UINT16  DeviceHandle;         ///< Unique ID indicating the group of display
> device (LFP/EFP1/EFP2/EFP3/EFP4).
> +  UINT16  DeviceClass;          ///< Indicates the class of display device.
> +  UINT8   I2CSpeed;             ///< Defines the I2C speed to be used for I2C
> transaction.
> +  /**
> +  Defines the DP on board redriver configuration.
> +  BIT[7]    : Reserved
> +  BIT[6]    : Is On Board DP Redriver Present
> +          0 : No
> +          1 : Yes
> +  BIT[5:3]  : On Board Redriver VSwing Level
> +          0 : Level 0
> +          1 : Level 1
> +          2 : Level 2
> +          3 : Level 3
> +     Others : Reserved
> +  BIT[2:0]  : On Board Redriver PreEmph Level
> +          0 : Level 0
> +          1 : Level 1
> +          2 : Level 2
> +          3 : Level 3
> +  Others    : Reserved
> +  **/
> +  union{
> +  UINT8 Value;
> +  struct {
> +    UINT8 OnBoardPreEmphLevel:3;
> +    UINT8 OnBoardVSwingLevel:3;
> +    UINT8 OnBoardRedriverPresent:1;
> +    UINT8 Reserved:1;
> +    } Bits;
> +  } DpOnBoardRedriver;
> +
> +  /**
> +  Defines the DP on dock redriver configuration.
> +  BIT[7]    : Reserved
> +  BIT[6]    : Is On Dock DP Redriver Present
> +          0 : No
> +          1 : Yes
> +  BIT[5:3]  : On Dock Redriver VSwing Level
> +          0 : Level 0
> +          1 : Level 1
> +          2 : Level 2
> +          3 : Level 3
> +     Others : Reserved
> +  BIT[2:0]  : On Dock Redriver PreEmph Level
> +          0 : Level 0
> +          1 : Level 1
> +          2 : Level 2
> +          3 : Level 3
> +  Others    : Reserved
> +  **/
> +  union {
> +  UINT8 Value;
> +  struct {
> +    UINT8 OnDockPreEmphLevel:3;
> +    UINT8 OnDockVSwingLevel:3;
> +    UINT8 OnDockRedriverPresent:1;
> +    UINT8 Reserved:1;
> +    } Bits;
> +  } DpOnDockRedriver;
> +
> +  /**
> +
> +  Defines the HDMI level shifter configuration.
> +  BIT[7:5]  : Hdmi Maximum data rate
> +  BIT[4:0]  : Hdmi Level shifter value
> +
> +  **/
> +  union{
> +  UINT8 Value;
> +  struct {
> +    UINT8 HdmiLevelShifterValue:5;
> +    UINT8 HdmiMaxDataRateBits:3;
> +    } Bits;
> +  } HdmiLevelShifterConfig;
> +
> +  UINT16  EFPDTDBufferPointer;  ///< Pointer to the DTD timing to be used in
> case of edidless EFP.
> +
> +  /**
> +  Defines the first set of flags.
> +  BIT[7-4]  : Reserved
> +  BIT[3]    : Dual pipe ganged display support
> +          0 : Display uses a single pipe/port
> +          1 : Display uses two distinct pipes/ports.
> +  BIT[2]    : Compression Method Select
> +          0 : Compression using picture parameter set (PPS)
> +          1 : Compression using Capability parameter set (CPS)
> +  BIT[1]    : Compression enable/disable for this display.
> +          0 : Disabled
> +          1 : Enabled
> +  BIT[0]    : EDID less EFP Enable
> +          0 : Enable support for EDID less EFP.
> +          1 : Disable support for EDID less EFP.
> +  **/
> +  union {
> +  UINT8 Value;
> +  struct {
> +    UINT8 EdidlessEfpEnable:1;
> +    UINT8 CompressionEnable:1;
> +    UINT8 CompressionMethod:1;
> +    UINT8 IsDualPortEnabled:1;
> +    UINT8 Reserved:4;
> +    } Bits;
> +  } Flags0;
> +
> +  /**
> +  Defines the compression index field for the display.
> +  BITS[7-4]  : Reserved
> +  BITS[3-0]  : Compression Structure index in the block 55.
> +        0x0  : Index 0 in block 55
> +        0x1  : Index 1 in block 55
> +        0xF  : Not Applicable.
> +      Others : Reserved
> +  **/
> +  union {
> +  UINT8 Value;
> +  struct {
> +    UINT8 IndexInBlock55:4;
> +    UINT8 Reserved:4;
> +    } Bits;
> +  } CompressionStructureIndex;
> +
> +  UINT8   SlaveDdiPort;         ///< The DVO port number of slave DDI to be
> used in case Flags0[3] = 1.
> +
> +  UINT8   Reserved_1;           ///< Reserved and might be used in other
> platforms.
> +  UINT16  AddInOffset;          ///< Obsolete field.
> +  UINT8   DVOPort;              ///< Specifies the port number of the display
> device represented in the device class.
> +  UINT8   I2CBus;               ///< Specifies the GMBUS or I2C pin pair for add
> in card.
> +  UINT8   SlaveAddr;            ///< Specifies the I2C address of the add in card.
> +  UINT8   DDCBus;               ///< Specifies the GMBUS pin pair for EDID read.
> +  UINT16  TimingInfoPtr;        ///< Pointer to the buffer where VBIOS stores
> the EDID of device.
> +  UINT8   DVOCfg;               ///< Obsolete field.
> +
> +  /**
> +  Flags 1\n
> +  Bits 7:5  : Reserved
> +  Bit 4     : HPD Sense Invert
> +          0 : Invert not required (default)
> +          1 : Invert required
> +  Bit 3     : IBoost feature enable/disable.
> +          0 : IBoost feature is disabled.
> +          1 : IBoost feature is enabled.
> +  Bit 2     : Hdmi 2.0 Motherboard Downsuppotred options
> +          0 : Motherboard Down chip not supported
> +          1 : Motherboard Down Chip Supported on the Board
> +  Bit 1     : Lane Reversal feature.
> +          0 : Disable
> +          1 : Enable
> +  Bit 0     : DP/HDMI routed to dock.
> +          0 : Disable
> +          1 : Enable
> +  **/
> +  union {
> +  UINT8 Value;
> +  struct {
> +    UINT8 DockablePort:1;
> +    UINT8 EnableLaneReversal:1;
> +    UINT8 OnBoardLsPconDonglePresent:1;
> +    UINT8 IBoostEnable:1;
> +    UINT8 IsHpdInverted:1;
> +    UINT8 Reserved:3;
> +    } Bits;
> +  } Flags_1;
> +
> +  UINT8   Compatibility;        ///< Compatibility is used in VBIOS only. It was
> used before device class was defined.
> +  UINT8   AUX_Channel;          ///< Specifies the aux channel to be used for
> display port devices.
> +  UINT8   Dongle_Detect;        ///< Indicates whether dongle detect is
> enabled or not.
> +  UINT8   Capabilities;         ///< Bits 1-0 indicate pipe capabilities whether
> display can be used on one pipe or both the pipes.
> +  UINT8   DVOWiring;            ///< Obsolete field.
> +  UINT8   MipiBridgeType;       ///< MIPI bridge type
> +  UINT16  DeviceClassExtension; ///< Obsolete.
> +  UINT8   DVOFunction;          ///< Obsolete.
> +
> +  /**
> +  Flags 2
> +  Bits 7:4  : DP Port trace length from silicon to output port on the board
> +          0 : Default RVP length
> +          1 : Short trace length
> +          2 : Long trace length
> +  Bits 3:2  : Reserved
> +  Bit 1     : Indicates whether this port is Thunderbolt port or not.
> +          0 : No
> +          1 : Yes
> +  Bit 0     : DP 2 lane RCR# 1024829: USB type C to enable 2 lane DP display
> +          0 : Disable
> +          1 : Enable
> +  **/
> +  union {
> +    UINT8   Value;
> +    struct {
> +      UINT8   UsbTypeCDongleEnabled:1;  ///< Indicates whether this port is
> USB type C.
> +      UINT8   IsThunderboltPort:1;      ///< Indicates whether this port is
> Thunderbolt. (ICL+)
> +      UINT8   Reserved:2;               ///< Reserved for future use.
> +      UINT8   DpPortTraceLength:4;      ///< Dp port trace length from silicon
> to port.
> +    } Bits;
> +  } Flags_2;
> +  UINT8   DP2XGpioIndex;        ///< GPIO index number for the USB type C.
> +  UINT16  DP2XGpioNumber;       ///< GPIO number for USB type C.
> +
> +  /**
> +  IBoost magnitude field.
> +  Bits 7:4  : DP Boost magnitude
> +          0 : 1
> +          1 : 3
> +          2 : 7
> +     Others : Reserved for WHL.
> +  Bits 3:0  : HDMI Boost magnitude
> +          0 : 1
> +          1 : 3
> +          2 : 7
> +  Others : Reserved.
> +  **/
> +  union {
> +    UINT8   Value;
> +    struct {
> +      UINT8   DpEdpBoostMagnitude:4;
> +      UINT8   HdmiBoostMagnitude:4;
> +    } Bits;
> +  } BoostMagnitude;
> +} CHILD_STRUCT;
> +
> +/**
> +  This structure defines Block 2 (General Bytes Definitions)
> +**/
> +typedef struct {
> +  UINT8         BlockId;          ///< Defines the Block ID : 2.
> +  UINT16        BlockSize;        ///< Defines the size of VBT General Info 2
> Block.
> +
> +  UINT8         bmp_CRT_DDC_GMBUS_Pin;  ///< Obsolete field: Selects the
> CRT DDC GMBUS pin pair.
> +  UINT8         bmp_DPMS_Bits;          ///< BMP DPMS Bit Definitions.
> +  UINT16        bmp_Boot_Dev_Bits;      ///< BMP Boot Device Bit
> Definitions.
> +  UINT8         SizeChild_Struct;       ///< Size of the ChildStruc structure.
> +
> +  CHILD_STRUCT  Child_Struct[ChildStruct_MAX];  ///< This array defines all
> the supported child structures.
> +} VBT_GENERAL2_INFO;
> +
> +/**
> +  This defines the structure of Block 3 (Original Display Toggle List)
> +**/
> +typedef struct {
> +  UINT8   BlockId;                ///< Defines the Block ID : 3
> +  UINT16  BlockSize;              ///< Defines the size of Original Display Toggle
> List Block
> +  UINT8   bmp_Display_Detect;     ///< Display must be attached or not
> +} BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST;
> +
> +/**
> +  This defines structure of a pointer table.
> +**/
> +typedef struct {
> +  UINT16  Offset;       ///< Defines the offset of the table from start of BIOS
> Data block.
> +  UINT16  Size;         ///< Defines the size of an entry of the table.
> +} BMP_TABLE_PTR;
> +
> +/**
> +  This structure defines Block 252 (SBIOS Hooks and BMP Table Pointers).
> +**/
> +typedef struct {
> +  UINT8           BlockId;          ///< Defines the Block ID : 252.
> +  UINT16          BlockSize;        ///< Defines the size of SBIOS Hooks block.
> +  UINT8           SbiosHooks[18];   ///< This array defines a series of SBIOS
> hooks. Each entry represents one hook.
> +  BMP_TABLE_PTR   BmpTablePtr[26];  ///< This array defines pointers to all
> the important tables in the VBT.
> +} BLOCK252_SBIOS_Hook;
> +
> +/**
> +  This defines the structure of MMIO boot table entry
> +**/
> +typedef struct {
> +  UINT32  Register;   ///< Defines the MMIO offset of the register.
> +  UINT32  Value;      ///< Defines the default value of the register.
> +} MMIO_BOOT_TABLE;
> +
> +/**
> +  This structure defines Block 6 (MMIO Register Block)
> +**/
> +typedef struct {
> +  UINT8           BlockId;              ///< Defines the Block ID : 6
> +  UINT16          BlockSize;            ///< Defines the size of MMIO Register
> Table block.
> +  UINT16          RegTableId;           ///< Defines the ID for MMIO register
> table (0xFFFC).
> +  UINT8           AccessFlag;           ///< Defines the flag for data access size
> (02 for 4 byte read/write).
> +  MMIO_BOOT_TABLE MMIOBootTable[14];    ///< Array containing the
> MMIO register table.
> +  UINT16          TableEnd;             ///< Special value describing End of table
> (0xFFFF).
> +} BLOCK06_MMIO_REG_TABLE;
> +
> +/**
> +  This structure defines Block 7 (IO SW Flag Register Table)
> +**/
> +typedef struct {
> +  UINT8   BlockId;          ///< Defines Block ID (7).
> +  UINT16  BlockSize;        ///< Defines the size of IO SW Flag register table
> block.
> +  UINT16  RegTableId;       ///< Defines the ID for IO SW Flag register table
> (0xFFFE).
> +  UINT8   GRIndexRegLsb;    ///< Defines the read/write size. Value is 0xCE
> meaning 1 byte without mask.
> +  UINT8   IOSWFlagReg;      ///< Defines the offset for the IO SW Flag register.
> +  UINT8   Value;            ///< Defines the data/value for the register.
> +  UINT16  TableEnd;         ///< Special value describing the end of table
> (0xFFFF).
> +} BLOCK07_IOSWFLAG_REG_TABLE;
> +
> +/**
> +  This structure defines the entry of SWF table.
> +**/
> +typedef struct {
> +  UINT32  Register;   ///< Defines the MMIO offset of the SWF register.
> +  UINT32  Value;      ///< Defines the default value for the SWF register.
> +} SWF_TABLE;
> +
> +/**
> +  This defines the structure of Block 8 (MMIO SW Flag Block).
> +**/
> +typedef struct {
> +  UINT8     BlockId;      ///< Defines the Block ID : 8.
> +  UINT16    BlockSize;    ///< Defines the size of MMIO SWF register table
> block.
> +  UINT16    RegTableId;   ///< Defines the ID for MMIO SWF register table
> (0xFFFC).
> +  UINT8     AccessFlag;   ///< Defines the data access size. Value is 0x02
> meaning 4 bytes read/write.
> +  SWF_TABLE SWFTable[7];  ///< Array containing the MMIO SWF register
> table.
> +  UINT16    TableEnd;     ///< Special value describing end of table (0xFFFF).
> +} BLOCK08_MMIOSWFLAG_REG_TABLE;
> +
> +/**
> +  This structure defines the PSR feature table entry.
> +**/
> +typedef struct {
> +  UINT8   SRD_Enables;        ///< Defines PSR features such as full link
> enable/disable and whether aux is required to wake up.
> +  UINT8   SRD_WaitTimes;      ///< Defines lines to wait before link standby
> and idle frames to wait before SRD enable.
> +  UINT16  SRD_TP1_WakeupTime; ///< TP 1 wake up time in multiples of 100.
> +  UINT16  SRD_TP2_WakeupTime; ///< TP2/TP3 wake up time in multiples of
> 100
> +} PSR_FEATURE_TABLE;
> +
> +/**
> +  This defines the structure of Block 9 (PSR Features Block)
> +**/
> +typedef struct {
> +  UINT8             BlockId;              ///< Defines the block ID : 9
> +  UINT16            BlockSize;            ///< Defines the size of PSR Feature
> block.
> +  PSR_FEATURE_TABLE PSRFeatureTable[16];  ///< Array containing the PSR
> Feature table.
> +} BLOCK09_PSR_FEATURE;
> +
> +/**
> +  This structure defines an entry of Mode Removal table.
> +**/
> +typedef struct {
> +  UINT16  XRes;         ///< X resolution of the mode.
> +  UINT16  YRes;         ///< Y resolution of the mode.
> +  UINT8   Bpp;          ///< Bits per pixel of the mode.
> +  UINT16  RRate;        ///< Refresh rate of the mode.
> +  UINT8   RFlags;       ///< Flags specifying display type and functional area
> where the mode is to be removed.
> +  UINT16  PanelFlags;   ///< Applicable to LFP only. Indicates which LFP
> panels the mode is to be removed.
> +} MODE_REMOVAL_TABLE_ENTRY;
> +
> +/**
> +  This defines the structure of Block 10 (Mode Removal Block)
> +**/
> +typedef struct {
> +  UINT8                     BlockId;              ///< Defines the Block ID : 10.
> +  UINT16                    BlockSize;            ///< Defines the size of Mode
> Removal table block.
> +  UINT8                     EntrySize;            ///< Defines the size of one entry of
> mode removal table.
> +  MODE_REMOVAL_TABLE_ENTRY  ModeRemovalTable[20]; ///< Array
> containing the mode removal table.
> +  UINT16                    Terminator;           ///< Special value indicating end
> of mode removal table (0xFFFF).
> +} BLOCK10_MODE_REMOVAL_TABLE;
> +
> +/**
> +  This defines the structure of Block 12 (Driver Features Data Block)
> +**/
> +typedef struct {
> +  UINT8   BlockId;                  ///< Defines the unique Block ID : 12
> +  UINT16  BlockSize;                ///< Defines the size of Driver features block.
> +
> +  /**
> +  This field defines the various driver related bits:\n
> +  Bit 7 = Use 00000110h ID for Primary LFP
> +        = 0, No
> +        = 1, Yes
> +  Bit 6 = Enable/Disable Sprite in Clone Mode
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 5 = Driver INT 15h hook
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 4 = Dual View Zoom
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 3 = Hot Plug DVO
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 2 = Allow display switching when in Full Screen DOS.
> +        = 0, Block Display Switching
> +        = 1, Allow Display Switching
> +  Bit 1 = Block display switching when DVD active
> +        = 0, No Block Display Switching
> +        = 1, Block Display Switching
> +  Bit 0 = Boot device algorithm
> +        = 0, OS Default
> +        = 1, Driver Default
> +  **/
> +  UINT8   bmp_Driver_Bits;
> +  UINT16  bmp_Driver_Boot_Mode_X;   ///< X resolution of driver boot
> mode.
> +  UINT16  bmp_Driver_Boot_Mode_Y;   ///< Y resolution of driver boot
> mode.
> +  UINT8   bmp_Driver_Boot_Mode_BPP; ///< Bits per pixel of driver boot
> mode.
> +  UINT8   bmp_Driver_Boot_Mode_RR;  ///< Refresh rate of driver boot
> mode.
> +
> +  /**
> +  This field defines the extended driver bits 1.\n
> +  Bits [15:14] = Integrated HDMI configuration
> +              = 00b,  No Integrated HDMI
> +              = 01b,  Port-B Only
> +              = 10b,  Port-C Only
> +              = 11b,  Both Port-B and Port-C
> +  Bits 13 = TV Hotplug
> +  Bits [12:11]  = LFP configuration
> +                = 00b,  No LVDS
> +                = 01b,  Integrated LVDS
> +                = 10b,  SDVO LVDS
> +                = 11b,  eDP
> +  Bit 10 = Obsolete field: CRT hotplug
> +          = 0, Disabled
> +          = 1, Enabled (Default)
> +  Bit 9 = SDVO device power down
> +        = 0, Disabled (Default)
> +        = 1, Enabled
> +  Bit 8 = Preserve Aspect Ratio
> +        = 0, Disabled (Default)
> +        = 1, Enabled
> +  Bit 7 = Display "Maintain Aspect Scaling" via CUI
> +        = 0, No
> +        = 1, Yes (Default)
> +  Bit 6 = Sprite Display Assignment when Overlay is Active in Clone Mode:
> +        = 0, Secondary
> +        = 1, Primary
> +  Bit 5 = Default Power Scheme user interface
> +        = 0, CUI
> +        = 1, 3rd Party Application
> +  Bit 4 = NT 4.0 Dual Display Clone Support
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 3 = Default Render Clock Frequency
> +        = 0, High Frequency
> +        = 1, Low Frequency
> +  Bit 2 = Dual-Frequency Graphics Technology
> +        = 0, No
> +        = 1, Yes
> +  Bit 1 = Selective Mode Pruning
> +        = 0, No
> +        = 1, Yes
> +  Bit 0 = Enable LFP as primary
> +        = 0, Disable
> +        = 1, Enable
> +**/
> +  UINT16  bmp_Ext_Driver_Bits;
> +
> +  /**
> +  This defines the driver flags related to CUI Hot key.\n
> +  Bits [7:3] - Reserved
> +  Bit 2 = Display Subsystem Enable/Disable
> +        = 0, Enable (default Value)
> +        = 1, Disable
> +  Bit 1 = Embedded Platform
> +        = 0, False
> +        = 1, True
> +  Bit 0 = Define CUI HotK Displays Statically
> +        = 0, No
> +        = 1, Yes
> +  **/
> +  UINT8   bmp_Display_Detect_CUIHotK;
> +
> +  UINT16  bmp_Legacy_CRT_Max_X;         ///< Obsolete field: Defines the
> legacy CRT X resolution for driver boot mode.
> +  UINT16  bmp_Legacy_CRT_Max_Y;         ///< Obsolete field: Defines the
> legacy CRT Y resolution for driver boot mode.
> +  UINT8   bmp_Legacy_CRT_Max_RR;        ///< Obsolete field: Defines the
> legacy CRT refresh rate for driver boot mode.
> +
> +  /**
> +  This field defines the extended driver bits 2.\n
> +  Bits [7:1] - Reserved
> +  Bit 0 = Enable Internal Source Termination for HDMI
> +        = 0, External Termination
> +        = 1, Internal Termination
> +  **/
> +  UINT8   bmp_Ext2_Driver_Bits;
> +
> +  UINT8   bmp_VBT_Customization_Version;  ///< Defines the customized
> VBT version number.
> +
> +  /**
> +  This field defines all the driver feature flags.\n
> +  Bit 15 = PC Features Field's Validity
> +         = 0, Invalid
> +         = 1, Valid
> +  Bit 14 = Hpd_wake - HPD events are routed to display driver when system is
> in S0ix/DC9
> +         = 0, Disable
> +         = 1, Enable
> +  Bit 13 = Assertive Display Technology (ADT)
> +         = 0, Disable
> +         = 1, Enable
> +  Bit 12 = Dynamic Media Refresh Rate Switching (DMRRS)
> +         = 0, Disable
> +         = 1, Enable
> +  Bit 11 = Dynamic Frames Per Second (DFPS)
> +         = 0, Disable
> +         = 1, Enable
> +  Bit 10 = Intermediate Pixel Storage (IPS)
> +         = 0, Disable
> +         = 1, Enable
> +  Bit 9 = Panel Self Refresh (PSR)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 8 = Intel Turbo Boost Technology
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 7 = Graphics Power Modulation Technology (GPMT)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 6 = Graphics Render Standby (RS)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 5 = Intel Display Refresh Rate Switching (DRRS)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 4 = Intel Automatic Display Brightness (ADB)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 3 = DxgkDDI Backlight Control (DxgkDdiBLC)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 2 = Intel Display Power Saving Technology (DPST)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 1 = Intel Smart 2D Display Technology (S2DDT)
> +        = 0, Disable
> +        = 1, Enable
> +  Bit 0 = Intel Rapid Memory Power Management (RMPM)
> +        = 0, Disable
> +        = 1, Enable
> +  **/
> +  UINT16  bmp_Driver_Feature_Flags;
> +} BLOCK12_DRIVER_FEATURES;
> +
> +/**
> +  This defines the structure of Block 13 (Driver Persistence Options)
> +**/
> +typedef struct {
> +  UINT8   BlockId;                ///< Defines the unique Block ID : 13
> +  UINT16  BlockSize;              ///< Defines the size of Driver Persistence
> options block.
> +
> +  /**
> +  Defines the various persistence options.\n
> +  Bits [15:10] - Reserved
> +  Bit 9 = Docking Persistence Algorithm
> +        = 0, OS Default
> +        = 1, Driver Default
> +  Bit 8 = DVO Hot Plug Persistence on Mode
> +  Bit 7 = EDID Persistence on Mode
> +  Bit 6 = Hot Key Persistence on Mode
> +        = 0, No
> +        = 1, Yes
> +  Bit 5 = Hot Key Persistence on RestorePipe
> +        = 0, No
> +        = 1, Yes
> +  Bit 4 = Hot Key Persistence on RefreshRate
> +        = 0, No
> +        = 1, Yes
> +  Bit 3 = Hot Key Persistence on MDS/Twin
> +        = 0, No
> +        = 1, Yes
> +  Bit 2 = Power Management Persistence Algorithm
> +        = 0, OS Default
> +        = 1, Driver Default
> +  Bit 1 = Lid Switch Persistence Algorithm
> +        = 0, OS Default
> +        = 1, Driver Default
> +  Bit 0 = Hot Key Persistence Algorithm
> +        = 0, OS Default
> +        = 1, Driver Default
> +  **/
> +  UINT16  PersistenceAlgorithm;
> +
> +  UINT8   PersistMaxconfig;       ///< Maximum mode persistence
> configurations (10-200)
> +} BLOCK13_DRIVER_PERSISTENCE;
> +
> +/**
> +  This defines the structure of Block 17 (SV Bits)
> +**/
> +typedef struct {
> +  UINT8   BlockId;      ///< Defnies the unique Block ID : 17
> +  UINT16  BlockSize;    ///< Defines the size of SV Bits block.
> +
> +  /**
> +  Bits [7:4] = Reserved
> +    Bit3  = Allow VBlank/VblankScanline timeout hang
> +          = 0, Disable
> +          = 1, Enable
> +    Bit2  = Special GMBus support
> +          = 0, Disable
> +          = 1, Enable
> +    Bit1  = Skip program pipe timings when set VGA modes
> +          = 0, Setmode skip DVO Update
> +          = 1, Setmode updates DVO
> +    Bit0  = Disable VGA fast arbiter
> +          = 0, Enabled
> +          = 1, Disabled
> +  **/
> +  UINT8   SvBits1;
> +  UINT8   SvBits2;      ///< Reserved for future use.
> +  UINT8   SvBits3;      ///< Reserved for future use.
> +  UINT8   SvBits4;      ///< Reserved for future use.
> +  UINT8   SvBits5;      ///< Reserved for future use.
> +  UINT8   SvBits6;      ///< Reserved for future use.
> +  UINT8   SvBits7;      ///< Reserved for future use.
> +  UINT8   SvBits8;      ///< Reserved for future use.
> +} BLOCK17_SV_BITS;
> +
> +/**
> +  This defines the structure of Block 18 (Driver Rotation)
> +**/
> +typedef struct {
> +  UINT8   BlockId;                    ///< Defines the unique Block ID : 18
> +  UINT16  BlockSize;                  ///< Defines the size of Driver Rotation
> block.
> +  UINT8   RotationFeatureSupport;     ///< Rotation feature support field
> used by driver.
> +  UINT8   Reserved1;                  ///< Reserved for future use.
> +  UINT16  Reserved2;                  ///< Reserved for future use.
> +  UINT32  Reserved3;                  ///< Reserved for future use.
> +  UINT32  Reserved4;                  ///< Reserved for future use.
> +} BLOCK18_DRIVER_ROTATION;
> +
> +/**
> +  This structure defines an entry of OEM mode table.
> +**/
> +typedef struct {
> +  /**
> +  Mode Flags:
> +    Bits[7:3] = Reserved
> +    Bit 2 = Enable/disable this OEM mode in GOP driver.
> +    Bit 1 = Enable/disable this mode in Driver
> +    Bit 0 = Enable/disable this mode in VBIOS
> +  **/
> +  UINT8   ModeFlags;
> +
> +  /**
> +  Display Device Flags:
> +    Bit 7 = LFP2
> +    Bit 6 = EFP2
> +    Bit 5 = EFP3
> +    Bit 4 = EFP4
> +    Bit 3 = LFP
> +    Bit 2 = EFP
> +    Bit 1 = Rsvd
> +    Bit 0 = Rsvd
> +  **/
> +  UINT8   DisplayFlags;
> +  UINT16  XRes;         ///< Defines the X resolution of the mode.
> +  UINT16  YRes;         ///< Defines the Y resolution of the mode.
> +
> +  /**
> +  Defines the bits per pixel of the mode.
> +    Bit 7:3 = Reserved
> +    Bit 2 = 32 BPP
> +    Bit 1 = 16 BPP
> +    Bit 0 = 8 BPP
> +  **/
> +  UINT8   Bpp;
> +  UINT8   RRate;        ///< Defines the refresh rate of the mode.
> +  DTD_STRUCTURE Dtd;    ///< Defines the 18 byte timing config for the
> mode.
> +} OEM_MODE_ENTRY;
> +
> +/**
> +  This defines the structure of Block 20 (OEM Mode Customization Block)
> +**/
> +typedef struct {
> +  UINT8           BlockId;          ///< Defines the unique block ID : 20
> +  UINT16          BlockSize;        ///< Defines the size of OEM customization
> block.
> +  UINT8           NumOfEntry;       ///< Defines the number of entries in OEM
> Mode table.
> +  UINT8           EntrySize;        ///< Defines the size of one entry of OEM
> Mode table.
> +  OEM_MODE_ENTRY  OemModeTable[6];  ///< Array defining the OEM
> mode table.
> +} BLOCK20_OEM_CUSTOMIZATION;
> +
> +/**
> +  This defines the structure of Block 26 (TV options)
> +**/
> +typedef struct {
> +  UINT8   BlockId;                  ///< Defines the unique Block ID : 26
> +  UINT16  BlockSize;                ///< Defines the size of TV Options block.
> +
> +  /**
> +  Defines the TV options:
> +    Bit 15  = D-Conector Support
> +            = 0, Disable
> +            = 1, Enable
> +    Bit 14 = Add 1776x1000 when 1080i is selected and add 1184x666 when
> 720p is selected
> +            = 0, Disable
> +            = 1, Enable
> +    Bit 13:12 Underscan/overscan for HDTV via DVI
> +            = 00b, Enable Underscan and Overscan modes (Default)
> +            = 01b, Enable only overscan modes
> +            = 10b, Enable only underscan modes
> +    Bits 11:2 = Reserved
> +    Bit 1:0 = Underscan/overscan for HDTV via Component (YPrPb)
> +            = 00b, Enable Underscan and Overscan modes (Default)
> +            = 01b, Enable only overscan modes
> +            = 10b, Enable only underscan modes
> +  **/
> +  UINT16  bmp_TV_Options_1;
> +} BLOCK26_TV_OPTIONS;
> +
> +/**
> +  This structure defines the eDP panel power sequencing parameters.
> +**/
> +typedef struct {
> +  UINT16  T3;         ///< Panel Power-Up Delay.
> +  UINT16  T8;         ///< Panel Power-On to backlight Enable Delay.
> +  UINT16  T9;         ///< Backlight-Off to Power-Down Delay.
> +  UINT16  T10;        ///< Power-Down Delay.
> +  UINT16  T12;        ///< Power Cycle Delay.
> +} EDP_PWR_SEQ;
> +
> +/**
> +  This structure defines the PWM<-->Backlight delays for a single eDP panel.
> +**/
> +typedef struct {
> +  UINT16  PwmOnToBacklightEnableDelay;      ///< PWM on to backight
> enable delay.
> +  UINT16  BacklightDisableToPwmOffDelay;    ///< Backlight disable to PWM
> off delay.
> +} EDP_PWM_BACKLIGHT_DELAYS;
> +
> +/**
> +  This defines FLT parameters for a single eDP panel.
> +  Bits[15:12] : VSwing level
> +            0 : 0.4V (default)
> +            1 : 0.6V
> +            2 : 0.8V
> +            3 : 1.2V
> +       Others : Reserved
> +  Bits[11:8]  : Pre-emphasis level
> +            0 : no pre-emphasis (default)
> +            1 : 3.5dB
> +            2 : 6dB
> +            3 : 9.5dB
> +       Others : Reserved
> +  Bits[7:4]   : Lane count (port width)
> +            0 : x1 mode (default)
> +            1 : x2 mode
> +            2 : Reserved
> +            3 : x4 mode
> +       Others : Reserved
> +  Bits[3:0]   : data rate
> +            0 : 1.62 Gbps
> +            1 : 2.7 Gbps
> +            2 : 5.4 Gbps
> +       Others : Reserved
> +**/
> +typedef union {
> +  UINT16 Value;
> +  struct {
> +    UINT16 DataRate:4;
> +    UINT16 LaneCount:4;
> +    UINT16 PreEmphasisLevel:4;
> +    UINT16 VSwingLevel:4;
> +  } Bits;
> +} EDP_FAST_LINK_TRAINING_PARAMS;
> +
> +/**
> +  This defines Full link training parameters for a single eDP panel.
> +  Bits[7:4] : VSwing level
> +          0 : 0.4V (default)
> +          1 : 0.6V
> +          2 : 0.8V
> +          3 : 1.2V
> +     Others : Reserved
> +  Bits[3:0] : Pre-emphasis level
> +          0 : no pre-emphasis (default)
> +          1 : 3.5dB
> +          2 : 6dB
> +          3 : 9.5dB
> +     Others : Reserved
> +**/
> +typedef union {
> +  UINT8   Value;
> +  struct {
> +    UINT8   PreEmphasisLevel:4;
> +    UINT8   VSwingLevel:4;
> +  } Bits;
> +} EDP_FULL_LINK_TRAINING_PARAMS;
> +
> +/**
> +  This defines the structure of Apical Parameters for a single eDP panel.
> +**/
> +typedef struct {
> +  UINT32      PanelOui;             ///< Apical IP specific field for Panel OUI
> +  UINT32      DPCDBaseAddress;      ///< Apical IP specific field for DPCD Base
> address
> +  UINT32      DPCDIrdidixControl0;  ///< Apical IP specific field for DPCD
> Idridix Control 0
> +  UINT32      DPCDOptionSelect;     ///< Apical IP specific field for DPCD
> option select
> +  UINT32      DPCDBacklight;        ///< Apical IP specific field for DPCD
> backlight
> +  UINT32      AmbientLight;         ///< Apical IP specific field for Ambient
> light
> +  UINT32      BacklightScale;       ///< Apical IP specific field for backlight
> scale
> +} EDP_APICAL_PARAMS;
> +
> +/**
> +  This defines the structure of Block 27 (eDP Display Block)
> +**/
> +typedef struct {
> +  UINT8       BlockId;            ///< Defines the unique Block ID : 27
> +  UINT16      BlockSize;          ///< Defines the size of eDP display VBT block.
> +
> +  EDP_PWR_SEQ eDP_PWR_SEQ[16];    ///< Array defining the panel power
> sequencing for all 16 eDP panels.
> +
> +  /**
> +  Defines the panel color depth in bits per pixel. 2 Bits for each Panel.
> +    Bits[1:0] Panel color depth for Panel #1
> +      = 00, 18bpp
> +      = 01, 24bpp
> +      = 10, 30bpp
> +      = 11, 36bpp
> +  **/
> +  UINT32      eDP_Panel_Color_Depth;
> +
> +  /**
> +    Array containing the FLT parameters of 16 eDP panels.
> +  **/
> +  EDP_FAST_LINK_TRAINING_PARAMS
> eDP_Fast_Link_Training_Params[16];
> +
> +  /**
> +  This field defines the eDP sDRRS MSA Timing Delay for all 16 eDP panels. 2
> Bits for Each Panel.
> +  Bits[1:0] for Panel #1
> +    = 00, Line 1
> +    = 01, Line 2
> +    = 10, Line 3
> +    = 11, Line 4
> +  **/
> +  UINT32      eDP_sDRRS_MSA_Delay;
> +
> +  /**
> +  Defines the S3D feature enable/disable for all 16 eDP panels. 1 Bit for Each
> Panel.
> +  Bits[0] for Panel #1
> +    = 0, S3D disabled for this panel
> +    = 1, S3D enabled for this panel
> +  **/
> +  UINT16      eDP_S3D_Feature;
> +
> +  /**
> +  Defines the T3 optimization enable/disable for all 16 panels. 1 Bit for each
> panel.
> +  Bits[0] = Panel #1
> +    = 0, T3 optimization disabled for this panel
> +    = 1, T3 optimization enabled for this panel
> +  **/
> +  UINT16      eDP_T3_Optmization;
> +
> +  /**
> +  Defines the Edp vswing and pre-emphasis for all 16 panels. 4 Bits for Each
> Panel
> +  Bits[3:0] = Panel #1
> +    = 0, Use table 1 for this panel.
> +    = 1, Use table 2 for this panel.
> +  **/
> +  UINT64       VswingPreEmphasisTableNum;
> +
> +  /**
> +  Defines the Edp fast link training support on all 16 panels. 1 Bit for Each
> Panel
> +  Bits[0] = Panel #1
> +    = 0, FastLinkTraining feature is disabled for this panel
> +    = 1, FastLinkTraining feature is enabled for this panel
> +  **/
> +  UINT16     EdpFastLinkTrainingSupportOnPanel;
> +
> +  /**
> +  Defines whether the Set power state at DPCD 600h is to be done in eDP
> enable/disable sequence.
> +  Bits[0] = Panel #1
> +    = 0, Set power state at DPCD 600h feature is disabled for this panel
> +    = 1, Set power state at DPCD 600h feature is enabled for this panel
> +  **/
> +  UINT16     SetPowerStateAtDPCD600h; //This is not used currently
> +
> +  /**
> +    Array defining the PWM <--> Backlight related delays for 16 panels.
> +  **/
> +  EDP_PWM_BACKLIGHT_DELAYS eDP_Pwm_BackLight_Delays[16];
> +
> +  /**
> +  Defines the Edp full link training support on all 16 panels. 1 Bit for Each
> Panel.
> +  \verbatim
> +  Bits[0] : Panel #1
> +        0 : Initial vswing and pre-emphasis levels are not provided for Full link
> training
> +        1 : Initial vswing and pre-emphasis levels are provided for Full link
> training
> +  Bits 1 to 15 are for panel # 2 to 16.
> +  \endverbatim
> +  **/
> +  UINT16     InitialFullLinkTrainingParamsProvidedInVbt;
> +
> +  /**
> +    Array containing the initial Vswing and Pre-emphasis parameters for Full
> link training.
> +  **/
> +  EDP_FULL_LINK_TRAINING_PARAMS
> eDP_Full_Link_Training_Params[16];
> +
> +  /**
> +  Defines the Edp Apical assertive display IP support on all 16 panels. 1 Bit for
> Each Panel.
> +  Bit 0   : Panel #1
> +        0 : Apical assertive display IP is disabled for this panel.
> +        1 : Apical assertive display IP is enabled for this panel.
> +  Bits 1 to 15 are for panel # 2 to 16.
> +  **/
> +  UINT16                           IsApicalAssertiveDisplayIpEnable;
> +
> +  /**
> +    Array containing the Apical parameters for all 16 panels
> +  **/
> +  EDP_APICAL_PARAMS                eDP_Apcial_Params[16];
> +} BLOCK27_EDP_FEATURES;
> +
> +/**
> +  This defines the structure of Block 28 (Edidless EFP support DTD timings)
> +**/
> +typedef struct {
> +  UINT8                 BlockId;                    ///< Defines the unique Block ID :
> 28
> +  UINT16                BlockSize;                  ///< Defines the size of Edidless
> EFP support block.
> +  DTD_STRUCTURE         Edidless_EFP_DTD_Struc[4];  ///< Array defining
> the DTD timing for 3 EFP devices.
> +} BLOCK28_EDIDLESS_EFP;
> +
> +/**
> +This defines the structure of toggle list entry.
> +**/
> +typedef struct {
> +  /**
> +  Defines the display device selection for toggling
> +  Bit 15 = EFP4.3 (Reserved for WHL)
> +  Bit 14 = EFP3.3
> +  Bit 13 = EFP2.3
> +  Bit 12 = EFP1.3
> +  Bit 11 = EFP4.2 (Reserved for WHL)
> +  Bit 10 = EFP3.2
> +  Bit 9  = EFP2.2
> +  Bit 8  = EFP1.2
> +  Bit 7  = LFP2
> +  Bit 6  = EFP2
> +  Bit 5  = EFP3
> +  Bit 4  = EFP4
> +  Bit 3  = LFP
> +  Bit 2  = EFP
> +  Bit 1  = TV
> +  Bit 0  = CRT
> +  **/
> +  UINT16  DisplayDevice;
> +} CNL_TOGGLE_LIST_ENTRY;
> +
> +/**
> +  This defines the structure of Block 31 (Toggle Lists for Cannonlake)
> +**/
> +typedef struct {
> +  UINT8                   BlockId;              ///< Defines the unique Block ID : 31
> +  UINT16                  BlockSize;            ///< Defines the size of Toggle List
> Block.
> +  UINT16                  NumOfEntry1;          ///< Defines the number of
> entries in toggle list 1.
> +  UINT8                   EntrySize1;           ///< Defines the size of toggle list
> entry present in list 1.
> +  CNL_TOGGLE_LIST_ENTRY   ToggleList1Entry[16]; ///< Array defining the
> toggle list 1.
> +  UINT16                  NumOfEntry2;          ///< Defines the number of
> entries in toggle list 2.
> +  UINT8                   EntrySize2;           ///< Defines the size of toggle list
> entry present in list 2.
> +  CNL_TOGGLE_LIST_ENTRY   ToggleList2Entry[8];  ///< Array defining the
> toggle list 2.
> +  UINT16                  NumOfEntry3;          ///< Defines the number of
> entries in toggle list 3.
> +  UINT8                   EntrySize3;           ///< Defines the size of toggle list
> entry present in list 3.
> +  CNL_TOGGLE_LIST_ENTRY   ToggleList3Entry[8];  ///< Array defining the
> toggle list 3.
> +  UINT16                  NumOfEntry4;          ///< Defines the number of
> entries in toggle list 4.
> +  UINT8                   EntrySize4;           ///< Defines the size of toggle list
> entry present in list 4.
> +  CNL_TOGGLE_LIST_ENTRY   ToggleList4Entry[8];  ///< Array defining the
> toggle list 4.
> +} BLOCK31_TOGGLE_LIST;
> +
> +/**
> +  This defines the structure of Display device removal configuration entry.
> +**/
> +typedef struct {
> +  /**
> +  Defines the display device configuration to be removed.
> +  Bit 15 = EFP4.3 (Reserved for WHL)
> +  Bit 14 = EFP3.3
> +  Bit 13 = EFP2.3
> +  Bit 12 = EFP1.3
> +  Bit 11 = EFP4.2 (Reserved for WHL)
> +  Bit 10 = EFP3.2
> +  Bit 9  = EFP2.2
> +  Bit 8  = EFP1.2
> +  Bit 7  = LFP2
> +  Bit 6  = EFP2
> +  Bit 5  = EFP3
> +  Bit 4  = EFP4
> +  Bit 3  = LFP
> +  Bit 2  = EFP
> +  Bit 1  = TV
> +  Bit 0  = CRT
> +  **/
> +  UINT16  DisplayDeviceConfiguration;
> +} CNL_DISPLAY_CONFIGURATION_ENTRY;
> +
> +/**
> +  This defines the structure of Block 32 (Display removal configuration Block)
> +**/
> +typedef struct {
> +  UINT8                                BlockId;       ///< Defines the unique Block ID
> = 32
> +  UINT16                               BlockSize;     ///< Defines the size of Display
> removal configuration block.
> +  UINT8                                NumOfEntry;    ///< Defines the number of
> entries in display removal configuraion table.
> +  UINT8                                EntrySize;     ///< Defines the size of 1 entry in
> display removal configuration table.
> +  CNL_DISPLAY_CONFIGURATION_ENTRY
> RemoveDisplayConfiguration[15];    ///< Array defining the display removal
> configuration table.
> +}BLOCK32_DISPLAY_CONFIGURATION_REMOVAL;
> +
> +/**
> +  This defines the Local Flat panel basic details such as resolution and the
> various registers.
> +**/
> +typedef struct {
> +  UINT16  XRes;                   ///< X resolution of the panel.
> +  UINT16  YRes;                   ///< Y resolution of the panel.
> +  UINT32  LVDSDigDisReg;          ///< MMIO offset of LFP digital display port
> register.
> +  UINT32  LVDSDigDisVal;          ///< Value of LFP digital display port register.
> +  UINT32  OnSeqDelayReg;          ///< MMIO offset of Panel power on
> sequencing delay register.
> +  UINT32  OnSeqDelayVal;          ///< Value of Panel power on sequencing
> delay register.
> +  UINT32  OffSeqDelayReg;         ///< MMIO offset of Panel power off
> sequencing delay register.
> +  UINT32  OffSeqDelayVal;         ///< Value of Panel power off sequencing
> delay register.
> +  UINT32  CycleDelay_RefDivReg;   ///< MMIO offset of Panel power cycle
> delay and reference divider register.
> +  UINT32  CycleDelay_RefDivVal;   ///< Value of Panel power cycle delay and
> reference divider register.
> +  UINT16  Terminate;              ///< Special value 0xFFFF indicating end of
> data.
> +} FP_DATA;
> +
> +/**
> +  This defines the structure consisting of all details for a single Local Flat
> panel.
> +**/
> +typedef struct {
> +  FP_DATA       FP_Data;      ///< Instance of ::FP_DATA structure.
> +  DTD_STRUCTURE DTD_Data;     ///< Instance of ::DTD_STRUCTURE which
> contains the DTD timings for the panel.
> +  PID_DATA      PID_Data;     ///< Instance of ::PID_DATA structure which
> contains panel related information used by driver.
> +} LVDS_FP_TABLE;
> +
> +/**
> +  This structure defines all the details regarding Backlight control for LFP.
> +**/
> +typedef struct {
> +  /**
> +  Defines the backlight features for the panel.
> +  Bits 7:6  = GMBus Speed:
> +            = 00, 100 KHz
> +            = 01, 50 KHz
> +            = 10, 400 KHz
> +            = 11, 1 MHz
> +  Bits 5:3  = Inverter GPIO Pins
> +            = 0, None
> +            = 1, I2C GPIO pins
> +            = 2, Analog CRT DDC pins
> +            = 3, DVI/LVDS DDC GPIO pins
> +            = 5, sDVO I2C GPIO pins
> +  Bit 2     = Inverter Polarity (i2c & PWM)
> +            = 0, Normal (0 = Minimum brightness)
> +            = 1, Inverted (0 = Maximum brightness)
> +  Bits 1:0  = BLC Inverter Type
> +            = 00, None/External
> +            = 01, i2c
> +            = 10, PWM
> +            = 11, Reserved
> +  **/
> +  UINT8   BLC_Ftr;
> +
> +  UINT16  PWM_Freq;       ///< PWM inverter frequency in KHz
> +  UINT8   Min_Brightness; ///< Minimum brightness in the range 0-255
> +  UINT8   I2C_Add;        ///< I2C Inverter Slave Address
> +  UINT8   I2C_Command;    ///< I2C Inverter command code
> +} BLC;
> +
> +/**
> +  This defines the structure of Block 40 (LFP Features)
> +**/
> +typedef struct {
> +  UINT8   BlockId;          ///< Defines the unique Block ID : 40
> +  UINT16  BlockSize;        ///< Defines the size of LFP Features block.
> +
> +  UINT8   bmp_Panel_type;   ///< Defines the panel type of LFP.
> +  UINT8   Skip1;            ///< Obsoleted.
> +
> +  /**
> +  Capabilities byte:
> +  Bit 15:7  = SW Workaround bits
> +  Bit 6     = Panel EDID support
> +            = 0, Disable
> +            = 1, Enable
> +  Bit 5     = Pixel dithering
> +            = 0, Disable
> +            = 1, Enable
> +  Bit 4     = Panel Fitting ratio calc.
> +            = 0 - Manual
> +            = 1 - Automatic
> +  Bit 3     = Panel Fitting Graphics mode
> +            = 0, Bilinear
> +            = 1, Enhanced
> +  Bit 2     = Panel Fitting Text mode
> +            = 0, Bilinear
> +            = 1, Enhanced
> +  Bit 1:0   = Panel Fitting Support
> +            = 00, No panel fitting
> +            = 01, Text panel fitting
> +            = 10, GFX panel fitting
> +            = 11, Text+GFX panel fitting
> +  **/
> +  UINT16  bmp_LVDS_Capabilities;
> +
> +  /**
> +  Defines the channel type of LFP. 2 Bits for each Panel.
> +  Bits [0:1] for Panel #1
> +    = 00, Automatic (algorithm)
> +    = 01, Single Channel
> +    = 10, Dual Channel
> +    = 11, Reserved
> +  **/
> +  UINT32  INT_LVDS_Panel_Channel_Bits;
> +
> +  UINT16  Enable_SSC_Bit;         ///< LVDS Spread Spectrum Clock
> +  UINT16  SSC_Freq_Bit;           ///< LVDS Spread Spectrum Clock Frequency
> +  UINT16  Disable_SSC_DDT_Bit;    ///< Disable SSC in Dual Display Twin
> +
> +  /**
> +  Defines the panel color depth. 1 Bits for each Panel.
> +  Bits[0] for Panel #01
> +    = 0, 18bpp
> +    = 1, 24bpp
> +  **/
> +  UINT16  INT_Panel_Color_Depth;
> +
> +  /**
> +  Defines the Panel type. 2 Bits for each Panel.
> +  Bits [0:1] for Panel #1
> +    = 00, Static DRRS
> +    = 01, D2PO
> +    = 10, Seamless
> +    = 11, Reserved
> +  **/
> +  UINT32  DPS_Panel_Type_Bits;
> +
> +  /**
> +  Defines the type of backlight control for the LFP. 2 bits for each Panel.
> +  Bits [0:1] for Panel #1
> +    = 00, Default
> +    = 01, CCFL backlight
> +    = 10, LED backlight
> +    = 11, Reserved
> +  **/
> +  UINT32  BLT_Control_Type_Bits;
> +  /**
> +  Defines the LFP power enable flag in S0 state for all 16 panels. 1 Bit for Each
> Panel.
> +  Bits[0] : Panel #1
> +        0 : Do not keep LCDVCC on during S0 state.
> +        1 : Keep LCDVCC on during S0 state.
> +  Bits 1 to 15 are for panel # 2 to 16.
> +  **/
> +  UINT16     LcdvccOnDuringS0State;
> +} BLOCK40_LVDS_FEATURES;
> +
> +/**
> +  This structure defines the second type of BMP table pointers.
> +  This is used to store pointers to LFP Flat panel data, DTD and PID
> information.
> +**/
> +typedef struct {
> +  UINT16  Offset;       ///< Offset of the table.
> +  UINT8   Size;         ///< Size of the table.
> +} BMP_TABLE_TYPE2_PTR;
> +
> +/**
> +  This structure defines a set of 3 pointers for LFP display.
> +  These pointers point to FP data, DTD and PID information respectively.
> +**/
> +typedef struct {
> +  BMP_TABLE_TYPE2_PTR   FpTablePtr;   ///< Pointer to FP Data of the LFP
> panel.
> +  BMP_TABLE_TYPE2_PTR   DtdTablePtr;  ///< Pointer to DTD of the LFP
> panel.
> +  BMP_TABLE_TYPE2_PTR   PidTablePtr;  ///< Pointer to the PID data of the
> LFP panel.
> +} LFP_TABLE_POINTERS;
> +
> +/**
> +  This defines the structure of Block 41 (LFP Table Pointers for FPDATA, DTD
> and PID)
> +**/
> +typedef struct {
> +  UINT8               BlockId;                  ///< Defines the unique Block ID:41
> +  UINT16              BlockSize;                ///< Defines the size of LFP Table
> Pointer Block.
> +  UINT8               NumOfEntries;             ///< Defines the number of
> entries in the Table.
> +  LFP_TABLE_POINTERS  LfpTablePointers[16];     ///< Array
> of ::LFP_TABLE_POINTERS for all 16 panels.
> +  UINT16              LfpPanelNameTableOffset;  ///< Offset of LFP panel
> names table.
> +  UINT8               LfpPanelNameLength;       ///< Length of a single LFP
> panel's name.
> +} BLOCK41_LFP_TABLE_POINTERS;
> +
> +/**
> +  This defines the structure of Block 42 (Complete LFP Panel Information)
> +**/
> +typedef struct {
> +  UINT8         BlockId;                ///< Defines the unique block ID : 42
> +  UINT16        BlockSize;              ///< Defines the size of Complete LFP
> panel information for all 16 panels.
> +  LVDS_FP_TABLE LVDS_FP_Table[16];      ///< Array of ::LVDS_FP_TABLE
> containing data of 16 panels.
> +  UINT8         LFP_PANEL_NAMES[16][13];///< Array defining the panel
> names for all 16 panels.
> +
> +  /**
> +  1 Bit for Each Panel
> +  Bit0  = Scaling feature for panel 1.
> +        = 0, Scaling feature is disabled for this panel.
> +        = 1, Scaling feature is enabled for this panel.
> +  **/
> +  UINT16        EnableScaling; //This is not used currently
> +
> +  /**
> +    Array defining DRRS minimum refresh rate. 1 Byte for Each Panel.
> +  **/
> +  UINT8         Seamless_DRRS_Min_RR[16];
> +
> +  /**
> +    Array defining Pixel Overlap Count. 1 Byte for Each Panel.
> +  **/
> +  UINT8         PixelOverlapCount[16];
> +} BLOCK42_LVDS_PANEL_INFO;
> +
> +typedef union {
> +  /**
> +  Backlight control parameters.\n
> +  Bits 7:4  : PWM Controller Selection
> +          0 : Controller 0
> +          1 : Controller 1
> +          2 : Controller 2
> +          3 : Controller 3
> +     Others : Reserved.
> +  Bits 3:0  : PWM Source Selection
> +          0 : PMIC PWM
> +          1 : LPSS PWM
> +          2 : DISPLAY PWM
> +          3 : CABC PWM
> +     Others : Reserved.
> +  **/
> +  UINT8 Value;
> +  struct {
> +    UINT8 PwmSourceSelection:4;
> +    UINT8 PwmControllerSelection:4;
> +  } Bits;
> +} BKLT_CTRL_PARAMS;
> +
> +/**
> +  This defines the structure of Block 43 (LFP Brightness Control)
> +**/
> +typedef struct {
> +  UINT8             BlockId;                ///< Defines the unique Block ID : 43
> +  UINT16            BlockSize;              ///< Defines the size of Brightness
> control block.
> +
> +  UINT8             SIZE_BLCStruc;          ///< Defines the size of single entry in
> Backlight control table for LFP.
> +  BLC               BLC_Struct[16];         ///< Array defining the backlight
> control for 16 LFP panels.
> +  UINT8             Post_Brightness[16];    ///< Array defining the initial
> brightness for all 16 panels.
> +  BKLT_CTRL_PARAMS  Brightness_Control[16]; ///< Array defining the
> brightness control method for all 16 panels
> +} BLOCK43_LVDS_BLC;
> +
> +/**
> +  This defines the structure of Block 44 (LFP Power Conservation Features)
> +**/
> +typedef struct {
> +  UINT8   BlockId;        ///< Defines the unique block ID : 44
> +  UINT16  BlockSize;      ///< Defines the size of LFP Power Conservation
> Features block.
> +  union {
> +  /**
> +  Bit[7]        : ALS Enable/Disable
> +               0 - Disable
> +               1 - Enable
> +  Bit[6]        : Display LACE support
> +               0 - Not supported
> +               1 - Supported
> +  Bit[5]        : Default Display LACE enabled status
> +               0 - Disabled
> +               1 - Enabled
> +  Bit[4]        : Reserved
> +  Bit[3:1]      : Power conservation preference level.
> +                 4 is default in a range of 1 to 6.
> +  Bit[0]        : Reserved
> +  **/
> +    UINT8  Value;
> +    struct {
> +      UINT8 Reserved:1;
> +      UINT8 PwrConservation:3;
> +      UINT8 Reserved_1:1;
> +      UINT8 DefalutDisplayLaceEnable:1;
> +      UINT8 DisplayLaceSupport:1;
> +      UINT8 AlsEnable:1;
> +    } Bits;
> +  } LfpFeatureBits;
> +
> +  UINT16  AlsData[10];    ///< Defines the main ALS data.
> +
> +  union {
> +  /**
> +  Bit[7:3]      : Reserved
> +  Bit[2:0]      : Aggressiveness Level Profile.
> +            000 - Minimum
> +            001 - Moderate
> +            010 - High
> +  **/
> +    UINT8  Value;
> +    struct {
> +      UINT8 AggressionProfileLevel:3;
> +      UINT8 Reserved:5;
> +    } Bits;
> +  } LaceAggressivenessProfile; ///< Defines the LACE Aggressiveness Profile
> +} BLOCK44_ALS;
> +
> +/**
> +  This defines the structure of Black Frame Insertion table entry.
> +**/
> +typedef struct {
> +  /**
> +  BFI Features\n
> +  Bit[7-2]  : Reserved\n
> +  Bit[1]    : Enable Brightness control in CUI\n
> +  Bit[0]    : Enable BFI in driver
> +  **/
> +  UINT8         EnableBits;
> +  UINT8         BrightnessNonBFI;   ///< Brightness percentage in non BFI
> mode
> +} BFI;
> +
> +/**
> +  This defines the structure of Block 45 (Black Frame insertion Support for LFP)
> +**/
> +typedef struct {
> +  UINT8              BlockId;         ///< Defines the unique Block ID : 45
> +  UINT16             BlockSize;       ///< Defines the size of Black frame
> insertion support block.
> +  UINT8              SIZE_BFIStruc;   ///< Defines the size of 1 entry of black
> frame data.
> +  BFI                BFI_Struct[16];  ///< Array defining the data of black frame
> insertion for all 16 panels.
> +} BLOCK45_BFI_SUPPORT;
> +
> +/**
> +  This structure defines the chromaticity information for a single LFP panel.
> +**/
> +typedef struct {
> +  /**
> +  Defines the chromaticity feature enable bits
> +  Bits 7:2  = Reserved
> +  Bit 1     = Override EDID values for chromaticity if enabled, Instead Use VBT
> values
> +            = 0, Disable, Use the EDID values
> +            = 1, Enable, Use the values from the VBT
> +  Bit 0     = Enable chromaticity feature. EDID values will be used when this
> feature is enabled.
> +            = 0, Disable
> +            = 1, Enable
> +  **/
> +  UINT8        EnableBits;
> +
> +  UINT8        Red_Green_1;   ///< Red/green chormaticity coordinates at
> EDID offset 19h
> +  UINT8        Blue_White_1;  ///< Blue/white chromatiity coordinates at
> EDID offset 1Ah
> +  UINT8        Red_X1;        ///< Red x coordinate at EDID offset 1Bh
> +  UINT8        Red_Y1;        ///< Red x coordinate at EDID offset 1Ch
> +  UINT8        Green_X1;      ///< Green x coordinate at EDID offset 1Dh
> +  UINT8        Green_Y1;      ///< Green x coordinate at EDID offset 1Eh
> +  UINT8        Blue_X1;       ///< Blue x coordinate at EDID offset 1Fh
> +  UINT8        Blue_Y1;       ///< Blue x coordinate at EDID offset 20h
> +  UINT8        White_X1;      ///< White x coordinate at EDID offset 21h
> +  UINT8        White_Y1;      ///< White x coordinate at EDID offset 22h
> +} CHROMATICITY;
> +
> +/**
> +  This structure defines the Luminance information for a single LFP panel.
> +**/
> +typedef struct {
> +  /**
> +  Defines the chromaticity feature enable bits
> +  Bits 7:2  : Reserved
> +  Bit 1     : Enable Gamma feature.
> +            : if enabled, use gamma values from this block.
> +          0 : Disable
> +          1 : Enable
> +  Bit 0     : Enable Luminance feature.
> +            : if enabled, use values from this block.
> +          0 : Disable
> +          1 : Enable
> +  **/
> +  UINT8        EnableBits;
> +  /**
> +    Luminance info (refer DisplayID 2.0)
> +    2 byte value, encoded in IEEE 754 half-precision binary floating point
> format
> +  **/
> +  UINT16      MinLuminance;           ///< Native minimum luminance
> +  UINT16      MaxFullFrameLuminance;  ///< Native maximum luminance
> (Full Frame)
> +  UINT16      MaxLuminance;           ///< Native Maximum Luminance (1%
> Rectangular Coverage)
> +  /**
> +    Gamma EOTF
> +    Gamma values range from 00h through FFh which will come from VBT.
> +    Value shall define the gamma range, from 1.00 to 3.54.
> +    Field Value = (Gamma (value from VBT) + 100) / 100
> +
> +    FFh = No gamma information shall be provided
> +  **/
> +  UINT8 Gamma;
> +
> +}LUMINANCE_AND_GAMMA;
> +
> +/**
> +  This defines the structure of Block 46 (Chromaticity Support)
> +**/
> +typedef struct {
> +  UINT8              BlockId;                 ///< Defines the unique Block ID : 46
> +  UINT16             BlockSize;               ///< Defines the size of Chromaticity
> Block.
> +  CHROMATICITY       Chromaticity_Struct[16]; ///< Defines the chromaticity
> information for all 16 panels.
> +  LUMINANCE_AND_GAMMA  Luminance_Gamma_Struct[16];    ///<
> Defines the lumianance information for all 16 panels.
> +} BLOCK46_CHROMATICITY_SUPPORT;
> +
> +/**
> +  This defines the structure of Block 51 (Fixed Mode Set)
> +**/
> +typedef struct{
> +  UINT8       BlockId;        ///< Defines the unique block ID : 51.
> +  UINT16      BlockSize;      ///< Defines the size of Fixed mode set feature
> block.
> +  UINT8       FeatureEnable;  ///< Whether the fixed mode set feature is
> enabled/disabled.
> +  UINT32      XRes;           ///< X resolution of the fixed mode.
> +  UINT32      YRes;           ///< Y resolution of the fixed mode.
> +} BLOCK51_FIXED_MODE_SET;
> +
> +/**
> +  This defines the Complete VBT Structure for generation purpose
> +**/
> +typedef struct {
> +  VBT_HEADER                                VbtHeader;
> +  VBT_BIOS_DATA_HEADER                      VbtBdbHeader;
> +  BLOCK254_BMP_Structure                    Block254BMPStructure;
> +  VBT_GENERAL1_INFO                         VbtGen1Info;
> +  PRD_BOOT_TABLE                            PrdBootTable;
> +  VBT_GENERAL2_INFO                         VbtGen2Info;
> +  BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST
> Block03OriginalDisplayToggleList;
> +  BLOCK252_SBIOS_Hook                       Block252SbiosHook;
> +  BLOCK06_MMIO_REG_TABLE                    Block06MmioRegTable;
> +  BLOCK07_IOSWFLAG_REG_TABLE                Block07IoswflagRegTable;
> +  BLOCK08_MMIOSWFLAG_REG_TABLE
> Block08MmioswflagRegTable;
> +  BLOCK09_PSR_FEATURE                       Block09PsrFeature;
> +  BLOCK10_MODE_REMOVAL_TABLE                Block10ModeRemovalTable;
> +  BLOCK12_DRIVER_FEATURES                   Block12DriverFeatures;
> +  BLOCK13_DRIVER_PERSISTENCE                Block13DriverPersistence;
> +  BLOCK17_SV_BITS                           Block17SvBits;
> +  BLOCK18_DRIVER_ROTATION                   Block18DriverRotation;
> +  BLOCK20_OEM_CUSTOMIZATION                 Block20OemCustomization;
> +  BLOCK26_TV_OPTIONS                        Block26TVOptions;
> +  BLOCK27_EDP_FEATURES                      Block27EDPFeatures;
> +  BLOCK28_EDIDLESS_EFP                      Block28EdidlessEFP;
> +  BLOCK31_TOGGLE_LIST                       Block31ToggleList;
> +  BLOCK32_DISPLAY_CONFIGURATION_REMOVAL
> Block32DisplayConfigurationRemoval;
> +  BLOCK40_LVDS_FEATURES                     Block40LVDSFeatures;
> +  BLOCK41_LFP_TABLE_POINTERS                Block41LfpTablePointers;
> +  BLOCK42_LVDS_PANEL_INFO                   Block42LvdsPanelInfo;
> +  BLOCK43_LVDS_BLC                          Block43LVDSBlc;
> +  BLOCK44_ALS                               Block44Als;
> +  BLOCK46_CHROMATICITY_SUPPORT
> Block46ChromaticitySupport;
> +  BLOCK51_FIXED_MODE_SET                    Block51FixedModeSet;
> +} VBT_TABLE_DATA;
> +
> +#pragma pack()
> +
> +/**
> +  This function will update the VBT checksum.
> +
> +  @param[in out] VbtPtr - Pointer to VBT table
> +
> +  @retval none
> +**/
> +VOID
> +UpdateVbtChecksum(
> +  VBT_TABLE_DATA *VbtPtr
> +);
> +
> +/**
> +  This function will update the VBT.
> +
> +  @param[in] VbtPtr - Pointer to VBT Table
> +
> +  @retval none
> +**/
> +VOID
> +UpdateGopVbt (
> +  IN  VBT_TABLE_DATA    *VbtPtr
> +);
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
> new file mode 100644
> index 0000000000..5bf2527963
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
> @@ -0,0 +1,41 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __TCO_WDT_HOB_H__
> +#define __TCO_WDT_HOB_H__
> +
> +#define TCO_WDT_HOB_GUID \
> +  { \
> +    0x3e405418, 0xd8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x8, 0x41, 0x46, 0x8d }
> \
> +  }
> +
> +#ifndef _PEI_HOB_H_
> +#ifndef __HOB__H__
> +#ifndef __PI_HOB_H__
> +typedef struct _EFI_HOB_GENERIC_HEADER {
> +  UINT16  HobType;
> +  UINT16  HobLength;
> +  UINT32  Reserved;
> +} EFI_HOB_GENERIC_HEADER;
> +
> +typedef struct _EFI_HOB_GUID_TYPE {
> +  EFI_HOB_GENERIC_HEADER  Header;
> +  EFI_GUID                Name;
> +  //
> +  // Guid specific data goes here
> +  //
> +} EFI_HOB_GUID_TYPE;
> +#endif
> +#endif
> +#endif
> +
> +typedef struct {
> +  EFI_HOB_GUID_TYPE Header;
> +  UINT8             TcoRebootHappened;
> +} TCO_WDT_HOB;
> +
> +#endif
> +
> diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
> new file mode 100644
> index 0000000000..671e3c5cde
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
> @@ -0,0 +1,68 @@
> +/** @file
> +  GPIO definition table for WhiskeylakeURvp
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _IO_EXPANDER_H_
> +#define _IO_EXPANDER_H_
> +
> +typedef struct {
> +  UINT32 IoExpanderNumber   : 1;  // IO Expander Number (0/1)
> +  UINT32 GpioPinNumber      : 5;  // GPIO Pin Number (0 to 23)
> +  UINT32 GpioDirection      : 1;  // GPIO Pin Direction (Input/Output)
> +  UINT32 GpioLevel          : 1;  // GPIO Pin Output Level (High/Low)
> +  UINT32 GpioInversion     : 1;  // GPIO Pin Inversion (Enabled/Disabled)
> +  UINT32 Reserved           : 23; // Reserved
> +} IO_EXPANDER_GPIO_CONFIG;
> +
> +//WHL PCH LP GPIO Expander Number
> +#define IO_EXPANDER_0            0
> +#define IO_EXPANDER_1            1
> +
> +//WHL PCH LP GPIO Pin Mapping
> +#define IO_EXPANDER_GPIO_0        0   // P00
> +#define IO_EXPANDER_GPIO_1        1   // P01
> +#define IO_EXPANDER_GPIO_2        2   // P02
> +#define IO_EXPANDER_GPIO_3        3   // P03
> +#define IO_EXPANDER_GPIO_4        4   // P04
> +#define IO_EXPANDER_GPIO_5        5   // P05
> +#define IO_EXPANDER_GPIO_6        6   // P06
> +#define IO_EXPANDER_GPIO_7        7   // P07
> +#define IO_EXPANDER_GPIO_8        8   // P10
> +#define IO_EXPANDER_GPIO_9        9   // P11
> +#define IO_EXPANDER_GPIO_10       10  // P12
> +#define IO_EXPANDER_GPIO_11       11  // P13
> +#define IO_EXPANDER_GPIO_12       12  // P14
> +#define IO_EXPANDER_GPIO_13       13  // P15
> +#define IO_EXPANDER_GPIO_14       14  // P16
> +#define IO_EXPANDER_GPIO_15       15  // P17
> +#define IO_EXPANDER_GPIO_16       16  // P20
> +#define IO_EXPANDER_GPIO_17       17  // P21
> +#define IO_EXPANDER_GPIO_18       18  // P22
> +#define IO_EXPANDER_GPIO_19       19  // P23
> +#define IO_EXPANDER_GPIO_20       20  // P24
> +#define IO_EXPANDER_GPIO_21       21  // P25
> +#define IO_EXPANDER_GPIO_22       22  // P26
> +#define IO_EXPANDER_GPIO_23       23  // P27
> +
> +//WHL PCH LP GPIO Expander GPIO Direction
> +#define IO_EXPANDER_GPIO_OUTPUT   0
> +#define IO_EXPANDER_GPIO_INPUT    1
> +
> +//WHL PCH LP GPIO Expaner GPIO Output Level
> +#define IO_EXPANDER_GPO_LEVEL_LOW    0
> +#define IO_EXPANDER_GPO_LEVEL_HIGH   1
> +
> +//WHL PCH LP GPIO Expaner GPIO Inversion Status
> +#define IO_EXPANDER_GPI_INV_DISABLED  0
> +#define IO_EXPANDER_GPI_INV_ENABLED   1
> +#define IO_EXPANDER_GPIO_RESERVED     0x00
> +
> +//GPIO Table Terminator
> +#define END_OF_GPIO_TABLE 0xFFFFFFFF
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyU
> pdateLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyU
> pdateLib.h
> new file mode 100644
> index 0000000000..5d5fba47ad
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyU
> pdateLib.h
> @@ -0,0 +1,75 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_CPU_POLICY_UPDATE_LIB_H_
> +#define _DXE_CPU_POLICY_UPDATE_LIB_H_
> +
> +#include <PiDxe.h>
> +#include <PchAccess.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/CpuPolicyProtocol.h>
> +
> +/**
> +
> +  This function prints the CPU DXE phase policy.
> +
> +  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
> +
> +**/
> +VOID
> +CpuDxePrintPolicyProtocol (
> +  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
> +  );
> +
> +/**
> +
> +Routine Description:
> +
> +  This function updates Dxe Cpu Policy Protocol
> +
> +Arguments:
> +
> +  @param[in] DxeCpuPolicy                 The Cpu Policy protocol instance
> +
> +Returns:
> +
> +  @retval EFI_SUCCESS                     Initialization complete.
> +  @retval 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
> +UpdateDxeSiCpuPolicy (
> +  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
> +  );
> +
> +/**
> +
> +  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol
> instance
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuInstallPolicyProtocol (
> +  IN  EFI_HANDLE                  ImageHandle,
> +  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUp
> dateLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyU
> pdateLib.h
> new file mode 100644
> index 0000000000..9b960159ba
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyU
> pdateLib.h
> @@ -0,0 +1,27 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_ME_POLICY_UPDATE_LIB_H_
> +#define _DXE_ME_POLICY_UPDATE_LIB_H_
> +
> +/**
> +  Update the ME Policy Library
> +
> +  @param[in] DxeMePolicy                The pointer to get ME Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS                   Initialization complete.
> +  @retval 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
> +UpdateDxeMePolicy (
> +  IN OUT  ME_POLICY_PROTOCOL      *DxeMePolicy
> +  );
> +
> +#endif // _DXE_ME_POLICY_UPDATE_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyU
> pdateLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyU
> pdateLib.h
> new file mode 100644
> index 0000000000..84db68e65c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyU
> pdateLib.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_PCH_POLICY_UPDATE_LIB_H_
> +#define _DXE_PCH_POLICY_UPDATE_LIB_H_
> +
> +/**
> +  Get data for platform policy from setup options.
> +
> +  @param[in] PchPolicy               The pointer to get PCH Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS               Operation success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxePchPolicy (
> +  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoard
> ConfigLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoard
> ConfigLib.h
> new file mode 100644
> index 0000000000..3bb941235c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoard
> ConfigLib.h
> @@ -0,0 +1,30 @@
> +/** @file
> +  Header file for the DxePolicyBoardConfig Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_POLICY_BOARD_CONFIG_LIB_H_
> +#define _DXE_POLICY_BOARD_CONFIG_LIB_H_
> +
> +#include <Protocol/MePolicy.h>
> +#include <Protocol/SaPolicy.h>
> +
> +/**
> +  This function performs DXE SA Policy update by board configuration.
> +
> +  @param[in, out] DxeSaPolicy     DXE SA Policy
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxeSaPolicyBoardConfig (
> +  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUp
> dateLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUp
> dateLib.h
> new file mode 100644
> index 0000000000..4279c0c6f1
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUp
> dateLib.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_SA_POLICY_UPDATE_LIB_H_
> +#define _DXE_SA_POLICY_UPDATE_LIB_H_
> +
> +/**
> +  Get data for platform policy from setup options.
> +
> +  @param[in] SaPolicy               The pointer to get SA Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS               Operation success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxeSaPolicy (
> +  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib
> .h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib
> .h
> new file mode 100644
> index 0000000000..4709179ac6
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib
> .h
> @@ -0,0 +1,29 @@
> +/** @file
> +  Function prototype of FspPolicyInitLib.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _FSP_POLICY_INIT_LIB_H_
> +#define _FSP_POLICY_INIT_LIB_H_
> +
> +#include <FspEas.h>
> +#include <FspmUpd.h>
> +#include <FspsUpd.h>
> +
> +VOID
> +EFIAPI
> +FspPolicyInitPreMem (
> +  IN FSPM_UPD           *FspmUpdDataPtr
> +  );
> +
> +VOID
> +EFIAPI
> +FspPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  );
> +
> +#endif // _FSP_POLICY_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConf
> lictLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConf
> lictLib.h
> new file mode 100644
> index 0000000000..ba73cad63b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConf
> lictLib.h
> @@ -0,0 +1,46 @@
> +/** @file
> +  Header file for check Gpio PadMode conflict.
> +
> +
> +  Copyright (c) 2019, 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 <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 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 UINT16                    GpioTableCount
> +  );
> +
> +#endif // _GPIO_CHECK_CONFLICT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderL
> ib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderL
> ib.h
> new file mode 100644
> index 0000000000..40ea4abc3d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderL
> ib.h
> @@ -0,0 +1,123 @@
> +/** @file
> +  Support for IO expander TCA6424.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_EXPANDER_LIB_H_
> +#define _GPIO_EXPANDER_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/DebugLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/UefiLib.h>
> +#include <PchAccess.h>
> +#include <Library/PchSerialIoLib.h>
> +
> +/**
> +  Set the Direction value for the given Expander Gpio pin.
> +
> +  This function is to Set the direction value for the GPIO
> +  Pin within the giving Expander.
> +
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +  @param[in]  Value       none
> +**/
> +VOID
> +GpioExpSetDirection (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin,
> +  IN UINT8 Direction
> +  );
> +/**
> +  Set the input value for the given Expander Gpio pin.
> +
> +  This function is to get the input value for the GPIO
> +  Pin within the giving Expander.
> +
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +  @param[in]  Value       none
> +
> +**/
> +VOID
> +GpioExpSetPolarity  (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin,
> +  IN UINT8 Polarity
> +  );
> +/**
> +  Set the Output value for the given Expander Gpio pin.
> +
> +  This function is to Set the Output value for the GPIO
> +  Pin within the giving Expander.
> +
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +  @param[in]  Value       none
> +
> +**/
> +VOID
> +GpioExpSetOutput    (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin,
> +  IN UINT8 Value
> +  );
> +/**
> +  Returns the data from register value giving in the input.
> +
> +  This function is to get the data from the Expander
> +  Registers by following the I2C Protocol communication
> +
> +
> +  @param[in]  Bar0       Bar address of the SerialIo Controller
> +  @param[in]  Address    Expander Value with in the Contoller
> +  @param[in]  Register   Address of Input/Output/Configure/Polarity
> +                         registers with in the Expander
> +
> +  @retval     UINT8      Value returned from the register
> +**/
> +UINT8
> +GpioExpGetInput     (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin
> +  );
> +
> +/**
> +  Configures all registers of a single IO Expander in one go.
> +
> +  @param[in]  Expander    Expander number (0/1)
> +  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc.
> 0=output, 1=input
> +  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0,
> etc. 0=normal, 1=inversion
> +  @param[in]  Output      Bit-encoded output state, ignores polarity, only
> applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
> +
> +**/
> +VOID
> +GpioExpBulkConfig (
> +  IN UINT8  Expander,
> +  IN UINT32 Direction,
> +  IN UINT32 Polarity,
> +  IN UINT32 Output
> +  );
> +
> +/**
> +  Returns the Controller on which GPIO expander is present.
> +
> +  This function returns the Controller value
> +
> +  @param[out] Controller              Pointer to a Controller value on
> +                                      which I2C expander is configured.
> +
> +  @retval     EFI_SUCCESS              non.
> +**/
> +EFI_STATUS
> +GpioExpGetController (
> +  OUT UINT8 *Controller
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLi
> b.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableL
> ib.h
> new file mode 100644
> index 0000000000..f08c88f114
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableL
> ib.h
> @@ -0,0 +1,48 @@
> +/** @file
> +
> +  Header file for the Intel HD Audio Verb Table library.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _HDA_VERB_TABLE_LIB_H_
> +#define _HDA_VERB_TABLE_LIB_H_
> +
> +#include <ConfigBlock/HdAudioConfig.h>
> +#include <Library/BaseLib.h>
> +
> +enum HDAUDIO_CODEC_SELECT {
> +  PchHdaCodecPlatformOnboard = 0,
> +  PchHdaCodecExternalKit     = 1
> +};
> +
> +/**
> +  Add verb table function.
> +  This function update the verb table number and verb table ptr of policy.
> +
> +  @param[in]  HdAudioConfig            HD Audio config block
> +  @param[out] VerbTableEntryNum        Number of verb table entries
> +  @param[out] HdaVerbTablePtr          Pointer to the verb table
> +**/
> +VOID
> +AddPlatformVerbTables (
> +  IN   UINT8              CodecType,
> +  OUT  UINT8              *VerbTableEntryNum,
> +  OUT  UINT32             *HdaVerbTablePtr
> +  );
> +
> +/**
> +  HDA VerbTable init function for PEI post memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +HdaVerbTableInit(
> +  IN UINT16 BoardId
> +  );
> +
> +#endif
> \ No newline at end of file
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
> new file mode 100644
> index 0000000000..cec045091b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
> @@ -0,0 +1,34 @@
> +/** @file
> +  Support for IO expander TCA6424.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _I2C_ACCESS_LIB_H_
> +#define _I2C_ACCESS_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/DebugLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/UefiLib.h>
> +#include <PchAccess.h>
> +#include <Library/PchSerialIoLib.h>
> +
> +#define WAIT_1_SECOND            1600000000 //1.6 * 10^9
> +
> +EFI_STATUS
> +I2cWriteRead (
> +  IN UINTN  MmioBase,
> +  IN UINT8  SlaveAddress,
> +  IN UINT8  WriteLength,
> +  IN UINT8  *WriteBuffer,
> +  IN UINT8  ReadLength,
> +  IN UINT8  *ReadBuffer,
> +  IN UINT64  TimeBudget
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.
> h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.
> h
> new file mode 100644
> index 0000000000..d65586dbb9
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.
> h
> @@ -0,0 +1,40 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_PLATFORM_LIB_H_
> +#define _PEI_PLATFORM_LIB_H_
> +
> +
> +
> +#define PEI_DEVICE_DISABLED 0
> +#define PEI_DEVICE_ENABLED  1
> +
> +typedef struct {
> +  UINT8   Register;
> +  UINT32  Value;
> +} PCH_GPIO_DEV;
> +
> +//
> +// GPIO Initialization Data Structure
> +//
> +typedef struct{
> +  PCH_GPIO_DEV Use_Sel;
> +  PCH_GPIO_DEV Use_Sel2;
> +  PCH_GPIO_DEV Use_Sel3;
> +  PCH_GPIO_DEV Io_Sel;
> +  PCH_GPIO_DEV Io_Sel2;
> +  PCH_GPIO_DEV Io_Sel3;
> +  PCH_GPIO_DEV Lvl;
> +  PCH_GPIO_DEV Lvl2;
> +  PCH_GPIO_DEV Lvl3;
> +  PCH_GPIO_DEV Inv;
> +  PCH_GPIO_DEV Blink;
> +  PCH_GPIO_DEV Rst_Sel;
> +  PCH_GPIO_DEV Rst_Sel2;
> +} GPIO_INIT_STRUCT;
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoard
> ConfigLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoard
> ConfigLib.h
> new file mode 100644
> index 0000000000..fe947482dc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoard
> ConfigLib.h
> @@ -0,0 +1,141 @@
> +/** @file
> +  Header file for the PeiPolicyBoardConfig Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_POLICY_BOARD_CONFIG_LIB_H_
> +#define _PEI_POLICY_BOARD_CONFIG_LIB_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  This function performs PEI CPU Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI ME Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiMePolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI PCH Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI SA Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSaPolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI CPU Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI ME Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiMePolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI PCH Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI SA Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSaPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  );
> +
> +/**
> +  This function performs PEI SI Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSiPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib
> .h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib
> .h
> new file mode 100644
> index 0000000000..15db1f1fbc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib
> .h
> @@ -0,0 +1,38 @@
> +/** @file
> +  Header file for the PolicyInitPei Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _POLICY_INIT_PEI_LIB_H_
> +#define _POLICY_INIT_PEI_LIB_H_
> +
> +/**
> +  Initialize Intel PEI Platform Policy
> +
> +  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that
> depends
> +                                     on the 'FirmwareConfiguration' varaible.
> +**/
> +VOID
> +EFIAPI
> +PeiPolicyInitPreMem (
> +  IN UINT8                     FirmwareConfiguration
> +  );
> +
> +/**
> +  Initialize Intel PEI Platform Policy
> +
> +  @param[in] PeiServices            General purpose services available to every
> PEIM.
> +  @param[in] FirmwareConfiguration  It uses to skip specific policy init that
> depends
> +                                    on the 'FirmwareConfiguration' varaible.
> +**/
> +VOID
> +EFIAPI
> +PeiPolicyInit (
> +//  IN CONST EFI_PEI_SERVICES    **PeiServices,
> +  IN UINT8                     FirmwareConfiguration
> +  );
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.
> h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib
> .h
> new file mode 100644
> index 0000000000..f0da2db968
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib
> .h
> @@ -0,0 +1,23 @@
> +/** @file
> +  Function prototype of PlatformInitLib.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_INIT_LIB_H_
> +#define _PLATFORM_INIT_LIB_H_
> +
> +VOID
> +PlatformLateInit (
> +  VOID
> +  );
> +
> +VOID
> +InitSerialPort (
> +  VOID
> +  );
> +
> +#endif // _PLATFORM_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
> new file mode 100644
> index 0000000000..8bf7deaa0c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
> @@ -0,0 +1,51 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef PCH_HSIO_PTSSTABLES_H_
> +#define PCH_HSIO_PTSSTABLES_H_
> +
> +#include <PchAccess.h>
> +
> +///
> +/// SATA PTSS Topology Types
> +///
> +typedef enum {
> +  PchSataTopoUnknown = 0x00,
> +  PchSataTopoIsata,
> +  PchSataTopoDirectConnect,
> +  PchSataTopoFlex,
> +  PchSataTopoM2
> +} PCH_SATA_TOPOLOGY;
> +
> +///
> +/// PCIe PTSS Topology Types
> +///
> +typedef enum {
> +  PchPcieTopoUnknown = 0x00,
> +  PchPcieTopox1,
> +  PchPcieTopox4,
> +  PchPcieTopoSataE,
> +  PchPcieTopoM2
> +} PCH_PCIE_TOPOLOGY;
> +
> +///
> +/// The PCH_SBI_PTSS_HSIO_TABLE block describes HSIO PTSS settings for
> PCH.
> +///
> +typedef struct {
> +  UINT8       LaneNum;
> +  UINT8       PhyMode;
> +  UINT16      Offset;
> +  UINT32      Value;
> +  UINT32      BitMask;
> +} PCH_SBI_PTSS_HSIO_TABLE;
> +
> +typedef struct {
> +  PCH_SBI_PTSS_HSIO_TABLE   PtssTable;
> +  UINT16                    Topology;
> +} HSIO_PTSS_TABLES;
> +
> +#endif // PCH_HSIO_PTSSTABLES_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTabl
> e.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTabl
> e.h
> new file mode 100644
> index 0000000000..395d08779c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTabl
> e.h
> @@ -0,0 +1,106 @@
> +/** @file
> +  PCIe Device Override Table
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _PCIE_DEVICE_OVERRIDE_TABLE_H_
> +#define _PCIE_DEVICE_OVERRIDE_TABLE_H_
> +
> +#include <ConfigBlock/PcieRpconfig.h>
> +#include <IndustryStandard/Pci22.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 },
> +
> +  //
> +  // End of Table
> +  //
> +  { 0 }
> +};
> +
> +#endif
> diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
> new file mode 100644
> index 0000000000..ea96227e3d
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
> @@ -0,0 +1,33 @@
> +/** @file
> +  This header file provides platform specific definitions used
> +  by other modules for platform specific initialization.
> +  This is not suitable for consumption by ASL or VRF files.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_H_
> +#define _PLATFORM_H_
> +
> +//#include "CommonDefinitions.h"
> +#include "PchAccess.h"
> +#include "SaAccess.h"
> +
> +//
> +// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
> +//
> +#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)
> // 80MB + 256MB
> +#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (10 * 0x800000 +
> 0x10000000)   // 80MB + 256MB
> +
> +#define FLASH_BLOCK_SIZE  0x10000
> +
> +#define CPU_EXTERNAL_CLOCK_FREQ  0x64
> +#define CPU_FREQUENCY_MODE_100  0x64
> +#define FREQUENCY_RESOLUTION_3182  0xc6e
> +#define NDIVIDER_BASE_VALUE  0x19d
> +#define MDIVIDER_VALUE_13  0xd
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
> new file mode 100644
> index 0000000000..3545b2a05c
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
> @@ -0,0 +1,29 @@
> +/** @file
> +Defines Platform BoardIds
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PLATFORM_BOARD_ID_H_
> +#define _PLATFORM_BOARD_ID_H_
> +
> +#define FlavorUnknown                       0x0
> +#define FlavorMobile                        0x1
> +#define FlavorDesktop                       0x2
> +#define FlavorWorkstation                   0x3
> +#define FlavorUpServer                      0x4
> +#define FlavorEmbedded                      0x5
> +#define FlavorPlatformMax                   0x6
> +
> +#define TypeUnknown                         0x0
> +#define TypeTrad                            0x1
> +#define TypeUltUlx                          0x2
> +
> +#define BoardIdWhiskeyLakeRvp               0x60
> +
> +#define BoardIdUnknown1                     0xffff
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsAre
> a.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsAre
> a.h
> new file mode 100644
> index 0000000000..b64cfff9a2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsAre
> a.h
> @@ -0,0 +1,47 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GLOBAL_NVS_AREA_H_
> +#define _GLOBAL_NVS_AREA_H_
> +
> +//
> +// Includes
> +//
> +#define GLOBAL_NVS_DEVICE_ENABLE 1
> +#define GLOBAL_NVS_DEVICE_DISABLE 0
> +
> +//
> +// Forward reference for pure ANSI compatibility
> +//
> +
> +typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL
> EFI_GLOBAL_NVS_AREA_PROTOCOL;
> +
> +//
> +// Global NVS Area Protocol GUID
> +//
> +#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
> +{ 0x74e1e48, 0x8132, 0x47a1, 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc }
> +
> +#define GLOBAL_NVS_AREA_REVISION       16
> +//
> +// Extern the GUID for protocol users.
> +//
> +extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
> +
> +//
> +// Global NVS Area definition
> +//
> +#include <Acpi/GlobalNvsAreaDef.h>
> +
> +//
> +// Global NVS Area Protocol
> +//
> +typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
> +  EFI_GLOBAL_NVS_AREA     *Area;
> +} EFI_GLOBAL_NVS_AREA_PROTOCOL;
> +
> +#endif
> +
> diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
> new file mode 100644
> index 0000000000..6dd6795a52
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
> @@ -0,0 +1,144 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SETUP__H__
> +#define __SETUP__H__
> +
> +#ifndef MDEPKG_NDEBUG
> +#define DEBUG_INTERFACE_FORM_ENABLE
> +#endif // MDEPKG_NDEBUG
> +//
> +// Form class guid for the forms those will be showed on first front page.
> +//
> +#define FRONT_PAGE_GUID        { 0xe58809f8, 0xfbc1, 0x48e2, { 0x88, 0x3a,
> 0xa3, 0xf, 0xdc, 0x4b, 0x44, 0x1e } }
> +//
> +// Form class guid for the forms those will be showed on boot maintenance
> manager menu.
> +//
> +#define BOOT_MAINTENANCE_GUID  { 0xb2dedc91, 0xd59f, 0x48d2, { 0x89,
> 0x8a, 0x12, 0x49, 0xc, 0x74, 0xa4, 0xe0 } }
> +
> +// VFR common Definitions
> +#define INVENTORY(Name,Value) \
> +    text \
> +      help  = STRING_TOKEN(STR_EMPTY), \
> +      text  = Name, \
> +      text  = Value, \
> +      flags = 0, \
> +      key   = 0;
> +
> +#define SUBTITLE(Text) subtitle text = Text;
> +#define SEPARATOR SUBTITLE(STRING_TOKEN(STR_EMPTY))
> +
> +#define INTERACTIVE_TEXT(HelpToken, CaptionToken, ValueToken, Key)\
> +  grayoutif TRUE;\
> +    oneof varid        = SETUP_DATA.InteractiveText,\
> +      questionid       = Key,\
> +      prompt           = CaptionToken,\
> +      help             = HelpToken,\
> +      option text      = ValueToken, value = 0, flags = INTERACTIVE | DEFAULT;\
> +      refresh interval = 1 \
> +    endoneof;\
> +  endif;
> +
> +#define SUPPRESS_GRAYOUT_ENDIF endif; endif;
> +#define DEFAULT_FLAG
> +
> +#define SYSTEM_ACCESS_KEY_ID            0xF000
> +//
> +// System Access defintions.
> +//
> +#define SYSTEM_ACCESS_GUID \
> + { 0xE770BB69, 0xBCB4, 0x4D04, { 0x9E, 0x97, 0x23, 0xFF, 0x94, 0x56, 0xFE,
> 0xAC }}
> +
> +#define SYSTEM_PASSWORD_ADMIN 0
> +#define SYSTEM_PASSWORD_USER  1
> +#define ADMIN_PW_CLEAR        0
> +#define ADMIN_PW_SET          1
> +
> +
> +typedef struct _SYSTEM_ACCESS
> +{
> +  //
> +  // Passwords
> +  //
> +  UINT8       Access;
> +} SYSTEM_ACCESS;
> +
> +//
> +// Record the password status.
> +//
> +typedef struct {
> +  UINT8   AdminName;
> +  UINT8   UserName;
> +} EFI_PASSWORD_STATUS;
> +
> +//
> +// Config Data
> +//
> +typedef struct {
> +  UINT8 SerialDebug;
> +  UINT8 SerialDebugBaudRate;
> +  UINT8 RamDebugInterface;
> +  UINT8 UartDebugInterface;
> +  UINT8 Usb3DebugInterface;
> +  UINT8 SerialIoDebugInterface;
> +  UINT8 TraceHubDebugInterface;
> +} DEBUG_CONFIG_DATA;
> +
> +//
> +// Config Data Hob
> +//
> +#define DEBUG_CONFIG_DATA_HOB DEBUG_CONFIG_DATA
> +
> +//
> +// Secure Boot Data
> +//
> +typedef struct{
> +  UINT8   SecureBoot;
> +} SECURE_BOOT_VARIABLE;
> +
> +#pragma pack()
> +
> +//
> +// Varstore statement
> +// Setup is EfiVarStore that is related to EFI variable with attribute 0x07
> +// (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
> EFI_VARIABLE_RUNTIME_ACCESS)
> +//
> +#define SETUP_DATA_VARSTORE\
> +    efivarstore SETUP_DATA, varid = 1,\
> +        attribute = 0x7, name = Setup, guid = SETUP_GUID;
> +#define SA_SETUP_VARSTORE\
> +    efivarstore SA_SETUP, varid = 2,\
> +        attribute = 0x7, name = SaSetup, guid = SA_SETUP_GUID;
> +#define CPU_SETUP_VARSTORE\
> +    efivarstore CPU_SETUP, varid = 3,\
> +        attribute = 0x7, name = CpuSetup, guid = CPU_SETUP_GUID;
> +#define ME_SETUP_VARSTORE\
> +    efivarstore ME_SETUP, varid = 4,\
> +        attribute = 0x7, name = MeSetup, guid = ME_SETUP_GUID;
> +#define PCH_SETUP_VARSTORE\
> +    efivarstore PCH_SETUP, varid = 5,\
> +        attribute = 0x7, name = PchSetup, guid = PCH_SETUP_GUID;
> +#define SI_SETUP_VARSTORE\
> +    efivarstore SI_SETUP, varid = 6,\
> +        attribute = 0x7, name = SiSetup, guid = SI_SETUP_GUID;
> +#ifdef DEBUG_INTERFACE_FORM_ENABLE
> +#define DEBUG_CONFIG_DATA_ID            0xF001
> +#define DEBUG_CONFIG_DATA_VARSTORE\
> +    efivarstore DEBUG_CONFIG_DATA, varid = DEBUG_CONFIG_DATA_ID,\
> +        attribute = 0x7, name = DebugConfigData, guid =
> DEBUG_CONFIG_GUID;
> +#endif // DEBUG_INTERFACE_FORM_ENABLE
> +#define SYSTEM_ACCESS_VARSTORE\
> +    varstore SYSTEM_ACCESS, varid = SYSTEM_ACCESS_KEY_ID,\
> +        name = SystemAccess, guid = SYSTEM_ACCESS_GUID;
> +#define SYSTEM_PASSWORD_VARSTORE\
> +    varstore EFI_PASSWORD_STATUS,\
> +        name = PasswordStatus, guid = SYSTEM_ACCESS_GUID;
> +
> +#define BOOT_FLOW_CONDITION_RECOVERY   2
> +#define BOOT_FLOW_CONDITION_FIRST_BOOT 4
> +
> +#endif
> +
> diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
> new file mode 100644
> index 0000000000..4ce85de5bd
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
> @@ -0,0 +1,157 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SIO_REG_H_
> +#define _SIO_REG_H_
> +
> +#define REG_LOGICAL_DEVICE        0x07
> +#define ACTIVATE                  0x30
> +
> +#define BASE_ADDRESS_HIGH0        0x60
> +#define BASE_ADDRESS_LOW0         0x61
> +#define BASE_ADDRESS_HIGH1        0x62
> +#define BASE_ADDRESS_LOW1         0x63
> +#define BASE_ADDRESS_HIGH2        0x64
> +#define BASE_ADDRESS_LOW2         0x65
> +#define BASE_ADDRESS_HIGH3        0x66
> +#define BASE_ADDRESS_LOW3         0x67
> +#define PRIMARY_INTERRUPT_SELECT  0x70
> +#define WAKEUP_ON_IRQ_EN          0x70
> +#define INTERRUPT_TYPE            0x71
> +#define DMA_CHANNEL_SELECT0       0x74
> +#define DMA_CHANNEL_SELECT1       0x75
> +
> +
> +
> +//
> +//Port address for PILOT - III
> +//
> +#define PILOTIII_CHIP_ID         0x03
> +#define PILOTIII_SIO_INDEX_PORT  0x04E
> +#define PILOTIII_SIO_DATA_PORT   (PILOTIII_SIO_INDEX_PORT+1)
> +
> +#define PILOTIII_UNLOCK      0x5A
> +#define PILOTIII_LOCK        0xA5
> +
> +//
> +// logical device in PILOT-III
> +//
> +#define PILOTIII_SIO_PSR     0x00
> +#define PILOTIII_SIO_COM2    0x01
> +#define PILOTIII_SIO_COM1    0x02
> +#define PILOTIII_SIO_SWCP    0x03
> +#define PILOTIII_SIO_GPIO    0x04
> +#define PILOTIII_SIO_WDT     0x05
> +#define PILOTIII_SIO_KCS3    0x08
> +#define PILOTIII_SIO_KCS4    0x09
> +#define PILOTIII_SIO_KCS5    0x0A
> +#define PILOTIII_SIO_BT      0x0B
> +#define PILOTIII_SIO_SMIC    0x0C
> +#define PILOTIII_SIO_MAILBOX 0x0D
> +#define PILOTIII_SIO_RTC     0x0E
> +#define PILOTIII_SIO_SPI     0x0F
> +#define PILOTIII_SIO_TAP     0x10
> +//
> +// Regisgers for Pilot-III
> +//
> +#define PILOTIII_CHIP_ID_REG               0x20
> +#define PILOTIII_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
> +#define PILOTIII_ACTIVATE                  ACTIVATE
> +#define PILOTIII_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
> +#define PILOTIII_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
> +#define PILOTIII_BASE_ADDRESS_HIGH1        BASE_ADDRESS_HIGH1
> +#define PILOTIII_BASE_ADDRESS_LOW1         BASE_ADDRESS_LOW1
> +#define PILOTIII_PRIMARY_INTERRUPT_SELECT
> PRIMARY_INTERRUPT_SELECT
> +
> +//
> +// Port address for PC8374
> +//
> +#define PC8374_SIO_INDEX_PORT  0x02E
> +#define PC8374_SIO_DATA_PORT   (PC8374_SIO_INDEX_PORT+1)
> +
> +//
> +// Logical device in PC8374
> +//
> +#define PC8374_SIO_FLOPPY  0x00
> +#define PC8374_SIO_PARA    0x01
> +#define PC8374_SIO_COM2    0x02
> +#define PC8374_SIO_COM1    0x03
> +#define PC8374_SIO_MOUSE   0x05
> +#define PC8374_SIO_KYBD    0x06
> +#define PC8374_SIO_GPIO    0x07
> +
> +//
> +// Registers specific for PC8374
> +//
> +#define PC8374_CLOCK_SELECT  0x2D
> +#define PC8374_CLOCK_CONFIG  0x29
> +
> +//
> +// Registers for PC8374
> +//
> +#define PC8374_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
> +#define PC8374_ACTIVATE                  ACTIVATE
> +#define PC8374_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
> +#define PC8374_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
> +#define PC8374_PRIMARY_INTERRUPT_SELECT
> PRIMARY_INTERRUPT_SELECT
> +#define PC8374_DMA_CHANNEL_SELECT        DMA_CHANNEL_SELECT0
> +
> +#define PC87427_SERVERIO_CNF2           0x22
> +
> +
> +//
> +// Pilot III Mailbox Data Register definitions
> +//
> +#define MBDAT00_OFFSET                  0x00
> +#define MBDAT01_OFFSET                  0x01
> +#define MBDAT02_OFFSET                  0x02
> +#define MBDAT03_OFFSET                  0x03
> +#define MBDAT04_OFFSET                  0x04
> +#define MBDAT05_OFFSET                  0x05
> +#define MBDAT06_OFFSET                  0x06
> +#define MBDAT07_OFFSET                  0x07
> +#define MBDAT08_OFFSET                  0x08
> +#define MBDAT09_OFFSET                  0x09
> +#define MBDAT10_OFFSET                  0x0A
> +#define MBDAT11_OFFSET                  0x0B
> +#define MBDAT12_OFFSET                  0x0C
> +#define MBDAT13_OFFSET                  0x0D
> +#define MBDAT14_OFFSET                  0x0E
> +#define MBDAT15_OFFSET                  0x0F
> +#define MBST0_OFFSET                    0x10
> +#define MBST1_OFFSET                    0x11
> +#define MBBINT_OFFSET                   0x12
> +
> +//
> +// Mailbox Bit definitions...
> +//
> +#define   MBBINT_MBBIST_BIT               0x80
> +// If both are there, use the default one
> +//
> +#define  W83527_EXIST     BIT2
> +#define  PC8374_EXIST     BIT1
> +#define  PILOTIII_EXIST   BIT0
> +#define  DEFAULT_SIO      PILOTIII_EXIST
> +#define  DEFAULT_KDB      PC8374_EXIST
> +
> +#define IPMI_DEFAULT_SMM_IO_BASE           0xca2
> +//
> +// For Pilot III
> +//
> +
> +#define PILOTIII_SWC_BASE_ADDRESS          0xA00
> +#define PILOTIII_PM1b_EVT_BLK_BASE_ADDRESS 0x0A80
> +#define PILOTIII_PM1b_CNT_BLK_BASE_ADDRESS 0x0A84
> +#define PILOTIII_GPE1_BLK_BASE_ADDRESS     0x0A86
> +#define PILOTIII_KCS3_DATA_BASE_ADDRESS    0x0CA4
> +#define PILOTIII_KCS3_CMD_BASE_ADDRESS     0x0CA5
> +#define PILOTIII_KCS4_DATA_BASE_ADDRESS    0x0CA2
> +#define PILOTIII_KCS4_CMD_BASE_ADDRESS     0x0CA3
> +#define PILOTIII_MAILBOX_BASE_ADDRESS      0x0600
> +#define PILOTIII_MAILBOX_MASK              0xFFE0
> +#define BMC_KCS_BASE_ADDRESS               0x0CA0
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
> new file mode 100644
> index 0000000000..af753e1dce
> --- /dev/null
> +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
> @@ -0,0 +1,112 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +  // Define a Global region of ACPI NVS Region that may be used for any
> +  // type of implementation.  The starting offset and size will be fixed
> +  // up by the System BIOS during POST.  Note that the Size must be a word
> +  // in size to be fixed up correctly.
> +
> +  OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55)
> +  Field(GNVS,AnyAcc,Lock,Preserve)
> +  {
> +  //
> +  // Miscellaneous Dynamic Registers:
> +  //
> +  Offset(0),      OSYS, 16, // Offset(0),     Operating System
> +  Offset(2),      SMIF, 8,  // Offset(2),     SMI Function Call (ASL to SMI via I/O
> Trap)
> +  Offset(3),      P80D, 32, // Offset(3),     Port 80 Debug Port Value
> +  Offset(7),      PWRS, 8,  // Offset(7),     Power State (AC Mode = 1)
> +  //
> +  // Thermal Policy Registers:
> +  //
> +  Offset(8),      DTSE, 8,  // Offset(8),    Digital Thermal Sensor Enable
> +  Offset(9),      DTSF, 8,  // Offset(9),    DTS SMI Function Call
> +  //
> +  // CPU Identification Registers:
> +  //
> +  Offset(10),     APIC, 8,  // Offset(10),    APIC Enabled by SBIOS (APIC
> Enabled = 1)
> +  Offset(11),     TCNT, 8,  // Offset(11),    Number of Enabled Threads
> +  //
> +  // PCIe Hot Plug
> +  //
> +  Offset(12),     OSCC, 8,  // Offset(12),    PCIE OSC Control
> +  Offset(13),     NEXP, 8,  // Offset(13),    Native PCIE Setup Value
> +  //
> +  // Global Variables
> +  //
> +  Offset(14),     DSEN, 8,  // Offset(14),    _DOS Display Support Flag.
> +  Offset(15),     GPIC, 8,  // Offset(15),    Global IOAPIC/8259 Interrupt Mode
> Flag.
> +  Offset(16),     L01C, 8,  // Offset(16),    Global L01 Counter.
> +  Offset(17),     LTR1, 8,  // Offset(17),    Latency Tolerance Reporting Enable
> +  Offset(18),     LTR2, 8,  // Offset(18),    Latency Tolerance Reporting Enable
> +  Offset(19),     LTR3, 8,  // Offset(19),    Latency Tolerance Reporting Enable
> +  Offset(20),     LTR4, 8,  // Offset(20),    Latency Tolerance Reporting Enable
> +  Offset(21),     LTR5, 8,  // Offset(21),    Latency Tolerance Reporting Enable
> +  Offset(22),     LTR6, 8,  // Offset(22),    Latency Tolerance Reporting Enable
> +  Offset(23),     LTR7, 8,  // Offset(23),    Latency Tolerance Reporting Enable
> +  Offset(24),     LTR8, 8,  // Offset(24),    Latency Tolerance Reporting Enable
> +  Offset(25),     LTR9, 8,  // Offset(25),    Latency Tolerance Reporting Enable
> +  Offset(26),     LTRA, 8,  // Offset(26),    Latency Tolerance Reporting Enable
> +  Offset(27),     LTRB, 8,  // Offset(27),    Latency Tolerance Reporting Enable
> +  Offset(28),     LTRC, 8,  // Offset(28),    Latency Tolerance Reporting Enable
> +  Offset(29),     LTRD, 8,  // Offset(29),    Latency Tolerance Reporting Enable
> +  Offset(30),     LTRE, 8,  // Offset(30),    Latency Tolerance Reporting Enable
> +  Offset(31),     LTRF, 8,  // Offset(31),    Latency Tolerance Reporting Enable
> +  Offset(32),     LTRG, 8,  // Offset(32),    Latency Tolerance Reporting Enable
> +  Offset(33),     LTRH, 8,  // Offset(33),    Latency Tolerance Reporting Enable
> +  Offset(34),     LTRI, 8,  // Offset(34),    Latency Tolerance Reporting Enable
> +  Offset(35),     LTRJ, 8,  // Offset(35),    Latency Tolerance Reporting Enable
> +  Offset(36),     LTRK, 8,  // Offset(36),    Latency Tolerance Reporting Enable
> +  Offset(37),     LTRL, 8,  // Offset(37),    Latency Tolerance Reporting Enable
> +  Offset(38),     LTRM, 8,  // Offset(38),    Latency Tolerance Reporting Enable
> +  Offset(39),     LTRN, 8,  // Offset(39),    Latency Tolerance Reporting Enable
> +  Offset(40),     LTRO, 8,  // Offset(40),    Latency Tolerance Reporting Enable
> +  Offset(41),     OBF1, 8,  // Offset(41),    Optimized Buffer Flush and Fill
> +  Offset(42),     OBF2, 8,  // Offset(42),    Optimized Buffer Flush and Fill
> +  Offset(43),     OBF3, 8,  // Offset(43),    Optimized Buffer Flush and Fill
> +  Offset(44),     OBF4, 8,  // Offset(44),    Optimized Buffer Flush and Fill
> +  Offset(45),     OBF5, 8,  // Offset(45),    Optimized Buffer Flush and Fill
> +  Offset(46),     OBF6, 8,  // Offset(46),    Optimized Buffer Flush and Fill
> +  Offset(47),     OBF7, 8,  // Offset(47),    Optimized Buffer Flush and Fill
> +  Offset(48),     OBF8, 8,  // Offset(48),    Optimized Buffer Flush and Fill
> +  Offset(49),     OBF9, 8,  // Offset(49),    Optimized Buffer Flush and Fill
> +  Offset(50),     OBFA, 8,  // Offset(50),    Optimized Buffer Flush and Fill
> +  Offset(51),     OBFB, 8,  // Offset(51),    Optimized Buffer Flush and Fill
> +  Offset(52),     OBFC, 8,  // Offset(52),    Optimized Buffer Flush and Fill
> +  Offset(53),     OBFD, 8,  // Offset(53),    Optimized Buffer Flush and Fill
> +  Offset(54),     OBFE, 8,  // Offset(54),    Optimized Buffer Flush and Fill
> +  Offset(55),     OBFF, 8,  // Offset(55),    Optimized Buffer Flush and Fill
> +  Offset(56),     OBFG, 8,  // Offset(56),    Optimized Buffer Flush and Fill
> +  Offset(57),     OBFH, 8,  // Offset(57),    Optimized Buffer Flush and Fill
> +  Offset(58),     OBFI, 8,  // Offset(58),    Optimized Buffer Flush and Fill
> +  Offset(59),     OBFJ, 8,  // Offset(59),    Optimized Buffer Flush and Fill
> +  Offset(60),     OBFK, 8,  // Offset(60),    Optimized Buffer Flush and Fill
> +  Offset(61),     OBFL, 8,  // Offset(61),    Optimized Buffer Flush and Fill
> +  Offset(62),     OBFM, 8,  // Offset(62),    Optimized Buffer Flush and Fill
> +  Offset(63),     OBFN, 8,  // Offset(63),    Optimized Buffer Flush and Fill
> +  Offset(64),     OBFO, 8,  // Offset(64),    Optimized Buffer Flush and Fill
> +  Offset(65),     RTD3, 8,  // Offset(65),    Runtime D3 support.
> +  Offset(66),     S0ID, 8,  // Offset(66),    Low Power S0 Idle Enable
> +  Offset(67),     GBSX, 8,  // Offset(67),    Virtual GPIO button Notify Sleep
> State Change
> +  Offset(68),     PSCP, 8,  // Offset(68),    P-state Capping
> +  Offset(69),     P2ME, 8,  // Offset(69),    Ps2 Mouse Enable
> +  Offset(70),     P2MK, 8,  // Offset(70),    Ps2 Keyboard and Mouse Enable
> +  //
> +  // Driver Mode
> +  //
> +  Offset(71),     GIRQ, 32, // Offset(71),    GPIO IRQ
> +  Offset(75),     PLCS, 8,  // Offset(75),    set PL1 limit when entering CS
> +  Offset(76),     PLVL, 16, // Offset(76),    PL1 limit value
> +  Offset(78),     PB1E, 8,  // Offset(78),    10sec Power button support
> +  Offset(79),     ECR1, 8,  // Offset(79),    Pci Delay Optimization Ecr
> +  Offset(80),     TBTS, 8,  // Offset(80),    Thunderbolt(TM) support
> +  Offset(81),     TNAT, 8,  // Offset(81),    TbtNativeOsHotPlug
> +  Offset(82),     TBSE, 8,  // Offset(82),    Thunderbolt(TM) Root port selector
> +  Offset(83),     TBS1, 8,  // Offset(83),    Thunderbolt(TM) Root port selector
> +  }
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
  2019-08-17  0:53   ` Nate DeSimone
@ 2019-08-17  1:16   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:16 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add
> SMM library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH SMM library class instances.
> 
> * SmmSpiFlashCommonLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/Sm
> mSpiFlashCommonLib.inf |  51 +++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiF
> lashCommon.c         | 196 ++++++++++++++++++++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiF
> lashCommonSmmLib.c   |  54 ++++++
>  3 files changed, 301 insertions(+)
> 
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/S
> mmSpiFlashCommonLib.inf
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/S
> mmSpiFlashCommonLib.inf
> new file mode 100644
> index 0000000000..abc919867c
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLi
> +++ b/SmmSpiFlashCommonLib.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# SMM Library instance of Spi Flash Common Library Class # # Copyright
> +(c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = SmmSpiFlashCommonLib
> +  FILE_GUID                      = 9632D96E-E849-4217-9217-DC500B8AAE47
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_SMM_DRIVER
> +  LIBRARY_CLASS                  = SpiFlashCommonLib|DXE_SMM_DRIVER
> +  CONSTRUCTOR                    = SmmSpiFlashCommonLibConstructor
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[LibraryClasses]
> +  PciLib
> +  IoLib
> +  MemoryAllocationLib
> +  BaseLib
> +  UefiLib
> +  SmmServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  MmPciLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +  gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress  ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdBiosSize         ## CONSUMES
> +
> +[Sources]
> +  SpiFlashCommonSmmLib.c
> +  SpiFlashCommon.c
> +
> +[Protocols]
> +  gPchSmmSpiProtocolGuid                        ## CONSUMES
> +
> +[Depex.X64.DXE_SMM_DRIVER]
> +  gPchSmmSpiProtocolGuid
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/S
> piFlashCommon.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/S
> piFlashCommon.c
> new file mode 100644
> index 0000000000..53711db632
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLi
> +++ b/SpiFlashCommon.c
> @@ -0,0 +1,196 @@
> +/** @file
> +  Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
> +  for module use.
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Library/SpiFlashCommonLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <PchAccess.h>
> +#include <Library/MmPciLib.h>
> +#include <Protocol/Spi.h>
> +
> +
> +PCH_SPI_PROTOCOL       *mSpiProtocol;
> +
> +//
> +// FlashAreaBaseAddress and Size for boottime and runtime usage.
> +//
> +UINTN mFlashAreaBaseAddress = 0;
> +UINTN mFlashAreaSize        = 0;
> +
> +/**
> +  Enable block protection on the Serial Flash device.
> +
> +  @retval     EFI_SUCCESS       Opertion is successful.
> +  @retval     EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashLock (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Read NumBytes bytes of data from the address specified by
> +  PAddress into Buffer.
> +
> +  @param[in]      Address       The starting physical address of the read.
> +  @param[in,out]  NumBytes      On input, the number of bytes to read. On
> output, the number
> +                                of bytes actually read.
> +  @param[out]     Buffer        The destination data buffer for the read.
> +
> +  @retval         EFI_SUCCESS       Opertion is successful.
> +  @retval         EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashRead (
> +  IN     UINTN                        Address,
> +  IN OUT UINT32                       *NumBytes,
> +     OUT UINT8                        *Buffer
> +  )
> +{
> +  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
> +  if ((NumBytes == NULL) || (Buffer == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // This function is implemented specifically for those platforms  //
> + at which the SPI device is memory mapped for read. So this  //
> + function just do a memory copy for Spi Flash Read.
> +  //
> +  CopyMem (Buffer, (VOID *) Address, *NumBytes);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Write NumBytes bytes of data from Buffer to the address specified by
> +  PAddresss.
> +
> +  @param[in]      Address         The starting physical address of the write.
> +  @param[in,out]  NumBytes        On input, the number of bytes to write.
> On output,
> +                                  the actual number of bytes written.
> +  @param[in]      Buffer          The source data buffer for the write.
> +
> +  @retval         EFI_SUCCESS       Opertion is successful.
> +  @retval         EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashWrite (
> +  IN     UINTN                      Address,
> +  IN OUT UINT32                     *NumBytes,
> +  IN     UINT8                      *Buffer
> +  )
> +{
> +  EFI_STATUS                Status;
> +  UINTN                     Offset;
> +  UINT32                    Length;
> +  UINT32                    RemainingBytes;
> +
> +  ASSERT ((NumBytes != NULL) && (Buffer != NULL));  if ((NumBytes ==
> + NULL) || (Buffer == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ASSERT (Address >= mFlashAreaBaseAddress);
> +
> +  Offset = Address - mFlashAreaBaseAddress;
> +
> +  ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
> +
> +  Status = EFI_SUCCESS;
> +  RemainingBytes = *NumBytes;
> +
> +
> +  while (RemainingBytes > 0) {
> +    if (RemainingBytes > SECTOR_SIZE_4KB) {
> +      Length = SECTOR_SIZE_4KB;
> +    } else {
> +      Length = RemainingBytes;
> +    }
> +    Status = mSpiProtocol->FlashWrite (
> +                             mSpiProtocol,
> +                             FlashRegionBios,
> +                             (UINT32) Offset,
> +                             Length,
> +                             Buffer
> +                             );
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +    RemainingBytes -= Length;
> +    Offset += Length;
> +    Buffer += Length;
> +  }
> +
> +  //
> +  // Actual number of bytes written
> +  //
> +  *NumBytes -= RemainingBytes;
> +
> +  return Status;
> +}
> +
> +/**
> +  Erase the block starting at Address.
> +
> +  @param[in]  Address         The starting physical address of the block to be
> erased.
> +                              This library assume that caller garantee that the
> PAddress
> +                              is at the starting address of this block.
> +  @param[in]  NumBytes        On input, the number of bytes of the logical
> block to be erased.
> +                              On output, the actual number of bytes erased.
> +
> +  @retval     EFI_SUCCESS.      Opertion is successful.
> +  @retval     EFI_DEVICE_ERROR  If there is any device errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SpiFlashBlockErase (
> +  IN    UINTN                     Address,
> +  IN    UINTN                     *NumBytes
> +  )
> +{
> +  EFI_STATUS          Status;
> +  UINTN               Offset;
> +  UINTN               RemainingBytes;
> +
> +  ASSERT (NumBytes != NULL);
> +  if (NumBytes == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ASSERT (Address >= mFlashAreaBaseAddress);
> +
> +  Offset = Address - mFlashAreaBaseAddress;
> +
> +  ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0);  ASSERT ((*NumBytes +
> + Offset) <= mFlashAreaSize);
> +
> +  Status = EFI_SUCCESS;
> +  RemainingBytes = *NumBytes;
> +
> +
> +  Status = mSpiProtocol->FlashErase (
> +                           mSpiProtocol,
> +                           FlashRegionBios,
> +                           (UINT32) Offset,
> +                           (UINT32) RemainingBytes
> +                           );
> +  return Status;
> +}
> +
> diff --git
> a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/S
> piFlashCommonSmmLib.c
> b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/S
> piFlashCommonSmmLib.c
> new file mode 100644
> index 0000000000..43c0218d85
> --- /dev/null
> +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLi
> +++ b/SpiFlashCommonSmmLib.c
> @@ -0,0 +1,54 @@
> +/** @file
> +  SMM Library instance of SPI Flash Common Library Class
> +
> +  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Library/SpiFlashCommonLib.h>
> +#include <Library/SmmServicesTableLib.h> #include <Protocol/Spi.h>
> +
> +extern PCH_SPI_PROTOCOL   *mSpiProtocol;
> +
> +extern UINTN mFlashAreaBaseAddress;
> +extern UINTN mFlashAreaSize;
> +
> +/**
> +  The library constructuor.
> +
> +  The function does the necessary initialization work for this library
> + instance.
> +
> +  @param[in]  ImageHandle       The firmware allocated handle for the UEFI
> image.
> +  @param[in]  SystemTable       A pointer to the EFI system table.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +                                It will ASSERT on error for debug version.
> +  @retval     EFI_ERROR         Please reference LocateProtocol for error code
> details.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmSpiFlashCommonLibConstructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  mFlashAreaBaseAddress = (UINTN)PcdGet32 (PcdBiosAreaBaseAddress);
> +  mFlashAreaSize        = (UINTN)PcdGet32 (PcdBiosSize);
> +
> +  //
> +  // Locate the SMM SPI protocol.
> +  //
> +  Status = gSmst->SmmLocateProtocol (
> +                    &gPchSmmSpiProtocolGuid,
> +                    NULL,
> +                    (VOID **) &mSpiProtocol
> +                    );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:16   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:16 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add
> library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> Common package library instances.
> 
> * BaseAcpiTimerLib - Support for ACPI timer services.
> * BaseGpioExpanderLib - Support for the TCA6424 IO expander.
> * DxePolicyUpdateLib - Policy update in DXE.
> * DxeTbtPolicyLib - DXE Thunderbolt policy initialization.
> * PeiDTbtInitLib - PEI discrete Thunderbolt initialization services.
> * PeiFspPolicyInitLib - PEI Intel FSP policy initialization.
> * PeiI2cAccessLib - Provides I2C read and write services.
> * PeiPolicyInitLib - Policy initialization in PEI.
> * PeiPolicyUpdateLib - Policy update in PEI.
> * PeiSiliconPolicyUpdateLibFsp - PEI FSP silicon policy initialization.
> * PeiTbtPolicyLib - PEI Thunderbolt policy initialization.
> * SecFspWrapperPlatformSecLib - FSP wrapper PlatformSecLib instance.
> * TbtCommonLib - Common Thunderbolt services.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolic
> yLib/DxeTbtPolicyLib.inf                         |   43 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmm
> TbtCommonLib/TbtCommonLib.inf                      |   60 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolic
> yLib/PeiTbtPolicyLib.inf                         |   51 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/Pei
> DTbtInitLib/PeiDTbtInitLib.inf                   |   45 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspPolicyInitLib.inf                   |  161 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf |  139 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/SecFspWrapperPlatformSecLib.inf   |   97 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTi
> merLib.inf                                        |   54 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/Ba
> seGpioExpanderLib.inf                              |   36 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiH
> daVerbTableLib.inf                                |   67 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAcc
> essLib.inf                                      |   39 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxePolicyUpdateLib.inf                         |   58 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> PolicyInitLib.inf                             |   61 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiPolicyUpdateLib.inf                         |  272 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolic
> yLib/DxeTbtPolicyLibrary.h                       |   25 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolic
> yLib/PeiTbtPolicyLibrary.h                       |   19 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspPolicyInitLib.h                     |  234 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiMiscPolicyUpdate.h            |   25 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiPchPolicyUpdate.h             |   28 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiSaPolicyUpdate.h              |   30 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/FsptCoreUpd.h                     |   40 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/Ia32/Fsp.h                        |   43 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchH
> daVerbTables.h                                    | 3014 ++++++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxeMePolicyUpdate.h                            |   91 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxeSaPolicyUpdate.h                            |   25 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> CpuPolicyInit.h                               |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> MePolicyInit.h                                |   23 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> PolicyInit.h                                  |   23 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> SaPolicyInit.h                                |   58 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> SiPolicyInit.h                                |   22 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiCpuPolicyUpdate.h                           |   32 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiMePolicyUpdate.h                            |   14 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiPchPolicyUpdate.h                           |   25 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiSaPolicyUpdate.h                            |   53 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiSiPolicyUpdate.h                            |   19 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolic
> yLib/DxeTbtPolicyLib.c                           |  148 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmm
> TbtCommonLib/TbtCommonLib.c                        |  316 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolic
> yLib/PeiTbtPolicyLib.c                           |  206 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/Pei
> DTbtInitLib/PeiDTbtInitLib.c                     |  567 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspCpuPolicyInitLib.c                  |  461 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspMePolicyInitLib.c                   |  121 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspMiscUpdInitLib.c                    |   77 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspPchPolicyInitLib.c                  |  736 +++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspPolicyInitLib.c                     |  223 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspSaPolicyInitLib.c                   |  848 ++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspSecurityPolicyInitLib.c             |   70 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyI
> nitLib/PeiFspSiPolicyInitLib.c                   |   95 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c         |  100 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiFspPolicyUpdateLib.c          |  124 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiPchPolicyUpdate.c             |   60 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c       |   39 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiSaPolicyUpdate.c              |   85 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPol
> icyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c        |   87 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/FspWrapperPlatformSecLib.c        |  163 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/PlatformInit.c                    |   54 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/SecGetPerformance.c               |   90 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/SecPlatformInformation.c          |   79 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/SecRamInitData.c                  |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/SecTempRamDone.c                  |   48 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTi
> merLib.c                                          |   48 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/Ba
> seGpioExpanderLib.c                                |  310 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiH
> daVerbTableLib.c                                  |  132 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAcc
> essLib.c                                        |  115 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxeCpuPolicyUpdate.c                           |   88 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxeMePolicyUpdate.c                            |  105 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxePchPolicyUpdate.c                           |   39 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLi
> b/DxeSaPolicyUpdate.c                            |   57 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> PolicyInit.c                                  |   65 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> PolicyInitPreMem.c                            |   60 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/Pei
> SaPolicyInit.c                                |  114 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiCpuPolicyUpdate.c                           |   80 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiCpuPolicyUpdatePreMem.c                     |  108 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiMePolicyUpdate.c                            |   49 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiMePolicyUpdatePreMem.c                      |   32 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiPchPolicyUpdate.c                           |  523 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiPchPolicyUpdatePreMem.c                     |  113 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiSaPolicyUpdate.c                            |  242 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiSaPolicyUpdatePreMem.c                      |  221 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib
> /PeiSiPolicyUpdate.c                            |  168 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/Ia32/PeiCoreEntry.nasm            |  130 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/Ia32/SecEntry.nasm                |  361 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrap
> perPlatformSecLib/Ia32/Stack.nasm                   |   72 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTi
> merLib.uni                                        |   15 +
>  83 files changed, 13144 insertions(+)
> 
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLib.inf
> new file mode 100644
> index 0000000000..0d2a6cceeb
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLib.inf
> @@ -0,0 +1,43 @@
> +## @file
> +# Component description file for Tbt functionality
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxeTbtPolicyLib
> +FILE_GUID = 28ABF346-4E52-4BD3-b1FF-63BA7563C9D4
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = DxeTbtPolicyLib
> +
> +
> +[LibraryClasses]
> +BaseMemoryLib
> +UefiRuntimeServicesTableLib
> +UefiBootServicesTableLib
> +DebugLib
> +PostCodeLib
> +HobLib
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +CoffeelakeSiliconPkg/SiPkg.dec
> +WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +[Sources]
> +DxeTbtPolicyLib.c
> +
> +
> +[Guids]
> +gEfiEndOfDxeEventGroupGuid
> +gTbtInfoHobGuid
> +
> +[Protocols]
> +gDxeTbtPolicyProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSm
> mTbtCommonLib/TbtCommonLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSm
> mTbtCommonLib/TbtCommonLib.inf
> new file mode 100644
> index 0000000000..f2330b5b71
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSm
> mTbtCommonLib/TbtCommonLib.inf
> @@ -0,0 +1,60 @@
> +## @file
> +# Component information file for Tbt common library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = TbtCommonLib
> +  FILE_GUID                      = 5F03614E-CB56-40B1-9989-A09E25BBA294
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = BASE
> +  LIBRARY_CLASS                  = TbtCommonLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[LibraryClasses]
> +  DebugLib
> +  PchPcieRpLib
> +  PciSegmentLib
> +  TimerLib
> +  BaseLib
> +  GpioLib
> +  GpioExpanderLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +
> +[Pcd]
> +gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode           ##
> CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport       ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI              ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify           ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq           ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtAspm                ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch          ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdRtd3Tbt                ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq          ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax  ##
> CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd       ## CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ##
> CONSUMES
> +gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber
> +
> +[Sources]
> +  TbtCommonLib.c
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLib.inf
> new file mode 100644
> index 0000000000..b74e641e16
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLib.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# Component description file for Tbt policy
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiTbtPolicyLib
> +FILE_GUID = 4A95FDBB-2535-49eb-9A79-D56D24257106
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = PeiTbtPolicyLib
> +
> +
> +[LibraryClasses]
> +BaseMemoryLib
> +PeiServicesLib
> +PeiServicesTablePointerLib
> +MemoryAllocationLib
> +DebugLib
> +PostCodeLib
> +HobLib
> +GpioLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[Pcd]
> +gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad    ##
> CONSUMES
> +
> +[Sources]
> +PeiTbtPolicyLib.c
> +
> +[Guids]
> +gTbtInfoHobGuid
> +
> +[Ppis]
> +gEfiPeiReadOnlyVariable2PpiGuid
> +gPeiTbtPolicyPpiGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/P
> eiDTbtInitLib/PeiDTbtInitLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/P
> eiDTbtInitLib/PeiDTbtInitLib.inf
> new file mode 100644
> index 0000000000..8e0dbe73ce
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/P
> eiDTbtInitLib/PeiDTbtInitLib.inf
> @@ -0,0 +1,45 @@
> +## @file
> +# Component description file for PEI DTBT Init library.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiDTbtInitLib
> +  FILE_GUID                      = 06768A8D-8152-403f-83C1-59584FD2B438
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  LIBRARY_CLASS                  = PeiDTbtInitLib
> +
> +[LibraryClasses]
> +  PeiServicesLib
> +  DebugLib
> +  PcdLib
> +  TbtCommonLib
> +  PciSegmentLib
> +  PeiTbtPolicyLib
> +  PchPmcLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Ppis]
> +  gPeiTbtPolicyPpiGuid                          ## CONSUMES
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +  #gClientCommonModuleTokenSpaceGuid.PcdTbtSupport    ## PRODUCES
> +
> +[Sources]
> +  PeiDTbtInitLib.c
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.inf
> new file mode 100644
> index 0000000000..bd39cd60b7
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.inf
> @@ -0,0 +1,161 @@
> +## @file
> +# Library functions for Fsp Policy Initialization Library.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +###############################################################
> #################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +###############################################################
> #################
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiFspPolicyInitLib
> +  FILE_GUID                      = 2CB87D67-D1A4-4CD3-8CD7-91A1FA1DF6E0
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SiliconPolicyInitLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32
> +#
> +
> +###############################################################
> #################
> +#
> +# Sources Section - list of files that are required for the build to succeed.
> +#
> +###############################################################
> #################
> +
> +[Sources]
> +  PeiFspPolicyInitLib.c
> +  PeiFspSiPolicyInitLib.c
> +  PeiFspPchPolicyInitLib.c
> +  PeiFspCpuPolicyInitLib.c
> +  PeiFspMePolicyInitLib.c
> +  PeiFspSaPolicyInitLib.c
> +  PeiFspSecurityPolicyInitLib.c
> +  PeiFspMiscUpdInitLib.c
> +
> +###############################################################
> #################
> +#
> +# Package Dependency Section - list of Package files that are required for
> +#                              this module.
> +#
> +###############################################################
> #################
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  CoffeeLakeFspBinPkg/CoffeeLakeFspBinPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  IoLib
> +  PeiServicesLib
> +  SmbusLib
> +  ConfigBlockLib
> +  PcdLib
> +  MemoryAllocationLib
> +  PchInfoLib
> +  SpiLib
> +
> +[Pcd]
> +  gSiPkgTokenSpaceGuid.PcdTsegSize
> +  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap                   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram              ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize          ##
> CONSUMES
> +  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase              ##
> CONSUMES
> +  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize              ##
> CONSUMES
> +  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize           ##
> CONSUMES
> +  gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize         ##
> CONSUMES
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode                   ##
> CONSUMES
> +
> +[Ppis]
> +  gSiPolicyPpiGuid                        ## CONSUMES
> +  gSiPreMemPolicyPpiGuid                  ## CONSUMES
> +  gEfiSecPlatformInformation2PpiGuid      ## CONSUMES
> +  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
> +
> +[Guids]
> +  gPchTraceHubPreMemConfigGuid            ## CONSUMES
> +  gSmbusPreMemConfigGuid                  ## CONSUMES
> +  gDciPreMemConfigGuid                    ## CONSUMES
> +  gPcieRpPreMemConfigGuid                 ## CONSUMES
> +  gHdAudioPreMemConfigGuid                ## CONSUMES
> +  gIshPreMemConfigGuid                    ## CONSUMES
> +  gHsioPciePreMemConfigGuid               ## CONSUMES
> +  gHsioSataPreMemConfigGuid               ## CONSUMES
> +  gLpcPreMemConfigGuid                    ## CONSUMES
> +  gPchGeneralPreMemConfigGuid             ## CONSUMES
> +  gWatchDogPreMemConfigGuid               ## CONSUMES
> +  gLanConfigGuid                          ## CONSUMES
> +  gPcieRpConfigGuid                       ## CONSUMES
> +  gSataConfigGuid                         ## CONSUMES
> +  gHdAudioConfigGuid                      ## CONSUMES
> +  gScsConfigGuid                          ## CONSUMES
> +  gIshConfigGuid                          ## CONSUMES
> +  gSataConfigGuid                         ## CONSUMES
> +  gUsbConfigGuid                          ## CONSUMES
> +  gSerialIoConfigGuid                     ## CONSUMES
> +  gInterruptConfigGuid                    ## CONSUMES
> +  gLockDownConfigGuid                     ## CONSUMES
> +  gSaMiscPeiPreMemConfigGuid              ## PRODUCES
> +  gSaMiscPeiConfigGuid                    ## PRODUCES
> +  gMemoryConfigGuid                       ## CONSUMES
> +  gMemoryConfigNoCrcGuid                  ## CONSUMES
> +  gSwitchableGraphicsConfigGuid           ## CONSUMES
> +  gGraphicsPeiPreMemConfigGuid            ## CONSUMES
> +  gSaPciePeiPreMemConfigGuid              ## CONSUMES
> +  gSaMiscPeiConfigGuid                    ## CONSUMES
> +  gSaPciePeiConfigGuid                    ## CONSUMES
> +  gGraphicsPeiConfigGuid                  ## CONSUMES
> +  gCpuTraceHubConfigGuid                  ## CONSUMES
> +  gIpuPreMemConfigGuid                    ## CONSUMES
> +  gCnviConfigGuid                         ## CONSUMES
> +  gHsioConfigGuid                         ## CONSUMES
> +  gEspiConfigGuid                         ## CONSUMES
> +  gGnaConfigGuid                          ## CONSUMES
> +  gVtdConfigGuid                          ## CONSUMES
> +  gSaOverclockingPreMemConfigGuid         ## CONSUMES
> +  gMePeiPreMemConfigGuid                  ## CONSUMES
> +  gMePeiConfigGuid                        ## CONSUMES
> +  gDmiConfigGuid                          ## CONSUMES
> +  gFlashProtectionConfigGuid              ## CONSUMES
> +  gIoApicConfigGuid                       ## CONSUMES
> +  gPmConfigGuid                           ## CONSUMES
> +  gP2sbConfigGuid                         ## CONSUMES
> +  gPchGeneralConfigGuid                   ## CONSUMES
> +  gSerialIrqConfigGuid                    ## CONSUMES
> +  gThermalConfigGuid                      ## CONSUMES
> +  gCpuSecurityPreMemConfigGuid            ## CONSUMES
> +  gCpuConfigGuid                          ## CONSUMES
> +  gCpuOverclockingPreMemConfigGuid        ## CONSUMES
> +  gCpuConfigLibPreMemConfigGuid           ## CONSUMES
> +  gCpuPowerMgmtBasicConfigGuid            ## CONSUMES
> +  gCpuPowerMgmtCustomConfigGuid           ## CONSUMES
> +  gCpuTestConfigGuid                      ## CONSUMES
> +  gCpuPidTestConfigGuid                   ## CONSUMES
> +  gCpuPowerMgmtTestConfigGuid             ## CONSUMES
> +  gFspNonVolatileStorageHobGuid           ## CONSUMES
> +  gSmramCpuDataHeaderGuid                 ## CONSUMES
> +  gFspReservedMemoryResourceHobTsegGuid   ## CONSUMES
> +  gSiConfigGuid                           ## CONSUMES
> +  gDebugConfigHobGuid                     ## CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
> new file mode 100644
> index 0000000000..994cf93e33
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
> @@ -0,0 +1,139 @@
> +## @file
> +#  Provide FSP wrapper platform related function.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +###############################################################
> #################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +###############################################################
> #################
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SiliconPolicyUpdateLibFsp
> +  FILE_GUID                      = 4E83003B-49A9-459E-AAA6-1CA3C6D04FB2
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = SiliconPolicyUpdateLib
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +###############################################################
> #################
> +#
> +# Sources Section - list of files that are required for the build to succeed.
> +#
> +###############################################################
> #################
> +
> +[Sources]
> +  PeiFspPolicyUpdateLib.c
> +  PeiPchPolicyUpdatePreMem.c
> +  PeiPchPolicyUpdate.c
> +  PeiSaPolicyUpdatePreMem.c
> +  PeiSaPolicyUpdate.c
> +  PeiFspMiscUpdUpdateLib.c
> +
> +###############################################################
> #################
> +#
> +# Package Dependency Section - list of Package files that are required for
> +#                              this module.
> +#
> +###############################################################
> #################
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> +  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  CoffeeLakeFspBinPkg/CoffeeLakeFspBinPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +
> +[LibraryClasses.IA32]
> +  FspWrapperApiLib
> +  OcWdtLib
> +  PchResetLib
> +  FspWrapperPlatformLib
> +  BaseMemoryLib
> +  CpuPlatformLib
> +  DebugLib
> +  HdaVerbTableLib
> +  HobLib
> +  IoLib
> +  PcdLib
> +  PostCodeLib
> +  SmbusLib
> +  ConfigBlockLib
> +  PeiSaPolicyLib
> +  PchGbeLib
> +  PchInfoLib
> +  PchHsioLib
> +  PchPcieRpLib
> +  MemoryAllocationLib
> +  DebugPrintErrorLevelLib
> +  SiPolicyLib
> +  PchGbeLib
> +  TimerLib
> +  GpioLib
> +  PeiLib
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor       ## CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget         ## CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap           ## CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram      ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
> +
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress      ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable        ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber             ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi                   ## CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit           ## CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1
> +  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2
> +  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size
> +  gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
> +
> +  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
> +  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
> +  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
> +  gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
> +  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1
> +  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2
> +  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size
> +  gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size
> +
> +  gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid
> +
> +  # SPD Address Table
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
> +
> +[Guids]
> +  gFspNonVolatileStorageHobGuid                 ## CONSUMES
> +  gTianoLogoGuid                                ## CONSUMES
> +  gEfiMemoryOverwriteControlDataGuid
> +
> +[Depex]
> +  gEdkiiVTdInfoPpiGuid
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
> new file mode 100644
> index 0000000000..06489a6336
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
> @@ -0,0 +1,97 @@
> +## @file
> +#  Provide FSP wrapper platform sec related function.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +###############################################################
> #################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +###############################################################
> #################
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SecFspWrapperPlatformSecLib
> +  FILE_GUID                      = 4E1C4F95-90EA-47de-9ACC-B8920189A1F5
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformSecLib
> +
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +###############################################################
> #################
> +#
> +# Sources Section - list of files that are required for the build to succeed.
> +#
> +###############################################################
> #################
> +
> +[Sources]
> +  FspWrapperPlatformSecLib.c
> +  SecRamInitData.c
> +  SecPlatformInformation.c
> +  SecGetPerformance.c
> +  SecTempRamDone.c
> +  PlatformInit.c
> +
> +[Sources.IA32]
> +  Ia32/SecEntry.nasm
> +  Ia32/PeiCoreEntry.nasm
> +  Ia32/Stack.nasm
> +  Ia32/Fsp.h
> +
> +###############################################################
> #################
> +#
> +# Package Dependency Section - list of Package files that are required for
> +#                              this module.
> +#
> +###############################################################
> #################
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> +  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  LocalApicLib
> +  SerialPortLib
> +  FspWrapperPlatformLib
> +  FspWrapperApiLib
> +  BoardInitLib
> +  SecBoardInitLib
> +  TestPointCheckLib
> +  IoLib
> +
> +[Ppis]
> +  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
> +  gPeiSecPerformancePpiGuid               ## CONSUMES
> +  gTopOfTemporaryRamPpiGuid               ## PRODUCES
> +  gEfiPeiFirmwareVolumeInfoPpiGuid        ## PRODUCES
> +
> +[Pcd]
> +  gUefiCpuPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize               ##
> CONSUMES
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress                  ##
> CONSUMES
> +  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize                  ##
> CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdSecSerialPortDebugEnable        ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
> +
> +[FixedPcd]
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress
> ## CONSUMES
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize
> ## CONSUMES
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset             ##
> CONSUMES
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress
> ## CONSUMES
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize               ##
> CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.inf
> new file mode 100644
> index 0000000000..e7eef24906
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.inf
> @@ -0,0 +1,54 @@
> +## @file
> +#  Base ACPI Timer Library
> +#
> +#  Provides basic timer support using the ACPI timer hardware.  The
> performance
> +#  counter features are provided by the processors time stamp counter.
> +#
> +#  Note: The implementation uses the lower 24-bits of the ACPI timer and
> +#  is compatible with both 24-bit and 32-bit ACPI timers.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BaseAcpiTimerLib
> +  FILE_GUID                      = 564DE85F-049E-4481-BF7A-CA04D2788CF9
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = TimerLib|SEC PEI_CORE PEIM
> +  CONSTRUCTOR                    = AcpiTimerLibConstructor
> +  MODULE_UNI_FILE                = BaseAcpiTimerLib.uni
> +
> +[Sources]
> +  AcpiTimerLib.c
> +  BaseAcpiTimerLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  PcAtChipsetPkg/PcAtChipsetPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec      ## OVERRIDE
> +
> +[LibraryClasses]
> +  BaseLib
> +  PcdLib
> +  PciLib
> +  IoLib
> +  DebugLib
> +
> +[Pcd]
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber             ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber          ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber        ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset  ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask            ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset     ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress          ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset               ##
> CONSUMES
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask      ##
> CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/
> BaseGpioExpanderLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/
> BaseGpioExpanderLib.inf
> new file mode 100644
> index 0000000000..ef5ede18cc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/
> BaseGpioExpanderLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# Library producing Gpio Expander functionality.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = BaseGpioExpanderLib
> +  FILE_GUID                      = D10AE2A4-782E-427E-92FB-BB74505ED329
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = BASE
> +  LIBRARY_CLASS                  = GpioExpanderLib
> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  DebugLib
> +  TimerLib
> +  PchSerialIoLib
> +  I2cAccessLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  BaseGpioExpanderLib.c
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pei
> HdaVerbTableLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pe
> iHdaVerbTableLib.inf
> new file mode 100644
> index 0000000000..3c017577b6
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pe
> iHdaVerbTableLib.inf
> @@ -0,0 +1,67 @@
> +## @file
> +#  PEI Intel HD Audio Verb Table library.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +###############################################################
> #################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +###############################################################
> #################
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiHdaVerbTableLib
> +  FILE_GUID                      = 821486A2-CF3B-4D24-BC45-AFE40D9737EB
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = HdaVerbTableLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +###############################################################
> #################
> +#
> +# Sources Section - list of files that are required for the build to succeed.
> +#
> +###############################################################
> #################
> +
> +[Sources]
> +  PeiHdaVerbTableLib.c
> +
> +###############################################################
> #################
> +#
> +# Package Dependency Section - list of Package files that are required for
> +#                              this module.
> +#
> +###############################################################
> #################
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  PcdLib
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdHdaVerbTable                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable    ##
> CONSUMES
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cA
> ccessLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cA
> ccessLib.inf
> new file mode 100644
> index 0000000000..887cbf84f8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cA
> ccessLib.inf
> @@ -0,0 +1,39 @@
> +## @file
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiI2cAccessLib
> +  FILE_GUID                      = 72CD3A7B-FEA5-4F5E-9165-4DD12187BB13
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = BASE
> +  LIBRARY_CLASS                  = PeiI2cAccessLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC
> +#
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  TimerLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PeiI2cAccessLib.c
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxePolicyUpdateLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxePolicyUpdateLib.inf
> new file mode 100644
> index 0000000000..16653f38bd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxePolicyUpdateLib.inf
> @@ -0,0 +1,58 @@
> +## @file
> +#  Component description file for DXE DxePolicyUpdateLib Library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = DxePolicyUpdateLib
> +  FILE_GUID                      = 690B3786-D215-4ABB-9EF2-7A80128560E0
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
> +#
> +
> +[Sources]
> +  DxeMePolicyUpdate.c
> +  DxeSaPolicyUpdate.c
> +  DxePchPolicyUpdate.c
> +  DxeCpuPolicyUpdate.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseLib
> +  BaseMemoryLib
> +  PcdLib
> +  DebugLib
> +  IoLib
> +  CpuPlatformLib
> +  HobLib
> +  ConfigBlockLib
> +  PciSegmentLib
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +
> +[Guids]
> +  gEfiGlobalVariableGuid                        ## CONSUMES
> +  gEfiEndOfDxeEventGroupGuid                    ## CONSUMES
> +  gMeInfoSetupGuid                              ## PRODUCES
> +  gMePolicyHobGuid                              ## CONSUMES
> +  gCpuSetupVariableGuid                         ## CONSUMES
> +  gPchSetupVariableGuid                         ## CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInitLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInitLib.inf
> new file mode 100644
> index 0000000000..293abf1904
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInitLib.inf
> @@ -0,0 +1,61 @@
> +## @file
> +# Component description file for PeiPolicyInit library.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiPolicyInitLib
> +  FILE_GUID                      = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  LIBRARY_CLASS                  = PeiPolicyInitLib
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  BaseLib
> +  CpuPlatformLib
> +  DebugLib
> +  DebugPrintErrorLevelLib
> +  HobLib
> +  IoLib
> +  MemoryAllocationLib
> +  PeiServicesLib
> +  PeiPolicyBoardConfigLib
> +  PeiPolicyUpdateLib
> +  PostCodeLib
> +  SmbusLib
> +  ConfigBlockLib
> +  SiPolicyLib
> +  TimerLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy ##
> CONSUMES
> +
> +
> +[Sources]
> +  PeiPolicyInitPreMem.c
> +  PeiPolicyInit.c
> +  PeiPolicyInit.h
> +  PeiCpuPolicyInit.h
> +  PeiMePolicyInit.h
> +  PeiSaPolicyInit.c
> +  PeiSaPolicyInit.h
> +
> +[Ppis]
> +  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
> +  gSiPolicyPpiGuid                              ## CONSUMES
> +  gSiPreMemPolicyPpiGuid                        ## CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPolicyUpdateLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPolicyUpdateLib.inf
> new file mode 100644
> index 0000000000..3095a7333e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPolicyUpdateLib.inf
> @@ -0,0 +1,272 @@
> +## @file
> +# Module Information file for PEI PolicyUpdateLib Library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiPolicyUpdateLib
> +  FILE_GUID                      = 6EA9585C-3C15-47DA-9FFC-25E9E4EA4D0C
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  LIBRARY_CLASS                  = PeiPolicyUpdateLib|PEIM PEI_CORE SEC
> +
> +[LibraryClasses]
> +  HobLib
> +  BaseCryptLib
> +  CpuPlatformLib
> +  IoLib
> +  PeiSaPolicyLib
> +  ConfigBlockLib
> +  PchGbeLib
> +  PchInfoLib
> +  PchPcieRpLib
> +  HdaVerbTableLib
> +  MemoryAllocationLib
> +  PeiServicesTablePointerLib
> +  PcdLib
> +  Tpm2CommandLib
> +  Tpm12CommandLib
> +  Tpm2DeviceLib
> +  Tpm12DeviceLib
> +  PmcLib
> +  SataLib
> +  PchInfoLib
> +  PciSegmentLib
> +  SiPolicyLib
> +  PeiServicesLib
> +  SpiLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +
> +[FixedPcd]
> +  gSiPkgTokenSpaceGuid.PcdTsegSize                             ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize          ##
> CONSUMES
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdMchBaseAddress             ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable    ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber         ## CONSUMES
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdGttMmAddress      ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress      ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardBomId           ## CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
> +  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit       ## CONSUMES
> +
> +  # SA Misc Config
> +  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd                   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap                   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram              ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize          ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved           ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdData                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize                 ##
> CONSUMES
> +
> +  # Display DDI
> +  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ##
> CONSUMES
> +
> +  # PEG Reset By GPIO
> +  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive            ##
> CONSUMES
> +
> +  # PCIE RTD3 GPIO
> +  gBoardModuleTokenSpaceGuid.PcdRootPortDev                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdRootPortFunc                   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdRootPortIndex                  ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo           ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive           ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo           ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive           ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo           ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive           ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo         ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo           ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive           ##
> CONSUMES
> +
> +  # SPD Address Table
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3            ##
> CONSUMES
> +
> +  # CA Vref Configuration
> +  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent              ##
> CONSUMES
> +
> +  # PCIe Clock Info
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock0                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock1                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock2                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock3                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock4                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock5                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock6                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock7                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock8                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock9                     ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock10                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock11                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock12                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock13                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock14                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock15                    ##
> CONSUMES
> +
> +  # USB 2.0 Port AFE
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe                 ##
> CONSUMES
> +
> +  # USB 2.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10      ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11      ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12      ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13      ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14      ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15      ##
> CONSUMES
> +
> +  # USB 3.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8       ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9       ##
> CONSUMES
> +
> +  # Pch SerialIo I2c Pads Termination
> +  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdEcPresent
> +
> +  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSataLedEnable                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdVrAlertEnable                  ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl          ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable            ##
> CONSUMES
> +
> gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEna
> ble  ## CONSUMES
> +
> gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEna
> ble  ## CONSUMES
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid
> ## CONSUMES
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
> ## CONSUMES
> +
> +[FixedPcd]
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiAcpiReclaimMemorySize
> ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiAcpiNvsMemorySize
> ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize
> ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize
> ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize
> ## CONSUMES
> +
> +[Sources]
> +  PeiPchPolicyUpdatePreMem.c
> +  PeiPchPolicyUpdate.c
> +  PeiCpuPolicyUpdatePreMem.c
> +  PeiCpuPolicyUpdate.c
> +  PeiMePolicyUpdatePreMem.c
> +  PeiMePolicyUpdate.c
> +  PeiSaPolicyUpdate.c
> +  PeiSaPolicyUpdatePreMem.c
> +  PeiSiPolicyUpdate.c
> +
> +[Ppis]
> +  gWdtPpiGuid                                   ## CONSUMES
> +  gPchSpiPpiGuid                                ## CONSUMES
> +  gSiPolicyPpiGuid                              ## CONSUMES
> +  gSiPreMemPolicyPpiGuid                        ## CONSUMES
> +  gPeiTbtPolicyPpiGuid                          ## CONSUMES
> +
> +[Guids]
> +  gTianoLogoGuid                                ## CONSUMES
> +  gSiConfigGuid                                 ## CONSUMES
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLibrary.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLibrary.h
> new file mode 100644
> index 0000000000..a88385f36f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLibrary.h
> @@ -0,0 +1,25 @@
> +/** @file
> +  Header file for the DxeTBTPolicy library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_TBT_POLICY_LIBRARY_H_
> +#define _DXE_TBT_POLICY_LIBRARY_H_
> +
> +#include <Uefi.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <ConfigBlock.h>
> +#include <Library/ConfigBlockLib.h>
> +//#include <SetupVariable.h>
> +#include <Guid/EventGroup.h>
> +
> +#endif // _DXE_TBT_POLICY_LIBRARY_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLibrary.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLibrary.h
> new file mode 100644
> index 0000000000..462bf780e3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLibrary.h
> @@ -0,0 +1,19 @@
> +/** @file
> +  Header file for the PeiTBTPolicy library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_TBT_POLICY_LIBRARY_H_
> +#define _PEI_TBT_POLICY_LIBRARY_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +#endif // _PEI_TBT_POLICY_LIBRARY_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.h
> new file mode 100644
> index 0000000000..52f9fbed8b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.h
> @@ -0,0 +1,234 @@
> +/** @file
> +  Internal header file for Fsp Policy Initialization Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_FSP_POLICY_INIT_LIB_H_
> +#define _PEI_FSP_POLICY_INIT_LIB_H_
> +
> +#include <PiPei.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/ConfigBlockLib.h>
> +
> +#include <FspEas.h>
> +#include <FspmUpd.h>
> +#include <FspsUpd.h>
> +#include <Setup.h>
> +
> +/**
> +  Performs FSP SI PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSiPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +/**
> +  Performs FSP SI PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSiPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  );
> +
> +/**
> +  Performs FSP PCH PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +/**
> +  Performs FSP PCH PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyInit (
> +  IN OUT FSPS_UPD     *FspsUpd
> +  );
> +
> +/**
> +  Performs FSP CPU PEI Policy initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspCpuPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +/**
> +Performs FSP Security PEI Policy initialization.
> +
> +@param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +@retval          EFI_SUCCESS         FSP UPD Data is updated.
> +@retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +@retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSecurityPolicyInitPreMem(
> +IN OUT FSPM_UPD    *FspmUpd
> +);
> +
> +/**
> +  Performs FSP ME PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMePolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +/**
> +  Performs FSP ME PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMePolicyInit (
> +  IN OUT FSPS_UPD     *FspsUpd
> +  );
> +
> +/**
> +  Performs FSP SA PEI Policy initialization in pre-memory.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSaPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +/**
> +  Performs FSP SA PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSaPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  );
> +
> +/**
> +  Performs FSP CPU PEI Policy post memory initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspCpuPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  );
> +
> +/**
> +Performs FSP Security PEI Policy post memory initialization.
> +
> +@param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +@retval          EFI_SUCCESS         FSP UPD Data is updated.
> +@retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +@retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSecurityPolicyInit(
> +IN OUT FSPS_UPD    *FspsUpd
> +);
> +
> +/**
> +  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
> +
> +  @param[in] NameGuid              - File GUID
> +  @param[out] Address              - Pointer to the File Address
> +  @param[out] Size                 - Pointer to File Size
> +
> +  @retval EFI_SUCCESS                Successfull in reading the section from FV
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiGetSectionFromFv (
> +  IN CONST  EFI_GUID        NameGuid,
> +  OUT VOID                  **Address,
> +  OUT UINT32               *Size
> +  );
> +
> +/**
> +  Performs FSP Misc UPD initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMiscUpdInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +#endif // _PEI_FSP_POLICY_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiMiscPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
> new file mode 100644
> index 0000000000..a0c8f2dae7
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_MISC_POLICY_UPDATE_H_
> +#define _PEI_MISC_POLICY_UPDATE_H_
> +
> +#include <FspmUpd.h>
> +
> +/**
> +  Performs FSP Misc UPD initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMiscUpdUpdatePreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  );
> +
> +#endif
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiPchPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiPchPolicyUpdate.h
> new file mode 100644
> index 0000000000..1ff16e2f32
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiPchPolicyUpdate.h
> @@ -0,0 +1,28 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_PCH_POLICY_UPDATE_H_
> +#define _PEI_PCH_POLICY_UPDATE_H_
> +
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +#include <PiPei.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/MmPciLib.h>
> +#include <Library/ConfigBlockLib.h>
> +
> +#include <FspEas.h>
> +#include <FspmUpd.h>
> +#include <FspsUpd.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiSaPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSaPolicyUpdate.h
> new file mode 100644
> index 0000000000..9b8c28c469
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSaPolicyUpdate.h
> @@ -0,0 +1,30 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SA_POLICY_UPDATE_H_
> +#define _PEI_SA_POLICY_UPDATE_H_
> +
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugPrintErrorLevelLib.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/PcdLib.h>
> +#include <CpuAccess.h>
> +
> +#include <FspEas.h>
> +#include <FspmUpd.h>
> +#include <FspsUpd.h>
> +
> +extern EFI_GUID gTianoLogoGuid;
> +
> +#endif
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/FsptCoreUpd.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/FsptCoreUpd.h
> new file mode 100644
> index 0000000000..e7b5ed952b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/FsptCoreUpd.h
> @@ -0,0 +1,40 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __FSPT_CORE_UPD_H__
> +#define __FSPT_CORE_UPD_H__
> +
> +#pragma pack(1)
> +
> +/** Fsp T Core UPD
> +**/
> +typedef struct {
> +
> +/** Offset 0x0020
> +**/
> +  UINT32                      MicrocodeRegionBase;
> +
> +/** Offset 0x0024
> +**/
> +  UINT32                      MicrocodeRegionSize;
> +
> +/** Offset 0x0028
> +**/
> +  UINT32                      CodeRegionBase;
> +
> +/** Offset 0x002C
> +**/
> +  UINT32                      CodeRegionSize;
> +
> +/** Offset 0x0030
> +**/
> +  UINT8                       Reserved[16];
> +} FSPT_CORE_UPD;
> +
> +#pragma pack()
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/Ia32/Fsp.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/Fsp.h
> new file mode 100644
> index 0000000000..1c88285a1d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/Fsp.h
> @@ -0,0 +1,43 @@
> +/** @file
> +  Fsp related definitions
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __FSP_H__
> +#define __FSP_H__
> +
> +//
> +// Fv Header
> +//
> +#define FVH_SIGINATURE_OFFSET         0x28
> +#define FVH_SIGINATURE_VALID_VALUE    0x4856465F  // valid
> signature:_FVH
> +#define FVH_HEADER_LENGTH_OFFSET      0x30
> +#define FVH_EXTHEADER_OFFSET_OFFSET   0x34
> +#define FVH_EXTHEADER_SIZE_OFFSET     0x10
> +
> +//
> +// Ffs Header
> +//
> +#define FSP_HEADER_GUID_DWORD1        0x912740BE
> +#define FSP_HEADER_GUID_DWORD2        0x47342284
> +#define FSP_HEADER_GUID_DWORD3        0xB08471B9
> +#define FSP_HEADER_GUID_DWORD4        0x0C3F3527
> +#define FFS_HEADER_SIZE_VALUE         0x18
> +
> +//
> +// Section Header
> +//
> +#define SECTION_HEADER_TYPE_OFFSET    0x03
> +#define RAW_SECTION_HEADER_SIZE_VALUE 0x04
> +
> +//
> +// Fsp Header
> +//
> +#define FSP_HEADER_IMAGEBASE_OFFSET     0x1C
> +#define FSP_HEADER_TEMPRAMINIT_OFFSET   0x30
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pc
> hHdaVerbTables.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pc
> hHdaVerbTables.h
> new file mode 100644
> index 0000000000..0d26e8ad7a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pc
> hHdaVerbTables.h
> @@ -0,0 +1,3014 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HDA_VERB_TABLES_H_
> +#define _PCH_HDA_VERB_TABLES_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio =
> HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: CFL Display Audio Codec
> +  //  Revision ID = 0xFF
> +  //  Codec Vendor: 0x8086280B
> +  //
> +  0x8086, 0x280B,
> +  0xFF, 0xFF,
> +  //
> +  // Display Audio Verb Table
> +  //
> +  // For GEN9, the Vendor Node ID is 08h
> +  // Port to be exposed to the inbox driver in the vanilla mode: PORT C -
> BIT[7:6] = 01b
> +  0x00878140,
> +  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
> +  0x00571C10,
> +  0x00571D00,
> +  0x00571E56,
> +  0x00571F18,
> +  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
> +  0x00671C20,
> +  0x00671D00,
> +  0x00671E56,
> +  0x00671F18,
> +  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
> +  0x00771C30,
> +  0x00771D00,
> +  0x00771E56,
> +  0x00771F18,
> +  // Disable the third converter and third Pin (NID 08h)
> +  0x00878140
> +);
> +
> +//
> +//codecs verb tables
> +//
> +HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC700)
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0700
> +  //
> +  0x10EC, 0x0700,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
> +  //Realtek HD Audio Codec : ALC700
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x411111F0
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x90170110
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A11030
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40622005
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x04211020
> +  //    NID 0x29 : 0x411111F0
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC10F2
> +  0x001720F2,
> +  0x00172110,
> +  0x001722EC,
> +  0x00172310,
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C00,
> +  0x01271D00,
> +  0x01271E00,
> +  0x01271F40,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C10,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C30,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C05,
> +  0x01D71D20,
> +  0x01D71E62,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C20,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +  //Widget node 0x20 :
> +  0x02050045,
> +  0x02045289,
> +  0x0205004A,
> +  0x0204201B,
> +  //Widget node 0x20 - 1 :
> +  0x05850000,
> +  0x05843888,
> +  0x0205006F,
> +  0x02042C0B,
> +
> +
> +  //Widget node 0X20 for ALC1305   20160603 update
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040000,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040600,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FFD0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02040DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x0204005D,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040442,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040005,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040006,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040008,
> +  0x02050028,
> +  0x0204B000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204002E,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C3,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204D4A0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204400A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040320,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040039,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003B,
> +  0x02050028,
> +  0x0204FFFF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02041DFE,
> +  0x02050029,
> +  0x0204B024,
> +  //
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C0,
> +  0x02050028,
> +  0x020401FA,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C1,
> +  0x02050028,
> +  0x0204DE23,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C2,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C3,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C4,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C5,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C6,
> +  0x02050028,
> +  0x020403F5,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C7,
> +  0x02050028,
> +  0x0204AF1B,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C8,
> +  0x02050028,
> +  0x02041E0A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C9,
> +  0x02050028,
> +  0x0204368E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CA,
> +  0x02050028,
> +  0x020401FA,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CB,
> +  0x02050028,
> +  0x0204DE23,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CC,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CD,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CE,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CF,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D0,
> +  0x02050028,
> +  0x020403F5,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D1,
> +  0x02050028,
> +  0x0204AF1B,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D2,
> +  0x02050028,
> +  0x02041E0A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D3,
> +  0x02050028,
> +  0x0204368E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040040,
> +  0x02050028,
> +  0x0204800F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040062,
> +  0x02050028,
> +  0x02048000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040063,
> +  0x02050028,
> +  0x02044848,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040064,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040065,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040066,
> +  0x02050028,
> +  0x02044004,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040067,
> +  0x02050028,
> +  0x02040802,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040068,
> +  0x02050028,
> +  0x0204890F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040069,
> +  0x02050028,
> +  0x0204E021,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040070,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040071,
> +  0x02050000,
> +  0x02043330,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040072,
> +  0x02050000,
> +  0x02043333,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040073,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040074,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040075,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040076,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040050,
> +  0x02050028,
> +  0x020402EC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040051,
> +  0x02050028,
> +  0x02044909,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040052,
> +  0x02050028,
> +  0x020440B0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040046,
> +  0x02050028,
> +  0x0204C22E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040047,
> +  0x02050028,
> +  0x02040C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040048,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040049,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004A,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004B,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204721F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204009E,
> +  0x02050028,
> +  0x02040001,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040500,
> +  0x02050029,
> +  0x0204B024
> +); // HdaVerbTableAlc700
> +
> +HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC701)
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0701
> +  //
> +  0x10EC, 0x0701,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
> +  //Realtek HD Audio Codec : ALC701
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x411111F0
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x90170110
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A11030
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40610041
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x04211020
> +  //    NID 0x29 : 0x411111F0
> +
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC1124
> +  0x00172024,
> +  0x00172111,
> +  0x001722EC,
> +  0x00172310,
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C00,
> +  0x01271D00,
> +  0x01271E00,
> +  0x01271F40,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C10,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C30,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C41,
> +  0x01D71D00,
> +  0x01D71E61,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C20,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +  //Widget node 0x20 :
> +  0x02050045,
> +  0x02045289,
> +  0x0205004A,
> +  0x0204201B,
> +  //Widget node 0x20 - 1 :
> +  0x05850000,
> +  0x05843888,
> +  0x0205006F,
> +  0x02042C0B
> +); // HdaVerbTableAlc701
> +
> +HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC274)
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0274
> +  //
> +  0x10EC, 0x0274,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
> +  //Realtek HD Audio Codec : ALC274
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
> +  //The number of verb command block : 16
> +
> +  //    NID 0x12 : 0x40000000
> +  //    NID 0x13 : 0x411111F0
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x411111F0
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A11020
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40451B05
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x04211010
> +
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //,DA Codec Subsystem ID  : 0x10EC10F6
> +  0x001720F6,
> +  0x00172110,
> +  0x001722EC,
> +  0x00172310,
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C00,
> +  0x01271D00,
> +  0x01271E00,
> +  0x01271F40,
> +  //Pin widget 0x13 - DMIC
> +  0x01371CF0,
> +  0x01371D11,
> +  0x01371E11,
> +  0x01371F41,
> +  //Pin widget 0x14 - NPC
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S_OUT2
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S_OUT1
> +  0x01771CF0,
> +  0x01771D11,
> +  0x01771E11,
> +  0x01771F41,
> +  //Pin widget 0x18 - I2S_IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C20,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C05,
> +  0x01D71D1B,
> +  0x01D71E45,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C10,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Widget node 0x20 :
> +  0x02050045,
> +  0x02045289,
> +  0x0205006F,
> +  0x02042C0B,
> +  //Widget node 0x20 - 1 :
> +  0x02050035,
> +  0x02048968,
> +  0x05B50001,
> +  0x05B48540,
> +  //Widget node 0x20 - 2 :
> +  0x05850000,
> +  0x05843888,
> +  0x05850000,
> +  0x05843888,
> +  //Widget node 0x20 - 3 :
> +  0x0205004A,
> +  0x0204201B,
> +  0x0205004A,
> +  0x0204201B
> +); //HdaVerbTableAlc274
> +
> +//
> +// CFL S Audio Codec
> +//
> +STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 =
> HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC700) CFL S RVP
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0700
> +  //
> +  0x10EC, 0x0700,
> +  0xFF, 0xFF,
> +
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
> +  //Realtek HD Audio Codec : ALC700
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x90A60130
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x03011010
> +  //    NID 0x17 : 0x90170120
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A1103E
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x03A11040
> +  //    NID 0x1D : 0x40600001
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x0421102F
> +  //    NID 0x29 : 0x411111F0
> +
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC112C
> +  0x0017202C,
> +  0x00172111,
> +  0x001722EC,
> +  0x00172310,
> +
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C30,
> +  0x01271D01,
> +  0x01271EA6,
> +  0x01271F90,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671C10,
> +  0x01671D10,
> +  0x01671E01,
> +  0x01671F03,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C20,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C3E,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71C40,
> +  0x01B71D10,
> +  0x01B71EA1,
> +  0x01B71F03,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C01,
> +  0x01D71D00,
> +  0x01D71E60,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C2F,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +
> +  //Widget node 0x20 - 0  FAKE JD unplug
> +  0x02050008,
> +  0x0204A80F,
> +  0x02050008,
> +  0x0204A80F,
> +  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of
> NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
> +  0x0205006B,
> +  0x02044260,
> +  0x0205006B,
> +  0x02044260,
> +  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
> +  0x05B50010,
> +  0x05B45C1D,
> +  0x0205006F,
> +  0x02040F8B,   //Zeek, 0F8Bh
> +  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent
> control
> +  0x02050045,
> +  0x02045089,
> +  0x0205004A,
> +  0x0204201B,
> +  //Widget node 0x20 - 4   From JD detect
> +  0x02050008,
> +  0x0204A807,
> +  0x02050008,
> +  0x0204A807,
> +  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and
> enable I2S BCLK first
> +  0x02050090,
> +  0x02040424,
> +  0x00171620,
> +  0x00171720,
> +
> +  0x00171520,
> +  0x01770740,
> +  0x01770740,
> +  0x01770740,
> +
> +
> +  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove
> ALC1305 EQ setting
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040000,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02045548,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02041000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040600,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FFD0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02040DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x0204005D,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040442,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040005,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040006,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040008,
> +  0x02050028,
> +  0x0204B000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204002E,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C3,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204D4A0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204400A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040320,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040039,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003B,
> +  0x02050028,
> +  0x0204FFFF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x020400C0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCF0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C0,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C1,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C2,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C3,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C4,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C5,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C6,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C7,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C8,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C9,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CA,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CB,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CC,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CD,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CE,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CF,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D0,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D1,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D2,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D3,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040062,
> +  0x02050028,
> +  0x02048000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040063,
> +  0x02050028,
> +  0x02045F5F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040064,
> +  0x02050028,
> +  0x02042000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040065,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040066,
> +  0x02050028,
> +  0x02044004,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040067,
> +  0x02050028,
> +  0x02040802,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040068,
> +  0x02050028,
> +  0x0204890F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040069,
> +  0x02050028,
> +  0x0204E021,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040070,
> +  0x02050028,
> +  0x02048012,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040071,
> +  0x02050028,
> +  0x02043450,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040072,
> +  0x02050028,
> +  0x02040123,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040073,
> +  0x02050028,
> +  0x02044543,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040074,
> +  0x02050028,
> +  0x02042100,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040075,
> +  0x02050028,
> +  0x02044321,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040076,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040050,
> +  0x02050028,
> +  0x02048200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040051,
> +  0x02050028,
> +  0x02040707,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040052,
> +  0x02050028,
> +  0x02044090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204721F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040012,
> +  0x02050028,
> +  0x0204DFDF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204009E,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040500,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040060,
> +  0x02050028,
> +  0x02042213,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02041DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02043000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040040,
> +  0x02050028,
> +  0x0204000C,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040046,
> +  0x02050028,
> +  0x0204C22E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004B,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024
> +);
> +
> +
> +//
> +// WHL codecs verb tables
> +//
> +HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 =
> HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC700) WHL RVP
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table for WHL PCH boards
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0700
> +  //
> +  0x10EC, 0x0700,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
> +  //Realtek HD Audio Codec : ALC700
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x411111F0
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x90170110
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x02A19040
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40638029
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x02211020
> +  //    NID 0x29 : 0x411111F0
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC10F2
> +  0x001720F2,
> +  0x00172110,
> +  0x001722EC,
> +  0x00172310,
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271CF0,
> +  0x01271D11,
> +  0x01271E11,
> +  0x01271F41,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C10,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C40,
> +  0x01971D90,
> +  0x01971EA1,
> +  0x01971F02,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C29,
> +  0x01D71D80,
> +  0x01D71E63,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C20,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F02,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +  //Widget node 0x20 - 0  FAKE JD unplug
> +  0x02050008,
> +  0x0204A80F,
> +  0x02050008,
> +  0x0204A80F,
> +
> +  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass
> DAC02 DRE(NID5B bit14)
> +  0x05B50010,
> +  0x05B45C1D,
> +  0x0205006F,
> +  0x02040F8B,   //Zeek, 0F8Bh
> +
> +  //Widget node 0x20 -2:
> +  0x02050045,
> +  0x02045089,
> +  0x0205004A,
> +  0x0204201B,
> +
> +  //Widget node 0x20 - 3   From JD detect
> +  0x02050008,
> +  0x0204A807,
> +  0x02050008,
> +  0x0204A807,
> +
> +  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and
> enable I2S BCLK first
> +  0x02050090,
> +  0x02040424,
> +  0x00171620,
> +  0x00171720,
> +
> +  0x00171520,
> +  0x01770740,
> +  0x01770740,
> +  0x01770740,
> +
> +  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove
> ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040000,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02045548,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02041000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040600,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FFD0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02040DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x0204005D,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040442,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040005,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040006,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040008,
> +  0x02050028,
> +  0x0204B000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204002E,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C3,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204D4A0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204400A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040320,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040039,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003B,
> +  0x02050028,
> +  0x0204FFFF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x020400C0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCF0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C0,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C1,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C2,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C3,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C4,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C5,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C6,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C7,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C8,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C9,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CA,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CB,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CC,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CD,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CE,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CF,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D0,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D1,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D2,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D3,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040062,
> +  0x02050028,
> +  0x02048000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040063,
> +  0x02050028,
> +  0x02045F5F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040064,
> +  0x02050028,
> +  0x02042000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040065,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040066,
> +  0x02050028,
> +  0x02044004,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040067,
> +  0x02050028,
> +  0x02040802,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040068,
> +  0x02050028,
> +  0x0204890F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040069,
> +  0x02050028,
> +  0x0204E021,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040070,
> +  0x02050028,
> +  0x02048012,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040071,
> +  0x02050028,
> +  0x02043450,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040072,
> +  0x02050028,
> +  0x02040123,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040073,
> +  0x02050028,
> +  0x02044543,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040074,
> +  0x02050028,
> +  0x02042100,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040075,
> +  0x02050028,
> +  0x02044321,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040076,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040050,
> +  0x02050028,
> +  0x02048200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040051,
> +  0x02050028,
> +  0x02040707,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040052,
> +  0x02050028,
> +  0x02044090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204721F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040012,
> +  0x02050028,
> +  0x0204DFDF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204009E,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040500,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040060,
> +  0x02050028,
> +  0x0204E213,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02041DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02043000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040040,
> +  0x02050028,
> +  0x0204000C,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040046,
> +  0x02050028,
> +  0x0204422E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004B,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024
> +); // WhlHdaVerbTableAlc700
> +
> +#endif // _PCH_HDA_VERB_TABLES_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeMePolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeMePolicyUpdate.h
> new file mode 100644
> index 0000000000..8cbcace075
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeMePolicyUpdate.h
> @@ -0,0 +1,91 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_ME_POLICY_UPDATE_H_
> +#define _DXE_ME_POLICY_UPDATE_H_
> +
> +#include <PiDxe.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Guid/EventGroup.h>
> +#include <IndustryStandard/Acpi10.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Protocol/MePolicy.h>
> +#include <Library/HobLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <ConfigBlock/MePeiConfig.h>
> +
> +#define PLATFORM_BOOT_TABLE_PTR_TYPE   0x1001
> +#define PLATFORM_BOOT_RECORD_TYPE      0x1022
> +//
> +// Timeout values based on HPET
> +//
> +#define HECI_MSG_DELAY                 2000000  ///< show warning msg and
> stay for 2 seconds.
> +#define CONVERSION_MULTIPLIER          1000000  ///< msec to nanosec
> multiplier
> +#define PLATFORM_BOOT_TABLE_SIGNATURE  SIGNATURE_32 ('P', 'B', 'P', 'T')
> +
> +//
> +// Platform Boot Performance Table Record
> +//
> +
> +typedef struct {
> +  UINT16 Type;
> +  UINT8  Length;
> +  UINT8  Revision;
> +  UINT32 Reserved;
> +  UINT64 TimestampDelta1;
> +  UINT64 TimestampDelta2;
> +  UINT64 TimestampDelta3;
> +} PLATFORM_BOOT_TABLE_RECORD;
> +
> +//
> +// Platform boot Performance Table
> +//
> +
> +typedef struct {
> +  EFI_ACPI_COMMON_HEADER     Header;
> +  PLATFORM_BOOT_TABLE_RECORD PlatformBoot;
> +} PLATFORM_BOOT_PERFORMANCE_TABLE;
> +
> +/**
> +  Update ME Policy while MePlatformProtocol is installed.
> +
> +  @param[in] MePolicyInstance     Instance of ME Policy Protocol
> +
> +**/
> +VOID
> +UpdateMePolicyFromMeSetup (
> +  IN ME_POLICY_PROTOCOL           *MePolicyInstance
> +  );
> +
> +/**
> +  Update ME Policy if Setup variable exists.
> +
> +  @param[in, out] MePolicyInstance     Instance of ME Policy Protocol
> +
> +**/
> +VOID
> +UpdateMePolicyFromSetup (
> +  IN OUT ME_POLICY_PROTOCOL     *MePolicyInstance
> +  );
> +
> +/**
> +  Functions performs HECI exchange with FW to update MePolicy settings.
> +
> +  @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
> +UpdateMeSetupCallback (
> +  IN  EFI_EVENT                       Event,
> +  IN  VOID                            *Context
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeSaPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeSaPolicyUpdate.h
> new file mode 100644
> index 0000000000..4521d83567
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeSaPolicyUpdate.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_SA_POLICY_UPDATE_H_
> +#define _DXE_SA_POLICY_UPDATE_H_
> +
> +#include <PiDxe.h>
> +#include <CpuRegs.h>
> +#include <PchAccess.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PciSegmentLib.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiCpuPolicyInit.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiCpuPolicyInit.h
> new file mode 100644
> index 0000000000..25c5213c2d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiCpuPolicyInit.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  Header file for the PeiCpuPolicyInit.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_CPU_POLICY_INIT_H_
> +#define _PEI_CPU_POLICY_INIT_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/CpuPolicyLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/PeiSiPolicyUpdateLib.h>
> +#include <Library/PeiPolicyBoardConfigLib.h>
> +#include <FirwmareConfigurations.h>
> +
> +/**
> +  This function performs CPU PEI Policy initialization in PreMem.
> +
> +  @param[in, out] SiPreMemPolicyPpi  The Si Pre-Mem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +  @retval EFI ERRORS              The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicyPreMem (
> +  IN OUT  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
> +  );
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiMePolicyInit.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiMePolicyInit.h
> new file mode 100644
> index 0000000000..7f3fde9fd8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiMePolicyInit.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  Header file for the PeiMePolicyInit
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_ME_POLICY_INIT_H_
> +#define _PEI_ME_POLICY_INIT_H_
> +
> +#include <PiPei.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiMePolicyLib.h>
> +
> +#include <Ppi/SiPolicy.h>
> +#include <Library/PeiSiPolicyUpdateLib.h>
> +#include <Library/PeiPolicyBoardConfigLib.h>
> +#include <FirwmareConfigurations.h>
> +
> +#endif // _PEI_ME_POLICY_INIT_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInit.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInit.h
> new file mode 100644
> index 0000000000..9c18f85735
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInit.h
> @@ -0,0 +1,23 @@
> +/** @file
> +  Header file for the PolicyInitPei PEIM.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_POLICY_INIT_H_
> +#define _PEI_POLICY_INIT_H_
> +
> +#include <PiPei.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +#include "PeiCpuPolicyInit.h"
> +#include "PeiMePolicyInit.h"
> +#include "PeiSaPolicyInit.h"
> +#include "PeiSiPolicyInit.h"
> +#include <Ppi/SiPolicy.h>
> +#include <Library/PeiPolicyBoardConfigLib.h>
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSaPolicyInit.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSaPolicyInit.h
> new file mode 100644
> index 0000000000..83b18bf533
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSaPolicyInit.h
> @@ -0,0 +1,58 @@
> +/** @file
> +  Header file for the SaPolicyInitPei PEIM.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_POLICY_INIT_PEI_H_
> +#define _SA_POLICY_INIT_PEI_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <SaPolicyCommon.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/PeiSiPolicyUpdateLib.h>
> +#include <Library/PeiPolicyBoardConfigLib.h>
> +#include <FirwmareConfigurations.h>
> +#include <Library/TimerLib.h>
> +#include <Library/GpioLib.h>
> +
> +//
> +// Functions
> +//
> +/**
> +PCIe GPIO Write
> +
> +@param[in] Gpio        - GPIO Number
> +@param[in] Active      - GPIO Active Information; High/Low
> +@param[in] Level       - Write GPIO value (0/1)
> +
> +**/
> +VOID
> +PcieGpioWrite(
> +IN       UINT32                       Gpio,
> +IN       BOOLEAN                      Active,
> +IN       BOOLEAN                      Level
> +);
> +
> +/**
> +PcieCardResetWorkAround performs PCIe Card reset on root port
> +
> +@param[in out] SiPreMemPolicyPpi       - SI_PREMEM_POLICY_PPI
> +
> +@retval EFI_SUCCESS              The policy is installed and initialized.
> +**/
> +EFI_STATUS
> +PcieCardResetWorkAround(
> +IN OUT   SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi
> +);
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSiPolicyInit.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSiPolicyInit.h
> new file mode 100644
> index 0000000000..1a28f426d6
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSiPolicyInit.h
> @@ -0,0 +1,22 @@
> +/** @file
> +  Header file for the PeiSiPolicyInit
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SI_POLICY_INIT_PEI_H_
> +#define _SI_POLICY_INIT_PEI_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/SiPolicyLib.h>
> +#include <Library/PeiSiPolicyUpdateLib.h>
> +#include <Library/PeiPolicyBoardConfigLib.h>
> +#include <FirwmareConfigurations.h>
> +
> +#endif // _SI_POLICY_INIT_PEI_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdate.h
> new file mode 100644
> index 0000000000..254e58edb7
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdate.h
> @@ -0,0 +1,32 @@
> +/** @file
> +  Header file for PEI CpuPolicyUpdate.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_CPU_POLICY_UPDATE_H_
> +#define _PEI_CPU_POLICY_UPDATE_H_
> +
> +#include <PiPei.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Ppi/Wdt.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiPlatformLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <PlatformBoardId.h>
> +#include <PchAccess.h>
> +#include <Register/Cpuid.h>
> +#include <Register/Msr.h>
> +#include <CpuAccess.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <Library/PeiServicesLib.h>
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/CpuPlatformLib.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdate.h
> new file mode 100644
> index 0000000000..37cd373c78
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdate.h
> @@ -0,0 +1,14 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_ME_POLICY_UPDATE_H_
> +#define _PEI_ME_POLICY_UPDATE_H_
> +
> +#include <Library/DebugLib.h>
> +#include <Ppi/SiPolicy.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdate.h
> new file mode 100644
> index 0000000000..5a69852801
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdate.h
> @@ -0,0 +1,25 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_PCH_POLICY_UPDATE_H_
> +#define _PEI_PCH_POLICY_UPDATE_H_
> +
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +#include <PiPei.h>
> +#include <PlatformBoardId.h>
> +#include <Library/PeiPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <PlatformBoardConfig.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdate.h
> new file mode 100644
> index 0000000000..8cf24ed24d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdate.h
> @@ -0,0 +1,53 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SA_POLICY_UPDATE_H_
> +#define _PEI_SA_POLICY_UPDATE_H_
> +
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +#include <PlatformBoardId.h>
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugPrintErrorLevelLib.h>
> +#include <Ppi/Wdt.h>
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/PcdLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <CpuAccess.h>
> +
> +#define WDT_TIMEOUT 60
> +
> +// BClk Frequency Limitations (in Hz)
> +#define BCLK_MAX                538000000
> +#define BCLK_100                100000000
> +#define BCLK_GRANULARITY        1000000
> +#define BCLK_100_KHZ            100000
> +
> +
> +/**
> +  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
> +
> +  @param[in] NameGuid              - File GUID
> +  @param[out] Address              - Pointer to the File Address
> +  @param[out] Size                 - Pointer to File Size
> +
> +  @retval EFI_SUCCESS                Successfull in reading the section from FV
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiGetSectionFromFv (
> +  IN CONST  EFI_GUID        NameGuid,
> +  OUT VOID                  **Address,
> +  OUT UINT32               *Size
> +  );
> +
> +#endif
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSiPolicyUpdate.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSiPolicyUpdate.h
> new file mode 100644
> index 0000000000..38ea081166
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSiPolicyUpdate.h
> @@ -0,0 +1,19 @@
> +/** @file
> +   Header file for PEI SiPolicyUpdate.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_SI_POLICY_UPDATE_H_
> +#define _PEI_SI_POLICY_UPDATE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Ppi/SiPolicy.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLib.c
> new file mode 100644
> index 0000000000..c185cda4ce
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPo
> licyLib/DxeTbtPolicyLib.c
> @@ -0,0 +1,148 @@
> +/** @file
> +  This file is DxeTbtPolicyLib library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <DxeTbtPolicyLibrary.h>
> +#include <TbtBoardInfo.h>
> +#include <Protocol/DxeTbtPolicy.h>
> +#include <Guid/HobList.h>
> +#include <Library/HobLib.h>
> +
> +
> +/**
> +  Update Tbt Policy Callback
> +**/
> +
> +VOID
> +EFIAPI
> +UpdateTbtPolicyCallback (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  DXE_TBT_POLICY_PROTOCOL        *DxeTbtConfig;
> +
> +  DxeTbtConfig = NULL;
> +  Status = EFI_NOT_FOUND;
> +  DEBUG ((DEBUG_INFO, "UpdateTbtPolicyCallback\n"));
> +
> +  Status = gBS->LocateProtocol (
> +                  &gDxeTbtPolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &DxeTbtConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not
> installed!!!\n"));
> +  } else {
> +
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  Print DXE TBT Policy
> +**/
> +VOID
> +TbtPrintDxePolicyConfig (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  UINT8                            Index;
> +  DXE_TBT_POLICY_PROTOCOL          *DxeTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "TbtPrintDxePolicyConfig Start\n"));
> +
> +  DxeTbtConfig = NULL;
> +  Status = EFI_NOT_FOUND;
> +  Status = gBS->LocateProtocol (
> +                  &gDxeTbtPolicyProtocolGuid,
> +                  NULL,
> +                  (VOID **) &DxeTbtConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not
> installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Print DTBT Policy
> +  //
> +  DEBUG ((DEBUG_ERROR, " ========================= DXE TBT POLICY
> ========================= \n"));
> +  for (Index = 0; Index < MAX_DTBT_CONTROLLER_NUMBER; Index++) {
> +    DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieExtraBusRsvd = %x\n",
> Index, DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieExtraBusRsvd));
> +    DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieMemRsvd = %x\n", Index,
> DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieMemRsvd));
> +    DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPcieMemAddrRngMax = %x\n",
> Index,
> DxeTbtConfig->DTbtResourceConfig[Index].DTbtPcieMemAddrRngMax));
> +    DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPciePMemRsvd = %x\n", Index,
> DxeTbtConfig->DTbtResourceConfig[Index].DTbtPciePMemRsvd));
> +    DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->DTbtResourceConfig[%x].DTbtPciePMemAddrRngMax =
> %x\n", Index,
> DxeTbtConfig->DTbtResourceConfig[Index].DTbtPciePMemAddrRngMax));
> +  }
> +
> +  //
> +  // Print TBT Common Policy
> +  //
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAspm =
> %x\n", DxeTbtConfig->TbtCommonConfig.TbtAspm));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtL1SubStates
> = %x\n", DxeTbtConfig->TbtCommonConfig.TbtL1SubStates));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotNotify =
> %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotNotify));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotSMI =
> %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotSMI));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtLtr = %x\n",
> DxeTbtConfig->TbtCommonConfig.TbtLtr));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtPtm = %x\n",
> DxeTbtConfig->TbtCommonConfig.TbtPtm));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtSetClkReq =
> %x\n", DxeTbtConfig->TbtCommonConfig.TbtSetClkReq));
> +  DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = %x\n",
> DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.SecurityMode =
> %x\n", DxeTbtConfig->TbtCommonConfig.SecurityMode));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Gpio5Filter =
> %x\n", DxeTbtConfig->TbtCommonConfig.Gpio5Filter));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TrA0OsupWa =
> %x\n", DxeTbtConfig->TbtCommonConfig.TrA0OsupWa));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch
> = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3Tbt =
> %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3Tbt));
> +  DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = %x\n",
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq
> = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq));
> +  DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay = %x\n",
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Win10Support
> = %x\n", DxeTbtConfig->TbtCommonConfig.Win10Support));
> +  DEBUG ((DEBUG_INFO,
> "DxeTbtConfig->TbtCommonConfig.TbtVtdBaseSecurity = %x\n",
> DxeTbtConfig->TbtCommonConfig.TbtVtdBaseSecurity));
> +  DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.ControlIommu
> = %x\n", DxeTbtConfig->TbtCommonConfig.ControlIommu));
> +  return;
> +}
> +
> +/**
> +  Install Tbt Policy
> +
> +  @param[in] ImageHandle                Image handle of this driver.
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallTbtPolicy (
> +  IN  EFI_HANDLE                    ImageHandle
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  DXE_TBT_POLICY_PROTOCOL       *DxeTbtPolicy;
> +
> +  DEBUG ((DEBUG_INFO, "Install DXE TBT Policy\n"));
> +
> +  DxeTbtPolicy = NULL;
> +  //Alloc memory for DxeTbtPolicy
> +  DxeTbtPolicy = (DXE_TBT_POLICY_PROTOCOL *) AllocateZeroPool (sizeof
> (DXE_TBT_POLICY_PROTOCOL));
> +  if (DxeTbtPolicy == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &ImageHandle,
> +                  &gDxeTbtPolicyProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  DxeTbtPolicy
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Install Tbt Secure Boot List protocol failed\n"));
> +  }
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSm
> mTbtCommonLib/TbtCommonLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSm
> mTbtCommonLib/TbtCommonLib.c
> new file mode 100644
> index 0000000000..690c9acf95
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSm
> mTbtCommonLib/TbtCommonLib.c
> @@ -0,0 +1,316 @@
> +/** @file
> +  PeiTbtInit library implementition with empty functions.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/TbtCommonLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/GpioLib.h>
> +
> +
> +/**
> +  Selects the proper TBT Root port to assign resources
> +  based on the user input value
> +
> +  @param[in]  SetupData          Pointer to Setup data
> +
> +  @retval     TbtSelectorChosen  Rootport number.
> +**/
> +VOID
> +GetRootporttoSetResourcesforTbt (
> +  IN UINTN                              RpIndex,
> +  OUT UINT8                             *RsvdExtraBusNum,
> +  OUT UINT16                            *RsvdPcieMegaMem,
> +  OUT UINT8                             *PcieMemAddrRngMax,
> +  OUT UINT16                            *RsvdPciePMegaMem,
> +  OUT UINT8                             *PciePMemAddrRngMax,
> +  OUT BOOLEAN                           *SetResourceforTbt
> +  )
> +{
> +  UINTN TbtRpNumber;
> +  TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber);
> +
> +    if (RpIndex == (TbtRpNumber - 1)) {
> +        *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
> +        *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd);
> +        *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
> +        *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd);
> +        *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
> +        *SetResourceforTbt = TRUE;
> +      }
> +      else {
> +        *SetResourceforTbt = FALSE;
> +      }
> +  }
> +
> +/**
> +  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
> +  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
> +  @param[in]  TimeOut                   Time out with 100 ms garnularity
> +  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to
> Clear/Set)
> +  @param[out] *Tbt2PcieValue Function   Register value
> +**/
> +BOOLEAN
> +InternalWaitforCommandCompletion(
> +  IN  UINT64   CommandOffsetAddress,
> +  IN  UINT32   TimeOut,
> +  IN  BOOLEAN  Tbt2PcieDone,
> +  OUT UINT32   *Tbt2PcieValue
> +  )
> +{
> +  BOOLEAN ReturnFlag;
> +  UINT32  Tbt2PcieCheck;
> +
> +  ReturnFlag = FALSE;
> +  while (TimeOut-- > 0) {
> +    *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress);
> +
> +    if (0xFFFFFFFF == *Tbt2PcieValue ) {
> +      //
> +      // Device is not here return now
> +      //
> +      ReturnFlag     = FALSE;
> +      break;
> +    }
> +
> +    if(Tbt2PcieDone) {
> +      Tbt2PcieCheck  =  *Tbt2PcieValue & TBT2PCIE_DON_R;
> +    } else {
> +      Tbt2PcieCheck  = !(*Tbt2PcieValue & TBT2PCIE_DON_R);
> +    }
> +
> +    if (Tbt2PcieCheck) {
> +      ReturnFlag     = TRUE;
> +      break;
> +    }
> +
> +    MicroSecondDelay(TBT_MAIL_BOX_DELAY);
> +  }
> +  return ReturnFlag;
> +}
> +/**
> +  Get Security Level.
> +  @param[in]  Bus       Bus number Host Router (DTBT)
> +  @param[in]  Device    Device number for Host Router (DTBT)
> +  @param[in]  Function  Function number for  Host Router (DTBT)
> +  @param[in]  Command   Command for  Host Router (DTBT)
> +  @param[in]  Timeout   Time out with 100 ms garnularity
> +**/
> +UINT8
> +GetSecLevel (
> +  IN    UINT8                   Bus,
> +  IN    UINT8                   Device,
> +  IN    UINT8                   Function,
> +  IN    UINT8                   Command,
> +  IN    UINT32                  Timeout
> +  )
> +{
> +  UINT64       Pcie2Tbt;
> +  UINT64       Tbt2Pcie;
> +  UINT32       RegisterValue;
> +  UINT8        ReturnFlag;
> +
> +  ReturnFlag           = 0xFF;
> +
> +  DEBUG ((DEBUG_INFO, "GetSecLevel() \n"));
> +
> +  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
> +  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
> +
> +  PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
> +
> +  if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE,
> &RegisterValue)) {
> +    ReturnFlag     = (UINT8) (0xFF & (RegisterValue >> 8));
> +  }
> +
> +  PciSegmentWrite32 (Pcie2Tbt, 0);
> +
> +  InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE,
> &RegisterValue);
> +  DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag));
> +
> +  return ReturnFlag;
> +}
> +
> +/**
> +  Set Security Level.
> +  @param[in]  Data      Security State
> +  @param[in]  Bus       Bus number for Host Router (DTBT)
> +  @param[in]  Device    Device number for Host Router (DTBT)
> +  @param[in]  Function  Function number for Host Router (DTBT)
> +  @param[in]  Command   Command for  Host Router (DTBT)
> +  @param[in]  Timeout   Time out with 100 ms garnularity
> +**/
> +BOOLEAN
> +SetSecLevel (
> +  IN    UINT8                   Data,
> +  IN    UINT8                   Bus,
> +  IN    UINT8                   Device,
> +  IN    UINT8                   Function,
> +  IN    UINT8                   Command,
> +  IN    UINT32                  Timeout
> +  )
> +{
> +  UINT64       Pcie2Tbt;
> +  UINT64       Tbt2Pcie;
> +  UINT32       RegisterValue;
> +  BOOLEAN      ReturnFlag;
> +
> +  ReturnFlag   = FALSE;
> +
> +  DEBUG ((DEBUG_INFO, "SetSecLevel() \n"));
> +
> +  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
> +  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
> +
> +  PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B);
> +
> +  ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout,
> TRUE, &RegisterValue);
> +  DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue));
> +  PciSegmentWrite32 (Pcie2Tbt, 0);
> +
> +  InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE,
> &RegisterValue);
> +  DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag));
> +  return ReturnFlag;
> +}
> +
> +/**
> +Based on the Security Mode Selection, BIOS drives FORCE_PWR.
> +
> +@param[in]  GpioNumber
> +@param[in]  Value
> +**/
> +VOID
> +ForceDtbtPower(
> +  IN  UINT8          GpioAccessType,
> +  IN  UINT8          Expander,
> +  IN  UINT32         GpioNumber,
> +  IN  BOOLEAN        Value
> +)
> +{
> +  if (GpioAccessType == 0x01) {
> +    // PCH
> +    GpioSetOutputValue (GpioNumber, (UINT32)Value);
> +  } else if (GpioAccessType == 0x02) {
> +    // IoExpander {TCA6424A}
> +    GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value);
> +  }
> +}
> +
> +/**
> +Execute TBT Mail Box Command
> +
> +@param[in]  Command   TBT Command
> +@param[in]  Bus       Bus number for  Host Router (DTBT)
> +@param[in]  Device    Device number for  Host Router (DTBT)
> +@param[in]  Function  Function number for  Host Router (DTBT)
> +@param[in]  Timeout   Time out with 100 ms garnularity
> +@Retval     true      if command executes succesfully
> +**/
> +BOOLEAN
> +TbtSetPcie2TbtCommand(
> +   IN    UINT8                   Command,
> +   IN    UINT8                   Bus,
> +   IN    UINT8                   Device,
> +   IN    UINT8                   Function,
> +   IN    UINT32                  Timeout
> +)
> +{
> +   UINT64      Pcie2Tbt;
> +   UINT64      Tbt2Pcie;
> +   UINT32      RegisterValue;
> +   BOOLEAN     ReturnFlag;
> +
> +   GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
> +   GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
> +
> +   PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
> +
> +   ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout,
> TRUE, &RegisterValue);
> +
> +   PciSegmentWrite32(Pcie2Tbt, 0);
> +
> +   return ReturnFlag;
> +}
> +/**
> +  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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 If Invalid Root Port Number or TYPE is
> Passed
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDTbtRpDevFun (
> +  IN  BOOLEAN Type,
> +  IN  UINTN   RpNumber,
> +  OUT UINTN   *RpDev,
> +  OUT UINTN   *RpFunc
> +  )
> +{
> +  EFI_STATUS            Status;
> +  UINTN                 TbtRpDev;
> +  UINTN                 TbtRpFunc;
> +
> +  Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if
> valid input found.
> +  //
> +  // PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be
> +  // with device number 0x1 and Function number 0,1 and 2 respectively.
> +  //
> +  if (Type == DTBT_TYPE_PEG)
> +  {
> +    //
> +    //  PEG Rootport
> +    //
> +    if (RpNumber <= 2) {
> +      *RpDev  =   0x01;
> +      *RpFunc =   RpNumber;
> +      Status  =   EFI_SUCCESS;
> +    }
> +  }
> +  if (Type == DTBT_TYPE_PCH)
> +  {
> +    //
> +    //  PCH Rootport
> +    //
> +    if (RpNumber <= 23) {
> +      Status  = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc);
> +      *RpDev  = TbtRpDev;
> +      *RpFunc = TbtRpFunc;
> +    }
> +  }
> +
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> +BOOLEAN
> +IsTbtHostRouter (
> +  IN    UINT16  DeviceID
> +  )
> +{
> +  switch (DeviceID) {
> +  case AR_HR_2C:
> +  case AR_HR_4C:
> +  case AR_HR_LP:
> +  case AR_HR_C0_2C:
> +  case AR_HR_C0_4C:
> +  case TR_HR_2C:
> +  case TR_HR_4C:
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +} // IsTbtHostRouter
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLib.c
> new file mode 100644
> index 0000000000..ffd8416660
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPol
> icyLib/PeiTbtPolicyLib.c
> @@ -0,0 +1,206 @@
> +/** @file
> +  This file is PeiTbtPolicyLib library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/PeiServicesLib.h>
> +#include <Library/GpioLib.h>
> +#include <PiPei.h>
> +#include <PeiTbtPolicyLibrary.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Ppi/PeiTbtPolicy.h>
> +#include <Base.h>
> +#include <GpioConfig.h>
> +
> +/**
> +  Update PEI TBT Policy Callback
> +**/
> +VOID
> +EFIAPI
> +UpdatePeiTbtPolicy (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *VariableServices;
> +  PEI_TBT_POLICY                   *PeiTbtConfig;
> +
> +  PeiTbtConfig = NULL;
> +  Status = EFI_NOT_FOUND;
> +
> +  DEBUG ((DEBUG_INFO, "UpdatePeiTbtPolicy \n"));
> +
> +  Status = PeiServicesLocatePpi (
> +             &gEfiPeiReadOnlyVariable2PpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &VariableServices
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Update DTBT Policy
> +  //
> +  PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn = PcdGet8
> (PcdDTbtControllerEn);
> +  if (PcdGet8 (PcdDTbtControllerType) == TYPE_PEG)
> +  {
> +    PeiTbtConfig-> DTbtControllerConfig.Type = (UINT8) TYPE_PEG;
> +    PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = 1; // PEG RP 1
> (Function no. 0)
> +  }
> +  else {
> +    PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = PcdGet8
> (PcdDTbtPcieRpNumber);
> +    PeiTbtConfig-> DTbtControllerConfig.Type = PcdGet8
> (PcdDTbtControllerType);
> +  }
> +  PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad =
> (GPIO_PAD) PcdGet32 (PcdDTbtCioPlugEventGpioPad);
> +  if
> (GpioCheckFor2Tier(PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.
> GpioPad)) {
> +
> PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePor
> ting = 0;
> +
> PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature =
> SIGNATURE_32('X', 'T', 'B', 'T');
> +  }
> +  else {
> +
> PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePor
> ting = 1;
> +    //
> +    // Update Signature based on platform GPIO.
> +    //
> +
> PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature =
> SIGNATURE_32('X', 'T', 'B', 'T');
> +  }
> +  PeiTbtConfig->DTbtCommonConfig.TbtBootOn = PcdGet8
> (PcdDTbtBootOn);
> +  PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = PcdGet8 (PcdDTbtUsbOn);
> +  PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = PcdGet8
> (PcdDTbtGpio3ForcePwr);
> +  PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = PcdGet16
> (PcdDTbtGpio3ForcePwrDly);
> +
> +  return;
> +}
> +
> +/**
> +  Print PEI TBT Policy
> +**/
> +VOID
> +EFIAPI
> +TbtPrintPeiPolicyConfig (
> +  VOID
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  EFI_STATUS                       Status;
> +  PEI_TBT_POLICY                   *PeiTbtConfig;
> +
> +  PeiTbtConfig = NULL;
> +  Status = EFI_NOT_FOUND;
> +  DEBUG ((DEBUG_INFO, "TbtPrintPolicyConfig Start\n"));
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Print DTBT Policy
> +  //
> +  DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print BEGIN
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", PEI_TBT_POLICY_REVISION));
> +  DEBUG ((DEBUG_INFO, "------------------------ PEI_TBT_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n", PEI_TBT_POLICY_REVISION));
> +
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.DTbtControllerEn = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn));
> +  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.Type = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.Type));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.PcieRpNumber = %x\n", PeiTbtConfig->
> DTbtControllerConfig.PcieRpNumber));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioPad = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioLevel = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioPad = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioLevel = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = %x\n",
> PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature =
> %x\n", PeiTbtConfig->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePo
> rting = %x\n", PeiTbtConfig->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting));
> +
> +
> +  //
> +  // Print DTBT Common Policy
> +  //
> +  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtBootOn =
> %x\n", PeiTbtConfig->DTbtCommonConfig.TbtBootOn));
> +  DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtUsbOn =
> %x\n", PeiTbtConfig->DTbtCommonConfig.TbtUsbOn));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = %x\n",
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = %x\n",
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration = %x\n",
> PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration));
> +  DEBUG ((DEBUG_INFO,
> "PeiTbtConfig->DTbtCommonConfig.PcieRstSupport = %x\n",
> PeiTbtConfig->DTbtCommonConfig.PcieRstSupport));
> +
> +  DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print END
> -----------------\n"));
> +  DEBUG_CODE_END ();
> +
> +  return;
> +}
> +
> +/**
> +  Install Tbt Policy
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallPeiTbtPolicy (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_PEI_PPI_DESCRIPTOR        *PeiTbtPolicyPpiDesc;
> +  PEI_TBT_POLICY                *PeiTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "Install PEI TBT Policy\n"));
> +
> +  PeiTbtConfig = NULL;
> +
> +  //
> +  // Allocate memory for PeiTbtPolicyPpiDesc
> +  //
> +  PeiTbtPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof
> (EFI_PEI_PPI_DESCRIPTOR));
> +  ASSERT (PeiTbtPolicyPpiDesc != NULL);
> +  if (PeiTbtPolicyPpiDesc == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Allocate memory and initialize all default to zero for PeiTbtPolicy
> +  //
> +  PeiTbtConfig = (PEI_TBT_POLICY *) AllocateZeroPool (sizeof
> (PEI_TBT_POLICY));
> +  ASSERT (PeiTbtConfig != NULL);
> +  if (PeiTbtConfig == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Initialize PPI
> +  //
> +  PeiTbtPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> +  PeiTbtPolicyPpiDesc->Guid = &gPeiTbtPolicyPpiGuid;
> +  PeiTbtPolicyPpiDesc->Ppi = PeiTbtConfig;
> +
> +  Status = PeiServicesInstallPpi (PeiTbtPolicyPpiDesc);
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Install PEI TBT Policy failed\n"));
> +  }
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/P
> eiDTbtInitLib/PeiDTbtInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/P
> eiDTbtInitLib/PeiDTbtInitLib.c
> new file mode 100644
> index 0000000000..f33ddebdb3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/P
> eiDTbtInitLib/PeiDTbtInitLib.c
> @@ -0,0 +1,567 @@
> +/** @file
> +  Thunderbolt(TM) Pei Library
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/PeiServicesLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/GpioLib.h>
> +#include <GpioPinsSklLp.h>
> +#include <GpioPinsSklH.h>
> +#include <Library/TimerLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MmPciLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/GpioExpanderLib.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +
> +#include <Base.h>
> +#include <Library/TbtCommonLib.h>
> +#include <TbtBoardInfo.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Ppi/PeiTbtPolicy.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PeiTbtPolicyLib.h>
> +#include <Library/PchPmcLib.h>
> +#include <Private/Library/PeiDTbtInitLib.h>
> +
> +/**
> +Is host router (For dTBT) or End Point (For iTBT) present before sleep
> +
> +@param[in] ControllerType - DTBT_CONTROLLER or ITBT_CONTROLLER
> +@param[in] Controller     - Controller begin offset of CMOS
> +
> +@Retval     TRUE      There is a TBT HostRouter presented before sleep
> +@Retval     FALSE     There is no TBT HostRouter presented before sleep
> +
> +BOOLEAN
> +IsHostRouterPresentBeforeSleep(
> +IN  UINT8        ControllerType,
> +IN  UINT8        Controller
> +)
> +{
> +  UINT8 SavedState;
> +
> +  SavedState = (UINT8)GetTbtHostRouterStatus();
> +  if (ControllerType == DTBT_CONTROLLER){
> +    return ((SavedState & (DTBT_SAVE_STATE_OFFSET << Controller)) ==
> (DTBT_SAVE_STATE_OFFSET << Controller));
> +  } else {
> +    if (ControllerType == ITBT_CONTROLLER) {
> +      return ((SavedState & (ITBT_SAVE_STATE_OFFSET << Controller)) ==
> (ITBT_SAVE_STATE_OFFSET << Controller));
> +    }
> +  }
> +  return 0;
> +}
> +**/
> +
> +/**
> +Execute TBT PCIE2TBT_SX_EXIT_TBT_CONNECTED Mail Box Command for S4
> mode with PreBootAclEnable
> +
> +@param[in]  Bus       Bus number for Host Router (DTBT)
> +@param[in]  Device    Device number for Host Router (DTBT)
> +@param[in]  Function  Function number for Host Router (DTBT)
> +@param[in]  Timeout   Time out with 100 ms garnularity
> +@Retval     true      if command executes succesfully
> +**/
> +BOOLEAN
> +TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(
> +   IN    UINT8                   Bus,
> +   IN    UINT8                   Device,
> +   IN    UINT8                   Function,
> +   IN    UINT32                  Timeout
> +)
> +{
> +  UINT64      Pcie2Tbt;
> +  UINT64      Tbt2Pcie;
> +  UINT32      RegisterValue;
> +  BOOLEAN     ReturnFlag;
> +  UINT32      Command;
> +
> +  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
> +  GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
> +
> +// If PreBootAcl is Enable, we need to enable DATA bit while sending SX EXIT
> MAIL BOX Command
> +  Command = (1 << 8) | PCIE2TBT_SX_EXIT_TBT_CONNECTED;
> +  PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
> +
> +  ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout,
> TRUE, &RegisterValue);
> +
> +  PciSegmentWrite32(Pcie2Tbt, 0);
> +
> +  return ReturnFlag;
> +}
> +
> +/**
> +Set the Sleep Mode if the HR is up.
> +@param[in]  Bus       Bus number for Host Router (DTBT)
> +@param[in]  Device    Device number for Host Router (DTBT)
> +@param[in]  Function  Function number for Host Router (DTBT)
> +**/
> +VOID
> +TbtSetSxMode(
> +IN    UINT8                   Bus,
> +IN    UINT8                   Device,
> +IN    UINT8                   Function,
> +IN    UINT8                   TbtBootOn
> +)
> +{
> +  UINT64                          TbtUsDevId;
> +  UINT64                          Tbt2Pcie;
> +  UINT32                          RegVal;
> +  UINT32                          MaxLoopCount;
> +  UINTN                           Delay;
> +  UINT8                           RetCode;
> +  EFI_BOOT_MODE                   BootMode;
> +  EFI_STATUS                      Status;
> +
> +  TbtUsDevId = PCI_SEGMENT_LIB_ADDRESS(0, Bus, Device, Function, 0);
> +  GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
> +
> +  MaxLoopCount = TBT_5S_TIMEOUT;  // Wait 5 sec
> +  Delay = 100 * 1000;
> +  RetCode = 0x62;
> +
> +  Status = PeiServicesGetBootMode(&BootMode);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  if ((BootMode == BOOT_ON_S4_RESUME) && (TbtBootOn == 2)) {
> +    MaxLoopCount = TBT_3S_TIMEOUT;
> +    if (!TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(Bus, Device,
> Function, MaxLoopCount)) {
> +      //
> +      // Nothing to wait, HR is not responsive
> +      //
> +      return;
> +    }
> +  }
> +  else {
> +    if (!TbtSetPcie2TbtCommand(PCIE2TBT_SX_EXIT_TBT_CONNECTED, Bus,
> Device, Function, MaxLoopCount)) {
> +      //
> +      // Nothing to wait, HR is not responsive
> +      //
> +      return;
> +    }
> +  }
> +
> +  DEBUG((DEBUG_INFO, "Wait for Dev ID != 0xFF\n"));
> +
> +  while (MaxLoopCount-- > 0) {
> +    //
> +    // Check what HR still here
> +    //
> +    RegVal = PciSegmentRead32(Tbt2Pcie);
> +    if (0xFFFFFFFF == RegVal) {
> +      RetCode = 0x6F;
> +      break;
> +    }
> +    //
> +    // Check completion of TBT link
> +    //
> +    RegVal = PciSegmentRead32(TbtUsDevId);
> +    if (0xFFFFFFFF != RegVal) {
> +      RetCode = 0x61;
> +      break;
> +    }
> +
> +    MicroSecondDelay(Delay);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "Return code = 0x%x\n", RetCode));
> +}
> +/**
> +  set tPCH25 Timing to 10 ms for DTBT.
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtSetTPch25Timing (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +)
> +{
> +  DEBUG ((DEBUG_INFO, "DTbtSetTPch25Timing call Inside\n"));
> +  UINT32                PchPwrmBase;
> +
> +  //
> +  //During boot, reboot and wake  tPCH25 Timing should be set to 10 ms
> +  //
> +  MmioOr32 (
> +    (UINTN) (PchPwrmBase + R_PCH_PWRM_CFG),
> +    (BIT0 | BIT1)
> +    );
> +
> +  DEBUG((DEBUG_INFO, "DTbtSetTPch25Timing call Return\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Do ForcePower for DTBT Controller
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtForcePower (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +)
> +{
> +
> +  DEBUG ((DEBUG_INFO, "DTbtForcePower call Inside\n"));
> +
> +      if (PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr) {
> +        DEBUG((DEBUG_INFO, "ForcePwrGpio.GpioPad = %x \n",
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
> +        ForceDtbtPower(PeiTbtConfig->
> DTbtControllerConfig.ForcePwrGpio.GpioAccessType,PeiTbtConfig->
> DTbtControllerConfig.ForcePwrGpio.Expander, PeiTbtConfig->
> DTbtControllerConfig.ForcePwrGpio.GpioPad, PeiTbtConfig->
> DTbtControllerConfig.ForcePwrGpio.GpioLevel);
> +        DEBUG((DEBUG_INFO, "ForceDtbtPower asserted \n"));
> +
> MicroSecondDelay(PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly *
> 1000);
> +        DEBUG((DEBUG_INFO, "Delay after ForceDtbtPower = 0x%x ms \n",
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
> +      }
> +
> +  DEBUG ((DEBUG_INFO, "DTbtForcePower call Return\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Clear VGA Registers for DTBT.
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtClearVgaRegisters (
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +)
> +{
> +  UINTN      RpDev;
> +  UINTN      RpFunc;
> +  EFI_STATUS Status;
> +  UINT64     BridngeBaseAddress;
> +  UINT16     Data16;
> +
> +  DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Inside\n"));
> +
> +  Status = EFI_SUCCESS;
> +
> +  Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type,
> PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
> +  ASSERT_EFI_ERROR(Status);
> +  //
> +  // VGA Enable and VGA 16-bit decode registers of Bridge control register of
> Root port where
> +  // Host router resides should be cleaned
> +  //
> +
> +  BridngeBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0, (UINT32)RpDev,
> (UINT32)RpFunc, 0);
> +  Data16 = PciSegmentRead16(BridngeBaseAddress +
> PCI_BRIDGE_CONTROL_REGISTER_OFFSET);
> +  Data16 &= (~(EFI_PCI_BRIDGE_CONTROL_VGA |
> EFI_PCI_BRIDGE_CONTROL_VGA_16));
> +  PciSegmentWrite16(BridngeBaseAddress +
> PCI_BRIDGE_CONTROL_REGISTER_OFFSET, Data16);
> +
> +  DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Return\n"));
> +  return Status;
> +}
> +
> +/**
> +  Exectue Mail box command "Boot On".
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtBootOn(
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +)
> +{
> +  EFI_STATUS Status;
> +  UINT32     OrgBusNumberConfiguration;
> +  UINTN      RpDev;
> +  UINTN      RpFunc;
> +
> +  DEBUG((DEBUG_INFO, "DTbtBootOn call Inside\n"));
> +
> +  Status = EFI_SUCCESS;
> +
> +      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type,
> PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
> +      ASSERT_EFI_ERROR(Status);
> +      OrgBusNumberConfiguration = PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
> +      //
> +      // Set Sec/Sub buses to 0xF0
> +      //
> +      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
> +      //
> +      //When Thunderbolt(TM) boot [TbtBootOn] is enabled in bios setup we
> need to do the below:
> +      //Bios should send "Boot On" message through PCIE2TBT register
> +      //The Boot On command as described above would include the
> command and acknowledge from FW (with the default timeout in BIOS),
> +      //once the Boot On command is completed it is guaranteed that the
> AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
> +      //next step from BIOS is enumeration using SMI
> +      //
> +
> +      if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
> +        //
> +        // Exectue Mail box command "Boot On / Pre-Boot ACL"
> +        //
> +        //Command may be executed only during boot/reboot and not during
> Sx exit flow
> +        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 1) {
> +          if (!TbtSetPcie2TbtCommand(PCIE2TBT_BOOT_ON, 0xF0, 0, 0,
> TBT_5S_TIMEOUT)) {
> +            //
> +            // Nothing to wait, HR is not responsive
> +            //
> +            DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Boot On message
> sent failed \n"));
> +          }
> +        }
> +        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2) {
> +          if (!TbtSetPcie2TbtCommand(PCIE2TBT_PREBOOTACL, 0xF0, 0, 0,
> TBT_3S_TIMEOUT)) {
> +            //
> +            // Nothing to wait, HR is not responsive
> +            //
> +            DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Pre-Boot ACL
> message sent failed \n"));
> +          }
> +        }
> +      }
> +      //
> +      // Reset Sec/Sub buses to original value
> +      //
> +      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET),
> OrgBusNumberConfiguration);
> +
> +  DEBUG((DEBUG_INFO, "DTbtBootOn call Return\n"));
> +  return Status;
> +}
> +
> +/**
> +  Exectue Mail box command "USB On".
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtUsbOn(
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +)
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           RpDev;
> +  UINTN                           RpFunc;
> +  UINT32                          OrgBusNumberConfiguration;
> +  UINT64                          TbtBaseAddress;
> +  UINT32                          MaxWaitIter;
> +  UINT32                          RegVal;
> +  EFI_BOOT_MODE                   BootMode;
> +
> +  DEBUG((DEBUG_INFO, "DTbtUsbOn call Inside\n"));
> +
> +  Status = EFI_SUCCESS;
> +
> +      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type,
> PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
> +      ASSERT_EFI_ERROR(Status);
> +      OrgBusNumberConfiguration =
> PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
> +      //
> +      // Set Sec/Sub buses to 0xF0
> +      //
> +      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
> +
> +      //
> +      //When Thunderbolt(TM) Usb boot [TbtUsbOn] is enabled in bios setup
> we need to do the below:
> +      //Bios should send "Usb On" message through PCIE2TBT register
> +      //The Usb On command as described above would include the command
> and acknowledge from FW (with the default timeout in BIOS),
> +      //once the Usb On command is completed it is guaranteed that the
> AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
> +      //next step from BIOS is enumeration using SMI
> +      //
> +      if (PeiTbtConfig->DTbtCommonConfig.TbtUsbOn) {
> +        if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
> +          MaxWaitIter = 50;   // Wait 5 sec
> +          TbtBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0xF0, 0, 0, 0);
> +          //
> +          // Driver clears the PCIe2TBT Valid bit to support two consicutive
> mailbox commands
> +          //
> +          PciSegmentWrite32(TbtBaseAddress + PCIE2TBT_DTBT_R, 0);
> +          DEBUG((DEBUG_INFO, "TbtBaseAddress + PCIE2TBT_DTBT_R = 0x%lx
> \n", TbtBaseAddress + PCIE2TBT_DTBT_R));
> +          while (MaxWaitIter-- > 0) {
> +            RegVal = PciSegmentRead32(TbtBaseAddress + TBT2PCIE_DTBT_R);
> +            if (0xFFFFFFFF == RegVal) {
> +              //
> +              // Device is not here return now
> +              //
> +              DEBUG((DEBUG_INFO, "TBT device is not present \n"));
> +              break;
> +            }
> +
> +            if (!(RegVal & TBT2PCIE_DON_R)) {
> +              break;
> +            }
> +            MicroSecondDelay(100 * 1000);
> +          }
> +        }
> +
> +        Status = PeiServicesGetBootMode(&BootMode);
> +        ASSERT_EFI_ERROR(Status);
> +
> +        //
> +        // Exectue Mail box command "Usb On"
> +        //
> +        //Command may be executed only during boot/reboot and not during
> S3 exit flow
> +        //In case of S4 Exit send USB ON cmd only if Host Router was
> inactive/not present during S4 entry
> +        if ((BootMode == BOOT_ON_S4_RESUME) ) {
> +          // USB_ON cmd not required
> +        } else {
> +          if (!TbtSetPcie2TbtCommand(PCIE2TBT_USB_ON, 0xF0, 0, 0,
> TBT_5S_TIMEOUT)) {
> +            //
> +            // Nothing to wait, HR is not responsive
> +            //
> +            DEBUG((DEBUG_INFO, "<TbtPei> TbtBootSupport - Usb On message
> sent failed \n"));
> +          }
> +        }
> +      }
> +      //
> +      // Reset Sec/Sub buses to original value
> +      //
> +      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET),
> OrgBusNumberConfiguration);
> +
> +  DEBUG((DEBUG_INFO, "DTbtUsbOn call return\n"));
> +  return Status;
> +}
> +
> +/**
> +  Exectue Mail box command "Sx Exit".
> +
> +  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     EFI_UNSUPPORTED  dTBT is not supported.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DTbtSxExitFlow(
> +  IN  PEI_TBT_POLICY  *PeiTbtConfig
> +)
> +{
> +  EFI_STATUS                      Status;
> +  UINT32                          OrgBusNumberConfiguration;
> +  UINTN                           RpDev;
> +  UINTN                           RpFunc;
> +  UINT32                          Count;
> +
> +  DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Inside\n"));
> +
> +  Status = EFI_SUCCESS;
> +  Count = 0;
> +
> +      Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type,
> PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
> +      ASSERT_EFI_ERROR(Status);
> +      OrgBusNumberConfiguration =
> PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
> +      //
> +      // Set Sec/Sub buses to 0xF0
> +      //
> +      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
> +
> +      if ( (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2)) {
> +        //
> +        // WA: When system with TBT 3.1 device, resume SX system need to wait
> device ready. In document that maximum time out should be 500ms.
> +        //
> +        while (PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS(0, 0xf0, 0x0,
> 0x0, 0x08)) == 0xffffffff) { //End Device will be with Device Number 0x0, Function
> Number 0x0.
> +          MicroSecondDelay(STALL_ONE_MICRO_SECOND * 1000); // 1000usec
> +          Count++;
> +          if (Count > 10000) { //Allowing Max Delay of 10 sec for CFL-S board.
> +          break;
> +          }
> +        }
> +
> +        //
> +        // Upon wake, if BIOS saved pre-Sx Host Router state as active (system
> went to sleep with
> +        // attached devices), BIOS should:
> +        // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
> +        // 2. If procedure above returns true, BIOS should perform "wait for fast
> link bring-up" loop
> +        // 3. Continue regular wake flow.
> +        //
> +        //
> +        // Exectue Mail box command and perform "wait for fast link bring-up"
> loop
> +        //
> +        TbtSetSxMode(0xF0, 0, 0,
> PeiTbtConfig->DTbtCommonConfig.TbtBootOn);
> +      }
> +      //
> +      // Reset Sec/Sub buses to original value
> +      //
> +      PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc,
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET),
> OrgBusNumberConfiguration);
> +
> +  DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Return\n"));
> +  return Status;
> +}
> +
> +
> +/**
> +  Initialize Thunderbolt(TM)
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +EFI_STATUS
> +EFIAPI
> +TbtInit (
> +  VOID
> +  )
> +{
> +  EFI_STATUS            Status;
> +  PEI_TBT_POLICY             *PeiTbtConfig;
> +
> +  //
> +  // Get the TBT Policy
> +  //
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Exectue Mail box command "Boot On"
> +  //
> +  Status = DTbtBootOn (PeiTbtConfig);
> +  //
> +  // Exectue Mail box command "Usb On"
> +  //
> +  Status = DTbtUsbOn (PeiTbtConfig);
> +  //
> +  //During boot, reboot and wake  (bits [1:0]) of PCH PM_CFG register should
> be
> +  //set to 11b - 10 ms (default value is 0b - 10 us)
> +  //
> +  Status = DTbtSetTPch25Timing (PeiTbtConfig);
> +  //
> +  // Configure Tbt Force Power
> +  //
> +  Status = DTbtForcePower (PeiTbtConfig);
> +  //
> +  // VGA Enable and VGA 16-bit decode registers of Bridge control register of
> Root port where
> +  // Host router resides should be cleaned
> +  //
> +  Status = DTbtClearVgaRegisters (PeiTbtConfig);
> +  //
> +  // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went
> to sleep with
> +  // attached devices), BIOS should:
> +  // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
> +  // 2. If procedure above returns true, BIOS should perform "wait for fast link
> bring-up" loop
> +  // 3. Continue regular wake flow.
> +  //
> +  Status = DTbtSxExitFlow (PeiTbtConfig);
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspCpuPolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspCpuPolicyInitLib.c
> new file mode 100644
> index 0000000000..f38901f2ae
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspCpuPolicyInitLib.c
> @@ -0,0 +1,461 @@
> +/** @file
> +  Implementation of Fsp CPU Policy Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +
> +#include <Ppi/SiPolicy.h>
> +#include <Ppi/SecPlatformInformation2.h>
> +
> +#include <CpuAccess.h>
> +#include <Library/HobLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Library/PcdLib.h>
> +#include <FspEas.h>
> +
> +/**
> +  Performs FSP CPU PEI Policy initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspCpuPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  SI_PREMEM_POLICY_PPI            *SiPreMemPolicyPpi;
> +  CPU_OVERCLOCKING_PREMEM_CONFIG
> *CpuOverClockingPreMemConfig;
> +  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy Pre-Mem
> Start\n"));
> +
> +  //
> +  // Locate SiPreMemPolicyPpi
> +  //
> +  SiPreMemPolicyPpi = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPreMemPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPreMemPolicyPpi
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gCpuOverclockingPreMemConfigGuid, (VOID *)
> &CpuOverClockingPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  ///
> +  ///
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy Pre-Mem
> End\n"));
> +
> +  //
> +  // Overclocking PreMem policies
> +  //
> +  FspmUpd->FspmConfig.OcSupport               = (UINT8)
> CpuOverClockingPreMemConfig->OcSupport;
> +  FspmUpd->FspmConfig.OcLock                  = (UINT8)
> CpuOverClockingPreMemConfig->OcLock;
> +  FspmUpd->FspmConfig.CoreMaxOcRatio          = (UINT8)
> CpuOverClockingPreMemConfig->CoreMaxOcRatio;
> +  FspmUpd->FspmConfig.CoreVoltageMode         = (UINT8)
> CpuOverClockingPreMemConfig->CoreVoltageMode;
> +  FspmUpd->FspmConfig.CoreVoltageOverride     = (UINT16)
> CpuOverClockingPreMemConfig->CoreVoltageOverride;
> +  FspmUpd->FspmConfig.CoreVoltageAdaptive     = (UINT16)
> CpuOverClockingPreMemConfig->CoreVoltageAdaptive;
> +  FspmUpd->FspmConfig.CoreVoltageOffset       = (UINT16)
> CpuOverClockingPreMemConfig->CoreVoltageOffset;
> +  FspmUpd->FspmConfig.CorePllVoltageOffset    = (UINT8)
> CpuOverClockingPreMemConfig->CorePllVoltageOffset;
> +  FspmUpd->FspmConfig.RingMaxOcRatio          = (UINT8)
> CpuOverClockingPreMemConfig->RingMaxOcRatio;
> +  FspmUpd->FspmConfig.RingVoltageOverride     = (UINT16)
> CpuOverClockingPreMemConfig->RingVoltageOverride;
> +  FspmUpd->FspmConfig.RingVoltageAdaptive     = (UINT16)
> CpuOverClockingPreMemConfig->RingVoltageAdaptive;
> +  FspmUpd->FspmConfig.RingVoltageOffset       = (UINT16)
> CpuOverClockingPreMemConfig->RingVoltageOffset;
> +  FspmUpd->FspmConfig.RingPllVoltageOffset    = (UINT8)
> CpuOverClockingPreMemConfig->RingPllVoltageOffset;
> +  FspmUpd->FspmConfig.GtPllVoltageOffset      = (UINT8)
> CpuOverClockingPreMemConfig->GtPllVoltageOffset;
> +  FspmUpd->FspmConfig.RingPllVoltageOffset    = (UINT8)
> CpuOverClockingPreMemConfig->RingPllVoltageOffset;
> +  FspmUpd->FspmConfig.SaPllVoltageOffset      = (UINT8)
> CpuOverClockingPreMemConfig->SaPllVoltageOffset;
> +  FspmUpd->FspmConfig.McPllVoltageOffset      = (UINT8)
> CpuOverClockingPreMemConfig->McPllVoltageOffset;
> +  FspmUpd->FspmConfig.RingDownBin             = (UINT8)
> CpuOverClockingPreMemConfig->RingDownBin;
> +  FspmUpd->FspmConfig.RingVoltageMode         = (UINT8)
> CpuOverClockingPreMemConfig->RingVoltageMode;
> +  FspmUpd->FspmConfig.Avx2RatioOffset         = (UINT8)
> CpuOverClockingPreMemConfig->Avx2RatioOffset;
> +  FspmUpd->FspmConfig.Avx3RatioOffset         = (UINT8)
> CpuOverClockingPreMemConfig->Avx3RatioOffset;
> +  FspmUpd->FspmConfig.BclkAdaptiveVoltage     = (UINT8)
> CpuOverClockingPreMemConfig->BclkAdaptiveVoltage;
> +  FspmUpd->FspmConfig.TjMaxOffset             = (UINT8)
> CpuOverClockingPreMemConfig->TjMaxOffset;
> +  FspmUpd->FspmConfig.TvbRatioClipping        = (UINT8)
> CpuOverClockingPreMemConfig->TvbRatioClipping;
> +  FspmUpd->FspmConfig.TvbVoltageOptimization  = (UINT8)
> CpuOverClockingPreMemConfig->TvbVoltageOptimization;
> +
> +  //
> +  //  Cpu Config Lib policies
> +  //
> +  FspmUpd->FspmConfig.HyperThreading            = (UINT8)
> CpuConfigLibPreMemConfig->HyperThreading;
> +  FspmUpd->FspmConfig.BootFrequency             = (UINT8)
> CpuConfigLibPreMemConfig->BootFrequency;
> +  FspmUpd->FspmConfig.ActiveCoreCount           = (UINT8)
> CpuConfigLibPreMemConfig->ActiveCoreCount;
> +  FspmUpd->FspmConfig.JtagC10PowerGateDisable   = (UINT8)
> CpuConfigLibPreMemConfig->JtagC10PowerGateDisable;
> +  FspmUpd->FspmConfig.FClkFrequency             = (UINT8)
> CpuConfigLibPreMemConfig->FClkFrequency;
> +  FspmUpd->FspmConfig.BistOnReset               = (UINT8)
> CpuConfigLibPreMemConfig->BistOnReset;
> +  FspmUpd->FspmConfig.VmxEnable                 = (UINT8)
> CpuConfigLibPreMemConfig->VmxEnable;
> +  FspmUpd->FspmConfig.CpuRatio                  = (UINT8)
> CpuConfigLibPreMemConfig->CpuRatio;
> +  FspmUpd->FspmConfig.PeciSxReset               = (UINT8)
> CpuConfigLibPreMemConfig->PeciSxReset;
> +  FspmUpd->FspmConfig.PeciC10Reset              = (UINT8)
> CpuConfigLibPreMemConfig->PeciC10Reset;
> +  FspmUpd->FspmConfig.SkipMpInit                = (UINT8)
> CpuConfigLibPreMemConfig->SkipMpInit;
> +  FspmUpd->FspmConfig.DpSscMarginEnable         = (UINT8)
> CpuConfigLibPreMemConfig->DpSscMarginEnable;
> +
> +  //
> +  // DisableMtrrProgram <1> Disable Mtrrs program. <0> Program Mtrrs in FSP
> +  //
> +  FspmUpd->FspmConfig.DisableMtrrProgram        = (UINT8) 0;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + This routine is used to get Sec Platform Information Record2 Pointer.
> +
> + @param[in] PeiServices    Pointer to the PEI services table
> +
> + @retval GetSecPlatformInformation2 - The pointer of Sec Platform
> Information Record2 Pointer.
> + **/
> +
> +EFI_SEC_PLATFORM_INFORMATION_RECORD2 *
> GetSecPlatformInformation2(
> +  IN EFI_PEI_SERVICES **PeiServices
> +  )
> +{
> +  EFI_SEC_PLATFORM_INFORMATION2_PPI    *SecPlatformInformation2Ppi;
> +  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2 =
> NULL;
> +  UINT64                               InformationSize;
> +  EFI_STATUS Status;
> +
> +  //
> +  // Get BIST information from Sec Platform Information2 Ppi firstly
> +  //
> +  Status = PeiServicesLocatePpi (
> +             &gEfiSecPlatformInformation2PpiGuid,   // GUID
> +             0,                                     // Instance
> +             NULL,                                  // EFI_PEI_PPI_DESCRIPTOR
> +             (VOID ** ) &SecPlatformInformation2Ppi // PPI
> +             );
> +
> +  DEBUG((DEBUG_INFO, "LocatePpi SecPlatformInformationPpi2 Status -
> %x\n", Status));
> +  if (EFI_ERROR(Status)) {
> +    return NULL;
> +  }
> +
> +  InformationSize = 0;
> +
> +  Status = SecPlatformInformation2Ppi->PlatformInformation2 (
> +                                         (CONST EFI_PEI_SERVICES  **) PeiServices,
> +                                         &InformationSize,
> +                                         SecPlatformInformation2
> +                                         );
> +
> +  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
> +  if (Status != EFI_BUFFER_TOO_SMALL) {
> +    return NULL;
> +  }
> +
> +  SecPlatformInformation2 = AllocatePool((UINTN)InformationSize);
> +  ASSERT (SecPlatformInformation2 != NULL);
> +  if (SecPlatformInformation2 == NULL) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Retrieve BIST data from SecPlatform2
> +  //
> +  Status = SecPlatformInformation2Ppi->PlatformInformation2 (
> +                                         PeiServices,
> +                                         &InformationSize,
> +                                         SecPlatformInformation2
> +                                         );
> +  DEBUG((DEBUG_INFO,
> "SecPlatformInformation2Ppi->PlatformInformation2 Status - %x\n", Status));
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return NULL;
> +  }
> +
> +  return SecPlatformInformation2;
> +}
> +
> +/**
> + This routine is used to get Sec Platform Information Record Pointer.
> +
> + @param[in] PeiServices    Pointer to the PEI services table
> +
> + @retval GetSecPlatformInformation2 - The pointer of Sec Platform
> Information Record Pointer.
> + **/
> +EFI_SEC_PLATFORM_INFORMATION_RECORD2 *
> GetSecPlatformInformationInfoInFormat2(
> +  IN EFI_PEI_SERVICES **PeiServices
> +  )
> +{
> +  EFI_SEC_PLATFORM_INFORMATION_PPI     *SecPlatformInformationPpi;
> +  EFI_SEC_PLATFORM_INFORMATION_RECORD  *SecPlatformInformation =
> NULL;
> +  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
> +  UINT64                               InformationSize;
> +  EFI_STATUS                           Status;
> +
> +  //
> +  // Get BIST information from Sec Platform Information
> +  //
> +  Status = PeiServicesLocatePpi (
> +             &gEfiSecPlatformInformationPpiGuid,    // GUID
> +             0,                                     // Instance
> +             NULL,                                  // EFI_PEI_PPI_DESCRIPTOR
> +             (VOID ** ) &SecPlatformInformationPpi  // PPI
> +             );
> +
> +  DEBUG((DEBUG_INFO, "LocatePpi SecPlatformInformationPpi Status -
> %x\n", Status));
> +  if (EFI_ERROR(Status)) {
> +    return NULL;
> +  }
> +
> +  InformationSize = 0;
> +  Status = SecPlatformInformationPpi->PlatformInformation (
> +                                        (CONST EFI_PEI_SERVICES  **) PeiServices,
> +                                        &InformationSize,
> +                                        SecPlatformInformation
> +                                        );
> +
> +  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
> +  if (Status != EFI_BUFFER_TOO_SMALL) {
> +    return NULL;
> +  }
> +
> +  SecPlatformInformation = AllocatePool((UINTN)InformationSize);
> +  ASSERT (SecPlatformInformation != NULL);
> +  if (SecPlatformInformation == NULL) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Retrieve BIST data from SecPlatform
> +  //
> +  Status = SecPlatformInformationPpi->PlatformInformation (
> +                                        PeiServices,
> +                                        &InformationSize,
> +                                        SecPlatformInformation
> +                                        );
> +  DEBUG((DEBUG_INFO, "FSP
> SecPlatformInformation2Ppi->PlatformInformation Status - %x\n", Status));
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return NULL;
> +  }
> +
> +  SecPlatformInformation2 = AllocatePool(sizeof
> (EFI_SEC_PLATFORM_INFORMATION_RECORD2));
> +  ASSERT (SecPlatformInformation2 != NULL);
> +  if (SecPlatformInformation2 == NULL) {
> +    return NULL;
> +  }
> +
> +  SecPlatformInformation2->NumberOfCpus = 1;
> +  SecPlatformInformation2->CpuInstance[0].CpuLocation = 0;
> +
> SecPlatformInformation2->CpuInstance[0].InfoRecord.x64HealthFlags.Uint32
> = SecPlatformInformation->x64HealthFlags.Uint32;
> +
> +  FreePool(SecPlatformInformation);
> +
> +  return SecPlatformInformation2;
> +}
> +
> +
> +/**
> + Performs FSP CPU PEI Policy post memory initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspCpuPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  EFI_STATUS                           Status;
> +  SI_POLICY_PPI                        *SiPolicyPpi;
> +  CPU_CONFIG                           *CpuConfig;
> +  CPU_POWER_MGMT_BASIC_CONFIG          *CpuPowerMgmtBasicConfig;
> +  CPU_POWER_MGMT_CUSTOM_CONFIG
> *CpuPowerMgmtCustomConfig;
> +  CPU_TEST_CONFIG                      *CpuTestConfig;
> +  CPU_POWER_MGMT_TEST_CONFIG           *CpuPowerMgmtTestConfig;
> +  UINTN                                Index;
> +  EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
> +  EFI_PEI_SERVICES                     **PeiServices;
> +
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SiCpuPolicy\n"));
> +  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
> +  //
> +  // Locate gSiPolicyPpiGuid
> +  //
> +  SiPolicyPpi = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPolicyPpi
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *)
> &CpuConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtCustomConfigGuid, (VOID *)
> &CpuPowerMgmtCustomConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID
> *) &CpuTestConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  ///
> +  ///Production RC Policies
> +  ///
> +
> +  FspsUpd->FspsConfig.AesEnable                 = (UINT8)
> CpuConfig->AesEnable;
> +  FspsUpd->FspsConfig.DebugInterfaceEnable      = (UINT8)
> CpuConfig->DebugInterfaceEnable;
> +
> +  FspsUpd->FspsConfig.TurboMode                 = (UINT8)
> CpuPowerMgmtBasicConfig->TurboMode;
> +
> +  ///
> +  /// Test RC Policies
> +  ///
> +  FspsUpd->FspsTestConfig.MlcStreamerPrefetcher      = (UINT8)
> CpuTestConfig->MlcStreamerPrefetcher;
> +  FspsUpd->FspsTestConfig.MlcSpatialPrefetcher       = (UINT8)
> CpuTestConfig->MlcSpatialPrefetcher;
> +  FspsUpd->FspsTestConfig.MonitorMwaitEnable         = (UINT8)
> CpuTestConfig->MonitorMwaitEnable;
> +  FspsUpd->FspsTestConfig.DebugInterfaceLockEnable   = (UINT8)
> CpuTestConfig->DebugInterfaceLockEnable;
> +  FspsUpd->FspsTestConfig.ApIdleManner               = PcdGet8
> (PcdCpuApLoopMode);
> +  FspsUpd->FspsTestConfig.ProcessorTraceOutputScheme = (UINT8)
> CpuTestConfig->ProcessorTraceOutputScheme;
> +  FspsUpd->FspsTestConfig.ProcessorTraceEnable       = (UINT8)
> CpuTestConfig->ProcessorTraceEnable;
> +  FspsUpd->FspsTestConfig.ProcessorTraceMemBase      =
> CpuTestConfig->ProcessorTraceMemBase;
> +  FspsUpd->FspsTestConfig.ProcessorTraceMemLength    = (UINT32)
> CpuTestConfig->ProcessorTraceMemLength;
> +  FspsUpd->FspsTestConfig.VoltageOptimization        = (UINT8)
> CpuTestConfig->VoltageOptimization;
> +  FspsUpd->FspsTestConfig.ThreeStrikeCounterDisable  = (UINT8)
> CpuTestConfig->ThreeStrikeCounterDisable;
> +  FspsUpd->FspsTestConfig.MachineCheckEnable         = (UINT8)
> CpuTestConfig->MachineCheckEnable;
> +  FspsUpd->FspsTestConfig.CpuWakeUpTimer             = (UINT8)
> CpuTestConfig->CpuWakeUpTimer;
> +
> +  FspsUpd->FspsTestConfig.OneCoreRatioLimit          = (UINT8)
> CpuPowerMgmtBasicConfig->OneCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.TwoCoreRatioLimit          = (UINT8)
> CpuPowerMgmtBasicConfig->TwoCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.ThreeCoreRatioLimit        = (UINT8)
> CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.FourCoreRatioLimit         = (UINT8)
> CpuPowerMgmtBasicConfig->FourCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.FiveCoreRatioLimit         = (UINT8)
> CpuPowerMgmtBasicConfig->FiveCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.SixCoreRatioLimit          = (UINT8)
> CpuPowerMgmtBasicConfig->SixCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.SevenCoreRatioLimit        = (UINT8)
> CpuPowerMgmtBasicConfig->SevenCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.EightCoreRatioLimit        = (UINT8)
> CpuPowerMgmtBasicConfig->EightCoreRatioLimit;
> +  FspsUpd->FspsTestConfig.Hwp                        = (UINT8)
> CpuPowerMgmtBasicConfig->Hwp;
> +  FspsUpd->FspsTestConfig.HdcControl                 = (UINT8)
> CpuPowerMgmtBasicConfig->HdcControl;
> +  FspsUpd->FspsTestConfig.PowerLimit1Time            = (UINT8)
> CpuPowerMgmtBasicConfig->PowerLimit1Time;
> +  FspsUpd->FspsTestConfig.PowerLimit2                = (UINT8)
> CpuPowerMgmtBasicConfig->PowerLimit2;
> +  FspsUpd->FspsTestConfig.TurboPowerLimitLock        = (UINT8)
> CpuPowerMgmtBasicConfig->TurboPowerLimitLock;
> +  FspsUpd->FspsTestConfig.PowerLimit3Time            = (UINT8)
> CpuPowerMgmtBasicConfig->PowerLimit3Time;
> +  FspsUpd->FspsTestConfig.PowerLimit3DutyCycle       = (UINT8)
> CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle;
> +  FspsUpd->FspsTestConfig.PowerLimit3Lock            = (UINT8)
> CpuPowerMgmtBasicConfig->PowerLimit3Lock;
> +  FspsUpd->FspsTestConfig.PowerLimit4Lock            = (UINT8)
> CpuPowerMgmtBasicConfig->PowerLimit4Lock;
> +  FspsUpd->FspsTestConfig.TccActivationOffset        = (UINT8)
> CpuPowerMgmtBasicConfig->TccActivationOffset;
> +  FspsUpd->FspsTestConfig.TccOffsetClamp             = (UINT8)
> CpuPowerMgmtBasicConfig->TccOffsetClamp;
> +  FspsUpd->FspsTestConfig.TccOffsetLock              = (UINT8)
> CpuPowerMgmtBasicConfig->TccOffsetLock;
> +  FspsUpd->FspsTestConfig.PowerLimit1                = (UINT32)
> (CpuPowerMgmtBasicConfig->PowerLimit1 * 125);
> +  FspsUpd->FspsTestConfig.PowerLimit2Power           = (UINT32)
> (CpuPowerMgmtBasicConfig->PowerLimit2Power * 125);
> +  FspsUpd->FspsTestConfig.PowerLimit3                = (UINT32)
> (CpuPowerMgmtBasicConfig->PowerLimit3 * 125);
> +  FspsUpd->FspsTestConfig.PowerLimit4                = (UINT32)
> (CpuPowerMgmtBasicConfig->PowerLimit4 * 125);
> +  FspsUpd->FspsTestConfig.TccOffsetTimeWindowForRatl = (UINT32)
> CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl;
> +  FspsUpd->FspsTestConfig.HwpInterruptControl        = (UINT8)
> CpuPowerMgmtBasicConfig->HwpInterruptControl;
> +  FspsUpd->FspsTestConfig.EnableItbm                 = (UINT8)
> CpuPowerMgmtBasicConfig->EnableItbm;
> +  FspsUpd->FspsTestConfig.EnableItbmDriver           = (UINT8)
> CpuPowerMgmtBasicConfig->EnableItbmDriver;
> +  FspsUpd->FspsTestConfig.MinRingRatioLimit          = (UINT8)
> CpuPowerMgmtBasicConfig->MinRingRatioLimit;
> +  FspsUpd->FspsTestConfig.MaxRingRatioLimit          = (UINT8)
> CpuPowerMgmtBasicConfig->MaxRingRatioLimit;
> +  FspsUpd->FspsTestConfig.NumberOfEntries             = (UINT8)
> CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries;
> +  FspsUpd->FspsTestConfig.Custom1PowerLimit1Time      = (UINT8)
> CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLimi
> t1Time;
> +  FspsUpd->FspsTestConfig.Custom2PowerLimit1Time      = (UINT8)
> CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLimi
> t1Time;
> +  FspsUpd->FspsTestConfig.Custom3PowerLimit1Time      = (UINT8)
> CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLimi
> t1Time;
> +  FspsUpd->FspsTestConfig.Custom1TurboActivationRatio = (UINT8)
> CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomTurboActiv
> ationRatio;
> +  FspsUpd->FspsTestConfig.Custom2TurboActivationRatio = (UINT8)
> CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomTurboActiv
> ationRatio;
> +  FspsUpd->FspsTestConfig.Custom3TurboActivationRatio = (UINT8)
> CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomTurboActiv
> ationRatio;
> +  FspsUpd->FspsTestConfig.ConfigTdpLock               = (UINT8)
> CpuPowerMgmtCustomConfig->ConfigTdpLock;
> +  FspsUpd->FspsTestConfig.ConfigTdpBios               = (UINT8)
> CpuPowerMgmtCustomConfig->ConfigTdpBios;
> +  FspsUpd->FspsTestConfig.MaxRatio                    = (UINT8)
> CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio;
> +  for (Index = 0; Index <
> CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries;
> Index++) {
> +    FspsUpd->FspsTestConfig.StateRatio[Index]         = (UINT8)
> CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index];
> +  }
> +  for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
> +    FspsUpd->FspsTestConfig.StateRatioMax16[Index]    = (UINT8)
> CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index];
> +  }
> +  FspsUpd->FspsTestConfig.Custom1PowerLimit1          = (UINT32)
> (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLim
> it1 * 125);
> +  FspsUpd->FspsTestConfig.Custom1PowerLimit2          = (UINT32)
> (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[0].CustomPowerLim
> it2 * 125);
> +  FspsUpd->FspsTestConfig.Custom2PowerLimit1          = (UINT32)
> (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLim
> it1 * 125);
> +  FspsUpd->FspsTestConfig.Custom2PowerLimit2          = (UINT32)
> (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[1].CustomPowerLim
> it2 * 125);
> +  FspsUpd->FspsTestConfig.Custom3PowerLimit1          = (UINT32)
> (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLim
> it1 * 125);
> +  FspsUpd->FspsTestConfig.Custom3PowerLimit2          = (UINT32)
> (CpuPowerMgmtCustomConfig->CustomConfigTdpTable[2].CustomPowerLim
> it2 * 125);
> +
> +  FspsUpd->FspsTestConfig.Eist                          = (UINT8)
> CpuPowerMgmtTestConfig->Eist;
> +  FspsUpd->FspsTestConfig.EnergyEfficientPState         = (UINT8)
> CpuPowerMgmtTestConfig->EnergyEfficientPState;
> +  FspsUpd->FspsTestConfig.EnergyEfficientTurbo          = (UINT8)
> CpuPowerMgmtTestConfig->EnergyEfficientTurbo;
> +  FspsUpd->FspsTestConfig.TStates                       = (UINT8)
> CpuPowerMgmtTestConfig->TStates;
> +  FspsUpd->FspsTestConfig.BiProcHot                     = (UINT8)
> CpuPowerMgmtTestConfig->BiProcHot;
> +  FspsUpd->FspsTestConfig.DisableProcHotOut             = (UINT8)
> CpuPowerMgmtTestConfig->DisableProcHotOut;
> +  FspsUpd->FspsTestConfig.ProcHotResponse               = (UINT8)
> CpuPowerMgmtTestConfig->ProcHotResponse;
> +  FspsUpd->FspsTestConfig.DisableVrThermalAlert         = (UINT8)
> CpuPowerMgmtTestConfig->DisableVrThermalAlert;
> +  FspsUpd->FspsTestConfig.AutoThermalReporting          = (UINT8)
> CpuPowerMgmtTestConfig->AutoThermalReporting;
> +  FspsUpd->FspsTestConfig.ThermalMonitor                = (UINT8)
> CpuPowerMgmtTestConfig->ThermalMonitor;
> +  FspsUpd->FspsTestConfig.Cx                            = (UINT8)
> CpuPowerMgmtTestConfig->Cx;
> +  FspsUpd->FspsTestConfig.PmgCstCfgCtrlLock             = (UINT8)
> CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock;
> +  FspsUpd->FspsTestConfig.C1e                           = (UINT8)
> CpuPowerMgmtTestConfig->C1e;
> +  FspsUpd->FspsTestConfig.C1StateAutoDemotion           = (UINT8)
> CpuPowerMgmtTestConfig->C1AutoDemotion;
> +  FspsUpd->FspsTestConfig.C1StateUnDemotion             = (UINT8)
> CpuPowerMgmtTestConfig->C1UnDemotion;
> +  FspsUpd->FspsTestConfig.C3StateAutoDemotion           = (UINT8)
> CpuPowerMgmtTestConfig->C3AutoDemotion;
> +  FspsUpd->FspsTestConfig.C3StateUnDemotion             = (UINT8)
> CpuPowerMgmtTestConfig->C3UnDemotion;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl0TimeUnit = (UINT8)
> CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl0Irtl     = (UINT16)
> CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl;
> +  FspsUpd->FspsTestConfig.PkgCStateDemotion             = (UINT8)
> CpuPowerMgmtTestConfig->PkgCStateDemotion;
> +  FspsUpd->FspsTestConfig.PkgCStateUnDemotion           = (UINT8)
> CpuPowerMgmtTestConfig->PkgCStateUnDemotion;
> +  FspsUpd->FspsTestConfig.CStatePreWake                 = (UINT8)
> CpuPowerMgmtTestConfig->CStatePreWake;
> +  FspsUpd->FspsTestConfig.TimedMwait                    = (UINT8)
> CpuPowerMgmtTestConfig->TimedMwait;
> +  FspsUpd->FspsTestConfig.CstCfgCtrIoMwaitRedirection   = (UINT8)
> CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection;
> +  FspsUpd->FspsTestConfig.PkgCStateLimit                = (UINT8)
> CpuPowerMgmtTestConfig->PkgCStateLimit;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl1TimeUnit = (UINT8)
> CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl2TimeUnit = (UINT8)
> CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl3TimeUnit = (UINT8)
> CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl4TimeUnit = (UINT8)
> CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl5TimeUnit = (UINT8)
> CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit;
> +  FspsUpd->FspsTestConfig.PpmIrmSetting                 = (UINT8)
> CpuPowerMgmtTestConfig->PpmIrmSetting;
> +  FspsUpd->FspsTestConfig.ProcHotLock                   = (UINT8)
> CpuPowerMgmtTestConfig->ProcHotLock;
> +  FspsUpd->FspsTestConfig.RaceToHalt                    = (UINT8)
> CpuPowerMgmtTestConfig->RaceToHalt;
> +  FspsUpd->FspsTestConfig.ConfigTdpLevel                = (UINT8)
> CpuPowerMgmtTestConfig->ConfigTdpLevel;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl1Irtl     = (UINT16)
> CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl2Irtl     = (UINT16)
> CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl3Irtl     = (UINT16)
> CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl4Irtl     = (UINT16)
> CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl;
> +  FspsUpd->FspsTestConfig.CstateLatencyControl5Irtl     = (UINT16)
> CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl;
> +
> +  //
> +  // Get BIST information from Sec Platform Information
> +  //
> +  SecPlatformInformation2 = GetSecPlatformInformation2 (PeiServices);
> +  if (SecPlatformInformation2 == NULL) {
> +    SecPlatformInformation2 = GetSecPlatformInformationInfoInFormat2
> (PeiServices);
> +  }
> +
> +  ASSERT (SecPlatformInformation2 != NULL);
> +
> +  if (SecPlatformInformation2 != NULL) {
> +    FspsUpd->FspsConfig.CpuBistData = (UINT32)SecPlatformInformation2;
> +    DEBUG((DEBUG_INFO, "SecPlatformInformation NumberOfCpus - %x\n",
> SecPlatformInformation2->NumberOfCpus));
> +    DEBUG ((DEBUG_INFO, "SecPlatformInformation BIST - %x\n",
> SecPlatformInformation2->CpuInstance[0].InfoRecord.x64HealthFlags.Uint32
> ));
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspMePolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspMePolicyInitLib.c
> new file mode 100644
> index 0000000000..97d9842aff
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspMePolicyInitLib.c
> @@ -0,0 +1,121 @@
> +/** @file
> +  Implementation of Fsp Me Policy Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +#include <ConfigBlock/MePeiConfig.h>
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Performs FSP ME PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMePolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                Status;
> +  SI_PREMEM_POLICY_PPI      *SiPreMemPolicy;
> +  ME_PEI_PREMEM_CONFIG      *MePeiPreMemConfig;
> +
> +  DEBUG ((DEBUG_INFO, "PeiFspMePolicyInitPreMem\n"));
> +
> +  //
> +  // Locate gSiPreMemPolicyPpi
> +  //
> +  SiPreMemPolicy = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPreMemPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPreMemPolicy
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  FspmUpd->FspmConfig.HeciTimeouts                      = (UINT8)
> MePeiPreMemConfig->HeciTimeouts;
> +  //
> +  // Test policies
> +  //
> +  FspmUpd->FspmTestConfig.DidInitStat                   = (UINT8)
> MePeiPreMemConfig->DidInitStat;
> +  FspmUpd->FspmTestConfig.DisableCpuReplacedPolling     = (UINT8)
> MePeiPreMemConfig->DisableCpuReplacedPolling;
> +  FspmUpd->FspmTestConfig.SendDidMsg                    = (UINT8)
> MePeiPreMemConfig->SendDidMsg;
> +  FspmUpd->FspmTestConfig.DisableHeciRetry              = (UINT8)
> MePeiPreMemConfig->DisableHeciRetry;
> +  FspmUpd->FspmTestConfig.DisableMessageCheck           = (UINT8)
> MePeiPreMemConfig->DisableMessageCheck;
> +  FspmUpd->FspmTestConfig.SkipMbpHob                    = (UINT8)
> MePeiPreMemConfig->SkipMbpHob;
> +
> +  FspmUpd->FspmTestConfig.HeciCommunication2            = (UINT8)
> MePeiPreMemConfig->HeciCommunication2;
> +  FspmUpd->FspmTestConfig.KtDeviceEnable                = (UINT8)
> MePeiPreMemConfig->KtDeviceEnable;
> +
> +  FspmUpd->FspmConfig.Heci1BarAddress                   =
> MePeiPreMemConfig->Heci1BarAddress;
> +  FspmUpd->FspmConfig.Heci2BarAddress                   =
> MePeiPreMemConfig->Heci2BarAddress;
> +  FspmUpd->FspmConfig.Heci3BarAddress                   =
> MePeiPreMemConfig->Heci3BarAddress;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Performs FSP ME PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMePolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  EFI_STATUS                Status;
> +  SI_POLICY_PPI             *SiPolicyPpi;
> +  ME_PEI_CONFIG             *MePeiConfig;
> +
> +  DEBUG ((DEBUG_INFO, "PeiFspMePolicyInit \n"));
> +  //
> +  // Locate gSiPolicyPpiGuid
> +  //
> +  SiPolicyPpi = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPolicyPpi
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *)
> &MePeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  FspsUpd->FspsConfig.Heci3Enabled                  = (UINT8)
> MePeiConfig->Heci3Enabled;
> +  FspsUpd->FspsConfig.MeUnconfigOnRtcClear          = (UINT8)
> MePeiConfig->MeUnconfigOnRtcClear;
> +
> +  //
> +  // Test policies
> +  //
> +  FspsUpd->FspsTestConfig.MctpBroadcastCycle        = (UINT8)
> MePeiConfig->MctpBroadcastCycle;
> +  FspsUpd->FspsTestConfig.EndOfPostMessage          = (UINT8)
> MePeiConfig->EndOfPostMessage;
> +  FspsUpd->FspsTestConfig.DisableD0I3SettingForHeci = (UINT8)
> MePeiConfig->DisableD0I3SettingForHeci;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspMiscUpdInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspMiscUpdInitLib.c
> new file mode 100644
> index 0000000000..9545e3df0b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspMiscUpdInitLib.c
> @@ -0,0 +1,77 @@
> +/** @file
> +  Implementation of Fsp Misc UPD Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/HobLib.h>
> +
> +#define STATUS_CODE_USE_RAM        BIT0
> +#define STATUS_CODE_USE_ISA_SERIAL BIT1
> +#define STATUS_CODE_USE_USB        BIT2
> +#define STATUS_CODE_USE_USB3       BIT3
> +#define STATUS_CODE_USE_SERIALIO   BIT4
> +#define STATUS_CODE_USE_TRACEHUB   BIT5
> +#define STATUS_CODE_CMOS_INVALID   BIT6
> +#define STATUS_CODE_CMOS_VALID     BIT7
> +/**
> +  Performs FSP Misc UPD initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSPM_UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMiscUpdInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_PEI_HOB_POINTERS              Hob;
> +  DEBUG_CONFIG_DATA_HOB             *DebugConfigData;
> +  UINT8                             DebugInterfaces;
> +
> +  FspmUpd->FspmArchUpd.StackBase = (VOID
> *)(UINTN)(PcdGet32(PcdTemporaryRamBase) +
> PcdGet32(PcdTemporaryRamSize) - (PcdGet32(PcdFspTemporaryRamSize) +
> PcdGet32(PcdFspReservedBufferSize)));
> +  FspmUpd->FspmArchUpd.StackSize = PcdGet32(PcdFspTemporaryRamSize);
> +
> +  Status = PeiServicesGetBootMode
> (&(FspmUpd->FspmArchUpd.BootMode));
> +  if (EFI_ERROR (Status)) {
> +    FspmUpd->FspmArchUpd.BootMode =
> BOOT_WITH_FULL_CONFIGURATION;
> +  }
> +
> +  FspmUpd->FspmArchUpd.BootLoaderTolumSize = 0x0;
> +
> +  //
> +  // Initialize DebugConfigData
> +  //
> +  DebugInterfaces = 0x00;
> +  Hob.Guid = GetFirstGuidHob (&gDebugConfigHobGuid);
> +  if (Hob.Guid != NULL) {
> +    DebugConfigData = (DEBUG_CONFIG_DATA_HOB *) GET_GUID_HOB_DATA
> (Hob.Guid);
> +    if (DebugConfigData != NULL) {
> +      // Debug Interfaces
> +      if (DebugConfigData->RamDebugInterface)      { DebugInterfaces |=
> STATUS_CODE_USE_RAM; }
> +      if (DebugConfigData->UartDebugInterface)     { DebugInterfaces |=
> STATUS_CODE_USE_ISA_SERIAL; }
> +      if (DebugConfigData->Usb3DebugInterface)     { DebugInterfaces |=
> STATUS_CODE_USE_USB3; }
> +      if (DebugConfigData->SerialIoDebugInterface) { DebugInterfaces |=
> STATUS_CODE_USE_SERIALIO; }
> +      if (DebugConfigData->TraceHubDebugInterface) { DebugInterfaces |=
> STATUS_CODE_USE_TRACEHUB; }
> +      FspmUpd->FspmConfig.PcdDebugInterfaceFlags  = DebugInterfaces;
> +      // Serial debug message baud rate
> +      FspmUpd->FspmConfig.PcdSerialDebugBaudRate  =
> DebugConfigData->SerialDebugBaudRate;
> +      //Serial debug message level
> +      FspmUpd->FspmConfig.PcdSerialDebugLevel     =
> DebugConfigData->SerialDebug;
> +    }
> +  }
> +  DEBUG ((DEBUG_INFO, "FspmConfig.PcdDebugInterfaceFlags is 0x%X\n",
> FspmUpd->FspmConfig.PcdDebugInterfaceFlags));
> +  DEBUG ((DEBUG_INFO, "FspmUpd->FspmConfig.PcdSerialDebugBaudRate
> is 0x%X\n", FspmUpd->FspmConfig.PcdSerialDebugBaudRate));
> +  DEBUG ((DEBUG_INFO, "FspmUpd->FspmConfig.PcdSerialDebugLevel is
> 0x%X\n", FspmUpd->FspmConfig.PcdSerialDebugLevel));
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPchPolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPchPolicyInitLib.c
> new file mode 100644
> index 0000000000..e2022929cd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPchPolicyInitLib.c
> @@ -0,0 +1,736 @@
> +/** @file
> +  Implementation of Fsp PCH Policy Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +
> +#include <Ppi/SiPolicy.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PchInfoLib.h>
> +
> +/**
> +  Performs FSP PCH PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  UINTN                            Index;
> +  UINTN                            MaxPcieRootPorts;
> +  SI_PREMEM_POLICY_PPI             *SiPreMemPolicy;
> +  PCH_TRACE_HUB_PREMEM_CONFIG      *PchTraceHubPreMemConfig;
> +  PCH_SMBUS_PREMEM_CONFIG          *SmbusPreMemConfig;
> +  PCH_DCI_PREMEM_CONFIG            *DciPreMemConfig;
> +  PCH_HSIO_PCIE_PREMEM_CONFIG      *HsioPciePreMemConfig;
> +  PCH_HSIO_SATA_PREMEM_CONFIG      *HsioSataPreMemConfig;
> +  PCH_PCIE_RP_PREMEM_CONFIG        *PcieRpPreMemConfig;
> +  PCH_LPC_PREMEM_CONFIG            *LpcPreMemConfig;
> +  PCH_GENERAL_PREMEM_CONFIG        *PchGeneralPreMemConfig;
> +  PCH_WDT_PREMEM_CONFIG            *WdtPreMemConfig;
> +  PCH_HDAUDIO_PREMEM_CONFIG        *HdaPreMemConfig;
> +  PCH_ISH_PREMEM_CONFIG            *IshPreMemConfig;
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP
> UpdatePeiPchPolicyPreMem\n"));
> +  DEBUG((DEBUG_INFO | DEBUG_INIT, "FspmUpd = 0x%x\n", FspmUpd));
> +  //
> +  // Locate PchPreMemPolicyPpi
> +  //
> +  SiPreMemPolicy = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPreMemPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPreMemPolicy
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ
> UpdatePeiPchPolicyPreMem\n"));
> +  //
> +  // Update PCIE RP policies
> +  //
> +//  MaxPcieRootPorts = 16;
> +
> +  MaxPcieRootPorts = GetPchMaxPciePortNum ();
> +//  MaxPcieRootPorts = 16;
> +  FspmUpd->FspmConfig.PcieRpEnableMask =
> PcieRpPreMemConfig->RpEnabledMask & ((1 << MaxPcieRootPorts) - 1);
> +  FspmUpd->FspmConfig.PcieImrEnabled =
> PcieRpPreMemConfig->PcieImrEnabled;
> +  FspmUpd->FspmConfig.PcieImrSize = PcieRpPreMemConfig->PcieImrSize;
> +  FspmUpd->FspmConfig.ImrRpSelection =
> PcieRpPreMemConfig->ImrRpSelection;
> +  //
> +  // Update TraceHub policies
> +  //
> +  FspmUpd->FspmConfig.PchTraceHubMode = (UINT8)
> PchTraceHubPreMemConfig->EnableMode;
> +  FspmUpd->FspmConfig.PchTraceHubMemReg0Size = (UINT8)
> PchTraceHubPreMemConfig->MemReg0Size;
> +  FspmUpd->FspmConfig.PchTraceHubMemReg1Size = (UINT8)
> PchTraceHubPreMemConfig->MemReg1Size;
> +
> +  //
> +  // Update Smbus policies
> +  //
> +  FspmUpd->FspmConfig.SmbusEnable =
> (UINT8)SmbusPreMemConfig->Enable;
> +  FspmUpd->FspmConfig.SmbusArpEnable =
> (UINT8)SmbusPreMemConfig->ArpEnable;
> +  FspmUpd->FspmTestConfig.SmbusDynamicPowerGating =
> (UINT8)SmbusPreMemConfig->DynamicPowerGating;
> +  FspmUpd->FspmTestConfig.SmbusSpdWriteDisable =
> (UINT8)SmbusPreMemConfig->SpdWriteDisable;
> +  FspmUpd->FspmConfig.PchSmbAlertEnable =
> (UINT8)SmbusPreMemConfig->SmbAlertEnable;
> +  FspmUpd->FspmConfig.PchSmbusIoBase =
> (UINT16)SmbusPreMemConfig->SmbusIoBase;
> +  FspmUpd->FspmConfig.PchNumRsvdSmbusAddresses =
> (UINT8)SmbusPreMemConfig->NumRsvdSmbusAddresses;
> +  FspmUpd->FspmConfig.RsvdSmbusAddressTablePtr =
> (UINT32)SmbusPreMemConfig->RsvdSmbusAddressTable;
> +
> +  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ1
> UpdatePeiPchPolicyPreMem\n"));
> +  //
> +  // Update Dci policies
> +  //
> +  FspmUpd->FspmConfig.PlatformDebugConsent =
> (UINT8)DciPreMemConfig->PlatformDebugConsent;
> +  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ11
> UpdatePeiPchPolicyPreMem\n"));
> +  FspmUpd->FspmConfig.DciUsb3TypecUfpDbg =
> (UINT8)DciPreMemConfig->DciUsb3TypecUfpDbg;
> +  //
> +  // Update HSIO PCIE policies
> +  //
> +  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
> +    FspmUpd->FspmConfig.PchPcieHsioRxSetCtleEnable[Index]           =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable;
> +    FspmUpd->FspmConfig.PchPcieHsioRxSetCtle[Index]                 =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen1DownscaleAmpEnable[Index]
> =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEna
> ble;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen1DownscaleAmp[Index]        =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen2DownscaleAmpEnable[Index]
> =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEna
> ble;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen2DownscaleAmp[Index]        =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen3DownscaleAmpEnable[Index]
> =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEna
> ble;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen3DownscaleAmp[Index]        =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen1DeEmphEnable[Index]        =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen1DeEmph[Index]              =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph3p5Enable[Index]
> =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph3p5[Index]           =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph6p0Enable[Index]
> =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable;
> +    FspmUpd->FspmConfig.PchPcieHsioTxGen2DeEmph6p0[Index]           =
> (UINT8)HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0;
> +  }
> +
> +  //
> +  // Update HSIO SATA policies
> +  //
> +  for (Index = 0; Index < PCH_MAX_SATA_PORTS; Index ++) {
> +    FspmUpd->FspmConfig.PchSataHsioRxGen1EqBoostMagEnable[Index]
> =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEn
> able;
> +    FspmUpd->FspmConfig.PchSataHsioRxGen1EqBoostMag[Index]          =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag;
> +    FspmUpd->FspmConfig.PchSataHsioRxGen2EqBoostMagEnable[Index]
> =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEn
> able;
> +    FspmUpd->FspmConfig.PchSataHsioRxGen2EqBoostMag[Index]          =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag;
> +    FspmUpd->FspmConfig.PchSataHsioRxGen3EqBoostMagEnable[Index]
> =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEn
> able;
> +    FspmUpd->FspmConfig.PchSataHsioRxGen3EqBoostMag[Index]          =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen1DownscaleAmpEnable[Index]
> =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp
> Enable;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen1DownscaleAmp[Index]        =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp
> ;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen2DownscaleAmpEnable[Index]
> =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp
> Enable;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen2DownscaleAmp[Index]        =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp
> ;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen3DownscaleAmpEnable[Index]
> =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp
> Enable;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen3DownscaleAmp[Index]        =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp
> ;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen1DeEmphEnable[Index]        =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable
> ;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen1DeEmph[Index]              =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen2DeEmphEnable[Index]        =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable
> ;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen2DeEmph[Index]              =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen3DeEmphEnable[Index]        =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable
> ;
> +    FspmUpd->FspmConfig.PchSataHsioTxGen3DeEmph[Index]              =
> (UINT8)HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph;
> +  }
> +  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ2
> UpdatePeiPchPolicyPreMem\n"));
> +  // Update LPC policies
> +  //
> +  FspmUpd->FspmConfig.PchLpcEnhancePort8xhDecoding =
> (UINT8)LpcPreMemConfig->EnhancePort8xhDecoding;
> +
> +  //
> +  // Update Pch General Premem policies
> +  //
> +  FspmUpd->FspmConfig.PchPort80Route =
> (UINT8)PchGeneralPreMemConfig->Port80Route;
> +
> +  //
> +  // Update Wdt policies
> +  //
> +  FspmUpd->FspmTestConfig.WdtDisableAndLock =
> (UINT8)WdtPreMemConfig->DisableAndLock;
> +
> +  //
> +  // HdAudioConfig
> +  //
> +  FspmUpd->FspmConfig.PchHdaEnable =
> (UINT8)HdaPreMemConfig->Enable;
> +
> +  //
> +  // IshConfig
> +  //
> +  FspmUpd->FspmConfig.PchIshEnable = (UINT8)IshPreMemConfig->Enable;
> +
> +  DEBUG((DEBUG_INFO | DEBUG_INIT, "WYQ3
> UpdatePeiPchPolicyPreMem\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Performs FSP PCH PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  UINTN                        Index;
> +  UINTN                        MaxPcieRootPorts;
> +  UINT8                        Data8;
> +  SI_POLICY_PPI                *SiPolicy;
> +  PCH_LAN_CONFIG               *LanConfig;
> +  PCH_HDAUDIO_CONFIG           *HdAudioConfig;
> +  PCH_SCS_CONFIG               *ScsConfig;
> +  PCH_ISH_CONFIG               *IshConfig;
> +  PCH_SATA_CONFIG              *SataConfig;
> +  USB_CONFIG                   *UsbConfig;
> +  PCH_SERIAL_IO_CONFIG         *SerialIoConfig;
> +  PCH_INTERRUPT_CONFIG         *InterruptConfig;
> +  PCH_LOCK_DOWN_CONFIG         *LockDownConfig;
> +  PCH_CNVI_CONFIG              *CnviConfig;
> +  PCH_HSIO_CONFIG              *HsioConfig;
> +  PCH_ESPI_CONFIG              *EspiConfig;
> +  PCH_PCIE_CONFIG              *PcieRpConfig;
> +  PCH_DMI_CONFIG               *DmiConfig;
> +  PCH_FLASH_PROTECTION_CONFIG  *FlashProtectionConfig;
> +  PCH_IOAPIC_CONFIG            *IoApicConfig;
> +  PCH_P2SB_CONFIG              *P2sbConfig;
> +  PCH_GENERAL_CONFIG           *PchGeneralConfig;
> +  PCH_PM_CONFIG                *PmConfig;
> +  PCH_LPC_SIRQ_CONFIG          *PchSerialIrqConfig;
> +  PCH_THERMAL_CONFIG           *PchThermalConfig;
> +
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP UpdatePeiPchPolicy\n"));
> +  //
> +  // Locate SiPolicyPpi
> +  //
> +  SiPolicy = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPolicy
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gLanConfigGuid, (VOID *)
> &LanConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gHdAudioConfigGuid, (VOID *)
> &HdAudioConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gScsConfigGuid, (VOID *)
> &ScsConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gIshConfigGuid, (VOID *)
> &IshConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *)
> &SataConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gUsbConfigGuid, (VOID *)
> &UsbConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIoConfigGuid, (VOID *)
> &SerialIoConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gInterruptConfigGuid, (VOID *)
> &InterruptConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gLockDownConfigGuid, (VOID *)
> &LockDownConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPcieRpConfigGuid, (VOID *)
> &PcieRpConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gDmiConfigGuid, (VOID *)
> &DmiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gFlashProtectionConfigGuid,
> (VOID *) &FlashProtectionConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gIoApicConfigGuid, (VOID *)
> &IoApicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gP2sbConfigGuid, (VOID *)
> &P2sbConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPchGeneralConfigGuid, (VOID
> *) &PchGeneralConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *)
> &PmConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIrqConfigGuid, (VOID *)
> &PchSerialIrqConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gThermalConfigGuid, (VOID *)
> &PchThermalConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gCnviConfigGuid, (VOID *)
> &CnviConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gHsioConfigGuid, (VOID *)
> &HsioConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gEspiConfigGuid, (VOID *)
> &EspiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Update LAN policies
> +  //
> +  FspsUpd->FspsConfig.PchLanEnable          = (UINT8)LanConfig->Enable;
> +  FspsUpd->FspsConfig.PchLanLtrEnable       = (UINT8)LanConfig->LtrEnable;
> +
> +  //
> +  // Update HDA policies
> +  //
> +  FspsUpd->FspsConfig.PchHdaDspEnable             =
> (UINT8)HdAudioConfig->DspEnable;
> +  FspsUpd->FspsConfig.PchHdaPme                   =
> (UINT8)HdAudioConfig->Pme;
> +  FspsUpd->FspsConfig.PchHdaVcType                =
> (UINT8)HdAudioConfig->VcType;
> +  FspsUpd->FspsConfig.PchHdaLinkFrequency         =
> (UINT8)HdAudioConfig->HdAudioLinkFrequency;
> +  FspsUpd->FspsConfig.PchHdaIDispLinkFrequency    =
> (UINT8)HdAudioConfig->IDispLinkFrequency;
> +  FspsUpd->FspsConfig.PchHdaIDispLinkTmode        =
> (UINT8)HdAudioConfig->IDispLinkTmode;
> +  FspsUpd->FspsConfig.PchHdaDspUaaCompliance      =
> (UINT8)HdAudioConfig->DspUaaCompliance;
> +  FspsUpd->FspsConfig.PchHdaIDispCodecDisconnect  =
> (UINT8)HdAudioConfig->IDispCodecDisconnect;
> +  FspsUpd->FspsConfig.PchHdaCodecSxWakeCapability =
> (UINT8)HdAudioConfig->CodecSxWakeCapability;
> +  FspsUpd->FspsTestConfig.PchHdaResetWaitTimer    =
> (UINT16)HdAudioConfig->ResetWaitTimer;
> +  FspsUpd->FspsConfig.PchHdaVerbTableEntryNum     =
> HdAudioConfig->VerbTableEntryNum;
> +  FspsUpd->FspsConfig.PchHdaVerbTablePtr          =
> HdAudioConfig->VerbTablePtr;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkHda          =
> (UINT8)HdAudioConfig->AudioLinkHda;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkDmic0        =
> (UINT8)HdAudioConfig->AudioLinkDmic0;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkDmic1        =
> (UINT8)HdAudioConfig->AudioLinkDmic1;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSsp0         =
> (UINT8)HdAudioConfig->AudioLinkSsp0;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSsp1         =
> (UINT8)HdAudioConfig->AudioLinkSsp1;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSsp2         =
> (UINT8)HdAudioConfig->AudioLinkSsp2;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSndw1        =
> (UINT8)HdAudioConfig->AudioLinkSndw1;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSndw2        =
> (UINT8)HdAudioConfig->AudioLinkSndw2;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSndw3        =
> (UINT8)HdAudioConfig->AudioLinkSndw3;
> +  FspsUpd->FspsConfig.PchHdaAudioLinkSndw4        =
> (UINT8)HdAudioConfig->AudioLinkSndw4;
> +  FspsUpd->FspsConfig.PchHdaSndwBufferRcomp       =
> (UINT8)HdAudioConfig->SndwBufferRcomp;
> +
> +  //
> +  // Update SCS policies
> +  //
> +  FspsUpd->FspsConfig.ScsEmmcEnabled =
> (UINT8)ScsConfig->ScsEmmcEnabled;
> +  FspsUpd->FspsConfig.ScsEmmcHs400Enabled =
> (UINT8)ScsConfig->ScsEmmcHs400Enabled;
> +  FspsUpd->FspsConfig.ScsSdCardEnabled =
> (UINT8)ScsConfig->ScsSdcardEnabled;
> +  FspsUpd->FspsConfig.SdCardPowerEnableActiveHigh =
> (UINT8)ScsConfig->SdCardPowerEnableActiveHigh;
> +#ifdef CFL_SIMICS
> +  FspsUpd->FspsConfig.ScsUfsEnabled    = 0;
> +#else
> +  FspsUpd->FspsConfig.ScsUfsEnabled    =
> (UINT8)ScsConfig->ScsUfsEnabled;
> +#endif
> +  FspsUpd->FspsConfig.PchScsEmmcHs400TuningRequired =
> (UINT8)ScsConfig->ScsEmmcHs400TuningRequired;
> +  FspsUpd->FspsConfig.PchScsEmmcHs400DllDataValid   =
> (UINT8)ScsConfig->ScsEmmcHs400DllDataValid;
> +  FspsUpd->FspsConfig.PchScsEmmcHs400RxStrobeDll1   =
> (UINT8)ScsConfig->ScsEmmcHs400RxStrobeDll1;
> +  FspsUpd->FspsConfig.PchScsEmmcHs400TxDataDll      =
> (UINT8)ScsConfig->ScsEmmcHs400TxDataDll;
> +  FspsUpd->FspsConfig.PchScsEmmcHs400DriverStrength =
> (UINT8)ScsConfig->ScsEmmcHs400DriverStrength;
> +
> +  //
> +  // Update ISH policies
> +  //
> +  FspsUpd->FspsConfig.PchIshSpiGpioAssign   =
> (UINT8)IshConfig->SpiGpioAssign;
> +  FspsUpd->FspsConfig.PchIshUart0GpioAssign =
> (UINT8)IshConfig->Uart0GpioAssign;
> +  FspsUpd->FspsConfig.PchIshUart1GpioAssign =
> (UINT8)IshConfig->Uart1GpioAssign;
> +  FspsUpd->FspsConfig.PchIshI2c0GpioAssign  =
> (UINT8)IshConfig->I2c0GpioAssign;
> +  FspsUpd->FspsConfig.PchIshI2c1GpioAssign  =
> (UINT8)IshConfig->I2c1GpioAssign;
> +  FspsUpd->FspsConfig.PchIshI2c2GpioAssign  =
> (UINT8)IshConfig->I2c2GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp0GpioAssign   =
> (UINT8)IshConfig->Gp0GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp1GpioAssign   =
> (UINT8)IshConfig->Gp1GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp2GpioAssign   =
> (UINT8)IshConfig->Gp2GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp3GpioAssign   =
> (UINT8)IshConfig->Gp3GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp4GpioAssign   =
> (UINT8)IshConfig->Gp4GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp5GpioAssign   =
> (UINT8)IshConfig->Gp5GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp6GpioAssign   =
> (UINT8)IshConfig->Gp6GpioAssign;
> +  FspsUpd->FspsConfig.PchIshGp7GpioAssign   =
> (UINT8)IshConfig->Gp7GpioAssign;
> +  FspsUpd->FspsConfig.PchIshPdtUnlock       =
> (UINT8)IshConfig->PdtUnlock;
> +
> +  //
> +  // Update PCIE RP RootPort policies
> +  //
> +  MaxPcieRootPorts = GetPchMaxPciePortNum ();
> +  FspsUpd->FspsConfig.PcieRpDpcMask = 0;
> +  FspsUpd->FspsConfig.PcieRpDpcExtensionsMask = 0;
> +  FspsUpd->FspsConfig.PcieRpPtmMask = 0;
> +  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
> +    FspsUpd->FspsConfig.PcieRpHotPlug[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].HotPlug;
> +    FspsUpd->FspsConfig.PcieRpSlotImplemented[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].SlotImplemented;
> +    FspsUpd->FspsConfig.PcieRpPmSci[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].PmSci;
> +    FspsUpd->FspsConfig.PcieRpExtSync[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].ExtSync;
> +    FspsUpd->FspsConfig.PcieRpTransmitterHalfSwing[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].TransmitterHalfSwing;
> +    FspsUpd->FspsConfig.PcieRpClkReqDetect[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].ClkReqDetect;
> +    FspsUpd->FspsConfig.PcieRpAdvancedErrorReporting[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].AdvancedErrorReporting;
> +    FspsUpd->FspsConfig.PcieRpUnsupportedRequestReport[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].UnsupportedRequestReport;
> +    FspsUpd->FspsConfig.PcieRpFatalErrorReport[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].FatalErrorReport;
> +    FspsUpd->FspsConfig.PcieRpNoFatalErrorReport[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].NoFatalErrorReport;
> +    FspsUpd->FspsConfig.PcieRpCorrectableErrorReport[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].CorrectableErrorReport;
> +    FspsUpd->FspsConfig.PcieRpSystemErrorOnFatalError[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnFatalError;
> +    FspsUpd->FspsConfig.PcieRpSystemErrorOnNonFatalError[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnNonFatalError;
> +    FspsUpd->FspsConfig.PcieRpSystemErrorOnCorrectableError[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].SystemErrorOnCorrectableError;
> +    FspsUpd->FspsConfig.PcieRpMaxPayload[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].MaxPayload;
> +    if (PcieRpConfig->RootPort[Index].DpcEnabled) {
> +      FspsUpd->FspsConfig.PcieRpDpcMask |= (BIT0<<Index);
> +    }
> +    if (PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled) {
> +      FspsUpd->FspsConfig.PcieRpDpcExtensionsMask |= (BIT0<<Index);
> +    }
> +    if (PcieRpConfig->RootPort[Index].PtmEnabled) {
> +      FspsUpd->FspsConfig.PcieRpPtmMask |= (BIT0<<Index);
> +    }
> +    FspsUpd->FspsConfig.PcieRpPcieSpeed[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].PcieSpeed;
> +    FspsUpd->FspsConfig.PcieRpGen3EqPh3Method[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].Gen3EqPh3Method;
> +    FspsUpd->FspsConfig.PcieRpPhysicalSlotNumber[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].PhysicalSlotNumber;
> +    FspsUpd->FspsConfig.PcieRpCompletionTimeout[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].CompletionTimeout;
> +    FspsUpd->FspsConfig.PcieRpAspm[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].Aspm;
> +    FspsUpd->FspsConfig.PcieRpL1Substates[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].L1Substates;
> +    FspsUpd->FspsConfig.PcieRpLtrEnable[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].LtrEnable;
> +    FspsUpd->FspsConfig.PcieRpLtrConfigLock[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].LtrConfigLock;
> +    FspsUpd->FspsConfig.PcieRpAcsEnabled[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].AcsEnabled;
> +    FspsUpd->FspsConfig.PcieRpDetectTimeoutMs[Index] =
> (UINT16)PcieRpConfig->RootPort[Index].DetectTimeoutMs;
> +    FspsUpd->FspsConfig.PcieRootPortGen2PllL1CgDisable[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].PcieRootPortGen2PllL1CgDisable;
> +
> +    FspsUpd->FspsTestConfig.PcieRpLtrMaxSnoopLatency[Index] =
> (UINT16)PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency;
> +    FspsUpd->FspsTestConfig.PcieRpLtrMaxNoSnoopLatency[Index] =
> (UINT16)PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency;
> +
> +    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideMode[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode;
> +    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideMultiplier[Index]
> = (UINT8)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier;
> +    FspsUpd->FspsTestConfig.PcieRpSnoopLatencyOverrideValue[Index] =
> (UINT16)PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue;
> +
> +    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideMode[Index]
> = (UINT8)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode;
> +
> FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideMultiplier[Index]
> =
> (UINT8)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier;
> +    FspsUpd->FspsTestConfig.PcieRpNonSnoopLatencyOverrideValue[Index]
> = (UINT16)PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue;
> +
> +    FspsUpd->FspsTestConfig.PcieRpSlotPowerLimitScale[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].SlotPowerLimitScale;
> +    FspsUpd->FspsTestConfig.PcieRpSlotPowerLimitValue[Index] =
> (UINT16)PcieRpConfig->RootPort[Index].SlotPowerLimitValue;
> +    FspsUpd->FspsTestConfig.PcieRpUptp[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].Uptp;
> +    FspsUpd->FspsTestConfig.PcieRpDptp[Index] =
> (UINT8)PcieRpConfig->RootPort[Index].Dptp;
> +
> +  }
> +  for (Index = 0; Index < GetPchMaxPcieClockNum (); Index ++) {
> +    FspsUpd->FspsConfig.PcieClkSrcUsage[Index] =
> PcieRpConfig->PcieClock[Index].Usage;
> +    FspsUpd->FspsConfig.PcieClkSrcClkReq[Index] =
> PcieRpConfig->PcieClock[Index].ClkReq;
> +  }
> +
> +  //
> +  // Update PCIE RP EqPh3LaneParam policies
> +  //
> +  for (Index = 0; Index < MaxPcieRootPorts; Index ++) {
> +    FspsUpd->FspsConfig.PcieEqPh3LaneParamCm[Index] =
> (UINT8)PcieRpConfig->EqPh3LaneParam[Index].Cm;
> +    FspsUpd->FspsConfig.PcieEqPh3LaneParamCp[Index] =
> (UINT8)PcieRpConfig->EqPh3LaneParam[Index].Cp;
> +  }
> +
> +  //
> +  // Update PCIE RP SwEqCoeffList policies
> +  //
> +  for (Index = 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index ++) {
> +    FspsUpd->FspsConfig.PcieSwEqCoeffListCm[Index] =
> (UINT8)PcieRpConfig->SwEqCoeffList[Index].Cm;
> +    FspsUpd->FspsConfig.PcieSwEqCoeffListCp[Index] =
> (UINT8)PcieRpConfig->SwEqCoeffList[Index].Cp;
> +  }
> +
> +  //
> +  // Update PCIE RP policies
> +  //
> +  FspsUpd->FspsTestConfig.PcieEnablePort8xhDecode        =
> (UINT8)PcieRpConfig->EnablePort8xhDecode;
> +  FspsUpd->FspsTestConfig.PchPciePort8xhDecodePortIndex  =
> (UINT8)PcieRpConfig->PchPciePort8xhDecodePortIndex;
> +  FspsUpd->FspsConfig.PcieDisableRootPortClockGating =
> (UINT8)PcieRpConfig->DisableRootPortClockGating;
> +  FspsUpd->FspsConfig.PcieEnablePeerMemoryWrite      =
> (UINT8)PcieRpConfig->EnablePeerMemoryWrite;
> +  FspsUpd->FspsConfig.PcieComplianceTestMode         =
> (UINT8)PcieRpConfig->ComplianceTestMode;
> +  FspsUpd->FspsConfig.PcieRpFunctionSwap             =
> (UINT8)PcieRpConfig->RpFunctionSwap;
> +  FspsUpd->FspsConfig.PchPcieDeviceOverrideTablePtr  =
> PcieRpConfig->PcieDeviceOverrideTablePtr;
> +
> +  //
> +  // Update Sata Policies
> +  //
> +  FspsUpd->FspsConfig.SataEnable                     =
> (UINT8)SataConfig->Enable;
> +  FspsUpd->FspsTestConfig.SataTestMode               =
> (UINT8)SataConfig->TestMode;
> +  FspsUpd->FspsConfig.SataSalpSupport                =
> (UINT8)SataConfig->SalpSupport;
> +  FspsUpd->FspsConfig.SataPwrOptEnable =
> (UINT8)SataConfig->PwrOptEnable;
> +  FspsUpd->FspsConfig.EsataSpeedLimit  =
> (UINT8)SataConfig->EsataSpeedLimit;
> +  FspsUpd->FspsConfig.SataLedEnable    = (UINT8)SataConfig->LedEnable;
> +  FspsUpd->FspsConfig.SataMode         = (UINT8)SataConfig->SataMode;
> +  FspsUpd->FspsConfig.SataSpeedLimit   = (UINT8)SataConfig->SpeedLimit;
> +
> +  for (Index = 0; Index < PCH_MAX_SATA_PORTS; Index++) {
> +    FspsUpd->FspsConfig.SataPortsEnable[Index] =
> (UINT8)SataConfig->PortSettings[Index].Enable;
> +    FspsUpd->FspsConfig.SataPortsHotPlug[Index]     =
> (UINT8)SataConfig->PortSettings[Index].HotPlug;
> +    FspsUpd->FspsConfig.SataPortsInterlockSw[Index] =
> (UINT8)SataConfig->PortSettings[Index].InterlockSw;
> +    FspsUpd->FspsConfig.SataPortsExternal[Index]    =
> (UINT8)SataConfig->PortSettings[Index].External;
> +    FspsUpd->FspsConfig.SataPortsSpinUp[Index]      =
> (UINT8)SataConfig->PortSettings[Index].SpinUp;
> +    FspsUpd->FspsConfig.SataPortsSolidStateDrive[Index]  =
> (UINT8)SataConfig->PortSettings[Index].SolidStateDrive;
> +    FspsUpd->FspsConfig.SataPortsDevSlp[Index] =
> (UINT8)SataConfig->PortSettings[Index].DevSlp;
> +    FspsUpd->FspsConfig.SataPortsEnableDitoConfig[Index] =
> (UINT8)SataConfig->PortSettings[Index].EnableDitoConfig;
> +    FspsUpd->FspsConfig.SataPortsDmVal[Index]       =
> (UINT8)SataConfig->PortSettings[Index].DmVal;
> +    FspsUpd->FspsConfig.SataPortsDitoVal[Index]     =
> (UINT16)SataConfig->PortSettings[Index].DitoVal;
> +    FspsUpd->FspsConfig.SataPortsZpOdd[Index]       =
> (UINT8)SataConfig->PortSettings[Index].ZpOdd;
> +  }
> +
> +  FspsUpd->FspsConfig.SataRstRaidDeviceId            =
> (UINT8)SataConfig->Rst.RaidDeviceId;
> +  FspsUpd->FspsConfig.SataRstInterrupt               =
> (UINT8)SataConfig->Rst.SataRstInterrupt;
> +  FspsUpd->FspsConfig.SataRstRaid0                   =
> (UINT8)SataConfig->Rst.Raid0;
> +  FspsUpd->FspsConfig.SataRstRaid1                   =
> (UINT8)SataConfig->Rst.Raid1;
> +  FspsUpd->FspsConfig.SataRstRaid10                  =
> (UINT8)SataConfig->Rst.Raid10;
> +  FspsUpd->FspsConfig.SataRstRaid5                   =
> (UINT8)SataConfig->Rst.Raid5;
> +  FspsUpd->FspsConfig.SataRstIrrt                    =
> (UINT8)SataConfig->Rst.Irrt;
> +  FspsUpd->FspsConfig.SataRstOromUiBanner            =
> (UINT8)SataConfig->Rst.OromUiBanner;
> +  FspsUpd->FspsConfig.SataRstOromUiDelay             =
> (UINT8)SataConfig->Rst.OromUiDelay;
> +  FspsUpd->FspsConfig.SataRstHddUnlock               =
> (UINT8)SataConfig->Rst.HddUnlock;
> +  FspsUpd->FspsConfig.SataRstLedLocate               =
> (UINT8)SataConfig->Rst.LedLocate;
> +  FspsUpd->FspsConfig.SataRstIrrtOnly                =
> (UINT8)SataConfig->Rst.IrrtOnly;
> +  FspsUpd->FspsConfig.SataRstSmartStorage            =
> (UINT8)SataConfig->Rst.SmartStorage;
> +  FspsUpd->FspsConfig.SataRstOptaneMemory            =
> (UINT8)SataConfig->Rst.OptaneMemory;
> +  FspsUpd->FspsConfig.SataRstLegacyOrom              =
> (UINT8)SataConfig->Rst.LegacyOrom;
> +  FspsUpd->FspsConfig.SataRstCpuAttachedStorage      =
> (UINT8)SataConfig->Rst.CpuAttachedStorage;
> +
> +  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
> +    FspsUpd->FspsConfig.SataRstPcieEnable[Index]           =
> (UINT8)SataConfig->RstPcieStorageRemap[Index].Enable;
> +    FspsUpd->FspsConfig.SataRstPcieStoragePort[Index]      =
> (UINT8)SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort;
> +    FspsUpd->FspsConfig.SataRstPcieDeviceResetDelay[Index] =
> (UINT8)SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay;
> +  }
> +
> +  FspsUpd->FspsConfig.SataP0T1M            =
> (UINT8)SataConfig->ThermalThrottling.P0T1M;
> +  FspsUpd->FspsConfig.SataP0T2M            =
> (UINT8)SataConfig->ThermalThrottling.P0T2M;
> +  FspsUpd->FspsConfig.SataP0T3M            =
> (UINT8)SataConfig->ThermalThrottling.P0T3M;
> +  FspsUpd->FspsConfig.SataP0TDisp          =
> (UINT8)SataConfig->ThermalThrottling.P0TDisp;
> +  FspsUpd->FspsConfig.SataP1T1M            =
> (UINT8)SataConfig->ThermalThrottling.P1T1M;
> +  FspsUpd->FspsConfig.SataP1T2M            =
> (UINT8)SataConfig->ThermalThrottling.P1T2M;
> +  FspsUpd->FspsConfig.SataP1T3M            =
> (UINT8)SataConfig->ThermalThrottling.P1T3M;
> +  FspsUpd->FspsConfig.SataP1TDisp          =
> (UINT8)SataConfig->ThermalThrottling.P1TDisp;
> +  FspsUpd->FspsConfig.SataP0Tinact         =
> (UINT8)SataConfig->ThermalThrottling.P0Tinact;
> +  FspsUpd->FspsConfig.SataP0TDispFinit     =
> (UINT8)SataConfig->ThermalThrottling.P0TDispFinit;
> +  FspsUpd->FspsConfig.SataP1Tinact         =
> (UINT8)SataConfig->ThermalThrottling.P1Tinact;
> +  FspsUpd->FspsConfig.SataP1TDispFinit     =
> (UINT8)SataConfig->ThermalThrottling.P1TDispFinit;
> +  FspsUpd->FspsConfig.SataThermalSuggestedSetting =
> (UINT8)SataConfig->ThermalThrottling.SuggestedSetting;
> +
> +  //
> +  // Update USB policies
> +  //
> +  FspsUpd->FspsConfig.PchEnableComplianceMode           =
> (UINT8)UsbConfig->EnableComplianceMode;
> +  FspsUpd->FspsConfig.UsbPdoProgramming                 =
> (UINT8)UsbConfig->PdoProgramming;
> +  FspsUpd->FspsConfig.PchUsbOverCurrentEnable           =
> (UINT8)UsbConfig->OverCurrentEnable;
> +  FspsUpd->FspsConfig.PchUsb2PhySusPgEnable             =
> (UINT8)UsbConfig->Usb2PhySusPgEnable;
> +  FspsUpd->FspsTestConfig.PchXhciOcLock                 =
> (UINT8)UsbConfig->XhciOcLock;
> +  for (Index = 0; Index < PCH_MAX_USB2_PORTS; Index++) {
> +    FspsUpd->FspsConfig.PortUsb20Enable[Index]  =
> (UINT8)UsbConfig->PortUsb20[Index].Enable;
> +    FspsUpd->FspsConfig.Usb2OverCurrentPin[Index] =
> (UINT8)UsbConfig->PortUsb20[Index].OverCurrentPin;
> +    FspsUpd->FspsConfig.Usb2AfePetxiset[Index]  =
> (UINT8)UsbConfig->PortUsb20[Index].Afe.Petxiset;
> +    FspsUpd->FspsConfig.Usb2AfeTxiset[Index]    =
> (UINT8)UsbConfig->PortUsb20[Index].Afe.Txiset;
> +    FspsUpd->FspsConfig.Usb2AfePredeemp[Index]  =
> (UINT8)UsbConfig->PortUsb20[Index].Afe.Predeemp;
> +    FspsUpd->FspsConfig.Usb2AfePehalfbit[Index] =
> (UINT8)UsbConfig->PortUsb20[Index].Afe.Pehalfbit;
> +  }
> +  for (Index = 0; Index < PCH_MAX_USB3_PORTS; Index++) {
> +    FspsUpd->FspsConfig.PortUsb30Enable[Index]              =
> (UINT8)UsbConfig->PortUsb30[Index].Enable;
> +    FspsUpd->FspsConfig.Usb3OverCurrentPin[Index]           =
> (UINT8)UsbConfig->PortUsb30[Index].OverCurrentPin;
> +    FspsUpd->FspsConfig.Usb3HsioTxDeEmphEnable[Index]       =
> (UINT8)UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable;
> +    FspsUpd->FspsConfig.Usb3HsioTxDeEmph[Index]             =
> (UINT8)UsbConfig->PortUsb30[Index].HsioTxDeEmph;
> +    FspsUpd->FspsConfig.Usb3HsioTxDownscaleAmpEnable[Index] =
> (UINT8)UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable;
> +    FspsUpd->FspsConfig.Usb3HsioTxDownscaleAmp[Index]       =
> (UINT8)UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp;
> +
> +    Data8 = 0;
> +    Data8 |=
> UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable ?
> B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN : 0;
> +    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable ?
> B_XHCI_HSIO_FILTER_SELECT_N_EN : 0;
> +    Data8 |= UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable ?
> B_XHCI_HSIO_FILTER_SELECT_P_EN : 0;
> +    Data8 |=
> UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable ?
> B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN : 0;
> +    FspsUpd->FspsConfig.PchUsbHsioRxTuningEnable[Index] = Data8;
> +
> +    Data8 = ((UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg &
> 0x1F) << N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG) |
> +            ((UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes
> & 0x7) << N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES);
> +    FspsUpd->FspsConfig.PchUsbHsioRxTuningParameters[Index] = Data8;
> +
> +    Data8 = ((UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN & 0x7) <<
> N_XHCI_UPD_HSIO_FILTER_SELECT_N) |
> +            ((UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP & 0x7) <<
> N_XHCI_UPD_HSIO_FILTER_SELECT_P);
> +    FspsUpd->FspsConfig.PchUsbHsioFilterSel[Index] = Data8;
> +  }
> +
> +  FspsUpd->FspsConfig.XdciEnable     =
> (UINT8)UsbConfig->XdciConfig.Enable;
> +
> +  //
> +  // Update SerialIo policies
> +  //
> +  for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
> +    FspsUpd->FspsConfig.SerialIoDevMode[Index] =
> SerialIoConfig->DevMode[Index];
> +  }
> +  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
> +    FspsUpd->FspsConfig.SerialIoSpiCsPolarity[Index] =
> SerialIoConfig->SpiCsPolarity[Index];
> +  }
> +  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
> +    FspsUpd->FspsConfig.SerialIoUartHwFlowCtrl[Index] =
> SerialIoConfig->UartHwFlowCtrl[Index];
> +  }
> +  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
> +    FspsUpd->FspsConfig.PchSerialIoI2cPadsTermination[Index] =
> SerialIoConfig->I2cPadsTermination[Index];
> +  }
> +
> +  FspsUpd->FspsConfig.SerialIoDebugUartNumber          =
> (UINT8)SerialIoConfig->DebugUartNumber;
> +  FspsUpd->FspsConfig.SerialIoEnableDebugUartAfterPost =
> (UINT8)SerialIoConfig->EnableDebugUartAfterPost;
> +  FspsUpd->FspsConfig.SerialIoUart0PinMuxing           =
> (UINT8)SerialIoConfig->Uart0PinMuxing;
> +
> +  //
> +  // Update Interrupt policies
> +  //
> +  FspsUpd->FspsConfig.DevIntConfigPtr =
> (UINT32)InterruptConfig->DevIntConfig;
> +  FspsUpd->FspsConfig.NumOfDevIntConfig =
> InterruptConfig->NumOfDevIntConfig;
> +  for (Index = 0; Index < PCH_MAX_PXRC_CONFIG; Index ++) {
> +    FspsUpd->FspsConfig.PxRcConfig[Index] =
> (UINT8)InterruptConfig->PxRcConfig[Index];
> +  }
> +  FspsUpd->FspsConfig.GpioIrqRoute =
> (UINT8)InterruptConfig->GpioIrqRoute;
> +  FspsUpd->FspsConfig.SciIrqSelect = (UINT8)InterruptConfig->SciIrqSelect;
> +  FspsUpd->FspsConfig.TcoIrqSelect = (UINT8)InterruptConfig->TcoIrqSelect;
> +  FspsUpd->FspsConfig.TcoIrqEnable =
> (UINT8)InterruptConfig->TcoIrqEnable;
> +
> +  //
> +  // Update LockDown policies
> +  //
> +  FspsUpd->FspsTestConfig.PchLockDownGlobalSmi     =
> (UINT8)LockDownConfig->GlobalSmi;
> +  FspsUpd->FspsTestConfig.PchLockDownBiosInterface =
> (UINT8)LockDownConfig->BiosInterface;
> +  FspsUpd->FspsConfig.PchLockDownBiosLock          =
> (UINT8)LockDownConfig->BiosLock;
> +  FspsUpd->FspsConfig.PchLockDownRtcMemoryLock     =
> (UINT8)LockDownConfig->RtcMemoryLock;
> +  FspsUpd->FspsTestConfig.PchUnlockGpioPads        =
> (UINT8)LockDownConfig->UnlockGpioPads;
> +
> +  //
> +  // Update Dmi policies
> +  //
> +  FspsUpd->FspsConfig.PchPwrOptEnable =
> (UINT8)DmiConfig->PwrOptEnable;
> +  FspsUpd->FspsConfig.PchDmiAspmCtrl = (UINT8)DmiConfig->DmiAspmCtrl;
> +
> +  //
> +  // Update Flash Protection policies
> +  //
> +  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; Index ++) {
> +    FspsUpd->FspsConfig.PchWriteProtectionEnable[Index] =
> (UINT8)FlashProtectionConfig->ProtectRange[Index].WriteProtectionEnable;
> +    FspsUpd->FspsConfig.PchReadProtectionEnable[Index]  =
> (UINT8)FlashProtectionConfig->ProtectRange[Index].ReadProtectionEnable;
> +    FspsUpd->FspsConfig.PchProtectedRangeLimit[Index]  =
> (UINT16)FlashProtectionConfig->ProtectRange[Index].ProtectedRangeLimit;
> +    FspsUpd->FspsConfig.PchProtectedRangeBase[Index]   =
> (UINT16)FlashProtectionConfig->ProtectRange[Index].ProtectedRangeBase;
> +  }
> +
> +  //
> +  // Update IO Apic policies
> +  //
> +  FspsUpd->FspsConfig.PchIoApicEntry24_119       =
> (UINT8)IoApicConfig->IoApicEntry24_119;
> +  FspsUpd->FspsConfig.Enable8254ClockGating      =
> (UINT8)IoApicConfig->Enable8254ClockGating;
> +  FspsUpd->FspsConfig.Enable8254ClockGatingOnS3  =
> (UINT8)IoApicConfig->Enable8254ClockGatingOnS3;
> +  FspsUpd->FspsConfig.PchIoApicId                =
> (UINT8)IoApicConfig->IoApicId;
> +
> +  //
> +  // Update P2sb policies
> +  //
> +  FspsUpd->FspsTestConfig.PchSbAccessUnlock  =
> (UINT8)P2sbConfig->SbAccessUnlock;
> +
> +  //
> +  // Update Pch General policies
> +  //
> +  FspsUpd->FspsConfig.PchCrid               = (UINT8)PchGeneralConfig->Crid;
> +  FspsUpd->FspsConfig.PchLegacyIoLowLatency =
> (UINT8)PchGeneralConfig->LegacyIoLowLatency;
> +
> +  //
> +  // Update Pm policies
> +  //
> +  FspsUpd->FspsConfig.PchPmPmeB0S5Dis         =
> (UINT8)PmConfig->WakeConfig.PmeB0S5Dis;
> +  FspsUpd->FspsConfig.PchPmWolEnableOverride  =
> (UINT8)PmConfig->WakeConfig.WolEnableOverride;
> +  FspsUpd->FspsConfig.PchPmPcieWakeFromDeepSx =
> (UINT8)PmConfig->WakeConfig.PcieWakeFromDeepSx;
> +  FspsUpd->FspsConfig.PchPmWoWlanEnable       =
> (UINT8)PmConfig->WakeConfig.WoWlanEnable;
> +  FspsUpd->FspsConfig.PchPmWoWlanDeepSxEnable =
> (UINT8)PmConfig->WakeConfig.WoWlanDeepSxEnable;
> +  FspsUpd->FspsConfig.PchPmLanWakeFromDeepSx  =
> (UINT8)PmConfig->WakeConfig.LanWakeFromDeepSx;
> +
> +  FspsUpd->FspsConfig.PchPmDeepSxPol          =
> (UINT8)PmConfig->PchDeepSxPol;
> +  FspsUpd->FspsConfig.PchPmSlpS3MinAssert     =
> (UINT8)PmConfig->PchSlpS3MinAssert;
> +  FspsUpd->FspsConfig.PchPmSlpS4MinAssert     =
> (UINT8)PmConfig->PchSlpS4MinAssert;
> +  FspsUpd->FspsConfig.PchPmSlpSusMinAssert    =
> (UINT8)PmConfig->PchSlpSusMinAssert;
> +  FspsUpd->FspsConfig.PchPmSlpAMinAssert      =
> (UINT8)PmConfig->PchSlpAMinAssert;
> +  FspsUpd->FspsConfig.PchPmLpcClockRun        =
> (UINT8)PmConfig->LpcClockRun;
> +  FspsUpd->FspsConfig.PchPmSlpStrchSusUp      =
> (UINT8)PmConfig->SlpStrchSusUp;
> +  FspsUpd->FspsConfig.PchPmSlpLanLowDc        =
> (UINT8)PmConfig->SlpLanLowDc;
> +  FspsUpd->FspsConfig.PchPmPwrBtnOverridePeriod =
> (UINT8)PmConfig->PwrBtnOverridePeriod;
> +  FspsUpd->FspsTestConfig.PchPmDisableEnergyReport  =
> (UINT8)PmConfig->DisableEnergyReport;
> +  FspsUpd->FspsConfig.PchPmDisableDsxAcPresentPulldown =
> (UINT8)PmConfig->DisableDsxAcPresentPulldown;
> +  FspsUpd->FspsConfig.PchPmDisableNativePowerButton    =
> (UINT8)PmConfig->DisableNativePowerButton;
> +  FspsUpd->FspsConfig.PmcPowerButtonDebounce  =
> PmConfig->PowerButtonDebounce;
> +  FspsUpd->FspsConfig.PchPmSlpS0Enable        =
> (UINT8)PmConfig->SlpS0Enable;
> +  FspsUpd->FspsConfig.PchPmMeWakeSts          =
> (UINT8)PmConfig->MeWakeSts;
> +  FspsUpd->FspsConfig.PchPmWolOvrWkSts        =
> (UINT8)PmConfig->WolOvrWkSts;
> +  FspsUpd->FspsConfig.EnableTcoTimer          =
> (UINT8)PmConfig->EnableTcoTimer;
> +  FspsUpd->FspsConfig.PchPmVrAlert            = (UINT8)PmConfig->VrAlert;
> +  FspsUpd->FspsConfig.PchPmPwrCycDur          =
> (UINT8)PmConfig->PchPwrCycDur;
> +  FspsUpd->FspsConfig.PchPmPciePllSsc         =
> (UINT8)PmConfig->PciePllSsc;
> +  FspsUpd->FspsConfig.PchPmSlpS0VmRuntimeControl =
> (UINT8)PmConfig->SlpS0VmRuntimeControl;
> +  FspsUpd->FspsConfig.PchPmSlpS0Vm070VSupport   =
> (UINT8)PmConfig->SlpS0Vm070VSupport;
> +  FspsUpd->FspsConfig.PchPmSlpS0Vm075VSupport   =
> (UINT8)PmConfig->SlpS0Vm075VSupport;
> +  FspsUpd->FspsConfig.SlpS0Override             =
> (UINT8)PmConfig->SlpS0Override;
> +  FspsUpd->FspsConfig.SlpS0DisQForDebug         =
> (UINT8)PmConfig->SlpS0DisQForDebug;
> +  FspsUpd->FspsConfig.PmcDbgMsgEn               =
> (UINT8)PmConfig->PmcDbgMsgEn;
> +  FspsUpd->FspsConfig.PsOnEnable                =
> (UINT8)PmConfig->PsOnEnable;
> +  FspsUpd->FspsConfig.PmcCpuC10GatePinEnable    =
> (UINT8)PmConfig->CpuC10GatePinEnable;
> +  FspsUpd->FspsConfig.PmcModPhySusPgEnable      =
> (UINT8)PmConfig->ModPhySusPgEnable;
> +  FspsUpd->FspsConfig.SlpS0WithGbeSupport       =
> (UINT8)PmConfig->SlpS0WithGbeSupport;
> +  //
> +  // Update Pch Serial IRQ policies
> +  //
> +  FspsUpd->FspsConfig.PchSirqEnable       =
> (UINT8)PchSerialIrqConfig->SirqEnable;
> +  FspsUpd->FspsConfig.PchSirqMode         =
> (UINT8)PchSerialIrqConfig->SirqMode;
> +  FspsUpd->FspsConfig.PchStartFramePulse  =
> (UINT8)PchSerialIrqConfig->StartFramePulse;
> +  //
> +  // Update Pch Thermal policies
> +  //
> +  FspsUpd->FspsConfig.PchTsmicLock        =
> (UINT8)PchThermalConfig->TsmicLock;
> +  FspsUpd->FspsConfig.PchHotEnable        =
> (UINT8)PchThermalConfig->PchHotEnable;
> +
> +  FspsUpd->FspsConfig.PchT0Level          =
> (UINT16)PchThermalConfig->TTLevels.T0Level;
> +  FspsUpd->FspsConfig.PchT1Level          =
> (UINT16)PchThermalConfig->TTLevels.T1Level;
> +  FspsUpd->FspsConfig.PchT2Level          =
> (UINT16)PchThermalConfig->TTLevels.T2Level;
> +  FspsUpd->FspsConfig.PchTTEnable         =
> (UINT8)PchThermalConfig->TTLevels.TTEnable;
> +  FspsUpd->FspsConfig.PchTTState13Enable  =
> (UINT8)PchThermalConfig->TTLevels.TTState13Enable;
> +  FspsUpd->FspsConfig.PchTTLock           =
> (UINT8)PchThermalConfig->TTLevels.TTLock;
> +  FspsUpd->FspsConfig.TTSuggestedSetting  =
> (UINT8)PchThermalConfig->TTLevels.SuggestedSetting;
> +  FspsUpd->FspsConfig.TTCrossThrottling   =
> (UINT8)PchThermalConfig->TTLevels.PchCrossThrottling;
> +
> +  FspsUpd->FspsConfig.PchDmiTsawEn        =
> (UINT8)PchThermalConfig->DmiHaAWC.DmiTsawEn;
> +  FspsUpd->FspsConfig.DmiSuggestedSetting =
> (UINT8)PchThermalConfig->DmiHaAWC.SuggestedSetting;
> +  FspsUpd->FspsConfig.DmiTS0TW            =
> (UINT8)PchThermalConfig->DmiHaAWC.TS0TW;
> +  FspsUpd->FspsConfig.DmiTS1TW            =
> (UINT8)PchThermalConfig->DmiHaAWC.TS1TW;
> +  FspsUpd->FspsConfig.DmiTS2TW            =
> (UINT8)PchThermalConfig->DmiHaAWC.TS2TW;
> +  FspsUpd->FspsConfig.DmiTS3TW            =
> (UINT8)PchThermalConfig->DmiHaAWC.TS3TW;
> +
> +  FspsUpd->FspsConfig.PchMemoryThrottlingEnable    =
> (UINT8)PchThermalConfig->MemoryThrottling.Enable;
> +  FspsUpd->FspsConfig.PchMemoryPmsyncEnable[0]     =
> (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].PmsyncEn
> able;
> +  FspsUpd->FspsConfig.PchMemoryPmsyncEnable[1]     =
> (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].PmsyncEn
> able;
> +  FspsUpd->FspsConfig.PchMemoryC0TransmitEnable[0] =
> (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].C0Transm
> itEnable;
> +  FspsUpd->FspsConfig.PchMemoryC0TransmitEnable[1] =
> (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].C0Transm
> itEnable;
> +  FspsUpd->FspsConfig.PchMemoryPinSelection[0]     =
> (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[0].PinSelecti
> on;
> +  FspsUpd->FspsConfig.PchMemoryPinSelection[1]     =
> (UINT8)PchThermalConfig->MemoryThrottling.TsGpioPinSetting[1].PinSelecti
> on;
> +
> +  FspsUpd->FspsConfig.PchTemperatureHotLevel =
> (UINT16)PchThermalConfig->PchHotLevel;
> +
> +  //
> +  // Update Pch CNVi policies
> +  //
> +  FspsUpd->FspsConfig.PchCnviMode        = (UINT8)CnviConfig->Mode;
> +  FspsUpd->FspsConfig.PchCnviMfUart1Type =
> (UINT8)CnviConfig->MfUart1Type;
> +
> +  //
> +  // Update Pch HSIO policies
> +  //
> +  FspsUpd->FspsConfig.ChipsetInitBinPtr = HsioConfig->ChipsetInitBinPtr;
> +  FspsUpd->FspsConfig.ChipsetInitBinLen = HsioConfig->ChipsetInitBinLen;
> +
> +  //
> +  // Update Pch Espi policies
> +  //
> +  FspsUpd->FspsConfig.PchEspiLgmrEnable =
> (UINT8)EspiConfig->LgmrEnable;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.c
> new file mode 100644
> index 0000000000..ce34325781
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspPolicyInitLib.c
> @@ -0,0 +1,223 @@
> +/** @file
> +  Instance of Fsp Policy Initialization Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +#include <Library/SpiLib.h>
> +
> +VOID
> +EFIAPI
> +FspPolicyInitPreMem(
> +  IN FSPM_UPD           *FspmUpdDataPtr
> +);
> +
> +VOID *
> +EFIAPI
> +SiliconPolicyInitPreMem(
> +  IN OUT VOID    *FspmUpd
> +)
> +{
> +  FspPolicyInitPreMem((FSPM_UPD *)FspmUpd);
> +  return FspmUpd;
> +}
> +
> +RETURN_STATUS
> +EFIAPI
> +SiliconPolicyDonePreMem(
> +  IN VOID *FspmUpd
> +)
> +{
> +  EFI_STATUS         Status;
> +
> +  Status = SpiServiceInit();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Performs FSP PEI Policy Pre-memory initialization.
> +
> +  @param[in] FspmUpdDataPtr       Pointer to FSPM UPD data.
> +**/
> +VOID
> +EFIAPI
> +FspPolicyInitPreMem (
> +  IN FSPM_UPD           *FspmUpdDataPtr
> +  )
> +{
> +  EFI_STATUS            Status;
> +
> +  //
> +  // SI Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspSiPolicyInitPreMem (FspmUpdDataPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy in Pre-Memory
> Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // PCH Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspPchPolicyInitPreMem (FspmUpdDataPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - PCH Pei Fsp Policy in Pre-Memory
> Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // Cpu Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspCpuPolicyInitPreMem (FspmUpdDataPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy in Pre-Memory
> Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // Security Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspSecurityPolicyInitPreMem (FspmUpdDataPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - Security Pei Fsp Policy in Pre-Memory
> Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // ME Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspMePolicyInitPreMem (FspmUpdDataPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - ME Pei Fsp Policy in Pre-Memory
> Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // SystemAgent Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspSaPolicyInitPreMem (FspmUpdDataPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy in
> Pre-Memory Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // Other Upd Initialization
> +  //
> +  Status = PeiFspMiscUpdInitPreMem (FspmUpdDataPtr);
> +
> +}
> +
> +/**
> +  Performs FSP PEI Policy initialization.
> +
> +  @param[in][out] FspsUpd  Pointer UPD data region
> +
> +**/
> +VOID
> +EFIAPI
> +FspPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  EFI_STATUS            Status;
> +
> +  //
> +  // SI Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspSiPolicyInit (FspsUpd);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - SI Pei Fsp Policy iInitialization fail,
> Status = %r\n", Status));
> +  }
> +
> +  //
> +  // PCH Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspPchPolicyInit (FspsUpd);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - PCH Pei Fsp Policy iInitialization fail,
> Status = %r\n", Status));
> +  }
> +
> +  //
> +  // ME Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspMePolicyInit (FspsUpd);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - ME Pei Fsp Policy Initialization fail,
> Status = %r\n", Status));
> +  }
> +
> +  //
> +  // SystemAgent Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspSaPolicyInit (FspsUpd);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - SystemAgent Pei Fsp Policy
> Initialization fail, Status = %r\n", Status));
> +  }
> +
> +  //
> +  // Cpu Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspCpuPolicyInit (FspsUpd);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "ERROR - CPU Pei Fsp Policy Initialization fail,
> Status = %r\n", Status));
> +  }
> +
> +  //
> +  // Security Pei Fsp Policy Initialization
> +  //
> +  Status = PeiFspSecurityPolicyInit(FspsUpd);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG((DEBUG_ERROR, "ERROR - Security Pei Fsp Policy Initialization fail,
> Status = %r\n", Status));
> +  }
> +
> +}
> +
> +/**
> +Performs silicon post-mem policy initialization.
> +
> +The meaning of Policy is defined by silicon code.
> +It could be the raw data, a handle, a PPI, etc.
> +
> +The returned data must be used as input data for
> SiliconPolicyDonePostMem(),
> +and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
> +
> +1) In FSP path, the input Policy should be FspsUpd.
> +Value of FspsUpd has been initialized by FSP binary default value.
> +Only a subset of FspsUpd needs to be updated for different silicon sku.
> +The return data is same FspsUpd.
> +
> +2) In non-FSP path, the input policy could be NULL.
> +The return data is the initialized policy.
> +
> +@param[in, out] Policy       Pointer to policy.
> +
> +@return the initialized policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyInitPostMem(
> +  IN OUT VOID    *FspsUpd
> +)
> +{
> +  FspPolicyInit((FSPS_UPD *)FspsUpd);
> +  return FspsUpd;
> +}
> +
> +/*
> +The silicon post-mem policy is finalized.
> +Silicon code can do initialization based upon the policy data.
> +
> +The input Policy must be returned by SiliconPolicyInitPostMem().
> +
> +@param[in] Policy       Pointer to policy.
> +
> +@retval EFI_SUCCESS The policy is handled consumed by silicon code.
> +*/
> +EFI_STATUS
> +EFIAPI
> +SiliconPolicyDonePostMem(
> +  IN OUT VOID    *FspsUpd
> +)
> +{
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSaPolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSaPolicyInitLib.c
> new file mode 100644
> index 0000000000..0bfc379386
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSaPolicyInitLib.c
> @@ -0,0 +1,848 @@
> +/** @file
> +  Implementation of Fsp SA Policy Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +
> +#include <Ppi/SiPolicy.h>
> +#include <ConfigBlock/MemoryConfig.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/SmbusLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PcdLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <PchAccess.h>
> +#include <Ppi/FirmwareVolume.h>
> +#include <Pi/PiFirmwareFile.h>
> +#include <Pi/PiPeiCis.h>
> +#include <Core/Pei/PeiMain.h>
> +
> +#define MAX_SPD_PAGE_COUNT           (2)
> +#define MAX_SPD_PAGE_SIZE            (256)
> +#define MAX_SPD_SIZE                 (MAX_SPD_PAGE_SIZE *
> MAX_SPD_PAGE_COUNT)
> +#define SPD_PAGE_ADDRESS_0           (0x6C)
> +#define SPD_PAGE_ADDRESS_1           (0x6E)
> +#define SPD_DDR3_SDRAM_TYPE_OFFSET   (0x02)
> +#define SPD_DDR3_SDRAM_TYPE_NUMBER   (0x0B)
> +#define SPD_DDR4_SDRAM_TYPE_NUMBER   (0x0C)
> +#define SPD_LPDDR3_SDRAM_TYPE_NUMBER (0xF1)
> +#define SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER (0x0F)
> +#define XMP_ID_STRING                (0x4A0C)
> +#define SPD3_MANUF_START             (117)
> +#define SPD3_MANUF_END               (127)
> +#define SPD4_MANUF_START             (320)
> +#define SPD4_MANUF_END               (328)
> +#define SPDLP_MANUF_START            (320)
> +#define SPDLP_MANUF_END              (328)
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE
> mSpdDdr3Table[] = {
> +  {   0,               1,             (1 << SpdCold),},
> +  {   2,               2,             (1 << SpdCold) | (1 << SpdFast),},
> +  {   3,              41,             (1 << SpdCold),},
> +  {  60,              63,             (1 << SpdCold),},
> +  { SPD3_MANUF_START, SPD3_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
> +  { 128,             145,             (1 << SpdCold),},
> +  {  39,              59,             (1 << SpdCold),},
> +  {  64,             125,             (1 << SpdCold),},
> +  { 176,             179,             (1 << SpdCold),},
> +  { 180,             184,             (1 << SpdCold),},
> +  { 185,             215,             (1 << SpdCold),},
> +  { 220,             250,             (1 << SpdCold),},
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE
> mSpdDdr4Table[] = {
> +  {   0,               1,             (1 << SpdCold),},
> +  {   2,               2,             (1 << SpdCold) | (1 << SpdFast),},
> +  {   3,              40,             (1 << SpdCold),},
> +  { 117,             131,             (1 << SpdCold),},
> +  { SPD4_MANUF_START, SPD4_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
> +  { 329,             348,             (1 << SpdCold),},
> +  {  32,             119,             (1 << SpdCold),},
> +  { 126,             255,             (1 << SpdCold),},
> +  { 349,             383,             (1 << SpdCold),},
> +  { 384,             387,             (1 << SpdCold),},
> +  { 388,             389,             (1 << SpdCold),},
> +  { 393,             431,             (1 << SpdCold),},
> +  { 440,             478,             (1 << SpdCold),},
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE
> mSpdLpddrTable[] = {
> +  {   0,               1,               (1 << SpdCold),},
> +  {   2,               2,               (1 << SpdCold) | (1 << SpdFast),},
> +  {   3,              32,               (1 << SpdCold),},
> +  { 120,             130,               (1 << SpdCold),},
> +  { SPDLP_MANUF_START, SPDLP_MANUF_END, (1 << SpdCold) | (1 <<
> SpdFast),},
> +  { 329,             348,               (1 << SpdCold),},
> +  {  31,             121,               (1 << SpdCold),},
> +  { 126,             255,               (1 << SpdCold),},
> +  { 349,             383,               (1 << SpdCold),},
> +  { 384,             387,               (1 << SpdCold),},
> +  { 388,             389,               (1 << SpdCold),},
> +  { 393,             431,               (1 << SpdCold),},
> +  { 440,             478,               (1 << SpdCold),},
> +};
> +
> +
> +/**
> +  Update Spd Data
> +
> +  @param[in][out] FspmUpd              Pointer to FSP UPD Data.
> +  @param[in]      MemConfigNoCrc       Pointer to Mem Config No Crc.
> +  @param[in]      MiscPeiPreMemConfig  Pointer to Misc Config.
> +
> +  @retval         EFI_SUCCESS          The function completes successfully
> +  @retval         Other                The function fail
> +**/
> +VOID
> +EFIAPI
> +InternalUpdateSpdInfo (
> +  IN OUT FSPM_UPD               *FspmUpd,
> +  IN MEMORY_CONFIG_NO_CRC       *MemConfigNoCrc,
> +  IN SA_MISC_PEI_PREMEM_CONFIG  *MiscPeiPreMemConfig
> +  )
> +{
> +
> +  DEBUG ((DEBUG_INFO, "Updating UPD:Memory Spd Pointers...\n"));
> +  if ((FspmUpd == NULL) || (MemConfigNoCrc == NULL) ||
> (MiscPeiPreMemConfig == NULL)) {
> +    DEBUG ((DEBUG_ERROR, "EFI_INVALID_PARAMETER.\n"));
> +    DEBUG ((DEBUG_ERROR, "Fail to access SPD from SiPolicyPpi\n"));
> +    return;
> +  }
> +
> +  //
> +  // Update MemorySpdPtrXX if SpdAddressTable is zero
> +  //
> +  if (MiscPeiPreMemConfig->SpdAddressTable[0] == 0x0) {
> +    FspmUpd->FspmConfig.MemorySpdPtr00 =
> (UINT32)MemConfigNoCrc->SpdData->SpdData;
> +  } else {
> +    FspmUpd->FspmConfig.SpdAddressTable[0] =
> MiscPeiPreMemConfig->SpdAddressTable[0];
> +  }
> +
> +  if (MiscPeiPreMemConfig->SpdAddressTable[1] == 0x0) {
> +    FspmUpd->FspmConfig.MemorySpdPtr01 =
> (UINT32)MemConfigNoCrc->SpdData->SpdData + (1 *
> SA_MC_MAX_SPD_SIZE);
> +  } else {
> +    FspmUpd->FspmConfig.SpdAddressTable[1] =
> MiscPeiPreMemConfig->SpdAddressTable[1];
> +  }
> +
> +  if (MiscPeiPreMemConfig->SpdAddressTable[2] == 0x0) {
> +    FspmUpd->FspmConfig.MemorySpdPtr10 =
> (UINT32)MemConfigNoCrc->SpdData->SpdData + (2 *
> SA_MC_MAX_SPD_SIZE);
> +  } else {
> +    FspmUpd->FspmConfig.SpdAddressTable[2] =
> MiscPeiPreMemConfig->SpdAddressTable[2];
> +  }
> +
> +  if (MiscPeiPreMemConfig->SpdAddressTable[3] == 0x0) {
> +    FspmUpd->FspmConfig.MemorySpdPtr11 =
> (UINT32)MemConfigNoCrc->SpdData->SpdData + (3 *
> SA_MC_MAX_SPD_SIZE);
> +  } else {
> +    FspmUpd->FspmConfig.SpdAddressTable[3] =
> MiscPeiPreMemConfig->SpdAddressTable[3];
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "UPD:MemorySpdPtr Updated\n"));
> +}
> +
> +/**
> +  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
> +
> +  @param[in] NameGuid              - File GUID
> +  @param[out] Address              - Pointer to the File Address
> +  @param[out] Size                 - Pointer to File Size
> +
> +  @retval EFI_SUCCESS                Successfull in reading the section from FV
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiGetSectionFromFv (
> +  IN CONST  EFI_GUID        NameGuid,
> +  OUT VOID                  **Address,
> +  OUT UINT32               *Size
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_PEI_FIRMWARE_VOLUME_PPI          *FvPpi;
> +  EFI_FV_FILE_INFO                     FvFileInfo;
> +  PEI_CORE_INSTANCE                    *PrivateData;
> +  UINTN                                CurrentFv;
> +  PEI_CORE_FV_HANDLE                   *CoreFvHandle;
> +  EFI_PEI_FILE_HANDLE                  VbtFileHandle;
> +  EFI_GUID                             *VbtGuid;
> +  EFI_COMMON_SECTION_HEADER            *Section;
> +  CONST EFI_PEI_SERVICES               **PeiServices;
> +
> +  PeiServices = GetPeiServicesTablePointer ();
> +
> +  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
> +
> +  Status = PeiServicesLocatePpi (
> +            &gEfiFirmwareFileSystem2Guid,
> +            0,
> +            NULL,
> +            (VOID **) &FvPpi
> +            );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  CurrentFv = PrivateData->CurrentPeimFvCount;
> +  CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
> +
> +  Status = FvPpi->FindFileByName (FvPpi, &NameGuid,
> &CoreFvHandle->FvHandle, &VbtFileHandle);
> +  if (!EFI_ERROR(Status) && VbtFileHandle != NULL) {
> +
> +  DEBUG ((DEBUG_INFO, "Find SectionByType \n"));
> +
> +    Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW,
> VbtFileHandle, (VOID **) &VbtGuid);
> +    if (!EFI_ERROR (Status)) {
> +
> +    DEBUG ((DEBUG_INFO, "GetFileInfo \n"));
> +
> +      Status = FvPpi->GetFileInfo (FvPpi, VbtFileHandle, &FvFileInfo);
> +      Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
> +
> +      if (IS_SECTION2 (Section)) {
> +        ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);
> +        *Size = SECTION2_SIZE (Section) - sizeof
> (EFI_COMMON_SECTION_HEADER2);
> +        *Address = ((UINT8 *)Section + sizeof
> (EFI_COMMON_SECTION_HEADER2));
> +      } else {
> +        *Size = SECTION_SIZE (Section) - sizeof
> (EFI_COMMON_SECTION_HEADER);
> +        *Address = ((UINT8 *)Section + sizeof
> (EFI_COMMON_SECTION_HEADER));
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Performs FSP SA PEI Policy initialization in pre-memory.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSaPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
> +  MEMORY_CONFIGURATION        *MemConfig;
> +  MEMORY_CONFIG_NO_CRC        *MemConfigNoCrc;
> +  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
> +  PCIE_PEI_PREMEM_CONFIG      *PciePeiPreMemConfig;
> +  SWITCHABLE_GRAPHICS_CONFIG  *SgGpioData;
> +  GRAPHICS_PEI_PREMEM_CONFIG  *GtPreMemConfig;
> +  OVERCLOCKING_PREMEM_CONFIG  *OcPreMemConfig;
> +  VTD_CONFIG                  *Vtd;
> +  IPU_PREMEM_CONFIG           *IpuPreMemPolicy;
> +  UINT8                       Index;
> +  VOID                        *Buffer;
> +
> +  SiPreMemPolicyPpi   = NULL;
> +  MiscPeiPreMemConfig = NULL;
> +  MemConfig           = NULL;
> +  MemConfigNoCrc      = NULL;
> +  PciePeiPreMemConfig = NULL;
> +  SgGpioData          = NULL;
> +  GtPreMemConfig      = NULL;
> +  OcPreMemConfig      = NULL;
> +  Vtd                 = NULL;
> +  IpuPreMemPolicy     = NULL;
> +
> +
> +
> +  //
> +  // Locate SiPreMemPolicyPpi
> +  //
> +  Status = PeiServicesLocatePpi(
> +             &gSiPreMemPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPreMemPolicyPpi
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +  if ((Status == EFI_SUCCESS) && (SiPreMemPolicyPpi != NULL)) {
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gMemoryConfigGuid, (VOID *) &MemConfig);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gSwitchableGraphicsConfigGuid, (VOID *) &SgGpioData);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gVtdConfigGuid,
> (VOID *) &Vtd);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
> +    ASSERT_EFI_ERROR (Status);
> +    Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
> +    ASSERT_EFI_ERROR (Status);
> +
> +  }
> +
> +  DEBUG((DEBUG_INFO, "Updating Dq Byte Map and DQS Byte Swizzling
> Settings...\n"));
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh0, Buffer, 12);
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh1, (UINT8*)
> Buffer + 12, 12);
> +  }
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh0, Buffer,
> 8);
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh1,
> (UINT8*) Buffer + 8, 8);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "Updating Dq Pins Interleaved,Rcomp Resistor &
> Rcomp Target Settings...\n"));
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompResistor, Buffer, 6);
> +  }
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompTarget, Buffer, 10);
> +  }
> +
> +  //
> +  // Update UPD:MemorySpdPtrXX and SpdAddressTable
> +  //
> +  InternalUpdateSpdInfo (FspmUpd, MemConfigNoCrc,
> MiscPeiPreMemConfig);
> +
> +  //
> +  // Update UPD:MemorySpdDataLen
> +  //
> +  FspmUpd->FspmConfig.MemorySpdDataLen = SA_MC_MAX_SPD_SIZE;
> +
> +  if (MemConfigNoCrc != NULL) {
> +    //
> +    // Update UPD:PlatformMemorySize
> +    //
> +    //
> +    // @todo: This value is used since #183932. Revisit.
> +    //
> +    FspmUpd->FspmConfig.PlatformMemorySize  =
> MemConfigNoCrc->PlatformMemorySize;
> +    FspmUpd->FspmConfig.CleanMemory         = (UINT8)
> MemConfigNoCrc->CleanMemory;
> +    FspmUpd->FspmConfig.MemTestOnWarmBoot   = (UINT8)
> MemConfigNoCrc->MemTestOnWarmBoot;
> +  }
> +
> +  if (MemConfig != NULL) {
> +    //
> +    // Update UPD:DqPinsInterleaved
> +    //
> +    FspmUpd->FspmConfig.DqPinsInterleaved     = (UINT8)
> MemConfig->DqPinsInterleaved;
> +
> +    FspmUpd->FspmConfig.ProbelessTrace        =
> MemConfig->ProbelessTrace;
> +    FspmUpd->FspmConfig.GdxcIotSize           = MemConfig->GdxcIotSize;
> +    FspmUpd->FspmConfig.GdxcMotSize           =
> MemConfig->GdxcMotSize;
> +    FspmUpd->FspmConfig.DualDimmPerChannelBoardType =(UINT8)
> MemConfig->DualDimmPerChannelBoardType;
> +    FspmUpd->FspmConfig.Ddr4MixedUDimm2DpcLimit     =(UINT8)
> MemConfig->Ddr4MixedUDimm2DpcLimit;
> +    //
> +    // Update UPD:CaVrefConfig
> +    //
> +    FspmUpd->FspmConfig.CaVrefConfig          = MemConfig->CaVrefConfig;
> +    FspmUpd->FspmConfig.SaGv                  = MemConfig->SaGv;
> +    FspmUpd->FspmConfig.FreqSaGvLow           =
> MemConfig->FreqSaGvLow;
> +    FspmUpd->FspmConfig.FreqSaGvMid           =
> MemConfig->FreqSaGvMid;
> +    FspmUpd->FspmConfig.RMT                   = (UINT8) MemConfig->RMT;
> +    FspmUpd->FspmConfig.DdrFreqLimit          = MemConfig->DdrFreqLimit;
> +
> +    FspmUpd->FspmConfig.SpdProfileSelected    =
> MemConfig->SpdProfileSelected;
> +    FspmUpd->FspmConfig.VddVoltage            = MemConfig->VddVoltage;
> +    FspmUpd->FspmConfig.RefClk                = MemConfig->RefClk;
> +    FspmUpd->FspmConfig.Ratio                 = MemConfig->Ratio;
> +    FspmUpd->FspmConfig.OddRatioMode          = (UINT8)
> MemConfig->OddRatioMode;
> +    FspmUpd->FspmConfig.tCL                   = (UINT8) MemConfig->tCL;
> +    FspmUpd->FspmConfig.tCWL                  = (UINT8) MemConfig->tCWL;
> +    FspmUpd->FspmConfig.tFAW                  = MemConfig->tFAW;
> +    FspmUpd->FspmConfig.tRAS                  = MemConfig->tRAS;
> +    FspmUpd->FspmConfig.tRCDtRP               = (UINT8)
> MemConfig->tRCDtRP;
> +    FspmUpd->FspmConfig.tREFI                 = MemConfig->tREFI;
> +    FspmUpd->FspmConfig.tRFC                  = MemConfig->tRFC;
> +    FspmUpd->FspmConfig.tRRD                  = (UINT8) MemConfig->tRRD;
> +    FspmUpd->FspmConfig.tRTP                  = (UINT8) MemConfig->tRTP;
> +    FspmUpd->FspmConfig.tWR                   = (UINT8) MemConfig->tWR;
> +    FspmUpd->FspmConfig.tWTR                  = (UINT8) MemConfig->tWTR;
> +    FspmUpd->FspmConfig.NModeSupport          =
> MemConfig->NModeSupport;
> +    FspmUpd->FspmConfig.DllBwEn0              = MemConfig->DllBwEn0;
> +    FspmUpd->FspmConfig.DllBwEn1              = MemConfig->DllBwEn1;
> +    FspmUpd->FspmConfig.DllBwEn2              = MemConfig->DllBwEn2;
> +    FspmUpd->FspmConfig.DllBwEn3              = MemConfig->DllBwEn3;
> +    FspmUpd->FspmConfig.MrcSafeConfig         = (UINT8)
> MemConfig->MrcSafeConfig; // Typecasting as MrcSafeConfig is of UINT32 in
> MEMORY_CONFIGURATION
> +    FspmUpd->FspmConfig.LpDdrDqDqsReTraining  = (UINT8)
> MemConfig->Lp4DqsOscEn;
> +    FspmUpd->FspmConfig.RmtPerTask            = (UINT8)
> MemConfig->RmtPerTask;
> +    FspmUpd->FspmConfig.TrainTrace            = (UINT8)
> MemConfig->TrainTrace;
> +    FspmUpd->FspmConfig.ScramblerSupport      = (UINT8)
> MemConfig->ScramblerSupport;
> +    FspmUpd->FspmConfig.SafeMode              = (UINT8)
> MemConfig->SafeMode;
> +
> +    //
> +    // Update UPD:SmramMask and DisableDimmChannel
> +    //
> +    FspmUpd->FspmConfig.SmramMask               =
> MemConfig->SmramMask;
> +    FspmUpd->FspmConfig.DisableDimmChannel0     =
> MemConfig->DisableDimmChannel[0];
> +    FspmUpd->FspmConfig.DisableDimmChannel1     =
> MemConfig->DisableDimmChannel[1];
> +    FspmUpd->FspmConfig.HobBufferSize           =
> MemConfig->HobBufferSize;
> +
> +    FspmUpd->FspmConfig.ECT                     = (UINT8) MemConfig->ECT;
> +    FspmUpd->FspmConfig.SOT                     = (UINT8) MemConfig->SOT;
> +    FspmUpd->FspmConfig.ERDMPRTC2D              = (UINT8)
> MemConfig->ERDMPRTC2D;
> +    FspmUpd->FspmConfig.RDMPRT                  = (UINT8)
> MemConfig->RDMPRT;
> +    FspmUpd->FspmConfig.RCVET                   = (UINT8)
> MemConfig->RCVET;
> +    FspmUpd->FspmConfig.JWRL                    = (UINT8) MemConfig->JWRL;
> +    FspmUpd->FspmConfig.EWRTC2D                 = (UINT8)
> MemConfig->EWRTC2D;
> +    FspmUpd->FspmConfig.ERDTC2D                 = (UINT8)
> MemConfig->ERDTC2D;
> +    FspmUpd->FspmConfig.WRTC1D                  = (UINT8)
> MemConfig->WRTC1D;
> +    FspmUpd->FspmConfig.WRVC1D                  = (UINT8)
> MemConfig->WRVC1D;
> +    FspmUpd->FspmConfig.RDTC1D                  = (UINT8)
> MemConfig->RDTC1D;
> +    FspmUpd->FspmConfig.DIMMODTT                = (UINT8)
> MemConfig->DIMMODTT;
> +    FspmUpd->FspmConfig.DIMMRONT                = (UINT8)
> MemConfig->DIMMRONT;
> +    FspmUpd->FspmConfig.WRSRT                   = (UINT8)
> MemConfig->WRSRT;
> +    FspmUpd->FspmConfig.RDODTT                  = (UINT8)
> MemConfig->RDODTT;
> +    FspmUpd->FspmConfig.RDEQT                   = (UINT8)
> MemConfig->RDEQT;
> +    FspmUpd->FspmConfig.RDAPT                   = (UINT8)
> MemConfig->RDAPT;
> +    FspmUpd->FspmConfig.WRTC2D                  = (UINT8)
> MemConfig->WRTC2D;
> +    FspmUpd->FspmConfig.RDTC2D                  = (UINT8)
> MemConfig->RDTC2D;
> +    FspmUpd->FspmConfig.WRVC2D                  = (UINT8)
> MemConfig->WRVC2D;
> +    FspmUpd->FspmConfig.RDVC2D                  = (UINT8)
> MemConfig->RDVC2D;
> +    FspmUpd->FspmConfig.CMDVC                   = (UINT8)
> MemConfig->CMDVC;
> +    FspmUpd->FspmConfig.LCT                     = (UINT8) MemConfig->LCT;
> +    FspmUpd->FspmConfig.RTL                     = (UINT8) MemConfig->RTL;
> +    FspmUpd->FspmConfig.TAT                     = (UINT8) MemConfig->TAT;
> +    FspmUpd->FspmConfig.RCVENC1D                = (UINT8)
> MemConfig->RCVENC1D;
> +    FspmUpd->FspmConfig.RMT                     = (UINT8) MemConfig->RMT;
> +    FspmUpd->FspmConfig.MEMTST                  = (UINT8)
> MemConfig->MEMTST;
> +    FspmUpd->FspmConfig.ALIASCHK                = (UINT8)
> MemConfig->ALIASCHK;
> +    FspmUpd->FspmConfig.RMC                     = (UINT8) MemConfig->RMC;
> +    FspmUpd->FspmConfig.WRDSUDT                 = (UINT8)
> MemConfig->WRDSUDT;
> +    FspmUpd->FspmConfig.EnBER                   = (UINT8)
> MemConfig->EnBER;
> +    FspmUpd->FspmConfig.EccSupport              = (UINT8)
> MemConfig->EccSupport;
> +    FspmUpd->FspmConfig.RemapEnable             = (UINT8)
> MemConfig->RemapEnable;
> +    FspmUpd->FspmConfig.ScramblerSupport        = (UINT8)
> MemConfig->ScramblerSupport;
> +    FspmUpd->FspmConfig.MrcFastBoot             = (UINT8)
> MemConfig->MrcFastBoot;
> +    FspmUpd->FspmConfig.RankInterleave          = (UINT8)
> MemConfig->RankInterleave;
> +    FspmUpd->FspmConfig.EnhancedInterleave      = (UINT8)
> MemConfig->EnhancedInterleave;
> +    FspmUpd->FspmConfig.MemoryTrace             = (UINT8)
> MemConfig->MemoryTrace;
> +    FspmUpd->FspmConfig.ChHashEnable            = (UINT8)
> MemConfig->ChHashEnable;
> +    FspmUpd->FspmConfig.EnableExtts             = (UINT8)
> MemConfig->EnableExtts;
> +    FspmUpd->FspmConfig.EnableCltm              = (UINT8)
> MemConfig->EnableCltm;
> +    FspmUpd->FspmConfig.EnableOltm              = (UINT8)
> MemConfig->EnableOltm;
> +    FspmUpd->FspmConfig.EnablePwrDn             = (UINT8)
> MemConfig->EnablePwrDn;
> +    FspmUpd->FspmConfig.EnablePwrDnLpddr        = (UINT8)
> MemConfig->EnablePwrDnLpddr;
> +    FspmUpd->FspmConfig.UserPowerWeightsEn      = (UINT8)
> MemConfig->UserPowerWeightsEn;
> +    FspmUpd->FspmConfig.RaplLim2Lock            = (UINT8)
> MemConfig->RaplLim2Lock;
> +    FspmUpd->FspmConfig.RaplLim2Ena             = (UINT8)
> MemConfig->RaplLim2Ena;
> +    FspmUpd->FspmConfig.RaplLim1Ena             = (UINT8)
> MemConfig->RaplLim1Ena;
> +    FspmUpd->FspmConfig.SrefCfgEna              = (UINT8)
> MemConfig->SrefCfgEna;
> +    FspmUpd->FspmConfig.ThrtCkeMinDefeatLpddr   = (UINT8)
> MemConfig->ThrtCkeMinDefeatLpddr;
> +    FspmUpd->FspmConfig.ThrtCkeMinDefeat        = (UINT8)
> MemConfig->ThrtCkeMinDefeat;
> +    FspmUpd->FspmConfig.RhPrevention            = (UINT8)
> MemConfig->RhPrevention;
> +    FspmUpd->FspmConfig.ExitOnFailure           = (UINT8)
> MemConfig->ExitOnFailure;
> +    FspmUpd->FspmConfig.DdrThermalSensor        = (UINT8)
> MemConfig->DdrThermalSensor;
> +    FspmUpd->FspmConfig.Ddr4DdpSharedClock      = (UINT8)
> MemConfig->Ddr4DdpSharedClock;
> +    FspmUpd->FspmConfig.Ddr4DdpSharedZq         = (UINT8)
> MemConfig->SharedZqPin;
> +    FspmUpd->FspmConfig.BClkFrequency           =
> MemConfig->BClkFrequency;
> +    FspmUpd->FspmConfig.ChHashInterleaveBit     =
> MemConfig->ChHashInterleaveBit;
> +    FspmUpd->FspmConfig.ChHashMask              =
> MemConfig->ChHashMask;
> +    FspmUpd->FspmConfig.EnergyScaleFact         =
> MemConfig->EnergyScaleFact;
> +    FspmUpd->FspmConfig.Idd3n                   = MemConfig->Idd3n;
> +    FspmUpd->FspmConfig.Idd3p                   = MemConfig->Idd3p;
> +    FspmUpd->FspmConfig.CMDSR                   = (UINT8)
> MemConfig->CMDSR;
> +    FspmUpd->FspmConfig.CMDDSEQ                 = (UINT8)
> MemConfig->CMDDSEQ;
> +    FspmUpd->FspmConfig.CMDNORM                 = (UINT8)
> MemConfig->CMDNORM;
> +    FspmUpd->FspmConfig.EWRDSEQ                 = (UINT8)
> MemConfig->EWRDSEQ;
> +    FspmUpd->FspmConfig.FreqSaGvLow             =
> MemConfig->FreqSaGvLow;
> +    FspmUpd->FspmConfig.RhActProbability        =
> MemConfig->RhActProbability;
> +    FspmUpd->FspmConfig.RaplLim2WindX           =
> MemConfig->RaplLim2WindX;
> +    FspmUpd->FspmConfig.RaplLim2WindY           =
> MemConfig->RaplLim2WindY;
> +    FspmUpd->FspmConfig.RaplLim1WindX           =
> MemConfig->RaplLim1WindX;
> +    FspmUpd->FspmConfig.RaplLim1WindY           =
> MemConfig->RaplLim1WindY;
> +    FspmUpd->FspmConfig.RaplLim2Pwr             =
> MemConfig->RaplLim2Pwr;
> +    FspmUpd->FspmConfig.RaplLim1Pwr             =
> MemConfig->RaplLim1Pwr;
> +    FspmUpd->FspmConfig.WarmThresholdCh0Dimm0   =
> MemConfig->WarmThresholdCh0Dimm0;
> +    FspmUpd->FspmConfig.WarmThresholdCh0Dimm1   =
> MemConfig->WarmThresholdCh0Dimm1;
> +    FspmUpd->FspmConfig.WarmThresholdCh1Dimm0   =
> MemConfig->WarmThresholdCh1Dimm0;
> +    FspmUpd->FspmConfig.WarmThresholdCh1Dimm1   =
> MemConfig->WarmThresholdCh1Dimm1;
> +    FspmUpd->FspmConfig.HotThresholdCh0Dimm0    =
> MemConfig->HotThresholdCh0Dimm0;
> +    FspmUpd->FspmConfig.HotThresholdCh0Dimm1    =
> MemConfig->HotThresholdCh0Dimm1;
> +    FspmUpd->FspmConfig.HotThresholdCh1Dimm0    =
> MemConfig->HotThresholdCh1Dimm0;
> +    FspmUpd->FspmConfig.HotThresholdCh1Dimm1    =
> MemConfig->HotThresholdCh1Dimm1;
> +    FspmUpd->FspmConfig.WarmBudgetCh0Dimm0      =
> MemConfig->WarmBudgetCh0Dimm0;
> +    FspmUpd->FspmConfig.WarmBudgetCh0Dimm1      =
> MemConfig->WarmBudgetCh0Dimm1;
> +    FspmUpd->FspmConfig.WarmBudgetCh1Dimm0      =
> MemConfig->WarmBudgetCh1Dimm0;
> +    FspmUpd->FspmConfig.WarmBudgetCh1Dimm1      =
> MemConfig->WarmBudgetCh1Dimm1;
> +    FspmUpd->FspmConfig.HotBudgetCh0Dimm0       =
> MemConfig->HotBudgetCh0Dimm0;
> +    FspmUpd->FspmConfig.HotBudgetCh0Dimm1       =
> MemConfig->HotBudgetCh0Dimm1;
> +    FspmUpd->FspmConfig.HotBudgetCh1Dimm0       =
> MemConfig->HotBudgetCh1Dimm0;
> +    FspmUpd->FspmConfig.HotBudgetCh1Dimm1       =
> MemConfig->HotBudgetCh1Dimm1;
> +    FspmUpd->FspmConfig.IdleEnergyCh0Dimm0      =
> MemConfig->IdleEnergyCh0Dimm0;
> +    FspmUpd->FspmConfig.IdleEnergyCh0Dimm1      =
> MemConfig->IdleEnergyCh0Dimm1;
> +    FspmUpd->FspmConfig.IdleEnergyCh1Dimm0      =
> MemConfig->IdleEnergyCh1Dimm0;
> +    FspmUpd->FspmConfig.IdleEnergyCh1Dimm1      =
> MemConfig->IdleEnergyCh1Dimm1;
> +    FspmUpd->FspmConfig.PdEnergyCh0Dimm0        =
> MemConfig->PdEnergyCh0Dimm0;
> +    FspmUpd->FspmConfig.PdEnergyCh0Dimm1        =
> MemConfig->PdEnergyCh0Dimm1;
> +    FspmUpd->FspmConfig.PdEnergyCh1Dimm0        =
> MemConfig->PdEnergyCh1Dimm0;
> +    FspmUpd->FspmConfig.PdEnergyCh1Dimm1        =
> MemConfig->PdEnergyCh1Dimm1;
> +    FspmUpd->FspmConfig.ActEnergyCh0Dimm0       =
> MemConfig->ActEnergyCh0Dimm0;
> +    FspmUpd->FspmConfig.ActEnergyCh0Dimm1       =
> MemConfig->ActEnergyCh0Dimm1;
> +    FspmUpd->FspmConfig.ActEnergyCh1Dimm0       =
> MemConfig->ActEnergyCh1Dimm0;
> +    FspmUpd->FspmConfig.ActEnergyCh1Dimm1       =
> MemConfig->ActEnergyCh1Dimm1;
> +    FspmUpd->FspmConfig.RdEnergyCh0Dimm0        =
> MemConfig->RdEnergyCh0Dimm0;
> +    FspmUpd->FspmConfig.RdEnergyCh0Dimm1        =
> MemConfig->RdEnergyCh0Dimm1;
> +    FspmUpd->FspmConfig.RdEnergyCh1Dimm0        =
> MemConfig->RdEnergyCh1Dimm0;
> +    FspmUpd->FspmConfig.RdEnergyCh1Dimm1        =
> MemConfig->RdEnergyCh1Dimm1;
> +    FspmUpd->FspmConfig.WrEnergyCh0Dimm0        =
> MemConfig->WrEnergyCh0Dimm0;
> +    FspmUpd->FspmConfig.WrEnergyCh0Dimm1        =
> MemConfig->WrEnergyCh0Dimm1;
> +    FspmUpd->FspmConfig.WrEnergyCh1Dimm0        =
> MemConfig->WrEnergyCh1Dimm0;
> +    FspmUpd->FspmConfig.WrEnergyCh1Dimm1        =
> MemConfig->WrEnergyCh1Dimm1;
> +    FspmUpd->FspmConfig.ThrtCkeMinTmr           =
> MemConfig->ThrtCkeMinTmr;
> +    FspmUpd->FspmConfig.CkeRankMapping          =
> MemConfig->CkeRankMapping;
> +    FspmUpd->FspmConfig.CaVrefConfig            =
> MemConfig->CaVrefConfig;
> +    FspmUpd->FspmConfig.RaplPwrFlCh1            =
> MemConfig->RaplPwrFlCh1;
> +    FspmUpd->FspmConfig.RaplPwrFlCh0            =
> MemConfig->RaplPwrFlCh0;
> +    FspmUpd->FspmConfig.EnCmdRate               =
> MemConfig->EnCmdRate;
> +    FspmUpd->FspmConfig.Refresh2X               = MemConfig->Refresh2X;
> +    FspmUpd->FspmConfig.EpgEnable               = MemConfig->EpgEnable;
> +    FspmUpd->FspmConfig.RhSolution              = MemConfig->RhSolution;
> +    FspmUpd->FspmConfig.UserThresholdEnable     =
> MemConfig->UserThresholdEnable;
> +    FspmUpd->FspmConfig.UserBudgetEnable        =
> MemConfig->UserBudgetEnable;
> +    FspmUpd->FspmConfig.TsodTcritMax            =
> MemConfig->TsodTcritMax;
> +    FspmUpd->FspmConfig.TsodEventMode           =
> MemConfig->TsodEventMode;
> +    FspmUpd->FspmConfig.TsodEventPolarity       =
> MemConfig->TsodEventPolarity;
> +    FspmUpd->FspmConfig.TsodCriticalEventOnly   =
> MemConfig->TsodCriticalEventOnly;
> +    FspmUpd->FspmConfig.TsodEventOutputControl  =
> MemConfig->TsodEventOutputControl;
> +    FspmUpd->FspmConfig.TsodAlarmwindowLockBit  =
> MemConfig->TsodAlarmwindowLockBit;
> +    FspmUpd->FspmConfig.TsodCriticaltripLockBit =
> MemConfig->TsodCriticaltripLockBit;
> +    FspmUpd->FspmConfig.TsodShutdownMode        =
> MemConfig->TsodShutdownMode;
> +    FspmUpd->FspmConfig.TsodThigMax             =
> MemConfig->TsodThigMax;
> +    FspmUpd->FspmConfig.TsodManualEnable        =
> MemConfig->TsodManualEnable;
> +    FspmUpd->FspmConfig.IsvtIoPort              = MemConfig->IsvtIoPort;
> +    FspmUpd->FspmConfig.ForceOltmOrRefresh2x    =
> MemConfig->ForceOltmOrRefresh2x;
> +    FspmUpd->FspmConfig.PwdwnIdleCounter        =
> MemConfig->PwdwnIdleCounter;
> +    FspmUpd->FspmConfig.CmdRanksTerminated      =
> MemConfig->CmdRanksTerminated;
> +    FspmUpd->FspmConfig.GdxcEnable              = MemConfig->GdxcEnable;
> +    FspmUpd->FspmConfig.RMTLoopCount            =
> MemConfig->RMTLoopCount;
> +
> +    // DDR4 Memory Timings
> +    FspmUpd->FspmTestConfig.tRRD_L = (UINT8) MemConfig->tRRD_L;
> +    FspmUpd->FspmTestConfig.tRRD_S = (UINT8) MemConfig->tRRD_S;
> +    FspmUpd->FspmTestConfig.tWTR_L = (UINT8) MemConfig->tWTR_L;
> +    FspmUpd->FspmTestConfig.tWTR_S = (UINT8) MemConfig->tWTR_S;
> +
> +    // TurnAround Timing
> +    // Read-to-Read
> +    FspmUpd->FspmTestConfig.tRd2RdSG = MemConfig->tRd2RdSG;
> +    FspmUpd->FspmTestConfig.tRd2RdDG = MemConfig->tRd2RdDG;
> +    FspmUpd->FspmTestConfig.tRd2RdDR = MemConfig->tRd2RdDR;
> +    FspmUpd->FspmTestConfig.tRd2RdDD = MemConfig->tRd2RdDD;
> +    // Write-to-Read
> +    FspmUpd->FspmTestConfig.tWr2RdSG = MemConfig->tWr2RdSG;
> +    FspmUpd->FspmTestConfig.tWr2RdDG = MemConfig->tWr2RdDG;
> +    FspmUpd->FspmTestConfig.tWr2RdDR = MemConfig->tWr2RdDR;
> +    FspmUpd->FspmTestConfig.tWr2RdDD = MemConfig->tWr2RdDD;
> +    // Write-to-Write
> +    FspmUpd->FspmTestConfig.tWr2WrSG = MemConfig->tWr2WrSG;
> +    FspmUpd->FspmTestConfig.tWr2WrDG = MemConfig->tWr2WrDG;
> +    FspmUpd->FspmTestConfig.tWr2WrDR = MemConfig->tWr2WrDR;
> +    FspmUpd->FspmTestConfig.tWr2WrDD = MemConfig->tWr2WrDD;
> +    // Read-to-Write
> +    FspmUpd->FspmTestConfig.tRd2WrSG = MemConfig->tRd2WrSG;
> +    FspmUpd->FspmTestConfig.tRd2WrDG = MemConfig->tRd2WrDG;
> +    FspmUpd->FspmTestConfig.tRd2WrDR = MemConfig->tRd2WrDR;
> +    FspmUpd->FspmTestConfig.tRd2WrDD = MemConfig->tRd2WrDD;
> +  }
> +
> +  if (MiscPeiPreMemConfig != NULL) {
> +    FspmUpd->FspmConfig.IedSize               =
> MiscPeiPreMemConfig->IedSize;
> +    FspmUpd->FspmConfig.UserBd                =
> MiscPeiPreMemConfig->UserBd;
> +    FspmUpd->FspmConfig.SgDelayAfterPwrEn     =
> MiscPeiPreMemConfig->SgDelayAfterPwrEn;
> +    FspmUpd->FspmConfig.SgDelayAfterHoldReset =
> MiscPeiPreMemConfig->SgDelayAfterHoldReset;
> +    FspmUpd->FspmConfig.MmioSize              =
> MiscPeiPreMemConfig->MmioSize;
> +    FspmUpd->FspmConfig.MmioSizeAdjustment    =
> MiscPeiPreMemConfig->MmioSizeAdjustment;
> +    FspmUpd->FspmConfig.TsegSize              =
> MiscPeiPreMemConfig->TsegSize;
> +
> +    FspmUpd->FspmTestConfig.SkipExtGfxScan           = (UINT8)
> MiscPeiPreMemConfig->SkipExtGfxScan;
> +    FspmUpd->FspmTestConfig.BdatEnable               = (UINT8)
> MiscPeiPreMemConfig->BdatEnable;
> +    FspmUpd->FspmTestConfig.BdatTestType             = (UINT8)
> MiscPeiPreMemConfig->BdatTestType;
> +    FspmUpd->FspmTestConfig.ScanExtGfxForLegacyOpRom = (UINT8)
> MiscPeiPreMemConfig->ScanExtGfxForLegacyOpRom;
> +    FspmUpd->FspmTestConfig.LockPTMregs              = (UINT8)
> MiscPeiPreMemConfig->LockPTMregs;
> +  }
> +
> +  if (Vtd != NULL) {
> +    FspmUpd->FspmConfig.X2ApicOptOut = (UINT8) Vtd->X2ApicOptOut;
> +    FspmUpd->FspmConfig.VtdBaseAddress[0] = Vtd->BaseAddress[0];
> +    FspmUpd->FspmConfig.VtdBaseAddress[1] = Vtd->BaseAddress[1];
> +    FspmUpd->FspmConfig.VtdBaseAddress[2] = Vtd->BaseAddress[2];
> +    FspmUpd->FspmTestConfig.VtdDisable = (UINT8) Vtd->VtdDisable;
> +  }
> +
> +  if (PciePeiPreMemConfig != NULL) {
> +    FspmUpd->FspmConfig.DmiGen3ProgramStaticEq = (UINT8)
> PciePeiPreMemConfig->DmiGen3ProgramStaticEq;
> +    FspmUpd->FspmConfig.Peg0Enable = (UINT8)
> PciePeiPreMemConfig->Peg0Enable;
> +    FspmUpd->FspmConfig.Peg1Enable = (UINT8)
> PciePeiPreMemConfig->Peg1Enable;
> +    FspmUpd->FspmConfig.Peg2Enable = (UINT8)
> PciePeiPreMemConfig->Peg2Enable;
> +    FspmUpd->FspmConfig.Peg3Enable = (UINT8)
> PciePeiPreMemConfig->Peg3Enable;
> +    FspmUpd->FspmConfig.Peg0MaxLinkSpeed = (UINT8)
> PciePeiPreMemConfig->Peg0MaxLinkSpeed;
> +    FspmUpd->FspmConfig.Peg1MaxLinkSpeed = (UINT8)
> PciePeiPreMemConfig->Peg1MaxLinkSpeed;
> +    FspmUpd->FspmConfig.Peg2MaxLinkSpeed = (UINT8)
> PciePeiPreMemConfig->Peg2MaxLinkSpeed;
> +    FspmUpd->FspmConfig.Peg3MaxLinkSpeed = (UINT8)
> PciePeiPreMemConfig->Peg3MaxLinkSpeed;
> +    FspmUpd->FspmConfig.Peg0MaxLinkWidth = (UINT8)
> PciePeiPreMemConfig->Peg0MaxLinkWidth;
> +    FspmUpd->FspmConfig.Peg1MaxLinkWidth = (UINT8)
> PciePeiPreMemConfig->Peg1MaxLinkWidth;
> +    FspmUpd->FspmConfig.Peg2MaxLinkWidth = (UINT8)
> PciePeiPreMemConfig->Peg2MaxLinkWidth;
> +    FspmUpd->FspmConfig.Peg3MaxLinkWidth = (UINT8)
> PciePeiPreMemConfig->Peg3MaxLinkWidth;
> +    FspmUpd->FspmConfig.Peg0PowerDownUnusedLanes = (UINT8)
> PciePeiPreMemConfig->Peg0PowerDownUnusedLanes;
> +    FspmUpd->FspmConfig.Peg1PowerDownUnusedLanes = (UINT8)
> PciePeiPreMemConfig->Peg1PowerDownUnusedLanes;
> +    FspmUpd->FspmConfig.Peg2PowerDownUnusedLanes = (UINT8)
> PciePeiPreMemConfig->Peg2PowerDownUnusedLanes;
> +    FspmUpd->FspmConfig.Peg3PowerDownUnusedLanes = (UINT8)
> PciePeiPreMemConfig->Peg3PowerDownUnusedLanes;
> +    FspmUpd->FspmConfig.InitPcieAspmAfterOprom = (UINT8)
> PciePeiPreMemConfig->InitPcieAspmAfterOprom;
> +    FspmUpd->FspmConfig.PegDisableSpreadSpectrumClocking = (UINT8)
> PciePeiPreMemConfig->PegDisableSpreadSpectrumClocking;
> +    for (Index = 0; Index < SA_DMI_MAX_LANE; Index++) {
> +      FspmUpd->FspmConfig.DmiGen3RootPortPreset[Index] =
> PciePeiPreMemConfig->DmiGen3RootPortPreset[Index];
> +      FspmUpd->FspmConfig.DmiGen3EndPointPreset[Index] =
> PciePeiPreMemConfig->DmiGen3EndPointPreset[Index];
> +      FspmUpd->FspmConfig.DmiGen3EndPointHint[Index] =
> PciePeiPreMemConfig->DmiGen3EndPointHint[Index];
> +    }
> +    for (Index = 0; Index < SA_DMI_MAX_BUNDLE; Index++) {
> +      FspmUpd->FspmConfig.DmiGen3RxCtlePeaking[Index] =
> PciePeiPreMemConfig->DmiGen3RxCtlePeaking[Index];
> +    }
> +    for (Index = 0; Index < SA_PEG_MAX_BUNDLE ; Index++) {
> +      FspmUpd->FspmConfig.PegGen3RxCtlePeaking[Index] =
> PciePeiPreMemConfig->PegGen3RxCtlePeaking[Index];
> +    }
> +    FspmUpd->FspmConfig.PegDataPtr = (UINT32)
> PciePeiPreMemConfig->PegDataPtr;
> +    CopyMem((VOID *)FspmUpd->FspmConfig.PegGpioData,
> &PciePeiPreMemConfig->PegGpioData, sizeof (PEG_GPIO_DATA));
> +    FspmUpd->FspmConfig.DmiDeEmphasis =
> PciePeiPreMemConfig->DmiDeEmphasis;
> +
> +    for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +      FspmUpd->FspmConfig.PegRootPortHPE[Index] =
> PciePeiPreMemConfig->PegRootPortHPE[Index];
> +    }
> +    FspmUpd->FspmTestConfig.DmiMaxLinkSpeed     = (UINT8)
> PciePeiPreMemConfig->DmiMaxLinkSpeed;
> +    FspmUpd->FspmTestConfig.DmiGen3EqPh2Enable  = (UINT8)
> PciePeiPreMemConfig->DmiGen3EqPh2Enable;
> +    FspmUpd->FspmTestConfig.DmiGen3EqPh3Method  = (UINT8)
> PciePeiPreMemConfig->DmiGen3EqPh3Method;
> +    FspmUpd->FspmTestConfig.Peg0Gen3EqPh2Enable = (UINT8)
> PciePeiPreMemConfig->Peg0Gen3EqPh2Enable;
> +    FspmUpd->FspmTestConfig.Peg1Gen3EqPh2Enable = (UINT8)
> PciePeiPreMemConfig->Peg1Gen3EqPh2Enable;
> +    FspmUpd->FspmTestConfig.Peg2Gen3EqPh2Enable = (UINT8)
> PciePeiPreMemConfig->Peg2Gen3EqPh2Enable;
> +    FspmUpd->FspmTestConfig.Peg3Gen3EqPh2Enable = (UINT8)
> PciePeiPreMemConfig->Peg3Gen3EqPh2Enable;
> +    FspmUpd->FspmTestConfig.Peg0Gen3EqPh3Method = (UINT8)
> PciePeiPreMemConfig->Peg0Gen3EqPh3Method;
> +    FspmUpd->FspmTestConfig.Peg1Gen3EqPh3Method = (UINT8)
> PciePeiPreMemConfig->Peg1Gen3EqPh3Method;
> +    FspmUpd->FspmTestConfig.Peg2Gen3EqPh3Method = (UINT8)
> PciePeiPreMemConfig->Peg2Gen3EqPh3Method;
> +    FspmUpd->FspmTestConfig.Peg3Gen3EqPh3Method = (UINT8)
> PciePeiPreMemConfig->Peg3Gen3EqPh3Method;
> +    FspmUpd->FspmTestConfig.PegGen3ProgramStaticEq = (UINT8)
> PciePeiPreMemConfig->PegGen3ProgramStaticEq;
> +    FspmUpd->FspmTestConfig.Gen3SwEqAlwaysAttempt = (UINT8)
> PciePeiPreMemConfig->Gen3SwEqAlwaysAttempt;
> +    FspmUpd->FspmTestConfig.Gen3SwEqNumberOfPresets = (UINT8)
> PciePeiPreMemConfig->Gen3SwEqNumberOfPresets;
> +    FspmUpd->FspmTestConfig.Gen3SwEqEnableVocTest = (UINT8)
> PciePeiPreMemConfig->Gen3SwEqEnableVocTest;
> +    FspmUpd->FspmTestConfig.PegRxCemTestingMode = (UINT8)
> PciePeiPreMemConfig->PegRxCemTestingMode;
> +    FspmUpd->FspmTestConfig.PegRxCemLoopbackLane = (UINT8)
> PciePeiPreMemConfig->PegRxCemLoopbackLane;
> +    FspmUpd->FspmTestConfig.PegGenerateBdatMarginTable = (UINT8)
> PciePeiPreMemConfig->PegGenerateBdatMarginTable;
> +    FspmUpd->FspmTestConfig.PegRxCemNonProtocolAwareness = (UINT8)
> PciePeiPreMemConfig->PegRxCemNonProtocolAwareness;
> +    FspmUpd->FspmTestConfig.PegGen3RxCtleOverride = (UINT8)
> PciePeiPreMemConfig->PegGen3RxCtleOverride;
> +    for (Index = 0; Index < SA_PEG_MAX_LANE; Index++) {
> +      FspmUpd->FspmTestConfig.PegGen3RootPortPreset[Index] =
> PciePeiPreMemConfig->PegGen3RootPortPreset[Index];
> +      FspmUpd->FspmTestConfig.PegGen3EndPointPreset[Index] =
> PciePeiPreMemConfig->PegGen3EndPointPreset[Index];
> +      FspmUpd->FspmTestConfig.PegGen3EndPointHint[Index] =
> PciePeiPreMemConfig->PegGen3EndPointHint[Index];
> +    }
> +    FspmUpd->FspmTestConfig.Gen3SwEqJitterDwellTime =
> PciePeiPreMemConfig->Gen3SwEqJitterDwellTime;
> +    FspmUpd->FspmTestConfig.Gen3SwEqJitterErrorTarget =
> PciePeiPreMemConfig->Gen3SwEqJitterErrorTarget;
> +    FspmUpd->FspmTestConfig.Gen3SwEqVocDwellTime =
> PciePeiPreMemConfig->Gen3SwEqVocDwellTime;
> +    FspmUpd->FspmTestConfig.Gen3SwEqVocErrorTarget =
> PciePeiPreMemConfig->Gen3SwEqVocErrorTarget;
> +  }
> +
> +  if (GtPreMemConfig != NULL) {
> +    FspmUpd->FspmConfig.PrimaryDisplay = (UINT8)
> GtPreMemConfig->PrimaryDisplay;
> +    FspmUpd->FspmConfig.InternalGfx = (UINT8)
> GtPreMemConfig->InternalGraphics;
> +    FspmUpd->FspmConfig.IgdDvmt50PreAlloc = (UINT8)
> GtPreMemConfig->IgdDvmt50PreAlloc;
> +    FspmUpd->FspmConfig.ApertureSize = (UINT8)
> GtPreMemConfig->ApertureSize;
> +    FspmUpd->FspmConfig.GttMmAdr = GtPreMemConfig->GttMmAdr;
> +    FspmUpd->FspmConfig.GmAdr = GtPreMemConfig->GmAdr;
> +    FspmUpd->FspmConfig.GttSize = GtPreMemConfig->GttSize;
> +    FspmUpd->FspmConfig.PsmiRegionSize = (UINT8)
> GtPreMemConfig->PsmiRegionSize;
> +    FspmUpd->FspmConfig.GtPsmiSupport =
> (UINT8)GtPreMemConfig->GtPsmiSupport;
> +    FspmUpd->FspmTestConfig.PanelPowerEnable = (UINT8)
> GtPreMemConfig->PanelPowerEnable;
> +    FspmUpd->FspmTestConfig.DeltaT12PowerCycleDelayPreMem = (UINT16)
> GtPreMemConfig->DeltaT12PowerCycleDelayPreMem;
> +  }
> +
> +  if (SgGpioData != NULL) {
> +    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie0Gpio,
> &SgGpioData->SaRtd3Pcie0Gpio, sizeof (SA_PCIE_RTD3_GPIO));
> +    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie1Gpio,
> &SgGpioData->SaRtd3Pcie1Gpio, sizeof (SA_PCIE_RTD3_GPIO));
> +    CopyMem((VOID *) FspmUpd->FspmConfig.SaRtd3Pcie2Gpio,
> &SgGpioData->SaRtd3Pcie2Gpio, sizeof (SA_PCIE_RTD3_GPIO));
> +    FspmUpd->FspmConfig.RootPortIndex = SgGpioData->RootPortIndex;
> +  }
> +
> +  if (IpuPreMemPolicy != NULL) {
> +    FspmUpd->FspmConfig.SaIpuEnable = (UINT8)
> IpuPreMemPolicy->SaIpuEnable;
> +    FspmUpd->FspmConfig.SaIpuImrConfiguration = (UINT8)
> IpuPreMemPolicy->SaIpuImrConfiguration;
> +  }
> +
> +  if (OcPreMemConfig != NULL) {
> +    FspmUpd->FspmConfig.SaOcSupport = (UINT8)
> OcPreMemConfig->OcSupport;
> +    FspmUpd->FspmConfig.RealtimeMemoryTiming = (UINT8)
> OcPreMemConfig->RealtimeMemoryTiming;
> +    FspmUpd->FspmConfig.GtVoltageMode = (UINT8)
> OcPreMemConfig->GtVoltageMode;
> +    FspmUpd->FspmConfig.GtMaxOcRatio =
> OcPreMemConfig->GtMaxOcRatio;
> +    FspmUpd->FspmConfig.GtVoltageOffset =
> OcPreMemConfig->GtVoltageOffset;
> +    FspmUpd->FspmConfig.GtVoltageOverride =
> OcPreMemConfig->GtVoltageOverride;
> +    FspmUpd->FspmConfig.GtExtraTurboVoltage =
> OcPreMemConfig->GtExtraTurboVoltage;
> +    FspmUpd->FspmConfig.SaVoltageOffset =
> OcPreMemConfig->SaVoltageOffset;
> +    FspmUpd->FspmConfig.GtusMaxOcRatio =
> OcPreMemConfig->GtusMaxOcRatio;
> +    FspmUpd->FspmConfig.GtusVoltageMode = (UINT8)
> OcPreMemConfig->GtusVoltageMode;
> +    FspmUpd->FspmConfig.GtusVoltageOffset =
> OcPreMemConfig->GtusVoltageOffset;
> +    FspmUpd->FspmConfig.GtusVoltageOverride =
> OcPreMemConfig->GtusVoltageOverride;
> +    FspmUpd->FspmConfig.GtusExtraTurboVoltage =
> OcPreMemConfig->GtusExtraTurboVoltage;
> +  }
> +
> +
> +
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs FSP SA PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSaPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  EFI_STATUS                Status;
> +  SI_POLICY_PPI             *SiPolicyPpi;
> +  SA_MISC_PEI_CONFIG        *MiscPeiConfig;
> +  GRAPHICS_PEI_CONFIG       *GtConfig;
> +  PCIE_PEI_CONFIG           *PciePeiConfig;
> +  GNA_CONFIG                *GnaConfig;
> +  UINT8                     Index;
> +  EFI_BOOT_MODE             BootMode;
> +
> +  MiscPeiConfig = NULL;
> +  GtConfig      = NULL;
> +  PciePeiConfig = NULL;
> +  GnaConfig     = NULL;
> +
> +  //
> +  // @todo This could be cleared up after FSP provides ExitBootServices
> NotifyPhase.
> +  //
> +  Status = PeiServicesGetBootMode (&BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Locate SiPolicyPpi
> +  //
> +  SiPolicyPpi = NULL;
> +  Status = PeiServicesLocatePpi(
> +             &gSiPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **)&SiPolicyPpi
> +             );
> +  if ((Status == EFI_SUCCESS) && (SiPolicyPpi != NULL)) {
> +    MiscPeiConfig = NULL;
> +    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid,
> (VOID *) &MiscPeiConfig);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    GtConfig = NULL;
> +    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid,
> (VOID *) &GtConfig);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    GnaConfig = NULL;
> +    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGnaConfigGuid, (VOID *)
> &GnaConfig);
> +    ASSERT_EFI_ERROR (Status);
> +
> +    PciePeiConfig = NULL;
> +    Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid,
> (VOID *) &PciePeiConfig);
> +    ASSERT_EFI_ERROR (Status);
> +
> +  }
> +
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Wrapper UpdatePeiSaPolicy\n"));
> +
> +
> +  if (MiscPeiConfig != NULL) {
> +    FspsUpd->FspsConfig.Device4Enable = (UINT8)
> MiscPeiConfig->Device4Enable;
> +    FspsUpd->FspsConfig.CridEnable = (UINT8) MiscPeiConfig->CridEnable;
> +    FspsUpd->FspsTestConfig.ChapDeviceEnable = (UINT8)
> MiscPeiConfig->ChapDeviceEnable;
> +    FspsUpd->FspsTestConfig.SkipPamLock = (UINT8)
> MiscPeiConfig->SkipPamLock;
> +    FspsUpd->FspsTestConfig.EdramTestMode = (UINT8)
> MiscPeiConfig->EdramTestMode;
> +  }
> +
> +  if (PciePeiConfig != NULL) {
> +    FspsUpd->FspsConfig.DmiAspm = (UINT8) PciePeiConfig->DmiAspm;
> +    FspsUpd->FspsTestConfig.DmiExtSync = (UINT8)
> PciePeiConfig->DmiExtSync;
> +    FspsUpd->FspsTestConfig.DmiIot = (UINT8) PciePeiConfig->DmiIot;
> +    for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
> +      FspsUpd->FspsConfig.PegDeEmphasis[Index] =
> PciePeiConfig->PegDeEmphasis[Index];
> +      FspsUpd->FspsConfig.PegSlotPowerLimitValue[Index] =
> PciePeiConfig->PegSlotPowerLimitValue[Index];
> +      FspsUpd->FspsConfig.PegSlotPowerLimitScale[Index] =
> PciePeiConfig->PegSlotPowerLimitScale[Index];
> +      FspsUpd->FspsConfig.PegPhysicalSlotNumber[Index] =
> PciePeiConfig->PegPhysicalSlotNumber[Index];
> +      FspsUpd->FspsTestConfig.PegMaxPayload[Index] =
> PciePeiConfig->PegMaxPayload[Index];
> +    }
> +  }
> +
> +  if (GtConfig != NULL) {
> +    FspsUpd->FspsConfig.PavpEnable = (UINT8) GtConfig->PavpEnable;
> +    FspsUpd->FspsConfig.CdClock = (UINT8) GtConfig->CdClock;
> +    FspsUpd->FspsTestConfig.RenderStandby = (UINT8)
> GtConfig->RenderStandby;
> +    FspsUpd->FspsTestConfig.PmSupport = (UINT8) GtConfig->PmSupport;
> +    FspsUpd->FspsTestConfig.CdynmaxClampEnable = (UINT8)
> GtConfig->CdynmaxClampEnable;
> +    FspsUpd->FspsTestConfig.GtFreqMax = (UINT8) GtConfig->GtFreqMax;
> +    FspsUpd->FspsTestConfig.DisableTurboGt = (UINT8)
> GtConfig->DisableTurboGt;
> +    FspsUpd->FspsConfig.SkipS3CdClockInit =
> (UINT8)GtConfig->SkipS3CdClockInit;
> +
> +    //
> +    // For FSP, FspsUpd->FspsConfig.PeiGraphicsPeimInit is always enabled as
> default.
> +    //
> +    FspsUpd->FspsConfig.PeiGraphicsPeimInit = (UINT8)
> GtConfig->PeiGraphicsPeimInit; // SA: InternalOnly: For Internal validation we
> still need to enable both Enable/Disable Cases
> +
> +    //
> +    // Update UPD: VBT & LogoPtr
> +    //
> +    if (BootMode == BOOT_ON_S3_RESUME) {
> +      FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) NULL;
> +    } else {
> +      FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32)
> GtConfig->GraphicsConfigPtr;
> +    }
> +    DEBUG(( DEBUG_INFO, "VbtPtr from GraphicsPeiConfig is 0x%x\n",
> FspsUpd->FspsConfig.GraphicsConfigPtr));
> +
> +    FspsUpd->FspsConfig.LogoPtr  = (UINT32) GtConfig->LogoPtr;
> +    FspsUpd->FspsConfig.LogoSize = GtConfig->LogoSize;
> +    DEBUG(( DEBUG_INFO, "LogoPtr from PeiFspSaPolicyInit
> GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoPtr));
> +    DEBUG(( DEBUG_INFO, "LogoSize from PeiFspSaPolicyInit
> GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoSize));
> +
> +    FspsUpd->FspsConfig.BltBufferAddress  = (UINT32)
> GtConfig->BltBufferAddress;
> +    FspsUpd->FspsConfig.BltBufferSize     = (UINT32) GtConfig->BltBufferSize;
> +
> +    //
> +    // Update DDI/DDC configuration
> +    //
> +    FspsUpd->FspsConfig.DdiPortEdp =
> GtConfig->DdiConfiguration.DdiPortEdp;
> +    FspsUpd->FspsConfig.DdiPortBHpd =
> GtConfig->DdiConfiguration.DdiPortBHpd;
> +    FspsUpd->FspsConfig.DdiPortCHpd =
> GtConfig->DdiConfiguration.DdiPortCHpd;
> +    FspsUpd->FspsConfig.DdiPortDHpd =
> GtConfig->DdiConfiguration.DdiPortDHpd;
> +    FspsUpd->FspsConfig.DdiPortFHpd =
> GtConfig->DdiConfiguration.DdiPortFHpd;
> +    FspsUpd->FspsConfig.DdiPortBDdc =
> GtConfig->DdiConfiguration.DdiPortBDdc;
> +    FspsUpd->FspsConfig.DdiPortCDdc =
> GtConfig->DdiConfiguration.DdiPortCDdc;
> +    FspsUpd->FspsConfig.DdiPortDDdc =
> GtConfig->DdiConfiguration.DdiPortDDdc;
> +    FspsUpd->FspsConfig.DdiPortFDdc =
> GtConfig->DdiConfiguration.DdiPortFDdc;
> +
> +  }
> +
> +  if (GnaConfig != NULL) {
> +    FspsUpd->FspsConfig.GnaEnable = (UINT8) GnaConfig->GnaEnable;
> +#ifdef TESTMENU_FLAG
> +#endif // TESTMENU_FLAG
> +  }
> +
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSecurityPolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSecurityPolicyInitLib.c
> new file mode 100644
> index 0000000000..80d20d74a9
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSecurityPolicyInitLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> +  Implementation of Fsp Security Policy Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Performs FSP Security PEI Policy initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSecurityPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi;
> +
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SecurityPolicy Pre-Mem
> Start\n"));
> +
> +  //
> +  // Locate SiPreMemPolicyPpi
> +  //
> +  SiPreMemPolicyPpi = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPreMemPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPreMemPolicyPpi
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Update SecurityPolicy Pre-Mem
> End\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Performs FSP Security PEI Policy post memory initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSecurityPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSiPolicyInitLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSiPolicyInitLib.c
> new file mode 100644
> index 0000000000..98658782aa
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPoli
> cyInitLib/PeiFspSiPolicyInitLib.c
> @@ -0,0 +1,95 @@
> +/** @file
> +  Implementation of Fsp SI Policy Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PeiFspPolicyInitLib.h>
> +#include <Ppi/SiPolicy.h>
> +
> +/**
> +  Performs FSP SI PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSiPolicyInitPreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                Status;
> +  SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi;
> +
> +  //
> +  // Locate SiPreMemPolicyPpi
> +  //
> +  SiPreMemPolicyPpi = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPreMemPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPreMemPolicyPpi
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Performs FSP SI PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSiPolicyInit (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  SI_POLICY_PPI                *SiPolicy;
> +  SI_CONFIG                    *SiConfig;
> +
> +  //
> +  // Locate SiPolicyPpi
> +  //
> +  SiPolicy = NULL;
> +  Status = PeiServicesLocatePpi (
> +             &gSiPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &SiPolicy
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSiConfigGuid, (VOID *)
> &SiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Update SiConfig policies
> +  //
> +  FspsUpd->FspsConfig.SiCsmFlag                = (UINT8)SiConfig->CsmFlag;
> +  FspsUpd->FspsConfig.SiSsidTablePtr           =
> (UINT32)(UINTN)SiConfig->SsidTablePtr;
> +  FspsUpd->FspsConfig.SiNumberOfSsidTableEntry =
> (UINT16)SiConfig->NumberOfSsidTableEntry;
> +  FspsUpd->FspsConfig.TraceHubMemBase          =
> SiConfig->TraceHubMemBase;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
> new file mode 100644
> index 0000000000..a341a58930
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
> @@ -0,0 +1,100 @@
> +/** @file
> +  Implementation of Fsp Misc UPD Initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PeiLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PeiServicesLib.h>
> +
> +#include <FspEas.h>
> +#include <FspmUpd.h>
> +#include <FspsUpd.h>
> +
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DebugPrintErrorLevelLib.h>
> +#include <Library/PciLib.h>
> +#include <Ppi/ReadOnlyVariable2.h>
> +#include <Guid/MemoryOverwriteControl.h>
> +#include <PchAccess.h>
> +
> +#include "PeiMiscPolicyUpdate.h"
> +
> +/**
> +  Performs FSP Misc UPD initialization.
> +
> +  @param[in,out]    FspmUpd                 Pointer to FSPM_UPD Data.
> +
> +  @retval           EFI_SUCCESS             FSP UPD Data is updated.
> +  @retval           EFI_NOT_FOUND           An instance of
> gEfiPeiReadOnlyVariable2PpiGuid
> +                                            could not be located.
> +  @retval           EFI_OUT_OF_RESOURCES    Insufficent resources to
> allocate a memory buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspMiscUpdUpdatePreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariableServices;
> +  UINTN                             VariableSize;
> +  VOID                              *MemorySavedData;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gEfiPeiReadOnlyVariable2PpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &VariableServices
> +             );
> +  if (EFI_ERROR (Status)) {
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +
> +  VariableSize = 0;
> +  MemorySavedData = NULL;
> +  Status = VariableServices->GetVariable (
> +                               VariableServices,
> +                               L"MemoryConfig",
> +                               &gFspNonVolatileStorageHobGuid,
> +                               NULL,
> +                               &VariableSize,
> +                               MemorySavedData
> +                               );
> +  if (Status == EFI_BUFFER_TOO_SMALL) {
> +    MemorySavedData = AllocatePool (VariableSize);
> +    if (MemorySavedData == NULL) {
> +      ASSERT (MemorySavedData != NULL);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    DEBUG ((DEBUG_INFO, "VariableSize is 0x%x\n", VariableSize));
> +    Status = VariableServices->GetVariable (
> +                                 VariableServices,
> +                                 L"MemoryConfig",
> +                                 &gFspNonVolatileStorageHobGuid,
> +                                 NULL,
> +                                 &VariableSize,
> +                                 MemorySavedData
> +                                 );
> +    if (Status == EFI_SUCCESS) {
> +      FspmUpd->FspmArchUpd.NvsBufferPtr = MemorySavedData;
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "Fail to retrieve Variable:\"MemoryConfig\"
> gMemoryConfigVariableGuid, Status = %r\n", Status));
> +      ASSERT_EFI_ERROR (Status);
> +    }
> +  }
> +  FspmUpd->FspmArchUpd.NvsBufferPtr = MemorySavedData;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
> new file mode 100644
> index 0000000000..5119e934a2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
> @@ -0,0 +1,124 @@
> +/** @file
> +  Provide FSP wrapper platform related function.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/FspWrapperApiLib.h>
> +#include <Library/SiliconPolicyUpdateLib.h>
> +
> +#include <FspEas.h>
> +#include <FspmUpd.h>
> +#include <FspsUpd.h>
> +
> +#include "PeiMiscPolicyUpdate.h"
> +
> +/**
> +  Performs FSP PCH PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyUpdate (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  );
> +
> +VOID
> +InternalPrintVariableData (
> +  IN UINT8   *Data8,
> +  IN UINTN   DataSize
> +  )
> +{
> +  UINTN      Index;
> +
> +  for (Index = 0; Index < DataSize; Index++) {
> +    if (Index % 0x10 == 0) {
> +      DEBUG ((DEBUG_INFO, "\n%08X:", Index));
> +    }
> +    DEBUG ((DEBUG_INFO, " %02X", *Data8++));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +/**
> +  Performs silicon pre-mem policy update.
> +
> +  The meaning of Policy is defined by silicon code.
> +  It could be the raw data, a handle, a PPI, etc.
> +
> +  The input Policy must be returned by SiliconPolicyDonePreMem().
> +
> +  1) In FSP path, the input Policy should be FspmUpd.
> +  A platform may use this API to update the FSPM UPD policy initialized
> +  by the silicon module or the default UPD data.
> +  The output of FSPM UPD data from this API is the final UPD data.
> +
> +  2) In non-FSP path, the board may use additional way to get
> +  the silicon policy data field based upon the input Policy.
> +
> +  @param[in, out] Policy       Pointer to policy.
> +
> +  @return the updated policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyUpdatePreMem (
> +  IN OUT VOID    *FspmUpd
> +  )
> +{
> +  FSPM_UPD              *FspmUpdDataPtr;
> +
> +  FspmUpdDataPtr = FspmUpd;
> +
> +  PeiFspMiscUpdUpdatePreMem (FspmUpdDataPtr);
> +  InternalPrintVariableData ((VOID *) FspmUpdDataPtr, sizeof (FSPM_UPD));
> +
> +  return FspmUpd;
> +}
> +
> +/**
> +  Performs silicon post-mem policy update.
> +
> +  The meaning of Policy is defined by silicon code.
> +  It could be the raw data, a handle, a PPI, etc.
> +
> +  The input Policy must be returned by SiliconPolicyDonePostMem().
> +
> +  1) In FSP path, the input Policy should be FspsUpd.
> +  A platform may use this API to update the FSPS UPD policy initialized
> +  by the silicon module or the default UPD data.
> +  The output of FSPS UPD data from this API is the final UPD data.
> +
> +  2) In non-FSP path, the board may use additional way to get
> +  the silicon policy data field based upon the input Policy.
> +
> +  @param[in, out] Policy       Pointer to policy.
> +
> +  @return the updated policy.
> +**/
> +VOID *
> +EFIAPI
> +SiliconPolicyUpdatePostMem (
> +  IN OUT VOID    *FspsUpd
> +  )
> +{
> +  FSPS_UPD              *FspsUpdDataPtr;
> +
> +  FspsUpdDataPtr = FspsUpd;
> +
> +  PeiFspPchPolicyUpdate (FspsUpd);
> +  InternalPrintVariableData ((VOID * )FspsUpdDataPtr, sizeof (FSPS_UPD));
> +
> +  return FspsUpd;
> +}
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiPchPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiPchPolicyUpdate.c
> new file mode 100644
> index 0000000000..455467dc25
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiPchPolicyUpdate.c
> @@ -0,0 +1,60 @@
> +/** @file
> +  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/HdaVerbTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/HobLib.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Library/PchGbeLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchHsioLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <GpioConfig.h>
> +#include <GpioPinsSklH.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PchGbeLib.h>
> +#include <PcieDeviceOverrideTable.h>
> +
> +/**
> +  Performs FSP PCH PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyUpdate (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  FspsUpd->FspsConfig.PchPcieDeviceOverrideTablePtr = (UINT32)
> mPcieDeviceTable;
> +
> +  AddPlatformVerbTables (
> +    PchHdaCodecPlatformOnboard,
> +    &(FspsUpd->FspsConfig.PchHdaVerbTableEntryNum),
> +    &(FspsUpd->FspsConfig.PchHdaVerbTablePtr)
> +    );
> +
> +DEBUG_CODE_BEGIN();
> +if ((PcdGet8 (PcdSerialIoUartDebugEnable) == 1) &&
> +      FspsUpd->FspsConfig.SerialIoDevMode[PchSerialIoIndexUart0 +
> PcdGet8 (PcdSerialIoUartNumber)] == PchSerialIoDisabled ) {
> +    FspsUpd->FspsConfig.SerialIoDevMode[PchSerialIoIndexUart0 + PcdGet8
> (PcdSerialIoUartNumber)] = PchSerialIoHidden;
> +  }
> +DEBUG_CODE_END();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
> new file mode 100644
> index 0000000000..cbb818c875
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
> @@ -0,0 +1,39 @@
> +/** @file
> +  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/HobLib.h>
> +#include <Guid/GlobalVariable.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchHsioLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <PchHsioPtssTables.h>
> +#include <Library/DebugLib.h>
> +
> +/**
> +  Performs FSP PCH PEI Policy pre mem initialization.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspPchPolicyUpdatePreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiSaPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSaPolicyUpdate.c
> new file mode 100644
> index 0000000000..2114479030
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSaPolicyUpdate.c
> @@ -0,0 +1,85 @@
> +/** @file
> +Do Platform Stage System Agent initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyUpdate.h"
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Library/HobLib.h>
> +#include <PchAccess.h>
> +#include <SaAccess.h>
> +#include <Pi/PiFirmwareFile.h>
> +#include <Pi/PiPeiCis.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/PeiLib.h>
> +
> +/**
> +  Performs FSP SA PEI Policy initialization.
> +
> +  @param[in][out]  FspsUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSaPolicyUpdate (
> +  IN OUT FSPS_UPD    *FspsUpd
> +  )
> +{
> +  VOID                            *Buffer;
> +  VOID                            *MemBuffer;
> +  UINT32                          Size;
> +
> +  DEBUG((DEBUG_INFO, "\nUpdating SA Policy in Post Mem\n"));
> +
> +    FspsUpd->FspsConfig.PeiGraphicsPeimInit = 1;
> +
> +    Size   = 0;
> +    Buffer = NULL;
> +    PeiGetSectionFromAnyFv (PcdGetPtr (PcdGraphicsVbtGuid),
> EFI_SECTION_RAW, 0, &Buffer, &Size);
> +    if (Buffer == NULL) {
> +      DEBUG((DEBUG_WARN, "Could not locate VBT\n"));
> +    } else {
> +      MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
> +      if ((MemBuffer != NULL) && (Buffer != NULL)) {
> +        CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
> +        FspsUpd->FspsConfig.GraphicsConfigPtr =
> (UINT32)(UINTN)MemBuffer;
> +      } else {
> +        DEBUG((DEBUG_WARN, "Error in locating / copying VBT.\n"));
> +        FspsUpd->FspsConfig.GraphicsConfigPtr = 0;
> +      }
> +    }
> +    DEBUG((DEBUG_INFO, "Vbt Pointer from PeiGetSectionFromFv is 0x%x\n",
> FspsUpd->FspsConfig.GraphicsConfigPtr));
> +    DEBUG((DEBUG_INFO, "Vbt Size from PeiGetSectionFromFv is 0x%x\n",
> Size));
> +
> +    Size   = 0;
> +    Buffer = NULL;
> +    PeiGetSectionFromAnyFv (&gTianoLogoGuid, EFI_SECTION_RAW, 0,
> &Buffer, &Size);
> +    if (Buffer == NULL) {
> +      DEBUG((DEBUG_WARN, "Could not locate Logo\n"));
> +    } else {
> +      MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
> +      if ((MemBuffer != NULL) && (Buffer != NULL)) {
> +        CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
> +        FspsUpd->FspsConfig.LogoPtr = (UINT32)(UINTN)MemBuffer;
> +        FspsUpd->FspsConfig.LogoSize = Size;
> +      } else {
> +        DEBUG((DEBUG_WARN, "Error in locating / copying LogoPtr.\n"));
> +        FspsUpd->FspsConfig.LogoPtr = 0;
> +        FspsUpd->FspsConfig.LogoSize = 0;
> +      }
> +    }
> +    DEBUG((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n",
> FspsUpd->FspsConfig.LogoPtr));
> +    DEBUG((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n",
> FspsUpd->FspsConfig.LogoSize));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconP
> olicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
> new file mode 100644
> index 0000000000..946182864e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSilicon
> PolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
> @@ -0,0 +1,87 @@
> +/** @file
> +Do Platform Stage System Agent initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyUpdate.h"
> +#include <CpuRegs.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Guid/MemoryOverwriteControl.h>
> +#include <Library/HobLib.h>
> +#include <PchAccess.h>
> +#include <SaAccess.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/GpioLib.h>
> +#include <GpioPinsSklH.h>
> +
> +
> +/**
> +  Performs FSP SA PEI Policy initialization in pre-memory.
> +
> +  @param[in][out]  FspmUpd             Pointer to FSP UPD Data.
> +
> +  @retval          EFI_SUCCESS         FSP UPD Data is updated.
> +  @retval          EFI_NOT_FOUND       Fail to locate required PPI.
> +  @retval          Other               FSP UPD Data update process fail.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiFspSaPolicyUpdatePreMem (
> +  IN OUT FSPM_UPD    *FspmUpd
> +  )
> +{
> +  VOID                        *Buffer;
> +
> +  //
> +  // If SpdAddressTable are not all 0, it means DIMM slots implemented and
> +  // MemorySpdPtr* already updated by reading SPD from DIMM in
> SiliconPolicyInitPreMem.
> +  //
> +  // If SpdAddressTable all 0, this is memory down design and hardcoded
> SpdData
> +  // should be applied to MemorySpdPtr*.
> +  //
> +  if ((PcdGet8 (PcdMrcSpdAddressTable0) == 0) && (PcdGet8
> (PcdMrcSpdAddressTable1) == 0)
> +      && (PcdGet8 (PcdMrcSpdAddressTable2) == 0) && (PcdGet8
> (PcdMrcSpdAddressTable3) == 0)) {
> +    DEBUG ((DEBUG_INFO, "Overriding SPD data for down memory.\n"));
> +    CopyMem (
> +      (VOID *) (UINTN) FspmUpd->FspmConfig.MemorySpdPtr00,
> +      (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData),
> +      PcdGet16 (PcdMrcSpdDataSize)
> +      );
> +    CopyMem (
> +      (VOID *) (UINTN) FspmUpd->FspmConfig.MemorySpdPtr10,
> +      (VOID *) (UINTN) PcdGet32 (PcdMrcSpdData),
> +      PcdGet16 (PcdMrcSpdDataSize)
> +      );
> +  }
> +
> +  DEBUG((DEBUG_INFO, "Updating Dq Byte Map and DQS Byte Swizzling
> Settings...\n"));
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqByteMap);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh0, Buffer, 12);
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqByteMapCh1, (UINT8*)
> Buffer + 12, 12);
> +  }
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcDqsMapCpu2Dram);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh0, Buffer,
> 8);
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.DqsMapCpu2DramCh1,
> (UINT8*) Buffer + 8, 8);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "Updating Dq Pins Interleaved,Rcomp Resistor &
> Rcomp Target Settings...\n"));
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompResistor);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompResistor, Buffer, 6);
> +  }
> +  Buffer = (VOID *) (UINTN) PcdGet32 (PcdMrcRcompTarget);
> +  if (Buffer) {
> +    CopyMem ((VOID *)FspmUpd->FspmConfig.RcompTarget, Buffer, 10);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/FspWrapperPlatformSecLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/FspWrapperPlatformSecLib.c
> new file mode 100644
> index 0000000000..a767289bc5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/FspWrapperPlatformSecLib.c
> @@ -0,0 +1,163 @@
> +/** @file
> +  Provide FSP wrapper platform sec related function.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Ppi/SecPlatformInformation.h>
> +#include <Ppi/SecPerformance.h>
> +#include <Ppi/FirmwareVolumeInfo.h>
> +#include <Ppi/TopOfTemporaryRam.h>
> +#include <Guid/FirmwareFileSystem2.h>
> +
> +#include <Library/LocalApicLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +
> +/**
> +  This interface conveys state information out of the Security (SEC) phase into
> PEI.
> +
> +  @param[in]     PeiServices               Pointer to the PEI Services Table.
> +  @param[in,out] StructureSize             Pointer to the variable describing
> size of the input buffer.
> +  @param[out]    PlatformInformationRecord Pointer to the
> EFI_SEC_PLATFORM_INFORMATION_RECORD.
> +
> +  @retval EFI_SUCCESS           The data was successfully returned.
> +  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecPlatformInformation (
> +  IN CONST EFI_PEI_SERVICES                     **PeiServices,
> +  IN OUT   UINT64                               *StructureSize,
> +     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD
> *PlatformInformationRecord
> +  );
> +
> +/**
> +  This interface conveys performance information out of the Security (SEC)
> phase into PEI.
> +
> +  This service is published by the SEC phase. The SEC phase handoff has an
> optional
> +  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> from SEC into the
> +  PEI Foundation. As such, if the platform supports collecting performance
> data in SEC,
> +  this information is encapsulated into the data structure abstracted by this
> service.
> +  This information is collected for the boot-strap processor (BSP) on IA-32.
> +
> +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> +  @param[in]  This         The pointer to this instance of the
> PEI_SEC_PERFORMANCE_PPI.
> +  @param[out] Performance  The pointer to performance data collected in
> SEC phase.
> +
> +  @retval EFI_SUCCESS  The data was successfully returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecGetPerformance (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN       PEI_SEC_PERFORMANCE_PPI   *This,
> +  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
> +  );
> +
> +PEI_SEC_PERFORMANCE_PPI  mSecPerformancePpi = {
> +  SecGetPerformance
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> +    &gTopOfTemporaryRamPpiGuid,
> +    NULL // To be patched later.
> +  },
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gPeiSecPerformancePpiGuid,
> +    &mSecPerformancePpi
> +  },
> +};
> +
> +#define LEGACY_8259_MASK_REGISTER_MASTER                  0x21
> +#define LEGACY_8259_MASK_REGISTER_SLAVE                   0xA1
> +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER  0x4D0
> +#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE   0x4D1
> +
> +/**
> +  Write to mask and edge/level triggered registers of master and slave 8259
> PICs.
> +
> +  @param[in]  Mask       low byte for master PIC mask register,
> +                         high byte for slave PIC mask register.
> +  @param[in]  EdgeLevel  low byte for master PIC edge/level triggered
> register,
> +                         high byte for slave PIC edge/level triggered register.
> +
> +**/
> +VOID
> +Interrupt8259WriteMask (
> +  IN UINT16  Mask,
> +  IN UINT16  EdgeLevel
> +  )
> +{
> +  IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, (UINT8) Mask);
> +  IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8) (Mask >> 8));
> +  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER,
> (UINT8) EdgeLevel);
> +  IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE,
> (UINT8) (EdgeLevel >> 8));
> +}
> +
> +/**
> +  A developer supplied function to perform platform specific operations.
> +
> +  It's a developer supplied function to perform any operations appropriate to
> a
> +  given platform. It's invoked just before passing control to PEI core by SEC
> +  core. Platform developer may modify the SecCoreData passed to PEI Core.
> +  It returns a platform specific PPI list that platform wishes to pass to PEI core.
> +  The Generic SEC core module will merge this list to join the final list passed
> to
> +  PEI core.
> +
> +  @param[in,out] SecCoreData           The same parameter as passing to PEI
> core. It
> +                                       could be overridden by this function.
> +
> +  @return The platform specific PPI list to be passed to PEI core or
> +          NULL if there is no need of such platform specific PPI list.
> +
> +**/
> +EFI_PEI_PPI_DESCRIPTOR *
> +EFIAPI
> +SecPlatformMain (
> +  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
> +  )
> +{
> +  EFI_PEI_PPI_DESCRIPTOR      *PpiList;
> +
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper BootFirmwareVolumeBase - 0x%x\n",
> SecCoreData->BootFirmwareVolumeBase));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper BootFirmwareVolumeSize - 0x%x\n",
> SecCoreData->BootFirmwareVolumeSize));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper TemporaryRamBase       - 0x%x\n",
> SecCoreData->TemporaryRamBase));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper TemporaryRamSize       - 0x%x\n",
> SecCoreData->TemporaryRamSize));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper PeiTemporaryRamBase    - 0x%x\n",
> SecCoreData->PeiTemporaryRamBase));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper PeiTemporaryRamSize    - 0x%x\n",
> SecCoreData->PeiTemporaryRamSize));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper StackBase              - 0x%x\n",
> SecCoreData->StackBase));
> +  DEBUG ((DEBUG_INFO, "FSP Wrapper StackSize              - 0x%x\n",
> SecCoreData->StackSize));
> +
> +  InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
> +
> +  //
> +  // Set all 8259 interrupts to edge triggered and disabled
> +  //
> +  Interrupt8259WriteMask (0xFFFF, 0x0000);
> +
> +  //
> +  // Use middle of Heap as temp buffer, it will be copied by caller.
> +  // Do not use Stack, because it will cause wrong calculation on stack by
> PeiCore
> +  //
> +  PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase +
> (UINTN)SecCoreData->PeiTemporaryRamSize/2);
> +  CopyMem (PpiList, mPeiSecPlatformPpi, sizeof(mPeiSecPlatformPpi));
> +
> +  //
> +  // Patch TopOfTemporaryRamPpi
> +  //
> +  PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase +
> SecCoreData->TemporaryRamSize);
> +
> +  return PpiList;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/PlatformInit.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/PlatformInit.c
> new file mode 100644
> index 0000000000..06ca63c19a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/PlatformInit.c
> @@ -0,0 +1,54 @@
> +/** @file
> +  Provide platform init function.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/DebugLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <Library/SecBoardInitLib.h>
> +#include <Library/TestPointCheckLib.h>
> +#include <Register/PchRegsPmc.h>
> +#include <Library/IoLib.h>
> +
> +/**
> +  Platform initialization.
> +
> +  @param[in] FspHobList   HobList produced by FSP.
> +  @param[in] StartOfRange Start of temporary RAM.
> +  @param[in] EndOfRange   End of temporary RAM.
> +**/
> +VOID
> +EFIAPI
> +PlatformInit (
> +  IN VOID                 *FspHobList,
> +  IN VOID                 *StartOfRange,
> +  IN VOID                 *EndOfRange
> +  )
> +{
> +  ///
> +  /// Halt the TCO timer as early as possible
> +  ///
> +  IoWrite16 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO1_CNT,
> B_TCO_IO_TCO1_CNT_TMR_HLT);
> +
> +  //
> +  // Platform initialization
> +  // Enable Serial port here
> +  //
> +  if (PcdGetBool(PcdSecSerialPortDebugEnable)) {
> +    SerialPortInitialize ();
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in PlatformInit\n"));
> +  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
> +  DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
> +  DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
> +
> +  BoardAfterTempRamInit ();
> +
> +  TestPointTempMemoryFunction (StartOfRange, EndOfRange);
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/SecGetPerformance.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecGetPerformance.c
> new file mode 100644
> index 0000000000..67bdd232bb
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecGetPerformance.c
> @@ -0,0 +1,90 @@
> +/** @file
> +  Sample to provide SecGetPerformance function.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Ppi/SecPerformance.h>
> +#include <Ppi/TopOfTemporaryRam.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/DebugLib.h>
> +
> +/**
> +  This interface conveys performance information out of the Security (SEC)
> phase into PEI.
> +
> +  This service is published by the SEC phase. The SEC phase handoff has an
> optional
> +  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> from SEC into the
> +  PEI Foundation. As such, if the platform supports collecting performance
> data in SEC,
> +  this information is encapsulated into the data structure abstracted by this
> service.
> +  This information is collected for the boot-strap processor (BSP) on IA-32.
> +
> +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> +  @param[in]  This         The pointer to this instance of the
> PEI_SEC_PERFORMANCE_PPI.
> +  @param[out] Performance  The pointer to performance data collected in
> SEC phase.
> +
> +  @retval EFI_SUCCESS  The data was successfully returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecGetPerformance (
> +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> +  IN       PEI_SEC_PERFORMANCE_PPI   *This,
> +  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
> +  )
> +{
> +  UINT32      Size;
> +  UINT32      Count;
> +  UINT32      TopOfTemporaryRam;
> +  UINT64      Ticker;
> +  VOID        *TopOfTemporaryRamPpi;
> +  EFI_STATUS  Status;
> +
> +  DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
> +
> +  Status = (*PeiServices)->LocatePpi (
> +                             PeiServices,
> +                             &gTopOfTemporaryRamPpiGuid,
> +                             0,
> +                             NULL,
> +                             (VOID **) &TopOfTemporaryRamPpi
> +                             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +  //
> +  // |--------------| <- TopOfTemporaryRam - BL
> +  // |   List Ptr   |
> +  // |--------------|
> +  // | BL RAM Start |
> +  // |--------------|
> +  // |  BL RAM End  |
> +  // |--------------|
> +  // |Number of BSPs|
> +  // |--------------|
> +  // |     BIST     |
> +  // |--------------|
> +  // |     ....     |
> +  // |--------------|
> +  // |  TSC[63:32]  |
> +  // |--------------|
> +  // |  TSC[31:00]  |
> +  // |--------------|
> +  //
> +  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi -
> sizeof(UINT32);
> +  TopOfTemporaryRam -= sizeof(UINT32) * 2;
> +  Count             = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof
> (UINT32));
> +  Size              = Count * sizeof (UINT32);
> +
> +  Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size -
> sizeof (UINT32) * 2);
> +  Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/SecPlatformInformation.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecPlatformInformation.c
> new file mode 100644
> index 0000000000..e05daa8784
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecPlatformInformation.c
> @@ -0,0 +1,79 @@
> +/** @file
> +  Provide SecPlatformInformation function.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Ppi/SecPlatformInformation.h>
> +#include <Ppi/TopOfTemporaryRam.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +
> +/**
> +  This interface conveys state information out of the Security (SEC) phase into
> PEI.
> +
> +  @param[in]     PeiServices               Pointer to the PEI Services Table.
> +  @param[in,out] StructureSize             Pointer to the variable describing
> size of the input buffer.
> +  @param[out]    PlatformInformationRecord Pointer to the
> EFI_SEC_PLATFORM_INFORMATION_RECORD.
> +
> +  @retval EFI_SUCCESS           The data was successfully returned.
> +  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SecPlatformInformation (
> +  IN CONST EFI_PEI_SERVICES                     **PeiServices,
> +  IN OUT   UINT64                               *StructureSize,
> +     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD
> *PlatformInformationRecord
> +  )
> +{
> +  UINT32      *Bist;
> +  UINT32      Size;
> +  UINT32      Count;
> +  UINT32      TopOfTemporaryRam;
> +  VOID        *TopOfTemporaryRamPpi;
> +  EFI_STATUS  Status;
> +
> +  DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
> +
> +  Status = (*PeiServices)->LocatePpi (
> +                             PeiServices,
> +                             &gTopOfTemporaryRamPpiGuid,
> +                             0,
> +                             NULL,
> +                             (VOID **) &TopOfTemporaryRamPpi
> +                             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // The entries of BIST information, together with the number of them,
> +  // reside in the bottom of stack, left untouched by normal stack operation.
> +  // This routine copies the BIST information to the buffer pointed by
> +  // PlatformInformationRecord for output.
> +  //
> +  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof
> (UINT32);
> +  TopOfTemporaryRam -= sizeof(UINT32) * 2;
> +  Count             = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof
> (UINT32)));
> +  Size              = Count * sizeof (IA32_HANDOFF_STATUS);
> +
> +  if ((*StructureSize) < (UINT64) Size) {
> +    *StructureSize = Size;
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +
> +  *StructureSize  = Size;
> +  Bist            = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);
> +
> +  CopyMem (PlatformInformationRecord, Bist, Size);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/SecRamInitData.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecRamInitData.c
> new file mode 100644
> index 0000000000..04f12a9438
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecRamInitData.c
> @@ -0,0 +1,37 @@
> +/** @file
> +  Provide TempRamInitParams data.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/PcdLib.h>
> +#include <FspEas.h>
> +#include "FsptCoreUpd.h"
> +
> +typedef struct {
> +  FSP_UPD_HEADER    FspUpdHeader;
> +  FSPT_CORE_UPD     FsptCoreUpd;
> +} FSPT_UPD_CORE_DATA;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA
> FsptUpdDataPtr = {
> +  {
> +    0x4450555F54505346,
> +    0x00,
> +    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +    }
> +  },
> +  {
> +    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) +
> FixedPcdGet32 (PcdFlashMicrocodeOffset)),
> +    ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) -
> FixedPcdGet32 (PcdFlashMicrocodeOffset)),
> +    0,          // Set CodeRegionBase as 0, so that caching will be
> 4GB-(CodeRegionSize > LLCSize ? LLCSize : CodeRegionSize) will be used.
> +    FixedPcdGet32 (PcdFlashCodeCacheSize),
> +    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +    }
> +  }
> +};
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/SecTempRamDone.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecTempRamDone.c
> new file mode 100644
> index 0000000000..6d65d7d23f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/SecTempRamDone.c
> @@ -0,0 +1,48 @@
> +/** @file
> +  Provide SecTemporaryRamDone function.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Ppi/TemporaryRamDone.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/FspWrapperPlatformLib.h>
> +#include <Library/FspWrapperApiLib.h>
> +#include <Library/BoardInitLib.h>
> +
> +/**
> +This interface disables temporary memory in SEC Phase.
> +**/
> +VOID
> +EFIAPI
> +SecPlatformDisableTemporaryMemory (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                Status;
> +  VOID                      *TempRamExitParam;
> +
> +  DEBUG((DEBUG_INFO, "SecPlatformDisableTemporaryMemory enter\n"));
> +
> +  Status = BoardInitBeforeTempRamExit ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  TempRamExitParam = UpdateTempRamExitParam ();
> +  Status = CallTempRamExit (TempRamExitParam);
> +  DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = BoardInitAfterTempRamExit ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return ;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.c
> new file mode 100644
> index 0000000000..7bdb3943e5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.c
> @@ -0,0 +1,48 @@
> +/** @file
> +  ACPI Timer implements one instance of Timer Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Library/TimerLib.h>
> +#include <Library/BaseLib.h>
> +
> +/**
> +  Calculate TSC frequency.
> +
> +  The TSC counting frequency is determined by comparing how far it counts
> +  during a 101.4 us period as determined by the ACPI timer.
> +  The ACPI timer is used because it counts at a known frequency.
> +  The TSC is sampled, followed by waiting 363 counts of the ACPI timer,
> +  or 101.4 us. The TSC is then sampled again. The difference multiplied by
> +  9861 is the TSC frequency. There will be a small error because of the
> +  overhead of reading the ACPI timer. An attempt is made to determine and
> +  compensate for this error.
> +
> +  @return The number of TSC counts per second.
> +
> +**/
> +UINT64
> +InternalCalculateTscFrequency (
> +  VOID
> +  );
> +
> +/**
> +  Internal function to retrieves the 64-bit frequency in Hz.
> +
> +  Internal function to retrieves the 64-bit frequency in Hz.
> +
> +  @return The frequency in Hz.
> +
> +**/
> +UINT64
> +InternalGetPerformanceCounterFrequency (
> +  VOID
> +  )
> +{
> +  return InternalCalculateTscFrequency ();
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/
> BaseGpioExpanderLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/
> BaseGpioExpanderLib.c
> new file mode 100644
> index 0000000000..8498952888
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/
> BaseGpioExpanderLib.c
> @@ -0,0 +1,310 @@
> +/** @file
> +  Support for IO expander TCA6424.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/GpioExpanderLib.h>
> +#include <Library/I2cAccessLib.h>
> +
> +//
> +// Addresses of registers inside expander
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mInputRegister[3]    =
> {0x0,0x1,0x2};
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mOutputRegister[3]   =
> {0x4,0x5,0x6};
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mConfigRegister[3]   =
> {0xC,0xD,0xE};
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mPolarityRegister[3] =
> {0x8,0x9,0xA};
> +
> +#define PCH_SERIAL_IO_I2C4                 4
> +#define TCA6424_I2C_ADDRESS 0x22
> +#define PINS_PER_REGISTER                  8
> +#define GPIO_EXP_PIN_DIRECTION_OUT         1
> +#define GPIO_EXP_PIN_DIRECTION_IN          0
> +#define GPIO_EXP_PIN_POLARITY_NORMAL       0
> +#define GPIO_EXP_PIN_POLARITY_INVERTED     1
> +#define GPIO_EXP_SET_OUTPUT                0
> +#define GPIO_EXP_SET_DIR                   1
> +#define GPIO_EXP_GET_INPUT                 2
> +#define GPIO_EXP_SET_POLARITY              3
> +#define AUTO_INCREMENT 0x80
> +
> +/**
> +  Returns the Controller on which GPIO expander is present.
> +
> +  This function returns the Controller value
> +
> +  @param[out] Controller              Pointer to a Controller value on
> +                                      which I2C expander is configured.
> +
> +  @retval     EFI_SUCCESS              non.
> +**/
> +EFI_STATUS
> +GpioExpGetController (
> +  OUT UINT8 *Controller
> +  )
> +{
> +  *Controller = PCH_SERIAL_IO_I2C4;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Returns the data from register value giving in the input.
> +
> +  This function is to get the data from the Expander
> +  Registers by following the I2C Protocol communication
> +
> +
> +  @param[in]  Bar0       Bar address of the SerialIo Controller
> +  @param[in]  Address    Expander Value with in the Contoller
> +  @param[in]  Register   Address of Input/Output/Configure/Polarity
> +                         registers with in the Expander
> +
> +  @retval     UINT8      Value returned from the register
> +**/
> +UINT8
> +GpioExpGetRegister (
> +  IN UINTN Bar0,
> +  IN UINT8 Address,
> +  IN UINT8 Register
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT8 WriBuf[1];
> +  UINT8 ReBuf[1] = {0};
> +
> +  WriBuf[0] = Register;
> +  Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 1, WriBuf, 1,
> ReBuf, WAIT_1_SECOND);
> +
> +  return ReBuf[0];
> +}
> +/**
> +  Set the input register to a give value mentioned in the function.
> +
> +  This function is to Programm the data value to the Expander
> +  Register by following the I2C Protocol communication.
> +
> +  @param[in]  Bar0       Bar address of the SerialIo Controller
> +  @param[in]  Address    Expander Value with in the Contoller
> +  @param[in]  Register   Address of Input/Output/Configure/Polarity
> +                         registers with in the Expander
> +  @param[in]  Value      Value to set in the mentioned the register
> +**/
> +VOID
> +GpioExpSetRegister (
> +  IN UINTN Bar0,
> +  IN UINT8 Address,
> +  IN UINT8 Register,
> +  IN UINT8 Value
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT8 WriBuf[2];
> +
> +  WriBuf[0] = Register;
> +  WriBuf[1] = Value;
> +  Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 2, WriBuf, 0,
> NULL, WAIT_1_SECOND);
> +
> +}
> +/**
> +  Set the input register to a give value mentioned in the function.
> +
> +  This function is to update the status of the Gpio Expander
> +  pin based on the input Operation value of the caller.This
> +  function calculates the exact address of the register with
> +  the help of the Register Bank
> +
> +  @param[in]  Controller  SerialIo Controller value
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +  @param[in]  Value       none
> +  @param[in]  Operation   Type of operation (Setoutput/Setdirection
> +                          /Getinput/Setpolarity)
> +  @retval     UINT8       Final Value returned from the register
> +**/
> +UINT8
> +GpioExpDecodeRegAccess (
> +  IN UINT8 Controller,
> +  IN UINT8 Expander,
> +  IN UINT8 Pin,
> +  IN UINT8 Value,
> +  IN UINT8 Operation
> +  )
> +{
> +  UINT8* RegisterBank;
> +  UINT8 OldValue;
> +  UINT8 NewValue;
> +  UINT8 RegisterAddress;
> +  UINT8 PinNumber;
> +  UINT8 ReturnValue = 0;
> +
> +  DEBUG ((DEBUG_INFO, "GpioExpDecodeRegAccess() %x:%x:%x:%x:%x\n",
> Controller, Expander, Pin, Value, Operation));
> +  ASSERT(Controller<6);
> +  ASSERT(Expander<2);
> +  ASSERT(Pin<24);
> +  ASSERT(Value<2);
> +  ASSERT(Operation<4);
> +  //
> +  // Find the register Address value based on the OPeration
> +  //
> +  switch(Operation) {
> +    case GPIO_EXP_SET_OUTPUT:
> +      RegisterBank = mOutputRegister;
> +      break;
> +    case GPIO_EXP_SET_DIR:
> +      RegisterBank = mConfigRegister;
> +      break;
> +    case GPIO_EXP_GET_INPUT:
> +      RegisterBank = mInputRegister;
> +      break;
> +    case GPIO_EXP_SET_POLARITY:
> +      RegisterBank = mPolarityRegister;
> +      break;
> +    default:
> +      ASSERT(FALSE);
> +      return 0;
> +    }
> +  //
> +  // Each bit of register represents each Pin
> +  // calaulate the register address and Pinnumber(offset with in register)
> +  //
> +  if (Pin >= 24) {
> +    //
> +    // Avoid out-of-bound usage of RegisterBank
> +    //
> +    return 0;
> +  }
> +
> +  RegisterAddress = RegisterBank[(Pin/PINS_PER_REGISTER)];
> +  PinNumber = Pin%PINS_PER_REGISTER;
> +
> +  OldValue = GpioExpGetRegister(FindSerialIoBar(Controller, 0), Expander,
> RegisterAddress);
> +  //
> +  // If it to get the data ,just returned otherwise mark the input value and
> write the register
> +  //
> +  if (Operation == GPIO_EXP_GET_INPUT) {
> +    ReturnValue = 0x1 & (OldValue>>PinNumber);
> +  } else {
> +    NewValue = OldValue;
> +    NewValue &= ~(BIT0<<PinNumber);
> +    NewValue |= (Value<<PinNumber);
> +    if(NewValue!=OldValue) {
> +      GpioExpSetRegister(FindSerialIoBar(Controller, 0), Expander,
> RegisterAddress, NewValue);
> +    }
> +  }
> +  return ReturnValue;
> +}
> +/**
> +  Set the Output value for the given Expander Gpio pin.
> +
> +  This function is to Set the Output value for the GPIO
> +  Pin within the giving Expander.
> +
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +  @param[in]  Value       none
> +
> +**/
> +VOID
> +GpioExpSetOutput (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin,
> +  IN UINT8 Value
> +  )
> +{
> +  UINT8 Controller;
> +  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
> +
> GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_OUT
> PUT);
> +  }
> +}
> +/**
> +  Set the Direction value for the given Expander Gpio pin.
> +
> +  This function is to Set the direction value for the GPIO
> +  Pin within the giving Expander.
> +
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +  @param[in]  Value       none
> +**/
> +VOID
> +GpioExpSetDirection (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin,
> +  IN UINT8 Value
> +  )
> +{
> +
> +  UINT8 Controller;
> +  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
> +
> GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_DIR)
> ;
> +  }
> +}
> +
> +
> +/**
> +  Get the input value for the given Expander Gpio pin.
> +
> +  This function is to get the input value for the GPIO
> +  Pin within the giving Expander.
> +
> +  @param[in]  Expander    Expander Value with in the Contoller
> +  @param[in]  Pin         Pin with in the Expnader Value
> +
> +  @retval     UINT8       Final Value returned from the register
> +**/
> +UINT8
> +GpioExpGetInput (
> +  IN UINT8 Expander,
> +  IN UINT8 Pin
> +  )
> +{
> +  UINT8 Controller;
> +  if(!EFI_ERROR(GpioExpGetController(&Controller))) {
> +    return
> GpioExpDecodeRegAccess(Controller,Expander,Pin,0,GPIO_EXP_GET_INPUT);
> +  }
> +  return 0;
> +}
> +
> +/**
> +  Configures all registers of a single IO Expander in one go.
> +
> +  @param[in]  Expander    Expander number (0/1)
> +  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc.
> 0=output, 1=input
> +  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0,
> etc. 0=normal, 1=inversion
> +  @param[in]  Output      Bit-encoded output state, ignores polarity, only
> applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
> +
> +**/
> +VOID
> +GpioExpBulkConfig (
> +  IN UINT8  Expander,
> +  IN UINT32 Direction,
> +  IN UINT32 Polarity,
> +  IN UINT32 Output
> +  )
> +{
> +  UINT8 WriteBuf[4];
> +  UINT8 Controller;
> +
> +  GpioExpGetController(&Controller);
> +
> +  WriteBuf[0] = mOutputRegister[0] + AUTO_INCREMENT;
> +  WriteBuf[1] = Output & 0xFF;
> +  WriteBuf[2] = (Output>>8) & 0xFF;
> +  WriteBuf[3] = (Output>>16) & 0xFF;
> +  I2cWriteRead( FindSerialIoBar(Controller,0),
> TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
> +  WriteBuf[0] = mPolarityRegister[0] + AUTO_INCREMENT;
> +  WriteBuf[1] = Polarity & 0xFF;
> +  WriteBuf[2] = (Polarity>>8) & 0xFF;
> +  WriteBuf[3] = (Polarity>>16) & 0xFF;
> +  I2cWriteRead( FindSerialIoBar(Controller,0),
> TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
> +  WriteBuf[0] = mConfigRegister[0] + AUTO_INCREMENT;
> +  WriteBuf[1] = Direction & 0xFF;
> +  WriteBuf[2] = (Direction>>8) & 0xFF;
> +  WriteBuf[3] = (Direction>>16) & 0xFF;
> +  I2cWriteRead( FindSerialIoBar(Controller,0),
> TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
> +
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pei
> HdaVerbTableLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pe
> iHdaVerbTableLib.c
> new file mode 100644
> index 0000000000..b8afd791f0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/Pe
> iHdaVerbTableLib.c
> @@ -0,0 +1,132 @@
> +/** @file
> +  This file is SampleCode of the library for Intel HD Audio Verb Table
> configuration.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <ConfigBlock.h>
> +#include <PlatformBoardId.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HdaVerbTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include "PchHdaVerbTables.h"
> +
> +/**
> +  Add verb table helper function.
> +  This function calculates verbtable number and shows verb table
> information.
> +
> +  @param[in,out] VerbTableEntryNum      Input current VerbTable number
> and output the number after adding new table
> +  @param[in,out] VerbTableArray         Pointer to array of VerbTable
> +  @param[in]     VerbTable              VerbTable which is going to add into
> array
> +**/
> +STATIC
> +VOID
> +InternalAddVerbTable (
> +  IN OUT  UINT8                   *VerbTableEntryNum,
> +  IN OUT  UINT32                  *VerbTableArray,
> +  IN      HDAUDIO_VERB_TABLE      *VerbTable
> +  )
> +{
> +  if (VerbTable == NULL) {
> +    DEBUG ((DEBUG_INFO, "InternalAddVerbTable wrong input: VerbTable ==
> NULL\n"));
> +    return;
> +  }
> +
> +  VerbTableArray[*VerbTableEntryNum] = (UINT32) VerbTable;
> +  *VerbTableEntryNum += 1;
> +
> +  DEBUG ((DEBUG_INFO,
> +    "HDA: Add verb table for vendor = 0x%04X devId = 0x%04X (size = %d
> DWords)\n",
> +    VerbTable->Header.VendorId,
> +    VerbTable->Header.DeviceId,
> +    VerbTable->Header.DataDwords)
> +    );
> +}
> +
> +/**
> +  Add verb table function.
> +  This function update the verb table number and verb table ptr of policy.
> +
> +  @param[in]  HdAudioConfig            HD Audio config block
> +  @param[out] VerbTableEntryNum        Number of verb table entries
> +  @param[out] HdaVerbTablePtr          Pointer to the verb table
> +**/
> +VOID
> +AddPlatformVerbTables (
> +  IN   UINT8              CodecType,
> +  OUT  UINT8              *VerbTableEntryNum,
> +  OUT  UINT32             *HdaVerbTablePtr
> +  )
> +{
> +  UINT8                   VerbTableEntries;
> +  UINT32                  VerbTableArray[6];
> +  UINT32                  *VerbTablePtr;
> +
> +  VerbTableEntries = 0;
> +
> +  InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *) (UINTN)
> PcdGet32 (PcdDisplayAudioHdaVerbTable));
> +
> +  if (CodecType == PchHdaCodecPlatformOnboard) {
> +    DEBUG ((DEBUG_INFO, "HDA Policy: Onboard codec selected\n"));
> +    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *)
> (UINTN) PcdGet32 (PcdHdaVerbTable));
> +    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *)
> (UINTN) PcdGet32 (PcdHdaVerbTable2));
> +  } else {
> +    DEBUG ((DEBUG_INFO, "HDA Policy: External codec kit selected\n"));
> +    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *)
> (UINTN) PcdGet32 (PcdCommonHdaVerbTable1));
> +    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *)
> (UINTN) PcdGet32 (PcdCommonHdaVerbTable2));
> +    InternalAddVerbTable (&VerbTableEntries, VerbTableArray, (VOID *)
> (UINTN) PcdGet32 (PcdCommonHdaVerbTable3));
> +  }
> +
> +  *VerbTableEntryNum = VerbTableEntries;
> +
> +  VerbTablePtr = (UINT32 *) AllocateZeroPool (sizeof (UINT32) *
> VerbTableEntries);
> +  CopyMem (VerbTablePtr, VerbTableArray, sizeof (UINT32) *
> VerbTableEntries);
> +  *HdaVerbTablePtr = (UINT32) VerbTablePtr;
> +}
> +
> +/**
> +  HDA VerbTable init function for PEI post memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +HdaVerbTableInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  HDAUDIO_VERB_TABLE *VerbTable;
> +  HDAUDIO_VERB_TABLE *VerbTable2;
> +
> +  VerbTable = NULL;
> +  VerbTable2 = NULL;
> +
> +  switch (BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +      VerbTable = &WhlHdaVerbTableAlc700;
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "HDA: Init default verb tables (Realtek ALC700
> and ALC701)\n"));
> +      VerbTable = &HdaVerbTableAlc700;
> +      VerbTable2 = &HdaVerbTableAlc701;
> +      break;
> +  }
> +
> +  PcdSet32S (PcdHdaVerbTable, (UINT32) VerbTable);
> +  PcdSet32S (PcdHdaVerbTable2, (UINT32) VerbTable2);
> +  PcdSet32S (PcdDisplayAudioHdaVerbTable, (UINT32)
> &HdaVerbTableDisplayAudio);
> +
> +  // Codecs - Realtek ALC700, ALC701, ALC274 (external - connected via HDA
> header)
> +  PcdSet32S (PcdCommonHdaVerbTable1, (UINT32) &HdaVerbTableAlc700);
> +  PcdSet32S (PcdCommonHdaVerbTable2, (UINT32) &HdaVerbTableAlc701);
> +  PcdSet32S (PcdCommonHdaVerbTable3, (UINT32) &HdaVerbTableAlc274);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cA
> ccessLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cA
> ccessLib.c
> new file mode 100644
> index 0000000000..70f531daca
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cA
> ccessLib.c
> @@ -0,0 +1,115 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/I2cAccessLib.h>
> +
> +EFI_STATUS
> +I2cWriteRead (
> +  IN UINTN  MmioBase,
> +  IN UINT8  SlaveAddress,
> +  IN UINT8  WriteLength,
> +  IN UINT8  *WriteBuffer,
> +  IN UINT8  ReadLength,
> +  IN UINT8  *ReadBuffer,
> +  IN UINT64  TimeBudget
> +  //TODO: add Speed parameter
> +  )
> +{
> +  UINT8 ReadsNeeded = ReadLength;
> +  UINT64 CutOffTime;
> +
> +  if ((WriteLength == 0 && ReadLength == 0) ||
> +      (WriteLength != 0 && WriteBuffer == NULL) ||
> +      (ReadLength != 0 && ReadBuffer == NULL) ) {
> +    DEBUG ((DEBUG_ERROR, "I2cWR Invalid Parameters\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Sanity checks to verify the I2C controller is alive
> +  // Conveniently, ICON register's values of 0 or FFFFFFFF indicate
> +  // I2c controller is out-of-order: either disabled, in D3 or in reset.
> +  //
> +  if (MmioRead32(MmioBase+R_IC_CON) == 0xFFFFFFFF ||
> MmioRead32(MmioBase+R_IC_CON) == 0x0) {
> +    DEBUG ((DEBUG_ERROR, "I2cWR Device Error\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  MmioWrite32(MmioBase+R_IC_ENABLE, 0x0);
> +  MmioRead32(MmioBase+0x40);
> +  MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
> +  MmioWrite32(MmioBase+R_IC_SDA_HOLD, 0x001C001C);
> +  //
> +  // Set I2C Bus Speed at 400 kHz for GPIO Expander
> +  //
> +  MmioWrite32(MmioBase + R_IC_FS_SCL_HCNT, 128);
> +  MmioWrite32(MmioBase + R_IC_FS_SCL_LCNT, 160);
> +  MmioWrite32(MmioBase + R_IC_TAR, SlaveAddress);
> +  MmioWrite32(MmioBase + R_IC_CON, B_IC_MASTER_MODE |
> V_IC_SPEED_FAST | B_IC_RESTART_EN | B_IC_SLAVE_DISABLE );
> +  MmioWrite32(MmioBase+R_IC_ENABLE, 0x1);
> +  CutOffTime = AsmReadTsc() + TimeBudget;
> +
> +  while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==0 ) {
> +    if (AsmReadTsc() > CutOffTime) {
> +      DEBUG ((DEBUG_ERROR, "I2cWR timeout\n"));
> +      return EFI_TIMEOUT;
> +    }
> +  }
> +
> +  while(1) {
> +    if(MmioRead32(MmioBase+R_IC_INTR_STAT) & B_IC_INTR_TX_ABRT) {
> +      DEBUG ((DEBUG_ERROR, "I2cWR Transfer aborted, reason =
> 0x%08x\n",MmioRead32(MmioBase+R_IC_TX_ABRT_SOURCE)));
> +      MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
> +      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
> +      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
> +      return EFI_DEVICE_ERROR;
> +    }
> +    if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_TFNF) {
> +      if (WriteLength > 1) {
> +        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
> +        WriteBuffer++;
> +        WriteLength--;
> +      } else if (WriteLength==1 && ReadLength != 0) {
> +        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
> +        WriteBuffer++;
> +        WriteLength--;
> +      } else if (WriteLength==1 && ReadLength == 0) {
> +        MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer |
> B_IC_CMD_STOP);
> +        WriteBuffer++;
> +        WriteLength--;
> +      } else if (ReadLength > 1) {
> +        MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ);
> +        ReadLength--;
> +      } else if (ReadLength == 1) {
> +        MmioWrite32(MmioBase+R_IC_DATA_CMD,
> B_IC_CMD_READ|B_IC_CMD_STOP);
> +        ReadLength--;
> +      }
> +    }
> +
> +    if (ReadsNeeded) {
> +      if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_RFNE) {
> +        *ReadBuffer = (UINT8)MmioRead32(MmioBase+R_IC_DATA_CMD);
> +        ReadBuffer++;
> +        ReadsNeeded--;
> +      }
> +    }
> +    if (WriteLength==0 && ReadsNeeded==0
> && !(MmioRead32(MmioBase+R_IC_STATUS)&B_IC_STATUS_ACTIVITY)) {
> +      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
> +      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
> +      DEBUG ((DEBUG_INFO, "I2cWR success\n"));
> +      return EFI_SUCCESS;
> +    }
> +    if (AsmReadTsc() > CutOffTime) {
> +      MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
> +      while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
> +      DEBUG ((DEBUG_ERROR, "I2cWR wrong ENST value\n"));
> +      return EFI_TIMEOUT;
> +    }
> +
> +  }
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeCpuPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeCpuPolicyUpdate.c
> new file mode 100644
> index 0000000000..7b9a32b3f5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeCpuPolicyUpdate.c
> @@ -0,0 +1,88 @@
> +/** @file
> +  This file is the library for CPU DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DxeCpuPolicyUpdateLib.h>
> +
> +/**
> +  This function prints the CPU DXE phase policy.
> +
> +  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
> +**/
> +VOID
> +CpuDxePrintPolicyProtocol (
> +  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
> +  )
> +{
> +  DEBUG_CODE_BEGIN ();
> +  DEBUG ((DEBUG_INFO, "\n------------------------ CPU Policy (DXE) print BEGIN
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, "Revision : %x\n", DxeCpuPolicy->Revision));
> +  ASSERT (DxeCpuPolicy->Revision ==
> DXE_CPU_POLICY_PROTOCOL_REVISION);
> +  DEBUG ((DEBUG_INFO, "\n------------------------ CPU_DXE_CONFIG
> -----------------\n"));
> +  DEBUG ((DEBUG_INFO, "EnableDts : %x\n", DxeCpuPolicy->EnableDts));
> +  DEBUG ((DEBUG_INFO, "\n------------------------ CPU Policy (DXE) print END
> -----------------\n"));
> +  DEBUG_CODE_END ();
> +}
> +
> +/**
> +  Get data for CPU policy from setup options.
> +
> +  @param[in] DxeCpuPolicy              The pointer to get CPU Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS                  Operation success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxeSiCpuPolicy (
> +  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol
> instance
> +
> +  @retval EFI_SUCCESS                   The policy is installed.
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuInstallPolicyProtocol (
> +  IN  EFI_HANDLE                  ImageHandle,
> +  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
> +  )
> +{
> +  EFI_STATUS            Status;
> +
> +  ///
> +  /// Print CPU DXE Policy
> +  ///
> +  CpuDxePrintPolicyProtocol(DxeCpuPolicy);
> +
> +  ///
> +  /// Install the DXE_CPU_POLICY_PROTOCOL interface
> +  ///
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gDxeCpuPolicyProtocolGuid,
> +                  DxeCpuPolicy,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeMePolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeMePolicyUpdate.c
> new file mode 100644
> index 0000000000..863df3328c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeMePolicyUpdate.c
> @@ -0,0 +1,105 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "DxeMePolicyUpdate.h"
> +
> +//
> +// Record version
> +//
> +#define RECORD_REVISION_1              0x01
> +#define MAX_FW_UPDATE_BIOS_SELECTIONS  2
> +
> +//
> +// Function implementations executed during policy initialization phase
> +//
> +
> +/**
> +  Update the ME Policy Library
> +
> +  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS                   Initialization complete.
> +  @retval 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
> +UpdateDxeMePolicy (
> +  IN OUT  ME_POLICY_PROTOCOL            *DxeMePolicy
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_EVENT               EndOfDxeEvent;
> +
> +  DEBUG ((DEBUG_INFO, "UpdateDxeMePolicy\n"));
> +  UpdateMePolicyFromSetup (DxeMePolicy);
> +  UpdateMePolicyFromMeSetup (DxeMePolicy);
> +
> +  //
> +  // Register End of DXE event
> +  //
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  UpdateMeSetupCallback,
> +                  NULL,
> +                  &gEfiEndOfDxeEventGroupGuid,
> +                  &EndOfDxeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> +/**
> +  Update ME Policy while MePlatformProtocol is installed.
> +
> +  @param[in] MePolicyInstance     Instance of ME Policy Protocol
> +
> +**/
> +VOID
> +UpdateMePolicyFromMeSetup (
> +  IN ME_POLICY_PROTOCOL           *MePolicyInstance
> +  )
> +{
> +
> +}
> +
> +/**
> +  Update ME Policy if Setup variable exists.
> +
> +  @param[in, out] MePolicyInstance     Instance of ME Policy Protocol
> +
> +**/
> +VOID
> +UpdateMePolicyFromSetup (
> +  IN OUT ME_POLICY_PROTOCOL     *MePolicyInstance
> +  )
> +{
> +
> +}
> +
> +/**
> +  Functions performs HECI exchange with FW to update MePolicy settings.
> +
> +  @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
> +UpdateMeSetupCallback (
> +  IN  EFI_EVENT                   Event,
> +  IN  VOID                        *Context
> +  )
> +{
> +  gBS->CloseEvent (Event);
> +
> +  return;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxePchPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxePchPolicyUpdate.c
> new file mode 100644
> index 0000000000..7945986aaa
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxePchPolicyUpdate.c
> @@ -0,0 +1,39 @@
> +/** @file
> +  This file is the library for PCH DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiDxe.h>
> +#include <PchAccess.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/PchPolicy.h>
> +#include <ConfigBlock/HdAudioConfig.h>
> +
> +/**
> +  Get data for PCH policy from setup options.
> +
> +  @param[in] PchPolicy                 The pointer to get PCH Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS                  Operation success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxePchPolicy (
> +  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
> +  )
> +{
> +  EFI_STATUS              Status;
> +  PCH_HDAUDIO_DXE_CONFIG  *HdAudioDxeConfig;
> +
> +  Status = GetConfigBlock ((VOID *)PchPolicy, &gHdAudioDxeConfigGuid,
> (VOID *)&HdAudioDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeSaPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeSaPolicyUpdate.c
> new file mode 100644
> index 0000000000..af4c76bcd0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdate
> Lib/DxeSaPolicyUpdate.c
> @@ -0,0 +1,57 @@
> +/** @file
> +  This file is the library for SA DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <DxeSaPolicyUpdate.h>
> +
> +/**
> +  Get data for platform policy from setup options.
> +
> +  @param[in] SaPolicy                  The pointer to get SA Policy protocol
> instance
> +
> +  @retval EFI_SUCCESS                  Operation success.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxeSaPolicy (
> +  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
> +  )
> +{
> +  EFI_STATUS                Status;
> +  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
> +  PCIE_DXE_CONFIG           *PcieDxeConfig;
> +  MISC_DXE_CONFIG           *MiscDxeConfig;
> +  MEMORY_DXE_CONFIG         *MemoryDxeConfig;
> +
> +  GraphicsDxeConfig = NULL;
> +  PcieDxeConfig = NULL;
> +  MiscDxeConfig = NULL;
> +  MemoryDxeConfig = NULL;
> +  //
> +  // Get requisite IP Config Blocks which needs to be used here
> +  //
> +  Status = GetConfigBlock ((VOID *)SaPolicy, &gGraphicsDxeConfigGuid, (VOID
> *)&GraphicsDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SaPolicy, &gMiscDxeConfigGuid, (VOID
> *)&MiscDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SaPolicy, &gPcieDxeConfigGuid, (VOID
> *)&PcieDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *)SaPolicy, &gMemoryDxeConfigGuid, (VOID
> *)&MemoryDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  PcieDxeConfig->PegAspmL0s[0] = 3;
> +  PcieDxeConfig->PegAspmL0s[1] = 3;
> +  PcieDxeConfig->PegAspmL0s[2] = 3;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInit.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInit.c
> new file mode 100644
> index 0000000000..93be38a832
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInit.c
> @@ -0,0 +1,65 @@
> +/** @file
> +  This file is SampleCode for Intel PEI Platform Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyInit.h"
> +
> +/**
> +  Initialize Intel PEI Platform Policy
> +
> +  @param[in] PeiServices            General purpose services available to every
> PEIM.
> +  @param[in] FirmwareConfiguration  It uses to skip specific policy init that
> depends
> +                                    on the 'FirmwareConfiguration' varaible.
> +**/
> +VOID
> +EFIAPI
> +PeiPolicyInit (
> +  IN UINT8                     FirmwareConfiguration
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  SI_POLICY_PPI                *SiPolicyPpi;
> +
> +  //
> +  // Call SiCreateConfigBlocks to initialize Silicon Policy structure
> +  // and get all Intel default policy settings.
> +  //
> +  Status = SiCreateConfigBlocks (&SiPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR(Status)) {
> +    return;
> +  }
> +
> +  if (PcdGetBool (PcdDumpDefaultSiliconPolicy)) {
> +    DEBUG ((DEBUG_INFO, "Dump Default Silicon Policy...\n"));
> +    DumpSiPolicy (SiPolicyPpi);
> +  }
> +
> +  //
> +  // Update policy by board configuration
> +  //
> +  UpdatePeiSiPolicyBoardConfig (SiPolicyPpi);
> +  UpdatePeiPchPolicyBoardConfig (SiPolicyPpi);
> +  UpdatePeiSaPolicyBoardConfig (SiPolicyPpi);
> +  UpdatePeiCpuPolicyBoardConfig (SiPolicyPpi);
> +  UpdatePeiMePolicyBoardConfig (SiPolicyPpi);
> +
> +  UpdatePeiSiPolicy(SiPolicyPpi);
> +  UpdatePeiPchPolicy(SiPolicyPpi);
> +  UpdatePeiSaPolicy(SiPolicyPpi);
> +  UpdatePeiCpuPolicy(SiPolicyPpi);
> +  UpdatePeiMePolicy(SiPolicyPpi);
> +
> +  //
> +  // Install SiPolicyPpi.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = SiInstallPolicyPpi (SiPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInitPreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInitPreMem.c
> new file mode 100644
> index 0000000000..9f8014b72a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiPolicyInitPreMem.c
> @@ -0,0 +1,60 @@
> +/** @file
> +  This file is SampleCode for Intel PEI Platform Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyInit.h"
> +
> +/**
> +  Initialize Intel PEI Platform Policy
> +
> +  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that
> depends
> +                                     on the 'FirmwareConfiguration' varaible.
> +**/
> +VOID
> +EFIAPI
> +PeiPolicyInitPreMem (
> +  IN UINT8                     FirmwareConfiguration
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
> +
> +  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Start in
> Pre-Memory...\n"));
> +  //
> +  // Call SiCreatePreMemConfigBlocks to initialize platform policy structure
> +  // and get all intel default policy settings.
> +  //
> +  Status = SiCreatePreMemConfigBlocks (&SiPreMemPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Update policy by board configuration
> +  //
> +  UpdatePeiPchPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
> +  UpdatePeiMePolicyBoardConfigPreMem (SiPreMemPolicyPpi);
> +  UpdatePeiSaPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
> +  UpdatePeiCpuPolicyBoardConfigPreMem (SiPreMemPolicyPpi);
> +
> +  //
> +  // Update and override all platform related and customized settings below.
> +  //
> +  UpdatePeiPchPolicyPreMem (SiPreMemPolicyPpi);
> +  UpdatePeiMePolicyPreMem (SiPreMemPolicyPpi);
> +  UpdatePeiSaPolicyPreMem (SiPreMemPolicyPpi);
> +  UpdatePeiCpuPolicyPreMem (SiPreMemPolicyPpi);
> +
> +  //
> +  // Install SiPreMemPolicyPpi.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = SiPreMemInstallPolicyPpi (SiPreMemPolicyPpi);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "Silicon PEI Policy Initialization Done in
> Pre-Memory\n"));
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSaPolicyInit.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSaPolicyInit.c
> new file mode 100644
> index 0000000000..922bcd135f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/
> PeiSaPolicyInit.c
> @@ -0,0 +1,114 @@
> +/** @file
> +  This file is SampleCode for Intel SA PEI Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyInit.h"
> +
> +
> +/**
> +  PcieCardResetWorkAround performs PCIe Card reset on root port
> +
> +  @param[in out] SiPreMemPolicyPpi SI_PREMEM_POLICY_PPI
> +
> +  @retval EFI_SUCCESS              The policy is installed and initialized.
> +**/
> +EFI_STATUS
> +  PcieCardResetWorkAround (
> +  IN OUT   SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  SA_MISC_PEI_PREMEM_CONFIG       *MiscPeiPreMemConfig;
> +  SWITCHABLE_GRAPHICS_CONFIG      *SgGpioData;
> +
> +  Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *)&MiscPeiPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi,
> &gSwitchableGraphicsConfigGuid, (VOID *)&SgGpioData);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  if (SgGpioData->SaRtd3Pcie0Gpio.GpioSupport != NotSupported) {
> +    ///
> +    /// dGPU is present.
> +    ///      If PCIe Mode or SG Muxless
> +    ///              Power on MXM
> +    ///              Configure GPIOs to drive MXM in PCIe mode or SG Muxless
> +    ///      else
> +    ///              Do Nothing
> +    ///
> +    if ((MiscPeiPreMemConfig->SgMode == SgModeMuxless) ||
> +        (MiscPeiPreMemConfig->SgMode == SgModeDgpu)) {
> +      DEBUG((DEBUG_INFO, "Configure GPIOs for driving the dGPU.\n"));
> +      ///
> +      ///  Drive DGPU HOLD RST Enable to make sure we hold reset
> +      ///
> +      PcieGpioWrite (
> +        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo,
> +        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active,
> +        GP_ENABLE
> +        );
> +      ///
> +      /// wait 100ms
> +      ///
> +      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) *
> STALL_ONE_MILLI_SECOND);
> +
> +      ///
> +      /// Drive DGPU PWR EN to Power On MXM
> +      ///
> +      PcieGpioWrite (
> +        SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.GpioNo,
> +        SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.Active,
> +        GP_ENABLE
> +        );
> +      ///
> +      /// wait 300ms
> +      ///
> +      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterPwrEn) *
> STALL_ONE_MILLI_SECOND);
> +
> +      ///
> +      /// Drive DGPU HOLD RST Disabled to remove reset
> +      ///
> +      PcieGpioWrite (
> +        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo,
> +        SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active,
> +        GP_DISABLE
> +        );
> +      ///
> +      /// wait 100ms
> +      ///
> +      MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) *
> STALL_ONE_MILLI_SECOND);
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  PCIe GPIO Write
> +
> +  @param[in] Gpio        - GPIO Number
> +  @param[in] Active      - GPIO Active Information; High/Low
> +  @param[in] Level       - Write GPIO value (0/1)
> +
> +**/
> +VOID
> +PcieGpioWrite (
> +  IN  UINT32                Gpio,
> +  IN  BOOLEAN               Active,
> +  IN  BOOLEAN               Level
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  if (Active == 0) {
> +    Level = (~Level) & 0x1;
> +  }
> +  Status = GpioSetOutputValue(Gpio, (UINT32)Level);
> +  if (Status != EFI_SUCCESS) {
> +    return;
> +  }
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdate.c
> new file mode 100644
> index 0000000000..144480a83d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdate.c
> @@ -0,0 +1,80 @@
> +/** @file
> +  CPU PEI Policy Update & initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiCpuPolicyUpdate.h"
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/CpuPlatformLib.h>
> +
> +/**
> +  This function performs CPU PEI Policy initialization.
> +
> +  @param[in] SiPolicyPpi           The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS              The PPI is installed and initialized.
> +  @retval EFI ERRORS               The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES     Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicy (
> +  IN OUT  SI_POLICY_PPI   *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  CPU_CONFIG                       *CpuConfig;
> +  CPU_POWER_MGMT_BASIC_CONFIG      *CpuPowerMgmtBasicConfig;
> +  SI_PREMEM_POLICY_PPI             *SiPreMemPolicyPpi;
> +  CPU_POWER_MGMT_CUSTOM_CONFIG
> *CpuPowerMgmtCustomConfig;
> +  CPU_POWER_MGMT_TEST_CONFIG      *CpuPowerMgmtTestConfig;
> +  CPU_TEST_CONFIG                 *CpuTestConfig;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *)
> &CpuConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi,
> &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock((VOID *)SiPolicyPpi,
> &gCpuPowerMgmtCustomConfigGuid, (VOID
> *)&CpuPowerMgmtCustomConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gCpuTestConfigGuid, (VOID
> *)&CpuTestConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = PeiServicesLocatePpi (
> +                &gSiPreMemPolicyPpiGuid,
> +                0,
> +                NULL,
> +                (VOID **) &SiPreMemPolicyPpi
> +                );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock((VOID *)SiPolicyPpi,
> &gCpuPowerMgmtTestConfigGuid, (VOID *)&CpuPowerMgmtTestConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Init Power Management Policy Variables
> +  //
> +  CpuPowerMgmtBasicConfig->HwpInterruptControl = 1;
> +  CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio = 0x4;
> +  CpuPowerMgmtBasicConfig->OneCoreRatioLimit = 0x22;
> +  CpuPowerMgmtBasicConfig->TwoCoreRatioLimit = 0x22;
> +  CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit = 0x22;
> +  CpuPowerMgmtBasicConfig->FourCoreRatioLimit = 0x22;
> +  CpuPowerMgmtBasicConfig->FiveCoreRatioLimit = 0;
> +  CpuPowerMgmtBasicConfig->SixCoreRatioLimit = 0;
> +  CpuPowerMgmtBasicConfig->SevenCoreRatioLimit = 0;
> +  CpuPowerMgmtBasicConfig->EightCoreRatioLimit = 0;
> +  CpuPowerMgmtBasicConfig->Hwp = 0x1;
> +  CpuTestConfig->CpuWakeUpTimer = 1;
> +  CpuPowerMgmtTestConfig->AutoThermalReporting = 0;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdatePreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdatePreMem.c
> new file mode 100644
> index 0000000000..bce02a9c5a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiCpuPolicyUpdatePreMem.c
> @@ -0,0 +1,108 @@
> +/** @file
> +  This file is SampleCode of the library for Intel CPU PEI Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiCpuPolicyUpdate.h"
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/SpiLib.h>
> +
> +/**
> +  Check on the processor if SGX is supported.
> +
> +  @retval True if SGX supported or FALSE if not
> +**/
> +BOOLEAN
> +IsSgxCapSupported (
> +  VOID
> +  )
> +{
> +  EFI_CPUID_REGISTER CpuidRegs;
> +
> +  ///
> +  /// Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
> +  ///
> +  AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0,
> &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.Re
> gEdx);
> +
> +  ///
> +  /// SGX feature is supported only on WHL and later,
> +  /// with CPUID.(EAX=7,ECX=0):EBX[2]=1
> +  /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
> +  ///
> +  if ((CpuidRegs.RegEbx & BIT2) && (AsmReadMsr64 (MSR_IA32_MTRRCAP) &
> BIT12)) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  This function performs CPU PEI Policy initialization in Pre-memory.
> +
> +  @param[in] SiPreMemPolicyPpi     The SI Pre-Mem Policy PPI instance
> +
> +  @retval EFI_SUCCESS              The PPI is installed and initialized.
> +  @retval EFI ERRORS               The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES     Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicyPreMem (
> +  IN OUT  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_BOOT_MODE                   BootMode;
> +  CPU_CONFIG_LIB_PREMEM_CONFIG    *CpuConfigLibPreMemConfig;
> +  CPU_OVERCLOCKING_PREMEM_CONFIG
> *CpuOverClockingPreMemConfig;
> +  UINT32                          PchSpiBar0;
> +  UINT32                          MaxLogicProcessors;
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gCpuOverclockingPreMemConfigGuid, (VOID *)
> &CpuOverClockingPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "UpdatePeiCpuPolicyPreMem Start\n"));
> +
> +  //
> +  // Get current boot mode
> +  //
> +  Status = PeiServicesGetBootMode (&BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SpiServiceInit ();
> +
> +  PchSpiBar0 = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
> +                                   DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                                   DEFAULT_PCI_BUS_NUMBER_PCH,
> +                                   PCI_DEVICE_NUMBER_PCH_SPI,
> +                                   PCI_FUNCTION_NUMBER_PCH_SPI,
> +                                   R_SPI_CFG_BAR0
> +                                   ));
> +  PchSpiBar0 &= ~(B_SPI_CFG_BAR0_MASK);
> +
> +  if (PchSpiBar0 == 0) {
> +    DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
> +    ASSERT (FALSE);
> +  }
> +
> +  CpuConfigLibPreMemConfig->PeciC10Reset = 0;
> +  CpuConfigLibPreMemConfig->CpuRatio = 0;
> +  ///
> +  /// Set PcdCpuMaxLogicalProcessorNumber to max number of logical
> processors enabled
> +  /// Read MSR_CORE_THREAD_COUNT (0x35) to check the total active
> Threads
> +  ///
> +  MaxLogicProcessors = (UINT32) (AsmReadMsr64
> (MSR_CORE_THREAD_COUNT) & B_THREAD_COUNT_MASK);
> +  DEBUG ((DEBUG_INFO, "MaxLogicProcessors = %d\n",
> MaxLogicProcessors));
> +  PcdSet32S (PcdCpuMaxLogicalProcessorNumber, MaxLogicProcessors);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdate.c
> new file mode 100644
> index 0000000000..e557f04971
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdate.c
> @@ -0,0 +1,49 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiMePolicyUpdate.h"
> +#include <ConfigBlock/MePeiConfig.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PmcLib.h>
> +
> +/**
> +  Update the ME Policy Library
> +
> +  @param[in, out] SiPolicyPpi     The pointer to SiPolicyPpi
> +
> +  @retval EFI_SUCCESS             Update complete.
> +**/
> +EFI_STATUS
> +UpdatePeiMePolicy (
> +  IN OUT SI_POLICY_PPI            *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  ME_PEI_CONFIG                   *MePeiConfig;
> +
> +  DEBUG ((DEBUG_INFO, "UpdatePeiMePolicy\n"));
> +
> +  Status = EFI_SUCCESS;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *)
> &MePeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if (!PmcIsRtcBatteryGood ()) {
> +    //
> +    // For non coin battery design, this can be skipped.
> +    //
> +    MePeiConfig->MeUnconfigOnRtcClear   = 2;
> +  }
> +
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdatePreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdatePreMem.c
> new file mode 100644
> index 0000000000..de9849b807
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiMePolicyUpdatePreMem.c
> @@ -0,0 +1,32 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiMePolicyUpdate.h"
> +#include <Library/PeiServicesLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/ConfigBlockLib.h>
> +
> +/**
> +  Update the ME Policy Library
> +
> +  @param[in] SiPreMemPolicyPpi  The pointer to SiPreMemPolicyPpi
> +
> +  @retval EFI_SUCCESS           Update complete.
> +**/
> +EFI_STATUS
> +UpdatePeiMePolicyPreMem (
> +  IN OUT SI_PREMEM_POLICY_PPI     *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                      Status;
> +
> +  DEBUG ((DEBUG_INFO, "UpdatePeiMePolicyPreMem\n"));
> +
> +  Status = EFI_SUCCESS;
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdate.c
> new file mode 100644
> index 0000000000..3e44c6cc29
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdate.c
> @@ -0,0 +1,523 @@
> +/** @file
> +  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/HdaVerbTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PchGbeLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Ppi/Spi.h>
> +#include <GpioConfig.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PchGbeLib.h>
> +#include <PlatformBoardConfig.h>
> +#include <Library/CnviLib.h>
> +#include <Register/PchRegsLpcCnl.h>
> +#include <Ppi/PeiTbtPolicy.h>
> +#include <PcieDeviceOverrideTable.h>
> +
> +VOID
> +UpdatePcieClockInfo (
> +  PCH_PCIE_CONFIG  *PcieRpConfig,
> +  UINTN            Index,
> +  UINT64           Data
> +  )
> +{
> +  PCD64_BLOB Pcd64;
> +
> +  Pcd64.Blob = Data;
> +  DEBUG ((DEBUG_INFO, "UpdatePcieClockInfo ClkIndex %x ClkUsage %x,
> Supported %x\n", Index, Pcd64.PcieClock.ClockUsage,
> Pcd64.PcieClock.ClkReqSupported));
> +
> +  PcieRpConfig->PcieClock[Index].Usage =
> (UINT8)Pcd64.PcieClock.ClockUsage;
> +  if (Pcd64.PcieClock.ClkReqSupported) {
> +    PcieRpConfig->PcieClock[Index].ClkReq = (UINT8)Index;
> +  } else {
> +    PcieRpConfig->PcieClock[Index].ClkReq = 0xFF;
> +  }
> +}
> +
> +/**
> +  This is helper function for getting I2C Pads Internal Termination settings
> from Pcd
> +
> +  @param[in]  Index            I2C Controller Index
> +**/
> +UINT8
> +GetSerialIoI2cPadsTerminationFromPcd (
> +  IN UINT8 Index
> +)
> +{
> +  switch (Index) {
> +    case 0:
> +      return PcdGet8 (PcdPchSerialIoI2c0PadInternalTerm);
> +    case 1:
> +      return PcdGet8 (PcdPchSerialIoI2c1PadInternalTerm);
> +    case 2:
> +      return PcdGet8 (PcdPchSerialIoI2c2PadInternalTerm);
> +    case 3:
> +      return PcdGet8 (PcdPchSerialIoI2c3PadInternalTerm);
> +    case 4:
> +      return PcdGet8 (PcdPchSerialIoI2c4PadInternalTerm);
> +    case 5:
> +      return PcdGet8 (PcdPchSerialIoI2c5PadInternalTerm);
> +    default:
> +      ASSERT (FALSE); // Invalid I2C Controller Index
> +  }
> +  return 0;
> +}
> +/**
> +  This is a helper function for updating USB Policy according to Blob data
> +
> +  @param[in]  UsbConfig        Pointer to USB_CONFIG data buffer
> +  @param[in]  PortIndex        USB Port index
> +  @param[in]  Data32           Blob containing USB2 Afe (PCD32_BLOB) data
> +**/
> +VOID
> +UpdateUsb20AfePolicy (
> +  IN USB_CONFIG                 *UsbConfig,
> +  IN UINT8                      PortIndex,
> +  UINT32                        Data32
> +)
> +{
> +  PCD32_BLOB Pcd32;
> +  Pcd32.Blob = Data32;
> +
> +  if (PortIndex < MAX_USB2_PORTS && Pcd32.Info.Petxiset != 0) {
> +    UsbConfig->PortUsb20[PortIndex].Afe.Petxiset     = Pcd32.Info.Petxiset;
> +    UsbConfig->PortUsb20[PortIndex].Afe.Txiset       = Pcd32.Info.Txiset;
> +    UsbConfig->PortUsb20[PortIndex].Afe.Predeemp     =
> Pcd32.Info.Predeemp;
> +    UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit    = Pcd32.Info.Pehalfbit;
> +  }
> +}
> +
> +/**
> +  This function updates USB Policy per port OC Pin number
> +
> +  @param[in]  PchUsbConfig     Pointer to USB_CONFIG data buffer
> +  @param[in]  PortIndex        USB Port index
> +  @param[in]  Pin              OverCurrent pin number
> +**/
> +VOID
> +UpdateUsb20OverCurrentPolicy (
> +  IN USB_CONFIG                 *UsbConfig,
> +  IN UINT8                      PortIndex,
> +  UINT8                         Pin
> +)
> +{
> +  if (PortIndex < MAX_USB2_PORTS && ((Pin < UsbOverCurrentPinMax) || (Pin
> == UsbOverCurrentPinSkip))) {
> +    UsbConfig->PortUsb20[PortIndex].OverCurrentPin = Pin;
> +  } else {
> +    if (PortIndex >= MAX_USB2_PORTS) {
> +      DEBUG ((DEBUG_ERROR, "UpdateUsb20OverCurrentPolicy: USB2 port
> number %d is not a valid USB2 port number\n", PortIndex));
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "UpdateUsb20OverCurrentPolicy: Invalid
> OverCurrent pin specified USB2 port %d\n", PortIndex));
> +    }
> +  }
> +}
> +
> +/**
> +  This function updates USB Policy per port OC Pin number
> +
> +  @param[in]  PchUsbConfig     Pointer to USB_CONFIG data buffer
> +  @param[in]  PortIndex        USB Port index
> +  @param[in]  Pin              OverCurrent pin number
> +**/
> +VOID
> +UpdateUsb30OverCurrentPolicy (
> +  IN USB_CONFIG                 *UsbConfig,
> +  IN UINT8                      PortIndex,
> +  UINT8                         Pin
> +)
> +{
> +  if (PortIndex < MAX_USB3_PORTS && ((Pin < UsbOverCurrentPinMax) || (Pin
> == UsbOverCurrentPinSkip))) {
> +    UsbConfig->PortUsb30[PortIndex].OverCurrentPin = Pin;
> +  } else {
> +    if (PortIndex >= MAX_USB2_PORTS) {
> +      DEBUG ((DEBUG_ERROR, "UpdateUsb30OverCurrentPolicy: USB3 port
> number %d is not a valid USB3 port number\n", PortIndex));
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "UpdateUsb30OverCurrentPolicy: Invalid
> OverCurrent pin specified USB3 port %d\n", PortIndex));
> +    }
> +  }
> +}
> +
> +/**
> +  This function performs PCH USB Platform Policy initialization
> +
> +  @param[in] PchUsbConfig         Pointer to USB_CONFIG data buffer
> +  @param[in] PchSetup             Pointer to PCH_SETUP data buffer
> +**/
> +VOID
> +UpdatePchUsbConfig (
> +  IN USB_CONFIG                *UsbConfig
> +  )
> +{
> +  UINTN              PortIndex;
> +
> +  UsbConfig->OverCurrentEnable = TRUE;
> +
> +  for (PortIndex = 0; PortIndex < GetPchUsb2MaxPhysicalPortNum ();
> PortIndex++) {
> +      UsbConfig->PortUsb20[PortIndex].Enable = TRUE;
> +  }
> +  for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++)
> {
> +      UsbConfig->PortUsb30[PortIndex].Enable = TRUE;
> +  }
> +
> +  UsbConfig->XdciConfig.Enable = FALSE;
> +
> +
> +  //
> +  // USB2 AFE settings.
> +  //
> +  UpdateUsb20AfePolicy (UsbConfig, 0, PcdGet32 (PcdUsb20Port0Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 1, PcdGet32 (PcdUsb20Port1Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 2, PcdGet32 (PcdUsb20Port2Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 3, PcdGet32 (PcdUsb20Port3Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 4, PcdGet32 (PcdUsb20Port4Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 5, PcdGet32 (PcdUsb20Port5Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 6, PcdGet32 (PcdUsb20Port6Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 7, PcdGet32 (PcdUsb20Port7Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 8, PcdGet32 (PcdUsb20Port8Afe));
> +  UpdateUsb20AfePolicy (UsbConfig, 9, PcdGet32 (PcdUsb20Port9Afe));
> +  UpdateUsb20AfePolicy (UsbConfig,10, PcdGet32 (PcdUsb20Port10Afe));
> +  UpdateUsb20AfePolicy (UsbConfig,11, PcdGet32 (PcdUsb20Port11Afe));
> +  UpdateUsb20AfePolicy (UsbConfig,12, PcdGet32 (PcdUsb20Port12Afe));
> +  UpdateUsb20AfePolicy (UsbConfig,13, PcdGet32 (PcdUsb20Port13Afe));
> +  UpdateUsb20AfePolicy (UsbConfig,14, PcdGet32 (PcdUsb20Port14Afe));
> +  UpdateUsb20AfePolicy (UsbConfig,15, PcdGet32 (PcdUsb20Port15Afe));
> +
> +  //
> +  // Platform Board programming per the layout of each port.
> +  //
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 0, PcdGet8
> (PcdUsb20OverCurrentPinPort0));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 1, PcdGet8
> (PcdUsb20OverCurrentPinPort1));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 2, PcdGet8
> (PcdUsb20OverCurrentPinPort2));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 3, PcdGet8
> (PcdUsb20OverCurrentPinPort3));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 4, PcdGet8
> (PcdUsb20OverCurrentPinPort4));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 5, PcdGet8
> (PcdUsb20OverCurrentPinPort5));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 6, PcdGet8
> (PcdUsb20OverCurrentPinPort6));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 7, PcdGet8
> (PcdUsb20OverCurrentPinPort7));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 8, PcdGet8
> (PcdUsb20OverCurrentPinPort8));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig, 9, PcdGet8
> (PcdUsb20OverCurrentPinPort9));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig,10, PcdGet8
> (PcdUsb20OverCurrentPinPort10));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig,11, PcdGet8
> (PcdUsb20OverCurrentPinPort11));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig,12, PcdGet8
> (PcdUsb20OverCurrentPinPort12));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig,13, PcdGet8
> (PcdUsb20OverCurrentPinPort13));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig,14, PcdGet8
> (PcdUsb20OverCurrentPinPort14));
> +  UpdateUsb20OverCurrentPolicy (UsbConfig,15, PcdGet8
> (PcdUsb20OverCurrentPinPort15));
> +
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 0, PcdGet8
> (PcdUsb30OverCurrentPinPort0));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 1, PcdGet8
> (PcdUsb30OverCurrentPinPort1));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 2, PcdGet8
> (PcdUsb30OverCurrentPinPort2));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 3, PcdGet8
> (PcdUsb30OverCurrentPinPort3));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 4, PcdGet8
> (PcdUsb30OverCurrentPinPort4));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 5, PcdGet8
> (PcdUsb30OverCurrentPinPort5));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 6, PcdGet8
> (PcdUsb30OverCurrentPinPort6));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 7, PcdGet8
> (PcdUsb30OverCurrentPinPort7));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 8, PcdGet8
> (PcdUsb30OverCurrentPinPort8));
> +  UpdateUsb30OverCurrentPolicy (UsbConfig, 9, PcdGet8
> (PcdUsb30OverCurrentPinPort9));
> +
> +}
> +
> +/**
> +  Return if input ImageGuid belongs to system FMP GUID list.
> +
> +  @param[in] ImageGuid A pointer to GUID
> +
> +  @retval TRUE  ImageGuid is in the list of
> PcdSystemFmpCapsuleImageTypeIdGuid
> +  @retval FALSE ImageGuid is not in the list of
> PcdSystemFmpCapsuleImageTypeIdGuid
> +**/
> +BOOLEAN
> +IsSystemFmpGuid (
> +  IN GUID   *ImageGuid
> +  )
> +{
> +  GUID      *Guid;
> +  UINTN     Count;
> +  UINTN     Index;
> +
> +  Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
> +  Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof
> (GUID);
> +
> +  for (Index = 0; Index < Count; Index++, Guid++) {
> +    if (CompareGuid (ImageGuid, Guid)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  This function performs PCH PEI Policy initialization.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +  @retval EFI ERRORS              The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicy (
> +  IN OUT      SI_POLICY_PPI     *SiPolicy
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINT8                           Index;
> +  DMI_HW_WIDTH_CONTROL            *DmiHaAWC;
> +  UINT16                          LpcDid;
> +  PCH_GENERAL_CONFIG              *PchGeneralConfig;
> +  PCH_PCIE_CONFIG                 *PcieRpConfig;
> +  PCH_SATA_CONFIG                 *SataConfig;
> +  PCH_IOAPIC_CONFIG               *IoApicConfig;
> +  PCH_DMI_CONFIG                  *DmiConfig;
> +  PCH_FLASH_PROTECTION_CONFIG     *FlashProtectionConfig;
> +  PCH_HDAUDIO_CONFIG              *HdAudioConfig;
> +  PCH_INTERRUPT_CONFIG            *InterruptConfig;
> +  PCH_ISH_CONFIG                  *IshConfig;
> +  PCH_LAN_CONFIG                  *LanConfig;
> +  PCH_LOCK_DOWN_CONFIG            *LockDownConfig;
> +  PCH_PM_CONFIG                   *PmConfig;
> +  PCH_SCS_CONFIG                  *ScsConfig;
> +  PCH_SERIAL_IO_CONFIG            *SerialIoConfig;
> +  PCH_LPC_SIRQ_CONFIG             *SerialIrqConfig;
> +  PCH_THERMAL_CONFIG              *ThermalConfig;
> +  USB_CONFIG                      *UsbConfig;
> +  PCH_ESPI_CONFIG                 *EspiConfig;
> +  PCH_CNVI_CONFIG                 *CnviConfig;
> +  PEI_TBT_POLICY                  *PeiTbtPolicy;
> +  SI_PREMEM_POLICY_PPI            *SiPreMemPolicyPpi;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPchGeneralConfigGuid, (VOID
> *) &PchGeneralConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPcieRpConfigGuid, (VOID *)
> &PcieRpConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID *)
> &SataConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gIoApicConfigGuid, (VOID *)
> &IoApicConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gDmiConfigGuid, (VOID *)
> &DmiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gFlashProtectionConfigGuid,
> (VOID *) &FlashProtectionConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gHdAudioConfigGuid, (VOID *)
> &HdAudioConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gInterruptConfigGuid, (VOID *)
> &InterruptConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gIshConfigGuid, (VOID *)
> &IshConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gLanConfigGuid, (VOID *)
> &LanConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gLockDownConfigGuid, (VOID *)
> &LockDownConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gPmConfigGuid, (VOID *)
> &PmConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gScsConfigGuid, (VOID *)
> &ScsConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIoConfigGuid, (VOID *)
> &SerialIoConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSerialIrqConfigGuid, (VOID *)
> &SerialIrqConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gThermalConfigGuid, (VOID *)
> &ThermalConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gUsbConfigGuid, (VOID *)
> &UsbConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gEspiConfigGuid, (VOID *)
> &EspiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gCnviConfigGuid, (VOID *)
> &CnviConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = PeiServicesLocatePpi (
> +                &gSiPreMemPolicyPpiGuid,
> +                0,
> +                NULL,
> +                (VOID **) &SiPreMemPolicyPpi
> +                );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  PeiTbtPolicy = NULL;
> +  LpcDid = PchGetLpcDid ();
> +
> +  DmiConfig->PwrOptEnable = TRUE;
> +  PmConfig->PchSlpS3MinAssert = 0;
> +  PmConfig->PchSlpS4MinAssert = 0;
> +  PmConfig->PchSlpSusMinAssert = 0;
> +  PmConfig->PchSlpAMinAssert = 0;
> +
> +  SataConfig->ThermalThrottling.P1T3M = 3;
> +  SataConfig->ThermalThrottling.P1T2M = 2;
> +  SataConfig->ThermalThrottling.P1T1M = 1;
> +  SataConfig->ThermalThrottling.P0T3M = 3;
> +  SataConfig->ThermalThrottling.P0T2M = 2;
> +  SataConfig->ThermalThrottling.P0T1M = 1;
> +
> +  UpdatePcieClockInfo (PcieRpConfig, 0, PcdGet64  (PcdPcieClock0));
> +  UpdatePcieClockInfo (PcieRpConfig, 1, PcdGet64  (PcdPcieClock1));
> +  UpdatePcieClockInfo (PcieRpConfig, 2, PcdGet64  (PcdPcieClock2));
> +  UpdatePcieClockInfo (PcieRpConfig, 3, PcdGet64  (PcdPcieClock3));
> +  UpdatePcieClockInfo (PcieRpConfig, 4, PcdGet64  (PcdPcieClock4));
> +  UpdatePcieClockInfo (PcieRpConfig, 5, PcdGet64  (PcdPcieClock5));
> +  UpdatePcieClockInfo (PcieRpConfig, 6, PcdGet64  (PcdPcieClock6));
> +  UpdatePcieClockInfo (PcieRpConfig, 7, PcdGet64  (PcdPcieClock7));
> +  UpdatePcieClockInfo (PcieRpConfig, 8, PcdGet64  (PcdPcieClock8));
> +  UpdatePcieClockInfo (PcieRpConfig, 9, PcdGet64  (PcdPcieClock9));
> +  UpdatePcieClockInfo (PcieRpConfig, 10, PcdGet64 (PcdPcieClock10));
> +  UpdatePcieClockInfo (PcieRpConfig, 11, PcdGet64 (PcdPcieClock11));
> +  UpdatePcieClockInfo (PcieRpConfig, 12, PcdGet64 (PcdPcieClock12));
> +  UpdatePcieClockInfo (PcieRpConfig, 13, PcdGet64 (PcdPcieClock13));
> +  UpdatePcieClockInfo (PcieRpConfig, 14, PcdGet64 (PcdPcieClock14));
> +  UpdatePcieClockInfo (PcieRpConfig, 15, PcdGet64 (PcdPcieClock15));
> +
> +  PcieRpConfig->PcieDeviceOverrideTablePtr = (UINT32) mPcieDeviceTable;
> +  PcieRpConfig->RootPort[0].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[1].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[2].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[3].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[4].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[5].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[6].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[7].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[8].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[9].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[10].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[11].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[12].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[13].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[14].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[15].ClkReqDetect = TRUE;
> +  PcieRpConfig->RootPort[0].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[1].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[2].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[3].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[4].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[5].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[6].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[7].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[8].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[9].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[10].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[11].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[12].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[13].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[14].AdvancedErrorReporting = TRUE;
> +  PcieRpConfig->RootPort[15].AdvancedErrorReporting = TRUE;
> +
> +  //
> +  // Install HDA Link/iDisplay Codec Verb Table
> +  //
> +  AddPlatformVerbTables (
> +    PchHdaCodecPlatformOnboard,
> +    &(HdAudioConfig->VerbTableEntryNum),
> +    &(HdAudioConfig->VerbTablePtr)
> +    );
> +
> +  LockDownConfig->BiosLock = FALSE;
> +  LockDownConfig->BiosInterface = FALSE;
> +
> +  //
> +  // IOAPIC Config
> +  //
> +//  IoApicConfig->IoApicEntry24_119     = PchSetup.PchIoApic24119Entries;
> +  //
> +  // To support SLP_S0, it's required to disable 8254 timer.
> +  // Note that CSM may require this option to be disabled for correct
> operation.
> +  // Once 8254 timer disabled, some legacy OPROM and legacy OS will fail
> while using 8254 timer.
> +  // For some OS environment that it needs to set 8254CGE in late state it
> should
> +  // set this policy to FALSE and use PmcSet8254ClockGateState (TRUE) in
> SMM later.
> +  // This is also required during S3 resume.
> +  //
> +  // The Enable8254ClockGatingOnS3 is only applicable when
> Enable8254ClockGating is disabled.
> +  // If Enable8254ClockGating is enabled, RC will do 8254 CGE programming
> on S3 as well.
> +  // else, RC will do the programming on S3 when
> Enable8254ClockGatingOnS3 is enabled.
> +  // This avoids the SMI requirement for the programming.
> +  //
> +  // If S0ix is not enabled, then disable 8254CGE for leagcy boot case.
> +  //
> +  IoApicConfig->Enable8254ClockGating     = FALSE;
> +  IoApicConfig->Enable8254ClockGatingOnS3 = FALSE;
> +
> +  //
> +  // SerialIo Config
> +  //
> +  SerialIoConfig->DevMode[0] = 1;
> +  SerialIoConfig->DevMode[1] = 1;
> +  SerialIoConfig->DevMode[2] = 0;
> +  SerialIoConfig->DevMode[3] = 0;
> +  SerialIoConfig->DevMode[4] = 1;
> +  SerialIoConfig->DevMode[5] = 0;
> +  SerialIoConfig->DevMode[6] = 0;
> +  SerialIoConfig->DevMode[7] = 0;
> +  SerialIoConfig->DevMode[8] = 0;
> +  SerialIoConfig->DevMode[9] = 0;
> +  SerialIoConfig->DevMode[10] = 0;
> +  SerialIoConfig->DevMode[11] = 3;
> +
> +  SerialIoConfig->Uart0PinMuxing = 1;
> +  SerialIoConfig->SpiCsPolarity[0] = 1;
> +  SerialIoConfig->SpiCsPolarity[1] = 0;
> +  SerialIoConfig->SpiCsPolarity[2] = 0;
> +
> +  SerialIoConfig->UartHwFlowCtrl[0] = 1;
> +  SerialIoConfig->UartHwFlowCtrl[1] = 1;
> +  SerialIoConfig->UartHwFlowCtrl[2] = 1;
> +  //
> +  // I2C4 and I2C5 don't exist in SPT-H chipset
> +  //
> +  if (IsPchH ()) {
> +    SerialIoConfig->DevMode[PchSerialIoIndexI2C4] = PchSerialIoDisabled;
> +    SerialIoConfig->DevMode[PchSerialIoIndexI2C5] = PchSerialIoDisabled;
> +  }
> +
> +  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
> +    SerialIoConfig->I2cPadsTermination[Index] =
> GetSerialIoI2cPadsTerminationFromPcd (Index);
> +  }
> +
> +  PmConfig->SlpS0Override                         = 2; //PchSetup.SlpS0Override;
> +  PmConfig->SlpS0DisQForDebug                     = 3;
> //PchSetup.SlpS0DisQForDebug;
> +  PmConfig->SlpS0Vm075VSupport                    = 1; //
> PcdGetBool(PcdSlpS0Vm075VSupport);
> +  PmConfig->CpuC10GatePinEnable                   = 1;
> +
> +  //
> +  // Thermal Config
> +  //
> +  ThermalConfig->TsmicLock           = TRUE;
> +  ThermalConfig->PchHotEnable        = PcdGetBool
> (PcdPchThermalHotEnable);
> +
> +  DmiHaAWC = &ThermalConfig->DmiHaAWC;
> +  DmiHaAWC->TS3TW = 0;
> +  DmiHaAWC->TS2TW = 1;
> +  DmiHaAWC->TS1TW = 2;
> +  DmiHaAWC->TS0TW = 3;
> +  //
> +  // Update Pch Usb Config
> +  //
> +  UpdatePchUsbConfig (
> +    UsbConfig
> +    );
> +
> +  ScsConfig->ScsUfsEnabled = 0;
> +  ScsConfig->ScsEmmcHs400Enabled = 1;
> +  ScsConfig->ScsEmmcHs400TuningRequired = TRUE;
> +
> +  IshConfig->I2c0GpioAssign = 1;
> +  IshConfig->I2c1GpioAssign = 1;
> +  IshConfig->Gp0GpioAssign = 1;
> +  IshConfig->Gp1GpioAssign = 1;
> +  IshConfig->Gp2GpioAssign = 1;
> +  IshConfig->Gp3GpioAssign = 1;
> +  IshConfig->Gp4GpioAssign = 1;
> +  IshConfig->Gp5GpioAssign = 1;
> +  IshConfig->Gp6GpioAssign = 1;
> +
> +  return Status;
> +}
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdatePreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdatePreMem.c
> new file mode 100644
> index 0000000000..968df0f55c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiPchPolicyUpdatePreMem.c
> @@ -0,0 +1,113 @@
> +/** @file
> +  This file is SampleCode of the library for Intel PCH PEI Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPchPolicyUpdate.h"
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/SataLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PchPolicyLib.h>
> +
> +//
> +// Sawtooth Peak
> +// Single SPD EEPROM at 0xA2 serves both C0D0 and C1D0 (LPDDR is 1DPC
> only)
> +//
> +#define DIMM_SMB_SPD_P0C0D0_STP 0xA2
> +#define DIMM_SMB_SPD_P0C0D1_STP 0xA0
> +#define DIMM_SMB_SPD_P0C1D0_STP 0xA2
> +#define DIMM_SMB_SPD_P0C1D1_STP 0xA0
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusSTPRsvdAddresses[] = {
> +  DIMM_SMB_SPD_P0C0D0_STP,
> +  DIMM_SMB_SPD_P0C0D1_STP,
> +  DIMM_SMB_SPD_P0C1D0_STP,
> +  DIMM_SMB_SPD_P0C1D1_STP
> +};
> +
> +
> +/**
> +  This function performs PCH PEI Policy initialization.
> +
> +  @param[in, out] SiPreMemPolicy  The SI PREMEM Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The PPI is installed and initialized.
> +  @retval EFI ERRORS              The PPI is not successfully installed.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicyPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicy
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINT8                           *SmBusReservedTable;
> +  UINT8                           SmBusReservedNum;
> +
> +  PCH_GENERAL_PREMEM_CONFIG       *PchGeneralPreMemConfig;
> +  PCH_TRACE_HUB_PREMEM_CONFIG     *PchTraceHubPreMemConfig;
> +  PCH_SMBUS_PREMEM_CONFIG         *SmbusPreMemConfig;
> +  PCH_LPC_PREMEM_CONFIG           *LpcPreMemConfig;
> +  PCH_WDT_PREMEM_CONFIG           *WatchDogPreMemConfig;
> +  PCH_DCI_PREMEM_CONFIG           *DciPreMemConfig;
> +  PCH_PCIE_RP_PREMEM_CONFIG       *PcieRpPreMemConfig;
> +  PCH_HDAUDIO_PREMEM_CONFIG       *HdaPreMemConfig;
> +  PCH_ISH_PREMEM_CONFIG           *IshPreMemConfig;
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gWatchDogPreMemConfigGuid, (VOID *) &WatchDogPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicy,
> &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DciPreMemConfig->DciUsb3TypecUfpDbg = 2;
> +  PchTraceHubPreMemConfig->MemReg0Size = 3;
> +  PchTraceHubPreMemConfig->MemReg1Size = 3;
> +  //
> +  // SMBUS
> +  //
> +  SmbusPreMemConfig->Enable = TRUE;
> +  SmbusPreMemConfig->SmbAlertEnable = PcdGetBool
> (PcdSmbusAlertEnable);
> +  //
> +  // SMBUS reserved addresses
> +  //
> +  SmBusReservedTable = NULL;
> +  SmBusReservedNum   = 0;
> +  SmbusPreMemConfig->SmbusIoBase = PcdGet16 (PcdSmbusBaseAddress);
> +  SmBusReservedTable = mSmbusSTPRsvdAddresses;
> +  SmBusReservedNum   = sizeof (mSmbusSTPRsvdAddresses);
> +
> +  if (SmBusReservedTable != NULL) {
> +    SmbusPreMemConfig->NumRsvdSmbusAddresses = SmBusReservedNum;
> +    CopyMem (
> +      SmbusPreMemConfig->RsvdSmbusAddressTable,
> +      SmBusReservedTable,
> +      SmBusReservedNum
> +      );
> +  }
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdate.c
> new file mode 100644
> index 0000000000..c1ac7d890f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdate.c
> @@ -0,0 +1,242 @@
> +/** @file
> +Do Platform Stage System Agent initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyUpdate.h"
> +#include <Protocol/GraphicsOutput.h>
> +#include <IndustryStandard/Bmp.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Library/HobLib.h>
> +#include <Platform.h>
> +#include <Ppi/FirmwareVolume.h>
> +#include <Pi/PiFirmwareFile.h>
> +#include <Pi/PiPeiCis.h>
> +#include <Core/Pei/PeiMain.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +
> +/**
> +  UpdatePeiSaPolicy performs SA PEI Policy initialization
> +
> +  @param[in out] SiPolicyPpi     - SI_POLICY PPI
> +
> +  @retval EFI_SUCCESS              The policy is installed and initialized.
> +**/
> +EFI_STATUS
> +UpdatePeiSaPolicy (
> +  IN OUT   SI_POLICY_PPI      *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_GUID                        FileGuid;
> +  VOID                            *Buffer;
> +  UINT8                           SaDisplayConfigTable[9] = {0};
> +  VOID                            *MemBuffer;
> +  BMP_IMAGE_HEADER                *BmpHeader;
> +  UINT64                          BltBufferSize;
> +  UINT32                          Size;
> +  GRAPHICS_PEI_CONFIG             *GtConfig;
> +  GNA_CONFIG                      *GnaConfig;
> +  WDT_PPI                         *gWdtPei;
> +  PCIE_PEI_CONFIG                 *PciePeiConfig;
> +  SA_MISC_PEI_CONFIG              *MiscPeiConfig;
> +  EFI_BOOT_MODE                   BootMode;
> +
> +  DEBUG((DEBUG_INFO, "\nUpdating SA Policy in Post Mem\n"));
> +
> +  Size = 0;
> +  MemBuffer = NULL;
> +  BmpHeader = NULL;
> +  BltBufferSize = 0;
> +  GtConfig = NULL;
> +  GnaConfig = NULL;
> +
> +  Status = GetConfigBlock((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid,
> (VOID *)&GtConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPolicyPpi, &gGnaConfigGuid, (VOID
> *)&GnaConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaPciePeiConfigGuid, (VOID
> *)&PciePeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gSaMiscPeiConfigGuid,
> (VOID *)&MiscPeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  //
> +  // Locate WDT_PPI (ICC WDT PPI)
> +  //
> +  gWdtPei = NULL;
> +  Status = PeiServicesLocatePpi(
> +             &gWdtPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &gWdtPei
> +             );
> +
> +  Status = PeiServicesGetBootMode(&BootMode);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  if (!EFI_ERROR (Status)) {
> +    Buffer = NULL;
> +
> +    CopyMem(&FileGuid, PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
> sizeof(FileGuid));
> +    PeiGetSectionFromFv(FileGuid, &Buffer, &Size);
> +    if (Buffer == NULL) {
> +      DEBUG((DEBUG_ERROR, "Could not locate VBT\n"));
> +    }
> +
> +    MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
> +    if ((MemBuffer != NULL) && (Buffer != NULL)) {
> +      CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
> +      GtConfig->GraphicsConfigPtr = MemBuffer;
> +    } else {
> +      DEBUG((DEBUG_WARN, "Error in locating / copying VBT.\n"));
> +      GtConfig->GraphicsConfigPtr = NULL;
> +    }
> +
> +    GtConfig->PeiGraphicsPeimInit = 1;
> +
> +    DEBUG((DEBUG_INFO, "Vbt Pointer from PeiGetSectionFromFv is 0x%x\n",
> GtConfig->GraphicsConfigPtr));
> +    DEBUG((DEBUG_INFO, "Vbt Size from PeiGetSectionFromFv is 0x%x\n",
> Size));
> +
> +    PeiGetSectionFromFv (gTianoLogoGuid, &Buffer, &Size);
> +    if (Buffer == NULL) {
> +      DEBUG((DEBUG_WARN, "Could not locate Logo\n"));
> +    }
> +
> +    MemBuffer = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)Size));
> +    if ((MemBuffer != NULL) && (Buffer != NULL)) {
> +      CopyMem (MemBuffer, (VOID *)Buffer, (UINTN)Size);
> +      GtConfig->LogoPtr = MemBuffer;
> +      GtConfig->LogoSize = Size;
> +
> +      //
> +      // Calculate the BltBuffer needed size.
> +      //
> +      BmpHeader = (BMP_IMAGE_HEADER *) GtConfig->LogoPtr;
> +
> +      if (BmpHeader->CharB == 'B' && BmpHeader->CharM == 'M') {
> +        BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth,
> BmpHeader->PixelHeight);
> +        if (BltBufferSize < DivU64x32 ((UINTN) ~0, sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
> +          BltBufferSize = MultU64x32 (BltBufferSize, sizeof
> (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
> +          GtConfig->BltBufferSize    = (UINT32) BltBufferSize;
> +          GtConfig->BltBufferAddress = (VOID *) AllocatePages
> (EFI_SIZE_TO_PAGES ((UINTN)GtConfig->BltBufferSize));
> +        } else {
> +          DEBUG ((DEBUG_ERROR, "Blt Buffer Size overflow.\n"));
> +          ASSERT (FALSE);
> +        }
> +      } else {
> +        DEBUG ((DEBUG_ERROR, "Wrong Bmp Image Header.\n"));
> +        ASSERT (FALSE);
> +      }
> +
> +    } else {
> +      DEBUG((DEBUG_WARN, "Error in locating / copying LogoPtr.\n"));
> +      GtConfig->LogoPtr = NULL;
> +      GtConfig->LogoSize = 0;
> +    }
> +
> +    DEBUG((DEBUG_INFO, "LogoPtr from PeiGetSectionFromFv is 0x%x\n",
> GtConfig->LogoPtr));
> +    DEBUG((DEBUG_INFO, "LogoSize from PeiGetSectionFromFv is 0x%x\n",
> GtConfig->LogoSize));
> +
> +    //
> +    // Display DDI Initialization ( default Native GPIO as per board during AUTO
> case)
> +    //
> +    if (PcdGet32 (PcdSaDisplayConfigTable) != 0) {
> +      CopyMem (SaDisplayConfigTable, (VOID *) (UINTN) PcdGet32
> (PcdSaDisplayConfigTable), (UINTN)PcdGet16 (PcdSaDisplayConfigTableSize));
> +      GtConfig->DdiConfiguration.DdiPortEdp     = SaDisplayConfigTable[0];
> +      GtConfig->DdiConfiguration.DdiPortBHpd    = SaDisplayConfigTable[1];
> +      GtConfig->DdiConfiguration.DdiPortCHpd    = SaDisplayConfigTable[2];
> +      GtConfig->DdiConfiguration.DdiPortDHpd    = SaDisplayConfigTable[3];
> +      GtConfig->DdiConfiguration.DdiPortFHpd    = SaDisplayConfigTable[4];
> +      GtConfig->DdiConfiguration.DdiPortBDdc    = SaDisplayConfigTable[5];
> +      GtConfig->DdiConfiguration.DdiPortCDdc    = SaDisplayConfigTable[6];
> +      GtConfig->DdiConfiguration.DdiPortDDdc    = SaDisplayConfigTable[7];
> +      GtConfig->DdiConfiguration.DdiPortFDdc    = SaDisplayConfigTable[8];
> +    }
> +  }
> +
> +  PciePeiConfig->DmiAspm = 0x3;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  PeiGetSectionFromFv finds the file in FV and gets file Address and Size
> +
> +  @param[in] NameGuid              - File GUID
> +  @param[out] Address              - Pointer to the File Address
> +  @param[out] Size                 - Pointer to File Size
> +
> +  @retval EFI_SUCCESS                Successfull in reading the section from FV
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiGetSectionFromFv (
> +  IN CONST  EFI_GUID        NameGuid,
> +  OUT VOID                  **Address,
> +  OUT UINT32                *Size
> +  )
> +{
> +  EFI_STATUS                           Status;
> +  EFI_PEI_FIRMWARE_VOLUME_PPI          *FvPpi;
> +  EFI_FV_FILE_INFO                     FvFileInfo;
> +  PEI_CORE_INSTANCE                    *PrivateData;
> +  UINTN                                CurrentFv;
> +  PEI_CORE_FV_HANDLE                   *CoreFvHandle;
> +  EFI_PEI_FILE_HANDLE                  VbtFileHandle;
> +  EFI_GUID                             *VbtGuid;
> +  EFI_COMMON_SECTION_HEADER            *Section;
> +  CONST EFI_PEI_SERVICES               **PeiServices;
> +
> +  PeiServices = GetPeiServicesTablePointer();
> +
> +  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
> +
> +  Status = PeiServicesLocatePpi(
> +             &gEfiFirmwareFileSystem2Guid,
> +             0,
> +             NULL,
> +             (VOID **)&FvPpi
> +             );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  CurrentFv = PrivateData->CurrentPeimFvCount;
> +  CoreFvHandle = &(PrivateData->Fv[CurrentFv]);
> +
> +  Status = FvPpi->FindFileByName(FvPpi, &NameGuid,
> &CoreFvHandle->FvHandle, &VbtFileHandle);
> +  if (!EFI_ERROR(Status) && VbtFileHandle != NULL) {
> +
> +    DEBUG((DEBUG_INFO, "Find SectionByType \n"));
> +
> +    Status = FvPpi->FindSectionByType(FvPpi, EFI_SECTION_RAW,
> VbtFileHandle, (VOID **)&VbtGuid);
> +    if (!EFI_ERROR(Status)) {
> +
> +      DEBUG((DEBUG_INFO, "GetFileInfo \n"));
> +
> +      Status = FvPpi->GetFileInfo(FvPpi, VbtFileHandle, &FvFileInfo);
> +      Section = (EFI_COMMON_SECTION_HEADER *)FvFileInfo.Buffer;
> +
> +      if (IS_SECTION2(Section)) {
> +        ASSERT(SECTION2_SIZE(Section) > 0x00FFFFFF);
> +        *Size = SECTION2_SIZE(Section) - sizeof
> (EFI_COMMON_SECTION_HEADER2);
> +        *Address = ((UINT8 *)Section + sizeof
> (EFI_COMMON_SECTION_HEADER2));
> +      } else {
> +        *Size = SECTION_SIZE(Section) - sizeof
> (EFI_COMMON_SECTION_HEADER);
> +        *Address = ((UINT8 *)Section + sizeof
> (EFI_COMMON_SECTION_HEADER));
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdatePreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdatePreMem.c
> new file mode 100644
> index 0000000000..3dc455ab29
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSaPolicyUpdatePreMem.c
> @@ -0,0 +1,221 @@
> +/** @file
> +Do Platform Stage System Agent initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSaPolicyUpdate.h"
> +#include <CpuRegs.h>
> +#include <Register/Cpuid.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Guid/MemoryOverwriteControl.h>
> +#include <Library/HobLib.h>
> +#include <Platform.h>
> +#include <PlatformBoardConfig.h>
> +#include <Library/SiPolicyLib.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/GpioLib.h>
> +
> +///
> +/// Memory Reserved should be between 125% to 150% of the Current
> required memory
> +/// otherwise BdsMisc.c would do a reset to make it 125% to avoid s4 resume
> issues.
> +///
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION
> mDefaultMemoryTypeInformation[] = {
> +  { EfiACPIReclaimMemory,   FixedPcdGet32
> (PcdPlatformEfiAcpiReclaimMemorySize) },  // ASL
> +  { EfiACPIMemoryNVS,       FixedPcdGet32
> (PcdPlatformEfiAcpiNvsMemorySize) },      // ACPI NVS (including S3 related)
> +  { EfiReservedMemoryType,  FixedPcdGet32
> (PcdPlatformEfiReservedMemorySize) },     // BIOS Reserved (including S3
> related)
> +  { EfiRuntimeServicesData, FixedPcdGet32
> (PcdPlatformEfiRtDataMemorySize) },       // Runtime Service Data
> +  { EfiRuntimeServicesCode, FixedPcdGet32
> (PcdPlatformEfiRtCodeMemorySize) },       // Runtime Service Code
> +  { EfiMaxMemoryType, 0 }
> +};
> +
> +
> +/**
> +  UpdatePeiSaPolicyPreMem performs SA PEI Policy initialization
> +
> +  @param[in out] SiPreMemPolicyPpi - SI_PREMEM_POLICY PPI
> +
> +  @retval EFI_SUCCESS              The policy is installed and initialized.
> +**/
> +EFI_STATUS
> +UpdatePeiSaPolicyPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  SA_MISC_PEI_PREMEM_CONFIG       *MiscPeiPreMemConfig = NULL;
> +  MEMORY_CONFIG_NO_CRC            *MemConfigNoCrc = NULL;
> +  SA_MEMORY_RCOMP                 *RcompData;
> +  WDT_PPI                         *gWdtPei;
> +  UINT8                           Index;
> +  UINTN                           DataSize;
> +  EFI_MEMORY_TYPE_INFORMATION     MemoryData[EfiMaxMemoryType +
> 1];
> +  EFI_BOOT_MODE                   BootMode;
> +  UINT8                           MorControl;
> +  UINT32                          TraceHubTotalMemSize;
> +  GRAPHICS_PEI_PREMEM_CONFIG      *GtPreMemConfig = NULL;
> +  MEMORY_CONFIGURATION            *MemConfig = NULL;
> +  PCIE_PEI_PREMEM_CONFIG          *PciePeiPreMemConfig = NULL;
> +  SWITCHABLE_GRAPHICS_CONFIG      *SgGpioData = NULL;
> +  IPU_PREMEM_CONFIG               *IpuPreMemPolicy = NULL;
> +  OVERCLOCKING_PREMEM_CONFIG      *OcPreMemConfig = NULL;
> +  VTD_CONFIG                      *Vtd = NULL;
> +  UINT32                          ProcessorTraceTotalMemSize;
> +  UINT16                          AdjustedMmioSize;
> +  CPU_FAMILY                      CpuFamilyId;
> +  CPU_STEPPING                    CpuStepping;
> +
> +  TraceHubTotalMemSize = 0;
> +  ProcessorTraceTotalMemSize = 0;
> +  AdjustedMmioSize = PcdGet16 (PcdSaMiscMmioSizeAdjustment);
> +  CpuFamilyId = GetCpuFamily();
> +  CpuStepping = GetCpuStepping();
> +
> +  DEBUG((DEBUG_INFO, "Entering Get Config Block function call from
> UpdatePeiSaPolicyPreMem\n"));
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gGraphicsPeiPreMemConfigGuid, (VOID *) &GtPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gMemoryConfigGuid, (VOID *) &MemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gSaPciePeiPreMemConfigGuid, (VOID *) &PciePeiPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gSwitchableGraphicsConfigGuid, (VOID *) &SgGpioData);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gIpuPreMemConfigGuid, (VOID *) &IpuPreMemPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gSaOverclockingPreMemConfigGuid, (VOID *) &OcPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gVtdConfigGuid,
> (VOID *)&Vtd);
> +  ASSERT_EFI_ERROR(Status);
> +
> +
> +  RcompData = MemConfigNoCrc->RcompData;
> +
> +  //
> +  // Locate WDT_PPI (ICC WDT PPI)
> +  //
> +  gWdtPei = NULL;
> +  Status = PeiServicesLocatePpi(
> +             &gWdtPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &gWdtPei
> +             );
> +
> +  Status = PeiServicesGetBootMode(&BootMode);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  MiscPeiPreMemConfig->S3DataPtr = NULL;
> +  MorControl = 0;
> +  MiscPeiPreMemConfig->UserBd = 0; // It's a CRB mobile board by default
> (btCRBMB)
> +
> +  PcdSetBoolS (PcdMobileDramPresent, (BOOLEAN)
> (MemConfig->MobilePlatform));
> +  MiscPeiPreMemConfig->SpdAddressTable[0] = PcdGet8
> (PcdMrcSpdAddressTable0);
> +  MiscPeiPreMemConfig->SpdAddressTable[1] = PcdGet8
> (PcdMrcSpdAddressTable1);
> +  MiscPeiPreMemConfig->SpdAddressTable[2] = PcdGet8
> (PcdMrcSpdAddressTable2);
> +  MiscPeiPreMemConfig->SpdAddressTable[3] = PcdGet8
> (PcdMrcSpdAddressTable3);
> +  MemConfig->CaVrefConfig                 = PcdGet8 (PcdMrcCaVrefConfig);
> +  MemConfig->DualDimmPerChannelBoardType  = PcdGetBool
> (PcdDualDimmPerChannelBoardType);
> +  if (PcdGet32 (PcdMrcRcompResistor)) {
> +    CopyMem((VOID *)RcompData->RcompResistor, (VOID *) (UINTN)
> PcdGet32 (PcdMrcRcompResistor), sizeof (RcompData->RcompResistor));
> +  }
> +  if (PcdGet32 (PcdMrcRcompTarget)) {
> +    CopyMem((VOID *)RcompData->RcompTarget, (VOID *) (UINTN) PcdGet32
> (PcdMrcRcompTarget), sizeof (RcompData->RcompTarget));
> +  }
> +  if (PcdGet32 (PcdMrcDqByteMap)) {
> +    CopyMem((VOID *)MemConfigNoCrc->DqByteMap, (VOID *) (UINTN)
> PcdGet32 (PcdMrcDqByteMap), sizeof (UINT8)* SA_MC_MAX_CHANNELS *
> SA_MRC_ITERATION_MAX * 2);
> +  }
> +  if (PcdGet32 (PcdMrcDqsMapCpu2Dram)) {
> +    CopyMem((VOID *)MemConfigNoCrc->DqsMap, (VOID *) (UINTN)
> PcdGet32 (PcdMrcDqsMapCpu2Dram), sizeof (UINT8)*
> SA_MC_MAX_CHANNELS * SA_MC_MAX_BYTES_NO_ECC);
> +  }
> +  if (PcdGetBool (PcdMrcDqPinsInterleavedControl)) {
> +    MemConfig->DqPinsInterleaved = PcdGetBool
> (PcdMrcDqPinsInterleaved);
> +  }
> +  if (PcdGet32 (PcdMrcSpdData)) {
> +    CopyMem((VOID *)MemConfigNoCrc->SpdData->SpdData[0][0], (VOID *)
> (UINTN) PcdGet32 (PcdMrcSpdData), SPD_DATA_SIZE);
> +    CopyMem((VOID *)MemConfigNoCrc->SpdData->SpdData[1][0], (VOID *)
> (UINTN) PcdGet32 (PcdMrcSpdData), SPD_DATA_SIZE);
> +  }
> +
> +  MiscPeiPreMemConfig->MchBar   = (UINTN) PcdGet64
> (PcdMchBaseAddress);
> +  MiscPeiPreMemConfig->DmiBar   = (UINTN) PcdGet64
> (PcdDmiBaseAddress);
> +  MiscPeiPreMemConfig->EpBar    = (UINTN) PcdGet64 (PcdEpBaseAddress);
> +  MiscPeiPreMemConfig->EdramBar = (UINTN) PcdGet64
> (PcdEdramBaseAddress);
> +  MiscPeiPreMemConfig->SmbusBar = PcdGet16(PcdSmbusBaseAddress);
> +  MiscPeiPreMemConfig->TsegSize = PcdGet32(PcdTsegSize);
> +  MiscPeiPreMemConfig->UserBd   = PcdGet8 (PcdSaMiscUserBd);
> +  MiscPeiPreMemConfig->MmioSizeAdjustment = PcdGet16
> (PcdSaMiscMmioSizeAdjustment);
> +  if (PcdGetBool (PcdPegGpioResetControl)) {
> +    PciePeiPreMemConfig->PegGpioData.GpioSupport = PcdGetBool
> (PcdPegGpioResetSupoort);
> +  } else {
> +
> +  }
> +  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.GpioPad =
> PcdGet32 (PcdPeg0ResetGpioPad);
> +  PciePeiPreMemConfig->PegGpioData.SaPeg0ResetGpio.Active  =
> PcdGetBool (PcdPeg0ResetGpioActive);
> +
> +  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.GpioPad =
> PcdGet32 (PcdPeg3ResetGpioPad);
> +  PciePeiPreMemConfig->PegGpioData.SaPeg3ResetGpio.Active  =
> PcdGetBool (PcdPeg3ResetGpioActive);
> +
> +  MemConfig->CkeRankMapping = 0xAA;
> +  ///
> +  /// Initialize the VTD Configuration
> +  ///
> +  Vtd->VtdDisable = 0;
> +
> +  MemConfig->RMT = 1;
> +  MemConfig->UserPowerWeightsEn = 0;
> +  MemConfig->RaplLim2WindY = 0x0A;
> +  MemConfig->ExitOnFailure = 1;
> +
> +  MemConfigNoCrc->PlatformMemorySize = PEI_MIN_MEMORY_SIZE +
> TraceHubTotalMemSize + ProcessorTraceTotalMemSize;
> +  DataSize = sizeof (mDefaultMemoryTypeInformation);
> +  CopyMem(MemoryData, mDefaultMemoryTypeInformation, DataSize);
> +
> +  if (BootMode != BOOT_IN_RECOVERY_MODE) {
> +    for (Index = 0; Index < DataSize / sizeof
> (EFI_MEMORY_TYPE_INFORMATION); Index++) {
> +      MemConfigNoCrc->PlatformMemorySize +=
> MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE;
> +    }
> +
> +    OcPreMemConfig->GtMaxOcRatio = 0;
> +    OcPreMemConfig->GtVoltageMode = 0;
> +    OcPreMemConfig->GtVoltageOverride = 0;
> +    OcPreMemConfig->GtExtraTurboVoltage = 0;
> +    OcPreMemConfig->GtVoltageOffset = 0;
> +    OcPreMemConfig->SaVoltageOffset = 0;
> +    OcPreMemConfig->GtusMaxOcRatio = 0;
> +    OcPreMemConfig->GtusVoltageMode = 0;
> +    OcPreMemConfig->GtusVoltageOverride = 0;
> +    OcPreMemConfig->GtusExtraTurboVoltage = 0;
> +    OcPreMemConfig->GtusVoltageOffset = 0;
> +
> +    ///
> +    /// Build the GUID'd HOB for DXE
> +    ///
> +    BuildGuidDataHob (
> +      &gEfiMemoryTypeInformationGuid,
> +      MemoryData,
> +      DataSize
> +      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSiPolicyUpdate.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSiPolicyUpdate.c
> new file mode 100644
> index 0000000000..3efbe2ccbd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdate
> Lib/PeiSiPolicyUpdate.c
> @@ -0,0 +1,168 @@
> +/** @file
> +  This file is SampleCode of the library for Intel Silicon PEI
> +  Platform Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiSiPolicyUpdate.h"
> +#include <MeChipset.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/SiPolicyLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +STATIC SVID_SID_INIT_ENTRY mCdfSsidTablePtr[] = {
> +  //
> +  // SA Device(s)
> +  //
> +  {{{PCI_SVID_OFFSET,    SA_MC_FUN,        SA_MC_DEV,        SA_MC_BUS, 0,
> SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{R_SA_PEG_SS_OFFSET, SA_PEG0_FUN_NUM,  SA_PEG0_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{R_SA_PEG_SS_OFFSET, SA_PEG1_FUN_NUM,  SA_PEG1_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{R_SA_PEG_SS_OFFSET, SA_PEG2_FUN_NUM,  SA_PEG2_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    SA_IGD_FUN_0,     SA_IGD_DEV,       SA_MC_BUS, 0,
> SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    SA_IPU_FUN_NUM,   SA_IPU_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    SA_GNA_FUN_NUM,   SA_GNA_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  //
> +  // PCH Device(s)
> +  //
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LPC,
> PCI_DEVICE_NUMBER_PCH_LPC,           DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_P2SB,
> PCI_DEVICE_NUMBER_PCH_P2SB,          DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_PMC,
> PCI_DEVICE_NUMBER_PCH_PMC,           DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_HDA,
> PCI_DEVICE_NUMBER_PCH_HDA,           DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1,
> PCI_DEVICE_NUMBER_CDF_PCH_SATA_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2,
> PCI_DEVICE_NUMBER_CDF_PCH_SATA_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3,
> PCI_DEVICE_NUMBER_CDF_PCH_SATA_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SMBUS,
> PCI_DEVICE_NUMBER_PCH_SMBUS,         DEFAULT_PCI_BUS_NUMBER_PCH,
> 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SPI,
> PCI_DEVICE_NUMBER_PCH_SPI,           DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_TRACE_HUB,
> PCI_DEVICE_NUMBER_PCH_TRACE_HUB,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_XHCI,
> PCI_DEVICE_NUMBER_PCH_XHCI,          DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_XDCI,
> PCI_DEVICE_NUMBER_PCH_XDCI,          DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_THERMAL,
> PCI_DEVICE_NUMBER_PCH_THERMAL,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +};
> +
> +STATIC SVID_SID_INIT_ENTRY mSsidTablePtr[] = {
> +  //
> +  // SA Device(s)
> +  //
> +  {{{PCI_SVID_OFFSET,    SA_MC_FUN,        SA_MC_DEV,        SA_MC_BUS, 0,
> SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{R_SA_PEG_SS_OFFSET, SA_PEG0_FUN_NUM,  SA_PEG0_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{R_SA_PEG_SS_OFFSET, SA_PEG1_FUN_NUM,  SA_PEG1_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{R_SA_PEG_SS_OFFSET, SA_PEG2_FUN_NUM,  SA_PEG2_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    SA_IGD_FUN_0,     SA_IGD_DEV,       SA_MC_BUS, 0,
> SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    SA_IPU_FUN_NUM,   SA_IPU_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    SA_GNA_FUN_NUM,   SA_GNA_DEV_NUM,
> SA_MC_BUS, 0, SA_SEG_NUM, 0}}, {0, 0},0},
> +  //
> +  // PCH Device(s)
> +  //
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LPC,
> PCI_DEVICE_NUMBER_PCH_LPC,    DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_P2SB,
> PCI_DEVICE_NUMBER_PCH_P2SB,   DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_PMC,
> PCI_DEVICE_NUMBER_PCH_PMC,    DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_HDA,
> PCI_DEVICE_NUMBER_PCH_HDA,    DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SATA,
> PCI_DEVICE_NUMBER_PCH_SATA,   DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SMBUS,
> PCI_DEVICE_NUMBER_PCH_SMBUS,  DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_SPI,
> PCI_DEVICE_NUMBER_PCH_SPI,    DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  //
> +  // Skip PCH LAN controller
> +  // PCH LAN SVID/SID may be loaded automatically from the NVM Word
> 0Ch/0Bh upon power up or reset
> +  // depending on the "Load Subsystem ID" bit field in NVM word 0Ah
> +  //
> +  //{{{PCI_SVID_OFFSET,    PCI_FUNCTION_NUMBER_PCH_LAN,
> PCI_DEVICE_NUMBER_PCH_LAN,    DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_TRACE_HUB,
> PCI_DEVICE_NUMBER_PCH_TRACE_HUB,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_CNL_SCS_SDCARD,
> PCI_DEVICE_NUMBER_PCH_CNL_SCS_SDCARD,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_XHCI,
> PCI_DEVICE_NUMBER_PCH_XHCI,       DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_XDCI,
> PCI_DEVICE_NUMBER_PCH_XDCI,       DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_THERMAL,
> PCI_DEVICE_NUMBER_PCH_THERMAL,    DEFAULT_PCI_BUS_NUMBER_PCH,
> 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_ISH,
> PCI_DEVICE_NUMBER_PCH_ISH,           DEFAULT_PCI_BUS_NUMBER_PCH, 0,
> DEFAULT_PCI_SEGMENT_NUMBER_PCH, 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_9,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_10,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_11,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_12,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_13,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_14,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_15,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_16,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_17,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_18,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_19,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_20,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_21,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_22,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_23,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{R_PCH_PCIE_CFG_SVID,
> PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_24,
> PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4,
> PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  //
> +  // ME Device(s)
> +  //
> +  {{{PCI_SVID_OFFSET,  HECI_FUNCTION_NUMBER,  ME_DEVICE_NUMBER,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  HECI2_FUNCTION_NUMBER, ME_DEVICE_NUMBER,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  IDER_FUNCTION_NUMBER,  ME_DEVICE_NUMBER,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  SOL_FUNCTION_NUMBER,   ME_DEVICE_NUMBER,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  HECI3_FUNCTION_NUMBER, ME_DEVICE_NUMBER,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0},
> +  {{{PCI_SVID_OFFSET,  HECI4_FUNCTION_NUMBER, ME_DEVICE_NUMBER,
> DEFAULT_PCI_BUS_NUMBER_PCH, 0, DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> 0}}, {0, 0},0}
> +};
> +
> +/**
> +  This function performs Silicon PEI Policy initialization.
> +
> +  @param[in] SiPolicy  The Silicon Policy PPI instance
> +
> +  @retval EFI_SUCCESS  The function completed successfully
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSiPolicy (
> +  IN OUT SI_POLICY_PPI *SiPolicy
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  SI_CONFIG                          *SiConfig;
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicy, &gSiConfigGuid, (VOID *)
> &SiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  SiConfig->CsmFlag       = 0;
> +
> +  if (IsCdfPch ()) {
> +    SiConfig->SsidTablePtr = (UINT32*)(UINTN) mCdfSsidTablePtr;
> +    SiConfig->NumberOfSsidTableEntry = (sizeof (mCdfSsidTablePtr) / sizeof
> (SVID_SID_INIT_ENTRY));
> +  } else {
> +    SiConfig->SsidTablePtr = (UINT32*)(UINTN) mSsidTablePtr;
> +    SiConfig->NumberOfSsidTableEntry = (sizeof (mSsidTablePtr) / sizeof
> (SVID_SID_INIT_ENTRY));
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/Ia32/PeiCoreEntry.nasm
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/PeiCoreEntry.nasm
> new file mode 100644
> index 0000000000..5c5b788085
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/PeiCoreEntry.nasm
> @@ -0,0 +1,130 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +; Module Name:
> +;
> +;  PeiCoreEntry.nasm
> +;
> +; Abstract:
> +;
> +;   Find and call SecStartup
> +;
> +;------------------------------------------------------------------------------
> +
> +SECTION .text
> +
> +extern ASM_PFX(SecStartup)
> +extern ASM_PFX(PlatformInit)
> +
> +global ASM_PFX(CallPeiCoreEntryPoint)
> +ASM_PFX(CallPeiCoreEntryPoint):
> +  ;
> +  ; Obtain the hob list pointer
> +  ;
> +  mov     eax, [esp+4]
> +  ;
> +  ; Obtain the stack information
> +  ;   ECX: start of range
> +  ;   EDX: end of range
> +  ;
> +  mov     ecx, [esp+8]
> +  mov     edx, [esp+0xC]
> +
> +  ;
> +  ; Platform init
> +  ;
> +  pushad
> +  push edx
> +  push ecx
> +  push eax
> +  call ASM_PFX(PlatformInit)
> +  pop  eax
> +  pop  eax
> +  pop  eax
> +  popad
> +
> +  ;
> +  ; Set stack top pointer
> +  ;
> +  mov     esp, edx
> +
> +  ;
> +  ; Push the hob list pointer
> +  ;
> +  push    eax
> +
> +  ;
> +  ; Save the value
> +  ;   ECX: start of range
> +  ;   EDX: end of range
> +  ;
> +  mov     ebp, esp
> +  push    ecx
> +  push    edx
> +
> +  ;
> +  ; Push processor count to stack first, then BIST status (AP then BSP)
> +  ;
> +  mov     eax, 1
> +  cpuid
> +  shr     ebx, 16
> +  and     ebx, 0xFF
> +  cmp     bl, 1
> +  jae     PushProcessorCount
> +
> +  ;
> +  ; Some processors report 0 logical processors.  Effectively 0 = 1.
> +  ; So we fix up the processor count
> +  ;
> +  inc     ebx
> +
> +PushProcessorCount:
> +  push    ebx
> +
> +  ;
> +  ; We need to implement a long-term solution for BIST capture.  For now, we
> just copy BSP BIST
> +  ; for all processor threads
> +  ;
> +  xor     ecx, ecx
> +  mov     cl, bl
> +PushBist:
> +  movd    eax, mm0
> +  push    eax
> +  loop    PushBist
> +
> +  ; Save Time-Stamp Counter
> +  movd eax, mm5
> +  push eax
> +
> +  movd eax, mm6
> +  push eax
> +
> +  ;
> +  ; Pass entry point of the PEI core
> +  ;
> +  mov     edi, 0xFFFFFFE0
> +  push    DWORD [edi]
> +
> +  ;
> +  ; Pass BFV into the PEI Core
> +  ;
> +  mov     edi, 0xFFFFFFFC
> +  push    DWORD [edi]
> +
> +  ;
> +  ; Pass stack size into the PEI Core
> +  ;
> +  mov     ecx, [ebp - 4]
> +  mov     edx, [ebp - 8]
> +  push    ecx       ; RamBase
> +
> +  sub     edx, ecx
> +  push    edx       ; RamSize
> +
> +  ;
> +  ; Pass Control into the PEI Core
> +  ;
> +  call ASM_PFX(SecStartup)
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/Ia32/SecEntry.nasm
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/SecEntry.nasm
> new file mode 100644
> index 0000000000..7f6d771e41
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/SecEntry.nasm
> @@ -0,0 +1,361 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +; Module Name:
> +;
> +;  SecEntry.nasm
> +;
> +; Abstract:
> +;
> +;  This is the code that goes from real-mode to protected mode.
> +;  It consumes the reset vector, calls TempRamInit API from FSP binary.
> +;
> +;------------------------------------------------------------------------------
> +
> +#include "Fsp.h"
> +
> +SECTION .text
> +
> +extern   ASM_PFX(CallPeiCoreEntryPoint)
> +extern   ASM_PFX(FsptUpdDataPtr)
> +extern   ASM_PFX(BoardBeforeTempRamInit)
> +; Pcds
> +extern   ASM_PFX(PcdGet32 (PcdFspTemporaryRamSize))
> +extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
> +
> +;----------------------------------------------------------------------------
> +;
> +; Procedure:    _ModuleEntryPoint
> +;
> +; Input:        None
> +;
> +; Output:       None
> +;
> +; Destroys:     Assume all registers
> +;
> +; Description:
> +;
> +;   Transition to non-paged flat-model protected mode from a
> +;   hard-coded GDT that provides exactly two descriptors.
> +;   This is a bare bones transition to protected mode only
> +;   used for a while in PEI and possibly DXE.
> +;
> +;   After enabling protected mode, a far jump is executed to
> +;   transfer to PEI using the newly loaded GDT.
> +;
> +; Return:       None
> +;
> +;  MMX Usage:
> +;              MM0 = BIST State
> +;              MM5 = Save time-stamp counter value high32bit
> +;              MM6 = Save time-stamp counter value low32bit.
> +;
> +;----------------------------------------------------------------------------
> +
> +BITS 16
> +align 4
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +  fninit                                ; clear any pending Floating point exceptions
> +  ;
> +  ; Store the BIST value in mm0
> +  ;
> +  movd    mm0, eax
> +  cli
> +
> +  ;
> +  ; Check INIT# is asserted by port 0xCF9
> +  ;
> +  mov dx, 0CF9h
> +  in  al, dx
> +  cmp al, 04h
> +  jnz NotWarmStart
> +
> +
> +  ;
> +  ; @note Issue warm reset, since if CPU only reset is issued not all MSRs are
> restored to their defaults
> +  ;
> +  mov dx, 0CF9h
> +  mov al, 06h
> +  out dx, al
> +
> +NotWarmStart:
> +  ;
> +  ; Save time-stamp counter value
> +  ; rdtsc load 64bit time-stamp counter to EDX:EAX
> +  ;
> +  rdtsc
> +  movd    mm5, edx
> +  movd    mm6, eax
> +
> +  ;
> +  ; Load the GDT table in GdtDesc
> +  ;
> +  mov     esi,  GdtDesc
> +  DB      66h
> +  lgdt    [cs:si]
> +
> +  ;
> +  ; Transition to 16 bit protected mode
> +  ;
> +  mov     eax, cr0                   ; Get control register 0
> +  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)
> +  mov     cr0, eax                   ; Activate protected mode
> +
> +  mov     eax, cr4                   ; Get control register 4
> +  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit
> (bit #10)
> +  mov     cr4, eax
> +
> +  ;
> +  ; Now we're in 16 bit protected mode
> +  ; Set up the selectors for 32 bit protected mode entry
> +  ;
> +  mov     ax, SYS_DATA_SEL
> +  mov     ds, ax
> +  mov     es, ax
> +  mov     fs, ax
> +  mov     gs, ax
> +  mov     ss, ax
> +
> +  ;
> +  ; Transition to Flat 32 bit protected mode
> +  ; The jump to a far pointer causes the transition to 32 bit mode
> +  ;
> +  mov esi, ProtectedModeEntryLinearAddress
> +  jmp   dword far  [cs:si]
> +
> +;----------------------------------------------------------------------------
> +;
> +; Procedure:    ProtectedModeEntryPoint
> +;
> +; Input:        None
> +;
> +; Output:       None
> +;
> +; Destroys:     Assume all registers
> +;
> +; Description:
> +;
> +; This function handles:
> +;   Call two basic APIs from FSP binary
> +;   Initializes stack with some early data (BIST, PEI entry, etc)
> +;
> +; Return:       None
> +;
> +;----------------------------------------------------------------------------
> +
> +BITS 32
> +align 4
> +ProtectedModeEntryPoint:
> +  ;
> +  ; Early board hooks
> +  ;
> +  mov     esp, BoardBeforeTempRamInitRet
> +  jmp     ASM_PFX(BoardBeforeTempRamInit)
> +
> +BoardBeforeTempRamInitRet:
> +
> +  ; Find the fsp info header
> +  mov  edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]
> +
> +  mov  eax, dword [edi + FVH_SIGINATURE_OFFSET]
> +  cmp  eax, FVH_SIGINATURE_VALID_VALUE
> +  jnz  FspHeaderNotFound
> +
> +  xor  eax, eax
> +  mov  ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]
> +  cmp  ax, 0
> +  jnz  FspFvExtHeaderExist
> +
> +  xor  eax, eax
> +  mov  ax, word [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header
> +  add  edi, eax
> +  jmp  FspCheckFfsHeader
> +
> +FspFvExtHeaderExist:
> +  add  edi, eax
> +  mov  eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv
> Header
> +  add  edi, eax
> +
> +  ; Round up to 8 byte alignment
> +  mov  eax, edi
> +  and  al,  07h
> +  jz   FspCheckFfsHeader
> +
> +  and  edi, 0FFFFFFF8h
> +  add  edi, 08h
> +
> +FspCheckFfsHeader:
> +  ; Check the ffs guid
> +  mov  eax, dword [edi]
> +  cmp  eax, FSP_HEADER_GUID_DWORD1
> +  jnz  FspHeaderNotFound
> +
> +  mov  eax, dword [edi + 4]
> +  cmp  eax, FSP_HEADER_GUID_DWORD2
> +  jnz  FspHeaderNotFound
> +
> +  mov  eax, dword [edi + 8]
> +  cmp  eax, FSP_HEADER_GUID_DWORD3
> +  jnz  FspHeaderNotFound
> +
> +  mov  eax, dword [edi + 0Ch]
> +  cmp  eax, FSP_HEADER_GUID_DWORD4
> +  jnz  FspHeaderNotFound
> +
> +  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header
> +
> +  ; Check the section type as raw section
> +  mov  al, byte [edi + SECTION_HEADER_TYPE_OFFSET]
> +  cmp  al, 019h
> +  jnz FspHeaderNotFound
> +
> +  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
> +  jmp FspHeaderFound
> +
> +FspHeaderNotFound:
> +  jmp  $
> +
> +FspHeaderFound:
> +  ; Get the fsp TempRamInit Api address
> +  mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]
> +  add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
> +
> +  ; Setup the hardcode stack
> +  mov esp, TempRamInitStack
> +
> +  ; Call the fsp TempRamInit Api
> +  jmp eax
> +
> +TempRamInitDone:
> +  cmp eax, 8000000Eh      ;Check if EFI_NOT_FOUND returned. Error code for
> Microcode Update not found.
> +  je  CallSecFspInit      ;If microcode not found, don't hang, but continue.
> +
> +  cmp eax, 0              ;Check if EFI_SUCCESS retuned.
> +  jnz FspApiFailed
> +
> +  ;   ECX: start of range
> +  ;   EDX: end of range
> +CallSecFspInit:
> +  sub     edx, [ASM_PFX(PcdGet32 (PcdFspTemporaryRamSize))] ;
> TemporaryRam for FSP
> +  xor     eax, eax
> +  mov     esp, edx
> +
> +  ; Align the stack at DWORD
> +  add  esp,  3
> +  and  esp, 0FFFFFFFCh
> +
> +  push    edx
> +  push    ecx
> +  push    eax ; zero - no hob list yet
> +  call    ASM_PFX(CallPeiCoreEntryPoint)
> +
> +FspApiFailed:
> +  jmp $
> +
> +align 10h
> +TempRamInitStack:
> +    DD  TempRamInitDone
> +    DD  ASM_PFX(FsptUpdDataPtr); TempRamInitParams
> +
> +;
> +; ROM-based Global-Descriptor Table for the Tiano PEI Phase
> +;
> +align 16
> +global  ASM_PFX(BootGdtTable)
> +
> +;
> +; GDT[0]: 0x00: Null entry, never used.
> +;
> +NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]
> +GDT_BASE:
> +ASM_PFX(BootGdtTable):
> +                    DD  0
> +                    DD  0
> +;
> +; Linear data segment descriptor
> +;
> +LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]
> +    DW  0FFFFh                          ; limit 0xFFFFF
> +    DW  0                               ; base 0
> +    DB  0
> +    DB  092h                            ; present, ring 0, data, expand-up, writable
> +    DB  0CFh                            ; page-granular, 32-bit
> +    DB  0
> +;
> +; Linear code segment descriptor
> +;
> +LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]
> +    DW  0FFFFh                          ; limit 0xFFFFF
> +    DW  0                               ; base 0
> +    DB  0
> +    DB  09Bh                            ; present, ring 0, data, expand-up,
> not-writable
> +    DB  0CFh                            ; page-granular, 32-bit
> +    DB  0
> +;
> +; System data segment descriptor
> +;
> +SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]
> +    DW  0FFFFh                          ; limit 0xFFFFF
> +    DW  0                               ; base 0
> +    DB  0
> +    DB  093h                            ; present, ring 0, data, expand-up,
> not-writable
> +    DB  0CFh                            ; page-granular, 32-bit
> +    DB  0
> +
> +;
> +; System code segment descriptor
> +;
> +SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]
> +    DW  0FFFFh                          ; limit 0xFFFFF
> +    DW  0                               ; base 0
> +    DB  0
> +    DB  09Ah                            ; present, ring 0, data, expand-up, writable
> +    DB  0CFh                            ; page-granular, 32-bit
> +    DB  0
> +;
> +; Spare segment descriptor
> +;
> +SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]
> +    DW  0FFFFh                          ; limit 0xFFFFF
> +    DW  0                               ; base 0
> +    DB  0Eh                             ; Changed from F000 to E000.
> +    DB  09Bh                            ; present, ring 0, code, expand-up, writable
> +    DB  00h                             ; byte-granular, 16-bit
> +    DB  0
> +;
> +; Spare segment descriptor
> +;
> +SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]
> +    DW  0FFFFh                          ; limit 0xFFFF
> +    DW  0                               ; base 0
> +    DB  0
> +    DB  093h                            ; present, ring 0, data, expand-up,
> not-writable
> +    DB  00h                             ; byte-granular, 16-bit
> +    DB  0
> +
> +;
> +; Spare segment descriptor
> +;
> +SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]
> +    DW  0                               ; limit 0
> +    DW  0                               ; base 0
> +    DB  0
> +    DB  0                               ; present, ring 0, data, expand-up, writable
> +    DB  0                               ; page-granular, 32-bit
> +    DB  0
> +GDT_SIZE            EQU $ - GDT_BASE    ; Size, in bytes
> +
> +;
> +; GDT Descriptor
> +;
> +GdtDesc:                                ; GDT descriptor
> +    DW  GDT_SIZE - 1                    ; GDT limit
> +    DD  GDT_BASE                        ; GDT base address
> +
> +
> +ProtectedModeEntryLinearAddress:
> +ProtectedModeEntryLinear:
> +  DD      ProtectedModeEntryPoint  ; Offset of our 32 bit code
> +  DW      LINEAR_CODE_SEL
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWra
> pperPlatformSecLib/Ia32/Stack.nasm
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/Stack.nasm
> new file mode 100644
> index 0000000000..47db32d64c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWr
> apperPlatformSecLib/Ia32/Stack.nasm
> @@ -0,0 +1,72 @@
> +;------------------------------------------------------------------------------
> +;
> +; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +; Abstract:
> +;
> +;   Switch the stack from temporary memory to permanent memory.
> +;
> +;------------------------------------------------------------------------------
> +
> +    SECTION .text
> +
> +;------------------------------------------------------------------------------
> +; VOID
> +; EFIAPI
> +; SecSwitchStack (
> +;   UINT32   TemporaryMemoryBase,
> +;   UINT32   PermanentMemoryBase
> +;   );
> +;------------------------------------------------------------------------------
> +global ASM_PFX(SecSwitchStack)
> +ASM_PFX(SecSwitchStack):
> +    ;
> +    ; Save three register: eax, ebx, ecx
> +    ;
> +    push  eax
> +    push  ebx
> +    push  ecx
> +    push  edx
> +
> +    ;
> +    ; !!CAUTION!! this function address's is pushed into stack after
> +    ; migration of whole temporary memory, so need save it to permanent
> +    ; memory at first!
> +    ;
> +
> +    mov   ebx, [esp + 20]          ; Save the first parameter
> +    mov   ecx, [esp + 24]          ; Save the second parameter
> +
> +    ;
> +    ; Save this function's return address into permanent memory at first.
> +    ; Then, Fixup the esp point to permanent memory
> +    ;
> +    mov   eax, esp
> +    sub   eax, ebx
> +    add   eax, ecx
> +    mov   edx, dword [esp]         ; copy pushed register's value to permanent
> memory
> +    mov   dword [eax], edx
> +    mov   edx, dword [esp + 4]
> +    mov   dword [eax + 4], edx
> +    mov   edx, dword [esp + 8]
> +    mov   dword [eax + 8], edx
> +    mov   edx, dword [esp + 12]
> +    mov   dword [eax + 12], edx
> +    mov   edx, dword [esp + 16]    ; Update this function's return address into
> permanent memory
> +    mov   dword [eax + 16], edx
> +    mov   esp, eax                     ; From now, esp is pointed to permanent
> memory
> +
> +    ;
> +    ; Fixup the ebp point to permanent memory
> +    ;
> +    mov   eax, ebp
> +    sub   eax, ebx
> +    add   eax, ecx
> +    mov   ebp, eax                ; From now, ebp is pointed to permanent
> memory
> +
> +    pop   edx
> +    pop   ecx
> +    pop   ebx
> +    pop   eax
> +    ret
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.uni
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.uni
> new file mode 100644
> index 0000000000..33b4be68db
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpi
> TimerLib.uni
> @@ -0,0 +1,15 @@
> +/** @file
> +  Base ACPI Timer Library
> +  Provides basic timer support using the ACPI timer hardware.  The
> performance
> +  counter features are provided by the processors time stamp counter.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "ACPI Timer
> Library"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "Provides basic
> timer support using the ACPI timer hardware."
> +
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:16   ` Chiu, Chasel
  2019-08-17 20:11   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:16 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 36/37]
> WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> Adds the DSC and build files necessary to build the
> WhiskeylakeURvp board instance.
> 
> Key files
> =========
> * build_config.cfg - Board-specific build configuration file.
> * OpenBoardPkg.dsc - The WhiskeylakeURvp board description file.
> * OpenBoardPkgConfig.dsc - Used for feature-related PCD
>   customization.
> * OpenBoardPkgPcd.dsc - Used for other PCD customization.
> * OpenBoardPkg.fdf - The WhiskeylakeURvp board flash file.
> * FlashMapInclude.fdf - The WhiskeylakeURvp board flash map.
> * OpenBoardPkgBuildOption.dsc - Sets build options Based
>   on PCD values.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg
> .dsc                | 385 +++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg
> BuildOption.dsc     | 154 +++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg
> Config.dsc          | 128 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg
> Pcd.dsc             | 245 +++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/Fla
> shMapInclude.fdf |  49 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg
> .fdf                | 706 ++++++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cf
> g                |  33 +
>  7 files changed, 1700 insertions(+)
> 
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kg.dsc
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kg.dsc
> new file mode 100644
> index 0000000000..eea809140c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kg.dsc
> @@ -0,0 +1,385 @@
> +## @file
> +#  Platform description.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  #
> +  # Set platform specific package/folder name, same as passed from PREBUILD
> script.
> +  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as
> package build folder
> +  # DEFINE only takes effect at R9 DSC and FDF.
> +  #
> +  DEFINE      PLATFORM_PACKAGE          = MinPlatformPkg
> +  DEFINE      PLATFORM_SI_PACKAGE       = CoffeelakeSiliconPkg
> +  DEFINE      PLATFORM_SI_BIN_PACKAGE   = CoffeelakeSiliconBinPkg
> +  DEFINE      PLATFORM_FSP_BIN_PACKAGE  = CoffeeLakeFspBinPkg
> +  DEFINE      PLATFORM_BOARD_PACKAGE    = WhiskeylakeOpenBoardPkg
> +  DEFINE      BOARD                     = WhiskeylakeURvp
> +  DEFINE      PROJECT                   =
> $(PLATFORM_BOARD_PACKAGE)/$(BOARD)
> +
> +  #
> +  # Platform On/Off features are defined here
> +  #
> +  !include OpenBoardPkgConfig.dsc
> +
> +###############################################################
> #################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +###############################################################
> #################
> +[Defines]
> +  PLATFORM_NAME                       = $(PLATFORM_PACKAGE)
> +  PLATFORM_GUID                       =
> 84D0F5BD-0EF3-4CC0-9B09-F2D0F2AA5C5E
> +  PLATFORM_VERSION                    = 0.1
> +  DSC_SPECIFICATION                   = 0x00010005
> +  OUTPUT_DIRECTORY                    = Build/$(PROJECT)
> +  SUPPORTED_ARCHITECTURES             = IA32|X64
> +  BUILD_TARGETS                       = DEBUG|RELEASE
> +  SKUID_IDENTIFIER                    = ALL
> +
> +
> +  FLASH_DEFINITION                    = $(PROJECT)/OpenBoardPkg.fdf
> +
> +  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
> +  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
> +
> +  #
> +  # Default value for OpenBoardPkg.fdf use
> +  #
> +  DEFINE BIOS_SIZE_OPTION = SIZE_70
> +
> +###############################################################
> #################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this
> +#                              Platform.
> +#
> +###############################################################
> #################
> +[SkuIds]
> +  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always
> required.
> +  0x60|WhiskeylakeURvp
> +
> +###############################################################
> #################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +###############################################################
> #################
> +
> +  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreCommonLib.dsc
> +  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiLib.dsc
> +  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeLib.dsc
> +
> +[LibraryClasses.common]
> +
> +  PeiLib|$(PLATFORM_PACKAGE)/Library/PeiLib/PeiLib.inf
> +
> ReportFvLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/PeiReportFvLib/Pe
> iReportFvLib.inf
> +
> +
> PciHostBridgeLib|$(PLATFORM_PACKAGE)/Pci/Library/PciHostBridgeLibSimpl
> e/PciHostBridgeLibSimple.inf
> +
> PciSegmentInfoLib|$(PLATFORM_PACKAGE)/Pci/Library/PciSegmentInfoLibSi
> mple/PciSegmentInfoLibSimple.inf
> +
> PlatformBootManagerLib|$(PLATFORM_PACKAGE)/Bds/Library/DxePlatformB
> ootManagerLib/DxePlatformBootManagerLib.inf
> +
> I2cAccessLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiI2cAccessLib/PeiI2c
> AccessLib.inf
> +
> GpioExpanderLib|$(PLATFORM_BOARD_PACKAGE)/Library/BaseGpioExpand
> erLib/BaseGpioExpanderLib.inf
> +
> +
> PlatformHookLib|$(PROJECT)/Library/BasePlatformHookLib/BasePlatformHo
> okLib.inf
> +
> +
> FspWrapperHobProcessLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/Pei
> FspWrapperHobProcessLib/PeiFspWrapperHobProcessLib.inf
> +
> PlatformSecLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/SecFsp
> WrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
> +
> +
> FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/Ba
> seFspWrapperApiLib.inf
> +
> FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestL
> ib/PeiFspWrapperApiTestLib.inf
> +
> +
> FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFsp
> WrapperPlatformLib/PeiFspWrapperPlatformLib.inf
> +
> SiliconPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library
> /PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
> +
> +
> ConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseConfigBlockLib/Base
> ConfigBlockLib.inf
> +
> BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/BoardInitLibNull/
> BoardInitLibNull.inf
> +
> TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLibN
> ull/TestPointCheckLibNull.inf
> +
> +  # Tbt
> +  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
> +
> TbtCommonLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiDx
> eSmmTbtCommonLib/TbtCommonLib.inf
> +  !endif
> +
> DxeTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/DxeT
> btPolicyLib/DxeTbtPolicyLib.inf
> +  #
> +  # Silicon Init Package
> +  #
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
> +
> PchHsioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchHsioLib/P
> eiDxeSmmPchHsioLib.inf
> +
> MmPciLib|$(PLATFORM_SI_PACKAGE)/Library/PeiDxeSmmMmPciLib/PeiDxeS
> mmMmPciLib.inf
> +
> PchPmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPmcLib/Pe
> iDxeSmmPchPmcLib.inf
> +
> +
> TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTim
> erLib.inf
> +
> +[LibraryClasses.IA32]
> +  #
> +  # PEI phase common
> +  #
> +
> SiliconPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/Pei
> FspPolicyInitLib/PeiFspPolicyInitLib.inf
> +
> FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFsp
> WrapperPlatformLib/PeiFspWrapperPlatformLib.inf
> +  !if $(TARGET) == DEBUG
> +
> TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/P
> eiTestPointCheckLib.inf
> +  !endif
> +
> TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/PeiTestPointL
> ib.inf
> +
> MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/Mult
> iBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
> +
> BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSu
> pportLib/PeiMultiBoardInitSupportLib.inf
> +
> TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTim
> erLib.inf
> +
> HdaVerbTableLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiHdaVerbTableL
> ib/PeiHdaVerbTableLib.inf
> +
> +  # Tbt
> +  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
> +
> PeiTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiTb
> tPolicyLib/PeiTbtPolicyLib.inf
> +
> PeiDTbtInitLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/Private
> /PeiDTbtInitLib/PeiDTbtInitLib.inf
> +  !endif
> +
> +  #
> +  # Silicon Init Package
> +  #
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
> +
> PeiPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyInitL
> ib/PeiPolicyInitLib.inf
> +
> PeiPolicyBoardConfigLib|$(PROJECT)/Library/PeiPolicyBoardConfigLib/PeiPoli
> cyBoardConfigLib.inf
> +
> PeiPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicy
> UpdateLib/PeiPolicyUpdateLib.inf
> +
> PeiPlatformHookLib|$(PROJECT)/Library/PeiPlatformHookLib/PeiPlatformHo
> oklib.inf
> +  !if $(TARGET) == DEBUG
> +
> GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLib/BaseGp
> ioCheckConflictLib.inf
> +  !else
> +
> GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLibNull/Bas
> eGpioCheckConflictLibNull.inf
> +  !endif
> +
> +[LibraryClasses.IA32.SEC]
> +
> TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/S
> ecTestPointCheckLib.inf
> +
> SecBoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/SecBoardInitLi
> bNull/SecBoardInitLibNull.inf
> +
> TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTim
> erLib.inf
> +
> +[LibraryClasses.X64]
> +  #
> +  # DXE phase common
> +  #
> +
> FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/DxeFs
> pWrapperPlatformLib/DxeFspWrapperPlatformLib.inf
> +  !if $(TARGET) == DEBUG
> +
> TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/D
> xeTestPointCheckLib.inf
> +  !endif
> +
> TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/DxeTestPoint
> Lib.inf
> +
> MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/Mult
> iBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
> +
> BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSu
> pportLib/DxeMultiBoardInitSupportLib.inf
> +
> MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoard
> AcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
> +
> BoardAcpiTableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSup
> portLib/DxeMultiBoardAcpiSupportLib.inf
> +
> +
> DxePolicyBoardConfigLib|$(PROJECT)/Library/DxePolicyBoardConfigLib/DxeP
> olicyBoardConfigLib.inf
> +
> DxePolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/DxePolic
> yUpdateLib/DxePolicyUpdateLib.inf
> +  #
> +  # Silicon Init Package
> +  #
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxeLib.dsc
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.i
> nf
> +
> +[LibraryClasses.X64.DXE_SMM_DRIVER]
> +
> SpiFlashCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/SmmSpiFlashCo
> mmonLib/SmmSpiFlashCommonLib.inf
> +  !if $(TARGET) == DEBUG
> +
> TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/S
> mmTestPointCheckLib.inf
> +  !endif
> +
> TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/SmmTestPoin
> tLib.inf
> +
> MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoard
> AcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
> +
> BoardAcpiEnableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSu
> pportLib/SmmMultiBoardAcpiSupportLib.inf
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.i
> nf
> +
> +[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
> +
> ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeRuntimeResetSy
> stemLib/DxeRuntimeResetSystemLib.inf
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.i
> nf
> +  !include OpenBoardPkgPcd.dsc
> +
> +[Components.IA32]
> +  #
> +  # Common
> +  #
> +  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiInclude.dsc
> +
> +  #
> +  # FSP wrapper SEC Core
> +  #
> +  UefiCpuPkg/SecCore/SecCore.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  #
> +  # Silicon
> +  #
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgPei.dsc
> +
> +  #
> +  # Platform
> +  #
> +  $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
> +
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.in
> f {
> +    <LibraryClasses>
> +      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
> +
> BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
> +      !else
> +
> NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
> +      !endif
> +      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
> +  }
> +  IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
> +
> $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMe
> m.inf {
> +    <LibraryClasses>
> +
> SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLib
> Null/SiliconPolicyInitLibNull.inf
> +
> SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUp
> dateLibNull/SiliconPolicyUpdateLibNull.inf
> +  }
> +
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.i
> nf {
> +    <LibraryClasses>
> +      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
> +
> BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
> +      !else
> +
> NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
> +      !endif
> +  }
> +  IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
> +#to do
> $(PLATFORM_PACKAGE)/FspWrapper/FspWrapperPeim/FspWrapperPeim.inf
> +
> $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMe
> m.inf {
> +    <LibraryClasses>
> +
> SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLib
> Null/SiliconPolicyInitLibNull.inf
> +
> SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUp
> dateLibNull/SiliconPolicyUpdateLibNull.inf
> +  }
> +
> +  #
> +  # Security
> +  #
> +
> +  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
> +    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
> +  !endif
> +
> +  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> +
> IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam
> plePei.inf
> +
> +  # Tbt
> +  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
> +    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
> +  !endif
> +
> +[Components.X64]
> +
> +  #
> +  # Common
> +  #
> +  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeInclude.dsc
> +
> +  $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> +
> +  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
> +  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +
> MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.
> inf
> +  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
> +  #
> +  # Shell
> +  #
> +  ShellPkg/Application/Shell/Shell.inf {
> +   <PcdsFixedAtBuild>
> +     gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +   <LibraryClasses>
> +
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comm
> andsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Com
> mandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1C
> ommandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2C
> ommandsLib.inf
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellComma
> ndLib.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsing
> Lib.inf
> +
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgC
> ommandLib.inf
> +
> ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
> +     ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> +  }
> +
> +  #
> +  # Silicon
> +  #
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxe.dsc
> +
> +  # Tbt
> +  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
> +    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
> +    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
> +    $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
> +  !endif
> +
> +  #
> +  # Platform
> +  #
> +  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf{
> +    <LibraryClasses>
> +      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
> +  }
> +
> +  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf
> {
> +    <LibraryClasses>
> +
> SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLib
> Null/SiliconPolicyInitLibNull.inf
> +
> SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUp
> dateLibNull/SiliconPolicyUpdateLibNull.inf
> +  }
> +  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
> +  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
> +
> +
> $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfi
> g.inf
> +
> +  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
> +  $(PLATFORM_PACKAGE)/Test/TestPointDumpApp/TestPointDumpApp.inf
> +
> +  #
> +  # OS Boot
> +  #
> +  !if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> +    $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
> +  $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
> +  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf {
> +    <LibraryClasses>
> +      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
> +
> BoardAcpiEnableLib|$(PROJECT)/Library/BoardAcpiLib/SmmBoardAcpiEnabl
> eLib.inf
> +      !else
> +
> NULL|$(PROJECT)/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
> +      !endif
> +  }
> +
> +  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
> +
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
> +
> +  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
> +    <PcdsPatchableInModule>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
> +    <LibraryClasses>
> +      !if $(TARGET) == DEBUG
> +
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.i
> nf
> +      !endif
> +  }
> +
> +  !endif
> +
> +  #
> +  # Security
> +  #
> +  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
> +
> +  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
> +    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
> +  !endif
> +
> +  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
> +
> +  #
> +  # Other
> +  #
> +  $(PLATFORM_SI_BIN_PACKAGE)/Microcode/MicrocodeUpdates.inf
> +
> +  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
> +  !include OpenBoardPkgBuildOption.dsc
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgBuildOption.dsc
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgBuildOption.dsc
> new file mode 100644
> index 0000000000..be1d47c719
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgBuildOption.dsc
> @@ -0,0 +1,154 @@
> +## @file
> +# platform build option configuration file.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[BuildOptions]
> +# Define Build Options both for EDK and EDKII drivers.
> +
> +
> +  DEFINE DSC_S3_BUILD_OPTIONS =
> +
> +  DEFINE DSC_CSM_BUILD_OPTIONS =
> +
> +!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
> +  DEFINE DSC_ACPI_BUILD_OPTIONS = -DACPI_SUPPORT=1
> +!else
> +  DEFINE DSC_ACPI_BUILD_OPTIONS =
> +!endif
> +
> +  DEFINE BIOS_GUARD_BUILD_OPTIONS =
> +
> +  DEFINE OVERCLOCKING_BUILD_OPTION =
> +
> +  DEFINE FSP_BINARY_BUILD_OPTIONS =
> +
> +  DEFINE FSP_WRAPPER_BUILD_OPTIONS = -DFSP_WRAPPER_FLAG
> +
> +  DEFINE SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS =
> +
> +  DEFINE RESTRICTED_OPTION =
> +
> +
> +  DEFINE SV_BUILD_OPTIONS =
> +
> +  DEFINE TEST_MENU_BUILD_OPTION =
> +
> +!if gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable == FALSE
> +  DEFINE OPTIMIZE_DISABLE_OPTIONS = -Od -GL-
> +!else
> +  DEFINE OPTIMIZE_DISABLE_OPTIONS =
> +!endif
> +
> +  DEFINE UP_SERVER_SUPPORT_BUILD_OPTIONS =
> +
> +
> +  DEFINE TPM_BUILD_OPTION =
> +
> +  DEFINE TPM2_BUILD_OPTION =
> +
> +  DEFINE DSC_TBT_BUILD_OPTIONS =
> +
> +  DEFINE DSC_DCTT_BUILD_OPTIONS =
> +
> +  DEFINE EMB_BUILD_OPTIONS =
> +
> +  DEFINE DSC_MEMORY_DOWN_BUILD_OPTIONS = -DMEM_DOWN_FLAG=1
> +
> +  DEFINE DSC_KBCEMUL_BUILD_OPTIONS =
> +
> +  DEFINE BOOT_GUARD_BUILD_OPTIONS =
> +
> +  DEFINE SECURE_BOOT_BUILD_OPTIONS =
> +
> +  DEFINE USBTYPEC_BUILD_OPTION =
> +
> +  DEFINE CAPSULE_BUILD_OPTIONS =
> +
> +  DEFINE PERFORMANCE_BUILD_OPTION =
> +
> +  DEFINE DEBUGUSEUSB_BUILD_OPTION =
> +
> +  DEFINE DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION =
> -DDISABLE_NEW_DEPRECATED_INTERFACES=1
> +
> +  DEFINE SINITBIN_BUILD_OPTION =
> +
> +  DEFINE MINTREE_FLAG_BUILD_OPTION = -DMINTREE_FLAG=1
> +
> +  DEFINE CPUTYPE_BUILD_OPTION = -DCPU_CFL=1
> +
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)  $(OVERCLOCKING_BUILD_OPTION)
> $(PERFORMANCE_BUILD_OPTION) $(EMB_BUILD_OPTIONS)
> $(BIOS_GUARD_BUILD_OPTIONS) $(DSC_TBT_BUILD_OPTIONS)
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(BOOT_GUARD_BUILD_OPTIONS)
> $(DSC_MEMORY_DOWN_BUILD_OPTIONS) $(DEBUGUSEUSB_BUILD_OPTION)
> $(DSC_S3_BUILD_OPTIONS)
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(FSP_BINARY_BUILD_OPTIONS)
> $(FSP_WRAPPER_BUILD_OPTIONS)
> $(SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS)
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_KBCEMUL_BUILD_OPTIONS)
> $(CAPSULE_BUILD_OPTIONS) $(SECURE_BOOT_BUILD_OPTIONS)
> $(DSC_CSM_BUILD_OPTIONS)
> $(DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION)
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(TPM2_BUILD_OPTION)
> $(TPM_BUILD_OPTION) $(DSC_DCTT_BUILD_OPTIONS)
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS)
> $(UP_SERVER_SUPPORT_BUILD_OPTIONS) $(USBTYPEC_BUILD_OPTION)
> $(SINITBIN_BUILD_OPTION) $(MINTREE_FLAG_BUILD_OPTION)
> +DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(CPUTYPE_BUILD_OPTION)
> +[BuildOptions.Common.EDKII]
> +
> +#
> +# For IA32 Global Build Flag
> +#
> +       *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D
> PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
> +       *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_IA32_NASM_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +
> +#
> +# For IA32 Specific Build Flag
> +#
> +GCC:   *_*_IA32_PP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +MSFT:  *_*_IA32_ASM_FLAGS     =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +MSFT:  *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
> -DASF_PEI
> +MSFT:  *_*_IA32_VFRPP_FLAGS   =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
> +MSFT:  *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> $(OPTIMIZE_DISABLE_OPTIONS)
> +MSFT:  *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> $(OPTIMIZE_DISABLE_OPTIONS)
> +MSFT:  *_*_IA32_ASLCC_FLAGS   =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
> +
> +#
> +# For X64 Global Build Flag
> +#
> +       *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D
> PI_SPECIFICATION_VERSION=0x00010015
> +       *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +       *_*_X64_NASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +
> +
> +#
> +# For X64 Specific Build Flag
> +#
> +GCC:   *_*_X64_PP_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +MSFT:  *_*_X64_ASM_FLAGS      =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +MSFT:  *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
> +MSFT:  *_*_X64_VFRPP_FLAGS    =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
> +MSFT:  *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> $(OPTIMIZE_DISABLE_OPTIONS)
> +MSFT:  *_*_X64_ASLPP_FLAGS    =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +MSFT:  *_*_X64_ASLCC_FLAGS    =
> $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
> +
> +
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page
> level protection
> +[BuildOptions.common.EDKII.DXE_SMM_DRIVER,
> BuildOptions.common.EDKII.SMM_CORE]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support
> MemoryAttribute table
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support NX
> protection
> +[BuildOptions.common.EDKII.DXE_DRIVER,
> BuildOptions.common.EDKII.DXE_CORE,
> BuildOptions.common.EDKII.UEFI_DRIVER,
> BuildOptions.common.EDKII.UEFI_APPLICATION]
> +  #MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  #GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgConfig.dsc
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgConfig.dsc
> new file mode 100644
> index 0000000000..c68fecf50e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgConfig.dsc
> @@ -0,0 +1,128 @@
> +## @file
> +#  Platform configuration file.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[PcdsFixedAtBuild]
> +  #
> +  # Please select BootStage here.
> +  # Stage 1 - enable debug (system deadloop after debug init)
> +  # Stage 2 - mem init (system deadloop after mem init)
> +  # Stage 3 - boot to shell only
> +  # Stage 4 - boot to OS
> +  # Stage 5 - boot to OS with security boot enabled
> +  #
> +  gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4
> +
> +[PcdsFeatureFlag]
> +  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
> +  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
> +  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
> +  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE
> +  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 1
> +  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 2
> +  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
> +  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 3
> +  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
> +  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 4
> +  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 5
> +  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE
> +  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
> +!endif
> +
> +  gBoardModuleTokenSpaceGuid.PcdTbtEnable|FALSE
> +  #
> +  # More fine granularity control below:
> +  #
> +
> +  gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport|TRUE
> +
> +#
> +# TRUE is ENABLE. FALSE is DISABLE.
> +#
> +#
> +# BIOS build switches configuration
> +#
> +  gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
> +
> +# CPU
> +  gSiPkgTokenSpaceGuid.PcdSourceDebugEnable|FALSE
> +
> +# SA
> +  gSiPkgTokenSpaceGuid.PcdIgdEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdPegEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSgEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSaDmiEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSaOcEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdVtdEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable|TRUE
> +
> +# ME
> +  gSiPkgTokenSpaceGuid.PcdAtaEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdPttEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdJhiEnable|TRUE
> +
> +  gSiPkgTokenSpaceGuid.PcdAcpiEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdBdatEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSiCsmEnable|FALSE
> +  gSiPkgTokenSpaceGuid.PcdTraceHubEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdPpmEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdS3Enable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSmbiosEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSmmVariableEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdUseHpetTimer|TRUE                       # TRUE -
> HPET / FALSE - 8254 timer is used.
> +  gSiPkgTokenSpaceGuid.PcdOcWdtEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable|FALSE
> +
> +  gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdCflCpuEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdIpuEnable|TRUE
> +  gSiPkgTokenSpaceGuid.PcdGnaEnable|TRUE
> +
> +#
> +# Override some PCDs for specific build requirements.
> +#
> +  #
> +  # Disable USB debug message when Source Level Debug is enabled
> +  # because they cannot be enabled at the same time.
> +  #
> +
> +    gSiPkgTokenSpaceGuid.PcdPttEnable|FALSE
> +
> +  !if $(TARGET) == DEBUG
> +    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
> +  !else
> +    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
> +  !endif
> +
> +  !if $(TARGET) == DEBUG
> +    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE
> +  !else
> +    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE
> +  !endif
> +
> +    gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgPcd.dsc
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgPcd.dsc
> new file mode 100644
> index 0000000000..96d65133ae
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kgPcd.dsc
> @@ -0,0 +1,245 @@
> +## @file
> +#  Platform description.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +###############################################################
> #################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +###############################################################
> #################
> +[PcdsFeatureFlag.common]
> +
> #gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport|T
> RUE
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSection
> First|FALSE
> +!if $(TARGET) == RELEASE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +!else
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
> +!endif
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
> +
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable|FALSE
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
> +
> +  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable|TRUE
> +
> +[PcdsFixedAtBuild.common]
> +  gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode|TRUE
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|140
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable == TRUE
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1
> +!endif
> +
> +  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|2
> +  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|8
> +  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|1
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
> +  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
> +  gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
> +  gSiPkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
> +  gSiPkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
> +  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF00000
> +  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
> +
> +  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize        |
> 0x00026000
> +
> +  gSiPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x20000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x5000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x40
> 0
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALS
> E
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +!endif
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(T
> OP_MEMORY_ADDRESS)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x20000
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe|TR
> UE
> +
> +#
> +# 8MB Default
> +#
> +gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000
> +
> +#
> +# 16MB TSEG in Debug build only.
> +#
> +!if $(TARGET) == DEBUG
> +  gSiPkgTokenSpaceGuid.PcdTsegSize|0x1000000
> +!endif
> +
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber|0x0
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber|0x1F
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber|0x2
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x44
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask|0x80
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset|0x00
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress|0x1800
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset|0x08
> +  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask|0xFFFC
> +
> +  !if $(TARGET) == RELEASE
> +
> gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x402
> +  !else
> +
> gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x188
> B
> +  !endif
> +
> +
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize|0x4b
> +  !if $(TARGET) == RELEASE
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0x70
> +  !else
> +  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0xE0
> +  !endif
> +
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress|0xFFEAC000
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress|0xFFDC0000
> +
> +  ## Specifies the size of the microcode Region.
> +  # @Prompt Microcode Region size.
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0
> +
> +  ## Specifies timeout value in microseconds for the BSP to detect all APs for
> the first time.
> +  # @Prompt Timeout for the BSP to detect all APs for the first time.
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|1000
> +
> +  ## 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
> +
> +
> +  #
> +  # The PCDs are used to control the Windows SMM Security Mitigations Table
> - Protection Flags
> +  #
> +  # BIT0: If set, expresses that for all synchronous SMM entries,SMM will
> validate that input and output buffers lie entirely within the expected fixed
> memory regions.
> +  # BIT1: If set, expresses that for all synchronous SMM entries, SMM will
> validate that input and output pointers embedded within the fixed
> communication buffer only refer to address ranges \
> +  #       that lie entirely within the expected fixed memory regions.
> +  # BIT2: Firmware setting this bit is an indication that it will not allow
> reconfiguration of system resources via non-architectural mechanisms.
> +  # BIT3-31: Reserved
> +  #
> +  gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags|0x07
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 1
> +  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03,
> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00}
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 2
> +  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03,
> 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00}
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 3
> +  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03,
> 0x07, 0x03, 0x05, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00}
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 4
> +  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03,
> 0x07, 0x03, 0x05, 0x1F, 0x00, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00}
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 5
> +  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03,
> 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00}
> +!endif
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 6
> +  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03,
> 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> 0x00}
> +!endif
> +
> +[PcdsFixedAtBuild.IA32]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
> +  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00148
> +  gMinPlatformPkgTokenSpaceGuid.PcdPeiPhaseStackTop|0xA0000
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x3800000
> +
> +[PcdsFixedAtBuild.X64]
> +  # Default platform supported RFC 4646 languages: (American) English
> +
> gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en-
> US"
> +
> +
> +[PcdsPatchableInModule.common]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
> +
> +!if $(TARGET) == DEBUG
> +  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable|1
> +!endif
> +
> +[PcdsDynamicHii.X64.DEFAULT]
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGloba
> lVariableGuid|0x0|5 # Variable: L"Timeout"
> +
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupp
> ort"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGloba
> lVariableGuid|0x0|1 # Variable: L"Timeout"
> +!endif
> +
> +[PcdsDynamicDefault]
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0xFFD50000
> +  # Platform will pre-allocate UPD buffer and pass it to FspWrapper
> +  # Those dummy address will be patched before FspWrapper executing
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress|0x0
> +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress|0x0
> +
> +  ## Specifies max supported number of Logical Processors.
> +  # @Prompt Configure max supported number of Logical Processors
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|16
> +
> +[PcdsDynamicDefault.common.DEFAULT]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAtaSmartEnable|TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE
> +  #
> +  #  Set video to native resolution as Windows 8 WHCK requirement.
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0x0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0x0
> +
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
> +
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum|0x00
> +
> +[PcdsDynamicDefault.common.DEFAULT]
> +
> +  # Tbt
> +  gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel | 0x1
> +  gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad | 13
> +  gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad |
> 0x02010011
> +  gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport | 0x0
> +  gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI | 0x1
> +  gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify | 0x1
> +  gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq| 0x1
> +  gBoardModuleTokenSpaceGuid.PcdDTbtAspm | 0x0
> +  gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch | 0x0
> +
> +  gBoardModuleTokenSpaceGuid.PcdRtd3Tbt | 0x1
> +  gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq | 0x1
> +  gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax | 26
> +  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd | 100
> +  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax | 28
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/
> FlashMapInclude.fdf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/
> FlashMapInclude.fdf
> new file mode 100644
> index 0000000000..9209b9e88a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/
> FlashMapInclude.fdf
> @@ -0,0 +1,49 @@
> +## @file
> +#  FDF file of Platform.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +#==============================================================
> ===================#
> +# 8 M BIOS - for FSP wrapper
> +#==============================================================
> ===================#
> +DEFINE FLASH_BASE                                                   = 0xFF800000  #
> +DEFINE FLASH_SIZE                                                   = 0x00800000  #
> +DEFINE FLASH_BLOCK_SIZE                                             = 0x00010000  #
> +DEFINE FLASH_NUM_BLOCKS                                             = 0x00000080
> #
> +#==============================================================
> ===================#
> +
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageOffset           =
> 0x00000000  # Flash addr (0xFF800000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize             =
> 0x00040000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset   =
> 0x00000000  # Flash addr (0xFF800000)
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize    =
> 0x0001E000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset
> = 0x0001E000  # Flash addr (0xFF81E000)
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> = 0x00002000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset   =
> 0x00020000  # Flash addr (0xFF820000)
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> = 0x00020000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset          =
> 0x00040000  # Flash addr (0xFF840000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            =
> 0x00060000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset          =
> 0x000A0000  # Flash addr (0xFF8A0000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            =
> 0x00070000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset            =
> 0x00110000  # Flash addr (0xFF910000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              =
> 0x00090000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset          =
> 0x001A0000  # Flash addr (0xFF9A0000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            =
> 0x00190000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset        =
> 0x00330000  # Flash addr (0xFFB30000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          =
> 0x00170000  #
> +SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset                  =
> 0x004A0000  # Flash addr (0xFFCA0000)
> +SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                    =
> 0x000B0000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset              =
> 0x00550000  # Flash addr (0xFFD50000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize                =
> 0x00070000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset              =
> 0x005C0000  # Flash addr (0xFFDC0000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                =
> 0x000EC000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset              =
> 0x006AC000  # Flash addr (0xFFEAC000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                =
> 0x00014000  #
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset         =
> 0x006C0000  # Flash addr (0xFFEC0000)
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           =
> 0x00140000  #
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kg.fdf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kg.fdf
> new file mode 100644
> index 0000000000..611078e4b4
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardP
> kg.fdf
> @@ -0,0 +1,706 @@
> +## @file
> +#  FDF file of Platform.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +   !include $(PROJECT)/Include/Fdf/FlashMapInclude.fdf
> +
> +###############################################################
> #################
> +#
> +# FD Section
> +# The [FD] Section is made up of the definition statements and a
> +# description of what goes into  the Flash Device Image.  Each FD section
> +# defines one flash "device" image.  A flash device image may be one of
> +# the following: Removable media bootable image (like a boot floppy
> +# image,) an Option ROM image (that would be "flashed" into an add-in
> +# card,) a System "Flash"  image (that would be burned into a system's
> +# flash) or an Update ("Capsule") image that will be used to update and
> +# existing system flash.
> +#
> +###############################################################
> #################
> +[FD.WhiskeylakeURvp]
> +#
> +# FD Tokens, BaseAddress, Size, ErasePolarity, BlockSize, and NumBlocks,
> cannot be
> +# assigned with PCD values. Instead, it uses the definitions for its variety,
> which
> +# are FLASH_BASE, FLASH_SIZE, FLASH_BLOCK_SIZE and
> FLASH_NUM_BLOCKS.
> +#
> +BaseAddress   = $(FLASH_BASE) |
> gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress      #The base address of the
> FLASH Device.
> +Size          = $(FLASH_SIZE) | gSiPkgTokenSpaceGuid.PcdBiosSize
> #The size in bytes of the FLASH Device
> +ErasePolarity = 1
> +BlockSize     = $(FLASH_BLOCK_SIZE)
> +NumBlocks     = $(FLASH_NUM_BLOCKS)
> +
> +DEFINE SIPKG_DXE_SMM_BIN  = INF
> +DEFINE SIPKG_PEI_BIN      = INF
> +
> +# Set FLASH_REGION_FV_RECOVERY_OFFSET to PcdNemCodeCacheBase,
> because macro expression is not supported.
> +# So, PlatformSecLib uses PcdBiosAreaBaseAddress +
> PcdNemCodeCacheBase to get the real CodeCache base address.
> +SET gSiPkgTokenSpaceGuid.PcdNemCodeCacheBase =
> $(gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset)
> +SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase =
> $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) +
> $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
> +SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize =
> $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
> +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress =
> $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase) + 0x60
> +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize =
> $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize) - 0x60
> +SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress =
> $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) +
> $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
> +SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize =
> $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
> +SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset = 0x60
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase    =
> gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize    =
> gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeOffset  =
> gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset
> +SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress =
> gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
> +SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize    =
> gSiPkgTokenSpaceGuid.PcdBiosSize
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress    =
> gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
> +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize           =
> gSiPkgTokenSpaceGuid.PcdBiosSize
> +###############################################################
> #################
> +#
> +# Following are lists of FD Region layout which correspond to the locations of
> different
> +# images within the flash device.
> +#
> +# Regions must be defined in ascending order and may not overlap.
> +#
> +# A Layout Region start with a eight digit hex offset (leading "0x" required)
> followed by
> +# the pipe "|" character, followed by the size of the region, also in hex with the
> leading
> +# "0x" characters. Like:
> +# Offset|Size
> +# PcdOffsetCName|PcdSizeCName
> +# RegionType <FV, DATA, or FILE>
> +# Fv Size can be adjusted
> +#
> +###############################################################
> #################
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset|gEfiMd
> eModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMd
> eModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +#NV_VARIABLE_STORE
> +DATA = {
> +  ## This is the EFI_FIRMWARE_VOLUME_HEADER
> +  # ZeroVector []
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  # FileSystemGuid
> +  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
> +  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
> +  # FvLength: 0x40000
> +  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  #Signature "_FVH"       #Attributes
> +  0x5F, 0x46, 0x56, 0x48, 0xFF, 0xFE, 0x04, 0x00,
> +  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
> +  #
> +  # Be careful on CheckSum field.
> +  #
> +  0x48, 0x00, 0x32, 0x09, 0x00, 0x00, 0x00, 0x02,
> +  #Blockmap[0]: 4 Blocks  0x10000 Bytes / Block
> +  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
> +  #Blockmap[1]: End
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  ## This is the VARIABLE_STORE_HEADER
> +!if gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable == TRUE
> +  #  Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a,
> { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
> +  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
> +  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
> +!else
> +  #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6,
> 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
> +  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
> +  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
> +!endif
> +  #Size: 0x1E000
> (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48
> (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x1DFB8
> +  # This can speed up the Variable Dispatch a bit.
> +  0xB8, 0xDF, 0x01, 0x00,
> +  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
> +  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset|gEfi
> MdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEf
> iMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +#NV_FTW_WORKING
> +DATA = {
> +  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature =
> gEdkiiWorkingBlockSignatureGuid         =
> +  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b,
> 0x95 }}
> +  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
> +  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
> +  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1,
> Reserved
> +  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
> +  # WriteQueueSize: UINT64
> +  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset|gEfiM
> deModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiM
> deModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +#NV_FTW_SPARE
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset|gMinPlatform
> PkgTokenSpaceGuid.PcdFlashFvAdvancedSize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase|gMinPlatformP
> kgTokenSpaceGuid.PcdFlashFvAdvancedSize
> +FV = FvAdvanced
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset|gMinPlatformPk
> gTokenSpaceGuid.PcdFlashFvSecuritySize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase|gMinPlatformPkg
> TokenSpaceGuid.PcdFlashFvSecuritySize
> +FV = FvSecurity
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset|gMinPlatformPk
> gTokenSpaceGuid.PcdFlashFvOsBootSize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase|gMinPlatformPkg
> TokenSpaceGuid.PcdFlashFvOsBootSize
> +FV = FvOsBoot
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset|gMinPlatformP
> kgTokenSpaceGuid.PcdFlashFvUefiBootSize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase|gMinPlatformPk
> gTokenSpaceGuid.PcdFlashFvUefiBootSize
> +FV = FvUefiBoot
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset|gMinPlatfo
> rmPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase|gMinPlatfor
> mPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
> +FV = FvPostMemory
> +
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|gSiPkgTokenSpaceGuid.P
> cdFlashMicrocodeFvSize
> +gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase|gSiPkgTokenSpaceGuid.Pc
> dFlashMicrocodeFvSize
> +#Microcode
> +FV = FvMicrocode
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset|gMinPlatformPkgTo
> kenSpaceGuid.PcdFlashFvFspSSize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase|gMinPlatformPkgTok
> enSpaceGuid.PcdFlashFvFspSSize
> +# FSP_S Section
> +FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_S.fd
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset|gMinPlatformPkgT
> okenSpaceGuid.PcdFlashFvFspMSize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase|gMinPlatformPkgTo
> kenSpaceGuid.PcdFlashFvFspMSize
> +# FSP_M Section
> +FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_M.fd
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset|gMinPlatformPkgTo
> kenSpaceGuid.PcdFlashFvFspTSize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase|gMinPlatformPkgTok
> enSpaceGuid.PcdFlashFvFspTSize
> +# FSP_T Section
> +FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_T.fd
> +
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset|gMinPlatfor
> mPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
> +gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase|gMinPlatfor
> mPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
> +FV = FvPreMemory
> +
> +###############################################################
> #################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed
> within a flash
> +# device file.  This section also defines order the components and modules
> are positioned
> +# within the image.  The [FV] section consists of define statements, set
> statements and
> +# module statements.
> +#
> +###############################################################
> #################
> +[FV.FvMicrocode]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = FALSE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = FALSE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
> +
> $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/X64/MicrocodeUpd
> ates.bin
> +}
> +
> +[FV.FvPreMemory]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = FC8FE6B5-CD9B-411E-BD8F-31824D0CDE3D
> +
> +INF  UefiCpuPkg/SecCore/SecCore.inf
> +INF  MdeModulePkg/Core/Pei/PeiMain.inf
> +!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePreMemoryInclude.fdf
> +
> +INF $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.in
> f
> +INF IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMe
> m.inf
> +
> +[FV.FvPostMemoryUncompact]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 7C4DCFC6-AECA-4707-85B9-FD4B2EEA49E7
> +
> +!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePostMemoryInclude.fdf
> +
> +# Init Board Config PCD
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.i
> nf
> +INF IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMe
> m.inf
> +
> +FILE RAW = C9505BC0-AA3D-4056-9995-870C8DE8594E {
> +
> $(PLATFORM_SI_BIN_PACKAGE)/ChipsetInit/CnlPchLpChipsetInitTable_Dx.bin
> +  }
> +!if gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable == TRUE
> +FILE FREEFORM
> =PCD(gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid) {
> +  SECTION RAW =
> $(PLATFORM_FSP_BIN_PACKAGE)/SampleCode/Vbt/Vbt.bin
> +  SECTION UI  = "Vbt"
> +}
> +FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D {
> +  SECTION RAW = MdeModulePkg/Logo/Logo.bmp
> +}
> +!endif # PcdPeiDisplayEnable
> +
> +
> +[FV.FvPostMemory]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 9DFE49DB-8EF0-4D9C-B273-0036144DE917
> +
> +FILE FV_IMAGE = 244FAAF4-FAE1-4892-8B7D-7EF84CBFA709 {
> +      SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +        SECTION FV_IMAGE = FvPostMemoryUncompact
> +      }
> +}
> +
> +[FV.FvUefiBootUncompact]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
> +
> +!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreUefiBootInclude.fdf
> +INF  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
> +
> +INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
> +INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> +INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +INF
> MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.
> inf
> +INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
> +INF  ShellPkg/Application/Shell/Shell.inf
> +
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
> +INF  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf
> +INF  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
> +
> +INF  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
> +
> +
> +[FV.FvUefiBoot]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 0496D33D-EA79-495C-B65D-ABF607184E3B
> +
> +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +         SECTION FV_IMAGE = FvUefiBootUncompact
> +       }
> +     }
> +
> +[FV.FvOsBootUncompact]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = A0F04529-B715-44C6-BCA4-2DEBDD01EEEC
> +
> +!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreOsBootInclude.fdf
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> +INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +INF
> $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
> +INF  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
> +
> +INF  $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
> +INF  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf
> +
> +INF  RuleOverride = DRIVER_ACPITABLE
> $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
> +INF
> $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfi
> g.inf
> +
> +!endif
> +
> +[FV.FvLateSilicon]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 97F09B89-9E83-4DDC-A3D1-10C4AF539D1E
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> +$(SIPKG_DXE_SMM_BIN)
> $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
> +$(SIPKG_DXE_SMM_BIN)
> $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
> +$(SIPKG_DXE_SMM_BIN)
> $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.in
> f
> +$(SIPKG_DXE_SMM_BIN)
> $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
> +$(SIPKG_DXE_SMM_BIN)
> $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
> +$(SIPKG_DXE_SMM_BIN)
> $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
> +
> +INF  RuleOverride = ACPITABLE
> $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
> +INF  RuleOverride = ACPITABLE
> $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
> +
> +!endif
> +
> +[FV.FvOsBoot]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 13BF8810-75FD-4B1A-91E6-E16C4201F80A
> +
> +FILE FV_IMAGE = B9020753-84A8-4BB6-947C-CE7D41F5CE39 {
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +         SECTION FV_IMAGE = FvOsBootUncompact
> +       }
> +     }
> +
> +FILE FV_IMAGE = D4632741-510C-44E3-BE21-C3D6D7881485 {
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +         SECTION FV_IMAGE = FvLateSilicon
> +       }
> +     }
> +
> +[FV.FvSecurityPreMemory]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 9B7FA59D-71C6-4A36-906E-9725EA6ADD5B
> +
> +!include
> $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
> +
> +INF
> IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam
> plePei.inf
> +
> +INF  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
> +
> +[FV.FvSecurityPostMemory]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16         #FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 4199E560-54AE-45E5-91A4-F7BC3804E14A
> +
> +!include
> $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPostMemoryInclude.fdf
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
> +INF $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
> +!endif
> +
> +[FV.FvSecurityLate]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = F753FE9A-EEFD-485B-840B-E032D538102C
> +
> +!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityLateInclude.fdf
> +INF  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
> +
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> +INF
> $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
> +!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
> +INF  $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
> +!endif
> +!endif
> +
> +[FV.FvSecurity]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 5A9A8B4E-149A-4CB2-BDC7-C8D62DE2C8CF
> +
> +FILE FV_IMAGE = 757CC075-1428-423D-A73C-22639706C119 {
> +       SECTION FV_IMAGE = FvSecurityPreMemory
> +     }
> +
> +FILE FV_IMAGE = 80BB8482-44D5-4BEC-82B5-8D87A933830B {
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +         SECTION FV_IMAGE = FvSecurityPostMemory
> +       }
> +     }
> +
> +FILE FV_IMAGE = C83522D9-80A1-4D95-8C25-3F1370497406 {
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +         SECTION FV_IMAGE = FvSecurityLate
> +       }
> +     }
> +
> +[FV.FvAdvancedPreMem]
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 6053D78A-457E-4490-A237-31D0FBE2F305
> +
> +!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
> +INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
> +!endif
> +
> +[FV.FvAdvancedPostMem]
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = BE3DF86F-E464-44A3-83F7-0D27E6B88C27
> +
> +[FV.FvAdvancedLate]
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 11F6E304-43F9-4B2F-90AB-B8FFEAD6205D
> +
> +!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
> +INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
> +INF  $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
> +INF
> $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
> +!endif
> +
> +[FV.FvAdvanced]
> +BlockSize          = $(FLASH_BLOCK_SIZE)
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = B23E7388-9953-45C7-9201-0473DDE5487A
> +
> +FILE FV_IMAGE = 35E7406A-5842-4F2B-BC62-19022C12AF74 {
> +       SECTION FV_IMAGE = FvAdvancedPreMem
> +     }
> +
> +FILE FV_IMAGE = F5DCB34F-27EA-48AC-9406-C894F6D587CA {
> +       SECTION FV_IMAGE = FvAdvancedPostMem
> +     }
> +
> +FILE FV_IMAGE = 5248467B-B87B-4E74-AC02-398AF4BCB712 {
> +       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF
> PROCESSING_REQUIRED = TRUE {
> +         SECTION FV_IMAGE = FvAdvancedLate
> +       }
> +     }
> +
> +###############################################################
> #################
> +#
> +# Rules are use with the [FV] section's module INF type to define
> +# how an FFS file is created for a given INF file. The following Rule are the
> default
> +# rules for the different module type. User can add the customized rules to
> define the
> +# content of the FFS file.
> +#
> +###############################################################
> #################
> +
> +!include $(PLATFORM_PACKAGE)/Include/Fdf/RuleInclude.fdf
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.
> cfg
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.
> cfg
> new file mode 100644
> index 0000000000..1b0619bc1c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.
> cfg
> @@ -0,0 +1,33 @@
> +# @ build_config.cfg
> +# This is the WhiskeylakeURvp board specific build settings
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +
> +[CONFIG]
> +WORKSPACE_PLATFORM_BIN =
> +EDK_SETUP_OPTION =
> +openssl_path =
> +PLATFORM_BOARD_PACKAGE = WhiskeylakeOpenBoardPkg
> +PROJECT = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp
> +BOARD = WhiskeylakeURvp
> +FLASH_MAP_FDF =
> WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.
> fdf
> +PROJECT_DSC =
> WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
> +BOARD_PKG_PCD_DSC =
> WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
> +PrepRELEASE = DEBUG
> +SILENT_MODE = FALSE
> +EXT_CONFIG_CLEAR =
> +CapsuleBuild = FALSE
> +EXT_BUILD_FLAGS =
> +CAPSULE_BUILD = 0
> +TARGET = DEBUG
> +TARGET_SHORT = D
> +PERFORMANCE_BUILD = FALSE
> +FSP_WRAPPER_BUILD = TRUE
> +FSP_BIN_PKG = CoffeeLakeFspBinPkg
> +FSP_PKG_NAME = CoffeelakeSiliconPkg
> +FSP_BINARY_BUILD = FALSE
> +FSP_TEST_RELEASE = FALSE
> +SECURE_BOOT_ENABLE = FALSE
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:16   ` Chiu, Chasel
  1 sibling, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:16 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 32/37]
> WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> Header files for the WhiskeylakeURvp board instance.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlat
> formHookLib.h  | 131 ++++++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlat
> formLib.h      |  40 ++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Platfor
> mBoardConfig.h | 105 ++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Platfor
> mInfo.h        |  44 +++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Whisk
> eylakeURvpId.h   |  12 ++
>  5 files changed, 332 insertions(+)
> 
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPl
> atformHookLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiP
> latformHookLib.h
> new file mode 100644
> index 0000000000..bd849b9ee2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pei
> +++ PlatformHookLib.h
> @@ -0,0 +1,131 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _PEI_PLATFORM_HOOK_LIB_H_
> +#define _PEI_PLATFORM_HOOK_LIB_H_
> +
> +#include <PlatformInfo.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/GpioLib.h>
> +
> +
> +//EC Command to provide one byte of debug indication #define
> +BSSB_DEBUG_INDICATION 0xAE
> +/**
> +  Configure EC for specific devices
> +
> +  @param[in] PchLan       - The PchLan of PCH_SETUP variable.
> +  @param[in] BootMode     - The current boot mode.
> +**/
> +VOID
> +EcInit (
> +  IN UINT8                PchLan,
> +  IN EFI_BOOT_MODE        BootMode
> +  );
> +
> +/**
> +  Checks if Premium PMIC present
> +
> +  @retval  TRUE  if present
> +  @retval  FALSE it discrete/other PMIC **/ BOOLEAN
> +IsPremiumPmicPresent (
> +  VOID
> +  );
> +
> +/**
> +  Pmic Programming to supprort LPAL Feature
> +
> +  @retval     NONE
> +**/
> +VOID
> +PremiumPmicDisableSlpS0Voltage (
> +  VOID
> +  );
> +
> +/**
> +Pmic Programming to supprort LPAL Feature
> +  @retval     NONE
> +**/
> +VOID
> +PremiumPmicEnableSlpS0Voltage(
> +  VOID
> +  );
> +
> +/**
> +  Do platform specific programming pre-memory. For example, EC init,
> +Chipset programming
> +
> +  @retval  Status
> +**/
> +EFI_STATUS
> +PlatformSpecificInitPreMem (
> +  VOID
> +  );
> +
> +/**
> +  Do platform specific programming post-memory.
> +
> +  @retval  Status
> +**/
> +EFI_STATUS
> +PlatformSpecificInit (
> +  VOID
> +  );
> +
> +/**
> +  Configure GPIO and SIO Before Memory is ready.
> +
> +  @retval  EFI_SUCCESS   Operation success.
> +**/
> +EFI_STATUS
> +BoardInitPreMem (
> +  VOID
> +  );
> +
> +/**
> +  Configure GPIO and SIO
> +
> +  @retval  EFI_SUCCESS   Operation success.
> +**/
> +EFI_STATUS
> +BoardInit (
> +  VOID
> +  );
> +
> +/**
> +Voltage Margining Routine
> +
> +@retval  EFI_SUCCESS   Operation success
> +**/
> +EFI_STATUS
> +VoltageMarginingRoutine(
> +  VOID
> +  );
> +
> +/**
> +  Detect recovery mode
> +
> +  @retval  EFI_SUCCESS       System in Recovery Mode
> +  @retval  EFI_UNSUPPORTED   System doesn't support Recovery Mode
> +  @retval  EFI_NOT_FOUND     System is not in Recovery Mode
> +**/
> +EFI_STATUS
> +IsRecoveryMode (
> +  VOID
> +  );
> +
> +/**
> +  Early board Configuration before Memory is ready.
> +
> +  @retval  EFI_SUCCESS  Operation success.
> +**/
> +EFI_STATUS
> +BoardInitEarlyPreMem (
> +  VOID
> +  );
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPl
> atformLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiP
> latformLib.h
> new file mode 100644
> index 0000000000..d65586dbb9
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pei
> +++ PlatformLib.h
> @@ -0,0 +1,40 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _PEI_PLATFORM_LIB_H_
> +#define _PEI_PLATFORM_LIB_H_
> +
> +
> +
> +#define PEI_DEVICE_DISABLED 0
> +#define PEI_DEVICE_ENABLED  1
> +
> +typedef struct {
> +  UINT8   Register;
> +  UINT32  Value;
> +} PCH_GPIO_DEV;
> +
> +//
> +// GPIO Initialization Data Structure
> +//
> +typedef struct{
> +  PCH_GPIO_DEV Use_Sel;
> +  PCH_GPIO_DEV Use_Sel2;
> +  PCH_GPIO_DEV Use_Sel3;
> +  PCH_GPIO_DEV Io_Sel;
> +  PCH_GPIO_DEV Io_Sel2;
> +  PCH_GPIO_DEV Io_Sel3;
> +  PCH_GPIO_DEV Lvl;
> +  PCH_GPIO_DEV Lvl2;
> +  PCH_GPIO_DEV Lvl3;
> +  PCH_GPIO_DEV Inv;
> +  PCH_GPIO_DEV Blink;
> +  PCH_GPIO_DEV Rst_Sel;
> +  PCH_GPIO_DEV Rst_Sel2;
> +} GPIO_INIT_STRUCT;
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Platf
> ormBoardConfig.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Platf
> ormBoardConfig.h
> new file mode 100644
> index 0000000000..44b4059f8e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pla
> +++ tformBoardConfig.h
> @@ -0,0 +1,105 @@
> +/** @file
> +  Header file for Platform Boards Configurations.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _PLATFORM_BOARD_CONFIG_H
> +#define _PLATFORM_BOARD_CONFIG_H
> +
> +#include <ConfigBlock.h>
> +#include <PchPolicyCommon.h>
> +#include <ConfigBlock/MemoryConfig.h>
> +#include <GpioConfig.h>
> +#include <TbtBoardInfo.h>
> +
> +#define IS_ALIGNED(addr, size) (((addr) & (size - 1)) ? 0 : 1)
> +#define ALIGN16(size)          (IS_ALIGNED(size, 16) ? size : ((size + 16) &
> 0xFFF0))
> +
> +#define BOARD_CONFIG_BLOCK_PEI_PREMEM_VERSION  0x00000001
> #define
> +BOARD_CONFIG_BLOCK_PEI_POSTMEM_VERSION 0x00000001 #define
> +BOARD_CONFIG_BLOCK_DXE_VERSION 0x00000001 #define
> +BOARD_NO_BATTERY_SUPPORT 0 #define
> BOARD_REAL_BATTERY_SUPPORTED BIT0
> +#define BOARD_VIRTUAL_BATTERY_SUPPORTED BIT1
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block
> Header
> +} BOARD_CONFIG_BLOCK;
> +
> +typedef struct {
> +  UINT8 GpioSupport;
> +  UINT32 WakeGpioNo;
> +  UINT8 HoldRstExpanderNo;
> +  UINT32 HoldRstGpioNo;
> +  BOOLEAN HoldRstActive;
> +  UINT8 PwrEnableExpanderNo;
> +  UINT32 PwrEnableGpioNo;
> +  BOOLEAN PwrEnableActive;
> +} SWITCH_GRAPHIC_GPIO;
> +
> +typedef struct {
> +  UINT8 ClkReqNumber : 4;
> +  UINT8 ClkReqSupported : 1;
> +  UINT8 DeviceResetPadActiveHigh : 1;
> +  UINT32 DeviceResetPad;
> +} ROOT_PORT_CLK_INFO;
> +
> +typedef struct {
> +  UINT8 Section;
> +  UINT8 Pin;
> +} EXPANDER_GPIO_CONFIG;
> +
> +typedef enum {
> +  BoardGpioTypePch,
> +  BoardGpioTypeExpander,
> +  BoardGpioTypeNotSupported = 0xFF
> +} BOARD_GPIO_TYPE;
> +
> +typedef struct {
> +  UINT8 Type;
> +  UINT8 Reserved[3];  // alignment for COMMON_GPIO_CONFIG
> +  union {
> +    UINT32 Pin;
> +    EXPANDER_GPIO_CONFIG Expander;
> +  } u;
> +} BOARD_GPIO_CONFIG;
> +
> +// Do not change the encoding. It must correspond with
> PCH_PCIE_CLOCK_USAGE from PCH RC.
> +#define NOT_USED     0xFF
> +#define FREE_RUNNING 0x80
> +#define LAN_CLOCK    0x70
> +#define PCIE_PEG     0x40
> +#define PCIE_PCH     0x00
> +
> +typedef struct {
> +  UINT32 ClockUsage;
> +  UINT32 ClkReqSupported;
> +} PCIE_CLOCK_CONFIG;
> +
> +typedef union {
> +  UINT64 Blob;
> +  BOARD_GPIO_CONFIG  BoardGpioConfig;
> +  ROOT_PORT_CLK_INFO Info;
> +  PCIE_CLOCK_CONFIG  PcieClock;
> +} PCD64_BLOB;
> +
> +typedef union {
> +  UINT32        Blob;
> +  USB20_AFE     Info;
> +} PCD32_BLOB;
> +
> +#ifndef IO_EXPANDER_DISABLED
> +#define IO_EXPANDER_DISABLED      0xFF
> +#endif
> +
> +#define SPD_DATA_SIZE 512
> +
> +#pragma pack()
> +
> +#endif // _PLATFORM_BOARD_CONFIG_H
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Platf
> ormInfo.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Platf
> ormInfo.h
> new file mode 100644
> index 0000000000..0e0b6c4f6c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Pla
> +++ tformInfo.h
> @@ -0,0 +1,44 @@
> +/** @file
> +  GUID used for Platform Info Data entries in the HOB list.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _PLATFORM_INFO_H_
> +#define _PLATFORM_INFO_H_
> +
> +#pragma pack(1)
> +
> +///
> +/// PCH_GPIO_PAD is equivalent to GPIO_PAD which is defined in
> +GpioConfig.h /// typedef UINT32 PCH_GPIO_PAD; //Copied from
> +GpioConfig.h (need to change it based on include)
> +
> +typedef struct {
> +UINT8    Expander;
> +UINT8    Pin;
> +UINT16   Reserved; // Reserved for future use
> +} IO_EXPANDER_PAD;
> +
> +typedef union {
> +PCH_GPIO_PAD       PchGpio;
> +IO_EXPANDER_PAD    IoExpGpio;
> +} GPIO_PAD_CONFIG;
> +
> +typedef struct {
> +UINT8                GpioType;    // 0: Disabled (no GPIO support), 1: PCH, 2: I/O
> Expander
> +UINT8                Reserved[3]; // Reserved for future use
> +GPIO_PAD_CONFIG      GpioData;
> +} PACKED_GPIO_CONFIG;
> +
> +typedef union {
> +PACKED_GPIO_CONFIG    PackedGpio;
> +UINT64                Data64;
> +} COMMON_GPIO_CONFIG;
> +
> +#pragma pack()
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Whi
> skeylakeURvpId.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Whi
> skeylakeURvpId.h
> new file mode 100644
> index 0000000000..7d44acccc1
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Whi
> +++ skeylakeURvpId.h
> @@ -0,0 +1,12 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef _WHISKEYLAKE_ERB_ID_H_
> +#define _WHISKEYLAKE_ERB_ID_H_
> +
> +#define BoardIdWhiskeyLakeRvp          0x60
> +#endif // _WHISKEYLAKE_RVP3_ID_H_
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:17   ` Chiu, Chasel
  2019-08-17 20:08   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:17 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 34/37]
> WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> WhiskeylakeURvp library instances.
> 
> * BaseFuncLib - Board-specific VBT update routines.
> * BaseGpioCheckConflictLib - Identifies GPIO pad conflicts.
> * BaseGpioCheckConflictLibNull - NULL library instance.
> * BasePlatformHookLib - Serial port initialization support.
> * DxePolicyBoardConfigLib - Board-specific silicon policy configuration
>   in DXE.
> * PeiBoardInitPostMemLib - PEI post-memory board-specific initialization.
>   This library implements board APIs declared in MinPlatformPkg.
> * PeiBoardInitPreMemLib - PEI pre-memory board-specific initialization.
>   This library implements board APIs declared in MinPlatformPkg.
> * PeiMultiBoardInitPostMemLib - PEI post-memory multi-board initialization.
>   This library implements board APIs declared in MinPlatformPkg.
> * PeiMultiBoardInitPreMemLib - PEI pre-memory multi-board initialization.
>   This library implements board APIs declared in MinPlatformPkg.
> * PeiPlatformHookLib - PEI board instance-specifc GPIO init.
> * PeiPolicyBoardConfigLib - Board instance-specific policy init in PEI.
> * SmmBoardAcpiEnableLib - Board instance-specific SMM ACPI enable
> support.
> * SmmMultiBoardAcpiSupportLib - Multi-board ACPI support in SMM.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFu
> ncLib/BaseFuncLib.inf                                   |   33 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseG
> pioCheckConflictLib/BaseGpioCheckConflictLib.inf         |   35 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseG
> pioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf |   32 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePl
> atformHookLib/BasePlatformHookLib.inf                   |   53 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardA
> cpiLib/SmmBoardAcpiEnableLib.inf                        |   50 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardA
> cpiLib/SmmMultiBoardAcpiSupportLib.inf                  |   50 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiBoardInitPostMemLib.inf                       |   53 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiBoardInitPreMemLib.inf                        |  116 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiMultiBoardInitPostMemLib.inf                  |  202 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiMultiBoardInitPreMemLib.inf                   |  296 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePoli
> cyBoardConfigLib/DxePolicyBoardConfigLib.inf           |   44 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlat
> formHookLib/PeiPlatformHooklib.inf                     |   94 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiPolicyBoardConfigLib.inf           |   70 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardFunc.h                                      |   18 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardInitLib.h                                   |   20 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardSaConfigPreMem.h                            |   90 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/GpioTableDefault.h                               |  225 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/GpioTableWhlUDdr4.h                              |  284 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/GpioTableWhlUDdr4PreMem.h                        |   59 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PchHdaVerbTables.h                               | 3014
> ++++++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiWhiskeylakeURvpInitLib.h                      |   41 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePoli
> cyBoardConfigLib/DxePolicyBoardConfig.h                |   20 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiPolicyBoardConfig.h                |   23 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFu
> ncLib/Gop.c                                             |   41 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseG
> pioCheckConflictLib/BaseGpioCheckConflictLib.c           |  137 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseG
> pioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c   |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePl
> atformHookLib/BasePlatformHookLib.c                     |  156 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardA
> cpiLib/SmmBoardAcpiEnableLib.c                          |   63 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardA
> cpiLib/SmmMultiBoardAcpiSupportLib.c                    |   82 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardA
> cpiLib/SmmSiliconAcpiEnableLib.c                        |  170 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardA
> cpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c                |   40 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardFunc.c                                      |   19 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardFuncInit.c                                  |   27 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardFuncInitPreMem.c                            |   41 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardPchInitPreMemLib.c                          |  398 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/BoardSaInitPreMemLib.c                           |  282 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiBoardInitPostMemLib.c                         |   40 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiBoardInitPreMemLib.c                          |  106 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiMultiBoardInitPostMemLib.c                    |   41 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiMultiBoardInitPreMemLib.c                     |   83 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiWhiskeylakeURvpDetect.c                       |   63 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiWhiskeylakeURvpInitPostMemLib.c               |  432 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/PeiWhiskeylakeURvpInitPreMemLib.c                |  636 +++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardI
> nitLib/WhiskeylakeURvpHsioPtssTables.c                  |   32 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePoli
> cyBoardConfigLib/DxeSaPolicyBoardConfig.c              |   35 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlat
> formHookLib/PeiPlatformHooklib.c                       |  299 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiCpuPolicyBoardConfig.c             |   48 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c       |   29 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiMePolicyBoardConfig.c              |   35 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c        |   36 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiPchPolicyBoardConfig.c             |   35 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c       |   36 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiSaPolicyBoardConfig.c              |   35 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c        |   36 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPoli
> cyBoardConfigLib/PeiSiPolicyBoardConfig.c              |   27 +
>  55 files changed, 8499 insertions(+)
> 
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> FuncLib/BaseFuncLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> FuncLib/BaseFuncLib.inf
> new file mode 100644
> index 0000000000..0ccc73b99f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> FuncLib/BaseFuncLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +# Component information file for Board Functions Library.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BaseBoardFuncInitLib
> +  FILE_GUID                      = 7ad17b6c-b9b6-4d88-85c4-7366a2bd12a3
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = NULL|PEIM
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +
> +[Packages]
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  Gop.c
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLib/BaseGpioCheckConflictLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLib/BaseGpioCheckConflictLib.inf
> new file mode 100644
> index 0000000000..5014faf664
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLib/BaseGpioCheckConflictLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +# Component information file for BaseGpioCheckConflictLib.
> +#
> +#
> +#  Copyright (c) 2019, 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
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  BaseGpioCheckConflictLib.c
> +
> +[Guids]
> +  gGpioCheckConflictHobGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
> new file mode 100644
> index 0000000000..d9b242b3fc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
> @@ -0,0 +1,32 @@
> +## @file
> +# Component information file for BaseGpioCheckConflictLib.
> +#
> +#
> +#  Copyright (c) 2019, 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
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  BaseGpioCheckConflictLibNull.c
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> PlatformHookLib/BasePlatformHookLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> PlatformHookLib/BasePlatformHookLib.inf
> new file mode 100644
> index 0000000000..143bb89c63
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> PlatformHookLib/BasePlatformHookLib.inf
> @@ -0,0 +1,53 @@
> +## @file
> +# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = BasePlatformHookLib
> +  FILE_GUID                      = E22ADCC6-ED90-4A90-9837-C8E7FF9E963D
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = BASE
> +  LIBRARY_CLASS                  = PlatformHookLib
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC
> +#
> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  PciSegmentLib
> +  PchCycleDecodingLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort                 ##
> CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort   ##
> CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort  ##
> CONSUMES
> +
> +[FixedPcd]
> +  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding            ##
> CONSUMES
> +
> +[Sources]
> +  BasePlatformHookLib.c
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmBoardAcpiEnableLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmBoardAcpiEnableLib.inf
> new file mode 100644
> index 0000000000..8ad32a55dc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmBoardAcpiEnableLib.inf
> @@ -0,0 +1,50 @@
> +## @file
> +# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = SmmBoardAcpiEnableLib
> +  FILE_GUID                      = 549E69AE-D3B3-485B-9C17-AF16E20A58AD
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = BASE
> +  LIBRARY_CLASS                  = BoardAcpiEnableLib
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC
> +#
> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  PciLib
> +  MmPciLib
> +  PchCycleDecodingLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
> +
> +[Protocols]
> +
> +[Sources]
> +  SmmWhiskeylakeURvpAcpiEnableLib.c
> +  SmmSiliconAcpiEnableLib.c
> +  SmmBoardAcpiEnableLib.c
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmMultiBoardAcpiSupportLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmMultiBoardAcpiSupportLib.inf
> new file mode 100644
> index 0000000000..27001c3b7f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmMultiBoardAcpiSupportLib.inf
> @@ -0,0 +1,50 @@
> +## @file
> +# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      =
> SmmWhiskeylakeURvpMultiBoardAcpiSupportLib
> +  FILE_GUID                      = 8929A54E-7ED8-4AB3-BEBB-C0367BDBBFF5
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = BASE
> +  LIBRARY_CLASS                  = NULL
> +  CONSTRUCTOR                    =
> SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF EBC
> +#
> +
> +[LibraryClasses]
> +  BaseLib
> +  IoLib
> +  PciLib
> +  PmcLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
> +
> +[Protocols]
> +
> +[Sources]
> +  SmmWhiskeylakeURvpAcpiEnableLib.c
> +  SmmSiliconAcpiEnableLib.c
> +  SmmMultiBoardAcpiSupportLib.c
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPostMemLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPostMemLib.inf
> new file mode 100644
> index 0000000000..a8c4869e96
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPostMemLib.inf
> @@ -0,0 +1,53 @@
> +## @file
> +# Component information file for WhiskeylakeURvpInitLib in PEI post memory
> phase.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiBoardPostMemInitLib
> +  FILE_GUID                      = 7fcc3900-d38d-419f-826b-72481e8b5509
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = BoardInitLib
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  HdaVerbTableLib
> +  MemoryAllocationLib
> +  GpioExpanderLib
> +  PcdLib
> +
> +[Packages]
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PeiWhiskeylakeURvpInitPostMemLib.c
> +  PeiBoardInitPostMemLib.c
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
> +
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
> +
> +  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
> +  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
> +
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPreMemLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPreMemLib.inf
> new file mode 100644
> index 0000000000..9361c3df3e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPreMemLib.inf
> @@ -0,0 +1,116 @@
> +## @file
> +# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem
> Library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiBoardInitPreMemLib
> +  FILE_GUID                      = ec3675bc-1470-417d-826e-37378140213d
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = BoardInitLib
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  PcdLib
> +
> +[Packages]
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PeiWhiskeylakeURvpDetect.c
> +  PeiWhiskeylakeURvpInitPreMemLib.c
> +  WhiskeylakeURvpHsioPtssTables.c
> +  PeiBoardInitPreMemLib.c
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
> +
> +  # PCH-LP HSIO PTSS Table
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
> +
> +  # SA Misc Config
> +  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
> +
> +  # PEG Reset By GPIO
> +  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
> +
> +
> +  # SPD Address Table
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
> +
> +  # USB 2.0 Port AFE
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
> +
> +  # USB 2.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
> +
> +  # USB 3.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
> +
> +  # Misc
> +  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPostMemLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPostMemLib.inf
> new file mode 100644
> index 0000000000..4831735dc5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPostMemLib.inf
> @@ -0,0 +1,202 @@
> +## @file
> +# Component information file for WhiskeylakeURvpInitLib in PEI post memory
> phase.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitLib
> +  FILE_GUID                      = C7D39F17-E5BA-41D9-8DFE-FF9017499280
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = NULL
> +  CONSTRUCTOR                    =
> PeiWhiskeylakeURvpMultiBoardInitLibConstructor
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  GpioExpanderLib
> +  PcdLib
> +  MultiBoardInitSupportLib
> +  HdaVerbTableLib
> +  PeiPlatformHookLib
> +  PeiPolicyInitLib
> +  PchInfoLib
> +
> +[Packages]
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +
> +[Sources]
> +  PeiWhiskeylakeURvpInitPostMemLib.c
> +  PeiMultiBoardInitPostMemLib.c
> +  BoardFunc.c
> +  BoardFuncInit.c
> +
> +[FixedPcd]
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
> +
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
> +
> +  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
> +  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
> +
> +  #===========================================================
> +  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase
> +  # Board Init Table List
> +
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
> +
> gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSiz
> e
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
> +
> gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSiz
> e
> +
> +  # WWAN Full Card Power Off and reset pins
> +  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
> +  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
> +  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
> +  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
> +
> +  # SA Misc Config
> +  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
> +  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
> +
> +  # Display DDI
> +  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ##
> PRODUCES
> +  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ##
> PRODUCES
> +
> +  # PEG Reset By GPIO
> +  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
> +  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
> +  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
> +  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
> +  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
> +  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
> +
> +  # PCIE RTD3 GPIO
> +  gBoardModuleTokenSpaceGuid.PcdRootPortDev
> +  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
> +  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
> +
> +  # CA Vref Configuration
> +  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
> +
> +  # PCIe Clock Info
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock0
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock1
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock2
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock3
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock4
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock5
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock6
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock7
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock8
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock9
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock10
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock11
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock12
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock13
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock14
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock15
> +
> +  # USB 2.0 Port AFE
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
> +
> +  # USB 2.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
> +
> +  # USB 3.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
> +
> +  # GPIO Group Tier
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
> +
> +  # Pch PmConfig Policy
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
> +
> +  # Misc
> +  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
> +  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
> +  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
> +  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
> +  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
> +  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
> +
> +
> +  gBoardModuleTokenSpaceGuid.PcdSpdPresent
> +  gBoardModuleTokenSpaceGuid.PcdBoardRev
> +  gBoardModuleTokenSpaceGuid.PcdBoardBomId
> +  gBoardModuleTokenSpaceGuid.PcdPlatformType
> +  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
> +
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable
> +  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable
> +  # TPM interrupt
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
> +
> +[Guids]
> +  gAttemptUsbFirstHotkeyInfoHobGuid             ## CONSUMES
> +  gCnlPchLpChipsetInitTableDxGuid               ## CONSUMES
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPreMemLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPreMemLib.inf
> new file mode 100644
> index 0000000000..6affc3180e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPreMemLib.inf
> @@ -0,0 +1,296 @@
> +## @file
> +# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem
> Library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      =
> PeiWhiskeylakeURvpMultiBoardInitPreMemLib
> +  FILE_GUID                      = EA05BD43-136F-45EE-BBBA-27D75817574F
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = NULL
> +  CONSTRUCTOR                    =
> PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  PcdLib
> +  MultiBoardInitSupportLib
> +  StallPpiLib
> +  PchResetLib
> +  PeiPlatformHookLib
> +  PlatformHookLib
> +  PeiPolicyInitLib
> +  OcWdtLib
> +
> +[Packages]
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PeiWhiskeylakeURvpInitPreMemLib.c
> +  WhiskeylakeURvpHsioPtssTables.c
> +  PeiMultiBoardInitPreMemLib.c
> +  PeiWhiskeylakeURvpDetect.c
> +  BoardSaInitPreMemLib.c
> +  BoardPchInitPreMemLib.c
> +  BoardFuncInitPreMem.c
> +
> +[Ppis]
> +  gEfiPeiReadOnlyVariable2PpiGuid
> +  gEfiPeiMemoryDiscoveredPpiGuid                ## CONSUMES
> +  gEfiPeiResetPpiGuid                           ## PRODUCES
> +
> +[Guids]
> +  gPchGeneralPreMemConfigGuid      ## CONSUMES
> +  gTcoWdtHobGuid                                ## CONSUMES
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
> +
> +  # PCH-LP HSIO PTSS Table
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
> +  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
> +
> +  # PCH-H HSIO PTSS Table
> +  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
> +  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
> +  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
> +  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
> +
> +  # SA Misc Config
> +  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
> +  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
> +
> +  # PEG Reset By GPIO
> +  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
> +
> +
> +  # SPD Address Table
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
> +  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
> +
> +  # USB 2.0 Port AFE
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
> +
> +  # USB 2.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
> +
> +  # USB 3.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
> +
> +  # Misc
> +  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
> +
> +  #===========================================================
> +  # Board Init Table List
> +
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
> +
> gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSiz
> e
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
> +
> gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSiz
> e
> +
> +  # WWAN Full Card Power Off and reset pins
> +  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
> +  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
> +  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
> +  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
> +
> +  # SA Misc Config
> +  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
> +  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
> +  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
> +
> +  # Display DDI
> +  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ##
> PRODUCES
> +  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ##
> PRODUCES
> +
> +  # PEG Reset By GPIO
> +  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
> +  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
> +  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
> +  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
> +  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
> +  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
> +
> +  # PCIE RTD3 GPIO
> +  gBoardModuleTokenSpaceGuid.PcdRootPortDev
> +  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
> +  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
> +  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
> +  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
> +
> +  # CA Vref Configuration
> +  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
> +
> +  # PCIe Clock Info
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock0
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock1
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock2
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock3
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock4
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock5
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock6
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock7
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock8
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock9
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock10
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock11
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock12
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock13
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock14
> +  gBoardModuleTokenSpaceGuid.PcdPcieClock15
> +
> +  # USB 2.0 Port AFE
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
> +  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
> +
> +  # USB 2.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
> +  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
> +
> +  # USB 3.0 Port Over Current Pin
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
> +  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
> +
> +  # GPIO Group Tier
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
> +
> +  # Pch PmConfig Policy
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
> +  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
> +
> +  # Misc
> +  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
> +  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
> +  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
> +  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
> +  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
> +  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
> +
> +
> +  gBoardModuleTokenSpaceGuid.PcdSpdPresent
> +  gBoardModuleTokenSpaceGuid.PcdBoardRev
> +  gBoardModuleTokenSpaceGuid.PcdBoardBomId
> +  gBoardModuleTokenSpaceGuid.PcdPlatformType
> +  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
> +
> +  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
> +  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
> +  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround    ##
> PRODUCES
> +  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
> +
> +
> +[FixedPcd]
> +  gSiPkgTokenSpaceGuid.PcdMchBaseAddress              ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdMchMmioSize                 ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress     ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize        ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress      ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdEpMmioSize         ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress    ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize       ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress   ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize  ## CONSUMES
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxePolicyBoardConfigLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxePolicyBoardConfigLib.inf
> new file mode 100644
> index 0000000000..2c9af5b9a3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxePolicyBoardConfigLib.inf
> @@ -0,0 +1,44 @@
> +## @file
> +# Module Information file for DxePolicyBoardConfigLib Library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = DxePolicyBoardConfigLib
> +  FILE_GUID                      = 17836E9F-7188-4640-80A3-B4441585FFE9
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
> +#
> +
> +[Sources]
> +  DxeSaPolicyBoardConfig.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseLib
> +  BaseMemoryLib
> +  PcdLib
> +  DebugLib
> +  HobLib
> +  ConfigBlockLib
> +
> +[Guids]
> +  gMemoryDxeConfigGuid                          ## CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPl
> atformHookLib/PeiPlatformHooklib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPl
> atformHookLib/PeiPlatformHooklib.inf
> new file mode 100644
> index 0000000000..079fb70ecb
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPl
> atformHookLib/PeiPlatformHooklib.inf
> @@ -0,0 +1,94 @@
> +## @file
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiPlatformHookLib
> +  FILE_GUID                      = AD901798-B0DA-4B20-B90C-283F886E76D0
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  LIBRARY_CLASS                  = PeiPlatformHookLib|PEIM PEI_CORE SEC
> +
> +[LibraryClasses]
> +  DebugLib
> +  BaseMemoryLib
> +  IoLib
> +  HobLib
> +  PcdLib
> +  TimerLib
> +  PchCycleDecodingLib
> +  GpioLib
> +  CpuPlatformLib
> +  PeiServicesLib
> +  ConfigBlockLib
> +  PeiSaPolicyLib
> +  GpioExpanderLib
> +  PmcLib
> +  PchPcrLib
> +  PciSegmentLib
> +  GpioCheckConflictLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable                    ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable                 ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2                ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel          ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
> +
> gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSiz
> e
> +  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
> +
> gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSiz
> e
> +
> +  # GPIO Group Tier
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0              ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1              ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2              ##
> CONSUMES
> +
> +  # Misc
> +  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent              ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent            ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable             ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio               ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable                ##
> CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
> +  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
> +  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround
> +
> +[Sources]
> +  PeiPlatformHooklib.c
> +
> +[Ppis]
> +  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
> +  gSiPolicyPpiGuid                              ## CONSUMES
> +
> +[Guids]
> +  gSaDataHobGuid                                ## CONSUMES
> +  gEfiGlobalVariableGuid                        ## CONSUMES
> +  gGpioCheckConflictHobGuid                     ## CONSUMES
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
> new file mode 100644
> index 0000000000..65e66ccb62
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
> @@ -0,0 +1,70 @@
> +## @file
> +# Module Information file for PeiPolicyBoardConfigLib Library
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiPolicyBoardConfigLib
> +  FILE_GUID                      = B1E959E3-9DCA-4D6F-938C-420C3BF5D820
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  LIBRARY_CLASS                  = PeiPolicyBoardConfigLib|PEIM PEI_CORE SEC
> +
> +[Sources]
> +  PeiCpuPolicyBoardConfigPreMem.c
> +  PeiCpuPolicyBoardConfig.c
> +  PeiMePolicyBoardConfigPreMem.c
> +  PeiMePolicyBoardConfig.c
> +  PeiPchPolicyBoardConfigPreMem.c
> +  PeiPchPolicyBoardConfig.c
> +  PeiSaPolicyBoardConfigPreMem.c
> +  PeiSaPolicyBoardConfig.c
> +  PeiSiPolicyBoardConfig.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  SecurityPkg/SecurityPkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +
> +[LibraryClasses]
> +  PcdLib
> +  DebugLib
> +  HobLib
> +  ConfigBlockLib
> +  IoLib
> +  BaseCryptLib
> +  BaseMemoryLib
> +
> +[Guids]
> +  gCpuSecurityPreMemConfigGuid                  ## CONSUMES
> +  gMePeiPreMemConfigGuid                        ## CONSUMES
> +  gPchGeneralPreMemConfigGuid                   ## CONSUMES
> +  gSaMiscPeiPreMemConfigGuid                    ## CONSUMES
> +  gCpuConfigGuid                                ## CONSUMES
> +  gPchGeneralConfigGuid                         ## CONSUMES
> +  gEfiTpmDeviceInstanceTpm20DtpmGuid
> +  gEfiTpmDeviceInstanceTpm12Guid
> +
> +[Ppis]
> +  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
> +
> +[Pcd]
> +  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
> +  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
> +  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
> +
> +[FixedPcd]
> +  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
> ## CONSUMES
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFunc.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFunc.h
> new file mode 100644
> index 0000000000..eca492e72d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFunc.h
> @@ -0,0 +1,18 @@
> +/** @file
> +  Header file for Board Hook function intance.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _BOARD_FUNC_H_
> +#define _BOARD_FUNC_H_
> +
> +EFI_STATUS
> +PeiBoardSpecificInitPostMemNull (
> +  VOID
> +  );
> +
> +#endif // _BOARD_FUNC_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardInitLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardInitLib.h
> new file mode 100644
> index 0000000000..5435b4a6e3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardInitLib.h
> @@ -0,0 +1,20 @@
> +/** @file
> + Header file for board Init function for Post Memory Init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_BOARD_INIT_LIB_H_
> +#define _PEI_BOARD_INIT_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <PlatformBoardId.h>
> +
> +#endif // _PEI_BOARD_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardSaConfigPreMem.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardSaConfigPreMem.h
> new file mode 100644
> index 0000000000..41c798a082
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardSaConfigPreMem.h
> @@ -0,0 +1,90 @@
> +/** @file
> +  PEI Boards Configurations for PreMem phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _BOARD_SA_CONFIG_PRE_MEM_H_
> +#define _BOARD_SA_CONFIG_PRE_MEM_H_
> +
> +#include <ConfigBlock.h>
> +#include <ConfigBlock/MemoryConfig.h>               // for MRC Configuration
> +#include <ConfigBlock/SwitchableGraphicsConfig.h>   // for PCIE RTD3 GPIO
> +#include <GpioPinsCnlLp.h>                          // for GPIO definition
> +#include <GpioPinsCnlH.h>
> +#include <SaAccess.h>                               // for Root Port number
> +#include <PchAccess.h>                              // for Root Port number
> +
> +//
> +// The following section contains board-specific CMD/CTL/CLK and DQ/DQS
> mapping, needed for LPDDR3/LPDDR4
> +//
> +
> +//
> +// DQByteMap[0] - ClkDQByteMap:
> +//   If clock is per rank, program to [0xFF, 0xFF]
> +//   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
> +//   If clock is shared by 2 ranks but does not go to all bytes,
> +//           Entry[i] defines which DQ bytes Group i services
> +// DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is
> CmdN/CAB
> +// DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is
> CmdS/CAB
> +// DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE
> /CAB
> +//                For DDR, DQByteMap[3:1] = [0xFF, 0]
> +// DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have
> 1 CTL / rank
> +//                               Variable only exists to make the code easier to use
> +// DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we
> have 1 CA Vref
> +//                               Variable only exists to make the code easier to use
> +//
> +//
> +// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for WHL RVP3, WHL
> SDS - used by WHL/WHL MRC
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8
> mDqByteMapWhlUDdr4Rvp[2][6][2] = {
> +  // Channel 0:
> +  {
> +    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package
> 1 - Bytes[7:4]
> +    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
> +    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
> +    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
> +    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
> +    { 0xFF, 0x00 }  // CA Vref is one for all bytes
> +  },
> +  // Channel 1:
> +  {
> +    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package
> 1 - Bytes[7:4]
> +    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
> +    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
> +    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
> +    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
> +    { 0xFF, 0x00 }  // CA Vref is one for all bytes
> +  }
> +};
> +
> +//
> +// DQS byte swizzling between CPU and DRAM
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8
> mDqsMapCpu2DramWhlUDdr4Rvp[2][8] = {
> +  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
> +  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
> +};
> +
> +//
> +// DQS byte swizzling between CPU and DRAM
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8
> DqsMapCpu2DramWhlUmDvp[2][8] = {
> +  { 0, 3, 1, 2, 7, 5, 6, 4 }, // Channel 0
> +  { 0, 2, 1, 3, 6, 4, 7, 5 }  // Channel 1
> +};
> +
> +//
> +// Reference RCOMP resistors on motherboard
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT16
> RcompResistorCflUDdr4Interposer[SA_MRC_MAX_RCOMP] = { 121, 81, 100 };
> +
> +//
> +// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT16
> RcompTargetWhlUDdr4Interposer[SA_MRC_MAX_RCOMP_TARGETS] = { 100,
> 40, 20, 20, 26 };
> +
> +#endif // _BOARD_SA_CONFIG_PRE_MEM_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableDefault.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableDefault.h
> new file mode 100644
> index 0000000000..a943d5bd04
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableDefault.h
> @@ -0,0 +1,225 @@
> +/** @file
> +  GPIO definition table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GPIO_TABLE_DEFAULT_H_
> +#define _GPIO_TABLE_DEFAULT_H_
> +
> +#include <GpioPinsCnlLp.h>
> +#include <Library/GpioLib.h>
> +#include <GpioConfig.h>
> +
> +#define END_OF_GPIO_TABLE 0xFFFFFFFF
> +
> +//
> +// CNL U DRR4 Board GPIO table configuration is used as default
> +//
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG
> mGpioTableDefault[] =
> +{
> +//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,
> GPIRoutConfig,  PadRstCfg,  Term,
> +  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_0
> +  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_1
> +  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_2
> +  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_2
> +  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_CSB
> +  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
> +  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntSci,  GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
> +  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
> +  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,
> GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},
> //WWAN_WAKE_N
> +  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2,
> GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault,
> GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
> +  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset,
> GpioTermNone } },  //DGPU_SEL_SLOT1
> +  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
> +  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //SPKR_PD_N
> +  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //WFCAM_PWREN
> +  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
> +  //(RC control) {GPIO_CNL_LP_GPP_A18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermWpu20K }},  //ACCEL_INT
> +  //(RC control) {GPIO_CNL_LP_GPP_A19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermWpu20K }},  //ALS_INT
> +  //(RC control) {GPIO_CNL_LP_GPP_A20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
> +  //(RC control) {GPIO_CNL_LP_GPP_A21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermWpu20K }},  //HALL_SENSOR_INT
> +  //(RC control) {GPIO_CNL_LP_GPP_A22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //IVCAM_WAKE
> +  //(RC control) {GPIO_CNL_LP_GPP_A23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermWpu20K }},  //SHARED_INT
> +  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,
> GpioResetDefault,  GpioTermNone }},  //CORE_VID0
> +  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,
> GpioResetDefault,  GpioTermNone }},  //CORE_VID0
> +  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,
> GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock } },
> //BT_UART_WAKE
> +  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock }},
> //FORCE_PAD_INT
> +  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone ,
> GpioPadConfigUnlock} },  //BT_DISABLE_N
> +  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
> +  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone }},
> +  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
> +  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
> +  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //TCH_PNL_PWR_EN
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_B15,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutLow,  GpioIntDis,
> GpioPlatformReset,  GpioTermNone }},  //NFC_DFU
> +  { GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
> +  { GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone,
> GpioPadConfigUnlock} },  //FPS_RESET_N
> +  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},
> //TBT_CIO_PWR_EN
> +  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
> +  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
> +  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
> +  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
> +  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone}},  //EC_SLP_S0_CS_N
> +  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
> +  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,
> GpioTermNone }},  //WIFI_RF_KILL_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
> +  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,
> GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},
> //WIFI_WAKE_N
> +  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic,
> GpioHostDeepReset, GpioTermWpu20K } },  //CODEC_INT_N
> +  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset,
> GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
> +  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone}},  //TBT_FORCE_PWR
> +  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
> +  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //PCIE_NAND_RST_N
> +  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //PCIE_NAND_PWREN_N
> +  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //SLOT1_PWREN_N
> +  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //SLOT1_RST_N
> +  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
> +  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
> +  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
> +  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
> +  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
> +  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
> +  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
> +  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
> +  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
> +  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone }},  //TCH_PNL2_RST_N
> +  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
> +  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,
> GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }},
> //SLOT1_WAKE_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,
> GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //NFC_RST_N
> +  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,
> GpioTermNone }},  //WWAN_PWREN
> +  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone }},  //TCH_PNL_RST_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,
> GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,
> GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},
> //NFC_INT_N
> +  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,
> GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
> +  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
> +  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
> +  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
> +  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
> +  {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //SPI1_TCH_PNL_IO2
> +  {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //SPI1_TCH_PNL_IO3
> +  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
> +  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,
> GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,
> GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
> +  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,
> GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
> +  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,
> GpioTermWpu20K}},  //Reserved for SATA HP val
> +  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,
> GpioTermNone}},  //EC_SMI_N
> +  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
> +  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,
> GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},
> //SSD_DEVSLP
> +  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,
> GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},
> //HDD_DEVSLP
> +  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,
> GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},
> //TCH_PNL_INT_N
> +  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
> +  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
> +  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
> +  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
> +  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
> +  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
> +  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
> +  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
> +  //(Not used){GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F0_COEX3
> +  {GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},
> //WWAN_RST_N
> +  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //SATA_HDD_PWREN
> +  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //WF_CLK_EN
> +  //(RC control) {GPIO_CNL_LP_GPP_F4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //CNV_BRI_DT_UART0_RTSB
> +  //(RC control) {GPIO_CNL_LP_GPP_F5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //CNV_BRI_RSP_UART0_RXD
> +  //(RC control) {GPIO_CNL_LP_GPP_F6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //CNV_RGI_DT_UART0_TXD
> +  //(RC control) {GPIO_CNL_LP_GPP_F7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //CNV_RGI_RSP_UART0_CTSB
> +  {GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermNone }},  //CNV_MFUART2_RXD
> +  {GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermNone }},  //CNV_MFUART2_TXD
> +
> +  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be
> used at IsRecoveryMode()
> +  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone}},  //BIOS_REC
> +
> +  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
> +  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
> +  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
> +  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
> +  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
> +  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
> +  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
> +  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
> +  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
> +  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
> +  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
> +  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
> +  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //GPP_F_23
> +  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
> +  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
> +  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
> +  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
> +  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
> +  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
> +  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
> +  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpd20K }},  //GPP_G_7_SD3_WP
> +  //{GPIO_CNL_LP_GPP_H0,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //GPP_H_0_SSP2_SCLK
> +  //{GPIO_CNL_LP_GPP_H1,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //GPP_H_1_SSP2_SFRM
> +  //{GPIO_CNL_LP_GPP_H2,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //GPP_H_2_SSP2_TXD
> +  //{GPIO_CNL_LP_GPP_H3,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //GPP_H_3_SSP2_RXD
> +  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
> +  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
> +  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
> +  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
> +  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
> +  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
> +  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_PWREN
> +  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_RECOVERY
> +  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IRIS_STROBE
> +  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_MUX_SEL0
> +  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
> +  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_KEY
> +  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
> +  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
> +  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
> +  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_MUX_SEL1
> +  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
> +  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H21
> +  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //WF_CAM_RST
> +  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H23
> +  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //BC_ACOK
> +  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
> +  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //SLP_A_N
> +  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermNone }},  //GPD_7
> +  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //SUS_CLK
> +  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
> +  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermWpd20K }}, // 20K PD for PECI
> +};
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG
> mGpioTablePreMemDefault[] =
> +{
> +  {END_OF_GPIO_TABLE,  {GpioPadModeGpio,    GpioHostOwnGpio,
> GpioDirNone,  GpioOutDefault, GpioIntDis, GpioDswReset,
> GpioTermNone}},//Marking End of Table
> +};
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableWhlUDdr4.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableWhlUDdr4.h
> new file mode 100644
> index 0000000000..86b7cb3717
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableWhlUDdr4.h
> @@ -0,0 +1,284 @@
> +/** @file
> +  GPIO definition table for WhiskeyLake U Ddr4 RVP
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
> +#define _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
> +
> +#include <GpioPinsCnlLp.h>
> +#include <Library/GpioLib.h>
> +#include <GpioConfig.h>
> +
> +static GPIO_INIT_CONFIG mGpioTableWhlUDdr4_0[] =
> +{
> +//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,
> GPIRoutConfig,  PadRstCfg,  Term,
> +  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_0
> +  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_1
> +  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_2
> +  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_IO_2
> +  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone }},  //eSPI_CSB
> +  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
> +  // TPM interrupt
> +  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
> +  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
> +  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //{GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,
> GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},
> //WWAN_WAKE_N
> +  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2,
> GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault,
> GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
> +  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset,
> GpioTermNone } },  //DGPU_SEL_SLOT1
> +  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
> +  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //SPKR_PD_N
> +  {GPIO_CNL_LP_GPP_A16, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutLow, GpioIntDefault, GpioPlatformReset,
> GpioTermWpu20K, GpioPadUnlock }},  //WFCAM_PWREN
> +  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
> +  //A18-A23 -> Under GPIO table for GPIO Termination -20K WPU
> +  {GPIO_CNL_LP_GPP_A18,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //ACCEL_INT
> +  {GPIO_CNL_LP_GPP_A19,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //ALS_INT
> +  {GPIO_CNL_LP_GPP_A20,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
> +  {GPIO_CNL_LP_GPP_A21,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //HALL_SENSOR_INT
> +  {GPIO_CNL_LP_GPP_A22,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //IVCAM_WAKE
> +  {GPIO_CNL_LP_GPP_A23,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //SHARED_INT
> +  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,
> GpioResetDefault,  GpioTermNone }},  //CORE_VID0
> +  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,
> GpioResetDefault,  GpioTermNone }},  //CORE_VID0
> +  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,
> GpioTermNone, GpioPadUnlock } },  //BT_UART_WAKE
> +  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,
> GpioTermNone, GpioPadUnlock }},  //FORCE_PAD_INT
> +  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone ,
> GpioOutputStateUnlock} },  //BT_DISABLE_N
> +  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
> +  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
> +  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone }},
> +  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
> +  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
> +  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //TCH_PNL_PWR_EN
> +  //B15 -Unused pin -> Under GPIO table for GPIO Termination - Input sensing
> disable
> +  {GPIO_CNL_LP_GPP_B15, { GpioPadModeGpio,  GpioHostOwnDefault,
> GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,
> GpioTermNone }},  //Former NFC_DFU
> +  {GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
> +  {GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone,
> GpioPadConfigUnlock} },  //FPS_RESET_N
> +  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},
> //TBT_CIO_PWR_EN
> +  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
> +  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
> +  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
> +  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
> +  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermNone, GpioPadUnlock }},  //EC_SLP_S0_CS_N
> +  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
> +  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,
> GpioTermNone, GpioOutputStateUnlock }},  //WIFI_RF_KILL_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
> +  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,
> GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},
> //WIFI_WAKE_N
> +  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},
> +  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi ,
> GpioDirIn , GpioOutDefault , GpioIntLevel | GpioIntApic , GpioPlatformReset,
> GpioTermWpu20K } },  //CODEC_INT_N
> +  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset,
> GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
> +  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone, GpioPadUnlock }},  //TBT_FORCE_PWR
> +  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
> +  //move to premem phase for early power turn on
> +  //  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //PCIE_NAND_RST_N
> +  //  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //PCIE_NAND_PWREN_N
> +  //  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //SLOT1_PWREN_N
> +  //  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //SLOT1_RST_N
> +
> +  //Only clear Reset pins in Post-Mem
> +  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //PCIE_NAND_RST_N
> +  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},  //SLOT1_RST_N
> +
> +  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
> +  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
> +  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
> +  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
> +  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
> +  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
> +  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
> +  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
> +  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
> +  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
> +  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
> +  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone }},  //TCH_PNL2_RST_N
> +  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
> +  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,
> GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},
> //SLOT1_WAKE_N
> +  //(Not used) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,
> GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //Former NFC_RST_N
> +  //{GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,
> GpioTermNone }},  //WWAN_PWREN
> +  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone }},  //TCH_PNL_RST_N
> +  //(Not used) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,
> GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,
> GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},
> //Former NFC_INT_N
> +  //{GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,
> GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
> +  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
> +  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
> +  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
> +  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
> +  //(CSME control) {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
> +  //(CSME control) {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
> +  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
> +  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,
> GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,
> GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
> +  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,
> GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
> +  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,
> GpioTermWpu20K}},  //Reserved for SATA HP val
> +  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,
> GpioTermNone, GpioPadUnlock}},  //EC_SMI_N
> +  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,
> GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
> +  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,
> GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},
> //SSD_DEVSLP
> +  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,
> GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},
> //HDD_DEVSLP
> +  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,
> GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,
> GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},
> //TCH_PNL_INT_N
> +  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
> +  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,
> GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
> +  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
> +  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
> +  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
> +  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
> +  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
> +  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
> +  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
> +  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
> +   //F0- unused pin-Input Sensing disable F4-F7 -> Under GPIO table for GPIO
> Termination -20K WPU
> +  {GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,
> GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,
> GpioTermNone }},  //GPP_F0_COEX3
> +  //{GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},
> //WWAN_RST_N
> +  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermWpu20K }},  //SATA_HDD_PWREN
> +  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermWpu20K, GpioPadUnlock }},  //WF_CLK_EN
> +  {GPIO_CNL_LP_GPP_F4,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //CNV_BRI_DT_UART0_RTSB
> +  {GPIO_CNL_LP_GPP_F5,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //CNV_BRI_RSP_UART0_RXD
> +  {GPIO_CNL_LP_GPP_F6,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //CNV_RGI_DT_UART0_TXD
> +  {GPIO_CNL_LP_GPP_F7,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //CNV_RGI_RSP_UART0_CTSB
> +  //{GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //CNV_MFUART2_RXD
> +  //{GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //CNV_MFUART2_TXD
> +
> +  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be
> used at IsRecoveryMode()
> +  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,
> GpioTermWpu20K}},  //BIOS_REC
> +
> +  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
> +  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
> +  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
> +  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
> +  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
> +  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
> +  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
> +  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
> +  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
> +  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
> +  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
> +  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
> +  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //GPP_F_23
> +  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
> +  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
> +  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
> +  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
> +  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
> +  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
> +  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
> +  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpd20K }},  //GPP_G_7_SD3_WP
> +  //H0-H3 -> Under GPIO table for GPIO Termination -20K WPU
> +  {GPIO_CNL_LP_GPP_H0,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //GPP_H_0_SSP2_SCLK
> +  {GPIO_CNL_LP_GPP_H1,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //GPP_H_1_SSP2_SFRM
> +  {GPIO_CNL_LP_GPP_H2,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //GPP_H_2_SSP2_TXD
> +  {GPIO_CNL_LP_GPP_H3,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermWpu20K }},  //GPP_H_3_SSP2_RXD
> +  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
> +  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
> +  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
> +  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
> +  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
> +  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
> +  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_PWREN
> +  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_RECOVERY
> +  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IRIS_STROBE
> +  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_MUX_SEL0
> +  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
> +  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_KEY
> +  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
> +  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
> +  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
> +  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone }},  //IVCAM_MUX_SEL1
> +  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
> +  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H21
> +  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,
> GpioTermNone, GpioPadUnlock }},  //WF_CAM_RST
> +  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,
> GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioPlatformReset,  GpioTermNone }},  //GPP_H23
> +  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //BC_ACOK
> +  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
> +  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //SLP_A_N
> +  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,
> GpioTermNone }},  //GPD_7
> +  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //SUS_CLK
> +  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
> +  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,
> GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,
> GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
> +  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,
> GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,
> GpioTermWpd20K }}, // 20K PD for PECI
> +};
> +
> +static GPIO_INIT_CONFIG mGpioTableCflUDdr4[] = {
> +  //                       Pmode,                GPI_IS,             GpioDir,
> GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
> +  // WiGig start
> +  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,
> GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
> +  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioHostDeepReset,
> GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
> +  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirInInv,    GpioOutHigh, GpioIntLevel | GpioIntSci,
> GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},
> //WIGIG_PEWAKE_R_N / WF_CAM_RST on CNL U
> +  //WiGig end
> +  // Camera start
> +  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirDefault, GpioOutDefault, GpioIntDefault,
> GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,
> GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
> +  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,
> GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
> +  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirDefault, GpioOutDefault, GpioIntDefault,
> GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
> +  // Camera end
> +  // Touch start
> +  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic,
> GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }},
> //TCH_PNL2_INT_N
> +  // Touch end
> +  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio,      GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,
> GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }},
> //SMC_RUNTIME_SCI_N
> +  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,      GpioHostOwnAcpi,
> GpioDirOut,    GpioOutHigh, GpioIntDis,                   GpioPlatformReset,
> GpioTermNone}},  //SLOT1_RST_N
> +  // TPM interrupt
> +  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock } },  //SPI_TPM_INT_N
> // Unused start
> +  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,
> GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,
> GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,
> GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,
> GpioTermWpu20K }}, //Unused so disabled / WF_CLK_EN on CNL U
> +  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,
> GpioTermNone   }}, //Unused so disabled / Not used on CNL U
> +  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,      GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,
> GpioTermNone   }}  //Unused so disabled / Not used on CNL U
> +  // Unused end
> +};
> +
> +static GPIO_INIT_CONFIG mGpioTableWhlUDdr4[] = {
> +  //                       Pmode,                GPI_IS,             GpioDir,
> GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
> +  // WiGig start
> +  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,
> GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
> +  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioHostDeepReset,
> GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
> +  // WiGig end
> +  // Camera start
> +  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,
> GpioTermNone   }}, //Camera / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,
> GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
> +  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,
> GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
> +  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,
> GpioTermNone   }}, //Camera / RC Control on CNL U
> +  // Camera end
> +  // Touch start
> +  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,
> GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
> +  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,
> GpioTermNone}},    //SLOT1_RST_N
> +  // Touch end
> +  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio, GpioHostOwnAcpi,
> GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,  GpioPlatformReset,
> GpioTermWpu20K,  GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
> +  // TBT start
> +  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,
> GpioTermNone   }},  //TBT_CIO_PWR_EN
> +  // TBT end
> +  // TPM interrupt
> +  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock }},         //SPI_TPM_INT_N
> +  // Unused start
> +  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,
> GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,
> GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
> +  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio, GpioHostOwnGpio,
> GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,
> GpioTermWpu20K }}  //Unused so disabled / WF_CLK_EN on CNL U
> +  // Unused end
> +};
> +
> +
> +#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableWhlUDdr4PreMem.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableWhlUDdr4PreMem.h
> new file mode 100644
> index 0000000000..01a6599564
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/GpioTableWhlUDdr4PreMem.h
> @@ -0,0 +1,59 @@
> +/** @file
> +  GPIO definition table for WhiskeyLake U Ddr4 RVP Pre-Memory
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
> +#define _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
> +
> +#include <GpioPinsCnlLp.h>
> +#include <Library/GpioLib.h>
> +#include <GpioConfig.h>
> +
> +static GPIO_INIT_CONFIG mGpioTableWhlUDdr4PreMem[] =
> +{
> +  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //SLOT1_RST_N
> +  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //SLOT1_PWREN_N
> +  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //PCIE_NAND_RST_N
> +  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //PCIE_NAND_PWREN_N
> +};
> +
> +static GPIO_INIT_CONFIG mGpioTableWhlTbtRvpPreMem[] =
> +{
> +  // do not reset SLOT1 due to TR AIC card cannot be reset in S3/S4 resume.
> +  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //SLOT1_RST_N
> +  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //SLOT1_PWREN_N
> +  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //PCIE_NAND_RST_N
> +  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,
> GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,
> GpioTermNone}},   //PCIE_NAND_PWREN_N
> +};
> +
> +
> +static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOnEarlyPreMem[] =
> +{
> +  // Turn on WWAN power and de-assert reset pins by default
> +  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
> +  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
> +  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
> +  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioPlatformReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
> +  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
> +  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
> +  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
> +};
> +
> +static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOffEarlyPreMem[] =
> +{
> +  // Assert reset pins and then turn off WWAN power
> +  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset,
> GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
> +  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
> +  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
> +  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioPlatformReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
> +  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
> +  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
> +  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,
> GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,
> GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
> +};
> +
> +#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PchHdaVerbTables.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PchHdaVerbTables.h
> new file mode 100644
> index 0000000000..0d26e8ad7a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PchHdaVerbTables.h
> @@ -0,0 +1,3014 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_HDA_VERB_TABLES_H_
> +#define _PCH_HDA_VERB_TABLES_H_
> +
> +#include <Ppi/SiPolicy.h>
> +
> +HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio =
> HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: CFL Display Audio Codec
> +  //  Revision ID = 0xFF
> +  //  Codec Vendor: 0x8086280B
> +  //
> +  0x8086, 0x280B,
> +  0xFF, 0xFF,
> +  //
> +  // Display Audio Verb Table
> +  //
> +  // For GEN9, the Vendor Node ID is 08h
> +  // Port to be exposed to the inbox driver in the vanilla mode: PORT C -
> BIT[7:6] = 01b
> +  0x00878140,
> +  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
> +  0x00571C10,
> +  0x00571D00,
> +  0x00571E56,
> +  0x00571F18,
> +  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
> +  0x00671C20,
> +  0x00671D00,
> +  0x00671E56,
> +  0x00671F18,
> +  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
> +  0x00771C30,
> +  0x00771D00,
> +  0x00771E56,
> +  0x00771F18,
> +  // Disable the third converter and third Pin (NID 08h)
> +  0x00878140
> +);
> +
> +//
> +//codecs verb tables
> +//
> +HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC700)
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0700
> +  //
> +  0x10EC, 0x0700,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
> +  //Realtek HD Audio Codec : ALC700
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x411111F0
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x90170110
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A11030
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40622005
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x04211020
> +  //    NID 0x29 : 0x411111F0
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC10F2
> +  0x001720F2,
> +  0x00172110,
> +  0x001722EC,
> +  0x00172310,
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C00,
> +  0x01271D00,
> +  0x01271E00,
> +  0x01271F40,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C10,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C30,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C05,
> +  0x01D71D20,
> +  0x01D71E62,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C20,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +  //Widget node 0x20 :
> +  0x02050045,
> +  0x02045289,
> +  0x0205004A,
> +  0x0204201B,
> +  //Widget node 0x20 - 1 :
> +  0x05850000,
> +  0x05843888,
> +  0x0205006F,
> +  0x02042C0B,
> +
> +
> +  //Widget node 0X20 for ALC1305   20160603 update
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040000,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040600,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FFD0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02040DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x0204005D,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040442,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040005,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040006,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040008,
> +  0x02050028,
> +  0x0204B000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204002E,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C3,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204D4A0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204400A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040320,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040039,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003B,
> +  0x02050028,
> +  0x0204FFFF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02041DFE,
> +  0x02050029,
> +  0x0204B024,
> +  //
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C0,
> +  0x02050028,
> +  0x020401FA,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C1,
> +  0x02050028,
> +  0x0204DE23,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C2,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C3,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C4,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C5,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C6,
> +  0x02050028,
> +  0x020403F5,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C7,
> +  0x02050028,
> +  0x0204AF1B,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C8,
> +  0x02050028,
> +  0x02041E0A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C9,
> +  0x02050028,
> +  0x0204368E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CA,
> +  0x02050028,
> +  0x020401FA,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CB,
> +  0x02050028,
> +  0x0204DE23,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CC,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CD,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CE,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CF,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D0,
> +  0x02050028,
> +  0x020403F5,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D1,
> +  0x02050028,
> +  0x0204AF1B,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D2,
> +  0x02050028,
> +  0x02041E0A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D3,
> +  0x02050028,
> +  0x0204368E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040040,
> +  0x02050028,
> +  0x0204800F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040062,
> +  0x02050028,
> +  0x02048000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040063,
> +  0x02050028,
> +  0x02044848,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040064,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040065,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040066,
> +  0x02050028,
> +  0x02044004,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040067,
> +  0x02050028,
> +  0x02040802,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040068,
> +  0x02050028,
> +  0x0204890F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040069,
> +  0x02050028,
> +  0x0204E021,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040070,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040071,
> +  0x02050000,
> +  0x02043330,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040072,
> +  0x02050000,
> +  0x02043333,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040073,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040074,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040075,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040076,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040050,
> +  0x02050028,
> +  0x020402EC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040051,
> +  0x02050028,
> +  0x02044909,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040052,
> +  0x02050028,
> +  0x020440B0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040046,
> +  0x02050028,
> +  0x0204C22E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040047,
> +  0x02050028,
> +  0x02040C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040048,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040049,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004A,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004B,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204721F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204009E,
> +  0x02050028,
> +  0x02040001,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040500,
> +  0x02050029,
> +  0x0204B024
> +); // HdaVerbTableAlc700
> +
> +HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC701)
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0701
> +  //
> +  0x10EC, 0x0701,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
> +  //Realtek HD Audio Codec : ALC701
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x411111F0
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x90170110
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A11030
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40610041
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x04211020
> +  //    NID 0x29 : 0x411111F0
> +
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC1124
> +  0x00172024,
> +  0x00172111,
> +  0x001722EC,
> +  0x00172310,
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C00,
> +  0x01271D00,
> +  0x01271E00,
> +  0x01271F40,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C10,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C30,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C41,
> +  0x01D71D00,
> +  0x01D71E61,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C20,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +  //Widget node 0x20 :
> +  0x02050045,
> +  0x02045289,
> +  0x0205004A,
> +  0x0204201B,
> +  //Widget node 0x20 - 1 :
> +  0x05850000,
> +  0x05843888,
> +  0x0205006F,
> +  0x02042C0B
> +); // HdaVerbTableAlc701
> +
> +HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC274)
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0274
> +  //
> +  0x10EC, 0x0274,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
> +  //Realtek HD Audio Codec : ALC274
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
> +  //The number of verb command block : 16
> +
> +  //    NID 0x12 : 0x40000000
> +  //    NID 0x13 : 0x411111F0
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x411111F0
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A11020
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40451B05
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x04211010
> +
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //,DA Codec Subsystem ID  : 0x10EC10F6
> +  0x001720F6,
> +  0x00172110,
> +  0x001722EC,
> +  0x00172310,
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C00,
> +  0x01271D00,
> +  0x01271E00,
> +  0x01271F40,
> +  //Pin widget 0x13 - DMIC
> +  0x01371CF0,
> +  0x01371D11,
> +  0x01371E11,
> +  0x01371F41,
> +  //Pin widget 0x14 - NPC
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S_OUT2
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S_OUT1
> +  0x01771CF0,
> +  0x01771D11,
> +  0x01771E11,
> +  0x01771F41,
> +  //Pin widget 0x18 - I2S_IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C20,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C05,
> +  0x01D71D1B,
> +  0x01D71E45,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C10,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Widget node 0x20 :
> +  0x02050045,
> +  0x02045289,
> +  0x0205006F,
> +  0x02042C0B,
> +  //Widget node 0x20 - 1 :
> +  0x02050035,
> +  0x02048968,
> +  0x05B50001,
> +  0x05B48540,
> +  //Widget node 0x20 - 2 :
> +  0x05850000,
> +  0x05843888,
> +  0x05850000,
> +  0x05843888,
> +  //Widget node 0x20 - 3 :
> +  0x0205004A,
> +  0x0204201B,
> +  0x0205004A,
> +  0x0204201B
> +); //HdaVerbTableAlc274
> +
> +//
> +// CFL S Audio Codec
> +//
> +STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 =
> HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC700) CFL S RVP
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0700
> +  //
> +  0x10EC, 0x0700,
> +  0xFF, 0xFF,
> +
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
> +  //Realtek HD Audio Codec : ALC700
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x90A60130
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x03011010
> +  //    NID 0x17 : 0x90170120
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x04A1103E
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x03A11040
> +  //    NID 0x1D : 0x40600001
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x0421102F
> +  //    NID 0x29 : 0x411111F0
> +
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC112C
> +  0x0017202C,
> +  0x00172111,
> +  0x001722EC,
> +  0x00172310,
> +
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271C30,
> +  0x01271D01,
> +  0x01271EA6,
> +  0x01271F90,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671C10,
> +  0x01671D10,
> +  0x01671E01,
> +  0x01671F03,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C20,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C3E,
> +  0x01971D10,
> +  0x01971EA1,
> +  0x01971F04,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71C40,
> +  0x01B71D10,
> +  0x01B71EA1,
> +  0x01B71F03,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C01,
> +  0x01D71D00,
> +  0x01D71E60,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C2F,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F04,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +
> +  //Widget node 0x20 - 0  FAKE JD unplug
> +  0x02050008,
> +  0x0204A80F,
> +  0x02050008,
> +  0x0204A80F,
> +  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of
> NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
> +  0x0205006B,
> +  0x02044260,
> +  0x0205006B,
> +  0x02044260,
> +  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
> +  0x05B50010,
> +  0x05B45C1D,
> +  0x0205006F,
> +  0x02040F8B,   //Zeek, 0F8Bh
> +  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent
> control
> +  0x02050045,
> +  0x02045089,
> +  0x0205004A,
> +  0x0204201B,
> +  //Widget node 0x20 - 4   From JD detect
> +  0x02050008,
> +  0x0204A807,
> +  0x02050008,
> +  0x0204A807,
> +  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and
> enable I2S BCLK first
> +  0x02050090,
> +  0x02040424,
> +  0x00171620,
> +  0x00171720,
> +
> +  0x00171520,
> +  0x01770740,
> +  0x01770740,
> +  0x01770740,
> +
> +
> +  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove
> ALC1305 EQ setting
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040000,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02045548,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02041000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040600,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FFD0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02040DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x0204005D,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040442,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040005,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040006,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040008,
> +  0x02050028,
> +  0x0204B000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204002E,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C3,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204D4A0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204400A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040320,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040039,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003B,
> +  0x02050028,
> +  0x0204FFFF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x020400C0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCF0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C0,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C1,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C2,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C3,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C4,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C5,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C6,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C7,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C8,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C9,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CA,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CB,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CC,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CD,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CE,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CF,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D0,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D1,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D2,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D3,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040062,
> +  0x02050028,
> +  0x02048000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040063,
> +  0x02050028,
> +  0x02045F5F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040064,
> +  0x02050028,
> +  0x02042000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040065,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040066,
> +  0x02050028,
> +  0x02044004,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040067,
> +  0x02050028,
> +  0x02040802,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040068,
> +  0x02050028,
> +  0x0204890F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040069,
> +  0x02050028,
> +  0x0204E021,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040070,
> +  0x02050028,
> +  0x02048012,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040071,
> +  0x02050028,
> +  0x02043450,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040072,
> +  0x02050028,
> +  0x02040123,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040073,
> +  0x02050028,
> +  0x02044543,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040074,
> +  0x02050028,
> +  0x02042100,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040075,
> +  0x02050028,
> +  0x02044321,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040076,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040050,
> +  0x02050028,
> +  0x02048200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040051,
> +  0x02050028,
> +  0x02040707,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040052,
> +  0x02050028,
> +  0x02044090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204721F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040012,
> +  0x02050028,
> +  0x0204DFDF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204009E,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040500,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040060,
> +  0x02050028,
> +  0x02042213,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02041DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02043000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040040,
> +  0x02050028,
> +  0x0204000C,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040046,
> +  0x02050028,
> +  0x0204C22E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004B,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024
> +);
> +
> +
> +//
> +// WHL codecs verb tables
> +//
> +HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 =
> HDAUDIO_VERB_TABLE_INIT (
> +  //
> +  //  VerbTable: (Realtek ALC700) WHL RVP
> +  //  Revision ID = 0xff
> +  //  Codec Verb Table for WHL PCH boards
> +  //  Codec Address: CAd value (0/1/2)
> +  //  Codec Vendor: 0x10EC0700
> +  //
> +  0x10EC, 0x0700,
> +  0xFF, 0xFF,
> +
> //==============================================================
> =====================================
> +  //
> +  //                               Realtek Semiconductor Corp.
> +  //
> +
> //==============================================================
> =====================================
> +
> +  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
> +  //Realtek HD Audio Codec : ALC700
> +  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
> +  //HDA Codec PnP ID :
> HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
> +  //The number of verb command block : 17
> +
> +  //    NID 0x12 : 0x411111F0
> +  //    NID 0x13 : 0x40000000
> +  //    NID 0x14 : 0x411111F0
> +  //    NID 0x15 : 0x411111F0
> +  //    NID 0x16 : 0x411111F0
> +  //    NID 0x17 : 0x90170110
> +  //    NID 0x18 : 0x411111F0
> +  //    NID 0x19 : 0x02A19040
> +  //    NID 0x1A : 0x411111F0
> +  //    NID 0x1B : 0x411111F0
> +  //    NID 0x1D : 0x40638029
> +  //    NID 0x1E : 0x411111F0
> +  //    NID 0x1F : 0x411111F0
> +  //    NID 0x21 : 0x02211020
> +  //    NID 0x29 : 0x411111F0
> +
> +  //===== HDA Codec Subsystem ID Verb-table =====
> +  //HDA Codec Subsystem ID  : 0x10EC10F2
> +  0x001720F2,
> +  0x00172110,
> +  0x001722EC,
> +  0x00172310,
> +
> +  //===== Pin Widget Verb-table =====
> +  //Widget node 0x01 :
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  0x0017FF00,
> +  //Pin widget 0x12 - DMIC
> +  0x01271CF0,
> +  0x01271D11,
> +  0x01271E11,
> +  0x01271F41,
> +  //Pin widget 0x13 - DMIC
> +  0x01371C00,
> +  0x01371D00,
> +  0x01371E00,
> +  0x01371F40,
> +  //Pin widget 0x14 - FRONT (Port-D)
> +  0x01471CF0,
> +  0x01471D11,
> +  0x01471E11,
> +  0x01471F41,
> +  //Pin widget 0x15 - I2S-OUT
> +  0x01571CF0,
> +  0x01571D11,
> +  0x01571E11,
> +  0x01571F41,
> +  //Pin widget 0x16 - LINE3 (Port-B)
> +  0x01671CF0,
> +  0x01671D11,
> +  0x01671E11,
> +  0x01671F41,
> +  //Pin widget 0x17 - I2S-OUT
> +  0x01771C10,
> +  0x01771D01,
> +  0x01771E17,
> +  0x01771F90,
> +  //Pin widget 0x18 - I2S-IN
> +  0x01871CF0,
> +  0x01871D11,
> +  0x01871E11,
> +  0x01871F41,
> +  //Pin widget 0x19 - MIC2 (Port-F)
> +  0x01971C40,
> +  0x01971D90,
> +  0x01971EA1,
> +  0x01971F02,
> +  //Pin widget 0x1A - LINE1 (Port-C)
> +  0x01A71CF0,
> +  0x01A71D11,
> +  0x01A71E11,
> +  0x01A71F41,
> +  //Pin widget 0x1B - LINE2 (Port-E)
> +  0x01B71CF0,
> +  0x01B71D11,
> +  0x01B71E11,
> +  0x01B71F41,
> +  //Pin widget 0x1D - PC-BEEP
> +  0x01D71C29,
> +  0x01D71D80,
> +  0x01D71E63,
> +  0x01D71F40,
> +  //Pin widget 0x1E - S/PDIF-OUT
> +  0x01E71CF0,
> +  0x01E71D11,
> +  0x01E71E11,
> +  0x01E71F41,
> +  //Pin widget 0x1F - S/PDIF-IN
> +  0x01F71CF0,
> +  0x01F71D11,
> +  0x01F71E11,
> +  0x01F71F41,
> +  //Pin widget 0x21 - HP-OUT (Port-I)
> +  0x02171C20,
> +  0x02171D10,
> +  0x02171E21,
> +  0x02171F02,
> +  //Pin widget 0x29 - I2S-IN
> +  0x02971CF0,
> +  0x02971D11,
> +  0x02971E11,
> +  0x02971F41,
> +  //Widget node 0x20 - 0  FAKE JD unplug
> +  0x02050008,
> +  0x0204A80F,
> +  0x02050008,
> +  0x0204A80F,
> +
> +  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass
> DAC02 DRE(NID5B bit14)
> +  0x05B50010,
> +  0x05B45C1D,
> +  0x0205006F,
> +  0x02040F8B,   //Zeek, 0F8Bh
> +
> +  //Widget node 0x20 -2:
> +  0x02050045,
> +  0x02045089,
> +  0x0205004A,
> +  0x0204201B,
> +
> +  //Widget node 0x20 - 3   From JD detect
> +  0x02050008,
> +  0x0204A807,
> +  0x02050008,
> +  0x0204A807,
> +
> +  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and
> enable I2S BCLK first
> +  0x02050090,
> +  0x02040424,
> +  0x00171620,
> +  0x00171720,
> +
> +  0x00171520,
> +  0x01770740,
> +  0x01770740,
> +  0x01770740,
> +
> +  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove
> ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040000,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02045548,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02041000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040600,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FFD0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02040DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x0204005D,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040442,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040005,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040006,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040008,
> +  0x02050028,
> +  0x0204B000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204002E,
> +  0x02050028,
> +  0x02040800,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C3,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204D4A0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400CC,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204400A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x020400C1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040320,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040039,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003B,
> +  0x02050028,
> +  0x0204FFFF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x020400C0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCF0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040080,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040880,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCE0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FCA0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003C,
> +  0x02050028,
> +  0x0204FC20,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040006,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040080,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C0,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C1,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C2,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C3,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C4,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C5,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C6,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C7,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C8,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400C9,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CA,
> +  0x02050028,
> +  0x020401F0,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CB,
> +  0x02050028,
> +  0x0204C1C7,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CC,
> +  0x02050028,
> +  0x02041C00,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CD,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CE,
> +  0x02050028,
> +  0x02040200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400CF,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D0,
> +  0x02050028,
> +  0x020403E1,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D1,
> +  0x02050028,
> +  0x02040F5A,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D2,
> +  0x02050028,
> +  0x02041E1E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x020400D3,
> +  0x02050028,
> +  0x0204083F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040062,
> +  0x02050028,
> +  0x02048000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040063,
> +  0x02050028,
> +  0x02045F5F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040064,
> +  0x02050028,
> +  0x02042000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040065,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040066,
> +  0x02050028,
> +  0x02044004,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040067,
> +  0x02050028,
> +  0x02040802,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040068,
> +  0x02050028,
> +  0x0204890F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040069,
> +  0x02050028,
> +  0x0204E021,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040070,
> +  0x02050028,
> +  0x02048012,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040071,
> +  0x02050028,
> +  0x02043450,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040072,
> +  0x02050028,
> +  0x02040123,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040073,
> +  0x02050028,
> +  0x02044543,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040074,
> +  0x02050028,
> +  0x02042100,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040075,
> +  0x02050028,
> +  0x02044321,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040076,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040050,
> +  0x02050028,
> +  0x02048200,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040051,
> +  0x02050028,
> +  0x02040707,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040052,
> +  0x02050028,
> +  0x02044090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006A,
> +  0x02050028,
> +  0x02040090,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204006C,
> +  0x02050028,
> +  0x0204721F,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040012,
> +  0x02050028,
> +  0x0204DFDF,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204009E,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040004,
> +  0x02050028,
> +  0x02040500,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040060,
> +  0x02050028,
> +  0x0204E213,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003A,
> +  0x02050028,
> +  0x02041DFE,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204003F,
> +  0x02050028,
> +  0x02043000,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040040,
> +  0x02050028,
> +  0x0204000C,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x02040046,
> +  0x02050028,
> +  0x0204422E,
> +  0x02050029,
> +  0x0204B024,
> +
> +  0x02050024,
> +  0x02040010,
> +  0x02050026,
> +  0x0204004B,
> +  0x02050028,
> +  0x02040000,
> +  0x02050029,
> +  0x0204B024
> +); // WhlHdaVerbTableAlc700
> +
> +#endif // _PCH_HDA_VERB_TABLES_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitLib.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitLib.h
> new file mode 100644
> index 0000000000..89c780cc0b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitLib.h
> @@ -0,0 +1,41 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
> +#define _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/GpioLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <PchHsioPtssTables.h>
> +#include <IoExpander.h>
> +
> +#include <WhiskeylakeURvpId.h>
> +
> +extern const UINT8 mDqByteMapSklRvp3[2][6][2];
> +extern const UINT8 mDqsMapCpu2DramSklRvp3[2][8];
> +extern const UINT8 mSkylakeRvp3Spd110[];
> +extern const UINT16 mSkylakeRvp3Spd110Size;
> +extern HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[];
> +extern UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size;
> +extern HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[];
> +extern UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size;
> +
> +extern GPIO_INIT_CONFIG mGpioTableLpddr3Rvp3UcmcDevice[];
> +extern UINT16 mGpioTableLpddr3Rvp3UcmcDeviceSize;
> +
> +extern IO_EXPANDER_GPIO_CONFIG mGpioTableIoExpander[];
> +extern UINT16 mGpioTableIoExpanderSize;
> +extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3Touchpanel;
> +extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3[];
> +extern UINT16 mGpioTableLpDdr3Rvp3Size;
> +
> +#endif // _PEI_Whiskeylake_RVP3_BOARD_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxePolicyBoardConfig.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxePolicyBoardConfig.h
> new file mode 100644
> index 0000000000..a6d48e906d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxePolicyBoardConfig.h
> @@ -0,0 +1,20 @@
> +/** @file
> + Header file for DxePolicyBoardConfig library instance.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_POLICY_BOARD_CONFIG_H_
> +#define _DXE_POLICY_BOARD_CONFIG_H_
> +
> +#include <PiDxe.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/DxePolicyBoardConfigLib.h>
> +
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPolicyBoardConfig.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPolicyBoardConfig.h
> new file mode 100644
> index 0000000000..03c27f2a41
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPolicyBoardConfig.h
> @@ -0,0 +1,23 @@
> +/** @file
> + Header file for PeiPolicyBoardConfig library instance.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PEI_POLICY_BOARD_CONFIG_H_
> +#define _PEI_POLICY_BOARD_CONFIG_H_
> +
> +#include <PiPei.h>
> +#include <ConfigBlock/MePeiConfig.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/ConfigBlockLib.h>
> +#include <Library/PeiPolicyBoardConfigLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> FuncLib/Gop.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> FuncLib/Gop.c
> new file mode 100644
> index 0000000000..01b3df984a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> FuncLib/Gop.c
> @@ -0,0 +1,41 @@
> +/** @file
> +  Others Board's PCD function hook.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/DebugLib.h>
> +#include <GopConfigLib.h>
> +
> +//
> +// Null function for nothing GOP VBT update.
> +//
> +VOID
> +EFIAPI
> +GopVbtSpecificUpdateNull (
> +  IN CHILD_STRUCT **ChildStructPtr
> +  )
> +{
> +  return;
> +}
> +
> +//
> +// for CFL U DDR4
> +//
> +VOID
> +EFIAPI
> +CflUDdr4GopVbtSpecificUpdate(
> +  IN CHILD_STRUCT **ChildStructPtr
> +)
> +{
> +  ChildStructPtr[1]->DeviceClass = DISPLAY_PORT_ONLY;
> +  ChildStructPtr[1]->DVOPort     = DISPLAY_PORT_B;
> +  ChildStructPtr[2]->DeviceClass = DISPLAY_PORT_HDMI_DVI_COMPATIBLE;
> +  ChildStructPtr[2]->DVOPort     = DISPLAY_PORT_C;
> +  ChildStructPtr[2]->AUX_Channel = AUX_CHANNEL_C;
> +  ChildStructPtr[3]->DeviceClass = NO_DEVICE;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLib/BaseGpioCheckConflictLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLib/BaseGpioCheckConflictLib.c
> new file mode 100644
> index 0000000000..7ebf8f8fdc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLib/BaseGpioCheckConflictLib.c
> @@ -0,0 +1,137 @@
> +/** @file
> +  Implementation of BaseGpioCheckConflictLib.
> +
> +
> +  Copyright (c) 2019, 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 <Private/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 Hob Check] Can't find Gpio Hob.\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, "[Hob 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 Check] Identified conflict on pad
> %a\n", GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad)));
> +        }
> +      }
> +      //
> +      // 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 UINT16                    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 how big size the Hob Data needs
> +      //
> +      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 {
> +      GpioCheckConflictHobData[GpioIndex].GpioPad =
> GpioDefinition[Index].GpioPad;
> +      GpioCheckConflictHobData[GpioIndex].GpioPadMode =
> GpioDefinition[Index].GpioConfig.PadMode;
> +      GpioIndex++;
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n"));
> +  return;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
> new file mode 100644
> index 0000000000..178ce1a124
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> GpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
> @@ -0,0 +1,37 @@
> +/** @file
> +  Implementation of BaseGpioCheckConflicLibNull.
> +
> +
> +  Copyright (c) 2019, 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 UINT16                    GpioTableCount
> +  )
> +{
> +  return;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> PlatformHookLib/BasePlatformHookLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> PlatformHookLib/BasePlatformHookLib.c
> new file mode 100644
> index 0000000000..24c6fa6277
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Base
> PlatformHookLib/BasePlatformHookLib.c
> @@ -0,0 +1,156 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Library/PlatformHookLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PcdLib.h>
> +#include <SystemAgent/Include/SaAccess.h>
> +#include <SioRegs.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Register/PchRegsLpc.h>
> +#include <PchAccess.h>
> +
> +#define LPC_SIO_INDEX_DEFAULT_PORT_2              0x2E
> +#define LPC_SIO_DATA_DEFAULT_PORT_2               0x2F
> +
> +#define IT8628_ENTER_CONFIG_WRITE_SEQ_0           0x87
> +#define IT8628_ENTER_CONFIG_WRITE_SEQ_1           0x01
> +#define IT8628_ENTER_CONFIG_WRITE_SEQ_2           0x55
> +#define IT8628_ENTER_CONFIG_WRITE_SEQ_3           0x55
> +#define IT8628_EXIT_CONFIG                        0x2
> +#define IT8628_CHIPID_BYTE1                       0x86
> +#define IT8628_CHIPID_BYTE2                       0x28
> +
> +typedef struct {
> +  UINT8 Register;
> +  UINT8 Value;
> +} EFI_SIO_TABLE;
> +
> +//
> +// IT8628
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE
> mSioIt8628TableSerialPort[] = {
> +  {0x023, 0x09}, // Clock Selection register
> +  {0x007, 0x01}, // Com1 Logical Device Number select
> +  {0x061, 0xF8}, // Serial Port 1 Base Address MSB Register
> +  {0x060, 0x03}, // Serial Port 1 Base Address LSB Register
> +  {0x070, 0x04}, // Serial Port 1 Interrupt Level Select
> +  {0x030, 0x01}, // Serial Port 1 Activate
> +  {0x007, 0x02}, // Com1 Logical Device Number select
> +  {0x061, 0xF8}, // Serial Port 2 Base Address MSB Register
> +  {0x060, 0x02}, // Serial Port 2 Base Address MSB Register
> +  {0x070, 0x03}, // Serial Port 2 Interrupt Level Select
> +  {0x030, 0x01}  // Serial Port 2 Activate
> +};
> +
> +/**
> +  Check whether the IT8628 SIO present on LPC. If yes, enable its serial ports
> +**/
> +STATIC
> +VOID
> +It8628SioSerialPortInit (
> +  VOID
> +  )
> +{
> +  UINT8   ChipId0;
> +  UINT8   ChipId1;
> +  UINT16  LpcIoDecondeRangeSet;
> +  UINT16  LpcIoDecoodeSet;
> +  UINT8   Index;
> +  UINT64  LpcBaseAddr;
> +
> +  ChipId0              = 0;
> +  ChipId1              = 0;
> +  LpcIoDecondeRangeSet = 0;
> +  LpcIoDecoodeSet      = 0;
> +
> +  //
> +  // Enable I/O decoding for COM1 (3F8h-3FFh), COM2(2F8h-2FFh), I/O port
> 2Eh/2Fh.
> +  //
> +  LpcBaseAddr = PCI_SEGMENT_LIB_ADDRESS (
> +                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                  DEFAULT_PCI_BUS_NUMBER_PCH,
> +                  PCI_DEVICE_NUMBER_PCH_LPC,
> +                  PCI_FUNCTION_NUMBER_PCH_LPC,
> +                  0
> +                  );
> +
> +  LpcIoDecondeRangeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr +
> R_LPC_CFG_IOD);
> +  LpcIoDecoodeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr +
> R_LPC_CFG_IOE);
> +  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOD),
> (LpcIoDecondeRangeSet | ((V_LPC_CFG_IOD_COMB_2F8 << 4) |
> V_LPC_CFG_IOD_COMA_3F8)));
> +  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOE), (LpcIoDecoodeSet |
> (B_LPC_CFG_IOE_SE | B_LPC_CFG_IOE_CBE |
> B_LPC_CFG_IOE_CAE|B_LPC_CFG_IOE_KE)));
> +
> +  //
> +  // Enter MB PnP Mode
> +  //
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2,
> IT8628_ENTER_CONFIG_WRITE_SEQ_0);
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2,
> IT8628_ENTER_CONFIG_WRITE_SEQ_1);
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2,
> IT8628_ENTER_CONFIG_WRITE_SEQ_2);
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2,
> IT8628_ENTER_CONFIG_WRITE_SEQ_3);
> +
> +  //
> +  // Read Chip Id of SIO IT8628 (registers 0x20 and 0x21)
> +  //
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x20);
> +  ChipId0 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
> +
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x21);
> +  ChipId1 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
> +
> +  //
> +  // Enable Serial Port 1, Port 2
> +  //
> +  if ((ChipId0 == IT8628_CHIPID_BYTE1) && (ChipId1 ==
> IT8628_CHIPID_BYTE2)) {
> +    for (Index = 0; Index < sizeof (mSioIt8628TableSerialPort) / sizeof
> (EFI_SIO_TABLE); Index++) {
> +      IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2,
> mSioIt8628TableSerialPort[Index].Register);
> +      IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2,
> mSioIt8628TableSerialPort[Index].Value);
> +    }
> +  }
> +
> +  //
> +  // Exit MB PnP Mode
> +  //
> +  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
> +  IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
> +
> +  return;
> +}
> +
> +/**
> +  Performs platform specific initialization required for the CPU to access
> +  the hardware associated with a SerialPortLib instance.  This function does
> +  not initialize the serial port hardware itself.  Instead, it initializes
> +  hardware devices that are required for the CPU to access the serial port
> +  hardware.  This function may be called more than once.
> +
> +  @retval RETURN_SUCCESS       The platform specific initialization
> succeeded.
> +  @retval RETURN_DEVICE_ERROR  The platform specific initialization could
> not be completed.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +PlatformHookSerialPortInitialize (
> +  VOID
> +  )
> +{
> +  //
> +  // Enable I/O decoding for COM1(3F8h-3FFh), COM2(2F8h-2FFh), I/O port
> 2Eh/2Fh, 4Eh/4Fh, 60h/64Fh and 62h/66h.
> +  //
> +  PchLpcIoDecodeRangesSet (PcdGet16 (PcdLpcIoDecodeRange));
> +  PchLpcIoEnableDecodingSet (PcdGet16 (PchLpcIoEnableDecoding));
> +
> +  // Configure Sio IT8628
> +  It8628SioSerialPortInit ();
> +
> +  return RETURN_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmBoardAcpiEnableLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmBoardAcpiEnableLib.c
> new file mode 100644
> index 0000000000..e7acbda03a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmBoardAcpiEnableLib.c
> @@ -0,0 +1,63 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardAcpiEnableLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SiliconEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SiliconDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +BoardEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  )
> +{
> +  SiliconEnableAcpi (EnableSci);
> +  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  )
> +{
> +  SiliconDisableAcpi (DisableSci);
> +  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
> +}
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmMultiBoardAcpiSupportLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmMultiBoardAcpiSupportLib.c
> new file mode 100644
> index 0000000000..978e367cda
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmMultiBoardAcpiSupportLib.c
> @@ -0,0 +1,82 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardAcpiEnableLib.h>
> +#include <Library/MultiBoardAcpiSupportLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <WhiskeylakeURvpId.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SiliconEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SiliconDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpMultiBoardEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  )
> +{
> +  SiliconEnableAcpi (EnableSci);
> +  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpMultiBoardDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  )
> +{
> +  SiliconDisableAcpi (DisableSci);
> +  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
> +}
> +
> +BOARD_ACPI_ENABLE_FUNC  mWhiskeylakeURvpBoardAcpiEnableFunc = {
> +  WhiskeylakeURvpMultiBoardEnableAcpi,
> +  WhiskeylakeURvpMultiBoardDisableAcpi,
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor (
> +  VOID
> +  )
> +{
> +  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
> +    return RegisterBoardAcpiEnableFunc
> (&mWhiskeylakeURvpBoardAcpiEnableFunc);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmSiliconAcpiEnableLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmSiliconAcpiEnableLib.c
> new file mode 100644
> index 0000000000..9daceaa25c
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmSiliconAcpiEnableLib.c
> @@ -0,0 +1,170 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/BoardAcpiEnableLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +#include <PchAccess.h>
> +#include <Library/MmPciLib.h>
> +#include <Library/PmcLib.h>
> +
> +/**
> +  Clear Port 80h
> +
> +  SMI handler to enable ACPI mode
> +
> +  Dispatched on reads from APM port with value EFI_ACPI_ENABLE_SW_SMI
> +
> +  Disables the SW SMI Timer.
> +  ACPI events are disabled and ACPI event status is cleared.
> +  SCI mode is then enabled.
> +
> +  Clear SLP SMI status
> +  Enable SLP SMI
> +
> +  Disable SW SMI Timer
> +
> +  Clear all ACPI event status and disable all ACPI events
> +
> +  Disable PM sources except power button
> +  Clear status bits
> +
> +  Disable GPE0 sources
> +  Clear status bits
> +
> +  Disable GPE1 sources
> +  Clear status bits
> +
> +  Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
> +
> +  Enable SCI
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiliconEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  )
> +{
> +
> +  UINT32                              OutputValue;
> +  UINT32                              SmiEn;
> +  UINT32                              SmiSts;
> +  UINT32                              ULKMC;
> +  UINTN                               LpcBaseAddress;
> +  UINT16                              AcpiBaseAddr;
> +  UINT32                              Pm1Cnt;
> +
> +  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
> +    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +    DEFAULT_PCI_BUS_NUMBER_PCH,
> +    PCI_DEVICE_NUMBER_PCH_LPC,
> +    PCI_FUNCTION_NUMBER_PCH_LPC,
> +    0
> +    );
> +  //
> +  // Get the ACPI Base Address
> +  //
> +  AcpiBaseAddr = PmcGetAcpiBase();
> +  //
> +  // BIOS must also ensure that CF9GR is cleared and locked before handing
> control to the
> +  // OS in order to prevent the host from issuing global resets and resetting
> ME
> +  //
> +  // EDK2: To match PCCG current BIOS behavior, do not lock CF9 Global Reset
> +  // MmioWrite32 (
> +  //     PmcBaseAddress + R_PCH_PMC_ETR3),
> +  //     PmInit);
> +
> +  //
> +  // Clear Port 80h
> +  //
> +  IoWrite8 (0x80, 0);
> +
> +  //
> +  // Disable SW SMI Timer and clean the status
> +  //
> +  SmiEn = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN);
> +  SmiEn &= ~(B_ACPI_IO_SMI_EN_LEGACY_USB2 |
> B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB);
> +  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN, SmiEn);
> +
> +  SmiSts = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS);
> +  SmiSts |= B_ACPI_IO_SMI_EN_LEGACY_USB2 |
> B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB;
> +  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS, SmiSts);
> +
> +  //
> +  // Disable port 60/64 SMI trap if they are enabled
> +  //
> +  ULKMC = MmioRead32 (LpcBaseAddress + R_LPC_CFG_ULKMC) &
> ~(B_LPC_CFG_ULKMC_60REN | B_LPC_CFG_ULKMC_60WEN |
> B_LPC_CFG_ULKMC_64REN | B_LPC_CFG_ULKMC_64WEN |
> B_LPC_CFG_ULKMC_A20PASSEN);
> +  MmioWrite32 (LpcBaseAddress + R_LPC_CFG_ULKMC, ULKMC);
> +
> +  //
> +  // Disable PM sources except power button
> +  //
> +  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_EN,
> B_ACPI_IO_PM1_EN_PWRBTN);
> +
> +  //
> +  // Clear PM status except Power Button status for RapidStart Resume
> +  //
> +  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_STS, 0xFEFF);
> +
> +  //
> +  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
> +  //
> +  IoWrite8 (R_RTC_IO_INDEX_ALT, R_RTC_IO_REGD);
> +  IoWrite8 (R_RTC_IO_TARGET_ALT, 0x0);
> +
> +  //
> +  // Write ALT_GPI_SMI_EN to disable GPI1 (SMC_EXTSMI#)
> +  //
> +  OutputValue = IoRead32 (AcpiBaseAddr + 0x38);
> +  OutputValue = OutputValue & ~(1 << (UINTN) PcdGet8
> (PcdSmcExtSmiBitPosition));
> +  IoWrite32 (AcpiBaseAddr + 0x38, OutputValue);
> +
> +  //
> +  // Enable SCI
> +  //
> +  if (EnableSci) {
> +    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
> +    Pm1Cnt |= B_ACPI_IO_PM1_CNT_SCI_EN;
> +    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SiliconDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  )
> +{
> +
> +  UINT16                              AcpiBaseAddr;
> +  UINT32                              Pm1Cnt;
> +
> +  //
> +  // Get the ACPI Base Address
> +  //
> +  AcpiBaseAddr = PmcGetAcpiBase();
> +  //
> +  // Disable SCI
> +  //
> +  if (DisableSci) {
> +    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
> +    Pm1Cnt &= ~B_ACPI_IO_PM1_CNT_SCI_EN;
> +    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
> new file mode 100644
> index 0000000000..97a3fae51b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
> @@ -0,0 +1,40 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardAcpiTableLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <WhiskeylakeURvpId.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardEnableAcpi (
> +  IN BOOLEAN  EnableSci
> +  )
> +{
> +  // enable additional board register
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDisableAcpi (
> +  IN BOOLEAN  DisableSci
> +  )
> +{
> +  // enable additional board register
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFunc.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFunc.c
> new file mode 100644
> index 0000000000..7a2fed9904
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFunc.c
> @@ -0,0 +1,19 @@
> +/** @file
> +  Board's PCD function hook.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +EFI_STATUS
> +PeiBoardSpecificInitPostMemNull (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFuncInit.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFuncInit.c
> new file mode 100644
> index 0000000000..5104329825
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFuncInit.c
> @@ -0,0 +1,27 @@
> +/** @file
> +  Source code for the board configuration init function in Post Memory init
> phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BoardInitLib.h"
> +#include "BoardFunc.h"
> +
> +/**
> +  Board's PCD function hook init function for PEI post memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardFunctionInit (
> +  IN UINT16 BoardId
> +)
> +{
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFuncInitPreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFuncInitPreMem.c
> new file mode 100644
> index 0000000000..3a42a9bd03
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardFuncInitPreMem.c
> @@ -0,0 +1,41 @@
> +/** @file
> +  Source code for the board configuration init function in Post Memory init
> phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BoardInitLib.h"
> +#include <GopConfigLib.h>
> +//
> +// Null function for nothing GOP VBT update.
> +//
> +VOID
> +GopVbtSpecificUpdateNull(
> +  IN CHILD_STRUCT **ChildStructPtr
> +);
> +//
> +// for CFL U DDR4
> +//
> +VOID
> +CflUDdr4GopVbtSpecificUpdate(
> +  IN CHILD_STRUCT **ChildStructPtr
> +);
> +/**
> +  Board's PCD function hook init function for PEI post memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardFunctionInitPreMem (
> +  IN UINT16 BoardId
> +  )
> +{
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardPchInitPreMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardPchInitPreMemLib.c
> new file mode 100644
> index 0000000000..458a73f892
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardPchInitPreMemLib.c
> @@ -0,0 +1,398 @@
> +/** @file
> + Source code for the board PCH configuration Pcd init functions for
> Pre-Mmeory Init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BoardInitLib.h"
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +#include <PlatformBoardConfig.h>        // for USB 20 AFE & Root Port Clk
> Info.
> +#include "GpioTableWhlUDdr4PreMem.h"
> +#include <Library/BaseMemoryLib.h>
> +
> +/**
> +  Board Root Port Clock Info configuration init function for PEI pre-memory
> phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +RootPortClkInfoInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  PCD64_BLOB                      *Clock;
> +  UINT32                          Index;
> +
> +  Clock = AllocateZeroPool (16 * sizeof (PCD64_BLOB));
> +  ASSERT (Clock != NULL);
> +  if (Clock == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  //
> +  // The default clock assignment will be FREE_RUNNING, which corresponds
> to PchClockUsageUnspecified
> +  // This is safe but power-consuming setting. If Platform code doesn't contain
> port-clock map for a given board,
> +  // the clocks will keep on running anyway, allowing PCIe devices to operate.
> Downside is that clocks will
> +  // continue to draw power. To prevent this, remember to provide port-clock
> map for every board.
> +  //
> +  for (Index = 0; Index < 16; Index++) {
> +    Clock[Index].PcieClock.ClkReqSupported = TRUE;
> +    Clock[Index].PcieClock.ClockUsage = FREE_RUNNING;
> +  }
> +
> +  ///
> +  /// Assign ClkReq signal to root port. (Base 0)
> +  /// For LP, Set 0 - 5
> +  /// For H,  Set 0 - 15
> +  /// Note that if GbE is enabled, ClkReq assigned to GbE will not be available
> for Root Port.
> +  ///
> +  switch (BoardId) {
> +    // CLKREQ
> +    case BoardIdWhiskeyLakeRvp:
> +      Clock[0].PcieClock.ClockUsage = PCIE_PCH + 1;
> +      Clock[1].PcieClock.ClockUsage = PCIE_PCH + 8;
> +      Clock[2].PcieClock.ClockUsage = LAN_CLOCK;
> +      Clock[3].PcieClock.ClockUsage = PCIE_PCH + 13;
> +      Clock[4].PcieClock.ClockUsage = PCIE_PCH + 4;
> +      Clock[5].PcieClock.ClockUsage = PCIE_PCH + 14;
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  PcdSet64S (PcdPcieClock0,  Clock[ 0].Blob);
> +  PcdSet64S (PcdPcieClock1,  Clock[ 1].Blob);
> +  PcdSet64S (PcdPcieClock2,  Clock[ 2].Blob);
> +  PcdSet64S (PcdPcieClock3,  Clock[ 3].Blob);
> +  PcdSet64S (PcdPcieClock4,  Clock[ 4].Blob);
> +  PcdSet64S (PcdPcieClock5,  Clock[ 5].Blob);
> +  PcdSet64S (PcdPcieClock6,  Clock[ 6].Blob);
> +  PcdSet64S (PcdPcieClock7,  Clock[ 7].Blob);
> +  PcdSet64S (PcdPcieClock8,  Clock[ 8].Blob);
> +  PcdSet64S (PcdPcieClock9,  Clock[ 9].Blob);
> +  PcdSet64S (PcdPcieClock10, Clock[10].Blob);
> +  PcdSet64S (PcdPcieClock11, Clock[11].Blob);
> +  PcdSet64S (PcdPcieClock12, Clock[12].Blob);
> +  PcdSet64S (PcdPcieClock13, Clock[13].Blob);
> +  PcdSet64S (PcdPcieClock14, Clock[14].Blob);
> +  PcdSet64S (PcdPcieClock15, Clock[15].Blob);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Board USB related configuration init function for PEI pre-memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +UsbConfigInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  PCD32_BLOB *UsbPort20Afe;
> +
> +  UsbPort20Afe = AllocateZeroPool (PCH_MAX_USB2_PORTS * sizeof
> (PCD32_BLOB));
> +  ASSERT (UsbPort20Afe != NULL);
> +  if (UsbPort20Afe == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // USB2 AFE settings.
> +  //
> +  UsbPort20Afe[0].Info.Petxiset   = 7;
> +  UsbPort20Afe[0].Info.Txiset     = 5;
> +  UsbPort20Afe[0].Info.Predeemp   = 3;
> +  UsbPort20Afe[0].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[1].Info.Petxiset   = 7;
> +  UsbPort20Afe[1].Info.Txiset     = 5;
> +  UsbPort20Afe[1].Info.Predeemp   = 3;
> +  UsbPort20Afe[1].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[2].Info.Petxiset   = 7;
> +  UsbPort20Afe[2].Info.Txiset     = 5;
> +  UsbPort20Afe[2].Info.Predeemp   = 3;
> +  UsbPort20Afe[2].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[3].Info.Petxiset   = 7;
> +  UsbPort20Afe[3].Info.Txiset     = 5;
> +  UsbPort20Afe[3].Info.Predeemp   = 3;
> +  UsbPort20Afe[3].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[4].Info.Petxiset   = 7;
> +  UsbPort20Afe[4].Info.Txiset     = 5;
> +  UsbPort20Afe[4].Info.Predeemp   = 3;
> +  UsbPort20Afe[4].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[5].Info.Petxiset   = 7;
> +  UsbPort20Afe[5].Info.Txiset     = 5;
> +  UsbPort20Afe[5].Info.Predeemp   = 3;
> +  UsbPort20Afe[5].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[6].Info.Petxiset   = 7;
> +  UsbPort20Afe[6].Info.Txiset     = 5;
> +  UsbPort20Afe[6].Info.Predeemp   = 3;
> +  UsbPort20Afe[6].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[7].Info.Petxiset   = 7;
> +  UsbPort20Afe[7].Info.Txiset     = 5;
> +  UsbPort20Afe[7].Info.Predeemp   = 3;
> +  UsbPort20Afe[7].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[8].Info.Petxiset   = 7;
> +  UsbPort20Afe[8].Info.Txiset     = 5;
> +  UsbPort20Afe[8].Info.Predeemp   = 3;
> +  UsbPort20Afe[8].Info.Pehalfbit  = 0;
> +
> +  UsbPort20Afe[9].Info.Petxiset   = 7;
> +  UsbPort20Afe[9].Info.Txiset     = 5;
> +  UsbPort20Afe[9].Info.Predeemp   = 3;
> +  UsbPort20Afe[9].Info.Pehalfbit  = 0;
> +
> +  //
> +  // USB Port Over Current Pin
> +  //
> +  PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinMax);
> +
> +  PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinMax);
> +  PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinMax);
> +
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPin2);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPin2);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPin2);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPin3);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPin3);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPin3);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPin3);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinSkip);
> +
> +      PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPin2);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPin2);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPin2);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinSkip);
> +      PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinSkip);
> +
> +      // USB2.0 AFE settings
> +      UsbPort20Afe[0].Info.Petxiset   = 6;
> +      UsbPort20Afe[0].Info.Txiset     = 0;
> +      UsbPort20Afe[0].Info.Predeemp   = 3;
> +      UsbPort20Afe[0].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[1].Info.Petxiset   = 6;
> +      UsbPort20Afe[1].Info.Txiset     = 0;
> +      UsbPort20Afe[1].Info.Predeemp   = 3;
> +      UsbPort20Afe[1].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[2].Info.Petxiset   = 6;
> +      UsbPort20Afe[2].Info.Txiset     = 0;
> +      UsbPort20Afe[2].Info.Predeemp   = 3;
> +      UsbPort20Afe[2].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[3].Info.Petxiset   = 6;
> +      UsbPort20Afe[3].Info.Txiset     = 0;
> +      UsbPort20Afe[3].Info.Predeemp   = 3;
> +      UsbPort20Afe[3].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[4].Info.Petxiset   = 6;
> +      UsbPort20Afe[4].Info.Txiset     = 0;
> +      UsbPort20Afe[4].Info.Predeemp   = 3;
> +      UsbPort20Afe[4].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[5].Info.Petxiset   = 6;
> +      UsbPort20Afe[5].Info.Txiset     = 0;
> +      UsbPort20Afe[5].Info.Predeemp   = 3;
> +      UsbPort20Afe[5].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[6].Info.Petxiset   = 6;
> +      UsbPort20Afe[6].Info.Txiset     = 0;
> +      UsbPort20Afe[6].Info.Predeemp   = 3;
> +      UsbPort20Afe[6].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[7].Info.Petxiset   = 6;
> +      UsbPort20Afe[7].Info.Txiset     = 0;
> +      UsbPort20Afe[7].Info.Predeemp   = 3;
> +      UsbPort20Afe[7].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[8].Info.Petxiset   = 6;
> +      UsbPort20Afe[8].Info.Txiset     = 0;
> +      UsbPort20Afe[8].Info.Predeemp   = 3;
> +      UsbPort20Afe[8].Info.Pehalfbit  = 0;
> +
> +      UsbPort20Afe[9].Info.Petxiset   = 6;
> +      UsbPort20Afe[9].Info.Txiset     = 0;
> +      UsbPort20Afe[9].Info.Predeemp   = 3;
> +      UsbPort20Afe[9].Info.Pehalfbit  = 0;
> +      break;
> +  }
> +
> +  //
> +  // Save USB2.0 AFE blobs
> +  //
> +  PcdSet32S (PcdUsb20Port0Afe,  UsbPort20Afe[ 0].Blob);
> +  PcdSet32S (PcdUsb20Port1Afe,  UsbPort20Afe[ 1].Blob);
> +  PcdSet32S (PcdUsb20Port2Afe,  UsbPort20Afe[ 2].Blob);
> +  PcdSet32S (PcdUsb20Port3Afe,  UsbPort20Afe[ 3].Blob);
> +  PcdSet32S (PcdUsb20Port4Afe,  UsbPort20Afe[ 4].Blob);
> +  PcdSet32S (PcdUsb20Port5Afe,  UsbPort20Afe[ 5].Blob);
> +  PcdSet32S (PcdUsb20Port6Afe,  UsbPort20Afe[ 6].Blob);
> +  PcdSet32S (PcdUsb20Port7Afe,  UsbPort20Afe[ 7].Blob);
> +  PcdSet32S (PcdUsb20Port8Afe,  UsbPort20Afe[ 8].Blob);
> +  PcdSet32S (PcdUsb20Port9Afe,  UsbPort20Afe[ 9].Blob);
> +  PcdSet32S (PcdUsb20Port10Afe, UsbPort20Afe[10].Blob);
> +  PcdSet32S (PcdUsb20Port11Afe, UsbPort20Afe[11].Blob);
> +  PcdSet32S (PcdUsb20Port12Afe, UsbPort20Afe[12].Blob);
> +  PcdSet32S (PcdUsb20Port13Afe, UsbPort20Afe[13].Blob);
> +  PcdSet32S (PcdUsb20Port14Afe, UsbPort20Afe[14].Blob);
> +  PcdSet32S (PcdUsb20Port15Afe, UsbPort20Afe[15].Blob);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Board GPIO Group Tier configuration init function for PEI pre-memory
> phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +GpioGroupTierInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  //
> +  // GPIO Group Tier
> +  //
> +
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdGpioGroupToGpeDw0, GPIO_CNL_LP_GROUP_GPP_G);
> +      PcdSet32S (PcdGpioGroupToGpeDw1, GPIO_CNL_LP_GROUP_SPI);
> +      PcdSet32S (PcdGpioGroupToGpeDw2, GPIO_CNL_LP_GROUP_GPP_E);
> +      break;
> +
> +    default:
> +      PcdSet32S (PcdGpioGroupToGpeDw0, 0);
> +      PcdSet32S (PcdGpioGroupToGpeDw1, 0);
> +      PcdSet32S (PcdGpioGroupToGpeDw2, 0);
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  GPIO init function for PEI pre-memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +GpioTablePreMemInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  //
> +  // GPIO Table Init.
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdBoardGpioTablePreMem, (UINTN)
> mGpioTableWhlUDdr4PreMem);
> +      PcdSet16S (PcdBoardGpioTablePreMemSize, sizeof
> (mGpioTableWhlUDdr4PreMem) / sizeof (GPIO_INIT_CONFIG));
> +      PcdSet32S (PcdBoardGpioTableWwanOnEarlyPreMem, (UINTN)
> mGpioTableWhlUDdr4WwanOnEarlyPreMem);
> +      PcdSet16S (PcdBoardGpioTableWwanOnEarlyPreMemSize, sizeof
> (mGpioTableWhlUDdr4WwanOnEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
> +      PcdSet32S (PcdBoardGpioTableWwanOffEarlyPreMem, (UINTN)
> mGpioTableWhlUDdr4WwanOffEarlyPreMem);
> +      PcdSet16S (PcdBoardGpioTableWwanOffEarlyPreMemSize, sizeof
> (mGpioTableWhlUDdr4WwanOffEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  PmConfig init function for PEI pre-memory phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +PchPmConfigInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  //
> +  // Update PmCofig policy: output voltage of VCCPRIMCORE RAIL when
> SLP_S0# is asserted based on board HW design
> +  // 1) Discete VR or Non Premium PMIC: 0.75V (PcdSlpS0Vm075VSupport)
> +  // 2) Premium PMIC: runtime control for voltage
> (PcdSlpS0VmRuntimeControl)
> +  // Only applys to board with PCH-LP. Board with Discrete PCH doesn't need
> this setting.
> +  //
> +  switch (BoardId) {
> +    // Discrete VR solution
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
> +      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
> +      PcdSetBoolS (PcdSlpS0Vm075VSupport, TRUE);
> +      break;
> +
> +    default:
> +      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
> +      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
> +      PcdSetBoolS (PcdSlpS0Vm075VSupport, FALSE);
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardSaInitPreMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardSaInitPreMemLib.c
> new file mode 100644
> index 0000000000..17f12c117d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/BoardSaInitPreMemLib.c
> @@ -0,0 +1,282 @@
> +/** @file
> + Source code for the board SA configuration Pcd init functions in Pre-Memory
> init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BoardInitLib.h"
> +#include "BoardSaConfigPreMem.h"
> +#include <PlatformBoardConfig.h>
> +#include <Library/CpuPlatformLib.h>
> +#include "SaPolicyCommon.h"
> +
> +//
> +// Display DDI settings for WHL ERB
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT8
> mWhlErbRowDisplayDdiConfig[9] = {
> +  DdiPortAEdp,     // DDI Port A Config : DdiPortADisabled = Disabled,
> DdiPortAEdp = eDP, DdiPortAMipiDsi = MIPI DSI
> +  DdiHpdEnable,    // DDI Port B HPD : DdiHpdDisable = Disable,
> DdiHpdEnable = Enable HPD
> +  DdiHpdEnable,    // DDI Port C HPD : DdiHpdDisable = Disable,
> DdiHpdEnable = Enable HPD
> +  DdiHpdDisable,   // DDI Port D HPD : DdiHpdDisable = Disable,
> DdiHpdEnable = Enable HPD
> +  DdiHpdDisable,   // DDI Port F HPD : DdiHpdDisable = Disable,
> DdiHpdEnable = Enable HPD
> +  DdiDdcEnable,    // DDI Port B DDC : DdiDisable = Disable, DdiDdcEnable =
> Enable DDC
> +  DdiDdcEnable,    // DDI Port C DDC : DdiDisable = Disable, DdiDdcEnable =
> Enable DDC
> +  DdiDdcEnable,    // DDI Port D DDC : DdiDisable = Disable, DdiDdcEnable =
> Enable DDC
> +  DdiDisable       // DDI Port F DDC : DdiDisable = Disable, DdiDdcEnable =
> Enable DDC
> +};
> +
> +/**
> +  MRC configuration init function for PEI pre-memory phase.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +SaMiscConfigInit (
> +  IN UINT16         BoardId
> +  )
> +{
> +  //
> +  // UserBd
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      //
> +      // Assign UserBd to 5 which is assigned to MrcInputs->BoardType btUser4
> for ULT platforms.
> +      // This is required to skip Memory voltage programming based on GPIO's
> in MRC
> +      //
> +      PcdSet8S (PcdSaMiscUserBd, 5); // MrcBoardType btUser4 for ULT
> platform
> +      break;
> +
> +    default:
> +      // MiscPeiPreMemConfig.UserBd = 0 by default.
> +      break;
> +  }
> +
> +  PcdSet16S (PcdSaDdrFreqLimit, 0);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Board Memory Init related configuration init function for PEI pre-memory
> phase.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +MrcConfigInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  CPU_FAMILY    CpuFamilyId;
> +  CPU_STEPPING  CpuStepping;
> +
> +  CpuFamilyId = GetCpuFamily();
> +  CpuStepping = GetCpuStepping();
> +
> +  if (CpuFamilyId == EnumCpuCflDtHalo) {
> +    PcdSetBoolS (PcdDualDimmPerChannelBoardType, TRUE);
> +  } else {
> +    PcdSetBoolS (PcdDualDimmPerChannelBoardType, FALSE);
> +  }
> +
> +  //
> +  // Example policy for DIMM slots implementation boards:
> +  // 1. Assign Smbus address of DIMMs and SpdData will be updated later
> +  //    by reading from DIMM SPD.
> +  // 2. No need to apply hardcoded SpdData buffers here for such board.
> +  //
> +  //  Whiskey Lake U RVP has removable DIMM slots.
> +  //  So assign all Smbus address of DIMMs and leave PcdMrcSpdData set to
> 0.
> +  //   Example:
> +  //   PcdMrcSpdData = 0
> +  //   PcdMrcSpdDataSize = 0
> +  //   PcdMrcSpdAddressTable0 = 0xA0
> +  //   PcdMrcSpdAddressTable1 = 0xA2
> +  //   PcdMrcSpdAddressTable2 = 0xA4
> +  //   PcdMrcSpdAddressTable3 = 0xA6
> +  //
> +  //  If a board has soldered down memory. It should use the following
> settings.
> +  //   Example:
> +  //   PcdMrcSpdAddressTable0 = 0
> +  //   PcdMrcSpdAddressTable1 = 0
> +  //   PcdMrcSpdAddressTable2 = 0
> +  //   PcdMrcSpdAddressTable3 = 0
> +  //   PcdMrcSpdData = static data buffer
> +  //   PcdMrcSpdDataSize = sizeof (static data buffer)
> +  //
> +
> +  //
> +  // SPD Address Table
> +  //
> +  PcdSet32S (PcdMrcSpdData, 0);
> +  PcdSet16S (PcdMrcSpdDataSize, 0);
> +  PcdSet8S (PcdMrcSpdAddressTable0, 0xA0);
> +  PcdSet8S (PcdMrcSpdAddressTable1, 0xA2);
> +  PcdSet8S (PcdMrcSpdAddressTable2, 0xA4);
> +  PcdSet8S (PcdMrcSpdAddressTable3, 0xA6);
> +
> +  //
> +  // DRAM SPD Data & related configuration
> +  //
> +  // Setting the PCD's to default value (WHL RVP3). It will be overriden to
> board specific settings below.
> +  PcdSet32S (PcdMrcDqByteMap, (UINTN) mDqByteMapWhlUDdr4Rvp);
> +  PcdSet16S (PcdMrcDqByteMapSize, sizeof (mDqByteMapWhlUDdr4Rvp));
> +  PcdSet32S (PcdMrcDqsMapCpu2Dram, (UINTN)
> mDqsMapCpu2DramWhlUDdr4Rvp);
> +  PcdSet16S (PcdMrcDqsMapCpu2DramSize, sizeof
> (mDqsMapCpu2DramWhlUDdr4Rvp));
> +
> +  switch (BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdMrcRcompResistor, (UINTN)
> RcompResistorCflUDdr4Interposer);
> +      PcdSet32S (PcdMrcRcompTarget, (UINTN)
> RcompTargetWhlUDdr4Interposer);
> +      PcdSetBoolS (PcdMrcDqPinsInterleavedControl, TRUE);
> +      PcdSetBoolS (PcdMrcDqPinsInterleaved, TRUE);
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // CA Vref routing: board-dependent
> +  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
> +  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
> +  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdMrcCaVrefConfig, 2); // DDR4 boards
> +      break;
> +
> +    default:
> +      PcdSet8S (PcdMrcCaVrefConfig, 0); // All DDR3L/LPDDR3/LPDDR4 boards
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Board SA related GPIO configuration init function for PEI pre-memory phase.
> +
> +  @param[in]  BoardId   An unsigned integer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +SaGpioConfigInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  //
> +  // Update board's GPIO for PEG slot reset
> +  //
> +  PcdSetBoolS (PcdPegGpioResetControl, TRUE);
> +  PcdSetBoolS (PcdPegGpioResetSupoort, FALSE);
> +  PcdSet32S (PcdPeg0ResetGpioPad, 0);
> +  PcdSetBoolS (PcdPeg0ResetGpioActive, FALSE);
> +  PcdSet32S (PcdPeg3ResetGpioPad, 0);
> +  PcdSetBoolS (PcdPeg3ResetGpioActive, FALSE);
> +
> +  //
> +  // PCIE RTD3 GPIO
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S(PcdRootPortIndex, 4);
> +      PcdSet8S (PcdPcie0GpioSupport, PchGpio);
> +      PcdSet32S (PcdPcie0WakeGpioNo, 0);
> +      PcdSet8S (PcdPcie0HoldRstExpanderNo, 0);
> +      PcdSet32S (PcdPcie0HoldRstGpioNo, GPIO_CNL_LP_GPP_C15);
> +      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
> +      PcdSet8S (PcdPcie0PwrEnableExpanderNo, 0);
> +      PcdSet32S (PcdPcie0PwrEnableGpioNo, GPIO_CNL_LP_GPP_C14);
> +      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
> +
> +      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
> +      PcdSet32S (PcdPcie1WakeGpioNo, 0);
> +      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
> +      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
> +      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
> +      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
> +      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
> +      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
> +
> +      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
> +      PcdSet32S (PcdPcie2WakeGpioNo, 0);
> +      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
> +      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
> +      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
> +      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
> +      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
> +      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
> +      break;
> +
> +    default:
> +      PcdSet8S(PcdRootPortIndex, 0xFF);
> +      PcdSet8S  (PcdPcie0GpioSupport, NotSupported);
> +      PcdSet32S (PcdPcie0WakeGpioNo, 0);
> +      PcdSet8S  (PcdPcie0HoldRstExpanderNo, 0);
> +      PcdSet32S (PcdPcie0HoldRstGpioNo, 0);
> +      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
> +      PcdSet8S  (PcdPcie0PwrEnableExpanderNo, 0);
> +      PcdSet32S (PcdPcie0PwrEnableGpioNo, 0);
> +      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
> +
> +      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
> +      PcdSet32S (PcdPcie1WakeGpioNo, 0);
> +      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
> +      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
> +      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
> +      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
> +      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
> +      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
> +
> +      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
> +      PcdSet32S (PcdPcie2WakeGpioNo, 0);
> +      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
> +      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
> +      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
> +      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
> +      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
> +      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  SA Display DDI configuration init function for PEI pre-memory phase.
> +
> +  @param[in]  BoardId       An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +SaDisplayConfigInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +  //
> +  // Update Display DDI Config
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdSaDisplayConfigTable, (UINTN)
> mWhlErbRowDisplayDdiConfig);
> +      PcdSet16S (PcdSaDisplayConfigTableSize, sizeof
> (mWhlErbRowDisplayDdiConfig));
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPostMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPostMemLib.c
> new file mode 100644
> index 0000000000..c52d4eceed
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPostMemLib.c
> @@ -0,0 +1,40 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardInitBeforeSiliconInit (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +BoardInitBeforeSiliconInit (
> +  VOID
> +  )
> +{
> +  WhiskeylakeURvpBoardInitBeforeSiliconInit ();
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardInitAfterSiliconInit (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPreMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPreMemLib.c
> new file mode 100644
> index 0000000000..1283a4c80a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiBoardInitPreMemLib.c
> @@ -0,0 +1,106 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDetect (
> +  VOID
> +  );
> +
> +EFI_BOOT_MODE
> +EFIAPI
> +WhiskeylakeURvpBoardBootModeDetect (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDebugInit (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardInitBeforeMemoryInit (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +BoardDetect (
> +  VOID
> +  )
> +{
> +  WhiskeylakeURvpBoardDetect ();
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardDebugInit (
> +  VOID
> +  )
> +{
> +  WhiskeylakeURvpBoardDebugInit ();
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_BOOT_MODE
> +EFIAPI
> +BoardBootModeDetect (
> +  VOID
> +  )
> +{
> +  return WhiskeylakeURvpBoardBootModeDetect ();
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardInitBeforeMemoryInit (
> +  VOID
> +  )
> +{
> +  WhiskeylakeURvpBoardInitBeforeMemoryInit ();
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardInitAfterMemoryInit (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardInitBeforeTempRamExit (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BoardInitAfterTempRamExit (
> +  VOID
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPostMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPostMemLib.c
> new file mode 100644
> index 0000000000..965110a5a5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPostMemLib.c
> @@ -0,0 +1,41 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <Library/MultiBoardInitSupportLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <WhiskeylakeURvpId.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardInitBeforeSiliconInit (
> +  VOID
> +  );
> +
> +BOARD_POST_MEM_INIT_FUNC  mWhiskeylakeURvpBoardInitFunc = {
> +  WhiskeylakeURvpBoardInitBeforeSiliconInit,
> +  NULL, // BoardInitAfterSiliconInit
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +PeiWhiskeylakeURvpMultiBoardInitLibConstructor (
> +  VOID
> +  )
> +{
> +  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
> +    return RegisterBoardPostMemInit (&mWhiskeylakeURvpBoardInitFunc);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPreMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPreMemLib.c
> new file mode 100644
> index 0000000000..a2a6efe506
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiMultiBoardInitPreMemLib.c
> @@ -0,0 +1,83 @@
> +/** @file
> +  Platform Hook Library instances
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <Library/MultiBoardInitSupportLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <WhiskeylakeURvpId.h>
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDetect (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpMultiBoardDetect (
> +  VOID
> +  );
> +
> +EFI_BOOT_MODE
> +EFIAPI
> +WhiskeylakeURvpBoardBootModeDetect (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDebugInit (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardInitBeforeMemoryInit (
> +  VOID
> +  );
> +
> +BOARD_DETECT_FUNC  mWhiskeylakeURvpBoardDetectFunc = {
> +  WhiskeylakeURvpMultiBoardDetect
> +};
> +
> +BOARD_PRE_MEM_INIT_FUNC  mWhiskeylakeURvpBoardPreMemInitFunc =
> {
> +  WhiskeylakeURvpBoardDebugInit,
> +  WhiskeylakeURvpBoardBootModeDetect,
> +  WhiskeylakeURvpBoardInitBeforeMemoryInit,
> +  NULL, // BoardInitAfterMemoryInit
> +  NULL, // BoardInitBeforeTempRamExit
> +  NULL, // BoardInitAfterTempRamExit
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpMultiBoardDetect (
> +  VOID
> +  )
> +{
> +  WhiskeylakeURvpBoardDetect ();
> +  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
> +    RegisterBoardPreMemInit (&mWhiskeylakeURvpBoardPreMemInitFunc);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor (
> +  VOID
> +  )
> +{
> +  return RegisterBoardDetect (&mWhiskeylakeURvpBoardDetectFunc);
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpDetect.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpDetect.c
> new file mode 100644
> index 0000000000..0adbed7f53
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpDetect.c
> @@ -0,0 +1,63 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <PchAccess.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Library/GpioLib.h>
> +#include <GpioPinsSklLp.h>
> +#include <GpioPinsSklH.h>
> +#include <Library/GpioExpanderLib.h>
> +#include <SioRegs.h>
> +#include <Library/PchPcrLib.h>
> +
> +#include "PeiWhiskeylakeURvpInitLib.h"
> +
> +#include <ConfigBlock.h>
> +#include <ConfigBlock/MemoryConfig.h>
> +
> +BOOLEAN
> +WhiskeylakeURvp(
> +  VOID
> +  )
> +{
> +  return TRUE;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDetect (
> +  VOID
> +  )
> +{
> +  if (LibPcdGetSku () != 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "WhiskeylakeURvpDetectionCallback\n"));
> +
> +  if (WhiskeylakeURvp()) {
> +    LibPcdSetSku (BoardIdWhiskeyLakeRvp);
> +
> +    DEBUG ((DEBUG_INFO, "SKU_ID: 0x%x\n", LibPcdGetSku()));
> +    ASSERT (LibPcdGetSku() == BoardIdWhiskeyLakeRvp);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
> new file mode 100644
> index 0000000000..80b0a97612
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
> @@ -0,0 +1,432 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/HdaVerbTableLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <PchAccess.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Library/GpioLib.h>
> +#include <GpioPinsSklLp.h>
> +#include <GpioPinsSklH.h>
> +#include <Library/GpioExpanderLib.h>
> +#include <SioRegs.h>
> +#include <Library/PchPcrLib.h>
> +#include <IoExpander.h>
> +#include "PeiWhiskeylakeURvpInitLib.h"
> +#include "GpioTableDefault.h"
> +#include "GpioTableWhlUDdr4.h"
> +#include <AttemptUsbFirst.h>
> +#include <PeiPlatformHookLib.h>
> +#include <Library/PeiPolicyInitLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <FirwmareConfigurations.h>
> +
> +EFI_STATUS
> +BoardFunctionInit(
> +  IN UINT16 BoardId
> +);
> +
> +/**
> +GPIO init function for PEI post memory phase.
> +
> +@param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +@retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardGpioInit(
> +  IN UINT16 BoardId
> +)
> +{
> +  //
> +  // GPIO Table Init.
> +  //
> +  switch (BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableWhlUDdr4_0);
> +      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableWhlUDdr4_0) /
> sizeof(GPIO_INIT_CONFIG));
> +      PcdSet32S(PcdBoardGpioTable2, (UINTN)mGpioTableWhlUDdr4);
> +      PcdSet16S(PcdBoardGpioTable2Size, sizeof(mGpioTableWhlUDdr4) /
> sizeof(GPIO_INIT_CONFIG));
> +      break;
> +
> +    default:
> +      DEBUG((DEBUG_INFO, "For Unknown Board ID..Use Default GPIO
> Table...\n"));
> +      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableDefault);
> +      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableDefault) /
> sizeof(GPIO_INIT_CONFIG));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +Touch panel GPIO init function for PEI post memory phase.
> +
> +@param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +@retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +TouchPanelGpioInit(
> +  IN UINT16 BoardId
> +)
> +{
> +  switch (BoardId) {
> +    default:
> +      PcdSet32S(PcdBoardGpioTableTouchPanel, 0);
> +    break;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +Misc. init function for PEI post memory phase.
> +
> +@param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +@retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardMiscInit(
> +  IN UINT16 BoardId
> +)
> +{
> +  PcdSetBoolS(PcdDebugUsbUartEnable, FALSE);
> +
> +  switch (BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +
> +      PcdSetBoolS(PcdMipiCamGpioEnable, TRUE);
> +      break;
> +
> +    default:
> +      PcdSetBoolS(PcdMipiCamGpioEnable, FALSE);
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +Security GPIO init function for PEI post memory phase.
> +
> +@param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +@retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardSecurityInit (
> +  IN UINT16 BoardId
> +)
> +{
> +  switch (BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +
> +      // TPM interrupt connects to GPIO_CNL_H_GPP_A_7
> +      PcdSet32S (PcdTpm2CurrentIrqNum, 0x1F);
> +      break;
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +WhiskeyLake board configuration init function for PEI post memory phase.
> +
> +@param[in]  Content  pointer to the buffer contain init information for
> board init.
> +
> +@retval EFI_SUCCESS             The function completed successfully.
> +@retval EFI_INVALID_PARAMETER   The parameter is NULL.
> +**/
> +EFI_STATUS
> +BoardConfigInit(
> +  VOID
> +)
> +{
> +  EFI_STATUS  Status;
> +  UINT16      BoardId;
> +
> +  BoardId = BoardIdWhiskeyLakeRvp;
> +
> +  Status = BoardGpioInit(BoardId);
> +  Status = TouchPanelGpioInit(BoardId);
> +  Status = HdaVerbTableInit(BoardId);
> +  Status = BoardMiscInit(BoardId);
> +  Status = BoardFunctionInit(BoardId);
> +  Status = BoardSecurityInit(BoardId);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//@todo Review this functionality and if it is required for WHL SDS
> +/**
> +Create the HOB for hotkey status for 'Attempt USB First' feature
> +
> +@retval  EFI_SUCCESS  HOB Creating successful.
> +@retval  Others       HOB Creating failed.
> +**/
> +EFI_STATUS
> +CreateAttemptUsbFirstHotkeyInfoHob(
> +  VOID
> +)
> +{
> +  EFI_STATUS                     Status;
> +  ATTEMPT_USB_FIRST_HOTKEY_INFO  AttemptUsbFirstHotkeyInfo;
> +
> +  Status = EFI_SUCCESS;
> +
> +  ZeroMem(
> +    &AttemptUsbFirstHotkeyInfo,
> +    sizeof(AttemptUsbFirstHotkeyInfo)
> +  );
> +
> +  AttemptUsbFirstHotkeyInfo.RevisonId = 0;
> +  AttemptUsbFirstHotkeyInfo.HotkeyTriggered = FALSE;
> +
> +  ///
> +  /// Build HOB for Attempt USB First feature
> +  ///
> +  BuildGuidDataHob(
> +    &gAttemptUsbFirstHotkeyInfoHobGuid,
> +    &(AttemptUsbFirstHotkeyInfo),
> +    sizeof(ATTEMPT_USB_FIRST_HOTKEY_INFO)
> +  );
> +
> +  return Status;
> +}
> +
> +/**
> +Search and identify the physical address of a
> +file module inside the FW_BINARIES_FV_SIGNED FV
> +
> +@retval  EFI_SUCCESS  If address has been found
> +@retval  Others       If address has not been found
> +**/
> +EFI_STATUS
> +FindModuleInFlash2(
> +  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
> +  IN EFI_GUID                   *GuidPtr,
> +  IN OUT UINT32                 *ModulePtr,
> +  IN OUT UINT32                 *ModuleSize
> +)
> +{
> +  EFI_FFS_FILE_HEADER        *FfsHeader;
> +  EFI_FV_FILE_INFO           FileInfo;
> +  EFI_PEI_FILE_HANDLE        FileHandle;
> +  EFI_COMMON_SECTION_HEADER  *SectionHeader;
> +  VOID                       *FileBuffer;
> +  EFI_STATUS                 Status;
> +
> +  FfsHeader = NULL;
> +  FileHandle = NULL;
> +  SectionHeader = NULL;
> +  FileBuffer = NULL;
> +
> +  while (TRUE) {
> +    //
> +    // Locate FV_IMAGE file type in the FW_BINARIES_FV_SIGNED firmware
> volume
> +    //
> +    Status =
> PeiServicesFfsFindNextFile(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
> FvHeader, &FileHandle);
> +    if (EFI_ERROR(Status)) {
> +      // unable to find FV_IMAGE file in this FV
> +      break;
> +    }
> +
> +    FfsHeader = (EFI_FFS_FILE_HEADER*)FileHandle;
> +    DEBUG((DEBUG_INFO, "FfsHeader 0x%X:\n", FfsHeader));
> +    DEBUG((DEBUG_INFO, " Name = 0x%g\n", &FfsHeader->Name));
> +    DEBUG((DEBUG_INFO, " Type = 0x%X\n", FfsHeader->Type));
> +    if (IS_FFS_FILE2(FfsHeader)) {
> +      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE2_SIZE(FfsHeader)));
> +    }
> +    else {
> +      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE_SIZE(FfsHeader)));
> +    }
> +
> +    //
> +    // Locate FW_BINARIES_FV FV_IMAGE Section
> +    //
> +    Status =
> PeiServicesFfsFindSectionData(EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> FileHandle, &FileBuffer);
> +    if (EFI_ERROR(Status)) {
> +      // continue to search for the next FV_IMAGE file
> +      DEBUG((DEBUG_INFO, "FW_BINARIES_FV section not found. Status =
> %r\n", Status));
> +      continue;
> +    }
> +
> +    SectionHeader = (EFI_COMMON_SECTION_HEADER *)FileBuffer;
> +    DEBUG((DEBUG_INFO, "GUIDED SectionHeader 0x%X:\n",
> +    (UINT32)(UINT8 *)SectionHeader));
> +    if (IS_SECTION2(SectionHeader)) {
> +      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
> +        &((EFI_GUID_DEFINED_SECTION2
> *)SectionHeader)->SectionDefinitionGuid));
> +      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
> +        ((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->DataOffset));
> +    }
> +    else {
> +      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
> +        &((EFI_GUID_DEFINED_SECTION
> *)SectionHeader)->SectionDefinitionGuid));
> +      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
> +        ((EFI_GUID_DEFINED_SECTION *)SectionHeader)->DataOffset));
> +    }
> +    DEBUG((DEBUG_INFO, " Type      = 0x%X\n", SectionHeader->Type));
> +
> +    //
> +    // Locate Firmware File System file within Firmware Volume
> +    //
> +    Status = PeiServicesFfsFindFileByName(GuidPtr, FileBuffer, (VOID
> **)&FfsHeader);
> +    if (EFI_ERROR(Status)) {
> +      // continue to search for the next FV_IMAGE file
> +      DEBUG((DEBUG_INFO, "Module not found. Status = %r\n", Status));
> +      continue;
> +    }
> +
> +    *ModulePtr = (UINT32)((UINT8 *)FfsHeader +
> sizeof(EFI_FFS_FILE_HEADER));
> +
> +    //
> +    // Get File Information
> +    //
> +    Status = PeiServicesFfsGetFileInfo(FfsHeader, &FileInfo);
> +    if (!EFI_ERROR(Status)) {
> +      *ModuleSize = (UINT32)FileInfo.BufferSize;
> +      DEBUG((DEBUG_INFO, "Module {0x%g} found at = 0x%X, Size = 0x%X\n",
> +        &FfsHeader->Name, *ModulePtr, *ModuleSize));
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +Get the ChipsetInit Binary pointer.
> +
> +@retval EFI_SUCCESS               - ChipsetInit Binary found.
> +@retval EFI_NOT_FOUND             - ChipsetInit Binary not found.
> +**/
> +EFI_STATUS
> +UpdateChipsetInitPtr(
> +  VOID
> +)
> +{
> +  EFI_STATUS                    Status;
> +  PCH_STEPPING                  PchStep;
> +  EFI_FIRMWARE_VOLUME_HEADER    *FvHeader;
> +  EFI_GUID                      *ChipsetInitBinaryGuidPtr;
> +  SI_POLICY_PPI                 *SiPolicyPpi;
> +  PCH_HSIO_CONFIG               *HsioConfig;
> +  UINT32                        ModuleAddr;
> +  UINT32                        ModuleSize;
> +
> +  ModuleAddr = 0;
> +  ModuleSize = 0;
> +  PchStep = PchStepping();
> +
> +  Status = PeiServicesLocatePpi(
> +    &gSiPolicyPpiGuid,
> +    0,
> +    NULL,
> +    (VOID **)&SiPolicyPpi
> +  );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gHsioConfigGuid, (VOID
> *)&HsioConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  ChipsetInitBinaryGuidPtr = NULL;
> +  if (IsPchLp()) {
> +    switch (PchStep) {
> +      case PCH_D0:
> +      case PCH_D1:
> +        ChipsetInitBinaryGuidPtr = &gCnlPchLpChipsetInitTableDxGuid;
> +        DEBUG((DEBUG_INFO, "Using CnlPchLpChipsetInitTable_Dx table \n"));
> +        break;
> +      default:
> +        return EFI_NOT_FOUND;
> +    }
> +  }
> +  else {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Locate Firmware Volume header
> +  //
> +  //	FvHeader = (EFI_FIRMWARE_VOLUME_HEADER
> *)(UINTN)GetFvBinaryBase();
> +  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)
> FixedPcdGet32(PcdFlashFvPostMemoryBase);
> +  Status = FindModuleInFlash2(FvHeader, ChipsetInitBinaryGuidPtr,
> &ModuleAddr, &ModuleSize);
> +  //
> +  // Get ChipsetInit Binary Pointer
> +  //
> +  HsioConfig->ChipsetInitBinPtr = ModuleAddr;
> +
> +  //
> +  // Get File Size
> +  //
> +  HsioConfig->ChipsetInitBinLen = ModuleSize;
> +
> +  DEBUG((DEBUG_INFO, "ChipsetInit Binary Location: %x\n",
> HsioConfig->ChipsetInitBinPtr));
> +  DEBUG((DEBUG_INFO, "ChipsetInit Binary Size: %x\n",
> HsioConfig->ChipsetInitBinLen));
> +
> +  return Status;
> +}
> +
> +/**
> +  Configure GPIO and SIO
> +
> +  @retval  EFI_SUCCESS   Operation success.
> +**/
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardInitBeforeSiliconInit (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  UINT8                            FwConfig;
> +
> +  BoardConfigInit();
> +  //
> +  // Configure GPIO and SIO
> +  //
> +  Status = BoardInit();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  FwConfig = FwConfigProduction;
> +  PeiPolicyInit(FwConfig);
> +
> +  //
> +  // Create USB Boot First hotkey information HOB
> +  //
> +  CreateAttemptUsbFirstHotkeyInfoHob();
> +
> +  //
> +  // Initializing Platform Specific Programming
> +  //
> +  Status = PlatformSpecificInit();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Update ChipsetInitPtr
> +  //
> +  Status = UpdateChipsetInitPtr();
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
> new file mode 100644
> index 0000000000..519a5be216
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
> @@ -0,0 +1,636 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/BaseMemoryLib.h>
> +
> +#include <Library/PeiSaPolicyLib.h>
> +#include <Library/BoardInitLib.h>
> +#include <PchAccess.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Library/GpioLib.h>
> +#include <GpioPinsSklLp.h>
> +#include <GpioPinsSklH.h>
> +#include <Library/GpioExpanderLib.h>
> +#include <SioRegs.h>
> +#include <Library/PchPcrLib.h>
> +
> +#include "PeiWhiskeylakeURvpInitLib.h"
> +#include <ConfigBlock.h>
> +#include <ConfigBlock/MemoryConfig.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Register/PchRegsPcr.h>
> +#include <Library/PchResetLib.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Library/StallPpiLib.h>
> +#include <Library/PeiPolicyInitLib.h>
> +#include <Ppi/Reset.h>
> +#include <PlatformBoardConfig.h>
> +#include <GpioPinsCnlLp.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <PeiPlatformHookLib.h>
> +#include <FirwmareConfigurations.h>
> +#include <Guid/TcoWdtHob.h>
> +#include <Library/OcWdtLib.h>
> +
> +///
> +/// Reset Generator I/O Port
> +///
> +#define RESET_GENERATOR_PORT           0xCF9
> +
> +typedef struct {
> +  EFI_PHYSICAL_ADDRESS    BaseAddress;
> +  UINT64                  Length;
> +} MEMORY_MAP;
> +
> +//
> +// Reference RCOMP resistors on motherboard - for WHL RVP1
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT16
> RcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
> +
> +//
> +// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for
> WHL RVP1
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED const UINT16
> RcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_MAP MmioMap[] = {
> +  { FixedPcdGet64(PcdApicLocalAddress),
> FixedPcdGet32(PcdApicLocalMmioSize) },
> +  { FixedPcdGet64(PcdMchBaseAddress), FixedPcdGet32(PcdMchMmioSize) },
> +  { FixedPcdGet64(PcdDmiBaseAddress), FixedPcdGet32(PcdDmiMmioSize) },
> +  { FixedPcdGet64(PcdEpBaseAddress), FixedPcdGet32(PcdEpMmioSize) },
> +  { FixedPcdGet64(PcdGdxcBaseAddress),
> FixedPcdGet32(PcdGdxcMmioSize) }
> +};
> +
> +EFI_STATUS
> +MrcConfigInit(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +SaGpioConfigInit(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +  SaMiscConfigInit(
> +IN UINT16         BoardId
> +);
> +
> +EFI_STATUS
> +  RootPortClkInfoInit(
> +IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +  UsbConfigInit(
> +IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +GpioGroupTierInit(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +GpioTablePreMemInit(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +PchPmConfigInit(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +SaDisplayConfigInit(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +BoardFunctionInitPreMem(
> +  IN UINT16 BoardId
> +);
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformInitPreMemCallBack(
> +  IN CONST EFI_PEI_SERVICES      **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
> +  IN VOID                        *Ppi
> +);
> +
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotify(
> +  IN CONST EFI_PEI_SERVICES      **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
> +  IN VOID                        *Ppi
> +);
> +
> +EFI_STATUS
> +EFIAPI
> +PchReset(
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +);
> +
> +static EFI_PEI_RESET_PPI mResetPpi = {
> +  PchReset
> +};
> +
> +static EFI_PEI_PPI_DESCRIPTOR mPreMemPpiList[] = {
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiPeiResetPpiGuid,
> +    &mResetPpi
> +  }
> +};
> +
> +static EFI_PEI_NOTIFY_DESCRIPTOR mPreMemNotifyList = {
> +  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiReadOnlyVariable2PpiGuid,
> +  (EFI_PEIM_NOTIFY_ENTRY_POINT)PlatformInitPreMemCallBack
> +};
> +
> +static EFI_PEI_NOTIFY_DESCRIPTOR mMemDiscoveredNotifyList = {
> +  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +  &gEfiPeiMemoryDiscoveredPpiGuid,
> +  (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotify
> +};
> +
> +/**
> +Board misc init function for PEI pre-memory phase.
> +
> +@param[in]  BoardId   An unsigned integer represent the board id.
> +
> +@retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardMiscInitPreMem(
> +  IN UINT16 BoardId
> +)
> +{
> +  PCD64_BLOB PcdData;
> +
> +  //
> +  // RecoveryMode GPIO
> +  //
> +  PcdData.Blob = 0;
> +  PcdData.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
> +
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdData.BoardGpioConfig.Type = BoardGpioTypePch;
> +      PcdData.BoardGpioConfig.u.Pin = GPIO_CNL_LP_GPP_F10;
> +    break;
> +
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // Configure WWAN Full Card Power Off and reset pins
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      //
> +      // According to board default settings, GPP_D16 is used to
> enable/disable modem
> +      // power. An alternative way to contol modem power is to toggle
> FCP_OFF via GPP_D13
> +      // but board rework is required.
> +      //
> +      PcdSet32S(PcdWwanFullCardPowerOffGpio, GPIO_CNL_LP_GPP_D16);
> +      PcdSet32S(PcdWwanBbrstGpio, GPIO_CNL_LP_GPP_F1);
> +      PcdSet32S(PcdWwanPerstGpio, GPIO_CNL_LP_GPP_E15);
> +      PcdSet8S(PcdWwanPerstGpioPolarity, 1);
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  PcdSet64S(PcdRecoveryModeGpio, PcdData.Blob);
> +
> +  //
> +  // Pc8374SioKbc Present
> +  //
> +  PcdSetBoolS(PcdPc8374SioKbcPresent, FALSE);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//@todo it should be moved to Si Pkg.
> +/**
> +Early Platform PCH initialization
> +**/
> +VOID
> +EarlyPlatformPchInit(
> +  VOID
> +)
> +{
> +  UINT8        Data8;
> +  UINT8        TcoRebootHappened;
> +  TCO_WDT_HOB  *TcoWdtHobPtr;
> +  EFI_STATUS   Status;
> +
> +  ///
> +  /// Read the Second TO status bit
> +  ///
> +  Data8 = IoRead8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS);
> +  if ((Data8 & B_TCO_IO_TCO2_STS_SECOND_TO) ==
> B_TCO_IO_TCO2_STS_SECOND_TO) {
> +    TcoRebootHappened = 1;
> +    DEBUG((DEBUG_INFO, "PlatformInitPreMem - TCO Second TO status bit is
> set. This might be a TCO reboot\n"));
> +  }
> +  else {
> +    TcoRebootHappened = 0;
> +  }
> +
> +  ///
> +  /// Create HOB
> +  ///
> +  Status = PeiServicesCreateHob(EFI_HOB_TYPE_GUID_EXTENSION,
> sizeof(TCO_WDT_HOB), (VOID **)&TcoWdtHobPtr);
> +  if (!EFI_ERROR(Status)) {
> +    TcoWdtHobPtr->Header.Name = gTcoWdtHobGuid;
> +    TcoWdtHobPtr->TcoRebootHappened = TcoRebootHappened;
> +  }
> +
> +  ///
> +  /// Clear the Second TO status bit
> +  ///
> +  IoWrite8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS,
> B_TCO_IO_TCO2_STS_SECOND_TO);
> +}
> +
> +/**
> +Board init function for PEI pre-memory phase.
> +
> +@param  Content  pointer to the buffer contain init information for board
> init.
> +
> +@retval EFI_SUCCESS             The function completed successfully.
> +@retval EFI_INVALID_PARAMETER   The parameter is NULL.
> +**/
> +EFI_STATUS
> +BoardConfigInitPreMem(
> +  VOID
> +)
> +{
> +  EFI_STATUS Status;
> +  UINT16 BoardId;
> +
> +  BoardId = BoardIdWhiskeyLakeRvp;
> +
> +  Status = MrcConfigInit(BoardId);
> +  Status = SaGpioConfigInit(BoardId);
> +  Status = SaMiscConfigInit(BoardId);
> +  Status = RootPortClkInfoInit(BoardId);
> +  Status = UsbConfigInit(BoardId);
> +  Status = GpioGroupTierInit(BoardId);
> +  Status = GpioTablePreMemInit(BoardId);
> +  Status = PchPmConfigInit(BoardId);
> +  Status = BoardMiscInitPreMem(BoardId);
> +  Status = SaDisplayConfigInit(BoardId);
> +  Status = BoardFunctionInitPreMem(BoardId);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +This function handles PlatformInit task after PeiReadOnlyVariable2 PPI
> produced
> +
> +@param[in]  PeiServices   Pointer to PEI Services Table.
> +@param[in]  NotifyDesc    Pointer to the descriptor for the Notification
> event that
> +                          caused this function to execute.
> +@param[in]  Ppi           Pointer to the PPI data associated with this function.
> +
> +@retval     EFI_SUCCESS  The function completes successfully
> +@retval     others
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformInitPreMemCallBack(
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +)
> +{
> +  EFI_STATUS                        Status;
> +  UINT16                            ABase;
> +  UINT8                             FwConfig;
> +  UINT8                             SynchDelay;
> +
> +  //
> +  // Init Board Config Pcd.
> +  //
> +  BoardConfigInitPreMem();
> +
> +  DEBUG((DEBUG_ERROR, "Fail to get System Configuration and set the
> configuration to production mode!\n"));
> +  FwConfig = FwConfigProduction;
> +  SynchDelay = 0;
> +  PcdSetBoolS(PcdPcieWwanEnable, FALSE);
> +  PcdSetBoolS(PcdWwanResetWorkaround, FALSE);
> +
> +  //
> +  // Early Board Configuration before memory is ready.
> +  //
> +  Status = BoardInitEarlyPreMem();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  ///
> +  /// If there was unexpected reset but no WDT expiration and no resume
> from S3/S4,
> +  /// clear unexpected reset status and enforce expiration. This is to inform
> Firmware
> +  /// which has no access to unexpected reset status bit, that something went
> wrong.
> +  ///
> +  OcWdtResetCheck();
> +
> +  Status = OcWdtInit();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  //
> +  // Initialize Intel PEI Platform Policy
> +  //
> +  PeiPolicyInitPreMem(FwConfig);
> +
> +  ///
> +  /// Configure GPIO and SIO
> +  ///
> +  Status = BoardInitPreMem();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  ABase = PmcGetAcpiBase();
> +
> +  ///
> +  /// Clear all pending SMI. On S3 clear power button enable so it will not
> generate an SMI.
> +  ///
> +  IoWrite16(ABase + R_ACPI_IO_PM1_EN, 0);
> +  IoWrite32(ABase + R_ACPI_IO_GPE0_EN_127_96, 0);
> +
> +  ///
> +  /// Install Pre Memory PPIs
> +  ///
> +  Status = PeiServicesInstallPpi(&mPreMemPpiList[0]);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return Status;
> +}
> +
> +/**
> +Provide hard reset PPI service.
> +To generate full hard reset, write 0x0E to PCH RESET_GENERATOR_PORT
> (0xCF9).
> +
> +@param[in]  PeiServices       General purpose services available to every
> PEIM.
> +
> +@retval     Not return        System reset occured.
> +@retval     EFI_DEVICE_ERROR  Device error, could not reset the system.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchReset(
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +)
> +{
> +  DEBUG((DEBUG_INFO, "Perform Cold Reset\n"));
> +  IoWrite8(RESET_GENERATOR_PORT, 0x0E);
> +
> +  CpuDeadLoop();
> +
> +  ///
> +  /// System reset occured, should never reach at this line.
> +  ///
> +  ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
> +
> +  return EFI_DEVICE_ERROR;
> +}
> +
> +/**
> +Install Firmware Volume Hob's once there is main memory
> +
> +@param[in]  PeiServices       General purpose services available to every
> PEIM.
> +@param[in]  NotifyDescriptor  Notify that this module published.
> +@param[in]  Ppi               PPI that was installed.
> +
> +@retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MemoryDiscoveredPpiNotify(
> +  IN CONST EFI_PEI_SERVICES     **PeiServices,
> +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
> +  IN VOID                       *Ppi
> +)
> +{
> +  EFI_STATUS                    Status;
> +  EFI_BOOT_MODE                 BootMode;
> +  UINTN                         Index;
> +  UINT8                         PhysicalAddressBits;
> +  UINT32                        RegEax;
> +  MEMORY_MAP                    PcieMmioMap;
> +
> +  Index = 0;
> +
> +  Status = PeiServicesGetBootMode(&BootMode);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  AsmCpuid(0x80000000, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= 0x80000008) {
> +    AsmCpuid(0x80000008, &RegEax, NULL, NULL, NULL);
> +    PhysicalAddressBits = (UINT8)RegEax;
> +  }
> +  else {
> +    PhysicalAddressBits = 36;
> +  }
> +
> +  ///
> +  /// Create a CPU hand-off information
> +  ///
> +  BuildCpuHob(PhysicalAddressBits, 16);
> +
> +  ///
> +  /// Build Memory Mapped IO Resource which is used to build E820 Table in
> LegacyBios.
> +  ///
> +  PcieMmioMap.BaseAddress = FixedPcdGet64(PcdPciExpressBaseAddress);
> +  PcieMmioMap.Length = PcdGet32(PcdPciExpressRegionLength);
> +
> +  BuildResourceDescriptorHob(
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    PcieMmioMap.BaseAddress,
> +    PcieMmioMap.Length
> +  );
> +  BuildMemoryAllocationHob(
> +    PcieMmioMap.BaseAddress,
> +    PcieMmioMap.Length,
> +    EfiMemoryMappedIO
> +  );
> +  for (Index = 0; Index < sizeof(MmioMap) / (sizeof(MEMORY_MAP)); Index++)
> {
> +    BuildResourceDescriptorHob(
> +      EFI_RESOURCE_MEMORY_MAPPED_IO,
> +      (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +      MmioMap[Index].BaseAddress,
> +      MmioMap[Index].Length
> +    );
> +    BuildMemoryAllocationHob(
> +      MmioMap[Index].BaseAddress,
> +      MmioMap[Index].Length,
> +      EfiMemoryMappedIO
> +    );
> +  }
> +
> +  //
> +  // Report resource HOB for flash FV
> +  //
> +  BuildResourceDescriptorHob(
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
> +    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
> +    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
> +  );
> +  BuildMemoryAllocationHob(
> +    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
> +    (UINTN)FixedPcdGet32(PcdFlashAreaSize),
> +    EfiMemoryMappedIO
> +  );
> +
> +  BuildFvHob(
> +    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
> +    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
> +  );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Board configuration init function for PEI pre-memory phase.
> +
> +  @retval EFI_SUCCESS             The function completed successfully.
> +  @retval EFI_INVALID_PARAMETER   The parameter is NULL.
> +**/
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpInitPreMem (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  ///
> +  /// Install Stall PPI
> +  ///
> +  Status = InstallStallPpi();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  ///@todo it should be moved to Si Pkg.
> +  ///
> +  /// Do Early PCH init
> +  ///
> +  EarlyPlatformPchInit();
> +
> +  //
> +  // Install PCH RESET PPI and EFI RESET2 PeiService
> +  //
> +  Status = PchInitializeReset();
> +  ASSERT_EFI_ERROR(Status);
> +
> +  ///
> +  /// Performing PlatformInitPreMemCallBack after PeiReadOnlyVariable2 PPI
> produced
> +  ///
> +  Status = PeiServicesNotifyPpi(&mPreMemNotifyList);
> +
> +  ///
> +  /// After code reorangized, memorycallback will run because the PPI is
> already
> +  /// installed when code run to here, it is supposed that the InstallEfiMemory
> is
> +  /// done before.
> +  ///
> +  Status = PeiServicesNotifyPpi(&mMemDiscoveredNotifyList);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Configure GPIO and SIO before memory ready
> +
> +  @retval  EFI_SUCCESS   Operation success.
> +**/
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardInitBeforeMemoryInit (
> +  VOID
> +  )
> +{
> +  WhiskeylakeURvpInitPreMem ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +WhiskeylakeURvpBoardDebugInit (
> +  VOID
> +  )
> +{
> +  UINT64                            LpcBaseAddress;
> +
> +  ///
> +  /// LPC I/O Configuration
> +  ///
> +  PchLpcIoDecodeRangesSet(
> +    (V_LPC_CFG_IOD_LPT_378 << N_LPC_CFG_IOD_LPT) |
> +    (V_LPC_CFG_IOD_COMB_3E8 << N_LPC_CFG_IOD_COMB) |
> +    (V_LPC_CFG_IOD_COMA_3F8 << N_LPC_CFG_IOD_COMA)
> +  );
> +
> +  PchLpcIoEnableDecodingSet(
> +    B_LPC_CFG_IOE_ME2 |
> +    B_LPC_CFG_IOE_SE |
> +    B_LPC_CFG_IOE_ME1 |
> +    B_LPC_CFG_IOE_KE |
> +    B_LPC_CFG_IOE_HGE |
> +    B_LPC_CFG_IOE_LGE |
> +    B_LPC_CFG_IOE_FDE |
> +    B_LPC_CFG_IOE_PPE |
> +    B_LPC_CFG_IOE_CBE |
> +    B_LPC_CFG_IOE_CAE
> +  );
> +
> +  ///
> +  /// Enable LPC IO decode for EC access
> +  ///
> +  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
> +    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +    DEFAULT_PCI_BUS_NUMBER_PCH,
> +    PCI_DEVICE_NUMBER_PCH_LPC,
> +    PCI_FUNCTION_NUMBER_PCH_LPC,
> +    0
> +  );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_BOOT_MODE
> +EFIAPI
> +WhiskeylakeURvpBoardBootModeDetect (
> +  VOID
> +  )
> +{
> +  return BOOT_WITH_FULL_CONFIGURATION;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/WhiskeylakeURvpHsioPtssTables.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/WhiskeylakeURvpHsioPtssTables.c
> new file mode 100644
> index 0000000000..8d8ca835bc
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/Boar
> dInitLib/WhiskeylakeURvpHsioPtssTables.c
> @@ -0,0 +1,32 @@
> +/** @file
> +    WhiskeylakeURvp HSIO PTSS H File
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef WHISKEYLAKE_RVP3_HSIO_PTSS_H_
> +#define WHISKEYLAKE_RVP3_HSIO_PTSS_H_
> +
> +#include <PchHsioPtssTables.h>
> +
> +#ifndef HSIO_PTSS_TABLE_SIZE
> +#define HSIO_PTSS_TABLE_SIZE(A) A##_Size = sizeof (A) / sizeof
> (HSIO_PTSS_TABLES)
> +#endif
> +
> +//BoardId WhiskeylakeURvp
> +HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[] = {
> +  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0}
> +};
> +
> +UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size =
> sizeof(PchLpHsioPtss_Cx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
> +
> +HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[] = {
> +  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0},
> +};
> +
> +UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size =
> sizeof(PchLpHsioPtss_Bx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
> +
> +#endif // WHISKEYLAKE_RVP3_HSIO_PTSS_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxeSaPolicyBoardConfig.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxeSaPolicyBoardConfig.c
> new file mode 100644
> index 0000000000..d2c26eb163
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxeP
> olicyBoardConfigLib/DxeSaPolicyBoardConfig.c
> @@ -0,0 +1,35 @@
> +/** @file
> + Intel DXE SA Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "DxePolicyBoardConfig.h"
> +
> +/**
> +  This function performs DXE SA Policy update by board configuration.
> +
> +  @param[in, out] DxeSaPolicy    DXE SA Policy
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateDxeSaPolicyBoardConfig (
> +  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  MEMORY_DXE_CONFIG                  *MemoryDxeConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in DXE\n"));
> +
> +  Status = GetConfigBlock ((VOID *)DxeSaPolicy, &gMemoryDxeConfigGuid,
> (VOID *)&MemoryDxeConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPl
> atformHookLib/PeiPlatformHooklib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPl
> atformHookLib/PeiPlatformHooklib.c
> new file mode 100644
> index 0000000000..c495a3a401
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPl
> atformHookLib/PeiPlatformHooklib.c
> @@ -0,0 +1,299 @@
> +/** @file
> +  PEI Library Functions. Initialize GPIOs
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +#include <PeiPlatformHookLib.h>
> +#include <SaPolicyCommon.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/PchCycleDecodingLib.h>
> +#include <Library/PeiPlatformLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PmcLib.h>
> +#include <Library/PeiSaPolicyLib.h>
> +#include <PchAccess.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <Library/GpioNativeLib.h>
> +#include <Library/GpioLib.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/CnviLib.h>
> +#include <SioRegs.h>
> +#include <PlatformBoardConfig.h>
> +#include <Library/PchPcrLib.h>
> +#include <Library/GpioCheckConflictLib.h>
> +
> +#define SIO_RUNTIME_REG_BASE_ADDRESS                          0x0680
> +
> +#define RECOVERY_MODE_GPIO_PIN                    0                    //
> Platform specific @todo use PCD
> +
> +#define MANUFACTURE_MODE_GPIO_PIN                 0                    //
> Platform specific @todo use PCD
> +
> +/**
> +  Configures GPIO
> +
> +  @param[in]  GpioTable       Point to Platform Gpio table
> +  @param[in]  GpioTableCount  Number of Gpio table entries
> +
> +**/
> +VOID
> +ConfigureGpio (
> +  IN GPIO_INIT_CONFIG                 *GpioDefinition,
> +  IN UINT16                           GpioTableCount
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "ConfigureGpio() Start\n"));
> +
> +
> +  CreateGpioCheckConflictHob (GpioDefinition, GpioTableCount);
> +
> +
> +  GpioConfigurePads (GpioTableCount, GpioDefinition);
> +
> +  DEBUG ((DEBUG_INFO, "ConfigureGpio() End\n"));
> +}
> +
> +/**
> +  Configure GPIO group GPE tier.
> +
> +  @retval     none.
> +**/
> +VOID
> +GpioGroupTierInitHook(
> +  VOID
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook Start\n"));
> +
> +  if (PcdGet32 (PcdGpioGroupToGpeDw0)) {
> +    GpioSetGroupToGpeDwX (PcdGet32 (PcdGpioGroupToGpeDw0),
> +                          PcdGet32 (PcdGpioGroupToGpeDw1),
> +                          PcdGet32 (PcdGpioGroupToGpeDw2));
> +  }
> +  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook End\n"));
> +}
> +
> +/**
> +  Configure single GPIO pad for touchpanel interrupt
> +**/
> +VOID
> +TouchpanelGpioInit (
> +  VOID
> +  )
> +{
> +  GPIO_INIT_CONFIG*     TouchpanelPad;
> +  GPIO_PAD_OWN          PadOwnVal;
> +
> +  PadOwnVal = 0;
> +  TouchpanelPad = (VOID *) (UINTN) PcdGet32
> (PcdBoardGpioTableTouchPanel);
> +  if (TouchpanelPad != NULL) {
> +    GpioGetPadOwnership (TouchpanelPad->GpioPad, &PadOwnVal);
> +    if (PadOwnVal == GpioPadOwnHost) {
> +      GpioConfigurePads (1, TouchpanelPad);
> +    }
> +  }
> +}
> +
> +/**
> +  Configure GPIO Before Memory is not ready.
> +
> +**/
> +VOID
> +GpioInitPreMem (
> +  VOID
> +  )
> +{
> +  if (PcdGet32 (PcdBoardGpioTablePreMem) != 0 && PcdGet16
> (PcdBoardGpioTablePreMemSize) != 0) {
> +    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTablePreMem),
> (UINTN) PcdGet16 (PcdBoardGpioTablePreMemSize));
> +  }
> +}
> +
> +/**
> +  Basic GPIO configuration before memory is ready
> +
> +**/
> +VOID
> +GpioInitEarlyPreMem (
> +  VOID
> +  )
> +{
> +  GPIO_CONFIG                     BbrstConfig;
> +  UINT32                          WwanBbrstGpio;
> +
> +  WwanBbrstGpio = PcdGet32 (PcdWwanBbrstGpio);
> +
> +  if (WwanBbrstGpio) {
> +    //
> +    // BIOS needs to put modem in OFF state for the two scenarios below.
> +    // 1. Modem RESET# is not asserted via PLTRST# in the previous sleep state
> +    // 2. Modem is disabled via setup option
> +    //
> +    GpioGetPadConfig (WwanBbrstGpio, &BbrstConfig);
> +    if ((PcdGetBool (PcdPcieWwanEnable) == FALSE) ||
> +        (PcdGetBool (PcdWwanResetWorkaround) == TRUE &&
> +        BbrstConfig.Direction == GpioDirOut &&
> +        BbrstConfig.OutputState == GpioOutHigh)) {
> +      //
> +      // Assert FULL_CARD_POWER_OFF#, RESET# and PERST# GPIOs
> +      //
> +      if (PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem) != 0 &&
> PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize) != 0) {
> +        ConfigureGpio ((VOID *) (UINTN) PcdGet32
> (PcdBoardGpioTableWwanOffEarlyPreMem), (UINTN) PcdGet16
> (PcdBoardGpioTableWwanOffEarlyPreMemSize));
> +      }
> +      if (PcdGetBool (PcdPcieWwanEnable) == TRUE && PcdGetBool
> (PcdWwanResetWorkaround) == TRUE) {
> +        MicroSecondDelay (1 * 1000); // Delay by 1ms
> +      }
> +    }
> +
> +    //
> +    // Turn ON modem power and de-assert RESET# and PERST# GPIOs
> +    //
> +    if (PcdGetBool (PcdPcieWwanEnable) == TRUE) {
> +      if (PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem) != 0 &&
> PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize) != 0) {
> +        ConfigureGpio ((VOID *) (UINTN) PcdGet32
> (PcdBoardGpioTableWwanOnEarlyPreMem), (UINTN) PcdGet16
> (PcdBoardGpioTableWwanOnEarlyPreMemSize));
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  Configure GPIO
> +
> +**/
> +VOID
> +GpioInit (
> +  VOID
> +  )
> +{
> +  ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable), (UINTN)
> PcdGet16 (PcdBoardGpioTableSize));
> +
> +  if (PcdGet32 (PcdBoardGpioTable2)) {
> +    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable2), (UINTN)
> PcdGet16 (PcdBoardGpioTable2Size));
> +  }
> +
> +  TouchpanelGpioInit();
> +
> +  //
> +  // Lock pads after initializing platform GPIO.
> +  // Pads which were requested to be unlocked during configuration
> +  // will not be locked.
> +  //
> +  GpioLockPads ();
> +
> +  return;
> +}
> +
> +/**
> +  Configure Super IO
> +
> +**/
> +VOID
> +SioInit (
> +  VOID
> +  )
> +{
> +  //
> +  // Program and Enable Default Super IO Configuration Port Addresses and
> range
> +  //
> +  PchLpcGenIoRangeSet (PcdGet16 (PcdLpcSioConfigDefaultPort) & (~0xF),
> 0x10);
> +
> +    PchLpcGenIoRangeSet (SIO_RUNTIME_REG_BASE_ADDRESS  & (~0x7F),
> 0x10);
> +  return;
> +}
> +
> +/**
> +  Configure GPIO and SIO before memory ready
> +
> +  @retval  EFI_SUCCESS   Operation success.
> +**/
> +EFI_STATUS
> +BoardInitPreMem (
> +  VOID
> +  )
> +{
> +  //
> +  // Obtain Platform Info from HOB.
> +  //
> +  GpioInitPreMem ();
> +  GpioGroupTierInitHook ();
> +  SioInit ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Configure GPIO and SIO
> +
> +  @retval  EFI_SUCCESS   Operation success.
> +**/
> +EFI_STATUS
> +BoardInit (
> +  VOID
> +  )
> +{
> +
> +  GpioInit ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Do platform specific programming post-memory.
> +
> +  @retval  EFI_SUCCESS       The function completed successfully.
> +**/
> +
> +EFI_STATUS
> +PlatformSpecificInit (
> +  VOID
> +  )
> +{
> +  GPIO_CONFIG                     GpioConfig;
> +
> +  if (IsCnlPch ()) {
> +
> +    //
> +    // Tristate unused pins by audio link mode.
> +    //
> +    ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
> +    GpioConfig.PadMode = GpioPadModeGpio;
> +    GpioConfig.HostSoftPadOwn = GpioHostOwnGpio;
> +    GpioConfig.Direction = GpioDirNone;
> +    GpioConfig.OutputState = GpioOutDefault;
> +    GpioConfig.InterruptConfig = GpioIntDis;
> +    GpioConfig.PowerConfig = GpioPlatformReset;
> +    GpioConfig.ElectricalConfig = GpioTermNone;
> +
> +    GpioSetPadConfig (GPIO_CNL_LP_SSP1_SFRM, &GpioConfig);
> +    GpioSetPadConfig (GPIO_CNL_LP_SSP1_TXD, &GpioConfig);
> +
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Early Board Configuration before memory is ready
> +
> +  @retval  EFI_SUCCESS  Operation success.
> +**/
> +EFI_STATUS
> +BoardInitEarlyPreMem (
> +  VOID
> +  )
> +{
> +  GpioInitEarlyPreMem ();
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
> new file mode 100644
> index 0000000000..e437814b10
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
> @@ -0,0 +1,48 @@
> +/** @file
> + Intel PEI CPU Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI CPU Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
> +  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
> +  CPU_CONFIG                  *CpuConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating CPU Policy by board config in Post
> Mem\n"));
> +
> +  Status = PeiServicesLocatePpi(
> +      &gSiPreMemPolicyPpiGuid,
> +      0,
> +      NULL,
> +      (VOID **)&SiPreMemPolicyPpi
> +      );
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *)
> &CpuConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
> new file mode 100644
> index 0000000000..3797df0856
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
> @@ -0,0 +1,29 @@
> +/** @file
> + Intel PEI CPU Pre-Memory Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +#include <Library/ConfigBlockLib.h>
> +
> +/**
> +  This function performs PEI CPU Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiCpuPolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  )
> +{
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiMePolicyBoardConfig.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiMePolicyBoardConfig.c
> new file mode 100644
> index 0000000000..843fe4accd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiMePolicyBoardConfig.c
> @@ -0,0 +1,35 @@
> +/** @file
> + Intel PEI ME Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI ME Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiMePolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  ME_PEI_CONFIG                      *MePeiConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Post
> Mem\n"));
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *)
> &MePeiConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
> new file mode 100644
> index 0000000000..79c93455a6
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
> @@ -0,0 +1,36 @@
> +/** @file
> + Intel PEI ME Pre-Memory Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI ME Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiMePolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Pre
> Mem\n"));
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPchPolicyBoardConfig.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPchPolicyBoardConfig.c
> new file mode 100644
> index 0000000000..5dbc412879
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPchPolicyBoardConfig.c
> @@ -0,0 +1,35 @@
> +/** @file
> + Intel PEI PCH Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI PCH Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  PCH_GENERAL_CONFIG                 *PchGeneralConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Post
> Mem\n"));
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid,
> (VOID *) &PchGeneralConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
> new file mode 100644
> index 0000000000..1080015029
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
> @@ -0,0 +1,36 @@
> +/** @file
> + Intel PEI PCH Pre-Memory Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI PCH Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiPchPolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  PCH_GENERAL_PREMEM_CONFIG          *PchGeneralPreMemConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Pre
> Mem\n"));
> +
> +  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi,
> &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSaPolicyBoardConfig.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSaPolicyBoardConfig.c
> new file mode 100644
> index 0000000000..d1d964aea7
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSaPolicyBoardConfig.c
> @@ -0,0 +1,35 @@
> +/** @file
> + Intel PEI SA Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI SA Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSaPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  GRAPHICS_PEI_CONFIG                *GtConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Post
> Mem\n"));
> +
> +  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid,
> (VOID *)&GtConfig);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
> new file mode 100644
> index 0000000000..34fca7fac3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
> @@ -0,0 +1,36 @@
> +/** @file
> + Intel PEI SA Pre-Memory Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI SA Pre-Memory Policy update by board
> configuration.
> +
> +  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSaPolicyBoardConfigPreMem (
> +  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  SA_MISC_PEI_PREMEM_CONFIG          *MiscPeiPreMemConfig;
> +
> +  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Pre Mem\n"));
> +
> +  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi,
> &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return Status;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSiPolicyBoardConfig.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSiPolicyBoardConfig.c
> new file mode 100644
> index 0000000000..f5f38910a8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiP
> olicyBoardConfigLib/PeiSiPolicyBoardConfig.c
> @@ -0,0 +1,27 @@
> +/** @file
> + Intel PEI SA Policy update by board configuration
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PeiPolicyBoardConfig.h"
> +
> +/**
> +  This function performs PEI SI Policy update by board configuration.
> +
> +  @param[in, out] SiPolicy        The SI Policy PPI instance
> +
> +  @retval EFI_SUCCESS             The SI Policy is successfully updated.
> +  @retval Others                  The SI Policy is not successfully updated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdatePeiSiPolicyBoardConfig (
> +  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:17   ` Chiu, Chasel
  2019-08-17 20:00   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:17 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to
> global build config and documentation
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> * Adds the WhiskeylakeURvp board as a build option in build.cfg so it
>   it is listed as a valid build target.
> * Updates relevant Readme.md files to include instructions for
>   WhiskeylakeOpenBoardPkg.
> * Adds the maintainers for WhiskeylakeOpenBoardPkg to maintainers.txt.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
>  Maintainers.txt          |  5 +++
>  Platform/Intel/Readme.md | 44 +++++++++++++-------
> Platform/Intel/build.cfg |  4 +-
>  Readme.md                |  1 +
>  4 files changed, 38 insertions(+), 16 deletions(-)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt index bc8cbd6458..b16432bf87
> 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -98,6 +98,11 @@ M: Shifei A Lu <shifei.a.lu@intel.com>
>  M: Xiaohu Zhou <bowen.zhou@intel.com>
>  M: Isaac W Oram <isaac.w.oram@intel.com>
> 
> +Platform/Intel/WhiskeylakeOpenBoardPkg
> +M: Chasel Chiu <chasel.chiu@intel.com>
> +M: Michael Kubacki <michael.a.kubacki@intel.com>
> +M: Nate DeSimone <nathaniel.l.desimone@intel.com>
> +
>  Platform/Intel/Tools
>  M: Bob Feng <bob.c.feng@intel.com>
>  M: Liming Gao <liming.gao@intel.com>
> diff --git a/Platform/Intel/Readme.md b/Platform/Intel/Readme.md index
> 00f42985a2..aaf6ef4d3e 100644
> --- a/Platform/Intel/Readme.md
> +++ b/Platform/Intel/Readme.md
> @@ -53,9 +53,10 @@ A UEFI firmware implementation using MinPlatformPkg
> is constructed using the fol
> 
> 
>  ## Board Support
> +* The `ClevoOpenBoardPkg` contains board implementations for Clevo
> systems.
>  * The `KabylakeOpenBoardPkg` contains board implementations for Kaby
> Lake systems.
>  * The `PurleyOpenBoardPkg` contains board implementations for Purley
> systems.
> -* The `ClevoOpenBoardPkg` contains board implementations for Clevo
> systems.
> +* The `WhiskeylakeOpenBoardPkg` contains board implementations for
> Whiskey Lake systems.
> 
>  ## Board Package Organization
>  The board package follows the standard EDK II package structure with the
> following additional elements and guidelines:
> @@ -189,7 +190,12 @@ return back to the minimum platform caller.
>            |       |        |                |---build_config.cfg: BoardMtOlympus
> specific
>            |       |        |                |                     build settings, environment
> variables.
>            |       |        |                |---build_board.py: Optional board-specific
> pre-build,
> -          |       |        |                |                   build, post-build and clean
> functions.
> +          |       |        |                                    build, post-build and clean
> functions.
> +          |       |        |
> +          |       |        |------WhiskeylakeOpenBoardPkg
> +          |       |        |        |------WhiskeylakeURvp
> +          |       |        |                |---build_config.cfg: WhiskeylakeURvp
> specific build
> +          |       |        |                                      settings environment
> variables.
>            |------FSP
>    </pre>
> 
> @@ -222,19 +228,6 @@ Users can also flash the UEFI firmware image to the
> highest area of the flash re
> 
>  ### **Known limitations**
> 
> -**KabylakeOpenBoardPkg**
> -1. This firmware project has only been tested on the Intel KabylakeRvp3
> board.
> -2. This firmware project has only been tested booting to Microsoft Windows
> 10 x64 with AHCI mode and Integrated Graphic
> -  Device.
> -3. The Windows build was tested on Windows 10 with Microsoft Visual Studio
> 2015.
> -4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
> -5. The build was tested with NASM version 2.11.08.
> -
> -**PurleyOpenBoardPkg**
> -1. This firmware project has only been tested on the Microsoft MtOlympus
> board.
> -2. This firmware project has only been tested booting to Microsoft Windows
> Server 2016 with NVME on M.2 slot.
> -3. This firmware project build has only been tested using the Microsoft Visual
> Studio 2015 compiler.
> -
>  **ClevoOpenBoardPkg**
>  1. Currently, support is only being added for the N1xxWU series of boards.
>  2. The Windows build was tested on Windows 10 with Microsoft Visual Studio
> 2015 compiler.
> @@ -244,6 +237,27 @@ Users can also flash the UEFI firmware image to the
> highest area of the flash re  6. The firmware project applies to all Clevo
> supported board configurations but is only being tested on System 76 Galago
>    Pro devices.
> 
> +**KabylakeOpenBoardPkg**
> +1. This firmware project has only been tested on the Intel KabylakeRvp3
> board.
> +2. This firmware project has only been tested booting to Microsoft
> +Windows 10 x64 with AHCI mode and Integrated Graphic
> +  Device.
> +3. The Windows build was tested on Windows 10 with Microsoft Visual Studio
> 2015.
> +4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
> +5. The build was tested with NASM version 2.11.08.
> +
> +**PurleyOpenBoardPkg**
> +1. This firmware project has only been tested on the Microsoft MtOlympus
> board.
> +2. This firmware project has only been tested booting to Microsoft Windows
> Server 2016 with NVME on M.2 slot.
> +3. This firmware project build has only been tested using the Microsoft Visual
> Studio 2015 compiler.
> +
> +**WhiskeylakeOpenBoardPkg**
> +1. This firmware project has only been tested on the Intel WhiskeylakeURvp
> board.
> +2. This firmware project has only been tested booting to Microsoft
> +Windows 10 x64 with AHCI mode and Integrated Graphic
> +  Device.
> +3. The Windows build was tested on Windows 10 with Microsoft Visual Studio
> 2015.
> +4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
> +5. The build was tested with NASM version 2.11.08.
> +
>  ### **Planned Activities**
>  * Replace the batch build scripts with cross-platform Python build scripts.
>  * Publish a Minimum Platform specification to describe the architecture and
> interfaces in more detail.
> diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index
> fc6e4fe824..b6d32ada49 100644
> --- a/Platform/Intel/build.cfg
> +++ b/Platform/Intel/build.cfg
> @@ -51,6 +51,8 @@ NUMBER_OF_PROCESSORS = 0
> 
>  [PLATFORMS]
>  # board_name = path_to_board_build_config.cfg
> +BoardMtOlympus =
> PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
>  KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
>  N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> -BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> +WhiskeylakeURvp =
> +WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
> +
> diff --git a/Readme.md b/Readme.md
> index 1befd0b544..e4f211eee6 100644
> --- a/Readme.md
> +++ b/Readme.md
> @@ -228,6 +228,7 @@ they will be documented with the platform.
>  * [Clevo](Platform/Intel/ClevoOpenBoardPkg)
>  * [Kaby Lake](Platform/Intel/KabylakeOpenBoardPkg)
>  * [Purley](Platform/Intel/PurleyOpenBoardPkg)
> +* [Whiskey Lake](Platform/Intel/WhiskeylakeOpenBoardPkg)
> 
>  For more information, see the
>  [EDK II Minimum Platform
> Specification](https://edk2-docs.gitbooks.io/edk-ii-minimum-platform-specif
> ication).
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
@ 2019-08-17  1:17   ` Chiu, Chasel
  2019-08-17  7:50   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chiu, Chasel @ 2019-08-17  1:17 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add
> modules
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> Modules shared across board instances.
> 
> * BoardAcpiDxe - Performs DXE board ACPI initialization.
> * PciHotPlug - Performs PCI-e resource configuration.
> * PeiTbtInit - Initializes Thunderbolt policy in PEI.
> * PolicyInitDxe - Initializes policy in DXE.
> * TbtDxe - Performs Thunderbolt initialization in DXE.
> * TbtSmm - Performs Thunderbolt initialization in SMM.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDx
> e.inf          |   71 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.i
> nf          |   62 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.
> inf         |   51 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtI
> nit.inf     |   47 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> mm.inf         |   80 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.
> inf      |  176 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.
> h            |  130 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> miHandler.h    |  180 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.
> h         |   32 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInit
> Dxe.h     |   38 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInit
> Dxe.h     |   41 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInit
> Dxe.h     |   52 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.
> h        |   45 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitD
> xe.h      |   56 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyI
> nitDxe.h |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.
> c            |   96 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDx
> e.c            |  290 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
> |  353 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.
> c           |  228 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtI
> nit.c       |  211 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> miHandler.c    | 1609 +++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> mm.c           | 1765 ++++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLi
> b.c         |  394 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.
> c         |  612 +++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInit
> Dxe.c     |   46 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInit
> Dxe.c     |  174 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInit
> Dxe.c     |   55 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.
> c        |   88 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitD
> xe.c      |   60 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyI
> nitDxe.c |   46 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUP
> D.asl           |   20 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.AS
> L             |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBu
> s.asl          |  516 ++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.
> asl          |  309 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfor
> m.asl         |   76 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3Pci
> eTbt.asl     |  405 +++++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
> | 1877 ++++++++++++++++++++
>  37 files changed, 10365 insertions(+)
> 
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.inf
> new file mode 100644
> index 0000000000..2bbc3cb9e2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.inf
> @@ -0,0 +1,71 @@
> +## @file
> +#  Component information file for AcpiPlatform module
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BoardAcpiDxe
> +  FILE_GUID                      = E269E77D-6163-4F5D-8E59-21EAF114D307
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InstallAcpiBoard
> +
> +[Sources.common]
> +  BoardAcpiDxe.c
> +  AcpiGnvsInit.c
> +  Dsdt/DSDT.ASL
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  PcAtChipsetPkg/PcAtChipsetPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  BaseLib
> +  DebugLib
> +  IoLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseMemoryLib
> +  HobLib
> +  AslUpdateLib
> +  BoardAcpiTableLib
> +
> +[Protocols]
> +  gEfiAcpiTableProtocolGuid                     ## CONSUMES
> +  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
> +  gEfiMpServiceProtocolGuid                     ## CONSUMES
> +  gEfiGlobalNvsAreaProtocolGuid
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress
> +
> +  gBoardModuleTokenSpaceGuid.PcdAcpiSleepState
> +  gBoardModuleTokenSpaceGuid.PcdAcpiHibernate
> +  gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle
> +  gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints
> +  gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints
> +  gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints
> +
> +[Depex]
> +  gEfiAcpiTableProtocolGuid           AND
> +  gEfiFirmwareVolume2ProtocolGuid     AND
> +  gEfiPciRootBridgeIoProtocolGuid     AND
> +  gEfiVariableArchProtocolGuid        AND
> +  gEfiVariableWriteArchProtocolGuid
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.inf
> new file mode 100644
> index 0000000000..dd4e41a409
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.inf
> @@ -0,0 +1,62 @@
> +## @file
> +# This module will perform specific PCI-Express devices
> +# resource configuration.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PciHotPlug
> +  FILE_GUID                      = 3022E512-B94A-4F12-806D-7EF1177899D8
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = PciHotPlug
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  DevicePathLib
> +  DebugLib
> +  UefiLib
> +  HobLib
> +  PchPcieRpLib
> +  ConfigBlockLib
> +  TbtCommonLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PciHotPlug.c
> +  PciHotPlug.h
> +
> +[Protocols]
> +  gEfiPciHotPlugInitProtocolGuid                ## PRODUCES
> +  gSaPolicyProtocolGuid                         ## CONSUMES
> +
> +[Guids]
> +  gEfiHobListGuid                               ## CONSUMES
> +  gPcieRpConfigGuid                  ## CONSUMES
> +
> +[Pcd]
> +
> +[Depex]
> +  gDxeTbtPolicyProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.inf
> new file mode 100644
> index 0000000000..5160bb1dbb
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.inf
> @@ -0,0 +1,51 @@
> +## @file
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = TbtDxe
> +  FILE_GUID                      = 19C9762C-3A88-41B0-906F-8C4C2895A887
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = TbtDxeEntryPoint
> +
> +[LibraryClasses]
> +  DebugLib
> +  BaseMemoryLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  UefiDriverEntryPoint
> +  HobLib
> +  UefiLib
> +  TbtCommonLib
> +  DxeTbtPolicyLib
> +  AslUpdateLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  TbtDxe.c
> +
> +[Protocols]
> +  gTbtNvsAreaProtocolGuid                       ## CONSUMES
> +  gDxeTbtPolicyProtocolGuid
> +
> +[Guids]
> +  gTbtInfoHobGuid                               ## CONSUMES
> +
> +[Depex]
> +  gEfiVariableWriteArchProtocolGuid   AND
> +  gEfiVariableArchProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.inf
> new file mode 100644
> index 0000000000..07962ffa10
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.inf
> @@ -0,0 +1,47 @@
> +## @file
> +# Component information file for the TBT Init PEI module.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiTbtInit
> +  FILE_GUID                      = 90BF2BFB-F998-4cbc-AD72-008D4D047A4B
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  ENTRY_POINT                    = TbtInitEntryPoint
> +
> +[LibraryClasses]
> +  PeimEntryPoint
> +  DebugLib
> +  HobLib
> +  PeiServicesLib
> +  PeiTbtPolicyLib
> +  PeiDTbtInitLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PeiTbtInit.c
> +
> +[Guids]
> +  gTbtInfoHobGuid                               ## CONSUMES
> +
> +[Ppis]
> +  gEfiEndOfPeiSignalPpiGuid                     ## CONSUMES
> +  gPeiTbtPolicyBoardInitDonePpiGuid             ## CONSUMES
> +
> +[Depex]
> +  gEfiPeiMemoryDiscoveredPpiGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.inf
> new file mode 100644
> index 0000000000..3d4e6ceea0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.inf
> @@ -0,0 +1,80 @@
> +## @file
> +# Component information file for the ThunderBolt Smm module.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = TbtSmm
> +  FILE_GUID                      = 5BDCD685-D80A-42E6-9867-A84CCE7F828E
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_SMM_DRIVER
> +  PI_SPECIFICATION_VERSION       = 1.10
> +  ENTRY_POINT                    = TbtSmmEntryPoint
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiRuntimeServicesTableLib
> +  UefiBootServicesTableLib
> +  IoLib
> +  PciExpressLib
> +  HobLib
> +  ReportStatusCodeLib
> +  PciSegmentLib
> +  UefiLib
> +  SmmServicesTableLib
> +  GpioLib
> +  PchInfoLib
> +  TbtCommonLib
> +  PchPmcLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +#  gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength      ##
> CONSUMES
> +
> +[FixedPcd]
> +  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress       ## CONSUMES
> +
> +[Sources]
> +  TbtSmiHandler.h
> +  TbtSmiHandler.c
> +  TbtSmm.c
> +
> +[Protocols]
> +  gTbtNvsAreaProtocolGuid                       ## CONSUMES
> +  gEfiSmmSxDispatch2ProtocolGuid                ## CONSUMES
> +  gEfiSmmSwDispatch2ProtocolGuid                ## CONSUMES
> +  gEfiSmmVariableProtocolGuid                   ## CONSUMES
> +  gDxeTbtPolicyProtocolGuid
> +
> +[Guids]
> +  gTbtInfoHobGuid                               ## CONSUMES
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +
> +[Depex]
> +  gEfiSmmBase2ProtocolGuid            AND
> +  gEfiSmmSxDispatch2ProtocolGuid      AND
> +  gEfiSmmSwDispatch2ProtocolGuid      AND
> +  gEfiGlobalNvsAreaProtocolGuid       AND
> +  gEfiVariableWriteArchProtocolGuid   AND
> +  gEfiVariableArchProtocolGuid        AND
> +  gEfiSmmVariableProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.inf
> new file mode 100644
> index 0000000000..65c531a532
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.inf
> @@ -0,0 +1,176 @@
> +## @file
> +# Module Information file for the PolicyInit DXE driver.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PolicyInitDxe
> +  FILE_GUID                      = 490D0119-4448-440D-8F5C-F58FB53EE057
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = PolicyInitDxeEntryPoint
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  CpuPlatformLib
> +  DebugLib
> +  DxeServicesTableLib
> +  IoLib
> +  MemoryAllocationLib
> +  DxeSaPolicyLib
> +  DxePchPolicyLib
> +  PcdLib
> +  DxePolicyBoardConfigLib
> +  DxePolicyUpdateLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +  ConfigBlockLib
> +  DevicePathLib
> +  DxeTbtPolicyLib
> +  PchPcieRpLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                          ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                          ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable
> +  gBoardModuleTokenSpaceGuid.PcdPlatformFlavor
> +  gBoardModuleTokenSpaceGuid.PcdPlatformType
> +  gBoardModuleTokenSpaceGuid.PcdEcPresent
> +  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid
> +  gBoardModuleTokenSpaceGuid.PcdTbtEnable
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable                      ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable
> ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication                      ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication                      ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication
> ## CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
> +  gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport
> +  gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport
> +  gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin
> +  gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
> +  gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
> +  gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature
> +  gBoardModuleTokenSpaceGuid.PcdBatteryPresent
> +
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support
> +
> +  #
> +  # PSS Board Configuration.
> +  #
> +  gBoardModuleTokenSpaceGuid.PcdPssReadSN
> +  gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber
> +  gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress
> +
> +  gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature
> +  gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile
> +  gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio
> +  gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdGnssResetGpio
> +  gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio
> +
> +  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
> +  gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber
> +  gBoardModuleTokenSpaceGuid.PcdEcSmiGpio
> +  gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio
> +  gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad
> +  gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck
> +  gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride
> +  gBoardModuleTokenSpaceGuid.PcdDDISelection
> +  gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed
> +  gPlatformModuleTokenSpaceGuid.PcdH8S2113Present
> +  gPlatformModuleTokenSpaceGuid.PcdNat87393Present
> +  gPlatformModuleTokenSpaceGuid.PcdNct677FPresent
> +  gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport
> +  gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin
> +  gBoardModuleTokenSpaceGuid.PcdRealBattery1Control
> +  gBoardModuleTokenSpaceGuid.PcdRealBattery2Control
> +  gBoardModuleTokenSpaceGuid.PcdDimmPopulationError
> +  gBoardModuleTokenSpaceGuid.PcdBtIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio
> +  gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable
> +  gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported
> +  gBoardModuleTokenSpaceGuid.PcdMipiCamSensor
> +  gBoardModuleTokenSpaceGuid.PcdH8S2113SIO
> +  gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM
> +  gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO
> +  gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON
> +  gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable
> +  gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate
> +
> +[Sources]
> +  PolicyInitDxe.c
> +  SaPolicyInitDxe.c
> +  SiliconPolicyInitDxe.c
> +  GopPolicyInitDxe.c
> +  PchPolicyInitDxe.c
> +  CpuPolicyInitDxe.c
> +  BoardInitLib.c
> +
> +[Protocols]
> +  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
> +  gDxeMePolicyGuid                              ## PRODUCES
> +  gSaPolicyProtocolGuid                         ## CONSUMES
> +  gPchPolicyProtocolGuid                        ## CONSUMES
> +  gDxeSiPolicyProtocolGuid                      ## PRODUCES
> +  gGopPolicyProtocolGuid                        ## PRODUCES
> +  gDxeCpuPolicyProtocolGuid                     ## PRODUCES
> +
> +[Guids]
> +  gCpuSmmGuid                                   ## CONSUMES
> +  gSiMemoryInfoDataGuid
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.h
> new file mode 100644
> index 0000000000..f57bfb8c26
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.h
> @@ -0,0 +1,130 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCI_HOT_PLUG_H_
> +#define _PCI_HOT_PLUG_H_
> +
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +#include <Base.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Acpi10.h>
> +#include <Protocol/PciHotPlugInit.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/UefiLib.h>
> +#include <Guid/HobList.h>
> +#include <Library/HobLib.h>
> +#include <Protocol/SaPolicy.h>
> +
> +#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U',
> 'L', 'P')
> +
> +#define ACPI \
> +  { \
> +    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
> (UINT8) \
> +      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 \
> +  }
> +
> +#define PCI(device, function) \
> +  { \
> +    { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof
> (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \
> +      (UINTN) function, (UINTN) device \
> +  }
> +
> +#define END \
> +  { \
> +    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
> { END_DEVICE_PATH_LENGTH, 0 } \
> +  }
> +
> +#define LPC(eisaid, function) \
> +  { \
> +    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
> (UINT8) \
> +      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid),
> function \
> +  }
> +
> +typedef struct PCIE_HOT_PLUG_DEVICE_PATH {
> +  ACPI_HID_DEVICE_PATH      PciRootBridgeNode;
> +  PCI_DEVICE_PATH           PciRootPortNode;
> +  EFI_DEVICE_PATH_PROTOCOL  EndDeviceNode;
> +} PCIE_HOT_PLUG_DEVICE_PATH;
> +
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      Handle; // Handle for protocol this driver
> installs on
> +  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  HotPlugInitProtocol;
> +} PCI_HOT_PLUG_INSTANCE;
> +
> +/**
> +  This procedure returns a list of Root Hot Plug controllers that require
> +  initialization during boot process
> +
> +  @param[in]  This      The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[out] HpcCount  The number of Root HPCs returned.
> +  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number
> of elements in this list.
> +
> +  @retval EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetRootHpcList (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
> +  OUT UINTN                             *PhpcCount,
> +  OUT EFI_HPC_LOCATION                  **PhpcList
> +  );
> +
> +/**
> +  This procedure Initializes one Root Hot Plug Controller
> +  This process may casue initialization of its subordinate buses
> +
> +  @param[in]  This            The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[in]  HpcDevicePath   The Device Path to the HPC that is being
> initialized.
> +  @param[in]  HpcPciAddress   The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[in]  Event           The event that should be signaled when the Hot
> Plug Controller initialization is complete. Set to NULL if the caller wants to wait
> until the entire initialization process is complete. The event must be of the
> type EFI_EVT_SIGNAL.
> +  @param[out] HpcState        The state of the Hot Plug Controller hardware.
> The type EFI_Hpc_STATE is defined in section 3.1.
> +
> +  @retval   EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeRootHpc (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
> +  IN  UINT64                          PhpcPciAddress,
> +  IN  EFI_EVENT                       Event, OPTIONAL
> +  OUT EFI_HPC_STATE                   *PhpcState
> +  );
> +
> +/**
> +  Returns the resource padding required by the PCI bus that is controlled by
> the specified Hot Plug Controller.
> +
> +  @param[in]  This           The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol. initialized.
> +  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
> +  @param[in]  HpcPciAddress  The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[out] HpcState       The state of the Hot Plug Controller hardware.
> The type EFI_HPC_STATE is defined in section 3.1.
> +  @param[out] Padding        This is the amount of resource padding
> required by the PCI bus under the control of the specified Hpc. Since the caller
> does not know the size of this buffer, this buffer is allocated by the callee and
> freed by the caller.
> +  @param[out] Attribute      Describes how padding is accounted for.
> +
> +  @retval     EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetResourcePadding (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
> +  IN  UINT64                          PhpcPciAddress,
> +  OUT EFI_HPC_STATE                   *PhpcState,
> +  OUT VOID                            **Padding,
> +  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.h
> new file mode 100644
> index 0000000000..b91b0f14bd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.h
> @@ -0,0 +1,180 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_SMI_HANDLER_H_
> +#define _TBT_SMI_HANDLER_H_
> +
> +#include <Library/TbtCommonLib.h>
> +#include <Library/IoLib.h>
> +#include <IndustryStandard/Pci.h>
> +
> +#ifdef PROGRESS_CODE
> +#undef PROGRESS_CODE
> +#endif
> +
> +#define MAX_TBT_DEPTH         6
> +
> +#define P2P_BRIDGE            (((PCI_CLASS_BRIDGE) << 8) |
> (PCI_CLASS_BRIDGE_P2P))
> +
> +#define BAR_ALIGN(v, a)       ((((v) - 1) | (a)) + 1)
> +
> +#define CMD_BUS_MASTER        BIT2
> +#define CMD_BM_IO             (CMD_BUS_MASTER | BIT0)
> +#define CMD_BM_MEM            (CMD_BUS_MASTER | BIT1)
> +#define CMD_BM_MEM_IO         (CMD_BUS_MASTER | BIT1 | BIT0)
> +
> +#define DEF_CACHE_LINE_SIZE   0x20
> +#define DEF_RES_IO_PER_DEV    4
> +#define DEF_RES_MEM_PER_DEV   32
> +#define DEF_RES_PMEM_PER_DEV  32
> +
> +#define DOCK_BUSSES           8
> +
> +#define DISBL_IO_REG1C        0x01F1
> +#define DISBL_MEM32_REG20     0x0000FFF0
> +#define DISBL_PMEM_REG24      0x0001FFF1
> +
> +#define count(x)              (sizeof (x) / sizeof ((x)[0]))
> +
> +#define PCIE_CAP_ID_SSID_SSVID 0x0D
> +#define INVALID_PCI_DEVICE    0xFFFFFFFF
> +#define PCI_TBT_VESC_REG2     0x510
> +
> +typedef struct _PortInfo {
> +  UINT8   IoBase;
> +  UINT8   IoLimit;
> +  UINT16  MemBase;
> +  UINT16  MemLimit;
> +  UINT64  PMemBase64;
> +  UINT64  PMemLimit64;
> +  UINT8   BusNumLimit;
> +  UINT8   ConfedEP;
> +} PORT_INFO;
> +
> +typedef struct _MEM_REGS {
> +  UINT32  Base;
> +  UINT32  Limit;
> +} MEM_REGS;
> +
> +typedef struct _PMEM_REGS {
> +  UINT64  Base64;
> +  UINT64  Limit64;
> +} PMEM_REGS;
> +
> +typedef struct _IO_REGS {
> +  UINT16  Base;
> +  UINT16  Limit;
> +} IO_REGS;
> +
> +typedef struct _BRDG_RES_CONFIG {
> +  UINT8   Cmd;
> +  UINT8   Cls;
> +  UINT8   IoBase;
> +  UINT8   IoLimit;
> +  UINT16  MemBase;
> +  UINT16  MemLimit;
> +  UINT64  PMemBase64;
> +  UINT64  PMemLimit64;
> +} BRDG_RES_CONFIG;
> +
> +typedef struct _BRDG_CONFIG {
> +  DEV_ID          DevId;
> +  UINT8           PBus;
> +  UINT8           SBus;
> +  UINT8           SubBus;
> +  BOOLEAN         IsDSBridge;
> +  BRDG_RES_CONFIG Res;
> +} BRDG_CONFIG;
> +
> +enum {
> +  HR_US_PORT,
> +  HR_DS_PORT0,
> +  HR_DS_PORT3,
> +  HR_DS_PORT4,
> +  HR_DS_PORT5,
> +  HR_DS_PORT6,
> +  MAX_CFG_PORTS
> +};
> +
> +enum {
> +  HR_DS_PORT1   = HR_DS_PORT3
> +};
> +
> +//
> +// Alpine Ridge
> +//
> +enum {
> +  AR_DS_PORT1 = HR_DS_PORT3,
> +  AR_DS_PORT2,
> +  AR_DS_PORT3,
> +  AR_DS_PORT4
> +};
> +
> +typedef struct _HR_CONFIG {
> +  UINT16  DeviceId;
> +  UINT8   HRBus;
> +  UINT8   MinDSNumber;
> +  UINT8   MaxDSNumber;
> +  UINT8   BridgeLoops;
> +} HR_CONFIG;
> +
> +STATIC const BRDG_RES_CONFIG  NOT_IN_USE_BRIDGE = {
> +  CMD_BUS_MASTER,
> +  0,
> +  DISBL_IO_REG1C & 0xFF,
> +  DISBL_IO_REG1C >> 8,
> +  DISBL_MEM32_REG20 & 0xFFFF,
> +  DISBL_MEM32_REG20 >> 16,
> +  DISBL_PMEM_REG24 & 0xFFFF,
> +  DISBL_PMEM_REG24 >> 16
> +};
> +
> +typedef union _BRDG_CIO_MAP_REG {
> +  UINT32  AB_REG;
> +  struct {
> +    UINT32  NumOfDSPorts : 5;
> +    UINT32  CioPortMap : 27;
> +  } Bits;
> +} BRDG_CIO_MAP_REG;
> +
> +//
> +// Functions
> +//
> +VOID
> +ThunderboltCallback (
> +  IN UINT8 Type
> +  );
> +
> +VOID
> +TbtDisablePCIDevicesAndBridges (
> +  IN UINT8 Type
> +  );
> +
> +VOID
> +EndOfThunderboltCallback(
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +);
> +
> +VOID
> +ConfigureTbtAspm(
> +  IN UINT8       Type,
> +  IN UINT16      Aspm
> +);
> +
> +UINT8
> +PcieFindCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT8   CapId
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.h
> new file mode 100644
> index 0000000000..ac13acc27d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.h
> @@ -0,0 +1,32 @@
> +/** @file
> + Header file for board Init function for DXE Init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_BOARD_INIT_LIB_H_
> +#define _DXE_BOARD_INIT_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <PlatformBoardId.h>
> +#include <Register/PchRegs.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Platform.h>
> +
> +EFI_STATUS
> +EFIAPI
> +BoardConfigInit (
> +   VOID
> +  );
> +
> +#endif // _DXE_BOARD_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.h
> new file mode 100644
> index 0000000000..5d0e2777d8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.h
> @@ -0,0 +1,38 @@
> +/** @file
> +  Header file for the SiliconPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_POLICY_INIT_DXE_H_
> +#define _CPU_POLICY_INIT_DXE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +
> +#include <Protocol/CpuPolicyProtocol.h>
> +#include <Library/DxeCpuPolicyUpdateLib.h>
> +
> +
> +/**
> +  Initialize Intel CPU DXE Policy
> +
> +  @param[in] ImageHandle          Image handle of this driver.
> +
> +  @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
> +CpuPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.h
> new file mode 100644
> index 0000000000..ff975efae0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.h
> @@ -0,0 +1,41 @@
> +/** @file
> +Header file for the GopPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GOP_POLICY_INIT_DXE_H_
> +#define _GOP_POLICY_INIT_DXE_H_
> +
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <PlatformBoardId.h>
> +#include <Library/PcdLib.h>
> +
> +/**
> +Initialize GOP DXE Policy
> +
> +@param[in] ImageHandle          Image handle of this driver.
> +
> +@retval EFI_SUCCESS             Initialization complete.
> +@retval 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
> +GopPolicyInitDxe(
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyIn
> itDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.h
> new file mode 100644
> index 0000000000..1055fed7c8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.h
> @@ -0,0 +1,52 @@
> +/** @file
> +  Header file for the PchPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_POLICY_INIT_DXE_H_
> +#define _PCH_POLICY_INIT_DXE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <FirwmareConfigurations.h>
> +#include <Protocol/PchPolicy.h>
> +#include <Library/DxePchPolicyLib.h>
> +#include <Library/DxePchPolicyUpdateLib.h>
> +
> +extern UINT8 mFirmwareConfiguration;
> +
> +/**
> +  <b>PCH DXE Policy Driver Entry Point</b> \n
> +  - <b>Introduction</b> \n
> +    Pch DXE drivers behavior can be controlled by platform policy without
> modifying reference code directly.
> +    Platform policy Protocol is initialized with default settings in this funciton.
> +    This policy Protocol has to be initialized prior to PCH initialization DXE
> drivers execution.
> +
> +  - @pre
> +    - Runtime variable service should be ready if policy initialization required.
> +
> +  - @result
> +    PCH_POLICY_PROTOCOL will be installed successfully and ready for Pch
> reference code use.
> +
> +  - <b>Porting Recommendations</b> \n
> +    Policy should be initialized basing on platform design or user selection (like
> BIOS Setup Menu)
> +
> +  @param[in] ImageHandle - Image handle of this driver.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @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
> +PchPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.h
> new file mode 100644
> index 0000000000..d2aac9823e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.h
> @@ -0,0 +1,45 @@
> +/** @file
> +  Header file for the PolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _POLICY_INIT_DXE_H_
> +#define _POLICY_INIT_DXE_H_
> +
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include "SaPolicyInitDxe.h"
> +#include "PchPolicyInitDxe.h"
> +#include "SiliconPolicyInitDxe.h"
> +#include "GopPolicyInitDxe.h"
> +#include "CpuPolicyInitDxe.h"
> +
> +#include <Library/DxeTbtPolicyLib.h>
> +/**
> +  Initialize DXE Platform Policy
> +
> +  @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
> +PolicyInitDxeEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.h
> new file mode 100644
> index 0000000000..0f86711e6a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.h
> @@ -0,0 +1,56 @@
> +/** @file
> +  Header file for the SaPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_POLICY_INIT_DXE_H_
> +#define _SA_POLICY_INIT_DXE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <FirwmareConfigurations.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Library/DxeSaPolicyLib.h>
> +#include <Library/DxePolicyBoardConfigLib.h>
> +#include <Library/DxeSaPolicyUpdateLib.h>
> +
> +#include <SaAccess.h>
> +
> +extern UINT8 mFirmwareConfiguration;
> +
> +/**
> +  <b>SA DXE Policy Driver Entry Point</b> \n
> +  - <b>Introduction</b> \n
> +    System Agent DXE drivers behavior can be controlled by platform policy
> without modifying reference code directly.
> +    Platform policy Protocol is initialized with default settings in this funciton.
> +    This policy Protocol has to be initialized prior to System Agent
> initialization DXE drivers execution.
> +
> +  - @pre
> +    - Runtime variable service should be ready if policy initialization required.
> +
> +  - @result
> +    SA_POLICY_PROTOCOL will be installed successfully and ready for System
> Agent reference code use.
> +
> +  - <b>Porting Recommendations</b> \n
> +    Policy should be initialized basing on platform design or user selection (like
> BIOS Setup Menu)
> +
> +  @param[in] ImageHandle - Image handle of this driver.
> +
> +  @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
> +SaPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolic
> yInitDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.h
> new file mode 100644
> index 0000000000..a2c5f548fa
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  Header file for the SiliconPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SILICON_POLICY_INIT_DXE_H_
> +#define _SILICON_POLICY_INIT_DXE_H_
> +
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Guid/StatusCodeDataTypeId.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <Protocol/SiPolicyProtocol.h>
> +
> +/**
> +  Initilize Intel CPU DXE Policy
> +
> +  @param[in] ImageHandle             Image handle of this driver.
> +
> +  @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
> +SiliconPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsIn
> it.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsIn
> it.c
> new file mode 100644
> index 0000000000..1ff129c307
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsIn
> it.c
> @@ -0,0 +1,96 @@
> +/** @file
> +  Acpi Gnvs Init Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <PchAccess.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/MpService.h>
> +
> +/**
> +@brief
> +  Global NVS initialize.
> +
> +  @param[in] GlobalNvs         - Pointer of Global NVS area
> +
> +  @retval EFI_SUCCESS          - Allocate Global NVS completed.
> +  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for
> GNVS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiGnvsInit (
> +  IN OUT VOID                   **GlobalNvs
> +  )
> +{
> +  UINTN                         Pages;
> +  EFI_PHYSICAL_ADDRESS          Address;
> +  EFI_STATUS                    Status;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GNVS;
> +  EFI_MP_SERVICES_PROTOCOL      *MpService;
> +  UINTN                         NumberOfCPUs;
> +  UINTN                         NumberOfEnabledCPUs;
> +
> +  Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
> +  Address = 0xffffffff; // allocate address below 4G.
> +
> +  Status  = gBS->AllocatePages (
> +                   AllocateMaxAddress,
> +                   EfiACPIMemoryNVS,
> +                   Pages,
> +                   &Address
> +                   );
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Locate the MP services protocol
> +  // Find the MP Protocol. This is an MP platform, so MP protocol must be
> there.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiMpServiceProtocolGuid,
> +                  NULL,
> +                  (VOID **) &MpService
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Determine the number of processors
> +  //
> +  MpService->GetNumberOfProcessors (
> +              MpService,
> +              &NumberOfCPUs,
> +              &NumberOfEnabledCPUs
> +              );
> +
> +  *GlobalNvs = (VOID *) (UINTN) Address;
> +  SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
> +
> +  //
> +  // GNVS default value init here...
> +  //
> +  GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
> +
> +  GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
> +
> +  //
> +  // Miscellaneous
> +  //
> +  GNVS->Area->PL1LimitCS = 0;
> +  GNVS->Area->PL1LimitCSValue = 4500;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.c
> new file mode 100644
> index 0000000000..cb5f328a39
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.c
> @@ -0,0 +1,290 @@
> +/** @file
> +  ACPI Platform Driver
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/BoardAcpiTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/AslUpdateLib.h>
> +
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/AcpiTable.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL
> mGlobalNvsArea;
> +
> +/**
> +@brief
> +  Global NVS initialize.
> +
> +  @param[in] GlobalNvs         - Pointer of Global NVS area
> +
> +  @retval EFI_SUCCESS          - Allocate Global NVS completed.
> +  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for
> GNVS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiGnvsInit (
> +  IN OUT VOID                   **GlobalNvs
> +  );
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  Locate the first instance of a protocol.  If the protocol requested is an
> +  FV protocol, then it will return the first FV that contains the ACPI table
> +  storage file.
> +
> +  @param[in] Protocol           The protocol to find.
> +  @param[in] Instance           Return pointer to the first instance of the
> protocol.
> +  @param[in] Type               TRUE if the desired protocol is a FV protocol.
> +
> +  @retval EFI_SUCCESS           The function completed successfully.
> +  @retval EFI_NOT_FOUND         The protocol could not be located.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to find
> the protocol.
> +**/
> +EFI_STATUS
> +LocateSupportProtocol (
> +  IN     EFI_GUID                      *Protocol,
> +  IN     EFI_GUID                      *gEfiAcpiMultiTableStorageGuid,
> +     OUT VOID                          **Instance,
> +  IN     BOOLEAN                       Type
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_HANDLE              *HandleBuffer;
> +  UINTN                   NumberOfHandles;
> +  EFI_FV_FILETYPE         FileType;
> +  UINT32                  FvStatus;
> +  EFI_FV_FILE_ATTRIBUTES  Attributes;
> +  UINTN                   Size;
> +  UINTN                   Index;
> +
> +  //
> +  // Locate protocol.
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  Protocol,
> +                  NULL,
> +                  &NumberOfHandles,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Defined errors at this time are not found and out of resources.
> +    //
> +    return Status;
> +  }
> +
> +  //
> +  // Looking 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],
> +                    Protocol,
> +                    Instance
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    if (!Type) {
> +
> +      //
> +      // Not looking for the FV protocol, so find the first instance of the
> +      // protocol.  There should not be any errors because our handle buffer
> +      // should always contain at least one or LocateHandleBuffer would have
> +      // returned not found.
> +      //
> +      break;
> +    }
> +    //
> +    // See if it has the ACPI storage file
> +    //
> +    Size      = 0;
> +    FvStatus  = 0;
> +    Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile
> (
> +                                                              *Instance,
> +
> gEfiAcpiMultiTableStorageGuid,
> +                                                              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);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +PublishAcpiTablesFromFv (
> +  IN EFI_GUID *gEfiAcpiMultiTableStorageGuid
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> +  EFI_ACPI_COMMON_HEADER        *CurrentTable;
> +  UINT32                        FvStatus;
> +  UINTN                         Size;
> +  UINTN                         TableHandle;
> +  INTN                          Instance;
> +  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
> +
> +  Instance      = 0;
> +  TableHandle   = 0;
> +  CurrentTable  = NULL;
> +  FwVol         = NULL;
> +
> +  //
> +  // Find the AcpiSupport protocol
> +  //
> +  Status = LocateSupportProtocol (
> +            &gEfiAcpiTableProtocolGuid,
> +            gEfiAcpiMultiTableStorageGuid,
> +            (VOID **) &AcpiTable,
> +            FALSE
> +            );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Locate the firmware volume protocol
> +  //
> +  Status = LocateSupportProtocol (
> +            &gEfiFirmwareVolume2ProtocolGuid,
> +            gEfiAcpiMultiTableStorageGuid,
> +            (VOID **) &FwVol,
> +            TRUE
> +            );
> +
> +  //
> +  // Read tables from the storage file.
> +  //
> +
> +  while (Status == EFI_SUCCESS) {
> +    Status = FwVol->ReadSection (
> +                      FwVol,
> +                      gEfiAcpiMultiTableStorageGuid,
> +                      EFI_SECTION_RAW,
> +                      Instance,
> +                      (VOID **) &CurrentTable,
> +                      &Size,
> +                      &FvStatus
> +                      );
> +
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Add the table
> +      //
> +      TableHandle = 0;
> +
> +      Status = AcpiTable->InstallAcpiTable (
> +                            AcpiTable,
> +                            CurrentTable,
> +                            CurrentTable->Length,
> +                            &TableHandle
> +                            );
> +
> +
> +      ASSERT_EFI_ERROR (Status);
> +
> +      //
> +      // Increment the instance
> +      //
> +      Instance++;
> +      CurrentTable = NULL;
> +    }
> +  }
> +
> +  //
> +  // Finished
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  ACPI Platform driver installation function.
> +
> +  @param[in] ImageHandle     Handle for this drivers loaded image protocol.
> +  @param[in] SystemTable     EFI system table.
> +
> +  @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
> +EFIAPI
> +InstallAcpiBoard (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS   Status;
> +  EFI_HANDLE   Handle;
> +
> +  AcpiGnvsInit((VOID **) &mGlobalNvsArea.Area);
> +
> +  //
> +  // This PCD set must be done before PublishAcpiTablesFromFv.
> +  // The PCD data will be used there.
> +  //
> +  PcdSet64S (PcdAcpiGnvsAddress, (UINT64)(UINTN)mGlobalNvsArea.Area);
> +
> +  //
> +  // Platform ACPI Tables
> +  //
> +  PublishAcpiTablesFromFv (&gEfiCallerIdGuid);
> +
> +  //
> +  // This protocol publish must be done after PublishAcpiTablesFromFv.
> +  // The NVS data is be updated there.
> +  //
> +  Handle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gEfiGlobalNvsAreaProtocolGuid,
> +                  &mGlobalNvsArea,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.c
> new file mode 100644
> index 0000000000..2b36475c53
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.c
> @@ -0,0 +1,353 @@
> +/** @file
> +  Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
> +  Devics resource configuration.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +#include "PciHotPlug.h"
> +#include <Ppi/SiPolicy.h>
> +#include <TbtBoardInfo.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/TbtCommonLib.h>
> +
> +#define PCIE_NUM  (20)
> +#define PEG_NUM   (3)
> +#define PADDING_BUS (1)
> +#define PADDING_NONPREFETCH_MEM (1)
> +#define PADDING_PREFETCH_MEM (1)
> +#define PADDING_IO (1)
> +#define PADDING_NUM (PADDING_BUS + PADDING_NONPREFETCH_MEM +
> PADDING_PREFETCH_MEM + PADDING_IO)
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_HPC_LOCATION
> mPcieLocation[PCIE_NUM + PEG_NUM];
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mHpcCount = 0;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PCIE_HOT_PLUG_DEVICE_PATH
> mHotplugPcieDevicePathTemplate = {
> +  ACPI,
> +  PCI(0xFF, 0xFF), // Dummy Device no & Function no
> +  END
> +};
> +
> +/**
> +  Entry point for the driver.
> +
> +  This routine reads the PlatformType GPI on FWH and produces a protocol
> +  to be consumed by the chipset driver to effect those settings.
> +
> +  @param[in]  ImageHandle    An image handle.
> +  @param[in]  SystemTable    A pointer to the system table.
> +
> +  @retval     EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciHotPlug (
> +  IN EFI_HANDLE                   ImageHandle,
> +  IN EFI_SYSTEM_TABLE             *SystemTable
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  PCI_HOT_PLUG_INSTANCE            *PciHotPlug;
> +  UINTN                            Index;
> +  UINTN                            RpDev;
> +  UINTN                            RpFunc;
> +  PCIE_HOT_PLUG_DEVICE_PATH       *HotplugPcieDevicePath;
> +  UINT32                           PcieRootPortHpeData = 0;
> +
> +  DEBUG ((DEBUG_INFO, "PciHotPlug Entry\n"));
> +
> +  PcieRootPortHpeData = PcdGet32 (PcdPchPcieRootPortHpe);
> +  //
> +  // PCH Rootports Hotplug device path creation
> +  //
> +  for (Index = 0; Index < PCIE_NUM; Index++) {
> +    if (((PcieRootPortHpeData >> Index) & BIT0) == BIT0) { // Check the
> Rootport no's hotplug is set
> +      Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFunc); // Get the
> actual device/function no corresponding to the Rootport no provided
> +      ASSERT_EFI_ERROR (Status);
> +
> +      HotplugPcieDevicePath = NULL;
> +      HotplugPcieDevicePath = AllocatePool (sizeof
> (PCIE_HOT_PLUG_DEVICE_PATH));
> +      ASSERT (HotplugPcieDevicePath != NULL);
> +      if (HotplugPcieDevicePath == NULL) {
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +      CopyMem (HotplugPcieDevicePath, &mHotplugPcieDevicePathTemplate,
> sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
> +      HotplugPcieDevicePath->PciRootPortNode.Device = (UINT8) RpDev; //
> Update real Device no
> +      HotplugPcieDevicePath->PciRootPortNode.Function = (UINT8) RpFunc;
> // Update real Function no
> +
> +      mPcieLocation[mHpcCount].HpcDevicePath =
> (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
> +      mPcieLocation[mHpcCount].HpbDevicePath =
> (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
> +      mHpcCount++;
> +
> +      DEBUG ((DEBUG_INFO, "(%02d) PciHotPlug (PCH RP#) : Bus 0x00, Device
> 0x%x, Function 0x%x is added to the Hotplug Device Path list \n", mHpcCount,
> RpDev, RpFunc));
> +    }
> +  }
> +
> +
> +  PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE));
> +  ASSERT (PciHotPlug != NULL);
> +  if (PciHotPlug == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Initialize driver private data.
> +  //
> +  ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE));
> +
> +  PciHotPlug->Signature                               =
> PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE;
> +  PciHotPlug->HotPlugInitProtocol.GetRootHpcList      = GetRootHpcList;
> +  PciHotPlug->HotPlugInitProtocol.InitializeRootHpc   = InitializeRootHpc;
> +  PciHotPlug->HotPlugInitProtocol.GetResourcePadding  =
> GetResourcePadding;
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &PciHotPlug->Handle,
> +                  &gEfiPciHotPlugInitProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &PciHotPlug->HotPlugInitProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This procedure returns a list of Root Hot Plug controllers that require
> +  initialization during boot process
> +
> +  @param[in]  This      The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[out] HpcCount  The number of Root HPCs returned.
> +  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number
> of elements in this list.
> +
> +  @retval EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetRootHpcList (
> +  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
> +  OUT UINTN                            *HpcCount,
> +  OUT EFI_HPC_LOCATION                 **HpcList
> +  )
> +{
> +  *HpcCount = mHpcCount;
> +  *HpcList  = mPcieLocation;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This procedure Initializes one Root Hot Plug Controller
> +  This process may casue initialization of its subordinate buses
> +
> +  @param[in]  This            The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[in]  HpcDevicePath   The Device Path to the HPC that is being
> initialized.
> +  @param[in]  HpcPciAddress   The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[in]  Event           The event that should be signaled when the Hot
> Plug Controller initialization is complete. Set to NULL if the caller wants to wait
> until the entire initialization process is complete. The event must be of the
> type EFI_EVT_SIGNAL.
> +  @param[out] HpcState        The state of the Hot Plug Controller hardware.
> The type EFI_Hpc_STATE is defined in section 3.1.
> +
> +  @retval   EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeRootHpc (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL      *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL            *HpcDevicePath,
> +  IN  UINT64                              HpcPciAddress,
> +  IN  EFI_EVENT                           Event, OPTIONAL
> +  OUT EFI_HPC_STATE                       *HpcState
> +  )
> +{
> +  if (Event) {
> +    gBS->SignalEvent (Event);
> +  }
> +
> +  *HpcState = EFI_HPC_STATE_INITIALIZED;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Returns the resource padding required by the PCI bus that is controlled by
> the specified Hot Plug Controller.
> +
> +  @param[in]  This           The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol. initialized.
> +  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
> +  @param[in]  HpcPciAddress  The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[out] HpcState       The state of the Hot Plug Controller hardware.
> The type EFI_HPC_STATE is defined in section 3.1.
> +  @param[out] Padding        This is the amount of resource padding
> required by the PCI bus under the control of the specified Hpc. Since the caller
> does not know the size of this buffer, this buffer is allocated by the callee and
> freed by the caller.
> +  @param[out] Attribute      Describes how padding is accounted for.
> +
> +  @retval     EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetResourcePadding (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *HpcDevicePath,
> +  IN  UINT64                          HpcPciAddress,
> +  OUT EFI_HPC_STATE                   *HpcState,
> +  OUT VOID                            **Padding,
> +  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
> +  )
> +{
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
> +  EFI_STATUS                        Status;
> +  UINT8                             RsvdExtraBusNum = 0;
> +  UINT16                            RsvdPcieMegaMem = 10;
> +  UINT8                             PcieMemAddrRngMax = 0;
> +  UINT16                            RsvdPciePMegaMem = 10;
> +  UINT8                             PciePMemAddrRngMax = 0;
> +  UINT8                             RsvdTbtExtraBusNum = 0;
> +  UINT16                            RsvdTbtPcieMegaMem = 10;
> +  UINT8                             TbtPcieMemAddrRngMax = 0;
> +  UINT16                            RsvdTbtPciePMegaMem = 10;
> +  UINT8                             TbtPciePMemAddrRngMax = 0;
> +  UINT8                             RsvdPcieKiloIo = 4;
> +  BOOLEAN                           SetResourceforTbt = FALSE;
> +  UINTN                             RpIndex;
> +  UINTN                             RpDev;
> +  UINTN                             RpFunc;
> +
> +DEBUG ((DEBUG_INFO, "GetResourcePadding : Start \n"));
> +
> +  PaddingResource = AllocatePool (PADDING_NUM * sizeof
> (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof
> (EFI_ACPI_END_TAG_DESCRIPTOR));
> +  ASSERT (PaddingResource != NULL);
> +  if (PaddingResource == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  *Padding = (VOID *) PaddingResource;
> +
> +  RpDev = (UINTN) ((HpcPciAddress >> 16) & 0xFF);
> +  RpFunc = (UINTN) ((HpcPciAddress >> 8) & 0xFF);
> +
> +  // Get the actual Rootport no corresponding to the device/function no
> provided
> +  if (RpDev == SA_PEG_DEV_NUM) {
> +    // PEG
> +    RpIndex = PCIE_NUM + RpFunc;
> +    DEBUG ((DEBUG_INFO, "GetResourcePadding : PEG Rootport no %02d Bus
> 0x00, Device 0x%x, Function 0x%x \n", (RpIndex-PCIE_NUM), RpDev, RpFunc));
> +  } else {
> +    // PCH
> +    Status = GetPchPcieRpNumber (RpDev, RpFunc, &RpIndex);
> +    DEBUG ((DEBUG_INFO, "GetResourcePadding : PCH Rootport no %02d Bus
> 0x00, Device 0x%x, Function 0x%x \n", RpIndex, RpDev, RpFunc));
> +  }
> +
> +  GetRootporttoSetResourcesforTbt(RpIndex, &RsvdTbtExtraBusNum,
> &RsvdTbtPcieMegaMem ,&TbtPcieMemAddrRngMax ,&RsvdTbtPciePMegaM
> em ,&TbtPciePMemAddrRngMax, &SetResourceforTbt);
> +    if (SetResourceforTbt) {
> +      RsvdExtraBusNum = RsvdTbtExtraBusNum;
> +      RsvdPcieMegaMem = RsvdTbtPcieMegaMem;
> +      PcieMemAddrRngMax = TbtPcieMemAddrRngMax;
> +      RsvdPciePMegaMem = RsvdTbtPciePMegaMem;
> +      PciePMemAddrRngMax = TbtPciePMemAddrRngMax;
> +    }
> +
> +  //
> +  // Padding for bus
> +  //
> +  ZeroMem (PaddingResource, PADDING_NUM * sizeof
> (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof
> (EFI_ACPI_END_TAG_DESCRIPTOR));
> +  *Attributes                   = EfiPaddingPciBus;
> +
> +  PaddingResource->Desc         = 0x8A;
> +  PaddingResource->Len          = 0x2B;
> +  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_BUS;
> +  PaddingResource->GenFlag      = 0x0;
> +  PaddingResource->SpecificFlag = 0;
> +  PaddingResource->AddrRangeMin = 0;
> +  PaddingResource->AddrRangeMax = 0;
> +  PaddingResource->AddrLen      = RsvdExtraBusNum;
> +
> +  //
> +  // Padding for non-prefetchable memory
> +  //
> +  PaddingResource++;
> +  PaddingResource->Desc                 = 0x8A;
> +  PaddingResource->Len                  = 0x2B;
> +  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +  PaddingResource->GenFlag              = 0x0;
> +    if (SetResourceforTbt) {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  } else {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  }
> +  PaddingResource->SpecificFlag         = 0;
> +  //
> +  // Pad non-prefetchable
> +  //
> +  PaddingResource->AddrRangeMin = 0;
> +  PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
> +  if (SetResourceforTbt) {
> +    PaddingResource->AddrRangeMax = (1 << PcieMemAddrRngMax) - 1;
> +  } else {
> +    PaddingResource->AddrRangeMax = 1;
> +  }
> +
> +  //
> +  // Padding for prefetchable memory
> +  //
> +  PaddingResource++;
> +  PaddingResource->Desc                 = 0x8A;
> +  PaddingResource->Len                  = 0x2B;
> +  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +  PaddingResource->GenFlag              = 0x0;
> +    if (SetResourceforTbt) {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  } else {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  }
> +  PaddingResource->SpecificFlag         = 06;
> +  //
> +  // Padding for prefetchable memory
> +  //
> +  PaddingResource->AddrRangeMin = 0;
> +  if (SetResourceforTbt) {
> +    PaddingResource->AddrLen      = RsvdPciePMegaMem * 0x100000;
> +  } else {
> +    PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
> +  }
> +  //
> +  // Pad 16 MB of MEM
> +  //
> +  if (SetResourceforTbt) {
> +    PaddingResource->AddrRangeMax = (1 << PciePMemAddrRngMax) - 1;
> +  } else {
> +    PaddingResource->AddrRangeMax = 1;
> +  }
> +  //
> +  // Alignment
> +  //
> +  // Padding for I/O
> +  //
> +  PaddingResource++;
> +  PaddingResource->Desc         = 0x8A;
> +  PaddingResource->Len          = 0x2B;
> +  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_IO;
> +  PaddingResource->GenFlag      = 0x0;
> +  PaddingResource->SpecificFlag = 0;
> +  PaddingResource->AddrRangeMin = 0;
> +  PaddingResource->AddrLen      = RsvdPcieKiloIo * 0x400;
> +  //
> +  // Pad 4K of IO
> +  //
> +  PaddingResource->AddrRangeMax = 1;
> +  //
> +  // Alignment
> +  //
> +  // Terminate the entries.
> +  //
> +  PaddingResource++;
> +  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc     =
> ACPI_END_TAG_DESCRIPTOR;
> +  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0;
> +
> +  *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.c
> new file mode 100644
> index 0000000000..c670f23320
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.c
> @@ -0,0 +1,228 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/TbtCommonLib.h>
> +#include <Library/DxeTbtPolicyLib.h>
> +#include <TbtBoardInfo.h>
> +#include <Protocol/DxeTbtPolicy.h>
> +#include <Protocol/TbtNvsArea.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/PcdLib.h>
> +#include <Library/AslUpdateLib.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL
> mTbtNvsAreaProtocol;
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB
> *gTbtInfoHob = NULL;
> +
> +/**
> +  TBT NVS Area Initialize
> +
> +**/
> +
> +VOID
> +TbtNvsAreaInit (
> +  IN  VOID              **mTbtNvsAreaPtr
> +  )
> +{
> +  UINTN                         Pages;
> +  EFI_PHYSICAL_ADDRESS          Address;
> +  EFI_STATUS                    Status;
> +  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
> +  DXE_TBT_POLICY_PROTOCOL       *DxeTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit Start\n"));
> +  Status = gBS->LocateProtocol (
> +              &gDxeTbtPolicyProtocolGuid,
> +              NULL,
> +              (VOID **) &DxeTbtConfig
> +              );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Pages = EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA));
> +  Address = 0xffffffff; // allocate address below 4G.
> +
> +  Status  = gBS->AllocatePages (
> +                   AllocateMaxAddress,
> +                   EfiACPIMemoryNVS,
> +                   Pages,
> +                   &Address
> +                   );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  *mTbtNvsAreaPtr = (VOID *) (UINTN) Address;
> +  SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0);
> +
> +  //
> +  // TBTNvsAreaProtocol default value init here
> +  //
> +  TbtNvsAreaProtocol = (TBT_NVS_AREA_PROTOCOL *) &Address;
> +
> +  //
> +  // Initialize default values
> +  //
> +  TbtNvsAreaProtocol->Area->WAKFinished             = 0;
> +  TbtNvsAreaProtocol->Area->DiscreteTbtSupport      = ((gTbtInfoHob->
> DTbtControllerConfig.DTbtControllerEn == 1 ) ? TRUE : FALSE);
> +  TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport   = 0;
> +  TbtNvsAreaProtocol->Area->TbtGpioFilter           = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Gpio5Filter;
> +//  TbtNvsAreaProtocol->Area->TrOsup                  = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TrA0OsupWa;
> +  TbtNvsAreaProtocol->Area->TbtFrcPwrEn             =
> gTbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr;
> +  TbtNvsAreaProtocol->Area->TbtAspm                 = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtAspm;
> +//  TbtNvsAreaProtocol->Area->TbtL1SubStates          = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtL1SubStates;
> +  TbtNvsAreaProtocol->Area->TbtSetClkReq            = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtSetClkReq;
> +  TbtNvsAreaProtocol->Area->TbtLtr                  = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtLtr;
> +//  TbtNvsAreaProtocol->Area->TbtPtm                  = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtPtm;
> +  TbtNvsAreaProtocol->Area->TbtWakeupSupport        = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport;
> +  TbtNvsAreaProtocol->Area->TbtAcDcSwitch           = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch;
> +  TbtNvsAreaProtocol->Area->Rtd3TbtSupport          = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Rtd3Tbt;             // TBT RTD3 Enable.
> +  TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay         = (UINT16)
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay;    // TBT RTD3 Off delay
> in ms.
> +  TbtNvsAreaProtocol->Area->Rtd3TbtClkReq           = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq;       // TBT RTD3 ClkReq
> Mask Enable.
> +  TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay      = (UINT16)
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq
> mask delay in ms.
> +  TbtNvsAreaProtocol->Area->TbtWin10Support         = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode
> +
> +  //
> +  // DTBT Controller 1
> +  //
> +  TbtNvsAreaProtocol->Area->DTbtControllerEn0       = gTbtInfoHob->
> DTbtControllerConfig.DTbtControllerEn;
> +  TbtNvsAreaProtocol->Area->RootportSelected0       = gTbtInfoHob->
> DTbtControllerConfig.PcieRpNumber;
> +  TbtNvsAreaProtocol->Area->RootportSelected0Type   = gTbtInfoHob->
> DTbtControllerConfig.Type;
> +  TbtNvsAreaProtocol->Area->RootportEnabled0        = gTbtInfoHob->
> DTbtControllerConfig.DTbtControllerEn;
> +  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0        = gTbtInfoHob->
> DTbtControllerConfig.ForcePwrGpio.GpioPad;
> +  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0     = gTbtInfoHob->
> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
> +  TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0  = gTbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
> +  TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0       = gTbtInfoHob->
> DTbtControllerConfig.PcieRstGpio.GpioPad;
> +  TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0    = gTbtInfoHob->
> DTbtControllerConfig.PcieRstGpio.GpioLevel;
> +
> +  TbtNvsAreaProtocol->Area->TBtCommonGpioSupport    =
> gTbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration;
> +
> +  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit End\n"));
> +}
> +
> +/**
> +  This function gets registered as a callback to patch TBT ASL code
> +
> +  @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.
> +  can we put this also in read me
> +**/
> +VOID
> +EFIAPI
> +TbtAcpiEndOfDxeCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  UINT32                                Address;
> +  UINT16                                Length;
> +  UINT32                                Signature;
> +
> +  Status = InitializeAslUpdateLib ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Address = (UINT32) (UINTN) mTbtNvsAreaProtocol.Area;
> +  Length  = (UINT16) sizeof (TBT_NVS_AREA);
> +  DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x
> Length %x\n", Address, Length));
> +  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address,
> sizeof (Address));
> +  ASSERT_EFI_ERROR (Status);
> +  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length,
> sizeof (Length));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (gTbtInfoHob != NULL) {
> +    if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1) {
> +      if (gTbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting == TRUE) {
> +        DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n"));
> +        Signature = gTbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
> +        Status  = UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'),
> &Signature, sizeof (Signature));
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +    }
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  Initialize Thunderbolt(TM) SSDT ACPI tables
> +
> +  @retval EFI_SUCCESS    ACPI tables are initialized successfully
> +  @retval EFI_NOT_FOUND  ACPI tables not found
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +TbtDxeEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_HANDLE              Handle;
> + // EFI_EVENT               EndOfDxeEvent;
> +
> +  DEBUG ((DEBUG_INFO, "TbtDxeEntryPoint \n"));
> +
> +  //
> +  // Get TBT INFO HOB
> +  //
> +  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +  if (gTbtInfoHob == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +  InstallTbtPolicy (ImageHandle);
> +  //
> +  // Update DXE TBT Policy
> +  //
> +  UpdateTbtPolicyCallback ();
> +
> +  //
> +  // Print DXE TBT Policy
> +  //
> +  TbtPrintDxePolicyConfig ();
> +
> +  //
> +  // Initialize Tbt Nvs Area
> +  //
> +  TbtNvsAreaInit ((VOID **) &mTbtNvsAreaProtocol.Area);
> +
> +
> +  //
> +  // [ACPI] Thunderbolt ACPI table
> +  //
> +
> +
> +  Handle = NULL;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gTbtNvsAreaProtocolGuid,
> +                  &mTbtNvsAreaProtocol,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Register an end of DXE event for TBT ACPI to do some patch can be put as
> description
> +  //
> +  /**
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  TbtAcpiEndOfDxeCallback,
> +                  NULL,
> +                  &gEfiEndOfDxeEventGroupGuid,
> +                  &EndOfDxeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +**/
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.c
> new file mode 100644
> index 0000000000..bdd8de0cfd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.c
> @@ -0,0 +1,211 @@
> +/** @file
> +  Source code file for TBT Init PEI module
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PeiTbtPolicyLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Ppi/PeiTbtPolicy.h>
> +#include <Ppi/EndOfPeiPhase.h>
> +#include <TbtBoardInfo.h>
> +#include <Private/Library/PeiDTbtInitLib.h>
> +/*
> +/**
> +  This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDone
> +
> +  @param[in]  PeiServices  Pointer to PEI Services Table.
> +  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification
> event that
> +                           caused this function to execute.
> +  @param[in]  Ppi          Pointer to the PPI data associated with this
> function.
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +
> +
> +/**
> +  This function pass PEI TBT Policy to Hob at the end of PEI
> +
> +  @param[in]  PeiServices  Pointer to PEI Services Table.
> +  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification
> event that
> +                           caused this function to execute.
> +  @param[in]  Ppi          Pointer to the PPI data associated with this
> function.
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +
> +
> +EFI_STATUS
> +EFIAPI
> +PassTbtPolicyToHob (
> +VOID
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_BOOT_MODE         BootMode;
> +  TBT_INFO_HOB          *TbtInfoHob;
> +  PEI_TBT_POLICY        *PeiTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "PassTbtPolicyToHob\n"));
> +
> +  Status = PeiServicesGetBootMode (&BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +  if (BootMode == BOOT_ON_S3_RESUME ) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Create HOB for TBT Data
> +  //
> +  Status = PeiServicesCreateHob (
> +             EFI_HOB_TYPE_GUID_EXTENSION,
> +             sizeof (TBT_INFO_HOB),
> +             (VOID **) &TbtInfoHob
> +             );
> +  DEBUG ((DEBUG_INFO, "TbtInfoHob Created \n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize the TBT INFO HOB data.
> +  //
> +  TbtInfoHob->EfiHobGuidType.Name = gTbtInfoHobGuid;
> +
> +  //
> +  // Update DTBT Policy
> +  //
> +  TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn = PeiTbtConfig->
> DTbtControllerConfig.DTbtControllerEn;
> +  TbtInfoHob-> DTbtControllerConfig.Type = PeiTbtConfig->
> DTbtControllerConfig.Type;
> +  TbtInfoHob-> DTbtControllerConfig.PcieRpNumber = PeiTbtConfig->
> DTbtControllerConfig.PcieRpNumber;
> +  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad =
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
> +  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel =
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
> +  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad =
> PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
> +  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature =
> PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
> +  TbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting =
> PeiTbtConfig->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting;
> +  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad = PeiTbtConfig->
> DTbtControllerConfig.PcieRstGpio.GpioPad;
> +  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel =
> PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
> +
> +  TbtInfoHob->DTbtCommonConfig.TbtBootOn =
> PeiTbtConfig->DTbtCommonConfig.TbtBootOn;
> +  TbtInfoHob->DTbtCommonConfig.TbtUsbOn =
> PeiTbtConfig->DTbtCommonConfig.TbtUsbOn;
> +  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr =
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr;
> +  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly =
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly;
> +  TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration =
> PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration;
> +  TbtInfoHob->DTbtCommonConfig.PcieRstSupport =
> PeiTbtConfig->DTbtCommonConfig.PcieRstSupport;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function handles TbtInit task at the end of PEI
> +
> +  @param[in]  PeiServices  Pointer to PEI Services Table.
> +  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification
> event that
> +                           caused this function to execute.
> +  @param[in]  Ppi          Pointer to the PPI data associated with this
> function.
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +TbtInitEndOfPei (
> +  VOID
> +  )
> +{
> +  EFI_STATUS      Status;
> +  BOOLEAN         DTbtExisted;
> +  PEI_TBT_POLICY  *PeiTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "TbtInitEndOfPei Entry\n"));
> +
> +  Status       = EFI_SUCCESS;
> +  PeiTbtConfig = NULL;
> +  DTbtExisted  = FALSE;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +    if (PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn == 1) {
> +      DTbtExisted = TRUE;
> +  }
> +
> +  if (DTbtExisted == TRUE) {
> +    //
> +    // Call Init function
> +    //
> +   Status = TbtInit ();
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  TBT Init PEI module entry point
> +
> +  @param[in]  FileHandle           Not used.
> +  @param[in]  PeiServices          General purpose services available to every
> PEIM.
> +
> +  @retval     EFI_SUCCESS          The function completes successfully
> +  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create
> database
> +**/
> +EFI_STATUS
> +EFIAPI
> +TbtInitEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS     Status;
> +
> +  DEBUG ((DEBUG_INFO, "TBT PEI EntryPoint\n"));
> +
> +  //
> +  // Install PEI TBT Policy
> +  //
> +  Status = InstallPeiTbtPolicy ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  UpdatePeiTbtPolicy ();
> +
> +  TbtPrintPeiPolicyConfig ();
> +  //
> +  // Performing PassTbtPolicyToHob and TbtInitEndOfPei
> +  //
> +  Status = PassTbtPolicyToHob ();
> +
> +  Status = TbtInitEndOfPei ();
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.c
> new file mode 100644
> index 0000000000..a6bdc6ef9f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.c
> @@ -0,0 +1,1609 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "TbtSmiHandler.h"
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Protocol/SmmVariable.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Library/PciSegmentLib.h>
> +#define MEM_PER_SLOT  (DEF_RES_MEM_PER_DEV << 4)
> +#define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
> +#define IO_PER_SLOT   (DEF_RES_IO_PER_DEV << 2)
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> gDeviceBaseAddress;
> +//
> +//US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG
> HrConfigs[MAX_CFG_PORTS];
> +
> +extern UINT8                      gCurrentDiscreteTbtRootPort;
> +extern UINT8                      gCurrentDiscreteTbtRootPortType;
> +
> +BOOLEAN isLegacyDevice          = FALSE;
> +STATIC UINT8 TbtSegment         = 0;
> +
> +STATIC
> +VOID
> +PortInfoInit (
> +  IN  OUT PORT_INFO *PortInfo
> +  )
> +{
> +  PortInfo->BusNumLimit = 4;
> +}
> +
> +STATIC
> +VOID
> +UnsetVesc (
> +  IN       UINT8     Bus,
> +  IN       UINT8     Dev,
> +  IN       UINT8     Fun
> +  )
> +{
> +  UINT8 Dbus;
> +  UINT32 Data32;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +
> +  //
> +  // Check for abcence of DS bridge
> +  //
> +  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +    return;
> +  }
> +
> +  //
> +  // Unset vesc_reg2[23] bit (to have an option to access below DS)
> +  //
> +  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
> +  Data32 &= 0xFF7FFFFF;
> +  PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
> +  //
> +  // Go to Device behind DS
> +  //
> +  Dbus = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
> +  //
> +  // Check if there is something behind this Downstream Port (Up or Ep)
> +  // If there nothing  behind Downstream Port Set vesc_reg2[23] bit -> this
> will flush all future MemWr
> +  //
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus,
> 0x00, 0x00, 0);
> +  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET))
> +  {
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
> +  Data32 |= 0x00800000;
> +  PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
> +  }
> +}// Unset_VESC_REG2
> +
> +STATIC
> +UINT16
> +MemPerSlot (
> +  IN    UINT16 CurrentUsage
> +  )
> +{
> +  if (CurrentUsage == 0) {
> +    return 0;
> +  }
> +
> +  if (CurrentUsage <= 16) {
> +    return 16;
> +  }
> +
> +  if (CurrentUsage <= 64) {
> +    return 64;
> +  }
> +
> +  if (CurrentUsage <= 128) {
> +    return 128;
> +  }
> +
> +  if (CurrentUsage <= 256) {
> +    return 256;
> +  }
> +
> +  if (CurrentUsage <= 512) {
> +    return 512;
> +  }
> +
> +  if (CurrentUsage <= 1024) {
> +    return 1024;
> +  }
> +
> +  return CurrentUsage;
> +} // MemPerSlot
> +
> +STATIC
> +UINT64
> +PMemPerSlot (
> +  IN    UINT64 CurrentUsage
> +  )
> +{
> +  if (CurrentUsage == 0) {
> +    return 0;
> +  }
> +
> +  if (CurrentUsage <= 1024ULL) {
> +    return 1024ULL;
> +  }
> +
> +  if (CurrentUsage <= 4096ULL) {
> +    return 4096ULL;
> +  }
> +
> +  return CurrentUsage;
> +} // PMemPerSlot
> +
> +STATIC
> +VOID
> +SetPhyPortResources (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      SubBus,
> +  IN       INT8       Depth,
> +  IN       PORT_INFO  *CurrentPi,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8   Cmd;
> +  UINT16  DeltaMem;
> +  UINT64  DeltaPMem;
> +
> +  Cmd               = CMD_BUS_MASTER;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> 0x00, 0);
> +
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +
> +  DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
> +  if (isLegacyDevice) {
> +    if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
> +      PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
> +    }
> +  } else {
> +    if (DeltaMem < MemPerSlot (DeltaMem)) {
> +      PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
> +    }
> +  }
> +
> +  if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase -
> 0x10) <= PortInfo->MemLimit) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), CurrentPi->MemBase);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), DISBL_MEM32_REG20);
> +    PortInfo->MemBase = CurrentPi->MemBase;
> +  }
> +
> +  DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
> +  if (isLegacyDevice) {
> +    if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
> +      PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
> +    }
> +  } else {
> +    if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
> +      PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
> +    }
> +  }
> +
> +  if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 &&
> (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 &
> 0xFFFF));
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10)
> & 0xFFFF));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10)
> >> 16));
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), 0);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), 0);
> +    PortInfo->PMemBase64 = CurrentPi->PMemBase64;
> +  }
> +
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +} // SetPhyPortResources
> +
> +STATIC
> +UINT32
> +SaveSetGetRestoreBar (
> +  IN  UINTN  Bar
> +  )
> +{
> +  UINT32  BarReq;
> +  UINT32  OrigBar;
> +
> +  OrigBar = PciSegmentRead32(Bar);     // Save BAR
> +  PciSegmentWrite32(Bar, 0xFFFFFFFF);  // Set BAR
> +  BarReq = PciSegmentRead32(Bar);      // Get BAR
> +  PciSegmentWrite32(Bar, OrigBar);     // Restore BAR
> +
> +  return BarReq;
> +} // SaveSetGetRestoreBar
> +
> +STATIC
> +VOID
> +SetIoBar (
> +  IN            UINTN    BAR,
> +  IN            UINT32   BarReq,
> +  IN  OUT       UINT8    *Cmd,
> +  IN  OUT       IO_REGS  *IoReg
> +  )
> +{
> +  UINT16  Alignment;
> +  UINT16  Size;
> +  UINT16  NewBase;
> +
> +  Alignment = ~(BarReq & 0xFFFC);
> +  Size      = Alignment + 1;
> +
> +  if (IoReg->Base > IoReg->Limit || !Size) {
> +    return ;
> +
> +  }
> +
> +  NewBase = BAR_ALIGN (IoReg->Base, Alignment);
> +  if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
> +    return ;
> +
> +  }
> +  PciSegmentWrite16(BAR, NewBase);
> +  IoReg->Base = NewBase + Size; // Advance to new position
> +  *Cmd      |= CMD_BM_IO; // Set Io Space Enable
> +} // SetIoBar
> +
> +STATIC
> +VOID
> +SetMemBar (
> +  IN            UINTN     BAR,
> +  IN            UINT32    BarReq,
> +  IN  OUT       UINT8     *Cmd,
> +  IN  OUT       MEM_REGS  *MemReg
> +  )
> +{
> +  UINT32  Alignment;
> +  UINT32  Size;
> +  UINT32  NewBase;
> +
> +  Alignment = ~(BarReq & 0xFFFFFFF0);
> +  Size      = Alignment + 1;
> +
> +  if (MemReg->Base > MemReg->Limit || !Size) {
> +    return ;
> +
> +  }
> +
> +  NewBase = BAR_ALIGN (MemReg->Base, Alignment);
> +  if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
> +    return ;
> +
> +  }
> +
> +  PciSegmentWrite32(BAR, NewBase);
> +  MemReg->Base = NewBase + Size; // Advance to new position
> +  *Cmd       |= CMD_BM_MEM; // Set Memory Space Enable
> +} // SetMemBar
> +
> +STATIC
> +VOID
> +SetPMem64Bar (
> +  IN              UINTN      BAR,
> +  IN              BOOLEAN    IsMaxBar,
> +  IN              UINT32     BarReq,
> +  IN    OUT       UINT8      *Cmd,
> +  IN    OUT       PMEM_REGS  *MemReg
> +  )
> +{
> +  UINT32  Alignment;
> +  UINT32  Size;
> +  UINT64  NewBase;
> +
> +  Alignment = ~(BarReq & 0xFFFFFFF0);
> +  Size      = Alignment + 1;
> +
> +  if (MemReg->Base64 > MemReg->Limit64 || !Size) {
> +    return ;
> +  }
> +
> +  NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
> +  if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64)
> {
> +    return ;
> +  }
> +  PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
> +  if (!IsMaxBar) {
> +    BAR++;
> +    PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
> +  }
> +  MemReg->Base64 = NewBase + Size; // Advance to new position
> +  *Cmd         |= CMD_BM_MEM; // Set Memory Space Enable
> +} // SetPMem64Bar
> +
> +STATIC
> +VOID
> +SetDevResources (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      MaxFun,  // PCI_MAX_FUNC for devices, 1 for bridge
> +  IN       UINT8      MaxBar,     // PCI_BAR5 for devices, PCI_BAR1 for bridge
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8     Fun;
> +  UINT8     Reg;
> +  UINT32    BarReq;
> +  IO_REGS   Io;
> +  MEM_REGS  Mem;
> +  PMEM_REGS PMem;
> +  UINT8     Cmd;
> +
> +  Io.Base       = PortInfo->IoBase << 8;
> +  Io.Limit      = (PortInfo->IoLimit << 8) | 0xFF;
> +  Mem.Base      = PortInfo->MemBase << 16;
> +  Mem.Limit     = (PortInfo->MemLimit << 16) | 0xFFFF;
> +  PMem.Base64   = PortInfo->PMemBase64 << 16;
> +  PMem.Limit64  = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
> +
> +  for (Fun = 0; Fun < MaxFun; ++Fun) {
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BUS_MASTER);
> +    Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
> +    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +      continue;
> +
> +    }
> +
> +    for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
> +      BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform
> BAR sizing
> +
> +      if (BarReq & BIT0) {
> +        //
> +        // I/O BAR
> +        //
> +        SetIoBar (
> +         (gDeviceBaseAddress + Reg),
> +          BarReq,
> +          &Cmd,
> +          &Io
> +          );
> +        continue;
> +      }
> +
> +      if (BarReq & BIT3) {
> +        //
> +        // P-Memory BAR
> +        //
> +        SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq,
> &Cmd, &PMem);
> +      } else {
> +        SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
> +      }
> +
> +      if (BIT2 == (BarReq & (BIT2 | BIT1))) {
> +        //
> +        // Base address is 64 bits wide
> +        //
> +        Reg += 4;
> +        if (!(BarReq & BIT3)) {
> +          //
> +          // 64-bit memory bar
> +          //
> +          PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
> +        }
> +      }
> +    }
> +
> +    if (Cmd & BIT1) {
> +      //
> +      // If device uses I/O and MEM mapping use only MEM mepping
> +      //
> +      Cmd &= ~BIT0;
> +    }
> +
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +  }
> +  //
> +  // Update PortInfo if any changes
> +  //
> +  if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
> +    PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
> +  }
> +
> +  if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
> +    PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
> +  }
> +
> +  if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
> +    PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
> +  }
> +} // SetDevResources
> +
> +STATIC
> +VOID
> +InitARHRConfigs(
> +  IN HR_CONFIG *Hr_Config,
> +  IN UINT8 BusNumLimit,
> +  IN OUT BRDG_RES_CONFIG* HrResConf
> +)
> +{
> +  UINT8 i,j;
> +
> +  //
> +  // DS port for USB device
> +  //
> +  HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus +
> 1;
> +  HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
> +  HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
> +  HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
> +  HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
> +  HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
> +  //
> +  // CIO port
> +  //
> +  HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus +
> 1;
> +  HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
> +  HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
> +  HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
> +  HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
> +  HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
> +
> +  switch(Hr_Config->DeviceId)
> +  {
> +    //
> +    // HR with 1 DS and 1 USB
> +    //
> +    case AR_HR_2C:
> +    case AR_HR_LP:
> +    case AR_HR_C0_2C:
> +    case TR_HR_2C:
> +      Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
> +      Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
> +      Hr_Config->BridgeLoops = 4;
> +      break;
> +    //
> +    // HR with 2 DS and 1 USB
> +    //
> +    case AR_HR_4C:
> +    case TR_HR_4C:
> +    case AR_HR_C0_4C:
> +      Hr_Config->MinDSNumber = 1;
> +      Hr_Config->MaxDSNumber = 4;
> +      Hr_Config->BridgeLoops = 6;
> +      for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <=
> Hr_Config->MaxDSNumber; ++j, ++i)
> +      {
> +        HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
> +        HrConfigs[j].DevId.Dev = i;
> +        HrConfigs[j].DevId.Fun = 0;
> +        HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
> +        HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
> +      }
> +    break;
> +  }
> +}//InitARHRConfigs
> +
> +
> +STATIC
> +VOID
> +InitCommonHRConfigs (
> +  IN       HR_CONFIG        *Hr_Config,
> +  IN       UINT8            BusNumLimit,
> +  IN  OUT  BRDG_RES_CONFIG  *HrResConf
> +  )
> +{
> +  UINT8 i;
> +
> +  UINT8 j;
> +  for(i = 0; i < count(HrConfigs); ++i) {
> +    HrConfigs[i].IsDSBridge = TRUE;
> +  }
> +  //
> +  // US(HRBus:0:0)
> +  //
> +  HrConfigs[HR_US_PORT].DevId.Bus   = Hr_Config->HRBus;
> +  HrConfigs[HR_US_PORT].DevId.Dev   = 0;
> +  HrConfigs[HR_US_PORT].DevId.Fun   = 0;
> +  HrConfigs[HR_US_PORT].Res         = *HrResConf;
> +  HrConfigs[HR_US_PORT].Res.IoBase  = 0xF1;
> +  HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
> +  HrConfigs[HR_US_PORT].PBus        = HrConfigs[HR_US_PORT].DevId.Bus;
> +  HrConfigs[HR_US_PORT].SBus        = HrConfigs[HR_US_PORT].PBus + 1;
> +  HrConfigs[HR_US_PORT].SubBus      = BusNumLimit;
> +  HrConfigs[HR_US_PORT].IsDSBridge  = FALSE;
> +
> +  //
> +  // HIA resides here
> +  //
> +  HrConfigs[HR_DS_PORT0].DevId.Bus    =
> HrConfigs[HR_US_PORT].DevId.Bus + 1;
> +  HrConfigs[HR_DS_PORT0].DevId.Dev    = 0;
> +  HrConfigs[HR_DS_PORT0].DevId.Fun    = 0;
> +  HrConfigs[HR_DS_PORT0].Res          = NOT_IN_USE_BRIDGE;
> +  HrConfigs[HR_DS_PORT0].Res.MemBase  = HrResConf->MemLimit;
> +  HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
> +  HrResConf->MemLimit                -= 0x10; //This 1 MB chunk will be used by
> HIA
> +  HrConfigs[HR_DS_PORT0].Res.Cmd      = CMD_BM_MEM;
> +  HrConfigs[HR_DS_PORT0].Res.Cls      = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[HR_DS_PORT0].PBus         =
> HrConfigs[HR_DS_PORT0].DevId.Bus;
> +  HrConfigs[HR_DS_PORT0].SBus         = HrConfigs[HR_DS_PORT0].PBus + 1;
> +  HrConfigs[HR_DS_PORT0].SubBus       = HrConfigs[HR_DS_PORT0].PBus +
> 1;
> +
> +  switch (Hr_Config->DeviceId) {
> +  //
> +  // Alpine Ridge
> +  //
> +  case AR_HR_2C:
> +  case AR_HR_C0_2C:
> +  case AR_HR_LP:
> +  case AR_HR_4C:
> +  case AR_HR_C0_4C:
> +  //
> +  // Titan Ridge
> +  //
> +  case TR_HR_2C:
> +  case TR_HR_4C:
> +    InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
> +    break;
> +
> +  default:
> +    //
> +    // DS(HRBus+2:3-6:0)
> +    //
> +    Hr_Config->MinDSNumber  = 3;
> +    Hr_Config->MaxDSNumber  = 6;
> +    Hr_Config->BridgeLoops  = count (HrConfigs);
> +
> +    for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <=
> Hr_Config->MaxDSNumber; ++j, ++i) {
> +      HrConfigs[j].DevId.Bus  = HrConfigs[HR_US_PORT].DevId.Bus + 1;
> +      HrConfigs[j].DevId.Dev  = i;
> +      HrConfigs[j].DevId.Fun  = 0;
> +      HrConfigs[j].PBus       = HrConfigs[j].DevId.Bus;
> +      HrConfigs[j].Res.Cls    = DEF_CACHE_LINE_SIZE;
> +    }
> +  }
> +} // InitCommonHRConfigs
> +
> +STATIC
> +VOID
> +InitHRDSPort_Disable (
> +  IN       UINT8        id,
> +  IN  OUT  BRDG_CONFIG  *BrdgConf
> +  )
> +{
> +  HrConfigs[id].Res     = NOT_IN_USE_BRIDGE;
> +  HrConfigs[id].SBus    = BrdgConf->SBus;
> +  HrConfigs[id].SubBus  = BrdgConf->SBus;
> +
> +  BrdgConf->SBus++;
> +} // InitHRDSPort_Disable
> +
> +//AR only
> +
> +STATIC
> +VOID
> +InitARDSPort_1Port(
> +  IN  OUT  BRDG_CONFIG* BrdgConf
> +)
> +{
> +  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
> +  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
> +  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
> +
> +  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
> +  HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
> +  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
> +  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 =
> BrdgConf->Res.PMemLimit64;
> +  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
> +
> +  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
> +  HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
> +  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
> +}//InitARDSPort_1Port
> +
> +STATIC
> +VOID
> +InitARDSPort_2Port(
> +  IN OUT BRDG_CONFIG* BrdgConf
> +)
> +{
> +  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
> +  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
> +  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
> +
> +  // Busses are split between ports 1 and 4
> +  BusRange /= 2;
> +
> +  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
> +  HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
> +  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
> +  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
> +  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
> +
> +  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
> +  HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
> +  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
> +
> +
> +  HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
> +  HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
> +  HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
> +  HrConfigs[AR_DS_PORT4].Res.PMemLimit64 =
> BrdgConf->Res.PMemLimit64;
> +  HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
> +}//InitARDSPort_2Port
> +
> +
> +STATIC
> +BOOLEAN
> +CheckLimits (
> +  IN    BOOLEAN          Is2PortDev,
> +  IN    BRDG_RES_CONFIG  *HrResConf,
> +  IN    UINT8            BusRange
> +  )
> +{
> +  UINT16  MemBase;
> +  UINT16  MemLimit;
> +  UINT64  PMemBase64;
> +  UINT64  PMemLimit64;
> +
> +  MemBase     = HrResConf->MemBase & 0xFFF0;
> +  MemLimit    = HrResConf->MemLimit & 0xFFF0;
> +  PMemBase64  = HrResConf->PMemBase64 & 0xFFF0;
> +  PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
> +  //
> +  // Check memoty alignment
> +  //
> +  if (MemBase & 0x3FF) {
> +    DEBUG((DEBUG_INFO, "M alig\n"));
> +    return FALSE;
> +  }
> +
> +  if (PMemBase64 & 0xFFF) {
> +    DEBUG((DEBUG_INFO, "PM alig\n"));
> +    return FALSE;
> +  }
> +
> +  if (Is2PortDev) {
> +    //
> +    // Check mem size
> +    //
> +    if (MemLimit + 0x10 - MemBase < 0x2E00) {
> +      DEBUG((DEBUG_INFO, "M size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check P-mem size
> +    //
> +    if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
> +      DEBUG((DEBUG_INFO, "PM size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check bus range
> +    //
> +    if (BusRange < 106) {
> +      DEBUG((DEBUG_INFO, "Bus range\n"));
> +      return FALSE;
> +    }
> +  } else {
> +    //
> +    // Check mem size
> +    //
> +    if (MemLimit + 0x10 - MemBase < 0x1600) {
> +      DEBUG((DEBUG_INFO, "M size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check P-mem size
> +    //
> +    if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
> +      DEBUG((DEBUG_INFO, "PM size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check bus range
> +    //
> +    if (BusRange < 56) {
> +      DEBUG((DEBUG_INFO, "Bus range\n"));
> +      return FALSE;
> +    }
> +  }
> +
> +  return TRUE;
> +} // CheckLimits
> +
> +STATIC
> +BOOLEAN
> +InitHRResConfigs (
> +  IN  OUT HR_CONFIG      *Hr_Config,
> +  IN    UINT8            BusNumLimit,
> +  IN  OUT BRDG_RES_CONFIG*HrResConf
> +  )
> +{
> +  BRDG_CONFIG  BrdgConf = { { 0 } };
> +
> +  InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
> +  BrdgConf.PBus   = Hr_Config->HRBus + 2;// Take into account busses
> +  BrdgConf.SBus   = Hr_Config->HRBus + 3;// for US and DS of HIA
> +  BrdgConf.SubBus = BusNumLimit;
> +  BrdgConf.Res    = *HrResConf;
> +  while (TRUE) {
> +    switch (Hr_Config->DeviceId) {
> +    case AR_HR_4C:
> +    case TR_HR_4C:
> +    case AR_HR_C0_4C:
> +      //
> +      // 2 Port host
> +      //
> +      if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
> +
> +
> +          InitARDSPort_2Port(&BrdgConf);
> +          DEBUG((DEBUG_INFO, "AR2\n"));
> +
> +        return TRUE;
> +      } else {
> +       return FALSE;
> +      }
> +    // AR only
> +  case AR_HR_2C: // 1 port host
> +  case AR_HR_C0_2C:
> +  case AR_HR_LP:
> +  case TR_HR_2C:
> +    DEBUG((DEBUG_INFO, "AR1\n"));
> +    InitARDSPort_1Port(&BrdgConf);
> +    return TRUE;
> +
> +    default:
> +      InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
> +      InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
> +      InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
> +      InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
> +      return FALSE;
> +    }
> +  }
> +} // InitHRResConfigs
> +
> +STATIC
> +BOOLEAN
> +InitializeHostRouter (
> +  OUT  HR_CONFIG  *Hr_Config,
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8           BusNumLimit;
> +  BRDG_RES_CONFIG HrResConf = { 0 };
> +  UINT8           i;
> +  BOOLEAN         Ret;
> +
> +  Ret = TRUE;
> +
> +  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus,
> RpDevice, RpFunction, 0);
> +  Hr_Config->HRBus    = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> Hr_Config->HRBus, 0x00, 0x00, 0);
> +  Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
> +    return FALSE;
> +  }
> +  TbtSegment = (UINT8)RpSegment;
> +
> +  HrResConf.Cmd          = CMD_BM_MEM;
> +  HrResConf.Cls          = DEF_CACHE_LINE_SIZE;
> +  gDeviceBaseAddress      = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus,
> RpDevice, RpFunction, 0);
> +  HrResConf.IoBase       = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
> +  HrResConf.IoLimit      = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
> +  HrResConf.MemBase      = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
> +  HrResConf.MemLimit     = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
> +  HrResConf.PMemBase64   = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
> +  HrResConf.PMemLimit64  = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
> +  HrResConf.PMemBase64  |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32))) << 16;
> +  HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32))) << 16;
> +  BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +
> +  Ret         = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
> +
> +  for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
> +    UINT8 Bus;
> +    UINT8 Dev;
> +    UINT8 Fun;
> +    Bus               = HrConfigs[i].DevId.Bus;
> +    Dev               = HrConfigs[i].DevId.Dev;
> +    Fun               = HrConfigs[i].DevId.Fun;
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> Fun, 0);
> +
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> HrConfigs[i].Res.Cls);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 &
> 0xFFFF));
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 &
> 0xFFFF));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64
> >> 16));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64
> >> 16));
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), HrConfigs[i].Res.IoBase);
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBaseUpper16), 0x00000000);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> HrConfigs[i].Res.Cmd);
> +  }
> +  if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C
> || Hr_Config->DeviceId == AR_HR_LP) {
> +    for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
> +      if(HrConfigs[i].IsDSBridge) {
> +        UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev,
> HrConfigs[i].DevId.Fun);
> +      }
> +    }
> +  }
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS
> (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
> +  PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4),
> HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
> +  PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4),
> (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BM_MEM);
> +  return Ret;
> +} // InitializeHostRouter
> +STATIC
> +UINT8
> +ConfigureSlot (
> +  IN       UINT8      Bus,
> +  IN       UINT8      MAX_DEVICE,
> +  IN       INT8       Depth,
> +  IN       BOOLEAN    ArPcie,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8      Device;
> +  UINT8      SBus;
> +  UINT8      UsedBusNumbers;
> +  UINT8      RetBusNum;
> +  PORT_INFO  CurrentSlot;
> +
> +  RetBusNum = 0;
> +
> +  for (Device = 0; Device < MAX_DEVICE; Device++) {
> +    //
> +    // Continue if device is absent
> +    //
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Device, 0x00, 0);
> +    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +      continue;
> +
> +    }
> +
> +    if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress +
> (PCI_CLASSCODE_OFFSET + 1))) {
> +      SetDevResources (
> +        Bus,
> +        Device,
> +        PCI_MAX_FUNC,
> +        PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
> +        PortInfo
> +        );
> +      continue;
> +    }
> +    //
> +    // Else Bridge
> +    //
> +    CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
> +
> +    ++RetBusNum; // UP Bridge
> +    SBus = Bus + RetBusNum; // DS Bridge
> +
> +    if (SBus + 1 >= PortInfo->BusNumLimit) {
> +      continue;
> +
> +    }
> +
> +    SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET +
> (PCI_BAR_IDX1 * 4), PortInfo);
> +
> +    //
> +    // Init UP Bridge to reach DS Bridge
> +    //
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BM_MEM);
> +
> +  if(ArPcie) {
> +    UnsetVesc(Bus, Device, 0x00);
> +  }
> +
> +  UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE,
> PortInfo);
> +  RetBusNum += UsedBusNumbers;
> +
> +    SetPhyPortResources (
> +      Bus,
> +      Device,
> +      SBus + UsedBusNumbers,
> +      Depth,
> +      &CurrentSlot,
> +      PortInfo
> +      );
> +  }
> +  //
> +  // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
> +  //
> +  return RetBusNum;
> +} // ConfigureSlot
> +
> +STATIC
> +VOID
> +SetCioPortResources (
> +  IN       UINT8     Bus,
> +  IN       UINT8     Dev,
> +  IN       UINT8     SBus,
> +  IN       UINT8     SubBus,
> +  IN       PORT_INFO  *portInfoBeforeChange,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8 Cmd;
> +  Cmd               = CMD_BUS_MASTER;
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> 0x00, 0);
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +
> +  if (PortInfo->IoBase <= PortInfo->IoLimit) {
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), PortInfo->IoBase);
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimit), PortInfo->IoLimit);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBaseUpper16), 0x00000000);
> +    Cmd |= CMD_BM_IO;
> +  } else {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), DISBL_IO_REG1C);
> +  }
> +
> +  if (PortInfo->MemBase <= PortInfo->MemLimit) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), PortInfo->MemBase);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit), PortInfo->MemLimit);
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), DISBL_MEM32_REG20);
> +  }
> +
> +  if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 &
> 0xFFFF));
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 &
> 0xFFFF));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), 0);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), 0);
> +  }
> +
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +} // SetCioPortResources
> +
> +STATIC
> +VOID
> +SetSlotsAsUnused (
> +  IN       UINT8      Bus,
> +  IN       UINT8      MaxSlotNum,
> +  IN       UINT8      CioSlot,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8 Slot;
> +  for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot,
> 0x00, 0);
> +    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +      continue;
> +    }
> +
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), DISBL_IO_REG1C);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), DISBL_MEM32_REG20);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BUS_MASTER);
> +    PortInfo->BusNumLimit--;
> +  }
> +} // SetSlotsAsUnused
> +
> +STATIC
> +UINT16
> +FindVendorSpecificHeader(
> +  IN  UINT8  Bus
> +)
> +{
> +  PCI_EXP_EXT_HDR   *ExtHdr;
> +  UINT32            ExtHdrValue;
> +  UINT16            ExtendedRegister;
> +
> +  ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
> +  ExtendedRegister  = 0x100;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00,
> 0x00, 0);
> +  while (ExtendedRegister) {
> +    ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress +
> ExtendedRegister);
> +    if (ExtHdr->CapabilityId == 0xFFFF) {
> +      return 0x0000; // No Vendor-Specific Extended Capability header
> +    }
> +
> +    if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID ==
> ExtHdr->CapabilityId) {
> +      return ExtendedRegister;
> +    }
> +
> +    ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
> +  }
> +  return 0x0000; // No Vendor-Specific Extended Capability header
> +}
> +
> +STATIC
> +UINT8
> +FindSsid_SsvidHeader (
> +  IN    UINT8  Bus
> +  )
> +{
> +  UINT8 CapHeaderId;
> +  UINT8 CapHeaderOffset;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00,
> 0x00, 0);
> +  CapHeaderOffset   = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_CAPBILITY_POINTER_OFFSET);
> +
> +  while (CapHeaderOffset != 0) {
> +    CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress +
> CapHeaderOffset);
> +
> +    if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
> +      return CapHeaderOffset;
> +    }
> +
> +    CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress +
> CapHeaderOffset + 1);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "SID0\n"));
> +  return 0;
> +} // FindSsid_SsvidHeader
> +
> +STATIC
> +BOOLEAN
> +GetCioSlotByDevId (
> +  IN   UINT8  Bus,
> +  OUT  UINT8  *CioSlot,
> +  OUT  UINT8  *MaxSlotNum,
> +  OUT  BOOLEAN *ArPcie
> +  )
> +{
> +  UINT16            VSECRegister;
> +  BRDG_CIO_MAP_REG  BridgMap;
> +  UINT32            BitScanRes;
> +  UINT16            DevId;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00,
> 0x00, 0);
> +  DevId             = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +
> +  //
> +  // Init out params in case device is not recognised
> +  //
> +  *CioSlot    = 4;
> +  *MaxSlotNum = 7;
> +  *ArPcie     = FALSE;
> +
> +  switch (DevId) {
> +    //
> +    // For known device IDs
> +    //
> +    case 0x1578:
> +      *ArPcie = TRUE;
> +  }
> +
> +  switch (DevId) {
> +  //
> +  // For known device IDs
> +  //
> +  case 0x1513:
> +  case 0x151A:
> +  case 0x151B:
> +  case 0x1547:
> +  case 0x1548:
> +    return TRUE; // Just return
> +  case 0x1549:
> +    return FALSE; // Just return
> +  }
> +
> +  VSECRegister = FindVendorSpecificHeader(Bus);
> +  if (!VSECRegister) {
> +    return TRUE; // Just return
> +  }
> +  //
> +  // Go to Bridge/CIO map register
> +  //
> +  VSECRegister += 0x18;
> +  BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress +
> VSECRegister);
> +  //
> +  // Check for range
> +  //
> +  if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
> +    return TRUE;
> +  //
> +  // Not a valid register
> +  //
> +  }
> +  //
> +  // Set OUT params
> +  //
> +  *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
> +
> +#ifdef _MSC_VER
> +  if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS
> bridge which is CIO port
> +    return FALSE;
> +  }
> +#else
> +#ifdef __GNUC__
> +  if (BridgMap.Bits.CioPortMap == 0) {
> +    return FALSE;
> +  }
> +  BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
> +#else
> +#error Unsupported Compiler
> +#endif
> +#endif
> +
> +  *CioSlot = (UINT8)BitScanRes;
> +  return TRUE;
> +} // GetCioSlotByDevId
> +
> +#define TBT_LEGACY_SUB_SYS_ID 0x11112222
> +
> +STATIC
> +BOOLEAN
> +IsLegacyDevice (
> +  IN    UINT8  Bus
> +  )
> +{
> +  UINT32  Sid;
> +  UINT8   SidRegister;
> +  UINT16  DevId;
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00,
> 0x00, 0);
> +  DevId             = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  switch (DevId) {
> +  //
> +  // For known device IDs
> +  //
> +  case 0x1513:
> +  case 0x151A:
> +  case 0x151B:
> +    DEBUG((DEBUG_INFO, "Legacy "));
> +    DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
> +    return TRUE;
> +    //
> +    // Legacy device by Device Id
> +    //
> +  }
> +
> +  SidRegister = FindSsid_SsvidHeader(Bus);
> +
> +  if (!SidRegister) {
> +    return TRUE; // May be absent for legacy devices
> +  }
> +  //
> +  // Go to register
> +  //
> +  SidRegister += 0x4;
> +  Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
> +  DEBUG((DEBUG_INFO, "SID"));
> +  DEBUG((DEBUG_INFO, " = %d\n", Sid));
> +
> +return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
> +} // IsLegacyDevice
> +
> +STATIC
> +VOID
> +UnsetVescEp(
> +  IN  UINT8     Bus,
> +  IN  UINT8     MaxSlotNum
> +  )
> +{
> +  UINT8 i;
> +
> +  for (i = 0; i <= MaxSlotNum; ++i)
> +  {
> +    UnsetVesc(Bus, i, 0);
> +  }
> +}// Unset_VESC_REG2_EP
> +
> +STATIC
> +BOOLEAN
> +ConfigureEP (
> +  IN       INT8      Depth,
> +  IN  OUT  UINT8     *Bus,
> +  IN  OUT  PORT_INFO *PortInfo
> +  )
> +{
> +  UINT8      SBus;
> +  UINT8      CioSlot;
> +  UINT8      MaxSlotNum;
> +  BOOLEAN    ArPcie;
> +  UINT8      MaxPHYSlots;
> +  UINT8      UsedBusNumbers;
> +  UINT8      cmd;
> +  BOOLEAN    CioSlotPresent;
> +  BOOLEAN    Continue;
> +  PORT_INFO  PortInfoOrg;
> +  UINT8      CioBus;
> +
> +  CioSlot     = 4;
> +  MaxSlotNum  = 7;
> +  CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus,
> 0x00, 0x00, 0);
> +  cmd               = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_COMMAND_OFFSET);
> +  // AR ONLY
> +  // Endpoint on CIO slot, but not a bridge device
> +  if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress +
> (PCI_CLASSCODE_OFFSET + 1))) {
> +    DEBUG((DEBUG_INFO, "UEP\n"));
> +    // Check whether EP already configured by examining CMD register
> +    if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
> +    {
> +      DEBUG((DEBUG_INFO, "BMF\n"));
> +      return FALSE;
> +    }
> +    // Configure it as regular PCIe device
> +    ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
> +
> +    return FALSE;
> +  }
> +
> +  //
> +  // Based on Device ID assign Cio slot and max number of PHY slots to scan
> +  //
> +  CioSlotPresent  =  GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum,
> &ArPcie);
> +  MaxPHYSlots     = MaxSlotNum;
> +  //
> +  // Check whether EP already configured by examining CMD register
> +  //
> +
> +  if (cmd & CMD_BUS_MASTER) {
> +    //
> +    // Yes no need to touch this EP, just move to next one in chain
> +    //
> +    CioBus = *Bus + 1;
> +    if(ArPcie){
> +      UnsetVescEp(CioBus, MaxSlotNum);
> +    }
> +    if (!CioSlotPresent) {
> +      //
> +      // Cio slot is not present in EP, just return FALSE
> +      //
> +      DEBUG((DEBUG_INFO, "BMF\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Take all resources from Cio slot and return
> +    //
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus,
> CioSlot, 0x00, 0);
> +    PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +    PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
> +    PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
> +    PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
> +    PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
> +    PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
> +    PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
> +    PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32))) << 16;
> +    PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32))) << 16;
> +    PortInfo->PMemLimit64  |= 0xF;
> +    //
> +    // Jump to next EP
> +    //
> +    *Bus = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +    //
> +    // Should we continue?
> +    //
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus,
> 0x00, 0x00, 0);
> +    Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +    return Continue;
> +  }
> +  //
> +  // Set is legacy dvice
> +  //
> +  isLegacyDevice = IsLegacyDevice (*Bus);
> +
> +  SetCioPortResources (
> +    *Bus,
> +    0, // Assign all available resources to US port of EP
> +    *Bus + 1,
> +    PortInfo->BusNumLimit,
> +    0,
> +    PortInfo
> +    );
> +
> +  SBus = *Bus + 1;// Jump to DS port
> +
> +  if (CioSlotPresent) {
> +    MaxPHYSlots = CioSlot;
> +  }
> +
> +  UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie,
> PortInfo);
> +  if (!CioSlotPresent) {
> +    return FALSE;
> +    //
> +    // Stop resource assignment on this chain
> +    //
> +  }
> +  //
> +  // Set rest of slots us unused
> +  //
> +  SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
> +
> +  SetCioPortResources (
> +    SBus,
> +    CioSlot,
> +    SBus + UsedBusNumbers + 1,
> +    PortInfo->BusNumLimit,
> +    &PortInfoOrg,
> +    PortInfo
> +    );
> +  *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
> +  if(ArPcie) {
> +    UnsetVesc(SBus, CioSlot, 0x00);
> +  }
> +  if (*Bus > PortInfo->BusNumLimit - 2) {
> +    //
> +    // In case of bus numbers are exhausted stop enumeration
> +    //
> +    return FALSE;
> +  }
> +  //
> +  // Check whether we should continue on this chain
> +  //
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus,
> 0x00, 0x00, 0);
> +  Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  return Continue;
> +} // ConfigureEP
> +
> +STATIC
> +VOID
> +GetPortResources (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      Fun,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> Fun, 0);
> +  PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +  PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
> +  PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
> +  PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
> +  PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
> +  PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
> +  PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
> +  PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32))) << 16;
> +  PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32))) << 16;
> +  PortInfo->IoLimit |= 0xF;
> +  PortInfo->MemLimit |= 0xF;
> +  PortInfo->PMemLimit64 |= 0xF;
> +} // GetPortResources
> +
> +STATIC
> +VOID
> +ConfigurePort (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      Fun,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  INT8  i;
> +  UINT8 USBusNum;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> Fun, 0);
> +  USBusNum          = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> USBusNum, 0x00, 0x00, 0);
> +  if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +    //
> +    // Nothing to do if TBT device is not connected
> +    //
> +    return ;
> +  }
> +
> +  GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from
> DS port
> +  //
> +  // Assign resources to EPs
> +  //
> +  for (i = 0; i < MAX_TBT_DEPTH; ++i) {
> +    PortInfo->ConfedEP++;
> +    if (!ConfigureEP (i, &USBusNum, PortInfo)) {
> +      return ;
> +    }
> +  }
> +} // ConfigurePort
> +
> +VOID
> +ThunderboltCallback (
> +  IN UINT8 Type
> +  )
> +{
> +  PORT_INFO                     PortInfoOrg  = { 0 };
> +  HR_CONFIG                     HrConfig  = { 0 };
> +  UINT8                         i;
> +  UINTN                         Segment = 0;
> +  UINTN                         Bus = 0;
> +  UINTN                         Device;
> +  UINTN                         Function;
> +
> +  DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
> +
> +  DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
> +  PortInfoInit (&PortInfoOrg);
> +  if(Type == DTBT_CONTROLLER) {
> +    if (gCurrentDiscreteTbtRootPort == 0) {
> +      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
> +      return;
> +    }
> +    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType,
> gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
> +    DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
> +    if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
> +      return ;
> +    }
> +  //
> +  // Configure DS ports
> +  //
> +  for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
> +    DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
> +    ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
> +  EndOfThunderboltCallback (Segment, Bus, Device, Function);
> +
> +  }
> +  DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
> +} // ThunderboltCallback
> +
> +VOID
> +DisablePCIDevicesAndBridges (
> +  IN UINT8 MinBus,
> +  IN UINT8 MaxBus
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   RegVal;
> +  //
> +  //  Disable PCI device First, and then Disable PCI Bridge
> +  //
> +  for (Bus = MaxBus; Bus > MinBus; --Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus,
> Dev, Fun, 0);
> +        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress +
> PCI_VENDOR_ID_OFFSET)) {
> +          if (Fun == 0) {
> +            break;
> +
> +          }
> +
> +          continue;
> +        }
> +
> +        RegVal = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +        if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
> +          //
> +          // ********     Disable PCI Device   ********
> +          // BIT0  I/O Space Enabled    BIT1  Memory Space Enabled
> +          // BIT2  Bus Master Enabled   BIT4  Memory Write and Invalidation
> Enable
> +          //
> +          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
> +        }
> +      }
> +    }
> +  }
> +  //
> +  // now no more PCI dev on another side of PCI Bridge can safty disable PCI
> Bridge
> +  //
> +  for (Bus = MaxBus; Bus > MinBus; --Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus,
> Dev, Fun, 0);
> +        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress +
> PCI_VENDOR_ID_OFFSET)) {
> +          if (Fun == 0) {
> +            break;
> +          }
> +
> +          continue;
> +        }
> +
> +        RegVal = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +        if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
> +          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
> +          PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
> +          PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
> +          PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), 0);
> +        }
> +      } // for ( Fun .. )
> +    } // for ( Dev ... )
> +  } // for ( Bus ... )
> +} // DisablePCIDevicesAndBridges
> +
> +VOID
> +TbtDisablePCIDevicesAndBridges (
> +  IN UINT8 Type
> +  )
> +{
> +  UINTN         Segment = 0;
> +  UINTN         Bus = 0;
> +  UINTN         Device;
> +  UINTN         Function;
> +  UINT8         MinBus;
> +  UINT8         MaxBus;
> +  UINT16        DeviceId;
> +
> +  MinBus = 1;
> +  if(Type == DTBT_CONTROLLER) {
> +    //
> +    // for(Dev = 0; Dev < 8; ++Dev)
> +    // {
> +    // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0,
> PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
> +    // gBS->Stall(2000);      // 2msec
> +    // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0,
> PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
> +    // }
> +    // gBS->Stall(200 * 1000);        // 200 msec
> +    //
> +    if (gCurrentDiscreteTbtRootPort == 0) {
> +      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
> +      return;
> +    }
> +    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType,
> gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> +    MinBus            = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +    MaxBus            = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus,
> 0x00, 0x00, 0);
> +    DeviceId          = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +    if (!(IsTbtHostRouter (DeviceId))) {
> +      return;
> +    }
> +    TbtSegment = (UINT8)Segment;
> +    MinBus++;
> +    //
> +    // @todo : Move this out when we dont have Loop for ITBT
> +    //
> +    DisablePCIDevicesAndBridges(MinBus, MaxBus);
> +
> +  }
> +} // DisablePCIDevicesAndBridges
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.c
> new file mode 100644
> index 0000000000..721438c718
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.c
> @@ -0,0 +1,1765 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Module specific Includes
> +//
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/GpioLib.h>
> +#include <TbtBoardInfo.h>
> +#include <Protocol/TbtNvsArea.h>
> +#include <PchAccess.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Protocol/SmmSxDispatch2.h>
> +#include <Protocol/SmmSwDispatch2.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Guid/HobList.h>
> +#include "TbtSmiHandler.h"
> +#include <PcieRegs.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Protocol/DxeTbtPolicy.h>
> +#include <Library/PchPmcLib.h>
> +#define P2P_BRIDGE                    (((PCI_CLASS_BRIDGE) << 8) |
> (PCI_CLASS_BRIDGE_P2P))
> +
> +#define CMD_BM_MEM_IO                 (CMD_BUS_MASTER | BIT1 | BIT0)
> +
> +#define DISBL_IO_REG1C                0x01F1
> +#define DISBL_MEM32_REG20             0x0000FFF0
> +#define DISBL_PMEM_REG24              0x0001FFF1
> +
> +#define DOCK_BUSSES                   8
> +
> +#define PCI_CAPABILITY_ID_PCIEXP      0x10
> +#define PCI_CAPBILITY_POINTER_OFFSET  0x34
> +
> +#define LTR_MAX_SNOOP_LATENCY_VALUE             0x0846    ///< Intel
> recommended maximum value for Snoop Latency  can we put like this ?
> +#define LTR_MAX_NON_SNOOP_LATENCY_VALUE         0x0846    ///< Intel
> recommended maximum value for Non-Snoop Latency can we put like this ?
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA
> *mTbtNvsAreaPtr;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> gCurrentDiscreteTbtRootPort;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> gCurrentDiscreteTbtRootPortType;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16
> TbtLtrMaxSnoopLatency;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16
> TbtLtrMaxNoSnoopLatency;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> gDTbtPcieRstSupport;
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB
> *gTbtInfoHob = NULL;
> +STATIC UINTN                                              mPciExpressBaseAddress;
> +STATIC UINT8                TbtSegment        = 0;
> +VOID
> +GpioWrite (
> +  IN  UINT32         GpioNumber,
> +  IN  BOOLEAN        Value
> +  )
> +{
> +  GpioSetOutputValue (GpioNumber, (UINT32)Value);
> +}
> +
> +/**
> +  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] 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   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT16  CapId
> +  )
> +{
> +  UINT16  CapHeaderOffset;
> +  UINT16  CapHeaderId;
> +  UINT64  DeviceBase;
> +
> +  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device,
> Function, 0);
> +
> +  ///
> +  /// 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 = 0x100;
> +  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
> +    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;
> +}
> +
> +/**
> +  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] 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
> +  )
> +{
> +  UINT8   CapHeaderOffset;
> +  UINT8   CapHeaderId;
> +  UINT64  DeviceBase;
> +
> +  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function,
> 0);
> +
> +  if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) &
> EFI_PCI_STATUS_CAPABILITY) == 0x00) {
> +    ///
> +    /// Function has no capability pointer
> +    ///
> +    return 0;
> +  }
> +
> +  ///
> +  /// 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 = 0x14;
> +  } else {
> +    ///
> +    /// Otherwise, start at Offset 0x34
> +    ///
> +    CapHeaderOffset = 0x34;
> +  }
> +  ///
> +  /// 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) {
> +    CapHeaderId = PciSegmentRead8 (DeviceBase + CapHeaderOffset);
> +    if (CapHeaderId == CapId) {
> +      return CapHeaderOffset;
> +    }
> +    ///
> +    /// 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 = PciSegmentRead8 (DeviceBase + CapHeaderOffset + 1)
> & ((UINT8) ~(BIT0 | BIT1));
> +  }
> +
> +  return 0;
> +}
> +/**
> +  This function configures the L1 Substates.
> +  It can be used for Rootport and endpoint devices.
> +
> +  @param[in] DownstreamPort               Indicates if the device about to be
> programmed is a downstream port
> +  @param[in] DeviceBase                   Device PCI configuration base address
> +  @param[in] L1SubstateExtCapOffset       Pointer to L1 Substate Capability
> Structure
> +  @param[in] PortL1SubstateCapSupport     L1 Substate capability setting
> +  @param[in] PortCommonModeRestoreTime    Common Mode Restore
> Time
> +  @param[in] PortTpowerOnValue            Tpower_on Power On Wait Time
> +  @param[in] PortTpowerOnScale            Tpower-on Scale
> +
> +  @retval none
> +**/
> +VOID
> +ConfigureL1s (
> +  IN UINTN                              DeviceBase,
> +  IN UINT16                             L1SubstateExtCapOffset,
> +  IN UINT32                             PortL1SubstateCapSupport,
> +  IN UINT32                             PortCommonModeRestoreTime,
> +  IN UINT32                             PortTpowerOnValue,
> +  IN UINT32                             PortTpowerOnScale,
> +  IN UINT16                             MaxLevel
> +  )
> +{
> +
> +  PciSegmentAndThenOr32 (
> +    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
> +    (UINT32) ~(0xFF00),
> +    (UINT32) PortCommonModeRestoreTime << 8
> +    );
> +
> +  PciSegmentAnd32(DeviceBase + L1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL2_OFFSET, 0xFFFFFF04);
> +
> +  PciSegmentOr32(DeviceBase + L1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL2_OFFSET,(UINT32) ((PortTpowerOnValue <<
> N_PCIE_EX_L1SCTL2_POWT) | PortTpowerOnScale));
> +
> +  PciSegmentAndThenOr32 (
> +    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
> +    (UINT32) ~(0xE3FF0000),
> +    (UINT32) (BIT30 | BIT23 | BIT21)
> +    );
> +
> +}
> +
> +VOID
> +RootportL1sSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT16  RootL1SubstateExtCapOffset,
> +  IN UINT16  MaxL1Level
> +  )
> +{
> +  UINTN       ComponentABaseAddress;
> +  UINTN       ComponentBBaseAddress;
> +  UINT8       SecBus;
> +  UINT32      PortL1SubstateCapSupport;
> +  UINT32      PortCommonModeRestoreTime;
> +  UINT32      PortTpowerOnValue;
> +  UINT32      PortTpowerOnScale;
> +  UINT16      ComponentBL1SubstateExtCapOffset;
> +  UINT32      ComponentBL1Substates;
> +  UINT32      ComponentBCommonModeRestoreTime;
> +  UINT32      ComponentBTpowerOnValue;
> +  UINT32      ComponentBTpowerOnScale;
> +  UINT32      Data32;
> +
> +  PortL1SubstateCapSupport  = 0;
> +  PortCommonModeRestoreTime = 0;
> +  PortTpowerOnValue = 0;
> +  PortTpowerOnScale = 0;
> +  Data32 = 0;
> +
> +  ComponentABaseAddress  = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> Bus, Dev, Fun, 0);
> +  if (RootL1SubstateExtCapOffset != 0) {
> +    Data32 = PciSegmentRead32 (ComponentABaseAddress +
> RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
> +    PortL1SubstateCapSupport  = (Data32) & 0x0F;
> +    PortCommonModeRestoreTime = (Data32 >> 8) & 0xFF;
> +    PortTpowerOnScale         = (Data32 >> 16) & 0x3;
> +    PortTpowerOnValue         = (Data32 >> 19) & 0x1F;
> +  } else {
> +    MaxL1Level                = 0; // If L1 Substates from Root Port side is disable,
> then Disable from Device side also.
> +  }
> +
> +  SecBus                = PciSegmentRead8 (ComponentABaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> SecBus, 0, 0, 0);
> +
> +  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET)
> == 0xFFFF) {
> +    ComponentBL1SubstateExtCapOffset = PcieFindExtendedCapId (
> +                                  SecBus,
> +                                  0,
> +                                  0,
> +                                  V_PCIE_EX_L1S_CID
> +                                  );
> +    if (ComponentBL1SubstateExtCapOffset != 0) {
> +      ComponentBL1Substates = PciSegmentRead32
> (ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCAP_OFFSET);
> +      ComponentBCommonModeRestoreTime = (ComponentBL1Substates >>
> 8) & 0xFF;
> +      ComponentBTpowerOnScale         = (ComponentBL1Substates >> 16) &
> 0x3;
> +      ComponentBTpowerOnValue         = (ComponentBL1Substates >> 19) &
> 0x1F;
> +
> +      if (MaxL1Level == 3) {
> +        if (Data32 >= ComponentBL1Substates) {
> +          if (~(Data32 | BIT2)) {
> +            MaxL1Level = 1;
> +          }
> +        }
> +        else {
> +          if (~(ComponentBL1Substates | BIT2)) {
> +          MaxL1Level = 1;
> +        }
> +      }
> +    }
> +
> +      if (MaxL1Level == 3) {
> +        ConfigureL1s (
> +          ComponentABaseAddress,
> +          RootL1SubstateExtCapOffset,
> +          PortL1SubstateCapSupport,
> +          ComponentBCommonModeRestoreTime,
> +          ComponentBTpowerOnValue,
> +          ComponentBTpowerOnScale,
> +          MaxL1Level
> +          );
> +
> +      ConfigureL1s (
> +          ComponentBBaseAddress,
> +          ComponentBL1SubstateExtCapOffset,
> +          ComponentBL1Substates,
> +          PortCommonModeRestoreTime,
> +          PortTpowerOnValue,
> +          PortTpowerOnScale,
> +          MaxL1Level
> +          );
> +      }
> +
> +      if (MaxL1Level == 1) {
> +        PciSegmentOr32 (
> +          ComponentABaseAddress + RootL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +          (UINT32) (BIT3 | BIT1)
> +          );
> +
> +        PciSegmentOr32 (
> +          ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +          (UINT32) (BIT3 | BIT1)
> +          );
> +      }
> +      else {
> +        if (RootL1SubstateExtCapOffset != 0) {
> +          PciSegmentOr32 (
> +            ComponentABaseAddress + RootL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT3 | BIT1)
> +            );
> +
> +          PciSegmentOr32 (
> +            ComponentABaseAddress + RootL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT2 | BIT0)
> +            );
> +        }
> +        if (ComponentBL1SubstateExtCapOffset != 0) {
> +          PciSegmentOr32 (
> +            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT3 | BIT1)
> +           );
> +
> +          PciSegmentOr32 (
> +            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT2 | BIT0)
> +            );
> +        }
> +      }
> +    }
> +  }
> +}
> +
> +VOID
> +MultiFunctionDeviceAspm (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev
> +  )
> +{
> +  UINT16  LowerAspm;
> +  UINT16  AspmVal;
> +  UINT8   Fun;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +
> +  LowerAspm = 3; // L0s and L1 Supported
> +  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +    //
> +    // Check for Device availability
> +    //
> +    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +      // Device not present
> +      continue;
> +    }
> +
> +    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +
> +    AspmVal = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset +
> 0x00C) >> 10) & 3;
> +    if (LowerAspm > AspmVal) {
> +      LowerAspm = AspmVal;
> +    }
> +  } //Fun
> +
> +  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +    //
> +    // Check for Device availability
> +    //
> +    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +      //
> +      // Device not present
> +      //
> +      continue;
> +    }
> +
> +    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +
> +    PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, LowerAspm);
> +  } //Fun
> +}
> +
> +UINT16
> +LimitAspmLevel (
> +  IN UINT16  SelectedAspm,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  SelectedAspm = SelectedAspm & MaxAspmLevel;
> +
> +  return SelectedAspm;
> +}
> +
> +UINT16
> +FindOptimalAspm (
> +  IN UINT16   ComponentAaspm,
> +  IN UINT16   ComponentBaspm
> +  )
> +{
> +  UINT16  SelectedAspm;
> +
> +  SelectedAspm = ComponentAaspm & ComponentBaspm;
> +
> +  return SelectedAspm;
> +}
> +
> +UINT16
> +FindComponentBaspm (
> +  IN UINT8   Bus,
> +  IN UINT8   MaxBus
> +  )
> +{
> +  UINT8   BusNo;
> +  UINT8   DevNo;
> +  UINT8   FunNo;
> +  UINT64  DevBaseAddress;
> +  UINT8   RegVal;
> +  UINT8   SecBusNo;
> +  UINT16  SelectedAspm; // No ASPM Support
> +  UINT8   CapHeaderOffset_B;
> +  BOOLEAN AspmFound;
> +
> +  SelectedAspm  = 0;
> +  AspmFound     = FALSE;
> +
> +  for (BusNo = MaxBus; (BusNo != 0xFF) && (!AspmFound); --BusNo) {
> +    for (DevNo = 0; (DevNo <= PCI_MAX_DEVICE) && (!AspmFound); ++DevNo)
> {
> +      for (FunNo = 0; (FunNo <= PCI_MAX_FUNC) && (!AspmFound); ++FunNo)
> {
> +        //
> +        // Check for Device availability
> +        //
> +        DevBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, BusNo,
> DevNo, FunNo, 0);
> +        if (PciSegmentRead16 (DevBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        RegVal = PciSegmentRead8 (DevBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +        if ((RegVal & (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6)) != 0x01) {
> +          //
> +          // Not a PCI-to-PCI bridges device
> +          //
> +          continue;
> +        }
> +
> +        SecBusNo = PciSegmentRead8 (DevBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +
> +        if (SecBusNo == Bus) {
> +          //
> +          // This is the Rootbridge for the given 'Bus' device
> +          //
> +          CapHeaderOffset_B = PcieFindCapId (TbtSegment, BusNo, DevNo,
> FunNo, 0x10);
> +          SelectedAspm      = (PciSegmentRead16 (DevBaseAddress +
> CapHeaderOffset_B + 0x00C) >> 10) & 3;
> +          AspmFound         = TRUE;
> +        }
> +      } //FunNo
> +    } //DevNo
> +  } //BusNo
> +
> +  return (SelectedAspm);
> +}
> +
> +VOID
> +NoAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset
> +  )
> +{
> +  UINT64 DeviceBaseAddress;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, 0x00);
> +}
> +
> +VOID
> +EndpointAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT8   MaxBus,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
> +  SelectedAspm      = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +UpstreamAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT8   MaxBus,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
> +  SelectedAspm      = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +DownstreamAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  ComponentABaseAddress;
> +  UINT64  ComponentBBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +  UINT8   SecBus;
> +  UINT8   CapHeaderOffset_B;
> +
> +  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +
> +  SecBus                = PciSegmentRead8 (ComponentABaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> SecBus, 0, 0, 0);
> +  ComponentBaspm        = 0; // No ASPM Support
> +  if (PciSegmentRead16 (ComponentBBaseAddress +
> PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
> +    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
> +    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress +
> CapHeaderOffset_B + 0x00C) >> 10) & 3;
> +  }
> +
> +  SelectedAspm = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset +
> 0x10, 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +RootportAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  ComponentABaseAddress;
> +  UINT64  ComponentBBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +  UINT8   SecBus;
> +  UINT8   CapHeaderOffset_B;
> +
> +  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +
> +  SecBus                = PciSegmentRead8 (ComponentABaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> SecBus, 0, 0, 0);
> +  ComponentBaspm        = 0; // No ASPM Support
> +  if (PciSegmentRead16 (ComponentBBaseAddress +
> PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
> +    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
> +    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress +
> CapHeaderOffset_B + 0x00C) >> 10) & 3;
> +  }
> +
> +  SelectedAspm = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset +
> 0x10, 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +ThunderboltEnableAspmWithoutLtr (
> +  IN   UINT16     MaxAspmLevel,
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   RootBus;
> +  UINT8   RootDev;
> +  UINT8   RootFun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   RegVal;
> +  UINT8   CapHeaderOffset;
> +  UINT16  DevicePortType;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +
> +  RootBus = (UINT8)RpBus;
> +  RootDev = (UINT8)RpDevice;
> +  RootFun = (UINT8)RpFunction;
> +
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      //
> +      // Check for Device availability
> +      //
> +      DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, 0, 0);
> +      if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +        //
> +        // Device not present
> +        //
> +        continue;
> +      }
> +
> +      RegVal = PciSegmentRead8 (DeviceBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +      if ((RegVal & BIT7) == 0) {
> +        //
> +        // Not a multi-function device
> +        //
> +        continue;
> +      }
> +
> +      MultiFunctionDeviceAspm(Bus, Dev);
> +    } //Dev
> +  } //Bus
> +
> +
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 0x002) >> 4) & 0xF;
> +        if(PciSegmentRead8 (DeviceBaseAddress + PCI_CLASSCODE_OFFSET) ==
> PCI_CLASS_SERIAL) {
> +          MaxAspmLevel = (UINT16) 0x1;
> +        }
> +
> +        switch (DevicePortType) {
> +        case 0:
> +          //
> +          // PCI Express Endpoint
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 1:
> +          //
> +          // Legacy PCI Express Endpoint
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 4:
> +          //
> +          // Root Port of PCI Express Root Complex
> +          //
> +          RootportAspmSupport (Bus, Dev, Fun, CapHeaderOffset,
> MaxAspmLevel);
> +          break;
> +
> +        case 5:
> +          //
> +          // Upstream Port of PCI Express Switch
> +          //
> +          UpstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 6:
> +          //
> +          // Downstream Port of PCI Express Switch
> +          //
> +          DownstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset,
> MaxAspmLevel);
> +          break;
> +
> +        case 7:
> +          //
> +          // PCI Express to PCI/PCI-X Bridge
> +          //
> +          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
> +          break;
> +
> +        case 8:
> +          //
> +          // PCI/PCI-X to PCI Express Bridge
> +          //
> +          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
> +          break;
> +
> +        case 9:
> +          //
> +          // Root Complex Integrated Endpoint
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 10:
> +          //
> +          // Root Complex Event Collector
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        default:
> +          break;
> +        }
> +        //
> +        // switch(DevicePortType)
> +        //
> +      }
> +      //
> +      // Fun
> +      //
> +    }
> +    //
> +    // Dev
> +    //
> +  }
> +  //
> +  // Bus
> +  //
> +  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun,
> 0x10);
> +  RootportAspmSupport (RootBus, RootDev, RootFun, CapHeaderOffset,
> MaxAspmLevel);
> +}
> +
> +
> +
> +VOID
> +ThunderboltEnableL1Sub (
> +  IN   UINT16     MaxL1Level,
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT16  CapHeaderOffsetExtd;
> +
> +  RpBus   = 0;
> +
> +  CapHeaderOffsetExtd = PcieFindExtendedCapId ((UINT8) RpBus, (UINT8)
> RpDevice, (UINT8) RpFunction, V_PCIE_EX_L1S_CID);
> +  RootportL1sSupport ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction,
> CapHeaderOffsetExtd, MaxL1Level);
> +}
> +
> +VOID
> +ThunderboltDisableAspmWithoutLtr (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   RootBus;
> +  UINT8   RootDev;
> +  UINT8   RootFun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +  RootBus = (UINT8)RpBus;
> +  RootDev = (UINT8)RpDevice;
> +  RootFun = (UINT8)RpFunction;
> +
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +        PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset +
> 0x10, 0xFFFC, 0x00);
> +      } //Fun
> +    } //Dev
> +  } //Bus
> +
> +  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun,
> 0x10);
> +  NoAspmSupport(RootBus, RootDev, RootFun, CapHeaderOffset);
> +}
> +
> +VOID
> +TbtProgramClkReq (
> +  IN        UINT8  Bus,
> +  IN        UINT8  Device,
> +  IN        UINT8  Function,
> +  IN        UINT8  ClkReqSetup
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +  UINT16  Data16;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Device, Function, 0);
> +  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function,
> 0x10);
> +
> +  //
> +  // Check if CLKREQ# is supported
> +  //
> +  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x0C) &
> BIT18) != 0) {
> +    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset +
> 0x010);
> +
> +    if (ClkReqSetup) {
> +      Data16 = Data16 | BIT8; // Enable Clock Power Management
> +    } else {
> +      Data16 =  Data16 & (UINT16)(~BIT8); // Disable Clock Power
> Management
> +    }
> +
> +    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x010,
> Data16);
> +  }
> +}
> +VOID
> +TbtProgramPtm(
> +   IN        UINT8  Bus,
> +   IN        UINT8  Device,
> +   IN        UINT8  Function,
> +   IN        UINT8  PtmSetup,
> +   IN        BOOLEAN IsRoot
> +)
> +{
> +   UINT64  DeviceBaseAddress;
> +   UINT16  CapHeaderOffset;
> +   UINT16  PtmControlRegister;
> +   UINT16  PtmCapabilityRegister;
> +
> +   DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS(TbtSegment, Bus,
> Device, Function, 0);
> +   CapHeaderOffset = PcieFindExtendedCapId(Bus, Device, Function, 0x001F
> /*V_PCIE_EX_PTM_CID*/);
> +   if(CapHeaderOffset != 0) {
> +      PtmCapabilityRegister = PciSegmentRead16(DeviceBaseAddress +
> CapHeaderOffset + 0x04);
> +     //
> +     // Check if PTM Requester/ Responder capability for the EP/Down stream
> etc
> +     //
> +     if ((PtmCapabilityRegister & (BIT1 | BIT0)) != 0) {
> +        PtmControlRegister = PciSegmentRead16(DeviceBaseAddress +
> CapHeaderOffset + 0x08);
> +
> +        if (PtmSetup) {
> +           PtmControlRegister = PtmControlRegister | BIT0; // Enable PTM
> +           if(IsRoot) {
> +             PtmControlRegister = PtmControlRegister | BIT1; // Enable PTM
> +           }
> +           PtmControlRegister = PtmControlRegister | (PtmCapabilityRegister &
> 0xFF00); // Programm Local Clock Granularity
> +        } else {
> +           PtmControlRegister = PtmControlRegister & (UINT16)(~(BIT0 | BIT1));
> // Disable Clock Power Management
> +        }
> +
> +        PciSegmentWrite16(DeviceBaseAddress + CapHeaderOffset + 0x08,
> PtmControlRegister);
> +     }
> +   }
> +}
> +
> +VOID
> +ConfigureTbtPm (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction,
> +  IN   UINT8      Configuration    // 1- Clk Request , 2- PTM ,
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  if ((Configuration != 1) && (Configuration != 2)) {
> +    return;
> +  }
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MaxBus; Bus >= MinBus; --Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          if (Fun == 0) {
> +            //
> +            // IF Fun is zero, stop enumerating other functions of the particular
> bridge
> +            //
> +            break;
> +          }
> +          //
> +          // otherwise, just skip checking for CLKREQ support
> +          //
> +          continue;
> +        }
> +        switch (Configuration) {
> +          case 1:
> +            TbtProgramClkReq (Bus, Dev, Fun, (UINT8)
> mTbtNvsAreaPtr->TbtSetClkReq);
> +            break;
> +          case 2:
> +            TbtProgramPtm (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtPtm,
> FALSE);
> +            TbtProgramPtm((UINT8) RpBus, (UINT8) RpDevice, (UINT8)
> RpFunction, (UINT8) mTbtNvsAreaPtr->TbtPtm, TRUE);
> +            break;
> +          default:
> +            break;
> +        }
> +      } //Fun
> +    } // Dev
> +  } // Bus
> +}
> +
> +/**
> +  1) Check LTR support in device capabilities 2 register (bit 11).
> +  2) If supported enable LTR in device control 2 register (bit 10).
> +
> +**/
> +VOID
> +TbtProgramLtr (
> +  IN        UINT8  Bus,
> +  IN        UINT8  Device,
> +  IN        UINT8  Function,
> +  IN        UINT8  LtrSetup
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +  UINT16  Data16;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Device, Function, 0);
> +  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function,
> 0x10);
> +
> +  //
> +  // Check if LTR# is supported
> +  //
> +  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x24) &
> BIT11) != 0) {
> +    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset +
> 0x028);
> +
> +    if (LtrSetup) {
> +      Data16 = Data16 | BIT10; // LTR Mechanism Enable
> +    } else {
> +      Data16 =  Data16 & (UINT16)(~BIT10); // LTR Mechanism Disable
> +    }
> +
> +    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x028,
> Data16);
> +  }
> +}
> +
> +VOID
> +ConfigureLtr (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          if (Fun == 0) {
> +            //
> +            // IF Fun is zero, stop enumerating other functions of the particular
> bridge
> +            //
> +            break;
> +          }
> +          //
> +          // otherwise, just skip checking for LTR support
> +          //
> +          continue;
> +        }
> +
> +        TbtProgramLtr (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtLtr);
> +
> +      } //Fun
> +    } // Dev
> +  } // Bus
> +  TbtProgramLtr ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction,
> (UINT8) mTbtNvsAreaPtr->TbtLtr);
> +}
> +
> +/*
> +  US ports and endpoints which declare support must also have the LTR
> capability structure (cap ID 18h).
> +  In this structure you need to enter the max snoop latency and max
> non-snoop latency in accordance with the format specified in the PCIe spec.
> +  The latency value itself is platform specific so you'll need to get it from the
> platform architect or whatever.
> +*/
> +VOID
> +ThunderboltGetLatencyLtr (
> +  VOID
> +  )
> +{
> +  PCH_SERIES       PchSeries;
> +
> +  PchSeries = GetPchSeries ();
> +
> +  if(gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PEG) {
> +  // PEG selector
> +  TbtLtrMaxSnoopLatency = LTR_MAX_SNOOP_LATENCY_VALUE;
> +  TbtLtrMaxNoSnoopLatency = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
> +  } else if (gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PCH) {
> +  // PCH selector
> +
> +    if (PchSeries == PchLp) {
> +      TbtLtrMaxSnoopLatency = 0x1003;
> +      TbtLtrMaxNoSnoopLatency = 0x1003;
> +    }
> +    if (PchSeries == PchH) {
> +      TbtLtrMaxSnoopLatency = 0x0846;
> +      TbtLtrMaxNoSnoopLatency = 0x0846;
> +    }
> +  }
> +}
> +
> +VOID
> +SetLatencyLtr (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT16  CapHeaderOffsetExtd,
> +  IN UINT16  LtrMaxSnoopLatency,
> +  IN UINT16  LtrMaxNoSnoopLatency
> +  )
> +{
> +  UINT64 DeviceBaseAddress;
> +  if(CapHeaderOffsetExtd == 0) {
> +    return;
> +  }
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x004,
> LtrMaxSnoopLatency);
> +  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x006,
> LtrMaxNoSnoopLatency);
> +}
> +
> +VOID
> +ThunderboltSetLatencyLtr (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffsetStd;
> +  UINT16  CapHeaderOffsetExtd;
> +  UINT16  DevicePortType;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        CapHeaderOffsetStd = PcieFindCapId (TbtSegment, Bus, Dev, Fun,
> 0x10);
> +        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffsetStd + 0x002) >> 4) & 0xF;
> +
> +        CapHeaderOffsetExtd = PcieFindExtendedCapId (Bus, Dev, Fun,
> 0x0018);
> +
> +        switch (DevicePortType) {
> +        case 0:
> +          //
> +          // PCI Express Endpoint
> +          //
> +          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd,
> TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
> +          break;
> +
> +        case 1:
> +          //
> +          // Legacy PCI Express Endpoint
> +          //
> +          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd,
> TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
> +          break;
> +
> +        case 4:
> +          //
> +          // Root Port of PCI Express Root Complex
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 5:
> +          //
> +          // Upstream Port of PCI Express Switch
> +          //
> +          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd,
> TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
> +          break;
> +
> +        case 6:
> +          //
> +          // Downstream Port of PCI Express Switch
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 7:
> +          //
> +          // PCI Express to PCI/PCI-X Bridge
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 8:
> +          //
> +          // PCI/PCI-X to PCI Express Bridge
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 9:
> +          //
> +          // Root Complex Integrated Endpoint
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 10:
> +          //
> +          // Root Complex Event Collector
> +          //
> +          // Do-nothing
> +          break;
> +
> +        default:
> +          break;
> +        }
> +        //
> +        // switch(DevicePortType)
> +        //
> +      }
> +      //
> +      // Fun
> +      //
> +    }
> +    //
> +    // Dev
> +    //
> +  }
> +  //
> +  // Bus
> +  //
> +}
> +
> +static
> +VOID
> +Stall (
> +  UINTN     Usec
> +  )
> +{
> +  UINTN   Index;
> +  UINT32  Data32;
> +  UINT32  PrevData;
> +  UINTN   Counter;
> +
> +  Counter = (UINTN) ((Usec * 10) / 3);
> +  //
> +  // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
> +  // periods, thus attempting to ensure Microseconds of stall time.
> +  //
> +  if (Counter != 0) {
> +
> +    PrevData = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) +
> R_PCH_ACPI_PM1_TMR);
> +    for (Index = 0; Index < Counter;) {
> +      Data32 = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) +
> R_PCH_ACPI_PM1_TMR);
> +      if (Data32 < PrevData) {
> +        //
> +        // Reset if there is a overlap
> +        //
> +        PrevData = Data32;
> +        continue;
> +      }
> +
> +      Index += (Data32 - PrevData);
> +      PrevData = Data32;
> +    }
> +  }
> +
> +  return ;
> +}
> +/**
> +  Called during Sx entry, initates TbtSetPcie2TbtCommand HandShake to set
> GO2SX_NO_WAKE
> +  for Tbt devices if WakeupSupport is not present.
> +
> +  @param[in] DispatchHandle         - The unique handle assigned to this
> handler by SmiHandlerRegister().
> +  @param[in] DispatchContext        - 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 successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SxDTbtEntryCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  CONST VOID                    *DispatchContext,
> +  IN  OUT VOID                      *CommBuffer OPTIONAL,
> +  IN  UINTN                         *CommBufferSize OPTIONAL
> +  )
> +{
> +  UINT16          DeviceId;
> +  UINT8           CableConnected;
> +  UINT8           RootportSelected;
> +  UINT8           HoustRouteBus;
> +  volatile UINT32 *PowerState;
> +  UINT32          PowerStatePrev;
> +  BOOLEAN         SecSubBusAssigned;
> +  UINT64          DeviceBaseAddress;
> +  UINT8           CapHeaderOffset;
> +  UINTN           RpDev;
> +  UINTN           RpFunc;
> +  EFI_STATUS      Status;
> +  UINT32          Timeout;
> +  UINT32          RegisterValue;
> +  UINT64          Tbt2Pcie;
> +  UINTN           Index;
> +  UINT32          TbtCioPlugEventGpioNo;
> +  UINT32          TbtFrcPwrGpioNo;
> +  UINT8           TbtFrcPwrGpioLevel;
> +  UINT32          TbtPcieRstGpioNo;
> +  UINT8           TbtPcieRstGpioLevel;
> +  EFI_SMM_SX_REGISTER_CONTEXT   *EntryDispatchContext;
> +
> +  CableConnected    = 0;
> +  HoustRouteBus     = 3;
> +  SecSubBusAssigned = FALSE;
> +  Timeout = 600;
> +  RootportSelected      = 0;
> +  TbtCioPlugEventGpioNo = 0;
> +  TbtFrcPwrGpioNo       = 0;
> +  TbtFrcPwrGpioLevel    = 0;
> +  TbtPcieRstGpioNo      = 0;
> +  TbtPcieRstGpioLevel   = 0;
> +  Index = 0;
> +
> +  EntryDispatchContext = (EFI_SMM_SX_REGISTER_CONTEXT*)
> DispatchContext;
> +
> +//  CableConnected = GetTbtHostRouterStatus ();
> +  //SaveTbtHostRouterStatus (CableConnected & 0xF0);
> +  //
> +  // Get the Power State and Save
> +  //
> +  if (((mTbtNvsAreaPtr->DTbtControllerEn0 == 0) && (Index == 0)))  {
> +
> +  RootportSelected      = mTbtNvsAreaPtr->RootportSelected0;
> +  TbtCioPlugEventGpioNo = mTbtNvsAreaPtr->TbtCioPlugEventGpioNo0;
> +  TbtFrcPwrGpioNo       = mTbtNvsAreaPtr->TbtFrcPwrGpioNo0;
> +  TbtFrcPwrGpioLevel    = mTbtNvsAreaPtr->TbtFrcPwrGpioLevel0;
> +  TbtPcieRstGpioNo      = mTbtNvsAreaPtr->TbtPcieRstGpioNo0;
> +  TbtPcieRstGpioLevel   = mTbtNvsAreaPtr->TbtPcieRstGpioLevel0;
> +  }
> +
> +  Status = GetDTbtRpDevFun (gCurrentDiscreteTbtRootPortType,
> RootportSelected - 1, &RpDev, &RpFunc);
> +  ASSERT_EFI_ERROR (Status);
> +  CapHeaderOffset = PcieFindCapId (TbtSegment, 0x00, (UINT8)RpDev,
> (UINT8)RpFunc, 0x01);
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, 0x00,
> (UINT32)RpDev, (UINT32)RpFunc, 0);
> +  PowerState        = &*((volatile UINT32 *) (mPciExpressBaseAddress +
> DeviceBaseAddress + CapHeaderOffset + 4)); //PMCSR
> +  PowerStatePrev    = *PowerState;
> +  *PowerState &= 0xFFFFFFFC;
> +
> +  HoustRouteBus = PciSegmentRead8 (DeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  //
> +  // Check the Subordinate bus .If it is Zero ,assign temporary bus to
> +  // find the device presence .
> +  //
> +  if (HoustRouteBus == 0) {
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0xF0);
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0xF0);
> +    HoustRouteBus     = 0xF0;
> +    SecSubBusAssigned = TRUE;
> +  }
> +  //
> +  // Clear Interrupt capability of TBT CIO Plug Event Pin to make sure no SCI is
> getting generated,
> +  // This GPIO will be reprogrammed while resuming as part of Platform GPIO
> Programming.
> +  //
> +  GpioSetPadInterruptConfig (TbtCioPlugEventGpioNo, GpioIntDis);
> +  //
> +  // Read the TBT Host router DeviceID
> +  //
> +  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> HoustRouteBus, 0, 0, PCI_DEVICE_ID_OFFSET));
> +
> +  //
> +  // Check For HostRouter Presence
> +  //
> +  if (IsTbtHostRouter (DeviceId)) {
> +    //    CableConnected = GetTbtHostRouterStatus ();
> +    if (!((CableConnected & (DTBT_SAVE_STATE_OFFSET << Index)) ==
> (DTBT_SAVE_STATE_OFFSET << Index))) {
> +      CableConnected = CableConnected | (DTBT_SAVE_STATE_OFFSET <<
> Index);
> +   //     SaveTbtHostRouterStatus (CableConnected);
> +    }
> +  }
> +
> +  //
> +  // Check value of Tbt2Pcie reg, if Tbt is not present, bios needs to apply force
> power prior to sending mailbox command
> +  //
> +  GET_TBT2PCIE_REGISTER_ADDRESS(TbtSegment, HoustRouteBus, 0x00,
> 0x00, Tbt2Pcie)
> +  RegisterValue = PciSegmentRead32 (Tbt2Pcie);
> +  if (0xFFFFFFFF == RegisterValue) {
> +
> +    GpioWrite (TbtFrcPwrGpioNo,TbtFrcPwrGpioLevel);
> +
> +    while (Timeout -- > 0) {
> +      RegisterValue = PciSegmentRead32 (Tbt2Pcie);
> +      if (0xFFFFFFFF != RegisterValue) {
> +        break;
> +      }
> +      Stall(1* (UINTN)1000);
> +    }
> +    //
> +    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox
> command for AIC.
> +    // However BIOS shall not execute go2sx mailbox command on S5/reboot
> cycle.
> +    //
> +
> +    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type
> == SxS4))
> +    {
> +      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
> +        //Wake Disabled, GO2SX_NO_WAKE Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE,
> HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
> +      } else {
> +        //Wake Enabled, GO2SX Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0,
> TBT_5S_TIMEOUT);
> +      }
> +    }
> +    if (mTbtNvsAreaPtr->TbtFrcPwrEn == 0) {
> +      GpioWrite (TbtFrcPwrGpioNo,!(TbtFrcPwrGpioLevel));
> +    }
> +  } else {
> +    //
> +    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox
> command for AIC.
> +    // However BIOS shall not execute go2sx mailbox command on S5/reboot
> cycle.
> +    //
> +    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type
> == SxS4))
> +    {
> +      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
> +        //Wake Disabled, GO2SX_NO_WAKE Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE,
> HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
> +      } else {
> +        //Wake Enabled, GO2SX Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0,
> TBT_5S_TIMEOUT);
> +      }
> +    }
> +  }
> +  *PowerState = PowerStatePrev;
> +  //
> +  // Restore the bus number in case we assigned temporarily
> +  //
> +  if (SecSubBusAssigned) {
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0x00);
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0x00);
> +  }
> +  if (gDTbtPcieRstSupport) {
> +    GpioWrite (TbtPcieRstGpioNo,TbtPcieRstGpioLevel);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +ThunderboltSwSmiCallback (
> +  IN UINT8 Type
> +  )
> +{
> +  UINT8 ThunderboltSmiFunction;
> +
> +  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Entry\n"));
> +  ThunderboltSmiFunction = mTbtNvsAreaPtr->ThunderboltSmiFunction;
> +  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback.
> ThunderboltSmiFunction=%d\n", ThunderboltSmiFunction));
> +  if (Type == DTBT_CONTROLLER) {
> +    gCurrentDiscreteTbtRootPort     =
> mTbtNvsAreaPtr->CurrentDiscreteTbtRootPort;
> +    gCurrentDiscreteTbtRootPortType =
> mTbtNvsAreaPtr->CurrentDiscreteTbtRootPortType;
> +  }
> +
> +  switch (ThunderboltSmiFunction) {
> +  case 21:
> +    ThunderboltCallback (Type);
> +    break;
> +
> +  case 22:
> +    TbtDisablePCIDevicesAndBridges (Type);
> +    break;
> +
> +  case 23:
> +    ConfigureTbtAspm (Type, (UINT16) 0x02);
> +    break;
> +
> +  case 24:
> +    ConfigureTbtAspm (Type, (UINT16) 0x01);
> +    break;
> +
> +  default:
> +    break;
> +  }
> +  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Exit.\n"));
> +}
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +DiscreteThunderboltSwSmiCallback (
> +  IN EFI_HANDLE                     DispatchHandle,
> +  IN  CONST VOID                    *DispatchContext,
> +  IN  OUT VOID                      *CommBuffer OPTIONAL,
> +  IN  UINTN                         *CommBufferSize OPTIONAL
> +  )
> +{
> +  ThunderboltSwSmiCallback(DTBT_CONTROLLER);
> +  return EFI_SUCCESS;
> +}
> +EFI_STATUS
> +TbtRegisterHandlers (
> +  IN BOOLEAN Type
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINTN                         SmiInputValue;
> +  EFI_SMM_HANDLER_ENTRY_POINT2   SxHandler;
> +  EFI_SMM_HANDLER_ENTRY_POINT2   SwHandler;
> +  EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatchProtocol;
> +  EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
> +  EFI_SMM_SX_REGISTER_CONTEXT   EntryDispatchContext;
> +  EFI_SMM_SW_REGISTER_CONTEXT   SwContext;
> +  EFI_HANDLE                    SwDispatchHandle;
> +  EFI_HANDLE                    S3DispatchHandle;
> +  EFI_HANDLE                    S4DispatchHandle;
> +  EFI_HANDLE                    S5DispatchHandle;
> +
> +  Status = EFI_UNSUPPORTED;
> +
> +  if(Type == DTBT_CONTROLLER) {
> +    SxHandler = SxDTbtEntryCallback;
> +    SwHandler = DiscreteThunderboltSwSmiCallback;
> +    SmiInputValue = PcdGet8 (PcdSwSmiDTbtEnumerate);
> +    gDTbtPcieRstSupport =
> gTbtInfoHob->DTbtCommonConfig.PcieRstSupport;
> +    Status = EFI_SUCCESS;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  SwDispatchHandle        = NULL;
> +  S3DispatchHandle        = NULL;
> +  S4DispatchHandle        = NULL;
> +  S5DispatchHandle        = NULL;
> +
> +   Status = gSmst->SmmLocateProtocol (
> +                    &gEfiSmmSxDispatch2ProtocolGuid,
> +                    NULL,
> +                    (VOID **) &SxDispatchProtocol
> +                    );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register S3 entry phase call back function
> +  //
> +  EntryDispatchContext.Type   = SxS3;
> +  EntryDispatchContext.Phase  = SxEntry;
> +  Status = SxDispatchProtocol->Register (
> +                                SxDispatchProtocol,
> +                                SxHandler,
> +                                &EntryDispatchContext,
> +                                &S3DispatchHandle
> +                                );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register S4 entry phase call back function
> +  //
> +  EntryDispatchContext.Type   = SxS4;
> +  EntryDispatchContext.Phase  = SxEntry;
> +  Status = SxDispatchProtocol->Register (
> +                                SxDispatchProtocol,
> +                                SxHandler,
> +                                &EntryDispatchContext,
> +                                &S4DispatchHandle
> +                                );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register S5 entry phase call back function
> +  //
> +  EntryDispatchContext.Type   = SxS5;
> +  EntryDispatchContext.Phase  = SxEntry;
> +  Status = SxDispatchProtocol->Register (
> +                                SxDispatchProtocol,
> +                                SxHandler,
> +                                &EntryDispatchContext,
> +                                &S5DispatchHandle
> +                                );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Locate the SMM SW dispatch protocol
> +  //
> +  Status = gSmst->SmmLocateProtocol (
> +                    &gEfiSmmSwDispatch2ProtocolGuid,
> +                    NULL,
> +                    (VOID **) &SwDispatch
> +                    );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register SWSMI handler
> +  //
> +  SwContext.SwSmiInputValue = SmiInputValue;
> +  Status = SwDispatch->Register (
> +                        SwDispatch,
> +                        SwHandler,
> +                        &SwContext,
> +                        &SwDispatchHandle
> +                        );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +EFI_STATUS
> +InSmmFunction (
> +  IN  EFI_HANDLE        ImageHandle,
> +  IN  EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                    Status;
> +
> +  Status = EFI_SUCCESS;
> +
> +  Status = TbtRegisterHandlers(DTBT_CONTROLLER);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TbtSmmEntryPoint (
> +  IN EFI_HANDLE               ImageHandle,
> +  IN EFI_SYSTEM_TABLE         *SystemTable
> +  )
> +{
> +  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
> +  EFI_STATUS                    Status;
> +
> +  DEBUG ((DEBUG_INFO, "TbtSmmEntryPoint\n"));
> +
> +  mPciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
> +  //
> +  // Locate Tbt shared data area
> +  //
> +  Status = gBS->LocateProtocol (&gTbtNvsAreaProtocolGuid, NULL, (VOID **)
> &TbtNvsAreaProtocol);
> +  ASSERT_EFI_ERROR (Status);
> +  mTbtNvsAreaPtr = TbtNvsAreaProtocol->Area;
> +
> +  //
> +  // Get TBT INFO HOB
> +  //
> +  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +  if (gTbtInfoHob == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return InSmmFunction (ImageHandle, SystemTable);
> +}
> +
> +VOID
> +EndOfThunderboltCallback (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  if(mTbtNvsAreaPtr->TbtL1SubStates != 0) {
> +    ThunderboltEnableL1Sub (mTbtNvsAreaPtr->TbtL1SubStates, RpSegment,
> RpBus, RpDevice, RpFunction);
> +  }
> +  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 1);
> +  if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
> +    ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice,
> RpFunction);
> +  } else { //Aspm enable case
> +    ThunderboltEnableAspmWithoutLtr
> ((UINT16)mTbtNvsAreaPtr->TbtAspm, RpSegment, RpBus, RpDevice,
> RpFunction);
> +  }
> +
> +  if (mTbtNvsAreaPtr->TbtLtr) {
> +    ThunderboltGetLatencyLtr ();
> +    ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +  }
> +  ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 2);
> +} // EndOfThunderboltCallback
> +
> +VOID
> +ConfigureTbtAspm (
> +  IN UINT8        Type,
> +  IN UINT16       Aspm
> +  )
> +{
> +  UINTN                         RpSegment = 0;
> +  UINTN                         RpBus = 0;
> +  UINTN                         RpDevice;
> +  UINTN                         RpFunction;
> +
> +  if(Type == DTBT_CONTROLLER) {
> +    if (gCurrentDiscreteTbtRootPort == 0) {
> +      return;
> +    }
> +    GetDTbtRpDevFun(DTBT_CONTROLLER, gCurrentDiscreteTbtRootPort - 1,
> &RpDevice, &RpFunction);
> +
> +    ConfigureTbtPm (RpSegment, RpBus, RpDevice, RpFunction, 1);
> +    if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
> +      ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice,
> RpFunction);
> +    } else { //Aspm enable case
> +      ThunderboltEnableAspmWithoutLtr ((UINT16) Aspm, RpSegment, RpBus,
> RpDevice, RpFunction);
> +    }
> +
> +  if (mTbtNvsAreaPtr->TbtLtr) {
> +      ThunderboltGetLatencyLtr ();
> +      ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +    }
> +    ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +  } // EndOfThunderboltCallback
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimer
> Lib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTime
> rLib.c
> new file mode 100644
> index 0000000000..ec06eee73f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTime
> rLib.c
> @@ -0,0 +1,394 @@
> +/** @file
> +  ACPI Timer implements one instance of Timer Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Library/TimerLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <IndustryStandard/Acpi.h>
> +//
> +// OVERRIDE: OverrideBegin
> +//
> +#include <Register/Cpuid.h>
> +//
> +// OVERRIDE: OverrideEnd
> +//
> +
> +
> +/**
> +  Internal function to retrieves the 64-bit frequency in Hz.
> +
> +  Internal function to retrieves the 64-bit frequency in Hz.
> +
> +  @return The frequency in Hz.
> +
> +**/
> +UINT64
> +InternalGetPerformanceCounterFrequency (
> +  VOID
> +  );
> +
> +/**
> +  The constructor function enables ACPI IO space.
> +
> +  If ACPI I/O space not enabled, this function will enable it.
> +  It will always return RETURN_SUCCESS.
> +
> +  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +AcpiTimerLibConstructor (
> +  VOID
> +  )
> +{
> +  UINTN   Bus;
> +  UINTN   Device;
> +  UINTN   Function;
> +  UINTN   EnableRegister;
> +  UINT8   EnableMask;
> +
> +  //
> +  // ASSERT for the invalid PCD values. They must be configured to the real
> value.
> +  //
> +  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);
> +  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);
> +
> +  //
> +  // If the register offset to the BAR for the ACPI I/O Port Base Address is
> 0x0000, then
> +  // no PCI register programming is required to enable access to the the ACPI
> registers
> +  // specified by PcdAcpiIoPortBaseAddress
> +  //
> +  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {
> +    return RETURN_SUCCESS;
> +  }
> +
> +  //
> +  // ASSERT for the invalid PCD values. They must be configured to the real
> value.
> +  //
> +  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);
> +  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);
> +  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);
> +
> +  //
> +  // Retrieve the PCD values for the PCI configuration space required to
> program the ACPI I/O Port Base Address
> +  //
> +  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);
> +  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);
> +  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);
> +  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);
> +  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);
> +
> +  //
> +  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and
> enable it.
> +  //
> +  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister)) &
> EnableMask) != EnableMask) {
> +    PciWrite16 (
> +      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16
> (PcdAcpiIoPciBarRegisterOffset)),
> +      PcdGet16 (PcdAcpiIoPortBaseAddress)
> +      );
> +    PciOr8 (
> +      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),
> +      EnableMask
> +      );
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Internal function to retrieve the ACPI I/O Port Base Address.
> +
> +  Internal function to retrieve the ACPI I/O Port Base Address.
> +
> +  @return The 16-bit ACPI I/O Port Base Address.
> +
> +**/
> +UINT16
> +InternalAcpiGetAcpiTimerIoPort (
> +  VOID
> +  )
> +{
> +  UINT16  Port;
> +
> +  Port = PcdGet16 (PcdAcpiIoPortBaseAddress);
> +
> +  //
> +  // If the register offset to the BAR for the ACPI I/O Port Base Address is not
> 0x0000, then
> +  // read the PCI register for the ACPI BAR value in case the BAR has been
> programmed to a
> +  // value other than PcdAcpiIoPortBaseAddress
> +  //
> +  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {
> +    Port = PciRead16 (PCI_LIB_ADDRESS (
> +                        PcdGet8  (PcdAcpiIoPciBusNumber),
> +                        PcdGet8  (PcdAcpiIoPciDeviceNumber),
> +                        PcdGet8  (PcdAcpiIoPciFunctionNumber),
> +                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)
> +                        ));
> +  }
> +
> +  return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16
> (PcdAcpiPm1TmrOffset);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of ticks.
> +
> +  Stalls the CPU for at least the given number of ticks. It's invoked by
> +  MicroSecondDelay() and NanoSecondDelay().
> +
> +  @param  Delay     A period of time to delay in ticks.
> +
> +**/
> +VOID
> +InternalAcpiDelay (
> +  IN UINT32  Delay
> +  )
> +{
> +  UINT16   Port;
> +  UINT32   Ticks;
> +  UINT32   Times;
> +
> +  Port   = InternalAcpiGetAcpiTimerIoPort ();
> +  Times  = Delay >> 22;
> +  Delay &= BIT22 - 1;
> +  do {
> +    //
> +    // The target timer count is calculated here
> +    //
> +    Ticks = IoBitFieldRead32 (Port, 0, 23) + Delay;
> +    Delay = BIT22;
> +    //
> +    // Wait until time out
> +    // Delay >= 2^23 could not be handled by this function
> +    // Timer wrap-arounds are handled correctly by this function
> +    //
> +    while (((Ticks - IoBitFieldRead32 (Port, 0, 23)) & BIT23) == 0) {
> +      CpuPause ();
> +    }
> +  } while (Times-- > 0);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of microseconds.
> +
> +  Stalls the CPU for the number of microseconds specified by MicroSeconds.
> +
> +  @param  MicroSeconds  The minimum number of microseconds to delay.
> +
> +  @return MicroSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +MicroSecondDelay (
> +  IN UINTN  MicroSeconds
> +  )
> +{
> +  InternalAcpiDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                MicroSeconds,
> +                ACPI_TIMER_FREQUENCY
> +                ),
> +              1000000u
> +              )
> +    );
> +  return MicroSeconds;
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of nanoseconds.
> +
> +  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
> +
> +  @param  NanoSeconds The minimum number of nanoseconds to delay.
> +
> +  @return NanoSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +NanoSecondDelay (
> +  IN UINTN  NanoSeconds
> +  )
> +{
> +  InternalAcpiDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                NanoSeconds,
> +                ACPI_TIMER_FREQUENCY
> +                ),
> +              1000000000u
> +              )
> +    );
> +  return NanoSeconds;
> +}
> +
> +/**
> +  Retrieves the current value of a 64-bit free running performance counter.
> +
> +  Retrieves the current value of a 64-bit free running performance counter.
> The
> +  counter can either count up by 1 or count down by 1. If the physical
> +  performance counter counts by a larger increment, then the counter values
> +  must be translated. The properties of the counter can be retrieved from
> +  GetPerformanceCounterProperties().
> +
> +  @return The current value of the free running performance counter.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounter (
> +  VOID
> +  )
> +{
> +  return AsmReadTsc ();
> +}
> +
> +/**
> +  Retrieves the 64-bit frequency in Hz and the range of performance counter
> +  values.
> +
> +  If StartValue is not NULL, then the value that the performance counter starts
> +  with immediately after is it rolls over is returned in StartValue. If
> +  EndValue is not NULL, then the value that the performance counter end with
> +  immediately before it rolls over is returned in EndValue. The 64-bit
> +  frequency of the performance counter in Hz is always returned. If StartValue
> +  is less than EndValue, then the performance counter counts up. If StartValue
> +  is greater than EndValue, then the performance counter counts down. For
> +  example, a 64-bit free running counter that counts up would have a
> StartValue
> +  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
> +  that counts down would have a StartValue of 0xFFFFFF and an EndValue of
> 0.
> +
> +  @param  StartValue  The value the performance counter starts with when
> it
> +                      rolls over.
> +  @param  EndValue    The value that the performance counter ends with
> before
> +                      it rolls over.
> +
> +  @return The frequency in Hz.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounterProperties (
> +  OUT UINT64  *StartValue,  OPTIONAL
> +  OUT UINT64  *EndValue     OPTIONAL
> +  )
> +{
> +  if (StartValue != NULL) {
> +    *StartValue = 0;
> +  }
> +
> +  if (EndValue != NULL) {
> +    *EndValue = 0xffffffffffffffffULL;
> +  }
> +  return InternalGetPerformanceCounterFrequency ();
> +}
> +
> +/**
> +  Converts elapsed ticks of performance counter to time in nanoseconds.
> +
> +  This function converts the elapsed ticks of running performance counter to
> +  time value in unit of nanoseconds.
> +
> +  @param  Ticks     The number of elapsed ticks of running performance
> counter.
> +
> +  @return The elapsed time in nanoseconds.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetTimeInNanoSecond (
> +  IN UINT64  Ticks
> +  )
> +{
> +  UINT64  Frequency;
> +  UINT64  NanoSeconds;
> +  UINT64  Remainder;
> +  INTN    Shift;
> +  Frequency = GetPerformanceCounterProperties (NULL, NULL);
> +
> +  //
> +  //          Ticks
> +  // Time = --------- x 1,000,000,000
> +  //        Frequency
> +  //
> +  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency,
> &Remainder), 1000000000u);
> +
> +  //
> +  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
> +  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should <
> 2^(64-30) = 2^34,
> +  // i.e. highest bit set in Remainder should <= 33.
> +  //
> +  Shift = MAX (0, HighBitSet64 (Remainder) - 33);
> +  Remainder = RShiftU64 (Remainder, (UINTN) Shift);
> +  Frequency = RShiftU64 (Frequency, (UINTN) Shift);
> +  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder,
> 1000000000u), Frequency, NULL);
> +
> +  return NanoSeconds;
> +}
> +
> +//
> +// OVERRIDE: OverrideBegin
> +//
> +/**
> +  Calculate TSC frequency.
> +
> +  The TSC counting frequency is determined by using CPUID leaf 0x15 that is
> the preferred
> +  method for Skylake and beyond.  Frequency in MHz = Core XTAL frequency
> * EBX/EAX.
> +  In newer flavors of the CPU, core xtal frequency is returned in ECX (or 0 if not
> +  supported).  If ECX is 0, 24MHz is assumed.
> +  @return The number of TSC counts per second.
> +
> +**/
> +UINT64
> +InternalCalculateTscFrequency (
> +  VOID
> +  )
> +{
> +  UINT64      TscFrequency;
> +  UINT64      CoreXtalFrequency;
> +  UINT32      RegEax;
> +  UINT32      RegEbx;
> +  UINT32      RegEcx;
> +
> +  //
> +  // Use CPUID leaf 0x15.
> +  // TSC frequency = (Core Xtal Frequency) * EBX/EAX.  EBX returns 0 if not
> +  // supported. ECX, if non zero, provides Core Xtal Frequency in hertz
> +  // (SDM Dec 2016).
> +  //
> +  AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx,
> NULL);
> +  ASSERT (RegEbx != 0);
> +
> +  //
> +  // If core xtal frequency (ECX) returns 0, it is safe to use 24MHz for post
> +  // Skylake client CPU's.
> +  //
> +  if (RegEcx == 0) {
> +    CoreXtalFrequency = 24000000ul;
> +  } else {
> +    CoreXtalFrequency = (UINT64)RegEcx;
> +  }
> +
> +  //
> +  // Calculate frequency.  For integer division, round up/down result
> +  // correctly by adding denominator/2 to the numerator prior to division.
> +  //
> +  TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) +
> (UINT64)(RegEax >> 1), RegEax);
> +
> +  return TscFrequency;
> +}
> +//
> +// OVERRIDE: OverrideEnd
> +//
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.c
> new file mode 100644
> index 0000000000..2bba58eed3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.c
> @@ -0,0 +1,612 @@
> +/** @file
> +  Source code for the board configuration init function in DXE init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BoardInitLib.h"
> +#include <Library/HobLib.h>
> +#include <MemInfoHob.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <PlatformBoardConfig.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchEspiLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <TbtBoardInfo.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <GopConfigLib.h>
> +//
> +// Null function for nothing GOP VBT update.
> +//
> +VOID
> +GopVbtSpecificUpdateNull(
> +  IN CHILD_STRUCT **ChildStructPtr
> +);
> +
> +//
> +// for CFL U DDR4
> +//
> +VOID
> +CflUDdr4GopVbtSpecificUpdate(
> +  IN CHILD_STRUCT **ChildStructPtr
> +);
> +
> +/**
> +  Updates DIMM slots status for Desktop,server and workstation boards
> +
> +**/
> +VOID
> +UpdateDimmPopulationConfig(
> +  VOID
> +  )
> +{
> +  MEMORY_INFO_DATA_HOB    *MemInfo;
> +  UINT8                   Slot0;
> +  UINT8                   Slot1;
> +  UINT8                   Slot2;
> +  UINT8                   Slot3;
> +  CONTROLLER_INFO         *ControllerInfo;
> +  EFI_HOB_GUID_TYPE       *GuidHob;
> +
> +  GuidHob = NULL;
> +  MemInfo = NULL;
> +
> +  GuidHob = GetFirstGuidHob (&gSiMemoryInfoDataGuid);
> +  ASSERT (GuidHob != NULL);
> +  if (GuidHob != NULL) {
> +    MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA
> (GuidHob);
> +  }
> +  if (MemInfo != NULL) {
> +    if (PcdGet8 (PcdPlatformFlavor) == FlavorDesktop ||
> +        PcdGet8 (PcdPlatformFlavor) == FlavorUpServer ||
> +        PcdGet8 (PcdPlatformFlavor) == FlavorWorkstation) {
> +      ControllerInfo = &MemInfo->Controller[0];
> +      Slot0 = ControllerInfo->ChannelInfo[0].DimmInfo[0].Status;
> +      Slot1 = ControllerInfo->ChannelInfo[0].DimmInfo[1].Status;
> +      Slot2 = ControllerInfo->ChannelInfo[1].DimmInfo[0].Status;
> +      Slot3 = ControllerInfo->ChannelInfo[1].DimmInfo[1].Status;
> +
> +      //
> +      // Channel 0          Channel 1
> +      // Slot0   Slot1      Slot0   Slot1      - Population            AIO board
> +      // 0          0          0          0          - Invalid        - Invalid
> +      // 0          0          0          1          - Valid          - Invalid
> +      // 0          0          1          0          - Invalid        - Valid
> +      // 0          0          1          1          - Valid          - Valid
> +      // 0          1          0          0          - Valid          - Invalid
> +      // 0          1          0          1          - Valid          - Invalid
> +      // 0          1          1          0          - Invalid        - Invalid
> +      // 0          1          1          1          - Valid          - Invalid
> +      // 1          0          0          0          - Invalid        - Valid
> +      // 1          0          0          1          - Invalid        - Invalid
> +      // 1          0          1          0          - Invalid        - Valid
> +      // 1          0          1          1          - Invalid        - Valid
> +      // 1          1          0          0          - Valid          - Valid
> +      // 1          1          0          1          - Valid          - Invalid
> +      // 1          1          1          0          - Invalid        - Valid
> +      // 1          1          1          1          - Valid          - Valid
> +      //
> +
> +      if ((Slot0 && (Slot1 == 0)) || (Slot2 && (Slot3 == 0))) {
> +        PcdSetBoolS (PcdDimmPopulationError, TRUE);
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  Init Misc Platform Board Config Block.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardMiscInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +//  PcdSet64S (PcdFuncBoardHookPlatformSetupOverride, (UINT64) (UINTN)
> BoardHookPlatformSetup);
> +
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdPssReadSN, TRUE);
> +      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
> +      PcdSet8S (PcdPssI2cBusNumber, 0x04);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdPssReadSN, FALSE);
> +      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
> +      PcdSet8S (PcdPssI2cBusNumber, 0x04);
> +      break;
> +  }
> +
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Init Platform Board Config Block for ACPI platform.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +InitAcpiPlatformPcd (
> +  IN UINT16 BoardId
> +  )
> +{
> +  TBT_INFO_HOB  *TbtInfoHob = NULL;
> +
> +  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +
> +  //
> +  // Update OEM table ID
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      if ((TbtInfoHob != NULL) &&
> (TbtInfoHob->DTbtControllerConfig[0].DTbtControllerEn == 1)) {
> +        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h',
> 'l', 't', '4'));
> +      } else {
> +        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h',
> 'l', 'd', '4'));
> +      }
> +      break;
> +    default:
> +      PcdSet64S (PcdXhciAcpiTableSignature, 0);
> +      break;
> +  }
> +
> +  //
> +  // Modify Preferred_PM_Profile field based on Board SKU's. Default is set to
> Mobile
> +  //
> +  PcdSet8S (PcdPreferredPmProfile, EFI_ACPI_2_0_PM_PROFILE_MOBILE);
> +
> +  //
> +  // Assign FingerPrint, Gnss, TouchPanel, Audio related GPIO.
> +  //
> +  switch(BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdFingerPrintSleepGpio, GPIO_CNL_LP_GPP_B17);
> +      PcdSet32S (PcdFingerPrintIrqGpio,   GPIO_CNL_LP_GPP_B16);
> +      //
> +      // Configure WWAN Reset pin
> +      //
> +      PcdSet32S (PcdGnssResetGpio,      GPIO_CNL_LP_GPP_F1);
> +      PcdSet32S (PcdTouchpanelIrqGpio,  GPIO_CNL_LP_GPP_D10);
> +      PcdSet32S (PcdTouchpadIrqGpio,    GPIO_CNL_LP_GPP_B3);
> +      PcdSet32S (PcdHdaI2sCodecIrqGpio, GPIO_CNL_LP_GPP_C8);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // Configure GPIOs for discrete USB BT module
> +  //
> +  switch(BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdBtIrqGpio,    GPIO_CNL_LP_GPP_B2);
> +      PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // Board Specific Init
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS(PcdWhlErbRtd3TableEnable, TRUE);
> +      PcdSet8S (PcdHdaI2sCodecI2cBusNumber, 0); // I2S Audio Codec
> conntected to I2C0
> +      PcdSet8S (PcdBleUsbPortNumber, 9);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Init Common Platform Board Config Block.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +InitCommonPlatformPcd (
> +  IN UINT16 BoardId
> +  )
> +{
> +  PCD64_BLOB Data64;
> +  TBT_INFO_HOB  *TbtInfoHob = NULL;
> +
> +  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +
> +
> +  //
> +  // Enable EC SMI# for SMI
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdEcSmiGpio, GPIO_CNL_LP_GPP_E3);
> +      PcdSet32S (PcdEcLowPowerExitGpio, GPIO_CNL_LP_GPP_B23);
> +      break;
> +  };
> +
> +  //
> +  // HID I2C Interrupt GPIO.
> +  //
> +  switch (BoardId) {
> +    default:
> +      // on all supported boards interrupt input is on same GPIO pad. How
> convenient.
> +      PcdSet32S (PcdHidI2cIntPad, GPIO_CNL_LP_GPP_D10);
> +      break;
> +  }
> +
> +  //
> +  // PS2 KB Specific Init for Sds Serial platform.
> +  //
> +  if (BoardId == BoardIdWhiskeyLakeRvp) {
> +    PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE);
> +  } else {
> +    PcdSetBoolS (PcdDetectPs2KbOnCmdAck,  FALSE);
> +  }
> +
> +  switch (BoardId) {
> +    default:
> +      PcdSetBoolS (PcdSpdAddressOverride, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // DDISelection
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdDDISelection, 1);
> +      break;
> +    default:
> +      PcdSet8S (PcdDDISelection, 0);
> +      break;
> +  }
> +
> +  //
> +  // GFX Detect
> +  //
> +  switch (BoardId) {
> +    default:
> +      // Not all the boards support GFX_CRB_DET. This is not an error.
> +      Data64.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
> +      break;
> +  }
> +
> +  PcdSet64S (PcdGfxCrbDetectGpio, Data64.Blob);
> +
> +  //
> +  // USB Type-C
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS(PcdUsbTypeCSupport, TRUE);
> +      // Discete Ports
> +      PcdSet8S(PcdTypeCPortsSupported, 2);
> +      // TBT Port 1  mapping and properties [TBT AIC]
> +      PcdSet8S(PcdUsbTypeCPort1, 1);
> +      PcdSet8S(PcdUsbTypeCPort1Pch, 5);
> +      // TBT Port 2  mapping and properties [TBT AIC]
> +      PcdSet8S(PcdUsbTypeCPort2, 2);
> +      PcdSet8S(PcdUsbTypeCPort2Pch, 7);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdUsbTypeCSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Battery Present
> +  //
> +  switch (BoardId) {
> +  default:
> +    PcdSet8S (PcdBatteryPresent, BOARD_REAL_BATTERY_SUPPORTED |
> BOARD_VIRTUAL_BATTERY_SUPPORTED);
> +    break;
> +  }
> +
> +  //
> +  // TS-on-DIMM temperature
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdTsOnDimmTemperature, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdTsOnDimmTemperature, FALSE);
> +      break;
> +  }
> +  //
> +  // Real Battery 1 Control & Real Battery 2 Control
> +  //
> +  PcdSet8S (PcdRealBattery1Control, 1);
> +  PcdSet8S (PcdRealBattery2Control, 2);
> +
> +  //
> +  // Mipi Camera Sensor
> +  //
> +  PcdSetBoolS (PcdMipiCamSensor, FALSE);
> +  //
> +  // Mipi Camera Sensor Link Used
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdMipiCam0LinkUsed, 3);
> +      PcdSet8S (PcdMipiCam1LinkUsed, 6);
> +      PcdSet8S (PcdMipiCam2LinkUsed, 9);
> +      PcdSet8S (PcdMipiCam3LinkUsed, 7);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // H8S2113 SIO
> +  //
> +  switch(BoardId) {
> +    default:
> +    PcdSetBoolS (PcdH8S2113SIO, FALSE);
> +    break;
> +  }
> +
> +
> +  //
> +  // NCT6776F COM, SIO & HWMON
> +  //
> +  PcdSetBoolS (PcdNCT6776FCOM, FALSE);
> +  PcdSetBoolS (PcdNCT6776FSIO, FALSE);
> +  PcdSetBoolS (PcdNCT6776FHWMON, FALSE);
> +
> +  //
> +  // SMC Runtime Sci Pin
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdSmcRuntimeSciPin, (UINT32) GPIO_CNL_LP_GPP_E16);
> +      break;
> +    default:
> +      PcdSet32S (PcdSmcRuntimeSciPin, 0x00);
> +      break;
> +  }
> +
> +  //
> +  // Convertable Dock Support
> +  //
> +  switch (BoardId) {
> +    default:
> +      PcdSetBoolS (PcdConvertableDockSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Ec Hotkey F3, F4, F5, F6, F7 and F8 Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdEcHotKeyF3Support, 1);
> +      PcdSet8S (PcdEcHotKeyF4Support, 1);
> +      PcdSet8S (PcdEcHotKeyF5Support, 1);
> +      PcdSet8S (PcdEcHotKeyF6Support, 1);
> +      PcdSet8S (PcdEcHotKeyF7Support, 1);
> +      PcdSet8S (PcdEcHotKeyF8Support, 1);
> +      break;
> +    default:
> +      PcdSet8S (PcdEcHotKeyF3Support, 0);
> +      PcdSet8S (PcdEcHotKeyF4Support, 0);
> +      PcdSet8S (PcdEcHotKeyF5Support, 0);
> +      PcdSet8S (PcdEcHotKeyF6Support, 0);
> +      PcdSet8S (PcdEcHotKeyF7Support, 0);
> +      PcdSet8S (PcdEcHotKeyF8Support, 0);
> +      break;
> +  }
> +
> +  //
> +  // Virtual Button Volume Up & Done Support
> +  // Virtual Button Home Button Support
> +  // Virtual Button Rotation Lock Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, TRUE);
> +      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, TRUE);
> +      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Slate Mode Switch Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdSlateModeSwitchSupport, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdSlateModeSwitchSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Ac Dc Auto Switch Support
> +  //
> +  switch (BoardId) {
> +  default:
> +    PcdSetBoolS (PcdAcDcAutoSwitchSupport, TRUE);
> +    break;
> +  }
> +
> +  //
> +  // Pm Power Button Gpio Pin
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3);
> +      break;
> +    default:
> +      PcdSet32S (PcdPmPowerButtonGpioPin, 0x00);
> +      break;
> +  }
> +
> +  //
> +  // Acpi Enable All Button Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Acpi Hid Driver Button Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // USB Type C EC less
> +  //
> +  switch (BoardId) {
> +    default:
> +      PcdSetBoolS (PcdUsbTypeCEcLess, FALSE);
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check if given rootport has device connected and enable wake capability
> +
> +  @param[in]  RpNum           An unsigned integer represent the root port
> number.
> +
> +  @retval                     TRUE if endpoint was connected
> +  @retval                     FALSE if no endpoint was detected
> +**/
> +BOOLEAN
> +IsPcieEndPointPresent (
> +  IN UINT8 RpNum
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINTN         RpDev;
> +  UINTN         RpFun;
> +  UINT64        RpBaseAddress;
> +
> +  Status = GetPchPcieRpDevFun (RpNum, &RpDev, &RpFun);
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // check if device is present
> +    //
> +    RpBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                      DEFAULT_PCI_BUS_NUMBER_PCH,
> +                      RpDev,
> +                      RpFun,
> +                      0
> +                      );
> +
> +    if ((PciSegmentRead16 (RpBaseAddress) != 0xFFFF) &&
> +        (PciSegmentRead16 (RpBaseAddress + R_PCH_PCIE_CFG_SLSTS) &
> B_PCIE_SLSTS_PDS)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +
> +}
> +
> +/**
> +  Enable Tier2 GPIO Sci wake capability.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +Tier2GpioWakeSupport (
> +  IN UINT16 BoardId
> +  )
> +{
> +  BOOLEAN Tier2GpioWakeEnable;
> +
> +  Tier2GpioWakeEnable = FALSE;
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      //
> +      // Root port #14: M.2 WLAN
> +      //
> +      if (IsPcieEndPointPresent (13)) {
> +        Tier2GpioWakeEnable = TRUE;
> +      }
> +      break;
> +    default:
> +      break;
> +  }
> +  PcdSetBoolS (PcdGpioTier2WakeEnable, Tier2GpioWakeEnable);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Board configuration init function for DXE phase.
> +
> +  @param  Content  pointer to the buffer contain init information for board
> init.
> +
> +  @retval EFI_SUCCESS             The function completed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BoardConfigInit (
> +    VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT16     BoardId;
> +
> +  BoardId = BoardIdWhiskeyLakeRvp;
> +
> +  Status = InitAcpiPlatformPcd (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = InitCommonPlatformPcd (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = BoardMiscInit (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = Tier2GpioWakeSupport (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.c
> new file mode 100644
> index 0000000000..eb7c3bbea0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.c
> @@ -0,0 +1,46 @@
> +/** @file
> +  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <CpuPolicyInitDxe.h>
> +
> +DXE_CPU_POLICY_PROTOCOL mCpuPolicyData;
> +
> +/**
> +  Initialize Intel CPU DXE Platform Policy
> +
> +  @param[in] ImageHandle        Image handle of this driver.
> +
> +  @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
> +CpuPolicyInitDxe (
> +  IN EFI_HANDLE       ImageHandle
> +  )
> +{
> +  EFI_STATUS                Status;
> +
> +  ZeroMem(&mCpuPolicyData, sizeof (DXE_CPU_POLICY_PROTOCOL));
> +  mCpuPolicyData.Revision                         =
> DXE_CPU_POLICY_PROTOCOL_REVISION;
> +
> +  UpdateDxeSiCpuPolicy(&mCpuPolicyData);
> +
> +  //
> +  // Install CpuInstallPolicyProtocol.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = CpuInstallPolicyProtocol(ImageHandle, &mCpuPolicyData);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.c
> new file mode 100644
> index 0000000000..66aab2d198
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.c
> @@ -0,0 +1,174 @@
> +/** @file
> +  This file initialises and Installs GopPolicy Protocol.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GopPolicyInitDxe.h"
> +#include <Protocol/GopPolicy.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL
> mGOPPolicy;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT32                     mVbtSize = 0;
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS
> mVbtAddress = 0;
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +
> +  @param[out] CurrentLidStatus
> +
> +  @retval     EFI_SUCCESS
> +  @retval     EFI_UNSUPPORTED
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +GetPlatformLidStatus (
> +  OUT LID_STATUS *CurrentLidStatus
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +
> +  @param[out] CurrentDockStatus
> +
> +  @retval     EFI_SUCCESS
> +  @retval     EFI_UNSUPPORTED
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetPlatformDockStatus (
> +  OUT DOCK_STATUS  CurrentDockStatus
> +  )
> +{
> +    return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +
> +  @param[out] VbtAddress
> +  @param[out] VbtSize
> +
> +  @retval     EFI_SUCCESS
> +  @retval     EFI_NOT_FOUND
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetVbtData (
> +  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
> +  OUT UINT32               *VbtSize
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINTN                         FvProtocolCount;
> +  EFI_HANDLE                    *FvHandles;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
> +  UINTN                         Index;
> +  UINT32                        AuthenticationStatus;
> +  UINT8                         *Buffer;
> +  UINTN                         VbtBufferSize;
> +
> +  Status = EFI_NOT_FOUND;
> +  if ( mVbtAddress == 0) {
> +    Fv           = NULL;
> +    Buffer       = 0;
> +    FvHandles    = NULL;
> +    Status = gBS->LocateHandleBuffer (
> +                    ByProtocol,
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    NULL,
> +                    &FvProtocolCount,
> +                    &FvHandles
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      for (Index = 0; Index < FvProtocolCount; Index++) {
> +        Status = gBS->HandleProtocol (
> +                        FvHandles[Index],
> +                        &gEfiFirmwareVolume2ProtocolGuid,
> +                        (VOID **) &Fv
> +                        );
> +        VbtBufferSize = 0;
> +        Status = Fv->ReadSection (
> +                       Fv,
> +                       PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
> +                       EFI_SECTION_RAW,
> +                       0,
> +                       (VOID **) &Buffer,
> +                       &VbtBufferSize,
> +                       &AuthenticationStatus
> +                       );
> +        if (!EFI_ERROR (Status)) {
> +          *VbtAddress = (EFI_PHYSICAL_ADDRESS)Buffer;
> +          *VbtSize = (UINT32)VbtBufferSize;
> +          mVbtAddress = *VbtAddress;
> +          mVbtSize = *VbtSize;
> +          Status = EFI_SUCCESS;
> +          break;
> +        }
> +      }
> +    } else {
> +      Status = EFI_NOT_FOUND;
> +    }
> +
> +    if (FvHandles != NULL) {
> +      FreePool (FvHandles);
> +      FvHandles = NULL;
> +    }
> +  } else {
> +    *VbtAddress = mVbtAddress;
> +    *VbtSize = mVbtSize;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +Initialize GOP DXE Policy
> +
> +@param[in] ImageHandle          Image handle of this driver.
> +
> +@retval EFI_SUCCESS             Initialization complete.
> +@retval 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
> +GopPolicyInitDxe (
> +  IN EFI_HANDLE       ImageHandle
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Initialize the EFI Driver Library
> +  //
> +  SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0);
> +
> +  mGOPPolicy.Revision                = GOP_POLICY_PROTOCOL_REVISION_03;
> +  mGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
> +  mGOPPolicy.GetVbtData              = GetVbtData;
> +  mGOPPolicy.GetPlatformDockStatus   = GetPlatformDockStatus;
> +
> +  //
> +  // Install protocol to allow access to this Policy.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gGopPolicyProtocolGuid,
> +                  &mGOPPolicy,
> +                  NULL
> +                  );
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyIn
> itDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.c
> new file mode 100644
> index 0000000000..2a1604fa13
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.c
> @@ -0,0 +1,55 @@
> +/** @file
> +  This file is SampleCode for PCH DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchPolicyInitDxe.h"
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  Initialize PCH DXE Policy
> +
> +  @param[in] ImageHandle          Image handle of this driver.
> +
> +  @retval EFI_SUCCESS             Initialization complete.
> +  @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
> +PchPolicyInitDxe (
> +  IN EFI_HANDLE                   ImageHandle
> +  )
> +{
> +  EFI_STATUS               Status;
> +  PCH_POLICY_PROTOCOL      *PchPolicy;
> +
> +  //
> +  // Call CreatePchDxeConfigBlocks to create & initialize platform policy
> structure
> +  // and get all Intel default policy settings.
> +  //
> +  Status = CreatePchDxeConfigBlocks (&PchPolicy);
> +  DEBUG((DEBUG_INFO, "PchPolicy->TableHeader.NumberOfBlocks =
> 0x%x\n", PchPolicy->TableHeader.NumberOfBlocks));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (mFirmwareConfiguration != FwConfigDefault) {
> +    UpdateDxePchPolicy (PchPolicy);
> +  }
> +
> +  //
> +  // Install PchInstallPolicyProtocol.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = PchInstallPolicyProtocol (ImageHandle, PchPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.c
> new file mode 100644
> index 0000000000..ccaa57ce16
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.c
> @@ -0,0 +1,88 @@
> +/** @file
> +  This file is a wrapper for Platform Policy driver. Get Setup
> +  Value to initialize Intel DXE Platform Policy.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PolicyInitDxe.h"
> +#include <CpuSmm.h>
> +#include "BoardInitLib.h"
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> mFirmwareConfiguration = 0;
> +
> +/**
> +  Initialize  DXE Platform Policy
> +
> +  @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
> +PolicyInitDxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS           Status;
> +
> +  Status = BoardConfigInit();
> +
> +  mFirmwareConfiguration = FwConfigProduction;
> +  //
> +  // SystemAgent Dxe Platform Policy Initialization
> +  //
> +  Status = SaPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "SystemAgent Dxe Platform Policy Initialization
> done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // PCH Dxe Platform Policy Initialization
> +  //
> +  Status = PchPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "PCH Dxe Platform Policy Initialization done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Silicon Dxe Platform Policy Initialization
> +  //
> +  Status = SiliconPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "Silicon Dxe Platform Policy Initialization done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // CPU DXE Platform Policy Initialization
> +  //
> +  Status = CpuPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "Cpu Dxe Platform Policy Initialization done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  if (PcdGetBool(PcdIntelGopEnable)) {
> +    //
> +    // GOP Dxe Policy Initialization
> +    //
> +    Status = GopPolicyInitDxe(ImageHandle);
> +    DEBUG((DEBUG_INFO, "GOP Dxe Policy Initialization done\n"));
> +    ASSERT_EFI_ERROR(Status);
> +  }
> +  if (PcdGetBool(PcdTbtEnable)) {
> +    //
> +    // Update TBT Policy
> +    //
> +    Status = InstallTbtPolicy (ImageHandle);
> +    DEBUG ((DEBUG_INFO, "Install Tbt Policy done\n"));
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  return Status;
> +
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.c
> new file mode 100644
> index 0000000000..c0095c09c3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.c
> @@ -0,0 +1,60 @@
> +/** @file
> +  This file is SampleCode for SA DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaPolicyInitDxe.h"
> +
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  Initialize SA DXE Policy
> +
> +  @param[in] ImageHandle          Image handle of this driver.
> +
> +  @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
> +SaPolicyInitDxe (
> +  IN EFI_HANDLE                   ImageHandle
> +  )
> +{
> +  EFI_STATUS               Status;
> +  SA_POLICY_PROTOCOL       *SaPolicy;
> +
> +  //
> +  // Call CreateSaDxeConfigBlocks to create & initialize platform policy
> structure
> +  // and get all Intel default policy settings.
> +  //
> +  Status = CreateSaDxeConfigBlocks(&SaPolicy);
> +  DEBUG((DEBUG_INFO, "SaPolicy->TableHeader.NumberOfBlocks = 0x%x\n ",
> SaPolicy->TableHeader.NumberOfBlocks));
> +  ASSERT_EFI_ERROR(Status);
> +
> +  UpdateDxeSaPolicyBoardConfig (SaPolicy);
> +
> +  if (mFirmwareConfiguration != FwConfigDefault) {
> +
> +    UpdateDxeSaPolicy (SaPolicy);
> +  }
> +
> +  //
> +  // Install SaInstallPolicyProtocol.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = SaInstallPolicyProtocol (ImageHandle, SaPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolic
> yInitDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.c
> new file mode 100644
> index 0000000000..15adca5cdd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.c
> @@ -0,0 +1,46 @@
> +/** @file
> +  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <SiliconPolicyInitDxe.h>
> +#include <Library/BaseLib.h>
> +
> +DXE_SI_POLICY_PROTOCOL mSiPolicyData  = { 0 };
> +
> +/**
> +  Initilize Intel Cpu DXE Platform Policy
> +
> +  @param[in] ImageHandle        Image handle of this driver.
> +
> +  @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
> +SiliconPolicyInitDxe (
> +  IN EFI_HANDLE       ImageHandle
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  mSiPolicyData.Revision                         =
> DXE_SI_POLICY_PROTOCOL_REVISION;
> +
> +  ///
> +  /// Install the DXE_SI_POLICY_PROTOCOL interface
> +  ///
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gDxeSiPolicyProtocolGuid,
> +                  &mSiPolicyData,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLU
> PD.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLU
> PD.asl
> new file mode 100644
> index 0000000000..7e44f5585a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLU
> PD.asl
> @@ -0,0 +1,20 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//////////////////////////////////////////////////////////////////////////////
> /////
> +//Values are set like this to have ASL compiler reserve enough space for
> objects
> +//////////////////////////////////////////////////////////////////////////////
> /////
> +//
> +// Available Sleep states
> +//
> +Name(SS1,0)
> +Name(SS2,0)
> +Name(SS3,1)
> +Name(SS4,1)
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.
> ASL
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.
> ASL
> new file mode 100644
> index 0000000000..dd85f07bd2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.
> ASL
> @@ -0,0 +1,37 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PlatformBoardId.h"
> +
> +DefinitionBlock (
> +  "DSDT.aml",
> +  "DSDT",
> +  0x02, // DSDT revision.
> +        // A Revision field value greater than or equal to 2 signifies that integers
> +        // declared within the Definition Block are to be evaluated as 64-bit
> values
> +  "INTEL",   // OEM ID (6 byte string)
> +  "WHL     ",// OEM table ID  (8 byte string)
> +  0x0 // OEM version of DSDT table (4 byte Integer)
> +)
> +
> +// BEGIN OF ASL SCOPE
> +{
> +  // Miscellaneous services enabled in Project
> +  Include ("AMLUPD.asl")
> +  Include ("PciTree.asl")
> +  Include ("Platform.asl")
> +
> +  Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state
> +  if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})}
> +  if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})}
> +  if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})}
> +  Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state
> +
> +}// End of ASL File
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostB
> us.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Host
> Bus.asl
> new file mode 100644
> index 0000000000..aa302b6e3b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Host
> Bus.asl
> @@ -0,0 +1,516 @@
> +/** @file
> +  This file contains the SystemAgent PCI Configuration space
> +  definition.
> +  It defines various System Agent PCI Configuration Space registers
> +  which will be used to dynamically produce all resources in the Host Bus.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Define various System Agent (SA) PCI Configuration Space
> +// registers which will be used to dynamically produce all
> +// resources in the Host Bus _CRS.
> +//
> +OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
> +Field (HBUS, DWordAcc, NoLock, Preserve)
> +{
> +  Offset(0x40),   // EPBAR (0:0:0:40)
> +  EPEN, 1,        // Enable
> +      , 11,
> +  EPBR, 20,       // EPBAR [31:12]
> +
> +  Offset(0x48),   // MCHBAR (0:0:0:48)
> +  MHEN, 1,        // Enable
> +      , 14,
> +  MHBR, 17,       // MCHBAR [31:15]
> +
> +  Offset(0x50),   // GGC (0:0:0:50)
> +  GCLK, 1,        // GGCLCK
> +
> +  Offset(0x54),   // DEVEN (0:0:0:54)
> +  D0EN, 1,        // DEV0 Enable
> +  D1F2, 1,        // DEV1 FUN2 Enable
> +  D1F1, 1,        // DEV1 FUN1 Enable
> +  D1F0, 1,        // DEV1 FUN0 Enable
> +
> +  Offset(0x60),   // PCIEXBAR (0:0:0:60)
> +  PXEN, 1,        // Enable
> +  PXSZ, 2,        // PCI Express Size
> +      , 23,
> +  PXBR, 6,        // PCI Express BAR [31:26]
> +
> +  Offset(0x68),   // DMIBAR (0:0:0:68)
> +  DIEN, 1,        // Enable
> +      , 11,
> +  DIBR, 20,       // DMIBAR [31:12]
> +
> +  Offset(0x70),   // MESEG_BASE (0:0:0:70)
> +      , 20,
> +  MEBR, 12,       // MESEG_BASE [31:20]
> +
> +  Offset(0x80),   // PAM0 Register (0:0:0:80)
> +  PMLK, 1,        // PAM Lock bit.
> +      , 3,
> +  PM0H, 2,        // PAM 0, High Nibble
> +      , 2,
> +
> +  Offset(0x81),   // PAM1 Register (0:0:0:81)
> +  PM1L, 2,        // PAM1, Low  Nibble
> +      , 2,
> +  PM1H, 2,        // PAM1, High Nibble
> +      , 2,
> +
> +  Offset(0x82),   // PAM2 Register (0:0:0:82)
> +  PM2L, 2,        // PAM2, Low  Nibble
> +      , 2,
> +  PM2H, 2,        // PAM2, High Nibble
> +      , 2,
> +
> +  Offset(0x83),   // PAM3 Register (0:0:0:83)
> +  PM3L, 2,        // PAM3, Low  Nibble
> +      , 2,
> +  PM3H, 2,        // PAM3, High Nibble
> +      , 2,
> +
> +  Offset(0x84),   // PAM4 Register (0:0:0:84)
> +  PM4L, 2,        // PAM4, Low  Nibble
> +      , 2,
> +  PM4H, 2,        // PAM4, High Nibble
> +      , 2,
> +
> +  Offset(0x85),   // PAM5 Register (0:0:0:85)
> +  PM5L, 2,        // PAM5, Low  Nibble
> +      , 2,
> +  PM5H, 2,        // PAM5, High Nibble
> +      , 2,
> +
> +  Offset(0x86),   // PAM6 Register (0:0:0:86)
> +  PM6L, 2,        // PAM6, Low  Nibble
> +      , 2,
> +  PM6H, 2,        // PAM6, High Nibble
> +      , 2,
> +
> +  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
> +      , 20,
> +  TUUD, 19,       // TOUUD [38:20]
> +
> +  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
> +      , 20,
> +  TLUD, 12,       // TOLUD [31:20]
> +
> +  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
> +      , 7,
> +  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
> +}
> +
> +//
> +// Define a buffer that will store all the bus, memory, and IO information
> +// relating to the Host Bus.  This buffer will be dynamically altered in
> +// the _CRS and passed back to the OS.
> +//
> +Name(BUF0,ResourceTemplate()
> +{
> +  //
> +  // Bus Number Allocation: Bus 0 to 0xFF
> +  //
> +  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
> +    0x0000,0x00FF,0x00,0x0100,,,PB00)
> +
> +  //
> +  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
> +
> +  //
> +  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
> +  //
> +  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
> +
> +  //
> +  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
> +
> +  //
> +  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
> +
> +  //
> +  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
> +
> +  //
> +  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
> +
> +  //
> +  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
> +
> +  //
> +  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
> +
> +  //
> +  // BIOS Area ( 0xF0000 - 0xFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
> +
> +//  //
> +//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
> +//  //
> +//
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
> +
> +  //
> +  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
> +
> +  //
> +  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
> +  // (This is dummy range for OS compatibility, will patch it in _CRS)
> +  //
> +
> QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
> +
> +  //
> +  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
> +})
> +
> +Name(EP_B, 0) // to store EP BAR
> +Name(MH_B, 0) // to store MCH BAR
> +Name(PC_B, 0) // to store PCIe BAR
> +Name(PC_L, 0) // to store PCIe BAR Length
> +Name(DM_B, 0) // to store DMI BAR
> +
> +//
> +// Get EP BAR
> +//
> +Method(GEPB,0,Serialized)
> +{
> +  if(LEqual(EP_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
> +  }
> +  Return(EP_B)
> +}
> +
> +//
> +// Get MCH BAR
> +//
> +Method(GMHB,0,Serialized)
> +{
> +  if(LEqual(MH_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
> +  }
> +  Return(MH_B)
> +}
> +
> +//
> +// Get PCIe BAR
> +//
> +Method(GPCB,0,Serialized)
> +{
> +  if(LEqual(PC_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
> +  }
> +  Return(PC_B)
> +}
> +
> +//
> +// Get PCIe Length
> +//
> +Method(GPCL,0,Serialized)
> +{
> +  if(LEqual(PC_L,0)) {
> +    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
> +  }
> +  Return(PC_L)
> +}
> +
> +//
> +// Get DMI BAR
> +//
> +Method(GDMB,0,Serialized)
> +{
> +  if(LEqual(DM_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
> +  }
> +  Return(DM_B)
> +}
> +
> +
> +Method(_CRS,0,Serialized)
> +{
> +  //
> +  // Fix up Max Bus Number and Length
> +  //
> +  Store(\_SB.PCI0.GPCL(),Local0)
> +  CreateWordField(BUF0, ^PB00._MAX, PBMX)
> +  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
> +  CreateWordField(BUF0, ^PB00._LEN, PBLN)
> +  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
> +  //
> +  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
> +  //
> +  If(PM1L)  // \_SB.PCI0
> +  {
> +    // PAMx != 0.  Set length = 0.
> +
> +    CreateDwordField(BUF0, ^C000._LEN,C0LN)
> +    Store(Zero,C0LN)
> +  }
> +
> +  If(LEqual(PM1L,1))
> +  {
> +    CreateBitField(BUF0, ^C000._RW,C0RW)
> +    Store(Zero,C0RW)
> +  }
> +
> +  If(PM1H)
> +  {
> +    CreateDwordField(BUF0, ^C400._LEN,C4LN)
> +    Store(Zero,C4LN)
> +  }
> +
> +  If(LEqual(PM1H,1))
> +  {
> +    CreateBitField(BUF0, ^C400._RW,C4RW)
> +    Store(Zero,C4RW)
> +  }
> +
> +  If(PM2L)
> +  {
> +    CreateDwordField(BUF0, ^C800._LEN,C8LN)
> +    Store(Zero,C8LN)
> +  }
> +
> +  If(LEqual(PM2L,1))
> +  {
> +    CreateBitField(BUF0, ^C800._RW,C8RW)
> +    Store(Zero,C8RW)
> +  }
> +
> +  If(PM2H)
> +  {
> +    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
> +    Store(Zero,CCLN)
> +  }
> +
> +  If(LEqual(PM2H,1))
> +  {
> +    CreateBitField(BUF0, ^CC00._RW,CCRW)
> +    Store(Zero,CCRW)
> +  }
> +
> +  If(PM3L)
> +  {
> +    CreateDwordField(BUF0, ^D000._LEN,D0LN)
> +    Store(Zero,D0LN)
> +  }
> +
> +  If(LEqual(PM3L,1))
> +  {
> +    CreateBitField(BUF0, ^D000._RW,D0RW)
> +    Store(Zero,D0RW)
> +  }
> +
> +  If(PM3H)
> +  {
> +    CreateDwordField(BUF0, ^D400._LEN,D4LN)
> +    Store(Zero,D4LN)
> +  }
> +
> +  If(LEqual(PM3H,1))
> +  {
> +    CreateBitField(BUF0, ^D400._RW,D4RW)
> +    Store(Zero,D4RW)
> +  }
> +
> +  If(PM4L)
> +  {
> +    CreateDwordField(BUF0, ^D800._LEN,D8LN)
> +    Store(Zero,D8LN)
> +  }
> +
> +  If(LEqual(PM4L,1))
> +  {
> +    CreateBitField(BUF0, ^D800._RW,D8RW)
> +    Store(Zero,D8RW)
> +  }
> +
> +  If(PM4H)
> +  {
> +    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
> +    Store(Zero,DCLN)
> +  }
> +
> +  If(LEqual(PM4H,1))
> +  {
> +    CreateBitField(BUF0, ^DC00._RW,DCRW)
> +    Store(Zero,DCRW)
> +  }
> +
> +  If(PM5L)
> +  {
> +    CreateDwordField(BUF0, ^E000._LEN,E0LN)
> +    Store(Zero,E0LN)
> +  }
> +
> +  If(LEqual(PM5L,1))
> +  {
> +    CreateBitField(BUF0, ^E000._RW,E0RW)
> +    Store(Zero,E0RW)
> +  }
> +
> +  If(PM5H)
> +  {
> +    CreateDwordField(BUF0, ^E400._LEN,E4LN)
> +    Store(Zero,E4LN)
> +  }
> +
> +  If(LEqual(PM5H,1))
> +  {
> +    CreateBitField(BUF0, ^E400._RW,E4RW)
> +    Store(Zero,E4RW)
> +  }
> +
> +  If(PM6L)
> +  {
> +    CreateDwordField(BUF0, ^E800._LEN,E8LN)
> +    Store(Zero,E8LN)
> +  }
> +
> +  If(LEqual(PM6L,1))
> +  {
> +    CreateBitField(BUF0, ^E800._RW,E8RW)
> +    Store(Zero,E8RW)
> +  }
> +
> +  If(PM6H)
> +  {
> +    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
> +    Store(Zero,ECLN)
> +  }
> +
> +  If(LEqual(PM6H,1))
> +  {
> +    CreateBitField(BUF0, ^EC00._RW,ECRW)
> +    Store(Zero,ECRW)
> +  }
> +
> +  If(PM0H)
> +  {
> +    CreateDwordField(BUF0, ^F000._LEN,F0LN)
> +    Store(Zero,F0LN)
> +  }
> +
> +  If(LEqual(PM0H,1))
> +  {
> +    CreateBitField(BUF0, ^F000._RW,F0RW)
> +    Store(Zero,F0RW)
> +  }
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  //
> +  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
> +  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
> +  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
> +
> +  //
> +  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
> +  // TOM, so shift these bits into the correct position and fix up
> +  // the Memory Region available to PCI.
> +  //
> +  Store (0x50800000, M1LN)
> +  Store (0x8F800000, M1MN)
> +  Subtract (Add (M1MN, M1LN), 1, M1MX)
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  // Patch PM02 range basing on memory size and OS type
> +  //
> +  CreateQwordField(BUF0, ^PM02._LEN,MSLN)
> +  //
> +  // Set resource length to 0
> +  //
> +  Store (0, MSLN)
> +
> +  D8XH (0, 0xC5)
> +  D8XH (1, 0xAA)
> +
> +  Return(BUF0)
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTre
> e.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTre
> e.asl
> new file mode 100644
> index 0000000000..ff3b0dbe08
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTre
> e.asl
> @@ -0,0 +1,309 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +Scope(\_SB) {
> +  Name(PD00, Package(){
> +// If the setting changed in PCH PxRcConfig policy, platform should also
> update static assignment here.
> +// PCI Bridge
> +// D31: cAVS, SMBus, GbE, Nothpeak
> +    Package(){0x001FFFFF, 0, 0, 11 },
> +    Package(){0x001FFFFF, 1, 0, 10 },
> +    Package(){0x001FFFFF, 2, 0, 11 },
> +    Package(){0x001FFFFF, 3, 0, 11 },
> +// D30: SerialIo and SCS - can't use PIC
> +// D29: PCI Express Port 9-16
> +    Package(){0x001DFFFF, 0, 0, 11 },
> +    Package(){0x001DFFFF, 1, 0, 10 },
> +    Package(){0x001DFFFF, 2, 0, 11 },
> +    Package(){0x001DFFFF, 3, 0, 11 },
> +// D28: PCI Express Port 1-8
> +    Package(){0x001CFFFF, 0, 0, 11 },
> +    Package(){0x001CFFFF, 1, 0, 10 },
> +    Package(){0x001CFFFF, 2, 0, 11 },
> +    Package(){0x001CFFFF, 3, 0, 11 },
> +// D27: PCI Express Port 17-20
> +    Package(){0x001BFFFF, 0, 0, 11 },
> +    Package(){0x001BFFFF, 1, 0, 10 },
> +    Package(){0x001BFFFF, 2, 0, 11 },
> +    Package(){0x001BFFFF, 3, 0, 11 },
> +// D25: SerialIo - can't use PIC
> +// D23: SATA controller
> +    Package(){0x0017FFFF, 0, 0, 11 },
> +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
> +    Package(){0x0016FFFF, 0, 0, 11 },
> +    Package(){0x0016FFFF, 1, 0, 10 },
> +    Package(){0x0016FFFF, 2, 0, 11 },
> +    Package(){0x0016FFFF, 3, 0, 11 },
> +// D21: SerialIo - can't use PIC
> +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
> +// D20: xHCI, OTG, CNVi WiFi, SDcard
> +    Package(){0x0014FFFF, 0, 0, 11 },
> +    Package(){0x0014FFFF, 1, 0, 10 },
> +    Package(){0x0014FFFF, 2, 0, 11 },
> +    Package(){0x0014FFFF, 3, 0, 11 },
> +// D19: Integrated Sensor Hub - can't use PIC
> +// D18: Thermal, UFS, SerialIo SPI2 - can't use PIC
> +    Package(){0x0012FFFF, 0, 0, 11 },
> +    Package(){0x0012FFFF, 1, 0, 10 },
> +    Package(){0x0012FFFF, 2, 0, 11 },
> +    Package(){0x0012FFFF, 3, 0, 11 },
> +
> +// Host Bridge
> +// P.E.G. Root Port D1F0
> +    Package(){0x0001FFFF, 0, 0, 11 },
> +    Package(){0x0001FFFF, 1, 0, 10 },
> +    Package(){0x0001FFFF, 2, 0, 11 },
> +    Package(){0x0001FFFF, 3, 0, 11 },
> +// P.E.G. Root Port D1F1
> +// P.E.G. Root Port D1F2
> +// SA IGFX Device
> +    Package(){0x0002FFFF, 0, 0, 11 },
> +// SA Thermal Device
> +    Package(){0x0004FFFF, 0, 0, 11 },
> +// SA IPU Device
> +    Package(){0x0005FFFF, 0, 0, 11 },
> +// SA GNA Device
> +    Package(){0x0008FFFF, 0, 0, 11 },
> +  })
> +  Name(AR00, Package(){
> +// PCI Bridge
> +// D31: cAVS, SMBus, GbE, Nothpeak
> +    Package(){0x001FFFFF, 0, 0, 16 },
> +    Package(){0x001FFFFF, 1, 0, 17 },
> +    Package(){0x001FFFFF, 2, 0, 18 },
> +    Package(){0x001FFFFF, 3, 0, 19 },
> +// D30: SerialIo and SCS
> +    Package(){0x001EFFFF, 0, 0, 20 },
> +    Package(){0x001EFFFF, 1, 0, 21 },
> +    Package(){0x001EFFFF, 2, 0, 22 },
> +    Package(){0x001EFFFF, 3, 0, 23 },
> +// D29: PCI Express Port 9-16
> +    Package(){0x001DFFFF, 0, 0, 16 },
> +    Package(){0x001DFFFF, 1, 0, 17 },
> +    Package(){0x001DFFFF, 2, 0, 18 },
> +    Package(){0x001DFFFF, 3, 0, 19 },
> +// D28: PCI Express Port 1-8
> +    Package(){0x001CFFFF, 0, 0, 16 },
> +    Package(){0x001CFFFF, 1, 0, 17 },
> +    Package(){0x001CFFFF, 2, 0, 18 },
> +    Package(){0x001CFFFF, 3, 0, 19 },
> +// D27: PCI Express Port 17-20
> +    Package(){0x001BFFFF, 0, 0, 16 },
> +    Package(){0x001BFFFF, 1, 0, 17 },
> +    Package(){0x001BFFFF, 2, 0, 18 },
> +    Package(){0x001BFFFF, 3, 0, 19 },
> +// D26: eMMC
> +    Package(){0x001AFFFF, 0, 0, 16 },
> +    Package(){0x001AFFFF, 1, 0, 17 },
> +    Package(){0x001AFFFF, 2, 0, 18 },
> +    Package(){0x001AFFFF, 3, 0, 19 },
> +// D25: SerialIo
> +    Package(){0x0019FFFF, 0, 0, 32 },
> +    Package(){0x0019FFFF, 1, 0, 33 },
> +    Package(){0x0019FFFF, 2, 0, 34 },
> +// D23: SATA controller
> +    Package(){0x0017FFFF, 0, 0, 16 },
> +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
> +    Package(){0x0016FFFF, 0, 0, 16 },
> +    Package(){0x0016FFFF, 1, 0, 17 },
> +    Package(){0x0016FFFF, 2, 0, 18 },
> +    Package(){0x0016FFFF, 3, 0, 19 },
> +// D21: SerialIo
> +    Package(){0x0015FFFF, 0, 0, 16 },
> +    Package(){0x0015FFFF, 1, 0, 17 },
> +    Package(){0x0015FFFF, 2, 0, 18 },
> +    Package(){0x0015FFFF, 3, 0, 19 },
> +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
> +// D20: xHCI, OTG, CNVi WiFi, SDcard
> +    Package(){0x0014FFFF, 0, 0, 16 },
> +    Package(){0x0014FFFF, 1, 0, 17 },
> +    Package(){0x0014FFFF, 2, 0, 18 },
> +    Package(){0x0014FFFF, 3, 0, 19 },
> +// D19: Integrated Sensor Hub
> +    Package(){0x0013FFFF, 0, 0, 20 },
> +// D18: Thermal, UFS, SerialIo SPI 2
> +    Package(){0x0012FFFF, 0, 0, 16 },
> +    Package(){0x0012FFFF, 1, 0, 24 },
> +    Package(){0x0012FFFF, 2, 0, 18 },
> +    Package(){0x0012FFFF, 3, 0, 19 },
> +
> +// Host Bridge
> +// P.E.G. Root Port D1F0
> +    Package(){0x0001FFFF, 0, 0, 16 },
> +    Package(){0x0001FFFF, 1, 0, 17 },
> +    Package(){0x0001FFFF, 2, 0, 18 },
> +    Package(){0x0001FFFF, 3, 0, 19 },
> +// P.E.G. Root Port D1F1
> +// P.E.G. Root Port D1F2
> +// SA IGFX Device
> +    Package(){0x0002FFFF, 0, 0, 16 },
> +// SA Thermal Device
> +    Package(){0x0004FFFF, 0, 0, 16 },
> +// SA IPU Device
> +    Package(){0x0005FFFF, 0, 0, 16 },
> +// SA GNA Device
> +    Package(){0x0008FFFF, 0, 0, 16 },
> +  })
> +  Name(PD04, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 10 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR04, Package(){
> +    Package(){0x0000FFFF, 0, 0, 16 },
> +    Package(){0x0000FFFF, 1, 0, 17 },
> +    Package(){0x0000FFFF, 2, 0, 18 },
> +    Package(){0x0000FFFF, 3, 0, 19 },
> +  })
> +  Name(PD05, Package(){
> +    Package(){0x0000FFFF, 0, 0, 10 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR05, Package(){
> +    Package(){0x0000FFFF, 0, 0, 17 },
> +    Package(){0x0000FFFF, 1, 0, 18 },
> +    Package(){0x0000FFFF, 2, 0, 19 },
> +    Package(){0x0000FFFF, 3, 0, 16 },
> +  })
> +  Name(PD06, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 10 },
> +  })
> +  Name(AR06, Package(){
> +    Package(){0x0000FFFF, 0, 0, 18 },
> +    Package(){0x0000FFFF, 1, 0, 19 },
> +    Package(){0x0000FFFF, 2, 0, 16 },
> +    Package(){0x0000FFFF, 3, 0, 17 },
> +  })
> +  Name(PD07, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 10 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR07, Package(){
> +    Package(){0x0000FFFF, 0, 0, 19 },
> +    Package(){0x0000FFFF, 1, 0, 16 },
> +    Package(){0x0000FFFF, 2, 0, 17 },
> +    Package(){0x0000FFFF, 3, 0, 18 },
> +  })
> +  Name(PD08, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 10 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR08, Package(){
> +    Package(){0x0000FFFF, 0, 0, 16 },
> +    Package(){0x0000FFFF, 1, 0, 17 },
> +    Package(){0x0000FFFF, 2, 0, 18 },
> +    Package(){0x0000FFFF, 3, 0, 19 },
> +  })
> +  Name(PD09, Package(){
> +    Package(){0x0000FFFF, 0, 0, 10 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR09, Package(){
> +    Package(){0x0000FFFF, 0, 0, 17 },
> +    Package(){0x0000FFFF, 1, 0, 18 },
> +    Package(){0x0000FFFF, 2, 0, 19 },
> +    Package(){0x0000FFFF, 3, 0, 16 },
> +  })
> +  Name(PD0E, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 10 },
> +  })
> +  Name(AR0E, Package(){
> +    Package(){0x0000FFFF, 0, 0, 18 },
> +    Package(){0x0000FFFF, 1, 0, 19 },
> +    Package(){0x0000FFFF, 2, 0, 16 },
> +    Package(){0x0000FFFF, 3, 0, 17 },
> +  })
> +  Name(PD0F, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 10 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR0F, Package(){
> +    Package(){0x0000FFFF, 0, 0, 19 },
> +    Package(){0x0000FFFF, 1, 0, 16 },
> +    Package(){0x0000FFFF, 2, 0, 17 },
> +    Package(){0x0000FFFF, 3, 0, 18 },
> +  })
> +  Name(PD02, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 10 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR02, Package(){
> +// P.E.G. Port Slot x16
> +    Package(){0x0000FFFF, 0, 0, 16 },
> +    Package(){0x0000FFFF, 1, 0, 17 },
> +    Package(){0x0000FFFF, 2, 0, 18 },
> +    Package(){0x0000FFFF, 3, 0, 19 },
> +  })
> +  Name(PD0A, Package(){
> +// P.E.G. Port Slot x8
> +    Package(){0x0000FFFF, 0, 0, 10 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR0A, Package(){
> +// P.E.G. Port Slot x8
> +    Package(){0x0000FFFF, 0, 0, 17 },
> +    Package(){0x0000FFFF, 1, 0, 18 },
> +    Package(){0x0000FFFF, 2, 0, 19 },
> +    Package(){0x0000FFFF, 3, 0, 16 },
> +  })
> +  Name(PD0B, Package(){
> +// P.E.G. Port Slot x4
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 10 },
> +  })
> +  Name(AR0B, Package(){
> +// P.E.G. Port Slot x4
> +    Package(){0x0000FFFF, 0, 0, 18 },
> +    Package(){0x0000FFFF, 1, 0, 19 },
> +    Package(){0x0000FFFF, 2, 0, 16 },
> +    Package(){0x0000FFFF, 3, 0, 17 },
> +  })
> +
> +//---------------------------------------------------------------------------
> +// Begin PCI tree object scope
> +//---------------------------------------------------------------------------
> +  Device(PCI0) { // PCI Bridge "Host Bridge"
> +    Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2
> host hierarchy
> +    Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't
> understand the new HID
> +    Name(_SEG, 0)
> +    Name(_ADR, 0x00000000)
> +    Method(^BN00, 0){ return(0x0000) }  // Returns default Bus number for
> Peer PCI busses. Name can be overriden with control method placed directly
> under Device scope
> +    Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root
> PCI Bus
> +    Name(_UID, 0x0000)  // Unique Bus ID, optional
> +    Method(_PRT,0) {
> +      If(PICM) {Return(AR00)} // APIC mode
> +      Return (PD00) // PIC Mode
> +    } // end _PRT
> +
> +  Include("HostBus.asl")
> +  } // end PCI0 Bridge "Host Bridge"
> +} // end _SB scope
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfo
> rm.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfo
> rm.asl
> new file mode 100644
> index 0000000000..951c01455f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfo
> rm.asl
> @@ -0,0 +1,76 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +// Define Port 80 as an ACPI Operating Region to use for debugging.  Please
> +// note that the Intel CRBs have the ability to ouput a Word to
> +// Port 80h for debugging purposes, so the model implemented here may not
> be
> +// able to be used on OEM Designs.
> +
> +OperationRegion(PRT0,SystemIO,0x80,2)
> +Field(PRT0,WordAcc,Lock,Preserve)
> +{
> +  P80B, 16
> +}
> +
> +// Port 80h Update:
> +//    Update 2 bytes of Port 80h.
> +//
> +//  Arguments:
> +//    Arg0: 0 = Write Port 80h
> +//          1 = Write Port 81h
> +//    Arg1: 8-bit Value to write
> +//
> +//  Return Value:
> +//    None
> +
> +Name(P80T, 0) // temp buffer for P80
> +
> +Method(D8XH,2,Serialized)
> +{
> +  If(LEqual(Arg0,0))    // Write Port 80h
> +  {
> +    Store(Or(And(P80T,0xFF00),Arg1),P80T)
> +  }
> +  If(LEqual(Arg0,1))    // Write Port 81h
> +  {
> +    Store(Or(And(P80T,0x00FF),ShiftLeft(Arg1,8)),P80T)
> +  }
> +  Store(P80T,P80B)
> +}
> +
> +//
> +// Define SW SMI port as an ACPI Operating Region to use for generate SW
> SMI.
> +//
> +OperationRegion(SPRT,SystemIO, 0xB2,2)
> +Field (SPRT, ByteAcc, Lock, Preserve) {
> +  SSMP, 8
> +}
> +
> +// The _PIC Control Method is optional for ACPI design.  It allows the
> +// OS to inform the ASL code which interrupt controller is being used,
> +// the 8259 or APIC.  The reference code in this document will address
> +// PCI IRQ Routing and resource allocation for both cases.
> +//
> +// The values passed into _PIC are:
> +//   0 = 8259
> +//   1 = IOAPIC
> +
> +Method(\_PIC,1)
> +{
> +  Store(Arg0,PICM)
> +}
> +
> +Scope (\)
> +{
> +  //
> +  // Global Name, returns current Interrupt controller mode;
> +  // updated from _PIC control method
> +  //
> +  Name(PICM, 0)
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3P
> cieTbt.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3P
> cieTbt.asl
> new file mode 100644
> index 0000000000..38d60d6dbd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3P
> cieTbt.asl
> @@ -0,0 +1,405 @@
> +/** @file
> +  ACPI RTD3 SSDT table for SPT PCIe
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#define PID_ICC                                   0xDC
> +#define R_PCH_PCR_ICC_MSKCKRQ                     0x100C                  ///<
> Mask Control CLKREQ
> +
> +External(PCRA,MethodObj)
> +External(PCRO,MethodObj)
> +External(\MMRP, MethodObj)
> +External(\MMTB, MethodObj)
> +External(\TRDO, IntObj)
> +External(\TRD3, IntObj)
> +External(\TBPE, IntObj)
> +External(\TOFF, IntObj)
> +External(\TBSE, IntObj)
> +External(\TBOD, IntObj)
> +External(\TBRP, IntObj)
> +External(\TBHR, IntObj)
> +External(\RTBC, IntObj)
> +External(\TBCD, IntObj)
> +
> +Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
> +
> +Name(WKEN, 0)
> +
> +  Method(_S0W, 0)
> +  {
> +  /// This method returns the lowest D-state supported by PCIe root port
> during S0 state
> +
> +   ///- PMEs can be generated from D3hot for ULT
> +      Return(4)
> +
> +  /** @defgroup pcie_s0W PCIE _S0W **/
> +  } // End _S0W
> +
> +  Method (_DSD, 0) {
> +    Return (
> +      Package () {
> +        ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
> +        Package () {
> +          Package (2) {"HotPlugSupportInD3", 1},
> +        }
> +      }
> +    ) // End of Return ()
> +  }
> +
> +    Method(_DSW, 3)
> +    {
> +    /// This method is used to enable/disable wake from PCIe (WKEN)
> +      If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE#
> from generating runtime PME
> +                                    /// Also set 2 to TOFF.
> +        Store(0, WKEN)
> +        Store (2, TOFF)
> +      } Else {  /// If Staying in S0
> +        If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
> +        { ///- Set PME
> +          Store(1, WKEN)
> +          Store (1, TOFF)
> +        } Else { ///- Disable runtime PME, either because staying in D0 or
> disabling wake
> +          Store(0, WKEN)
> +          Store(0, TOFF)
> +        }
> +      }
> +
> +    /** @defgroup pcie_dsw PCIE _DSW **/
> +    } // End _DSW
> +
> +
> +    PowerResource(PXP, 0, 0)
> +    {
> +    /// Define the PowerResource for PCIe slot
> +    /// Method: _STA(), _ON(), _OFF()
> +    /** @defgroup pcie_pxp PCIE Power Resource **/
> +
> +      Method(_STA, 0)
> +      {
> +          Return(PSTA())
> +      }  /** @defgroup pcie_sta PCIE _STA method **/
> +
> +      Method(_ON) /// Turn on core power to PCIe Slot
> +      {
> +        Store(1, TRDO)
> +        PON()
> +        Store(0, TRDO)
> +      } /** @defgroup pcie_on PCIE _ON method **/
> +
> +      Method(_OFF) /// Turn off core power to PCIe Slot
> +      {
> +        Store(1, TRD3)
> +        POFF()
> +        Store(0, TRD3)
> +      } // End of Method_OFF
> +    } // End PXP
> +
> +    Method(PSTA, 0)
> +    {
> +    /// Returns the status of PCIe slot core power
> +      // detect power pin status
> +      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) {
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
> +          if(LEqual(\_SB.GGOV(DeRefOf(Index(PWRG,
> 2))),DeRefOf(Index(PWRG, 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // GPIO mode
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
> +          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(PWRG,
> 1)),DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // IOEX mode
> +      }
> +      // detect reset pin status
> +      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) {
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
> +          if(LEqual(\_SB.GGOV(DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG,
> 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // GPIO mode
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),2))  { // IOEX mode
> +          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(RSTG,
> 1)),DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // IOEX mode
> +      }
> +      Return (0)
> +    }  /** @defgroup pcie_sta PCIE _STA method **/
> +
> +    Method (SXEX, 0, Serialized) {
> +
> +      Store(\MMTB(TBSE), Local7)
> +      OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG
> MMIO
> +      Field(TBDI,DWordAcc, NoLock, Preserve) {
> +        DIVI, 32,
> +        CMDR, 32,
> +        Offset(0x548),
> +        TB2P, 32,
> +        P2TB, 32
> +      }
> +
> +      Store(100, Local1)
> +      Store(0x09, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT
> +      While (LGreater(Local1, 0)) {
> +
> +        Store(Subtract(Local1, 1), Local1)
> +        Store(TB2P, Local2)
> +        If (LEqual(Local2, 0xFFFFFFFF)) { // Device gone
> +          Return()
> +        }
> +        If (And(Local2, 1)) { // Done
> +          break
> +        }
> +        Sleep(5)
> +      }
> +      Store(0x0, P2TB) // Write 0 to PCIe2TBT
> +
> +      // Fast Link bring-up flow
> +      Store(500, Local1)
> +      While (LGreater(Local1, 0)) {
> +        Store(Subtract(Local1, 1), Local1)
> +        Store(TB2P, Local2)
> +        If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
> +          Return()
> +        }
> +        If (LNotEqual(DIVI, 0xFFFFFFFF)) {
> +          break
> +        }
> +        Sleep(10)
> +      }
> +    } // End of Method(SXEX, 0, Serialized)
> +
> +    Method(PON) /// Turn on core power to PCIe Slot
> +    {
> +
> +      Store(\MMRP(\TBSE), Local7)
> +      OperationRegion(L23P,SystemMemory,Local7,0xE4)
> +      Field(L23P,WordAcc, NoLock, Preserve)
> +      {
> +        Offset(0xA4),// PMCSR
> +        PSD0, 2, // PowerState
> +        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
> +        , 2,
> +        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
> +        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
> +      }
> +
> +      Store(\MMTB(\TBSE), Local6)
> +      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG
> MMIO
> +      Field(TBDI,DWordAcc, NoLock, Preserve) {
> +        DIVI, 32,
> +        CMDR, 32,
> +        Offset(0xA4),
> +        TBPS, 2, // PowerState of TBT
> +        Offset(0x548),
> +        TB2P, 32,
> +        P2TB, 32
> +      }
> +
> +      Store(0, TOFF)
> +      // Check RTD3 power enable, if already ON, no need to execute sx_exit
> +      If (TBPE) {
> +        Return()
> +      }
> +
> +      Store(0,G2SD)
> +      If (\RTBC) {
> +        /// de-assert CLK_REQ MSK
> +        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
> +          PCRA(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,Not(DeRefOf(Index(SCLK,
> 1))))  // And ~SCLK to clear bit
> +        }
> +        Sleep(\TBCD)
> +      }
> +
> +      /// Turn ON Power for PCIe Slot
> +      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
> +          Store(1, TBPE)
> +          Sleep(PEP0)     /// Sleep for programmable delay
> +        }
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG,
> 2)),DeRefOf(Index(PWRG, 3)))
> +          Store(1, TBPE)
> +          Sleep(PEP0)     /// Sleep for programmable delay
> +        }
> +      }
> +
> +      /// De-Assert Reset Pin
> +      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
> +        }
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG,
> 2)),DeRefOf(Index(RSTG, 3)))
> +        }
> +      }
> +
> +      /// Clear DLSULPPGE, then set L23_Rdy to Detect Transition  (L23R2DT)
> +      Store(0, DPGE)
> +      Store(1, L2TR)
> +      Sleep(16)
> +      Store(0, Local0)
> +      /// Wait up to 12 ms for transition to Detect
> +      While(L2TR) {
> +        If(Lgreater(Local0, 4))    // Debug - Wait for 5 ms
> +        {
> +          Break
> +        }
> +        Sleep(16)
> +        Increment(Local0)
> +      }
> +      /// 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(1, DPGE)
> +      Store(0, Local0)
> +      While(LEqual(LASX,0)) {
> +        If(Lgreater(Local0, 8))
> +        {
> +          Break
> +        }
> +        Sleep(16)
> +        Increment(Local0)
> +      }
> +      Store(0, LEDM) /// Set PCIEDBG.DMIL1EDM (324[3]) = 0
> +
> +      // TBT special sleep.
> +      Store(PSD0, Local1)
> +      Store(0, PSD0)// D0
> +      Store(20, Local2) // Poll for TBT, up to 200 ms
> +
> +      While (LGreater(Local2, 0)) {
> +        Store(Subtract(Local2, 1), Local2)
> +        Store(TB2P, Local3)
> +        If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
> +          break
> +        }
> +        Sleep(10)
> +      }
> +
> +      If (LLessEqual(Local2, 0)) {
> +      }
> +      SXEX()
> +      Store(Local1, PSD0) // Back to Local1
> +    } /** @defgroup pcie_on PCIE _ON method **/
> +
> +    Method(POFF) { /// Turn off core power to PCIe Slot
> +      If (LEqual(TOFF, 0)) {
> +        Return()
> +      }
> +      Store(\MMRP(\TBSE), Local7)
> +      OperationRegion(L23P, SystemMemory, Local7, 0xE4)
> +      Field(L23P,WordAcc, NoLock, Preserve)
> +      {
> +        Offset(0xA4),// PMCSR
> +        PSD0, 2, // PowerState
> +        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
> +        , 2,
> +        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
> +        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
> +      }
> +
> +      Store(\MMTB(TBSE), Local6)
> +      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG
> MMIO
> +      Field(TBDI,DWordAcc, NoLock, Preserve) {
> +        DIVI, 32,
> +        CMDR, 32,
> +        Offset(0xA4),
> +        TBPS, 2, // PowerState of TBT
> +        Offset(0x548),
> +        TB2P, 32,
> +        P2TB, 32
> +      }
> +
> +      Store(PSD0, Local1)
> +      Store(0, PSD0)// D0
> +
> +      Store(P2TB, Local3)
> +
> +      If (Lgreater(TOFF, 1)) {
> +        Sleep(10)
> +        Store(Local1, PSD0) // Back to Local1
> +        Return()
> +      }
> +      Store(0, TOFF)
> +
> +      Store(Local1, PSD0) // Back to Local1
> +
> +      /// Set L23_Rdy Entry Request (L23ER)
> +      Store(1, L2TE)
> +      Sleep(16)
> +      Store(0, Local0)
> +      While(L2TE) {
> +        If(Lgreater(Local0, 4))    /// Debug - Wait for 5 ms
> +        {
> +          Break
> +        }
> +        Sleep(16)
> +        Increment(Local0)
> +      }
> +      Store(1, LEDM) /// PCIEDBG.DMIL1EDM (324[3]) = 1
> +
> +      /// Assert Reset Pin
> +      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
> +        }
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG,
> 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
> +        }
> +      }
> +      If (\RTBC) {
> +        /// assert CLK_REQ MSK
> +        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
> +          PCRO(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,DeRefOf(Index(SCLK, 1)))
> // Or SCLK to set bit
> +          Sleep(16)
> +        }
> +      }
> +
> +      /// Power OFF for TBT
> +      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG,
> 3)),1))
> +        }
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG,
> 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
> +        }
> +      }
> +
> +      Store(0, TBPE)
> +
> +      Store(1, LDIS) /// Set Link Disable
> +      Store(0, LDIS) /// Toggle link disable
> +
> +      /// enable WAKE
> +      If (WKEN) {
> +        If (LNotEqual(DeRefOf(Index(WAKG, 0)),0)) { // if power gating enabled
> +          If (LEqual(DeRefOf(Index(WAKG, 0)),1)) { // GPIO mode
> +            \_SB.SGOV(DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
> +            \_SB.SHPO(DeRefOf(Index(WAKG, 2)), 0) // set gpio ownership to
> ACPI(0=ACPI mode, 1=GPIO mode)
> +          }
> +          If (LEqual(DeRefOf(Index(WAKG, 0)),2))  { // IOEX mode
> +            \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG,
> 1)),DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
> +          }
> +        }
> +      }
> +      Sleep(\TBOD)
> +      /** @defgroup pcie_off PCIE _OFF method **/
> +    } // End of Method_OFF
> +
> +    Name(_PR0, Package(){PXP})
> +    Name(_PR3, Package(){PXP})
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as
> l
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as
> l
> new file mode 100644
> index 0000000000..66584c21c5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as
> l
> @@ -0,0 +1,1877 @@
> +/** @file
> + Thunderbolt ACPI methods
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#define DTBT_CONTROLLER                   0x00
> +#define DTBT_TYPE_PCH                     0x01
> +#define DTBT_TYPE_PEG                     0x02
> +#define DTBT_SMI_HANDLER_NUMBER           0xF7
> +#define TBT_SMI_ENUMERATION_FUNCTION      21
> +#define TBT_SMI_RESET_SWITCH_FUNCTION     22
> +#define TBT_SMI_DISABLE_MSI_FUNCTION      23
> +#ifndef  BIT29
> +#define  BIT29    0x20000000
> +#endif
> +
> +Name(LDLY, 300) //300 ms
> +Name (TNVB, 0xFFFF0000)  // TBT NVS Base address
> +Name (TNVL, 0xAA55)      // TBT NVS Length
> +Include ("Acpi/TbtNvs.asl")
> +
> +External(\_SB.PCI0.RP02.L23D, MethodObj)
> +External(\_SB.PCI0.RP03.L23D, MethodObj)
> +External(\_SB.PCI0.RP04.L23D, MethodObj)
> +External(\_SB.PCI0.RP05.L23D, MethodObj)
> +External(\_SB.PCI0.RP06.L23D, MethodObj)
> +External(\_SB.PCI0.RP07.L23D, MethodObj)
> +External(\_SB.PCI0.RP08.L23D, MethodObj)
> +External(\_SB.PCI0.RP09.L23D, MethodObj)
> +External(\_SB.PCI0.RP10.L23D, MethodObj)
> +External(\_SB.PCI0.RP11.L23D, MethodObj)
> +External(\_SB.PCI0.RP12.L23D, MethodObj)
> +External(\_SB.PCI0.RP13.L23D, MethodObj)
> +External(\_SB.PCI0.RP14.L23D, MethodObj)
> +External(\_SB.PCI0.RP15.L23D, MethodObj)
> +External(\_SB.PCI0.RP16.L23D, MethodObj)
> +External(\_SB.PCI0.RP17.L23D, MethodObj)
> +External(\_SB.PCI0.RP18.L23D, MethodObj)
> +External(\_SB.PCI0.RP19.L23D, MethodObj)
> +External(\_SB.PCI0.RP20.L23D, MethodObj)
> +External(\_SB.PCI0.RP21.L23D, MethodObj)
> +External(\_SB.PCI0.RP22.L23D, MethodObj)
> +External(\_SB.PCI0.RP23.L23D, MethodObj)
> +External(\_SB.PCI0.RP24.L23D, MethodObj)
> +
> +External(\_SB.PCI0.RP01.DL23, MethodObj)
> +External(\_SB.PCI0.RP02.DL23, MethodObj)
> +External(\_SB.PCI0.RP03.DL23, MethodObj)
> +External(\_SB.PCI0.RP04.DL23, MethodObj)
> +External(\_SB.PCI0.RP05.DL23, MethodObj)
> +External(\_SB.PCI0.RP06.DL23, MethodObj)
> +External(\_SB.PCI0.RP07.DL23, MethodObj)
> +External(\_SB.PCI0.RP08.DL23, MethodObj)
> +External(\_SB.PCI0.RP09.DL23, MethodObj)
> +External(\_SB.PCI0.RP10.DL23, MethodObj)
> +External(\_SB.PCI0.RP11.DL23, MethodObj)
> +External(\_SB.PCI0.RP12.DL23, MethodObj)
> +External(\_SB.PCI0.RP13.DL23, MethodObj)
> +External(\_SB.PCI0.RP14.DL23, MethodObj)
> +External(\_SB.PCI0.RP15.DL23, MethodObj)
> +External(\_SB.PCI0.RP16.DL23, MethodObj)
> +External(\_SB.PCI0.RP17.DL23, MethodObj)
> +External(\_SB.PCI0.RP18.DL23, MethodObj)
> +External(\_SB.PCI0.RP19.DL23, MethodObj)
> +External(\_SB.PCI0.RP20.DL23, MethodObj)
> +External(\_SB.PCI0.RP21.DL23, MethodObj)
> +External(\_SB.PCI0.RP22.DL23, MethodObj)
> +External(\_SB.PCI0.RP23.DL23, MethodObj)
> +External(\_SB.PCI0.RP24.DL23, MethodObj)
> +
> +External(\_SB.PCI0.RTEN, MethodObj)
> +External(\_SB.PCI0.RTDS, MethodObj)
> +External(\_SB.PCI0.RP01.PON, MethodObj)
> +External(\_SB.PCI0.RP02.PON, MethodObj)
> +External(\_SB.PCI0.RP03.PON, MethodObj)
> +External(\_SB.PCI0.RP04.PON, MethodObj)
> +External(\_SB.PCI0.RP05.PON, MethodObj)
> +External(\_SB.PCI0.RP06.PON, MethodObj)
> +External(\_SB.PCI0.RP07.PON, MethodObj)
> +External(\_SB.PCI0.RP08.PON, MethodObj)
> +External(\_SB.PCI0.RP09.PON, MethodObj)
> +External(\_SB.PCI0.RP10.PON, MethodObj)
> +External(\_SB.PCI0.RP11.PON, MethodObj)
> +External(\_SB.PCI0.RP12.PON, MethodObj)
> +External(\_SB.PCI0.RP13.PON, MethodObj)
> +External(\_SB.PCI0.RP14.PON, MethodObj)
> +External(\_SB.PCI0.RP15.PON, MethodObj)
> +External(\_SB.PCI0.RP16.PON, MethodObj)
> +External(\_SB.PCI0.RP17.PON, MethodObj)
> +External(\_SB.PCI0.RP18.PON, MethodObj)
> +External(\_SB.PCI0.RP19.PON, MethodObj)
> +External(\_SB.PCI0.RP20.PON, MethodObj)
> +External(\_SB.PCI0.RP21.PON, MethodObj)
> +External(\_SB.PCI0.RP22.PON, MethodObj)
> +External(\_SB.PCI0.RP23.PON, MethodObj)
> +External(\_SB.PCI0.RP24.PON, MethodObj)
> +External(\_SB.PCI0.PEG0.PG00._ON, MethodObj)
> +External(\_SB.PCI0.PEG1.PG01._ON, MethodObj)
> +External(\_SB.PCI0.PEG2.PG02._ON, MethodObj)
> +
> +Name(TRDO, 0) // 1 during TBT RTD3 _ON
> +Name(TRD3, 0) // 1 during TBT RTD3 _OFF
> +Name(TBPE, 0) // Reflects RTD3_PWR_EN value
> +Name(TOFF, 0) // param to TBT _OFF method
> +
> +  Method (TBON, 0, Serialized) {
> +    // TBT On process before entering Sx state.
> +    Store(1, TRDO)
> +    Switch (ToInteger(\RPS0)) { // TBT Root port Selector
> +      Case (1) {
> +        If (CondRefOf(\_SB.PCI0.RP01.PON)) {
> +          \_SB.PCI0.RP01.PON()
> +        }
> +      }
> +      Case (2) {
> +        If (CondRefOf(\_SB.PCI0.RP02.PON)) {
> +          \_SB.PCI0.RP02.PON()
> +        }
> +      }
> +      Case (3) {
> +        If (CondRefOf(\_SB.PCI0.RP03.PON)) {
> +          \_SB.PCI0.RP03.PON()
> +        }
> +      }
> +      Case (4) {
> +        If (CondRefOf(\_SB.PCI0.RP04.PON)) {
> +          \_SB.PCI0.RP04.PON()
> +        }
> +      }
> +      Case (5) {
> +        If (CondRefOf(\_SB.PCI0.RP05.PON)) {
> +          \_SB.PCI0.RP05.PON()
> +        }
> +      }
> +      Case (6) {
> +        If (CondRefOf(\_SB.PCI0.RP06.PON)) {
> +          \_SB.PCI0.RP06.PON()
> +        }
> +      }
> +      Case (7) {
> +        If (CondRefOf(\_SB.PCI0.RP07.PON)) {
> +          \_SB.PCI0.RP07.PON()
> +        }
> +      }
> +      Case (8) {
> +        If (CondRefOf(\_SB.PCI0.RP08.PON)) {
> +          \_SB.PCI0.RP08.PON()
> +        }
> +      }
> +      Case (9) {
> +        If (CondRefOf(\_SB.PCI0.RP09.PON)) {
> +          \_SB.PCI0.RP09.PON()
> +        }
> +      }
> +      Case (10) {
> +        If (CondRefOf(\_SB.PCI0.RP10.PON)) {
> +          \_SB.PCI0.RP10.PON()
> +        }
> +      }
> +      Case (11) {
> +        If (CondRefOf(\_SB.PCI0.RP11.PON)) {
> +          \_SB.PCI0.RP11.PON()
> +        }
> +      }
> +      Case (12) {
> +        If (CondRefOf(\_SB.PCI0.RP12.PON)) {
> +          \_SB.PCI0.RP12.PON()
> +        }
> +      }
> +      Case (13) {
> +        If (CondRefOf(\_SB.PCI0.RP13.PON)) {
> +          \_SB.PCI0.RP13.PON()
> +        }
> +      }
> +      Case (14) {
> +        If (CondRefOf(\_SB.PCI0.RP14.PON)) {
> +          \_SB.PCI0.RP14.PON()
> +        }
> +      }
> +      Case (15) {
> +        If (CondRefOf(\_SB.PCI0.RP15.PON)) {
> +          \_SB.PCI0.RP15.PON()
> +        }
> +      }
> +      Case (16) {
> +        If (CondRefOf(\_SB.PCI0.RP16.PON)) {
> +          \_SB.PCI0.RP16.PON()
> +        }
> +      }
> +      Case (17) {
> +        If (CondRefOf(\_SB.PCI0.RP17.PON)) {
> +          \_SB.PCI0.RP17.PON()
> +        }
> +      }
> +      Case (18) {
> +        If (CondRefOf(\_SB.PCI0.RP18.PON)) {
> +          \_SB.PCI0.RP18.PON()
> +        }
> +      }
> +      Case (19) {
> +        If (CondRefOf(\_SB.PCI0.RP19.PON)) {
> +          \_SB.PCI0.RP19.PON()
> +        }
> +      }
> +      Case (20) {
> +        If (CondRefOf(\_SB.PCI0.RP20.PON)) {
> +          \_SB.PCI0.RP20.PON()
> +        }
> +      }
> +      Case (21) {
> +        If (CondRefOf(\_SB.PCI0.RP21.PON)) {
> +          \_SB.PCI0.RP21.PON()
> +        }
> +      }
> +      Case (22) {
> +        If (CondRefOf(\_SB.PCI0.RP22.PON)) {
> +          \_SB.PCI0.RP22.PON()
> +        }
> +      }
> +      Case (23) {
> +        If (CondRefOf(\_SB.PCI0.RP23.PON)) {
> +          \_SB.PCI0.RP23.PON()
> +        }
> +      }
> +      Case (24) {
> +        If (CondRefOf(\_SB.PCI0.RP24.PON)) {
> +          \_SB.PCI0.RP24.PON()
> +        }
> +      }
> +    }//Switch(ToInteger(RPS0)) // TBT Selector
> +    Store(0, TRDO)
> +  } // End of TBON
> +  //
> +  // Name: TBTD
> +  // Description: Function to return the TBT RP# device no
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  // Return: TBT RP# device no
> +  //
> +  Method(TBTD,2)
> +  {
> +    ADBG("TBTD")
> +    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (Package () {1, 2, 3, 4, 5, 6, 7, 8})
> +        {
> +          Store(0x1C, Local0) //Device28-Function0...Function7 =
> 11100.000...111
> +        }
> +        Case (Package () {9, 10, 11, 12, 13, 14, 15, 16})
> +        {
> +          Store(0x1D, Local0) //Device29-Function0...Function7 =
> 11101.000...111
> +        }
> +        Case (Package () {17, 18, 19, 20, 21, 22, 23, 24})
> +        {
> +          Store(0x1B, Local0) //Device27-Function0...Function3 =
> 11011.000...011
> +        }
> +      }
> +    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (Package () {1, 2, 3})
> +        {
> +          Store(0x1, Local0) //Device1-Function0...Function2 = 00001.000...010
> +        }
> +      }
> +    } Else {
> +      Store(0xFF, Local0)
> +    }
> +
> +    ADBG("Device no")
> +    ADBG(Local0)
> +
> +    Return(Local0)
> +  } // End of Method(TBTD,1)
> +
> +  //
> +  // Name: TBTF
> +  // Description: Function to return the TBT RP# function no
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  // Return: TBT RP# function no
> +  //
> +  Method(TBTF,2)
> +  {
> +    ADBG("TBTF")
> +    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (1)
> +        {
> +          Store(And(\RPA1,0xF), Local0) //Device28-Function0 = 11100.000
> +        }
> +        Case (2)
> +        {
> +          Store(And(\RPA2,0xF), Local0) //Device28-Function1 = 11100.001
> +        }
> +        Case (3)
> +        {
> +          Store(And(\RPA3,0xF), Local0) //Device28-Function2 = 11100.010
> +        }
> +        Case (4)
> +        {
> +          Store(And(\RPA4,0xF), Local0) //Device28-Function3 = 11100.011
> +        }
> +        Case (5)
> +        {
> +          Store(And(\RPA5,0xF), Local0) //Device28-Function4 = 11100.100
> +        }
> +        Case (6)
> +        {
> +          Store(And(\RPA6,0xF), Local0) //Device28-Function5 = 11100.101
> +        }
> +        Case (7)
> +        {
> +          Store(And(\RPA7,0xF), Local0) //Device28-Function6 = 11100.110
> +        }
> +        Case (8)
> +        {
> +          Store(And(\RPA8,0xF), Local0) //Device28-Function7 = 11100.111
> +        }
> +        Case (9)
> +        {
> +          Store(And(\RPA9,0xF), Local0) //Device29-Function0 = 11101.000
> +        }
> +        Case (10)
> +        {
> +          Store(And(\RPAA,0xF), Local0) //Device29-Function1 = 11101.001
> +        }
> +        Case (11)
> +        {
> +          Store(And(\RPAB,0xF), Local0) //Device29-Function2 = 11101.010
> +        }
> +        Case (12)
> +        {
> +          Store(And(\RPAC,0xF), Local0) //Device29-Function3 = 11101.011
> +        }
> +        Case (13)
> +        {
> +          Store(And(\RPAD,0xF), Local0) //Device29-Function4 = 11101.100
> +        }
> +        Case (14)
> +        {
> +          Store(And(\RPAE,0xF), Local0) //Device29-Function5 = 11101.101
> +        }
> +        Case (15)
> +        {
> +          Store(And(\RPAF,0xF), Local0) //Device29-Function6 = 11101.110
> +        }
> +        Case (16)
> +        {
> +          Store(And(\RPAG,0xF), Local0) //Device29-Function7 = 11101.111
> +        }
> +        Case (17)
> +        {
> +          Store(And(\RPAH,0xF), Local0) //Device27-Function0 = 11011.000
> +        }
> +        Case (18)
> +        {
> +          Store(And(\RPAI,0xF), Local0) //Device27-Function1 = 11011.001
> +        }
> +        Case (19)
> +        {
> +          Store(And(\RPAJ,0xF), Local0) //Device27-Function2 = 11011.010
> +        }
> +        Case (20)
> +        {
> +          Store(And(\RPAK,0xF), Local0) //Device27-Function3 = 11011.011
> +        }
> +        Case (21)
> +        {
> +          Store(And(\RPAL,0xF), Local0) //Device27-Function4 = 11011.100
> +        }
> +        Case (22)
> +        {
> +          Store(And(\RPAM,0xF), Local0) //Device27-Function5 = 11011.101
> +        }
> +        Case (23)
> +        {
> +          Store(And(\RPAN,0xF), Local0) //Device27-Function6 = 11011.110
> +        }
> +        Case (24)
> +        {
> +          Store(And(\RPAO,0xF), Local0) //Device27-Function7 = 11011.111
> +        }
> +      }
> +    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (1)
> +        {
> +          Store(0x0, Local0) //Device1-Function0 = 00001.000
> +        }
> +        Case (2)
> +        {
> +          Store(0x1, Local0) //Device1-Function1 = 00001.001
> +        }
> +        Case (3)
> +        {
> +          Store(0x2, Local0) //Device1-Function2 = 00001.010
> +        }
> +      }
> +    } Else {
> +      Store(0xFF, Local0)
> +    }
> +
> +    ADBG("Function no")
> +    ADBG(Local0)
> +
> +    Return(Local0)
> +  } // End of Method(TBTF,1)
> +
> +  //
> +  // Name: MMRP
> +  // Description: Function to return the Pci base address of TBT rootport
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(MMRP, 2, Serialized)
> +  {
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    Return(Local0)
> +  } // End of Method(MMRP)
> +
> +  //
> +  // Name: MMRP
> +  // Description: Function to return the Pci base address of TBT Up stream
> port
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +  Method(MMTB, 2, Serialized)
> +  {
> +    ADBG("MMTB")
> +
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
> +    Field (MMMM, AnyAcc, NoLock, Preserve)
> +    {
> +      Offset(0x19),
> +      SBUS, 8
> +    }
> +    Store(SBUS, Local2)
> +    Store(\_SB.PCI0.GPCB(), Local0)
> +    Multiply(Local2, 0x100000, Local2)
> +    Add(Local2, Local0, Local0) // TBT HR US port
> +
> +    ADBG("TBT-US-ADR")
> +    ADBG(Local0)
> +
> +    Return(Local0)
> +  } // End of Method(MMTB, 1, Serialized)
> +  //
> +  // Name: FFTB
> +  // Description: Function to  Check for FFFF in TBT PCIe
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  // Return: 1 if TBT PCIe space has value FFFF, 0 if not
> +  //
> +  Method(FFTB, 2, Serialized)
> +  {
> +    ADBG("FFTB")
> +
> +    Add(MMTB(Arg0, Arg1), 0x548, Local0)
> +    OperationRegion(PXVD,SystemMemory,Local0,0x08)
> +    Field(PXVD,DWordAcc, NoLock, Preserve)
> +    {
> +      TB2P, 32,
> +      P2TB, 32
> +    }
> +
> +    Store(TB2P, Local1)
> +
> +    If(LEqual(Local1, 0xFFFFFFFF))
> +    {
> +      ADBG("FFTb 1")
> +      Return (1)
> +    }
> +    Else
> +    {
> +      ADBG("FFTb 0")
> +      Return (0)
> +    }
> +  } // End of Method(FFTB)
> +
> +Name(TDMA, 0x80000000) // Address of Thunderbolt(TM) debug memory
> buffer, fixed up during POST
> +
> +Scope(\_GPE)
> +{
> +  //
> +  //
> +  //OS up Mail Box command execution to host router upstream port each
> time
> +  //exiting from Sx State .Avoids intermediate
> +  //PCIe Scan by OS during resorce allocation
> +  // Arg0 : PCIe Base address
> +  // Arg1 : Controller Type 0x00 : DTBT
> +  //Developer notes: Called twice
> +  // 1. During OS INIT (booting to OS from S3-S5/Reboot)
> +  // 2. Up on Hot plug
> +  //
> +  Method(OSUP, 2, Serialized)
> +  {
> +    ADBG("OSUP")
> +
> +    Add(Arg0, 0x540, Local0)
> +    OperationRegion(PXVD,SystemMemory,Local0,0x10)
> +    Field(PXVD,DWordAcc, NoLock, Preserve)
> +    {
> +      IT2P, 32,
> +      IP2T, 32,
> +      DT2P, 32,
> +      DP2T, 32
> +    }
> +
> +    Store(100, Local1)
> +    Store(0x0D, DP2T) // Write OS_Up to PCIe2TBT
> +
> +    While(LGreater(Local1, 0))
> +    {
> +      Store(Subtract(Local1, 1), Local1)
> +      Store(DT2P, Local2)
> +
> +      If(LAnd(LEqual(Local2, 0xFFFFFFFF),LEqual(Arg1, DTBT_CONTROLLER)))//
> Device gone
> +      {
> +        ADBG("Dev gone")
> +        Return(2)
> +      }
> +      If(And(Local2, 1)) // Done
> +      {
> +        ADBG("Cmd acknowledged")
> +        break
> +      }
> +      Sleep(50)
> +    }
> +    If(LEqual(TRWA,1))
> +    {
> +      Store(0xC, DP2T) // Write OSUP to PCIe2TBT
> +    }
> +    Else
> +    {
> +      Store(0x0, DP2T) // Write 0 to PCIe2TBT
> +    }
> +
> +    //Store(0x00, P2TB) // Write 0 to PCIe2TBT
> +
> +    ADBG("End-of-OSUP")
> +
> +    Return(1)
> +  } // End of Method(OSUP, 1, Serialized)
> +
> +  //
> +  // Check for FFFF in TBT
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(TBFF, 2, Serialized)
> +  {
> +    ADBG("TBFF")
> +
> +    Store(MMTB(Arg0, Arg1), Local0)
> +    OperationRegion (PXVD, SystemMemory, Local0, 0x8)
> +    Field (PXVD, DWordAcc, NoLock, Preserve) {
> +      VEDI, 32, // Vendor/Device ID
> +      CMDR, 32 // CMD register
> +    }
> +
> +    Store(VEDI, Local1)
> +
> +    If (LEqual(Local1, 0xFFFFFFFF)) {
> +      If (LNotEqual(\TWIN, 0)) { // TBT Enumeration is Native mode?
> +        If (LEqual(CMDR, 0xFFFFFFFF)) { // Device Gone
> +          Return (2)// Notify only
> +        }
> +        Return (1)// Exit w/o notify
> +      } Else {
> +        Return (OSUP(Local0, DTBT_CONTROLLER))
> +      }
> +    } Else
> +    {
> +      ADBG("Dev Present")
> +      Return (0)
> +    }
> +  } // End of Method(TBFF, 1, Serialized)
> +
> +  //
> +  // Secondary bus of TBT RP
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(TSUB, 2, Serialized)
> +  {
> +    ADBG("TSUB")
> +
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    ADBG("ADR")
> +    ADBG(Local0)
> +
> +    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
> +    Field (MMMM, AnyAcc, NoLock, Preserve)
> +    {
> +      Offset(0x19),
> +      SBUS, 8
> +    }
> +
> +    ADBG("Sec Bus")
> +    ADBG(SBUS)
> +
> +    Return(SBUS)
> +  } // End of Method(TSUB, 0, Serialized)
> +
> +  //
> +  // Pmem of TBT RP
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(TSUP, 2, Serialized)
> +  {
> +    ADBG("TSUB")
> +
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    ADBG("ADR:")
> +    ADBG(Local0)
> +
> +    OperationRegion (MMMM, SystemMemory, Local0, 0x30)
> +    Field (MMMM, AnyAcc, NoLock, Preserve)
> +    {
> +      CMDS, 32,
> +      Offset(0x19),
> +      SBUS, 8,
> +      SBU5, 8,
> +      Offset(0x1C),
> +      SEIO, 32,
> +      MMBL, 32,
> +      PMBL, 32,
> +
> +    }
> +
> +    ADBG("Pmem of TBT RP:")
> +    ADBG(PMBL)
> +
> +    Return(PMBL)
> +  } // End of Method(TSUP, 0, Serialized)
> +
> +  //
> +  // Wait for secondary bus in TBT RP
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(WSUB, 2, Serialized)
> +  {
> +    ADBG(Concatenate("WSUB=", ToHexString(Arg0)))
> +    ADBG(ToHexString(Timer))
> +
> +    Store(0, Local0)
> +    Store(0, Local1)
> +    While(1)
> +    {
> +      Store(TSUP(Arg0, Arg1), Local1)
> +      If(LGreater(Local1, 0x1FFF1))
> +      {
> +        ADBG("WSUB-Finished")
> +        Break
> +      }
> +      Else
> +      {
> +        Add(Local0, 1, Local0)
> +        If(LGreater(Local0, 1000))
> +        {
> +          Sleep(1000)
> +          ADBG("WSUB-Deadlock")
> +        }
> +        Else
> +        {
> +          Sleep(16)
> +        }
> +      }
> +    }
> +     ADBG(Concatenate("WSUb=", ToHexString(Local1)))
> +  } // End of Method(WSUB)
> +
> +  // Wait for _WAK finished
> +  Method(WWAK)
> +  {
> +    ADBG("WWAK")
> +
> +    Wait(WFEV, 0xFFFF)
> +    Signal(WFEV) // Set it, to enter on next HP
> +  } // End of Method(WWAK)
> +
> +  Method(NTFY, 2, Serialized)
> +  {
> +    ADBG("NTFY")
> +
> +    If(LEqual(NOHP,1))
> +    {
> +      If (LEqual(Arg1, DTBT_TYPE_PCH)) {
> +        Switch(ToInteger(Arg0)) // TBT Selector
> +        {
> +          Case (1)
> +          {
> +            ADBG("Notify RP01")
> +            Notify(\_SB.PCI0.RP01,0)
> +          }
> +          Case (2)
> +          {
> +            ADBG("Notify RP02")
> +            Notify(\_SB.PCI0.RP02,0)
> +          }
> +          Case (3)
> +          {
> +            ADBG("Notify RP03")
> +            Notify(\_SB.PCI0.RP03,0)
> +          }
> +          Case (4)
> +          {
> +            ADBG("Notify RP04")
> +            Notify(\_SB.PCI0.RP04,0)
> +          }
> +          Case (5)
> +          {
> +            ADBG("Notify RP05")
> +            Notify(\_SB.PCI0.RP05,0)
> +          }
> +          Case (6)
> +          {
> +            ADBG("Notify RP06")
> +            Notify(\_SB.PCI0.RP06,0)
> +          }
> +          Case (7)
> +          {
> +            ADBG("Notify RP07")
> +            Notify(\_SB.PCI0.RP07,0)
> +          }
> +          Case (8)
> +          {
> +            ADBG("Notify RP08")
> +            Notify(\_SB.PCI0.RP08,0)
> +          }
> +          Case (9)
> +          {
> +            ADBG("Notify RP09")
> +            Notify(\_SB.PCI0.RP09,0)
> +          }
> +          Case (10)
> +          {
> +            ADBG("Notify RP10")
> +            Notify(\_SB.PCI0.RP10,0)
> +          }
> +          Case (11)
> +          {
> +            ADBG("Notify RP11")
> +            Notify(\_SB.PCI0.RP11,0)
> +          }
> +          Case (12)
> +          {
> +            ADBG("Notify RP12")
> +            Notify(\_SB.PCI0.RP12,0)
> +          }
> +          Case (13)
> +          {
> +            ADBG("Notify RP13")
> +            Notify(\_SB.PCI0.RP13,0)
> +          }
> +          Case (14)
> +          {
> +            ADBG("Notify RP14")
> +            Notify(\_SB.PCI0.RP14,0)
> +          }
> +          Case (15)
> +          {
> +            ADBG("Notify RP15")
> +            Notify(\_SB.PCI0.RP15,0)
> +          }
> +          Case (16)
> +          {
> +            ADBG("Notify RP16")
> +            Notify(\_SB.PCI0.RP16,0)
> +          }
> +          Case (17)
> +          {
> +            ADBG("Notify RP17")
> +            Notify(\_SB.PCI0.RP17,0)
> +          }
> +          Case (18)
> +          {
> +            ADBG("Notify RP18")
> +            Notify(\_SB.PCI0.RP18,0)
> +          }
> +          Case (19)
> +          {
> +            ADBG("Notify RP19")
> +            Notify(\_SB.PCI0.RP19,0)
> +          }
> +          Case (20)
> +          {
> +            ADBG("Notify RP20")
> +            Notify(\_SB.PCI0.RP20,0)
> +          }
> +          Case (21)
> +          {
> +            ADBG("Notify RP21")
> +            Notify(\_SB.PCI0.RP21,0)
> +          }
> +          Case (22)
> +          {
> +            ADBG("Notify RP22")
> +            Notify(\_SB.PCI0.RP22,0)
> +          }
> +          Case (23)
> +          {
> +            ADBG("Notify RP23")
> +            Notify(\_SB.PCI0.RP23,0)
> +          }
> +          Case (24)
> +          {
> +            ADBG("Notify RP24")
> +            Notify(\_SB.PCI0.RP24,0)
> +          }
> +        }//Switch(ToInteger(TBSS)) // TBT Selector
> +      } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
> +        Switch(ToInteger(Arg0))
> +        {
> +          Case (1)
> +          {
> +            ADBG("Notify PEG0")
> +            Notify(\_SB.PCI0.PEG0,0)
> +          }
> +          Case (2)
> +          {
> +            ADBG("Notify PEG1")
> +            Notify(\_SB.PCI0.PEG1,0)
> +          }
> +          Case (3)
> +          {
> +            ADBG("Notify PEG2")
> +            Notify(\_SB.PCI0.PEG2,0)
> +          }
> +        }
> +      }//Switch(ToInteger(TBSS)) // TBT Selector
> +    }//If(NOHP())
> +    P8XH(0,0xC2)
> +    P8XH(1,0xC2)
> +  }// End of Method(NTFY)
> +
> +//
> +//  TBT BIOS, GPIO 5 filtering,
> +//  Hot plug of 12V USB devices, into TBT host router, cause electrical noise on
> PCH GPIOs,
> +//  This noise cause false hot-plug events, and negatively influence BIOS
> assisted hot-plug.
> +//  WHL-PCH GPIO does not implement Glitch Filter logic (refer to GPIO HAS)
> on any GPIO pad. Native functions have to implement their own digital
> glitch-filter logic
> +//  if needed. As HW filter was not implemented on WHL PCH, because of that
> SW workaround should be implemented in BIOS.
> +//  Register 0x544(Bios mailbox) bit 0 definition:
> +//  if BIOS reads bit as 1, BIOS will clear the bit and continue normal flow, if bit
> is 0 BIOS will exit from method
> +//
> +
> +  Method(GNIS,2, Serialized)
> +  {
> +
> +    ADBG("GNIS")
> +    If(LEqual(GP5F, 0))
> +    {
> +      ADBG("GNIS_Dis=0")
> +      Return(0)
> +    }
> +    //
> +    // BIOS mailbox command for GPIO filter
> +    //
> +    Add(MMTB(Arg0, Arg1), 0x544, Local0)
> +    OperationRegion(PXVD,SystemMemory,Local0,0x08)
> +
> +    Field(PXVD,DWordAcc, NoLock, Preserve)
> +    {
> +      HPFI, 1,
> +      Offset(0x4),
> +      TB2P, 32
> +    }
> +    Store(TB2P, Local1)
> +    ADBG(Concatenate("TB2P=", ToHexString(Local1)))
> +    If(LEqual(Local1, 0xFFFFFFFF)) // Disconnect?
> +    {
> +      ADBG("GNIS=0")
> +      Return(0)
> +    }
> +    Store(HPFI, Local2)
> +    ADBG(Concatenate("HPFI=", ToHexString(Local2)))
> +    If(LEqual(Local2, 0x01))
> +    {
> +      Store(0x00, HPFI)
> +      ADBG("GNIS=0")
> +      Return(0)
> +    }
> +    // Any other values treated as a GPIO noise
> +    ADBG("GNIS=1")
> +    Return(1)
> +  }
> +
> +  Method(CHKP,2, Serialized)
> +  {
> +    Add(MMTB(Arg0, Arg1), 0x544, Local0)
> +    OperationRegion(PXVE,SystemMemory,Local0,0x08)
> +
> +    Field(PXVE,DWordAcc, NoLock, Preserve)
> +    {
> +      HPFI, 1,
> +      Offset(0x4),
> +      TB2P, 32
> +    }
> +    Store(TB2P, Local1)
> +    And(Local1,BIT29,Local1)
> +    ADBG(Concatenate("Local1=", ToHexString(Local1)))
> +    //ADBG(Concatenate("BIT29=", ToHexString(LAnd(Local1,BIT29))))
> +    If(LEqual(Local1, BIT29))
> +    {
> +      Return(1)
> +    }
> +    Else
> +    {
> +      Return(0)
> +    }
> +  }
> +
> +  //
> +  // Method to Handle enumerate PCIe structure through
> +  // SMI for Thunderbolt(TM) devices
> +  //
> +  Method(XTBT,2, Serialized)
> +  {
> +    ADBG("XTBT")
> +    ADBG("RP :")
> +    ADBG(Arg0)
> +    Store(Arg0, DTCP) // Root port to enumerate
> +    Store(Arg1, DTPT)   // Root port Type
> +    If(LEqual(Arg0, RPS0)) {
> +      Store (1, Local0)
> +    } ElseIf (LEqual(Arg0, RPS1)) {
> +      Store (2, Local0)
> +    } Else {
> +      Store (0, Local0)
> +      Return ()
> +    }
> +
> +    If (TRDO) {
> +      ADBG("Durng TBT_ON")
> +      Return ()
> +    }
> +
> +    If (TRD3) {
> +      ADBG("During TBT_OFF")
> +      Return ()
> +    }
> +    WWAK()
> +    WSUB(Arg0, Arg1)
> +    If(GNIS(Arg0, Arg1))
> +    {
> +      Return()
> +    }
> +
> +    OperationRegion(SPRT,SystemIO, 0xB2,2)
> +    Field (SPRT, ByteAcc, Lock, Preserve)
> +    {
> +      SSMP, 8
> +    }
> +
> +    ADBG("TBT-HP-Handler")
> +
> +    Acquire(OSUM, 0xFFFF)
> +    Store(TBFF(Arg0, Arg1), Local1)
> +    If(LEqual(Local1, 1))// Only HR
> +    {
> +      Sleep(16)
> +      Release(OSUM)
> +      ADBG("OS_Up_Received")
> +      Return ()
> +    }
> +    If(LEqual(Local1, 2)) // Disconnect
> +    {
> +      NTFY(Arg0, Arg1)
> +      Sleep(16)
> +      Release(OSUM)
> +      ADBG("Disconnect")
> +      Return ()
> +    }
> +
> +    // HR and EP
> +    If(LEqual(SOHP, 1))
> +    {
> +      // Trigger SMI to enumerate PCIe Structure
> +      ADBG("TBT SW SMI")
> +      Store(21, TBSF)
> +      Store(0xF7, SSMP)
> +    }
> +    NTFY(Arg0, Arg1)
> +    Sleep(16)
> +    Release(OSUM)
> +
> +    ADBG("End-of-XTBT")
> +  } // End of Method(XTBT)
> +
> +  //
> +  // Calling Method to Handle enumerate PCIe structure through
> +  // SMI for Thunderbolt(TM) devices for Tier 1 GPIOs
> +  // Used in Two ways ,
> +  // If CIO GPIO(1 Tier) is Different for the Controllers, this will be used as 1 Tier
> GPIO Handler for 1st controller
> +  // If CIO GPIO(1 Tier) is Same for all the controllers, this will be used as 1 Tier
> GPIO Handler for All the controllers
> +  //
> +  Method(ATBT)
> +  {
> +    ADBG("ATBT")
> +    //
> +    // Calling Method to Handle enumerate PCIe structure through
> +    //
> +    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
> +      If(LEqual(RPN0,1))
> +      {
> +        XTBT(RPS0, RPT0)
> +      }
> +    } Else {
> +      If(LEqual(RPN0,1))
> +      {
> +        XTBT(RPS0, RPT0)
> +      }
> +      ElseIf(LEqual(RPN1,1))
> +      {
> +        XTBT(RPS1, RPT1)
> +      }
> +    }
> +    ADBG("End-of-ATBT")
> +  } // End of Method(ATBT)
> +
> +  Method(BTBT)
> +  {
> +    ADBG("BTBT")
> +    //
> +    // Calling Method to Handle enumerate PCIe structure through
> +    //
> +    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
> +      If(LEqual(RPN1,1))
> +      {
> +        XTBT(RPS1, RPT1)
> +      }
> +    }
> +    ADBG("End-of-BTBT")
> +  } // End of Method(BTBT)
> +  //
> +  // Method to call OSPU Mail box command
> +  // Arg0 : Controller type 0x00 : Discrete 0x80 : Integrated TBT
> +  // Arg1 : TBT RP Selector / DMA
> +  // Arg2 : TBT Type (PCH or PEG)
> +  //
> +  Method(TINI, 3, Serialized)
> +  {
> +    ADBG("TINI")
> +    If(Lequal (Arg0, DTBT_CONTROLLER))
> +    {
> +      //ADBG("DTBT")
> +    Store(MMRP(Arg1, Arg2), Local0)
> +      OperationRegion(RP_X,SystemMemory,Local0,0x20)
> +      Field(RP_X,DWordAcc, NoLock, Preserve)
> +      {
> +        REG0, 32,
> +        REG1, 32,
> +        REG2, 32,
> +        REG3, 32,
> +        REG4, 32,
> +        REG5, 32,
> +        REG6, 32,
> +        REG7, 32
> +      }
> +      Store(REG6, Local1)
> +      Store(0x00F0F000, REG6)
> +      Store(MMTB(Arg1, Arg2), Local2)
> +      OSUP(Local2, DTBT_CONTROLLER)
> +      Store(Local1, REG6)
> +    }
> +    ADBG("End-of-TINI")
> +  }
> +
> +} // End of Scope (\_GPE)
> +
> +Scope (\_SB)
> +{
> +  //
> +  // The code needs to be executed for TBT Hotplug Handler event (2-tier GPI
> GPE event architecture) is presented here
> +  //
> +  Method(THDR, 3, Serialized)
> +  {
> +    ADBG("THDR")
> +    \_SB.CAGS(Arg0)
> +    \_GPE.XTBT(Arg1, Arg2)
> +  } // End of Method(THDR, 3, Serialized)
> +} // End of Scope(\_SB)
> +
> +Scope (\_SB)
> +{
> +  //
> +  // Name: CGWR [Combined GPIO Write]
> +  // Description: Function to write into GPIO
> +  // Input: Arg0 -> GpioPad / Expander pin
> +  //        Arg1 -> Value
> +  // Return: Nothing
> +  //
> +  Method(CGWR, 2, Serialized)
> +  {
> +    // PCH
> +    If (CondRefOf(\_SB.SGOV))
> +    {
> +      \_SB.SGOV(Arg0, Arg1)
> +    }
> +  } // End of Method(CGWR, 4, Serialized)
> +
> +  //
> +  // Name: CGRD [Combined GPIO Read]
> +  // Description: Function to read from GPIO
> +  // Input: Arg0 -> GpioPad / Expander pin
> +  //        Arg1 -> 0: GPO [GPIO TX State]
> +  //                1: GPI [GPIO RX State]
> +  // Return: Value
> +  //
> +  Method(CGRD, 2, Serialized)
> +  {
> +    Store(1, Local0)
> +    // PCH
> +    If (LEqual(Arg1, 0))
> +    {
> +      // GPIO TX State
> +      If (CondRefOf(\_SB.GGOV))
> +      {
> +        Store(\_SB.GGOV(Arg0), Local0)
> +      }
> +    }
> +    ElseIf (LEqual(Arg1, 1))
> +    {
> +      // GPIO RX State
> +      If (CondRefOf(\_SB.GGIV))
> +      {
> +        Store(\_SB.GGIV(Arg0), Local0)
> +      }
> +    }
> +    Return(Local0)
> +  } // End of Method(CGRD, 4, Serialized)
> +  //
> +  // Name: WRGP [GPIO Write]
> +  // Description: Function to write into GPIO
> +  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
> +  //        Arg1 -> Value
> +  // Return: Nothing
> +  //
> +  Method(WRGP, 2, Serialized)
> +  {
> +    Store(Arg0, Local0)
> +    Store(Arg0, Local1)
> +    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
> +    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
> +    If (LEqual(And(Local0, 0xFF), 1))
> +    {
> +      // PCH
> +      \_SB.CGWR(Local1, Arg1)
> +    }
> +  } // End of Method(WRGP, 2, Serialized)
> +
> +  //
> +  // Name: RDGP [GPIO Read]
> +  // Description: Function to write into GPIO
> +  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
> +  //        Arg1 -> In case of PCH Gpio Read {GPIO TX(0)/RX(1) State indicator}
> +  // Return: Value
> +  //
> +  Method(RDGP, 2, Serialized)
> +  {
> +    Store(1, Local7)
> +    Store(Arg0, Local0)
> +    Store(Arg0, Local1)
> +    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
> +    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
> +    If (LEqual(And(Local0, 0xFF), 1))
> +    {
> +      // PCH
> +      Store(\_SB.CGRD(Local1, Arg1), Local7)
> +    }
> +    Return(Local7)
> +  } // End of Method(RDGP, 2, Serialized)
> +
> +} // End of Scope(\_SB)
> +
> +Scope(\_SB)
> +{
> +  // Asserts/De-asserts TBT force power
> +  Method(TBFP, 2)
> +  {
> +    If(Arg0)
> +    {
> +      // Implementation dependent way to assert TBT force power
> +      If(LEqual(Arg1, 1)) {
> +        CGWR(FPG0, FP0L)
> +      }
> +      Else {
> +        CGWR(FPG1, FP1L)
> +      }
> +    }
> +    Else
> +    {
> +      // Implementation dependent way to de-assert TBT force power
> +      If(LEqual(Arg1, 1)) {
> +        CGWR(FPG0, LNot(FP0L))
> +      }
> +      Else {
> +        CGWR(FPG1, LNot(FP1L))
> +      }
> +    }
> +  }
> +
> +  // WMI ACPI device to control TBT force power
> +  Device(WMTF)
> +  {
> +    // pnp0c14 is pnp id assigned to WMI mapper
> +    Name(_HID, "PNP0C14")
> +    Name(_UID, "TBFP")
> +
> +    Name(_WDG, Buffer() {
> +      // {86CCFD48-205E-4A77-9C48-2021CBEDE341}
> +      0x48, 0xFD, 0xCC, 0x86,
> +      0x5E, 0x20,
> +      0x77, 0x4A,
> +      0x9C, 0x48,
> +      0x20, 0x21, 0xCB, 0xED, 0xE3, 0x41,
> +      84, 70,    // Object Id (TF)
> +      1,         // Instance Count
> +      0x02       // Flags (WMIACPI_REGFLAG_METHOD)
> +    })
> +
> +    // Set TBT force power
> +    // Arg2 is force power value
> +    Method(WMTF, 3)
> +    {
> +      CreateByteField(Arg2,0,FP)
> +
> +      If(FP)
> +      {
> +        TBFP(1, 1)
> +      }
> +      Else
> +      {
> +        TBFP(0, 1)
> +      }
> +    }
> +  }
> +} // End of Scope(\_SB)
> +
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 1),LEqual(RPS1, 1))))
> +{
> +  Scope(\_SB.PCI0.RP01)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP01)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 2),LEqual(RPS1, 2))))
> +{
> +  Scope(\_SB.PCI0.RP02)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP02)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 3),LEqual(RPS1, 3))))
> +{
> +  Scope(\_SB.PCI0.RP03)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP03)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 4),LEqual(RPS1, 4))))
> +{
> +  Scope(\_SB.PCI0.RP04)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP04)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 5),LEqual(RPS1, 5))))
> +{
> +  Scope(\_SB.PCI0.RP05)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP05)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 6),LEqual(RPS1, 6))))
> +{
> +  Scope(\_SB.PCI0.RP06)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP06)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 7),LEqual(RPS1, 7))))
> +{
> +  Scope(\_SB.PCI0.RP07)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP07)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 8),LEqual(RPS1, 8))))
> +{
> +  Scope(\_SB.PCI0.RP08)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP08)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 9),LEqual(RPS1, 9))))
> +{
> +  Scope(\_SB.PCI0.RP09)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP09)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 10),LEqual(RPS1, 10))))
> +{
> +  Scope(\_SB.PCI0.RP10)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP10)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 11),LEqual(RPS1, 11))))
> +{
> +  Scope(\_SB.PCI0.RP11)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP11)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 12),LEqual(RPS1, 12))))
> +{
> +  Scope(\_SB.PCI0.RP12)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP12)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 13),LEqual(RPS1, 13))))
> +{
> +  Scope(\_SB.PCI0.RP13)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP13)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 14),LEqual(RPS1, 14))))
> +{
> +  Scope(\_SB.PCI0.RP14)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP14)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 15),LEqual(RPS1, 15))))
> +{
> +  Scope(\_SB.PCI0.RP15)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP15)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 16),LEqual(RPS1, 16))))
> +{
> +  Scope(\_SB.PCI0.RP16)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP16)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 17),LEqual(RPS1, 17))))
> +{
> +  Scope(\_SB.PCI0.RP17)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP17)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 18),LEqual(RPS1, 18))))
> +{
> +  Scope(\_SB.PCI0.RP18)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP18)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 19),LEqual(RPS1, 19))))
> +{
> +  Scope(\_SB.PCI0.RP19)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP19)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 20),LEqual(RPS1, 20))))
> +{
> +  Scope(\_SB.PCI0.RP20)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP20)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 21),LEqual(RPS1, 21))))
> +{
> +  Scope(\_SB.PCI0.PEG0)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.PEG0)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 22),LEqual(RPS1, 22))))
> +{
> +  Scope(\_SB.PCI0.PEG1)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.PEG1)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 23),LEqual(RPS1, 23))))
> +{
> +  Scope(\_SB.PCI0.PEG2)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.PEG2)
> +}
> +
> +Scope(\_SB)
> +{
> +    //
> +    // Name: PERB
> +    // Description: Function to read a Byte from PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    // Return: Byte data read from PCIE-MMIO
> +    //
> +    Method(PERB,5,Serialized)
> +    {
> +      ADBG("PERB")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 1)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 8
> +      }
> +
> +      Return(TEMP)
> +    } // End of Method(PERB,5,Serialized)
> +
> +    //
> +    // Name: PEWB
> +    // Description: Function to write a Byte into PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    //        Arg5 -> Data
> +    // Return: Nothing
> +    //
> +    Method(PEWB,6,Serialized)
> +    {
> +      ADBG("PEWB")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 1)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 8
> +      }
> +
> +      Store(Arg5,TEMP)
> +    } // End of Method(PEWB,6,Serialized)
> +
> +    //
> +    // Name: PERW
> +    // Description: Function to read a Word from PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    // Return: Word data read from PCIE-MMIO
> +    //
> +    Method(PERW,5,Serialized)
> +    {
> +      ADBG("PERW")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 2)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 16
> +      }
> +
> +      Return(TEMP)
> +    } // End of Method(PERW,5,Serialized)
> +
> +    //
> +    // Name: PEWW
> +    // Description: Function to write a Word into PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    //        Arg5 -> Data
> +    // Return: Nothing
> +    //
> +    Method(PEWW,6,Serialized)
> +    {
> +      ADBG("PEWW")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 2)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 16
> +      }
> +
> +      Store(Arg5,TEMP)
> +    } // End of Method(PEWW,6,Serialized)
> +
> +    //
> +    // Name: PERD
> +    // Description: Function to read a Dword from PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    // Return: Dword data read from PCIE-MMIO
> +    //
> +    Method(PERD,5,Serialized)
> +    {
> +      ADBG("PERD")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 4)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 32
> +      }
> +
> +      Return(TEMP)
> +    } // End of Method(PERD,5,Serialized)
> +
> +    //
> +    // Name: PEWD
> +    // Description: Function to write a Dword into PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    //        Arg5 -> Data
> +    // Return: Nothing
> +    //
> +    Method(PEWD,6,Serialized)
> +    {
> +      ADBG("PEWD")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 4)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 32
> +      }
> +
> +      Store(Arg5,TEMP)
> +    } // End of Method(PEWD,6,Serialized)
> +
> +    //
> +    // Name: STDC
> +    // Description: Function to get Standard Capability Register Offset
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Capability ID
> +    // Return: Capability Register Offset data
> +    //
> +    Method(STDC,5,Serialized)
> +    {
> +      ADBG("STDC")
> +
> +      //Check for Referenced device is present or not
> +      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x00), Local7) //Vendor ID register
> +      If(LEqual(Local7, 0xFFFF))
> +      {
> +        ADBG("Referenced device is not present")
> +        Return(0)
> +      }
> +
> +      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x06), Local0) //Device Status register
> +      If (LEqual(And(Local0, 16), 0)) //Bit4 - Capabilities List
> +      {
> +        //No Capabilities linked list is available
> +        ADBG("No Capabilities linked list is available")
> +        Return(0)
> +      }
> +
> +      //Local1 is for storing CapabilityID
> +      //Local2 is for storing CapabilityPtr
> +      Store(PERB(Arg0, Arg1, Arg2, Arg3, 0x34), Local2) //CapabilityPtr
> +
> +      While(1)
> +      {
> +        And(Local2, 0xFC, Local2) //Each capability must be DWORD aligned
> +
> +        If(LEqual(Local2, 0)) //A pointer value of 00h is used to indicate the last
> capability in the list
> +        {
> +          ADBG("Capability ID is not found")
> +          Return(0)
> +        }
> +
> +        Store(PERB(Arg0, Arg1, Arg2, Arg3, Local2), Local1) //CapabilityID
> +
> +        If(LEqual(Arg4, Local1)) //CapabilityID match
> +        {
> +          ADBG("Capability ID is found")
> +          ADBG("Capability Offset : ")
> +          ADBG(Local2)
> +          Return(Local2)
> +        }
> +        Store(PERB(Arg0, Arg1, Arg2, Arg3, Add(Local2, 1)), Local2)
> //CapabilityPtr
> +        Return(0)
> +      }
> +    } // End of Method(STDC,5,Serialized)
> +
> +} // End Scope(\_SB)
> +
> --
> 2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
@ 2019-08-17  1:18   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17  1:18 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com> 

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers

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

Create the CoffeelakeSiliconPkg to provide an initial package for
silicon initialization code for Coffee Lake (CFL) and Whiskey Lake
(WHL) generation products.

* Major areas of functionality are categorized into CPU, Management
  Engine (ME), 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: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec                              | 714 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h                  |  53 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h         |  89 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h        | 291 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h         | 157 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h       |  64 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h             |  28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h | 123 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h     |  58 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h          | 110 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h          |  22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h               |  34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h                     | 319 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h                 |  29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h  |  26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h   |  71 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h    |  60 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h             |  55 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h                  |  19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h               |  65 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h         |  23 +
 21 files changed, 2410 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
new file mode 100644
index 0000000000..fa8c11e93d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
@@ -0,0 +1,714 @@
+## @file
+# Component description file for the Silicon Reference Code.
+#
+# Copyright (c) 2019 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]
+  Include
+  SampleCode/Include
+  SampleCode/MdeModulePkg/Include
+  SampleCode/IntelFrameworkPkg/Include
+  #
+  # SystemAgent
+  #
+  SystemAgent/Include
+  SystemAgent/MemoryInit/Include
+  SystemAgent/AcpiTables
+  #
+  # Cpu
+  #
+  Cpu/Include
+  #
+  # Me
+  #
+  Me/Include
+  #
+  # Pch
+  #
+  Pch/Include
+
+[Guids.common.Private]
+  #
+  # PCH
+  #
+  gPchDeviceTableHobGuid       = { 0xb3e123d0, 0x7a1e, 0x4db4, { 0xaf, 0x66, 0xbe, 0xd4, 0x1e, 0x9c, 0x66, 0x38 }}
+  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 }}
+
+[Guids]
+##
+## 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}}
+
+##
+## IntelFrameworkPkg
+##
+gEfiSmmPeiSmramMemoryReserveGuid =  {0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d}}
+
+##
+## Common
+##
+## Include/ConfigBlock/SiConfig.h
+gSiConfigGuid = {0x4ed6d282, 0x22f3, 0x4fe1, {0xa6, 0x61, 0x6, 0x1a, 0x97, 0x38, 0x59, 0xd8 }}
+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}}
+
+##
+## System Agent
+##
+gSaAcpiTableStorageGuid  =  {0x3c0ed5e2, 0x91ea, 0x4b94, { 0x82, 0xd, 0x9d, 0xaf, 0x9a, 0x3b, 0xb4, 0xa2}}
+gSaDataHobGuid  =  {0xe07d0bda, 0xbf90, 0x46a9, { 0xb0, 0x0e, 0xb2, 0xc4, 0x4a, 0x0e, 0xd6, 0xd0}}
+gSaConfigHobGuid  = {0x762fa2e6, 0xea3b, 0x41c8, { 0x8c, 0x52, 0x63, 0x76, 0x6d, 0x70, 0x39, 0xe0}}
+gSaPegHobGuid  = {0x440ab2e5, 0xa3ea, 0x466f, { 0x84, 0x96, 0xdf, 0xb1, 0x3b, 0x75, 0x29, 0x95}}
+gSgAcpiTableStorageGuid  =  {0x8de8964f, 0x2939, 0x4b49, { 0xa3, 0x48, 0xf6, 0xb2, 0xb2, 0xde, 0x4a, 0x42}}
+gSaSsdtAcpiTableStorageGuid  =  {0xca89914d, 0x2317, 0x452e, { 0xb2, 0x45, 0x36, 0xc6, 0xfb, 0x77, 0xa9, 0xc6}}
+gPegSsdtAcpiTableStorageGuid  =  {0xE05B8635, 0xE5C0, 0x4D88, { 0xB6, 0x29, 0x19, 0xD6, 0xA2, 0xC6, 0xE9, 0x2E}}
+gSgAcpiTablePchStorageGuid  =  {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}}
+gSaPciePeiPreMemConfigGuid  =  { 0x81baf3c9, 0xf295, 0x4572, { 0x8b, 0x21, 0x79, 0x3f, 0xa3, 0x1b, 0xa5, 0xdb}}
+gSaPciePeiConfigGuid  =  { 0xdaa929a9, 0x5ec9, 0x486a, { 0xb0, 0xf7, 0x82, 0x3a, 0x55, 0xc7, 0xb5, 0xb3}}
+gGraphicsPeiPreMemConfigGuid  =  { 0x0319c56b, 0xc43a, 0x42f1, { 0x80, 0xbe, 0xca, 0x5b, 0xd1, 0xd5, 0xc9, 0x28}}
+gGraphicsPeiConfigGuid  =  { 0x04249ac0, 0x0088, 0x439f, { 0xa7, 0x4e, 0xa7, 0x04, 0x2a, 0x06, 0x2f, 0x5d}}
+gSwitchableGraphicsConfigGuid  =  { 0xc7956998, 0xc065, 0x46c4, { 0x8e, 0x2f, 0x58, 0x2b, 0x67, 0xeb, 0xbe, 0x2f}}
+gCpuTraceHubConfigGuid =  { 0xf2e17477, 0x93f3, 0x430d, { 0x9e, 0x08, 0x3c, 0xcc, 0x6e, 0x2f, 0x6c, 0x4b}}
+gMemoryConfigGuid  =  { 0x26cf084c, 0xc9db, 0x41bb, { 0x92, 0xc6, 0xd1, 0x97, 0xb8, 0xa1, 0xe4, 0xbf}}
+gMemoryConfigNoCrcGuid  =  { 0xc56c73d0, 0x1cdb, 0x4c0c, { 0xa9, 0x57, 0xea, 0x62, 0xa9, 0xe6, 0xf5, 0x0c}}
+gIpuPreMemConfigGuid  =  { 0x830a222b, 0x3ff5, 0x432e, { 0x9d, 0xd5, 0x4e, 0xe3, 0xfc, 0xa2, 0xaa, 0xa2}}
+gGnaConfigGuid  =  { 0x53e0ef18, 0xb8a8, 0x4795, { 0xa6, 0x6d, 0xe4, 0x77, 0x2c, 0xc3, 0xae, 0x82}}
+gVtdConfigGuid  =  { 0x03e5cf63, 0xbebb, 0x4041, { 0xb7, 0xe7, 0xbf, 0x54, 0x61, 0x20, 0xf1, 0xc5}}
+gGraphicsDxeConfigGuid  =  {0x34d93161, 0xf78e, 0x4915, {0xad, 0xc4, 0xdb, 0x67, 0x16, 0x42, 0x39, 0x24}}
+gMiscDxeConfigGuid  =  {0x7ce5f5ef, 0x4ef1, 0x4f9f, {0x8e, 0x29, 0x5f, 0xf4, 0x5f, 0x2f, 0xd8, 0xaf}}
+gPcieDxeConfigGuid  =  {0x1ed2d6f1, 0xa9d2, 0x476e, {0x8e, 0x74, 0xad, 0xd9, 0x5b, 0x5,  0x10, 0x82}}
+gMemoryDxeConfigGuid  =  {0xa5c7dda8, 0x686b, 0x404f, {0x86, 0x40, 0xf8, 0x2,  0xd,  0x84, 0x4c, 0x94}}
+gVbiosDxeConfigGuid  =  {0x8df0f30a, 0x8156, 0x4897, {0xa2, 0x18, 0x1f, 0xd3, 0x91, 0xbc, 0x46, 0x26}}
+gSaOverclockingPreMemConfigGuid  =  { 0x09ecc29d, 0xdbbe, 0x49fb, { 0xa6, 0x49, 0x4b, 0xf6, 0x40, 0xe2, 0xeb, 0xd6}}
+gFspReservedMemoryResourceHobTsegGuid  =  { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}}
+
+## 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}}
+
+## 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 }}
+
+##
+## 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}}
+gHtBistHobGuid  =  {0xbe644001, 0xe7d4, 0x48b1, {0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7}}
+gCpuInitDataHobGuid  =  {0x266e31cc, 0x13c5, 0x4807, {0xb9, 0xdc, 0x39, 0xa6, 0xba, 0x88, 0xff, 0x1a}}
+gEpcBiosDataGuid  =  {0xc60aa7f6, 0xe8d6, 0x4956, {0x8b, 0xa1, 0xfe, 0x26, 0x29, 0x8f, 0x5e, 0x87}}
+gCpuSecurityPreMemConfigGuid = {0xfd5c346, 0x8260, 0x4067, {0x94, 0x69, 0xcf, 0x91, 0x68, 0xa3, 0x42, 0x90}}
+gCpuConfigLibPreMemConfigGuid = {0xfc1c0ec2, 0xc6b4, 0x4f05, {0xbb, 0x85, 0xc8, 0x0, 0x8d, 0x5b, 0x4a, 0xb7}}
+gCpuSgxConfigGuid = {0xc30bc5ac, 0x828a, 0x45ae, {0x83, 0x1b, 0x8e, 0xb, 0x73, 0x9a, 0xb2, 0xf2}}
+gCpuTestConfigGuid = {0xd4dba957, 0xd9c, 0x4af2, {0x9d, 0x40, 0x35, 0xa8, 0x44, 0xe4, 0x93, 0xad}}
+gCpuConfigGuid = {0x48c3aac9, 0xd66c, 0x42e4, {0x9b, 0x1d, 0x39, 0x4, 0x5f, 0x46, 0x53, 0x41}}
+gCpuOverclockingPreMemConfigGuid = {0x396223b6, 0x6088, 0x44e7, {0x99, 0xcb, 0xfa, 0x8b, 0x99, 0x3d, 0xed, 0x4c}}
+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}}
+gCpuPowerMgmtTestConfigGuid = {0x5161ed3d, 0x90bf, 0x436f, {0xb8, 0x33, 0xd7, 0x17, 0x89, 0xb3, 0x48, 0xc1}}
+
+##
+## Me
+##
+gMePeiPreMemConfigGuid  =  {0x67ed113b, 0xd4ab, 0x43f5, {0x9c, 0x3c, 0x35, 0x44, 0x15, 0xaa, 0x47, 0x5c}}
+gMePeiConfigGuid  =  {0x9bad5628, 0x657b, 0x48e3, {0xb1, 0x11, 0xc3, 0xb9, 0xeb, 0xea, 0xee, 0x17}}
+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}}
+
+##
+## 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 = {0x8c7ee32c, 0x0870, 0x4bfa, {0x84, 0x79, 0x5b, 0xa5, 0x67, 0xc4, 0xae, 0x5b}}
+
+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}}
+gTraceHubPreMemConfigGuid  =  {0xC26AC3F6, 0xDAD0, 0x4E91, {0xB6, 0xD6, 0xD8, 0x51, 0x6F, 0x8F, 0x9B, 0x7B}}
+gPchTraceHubPreMemConfigGuid  = {0x8456c11, 0xdb85, 0x4914, {0x8d, 0x1a, 0xe5, 0xac, 0x64, 0x37, 0xe8, 0x96}}
+gPcieRpPreMemConfigGuid  =  {0x8377AB38, 0xF8B0, 0x476A, { 0x9C, 0xA1, 0x68, 0xEA, 0x78, 0x57, 0xD8, 0x2A}}
+gHpetPreMemConfigGuid  =  {0x7C75C0F1, 0xA20F, 0x42EB, {0x83, 0xDE, 0xE8, 0x58, 0xAB, 0x81, 0xC5, 0xDC}}
+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}}
+gHsioPreMemConfigGuid  =  {0xbc9e5787, 0x3ddb, 0x4916, {0x8c, 0xcc, 0x82, 0xb8, 0x9, 0x43, 0xe2, 0xf0}} #deprecated
+
+gPchGeneralConfigGuid  =  {0x6ED94C8C, 0x25F7, 0x4686, {0xB2, 0x46, 0xCA, 0x4D, 0xE2, 0x95, 0x4B, 0x5D}}
+gPcieRpConfigGuid  =  {0x0A53B507, 0x988B, 0x475C, {0xBF, 0x76, 0x33, 0xDE, 0x10, 0x6D, 0x94, 0x84}}
+gSataConfigGuid  =  {0xF5F87B4F, 0xCC3C, 0x408D, {0x89, 0xE3, 0x61, 0xC5, 0x9C, 0x54, 0x07, 0xC4}}
+gIoApicConfigGuid  =  {0x2873D0F1, 0x00F6, 0x40AB, {0xAC, 0x36, 0x9A, 0x68, 0xBA, 0x87, 0x3E, 0x6C}}
+gCio2ConfigGuid  =  {0xFBC4C192, 0x789D, 0x4038, {0x90, 0xE1, 0x5E, 0x6D, 0xFD, 0x52, 0xAF, 0x8A}}
+gDmiConfigGuid  =  {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}}
+gLanConfigGuid  =  {0x4B2DE99E, 0x7517, 0x4D04, {0x8C, 0x02, 0xF1, 0x1A, 0x59, 0x2B, 0x14, 0x2F}}
+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}}
+gPort61ConfigGuid  =  {0x59913475, 0x1960, 0x4099, {0x80, 0xEC, 0xAF, 0xC7, 0xCF, 0x5F, 0x9F, 0xAC}}
+gScsConfigGuid  =  {0xF4DE6D52, 0xB5C9, 0x48C0, {0xA0, 0x4A, 0x68, 0x54, 0x20, 0x94, 0x05, 0xD0}}
+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}}
+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}}
+
+##
+## 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 }}
+gTpmDeviceInstanceTpm20PttGuid        =  {0x72cd3a7b, 0xfea5, 0x4f5e, {0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13}}
+gTpmDeviceInstanceTpm20PttPtpGuid     =  {0x93d66f66, 0x55da, 0x4f03, {0x9b, 0x5f, 0x32, 0xcf, 0x9e, 0x54, 0x3b, 0x3a}}
+gEfiTrEEPhysicalPresenceGuid          =  {0xf24643c2, 0xc622, 0x494e, {0x8a, 0x0d, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b}}
+gTcoWdtHobGuid                        = { 0x3e405418, 0x0d8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x08, 0x41, 0x46, 0x8d }}
+
+##
+## Pre-Memory 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}}
+
+##
+## Post-Memory 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}}
+
+[Protocols.common.Private]
+  #
+  # SA
+  #
+  gSaIotrapSmiProtocolGuid        = { 0x1861e089, 0xcaa3, 0x473e, { 0x84, 0x32, 0xdc, 0x1f, 0x94, 0xc6, 0xc1, 0xa6 }}
+
+  #
+  # CPU
+  #
+  gPchPcieIoTrapProtocolGuid      = { 0xd66a1cf,  0x79ad, 0x494b, { 0x97, 0x8b, 0xb2, 0x59, 0x81, 0x68, 0x93, 0x34 }}
+
+[Protocols]
+##
+## IntelFrameworkPkg
+##
+gEfiLegacyBiosProtocolGuid  =  {0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d}}
+gEfiLegacyInterruptProtocolGuid  =  {0x31ce593d, 0x108a, 0x485d, {0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe}}
+gEfiDataHubProtocolGuid  =  {0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81}}
+
+##
+## MdeModulePkg
+##
+gEfiSmmVariableProtocolGuid  =  {0xed32d533, 0x99e6, 0x4209, {0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7}}
+
+##
+## 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}}
+gGopComponentName2ProtocolGuid  =  {0x651b7ebd, 0xce13, 0x41d0, {0x82, 0xe5, 0xa0, 0x63, 0xab, 0xbe, 0x9b, 0xb6}}
+gGopOverrideProtocolGuid        =  {0x4a89a16e, 0x67b8, 0x4429, {0x8c, 0x47, 0x43, 0x67, 0x90, 0xf2, 0xf2, 0x69}}
+
+##
+## AcpiTables
+##
+gEfiGlobalNvsAreaProtocolGuid  =  {0x074e1e48, 0x8132, 0x47a1, {0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc}}
+
+##
+## Cpu
+##
+gCpuInfoProtocolGuid  =  {0xe223cf65, 0xf6ce, 0x4122, {0xb3, 0xaf, 0x4b, 0xd1, 0x8a, 0xff, 0x40, 0xa1}}
+gCpuNvsAreaProtocolGuid  =  {0xb9cf3f43, 0xbe3e, 0x4e45, {0xa0, 0xbe, 0x1a, 0x4, 0x89, 0xdf, 0x1a, 0xc9}}
+gDxeCpuPolicyProtocolGuid  =  {0x8282b977, 0x22f9, 0x4134, {0x99, 0x43, 0x7b, 0xcc, 0x5f, 0x40, 0x33, 0x52}}
+
+##
+## Me
+##
+gDxeMePolicyGuid                 = {0xa0b5dc52, 0x4f34, 0x3990, {0xd4, 0x91, 0x10, 0x8b, 0xe8, 0xba, 0x75, 0x42}}
+
+##
+## PCH
+##
+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}}
+gPchResetCallbackProtocolGuid  =  {0x3a3300ab, 0xc929, 0x487d, {0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0}}
+gPchNvsAreaProtocolGuid  =  {0x2e058b2b, 0xedc1, 0x4431, {0x87, 0xd9, 0xc6, 0xc4, 0xea, 0x10, 0x2b, 0xe3}}
+gPchEmmcTuningProtocolGuid  =  {0x10fe7e3b, 0xdbe5, 0x4cfa, {0x90, 0x25, 0x40, 0x02, 0xcf, 0xdd, 0xbb, 0x89}}
+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}}
+gPchSraProtocolGuid = {0x7AE12E27, 0x5087, 0x46C8, {0xBF, 0xF0, 0x83, 0x9C, 0x53, 0x7B, 0x25, 0xEB}}
+
+##
+## 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 }}
+
+[Ppis.common.Private]
+
+[Ppis]
+##
+## MdeModulePkg
+##
+gPeiCapsulePpiGuid  =  {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d}}
+gPeiSmmAccessPpiGuid  =  {0x268f33a9, 0xcccd, 0x48be, {0x88, 0x17, 0x86, 0x05, 0x3a, 0xc3, 0x2e, 0xd6}}
+gPeiSmmControlPpiGuid  =  {0x61c68702, 0x4d7e, 0x4f43, {0x8d, 0xef, 0xa7, 0x43, 0x05, 0xce, 0x74, 0xc5}}
+
+##
+## SecurityPkg
+##
+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}}
+
+##
+## 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}}
+
+##
+## Cpu
+##
+gPeiCachePpiGuid  =  {0x09be4bc2, 0x790e, 0x4dea, {0x8b, 0xdc, 0x38, 0x05, 0x16, 0x98, 0x39, 0x44}}
+
+##
+## Me
+##
+gMeDidSentPpiGuid = {0x45dc3106, 0xef67, 0x4c71, {0xb0, 0xf0, 0x97, 0x15, 0x9c, 0x7d, 0xbb, 0x7c}}
+
+##
+## 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}}
+gPchResetCallbackPpiGuid  =  {0x17865dc0, 0x0b8b, 0x4da8, {0x8b, 0x42, 0x7c, 0x46, 0xb8, 0x5c, 0xca, 0x4d}}
+
+[LibraryClasses]
+##
+## Common
+##
+AslUpdateLib|Include/Library/AslUpdateLib.h
+SiPolicyLib|Include/Library/SiPolicyLib.h
+UsbLib|Include/Library/UsbLib.h
+UsbInitLib|Include/Private/Library/UsbInitLib.h
+
+##
+## CPU
+##
+CpuMailboxLib|Cpu/Include/Library/CpuMailboxLib.h
+CpuPlatformLib|Cpu/Include/Library/CpuPlatformLib.h
+CpuPolicyLib|Cpu/Include/Library/CpuPolicyLib.h
+
+##
+## Me
+##
+PeiMePolicyLib|Me/Include/Library/PeiMePolicyLib.h
+
+##
+## Pch
+##
+GpioLib|Pch/Include/Library/GpioLib.h
+GpioLib|Pch/Include/Library/GpioNativeLib.h
+PchCycleDecodingLib|Pch/Include/Library/PchCycleDecodingLib.h
+PchEspiLib|Pch/Include/Library/PchEspiLib.h
+PchGbeLib|Pch/Include/Library/PchGbeLib.h
+GbeMdiLib|Pch/Include/Library/GbeMdiLib.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
+PchPmcLib|Pch/Include/Library/PchPmcLib.h
+PchPolicyLib|Pch/Include/Library/PchPolicyLib.h
+PchSbiAccessLib|Pch/Include/Library/PchSbiAccessLib.h
+PchSerialIoLib|Pch/Include/Library/PchSerialIoLib.h
+PchSerialIoUartLib|Pch/Include/Library/PchSerialIoUartLib.h
+SecPchLib|Pch/Include/Library/SecPchLib.h
+PchTraceHubLib|Pch/Include/Private/Library/PchTraceHubLib.h
+PchSmmControlLib|Pch/IncludePrivate/Library/PchSmmControlLib.h
+PchWdtCommonLib|Pch/Include/Library/PchWdtCommonLib.h
+OcWdtLib|Pch/Include/Library/OcWdtLib.h
+PchResetLib|Pch/Include/Library/PchResetLib.h
+DxePchPolicyLib|Pch/Include/Library/DxePchPolicyLib.h
+GpioNameBufferLib|Pch/IncludePrivate/Library/GpioNameBufferLib.h
+
+##
+## Sa
+##
+DxeSaPolicyLib|SystemAgent/Include/Library/DxeSaPolicyLib.h
+PeiSaPolicyLib|SystemAgent/Include/Library/PeiSaPolicyLib.h
+SaPlatformLib|SystemAgent/Include/Library/SaPlatformLib.h
+
+##
+## Memory
+##
+
+[PcdsFixedAtBuild]
+## From MdeModulePkg.dec
+## 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.PcdFlashMicrocodeFvBase|0xFFE60000|UINT32|0x30000004
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize|0x000A0000|UINT32|0x30000005
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|0x00660000|UINT32|0x30000006
+
+##
+## 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
+
+gSiPkgTokenSpaceGuid.PcdSmmbaseSwSmi|0x55|UINT8|0x0010005
+gSiPkgTokenSpaceGuid.PcdHwpSmi|0x27|UINT8|0x40000001
+gSiPkgTokenSpaceGuid.PcdItbmSmi|0x29|UINT8|0x40000002
+
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioBase|0x0000004000000000|UINT64|0x40000003
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioSize|0x0000004000000000|UINT64|0x40000004
+
+[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
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+## Maximun number of performance log entries during PEI phase.
+gSiPkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|40|UINT8|0x0001002f
+## This value is used to set the base address of MCH
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress|0xFED10000|UINT64|0x00010030
+## This value is used to set the base address of PCH devices
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress|0x0000EFA0|UINT16|0x00010031
+gSiPkgTokenSpaceGuid.PcdTcoBaseAddress|0x0400|UINT16|0x00010034
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress|0x1800|UINT16|0x00010035
+
+## 32KB window
+gSiPkgTokenSpaceGuid.PcdMchMmioSize|0x8000|UINT32|0x50000000
+
+## 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
+
+##
+## Default 8MB TSEG
+##
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000|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
+##
+
+##Major:To represent code generation
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionMajor   |0x07|UINT8|0x00010049
+
+##Revision:Weekly build number
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionRevision|0x57|UINT8|0x00010051
+
+##Build[7:4]:Daily build number.
+##Build[3:0]:Patch build number.
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionBuild   |0x40|UINT8|0x00010052
+
+
+##
+## 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.PcdHpetBaseAddress    |0xFED00000|UINT32|0x00010057
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress  |0xFED00000|UINT32|0x00010060
+##
+## This PCD specifies the base address of the IO APIC.
+## The acceptable values are 0xFECxx000.
+##
+#gSiPkgTokenSpaceGuid.PcdIoApicBaseAddress  |0xFEC00000|UINT32|0x00010058
+##
+## Regbar Base Address
+##
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress|0xFC000000|UINT32|0x00010059
+
+## 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
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+##
+## SerialIo Uart Configuration
+##
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable |0      |UINT8 |0x00100001 # 0:Disable, 1:Enable and Initialize, 2:Enable without Initializing
+gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber      |2      |UINT8 |0x00100002
+gSiPkgTokenSpaceGuid.PcdSerialIoUartInputClock  |1843200|UINT32|0x00100003
+gSiPkgTokenSpaceGuid.PcdSerialIoUart0PinMuxing  |0      |UINT8 |0x00100009 # 0: default pins, 1: pins muxed with CNV_BRI/RGI
+##
+## PCI Express MMIO region length
+## Valid settings: 0x10000000/256MB, 0x8000000/128MB, 0x4000000/64MB
+##
+gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000|UINT32|0x0010004
+
+## Indidates if SMM Save State saved in MSRs.
+#  if enabled, SMM Save State will use the MSRs instead of the memory.<BR><BR>
+#   TRUE  - SMM Save State will use the MSRs.<BR>
+#   FALSE - SMM Save State will use the memory.<BR>
+# @Prompt SMM Save State uses MSRs.
+gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable|FALSE|BOOLEAN|0x20000001
+[PcdsDynamic]
+
+## Indidates if SMM Delay feature is supported.<BR><BR>
+#   TRUE  - SMM Delay feature is supported.<BR>
+#   FALSE - SMM Delay feature is not supported.<BR>
+# @Prompt SMM Delay feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication|TRUE|BOOLEAN|0x0010009
+
+## Indidates if SMM Block feature is supported.<BR><BR>
+#   TRUE  - SMM Block feature is supported.<BR>
+#   FALSE - SMM Block feature is not supported.<BR>
+# @Prompt SMM Block feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication|TRUE|BOOLEAN|0x001000A
+
+## Indidates if SMM Enable/Disable feature is supported.<BR><BR>
+#   TRUE  - SMM Enable/Disable feature is supported.<BR>
+#   FALSE - SMM Enable/Disable feature is not supported.<BR>
+# @Prompt SMM Enable/Disable feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication|TRUE|BOOLEAN|0x001000B
+
+## 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|TRUE|BOOLEAN|0x001000C
+
+## 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
+
+[PcdsFeatureFlag]
+##
+## Those PCDs are used to control build process.
+##
+gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE|BOOLEAN|0xF0000001
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |FALSE|BOOLEAN|0xF0000002
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE|BOOLEAN|0xF0000004
+gSiPkgTokenSpaceGuid.PcdSiCsmEnable                  |FALSE|BOOLEAN|0xF0000005
+gSiPkgTokenSpaceGuid.PcdUseHpetTimer                 |TRUE |BOOLEAN|0xF0000006
+gSiPkgTokenSpaceGuid.PcdSgEnable                     |TRUE |BOOLEAN|0xF0000008
+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.PcdSmbiosEnable                 |TRUE |BOOLEAN|0xF0000014
+gSiPkgTokenSpaceGuid.PcdS3Enable                     |TRUE |BOOLEAN|0xF0000015
+gSiPkgTokenSpaceGuid.PcdOverclockEnable              |FALSE|BOOLEAN|0xF0000016
+gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable       |FALSE|BOOLEAN|0xF0000017
+gSiPkgTokenSpaceGuid.PcdIgdEnable                    |TRUE |BOOLEAN|0xF000001A
+gSiPkgTokenSpaceGuid.PcdPegEnable                    |TRUE |BOOLEAN|0xF000001B
+gSiPkgTokenSpaceGuid.PcdSaDmiEnable                  |TRUE |BOOLEAN|0xF000001C
+gSiPkgTokenSpaceGuid.PcdIpuEnable                    |TRUE |BOOLEAN|0xF000001D
+gSiPkgTokenSpaceGuid.PcdGnaEnable                    |TRUE |BOOLEAN|0xF000001E
+gSiPkgTokenSpaceGuid.PcdSaOcEnable                   |TRUE |BOOLEAN|0xF000001F
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE |BOOLEAN|0xF0000020
+gSiPkgTokenSpaceGuid.PcdBdatEnable                   |FALSE|BOOLEAN|0xF0000023
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE |BOOLEAN|0xF0000024
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE |BOOLEAN|0xF0000025
+gSiPkgTokenSpaceGuid.PcdCflCpuEnable                 |FALSE|BOOLEAN|0xF0000027
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |FALSE|BOOLEAN|0xF0000029
+gSiPkgTokenSpaceGuid.PcdMinTreeEnable                |FALSE|BOOLEAN|0xF000002A  # To separate modules used in mininal source tree and advanced features
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |FALSE|BOOLEAN|0xF0000033
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE|BOOLEAN|0xF0000034
+
+gSiPkgTokenSpaceGuid.PcdEdk2MasterEnable             |FALSE|BOOLEAN|0xF0000035
+gSiPkgTokenSpaceGuid.PcdPpamEnable                   |TRUE |BOOLEAN|0xF0000036
+
+#This PCD is used to enable WDT for debug purposes in OverClocking.
+gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug          |FALSE|BOOLEAN|0xF0000037
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
new file mode 100644
index 0000000000..d0e3d94418
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
new file mode 100644
index 0000000000..27b5a9440e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
@@ -0,0 +1,89 @@
+/** @file
+  Si Config Block
+
+  Copyright (c) 2019 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  3
+
+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
+  <b>Revision 3</b>
+  - Deprecated SkipPostBootSai
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Offset 0 - 27 Config Block Header
+  //
+  // Platform specific common policies that used by several silicon components.
+  //
+  UINT32 CsmFlag          :  1;  ///< Offset 44 BIT0: CSM status flag.
+  /**
+    @deprecated since revision 3
+  **/
+  UINT32 SkipPostBootSai  :  1;
+  UINT32 RsvdBits         : 30;  ///< Reserved
+  UINT32 *SsidTablePtr;          // Offset 48
+  UINT16 NumberOfSsidTableEntry; // Offset 52
+  UINT16 Reserved;               // Offset 54
+  /**
+    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
+} SI_CONFIG;
+
+#pragma pack (pop)
+
+#define DEFAULT_SSVID    0x8086
+#define DEFAULT_SSDID    0x7270
+#define 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 {
+      UINT64  Register:12;
+      UINT64  Function:3;
+      UINT64  Device:5;
+      UINT64  Bus:8;
+      UINT64  Reserved1:4;
+      UINT64  Segment:16;
+      UINT64  Reserved2:16;
+    } Bits;
+    UINT64    SegBusDevFuncRegister;
+  } Address;
+  SVID_SID_VALUE SvidSidValue;
+  UINT32 Reserved;
+} SVID_SID_INIT_ENTRY;
+
+#endif // _SI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
new file mode 100644
index 0000000000..8b51e2d47a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
@@ -0,0 +1,291 @@
+/** @file
+  Common USB policy shared between PCH and CPU
+  Contains general features settings for xHCI and xDCI
+
+  Copyright (c) 2019 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 3
+extern EFI_GUID gUsbConfigGuid;
+
+#define MAX_USB2_PORTS  16
+#define MAX_USB3_PORTS  10
+
+#pragma pack (push,1)
+
+#define PCH_USB_OC_PINS_MAX  8  ///< Maximal possible number of USB Over Current pins
+
+///
+/// Overcurrent pins, the values match the setting of EDS, please refer to EDS for more details
+///
+typedef enum {
+  UsbOverCurrentPin0 = 0,
+  UsbOverCurrentPin1,
+  UsbOverCurrentPin2,
+  UsbOverCurrentPin3,
+  UsbOverCurrentPin4,
+  UsbOverCurrentPin5,
+  UsbOverCurrentPin6,
+  UsbOverCurrentPin7,
+  UsbOverCurrentPinMax,
+  UsbOverCurrentPinSkip = 0xFF
+} USB_OVERCURRENT_PIN;
+
+/**
+  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;
+} USB20_AFE;
+
+/**
+  This structure configures per USB2 port physical settings.
+  It allows to setup the port location and port length, and configures the port strength accordingly.
+**/
+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 (see: USB_OVERCURRENT_PIN).
+  **/
+  UINT32     OverCurrentPin     :  8;
+  UINT32     Enable             :  1;     ///< 0: Disable; <b>1: Enable</b>.
+  UINT32     RsvdBits0          : 23;     ///< Reserved bits
+  /**
+    Changing this policy values from default ones may require disabling USB2 PHY Sus Well Power Gating
+    through Usb2PhySusPgEnable on PCH-LP
+  **/
+  USB20_AFE  Afe;                         ///< USB2 AFE settings
+} USB20_PORT_CONFIG;
+
+/**
+  This structure describes whether the USB3 Port N is enabled by platform modules.
+**/
+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 (see: USB_OVERCURRENT_PIN).
+  **/
+  UINT32  OverCurrentPin            :  8;
+
+  /**
+    USB 3.0 TX Output Downscale Amplitude Adjustment (orate01margin)
+    HSIO_TX_DWORD8[21:16]
+    <b>Default = 00h</b>
+  **/
+  UINT32  HsioTxDownscaleAmp        :  8;
+  /**
+    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)
+  **/
+  UINT32  HsioTxDeEmph              :  8;
+
+  UINT32  Enable                    :  1; ///< 0: Disable; <b>1: Enable</b>.
+  UINT32  HsioTxDeEmphEnable        :  1; ///< Enable the write to USB 3.0 TX Output -3.5dB De-Emphasis Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioTxDownscaleAmpEnable  :  1; ///< Enable the write to USB 3.0 TX Output Downscale Amplitude Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                 :  5; ///< Reserved bits
+} USB30_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;
+
+//
+// Below defines are for proper UPD construction and values syncing between UPD and policy
+//
+#define B_XHCI_HSIO_CTRL_ADAPT_OFFSET_CFG_EN      BIT0  ///< Enable the write to Signed Magnatude number added to the CTLE code bit
+#define B_XHCI_HSIO_FILTER_SELECT_N_EN            BIT1  ///< Enable the write to LFPS filter select for n
+#define B_XHCI_HSIO_FILTER_SELECT_P_EN            BIT2  ///< Enable the write to LFPS filter select for p
+#define B_XHCI_HSIO_LFPS_CFG_PULLUP_DWN_RES_EN    BIT3  ///< Enable the write to olfpscfgpullupdwnres
+#define N_XHCI_UPD_HSIO_CTRL_ADAPT_OFFSET_CFG     3
+#define N_XHCI_UPD_HSIO_LFPS_CFG_PULLUP_DWN_RES   0
+#define N_XHCI_UPD_HSIO_FILTER_SELECT_P           0
+#define N_XHCI_UPD_HSIO_FILTER_SELECT_N           4
+
+typedef struct {
+  /**
+    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>
+  **/
+  UINT32  HsioCtrlAdaptOffsetCfg      :  5;
+  /**
+    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>
+  **/
+  UINT32  HsioFilterSelN              :  3;
+  /**
+    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>
+  **/
+  UINT32  HsioFilterSelP              :  3;
+  /**
+    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>
+  **/
+  UINT32  HsioOlfpsCfgPullUpDwnRes    :  3;
+
+  UINT32  HsioCtrlAdaptOffsetCfgEnable    :  1; ///< Enable the write to Signed Magnatude number added to the CTLE code, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioFilterSelNEnable            :  1; ///< Enable the write to LFPS filter select for n, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioFilterSelPEnable            :  1; ///< Enable the write to LFPS filter select for p, <b>0: Disable</b>; 1: Enable.
+  UINT32  HsioOlfpsCfgPullUpDwnResEnable  :  1; ///< Enable the write to olfpscfgpullupdwnres, <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                       : 14; ///< Reserved bits
+} USB30_HSIO_RX_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>:
+  - Added Usb2PhySusPgEnable - for enabling/disabling USB2 PHY SUS Well Power Gating
+  <b>Revision 3</b>:
+    Added HSIO Rx tuning policy options structure USB30_HSIO_RX_CONFIG
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
+  /**
+    This policy setting controls state of Compliance Mode enabling.
+    Compliance Mode can be enabled for testing through this option but defualt setting is Disabled.
+    <b>0:Disable</b>, 1: Enable
+  **/
+  UINT32                  EnableComplianceMode         :  1;
+  /**
+    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;
+  /**
+    <b>(Test)</b>
+    This policy option enables USB2 PHY SUS Well Power Gating functionality.
+    Please note this is ignored on PCH H
+    <b>0: disable USB2 PHY SUS Well Power Gating</b>
+    1: enable USB2 PHY SUS Well Power Gating
+  **/
+  UINT32                  Usb2PhySusPgEnable           :  1;
+  UINT32                  RsvdBits0                    : 27;     ///< Reserved bits
+  /**
+    These members describe whether the USB2 Port N of PCH is enabled by platform modules.
+  **/
+  USB20_PORT_CONFIG       PortUsb20[MAX_USB2_PORTS];
+  /**
+    These members describe whether the USB3 Port N of PCH is enabled by platform modules.
+  **/
+  USB30_PORT_CONFIG       PortUsb30[MAX_USB3_PORTS];
+  /**
+    This member describes whether or not the xDCI controller should be enabled.
+  **/
+  XDCI_CONFIG             XdciConfig;
+  /**
+    This member describes policy options for RX signal tuning in ModPHY
+  **/
+  USB30_HSIO_RX_CONFIG    PortUsb30HsioRx[MAX_USB3_PORTS];
+} USB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _USB_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..39baa6c03a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,157 @@
+/** @file
+  ASL dynamic update library definitions.
+  This library provides dymanic update to various ASL structures.
+  There may be different libraries for different environments (PEI, BS, RT, SMM).
+  Make sure you meet the requirements for the library (protocol dependencies, use
+  restrictions, etc).
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ASL_UPDATE_LIB_H_
+#define _ASL_UPDATE_LIB_H_
+
+//
+// Include files
+//
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+//
+// AML parsing definitions
+//
+#define AML_RESRC_TEMP_END_TAG  0x0079
+
+//
+// ASL PSS package structure layout
+//
+#pragma pack (1)
+typedef struct {
+  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
+  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
+  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
+  UINT8     DwordPrefix1;     // 0Ch
+  UINT32    CoreFrequency;    // 00h
+  UINT8     DwordPrefix2;     // 0Ch
+  UINT32    Power;            // 00h
+  UINT8     DwordPrefix3;     // 0Ch
+  UINT32    TransLatency;     // 00h
+  UINT8     DwordPrefix4;     // 0Ch
+  UINT32    BmLatency;        // 00h
+  UINT8     DwordPrefix5;     // 0Ch
+  UINT32    Control;          // 00h
+  UINT8     DwordPrefix6;     // 0Ch
+  UINT32    Status;           // 00h
+} PSS_PACKAGE_LAYOUT;
+#pragma pack()
+
+/**
+  Initialize the ASL update library state.
+  This must be called prior to invoking other library functions.
+
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+  VOID
+  );
+
+/**
+  This procedure will update immediate value assigned to a Name
+
+  @param[in] AslSignature               The signature of Operation Region that we want to update.
+  @param[in] Buffer                     source of data to be written over original aml
+  @param[in] Length                     length of data to be overwritten
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode(
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  );
+
+/**
+  This procedure will update the name of ASL Method
+
+  @param[in] AslSignature      - The signature of Operation Region that we want to update.
+  @param[in] Buffer            - source of data to be written over original aml
+  @param[in] Length            - length of data to be overwritten
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+  @retval EFI_NOT_FOUND        - Failed to locate AcpiTable.
+**/
+EFI_STATUS
+UpdateMethodAslCode (
+  IN     UINT32                        AslSignature,
+  IN     VOID                          *Buffer,
+  IN     UINTN                         Length
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI table using the .
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+  Matches are determined by finding the table with ACPI table that has
+  a matching signature and version.
+
+  @param[in] Signature                  Pointer to an ASCII string containing the Signature to match
+  @param[in, out] Table                 Updated with a pointer to the table
+  @param[in, out] Handle                AcpiSupport protocol table handle for the table found
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI SSDT table.
+  The table is located by searching for a matching OEM Table ID field.
+  Partial match searches are supported via the TableIdSize parameter.
+
+  @param[in] TableId                    Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in] TableIdSize                Length of the TableId to match.  Table ID are 8 bytes long, this function
+                                        will consider it a match if the first TableIdSize bytes match
+  @param[in, out] Table                 Updated with a pointer to the table
+  @param[in, out] Handle                AcpiSupport protocol table handle for the table found
+  @param[in, out] Version               See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+  IN      UINT8                         *TableId,
+  IN      UINT8                         TableIdSize,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer                     Pointer to buffer to checksum
+  @param[in] Size                       Number of bytes to checksum
+  @param[in] ChecksumOffset             Offset to place the checksum result in
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
new file mode 100644
index 0000000000..9a3bf373a6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
@@ -0,0 +1,64 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
new file mode 100644
index 0000000000..858f8ac5e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
@@ -0,0 +1,28 @@
+/** @file
+  Get Pci Express address library implementation.
+
+  Copyright (c) 2019 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
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+);
+
+#endif // _PEI_DXE_SMM_MM_PCI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
new file mode 100644
index 0000000000..c6eb70f6e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Header file for PEI SiPolicyUpdate Library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_SI_POLICY_UPDATE_LIB_H_
+#define _PEI_SI_POLICY_UPDATE_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  This function performs Silicon PEI Policy initialization.
+
+  @param[in, out] SiPolicy The Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS      The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicy (
+  IN OUT SI_POLICY_PPI *SiPolicy
+  );
+
+/**
+  This function performs CPU PEI Policy initialization in Post-memory.
+
+  @param[in, out] SiPolicyPpi     The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicy (
+  IN OUT  SI_POLICY_PPI *SiPolicyPpi
+  );
+
+/**
+  This function performs SI PEI Policy initialization.
+
+  @param[in, out] SiPolicyPpi     The SA Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicy (
+  IN OUT   SI_POLICY_PPI  *SiPolicyPpi
+  );
+
+
+/**
+This function performs SA PEI Policy initialization for PreMem.
+
+@param[in, out] SiPreMemPolicyPpi   The SI PreMem Policy PPI instance
+
+@retval EFI_SUCCESS             Update complete.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyPreMem (
+IN OUT   SI_PREMEM_POLICY_PPI  *SiPreMemPolicyPpi
+);
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicy (
+  IN OUT  SI_POLICY_PPI         *SiPolicy
+  );
+
+/**
+  This function performs PCH PEI Policy initialization.
+
+  @param[in, out] SiPreMemPolicy  The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The PPI is installed and initialized.
+  @retval EFI ERRORS              The PPI is not successfully installed.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
+  );
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPolicy       The SI Policy PPI instance
+
+  @retval EFI_SUCCESS            Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicy (
+  IN OUT  SI_POLICY_PPI         *SiPolicy
+  );
+
+/**
+  Update the ME Policy Library
+
+  @param[in, out] SiPreMemPolicy The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS            Update complete.
+**/
+EFI_STATUS
+UpdatePeiMePolicyPreMem (
+  IN OUT  SI_PREMEM_POLICY_PPI   *SiPreMemPolicy
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
new file mode 100644
index 0000000000..fd8582b981
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
@@ -0,0 +1,58 @@
+/** @file
+  Prototype of the SiConfigBlockLib library.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
new file mode 100644
index 0000000000..5633e2892c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
@@ -0,0 +1,110 @@
+/** @file
+  Prototype of the SiPolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_LIB_H_
+#define _SI_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole SI_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi          The RC PREMEM Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPreMemPrintPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  Print whole SI_POLICY_PPI and serial out.
+
+  @param[in] SiPolicyPpi          The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+SiPrintPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  );
+
+/**
+  SiCreatePreMemConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPreMemPolicyPpi   The pointer to get Silicon PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreatePreMemConfigBlocks (
+  OUT  SI_PREMEM_POLICY_PPI         **SiPreMemPolicyPpi
+  );
+
+/**
+  SiCreateConfigBlocks creates the config blocksg of Silicon Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SiPolicyPpi         The pointer to get Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS             The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiCreateConfigBlocks (
+  OUT  SI_POLICY_PPI         **SiPolicyPpi
+  );
+
+/**
+  SiPreMemInstallPolicyPpi installs SiPreMemPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPreMemPolicyPpi   The pointer to Silicon PREMEM Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiPreMemInstallPolicyPpi (
+  IN  SI_PREMEM_POLICY_PPI          *SiPreMemPolicyPpi
+  );
+
+/**
+  SiInstallPolicyPpi installs SiPolicyPpi.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval EFI_SUCCESS            The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+SiInstallPolicyPpi (
+  IN  SI_POLICY_PPI          *SiPolicyPpi
+  );
+
+/**
+  Print out all silicon policy information.
+
+  @param[in] SiPolicyPpi         The pointer to Silicon Policy PPI instance
+
+  @retval none
+**/
+VOID
+DumpSiPolicy (
+  IN  SI_POLICY_PPI *SiPolicyPpi
+  );
+
+#endif // _SI_PREMEM_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
new file mode 100644
index 0000000000..cab5342c54
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
@@ -0,0 +1,22 @@
+/** @file
+  Header file for a library to install StallPpi.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _STALL_PPI_LIB_H_
+#define _STALL_PPI_LIB_H_
+
+/**
+  This function is to install StallPpi
+
+  @retval  EFI_SUCCESS if Ppi is installed successfully.
+**/
+EFI_STATUS
+EFIAPI
+InstallStallPpi(
+  VOID
+  );
+#endif //_STALL_PPI_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
new file mode 100644
index 0000000000..a7cd305c62
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Header file of available functions in general USB Library
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB_LIB_H_
+#define _USB_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+
+/*
+  Disables requested ports through Port Disable Override register programming
+
+  @param[in]  XhciMmioBase        xHCI Memory BAR0 address
+  @param[in]  Usb2DisabledPorts   Disabled ports bitmask with a bit for each USB2 port
+                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
+  @param[in]  Usb3DisabledPorts   Disabled ports bitmask with a bit for each USB3 port
+                                  i.e. BIT0 is Port 0, BIT1 is Port 1 etc
+
+  @retval EFI_SUCCESS             Programming ended successfully and no errors occured
+          EFI_ACCESS_DENIED       Port Disable Override register was locked and write
+                                  didn't go through. Platform may require restart to unlock.
+*/
+EFI_STATUS
+UsbDisablePorts (
+  IN  UINTN   XhciMmioBase,
+  IN  UINT32  Usb2DisabledPorts,
+  IN  UINT32  Usb3DisabledPorts
+  );
+
+#endif // _USB_LIB_H
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
new file mode 100644
index 0000000000..86bed53c6f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
@@ -0,0 +1,319 @@
+/** @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) 2019 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_PI_OFFSET                           0x09
+#define R_PCI_SCC_OFFSET                          0x0A
+#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
+#define B_PCI_BRIDGE_BNUM_PBN                     0x000000FF ///< Primary Bus Number
+#define B_PCI_BRIDGE_BNUM_SBBN_SCBN               (B_PCI_BRIDGE_BNUM_SBBN | B_PCI_BRIDGE_BNUM_SCBN)
+
+#define R_PCI_BRIDGE_IOBL                         0x1C ///< I/O Base and Limit Register
+
+#define R_PCI_BRIDGE_MBL                          0x20 ///< Memory Base and Limit Register
+#define B_PCI_BRIDGE_MBL_ML                       0xFFF00000 ///< Memory Limit
+#define B_PCI_BRIDGE_MBL_MB                       0x0000FFF0 ///< Memory Base
+
+#define R_PCI_BRIDGE_PMBL                         0x24 ///< Prefetchable Memory Base and Limit Register
+#define B_PCI_BRIDGE_PMBL_PML                     0xFFF00000 ///< Prefetchable Memory Limit
+#define B_PCI_BRIDGE_PMBL_I64L                    0x000F0000 ///< 64-bit Indicator
+#define B_PCI_BRIDGE_PMBL_PMB                     0x0000FFF0 ///< Prefetchable Memory Base
+#define B_PCI_BRIDGE_PMBL_I64B                    0x0000000F ///< 64-bit Indicator
+
+#define R_PCI_BRIDGE_PMBU32                       0x28 ///< Prefetchable Memory Base Upper 32-Bit Register
+#define B_PCI_BRIDGE_PMBU32                       0xFFFFFFFF
+
+#define R_PCI_BRIDGE_PMLU32                       0x2C ///< Prefetchable Memory Limit Upper 32-Bit Register
+#define B_PCI_BRIDGE_PMLU32                       0xFFFFFFFF
+
+//
+// PCIE capabilities register
+//
+#define R_PCIE_CAP_ID_OFFSET                      0x00 ///< Capability ID
+#define R_PCIE_CAP_NEXT_PRT_OFFSET                0x01 ///< Next Capability Capability ID Pointer
+
+//
+// PCI Express Capability List Register (CAPID:10h)
+//
+#define R_PCIE_XCAP_OFFSET                        0x02 ///< PCI Express Capabilities Register (Offset 02h)
+#define S_PCIE_XCAP                               2
+#define B_PCIE_XCAP_SI                            BIT8 ///< Slot Implemented
+#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 S_PCIE_DCAP                               4
+#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 B_PCIE_DCTL_URE                           BIT3 ///< Unsupported Request Reporting Enable
+#define B_PCIE_DCTL_FEE                           BIT2 ///< Fatal Error Reporting Enable
+#define B_PCIE_DCTL_NFE                           BIT1 ///< Non-Fatal Error Reporting Enable
+#define B_PCIE_DCTL_CEE                           BIT0 ///< Correctable Error Reporting Enable
+
+#define R_PCIE_DSTS_OFFSET                        0x0A ///< Device Status Register (Offset 0Ah)
+#define B_PCIE_DSTS_TDP                           BIT5 ///< Transactions Pending
+#define B_PCIE_DSTS_APD                           BIT4 ///< AUX Power Detected
+#define B_PCIE_DSTS_URD                           BIT3 ///< Unsupported Request Detected
+#define B_PCIE_DSTS_FED                           BIT2 ///< Fatal Error Detected
+#define B_PCIE_DSTS_NFED                          BIT1 ///< Non-Fatal Error Detected
+#define B_PCIE_DSTS_CED                           BIT0 ///< Correctable Error Detected
+
+#define R_PCIE_LCAP_OFFSET                        0x0C ///< Link Capabilities Register (Offset 0Ch)
+#define B_PCIE_LCAP_ASPMOC                        BIT22 ///< ASPM Optionality Compliance
+#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                          (BIT11 | BIT10) ///< Active State Power Management (ASPM) Support
+#define B_PCIE_LCAP_APMS_L0S                      BIT10
+#define B_PCIE_LCAP_APMS_L1                       BIT11
+#define N_PCIE_LCAP_APMS                          10
+#define B_PCIE_LCAP_MLW                           0x000003F0 ///< Maximum Link Width
+#define N_PCIE_LCAP_MLW                           4
+#define B_PCIE_LCAP_MLS                           (BIT3 | BIT2 | BIT1 | BIT0) ///< Max Link Speed
+#define V_PCIE_LCAP_MLS_GEN3                      3
+
+#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_ES                            BIT7 ///< Extended Synch
+#define B_PCIE_LCTL_CCC                           BIT6 ///< Common Clock Configuration
+#define B_PCIE_LCTL_RL                            BIT5 ///< Retrain Link
+#define B_PCIE_LCTL_LD                            BIT4 ///< Link Disable
+#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 V_PCIE_LSTS_NLW_1                         0x0010
+#define V_PCIE_LSTS_NLW_2                         0x0020
+#define V_PCIE_LSTS_NLW_4                         0x0040
+#define B_PCIE_LSTS_CLS                           0x000F ///< Current Link Speed
+#define V_PCIE_LSTS_CLS_GEN1                      1
+#define V_PCIE_LSTS_CLS_GEN2                      2
+#define V_PCIE_LSTS_CLS_GEN3                      3
+
+#define R_PCIE_SLCAP_OFFSET                       0x14 ///< Slot Capabilities Register (Offset 14h)
+#define S_PCIE_SLCAP                              4
+#define B_PCIE_SLCAP_PSN                          0xFFF80000 ///< Physical Slot Number
+#define B_PCIE_SLCAP_SLS                          0x00018000 ///< Slot Power Limit Scale
+#define B_PCIE_SLCAP_SLV                          0x00007F80 ///< Slot Power Limit Value
+#define B_PCIE_SLCAP_HPC                          BIT6 ///< Hot-Plug Capable
+#define B_PCIE_SLCAP_HPS                          BIT5 ///< Hot-Plug Surprise
+
+#define R_PCIE_SLCTL_OFFSET                       0x18 ///< Slot Control Register (Offset 18h)
+#define S_PCIE_SLCTL                              2
+#define B_PCIE_SLCTL_HPE                          BIT5 ///< Hot Plug Interrupt Enable
+#define B_PCIE_SLCTL_PDE                          BIT3 ///< Presence Detect Changed Enable
+
+#define R_PCIE_SLSTS_OFFSET                       0x1A ///< Slot Status Register (Offset 1Ah)
+#define S_PCIE_SLSTS                              2
+#define B_PCIE_SLSTS_PDS                          BIT6 ///< Presence Detect State
+#define B_PCIE_SLSTS_PDC                          BIT3 ///< Presence Detect Changed
+
+#define R_PCIE_RCTL_OFFSET                        0x1C ///< Root Control Register (Offset 1Ch)
+#define S_PCIE_RCTL                               2
+#define B_PCIE_RCTL_PIE                           BIT3 ///< PME Interrupt Enable
+#define B_PCIE_RCTL_SFE                           BIT2 ///< System Error on Fatal Error Enable
+#define B_PCIE_RCTL_SNE                           BIT1 ///< System Error on Non-Fatal Error Enable
+#define B_PCIE_RCTL_SCE                           BIT0 ///< System Error on Correctable Error Enable
+
+#define R_PCIE_RSTS_OFFSET                        0x20 ///< Root Status Register (Offset 20h)
+#define S_PCIE_RSTS                               4
+
+#define R_PCIE_DCAP2_OFFSET                       0x24 ///< Device Capabilities 2 Register (Offset 24h)
+#define B_PCIE_DCAP2_OBFFS                        (BIT19 | BIT18) ///< OBFF Supported
+#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_OBFFEN                       (BIT14 | BIT13) ///< OBFF Enable
+#define N_PCIE_DCTL2_OBFFEN                       13
+#define V_PCIE_DCTL2_OBFFEN_DIS                   0 ///< Disabled
+#define V_PCIE_DCTL2_OBFFEN_WAKE                  3 ///< Enabled using WAKE# signaling
+#define B_PCIE_DCTL2_LTREN                        BIT10 ///< LTR Mechanism Enable
+#define B_PCIE_DCTL2_CTD                          BIT4 ///< Completion Timeout Disable
+#define B_PCIE_DCTL2_CTV                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Completion Timeout Value
+#define V_PCIE_DCTL2_CTV_DEFAULT                  0x0
+#define V_PCIE_DCTL2_CTV_40MS_50MS                0x5
+#define V_PCIE_DCTL2_CTV_160MS_170MS              0x6
+#define V_PCIE_DCTL2_CTV_400MS_500MS              0x9
+#define V_PCIE_DCTL2_CTV_1P6S_1P7S                0xA
+
+#define R_PCIE_LCTL2_OFFSET                       0x30 ///< Link Control 2 Register (Offset 30h)
+#define B_PCIE_LCTL2_SD                           BIT6 ///< Selectable de-emphasis (0 = -6dB, 1 = -3.5dB)
+#define B_PCIE_LCTL2_TLS                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Target Link Speed
+#define V_PCIE_LCTL2_TLS_GEN1                     1
+#define V_PCIE_LCTL2_TLS_GEN2                     2
+#define V_PCIE_LCTL2_TLS_GEN3                     3
+
+#define R_PCIE_LSTS2_OFFSET                       0x32 ///< Link Status 2 Register (Offset 32h)
+#define B_PCIE_LSTS2_LER                          BIT5 ///< Link Equalization Request
+#define B_PCIE_LSTS2_EQP3S                        BIT4 ///< Equalization Phase 3 Successful
+#define B_PCIE_LSTS2_EQP2S                        BIT3 ///< Equalization Phase 2 Successful
+#define B_PCIE_LSTS2_EQP1S                        BIT2 ///< Equalization Phase 1 Successful
+#define B_PCIE_LSTS2_EC                           BIT1 ///< Equalization Complete
+#define B_PCIE_LSTS2_CDL                          BIT0 ///< Current De-emphasis Level
+
+//
+// PCI Power Management Capability (CAPID:01h)
+//
+#define R_PCIE_PMC_OFFSET                         0x02 ///< Power Management Capabilities Register
+#define S_PCIE_PMC                                2
+#define B_PCIE_PMC_PMES                           (BIT15 | BIT14 | BIT13 | BIT12 | BIT11) ///< PME Support
+#define B_PCIE_PMC_PMEC                           BIT3 ///< PME Clock
+
+#define R_PCIE_PMCS_OFFST                         0x04 ///< Power Management Status/Control Register
+#define S_PCIE_PMCS                               4
+#define B_PCIE_PMCS_BPCE                          BIT23 ///< Bus Power/Clock Control Enable
+#define B_PCIE_PMCS_B23S                          BIT22 ///< B2/B3 Support
+#define B_PCIE_PMCS_PMES                          BIT15 ///< PME_Status
+#define B_PCIE_PMCS_PMEE                          BIT8 ///< PME Enable
+#define B_PCIE_PMCS_NSR                           BIT3 ///< No Soft Reset
+#define B_PCIE_PMCS_PS                            (BIT1 | BIT0) ///< Power State
+#define V_PCIE_PMCS_PS_D0                         0
+#define V_PCIE_PMCS_PS_D3H                        3
+
+//
+// PCIE Extension Capability Register
+//
+#define B_PCIE_EXCAP_NCO                          0xFFF00000 ///< Next Capability Offset
+#define N_PCIE_EXCAP_NCO                          20
+#define V_PCIE_EXCAP_NCO_LISTEND                  0
+#define B_PCIE_EXCAP_CV                           0x000F0000 ///< Capability Version
+#define N_PCIE_EXCAP_CV                           16
+#define B_PCIE_EXCAP_CID                          0x0000FFFF ///< Capability ID
+
+//
+// Advanced Error Reporting Capability (CAPID:0001h)
+//
+#define V_PCIE_EX_AEC_CID                         0x0001 ///< Capability ID
+#define R_PCIE_EX_UEM_OFFSET                      0x08 ///< Uncorrectable Error Mask Register
+#define B_PCIE_EX_UEM_CT                          BIT14 ///< Completion Timeout Mask
+#define B_PCIE_EX_UEM_UC                          BIT16 ///< Unexpected Completion
+
+//
+// ACS Extended Capability (CAPID:000Dh)
+//
+#define V_PCIE_EX_ACS_CID                         0x000D ///< Capability ID
+#define R_PCIE_EX_ACSCAPR_OFFSET                  0x04 ///< ACS Capability Register
+//#define R_PCIE_EX_ACSCTLR_OFFSET                  0x08 ///< ACS Control Register (NOTE: register size in PCIE spce is not match the PCH register size)
+
+
+//
+// Latency Tolerance Reporting Extended Capability Registers (CAPID:0018h)
+//
+#define R_PCH_PCIE_LTRECH_CID                     0x0018
+#define R_PCH_PCIE_LTRECH_MSLR_OFFSET             0x04
+#define N_PCH_PCIE_LTRECH_MSLR_VALUE              0
+#define N_PCH_PCIE_LTRECH_MSLR_SCALE              10
+#define R_PCH_PCIE_LTRECH_MNSLR_OFFSET            0x06
+#define N_PCH_PCIE_LTRECH_MNSLR_VALUE             0
+#define N_PCH_PCIE_LTRECH_MNSLR_SCALE             10
+//
+// Secondary PCI Express Extended Capability Header (CAPID:0019h)
+//
+#define V_PCIE_EX_SPE_CID                         0x0019 ///< Capability ID
+#define R_PCIE_EX_LCTL3_OFFSET                    0x04 ///< Link Control 3 Register
+#define B_PCIE_EX_LCTL3_PE                        BIT0 ///< Perform Equalization
+#define R_PCIE_EX_LES_OFFSET                      0x08 ///< Lane Error Status
+#define R_PCIE_EX_L01EC_OFFSET                    0x0C ///< Lane 0 and Lan 1 Equalization Control Register (Offset 0Ch)
+#define B_PCIE_EX_L01EC_UPL1TP                    0x0F000000 ///< Upstream Port Lane 1 Transmitter Preset
+#define N_PCIE_EX_L01EC_UPL1TP                    24
+#define B_PCIE_EX_L01EC_DPL1TP                    0x000F0000 ///< Downstream Port Lane 1 Transmitter Preset
+#define N_PCIE_EX_L01EC_DPL1TP                    16
+#define B_PCIE_EX_L01EC_UPL0TP                    0x00000F00 ///< Upstream Port Transmitter Preset
+#define N_PCIE_EX_L01EC_UPL0TP                    8
+#define B_PCIE_EX_L01EC_DPL0TP                    0x0000000F ///< Downstream Port Transmitter Preset
+#define N_PCIE_EX_L01EC_DPL0TP                    0
+
+#define R_PCIE_EX_L23EC_OFFSET                    0x10 ///< Lane 2 and Lane 3 Equalization Control Register (Offset 10h)
+#define B_PCIE_EX_L23EC_UPL3TP                    0x0F000000 ///< Upstream Port Lane 3 Transmitter Preset
+#define N_PCIE_EX_L23EC_UPL3TP                    24
+#define B_PCIE_EX_L23EC_DPL3TP                    0x000F0000 ///< Downstream Port Lane 3 Transmitter Preset
+#define N_PCIE_EX_L23EC_DPL3TP                    16
+#define B_PCIE_EX_L23EC_UPL2TP                    0x00000F00 ///< Upstream Port Lane 2 Transmitter Preset
+#define N_PCIE_EX_L23EC_UPL2TP                    8
+#define B_PCIE_EX_L23EC_DPL2TP                    0x0000000F ///< Downstream Port Lane 2 Transmitter Preset
+#define N_PCIE_EX_L23EC_DPL2TP                    0
+
+
+//
+// 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  V_PCIE_EX_L1SCAP_PTPOS_2us               0
+#define  V_PCIE_EX_L1SCAP_PTPOS_10us              1
+#define  V_PCIE_EX_L1SCAP_PTPOS_100us             2
+#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 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
+
+//
+// Base Address Offset
+//
+#define R_BASE_ADDRESS_OFFSET_0                   0x0010 ///< Base Address Register 0
+#define R_BASE_ADDRESS_OFFSET_1                   0x0014 ///< Base Address Register 1
+#define R_BASE_ADDRESS_OFFSET_2                   0x0018 ///< Base Address Register 2
+#define R_BASE_ADDRESS_OFFSET_3                   0x001C ///< Base Address Register 3
+#define R_BASE_ADDRESS_OFFSET_4                   0x0020 ///< Base Address Register 4
+#define R_BASE_ADDRESS_OFFSET_5                   0x0024 ///< Base Address Register 5
+#define B_PCI_BAR_MEMORY_TYPE_MASK                (BIT1 | BIT2)
+#define B_PCI_BAR_MEMORY_TYPE_64                  BIT2
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
new file mode 100644
index 0000000000..ac270e24fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
@@ -0,0 +1,29 @@
+/** @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) 2019 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 <PchAccess.h>
+#include <PchPolicyCommon.h>
+#include <PchPreMemPolicyCommon.h>
+#include <SaPolicyCommon.h>
+#include <CpuPolicyCommon.h>
+
+extern EFI_GUID gSiPreMemPolicyPpiGuid;
+extern EFI_GUID gSiPolicyPpiGuid;
+
+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/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
new file mode 100644
index 0000000000..fe676f8519
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
@@ -0,0 +1,26 @@
+/** @file
+  PCIe Initialization Library header file
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCIE_INIT_LIB_H_
+#define _PCIE_INIT_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/GpioLib.h>
+#include <SaRegs.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
new file mode 100644
index 0000000000..f05cf0fdea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for USB initialization library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB_INIT_LIB_H_
+#define _USB_INIT_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Common entry point for PCH and CPU xDCI controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XdciPciMmBase       xDCI PCI config space address
+**/
+VOID
+XdciConfigure (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Common entry point for PCH and CPU xHCI controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciMmBase       xHCI PCI config space address
+**/
+VOID
+XhciConfigure (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Configure xHCI after initialization
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciMmBase       XHCI PCI CFG Base Address
+**/
+VOID
+XhciConfigureAfterInit (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciMmBase
+  );
+
+/**
+  Locks xHCI configuration by setting the proper lock bits in controller
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+  @param[in]  XhciPciBase         xHCI PCI config space address
+**/
+VOID
+XhciLockConfiguration (
+  IN  USB_CONFIG      *UsbConfig,
+  IN  UINT64          XhciPciBase
+  );
+
+/**
+  Tune the USB 2.0 high-speed signals quality.
+
+  @param[in]  UsbConfig           The USB_CONFIG policy instance
+**/
+VOID
+Usb2AfeProgramming (
+  IN  USB_CONFIG      *UsbConfig
+  );
+#endif // _USB_INIT_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
new file mode 100644
index 0000000000..671e94b3bc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
@@ -0,0 +1,60 @@
+/** @file
+  Protocol used for specifying platform related Silicon information and policy setting.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_PROTOCOL_H_
+#define _SI_POLICY_PROTOCOL_H_
+
+#include <IndustryStandard/Hsti.h>
+
+//
+// DXE_SI_POLICY_PROTOCOL revisions
+//
+#define DXE_SI_POLICY_PROTOCOL_REVISION 2
+
+extern EFI_GUID gDxeSiPolicyProtocolGuid;
+
+#pragma pack (push,1)
+
+/**
+  The protocol allows the platform code to publish a set of configuration information that the
+  Silicon drivers will use to configure the processor in the DXE phase.
+  This Policy Protocol needs to be initialized for Silicon configuration.
+  @note The Protocol has to be published before processor DXE drivers are dispatched.
+**/
+typedef struct {
+  /**
+  This member specifies the revision of the Si Policy protocol. This field is used to indicate backward
+  compatible changes to the protocol. Any such changes to this protocol will result in an update in the revision number.
+
+  <b>Revision 1</b>:
+   - Initial version
+  <b>Revision 2</b>:
+   - Added SmbiosOemTypeFirmwareVersionInfo to determines the SMBIOS OEM type
+  **/
+  UINT8                          Revision;
+  /**
+    SmbiosOemTypeFirmwareVersionInfo 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.
+  **/
+  UINT8                          SmbiosOemTypeFirmwareVersionInfo;
+  UINT8                          ReservedByte[6];  ///< Reserved bytes, align to multiple 8.
+  /**
+    This member describes a pointer to Hsti results from previous boot. In order to mitigate the large performance cost
+    of performing all of the platform security tests on each boot, we can save the results across boots and retrieve
+    and point this policy to them prior to the launch of HstiSiliconDxe. Logic should be implemented to not populate this
+    upon major platform changes (i.e changes to setup option or platform hw)to ensure that results accurately reflect the
+    configuration of the platform.
+  **/
+  ADAPTER_INFO_PLATFORM_SECURITY *Hsti;    ///< This is a pointer to Hsti results from previous boot
+  UINTN                          HstiSize; ///< Size of results, if setting Hsti policy to point to previous results
+} DXE_SI_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
new file mode 100644
index 0000000000..58a185c8fd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
@@ -0,0 +1,55 @@
+/** @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 .
+    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 -H denoted by "_PCH_H_" in component name.
+    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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _REGS_USB_H_
+#define _REGS_USB_H_
+
+//
+// USB3 (XHCI) related definitions
+// @todo: Add CPU PCI defs for xHCI
+//
+#define PCI_BUS_NUMBER_PCH_XHCI             0
+#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
+#endif // _REGS_USB_H_
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
new file mode 100644
index 0000000000..b5aeccbe5d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
@@ -0,0 +1,19 @@
+/** @file
+  Silicon Config HOB is used for gathering platform
+  related Intel silicon information and config setting.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
new file mode 100644
index 0000000000..da16aad257
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
@@ -0,0 +1,65 @@
+/** @file
+  Intel reference code configuration policies.
+
+  Copyright (c) 2019 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/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;
+/*
+  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;
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
new file mode 100644
index 0000000000..7e056a25af
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
@@ -0,0 +1,23 @@
+/** @file
+ Common configurations for CPU and PCH trace hub
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TRACE_HUB_COMMON_CONFIG_H_
+#define _TRACE_HUB_COMMON_CONFIG_H_
+
+///
+/// The TRACE_HUB_ENABLE_MODE describes the desired TraceHub mode of operation
+///
+typedef enum {
+  TraceHubModeDisabled       = 0,       ///< TraceHub Disabled
+  TraceHubModeTargetDebugger = 1,       ///< TraceHub Target Debugger mode, debug on target device itself, config to PCI mode
+  TraceHubModeHostDebugger   = 2,       ///< TraceHub Host Debugger mode, debugged by host with cable attached, config to ACPI mode
+  TraceHubModeMax
+} TRACE_HUB_ENABLE_MODE;
+
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
@ 2019-08-17  6:58   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17  6:58 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com> 

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add Include headers

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

Adds header files common to CPU modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h                |  45 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h | 106 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h    | 141 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h         |  54 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h  | 179 ++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h |  78 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h   | 149 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h            |  66 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h                            |  16 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h                        | 113 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h                        |  88 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h                      |  23 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h                         | 100 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h                              | 261 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h                |  90 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h               | 118 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h                 |  84 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h                     | 123 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h           |  50 ++++
 19 files changed, 1884 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
new file mode 100644
index 0000000000..47a98131d0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
@@ -0,0 +1,45 @@
+/** @file
+  CPU Config Block.
+
+  Copyright (c) 2019 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>:
+  - Deprecate and move SkipMpInit to CpuConfigLibPreMemConfig.
+  <b>Revision 3</b>:
+  - Move DebugInterfaceEnable from CPU_TEST_CONFIG.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    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;
+  UINT32 SkipMpInit               : 1;            ///< @deprecated since revision 2. For Fsp only, Silicon Initialization will skip MP Initialization (including BSP) if enabled. For non-FSP, this should always be 0.
+  UINT32 DebugInterfaceEnable     : 1;            ///< Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+  UINT32 RsvdBits                 : 28;           ///< Reserved for future use
+  EFI_PHYSICAL_ADDRESS MicrocodePatchAddress;     ///< Pointer to microcode patch that is suitable for this processor.
+} CPU_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
new file mode 100644
index 0000000000..ce965a7510
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
@@ -0,0 +1,106 @@
+/** @file
+  CPU Security PreMemory Config Block.
+
+  Copyright (c) 2019 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 5
+
+extern EFI_GUID gCpuConfigLibPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Config Library PreMemory Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Update for JTAG Power Gate comment.
+  <b>Revision 3</b>:
+  - Add PeciSxReset and PeciC10Reset
+  <b>Revision 4</b>:
+  - Add SkipMpInit
+  <b>Revision 5</b>:
+  - Add DpSscMarginEnable
+**/
+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.
+   - <b>1: Maximum non-turbo performance</b>.
+   - 2: Turbo performance.
+  @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;
+  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;
+  /**
+    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>0: Disable</b> for CNL, and <b>1: Enable</b> for all other CPU's
+    - 0: Disable
+    - 1: Enable
+  **/
+  UINT32 PeciC10Reset               : 1;
+  /**
+    For Fsp only, Silicon Initialization will skip MP Initialization
+    (including BSP) if enabled. For non-FSP, this should always be 0.
+    - <b>0: Disable</b>
+    - 1: Enable
+  **/
+  UINT32 SkipMpInit                 : 1;
+  /**
+    Enable DisplayPort SSC range reduction
+    @note This should only be used on systems that exceeds allowed SSC modulation range as defined in VESA's spec.
+    - <b>0: Disable</b>
+    - 1: Enable
+  **/
+  UINT32 DpSscMarginEnable          : 1;
+  UINT32 RsvdBits                   : 17;
+  /**
+    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;
+  UINT8  Reserved[3];                    ///< Reserved for alignment
+} CPU_CONFIG_LIB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
new file mode 100644
index 0000000000..a0b8a208e6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
@@ -0,0 +1,141 @@
+/** @file
+  CPU Overclocking Config Block.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
+#define _CPU_OVERCLOCKING_PREMEM_CONFIG_H_
+
+#define CPU_OVERCLOCKING_CONFIG_REVISION 4
+
+extern EFI_GUID gCpuOverclockingPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Overclocking Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>
+  - Deprecate RingMinOcRatio
+  <b>Revision 3</b>
+  - Change RingDownBin default to 'Enabled'
+  <b>Revision 4</b>
+  - Add TvbRatioClipping, TvbVoltageOptimization
+
+**/
+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.; <b>0: Disable</b>; 1: Enable (Lock).
+  /**
+  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 RsvdBits             :  10;              ///< 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-255. Max range varies by CPU sku.
+  **/
+  UINT8  CoreMaxOcRatio;
+  /**
+  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;
+  /**
+  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-255. Max range varies by CPU sku.
+  **/
+  UINT8  RingMaxOcRatio;
+  /**
+  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;
+  UINT8  RingMinOcRatio;                          ///< Deprecated since rev 2. Minimum ring ratio override. <b>0: Hardware defaults.</b> Range: 0-83.
+  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.
+  /**
+  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 RsvdBits1              :  6;
+  /**
+  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 0 to 63.
+  **/
+  UINT8  TjMaxOffset;
+} CPU_OVERCLOCKING_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_OVERCLOCKING_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
new file mode 100644
index 0000000000..e45f335ff9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
@@ -0,0 +1,54 @@
+/** @file
+  CPU PID Config Block.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
new file mode 100644
index 0000000000..2ad474b7e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
@@ -0,0 +1,179 @@
+/** @file
+  CPU Power Management Basic Config Block.
+
+  Copyright (c) 2019 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 2
+
+extern EFI_GUID gCpuPowerMgmtBasicConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Power Management Basic Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added MinRingRatioLimit
+  - Added MaxRingRatioLimit
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+  Sets the boot frequency starting from reset vector.
+   - 0: Maximum battery performance.
+   - <b>1: Maximum non-turbo performance</b>.
+   - 2: Turbo performance.
+  @note If Turbo is selected BIOS will start in max non-turbo mode and switch to Turbo mode.
+  **/
+  UINT32 BootFrequency                  : 2;
+  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; <b>0: Disabled</b>; 1: Enabled (Lock).
+  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 RsvdBits                       : 9;      ///< 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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 255.
+     - 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>15</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.
+  0: Disable; <b>1: Enable;</b>
+  **/
+  UINT8  EnableItbm                     : 1;
+  /**
+  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;
+  UINT8  ReservedBits1                  : 6;      ///< 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.
+  Default: <b>0 - AUTO</b>, auto will program 28 seconds.
+  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;
+} CPU_POWER_MGMT_BASIC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_BASIC_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
new file mode 100644
index 0000000000..7eb91fa3ee
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
@@ -0,0 +1,78 @@
+/** @file
+  CPU Power Managment Custom Config Block.
+
+  Copyright (c) 2019 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
new file mode 100644
index 0000000000..cb9b20249f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
@@ -0,0 +1,149 @@
+/** @file
+  CPU Power Management Test Config Block.
+
+  Copyright (c) 2019 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 3
+
+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,
+  PpmIrmPairFixedPriority,
+  PpmIrmPairRoundRobin,
+  PpmIrmPairHashVector,
+  PpmIrmNoChange
+} PPM_IRM_SETTING;
+
+/**
+  CPU Power Management Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Update PkgCStateDemotion and PkgCStateUnDemotion to be Disable.
+  <b>Revision 3</b>:
+  - Add  CstateLatencyControl0TimeUnit for CFL only
+  - Add  CstateLatencyControl0Irtl for CFL only
+**/
+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 AutoThermalReporting          : 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. [Cannonlake Y] 0: Disable; <b>1: Enable</b> [CoffeeLake] <b>Disable</b>; 1: Enable
+  UINT32 PkgCStateUnDemotion           : 1;        ///<              Enable or Disable Package Cstate UnDemotion.  0: [Cannonlake Y] 0: Disable; <b>1: Enable</b> [CoffeeLake] <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;        ///<              Configuration for boot TDP selection; <b>0: TDP Nominal</b>; 1: TDP Down; 2: TDP Up.
+  UINT16 CstateLatencyControl1Irtl;                ///< Offset 32-33 Interrupt Response Time Limit of LatencyContol1 MSR 0x60B[9:0].
+  UINT16 CstateLatencyControl2Irtl;                ///< Offset 34-35 Interrupt Response Time Limit of LatencyContol2 MSR 0x60C[9:0].
+  UINT16 CstateLatencyControl3Irtl;                ///< Offset 36-37 Interrupt Response Time Limit of LatencyContol3 MSR 0x633[9:0].
+  UINT16 CstateLatencyControl4Irtl;                ///< Offset 38-39 Interrupt Response Time Limit of LatencyContol4 MSR 0x634[9:0].
+  UINT16 CstateLatencyControl5Irtl;                ///< Offset 40-41 Interrupt Response Time Limit of LatencyContol5 MSR 0x635[9:0].
+  UINT16 CstateLatencyControl0Irtl;                ///< Offset 42-43 Interrupt Response Time Limit of LatencyContol1 MSR 0x60A[9:0].
+  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 CstateLatencyControl0TimeUnit; ///< Offset 45    TimeUnit for Latency Control0 MSR 0x60A[12:10]; (CFL)2: 1024ns
+  C_STATE_TIME_UNIT CstateLatencyControl1TimeUnit; ///< Offset 46    TimeUnit for Latency Control1 MSR 0x60B[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl2TimeUnit; ///< Offset 47    TimeUnit for Latency Control2 MSR 0x60C[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl3TimeUnit; ///< Offset 48    TimeUnit for Latency Control3 MSR 0x633[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl4TimeUnit; ///< Offset 49    TimeUnit for Latency Control4 MSR 0x634[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  C_STATE_TIME_UNIT CstateLatencyControl5TimeUnit; ///< Offset 50    TimeUnit for Latency Control5 MSR 0x635[12:10]; (CFL)2: 1024ns, (CNL)3: 32768ns
+  /**
+  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.
+   - 1: Round robin.
+   - 2: Hash vector.
+   - 4: PAIR with fixed priority.
+   - 5: PAIR with round robin.
+   - 6: PAIR with hash vector.
+   - 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/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
new file mode 100644
index 0000000000..b94eb5e263
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
@@ -0,0 +1,66 @@
+/** @file
+  CPU Test Config Block.
+
+  Copyright (c) 2019 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 4
+
+extern EFI_GUID gCpuTestConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Fixed RsvdBits incorrect value.
+  <b>Revision 3</b>:
+  - Added CpuWakeUpTimer
+  <b>Revision 4</b>:
+  - Deprecate and move DebugInterfaceEnable to CPU_CONFIG.
+**/
+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                DebugInterfaceEnable            : 1;     ///< @deprecated Enable or Disable processor debug features; <b>0: Disable</b>; 1: Enable.
+  UINT32                DebugInterfaceLockEnable        : 1;     ///< Lock or Unlock debug interface features; 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.
+  /**
+    This policy should be used to enable or disable Voltage Optimization feature.
+    Recommended defaults:
+     Enable  - For Mobile SKUs(U/Y)
+     Disable - Rest of all SKUs other than Mobile.
+  **/
+  UINT32                VoltageOptimization             : 1;
+  UINT32                CpuWakeUpTimer                  : 1;      ///< Enable or Disable long CPU wake up timer. 0: Disabled (8s); <b>1: Enabled (180s)</b>.
+  UINT32                RsvdBits                        : 21;     ///< 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;
+} CPU_TEST_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_TEST_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
new file mode 100644
index 0000000000..48fdbdd012
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
@@ -0,0 +1,16 @@
+/** @file
+  Macros to simplify and abstract the interface to CPU configuration.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPUACCESS_H_
+#define _CPUACCESS_H_
+
+#include "CpuRegs.h"
+#include "CpuDataStruct.h"
+#include "CpuPowerMgmt.h"
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
new file mode 100644
index 0000000000..2382e60dca
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
@@ -0,0 +1,113 @@
+/** @file
+  This file declares various data structures used in CPU reference code.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_DATA_STRUCT_H
+#define _CPU_DATA_STRUCT_H
+
+//
+// The reason for changing the state of the processor Only applies to Disabling processors.
+// In future, we can add add/remove support
+//
+#define CPU_CAUSE_NOT_DISABLED      0x0000
+#define CPU_CAUSE_INTERNAL_ERROR    0x0001
+#define CPU_CAUSE_THERMAL_ERROR     0x0002
+#define CPU_CAUSE_SELFTEST_FAILURE  0x0004
+#define CPU_CAUSE_PREBOOT_TIMEOUT   0x0008
+#define CPU_CAUSE_FAILED_TO_START   0x0010
+#define CPU_CAUSE_CONFIG_ERROR      0x0020
+#define CPU_CAUSE_USER_SELECTION    0x0080
+#define CPU_CAUSE_BY_ASSOCIATION    0x0100
+#define CPU_CAUSE_UNSPECIFIED       0x8000
+
+typedef UINT32 CPU_STATE_CHANGE_CAUSE;
+
+///
+/// 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;
+
+///
+/// Structure to describe microcode header
+///
+typedef struct {
+  UINT32 HeaderVersion;  ///< Version number of the update header.
+  UINT32 UpdateRevision; ///< Unique version number for the update.
+  UINT32 Date;           ///< Date of the update creation.
+  UINT32 ProcessorId;    ///< Signature of the processor that requires this update.
+  UINT32 Checksum;       ///< Checksum of update data and header.
+  UINT32 LoaderRevision; ///< Version number of the microcode loader program.
+  UINT32 ProcessorFlags; ///< Lower 4 bits denoting platform type information.
+  UINT32 DataSize;       ///< Size of encoded data in bytes.
+  UINT32 TotalSize;      ///< Total size of microcode update in bytes.
+  UINT8  Reserved[12];   ///< Reserved bits.
+} CPU_MICROCODE_HEADER;
+
+///
+/// Structure to describe the extended signature table header of the microcode update
+///
+typedef struct {
+  UINT32 ExtendedSignatureCount; ///< Number of extended signature structures.
+  UINT32 ExtendedTableChecksum;  ///< Checksum of update extended processor signature table.
+  UINT8  Reserved[12];           ///< Reserved bits.
+} CPU_MICROCODE_EXTENDED_TABLE_HEADER;
+
+///
+/// Structure to describe the data of the extended table of the microcode update
+///
+typedef struct {
+  UINT32 ProcessorSignature; ///< Extended signature of the processor that requires this update
+  UINT32 ProcessorFlag;      ///< Lower 4 bits denoting platform type information
+  UINT32 ProcessorChecksum;  ///< checksum of each of the extended update
+} CPU_MICROCODE_EXTENDED_TABLE;
+
+#pragma pack(1)
+///
+/// MSR_REGISTER definition as a Union of QWORDS, DWORDS and BYTES
+///
+typedef union _MSR_REGISTER {
+  UINT64  Qword;       ///< MSR value in 64 bit QWORD.
+
+  ///
+  /// MSR value represented in two DWORDS
+  ///
+  struct {
+    UINT32  Low;       ///< Lower DWORD of the 64 bit MSR value.
+    UINT32  High;      ///< Higher DWORD of the 64 bit MSR value.
+  } Dwords;
+
+  ///
+  /// MSR value represented in eight bytes.
+  ///
+  struct {
+    UINT8 FirstByte;   ///< First byte of the 64 bit MSR value.
+    UINT8 SecondByte;  ///< Second byte of the 64 bit MSR value.
+    UINT8 ThirdByte;   ///< Third byte of the 64 bit MSR value.
+    UINT8 FouthByte;   ///< Fourth byte of the 64 bit MSR value.
+    UINT8 FifthByte;   ///< Fifth byte of the 64 bit MSR value.
+    UINT8 SixthByte;   ///< Sixth byte of the 64 bit MSR value.
+    UINT8 SeventhByte; ///< Seventh byte of the 64 bit MSR value.
+    UINT8 EighthByte;  ///< Eigth byte of the 64 bit MSR value.
+  } Bytes;
+} MSR_REGISTER;
+
+///
+/// Store BIST data for BSP.
+///
+typedef struct {
+  UINT32 ApicId;    ///< APIC ID
+  UINT32 Health;    ///< BIST result
+} BIST_HOB_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
new file mode 100644
index 0000000000..4862d62975
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
@@ -0,0 +1,88 @@
+/** @file
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define CPU NVS Area operation region.
+  //
+
+#ifndef _CPU_NVS_AREA_DEF_H_
+#define _CPU_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT8    Revision;                                ///< Offset 0       CPU GlobalNvs Revision
+  UINT32   PpmFlags;                                ///< Offset 1       PPM Flags Values
+  UINT8    Reserved0[1];                            ///< Offset 5:5
+  UINT8    AutoCriticalTripPoint;                   ///< Offset 6       Auto Critical Trip Point
+  UINT8    AutoPassiveTripPoint;                    ///< Offset 7       Auto Passive Trip Point
+  UINT8    AutoActiveTripPoint;                     ///< Offset 8       Auto Active Trip Point
+  UINT32   Cpuid;                                   ///< Offset 9       CPUID
+  UINT8    ConfigurablePpc;                         ///< Offset 13      Boot Mode vlues for _PPC
+  UINT8    CtdpLevelsSupported;                     ///< Offset 14      ConfigTdp Number Of Levels
+  UINT8    ConfigTdpBootModeIndex;                  ///< Offset 15      CTDP Boot Mode Index
+  UINT16   CtdpPowerLimit1[3];                      ///< Offset 16      CTDP Level 0 Power Limit1
+                                                    ///< Offset 18      CTDP Level 1 Power Limit1
+                                                    ///< Offset 20      CTDP Level 2 Power Limit1
+  UINT16   CtdpPowerLimit2[3];                      ///< Offset 22      CTDP Level 0 Power Limit2
+                                                    ///< Offset 24      CTDP Level 1 Power Limit2
+                                                    ///< Offset 26      CTDP Level 2 Power Limit2
+  UINT8    CtdpPowerLimitWindow[3];                 ///< Offset 28      CTDP Level 0 Power Limit1 Time Window
+                                                    ///< Offset 29      CTDP Level 1 Power Limit1 Time Window
+                                                    ///< Offset 30      CTDP Level 2 Power Limit1 Time Window
+  UINT8    CtdpCtc[3];                              ///< Offset 31      CTDP Level 0 CTC
+                                                    ///< Offset 32      CTDP Level 1 CTC
+                                                    ///< Offset 33      CTDP Level 2 CTC
+  UINT8    CtdpTar[3];                              ///< Offset 34      CTDP Level 0 TAR
+                                                    ///< Offset 35      CTDP Level 1 TAR
+                                                    ///< Offset 36      CTDP Level 2 TAR
+  UINT8    CtdpPpc[3];                              ///< Offset 37      CTDP Level 0 PPC
+                                                    ///< Offset 38      CTDP Level 1 PPC
+                                                    ///< Offset 39      CTDP Level 2 PPC
+  UINT8    Reserved1[1];                            ///< Offset 40:40
+  UINT8    C6MwaitValue;                            ///< Offset 41      Mwait Hint value for C6
+  UINT8    C7MwaitValue;                            ///< Offset 42      Mwait Hint value for C7/C7s
+  UINT8    CDMwaitValue;                            ///< Offset 43      Mwait Hint value for C7/C8/C9/C10
+  UINT8    Reserved2[2];                            ///< Offset 44:45
+  UINT16   C6Latency;                               ///< Offset 46      Latency Value for C6
+  UINT16   C7Latency;                               ///< Offset 48      Latency Value for C7/C7S
+  UINT16   CDLatency;                               ///< Offset 50      Latency Value for C8/C9/C10
+  UINT16   CDIOLevel;                               ///< Offset 52      IO LVL value for C8/C9/C10
+  UINT16   CDPowerValue;                            ///< Offset 54      Power value for C8/C9/C10
+  UINT8    MiscPowerManagementFlags;                ///< Offset 56      MiscPowerManagementFlags
+  UINT8    EnableDigitalThermalSensor;              ///< Offset 57      Digital Thermal Sensor Enable
+  UINT8    BspDigitalThermalSensorTemperature;      ///< Offset 58      Digital Thermal Sensor 1 Readingn for BSP
+  UINT8    ApDigitalThermalSensorTemperature;       ///< Offset 59      Digital Thermal Sensor 2 Reading for AP1
+  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 60      DTS SMI Function Call via DTS IO Trap
+  UINT8    PackageDTSTemperature;                   ///< Offset 61      Package Temperature
+  UINT8    IsPackageTempMSRAvailable;               ///< Offset 62      Package Temperature MSR available
+  UINT8    Ap2DigitalThermalSensorTemperature;      ///< Offset 63      Digital Thermal Sensor 3 Reading for AP2
+  UINT8    Ap3DigitalThermalSensorTemperature;      ///< Offset 64      Digital Thermal Sensor 4 Reading for AP3
+  UINT64   BiosGuardMemAddress;                     ///< Offset 65      BIOS Guard Memory Address for Tool Interface
+  UINT8    BiosGuardMemSize;                        ///< Offset 73      BIOS Guard Memory Size for Tool Interface
+  UINT16   BiosGuardIoTrapAddress;                  ///< Offset 74      BIOS Guard IoTrap Address for Tool Interface
+  UINT16   BiosGuardIoTrapLength;                   ///< Offset 76      BIOS Guard IoTrap Length for Tool Interface
+  UINT16   DtsIoTrapAddress;                        ///< Offset 78      DTS IO trap Address
+  UINT8    DtsIoTrapLength;                         ///< Offset 80      DTS IO trap Length
+  UINT8    DtsAcpiEnable;                           ///< Offset 81      DTS is in ACPI Mode Enabled
+  UINT8    SgxStatus;                               ///< Offset 82      SGX Status
+  UINT64   EpcBaseAddress;                          ///< Offset 83      EPC Base Address
+  UINT64   EpcLength;                               ///< Offset 91      EPC Length
+  UINT8    HwpVersion;                              ///< Offset 99      HWP Version
+  UINT8    HwpInterruptStatus;                      ///< Offset 100     HWP Interrupt Status
+  UINT8    DtsInterruptStatus;                      ///< Offset 101     DTS Interrupt Status
+  UINT8    HwpSmi;                                  ///< Offset 102     SMI to setup HWP LVT tables
+  UINT8    LowestMaxPerf;                           ///< Offset 103     Max ratio of the slowest core.
+  UINT8    EnableItbm;                              ///< Offset 104     Enable/Disable Intel Turbo Boost Max Technology 3.0.
+  UINT8    EnableItbmDriver;                        ///< Offset 105     Enable/Disable Intel Turbo Boost Max Technology 3.0 Driver.
+  UINT8    ItbmInterruptStatus;                     ///< Offset 106     Intel Turbo Boost Max Technology 3.0 interrupt status.
+  UINT8    ItbmSmi;                                 ///< Offset 107     SMI to resume periodic SMM for Intel Turbo Boost Max Technology 3.0.
+  UINT8    OcBins;                                  ///< Offset 108     Indicates bins of Oc support. MSR 194h FLEX_RATIO Bits (19:17)
+  UINT8    C3MwaitValue;                            ///< Offset 109     Mwait Hint value for C3 (CFL only)
+  UINT16   C3Latency;                               ///< Offset 110     Latency Value for C3 (CFL only)
+} CPU_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
new file mode 100644
index 0000000000..a9abd426f9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
@@ -0,0 +1,23 @@
+/** @file
+  CPU Policy structure definition which will contain several config blocks during runtime.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_COMMON_H_
+#define _CPU_POLICY_COMMON_H_
+
+#include "CpuPowerMgmt.h"
+#include <ConfigBlock.h>
+#include <ConfigBlock/CpuOverclockingConfig.h>
+#include <ConfigBlock/CpuConfig.h>
+#include <ConfigBlock/CpuPidTestConfig.h>
+#include <ConfigBlock/CpuPowerMgmtBasicConfig.h>
+#include <ConfigBlock/CpuPowerMgmtCustomConfig.h>
+#include <ConfigBlock/CpuPowerMgmtTestConfig.h>
+#include <ConfigBlock/CpuTestConfig.h>
+#include <ConfigBlock/CpuConfigLibPreMemConfig.h>
+
+#endif // _CPU_POLICY_COMMON_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
new file mode 100644
index 0000000000..af1f70b34f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
@@ -0,0 +1,100 @@
+/** @file
+  This file contains define definitions specific to processor
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POWER_MGMT_DEFINITIONS_H_
+#define _POWER_MGMT_DEFINITIONS_H_
+
+#define CSTATE_SUPPORTED          0x1
+#define ENHANCED_CSTATE_SUPPORTED 0x2
+#define C6_C7_SHORT_LATENCY_SUPPORTED 0x01
+#define C6_C7_LONG_LATENCY_SUPPORTED  0x02
+#define C7s_SHORT_LATENCY_SUPPORTED   0x03
+#define C7s_LONG_LATENCY_SUPPORTED    0x04
+//
+// Voltage offset definitions
+//
+#define OC_LIB_OFFSET_ADAPTIVE  0
+#define OC_LIB_OFFSET_OVERRIDE  1
+//
+// Platform Power Management Flags Bit Definitions:
+//   These defines are also used in CPU0CST.ASL to check platform configuration
+//   and build C-state table accordingly.
+//
+#define PPM_EIST                BIT0   ///< Enhanced Intel Speed Step Technology.
+#define PPM_C1                  BIT1   ///< C1 enabled, supported.
+#define PPM_C1E                 BIT2   ///< C1E enabled.
+#define PPM_C3                  BIT3   ///< C3 enabled, supported.
+#define PPM_C6                  BIT4   ///< C6 enabled, supported.
+#define PPM_C7                  BIT5   ///< C7 enabled, supported.
+#define PPM_C7S                 BIT6   ///< C7S enabled, supported
+#define PPM_TM                  BIT7   ///< Adaptive Thermal Monitor.
+#define PPM_TURBO               BIT8   ///< Long duration turbo mode
+#define PPM_CMP                 BIT9   ///< CMP.
+#define PPM_TSTATES             BIT10  ///< CPU throttling states
+#define PPM_MWAIT_EXT           BIT11  ///< MONITIOR/MWAIT Extensions supported.
+#define PPM_EEPST               BIT12  ///< Energy efficient P-State Feature enabled
+#define PPM_TSTATE_FINE_GRAINED BIT13  ///< Fine grained CPU Throttling states
+#define PPM_CD                  BIT14  ///< Deep Cstate - C8/C9/C10
+#define PPM_TIMED_MWAIT         BIT15  ///< Timed Mwait support
+#define C6_LONG_LATENCY_ENABLE  BIT16  ///< 1=C6 Long and Short,0=C6 Short only
+#define C7_LONG_LATENCY_ENABLE  BIT17  ///< 1=C7 Long and Short,0=C7 Short only
+#define C7s_LONG_LATENCY_ENABLE BIT18  ///< 1=C7s Long and Short,0=C7s Short only
+#define PPM_C8                  BIT19  ///< 1= C8 enabled/supported
+#define PPM_C9                  BIT20  ///< 1= C9 enabled/supported
+#define PPM_C10                 BIT21  ///< 1= C10 enabled/supported
+#define PPM_HWP                 BIT22  ///< 1= HWP enabled/supported
+#define PPM_HWP_LVT             BIT23  ///< 1= HWP LVT enabled/supported
+#define PPM_OC_UNLOCKED         BIT24  ///< 1= Overclocking fully unlocked
+
+#define PPM_C_STATES            0x7A    ///< PPM_C1 + PPM_C3 + PPM_C6 + PPM_C7 + PPM_C7S
+#define C3_LATENCY              0x4E
+#define C6_C7_SHORT_LATENCY     0x76
+#define C6_C7_LONG_LATENCY      0x94
+#define C8_LATENCY              0xFA
+#define C9_LATENCY              0x14C
+#define C10_LATENCY             0x3F2
+
+//
+// The following definitions are based on assumed location for the  ACPI
+// Base Address.  Modify as necessary base on platform-specific requirements.
+//
+#define PCH_ACPI_PBLK 0x1810
+#define PCH_ACPI_LV2  0x1814
+#define PCH_ACPI_LV3  0x1815
+#define PCH_ACPI_LV4  0x1816
+#define PCH_ACPI_LV6  0x1818
+#define PCH_ACPI_LV5  0x1817
+#define PCH_ACPI_LV7  0x1819
+
+//
+// C-State Latency (us) and Power (mW) for C1
+//
+#define C1_LATENCY                        1
+#define C1_POWER                          0x3E8
+#define C3_POWER                          0x1F4
+#define C6_POWER                          0x15E
+#define C7_POWER                          0xC8
+#define C8_POWER                          0xC8
+#define C9_POWER                          0xC8
+#define C10_POWER                         0xC8
+
+
+#define PID_DOMAIN_KP                     0
+#define PID_DOMAIN_KI                     1
+#define PID_DOMAIN_KD                     2
+#define MAILBOX_PARAM_1_OFFSET            8
+
+///
+///  VR Domain Definitions
+///
+#define CPU_VR_DOMAIN_SA           0x0
+#define CPU_VR_DOMAIN_IA           0x1
+#define CPU_VR_DOMAIN_RING         0x2
+#define CPU_VR_DOMAIN_GT           0x3
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
new file mode 100644
index 0000000000..68f2c019e2
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
@@ -0,0 +1,261 @@
+/** @file
+  Register names for CPU registers
+
+  <b>Conventions</b>
+  - Definitions beginning with "MSR_" are MSRs
+  - 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) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_REGS_H_
+#define _CPU_REGS_H_
+
+#define MSR_CORE_THREAD_COUNT                                         0x00000035
+#define B_THREAD_COUNT_MASK                                           0xFFFF
+#define MSR_SPCL_CHIPSET_USAGE_ADDR                                   0x000001FE
+///
+/// Arch-specific MSR defines in SDM
+/// @{
+
+#define MSR_PLATFORM_INFO                                             0x000000CE
+#define N_PLATFORM_INFO_MIN_RATIO                                     40
+#define B_PLATFORM_INFO_RATIO_MASK                                    0xFF
+#define N_PLATFORM_INFO_MAX_RATIO                                     8
+#define B_MSR_PLATFORM_INFO_BIOSGUARD_AVAIL                           BIT35
+#define N_MSR_PLATFORM_INFO_CONFIG_TDP_NUM_LEVELS_OFFSET              33
+#define V_CONFIG_TDP_NUM_LEVELS_MASK                                  (BIT34 | BIT33)
+#define B_PLATFORM_INFO_TDC_TDP_LIMIT                                 BIT29
+#define N_PLATFORM_INFO_RATIO_LIMIT                                   28
+#define B_PLATFORM_INFO_RATIO_LIMIT                                   BIT28
+#define B_PLATFORM_INFO_SAMPLE_PART                                   BIT27
+#define B_PLATFORM_INFO_SMM_SAVE_CONTROL                              BIT16
+#define N_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET                    30
+#define B_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET                    BIT30
+#define B_PLATFORM_INFO_TIMED_MWAIT_SUPPORTED                         BIT37
+#define B_PLATFORM_INFO_EDRAM_EN                                      BIT57
+
+//
+// MSR_BROADWELL_PKG_CST_CONFIG_CONTROL: related defines
+//
+#define B_TIMED_MWAIT_ENABLE                                          BIT31 ///< @todo Remove when bitfield definition is available.
+#define V_CSTATE_LIMIT_C1                                             0x01
+#define V_CSTATE_LIMIT_C3                                             0x02
+#define V_CSTATE_LIMIT_C6                                             0x03
+#define V_CSTATE_LIMIT_C7                                             0x04
+#define V_CSTATE_LIMIT_C7S                                            0x05
+#define V_CSTATE_LIMIT_C8                                             0x06
+#define V_CSTATE_LIMIT_C9                                             0x07
+#define V_CSTATE_LIMIT_C10                                            0x08
+
+#define MSR_PMG_IO_CAPTURE_BASE                                       0x000000E4
+#define B_MSR_PMG_CST_RANGE                                           (BIT18 | BIT17 | BIT16)
+#define V_IO_CAPT_LVL2                                                (0x0 << 16)   ///< C3
+#define V_IO_CAPT_LVL3                                                (0x1 << 16)   ///< C6
+#define V_IO_CAPT_LVL4                                                (0x2 << 16)   ///< C7
+#define V_IO_CAPT_LVL5                                                (0x3 << 16)   ///< C8
+#define V_IO_CAPT_LVL6                                                (0x4 << 16)   ///< C9
+#define V_IO_CAPT_LVL7                                                (0x5 << 16)   ///< C10
+#define V_IO_CAPT_LVL2_BASE_ADDR_MASK                                 0xFFFF
+
+#define MSR_TEMPERATURE_TARGET                                        0x000001A2
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LOCK                      BIT31
+#define N_MSR_TEMPERATURE_TARGET_TCC_OFFSET_LIMIT                     24
+#define V_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_OFFSET_MASK           0x3F
+#define N_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_OFFSET    (16)
+#define B_MSR_TEMPERATURE_TARGET_TCC_ACTIVATION_TEMPERATURE_MASK      (0xFF << 16)
+#define N_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET               8
+#define B_MSR_TEMPERATURE_TARGET_FAN_TEMP_TARGET_OFFSET               (0xFF << 8)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_TIME_WINDOW               (0x7F)
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_MASK                      0xFF
+#define B_MSR_TEMPERATURE_TARGET_TCC_OFFSET_CLAMP_BIT                 BIT7
+
+
+#define MSR_TURBO_RATIO_LIMIT                                         0x000001AD
+#define N_MSR_TURBO_RATIO_LIMIT_1C                                    0
+#define B_MSR_TURBO_RATIO_LIMIT_1C                                    (0xFF << 0)
+#define N_MSR_TURBO_RATIO_LIMIT_2C                                    8
+#define B_MSR_TURBO_RATIO_LIMIT_2C                                    (0xFF << 8)
+#define N_MSR_TURBO_RATIO_LIMIT_3C                                    16
+#define B_MSR_TURBO_RATIO_LIMIT_3C                                    (0xFF << 16)
+#define N_MSR_TURBO_RATIO_LIMIT_4C                                    24
+#define B_MSR_TURBO_RATIO_LIMIT_4C                                    (0xFF << 24)
+#define N_MSR_TURBO_RATIO_LIMIT_5C                                    32
+#define B_MSR_TURBO_RATIO_LIMIT_5C                                    (0xFF << 32)
+#define N_MSR_TURBO_RATIO_LIMIT_6C                                    40
+#define B_MSR_TURBO_RATIO_LIMIT_6C                                    (0xFF << 40)
+#define N_MSR_TURBO_RATIO_LIMIT_7C                                    48
+#define B_MSR_TURBO_RATIO_LIMIT_7C                                    (0xFF << 48)
+#define N_MSR_TURBO_RATIO_LIMIT_8C                                    56
+#define B_MSR_TURBO_RATIO_LIMIT_8C                                    (0xFF << 56)
+
+#define MSR_IA32_FEATURE_CONFIG                                       0x0000013C
+#define B_IA32_FEATURE_CONFIG_AES_DIS                                 BIT1
+#define B_IA32_FEATURE_CONFIG_LOCK                                    BIT0
+
+//
+// MSRs for SMM State Save Register
+//
+#define MSR_SMM_MCA_CAP                                               0x0000017D
+#define B_TARGETED_SMI                                                BIT56
+#define N_TARGETED_SMI                                                56
+#define B_SMM_CPU_SVRSTR                                              BIT57
+#define N_SMM_CPU_SVRSTR                                              57
+#define B_SMM_CODE_ACCESS_CHK                                         BIT58
+#define N_SMM_CODE_ACCESS_CHK                                         58
+#define B_LONG_FLOW_INDICATION                                        BIT59
+#define N_LONG_FLOW_INDICATION                                        59
+#define MSR_SMM_FEATURE_CONTROL                                       0x000004E0
+#define B_SMM_FEATURE_CONTROL_LOCK                                    BIT0
+#define B_SMM_CPU_SAVE_EN                                             BIT1
+#define B_SMM_CODE_CHK_EN                                             BIT2
+
+/// @}
+
+
+///
+/// Bit defines for MSRs defined in UefiCpuPkg/Include/Register/ArchitecturalMsr.h.
+/// @{
+
+//
+// Number of fixed MTRRs
+//
+#define V_FIXED_MTRR_NUMBER                                           11
+
+//
+// Number of variable MTRRs
+//
+#define V_MAXIMUM_VARIABLE_MTRR_NUMBER                                10
+
+//
+// Bit defines for MSR_IA32_MTRR_DEF_TYPE
+//
+#define B_CACHE_MTRR_VALID                                            BIT11
+#define B_CACHE_FIXED_MTRR_VALID                                      BIT10
+
+//
+// Bit defines for MSR_IA32_DEBUG_INTERFACE
+//
+#define B_DEBUG_INTERFACE_ENABLE                                      BIT0
+#define B_DEBUG_INTERFACE_LOCK                                        BIT30
+#define B_DEBUG_INTERFACE_DEBUG_STATUS                                BIT31
+
+/// @}
+
+///
+/// Other defines
+///
+#ifndef TRIGGER_MODE_EDGE
+#define TRIGGER_MODE_EDGE             0x00
+#endif
+#ifndef TRIGGER_MODE_LEVEL
+#define TRIGGER_MODE_LEVEL            0x01
+#endif
+
+#ifndef CPU_FEATURE_DISABLE
+#define CPU_FEATURE_DISABLE  0
+#endif
+#ifndef CPU_FEATURE_ENABLE
+#define CPU_FEATURE_ENABLE   1
+#endif
+
+#define CACHE_UNCACHEABLE               0
+#define CACHE_WRITECOMBINING            1
+#define CACHE_WRITETHROUGH              4
+#define CACHE_WRITEPROTECTED            5
+#define CACHE_WRITEBACK                 6
+
+
+//
+// Processor Definitions
+//
+#define CPUID_FULL_STEPPING                      0x0000000F
+#define CPUID_FULL_FAMILY_MODEL                  0x0FFF0FF0
+#define CPUID_FULL_FAMILY_MODEL_STEPPING         0x0FFF0FFF
+#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX 0x000806E0
+#define CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO 0x000906E0
+#define CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO 0x00060670
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND 1000
+#endif
+
+#define BITS(x) (1 << (x))
+
+/**
+Notes :
+  1.  Bit position always starts at 0.
+  2.  Following macros are applicable only for Word aligned integers.
+**/
+#define BIT(Pos, Value)               (1 << (Pos) & (Value))
+#define BITRANGE(From, Width, Value)  (((Value) >> (From)) & ((1 << (Width)) - 1))
+
+///
+/// Enums for CPU Family IDs
+///
+typedef enum {
+  EnumCpuCflUltUlx    = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX,
+  EnumCpuCflDtHalo    = CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO,
+  EnumCpuCnlDtHalo    = CPUID_FULL_FAMILY_MODEL_CANNONLAKE_DT_HALO,
+  EnumCpuMax          = CPUID_FULL_FAMILY_MODEL
+} CPU_FAMILY;
+
+///
+/// Enums for CPU Stepping IDs
+///
+typedef enum {
+  ///
+  /// Coffeelake ULX/ULT Steppings
+  ///
+  EnumKblH0         = 9,
+  EnumCflD0         = 0xA,
+
+  /// Whiskey Lake ULT Steppings
+  EnumCflW0         = 0xB,
+  EnumCflV0         = 0xC,
+
+  EnumCflMaxUltUlxStep = EnumCflV0,
+
+  ///
+  /// Coffeelake DT/Halo Steppings
+  ///
+  EnumCflU0         = 0xA,
+  EnumCflB0         = 0xB,
+  EnumCflP0         = 0xC,
+  EnumCflR0         = 0xD,
+  EnumCflMaxDtHaloStep = EnumCflR0,
+
+  ///
+  /// Max Stepping
+  ///
+  EnumCpuSteppingMax  = CPUID_FULL_STEPPING
+} CPU_STEPPING;
+
+///
+/// Enums for CPU SKU IDs
+///
+typedef enum {
+  EnumCpuUlt        = 0,
+  EnumCpuTrad,
+  EnumCpuUlx,
+  EnumCpuHalo,
+  EnumCpuUnknown
+} CPU_SKU;
+
+///
+/// Enums for CPU Generation
+///
+typedef enum {
+  EnumCflCpu  = 0,
+  EnumCpuUnknownGeneration = 255
+} CPU_GENERATION;
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
new file mode 100644
index 0000000000..79dff36783
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
@@ -0,0 +1,90 @@
+/** @file
+  Header file for Cpu Mailbox Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_MAILBOX_LIB_H_
+#define _CPU_MAILBOX_LIB_H_
+
+//
+//  Mailbox Related Definitions
+//
+
+/**
+  Generic Mailbox function for mailbox write commands. This function will
+  poll the mailbox interface for control, issue the write request, poll
+  for completion, and verify the write was succussful.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[in]  MailboxData     Overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status values are:
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  IN UINT32  MailboxData,
+  OUT UINT32 *MailboxStatus
+  );
+
+/**
+  Generic Mailbox function for mailbox read commands. This function will write
+  the read request from MailboxType, and populate the read results in the MailboxDataPtr.
+
+  @param[in]  MailboxType     The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+  @param[in]  MailboxCommand  Overclocking mailbox command data
+  @param[out] *MailboxDataPtr Pointer to the overclocking mailbox interface data
+  @param[out] *MailboxStatus  Pointer to the mailbox status returned from pcode. Possible mailbox status are
+                              - SUCCESS (0)               Command succeeded.
+                              - OC_LOCKED (1)             Overclocking is locked. Service is read-only.
+                              - INVALID_DOMAIN (2)        Invalid Domain ID provided in command data.
+                              - MAX_RATIO_EXCEEDED (3)    Ratio exceeds maximum overclocking limits.
+                              - MAX_VOLTAGE_EXCEEDED (4)  Voltage exceeds input VR's max voltage.
+                              - OC_NOT_SUPPORTED (5)      Domain does not support overclocking.
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+          - EFI_UNSUPPORTED       Unsupported MailboxType parameter.
+
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN UINT32  MailboxType,
+  IN UINT32  MailboxCommand,
+  OUT UINT32 *MailboxDataPtr,
+  OUT UINT32 *MailboxStatus
+  );
+
+/**
+  Poll the run/busy bit of the mailbox until available or timeout expires.
+
+  @param[in]  MailboxType
+
+  @retval EFI_STATUS
+          - EFI_SUCCESS           Command succeeded.
+          - EFI_TIMEOUT           Command timeout.
+**/
+EFI_STATUS
+EFIAPI
+PollMailboxReady (
+  IN UINT32 MailboxType
+  );
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
new file mode 100644
index 0000000000..a2dc83efb5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
@@ -0,0 +1,118 @@
+/** @file
+  Header file for CpuPlatform Lib.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PLATFORM_LIB_H_
+#define _CPU_PLATFORM_LIB_H_
+
+#include <CpuRegs.h>
+#include <CpuDataStruct.h>
+#include <CpuPowerMgmt.h>
+
+/**
+  Check CPU Type of the platform
+
+  @retval CPU_FAMILY              CPU type
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+  VOID
+  );
+
+/**
+  Return Cpu stepping type
+
+  @retval CPU_STEPPING                   Cpu stepping type
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+  VOID
+  );
+
+/**
+  Return CPU Sku
+
+  @retval UINT8              CPU Sku
+**/
+UINT8
+EFIAPI
+GetCpuSku (
+  VOID
+  );
+
+/**
+  Returns the processor microcode revision of the processor installed in the system.
+
+  @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+  VOID
+  );
+
+/**
+  Check if this microcode is correct one for processor
+
+  @param[in] Cpuid               - processor CPUID
+  @param[in] MicrocodeEntryPoint - entry point of microcode
+  @param[in] Revision            - revision of microcode
+
+  @retval CorrectMicrocode if this microcode is correct
+**/
+BOOLEAN
+CheckMicrocode (
+  IN UINT32               Cpuid,
+  IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+  IN UINT32               *Revision
+  );
+
+/**
+  Check on the processor if SGX is supported.
+
+  @retval True if SGX supported or FALSE if not
+**/
+BOOLEAN
+IsSgxSupported (
+  VOID
+  );
+
+/**
+  Get processor generation
+
+  @retval CPU_GENERATION  Returns the executing thread's processor generation.
+**/
+CPU_GENERATION
+GetCpuGeneration (
+  VOID
+  );
+
+/**
+  Check if Disable CPU Debug (DCD) bit is set from FIT CPU Debugging [Disabled].
+  If it is set, CPU probe mode is disabled.
+
+  @retval TRUE    DCD is set
+  @retval FALSE   DCD is clear
+**/
+BOOLEAN
+IsCpuDebugDisabled (
+  VOID
+  );
+
+/**
+  Is Whiskey Lake CPU.
+
+  @retval TRUE  The CPUID corresponds with a Whiskey Lake CPU
+  @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
+**/
+BOOLEAN
+IsWhlCpu (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
new file mode 100644
index 0000000000..88f4353e91
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
@@ -0,0 +1,84 @@
+/** @file
+  Prototype of the CpuPolicy library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_LIB_H_
+#define _CPU_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  Print whole CPU related config blocks of SI_PREMEM_POLICY_PPI and serial out.
+
+  @param[in] SiPreMemPolicyPpi             The Si PreMem Policy PPI instance
+**/
+VOID
+CpuPreMemPrintPolicy (
+IN  SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+);
+
+/**
+  Get CPU PREMEM config block table total size.
+
+  @retval Size of CPU PREMEM config block table
+**/
+UINT16
+EFIAPI
+CpuGetPreMemConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU PREMEM config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddPreMemConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+/**
+  Print whole CPU config blocks of SiPolicyPpi and serial out.
+
+  @param[in] SiPolicyPpi             The SI Policy PPI instance
+**/
+VOID
+CpuPrintPolicy (
+  IN  SI_POLICY_PPI                 *SiPolicyPpi
+  );
+
+/**
+  Get CPU config block table total size.
+
+  @retval Size of CPU config block table
+**/
+UINT16
+EFIAPI
+CpuGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  CpuAddConfigBlocks add all Cpu config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add CPU config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddConfigBlocks (
+  IN     VOID      *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_CPU_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
new file mode 100644
index 0000000000..67f88ce987
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
@@ -0,0 +1,123 @@
+/** @file
+  Protocol used to report CPU information
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_INFO_H_
+#define _CPU_INFO_H_
+
+#include <CpuDataStruct.h>
+
+typedef struct _CPU_INFO_PROTOCOL CPU_INFO_PROTOCOL;
+
+
+extern EFI_GUID gCpuInfoProtocolGuid;
+
+//
+// DXE_CPU_INFO_PROTOCOL revisions
+//
+#define CPU_INFO_PROTOCOL_REVISION 1
+
+//
+// Processor feature definitions.
+//
+#define TXT_SUPPORT        BIT0
+#define VMX_SUPPORT        BIT1
+#define XD_SUPPORT         BIT2
+#define DCA_SUPPORT        BIT3
+#define X2APIC_SUPPORT     BIT4
+#define AES_SUPPORT        BIT5
+#define HT_SUPPORT         BIT6
+#define DEBUG_SUPPORT      BIT7
+#define DEBUG_LOCK_SUPPORT BIT8
+#define PROC_TRACE_SUPPORT BIT9
+#define HDC_SUPPORT        BIT10
+
+
+#pragma pack(1)
+///
+/// Cache descriptor information
+///
+typedef struct {
+  UINT8   Desc;                                    ///< Cache Descriptor
+  UINT8   Level;                                   ///< Cache Level
+  UINT8   Type;                                    ///< Cache Type. 0: Data, 1: Instruction, 3: Unified
+  UINT32  Size;                                    ///< Cache Size.
+  UINT16  Associativity;                           ///< Cache Ways of Associativity.
+} CACHE_DESCRIPTOR_INFO;
+
+///
+/// Processor information
+///
+typedef struct {
+  UINT32                CpuSignature;               ///< Processor signature and version information.
+  UINT64                Features;                   ///< Features availability in the CPU based on reading ECX after doing Asmcpuid(EAX=1).
+  CHAR8                 *BrandString;               ///< Processor Brand String.
+  UINT8                 NumSupportedCores;          ///< Total Number of Supported Cores in CPU Package. If Dual core, 2 cores.
+  UINT8                 NumSupportedThreadsPerCore; ///< Number of Supported Threads per Core.
+  UINT8                 NumCores;                   ///< Number of Enabled or Active Cores.
+  UINT8                 NumHts;                     ///< Number of Enabled Threads per Core. This will be 1 or 2.
+  UINT32                IntendedFreq;               ///< Maximum non turbo ratio in MHz
+  UINT32                ActualFreq;                 ///< Actual frequency in MHz
+  UINT32                Voltage;                    ///< Current operating voltage.
+  CACHE_DESCRIPTOR_INFO *CacheInfo;                 ///< Cache descriptor information.
+  UINT8                 MaxCacheSupported;          ///< Maximum cache supported.
+  UINT8                 SmmbaseSwSmiNumber;         ///< Software SMI Number from Smbase. @Note: This is unused.
+  UINT16                NumberOfPStates;            ///< Number of P-States.
+} CPU_INFO;
+
+///
+/// This HOB is data structure representing two different address location in SMRAM to hold SMRAM CPU DATA.
+///
+typedef struct {
+  EFI_PHYSICAL_ADDRESS LockBoxData;  ///< First location (address) of SMRAM CPU DATA.
+  EFI_PHYSICAL_ADDRESS SmramCpuData; ///< Second location (Address) of SMRAM CPU DATA.
+  UINT64               LockBoxSize;  ///< Size of SMRAM CPU DATA.
+} SMRAM_CPU_INFO;
+
+///
+/// SGX Information
+///
+typedef struct {
+  UINT64  SgxSinitNvsData;  ///< Sinit SE SVN Version saved and passed back in next boot
+} SGX_INFO;
+
+#pragma pack()
+
+///
+/// This protocol provides information about the common features available in this CPU.
+///
+struct _CPU_INFO_PROTOCOL {
+  /**
+  Revision for the protocol structure.
+  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>:
+   -  Initial version
+  **/
+  UINT8  Revision;
+  /**
+  CPU Supported Feature.
+   - BIT0:  If set then processor supports TXT.
+   - BIT1:  If set then processor supports virtual mode extensions.
+   - BIT2:  If set then processor supports execute disable bit.
+   - BIT3:  If set then processor supports DCA.
+   - BIT4:  If set then processor supports X2APIC.
+   - BIT5:  If set then processor supports Advanced Encryption Standard.
+   - BIT6:  If set then processor supports hyperthreading.
+   - BIT7:  If set then processor supports debug interface.
+   - BIT8:  If set then processor supports debug interface lock.
+   - BIT9:  If set then processor supports processor trace.
+   - BIT10: If Set then processor supports supports HDC.
+  **/
+  UINT64         CpuCommonFeatures;
+  CPU_INFO       *CpuInfo;      ///< Processor Basic Information
+  SMRAM_CPU_INFO *SmramCpuInfo; ///< SMRAM CPU Information
+  SGX_INFO       *SgxInfo;      ///< SGX Information
+};
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
new file mode 100644
index 0000000000..ed056025b7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
@@ -0,0 +1,50 @@
+/** @file
+  Protocol used for specifying platform related CPU information and policy setting.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_PROTOCOL_H_
+#define _CPU_POLICY_PROTOCOL_H_
+
+//
+// DXE_CPU_POLICY_PROTOCOL revisions
+//
+#define DXE_CPU_POLICY_PROTOCOL_REVISION 1
+
+extern EFI_GUID gDxeCpuPolicyProtocolGuid;
+
+#pragma pack (push,1)
+
+/**
+  The protocol allows the platform code to publish a set of configuration information that the
+  CPU drivers will use to configure the processor in the DXE phase.
+  This Policy Protocol needs to be initialized for CPU configuration.
+  @note The Protocol has to be published before processor DXE drivers are dispatched.
+**/
+typedef struct {
+  /**
+  This member specifies the revision of the Cpu Policy protocol. This field is used to indicate backward
+  compatible changes to the protocol. Any such changes to this protocol will result in an update in the revision number.
+
+  <b>Revision 1</b>:
+   - Initial version
+  **/
+  /**
+  Policies to obtain CPU temperature.
+   - <b>0: ACPI thermal management uses EC reported temperature values</b>.
+   - 1: ACPI thermal management uses DTS SMM mechanism to obtain CPU temperature values.
+   - 2: ACPI Thermal Management uses EC reported temperature values and DTS SMM is used to handle Out of Spec condition.
+  **/
+  UINT32                         EnableDts           : 2;
+  UINT32                         RsvdBit             : 30;  ///< Reserved bits, align to multiple 32;
+
+  UINT8                          Revision;                  ///< Current revision of policy.
+  UINT8                          ReservedByte[3];           ///< Reserved bytes, align to multiple 8.
+} DXE_CPU_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add Include headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
  2019-08-17  0:51   ` Nate DeSimone
  2019-08-17  1:08   ` Chiu, Chasel
@ 2019-08-17  7:04   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17  7:04 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Desimone, Nathaniel L, Gao, Liming,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: Add Include headers

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

Adds header files common to ME modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h | 124 ++++++++++++++  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h  |  59 +++++++  Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h  |  87 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h               | 172 ++++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h             |  17 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h                |  19 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h       |  41 +++++
 7 files changed, 519 insertions(+)

diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
new file mode 100644
index 0000000000..102fb43bd1
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiCon
+++ fig.h
@@ -0,0 +1,124 @@
+/** @file
+  ME config block for PEI phase
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_PEI_CONFIG_H_
+#define _ME_PEI_CONFIG_H_
+
+#include <ConfigBlock.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>:
+  - Change DidInitStat bit width.
+**/
+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>(Test)</b> 0: Disable; <b>1: Enable</b> - Enable/Disable to send DID message.
+  /**
+    <b>(Test)</b>
+    <b>0: Set to 0 to enable retry mechanism for HECI APIs</b>
+       1: Set to 1 will disable retry mechanism for HECI APIs
+  **/
+  UINT32 DisableHeciRetry                 : 1;
+  /**
+    <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 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 2
+extern EFI_GUID gMePeiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME Pei Post-Memory Configuration Structure.
+
+  <b>Revision 1:</b>
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add MctpBroadcastCycle test setting.
+**/
+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.
+  /**
+    HECI3 state from Mbp for reference in S3 path only
+    <b>0: Disabled</b>; 1: Enabled
+  **/
+  UINT32 Heci3Enabled                     : 1;
+  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 RsvdBits                         : 25;  ///< Reserved for future use & Config block alignment
+} ME_PEI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ME_PEI_CONFIG_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
new file mode 100644
index 0000000000..46f7f86021
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyL
+++ ib.h
@@ -0,0 +1,59 @@
+/** @file
+  Prototype of the DxeMePolicyLib library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _DXE_ME_POLICY_LIB_H_
+#define _DXE_ME_POLICY_LIB_H_
+
+#include <Protocol/MePolicy.h>
+
+/**
+  This function prints the ME DXE phase policy.
+
+  @param[in] DxeMePolicy - ME DXE Policy protocol **/ VOID 
+MePrintPolicyProtocol (
+  IN  ME_POLICY_PROTOCOL             *DxeMePolicy
+  );
+
+/**
+  MeCreatePolicyDefaults creates the default setting of ME Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[in, out] DxeMePolicy           The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+MeCreatePolicyDefaults (
+  IN OUT  ME_POLICY_PROTOCOL            **DxeMePolicy
+  );
+
+/**
+  MeInstallPolicyProtocol installs ME 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] DxeMePolicy                The pointer to ME Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+MeInstallPolicyProtocol (
+  IN  EFI_HANDLE                    ImageHandle,
+  IN  ME_POLICY_PROTOCOL            *DxeMePolicy
+  );
+
+#endif // _DXE_ME_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
new file mode 100644
index 0000000000..5db4714346
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyL
+++ ib.h
@@ -0,0 +1,87 @@
+/** @file
+  Prototype of the MePolicyLibPei library.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _PEI_ME_POLICY_LIB_H_
+#define _PEI_ME_POLICY_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function prints the PEI phase PreMem policy.
+
+  @param[in] SiPolicyPreMemPpi              The RC PreMem Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpiPreMem (
+  IN  SI_PREMEM_POLICY_PPI *SiPolicyPreMemPpi
+  );
+
+/**
+  This function prints the PEI phase policy.
+
+  @param[in] SiPolicyPpi              The RC Policy PPI instance
+**/
+VOID
+EFIAPI
+MePrintPolicyPpi (
+  IN  SI_POLICY_PPI     *SiPolicyPpi
+  );
+
+/**
+  Get Me config block table total size.
+
+  @retval     Size of Me config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Get ME config block table total size.
+
+  @retval      Size of ME config block table
+**/
+UINT16
+EFIAPI
+MeGetConfigBlockTotalSizePreMem (
+  VOID
+  );
+
+/**
+  MeAddConfigBlocksPreMem add all ME config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add ME config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocksPreMem (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  MeAddConfigBlocks add all ME config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add ME config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+MeAddConfigBlocks (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _PEI_ME_POLICY_LIB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
new file mode 100644
index 0000000000..f29f9bc8bd
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
@@ -0,0 +1,172 @@
+/** @file
+  Chipset definition for ME Devices.
+
+  Conventions:
+
+  - 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
+  - Registers / bits that are different between PCH generations are denoted by
+    "_ME_[generation_name]_" in register/bit names.
+  - Registers / bits that are specific to PCH-H denoted by "PCH_H_" in register/bit names.
+    Registers / bits that are specific to PCH-LP denoted by "PCH_LP_" in register/bit names.
+    e.g., "_ME_PCH_H_", "_ME_PCH_LP_"
+    Registers / bits names without _PCH_H_ or _PCH_LP_ apply for both H and 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 "_ME_" without [generation_name] inserted.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_CHIPSET_H_
+#define _ME_CHIPSET_H_
+
+#define ME_SEGMENT            0
+#define ME_BUS                0
+#define ME_DEVICE_NUMBER      22
+#define HECI_MIN_FUNC         0
+#define HECI_MAX_FUNC         5
+
+#define HECI_FUNCTION_NUMBER  0x00
+#define HECI2_FUNCTION_NUMBER 0x01
+#define IDER_FUNCTION_NUMBER  0x02
+#define SOL_FUNCTION_NUMBER   0x03
+#define HECI3_FUNCTION_NUMBER 0x04
+#define HECI4_FUNCTION_NUMBER 0x05
+
+#define IDER_BUS_NUMBER       ME_BUS
+#define IDER_DEVICE_NUMBER    ME_DEVICE_NUMBER
+#define SOL_BUS_NUMBER        ME_BUS
+#define SOL_DEVICE_NUMBER     ME_DEVICE_NUMBER
+
+ ///
+/// Convert to HECI# defined in BWG from Fun# /// #define 
+HECI_NAME_MAP(a) ((a < 2) ? (a + 1) : (a - 1))
+
+///
+/// ME-related Chipset Definition
+///
+#define HeciEnable()    MeDeviceControl (HECI1, Enabled);
+#define Heci2Enable()   MeDeviceControl (HECI2, Enabled);
+#define Heci3Enable()   MeDeviceControl (HECI3, Enabled);
+#define Heci4Enable()   MeDeviceControl (HECI4, Enabled);
+#define IderEnable()    MeDeviceControl (IDER, Enabled);
+#define SolEnable()     MeDeviceControl (SOL, Enabled);
+
+#define HeciDisable()   MeDeviceControl (HECI1, Disabled);
+#define Heci2Disable()  MeDeviceControl (HECI2, Disabled); #define 
+Heci3Disable()  MeDeviceControl (HECI3, Disabled);
+#define IderDisable()   MeDeviceControl (IDER, Disabled);
+#define SolDisable()    MeDeviceControl (SOL, Disabled);
+
+#define DisableAllMeDevices() \
+  HeciDisable (); \
+  Heci2Disable (); \
+  Heci3Disable (); \
+  IderDisable (); \
+  SolDisable ();
+
+///
+/// HECI Device Id Definitions
+///
+ #define IS_PCH_H_HECI_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_H_HECI_DEVICE_ID) \
+     )
+
+ #define IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_LP_HECI_DEVICE_ID) \
+     )
+
+ #define IS_HECI_DEVICE_ID(DeviceId) \
+     ( \
+       IS_PCH_H_HECI_DEVICE_ID(DeviceId) || \
+       IS_PCH_LP_HECI_DEVICE_ID(DeviceId) \
+     )
+
+///
+/// HECI2 Device Id Definitions
+///
+#define IS_PCH_H_HECI2_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_H_HECI2_DEVICE_ID) \
+     )
+
+#define IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
+     (  \
+       (DeviceId == V_ME_PCH_LP_HECI2_DEVICE_ID) \
+     )
+
+#define IS_HECI2_DEVICE_ID(DeviceId) \
+     ( \
+       IS_PCH_H_HECI2_DEVICE_ID(DeviceId) || \
+       IS_PCH_LP_HECI2_DEVICE_ID(DeviceId) \
+     )
+
+///
+/// HECI3 Device Id Definitions
+///
+#define IS_PCH_H_HECI3_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_HECI3_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_HECI3_DEVICE_ID) \
+    )
+
+#define IS_HECI3_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_HECI3_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_HECI3_DEVICE_ID(DeviceId) \
+    )
+
+///
+/// HECI4 Device Id Definitions
+///
+#define IS_PCH_H_HECI4_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_HECI4_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_HECI4_DEVICE_ID) \
+    )
+
+#define IS_HECI4_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_HECI4_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_HECI4_DEVICE_ID(DeviceId) \
+    )
+
+///
+/// SoL Device Id Definitions
+///
+#define IS_PCH_H_SOL_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_H_SOL_DEVICE_ID) \
+    )
+
+#define IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
+    (  \
+      (DeviceId == V_ME_PCH_LP_SOL_DEVICE_ID) \
+    )
+
+#define IS_PCH_SOL_DEVICE_ID(DeviceId) \
+    ( \
+      IS_PCH_H_SOL_DEVICE_ID(DeviceId) || \
+      IS_PCH_LP_SOL_DEVICE_ID(DeviceId) \
+    )
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
new file mode 100644
index 0000000000..a24973ce32
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
@@ -0,0 +1,17 @@
+/** @file
+  This file contains definitions of ME Policy HOB.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_POLICY_HOB_H_
+#define _ME_POLICY_HOB_H_
+
+#include <MePolicyCommon.h>
+
+extern EFI_GUID gMePolicyHobGuid;
+extern EFI_GUID gMePreMemPolicyHobGuid;
+
+#endif // _ME_POLICY_HOB_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
new file mode 100644
index 0000000000..2d8ef1cf7a
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
@@ -0,0 +1,19 @@
+/** @file
+  MKHI Messages
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _MKHI_MSGS_H
+#define _MKHI_MSGS_H
+
+///
+/// End of Post
+///
+#define EOP_DISABLED    0
+#define EOP_SEND_IN_PEI 1
+#define EOP_SEND_IN_DXE 2
+
+#endif // _MKHI_MSGS_H
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
new file mode 100644
index 0000000000..518041cb58
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
@@ -0,0 +1,41 @@
+/** @file
+  Interface definition details between ME and platform drivers during DXE phase.
+
+  Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef _ME_POLICY_H_
+#define _ME_POLICY_H_
+
+#include <ConfigBlock.h>
+
+/**
+  ME Policy Protocol.
+  All ME Policy Protocol change history listed here.
+
+**/
+#define ME_POLICY_PROTOCOL_REVISION  1
+
+extern EFI_GUID gDxeMePolicyGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME policy provided by platform for DXE phase
+  This protocol provides an interface to get Intel ME Configuration 
+information
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _ME_POLICY_PROTOCOL {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;
+/*
+  Individual Config Block Structures are added here in memory as part 
+of AddConfigBlock() */ } ME_POLICY_PROTOCOL;
+
+#pragma pack (pop)
+
+#endif // _ME_POLICY_H_
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:17   ` Chiu, Chasel
@ 2019-08-17  7:50   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17  7:50 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules

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

Modules shared across board instances.

* BoardAcpiDxe - Performs DXE board ACPI initialization.
* PciHotPlug - Performs PCI-e resource configuration.
* PeiTbtInit - Initializes Thunderbolt policy in PEI.
* PolicyInitDxe - Initializes policy in DXE.
* TbtDxe - Performs Thunderbolt initialization in DXE.
* TbtSmm - Performs Thunderbolt initialization in SMM.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf          |   71 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf          |   62 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf         |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf     |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf         |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf      |  176 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h            |  130 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h    |  180 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h         |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h     |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h     |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h     |   52 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h        |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h      |   56 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c            |   96 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c            |  290 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c            |  353 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c           |  228 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c       |  211 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c    | 1609 +++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c           | 1765 ++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c         |  394 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c         |  612 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c     |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c     |  174 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c     |   55 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c        |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c      |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl           |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL             |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl          |  516 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl          |  309 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl         |   76 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl     |  405 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl             | 1877 ++++++++++++++++++++
 37 files changed, 10365 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
new file mode 100644
index 0000000000..2bbc3cb9e2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
@@ -0,0 +1,71 @@
+## @file
+#  Component information file for AcpiPlatform module
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BoardAcpiDxe
+  FILE_GUID                      = E269E77D-6163-4F5D-8E59-21EAF114D307
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InstallAcpiBoard
+
+[Sources.common]
+  BoardAcpiDxe.c
+  AcpiGnvsInit.c
+  Dsdt/DSDT.ASL
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  PcAtChipsetPkg/PcAtChipsetPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  IoLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  HobLib
+  AslUpdateLib
+  BoardAcpiTableLib
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     ## CONSUMES
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gEfiMpServiceProtocolGuid                     ## CONSUMES
+  gEfiGlobalNvsAreaProtocolGuid
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress
+
+  gBoardModuleTokenSpaceGuid.PcdAcpiSleepState
+  gBoardModuleTokenSpaceGuid.PcdAcpiHibernate
+  gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle
+  gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints
+  gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints
+  gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints
+
+[Depex]
+  gEfiAcpiTableProtocolGuid           AND
+  gEfiFirmwareVolume2ProtocolGuid     AND
+  gEfiPciRootBridgeIoProtocolGuid     AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiVariableWriteArchProtocolGuid
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
new file mode 100644
index 0000000000..dd4e41a409
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
@@ -0,0 +1,62 @@
+## @file
+# This module will perform specific PCI-Express devices
+# resource configuration.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PciHotPlug
+  FILE_GUID                      = 3022E512-B94A-4F12-806D-7EF1177899D8
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = PciHotPlug
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DevicePathLib
+  DebugLib
+  UefiLib
+  HobLib
+  PchPcieRpLib
+  ConfigBlockLib
+  TbtCommonLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PciHotPlug.c
+  PciHotPlug.h
+
+[Protocols]
+  gEfiPciHotPlugInitProtocolGuid                ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+
+[Guids]
+  gEfiHobListGuid                               ## CONSUMES
+  gPcieRpConfigGuid                  ## CONSUMES
+
+[Pcd]
+
+[Depex]
+  gDxeTbtPolicyProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
new file mode 100644
index 0000000000..5160bb1dbb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
@@ -0,0 +1,51 @@
+## @file
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtDxe
+  FILE_GUID                      = 19C9762C-3A88-41B0-906F-8C4C2895A887
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = TbtDxeEntryPoint
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  HobLib
+  UefiLib
+  TbtCommonLib
+  DxeTbtPolicyLib
+  AslUpdateLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  TbtDxe.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Depex]
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
new file mode 100644
index 0000000000..07962ffa10
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
@@ -0,0 +1,47 @@
+## @file
+# Component information file for the TBT Init PEI module.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiTbtInit
+  FILE_GUID                      = 90BF2BFB-F998-4cbc-AD72-008D4D047A4B
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = TbtInitEntryPoint
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  HobLib
+  PeiServicesLib
+  PeiTbtPolicyLib
+  PeiDTbtInitLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiTbtInit.c
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Ppis]
+  gEfiEndOfPeiSignalPpiGuid                     ## CONSUMES
+  gPeiTbtPolicyBoardInitDonePpiGuid             ## CONSUMES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
new file mode 100644
index 0000000000..3d4e6ceea0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
@@ -0,0 +1,80 @@
+## @file
+# Component information file for the ThunderBolt Smm module.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = TbtSmm
+  FILE_GUID                      = 5BDCD685-D80A-42E6-9867-A84CCE7F828E
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  PI_SPECIFICATION_VERSION       = 1.10
+  ENTRY_POINT                    = TbtSmmEntryPoint
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  IoLib
+  PciExpressLib
+  HobLib
+  ReportStatusCodeLib
+  PciSegmentLib
+  UefiLib
+  SmmServicesTableLib
+  GpioLib
+  PchInfoLib
+  TbtCommonLib
+  PchPmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+#  gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength      ## CONSUMES
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress       ## CONSUMES
+
+[Sources]
+  TbtSmiHandler.h
+  TbtSmiHandler.c
+  TbtSmm.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gEfiSmmSxDispatch2ProtocolGuid                ## CONSUMES
+  gEfiSmmSwDispatch2ProtocolGuid                ## CONSUMES
+  gEfiSmmVariableProtocolGuid                   ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+
+[Depex]
+  gEfiSmmBase2ProtocolGuid            AND
+  gEfiSmmSxDispatch2ProtocolGuid      AND
+  gEfiSmmSwDispatch2ProtocolGuid      AND
+  gEfiGlobalNvsAreaProtocolGuid       AND
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiSmmVariableProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
new file mode 100644
index 0000000000..65c531a532
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
@@ -0,0 +1,176 @@
+## @file
+# Module Information file for the PolicyInit DXE driver.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PolicyInitDxe
+  FILE_GUID                      = 490D0119-4448-440D-8F5C-F58FB53EE057
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = PolicyInitDxeEntryPoint
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CpuPlatformLib
+  DebugLib
+  DxeServicesTableLib
+  IoLib
+  MemoryAllocationLib
+  DxeSaPolicyLib
+  DxePchPolicyLib
+  PcdLib
+  DxePolicyBoardConfigLib
+  DxePolicyUpdateLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+  ConfigBlockLib
+  DevicePathLib
+  DxeTbtPolicyLib
+  PchPcieRpLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                          ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                          ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable
+  gBoardModuleTokenSpaceGuid.PcdPlatformFlavor
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdEcPresent
+  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid
+  gBoardModuleTokenSpaceGuid.PcdTbtEnable
+  gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable                   ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication                  ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
+  gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport
+  gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport
+  gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin
+  gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
+  gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature
+  gBoardModuleTokenSpaceGuid.PcdBatteryPresent
+
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support
+  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support
+
+  #
+  # PSS Board Configuration.
+  #
+  gBoardModuleTokenSpaceGuid.PcdPssReadSN
+  gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber
+  gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress
+
+  gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature
+  gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile
+  gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio
+  gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdGnssResetGpio
+  gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio
+
+  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
+  gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber
+  gBoardModuleTokenSpaceGuid.PcdEcSmiGpio
+  gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio
+  gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad
+  gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck
+  gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride
+  gBoardModuleTokenSpaceGuid.PcdDDISelection
+  gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6
+  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch
+  gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties
+  gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed
+  gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed
+  gPlatformModuleTokenSpaceGuid.PcdH8S2113Present
+  gPlatformModuleTokenSpaceGuid.PcdNat87393Present
+  gPlatformModuleTokenSpaceGuid.PcdNct677FPresent
+  gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport
+  gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin
+  gBoardModuleTokenSpaceGuid.PcdRealBattery1Control
+  gBoardModuleTokenSpaceGuid.PcdRealBattery2Control
+  gBoardModuleTokenSpaceGuid.PcdDimmPopulationError
+  gBoardModuleTokenSpaceGuid.PcdBtIrqGpio
+  gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio
+  gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable
+  gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported
+  gBoardModuleTokenSpaceGuid.PcdMipiCamSensor
+  gBoardModuleTokenSpaceGuid.PcdH8S2113SIO
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO
+  gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON
+  gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable
+  gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate
+
+[Sources]
+  PolicyInitDxe.c
+  SaPolicyInitDxe.c
+  SiliconPolicyInitDxe.c
+  GopPolicyInitDxe.c
+  PchPolicyInitDxe.c
+  CpuPolicyInitDxe.c
+  BoardInitLib.c
+
+[Protocols]
+  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
+  gDxeMePolicyGuid                              ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+  gPchPolicyProtocolGuid                        ## CONSUMES
+  gDxeSiPolicyProtocolGuid                      ## PRODUCES
+  gGopPolicyProtocolGuid                        ## PRODUCES
+  gDxeCpuPolicyProtocolGuid                     ## PRODUCES
+
+[Guids]
+  gCpuSmmGuid                                   ## CONSUMES
+  gSiMemoryInfoDataGuid
+
+[Depex]
+  gEfiVariableArchProtocolGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
new file mode 100644
index 0000000000..f57bfb8c26
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
@@ -0,0 +1,130 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCI_HOT_PLUG_H_
+#define _PCI_HOT_PLUG_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <Base.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Acpi10.h>
+#include <Protocol/PciHotPlugInit.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+#include <Protocol/SaPolicy.h>
+
+#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U', 'L', 'P')
+
+#define ACPI \
+  { \
+    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 \
+  }
+
+#define PCI(device, function) \
+  { \
+    { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \
+      (UINTN) function, (UINTN) device \
+  }
+
+#define END \
+  { \
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
+  }
+
+#define LPC(eisaid, function) \
+  { \
+    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid), function \
+  }
+
+typedef struct PCIE_HOT_PLUG_DEVICE_PATH {
+  ACPI_HID_DEVICE_PATH      PciRootBridgeNode;
+  PCI_DEVICE_PATH           PciRootPortNode;
+  EFI_DEVICE_PATH_PROTOCOL  EndDeviceNode;
+} PCIE_HOT_PLUG_DEVICE_PATH;
+
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle; // Handle for protocol this driver installs on
+  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  HotPlugInitProtocol;
+} PCI_HOT_PLUG_INSTANCE;
+
+/**
+  This procedure returns a list of Root Hot Plug controllers that require
+  initialization during boot process
+
+  @param[in]  This      The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[out] HpcCount  The number of Root HPCs returned.
+  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+  @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
+  OUT UINTN                             *PhpcCount,
+  OUT EFI_HPC_LOCATION                  **PhpcList
+  );
+
+/**
+  This procedure Initializes one Root Hot Plug Controller
+  This process may casue initialization of its subordinate buses
+
+  @param[in]  This            The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[in]  HpcDevicePath   The Device Path to the HPC that is being initialized.
+  @param[in]  HpcPciAddress   The address of the Hot Plug Controller function on the PCI bus.
+  @param[in]  Event           The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+  @param[out] HpcState        The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+  @retval   EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
+  IN  UINT64                          PhpcPciAddress,
+  IN  EFI_EVENT                       Event, OPTIONAL
+  OUT EFI_HPC_STATE                   *PhpcState
+  );
+
+/**
+  Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+  @param[in]  This           The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
+  @param[in]  HpcPciAddress  The address of the Hot Plug Controller function on the PCI bus.
+  @param[out] HpcState       The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+  @param[out] Padding        This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+  @param[out] Attribute      Describes how padding is accounted for.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
+  IN  UINT64                          PhpcPciAddress,
+  OUT EFI_HPC_STATE                   *PhpcState,
+  OUT VOID                            **Padding,
+  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
new file mode 100644
index 0000000000..b91b0f14bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
@@ -0,0 +1,180 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_SMI_HANDLER_H_
+#define _TBT_SMI_HANDLER_H_
+
+#include <Library/TbtCommonLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/Pci.h>
+
+#ifdef PROGRESS_CODE
+#undef PROGRESS_CODE
+#endif
+
+#define MAX_TBT_DEPTH         6
+
+#define P2P_BRIDGE            (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define BAR_ALIGN(v, a)       ((((v) - 1) | (a)) + 1)
+
+#define CMD_BUS_MASTER        BIT2
+#define CMD_BM_IO             (CMD_BUS_MASTER | BIT0)
+#define CMD_BM_MEM            (CMD_BUS_MASTER | BIT1)
+#define CMD_BM_MEM_IO         (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DEF_CACHE_LINE_SIZE   0x20
+#define DEF_RES_IO_PER_DEV    4
+#define DEF_RES_MEM_PER_DEV   32
+#define DEF_RES_PMEM_PER_DEV  32
+
+#define DOCK_BUSSES           8
+
+#define DISBL_IO_REG1C        0x01F1
+#define DISBL_MEM32_REG20     0x0000FFF0
+#define DISBL_PMEM_REG24      0x0001FFF1
+
+#define count(x)              (sizeof (x) / sizeof ((x)[0]))
+
+#define PCIE_CAP_ID_SSID_SSVID 0x0D
+#define INVALID_PCI_DEVICE    0xFFFFFFFF
+#define PCI_TBT_VESC_REG2     0x510
+
+typedef struct _PortInfo {
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+  UINT8   BusNumLimit;
+  UINT8   ConfedEP;
+} PORT_INFO;
+
+typedef struct _MEM_REGS {
+  UINT32  Base;
+  UINT32  Limit;
+} MEM_REGS;
+
+typedef struct _PMEM_REGS {
+  UINT64  Base64;
+  UINT64  Limit64;
+} PMEM_REGS;
+
+typedef struct _IO_REGS {
+  UINT16  Base;
+  UINT16  Limit;
+} IO_REGS;
+
+typedef struct _BRDG_RES_CONFIG {
+  UINT8   Cmd;
+  UINT8   Cls;
+  UINT8   IoBase;
+  UINT8   IoLimit;
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+} BRDG_RES_CONFIG;
+
+typedef struct _BRDG_CONFIG {
+  DEV_ID          DevId;
+  UINT8           PBus;
+  UINT8           SBus;
+  UINT8           SubBus;
+  BOOLEAN         IsDSBridge;
+  BRDG_RES_CONFIG Res;
+} BRDG_CONFIG;
+
+enum {
+  HR_US_PORT,
+  HR_DS_PORT0,
+  HR_DS_PORT3,
+  HR_DS_PORT4,
+  HR_DS_PORT5,
+  HR_DS_PORT6,
+  MAX_CFG_PORTS
+};
+
+enum {
+  HR_DS_PORT1   = HR_DS_PORT3
+};
+
+//
+// Alpine Ridge
+//
+enum {
+  AR_DS_PORT1 = HR_DS_PORT3,
+  AR_DS_PORT2,
+  AR_DS_PORT3,
+  AR_DS_PORT4
+};
+
+typedef struct _HR_CONFIG {
+  UINT16  DeviceId;
+  UINT8   HRBus;
+  UINT8   MinDSNumber;
+  UINT8   MaxDSNumber;
+  UINT8   BridgeLoops;
+} HR_CONFIG;
+
+STATIC const BRDG_RES_CONFIG  NOT_IN_USE_BRIDGE = {
+  CMD_BUS_MASTER,
+  0,
+  DISBL_IO_REG1C & 0xFF,
+  DISBL_IO_REG1C >> 8,
+  DISBL_MEM32_REG20 & 0xFFFF,
+  DISBL_MEM32_REG20 >> 16,
+  DISBL_PMEM_REG24 & 0xFFFF,
+  DISBL_PMEM_REG24 >> 16
+};
+
+typedef union _BRDG_CIO_MAP_REG {
+  UINT32  AB_REG;
+  struct {
+    UINT32  NumOfDSPorts : 5;
+    UINT32  CioPortMap : 27;
+  } Bits;
+} BRDG_CIO_MAP_REG;
+
+//
+// Functions
+//
+VOID
+ThunderboltCallback (
+  IN UINT8 Type
+  );
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+  IN UINT8 Type
+  );
+
+VOID
+EndOfThunderboltCallback(
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+);
+
+VOID
+ConfigureTbtAspm(
+  IN UINT8       Type,
+  IN UINT16      Aspm
+);
+
+UINT8
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
new file mode 100644
index 0000000000..ac13acc27d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
@@ -0,0 +1,32 @@
+/** @file
+ Header file for board Init function for DXE Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_BOARD_INIT_LIB_H_
+#define _DXE_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+#include <Register/PchRegs.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Platform.h>
+
+EFI_STATUS
+EFIAPI
+BoardConfigInit (
+   VOID
+  );
+
+#endif // _DXE_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
new file mode 100644
index 0000000000..5d0e2777d8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_POLICY_INIT_DXE_H_
+#define _CPU_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+#include <Protocol/CpuPolicyProtocol.h>
+#include <Library/DxeCpuPolicyUpdateLib.h>
+
+
+/**
+  Initialize Intel CPU DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @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
+CpuPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
new file mode 100644
index 0000000000..ff975efae0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
@@ -0,0 +1,41 @@
+/** @file
+Header file for the GopPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GOP_POLICY_INIT_DXE_H_
+#define _GOP_POLICY_INIT_DXE_H_
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+#include <Library/PcdLib.h>
+
+/**
+Initialize GOP DXE Policy
+
+@param[in] ImageHandle          Image handle of this driver.
+
+@retval EFI_SUCCESS             Initialization complete.
+@retval 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
+GopPolicyInitDxe(
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
new file mode 100644
index 0000000000..1055fed7c8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
@@ -0,0 +1,52 @@
+/** @file
+  Header file for the PchPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_POLICY_INIT_DXE_H_
+#define _PCH_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <FirwmareConfigurations.h>
+#include <Protocol/PchPolicy.h>
+#include <Library/DxePchPolicyLib.h>
+#include <Library/DxePchPolicyUpdateLib.h>
+
+extern UINT8 mFirmwareConfiguration;
+
+/**
+  <b>PCH DXE Policy Driver Entry Point</b> \n
+  - <b>Introduction</b> \n
+    Pch DXE drivers behavior can be controlled by platform policy without modifying reference code directly.
+    Platform policy Protocol is initialized with default settings in this funciton.
+    This policy Protocol has to be initialized prior to PCH initialization DXE drivers execution.
+
+  - @pre
+    - Runtime variable service should be ready if policy initialization required.
+
+  - @result
+    PCH_POLICY_PROTOCOL will be installed successfully and ready for Pch reference code use.
+
+  - <b>Porting Recommendations</b> \n
+    Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+  @param[in] ImageHandle - Image handle of this driver.
+
+  @retval EFI_SUCCESS           Initialization complete.
+  @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
+PchPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
new file mode 100644
index 0000000000..d2aac9823e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
@@ -0,0 +1,45 @@
+/** @file
+  Header file for the PolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POLICY_INIT_DXE_H_
+#define _POLICY_INIT_DXE_H_
+
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include "SaPolicyInitDxe.h"
+#include "PchPolicyInitDxe.h"
+#include "SiliconPolicyInitDxe.h"
+#include "GopPolicyInitDxe.h"
+#include "CpuPolicyInitDxe.h"
+
+#include <Library/DxeTbtPolicyLib.h>
+/**
+  Initialize DXE Platform Policy
+
+  @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
+PolicyInitDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
new file mode 100644
index 0000000000..0f86711e6a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
@@ -0,0 +1,56 @@
+/** @file
+  Header file for the SaPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_POLICY_INIT_DXE_H_
+#define _SA_POLICY_INIT_DXE_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <FirwmareConfigurations.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/DxeSaPolicyLib.h>
+#include <Library/DxePolicyBoardConfigLib.h>
+#include <Library/DxeSaPolicyUpdateLib.h>
+
+#include <SaAccess.h>
+
+extern UINT8 mFirmwareConfiguration;
+
+/**
+  <b>SA DXE Policy Driver Entry Point</b> \n
+  - <b>Introduction</b> \n
+    System Agent DXE drivers behavior can be controlled by platform policy without modifying reference code directly.
+    Platform policy Protocol is initialized with default settings in this funciton.
+    This policy Protocol has to be initialized prior to System Agent initialization DXE drivers execution.
+
+  - @pre
+    - Runtime variable service should be ready if policy initialization required.
+
+  - @result
+    SA_POLICY_PROTOCOL will be installed successfully and ready for System Agent reference code use.
+
+  - <b>Porting Recommendations</b> \n
+    Policy should be initialized basing on platform design or user selection (like BIOS Setup Menu)
+
+  @param[in] ImageHandle - Image handle of this driver.
+
+  @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
+SaPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
new file mode 100644
index 0000000000..a2c5f548fa
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
@@ -0,0 +1,37 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SILICON_POLICY_INIT_DXE_H_
+#define _SILICON_POLICY_INIT_DXE_H_
+
+#include <Protocol/FirmwareVolume2.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+#include <Protocol/SiPolicyProtocol.h>
+
+/**
+  Initilize Intel CPU DXE Policy
+
+  @param[in] ImageHandle             Image handle of this driver.
+
+  @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
+SiliconPolicyInitDxe (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
new file mode 100644
index 0000000000..1ff129c307
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
@@ -0,0 +1,96 @@
+/** @file
+  Acpi Gnvs Init Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <PchAccess.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/MpService.h>
+
+/**
+@brief
+  Global NVS initialize.
+
+  @param[in] GlobalNvs         - Pointer of Global NVS area
+
+  @retval EFI_SUCCESS          - Allocate Global NVS completed.
+  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGnvsInit (
+  IN OUT VOID                   **GlobalNvs
+  )
+{
+  UINTN                         Pages;
+  EFI_PHYSICAL_ADDRESS          Address;
+  EFI_STATUS                    Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GNVS;
+  EFI_MP_SERVICES_PROTOCOL      *MpService;
+  UINTN                         NumberOfCPUs;
+  UINTN                         NumberOfEnabledCPUs;
+
+  Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
+  Address = 0xffffffff; // allocate address below 4G.
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Locate the MP services protocol
+  // Find the MP Protocol. This is an MP platform, so MP protocol must be there.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiMpServiceProtocolGuid,
+                  NULL,
+                  (VOID **) &MpService
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Determine the number of processors
+  //
+  MpService->GetNumberOfProcessors (
+              MpService,
+              &NumberOfCPUs,
+              &NumberOfEnabledCPUs
+              );
+
+  *GlobalNvs = (VOID *) (UINTN) Address;
+  SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
+
+  //
+  // GNVS default value init here...
+  //
+  GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
+
+  GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
+
+  //
+  // Miscellaneous
+  //
+  GNVS->Area->PL1LimitCS = 0;
+  GNVS->Area->PL1LimitCSValue = 4500;
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
new file mode 100644
index 0000000000..cb5f328a39
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
@@ -0,0 +1,290 @@
+/** @file
+  ACPI Platform Driver
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+
+#include <Protocol/GlobalNvsArea.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/AcpiTable.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL              mGlobalNvsArea;
+
+/**
+@brief
+  Global NVS initialize.
+
+  @param[in] GlobalNvs         - Pointer of Global NVS area
+
+  @retval EFI_SUCCESS          - Allocate Global NVS completed.
+  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGnvsInit (
+  IN OUT VOID                   **GlobalNvs
+  );
+
+//
+// Function implementations
+//
+
+/**
+  Locate the first instance of a protocol.  If the protocol requested is an
+  FV protocol, then it will return the first FV that contains the ACPI table
+  storage file.
+
+  @param[in] Protocol           The protocol to find.
+  @param[in] Instance           Return pointer to the first instance of the protocol.
+  @param[in] Type               TRUE if the desired protocol is a FV protocol.
+
+  @retval EFI_SUCCESS           The function completed successfully.
+  @retval EFI_NOT_FOUND         The protocol could not be located.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
+**/
+EFI_STATUS
+LocateSupportProtocol (
+  IN     EFI_GUID                      *Protocol,
+  IN     EFI_GUID                      *gEfiAcpiMultiTableStorageGuid,
+     OUT VOID                          **Instance,
+  IN     BOOLEAN                       Type
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *HandleBuffer;
+  UINTN                   NumberOfHandles;
+  EFI_FV_FILETYPE         FileType;
+  UINT32                  FvStatus;
+  EFI_FV_FILE_ATTRIBUTES  Attributes;
+  UINTN                   Size;
+  UINTN                   Index;
+
+  //
+  // Locate protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  Protocol,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // Defined errors at this time are not found and out of resources.
+    //
+    return Status;
+  }
+
+  //
+  // Looking 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],
+                    Protocol,
+                    Instance
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    if (!Type) {
+
+      //
+      // Not looking for the FV protocol, so find the first instance of the
+      // protocol.  There should not be any errors because our handle buffer
+      // should always contain at least one or LocateHandleBuffer would have
+      // returned not found.
+      //
+      break;
+    }
+    //
+    // See if it has the ACPI storage file
+    //
+    Size      = 0;
+    FvStatus  = 0;
+    Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile (
+                                                              *Instance,
+                                                              gEfiAcpiMultiTableStorageGuid,
+                                                              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);
+
+  return Status;
+}
+
+EFI_STATUS
+PublishAcpiTablesFromFv (
+  IN EFI_GUID *gEfiAcpiMultiTableStorageGuid
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;
+  UINT32                        FvStatus;
+  UINTN                         Size;
+  UINTN                         TableHandle;
+  INTN                          Instance;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+
+  Instance      = 0;
+  TableHandle   = 0;
+  CurrentTable  = NULL;
+  FwVol         = NULL;
+
+  //
+  // Find the AcpiSupport protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiAcpiTableProtocolGuid,
+            gEfiAcpiMultiTableStorageGuid,
+            (VOID **) &AcpiTable,
+            FALSE
+            );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Locate the firmware volume protocol
+  //
+  Status = LocateSupportProtocol (
+            &gEfiFirmwareVolume2ProtocolGuid,
+            gEfiAcpiMultiTableStorageGuid,
+            (VOID **) &FwVol,
+            TRUE
+            );
+
+  //
+  // Read tables from the storage file.
+  //
+
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      gEfiAcpiMultiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      //
+      // Add the table
+      //
+      TableHandle = 0;
+
+      Status = AcpiTable->InstallAcpiTable (
+                            AcpiTable,
+                            CurrentTable,
+                            CurrentTable->Length,
+                            &TableHandle
+                            );
+
+
+      ASSERT_EFI_ERROR (Status);
+
+      //
+      // Increment the instance
+      //
+      Instance++;
+      CurrentTable = NULL;
+    }
+  }
+
+  //
+  // Finished
+  //
+  return EFI_SUCCESS;
+}
+
+/**
+  ACPI Platform driver installation function.
+
+  @param[in] ImageHandle     Handle for this drivers loaded image protocol.
+  @param[in] SystemTable     EFI system table.
+
+  @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
+EFIAPI
+InstallAcpiBoard (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS   Status;
+  EFI_HANDLE   Handle;
+
+  AcpiGnvsInit((VOID **) &mGlobalNvsArea.Area);
+
+  //
+  // This PCD set must be done before PublishAcpiTablesFromFv.
+  // The PCD data will be used there.
+  //
+  PcdSet64S (PcdAcpiGnvsAddress, (UINT64)(UINTN)mGlobalNvsArea.Area);
+
+  //
+  // Platform ACPI Tables
+  //
+  PublishAcpiTablesFromFv (&gEfiCallerIdGuid);
+
+  //
+  // This protocol publish must be done after PublishAcpiTablesFromFv.
+  // The NVS data is be updated there.
+  //
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  &mGlobalNvsArea,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
new file mode 100644
index 0000000000..2b36475c53
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
@@ -0,0 +1,353 @@
+/** @file
+  Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
+  Devics resource configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include "PciHotPlug.h"
+#include <Ppi/SiPolicy.h>
+#include <TbtBoardInfo.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+
+#define PCIE_NUM  (20)
+#define PEG_NUM   (3)
+#define PADDING_BUS (1)
+#define PADDING_NONPREFETCH_MEM (1)
+#define PADDING_PREFETCH_MEM (1)
+#define PADDING_IO (1)
+#define PADDING_NUM (PADDING_BUS + PADDING_NONPREFETCH_MEM + PADDING_PREFETCH_MEM + PADDING_IO)
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HPC_LOCATION          mPcieLocation[PCIE_NUM + PEG_NUM];
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mHpcCount = 0;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCIE_HOT_PLUG_DEVICE_PATH mHotplugPcieDevicePathTemplate = {
+  ACPI,
+  PCI(0xFF, 0xFF), // Dummy Device no & Function no
+  END
+};
+
+/**
+  Entry point for the driver.
+
+  This routine reads the PlatformType GPI on FWH and produces a protocol
+  to be consumed by the chipset driver to effect those settings.
+
+  @param[in]  ImageHandle    An image handle.
+  @param[in]  SystemTable    A pointer to the system table.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+PciHotPlug (
+  IN EFI_HANDLE                   ImageHandle,
+  IN EFI_SYSTEM_TABLE             *SystemTable
+  )
+{
+  EFI_STATUS                       Status;
+  PCI_HOT_PLUG_INSTANCE            *PciHotPlug;
+  UINTN                            Index;
+  UINTN                            RpDev;
+  UINTN                            RpFunc;
+  PCIE_HOT_PLUG_DEVICE_PATH       *HotplugPcieDevicePath;
+  UINT32                           PcieRootPortHpeData = 0;
+
+  DEBUG ((DEBUG_INFO, "PciHotPlug Entry\n"));
+
+  PcieRootPortHpeData = PcdGet32 (PcdPchPcieRootPortHpe);
+  //
+  // PCH Rootports Hotplug device path creation
+  //
+  for (Index = 0; Index < PCIE_NUM; Index++) {
+    if (((PcieRootPortHpeData >> Index) & BIT0) == BIT0) { // Check the Rootport no's hotplug is set
+      Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFunc); // Get the actual device/function no corresponding to the Rootport no provided
+      ASSERT_EFI_ERROR (Status);
+
+      HotplugPcieDevicePath = NULL;
+      HotplugPcieDevicePath = AllocatePool (sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
+      ASSERT (HotplugPcieDevicePath != NULL);
+      if (HotplugPcieDevicePath == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      CopyMem (HotplugPcieDevicePath, &mHotplugPcieDevicePathTemplate, sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
+      HotplugPcieDevicePath->PciRootPortNode.Device = (UINT8) RpDev; // Update real Device no
+      HotplugPcieDevicePath->PciRootPortNode.Function = (UINT8) RpFunc; // Update real Function no
+
+      mPcieLocation[mHpcCount].HpcDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
+      mPcieLocation[mHpcCount].HpbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
+      mHpcCount++;
+
+      DEBUG ((DEBUG_INFO, "(%02d) PciHotPlug (PCH RP#) : Bus 0x00, Device 0x%x, Function 0x%x is added to the Hotplug Device Path list \n", mHpcCount, RpDev, RpFunc));
+    }
+  }
+
+
+  PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE));
+  ASSERT (PciHotPlug != NULL);
+  if (PciHotPlug == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize driver private data.
+  //
+  ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE));
+
+  PciHotPlug->Signature                               = PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE;
+  PciHotPlug->HotPlugInitProtocol.GetRootHpcList      = GetRootHpcList;
+  PciHotPlug->HotPlugInitProtocol.InitializeRootHpc   = InitializeRootHpc;
+  PciHotPlug->HotPlugInitProtocol.GetResourcePadding  = GetResourcePadding;
+
+  Status = gBS->InstallProtocolInterface (
+                  &PciHotPlug->Handle,
+                  &gEfiPciHotPlugInitProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &PciHotPlug->HotPlugInitProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure returns a list of Root Hot Plug controllers that require
+  initialization during boot process
+
+  @param[in]  This      The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[out] HpcCount  The number of Root HPCs returned.
+  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+  @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
+  OUT UINTN                            *HpcCount,
+  OUT EFI_HPC_LOCATION                 **HpcList
+  )
+{
+  *HpcCount = mHpcCount;
+  *HpcList  = mPcieLocation;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure Initializes one Root Hot Plug Controller
+  This process may casue initialization of its subordinate buses
+
+  @param[in]  This            The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+  @param[in]  HpcDevicePath   The Device Path to the HPC that is being initialized.
+  @param[in]  HpcPciAddress   The address of the Hot Plug Controller function on the PCI bus.
+  @param[in]  Event           The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+  @param[out] HpcState        The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+  @retval   EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL      *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL            *HpcDevicePath,
+  IN  UINT64                              HpcPciAddress,
+  IN  EFI_EVENT                           Event, OPTIONAL
+  OUT EFI_HPC_STATE                       *HpcState
+  )
+{
+  if (Event) {
+    gBS->SignalEvent (Event);
+  }
+
+  *HpcState = EFI_HPC_STATE_INITIALIZED;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+  @param[in]  This           The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
+  @param[in]  HpcPciAddress  The address of the Hot Plug Controller function on the PCI bus.
+  @param[out] HpcState       The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+  @param[out] Padding        This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+  @param[out] Attribute      Describes how padding is accounted for.
+
+  @retval     EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
+  IN  EFI_DEVICE_PATH_PROTOCOL        *HpcDevicePath,
+  IN  UINT64                          HpcPciAddress,
+  OUT EFI_HPC_STATE                   *HpcState,
+  OUT VOID                            **Padding,
+  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
+  EFI_STATUS                        Status;
+  UINT8                             RsvdExtraBusNum = 0;
+  UINT16                            RsvdPcieMegaMem = 10;
+  UINT8                             PcieMemAddrRngMax = 0;
+  UINT16                            RsvdPciePMegaMem = 10;
+  UINT8                             PciePMemAddrRngMax = 0;
+  UINT8                             RsvdTbtExtraBusNum = 0;
+  UINT16                            RsvdTbtPcieMegaMem = 10;
+  UINT8                             TbtPcieMemAddrRngMax = 0;
+  UINT16                            RsvdTbtPciePMegaMem = 10;
+  UINT8                             TbtPciePMemAddrRngMax = 0;
+  UINT8                             RsvdPcieKiloIo = 4;
+  BOOLEAN                           SetResourceforTbt = FALSE;
+  UINTN                             RpIndex;
+  UINTN                             RpDev;
+  UINTN                             RpFunc;
+
+DEBUG ((DEBUG_INFO, "GetResourcePadding : Start \n"));
+
+  PaddingResource = AllocatePool (PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  ASSERT (PaddingResource != NULL);
+  if (PaddingResource == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *Padding = (VOID *) PaddingResource;
+
+  RpDev = (UINTN) ((HpcPciAddress >> 16) & 0xFF);
+  RpFunc = (UINTN) ((HpcPciAddress >> 8) & 0xFF);
+
+  // Get the actual Rootport no corresponding to the device/function no provided
+  if (RpDev == SA_PEG_DEV_NUM) {
+    // PEG
+    RpIndex = PCIE_NUM + RpFunc;
+    DEBUG ((DEBUG_INFO, "GetResourcePadding : PEG Rootport no %02d Bus 0x00, Device 0x%x, Function 0x%x \n", (RpIndex-PCIE_NUM), RpDev, RpFunc));
+  } else {
+    // PCH
+    Status = GetPchPcieRpNumber (RpDev, RpFunc, &RpIndex);
+    DEBUG ((DEBUG_INFO, "GetResourcePadding : PCH Rootport no %02d Bus 0x00, Device 0x%x, Function 0x%x \n", RpIndex, RpDev, RpFunc));
+  }
+
+  GetRootporttoSetResourcesforTbt(RpIndex, &RsvdTbtExtraBusNum, &RsvdTbtPcieMegaMem ,&TbtPcieMemAddrRngMax ,&RsvdTbtPciePMegaMem ,&TbtPciePMemAddrRngMax, &SetResourceforTbt);
+    if (SetResourceforTbt) {
+      RsvdExtraBusNum = RsvdTbtExtraBusNum;
+      RsvdPcieMegaMem = RsvdTbtPcieMegaMem;
+      PcieMemAddrRngMax = TbtPcieMemAddrRngMax;
+      RsvdPciePMegaMem = RsvdTbtPciePMegaMem;
+      PciePMemAddrRngMax = TbtPciePMemAddrRngMax;
+    }
+
+  //
+  // Padding for bus
+  //
+  ZeroMem (PaddingResource, PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+  *Attributes                   = EfiPaddingPciBus;
+
+  PaddingResource->Desc         = 0x8A;
+  PaddingResource->Len          = 0x2B;
+  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_BUS;
+  PaddingResource->GenFlag      = 0x0;
+  PaddingResource->SpecificFlag = 0;
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrRangeMax = 0;
+  PaddingResource->AddrLen      = RsvdExtraBusNum;
+
+  //
+  // Padding for non-prefetchable memory
+  //
+  PaddingResource++;
+  PaddingResource->Desc                 = 0x8A;
+  PaddingResource->Len                  = 0x2B;
+  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+  PaddingResource->GenFlag              = 0x0;
+    if (SetResourceforTbt) {
+    PaddingResource->AddrSpaceGranularity = 32;
+  } else {
+    PaddingResource->AddrSpaceGranularity = 32;
+  }
+  PaddingResource->SpecificFlag         = 0;
+  //
+  // Pad non-prefetchable
+  //
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
+  if (SetResourceforTbt) {
+    PaddingResource->AddrRangeMax = (1 << PcieMemAddrRngMax) - 1;
+  } else {
+    PaddingResource->AddrRangeMax = 1;
+  }
+
+  //
+  // Padding for prefetchable memory
+  //
+  PaddingResource++;
+  PaddingResource->Desc                 = 0x8A;
+  PaddingResource->Len                  = 0x2B;
+  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+  PaddingResource->GenFlag              = 0x0;
+    if (SetResourceforTbt) {
+    PaddingResource->AddrSpaceGranularity = 32;
+  } else {
+    PaddingResource->AddrSpaceGranularity = 32;
+  }
+  PaddingResource->SpecificFlag         = 06;
+  //
+  // Padding for prefetchable memory
+  //
+  PaddingResource->AddrRangeMin = 0;
+  if (SetResourceforTbt) {
+    PaddingResource->AddrLen      = RsvdPciePMegaMem * 0x100000;
+  } else {
+    PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
+  }
+  //
+  // Pad 16 MB of MEM
+  //
+  if (SetResourceforTbt) {
+    PaddingResource->AddrRangeMax = (1 << PciePMemAddrRngMax) - 1;
+  } else {
+    PaddingResource->AddrRangeMax = 1;
+  }
+  //
+  // Alignment
+  //
+  // Padding for I/O
+  //
+  PaddingResource++;
+  PaddingResource->Desc         = 0x8A;
+  PaddingResource->Len          = 0x2B;
+  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_IO;
+  PaddingResource->GenFlag      = 0x0;
+  PaddingResource->SpecificFlag = 0;
+  PaddingResource->AddrRangeMin = 0;
+  PaddingResource->AddrLen      = RsvdPcieKiloIo * 0x400;
+  //
+  // Pad 4K of IO
+  //
+  PaddingResource->AddrRangeMax = 1;
+  //
+  // Alignment
+  //
+  // Terminate the entries.
+  //
+  PaddingResource++;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc     = ACPI_END_TAG_DESCRIPTOR;
+  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0;
+
+  *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
new file mode 100644
index 0000000000..c670f23320
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
@@ -0,0 +1,228 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/DxeTbtPolicyLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Protocol/TbtNvsArea.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/PcdLib.h>
+#include <Library/AslUpdateLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL                     mTbtNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB                              *gTbtInfoHob = NULL;
+
+/**
+  TBT NVS Area Initialize
+
+**/
+
+VOID
+TbtNvsAreaInit (
+  IN  VOID              **mTbtNvsAreaPtr
+  )
+{
+  UINTN                         Pages;
+  EFI_PHYSICAL_ADDRESS          Address;
+  EFI_STATUS                    Status;
+  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
+  DXE_TBT_POLICY_PROTOCOL       *DxeTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit Start\n"));
+  Status = gBS->LocateProtocol (
+              &gDxeTbtPolicyProtocolGuid,
+              NULL,
+              (VOID **) &DxeTbtConfig
+              );
+  ASSERT_EFI_ERROR (Status);
+
+  Pages = EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA));
+  Address = 0xffffffff; // allocate address below 4G.
+
+  Status  = gBS->AllocatePages (
+                   AllocateMaxAddress,
+                   EfiACPIMemoryNVS,
+                   Pages,
+                   &Address
+                   );
+  ASSERT_EFI_ERROR (Status);
+
+  *mTbtNvsAreaPtr = (VOID *) (UINTN) Address;
+  SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0);
+
+  //
+  // TBTNvsAreaProtocol default value init here
+  //
+  TbtNvsAreaProtocol = (TBT_NVS_AREA_PROTOCOL *) &Address;
+
+  //
+  // Initialize default values
+  //
+  TbtNvsAreaProtocol->Area->WAKFinished             = 0;
+  TbtNvsAreaProtocol->Area->DiscreteTbtSupport      = ((gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1 ) ? TRUE : FALSE);
+  TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport   = 0;
+  TbtNvsAreaProtocol->Area->TbtGpioFilter           = (UINT8) DxeTbtConfig->TbtCommonConfig.Gpio5Filter;
+//  TbtNvsAreaProtocol->Area->TrOsup                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TrA0OsupWa;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrEn             = gTbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr;
+  TbtNvsAreaProtocol->Area->TbtAspm                 = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAspm;
+//  TbtNvsAreaProtocol->Area->TbtL1SubStates          = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtL1SubStates;
+  TbtNvsAreaProtocol->Area->TbtSetClkReq            = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtSetClkReq;
+  TbtNvsAreaProtocol->Area->TbtLtr                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtLtr;
+//  TbtNvsAreaProtocol->Area->TbtPtm                  = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtPtm;
+  TbtNvsAreaProtocol->Area->TbtWakeupSupport        = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport;
+  TbtNvsAreaProtocol->Area->TbtAcDcSwitch           = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch;
+  TbtNvsAreaProtocol->Area->Rtd3TbtSupport          = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3Tbt;             // TBT RTD3 Enable.
+  TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay         = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay;    // TBT RTD3 Off delay in ms.
+  TbtNvsAreaProtocol->Area->Rtd3TbtClkReq           = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq;       // TBT RTD3 ClkReq Mask Enable.
+  TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay      = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq mask delay in ms.
+  TbtNvsAreaProtocol->Area->TbtWin10Support         = (UINT8) DxeTbtConfig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode
+
+  //
+  // DTBT Controller 1
+  //
+  TbtNvsAreaProtocol->Area->DTbtControllerEn0       = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+  TbtNvsAreaProtocol->Area->RootportSelected0       = gTbtInfoHob-> DTbtControllerConfig.PcieRpNumber;
+  TbtNvsAreaProtocol->Area->RootportSelected0Type   = gTbtInfoHob-> DTbtControllerConfig.Type;
+  TbtNvsAreaProtocol->Area->RootportEnabled0        = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0        = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0     = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+  TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0  = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0       = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+  TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0    = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+  TbtNvsAreaProtocol->Area->TBtCommonGpioSupport    = gTbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+
+  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit End\n"));
+}
+
+/**
+  This function gets registered as a callback to patch TBT ASL code
+
+  @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.
+  can we put this also in read me
+**/
+VOID
+EFIAPI
+TbtAcpiEndOfDxeCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Address;
+  UINT16                                Length;
+  UINT32                                Signature;
+
+  Status = InitializeAslUpdateLib ();
+  ASSERT_EFI_ERROR (Status);
+
+  Address = (UINT32) (UINTN) mTbtNvsAreaProtocol.Area;
+  Length  = (UINT16) sizeof (TBT_NVS_AREA);
+  DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x Length %x\n", Address, Length));
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address, sizeof (Address));
+  ASSERT_EFI_ERROR (Status);
+  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length, sizeof (Length));
+  ASSERT_EFI_ERROR (Status);
+
+  if (gTbtInfoHob != NULL) {
+    if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1) {
+      if (gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting == TRUE) {
+        DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n"));
+        Signature = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+        Status  = UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'), &Signature, sizeof (Signature));
+        ASSERT_EFI_ERROR (Status);
+      }
+    }
+  }
+
+  return;
+}
+
+/**
+  Initialize Thunderbolt(TM) SSDT ACPI tables
+
+  @retval EFI_SUCCESS    ACPI tables are initialized successfully
+  @retval EFI_NOT_FOUND  ACPI tables not found
+**/
+
+EFI_STATUS
+EFIAPI
+TbtDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              Handle;
+ // EFI_EVENT               EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "TbtDxeEntryPoint \n"));
+
+  //
+  // Get TBT INFO HOB
+  //
+  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+  if (gTbtInfoHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  InstallTbtPolicy (ImageHandle);
+  //
+  // Update DXE TBT Policy
+  //
+  UpdateTbtPolicyCallback ();
+
+  //
+  // Print DXE TBT Policy
+  //
+  TbtPrintDxePolicyConfig ();
+
+  //
+  // Initialize Tbt Nvs Area
+  //
+  TbtNvsAreaInit ((VOID **) &mTbtNvsAreaProtocol.Area);
+
+
+  //
+  // [ACPI] Thunderbolt ACPI table
+  //
+
+
+  Handle = NULL;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gTbtNvsAreaProtocolGuid,
+                  &mTbtNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register an end of DXE event for TBT ACPI to do some patch can be put as description
+  //
+  /**
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  TbtAcpiEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+**/
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
new file mode 100644
index 0000000000..bdd8de0cfd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
@@ -0,0 +1,211 @@
+/** @file
+  Source code file for TBT Init PEI module
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <TbtBoardInfo.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+/*
+/**
+  This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDone
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+
+/**
+  This function pass PEI TBT Policy to Hob at the end of PEI
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+
+EFI_STATUS
+EFIAPI
+PassTbtPolicyToHob (
+VOID
+  )
+{
+  EFI_STATUS            Status;
+  EFI_BOOT_MODE         BootMode;
+  TBT_INFO_HOB          *TbtInfoHob;
+  PEI_TBT_POLICY        *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "PassTbtPolicyToHob\n"));
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+  if (BootMode == BOOT_ON_S3_RESUME ) {
+    return EFI_SUCCESS;
+  }
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Create HOB for TBT Data
+  //
+  Status = PeiServicesCreateHob (
+             EFI_HOB_TYPE_GUID_EXTENSION,
+             sizeof (TBT_INFO_HOB),
+             (VOID **) &TbtInfoHob
+             );
+  DEBUG ((DEBUG_INFO, "TbtInfoHob Created \n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize the TBT INFO HOB data.
+  //
+  TbtInfoHob->EfiHobGuidType.Name = gTbtInfoHobGuid;
+
+  //
+  // Update DTBT Policy
+  //
+  TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn = PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn;
+  TbtInfoHob-> DTbtControllerConfig.Type = PeiTbtConfig-> DTbtControllerConfig.Type;
+  TbtInfoHob-> DTbtControllerConfig.PcieRpNumber = PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber;
+  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting;
+  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+  TbtInfoHob->DTbtCommonConfig.TbtBootOn = PeiTbtConfig->DTbtCommonConfig.TbtBootOn;
+  TbtInfoHob->DTbtCommonConfig.TbtUsbOn = PeiTbtConfig->DTbtCommonConfig.TbtUsbOn;
+  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr;
+  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly;
+  TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration = PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+  TbtInfoHob->DTbtCommonConfig.PcieRstSupport = PeiTbtConfig->DTbtCommonConfig.PcieRstSupport;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function handles TbtInit task at the end of PEI
+
+  @param[in]  PeiServices  Pointer to PEI Services Table.
+  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification event that
+                           caused this function to execute.
+  @param[in]  Ppi          Pointer to the PPI data associated with this function.
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     others
+**/
+
+EFI_STATUS
+EFIAPI
+TbtInitEndOfPei (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  BOOLEAN         DTbtExisted;
+  PEI_TBT_POLICY  *PeiTbtConfig;
+
+  DEBUG ((DEBUG_INFO, "TbtInitEndOfPei Entry\n"));
+
+  Status       = EFI_SUCCESS;
+  PeiTbtConfig = NULL;
+  DTbtExisted  = FALSE;
+
+  Status = PeiServicesLocatePpi (
+             &gPeiTbtPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &PeiTbtConfig
+             );
+  if (EFI_ERROR(Status)) {
+    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+    if (PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn == 1) {
+      DTbtExisted = TRUE;
+  }
+
+  if (DTbtExisted == TRUE) {
+    //
+    // Call Init function
+    //
+   Status = TbtInit ();
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  TBT Init PEI module entry point
+
+  @param[in]  FileHandle           Not used.
+  @param[in]  PeiServices          General purpose services available to every PEIM.
+
+  @retval     EFI_SUCCESS          The function completes successfully
+  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+EFIAPI
+TbtInitEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS     Status;
+
+  DEBUG ((DEBUG_INFO, "TBT PEI EntryPoint\n"));
+
+  //
+  // Install PEI TBT Policy
+  //
+  Status = InstallPeiTbtPolicy ();
+  ASSERT_EFI_ERROR (Status);
+
+
+  UpdatePeiTbtPolicy ();
+
+  TbtPrintPeiPolicyConfig ();
+  //
+  // Performing PassTbtPolicyToHob and TbtInitEndOfPei
+  //
+  Status = PassTbtPolicyToHob ();
+
+  Status = TbtInitEndOfPei ();
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
new file mode 100644
index 0000000000..a6bdc6ef9f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
@@ -0,0 +1,1609 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "TbtSmiHandler.h"
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SmmVariable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/PciSegmentLib.h>
+#define MEM_PER_SLOT  (DEF_RES_MEM_PER_DEV << 4)
+#define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
+#define IO_PER_SLOT   (DEF_RES_IO_PER_DEV << 2)
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN                 gDeviceBaseAddress;
+//
+//US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG           HrConfigs[MAX_CFG_PORTS];
+
+extern UINT8                      gCurrentDiscreteTbtRootPort;
+extern UINT8                      gCurrentDiscreteTbtRootPortType;
+
+BOOLEAN isLegacyDevice          = FALSE;
+STATIC UINT8 TbtSegment         = 0;
+
+STATIC
+VOID
+PortInfoInit (
+  IN  OUT PORT_INFO *PortInfo
+  )
+{
+  PortInfo->BusNumLimit = 4;
+}
+
+STATIC
+VOID
+UnsetVesc (
+  IN       UINT8     Bus,
+  IN       UINT8     Dev,
+  IN       UINT8     Fun
+  )
+{
+  UINT8 Dbus;
+  UINT32 Data32;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+
+  //
+  // Check for abcence of DS bridge
+  //
+  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+    return;
+  }
+
+  //
+  // Unset vesc_reg2[23] bit (to have an option to access below DS)
+  //
+  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+  Data32 &= 0xFF7FFFFF;
+  PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+  //
+  // Go to Device behind DS
+  //
+  Dbus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
+  //
+  // Check if there is something behind this Downstream Port (Up or Ep)
+  // If there nothing  behind Downstream Port Set vesc_reg2[23] bit -> this will flush all future MemWr
+  //
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus, 0x00, 0x00, 0);
+  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET))
+  {
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+  Data32 |= 0x00800000;
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+  }
+}// Unset_VESC_REG2
+
+STATIC
+UINT16
+MemPerSlot (
+  IN    UINT16 CurrentUsage
+  )
+{
+  if (CurrentUsage == 0) {
+    return 0;
+  }
+
+  if (CurrentUsage <= 16) {
+    return 16;
+  }
+
+  if (CurrentUsage <= 64) {
+    return 64;
+  }
+
+  if (CurrentUsage <= 128) {
+    return 128;
+  }
+
+  if (CurrentUsage <= 256) {
+    return 256;
+  }
+
+  if (CurrentUsage <= 512) {
+    return 512;
+  }
+
+  if (CurrentUsage <= 1024) {
+    return 1024;
+  }
+
+  return CurrentUsage;
+} // MemPerSlot
+
+STATIC
+UINT64
+PMemPerSlot (
+  IN    UINT64 CurrentUsage
+  )
+{
+  if (CurrentUsage == 0) {
+    return 0;
+  }
+
+  if (CurrentUsage <= 1024ULL) {
+    return 1024ULL;
+  }
+
+  if (CurrentUsage <= 4096ULL) {
+    return 4096ULL;
+  }
+
+  return CurrentUsage;
+} // PMemPerSlot
+
+STATIC
+VOID
+SetPhyPortResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      SubBus,
+  IN       INT8       Depth,
+  IN       PORT_INFO  *CurrentPi,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8   Cmd;
+  UINT16  DeltaMem;
+  UINT64  DeltaPMem;
+
+  Cmd               = CMD_BUS_MASTER;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0x00, 0);
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+  DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
+  if (isLegacyDevice) {
+    if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
+      PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
+    }
+  } else {
+    if (DeltaMem < MemPerSlot (DeltaMem)) {
+      PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
+    }
+  }
+
+  if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase - 0x10) <= PortInfo->MemLimit) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), CurrentPi->MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+    PortInfo->MemBase = CurrentPi->MemBase;
+  }
+
+  DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
+  if (isLegacyDevice) {
+    if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
+      PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
+    }
+  } else {
+    if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
+      PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
+    }
+  }
+
+  if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 && (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10) & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10) >> 16));
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+    PortInfo->PMemBase64 = CurrentPi->PMemBase64;
+  }
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetPhyPortResources
+
+STATIC
+UINT32
+SaveSetGetRestoreBar (
+  IN  UINTN  Bar
+  )
+{
+  UINT32  BarReq;
+  UINT32  OrigBar;
+
+  OrigBar = PciSegmentRead32(Bar);     // Save BAR
+  PciSegmentWrite32(Bar, 0xFFFFFFFF);  // Set BAR
+  BarReq = PciSegmentRead32(Bar);      // Get BAR
+  PciSegmentWrite32(Bar, OrigBar);     // Restore BAR
+
+  return BarReq;
+} // SaveSetGetRestoreBar
+
+STATIC
+VOID
+SetIoBar (
+  IN            UINTN    BAR,
+  IN            UINT32   BarReq,
+  IN  OUT       UINT8    *Cmd,
+  IN  OUT       IO_REGS  *IoReg
+  )
+{
+  UINT16  Alignment;
+  UINT16  Size;
+  UINT16  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFC);
+  Size      = Alignment + 1;
+
+  if (IoReg->Base > IoReg->Limit || !Size) {
+    return ;
+
+  }
+
+  NewBase = BAR_ALIGN (IoReg->Base, Alignment);
+  if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
+    return ;
+
+  }
+  PciSegmentWrite16(BAR, NewBase);
+  IoReg->Base = NewBase + Size; // Advance to new position
+  *Cmd      |= CMD_BM_IO; // Set Io Space Enable
+} // SetIoBar
+
+STATIC
+VOID
+SetMemBar (
+  IN            UINTN     BAR,
+  IN            UINT32    BarReq,
+  IN  OUT       UINT8     *Cmd,
+  IN  OUT       MEM_REGS  *MemReg
+  )
+{
+  UINT32  Alignment;
+  UINT32  Size;
+  UINT32  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFFFFF0);
+  Size      = Alignment + 1;
+
+  if (MemReg->Base > MemReg->Limit || !Size) {
+    return ;
+
+  }
+
+  NewBase = BAR_ALIGN (MemReg->Base, Alignment);
+  if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
+    return ;
+
+  }
+
+  PciSegmentWrite32(BAR, NewBase);
+  MemReg->Base = NewBase + Size; // Advance to new position
+  *Cmd       |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetMemBar
+
+STATIC
+VOID
+SetPMem64Bar (
+  IN              UINTN      BAR,
+  IN              BOOLEAN    IsMaxBar,
+  IN              UINT32     BarReq,
+  IN    OUT       UINT8      *Cmd,
+  IN    OUT       PMEM_REGS  *MemReg
+  )
+{
+  UINT32  Alignment;
+  UINT32  Size;
+  UINT64  NewBase;
+
+  Alignment = ~(BarReq & 0xFFFFFFF0);
+  Size      = Alignment + 1;
+
+  if (MemReg->Base64 > MemReg->Limit64 || !Size) {
+    return ;
+  }
+
+  NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
+  if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64) {
+    return ;
+  }
+  PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
+  if (!IsMaxBar) {
+    BAR++;
+    PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
+  }
+  MemReg->Base64 = NewBase + Size; // Advance to new position
+  *Cmd         |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetPMem64Bar
+
+STATIC
+VOID
+SetDevResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      MaxFun,  // PCI_MAX_FUNC for devices, 1 for bridge
+  IN       UINT8      MaxBar,     // PCI_BAR5 for devices, PCI_BAR1 for bridge
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8     Fun;
+  UINT8     Reg;
+  UINT32    BarReq;
+  IO_REGS   Io;
+  MEM_REGS  Mem;
+  PMEM_REGS PMem;
+  UINT8     Cmd;
+
+  Io.Base       = PortInfo->IoBase << 8;
+  Io.Limit      = (PortInfo->IoLimit << 8) | 0xFF;
+  Mem.Base      = PortInfo->MemBase << 16;
+  Mem.Limit     = (PortInfo->MemLimit << 16) | 0xFFFF;
+  PMem.Base64   = PortInfo->PMemBase64 << 16;
+  PMem.Limit64  = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
+
+  for (Fun = 0; Fun < MaxFun; ++Fun) {
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+    Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+
+    }
+
+    for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
+      BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform BAR sizing
+
+      if (BarReq & BIT0) {
+        //
+        // I/O BAR
+        //
+        SetIoBar (
+         (gDeviceBaseAddress + Reg),
+          BarReq,
+          &Cmd,
+          &Io
+          );
+        continue;
+      }
+
+      if (BarReq & BIT3) {
+        //
+        // P-Memory BAR
+        //
+        SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq, &Cmd, &PMem);
+      } else {
+        SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
+      }
+
+      if (BIT2 == (BarReq & (BIT2 | BIT1))) {
+        //
+        // Base address is 64 bits wide
+        //
+        Reg += 4;
+        if (!(BarReq & BIT3)) {
+          //
+          // 64-bit memory bar
+          //
+          PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
+        }
+      }
+    }
+
+    if (Cmd & BIT1) {
+      //
+      // If device uses I/O and MEM mapping use only MEM mepping
+      //
+      Cmd &= ~BIT0;
+    }
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+  }
+  //
+  // Update PortInfo if any changes
+  //
+  if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
+    PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
+  }
+
+  if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
+    PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
+  }
+
+  if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
+    PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
+  }
+} // SetDevResources
+
+STATIC
+VOID
+InitARHRConfigs(
+  IN HR_CONFIG *Hr_Config,
+  IN UINT8 BusNumLimit,
+  IN OUT BRDG_RES_CONFIG* HrResConf
+)
+{
+  UINT8 i,j;
+
+  //
+  // DS port for USB device
+  //
+  HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
+  HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
+  HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
+  HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+  HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+  //
+  // CIO port
+  //
+  HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
+  HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
+  HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
+  HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
+  HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
+
+  switch(Hr_Config->DeviceId)
+  {
+    //
+    // HR with 1 DS and 1 USB
+    //
+    case AR_HR_2C:
+    case AR_HR_LP:
+    case AR_HR_C0_2C:
+    case TR_HR_2C:
+      Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
+      Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
+      Hr_Config->BridgeLoops = 4;
+      break;
+    //
+    // HR with 2 DS and 1 USB
+    //
+    case AR_HR_4C:
+    case TR_HR_4C:
+    case AR_HR_C0_4C:
+      Hr_Config->MinDSNumber = 1;
+      Hr_Config->MaxDSNumber = 4;
+      Hr_Config->BridgeLoops = 6;
+      for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i)
+      {
+        HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+        HrConfigs[j].DevId.Dev = i;
+        HrConfigs[j].DevId.Fun = 0;
+        HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
+        HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
+      }
+    break;
+  }
+}//InitARHRConfigs
+
+
+STATIC
+VOID
+InitCommonHRConfigs (
+  IN       HR_CONFIG        *Hr_Config,
+  IN       UINT8            BusNumLimit,
+  IN  OUT  BRDG_RES_CONFIG  *HrResConf
+  )
+{
+  UINT8 i;
+
+  UINT8 j;
+  for(i = 0; i < count(HrConfigs); ++i) {
+    HrConfigs[i].IsDSBridge = TRUE;
+  }
+  //
+  // US(HRBus:0:0)
+  //
+  HrConfigs[HR_US_PORT].DevId.Bus   = Hr_Config->HRBus;
+  HrConfigs[HR_US_PORT].DevId.Dev   = 0;
+  HrConfigs[HR_US_PORT].DevId.Fun   = 0;
+  HrConfigs[HR_US_PORT].Res         = *HrResConf;
+  HrConfigs[HR_US_PORT].Res.IoBase  = 0xF1;
+  HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
+  HrConfigs[HR_US_PORT].PBus        = HrConfigs[HR_US_PORT].DevId.Bus;
+  HrConfigs[HR_US_PORT].SBus        = HrConfigs[HR_US_PORT].PBus + 1;
+  HrConfigs[HR_US_PORT].SubBus      = BusNumLimit;
+  HrConfigs[HR_US_PORT].IsDSBridge  = FALSE;
+
+  //
+  // HIA resides here
+  //
+  HrConfigs[HR_DS_PORT0].DevId.Bus    = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+  HrConfigs[HR_DS_PORT0].DevId.Dev    = 0;
+  HrConfigs[HR_DS_PORT0].DevId.Fun    = 0;
+  HrConfigs[HR_DS_PORT0].Res          = NOT_IN_USE_BRIDGE;
+  HrConfigs[HR_DS_PORT0].Res.MemBase  = HrResConf->MemLimit;
+  HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
+  HrResConf->MemLimit                -= 0x10; //This 1 MB chunk will be used by HIA
+  HrConfigs[HR_DS_PORT0].Res.Cmd      = CMD_BM_MEM;
+  HrConfigs[HR_DS_PORT0].Res.Cls      = DEF_CACHE_LINE_SIZE;
+  HrConfigs[HR_DS_PORT0].PBus         = HrConfigs[HR_DS_PORT0].DevId.Bus;
+  HrConfigs[HR_DS_PORT0].SBus         = HrConfigs[HR_DS_PORT0].PBus + 1;
+  HrConfigs[HR_DS_PORT0].SubBus       = HrConfigs[HR_DS_PORT0].PBus + 1;
+
+  switch (Hr_Config->DeviceId) {
+  //
+  // Alpine Ridge
+  //
+  case AR_HR_2C:
+  case AR_HR_C0_2C:
+  case AR_HR_LP:
+  case AR_HR_4C:
+  case AR_HR_C0_4C:
+  //
+  // Titan Ridge
+  //
+  case TR_HR_2C:
+  case TR_HR_4C:
+    InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
+    break;
+
+  default:
+    //
+    // DS(HRBus+2:3-6:0)
+    //
+    Hr_Config->MinDSNumber  = 3;
+    Hr_Config->MaxDSNumber  = 6;
+    Hr_Config->BridgeLoops  = count (HrConfigs);
+
+    for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i) {
+      HrConfigs[j].DevId.Bus  = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+      HrConfigs[j].DevId.Dev  = i;
+      HrConfigs[j].DevId.Fun  = 0;
+      HrConfigs[j].PBus       = HrConfigs[j].DevId.Bus;
+      HrConfigs[j].Res.Cls    = DEF_CACHE_LINE_SIZE;
+    }
+  }
+} // InitCommonHRConfigs
+
+STATIC
+VOID
+InitHRDSPort_Disable (
+  IN       UINT8        id,
+  IN  OUT  BRDG_CONFIG  *BrdgConf
+  )
+{
+  HrConfigs[id].Res     = NOT_IN_USE_BRIDGE;
+  HrConfigs[id].SBus    = BrdgConf->SBus;
+  HrConfigs[id].SubBus  = BrdgConf->SBus;
+
+  BrdgConf->SBus++;
+} // InitHRDSPort_Disable
+
+//AR only
+
+STATIC
+VOID
+InitARDSPort_1Port(
+  IN  OUT  BRDG_CONFIG* BrdgConf
+)
+{
+  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
+  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
+
+  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+  HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
+  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+}//InitARDSPort_1Port
+
+STATIC
+VOID
+InitARDSPort_2Port(
+  IN OUT BRDG_CONFIG* BrdgConf
+)
+{
+  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
+  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
+
+  // Busses are split between ports 1 and 4
+  BusRange /= 2;
+
+  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+  HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
+  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
+  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
+  HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
+  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+
+
+  HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
+  HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
+  HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
+  HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
+  HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
+  HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
+  HrConfigs[AR_DS_PORT4].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+  HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
+  HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
+
+  BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
+}//InitARDSPort_2Port
+
+
+STATIC
+BOOLEAN
+CheckLimits (
+  IN    BOOLEAN          Is2PortDev,
+  IN    BRDG_RES_CONFIG  *HrResConf,
+  IN    UINT8            BusRange
+  )
+{
+  UINT16  MemBase;
+  UINT16  MemLimit;
+  UINT64  PMemBase64;
+  UINT64  PMemLimit64;
+
+  MemBase     = HrResConf->MemBase & 0xFFF0;
+  MemLimit    = HrResConf->MemLimit & 0xFFF0;
+  PMemBase64  = HrResConf->PMemBase64 & 0xFFF0;
+  PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
+  //
+  // Check memoty alignment
+  //
+  if (MemBase & 0x3FF) {
+    DEBUG((DEBUG_INFO, "M alig\n"));
+    return FALSE;
+  }
+
+  if (PMemBase64 & 0xFFF) {
+    DEBUG((DEBUG_INFO, "PM alig\n"));
+    return FALSE;
+  }
+
+  if (Is2PortDev) {
+    //
+    // Check mem size
+    //
+    if (MemLimit + 0x10 - MemBase < 0x2E00) {
+      DEBUG((DEBUG_INFO, "M size\n"));
+      return FALSE;
+    }
+    //
+    // Check P-mem size
+    //
+    if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
+      DEBUG((DEBUG_INFO, "PM size\n"));
+      return FALSE;
+    }
+    //
+    // Check bus range
+    //
+    if (BusRange < 106) {
+      DEBUG((DEBUG_INFO, "Bus range\n"));
+      return FALSE;
+    }
+  } else {
+    //
+    // Check mem size
+    //
+    if (MemLimit + 0x10 - MemBase < 0x1600) {
+      DEBUG((DEBUG_INFO, "M size\n"));
+      return FALSE;
+    }
+    //
+    // Check P-mem size
+    //
+    if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
+      DEBUG((DEBUG_INFO, "PM size\n"));
+      return FALSE;
+    }
+    //
+    // Check bus range
+    //
+    if (BusRange < 56) {
+      DEBUG((DEBUG_INFO, "Bus range\n"));
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+} // CheckLimits
+
+STATIC
+BOOLEAN
+InitHRResConfigs (
+  IN  OUT HR_CONFIG      *Hr_Config,
+  IN    UINT8            BusNumLimit,
+  IN  OUT BRDG_RES_CONFIG*HrResConf
+  )
+{
+  BRDG_CONFIG  BrdgConf = { { 0 } };
+
+  InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
+  BrdgConf.PBus   = Hr_Config->HRBus + 2;// Take into account busses
+  BrdgConf.SBus   = Hr_Config->HRBus + 3;// for US and DS of HIA
+  BrdgConf.SubBus = BusNumLimit;
+  BrdgConf.Res    = *HrResConf;
+  while (TRUE) {
+    switch (Hr_Config->DeviceId) {
+    case AR_HR_4C:
+    case TR_HR_4C:
+    case AR_HR_C0_4C:
+      //
+      // 2 Port host
+      //
+      if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
+
+
+          InitARDSPort_2Port(&BrdgConf);
+          DEBUG((DEBUG_INFO, "AR2\n"));
+
+        return TRUE;
+      } else {
+       return FALSE;
+      }
+    // AR only
+  case AR_HR_2C: // 1 port host
+  case AR_HR_C0_2C:
+  case AR_HR_LP:
+  case TR_HR_2C:
+    DEBUG((DEBUG_INFO, "AR1\n"));
+    InitARDSPort_1Port(&BrdgConf);
+    return TRUE;
+
+    default:
+      InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
+      InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
+      return FALSE;
+    }
+  }
+} // InitHRResConfigs
+
+STATIC
+BOOLEAN
+InitializeHostRouter (
+  OUT  HR_CONFIG  *Hr_Config,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8           BusNumLimit;
+  BRDG_RES_CONFIG HrResConf = { 0 };
+  UINT8           i;
+  BOOLEAN         Ret;
+
+  Ret = TRUE;
+
+  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  Hr_Config->HRBus    = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, Hr_Config->HRBus, 0x00, 0x00, 0);
+  Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
+    return FALSE;
+  }
+  TbtSegment = (UINT8)RpSegment;
+
+  HrResConf.Cmd          = CMD_BM_MEM;
+  HrResConf.Cls          = DEF_CACHE_LINE_SIZE;
+  gDeviceBaseAddress      = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  HrResConf.IoBase       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+  HrResConf.IoLimit      = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+  HrResConf.MemBase      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+  HrResConf.MemLimit     = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+  HrResConf.PMemBase64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
+  HrResConf.PMemLimit64  = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
+  HrResConf.PMemBase64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+  HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+  BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+
+  Ret         = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
+
+  for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+    UINT8 Bus;
+    UINT8 Dev;
+    UINT8 Fun;
+    Bus               = HrConfigs[i].DevId.Bus;
+    Dev               = HrConfigs[i].DevId.Dev;
+    Fun               = HrConfigs[i].DevId.Fun;
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, HrConfigs[i].Res.Cls);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64 >> 16));
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), HrConfigs[i].Res.IoBase);
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, HrConfigs[i].Res.Cmd);
+  }
+  if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C || Hr_Config->DeviceId == AR_HR_LP) {
+    for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+      if(HrConfigs[i].IsDSBridge) {
+        UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev, HrConfigs[i].DevId.Fun);
+      }
+    }
+  }
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
+  PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+  return Ret;
+} // InitializeHostRouter
+STATIC
+UINT8
+ConfigureSlot (
+  IN       UINT8      Bus,
+  IN       UINT8      MAX_DEVICE,
+  IN       INT8       Depth,
+  IN       BOOLEAN    ArPcie,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8      Device;
+  UINT8      SBus;
+  UINT8      UsedBusNumbers;
+  UINT8      RetBusNum;
+  PORT_INFO  CurrentSlot;
+
+  RetBusNum = 0;
+
+  for (Device = 0; Device < MAX_DEVICE; Device++) {
+    //
+    // Continue if device is absent
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, 0x00, 0);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+
+    }
+
+    if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+      SetDevResources (
+        Bus,
+        Device,
+        PCI_MAX_FUNC,
+        PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
+        PortInfo
+        );
+      continue;
+    }
+    //
+    // Else Bridge
+    //
+    CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
+
+    ++RetBusNum; // UP Bridge
+    SBus = Bus + RetBusNum; // DS Bridge
+
+    if (SBus + 1 >= PortInfo->BusNumLimit) {
+      continue;
+
+    }
+
+    SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), PortInfo);
+
+    //
+    // Init UP Bridge to reach DS Bridge
+    //
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+
+  if(ArPcie) {
+    UnsetVesc(Bus, Device, 0x00);
+  }
+
+  UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+  RetBusNum += UsedBusNumbers;
+
+    SetPhyPortResources (
+      Bus,
+      Device,
+      SBus + UsedBusNumbers,
+      Depth,
+      &CurrentSlot,
+      PortInfo
+      );
+  }
+  //
+  // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
+  //
+  return RetBusNum;
+} // ConfigureSlot
+
+STATIC
+VOID
+SetCioPortResources (
+  IN       UINT8     Bus,
+  IN       UINT8     Dev,
+  IN       UINT8     SBus,
+  IN       UINT8     SubBus,
+  IN       PORT_INFO  *portInfoBeforeChange,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8 Cmd;
+  Cmd               = CMD_BUS_MASTER;
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, 0x00, 0);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+  if (PortInfo->IoBase <= PortInfo->IoLimit) {
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), PortInfo->IoBase);
+    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), PortInfo->IoLimit);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+    Cmd |= CMD_BM_IO;
+  } else {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+  }
+
+  if (PortInfo->MemBase <= PortInfo->MemLimit) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), PortInfo->MemBase);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemLimit);
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+  }
+
+  if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 & 0xFFFF));
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 & 0xFFFF));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
+    Cmd |= CMD_BM_MEM;
+  } else {
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+  }
+
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetCioPortResources
+
+STATIC
+VOID
+SetSlotsAsUnused (
+  IN       UINT8      Bus,
+  IN       UINT8      MaxSlotNum,
+  IN       UINT8      CioSlot,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  UINT8 Slot;
+  for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot, 0x00, 0);
+    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+      continue;
+    }
+
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+    PortInfo->BusNumLimit--;
+  }
+} // SetSlotsAsUnused
+
+STATIC
+UINT16
+FindVendorSpecificHeader(
+  IN  UINT8  Bus
+)
+{
+  PCI_EXP_EXT_HDR   *ExtHdr;
+  UINT32            ExtHdrValue;
+  UINT16            ExtendedRegister;
+
+  ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
+  ExtendedRegister  = 0x100;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  while (ExtendedRegister) {
+    ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress + ExtendedRegister);
+    if (ExtHdr->CapabilityId == 0xFFFF) {
+      return 0x0000; // No Vendor-Specific Extended Capability header
+    }
+
+    if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID == ExtHdr->CapabilityId) {
+      return ExtendedRegister;
+    }
+
+    ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
+  }
+  return 0x0000; // No Vendor-Specific Extended Capability header
+}
+
+STATIC
+UINT8
+FindSsid_SsvidHeader (
+  IN    UINT8  Bus
+  )
+{
+  UINT8 CapHeaderId;
+  UINT8 CapHeaderOffset;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  CapHeaderOffset   = PciSegmentRead8 (gDeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+
+  while (CapHeaderOffset != 0) {
+    CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset);
+
+    if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
+      return CapHeaderOffset;
+    }
+
+    CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset + 1);
+  }
+
+  DEBUG((DEBUG_INFO, "SID0\n"));
+  return 0;
+} // FindSsid_SsvidHeader
+
+STATIC
+BOOLEAN
+GetCioSlotByDevId (
+  IN   UINT8  Bus,
+  OUT  UINT8  *CioSlot,
+  OUT  UINT8  *MaxSlotNum,
+  OUT  BOOLEAN *ArPcie
+  )
+{
+  UINT16            VSECRegister;
+  BRDG_CIO_MAP_REG  BridgMap;
+  UINT32            BitScanRes;
+  UINT16            DevId;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00, 0x00, 0);
+  DevId             = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+
+  //
+  // Init out params in case device is not recognised
+  //
+  *CioSlot    = 4;
+  *MaxSlotNum = 7;
+  *ArPcie     = FALSE;
+
+  switch (DevId) {
+    //
+    // For known device IDs
+    //
+    case 0x1578:
+      *ArPcie = TRUE;
+  }
+
+  switch (DevId) {
+  //
+  // For known device IDs
+  //
+  case 0x1513:
+  case 0x151A:
+  case 0x151B:
+  case 0x1547:
+  case 0x1548:
+    return TRUE; // Just return
+  case 0x1549:
+    return FALSE; // Just return
+  }
+
+  VSECRegister = FindVendorSpecificHeader(Bus);
+  if (!VSECRegister) {
+    return TRUE; // Just return
+  }
+  //
+  // Go to Bridge/CIO map register
+  //
+  VSECRegister += 0x18;
+  BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress + VSECRegister);
+  //
+  // Check for range
+  //
+  if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
+    return TRUE;
+  //
+  // Not a valid register
+  //
+  }
+  //
+  // Set OUT params
+  //
+  *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
+
+#ifdef _MSC_VER
+  if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS bridge which is CIO port
+    return FALSE;
+  }
+#else
+#ifdef __GNUC__
+  if (BridgMap.Bits.CioPortMap == 0) {
+    return FALSE;
+  }
+  BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
+#else
+#error Unsupported Compiler
+#endif
+#endif
+
+  *CioSlot = (UINT8)BitScanRes;
+  return TRUE;
+} // GetCioSlotByDevId
+
+#define TBT_LEGACY_SUB_SYS_ID 0x11112222
+
+STATIC
+BOOLEAN
+IsLegacyDevice (
+  IN    UINT8  Bus
+  )
+{
+  UINT32  Sid;
+  UINT8   SidRegister;
+  UINT16  DevId;
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+  DevId             = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  switch (DevId) {
+  //
+  // For known device IDs
+  //
+  case 0x1513:
+  case 0x151A:
+  case 0x151B:
+    DEBUG((DEBUG_INFO, "Legacy "));
+    DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
+    return TRUE;
+    //
+    // Legacy device by Device Id
+    //
+  }
+
+  SidRegister = FindSsid_SsvidHeader(Bus);
+
+  if (!SidRegister) {
+    return TRUE; // May be absent for legacy devices
+  }
+  //
+  // Go to register
+  //
+  SidRegister += 0x4;
+  Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
+  DEBUG((DEBUG_INFO, "SID"));
+  DEBUG((DEBUG_INFO, " = %d\n", Sid));
+
+return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
+} // IsLegacyDevice
+
+STATIC
+VOID
+UnsetVescEp(
+  IN  UINT8     Bus,
+  IN  UINT8     MaxSlotNum
+  )
+{
+  UINT8 i;
+
+  for (i = 0; i <= MaxSlotNum; ++i)
+  {
+    UnsetVesc(Bus, i, 0);
+  }
+}// Unset_VESC_REG2_EP
+
+STATIC
+BOOLEAN
+ConfigureEP (
+  IN       INT8      Depth,
+  IN  OUT  UINT8     *Bus,
+  IN  OUT  PORT_INFO *PortInfo
+  )
+{
+  UINT8      SBus;
+  UINT8      CioSlot;
+  UINT8      MaxSlotNum;
+  BOOLEAN    ArPcie;
+  UINT8      MaxPHYSlots;
+  UINT8      UsedBusNumbers;
+  UINT8      cmd;
+  BOOLEAN    CioSlotPresent;
+  BOOLEAN    Continue;
+  PORT_INFO  PortInfoOrg;
+  UINT8      CioBus;
+
+  CioSlot     = 4;
+  MaxSlotNum  = 7;
+  CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
+
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus, 0x00, 0x00, 0);
+  cmd               = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+  // AR ONLY
+  // Endpoint on CIO slot, but not a bridge device
+  if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+    DEBUG((DEBUG_INFO, "UEP\n"));
+    // Check whether EP already configured by examining CMD register
+    if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
+    {
+      DEBUG((DEBUG_INFO, "BMF\n"));
+      return FALSE;
+    }
+    // Configure it as regular PCIe device
+    ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+
+    return FALSE;
+  }
+
+  //
+  // Based on Device ID assign Cio slot and max number of PHY slots to scan
+  //
+  CioSlotPresent  =  GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum, &ArPcie);
+  MaxPHYSlots     = MaxSlotNum;
+  //
+  // Check whether EP already configured by examining CMD register
+  //
+
+  if (cmd & CMD_BUS_MASTER) {
+    //
+    // Yes no need to touch this EP, just move to next one in chain
+    //
+    CioBus = *Bus + 1;
+    if(ArPcie){
+      UnsetVescEp(CioBus, MaxSlotNum);
+    }
+    if (!CioSlotPresent) {
+      //
+      // Cio slot is not present in EP, just return FALSE
+      //
+      DEBUG((DEBUG_INFO, "BMF\n"));
+      return FALSE;
+    }
+    //
+    // Take all resources from Cio slot and return
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus, CioSlot, 0x00, 0);
+    PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+    PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+    PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+    PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+    PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+    PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+    PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+    PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+    PortInfo->PMemLimit64  |= 0xF;
+    //
+    // Jump to next EP
+    //
+    *Bus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    //
+    // Should we continue?
+    //
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+    Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+    return Continue;
+  }
+  //
+  // Set is legacy dvice
+  //
+  isLegacyDevice = IsLegacyDevice (*Bus);
+
+  SetCioPortResources (
+    *Bus,
+    0, // Assign all available resources to US port of EP
+    *Bus + 1,
+    PortInfo->BusNumLimit,
+    0,
+    PortInfo
+    );
+
+  SBus = *Bus + 1;// Jump to DS port
+
+  if (CioSlotPresent) {
+    MaxPHYSlots = CioSlot;
+  }
+
+  UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie, PortInfo);
+  if (!CioSlotPresent) {
+    return FALSE;
+    //
+    // Stop resource assignment on this chain
+    //
+  }
+  //
+  // Set rest of slots us unused
+  //
+  SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
+
+  SetCioPortResources (
+    SBus,
+    CioSlot,
+    SBus + UsedBusNumbers + 1,
+    PortInfo->BusNumLimit,
+    &PortInfoOrg,
+    PortInfo
+    );
+  *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
+  if(ArPcie) {
+    UnsetVesc(SBus, CioSlot, 0x00);
+  }
+  if (*Bus > PortInfo->BusNumLimit - 2) {
+    //
+    // In case of bus numbers are exhausted stop enumeration
+    //
+    return FALSE;
+  }
+  //
+  // Check whether we should continue on this chain
+  //
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+  Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+  return Continue;
+} // ConfigureEP
+
+STATIC
+VOID
+GetPortResources (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      Fun,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+  PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+  PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
+  PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
+  PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
+  PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
+  PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+  PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+  PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+  PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+  PortInfo->IoLimit |= 0xF;
+  PortInfo->MemLimit |= 0xF;
+  PortInfo->PMemLimit64 |= 0xF;
+} // GetPortResources
+
+STATIC
+VOID
+ConfigurePort (
+  IN       UINT8      Bus,
+  IN       UINT8      Dev,
+  IN       UINT8      Fun,
+  IN  OUT  PORT_INFO  *PortInfo
+  )
+{
+  INT8  i;
+  UINT8 USBusNum;
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+  USBusNum          = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, USBusNum, 0x00, 0x00, 0);
+  if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+    //
+    // Nothing to do if TBT device is not connected
+    //
+    return ;
+  }
+
+  GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from DS port
+  //
+  // Assign resources to EPs
+  //
+  for (i = 0; i < MAX_TBT_DEPTH; ++i) {
+    PortInfo->ConfedEP++;
+    if (!ConfigureEP (i, &USBusNum, PortInfo)) {
+      return ;
+    }
+  }
+} // ConfigurePort
+
+VOID
+ThunderboltCallback (
+  IN UINT8 Type
+  )
+{
+  PORT_INFO                     PortInfoOrg  = { 0 };
+  HR_CONFIG                     HrConfig  = { 0 };
+  UINT8                         i;
+  UINTN                         Segment = 0;
+  UINTN                         Bus = 0;
+  UINTN                         Device;
+  UINTN                         Function;
+
+  DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
+
+  DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
+  PortInfoInit (&PortInfoOrg);
+  if(Type == DTBT_CONTROLLER) {
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+      return;
+    }
+    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+    DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
+    if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
+      return ;
+    }
+  //
+  // Configure DS ports
+  //
+  for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
+    DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
+    ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
+  }
+
+  DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
+  EndOfThunderboltCallback (Segment, Bus, Device, Function);
+
+  }
+  DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
+} // ThunderboltCallback
+
+VOID
+DisablePCIDevicesAndBridges (
+  IN UINT8 MinBus,
+  IN UINT8 MaxBus
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RegVal;
+  //
+  //  Disable PCI device First, and then Disable PCI Bridge
+  //
+  for (Bus = MaxBus; Bus > MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+          if (Fun == 0) {
+            break;
+
+          }
+
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
+          //
+          // ********     Disable PCI Device   ********
+          // BIT0  I/O Space Enabled    BIT1  Memory Space Enabled
+          // BIT2  Bus Master Enabled   BIT4  Memory Write and Invalidation Enable
+          //
+          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
+        }
+      }
+    }
+  }
+  //
+  // now no more PCI dev on another side of PCI Bridge can safty disable PCI Bridge
+  //
+  for (Bus = MaxBus; Bus > MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+          if (Fun == 0) {
+            break;
+          }
+
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
+          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
+          PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+        }
+      } // for ( Fun .. )
+    } // for ( Dev ... )
+  } // for ( Bus ... )
+} // DisablePCIDevicesAndBridges
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+  IN UINT8 Type
+  )
+{
+  UINTN         Segment = 0;
+  UINTN         Bus = 0;
+  UINTN         Device;
+  UINTN         Function;
+  UINT8         MinBus;
+  UINT8         MaxBus;
+  UINT16        DeviceId;
+
+  MinBus = 1;
+  if(Type == DTBT_CONTROLLER) {
+    //
+    // for(Dev = 0; Dev < 8; ++Dev)
+    // {
+    // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
+    // gBS->Stall(2000);      // 2msec
+    // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
+    // }
+    // gBS->Stall(200 * 1000);        // 200 msec
+    //
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+      return;
+    }
+    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+    MinBus            = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    MaxBus            = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus, 0x00, 0x00, 0);
+    DeviceId          = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+    if (!(IsTbtHostRouter (DeviceId))) {
+      return;
+    }
+    TbtSegment = (UINT8)Segment;
+    MinBus++;
+    //
+    // @todo : Move this out when we dont have Loop for ITBT
+    //
+    DisablePCIDevicesAndBridges(MinBus, MaxBus);
+
+  }
+} // DisablePCIDevicesAndBridges
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
new file mode 100644
index 0000000000..721438c718
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
@@ -0,0 +1,1765 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Module specific Includes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/TbtNvsArea.h>
+#include <PchAccess.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/IoLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Guid/HobList.h>
+#include "TbtSmiHandler.h"
+#include <PcieRegs.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Library/PchPmcLib.h>
+#define P2P_BRIDGE                    (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define CMD_BM_MEM_IO                 (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DISBL_IO_REG1C                0x01F1
+#define DISBL_MEM32_REG20             0x0000FFF0
+#define DISBL_PMEM_REG24              0x0001FFF1
+
+#define DOCK_BUSSES                   8
+
+#define PCI_CAPABILITY_ID_PCIEXP      0x10
+#define PCI_CAPBILITY_POINTER_OFFSET  0x34
+
+#define LTR_MAX_SNOOP_LATENCY_VALUE             0x0846    ///< Intel recommended maximum value for Snoop Latency  can we put like this ?
+#define LTR_MAX_NON_SNOOP_LATENCY_VALUE         0x0846    ///< Intel recommended maximum value for Non-Snoop Latency can we put like this ?
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA                *mTbtNvsAreaPtr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gCurrentDiscreteTbtRootPort;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gCurrentDiscreteTbtRootPortType;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                      TbtLtrMaxSnoopLatency;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                      TbtLtrMaxNoSnoopLatency;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       gDTbtPcieRstSupport;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB                *gTbtInfoHob = NULL;
+STATIC UINTN                                              mPciExpressBaseAddress;
+STATIC UINT8                TbtSegment        = 0;
+VOID
+GpioWrite (
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+  )
+{
+  GpioSetOutputValue (GpioNumber, (UINT32)Value);
+}
+
+/**
+  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] 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   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+
+  ///
+  /// 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 = 0x100;
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+    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;
+}
+
+/**
+  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] 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
+  )
+{
+  UINT8   CapHeaderOffset;
+  UINT8   CapHeaderId;
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+
+  if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) & EFI_PCI_STATUS_CAPABILITY) == 0x00) {
+    ///
+    /// Function has no capability pointer
+    ///
+    return 0;
+  }
+
+  ///
+  /// 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 = 0x14;
+  } else {
+    ///
+    /// Otherwise, start at Offset 0x34
+    ///
+    CapHeaderOffset = 0x34;
+  }
+  ///
+  /// 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) {
+    CapHeaderId = PciSegmentRead8 (DeviceBase + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+    ///
+    /// 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 = PciSegmentRead8 (DeviceBase + CapHeaderOffset + 1) & ((UINT8) ~(BIT0 | BIT1));
+  }
+
+  return 0;
+}
+/**
+  This function configures the L1 Substates.
+  It can be used for Rootport and endpoint devices.
+
+  @param[in] DownstreamPort               Indicates if the device about to be programmed is a downstream port
+  @param[in] DeviceBase                   Device PCI configuration base address
+  @param[in] L1SubstateExtCapOffset       Pointer to L1 Substate Capability Structure
+  @param[in] PortL1SubstateCapSupport     L1 Substate capability setting
+  @param[in] PortCommonModeRestoreTime    Common Mode Restore Time
+  @param[in] PortTpowerOnValue            Tpower_on Power On Wait Time
+  @param[in] PortTpowerOnScale            Tpower-on Scale
+
+  @retval none
+**/
+VOID
+ConfigureL1s (
+  IN UINTN                              DeviceBase,
+  IN UINT16                             L1SubstateExtCapOffset,
+  IN UINT32                             PortL1SubstateCapSupport,
+  IN UINT32                             PortCommonModeRestoreTime,
+  IN UINT32                             PortTpowerOnValue,
+  IN UINT32                             PortTpowerOnScale,
+  IN UINT16                             MaxLevel
+  )
+{
+
+  PciSegmentAndThenOr32 (
+    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+    (UINT32) ~(0xFF00),
+    (UINT32) PortCommonModeRestoreTime << 8
+    );
+
+  PciSegmentAnd32(DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL2_OFFSET, 0xFFFFFF04);
+
+  PciSegmentOr32(DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL2_OFFSET,(UINT32) ((PortTpowerOnValue << N_PCIE_EX_L1SCTL2_POWT) | PortTpowerOnScale));
+
+  PciSegmentAndThenOr32 (
+    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+    (UINT32) ~(0xE3FF0000),
+    (UINT32) (BIT30 | BIT23 | BIT21)
+    );
+
+}
+
+VOID
+RootportL1sSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT16  RootL1SubstateExtCapOffset,
+  IN UINT16  MaxL1Level
+  )
+{
+  UINTN       ComponentABaseAddress;
+  UINTN       ComponentBBaseAddress;
+  UINT8       SecBus;
+  UINT32      PortL1SubstateCapSupport;
+  UINT32      PortCommonModeRestoreTime;
+  UINT32      PortTpowerOnValue;
+  UINT32      PortTpowerOnScale;
+  UINT16      ComponentBL1SubstateExtCapOffset;
+  UINT32      ComponentBL1Substates;
+  UINT32      ComponentBCommonModeRestoreTime;
+  UINT32      ComponentBTpowerOnValue;
+  UINT32      ComponentBTpowerOnScale;
+  UINT32      Data32;
+
+  PortL1SubstateCapSupport  = 0;
+  PortCommonModeRestoreTime = 0;
+  PortTpowerOnValue = 0;
+  PortTpowerOnScale = 0;
+  Data32 = 0;
+
+  ComponentABaseAddress  = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  if (RootL1SubstateExtCapOffset != 0) {
+    Data32 = PciSegmentRead32 (ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+    PortL1SubstateCapSupport  = (Data32) & 0x0F;
+    PortCommonModeRestoreTime = (Data32 >> 8) & 0xFF;
+    PortTpowerOnScale         = (Data32 >> 16) & 0x3;
+    PortTpowerOnValue         = (Data32 >> 19) & 0x1F;
+  } else {
+    MaxL1Level                = 0; // If L1 Substates from Root Port side is disable, then Disable from Device side also.
+  }
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+    ComponentBL1SubstateExtCapOffset = PcieFindExtendedCapId (
+                                  SecBus,
+                                  0,
+                                  0,
+                                  V_PCIE_EX_L1S_CID
+                                  );
+    if (ComponentBL1SubstateExtCapOffset != 0) {
+      ComponentBL1Substates = PciSegmentRead32 (ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+      ComponentBCommonModeRestoreTime = (ComponentBL1Substates >> 8) & 0xFF;
+      ComponentBTpowerOnScale         = (ComponentBL1Substates >> 16) & 0x3;
+      ComponentBTpowerOnValue         = (ComponentBL1Substates >> 19) & 0x1F;
+
+      if (MaxL1Level == 3) {
+        if (Data32 >= ComponentBL1Substates) {
+          if (~(Data32 | BIT2)) {
+            MaxL1Level = 1;
+          }
+        }
+        else {
+          if (~(ComponentBL1Substates | BIT2)) {
+          MaxL1Level = 1;
+        }
+      }
+    }
+
+      if (MaxL1Level == 3) {
+        ConfigureL1s (
+          ComponentABaseAddress,
+          RootL1SubstateExtCapOffset,
+          PortL1SubstateCapSupport,
+          ComponentBCommonModeRestoreTime,
+          ComponentBTpowerOnValue,
+          ComponentBTpowerOnScale,
+          MaxL1Level
+          );
+
+      ConfigureL1s (
+          ComponentBBaseAddress,
+          ComponentBL1SubstateExtCapOffset,
+          ComponentBL1Substates,
+          PortCommonModeRestoreTime,
+          PortTpowerOnValue,
+          PortTpowerOnScale,
+          MaxL1Level
+          );
+      }
+
+      if (MaxL1Level == 1) {
+        PciSegmentOr32 (
+          ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+          (UINT32) (BIT3 | BIT1)
+          );
+
+        PciSegmentOr32 (
+          ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+          (UINT32) (BIT3 | BIT1)
+          );
+      }
+      else {
+        if (RootL1SubstateExtCapOffset != 0) {
+          PciSegmentOr32 (
+            ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT3 | BIT1)
+            );
+
+          PciSegmentOr32 (
+            ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT2 | BIT0)
+            );
+        }
+        if (ComponentBL1SubstateExtCapOffset != 0) {
+          PciSegmentOr32 (
+            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT3 | BIT1)
+           );
+
+          PciSegmentOr32 (
+            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
+            (UINT32) (BIT2 | BIT0)
+            );
+        }
+      }
+    }
+  }
+}
+
+VOID
+MultiFunctionDeviceAspm (
+  IN UINT8   Bus,
+  IN UINT8   Dev
+  )
+{
+  UINT16  LowerAspm;
+  UINT16  AspmVal;
+  UINT8   Fun;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+
+  LowerAspm = 3; // L0s and L1 Supported
+  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+    //
+    // Check for Device availability
+    //
+    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+      // Device not present
+      continue;
+    }
+
+    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+
+    AspmVal = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+    if (LowerAspm > AspmVal) {
+      LowerAspm = AspmVal;
+    }
+  } //Fun
+
+  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+    //
+    // Check for Device availability
+    //
+    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+      //
+      // Device not present
+      //
+      continue;
+    }
+
+    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+
+    PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, LowerAspm);
+  } //Fun
+}
+
+UINT16
+LimitAspmLevel (
+  IN UINT16  SelectedAspm,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  SelectedAspm = SelectedAspm & MaxAspmLevel;
+
+  return SelectedAspm;
+}
+
+UINT16
+FindOptimalAspm (
+  IN UINT16   ComponentAaspm,
+  IN UINT16   ComponentBaspm
+  )
+{
+  UINT16  SelectedAspm;
+
+  SelectedAspm = ComponentAaspm & ComponentBaspm;
+
+  return SelectedAspm;
+}
+
+UINT16
+FindComponentBaspm (
+  IN UINT8   Bus,
+  IN UINT8   MaxBus
+  )
+{
+  UINT8   BusNo;
+  UINT8   DevNo;
+  UINT8   FunNo;
+  UINT64  DevBaseAddress;
+  UINT8   RegVal;
+  UINT8   SecBusNo;
+  UINT16  SelectedAspm; // No ASPM Support
+  UINT8   CapHeaderOffset_B;
+  BOOLEAN AspmFound;
+
+  SelectedAspm  = 0;
+  AspmFound     = FALSE;
+
+  for (BusNo = MaxBus; (BusNo != 0xFF) && (!AspmFound); --BusNo) {
+    for (DevNo = 0; (DevNo <= PCI_MAX_DEVICE) && (!AspmFound); ++DevNo) {
+      for (FunNo = 0; (FunNo <= PCI_MAX_FUNC) && (!AspmFound); ++FunNo) {
+        //
+        // Check for Device availability
+        //
+        DevBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, BusNo, DevNo, FunNo, 0);
+        if (PciSegmentRead16 (DevBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        RegVal = PciSegmentRead8 (DevBaseAddress + PCI_HEADER_TYPE_OFFSET);
+        if ((RegVal & (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6)) != 0x01) {
+          //
+          // Not a PCI-to-PCI bridges device
+          //
+          continue;
+        }
+
+        SecBusNo = PciSegmentRead8 (DevBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+
+        if (SecBusNo == Bus) {
+          //
+          // This is the Rootbridge for the given 'Bus' device
+          //
+          CapHeaderOffset_B = PcieFindCapId (TbtSegment, BusNo, DevNo, FunNo, 0x10);
+          SelectedAspm      = (PciSegmentRead16 (DevBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+          AspmFound         = TRUE;
+        }
+      } //FunNo
+    } //DevNo
+  } //BusNo
+
+  return (SelectedAspm);
+}
+
+VOID
+NoAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset
+  )
+{
+  UINT64 DeviceBaseAddress;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, 0x00);
+}
+
+VOID
+EndpointAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT8   MaxBus,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
+  SelectedAspm      = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+UpstreamAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT8   MaxBus,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
+  SelectedAspm      = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+DownstreamAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  ComponentABaseAddress;
+  UINT64  ComponentBBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+  UINT8   SecBus;
+  UINT8   CapHeaderOffset_B;
+
+  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+  ComponentBaspm        = 0; // No ASPM Support
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
+    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
+    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+  }
+
+  SelectedAspm = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+RootportAspmSupport (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT8   CapHeaderOffset,
+  IN UINT16  MaxAspmLevel
+  )
+{
+  UINT64  ComponentABaseAddress;
+  UINT64  ComponentBBaseAddress;
+  UINT16  ComponentAaspm;
+  UINT16  ComponentBaspm;
+  UINT16  SelectedAspm;
+  UINT8   SecBus;
+  UINT8   CapHeaderOffset_B;
+
+  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress + CapHeaderOffset + 0x00C) >> 10) & 3;
+
+  SecBus                = PciSegmentRead8 (ComponentABaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0, 0, 0);
+  ComponentBaspm        = 0; // No ASPM Support
+  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
+    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
+    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress + CapHeaderOffset_B + 0x00C) >> 10) & 3;
+  }
+
+  SelectedAspm = FindOptimalAspm (ComponentAaspm, ComponentBaspm);
+  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
+  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0xFFFC, SelectedAspm);
+}
+
+VOID
+ThunderboltEnableAspmWithoutLtr (
+  IN   UINT16     MaxAspmLevel,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RootBus;
+  UINT8   RootDev;
+  UINT8   RootFun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   RegVal;
+  UINT8   CapHeaderOffset;
+  UINT16  DevicePortType;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+
+  RootBus = (UINT8)RpBus;
+  RootDev = (UINT8)RpDevice;
+  RootFun = (UINT8)RpFunction;
+
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      //
+      // Check for Device availability
+      //
+      DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0, 0);
+      if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+        //
+        // Device not present
+        //
+        continue;
+      }
+
+      RegVal = PciSegmentRead8 (DeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+      if ((RegVal & BIT7) == 0) {
+        //
+        // Not a multi-function device
+        //
+        continue;
+      }
+
+      MultiFunctionDeviceAspm(Bus, Dev);
+    } //Dev
+  } //Bus
+
+
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x002) >> 4) & 0xF;
+        if(PciSegmentRead8 (DeviceBaseAddress + PCI_CLASSCODE_OFFSET) == PCI_CLASS_SERIAL) {
+          MaxAspmLevel = (UINT16) 0x1;
+        }
+
+        switch (DevicePortType) {
+        case 0:
+          //
+          // PCI Express Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 1:
+          //
+          // Legacy PCI Express Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 4:
+          //
+          // Root Port of PCI Express Root Complex
+          //
+          RootportAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLevel);
+          break;
+
+        case 5:
+          //
+          // Upstream Port of PCI Express Switch
+          //
+          UpstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 6:
+          //
+          // Downstream Port of PCI Express Switch
+          //
+          DownstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLevel);
+          break;
+
+        case 7:
+          //
+          // PCI Express to PCI/PCI-X Bridge
+          //
+          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
+          break;
+
+        case 8:
+          //
+          // PCI/PCI-X to PCI Express Bridge
+          //
+          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
+          break;
+
+        case 9:
+          //
+          // Root Complex Integrated Endpoint
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        case 10:
+          //
+          // Root Complex Event Collector
+          //
+          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, MaxAspmLevel);
+          break;
+
+        default:
+          break;
+        }
+        //
+        // switch(DevicePortType)
+        //
+      }
+      //
+      // Fun
+      //
+    }
+    //
+    // Dev
+    //
+  }
+  //
+  // Bus
+  //
+  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun, 0x10);
+  RootportAspmSupport (RootBus, RootDev, RootFun, CapHeaderOffset, MaxAspmLevel);
+}
+
+
+
+VOID
+ThunderboltEnableL1Sub (
+  IN   UINT16     MaxL1Level,
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT16  CapHeaderOffsetExtd;
+
+  RpBus   = 0;
+
+  CapHeaderOffsetExtd = PcieFindExtendedCapId ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, V_PCIE_EX_L1S_CID);
+  RootportL1sSupport ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, CapHeaderOffsetExtd, MaxL1Level);
+}
+
+VOID
+ThunderboltDisableAspmWithoutLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   RootBus;
+  UINT8   RootDev;
+  UINT8   RootFun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  RootBus = (UINT8)RpBus;
+  RootDev = (UINT8)RpDevice;
+  RootFun = (UINT8)RpFunction;
+
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFFC, 0x00);
+      } //Fun
+    } //Dev
+  } //Bus
+
+  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun, 0x10);
+  NoAspmSupport(RootBus, RootDev, RootFun, CapHeaderOffset);
+}
+
+VOID
+TbtProgramClkReq (
+  IN        UINT8  Bus,
+  IN        UINT8  Device,
+  IN        UINT8  Function,
+  IN        UINT8  ClkReqSetup
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+  UINT16  Data16;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function, 0x10);
+
+  //
+  // Check if CLKREQ# is supported
+  //
+  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x0C) & BIT18) != 0) {
+    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x010);
+
+    if (ClkReqSetup) {
+      Data16 = Data16 | BIT8; // Enable Clock Power Management
+    } else {
+      Data16 =  Data16 & (UINT16)(~BIT8); // Disable Clock Power Management
+    }
+
+    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x010, Data16);
+  }
+}
+VOID
+TbtProgramPtm(
+   IN        UINT8  Bus,
+   IN        UINT8  Device,
+   IN        UINT8  Function,
+   IN        UINT8  PtmSetup,
+   IN        BOOLEAN IsRoot
+)
+{
+   UINT64  DeviceBaseAddress;
+   UINT16  CapHeaderOffset;
+   UINT16  PtmControlRegister;
+   UINT16  PtmCapabilityRegister;
+
+   DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS(TbtSegment, Bus, Device, Function, 0);
+   CapHeaderOffset = PcieFindExtendedCapId(Bus, Device, Function, 0x001F /*V_PCIE_EX_PTM_CID*/);
+   if(CapHeaderOffset != 0) {
+      PtmCapabilityRegister = PciSegmentRead16(DeviceBaseAddress + CapHeaderOffset + 0x04);
+     //
+     // Check if PTM Requester/ Responder capability for the EP/Down stream etc
+     //
+     if ((PtmCapabilityRegister & (BIT1 | BIT0)) != 0) {
+        PtmControlRegister = PciSegmentRead16(DeviceBaseAddress + CapHeaderOffset + 0x08);
+
+        if (PtmSetup) {
+           PtmControlRegister = PtmControlRegister | BIT0; // Enable PTM
+           if(IsRoot) {
+             PtmControlRegister = PtmControlRegister | BIT1; // Enable PTM
+           }
+           PtmControlRegister = PtmControlRegister | (PtmCapabilityRegister & 0xFF00); // Programm Local Clock Granularity
+        } else {
+           PtmControlRegister = PtmControlRegister & (UINT16)(~(BIT0 | BIT1)); // Disable Clock Power Management
+        }
+
+        PciSegmentWrite16(DeviceBaseAddress + CapHeaderOffset + 0x08, PtmControlRegister);
+     }
+   }
+}
+
+VOID
+ConfigureTbtPm (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction,
+  IN   UINT8      Configuration    // 1- Clk Request , 2- PTM ,
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  if ((Configuration != 1) && (Configuration != 2)) {
+    return;
+  }
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MaxBus; Bus >= MinBus; --Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          if (Fun == 0) {
+            //
+            // IF Fun is zero, stop enumerating other functions of the particular bridge
+            //
+            break;
+          }
+          //
+          // otherwise, just skip checking for CLKREQ support
+          //
+          continue;
+        }
+        switch (Configuration) {
+          case 1:
+            TbtProgramClkReq (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtSetClkReq);
+            break;
+          case 2:
+            TbtProgramPtm (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtPtm, FALSE);
+            TbtProgramPtm((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, (UINT8) mTbtNvsAreaPtr->TbtPtm, TRUE);
+            break;
+          default:
+            break;
+        }
+      } //Fun
+    } // Dev
+  } // Bus
+}
+
+/**
+  1) Check LTR support in device capabilities 2 register (bit 11).
+  2) If supported enable LTR in device control 2 register (bit 10).
+
+**/
+VOID
+TbtProgramLtr (
+  IN        UINT8  Bus,
+  IN        UINT8  Device,
+  IN        UINT8  Function,
+  IN        UINT8  LtrSetup
+  )
+{
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffset;
+  UINT16  Data16;
+
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Function, 0);
+  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function, 0x10);
+
+  //
+  // Check if LTR# is supported
+  //
+  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x24) & BIT11) != 0) {
+    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x028);
+
+    if (LtrSetup) {
+      Data16 = Data16 | BIT10; // LTR Mechanism Enable
+    } else {
+      Data16 =  Data16 & (UINT16)(~BIT10); // LTR Mechanism Disable
+    }
+
+    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x028, Data16);
+  }
+}
+
+VOID
+ConfigureLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+  //
+  //  Enumerate all the bridges and devices which are available on TBT host controller
+  //
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          if (Fun == 0) {
+            //
+            // IF Fun is zero, stop enumerating other functions of the particular bridge
+            //
+            break;
+          }
+          //
+          // otherwise, just skip checking for LTR support
+          //
+          continue;
+        }
+
+        TbtProgramLtr (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtLtr);
+
+      } //Fun
+    } // Dev
+  } // Bus
+  TbtProgramLtr ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction, (UINT8) mTbtNvsAreaPtr->TbtLtr);
+}
+
+/*
+  US ports and endpoints which declare support must also have the LTR capability structure (cap ID 18h).
+  In this structure you need to enter the max snoop latency and max non-snoop latency in accordance with the format specified in the PCIe spec.
+  The latency value itself is platform specific so you'll need to get it from the platform architect or whatever.
+*/
+VOID
+ThunderboltGetLatencyLtr (
+  VOID
+  )
+{
+  PCH_SERIES       PchSeries;
+
+  PchSeries = GetPchSeries ();
+
+  if(gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PEG) {
+  // PEG selector
+  TbtLtrMaxSnoopLatency = LTR_MAX_SNOOP_LATENCY_VALUE;
+  TbtLtrMaxNoSnoopLatency = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+  } else if (gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PCH) {
+  // PCH selector
+
+    if (PchSeries == PchLp) {
+      TbtLtrMaxSnoopLatency = 0x1003;
+      TbtLtrMaxNoSnoopLatency = 0x1003;
+    }
+    if (PchSeries == PchH) {
+      TbtLtrMaxSnoopLatency = 0x0846;
+      TbtLtrMaxNoSnoopLatency = 0x0846;
+    }
+  }
+}
+
+VOID
+SetLatencyLtr (
+  IN UINT8   Bus,
+  IN UINT8   Dev,
+  IN UINT8   Fun,
+  IN UINT16  CapHeaderOffsetExtd,
+  IN UINT16  LtrMaxSnoopLatency,
+  IN UINT16  LtrMaxNoSnoopLatency
+  )
+{
+  UINT64 DeviceBaseAddress;
+  if(CapHeaderOffsetExtd == 0) {
+    return;
+  }
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x004, LtrMaxSnoopLatency);
+  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x006, LtrMaxNoSnoopLatency);
+}
+
+VOID
+ThunderboltSetLatencyLtr (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  UINT8   Bus;
+  UINT8   Dev;
+  UINT8   Fun;
+  UINT8   MinBus;
+  UINT8   MaxBus;
+  UINT16  DeviceId;
+  UINT64  DeviceBaseAddress;
+  UINT8   CapHeaderOffsetStd;
+  UINT16  CapHeaderOffsetExtd;
+  UINT16  DevicePortType;
+
+  MinBus  = 0;
+  MaxBus  = 0;
+
+  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
+  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
+  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
+  if (!(IsTbtHostRouter (DeviceId))) {
+    return;
+  }
+
+  TbtSegment = (UINT8)RpSegment;
+
+  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
+    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+        //
+        // Check for Device availability
+        //
+        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+          //
+          // Device not present
+          //
+          continue;
+        }
+
+        CapHeaderOffsetStd = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
+        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffsetStd + 0x002) >> 4) & 0xF;
+
+        CapHeaderOffsetExtd = PcieFindExtendedCapId (Bus, Dev, Fun, 0x0018);
+
+        switch (DevicePortType) {
+        case 0:
+          //
+          // PCI Express Endpoint
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 1:
+          //
+          // Legacy PCI Express Endpoint
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 4:
+          //
+          // Root Port of PCI Express Root Complex
+          //
+          // Do-nothing
+          break;
+
+        case 5:
+          //
+          // Upstream Port of PCI Express Switch
+          //
+          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
+          break;
+
+        case 6:
+          //
+          // Downstream Port of PCI Express Switch
+          //
+          // Do-nothing
+          break;
+
+        case 7:
+          //
+          // PCI Express to PCI/PCI-X Bridge
+          //
+          // Do-nothing
+          break;
+
+        case 8:
+          //
+          // PCI/PCI-X to PCI Express Bridge
+          //
+          // Do-nothing
+          break;
+
+        case 9:
+          //
+          // Root Complex Integrated Endpoint
+          //
+          // Do-nothing
+          break;
+
+        case 10:
+          //
+          // Root Complex Event Collector
+          //
+          // Do-nothing
+          break;
+
+        default:
+          break;
+        }
+        //
+        // switch(DevicePortType)
+        //
+      }
+      //
+      // Fun
+      //
+    }
+    //
+    // Dev
+    //
+  }
+  //
+  // Bus
+  //
+}
+
+static
+VOID
+Stall (
+  UINTN     Usec
+  )
+{
+  UINTN   Index;
+  UINT32  Data32;
+  UINT32  PrevData;
+  UINTN   Counter;
+
+  Counter = (UINTN) ((Usec * 10) / 3);
+  //
+  // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+  // periods, thus attempting to ensure Microseconds of stall time.
+  //
+  if (Counter != 0) {
+
+    PrevData = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_TMR);
+    for (Index = 0; Index < Counter;) {
+      Data32 = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_TMR);
+      if (Data32 < PrevData) {
+        //
+        // Reset if there is a overlap
+        //
+        PrevData = Data32;
+        continue;
+      }
+
+      Index += (Data32 - PrevData);
+      PrevData = Data32;
+    }
+  }
+
+  return ;
+}
+/**
+  Called during Sx entry, initates TbtSetPcie2TbtCommand HandShake to set GO2SX_NO_WAKE
+  for Tbt devices if WakeupSupport is not present.
+
+  @param[in] DispatchHandle         - The unique handle assigned to this handler by SmiHandlerRegister().
+  @param[in] DispatchContext        - 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 successfully.
+**/
+EFI_STATUS
+EFIAPI
+SxDTbtEntryCallback (
+  IN  EFI_HANDLE                    DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer OPTIONAL,
+  IN  UINTN                         *CommBufferSize OPTIONAL
+  )
+{
+  UINT16          DeviceId;
+  UINT8           CableConnected;
+  UINT8           RootportSelected;
+  UINT8           HoustRouteBus;
+  volatile UINT32 *PowerState;
+  UINT32          PowerStatePrev;
+  BOOLEAN         SecSubBusAssigned;
+  UINT64          DeviceBaseAddress;
+  UINT8           CapHeaderOffset;
+  UINTN           RpDev;
+  UINTN           RpFunc;
+  EFI_STATUS      Status;
+  UINT32          Timeout;
+  UINT32          RegisterValue;
+  UINT64          Tbt2Pcie;
+  UINTN           Index;
+  UINT32          TbtCioPlugEventGpioNo;
+  UINT32          TbtFrcPwrGpioNo;
+  UINT8           TbtFrcPwrGpioLevel;
+  UINT32          TbtPcieRstGpioNo;
+  UINT8           TbtPcieRstGpioLevel;
+  EFI_SMM_SX_REGISTER_CONTEXT   *EntryDispatchContext;
+
+  CableConnected    = 0;
+  HoustRouteBus     = 3;
+  SecSubBusAssigned = FALSE;
+  Timeout = 600;
+  RootportSelected      = 0;
+  TbtCioPlugEventGpioNo = 0;
+  TbtFrcPwrGpioNo       = 0;
+  TbtFrcPwrGpioLevel    = 0;
+  TbtPcieRstGpioNo      = 0;
+  TbtPcieRstGpioLevel   = 0;
+  Index = 0;
+
+  EntryDispatchContext = (EFI_SMM_SX_REGISTER_CONTEXT*) DispatchContext;
+
+//  CableConnected = GetTbtHostRouterStatus ();
+  //SaveTbtHostRouterStatus (CableConnected & 0xF0);
+  //
+  // Get the Power State and Save
+  //
+  if (((mTbtNvsAreaPtr->DTbtControllerEn0 == 0) && (Index == 0)))  {
+
+  RootportSelected      = mTbtNvsAreaPtr->RootportSelected0;
+  TbtCioPlugEventGpioNo = mTbtNvsAreaPtr->TbtCioPlugEventGpioNo0;
+  TbtFrcPwrGpioNo       = mTbtNvsAreaPtr->TbtFrcPwrGpioNo0;
+  TbtFrcPwrGpioLevel    = mTbtNvsAreaPtr->TbtFrcPwrGpioLevel0;
+  TbtPcieRstGpioNo      = mTbtNvsAreaPtr->TbtPcieRstGpioNo0;
+  TbtPcieRstGpioLevel   = mTbtNvsAreaPtr->TbtPcieRstGpioLevel0;
+  }
+
+  Status = GetDTbtRpDevFun (gCurrentDiscreteTbtRootPortType, RootportSelected - 1, &RpDev, &RpFunc);
+  ASSERT_EFI_ERROR (Status);
+  CapHeaderOffset = PcieFindCapId (TbtSegment, 0x00, (UINT8)RpDev, (UINT8)RpFunc, 0x01);
+  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, 0x00, (UINT32)RpDev, (UINT32)RpFunc, 0);
+  PowerState        = &*((volatile UINT32 *) (mPciExpressBaseAddress + DeviceBaseAddress + CapHeaderOffset + 4)); //PMCSR
+  PowerStatePrev    = *PowerState;
+  *PowerState &= 0xFFFFFFFC;
+
+  HoustRouteBus = PciSegmentRead8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+  //
+  // Check the Subordinate bus .If it is Zero ,assign temporary bus to
+  // find the device presence .
+  //
+  if (HoustRouteBus == 0) {
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0xF0);
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0xF0);
+    HoustRouteBus     = 0xF0;
+    SecSubBusAssigned = TRUE;
+  }
+  //
+  // Clear Interrupt capability of TBT CIO Plug Event Pin to make sure no SCI is getting generated,
+  // This GPIO will be reprogrammed while resuming as part of Platform GPIO Programming.
+  //
+  GpioSetPadInterruptConfig (TbtCioPlugEventGpioNo, GpioIntDis);
+  //
+  // Read the TBT Host router DeviceID
+  //
+  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (TbtSegment, HoustRouteBus, 0, 0, PCI_DEVICE_ID_OFFSET));
+
+  //
+  // Check For HostRouter Presence
+  //
+  if (IsTbtHostRouter (DeviceId)) {
+    //    CableConnected = GetTbtHostRouterStatus ();
+    if (!((CableConnected & (DTBT_SAVE_STATE_OFFSET << Index)) == (DTBT_SAVE_STATE_OFFSET << Index))) {
+      CableConnected = CableConnected | (DTBT_SAVE_STATE_OFFSET << Index);
+   //     SaveTbtHostRouterStatus (CableConnected);
+    }
+  }
+
+  //
+  // Check value of Tbt2Pcie reg, if Tbt is not present, bios needs to apply force power prior to sending mailbox command
+  //
+  GET_TBT2PCIE_REGISTER_ADDRESS(TbtSegment, HoustRouteBus, 0x00, 0x00, Tbt2Pcie)
+  RegisterValue = PciSegmentRead32 (Tbt2Pcie);
+  if (0xFFFFFFFF == RegisterValue) {
+
+    GpioWrite (TbtFrcPwrGpioNo,TbtFrcPwrGpioLevel);
+
+    while (Timeout -- > 0) {
+      RegisterValue = PciSegmentRead32 (Tbt2Pcie);
+      if (0xFFFFFFFF != RegisterValue) {
+        break;
+      }
+      Stall(1* (UINTN)1000);
+    }
+    //
+    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox command for AIC.
+    // However BIOS shall not execute go2sx mailbox command on S5/reboot cycle.
+    //
+
+    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type == SxS4))
+    {
+      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
+        //Wake Disabled, GO2SX_NO_WAKE Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      } else {
+        //Wake Enabled, GO2SX Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      }
+    }
+    if (mTbtNvsAreaPtr->TbtFrcPwrEn == 0) {
+      GpioWrite (TbtFrcPwrGpioNo,!(TbtFrcPwrGpioLevel));
+    }
+  } else {
+    //
+    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox command for AIC.
+    // However BIOS shall not execute go2sx mailbox command on S5/reboot cycle.
+    //
+    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type == SxS4))
+    {
+      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
+        //Wake Disabled, GO2SX_NO_WAKE Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      } else {
+        //Wake Enabled, GO2SX Command
+        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
+      }
+    }
+  }
+  *PowerState = PowerStatePrev;
+  //
+  // Restore the bus number in case we assigned temporarily
+  //
+  if (SecSubBusAssigned) {
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0x00);
+    PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0x00);
+  }
+  if (gDTbtPcieRstSupport) {
+    GpioWrite (TbtPcieRstGpioNo,TbtPcieRstGpioLevel);
+  }
+  return EFI_SUCCESS;
+}
+
+VOID
+ThunderboltSwSmiCallback (
+  IN UINT8 Type
+  )
+{
+  UINT8 ThunderboltSmiFunction;
+
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Entry\n"));
+  ThunderboltSmiFunction = mTbtNvsAreaPtr->ThunderboltSmiFunction;
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback. ThunderboltSmiFunction=%d\n", ThunderboltSmiFunction));
+  if (Type == DTBT_CONTROLLER) {
+    gCurrentDiscreteTbtRootPort     = mTbtNvsAreaPtr->CurrentDiscreteTbtRootPort;
+    gCurrentDiscreteTbtRootPortType = mTbtNvsAreaPtr->CurrentDiscreteTbtRootPortType;
+  }
+
+  switch (ThunderboltSmiFunction) {
+  case 21:
+    ThunderboltCallback (Type);
+    break;
+
+  case 22:
+    TbtDisablePCIDevicesAndBridges (Type);
+    break;
+
+  case 23:
+    ConfigureTbtAspm (Type, (UINT16) 0x02);
+    break;
+
+  case 24:
+    ConfigureTbtAspm (Type, (UINT16) 0x01);
+    break;
+
+  default:
+    break;
+  }
+  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Exit.\n"));
+}
+STATIC
+EFI_STATUS
+EFIAPI
+DiscreteThunderboltSwSmiCallback (
+  IN EFI_HANDLE                     DispatchHandle,
+  IN  CONST VOID                    *DispatchContext,
+  IN  OUT VOID                      *CommBuffer OPTIONAL,
+  IN  UINTN                         *CommBufferSize OPTIONAL
+  )
+{
+  ThunderboltSwSmiCallback(DTBT_CONTROLLER);
+  return EFI_SUCCESS;
+}
+EFI_STATUS
+TbtRegisterHandlers (
+  IN BOOLEAN Type
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         SmiInputValue;
+  EFI_SMM_HANDLER_ENTRY_POINT2   SxHandler;
+  EFI_SMM_HANDLER_ENTRY_POINT2   SwHandler;
+  EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatchProtocol;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+  EFI_SMM_SX_REGISTER_CONTEXT   EntryDispatchContext;
+  EFI_SMM_SW_REGISTER_CONTEXT   SwContext;
+  EFI_HANDLE                    SwDispatchHandle;
+  EFI_HANDLE                    S3DispatchHandle;
+  EFI_HANDLE                    S4DispatchHandle;
+  EFI_HANDLE                    S5DispatchHandle;
+
+  Status = EFI_UNSUPPORTED;
+
+  if(Type == DTBT_CONTROLLER) {
+    SxHandler = SxDTbtEntryCallback;
+    SwHandler = DiscreteThunderboltSwSmiCallback;
+    SmiInputValue = PcdGet8 (PcdSwSmiDTbtEnumerate);
+    gDTbtPcieRstSupport = gTbtInfoHob->DTbtCommonConfig.PcieRstSupport;
+    Status = EFI_SUCCESS;
+  }
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SwDispatchHandle        = NULL;
+  S3DispatchHandle        = NULL;
+  S4DispatchHandle        = NULL;
+  S5DispatchHandle        = NULL;
+
+   Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSxDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &SxDispatchProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S3 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS3;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S3DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S4 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS4;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S4DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register S5 entry phase call back function
+  //
+  EntryDispatchContext.Type   = SxS5;
+  EntryDispatchContext.Phase  = SxEntry;
+  Status = SxDispatchProtocol->Register (
+                                SxDispatchProtocol,
+                                SxHandler,
+                                &EntryDispatchContext,
+                                &S5DispatchHandle
+                                );
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Locate the SMM SW dispatch protocol
+  //
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSwDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &SwDispatch
+                    );
+
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Register SWSMI handler
+  //
+  SwContext.SwSmiInputValue = SmiInputValue;
+  Status = SwDispatch->Register (
+                        SwDispatch,
+                        SwHandler,
+                        &SwContext,
+                        &SwDispatchHandle
+                        );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+EFI_STATUS
+InSmmFunction (
+  IN  EFI_HANDLE        ImageHandle,
+  IN  EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                    Status;
+
+  Status = EFI_SUCCESS;
+
+  Status = TbtRegisterHandlers(DTBT_CONTROLLER);
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+TbtSmmEntryPoint (
+  IN EFI_HANDLE               ImageHandle,
+  IN EFI_SYSTEM_TABLE         *SystemTable
+  )
+{
+  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
+  EFI_STATUS                    Status;
+
+  DEBUG ((DEBUG_INFO, "TbtSmmEntryPoint\n"));
+
+  mPciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
+  //
+  // Locate Tbt shared data area
+  //
+  Status = gBS->LocateProtocol (&gTbtNvsAreaProtocolGuid, NULL, (VOID **) &TbtNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+  mTbtNvsAreaPtr = TbtNvsAreaProtocol->Area;
+
+  //
+  // Get TBT INFO HOB
+  //
+  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+  if (gTbtInfoHob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  return InSmmFunction (ImageHandle, SystemTable);
+}
+
+VOID
+EndOfThunderboltCallback (
+  IN   UINTN      RpSegment,
+  IN   UINTN      RpBus,
+  IN   UINTN      RpDevice,
+  IN   UINTN      RpFunction
+  )
+{
+  if(mTbtNvsAreaPtr->TbtL1SubStates != 0) {
+    ThunderboltEnableL1Sub (mTbtNvsAreaPtr->TbtL1SubStates, RpSegment, RpBus, RpDevice, RpFunction);
+  }
+  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 1);
+  if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
+    ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  } else { //Aspm enable case
+    ThunderboltEnableAspmWithoutLtr ((UINT16)mTbtNvsAreaPtr->TbtAspm, RpSegment, RpBus, RpDevice, RpFunction);
+  }
+
+  if (mTbtNvsAreaPtr->TbtLtr) {
+    ThunderboltGetLatencyLtr ();
+    ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  }
+  ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 2);
+} // EndOfThunderboltCallback
+
+VOID
+ConfigureTbtAspm (
+  IN UINT8        Type,
+  IN UINT16       Aspm
+  )
+{
+  UINTN                         RpSegment = 0;
+  UINTN                         RpBus = 0;
+  UINTN                         RpDevice;
+  UINTN                         RpFunction;
+
+  if(Type == DTBT_CONTROLLER) {
+    if (gCurrentDiscreteTbtRootPort == 0) {
+      return;
+    }
+    GetDTbtRpDevFun(DTBT_CONTROLLER, gCurrentDiscreteTbtRootPort - 1, &RpDevice, &RpFunction);
+
+    ConfigureTbtPm (RpSegment, RpBus, RpDevice, RpFunction, 1);
+    if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
+      ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunction);
+    } else { //Aspm enable case
+      ThunderboltEnableAspmWithoutLtr ((UINT16) Aspm, RpSegment, RpBus, RpDevice, RpFunction);
+    }
+
+  if (mTbtNvsAreaPtr->TbtLtr) {
+      ThunderboltGetLatencyLtr ();
+      ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
+    }
+    ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
+  } // EndOfThunderboltCallback
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
new file mode 100644
index 0000000000..ec06eee73f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -0,0 +1,394 @@
+/** @file
+  ACPI Timer implements one instance of Timer Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Acpi.h>
+//
+// OVERRIDE: OverrideBegin
+//
+#include <Register/Cpuid.h>
+//
+// OVERRIDE: OverrideEnd
+//
+
+
+/**
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  Internal function to retrieves the 64-bit frequency in Hz.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+InternalGetPerformanceCounterFrequency (
+  VOID
+  );
+
+/**
+  The constructor function enables ACPI IO space.
+
+  If ACPI I/O space not enabled, this function will enable it.
+  It will always return RETURN_SUCCESS.
+
+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+AcpiTimerLibConstructor (
+  VOID
+  )
+{
+  UINTN   Bus;
+  UINTN   Device;
+  UINTN   Function;
+  UINTN   EnableRegister;
+  UINT8   EnableMask;
+
+  //
+  // ASSERT for the invalid PCD values. They must be configured to the real value.
+  //
+  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);
+  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);
+
+  //
+  // If the register offset to the BAR for the ACPI I/O Port Base Address is 0x0000, then
+  // no PCI register programming is required to enable access to the the ACPI registers
+  // specified by PcdAcpiIoPortBaseAddress
+  //
+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {
+    return RETURN_SUCCESS;
+  }
+
+  //
+  // ASSERT for the invalid PCD values. They must be configured to the real value.
+  //
+  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);
+  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);
+  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);
+
+  //
+  // Retrieve the PCD values for the PCI configuration space required to program the ACPI I/O Port Base Address
+  //
+  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);
+  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);
+  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);
+  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);
+  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);
+
+  //
+  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and enable it.
+  //
+  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister)) & EnableMask) != EnableMask) {
+    PciWrite16 (
+      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16 (PcdAcpiIoPciBarRegisterOffset)),
+      PcdGet16 (PcdAcpiIoPortBaseAddress)
+      );
+    PciOr8 (
+      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),
+      EnableMask
+      );
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Internal function to retrieve the ACPI I/O Port Base Address.
+
+  Internal function to retrieve the ACPI I/O Port Base Address.
+
+  @return The 16-bit ACPI I/O Port Base Address.
+
+**/
+UINT16
+InternalAcpiGetAcpiTimerIoPort (
+  VOID
+  )
+{
+  UINT16  Port;
+
+  Port = PcdGet16 (PcdAcpiIoPortBaseAddress);
+
+  //
+  // If the register offset to the BAR for the ACPI I/O Port Base Address is not 0x0000, then
+  // read the PCI register for the ACPI BAR value in case the BAR has been programmed to a
+  // value other than PcdAcpiIoPortBaseAddress
+  //
+  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {
+    Port = PciRead16 (PCI_LIB_ADDRESS (
+                        PcdGet8  (PcdAcpiIoPciBusNumber),
+                        PcdGet8  (PcdAcpiIoPciDeviceNumber),
+                        PcdGet8  (PcdAcpiIoPciFunctionNumber),
+                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)
+                        ));
+  }
+
+  return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16 (PcdAcpiPm1TmrOffset);
+}
+
+/**
+  Stalls the CPU for at least the given number of ticks.
+
+  Stalls the CPU for at least the given number of ticks. It's invoked by
+  MicroSecondDelay() and NanoSecondDelay().
+
+  @param  Delay     A period of time to delay in ticks.
+
+**/
+VOID
+InternalAcpiDelay (
+  IN UINT32  Delay
+  )
+{
+  UINT16   Port;
+  UINT32   Ticks;
+  UINT32   Times;
+
+  Port   = InternalAcpiGetAcpiTimerIoPort ();
+  Times  = Delay >> 22;
+  Delay &= BIT22 - 1;
+  do {
+    //
+    // The target timer count is calculated here
+    //
+    Ticks = IoBitFieldRead32 (Port, 0, 23) + Delay;
+    Delay = BIT22;
+    //
+    // Wait until time out
+    // Delay >= 2^23 could not be handled by this function
+    // Timer wrap-arounds are handled correctly by this function
+    //
+    while (((Ticks - IoBitFieldRead32 (Port, 0, 23)) & BIT23) == 0) {
+      CpuPause ();
+    }
+  } while (Times-- > 0);
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN UINTN  MicroSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                MicroSeconds,
+                ACPI_TIMER_FREQUENCY
+                ),
+              1000000u
+              )
+    );
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN UINTN  NanoSeconds
+  )
+{
+  InternalAcpiDelay (
+    (UINT32)DivU64x32 (
+              MultU64x32 (
+                NanoSeconds,
+                ACPI_TIMER_FREQUENCY
+                ),
+              1000000000u
+              )
+    );
+  return NanoSeconds;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  Retrieves the current value of a 64-bit free running performance counter. The
+  counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return AsmReadTsc ();
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT UINT64  *StartValue,  OPTIONAL
+  OUT UINT64  *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 0xffffffffffffffffULL;
+  }
+  return InternalGetPerformanceCounterFrequency ();
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN UINT64  Ticks
+  )
+{
+  UINT64  Frequency;
+  UINT64  NanoSeconds;
+  UINT64  Remainder;
+  INTN    Shift;
+  Frequency = GetPerformanceCounterProperties (NULL, NULL);
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
+
+  //
+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
+  // i.e. highest bit set in Remainder should <= 33.
+  //
+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);
+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);
+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);
+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
+
+  return NanoSeconds;
+}
+
+//
+// OVERRIDE: OverrideBegin
+//
+/**
+  Calculate TSC frequency.
+
+  The TSC counting frequency is determined by using CPUID leaf 0x15 that is the preferred
+  method for Skylake and beyond.  Frequency in MHz = Core XTAL frequency * EBX/EAX.
+  In newer flavors of the CPU, core xtal frequency is returned in ECX (or 0 if not
+  supported).  If ECX is 0, 24MHz is assumed.
+  @return The number of TSC counts per second.
+
+**/
+UINT64
+InternalCalculateTscFrequency (
+  VOID
+  )
+{
+  UINT64      TscFrequency;
+  UINT64      CoreXtalFrequency;
+  UINT32      RegEax;
+  UINT32      RegEbx;
+  UINT32      RegEcx;
+
+  //
+  // Use CPUID leaf 0x15.
+  // TSC frequency = (Core Xtal Frequency) * EBX/EAX.  EBX returns 0 if not
+  // supported. ECX, if non zero, provides Core Xtal Frequency in hertz
+  // (SDM Dec 2016).
+  //
+  AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL);
+  ASSERT (RegEbx != 0);
+
+  //
+  // If core xtal frequency (ECX) returns 0, it is safe to use 24MHz for post
+  // Skylake client CPU's.
+  //
+  if (RegEcx == 0) {
+    CoreXtalFrequency = 24000000ul;
+  } else {
+    CoreXtalFrequency = (UINT64)RegEcx;
+  }
+
+  //
+  // Calculate frequency.  For integer division, round up/down result
+  // correctly by adding denominator/2 to the numerator prior to division.
+  //
+  TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UINT64)(RegEax >> 1), RegEax);
+
+  return TscFrequency;
+}
+//
+// OVERRIDE: OverrideEnd
+//
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
new file mode 100644
index 0000000000..2bba58eed3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
@@ -0,0 +1,612 @@
+/** @file
+  Source code for the board configuration init function in DXE init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <Library/HobLib.h>
+#include <MemInfoHob.h>
+#include <Library/PchSerialIoLib.h>
+#include <PlatformBoardConfig.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchEspiLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <TbtBoardInfo.h>
+#include <Library/CpuPlatformLib.h>
+#include <GopConfigLib.h>
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+GopVbtSpecificUpdateNull(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+
+//
+// for CFL U DDR4
+//
+VOID
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+
+/**
+  Updates DIMM slots status for Desktop,server and workstation boards
+
+**/
+VOID
+UpdateDimmPopulationConfig(
+  VOID
+  )
+{
+  MEMORY_INFO_DATA_HOB    *MemInfo;
+  UINT8                   Slot0;
+  UINT8                   Slot1;
+  UINT8                   Slot2;
+  UINT8                   Slot3;
+  CONTROLLER_INFO         *ControllerInfo;
+  EFI_HOB_GUID_TYPE       *GuidHob;
+
+  GuidHob = NULL;
+  MemInfo = NULL;
+
+  GuidHob = GetFirstGuidHob (&gSiMemoryInfoDataGuid);
+  ASSERT (GuidHob != NULL);
+  if (GuidHob != NULL) {
+    MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA (GuidHob);
+  }
+  if (MemInfo != NULL) {
+    if (PcdGet8 (PcdPlatformFlavor) == FlavorDesktop ||
+        PcdGet8 (PcdPlatformFlavor) == FlavorUpServer ||
+        PcdGet8 (PcdPlatformFlavor) == FlavorWorkstation) {
+      ControllerInfo = &MemInfo->Controller[0];
+      Slot0 = ControllerInfo->ChannelInfo[0].DimmInfo[0].Status;
+      Slot1 = ControllerInfo->ChannelInfo[0].DimmInfo[1].Status;
+      Slot2 = ControllerInfo->ChannelInfo[1].DimmInfo[0].Status;
+      Slot3 = ControllerInfo->ChannelInfo[1].DimmInfo[1].Status;
+
+      //
+      // Channel 0          Channel 1
+      // Slot0   Slot1      Slot0   Slot1      - Population            AIO board
+      // 0          0          0          0          - Invalid        - Invalid
+      // 0          0          0          1          - Valid          - Invalid
+      // 0          0          1          0          - Invalid        - Valid
+      // 0          0          1          1          - Valid          - Valid
+      // 0          1          0          0          - Valid          - Invalid
+      // 0          1          0          1          - Valid          - Invalid
+      // 0          1          1          0          - Invalid        - Invalid
+      // 0          1          1          1          - Valid          - Invalid
+      // 1          0          0          0          - Invalid        - Valid
+      // 1          0          0          1          - Invalid        - Invalid
+      // 1          0          1          0          - Invalid        - Valid
+      // 1          0          1          1          - Invalid        - Valid
+      // 1          1          0          0          - Valid          - Valid
+      // 1          1          0          1          - Valid          - Invalid
+      // 1          1          1          0          - Invalid        - Valid
+      // 1          1          1          1          - Valid          - Valid
+      //
+
+      if ((Slot0 && (Slot1 == 0)) || (Slot2 && (Slot3 == 0))) {
+        PcdSetBoolS (PcdDimmPopulationError, TRUE);
+      }
+    }
+  }
+}
+
+/**
+  Init Misc Platform Board Config Block.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInit (
+  IN UINT16 BoardId
+  )
+{
+//  PcdSet64S (PcdFuncBoardHookPlatformSetupOverride, (UINT64) (UINTN) BoardHookPlatformSetup);
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdPssReadSN, TRUE);
+      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
+      PcdSet8S (PcdPssI2cBusNumber, 0x04);
+      break;
+    default:
+      PcdSetBoolS (PcdPssReadSN, FALSE);
+      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
+      PcdSet8S (PcdPssI2cBusNumber, 0x04);
+      break;
+  }
+
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init Platform Board Config Block for ACPI platform.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+InitAcpiPlatformPcd (
+  IN UINT16 BoardId
+  )
+{
+  TBT_INFO_HOB  *TbtInfoHob = NULL;
+
+  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+
+  //
+  // Update OEM table ID
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      if ((TbtInfoHob != NULL) && (TbtInfoHob->DTbtControllerConfig[0].DTbtControllerEn == 1)) {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h', 'l', 't', '4'));
+      } else {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h', 'l', 'd', '4'));
+      }
+      break;
+    default:
+      PcdSet64S (PcdXhciAcpiTableSignature, 0);
+      break;
+  }
+
+  //
+  // Modify Preferred_PM_Profile field based on Board SKU's. Default is set to Mobile
+  //
+  PcdSet8S (PcdPreferredPmProfile, EFI_ACPI_2_0_PM_PROFILE_MOBILE);
+
+  //
+  // Assign FingerPrint, Gnss, TouchPanel, Audio related GPIO.
+  //
+  switch(BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdFingerPrintSleepGpio, GPIO_CNL_LP_GPP_B17);
+      PcdSet32S (PcdFingerPrintIrqGpio,   GPIO_CNL_LP_GPP_B16);
+      //
+      // Configure WWAN Reset pin
+      //
+      PcdSet32S (PcdGnssResetGpio,      GPIO_CNL_LP_GPP_F1);
+      PcdSet32S (PcdTouchpanelIrqGpio,  GPIO_CNL_LP_GPP_D10);
+      PcdSet32S (PcdTouchpadIrqGpio,    GPIO_CNL_LP_GPP_B3);
+      PcdSet32S (PcdHdaI2sCodecIrqGpio, GPIO_CNL_LP_GPP_C8);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Configure GPIOs for discrete USB BT module
+  //
+  switch(BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdBtIrqGpio,    GPIO_CNL_LP_GPP_B2);
+      PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Board Specific Init
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS(PcdWhlErbRtd3TableEnable, TRUE);
+      PcdSet8S (PcdHdaI2sCodecI2cBusNumber, 0); // I2S Audio Codec conntected to I2C0
+      PcdSet8S (PcdBleUsbPortNumber, 9);
+      break;
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init Common Platform Board Config Block.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+InitCommonPlatformPcd (
+  IN UINT16 BoardId
+  )
+{
+  PCD64_BLOB Data64;
+  TBT_INFO_HOB  *TbtInfoHob = NULL;
+
+  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+
+
+  //
+  // Enable EC SMI# for SMI
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdEcSmiGpio, GPIO_CNL_LP_GPP_E3);
+      PcdSet32S (PcdEcLowPowerExitGpio, GPIO_CNL_LP_GPP_B23);
+      break;
+  };
+
+  //
+  // HID I2C Interrupt GPIO.
+  //
+  switch (BoardId) {
+    default:
+      // on all supported boards interrupt input is on same GPIO pad. How convenient.
+      PcdSet32S (PcdHidI2cIntPad, GPIO_CNL_LP_GPP_D10);
+      break;
+  }
+
+  //
+  // PS2 KB Specific Init for Sds Serial platform.
+  //
+  if (BoardId == BoardIdWhiskeyLakeRvp) {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE);
+  } else {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck,  FALSE);
+  }
+
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdSpdAddressOverride, FALSE);
+      break;
+  }
+
+  //
+  // DDISelection
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdDDISelection, 1);
+      break;
+    default:
+      PcdSet8S (PcdDDISelection, 0);
+      break;
+  }
+
+  //
+  // GFX Detect
+  //
+  switch (BoardId) {
+    default:
+      // Not all the boards support GFX_CRB_DET. This is not an error.
+      Data64.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
+      break;
+  }
+
+  PcdSet64S (PcdGfxCrbDetectGpio, Data64.Blob);
+
+  //
+  // USB Type-C
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS(PcdUsbTypeCSupport, TRUE);
+      // Discete Ports
+      PcdSet8S(PcdTypeCPortsSupported, 2);
+      // TBT Port 1  mapping and properties [TBT AIC]
+      PcdSet8S(PcdUsbTypeCPort1, 1);
+      PcdSet8S(PcdUsbTypeCPort1Pch, 5);
+      // TBT Port 2  mapping and properties [TBT AIC]
+      PcdSet8S(PcdUsbTypeCPort2, 2);
+      PcdSet8S(PcdUsbTypeCPort2Pch, 7);
+      break;
+    default:
+      PcdSetBoolS (PcdUsbTypeCSupport, FALSE);
+      break;
+  }
+
+  //
+  // Battery Present
+  //
+  switch (BoardId) {
+  default:
+    PcdSet8S (PcdBatteryPresent, BOARD_REAL_BATTERY_SUPPORTED | BOARD_VIRTUAL_BATTERY_SUPPORTED);
+    break;
+  }
+
+  //
+  // TS-on-DIMM temperature
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdTsOnDimmTemperature, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdTsOnDimmTemperature, FALSE);
+      break;
+  }
+  //
+  // Real Battery 1 Control & Real Battery 2 Control
+  //
+  PcdSet8S (PcdRealBattery1Control, 1);
+  PcdSet8S (PcdRealBattery2Control, 2);
+
+  //
+  // Mipi Camera Sensor
+  //
+  PcdSetBoolS (PcdMipiCamSensor, FALSE);
+  //
+  // Mipi Camera Sensor Link Used
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdMipiCam0LinkUsed, 3);
+      PcdSet8S (PcdMipiCam1LinkUsed, 6);
+      PcdSet8S (PcdMipiCam2LinkUsed, 9);
+      PcdSet8S (PcdMipiCam3LinkUsed, 7);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // H8S2113 SIO
+  //
+  switch(BoardId) {
+    default:
+    PcdSetBoolS (PcdH8S2113SIO, FALSE);
+    break;
+  }
+
+
+  //
+  // NCT6776F COM, SIO & HWMON
+  //
+  PcdSetBoolS (PcdNCT6776FCOM, FALSE);
+  PcdSetBoolS (PcdNCT6776FSIO, FALSE);
+  PcdSetBoolS (PcdNCT6776FHWMON, FALSE);
+
+  //
+  // SMC Runtime Sci Pin
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdSmcRuntimeSciPin, (UINT32) GPIO_CNL_LP_GPP_E16);
+      break;
+    default:
+      PcdSet32S (PcdSmcRuntimeSciPin, 0x00);
+      break;
+  }
+
+  //
+  // Convertable Dock Support
+  //
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdConvertableDockSupport, FALSE);
+      break;
+  }
+
+  //
+  // Ec Hotkey F3, F4, F5, F6, F7 and F8 Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdEcHotKeyF3Support, 1);
+      PcdSet8S (PcdEcHotKeyF4Support, 1);
+      PcdSet8S (PcdEcHotKeyF5Support, 1);
+      PcdSet8S (PcdEcHotKeyF6Support, 1);
+      PcdSet8S (PcdEcHotKeyF7Support, 1);
+      PcdSet8S (PcdEcHotKeyF8Support, 1);
+      break;
+    default:
+      PcdSet8S (PcdEcHotKeyF3Support, 0);
+      PcdSet8S (PcdEcHotKeyF4Support, 0);
+      PcdSet8S (PcdEcHotKeyF5Support, 0);
+      PcdSet8S (PcdEcHotKeyF6Support, 0);
+      PcdSet8S (PcdEcHotKeyF7Support, 0);
+      PcdSet8S (PcdEcHotKeyF8Support, 0);
+      break;
+  }
+
+  //
+  // Virtual Button Volume Up & Done Support
+  // Virtual Button Home Button Support
+  // Virtual Button Rotation Lock Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, TRUE);
+      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, TRUE);
+      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
+      break;
+    default:
+      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
+      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
+      break;
+  }
+
+  //
+  // Slate Mode Switch Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdSlateModeSwitchSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdSlateModeSwitchSupport, FALSE);
+      break;
+  }
+
+  //
+  // Ac Dc Auto Switch Support
+  //
+  switch (BoardId) {
+  default:
+    PcdSetBoolS (PcdAcDcAutoSwitchSupport, TRUE);
+    break;
+  }
+
+  //
+  // Pm Power Button Gpio Pin
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3);
+      break;
+    default:
+      PcdSet32S (PcdPmPowerButtonGpioPin, 0x00);
+      break;
+  }
+
+  //
+  // Acpi Enable All Button Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // Acpi Hid Driver Button Support
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // USB Type C EC less
+  //
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdUsbTypeCEcLess, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check if given rootport has device connected and enable wake capability
+
+  @param[in]  RpNum           An unsigned integer represent the root port number.
+
+  @retval                     TRUE if endpoint was connected
+  @retval                     FALSE if no endpoint was detected
+**/
+BOOLEAN
+IsPcieEndPointPresent (
+  IN UINT8 RpNum
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         RpDev;
+  UINTN         RpFun;
+  UINT64        RpBaseAddress;
+
+  Status = GetPchPcieRpDevFun (RpNum, &RpDev, &RpFun);
+  if (!EFI_ERROR (Status)) {
+    //
+    // check if device is present
+    //
+    RpBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                      DEFAULT_PCI_BUS_NUMBER_PCH,
+                      RpDev,
+                      RpFun,
+                      0
+                      );
+
+    if ((PciSegmentRead16 (RpBaseAddress) != 0xFFFF) &&
+        (PciSegmentRead16 (RpBaseAddress + R_PCH_PCIE_CFG_SLSTS) & B_PCIE_SLSTS_PDS)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+
+}
+
+/**
+  Enable Tier2 GPIO Sci wake capability.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+Tier2GpioWakeSupport (
+  IN UINT16 BoardId
+  )
+{
+  BOOLEAN Tier2GpioWakeEnable;
+
+  Tier2GpioWakeEnable = FALSE;
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // Root port #14: M.2 WLAN
+      //
+      if (IsPcieEndPointPresent (13)) {
+        Tier2GpioWakeEnable = TRUE;
+      }
+      break;
+    default:
+      break;
+  }
+  PcdSetBoolS (PcdGpioTier2WakeEnable, Tier2GpioWakeEnable);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board configuration init function for DXE phase.
+
+  @param  Content  pointer to the buffer contain init information for board init.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+BoardConfigInit (
+    VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT16     BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = InitAcpiPlatformPcd (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = InitCommonPlatformPcd (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = BoardMiscInit (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = Tier2GpioWakeSupport (BoardId);
+  ASSERT_EFI_ERROR(Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
new file mode 100644
index 0000000000..eb7c3bbea0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <CpuPolicyInitDxe.h>
+
+DXE_CPU_POLICY_PROTOCOL mCpuPolicyData;
+
+/**
+  Initialize Intel CPU DXE Platform Policy
+
+  @param[in] ImageHandle        Image handle of this driver.
+
+  @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
+CpuPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS                Status;
+
+  ZeroMem(&mCpuPolicyData, sizeof (DXE_CPU_POLICY_PROTOCOL));
+  mCpuPolicyData.Revision                         = DXE_CPU_POLICY_PROTOCOL_REVISION;
+
+  UpdateDxeSiCpuPolicy(&mCpuPolicyData);
+
+  //
+  // Install CpuInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = CpuInstallPolicyProtocol(ImageHandle, &mCpuPolicyData);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
new file mode 100644
index 0000000000..66aab2d198
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
@@ -0,0 +1,174 @@
+/** @file
+  This file initialises and Installs GopPolicy Protocol.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GopPolicyInitDxe.h"
+#include <Protocol/GopPolicy.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL        mGOPPolicy;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32                     mVbtSize = 0;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS       mVbtAddress = 0;
+
+//
+// Function implementations
+//
+
+/**
+
+  @param[out] CurrentLidStatus
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_UNSUPPORTED
+**/
+
+EFI_STATUS
+EFIAPI
+GetPlatformLidStatus (
+  OUT LID_STATUS *CurrentLidStatus
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+
+  @param[out] CurrentDockStatus
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_UNSUPPORTED
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformDockStatus (
+  OUT DOCK_STATUS  CurrentDockStatus
+  )
+{
+    return EFI_UNSUPPORTED;
+}
+
+
+/**
+
+  @param[out] VbtAddress
+  @param[out] VbtSize
+
+  @retval     EFI_SUCCESS
+  @retval     EFI_NOT_FOUND
+**/
+EFI_STATUS
+EFIAPI
+GetVbtData (
+  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
+  OUT UINT32               *VbtSize
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         FvProtocolCount;
+  EFI_HANDLE                    *FvHandles;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+  UINTN                         Index;
+  UINT32                        AuthenticationStatus;
+  UINT8                         *Buffer;
+  UINTN                         VbtBufferSize;
+
+  Status = EFI_NOT_FOUND;
+  if ( mVbtAddress == 0) {
+    Fv           = NULL;
+    Buffer       = 0;
+    FvHandles    = NULL;
+    Status = gBS->LocateHandleBuffer (
+                    ByProtocol,
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    NULL,
+                    &FvProtocolCount,
+                    &FvHandles
+                    );
+    if (!EFI_ERROR (Status)) {
+      for (Index = 0; Index < FvProtocolCount; Index++) {
+        Status = gBS->HandleProtocol (
+                        FvHandles[Index],
+                        &gEfiFirmwareVolume2ProtocolGuid,
+                        (VOID **) &Fv
+                        );
+        VbtBufferSize = 0;
+        Status = Fv->ReadSection (
+                       Fv,
+                       PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
+                       EFI_SECTION_RAW,
+                       0,
+                       (VOID **) &Buffer,
+                       &VbtBufferSize,
+                       &AuthenticationStatus
+                       );
+        if (!EFI_ERROR (Status)) {
+          *VbtAddress = (EFI_PHYSICAL_ADDRESS)Buffer;
+          *VbtSize = (UINT32)VbtBufferSize;
+          mVbtAddress = *VbtAddress;
+          mVbtSize = *VbtSize;
+          Status = EFI_SUCCESS;
+          break;
+        }
+      }
+    } else {
+      Status = EFI_NOT_FOUND;
+    }
+
+    if (FvHandles != NULL) {
+      FreePool (FvHandles);
+      FvHandles = NULL;
+    }
+  } else {
+    *VbtAddress = mVbtAddress;
+    *VbtSize = mVbtSize;
+    Status = EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+/**
+Initialize GOP DXE Policy
+
+@param[in] ImageHandle          Image handle of this driver.
+
+@retval EFI_SUCCESS             Initialization complete.
+@retval 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
+GopPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Initialize the EFI Driver Library
+  //
+  SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0);
+
+  mGOPPolicy.Revision                = GOP_POLICY_PROTOCOL_REVISION_03;
+  mGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
+  mGOPPolicy.GetVbtData              = GetVbtData;
+  mGOPPolicy.GetPlatformDockStatus   = GetPlatformDockStatus;
+
+  //
+  // Install protocol to allow access to this Policy.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gGopPolicyProtocolGuid,
+                  &mGOPPolicy,
+                  NULL
+                  );
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
new file mode 100644
index 0000000000..2a1604fa13
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
@@ -0,0 +1,55 @@
+/** @file
+  This file is SampleCode for PCH DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchPolicyInitDxe.h"
+
+//
+// Function implementations
+//
+
+/**
+  Initialize PCH DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @retval EFI_SUCCESS             Initialization complete.
+  @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
+PchPolicyInitDxe (
+  IN EFI_HANDLE                   ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+  PCH_POLICY_PROTOCOL      *PchPolicy;
+
+  //
+  // Call CreatePchDxeConfigBlocks to create & initialize platform policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = CreatePchDxeConfigBlocks (&PchPolicy);
+  DEBUG((DEBUG_INFO, "PchPolicy->TableHeader.NumberOfBlocks = 0x%x\n", PchPolicy->TableHeader.NumberOfBlocks));
+  ASSERT_EFI_ERROR (Status);
+
+  if (mFirmwareConfiguration != FwConfigDefault) {
+    UpdateDxePchPolicy (PchPolicy);
+  }
+
+  //
+  // Install PchInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = PchInstallPolicyProtocol (ImageHandle, PchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
new file mode 100644
index 0000000000..ccaa57ce16
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
@@ -0,0 +1,88 @@
+/** @file
+  This file is a wrapper for Platform Policy driver. Get Setup
+  Value to initialize Intel DXE Platform Policy.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PolicyInitDxe.h"
+#include <CpuSmm.h>
+#include "BoardInitLib.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8            mFirmwareConfiguration = 0;
+
+/**
+  Initialize  DXE Platform Policy
+
+  @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
+PolicyInitDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS           Status;
+
+  Status = BoardConfigInit();
+
+  mFirmwareConfiguration = FwConfigProduction;
+  //
+  // SystemAgent Dxe Platform Policy Initialization
+  //
+  Status = SaPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "SystemAgent Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // PCH Dxe Platform Policy Initialization
+  //
+  Status = PchPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "PCH Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Silicon Dxe Platform Policy Initialization
+  //
+  Status = SiliconPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "Silicon Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // CPU DXE Platform Policy Initialization
+  //
+  Status = CpuPolicyInitDxe (ImageHandle);
+  DEBUG ((DEBUG_INFO, "Cpu Dxe Platform Policy Initialization done\n"));
+  ASSERT_EFI_ERROR (Status);
+
+
+  if (PcdGetBool(PcdIntelGopEnable)) {
+    //
+    // GOP Dxe Policy Initialization
+    //
+    Status = GopPolicyInitDxe(ImageHandle);
+    DEBUG((DEBUG_INFO, "GOP Dxe Policy Initialization done\n"));
+    ASSERT_EFI_ERROR(Status);
+  }
+  if (PcdGetBool(PcdTbtEnable)) {
+    //
+    // Update TBT Policy
+    //
+    Status = InstallTbtPolicy (ImageHandle);
+    DEBUG ((DEBUG_INFO, "Install Tbt Policy done\n"));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
new file mode 100644
index 0000000000..c0095c09c3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode for SA DXE Policy initialization.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SaPolicyInitDxe.h"
+
+
+//
+// Function implementations
+//
+
+/**
+  Initialize SA DXE Policy
+
+  @param[in] ImageHandle          Image handle of this driver.
+
+  @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
+SaPolicyInitDxe (
+  IN EFI_HANDLE                   ImageHandle
+  )
+{
+  EFI_STATUS               Status;
+  SA_POLICY_PROTOCOL       *SaPolicy;
+
+  //
+  // Call CreateSaDxeConfigBlocks to create & initialize platform policy structure
+  // and get all Intel default policy settings.
+  //
+  Status = CreateSaDxeConfigBlocks(&SaPolicy);
+  DEBUG((DEBUG_INFO, "SaPolicy->TableHeader.NumberOfBlocks = 0x%x\n ", SaPolicy->TableHeader.NumberOfBlocks));
+  ASSERT_EFI_ERROR(Status);
+
+  UpdateDxeSaPolicyBoardConfig (SaPolicy);
+
+  if (mFirmwareConfiguration != FwConfigDefault) {
+
+    UpdateDxeSaPolicy (SaPolicy);
+  }
+
+  //
+  // Install SaInstallPolicyProtocol.
+  // While installed, RC assumes the Policy is ready and finalized. So please
+  // update and override any setting before calling this function.
+  //
+  Status = SaInstallPolicyProtocol (ImageHandle, SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
new file mode 100644
index 0000000000..15adca5cdd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <SiliconPolicyInitDxe.h>
+#include <Library/BaseLib.h>
+
+DXE_SI_POLICY_PROTOCOL mSiPolicyData  = { 0 };
+
+/**
+  Initilize Intel Cpu DXE Platform Policy
+
+  @param[in] ImageHandle        Image handle of this driver.
+
+  @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
+SiliconPolicyInitDxe (
+  IN EFI_HANDLE       ImageHandle
+  )
+{
+  EFI_STATUS Status;
+
+  mSiPolicyData.Revision                         = DXE_SI_POLICY_PROTOCOL_REVISION;
+
+  ///
+  /// Install the DXE_SI_POLICY_PROTOCOL interface
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gDxeSiPolicyProtocolGuid,
+                  &mSiPolicyData,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
new file mode 100644
index 0000000000..7e44f5585a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
@@ -0,0 +1,20 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+///////////////////////////////////////////////////////////////////////////////////
+//Values are set like this to have ASL compiler reserve enough space for objects
+///////////////////////////////////////////////////////////////////////////////////
+//
+// Available Sleep states
+//
+Name(SS1,0)
+Name(SS2,0)
+Name(SS3,1)
+Name(SS4,1)
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
new file mode 100644
index 0000000000..dd85f07bd2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
@@ -0,0 +1,37 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformBoardId.h"
+
+DefinitionBlock (
+  "DSDT.aml",
+  "DSDT",
+  0x02, // DSDT revision.
+        // A Revision field value greater than or equal to 2 signifies that integers
+        // declared within the Definition Block are to be evaluated as 64-bit values
+  "INTEL",   // OEM ID (6 byte string)
+  "WHL     ",// OEM table ID  (8 byte string)
+  0x0 // OEM version of DSDT table (4 byte Integer)
+)
+
+// BEGIN OF ASL SCOPE
+{
+  // Miscellaneous services enabled in Project
+  Include ("AMLUPD.asl")
+  Include ("PciTree.asl")
+  Include ("Platform.asl")
+
+  Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state
+  if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})}
+  if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})}
+  if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})}
+  Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state
+
+}// End of ASL File
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
new file mode 100644
index 0000000000..aa302b6e3b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
@@ -0,0 +1,516 @@
+/** @file
+  This file contains the SystemAgent PCI Configuration space
+  definition.
+  It defines various System Agent PCI Configuration Space registers
+  which will be used to dynamically produce all resources in the Host Bus.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Define various System Agent (SA) PCI Configuration Space
+// registers which will be used to dynamically produce all
+// resources in the Host Bus _CRS.
+//
+OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
+Field (HBUS, DWordAcc, NoLock, Preserve)
+{
+  Offset(0x40),   // EPBAR (0:0:0:40)
+  EPEN, 1,        // Enable
+      , 11,
+  EPBR, 20,       // EPBAR [31:12]
+
+  Offset(0x48),   // MCHBAR (0:0:0:48)
+  MHEN, 1,        // Enable
+      , 14,
+  MHBR, 17,       // MCHBAR [31:15]
+
+  Offset(0x50),   // GGC (0:0:0:50)
+  GCLK, 1,        // GGCLCK
+
+  Offset(0x54),   // DEVEN (0:0:0:54)
+  D0EN, 1,        // DEV0 Enable
+  D1F2, 1,        // DEV1 FUN2 Enable
+  D1F1, 1,        // DEV1 FUN1 Enable
+  D1F0, 1,        // DEV1 FUN0 Enable
+
+  Offset(0x60),   // PCIEXBAR (0:0:0:60)
+  PXEN, 1,        // Enable
+  PXSZ, 2,        // PCI Express Size
+      , 23,
+  PXBR, 6,        // PCI Express BAR [31:26]
+
+  Offset(0x68),   // DMIBAR (0:0:0:68)
+  DIEN, 1,        // Enable
+      , 11,
+  DIBR, 20,       // DMIBAR [31:12]
+
+  Offset(0x70),   // MESEG_BASE (0:0:0:70)
+      , 20,
+  MEBR, 12,       // MESEG_BASE [31:20]
+
+  Offset(0x80),   // PAM0 Register (0:0:0:80)
+  PMLK, 1,        // PAM Lock bit.
+      , 3,
+  PM0H, 2,        // PAM 0, High Nibble
+      , 2,
+
+  Offset(0x81),   // PAM1 Register (0:0:0:81)
+  PM1L, 2,        // PAM1, Low  Nibble
+      , 2,
+  PM1H, 2,        // PAM1, High Nibble
+      , 2,
+
+  Offset(0x82),   // PAM2 Register (0:0:0:82)
+  PM2L, 2,        // PAM2, Low  Nibble
+      , 2,
+  PM2H, 2,        // PAM2, High Nibble
+      , 2,
+
+  Offset(0x83),   // PAM3 Register (0:0:0:83)
+  PM3L, 2,        // PAM3, Low  Nibble
+      , 2,
+  PM3H, 2,        // PAM3, High Nibble
+      , 2,
+
+  Offset(0x84),   // PAM4 Register (0:0:0:84)
+  PM4L, 2,        // PAM4, Low  Nibble
+      , 2,
+  PM4H, 2,        // PAM4, High Nibble
+      , 2,
+
+  Offset(0x85),   // PAM5 Register (0:0:0:85)
+  PM5L, 2,        // PAM5, Low  Nibble
+      , 2,
+  PM5H, 2,        // PAM5, High Nibble
+      , 2,
+
+  Offset(0x86),   // PAM6 Register (0:0:0:86)
+  PM6L, 2,        // PAM6, Low  Nibble
+      , 2,
+  PM6H, 2,        // PAM6, High Nibble
+      , 2,
+
+  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
+      , 20,
+  TUUD, 19,       // TOUUD [38:20]
+
+  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
+      , 20,
+  TLUD, 12,       // TOLUD [31:20]
+
+  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
+      , 7,
+  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
+}
+
+//
+// Define a buffer that will store all the bus, memory, and IO information
+// relating to the Host Bus.  This buffer will be dynamically altered in
+// the _CRS and passed back to the OS.
+//
+Name(BUF0,ResourceTemplate()
+{
+  //
+  // Bus Number Allocation: Bus 0 to 0xFF
+  //
+  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
+    0x0000,0x00FF,0x00,0x0100,,,PB00)
+
+  //
+  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
+
+  //
+  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
+  //
+  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
+
+  //
+  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
+  //
+  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
+    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
+
+  //
+  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
+
+  //
+  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
+
+  //
+  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
+
+  //
+  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
+
+  //
+  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
+
+  //
+  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
+
+  //
+  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
+
+  //
+  // BIOS Area ( 0xF0000 - 0xFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
+
+//  //
+//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
+//  //
+//  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
+//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
+
+  //
+  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
+
+  //
+  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
+  // (This is dummy range for OS compatibility, will patch it in _CRS)
+  //
+  QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
+})
+
+Name(EP_B, 0) // to store EP BAR
+Name(MH_B, 0) // to store MCH BAR
+Name(PC_B, 0) // to store PCIe BAR
+Name(PC_L, 0) // to store PCIe BAR Length
+Name(DM_B, 0) // to store DMI BAR
+
+//
+// Get EP BAR
+//
+Method(GEPB,0,Serialized)
+{
+  if(LEqual(EP_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
+  }
+  Return(EP_B)
+}
+
+//
+// Get MCH BAR
+//
+Method(GMHB,0,Serialized)
+{
+  if(LEqual(MH_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
+  }
+  Return(MH_B)
+}
+
+//
+// Get PCIe BAR
+//
+Method(GPCB,0,Serialized)
+{
+  if(LEqual(PC_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
+  }
+  Return(PC_B)
+}
+
+//
+// Get PCIe Length
+//
+Method(GPCL,0,Serialized)
+{
+  if(LEqual(PC_L,0)) {
+    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
+  }
+  Return(PC_L)
+}
+
+//
+// Get DMI BAR
+//
+Method(GDMB,0,Serialized)
+{
+  if(LEqual(DM_B,0))
+  {
+    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
+  }
+  Return(DM_B)
+}
+
+
+Method(_CRS,0,Serialized)
+{
+  //
+  // Fix up Max Bus Number and Length
+  //
+  Store(\_SB.PCI0.GPCL(),Local0)
+  CreateWordField(BUF0, ^PB00._MAX, PBMX)
+  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
+  CreateWordField(BUF0, ^PB00._LEN, PBLN)
+  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
+  //
+  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
+  //
+  If(PM1L)  // \_SB.PCI0
+  {
+    // PAMx != 0.  Set length = 0.
+
+    CreateDwordField(BUF0, ^C000._LEN,C0LN)
+    Store(Zero,C0LN)
+  }
+
+  If(LEqual(PM1L,1))
+  {
+    CreateBitField(BUF0, ^C000._RW,C0RW)
+    Store(Zero,C0RW)
+  }
+
+  If(PM1H)
+  {
+    CreateDwordField(BUF0, ^C400._LEN,C4LN)
+    Store(Zero,C4LN)
+  }
+
+  If(LEqual(PM1H,1))
+  {
+    CreateBitField(BUF0, ^C400._RW,C4RW)
+    Store(Zero,C4RW)
+  }
+
+  If(PM2L)
+  {
+    CreateDwordField(BUF0, ^C800._LEN,C8LN)
+    Store(Zero,C8LN)
+  }
+
+  If(LEqual(PM2L,1))
+  {
+    CreateBitField(BUF0, ^C800._RW,C8RW)
+    Store(Zero,C8RW)
+  }
+
+  If(PM2H)
+  {
+    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
+    Store(Zero,CCLN)
+  }
+
+  If(LEqual(PM2H,1))
+  {
+    CreateBitField(BUF0, ^CC00._RW,CCRW)
+    Store(Zero,CCRW)
+  }
+
+  If(PM3L)
+  {
+    CreateDwordField(BUF0, ^D000._LEN,D0LN)
+    Store(Zero,D0LN)
+  }
+
+  If(LEqual(PM3L,1))
+  {
+    CreateBitField(BUF0, ^D000._RW,D0RW)
+    Store(Zero,D0RW)
+  }
+
+  If(PM3H)
+  {
+    CreateDwordField(BUF0, ^D400._LEN,D4LN)
+    Store(Zero,D4LN)
+  }
+
+  If(LEqual(PM3H,1))
+  {
+    CreateBitField(BUF0, ^D400._RW,D4RW)
+    Store(Zero,D4RW)
+  }
+
+  If(PM4L)
+  {
+    CreateDwordField(BUF0, ^D800._LEN,D8LN)
+    Store(Zero,D8LN)
+  }
+
+  If(LEqual(PM4L,1))
+  {
+    CreateBitField(BUF0, ^D800._RW,D8RW)
+    Store(Zero,D8RW)
+  }
+
+  If(PM4H)
+  {
+    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
+    Store(Zero,DCLN)
+  }
+
+  If(LEqual(PM4H,1))
+  {
+    CreateBitField(BUF0, ^DC00._RW,DCRW)
+    Store(Zero,DCRW)
+  }
+
+  If(PM5L)
+  {
+    CreateDwordField(BUF0, ^E000._LEN,E0LN)
+    Store(Zero,E0LN)
+  }
+
+  If(LEqual(PM5L,1))
+  {
+    CreateBitField(BUF0, ^E000._RW,E0RW)
+    Store(Zero,E0RW)
+  }
+
+  If(PM5H)
+  {
+    CreateDwordField(BUF0, ^E400._LEN,E4LN)
+    Store(Zero,E4LN)
+  }
+
+  If(LEqual(PM5H,1))
+  {
+    CreateBitField(BUF0, ^E400._RW,E4RW)
+    Store(Zero,E4RW)
+  }
+
+  If(PM6L)
+  {
+    CreateDwordField(BUF0, ^E800._LEN,E8LN)
+    Store(Zero,E8LN)
+  }
+
+  If(LEqual(PM6L,1))
+  {
+    CreateBitField(BUF0, ^E800._RW,E8RW)
+    Store(Zero,E8RW)
+  }
+
+  If(PM6H)
+  {
+    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
+    Store(Zero,ECLN)
+  }
+
+  If(LEqual(PM6H,1))
+  {
+    CreateBitField(BUF0, ^EC00._RW,ECRW)
+    Store(Zero,ECRW)
+  }
+
+  If(PM0H)
+  {
+    CreateDwordField(BUF0, ^F000._LEN,F0LN)
+    Store(Zero,F0LN)
+  }
+
+  If(LEqual(PM0H,1))
+  {
+    CreateBitField(BUF0, ^F000._RW,F0RW)
+    Store(Zero,F0RW)
+  }
+
+  //
+  // Create pointers to Memory Sizing values.
+  //
+  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
+  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
+  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
+
+  //
+  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
+  // TOM, so shift these bits into the correct position and fix up
+  // the Memory Region available to PCI.
+  //
+  Store (0x50800000, M1LN)
+  Store (0x8F800000, M1MN)
+  Subtract (Add (M1MN, M1LN), 1, M1MX)
+
+  //
+  // Create pointers to Memory Sizing values.
+  // Patch PM02 range basing on memory size and OS type
+  //
+  CreateQwordField(BUF0, ^PM02._LEN,MSLN)
+  //
+  // Set resource length to 0
+  //
+  Store (0, MSLN)
+
+  D8XH (0, 0xC5)
+  D8XH (1, 0xAA)
+
+  Return(BUF0)
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
new file mode 100644
index 0000000000..ff3b0dbe08
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
@@ -0,0 +1,309 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Scope(\_SB) {
+  Name(PD00, Package(){
+// If the setting changed in PCH PxRcConfig policy, platform should also update static assignment here.
+// PCI Bridge
+// D31: cAVS, SMBus, GbE, Nothpeak
+    Package(){0x001FFFFF, 0, 0, 11 },
+    Package(){0x001FFFFF, 1, 0, 10 },
+    Package(){0x001FFFFF, 2, 0, 11 },
+    Package(){0x001FFFFF, 3, 0, 11 },
+// D30: SerialIo and SCS - can't use PIC
+// D29: PCI Express Port 9-16
+    Package(){0x001DFFFF, 0, 0, 11 },
+    Package(){0x001DFFFF, 1, 0, 10 },
+    Package(){0x001DFFFF, 2, 0, 11 },
+    Package(){0x001DFFFF, 3, 0, 11 },
+// D28: PCI Express Port 1-8
+    Package(){0x001CFFFF, 0, 0, 11 },
+    Package(){0x001CFFFF, 1, 0, 10 },
+    Package(){0x001CFFFF, 2, 0, 11 },
+    Package(){0x001CFFFF, 3, 0, 11 },
+// D27: PCI Express Port 17-20
+    Package(){0x001BFFFF, 0, 0, 11 },
+    Package(){0x001BFFFF, 1, 0, 10 },
+    Package(){0x001BFFFF, 2, 0, 11 },
+    Package(){0x001BFFFF, 3, 0, 11 },
+// D25: SerialIo - can't use PIC
+// D23: SATA controller
+    Package(){0x0017FFFF, 0, 0, 11 },
+// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
+    Package(){0x0016FFFF, 0, 0, 11 },
+    Package(){0x0016FFFF, 1, 0, 10 },
+    Package(){0x0016FFFF, 2, 0, 11 },
+    Package(){0x0016FFFF, 3, 0, 11 },
+// D21: SerialIo - can't use PIC
+// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
+// D20: xHCI, OTG, CNVi WiFi, SDcard
+    Package(){0x0014FFFF, 0, 0, 11 },
+    Package(){0x0014FFFF, 1, 0, 10 },
+    Package(){0x0014FFFF, 2, 0, 11 },
+    Package(){0x0014FFFF, 3, 0, 11 },
+// D19: Integrated Sensor Hub - can't use PIC
+// D18: Thermal, UFS, SerialIo SPI2 - can't use PIC
+    Package(){0x0012FFFF, 0, 0, 11 },
+    Package(){0x0012FFFF, 1, 0, 10 },
+    Package(){0x0012FFFF, 2, 0, 11 },
+    Package(){0x0012FFFF, 3, 0, 11 },
+
+// Host Bridge
+// P.E.G. Root Port D1F0
+    Package(){0x0001FFFF, 0, 0, 11 },
+    Package(){0x0001FFFF, 1, 0, 10 },
+    Package(){0x0001FFFF, 2, 0, 11 },
+    Package(){0x0001FFFF, 3, 0, 11 },
+// P.E.G. Root Port D1F1
+// P.E.G. Root Port D1F2
+// SA IGFX Device
+    Package(){0x0002FFFF, 0, 0, 11 },
+// SA Thermal Device
+    Package(){0x0004FFFF, 0, 0, 11 },
+// SA IPU Device
+    Package(){0x0005FFFF, 0, 0, 11 },
+// SA GNA Device
+    Package(){0x0008FFFF, 0, 0, 11 },
+  })
+  Name(AR00, Package(){
+// PCI Bridge
+// D31: cAVS, SMBus, GbE, Nothpeak
+    Package(){0x001FFFFF, 0, 0, 16 },
+    Package(){0x001FFFFF, 1, 0, 17 },
+    Package(){0x001FFFFF, 2, 0, 18 },
+    Package(){0x001FFFFF, 3, 0, 19 },
+// D30: SerialIo and SCS
+    Package(){0x001EFFFF, 0, 0, 20 },
+    Package(){0x001EFFFF, 1, 0, 21 },
+    Package(){0x001EFFFF, 2, 0, 22 },
+    Package(){0x001EFFFF, 3, 0, 23 },
+// D29: PCI Express Port 9-16
+    Package(){0x001DFFFF, 0, 0, 16 },
+    Package(){0x001DFFFF, 1, 0, 17 },
+    Package(){0x001DFFFF, 2, 0, 18 },
+    Package(){0x001DFFFF, 3, 0, 19 },
+// D28: PCI Express Port 1-8
+    Package(){0x001CFFFF, 0, 0, 16 },
+    Package(){0x001CFFFF, 1, 0, 17 },
+    Package(){0x001CFFFF, 2, 0, 18 },
+    Package(){0x001CFFFF, 3, 0, 19 },
+// D27: PCI Express Port 17-20
+    Package(){0x001BFFFF, 0, 0, 16 },
+    Package(){0x001BFFFF, 1, 0, 17 },
+    Package(){0x001BFFFF, 2, 0, 18 },
+    Package(){0x001BFFFF, 3, 0, 19 },
+// D26: eMMC
+    Package(){0x001AFFFF, 0, 0, 16 },
+    Package(){0x001AFFFF, 1, 0, 17 },
+    Package(){0x001AFFFF, 2, 0, 18 },
+    Package(){0x001AFFFF, 3, 0, 19 },
+// D25: SerialIo
+    Package(){0x0019FFFF, 0, 0, 32 },
+    Package(){0x0019FFFF, 1, 0, 33 },
+    Package(){0x0019FFFF, 2, 0, 34 },
+// D23: SATA controller
+    Package(){0x0017FFFF, 0, 0, 16 },
+// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
+    Package(){0x0016FFFF, 0, 0, 16 },
+    Package(){0x0016FFFF, 1, 0, 17 },
+    Package(){0x0016FFFF, 2, 0, 18 },
+    Package(){0x0016FFFF, 3, 0, 19 },
+// D21: SerialIo
+    Package(){0x0015FFFF, 0, 0, 16 },
+    Package(){0x0015FFFF, 1, 0, 17 },
+    Package(){0x0015FFFF, 2, 0, 18 },
+    Package(){0x0015FFFF, 3, 0, 19 },
+// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
+// D20: xHCI, OTG, CNVi WiFi, SDcard
+    Package(){0x0014FFFF, 0, 0, 16 },
+    Package(){0x0014FFFF, 1, 0, 17 },
+    Package(){0x0014FFFF, 2, 0, 18 },
+    Package(){0x0014FFFF, 3, 0, 19 },
+// D19: Integrated Sensor Hub
+    Package(){0x0013FFFF, 0, 0, 20 },
+// D18: Thermal, UFS, SerialIo SPI 2
+    Package(){0x0012FFFF, 0, 0, 16 },
+    Package(){0x0012FFFF, 1, 0, 24 },
+    Package(){0x0012FFFF, 2, 0, 18 },
+    Package(){0x0012FFFF, 3, 0, 19 },
+
+// Host Bridge
+// P.E.G. Root Port D1F0
+    Package(){0x0001FFFF, 0, 0, 16 },
+    Package(){0x0001FFFF, 1, 0, 17 },
+    Package(){0x0001FFFF, 2, 0, 18 },
+    Package(){0x0001FFFF, 3, 0, 19 },
+// P.E.G. Root Port D1F1
+// P.E.G. Root Port D1F2
+// SA IGFX Device
+    Package(){0x0002FFFF, 0, 0, 16 },
+// SA Thermal Device
+    Package(){0x0004FFFF, 0, 0, 16 },
+// SA IPU Device
+    Package(){0x0005FFFF, 0, 0, 16 },
+// SA GNA Device
+    Package(){0x0008FFFF, 0, 0, 16 },
+  })
+  Name(PD04, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR04, Package(){
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD05, Package(){
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR05, Package(){
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD06, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR06, Package(){
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+  Name(PD07, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 10 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR07, Package(){
+    Package(){0x0000FFFF, 0, 0, 19 },
+    Package(){0x0000FFFF, 1, 0, 16 },
+    Package(){0x0000FFFF, 2, 0, 17 },
+    Package(){0x0000FFFF, 3, 0, 18 },
+  })
+  Name(PD08, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR08, Package(){
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD09, Package(){
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR09, Package(){
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD0E, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR0E, Package(){
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+  Name(PD0F, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 10 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR0F, Package(){
+    Package(){0x0000FFFF, 0, 0, 19 },
+    Package(){0x0000FFFF, 1, 0, 16 },
+    Package(){0x0000FFFF, 2, 0, 17 },
+    Package(){0x0000FFFF, 3, 0, 18 },
+  })
+  Name(PD02, Package(){
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 10 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR02, Package(){
+// P.E.G. Port Slot x16
+    Package(){0x0000FFFF, 0, 0, 16 },
+    Package(){0x0000FFFF, 1, 0, 17 },
+    Package(){0x0000FFFF, 2, 0, 18 },
+    Package(){0x0000FFFF, 3, 0, 19 },
+  })
+  Name(PD0A, Package(){
+// P.E.G. Port Slot x8
+    Package(){0x0000FFFF, 0, 0, 10 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 11 },
+  })
+  Name(AR0A, Package(){
+// P.E.G. Port Slot x8
+    Package(){0x0000FFFF, 0, 0, 17 },
+    Package(){0x0000FFFF, 1, 0, 18 },
+    Package(){0x0000FFFF, 2, 0, 19 },
+    Package(){0x0000FFFF, 3, 0, 16 },
+  })
+  Name(PD0B, Package(){
+// P.E.G. Port Slot x4
+    Package(){0x0000FFFF, 0, 0, 11 },
+    Package(){0x0000FFFF, 1, 0, 11 },
+    Package(){0x0000FFFF, 2, 0, 11 },
+    Package(){0x0000FFFF, 3, 0, 10 },
+  })
+  Name(AR0B, Package(){
+// P.E.G. Port Slot x4
+    Package(){0x0000FFFF, 0, 0, 18 },
+    Package(){0x0000FFFF, 1, 0, 19 },
+    Package(){0x0000FFFF, 2, 0, 16 },
+    Package(){0x0000FFFF, 3, 0, 17 },
+  })
+
+//---------------------------------------------------------------------------
+// Begin PCI tree object scope
+//---------------------------------------------------------------------------
+  Device(PCI0) { // PCI Bridge "Host Bridge"
+    Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2 host hierarchy
+    Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't understand the new HID
+    Name(_SEG, 0)
+    Name(_ADR, 0x00000000)
+    Method(^BN00, 0){ return(0x0000) }  // Returns default Bus number for Peer PCI busses. Name can be overriden with control method placed directly under Device scope
+    Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root PCI Bus
+    Name(_UID, 0x0000)  // Unique Bus ID, optional
+    Method(_PRT,0) {
+      If(PICM) {Return(AR00)} // APIC mode
+      Return (PD00) // PIC Mode
+    } // end _PRT
+
+  Include("HostBus.asl")
+  } // end PCI0 Bridge "Host Bridge"
+} // end _SB scope
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
new file mode 100644
index 0000000000..951c01455f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
@@ -0,0 +1,76 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+// Define Port 80 as an ACPI Operating Region to use for debugging.  Please
+// note that the Intel CRBs have the ability to ouput a Word to
+// Port 80h for debugging purposes, so the model implemented here may not be
+// able to be used on OEM Designs.
+
+OperationRegion(PRT0,SystemIO,0x80,2)
+Field(PRT0,WordAcc,Lock,Preserve)
+{
+  P80B, 16
+}
+
+// Port 80h Update:
+//    Update 2 bytes of Port 80h.
+//
+//  Arguments:
+//    Arg0: 0 = Write Port 80h
+//          1 = Write Port 81h
+//    Arg1: 8-bit Value to write
+//
+//  Return Value:
+//    None
+
+Name(P80T, 0) // temp buffer for P80
+
+Method(D8XH,2,Serialized)
+{
+  If(LEqual(Arg0,0))    // Write Port 80h
+  {
+    Store(Or(And(P80T,0xFF00),Arg1),P80T)
+  }
+  If(LEqual(Arg0,1))    // Write Port 81h
+  {
+    Store(Or(And(P80T,0x00FF),ShiftLeft(Arg1,8)),P80T)
+  }
+  Store(P80T,P80B)
+}
+
+//
+// Define SW SMI port as an ACPI Operating Region to use for generate SW SMI.
+//
+OperationRegion(SPRT,SystemIO, 0xB2,2)
+Field (SPRT, ByteAcc, Lock, Preserve) {
+  SSMP, 8
+}
+
+// The _PIC Control Method is optional for ACPI design.  It allows the
+// OS to inform the ASL code which interrupt controller is being used,
+// the 8259 or APIC.  The reference code in this document will address
+// PCI IRQ Routing and resource allocation for both cases.
+//
+// The values passed into _PIC are:
+//   0 = 8259
+//   1 = IOAPIC
+
+Method(\_PIC,1)
+{
+  Store(Arg0,PICM)
+}
+
+Scope (\)
+{
+  //
+  // Global Name, returns current Interrupt controller mode;
+  // updated from _PIC control method
+  //
+  Name(PICM, 0)
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
new file mode 100644
index 0000000000..38d60d6dbd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
@@ -0,0 +1,405 @@
+/** @file
+  ACPI RTD3 SSDT table for SPT PCIe
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#define PID_ICC                                   0xDC
+#define R_PCH_PCR_ICC_MSKCKRQ                     0x100C                  ///< Mask Control CLKREQ
+
+External(PCRA,MethodObj)
+External(PCRO,MethodObj)
+External(\MMRP, MethodObj)
+External(\MMTB, MethodObj)
+External(\TRDO, IntObj)
+External(\TRD3, IntObj)
+External(\TBPE, IntObj)
+External(\TOFF, IntObj)
+External(\TBSE, IntObj)
+External(\TBOD, IntObj)
+External(\TBRP, IntObj)
+External(\TBHR, IntObj)
+External(\RTBC, IntObj)
+External(\TBCD, IntObj)
+
+Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
+
+Name(WKEN, 0)
+
+  Method(_S0W, 0)
+  {
+  /// This method returns the lowest D-state supported by PCIe root port during S0 state
+
+   ///- PMEs can be generated from D3hot for ULT
+      Return(4)
+
+  /** @defgroup pcie_s0W PCIE _S0W **/
+  } // End _S0W
+
+  Method (_DSD, 0) {
+    Return (
+      Package () {
+        ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
+        Package () {
+          Package (2) {"HotPlugSupportInD3", 1},
+        }
+      }
+    ) // End of Return ()
+  }
+
+    Method(_DSW, 3)
+    {
+    /// This method is used to enable/disable wake from PCIe (WKEN)
+      If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE# from generating runtime PME
+                                    /// Also set 2 to TOFF.
+        Store(0, WKEN)
+        Store (2, TOFF)
+      } Else {  /// If Staying in S0
+        If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
+        { ///- Set PME
+          Store(1, WKEN)
+          Store (1, TOFF)
+        } Else { ///- Disable runtime PME, either because staying in D0 or disabling wake
+          Store(0, WKEN)
+          Store(0, TOFF)
+        }
+      }
+
+    /** @defgroup pcie_dsw PCIE _DSW **/
+    } // End _DSW
+
+
+    PowerResource(PXP, 0, 0)
+    {
+    /// Define the PowerResource for PCIe slot
+    /// Method: _STA(), _ON(), _OFF()
+    /** @defgroup pcie_pxp PCIE Power Resource **/
+
+      Method(_STA, 0)
+      {
+          Return(PSTA())
+      }  /** @defgroup pcie_sta PCIE _STA method **/
+
+      Method(_ON) /// Turn on core power to PCIe Slot
+      {
+        Store(1, TRDO)
+        PON()
+        Store(0, TRDO)
+      } /** @defgroup pcie_on PCIE _ON method **/
+
+      Method(_OFF) /// Turn off core power to PCIe Slot
+      {
+        Store(1, TRD3)
+        POFF()
+        Store(0, TRD3)
+      } // End of Method_OFF
+    } // End PXP
+
+    Method(PSTA, 0)
+    {
+    /// Returns the status of PCIe slot core power
+      // detect power pin status
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) {
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          if(LEqual(\_SB.GGOV(DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // GPIO mode
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // IOEX mode
+      }
+      // detect reset pin status
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) {
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          if(LEqual(\_SB.GGOV(DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // GPIO mode
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2))  { // IOEX mode
+          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+            Return (1)
+          } Else {
+            Return (0)
+          }
+        } // IOEX mode
+      }
+      Return (0)
+    }  /** @defgroup pcie_sta PCIE _STA method **/
+
+    Method (SXEX, 0, Serialized) {
+
+      Store(\MMTB(TBSE), Local7)
+      OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(100, Local1)
+      Store(0x09, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT
+      While (LGreater(Local1, 0)) {
+
+        Store(Subtract(Local1, 1), Local1)
+        Store(TB2P, Local2)
+        If (LEqual(Local2, 0xFFFFFFFF)) { // Device gone
+          Return()
+        }
+        If (And(Local2, 1)) { // Done
+          break
+        }
+        Sleep(5)
+      }
+      Store(0x0, P2TB) // Write 0 to PCIe2TBT
+
+      // Fast Link bring-up flow
+      Store(500, Local1)
+      While (LGreater(Local1, 0)) {
+        Store(Subtract(Local1, 1), Local1)
+        Store(TB2P, Local2)
+        If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
+          Return()
+        }
+        If (LNotEqual(DIVI, 0xFFFFFFFF)) {
+          break
+        }
+        Sleep(10)
+      }
+    } // End of Method(SXEX, 0, Serialized)
+
+    Method(PON) /// Turn on core power to PCIe Slot
+    {
+
+      Store(\MMRP(\TBSE), Local7)
+      OperationRegion(L23P,SystemMemory,Local7,0xE4)
+      Field(L23P,WordAcc, NoLock, Preserve)
+      {
+        Offset(0xA4),// PMCSR
+        PSD0, 2, // PowerState
+        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+        , 2,
+        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
+        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+      }
+
+      Store(\MMTB(\TBSE), Local6)
+      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0xA4),
+        TBPS, 2, // PowerState of TBT
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(0, TOFF)
+      // Check RTD3 power enable, if already ON, no need to execute sx_exit
+      If (TBPE) {
+        Return()
+      }
+
+      Store(0,G2SD)
+      If (\RTBC) {
+        /// de-assert CLK_REQ MSK
+        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+          PCRA(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,Not(DeRefOf(Index(SCLK, 1))))  // And ~SCLK to clear bit
+        }
+        Sleep(\TBCD)
+      }
+
+      /// Turn ON Power for PCIe Slot
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+          Store(1, TBPE)
+          Sleep(PEP0)     /// Sleep for programmable delay
+        }
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+          Store(1, TBPE)
+          Sleep(PEP0)     /// Sleep for programmable delay
+        }
+      }
+
+      /// De-Assert Reset Pin
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+        }
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+        }
+      }
+
+      /// Clear DLSULPPGE, then set L23_Rdy to Detect Transition  (L23R2DT)
+      Store(0, DPGE)
+      Store(1, L2TR)
+      Sleep(16)
+      Store(0, Local0)
+      /// Wait up to 12 ms for transition to Detect
+      While(L2TR) {
+        If(Lgreater(Local0, 4))    // Debug - Wait for 5 ms
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      /// 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(1, DPGE)
+      Store(0, Local0)
+      While(LEqual(LASX,0)) {
+        If(Lgreater(Local0, 8))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(0, LEDM) /// Set PCIEDBG.DMIL1EDM (324[3]) = 0
+
+      // TBT special sleep.
+      Store(PSD0, Local1)
+      Store(0, PSD0)// D0
+      Store(20, Local2) // Poll for TBT, up to 200 ms
+
+      While (LGreater(Local2, 0)) {
+        Store(Subtract(Local2, 1), Local2)
+        Store(TB2P, Local3)
+        If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
+          break
+        }
+        Sleep(10)
+      }
+
+      If (LLessEqual(Local2, 0)) {
+      }
+      SXEX()
+      Store(Local1, PSD0) // Back to Local1
+    } /** @defgroup pcie_on PCIE _ON method **/
+
+    Method(POFF) { /// Turn off core power to PCIe Slot
+      If (LEqual(TOFF, 0)) {
+        Return()
+      }
+      Store(\MMRP(\TBSE), Local7)
+      OperationRegion(L23P, SystemMemory, Local7, 0xE4)
+      Field(L23P,WordAcc, NoLock, Preserve)
+      {
+        Offset(0xA4),// PMCSR
+        PSD0, 2, // PowerState
+        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+        , 2,
+        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
+        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+      }
+
+      Store(\MMTB(TBSE), Local6)
+      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+      Field(TBDI,DWordAcc, NoLock, Preserve) {
+        DIVI, 32,
+        CMDR, 32,
+        Offset(0xA4),
+        TBPS, 2, // PowerState of TBT
+        Offset(0x548),
+        TB2P, 32,
+        P2TB, 32
+      }
+
+      Store(PSD0, Local1)
+      Store(0, PSD0)// D0
+
+      Store(P2TB, Local3)
+
+      If (Lgreater(TOFF, 1)) {
+        Sleep(10)
+        Store(Local1, PSD0) // Back to Local1
+        Return()
+      }
+      Store(0, TOFF)
+
+      Store(Local1, PSD0) // Back to Local1
+
+      /// Set L23_Rdy Entry Request (L23ER)
+      Store(1, L2TE)
+      Sleep(16)
+      Store(0, Local0)
+      While(L2TE) {
+        If(Lgreater(Local0, 4))    /// Debug - Wait for 5 ms
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(1, LEDM) /// PCIEDBG.DMIL1EDM (324[3]) = 1
+
+      /// Assert Reset Pin
+      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+        }
+        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+        }
+      }
+      If (\RTBC) {
+        /// assert CLK_REQ MSK
+        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+          PCRO(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,DeRefOf(Index(SCLK, 1)))    // Or SCLK to set bit
+          Sleep(16)
+        }
+      }
+
+      /// Power OFF for TBT
+      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+        }
+        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
+          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+        }
+      }
+
+      Store(0, TBPE)
+
+      Store(1, LDIS) /// Set Link Disable
+      Store(0, LDIS) /// Toggle link disable
+
+      /// enable WAKE
+      If (WKEN) {
+        If (LNotEqual(DeRefOf(Index(WAKG, 0)),0)) { // if power gating enabled
+          If (LEqual(DeRefOf(Index(WAKG, 0)),1)) { // GPIO mode
+            \_SB.SGOV(DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+            \_SB.SHPO(DeRefOf(Index(WAKG, 2)), 0) // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+          }
+          If (LEqual(DeRefOf(Index(WAKG, 0)),2))  { // IOEX mode
+            \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG, 1)),DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+          }
+        }
+      }
+      Sleep(\TBOD)
+      /** @defgroup pcie_off PCIE _OFF method **/
+    } // End of Method_OFF
+
+    Name(_PR0, Package(){PXP})
+    Name(_PR3, Package(){PXP})
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
new file mode 100644
index 0000000000..66584c21c5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
@@ -0,0 +1,1877 @@
+/** @file
+ Thunderbolt ACPI methods
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#define DTBT_CONTROLLER                   0x00
+#define DTBT_TYPE_PCH                     0x01
+#define DTBT_TYPE_PEG                     0x02
+#define DTBT_SMI_HANDLER_NUMBER           0xF7
+#define TBT_SMI_ENUMERATION_FUNCTION      21
+#define TBT_SMI_RESET_SWITCH_FUNCTION     22
+#define TBT_SMI_DISABLE_MSI_FUNCTION      23
+#ifndef  BIT29
+#define  BIT29    0x20000000
+#endif
+
+Name(LDLY, 300) //300 ms
+Name (TNVB, 0xFFFF0000)  // TBT NVS Base address
+Name (TNVL, 0xAA55)      // TBT NVS Length
+Include ("Acpi/TbtNvs.asl")
+
+External(\_SB.PCI0.RP02.L23D, MethodObj)
+External(\_SB.PCI0.RP03.L23D, MethodObj)
+External(\_SB.PCI0.RP04.L23D, MethodObj)
+External(\_SB.PCI0.RP05.L23D, MethodObj)
+External(\_SB.PCI0.RP06.L23D, MethodObj)
+External(\_SB.PCI0.RP07.L23D, MethodObj)
+External(\_SB.PCI0.RP08.L23D, MethodObj)
+External(\_SB.PCI0.RP09.L23D, MethodObj)
+External(\_SB.PCI0.RP10.L23D, MethodObj)
+External(\_SB.PCI0.RP11.L23D, MethodObj)
+External(\_SB.PCI0.RP12.L23D, MethodObj)
+External(\_SB.PCI0.RP13.L23D, MethodObj)
+External(\_SB.PCI0.RP14.L23D, MethodObj)
+External(\_SB.PCI0.RP15.L23D, MethodObj)
+External(\_SB.PCI0.RP16.L23D, MethodObj)
+External(\_SB.PCI0.RP17.L23D, MethodObj)
+External(\_SB.PCI0.RP18.L23D, MethodObj)
+External(\_SB.PCI0.RP19.L23D, MethodObj)
+External(\_SB.PCI0.RP20.L23D, MethodObj)
+External(\_SB.PCI0.RP21.L23D, MethodObj)
+External(\_SB.PCI0.RP22.L23D, MethodObj)
+External(\_SB.PCI0.RP23.L23D, MethodObj)
+External(\_SB.PCI0.RP24.L23D, MethodObj)
+
+External(\_SB.PCI0.RP01.DL23, MethodObj)
+External(\_SB.PCI0.RP02.DL23, MethodObj)
+External(\_SB.PCI0.RP03.DL23, MethodObj)
+External(\_SB.PCI0.RP04.DL23, MethodObj)
+External(\_SB.PCI0.RP05.DL23, MethodObj)
+External(\_SB.PCI0.RP06.DL23, MethodObj)
+External(\_SB.PCI0.RP07.DL23, MethodObj)
+External(\_SB.PCI0.RP08.DL23, MethodObj)
+External(\_SB.PCI0.RP09.DL23, MethodObj)
+External(\_SB.PCI0.RP10.DL23, MethodObj)
+External(\_SB.PCI0.RP11.DL23, MethodObj)
+External(\_SB.PCI0.RP12.DL23, MethodObj)
+External(\_SB.PCI0.RP13.DL23, MethodObj)
+External(\_SB.PCI0.RP14.DL23, MethodObj)
+External(\_SB.PCI0.RP15.DL23, MethodObj)
+External(\_SB.PCI0.RP16.DL23, MethodObj)
+External(\_SB.PCI0.RP17.DL23, MethodObj)
+External(\_SB.PCI0.RP18.DL23, MethodObj)
+External(\_SB.PCI0.RP19.DL23, MethodObj)
+External(\_SB.PCI0.RP20.DL23, MethodObj)
+External(\_SB.PCI0.RP21.DL23, MethodObj)
+External(\_SB.PCI0.RP22.DL23, MethodObj)
+External(\_SB.PCI0.RP23.DL23, MethodObj)
+External(\_SB.PCI0.RP24.DL23, MethodObj)
+
+External(\_SB.PCI0.RTEN, MethodObj)
+External(\_SB.PCI0.RTDS, MethodObj)
+External(\_SB.PCI0.RP01.PON, MethodObj)
+External(\_SB.PCI0.RP02.PON, MethodObj)
+External(\_SB.PCI0.RP03.PON, MethodObj)
+External(\_SB.PCI0.RP04.PON, MethodObj)
+External(\_SB.PCI0.RP05.PON, MethodObj)
+External(\_SB.PCI0.RP06.PON, MethodObj)
+External(\_SB.PCI0.RP07.PON, MethodObj)
+External(\_SB.PCI0.RP08.PON, MethodObj)
+External(\_SB.PCI0.RP09.PON, MethodObj)
+External(\_SB.PCI0.RP10.PON, MethodObj)
+External(\_SB.PCI0.RP11.PON, MethodObj)
+External(\_SB.PCI0.RP12.PON, MethodObj)
+External(\_SB.PCI0.RP13.PON, MethodObj)
+External(\_SB.PCI0.RP14.PON, MethodObj)
+External(\_SB.PCI0.RP15.PON, MethodObj)
+External(\_SB.PCI0.RP16.PON, MethodObj)
+External(\_SB.PCI0.RP17.PON, MethodObj)
+External(\_SB.PCI0.RP18.PON, MethodObj)
+External(\_SB.PCI0.RP19.PON, MethodObj)
+External(\_SB.PCI0.RP20.PON, MethodObj)
+External(\_SB.PCI0.RP21.PON, MethodObj)
+External(\_SB.PCI0.RP22.PON, MethodObj)
+External(\_SB.PCI0.RP23.PON, MethodObj)
+External(\_SB.PCI0.RP24.PON, MethodObj)
+External(\_SB.PCI0.PEG0.PG00._ON, MethodObj)
+External(\_SB.PCI0.PEG1.PG01._ON, MethodObj)
+External(\_SB.PCI0.PEG2.PG02._ON, MethodObj)
+
+Name(TRDO, 0) // 1 during TBT RTD3 _ON
+Name(TRD3, 0) // 1 during TBT RTD3 _OFF
+Name(TBPE, 0) // Reflects RTD3_PWR_EN value
+Name(TOFF, 0) // param to TBT _OFF method
+
+  Method (TBON, 0, Serialized) {
+    // TBT On process before entering Sx state.
+    Store(1, TRDO)
+    Switch (ToInteger(\RPS0)) { // TBT Root port Selector
+      Case (1) {
+        If (CondRefOf(\_SB.PCI0.RP01.PON)) {
+          \_SB.PCI0.RP01.PON()
+        }
+      }
+      Case (2) {
+        If (CondRefOf(\_SB.PCI0.RP02.PON)) {
+          \_SB.PCI0.RP02.PON()
+        }
+      }
+      Case (3) {
+        If (CondRefOf(\_SB.PCI0.RP03.PON)) {
+          \_SB.PCI0.RP03.PON()
+        }
+      }
+      Case (4) {
+        If (CondRefOf(\_SB.PCI0.RP04.PON)) {
+          \_SB.PCI0.RP04.PON()
+        }
+      }
+      Case (5) {
+        If (CondRefOf(\_SB.PCI0.RP05.PON)) {
+          \_SB.PCI0.RP05.PON()
+        }
+      }
+      Case (6) {
+        If (CondRefOf(\_SB.PCI0.RP06.PON)) {
+          \_SB.PCI0.RP06.PON()
+        }
+      }
+      Case (7) {
+        If (CondRefOf(\_SB.PCI0.RP07.PON)) {
+          \_SB.PCI0.RP07.PON()
+        }
+      }
+      Case (8) {
+        If (CondRefOf(\_SB.PCI0.RP08.PON)) {
+          \_SB.PCI0.RP08.PON()
+        }
+      }
+      Case (9) {
+        If (CondRefOf(\_SB.PCI0.RP09.PON)) {
+          \_SB.PCI0.RP09.PON()
+        }
+      }
+      Case (10) {
+        If (CondRefOf(\_SB.PCI0.RP10.PON)) {
+          \_SB.PCI0.RP10.PON()
+        }
+      }
+      Case (11) {
+        If (CondRefOf(\_SB.PCI0.RP11.PON)) {
+          \_SB.PCI0.RP11.PON()
+        }
+      }
+      Case (12) {
+        If (CondRefOf(\_SB.PCI0.RP12.PON)) {
+          \_SB.PCI0.RP12.PON()
+        }
+      }
+      Case (13) {
+        If (CondRefOf(\_SB.PCI0.RP13.PON)) {
+          \_SB.PCI0.RP13.PON()
+        }
+      }
+      Case (14) {
+        If (CondRefOf(\_SB.PCI0.RP14.PON)) {
+          \_SB.PCI0.RP14.PON()
+        }
+      }
+      Case (15) {
+        If (CondRefOf(\_SB.PCI0.RP15.PON)) {
+          \_SB.PCI0.RP15.PON()
+        }
+      }
+      Case (16) {
+        If (CondRefOf(\_SB.PCI0.RP16.PON)) {
+          \_SB.PCI0.RP16.PON()
+        }
+      }
+      Case (17) {
+        If (CondRefOf(\_SB.PCI0.RP17.PON)) {
+          \_SB.PCI0.RP17.PON()
+        }
+      }
+      Case (18) {
+        If (CondRefOf(\_SB.PCI0.RP18.PON)) {
+          \_SB.PCI0.RP18.PON()
+        }
+      }
+      Case (19) {
+        If (CondRefOf(\_SB.PCI0.RP19.PON)) {
+          \_SB.PCI0.RP19.PON()
+        }
+      }
+      Case (20) {
+        If (CondRefOf(\_SB.PCI0.RP20.PON)) {
+          \_SB.PCI0.RP20.PON()
+        }
+      }
+      Case (21) {
+        If (CondRefOf(\_SB.PCI0.RP21.PON)) {
+          \_SB.PCI0.RP21.PON()
+        }
+      }
+      Case (22) {
+        If (CondRefOf(\_SB.PCI0.RP22.PON)) {
+          \_SB.PCI0.RP22.PON()
+        }
+      }
+      Case (23) {
+        If (CondRefOf(\_SB.PCI0.RP23.PON)) {
+          \_SB.PCI0.RP23.PON()
+        }
+      }
+      Case (24) {
+        If (CondRefOf(\_SB.PCI0.RP24.PON)) {
+          \_SB.PCI0.RP24.PON()
+        }
+      }
+    }//Switch(ToInteger(RPS0)) // TBT Selector
+    Store(0, TRDO)
+  } // End of TBON
+  //
+  // Name: TBTD
+  // Description: Function to return the TBT RP# device no
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: TBT RP# device no
+  //
+  Method(TBTD,2)
+  {
+    ADBG("TBTD")
+    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (Package () {1, 2, 3, 4, 5, 6, 7, 8})
+        {
+          Store(0x1C, Local0) //Device28-Function0...Function7 = 11100.000...111
+        }
+        Case (Package () {9, 10, 11, 12, 13, 14, 15, 16})
+        {
+          Store(0x1D, Local0) //Device29-Function0...Function7 = 11101.000...111
+        }
+        Case (Package () {17, 18, 19, 20, 21, 22, 23, 24})
+        {
+          Store(0x1B, Local0) //Device27-Function0...Function3 = 11011.000...011
+        }
+      }
+    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (Package () {1, 2, 3})
+        {
+          Store(0x1, Local0) //Device1-Function0...Function2 = 00001.000...010
+        }
+      }
+    } Else {
+      Store(0xFF, Local0)
+    }
+
+    ADBG("Device no")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(TBTD,1)
+
+  //
+  // Name: TBTF
+  // Description: Function to return the TBT RP# function no
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: TBT RP# function no
+  //
+  Method(TBTF,2)
+  {
+    ADBG("TBTF")
+    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (1)
+        {
+          Store(And(\RPA1,0xF), Local0) //Device28-Function0 = 11100.000
+        }
+        Case (2)
+        {
+          Store(And(\RPA2,0xF), Local0) //Device28-Function1 = 11100.001
+        }
+        Case (3)
+        {
+          Store(And(\RPA3,0xF), Local0) //Device28-Function2 = 11100.010
+        }
+        Case (4)
+        {
+          Store(And(\RPA4,0xF), Local0) //Device28-Function3 = 11100.011
+        }
+        Case (5)
+        {
+          Store(And(\RPA5,0xF), Local0) //Device28-Function4 = 11100.100
+        }
+        Case (6)
+        {
+          Store(And(\RPA6,0xF), Local0) //Device28-Function5 = 11100.101
+        }
+        Case (7)
+        {
+          Store(And(\RPA7,0xF), Local0) //Device28-Function6 = 11100.110
+        }
+        Case (8)
+        {
+          Store(And(\RPA8,0xF), Local0) //Device28-Function7 = 11100.111
+        }
+        Case (9)
+        {
+          Store(And(\RPA9,0xF), Local0) //Device29-Function0 = 11101.000
+        }
+        Case (10)
+        {
+          Store(And(\RPAA,0xF), Local0) //Device29-Function1 = 11101.001
+        }
+        Case (11)
+        {
+          Store(And(\RPAB,0xF), Local0) //Device29-Function2 = 11101.010
+        }
+        Case (12)
+        {
+          Store(And(\RPAC,0xF), Local0) //Device29-Function3 = 11101.011
+        }
+        Case (13)
+        {
+          Store(And(\RPAD,0xF), Local0) //Device29-Function4 = 11101.100
+        }
+        Case (14)
+        {
+          Store(And(\RPAE,0xF), Local0) //Device29-Function5 = 11101.101
+        }
+        Case (15)
+        {
+          Store(And(\RPAF,0xF), Local0) //Device29-Function6 = 11101.110
+        }
+        Case (16)
+        {
+          Store(And(\RPAG,0xF), Local0) //Device29-Function7 = 11101.111
+        }
+        Case (17)
+        {
+          Store(And(\RPAH,0xF), Local0) //Device27-Function0 = 11011.000
+        }
+        Case (18)
+        {
+          Store(And(\RPAI,0xF), Local0) //Device27-Function1 = 11011.001
+        }
+        Case (19)
+        {
+          Store(And(\RPAJ,0xF), Local0) //Device27-Function2 = 11011.010
+        }
+        Case (20)
+        {
+          Store(And(\RPAK,0xF), Local0) //Device27-Function3 = 11011.011
+        }
+        Case (21)
+        {
+          Store(And(\RPAL,0xF), Local0) //Device27-Function4 = 11011.100
+        }
+        Case (22)
+        {
+          Store(And(\RPAM,0xF), Local0) //Device27-Function5 = 11011.101
+        }
+        Case (23)
+        {
+          Store(And(\RPAN,0xF), Local0) //Device27-Function6 = 11011.110
+        }
+        Case (24)
+        {
+          Store(And(\RPAO,0xF), Local0) //Device27-Function7 = 11011.111
+        }
+      }
+    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+      Switch(ToInteger(Arg0))
+      {
+        Case (1)
+        {
+          Store(0x0, Local0) //Device1-Function0 = 00001.000
+        }
+        Case (2)
+        {
+          Store(0x1, Local0) //Device1-Function1 = 00001.001
+        }
+        Case (3)
+        {
+          Store(0x2, Local0) //Device1-Function2 = 00001.010
+        }
+      }
+    } Else {
+      Store(0xFF, Local0)
+    }
+
+    ADBG("Function no")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(TBTF,1)
+
+  //
+  // Name: MMRP
+  // Description: Function to return the Pci base address of TBT rootport
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(MMRP, 2, Serialized)
+  {
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    Return(Local0)
+  } // End of Method(MMRP)
+
+  //
+  // Name: MMRP
+  // Description: Function to return the Pci base address of TBT Up stream port
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+  Method(MMTB, 2, Serialized)
+  {
+    ADBG("MMTB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x19),
+      SBUS, 8
+    }
+    Store(SBUS, Local2)
+    Store(\_SB.PCI0.GPCB(), Local0)
+    Multiply(Local2, 0x100000, Local2)
+    Add(Local2, Local0, Local0) // TBT HR US port
+
+    ADBG("TBT-US-ADR")
+    ADBG(Local0)
+
+    Return(Local0)
+  } // End of Method(MMTB, 1, Serialized)
+  //
+  // Name: FFTB
+  // Description: Function to  Check for FFFF in TBT PCIe
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  // Return: 1 if TBT PCIe space has value FFFF, 0 if not
+  //
+  Method(FFTB, 2, Serialized)
+  {
+    ADBG("FFTB")
+
+    Add(MMTB(Arg0, Arg1), 0x548, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x08)
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      TB2P, 32,
+      P2TB, 32
+    }
+
+    Store(TB2P, Local1)
+
+    If(LEqual(Local1, 0xFFFFFFFF))
+    {
+      ADBG("FFTb 1")
+      Return (1)
+    }
+    Else
+    {
+      ADBG("FFTb 0")
+      Return (0)
+    }
+  } // End of Method(FFTB)
+
+Name(TDMA, 0x80000000) // Address of Thunderbolt(TM) debug memory buffer, fixed up during POST
+
+Scope(\_GPE)
+{
+  //
+  //
+  //OS up Mail Box command execution to host router upstream port each time
+  //exiting from Sx State .Avoids intermediate
+  //PCIe Scan by OS during resorce allocation
+  // Arg0 : PCIe Base address
+  // Arg1 : Controller Type 0x00 : DTBT
+  //Developer notes: Called twice
+  // 1. During OS INIT (booting to OS from S3-S5/Reboot)
+  // 2. Up on Hot plug
+  //
+  Method(OSUP, 2, Serialized)
+  {
+    ADBG("OSUP")
+
+    Add(Arg0, 0x540, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x10)
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      IT2P, 32,
+      IP2T, 32,
+      DT2P, 32,
+      DP2T, 32
+    }
+
+    Store(100, Local1)
+    Store(0x0D, DP2T) // Write OS_Up to PCIe2TBT
+
+    While(LGreater(Local1, 0))
+    {
+      Store(Subtract(Local1, 1), Local1)
+      Store(DT2P, Local2)
+
+      If(LAnd(LEqual(Local2, 0xFFFFFFFF),LEqual(Arg1, DTBT_CONTROLLER)))// Device gone
+      {
+        ADBG("Dev gone")
+        Return(2)
+      }
+      If(And(Local2, 1)) // Done
+      {
+        ADBG("Cmd acknowledged")
+        break
+      }
+      Sleep(50)
+    }
+    If(LEqual(TRWA,1))
+    {
+      Store(0xC, DP2T) // Write OSUP to PCIe2TBT
+    }
+    Else
+    {
+      Store(0x0, DP2T) // Write 0 to PCIe2TBT
+    }
+
+    //Store(0x00, P2TB) // Write 0 to PCIe2TBT
+
+    ADBG("End-of-OSUP")
+
+    Return(1)
+  } // End of Method(OSUP, 1, Serialized)
+
+  //
+  // Check for FFFF in TBT
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TBFF, 2, Serialized)
+  {
+    ADBG("TBFF")
+
+    Store(MMTB(Arg0, Arg1), Local0)
+    OperationRegion (PXVD, SystemMemory, Local0, 0x8)
+    Field (PXVD, DWordAcc, NoLock, Preserve) {
+      VEDI, 32, // Vendor/Device ID
+      CMDR, 32 // CMD register
+    }
+
+    Store(VEDI, Local1)
+
+    If (LEqual(Local1, 0xFFFFFFFF)) {
+      If (LNotEqual(\TWIN, 0)) { // TBT Enumeration is Native mode?
+        If (LEqual(CMDR, 0xFFFFFFFF)) { // Device Gone
+          Return (2)// Notify only
+        }
+        Return (1)// Exit w/o notify
+      } Else {
+        Return (OSUP(Local0, DTBT_CONTROLLER))
+      }
+    } Else
+    {
+      ADBG("Dev Present")
+      Return (0)
+    }
+  } // End of Method(TBFF, 1, Serialized)
+
+  //
+  // Secondary bus of TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TSUB, 2, Serialized)
+  {
+    ADBG("TSUB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    ADBG("ADR")
+    ADBG(Local0)
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      Offset(0x19),
+      SBUS, 8
+    }
+
+    ADBG("Sec Bus")
+    ADBG(SBUS)
+
+    Return(SBUS)
+  } // End of Method(TSUB, 0, Serialized)
+
+  //
+  // Pmem of TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(TSUP, 2, Serialized)
+  {
+    ADBG("TSUB")
+
+    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
+
+    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
+    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
+
+    ADBG("ADR:")
+    ADBG(Local0)
+
+    OperationRegion (MMMM, SystemMemory, Local0, 0x30)
+    Field (MMMM, AnyAcc, NoLock, Preserve)
+    {
+      CMDS, 32,
+      Offset(0x19),
+      SBUS, 8,
+      SBU5, 8,
+      Offset(0x1C),
+      SEIO, 32,
+      MMBL, 32,
+      PMBL, 32,
+
+    }
+
+    ADBG("Pmem of TBT RP:")
+    ADBG(PMBL)
+
+    Return(PMBL)
+  } // End of Method(TSUP, 0, Serialized)
+
+  //
+  // Wait for secondary bus in TBT RP
+  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
+  // Input: Arg1 -> Tbt port type value from Tbt NVS
+  //
+
+  Method(WSUB, 2, Serialized)
+  {
+    ADBG(Concatenate("WSUB=", ToHexString(Arg0)))
+    ADBG(ToHexString(Timer))
+
+    Store(0, Local0)
+    Store(0, Local1)
+    While(1)
+    {
+      Store(TSUP(Arg0, Arg1), Local1)
+      If(LGreater(Local1, 0x1FFF1))
+      {
+        ADBG("WSUB-Finished")
+        Break
+      }
+      Else
+      {
+        Add(Local0, 1, Local0)
+        If(LGreater(Local0, 1000))
+        {
+          Sleep(1000)
+          ADBG("WSUB-Deadlock")
+        }
+        Else
+        {
+          Sleep(16)
+        }
+      }
+    }
+     ADBG(Concatenate("WSUb=", ToHexString(Local1)))
+  } // End of Method(WSUB)
+
+  // Wait for _WAK finished
+  Method(WWAK)
+  {
+    ADBG("WWAK")
+
+    Wait(WFEV, 0xFFFF)
+    Signal(WFEV) // Set it, to enter on next HP
+  } // End of Method(WWAK)
+
+  Method(NTFY, 2, Serialized)
+  {
+    ADBG("NTFY")
+
+    If(LEqual(NOHP,1))
+    {
+      If (LEqual(Arg1, DTBT_TYPE_PCH)) {
+        Switch(ToInteger(Arg0)) // TBT Selector
+        {
+          Case (1)
+          {
+            ADBG("Notify RP01")
+            Notify(\_SB.PCI0.RP01,0)
+          }
+          Case (2)
+          {
+            ADBG("Notify RP02")
+            Notify(\_SB.PCI0.RP02,0)
+          }
+          Case (3)
+          {
+            ADBG("Notify RP03")
+            Notify(\_SB.PCI0.RP03,0)
+          }
+          Case (4)
+          {
+            ADBG("Notify RP04")
+            Notify(\_SB.PCI0.RP04,0)
+          }
+          Case (5)
+          {
+            ADBG("Notify RP05")
+            Notify(\_SB.PCI0.RP05,0)
+          }
+          Case (6)
+          {
+            ADBG("Notify RP06")
+            Notify(\_SB.PCI0.RP06,0)
+          }
+          Case (7)
+          {
+            ADBG("Notify RP07")
+            Notify(\_SB.PCI0.RP07,0)
+          }
+          Case (8)
+          {
+            ADBG("Notify RP08")
+            Notify(\_SB.PCI0.RP08,0)
+          }
+          Case (9)
+          {
+            ADBG("Notify RP09")
+            Notify(\_SB.PCI0.RP09,0)
+          }
+          Case (10)
+          {
+            ADBG("Notify RP10")
+            Notify(\_SB.PCI0.RP10,0)
+          }
+          Case (11)
+          {
+            ADBG("Notify RP11")
+            Notify(\_SB.PCI0.RP11,0)
+          }
+          Case (12)
+          {
+            ADBG("Notify RP12")
+            Notify(\_SB.PCI0.RP12,0)
+          }
+          Case (13)
+          {
+            ADBG("Notify RP13")
+            Notify(\_SB.PCI0.RP13,0)
+          }
+          Case (14)
+          {
+            ADBG("Notify RP14")
+            Notify(\_SB.PCI0.RP14,0)
+          }
+          Case (15)
+          {
+            ADBG("Notify RP15")
+            Notify(\_SB.PCI0.RP15,0)
+          }
+          Case (16)
+          {
+            ADBG("Notify RP16")
+            Notify(\_SB.PCI0.RP16,0)
+          }
+          Case (17)
+          {
+            ADBG("Notify RP17")
+            Notify(\_SB.PCI0.RP17,0)
+          }
+          Case (18)
+          {
+            ADBG("Notify RP18")
+            Notify(\_SB.PCI0.RP18,0)
+          }
+          Case (19)
+          {
+            ADBG("Notify RP19")
+            Notify(\_SB.PCI0.RP19,0)
+          }
+          Case (20)
+          {
+            ADBG("Notify RP20")
+            Notify(\_SB.PCI0.RP20,0)
+          }
+          Case (21)
+          {
+            ADBG("Notify RP21")
+            Notify(\_SB.PCI0.RP21,0)
+          }
+          Case (22)
+          {
+            ADBG("Notify RP22")
+            Notify(\_SB.PCI0.RP22,0)
+          }
+          Case (23)
+          {
+            ADBG("Notify RP23")
+            Notify(\_SB.PCI0.RP23,0)
+          }
+          Case (24)
+          {
+            ADBG("Notify RP24")
+            Notify(\_SB.PCI0.RP24,0)
+          }
+        }//Switch(ToInteger(TBSS)) // TBT Selector
+      } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
+        Switch(ToInteger(Arg0))
+        {
+          Case (1)
+          {
+            ADBG("Notify PEG0")
+            Notify(\_SB.PCI0.PEG0,0)
+          }
+          Case (2)
+          {
+            ADBG("Notify PEG1")
+            Notify(\_SB.PCI0.PEG1,0)
+          }
+          Case (3)
+          {
+            ADBG("Notify PEG2")
+            Notify(\_SB.PCI0.PEG2,0)
+          }
+        }
+      }//Switch(ToInteger(TBSS)) // TBT Selector
+    }//If(NOHP())
+    P8XH(0,0xC2)
+    P8XH(1,0xC2)
+  }// End of Method(NTFY)
+
+//
+//  TBT BIOS, GPIO 5 filtering,
+//  Hot plug of 12V USB devices, into TBT host router, cause electrical noise on PCH GPIOs,
+//  This noise cause false hot-plug events, and negatively influence BIOS assisted hot-plug.
+//  WHL-PCH GPIO does not implement Glitch Filter logic (refer to GPIO HAS) on any GPIO pad. Native functions have to implement their own digital glitch-filter logic
+//  if needed. As HW filter was not implemented on WHL PCH, because of that SW workaround should be implemented in BIOS.
+//  Register 0x544(Bios mailbox) bit 0 definition:
+//  if BIOS reads bit as 1, BIOS will clear the bit and continue normal flow, if bit is 0 BIOS will exit from method
+//
+
+  Method(GNIS,2, Serialized)
+  {
+
+    ADBG("GNIS")
+    If(LEqual(GP5F, 0))
+    {
+      ADBG("GNIS_Dis=0")
+      Return(0)
+    }
+    //
+    // BIOS mailbox command for GPIO filter
+    //
+    Add(MMTB(Arg0, Arg1), 0x544, Local0)
+    OperationRegion(PXVD,SystemMemory,Local0,0x08)
+
+    Field(PXVD,DWordAcc, NoLock, Preserve)
+    {
+      HPFI, 1,
+      Offset(0x4),
+      TB2P, 32
+    }
+    Store(TB2P, Local1)
+    ADBG(Concatenate("TB2P=", ToHexString(Local1)))
+    If(LEqual(Local1, 0xFFFFFFFF)) // Disconnect?
+    {
+      ADBG("GNIS=0")
+      Return(0)
+    }
+    Store(HPFI, Local2)
+    ADBG(Concatenate("HPFI=", ToHexString(Local2)))
+    If(LEqual(Local2, 0x01))
+    {
+      Store(0x00, HPFI)
+      ADBG("GNIS=0")
+      Return(0)
+    }
+    // Any other values treated as a GPIO noise
+    ADBG("GNIS=1")
+    Return(1)
+  }
+
+  Method(CHKP,2, Serialized)
+  {
+    Add(MMTB(Arg0, Arg1), 0x544, Local0)
+    OperationRegion(PXVE,SystemMemory,Local0,0x08)
+
+    Field(PXVE,DWordAcc, NoLock, Preserve)
+    {
+      HPFI, 1,
+      Offset(0x4),
+      TB2P, 32
+    }
+    Store(TB2P, Local1)
+    And(Local1,BIT29,Local1)
+    ADBG(Concatenate("Local1=", ToHexString(Local1)))
+    //ADBG(Concatenate("BIT29=", ToHexString(LAnd(Local1,BIT29))))
+    If(LEqual(Local1, BIT29))
+    {
+      Return(1)
+    }
+    Else
+    {
+      Return(0)
+    }
+  }
+
+  //
+  // Method to Handle enumerate PCIe structure through
+  // SMI for Thunderbolt(TM) devices
+  //
+  Method(XTBT,2, Serialized)
+  {
+    ADBG("XTBT")
+    ADBG("RP :")
+    ADBG(Arg0)
+    Store(Arg0, DTCP) // Root port to enumerate
+    Store(Arg1, DTPT)   // Root port Type
+    If(LEqual(Arg0, RPS0)) {
+      Store (1, Local0)
+    } ElseIf (LEqual(Arg0, RPS1)) {
+      Store (2, Local0)
+    } Else {
+      Store (0, Local0)
+      Return ()
+    }
+
+    If (TRDO) {
+      ADBG("Durng TBT_ON")
+      Return ()
+    }
+
+    If (TRD3) {
+      ADBG("During TBT_OFF")
+      Return ()
+    }
+    WWAK()
+    WSUB(Arg0, Arg1)
+    If(GNIS(Arg0, Arg1))
+    {
+      Return()
+    }
+
+    OperationRegion(SPRT,SystemIO, 0xB2,2)
+    Field (SPRT, ByteAcc, Lock, Preserve)
+    {
+      SSMP, 8
+    }
+
+    ADBG("TBT-HP-Handler")
+
+    Acquire(OSUM, 0xFFFF)
+    Store(TBFF(Arg0, Arg1), Local1)
+    If(LEqual(Local1, 1))// Only HR
+    {
+      Sleep(16)
+      Release(OSUM)
+      ADBG("OS_Up_Received")
+      Return ()
+    }
+    If(LEqual(Local1, 2)) // Disconnect
+    {
+      NTFY(Arg0, Arg1)
+      Sleep(16)
+      Release(OSUM)
+      ADBG("Disconnect")
+      Return ()
+    }
+
+    // HR and EP
+    If(LEqual(SOHP, 1))
+    {
+      // Trigger SMI to enumerate PCIe Structure
+      ADBG("TBT SW SMI")
+      Store(21, TBSF)
+      Store(0xF7, SSMP)
+    }
+    NTFY(Arg0, Arg1)
+    Sleep(16)
+    Release(OSUM)
+
+    ADBG("End-of-XTBT")
+  } // End of Method(XTBT)
+
+  //
+  // Calling Method to Handle enumerate PCIe structure through
+  // SMI for Thunderbolt(TM) devices for Tier 1 GPIOs
+  // Used in Two ways ,
+  // If CIO GPIO(1 Tier) is Different for the Controllers, this will be used as 1 Tier GPIO Handler for 1st controller
+  // If CIO GPIO(1 Tier) is Same for all the controllers, this will be used as 1 Tier GPIO Handler for All the controllers
+  //
+  Method(ATBT)
+  {
+    ADBG("ATBT")
+    //
+    // Calling Method to Handle enumerate PCIe structure through
+    //
+    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
+      If(LEqual(RPN0,1))
+      {
+        XTBT(RPS0, RPT0)
+      }
+    } Else {
+      If(LEqual(RPN0,1))
+      {
+        XTBT(RPS0, RPT0)
+      }
+      ElseIf(LEqual(RPN1,1))
+      {
+        XTBT(RPS1, RPT1)
+      }
+    }
+    ADBG("End-of-ATBT")
+  } // End of Method(ATBT)
+
+  Method(BTBT)
+  {
+    ADBG("BTBT")
+    //
+    // Calling Method to Handle enumerate PCIe structure through
+    //
+    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
+      If(LEqual(RPN1,1))
+      {
+        XTBT(RPS1, RPT1)
+      }
+    }
+    ADBG("End-of-BTBT")
+  } // End of Method(BTBT)
+  //
+  // Method to call OSPU Mail box command
+  // Arg0 : Controller type 0x00 : Discrete 0x80 : Integrated TBT
+  // Arg1 : TBT RP Selector / DMA
+  // Arg2 : TBT Type (PCH or PEG)
+  //
+  Method(TINI, 3, Serialized)
+  {
+    ADBG("TINI")
+    If(Lequal (Arg0, DTBT_CONTROLLER))
+    {
+      //ADBG("DTBT")
+    Store(MMRP(Arg1, Arg2), Local0)
+      OperationRegion(RP_X,SystemMemory,Local0,0x20)
+      Field(RP_X,DWordAcc, NoLock, Preserve)
+      {
+        REG0, 32,
+        REG1, 32,
+        REG2, 32,
+        REG3, 32,
+        REG4, 32,
+        REG5, 32,
+        REG6, 32,
+        REG7, 32
+      }
+      Store(REG6, Local1)
+      Store(0x00F0F000, REG6)
+      Store(MMTB(Arg1, Arg2), Local2)
+      OSUP(Local2, DTBT_CONTROLLER)
+      Store(Local1, REG6)
+    }
+    ADBG("End-of-TINI")
+  }
+
+} // End of Scope (\_GPE)
+
+Scope (\_SB)
+{
+  //
+  // The code needs to be executed for TBT Hotplug Handler event (2-tier GPI GPE event architecture) is presented here
+  //
+  Method(THDR, 3, Serialized)
+  {
+    ADBG("THDR")
+    \_SB.CAGS(Arg0)
+    \_GPE.XTBT(Arg1, Arg2)
+  } // End of Method(THDR, 3, Serialized)
+} // End of Scope(\_SB)
+
+Scope (\_SB)
+{
+  //
+  // Name: CGWR [Combined GPIO Write]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> GpioPad / Expander pin
+  //        Arg1 -> Value
+  // Return: Nothing
+  //
+  Method(CGWR, 2, Serialized)
+  {
+    // PCH
+    If (CondRefOf(\_SB.SGOV))
+    {
+      \_SB.SGOV(Arg0, Arg1)
+    }
+  } // End of Method(CGWR, 4, Serialized)
+
+  //
+  // Name: CGRD [Combined GPIO Read]
+  // Description: Function to read from GPIO
+  // Input: Arg0 -> GpioPad / Expander pin
+  //        Arg1 -> 0: GPO [GPIO TX State]
+  //                1: GPI [GPIO RX State]
+  // Return: Value
+  //
+  Method(CGRD, 2, Serialized)
+  {
+    Store(1, Local0)
+    // PCH
+    If (LEqual(Arg1, 0))
+    {
+      // GPIO TX State
+      If (CondRefOf(\_SB.GGOV))
+      {
+        Store(\_SB.GGOV(Arg0), Local0)
+      }
+    }
+    ElseIf (LEqual(Arg1, 1))
+    {
+      // GPIO RX State
+      If (CondRefOf(\_SB.GGIV))
+      {
+        Store(\_SB.GGIV(Arg0), Local0)
+      }
+    }
+    Return(Local0)
+  } // End of Method(CGRD, 4, Serialized)
+  //
+  // Name: WRGP [GPIO Write]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
+  //        Arg1 -> Value
+  // Return: Nothing
+  //
+  Method(WRGP, 2, Serialized)
+  {
+    Store(Arg0, Local0)
+    Store(Arg0, Local1)
+    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
+    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
+    If (LEqual(And(Local0, 0xFF), 1))
+    {
+      // PCH
+      \_SB.CGWR(Local1, Arg1)
+    }
+  } // End of Method(WRGP, 2, Serialized)
+
+  //
+  // Name: RDGP [GPIO Read]
+  // Description: Function to write into GPIO
+  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
+  //        Arg1 -> In case of PCH Gpio Read {GPIO TX(0)/RX(1) State indicator}
+  // Return: Value
+  //
+  Method(RDGP, 2, Serialized)
+  {
+    Store(1, Local7)
+    Store(Arg0, Local0)
+    Store(Arg0, Local1)
+    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
+    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
+    If (LEqual(And(Local0, 0xFF), 1))
+    {
+      // PCH
+      Store(\_SB.CGRD(Local1, Arg1), Local7)
+    }
+    Return(Local7)
+  } // End of Method(RDGP, 2, Serialized)
+
+} // End of Scope(\_SB)
+
+Scope(\_SB)
+{
+  // Asserts/De-asserts TBT force power
+  Method(TBFP, 2)
+  {
+    If(Arg0)
+    {
+      // Implementation dependent way to assert TBT force power
+      If(LEqual(Arg1, 1)) {
+        CGWR(FPG0, FP0L)
+      }
+      Else {
+        CGWR(FPG1, FP1L)
+      }
+    }
+    Else
+    {
+      // Implementation dependent way to de-assert TBT force power
+      If(LEqual(Arg1, 1)) {
+        CGWR(FPG0, LNot(FP0L))
+      }
+      Else {
+        CGWR(FPG1, LNot(FP1L))
+      }
+    }
+  }
+
+  // WMI ACPI device to control TBT force power
+  Device(WMTF)
+  {
+    // pnp0c14 is pnp id assigned to WMI mapper
+    Name(_HID, "PNP0C14")
+    Name(_UID, "TBFP")
+
+    Name(_WDG, Buffer() {
+      // {86CCFD48-205E-4A77-9C48-2021CBEDE341}
+      0x48, 0xFD, 0xCC, 0x86,
+      0x5E, 0x20,
+      0x77, 0x4A,
+      0x9C, 0x48,
+      0x20, 0x21, 0xCB, 0xED, 0xE3, 0x41,
+      84, 70,    // Object Id (TF)
+      1,         // Instance Count
+      0x02       // Flags (WMIACPI_REGFLAG_METHOD)
+    })
+
+    // Set TBT force power
+    // Arg2 is force power value
+    Method(WMTF, 3)
+    {
+      CreateByteField(Arg2,0,FP)
+
+      If(FP)
+      {
+        TBFP(1, 1)
+      }
+      Else
+      {
+        TBFP(0, 1)
+      }
+    }
+  }
+} // End of Scope(\_SB)
+
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 1),LEqual(RPS1, 1))))
+{
+  Scope(\_SB.PCI0.RP01)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP01)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 2),LEqual(RPS1, 2))))
+{
+  Scope(\_SB.PCI0.RP02)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP02)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 3),LEqual(RPS1, 3))))
+{
+  Scope(\_SB.PCI0.RP03)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP03)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 4),LEqual(RPS1, 4))))
+{
+  Scope(\_SB.PCI0.RP04)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP04)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 5),LEqual(RPS1, 5))))
+{
+  Scope(\_SB.PCI0.RP05)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP05)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 6),LEqual(RPS1, 6))))
+{
+  Scope(\_SB.PCI0.RP06)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP06)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 7),LEqual(RPS1, 7))))
+{
+  Scope(\_SB.PCI0.RP07)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP07)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 8),LEqual(RPS1, 8))))
+{
+  Scope(\_SB.PCI0.RP08)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP08)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 9),LEqual(RPS1, 9))))
+{
+  Scope(\_SB.PCI0.RP09)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP09)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 10),LEqual(RPS1, 10))))
+{
+  Scope(\_SB.PCI0.RP10)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP10)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 11),LEqual(RPS1, 11))))
+{
+  Scope(\_SB.PCI0.RP11)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP11)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 12),LEqual(RPS1, 12))))
+{
+  Scope(\_SB.PCI0.RP12)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP12)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 13),LEqual(RPS1, 13))))
+{
+  Scope(\_SB.PCI0.RP13)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP13)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 14),LEqual(RPS1, 14))))
+{
+  Scope(\_SB.PCI0.RP14)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP14)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 15),LEqual(RPS1, 15))))
+{
+  Scope(\_SB.PCI0.RP15)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP15)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 16),LEqual(RPS1, 16))))
+{
+  Scope(\_SB.PCI0.RP16)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP16)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 17),LEqual(RPS1, 17))))
+{
+  Scope(\_SB.PCI0.RP17)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP17)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 18),LEqual(RPS1, 18))))
+{
+  Scope(\_SB.PCI0.RP18)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP18)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 19),LEqual(RPS1, 19))))
+{
+  Scope(\_SB.PCI0.RP19)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP19)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 20),LEqual(RPS1, 20))))
+{
+  Scope(\_SB.PCI0.RP20)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.RP20)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 21),LEqual(RPS1, 21))))
+{
+  Scope(\_SB.PCI0.PEG0)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG0)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 22),LEqual(RPS1, 22))))
+{
+  Scope(\_SB.PCI0.PEG1)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG1)
+}
+
+If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 23),LEqual(RPS1, 23))))
+{
+  Scope(\_SB.PCI0.PEG2)
+  {
+    Device(HRUS)// Host router Upstream port
+    {
+      Name(_ADR, 0x00000000)
+
+      Method(_RMV)
+      {
+        Return(TARS)
+      } // end _RMV
+    }
+  }//End of Scope(\_SB.PCI0.PEG2)
+}
+
+Scope(\_SB)
+{
+    //
+    // Name: PERB
+    // Description: Function to read a Byte from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Byte data read from PCIE-MMIO
+    //
+    Method(PERB,5,Serialized)
+    {
+      ADBG("PERB")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 1)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 8
+      }
+
+      Return(TEMP)
+    } // End of Method(PERB,5,Serialized)
+
+    //
+    // Name: PEWB
+    // Description: Function to write a Byte into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWB,6,Serialized)
+    {
+      ADBG("PEWB")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 1)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 8
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWB,6,Serialized)
+
+    //
+    // Name: PERW
+    // Description: Function to read a Word from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Word data read from PCIE-MMIO
+    //
+    Method(PERW,5,Serialized)
+    {
+      ADBG("PERW")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 2)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 16
+      }
+
+      Return(TEMP)
+    } // End of Method(PERW,5,Serialized)
+
+    //
+    // Name: PEWW
+    // Description: Function to write a Word into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWW,6,Serialized)
+    {
+      ADBG("PEWW")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 2)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 16
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWW,6,Serialized)
+
+    //
+    // Name: PERD
+    // Description: Function to read a Dword from PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    // Return: Dword data read from PCIE-MMIO
+    //
+    Method(PERD,5,Serialized)
+    {
+      ADBG("PERD")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 4)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 32
+      }
+
+      Return(TEMP)
+    } // End of Method(PERD,5,Serialized)
+
+    //
+    // Name: PEWD
+    // Description: Function to write a Dword into PCIE-MMIO
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Register offset
+    //        Arg5 -> Data
+    // Return: Nothing
+    //
+    Method(PEWD,6,Serialized)
+    {
+      ADBG("PEWD")
+
+      Store(Arg0, Local7)
+      Or(Local7, ShiftLeft(Arg1, 20), Local7)
+      Or(Local7, ShiftLeft(Arg2, 15), Local7)
+      Or(Local7, ShiftLeft(Arg3, 12), Local7)
+      Or(Local7, Arg4, Local7)
+
+      OperationRegion(PCI0, SystemMemory, Local7, 4)
+      Field(PCI0, ByteAcc,NoLock,Preserve)
+      {
+        TEMP, 32
+      }
+
+      Store(Arg5,TEMP)
+    } // End of Method(PEWD,6,Serialized)
+
+    //
+    // Name: STDC
+    // Description: Function to get Standard Capability Register Offset
+    // Input: Arg0 -> PCIE base address
+    //        Arg1 -> Bus
+    //        Arg2 -> Device
+    //        Arg3 -> Function
+    //        Arg4 -> Capability ID
+    // Return: Capability Register Offset data
+    //
+    Method(STDC,5,Serialized)
+    {
+      ADBG("STDC")
+
+      //Check for Referenced device is present or not
+      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x00), Local7) //Vendor ID register
+      If(LEqual(Local7, 0xFFFF))
+      {
+        ADBG("Referenced device is not present")
+        Return(0)
+      }
+
+      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x06), Local0) //Device Status register
+      If (LEqual(And(Local0, 16), 0)) //Bit4 - Capabilities List
+      {
+        //No Capabilities linked list is available
+        ADBG("No Capabilities linked list is available")
+        Return(0)
+      }
+
+      //Local1 is for storing CapabilityID
+      //Local2 is for storing CapabilityPtr
+      Store(PERB(Arg0, Arg1, Arg2, Arg3, 0x34), Local2) //CapabilityPtr
+
+      While(1)
+      {
+        And(Local2, 0xFC, Local2) //Each capability must be DWORD aligned
+
+        If(LEqual(Local2, 0)) //A pointer value of 00h is used to indicate the last capability in the list
+        {
+          ADBG("Capability ID is not found")
+          Return(0)
+        }
+
+        Store(PERB(Arg0, Arg1, Arg2, Arg3, Local2), Local1) //CapabilityID
+
+        If(LEqual(Arg4, Local1)) //CapabilityID match
+        {
+          ADBG("Capability ID is found")
+          ADBG("Capability Offset : ")
+          ADBG(Local2)
+          Return(Local2)
+        }
+        Store(PERB(Arg0, Arg1, Arg2, Arg3, Add(Local2, 1)), Local2) //CapabilityPtr
+        Return(0)
+      }
+    } // End of Method(STDC,5,Serialized)
+
+} // End Scope(\_SB)
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:17   ` Chiu, Chasel
@ 2019-08-17 20:00   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17 20:00 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation

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

* Adds the WhiskeylakeURvp board as a build option in build.cfg so it
  it is listed as a valid build target.
* Updates relevant Readme.md files to include instructions for
  WhiskeylakeOpenBoardPkg.
* Adds the maintainers for WhiskeylakeOpenBoardPkg to maintainers.txt.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Maintainers.txt          |  5 +++
 Platform/Intel/Readme.md | 44 +++++++++++++-------  Platform/Intel/build.cfg |  4 +-
 Readme.md                |  1 +
 4 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/Maintainers.txt b/Maintainers.txt index bc8cbd6458..b16432bf87 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -98,6 +98,11 @@ M: Shifei A Lu <shifei.a.lu@intel.com>
 M: Xiaohu Zhou <bowen.zhou@intel.com>
 M: Isaac W Oram <isaac.w.oram@intel.com>
 
+Platform/Intel/WhiskeylakeOpenBoardPkg
+M: Chasel Chiu <chasel.chiu@intel.com>
+M: Michael Kubacki <michael.a.kubacki@intel.com>
+M: Nate DeSimone <nathaniel.l.desimone@intel.com>
+
 Platform/Intel/Tools
 M: Bob Feng <bob.c.feng@intel.com>
 M: Liming Gao <liming.gao@intel.com>
diff --git a/Platform/Intel/Readme.md b/Platform/Intel/Readme.md index 00f42985a2..aaf6ef4d3e 100644
--- a/Platform/Intel/Readme.md
+++ b/Platform/Intel/Readme.md
@@ -53,9 +53,10 @@ A UEFI firmware implementation using MinPlatformPkg is constructed using the fol
 
 
 ## Board Support
+* The `ClevoOpenBoardPkg` contains board implementations for Clevo systems.
 * The `KabylakeOpenBoardPkg` contains board implementations for Kaby Lake systems.
 * The `PurleyOpenBoardPkg` contains board implementations for Purley systems.
-* The `ClevoOpenBoardPkg` contains board implementations for Clevo systems.
+* The `WhiskeylakeOpenBoardPkg` contains board implementations for Whiskey Lake systems.
 
 ## Board Package Organization
 The board package follows the standard EDK II package structure with the following additional elements and guidelines:
@@ -189,7 +190,12 @@ return back to the minimum platform caller.
           |       |        |                |---build_config.cfg: BoardMtOlympus specific
           |       |        |                |                     build settings, environment variables.
           |       |        |                |---build_board.py: Optional board-specific pre-build,
-          |       |        |                |                   build, post-build and clean functions.
+          |       |        |                                    build, post-build and clean functions.
+          |       |        |
+          |       |        |------WhiskeylakeOpenBoardPkg
+          |       |        |        |------WhiskeylakeURvp
+          |       |        |                |---build_config.cfg: WhiskeylakeURvp specific build
+          |       |        |                                      settings environment variables.
           |------FSP
   </pre>
 
@@ -222,19 +228,6 @@ Users can also flash the UEFI firmware image to the highest area of the flash re
 
 ### **Known limitations**
 
-**KabylakeOpenBoardPkg**
-1. This firmware project has only been tested on the Intel KabylakeRvp3 board.
-2. This firmware project has only been tested booting to Microsoft Windows 10 x64 with AHCI mode and Integrated Graphic
-  Device.
-3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
-4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
-5. The build was tested with NASM version 2.11.08.
-
-**PurleyOpenBoardPkg**
-1. This firmware project has only been tested on the Microsoft MtOlympus board.
-2. This firmware project has only been tested booting to Microsoft Windows Server 2016 with NVME on M.2 slot.
-3. This firmware project build has only been tested using the Microsoft Visual Studio 2015 compiler.
-
 **ClevoOpenBoardPkg**
 1. Currently, support is only being added for the N1xxWU series of boards.
 2. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015 compiler.
@@ -244,6 +237,27 @@ Users can also flash the UEFI firmware image to the highest area of the flash re  6. The firmware project applies to all Clevo supported board configurations but is only being tested on System 76 Galago
   Pro devices.
 
+**KabylakeOpenBoardPkg**
+1. This firmware project has only been tested on the Intel KabylakeRvp3 board.
+2. This firmware project has only been tested booting to Microsoft 
+Windows 10 x64 with AHCI mode and Integrated Graphic
+  Device.
+3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
+4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
+5. The build was tested with NASM version 2.11.08.
+
+**PurleyOpenBoardPkg**
+1. This firmware project has only been tested on the Microsoft MtOlympus board.
+2. This firmware project has only been tested booting to Microsoft Windows Server 2016 with NVME on M.2 slot.
+3. This firmware project build has only been tested using the Microsoft Visual Studio 2015 compiler.
+
+**WhiskeylakeOpenBoardPkg**
+1. This firmware project has only been tested on the Intel WhiskeylakeURvp board.
+2. This firmware project has only been tested booting to Microsoft 
+Windows 10 x64 with AHCI mode and Integrated Graphic
+  Device.
+3. The Windows build was tested on Windows 10 with Microsoft Visual Studio 2015.
+4. The Linux build was tested on Ubuntu 16.04.5 LTS with GCC version 5.4.0.
+5. The build was tested with NASM version 2.11.08.
+
 ### **Planned Activities**
 * Replace the batch build scripts with cross-platform Python build scripts.
 * Publish a Minimum Platform specification to describe the architecture and interfaces in more detail.
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index fc6e4fe824..b6d32ada49 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -51,6 +51,8 @@ NUMBER_OF_PROCESSORS = 0
 
 [PLATFORMS]
 # board_name = path_to_board_build_config.cfg
+BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
-BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+WhiskeylakeURvp = 
+WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
+
diff --git a/Readme.md b/Readme.md
index 1befd0b544..e4f211eee6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -228,6 +228,7 @@ they will be documented with the platform.
 * [Clevo](Platform/Intel/ClevoOpenBoardPkg)
 * [Kaby Lake](Platform/Intel/KabylakeOpenBoardPkg)
 * [Purley](Platform/Intel/PurleyOpenBoardPkg)
+* [Whiskey Lake](Platform/Intel/WhiskeylakeOpenBoardPkg)
 
 For more information, see the
 [EDK II Minimum Platform Specification](https://edk2-docs.gitbooks.io/edk-ii-minimum-platform-specification).
--
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:17   ` Chiu, Chasel
@ 2019-08-17 20:08   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17 20:08 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances

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

WhiskeylakeURvp library instances.

* BaseFuncLib - Board-specific VBT update routines.
* BaseGpioCheckConflictLib - Identifies GPIO pad conflicts.
* BaseGpioCheckConflictLibNull - NULL library instance.
* BasePlatformHookLib - Serial port initialization support.
* DxePolicyBoardConfigLib - Board-specific silicon policy configuration
  in DXE.
* PeiBoardInitPostMemLib - PEI post-memory board-specific initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiBoardInitPreMemLib - PEI pre-memory board-specific initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiMultiBoardInitPostMemLib - PEI post-memory multi-board initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiMultiBoardInitPreMemLib - PEI pre-memory multi-board initialization.
  This library implements board APIs declared in MinPlatformPkg.
* PeiPlatformHookLib - PEI board instance-specifc GPIO init.
* PeiPolicyBoardConfigLib - Board instance-specific policy init in PEI.
* SmmBoardAcpiEnableLib - Board instance-specific SMM ACPI enable support.
* SmmMultiBoardAcpiSupportLib - Multi-board ACPI support in SMM.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf                                   |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf         |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf                   |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf                        |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf                  |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf                       |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf                        |  116 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf                  |  202 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf                   |  296 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf                     |   94 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf           |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h                                      |   18 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h                                   |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h                            |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h                               |  225 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h                              |  284 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h                        |   59 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h                               | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h                      |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h                |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h                |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c                                             |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c           |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c   |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c                     |  156 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c                          |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c                    |   82 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c                        |  170 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c                |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c                                      |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c                                  |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c                            |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c                          |  398 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c                           |  282 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c                         |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c                          |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c                    |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c                     |   83 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c                       |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c               |  432 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c                |  636 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c                  |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c                       |  299 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c             |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c       |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c             |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c       |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c              |   27 +
 55 files changed, 8499 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
new file mode 100644
index 0000000000..0ccc73b99f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component information file for Board Functions Library.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseBoardFuncInitLib
+  FILE_GUID                      = 7ad17b6c-b9b6-4d88-85c4-7366a2bd12a3
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL|PEIM
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+
+[Packages]
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  Gop.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
new file mode 100644
index 0000000000..5014faf664
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component information file for BaseGpioCheckConflictLib.
+#
+#
+#  Copyright (c) 2019, 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
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLib.c
+
+[Guids]
+  gGpioCheckConflictHobGuid
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
new file mode 100644
index 0000000000..d9b242b3fc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
@@ -0,0 +1,32 @@
+## @file
+# Component information file for BaseGpioCheckConflictLib.
+#
+#
+#  Copyright (c) 2019, 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
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLibNull.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
new file mode 100644
index 0000000000..143bb89c63
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BasePlatformHookLib
+  FILE_GUID                      = E22ADCC6-ED90-4A90-9837-C8E7FF9E963D
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = PlatformHookLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciSegmentLib
+  PchCycleDecodingLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort                 ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort  ## CONSUMES
+
+[FixedPcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding            ## CONSUMES
+
+[Sources]
+  BasePlatformHookLib.c
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
new file mode 100644
index 0000000000..8ad32a55dc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmBoardAcpiEnableLib
+  FILE_GUID                      = 549E69AE-D3B3-485B-9C17-AF16E20A58AD
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = BoardAcpiEnableLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciLib
+  MmPciLib
+  PchCycleDecodingLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
+
+[Protocols]
+
+[Sources]
+  SmmWhiskeylakeURvpAcpiEnableLib.c
+  SmmSiliconAcpiEnableLib.c
+  SmmBoardAcpiEnableLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
new file mode 100644
index 0000000000..27001c3b7f
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
@@ -0,0 +1,50 @@
+## @file
+# Platform Hook Library instance for Whiskeylake Mobile/Desktop CRB.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = SmmWhiskeylakeURvpMultiBoardAcpiSupportLib
+  FILE_GUID                      = 8929A54E-7ED8-4AB3-BEBB-C0367BDBBFF5
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = BASE
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  PciLib
+  PmcLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition   ## CONSUMES
+
+[Protocols]
+
+[Sources]
+  SmmWhiskeylakeURvpAcpiEnableLib.c
+  SmmSiliconAcpiEnableLib.c
+  SmmMultiBoardAcpiSupportLib.c
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..a8c4869e96
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
@@ -0,0 +1,53 @@
+## @file
+# Component information file for WhiskeylakeURvpInitLib in PEI post memory phase.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiBoardPostMemInitLib
+  FILE_GUID                      = 7fcc3900-d38d-419f-826b-72481e8b5509
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  HdaVerbTableLib
+  MemoryAllocationLib
+  GpioExpanderLib
+  PcdLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPostMemLib.c
+  PeiBoardInitPostMemLib.c
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
+
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
+
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..9361c3df3e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,116 @@
+## @file
+# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiBoardInitPreMemLib
+  FILE_GUID                      = ec3675bc-1470-417d-826e-37378140213d
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  PcdLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpDetect.c
+  PeiWhiskeylakeURvpInitPreMemLib.c
+  WhiskeylakeURvpHsioPtssTables.c
+  PeiBoardInitPreMemLib.c
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
+
+  # PCH-LP HSIO PTSS Table
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
+
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..4831735dc5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
@@ -0,0 +1,202 @@
+## @file
+# Component information file for WhiskeylakeURvpInitLib in PEI post memory phase.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitLib
+  FILE_GUID                      = C7D39F17-E5BA-41D9-8DFE-FF9017499280
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = PeiWhiskeylakeURvpMultiBoardInitLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  GpioExpanderLib
+  PcdLib
+  MultiBoardInitSupportLib
+  HdaVerbTableLib
+  PeiPlatformHookLib
+  PeiPolicyInitLib
+  PchInfoLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPostMemLib.c
+  PeiMultiBoardInitPostMemLib.c
+  BoardFunc.c
+  BoardFuncInit.c
+
+[FixedPcd]
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel
+
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize
+
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable
+  gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize
+
+  #===========================================================
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase
+  # Board Init Table List
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # WWAN Full Card Power Off and reset pins
+  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## PRODUCES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## PRODUCES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
+
+  # Pch PmConfig Policy
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
+
+
+  gBoardModuleTokenSpaceGuid.PcdSpdPresent
+  gBoardModuleTokenSpaceGuid.PcdBoardRev
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable
+  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable
+  # TPM interrupt
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum
+
+[Guids]
+  gAttemptUsbFirstHotkeyInfoHobGuid             ## CONSUMES
+  gCnlPchLpChipsetInitTableDxGuid               ## CONSUMES
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..6affc3180e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
@@ -0,0 +1,296 @@
+## @file
+# Component information file for PEI WhiskeylakeURvp Board Init Pre-Mem Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiWhiskeylakeURvpMultiBoardInitPreMemLib
+  FILE_GUID                      = EA05BD43-136F-45EE-BBBA-27D75817574F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL
+  CONSTRUCTOR                    = PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  PcdLib
+  MultiBoardInitSupportLib
+  StallPpiLib
+  PchResetLib
+  PeiPlatformHookLib
+  PlatformHookLib
+  PeiPolicyInitLib
+  OcWdtLib
+
+[Packages]
+  MinPlatformPkg/MinPlatformPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiWhiskeylakeURvpInitPreMemLib.c
+  WhiskeylakeURvpHsioPtssTables.c
+  PeiMultiBoardInitPreMemLib.c
+  PeiWhiskeylakeURvpDetect.c
+  BoardSaInitPreMemLib.c
+  BoardPchInitPreMemLib.c
+  BoardFuncInitPreMem.c
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid
+  gEfiPeiMemoryDiscoveredPpiGuid                ## CONSUMES
+  gEfiPeiResetPpiGuid                           ## PRODUCES
+
+[Guids]
+  gPchGeneralPreMemConfigGuid      ## CONSUMES
+  gTcoWdtHobGuid                                ## CONSUMES
+
+[Pcd]
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort
+
+  # PCH-LP HSIO PTSS Table
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size
+  gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size
+
+  # PCH-H HSIO PTSS Table
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size
+  #gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor
+  gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap
+  gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram
+  gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdData
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive
+
+
+  # SPD Address Table
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2
+  gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent
+
+  #===========================================================
+  # Board Init Table List
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # WWAN Full Card Power Off and reset pins
+  gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio
+  gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity
+
+  # SA Misc Config
+  gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl
+  gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved
+  gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit
+
+  # Display DDI
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable           ## PRODUCES
+  gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize       ## PRODUCES
+
+  # PEG Reset By GPIO
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl
+  gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad
+  gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive
+
+  # PCIE RTD3 GPIO
+  gBoardModuleTokenSpaceGuid.PcdRootPortDev
+  gBoardModuleTokenSpaceGuid.PcdRootPortFunc
+  gBoardModuleTokenSpaceGuid.PcdRootPortIndex
+
+  gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport
+
+  gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive
+
+  gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport
+  gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo
+  gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive
+
+  # CA Vref Configuration
+  gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig
+
+  # PCIe Clock Info
+  gBoardModuleTokenSpaceGuid.PcdPcieClock0
+  gBoardModuleTokenSpaceGuid.PcdPcieClock1
+  gBoardModuleTokenSpaceGuid.PcdPcieClock2
+  gBoardModuleTokenSpaceGuid.PcdPcieClock3
+  gBoardModuleTokenSpaceGuid.PcdPcieClock4
+  gBoardModuleTokenSpaceGuid.PcdPcieClock5
+  gBoardModuleTokenSpaceGuid.PcdPcieClock6
+  gBoardModuleTokenSpaceGuid.PcdPcieClock7
+  gBoardModuleTokenSpaceGuid.PcdPcieClock8
+  gBoardModuleTokenSpaceGuid.PcdPcieClock9
+  gBoardModuleTokenSpaceGuid.PcdPcieClock10
+  gBoardModuleTokenSpaceGuid.PcdPcieClock11
+  gBoardModuleTokenSpaceGuid.PcdPcieClock12
+  gBoardModuleTokenSpaceGuid.PcdPcieClock13
+  gBoardModuleTokenSpaceGuid.PcdPcieClock14
+  gBoardModuleTokenSpaceGuid.PcdPcieClock15
+
+  # USB 2.0 Port AFE
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe
+  gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe
+
+  # USB 2.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14
+  gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15
+
+  # USB 3.0 Port Over Current Pin
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8
+  gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2
+
+  # Pch PmConfig Policy
+  gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport
+  gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio
+  gBoardModuleTokenSpaceGuid.PcdMobileDramPresent
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable
+
+
+  gBoardModuleTokenSpaceGuid.PcdSpdPresent
+  gBoardModuleTokenSpaceGuid.PcdBoardRev
+  gBoardModuleTokenSpaceGuid.PcdBoardBomId
+  gBoardModuleTokenSpaceGuid.PcdPlatformType
+  gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength     ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
+  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround    ## PRODUCES
+  gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
+
+
+[FixedPcd]
+  gSiPkgTokenSpaceGuid.PcdMchBaseAddress              ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdMchMmioSize                 ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize        ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress      ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpMmioSize         ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize       ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress   ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize  ## CONSUMES
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
new file mode 100644
index 0000000000..2c9af5b9a3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
@@ -0,0 +1,44 @@
+## @file
+# Module Information file for DxePolicyBoardConfigLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = DxePolicyBoardConfigLib
+  FILE_GUID                      = 17836E9F-7188-4640-80A3-B4441585FFE9
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = DXE_DRIVER
+  LIBRARY_CLASS                  = DxePolicyUpdateLib|DXE_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  DxeSaPolicyBoardConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseLib
+  BaseMemoryLib
+  PcdLib
+  DebugLib
+  HobLib
+  ConfigBlockLib
+
+[Guids]
+  gMemoryDxeConfigGuid                          ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
new file mode 100644
index 0000000000..079fb70ecb
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
@@ -0,0 +1,94 @@
+## @file
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPlatformHookLib
+  FILE_GUID                      = AD901798-B0DA-4B20-B90C-283F886E76D0
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPlatformHookLib|PEIM PEI_CORE SEC
+
+[LibraryClasses]
+  DebugLib
+  BaseMemoryLib
+  IoLib
+  HobLib
+  PcdLib
+  TimerLib
+  PchCycleDecodingLib
+  GpioLib
+  CpuPlatformLib
+  PeiServicesLib
+  ConfigBlockLib
+  PeiSaPolicyLib
+  GpioExpanderLib
+  PmcLib
+  PchPcrLib
+  PciSegmentLib
+  GpioCheckConflictLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort        ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdSioBaseAddress                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable                    ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2                   ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable                 ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2                ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel          ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem
+  gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize
+
+  # GPIO Group Tier
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2              ## CONSUMES
+
+  # Misc
+  gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent              ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent            ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable             ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio               ## CONSUMES
+  gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable                ## CONSUMES
+
+  gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio
+  gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable
+  gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround
+
+[Sources]
+  PeiPlatformHooklib.c
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+  gSiPolicyPpiGuid                              ## CONSUMES
+
+[Guids]
+  gSaDataHobGuid                                ## CONSUMES
+  gEfiGlobalVariableGuid                        ## CONSUMES
+  gGpioCheckConflictHobGuid                     ## CONSUMES
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
new file mode 100644
index 0000000000..65e66ccb62
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
@@ -0,0 +1,70 @@
+## @file
+# Module Information file for PeiPolicyBoardConfigLib Library
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiPolicyBoardConfigLib
+  FILE_GUID                      = B1E959E3-9DCA-4D6F-938C-420C3BF5D820
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = PeiPolicyBoardConfigLib|PEIM PEI_CORE SEC
+
+[Sources]
+  PeiCpuPolicyBoardConfigPreMem.c
+  PeiCpuPolicyBoardConfig.c
+  PeiMePolicyBoardConfigPreMem.c
+  PeiMePolicyBoardConfig.c
+  PeiPchPolicyBoardConfigPreMem.c
+  PeiPchPolicyBoardConfig.c
+  PeiSaPolicyBoardConfigPreMem.c
+  PeiSaPolicyBoardConfig.c
+  PeiSiPolicyBoardConfig.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
+  SecurityPkg/SecurityPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  DebugLib
+  HobLib
+  ConfigBlockLib
+  IoLib
+  BaseCryptLib
+  BaseMemoryLib
+
+[Guids]
+  gCpuSecurityPreMemConfigGuid                  ## CONSUMES
+  gMePeiPreMemConfigGuid                        ## CONSUMES
+  gPchGeneralPreMemConfigGuid                   ## CONSUMES
+  gSaMiscPeiPreMemConfigGuid                    ## CONSUMES
+  gCpuConfigGuid                                ## CONSUMES
+  gPchGeneralConfigGuid                         ## CONSUMES
+  gEfiTpmDeviceInstanceTpm20DtpmGuid
+  gEfiTpmDeviceInstanceTpm12Guid
+
+[Ppis]
+  gEfiPeiReadOnlyVariable2PpiGuid               ## CONSUMES
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress           ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress    ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress     ## CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress  ## CONSUMES
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid   ## CONSUMES
+
+[FixedPcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize                             ## CONSUMES
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
new file mode 100644
index 0000000000..eca492e72d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
@@ -0,0 +1,18 @@
+/** @file
+  Header file for Board Hook function intance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BOARD_FUNC_H_
+#define _BOARD_FUNC_H_
+
+EFI_STATUS
+PeiBoardSpecificInitPostMemNull (
+  VOID
+  );
+
+#endif // _BOARD_FUNC_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
new file mode 100644
index 0000000000..5435b4a6e3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
@@ -0,0 +1,20 @@
+/** @file
+ Header file for board Init function for Post Memory Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_BOARD_INIT_LIB_H_
+#define _PEI_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <PlatformBoardId.h>
+
+#endif // _PEI_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
new file mode 100644
index 0000000000..41c798a082
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
@@ -0,0 +1,90 @@
+/** @file
+  PEI Boards Configurations for PreMem phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _BOARD_SA_CONFIG_PRE_MEM_H_
+#define _BOARD_SA_CONFIG_PRE_MEM_H_
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>               // for MRC Configuration
+#include <ConfigBlock/SwitchableGraphicsConfig.h>   // for PCIE RTD3 GPIO
+#include <GpioPinsCnlLp.h>                          // for GPIO definition
+#include <GpioPinsCnlH.h>
+#include <SaAccess.h>                               // for Root Port number
+#include <PchAccess.h>                              // for Root Port number
+
+//
+// The following section contains board-specific CMD/CTL/CLK and DQ/DQS mapping, needed for LPDDR3/LPDDR4
+//
+
+//
+// DQByteMap[0] - ClkDQByteMap:
+//   If clock is per rank, program to [0xFF, 0xFF]
+//   If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+//   If clock is shared by 2 ranks but does not go to all bytes,
+//           Entry[i] defines which DQ bytes Group i services
+// DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+// DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+// DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+//                For DDR, DQByteMap[3:1] = [0xFF, 0]
+// DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+//                               Variable only exists to make the code easier to use
+// DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+//                               Variable only exists to make the code easier to use
+//
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for WHL RVP3, WHL SDS - used by WHL/WHL MRC
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqByteMapWhlUDdr4Rvp[2][6][2] = {
+  // Channel 0:
+  {
+    { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  },
+  // Channel 1:
+  {
+    { 0x33, 0xCC }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+    { 0x00, 0xCC }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+    { 0x33, 0xCC }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+    { 0x33, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+    { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+    { 0xFF, 0x00 }  // CA Vref is one for all bytes
+  }
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mDqsMapCpu2DramWhlUDdr4Rvp[2][8] = {
+  { 0, 1, 3, 2, 4, 5, 6, 7 }, // Channel 0
+  { 1, 0, 4, 5, 2, 3, 6, 7 }  // Channel 1
+};
+
+//
+// DQS byte swizzling between CPU and DRAM
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 DqsMapCpu2DramWhlUmDvp[2][8] = {
+  { 0, 3, 1, 2, 7, 5, 6, 4 }, // Channel 0
+  { 0, 2, 1, 3, 6, 4, 7, 5 }  // Channel 1
+};
+
+//
+// Reference RCOMP resistors on motherboard
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorCflUDdr4Interposer[SA_MRC_MAX_RCOMP] = { 121, 81, 100 };
+
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetWhlUDdr4Interposer[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 20, 20, 26 };
+
+#endif // _BOARD_SA_CONFIG_PRE_MEM_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
new file mode 100644
index 0000000000..a943d5bd04
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
@@ -0,0 +1,225 @@
+/** @file
+  GPIO definition table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_TABLE_DEFAULT_H_
+#define _GPIO_TABLE_DEFAULT_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+#define END_OF_GPIO_TABLE 0xFFFFFFFF
+
+//
+// CNL U DRR4 Board GPIO table configuration is used as default
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG mGpioTableDefault[] =
+{
+//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,  GPIRoutConfig,  PadRstCfg,  Term,
+  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_0
+  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_1
+  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CSB
+  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
+  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
+  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
+  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //WWAN_WAKE_N
+  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2, GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault, GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
+  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset, GpioTermNone } },  //DGPU_SEL_SLOT1
+  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
+  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPKR_PD_N
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WFCAM_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //ACCEL_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //ALS_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //HALL_SENSOR_INT
+  //(RC control) {GPIO_CNL_LP_GPP_A22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_WAKE
+  //(RC control) {GPIO_CNL_LP_GPP_A23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpu20K }},  //SHARED_INT
+  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock } },  //BT_UART_WAKE
+  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock | GpioOutputStateUnlock }},  //FORCE_PAD_INT
+  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone , GpioPadConfigUnlock} },  //BT_DISABLE_N
+  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
+  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
+  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
+  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //TCH_PNL_PWR_EN
+  //(CSME Pad) {GPIO_CNL_LP_GPP_B15,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //NFC_DFU
+  { GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
+  { GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock} },  //FPS_RESET_N
+  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},  //TBT_CIO_PWR_EN
+  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
+  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone}},  //EC_SLP_S0_CS_N
+  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
+  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,  GpioTermNone }},  //WIFI_RF_KILL_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
+  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIFI_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermWpu20K } },  //CODEC_INT_N
+  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
+  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone}},  //TBT_FORCE_PWR
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_PWREN_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
+  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
+  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
+  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
+  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL2_RST_N
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SLOT1_WAKE_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //NFC_RST_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,  GpioTermNone }},  //WWAN_PWREN
+  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL_RST_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //NFC_INT_N
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
+  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
+  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
+  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
+  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
+  {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
+  {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
+  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
+  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
+  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
+  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,  GpioTermWpu20K}},  //Reserved for SATA HP val
+  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,  GpioTermNone}},  //EC_SMI_N
+  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
+  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SSD_DEVSLP
+  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //HDD_DEVSLP
+  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL_INT_N
+  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
+  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
+  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
+  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
+  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
+  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
+  //(Not used){GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F0_COEX3
+  {GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},  //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_HDD_PWREN
+  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WF_CLK_EN
+  //(RC control) {GPIO_CNL_LP_GPP_F4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_BRI_DT_UART0_RTSB
+  //(RC control) {GPIO_CNL_LP_GPP_F5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_BRI_RSP_UART0_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_F6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_RGI_DT_UART0_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_F7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_RGI_RSP_UART0_CTSB
+  {GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_MFUART2_RXD
+  {GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //CNV_MFUART2_TXD
+
+  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be used at IsRecoveryMode()
+  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone}},  //BIOS_REC
+
+  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
+  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
+  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
+  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
+  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
+  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
+  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
+  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
+  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
+  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_F_23
+  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
+  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
+  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
+  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
+  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
+  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
+  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpd20K }},  //GPP_G_7_SD3_WP
+  //{GPIO_CNL_LP_GPP_H0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_0_SSP2_SCLK
+  //{GPIO_CNL_LP_GPP_H1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_1_SSP2_SFRM
+  //{GPIO_CNL_LP_GPP_H2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_2_SSP2_TXD
+  //{GPIO_CNL_LP_GPP_H3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPP_H_3_SSP2_RXD
+  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
+  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_PWREN
+  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_RECOVERY
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IRIS_STROBE
+  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL0
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
+  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_KEY
+  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
+  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
+  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
+  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL1
+  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
+  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H21
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WF_CAM_RST
+  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H23
+  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
+  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //BC_ACOK
+  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
+  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
+  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
+  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SLP_A_N
+  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPD_7
+  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SUS_CLK
+  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
+  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
+  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpd20K }}, // 20K PD for PECI
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_INIT_CONFIG mGpioTablePreMemDefault[] =
+{
+  {END_OF_GPIO_TABLE,  {GpioPadModeGpio,    GpioHostOwnGpio, GpioDirNone,  GpioOutDefault, GpioIntDis, GpioDswReset,  GpioTermNone}},//Marking End of Table
+};
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
new file mode 100644
index 0000000000..86b7cb3717
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
@@ -0,0 +1,284 @@
+/** @file
+  GPIO definition table for WhiskeyLake U Ddr4 RVP
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+#define _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4_0[] =
+{
+//                      Pmode,  GPI_IS,  GpioDir,  GPIOTxState,  RxEvCfg,  GPIRoutConfig,  PadRstCfg,  Term,
+  //{GPIO_CNL_LP_GPP_A0,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A1,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_0
+  //{GPIO_CNL_LP_GPP_A2,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_1
+  //{GPIO_CNL_LP_GPP_A3,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A4,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_IO_2
+  //{GPIO_CNL_LP_GPP_A5,  { GpioPadModeNative2,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CSB
+  //{GPIO_CNL_LP_GPP_A6,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //GPPC_A6_SERIRQ
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //SPI_TPM_INT_N
+  //{GPIO_CNL_LP_GPP_A8,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_A9,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_CLK
+  //{GPIO_CNL_LP_GPP_A10,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //{GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //WWAN_WAKE_N
+  // (RC control) {GPIO_CNL_LP_GPP_A12, { GpioPadModeNative2, GpioHostOwnDefault, GpioDirInOut, GpioOutDefault, GpioIntDefault, GpioPlatformReset, GpioTermNone }},  //SLATEMODE_HALLOUT
+  {GPIO_CNL_LP_GPP_A13, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDefault, GpioPlatformReset, GpioTermNone } },  //DGPU_SEL_SLOT1
+  //(Default HW)  {GPIO_CNL_LP_GPP_A14,  { GpioPadModeNative2,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //eSPI_Reset
+  {GPIO_CNL_LP_GPP_A15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPKR_PD_N
+  {GPIO_CNL_LP_GPP_A16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutLow, GpioIntDefault, GpioPlatformReset, GpioTermWpu20K, GpioPadUnlock }},  //WFCAM_PWREN
+  //(RC control) {GPIO_CNL_LP_GPP_A17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SD_PWREN
+  //A18-A23 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_A18,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //ACCEL_INT
+  {GPIO_CNL_LP_GPP_A19,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //ALS_INT
+  {GPIO_CNL_LP_GPP_A20,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //HUMAN_PRESENCE_INT
+  {GPIO_CNL_LP_GPP_A21,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //HALL_SENSOR_INT
+  {GPIO_CNL_LP_GPP_A22,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //IVCAM_WAKE
+  {GPIO_CNL_LP_GPP_A23,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //SHARED_INT
+  //(Not used) {GPIO_CNL_LP_GPP_B0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  //(Not used) {GPIO_CNL_LP_GPP_B1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDis,  GpioResetDefault,  GpioTermNone }},  //CORE_VID0
+  {GPIO_CNL_LP_GPP_B2, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset, GpioTermNone, GpioPadUnlock } },  //BT_UART_WAKE
+  {GPIO_CNL_LP_GPP_B3, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadUnlock }},  //FORCE_PAD_INT
+  {GPIO_CNL_LP_GPP_B4, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioHostDeepReset, GpioTermNone , GpioOutputStateUnlock} },  //BT_DISABLE_N
+  //(RC control) {GPIO_CNL_LP_GPP_B5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WWAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_NAND_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //LAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //WLAN_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT1_CLK_REQ
+  //(RC control) {GPIO_CNL_LP_GPP_B10,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //PCIE_SLOT2_CLK_REQ
+  {GPIO_CNL_LP_GPP_B11, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},
+  //(Default HW)  {GPIO_CNL_LP_GPP_B12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S0_N
+  //(Default HW)  {GPIO_CNL_LP_GPP_B13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PLT_RST_N
+  {GPIO_CNL_LP_GPP_B14, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //TCH_PNL_PWR_EN
+  //B15 -Unused pin -> Under GPIO table for GPIO Termination - Input sensing disable
+  {GPIO_CNL_LP_GPP_B15, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,  GpioTermNone }},  //Former NFC_DFU
+  {GPIO_CNL_LP_GPP_B16, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock } },  //FPS_INT_N
+  {GPIO_CNL_LP_GPP_B17, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone, GpioPadConfigUnlock} },  //FPS_RESET_N
+  {GPIO_CNL_LP_GPP_B18, { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioPlatformReset, GpioTermNone }},  //TBT_CIO_PWR_EN
+  //(RC control) {GPIO_CNL_LP_GPP_B19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CS_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_CLK_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MISO_FPS
+  //(RC control) {GPIO_CNL_LP_GPP_B22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GSPI1_MOSI_FPS
+  {GPIO_CNL_LP_GPP_B23, { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone, GpioPadUnlock }},  //EC_SLP_S0_CS_N
+  //(RC control) {GPIO_CNL_LP_GPP_C0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_C1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SMB_DATA
+  {GPIO_CNL_LP_GPP_C2, { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioHostDeepReset,  GpioTermNone, GpioOutputStateUnlock }},  //WIFI_RF_KILL_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_CLK
+  //(CSME Pad) {GPIO_CNL_LP_GPP_C4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SML0_DATA
+  {GPIO_CNL_LP_GPP_C5, { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv,  GpioOutDefault,  GpioIntLevel | GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIFI_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_C6,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  //(Not used) {GPIO_CNL_LP_GPP_C7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},
+  { GPIO_CNL_LP_GPP_C8, { GpioPadModeGpio, GpioHostOwnAcpi , GpioDirIn , GpioOutDefault , GpioIntLevel | GpioIntApic , GpioPlatformReset, GpioTermWpu20K } },  //CODEC_INT_N
+  { GPIO_CNL_LP_GPP_C9, { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntEdge | GpioIntSci, GpioPlatformReset, GpioTermWpu20K, GpioPadConfigUnlock }},  //TBT_CIO_PLUG_EVENT_N
+  {GPIO_CNL_LP_GPP_C10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //TBT_FORCE_PWR
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnAcpi, GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock } },  //IVCAM_WAKE_N
+  //move to premem phase for early power turn on
+  //  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  //  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_PWREN_N
+  //  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_PWREN_N
+  //  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+
+  //Only clear Reset pins in Post-Mem
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //PCIE_NAND_RST_N
+  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+
+  //(RC control) {GPIO_CNL_LP_GPP_C16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_C19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //I2C1_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_C20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RXD
+  //(RC control) {GPIO_CNL_LP_GPP_C21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_TXD
+  //(RC control) {GPIO_CNL_LP_GPP_C22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_RTS
+  //(RC control) {GPIO_CNL_LP_GPP_C23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //UART2_CTS
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CS0_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_CLK_N
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MISO
+  //(CSME Pad) {GPIO_CNL_LP_GPP_D3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_MOSI
+  //(RC control) {GPIO_CNL_LP_GPP_D4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT
+  //(RC control) {GPIO_CNL_LP_GPP_D5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C0_SCL
+  //(RC control) {GPIO_CNL_LP_GPP_D7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SDA
+  //(RC control) {GPIO_CNL_LP_GPP_D8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //ISH_I2C1_SCL
+  {GPIO_CNL_LP_GPP_D9,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL2_RST_N
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntEdge | GpioIntApic,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_D11,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirInInv ,  GpioOutDefault,  GpioIntLevel| GpioIntSci,  GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},  //SLOT1_WAKE_N
+  //(Not used) {GPIO_CNL_LP_GPP_D12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //Former NFC_RST_N
+  //{GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioResumeReset,  GpioTermNone }},  //WWAN_PWREN
+  {GPIO_CNL_LP_GPP_D14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDis,  GpioPlatformReset,  GpioTermNone }},  //TCH_PNL_RST_N
+  //(Not used) {GPIO_CNL_LP_GPP_D15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //Former NFC_INT_N
+  //{GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_WAKE_N
+  //(RC control) {GPIO_CNL_LP_GPP_D17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_1
+  //(RC control) {GPIO_CNL_LP_GPP_D18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_1
+  //(RC control) {GPIO_CNL_LP_GPP_D19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_CLK_0
+  //(RC control) {GPIO_CNL_LP_GPP_D20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //DMIC_DATA_0
+  //(CSME control) {GPIO_CNL_LP_GPP_D21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO2
+  //(CSME control) {GPIO_CNL_LP_GPP_D22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirInOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SPI1_TCH_PNL_IO3
+  //(RC control) {GPIO_CNL_LP_GPP_D23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //SSP_MCLK
+  //(Not used) {GPIO_CNL_LP_GPP_E0,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K }},  //Reserved for SATA/PCIE detect
+  //(RC control) {GPIO_CNL_LP_GPP_E1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone }},  //M.2_SSD_DET
+  {GPIO_CNL_LP_GPP_E2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDis,  GpioPlatformReset,  GpioTermWpu20K}},  //Reserved for SATA HP val
+  {GPIO_CNL_LP_GPP_E3,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntSmi,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock}},  //EC_SMI_N
+  {GPIO_CNL_LP_GPP_E4,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntSci,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //DGPU_PWROK
+  //(RC control) {GPIO_CNL_LP_GPP_E5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SSD_DEVSLP
+  //(RC control) {GPIO_CNL_LP_GPP_E6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntLevel|GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //HDD_DEVSLP
+  {GPIO_CNL_LP_GPP_E7,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntEdge|GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadConfigUnlock }},  //TCH_PNL_INT_N
+  //(RC control) {GPIO_CNL_LP_GPP_E8,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //SATA_LED_N
+  //(RC control) {GPIO_CNL_LP_GPP_E9,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E10,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //BSSB_DI
+  //(RC control) {GPIO_CNL_LP_GPP_E11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_2
+  //(RC control) {GPIO_CNL_LP_GPP_E12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermNone }},  //USB_OC_3
+  //(RC control) {GPIO_CNL_LP_GPP_E13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_HPD_EC
+  //(RC control) {GPIO_CNL_LP_GPP_E15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //EDP_HPD
+  //(RC control) {GPIO_CNL_LP_GPP_E18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI1_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI2_CTRL_DATA
+  //(RC control) {GPIO_CNL_LP_GPP_E22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_CLK
+  //(RC control) {GPIO_CNL_LP_GPP_E23,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI3_CTRL_DATA
+   //F0- unused pin-Input Sensing disable F4-F7 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_F0,  { GpioPadModeGpio,  GpioHostOwnDefault,  GpioDirNone,  GpioOutHigh,  GpioIntLevel,  GpioResumeReset,  GpioTermNone }},  //GPP_F0_COEX3
+  //{GPIO_CNL_LP_GPP_F1,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutHigh, GpioIntDis, GpioResumeReset, GpioTermWpu20K }},  //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_F2,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K }},  //SATA_HDD_PWREN
+  {GPIO_CNL_LP_GPP_F3,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K, GpioPadUnlock }},  //WF_CLK_EN
+  {GPIO_CNL_LP_GPP_F4,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_BRI_DT_UART0_RTSB
+  {GPIO_CNL_LP_GPP_F5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_BRI_RSP_UART0_RXD
+  {GPIO_CNL_LP_GPP_F6,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_RGI_DT_UART0_TXD
+  {GPIO_CNL_LP_GPP_F7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_RGI_RSP_UART0_CTSB
+  //{GPIO_CNL_LP_GPP_F8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_MFUART2_RXD
+  //{GPIO_CNL_LP_GPP_F9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //CNV_MFUART2_TXD
+
+  //Also need to assign same GPIO pin to PcdRecoveryModeGpio which will be used at IsRecoveryMode()
+  {GPIO_CNL_LP_GPP_F10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirIn,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermWpu20K}},  //BIOS_REC
+
+  //(RC control)  {GPIO_CNL_LP_GPP_F11,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F11_EMMC_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_F12,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F12_EMMC_DATA0
+  //(RC control)  {GPIO_CNL_LP_GPP_F13,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F13_EMMC_DATA1
+  //(RC control)  {GPIO_CNL_LP_GPP_F14,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F14_EMMC_DATA2
+  //(RC control)  {GPIO_CNL_LP_GPP_F15,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F15_EMMC_DATA3
+  //(RC control)  {GPIO_CNL_LP_GPP_F16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F16_EMMC_DATA4
+  //(RC control)  {GPIO_CNL_LP_GPP_F17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F17_EMMC_DATA5
+  //(RC control)  {GPIO_CNL_LP_GPP_F18,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F18_EMMC_DATA6
+  //(RC control)  {GPIO_CNL_LP_GPP_F19,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F19_EMMC_DATA7
+  //(RC control)  {GPIO_CNL_LP_GPP_F20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F20_EMMC_RCLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F21,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F21_EMMC_CLK
+  //(RC control)  {GPIO_CNL_LP_GPP_F22,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_F22_EMMC_RESETB
+  //{GPIO_CNL_LP_GPP_F23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_F_23
+  //(RC control)  {GPIO_CNL_LP_GPP_G0,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_0_SD3_CMD
+  //(RC control)  {GPIO_CNL_LP_GPP_G1,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_1_SD3_D0_SD4_RCLK_P
+  //(RC control)  {GPIO_CNL_LP_GPP_G2,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_2_SD3_D1_SD4_RCLK_N
+  //(RC control)  {GPIO_CNL_LP_GPP_G3,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_3_SD3_D2
+  //(RC control)  {GPIO_CNL_LP_GPP_G4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNative }},  //GPP_G_4_SD3_D3
+  {GPIO_CNL_LP_GPP_G5,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_G_5_SD3_CDB
+  //(Default HW)  {GPIO_CNL_LP_GPP_G6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPP_G_6_SD3_CLK
+  {GPIO_CNL_LP_GPP_G7,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpd20K }},  //GPP_G_7_SD3_WP
+  //H0-H3 -> Under GPIO table for GPIO Termination -20K WPU
+  {GPIO_CNL_LP_GPP_H0,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_0_SSP2_SCLK
+  {GPIO_CNL_LP_GPP_H1,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_1_SSP2_SFRM
+  {GPIO_CNL_LP_GPP_H2,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_2_SSP2_TXD
+  {GPIO_CNL_LP_GPP_H3,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermWpu20K }},  //GPP_H_3_SSP2_RXD
+  //(RC control)  {GPIO_CNL_LP_GPP_H4,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_4_I2C2_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H5,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_5_I2C2_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H6,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_6_I2C3_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H7,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_7_I2C3_SCL
+  //(RC control)  {GPIO_CNL_LP_GPP_H8,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_8_I2C4_SDA
+  //(RC control)  {GPIO_CNL_LP_GPP_H9,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H_9_I2C4_SCL
+  {GPIO_CNL_LP_GPP_H10,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_PWREN
+  {GPIO_CNL_LP_GPP_H11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_RECOVERY
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IRIS_STROBE
+  {GPIO_CNL_LP_GPP_H13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL0
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //UF_CAM_PRIVACY_LED
+  {GPIO_CNL_LP_GPP_H15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_KEY
+  //(Not used) {GPIO_CNL_LP_GPP_H16,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_CLK
+  //(Not used) {GPIO_CNL_LP_GPP_H17,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //DDI4_CTRL_DATA
+  //(Default HW)  {GPIO_CNL_LP_GPP_H18,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirOut,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //VCCIO_LPM
+  {GPIO_CNL_LP_GPP_H19,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IVCAM_MUX_SEL1
+  //(RC control) {GPIO_CNL_LP_GPP_H20,  { GpioPadModeNative1,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //IMGCLKOUT_WF_CAM
+  //(Not used) {GPIO_CNL_LP_GPP_H21,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H21
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutHigh,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone, GpioPadUnlock }},  //WF_CAM_RST
+  //(Not used) {GPIO_CNL_LP_GPP_H23,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioPlatformReset,  GpioTermNone }},  //GPP_H23
+  //(Default HW)  {GPIO_CNL_LP_GPD0,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_BATLOW_N
+  //(Default HW)  {GPIO_CNL_LP_GPD1,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //BC_ACOK
+  //(Default HW)  {GPIO_CNL_LP_GPD2,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LAN_WAKE
+  //(Default HW)  {GPIO_CNL_LP_GPD3,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_PWRBTN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD4,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S3_N
+  //(Default HW)  {GPIO_CNL_LP_GPD5,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S4_N
+  //(Default HW)  {GPIO_CNL_LP_GPD6,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SLP_A_N
+  //{GPIO_CNL_LP_GPD7,  { GpioPadModeNotUsed,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //GPD_7
+  //(Default HW)  {GPIO_CNL_LP_GPD8,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //SUS_CLK
+  //(Default HW)  {GPIO_CNL_LP_GPD9,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_WLAN_N
+  //(Default HW)  {GPIO_CNL_LP_GPD10,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //PM_SLP_S5_N
+  //(Default HW)  {GPIO_CNL_LP_GPD11,  { GpioPadModeNative1,  GpioHostOwnGpio,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioResetDefault,  GpioTermNone }},  //LANPHY_EN
+  {GPIO_CNL_LP_PECI,  { GpioHardwareDefault,  GpioHostOwnDefault,  GpioDirDefault,  GpioOutDefault,  GpioIntDefault,  GpioHostDeepReset,  GpioTermWpd20K }}, // 20K PD for PECI
+};
+
+static GPIO_INIT_CONFIG mGpioTableCflUDdr4[] = {
+  //                       Pmode,                GPI_IS,             GpioDir,        GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
+  // WiGig start
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioHostDeepReset,  GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio,      GpioHostOwnGpio,   GpioDirInInv,    GpioOutHigh, GpioIntLevel | GpioIntSci,    GpioHostDeepReset,  GpioTermNone, GpioPadConfigUnlock }},  //WIGIG_PEWAKE_R_N / WF_CAM_RST on CNL U
+  //WiGig end
+  // Camera start
+  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio,      GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio,      GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
+  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio,      GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,               GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  // Camera end
+  // Touch start
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio,      GpioHostOwnGpio,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
+  // Touch end
+  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio,      GpioHostOwnAcpi,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,    GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,      GpioHostOwnAcpi,     GpioDirOut,    GpioOutHigh, GpioIntDis,                   GpioPlatformReset,  GpioTermNone}},  //SLOT1_RST_N
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio,      GpioHostOwnGpio,      GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic,   GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock } },  //SPI_TPM_INT_N                                                                                                                                          // Unused start
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermWpu20K }}, //Unused so disabled / WF_CLK_EN on CNL U
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / Not used on CNL U
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,      GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                   GpioPlatformReset,  GpioTermNone   }}  //Unused so disabled / Not used on CNL U
+  // Unused end
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4[] = {
+  //                       Pmode,                GPI_IS,             GpioDir,        GPIOTxState,    RxEvCfg/GPIRoutConfig,          PadRstCfg,        Term,
+  // WiGig start
+  {GPIO_CNL_LP_GPP_A16,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermWpu20K }}, //M.2_WIGIG_PWREN / WFCAM_PWREN on CNL U
+  {GPIO_CNL_LP_GPP_C11,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioHostDeepReset,  GpioTermWpu20K }}, //M.2_WIGIG_RF_KILL_N / IVCAM_WAKE_N on CNL U
+  // WiGig end
+  // Camera start
+  {GPIO_CNL_LP_GPP_D4,   { GpioPadModeGpio, GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_H12,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / IRIS_STROBE on CNL U
+  {GPIO_CNL_LP_GPP_H14,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / UF_CAM_PRIVACY_LED on CNL U
+  {GPIO_CNL_LP_GPP_H20,  { GpioPadModeGpio, GpioHostOwnGpio, GpioDirDefault, GpioOutDefault, GpioIntDefault,             GpioPlatformReset,  GpioTermNone   }}, //Camera / RC Control on CNL U
+  // Camera end
+  // Touch start
+  {GPIO_CNL_LP_GPP_D10,  { GpioPadModeGpio, GpioHostOwnGpio,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioPlatformReset,  GpioTermWpu20K, GpioPadConfigUnlock }}, //TCH_PNL2_INT_N
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio, GpioHostOwnAcpi,     GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,  GpioTermNone}},    //SLOT1_RST_N
+  // Touch end
+  {GPIO_CNL_LP_GPP_E16,  { GpioPadModeGpio, GpioHostOwnAcpi,   GpioDirInInv, GpioOutDefault, GpioIntLevel | GpioIntSci,  GpioPlatformReset,  GpioTermWpu20K,  GpioPadConfigUnlock }}, //SMC_RUNTIME_SCI_N
+  // TBT start
+  {GPIO_CNL_LP_GPP_H22,  { GpioPadModeGpio, GpioHostOwnGpio,     GpioDirOut,    GpioOutHigh, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }},  //TBT_CIO_PWR_EN
+  // TBT end
+  // TPM interrupt
+  {GPIO_CNL_LP_GPP_A7,   { GpioPadModeGpio, GpioHostOwnGpio,      GpioDirIn, GpioOutDefault, GpioIntLevel | GpioIntApic, GpioHostDeepReset,  GpioTermWpu20K, GpioPadConfigUnlock }},         //SPI_TPM_INT_N
+  // Unused start
+  {GPIO_CNL_LP_GPP_E22,  { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_E23,  { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermNone   }}, //Unused so disabled / RC Control on CNL U
+  {GPIO_CNL_LP_GPP_F3,   { GpioPadModeGpio, GpioHostOwnGpio,    GpioDirNone, GpioOutDefault, GpioIntDis,                 GpioPlatformReset,  GpioTermWpu20K }}  //Unused so disabled / WF_CLK_EN on CNL U
+  // Unused end
+};
+
+
+#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
new file mode 100644
index 0000000000..01a6599564
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
@@ -0,0 +1,59 @@
+/** @file
+  GPIO definition table for WhiskeyLake U Ddr4 RVP Pre-Memory
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+#define _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+
+#include <GpioPinsCnlLp.h>
+#include <Library/GpioLib.h>
+#include <GpioConfig.h>
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4PreMem[] =
+{
+  {GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_RST_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_PWREN_N
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlTbtRvpPreMem[] =
+{
+  // do not reset SLOT1 due to TR AIC card cannot be reset in S3/S4 resume.
+  //{GPIO_CNL_LP_GPP_C15,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_RST_N
+  {GPIO_CNL_LP_GPP_C14,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //SLOT1_PWREN_N
+  {GPIO_CNL_LP_GPP_C12,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutLow,  GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_RST_N
+  {GPIO_CNL_LP_GPP_C13,  { GpioPadModeGpio,  GpioHostOwnAcpi,  GpioDirOut,  GpioOutHigh, GpioIntDis,  GpioPlatformReset,  GpioTermNone}},   //PCIE_NAND_PWREN_N
+};
+
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOnEarlyPreMem[] =
+{
+  // Turn on WWAN power and de-assert reset pins by default
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioPlatformReset, GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
+  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
+};
+
+static GPIO_INIT_CONFIG mGpioTableWhlUDdr4WwanOffEarlyPreMem[] =
+{
+  // Assert reset pins and then turn off WWAN power
+  {GPIO_CNL_LP_GPP_A11,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirInInv, GpioOutDefault, GpioIntLevel|GpioIntSci, GpioHostDeepReset, GpioTermWpu20K, GpioPadConfigUnlock}},   //WWAN_WAKE_N
+  {GPIO_CNL_LP_GPP_D13,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_FCP_OFF
+  {GPIO_CNL_LP_GPP_F1,   { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_RST_N
+  {GPIO_CNL_LP_GPP_E15,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioPlatformReset, GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_PERST
+  {GPIO_CNL_LP_GPP_D16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutLow,     GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //EN_V3.3A_WWAN_LS
+  {GPIO_CNL_LP_GPP_H16,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_WAKE_CTRL
+  {GPIO_CNL_LP_GPP_H17,  { GpioPadModeGpio,  GpioHostOwnGpio,  GpioDirOut,   GpioOutHigh,    GpioIntDis,              GpioResumeReset,   GpioTermNone,   GpioOutputStateUnlock}}, //WWAN_DISABLE_N
+};
+
+#endif // _CANNONLAKE_U_DDR4_GPIO_TABLE_PRE_MEM_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
new file mode 100644
index 0000000000..0d26e8ad7a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
@@ -0,0 +1,3014 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HDA_VERB_TABLES_H_
+#define _PCH_HDA_VERB_TABLES_H_
+
+#include <Ppi/SiPolicy.h>
+
+HDAUDIO_VERB_TABLE HdaVerbTableDisplayAudio = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: CFL Display Audio Codec
+  //  Revision ID = 0xFF
+  //  Codec Vendor: 0x8086280B
+  //
+  0x8086, 0x280B,
+  0xFF, 0xFF,
+  //
+  // Display Audio Verb Table
+  //
+  // For GEN9, the Vendor Node ID is 08h
+  // Port to be exposed to the inbox driver in the vanilla mode: PORT C - BIT[7:6] = 01b
+  0x00878140,
+  // Pin Widget 5 - PORT B - Configuration Default: 0x18560010
+  0x00571C10,
+  0x00571D00,
+  0x00571E56,
+  0x00571F18,
+  // Pin Widget 6 - PORT C - Configuration Default: 0x18560020
+  0x00671C20,
+  0x00671D00,
+  0x00671E56,
+  0x00671F18,
+  // Pin Widget 7 - PORT D - Configuration Default: 0x18560030
+  0x00771C30,
+  0x00771D00,
+  0x00771E56,
+  0x00771F18,
+  // Disable the third converter and third Pin (NID 08h)
+  0x00878140
+);
+
+//
+//codecs verb tables
+//
+HDAUDIO_VERB_TABLE HdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40622005
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D20,
+  0x01D71E62,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B,
+
+
+  //Widget node 0X20 for ALC1305   20160603 update
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+  //
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401FA,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204DE23,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403F5,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x0204AF1B,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E0A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204368E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204800F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02044848,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050000,
+  0x02043330,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050000,
+  0x02043333,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x020402EC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02044909,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x020440B0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040047,
+  0x02050028,
+  0x02040C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040048,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040049,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004A,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040001,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024
+); // HdaVerbTableAlc700
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc701 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC701)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0701
+  //
+  0x10EC, 0x0701,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC701
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0701&SUBSYS_10EC1124
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11030
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40610041
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211020
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC1124
+  0x00172024,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C30,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C41,
+  0x01D71D00,
+  0x01D71E61,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 1 :
+  0x05850000,
+  0x05843888,
+  0x0205006F,
+  0x02042C0B
+); // HdaVerbTableAlc701
+
+HDAUDIO_VERB_TABLE HdaVerbTableAlc274 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC274)
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0274
+  //
+  0x10EC, 0x0274,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.0
+  //Realtek HD Audio Codec : ALC274
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0274&SUBSYS_10EC10F6
+  //The number of verb command block : 16
+
+  //    NID 0x12 : 0x40000000
+  //    NID 0x13 : 0x411111F0
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x411111F0
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A11020
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40451B05
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x04211010
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //,DA Codec Subsystem ID  : 0x10EC10F6
+  0x001720F6,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C00,
+  0x01271D00,
+  0x01271E00,
+  0x01271F40,
+  //Pin widget 0x13 - DMIC
+  0x01371CF0,
+  0x01371D11,
+  0x01371E11,
+  0x01371F41,
+  //Pin widget 0x14 - NPC
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S_OUT2
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S_OUT1
+  0x01771CF0,
+  0x01771D11,
+  0x01771E11,
+  0x01771F41,
+  //Pin widget 0x18 - I2S_IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C20,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C05,
+  0x01D71D1B,
+  0x01D71E45,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C10,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Widget node 0x20 :
+  0x02050045,
+  0x02045289,
+  0x0205006F,
+  0x02042C0B,
+  //Widget node 0x20 - 1 :
+  0x02050035,
+  0x02048968,
+  0x05B50001,
+  0x05B48540,
+  //Widget node 0x20 - 2 :
+  0x05850000,
+  0x05843888,
+  0x05850000,
+  0x05843888,
+  //Widget node 0x20 - 3 :
+  0x0205004A,
+  0x0204201B,
+  0x0205004A,
+  0x0204201B
+); //HdaVerbTableAlc274
+
+//
+// CFL S Audio Codec
+//
+STATIC HDAUDIO_VERB_TABLE CflSHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) CFL S RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC112C
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x90A60130
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x03011010
+  //    NID 0x17 : 0x90170120
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x04A1103E
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x03A11040
+  //    NID 0x1D : 0x40600001
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x0421102F
+  //    NID 0x29 : 0x411111F0
+
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC112C
+  0x0017202C,
+  0x00172111,
+  0x001722EC,
+  0x00172310,
+
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271C30,
+  0x01271D01,
+  0x01271EA6,
+  0x01271F90,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671C10,
+  0x01671D10,
+  0x01671E01,
+  0x01671F03,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C20,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C3E,
+  0x01971D10,
+  0x01971EA1,
+  0x01971F04,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71C40,
+  0x01B71D10,
+  0x01B71EA1,
+  0x01B71F03,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C01,
+  0x01D71D00,
+  0x01D71E60,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C2F,
+  0x02171D10,
+  0x02171E21,
+  0x02171F04,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+  //Widget node 0x20 - 1 : LINE2-VREFO( MIC2-vrefo-R) base on verb_707h of NID 1Bh ,  HP-JD gating MIC2-vrefo-L, bypass DAC02 DRE(NID5B bit14)
+  0x0205006B,
+  0x02044260,
+  0x0205006B,
+  0x02044260,
+  //Widget node 0x20 - 2 : //remove NID 58 realted setting for ALC700
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+  //Widget node 0x20 -3 :  MIC2-Vrefo-R and MIC2-vrefo-L to independent control
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+  //Widget node 0x20 - 4   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+  //Widget node 0x20 - 5  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+
+  //Widget node 0X20 for ALC1305   20181023 update   2W/4ohm to remove ALC1305 EQ setting
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x02042213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204C22E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+);
+
+
+//
+// WHL codecs verb tables
+//
+HDAUDIO_VERB_TABLE WhlHdaVerbTableAlc700 = HDAUDIO_VERB_TABLE_INIT (
+  //
+  //  VerbTable: (Realtek ALC700) WHL RVP
+  //  Revision ID = 0xff
+  //  Codec Verb Table for WHL PCH boards
+  //  Codec Address: CAd value (0/1/2)
+  //  Codec Vendor: 0x10EC0700
+  //
+  0x10EC, 0x0700,
+  0xFF, 0xFF,
+  //===================================================================================================
+  //
+  //                               Realtek Semiconductor Corp.
+  //
+  //===================================================================================================
+
+  //Realtek High Definition Audio Configuration - Version : 5.0.3.1
+  //Realtek HD Audio Codec : ALC700
+  //PCI PnP ID : PCI\VEN_8086&DEV_2668&SUBSYS_72708086
+  //HDA Codec PnP ID : HDAUDIO\FUNC_01&VEN_10EC&DEV_0700&SUBSYS_10EC10F2
+  //The number of verb command block : 17
+
+  //    NID 0x12 : 0x411111F0
+  //    NID 0x13 : 0x40000000
+  //    NID 0x14 : 0x411111F0
+  //    NID 0x15 : 0x411111F0
+  //    NID 0x16 : 0x411111F0
+  //    NID 0x17 : 0x90170110
+  //    NID 0x18 : 0x411111F0
+  //    NID 0x19 : 0x02A19040
+  //    NID 0x1A : 0x411111F0
+  //    NID 0x1B : 0x411111F0
+  //    NID 0x1D : 0x40638029
+  //    NID 0x1E : 0x411111F0
+  //    NID 0x1F : 0x411111F0
+  //    NID 0x21 : 0x02211020
+  //    NID 0x29 : 0x411111F0
+
+  //===== HDA Codec Subsystem ID Verb-table =====
+  //HDA Codec Subsystem ID  : 0x10EC10F2
+  0x001720F2,
+  0x00172110,
+  0x001722EC,
+  0x00172310,
+
+  //===== Pin Widget Verb-table =====
+  //Widget node 0x01 :
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  0x0017FF00,
+  //Pin widget 0x12 - DMIC
+  0x01271CF0,
+  0x01271D11,
+  0x01271E11,
+  0x01271F41,
+  //Pin widget 0x13 - DMIC
+  0x01371C00,
+  0x01371D00,
+  0x01371E00,
+  0x01371F40,
+  //Pin widget 0x14 - FRONT (Port-D)
+  0x01471CF0,
+  0x01471D11,
+  0x01471E11,
+  0x01471F41,
+  //Pin widget 0x15 - I2S-OUT
+  0x01571CF0,
+  0x01571D11,
+  0x01571E11,
+  0x01571F41,
+  //Pin widget 0x16 - LINE3 (Port-B)
+  0x01671CF0,
+  0x01671D11,
+  0x01671E11,
+  0x01671F41,
+  //Pin widget 0x17 - I2S-OUT
+  0x01771C10,
+  0x01771D01,
+  0x01771E17,
+  0x01771F90,
+  //Pin widget 0x18 - I2S-IN
+  0x01871CF0,
+  0x01871D11,
+  0x01871E11,
+  0x01871F41,
+  //Pin widget 0x19 - MIC2 (Port-F)
+  0x01971C40,
+  0x01971D90,
+  0x01971EA1,
+  0x01971F02,
+  //Pin widget 0x1A - LINE1 (Port-C)
+  0x01A71CF0,
+  0x01A71D11,
+  0x01A71E11,
+  0x01A71F41,
+  //Pin widget 0x1B - LINE2 (Port-E)
+  0x01B71CF0,
+  0x01B71D11,
+  0x01B71E11,
+  0x01B71F41,
+  //Pin widget 0x1D - PC-BEEP
+  0x01D71C29,
+  0x01D71D80,
+  0x01D71E63,
+  0x01D71F40,
+  //Pin widget 0x1E - S/PDIF-OUT
+  0x01E71CF0,
+  0x01E71D11,
+  0x01E71E11,
+  0x01E71F41,
+  //Pin widget 0x1F - S/PDIF-IN
+  0x01F71CF0,
+  0x01F71D11,
+  0x01F71E11,
+  0x01F71F41,
+  //Pin widget 0x21 - HP-OUT (Port-I)
+  0x02171C20,
+  0x02171D10,
+  0x02171E21,
+  0x02171F02,
+  //Pin widget 0x29 - I2S-IN
+  0x02971CF0,
+  0x02971D11,
+  0x02971E11,
+  0x02971F41,
+  //Widget node 0x20 - 0  FAKE JD unplug
+  0x02050008,
+  0x0204A80F,
+  0x02050008,
+  0x0204A80F,
+
+  //Widget node 0x20 - 1 : //remove NID 58 realted setting for ALC700  bypass DAC02 DRE(NID5B bit14)
+  0x05B50010,
+  0x05B45C1D,
+  0x0205006F,
+  0x02040F8B,   //Zeek, 0F8Bh
+
+  //Widget node 0x20 -2:
+  0x02050045,
+  0x02045089,
+  0x0205004A,
+  0x0204201B,
+
+  //Widget node 0x20 - 3   From JD detect
+  0x02050008,
+  0x0204A807,
+  0x02050008,
+  0x0204A807,
+
+  //Widget node 0x20 - 4  Pull high ALC700 GPIO5 for AMP1305 PD pin and enable I2S BCLK first
+  0x02050090,
+  0x02040424,
+  0x00171620,
+  0x00171720,
+
+  0x00171520,
+  0x01770740,
+  0x01770740,
+  0x01770740,
+
+  //Widget node 0x20 for ALC1305   20181105 update   2W/4ohm to remove ALC1305 EQ setting and enable ALC1305 silencet detect to prevent I2S noise
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040000,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02045548,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02041000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040600,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FFD0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02040DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x0204005D,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040442,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040005,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040006,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040008,
+  0x02050028,
+  0x0204B000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204002E,
+  0x02050028,
+  0x02040800,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C3,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204D4A0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400CC,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204400A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x020400C1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040320,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040039,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003B,
+  0x02050028,
+  0x0204FFFF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x020400C0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCF0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040080,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040880,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCE0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FCA0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003C,
+  0x02050028,
+  0x0204FC20,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040006,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040080,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C0,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C1,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C2,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C3,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C4,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C5,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C6,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C7,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C8,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400C9,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CA,
+  0x02050028,
+  0x020401F0,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CB,
+  0x02050028,
+  0x0204C1C7,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CC,
+  0x02050028,
+  0x02041C00,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CD,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CE,
+  0x02050028,
+  0x02040200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400CF,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D0,
+  0x02050028,
+  0x020403E1,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D1,
+  0x02050028,
+  0x02040F5A,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D2,
+  0x02050028,
+  0x02041E1E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x020400D3,
+  0x02050028,
+  0x0204083F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040062,
+  0x02050028,
+  0x02048000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040063,
+  0x02050028,
+  0x02045F5F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040064,
+  0x02050028,
+  0x02042000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040065,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040066,
+  0x02050028,
+  0x02044004,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040067,
+  0x02050028,
+  0x02040802,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040068,
+  0x02050028,
+  0x0204890F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040069,
+  0x02050028,
+  0x0204E021,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040070,
+  0x02050028,
+  0x02048012,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040071,
+  0x02050028,
+  0x02043450,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040072,
+  0x02050028,
+  0x02040123,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040073,
+  0x02050028,
+  0x02044543,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040074,
+  0x02050028,
+  0x02042100,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040075,
+  0x02050028,
+  0x02044321,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040076,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040050,
+  0x02050028,
+  0x02048200,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040051,
+  0x02050028,
+  0x02040707,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040052,
+  0x02050028,
+  0x02044090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006A,
+  0x02050028,
+  0x02040090,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204006C,
+  0x02050028,
+  0x0204721F,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040012,
+  0x02050028,
+  0x0204DFDF,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204009E,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040004,
+  0x02050028,
+  0x02040500,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040060,
+  0x02050028,
+  0x0204E213,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003A,
+  0x02050028,
+  0x02041DFE,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204003F,
+  0x02050028,
+  0x02043000,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040040,
+  0x02050028,
+  0x0204000C,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x02040046,
+  0x02050028,
+  0x0204422E,
+  0x02050029,
+  0x0204B024,
+
+  0x02050024,
+  0x02040010,
+  0x02050026,
+  0x0204004B,
+  0x02050028,
+  0x02040000,
+  0x02050029,
+  0x0204B024
+); // WhlHdaVerbTableAlc700
+
+#endif // _PCH_HDA_VERB_TABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
new file mode 100644
index 0000000000..89c780cc0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
+#define _PEI_WHISKEYLAKE_RVP3_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Ppi/SiPolicy.h>
+#include <PchHsioPtssTables.h>
+#include <IoExpander.h>
+
+#include <WhiskeylakeURvpId.h>
+
+extern const UINT8 mDqByteMapSklRvp3[2][6][2];
+extern const UINT8 mDqsMapCpu2DramSklRvp3[2][8];
+extern const UINT8 mSkylakeRvp3Spd110[];
+extern const UINT16 mSkylakeRvp3Spd110Size;
+extern HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[];
+extern UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size;
+extern HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[];
+extern UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size;
+
+extern GPIO_INIT_CONFIG mGpioTableLpddr3Rvp3UcmcDevice[];
+extern UINT16 mGpioTableLpddr3Rvp3UcmcDeviceSize;
+
+extern IO_EXPANDER_GPIO_CONFIG mGpioTableIoExpander[];
+extern UINT16 mGpioTableIoExpanderSize;
+extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3Touchpanel;
+extern GPIO_INIT_CONFIG mGpioTableLpDdr3Rvp3[];
+extern UINT16 mGpioTableLpDdr3Rvp3Size;
+
+#endif // _PEI_Whiskeylake_RVP3_BOARD_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
new file mode 100644
index 0000000000..a6d48e906d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
@@ -0,0 +1,20 @@
+/** @file
+ Header file for DxePolicyBoardConfig library instance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_POLICY_BOARD_CONFIG_H_
+#define _DXE_POLICY_BOARD_CONFIG_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/DxePolicyBoardConfigLib.h>
+
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
new file mode 100644
index 0000000000..03c27f2a41
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
@@ -0,0 +1,23 @@
+/** @file
+ Header file for PeiPolicyBoardConfig library instance.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_BOARD_CONFIG_H_
+#define _PEI_POLICY_BOARD_CONFIG_H_
+
+#include <PiPei.h>
+#include <ConfigBlock/MePeiConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PeiPolicyBoardConfigLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
new file mode 100644
index 0000000000..01b3df984a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
@@ -0,0 +1,41 @@
+/** @file
+  Others Board's PCD function hook.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <GopConfigLib.h>
+
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+EFIAPI
+GopVbtSpecificUpdateNull (
+  IN CHILD_STRUCT **ChildStructPtr
+  )
+{
+  return;
+}
+
+//
+// for CFL U DDR4
+//
+VOID
+EFIAPI
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+)
+{
+  ChildStructPtr[1]->DeviceClass = DISPLAY_PORT_ONLY;
+  ChildStructPtr[1]->DVOPort     = DISPLAY_PORT_B;
+  ChildStructPtr[2]->DeviceClass = DISPLAY_PORT_HDMI_DVI_COMPATIBLE;
+  ChildStructPtr[2]->DVOPort     = DISPLAY_PORT_C;
+  ChildStructPtr[2]->AUX_Channel = AUX_CHANNEL_C;
+  ChildStructPtr[3]->DeviceClass = NO_DEVICE;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
new file mode 100644
index 0000000000..7ebf8f8fdc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
@@ -0,0 +1,137 @@
+/** @file
+  Implementation of BaseGpioCheckConflictLib.
+
+
+  Copyright (c) 2019, 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 <Private/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 Hob Check] Can't find Gpio Hob.\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, "[Hob 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 Check] Identified conflict on pad %a\n", GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad)));
+        }
+      }
+      //
+      // 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 UINT16                    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 how big size the Hob Data needs
+      //
+      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 {
+      GpioCheckConflictHobData[GpioIndex].GpioPad = GpioDefinition[Index].GpioPad;
+      GpioCheckConflictHobData[GpioIndex].GpioPadMode = GpioDefinition[Index].GpioConfig.PadMode;
+      GpioIndex++;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n"));
+  return;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
new file mode 100644
index 0000000000..178ce1a124
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
@@ -0,0 +1,37 @@
+/** @file
+  Implementation of BaseGpioCheckConflicLibNull.
+
+
+  Copyright (c) 2019, 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 UINT16                    GpioTableCount
+  )
+{
+  return;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
new file mode 100644
index 0000000000..24c6fa6277
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
@@ -0,0 +1,156 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PlatformHookLib.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <SystemAgent/Include/SaAccess.h>
+#include <SioRegs.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Register/PchRegsLpc.h>
+#include <PchAccess.h>
+
+#define LPC_SIO_INDEX_DEFAULT_PORT_2              0x2E
+#define LPC_SIO_DATA_DEFAULT_PORT_2               0x2F
+
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_0           0x87
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_1           0x01
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_2           0x55
+#define IT8628_ENTER_CONFIG_WRITE_SEQ_3           0x55
+#define IT8628_EXIT_CONFIG                        0x2
+#define IT8628_CHIPID_BYTE1                       0x86
+#define IT8628_CHIPID_BYTE2                       0x28
+
+typedef struct {
+  UINT8 Register;
+  UINT8 Value;
+} EFI_SIO_TABLE;
+
+//
+// IT8628
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SIO_TABLE mSioIt8628TableSerialPort[] = {
+  {0x023, 0x09}, // Clock Selection register
+  {0x007, 0x01}, // Com1 Logical Device Number select
+  {0x061, 0xF8}, // Serial Port 1 Base Address MSB Register
+  {0x060, 0x03}, // Serial Port 1 Base Address LSB Register
+  {0x070, 0x04}, // Serial Port 1 Interrupt Level Select
+  {0x030, 0x01}, // Serial Port 1 Activate
+  {0x007, 0x02}, // Com1 Logical Device Number select
+  {0x061, 0xF8}, // Serial Port 2 Base Address MSB Register
+  {0x060, 0x02}, // Serial Port 2 Base Address MSB Register
+  {0x070, 0x03}, // Serial Port 2 Interrupt Level Select
+  {0x030, 0x01}  // Serial Port 2 Activate
+};
+
+/**
+  Check whether the IT8628 SIO present on LPC. If yes, enable its serial ports
+**/
+STATIC
+VOID
+It8628SioSerialPortInit (
+  VOID
+  )
+{
+  UINT8   ChipId0;
+  UINT8   ChipId1;
+  UINT16  LpcIoDecondeRangeSet;
+  UINT16  LpcIoDecoodeSet;
+  UINT8   Index;
+  UINT64  LpcBaseAddr;
+
+  ChipId0              = 0;
+  ChipId1              = 0;
+  LpcIoDecondeRangeSet = 0;
+  LpcIoDecoodeSet      = 0;
+
+  //
+  // Enable I/O decoding for COM1 (3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh.
+  //
+  LpcBaseAddr = PCI_SEGMENT_LIB_ADDRESS (
+                  DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPC,
+                  PCI_FUNCTION_NUMBER_PCH_LPC,
+                  0
+                  );
+
+  LpcIoDecondeRangeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOD);
+  LpcIoDecoodeSet = (UINT16) PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOE);
+  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOD), (LpcIoDecondeRangeSet | ((V_LPC_CFG_IOD_COMB_2F8 << 4) | V_LPC_CFG_IOD_COMA_3F8)));
+  PciSegmentWrite16 ((LpcBaseAddr + R_LPC_CFG_IOE), (LpcIoDecoodeSet | (B_LPC_CFG_IOE_SE | B_LPC_CFG_IOE_CBE | B_LPC_CFG_IOE_CAE|B_LPC_CFG_IOE_KE)));
+
+  //
+  // Enter MB PnP Mode
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_0);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_1);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_2);
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_ENTER_CONFIG_WRITE_SEQ_3);
+
+  //
+  // Read Chip Id of SIO IT8628 (registers 0x20 and 0x21)
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x20);
+  ChipId0 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
+
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, 0x21);
+  ChipId1 = IoRead8 (LPC_SIO_DATA_DEFAULT_PORT_2);
+
+  //
+  // Enable Serial Port 1, Port 2
+  //
+  if ((ChipId0 == IT8628_CHIPID_BYTE1) && (ChipId1 == IT8628_CHIPID_BYTE2)) {
+    for (Index = 0; Index < sizeof (mSioIt8628TableSerialPort) / sizeof (EFI_SIO_TABLE); Index++) {
+      IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Register);
+      IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, mSioIt8628TableSerialPort[Index].Value);
+    }
+  }
+
+  //
+  // Exit MB PnP Mode
+  //
+  IoWrite8 (LPC_SIO_INDEX_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
+  IoWrite8 (LPC_SIO_DATA_DEFAULT_PORT_2, IT8628_EXIT_CONFIG);
+
+  return;
+}
+
+/**
+  Performs platform specific initialization required for the CPU to access
+  the hardware associated with a SerialPortLib instance.  This function does
+  not initialize the serial port hardware itself.  Instead, it initializes
+  hardware devices that are required for the CPU to access the serial port
+  hardware.  This function may be called more than once.
+
+  @retval RETURN_SUCCESS       The platform specific initialization succeeded.
+  @retval RETURN_DEVICE_ERROR  The platform specific initialization could not be completed.
+
+**/
+RETURN_STATUS
+EFIAPI
+PlatformHookSerialPortInitialize (
+  VOID
+  )
+{
+  //
+  // Enable I/O decoding for COM1(3F8h-3FFh), COM2(2F8h-2FFh), I/O port 2Eh/2Fh, 4Eh/4Fh, 60h/64Fh and 62h/66h.
+  //
+  PchLpcIoDecodeRangesSet (PcdGet16 (PcdLpcIoDecodeRange));
+  PchLpcIoEnableDecodingSet (PcdGet16 (PchLpcIoEnableDecoding));
+
+  // Configure Sio IT8628
+  It8628SioSerialPortInit ();
+
+  return RETURN_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
new file mode 100644
index 0000000000..e7acbda03a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
@@ -0,0 +1,63 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+BoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  SiliconEnableAcpi (EnableSci);
+  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
+}
+
+EFI_STATUS
+EFIAPI
+BoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  SiliconDisableAcpi (DisableSci);
+  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
+}
+
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
new file mode 100644
index 0000000000..978e367cda
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
@@ -0,0 +1,82 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/MultiBoardAcpiSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  );
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  SiliconEnableAcpi (EnableSci);
+  return WhiskeylakeURvpBoardEnableAcpi (EnableSci);
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  SiliconDisableAcpi (DisableSci);
+  return WhiskeylakeURvpBoardDisableAcpi (DisableSci);
+}
+
+BOARD_ACPI_ENABLE_FUNC  mWhiskeylakeURvpBoardAcpiEnableFunc = {
+  WhiskeylakeURvpMultiBoardEnableAcpi,
+  WhiskeylakeURvpMultiBoardDisableAcpi,
+};
+
+EFI_STATUS
+EFIAPI
+SmmWhiskeylakeURvpMultiBoardAcpiSupportLibConstructor (
+  VOID
+  )
+{
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    return RegisterBoardAcpiEnableFunc (&mWhiskeylakeURvpBoardAcpiEnableFunc);
+  }
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
new file mode 100644
index 0000000000..9daceaa25c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
@@ -0,0 +1,170 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BoardAcpiEnableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <PchAccess.h>
+#include <Library/MmPciLib.h>
+#include <Library/PmcLib.h>
+
+/**
+  Clear Port 80h
+
+  SMI handler to enable ACPI mode
+
+  Dispatched on reads from APM port with value EFI_ACPI_ENABLE_SW_SMI
+
+  Disables the SW SMI Timer.
+  ACPI events are disabled and ACPI event status is cleared.
+  SCI mode is then enabled.
+
+  Clear SLP SMI status
+  Enable SLP SMI
+
+  Disable SW SMI Timer
+
+  Clear all ACPI event status and disable all ACPI events
+
+  Disable PM sources except power button
+  Clear status bits
+
+  Disable GPE0 sources
+  Clear status bits
+
+  Disable GPE1 sources
+  Clear status bits
+
+  Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+
+  Enable SCI
+**/
+EFI_STATUS
+EFIAPI
+SiliconEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+
+  UINT32                              OutputValue;
+  UINT32                              SmiEn;
+  UINT32                              SmiSts;
+  UINT32                              ULKMC;
+  UINTN                               LpcBaseAddress;
+  UINT16                              AcpiBaseAddr;
+  UINT32                              Pm1Cnt;
+
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
+    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    0
+    );
+  //
+  // Get the ACPI Base Address
+  //
+  AcpiBaseAddr = PmcGetAcpiBase();
+  //
+  // BIOS must also ensure that CF9GR is cleared and locked before handing control to the
+  // OS in order to prevent the host from issuing global resets and resetting ME
+  //
+  // EDK2: To match PCCG current BIOS behavior, do not lock CF9 Global Reset
+  // MmioWrite32 (
+  //     PmcBaseAddress + R_PCH_PMC_ETR3),
+  //     PmInit);
+
+  //
+  // Clear Port 80h
+  //
+  IoWrite8 (0x80, 0);
+
+  //
+  // Disable SW SMI Timer and clean the status
+  //
+  SmiEn = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN);
+  SmiEn &= ~(B_ACPI_IO_SMI_EN_LEGACY_USB2 | B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB);
+  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_EN, SmiEn);
+
+  SmiSts = IoRead32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS);
+  SmiSts |= B_ACPI_IO_SMI_EN_LEGACY_USB2 | B_ACPI_IO_SMI_EN_SWSMI_TMR | B_ACPI_IO_SMI_EN_LEGACY_USB;
+  IoWrite32 (AcpiBaseAddr + R_ACPI_IO_SMI_STS, SmiSts);
+
+  //
+  // Disable port 60/64 SMI trap if they are enabled
+  //
+  ULKMC = MmioRead32 (LpcBaseAddress + R_LPC_CFG_ULKMC) & ~(B_LPC_CFG_ULKMC_60REN | B_LPC_CFG_ULKMC_60WEN | B_LPC_CFG_ULKMC_64REN | B_LPC_CFG_ULKMC_64WEN | B_LPC_CFG_ULKMC_A20PASSEN);
+  MmioWrite32 (LpcBaseAddress + R_LPC_CFG_ULKMC, ULKMC);
+
+  //
+  // Disable PM sources except power button
+  //
+  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_EN, B_ACPI_IO_PM1_EN_PWRBTN);
+
+  //
+  // Clear PM status except Power Button status for RapidStart Resume
+  //
+  IoWrite16 (AcpiBaseAddr + R_ACPI_IO_PM1_STS, 0xFEFF);
+
+  //
+  // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+  //
+  IoWrite8 (R_RTC_IO_INDEX_ALT, R_RTC_IO_REGD);
+  IoWrite8 (R_RTC_IO_TARGET_ALT, 0x0);
+
+  //
+  // Write ALT_GPI_SMI_EN to disable GPI1 (SMC_EXTSMI#)
+  //
+  OutputValue = IoRead32 (AcpiBaseAddr + 0x38);
+  OutputValue = OutputValue & ~(1 << (UINTN) PcdGet8 (PcdSmcExtSmiBitPosition));
+  IoWrite32 (AcpiBaseAddr + 0x38, OutputValue);
+
+  //
+  // Enable SCI
+  //
+  if (EnableSci) {
+    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
+    Pm1Cnt |= B_ACPI_IO_PM1_CNT_SCI_EN;
+    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SiliconDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+
+  UINT16                              AcpiBaseAddr;
+  UINT32                              Pm1Cnt;
+
+  //
+  // Get the ACPI Base Address
+  //
+  AcpiBaseAddr = PmcGetAcpiBase();
+  //
+  // Disable SCI
+  //
+  if (DisableSci) {
+    Pm1Cnt = IoRead32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT);
+    Pm1Cnt &= ~B_ACPI_IO_PM1_CNT_SCI_EN;
+    IoWrite32 (AcpiBaseAddr + R_ACPI_IO_PM1_CNT, Pm1Cnt);
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
new file mode 100644
index 0000000000..97a3fae51b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
@@ -0,0 +1,40 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardEnableAcpi (
+  IN BOOLEAN  EnableSci
+  )
+{
+  // enable additional board register
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDisableAcpi (
+  IN BOOLEAN  DisableSci
+  )
+{
+  // enable additional board register
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
new file mode 100644
index 0000000000..7a2fed9904
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
@@ -0,0 +1,19 @@
+/** @file
+  Board's PCD function hook.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+EFI_STATUS
+PeiBoardSpecificInitPostMemNull (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
new file mode 100644
index 0000000000..5104329825
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
@@ -0,0 +1,27 @@
+/** @file
+  Source code for the board configuration init function in Post Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include "BoardFunc.h"
+
+/**
+  Board's PCD function hook init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardFunctionInit (
+  IN UINT16 BoardId
+)
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
new file mode 100644
index 0000000000..3a42a9bd03
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
@@ -0,0 +1,41 @@
+/** @file
+  Source code for the board configuration init function in Post Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <GopConfigLib.h>
+//
+// Null function for nothing GOP VBT update.
+//
+VOID
+GopVbtSpecificUpdateNull(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+//
+// for CFL U DDR4
+//
+VOID
+CflUDdr4GopVbtSpecificUpdate(
+  IN CHILD_STRUCT **ChildStructPtr
+);
+/**
+  Board's PCD function hook init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardFunctionInitPreMem (
+  IN UINT16 BoardId
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
new file mode 100644
index 0000000000..458a73f892
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
@@ -0,0 +1,398 @@
+/** @file
+ Source code for the board PCH configuration Pcd init functions for Pre-Mmeory Init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <PlatformBoardConfig.h>        // for USB 20 AFE & Root Port Clk Info.
+#include "GpioTableWhlUDdr4PreMem.h"
+#include <Library/BaseMemoryLib.h>
+
+/**
+  Board Root Port Clock Info configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+RootPortClkInfoInit (
+  IN UINT16 BoardId
+  )
+{
+  PCD64_BLOB                      *Clock;
+  UINT32                          Index;
+
+  Clock = AllocateZeroPool (16 * sizeof (PCD64_BLOB));
+  ASSERT (Clock != NULL);
+  if (Clock == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // The default clock assignment will be FREE_RUNNING, which corresponds to PchClockUsageUnspecified
+  // This is safe but power-consuming setting. If Platform code doesn't contain port-clock map for a given board,
+  // the clocks will keep on running anyway, allowing PCIe devices to operate. Downside is that clocks will
+  // continue to draw power. To prevent this, remember to provide port-clock map for every board.
+  //
+  for (Index = 0; Index < 16; Index++) {
+    Clock[Index].PcieClock.ClkReqSupported = TRUE;
+    Clock[Index].PcieClock.ClockUsage = FREE_RUNNING;
+  }
+
+  ///
+  /// Assign ClkReq signal to root port. (Base 0)
+  /// For LP, Set 0 - 5
+  /// For H,  Set 0 - 15
+  /// Note that if GbE is enabled, ClkReq assigned to GbE will not be available for Root Port.
+  ///
+  switch (BoardId) {
+    // CLKREQ
+    case BoardIdWhiskeyLakeRvp:
+      Clock[0].PcieClock.ClockUsage = PCIE_PCH + 1;
+      Clock[1].PcieClock.ClockUsage = PCIE_PCH + 8;
+      Clock[2].PcieClock.ClockUsage = LAN_CLOCK;
+      Clock[3].PcieClock.ClockUsage = PCIE_PCH + 13;
+      Clock[4].PcieClock.ClockUsage = PCIE_PCH + 4;
+      Clock[5].PcieClock.ClockUsage = PCIE_PCH + 14;
+      break;
+
+    default:
+      break;
+  }
+
+  PcdSet64S (PcdPcieClock0,  Clock[ 0].Blob);
+  PcdSet64S (PcdPcieClock1,  Clock[ 1].Blob);
+  PcdSet64S (PcdPcieClock2,  Clock[ 2].Blob);
+  PcdSet64S (PcdPcieClock3,  Clock[ 3].Blob);
+  PcdSet64S (PcdPcieClock4,  Clock[ 4].Blob);
+  PcdSet64S (PcdPcieClock5,  Clock[ 5].Blob);
+  PcdSet64S (PcdPcieClock6,  Clock[ 6].Blob);
+  PcdSet64S (PcdPcieClock7,  Clock[ 7].Blob);
+  PcdSet64S (PcdPcieClock8,  Clock[ 8].Blob);
+  PcdSet64S (PcdPcieClock9,  Clock[ 9].Blob);
+  PcdSet64S (PcdPcieClock10, Clock[10].Blob);
+  PcdSet64S (PcdPcieClock11, Clock[11].Blob);
+  PcdSet64S (PcdPcieClock12, Clock[12].Blob);
+  PcdSet64S (PcdPcieClock13, Clock[13].Blob);
+  PcdSet64S (PcdPcieClock14, Clock[14].Blob);
+  PcdSet64S (PcdPcieClock15, Clock[15].Blob);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board USB related configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+UsbConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  PCD32_BLOB *UsbPort20Afe;
+
+  UsbPort20Afe = AllocateZeroPool (PCH_MAX_USB2_PORTS * sizeof (PCD32_BLOB));
+  ASSERT (UsbPort20Afe != NULL);
+  if (UsbPort20Afe == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // USB2 AFE settings.
+  //
+  UsbPort20Afe[0].Info.Petxiset   = 7;
+  UsbPort20Afe[0].Info.Txiset     = 5;
+  UsbPort20Afe[0].Info.Predeemp   = 3;
+  UsbPort20Afe[0].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[1].Info.Petxiset   = 7;
+  UsbPort20Afe[1].Info.Txiset     = 5;
+  UsbPort20Afe[1].Info.Predeemp   = 3;
+  UsbPort20Afe[1].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[2].Info.Petxiset   = 7;
+  UsbPort20Afe[2].Info.Txiset     = 5;
+  UsbPort20Afe[2].Info.Predeemp   = 3;
+  UsbPort20Afe[2].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[3].Info.Petxiset   = 7;
+  UsbPort20Afe[3].Info.Txiset     = 5;
+  UsbPort20Afe[3].Info.Predeemp   = 3;
+  UsbPort20Afe[3].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[4].Info.Petxiset   = 7;
+  UsbPort20Afe[4].Info.Txiset     = 5;
+  UsbPort20Afe[4].Info.Predeemp   = 3;
+  UsbPort20Afe[4].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[5].Info.Petxiset   = 7;
+  UsbPort20Afe[5].Info.Txiset     = 5;
+  UsbPort20Afe[5].Info.Predeemp   = 3;
+  UsbPort20Afe[5].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[6].Info.Petxiset   = 7;
+  UsbPort20Afe[6].Info.Txiset     = 5;
+  UsbPort20Afe[6].Info.Predeemp   = 3;
+  UsbPort20Afe[6].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[7].Info.Petxiset   = 7;
+  UsbPort20Afe[7].Info.Txiset     = 5;
+  UsbPort20Afe[7].Info.Predeemp   = 3;
+  UsbPort20Afe[7].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[8].Info.Petxiset   = 7;
+  UsbPort20Afe[8].Info.Txiset     = 5;
+  UsbPort20Afe[8].Info.Predeemp   = 3;
+  UsbPort20Afe[8].Info.Pehalfbit  = 0;
+
+  UsbPort20Afe[9].Info.Petxiset   = 7;
+  UsbPort20Afe[9].Info.Txiset     = 5;
+  UsbPort20Afe[9].Info.Predeemp   = 3;
+  UsbPort20Afe[9].Info.Pehalfbit  = 0;
+
+  //
+  // USB Port Over Current Pin
+  //
+  PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinMax);
+
+  PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinMax);
+  PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinMax);
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdUsb20OverCurrentPinPort0, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort1, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort2, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort3, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb20OverCurrentPinPort4, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort5, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort6, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort7, UsbOverCurrentPin3);
+      PcdSet8S (PcdUsb20OverCurrentPinPort8, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort9, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort10, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort11, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort12, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort13, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort14, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb20OverCurrentPinPort15, UsbOverCurrentPinSkip);
+
+      PcdSet8S (PcdUsb30OverCurrentPinPort0, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort1, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort2, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort3, UsbOverCurrentPin2);
+      PcdSet8S (PcdUsb30OverCurrentPinPort4, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort5, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort6, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort7, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort8, UsbOverCurrentPinSkip);
+      PcdSet8S (PcdUsb30OverCurrentPinPort9, UsbOverCurrentPinSkip);
+
+      // USB2.0 AFE settings
+      UsbPort20Afe[0].Info.Petxiset   = 6;
+      UsbPort20Afe[0].Info.Txiset     = 0;
+      UsbPort20Afe[0].Info.Predeemp   = 3;
+      UsbPort20Afe[0].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[1].Info.Petxiset   = 6;
+      UsbPort20Afe[1].Info.Txiset     = 0;
+      UsbPort20Afe[1].Info.Predeemp   = 3;
+      UsbPort20Afe[1].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[2].Info.Petxiset   = 6;
+      UsbPort20Afe[2].Info.Txiset     = 0;
+      UsbPort20Afe[2].Info.Predeemp   = 3;
+      UsbPort20Afe[2].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[3].Info.Petxiset   = 6;
+      UsbPort20Afe[3].Info.Txiset     = 0;
+      UsbPort20Afe[3].Info.Predeemp   = 3;
+      UsbPort20Afe[3].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[4].Info.Petxiset   = 6;
+      UsbPort20Afe[4].Info.Txiset     = 0;
+      UsbPort20Afe[4].Info.Predeemp   = 3;
+      UsbPort20Afe[4].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[5].Info.Petxiset   = 6;
+      UsbPort20Afe[5].Info.Txiset     = 0;
+      UsbPort20Afe[5].Info.Predeemp   = 3;
+      UsbPort20Afe[5].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[6].Info.Petxiset   = 6;
+      UsbPort20Afe[6].Info.Txiset     = 0;
+      UsbPort20Afe[6].Info.Predeemp   = 3;
+      UsbPort20Afe[6].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[7].Info.Petxiset   = 6;
+      UsbPort20Afe[7].Info.Txiset     = 0;
+      UsbPort20Afe[7].Info.Predeemp   = 3;
+      UsbPort20Afe[7].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[8].Info.Petxiset   = 6;
+      UsbPort20Afe[8].Info.Txiset     = 0;
+      UsbPort20Afe[8].Info.Predeemp   = 3;
+      UsbPort20Afe[8].Info.Pehalfbit  = 0;
+
+      UsbPort20Afe[9].Info.Petxiset   = 6;
+      UsbPort20Afe[9].Info.Txiset     = 0;
+      UsbPort20Afe[9].Info.Predeemp   = 3;
+      UsbPort20Afe[9].Info.Pehalfbit  = 0;
+      break;
+  }
+
+  //
+  // Save USB2.0 AFE blobs
+  //
+  PcdSet32S (PcdUsb20Port0Afe,  UsbPort20Afe[ 0].Blob);
+  PcdSet32S (PcdUsb20Port1Afe,  UsbPort20Afe[ 1].Blob);
+  PcdSet32S (PcdUsb20Port2Afe,  UsbPort20Afe[ 2].Blob);
+  PcdSet32S (PcdUsb20Port3Afe,  UsbPort20Afe[ 3].Blob);
+  PcdSet32S (PcdUsb20Port4Afe,  UsbPort20Afe[ 4].Blob);
+  PcdSet32S (PcdUsb20Port5Afe,  UsbPort20Afe[ 5].Blob);
+  PcdSet32S (PcdUsb20Port6Afe,  UsbPort20Afe[ 6].Blob);
+  PcdSet32S (PcdUsb20Port7Afe,  UsbPort20Afe[ 7].Blob);
+  PcdSet32S (PcdUsb20Port8Afe,  UsbPort20Afe[ 8].Blob);
+  PcdSet32S (PcdUsb20Port9Afe,  UsbPort20Afe[ 9].Blob);
+  PcdSet32S (PcdUsb20Port10Afe, UsbPort20Afe[10].Blob);
+  PcdSet32S (PcdUsb20Port11Afe, UsbPort20Afe[11].Blob);
+  PcdSet32S (PcdUsb20Port12Afe, UsbPort20Afe[12].Blob);
+  PcdSet32S (PcdUsb20Port13Afe, UsbPort20Afe[13].Blob);
+  PcdSet32S (PcdUsb20Port14Afe, UsbPort20Afe[14].Blob);
+  PcdSet32S (PcdUsb20Port15Afe, UsbPort20Afe[15].Blob);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board GPIO Group Tier configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+GpioGroupTierInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // GPIO Group Tier
+  //
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdGpioGroupToGpeDw0, GPIO_CNL_LP_GROUP_GPP_G);
+      PcdSet32S (PcdGpioGroupToGpeDw1, GPIO_CNL_LP_GROUP_SPI);
+      PcdSet32S (PcdGpioGroupToGpeDw2, GPIO_CNL_LP_GROUP_GPP_E);
+      break;
+
+    default:
+      PcdSet32S (PcdGpioGroupToGpeDw0, 0);
+      PcdSet32S (PcdGpioGroupToGpeDw1, 0);
+      PcdSet32S (PcdGpioGroupToGpeDw2, 0);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  GPIO init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+GpioTablePreMemInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // GPIO Table Init.
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdBoardGpioTablePreMem, (UINTN) mGpioTableWhlUDdr4PreMem);
+      PcdSet16S (PcdBoardGpioTablePreMemSize, sizeof (mGpioTableWhlUDdr4PreMem) / sizeof (GPIO_INIT_CONFIG));
+      PcdSet32S (PcdBoardGpioTableWwanOnEarlyPreMem, (UINTN) mGpioTableWhlUDdr4WwanOnEarlyPreMem);
+      PcdSet16S (PcdBoardGpioTableWwanOnEarlyPreMemSize, sizeof (mGpioTableWhlUDdr4WwanOnEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
+      PcdSet32S (PcdBoardGpioTableWwanOffEarlyPreMem, (UINTN) mGpioTableWhlUDdr4WwanOffEarlyPreMem);
+      PcdSet16S (PcdBoardGpioTableWwanOffEarlyPreMemSize, sizeof (mGpioTableWhlUDdr4WwanOffEarlyPreMem) / sizeof (GPIO_INIT_CONFIG));
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PmConfig init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+PchPmConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update PmCofig policy: output voltage of VCCPRIMCORE RAIL when SLP_S0# is asserted based on board HW design
+  // 1) Discete VR or Non Premium PMIC: 0.75V (PcdSlpS0Vm075VSupport)
+  // 2) Premium PMIC: runtime control for voltage (PcdSlpS0VmRuntimeControl)
+  // Only applys to board with PCH-LP. Board with Discrete PCH doesn't need this setting.
+  //
+  switch (BoardId) {
+    // Discrete VR solution
+    case BoardIdWhiskeyLakeRvp:
+      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm075VSupport, TRUE);
+      break;
+
+    default:
+      PcdSetBoolS (PcdSlpS0VmRuntimeControl, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm070VSupport, FALSE);
+      PcdSetBoolS (PcdSlpS0Vm075VSupport, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
new file mode 100644
index 0000000000..17f12c117d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
@@ -0,0 +1,282 @@
+/** @file
+ Source code for the board SA configuration Pcd init functions in Pre-Memory init phase.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BoardInitLib.h"
+#include "BoardSaConfigPreMem.h"
+#include <PlatformBoardConfig.h>
+#include <Library/CpuPlatformLib.h>
+#include "SaPolicyCommon.h"
+
+//
+// Display DDI settings for WHL ERB
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mWhlErbRowDisplayDdiConfig[9] = {
+  DdiPortAEdp,     // DDI Port A Config : DdiPortADisabled = Disabled, DdiPortAEdp = eDP, DdiPortAMipiDsi = MIPI DSI
+  DdiHpdEnable,    // DDI Port B HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdEnable,    // DDI Port C HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdDisable,   // DDI Port D HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiHpdDisable,   // DDI Port F HPD : DdiHpdDisable = Disable, DdiHpdEnable = Enable HPD
+  DdiDdcEnable,    // DDI Port B DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDdcEnable,    // DDI Port C DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDdcEnable,    // DDI Port D DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+  DdiDisable       // DDI Port F DDC : DdiDisable = Disable, DdiDdcEnable = Enable DDC
+};
+
+/**
+  MRC configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId           An unsigned integer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaMiscConfigInit (
+  IN UINT16         BoardId
+  )
+{
+  //
+  // UserBd
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // Assign UserBd to 5 which is assigned to MrcInputs->BoardType btUser4 for ULT platforms.
+      // This is required to skip Memory voltage programming based on GPIO's in MRC
+      //
+      PcdSet8S (PcdSaMiscUserBd, 5); // MrcBoardType btUser4 for ULT platform
+      break;
+
+    default:
+      // MiscPeiPreMemConfig.UserBd = 0 by default.
+      break;
+  }
+
+  PcdSet16S (PcdSaDdrFreqLimit, 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board Memory Init related configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+MrcConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  CPU_FAMILY    CpuFamilyId;
+  CPU_STEPPING  CpuStepping;
+
+  CpuFamilyId = GetCpuFamily();
+  CpuStepping = GetCpuStepping();
+
+  if (CpuFamilyId == EnumCpuCflDtHalo) {
+    PcdSetBoolS (PcdDualDimmPerChannelBoardType, TRUE);
+  } else {
+    PcdSetBoolS (PcdDualDimmPerChannelBoardType, FALSE);
+  }
+
+  //
+  // Example policy for DIMM slots implementation boards:
+  // 1. Assign Smbus address of DIMMs and SpdData will be updated later
+  //    by reading from DIMM SPD.
+  // 2. No need to apply hardcoded SpdData buffers here for such board.
+  //
+  //  Whiskey Lake U RVP has removable DIMM slots.
+  //  So assign all Smbus address of DIMMs and leave PcdMrcSpdData set to 0.
+  //   Example:
+  //   PcdMrcSpdData = 0
+  //   PcdMrcSpdDataSize = 0
+  //   PcdMrcSpdAddressTable0 = 0xA0
+  //   PcdMrcSpdAddressTable1 = 0xA2
+  //   PcdMrcSpdAddressTable2 = 0xA4
+  //   PcdMrcSpdAddressTable3 = 0xA6
+  //
+  //  If a board has soldered down memory. It should use the following settings.
+  //   Example:
+  //   PcdMrcSpdAddressTable0 = 0
+  //   PcdMrcSpdAddressTable1 = 0
+  //   PcdMrcSpdAddressTable2 = 0
+  //   PcdMrcSpdAddressTable3 = 0
+  //   PcdMrcSpdData = static data buffer
+  //   PcdMrcSpdDataSize = sizeof (static data buffer)
+  //
+
+  //
+  // SPD Address Table
+  //
+  PcdSet32S (PcdMrcSpdData, 0);
+  PcdSet16S (PcdMrcSpdDataSize, 0);
+  PcdSet8S (PcdMrcSpdAddressTable0, 0xA0);
+  PcdSet8S (PcdMrcSpdAddressTable1, 0xA2);
+  PcdSet8S (PcdMrcSpdAddressTable2, 0xA4);
+  PcdSet8S (PcdMrcSpdAddressTable3, 0xA6);
+
+  //
+  // DRAM SPD Data & related configuration
+  //
+  // Setting the PCD's to default value (WHL RVP3). It will be overriden to board specific settings below.
+  PcdSet32S (PcdMrcDqByteMap, (UINTN) mDqByteMapWhlUDdr4Rvp);
+  PcdSet16S (PcdMrcDqByteMapSize, sizeof (mDqByteMapWhlUDdr4Rvp));
+  PcdSet32S (PcdMrcDqsMapCpu2Dram, (UINTN) mDqsMapCpu2DramWhlUDdr4Rvp);
+  PcdSet16S (PcdMrcDqsMapCpu2DramSize, sizeof (mDqsMapCpu2DramWhlUDdr4Rvp));
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdMrcRcompResistor, (UINTN) RcompResistorCflUDdr4Interposer);
+      PcdSet32S (PcdMrcRcompTarget, (UINTN) RcompTargetWhlUDdr4Interposer);
+      PcdSetBoolS (PcdMrcDqPinsInterleavedControl, TRUE);
+      PcdSetBoolS (PcdMrcDqPinsInterleaved, TRUE);
+      break;
+
+    default:
+      break;
+  }
+
+  //
+  // CA Vref routing: board-dependent
+  // 0 - VREF_CA goes to both CH_A and CH_B (LPDDR3/DDR3L)
+  // 1 - VREF_CA to CH_A, VREF_DQ_A to CH_B (should not be used)
+  // 2 - VREF_CA to CH_A, VREF_DQ_B to CH_B (DDR4)
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S (PcdMrcCaVrefConfig, 2); // DDR4 boards
+      break;
+
+    default:
+      PcdSet8S (PcdMrcCaVrefConfig, 0); // All DDR3L/LPDDR3/LPDDR4 boards
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Board SA related GPIO configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId   An unsigned integer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaGpioConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update board's GPIO for PEG slot reset
+  //
+  PcdSetBoolS (PcdPegGpioResetControl, TRUE);
+  PcdSetBoolS (PcdPegGpioResetSupoort, FALSE);
+  PcdSet32S (PcdPeg0ResetGpioPad, 0);
+  PcdSetBoolS (PcdPeg0ResetGpioActive, FALSE);
+  PcdSet32S (PcdPeg3ResetGpioPad, 0);
+  PcdSetBoolS (PcdPeg3ResetGpioActive, FALSE);
+
+  //
+  // PCIE RTD3 GPIO
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet8S(PcdRootPortIndex, 4);
+      PcdSet8S (PcdPcie0GpioSupport, PchGpio);
+      PcdSet32S (PcdPcie0WakeGpioNo, 0);
+      PcdSet8S (PcdPcie0HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie0HoldRstGpioNo, GPIO_CNL_LP_GPP_C15);
+      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
+      PcdSet8S (PcdPcie0PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie0PwrEnableGpioNo, GPIO_CNL_LP_GPP_C14);
+      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie1WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie2WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
+      break;
+
+    default:
+      PcdSet8S(PcdRootPortIndex, 0xFF);
+      PcdSet8S  (PcdPcie0GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie0WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie0HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie0HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie0HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie0PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie0PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie0PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie1GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie1WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie1HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie1HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie1HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie1PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie1PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie1PwrEnableActive, FALSE);
+
+      PcdSet8S  (PcdPcie2GpioSupport, NotSupported);
+      PcdSet32S (PcdPcie2WakeGpioNo, 0);
+      PcdSet8S  (PcdPcie2HoldRstExpanderNo, 0);
+      PcdSet32S (PcdPcie2HoldRstGpioNo, 0);
+      PcdSetBoolS (PcdPcie2HoldRstActive, FALSE);
+      PcdSet8S  (PcdPcie2PwrEnableExpanderNo, 0);
+      PcdSet32S (PcdPcie2PwrEnableGpioNo, 0);
+      PcdSetBoolS (PcdPcie2PwrEnableActive, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  SA Display DDI configuration init function for PEI pre-memory phase.
+
+  @param[in]  BoardId       An unsigned integer represent the board id.
+
+  @retval     EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+SaDisplayConfigInit (
+  IN UINT16 BoardId
+  )
+{
+  //
+  // Update Display DDI Config
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S (PcdSaDisplayConfigTable, (UINTN) mWhlErbRowDisplayDdiConfig);
+      PcdSet16S (PcdSaDisplayConfigTableSize, sizeof (mWhlErbRowDisplayDdiConfig));
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..c52d4eceed
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
@@ -0,0 +1,40 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardInitBeforeSiliconInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..1283a4c80a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,106 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  );
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+BoardDetect (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDetect ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDebugInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+  VOID
+  )
+{
+  return WhiskeylakeURvpBoardBootModeDetect ();
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardInitBeforeMemoryInit ();
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..965110a5a5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
@@ -0,0 +1,41 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/MultiBoardInitSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  );
+
+BOARD_POST_MEM_INIT_FUNC  mWhiskeylakeURvpBoardInitFunc = {
+  WhiskeylakeURvpBoardInitBeforeSiliconInit,
+  NULL, // BoardInitAfterSiliconInit
+};
+
+EFI_STATUS
+EFIAPI
+PeiWhiskeylakeURvpMultiBoardInitLibConstructor (
+  VOID
+  )
+{
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    return RegisterBoardPostMemInit (&mWhiskeylakeURvpBoardInitFunc);
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..a2a6efe506
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
@@ -0,0 +1,83 @@
+/** @file
+  Platform Hook Library instances
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/MultiBoardInitSupportLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+#include <WhiskeylakeURvpId.h>
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDetect (
+  VOID
+  );
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  );
+
+BOARD_DETECT_FUNC  mWhiskeylakeURvpBoardDetectFunc = {
+  WhiskeylakeURvpMultiBoardDetect
+};
+
+BOARD_PRE_MEM_INIT_FUNC  mWhiskeylakeURvpBoardPreMemInitFunc = {
+  WhiskeylakeURvpBoardDebugInit,
+  WhiskeylakeURvpBoardBootModeDetect,
+  WhiskeylakeURvpBoardInitBeforeMemoryInit,
+  NULL, // BoardInitAfterMemoryInit
+  NULL, // BoardInitBeforeTempRamExit
+  NULL, // BoardInitAfterTempRamExit
+};
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpMultiBoardDetect (
+  VOID
+  )
+{
+  WhiskeylakeURvpBoardDetect ();
+  if (LibPcdGetSku () == BoardIdWhiskeyLakeRvp) {
+    RegisterBoardPreMemInit (&mWhiskeylakeURvpBoardPreMemInitFunc);
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeiWhiskeylakeURvpMultiBoardInitPreMemLibConstructor (
+  VOID
+  )
+{
+  return RegisterBoardDetect (&mWhiskeylakeURvpBoardDetectFunc);
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
new file mode 100644
index 0000000000..0adbed7f53
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
@@ -0,0 +1,63 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+
+#include "PeiWhiskeylakeURvpInitLib.h"
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>
+
+BOOLEAN
+WhiskeylakeURvp(
+  VOID
+  )
+{
+  return TRUE;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDetect (
+  VOID
+  )
+{
+  if (LibPcdGetSku () != 0) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((EFI_D_INFO, "WhiskeylakeURvpDetectionCallback\n"));
+
+  if (WhiskeylakeURvp()) {
+    LibPcdSetSku (BoardIdWhiskeyLakeRvp);
+
+    DEBUG ((DEBUG_INFO, "SKU_ID: 0x%x\n", LibPcdGetSku()));
+    ASSERT (LibPcdGetSku() == BoardIdWhiskeyLakeRvp);
+  }
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
new file mode 100644
index 0000000000..80b0a97612
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
@@ -0,0 +1,432 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HdaVerbTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+#include <IoExpander.h>
+#include "PeiWhiskeylakeURvpInitLib.h"
+#include "GpioTableDefault.h"
+#include "GpioTableWhlUDdr4.h"
+#include <AttemptUsbFirst.h>
+#include <PeiPlatformHookLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Library/PchInfoLib.h>
+#include <FirwmareConfigurations.h>
+
+EFI_STATUS
+BoardFunctionInit(
+  IN UINT16 BoardId
+);
+
+/**
+GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardGpioInit(
+  IN UINT16 BoardId
+)
+{
+  //
+  // GPIO Table Init.
+  //
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableWhlUDdr4_0);
+      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableWhlUDdr4_0) / sizeof(GPIO_INIT_CONFIG));
+      PcdSet32S(PcdBoardGpioTable2, (UINTN)mGpioTableWhlUDdr4);
+      PcdSet16S(PcdBoardGpioTable2Size, sizeof(mGpioTableWhlUDdr4) / sizeof(GPIO_INIT_CONFIG));
+      break;
+
+    default:
+      DEBUG((DEBUG_INFO, "For Unknown Board ID..Use Default GPIO Table...\n"));
+      PcdSet32S(PcdBoardGpioTable, (UINTN)mGpioTableDefault);
+      PcdSet16S(PcdBoardGpioTableSize, sizeof(mGpioTableDefault) / sizeof(GPIO_INIT_CONFIG));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+Touch panel GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+TouchPanelGpioInit(
+  IN UINT16 BoardId
+)
+{
+  switch (BoardId) {
+    default:
+      PcdSet32S(PcdBoardGpioTableTouchPanel, 0);
+    break;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+Misc. init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInit(
+  IN UINT16 BoardId
+)
+{
+  PcdSetBoolS(PcdDebugUsbUartEnable, FALSE);
+
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+
+      PcdSetBoolS(PcdMipiCamGpioEnable, TRUE);
+      break;
+
+    default:
+      PcdSetBoolS(PcdMipiCamGpioEnable, FALSE);
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+Security GPIO init function for PEI post memory phase.
+
+@param[in]  BoardId   An unsigned integrer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardSecurityInit (
+  IN UINT16 BoardId
+)
+{
+  switch (BoardId) {
+
+    case BoardIdWhiskeyLakeRvp:
+
+      // TPM interrupt connects to GPIO_CNL_H_GPP_A_7
+      PcdSet32S (PcdTpm2CurrentIrqNum, 0x1F);
+      break;
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+WhiskeyLake board configuration init function for PEI post memory phase.
+
+@param[in]  Content  pointer to the buffer contain init information for board init.
+
+@retval EFI_SUCCESS             The function completed successfully.
+@retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+BoardConfigInit(
+  VOID
+)
+{
+  EFI_STATUS  Status;
+  UINT16      BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = BoardGpioInit(BoardId);
+  Status = TouchPanelGpioInit(BoardId);
+  Status = HdaVerbTableInit(BoardId);
+  Status = BoardMiscInit(BoardId);
+  Status = BoardFunctionInit(BoardId);
+  Status = BoardSecurityInit(BoardId);
+
+  return EFI_SUCCESS;
+}
+
+//@todo Review this functionality and if it is required for WHL SDS
+/**
+Create the HOB for hotkey status for 'Attempt USB First' feature
+
+@retval  EFI_SUCCESS  HOB Creating successful.
+@retval  Others       HOB Creating failed.
+**/
+EFI_STATUS
+CreateAttemptUsbFirstHotkeyInfoHob(
+  VOID
+)
+{
+  EFI_STATUS                     Status;
+  ATTEMPT_USB_FIRST_HOTKEY_INFO  AttemptUsbFirstHotkeyInfo;
+
+  Status = EFI_SUCCESS;
+
+  ZeroMem(
+    &AttemptUsbFirstHotkeyInfo,
+    sizeof(AttemptUsbFirstHotkeyInfo)
+  );
+
+  AttemptUsbFirstHotkeyInfo.RevisonId = 0;
+  AttemptUsbFirstHotkeyInfo.HotkeyTriggered = FALSE;
+
+  ///
+  /// Build HOB for Attempt USB First feature
+  ///
+  BuildGuidDataHob(
+    &gAttemptUsbFirstHotkeyInfoHobGuid,
+    &(AttemptUsbFirstHotkeyInfo),
+    sizeof(ATTEMPT_USB_FIRST_HOTKEY_INFO)
+  );
+
+  return Status;
+}
+
+/**
+Search and identify the physical address of a
+file module inside the FW_BINARIES_FV_SIGNED FV
+
+@retval  EFI_SUCCESS  If address has been found
+@retval  Others       If address has not been found
+**/
+EFI_STATUS
+FindModuleInFlash2(
+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader,
+  IN EFI_GUID                   *GuidPtr,
+  IN OUT UINT32                 *ModulePtr,
+  IN OUT UINT32                 *ModuleSize
+)
+{
+  EFI_FFS_FILE_HEADER        *FfsHeader;
+  EFI_FV_FILE_INFO           FileInfo;
+  EFI_PEI_FILE_HANDLE        FileHandle;
+  EFI_COMMON_SECTION_HEADER  *SectionHeader;
+  VOID                       *FileBuffer;
+  EFI_STATUS                 Status;
+
+  FfsHeader = NULL;
+  FileHandle = NULL;
+  SectionHeader = NULL;
+  FileBuffer = NULL;
+
+  while (TRUE) {
+    //
+    // Locate FV_IMAGE file type in the FW_BINARIES_FV_SIGNED firmware volume
+    //
+    Status = PeiServicesFfsFindNextFile(EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, FvHeader, &FileHandle);
+    if (EFI_ERROR(Status)) {
+      // unable to find FV_IMAGE file in this FV
+      break;
+    }
+
+    FfsHeader = (EFI_FFS_FILE_HEADER*)FileHandle;
+    DEBUG((DEBUG_INFO, "FfsHeader 0x%X:\n", FfsHeader));
+    DEBUG((DEBUG_INFO, " Name = 0x%g\n", &FfsHeader->Name));
+    DEBUG((DEBUG_INFO, " Type = 0x%X\n", FfsHeader->Type));
+    if (IS_FFS_FILE2(FfsHeader)) {
+      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE2_SIZE(FfsHeader)));
+    }
+    else {
+      DEBUG((DEBUG_INFO, " Size = 0x%X\n", FFS_FILE_SIZE(FfsHeader)));
+    }
+
+    //
+    // Locate FW_BINARIES_FV FV_IMAGE Section
+    //
+    Status = PeiServicesFfsFindSectionData(EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FileHandle, &FileBuffer);
+    if (EFI_ERROR(Status)) {
+      // continue to search for the next FV_IMAGE file
+      DEBUG((DEBUG_INFO, "FW_BINARIES_FV section not found. Status = %r\n", Status));
+      continue;
+    }
+
+    SectionHeader = (EFI_COMMON_SECTION_HEADER *)FileBuffer;
+    DEBUG((DEBUG_INFO, "GUIDED SectionHeader 0x%X:\n",
+    (UINT32)(UINT8 *)SectionHeader));
+    if (IS_SECTION2(SectionHeader)) {
+      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
+        &((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->SectionDefinitionGuid));
+      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
+        ((EFI_GUID_DEFINED_SECTION2 *)SectionHeader)->DataOffset));
+    }
+    else {
+      DEBUG((DEBUG_INFO, " Guid      = 0x%g\n",
+        &((EFI_GUID_DEFINED_SECTION *)SectionHeader)->SectionDefinitionGuid));
+      DEBUG((DEBUG_INFO, " DataOfset = 0x%X\n",
+        ((EFI_GUID_DEFINED_SECTION *)SectionHeader)->DataOffset));
+    }
+    DEBUG((DEBUG_INFO, " Type      = 0x%X\n", SectionHeader->Type));
+
+    //
+    // Locate Firmware File System file within Firmware Volume
+    //
+    Status = PeiServicesFfsFindFileByName(GuidPtr, FileBuffer, (VOID **)&FfsHeader);
+    if (EFI_ERROR(Status)) {
+      // continue to search for the next FV_IMAGE file
+      DEBUG((DEBUG_INFO, "Module not found. Status = %r\n", Status));
+      continue;
+    }
+
+    *ModulePtr = (UINT32)((UINT8 *)FfsHeader + sizeof(EFI_FFS_FILE_HEADER));
+
+    //
+    // Get File Information
+    //
+    Status = PeiServicesFfsGetFileInfo(FfsHeader, &FileInfo);
+    if (!EFI_ERROR(Status)) {
+      *ModuleSize = (UINT32)FileInfo.BufferSize;
+      DEBUG((DEBUG_INFO, "Module {0x%g} found at = 0x%X, Size = 0x%X\n",
+        &FfsHeader->Name, *ModulePtr, *ModuleSize));
+      return Status;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+Get the ChipsetInit Binary pointer.
+
+@retval EFI_SUCCESS               - ChipsetInit Binary found.
+@retval EFI_NOT_FOUND             - ChipsetInit Binary not found.
+**/
+EFI_STATUS
+UpdateChipsetInitPtr(
+  VOID
+)
+{
+  EFI_STATUS                    Status;
+  PCH_STEPPING                  PchStep;
+  EFI_FIRMWARE_VOLUME_HEADER    *FvHeader;
+  EFI_GUID                      *ChipsetInitBinaryGuidPtr;
+  SI_POLICY_PPI                 *SiPolicyPpi;
+  PCH_HSIO_CONFIG               *HsioConfig;
+  UINT32                        ModuleAddr;
+  UINT32                        ModuleSize;
+
+  ModuleAddr = 0;
+  ModuleSize = 0;
+  PchStep = PchStepping();
+
+  Status = PeiServicesLocatePpi(
+    &gSiPolicyPpiGuid,
+    0,
+    NULL,
+    (VOID **)&SiPolicyPpi
+  );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *)SiPolicyPpi, &gHsioConfigGuid, (VOID *)&HsioConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  ChipsetInitBinaryGuidPtr = NULL;
+  if (IsPchLp()) {
+    switch (PchStep) {
+      case PCH_D0:
+      case PCH_D1:
+        ChipsetInitBinaryGuidPtr = &gCnlPchLpChipsetInitTableDxGuid;
+        DEBUG((DEBUG_INFO, "Using CnlPchLpChipsetInitTable_Dx table \n"));
+        break;
+      default:
+        return EFI_NOT_FOUND;
+    }
+  }
+  else {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Locate Firmware Volume header
+  //
+  //	FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)GetFvBinaryBase();
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FixedPcdGet32(PcdFlashFvPostMemoryBase);
+  Status = FindModuleInFlash2(FvHeader, ChipsetInitBinaryGuidPtr, &ModuleAddr, &ModuleSize);
+  //
+  // Get ChipsetInit Binary Pointer
+  //
+  HsioConfig->ChipsetInitBinPtr = ModuleAddr;
+
+  //
+  // Get File Size
+  //
+  HsioConfig->ChipsetInitBinLen = ModuleSize;
+
+  DEBUG((DEBUG_INFO, "ChipsetInit Binary Location: %x\n", HsioConfig->ChipsetInitBinPtr));
+  DEBUG((DEBUG_INFO, "ChipsetInit Binary Size: %x\n", HsioConfig->ChipsetInitBinLen));
+
+  return Status;
+}
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  UINT8                            FwConfig;
+
+  BoardConfigInit();
+  //
+  // Configure GPIO and SIO
+  //
+  Status = BoardInit();
+  ASSERT_EFI_ERROR(Status);
+
+  FwConfig = FwConfigProduction;
+  PeiPolicyInit(FwConfig);
+
+  //
+  // Create USB Boot First hotkey information HOB
+  //
+  CreateAttemptUsbFirstHotkeyInfoHob();
+
+  //
+  // Initializing Platform Specific Programming
+  //
+  Status = PlatformSpecificInit();
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Update ChipsetInitPtr
+  //
+  Status = UpdateChipsetInitPtr();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
new file mode 100644
index 0000000000..519a5be216
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
@@ -0,0 +1,636 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <Library/PeiSaPolicyLib.h>
+#include <Library/BoardInitLib.h>
+#include <PchAccess.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/GpioExpanderLib.h>
+#include <SioRegs.h>
+#include <Library/PchPcrLib.h>
+
+#include "PeiWhiskeylakeURvpInitLib.h"
+#include <ConfigBlock.h>
+#include <ConfigBlock/MemoryConfig.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchRegsPcr.h>
+#include <Library/PchResetLib.h>
+#include <Register/PchRegsLpc.h>
+#include <Library/StallPpiLib.h>
+#include <Library/PeiPolicyInitLib.h>
+#include <Ppi/Reset.h>
+#include <PlatformBoardConfig.h>
+#include <GpioPinsCnlLp.h>
+#include <Library/PmcLib.h>
+#include <Library/PciSegmentLib.h>
+#include <PeiPlatformHookLib.h>
+#include <FirwmareConfigurations.h>
+#include <Guid/TcoWdtHob.h>
+#include <Library/OcWdtLib.h>
+
+///
+/// Reset Generator I/O Port
+///
+#define RESET_GENERATOR_PORT           0xCF9
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS    BaseAddress;
+  UINT64                  Length;
+} MEMORY_MAP;
+
+//
+// Reference RCOMP resistors on motherboard - for WHL RVP1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompResistorSklRvp1[SA_MRC_MAX_RCOMP] = { 200, 81, 162 };
+
+//
+// RCOMP target values for RdOdt, WrDS, WrDSCmd, WrDSCtl, WrDSClk - for WHL RVP1
+//
+GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 RcompTargetSklRvp1[SA_MRC_MAX_RCOMP_TARGETS] = { 100, 40, 40, 23, 40 };
+
+GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_MAP MmioMap[] = {
+  { FixedPcdGet64(PcdApicLocalAddress), FixedPcdGet32(PcdApicLocalMmioSize) },
+  { FixedPcdGet64(PcdMchBaseAddress), FixedPcdGet32(PcdMchMmioSize) },
+  { FixedPcdGet64(PcdDmiBaseAddress), FixedPcdGet32(PcdDmiMmioSize) },
+  { FixedPcdGet64(PcdEpBaseAddress), FixedPcdGet32(PcdEpMmioSize) },
+  { FixedPcdGet64(PcdGdxcBaseAddress), FixedPcdGet32(PcdGdxcMmioSize) }
+};
+
+EFI_STATUS
+MrcConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+SaGpioConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+  SaMiscConfigInit(
+IN UINT16         BoardId
+);
+
+EFI_STATUS
+  RootPortClkInfoInit(
+IN UINT16 BoardId
+);
+
+EFI_STATUS
+  UsbConfigInit(
+IN UINT16 BoardId
+);
+
+EFI_STATUS
+GpioGroupTierInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+GpioTablePreMemInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+PchPmConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+SaDisplayConfigInit(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+BoardFunctionInitPreMem(
+  IN UINT16 BoardId
+);
+
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemCallBack(
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN VOID                        *Ppi
+);
+
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotify(
+  IN CONST EFI_PEI_SERVICES      **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor,
+  IN VOID                        *Ppi
+);
+
+EFI_STATUS
+EFIAPI
+PchReset(
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+);
+
+static EFI_PEI_RESET_PPI mResetPpi = {
+  PchReset
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPreMemPpiList[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiPeiResetPpiGuid,
+    &mResetPpi
+  }
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mPreMemNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiReadOnlyVariable2PpiGuid,
+  (EFI_PEIM_NOTIFY_ENTRY_POINT)PlatformInitPreMemCallBack
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mMemDiscoveredNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiMemoryDiscoveredPpiGuid,
+  (EFI_PEIM_NOTIFY_ENTRY_POINT)MemoryDiscoveredPpiNotify
+};
+
+/**
+Board misc init function for PEI pre-memory phase.
+
+@param[in]  BoardId   An unsigned integer represent the board id.
+
+@retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+BoardMiscInitPreMem(
+  IN UINT16 BoardId
+)
+{
+  PCD64_BLOB PcdData;
+
+  //
+  // RecoveryMode GPIO
+  //
+  PcdData.Blob = 0;
+  PcdData.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
+
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      PcdData.BoardGpioConfig.Type = BoardGpioTypePch;
+      PcdData.BoardGpioConfig.u.Pin = GPIO_CNL_LP_GPP_F10;
+    break;
+
+    default:
+      break;
+  }
+
+  //
+  // Configure WWAN Full Card Power Off and reset pins
+  //
+  switch (BoardId) {
+    case BoardIdWhiskeyLakeRvp:
+      //
+      // According to board default settings, GPP_D16 is used to enable/disable modem
+      // power. An alternative way to contol modem power is to toggle FCP_OFF via GPP_D13
+      // but board rework is required.
+      //
+      PcdSet32S(PcdWwanFullCardPowerOffGpio, GPIO_CNL_LP_GPP_D16);
+      PcdSet32S(PcdWwanBbrstGpio, GPIO_CNL_LP_GPP_F1);
+      PcdSet32S(PcdWwanPerstGpio, GPIO_CNL_LP_GPP_E15);
+      PcdSet8S(PcdWwanPerstGpioPolarity, 1);
+      break;
+
+    default:
+      break;
+  }
+
+  PcdSet64S(PcdRecoveryModeGpio, PcdData.Blob);
+
+  //
+  // Pc8374SioKbc Present
+  //
+  PcdSetBoolS(PcdPc8374SioKbcPresent, FALSE);
+
+  return EFI_SUCCESS;
+}
+
+//@todo it should be moved to Si Pkg.
+/**
+Early Platform PCH initialization
+**/
+VOID
+EarlyPlatformPchInit(
+  VOID
+)
+{
+  UINT8        Data8;
+  UINT8        TcoRebootHappened;
+  TCO_WDT_HOB  *TcoWdtHobPtr;
+  EFI_STATUS   Status;
+
+  ///
+  /// Read the Second TO status bit
+  ///
+  Data8 = IoRead8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS);
+  if ((Data8 & B_TCO_IO_TCO2_STS_SECOND_TO) == B_TCO_IO_TCO2_STS_SECOND_TO) {
+    TcoRebootHappened = 1;
+    DEBUG((DEBUG_INFO, "PlatformInitPreMem - TCO Second TO status bit is set. This might be a TCO reboot\n"));
+  }
+  else {
+    TcoRebootHappened = 0;
+  }
+
+  ///
+  /// Create HOB
+  ///
+  Status = PeiServicesCreateHob(EFI_HOB_TYPE_GUID_EXTENSION, sizeof(TCO_WDT_HOB), (VOID **)&TcoWdtHobPtr);
+  if (!EFI_ERROR(Status)) {
+    TcoWdtHobPtr->Header.Name = gTcoWdtHobGuid;
+    TcoWdtHobPtr->TcoRebootHappened = TcoRebootHappened;
+  }
+
+  ///
+  /// Clear the Second TO status bit
+  ///
+  IoWrite8(PcdGet16(PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS, B_TCO_IO_TCO2_STS_SECOND_TO);
+}
+
+/**
+Board init function for PEI pre-memory phase.
+
+@param  Content  pointer to the buffer contain init information for board init.
+
+@retval EFI_SUCCESS             The function completed successfully.
+@retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+BoardConfigInitPreMem(
+  VOID
+)
+{
+  EFI_STATUS Status;
+  UINT16 BoardId;
+
+  BoardId = BoardIdWhiskeyLakeRvp;
+
+  Status = MrcConfigInit(BoardId);
+  Status = SaGpioConfigInit(BoardId);
+  Status = SaMiscConfigInit(BoardId);
+  Status = RootPortClkInfoInit(BoardId);
+  Status = UsbConfigInit(BoardId);
+  Status = GpioGroupTierInit(BoardId);
+  Status = GpioTablePreMemInit(BoardId);
+  Status = PchPmConfigInit(BoardId);
+  Status = BoardMiscInitPreMem(BoardId);
+  Status = SaDisplayConfigInit(BoardId);
+  Status = BoardFunctionInitPreMem(BoardId);
+
+  return EFI_SUCCESS;
+}
+
+/**
+This function handles PlatformInit task after PeiReadOnlyVariable2 PPI produced
+
+@param[in]  PeiServices   Pointer to PEI Services Table.
+@param[in]  NotifyDesc    Pointer to the descriptor for the Notification event that
+                          caused this function to execute.
+@param[in]  Ppi           Pointer to the PPI data associated with this function.
+
+@retval     EFI_SUCCESS  The function completes successfully
+@retval     others
+**/
+EFI_STATUS
+EFIAPI
+PlatformInitPreMemCallBack(
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+)
+{
+  EFI_STATUS                        Status;
+  UINT16                            ABase;
+  UINT8                             FwConfig;
+  UINT8                             SynchDelay;
+
+  //
+  // Init Board Config Pcd.
+  //
+  BoardConfigInitPreMem();
+
+  DEBUG((DEBUG_ERROR, "Fail to get System Configuration and set the configuration to production mode!\n"));
+  FwConfig = FwConfigProduction;
+  SynchDelay = 0;
+  PcdSetBoolS(PcdPcieWwanEnable, FALSE);
+  PcdSetBoolS(PcdWwanResetWorkaround, FALSE);
+
+  //
+  // Early Board Configuration before memory is ready.
+  //
+  Status = BoardInitEarlyPreMem();
+  ASSERT_EFI_ERROR(Status);
+
+  ///
+  /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
+  /// clear unexpected reset status and enforce expiration. This is to inform Firmware
+  /// which has no access to unexpected reset status bit, that something went wrong.
+  ///
+  OcWdtResetCheck();
+
+  Status = OcWdtInit();
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Initialize Intel PEI Platform Policy
+  //
+  PeiPolicyInitPreMem(FwConfig);
+
+  ///
+  /// Configure GPIO and SIO
+  ///
+  Status = BoardInitPreMem();
+  ASSERT_EFI_ERROR(Status);
+
+  ABase = PmcGetAcpiBase();
+
+  ///
+  /// Clear all pending SMI. On S3 clear power button enable so it will not generate an SMI.
+  ///
+  IoWrite16(ABase + R_ACPI_IO_PM1_EN, 0);
+  IoWrite32(ABase + R_ACPI_IO_GPE0_EN_127_96, 0);
+
+  ///
+  /// Install Pre Memory PPIs
+  ///
+  Status = PeiServicesInstallPpi(&mPreMemPpiList[0]);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
+/**
+Provide hard reset PPI service.
+To generate full hard reset, write 0x0E to PCH RESET_GENERATOR_PORT (0xCF9).
+
+@param[in]  PeiServices       General purpose services available to every PEIM.
+
+@retval     Not return        System reset occured.
+@retval     EFI_DEVICE_ERROR  Device error, could not reset the system.
+**/
+EFI_STATUS
+EFIAPI
+PchReset(
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+)
+{
+  DEBUG((DEBUG_INFO, "Perform Cold Reset\n"));
+  IoWrite8(RESET_GENERATOR_PORT, 0x0E);
+
+  CpuDeadLoop();
+
+  ///
+  /// System reset occured, should never reach at this line.
+  ///
+  ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
+
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+Install Firmware Volume Hob's once there is main memory
+
+@param[in]  PeiServices       General purpose services available to every PEIM.
+@param[in]  NotifyDescriptor  Notify that this module published.
+@param[in]  Ppi               PPI that was installed.
+
+@retval     EFI_SUCCESS       The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotify(
+  IN CONST EFI_PEI_SERVICES     **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+)
+{
+  EFI_STATUS                    Status;
+  EFI_BOOT_MODE                 BootMode;
+  UINTN                         Index;
+  UINT8                         PhysicalAddressBits;
+  UINT32                        RegEax;
+  MEMORY_MAP                    PcieMmioMap;
+
+  Index = 0;
+
+  Status = PeiServicesGetBootMode(&BootMode);
+  ASSERT_EFI_ERROR(Status);
+
+  AsmCpuid(0x80000000, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= 0x80000008) {
+    AsmCpuid(0x80000008, &RegEax, NULL, NULL, NULL);
+    PhysicalAddressBits = (UINT8)RegEax;
+  }
+  else {
+    PhysicalAddressBits = 36;
+  }
+
+  ///
+  /// Create a CPU hand-off information
+  ///
+  BuildCpuHob(PhysicalAddressBits, 16);
+
+  ///
+  /// Build Memory Mapped IO Resource which is used to build E820 Table in LegacyBios.
+  ///
+  PcieMmioMap.BaseAddress = FixedPcdGet64(PcdPciExpressBaseAddress);
+  PcieMmioMap.Length = PcdGet32(PcdPciExpressRegionLength);
+
+  BuildResourceDescriptorHob(
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    PcieMmioMap.BaseAddress,
+    PcieMmioMap.Length
+  );
+  BuildMemoryAllocationHob(
+    PcieMmioMap.BaseAddress,
+    PcieMmioMap.Length,
+    EfiMemoryMappedIO
+  );
+  for (Index = 0; Index < sizeof(MmioMap) / (sizeof(MEMORY_MAP)); Index++) {
+    BuildResourceDescriptorHob(
+      EFI_RESOURCE_MEMORY_MAPPED_IO,
+      (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+       EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+      MmioMap[Index].BaseAddress,
+      MmioMap[Index].Length
+    );
+    BuildMemoryAllocationHob(
+      MmioMap[Index].BaseAddress,
+      MmioMap[Index].Length,
+      EfiMemoryMappedIO
+    );
+  }
+
+  //
+  // Report resource HOB for flash FV
+  //
+  BuildResourceDescriptorHob(
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
+  );
+  BuildMemoryAllocationHob(
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize),
+    EfiMemoryMappedIO
+  );
+
+  BuildFvHob(
+    (UINTN)FixedPcdGet32(PcdFlashAreaBaseAddress),
+    (UINTN)FixedPcdGet32(PcdFlashAreaSize)
+  );
+
+  return Status;
+}
+
+
+/**
+  Board configuration init function for PEI pre-memory phase.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   The parameter is NULL.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpInitPreMem (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  ///
+  /// Install Stall PPI
+  ///
+  Status = InstallStallPpi();
+  ASSERT_EFI_ERROR(Status);
+
+  ///@todo it should be moved to Si Pkg.
+  ///
+  /// Do Early PCH init
+  ///
+  EarlyPlatformPchInit();
+
+  //
+  // Install PCH RESET PPI and EFI RESET2 PeiService
+  //
+  Status = PchInitializeReset();
+  ASSERT_EFI_ERROR(Status);
+
+  ///
+  /// Performing PlatformInitPreMemCallBack after PeiReadOnlyVariable2 PPI produced
+  ///
+  Status = PeiServicesNotifyPpi(&mPreMemNotifyList);
+
+  ///
+  /// After code reorangized, memorycallback will run because the PPI is already
+  /// installed when code run to here, it is supposed that the InstallEfiMemory is
+  /// done before.
+  ///
+  Status = PeiServicesNotifyPpi(&mMemDiscoveredNotifyList);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure GPIO and SIO before memory ready
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  WhiskeylakeURvpInitPreMem ();
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+WhiskeylakeURvpBoardDebugInit (
+  VOID
+  )
+{
+  UINT64                            LpcBaseAddress;
+
+  ///
+  /// LPC I/O Configuration
+  ///
+  PchLpcIoDecodeRangesSet(
+    (V_LPC_CFG_IOD_LPT_378 << N_LPC_CFG_IOD_LPT) |
+    (V_LPC_CFG_IOD_COMB_3E8 << N_LPC_CFG_IOD_COMB) |
+    (V_LPC_CFG_IOD_COMA_3F8 << N_LPC_CFG_IOD_COMA)
+  );
+
+  PchLpcIoEnableDecodingSet(
+    B_LPC_CFG_IOE_ME2 |
+    B_LPC_CFG_IOE_SE |
+    B_LPC_CFG_IOE_ME1 |
+    B_LPC_CFG_IOE_KE |
+    B_LPC_CFG_IOE_HGE |
+    B_LPC_CFG_IOE_LGE |
+    B_LPC_CFG_IOE_FDE |
+    B_LPC_CFG_IOE_PPE |
+    B_LPC_CFG_IOE_CBE |
+    B_LPC_CFG_IOE_CAE
+  );
+
+  ///
+  /// Enable LPC IO decode for EC access
+  ///
+  LpcBaseAddress = PCI_SEGMENT_LIB_ADDRESS(
+    DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+    DEFAULT_PCI_BUS_NUMBER_PCH,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    0
+  );
+
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+WhiskeylakeURvpBoardBootModeDetect (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
new file mode 100644
index 0000000000..8d8ca835bc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
@@ -0,0 +1,32 @@
+/** @file
+    WhiskeylakeURvp HSIO PTSS H File
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+#define WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+
+#include <PchHsioPtssTables.h>
+
+#ifndef HSIO_PTSS_TABLE_SIZE
+#define HSIO_PTSS_TABLE_SIZE(A) A##_Size = sizeof (A) / sizeof (HSIO_PTSS_TABLES)
+#endif
+
+//BoardId WhiskeylakeURvp
+HSIO_PTSS_TABLES PchLpHsioPtss_Cx_WhiskeylakeURvp[] = {
+  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0}
+};
+
+UINT16 PchLpHsioPtss_Cx_WhiskeylakeURvp_Size = sizeof(PchLpHsioPtss_Cx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
+
+HSIO_PTSS_TABLES PchLpHsioPtss_Bx_WhiskeylakeURvp[] = {
+  {{14, 0, 0xa0, 0x00000000, (UINT32) ~0x3F3F00}, 0},
+};
+
+UINT16 PchLpHsioPtss_Bx_WhiskeylakeURvp_Size = sizeof(PchLpHsioPtss_Bx_WhiskeylakeURvp) / sizeof(HSIO_PTSS_TABLES);
+
+#endif // WHISKEYLAKE_RVP3_HSIO_PTSS_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
new file mode 100644
index 0000000000..d2c26eb163
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel DXE SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxePolicyBoardConfig.h"
+
+/**
+  This function performs DXE SA Policy update by board configuration.
+
+  @param[in, out] DxeSaPolicy    DXE SA Policy
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicyBoardConfig (
+  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
+  )
+{
+  EFI_STATUS                         Status;
+  MEMORY_DXE_CONFIG                  *MemoryDxeConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in DXE\n"));
+
+  Status = GetConfigBlock ((VOID *)DxeSaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
new file mode 100644
index 0000000000..c495a3a401
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
@@ -0,0 +1,299 @@
+/** @file
+  PEI Library Functions. Initialize GPIOs
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <PeiPlatformHookLib.h>
+#include <SaPolicyCommon.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PeiPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PeiSaPolicyLib.h>
+#include <PchAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsCnlLp.h>
+#include <GpioPinsCnlH.h>
+#include <Library/PchInfoLib.h>
+#include <Library/CnviLib.h>
+#include <SioRegs.h>
+#include <PlatformBoardConfig.h>
+#include <Library/PchPcrLib.h>
+#include <Library/GpioCheckConflictLib.h>
+
+#define SIO_RUNTIME_REG_BASE_ADDRESS                          0x0680
+
+#define RECOVERY_MODE_GPIO_PIN                    0                    // Platform specific @todo use PCD
+
+#define MANUFACTURE_MODE_GPIO_PIN                 0                    // Platform specific @todo use PCD
+
+/**
+  Configures GPIO
+
+  @param[in]  GpioTable       Point to Platform Gpio table
+  @param[in]  GpioTableCount  Number of Gpio table entries
+
+**/
+VOID
+ConfigureGpio (
+  IN GPIO_INIT_CONFIG                 *GpioDefinition,
+  IN UINT16                           GpioTableCount
+  )
+{
+  DEBUG ((DEBUG_INFO, "ConfigureGpio() Start\n"));
+
+
+  CreateGpioCheckConflictHob (GpioDefinition, GpioTableCount);
+
+
+  GpioConfigurePads (GpioTableCount, GpioDefinition);
+
+  DEBUG ((DEBUG_INFO, "ConfigureGpio() End\n"));
+}
+
+/**
+  Configure GPIO group GPE tier.
+
+  @retval     none.
+**/
+VOID
+GpioGroupTierInitHook(
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook Start\n"));
+
+  if (PcdGet32 (PcdGpioGroupToGpeDw0)) {
+    GpioSetGroupToGpeDwX (PcdGet32 (PcdGpioGroupToGpeDw0),
+                          PcdGet32 (PcdGpioGroupToGpeDw1),
+                          PcdGet32 (PcdGpioGroupToGpeDw2));
+  }
+  DEBUG ((DEBUG_INFO, "GpioGroupTierInitHook End\n"));
+}
+
+/**
+  Configure single GPIO pad for touchpanel interrupt
+**/
+VOID
+TouchpanelGpioInit (
+  VOID
+  )
+{
+  GPIO_INIT_CONFIG*     TouchpanelPad;
+  GPIO_PAD_OWN          PadOwnVal;
+
+  PadOwnVal = 0;
+  TouchpanelPad = (VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableTouchPanel);
+  if (TouchpanelPad != NULL) {
+    GpioGetPadOwnership (TouchpanelPad->GpioPad, &PadOwnVal);
+    if (PadOwnVal == GpioPadOwnHost) {
+      GpioConfigurePads (1, TouchpanelPad);
+    }
+  }
+}
+
+/**
+  Configure GPIO Before Memory is not ready.
+
+**/
+VOID
+GpioInitPreMem (
+  VOID
+  )
+{
+  if (PcdGet32 (PcdBoardGpioTablePreMem) != 0 && PcdGet16 (PcdBoardGpioTablePreMemSize) != 0) {
+    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTablePreMem), (UINTN) PcdGet16 (PcdBoardGpioTablePreMemSize));
+  }
+}
+
+/**
+  Basic GPIO configuration before memory is ready
+
+**/
+VOID
+GpioInitEarlyPreMem (
+  VOID
+  )
+{
+  GPIO_CONFIG                     BbrstConfig;
+  UINT32                          WwanBbrstGpio;
+
+  WwanBbrstGpio = PcdGet32 (PcdWwanBbrstGpio);
+
+  if (WwanBbrstGpio) {
+    //
+    // BIOS needs to put modem in OFF state for the two scenarios below.
+    // 1. Modem RESET# is not asserted via PLTRST# in the previous sleep state
+    // 2. Modem is disabled via setup option
+    //
+    GpioGetPadConfig (WwanBbrstGpio, &BbrstConfig);
+    if ((PcdGetBool (PcdPcieWwanEnable) == FALSE) ||
+        (PcdGetBool (PcdWwanResetWorkaround) == TRUE &&
+        BbrstConfig.Direction == GpioDirOut &&
+        BbrstConfig.OutputState == GpioOutHigh)) {
+      //
+      // Assert FULL_CARD_POWER_OFF#, RESET# and PERST# GPIOs
+      //
+      if (PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize) != 0) {
+        ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOffEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOffEarlyPreMemSize));
+      }
+      if (PcdGetBool (PcdPcieWwanEnable) == TRUE && PcdGetBool (PcdWwanResetWorkaround) == TRUE) {
+        MicroSecondDelay (1 * 1000); // Delay by 1ms
+      }
+    }
+
+    //
+    // Turn ON modem power and de-assert RESET# and PERST# GPIOs
+    //
+    if (PcdGetBool (PcdPcieWwanEnable) == TRUE) {
+      if (PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem) != 0 && PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize) != 0) {
+        ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTableWwanOnEarlyPreMem), (UINTN) PcdGet16 (PcdBoardGpioTableWwanOnEarlyPreMemSize));
+      }
+    }
+  }
+}
+
+/**
+  Configure GPIO
+
+**/
+VOID
+GpioInit (
+  VOID
+  )
+{
+  ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable), (UINTN) PcdGet16 (PcdBoardGpioTableSize));
+
+  if (PcdGet32 (PcdBoardGpioTable2)) {
+    ConfigureGpio ((VOID *) (UINTN) PcdGet32 (PcdBoardGpioTable2), (UINTN) PcdGet16 (PcdBoardGpioTable2Size));
+  }
+
+  TouchpanelGpioInit();
+
+  //
+  // Lock pads after initializing platform GPIO.
+  // Pads which were requested to be unlocked during configuration
+  // will not be locked.
+  //
+  GpioLockPads ();
+
+  return;
+}
+
+/**
+  Configure Super IO
+
+**/
+VOID
+SioInit (
+  VOID
+  )
+{
+  //
+  // Program and Enable Default Super IO Configuration Port Addresses and range
+  //
+  PchLpcGenIoRangeSet (PcdGet16 (PcdLpcSioConfigDefaultPort) & (~0xF), 0x10);
+
+    PchLpcGenIoRangeSet (SIO_RUNTIME_REG_BASE_ADDRESS  & (~0x7F), 0x10);
+  return;
+}
+
+/**
+  Configure GPIO and SIO before memory ready
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInitPreMem (
+  VOID
+  )
+{
+  //
+  // Obtain Platform Info from HOB.
+  //
+  GpioInitPreMem ();
+  GpioGroupTierInitHook ();
+  SioInit ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure GPIO and SIO
+
+  @retval  EFI_SUCCESS   Operation success.
+**/
+EFI_STATUS
+BoardInit (
+  VOID
+  )
+{
+
+  GpioInit ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Do platform specific programming post-memory.
+
+  @retval  EFI_SUCCESS       The function completed successfully.
+**/
+
+EFI_STATUS
+PlatformSpecificInit (
+  VOID
+  )
+{
+  GPIO_CONFIG                     GpioConfig;
+
+  if (IsCnlPch ()) {
+
+    //
+    // Tristate unused pins by audio link mode.
+    //
+    ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
+    GpioConfig.PadMode = GpioPadModeGpio;
+    GpioConfig.HostSoftPadOwn = GpioHostOwnGpio;
+    GpioConfig.Direction = GpioDirNone;
+    GpioConfig.OutputState = GpioOutDefault;
+    GpioConfig.InterruptConfig = GpioIntDis;
+    GpioConfig.PowerConfig = GpioPlatformReset;
+    GpioConfig.ElectricalConfig = GpioTermNone;
+
+    GpioSetPadConfig (GPIO_CNL_LP_SSP1_SFRM, &GpioConfig);
+    GpioSetPadConfig (GPIO_CNL_LP_SSP1_TXD, &GpioConfig);
+
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Early Board Configuration before memory is ready
+
+  @retval  EFI_SUCCESS  Operation success.
+**/
+EFI_STATUS
+BoardInitEarlyPreMem (
+  VOID
+  )
+{
+  GpioInitEarlyPreMem ();
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
new file mode 100644
index 0000000000..e437814b10
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
@@ -0,0 +1,48 @@
+/** @file
+ Intel PEI CPU Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI CPU Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                  Status;
+  SA_MISC_PEI_PREMEM_CONFIG   *MiscPeiPreMemConfig;
+  SI_PREMEM_POLICY_PPI        *SiPreMemPolicyPpi;
+  CPU_CONFIG                  *CpuConfig;
+
+  DEBUG((DEBUG_INFO, "Updating CPU Policy by board config in Post Mem\n"));
+
+  Status = PeiServicesLocatePpi(
+      &gSiPreMemPolicyPpiGuid,
+      0,
+      NULL,
+      (VOID **)&SiPreMemPolicyPpi
+      );
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..3797df0856
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
@@ -0,0 +1,29 @@
+/** @file
+ Intel PEI CPU Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+#include <Library/ConfigBlockLib.h>
+
+/**
+  This function performs PEI CPU Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
new file mode 100644
index 0000000000..843fe4accd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI ME Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI ME Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  ME_PEI_CONFIG                      *MePeiConfig;
+
+  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gMePeiConfigGuid, (VOID *) &MePeiConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..79c93455a6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI ME Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI ME Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  ME_PEI_PREMEM_CONFIG               *MePeiPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating ME Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMePeiPreMemConfigGuid, (VOID *) &MePeiPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
new file mode 100644
index 0000000000..5dbc412879
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI PCH Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI PCH Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  PCH_GENERAL_CONFIG                 *PchGeneralConfig;
+
+  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGuid, (VOID *) &PchGeneralConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..1080015029
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI PCH Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI PCH Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  PCH_GENERAL_PREMEM_CONFIG          *PchGeneralPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating PCH Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
new file mode 100644
index 0000000000..d1d964aea7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
@@ -0,0 +1,35 @@
+/** @file
+ Intel PEI SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SA Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  GRAPHICS_PEI_CONFIG                *GtConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Post Mem\n"));
+
+  Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *)&GtConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
new file mode 100644
index 0000000000..34fca7fac3
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
@@ -0,0 +1,36 @@
+/** @file
+ Intel PEI SA Pre-Memory Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SA Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  )
+{
+  EFI_STATUS                         Status;
+  SA_MISC_PEI_PREMEM_CONFIG          *MiscPeiPreMemConfig;
+
+  DEBUG((DEBUG_INFO, "Updating SA Policy by board config in Pre Mem\n"));
+
+  Status = GetConfigBlock((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
new file mode 100644
index 0000000000..f5f38910a8
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
@@ -0,0 +1,27 @@
+/** @file
+ Intel PEI SA Policy update by board configuration
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiPolicyBoardConfig.h"
+
+/**
+  This function performs PEI SI Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  )
+{
+  return EFI_SUCCESS;
+}
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
@ 2019-08-17 20:11   ` Chaganty, Rangasai V
  2 siblings, 0 replies; 121+ messages in thread
From: Chaganty, Rangasai V @ 2019-08-17 20:11 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chiu, Chasel, Gao, Liming, Desimone, Nathaniel L,
	Kinney, Michael D, Sinha, Ankit

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files

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

Adds the DSC and build files necessary to build the
WhiskeylakeURvp board instance.

Key files
=========
* build_config.cfg - Board-specific build configuration file.
* OpenBoardPkg.dsc - The WhiskeylakeURvp board description file.
* OpenBoardPkgConfig.dsc - Used for feature-related PCD
  customization.
* OpenBoardPkgPcd.dsc - Used for other PCD customization.
* OpenBoardPkg.fdf - The WhiskeylakeURvp board flash file.
* FlashMapInclude.fdf - The WhiskeylakeURvp board flash map.
* OpenBoardPkgBuildOption.dsc - Sets build options Based
  on PCD values.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc                | 385 +++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc     | 154 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc          | 128 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc             | 245 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf |  49 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf                | 706 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg                |  33 +
 7 files changed, 1700 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
new file mode 100644
index 0000000000..eea809140c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
@@ -0,0 +1,385 @@
+## @file
+#  Platform description.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  #
+  # Set platform specific package/folder name, same as passed from PREBUILD script.
+  # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package build folder
+  # DEFINE only takes effect at R9 DSC and FDF.
+  #
+  DEFINE      PLATFORM_PACKAGE          = MinPlatformPkg
+  DEFINE      PLATFORM_SI_PACKAGE       = CoffeelakeSiliconPkg
+  DEFINE      PLATFORM_SI_BIN_PACKAGE   = CoffeelakeSiliconBinPkg
+  DEFINE      PLATFORM_FSP_BIN_PACKAGE  = CoffeeLakeFspBinPkg
+  DEFINE      PLATFORM_BOARD_PACKAGE    = WhiskeylakeOpenBoardPkg
+  DEFINE      BOARD                     = WhiskeylakeURvp
+  DEFINE      PROJECT                   = $(PLATFORM_BOARD_PACKAGE)/$(BOARD)
+
+  #
+  # Platform On/Off features are defined here
+  #
+  !include OpenBoardPkgConfig.dsc
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                       = $(PLATFORM_PACKAGE)
+  PLATFORM_GUID                       = 84D0F5BD-0EF3-4CC0-9B09-F2D0F2AA5C5E
+  PLATFORM_VERSION                    = 0.1
+  DSC_SPECIFICATION                   = 0x00010005
+  OUTPUT_DIRECTORY                    = Build/$(PROJECT)
+  SUPPORTED_ARCHITECTURES             = IA32|X64
+  BUILD_TARGETS                       = DEBUG|RELEASE
+  SKUID_IDENTIFIER                    = ALL
+
+
+  FLASH_DEFINITION                    = $(PROJECT)/OpenBoardPkg.fdf
+
+  FIX_LOAD_TOP_MEMORY_ADDRESS         = 0x0
+  DEFINE   TOP_MEMORY_ADDRESS         = 0x0
+
+  #
+  # Default value for OpenBoardPkg.fdf use
+  #
+  DEFINE BIOS_SIZE_OPTION = SIZE_70
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+#                              Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT              # The entry: 0|DEFAULT is reserved and always required.
+  0x60|WhiskeylakeURvp
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreCommonLib.dsc
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiLib.dsc
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeLib.dsc
+
+[LibraryClasses.common]
+
+  PeiLib|$(PLATFORM_PACKAGE)/Library/PeiLib/PeiLib.inf
+  ReportFvLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/PeiReportFvLib/PeiReportFvLib.inf
+
+  PciHostBridgeLib|$(PLATFORM_PACKAGE)/Pci/Library/PciHostBridgeLibSimple/PciHostBridgeLibSimple.inf
+  PciSegmentInfoLib|$(PLATFORM_PACKAGE)/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
+  PlatformBootManagerLib|$(PLATFORM_PACKAGE)/Bds/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf
+  I2cAccessLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
+  GpioExpanderLib|$(PLATFORM_BOARD_PACKAGE)/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
+
+  PlatformHookLib|$(PROJECT)/Library/BasePlatformHookLib/BasePlatformHookLib.inf
+
+  FspWrapperHobProcessLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperHobProcessLib/PeiFspWrapperHobProcessLib.inf
+  PlatformSecLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
+
+  FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
+  FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
+
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf
+  SiliconPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
+
+  ConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/BoardInitLibNull/BoardInitLibNull.inf
+  TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    TbtCommonLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
+  !endif
+  DxeTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
+  PchHsioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
+  MmPciLib|$(PLATFORM_SI_PACKAGE)/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
+  PchPmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
+
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.IA32]
+  #
+  # PEI phase common
+  #
+  SiliconPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/PeiTestPointLib.inf
+  MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  HdaVerbTableLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    PeiTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
+    PeiDTbtInitLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
+  !endif
+
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
+    PeiPolicyInitLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
+    PeiPolicyBoardConfigLib|$(PROJECT)/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
+    PeiPolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
+    PeiPlatformHookLib|$(PROJECT)/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
+  !if $(TARGET) == DEBUG
+    GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
+  !else
+    GpioCheckConflictLib|$(PROJECT)/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
+  !endif
+
+[LibraryClasses.IA32.SEC]
+  TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf
+  SecBoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/SecBoardInitLibNull/SecBoardInitLibNull.inf
+  TimerLib|$(PLATFORM_BOARD_PACKAGE)/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.X64]
+  #
+  # DXE phase common
+  #
+  FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/DxeFspWrapperPlatformLib/DxeFspWrapperPlatformLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/DxeTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/DxeTestPointLib.inf
+  MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
+  BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/DxeMultiBoardInitSupportLib.inf
+  MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
+  BoardAcpiTableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/DxeMultiBoardAcpiSupportLib.inf
+
+  DxePolicyBoardConfigLib|$(PROJECT)/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
+  DxePolicyUpdateLib|$(PLATFORM_BOARD_PACKAGE)/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
+  #
+  # Silicon Init Package
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxeLib.dsc
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  SpiFlashCommonLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+  !if $(TARGET) == DEBUG
+    TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SmmTestPointCheckLib.inf
+  !endif
+  TestPointLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointLib/SmmTestPointLib.inf
+  MultiBoardAcpiSupportLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
+  BoardAcpiEnableLib|$(PLATFORM_PACKAGE)/Acpi/Library/MultiBoardAcpiSupportLib/SmmMultiBoardAcpiSupportLib.inf
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+
+[LibraryClasses.X64.DXE_RUNTIME_DRIVER]
+  ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  !include OpenBoardPkgPcd.dsc
+
+[Components.IA32]
+  #
+  # Common
+  #
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiInclude.dsc
+
+  #
+  # FSP wrapper SEC Core
+  #
+  UefiCpuPkg/SecCore/SecCore.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  #
+  # Silicon
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgPei.dsc
+
+  #
+  # Platform
+  #
+  $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
+      !endif
+      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
+  }
+  IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+      SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardInitLib|$(PROJECT)/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
+      !endif
+  }
+  IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
+#to do  $(PLATFORM_PACKAGE)/FspWrapper/FspWrapperPeim/FspWrapperPeim.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+      SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+
+  #
+  # Security
+  #
+
+  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
+  !endif
+
+  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+  IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+  !endif
+
+[Components.X64]
+
+  #
+  # Common
+  #
+  !include $(PLATFORM_PACKAGE)/Include/Dsc/CoreDxeInclude.dsc
+
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # Shell
+  #
+  ShellPkg/Application/Shell/Shell.inf {
+   <PcdsFixedAtBuild>
+     gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+   <LibraryClasses>
+     NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+     NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+     ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+     HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+     BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+     ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+     ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  }
+
+  #
+  # Silicon
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgDxe.dsc
+
+  # Tbt
+  !if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+    $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+    $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+  !endif
+
+  #
+  # Platform
+  #
+  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf{
+    <LibraryClasses>
+      NULL|$(PROJECT)/Library/BaseFuncLib/BaseFuncLib.inf
+  }
+
+  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf {
+    <LibraryClasses>
+      SiliconPolicyInitLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+	  SiliconPolicyUpdateLib|MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  }
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
+
+  $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+
+  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
+  $(PLATFORM_PACKAGE)/Test/TestPointDumpApp/TestPointDumpApp.inf
+
+  #
+  # OS Boot
+  #
+  !if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+    $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
+  $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
+  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf {
+    <LibraryClasses>
+      !if gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport == FALSE
+        BoardAcpiEnableLib|$(PROJECT)/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
+      !else
+        NULL|$(PROJECT)/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
+      !endif
+  }
+
+  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
+    <PcdsPatchableInModule>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80080046
+    <LibraryClasses>
+      !if $(TARGET) == DEBUG
+        DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+      !endif
+  }
+
+  !endif
+
+  #
+  # Security
+  #
+  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
+
+  !if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+    $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
+  !endif
+
+  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
+
+  #
+  # Other
+  #
+  $(PLATFORM_SI_BIN_PACKAGE)/Microcode/MicrocodeUpdates.inf
+
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
+  !include OpenBoardPkgBuildOption.dsc
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
new file mode 100644
index 0000000000..be1d47c719
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
@@ -0,0 +1,154 @@
+## @file
+# platform build option configuration file.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[BuildOptions]
+# Define Build Options both for EDK and EDKII drivers.
+
+
+  DEFINE DSC_S3_BUILD_OPTIONS =
+
+  DEFINE DSC_CSM_BUILD_OPTIONS =
+
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+  DEFINE DSC_ACPI_BUILD_OPTIONS = -DACPI_SUPPORT=1
+!else
+  DEFINE DSC_ACPI_BUILD_OPTIONS =
+!endif
+
+  DEFINE BIOS_GUARD_BUILD_OPTIONS =
+
+  DEFINE OVERCLOCKING_BUILD_OPTION =
+
+  DEFINE FSP_BINARY_BUILD_OPTIONS =
+
+  DEFINE FSP_WRAPPER_BUILD_OPTIONS = -DFSP_WRAPPER_FLAG
+
+  DEFINE SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS =
+
+  DEFINE RESTRICTED_OPTION =
+
+
+  DEFINE SV_BUILD_OPTIONS =
+
+  DEFINE TEST_MENU_BUILD_OPTION =
+
+!if gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable == FALSE
+  DEFINE OPTIMIZE_DISABLE_OPTIONS = -Od -GL-
+!else
+  DEFINE OPTIMIZE_DISABLE_OPTIONS =
+!endif
+
+  DEFINE UP_SERVER_SUPPORT_BUILD_OPTIONS =
+
+
+  DEFINE TPM_BUILD_OPTION =
+
+  DEFINE TPM2_BUILD_OPTION =
+
+  DEFINE DSC_TBT_BUILD_OPTIONS =
+
+  DEFINE DSC_DCTT_BUILD_OPTIONS =
+
+  DEFINE EMB_BUILD_OPTIONS =
+
+  DEFINE DSC_MEMORY_DOWN_BUILD_OPTIONS = -DMEM_DOWN_FLAG=1
+
+  DEFINE DSC_KBCEMUL_BUILD_OPTIONS =
+
+  DEFINE BOOT_GUARD_BUILD_OPTIONS =
+
+  DEFINE SECURE_BOOT_BUILD_OPTIONS =
+
+  DEFINE USBTYPEC_BUILD_OPTION =
+
+  DEFINE CAPSULE_BUILD_OPTIONS =
+
+  DEFINE PERFORMANCE_BUILD_OPTION =
+
+  DEFINE DEBUGUSEUSB_BUILD_OPTION =
+
+  DEFINE DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION = -DDISABLE_NEW_DEPRECATED_INTERFACES=1
+
+  DEFINE SINITBIN_BUILD_OPTION =
+
+  DEFINE MINTREE_FLAG_BUILD_OPTION = -DMINTREE_FLAG=1
+
+  DEFINE CPUTYPE_BUILD_OPTION = -DCPU_CFL=1
+
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)  $(OVERCLOCKING_BUILD_OPTION) $(PERFORMANCE_BUILD_OPTION) $(EMB_BUILD_OPTIONS) $(BIOS_GUARD_BUILD_OPTIONS) $(DSC_TBT_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(BOOT_GUARD_BUILD_OPTIONS) $(DSC_MEMORY_DOWN_BUILD_OPTIONS) $(DEBUGUSEUSB_BUILD_OPTION) $(DSC_S3_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(FSP_BINARY_BUILD_OPTIONS) $(FSP_WRAPPER_BUILD_OPTIONS) $(SKIP_FSP_TEMPRAM_INIT_AND_EXIT_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_KBCEMUL_BUILD_OPTIONS) $(CAPSULE_BUILD_OPTIONS) $(SECURE_BOOT_BUILD_OPTIONS) $(DSC_CSM_BUILD_OPTIONS) $(DISABLE_NEW_DEPRECATED_INTERFACES_BUILD_OPTION)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(TPM2_BUILD_OPTION) $(TPM_BUILD_OPTION) $(DSC_DCTT_BUILD_OPTIONS)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(DSC_ACPI_BUILD_OPTIONS) $(UP_SERVER_SUPPORT_BUILD_OPTIONS) $(USBTYPEC_BUILD_OPTION) $(SINITBIN_BUILD_OPTION) $(MINTREE_FLAG_BUILD_OPTION)
+DEFINE DSC_PLTPKG_FEATURE_BUILD_OPTIONS = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(CPUTYPE_BUILD_OPTION)
+[BuildOptions.Common.EDKII]
+
+#
+# For IA32 Global Build Flag
+#
+       *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+       *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_NASM_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+#
+# For IA32 Specific Build Flag
+#
+GCC:   *_*_IA32_PP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_ASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_CC_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+MSFT:  *_*_IA32_VFRPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_APP_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLPP_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLCC_FLAGS   = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+
+#
+# For X64 Global Build Flag
+#
+       *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+       *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_NASM_FLAGS     = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+
+#
+# For X64 Specific Build Flag
+#
+GCC:   *_*_X64_PP_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASM_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_CC_FLAGS       = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+MSFT:  *_*_X64_VFRPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_APP_FLAGS      = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_ASLPP_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASLCC_FLAGS    = $(DSC_PLTPKG_FEATURE_BUILD_OPTIONS)
+
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support MemoryAttribute table
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support NX protection
+[BuildOptions.common.EDKII.DXE_DRIVER, BuildOptions.common.EDKII.DXE_CORE, BuildOptions.common.EDKII.UEFI_DRIVER, BuildOptions.common.EDKII.UEFI_APPLICATION]
+  #MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  #GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
new file mode 100644
index 0000000000..c68fecf50e
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
@@ -0,0 +1,128 @@
+## @file
+#  Platform configuration file.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[PcdsFixedAtBuild]
+  #
+  # Please select BootStage here.
+  # Stage 1 - enable debug (system deadloop after debug init)
+  # Stage 2 - mem init (system deadloop after mem init)
+  # Stage 3 - boot to shell only
+  # Stage 4 - boot to OS
+  # Stage 5 - boot to OS with security boot enabled
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4
+
+[PcdsFeatureFlag]
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 1
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 2
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 3
+  gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 4
+  gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 5
+  gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE
+  gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
+!endif
+
+  gBoardModuleTokenSpaceGuid.PcdTbtEnable|FALSE
+  #
+  # More fine granularity control below:
+  #
+
+  gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport|TRUE
+
+#
+# TRUE is ENABLE. FALSE is DISABLE.
+#
+#
+# BIOS build switches configuration
+#
+  gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+
+# CPU
+  gSiPkgTokenSpaceGuid.PcdSourceDebugEnable|FALSE
+
+# SA
+  gSiPkgTokenSpaceGuid.PcdIgdEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPegEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSgEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSaDmiEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSaOcEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdVtdEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable|TRUE
+
+# ME
+  gSiPkgTokenSpaceGuid.PcdAtaEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPttEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdJhiEnable|TRUE
+
+  gSiPkgTokenSpaceGuid.PcdAcpiEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdBdatEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSiCsmEnable|FALSE
+  gSiPkgTokenSpaceGuid.PcdTraceHubEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdOverclockEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdPpmEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdS3Enable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSmbiosEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSmmVariableEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdUseHpetTimer|TRUE                       # TRUE - HPET / FALSE - 8254 timer is used.
+  gSiPkgTokenSpaceGuid.PcdOcWdtEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable|FALSE
+
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdCflCpuEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdIpuEnable|TRUE
+  gSiPkgTokenSpaceGuid.PcdGnaEnable|TRUE
+
+#
+# Override some PCDs for specific build requirements.
+#
+  #
+  # Disable USB debug message when Source Level Debug is enabled
+  # because they cannot be enabled at the same time.
+  #
+
+    gSiPkgTokenSpaceGuid.PcdPttEnable|FALSE
+
+  !if $(TARGET) == DEBUG
+    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+  !else
+    gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable|TRUE
+  !endif
+
+  !if $(TARGET) == DEBUG
+    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE
+  !else
+    gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE
+  !endif
+
+    gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
new file mode 100644
index 0000000000..96d65133ae
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
@@ -0,0 +1,245 @@
+## @file
+#  Platform description.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+  #gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport|TRUE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+!if $(TARGET) == RELEASE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
+
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable|TRUE
+
+[PcdsFixedAtBuild.common]
+  gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode|TRUE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|140
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable == TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1
+!endif
+
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|2
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|8
+  gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|1
+
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
+  gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000
+  gSiPkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF80000
+  gSiPkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase|0xFEF00000
+  gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize|0x00040000
+
+  gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize        | 0x00026000
+
+  gSiPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x5000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+  gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x20000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe|TRUE
+
+#
+# 8MB Default
+#
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000
+
+#
+# 16MB TSEG in Debug build only.
+#
+!if $(TARGET) == DEBUG
+  gSiPkgTokenSpaceGuid.PcdTsegSize|0x1000000
+!endif
+
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber|0x0
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber|0x1F
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber|0x2
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset|0x44
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask|0x80
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset|0x00
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress|0x1800
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset|0x08
+  gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask|0xFFFC
+
+  !if $(TARGET) == RELEASE
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x402
+  !else
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiReservedMemorySize|0x188B
+  !endif
+
+
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtDataMemorySize|0x4b
+  !if $(TARGET) == RELEASE
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0x70
+  !else
+  gMinPlatformPkgTokenSpaceGuid.PcdPlatformEfiRtCodeMemorySize|0xE0
+  !endif
+
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress|0xFFEAC000
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress|0xFFDC0000
+
+  ## Specifies the size of the microcode Region.
+  # @Prompt Microcode Region size.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize|0
+
+  ## Specifies timeout value in microseconds for the BSP to detect all APs for the first time.
+  # @Prompt Timeout for the BSP to detect all APs for the first time.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|1000
+
+  ## 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
+
+
+  #
+  # The PCDs are used to control the Windows SMM Security Mitigations Table - Protection Flags
+  #
+  # BIT0: If set, expresses that for all synchronous SMM entries,SMM will validate that input and output buffers lie entirely within the expected fixed memory regions.
+  # BIT1: If set, expresses that for all synchronous SMM entries, SMM will validate that input and output pointers embedded within the fixed communication buffer only refer to address ranges \
+  #       that lie entirely within the expected fixed memory regions.
+  # BIT2: Firmware setting this bit is an indication that it will not allow reconfiguration of system resources via non-architectural mechanisms.
+  # BIT3-31: Reserved
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags|0x07
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 1
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 2
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 3
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x03, 0x05, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 4
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x07, 0x03, 0x05, 0x1F, 0x00, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage == 5
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 6
+  gMinPlatformPkgTokenSpaceGuid.PcdTestPointIbvPlatformFeature|{0x03, 0x0F, 0x07, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+!endif
+
+[PcdsFixedAtBuild.IA32]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+  gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00148
+  gMinPlatformPkgTokenSpaceGuid.PcdPeiPhaseStackTop|0xA0000
+  gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x3800000
+
+[PcdsFixedAtBuild.X64]
+  # Default platform supported RFC 4646 languages: (American) English
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en-US"
+
+
+[PcdsPatchableInModule.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046
+
+!if $(TARGET) == DEBUG
+  gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable|1
+!endif
+
+[PcdsDynamicHii.X64.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout"
+  gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"Timeout"
+!endif
+
+[PcdsDynamicDefault]
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress|0xFFD50000
+  # Platform will pre-allocate UPD buffer and pass it to FspWrapper
+  # Those dummy address will be patched before FspWrapper executing
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress|0x0
+  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress|0x0
+
+  ## Specifies max supported number of Logical Processors.
+  # @Prompt Configure max supported number of Logical Processors
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|16
+
+[PcdsDynamicDefault.common.DEFAULT]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAtaSmartEnable|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE
+  #
+  #  Set video to native resolution as Windows 8 WHCK requirement.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0x0
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0
+
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum|0x00
+
+[PcdsDynamicDefault.common.DEFAULT]
+
+  # Tbt
+  gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad | 13
+  gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad | 0x02010011
+  gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport | 0x0
+  gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq| 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtAspm | 0x0
+  gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch | 0x0
+
+  gBoardModuleTokenSpaceGuid.PcdRtd3Tbt | 0x1
+  gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq | 0x1
+  gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax | 26
+  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd | 100
+  gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax | 28
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
new file mode 100644
index 0000000000..9209b9e88a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
@@ -0,0 +1,49 @@
+## @file
+#  FDF file of Platform.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+#=================================================================================#
+# 8 M BIOS - for FSP wrapper
+#=================================================================================#
+DEFINE FLASH_BASE                                                   = 0xFF800000  #
+DEFINE FLASH_SIZE                                                   = 0x00800000  #
+DEFINE FLASH_BLOCK_SIZE                                             = 0x00010000  #
+DEFINE FLASH_NUM_BLOCKS                                             = 0x00000080  #
+#=================================================================================#
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageOffset           = 0x00000000  # Flash addr (0xFF800000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageSize             = 0x00040000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset   = 0x00000000  # Flash addr (0xFF800000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize    = 0x0001E000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset = 0x0001E000  # Flash addr (0xFF81E000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize  = 0x00002000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset   = 0x00020000  # Flash addr (0xFF820000)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize    = 0x00020000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset          = 0x00040000  # Flash addr (0xFF840000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            = 0x00060000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset          = 0x000A0000  # Flash addr (0xFF8A0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            = 0x00070000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset            = 0x00110000  # Flash addr (0xFF910000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              = 0x00090000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset          = 0x001A0000  # Flash addr (0xFF9A0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            = 0x00190000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset        = 0x00330000  # Flash addr (0xFFB30000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          = 0x00170000  #
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset                  = 0x004A0000  # Flash addr (0xFFCA0000)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                    = 0x000B0000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset              = 0x00550000  # Flash addr (0xFFD50000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize                = 0x00070000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset              = 0x005C0000  # Flash addr (0xFFDC0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                = 0x000EC000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset              = 0x006AC000  # Flash addr (0xFFEAC000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                = 0x00014000  #
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset         = 0x006C0000  # Flash addr (0xFFEC0000)
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           = 0x00140000  #
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
new file mode 100644
index 0000000000..611078e4b4
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
@@ -0,0 +1,706 @@
+## @file
+#  FDF file of Platform.
+#
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+   !include $(PROJECT)/Include/Fdf/FlashMapInclude.fdf
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+[FD.WhiskeylakeURvp]
+#
+# FD Tokens, BaseAddress, Size, ErasePolarity, BlockSize, and NumBlocks, cannot be
+# assigned with PCD values. Instead, it uses the definitions for its variety, which
+# are FLASH_BASE, FLASH_SIZE, FLASH_BLOCK_SIZE and FLASH_NUM_BLOCKS.
+#
+BaseAddress   = $(FLASH_BASE) | gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress      #The base address of the FLASH Device.
+Size          = $(FLASH_SIZE) | gSiPkgTokenSpaceGuid.PcdBiosSize             #The size in bytes of the FLASH Device
+ErasePolarity = 1
+BlockSize     = $(FLASH_BLOCK_SIZE)
+NumBlocks     = $(FLASH_NUM_BLOCKS)
+
+DEFINE SIPKG_DXE_SMM_BIN  = INF
+DEFINE SIPKG_PEI_BIN      = INF
+
+# Set FLASH_REGION_FV_RECOVERY_OFFSET to PcdNemCodeCacheBase, because macro expression is not supported.
+# So, PlatformSecLib uses PcdBiosAreaBaseAddress + PcdNemCodeCacheBase to get the real CodeCache base address.
+SET gSiPkgTokenSpaceGuid.PcdNemCodeCacheBase = $(gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase = $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) + $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
+SET gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase) + 0x60
+SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize) - 0x60
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress) + $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset)
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize)
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashMicrocodeOffset = 0x60
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase    = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize    = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeOffset  = gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress = gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
+SET gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize    = gSiPkgTokenSpaceGuid.PcdBiosSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress    = gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize           = gSiPkgTokenSpaceGuid.PcdBiosSize
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+# Fv Size can be adjusted
+#
+################################################################################
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x40000
+  0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  #Signature "_FVH"       #Attributes
+  0x5F, 0x46, 0x56, 0x48, 0xFF, 0xFE, 0x04, 0x00,
+  #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+  #
+  # Be careful on CheckSum field.
+  #
+  0x48, 0x00, 0x32, 0x09, 0x00, 0x00, 0x00, 0x02,
+  #Blockmap[0]: 4 Blocks  0x10000 Bytes / Block
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+  #Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+!if gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable == TRUE
+  #  Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+  #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+  #Size: 0x1E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x1DFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xDF, 0x01, 0x00,
+  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64
+  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+FV = FvAdvanced
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+FV = FvSecurity
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+FV = FvOsBoot
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+FV = FvUefiBoot
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+FV = FvPostMemory
+
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase|gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+#Microcode
+FV = FvMicrocode
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+# FSP_S Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_S.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+# FSP_M Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_M.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+# FSP_T Section
+FILE = $(PLATFORM_FSP_BIN_PACKAGE)/Fsp_Rebased_T.fd
+
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+FV = FvPreMemory
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FvMicrocode]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = FALSE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = FALSE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 {
+  $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/X64/MicrocodeUpdates.bin
+}
+
+[FV.FvPreMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = FC8FE6B5-CD9B-411E-BD8F-31824D0CDE3D
+
+INF  UefiCpuPkg/SecCore/SecCore.inf
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePreMemoryInclude.fdf
+
+INF $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+INF IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+
+[FV.FvPostMemoryUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 7C4DCFC6-AECA-4707-85B9-FD4B2EEA49E7
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CorePostMemoryInclude.fdf
+
+# Init Board Config PCD
+INF $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+INF IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
+INF $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+
+FILE RAW = C9505BC0-AA3D-4056-9995-870C8DE8594E {
+    $(PLATFORM_SI_BIN_PACKAGE)/ChipsetInit/CnlPchLpChipsetInitTable_Dx.bin
+  }
+!if gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable == TRUE
+FILE FREEFORM =PCD(gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid) {
+  SECTION RAW = $(PLATFORM_FSP_BIN_PACKAGE)/SampleCode/Vbt/Vbt.bin
+  SECTION UI  = "Vbt"
+}
+FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D {
+  SECTION RAW = MdeModulePkg/Logo/Logo.bmp
+}
+!endif # PcdPeiDisplayEnable
+
+
+[FV.FvPostMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 9DFE49DB-8EF0-4D9C-B273-0036144DE917
+
+FILE FV_IMAGE = 244FAAF4-FAE1-4892-8B7D-7EF84CBFA709 {
+      SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+        SECTION FV_IMAGE = FvPostMemoryUncompact
+      }
+}
+
+[FV.FvUefiBootUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A881D567-6CB0-4eee-8435-2E72D33E45B5
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreUefiBootInclude.fdf
+INF  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeCnl.inf
+
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF  MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+INF  ShellPkg/Application/Shell/Shell.inf
+
+INF  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Policy/PolicyInitDxe/PolicyInitDxe.inf
+INF  $(PLATFORM_PACKAGE)/PlatformInit/SiliconPolicyDxe/SiliconPolicyDxe.inf
+INF  IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
+
+INF  $(PLATFORM_PACKAGE)/Test/TestPointStubDxe/TestPointStubDxe.inf
+
+
+[FV.FvUefiBoot]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 0496D33D-EA79-495C-B65D-ABF607184E3B
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvUefiBootUncompact
+       }
+     }
+
+[FV.FvOsBootUncompact]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = A0F04529-B715-44C6-BCA4-2DEBDD01EEEC
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreOsBootInclude.fdf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+INF  $(PLATFORM_PACKAGE)/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+INF  $(PLATFORM_PACKAGE)/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+
+INF  $(PLATFORM_PACKAGE)/Acpi/AcpiTables/AcpiPlatform.inf
+INF  $(PLATFORM_PACKAGE)/Acpi/AcpiSmm/AcpiSmm.inf
+
+INF  RuleOverride = DRIVER_ACPITABLE $(PLATFORM_BOARD_PACKAGE)/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
+INF  $(PLATFORM_PACKAGE)/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+
+!endif
+
+[FV.FvLateSilicon]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 97F09B89-9E83-4DDC-A3D1-10C4AF539D1E
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/Spi/Smm/PchSpiSmm.inf
+$(SIPKG_DXE_SMM_BIN) $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
+
+INF  RuleOverride = ACPITABLE $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaAcpiTables.inf
+INF  RuleOverride = ACPITABLE $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
+
+!endif
+
+[FV.FvOsBoot]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 13BF8810-75FD-4B1A-91E6-E16C4201F80A
+
+FILE FV_IMAGE = B9020753-84A8-4BB6-947C-CE7D41F5CE39 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvOsBootUncompact
+       }
+     }
+
+FILE FV_IMAGE = D4632741-510C-44E3-BE21-C3D6D7881485 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvLateSilicon
+       }
+     }
+
+[FV.FvSecurityPreMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 9B7FA59D-71C6-4A36-906E-9725EA6ADD5B
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
+
+INF  IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+
+INF  IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
+
+[FV.FvSecurityPostMemory]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16         #FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 4199E560-54AE-45E5-91A4-F7BC3804E14A
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityPostMemoryInclude.fdf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+INF $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformPei/Tcg2PlatformPei.inf
+!endif
+
+[FV.FvSecurityLate]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = F753FE9A-EEFD-485B-840B-E032D538102C
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/CoreSecurityLateInclude.fdf
+INF  IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+INF  $(PLATFORM_PACKAGE)/Hsti/HstiIbvPlatformDxe/HstiIbvPlatformDxe.inf
+!if gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable == TRUE
+INF  $(PLATFORM_PACKAGE)/Tcg/Tcg2PlatformDxe/Tcg2PlatformDxe.inf
+!endif
+!endif
+
+[FV.FvSecurity]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 5A9A8B4E-149A-4CB2-BDC7-C8D62DE2C8CF
+
+FILE FV_IMAGE = 757CC075-1428-423D-A73C-22639706C119 {
+       SECTION FV_IMAGE = FvSecurityPreMemory
+     }
+
+FILE FV_IMAGE = 80BB8482-44D5-4BEC-82B5-8D87A933830B {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvSecurityPostMemory
+       }
+     }
+
+FILE FV_IMAGE = C83522D9-80A1-4D95-8C25-3F1370497406 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvSecurityLate
+       }
+     }
+
+[FV.FvAdvancedPreMem]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 6053D78A-457E-4490-A237-31D0FBE2F305
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+!endif
+
+[FV.FvAdvancedPostMem]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = BE3DF86F-E464-44A3-83F7-0D27E6B88C27
+
+[FV.FvAdvancedLate]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 11F6E304-43F9-4B2F-90AB-B8FFEAD6205D
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+INF  $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+!endif
+
+[FV.FvAdvanced]
+BlockSize          = $(FLASH_BLOCK_SIZE)
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = B23E7388-9953-45C7-9201-0473DDE5487A
+
+FILE FV_IMAGE = 35E7406A-5842-4F2B-BC62-19022C12AF74 {
+       SECTION FV_IMAGE = FvAdvancedPreMem
+     }
+
+FILE FV_IMAGE = F5DCB34F-27EA-48AC-9406-C894F6D587CA {
+       SECTION FV_IMAGE = FvAdvancedPostMem
+     }
+
+FILE FV_IMAGE = 5248467B-B87B-4E74-AC02-398AF4BCB712 {
+       SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+         SECTION FV_IMAGE = FvAdvancedLate
+       }
+     }
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+!include $(PLATFORM_PACKAGE)/Include/Fdf/RuleInclude.fdf
+
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
new file mode 100644
index 0000000000..1b0619bc1c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
@@ -0,0 +1,33 @@
+# @ build_config.cfg
+# This is the WhiskeylakeURvp board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN =
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = WhiskeylakeOpenBoardPkg
+PROJECT = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp
+BOARD = WhiskeylakeURvp
+FLASH_MAP_FDF = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = CoffeeLakeFspBinPkg
+FSP_PKG_NAME = CoffeelakeSiliconPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers
  2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
  2019-08-17  0:54   ` Nate DeSimone
  2019-08-17  1:16   ` Chiu, Chasel
@ 2019-08-19 18:09   ` Sinha, Ankit
  2 siblings, 0 replies; 121+ messages in thread
From: Sinha, Ankit @ 2019-08-19 18:09 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Gao, Liming,
	Desimone, Nathaniel L, Kinney, Michael D

Reviewed-by: Ankit Sinha <ankit.sinha@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:16 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers

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

Create the WhiskeylakeOpenBoardPkg to provide board support code. The
package may support Coffee Lake (CFL) and Whiskey Lake (WHL) boards. The
package serves as a board support package in the EDK II Minimum Platform
design. Silicon support for this package is provided in CoffeeLakeFspBinPkg
in the FSP repository and CoffeelakeSiliconPkg in the edk2-platforms
repository.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec                                           |  565 +++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h     |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h             |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h           |  131 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h     |   21 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h             |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h       |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h                |  261 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h                    |   31 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h      |  130 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h         |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h               |  137 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h                 |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h                        |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h                       |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h           |   84 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h                            |  118 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h                                  |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h                                           |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h                           |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h                                     | 1766 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h                                   |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h                                       |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h                    |   75 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h                     |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h                    |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h                  |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h                     |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h                         |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h                     |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h                          |  123 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h                          |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h                             |   34 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h                           |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h                  |  141 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h                         |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h                          |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h                                |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h                          |  106 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h                                         |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h                                  |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h                           |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h                                            |  144 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h                                          |  157 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl                                 |  112 ++
 46 files changed, 5288 insertions(+)

diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
new file mode 100644
index 0000000000..9d56f0e841
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
@@ -0,0 +1,565 @@
+## @file
+# Module describe the entire platform configuration.
+#
+# The DEC files are used by the utilities that parse DSC and
+# INF files to generate AutoGen.c and AutoGen.h files
+# for the build infrastructure.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+
+[Defines]
+DEC_SPECIFICATION = 0x00010017
+PACKAGE_NAME = OpenBoardPkg
+PACKAGE_VERSION = 0.1
+PACKAGE_GUID = 0A8BA6E8-C8AC-4AC1-87AC-52772FA6AE5E
+
+[Includes]
+Include
+WhiskeylakeURvp\Include
+Features\Tbt\Include
+
+[Guids]
+
+gBoardModuleTokenSpaceGuid            =  {0x72d1fff7, 0xa42a, 0x4219, {0xb9, 0x95, 0x5a, 0x67, 0x53, 0x6e, 0xa4, 0x2a}}
+
+gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+
+gTbtInfoHobGuid                       =  {0x74a81eaa, 0x033c, 0x4783, {0xbe, 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}}
+
+gPlatformModuleTokenSpaceGuid         =  {0x69d13bf0, 0xaf91, 0x4d96, {0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0}}
+
+gMeInfoSetupGuid                      =  {0x78259433, 0x7b6d, 0x4db3, {0x9a, 0xe8, 0x36, 0xc4, 0xc2, 0xc3, 0xa1, 0x7d}}
+gRealModeFileGuid                     =  {0xdf84ed23, 0x5d53, 0x423f, {0xaa, 0x81, 0x0f, 0x0e, 0x6f, 0x55, 0xc6, 0x9b}}
+gVirtualKeyboardDriverImageGuid       =  {0xe4735aac, 0x9c27, 0x493f, {0x86, 0xea, 0x9e, 0xff, 0x43, 0xd7, 0xad, 0xcd}}
+gPegConfigVariableGuid                =  {0xb414caf8, 0x8225, 0x4d6f, {0xb9, 0x18, 0xcd, 0xe5, 0xcb, 0x84, 0xcf, 0x0b}}
+gSaSetupVariableGuid                  =  {0x72c5e28c, 0x7783, 0x43a1, {0x87, 0x67, 0xfa, 0xd7, 0x3f, 0xcc, 0xaf, 0xa4}}
+gMeSetupVariableGuid                  =  {0x5432122d, 0xd034, 0x49d2, {0xa6, 0xde, 0x65, 0xa8, 0x29, 0xeb, 0x4c, 0x74}}
+gCpuSetupVariableGuid                 =  {0xb08f97ff, 0xe6e8, 0x4193, {0xa9, 0x97, 0x5e, 0x9e, 0x9b, 0xa,  0xdb, 0x32}}
+gCpuSmmGuid                           =  {0x90d93e09, 0x4e91, 0x4b3d, {0x8c, 0x77, 0xc8, 0x2f, 0xf1, 0xe,  0x3c, 0x81}}
+gPchSetupVariableGuid                 =  {0x4570b7f1, 0xade8, 0x4943, {0x8d, 0xc3, 0x40, 0x64, 0x72, 0x84, 0x23, 0x84}}
+gSiSetupVariableGuid                  =  {0xAAF8E719, 0x48F8, 0x4099, {0xA6, 0xF7, 0x64, 0x5F, 0xBD, 0x69, 0x4C, 0x3D}}
+gDebugConfigVariableGuid              =  {0xDE0A5E74, 0x4E3E, 0x3D96, {0xA4, 0x40, 0x2C, 0x96, 0xEC, 0xBD, 0x3C, 0x97}}
+gDebugConfigHobGuid                   =  {0x2f6a6bb7, 0x9dc7, 0x4bf6, {0x94, 0x04, 0x22, 0x70, 0xc0, 0xe3, 0xbe, 0x2f}}
+gChassisIntrudeDetHobGuid             =  {0xdea43de2, 0x756b, 0x4b3b, {0x75, 0x1c, 0xad, 0xeb, 0x8d, 0xff, 0x56, 0xa3}}
+
+gGpioCheckConflictHobGuid             =  {0x5603f872, 0xefac, 0x40ae, {0xb9, 0x7e, 0x13, 0xb2, 0xf8, 0x07, 0x80, 0x21}}
+
+gAttemptUsbFirstHotkeyInfoHobGuid     =  {0x38b8e214, 0x1468, 0x4bb7, {0x95, 0xb1, 0x74, 0x59, 0x1e, 0x4c, 0x6e, 0x1d}}
+gTianoLogoGuid                        =  {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+##
+## ChipsetInitBinary
+##
+gCnlPchLpChipsetInitTableDxGuid          =  {0xc9505bc0, 0xaa3d, 0x4056, {0x99, 0x95, 0x87, 0x0c, 0x8d, 0xe8, 0x59, 0x4e}}
+
+
+[Protocols]
+gTbtNvsAreaProtocolGuid               =  {0x4d6a54d1, 0xcd56, 0x47f3, {0x93, 0x6e, 0x7e, 0x51, 0xd9, 0x31, 0x15, 0x4f}}
+gDxeTbtPolicyProtocolGuid             =  {0x196bf9e3, 0x20d7, 0x4b7b, {0x89, 0xf9, 0x31, 0xc2, 0x72, 0x08, 0xc9, 0xb9}}
+
+[Ppis]
+gPeiTbtPolicyPpiGuid                  =  {0xd7e7e1e6, 0xcbec, 0x4f5f, {0xae, 0xd3, 0xfd, 0xc0, 0xa8, 0xb0, 0x7e, 0x25}}
+gPeiTbtPolicyBoardInitDonePpiGuid     =  {0x970f9c60, 0x8547, 0x49d7, { 0xa4, 0xb, 0x1e, 0xc4, 0xbc, 0x4e, 0xe8, 0x9b}}
+
+[LibraryClasses]
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+
+[PcdsFixedAtBuild]
+
+gBoardModuleTokenSpaceGuid.PcdLpcIoDecodeRange|0x0010|UINT16|0x10001004
+gBoardModuleTokenSpaceGuid.PchLpcIoEnableDecoding|0x3c03|UINT16|0x10001005
+
+gPlatformModuleTokenSpaceGuid.PcdDmiBaseAddress|0xFED18000|UINT64|0x90000003
+gPlatformModuleTokenSpaceGuid.PcdDmiMmioSize|0x1000|UINT32|0x90000004
+gPlatformModuleTokenSpaceGuid.PcdEpBaseAddress|0xFED19000|UINT64|0x90000005
+gPlatformModuleTokenSpaceGuid.PcdEpMmioSize|0x1000|UINT32|0x90000006
+gPlatformModuleTokenSpaceGuid.PcdGdxcBaseAddress|0xFED84000|UINT64|0x90000007
+gPlatformModuleTokenSpaceGuid.PcdGdxcMmioSize|0x1000|UINT32|0x90000008
+gPlatformModuleTokenSpaceGuid.PcdEdramBaseAddress|0xFED80000|UINT64|0x90000009
+gPlatformModuleTokenSpaceGuid.PcdEdramMmioSize|0x4000|UINT32|0x9000000A
+gPlatformModuleTokenSpaceGuid.PcdApicLocalAddress|0xFEE00000|UINT64|0x9000000B
+gPlatformModuleTokenSpaceGuid.PcdApicLocalMmioSize|0x1000|UINT32|0x9000000C
+gPlatformModuleTokenSpaceGuid.PcdApicIoAddress|0xFEC00000|UINT64|0x9000000D
+gPlatformModuleTokenSpaceGuid.PcdApicIoMmioSize|0x1000|UINT32|0x9000000E
+gPlatformModuleTokenSpaceGuid.PcdGttMmAddress|0xCF000000|UINT64|0x9000000F
+gPlatformModuleTokenSpaceGuid.PcdGmAdrAddress|0xD0000000|UINT64|0x90000010
+gPlatformModuleTokenSpaceGuid.PcdAcpiEnableSwSmi|0xF0|UINT8|0x90000012
+gPlatformModuleTokenSpaceGuid.PcdAcpiDisableSwSmi|0xF1|UINT8|0x90000013
+gPlatformModuleTokenSpaceGuid.PcdPcieDockBridgeResourcePatchSmi|0x4D|UINT8|0x90000014
+gPlatformModuleTokenSpaceGuid.PcdCmosFastBootDefaultValue|0x01|UINT8|0x90000016
+gPlatformModuleTokenSpaceGuid.PcdCmosDebugPrintErrorLevelDefaultValue|0x80000046|UINT32|0x90000017
+gPlatformModuleTokenSpaceGuid.PcdOverClockingInterfaceSwSmi|0x72|UINT8|0x90000019
+gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioDataDefaultPort|0x2F|UINT16|0x9000001A
+gPlatformModuleTokenSpaceGuid.PcdDesktopLpcSioIndexDefaultPort|0x2E|UINT16|0x9000001B
+gPlatformModuleTokenSpaceGuid.PcdApicIoIdPch|0x02|UINT8|0x9000001E
+gPlatformModuleTokenSpaceGuid.PcdRuntimeUpdateFvHeaderLength|0x48|UINT8|0x90000020
+gPlatformModuleTokenSpaceGuid.PcdEcExtraIoBase|0x6A0|UINT16|0x20000505
+gPlatformModuleTokenSpaceGuid.PcdFspTemporaryRamSize|0x1000|UINT32|0x10001003
+
+gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition|0x01|UINT8|0x90000015
+gBoardModuleTokenSpaceGuid.PcdLpcSioIndexPort|0x4e|UINT16|0x90000018
+gBoardModuleTokenSpaceGuid.PcdLpcSioConfigDefaultPort|0x164E|UINT16|0x9000001C
+gBoardModuleTokenSpaceGuid.PcdSioBaseAddress|0x0680|UINT16|0x9000001D
+gBoardModuleTokenSpaceGuid.PcdLpcSioDataPort|0x4f|UINT16|0x9000001F
+gBoardModuleTokenSpaceGuid.PcdLpcSioIndexDefaultPort|0x164E|UINT16|0x90000021
+gBoardModuleTokenSpaceGuid.PcdLpcSioDataDefaultPort|0x164F|UINT16|0x90000022
+
+[PcdsDynamic]
+# Board GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable|0|UINT32|0x00000040
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableSize|0|UINT16|0x00000041
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2|0|UINT32|0x00000042
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTable2Size|0|UINT16|0x00000043
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMem|0|UINT32|0x000000113
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTablePreMemSize|0|UINT16|0x000000114
+
+# Board Expander GPIO Table
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable|0|UINT32|0x00000044
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTableSize|0|UINT16|0x00000045
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2|0|UINT32|0x00000046
+gBoardModuleTokenSpaceGuid.PcdGpioExpanderTable2Size|0|UINT16|0x00000047
+
+# TouchPanel & SDHC CD GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableTouchPanel|0|UINT32|0x00000048
+
+# PCH-LP HSIO PTSS Table
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1|0|UINT32|0x0000004A
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2|0|UINT32|0x0000004B
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable1Size|0|UINT16|0x0000004C
+gBoardModuleTokenSpaceGuid.PcdUnknowLpHsioPtssTable2Size|0|UINT16|0x0000004D
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1|0|UINT32|0x0000004E
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2|0|UINT32|0x0000004F
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable1Size|0|UINT16|0x00000050
+gBoardModuleTokenSpaceGuid.PcdSpecificLpHsioPtssTable2Size|0|UINT16|0x00000051
+
+# PCH-H HSIO PTSS Table
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1|0|UINT32|0x00000052
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2|0|UINT32|0x00000053
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable1Size|0|UINT16|0x00000054
+gBoardModuleTokenSpaceGuid.PcdUnknowHHsioPtssTable2Size|0|UINT16|0x00000055
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1|0|UINT32|0x00000056
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2|0|UINT32|0x00000057
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable1Size|0|UINT16|0x00000058
+gBoardModuleTokenSpaceGuid.PcdSpecificHHsioPtssTable2Size|0|UINT16|0x00000059
+
+# HDA Verb Table
+gBoardModuleTokenSpaceGuid.PcdHdaVerbTable|0|UINT32|0x0000005A
+gBoardModuleTokenSpaceGuid.PcdHdaVerbTable2|0|UINT32|0x0000005B
+gBoardModuleTokenSpaceGuid.PcdExtHdaVerbTable|0|UINT32|0x0000005C
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable1|0|UINT32|0x0000005D
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable2|0|UINT32|0x0000005E
+gBoardModuleTokenSpaceGuid.PcdCommonHdaVerbTable3|0|UINT32|0x0000005F
+gBoardModuleTokenSpaceGuid.PcdDisplayAudioHdaVerbTable|0|UINT32|0x00000060
+
+# SA Misc Configuration
+gBoardModuleTokenSpaceGuid.PcdSaMiscUserBd|0|UINT8|0x00000066
+gBoardModuleTokenSpaceGuid.PcdSaMiscMmioSizeAdjustment|0|UINT16|0x00000067
+gBoardModuleTokenSpaceGuid.PcdSaDdrFreqLimit|0|UINT16|0x00000101
+
+# DRAM Configuration
+gBoardModuleTokenSpaceGuid.PcdMrcRcompResistor|0|UINT32|0x00000068
+gBoardModuleTokenSpaceGuid.PcdMrcRcompTarget|0|UINT32|0x00000069
+gBoardModuleTokenSpaceGuid.PcdMrcDqByteMap|0|UINT32|0x0000006A
+gBoardModuleTokenSpaceGuid.PcdMrcDqByteMapSize|0|UINT16|0x0000006B
+gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2Dram|0|UINT32|0x0000006C
+gBoardModuleTokenSpaceGuid.PcdMrcDqsMapCpu2DramSize|0|UINT16|0x0000006D
+gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleavedControl|FALSE|BOOLEAN|0x0000006E
+gBoardModuleTokenSpaceGuid.PcdMrcDqPinsInterleaved|FALSE|BOOLEAN|0x0000006F
+gBoardModuleTokenSpaceGuid.PcdMrcSpdData|0|UINT32|0x00000070
+gBoardModuleTokenSpaceGuid.PcdMrcSpdDataSize|0|UINT16|0x00000071
+
+# PEG RESET GPIO
+gBoardModuleTokenSpaceGuid.PcdPegGpioResetControl|FALSE|BOOLEAN|0x00000072
+gBoardModuleTokenSpaceGuid.PcdPegGpioResetSupoort|FALSE|BOOLEAN|0x00000073
+gBoardModuleTokenSpaceGuid.PcdPcie0WakeGpioNo|0|UINT32|0x00000079
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstExpanderNo|0|UINT8|0x0000007A
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstGpioNo|0|UINT32|0x0000007B
+gBoardModuleTokenSpaceGuid.PcdPcie0HoldRstActive|FALSE|BOOLEAN|0x0000007C
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableExpanderNo|0|UINT8|0x0000007D
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableGpioNo|0|UINT32|0x0000007E
+gBoardModuleTokenSpaceGuid.PcdPcie0PwrEnableActive|FALSE|BOOLEAN|0x0000007F
+
+# SPD Address Table
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable0|0|UINT8|0x00000099
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable1|0|UINT8|0x0000009A
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable2|0|UINT8|0x0000009B
+gBoardModuleTokenSpaceGuid.PcdMrcSpdAddressTable3|0|UINT8|0x0000009C
+
+# CA Vref Configuration
+gBoardModuleTokenSpaceGuid.PcdMrcCaVrefConfig|0|UINT8|0x0000009D
+
+# USB 2.0 Port AFE
+gBoardModuleTokenSpaceGuid.PcdUsb20Port0Afe|0|UINT32|0x000000BF
+gBoardModuleTokenSpaceGuid.PcdUsb20Port1Afe|0|UINT32|0x000000C0
+gBoardModuleTokenSpaceGuid.PcdUsb20Port2Afe|0|UINT32|0x000000C1
+gBoardModuleTokenSpaceGuid.PcdUsb20Port3Afe|0|UINT32|0x000000C2
+gBoardModuleTokenSpaceGuid.PcdUsb20Port4Afe|0|UINT32|0x000000C3
+gBoardModuleTokenSpaceGuid.PcdUsb20Port5Afe|0|UINT32|0x000000C4
+gBoardModuleTokenSpaceGuid.PcdUsb20Port6Afe|0|UINT32|0x000000C5
+gBoardModuleTokenSpaceGuid.PcdUsb20Port7Afe|0|UINT32|0x000000C6
+gBoardModuleTokenSpaceGuid.PcdUsb20Port8Afe|0|UINT32|0x000000C7
+gBoardModuleTokenSpaceGuid.PcdUsb20Port9Afe|0|UINT32|0x000000C8
+gBoardModuleTokenSpaceGuid.PcdUsb20Port10Afe|0|UINT32|0x000000C9
+gBoardModuleTokenSpaceGuid.PcdUsb20Port11Afe|0|UINT32|0x000000CA
+gBoardModuleTokenSpaceGuid.PcdUsb20Port12Afe|0|UINT32|0x000000CB
+gBoardModuleTokenSpaceGuid.PcdUsb20Port13Afe|0|UINT32|0x000000CC
+gBoardModuleTokenSpaceGuid.PcdUsb20Port14Afe|0|UINT32|0x000000CD
+gBoardModuleTokenSpaceGuid.PcdUsb20Port15Afe|0|UINT32|0x000000CE
+
+# USB 2.0 Port Over Current Pin
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort0|0|UINT8|0x000000CF
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort1|0|UINT8|0x000000D0
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort2|0|UINT8|0x000000D1
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort3|0|UINT8|0x000000D2
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort4|0|UINT8|0x000000D3
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort5|0|UINT8|0x000000D4
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort6|0|UINT8|0x000000D5
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort7|0|UINT8|0x000000D6
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort8|0|UINT8|0x000000D7
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort9|0|UINT8|0x000000D8
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort10|0|UINT8|0x000000D9
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort11|0|UINT8|0x000000DA
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort12|0|UINT8|0x000000DB
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort13|0|UINT8|0x000000DC
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort14|0|UINT8|0x000000DD
+gBoardModuleTokenSpaceGuid.PcdUsb20OverCurrentPinPort15|0|UINT8|0x000000DE
+
+# USB 3.0 Port Over Current Pin
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort0|0|UINT8|0x000000DF
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort1|0|UINT8|0x000000E0
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort2|0|UINT8|0x000000E1
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort3|0|UINT8|0x000000E2
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort4|0|UINT8|0x000000E3
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort5|0|UINT8|0x000000E4
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort6|0|UINT8|0x000000E5
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7|0|UINT8|0x000000E6
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8|0|UINT8|0x000000E7
+gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9|0|UINT8|0x000000E8
+
+# Misc
+gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent|FALSE|BOOLEAN|0x000000EC
+
+# TBT
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel |0|BOOLEAN|0x000000F3
+gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad |0|UINT32|0x000000F4
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad |0|UINT32|0x000000F5
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport |0|UINT8|0x000000FA
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI |0|UINT8|0x000000FB
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify |0|UINT8|0x000000FC
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq|0|UINT8|0x000000FD
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm |0|UINT8|0x000000FE
+gBoardModuleTokenSpaceGuid.PcdDTbtLtr | 0 | UINT8| 0x00000116
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch |0|UINT8|0x000000FF
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt |0|UINT8|0x00000100
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq |0|UINT8|0x0000010A
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax |0|UINT8|0x00000107
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd |0|UINT16|0x00000108
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax |0|UINT8|0x00000109
+
+# UCMC GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable|0|UINT32|0x000000111
+gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize|0|UINT16|0x000000112
+
+gBoardModuleTokenSpaceGuid.PcdAcpiSleepState|1|UINT8|0x40000002
+gBoardModuleTokenSpaceGuid.PcdAcpiHibernate|1|UINT8|0x40000003
+gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle|0|UINT8|0x40000004
+gBoardModuleTokenSpaceGuid.PcdPciExpNative|0|UINT8|0x40000005
+gBoardModuleTokenSpaceGuid.PcdNativeAspmEnable|1|UINT8|0x40000006
+gBoardModuleTokenSpaceGuid.PcdPs2KbMsEnable|0|UINT8|0x40000009
+gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints|1|UINT8|0x4000000A
+gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints|0|UINT8|0x4000000B
+gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints|1|UINT8|0x4000000C
+
+# 0: Type-C
+# 1: Stacked-Jack
+gBoardModuleTokenSpaceGuid.PcdAudioConnector|0|UINT8|0x40000012
+
+gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress|0|UINT64|0x40000013
+
+# gIntelPeiGraphicsVbtGuid =  {0x4ad46122, 0xffeb, 0x4a52, {0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}}
+gBoardModuleTokenSpaceGuid.PcdGraphicsVbtGuid|{0x22, 0x61, 0xd4, 0x4a, 0xeb, 0xff, 0x52, 0x4a, 0xbf, 0xb0, 0x51, 0x8c, 0xfc, 0xa0, 0x2d, 0xb0}|VOID*|0x40000014
+#==============================================================
+#
+# The PCD which indicates the Memory Slot Population.
+#
+gBoardModuleTokenSpaceGuid.PcdDualDimmPerChannelBoardType|FALSE|BOOLEAN|0x00101027
+gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate|0|UINT64|0x00000010
+
+# Board GPIO Table
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMem|0|UINT32|0x001000115
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOnEarlyPreMemSize|0|UINT16|0x001000116
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMem|0|UINT32|0x001000117
+gBoardModuleTokenSpaceGuid.PcdBoardGpioTableWwanOffEarlyPreMemSize|0|UINT16|0x001000118
+gBoardModuleTokenSpaceGuid.PcdWwanFullCardPowerOffGpio|0x0|UINT32|0x0010020C
+gBoardModuleTokenSpaceGuid.PcdWwanPerstGpioPolarity|0x0|UINT8|0x0010022E
+gBoardModuleTokenSpaceGuid.PcdWwanPerstGpio|0x0|UINT32|0x0010022F
+gBoardModuleTokenSpaceGuid.PcdWwanBbrstGpio|0x0|UINT32|0x00100230
+gBoardModuleTokenSpaceGuid.PcdPcieWwanEnable|FALSE|BOOLEAN|0x00100231
+gBoardModuleTokenSpaceGuid.PcdWlanWakeGpio|0x0|UINT32|0x00100234
+gBoardModuleTokenSpaceGuid.PcdWlanRootPortNumber|0x0|UINT8|0x00100235
+gBoardModuleTokenSpaceGuid.PcdWwanResetWorkaround|FALSE|BOOLEAN|0x00100236
+
+# UCMC GPIO Table
+gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTable|0|UINT32|0x00100033
+gBoardModuleTokenSpaceGuid.PcdSaDisplayConfigTableSize|0|UINT16|0x00100034
+
+# PEG RESET GPIO
+gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioPad|0|UINT32|0x00000074
+gBoardModuleTokenSpaceGuid.PcdPeg0ResetGpioActive|FALSE|BOOLEAN|0x00000075
+gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioPad|0|UINT32|0x00000105
+gBoardModuleTokenSpaceGuid.PcdPeg3ResetGpioActive|FALSE|BOOLEAN|0x00000106
+
+# PCIE RTD3 GPIO
+gBoardModuleTokenSpaceGuid.PcdRootPortDev|0xFF|UINT8|0x00000076
+gBoardModuleTokenSpaceGuid.PcdRootPortFunc|0xFF|UINT8|0x00000077
+gBoardModuleTokenSpaceGuid.PcdRootPortIndex|0xFF|UINT8|0x00000104
+gBoardModuleTokenSpaceGuid.PcdPcie0GpioSupport|0|UINT8|0x00000078
+
+gBoardModuleTokenSpaceGuid.PcdPcie1GpioSupport|0|UINT8|0x00000080
+gBoardModuleTokenSpaceGuid.PcdPcie1WakeGpioNo|0|UINT32|0x00000081
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstExpanderNo|0|UINT8|0x00000082
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstGpioNo|0|UINT32|0x00000083
+gBoardModuleTokenSpaceGuid.PcdPcie1HoldRstActive|FALSE|BOOLEAN|0x00000084
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableExpanderNo|0|UINT8|0x00000085
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableGpioNo|0|UINT32|0x00000086
+gBoardModuleTokenSpaceGuid.PcdPcie1PwrEnableActive|FALSE|BOOLEAN|0x00000087
+
+gBoardModuleTokenSpaceGuid.PcdPcie2GpioSupport|0|UINT8|0x00000088
+gBoardModuleTokenSpaceGuid.PcdPcie2WakeGpioNo|0|UINT32|0x00000089
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstExpanderNo|0|UINT8|0x0000008A
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstGpioNo|0|UINT32|0x0000008B
+gBoardModuleTokenSpaceGuid.PcdPcie2HoldRstActive|FALSE|BOOLEAN|0x0000008C
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableExpanderNo|0|UINT8|0x0000008D
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableGpioNo|0|UINT32|0x0000008E
+gBoardModuleTokenSpaceGuid.PcdPcie2PwrEnableActive|FALSE|BOOLEAN|0x0000008F
+gBoardModuleTokenSpaceGuid.PcdPcie3GpioSupport|0|UINT8|0x00000130
+gBoardModuleTokenSpaceGuid.PcdPcie3WakeGpioNo|0|UINT32|0x00000131
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstExpanderNo|0|UINT8|0x00000132
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstGpioNo|0|UINT32|0x00000133
+gBoardModuleTokenSpaceGuid.PcdPcie3HoldRstActive|FALSE|BOOLEAN|0x00000134
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableExpanderNo|0|UINT8|0x00000135
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableGpioNo|0|UINT32|0x00000136
+gBoardModuleTokenSpaceGuid.PcdPcie3PwrEnableActive|FALSE|BOOLEAN|0x00000137
+
+# Root Port Clock Info
+gBoardModuleTokenSpaceGuid.PcdPcieClock0|0|UINT64|0x0000009E
+gBoardModuleTokenSpaceGuid.PcdPcieClock1|0|UINT64|0x0000009F
+gBoardModuleTokenSpaceGuid.PcdPcieClock2|0|UINT64|0x000000A0
+gBoardModuleTokenSpaceGuid.PcdPcieClock3|0|UINT64|0x000000A1
+gBoardModuleTokenSpaceGuid.PcdPcieClock4|0|UINT64|0x000000A2
+gBoardModuleTokenSpaceGuid.PcdPcieClock5|0|UINT64|0x000000A3
+gBoardModuleTokenSpaceGuid.PcdPcieClock6|0|UINT64|0x000000A4
+gBoardModuleTokenSpaceGuid.PcdPcieClock7|0|UINT64|0x000000A5
+gBoardModuleTokenSpaceGuid.PcdPcieClock8|0|UINT64|0x000000A6
+gBoardModuleTokenSpaceGuid.PcdPcieClock9|0|UINT64|0x000000A7
+gBoardModuleTokenSpaceGuid.PcdPcieClock10|0|UINT64|0x000000A8
+gBoardModuleTokenSpaceGuid.PcdPcieClock11|0|UINT64|0x000000A9
+gBoardModuleTokenSpaceGuid.PcdPcieClock12|0|UINT64|0x000000AA
+gBoardModuleTokenSpaceGuid.PcdPcieClock13|0|UINT64|0x000000AB
+gBoardModuleTokenSpaceGuid.PcdPcieClock14|0|UINT64|0x000000AC
+gBoardModuleTokenSpaceGuid.PcdPcieClock15|0|UINT64|0x000000AD
+
+# GPIO Group Tier
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw0|0|UINT32|0x000000E9
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw1|0|UINT32|0x000000EA
+gBoardModuleTokenSpaceGuid.PcdGpioGroupToGpeDw2|0|UINT32|0x000000EB
+
+# Board related PCH PmConfig
+gBoardModuleTokenSpaceGuid.PcdSlpS0VmRuntimeControl|FALSE|BOOLEAN|0x000000F6
+gBoardModuleTokenSpaceGuid.PcdSlpS0Vm070VSupport|FALSE|BOOLEAN|0x000000F7
+gBoardModuleTokenSpaceGuid.PcdSlpS0Vm075VSupport|FALSE|BOOLEAN|0x000000F8
+
+# Misc
+gBoardModuleTokenSpaceGuid.PcdPc8374SioKbcPresent|FALSE|BOOLEAN|0x000000ED
+gBoardModuleTokenSpaceGuid.PcdOddPowerInitEnable|FALSE|BOOLEAN|0x000000EE
+gBoardModuleTokenSpaceGuid.PcdIvCamInitPresent|FALSE|BOOLEAN|0x000000EF
+gBoardModuleTokenSpaceGuid.PcdRecoveryModeGpio|0|UINT64|0x000000F0
+gBoardModuleTokenSpaceGuid.PcdMobileDramPresent|FALSE|BOOLEAN|0x000000F1
+gBoardModuleTokenSpaceGuid.PcdCpuVboostEnable|FALSE|BOOLEAN|0x000000F2
+gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable|FALSE|BOOLEAN|0x000000F9
+#gBoardModuleTokenSpaceGuid.PcdxxxNotInUse|FALSE|BOOLEAN|0x000000FC
+
+#PlatformInfoPcd
+gBoardModuleTokenSpaceGuid.PcdEnableVoltageMargining|FALSE|BOOLEAN|0x00101000
+gBoardModuleTokenSpaceGuid.PcdGfxCrbDetect|FALSE|BOOLEAN|0x00101001
+gBoardModuleTokenSpaceGuid.PcdHsioBoardPresent|FALSE|BOOLEAN|0x00101002
+gBoardModuleTokenSpaceGuid.PcdHsioBoardType|0x0|UINT8|0x00101003
+gBoardModuleTokenSpaceGuid.PcdWakeupType|0x0|UINT8|0x00101004
+gBoardModuleTokenSpaceGuid.PcdMfgMode|FALSE|BOOLEAN|0x00101005
+gBoardModuleTokenSpaceGuid.PcdBoardName|L"0123456789ABCDEF0123456789ABCDEF"|VOID*|0x00101007
+gBoardModuleTokenSpaceGuid.PcdEcMajorRevision|0x0|UINT8|0x00101008
+gBoardModuleTokenSpaceGuid.PcdEcMinorRevision|0x0|UINT8|0x00101009
+gBoardModuleTokenSpaceGuid.PcdBiosVersion|L"0123456789012345678901234567890123456789"|VOID*|0x0010100E
+gBoardModuleTokenSpaceGuid.PcdReleaseDate|L"01234567890123456789"|VOID*|0x0010100F
+gBoardModuleTokenSpaceGuid.PcdReleaseTime|L"01234567890123456789"|VOID*|0x00101010
+gBoardModuleTokenSpaceGuid.PcdPlatformGeneration|0x0|UINT8|0x00101011
+gBoardModuleTokenSpaceGuid.PcdSpdPresent|FALSE|BOOLEAN|0x00101012
+gBoardModuleTokenSpaceGuid.PcdDockAttached|FALSE|BOOLEAN|0x00101013
+gBoardModuleTokenSpaceGuid.PcdPlatformType|0x0|UINT8|0x00101014
+gBoardModuleTokenSpaceGuid.PcdPlatformFlavor|0x0|UINT8|0x00101015
+gBoardModuleTokenSpaceGuid.PcdBoardRev|0x0|UINT8|0x00101016
+gBoardModuleTokenSpaceGuid.PcdBoardBomId|0x0|UINT8|0x00101017
+gBoardModuleTokenSpaceGuid.PcdBoardId|0x0|UINT8|0x00101018
+gBoardModuleTokenSpaceGuid.PcdBoardType|0x0|UINT8|0x00101019
+gBoardModuleTokenSpaceGuid.PcdEcPresent|FALSE|BOOLEAN|0x0010101A
+
+# PCH Misc Configuration
+gBoardModuleTokenSpaceGuid.PcdDebugUsbUartEnable|FALSE|BOOLEAN|0x00000061
+gBoardModuleTokenSpaceGuid.PcdMipiCamGpioEnable|FALSE|BOOLEAN|0x00000065
+gBoardModuleTokenSpaceGuid.PcdSmbiosFabBoardName|0|UINT64|0x00000102
+gBoardModuleTokenSpaceGuid.PcdSmbiosMainSlotEntry|0|UINT64|0x00000103
+gBoardModuleTokenSpaceGuid.PcdUsbcEcPdNegotiation|FALSE|BOOLEAN|0x00000110
+
+# Control PCD to dump default silicon policy
+gPlatformModuleTokenSpaceGuid.PcdDumpDefaultSiliconPolicy|FALSE|BOOLEAN|0x00010064
+
+# Pch SerialIo I2c Pads Termination
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c0PadInternalTerm|0x1|UINT8|0x00000020
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c1PadInternalTerm|0x1|UINT8|0x00000021
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c2PadInternalTerm|0x1|UINT8|0x00000022
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c3PadInternalTerm|0x1|UINT8|0x00000023
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c4PadInternalTerm|0x1|UINT8|0x00000030
+gBoardModuleTokenSpaceGuid.PcdPchSerialIoI2c5PadInternalTerm|0x1|UINT8|0x00000031
+#
+# The PCD which holds the pointer of Smbios Platform Info table
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosPlatformInfo|0|UINT64|0x0010101B
+#
+# The PCD which used to enable / disable the code to use RVP Smbios Board Info
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfoEnable|FALSE|BOOLEAN|0x0010101C
+#
+# The PCD which holds the pointer of RVP Smbios Board Info
+#
+gBoardModuleTokenSpaceGuid.PcdSmbiosBoardInfo|0|UINT64|0x0010101D
+#
+# CoEngineering Custom Defaults PCD
+#
+gBoardModuleTokenSpaceGuid.PcdCoEngEnableCustomDefaults|0x0|UINT8|0x00100227
+#
+# The PCD which is defined to enable/disable the SMBus Alert function.
+#
+gBoardModuleTokenSpaceGuid.PcdSmbusAlertEnable|FALSE|BOOLEAN|0x0010101E
+#
+# The PCD which is defined to enable/disable the SATA LED function.
+#
+gBoardModuleTokenSpaceGuid.PcdSataLedEnable|FALSE|BOOLEAN|0x0010101F
+#
+# The PCD which is defined to enable/disable the VR Alert function.
+#
+gBoardModuleTokenSpaceGuid.PcdVrAlertEnable|FALSE|BOOLEAN|0x00101020
+#
+# The PCD which is defined to enable/disable the PCH thermal hot threshold function.
+#
+gBoardModuleTokenSpaceGuid.PcdPchThermalHotEnable|FALSE|BOOLEAN|0x00101021
+#
+# The PCD which is defined to enable/disable the memory thermal sensor GPIO C/D function.
+#
+gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioCPmsyncEnable|TRUE|BOOLEAN|0x00101022
+gBoardModuleTokenSpaceGuid.PcdMemoryThermalSensorGpioDPmsyncEnable|TRUE|BOOLEAN|0x00101023
+#
+# The PCD defines the I2C bus number to which PSS chip connected.
+#
+gBoardModuleTokenSpaceGuid.PcdPssReadSN|FALSE|BOOLEAN|0x00101024
+gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber|0x04|UINT8|0x00101025
+gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress|0x6E|UINT8|0x00101026
+#
+# The PCD defines the USB port number to which BLE connected.
+#
+gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber                     |0x0|UINT8|0x00101028
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support                    |0x00|UINT8|0x00100113
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support                    |0x00|UINT8|0x00100114
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support                    |0x00|UINT8|0x00100115
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support                    |0x00|UINT8|0x00100116
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support                    |0x00|UINT8|0x00100117
+gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support                    |0x00|UINT8|0x00100118
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport         |FALSE|BOOLEAN|0x00100119
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport       |FALSE|BOOLEAN|0x0010011A
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport       |FALSE|BOOLEAN|0x0010011B
+gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport     |FALSE|BOOLEAN|0x0010011C
+gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport               |FALSE|BOOLEAN|0x0010011D
+gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport                |FALSE|BOOLEAN|0x0010011F
+gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin                 |0x00|UINT32|0x00100120
+gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport           |FALSE|BOOLEAN|0x00100121
+gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport           |FALSE|BOOLEAN|0x00100122
+gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature                  |FALSE|BOOLEAN|0x00100123
+gBoardModuleTokenSpaceGuid.PcdBatteryPresent                       |0x0|UINT8|0x00100124
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport|FALSE|BOOLEAN|0x00100212
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess|FALSE|BOOLEAN|0x00100213
+gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature|0x0|UINT64|0x00100204
+gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile|0x0|UINT8|0x00100205
+gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio|0x0|UINT32|0x00100209
+gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio|0x0|UINT32|0x0010020A
+gBoardModuleTokenSpaceGuid.PcdGnssResetGpio|0x0|UINT32|0x0010020B
+gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio|0x0|UINT32|0x0010020F
+gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio|0x0|UINT32|0x00100210
+
+gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio                   |0x0|UINT32|0x00100126
+gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber              |0x0|UINT8|0x00100127
+gBoardModuleTokenSpaceGuid.PcdEcSmiGpio|0x0|UINT32|0x00100200
+gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio                   |0x0|UINT32|0x00100125
+gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad|0x0|UINT32|0x00100201
+gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck|FALSE|BOOLEAN|0x00100202
+gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride|FALSE|BOOLEAN|0x00100203
+gBoardModuleTokenSpaceGuid.PcdDDISelection|0x0|UINT8|0x00100215
+gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio|0x0|UINT64|0x00100217
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1|0x00|UINT8|0x00100039
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch|0x00|UINT8|0x0010003A
+gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties|0x00|UINT8|0x0010003B
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2|0x00|UINT8|0x0010003C
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch|0x00|UINT8|0x0010003D
+gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties|0x00|UINT8|0x0010003E
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3|0x00|UINT8|0x0010003F
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch|0x00|UINT8|0x00100040
+gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties|0x00|UINT8|0x00100041
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4|0x00|UINT8|0x00100042
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch|0x00|UINT8|0x00100043
+gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties|0x00|UINT8|0x00100044
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5|0x00|UINT8|0x00100045
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch|0x00|UINT8|0x00100046
+gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties|0x00|UINT8|0x00100047
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6|0x00|UINT8|0x00100048
+gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch|0x00|UINT8|0x00100049
+gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties|0x00|UINT8|0x0010004A
+gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed                     |0x0|UINT8|0x00100128
+gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed                     |0x0|UINT8|0x00100129
+gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed                     |0x0|UINT8|0x0010012A
+gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed                     |0x0|UINT8|0x0010012B
+
+# Super IO Pcd
+gPlatformModuleTokenSpaceGuid.PcdH8S2113Present|TRUE|BOOLEAN|0xF0000100
+gPlatformModuleTokenSpaceGuid.PcdNat87393Present|TRUE|BOOLEAN|0xF0000104
+gPlatformModuleTokenSpaceGuid.PcdNct677FPresent|TRUE|BOOLEAN|0xF0000105
+gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport               |FALSE|BOOLEAN|0x00100112
+gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin                     |0x00|UINT32|0x00100111
+gBoardModuleTokenSpaceGuid.PcdRealBattery1Control                  |0x00|UINT8|0x00100103
+gBoardModuleTokenSpaceGuid.PcdRealBattery2Control                  |0x00|UINT8|0x00100104
+
+gBoardModuleTokenSpaceGuid.PcdDimmPopulationError|FALSE|BOOLEAN|0x00100221
+gBoardModuleTokenSpaceGuid.PcdBtIrqGpio|0x0|UINT32|0x0010020E
+gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio|0x0|UINT32|0x0010020D
+gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable|FALSE|BOOLEAN|0x0010022C
+gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported|0x00|UINT8|0x0010004B
+gBoardModuleTokenSpaceGuid.PcdMipiCamSensor                        |FALSE|BOOLEAN|0x00100105
+gBoardModuleTokenSpaceGuid.PcdH8S2113SIO                           |FALSE|BOOLEAN|0x0010010A
+gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM                          |FALSE|BOOLEAN|0x00100107
+gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO                          |FALSE|BOOLEAN|0x00100108
+gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON                        |FALSE|BOOLEAN|0x00100109
+
+[PcdsDynamicEx]
+
+[PcdsDynamic, PcdsDynamicEx]
+
+[PcdsPatchableInModule]
+
+[PcdsFeatureFlag]
+gBoardModuleTokenSpaceGuid.PcdIntelGopEnable      |TRUE|BOOLEAN|0xF0000062
+gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport   |TRUE|BOOLEAN|0xF0000000
+gBoardModuleTokenSpaceGuid.PcdTbtEnable           |FALSE|BOOLEAN|0x000000115
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
new file mode 100644
index 0000000000..4aae18cac4
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Header file for the DxeCheckIommuSupport library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+#define _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
+/**
+  Detect ME FW and Board Type and return the result via IommuSkuCheck.
+
+  IommuSkuCheck
+  BIT0: Indicate system has a Corporate CSME firmware
+  BIT1: Indicate BIOS is running on a WHL RVP
+  BIT2: Indicate BIOS is running on a CFL-H RVP
+  BIT3: Indicate BIOS is running on a CFL-S 8+2 RVP
+
+  @retval Return 0 means not support, otherwise value is defined by IommuSkuCheck
+**/
+UINT8
+DetectMeAndBoard (
+  VOID
+  );
+
+/**
+  DxeCheckIommuSupport
+
+  Only WHL/CFL-H/CFL-S 8+2 Crop SKUs support Iommu.
+  This function will save sku information to PcdIommuSkuCheck.
+  BIOS will use PcdIommuSkuCheck and other factors to set PcdVTdPolicyPropertyMask on the next boot in PEI phase
+
+  This function might perform a system reset.
+**/
+EFI_STATUS
+EFIAPI
+DxeCheckIommuSupport (
+  VOID
+  );
+#endif // _DXE_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
new file mode 100644
index 0000000000..167cc8af83
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
@@ -0,0 +1,49 @@
+/** @file
+  Prototype of the DxeTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_LIB_H_
+#define _DXE_TBT_POLICY_LIB_H_
+
+
+/**
+  Install TBT Policy.
+
+  @param[in] ImageHandle                Image handle of this driver.
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+  IN  EFI_HANDLE                    ImageHandle
+  );
+
+/**
+  Update Tbt Policy Callback.
+
+  @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
+UpdateTbtPolicyCallback (
+  VOID
+  );
+
+/**
+  Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+  VOID
+  );
+#endif // _DXE_TBT_POLICY_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
new file mode 100644
index 0000000000..17337ceb0b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
@@ -0,0 +1,131 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_SECURITY_LIB_H_
+#define _TBT_SECURITY_LIB_H_
+
+#include <Protocol/Tcg2Protocol.h>
+#include <Protocol/AcpiTable.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi.h>
+#include <SetupVariable.h>
+#include <OemSetup.h>
+#include <DmaRemappingTable.h>
+#include <PcieRegs.h>
+#include <Tcg2ConfigNvData.h>
+#include <TbtPolicyCommonDefinition.h>
+#include <Library/TbtCommonLib.h>
+
+#define TBT_SECURITY_EVENT_STRING                 "DMA Protection Disabled"
+#define TBT_SECURITY_EVENT_STRING_LEN             (sizeof (TBT_SECURITY_EVENT_STRING) - 1)
+
+#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING      "Security Level is Downgraded to 0"
+#define TBT_SECURITY_LEVEL_DOWNGRADED_STRING_LEN  (sizeof (TBT_SECURITY_LEVEL_DOWNGRADED_STRING) - 1)
+
+#define GET_TBT_SECURITY_MODE    0
+#define SET_TBT_SECURITY_MODE    1
+
+typedef struct {
+  UINT8       EnableVtd;
+  BOOLEAN     SLDowngrade;
+} PCR7_DATA;
+
+/**
+  TBT Security ExtendPCR7 CallBackFunction
+  If the firmware/BIOS has an option to enable and disable DMA protections via a VT-d switch in BIOS options, then the shipping configuration must be with VT-d protection enabled.
+  On every boot where VT-d/DMA protection is disabled, or will be disabled, or configured to a lower security state, and a platform has a TPM enabled, then the platform SHALL extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA.
+  The event string SHALL be "DMA Protection Disabled". The platform firmware MUST log this measurement in the event log using the string "DMA Protection Disabled" for the Event Data.
+  Measure and log launch of TBT Security, and extend the measurement result into a specific PCR.
+  Extend an EV_EFI_ACTION event into PCR[7] before enabling external DMA. The event string SHALL be "DMA Protection Disabled". The platform firmware MUST log this measurement in the event log using the string "DMA Protection Disabled" for the Event Data.
+
+  @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
+ExtendPCR7CallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  TBT Security DisableBme CallBackFunction
+
+  BIOS will disable BME and tear down the Thunderbolt DMAR tables at ExitBootServices
+  in order to hand off security of TBT hierarchies to the OS.
+  The BIOS is expected to either: Disable BME from power on till the OS starts configuring the devices and enabling BME Enable BME only for devices that can be protected by VT-d in preboot environment,
+  but disable BME and tear down any Thunderbolt DMAR tables at ExitBootServices()
+
+  @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
+TbtDisableBmeCallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  TBT Security SetDmarOptIn CallBackFunction
+
+  A new security feature will be supported to protect against Physical DMA attacks over Thunderbolt connects.
+  In order to do this, they need a new flag added to the DMAR tables that a DMA is only permitted into RMRR at ExitBootServices().  With this flag available, OS can then Bug Check if any DMA is requested outside of the RMRR before OS supported device drivers are started.
+  ReadyToBoot callback routine to update DMAR BIT2
+  Bit definition: DMA_CONTROL_GUARANTEE
+  If Set, the platform supports blocking all DMA outside of the regions defined in the RMRR structures from ExitBootServices() until OS supported device drivers are started.
+
+  @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
+SetDmarOptInCallBackFunction (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+/**
+  The function install DisableBme protocol for TBT Shell validation
+**/
+VOID
+InstallDisableBmeProtocol (
+  VOID
+  );
+
+/**
+  Get or set Thunderbolt(TM) security mode
+
+  @param[in]  DelayTime           - The delay time after do ForcePwr
+  @param[in]  SecurityMode        - TBT Security Level
+  @param[in]  Gpio3ForcePwrEn     - Force GPIO to power on or not
+  @param[in]  DTbtController      - Enable/Disable DTbtController
+  @param[in]  MaxControllerNumber - Number of contorller
+  @param[in]  Action              - 0 = get, 1 = set
+
+  @retval                         - Return security level
+**/
+UINT8
+EFIAPI
+GetSetSecurityMode (
+  IN UINTN                       DelayTime,
+  IN UINT8                       SecurityMode,
+  IN UINT8                       Gpio3ForcePwrEn,
+  IN UINT8                       *DTbtController,
+  IN UINT8                       MaxControllerNumber,
+  IN UINT8                       Action
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
new file mode 100644
index 0000000000..9afb36f011
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for the PeiCheckIommuSupport library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+#define _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
+/**
+  Check Iommu Ability base on SKU type, CSME FW type, Vtd and setup options.
+**/
+VOID
+PeiCheckIommuSupport (
+  VOID
+  );
+
+#endif // _PEI_CHECK_IOMMU_SUPPORT_LIBRARY_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
new file mode 100644
index 0000000000..45bd8f38ed
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Prototype of the PeiTbtPolicyLib library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_LIB_H_
+#define _PEI_TBT_POLICY_LIB_H_
+
+/**
+  Install Tbt Policy
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+  VOID
+  );
+
+/**
+  Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicyCallback (
+  VOID
+  );
+
+/**
+  Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+  VOID
+  );
+#endif // _DXE_TBT_POLICY_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
new file mode 100644
index 0000000000..44ae01a3f7
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
@@ -0,0 +1,61 @@
+/** @file
+  PEI TBT Task Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_TBT_TASK_DISPATCH_LIB_H__
+#define __PEI_TBT_TASK_DISPATCH_LIB_H__
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+
+typedef
+EFI_STATUS
+(EFIAPI *TBT_TASK) (
+  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+typedef enum {
+  TBT_NULL,                ///< All policy flags turned off.
+  TBT_NORMAL   = (1 << 0), ///< Execute TBT function on cold reset.
+  TBT_S3       = (1 << 1), ///< Execute TBT function on S3 exit.
+  TBT_S4       = (1 << 2), ///< Execute TBT function on S4 exit.
+  TBT_ALL      = MAX_UINTN ///< Execute TBT function always.
+} TBT_BOOT_MODE;
+
+typedef struct {
+  TBT_TASK      TbtTask;         ///< Ptr to function to execute, with parameter list.
+  TBT_BOOT_MODE TbtBootModeFlag; ///< Call table base on TbtBootModeFlag
+  CHAR8         *String;         ///< Output string describing this task.
+} TBT_CALL_TABLE_ENTRY;
+
+/**
+  Covert the current EFI_BOOT_MODE to TBT_BOOT_MODE
+**/
+TBT_BOOT_MODE
+TbtGetBootMode (
+  VOID
+);
+
+/**
+  TbtTaskDistpach: Dispatch the TBT tasks according to TBT_CALL_TABLE_ENTRY
+
+  @param[in] TBT_CALL_TABLE_ENTRY   TbtCallTable
+
+**/
+VOID
+TbtTaskDistpach (
+  IN TBT_CALL_TABLE_ENTRY *TbtCallTable
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
new file mode 100644
index 0000000000..3e9e7c4b76
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
@@ -0,0 +1,261 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_COMMON_LIB_H_
+#define _TBT_COMMON_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+
+#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_RP     0 // @todo : Update when once finalized
+#define DEFAULT_PCI_BUS_NUMBER_ITBT_RP         0
+#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_RP      0x07
+
+#define DEFAULT_PCI_SEGMENT_NUMBER_ITBT_DMA0   0
+#define DEFAULT_PCI_BUS_NUMBER_ITBT_DMA0       0
+#define DEFAULT_PCI_DEVICE_NUMBER_ITBT_DMA0    0x0D
+#define DEFAULT_PCI_FUNCTION_NUMBER_ITBT_DMA0  0x02
+
+#define DTBT_CONTROLLER                   0x00
+#define DTBT_TYPE_PCH                     0x01
+#define DTBT_TYPE_PEG                     0x02
+#define ITBT_CONTROLLER                   0x80
+#define TBT2PCIE_ITBT_R                   0xEC
+#define PCIE2TBT_ITBT_R                   0xF0
+#define TBT2PCIE_DTBT_R                   0x548
+#define PCIE2TBT_DTBT_R                   0x54C
+
+#define INVALID_RP_CONTROLLER_TYPE        0xFF
+
+//
+//  Thunderbolt FW OS capability
+//
+#define NO_OS_NATIVE_SUPPORT    0
+#define OS_NATIVE_SUPPORT_ONLY  1
+#define OS_NATIVE_SUPPORT_RTD3  2
+
+#define ITBT_SAVE_STATE_OFFSET  BIT4 // Bits 4-7 is for ITBT (HIA0/1/2/Reserved)
+#define DTBT_SAVE_STATE_OFFSET  BIT0 // Bits 0-3 is for DTBT (only bit 0 is in use)
+/**
+Get Tbt2Pcie Register Offset
+
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@retval     Register  Register Variable
+**/
+
+#define GET_TBT2PCIE_REGISTER_ADDRESS(Type, Segment, Bus, Device, Function, RegisterAddress) \
+  if (Type == ITBT_CONTROLLER) { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_ITBT_R); \
+  } else { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_DTBT_R); \
+  }
+
+/**
+Get Pcie2Tbt Register Offset
+
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@retval     Register  Register Variable
+**/
+
+#define GET_PCIE2TBT_REGISTER_ADDRESS(Type, Segment, Bus, Device, Function, RegisterAddress) \
+  if (Type == ITBT_CONTROLLER) { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_ITBT_R); \
+  } else { \
+    RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_DTBT_R); \
+  }
+
+#define PCIE2TBT_VLD_B                    BIT0
+#define TBT2PCIE_DON_R                    BIT0
+#define TBT_MAIL_BOX_DELAY                (100*1000)
+#define TBT_5S_TIMEOUT                    50
+#define TBT_1S_TIMEOUT                    10
+#define TBT_3S_TIMEOUT                    30
+
+#define PCIE2TBT_GO2SX                    (0x02 << 1)
+#define PCIE2TBT_GO2SX_NO_WAKE            (0x03 << 1)
+#define PCIE2TBT_SX_EXIT_TBT_CONNECTED    (0x04 << 1)
+#define PCIE2TBT_SX_EXIT_NO_TBT_CONNECTED (0x05 << 1)
+#define PCIE2TBT_OS_UP                    (0x06 << 1)
+#define PCIE2TBT_SET_SECURITY_LEVEL       (0x08 << 1)
+#define PCIE2TBT_GET_SECURITY_LEVEL       (0x09 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_ENTER       (0x10 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_EXIT        (0x11 << 1)
+#define PCIE2TBT_BOOT_ON                  (0x18 << 1)
+#define PCIE2TBT_BOOT_OFF                 (0x19 << 1)
+#define PCIE2TBT_USB_ON                   (0x19 << 1)
+#define PCIE2TBT_GET_ENUMERATION_METHOD   (0x1A << 1)
+#define PCIE2TBT_SET_ENUMERATION_METHOD   (0x1B << 1)
+#define PCIE2TBT_POWER_CYCLE              (0x1C << 1)
+#define PCIE2TBT_PREBOOTACL               (0x1E << 1)
+#define CONNECT_TOPOLOGY_COMMAND          (0x1F << 1)
+
+#define RESET_HR_BIT                      BIT0
+#define ENUMERATE_HR_BIT                  BIT1
+#ifndef AUTO
+#define AUTO                              0x0
+#endif
+
+//
+//Thunder Bolt Device IDs
+//
+
+//
+// Alpine Ridge HR device IDs
+//
+#define AR_HR_2C  0x1576
+#define AR_HR_4C  0x1578
+#define AR_XHC    0x15B5
+#define AR_XHC_4C 0x15B6
+#define AR_HR_LP  0x15C0
+//
+// Alpine Ridge C0 HR device IDs
+//
+#define AR_HR_C0_2C  0x15DA
+#define AR_HR_C0_4C  0x15D3
+//
+// Titan Ridge HR device IDs
+//
+#define TR_HR_2C  0x15E7
+#define TR_HR_4C  0x15EA
+//
+//End of Thunderbolt(TM) Device IDs
+//
+
+typedef struct _DEV_ID {
+  UINT8 Segment;
+  UINT8 Bus;
+  UINT8 Dev;
+  UINT8 Fun;
+} DEV_ID;
+
+//@todo Seems to only be used by Platform/TBT/Smm/TbtSmm.inf
+//@todo should refactor this to only be present in that driver
+//@todo also definitions like this should never be in a .h file anyway
+//@todo this is a quick hack to get things compiling for now
+#ifdef __GNUC__
+#pragma GCC diagnostic warning "-Wunused-variable"
+#endif
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in]  GpioNumber
+@param[in]  Value
+**/
+VOID
+ForceDtbtPower(
+  IN  UINT32         GpioNumber,
+  IN  BOOLEAN        Value
+);
+
+/**
+  Get Security Level.
+  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
+  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  );
+
+/**
+  Set Security Level.
+  @param[in]  Data      Security State
+  @param[in]  Type      ITBT (0x80) or DTBT (0x00)
+  @param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+  @param[in]  Timeout   Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+  IN    UINT8                   Data,
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT8                   Command,
+  IN    UINT32                  Timeout
+  );
+
+/**
+Execute TBT Mail Box Command
+
+@param[in]  Command   TBT Command
+@param[in]  Type      ITBT (0x80) or DTBT (0x00)
+@param[in]  Bus       Bus number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Device    Device number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Function  Function number for HIA (ITBT) or Host Router (DTBT)
+@param[in]  Timeout   Time out with 100 ms garnularity
+@Retval     true      if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+  IN    UINT8                   Command,
+  IN    BOOLEAN                 Type,
+  IN    UINT8                   Bus,
+  IN    UINT8                   Device,
+  IN    UINT8                   Function,
+  IN    UINT32                  Timeout
+);
+/**
+  Check connected TBT controller is supported or not by DeviceID
+
+  @param[in]  DeviceID              DeviceID of of TBT controller
+
+
+  @retval     TRUE                  Valid DeviceID
+  @retval     FALSE                 Invalid DeviceID
+**/
+
+BOOLEAN
+IsTbtHostRouter (
+  IN    UINT16  DeviceID
+  );
+
+/**
+  Get Pch/Peg Pcie Root Port Device and Function Number for TBT 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
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun(
+  IN  BOOLEAN Type,
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFunc
+  );
+
+/**
+  Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+  @param[in]  CommandOffsetAddress      Tbt2Pcie Register Address
+  @param[in]  TimeOut                   Time out with 100 ms garnularity
+  @param[in]  Tbt2PcieDone              Wait condition (wait for Bit to Clear/Set)
+  @param[out] *Tbt2PcieValue Function   Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion (
+  IN  UINT64   CommandOffsetAddress,
+  IN  UINT32   TimeOut,
+  IN  BOOLEAN  Tbt2PcieDone,
+  OUT UINT32   *Tbt2PcieValue
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
new file mode 100644
index 0000000000..17d8a62f66
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
@@ -0,0 +1,31 @@
+/** @file
+TBT PEI Policy
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_TBT_POLICY_H_
+#define _PEI_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define PEI_TBT_POLICY_REVISION 1
+
+/**
+ TBT PEI configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _PEI_TBT_POLICY {
+  DTBT_COMMON_CONFIG     DTbtCommonConfig;                                  ///< dTbt Common Configuration
+  DTBT_CONTROLLER_CONFIG DTbtControllerConfig [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
+} PEI_TBT_POLICY;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
new file mode 100644
index 0000000000..bb30c2c0ec
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
@@ -0,0 +1,130 @@
+/** @file
+  PEI DTBT Init Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_DTBT_INIT_LIB_H__
+#define __PEI_DTBT_INIT_LIB_H__
+
+#include <Private/Library/PeiTbtCommonInitLib.h>
+#include <Library/PeiTbtTaskDispatchLib.h>
+
+extern TBT_CALL_TABLE_ENTRY DTbtCallTable[];
+
+/**
+  Get Thunderbolt(TM) (TBT) PEI Policy Data.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtGetPeiTbtPolicyData (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Toggle related GPIO pin for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtToggleGPIO (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  set tPCH25 Timing to 10 ms for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Do ForcePower for DTBT Controller
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Clear VGA Registers for DTBT.
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "Boot On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "USB On".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+/**
+  Exectue Mail box command "Sx Exit".
+
+  @param[in]  PEI_TBT_POLICY   PeiTbtConfig
+
+  @retval     EFI_SUCCESS  The function completes successfully
+  @retval     EFI_UNSUPPORTED  dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow (
+  IN  PEI_TBT_POLICY  *PeiTbtConfig
+);
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
new file mode 100644
index 0000000000..0ed13fd300
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
@@ -0,0 +1,51 @@
+/** @file
+  PEI TBT Common Init Dispatch library Header file
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __PEI_TBT_COMMON_INIT_LIB_H__
+#define __PEI_TBT_COMMON_INIT_LIB_H__
+
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiTbtTaskDispatchLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TbtCommonLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PmcLib.h>
+#include <PlatformNvRamHookLib.h>
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN  UINT8        ControllerType,
+IN  UINT8        Controller
+);
+
+VOID
+TbtSetSxMode(
+IN    BOOLEAN                 Type,
+IN    UINT8                   Bus,
+IN    UINT8                   Device,
+IN    UINT8                   Function,
+IN    UINT8                   TbtBootOn
+);
+
+VOID
+TbtClearVgaRegisters(
+IN    UINTN                   Segment,
+IN    UINTN                   Bus,
+IN    UINTN                   Device,
+IN    UINTN                   Function
+);
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
new file mode 100644
index 0000000000..1948c252f0
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
@@ -0,0 +1,36 @@
+/** @file
+  Definitions for DisableBmeProtocol
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DISABLE_TBT_BME_PROTOCOL_H_
+#define _DISABLE_TBT_BME_PROTOCOL_H_
+
+typedef struct EFI_DISABLE_BME_PROTOCOL EFI_DISABLE_TBT_BME_PROTOCOL;
+
+/**
+  This is for disable TBT BME bit under shell environment
+
+  @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.
+**/
+typedef
+VOID
+(EFIAPI *DISABLE_BUS_MASTER_ENABLE) (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+struct EFI_DISABLE_BME_PROTOCOL {
+  DISABLE_BUS_MASTER_ENABLE DisableBme;
+};
+
+extern EFI_GUID gDxeDisableTbtBmeProtocolGuid;
+
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
new file mode 100644
index 0000000000..437f6a8401
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
@@ -0,0 +1,137 @@
+/** @file
+TBT DXE Policy
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_TBT_POLICY_H_
+#define _DXE_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define DXE_TBT_POLICY_REVISION 1
+
+//
+// TBT Common Data Structure
+//
+typedef struct _TBT_COMMON_CONFIG{
+  /**
+    TBT Security Level
+    <b>0: SL0 No Security</b>, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+  **/
+  UINT32   SecurityMode      : 3;
+  /**
+    BIOS W/A for Hot plug of 12V USB devices cause electrical noise on PCH GPIOs
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Gpio5Filter       : 1;
+  /**
+     WA for TR A0 OS_UP Command, it is only needed for TR A0 stepping
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TrA0OsupWa        : 1;
+  /**
+    Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtWakeupSupport  : 1;
+  /**
+    SMI TBT enumeration
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtHotSMI         : 1;
+  /**
+    Notify PCIe RP after Hot-Plug/Hot-Unplug occurred.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtHotNotify      : 1;
+  /**
+    CLK REQ for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtSetClkReq      : 1;
+  /**
+    ASPM setting for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: L0s, 2: L1, 3: L0sL1
+  **/
+  UINT32   TbtAspm           : 2;
+  /**
+    L1 SubState for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: L1.1, 2: L1.1 & L1.2
+  **/
+  UINT32   TbtL1SubStates    : 2;
+  /**
+    LTR for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtLtr            : 1;
+  /**
+    PTM for for all the PCIe device in TBT daisy chain.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtPtm            : 1;
+  /**
+    TBT Dynamic AC/DC L1.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtAcDcSwitch     : 1;
+  /**
+    TBT RTD3 Support.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Rtd3Tbt           : 1;
+  /**
+    TBT ClkReq for RTD3 Flow.
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   Rtd3TbtClkReq     : 1;
+  /**
+    TBT Win10support for Tbt FW execution mode.
+    <b>0: Disabled</b>, 1: Native, 2: Native + RTD3
+  **/
+  UINT32   Win10Support      : 2;
+  /**
+    TbtVtdBaseSecurity
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32   TbtVtdBaseSecurity: 1;
+  /**
+    Control Iommu behavior in pre-boot
+    <b>0: Disabled Iommu</b>, 1: Enable Iommu, Disable exception list, 2: Enable Iommu, Enable exception list
+  **/
+  UINT32   ControlIommu      : 3;
+  UINT32   Rsvd0             : 8; ///< Reserved bits
+  UINT16   Rtd3TbtClkReqDelay;
+  UINT16   Rtd3TbtOffDelay;
+} TBT_COMMON_CONFIG;
+
+//
+// dTBT Resource Data Structure
+//
+typedef struct _DTBT_RESOURCE_CONFIG{
+  UINT8  DTbtPcieExtraBusRsvd;     ///< Preserve Bus resource for PCIe RP that connect to dTBT Host Router
+  UINT16 DTbtPcieMemRsvd;          ///< Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  DTbtPcieMemAddrRngMax;    ///< Alignment of Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+  UINT16 DTbtPciePMemRsvd;         ///< Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  DTbtPciePMemAddrRngMax;   ///< Alignment of Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+  UINT8  Reserved[1];      ///< Reserved for DWORD alignment
+} DTBT_RESOURCE_CONFIG;
+
+/**
+ TBT DXE configuration\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct _DXE_TBT_POLICY_PROTOCOL {
+  TBT_COMMON_CONFIG      TbtCommonConfig;                                  ///< Tbt Common Information
+  DTBT_RESOURCE_CONFIG   DTbtResourceConfig[MAX_DTBT_CONTROLLER_NUMBER];   ///< dTbt Resource Configuration
+} DXE_TBT_POLICY_PROTOCOL;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
new file mode 100644
index 0000000000..e6654b4094
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
@@ -0,0 +1,50 @@
+/** @file
+  This file defines the TBT NVS Area Protocol.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_NVS_AREA_H_
+#define _TBT_NVS_AREA_H_
+
+//
+// Platform NVS Area definition
+//
+#include <TbtNvsAreaDef.h>
+
+//
+// Includes
+//
+#define TBT_NVS_DEVICE_ENABLE 1
+#define TBT_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL TBT_NVS_AREA_PROTOCOL;
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gTbtNvsAreaProtocolGuid;
+
+/**
+ Making any TBT_NVS_AREA 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.\n
+  <b>Revision 2</b>:   - Adding TBT NVS AREA Revision, Deprecated DTbtControllerEn0, DTbtControllerEn1.\n
+**/
+#define TBT_NVS_AREA_REVISION       2
+
+//
+// Platform NVS Area Protocol
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL {
+  TBT_NVS_AREA     *Area;
+} TBT_NVS_AREA_PROTOCOL;
+
+#endif // _TBT_NVS_AREA_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
new file mode 100644
index 0000000000..bd5e577fbe
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
@@ -0,0 +1,23 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_INFO_GUID_H_
+#define _TBT_INFO_GUID_H_
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(1)
+//
+// TBT Info HOB
+//
+typedef struct _TBT_INFO_HOB {
+  EFI_HOB_GUID_TYPE      EfiHobGuidType;
+  DTBT_COMMON_CONFIG     DTbtCommonConfig;                                  ///< dTbt Common Configuration
+  DTBT_CONTROLLER_CONFIG DTbtControllerConfig [MAX_DTBT_CONTROLLER_NUMBER]; ///< dTbt Controller Configuration
+} TBT_INFO_HOB;
+#pragma pack()
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
new file mode 100644
index 0000000000..21e17b4609
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
@@ -0,0 +1,68 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define TBT NVS Area operation region.
+  //
+
+#ifndef _TBT_NVS_AREA_DEF_H_
+#define _TBT_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT8    ThunderboltSmiFunction;                  ///< Offset 0       Thunderbolt(TM) SMI Function Number
+  UINT8    ThunderboltHotSmi;                       ///< Offset 1       SMI on Hot Plug for TBT devices
+  UINT8    TbtWin10Support;                         ///< Offset 2       TbtWin10Support
+  UINT8    TbtGpioFilter;                           ///< Offset 3       Gpio filter to detect USB Hotplug event
+  UINT8    ThunderboltHotNotify;                    ///< Offset 4       Notify on Hot Plug for TBT devices
+  UINT8    TbtSelector;                             ///< Offset 5       Thunderbolt(TM) Root port selector
+  UINT8    WAKFinished;                             ///< Offset 6       WAK Finished
+  UINT8    DiscreteTbtSupport;                      ///< Offset 7       Thunderbolt(TM) support
+  UINT8    TbtAcpiRemovalSupport;                   ///< Offset 8       TbtAcpiRemovalSupport
+  UINT32   TbtFrcPwrEn;                             ///< Offset 9       TbtFrcPwrEn
+  UINT32   TbtFrcPwrGpioNo0;                        ///< Offset 13      TbtFrcPwrGpioNo
+  UINT8    TbtFrcPwrGpioLevel0;                     ///< Offset 17      TbtFrcPwrGpioLevel
+  UINT32   TbtCioPlugEventGpioNo0;                  ///< Offset 18      TbtCioPlugEventGpioNo
+  UINT32   TbtPcieRstGpioNo0;                       ///< Offset 22      TbtPcieRstGpioNo
+  UINT8    TbtPcieRstGpioLevel0;                    ///< Offset 26      TbtPcieRstGpioLevel
+  UINT8    CurrentDiscreteTbtRootPort;              ///< Offset 27      Current Port that has plug event
+  UINT8    RootportSelected0;                       ///< Offset 28      Root port Selected by the User
+  UINT8    RootportSelected0Type;                   ///< Offset 29      Root port Type
+  UINT8    RootportSelected1;                       ///< Offset 30      Root port Selected by the User
+  UINT8    RootportSelected1Type;                   ///< Offset 31      Root port Type
+  UINT8    RootportEnabled0;                        ///< Offset 32      Root port Enabled by the User
+  UINT8    RootportEnabled1;                        ///< Offset 33      Root port Enabled by the User
+  UINT32   TbtFrcPwrGpioNo1;                        ///< Offset 34      TbtFrcPwrGpioNo
+  UINT8    TbtFrcPwrGpioLevel1;                     ///< Offset 38      TbtFrcPwrGpioLevel
+  UINT32   TbtCioPlugEventGpioNo1;                  ///< Offset 39      TbtCioPlugEventGpioNo
+  UINT32   TbtPcieRstGpioNo1;                       ///< Offset 43      TbtPcieRstGpioNo
+  UINT8    TbtPcieRstGpioLevel1;                    ///< Offset 47      TbtPcieRstGpioLevel
+  UINT8    TBtCommonGpioSupport;                    ///< Offset 48      Set if Single GPIO is used for Multi/Different Controller Hot plug support
+  UINT8    CurrentDiscreteTbtRootPortType;          ///< Offset 49      Root Port type for which SCI Triggered
+  UINT8    TrOsup;                                  ///< Offset 50      Titan Ridge Osup command
+  UINT8    TbtAcDcSwitch;                           ///< Offset 51      TBT Dynamic AcDc L1
+  UINT8    DTbtControllerEn0;                       ///< Offset 52      DTbtController0 is enabled or not.  @deprecated since revision 2
+  UINT8    DTbtControllerEn1;                       ///< Offset 53      DTbtController1 is enabled or not.  @deprecated since revision 2
+  UINT8    TbtAspm;                                 ///< Offset 54      ASPM setting for all the PCIe device in TBT daisy chain.
+  UINT8    TbtL1SubStates;                          ///< Offset 55      L1 SubState for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtSetClkReq;                            ///< Offset 56      CLK REQ for all the PCIe device in TBT daisy chain.
+  UINT8    TbtLtr;                                  ///< Offset 57      LTR for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtPtm;                                  ///< Offset 58      PTM for for all the PCIe device in TBT daisy chain.
+  UINT8    TbtWakeupSupport;                        ///< Offset 59      Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+  UINT16   Rtd3TbtOffDelay;                         ///< Offset 60      Rtd3TbtOffDelay TBT RTD3 Off Delay
+  UINT8    TbtSxWakeSwitchLogicEnable;              ///< Offset 62      TbtSxWakeSwitchLogicEnable Set True if TBT_WAKE_N will be routed to PCH WakeB at Sx entry point. HW logic is required.
+  UINT8    Rtd3TbtSupport;                          ///< Offset 63      Enable Rtd3 support for TBT. Corresponding to Rtd3Tbt in Setup.
+  UINT8    Rtd3TbtClkReq;                           ///< Offset 64      Enable TBT RTD3 CLKREQ mask.
+  UINT16   Rtd3TbtClkReqDelay;                      ///< Offset 65      TBT RTD3 CLKREQ mask delay.
+  //
+  // Revision Field:
+  //
+  UINT8    TbtRevision;                             ///< Offset 67      Revison of TbtNvsArea
+} TBT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
new file mode 100644
index 0000000000..7771fc7a95
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
@@ -0,0 +1,84 @@
+/** @file
+TBT Policy Common definition.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _TBT_POLICY_COMMON_H_
+#define _TBT_POLICY_COMMON_H_
+
+#include <Library/GpioLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#define MAX_DTBT_CONTROLLER_NUMBER 2
+
+#define TYPE_PCIE           0x01
+#define TYPE_PEG            0x02
+
+#pragma pack(push, 1)
+
+//
+// dTBT Force Power GPIO Data Structure
+//
+typedef struct _DTBT_FORCE_POWER_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_FORCE_POWER_GPIO_CONFIG;
+
+//
+// dTBT CIO Plug Event GPIO Data Structure
+//
+typedef struct _DTBT_CIO_PLUG_EVENT_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  UINT32         AcpiGpeSignature;        ///< AcpiPlatform driver will change the XTBT method to the _Lxx or _Exx that we assign in this item.
+  BOOLEAN        AcpiGpeSignaturePorting; ///< 0 = No porting required(for 2-tier GPI GPE event architecture), 1 = Porting required(for 1-tier GPI GPE event architecture)
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_CIO_PLUG_EVENT_GPIO_CONFIG;
+
+//
+// dTBT PCIE Reset GPIO Data Structure
+//
+typedef struct _DTBT_PCIE_RESET_GPIO_CONFIG {
+  GPIO_PAD       GpioPad;                 ///< GPIO Pad Number
+  BOOLEAN        GpioLevel;               ///< 0 = Active Low; 1 = Active High
+  UINT8          Reserved[3];             ///< Reserved for DWORD alignment
+} DTBT_PCIE_RESET_GPIO_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_CONTROLLER_CONFIG {
+  UINT8                           DTbtControllerEn; ///< Enable/Disable DTbtController.
+  UINT8                           Type;             ///< 01-Pcie RP, 02- PEG,Reserved. <Specific according to Board Design>
+  UINT8                           PcieRpNumber;     ///< RP Number/ PEG Port (0,1,2) that connecet to dTBT controller. <Specific according to Board Design>
+  DTBT_FORCE_POWER_GPIO_CONFIG    ForcePwrGpio;     ///< The GPIO pin that can force dTBT Power On. <Specific according to Board Design>
+  DTBT_CIO_PLUG_EVENT_GPIO_CONFIG CioPlugEventGpio; ///< The GPIO pin that can generate Hot-Plug event. <Specific according to Board Design>
+  DTBT_PCIE_RESET_GPIO_CONFIG     PcieRstGpio;      ///< The GPIO pin that is use to perform Reset when platform enters to Sx, it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO <Specific according to Board Design>
+  GPIO_PAD                        PdResetGpioPad;   ///< PD HRESET GPIO Pad Number
+  GPIO_PAD                        PdSxEntryGpioPad; ///< PD SX Entry GPIO Pad Number
+  GPIO_PAD                        PdSxAckGpioPad;   ///< PD SX Ack GPIO Pad Number
+  UINT8                           Reserved[1];      ///< Reserved for DWORD alignment
+} DTBT_CONTROLLER_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_COMMON_CONFIG {
+  UINT8            TbtBootOn;                    ///< Send BootOn Mailbox command when TbtBootOn is enabled.
+  UINT8            TbtUsbOn;                     ///< Send UsbOn Mailbox command when TbtBootOn is enabled.
+  UINT8            Gpio3ForcePwr;                ///< Force GPIO to power on or not
+  UINT16           Gpio3ForcePwrDly;             ///< The delay time after do ForcePwr
+  BOOLEAN          DTbtSharedGpioConfiguration;  ///< Multiple DTBT controllers share the same GPIO pin <Specific according to Board Design>
+  BOOLEAN          PcieRstSupport;               ///< 0 = Not Support, 1 = Supported. it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO
+  UINT8            SecurityMode;                 ///< 0: SL0 No Security, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+  UINT8            ControlIommu;                 ///< Control Iommu behavior in pre-boot, 0: Disabled Iommu, 1: Enable Iommu, Disable exception list, 2: Enable Iommu, Enable exception list
+  UINT8            Reserved[3];                  ///< Reserved for DWORD alignment
+} DTBT_COMMON_CONFIG;
+
+#pragma pack(pop)
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
new file mode 100644
index 0000000000..d8021e8c22
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
@@ -0,0 +1,118 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  // Define a Global region of ACPI NVS Region that may be used for any
+  // type of implementation.  The starting offset and size will be fixed
+  // up by the System BIOS during POST.  Note that the Size must be a word
+  // in size to be fixed up correctly.
+
+
+#ifndef _GLOBAL_NVS_AREA_DEF_H_
+#define _GLOBAL_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  //
+  // Miscellaneous Dynamic Registers:
+  //
+  UINT16   OperatingSystem;                         ///< Offset 0       Operating System
+  UINT8    SmiFunction;                             ///< Offset 2       SMI Function Call (ASL to SMI via I/O Trap)
+  UINT32   Port80DebugValue;                        ///< Offset 3       Port 80 Debug Port Value
+  UINT8    PowerState;                              ///< Offset 7       Power State (AC Mode = 1)
+  //
+  // Thermal Policy Registers:
+  //
+  UINT8    EnableDigitalThermalSensor;              ///< Offset 8       Digital Thermal Sensor Enable
+  UINT8    DigitalThermalSensorSmiFunction;         ///< Offset 9       DTS SMI Function Call
+  //
+  // CPU Identification Registers:
+  //
+  UINT8    ApicEnable;                              ///< Offset 10      APIC Enabled by SBIOS (APIC Enabled = 1)
+  UINT8    ThreadCount;                             ///< Offset 11      Number of Enabled Threads
+  //
+  // PCIe Hot Plug
+  //
+  UINT8    PcieOSCControl;                          ///< Offset 12      PCIE OSC Control
+  UINT8    NativePCIESupport;                       ///< Offset 13      Native PCIE Setup Value
+  //
+  // Global Variables
+  //
+  UINT8    DisplaySupportFlag;                      ///< Offset 14      _DOS Display Support Flag.
+  UINT8    InterruptModeFlag;                       ///< Offset 15      Global IOAPIC/8259 Interrupt Mode Flag.
+  UINT8    L01Counter;                              ///< Offset 16      Global L01 Counter.
+  UINT8    LtrEnable[24];                           ///< Offset 17      Latency Tolerance Reporting Enable
+                                                    ///< Offset 18      Latency Tolerance Reporting Enable
+                                                    ///< Offset 19      Latency Tolerance Reporting Enable
+                                                    ///< Offset 20      Latency Tolerance Reporting Enable
+                                                    ///< Offset 21      Latency Tolerance Reporting Enable
+                                                    ///< Offset 22      Latency Tolerance Reporting Enable
+                                                    ///< Offset 23      Latency Tolerance Reporting Enable
+                                                    ///< Offset 24      Latency Tolerance Reporting Enable
+                                                    ///< Offset 25      Latency Tolerance Reporting Enable
+                                                    ///< Offset 26      Latency Tolerance Reporting Enable
+                                                    ///< Offset 27      Latency Tolerance Reporting Enable
+                                                    ///< Offset 28      Latency Tolerance Reporting Enable
+                                                    ///< Offset 29      Latency Tolerance Reporting Enable
+                                                    ///< Offset 30      Latency Tolerance Reporting Enable
+                                                    ///< Offset 31      Latency Tolerance Reporting Enable
+                                                    ///< Offset 32      Latency Tolerance Reporting Enable
+                                                    ///< Offset 33      Latency Tolerance Reporting Enable
+                                                    ///< Offset 34      Latency Tolerance Reporting Enable
+                                                    ///< Offset 35      Latency Tolerance Reporting Enable
+                                                    ///< Offset 36      Latency Tolerance Reporting Enable
+                                                    ///< Offset 37      Latency Tolerance Reporting Enable
+                                                    ///< Offset 38      Latency Tolerance Reporting Enable
+                                                    ///< Offset 39      Latency Tolerance Reporting Enable
+                                                    ///< Offset 40      Latency Tolerance Reporting Enable
+  UINT8    ObffEnable[24];                          ///< Offset 41      Optimized Buffer Flush and Fill
+                                                    ///< Offset 42      Optimized Buffer Flush and Fill
+                                                    ///< Offset 43      Optimized Buffer Flush and Fill
+                                                    ///< Offset 44      Optimized Buffer Flush and Fill
+                                                    ///< Offset 45      Optimized Buffer Flush and Fill
+                                                    ///< Offset 46      Optimized Buffer Flush and Fill
+                                                    ///< Offset 47      Optimized Buffer Flush and Fill
+                                                    ///< Offset 48      Optimized Buffer Flush and Fill
+                                                    ///< Offset 49      Optimized Buffer Flush and Fill
+                                                    ///< Offset 50      Optimized Buffer Flush and Fill
+                                                    ///< Offset 51      Optimized Buffer Flush and Fill
+                                                    ///< Offset 52      Optimized Buffer Flush and Fill
+                                                    ///< Offset 53      Optimized Buffer Flush and Fill
+                                                    ///< Offset 54      Optimized Buffer Flush and Fill
+                                                    ///< Offset 55      Optimized Buffer Flush and Fill
+                                                    ///< Offset 56      Optimized Buffer Flush and Fill
+                                                    ///< Offset 57      Optimized Buffer Flush and Fill
+                                                    ///< Offset 58      Optimized Buffer Flush and Fill
+                                                    ///< Offset 59      Optimized Buffer Flush and Fill
+                                                    ///< Offset 60      Optimized Buffer Flush and Fill
+                                                    ///< Offset 61      Optimized Buffer Flush and Fill
+                                                    ///< Offset 62      Optimized Buffer Flush and Fill
+                                                    ///< Offset 63      Optimized Buffer Flush and Fill
+                                                    ///< Offset 64      Optimized Buffer Flush and Fill
+  UINT8    Rtd3Support;                             ///< Offset 65      Runtime D3 support.
+  UINT8    LowPowerS0Idle;                          ///< Offset 66      Low Power S0 Idle Enable
+  UINT8    VirtualGpioButtonSxBitmask;              ///< Offset 67      Virtual GPIO button Notify Sleep State Change
+  UINT8    PstateCapping;                           ///< Offset 68      P-state Capping
+  UINT8    Ps2MouseEnable;                          ///< Offset 69      Ps2 Mouse Enable
+  UINT8    Ps2KbMsEnable;                           ///< Offset 70      Ps2 Keyboard and Mouse Enable
+  //
+  // Driver Mode
+  //
+  UINT32   GpioIrqRoute;                            ///< Offset 71      GPIO IRQ
+  UINT8    PL1LimitCS;                              ///< Offset 75      set PL1 limit when entering CS
+  UINT16   PL1LimitCSValue;                         ///< Offset 76      PL1 limit value
+  UINT8    TenSecondPowerButtonEnable;              ///< Offset 78      10sec Power button support
+  UINT8    PciDelayOptimizationEcr;                 ///< Offset 79      Pci Delay Optimization Ecr
+  UINT8    TbtSupport;                              ///< Offset 80      Thunderbolt(TM) support
+  UINT8    TbtNativeOsHotPlug;                      ///< Offset 81      TbtNativeOsHotPlug
+  UINT8    TbtSelector;                             ///< Offset 82      Thunderbolt(TM) Root port selector
+  UINT8    TbtSelector1;                            ///< Offset 83      Thunderbolt(TM) Root port selector
+} EFI_GLOBAL_NVS_AREA;
+
+#pragma pack(pop)
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
new file mode 100644
index 0000000000..bbdeb71da5
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ATTEMPT_USB_FIRST_H_
+#define _ATTEMPT_USB_FIRST_H_
+
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_HOTKEY_INFO {
+  UINT8 RevisonId;         // Structure Revision ID
+  UINT8 HotkeyTriggered;   // Hot key status
+} ATTEMPT_USB_FIRST_HOTKEY_INFO;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_VARIABLE {
+  UINT8 UsbBootPrior;
+} ATTEMPT_USB_FIRST_VARIABLE;
+#pragma pack()
+
+//
+// Volatile variable definition for Attempt USB first features
+//
+#pragma pack(1)
+typedef struct _ATTEMPT_USB_FIRST_RUNTIME_VARIABLE {
+  UINT8 RevisonId;        // Structure Revision ID
+  UINT8 UsbFirstEnable;   // Attempt USB First is enabled or not
+} ATTEMPT_USB_FIRST_RUNTIME_VARIABLE;
+#pragma pack()
+
+//
+// Volatile variable definition for third party Default Enabling via UEFI Variable.
+//
+#pragma pack(1)
+typedef struct _ENABLE_CUSTOM_DEFAULTS{
+  UINT32 EnableCustomDefaults;
+} ENABLE_CUSTOM_DEFAULTS;
+#pragma pack()
+
+#define COENG_DEFAULTS_UNKNOWN   0
+#define COENG_DEFAULTS_SUPPORTED 1
+#define COENG_DEFAULTS_VAR_EXITS 2
+#define COENG_DEFAULTS_VAR_SET   4
+#define COENG_DEFAULTS_AVAILABLE (COENG_DEFAULTS_SUPPORTED | COENG_DEFAULTS_VAR_EXITS |COENG_DEFAULTS_VAR_SET)
+
+extern EFI_GUID gAttemptUsbFirstHotkeyInfoHobGuid;
+extern EFI_GUID gAttemptUsbFirstRuntimeVarInfoGuid;
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
new file mode 100644
index 0000000000..17ccd56373
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
@@ -0,0 +1,57 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPUSMM_H_
+#define _CPUSMM_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CPUSMM_GUID { 0x90d93e09, 0x4e91, 0x4b3d, { 0x8c, 0x77, 0xc8, 0x2f, 0xf1, 0xe, 0x3c, 0x81 }}
+#define CPUSMM_SETUP_NAME             L"CpuSmm"
+
+#pragma pack(1)
+typedef struct {
+  UINT8     CpuSmmMsrSaveStateEnable;
+  UINT8     CpuSmmCodeAccessCheckEnable;
+  UINT8     CpuSmmUseDelayIndication;
+  UINT8     CpuSmmUseBlockIndication;
+  UINT8     CpuSmmUseSmmEnableIndication;
+  UINT8     CpuSmmProcTraceEnable;
+} CPU_SMM;
+#pragma pack()
+
+#ifndef OFFSET_OF
+#ifdef __GNUC__
+#if __GNUC__ >= 4
+#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
+#endif
+#endif
+#endif
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+#define VERIFY_OFFSET(TYPE, Field, Offset) extern UINT8 _VerifyOffset##TYPE##Field[(OFFSET_OF(TYPE, Field) == Offset) / (OFFSET_OF(TYPE, Field) == Offset)]
+
+//
+// If TpmSupport/MorStae isn't in this offset, build failure (0 size array or divided by 0) will be generated.
+// Platform DSC file maps the two field to HII PCD so the offset value is critical.
+//
+VERIFY_OFFSET (CPU_SMM, CpuSmmMsrSaveStateEnable, 0x0);
+VERIFY_OFFSET (CPU_SMM, CpuSmmCodeAccessCheckEnable, 0x1);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseDelayIndication, 0x2);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseBlockIndication, 0x3);
+VERIFY_OFFSET (CPU_SMM, CpuSmmUseSmmEnableIndication, 0x4);
+VERIFY_OFFSET (CPU_SMM, CpuSmmProcTraceEnable, 0x5);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
new file mode 100644
index 0000000000..b7202a6b4a
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
@@ -0,0 +1,20 @@
+/** @file
+  This header file provides definitions of firmware configuration.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _FIRMWARE_CONFIGURATION_H_
+#define _FIRMWARE_CONFIGURATION_H_
+
+typedef enum {
+  FwConfigDefault = 0,
+  FwConfigProduction,
+  FwConfigTest,
+  FwConfigMax
+} FW_CONFIG;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
new file mode 100644
index 0000000000..ed63b28adf
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
@@ -0,0 +1,1766 @@
+/** @file
+Header file for GOP Configuration Library
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GOP_CONFIG_LIB_H_
+#define _GOP_CONFIG_LIB_H_
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#pragma pack(1)
+#define GOP_CONFIG_VBT_REVISION 0xC1
+
+#define ChildStruct_MAX                       8         ///< Maximum number of child structures in VBT
+#define CompressionStruct_MAX                 2         ///< Maximum number of compression parameter structures in VBT.
+#define NO_DEVICE                             0x00      ///< Defines a null display class.
+#define DISPLAY_PORT_ONLY                     0x68C6    ///< Defines a display class of Integrated Display Port Only
+#define DISPLAY_PORT_HDMI_DVI_COMPATIBLE      0x60D6    ///< Defines a display class of Integrated DisplayPort with HDMI/DVI Compatible
+#define DISPLAY_PORT_DVI_COMPATIBLE           0x68D6    ///< Defines a display class of Integrated DisplayPort with DVI Compatible
+#define HDMI_DVI                              0x60D2    ///< Defines a display class of Integrated HDMI/DVI
+#define DVI_ONLY                              0x68D2    ///< Defines a display class of Integrated DVI Only
+#define MIPI_ONLY                             0x1400
+#define eDP_ONLY                              0x1806    ///< Defines a display class of eDP only
+#define AUX_CHANNEL_A                         0x40
+#define AUX_CHANNEL_B                         0x10
+#define AUX_CHANNEL_C                         0x20
+#define AUX_CHANNEL_D                         0x30
+#define NO_PORT                               0x00      ///< Defines a output port NA
+#define HDMI_B                                0x01      ///< Defines a output port HDMI-B
+#define HDMI_C                                0x02      ///< Defines a output port HDMI-C
+#define HDMI_D                                0x03      ///< Defines a output port HDMI-D
+#define HDMI_F                                0x0E      ///< Defines a output port HDMI-D
+#define DISPLAY_PORT_A                        0x0A      ///< Defines a output port DisplayPort A
+#define DISPLAY_PORT_B                        0x07      ///< Defines a output port DisplayPort B
+#define DISPLAY_PORT_C                        0x08      ///< Defines a output port DisplayPort C
+#define DISPLAY_PORT_D                        0x09      ///< Defines a output port DisplayPort D
+#define DISPLAY_PORT_E                        0x0B      ///< Defines a output port DisplayPort E
+#define DISPLAY_PORT_F                        0x0D      ///< Defines a output port DisplayPort F
+#define PORT_MIPI_A                           0x15      ///< Mipi Port A
+#define PORT_MIPI_C                           0x17      ///< Mipi Port C
+
+typedef struct {
+  UINT16  Dclk;                         // DClk in 10 KHz
+  UINT8   HActive;                      // HActive [7:0]
+  UINT8   HBlank;                       // HBlank [7:0]
+  UINT8   HA_HB_UpperNibble;            // Upper nibble = HActive [11:8]
+  UINT8   VActive;                      // VActive [7:0]
+  UINT8   VBlank;                       // VBlank [7:0]
+  UINT8   VA_VB_UpperNibble;            // Upper nibble = VActive [11:8]
+  UINT8   HSyncOffset;                  // HSync offset from blank start LSB
+  UINT8   HPulseWidth;                  // HSync Pulse Width, LSB
+  UINT8   VsyncOffset_VpulseWidth_LSB;  // Bits 7:4 = VSync offset [3:0]
+  UINT8   HSO_HSPW_V_High;              // Bits 7:6 = HSync Offset [9:8]
+  UINT8   HorImageSize;                 // Horizontal Image Size
+  UINT8   VerImageSize;                 // Vertical Image Size
+  UINT8   HIS_VIS_High;                 // UpperLmtH_V Upper limits of H. and V. image size
+  UINT8   HBorder;                      // Horizontal Border
+  UINT8   VBorder;                      // Vertical Border
+  UINT8   Flags;                        // Flags
+} DTD_STRUCTURE;                        // 18 Bytes
+
+typedef struct {
+  UINT16  XRes;
+  UINT16  YRes;
+  UINT32  SerialNo;
+  UINT8   Week;
+  UINT8   Year;
+} PID_DATA;                             // 10 Bytes
+
+//
+// VBT Header
+//
+/**
+  This structure defines the VBT Header.
+**/
+typedef struct {
+  UINT8   Product_String[20]; ///< "$VBT_Cannonlake" is the product string
+  UINT16  Version_Num;        ///< Defines the VBT Header version number.
+  UINT16  Header_Size;        ///< Defines the size of VBT Header.
+  UINT16  Table_Size;         ///< Defines the size of complete VBT.
+  UINT8   Checksum;           ///< Defines the checksum of entire VBT
+  UINT8   Reserved1;          ///< Reserved field 1 of 1 byte.
+  UINT32  Bios_Data_Offset;   ///< Defines the offset of VBT Data block.
+  UINT32  Aim_Data_Offset[4]; ///< 4 reserved pointers to VBT data blocks.
+} VBT_HEADER;
+
+/**
+  This structure defines the VBT BIOS Data Block Header
+**/
+typedef struct {
+  UINT8   BDB_Signature[16];  ///< Defines the Bios Data Block signature "BIOS_DATA_BLOCK".
+  UINT16  BDB_Version;        ///< Defines the VBT (data) version.
+  UINT16  BDB_Header_Size;    ///< Defines the size of VBT Bios data block header.
+  UINT16  BDB_Size;           ///< Defines the size of Bios data block.
+} VBT_BIOS_DATA_HEADER;
+
+/**
+  This structure defines the BMP Signon Message and Copyright Message Structure
+**/
+typedef struct {
+  UINT8   BlockId;            ///< Defines Block ID : 254
+  UINT16  BlockSize;          ///< Defines the size of BMP Signon block.
+
+  UINT16  Bmp_BIOS_Size;      ///< Defines the BIOS size 32k/48k/64k.
+  UINT8   BIOS_Type;          ///< Defines the type of BIOS desktop or mobile.
+  UINT8   RelStatus;          ///< Defines the release status of the current GOP driver.
+  UINT8   BIOS_HW;            ///< Defines the Hardware i.e. Cannonlake.
+  UINT8   INT_HW;             ///< Defines the integrated hardware supported eDP/HDMI/DP.
+  UINT8   Build_Number[4];    ///< Defines the build number string.
+  UINT8   SignOn[155];        ///< Defines the sign on message.
+  UINT8   CopyRight[61];      ///< Defines the copyright message.
+} BMP_STRUCTURE_SIGNON;
+
+/**
+  This structure defines the BMP General Bits
+**/
+typedef struct {
+  UINT16  bmp_BIOS_CS;          ///< Defines the start of BIOS code segment
+  UINT8   bmp_DOS_Boot_Mode;    ///< Defines the mode number to set when DOS is boot
+  UINT8   bmp_BW_Percent;       ///< Set percentage of total memory BW
+  UINT8   bmp_Popup_Mem_Size;   ///< Default Popup memory size in KB
+  UINT8   bmp_Resize_PCI_BIOS;  ///< BIOS size granularity in 0.5 KB
+  UINT8   Switch_CRT_To_DDC2;   ///< Obsolete field: Is the CRT already switched to DDC2
+  UINT8   bmp_Allow_Config;     ///< Bit 1 : 1, Enable aspect ratio for DOS
+                                ///< Bit 0 : 1, Allow boot to DVI even if it is not attached.
+} BMPGEN;
+
+/**
+  This structure defines Block 254 (BMP structure)
+**/
+typedef struct {
+  BMP_STRUCTURE_SIGNON    bmp_Signon_Message;   ///< Instance of signon and copyright message structure
+  BMPGEN                  bmp_General_Bytes;    ///< Instance of BMP General Bits structure.
+} BLOCK254_BMP_Structure;
+
+/**
+  This structure defines Block 1 (General Bytes Definitions)
+**/
+typedef struct {
+  UINT8   BlockId;        ///< Defines the Block ID (1)
+  UINT16  BlockSize;      ///< Defines the size of General bytes definition block.
+
+  /**
+  BMP General Bit Definitions 1\n
+  Bit 7 = DVO A color flip bit
+    = 0, No DVO A color flip
+    = 1, Flip DVO A color
+  Bits 6:4 = Clear screen (CLS) after Signon
+      = 000, No CLS
+      = 001, 0.5 sec pause and then CLS
+      = 010, 1.0 sec pause and then CLS
+      = 011, 1.5 sec pause and then CLS
+      = 100, 2.0 sec pause and then CLS
+      = 101, 2.5 sec pause and then CLS
+      = 110, 3.0 sec pause and then CLS
+      = 111, 3.5 sec pause and then CLS
+  Bit 3 = 1  Enable Display Signon
+  Bit 2 = 1  Enable Flex-aim Support
+  Bits 1:0 = Flat panel fitting enabling
+      = 00, Centering
+      = 01, Reserved
+      = 10, Aspect scaling
+      = 11, Fullscreen
+  **/
+  union {
+    UINT8  Value;
+    struct {
+      UINT8 PanelFitterEnabling:2;
+      UINT8 FlexAimSupportEnable:1;
+      UINT8 DisplaySignonEnable:1;
+      UINT8 ClearScreenTime:3;
+      UINT8 DvoAColorFlipEnable:1;
+    } Bits;
+  } bmp_Bits_1;
+
+  /**
+  BMP General Bit Definitions\n
+  Bit 7 = Hot plug support
+    = 0, Hot plug disabled
+    = 1, Hot plug enabled
+  Bit 6 = Dynamic CD clock feature
+    = 0, Dynamic CD clock feature is disabled
+    = 1, Dynamic CD clock feature is enabled
+  Bit 5 = Underscan support for VGA timings
+  Bit 4 = Disable SSC in Dual Display Twin Mode. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, No
+    = 1, Yes
+  Bit 3 = LFP power state on override by 5f64h,08h
+    = 0, No Override
+    = 1, Override
+  Bit 2 = Internal LVDS SSC frequency. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, 96/120MHz
+    = 1, 100MHz
+  Bit 1 = internal LVDS SSC (Spread Spectrum Clock) (This field is obsolete now. Kept for VBIOS only.)
+    = 0, Disabled
+    = 1, Enabled
+  Bit 0 = KvmrSessionEnable.
+    = 0, Disabled
+    = 1, Enabled
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 KvmrSessionEnable:1;
+      UINT8 Reserved_1:5;
+      UINT8 DynamicCdClockEnable:1;
+      UINT8 HotPlugEnable:1;
+    } Bits;
+  } bmp_Bits_2;
+
+  /**
+  BMP General Bit Definitions 3\n
+  Bit 7 = Ignore strap status
+      = 0 Do not ignore
+      = 1 Ignore
+  Bit 6 = Panel Timing algorithm
+      = 0 Preferred timings
+      = 1 Best fit timings
+  Bit 5 Copy iLFP DTD to SDVO LVDS DTD
+      = 0 Don't copy DTD
+      = 1 Copy DTD to
+  Bit 4 = VBIOS normal/extd. DT mode
+      = 0 Normal mode
+      = 1 DUAL mode
+  Bit 3 = FDI RX Polarity
+      = 0 Normal
+      = 1 Inverted
+  Bit 2 = Enable 180 Degree Rotation
+      = 0  Disable
+      = 1  Enable
+  Bit 1 = Single DVI-I connector for CRT and DVI display: Obsolete field
+      = 0 Disabled
+      = 1 Enabled
+  Bit 0 = Smooth Vision
+      = 0  Disabled
+      = 1  Enabled
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 Reserved1:1;
+      UINT8 SingleDviiCrtConnector:1;
+      UINT8 Enable180DegRotation:1;
+      UINT8 FdiRxPolarity:1;
+      UINT8 Reserved2:4;
+    } Bits;
+  } bmp_Bits_3;
+
+  UINT8   Reserved;     ///< Reserved field. It was Legacy_Monitor_Detect in previous platforms.
+
+  /**
+  Integrated display device support\n
+  Bits 7:6 = Reserved
+  Bit 5 = DP SSC Dongle Enable/Disable
+  Bit 4 = DP SSC Frequency. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, 96 MHz
+    = 1, 100 MHz
+  Bit 3 = DP SSC Enable
+    = 0, Disable
+    = 1, Enable
+  Bit 2 = Integrated EFP support
+    = 0, Disable
+    = 1, Enable
+  Bit 1 = Integrated TV support. (This field is obsolete now. Kept for VBIOS only.)
+    = 0, Disable
+    = 1, Enable
+  Bit 0 = Integrated CRT support: Obsolete field
+    = 0, Disable
+    = 1, Enable
+  **/
+  union {
+    UINT8 Value;
+    struct {
+      UINT8 CrtSupported:1;
+      UINT8 TvSupported:1;
+      UINT8 EfpSupported:1;
+      UINT8 DpSscEnable:1;
+      UINT8 DpSscFrequency:1;
+      UINT8 DpDongleSscEnable:1;
+      UINT8 Reserved1:2;
+    } Bits;
+  } Int_Displays_Support;
+} VBT_GENERAL1_INFO;
+
+/**
+  This defines the Structure of PRD Boot Table Entry
+**/
+typedef struct {
+  UINT8 AttachBits;     ///< Bitmap representing the displays attached currently.
+  UINT8 BootDev_PipeA;  ///< Bitmap representing the display to boot on Pipe A.
+  UINT8 BootDev_PipeB;  ///< Bitmap representing the display to boot on Pipe B.
+} PRD_TABLE;
+
+/**
+  This defines the structure of Block 254 (PRD Boot Table/Child Device List)
+**/
+typedef struct {
+  UINT8     BlockId;    ///< Defines the Block ID (254)
+  UINT16    BlockSize;  ///< Defines the size of Block 254
+
+  PRD_TABLE PRDTable[16];                     ///< Defines the Child device list for enumerating child handles.
+  UINT16    PRD_Boot_Table_Number_Of_Entries; ///< Number of entries in child device list.
+} PRD_BOOT_TABLE;
+
+/**
+  This defines the Structure for a CHILD_STRUCT (used for all the displays).
+**/
+typedef struct {
+  UINT16  DeviceHandle;         ///< Unique ID indicating the group of display device (LFP/EFP1/EFP2/EFP3/EFP4).
+  UINT16  DeviceClass;          ///< Indicates the class of display device.
+  UINT8   I2CSpeed;             ///< Defines the I2C speed to be used for I2C transaction.
+  /**
+  Defines the DP on board redriver configuration.
+  BIT[7]    : Reserved
+  BIT[6]    : Is On Board DP Redriver Present
+          0 : No
+          1 : Yes
+  BIT[5:3]  : On Board Redriver VSwing Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+     Others : Reserved
+  BIT[2:0]  : On Board Redriver PreEmph Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+  Others    : Reserved
+  **/
+  union{
+  UINT8 Value;
+  struct {
+    UINT8 OnBoardPreEmphLevel:3;
+    UINT8 OnBoardVSwingLevel:3;
+    UINT8 OnBoardRedriverPresent:1;
+    UINT8 Reserved:1;
+    } Bits;
+  } DpOnBoardRedriver;
+
+  /**
+  Defines the DP on dock redriver configuration.
+  BIT[7]    : Reserved
+  BIT[6]    : Is On Dock DP Redriver Present
+          0 : No
+          1 : Yes
+  BIT[5:3]  : On Dock Redriver VSwing Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+     Others : Reserved
+  BIT[2:0]  : On Dock Redriver PreEmph Level
+          0 : Level 0
+          1 : Level 1
+          2 : Level 2
+          3 : Level 3
+  Others    : Reserved
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 OnDockPreEmphLevel:3;
+    UINT8 OnDockVSwingLevel:3;
+    UINT8 OnDockRedriverPresent:1;
+    UINT8 Reserved:1;
+    } Bits;
+  } DpOnDockRedriver;
+
+  /**
+
+  Defines the HDMI level shifter configuration.
+  BIT[7:5]  : Hdmi Maximum data rate
+  BIT[4:0]  : Hdmi Level shifter value
+
+  **/
+  union{
+  UINT8 Value;
+  struct {
+    UINT8 HdmiLevelShifterValue:5;
+    UINT8 HdmiMaxDataRateBits:3;
+    } Bits;
+  } HdmiLevelShifterConfig;
+
+  UINT16  EFPDTDBufferPointer;  ///< Pointer to the DTD timing to be used in case of edidless EFP.
+
+  /**
+  Defines the first set of flags.
+  BIT[7-4]  : Reserved
+  BIT[3]    : Dual pipe ganged display support
+          0 : Display uses a single pipe/port
+          1 : Display uses two distinct pipes/ports.
+  BIT[2]    : Compression Method Select
+          0 : Compression using picture parameter set (PPS)
+          1 : Compression using Capability parameter set (CPS)
+  BIT[1]    : Compression enable/disable for this display.
+          0 : Disabled
+          1 : Enabled
+  BIT[0]    : EDID less EFP Enable
+          0 : Enable support for EDID less EFP.
+          1 : Disable support for EDID less EFP.
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 EdidlessEfpEnable:1;
+    UINT8 CompressionEnable:1;
+    UINT8 CompressionMethod:1;
+    UINT8 IsDualPortEnabled:1;
+    UINT8 Reserved:4;
+    } Bits;
+  } Flags0;
+
+  /**
+  Defines the compression index field for the display.
+  BITS[7-4]  : Reserved
+  BITS[3-0]  : Compression Structure index in the block 55.
+        0x0  : Index 0 in block 55
+        0x1  : Index 1 in block 55
+        0xF  : Not Applicable.
+      Others : Reserved
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 IndexInBlock55:4;
+    UINT8 Reserved:4;
+    } Bits;
+  } CompressionStructureIndex;
+
+  UINT8   SlaveDdiPort;         ///< The DVO port number of slave DDI to be used in case Flags0[3] = 1.
+
+  UINT8   Reserved_1;           ///< Reserved and might be used in other platforms.
+  UINT16  AddInOffset;          ///< Obsolete field.
+  UINT8   DVOPort;              ///< Specifies the port number of the display device represented in the device class.
+  UINT8   I2CBus;               ///< Specifies the GMBUS or I2C pin pair for add in card.
+  UINT8   SlaveAddr;            ///< Specifies the I2C address of the add in card.
+  UINT8   DDCBus;               ///< Specifies the GMBUS pin pair for EDID read.
+  UINT16  TimingInfoPtr;        ///< Pointer to the buffer where VBIOS stores the EDID of device.
+  UINT8   DVOCfg;               ///< Obsolete field.
+
+  /**
+  Flags 1\n
+  Bits 7:5  : Reserved
+  Bit 4     : HPD Sense Invert
+          0 : Invert not required (default)
+          1 : Invert required
+  Bit 3     : IBoost feature enable/disable.
+          0 : IBoost feature is disabled.
+          1 : IBoost feature is enabled.
+  Bit 2     : Hdmi 2.0 Motherboard Downsuppotred options
+          0 : Motherboard Down chip not supported
+          1 : Motherboard Down Chip Supported on the Board
+  Bit 1     : Lane Reversal feature.
+          0 : Disable
+          1 : Enable
+  Bit 0     : DP/HDMI routed to dock.
+          0 : Disable
+          1 : Enable
+  **/
+  union {
+  UINT8 Value;
+  struct {
+    UINT8 DockablePort:1;
+    UINT8 EnableLaneReversal:1;
+    UINT8 OnBoardLsPconDonglePresent:1;
+    UINT8 IBoostEnable:1;
+    UINT8 IsHpdInverted:1;
+    UINT8 Reserved:3;
+    } Bits;
+  } Flags_1;
+
+  UINT8   Compatibility;        ///< Compatibility is used in VBIOS only. It was used before device class was defined.
+  UINT8   AUX_Channel;          ///< Specifies the aux channel to be used for display port devices.
+  UINT8   Dongle_Detect;        ///< Indicates whether dongle detect is enabled or not.
+  UINT8   Capabilities;         ///< Bits 1-0 indicate pipe capabilities whether display can be used on one pipe or both the pipes.
+  UINT8   DVOWiring;            ///< Obsolete field.
+  UINT8   MipiBridgeType;       ///< MIPI bridge type
+  UINT16  DeviceClassExtension; ///< Obsolete.
+  UINT8   DVOFunction;          ///< Obsolete.
+
+  /**
+  Flags 2
+  Bits 7:4  : DP Port trace length from silicon to output port on the board
+          0 : Default RVP length
+          1 : Short trace length
+          2 : Long trace length
+  Bits 3:2  : Reserved
+  Bit 1     : Indicates whether this port is Thunderbolt port or not.
+          0 : No
+          1 : Yes
+  Bit 0     : DP 2 lane RCR# 1024829: USB type C to enable 2 lane DP display
+          0 : Disable
+          1 : Enable
+  **/
+  union {
+    UINT8   Value;
+    struct {
+      UINT8   UsbTypeCDongleEnabled:1;  ///< Indicates whether this port is USB type C.
+      UINT8   IsThunderboltPort:1;      ///< Indicates whether this port is Thunderbolt. (ICL+)
+      UINT8   Reserved:2;               ///< Reserved for future use.
+      UINT8   DpPortTraceLength:4;      ///< Dp port trace length from silicon to port.
+    } Bits;
+  } Flags_2;
+  UINT8   DP2XGpioIndex;        ///< GPIO index number for the USB type C.
+  UINT16  DP2XGpioNumber;       ///< GPIO number for USB type C.
+
+  /**
+  IBoost magnitude field.
+  Bits 7:4  : DP Boost magnitude
+          0 : 1
+          1 : 3
+          2 : 7
+     Others : Reserved for WHL.
+  Bits 3:0  : HDMI Boost magnitude
+          0 : 1
+          1 : 3
+          2 : 7
+  Others : Reserved.
+  **/
+  union {
+    UINT8   Value;
+    struct {
+      UINT8   DpEdpBoostMagnitude:4;
+      UINT8   HdmiBoostMagnitude:4;
+    } Bits;
+  } BoostMagnitude;
+} CHILD_STRUCT;
+
+/**
+  This structure defines Block 2 (General Bytes Definitions)
+**/
+typedef struct {
+  UINT8         BlockId;          ///< Defines the Block ID : 2.
+  UINT16        BlockSize;        ///< Defines the size of VBT General Info 2 Block.
+
+  UINT8         bmp_CRT_DDC_GMBUS_Pin;  ///< Obsolete field: Selects the CRT DDC GMBUS pin pair.
+  UINT8         bmp_DPMS_Bits;          ///< BMP DPMS Bit Definitions.
+  UINT16        bmp_Boot_Dev_Bits;      ///< BMP Boot Device Bit Definitions.
+  UINT8         SizeChild_Struct;       ///< Size of the ChildStruc structure.
+
+  CHILD_STRUCT  Child_Struct[ChildStruct_MAX];  ///< This array defines all the supported child structures.
+} VBT_GENERAL2_INFO;
+
+/**
+  This defines the structure of Block 3 (Original Display Toggle List)
+**/
+typedef struct {
+  UINT8   BlockId;                ///< Defines the Block ID : 3
+  UINT16  BlockSize;              ///< Defines the size of Original Display Toggle List Block
+  UINT8   bmp_Display_Detect;     ///< Display must be attached or not
+} BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST;
+
+/**
+  This defines structure of a pointer table.
+**/
+typedef struct {
+  UINT16  Offset;       ///< Defines the offset of the table from start of BIOS Data block.
+  UINT16  Size;         ///< Defines the size of an entry of the table.
+} BMP_TABLE_PTR;
+
+/**
+  This structure defines Block 252 (SBIOS Hooks and BMP Table Pointers).
+**/
+typedef struct {
+  UINT8           BlockId;          ///< Defines the Block ID : 252.
+  UINT16          BlockSize;        ///< Defines the size of SBIOS Hooks block.
+  UINT8           SbiosHooks[18];   ///< This array defines a series of SBIOS hooks. Each entry represents one hook.
+  BMP_TABLE_PTR   BmpTablePtr[26];  ///< This array defines pointers to all the important tables in the VBT.
+} BLOCK252_SBIOS_Hook;
+
+/**
+  This defines the structure of MMIO boot table entry
+**/
+typedef struct {
+  UINT32  Register;   ///< Defines the MMIO offset of the register.
+  UINT32  Value;      ///< Defines the default value of the register.
+} MMIO_BOOT_TABLE;
+
+/**
+  This structure defines Block 6 (MMIO Register Block)
+**/
+typedef struct {
+  UINT8           BlockId;              ///< Defines the Block ID : 6
+  UINT16          BlockSize;            ///< Defines the size of MMIO Register Table block.
+  UINT16          RegTableId;           ///< Defines the ID for MMIO register table (0xFFFC).
+  UINT8           AccessFlag;           ///< Defines the flag for data access size (02 for 4 byte read/write).
+  MMIO_BOOT_TABLE MMIOBootTable[14];    ///< Array containing the MMIO register table.
+  UINT16          TableEnd;             ///< Special value describing End of table (0xFFFF).
+} BLOCK06_MMIO_REG_TABLE;
+
+/**
+  This structure defines Block 7 (IO SW Flag Register Table)
+**/
+typedef struct {
+  UINT8   BlockId;          ///< Defines Block ID (7).
+  UINT16  BlockSize;        ///< Defines the size of IO SW Flag register table block.
+  UINT16  RegTableId;       ///< Defines the ID for IO SW Flag register table (0xFFFE).
+  UINT8   GRIndexRegLsb;    ///< Defines the read/write size. Value is 0xCE meaning 1 byte without mask.
+  UINT8   IOSWFlagReg;      ///< Defines the offset for the IO SW Flag register.
+  UINT8   Value;            ///< Defines the data/value for the register.
+  UINT16  TableEnd;         ///< Special value describing the end of table (0xFFFF).
+} BLOCK07_IOSWFLAG_REG_TABLE;
+
+/**
+  This structure defines the entry of SWF table.
+**/
+typedef struct {
+  UINT32  Register;   ///< Defines the MMIO offset of the SWF register.
+  UINT32  Value;      ///< Defines the default value for the SWF register.
+} SWF_TABLE;
+
+/**
+  This defines the structure of Block 8 (MMIO SW Flag Block).
+**/
+typedef struct {
+  UINT8     BlockId;      ///< Defines the Block ID : 8.
+  UINT16    BlockSize;    ///< Defines the size of MMIO SWF register table block.
+  UINT16    RegTableId;   ///< Defines the ID for MMIO SWF register table (0xFFFC).
+  UINT8     AccessFlag;   ///< Defines the data access size. Value is 0x02 meaning 4 bytes read/write.
+  SWF_TABLE SWFTable[7];  ///< Array containing the MMIO SWF register table.
+  UINT16    TableEnd;     ///< Special value describing end of table (0xFFFF).
+} BLOCK08_MMIOSWFLAG_REG_TABLE;
+
+/**
+  This structure defines the PSR feature table entry.
+**/
+typedef struct {
+  UINT8   SRD_Enables;        ///< Defines PSR features such as full link enable/disable and whether aux is required to wake up.
+  UINT8   SRD_WaitTimes;      ///< Defines lines to wait before link standby and idle frames to wait before SRD enable.
+  UINT16  SRD_TP1_WakeupTime; ///< TP 1 wake up time in multiples of 100.
+  UINT16  SRD_TP2_WakeupTime; ///< TP2/TP3 wake up time in multiples of 100
+} PSR_FEATURE_TABLE;
+
+/**
+  This defines the structure of Block 9 (PSR Features Block)
+**/
+typedef struct {
+  UINT8             BlockId;              ///< Defines the block ID : 9
+  UINT16            BlockSize;            ///< Defines the size of PSR Feature block.
+  PSR_FEATURE_TABLE PSRFeatureTable[16];  ///< Array containing the PSR Feature table.
+} BLOCK09_PSR_FEATURE;
+
+/**
+  This structure defines an entry of Mode Removal table.
+**/
+typedef struct {
+  UINT16  XRes;         ///< X resolution of the mode.
+  UINT16  YRes;         ///< Y resolution of the mode.
+  UINT8   Bpp;          ///< Bits per pixel of the mode.
+  UINT16  RRate;        ///< Refresh rate of the mode.
+  UINT8   RFlags;       ///< Flags specifying display type and functional area where the mode is to be removed.
+  UINT16  PanelFlags;   ///< Applicable to LFP only. Indicates which LFP panels the mode is to be removed.
+} MODE_REMOVAL_TABLE_ENTRY;
+
+/**
+  This defines the structure of Block 10 (Mode Removal Block)
+**/
+typedef struct {
+  UINT8                     BlockId;              ///< Defines the Block ID : 10.
+  UINT16                    BlockSize;            ///< Defines the size of Mode Removal table block.
+  UINT8                     EntrySize;            ///< Defines the size of one entry of mode removal table.
+  MODE_REMOVAL_TABLE_ENTRY  ModeRemovalTable[20]; ///< Array containing the mode removal table.
+  UINT16                    Terminator;           ///< Special value indicating end of mode removal table (0xFFFF).
+} BLOCK10_MODE_REMOVAL_TABLE;
+
+/**
+  This defines the structure of Block 12 (Driver Features Data Block)
+**/
+typedef struct {
+  UINT8   BlockId;                  ///< Defines the unique Block ID : 12
+  UINT16  BlockSize;                ///< Defines the size of Driver features block.
+
+  /**
+  This field defines the various driver related bits:\n
+  Bit 7 = Use 00000110h ID for Primary LFP
+        = 0, No
+        = 1, Yes
+  Bit 6 = Enable/Disable Sprite in Clone Mode
+        = 0, Disable
+        = 1, Enable
+  Bit 5 = Driver INT 15h hook
+        = 0, Disable
+        = 1, Enable
+  Bit 4 = Dual View Zoom
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = Hot Plug DVO
+        = 0, Disable
+        = 1, Enable
+  Bit 2 = Allow display switching when in Full Screen DOS.
+        = 0, Block Display Switching
+        = 1, Allow Display Switching
+  Bit 1 = Block display switching when DVD active
+        = 0, No Block Display Switching
+        = 1, Block Display Switching
+  Bit 0 = Boot device algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  **/
+  UINT8   bmp_Driver_Bits;
+  UINT16  bmp_Driver_Boot_Mode_X;   ///< X resolution of driver boot mode.
+  UINT16  bmp_Driver_Boot_Mode_Y;   ///< Y resolution of driver boot mode.
+  UINT8   bmp_Driver_Boot_Mode_BPP; ///< Bits per pixel of driver boot mode.
+  UINT8   bmp_Driver_Boot_Mode_RR;  ///< Refresh rate of driver boot mode.
+
+  /**
+  This field defines the extended driver bits 1.\n
+  Bits [15:14] = Integrated HDMI configuration
+              = 00b,  No Integrated HDMI
+              = 01b,  Port-B Only
+              = 10b,  Port-C Only
+              = 11b,  Both Port-B and Port-C
+  Bits 13 = TV Hotplug
+  Bits [12:11]  = LFP configuration
+                = 00b,  No LVDS
+                = 01b,  Integrated LVDS
+                = 10b,  SDVO LVDS
+                = 11b,  eDP
+  Bit 10 = Obsolete field: CRT hotplug
+          = 0, Disabled
+          = 1, Enabled (Default)
+  Bit 9 = SDVO device power down
+        = 0, Disabled (Default)
+        = 1, Enabled
+  Bit 8 = Preserve Aspect Ratio
+        = 0, Disabled (Default)
+        = 1, Enabled
+  Bit 7 = Display "Maintain Aspect Scaling" via CUI
+        = 0, No
+        = 1, Yes (Default)
+  Bit 6 = Sprite Display Assignment when Overlay is Active in Clone Mode:
+        = 0, Secondary
+        = 1, Primary
+  Bit 5 = Default Power Scheme user interface
+        = 0, CUI
+        = 1, 3rd Party Application
+  Bit 4 = NT 4.0 Dual Display Clone Support
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = Default Render Clock Frequency
+        = 0, High Frequency
+        = 1, Low Frequency
+  Bit 2 = Dual-Frequency Graphics Technology
+        = 0, No
+        = 1, Yes
+  Bit 1 = Selective Mode Pruning
+        = 0, No
+        = 1, Yes
+  Bit 0 = Enable LFP as primary
+        = 0, Disable
+        = 1, Enable
+**/
+  UINT16  bmp_Ext_Driver_Bits;
+
+  /**
+  This defines the driver flags related to CUI Hot key.\n
+  Bits [7:3] - Reserved
+  Bit 2 = Display Subsystem Enable/Disable
+        = 0, Enable (default Value)
+        = 1, Disable
+  Bit 1 = Embedded Platform
+        = 0, False
+        = 1, True
+  Bit 0 = Define CUI HotK Displays Statically
+        = 0, No
+        = 1, Yes
+  **/
+  UINT8   bmp_Display_Detect_CUIHotK;
+
+  UINT16  bmp_Legacy_CRT_Max_X;         ///< Obsolete field: Defines the legacy CRT X resolution for driver boot mode.
+  UINT16  bmp_Legacy_CRT_Max_Y;         ///< Obsolete field: Defines the legacy CRT Y resolution for driver boot mode.
+  UINT8   bmp_Legacy_CRT_Max_RR;        ///< Obsolete field: Defines the legacy CRT refresh rate for driver boot mode.
+
+  /**
+  This field defines the extended driver bits 2.\n
+  Bits [7:1] - Reserved
+  Bit 0 = Enable Internal Source Termination for HDMI
+        = 0, External Termination
+        = 1, Internal Termination
+  **/
+  UINT8   bmp_Ext2_Driver_Bits;
+
+  UINT8   bmp_VBT_Customization_Version;  ///< Defines the customized VBT version number.
+
+  /**
+  This field defines all the driver feature flags.\n
+  Bit 15 = PC Features Field's Validity
+         = 0, Invalid
+         = 1, Valid
+  Bit 14 = Hpd_wake - HPD events are routed to display driver when system is in S0ix/DC9
+         = 0, Disable
+         = 1, Enable
+  Bit 13 = Assertive Display Technology (ADT)
+         = 0, Disable
+         = 1, Enable
+  Bit 12 = Dynamic Media Refresh Rate Switching (DMRRS)
+         = 0, Disable
+         = 1, Enable
+  Bit 11 = Dynamic Frames Per Second (DFPS)
+         = 0, Disable
+         = 1, Enable
+  Bit 10 = Intermediate Pixel Storage (IPS)
+         = 0, Disable
+         = 1, Enable
+  Bit 9 = Panel Self Refresh (PSR)
+        = 0, Disable
+        = 1, Enable
+  Bit 8 = Intel Turbo Boost Technology
+        = 0, Disable
+        = 1, Enable
+  Bit 7 = Graphics Power Modulation Technology (GPMT)
+        = 0, Disable
+        = 1, Enable
+  Bit 6 = Graphics Render Standby (RS)
+        = 0, Disable
+        = 1, Enable
+  Bit 5 = Intel Display Refresh Rate Switching (DRRS)
+        = 0, Disable
+        = 1, Enable
+  Bit 4 = Intel Automatic Display Brightness (ADB)
+        = 0, Disable
+        = 1, Enable
+  Bit 3 = DxgkDDI Backlight Control (DxgkDdiBLC)
+        = 0, Disable
+        = 1, Enable
+  Bit 2 = Intel Display Power Saving Technology (DPST)
+        = 0, Disable
+        = 1, Enable
+  Bit 1 = Intel Smart 2D Display Technology (S2DDT)
+        = 0, Disable
+        = 1, Enable
+  Bit 0 = Intel Rapid Memory Power Management (RMPM)
+        = 0, Disable
+        = 1, Enable
+  **/
+  UINT16  bmp_Driver_Feature_Flags;
+} BLOCK12_DRIVER_FEATURES;
+
+/**
+  This defines the structure of Block 13 (Driver Persistence Options)
+**/
+typedef struct {
+  UINT8   BlockId;                ///< Defines the unique Block ID : 13
+  UINT16  BlockSize;              ///< Defines the size of Driver Persistence options block.
+
+  /**
+  Defines the various persistence options.\n
+  Bits [15:10] - Reserved
+  Bit 9 = Docking Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 8 = DVO Hot Plug Persistence on Mode
+  Bit 7 = EDID Persistence on Mode
+  Bit 6 = Hot Key Persistence on Mode
+        = 0, No
+        = 1, Yes
+  Bit 5 = Hot Key Persistence on RestorePipe
+        = 0, No
+        = 1, Yes
+  Bit 4 = Hot Key Persistence on RefreshRate
+        = 0, No
+        = 1, Yes
+  Bit 3 = Hot Key Persistence on MDS/Twin
+        = 0, No
+        = 1, Yes
+  Bit 2 = Power Management Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 1 = Lid Switch Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  Bit 0 = Hot Key Persistence Algorithm
+        = 0, OS Default
+        = 1, Driver Default
+  **/
+  UINT16  PersistenceAlgorithm;
+
+  UINT8   PersistMaxconfig;       ///< Maximum mode persistence configurations (10-200)
+} BLOCK13_DRIVER_PERSISTENCE;
+
+/**
+  This defines the structure of Block 17 (SV Bits)
+**/
+typedef struct {
+  UINT8   BlockId;      ///< Defnies the unique Block ID : 17
+  UINT16  BlockSize;    ///< Defines the size of SV Bits block.
+
+  /**
+  Bits [7:4] = Reserved
+    Bit3  = Allow VBlank/VblankScanline timeout hang
+          = 0, Disable
+          = 1, Enable
+    Bit2  = Special GMBus support
+          = 0, Disable
+          = 1, Enable
+    Bit1  = Skip program pipe timings when set VGA modes
+          = 0, Setmode skip DVO Update
+          = 1, Setmode updates DVO
+    Bit0  = Disable VGA fast arbiter
+          = 0, Enabled
+          = 1, Disabled
+  **/
+  UINT8   SvBits1;
+  UINT8   SvBits2;      ///< Reserved for future use.
+  UINT8   SvBits3;      ///< Reserved for future use.
+  UINT8   SvBits4;      ///< Reserved for future use.
+  UINT8   SvBits5;      ///< Reserved for future use.
+  UINT8   SvBits6;      ///< Reserved for future use.
+  UINT8   SvBits7;      ///< Reserved for future use.
+  UINT8   SvBits8;      ///< Reserved for future use.
+} BLOCK17_SV_BITS;
+
+/**
+  This defines the structure of Block 18 (Driver Rotation)
+**/
+typedef struct {
+  UINT8   BlockId;                    ///< Defines the unique Block ID : 18
+  UINT16  BlockSize;                  ///< Defines the size of Driver Rotation block.
+  UINT8   RotationFeatureSupport;     ///< Rotation feature support field used by driver.
+  UINT8   Reserved1;                  ///< Reserved for future use.
+  UINT16  Reserved2;                  ///< Reserved for future use.
+  UINT32  Reserved3;                  ///< Reserved for future use.
+  UINT32  Reserved4;                  ///< Reserved for future use.
+} BLOCK18_DRIVER_ROTATION;
+
+/**
+  This structure defines an entry of OEM mode table.
+**/
+typedef struct {
+  /**
+  Mode Flags:
+    Bits[7:3] = Reserved
+    Bit 2 = Enable/disable this OEM mode in GOP driver.
+    Bit 1 = Enable/disable this mode in Driver
+    Bit 0 = Enable/disable this mode in VBIOS
+  **/
+  UINT8   ModeFlags;
+
+  /**
+  Display Device Flags:
+    Bit 7 = LFP2
+    Bit 6 = EFP2
+    Bit 5 = EFP3
+    Bit 4 = EFP4
+    Bit 3 = LFP
+    Bit 2 = EFP
+    Bit 1 = Rsvd
+    Bit 0 = Rsvd
+  **/
+  UINT8   DisplayFlags;
+  UINT16  XRes;         ///< Defines the X resolution of the mode.
+  UINT16  YRes;         ///< Defines the Y resolution of the mode.
+
+  /**
+  Defines the bits per pixel of the mode.
+    Bit 7:3 = Reserved
+    Bit 2 = 32 BPP
+    Bit 1 = 16 BPP
+    Bit 0 = 8 BPP
+  **/
+  UINT8   Bpp;
+  UINT8   RRate;        ///< Defines the refresh rate of the mode.
+  DTD_STRUCTURE Dtd;    ///< Defines the 18 byte timing config for the mode.
+} OEM_MODE_ENTRY;
+
+/**
+  This defines the structure of Block 20 (OEM Mode Customization Block)
+**/
+typedef struct {
+  UINT8           BlockId;          ///< Defines the unique block ID : 20
+  UINT16          BlockSize;        ///< Defines the size of OEM customization block.
+  UINT8           NumOfEntry;       ///< Defines the number of entries in OEM Mode table.
+  UINT8           EntrySize;        ///< Defines the size of one entry of OEM Mode table.
+  OEM_MODE_ENTRY  OemModeTable[6];  ///< Array defining the OEM mode table.
+} BLOCK20_OEM_CUSTOMIZATION;
+
+/**
+  This defines the structure of Block 26 (TV options)
+**/
+typedef struct {
+  UINT8   BlockId;                  ///< Defines the unique Block ID : 26
+  UINT16  BlockSize;                ///< Defines the size of TV Options block.
+
+  /**
+  Defines the TV options:
+    Bit 15  = D-Conector Support
+            = 0, Disable
+            = 1, Enable
+    Bit 14 = Add 1776x1000 when 1080i is selected and add 1184x666 when 720p is selected
+            = 0, Disable
+            = 1, Enable
+    Bit 13:12 Underscan/overscan for HDTV via DVI
+            = 00b, Enable Underscan and Overscan modes (Default)
+            = 01b, Enable only overscan modes
+            = 10b, Enable only underscan modes
+    Bits 11:2 = Reserved
+    Bit 1:0 = Underscan/overscan for HDTV via Component (YPrPb)
+            = 00b, Enable Underscan and Overscan modes (Default)
+            = 01b, Enable only overscan modes
+            = 10b, Enable only underscan modes
+  **/
+  UINT16  bmp_TV_Options_1;
+} BLOCK26_TV_OPTIONS;
+
+/**
+  This structure defines the eDP panel power sequencing parameters.
+**/
+typedef struct {
+  UINT16  T3;         ///< Panel Power-Up Delay.
+  UINT16  T8;         ///< Panel Power-On to backlight Enable Delay.
+  UINT16  T9;         ///< Backlight-Off to Power-Down Delay.
+  UINT16  T10;        ///< Power-Down Delay.
+  UINT16  T12;        ///< Power Cycle Delay.
+} EDP_PWR_SEQ;
+
+/**
+  This structure defines the PWM<-->Backlight delays for a single eDP panel.
+**/
+typedef struct {
+  UINT16  PwmOnToBacklightEnableDelay;      ///< PWM on to backight enable delay.
+  UINT16  BacklightDisableToPwmOffDelay;    ///< Backlight disable to PWM off delay.
+} EDP_PWM_BACKLIGHT_DELAYS;
+
+/**
+  This defines FLT parameters for a single eDP panel.
+  Bits[15:12] : VSwing level
+            0 : 0.4V (default)
+            1 : 0.6V
+            2 : 0.8V
+            3 : 1.2V
+       Others : Reserved
+  Bits[11:8]  : Pre-emphasis level
+            0 : no pre-emphasis (default)
+            1 : 3.5dB
+            2 : 6dB
+            3 : 9.5dB
+       Others : Reserved
+  Bits[7:4]   : Lane count (port width)
+            0 : x1 mode (default)
+            1 : x2 mode
+            2 : Reserved
+            3 : x4 mode
+       Others : Reserved
+  Bits[3:0]   : data rate
+            0 : 1.62 Gbps
+            1 : 2.7 Gbps
+            2 : 5.4 Gbps
+       Others : Reserved
+**/
+typedef union {
+  UINT16 Value;
+  struct {
+    UINT16 DataRate:4;
+    UINT16 LaneCount:4;
+    UINT16 PreEmphasisLevel:4;
+    UINT16 VSwingLevel:4;
+  } Bits;
+} EDP_FAST_LINK_TRAINING_PARAMS;
+
+/**
+  This defines Full link training parameters for a single eDP panel.
+  Bits[7:4] : VSwing level
+          0 : 0.4V (default)
+          1 : 0.6V
+          2 : 0.8V
+          3 : 1.2V
+     Others : Reserved
+  Bits[3:0] : Pre-emphasis level
+          0 : no pre-emphasis (default)
+          1 : 3.5dB
+          2 : 6dB
+          3 : 9.5dB
+     Others : Reserved
+**/
+typedef union {
+  UINT8   Value;
+  struct {
+    UINT8   PreEmphasisLevel:4;
+    UINT8   VSwingLevel:4;
+  } Bits;
+} EDP_FULL_LINK_TRAINING_PARAMS;
+
+/**
+  This defines the structure of Apical Parameters for a single eDP panel.
+**/
+typedef struct {
+  UINT32      PanelOui;             ///< Apical IP specific field for Panel OUI
+  UINT32      DPCDBaseAddress;      ///< Apical IP specific field for DPCD Base address
+  UINT32      DPCDIrdidixControl0;  ///< Apical IP specific field for DPCD Idridix Control 0
+  UINT32      DPCDOptionSelect;     ///< Apical IP specific field for DPCD option select
+  UINT32      DPCDBacklight;        ///< Apical IP specific field for DPCD backlight
+  UINT32      AmbientLight;         ///< Apical IP specific field for Ambient light
+  UINT32      BacklightScale;       ///< Apical IP specific field for backlight scale
+} EDP_APICAL_PARAMS;
+
+/**
+  This defines the structure of Block 27 (eDP Display Block)
+**/
+typedef struct {
+  UINT8       BlockId;            ///< Defines the unique Block ID : 27
+  UINT16      BlockSize;          ///< Defines the size of eDP display VBT block.
+
+  EDP_PWR_SEQ eDP_PWR_SEQ[16];    ///< Array defining the panel power sequencing for all 16 eDP panels.
+
+  /**
+  Defines the panel color depth in bits per pixel. 2 Bits for each Panel.
+    Bits[1:0] Panel color depth for Panel #1
+      = 00, 18bpp
+      = 01, 24bpp
+      = 10, 30bpp
+      = 11, 36bpp
+  **/
+  UINT32      eDP_Panel_Color_Depth;
+
+  /**
+    Array containing the FLT parameters of 16 eDP panels.
+  **/
+  EDP_FAST_LINK_TRAINING_PARAMS      eDP_Fast_Link_Training_Params[16];
+
+  /**
+  This field defines the eDP sDRRS MSA Timing Delay for all 16 eDP panels. 2 Bits for Each Panel.
+  Bits[1:0] for Panel #1
+    = 00, Line 1
+    = 01, Line 2
+    = 10, Line 3
+    = 11, Line 4
+  **/
+  UINT32      eDP_sDRRS_MSA_Delay;
+
+  /**
+  Defines the S3D feature enable/disable for all 16 eDP panels. 1 Bit for Each Panel.
+  Bits[0] for Panel #1
+    = 0, S3D disabled for this panel
+    = 1, S3D enabled for this panel
+  **/
+  UINT16      eDP_S3D_Feature;
+
+  /**
+  Defines the T3 optimization enable/disable for all 16 panels. 1 Bit for each panel.
+  Bits[0] = Panel #1
+    = 0, T3 optimization disabled for this panel
+    = 1, T3 optimization enabled for this panel
+  **/
+  UINT16      eDP_T3_Optmization;
+
+  /**
+  Defines the Edp vswing and pre-emphasis for all 16 panels. 4 Bits for Each Panel
+  Bits[3:0] = Panel #1
+    = 0, Use table 1 for this panel.
+    = 1, Use table 2 for this panel.
+  **/
+  UINT64       VswingPreEmphasisTableNum;
+
+  /**
+  Defines the Edp fast link training support on all 16 panels. 1 Bit for Each Panel
+  Bits[0] = Panel #1
+    = 0, FastLinkTraining feature is disabled for this panel
+    = 1, FastLinkTraining feature is enabled for this panel
+  **/
+  UINT16     EdpFastLinkTrainingSupportOnPanel;
+
+  /**
+  Defines whether the Set power state at DPCD 600h is to be done in eDP enable/disable sequence.
+  Bits[0] = Panel #1
+    = 0, Set power state at DPCD 600h feature is disabled for this panel
+    = 1, Set power state at DPCD 600h feature is enabled for this panel
+  **/
+  UINT16     SetPowerStateAtDPCD600h; //This is not used currently
+
+  /**
+    Array defining the PWM <--> Backlight related delays for 16 panels.
+  **/
+  EDP_PWM_BACKLIGHT_DELAYS eDP_Pwm_BackLight_Delays[16];
+
+  /**
+  Defines the Edp full link training support on all 16 panels. 1 Bit for Each Panel.
+  \verbatim
+  Bits[0] : Panel #1
+        0 : Initial vswing and pre-emphasis levels are not provided for Full link training
+        1 : Initial vswing and pre-emphasis levels are provided for Full link training
+  Bits 1 to 15 are for panel # 2 to 16.
+  \endverbatim
+  **/
+  UINT16     InitialFullLinkTrainingParamsProvidedInVbt;
+
+  /**
+    Array containing the initial Vswing and Pre-emphasis parameters for Full link training.
+  **/
+  EDP_FULL_LINK_TRAINING_PARAMS    eDP_Full_Link_Training_Params[16];
+
+  /**
+  Defines the Edp Apical assertive display IP support on all 16 panels. 1 Bit for Each Panel.
+  Bit 0   : Panel #1
+        0 : Apical assertive display IP is disabled for this panel.
+        1 : Apical assertive display IP is enabled for this panel.
+  Bits 1 to 15 are for panel # 2 to 16.
+  **/
+  UINT16                           IsApicalAssertiveDisplayIpEnable;
+
+  /**
+    Array containing the Apical parameters for all 16 panels
+  **/
+  EDP_APICAL_PARAMS                eDP_Apcial_Params[16];
+} BLOCK27_EDP_FEATURES;
+
+/**
+  This defines the structure of Block 28 (Edidless EFP support DTD timings)
+**/
+typedef struct {
+  UINT8                 BlockId;                    ///< Defines the unique Block ID : 28
+  UINT16                BlockSize;                  ///< Defines the size of Edidless EFP support block.
+  DTD_STRUCTURE         Edidless_EFP_DTD_Struc[4];  ///< Array defining the DTD timing for 3 EFP devices.
+} BLOCK28_EDIDLESS_EFP;
+
+/**
+This defines the structure of toggle list entry.
+**/
+typedef struct {
+  /**
+  Defines the display device selection for toggling
+  Bit 15 = EFP4.3 (Reserved for WHL)
+  Bit 14 = EFP3.3
+  Bit 13 = EFP2.3
+  Bit 12 = EFP1.3
+  Bit 11 = EFP4.2 (Reserved for WHL)
+  Bit 10 = EFP3.2
+  Bit 9  = EFP2.2
+  Bit 8  = EFP1.2
+  Bit 7  = LFP2
+  Bit 6  = EFP2
+  Bit 5  = EFP3
+  Bit 4  = EFP4
+  Bit 3  = LFP
+  Bit 2  = EFP
+  Bit 1  = TV
+  Bit 0  = CRT
+  **/
+  UINT16  DisplayDevice;
+} CNL_TOGGLE_LIST_ENTRY;
+
+/**
+  This defines the structure of Block 31 (Toggle Lists for Cannonlake)
+**/
+typedef struct {
+  UINT8                   BlockId;              ///< Defines the unique Block ID : 31
+  UINT16                  BlockSize;            ///< Defines the size of Toggle List Block.
+  UINT16                  NumOfEntry1;          ///< Defines the number of entries in toggle list 1.
+  UINT8                   EntrySize1;           ///< Defines the size of toggle list entry present in list 1.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList1Entry[16]; ///< Array defining the toggle list 1.
+  UINT16                  NumOfEntry2;          ///< Defines the number of entries in toggle list 2.
+  UINT8                   EntrySize2;           ///< Defines the size of toggle list entry present in list 2.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList2Entry[8];  ///< Array defining the toggle list 2.
+  UINT16                  NumOfEntry3;          ///< Defines the number of entries in toggle list 3.
+  UINT8                   EntrySize3;           ///< Defines the size of toggle list entry present in list 3.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList3Entry[8];  ///< Array defining the toggle list 3.
+  UINT16                  NumOfEntry4;          ///< Defines the number of entries in toggle list 4.
+  UINT8                   EntrySize4;           ///< Defines the size of toggle list entry present in list 4.
+  CNL_TOGGLE_LIST_ENTRY   ToggleList4Entry[8];  ///< Array defining the toggle list 4.
+} BLOCK31_TOGGLE_LIST;
+
+/**
+  This defines the structure of Display device removal configuration entry.
+**/
+typedef struct {
+  /**
+  Defines the display device configuration to be removed.
+  Bit 15 = EFP4.3 (Reserved for WHL)
+  Bit 14 = EFP3.3
+  Bit 13 = EFP2.3
+  Bit 12 = EFP1.3
+  Bit 11 = EFP4.2 (Reserved for WHL)
+  Bit 10 = EFP3.2
+  Bit 9  = EFP2.2
+  Bit 8  = EFP1.2
+  Bit 7  = LFP2
+  Bit 6  = EFP2
+  Bit 5  = EFP3
+  Bit 4  = EFP4
+  Bit 3  = LFP
+  Bit 2  = EFP
+  Bit 1  = TV
+  Bit 0  = CRT
+  **/
+  UINT16  DisplayDeviceConfiguration;
+} CNL_DISPLAY_CONFIGURATION_ENTRY;
+
+/**
+  This defines the structure of Block 32 (Display removal configuration Block)
+**/
+typedef struct {
+  UINT8                                BlockId;       ///< Defines the unique Block ID = 32
+  UINT16                               BlockSize;     ///< Defines the size of Display removal configuration block.
+  UINT8                                NumOfEntry;    ///< Defines the number of entries in display removal configuraion table.
+  UINT8                                EntrySize;     ///< Defines the size of 1 entry in display removal configuration table.
+  CNL_DISPLAY_CONFIGURATION_ENTRY      RemoveDisplayConfiguration[15];    ///< Array defining the display removal configuration table.
+}BLOCK32_DISPLAY_CONFIGURATION_REMOVAL;
+
+/**
+  This defines the Local Flat panel basic details such as resolution and the various registers.
+**/
+typedef struct {
+  UINT16  XRes;                   ///< X resolution of the panel.
+  UINT16  YRes;                   ///< Y resolution of the panel.
+  UINT32  LVDSDigDisReg;          ///< MMIO offset of LFP digital display port register.
+  UINT32  LVDSDigDisVal;          ///< Value of LFP digital display port register.
+  UINT32  OnSeqDelayReg;          ///< MMIO offset of Panel power on sequencing delay register.
+  UINT32  OnSeqDelayVal;          ///< Value of Panel power on sequencing delay register.
+  UINT32  OffSeqDelayReg;         ///< MMIO offset of Panel power off sequencing delay register.
+  UINT32  OffSeqDelayVal;         ///< Value of Panel power off sequencing delay register.
+  UINT32  CycleDelay_RefDivReg;   ///< MMIO offset of Panel power cycle delay and reference divider register.
+  UINT32  CycleDelay_RefDivVal;   ///< Value of Panel power cycle delay and reference divider register.
+  UINT16  Terminate;              ///< Special value 0xFFFF indicating end of data.
+} FP_DATA;
+
+/**
+  This defines the structure consisting of all details for a single Local Flat panel.
+**/
+typedef struct {
+  FP_DATA       FP_Data;      ///< Instance of ::FP_DATA structure.
+  DTD_STRUCTURE DTD_Data;     ///< Instance of ::DTD_STRUCTURE which contains the DTD timings for the panel.
+  PID_DATA      PID_Data;     ///< Instance of ::PID_DATA structure which contains panel related information used by driver.
+} LVDS_FP_TABLE;
+
+/**
+  This structure defines all the details regarding Backlight control for LFP.
+**/
+typedef struct {
+  /**
+  Defines the backlight features for the panel.
+  Bits 7:6  = GMBus Speed:
+            = 00, 100 KHz
+            = 01, 50 KHz
+            = 10, 400 KHz
+            = 11, 1 MHz
+  Bits 5:3  = Inverter GPIO Pins
+            = 0, None
+            = 1, I2C GPIO pins
+            = 2, Analog CRT DDC pins
+            = 3, DVI/LVDS DDC GPIO pins
+            = 5, sDVO I2C GPIO pins
+  Bit 2     = Inverter Polarity (i2c & PWM)
+            = 0, Normal (0 = Minimum brightness)
+            = 1, Inverted (0 = Maximum brightness)
+  Bits 1:0  = BLC Inverter Type
+            = 00, None/External
+            = 01, i2c
+            = 10, PWM
+            = 11, Reserved
+  **/
+  UINT8   BLC_Ftr;
+
+  UINT16  PWM_Freq;       ///< PWM inverter frequency in KHz
+  UINT8   Min_Brightness; ///< Minimum brightness in the range 0-255
+  UINT8   I2C_Add;        ///< I2C Inverter Slave Address
+  UINT8   I2C_Command;    ///< I2C Inverter command code
+} BLC;
+
+/**
+  This defines the structure of Block 40 (LFP Features)
+**/
+typedef struct {
+  UINT8   BlockId;          ///< Defines the unique Block ID : 40
+  UINT16  BlockSize;        ///< Defines the size of LFP Features block.
+
+  UINT8   bmp_Panel_type;   ///< Defines the panel type of LFP.
+  UINT8   Skip1;            ///< Obsoleted.
+
+  /**
+  Capabilities byte:
+  Bit 15:7  = SW Workaround bits
+  Bit 6     = Panel EDID support
+            = 0, Disable
+            = 1, Enable
+  Bit 5     = Pixel dithering
+            = 0, Disable
+            = 1, Enable
+  Bit 4     = Panel Fitting ratio calc.
+            = 0 - Manual
+            = 1 - Automatic
+  Bit 3     = Panel Fitting Graphics mode
+            = 0, Bilinear
+            = 1, Enhanced
+  Bit 2     = Panel Fitting Text mode
+            = 0, Bilinear
+            = 1, Enhanced
+  Bit 1:0   = Panel Fitting Support
+            = 00, No panel fitting
+            = 01, Text panel fitting
+            = 10, GFX panel fitting
+            = 11, Text+GFX panel fitting
+  **/
+  UINT16  bmp_LVDS_Capabilities;
+
+  /**
+  Defines the channel type of LFP. 2 Bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Automatic (algorithm)
+    = 01, Single Channel
+    = 10, Dual Channel
+    = 11, Reserved
+  **/
+  UINT32  INT_LVDS_Panel_Channel_Bits;
+
+  UINT16  Enable_SSC_Bit;         ///< LVDS Spread Spectrum Clock
+  UINT16  SSC_Freq_Bit;           ///< LVDS Spread Spectrum Clock Frequency
+  UINT16  Disable_SSC_DDT_Bit;    ///< Disable SSC in Dual Display Twin
+
+  /**
+  Defines the panel color depth. 1 Bits for each Panel.
+  Bits[0] for Panel #01
+    = 0, 18bpp
+    = 1, 24bpp
+  **/
+  UINT16  INT_Panel_Color_Depth;
+
+  /**
+  Defines the Panel type. 2 Bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Static DRRS
+    = 01, D2PO
+    = 10, Seamless
+    = 11, Reserved
+  **/
+  UINT32  DPS_Panel_Type_Bits;
+
+  /**
+  Defines the type of backlight control for the LFP. 2 bits for each Panel.
+  Bits [0:1] for Panel #1
+    = 00, Default
+    = 01, CCFL backlight
+    = 10, LED backlight
+    = 11, Reserved
+  **/
+  UINT32  BLT_Control_Type_Bits;
+  /**
+  Defines the LFP power enable flag in S0 state for all 16 panels. 1 Bit for Each Panel.
+  Bits[0] : Panel #1
+        0 : Do not keep LCDVCC on during S0 state.
+        1 : Keep LCDVCC on during S0 state.
+  Bits 1 to 15 are for panel # 2 to 16.
+  **/
+  UINT16     LcdvccOnDuringS0State;
+} BLOCK40_LVDS_FEATURES;
+
+/**
+  This structure defines the second type of BMP table pointers.
+  This is used to store pointers to LFP Flat panel data, DTD and PID information.
+**/
+typedef struct {
+  UINT16  Offset;       ///< Offset of the table.
+  UINT8   Size;         ///< Size of the table.
+} BMP_TABLE_TYPE2_PTR;
+
+/**
+  This structure defines a set of 3 pointers for LFP display.
+  These pointers point to FP data, DTD and PID information respectively.
+**/
+typedef struct {
+  BMP_TABLE_TYPE2_PTR   FpTablePtr;   ///< Pointer to FP Data of the LFP panel.
+  BMP_TABLE_TYPE2_PTR   DtdTablePtr;  ///< Pointer to DTD of the LFP panel.
+  BMP_TABLE_TYPE2_PTR   PidTablePtr;  ///< Pointer to the PID data of the LFP panel.
+} LFP_TABLE_POINTERS;
+
+/**
+  This defines the structure of Block 41 (LFP Table Pointers for FPDATA, DTD and PID)
+**/
+typedef struct {
+  UINT8               BlockId;                  ///< Defines the unique Block ID:41
+  UINT16              BlockSize;                ///< Defines the size of LFP Table Pointer Block.
+  UINT8               NumOfEntries;             ///< Defines the number of entries in the Table.
+  LFP_TABLE_POINTERS  LfpTablePointers[16];     ///< Array of ::LFP_TABLE_POINTERS for all 16 panels.
+  UINT16              LfpPanelNameTableOffset;  ///< Offset of LFP panel names table.
+  UINT8               LfpPanelNameLength;       ///< Length of a single LFP panel's name.
+} BLOCK41_LFP_TABLE_POINTERS;
+
+/**
+  This defines the structure of Block 42 (Complete LFP Panel Information)
+**/
+typedef struct {
+  UINT8         BlockId;                ///< Defines the unique block ID : 42
+  UINT16        BlockSize;              ///< Defines the size of Complete LFP panel information for all 16 panels.
+  LVDS_FP_TABLE LVDS_FP_Table[16];      ///< Array of ::LVDS_FP_TABLE containing data of 16 panels.
+  UINT8         LFP_PANEL_NAMES[16][13];///< Array defining the panel names for all 16 panels.
+
+  /**
+  1 Bit for Each Panel
+  Bit0  = Scaling feature for panel 1.
+        = 0, Scaling feature is disabled for this panel.
+        = 1, Scaling feature is enabled for this panel.
+  **/
+  UINT16        EnableScaling; //This is not used currently
+
+  /**
+    Array defining DRRS minimum refresh rate. 1 Byte for Each Panel.
+  **/
+  UINT8         Seamless_DRRS_Min_RR[16];
+
+  /**
+    Array defining Pixel Overlap Count. 1 Byte for Each Panel.
+  **/
+  UINT8         PixelOverlapCount[16];
+} BLOCK42_LVDS_PANEL_INFO;
+
+typedef union {
+  /**
+  Backlight control parameters.\n
+  Bits 7:4  : PWM Controller Selection
+          0 : Controller 0
+          1 : Controller 1
+          2 : Controller 2
+          3 : Controller 3
+     Others : Reserved.
+  Bits 3:0  : PWM Source Selection
+          0 : PMIC PWM
+          1 : LPSS PWM
+          2 : DISPLAY PWM
+          3 : CABC PWM
+     Others : Reserved.
+  **/
+  UINT8 Value;
+  struct {
+    UINT8 PwmSourceSelection:4;
+    UINT8 PwmControllerSelection:4;
+  } Bits;
+} BKLT_CTRL_PARAMS;
+
+/**
+  This defines the structure of Block 43 (LFP Brightness Control)
+**/
+typedef struct {
+  UINT8             BlockId;                ///< Defines the unique Block ID : 43
+  UINT16            BlockSize;              ///< Defines the size of Brightness control block.
+
+  UINT8             SIZE_BLCStruc;          ///< Defines the size of single entry in Backlight control table for LFP.
+  BLC               BLC_Struct[16];         ///< Array defining the backlight control for 16 LFP panels.
+  UINT8             Post_Brightness[16];    ///< Array defining the initial brightness for all 16 panels.
+  BKLT_CTRL_PARAMS  Brightness_Control[16]; ///< Array defining the brightness control method for all 16 panels
+} BLOCK43_LVDS_BLC;
+
+/**
+  This defines the structure of Block 44 (LFP Power Conservation Features)
+**/
+typedef struct {
+  UINT8   BlockId;        ///< Defines the unique block ID : 44
+  UINT16  BlockSize;      ///< Defines the size of LFP Power Conservation Features block.
+  union {
+  /**
+  Bit[7]        : ALS Enable/Disable
+               0 - Disable
+               1 - Enable
+  Bit[6]        : Display LACE support
+               0 - Not supported
+               1 - Supported
+  Bit[5]        : Default Display LACE enabled status
+               0 - Disabled
+               1 - Enabled
+  Bit[4]        : Reserved
+  Bit[3:1]      : Power conservation preference level.
+                 4 is default in a range of 1 to 6.
+  Bit[0]        : Reserved
+  **/
+    UINT8  Value;
+    struct {
+      UINT8 Reserved:1;
+      UINT8 PwrConservation:3;
+      UINT8 Reserved_1:1;
+      UINT8 DefalutDisplayLaceEnable:1;
+      UINT8 DisplayLaceSupport:1;
+      UINT8 AlsEnable:1;
+    } Bits;
+  } LfpFeatureBits;
+
+  UINT16  AlsData[10];    ///< Defines the main ALS data.
+
+  union {
+  /**
+  Bit[7:3]      : Reserved
+  Bit[2:0]      : Aggressiveness Level Profile.
+            000 - Minimum
+            001 - Moderate
+            010 - High
+  **/
+    UINT8  Value;
+    struct {
+      UINT8 AggressionProfileLevel:3;
+      UINT8 Reserved:5;
+    } Bits;
+  } LaceAggressivenessProfile; ///< Defines the LACE Aggressiveness Profile
+} BLOCK44_ALS;
+
+/**
+  This defines the structure of Black Frame Insertion table entry.
+**/
+typedef struct {
+  /**
+  BFI Features\n
+  Bit[7-2]  : Reserved\n
+  Bit[1]    : Enable Brightness control in CUI\n
+  Bit[0]    : Enable BFI in driver
+  **/
+  UINT8         EnableBits;
+  UINT8         BrightnessNonBFI;   ///< Brightness percentage in non BFI mode
+} BFI;
+
+/**
+  This defines the structure of Block 45 (Black Frame insertion Support for LFP)
+**/
+typedef struct {
+  UINT8              BlockId;         ///< Defines the unique Block ID : 45
+  UINT16             BlockSize;       ///< Defines the size of Black frame insertion support block.
+  UINT8              SIZE_BFIStruc;   ///< Defines the size of 1 entry of black frame data.
+  BFI                BFI_Struct[16];  ///< Array defining the data of black frame insertion for all 16 panels.
+} BLOCK45_BFI_SUPPORT;
+
+/**
+  This structure defines the chromaticity information for a single LFP panel.
+**/
+typedef struct {
+  /**
+  Defines the chromaticity feature enable bits
+  Bits 7:2  = Reserved
+  Bit 1     = Override EDID values for chromaticity if enabled, Instead Use VBT values
+            = 0, Disable, Use the EDID values
+            = 1, Enable, Use the values from the VBT
+  Bit 0     = Enable chromaticity feature. EDID values will be used when this feature is enabled.
+            = 0, Disable
+            = 1, Enable
+  **/
+  UINT8        EnableBits;
+
+  UINT8        Red_Green_1;   ///< Red/green chormaticity coordinates at EDID offset 19h
+  UINT8        Blue_White_1;  ///< Blue/white chromatiity coordinates at EDID offset 1Ah
+  UINT8        Red_X1;        ///< Red x coordinate at EDID offset 1Bh
+  UINT8        Red_Y1;        ///< Red x coordinate at EDID offset 1Ch
+  UINT8        Green_X1;      ///< Green x coordinate at EDID offset 1Dh
+  UINT8        Green_Y1;      ///< Green x coordinate at EDID offset 1Eh
+  UINT8        Blue_X1;       ///< Blue x coordinate at EDID offset 1Fh
+  UINT8        Blue_Y1;       ///< Blue x coordinate at EDID offset 20h
+  UINT8        White_X1;      ///< White x coordinate at EDID offset 21h
+  UINT8        White_Y1;      ///< White x coordinate at EDID offset 22h
+} CHROMATICITY;
+
+/**
+  This structure defines the Luminance information for a single LFP panel.
+**/
+typedef struct {
+  /**
+  Defines the chromaticity feature enable bits
+  Bits 7:2  : Reserved
+  Bit 1     : Enable Gamma feature.
+            : if enabled, use gamma values from this block.
+          0 : Disable
+          1 : Enable
+  Bit 0     : Enable Luminance feature.
+            : if enabled, use values from this block.
+          0 : Disable
+          1 : Enable
+  **/
+  UINT8        EnableBits;
+  /**
+    Luminance info (refer DisplayID 2.0)
+    2 byte value, encoded in IEEE 754 half-precision binary floating point format
+  **/
+  UINT16      MinLuminance;           ///< Native minimum luminance
+  UINT16      MaxFullFrameLuminance;  ///< Native maximum luminance (Full Frame)
+  UINT16      MaxLuminance;           ///< Native Maximum Luminance (1% Rectangular Coverage)
+  /**
+    Gamma EOTF
+    Gamma values range from 00h through FFh which will come from VBT.
+    Value shall define the gamma range, from 1.00 to 3.54.
+    Field Value = (Gamma (value from VBT) + 100) / 100
+
+    FFh = No gamma information shall be provided
+  **/
+  UINT8 Gamma;
+
+}LUMINANCE_AND_GAMMA;
+
+/**
+  This defines the structure of Block 46 (Chromaticity Support)
+**/
+typedef struct {
+  UINT8              BlockId;                 ///< Defines the unique Block ID : 46
+  UINT16             BlockSize;               ///< Defines the size of Chromaticity Block.
+  CHROMATICITY       Chromaticity_Struct[16]; ///< Defines the chromaticity information for all 16 panels.
+  LUMINANCE_AND_GAMMA  Luminance_Gamma_Struct[16];    ///< Defines the lumianance information for all 16 panels.
+} BLOCK46_CHROMATICITY_SUPPORT;
+
+/**
+  This defines the structure of Block 51 (Fixed Mode Set)
+**/
+typedef struct{
+  UINT8       BlockId;        ///< Defines the unique block ID : 51.
+  UINT16      BlockSize;      ///< Defines the size of Fixed mode set feature block.
+  UINT8       FeatureEnable;  ///< Whether the fixed mode set feature is enabled/disabled.
+  UINT32      XRes;           ///< X resolution of the fixed mode.
+  UINT32      YRes;           ///< Y resolution of the fixed mode.
+} BLOCK51_FIXED_MODE_SET;
+
+/**
+  This defines the Complete VBT Structure for generation purpose
+**/
+typedef struct {
+  VBT_HEADER                                VbtHeader;
+  VBT_BIOS_DATA_HEADER                      VbtBdbHeader;
+  BLOCK254_BMP_Structure                    Block254BMPStructure;
+  VBT_GENERAL1_INFO                         VbtGen1Info;
+  PRD_BOOT_TABLE                            PrdBootTable;
+  VBT_GENERAL2_INFO                         VbtGen2Info;
+  BLOCK03_ORIGINAL_DISPLAY_TOGGLE_LIST      Block03OriginalDisplayToggleList;
+  BLOCK252_SBIOS_Hook                       Block252SbiosHook;
+  BLOCK06_MMIO_REG_TABLE                    Block06MmioRegTable;
+  BLOCK07_IOSWFLAG_REG_TABLE                Block07IoswflagRegTable;
+  BLOCK08_MMIOSWFLAG_REG_TABLE              Block08MmioswflagRegTable;
+  BLOCK09_PSR_FEATURE                       Block09PsrFeature;
+  BLOCK10_MODE_REMOVAL_TABLE                Block10ModeRemovalTable;
+  BLOCK12_DRIVER_FEATURES                   Block12DriverFeatures;
+  BLOCK13_DRIVER_PERSISTENCE                Block13DriverPersistence;
+  BLOCK17_SV_BITS                           Block17SvBits;
+  BLOCK18_DRIVER_ROTATION                   Block18DriverRotation;
+  BLOCK20_OEM_CUSTOMIZATION                 Block20OemCustomization;
+  BLOCK26_TV_OPTIONS                        Block26TVOptions;
+  BLOCK27_EDP_FEATURES                      Block27EDPFeatures;
+  BLOCK28_EDIDLESS_EFP                      Block28EdidlessEFP;
+  BLOCK31_TOGGLE_LIST                       Block31ToggleList;
+  BLOCK32_DISPLAY_CONFIGURATION_REMOVAL     Block32DisplayConfigurationRemoval;
+  BLOCK40_LVDS_FEATURES                     Block40LVDSFeatures;
+  BLOCK41_LFP_TABLE_POINTERS                Block41LfpTablePointers;
+  BLOCK42_LVDS_PANEL_INFO                   Block42LvdsPanelInfo;
+  BLOCK43_LVDS_BLC                          Block43LVDSBlc;
+  BLOCK44_ALS                               Block44Als;
+  BLOCK46_CHROMATICITY_SUPPORT              Block46ChromaticitySupport;
+  BLOCK51_FIXED_MODE_SET                    Block51FixedModeSet;
+} VBT_TABLE_DATA;
+
+#pragma pack()
+
+/**
+  This function will update the VBT checksum.
+
+  @param[in out] VbtPtr - Pointer to VBT table
+
+  @retval none
+**/
+VOID
+UpdateVbtChecksum(
+  VBT_TABLE_DATA *VbtPtr
+);
+
+/**
+  This function will update the VBT.
+
+  @param[in] VbtPtr - Pointer to VBT Table
+
+  @retval none
+**/
+VOID
+UpdateGopVbt (
+  IN  VBT_TABLE_DATA    *VbtPtr
+);
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
new file mode 100644
index 0000000000..5bf2527963
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __TCO_WDT_HOB_H__
+#define __TCO_WDT_HOB_H__
+
+#define TCO_WDT_HOB_GUID \
+  { \
+    0x3e405418, 0xd8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x8, 0x41, 0x46, 0x8d } \
+  }
+
+#ifndef _PEI_HOB_H_
+#ifndef __HOB__H__
+#ifndef __PI_HOB_H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+  EFI_HOB_GENERIC_HEADER  Header;
+  EFI_GUID                Name;
+  //
+  // Guid specific data goes here
+  //
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+#endif
+
+typedef struct {
+  EFI_HOB_GUID_TYPE Header;
+  UINT8             TcoRebootHappened;
+} TCO_WDT_HOB;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
new file mode 100644
index 0000000000..671e3c5cde
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
@@ -0,0 +1,68 @@
+/** @file
+  GPIO definition table for WhiskeylakeURvp
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IO_EXPANDER_H_
+#define _IO_EXPANDER_H_
+
+typedef struct {
+  UINT32 IoExpanderNumber   : 1;  // IO Expander Number (0/1)
+  UINT32 GpioPinNumber      : 5;  // GPIO Pin Number (0 to 23)
+  UINT32 GpioDirection      : 1;  // GPIO Pin Direction (Input/Output)
+  UINT32 GpioLevel          : 1;  // GPIO Pin Output Level (High/Low)
+  UINT32 GpioInversion     : 1;  // GPIO Pin Inversion (Enabled/Disabled)
+  UINT32 Reserved           : 23; // Reserved
+} IO_EXPANDER_GPIO_CONFIG;
+
+//WHL PCH LP GPIO Expander Number
+#define IO_EXPANDER_0            0
+#define IO_EXPANDER_1            1
+
+//WHL PCH LP GPIO Pin Mapping
+#define IO_EXPANDER_GPIO_0        0   // P00
+#define IO_EXPANDER_GPIO_1        1   // P01
+#define IO_EXPANDER_GPIO_2        2   // P02
+#define IO_EXPANDER_GPIO_3        3   // P03
+#define IO_EXPANDER_GPIO_4        4   // P04
+#define IO_EXPANDER_GPIO_5        5   // P05
+#define IO_EXPANDER_GPIO_6        6   // P06
+#define IO_EXPANDER_GPIO_7        7   // P07
+#define IO_EXPANDER_GPIO_8        8   // P10
+#define IO_EXPANDER_GPIO_9        9   // P11
+#define IO_EXPANDER_GPIO_10       10  // P12
+#define IO_EXPANDER_GPIO_11       11  // P13
+#define IO_EXPANDER_GPIO_12       12  // P14
+#define IO_EXPANDER_GPIO_13       13  // P15
+#define IO_EXPANDER_GPIO_14       14  // P16
+#define IO_EXPANDER_GPIO_15       15  // P17
+#define IO_EXPANDER_GPIO_16       16  // P20
+#define IO_EXPANDER_GPIO_17       17  // P21
+#define IO_EXPANDER_GPIO_18       18  // P22
+#define IO_EXPANDER_GPIO_19       19  // P23
+#define IO_EXPANDER_GPIO_20       20  // P24
+#define IO_EXPANDER_GPIO_21       21  // P25
+#define IO_EXPANDER_GPIO_22       22  // P26
+#define IO_EXPANDER_GPIO_23       23  // P27
+
+//WHL PCH LP GPIO Expander GPIO Direction
+#define IO_EXPANDER_GPIO_OUTPUT   0
+#define IO_EXPANDER_GPIO_INPUT    1
+
+//WHL PCH LP GPIO Expaner GPIO Output Level
+#define IO_EXPANDER_GPO_LEVEL_LOW    0
+#define IO_EXPANDER_GPO_LEVEL_HIGH   1
+
+//WHL PCH LP GPIO Expaner GPIO Inversion Status
+#define IO_EXPANDER_GPI_INV_DISABLED  0
+#define IO_EXPANDER_GPI_INV_ENABLED   1
+#define IO_EXPANDER_GPIO_RESERVED     0x00
+
+//GPIO Table Terminator
+#define END_OF_GPIO_TABLE 0xFFFFFFFF
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
new file mode 100644
index 0000000000..5d5fba47ad
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
@@ -0,0 +1,75 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_CPU_POLICY_UPDATE_LIB_H_
+#define _DXE_CPU_POLICY_UPDATE_LIB_H_
+
+#include <PiDxe.h>
+#include <PchAccess.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CpuPolicyProtocol.h>
+
+/**
+
+  This function prints the CPU DXE phase policy.
+
+  @param[in] DxeCpuPolicy - CPU DXE Policy protocol
+
+**/
+VOID
+CpuDxePrintPolicyProtocol (
+  IN  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  );
+
+/**
+
+Routine Description:
+
+  This function updates Dxe Cpu Policy Protocol
+
+Arguments:
+
+  @param[in] DxeCpuPolicy                 The Cpu Policy protocol instance
+
+Returns:
+
+  @retval EFI_SUCCESS                     Initialization complete.
+  @retval 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
+UpdateDxeSiCpuPolicy (
+  IN OUT  DXE_CPU_POLICY_PROTOCOL  *DxeCpuPolicy
+  );
+
+/**
+
+  CpuInstallPolicyProtocol installs CPU 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] DxeCpuPolicy               The pointer to CPU Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  DXE_CPU_POLICY_PROTOCOL     *DxeCpuPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
new file mode 100644
index 0000000000..9b960159ba
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
@@ -0,0 +1,27 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_ME_POLICY_UPDATE_LIB_H_
+#define _DXE_ME_POLICY_UPDATE_LIB_H_
+
+/**
+  Update the ME Policy Library
+
+  @param[in] DxeMePolicy                The pointer to get ME Policy protocol instance
+
+  @retval EFI_SUCCESS                   Initialization complete.
+  @retval 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
+UpdateDxeMePolicy (
+  IN OUT  ME_POLICY_PROTOCOL      *DxeMePolicy
+  );
+
+#endif // _DXE_ME_POLICY_UPDATE_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
new file mode 100644
index 0000000000..84db68e65c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_PCH_POLICY_UPDATE_LIB_H_
+#define _DXE_PCH_POLICY_UPDATE_LIB_H_
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] PchPolicy               The pointer to get PCH Policy protocol instance
+
+  @retval EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxePchPolicy (
+  IN OUT  PCH_POLICY_PROTOCOL    *PchPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
new file mode 100644
index 0000000000..3bb941235c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
@@ -0,0 +1,30 @@
+/** @file
+  Header file for the DxePolicyBoardConfig Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_POLICY_BOARD_CONFIG_LIB_H_
+#define _DXE_POLICY_BOARD_CONFIG_LIB_H_
+
+#include <Protocol/MePolicy.h>
+#include <Protocol/SaPolicy.h>
+
+/**
+  This function performs DXE SA Policy update by board configuration.
+
+  @param[in, out] DxeSaPolicy     DXE SA Policy
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicyBoardConfig (
+  IN OUT  SA_POLICY_PROTOCOL         *DxeSaPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
new file mode 100644
index 0000000000..4279c0c6f1
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
@@ -0,0 +1,25 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_SA_POLICY_UPDATE_LIB_H_
+#define _DXE_SA_POLICY_UPDATE_LIB_H_
+
+/**
+  Get data for platform policy from setup options.
+
+  @param[in] SaPolicy               The pointer to get SA Policy protocol instance
+
+  @retval EFI_SUCCESS               Operation success.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateDxeSaPolicy (
+  IN OUT  SA_POLICY_PROTOCOL    *SaPolicy
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
new file mode 100644
index 0000000000..4709179ac6
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
@@ -0,0 +1,29 @@
+/** @file
+  Function prototype of FspPolicyInitLib.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _FSP_POLICY_INIT_LIB_H_
+#define _FSP_POLICY_INIT_LIB_H_
+
+#include <FspEas.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+VOID
+EFIAPI
+FspPolicyInitPreMem (
+  IN FSPM_UPD           *FspmUpdDataPtr
+  );
+
+VOID
+EFIAPI
+FspPolicyInit (
+  IN OUT FSPS_UPD    *FspsUpd
+  );
+
+#endif // _FSP_POLICY_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
new file mode 100644
index 0000000000..ba73cad63b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
@@ -0,0 +1,46 @@
+/** @file
+  Header file for check Gpio PadMode conflict.
+
+
+  Copyright (c) 2019, 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 <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 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 UINT16                    GpioTableCount
+  );
+
+#endif // _GPIO_CHECK_CONFLICT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
new file mode 100644
index 0000000000..40ea4abc3d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GPIO_EXPANDER_LIB_H_
+#define _GPIO_EXPANDER_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <PchAccess.h>
+#include <Library/PchSerialIoLib.h>
+
+/**
+  Set the Direction value for the given Expander Gpio pin.
+
+  This function is to Set the direction value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+**/
+VOID
+GpioExpSetDirection (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Direction
+  );
+/**
+  Set the input value for the given Expander Gpio pin.
+
+  This function is to get the input value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetPolarity  (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Polarity
+  );
+/**
+  Set the Output value for the given Expander Gpio pin.
+
+  This function is to Set the Output value for the GPIO
+  Pin within the giving Expander.
+
+  @param[in]  Expander    Expander Value with in the Contoller
+  @param[in]  Pin         Pin with in the Expnader Value
+  @param[in]  Value       none
+
+**/
+VOID
+GpioExpSetOutput    (
+  IN UINT8 Expander,
+  IN UINT8 Pin,
+  IN UINT8 Value
+  );
+/**
+  Returns the data from register value giving in the input.
+
+  This function is to get the data from the Expander
+  Registers by following the I2C Protocol communication
+
+
+  @param[in]  Bar0       Bar address of the SerialIo Controller
+  @param[in]  Address    Expander Value with in the Contoller
+  @param[in]  Register   Address of Input/Output/Configure/Polarity
+                         registers with in the Expander
+
+  @retval     UINT8      Value returned from the register
+**/
+UINT8
+GpioExpGetInput     (
+  IN UINT8 Expander,
+  IN UINT8 Pin
+  );
+
+/**
+  Configures all registers of a single IO Expander in one go.
+
+  @param[in]  Expander    Expander number (0/1)
+  @param[in]  Direction   Bit-encoded direction values. BIT0 is for pin0, etc. 0=output, 1=input
+  @param[in]  Polarity    Bit-encoded input inversion values. BIT0 is for pin0, etc. 0=normal, 1=inversion
+  @param[in]  Output      Bit-encoded output state, ignores polarity, only applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
+
+**/
+VOID
+GpioExpBulkConfig (
+  IN UINT8  Expander,
+  IN UINT32 Direction,
+  IN UINT32 Polarity,
+  IN UINT32 Output
+  );
+
+/**
+  Returns the Controller on which GPIO expander is present.
+
+  This function returns the Controller value
+
+  @param[out] Controller              Pointer to a Controller value on
+                                      which I2C expander is configured.
+
+  @retval     EFI_SUCCESS              non.
+**/
+EFI_STATUS
+GpioExpGetController (
+  OUT UINT8 *Controller
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
new file mode 100644
index 0000000000..f08c88f114
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
@@ -0,0 +1,48 @@
+/** @file
+
+  Header file for the Intel HD Audio Verb Table library.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _HDA_VERB_TABLE_LIB_H_
+#define _HDA_VERB_TABLE_LIB_H_
+
+#include <ConfigBlock/HdAudioConfig.h>
+#include <Library/BaseLib.h>
+
+enum HDAUDIO_CODEC_SELECT {
+  PchHdaCodecPlatformOnboard = 0,
+  PchHdaCodecExternalKit     = 1
+};
+
+/**
+  Add verb table function.
+  This function update the verb table number and verb table ptr of policy.
+
+  @param[in]  HdAudioConfig            HD Audio config block
+  @param[out] VerbTableEntryNum        Number of verb table entries
+  @param[out] HdaVerbTablePtr          Pointer to the verb table
+**/
+VOID
+AddPlatformVerbTables (
+  IN   UINT8              CodecType,
+  OUT  UINT8              *VerbTableEntryNum,
+  OUT  UINT32             *HdaVerbTablePtr
+  );
+
+/**
+  HDA VerbTable init function for PEI post memory phase.
+
+  @param[in]  BoardId   An unsigned integrer represent the board id.
+
+  @retval EFI_SUCCESS   The function completed successfully.
+**/
+EFI_STATUS
+HdaVerbTableInit(
+  IN UINT16 BoardId
+  );
+
+#endif
\ No newline at end of file
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
new file mode 100644
index 0000000000..cec045091b
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Support for IO expander TCA6424.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _I2C_ACCESS_LIB_H_
+#define _I2C_ACCESS_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <PchAccess.h>
+#include <Library/PchSerialIoLib.h>
+
+#define WAIT_1_SECOND            1600000000 //1.6 * 10^9
+
+EFI_STATUS
+I2cWriteRead (
+  IN UINTN  MmioBase,
+  IN UINT8  SlaveAddress,
+  IN UINT8  WriteLength,
+  IN UINT8  *WriteBuffer,
+  IN UINT8  ReadLength,
+  IN UINT8  *ReadBuffer,
+  IN UINT64  TimeBudget
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
new file mode 100644
index 0000000000..d65586dbb9
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PLATFORM_LIB_H_
+#define _PEI_PLATFORM_LIB_H_
+
+
+
+#define PEI_DEVICE_DISABLED 0
+#define PEI_DEVICE_ENABLED  1
+
+typedef struct {
+  UINT8   Register;
+  UINT32  Value;
+} PCH_GPIO_DEV;
+
+//
+// GPIO Initialization Data Structure
+//
+typedef struct{
+  PCH_GPIO_DEV Use_Sel;
+  PCH_GPIO_DEV Use_Sel2;
+  PCH_GPIO_DEV Use_Sel3;
+  PCH_GPIO_DEV Io_Sel;
+  PCH_GPIO_DEV Io_Sel2;
+  PCH_GPIO_DEV Io_Sel3;
+  PCH_GPIO_DEV Lvl;
+  PCH_GPIO_DEV Lvl2;
+  PCH_GPIO_DEV Lvl3;
+  PCH_GPIO_DEV Inv;
+  PCH_GPIO_DEV Blink;
+  PCH_GPIO_DEV Rst_Sel;
+  PCH_GPIO_DEV Rst_Sel2;
+} GPIO_INIT_STRUCT;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
new file mode 100644
index 0000000000..fe947482dc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
@@ -0,0 +1,141 @@
+/** @file
+  Header file for the PeiPolicyBoardConfig Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_POLICY_BOARD_CONFIG_LIB_H_
+#define _PEI_POLICY_BOARD_CONFIG_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+
+/**
+  This function performs PEI CPU Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI ME Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI PCH Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI SA Pre-Memory Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI PreMem Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfigPreMem (
+  IN OUT   SI_PREMEM_POLICY_PPI      *SiPreMemPolicyPpi
+  );
+
+/**
+  This function performs PEI CPU Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiCpuPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI ME Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiMePolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI PCH Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiPchPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI SA Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSaPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+/**
+  This function performs PEI SI Policy update by board configuration.
+
+  @param[in, out] SiPolicy        The SI Policy PPI instance
+
+  @retval EFI_SUCCESS             The SI Policy is successfully updated.
+  @retval Others                  The SI Policy is not successfully updated.
+**/
+EFI_STATUS
+EFIAPI
+UpdatePeiSiPolicyBoardConfig (
+  IN OUT  SI_POLICY_PPI              *SiPolicyPpi
+  );
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
new file mode 100644
index 0000000000..15db1f1fbc
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
@@ -0,0 +1,38 @@
+/** @file
+  Header file for the PolicyInitPei Library.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _POLICY_INIT_PEI_LIB_H_
+#define _POLICY_INIT_PEI_LIB_H_
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in]  FirmwareConfiguration  It uses to skip specific policy init that depends
+                                     on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInitPreMem (
+  IN UINT8                     FirmwareConfiguration
+  );
+
+/**
+  Initialize Intel PEI Platform Policy
+
+  @param[in] PeiServices            General purpose services available to every PEIM.
+  @param[in] FirmwareConfiguration  It uses to skip specific policy init that depends
+                                    on the 'FirmwareConfiguration' varaible.
+**/
+VOID
+EFIAPI
+PeiPolicyInit (
+//  IN CONST EFI_PEI_SERVICES    **PeiServices,
+  IN UINT8                     FirmwareConfiguration
+  );
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
new file mode 100644
index 0000000000..f0da2db968
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Function prototype of PlatformInitLib.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_INIT_LIB_H_
+#define _PLATFORM_INIT_LIB_H_
+
+VOID
+PlatformLateInit (
+  VOID
+  );
+
+VOID
+InitSerialPort (
+  VOID
+  );
+
+#endif // _PLATFORM_INIT_LIB_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
new file mode 100644
index 0000000000..8bf7deaa0c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PCH_HSIO_PTSSTABLES_H_
+#define PCH_HSIO_PTSSTABLES_H_
+
+#include <PchAccess.h>
+
+///
+/// SATA PTSS Topology Types
+///
+typedef enum {
+  PchSataTopoUnknown = 0x00,
+  PchSataTopoIsata,
+  PchSataTopoDirectConnect,
+  PchSataTopoFlex,
+  PchSataTopoM2
+} PCH_SATA_TOPOLOGY;
+
+///
+/// PCIe PTSS Topology Types
+///
+typedef enum {
+  PchPcieTopoUnknown = 0x00,
+  PchPcieTopox1,
+  PchPcieTopox4,
+  PchPcieTopoSataE,
+  PchPcieTopoM2
+} PCH_PCIE_TOPOLOGY;
+
+///
+/// The PCH_SBI_PTSS_HSIO_TABLE block describes HSIO PTSS settings for PCH.
+///
+typedef struct {
+  UINT8       LaneNum;
+  UINT8       PhyMode;
+  UINT16      Offset;
+  UINT32      Value;
+  UINT32      BitMask;
+} PCH_SBI_PTSS_HSIO_TABLE;
+
+typedef struct {
+  PCH_SBI_PTSS_HSIO_TABLE   PtssTable;
+  UINT16                    Topology;
+} HSIO_PTSS_TABLES;
+
+#endif // PCH_HSIO_PTSSTABLES_H_
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
new file mode 100644
index 0000000000..395d08779c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
@@ -0,0 +1,106 @@
+/** @file
+  PCIe Device Override Table
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PCIE_DEVICE_OVERRIDE_TABLE_H_
+#define _PCIE_DEVICE_OVERRIDE_TABLE_H_
+
+#include <ConfigBlock/PcieRpconfig.h>
+#include <IndustryStandard/Pci22.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 },
+
+  //
+  // End of Table
+  //
+  { 0 }
+};
+
+#endif
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
new file mode 100644
index 0000000000..ea96227e3d
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
@@ -0,0 +1,33 @@
+/** @file
+  This header file provides platform specific definitions used
+  by other modules for platform specific initialization.
+  This is not suitable for consumption by ASL or VRF files.
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//#include "CommonDefinitions.h"
+#include "PchAccess.h"
+#include "SaAccess.h"
+
+//
+// Need minimum of 48MB during PEI phase for IAG and some buffer for boot.
+//
+#define  PEI_MIN_MEMORY_SIZE               (10 * 0x800000 + 0x10000000)   // 80MB + 256MB
+#define  PEI_RECOVERY_MIN_MEMORY_SIZE      (10 * 0x800000 + 0x10000000)   // 80MB + 256MB
+
+#define FLASH_BLOCK_SIZE  0x10000
+
+#define CPU_EXTERNAL_CLOCK_FREQ  0x64
+#define CPU_FREQUENCY_MODE_100  0x64
+#define FREQUENCY_RESOLUTION_3182  0xc6e
+#define NDIVIDER_BASE_VALUE  0x19d
+#define MDIVIDER_VALUE_13  0xd
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
new file mode 100644
index 0000000000..3545b2a05c
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
@@ -0,0 +1,29 @@
+/** @file
+Defines Platform BoardIds
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_BOARD_ID_H_
+#define _PLATFORM_BOARD_ID_H_
+
+#define FlavorUnknown                       0x0
+#define FlavorMobile                        0x1
+#define FlavorDesktop                       0x2
+#define FlavorWorkstation                   0x3
+#define FlavorUpServer                      0x4
+#define FlavorEmbedded                      0x5
+#define FlavorPlatformMax                   0x6
+
+#define TypeUnknown                         0x0
+#define TypeTrad                            0x1
+#define TypeUltUlx                          0x2
+
+#define BoardIdWhiskeyLakeRvp               0x60
+
+#define BoardIdUnknown1                     0xffff
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
new file mode 100644
index 0000000000..b64cfff9a2
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
@@ -0,0 +1,47 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _GLOBAL_NVS_AREA_H_
+#define _GLOBAL_NVS_AREA_H_
+
+//
+// Includes
+//
+#define GLOBAL_NVS_DEVICE_ENABLE 1
+#define GLOBAL_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+//
+// Global NVS Area Protocol GUID
+//
+#define EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID \
+{ 0x74e1e48, 0x8132, 0x47a1, 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc }
+
+#define GLOBAL_NVS_AREA_REVISION       16
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiGlobalNvsAreaProtocolGuid;
+
+//
+// Global NVS Area definition
+//
+#include <Acpi/GlobalNvsAreaDef.h>
+
+//
+// Global NVS Area Protocol
+//
+typedef struct _EFI_GLOBAL_NVS_AREA_PROTOCOL {
+  EFI_GLOBAL_NVS_AREA     *Area;
+} EFI_GLOBAL_NVS_AREA_PROTOCOL;
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
new file mode 100644
index 0000000000..6dd6795a52
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
@@ -0,0 +1,144 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SETUP__H__
+#define __SETUP__H__
+
+#ifndef MDEPKG_NDEBUG
+#define DEBUG_INTERFACE_FORM_ENABLE
+#endif // MDEPKG_NDEBUG
+//
+// Form class guid for the forms those will be showed on first front page.
+//
+#define FRONT_PAGE_GUID        { 0xe58809f8, 0xfbc1, 0x48e2, { 0x88, 0x3a, 0xa3, 0xf, 0xdc, 0x4b, 0x44, 0x1e } }
+//
+// Form class guid for the forms those will be showed on boot maintenance manager menu.
+//
+#define BOOT_MAINTENANCE_GUID  { 0xb2dedc91, 0xd59f, 0x48d2, { 0x89, 0x8a, 0x12, 0x49, 0xc, 0x74, 0xa4, 0xe0 } }
+
+// VFR common Definitions
+#define INVENTORY(Name,Value) \
+    text \
+      help  = STRING_TOKEN(STR_EMPTY), \
+      text  = Name, \
+      text  = Value, \
+      flags = 0, \
+      key   = 0;
+
+#define SUBTITLE(Text) subtitle text = Text;
+#define SEPARATOR SUBTITLE(STRING_TOKEN(STR_EMPTY))
+
+#define INTERACTIVE_TEXT(HelpToken, CaptionToken, ValueToken, Key)\
+  grayoutif TRUE;\
+    oneof varid        = SETUP_DATA.InteractiveText,\
+      questionid       = Key,\
+      prompt           = CaptionToken,\
+      help             = HelpToken,\
+      option text      = ValueToken, value = 0, flags = INTERACTIVE | DEFAULT;\
+      refresh interval = 1 \
+    endoneof;\
+  endif;
+
+#define SUPPRESS_GRAYOUT_ENDIF endif; endif;
+#define DEFAULT_FLAG
+
+#define SYSTEM_ACCESS_KEY_ID            0xF000
+//
+// System Access defintions.
+//
+#define SYSTEM_ACCESS_GUID \
+ { 0xE770BB69, 0xBCB4, 0x4D04, { 0x9E, 0x97, 0x23, 0xFF, 0x94, 0x56, 0xFE, 0xAC }}
+
+#define SYSTEM_PASSWORD_ADMIN 0
+#define SYSTEM_PASSWORD_USER  1
+#define ADMIN_PW_CLEAR        0
+#define ADMIN_PW_SET          1
+
+
+typedef struct _SYSTEM_ACCESS
+{
+  //
+  // Passwords
+  //
+  UINT8       Access;
+} SYSTEM_ACCESS;
+
+//
+// Record the password status.
+//
+typedef struct {
+  UINT8   AdminName;
+  UINT8   UserName;
+} EFI_PASSWORD_STATUS;
+
+//
+// Config Data
+//
+typedef struct {
+  UINT8 SerialDebug;
+  UINT8 SerialDebugBaudRate;
+  UINT8 RamDebugInterface;
+  UINT8 UartDebugInterface;
+  UINT8 Usb3DebugInterface;
+  UINT8 SerialIoDebugInterface;
+  UINT8 TraceHubDebugInterface;
+} DEBUG_CONFIG_DATA;
+
+//
+// Config Data Hob
+//
+#define DEBUG_CONFIG_DATA_HOB DEBUG_CONFIG_DATA
+
+//
+// Secure Boot Data
+//
+typedef struct{
+  UINT8   SecureBoot;
+} SECURE_BOOT_VARIABLE;
+
+#pragma pack()
+
+//
+// Varstore statement
+// Setup is EfiVarStore that is related to EFI variable with attribute 0x07
+// (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
+//
+#define SETUP_DATA_VARSTORE\
+    efivarstore SETUP_DATA, varid = 1,\
+        attribute = 0x7, name = Setup, guid = SETUP_GUID;
+#define SA_SETUP_VARSTORE\
+    efivarstore SA_SETUP, varid = 2,\
+        attribute = 0x7, name = SaSetup, guid = SA_SETUP_GUID;
+#define CPU_SETUP_VARSTORE\
+    efivarstore CPU_SETUP, varid = 3,\
+        attribute = 0x7, name = CpuSetup, guid = CPU_SETUP_GUID;
+#define ME_SETUP_VARSTORE\
+    efivarstore ME_SETUP, varid = 4,\
+        attribute = 0x7, name = MeSetup, guid = ME_SETUP_GUID;
+#define PCH_SETUP_VARSTORE\
+    efivarstore PCH_SETUP, varid = 5,\
+        attribute = 0x7, name = PchSetup, guid = PCH_SETUP_GUID;
+#define SI_SETUP_VARSTORE\
+    efivarstore SI_SETUP, varid = 6,\
+        attribute = 0x7, name = SiSetup, guid = SI_SETUP_GUID;
+#ifdef DEBUG_INTERFACE_FORM_ENABLE
+#define DEBUG_CONFIG_DATA_ID            0xF001
+#define DEBUG_CONFIG_DATA_VARSTORE\
+    efivarstore DEBUG_CONFIG_DATA, varid = DEBUG_CONFIG_DATA_ID,\
+        attribute = 0x7, name = DebugConfigData, guid = DEBUG_CONFIG_GUID;
+#endif // DEBUG_INTERFACE_FORM_ENABLE
+#define SYSTEM_ACCESS_VARSTORE\
+    varstore SYSTEM_ACCESS, varid = SYSTEM_ACCESS_KEY_ID,\
+        name = SystemAccess, guid = SYSTEM_ACCESS_GUID;
+#define SYSTEM_PASSWORD_VARSTORE\
+    varstore EFI_PASSWORD_STATUS,\
+        name = PasswordStatus, guid = SYSTEM_ACCESS_GUID;
+
+#define BOOT_FLOW_CONDITION_RECOVERY   2
+#define BOOT_FLOW_CONDITION_FIRST_BOOT 4
+
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
new file mode 100644
index 0000000000..4ce85de5bd
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
@@ -0,0 +1,157 @@
+/** @file
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_REG_H_
+#define _SIO_REG_H_
+
+#define REG_LOGICAL_DEVICE        0x07
+#define ACTIVATE                  0x30
+
+#define BASE_ADDRESS_HIGH0        0x60
+#define BASE_ADDRESS_LOW0         0x61
+#define BASE_ADDRESS_HIGH1        0x62
+#define BASE_ADDRESS_LOW1         0x63
+#define BASE_ADDRESS_HIGH2        0x64
+#define BASE_ADDRESS_LOW2         0x65
+#define BASE_ADDRESS_HIGH3        0x66
+#define BASE_ADDRESS_LOW3         0x67
+#define PRIMARY_INTERRUPT_SELECT  0x70
+#define WAKEUP_ON_IRQ_EN          0x70
+#define INTERRUPT_TYPE            0x71
+#define DMA_CHANNEL_SELECT0       0x74
+#define DMA_CHANNEL_SELECT1       0x75
+
+
+
+//
+//Port address for PILOT - III
+//
+#define PILOTIII_CHIP_ID         0x03
+#define PILOTIII_SIO_INDEX_PORT  0x04E
+#define PILOTIII_SIO_DATA_PORT   (PILOTIII_SIO_INDEX_PORT+1)
+
+#define PILOTIII_UNLOCK      0x5A
+#define PILOTIII_LOCK        0xA5
+
+//
+// logical device in PILOT-III
+//
+#define PILOTIII_SIO_PSR     0x00
+#define PILOTIII_SIO_COM2    0x01
+#define PILOTIII_SIO_COM1    0x02
+#define PILOTIII_SIO_SWCP    0x03
+#define PILOTIII_SIO_GPIO    0x04
+#define PILOTIII_SIO_WDT     0x05
+#define PILOTIII_SIO_KCS3    0x08
+#define PILOTIII_SIO_KCS4    0x09
+#define PILOTIII_SIO_KCS5    0x0A
+#define PILOTIII_SIO_BT      0x0B
+#define PILOTIII_SIO_SMIC    0x0C
+#define PILOTIII_SIO_MAILBOX 0x0D
+#define PILOTIII_SIO_RTC     0x0E
+#define PILOTIII_SIO_SPI     0x0F
+#define PILOTIII_SIO_TAP     0x10
+//
+// Regisgers for Pilot-III
+//
+#define PILOTIII_CHIP_ID_REG               0x20
+#define PILOTIII_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
+#define PILOTIII_ACTIVATE                  ACTIVATE
+#define PILOTIII_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
+#define PILOTIII_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
+#define PILOTIII_BASE_ADDRESS_HIGH1        BASE_ADDRESS_HIGH1
+#define PILOTIII_BASE_ADDRESS_LOW1         BASE_ADDRESS_LOW1
+#define PILOTIII_PRIMARY_INTERRUPT_SELECT  PRIMARY_INTERRUPT_SELECT
+
+//
+// Port address for PC8374
+//
+#define PC8374_SIO_INDEX_PORT  0x02E
+#define PC8374_SIO_DATA_PORT   (PC8374_SIO_INDEX_PORT+1)
+
+//
+// Logical device in PC8374
+//
+#define PC8374_SIO_FLOPPY  0x00
+#define PC8374_SIO_PARA    0x01
+#define PC8374_SIO_COM2    0x02
+#define PC8374_SIO_COM1    0x03
+#define PC8374_SIO_MOUSE   0x05
+#define PC8374_SIO_KYBD    0x06
+#define PC8374_SIO_GPIO    0x07
+
+//
+// Registers specific for PC8374
+//
+#define PC8374_CLOCK_SELECT  0x2D
+#define PC8374_CLOCK_CONFIG  0x29
+
+//
+// Registers for PC8374
+//
+#define PC8374_LOGICAL_DEVICE            REG_LOGICAL_DEVICE
+#define PC8374_ACTIVATE                  ACTIVATE
+#define PC8374_BASE_ADDRESS_HIGH0        BASE_ADDRESS_HIGH0
+#define PC8374_BASE_ADDRESS_LOW0         BASE_ADDRESS_LOW0
+#define PC8374_PRIMARY_INTERRUPT_SELECT  PRIMARY_INTERRUPT_SELECT
+#define PC8374_DMA_CHANNEL_SELECT        DMA_CHANNEL_SELECT0
+
+#define PC87427_SERVERIO_CNF2           0x22
+
+
+//
+// Pilot III Mailbox Data Register definitions
+//
+#define MBDAT00_OFFSET                  0x00
+#define MBDAT01_OFFSET                  0x01
+#define MBDAT02_OFFSET                  0x02
+#define MBDAT03_OFFSET                  0x03
+#define MBDAT04_OFFSET                  0x04
+#define MBDAT05_OFFSET                  0x05
+#define MBDAT06_OFFSET                  0x06
+#define MBDAT07_OFFSET                  0x07
+#define MBDAT08_OFFSET                  0x08
+#define MBDAT09_OFFSET                  0x09
+#define MBDAT10_OFFSET                  0x0A
+#define MBDAT11_OFFSET                  0x0B
+#define MBDAT12_OFFSET                  0x0C
+#define MBDAT13_OFFSET                  0x0D
+#define MBDAT14_OFFSET                  0x0E
+#define MBDAT15_OFFSET                  0x0F
+#define MBST0_OFFSET                    0x10
+#define MBST1_OFFSET                    0x11
+#define MBBINT_OFFSET                   0x12
+
+//
+// Mailbox Bit definitions...
+//
+#define   MBBINT_MBBIST_BIT               0x80
+// If both are there, use the default one
+//
+#define  W83527_EXIST     BIT2
+#define  PC8374_EXIST     BIT1
+#define  PILOTIII_EXIST   BIT0
+#define  DEFAULT_SIO      PILOTIII_EXIST
+#define  DEFAULT_KDB      PC8374_EXIST
+
+#define IPMI_DEFAULT_SMM_IO_BASE           0xca2
+//
+// For Pilot III
+//
+
+#define PILOTIII_SWC_BASE_ADDRESS          0xA00
+#define PILOTIII_PM1b_EVT_BLK_BASE_ADDRESS 0x0A80
+#define PILOTIII_PM1b_CNT_BLK_BASE_ADDRESS 0x0A84
+#define PILOTIII_GPE1_BLK_BASE_ADDRESS     0x0A86
+#define PILOTIII_KCS3_DATA_BASE_ADDRESS    0x0CA4
+#define PILOTIII_KCS3_CMD_BASE_ADDRESS     0x0CA5
+#define PILOTIII_KCS4_DATA_BASE_ADDRESS    0x0CA2
+#define PILOTIII_KCS4_CMD_BASE_ADDRESS     0x0CA3
+#define PILOTIII_MAILBOX_BASE_ADDRESS      0x0600
+#define PILOTIII_MAILBOX_MASK              0xFFE0
+#define BMC_KCS_BASE_ADDRESS               0x0CA0
+#endif
+
diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
new file mode 100644
index 0000000000..af753e1dce
--- /dev/null
+++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
@@ -0,0 +1,112 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  // Define a Global region of ACPI NVS Region that may be used for any
+  // type of implementation.  The starting offset and size will be fixed
+  // up by the System BIOS during POST.  Note that the Size must be a word
+  // in size to be fixed up correctly.
+
+  OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55)
+  Field(GNVS,AnyAcc,Lock,Preserve)
+  {
+  //
+  // Miscellaneous Dynamic Registers:
+  //
+  Offset(0),      OSYS, 16, // Offset(0),     Operating System
+  Offset(2),      SMIF, 8,  // Offset(2),     SMI Function Call (ASL to SMI via I/O Trap)
+  Offset(3),      P80D, 32, // Offset(3),     Port 80 Debug Port Value
+  Offset(7),      PWRS, 8,  // Offset(7),     Power State (AC Mode = 1)
+  //
+  // Thermal Policy Registers:
+  //
+  Offset(8),      DTSE, 8,  // Offset(8),    Digital Thermal Sensor Enable
+  Offset(9),      DTSF, 8,  // Offset(9),    DTS SMI Function Call
+  //
+  // CPU Identification Registers:
+  //
+  Offset(10),     APIC, 8,  // Offset(10),    APIC Enabled by SBIOS (APIC Enabled = 1)
+  Offset(11),     TCNT, 8,  // Offset(11),    Number of Enabled Threads
+  //
+  // PCIe Hot Plug
+  //
+  Offset(12),     OSCC, 8,  // Offset(12),    PCIE OSC Control
+  Offset(13),     NEXP, 8,  // Offset(13),    Native PCIE Setup Value
+  //
+  // Global Variables
+  //
+  Offset(14),     DSEN, 8,  // Offset(14),    _DOS Display Support Flag.
+  Offset(15),     GPIC, 8,  // Offset(15),    Global IOAPIC/8259 Interrupt Mode Flag.
+  Offset(16),     L01C, 8,  // Offset(16),    Global L01 Counter.
+  Offset(17),     LTR1, 8,  // Offset(17),    Latency Tolerance Reporting Enable
+  Offset(18),     LTR2, 8,  // Offset(18),    Latency Tolerance Reporting Enable
+  Offset(19),     LTR3, 8,  // Offset(19),    Latency Tolerance Reporting Enable
+  Offset(20),     LTR4, 8,  // Offset(20),    Latency Tolerance Reporting Enable
+  Offset(21),     LTR5, 8,  // Offset(21),    Latency Tolerance Reporting Enable
+  Offset(22),     LTR6, 8,  // Offset(22),    Latency Tolerance Reporting Enable
+  Offset(23),     LTR7, 8,  // Offset(23),    Latency Tolerance Reporting Enable
+  Offset(24),     LTR8, 8,  // Offset(24),    Latency Tolerance Reporting Enable
+  Offset(25),     LTR9, 8,  // Offset(25),    Latency Tolerance Reporting Enable
+  Offset(26),     LTRA, 8,  // Offset(26),    Latency Tolerance Reporting Enable
+  Offset(27),     LTRB, 8,  // Offset(27),    Latency Tolerance Reporting Enable
+  Offset(28),     LTRC, 8,  // Offset(28),    Latency Tolerance Reporting Enable
+  Offset(29),     LTRD, 8,  // Offset(29),    Latency Tolerance Reporting Enable
+  Offset(30),     LTRE, 8,  // Offset(30),    Latency Tolerance Reporting Enable
+  Offset(31),     LTRF, 8,  // Offset(31),    Latency Tolerance Reporting Enable
+  Offset(32),     LTRG, 8,  // Offset(32),    Latency Tolerance Reporting Enable
+  Offset(33),     LTRH, 8,  // Offset(33),    Latency Tolerance Reporting Enable
+  Offset(34),     LTRI, 8,  // Offset(34),    Latency Tolerance Reporting Enable
+  Offset(35),     LTRJ, 8,  // Offset(35),    Latency Tolerance Reporting Enable
+  Offset(36),     LTRK, 8,  // Offset(36),    Latency Tolerance Reporting Enable
+  Offset(37),     LTRL, 8,  // Offset(37),    Latency Tolerance Reporting Enable
+  Offset(38),     LTRM, 8,  // Offset(38),    Latency Tolerance Reporting Enable
+  Offset(39),     LTRN, 8,  // Offset(39),    Latency Tolerance Reporting Enable
+  Offset(40),     LTRO, 8,  // Offset(40),    Latency Tolerance Reporting Enable
+  Offset(41),     OBF1, 8,  // Offset(41),    Optimized Buffer Flush and Fill
+  Offset(42),     OBF2, 8,  // Offset(42),    Optimized Buffer Flush and Fill
+  Offset(43),     OBF3, 8,  // Offset(43),    Optimized Buffer Flush and Fill
+  Offset(44),     OBF4, 8,  // Offset(44),    Optimized Buffer Flush and Fill
+  Offset(45),     OBF5, 8,  // Offset(45),    Optimized Buffer Flush and Fill
+  Offset(46),     OBF6, 8,  // Offset(46),    Optimized Buffer Flush and Fill
+  Offset(47),     OBF7, 8,  // Offset(47),    Optimized Buffer Flush and Fill
+  Offset(48),     OBF8, 8,  // Offset(48),    Optimized Buffer Flush and Fill
+  Offset(49),     OBF9, 8,  // Offset(49),    Optimized Buffer Flush and Fill
+  Offset(50),     OBFA, 8,  // Offset(50),    Optimized Buffer Flush and Fill
+  Offset(51),     OBFB, 8,  // Offset(51),    Optimized Buffer Flush and Fill
+  Offset(52),     OBFC, 8,  // Offset(52),    Optimized Buffer Flush and Fill
+  Offset(53),     OBFD, 8,  // Offset(53),    Optimized Buffer Flush and Fill
+  Offset(54),     OBFE, 8,  // Offset(54),    Optimized Buffer Flush and Fill
+  Offset(55),     OBFF, 8,  // Offset(55),    Optimized Buffer Flush and Fill
+  Offset(56),     OBFG, 8,  // Offset(56),    Optimized Buffer Flush and Fill
+  Offset(57),     OBFH, 8,  // Offset(57),    Optimized Buffer Flush and Fill
+  Offset(58),     OBFI, 8,  // Offset(58),    Optimized Buffer Flush and Fill
+  Offset(59),     OBFJ, 8,  // Offset(59),    Optimized Buffer Flush and Fill
+  Offset(60),     OBFK, 8,  // Offset(60),    Optimized Buffer Flush and Fill
+  Offset(61),     OBFL, 8,  // Offset(61),    Optimized Buffer Flush and Fill
+  Offset(62),     OBFM, 8,  // Offset(62),    Optimized Buffer Flush and Fill
+  Offset(63),     OBFN, 8,  // Offset(63),    Optimized Buffer Flush and Fill
+  Offset(64),     OBFO, 8,  // Offset(64),    Optimized Buffer Flush and Fill
+  Offset(65),     RTD3, 8,  // Offset(65),    Runtime D3 support.
+  Offset(66),     S0ID, 8,  // Offset(66),    Low Power S0 Idle Enable
+  Offset(67),     GBSX, 8,  // Offset(67),    Virtual GPIO button Notify Sleep State Change
+  Offset(68),     PSCP, 8,  // Offset(68),    P-state Capping
+  Offset(69),     P2ME, 8,  // Offset(69),    Ps2 Mouse Enable
+  Offset(70),     P2MK, 8,  // Offset(70),    Ps2 Keyboard and Mouse Enable
+  //
+  // Driver Mode
+  //
+  Offset(71),     GIRQ, 32, // Offset(71),    GPIO IRQ
+  Offset(75),     PLCS, 8,  // Offset(75),    set PL1 limit when entering CS
+  Offset(76),     PLVL, 16, // Offset(76),    PL1 limit value
+  Offset(78),     PB1E, 8,  // Offset(78),    10sec Power button support
+  Offset(79),     ECR1, 8,  // Offset(79),    Pci Delay Optimization Ecr
+  Offset(80),     TBTS, 8,  // Offset(80),    Thunderbolt(TM) support
+  Offset(81),     TNAT, 8,  // Offset(81),    TbtNativeOsHotPlug
+  Offset(82),     TBSE, 8,  // Offset(82),    Thunderbolt(TM) Root port selector
+  Offset(83),     TBS1, 8,  // Offset(83),    Thunderbolt(TM) Root port selector
+  }
+
-- 
2.16.2.windows.1


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

* Re: [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support
  2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
                   ` (36 preceding siblings ...)
  2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
@ 2019-08-19 18:14 ` Sinha, Ankit
  37 siblings, 0 replies; 121+ messages in thread
From: Sinha, Ankit @ 2019-08-19 18:14 UTC (permalink / raw)
  To: Kubacki, Michael A, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Desimone, Nathaniel L,
	Gao, Liming, Kinney, Michael D

Reviewed-by: Ankit Sinha <ankit.sinha@intel.com>

-----Original Message-----
From: Kubacki, Michael A 
Sent: Friday, August 16, 2019 5:15 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support

This patch series adds support for Intel Coffee Lake and Intel Whiskey Lake
products.

The following are a comprehensive set of packages to build a functional firmware.
Currently source code is only provided for the Intel Whiskey Lake U Reference
Validation Platform (RVP). This code is intended to provide sample code that will
enable additional board ports.

 - EDK II core
   - Package(s): Various
   - Repository: https://github.com/tianocore/edk2
 - Intel FSP:
   - Package(s): CoffeeLakeFspBinPkg
   - Repository: https://github.com/IntelFsp/FSP
 - Silicon binaries:
   - Package(s): Silicon/Intel/CoffeeLakeFspBinPkg
   - Repository: https://github.com/tianocore/edk2-non-osi
 - Silicon source:
   - Package(s): Silicon/Intel/CoffeelakeSiliconPkg
   - Repository: https://github.com/tianocore/edk2-platforms
 - Board source:
   - Package(s): Platform/Intel/WhiskeylakeOpenBoardPkg
   - Repository: https://github.com/tianocore/edk2-platforms

For build instructions and a brief background on EDK II Minimum Platform,
please reference:
https://github.com/tianocore/edk2-platforms/blob/master/Platform/Intel/Readme.md

For a more comprehensive explanation of EDK II Minimum Platform, please
reference the draft specification at:
https://edk2-docs.gitbooks.io/edk-ii-minimum-platform-specification/

Some TianoCore BZ cleanup bugs will be filed after the package is pushed.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>

Michael Kubacki (37):
  CoffeelakeSiliconPkg: Add package and Include headers
  CoffeelakeSiliconPkg/Cpu: Add Include headers
  CoffeelakeSiliconPkg/Me: Add Include headers
  CoffeelakeSiliconPkg/Pch: Add include headers
  CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers
  CoffeelakeSiliconPkg/Pch: Add Library include headers
  CoffeelakeSiliconPkg/Pch: Add PPI and Protocol include headers
  CoffeelakeSiliconPkg/Pch: Add Register include headers
  CoffeelakeSiliconPkg/Pch: Add Private include headers
  CoffeelakeSiliconPkg/Pch: Add Private/Library include headers
  CoffeelakeSiliconPkg/Pch: Add Private/Protocol include headers
  CoffeelakeSiliconPkg/SampleCode: Add Include headers
  CoffeelakeSiliconPkg/SystemAgent: Add Include headers
  CoffeelakeSiliconPkg: Add package common library instances
  CoffeelakeSiliconPkg/Cpu: Add library instances
  CoffeelakeSiliconPkg/Me: Add library instances
  CoffeelakeSiliconPkg/Pch: Add Base library instances
  CoffeelakeSiliconPkg/Pch: Add DXE library instances
  CoffeelakeSiliconPkg/Pch: Add PEI library instances
  CoffeelakeSiliconPkg/Pch: Add SMM library instances
  CoffeelakeSiliconPkg/Pch: Add Base library instances
  CoffeelakeSiliconPkg/Pch: Add DXE private library instances
  CoffeelakeSiliconPkg/Pch: Add PEI private library instances
  CoffeelakeSiliconPkg/Pch: Add SMM private library instances
  CoffeelakeSiliconPkg/SystemAgent: Add library instances
  CoffeelakeSiliconPkg/Pch: Add modules
  CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher
  CoffeelakeSiliconPkg/SystemAgent: Add modules
  CoffeelakeSiliconPkg: Add package DSC files
  Maintainers.txt: Add CoffeelakeSiliconPkg maintainers
  WhiskeylakeOpenBoardPkg: Add package and headers
  WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers
  WhiskeylakeOpenBoardPkg: Add library instances
  WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add library instances
  WhiskeylakeOpenBoardPkg: Add modules
  WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files
  Add WhiskeylakeOpenBoardPkg to global build config and documentation

 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec                                                                      |  565 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec                                                                                 |  714 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc                                                      |  385 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc                                           |  154 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc                                                |  128 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc                                                   |  245 ++
 Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc                                                                  |  215 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc                                                                      |  130 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc                                                                        |   69 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc                                                                              |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc                                                                           |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc                                                                              |   21 +
 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc                                                                           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf                                       |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf                                                      |  706 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf                                                    |   71 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf                                                    |   62 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf                              |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf                           |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf                              |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf                        |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf                                                   |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf                                               |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf                                                   |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf                        |  161 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf      |  139 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf        |   97 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf                                             |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf                                   |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf                                     |   67 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf                                           |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf                              |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf                                  |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf                              |  272 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf                                                |  176 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf                                   |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf         |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf                   |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf                        |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf                  |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf                       |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf                        |  116 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf                  |  202 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf                   |  296 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf           |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf                     |   94 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf           |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf                               |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf                                           |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf                                     |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf                           |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf                                         |   29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf                                     |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf                                               |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf                                       |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf                                           |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf                                          |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf                                                 |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf                                              |   44 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf                                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf                                                 |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf                                           |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf                                       |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf                         |   52 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf                                 |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf                                         |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf                 |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf                                   |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf                                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf                                   |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf                                |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf                               |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf                                     |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf                                     |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf                        |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf                   |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf                         |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf                                           |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf                                      |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf                                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf                                           |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf                                        |   86 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf                                             |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf                                       |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf                                                       |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf                     |   26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf                           |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf                     |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf                  |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf                         |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf                                         |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf                |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf                             |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf                       |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf               |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf            |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf                  |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf               |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf                        |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf                               |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf                                 |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf                                 |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf                                                         |   99 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf                                                      |   77 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf                                                            |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf                                             |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf                                                  |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf                                                                 |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf                                                   |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                                                  |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf                                     |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf                     |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf                                     |   74 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf                                                      |  116 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf                                                   |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h                                                      |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h                                |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h                                        |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h                                      |  131 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h                                |   21 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h                                        |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h                                  |   61 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h                                           |  261 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h                                               |   31 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h                                 |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h                            |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h                                    |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h                                          |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h                                            |   50 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h                                                   |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h                                                  |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h                                      |   84 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h                            |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h                            |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h                                              |  180 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h                          |  234 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h                 |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h                  |   28 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h                   |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h                          |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h                             |   43 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h                                                       |  118 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h                                                             |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h                                                                      |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h                                                      |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h                                                                | 1766 ++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h                                                              |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h                                                                  |   68 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h                                               |   75 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h                                                |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h                                               |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h                                             |   30 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h                                                |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h                                                    |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h                                                |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h                                                     |  123 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h                                                     |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h                                                        |   34 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h                                                      |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h                                             |  141 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h                                                    |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h                                                     |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h                                                           |   51 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h                                                     |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h                                                                    |   33 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h                                                             |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h                                                      |   47 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h                                                                       |  144 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h                                                                     |  157 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h                                         | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h                                 |   91 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h                                 |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h                                    |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h                                     |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h                                       |   23 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h                                     |   58 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h                                     |   22 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h                                |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h                                 |   14 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h                                |   25 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h                                 |   53 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h                                 |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h                                                   |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h                                               |   38 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h                                               |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h                                               |   52 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h                                                  |   45 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h                                                |   56 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h                                           |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h                                          |  131 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h                                              |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h                                         |  105 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h                                                |   44 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h                                           |   12 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h                                      |   18 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h                                   |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h                            |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h                               |  225 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h                              |  284 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h                        |   59 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h                               | 3014 ++++++++++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h                      |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h                |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h                |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h                                                       |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h                                        |  106 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h                                           |  141 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h                                                |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h                                         |  179 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h                                        |   78 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h                                          |  149 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h                                                   |   66 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h                                                                   |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h                                                               |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h                                                               |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h                                                             |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h                                                                |  100 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h                                                                     |  261 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h                                                       |   90 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h                                                      |  118 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h                                                        |   84 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h                                                            |  123 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h                                                  |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h                                         |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h                                  |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h                                                                     |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h                                                            |   89 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h                                                           |  291 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h                                                            |  157 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h                                                          |   64 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h                                                                |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h                                                    |  123 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h                                                        |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h                                                             |  110 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h                                                             |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h                                                                  |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h                                                                        |  319 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h                                                                    |   29 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h                                                     |   26 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h                                                      |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h                                                       |   60 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h                                                                |   55 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h                                                                     |   19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h                                                                  |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h                                                            |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h                                               |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h                                                      |  124 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h                                                       |   59 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h                                                       |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h                                                                    |  172 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h                                                                  |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h                                                                     |   19 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h                                                            |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h                                            |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h                                                      |   69 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h                                                       |   56 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h                                                       |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h                                                      |   40 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h                                           |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h                                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h                                                   |  178 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h                                                      |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h                                                  |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h                                                  |   66 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h                                                 |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h                                                    |   68 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h                                                       |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h                                                       |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h                                                  |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h                                                       |   34 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h                                                      |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h                                                |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h                                               |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h                                                    |  429 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h                                                        |  311 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h                                                      |  230 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h                                                       |   63 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h                                                  |   96 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h                                                 |   43 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h                                                     |   52 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h                                                   |  139 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h                                                  |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h                                                                  |  135 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h                                                                  |  326 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h                                                                |  381 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h                                                               |  340 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h                                                                |  241 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h                                                               |  200 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h                                                         |   27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h                                                             |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h                                                     |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h                                                           |  265 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h                                                             |  788 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h                                                       |  166 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h                                                            |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h                                                 |  371 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h                                                          |  141 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h                                                           |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h                                                          |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h                                                          |  407 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h                                                        |  105 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h                                                           |  226 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h                                                           |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h                                                        |  114 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h                                                         |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h                                                     |  116 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h                                                      |  240 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h                                                  |  111 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h                                                    |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h                                                     |  121 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h                                                              |  207 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h                                                             |   76 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h                                                           |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h                                                   |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h                                                              |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h                                                                   |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h                                                                      |   38 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h                                                                  |   80 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h                                                                   |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h                                                     |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h                                                             |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h                                                       |   59 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h                                                        |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h                                                    |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h                                                                |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h                                                                     |   27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h                                                                     |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h                                                      |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h                                               |  134 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h                                              |   97 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h                                           |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h                                              | 1061 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h                                          |  288 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h                                                   |  344 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h                                                   |   56 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h                                            |  100 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h                                     |  371 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h                                            |  578 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h                                           |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h                                             |  366 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h                                                |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h                                               |  706 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h                                          |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h                                            |   28 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h                                                        |  273 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h                                                     |  115 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h                                                             |   92 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h                                                       |  269 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h                                                           |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h                                                 |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h                                                 |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h                                                  |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h                                                   |  186 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h                                                 |  136 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h                                                      |   68 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h                                                 |  146 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h                                                 |  132 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h                                                          |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h                                                           |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h                                                     |  134 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h                                                |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h                                         |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h                                                  |  152 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h                                                           |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h                                                                |  295 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h                                                                |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h                                                            |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h                                                         |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h                                                         |  122 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h                                                       |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h                                                       |   62 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h                                                         |   90 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h                                                        |  273 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h                                                     |  694 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h                                                         |  204 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h                                                        |  170 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h                                                         |   79 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h                                                        |  103 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h                                                         |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h                                                         |  360 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h                                                      |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h                                                        |  116 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h                                                        |  484 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h                                                         |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h                                                         |  670 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h                                                      |   72 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h                                                         |  104 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h                                                      |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h                                                        |   77 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h                                                        |  668 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h                                                         |   52 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h                                                      |   48 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h                                                    |  232 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h                                                 |  138 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h                                                       |  151 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h                                                         |  295 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h                                                  |   49 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h                                                    |  134 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h                                                |  117 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h                                       |   45 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h                              |   16 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h                                         |   35 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h                |  477 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h                                         |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h        |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h                  |  490 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h                        |   47 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h                                                                 |  223 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h                                                              |  187 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h                                                         |  228 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h                                                         | 1031 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h                                                     |  342 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h                                                  |  157 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h                                                 |  105 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h                                              |  132 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h                                               |   82 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h                            |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h                                | 1513 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h                           |  118 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h                                      |   65 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h                                   |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h                              |   30 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h                                  |   80 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h                                           |  137 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h                                          |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h                                    |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h                                                        |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h                                               |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h                                       |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h                                       |   96 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h                                 |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h                                         |   46 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h                                            |  534 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h                                         |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h                                           |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h                                      |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h                                           |  135 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h                                           |   60 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h                                     |  354 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h                                         |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h                                   |  103 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h                                |   63 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h                                          |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h                                               |   42 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h                                                   |   77 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h                                              |   60 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h                                              |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h                                               |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h                                                          |  259 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h                                     |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h                                        |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h                                   |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h                                           |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h                                        |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h                                          |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h                                                 |   89 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h                                                |  151 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h                                          |   63 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h                                                  |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h                                                |   24 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h                                                    |  132 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h                                                   |   66 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h                                                  |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h                                           |  214 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h                                                  |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h                                                  |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h                                                  |   64 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h                                                            |  106 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h                                                 |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h                                                     |   25 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h                                                      |   51 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h                                                              |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h                                   |   37 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h                            |   21 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h                                       |  323 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h                                   |   39 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h                                |  230 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h                                  | 1567 ++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h                                    |  203 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h                                    | 1167 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h                                      |  237 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h                                             |   15 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h                                                     |   50 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h                                                  |  193 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h                                                   |   91 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h                                                      |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h                                                           |   71 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h                                                        |  139 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h                                           |   17 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h                                                              |   53 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h                                               |  162 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c                                                      |   96 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c                                                      |  290 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c                                                      |  353 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c                                |  148 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c                             |  316 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c                                |  206 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c                          |  567 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c                                                     |  228 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c                                                 |  211 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c                                              | 1609 +++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c                                                     | 1765 ++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c                       |  461 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c                        |  121 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c                         |   77 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c                       |  736 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c                          |  223 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c                        |  848 ++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c                  |   70 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c                        |   95 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c              |  100 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c               |  124 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c                  |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c            |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c                   |   85 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c             |   87 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c             |  163 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c                         |   54 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c                    |   90 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c               |   79 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c                       |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c                       |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c                                                   |  394 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c                                               |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c                                     |  310 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c                                       |  132 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c                                             |  115 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c                                |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c                                 |  105 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c                                |   39 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c                                 |   57 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c                                       |   65 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c                                 |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c                                     |  114 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c                                |   80 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c                          |  108 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c                                 |   49 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c                           |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c                                |  523 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c                          |  113 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c                                 |  242 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c                           |  221 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c                                 |  168 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c                                                   |  612 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c                                               |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c                                               |  174 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c                                               |   55 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c                                                  |   88 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c                                                |   60 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c                                           |   46 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c                                             |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c           |  137 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c   |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c                     |  156 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c                          |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c                    |   82 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c                        |  170 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c                |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c                                      |   19 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c                                  |   27 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c                            |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c                          |  398 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c                           |  282 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c                         |   40 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c                          |  106 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c                    |   41 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c                     |   83 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c                       |   63 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c               |  432 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c                |  636 +++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c                  |   32 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c                       |  299 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c             |   48 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c       |   29 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c             |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c       |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c              |   35 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c        |   36 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c              |   27 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c                                 |   90 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c                                              |  293 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c                                        |  108 +
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c                                             |  434 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c                                       |  160 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c                                  |  415 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c                                           |  146 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c                                       |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c                                                 |  403 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c                                         |  126 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c                                             |   32 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c                                            |   78 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c                                                   |  214 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c                                             |  122 +
 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c                                                    |   36 +
 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c                                                |  251 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c                                       |  153 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c                                                   |  993 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c                                             |  218 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c                                         |  310 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c                           |  323 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c                                            |   98 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c                                                   |  553 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c                                                    | 2710 ++++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c                                                  |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c                                              |  234 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c                            | 1136 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c                                              |  505 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c                                                |   82 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c                                              |  127 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c                                              |  272 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c                                        |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c                                           |  386 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c                                          |  183 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c                                                |  279 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c                                                |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c                                    |  270 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c                                      |  516 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c                                   |  181 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c                     |  372 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c                                          |  242 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c                                                      |  330 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c                                                    |   41 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c                                                 |  101 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c                                                 |   88 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c                                                     |  130 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c                                             |   23 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c                                        |  307 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c                                              |  778 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c                                             |  739 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c                                          |  169 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c                                       |  318 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c                                                     |  109 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c                                         |  257 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c                                                            |  217 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c                       |  108 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c                                       | 1081 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c                       |   70 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c                 |  125 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c                    |   61 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c                              |   20 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c                                        |  333 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c                                              |  886 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c                                       |  439 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c                                |  166 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c                        | 1304 +++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c                     | 2275 +++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c                              |  752 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c                           |  225 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c                                         |   67 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c                                         |  113 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c                                        |  569 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c                                  |   79 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c                             |  221 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c        | 2407 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c                          |  542 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c                       |  338 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c                             |   92 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c                                | 1033 +++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c                          |   73 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c                             |  360 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c                          |  194 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c                                 |  356 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c                              |   68 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c                                   |   58 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c                                         |  196 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c                                   |   54 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c                                                                 |  451 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c                                                             |   33 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c                                                              |  323 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c                                                                 |  554 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c                                                              |  382 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c                                                              |   85 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c                                                                 |   89 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c                                                             |   57 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c                                                          |  156 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c                                                     |  156 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c                                                              |  179 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c                                                             |  298 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c                                                              |  436 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c                                                             |   69 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c                                                         | 1264 ++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c                                                 | 2452 ++++++++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c                                                     |  911 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c                                                     | 1595 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c                                                      |  254 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c                                                  |  358 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c                                            |  675 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c                                              |   83 +
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c                                                       |  385 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c                                                       |  229 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c                                                      |  231 ++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c                                                 |  764 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c                                              |  399 +++
 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c                                                                      |  310 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c                                       |  473 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c                            |  128 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c                                       |  745 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c                                       |  656 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c                                 |  284 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c                                        |  559 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c                                                     |  157 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c                                                  |  570 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c                                                   |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c                                                      |  171 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c                                                           |  496 ++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c                                                           |  179 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c                                                        |  122 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c                                                              |  717 +++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c                                               |  356 +++
 Maintainers.txt                                                                                                              |   12 +-
 Platform/Intel/Readme.md                                                                                                     |   44 +-
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl                                                     |   20 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL                                                       |   37 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl                                                    |  516 ++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl                                                    |  309 ++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl                                                   |   76 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl                                               |  405 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl                                                       | 1877 ++++++++++++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm                 |  130 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm                     |  361 +++
 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm                        |   72 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl                                                            |  112 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni                                             |   15 +
 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg                                                      |   33 +
 Platform/Intel/build.cfg                                                                                                     |    4 +-
 Readme.md                                                                                                                    |    1 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc                                                     |  250 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl                                                        |  794 ++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl                                                    | 1666 +++++++++++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl                                              |  472 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl                                                 |  369 +++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl                                              |  129 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl                                                |  296 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl                                              |  262 ++
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl                                                     |   87 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                                                      |   31 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl                                                   |  147 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                                                  |   22 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S                                  |  114 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm                                |  126 +
 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm                               |  118 +
 749 files changed, 139608 insertions(+), 17 deletions(-)
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkg.dec
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgBuildOption.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgConfig.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkgPcd.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/CoffeelakeSiliconPkg.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgBuildOption.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxe.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgDxeLib.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPei.dsc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SiPkgPeiLib.dsc
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/Fdf/FlashMapInclude.fdf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/OpenBoardPkg.fdf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSiliconPolicyUpdateLibFsp.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecFspWrapperPlatformSecLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePolicyUpdateLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPolicyUpdateLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/BaseFuncLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfigLib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfigLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDxeSmmBiosLockLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxeSmmPchEspiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxeSmmPchGbeLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxeSmmPchHsioLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxeSmmPchPmcLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PeiDxeSmmPchSerialIoLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/PeiDxeSmmPchWdtCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchResetLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/DxePchHdaLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PeiDxeSmmPchInitCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PeiDxeSmmPchPciExpressHelpersLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PeiDxeSmmPchPsfPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLibCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaAcpiTables.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccess.inf
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeCheckIommuSupportLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtSecurityLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiCheckIommuSupportLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtTaskDispatchLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DisableBmeProtocol.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtNvsAreaDef.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiMiscPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FsptCoreUpd.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Fsp.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvsAreaDef.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/AttemptUsbFirst.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/CpuSmm.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/FirwmareConfigurations.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/GopConfigLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Guid/TcoWdtHob.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/IoExpander.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeCpuPolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeMePolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePchPolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxePolicyBoardConfigLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/DxeSaPolicyUpdateLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/FspPolicyInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioCheckConflictLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/GpioExpanderLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/HdaVerbTableLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/I2cAccessLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPlatformLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyBoardConfigLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PeiPolicyInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Library/PlatformInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PchHsioPtssTables.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PcieDeviceOverrideTable.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Platform.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/PlatformBoardId.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Protocol/GlobalNvsArea.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Setup.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/SioRegs.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PchHdaVerbTables.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiCpuPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiMePolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSiPolicyInit.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformHookLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PeiPlatformLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformBoardConfig.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/PlatformInfo.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Include/WhiskeylakeURvpId.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaConfigPreMem.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableDefault.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/GpioTableWhlUDdr4PreMem.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PchHdaVerbTables.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitLib.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxePolicyBoardConfig.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPolicyBoardConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuOverclockingConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuDataStruct.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuNvsAreaDef.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuPowerMgmt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/CpuRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuMailboxLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPlatformLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Library/CpuPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuInfo.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Include/Protocol/CpuPolicyProtocol.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/SiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/ConfigBlock/UsbConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/AslUpdateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/ConfigBlockLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/MmPciLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/PeiSiPolicyUpdateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiConfigBlockLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/SiPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/StallPpiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Library/UsbLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/PcieRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Ppi/SiPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/PcieInitLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Private/Library/UsbInitLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Protocol/SiPolicyProtocol.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/Register/RegsUsb.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiConfigHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/SiPolicyStruct.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Include/TraceHubCommonConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/ConfigBlock/MePeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/DxeMePolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Library/PeiMePolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MeChipset.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MePolicyHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/MkhiMsgs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Include/Protocol/MePolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/CnviConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DciConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/DmiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/EspiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/GpioDevConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HdAudioConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/InterruptConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IoApicConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/IshConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LanConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/P2sbConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PchTraceHubConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PcieRpConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/PmConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SataConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ScsConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIoConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SerialIrqConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/SmbusConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/ThermalConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/ConfigBlock/WatchDogConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/DxeHdaNhlt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlH.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsCnlLp.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklH.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/GpioPinsSklLp.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/BiosLockLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/CnviLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/DxePchPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GpioNativeLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/OcWdtLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchEspiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchGbeLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchHsioLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcieRpLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPcrLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPmcLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchResetLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSbiAccessLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSerialIoUartLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchSmmControlLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PchWdtCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/PmcLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SataLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SecPchLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiFlashCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/SpiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchHda.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchInfoHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchLimits.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPcieStorageDetectHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchReservedResources.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/PchReset.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Spi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Ppi/Wdt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/CnlPchLpHsioDx.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/DxePchHdaNhlt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioHelpersLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioNameBufferLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/GpioPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/I2cMasterCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchDmiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchHdaLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchInitCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPciExpressHelpersLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchPsfPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSmbusCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PchSpiCommonLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PeiPchDmiLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/PmcPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SiScheduleResetLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Library/SmmPchPrivateLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchConfigHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHdaEndpoints.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchHsio.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchNvsAreaDef.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/PchRstHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PchNvsArea.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/Protocol/PcieIoTrap.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Private/SiScheduleResetHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEmmcTuning.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchReset.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/SmmSmbus.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Spi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Protocol/Wdt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi14.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDmi15.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsFia.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpio.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsGpioCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHda.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsHsio.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsIsh.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsItss.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLpcCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsP2sb.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcie.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPcr.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmc.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPmcCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsfCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSata.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsScsCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIo.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSerialIoCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSmbus.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsSpi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsThermalCnl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsTraceHub.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibInternal.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/Include/Library/SecPlatformLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Guid/SmramMemoryReserve.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyBios.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/IntelFrameworkPkg/Include/Protocol/LegacyInterrupt.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/AcpiS3Context.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/ConsoleOutDevice.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Guid/MemoryTypeInformation.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Library/ResetSystemLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Ppi/SmmControl.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SampleCode/MdeModulePkg/Include/Protocol/SmmVariable.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GnaConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/GraphicsPeiPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/IpuPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/MiscDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/OverClockingConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/PciePeiPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/SwitchableGraphicsConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VbiosDxeConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/ConfigBlock/VtdConfig.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/DmaRemappingTable.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/DxeSaPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/PeiSaPolicyLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/GraphicsInitLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/LegacyRegion.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/PeiCpuTraceHubLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Library/SaPcieLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaIotrapSmi.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/Protocol/SaNvsArea.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaConfigHob.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Private/SaNvsAreaDef.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopComponentName2.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/GopPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/IgdOpRegion.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/MemInfo.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsGna.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsHostBridge.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIgd.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsIpu.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/Register/SaRegsPeg.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaAccess.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaCommonDefinitions.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPciExpressLib.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaPolicyCommon.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Include/SaRegs.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibrary.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcCommonTypes.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcInterface.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcRmtData.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcSpdData.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/Coffeelake/MrcTypes.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/MemoryInit/Include/MrcInterface.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SwitchableGraphicsInit.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.h
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.h
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspCpuPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMePolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspMiscUpdInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPchPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSaPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSecurityPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiFspPolicyInitLib/PeiFspSiPolicyInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspMiscUpdUpdateLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiFspPolicyUpdateLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiPchPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/PeiSiliconPolicyUpdateLibFsp/PeiSaPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/FspWrapperPlatformSecLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/PlatformInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecGetPerformance.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecPlatformInformation.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecRamInitData.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/SecTempRamDone.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiHdaVerbTableLib/PeiHdaVerbTableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeCpuPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeMePolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxePchPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/DxePolicyUpdateLib/DxeSaPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiPolicyInitPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyInitLib/PeiSaPolicyInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiCpuPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiMePolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiPchPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSaPolicyUpdatePreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Library/PeiPolicyUpdateLib/PeiSiPolicyUpdate.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseFuncLib/Gop.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BasePlatformHookLib/BasePlatformHookLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmBoardAcpiEnableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmMultiBoardAcpiSupportLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmSiliconAcpiEnableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardAcpiLib/SmmWhiskeylakeURvpAcpiEnableLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFunc.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInit.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardFuncInitPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardPchInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/BoardSaInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPostMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiBoardInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPostMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiMultiBoardInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpDetect.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPostMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/PeiWhiskeylakeURvpInitPreMemLib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/BoardInitLib/WhiskeylakeURvpHsioPtssTables.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/DxePolicyBoardConfigLib/DxeSaPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPlatformHookLib/PeiPlatformHooklib.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiCpuPolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiMePolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiPchPolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfig.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSaPolicyBoardConfigPreMem.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/Library/PeiPolicyBoardConfigLib/PeiSiPolicyBoardConfig.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/DxeAslUpdateLibNull/DxeAslUpdateLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiInstallStallPpiLib/PeiStallPpiLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/PeiSiPolicyLibPreMem.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Library/PeiSiPolicyLib/SiPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Me/Library/PeiMePolicyLib/PeiMePolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeResetSystemLib/DxeResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/DxeRuntimeResetSystemLib/DxeRuntimeResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosLockLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNames.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEspiLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGbeLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsioLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibClient.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPmcLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/PchSerialIoLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLib/PeiDxeSmmPchSerialIoUartLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLib/WdtCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCdf.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPolicyLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreMemPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiResetSystemLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BasePchSpiCommonLib/SpiCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/BaseSiScheduleResetLib/BaseSiScheduleResetLibFsp.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxeGpioNameBufferLib/GpioNameBufferDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaEndpoints.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/DxePchHdaLib/PchHdaNhltConfig.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNamesCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmGpioPrivateLib/GpioPrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi14.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmi15.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchInitCommonLib/PchInitCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPchPsfPrivateLib/PchPsfPrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PeiPmcPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibClient.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibCnl.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioHelpersLib/PeiGpioHelpersLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/PeiGpioNameBufferLib/GpioNameBufferPei.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/Private/SmmPchPrivateLib/SmmPchPrivateLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/MrcOemPlatform.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLib.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/PeiSaPolicyLibSample.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/SaPrintPolicy.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/GraphicsInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/IgdOpRegionInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PciExpressInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/PcieComplex.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SaInit/Dxe/VTd.c
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/SmmAccess/Dxe/SmmAccessDriver.c
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/PeiCoreEntry.nasm
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/SecEntry.nasm
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/FspWrapper/Library/SecFspWrapperPlatformSecLib/Ia32/Stack.nasm
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Include/Acpi/GlobalNvs.asl
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.uni
 create mode 100644 Platform/Intel/WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/Dmar/Dmar.aslc
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/HostBus.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Igfx.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxCommon.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxDsm.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpGbda.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpRn.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/IgfxOpSbcb.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Ipu.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaNvs.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.S
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.asm
 create mode 100644 Silicon/Intel/CoffeelakeSiliconPkg/SystemAgent/Library/PeiSaPolicyLib/Ia32/MrcOemPlatform.nasm

-- 
2.16.2.windows.1


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

end of thread, other threads:[~2019-08-19 18:14 UTC | newest]

Thread overview: 121+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  1:18   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  6:58   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  7:04   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:10   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-19 18:09   ` Sinha, Ankit
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:08   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17  7:50   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17 20:11   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:00   ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit

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